mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
feeced81d2
* window: auto-hide the cursor over the game window Hide the cursor when the game window is created and whenever the mouse has been idle for two seconds; any mouse motion, button or wheel event shows it again. Games that draw their own cursor (e.g. Blue Prince) no longer show the host pointer on top of it. Only real mouse input counts as activity: synthetic touch/pen mouse events and zero-delta motion (sent by some platforms on focus or cursor visibility changes) are ignored. The event loop only waits with a timeout while the cursor is visible, so it still blocks indefinitely once the cursor is hidden. The cursor is restored on shutdown. Uses SDL_HideCursor/SDL_ShowCursor, which SDL implements for X11, Wayland, Cocoa and Win32 and which only affect the cursor over the emulator window. Closes #282 * window: make cursor auto-hide optional in CLI and launcher Co-authored-by: Anatolii Kucheruk <anatolii.kucheruk01@gmail.com> --------- Co-authored-by: nmzik <Nmzik@mail.ru> Co-authored-by: Anatolii Kucheruk <anatolii.kucheruk01@gmail.com>
276 lines
10 KiB
C++
276 lines
10 KiB
C++
#ifndef LAUNCHER_INCLUDE_CONFIGURATION_H_
|
|
#define LAUNCHER_INCLUDE_CONFIGURATION_H_
|
|
|
|
#include "common/emulatorConfig.h"
|
|
|
|
#include <QByteArray>
|
|
#include <QChar>
|
|
#include <QColor>
|
|
#include <QMetaEnum>
|
|
#include <QMetaType>
|
|
#include <QObject>
|
|
#include <QSettings>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <QVariant>
|
|
|
|
#define KYTY_CFG_SET(n) s->setValue(#n, QVariant::fromValue(n).toString());
|
|
#define KYTY_CFG_GET(n) n = s->value(#n).value<decltype(n)>();
|
|
|
|
template <class T>
|
|
inline QStringList EnumToList() {
|
|
QStringList ret;
|
|
auto me = QMetaEnum::fromType<T>();
|
|
int count = me.keyCount();
|
|
for (int i = 0; i < count; i++) {
|
|
auto key = QString(me.key(i));
|
|
ret << (key.startsWith('R') && key.size() > 2 && key.at(1).isDigit()
|
|
? key.remove('R').toLower()
|
|
: key);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
template <class T>
|
|
T TextToEnum(const QString& text) {
|
|
auto me = QMetaEnum::fromType<T>();
|
|
return static_cast<T>(me.keyToValue(
|
|
((text.size() > 1 && text.at(0).isDigit()) ? 'R' + text.toUpper() : text).toUtf8().data()));
|
|
}
|
|
|
|
template <class T>
|
|
QString EnumToText(T value) {
|
|
auto me = QMetaEnum::fromType<T>();
|
|
auto key = QString(me.valueToKey(static_cast<int>(value)));
|
|
return (key.startsWith('R') && key.size() > 2 && key.at(1).isDigit() ? key.remove('R').toLower()
|
|
: key);
|
|
}
|
|
|
|
struct ControllerSettings {
|
|
QString color;
|
|
int speaker_volume = 100;
|
|
int vibration_intensity = 100;
|
|
|
|
void WriteSettings(QSettings* s) const {
|
|
s->setValue("controller_color", color);
|
|
s->setValue("controller_speaker_volume", speaker_volume);
|
|
s->setValue("controller_vibration_intensity", vibration_intensity);
|
|
}
|
|
|
|
void ReadSettings(QSettings* s) {
|
|
const QColor saved_color(s->value("controller_color").toString());
|
|
color = saved_color.isValid() ? saved_color.name(QColor::HexRgb) : QString {};
|
|
const auto read_percent = [s](const char* key) {
|
|
bool ok = false;
|
|
const int value = s->value(key, 100).toInt(&ok);
|
|
return ok ? qBound(0, value, 100) : 100;
|
|
};
|
|
speaker_volume = read_percent("controller_speaker_volume");
|
|
vibration_intensity = read_percent("controller_vibration_intensity");
|
|
}
|
|
};
|
|
|
|
class Configuration: public QObject {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
static constexpr int DEFAULT_CONSOLE_LANGUAGE = 1;
|
|
static constexpr int MAX_CONSOLE_LANGUAGE = 29;
|
|
|
|
enum class Resolution {
|
|
R1280X720,
|
|
R1920X1080,
|
|
R2560X1440,
|
|
R3840X2160,
|
|
};
|
|
Q_ENUM(Resolution)
|
|
|
|
enum class ShaderOptimizationType { None, Size, Performance };
|
|
Q_ENUM(ShaderOptimizationType)
|
|
|
|
enum class PresentMode { Fifo, Mailbox, Immediate };
|
|
Q_ENUM(PresentMode)
|
|
|
|
enum class LogDirection { Silent, Console, File };
|
|
Q_ENUM(LogDirection)
|
|
|
|
enum class GameStatus { Unknown, InGame, Logo, DoesntBoot, MainMenu };
|
|
Q_ENUM(GameStatus)
|
|
|
|
Configuration() = default;
|
|
|
|
QString name;
|
|
QString title_id; /* Serial / title id from sce_sys/param.json */
|
|
QString gameVersion; /* appVersion / contentVersion from sce_sys/param.json */
|
|
QString firmwareVer; /* requiredSystemSoftwareVersion from sce_sys/param.json */
|
|
QString basedir; /* Game base directory */
|
|
QString game_path; /* Launcher-unique game path */
|
|
bool custom_settings = false;
|
|
GameStatus game_status = GameStatus::Unknown;
|
|
QString game_comment;
|
|
|
|
// Controller preferences always come from the global configuration.
|
|
ControllerSettings controller;
|
|
|
|
Resolution screen_resolution = Resolution::R1280X720;
|
|
QString user_name = "Kyty";
|
|
int user_id = Config::DEFAULT_USER_ID;
|
|
QString audio_input_device;
|
|
PresentMode present_mode = PresentMode::Mailbox;
|
|
int gpu_index = -1;
|
|
bool fullscreen_enabled = false;
|
|
bool hide_cursor_enabled = false;
|
|
bool readback_linear_images = false;
|
|
bool tessellation_enabled = false;
|
|
int vblank_frequency = 60;
|
|
int console_language = DEFAULT_CONSOLE_LANGUAGE;
|
|
bool vulkan_validation_enabled = false;
|
|
bool shader_validation_enabled = true;
|
|
ShaderOptimizationType shader_optimization_type = ShaderOptimizationType::Performance;
|
|
LogDirection shader_log_direction = LogDirection::Silent;
|
|
QString shader_log_folder = "_Shaders";
|
|
bool command_buffer_dump_enabled = false;
|
|
QString command_buffer_dump_folder = "_Buffers";
|
|
LogDirection printf_direction = LogDirection::Silent;
|
|
QString printf_output_file = "_kyty.txt";
|
|
bool profiler_enabled = false;
|
|
bool renderdoc_enabled = false;
|
|
bool amd_cpu_enabled = false;
|
|
#if defined(_WIN32)
|
|
bool red_zone_protection_enabled = false;
|
|
#endif
|
|
QStringList host_input_mapping;
|
|
|
|
QString elf = QStringLiteral("eboot.bin");
|
|
|
|
void CopyEmulatorSettingsFrom(const Configuration& other) {
|
|
screen_resolution = other.screen_resolution;
|
|
user_name = other.user_name;
|
|
user_id = other.user_id;
|
|
audio_input_device = other.audio_input_device;
|
|
present_mode = other.present_mode;
|
|
gpu_index = other.gpu_index;
|
|
fullscreen_enabled = other.fullscreen_enabled;
|
|
hide_cursor_enabled = other.hide_cursor_enabled;
|
|
readback_linear_images = other.readback_linear_images;
|
|
tessellation_enabled = other.tessellation_enabled;
|
|
vblank_frequency = other.vblank_frequency;
|
|
console_language = other.console_language;
|
|
vulkan_validation_enabled = other.vulkan_validation_enabled;
|
|
shader_validation_enabled = other.shader_validation_enabled;
|
|
shader_optimization_type = other.shader_optimization_type;
|
|
shader_log_direction = other.shader_log_direction;
|
|
shader_log_folder = other.shader_log_folder;
|
|
command_buffer_dump_enabled = other.command_buffer_dump_enabled;
|
|
command_buffer_dump_folder = other.command_buffer_dump_folder;
|
|
printf_direction = other.printf_direction;
|
|
printf_output_file = other.printf_output_file;
|
|
profiler_enabled = other.profiler_enabled;
|
|
renderdoc_enabled = other.renderdoc_enabled;
|
|
amd_cpu_enabled = other.amd_cpu_enabled;
|
|
#if defined(_WIN32)
|
|
red_zone_protection_enabled = other.red_zone_protection_enabled;
|
|
#endif
|
|
host_input_mapping = other.host_input_mapping;
|
|
}
|
|
|
|
void CopyGameInfoFrom(const Configuration& other) {
|
|
name = other.name;
|
|
title_id = other.title_id;
|
|
gameVersion = other.gameVersion;
|
|
firmwareVer = other.firmwareVer;
|
|
basedir = other.basedir;
|
|
game_path = other.game_path;
|
|
custom_settings = other.custom_settings;
|
|
game_status = other.game_status;
|
|
game_comment = other.game_comment;
|
|
}
|
|
|
|
void WriteSettings(QSettings* s) const {
|
|
KYTY_CFG_SET(name);
|
|
KYTY_CFG_SET(basedir);
|
|
KYTY_CFG_SET(game_path);
|
|
KYTY_CFG_SET(custom_settings);
|
|
KYTY_CFG_SET(screen_resolution);
|
|
KYTY_CFG_SET(user_name);
|
|
KYTY_CFG_SET(user_id);
|
|
KYTY_CFG_SET(audio_input_device);
|
|
KYTY_CFG_SET(present_mode);
|
|
KYTY_CFG_SET(gpu_index);
|
|
KYTY_CFG_SET(fullscreen_enabled);
|
|
KYTY_CFG_SET(hide_cursor_enabled);
|
|
KYTY_CFG_SET(readback_linear_images);
|
|
KYTY_CFG_SET(tessellation_enabled);
|
|
KYTY_CFG_SET(vblank_frequency);
|
|
KYTY_CFG_SET(console_language);
|
|
KYTY_CFG_SET(vulkan_validation_enabled);
|
|
KYTY_CFG_SET(shader_validation_enabled);
|
|
KYTY_CFG_SET(shader_optimization_type);
|
|
KYTY_CFG_SET(shader_log_direction);
|
|
KYTY_CFG_SET(shader_log_folder);
|
|
KYTY_CFG_SET(command_buffer_dump_enabled);
|
|
KYTY_CFG_SET(command_buffer_dump_folder);
|
|
KYTY_CFG_SET(printf_direction);
|
|
KYTY_CFG_SET(printf_output_file);
|
|
KYTY_CFG_SET(profiler_enabled);
|
|
KYTY_CFG_SET(renderdoc_enabled);
|
|
KYTY_CFG_SET(amd_cpu_enabled);
|
|
#if defined(_WIN32)
|
|
KYTY_CFG_SET(red_zone_protection_enabled);
|
|
#endif
|
|
s->setValue("host_input_mapping", host_input_mapping);
|
|
KYTY_CFG_SET(elf);
|
|
}
|
|
|
|
void ReadSettings(QSettings* s) {
|
|
KYTY_CFG_GET(name);
|
|
KYTY_CFG_GET(basedir);
|
|
KYTY_CFG_GET(game_path);
|
|
KYTY_CFG_GET(custom_settings);
|
|
KYTY_CFG_GET(screen_resolution);
|
|
user_name = s->value("user_name", user_name).toString();
|
|
bool user_id_ok = false;
|
|
auto saved_user_id = s->value("user_id", user_id).toInt(&user_id_ok);
|
|
user_id = user_id_ok && Config::IsConfiguredUserIdValid(saved_user_id)
|
|
? saved_user_id
|
|
: Config::DEFAULT_USER_ID;
|
|
audio_input_device = s->value("audio_input_device", audio_input_device).toString();
|
|
KYTY_CFG_GET(present_mode);
|
|
gpu_index = s->value("gpu_index", -1).toInt();
|
|
if (EnumToText(present_mode).isEmpty()) {
|
|
present_mode = PresentMode::Mailbox;
|
|
}
|
|
KYTY_CFG_GET(fullscreen_enabled);
|
|
KYTY_CFG_GET(hide_cursor_enabled);
|
|
KYTY_CFG_GET(readback_linear_images);
|
|
KYTY_CFG_GET(tessellation_enabled);
|
|
vblank_frequency = s->value("vblank_frequency", vblank_frequency).toInt();
|
|
console_language = s->value("console_language", console_language).toInt();
|
|
if (console_language < 0 || console_language > MAX_CONSOLE_LANGUAGE) {
|
|
console_language = DEFAULT_CONSOLE_LANGUAGE;
|
|
}
|
|
KYTY_CFG_GET(vulkan_validation_enabled);
|
|
KYTY_CFG_GET(shader_validation_enabled);
|
|
KYTY_CFG_GET(shader_optimization_type);
|
|
KYTY_CFG_GET(shader_log_direction);
|
|
KYTY_CFG_GET(shader_log_folder);
|
|
KYTY_CFG_GET(command_buffer_dump_enabled);
|
|
KYTY_CFG_GET(command_buffer_dump_folder);
|
|
KYTY_CFG_GET(printf_direction);
|
|
KYTY_CFG_GET(printf_output_file);
|
|
KYTY_CFG_GET(profiler_enabled);
|
|
KYTY_CFG_GET(renderdoc_enabled);
|
|
amd_cpu_enabled = s->value("amd_cpu_enabled", false).toBool();
|
|
#if defined(_WIN32)
|
|
red_zone_protection_enabled =
|
|
s->value("red_zone_protection_enabled", red_zone_protection_enabled).toBool();
|
|
#endif
|
|
host_input_mapping = s->value("host_input_mapping", host_input_mapping).toStringList();
|
|
elf = s->value("elf", elf).toString();
|
|
}
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(Configuration*)
|
|
|
|
#endif /* LAUNCHER_INCLUDE_CONFIGURATION_H_ */
|