mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
69fdb03dc2
* launcher: add minimize and maximize buttons to the main window
The main window is a QDialog, which on Windows only gets a close button.
* graphics: keep the game's aspect ratio when presenting to the window
The guest frame was blitted across the whole swapchain image, so a window
or fullscreen display whose shape differs from the frame stretched the
picture. Fit the frame inside the window instead and clear the remaining
bars to black. The video-out overlay layer is drawn into the same
rectangle so it stays aligned with the frame underneath.
* launcher: accept custom screen resolutions such as 21:9
The resolution was a fixed enum of four 16:9 sizes. Make the combo box
editable so any WIDTHxHEIGHT between 320 and 16384 can be entered, and
add ultrawide presets (2560x1080, 3440x1440, 3840x1600, 5120x2160).
Settings saved by older launchers stored the enum key ("R1920X1080");
NormalizeResolution still accepts that form, so they load unchanged.
* launcher: add a Stretch to window option
Presentation now keeps the game's aspect ratio with black bars. Add
--stretch to fill the whole window as before, exposed in the launcher as
a "Stretch to window" checkbox under General, off by default.
* launcher: make the settings dialog resizable and its tabs scrollable
The dialog had no maximize button and pinned its minimum width to its
initial 900 px, and without scroll areas it could not be made shorter
than its content. Add a maximize button (not minimize, since the dialog
is modal), drop the width pin, and wrap each tab page in a frameless
scroll area.
With the scroll areas the layout's minimum size no longer forces the
dialog open, so size it explicitly: grow it to fit the largest tab,
capped at the available screen, when there is no saved geometry and
whenever the global settings add the game folders panel.
* launcher: simplify display options and preserve saved settings
---------
Co-authored-by: nmzik <Nmzik@mail.ru>
221 lines
8.8 KiB
C++
221 lines
8.8 KiB
C++
#ifndef LAUNCHER_INCLUDE_CONFIGURATION_H_
|
|
#define LAUNCHER_INCLUDE_CONFIGURATION_H_
|
|
|
|
#include "common/emulatorConfig.h"
|
|
|
|
#include <QByteArray>
|
|
#include <QChar>
|
|
#include <QColor>
|
|
#include <QJsonObject>
|
|
#include <QMetaEnum>
|
|
#include <QMetaType>
|
|
#include <QObject>
|
|
#include <QSettings>
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <QVariant>
|
|
|
|
template <class T>
|
|
inline QStringList EnumToList() {
|
|
QStringList ret;
|
|
auto me = QMetaEnum::fromType<T>();
|
|
int count = me.keyCount();
|
|
for (int i = 0; i < count; i++) {
|
|
ret << QString(me.key(i));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
template <class T>
|
|
T TextToEnum(const QString& text) {
|
|
auto me = QMetaEnum::fromType<T>();
|
|
return static_cast<T>(me.keyToValue(text.toUtf8().constData()));
|
|
}
|
|
|
|
template <class T>
|
|
QString EnumToText(T value) {
|
|
return QString(QMetaEnum::fromType<T>().valueToKey(static_cast<int>(value)));
|
|
}
|
|
|
|
struct ControllerSettings {
|
|
QString color;
|
|
int speaker_volume = 50;
|
|
int vibration_intensity = 100;
|
|
// 0 shares player 1 with the first gamepad; 1..MAX_PLAYERS dedicates that player to the keyboard.
|
|
int keyboard_player = 0;
|
|
|
|
void WriteSettings(QSettings* s) const {
|
|
s->setValue("controller_color", color);
|
|
s->setValue("controller_speaker_volume", speaker_volume);
|
|
s->setValue("controller_vibration_intensity", vibration_intensity);
|
|
s->setValue("controller_keyboard_player", keyboard_player);
|
|
}
|
|
|
|
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, int fallback) {
|
|
bool ok = false;
|
|
const int value = s->value(key, fallback).toInt(&ok);
|
|
return ok ? qBound(0, value, 100) : fallback;
|
|
};
|
|
speaker_volume = read_percent("controller_speaker_volume", 50);
|
|
vibration_intensity = read_percent("controller_vibration_intensity", 100);
|
|
keyboard_player = qBound(0, s->value("controller_keyboard_player", 0).toInt(),
|
|
Config::MAX_PLAYERS);
|
|
}
|
|
};
|
|
|
|
class Configuration: public QObject {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
static constexpr int DEFAULT_CONSOLE_LANGUAGE = 1;
|
|
static constexpr int MAX_CONSOLE_LANGUAGE = 29;
|
|
|
|
static constexpr int MIN_SCREEN_SIZE = 320;
|
|
static constexpr int MAX_SCREEN_SIZE = 16384;
|
|
|
|
static QString NormalizeResolution(const QString& text);
|
|
|
|
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 */
|
|
QString addons_dir; /* Global setting; not saved per game. */
|
|
QStringList addcont; /* User add-ons ("LABEL" or "LABEL=DIR"), saved by title ID. */
|
|
bool custom_settings = false;
|
|
GameStatus game_status = GameStatus::Unknown;
|
|
QString game_comment;
|
|
|
|
// Controller preferences always come from the global configuration.
|
|
ControllerSettings controller;
|
|
|
|
QString screen_resolution = QStringLiteral("1280x720");
|
|
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 hdr_enabled = false;
|
|
bool hide_cursor_enabled = false;
|
|
bool stretch_enabled = false;
|
|
bool readback_linear_images = false;
|
|
bool readback_tiled_images = false;
|
|
bool sync_raw_image_buffers = false;
|
|
bool tessellation_enabled = false;
|
|
bool occlusion_queries_enabled = false;
|
|
bool shader_cache_enabled = true;
|
|
bool trophy_enabled = true;
|
|
int trophy_duration_seconds = 6;
|
|
bool perf_overlay_enabled = false;
|
|
bool skip_notice_screen = false;
|
|
bool network_connected = false;
|
|
int vblank_frequency = 60;
|
|
int console_language = DEFAULT_CONSOLE_LANGUAGE;
|
|
bool vulkan_validation_enabled = false;
|
|
bool shader_validation_enabled = false;
|
|
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;
|
|
hdr_enabled = other.hdr_enabled;
|
|
hide_cursor_enabled = other.hide_cursor_enabled;
|
|
stretch_enabled = other.stretch_enabled;
|
|
readback_linear_images = other.readback_linear_images;
|
|
readback_tiled_images = other.readback_tiled_images;
|
|
sync_raw_image_buffers = other.sync_raw_image_buffers;
|
|
tessellation_enabled = other.tessellation_enabled;
|
|
occlusion_queries_enabled = other.occlusion_queries_enabled;
|
|
shader_cache_enabled = other.shader_cache_enabled;
|
|
trophy_enabled = other.trophy_enabled;
|
|
trophy_duration_seconds = other.trophy_duration_seconds;
|
|
perf_overlay_enabled = other.perf_overlay_enabled;
|
|
skip_notice_screen = other.skip_notice_screen;
|
|
network_connected = other.network_connected;
|
|
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;
|
|
void ReadSettings(QSettings* s);
|
|
|
|
[[nodiscard]] QVariantMap GameSettings() const;
|
|
// Call on a temporary configuration: validation can fail after loading values.
|
|
bool SetGameSettings(const QJsonObject& settings, QString& error);
|
|
|
|
private:
|
|
template <class Settings>
|
|
void ReadGameSettingsValues(const Settings& s);
|
|
};
|
|
|
|
Q_DECLARE_METATYPE(Configuration*)
|
|
|
|
#endif /* LAUNCHER_INCLUDE_CONFIGURATION_H_ */
|