Merge branch 'master' of https://github.com/GPUCode/citra into vulkan-2
This commit is contained in:
@ -161,6 +161,8 @@ void Config::ReadValues() {
|
||||
static_cast<Settings::LayoutOption>(sdl2_config->GetInteger("Layout", "layout_option", 0));
|
||||
Settings::values.swap_screen = sdl2_config->GetBoolean("Layout", "swap_screen", false);
|
||||
Settings::values.upright_screen = sdl2_config->GetBoolean("Layout", "upright_screen", false);
|
||||
Settings::values.large_screen_proportion =
|
||||
sdl2_config->GetReal("Layout", "large_screen_proportion", 4.0);
|
||||
Settings::values.custom_layout = sdl2_config->GetBoolean("Layout", "custom_layout", false);
|
||||
Settings::values.custom_top_left =
|
||||
static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_left", 0));
|
||||
|
@ -216,6 +216,10 @@ swap_screen =
|
||||
# 0 (default): Off, 1: On
|
||||
upright_screen =
|
||||
|
||||
# The proportion between the large and small screens when playing in Large Screen Small Screen layout.
|
||||
# Must be a real value between 1.0 and 16.0. Default is 4
|
||||
large_screen_proportion =
|
||||
|
||||
# Dumps textures as PNG to dump/textures/[Title ID]/.
|
||||
# 0 (default): Off, 1: On
|
||||
dump_textures =
|
||||
|
@ -487,6 +487,7 @@ void Config::ReadLayoutValues() {
|
||||
ReadGlobalSetting(Settings::values.layout_option);
|
||||
ReadGlobalSetting(Settings::values.swap_screen);
|
||||
ReadGlobalSetting(Settings::values.upright_screen);
|
||||
ReadGlobalSetting(Settings::values.large_screen_proportion);
|
||||
|
||||
if (global) {
|
||||
ReadBasicSetting(Settings::values.mono_render_option);
|
||||
@ -1004,6 +1005,7 @@ void Config::SaveLayoutValues() {
|
||||
WriteGlobalSetting(Settings::values.layout_option);
|
||||
WriteGlobalSetting(Settings::values.swap_screen);
|
||||
WriteGlobalSetting(Settings::values.upright_screen);
|
||||
WriteGlobalSetting(Settings::values.large_screen_proportion);
|
||||
|
||||
if (global) {
|
||||
WriteBasicSetting(Settings::values.mono_render_option);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <QDesktopServices>
|
||||
#include <QMessageBox>
|
||||
#include <QUrl>
|
||||
#include "citra_qt/configuration/configuration_shared.h"
|
||||
#include "citra_qt/configuration/configure_debug.h"
|
||||
#include "citra_qt/debugger/console.h"
|
||||
#include "citra_qt/uisettings.h"
|
||||
@ -16,6 +17,17 @@
|
||||
#include "ui_configure_debug.h"
|
||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||
|
||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
||||
// so we can just convert from the sliders range (0 - 79) to the expected
|
||||
// settings range (5 - 400) with simple math.
|
||||
static constexpr int SliderToSettings(int value) {
|
||||
return 5 * value + 5;
|
||||
}
|
||||
|
||||
static constexpr int SettingsToSlider(int value) {
|
||||
return (value - 5) / 5;
|
||||
}
|
||||
|
||||
ConfigureDebug::ConfigureDebug(QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureDebug>()) {
|
||||
ui->setupUi(this);
|
||||
@ -60,6 +72,19 @@ ConfigureDebug::ConfigureDebug(QWidget* parent)
|
||||
ui->toggle_cpu_jit->setEnabled(!is_powered_on);
|
||||
ui->toggle_renderer_debug->setEnabled(!is_powered_on);
|
||||
ui->toggle_dump_command_buffers->setEnabled(!is_powered_on);
|
||||
|
||||
// Set a minimum width for the label to prevent the slider from changing size.
|
||||
// This scales across DPIs. (This value should be enough for "xxx%")
|
||||
ui->clock_display_label->setMinimumWidth(40);
|
||||
|
||||
connect(ui->slider_clock_speed, &QSlider::valueChanged, this, [&](int value) {
|
||||
ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value)));
|
||||
});
|
||||
|
||||
ui->clock_speed_label->setVisible(Settings::IsConfiguringGlobal());
|
||||
ui->clock_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||
|
||||
SetupPerGameUI();
|
||||
}
|
||||
|
||||
ConfigureDebug::~ConfigureDebug() = default;
|
||||
@ -74,6 +99,23 @@ void ConfigureDebug::SetConfiguration() {
|
||||
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
||||
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue());
|
||||
ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers.GetValue());
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
|
||||
ui->clock_speed_combo->setCurrentIndex(0);
|
||||
ui->slider_clock_speed->setEnabled(false);
|
||||
} else {
|
||||
ui->clock_speed_combo->setCurrentIndex(1);
|
||||
ui->slider_clock_speed->setEnabled(true);
|
||||
}
|
||||
ConfigurationShared::SetHighlight(ui->clock_speed_widget,
|
||||
!Settings::values.cpu_clock_percentage.UsingGlobal());
|
||||
}
|
||||
|
||||
ui->slider_clock_speed->setValue(
|
||||
SettingsToSlider(Settings::values.cpu_clock_percentage.GetValue()));
|
||||
ui->clock_display_label->setText(
|
||||
QStringLiteral("%1%").arg(Settings::values.cpu_clock_percentage.GetValue()));
|
||||
}
|
||||
|
||||
void ConfigureDebug::ApplyConfiguration() {
|
||||
@ -88,6 +130,27 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
||||
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
|
||||
Settings::values.dump_command_buffers = ui->toggle_dump_command_buffers->isChecked();
|
||||
|
||||
ConfigurationShared::ApplyPerGameSetting(
|
||||
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
|
||||
[this](s32) { return SliderToSettings(ui->slider_clock_speed->value()); });
|
||||
}
|
||||
|
||||
void ConfigureDebug::SetupPerGameUI() {
|
||||
// Block the global settings if a game is currently running that overrides them
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->slider_clock_speed->setEnabled(Settings::values.cpu_clock_percentage.UsingGlobal());
|
||||
return;
|
||||
}
|
||||
|
||||
connect(ui->clock_speed_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||
ui->slider_clock_speed->setEnabled(index == 1);
|
||||
ConfigurationShared::SetHighlight(ui->clock_speed_widget, index == 1);
|
||||
});
|
||||
|
||||
ui->groupBox->setVisible(false);
|
||||
ui->groupBox_2->setVisible(false);
|
||||
ui->toggle_cpu_jit->setVisible(false);
|
||||
}
|
||||
|
||||
void ConfigureDebug::RetranslateUI() {
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
void ApplyConfiguration();
|
||||
void RetranslateUI();
|
||||
void SetConfiguration();
|
||||
void SetupPerGameUI();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::ConfigureDebug> ui;
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>454</width>
|
||||
<height>356</height>
|
||||
<width>443</width>
|
||||
<height>358</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -107,12 +107,80 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Miscellaneous</string>
|
||||
<string>CPU</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="clock_speed_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="clock_speed_layout">
|
||||
<property name="spacing">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QComboBox" name="clock_speed_combo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global clock speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set clock speed:</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="clock_speed_label">
|
||||
<property name="text">
|
||||
<string>CPU Clock Speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="slider_clock_speed">
|
||||
<property name="toolTip">
|
||||
<string><html><body>Changes the emulated CPU clock frequency.<br>Underclocking can increase performance but may cause the game to freeze.<br>Overclocking may reduce in game lag but also might cause freezes</body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>79</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="clock_display_label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="toggle_cpu_jit">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enables the use of the ARM JIT compiler for emulating the 3DS CPUs. Don't disable unless for debugging purposes</p></body></html></string>
|
||||
@ -142,6 +210,16 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_cpu_clock_info">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>CPU Clock Speed Information<br/>Underclocking can increase performance but may cause the game to freeze.<br/>Overclocking may reduce in game lag but also might cause freezes</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@ -163,7 +241,6 @@
|
||||
<tabstop>log_filter_edit</tabstop>
|
||||
<tabstop>toggle_console</tabstop>
|
||||
<tabstop>open_log_button</tabstop>
|
||||
<tabstop>toggle_cpu_jit</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
@ -69,6 +69,7 @@ void ConfigureEnhancements::SetConfiguration() {
|
||||
static_cast<int>(Settings::values.layout_option.GetValue()));
|
||||
ui->swap_screen->setChecked(Settings::values.swap_screen.GetValue());
|
||||
ui->upright_screen->setChecked(Settings::values.upright_screen.GetValue());
|
||||
ui->large_screen_proportion->setValue(Settings::values.large_screen_proportion.GetValue());
|
||||
ui->toggle_dump_textures->setChecked(Settings::values.dump_textures.GetValue());
|
||||
ui->toggle_custom_textures->setChecked(Settings::values.custom_textures.GetValue());
|
||||
ui->toggle_preload_textures->setChecked(Settings::values.preload_textures.GetValue());
|
||||
@ -122,6 +123,7 @@ void ConfigureEnhancements::ApplyConfiguration() {
|
||||
static_cast<Settings::LayoutOption>(ui->layout_combobox->currentIndex());
|
||||
Settings::values.swap_screen = ui->swap_screen->isChecked();
|
||||
Settings::values.upright_screen = ui->upright_screen->isChecked();
|
||||
Settings::values.large_screen_proportion = ui->large_screen_proportion->value();
|
||||
Settings::values.dump_textures = ui->toggle_dump_textures->isChecked();
|
||||
Settings::values.custom_textures = ui->toggle_custom_textures->isChecked();
|
||||
Settings::values.preload_textures = ui->toggle_preload_textures->isChecked();
|
||||
|
@ -295,6 +295,30 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Large Screen Proportion:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="large_screen_proportion">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
@ -384,6 +408,7 @@
|
||||
<tabstop>layout_combobox</tabstop>
|
||||
<tabstop>swap_screen</tabstop>
|
||||
<tabstop>upright_screen</tabstop>
|
||||
<tabstop>large_screen_proportion</tabstop>
|
||||
<tabstop>bg_button</tabstop>
|
||||
<tabstop>toggle_custom_textures</tabstop>
|
||||
<tabstop>toggle_dump_textures</tabstop>
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <fmt/format.h>
|
||||
#include "citra_qt/configuration/config.h"
|
||||
#include "citra_qt/configuration/configure_audio.h"
|
||||
#include "citra_qt/configuration/configure_debug.h"
|
||||
#include "citra_qt/configuration/configure_general.h"
|
||||
#include "citra_qt/configuration/configure_graphics.h"
|
||||
#include "citra_qt/configuration/configure_per_game.h"
|
||||
@ -31,6 +32,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString
|
||||
general_tab = std::make_unique<ConfigureGeneral>(this);
|
||||
graphics_tab = std::make_unique<ConfigureGraphics>(this);
|
||||
system_tab = std::make_unique<ConfigureSystem>(this);
|
||||
debug_tab = std::make_unique<ConfigureDebug>(this);
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -38,6 +40,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString
|
||||
ui->tabWidget->addTab(system_tab.get(), tr("System"));
|
||||
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
|
||||
ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
|
||||
ui->tabWidget->addTab(debug_tab.get(), tr("Debug"));
|
||||
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setWindowTitle(tr("Properties"));
|
||||
@ -80,6 +83,7 @@ void ConfigurePerGame::ApplyConfiguration() {
|
||||
system_tab->ApplyConfiguration();
|
||||
graphics_tab->ApplyConfiguration();
|
||||
audio_tab->ApplyConfiguration();
|
||||
debug_tab->ApplyConfiguration();
|
||||
|
||||
Settings::LogSettings();
|
||||
|
||||
|
@ -17,6 +17,7 @@ class ConfigureAudio;
|
||||
class ConfigureGeneral;
|
||||
class ConfigureGraphics;
|
||||
class ConfigureSystem;
|
||||
class ConfigureDebug;
|
||||
|
||||
class QGraphicsScene;
|
||||
class QStandardItem;
|
||||
@ -66,4 +67,5 @@ private:
|
||||
std::unique_ptr<ConfigureGeneral> general_tab;
|
||||
std::unique_ptr<ConfigureGraphics> graphics_tab;
|
||||
std::unique_ptr<ConfigureSystem> system_tab;
|
||||
std::unique_ptr<ConfigureDebug> debug_tab;
|
||||
};
|
||||
|
@ -225,17 +225,6 @@ static const std::array<const char*, 187> country_names = {
|
||||
QT_TRANSLATE_NOOP("ConfigureSystem", "Bermuda"), // 180-186
|
||||
};
|
||||
|
||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
||||
// so we can just convert from the sliders range (0 - 79) to the expected
|
||||
// settings range (5 - 400) with simple math.
|
||||
static constexpr int SliderToSettings(int value) {
|
||||
return 5 * value + 5;
|
||||
}
|
||||
|
||||
static constexpr int SettingsToSlider(int value) {
|
||||
return (value - 5) / 5;
|
||||
}
|
||||
|
||||
ConfigureSystem::ConfigureSystem(QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureSystem>()) {
|
||||
ui->setupUi(this);
|
||||
@ -255,17 +244,6 @@ ConfigureSystem::ConfigureSystem(QWidget* parent)
|
||||
}
|
||||
}
|
||||
|
||||
// Set a minimum width for the label to prevent the slider from changing size.
|
||||
// This scales across DPIs. (This value should be enough for "xxx%")
|
||||
ui->clock_display_label->setMinimumWidth(40);
|
||||
|
||||
connect(ui->slider_clock_speed, &QSlider::valueChanged, this, [&](int value) {
|
||||
ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value)));
|
||||
});
|
||||
|
||||
ui->clock_speed_label->setVisible(Settings::IsConfiguringGlobal());
|
||||
ui->clock_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||
|
||||
SetupPerGameUI();
|
||||
|
||||
ui->combo_download_mode->setCurrentIndex(1); // set to Recommended
|
||||
@ -325,22 +303,6 @@ void ConfigureSystem::SetConfiguration() {
|
||||
ui->label_disable_info->hide();
|
||||
}
|
||||
|
||||
if (!Settings::IsConfiguringGlobal()) {
|
||||
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
|
||||
ui->clock_speed_combo->setCurrentIndex(0);
|
||||
ui->slider_clock_speed->setEnabled(false);
|
||||
} else {
|
||||
ui->clock_speed_combo->setCurrentIndex(1);
|
||||
ui->slider_clock_speed->setEnabled(true);
|
||||
}
|
||||
ConfigurationShared::SetHighlight(ui->clock_speed_widget,
|
||||
!Settings::values.cpu_clock_percentage.UsingGlobal());
|
||||
}
|
||||
|
||||
ui->slider_clock_speed->setValue(
|
||||
SettingsToSlider(Settings::values.cpu_clock_percentage.GetValue()));
|
||||
ui->clock_display_label->setText(
|
||||
QStringLiteral("%1%").arg(Settings::values.cpu_clock_percentage.GetValue()));
|
||||
ui->toggle_new_3ds->setChecked(Settings::values.is_new_3ds.GetValue());
|
||||
ui->plugin_loader->setChecked(Settings::values.plugin_loader_enabled.GetValue());
|
||||
ui->allow_plugin_loader->setChecked(Settings::values.allow_plugin_loader.GetValue());
|
||||
@ -452,10 +414,6 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||
Settings::values.plugin_loader_enabled.SetValue(ui->plugin_loader->isChecked());
|
||||
Settings::values.allow_plugin_loader.SetValue(ui->allow_plugin_loader->isChecked());
|
||||
}
|
||||
|
||||
ConfigurationShared::ApplyPerGameSetting(
|
||||
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
|
||||
[this](s32) { return SliderToSettings(ui->slider_clock_speed->value()); });
|
||||
}
|
||||
|
||||
void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
||||
@ -534,7 +492,6 @@ void ConfigureSystem::SetupPerGameUI() {
|
||||
// Block the global settings if a game is currently running that overrides them
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->toggle_new_3ds->setEnabled(Settings::values.is_new_3ds.UsingGlobal());
|
||||
ui->slider_clock_speed->setEnabled(Settings::values.cpu_clock_percentage.UsingGlobal());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -568,11 +525,6 @@ void ConfigureSystem::SetupPerGameUI() {
|
||||
ui->plugin_loader->setVisible(false);
|
||||
ui->allow_plugin_loader->setVisible(false);
|
||||
|
||||
connect(ui->clock_speed_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||
ui->slider_clock_speed->setEnabled(index == 1);
|
||||
ConfigurationShared::SetHighlight(ui->clock_speed_widget, index == 1);
|
||||
});
|
||||
|
||||
ConfigurationShared::SetColoredTristate(ui->toggle_new_3ds, Settings::values.is_new_3ds,
|
||||
is_new_3ds);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>525</width>
|
||||
<width>535</width>
|
||||
<height>619</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -274,7 +274,7 @@
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QGridLayout" name="edit_init_time_offset_grid">
|
||||
<item column="0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSpinBox" name="edit_init_time_offset_days">
|
||||
<property name="suffix">
|
||||
<string> days</string>
|
||||
@ -287,7 +287,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item column="1">
|
||||
<item row="0" column="1">
|
||||
<widget class="QTimeEdit" name="edit_init_time_offset_time">
|
||||
<property name="displayFormat">
|
||||
<string>HH:mm:ss</string>
|
||||
@ -410,86 +410,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="group_advanced">
|
||||
<property name="title">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QWidget" name="clock_speed_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="clock_speed_layout">
|
||||
<property name="spacing">
|
||||
<number>7</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="clock_speed_combo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use global clock speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set clock speed:</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="clock_speed_label">
|
||||
<property name="text">
|
||||
<string>CPU Clock Speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="slider_clock_speed">
|
||||
<property name="toolTip">
|
||||
<string><html><body>Changes the emulated CPU clock frequency.<br>Underclocking can increase performance but may cause the game to freeze.<br>Overclocking may reduce in game lag but also might cause freezes</body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>79</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="clock_display_label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_disable_info">
|
||||
<property name="text">
|
||||
@ -500,16 +420,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_cpu_clock_info">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>CPU Clock Speed Information<br/>Underclocking can increase performance but may cause the game to freeze.<br/>Overclocking may reduce in game lag but also might cause freezes</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
@ -100,8 +100,6 @@
|
||||
<addaction name="menu_Load_State"/>
|
||||
<addaction name="menu_Save_State"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Report_Compatibility"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Configure"/>
|
||||
<addaction name="action_Configure_Current_Game"/>
|
||||
<addaction name="action_Cheats"/>
|
||||
@ -189,6 +187,8 @@
|
||||
<addaction name="action_Check_For_Updates"/>
|
||||
<addaction name="action_Open_Maintenance_Tool"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Report_Compatibility"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_FAQ"/>
|
||||
<addaction name="action_About"/>
|
||||
</widget>
|
||||
|
@ -127,6 +127,7 @@ void LogSettings() {
|
||||
log_setting("Layout_LayoutOption", values.layout_option.GetValue());
|
||||
log_setting("Layout_SwapScreen", values.swap_screen.GetValue());
|
||||
log_setting("Layout_UprightScreen", values.upright_screen.GetValue());
|
||||
log_setting("Layout_LargeScreenProportion", values.large_screen_proportion.GetValue());
|
||||
log_setting("Utility_DumpTextures", values.dump_textures.GetValue());
|
||||
log_setting("Utility_CustomTextures", values.custom_textures.GetValue());
|
||||
log_setting("Utility_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
|
||||
@ -204,6 +205,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||
values.layout_option.SetGlobal(true);
|
||||
values.swap_screen.SetGlobal(true);
|
||||
values.upright_screen.SetGlobal(true);
|
||||
values.large_screen_proportion.SetGlobal(true);
|
||||
values.bg_red.SetGlobal(true);
|
||||
values.bg_green.SetGlobal(true);
|
||||
values.bg_blue.SetGlobal(true);
|
||||
|
@ -466,6 +466,8 @@ struct Values {
|
||||
SwitchableSetting<LayoutOption> layout_option{LayoutOption::Default, "layout_option"};
|
||||
SwitchableSetting<bool> swap_screen{false, "swap_screen"};
|
||||
SwitchableSetting<bool> upright_screen{false, "upright_screen"};
|
||||
SwitchableSetting<float, true> large_screen_proportion{4.f, 1.f, 16.f,
|
||||
"large_screen_proportion"};
|
||||
Setting<bool> custom_layout{false, "custom_layout"};
|
||||
Setting<u16> custom_top_left{0, "custom_top_left"};
|
||||
Setting<u16> custom_top_top{0, "custom_top_top"};
|
||||
|
@ -197,7 +197,8 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height,
|
||||
case Settings::LayoutOption::LargeScreen:
|
||||
layout =
|
||||
Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||
Settings::values.upright_screen.GetValue());
|
||||
Settings::values.upright_screen.GetValue(),
|
||||
Settings::values.large_screen_proportion.GetValue());
|
||||
break;
|
||||
case Settings::LayoutOption::SideScreen:
|
||||
layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||
|
@ -231,7 +231,8 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool swapped, bool up
|
||||
return res;
|
||||
}
|
||||
|
||||
FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upright) {
|
||||
FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upright,
|
||||
float scale_factor) {
|
||||
ASSERT(width > 0);
|
||||
ASSERT(height > 0);
|
||||
|
||||
@ -244,25 +245,29 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
||||
float small_screen_aspect_ratio;
|
||||
if (upright) {
|
||||
if (swapped) {
|
||||
emulation_aspect_ratio = (Core::kScreenBottomWidth * 4.0f + Core::kScreenTopWidth) /
|
||||
(Core::kScreenBottomHeight * 4);
|
||||
emulation_aspect_ratio =
|
||||
(Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth) /
|
||||
(Core::kScreenBottomHeight * scale_factor);
|
||||
large_screen_aspect_ratio = BOT_SCREEN_UPRIGHT_ASPECT_RATIO;
|
||||
small_screen_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO;
|
||||
} else {
|
||||
emulation_aspect_ratio = (Core::kScreenTopWidth * 4.0f + Core::kScreenBottomWidth) /
|
||||
(Core::kScreenTopHeight * 4);
|
||||
emulation_aspect_ratio =
|
||||
(Core::kScreenTopWidth * scale_factor + Core::kScreenBottomWidth) /
|
||||
(Core::kScreenTopHeight * scale_factor);
|
||||
large_screen_aspect_ratio = TOP_SCREEN_UPRIGHT_ASPECT_RATIO;
|
||||
small_screen_aspect_ratio = BOT_SCREEN_UPRIGHT_ASPECT_RATIO;
|
||||
}
|
||||
} else {
|
||||
if (swapped) {
|
||||
emulation_aspect_ratio = Core::kScreenBottomHeight * 4 /
|
||||
(Core::kScreenBottomWidth * 4.0f + Core::kScreenTopWidth);
|
||||
emulation_aspect_ratio =
|
||||
Core::kScreenBottomHeight * scale_factor /
|
||||
(Core::kScreenBottomWidth * scale_factor + Core::kScreenTopWidth);
|
||||
large_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO;
|
||||
small_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO;
|
||||
} else {
|
||||
emulation_aspect_ratio = Core::kScreenTopHeight * 4 /
|
||||
(Core::kScreenTopWidth * 4.0f + Core::kScreenBottomWidth);
|
||||
emulation_aspect_ratio =
|
||||
Core::kScreenTopHeight * scale_factor /
|
||||
(Core::kScreenTopWidth * scale_factor + Core::kScreenBottomWidth);
|
||||
large_screen_aspect_ratio = TOP_SCREEN_ASPECT_RATIO;
|
||||
small_screen_aspect_ratio = BOT_SCREEN_ASPECT_RATIO;
|
||||
}
|
||||
@ -271,7 +276,7 @@ FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool swapped, bool upr
|
||||
Common::Rectangle<u32> screen_window_area{0, 0, width, height};
|
||||
Common::Rectangle<u32> total_rect = maxRectangle(screen_window_area, emulation_aspect_ratio);
|
||||
Common::Rectangle<u32> large_screen = maxRectangle(total_rect, large_screen_aspect_ratio);
|
||||
Common::Rectangle<u32> fourth_size_rect = total_rect.Scale(.25f);
|
||||
Common::Rectangle<u32> fourth_size_rect = total_rect.Scale(1.f / scale_factor);
|
||||
Common::Rectangle<u32> small_screen = maxRectangle(fourth_size_rect, small_screen_aspect_ratio);
|
||||
|
||||
if (window_aspect_ratio < emulation_aspect_ratio) {
|
||||
@ -416,22 +421,35 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
|
||||
if (Settings::values.upright_screen.GetValue()) {
|
||||
if (Settings::values.swap_screen.GetValue()) {
|
||||
width = Core::kScreenBottomHeight * res_scale;
|
||||
height = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale;
|
||||
height = (Core::kScreenBottomWidth +
|
||||
Core::kScreenTopWidth /
|
||||
Settings::values.large_screen_proportion.GetValue()) *
|
||||
res_scale;
|
||||
} else {
|
||||
width = Core::kScreenTopHeight * res_scale;
|
||||
height = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale;
|
||||
height = (Core::kScreenTopWidth +
|
||||
Core::kScreenBottomWidth /
|
||||
Settings::values.large_screen_proportion.GetValue()) *
|
||||
res_scale;
|
||||
}
|
||||
} else {
|
||||
if (Settings::values.swap_screen.GetValue()) {
|
||||
width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale;
|
||||
width = (Core::kScreenBottomWidth +
|
||||
Core::kScreenTopWidth /
|
||||
Settings::values.large_screen_proportion.GetValue()) *
|
||||
res_scale;
|
||||
height = Core::kScreenBottomHeight * res_scale;
|
||||
} else {
|
||||
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale;
|
||||
width = (Core::kScreenTopWidth +
|
||||
Core::kScreenBottomWidth /
|
||||
Settings::values.large_screen_proportion.GetValue()) *
|
||||
res_scale;
|
||||
height = Core::kScreenTopHeight * res_scale;
|
||||
}
|
||||
}
|
||||
layout = LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||
Settings::values.upright_screen.GetValue());
|
||||
Settings::values.upright_screen.GetValue(),
|
||||
Settings::values.large_screen_proportion.GetValue());
|
||||
break;
|
||||
case Settings::LayoutOption::SideScreen:
|
||||
if (Settings::values.upright_screen.GetValue()) {
|
||||
@ -576,9 +594,12 @@ std::pair<unsigned, unsigned> GetMinimumSizeFromLayout(Settings::LayoutOption la
|
||||
min_height = Core::kScreenBottomHeight;
|
||||
break;
|
||||
case Settings::LayoutOption::LargeScreen:
|
||||
min_width = Settings::values.swap_screen
|
||||
? Core::kScreenTopWidth / 4 + Core::kScreenBottomWidth
|
||||
: Core::kScreenTopWidth + Core::kScreenBottomWidth / 4;
|
||||
min_width =
|
||||
Settings::values.swap_screen
|
||||
? Core::kScreenTopWidth / Settings::values.large_screen_proportion.GetValue() +
|
||||
Core::kScreenBottomWidth
|
||||
: Core::kScreenTopWidth + Core::kScreenBottomWidth /
|
||||
Settings::values.large_screen_proportion.GetValue();
|
||||
min_height = Core::kScreenBottomHeight;
|
||||
break;
|
||||
case Settings::LayoutOption::SideScreen:
|
||||
|
@ -83,9 +83,11 @@ FramebufferLayout SingleFrameLayout(u32 width, u32 height, bool is_swapped, bool
|
||||
* @param width Window framebuffer width in pixels
|
||||
* @param height Window framebuffer height in pixels
|
||||
* @param is_swapped if true, the bottom screen will be the large display
|
||||
* @param scale_factor The ratio between the large screen with respect to the smaller screen
|
||||
* @return Newly created FramebufferLayout object with default screen regions initialized
|
||||
*/
|
||||
FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool upright);
|
||||
FramebufferLayout LargeFrameLayout(u32 width, u32 height, bool is_swapped, bool upright,
|
||||
float scale_factor);
|
||||
|
||||
/**
|
||||
* Factory method for constructing a Frame with the Top screen and bottom
|
||||
|
@ -1087,7 +1087,11 @@ void Module::Interface::DeleteTicket(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
void Module::Interface::GetNumTickets(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x0008, 0, 0); // 0x00080000
|
||||
|
||||
u32 ticket_count = 0;
|
||||
for (const auto& title_list : am->am_title_list) {
|
||||
ticket_count += static_cast<u32>(title_list.size());
|
||||
}
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@ -1101,9 +1105,18 @@ void Module::Interface::GetTicketList(Kernel::HLERequestContext& ctx) {
|
||||
u32 ticket_index = rp.Pop<u32>();
|
||||
auto& ticket_tids_out = rp.PopMappedBuffer();
|
||||
|
||||
u32 tickets_written = 0;
|
||||
for (const auto& title_list : am->am_title_list) {
|
||||
const auto tickets_to_write =
|
||||
std::min(static_cast<u32>(title_list.size()), ticket_list_count - tickets_written);
|
||||
ticket_tids_out.Write(title_list.data(), tickets_written * sizeof(u64),
|
||||
tickets_to_write * sizeof(u64));
|
||||
tickets_written += tickets_to_write;
|
||||
}
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(ticket_list_count);
|
||||
rb.Push(tickets_written);
|
||||
rb.PushMappedBuffer(ticket_tids_out);
|
||||
LOG_WARNING(Service_AM, "(STUBBED) ticket_list_count=0x{:08x}, ticket_index=0x{:08x}",
|
||||
ticket_list_count, ticket_index);
|
||||
|
@ -3,9 +3,9 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/archives.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/service/nim/nim_u.h"
|
||||
|
||||
SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U)
|
||||
@ -13,37 +13,736 @@ SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_U)
|
||||
|
||||
namespace Service::NIM {
|
||||
|
||||
enum class SystemUpdateState : u32 {
|
||||
NotInitialized,
|
||||
StartingSystemUpdate,
|
||||
FetchingHashAndAccountStatus,
|
||||
InstallingNewTickets,
|
||||
InstallingTitles,
|
||||
UpdateComplete,
|
||||
SystemUpdatesDisabled,
|
||||
Unknown7,
|
||||
Unknown8,
|
||||
};
|
||||
|
||||
struct SystemUpdateProgress {
|
||||
SystemUpdateState state;
|
||||
u32 last_operation_result;
|
||||
u64 current_title_downloaded_bytes;
|
||||
u64 current_title_total_bytes;
|
||||
u64 titles_downloaded;
|
||||
u64 titles_total;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SystemUpdateProgress) == 0x28, "SystemUpdateProgress structure size is wrong");
|
||||
|
||||
enum class TitleDownloadState : u32 {
|
||||
NotInitialized,
|
||||
StartingTitleDownload,
|
||||
InstallingTmd,
|
||||
CommittingTmd,
|
||||
InstallingContents,
|
||||
ContentsInstalled,
|
||||
CommittingTitles,
|
||||
Finished,
|
||||
Unknown8,
|
||||
Unknown9,
|
||||
BackgroundDownloadFailed,
|
||||
};
|
||||
|
||||
struct TitleDownloadProgress {
|
||||
TitleDownloadState state;
|
||||
u32 last_operation_result;
|
||||
u64 downloaded_bytes;
|
||||
u64 total_bytes;
|
||||
};
|
||||
|
||||
static_assert(sizeof(TitleDownloadProgress) == 0x18,
|
||||
"TitleDownloadProgress structure size is wrong");
|
||||
|
||||
struct TitleDownloadConfig {
|
||||
u64 title_id;
|
||||
u32 title_version;
|
||||
u32 unknown_1;
|
||||
u8 age_rating;
|
||||
u8 media_type;
|
||||
INSERT_PADDING_BYTES(2);
|
||||
u32 unknown_2;
|
||||
};
|
||||
|
||||
static_assert(sizeof(TitleDownloadConfig) == 0x18, "TitleDownloadConfig structure size is wrong");
|
||||
|
||||
#pragma pack(1)
|
||||
struct BackgroundTitleDownloadConfig {
|
||||
TitleDownloadConfig base_config;
|
||||
u8 unknown_1;
|
||||
u8 unknown_2;
|
||||
INSERT_PADDING_BYTES(6);
|
||||
u64 requester_title_id;
|
||||
std::array<u16, 0x48> title_name;
|
||||
u16 title_name_terminator;
|
||||
std::array<u16, 0x24> developer_name;
|
||||
u16 developer_name_terminator;
|
||||
};
|
||||
|
||||
static_assert(sizeof(BackgroundTitleDownloadConfig) == 0x104,
|
||||
"BackgroundTitleDownloadConfig structure size is wrong");
|
||||
|
||||
struct BackgroundTitleDownloadTaskInfo {
|
||||
BackgroundTitleDownloadConfig config;
|
||||
INSERT_PADDING_BYTES(4);
|
||||
TitleDownloadProgress progress;
|
||||
};
|
||||
|
||||
static_assert(sizeof(BackgroundTitleDownloadTaskInfo) == 0x120,
|
||||
"BackgroundTitleDownloadTaskInfo structure size is wrong");
|
||||
|
||||
struct AutoTitleDownloadTaskInfo {
|
||||
u64 task_id;
|
||||
u64 title_id;
|
||||
u32 title_version;
|
||||
u8 unknown_4[0x14];
|
||||
u64 required_size;
|
||||
u32 last_operation_result_code;
|
||||
u32 last_operation_customer_support_code;
|
||||
std::array<u16, 0x48> title_name;
|
||||
u16 title_name_terminator;
|
||||
std::array<u16, 0x24> developer_name;
|
||||
u16 developer_name_terminator;
|
||||
u8 unknown_5[0x24];
|
||||
};
|
||||
|
||||
static_assert(sizeof(AutoTitleDownloadTaskInfo) == 0x138,
|
||||
"AutoTitleDownloadTaskInfo structure size is wrong");
|
||||
|
||||
struct AutoDbgDat {
|
||||
u8 unknown_1[0x4];
|
||||
u32 num_auto_download_tasks;
|
||||
u8 unknown_2[0x100];
|
||||
};
|
||||
|
||||
static_assert(sizeof(AutoDbgDat) == 0x108, "AutoDbgDat structure size is wrong");
|
||||
|
||||
NIM_U::NIM_U(Core::System& system) : ServiceFramework("nim:u", 2) {
|
||||
const FunctionInfo functions[] = {
|
||||
{0x00010000, nullptr, "StartSysUpdate"},
|
||||
{0x00020000, nullptr, "GetUpdateDownloadProgress"},
|
||||
{0x00040000, nullptr, "FinishTitlesInstall"},
|
||||
{0x00050000, &NIM_U::CheckForSysUpdateEvent, "CheckForSysUpdateEvent"},
|
||||
{0x00090000, &NIM_U::CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
|
||||
{0x000A0000, nullptr, "GetState"},
|
||||
{0x000B0000, nullptr, "GetSystemTitleHash"},
|
||||
{0x00010000, &NIM_U::StartNetworkUpdate, "StartNetworkUpdate"},
|
||||
{0x00020000, &NIM_U::GetProgress, "GetProgress"},
|
||||
{0x00030000, &NIM_U::Cancel, "Cancel"},
|
||||
{0x00040000, &NIM_U::CommitSystemTitles, "CommitSystemTitles"},
|
||||
{0x00050000, &NIM_U::GetBackgroundEventForMenu, "GetBackgroundEventForMenu"},
|
||||
{0x00060000, &NIM_U::GetBackgroundEventForNews, "GetBackgroundEventForNews"},
|
||||
{0x00070000, &NIM_U::FormatSaveData, "FormatSaveData"},
|
||||
{0x00080000, &NIM_U::GetCustomerSupportCode, "GetCustomerSupportCode"},
|
||||
{0x00090000, &NIM_U::IsCommittableAllSystemTitles, "IsCommittableAllSystemTitles"},
|
||||
{0x000A0000, &NIM_U::GetBackgroundProgress, "GetBackgroundProgress"},
|
||||
{0x000B0000, &NIM_U::GetSavedHash, "GetSavedHash"},
|
||||
{0x000C0082, &NIM_U::UnregisterTask, "UnregisterTask"},
|
||||
{0x000D0080, &NIM_U::IsRegistered, "IsRegistered"},
|
||||
{0x000E0080, &NIM_U::FindTaskInfo, "FindTaskInfo"},
|
||||
{0x000F0042, &NIM_U::GetTaskInfos, "GetTaskInfos"},
|
||||
{0x00100000, &NIM_U::DeleteUnmanagedContexts, "DeleteUnmanagedContexts"},
|
||||
{0x00110000, &NIM_U::UpdateAutoTitleDownloadTasksAsync,
|
||||
"UpdateAutoTitleDownloadTasksAsync"},
|
||||
{0x00120000, &NIM_U::StartPendingAutoTitleDownloadTasksAsync,
|
||||
"StartPendingAutoTitleDownloadTasksAsync"},
|
||||
{0x00130000, &NIM_U::GetAsyncResult, "GetAsyncResult"},
|
||||
{0x00140000, &NIM_U::CancelAsyncCall, "CancelAsyncCall"},
|
||||
{0x00150000, &NIM_U::IsPendingAutoTitleDownloadTasks, "IsPendingAutoTitleDownloadTasks"},
|
||||
{0x00160000, &NIM_U::GetNumAutoTitleDownloadTasks, "GetNumAutoTitleDownloadTasks"},
|
||||
{0x00170042, &NIM_U::GetAutoTitleDownloadTaskInfos, "GetAutoTitleDownloadTaskInfos"},
|
||||
{0x00180080, &NIM_U::CancelAutoTitleDownloadTask, "CancelAutoTitleDownloadTask"},
|
||||
{0x00190002, &NIM_U::SetAutoDbgDat, "SetAutoDbgDat"},
|
||||
{0x001A0002, &NIM_U::GetAutoDbgDat, "GetAutoDbgDat"},
|
||||
{0x001B0042, &NIM_U::SetDbgTasks, "SetDbgTasks"},
|
||||
{0x001C0042, &NIM_U::GetDbgTasks, "GetDbgTasks"},
|
||||
{0x001D0000, &NIM_U::DeleteDbgData, "DeleteDbgData"},
|
||||
{0x001E0042, &NIM_U::SetTslXml, "SetTslXml"},
|
||||
{0x001F0000, &NIM_U::GetTslXmlSize, "GetTslXmlSize"},
|
||||
{0x00200042, &NIM_U::GetTslXml, "GetTslXml"},
|
||||
{0x00210000, &NIM_U::DeleteTslXml, "DeleteTslXml"},
|
||||
{0x00220042, &NIM_U::SetDtlXml, "SetDtlXml"},
|
||||
{0x00230000, &NIM_U::GetDtlXmlSize, "GetDtlXmlSize"},
|
||||
{0x00240042, &NIM_U::GetDtlXml, "GetDtlXml"},
|
||||
{0x00250000, &NIM_U::UpdateAccountStatus, "UpdateAccountStatus"},
|
||||
{0x00260180, &NIM_U::StartTitleDownload, "StartTitleDownload"},
|
||||
{0x00270000, &NIM_U::StopTitleDownload, "StopTitleDownload"},
|
||||
{0x00280000, &NIM_U::GetTitleDownloadProgress, "GetTitleDownloadProgress"},
|
||||
{0x00290246, &NIM_U::RegisterTask, "RegisterTask"},
|
||||
{0x002A0000, &NIM_U::IsSystemUpdateAvailable, "IsSystemUpdateAvailable"},
|
||||
{0x002B0000, &NIM_U::Unknown2B, "Unknown2B"},
|
||||
{0x002C0000, &NIM_U::UpdateTickets, "UpdateTickets"},
|
||||
{0x002D00C0, &NIM_U::DownloadTitleSeedAsync, "DownloadTitleSeedAsync"},
|
||||
{0x002E0000, &NIM_U::DownloadMissingTitleSeedsAsync, "DownloadMissingTitleSeedsAsync"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
nim_system_update_event =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event");
|
||||
nim_system_update_event_for_menu =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event (Menu)");
|
||||
nim_system_update_event_for_news =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event (News)");
|
||||
nim_async_completion_event =
|
||||
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM Async Completion Event");
|
||||
}
|
||||
|
||||
NIM_U::~NIM_U() = default;
|
||||
|
||||
void NIM_U::CheckForSysUpdateEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x5, 0, 0); // 0x50000
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
void NIM_U::StartNetworkUpdate(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1, 0, 0); // 0x10000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_system_update_event);
|
||||
LOG_TRACE(Service_NIM, "called");
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx) {
|
||||
void NIM_U::GetProgress(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x2, 0, 0); // 0x20000
|
||||
|
||||
SystemUpdateProgress progress{};
|
||||
std::memset(&progress, 0, sizeof(progress));
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(13, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(progress);
|
||||
rb.Push(0);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::Cancel(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x3, 0, 0); // 0x30000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::CommitSystemTitles(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x4, 0, 0); // 0x40000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetBackgroundEventForMenu(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x5, 0, 0); // 0x50000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_system_update_event_for_menu);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetBackgroundEventForNews(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x6, 0, 0); // 0x60000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_system_update_event_for_news);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::FormatSaveData(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x7, 0, 0); // 0x70000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetCustomerSupportCode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x8, 0, 0); // 0x80000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0); // Customer support code
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::IsCommittableAllSystemTitles(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x9, 0, 0); // 0x90000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(false); // No update available
|
||||
rb.Push(false);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetBackgroundProgress(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0xA, 0, 0); // 0xA0000
|
||||
|
||||
SystemUpdateProgress progress{};
|
||||
std::memset(&progress, 0, sizeof(progress));
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(13, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(progress);
|
||||
rb.Push(0);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetSavedHash(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0xB, 0, 0); // 0xB0000
|
||||
|
||||
std::array<char, 0x24> hash{};
|
||||
std::memset(&hash, 0, sizeof(hash));
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(10, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(hash);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::UnregisterTask(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0xC, 2, 2); // 0xC0082
|
||||
|
||||
const u64 title_id = rp.Pop<u64>();
|
||||
const u32 process_id = rp.PopPID();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::NIM, ErrorSummary::NotFound,
|
||||
ErrorLevel::Status));
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}, process_id={:08X}", title_id,
|
||||
process_id);
|
||||
}
|
||||
|
||||
void NIM_U::IsRegistered(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0xD, 2, 0); // 0xD0080
|
||||
|
||||
const u64 title_id = rp.Pop<u64>();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(false);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}", title_id);
|
||||
}
|
||||
|
||||
void NIM_U::FindTaskInfo(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0xE, 2, 0); // 0xE0080
|
||||
|
||||
const u64 title_id = rp.Pop<u64>();
|
||||
|
||||
std::vector<u8> buffer(0x120, 0);
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::NIM, ErrorSummary::NotFound,
|
||||
ErrorLevel::Status));
|
||||
rb.PushStaticBuffer(std::move(buffer), 0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}", title_id);
|
||||
}
|
||||
|
||||
void NIM_U::GetTaskInfos(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0xF, 1, 2); // 0xF0042
|
||||
|
||||
const u64 max_task_infos = rp.Pop<u32>();
|
||||
auto& task_infos_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
rb.PushMappedBuffer(task_infos_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
|
||||
max_task_infos, task_infos_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::DeleteUnmanagedContexts(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x10, 0, 0); // 0x100000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::UpdateAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x11, 0, 0); // 0x110000
|
||||
|
||||
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
|
||||
nim_async_completion_event->Signal();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_async_completion_event);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::StartPendingAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x11, 0, 0); // 0x120000
|
||||
|
||||
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
|
||||
nim_async_completion_event->Signal();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_async_completion_event);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetAsyncResult(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x13, 0, 0); // 0x130000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::CancelAsyncCall(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x14, 0, 0); // 0x140000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::IsPendingAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x15, 0, 0); // 0x150000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(false);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetNumAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x16, 0, 0); // 0x160000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetAutoTitleDownloadTaskInfos(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x17, 1, 2); // 0x170042
|
||||
|
||||
const u64 max_task_infos = rp.Pop<u32>();
|
||||
auto& task_infos_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
rb.PushMappedBuffer(task_infos_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
|
||||
max_task_infos, task_infos_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::CancelAutoTitleDownloadTask(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x18, 2, 0); // 0x180080
|
||||
|
||||
const u64 task_id = rp.Pop<u64>();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called task_id={:016X}", task_id);
|
||||
}
|
||||
|
||||
void NIM_U::SetAutoDbgDat(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x19, 0, 2); // 0x190002
|
||||
|
||||
auto& auto_dbg_dat_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(auto_dbg_dat_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called auto_dbg_dat_buffer=0x{:08X}",
|
||||
auto_dbg_dat_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::GetAutoDbgDat(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1A, 0, 2); // 0x1A0002
|
||||
|
||||
auto& auto_dbg_dat_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(auto_dbg_dat_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called auto_dbg_dat_buffer=0x{:08X}",
|
||||
auto_dbg_dat_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::SetDbgTasks(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1B, 1, 2); // 0x1B0042
|
||||
|
||||
const u64 max_task_infos = rp.Pop<u32>();
|
||||
auto& task_infos_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(task_infos_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
|
||||
max_task_infos, task_infos_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::GetDbgTasks(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1C, 1, 2); // 0x1C0042
|
||||
|
||||
const u64 max_task_infos = rp.Pop<u32>();
|
||||
auto& task_infos_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
rb.PushMappedBuffer(task_infos_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
|
||||
max_task_infos, task_infos_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::DeleteDbgData(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1D, 0, 0); // 0x1D0000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::SetTslXml(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1E, 1, 2); // 0x1E0042
|
||||
|
||||
const u32 buffer_size = rp.Pop<u32>();
|
||||
auto& xml_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(xml_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_size={:08X}, xml_buffer=0x{:08X}",
|
||||
buffer_size, xml_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::GetTslXmlSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1F, 0, 0); // 0x1F0000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetTslXml(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x20, 1, 2); // 0x200042
|
||||
|
||||
const u32 buffer_capacity = rp.Pop<u32>();
|
||||
auto& xml_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(xml_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_capacity={:08X}, xml_buffer=0x{:08X}",
|
||||
buffer_capacity, xml_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::DeleteTslXml(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x21, 0, 0); // 0x210000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::SetDtlXml(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x22, 1, 2); // 0x220042
|
||||
|
||||
const u32 buffer_size = rp.Pop<u32>();
|
||||
auto& xml_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(xml_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_size={:08X}, xml_buffer=0x{:08X}",
|
||||
buffer_size, xml_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::GetDtlXmlSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x23, 0, 0); // 0x230000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetDtlXml(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x24, 1, 2); // 0x240042
|
||||
|
||||
const u32 buffer_capacity = rp.Pop<u32>();
|
||||
auto& xml_buffer = rp.PopMappedBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMappedBuffer(xml_buffer);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_capacity={:08X}, xml_buffer=0x{:08X}",
|
||||
buffer_capacity, xml_buffer.GetId());
|
||||
}
|
||||
|
||||
void NIM_U::UpdateAccountStatus(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x25, 0, 0); // 0x250000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::StartTitleDownload(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x26, 6, 0); // 0x260180
|
||||
|
||||
const auto& download_config = rp.PopRaw<TitleDownloadConfig>();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}", download_config.title_id);
|
||||
}
|
||||
|
||||
void NIM_U::StopTitleDownload(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x27, 0, 0); // 0x270000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::GetTitleDownloadProgress(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x28, 0, 0); // 0x280000
|
||||
|
||||
TitleDownloadProgress progress{};
|
||||
std::memset(&progress, 0, sizeof(progress));
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(9, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(progress);
|
||||
rb.Push(0);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::RegisterTask(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x29, 9, 6); // 0x290246
|
||||
|
||||
const auto& download_config = rp.PopRaw<TitleDownloadConfig>();
|
||||
const u32 unknown_1 = rp.Pop<u32>();
|
||||
const u32 unknown_2 = rp.Pop<u32>();
|
||||
const u32 unknown_3 = rp.Pop<u32>();
|
||||
const u32 pid = rp.PopPID();
|
||||
const auto& title_name = rp.PopStaticBuffer();
|
||||
const auto& developer_name = rp.PopStaticBuffer();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
const auto title_name_end = std::find(title_name.begin(), title_name.end(), u'\0');
|
||||
const auto title_name_utf8 =
|
||||
Common::UTF16ToUTF8(std::u16string{title_name.begin(), title_name_end});
|
||||
|
||||
const auto developer_name_end = std::find(developer_name.begin(), developer_name.end(), u'\0');
|
||||
const auto developer_name_utf8 =
|
||||
Common::UTF16ToUTF8(std::u16string{developer_name.begin(), developer_name_end});
|
||||
|
||||
LOG_WARNING(Service_NIM,
|
||||
"(STUBBED) called title_id={:016X}, unknown_1={:08X}, unknown_2={:08X}, "
|
||||
"unknown_3={:08X}, pid={:08X}, title_name='{}', developer_name='{}'",
|
||||
download_config.title_id, unknown_1, unknown_2, unknown_3, pid, title_name_utf8,
|
||||
developer_name_utf8);
|
||||
}
|
||||
|
||||
void NIM_U::IsSystemUpdateAvailable(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x2A, 0, 0); // 0x2A0000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(4, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
rb.Push(false);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::Unknown2B(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x2B, 0, 0); // 0x2B0000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::UpdateTickets(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x2C, 0, 0); // 0x2C0000
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(0);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NIM_U::DownloadTitleSeedAsync(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x2D, 3, 0); // 0x2D00C0
|
||||
|
||||
const u64 title_id = rp.Pop<u64>();
|
||||
const u16 country_code = rp.Pop<u16>();
|
||||
|
||||
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
|
||||
nim_async_completion_event->Signal();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_async_completion_event);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}, country_code={:04X}", title_id,
|
||||
country_code);
|
||||
}
|
||||
|
||||
void NIM_U::DownloadMissingTitleSeedsAsync(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x2E, 0, 0); // 0x2E0000
|
||||
|
||||
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
|
||||
nim_async_completion_event->Signal();
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(nim_async_completion_event);
|
||||
|
||||
LOG_WARNING(Service_NIM, "(STUBBED) called");
|
||||
}
|
||||
|
@ -20,32 +20,522 @@ public:
|
||||
|
||||
private:
|
||||
/**
|
||||
* NIM::CheckForSysUpdateEvent service function
|
||||
* NIM::StartNetworkUpdate service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy handle descriptor
|
||||
* 3 : System Update event handle
|
||||
*/
|
||||
void CheckForSysUpdateEvent(Kernel::HLERequestContext& ctx);
|
||||
void StartNetworkUpdate(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::CheckSysUpdateAvailable service function
|
||||
* NIM::GetProgress service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : u8 flag, 0 = no system update available, 1 = system update available.
|
||||
* 2-11 : SystemUpdateProgress structure for the foreground system update
|
||||
* 12: ?
|
||||
* 13: ?
|
||||
*/
|
||||
void CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx);
|
||||
void GetProgress(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<Kernel::Event> nim_system_update_event;
|
||||
/**
|
||||
* NIM::Cancel service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void Cancel(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::CommitSystemTitles service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void CommitSystemTitles(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetBackgroundEventForMenu service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy handle IPC header
|
||||
* 3 : System update ready event handle for home menu
|
||||
*/
|
||||
void GetBackgroundEventForMenu(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetBackgroundEventForNews service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy handle IPC header
|
||||
* 3 : System update ready event handle for news module
|
||||
*/
|
||||
void GetBackgroundEventForNews(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::FormatSaveData service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void FormatSaveData(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetCustomerSupportCode service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Customer support code for the last system update error
|
||||
*/
|
||||
void GetCustomerSupportCode(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::IsCommittableAllSystemTitles service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Boolean indicating whether system titles are ready to commit
|
||||
*/
|
||||
void IsCommittableAllSystemTitles(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetBackgroundProgress service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2-11 : SystemUpdateProgress structure for the background system update
|
||||
* 12: ?
|
||||
* 13: ?
|
||||
*/
|
||||
void GetBackgroundProgress(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetSavedHash service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2-10 : NUL-terminated saved system update hash
|
||||
*/
|
||||
void GetSavedHash(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::UnregisterTask service function
|
||||
* Inputs:
|
||||
* 1-2 : Title ID
|
||||
* 3 : Process ID IPC Header
|
||||
* 4 : Process ID (Auto-filled by kernel)
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void UnregisterTask(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::IsRegistered service function
|
||||
* Inputs:
|
||||
* 1-2 : Title ID
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Boolean indicating whether a download task is registered for the title ID
|
||||
*/
|
||||
void IsRegistered(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::FindTaskInfo service function
|
||||
* Inputs:
|
||||
* 1-2 : Title ID
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Static Buffer IPC Header (ID = 0, Size = 0x120)
|
||||
* 3 : BackgroundTitleDownloadTaskInfo structure pointer
|
||||
*/
|
||||
void FindTaskInfo(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetTaskInfos service function
|
||||
* Inputs:
|
||||
* 1 : Maximum Number of BackgroundTitleDownloadTaskInfos
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : BackgroundTitleDownloadTaskInfos Output Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Number of BackgroundTitleDownloadTaskInfos Read
|
||||
* 3 : Mapped Output Buffer IPC Header
|
||||
* 4 : BackgroundTitleDownloadTaskInfos Output Buffer Pointer
|
||||
*/
|
||||
void GetTaskInfos(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::DeleteUnmanagedContexts service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void DeleteUnmanagedContexts(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::UpdateAutoTitleDownloadTasksAsync service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy Handle IPC Header
|
||||
* 3 : Event handle signaled when the operation completes
|
||||
*/
|
||||
void UpdateAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::StartPendingAutoTitleDownloadTasksAsync service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy Handle IPC Header
|
||||
* 3 : Event handle signaled when the operation completes
|
||||
*/
|
||||
void StartPendingAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetAsyncResult service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Async operation result code
|
||||
* 3 : Async operation customer support code
|
||||
*/
|
||||
void GetAsyncResult(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::CancelAsyncCall service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void CancelAsyncCall(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::IsPendingAutoTitleDownloadTasks service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Boolean indicating whether there are auto title downloads ready to start
|
||||
*/
|
||||
void IsPendingAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetNumAutoTitleDownloadTasks service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Number of auto title download tasks
|
||||
*/
|
||||
void GetNumAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetAutoTitleDownloadTasks service function
|
||||
* Inputs:
|
||||
* 1 : Maximum number of AutoTitleDownloadTaskInfos
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : AutoTitleDownloadTaskInfos Output Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Number of AutoTitleDownloadTaskInfos Read
|
||||
* 3 : Mapped Output Buffer IPC Header
|
||||
* 4 : AutoTitleDownloadTaskInfos Output Buffer Pointer
|
||||
*/
|
||||
void GetAutoTitleDownloadTaskInfos(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::CancelAutoTitleDownloadTask service function
|
||||
* Inputs:
|
||||
* 1-2 : Auto Title Download Task ID
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void CancelAutoTitleDownloadTask(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::SetAutoDbgDat service function
|
||||
* Inputs:
|
||||
* 1 : Mapped Input Buffer IPC Header
|
||||
* 2 : AutoDbgDat Input Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Mapped Input Buffer IPC Header
|
||||
* 3 : AutoDbgDat Input Buffer Pointer
|
||||
*/
|
||||
void SetAutoDbgDat(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetAutoDbgDat service function
|
||||
* Inputs:
|
||||
* 1 : Mapped Output Buffer IPC Header
|
||||
* 2 : AutoDbgDat Output Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : AutoDbgDat Output Buffer Pointer
|
||||
*/
|
||||
void GetAutoDbgDat(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::SetDbgTasks service function
|
||||
* Inputs:
|
||||
* 1 : Number of AutoTitleDownloadTaskInfos
|
||||
* 2 : Mapped Input Buffer IPC Header
|
||||
* 3 : AutoTitleDownloadTaskInfos Input Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 3 : Mapped Input Buffer IPC Header
|
||||
* 4 : AutoTitleDownloadTaskInfos Input Buffer Pointer
|
||||
*/
|
||||
void SetDbgTasks(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetDbgTasks service function
|
||||
* Inputs:
|
||||
* 1 : Maximum number of AutoTitleDownloadTaskInfos
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : AutoTitleDownloadTaskInfos Output Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Number of AutoTitleDownloadTaskInfos Read
|
||||
* 3 : Mapped Output Buffer IPC Header
|
||||
* 4 : AutoTitleDownloadTaskInfos Output Buffer Pointer
|
||||
*/
|
||||
void GetDbgTasks(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::DeleteDbgData service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void DeleteDbgData(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::SetTslXml service function
|
||||
* Inputs:
|
||||
* 1 : Buffer Size
|
||||
* 2 : Mapped Input Buffer IPC Header
|
||||
* 3 : XML Input Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Mapped Input Buffer IPC Header
|
||||
* 3 : XML Input Buffer Pointer
|
||||
*/
|
||||
void SetTslXml(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetTslXmlSize service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2-3 : XML Size
|
||||
*/
|
||||
void GetTslXmlSize(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetTslXml service function
|
||||
* Inputs:
|
||||
* 1 : Buffer Capacity
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : XML Output Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : XML Output Buffer Pointer
|
||||
*/
|
||||
void GetTslXml(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::DeleteTslXml service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void DeleteTslXml(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::SetDtlXml service function
|
||||
* Inputs:
|
||||
* 1 : Buffer Size
|
||||
* 2 : Mapped Input Buffer IPC Header
|
||||
* 3 : XML Input Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Mapped Input Buffer IPC Header
|
||||
* 3 : XML Input Buffer Pointer
|
||||
*/
|
||||
void SetDtlXml(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetDtlXmlSize service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2-3 : XML Size
|
||||
*/
|
||||
void GetDtlXmlSize(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetDtlXml service function
|
||||
* Inputs:
|
||||
* 1 : Buffer Capacity
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : XML Output Buffer Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Mapped Output Buffer IPC Header
|
||||
* 3 : XML Output Buffer Pointer
|
||||
*/
|
||||
void GetDtlXml(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::UpdateAccountStatus service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Result of the actual operation
|
||||
* 3 : Customer support code of the actual operation
|
||||
*/
|
||||
void UpdateAccountStatus(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::StartTitleDownload service function
|
||||
* Inputs:
|
||||
* 1-6 : TitleDownloadConfig structure
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void StartTitleDownload(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::StopDownload service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void StopTitleDownload(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::GetTitleDownloadProgress service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2-7 : TitleDownloadProgress structure
|
||||
* 8: ?
|
||||
* 9: ?
|
||||
*/
|
||||
void GetTitleDownloadProgress(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::RegisterTask service function
|
||||
* Inputs:
|
||||
* 1-6 : TitleDownloadConfig structure
|
||||
* 7: ?
|
||||
* 8: ?
|
||||
* 9: ?
|
||||
* 10: Process ID IPC Header
|
||||
* 11: Process ID (Auto-filled by Kernel)
|
||||
* 12: Static Buffer IPC Header (ID = 0, Size = 0x90)
|
||||
* 13: Title Name UTF-16 String Pointer
|
||||
* 14: Static Buffer IPC Header (ID = 1, Size = 0x48)
|
||||
* 15: Developer Name UTF-16 String Pointer
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void RegisterTask(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::IsSystemUpdateAvailable service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Result code from the actual operation
|
||||
* 3 : Customer support code from the actual operation
|
||||
* 4 : Boolean indicating whether a system update is available
|
||||
*/
|
||||
void IsSystemUpdateAvailable(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::Unknown2B service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
*/
|
||||
void Unknown2B(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::UpdateTickets service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Result code from the actual operation
|
||||
* 3 : Customer support code from the actual operation
|
||||
*/
|
||||
void UpdateTickets(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::DownloadTitleSeedAsync service function
|
||||
* Inputs:
|
||||
* 1-2 : Title ID
|
||||
* 3: u16 Country Code
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy Handle IPC Header
|
||||
* 3 : Event handle signaled when the operation completes
|
||||
*/
|
||||
void DownloadTitleSeedAsync(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/**
|
||||
* NIM::DownloadMissingTitleSeedsAsync service function
|
||||
* Inputs:
|
||||
* 1 : None
|
||||
* Outputs:
|
||||
* 1 : Result of function, 0 on success, otherwise error code
|
||||
* 2 : Copy Handle IPC Header
|
||||
* 3 : Event handle signaled when the operation completes
|
||||
*/
|
||||
void DownloadMissingTitleSeedsAsync(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<Kernel::Event> nim_system_update_event_for_menu;
|
||||
std::shared_ptr<Kernel::Event> nim_system_update_event_for_news;
|
||||
std::shared_ptr<Kernel::Event> nim_async_completion_event;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int) {
|
||||
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
|
||||
ar& nim_system_update_event;
|
||||
ar& nim_system_update_event_for_menu;
|
||||
ar& nim_system_update_event_for_news;
|
||||
ar& nim_async_completion_event;
|
||||
}
|
||||
friend class boost::serialization::access;
|
||||
};
|
||||
|
@ -233,7 +233,7 @@ void LoadNativeFirmKeysOld3DS() {
|
||||
firm->Read(0, firm_buffer.size(), firm_buffer.data());
|
||||
firm->Close();
|
||||
|
||||
constexpr std::size_t SLOT_0x25_KEY_X_SECRET_OFFSET = 933480;
|
||||
constexpr std::size_t SLOT_0x25_KEY_X_SECRET_OFFSET = 934444;
|
||||
constexpr std::size_t SLOT_0x25_KEY_X_SECRET_SIZE = 64;
|
||||
std::vector<u8> secret_data(SLOT_0x25_KEY_X_SECRET_SIZE);
|
||||
std::memcpy(secret_data.data(), firm_buffer.data() + SLOT_0x25_KEY_X_SECRET_OFFSET,
|
||||
|
@ -876,7 +876,7 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||
}
|
||||
|
||||
glUniform1i(uniform_layer, 0);
|
||||
if (!Settings::values.swap_screen) {
|
||||
if (!Settings::values.swap_screen.GetValue()) {
|
||||
DrawTopScreen(layout, top_screen, stereo_single_screen);
|
||||
glUniform1i(uniform_layer, 0);
|
||||
ApplySecondLayerOpacity();
|
||||
@ -887,13 +887,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||
ApplySecondLayerOpacity();
|
||||
DrawTopScreen(layout, top_screen, stereo_single_screen);
|
||||
}
|
||||
state.blend.enabled = false;
|
||||
ResetSecondLayerOpacity();
|
||||
}
|
||||
|
||||
void RendererOpenGL::ApplySecondLayerOpacity() {
|
||||
if (Settings::values.custom_layout &&
|
||||
Settings::values.custom_second_layer_opacity.GetValue() < 100) {
|
||||
state.blend.enabled = true;
|
||||
state.blend.src_rgb_func = GL_CONSTANT_ALPHA;
|
||||
state.blend.src_a_func = GL_CONSTANT_ALPHA;
|
||||
state.blend.dst_a_func = GL_ONE_MINUS_CONSTANT_ALPHA;
|
||||
@ -902,6 +901,17 @@ void RendererOpenGL::ApplySecondLayerOpacity() {
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::ResetSecondLayerOpacity() {
|
||||
if (Settings::values.custom_layout &&
|
||||
Settings::values.custom_second_layer_opacity.GetValue() < 100) {
|
||||
state.blend.src_rgb_func = GL_ONE;
|
||||
state.blend.dst_rgb_func = GL_ZERO;
|
||||
state.blend.src_a_func = GL_ONE;
|
||||
state.blend.dst_a_func = GL_ZERO;
|
||||
state.blend.color.alpha = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
|
||||
const Common::Rectangle<u32>& top_screen,
|
||||
const bool stereo_single_screen) {
|
||||
@ -911,8 +921,10 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
|
||||
|
||||
if (layout.is_rotated) {
|
||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
|
||||
DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top,
|
||||
(float)top_screen.GetWidth(), (float)top_screen.GetHeight());
|
||||
int eye = static_cast<int>(Settings::values.mono_render_option.GetValue());
|
||||
DrawSingleScreenRotated(screen_infos[eye], (float)top_screen.left,
|
||||
(float)top_screen.top, (float)top_screen.GetWidth(),
|
||||
(float)top_screen.GetHeight());
|
||||
} else if (Settings::values.render_3d.GetValue() ==
|
||||
Settings::StereoRenderOption::SideBySide) {
|
||||
DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left / 2,
|
||||
@ -938,7 +950,8 @@ void RendererOpenGL::DrawTopScreen(const Layout::FramebufferLayout& layout,
|
||||
}
|
||||
} else {
|
||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
|
||||
DrawSingleScreen(screen_infos[0], (float)top_screen.left, (float)top_screen.top,
|
||||
int eye = static_cast<int>(Settings::values.mono_render_option.GetValue());
|
||||
DrawSingleScreen(screen_infos[eye], (float)top_screen.left, (float)top_screen.top,
|
||||
(float)top_screen.GetWidth(), (float)top_screen.GetHeight());
|
||||
} else if (Settings::values.render_3d.GetValue() ==
|
||||
Settings::StereoRenderOption::SideBySide) {
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
*/
|
||||
void DrawScreens(const Layout::FramebufferLayout& layout, bool flipped);
|
||||
void ApplySecondLayerOpacity();
|
||||
void ResetSecondLayerOpacity();
|
||||
void DrawBottomScreen(const Layout::FramebufferLayout& layout,
|
||||
const Common::Rectangle<u32>& bottom_screen,
|
||||
const bool stereo_single_screen);
|
||||
|
Reference in New Issue
Block a user