'temp2'
This commit is contained in:
parent
73a80d3a1d
commit
33590d58a1
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
*
|
||||
* Created: 29.03.2018
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* Assembled from the code released on Stackoverflow by:
|
||||
* Dennis (instructable.com/member/nqtronix) | https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string
|
||||
* and
|
||||
* Alexis Wilke | https://stackoverflow.com/questions/10538444/do-you-know-of-a-c-macro-to-compute-unix-time-and-date
|
||||
*
|
||||
* Assembled by Jean Rabault
|
||||
*
|
||||
* BUILD_UNIX_TIMESTAMP gives the UNIX timestamp (unsigned long integer of seconds since 1st Jan 1970) of compilation from macros using the compiler defined __TIME__ macro.
|
||||
* This should include Gregorian calendar leap days, in particular the 29ths of February, 100 and 400 years modulo leaps.
|
||||
*
|
||||
* Careful: __TIME__ is the local time of the computer, NOT the UTC time in general!
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMPILE_TIME_H_
|
||||
#define COMPILE_TIME_H_
|
||||
|
||||
// Some definitions for calculation
|
||||
#define SEC_PER_MIN 60UL
|
||||
#define SEC_PER_HOUR 3600UL
|
||||
#define SEC_PER_DAY 86400UL
|
||||
#define SEC_PER_YEAR (SEC_PER_DAY*365)
|
||||
|
||||
// extracts 1..4 characters from a string and interprets it as a decimal value
|
||||
#define CONV_STR2DEC_1(str, i) (str[i]>'0'?str[i]-'0':0)
|
||||
#define CONV_STR2DEC_2(str, i) (CONV_STR2DEC_1(str, i)*10 + str[i+1]-'0')
|
||||
#define CONV_STR2DEC_3(str, i) (CONV_STR2DEC_2(str, i)*10 + str[i+2]-'0')
|
||||
#define CONV_STR2DEC_4(str, i) (CONV_STR2DEC_3(str, i)*10 + str[i+3]-'0')
|
||||
|
||||
// Custom "glue logic" to convert the month name to a usable number
|
||||
#define GET_MONTH(str, i) (str[i]=='J' && str[i+1]=='a' && str[i+2]=='n' ? 1 : \
|
||||
str[i]=='F' && str[i+1]=='e' && str[i+2]=='b' ? 2 : \
|
||||
str[i]=='M' && str[i+1]=='a' && str[i+2]=='r' ? 3 : \
|
||||
str[i]=='A' && str[i+1]=='p' && str[i+2]=='r' ? 4 : \
|
||||
str[i]=='M' && str[i+1]=='a' && str[i+2]=='y' ? 5 : \
|
||||
str[i]=='J' && str[i+1]=='u' && str[i+2]=='n' ? 6 : \
|
||||
str[i]=='J' && str[i+1]=='u' && str[i+2]=='l' ? 7 : \
|
||||
str[i]=='A' && str[i+1]=='u' && str[i+2]=='g' ? 8 : \
|
||||
str[i]=='S' && str[i+1]=='e' && str[i+2]=='p' ? 9 : \
|
||||
str[i]=='O' && str[i+1]=='c' && str[i+2]=='t' ? 10 : \
|
||||
str[i]=='N' && str[i+1]=='o' && str[i+2]=='v' ? 11 : \
|
||||
str[i]=='D' && str[i+1]=='e' && str[i+2]=='c' ? 12 : 0)
|
||||
|
||||
// extract the information from the time string given by __TIME__ and __DATE__
|
||||
#define __TIME_SECONDS__ CONV_STR2DEC_2(__TIME__, 6)
|
||||
#define __TIME_MINUTES__ CONV_STR2DEC_2(__TIME__, 3)
|
||||
#define __TIME_HOURS__ CONV_STR2DEC_2(__TIME__, 0)
|
||||
#define __TIME_DAYS__ CONV_STR2DEC_2(__DATE__, 4)
|
||||
#define __TIME_MONTH__ GET_MONTH(__DATE__, 0)
|
||||
#define __TIME_YEARS__ CONV_STR2DEC_4(__DATE__, 7)
|
||||
|
||||
// Days in February
|
||||
#define _UNIX_TIMESTAMP_FDAY(year) \
|
||||
(((year) % 400) == 0UL ? 29UL : \
|
||||
(((year) % 100) == 0UL ? 28UL : \
|
||||
(((year) % 4) == 0UL ? 29UL : \
|
||||
28UL)))
|
||||
|
||||
// Days in the year
|
||||
#define _UNIX_TIMESTAMP_YDAY(year, month, day) \
|
||||
( \
|
||||
/* January */ day \
|
||||
/* February */ + (month >= 2 ? 31UL : 0UL) \
|
||||
/* March */ + (month >= 3 ? _UNIX_TIMESTAMP_FDAY(year) : 0UL) \
|
||||
/* April */ + (month >= 4 ? 31UL : 0UL) \
|
||||
/* May */ + (month >= 5 ? 30UL : 0UL) \
|
||||
/* June */ + (month >= 6 ? 31UL : 0UL) \
|
||||
/* July */ + (month >= 7 ? 30UL : 0UL) \
|
||||
/* August */ + (month >= 8 ? 31UL : 0UL) \
|
||||
/* September */+ (month >= 9 ? 31UL : 0UL) \
|
||||
/* October */ + (month >= 10 ? 30UL : 0UL) \
|
||||
/* November */ + (month >= 11 ? 31UL : 0UL) \
|
||||
/* December */ + (month >= 12 ? 30UL : 0UL) \
|
||||
)
|
||||
|
||||
// get the UNIX timestamp from a digits representation
|
||||
#define _UNIX_TIMESTAMP(year, month, day, hour, minute, second) \
|
||||
( /* time */ second \
|
||||
+ minute * SEC_PER_MIN \
|
||||
+ hour * SEC_PER_HOUR \
|
||||
+ /* year day (month + day) */ (_UNIX_TIMESTAMP_YDAY(year, month, day) - 1) * SEC_PER_DAY \
|
||||
+ /* year */ (year - 1970UL) * SEC_PER_YEAR \
|
||||
+ ((year - 1969UL) / 4UL) * SEC_PER_DAY \
|
||||
- ((year - 1901UL) / 100UL) * SEC_PER_DAY \
|
||||
+ ((year - 1601UL) / 400UL) * SEC_PER_DAY \
|
||||
)
|
||||
|
||||
// the UNIX timestamp
|
||||
#define BUILD_UNIX_TIMESTAMP (_UNIX_TIMESTAMP(__TIME_YEARS__, __TIME_MONTH__, __TIME_DAYS__, __TIME_HOURS__, __TIME_MINUTES__, __TIME_SECONDS__))
|
||||
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
<ClInclude Include="assert.h" />
|
||||
<ClInclude Include="bitfield.h" />
|
||||
<ClInclude Include="bitutils.h" />
|
||||
<ClInclude Include="build_timestamp.h" />
|
||||
<ClInclude Include="byte_stream.h" />
|
||||
<ClInclude Include="crash_handler.h" />
|
||||
<ClInclude Include="d3d11\shader_cache.h" />
|
||||
|
|
|
@ -137,6 +137,7 @@
|
|||
<ClInclude Include="memory_settings_interface.h" />
|
||||
<ClInclude Include="threading.h" />
|
||||
<ClInclude Include="scoped_guard.h" />
|
||||
<ClInclude Include="build_timestamp.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="gl\program.cpp">
|
||||
|
|
|
@ -186,8 +186,21 @@ void Timer::SleepUntil(Value value, bool exact)
|
|||
{
|
||||
if (exact)
|
||||
{
|
||||
while (GetCurrentValue() < value)
|
||||
SleepUntil(value, false);
|
||||
for (;;)
|
||||
{
|
||||
Value current = GetCurrentValue();
|
||||
if (current >= value)
|
||||
break;
|
||||
|
||||
static constexpr Value min_sleep_time = 1 * 1000000;
|
||||
|
||||
// spin for the last 1ms
|
||||
if ((value - current) > min_sleep_time)
|
||||
{
|
||||
SleepUntil(value, false);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "analog_controller.h"
|
||||
#include "IconsFontAwesome5.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "host.h"
|
||||
|
@ -10,8 +11,9 @@ Log_SetChannel(AnalogController);
|
|||
|
||||
AnalogController::AnalogController(u32 index) : Controller(index)
|
||||
{
|
||||
m_status_byte = 0x5A;
|
||||
m_axis_state.fill(0x80);
|
||||
Reset();
|
||||
m_rumble_config.fill(0xFF);
|
||||
}
|
||||
|
||||
AnalogController::~AnalogController() = default;
|
||||
|
@ -45,14 +47,16 @@ void AnalogController::Reset()
|
|||
{
|
||||
if (g_settings.controller_disable_analog_mode_forcing)
|
||||
{
|
||||
Host::AddKeyedOSDMessage(
|
||||
"analog_controller_mode_ignored",
|
||||
Host::AddIconOSDMessage(
|
||||
fmt::format("Controller{}AnalogMode", m_index), ICON_FA_GAMEPAD,
|
||||
Host::TranslateStdString(
|
||||
"OSDMessage", "Analog mode forcing is disabled by game settings. Controller will start in digital mode."),
|
||||
10.0f);
|
||||
}
|
||||
else
|
||||
SetAnalogMode(true);
|
||||
{
|
||||
SetAnalogMode(true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,11 +98,14 @@ bool AnalogController::DoState(StateWrapper& sw, bool apply_input_state)
|
|||
|
||||
if (old_analog_mode != m_analog_mode)
|
||||
{
|
||||
Host::AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
m_analog_mode ? Host::TranslateString("AnalogController", "Controller %u switched to analog mode.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
Host::AddIconOSDMessage(
|
||||
fmt::format("Controller{}AnalogMode", m_index), ICON_FA_GAMEPAD,
|
||||
fmt::format((m_analog_mode ?
|
||||
Host::TranslateString("AnalogController", "Controller {} switched to analog mode.") :
|
||||
Host::TranslateString("AnalogController", "Controller {} switched to digital mode."))
|
||||
.GetCharArray(),
|
||||
m_index + 1u),
|
||||
5.0f);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -230,17 +237,22 @@ void AnalogController::ResetTransferState()
|
|||
m_command_step = 0;
|
||||
}
|
||||
|
||||
void AnalogController::SetAnalogMode(bool enabled)
|
||||
void AnalogController::SetAnalogMode(bool enabled, bool show_message)
|
||||
{
|
||||
if (m_analog_mode == enabled)
|
||||
return;
|
||||
|
||||
Log_InfoPrintf("Controller %u switched to %s mode.", m_index + 1u, enabled ? "analog" : "digital");
|
||||
Host::AddFormattedOSDMessage(5.0f,
|
||||
enabled ?
|
||||
Host::TranslateString("AnalogController", "Controller %u switched to analog mode.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
if (show_message)
|
||||
{
|
||||
Host::AddIconOSDMessage(
|
||||
fmt::format("Controller{}AnalogMode", m_index), ICON_FA_GAMEPAD,
|
||||
fmt::format((enabled ? Host::TranslateString("AnalogController", "Controller {} switched to analog mode.") :
|
||||
Host::TranslateString("AnalogController", "Controller {} switched to digital mode."))
|
||||
.GetCharArray(),
|
||||
m_index + 1u),
|
||||
5.0f);
|
||||
}
|
||||
m_analog_mode = enabled;
|
||||
}
|
||||
|
||||
|
@ -248,15 +260,18 @@ void AnalogController::ProcessAnalogModeToggle()
|
|||
{
|
||||
if (m_analog_locked)
|
||||
{
|
||||
Host::AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
m_analog_mode ? Host::TranslateString("AnalogController", "Controller %u is locked to analog mode by the game.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u is locked to digital mode by the game."),
|
||||
m_index + 1u);
|
||||
Host::AddIconOSDMessage(
|
||||
fmt::format("Controller{}AnalogMode", m_index), ICON_FA_GAMEPAD,
|
||||
fmt::format((m_analog_mode ?
|
||||
Host::TranslateString("AnalogController", "Controller %u is locked to analog mode by the game.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u is locked to digital mode by the game."))
|
||||
.GetCharArray(),
|
||||
m_index + 1u),
|
||||
5.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAnalogMode(!m_analog_mode);
|
||||
SetAnalogMode(!m_analog_mode, true);
|
||||
ResetRumbleConfig();
|
||||
|
||||
if (m_dualshock_enabled)
|
||||
|
@ -604,7 +619,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
|
|||
Log_DevPrintf("analog mode val 0x%02x", data_in);
|
||||
|
||||
if (data_in == 0x00 || data_in == 0x01)
|
||||
SetAnalogMode((data_in == 0x01));
|
||||
SetAnalogMode((data_in == 0x01), true);
|
||||
}
|
||||
else if (m_command_step == 3)
|
||||
{
|
||||
|
@ -777,17 +792,17 @@ static const SettingInfo s_settings[] = {
|
|||
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogController", "Analog Deadzone"),
|
||||
TRANSLATABLE("AnalogController",
|
||||
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."),
|
||||
"0.00f", "0.00f", "1.00f", "0.01f"},
|
||||
"0.00f", "0.00f", "1.00f", "0.01f", "%.0f%%", 100.0f},
|
||||
{SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogController", "Analog Sensitivity"),
|
||||
TRANSLATABLE(
|
||||
"AnalogController",
|
||||
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
|
||||
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"1.33f", "0.01f", "2.00f", "0.01f"},
|
||||
"1.33f", "0.01f", "2.00f", "0.01f", "%.0f%%", 100.0f},
|
||||
{SettingInfo::Type::Integer, "VibrationBias", TRANSLATABLE("AnalogController", "Vibration Bias"),
|
||||
TRANSLATABLE("AnalogController", "Sets the rumble bias value. If rumble in some games is too weak or not "
|
||||
"functioning, try increasing this value."),
|
||||
"8", "0", "255", "1"}};
|
||||
"8", "0", "255", "1", "%d", 1.0f}};
|
||||
|
||||
const Controller::ControllerInfo AnalogController::INFO = {ControllerType::AnalogController,
|
||||
"AnalogController",
|
||||
|
|
|
@ -108,7 +108,7 @@ private:
|
|||
u8 GetModeID() const;
|
||||
u8 GetIDByte() const;
|
||||
|
||||
void SetAnalogMode(bool enabled);
|
||||
void SetAnalogMode(bool enabled, bool show_message);
|
||||
void ProcessAnalogModeToggle();
|
||||
void SetMotorState(u32 motor, u8 value);
|
||||
void UpdateHostVibration();
|
||||
|
@ -140,7 +140,7 @@ private:
|
|||
int m_rumble_config_small_motor_index = -1;
|
||||
|
||||
bool m_analog_toggle_queued = false;
|
||||
u8 m_status_byte = 0x5A;
|
||||
u8 m_status_byte = 0;
|
||||
|
||||
// TODO: Set this with command 0x4D and increase response length in digital mode accordingly
|
||||
u8 m_digital_mode_extra_halfwords = 0;
|
||||
|
|
|
@ -328,13 +328,13 @@ static const SettingInfo s_settings[] = {
|
|||
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogJoystick", "Analog Deadzone"),
|
||||
TRANSLATABLE("AnalogJoystick",
|
||||
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."),
|
||||
"1.00f", "0.00f", "1.00f", "0.01f"},
|
||||
"1.00f", "0.00f", "1.00f", "0.01f", "%.0f%%", 100.0f},
|
||||
{SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogJoystick", "Analog Sensitivity"),
|
||||
TRANSLATABLE(
|
||||
"AnalogJoystick",
|
||||
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
|
||||
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"1.33f", "0.01f", "2.00f", "0.01f"}};
|
||||
"1.33f", "0.01f", "2.00f", "0.01f", "%.0f%%", 100.0f}};
|
||||
|
||||
const Controller::ControllerInfo AnalogJoystick::INFO = {ControllerType::AnalogJoystick,
|
||||
"AnalogJoystick",
|
||||
|
|
|
@ -542,6 +542,12 @@ bool GameDatabase::LoadFromCache()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (gamedb_ts != file_gamedb_ts || gamesettings_ts != file_gamesettings_ts || compat_ts != file_compat_ts)
|
||||
{
|
||||
Log_DevPrintf("Cache is out of date, recreating.");
|
||||
return false;
|
||||
}
|
||||
|
||||
s_entries.reserve(num_entries);
|
||||
|
||||
for (u32 i = 0; i < num_entries; i++)
|
||||
|
|
|
@ -220,10 +220,10 @@ static const SettingInfo s_settings[] = {
|
|||
{SettingInfo::Type::Path, "CrosshairImagePath", TRANSLATABLE("GunCon", "Crosshair Image Path"),
|
||||
TRANSLATABLE("GunCon", "Path to an image to use as a crosshair/cursor.")},
|
||||
{SettingInfo::Type::Float, "CrosshairScale", TRANSLATABLE("GunCon", "Crosshair Image Scale"),
|
||||
TRANSLATABLE("GunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0", "0.10"},
|
||||
TRANSLATABLE("GunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0", "0.10", "%.0f%%", 100.0f},
|
||||
{SettingInfo::Type::Float, "XScale", TRANSLATABLE("GunCon", "X Scale"),
|
||||
TRANSLATABLE("GunCon", "Scales X coordinates relative to the center of the screen."), "1.0", "0.01", "2.0",
|
||||
"0.01"}};
|
||||
"0.01", "%.0f%%", 100.0f}};
|
||||
|
||||
const Controller::ControllerInfo GunCon::INFO = {ControllerType::GunCon,
|
||||
"GunCon",
|
||||
|
|
|
@ -251,7 +251,7 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
|
|||
|
||||
static const SettingInfo s_settings[] = {
|
||||
{SettingInfo::Type::Float, "SteeringDeadzone", TRANSLATABLE("NeGcon", "Steering Axis Deadzone"),
|
||||
TRANSLATABLE("NeGcon", "Sets deadzone size for steering axis."), "0.00f", "0.00f", "0.99f", "0.01f"}};
|
||||
TRANSLATABLE("NeGcon", "Sets deadzone size for steering axis."), "0.00f", "0.00f", "0.99f", "0.01f", "%.0f%%", 100.0f}};
|
||||
|
||||
const Controller::ControllerInfo NeGcon::INFO = {ControllerType::NeGcon,
|
||||
"NeGcon",
|
||||
|
|
|
@ -21,13 +21,15 @@ struct SettingInfo
|
|||
};
|
||||
|
||||
Type type;
|
||||
const char* key;
|
||||
const char* visible_name;
|
||||
const char* name;
|
||||
const char* display_name;
|
||||
const char* description;
|
||||
const char* default_value;
|
||||
const char* min_value;
|
||||
const char* max_value;
|
||||
const char* step_value;
|
||||
const char* format;
|
||||
float multiplier;
|
||||
|
||||
const char* StringDefaultValue() const;
|
||||
bool BooleanDefaultValue() const;
|
||||
|
|
|
@ -862,8 +862,13 @@ bool System::UpdateGameSettingsLayer()
|
|||
}
|
||||
|
||||
std::string input_profile_name;
|
||||
bool use_game_settings_for_controller = false;
|
||||
if (new_interface)
|
||||
new_interface->GetStringValue("ControllerPorts", "InputProfileName", &input_profile_name);
|
||||
{
|
||||
new_interface->GetBoolValue("ControllerPorts", "UseGameSettingsForController", &use_game_settings_for_controller);
|
||||
if (!use_game_settings_for_controller)
|
||||
new_interface->GetStringValue("ControllerPorts", "InputProfileName", &input_profile_name);
|
||||
}
|
||||
|
||||
if (!s_game_settings_interface && !new_interface && s_input_profile_name == input_profile_name)
|
||||
return false;
|
||||
|
@ -872,31 +877,39 @@ bool System::UpdateGameSettingsLayer()
|
|||
s_game_settings_interface = std::move(new_interface);
|
||||
|
||||
std::unique_ptr<INISettingsInterface> input_interface;
|
||||
if (!input_profile_name.empty())
|
||||
if (!use_game_settings_for_controller)
|
||||
{
|
||||
const std::string filename(GetInputProfilePath(input_profile_name));
|
||||
if (FileSystem::FileExists(filename.c_str()))
|
||||
if (!input_profile_name.empty())
|
||||
{
|
||||
Log_InfoPrintf("Loading input profile from '%s'...", filename.c_str());
|
||||
input_interface = std::make_unique<INISettingsInterface>(std::move(filename));
|
||||
if (!input_interface->Load())
|
||||
const std::string filename(GetInputProfilePath(input_profile_name));
|
||||
if (FileSystem::FileExists(filename.c_str()))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to parse input profile ini '%s'", input_interface->GetFileName().c_str());
|
||||
input_interface.reset();
|
||||
Log_InfoPrintf("Loading input profile from '%s'...", filename.c_str());
|
||||
input_interface = std::make_unique<INISettingsInterface>(std::move(filename));
|
||||
if (!input_interface->Load())
|
||||
{
|
||||
Log_ErrorPrintf("Failed to parse input profile ini '%s'", input_interface->GetFileName().c_str());
|
||||
input_interface.reset();
|
||||
input_profile_name = {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log_InfoPrintf("No input profile found (tried '%s')", filename.c_str());
|
||||
input_profile_name = {};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log_InfoPrintf("No input profile found (tried '%s')", filename.c_str());
|
||||
input_profile_name = {};
|
||||
}
|
||||
|
||||
Host::Internal::SetInputSettingsLayer(input_interface.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
// using game settings for bindings too
|
||||
Host::Internal::SetInputSettingsLayer(s_game_settings_interface.get());
|
||||
}
|
||||
|
||||
Host::Internal::SetInputSettingsLayer(input_interface.get());
|
||||
s_input_settings_interface = std::move(input_interface);
|
||||
s_input_profile_name = std::move(input_profile_name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -930,7 +943,7 @@ void System::PauseSystem(bool paused)
|
|||
else
|
||||
{
|
||||
Host::OnSystemResumed();
|
||||
g_host_display->SetVSync(ShouldUseVSync());
|
||||
UpdateDisplaySync();
|
||||
ResetPerformanceCounters();
|
||||
ResetThrottler();
|
||||
}
|
||||
|
@ -1249,6 +1262,7 @@ bool System::Initialize(bool force_software_renderer)
|
|||
s_frame_number = 1;
|
||||
s_internal_frame_number = 1;
|
||||
|
||||
s_target_speed = g_settings.emulation_speed;
|
||||
s_throttle_frequency = 60.0f;
|
||||
s_frame_period = 0;
|
||||
s_next_frame_time = 0;
|
||||
|
@ -2064,6 +2078,7 @@ void System::ResetThrottler()
|
|||
|
||||
void System::Throttle()
|
||||
{
|
||||
#if 0
|
||||
// Allow variance of up to 40ms either way.
|
||||
#ifndef __ANDROID__
|
||||
static constexpr double MAX_VARIANCE_TIME_NS = 40 * 1000000;
|
||||
|
@ -2085,6 +2100,7 @@ void System::Throttle()
|
|||
ResetThrottler();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Common::Timer::SleepUntil(s_next_frame_time, true);
|
||||
}
|
||||
|
@ -2210,12 +2226,7 @@ void System::UpdateSpeedLimiterState()
|
|||
}
|
||||
}
|
||||
|
||||
const bool video_sync_enabled = ShouldUseVSync();
|
||||
const float max_display_fps = (!IsRunning() || m_throttler_enabled) ? 0.0f : g_settings.display_max_fps;
|
||||
Log_InfoPrintf("Target speed: %f%%", target_speed * 100.0f);
|
||||
Log_InfoPrintf("Using vsync: %s", video_sync_enabled ? "YES" : "NO");
|
||||
Log_InfoPrintf("Max display fps: %f (%s)", max_display_fps,
|
||||
m_display_all_frames ? "displaying all frames" : "skipping displaying frames when needed");
|
||||
Log_VerbosePrintf("Target speed: %f%%", s_target_speed * 100.0f);
|
||||
|
||||
if (IsValid())
|
||||
{
|
||||
|
@ -2235,23 +2246,36 @@ void System::UpdateSpeedLimiterState()
|
|||
ResetThrottler();
|
||||
}
|
||||
|
||||
g_host_display->SetDisplayMaxFPS(max_display_fps);
|
||||
g_host_display->SetVSync(video_sync_enabled);
|
||||
// Defer vsync update until we unpause, in case of fullscreen UI.
|
||||
if (IsRunning())
|
||||
UpdateDisplaySync();
|
||||
|
||||
if (g_settings.increase_timer_resolution)
|
||||
SetTimerResolutionIncreased(m_throttler_enabled);
|
||||
|
||||
// When syncing to host and using vsync, we don't need to sleep.
|
||||
if (syncing_to_host && video_sync_enabled && m_display_all_frames)
|
||||
if (syncing_to_host && ShouldUseVSync() && m_display_all_frames)
|
||||
{
|
||||
Log_InfoPrintf("Using host vsync for throttling.");
|
||||
m_throttler_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void System::UpdateDisplaySync()
|
||||
{
|
||||
const bool video_sync_enabled = ShouldUseVSync();
|
||||
const float max_display_fps = m_throttler_enabled ? 0.0f : g_settings.display_max_fps;
|
||||
Log_VerbosePrintf("Using vsync: %s", video_sync_enabled ? "YES" : "NO");
|
||||
Log_VerbosePrintf("Max display fps: %f (%s)", max_display_fps,
|
||||
m_display_all_frames ? "displaying all frames" : "skipping displaying frames when needed");
|
||||
|
||||
g_host_display->SetDisplayMaxFPS(max_display_fps);
|
||||
g_host_display->SetVSync(video_sync_enabled);
|
||||
}
|
||||
|
||||
bool System::ShouldUseVSync()
|
||||
{
|
||||
return (!IsRunning() || (m_throttler_enabled && g_settings.video_sync_enabled && !IsRunningAtNonStandardSpeed()));
|
||||
return g_settings.video_sync_enabled && !IsRunningAtNonStandardSpeed();
|
||||
}
|
||||
|
||||
bool System::IsFastForwardEnabled()
|
||||
|
|
|
@ -230,6 +230,9 @@ void Throttle();
|
|||
void UpdatePerformanceCounters();
|
||||
void ResetPerformanceCounters();
|
||||
|
||||
/// Resets vsync/max present fps state.
|
||||
void UpdateDisplaySync();
|
||||
|
||||
// Access controllers for simulating input.
|
||||
Controller* GetController(u32 slot);
|
||||
void UpdateControllers();
|
||||
|
|
|
@ -521,14 +521,14 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
|
|||
for (u32 i = 0; i < cinfo->num_settings; i++)
|
||||
{
|
||||
const SettingInfo& si = cinfo->settings[i];
|
||||
std::string key_name = si.key;
|
||||
std::string key_name = si.name;
|
||||
|
||||
switch (si.type)
|
||||
{
|
||||
case SettingInfo::Type::Boolean:
|
||||
{
|
||||
QCheckBox* cb = new QCheckBox(qApp->translate(cinfo->name, si.visible_name), this);
|
||||
cb->setObjectName(QString::fromUtf8(si.key));
|
||||
QCheckBox* cb = new QCheckBox(qApp->translate(cinfo->name, si.display_name), this);
|
||||
cb->setObjectName(QString::fromUtf8(si.name));
|
||||
ControllerSettingWidgetBinder::BindWidgetToInputProfileBool(sif, cb, section, std::move(key_name),
|
||||
si.BooleanDefaultValue());
|
||||
layout->addWidget(cb, current_row, 0, 1, 4);
|
||||
|
@ -539,12 +539,12 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
|
|||
case SettingInfo::Type::Integer:
|
||||
{
|
||||
QSpinBox* sb = new QSpinBox(this);
|
||||
sb->setObjectName(QString::fromUtf8(si.key));
|
||||
sb->setObjectName(QString::fromUtf8(si.name));
|
||||
sb->setMinimum(si.IntegerMinValue());
|
||||
sb->setMaximum(si.IntegerMaxValue());
|
||||
sb->setSingleStep(si.IntegerStepValue());
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, sb, section, std::move(key_name), si.IntegerDefaultValue());
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.visible_name), this), current_row, 0);
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
|
||||
layout->addWidget(sb, current_row, 1, 1, 3);
|
||||
current_row++;
|
||||
}
|
||||
|
@ -553,12 +553,12 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
|
|||
case SettingInfo::Type::Float:
|
||||
{
|
||||
QDoubleSpinBox* sb = new QDoubleSpinBox(this);
|
||||
sb->setObjectName(QString::fromUtf8(si.key));
|
||||
sb->setObjectName(QString::fromUtf8(si.name));
|
||||
sb->setMinimum(si.FloatMinValue());
|
||||
sb->setMaximum(si.FloatMaxValue());
|
||||
sb->setSingleStep(si.FloatStepValue());
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(sif, sb, section, std::move(key_name), si.FloatDefaultValue());
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.visible_name), this), current_row, 0);
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
|
||||
layout->addWidget(sb, current_row, 1, 1, 3);
|
||||
current_row++;
|
||||
}
|
||||
|
@ -567,9 +567,9 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
|
|||
case SettingInfo::Type::String:
|
||||
{
|
||||
QLineEdit* le = new QLineEdit(this);
|
||||
le->setObjectName(QString::fromUtf8(si.key));
|
||||
le->setObjectName(QString::fromUtf8(si.name));
|
||||
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, section, std::move(key_name), si.StringDefaultValue());
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.visible_name), this), current_row, 0);
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
|
||||
layout->addWidget(le, current_row, 1, 1, 3);
|
||||
current_row++;
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
|
|||
case SettingInfo::Type::Path:
|
||||
{
|
||||
QLineEdit* le = new QLineEdit(this);
|
||||
le->setObjectName(QString::fromUtf8(si.key));
|
||||
le->setObjectName(QString::fromUtf8(si.name));
|
||||
QPushButton* browse_button = new QPushButton(tr("Browse..."), this);
|
||||
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, section, std::move(key_name), si.StringDefaultValue());
|
||||
connect(browse_button, &QPushButton::clicked, [this, le]() {
|
||||
|
@ -591,7 +591,7 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
|
|||
hbox->addWidget(le, 1);
|
||||
hbox->addWidget(browse_button);
|
||||
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.visible_name), this), current_row, 0);
|
||||
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
|
||||
layout->addLayout(hbox, current_row, 1, 1, 3);
|
||||
current_row++;
|
||||
}
|
||||
|
@ -615,13 +615,13 @@ void ControllerCustomSettingsWidget::restoreDefaults()
|
|||
for (u32 i = 0; i < cinfo->num_settings; i++)
|
||||
{
|
||||
const SettingInfo& si = cinfo->settings[i];
|
||||
const QString key(QString::fromStdString(si.key));
|
||||
const QString key(QString::fromStdString(si.name));
|
||||
|
||||
switch (si.type)
|
||||
{
|
||||
case SettingInfo::Type::Boolean:
|
||||
{
|
||||
QCheckBox* widget = findChild<QCheckBox*>(QString::fromStdString(si.key));
|
||||
QCheckBox* widget = findChild<QCheckBox*>(QString::fromStdString(si.name));
|
||||
if (widget)
|
||||
widget->setChecked(si.BooleanDefaultValue());
|
||||
}
|
||||
|
@ -629,7 +629,7 @@ void ControllerCustomSettingsWidget::restoreDefaults()
|
|||
|
||||
case SettingInfo::Type::Integer:
|
||||
{
|
||||
QSpinBox* widget = findChild<QSpinBox*>(QString::fromStdString(si.key));
|
||||
QSpinBox* widget = findChild<QSpinBox*>(QString::fromStdString(si.name));
|
||||
if (widget)
|
||||
widget->setValue(si.IntegerDefaultValue());
|
||||
}
|
||||
|
@ -637,7 +637,7 @@ void ControllerCustomSettingsWidget::restoreDefaults()
|
|||
|
||||
case SettingInfo::Type::Float:
|
||||
{
|
||||
QDoubleSpinBox* widget = findChild<QDoubleSpinBox*>(QString::fromStdString(si.key));
|
||||
QDoubleSpinBox* widget = findChild<QDoubleSpinBox*>(QString::fromStdString(si.name));
|
||||
if (widget)
|
||||
widget->setValue(si.FloatDefaultValue());
|
||||
}
|
||||
|
@ -645,7 +645,7 @@ void ControllerCustomSettingsWidget::restoreDefaults()
|
|||
|
||||
case SettingInfo::Type::String:
|
||||
{
|
||||
QLineEdit* widget = findChild<QLineEdit*>(QString::fromStdString(si.key));
|
||||
QLineEdit* widget = findChild<QLineEdit*>(QString::fromStdString(si.name));
|
||||
if (widget)
|
||||
widget->setText(QString::fromUtf8(si.StringDefaultValue()));
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ void ControllerCustomSettingsWidget::restoreDefaults()
|
|||
|
||||
case SettingInfo::Type::Path:
|
||||
{
|
||||
QLineEdit* widget = findChild<QLineEdit*>(QString::fromStdString(si.key));
|
||||
QLineEdit* widget = findChild<QLineEdit*>(QString::fromStdString(si.name));
|
||||
if (widget)
|
||||
widget->setText(QString::fromUtf8(si.StringDefaultValue()));
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ static void DeactivateAchievement(Achievement* achievement);
|
|||
static void SendPing();
|
||||
static void SendPlaying();
|
||||
static void UpdateRichPresence();
|
||||
static Achievement* GetAchievementByID(u32 id);
|
||||
static Achievement* GetMutableAchievementByID(u32 id);
|
||||
static void ClearGameInfo(bool clear_achievements = true, bool clear_leaderboards = true);
|
||||
static void ClearGameHash();
|
||||
static std::string GetUserAgent();
|
||||
|
@ -80,6 +80,7 @@ static void GetLbInfoCallback(s32 status_code, Common::HTTPDownloader::Request::
|
|||
static void GetPatches(u32 game_id);
|
||||
static std::string GetGameHash(CDImage* image);
|
||||
static void SetChallengeMode(bool enabled);
|
||||
static void SendGetGameId();
|
||||
static void GetGameIdCallback(s32 status_code, Common::HTTPDownloader::Request::Data data);
|
||||
static void SendPlayingCallback(s32 status_code, Common::HTTPDownloader::Request::Data data);
|
||||
static void UpdateRichPresence();
|
||||
|
@ -205,6 +206,18 @@ public:
|
|||
Achievements::DownloadImage(api_request.url, std::move(cache_filename));
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetURL()
|
||||
{
|
||||
const int error = InitFunc(&api_request, this);
|
||||
if (error != RC_OK)
|
||||
{
|
||||
FormattedError("%s failed: error %d (%s)", RAPIStructName<T>(), error, rc_error_str(error));
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return api_request.url;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int (*ParseFunc)(T*, const char*), void (*DestroyFunc)(T*)>
|
||||
|
@ -278,7 +291,18 @@ void Achievements::LogFailedResponseJSON(const Common::HTTPDownloader::Request::
|
|||
Log_ErrorPrintf("API call failed. Response JSON was:\n%s", str_data.c_str());
|
||||
}
|
||||
|
||||
static Achievements::Achievement* Achievements::GetAchievementByID(u32 id)
|
||||
const Achievements::Achievement* Achievements::GetAchievementByID(u32 id)
|
||||
{
|
||||
for (const Achievement& ach : s_achievements)
|
||||
{
|
||||
if (ach.id == id)
|
||||
return &ach;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Achievements::Achievement* Achievements::GetMutableAchievementByID(u32 id)
|
||||
{
|
||||
for (Achievement& ach : s_achievements)
|
||||
{
|
||||
|
@ -420,7 +444,7 @@ void Achievements::Initialize()
|
|||
s_api_token = Host::GetBaseStringSettingValue("Cheevos", "Token");
|
||||
s_logged_in = (!s_username.empty() && !s_api_token.empty());
|
||||
|
||||
if (IsLoggedIn() && System::IsValid())
|
||||
if (System::IsValid())
|
||||
GameChanged(System::GetRunningPath(), nullptr);
|
||||
}
|
||||
|
||||
|
@ -742,6 +766,7 @@ bool Achievements::DoState(StateWrapper& sw)
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// internally this happens twice.. not great.
|
||||
const int size = rc_runtime_progress_size(&s_rcheevos_runtime, nullptr);
|
||||
|
@ -757,7 +782,6 @@ bool Achievements::DoState(StateWrapper& sw)
|
|||
data_size = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sw.Do(&data_size);
|
||||
if (data_size > 0)
|
||||
|
@ -829,8 +853,8 @@ void Achievements::LoginCallback(s32 status_code, Common::HTTPDownloader::Reques
|
|||
s_logged_in = true;
|
||||
|
||||
// If we have a game running, set it up.
|
||||
if (System::IsValid())
|
||||
GameChanged(System::GetRunningPath(), nullptr);
|
||||
if (!s_game_hash.empty())
|
||||
SendGetGameId();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -968,7 +992,10 @@ void Achievements::DisplayAchievementSummary()
|
|||
}
|
||||
}
|
||||
|
||||
ImGuiFullscreen::AddNotification(10.0f, std::move(title), std::move(summary), s_game_icon);
|
||||
Host::RunOnCPUThread([title = std::move(title), summary = std::move(summary), icon = s_game_icon]() {
|
||||
if (FullscreenUI::IsInitialized())
|
||||
ImGuiFullscreen::AddNotification(10.0f, std::move(title), std::move(summary), std::move(icon));
|
||||
});
|
||||
}
|
||||
|
||||
void Achievements::GetUserUnlocksCallback(s32 status_code, Common::HTTPDownloader::Request::Data data)
|
||||
|
@ -990,7 +1017,7 @@ void Achievements::GetUserUnlocksCallback(s32 status_code, Common::HTTPDownloade
|
|||
// flag achievements as unlocked
|
||||
for (u32 i = 0; i < response.num_achievement_ids; i++)
|
||||
{
|
||||
Achievement* cheevo = GetAchievementByID(response.achievement_ids[i]);
|
||||
Achievement* cheevo = GetMutableAchievementByID(response.achievement_ids[i]);
|
||||
if (!cheevo)
|
||||
{
|
||||
Log_ErrorPrintf("Server returned unknown achievement %u", response.achievement_ids[i]);
|
||||
|
@ -1075,7 +1102,7 @@ void Achievements::GetPatchesCallback(s32 status_code, Common::HTTPDownloader::R
|
|||
continue;
|
||||
}
|
||||
|
||||
if (GetAchievementByID(defn.id))
|
||||
if (GetMutableAchievementByID(defn.id))
|
||||
{
|
||||
Log_ErrorPrintf("Achievement %u already exists", defn.id);
|
||||
continue;
|
||||
|
@ -1351,6 +1378,12 @@ void Achievements::GameChanged(const std::string& path, CDImage* image)
|
|||
return;
|
||||
}
|
||||
|
||||
if (IsLoggedIn())
|
||||
SendGetGameId();
|
||||
}
|
||||
|
||||
void Achievements::SendGetGameId()
|
||||
{
|
||||
RAPIRequest<rc_api_resolve_hash_request_t, rc_api_init_resolve_hash_request> request;
|
||||
request.username = s_username.c_str();
|
||||
request.api_token = s_api_token.c_str();
|
||||
|
@ -1643,7 +1676,7 @@ void Achievements::SubmitLeaderboardCallback(s32 status_code, Common::HTTPDownlo
|
|||
|
||||
void Achievements::UnlockAchievement(u32 achievement_id, bool add_notification /* = true*/)
|
||||
{
|
||||
Achievement* achievement = GetAchievementByID(achievement_id);
|
||||
Achievement* achievement = GetMutableAchievementByID(achievement_id);
|
||||
if (!achievement)
|
||||
{
|
||||
Log_ErrorPrintf("Attempting to unlock unknown achievement %u", achievement_id);
|
||||
|
@ -1740,7 +1773,7 @@ std::string Achievements::GetAchievementProgressText(const Achievement& achievem
|
|||
return buf;
|
||||
}
|
||||
|
||||
const std::string& Achievements::GetAchievementBadgePath(const Achievement& achievement)
|
||||
const std::string& Achievements::GetAchievementBadgePath(const Achievement& achievement, bool download_if_missing)
|
||||
{
|
||||
std::string& badge_path = achievement.locked ? achievement.locked_badge_path : achievement.unlocked_badge_path;
|
||||
if (!badge_path.empty() || achievement.badge_name.empty())
|
||||
|
@ -1754,11 +1787,23 @@ const std::string& Achievements::GetAchievementBadgePath(const Achievement& achi
|
|||
return badge_path;
|
||||
|
||||
// need to download it
|
||||
if (download_if_missing)
|
||||
{
|
||||
RAPIRequest<rc_api_fetch_image_request_t, rc_api_init_fetch_image_request> request;
|
||||
request.image_name = achievement.badge_name.c_str();
|
||||
request.image_type = achievement.locked ? RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED : RC_IMAGE_TYPE_ACHIEVEMENT;
|
||||
request.DownloadImage(badge_path);
|
||||
}
|
||||
|
||||
return badge_path;
|
||||
}
|
||||
|
||||
std::string Achievements::GetAchievementBadgeURL(const Achievement& achievement)
|
||||
{
|
||||
RAPIRequest<rc_api_fetch_image_request_t, rc_api_init_fetch_image_request> request;
|
||||
request.image_name = achievement.badge_name.c_str();
|
||||
request.image_type = achievement.locked ? RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED : RC_IMAGE_TYPE_ACHIEVEMENT;
|
||||
request.DownloadImage(badge_path);
|
||||
return badge_path;
|
||||
return request.GetURL();
|
||||
}
|
||||
|
||||
void Achievements::CheevosEventHandler(const rc_runtime_event_t* runtime_event)
|
||||
|
|
|
@ -143,9 +143,11 @@ const Leaderboard* GetLeaderboardByID(u32 id);
|
|||
u32 GetLeaderboardCount();
|
||||
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
|
||||
|
||||
const Achievement* GetAchievementByID(u32 id);
|
||||
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
|
||||
std::string GetAchievementProgressText(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(const Achievement& achievement, bool download_if_missing = true);
|
||||
std::string GetAchievementBadgeURL(const Achievement& achievement);
|
||||
|
||||
void UnlockAchievement(u32 achievement_id, bool add_notification = true);
|
||||
void SubmitLeaderboard(u32 leaderboard_id, int value);
|
||||
|
|
|
@ -358,7 +358,7 @@ void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/,
|
|||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoBackground))
|
||||
{
|
||||
HostDisplayTexture* tex = ImGuiFullscreen::GetCachedTexture("fullscreenui/duck.png");
|
||||
HostDisplayTexture* tex = ImGuiFullscreen::GetCachedTexture("images/duck.png");
|
||||
if (tex)
|
||||
ImGui::Image(tex->GetHandle(), ImVec2(logo_width, logo_height));
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ using ImGuiFullscreen::ThreeWayToggleButton;
|
|||
using ImGuiFullscreen::ToggleButton;
|
||||
using ImGuiFullscreen::WantsToCloseMenu;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
namespace FullscreenUI {
|
||||
enum class MainWindowType
|
||||
{
|
||||
|
@ -159,11 +160,6 @@ enum class SettingsPage
|
|||
Count
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Utility
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static std::string TimeToPrintableString(time_t t);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Main
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -388,24 +384,6 @@ static std::optional<u32> s_open_leaderboard_id;
|
|||
#endif
|
||||
} // namespace FullscreenUI
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Utility
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string FullscreenUI::TimeToPrintableString(time_t t)
|
||||
{
|
||||
struct tm lt = {};
|
||||
#ifdef _MSC_VER
|
||||
localtime_s(<, &t);
|
||||
#else
|
||||
localtime_r(&t, <);
|
||||
#endif
|
||||
|
||||
char buf[256];
|
||||
std::strftime(buf, sizeof(buf), "%c", <);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Main
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -421,7 +399,7 @@ bool FullscreenUI::Initialize()
|
|||
ImGuiFullscreen::SetTheme();
|
||||
ImGuiFullscreen::UpdateLayoutScale();
|
||||
|
||||
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("fullscreenui/placeholder.png") ||
|
||||
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("images/placeholder.png") ||
|
||||
!LoadResources())
|
||||
{
|
||||
DestroyResources();
|
||||
|
@ -437,7 +415,6 @@ bool FullscreenUI::Initialize()
|
|||
s_was_paused_on_quick_menu_open = false;
|
||||
s_about_window_open = false;
|
||||
s_hotkey_list_cache = InputManager::GetHotkeyList();
|
||||
// GetMTGS().SetRunIdle(true);
|
||||
|
||||
if (!System::IsValid())
|
||||
SwitchToLanding();
|
||||
|
@ -467,15 +444,14 @@ void FullscreenUI::OnSystemStarted()
|
|||
|
||||
void FullscreenUI::OnSystemPaused()
|
||||
{
|
||||
if (!IsInitialized())
|
||||
return;
|
||||
|
||||
g_host_display->SetVSync(true);
|
||||
// noop
|
||||
}
|
||||
|
||||
void FullscreenUI::OnSystemResumed()
|
||||
{
|
||||
// noop
|
||||
// get rid of pause menu if we unpaused another way
|
||||
if (s_current_main_window == MainWindowType::PauseMenu)
|
||||
ClosePauseMenu();
|
||||
}
|
||||
|
||||
void FullscreenUI::OnSystemDestroyed()
|
||||
|
@ -505,7 +481,15 @@ void FullscreenUI::PauseForMenuOpen()
|
|||
{
|
||||
s_was_paused_on_quick_menu_open = (System::GetState() == System::State::Paused);
|
||||
if (g_settings.pause_on_menu && !s_was_paused_on_quick_menu_open)
|
||||
Host::RunOnCPUThread([]() { System::PauseSystem(true); });
|
||||
{
|
||||
Host::RunOnCPUThread([]() {
|
||||
System::PauseSystem(true);
|
||||
|
||||
// force vsync on when pausing
|
||||
if (g_host_display)
|
||||
g_host_display->SetVSync(true);
|
||||
});
|
||||
}
|
||||
|
||||
s_pause_menu_was_open = true;
|
||||
}
|
||||
|
@ -635,7 +619,7 @@ void FullscreenUI::ReturnToMainWindow()
|
|||
|
||||
bool FullscreenUI::LoadResources()
|
||||
{
|
||||
s_app_icon_texture = LoadTexture("fullscreenui/duck.png");
|
||||
s_app_icon_texture = LoadTexture("images/duck.png");
|
||||
|
||||
s_fallback_disc_texture = LoadTexture("fullscreenui/media-cdrom.png");
|
||||
s_fallback_exe_texture = LoadTexture("fullscreenui/applications-system.png");
|
||||
|
@ -5796,3 +5780,104 @@ void DrawDebugDebugMenu()
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// "Lightweight" version with only notifications for Android.
|
||||
namespace FullscreenUI {
|
||||
static bool s_initialized = false;
|
||||
static bool s_tried_to_initialize = false;
|
||||
}
|
||||
|
||||
bool FullscreenUI::Initialize()
|
||||
{
|
||||
if (s_initialized)
|
||||
return true;
|
||||
|
||||
if (s_tried_to_initialize)
|
||||
return false;
|
||||
|
||||
ImGuiFullscreen::SetTheme();
|
||||
ImGuiFullscreen::UpdateLayoutScale();
|
||||
|
||||
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("images/placeholder.png"))
|
||||
{
|
||||
ImGuiFullscreen::Shutdown();
|
||||
s_tried_to_initialize = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
s_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FullscreenUI::IsInitialized()
|
||||
{
|
||||
return s_initialized;
|
||||
}
|
||||
|
||||
bool FullscreenUI::HasActiveWindow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void FullscreenUI::OnSystemStarted()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void FullscreenUI::OnSystemPaused()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void FullscreenUI::OnSystemResumed()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void FullscreenUI::OnSystemDestroyed()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void FullscreenUI::OnRunningGameChanged()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
void FullscreenUI::OpenPauseMenu()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
bool FullscreenUI::OpenAchievementsWindow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FullscreenUI::OpenLeaderboardsWindow()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void FullscreenUI::Shutdown()
|
||||
{
|
||||
ImGuiFullscreen::Shutdown();
|
||||
s_initialized = false;
|
||||
s_tried_to_initialize = false;
|
||||
}
|
||||
|
||||
void FullscreenUI::Render()
|
||||
{
|
||||
if (!s_initialized)
|
||||
return;
|
||||
|
||||
ImGuiFullscreen::UploadAsyncTextures();
|
||||
|
||||
ImGuiFullscreen::BeginLayout();
|
||||
ImGuiFullscreen::EndLayout();
|
||||
ImGuiFullscreen::ResetCloseMenuIfNeeded();
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
|
|
|
@ -114,7 +114,7 @@ bool GameList::GetExeListEntry(const std::string& path, GameList::Entry* entry)
|
|||
|
||||
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
|
||||
entry->serial.clear();
|
||||
entry->title = Path::StripExtension(display_name);
|
||||
entry->title = Path::GetFileTitle(display_name);
|
||||
entry->region = BIOS::GetPSExeDiscRegion(header);
|
||||
entry->total_size = ZeroExtend64(file_size);
|
||||
entry->type = EntryType::PSExe;
|
||||
|
@ -156,7 +156,7 @@ bool GameList::GetPsfListEntry(const std::string& path, Entry* entry)
|
|||
else
|
||||
{
|
||||
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
|
||||
entry->title += Path::StripExtension(display_name);
|
||||
entry->title += Path::GetFileTitle(display_name);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -193,7 +193,7 @@ bool GameList::GetDiscListEntry(const std::string& path, Entry* entry)
|
|||
}
|
||||
else
|
||||
{
|
||||
const std::string display_name(Path::GetFileTitle(FileSystem::GetDisplayNameFromPath(path)));
|
||||
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
|
||||
|
||||
// no game code, so use the filename title
|
||||
entry->serial = System::GetGameCodeForImage(cdi.get(), true);
|
||||
|
|
Loading…
Reference in New Issue