summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/hle/dsp.cpp4
-rw-r--r--src/audio_core/hle/pipe.cpp4
-rw-r--r--src/audio_core/sdl2_sink.cpp4
-rw-r--r--src/citra/CMakeLists.txt2
-rw-r--r--src/citra/config.cpp5
-rw-r--r--src/citra/default_ini.h10
-rw-r--r--src/citra/emu_window/emu_window_sdl2.cpp5
-rw-r--r--src/citra_qt/CMakeLists.txt2
-rw-r--r--src/citra_qt/bootmanager.cpp4
-rw-r--r--src/citra_qt/config.cpp11
-rw-r--r--src/citra_qt/configure_dialog.cpp1
-rw-r--r--src/citra_qt/configure_graphics.cpp5
-rw-r--r--src/citra_qt/configure_graphics.ui115
-rw-r--r--src/citra_qt/debugger/graphics_vertex_shader.cpp4
-rw-r--r--src/citra_qt/debugger/registers.cpp2
-rw-r--r--src/citra_qt/game_list_p.h2
-rw-r--r--src/citra_qt/main.cpp14
-rw-r--r--src/citra_qt/main.h1
-rw-r--r--src/citra_qt/main.ui2
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/emu_window.cpp68
-rw-r--r--src/common/emu_window.h30
-rw-r--r--src/common/file_util.cpp25
-rw-r--r--src/common/framebuffer_layout.cpp138
-rw-r--r--src/common/framebuffer_layout.h47
-rw-r--r--src/common/hash.cpp2
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/logging/text_formatter.h2
-rw-r--r--src/common/math_util.h10
-rw-r--r--src/common/string_util.cpp5
-rw-r--r--src/common/swap.h7
-rw-r--r--src/common/thread.cpp12
-rw-r--r--src/common/vector_math.h3
-rw-r--r--src/common/x64/cpu_detect.cpp8
-rw-r--r--src/core/gdbstub/gdbstub.cpp4
-rw-r--r--src/core/hle/applets/erreula.cpp6
-rw-r--r--src/core/hle/applets/mii_selector.cpp6
-rw-r--r--src/core/hle/applets/swkbd.cpp6
-rw-r--r--src/core/hle/kernel/event.cpp5
-rw-r--r--src/core/hle/kernel/memory.cpp2
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/kernel/timer.cpp5
-rw-r--r--src/core/hle/service/ac_u.cpp207
-rw-r--r--src/core/hle/service/ac_u.h1
-rw-r--r--src/core/hle/service/apt/apt.cpp2
-rw-r--r--src/core/hle/service/apt/apt.h23
-rw-r--r--src/core/hle/service/boss/boss.cpp967
-rw-r--r--src/core/hle/service/boss/boss.h785
-rw-r--r--src/core/hle/service/boss/boss_u.cpp60
-rw-r--r--src/core/hle/service/frd/frd.cpp2
-rw-r--r--src/core/hle/service/ldr_ro/cro_helper.cpp2
-rw-r--r--src/core/hle/service/nwm_uds.cpp11
-rw-r--r--src/core/hle/service/soc_u.cpp8
-rw-r--r--src/core/loader/ncch.cpp2
-rw-r--r--src/core/loader/ncch.h2
-rw-r--r--src/core/settings.cpp7
-rw-r--r--src/core/settings.h11
-rw-r--r--src/video_core/command_processor.cpp13
-rw-r--r--src/video_core/pica.h2
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp17
-rw-r--r--src/video_core/shader/shader.cpp4
-rw-r--r--src/video_core/shader/shader_interpreter.cpp74
63 files changed, 2538 insertions, 256 deletions
diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp
index 58690970a..31421fdc6 100644
--- a/src/audio_core/hle/dsp.cpp
+++ b/src/audio_core/hle/dsp.cpp
@@ -23,12 +23,12 @@ static size_t CurrentRegionIndex() {
// This function only returns a 0 or 1.
if (g_regions[0].frame_counter == 0xFFFFu && g_regions[1].frame_counter != 0xFFFEu) {
- // Wraparound has occured.
+ // Wraparound has occurred.
return 1;
}
if (g_regions[1].frame_counter == 0xFFFFu && g_regions[0].frame_counter != 0xFFFEu) {
- // Wraparound has occured.
+ // Wraparound has occurred.
return 0;
}
diff --git a/src/audio_core/hle/pipe.cpp b/src/audio_core/hle/pipe.cpp
index b472c81d8..bc69acbc2 100644
--- a/src/audio_core/hle/pipe.cpp
+++ b/src/audio_core/hle/pipe.cpp
@@ -117,7 +117,7 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) {
}
enum class StateChange {
- Initalize = 0,
+ Initialize = 0,
Shutdown = 1,
Wakeup = 2,
Sleep = 3,
@@ -130,7 +130,7 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) {
// sleeping and reset it back after wakeup on behalf of the DSP.
switch (static_cast<StateChange>(buffer[0])) {
- case StateChange::Initalize:
+ case StateChange::Initialize:
LOG_INFO(Audio_DSP, "Application has requested initialization of DSP hardware");
ResetPipes();
AudioPipeWriteStructAddresses();
diff --git a/src/audio_core/sdl2_sink.cpp b/src/audio_core/sdl2_sink.cpp
index 75cc0d6dd..4b66cd826 100644
--- a/src/audio_core/sdl2_sink.cpp
+++ b/src/audio_core/sdl2_sink.cpp
@@ -25,7 +25,7 @@ struct SDL2Sink::Impl {
SDL2Sink::SDL2Sink() : impl(std::make_unique<Impl>()) {
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
- LOG_CRITICAL(Audio_Sink, "SDL_Init(SDL_INIT_AUDIO) failed");
+ LOG_CRITICAL(Audio_Sink, "SDL_Init(SDL_INIT_AUDIO) failed with: %s", SDL_GetError());
impl->audio_device_id = 0;
return;
}
@@ -45,7 +45,7 @@ SDL2Sink::SDL2Sink() : impl(std::make_unique<Impl>()) {
impl->audio_device_id =
SDL_OpenAudioDevice(nullptr, false, &desired_audiospec, &obtained_audiospec, 0);
if (impl->audio_device_id <= 0) {
- LOG_CRITICAL(Audio_Sink, "SDL_OpenAudioDevice failed");
+ LOG_CRITICAL(Audio_Sink, "SDL_OpenAudioDevice failed with: %s", SDL_GetError());
return;
}
diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt
index 43fa06b4e..f9c488a1a 100644
--- a/src/citra/CMakeLists.txt
+++ b/src/citra/CMakeLists.txt
@@ -23,7 +23,7 @@ if (MSVC)
endif()
target_link_libraries(citra ${PLATFORM_LIBRARIES} Threads::Threads)
-if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD")
+if(UNIX AND NOT APPLE)
install(TARGETS citra RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endif()
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 05eabfa3d..fd30bfc85 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -72,6 +72,11 @@ void Config::ReadValues() {
Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 1.0);
Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 1.0);
+ // Layout
+ Settings::values.layout_option =
+ static_cast<Settings::LayoutOption>(sdl2_config->GetInteger("Layout", "layout_option", 0));
+ Settings::values.swap_screen = sdl2_config->GetBoolean("Layout", "swap_screen", false);
+
// Audio
Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto");
Settings::values.enable_audio_stretching =
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h
index 0b49e0230..b22627a2f 100644
--- a/src/citra/default_ini.h
+++ b/src/citra/default_ini.h
@@ -63,6 +63,16 @@ use_scaled_resolution =
# 0 (default): Off, 1: On
use_vsync =
+[Layout]
+# Layout for the screen inside the render window.
+# 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen
+layout_option =
+
+# Swaps the prominent screen with the other screen.
+# For example, if Single Screen is chosen, setting this to 1 will display the bottom screen instead of the top screen.
+# 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent
+swap_screen =
+
# The clear color for the renderer. What shows up on the sides of the bottom screen.
# Must be in range of 0.0-1.0. Defaults to 1.0 for all.
bg_red =
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp
index 7df054208..8abe48984 100644
--- a/src/citra/emu_window/emu_window_sdl2.cpp
+++ b/src/citra/emu_window/emu_window_sdl2.cpp
@@ -46,11 +46,8 @@ bool EmuWindow_SDL2::IsOpen() const {
void EmuWindow_SDL2::OnResize() {
int width, height;
-
SDL_GetWindowSize(render_window, &width, &height);
-
- NotifyFramebufferLayoutChanged(
- EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height));
+ UpdateCurrentFramebufferLayout(width, height);
}
EmuWindow_SDL2::EmuWindow_SDL2() {
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index b3c01ddd8..384875450 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -104,7 +104,7 @@ target_link_libraries(citra-qt core video_core audio_core common qhexedit)
target_link_libraries(citra-qt ${OPENGL_gl_LIBRARY} ${CITRA_QT_LIBS})
target_link_libraries(citra-qt ${PLATFORM_LIBRARIES} Threads::Threads)
-if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD")
+if(UNIX AND NOT APPLE)
install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endif()
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 0abae86c3..7699ca8d0 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -161,9 +161,7 @@ void GRenderWindow::OnFramebufferSizeChanged() {
qreal pixelRatio = windowPixelRatio();
unsigned width = child->QPaintDevice::width() * pixelRatio;
unsigned height = child->QPaintDevice::height() * pixelRatio;
-
- NotifyFramebufferLayoutChanged(
- EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height));
+ UpdateCurrentFramebufferLayout(width, height);
}
void GRenderWindow::BackupGeometry() {
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 0b46ca6bb..3d2312619 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -54,6 +54,12 @@ void Config::ReadValues() {
Settings::values.bg_blue = qt_config->value("bg_blue", 1.0).toFloat();
qt_config->endGroup();
+ qt_config->beginGroup("Layout");
+ Settings::values.layout_option =
+ static_cast<Settings::LayoutOption>(qt_config->value("layout_option").toInt());
+ Settings::values.swap_screen = qt_config->value("swap_screen", false).toBool();
+ qt_config->endGroup();
+
qt_config->beginGroup("Audio");
Settings::values.sink_id = qt_config->value("output_engine", "auto").toString().toStdString();
Settings::values.enable_audio_stretching =
@@ -155,6 +161,11 @@ void Config::SaveValues() {
qt_config->setValue("bg_blue", (double)Settings::values.bg_blue);
qt_config->endGroup();
+ qt_config->beginGroup("Layout");
+ qt_config->setValue("layout_option", static_cast<int>(Settings::values.layout_option));
+ qt_config->setValue("swap_screen", Settings::values.swap_screen);
+ qt_config->endGroup();
+
qt_config->beginGroup("Audio");
qt_config->setValue("output_engine", QString::fromStdString(Settings::values.sink_id));
qt_config->setValue("enable_audio_stretching", Settings::values.enable_audio_stretching);
diff --git a/src/citra_qt/configure_dialog.cpp b/src/citra_qt/configure_dialog.cpp
index 446ad04a1..525a7cc4e 100644
--- a/src/citra_qt/configure_dialog.cpp
+++ b/src/citra_qt/configure_dialog.cpp
@@ -23,4 +23,5 @@ void ConfigureDialog::applyConfiguration() {
ui->graphicsTab->applyConfiguration();
ui->audioTab->applyConfiguration();
ui->debugTab->applyConfiguration();
+ Settings::Apply();
}
diff --git a/src/citra_qt/configure_graphics.cpp b/src/citra_qt/configure_graphics.cpp
index 19c1f75c2..29834e11b 100644
--- a/src/citra_qt/configure_graphics.cpp
+++ b/src/citra_qt/configure_graphics.cpp
@@ -23,6 +23,8 @@ void ConfigureGraphics::setConfiguration() {
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit);
ui->toggle_scaled_resolution->setChecked(Settings::values.use_scaled_resolution);
ui->toggle_vsync->setChecked(Settings::values.use_vsync);
+ ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option));
+ ui->swap_screen->setChecked(Settings::values.swap_screen);
}
void ConfigureGraphics::applyConfiguration() {
@@ -30,5 +32,8 @@ void ConfigureGraphics::applyConfiguration() {
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
Settings::values.use_scaled_resolution = ui->toggle_scaled_resolution->isChecked();
Settings::values.use_vsync = ui->toggle_vsync->isChecked();
+ Settings::values.layout_option =
+ static_cast<Settings::LayoutOption>(ui->layout_combobox->currentIndex());
+ Settings::values.swap_screen = ui->swap_screen->isChecked();
Settings::Apply();
}
diff --git a/src/citra_qt/configure_graphics.ui b/src/citra_qt/configure_graphics.ui
index da6e19ce1..af16a4292 100644
--- a/src/citra_qt/configure_graphics.ui
+++ b/src/citra_qt/configure_graphics.ui
@@ -22,38 +22,88 @@
<string>Graphics</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QCheckBox" name="toggle_hw_renderer">
- <property name="text">
- <string>Enable hardware renderer</string>
- </property>
+ <item>
+ <widget class="QCheckBox" name="toggle_hw_renderer">
+ <property name="text">
+ <string>Enable hardware renderer</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="toggle_shader_jit">
+ <property name="text">
+ <string>Enable shader JIT</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="toggle_scaled_resolution">
+ <property name="text">
+ <string>Enable scaled resolution</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="toggle_vsync">
+ <property name="text">
+ <string>Enable V-Sync</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox2">
+ <property name="title">
+ <string>Layout</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label1">
+ <property name="text">
+ <string>Screen Layout:</string>
+ </property>
</widget>
- </item>
- <item>
- <widget class="QCheckBox" name="toggle_shader_jit">
+ </item>
+ <item>
+ <widget class="QComboBox" name="layout_combobox">
+ <item>
<property name="text">
- <string>Enable shader JIT</string>
+ <string notr="true">Default</string>
</property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="toggle_scaled_resolution">
+ </item>
+ <item>
<property name="text">
- <string>Enable scaled resolution</string>
+ <string notr="true">Single Screen</string>
</property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="toggle_vsync">
+ </item>
+ <item>
<property name="text">
- <string>Enable V-Sync</string>
+ <string notr="true">Large Screen</string>
</property>
+ </item>
</widget>
- </item>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="swap_screen">
+ <property name="text">
+ <string>Swap Screens</string>
+ </property>
+ </widget>
+ </item>
</layout>
- </widget>
- </item>
- </layout>
+ </item>
+ </layout>
+ </widget>
</item>
<item>
<spacer name="verticalSpacer">
@@ -71,22 +121,5 @@
</layout>
</widget>
<resources/>
- <connections>
- <connection>
- <sender>toggle_gdbstub</sender>
- <signal>toggled(bool)</signal>
- <receiver>gdbport_spinbox</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>84</x>
- <y>157</y>
- </hint>
- <hint type="destinationlabel">
- <x>342</x>
- <y>158</y>
- </hint>
- </hints>
- </connection>
- </connections>
+ <connections/>
</ui>
diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp
index 0b4320da5..96b40db1e 100644
--- a/src/citra_qt/debugger/graphics_vertex_shader.cpp
+++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp
@@ -424,7 +424,7 @@ GraphicsVertexShaderWidget::GraphicsVertexShaderWidget(
// Create an HBoxLayout to store the widgets used to specify a particular attribute
// and store it in a QWidget to allow for easy hiding and unhiding.
auto row_layout = new QHBoxLayout;
- // Remove unecessary padding between rows
+ // Remove unnecessary padding between rows
row_layout->setContentsMargins(0, 0, 0, 0);
row_layout->addWidget(new QLabel(tr("Attribute %1").arg(i, 2)));
@@ -590,7 +590,7 @@ void GraphicsVertexShaderWidget::OnCycleIndexChanged(int index) {
.arg(record.dest_out.w.ToFloat32());
if (record.mask & Pica::Shader::DebugDataRecord::ADDR_REG_OUT)
- text += tr("Addres Registers: %1, %2\n")
+ text += tr("Address Registers: %1, %2\n")
.arg(record.address_registers[0])
.arg(record.address_registers[1]);
if (record.mask & Pica::Shader::DebugDataRecord::CMP_RESULT)
diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp
index 0b644432f..4c529d3c3 100644
--- a/src/citra_qt/debugger/registers.cpp
+++ b/src/citra_qt/debugger/registers.cpp
@@ -136,7 +136,7 @@ void RegistersWidget::UpdateCPSRValues() {
cpsr->child(2)->setText(1, QString::number((cpsr_val >> 6) & 1)); // F - FIQ disable
cpsr->child(3)->setText(1, QString::number((cpsr_val >> 7) & 1)); // I - IRQ disable
cpsr->child(4)->setText(1, QString::number((cpsr_val >> 8) & 1)); // A - Imprecise abort
- cpsr->child(5)->setText(1, QString::number((cpsr_val >> 9) & 1)); // E - Data endianess
+ cpsr->child(5)->setText(1, QString::number((cpsr_val >> 9) & 1)); // E - Data endianness
cpsr->child(6)->setText(1,
QString::number((cpsr_val >> 10) & 0x3F)); // IT - If-Then state (DNM)
cpsr->child(7)->setText(1,
diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h
index 60ab4cf02..5ca3fe991 100644
--- a/src/citra_qt/game_list_p.h
+++ b/src/citra_qt/game_list_p.h
@@ -64,7 +64,7 @@ public:
* A specialization of GameListItem for path values.
* This class ensures that for every full path value it holds, a correct string representation
* of just the filename (with no extension) will be displayed to the user.
- * If this class recieves valid SMDH data, it will also display game icons and titles.
+ * If this class receives valid SMDH data, it will also display game icons and titles.
*/
class GameListItemPath : public GameListItem {
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 8322e2305..0bf9f48d6 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -48,6 +48,10 @@
#include "qhexedit.h"
#include "video_core/video_core.h"
+#ifdef QT_STATICPLUGIN
+Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
+#endif
+
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
Pica::g_debug_context = Pica::DebugContext::Construct();
@@ -101,7 +105,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget);
graphicsTracingWidget->hide();
- auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica surface viewer"), this);
+ auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica Surface Viewer"), this);
connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this,
SLOT(OnCreateGraphicsSurfaceViewer()));
@@ -196,6 +200,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
// Setup hotkeys
RegisterHotkey("Main Window", "Load File", QKeySequence::Open);
+ RegisterHotkey("Main Window", "Swap Screens", QKeySequence::NextChild);
RegisterHotkey("Main Window", "Start Emulation");
LoadHotkeys();
@@ -203,6 +208,8 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
SLOT(OnMenuLoadFile()));
connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this,
SLOT(OnStartGame()));
+ connect(GetHotkey("Main Window", "Swap Screens", this), SIGNAL(activated()), this,
+ SLOT(OnSwapScreens()));
std::string window_title =
Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
@@ -550,6 +557,11 @@ void GMainWindow::OnConfigure() {
}
}
+void GMainWindow::OnSwapScreens() {
+ Settings::values.swap_screen = !Settings::values.swap_screen;
+ Settings::Apply();
+}
+
void GMainWindow::OnCreateGraphicsSurfaceViewer() {
auto graphicsSurfaceViewerWidget = new GraphicsSurfaceWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsSurfaceViewerWidget);
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index 2cf308d80..82eb90aae 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -105,6 +105,7 @@ private slots:
/// Called whenever a user selects the "File->Select Game List Root" menu item
void OnMenuSelectGameListRoot();
void OnMenuRecentFile();
+ void OnSwapScreens();
void OnConfigure();
void OnDisplayTitleBars(bool);
void ToggleWindowMode();
diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui
index 441e0b81e..adfa3689e 100644
--- a/src/citra_qt/main.ui
+++ b/src/citra_qt/main.ui
@@ -148,7 +148,7 @@
</action>
<action name="action_Configure">
<property name="text">
- <string>Configure ...</string>
+ <string>Configure...</string>
</property>
</action>
<action name="actionDisplay_widget_title_bars">
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index aa6eee2a3..74a271f08 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SRCS
break_points.cpp
emu_window.cpp
file_util.cpp
+ framebuffer_layout.cpp
hash.cpp
key_map.cpp
logging/filter.cpp
@@ -35,6 +36,7 @@ set(HEADERS
common_types.h
emu_window.h
file_util.h
+ framebuffer_layout.h
hash.h
key_map.h
linear_disk_cache.h
diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp
index 122f1c212..e3a9e08e6 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -40,7 +40,7 @@ void EmuWindow::CirclePadUpdated(float x, float y) {
* @param framebuffer_y Framebuffer y-coordinate to check
* @return True if the coordinates are within the touchpad, otherwise false
*/
-static bool IsWithinTouchscreen(const EmuWindow::FramebufferLayout& layout, unsigned framebuffer_x,
+static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
unsigned framebuffer_y) {
return (
framebuffer_y >= layout.bottom_screen.top && framebuffer_y < layout.bottom_screen.bottom &&
@@ -89,57 +89,19 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) {
TouchPressed(framebuffer_x, framebuffer_y);
}
-EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width,
- unsigned height) {
- // When hiding the widget, the function receives a size of 0
- if (width == 0)
- width = 1;
- if (height == 0)
- height = 1;
-
- EmuWindow::FramebufferLayout res = {width, height, {}, {}};
-
- float window_aspect_ratio = static_cast<float>(height) / width;
- float emulation_aspect_ratio =
- static_cast<float>(VideoCore::kScreenTopHeight * 2) / VideoCore::kScreenTopWidth;
-
- if (window_aspect_ratio > emulation_aspect_ratio) {
- // Window is narrower than the emulation content => apply borders to the top and bottom
- int viewport_height = static_cast<int>(std::round(emulation_aspect_ratio * width));
-
- res.top_screen.left = 0;
- res.top_screen.right = res.top_screen.left + width;
- res.top_screen.top = (height - viewport_height) / 2;
- res.top_screen.bottom = res.top_screen.top + viewport_height / 2;
-
- int bottom_width = static_cast<int>(
- (static_cast<float>(VideoCore::kScreenBottomWidth) / VideoCore::kScreenTopWidth) *
- (res.top_screen.right - res.top_screen.left));
- int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2;
-
- res.bottom_screen.left = bottom_border;
- res.bottom_screen.right = res.bottom_screen.left + bottom_width;
- res.bottom_screen.top = res.top_screen.bottom;
- res.bottom_screen.bottom = res.bottom_screen.top + viewport_height / 2;
- } else {
- // Otherwise, apply borders to the left and right sides of the window.
- int viewport_width = static_cast<int>(std::round(height / emulation_aspect_ratio));
-
- res.top_screen.left = (width - viewport_width) / 2;
- res.top_screen.right = res.top_screen.left + viewport_width;
- res.top_screen.top = 0;
- res.top_screen.bottom = res.top_screen.top + height / 2;
-
- int bottom_width = static_cast<int>(
- (static_cast<float>(VideoCore::kScreenBottomWidth) / VideoCore::kScreenTopWidth) *
- (res.top_screen.right - res.top_screen.left));
- int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2;
-
- res.bottom_screen.left = res.top_screen.left + bottom_border;
- res.bottom_screen.right = res.bottom_screen.left + bottom_width;
- res.bottom_screen.top = res.top_screen.bottom;
- res.bottom_screen.bottom = res.bottom_screen.top + height / 2;
+void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) {
+ Layout::FramebufferLayout layout;
+ switch (Settings::values.layout_option) {
+ case Settings::LayoutOption::SingleScreen:
+ layout = Layout::SingleFrameLayout(width, height, Settings::values.swap_screen);
+ break;
+ case Settings::LayoutOption::LargeScreen:
+ layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen);
+ break;
+ case Settings::LayoutOption::Default:
+ default:
+ layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen);
+ break;
}
-
- return res;
+ NotifyFramebufferLayoutChanged(layout);
}
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index 67df63e06..835c4d500 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -7,6 +7,7 @@
#include <tuple>
#include <utility>
#include "common/common_types.h"
+#include "common/framebuffer_layout.h"
#include "common/math_util.h"
#include "core/hle/service/hid/hid.h"
@@ -38,23 +39,6 @@ public:
std::pair<unsigned, unsigned> min_client_area_size;
};
- /// Describes the layout of the window framebuffer (size and top/bottom screen positions)
- struct FramebufferLayout {
-
- /**
- * Factory method for constructing a default FramebufferLayout
- * @param width Window framebuffer width in pixels
- * @param height Window framebuffer height in pixels
- * @return Newly created FramebufferLayout object with default screen regions initialized
- */
- static FramebufferLayout DefaultScreenLayout(unsigned width, unsigned height);
-
- unsigned width;
- unsigned height;
- MathUtil::Rectangle<unsigned> top_screen;
- MathUtil::Rectangle<unsigned> bottom_screen;
- };
-
/// Swap buffers to display the next frame
virtual void SwapBuffers() = 0;
@@ -211,10 +195,16 @@ public:
* Gets the framebuffer layout (width, height, and screen regions)
* @note This method is thread-safe
*/
- const FramebufferLayout& GetFramebufferLayout() const {
+ const Layout::FramebufferLayout& GetFramebufferLayout() const {
return framebuffer_layout;
}
+ /**
+ * Convenience method to update the current frame layout
+ * Read from the current settings to determine which layout to use.
+ */
+ void UpdateCurrentFramebufferLayout(unsigned width, unsigned height);
+
protected:
EmuWindow() {
// TODO: Find a better place to set this.
@@ -250,7 +240,7 @@ protected:
* Update framebuffer layout with the given parameter.
* @note EmuWindow implementations will usually use this in window resize event handlers.
*/
- void NotifyFramebufferLayoutChanged(const FramebufferLayout& layout) {
+ void NotifyFramebufferLayoutChanged(const Layout::FramebufferLayout& layout) {
framebuffer_layout = layout;
}
@@ -274,7 +264,7 @@ private:
// By default, ignore this request and do nothing.
}
- FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
+ Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout
unsigned client_area_width; ///< Current client width, should be set by window impl.
unsigned client_area_height; ///< Current client height, should be set by window impl.
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 14cbcac6b..407ed047a 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -23,8 +23,8 @@
#define fseeko _fseeki64
#define ftello _ftelli64
#define atoll _atoi64
-#define stat64 _stat64
-#define fstat64 _fstat64
+#define stat _stat64
+#define fstat _fstat64
#define fileno _fileno
#else
#ifdef __APPLE__
@@ -52,11 +52,6 @@
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
#endif
-#ifdef BSD4_4
-#define stat64 stat
-#define fstat64 fstat
-#endif
-
// This namespace has various generic functions related to files and paths.
// The code still needs a ton of cleanup.
// REMEMBER: strdup considered harmful!
@@ -76,7 +71,7 @@ static void StripTailDirSlashes(std::string& fname) {
// Returns true if file filename exists
bool Exists(const std::string& filename) {
- struct stat64 file_info;
+ struct stat file_info;
std::string copy(filename);
StripTailDirSlashes(copy);
@@ -88,7 +83,7 @@ bool Exists(const std::string& filename) {
int result = _wstat64(Common::UTF8ToUTF16W(copy).c_str(), &file_info);
#else
- int result = stat64(copy.c_str(), &file_info);
+ int result = stat(copy.c_str(), &file_info);
#endif
return (result == 0);
@@ -96,7 +91,7 @@ bool Exists(const std::string& filename) {
// Returns true if filename is a directory
bool IsDirectory(const std::string& filename) {
- struct stat64 file_info;
+ struct stat file_info;
std::string copy(filename);
StripTailDirSlashes(copy);
@@ -108,7 +103,7 @@ bool IsDirectory(const std::string& filename) {
int result = _wstat64(Common::UTF8ToUTF16W(copy).c_str(), &file_info);
#else
- int result = stat64(copy.c_str(), &file_info);
+ int result = stat(copy.c_str(), &file_info);
#endif
if (result < 0) {
@@ -339,11 +334,11 @@ u64 GetSize(const std::string& filename) {
return 0;
}
- struct stat64 buf;
+ struct stat buf;
#ifdef _WIN32
if (_wstat64(Common::UTF8ToUTF16W(filename).c_str(), &buf) == 0)
#else
- if (stat64(filename.c_str(), &buf) == 0)
+ if (stat(filename.c_str(), &buf) == 0)
#endif
{
LOG_TRACE(Common_Filesystem, "%s: %lld", filename.c_str(), (long long)buf.st_size);
@@ -356,8 +351,8 @@ u64 GetSize(const std::string& filename) {
// Overloaded GetSize, accepts file descriptor
u64 GetSize(const int fd) {
- struct stat64 buf;
- if (fstat64(fd, &buf) != 0) {
+ struct stat buf;
+ if (fstat(fd, &buf) != 0) {
LOG_ERROR(Common_Filesystem, "GetSize: stat failed %i: %s", fd, GetLastErrorMsg());
return 0;
}
diff --git a/src/common/framebuffer_layout.cpp b/src/common/framebuffer_layout.cpp
new file mode 100644
index 000000000..46c008d9c
--- /dev/null
+++ b/src/common/framebuffer_layout.cpp
@@ -0,0 +1,138 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cmath>
+
+#include "common/assert.h"
+#include "common/framebuffer_layout.h"
+#include "video_core/video_core.h"
+
+namespace Layout {
+
+static const float TOP_SCREEN_ASPECT_RATIO =
+ static_cast<float>(VideoCore::kScreenTopHeight) / VideoCore::kScreenTopWidth;
+static const float BOT_SCREEN_ASPECT_RATIO =
+ static_cast<float>(VideoCore::kScreenBottomHeight) / VideoCore::kScreenBottomWidth;
+
+// Finds the largest size subrectangle contained in window area that is confined to the aspect ratio
+template <class T>
+static MathUtil::Rectangle<T> maxRectangle(MathUtil::Rectangle<T> window_area,
+ float screen_aspect_ratio) {
+ float scale = std::min(static_cast<float>(window_area.GetWidth()),
+ window_area.GetHeight() / screen_aspect_ratio);
+ return MathUtil::Rectangle<T>{0, 0, static_cast<T>(std::round(scale)),
+ static_cast<T>(std::round(scale * screen_aspect_ratio))};
+}
+
+FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool swapped) {
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+
+ FramebufferLayout res{width, height, true, true, {}, {}};
+ // Default layout gives equal screen sizes to the top and bottom screen
+ MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height / 2};
+ MathUtil::Rectangle<unsigned> top_screen =
+ maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
+ MathUtil::Rectangle<unsigned> bot_screen =
+ maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO);
+
+ float window_aspect_ratio = static_cast<float>(height) / width;
+ // both screens height are taken into account by multiplying by 2
+ float emulation_aspect_ratio = TOP_SCREEN_ASPECT_RATIO * 2;
+
+ if (window_aspect_ratio < emulation_aspect_ratio) {
+ // Apply borders to the left and right sides of the window.
+ top_screen =
+ top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2);
+ bot_screen =
+ bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2);
+ } else {
+ // Window is narrower than the emulation content => apply borders to the top and bottom
+ // Recalculate the bottom screen to account for the width difference between top and bottom
+ screen_window_area = {0, 0, width, top_screen.GetHeight()};
+ bot_screen = maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO);
+ bot_screen = bot_screen.TranslateX((top_screen.GetWidth() - bot_screen.GetWidth()) / 2);
+ if (swapped) {
+ bot_screen = bot_screen.TranslateY(height / 2 - bot_screen.GetHeight());
+ } else {
+ top_screen = top_screen.TranslateY(height / 2 - top_screen.GetHeight());
+ }
+ }
+ // Move the top screen to the bottom if we are swapped.
+ res.top_screen = swapped ? top_screen.TranslateY(height / 2) : top_screen;
+ res.bottom_screen = swapped ? bot_screen : bot_screen.TranslateY(height / 2);
+ return res;
+}
+
+FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool swapped) {
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+ // The drawing code needs at least somewhat valid values for both screens
+ // so just calculate them both even if the other isn't showing.
+ FramebufferLayout res{width, height, !swapped, swapped, {}, {}};
+
+ MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
+ MathUtil::Rectangle<unsigned> top_screen =
+ maxRectangle(screen_window_area, TOP_SCREEN_ASPECT_RATIO);
+ MathUtil::Rectangle<unsigned> bot_screen =
+ maxRectangle(screen_window_area, BOT_SCREEN_ASPECT_RATIO);
+
+ float window_aspect_ratio = static_cast<float>(height) / width;
+ float emulation_aspect_ratio = (swapped) ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO;
+
+ if (window_aspect_ratio < emulation_aspect_ratio) {
+ top_screen =
+ top_screen.TranslateX((screen_window_area.GetWidth() - top_screen.GetWidth()) / 2);
+ bot_screen =
+ bot_screen.TranslateX((screen_window_area.GetWidth() - bot_screen.GetWidth()) / 2);
+ } else {
+ top_screen = top_screen.TranslateY((height - top_screen.GetHeight()) / 2);
+ bot_screen = bot_screen.TranslateY((height - bot_screen.GetHeight()) / 2);
+ }
+ res.top_screen = top_screen;
+ res.bottom_screen = bot_screen;
+ return res;
+}
+
+FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped) {
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+
+ FramebufferLayout res{width, height, true, true, {}, {}};
+ // Split the window into two parts. Give 4x width to the main screen and 1x width to the small
+ // To do that, find the total emulation box and maximize that based on window size
+ float window_aspect_ratio = static_cast<float>(height) / width;
+ float emulation_aspect_ratio =
+ swapped
+ ? VideoCore::kScreenBottomHeight * 4 /
+ (VideoCore::kScreenBottomWidth * 4.0f + VideoCore::kScreenTopWidth)
+ : VideoCore::kScreenTopHeight * 4 /
+ (VideoCore::kScreenTopWidth * 4.0f + VideoCore::kScreenBottomWidth);
+ float large_screen_aspect_ratio = swapped ? BOT_SCREEN_ASPECT_RATIO : TOP_SCREEN_ASPECT_RATIO;
+ float small_screen_aspect_ratio = swapped ? TOP_SCREEN_ASPECT_RATIO : BOT_SCREEN_ASPECT_RATIO;
+
+ MathUtil::Rectangle<unsigned> screen_window_area{0, 0, width, height};
+ MathUtil::Rectangle<unsigned> total_rect =
+ maxRectangle(screen_window_area, emulation_aspect_ratio);
+ MathUtil::Rectangle<unsigned> large_screen =
+ maxRectangle(total_rect, large_screen_aspect_ratio);
+ MathUtil::Rectangle<unsigned> fourth_size_rect = total_rect.Scale(.25f);
+ MathUtil::Rectangle<unsigned> small_screen =
+ maxRectangle(fourth_size_rect, small_screen_aspect_ratio);
+
+ if (window_aspect_ratio < emulation_aspect_ratio) {
+ large_screen =
+ large_screen.TranslateX((screen_window_area.GetWidth() - total_rect.GetWidth()) / 2);
+ } else {
+ large_screen = large_screen.TranslateY((height - total_rect.GetHeight()) / 2);
+ }
+ // Shift the small screen to the bottom right corner
+ small_screen =
+ small_screen.TranslateX(large_screen.right)
+ .TranslateY(large_screen.GetHeight() + large_screen.top - small_screen.GetHeight());
+ res.top_screen = swapped ? small_screen : large_screen;
+ res.bottom_screen = swapped ? large_screen : small_screen;
+ return res;
+}
+}
diff --git a/src/common/framebuffer_layout.h b/src/common/framebuffer_layout.h
new file mode 100644
index 000000000..a125646a3
--- /dev/null
+++ b/src/common/framebuffer_layout.h
@@ -0,0 +1,47 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/math_util.h"
+namespace Layout {
+/// Describes the layout of the window framebuffer (size and top/bottom screen positions)
+struct FramebufferLayout {
+ unsigned width;
+ unsigned height;
+ bool top_screen_enabled;
+ bool bottom_screen_enabled;
+ MathUtil::Rectangle<unsigned> top_screen;
+ MathUtil::Rectangle<unsigned> bottom_screen;
+};
+
+/**
+ * Factory method for constructing a default FramebufferLayout
+ * @param width Window framebuffer width in pixels
+ * @param height Window framebuffer height in pixels
+ * @param is_swapped if true, the bottom screen will be displayed above the top screen
+ * @return Newly created FramebufferLayout object with default screen regions initialized
+ */
+FramebufferLayout DefaultFrameLayout(unsigned width, unsigned height, bool is_swapped);
+
+/**
+ * Factory method for constructing a FramebufferLayout with only the top or bottom screen
+ * @param width Window framebuffer width in pixels
+ * @param height Window framebuffer height in pixels
+ * @param is_swapped if true, the bottom screen will be displayed (and the top won't be displayed)
+ * @return Newly created FramebufferLayout object with default screen regions initialized
+ */
+FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swapped);
+
+/**
+ * Factory method for constructing a Frame with the a 4x size Top screen with a 1x size bottom
+ * screen on the right
+ * This is useful in particular because it matches well with a 1920x1080 resolution monitor
+ * @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
+ * @return Newly created FramebufferLayout object with default screen regions initialized
+ */
+FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped);
+}
diff --git a/src/common/hash.cpp b/src/common/hash.cpp
index 5aa5118eb..2309320bb 100644
--- a/src/common/hash.cpp
+++ b/src/common/hash.cpp
@@ -31,7 +31,7 @@ static FORCE_INLINE u64 fmix64(u64 k) {
return k;
}
-// This is the 128-bit variant of the MurmurHash3 hash function that is targetted for 64-bit
+// This is the 128-bit variant of the MurmurHash3 hash function that is targeted for 64-bit
// platforms (MurmurHash3_x64_128). It was taken from:
// https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
void MurmurHash3_128(const void* key, int len, u32 seed, void* out) {
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 9a13a9e90..88209081d 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -37,6 +37,7 @@ namespace Log {
SUB(Service, FS) \
SUB(Service, ERR) \
SUB(Service, APT) \
+ SUB(Service, BOSS) \
SUB(Service, GSP) \
SUB(Service, AC) \
SUB(Service, AM) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index a4b4750de..8d3a2d03e 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -54,6 +54,7 @@ enum class Class : ClassType {
Service_FS, ///< The FS (Filesystem) service implementation
Service_ERR, ///< The ERR (Error) port implementation
Service_APT, ///< The APT (Applets) service
+ Service_BOSS, ///< The BOSS (SpotPass) service
Service_GSP, ///< The GSP (GPU control) service
Service_AC, ///< The AC (WiFi status) service
Service_AM, ///< The AM (Application manager) service
diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h
index 0da102bc6..749268310 100644
--- a/src/common/logging/text_formatter.h
+++ b/src/common/logging/text_formatter.h
@@ -17,7 +17,7 @@ struct Entry;
*
* @param path The input file path as a null-terminated string
* @param root The name of the root source directory as a null-terminated string. Path up to and
- * including the last occurence of this name will be stripped
+ * including the last occurrence of this name will be stripped
* @return A pointer to the same string passed as `path`, but starting at the trimmed portion
*/
const char* TrimSourcePath(const char* path, const char* root = "src");
diff --git a/src/common/math_util.h b/src/common/math_util.h
index 41d89666c..cdeaeb733 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -38,6 +38,16 @@ struct Rectangle {
T GetHeight() const {
return std::abs(static_cast<typename std::make_signed<T>::type>(bottom - top));
}
+ Rectangle<T> TranslateX(const T x) const {
+ return Rectangle{left + x, top, right + x, bottom};
+ }
+ Rectangle<T> TranslateY(const T y) const {
+ return Rectangle{left, top + y, right, bottom + y};
+ }
+ Rectangle<T> Scale(const float s) const {
+ return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
+ static_cast<T>(top + GetHeight() * s)};
+ }
};
} // namespace MathUtil
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 596ae01bf..df1008180 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -11,7 +11,8 @@
#include "common/common_paths.h"
#include "common/logging/log.h"
#include "common/string_util.h"
-#ifdef _MSC_VER
+
+#ifdef _WIN32
#include <codecvt>
#include <Windows.h>
#include "common/common_funcs.h"
@@ -270,7 +271,7 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
return result;
}
-#ifdef _MSC_VER
+#ifdef _WIN32
std::string UTF16ToUTF8(const std::u16string& input) {
#if _MSC_VER >= 1900
diff --git a/src/common/swap.h b/src/common/swap.h
index e241c9f73..d94cbe6b2 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -21,7 +21,8 @@
#include <cstdlib>
#elif defined(__linux__)
#include <byteswap.h>
-#elif defined(__FreeBSD__)
+#elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
+ defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/endian.h>
#endif
#include <cstring>
@@ -101,7 +102,9 @@ inline __attribute__((always_inline)) u32 swap32(u32 _data) {
inline __attribute__((always_inline)) u64 swap64(u64 _data) {
return __builtin_bswap64(_data);
}
-#elif __FreeBSD__
+#elif defined(__Bitrig__) || defined(__OpenBSD__)
+// swap16, swap32, swap64 are left as is
+#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
inline u16 swap16(u16 _data) {
return bswap16(_data);
}
diff --git a/src/common/thread.cpp b/src/common/thread.cpp
index 6e7b39b9a..9bb2f4e1d 100644
--- a/src/common/thread.cpp
+++ b/src/common/thread.cpp
@@ -8,7 +8,7 @@
#elif defined(_WIN32)
#include <Windows.h>
#else
-#if defined(BSD4_4) || defined(__OpenBSD__)
+#if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <pthread_np.h>
#else
#include <pthread.h>
@@ -19,6 +19,10 @@
#include <unistd.h>
#endif
+#ifdef __FreeBSD__
+#define cpu_set_t cpuset_t
+#endif
+
namespace Common {
int CurrentThreadId() {
@@ -86,7 +90,7 @@ void SetCurrentThreadName(const char* szThreadName) {
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) {
#ifdef __APPLE__
thread_policy_set(pthread_mach_thread_np(thread), THREAD_AFFINITY_POLICY, (integer_t*)&mask, 1);
-#elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID)
+#elif (defined __linux__ || defined __FreeBSD__) && !(defined ANDROID)
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
@@ -117,8 +121,10 @@ void SwitchCurrentThread() {
void SetCurrentThreadName(const char* szThreadName) {
#ifdef __APPLE__
pthread_setname_np(szThreadName);
-#elif defined(__OpenBSD__)
+#elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
pthread_set_name_np(pthread_self(), szThreadName);
+#elif defined(__NetBSD__)
+ pthread_setname_np(pthread_self(), "%s", (void*)szThreadName);
#else
pthread_setname_np(pthread_self(), szThreadName);
#endif
diff --git a/src/common/vector_math.h b/src/common/vector_math.h
index 2d56f168c..a57d86d88 100644
--- a/src/common/vector_math.h
+++ b/src/common/vector_math.h
@@ -60,7 +60,6 @@ public:
}
Vec2() = default;
- Vec2(const T a[2]) : x(a[0]), y(a[1]) {}
Vec2(const T& _x, const T& _y) : x(_x), y(_y) {}
template <typename T2>
@@ -199,7 +198,6 @@ public:
}
Vec3() = default;
- Vec3(const T a[3]) : x(a[0]), y(a[1]), z(a[2]) {}
Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {}
template <typename T2>
@@ -405,7 +403,6 @@ public:
}
Vec4() = default;
- Vec4(const T a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3]) {}
Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {}
template <typename T2>
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 6ddf9b70c..370ae2c80 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -12,13 +12,15 @@ namespace Common {
#ifndef _MSC_VER
-#ifdef __FreeBSD__
-#include <machine/cpufunc.h>
+#if defined(__DragonFly__) || defined(__FreeBSD__)
+// clang-format off
#include <sys/types.h>
+#include <machine/cpufunc.h>
+// clang-format on
#endif
static inline void __cpuidex(int info[4], int function_id, int subfunction_id) {
-#ifdef __FreeBSD__
+#if defined(__DragonFly__) || defined(__FreeBSD__)
// Despite the name, this is just do_cpuid() with ECX as second input.
cpuid_count((u_int)function_id, (u_int)subfunction_id, (u_int*)info);
#else
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 7fc72d801..aea43e92b 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -14,7 +14,7 @@
#include <numeric>
#include <fcntl.h>
-#ifdef _MSC_VER
+#ifdef _WIN32
#include <WinSock2.h>
#include <common/x64/abi.h>
#include <io.h>
@@ -413,7 +413,7 @@ static void HandleQuery() {
if (strcmp(query, "TStatus") == 0) {
SendReply("T0");
- } else if (strncmp(query, "Supported:", strlen("Supported:")) == 0) {
+ } else if (strncmp(query, "Supported", strlen("Supported")) == 0) {
// PacketSize needs to be large enough for target xml
SendReply("PacketSize=800;qXfer:features:read+");
} else if (strncmp(query, "Xfer:features:read:target.xml:",
diff --git a/src/core/hle/applets/erreula.cpp b/src/core/hle/applets/erreula.cpp
index 14964427b..e1379ac4d 100644
--- a/src/core/hle/applets/erreula.cpp
+++ b/src/core/hle/applets/erreula.cpp
@@ -10,7 +10,7 @@ namespace HLE {
namespace Applets {
ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& parameter) {
- if (parameter.signal != static_cast<u32>(Service::APT::SignalType::LibAppJustStarted)) {
+ if (parameter.signal != static_cast<u32>(Service::APT::SignalType::Request)) {
LOG_ERROR(Service_APT, "unsupported signal %u", parameter.signal);
UNIMPLEMENTED();
// TODO(Subv): Find the right error code
@@ -36,7 +36,7 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param
// Send the response message with the newly created SharedMemory
Service::APT::MessageParameter result;
- result.signal = static_cast<u32>(Service::APT::SignalType::LibAppFinished);
+ result.signal = static_cast<u32>(Service::APT::SignalType::Response);
result.buffer.clear();
result.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
result.sender_id = static_cast<u32>(id);
@@ -57,7 +57,7 @@ ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parame
Service::APT::MessageParameter message;
message.buffer.resize(parameter.buffer.size());
std::fill(message.buffer.begin(), message.buffer.end(), 0);
- message.signal = static_cast<u32>(Service::APT::SignalType::LibAppClosed);
+ message.signal = static_cast<u32>(Service::APT::SignalType::WakeupByExit);
message.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
message.sender_id = static_cast<u32>(id);
Service::APT::SendParameter(message);
diff --git a/src/core/hle/applets/mii_selector.cpp b/src/core/hle/applets/mii_selector.cpp
index 53a8683a4..3455b9201 100644
--- a/src/core/hle/applets/mii_selector.cpp
+++ b/src/core/hle/applets/mii_selector.cpp
@@ -19,7 +19,7 @@ namespace HLE {
namespace Applets {
ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& parameter) {
- if (parameter.signal != static_cast<u32>(Service::APT::SignalType::LibAppJustStarted)) {
+ if (parameter.signal != static_cast<u32>(Service::APT::SignalType::Request)) {
LOG_ERROR(Service_APT, "unsupported signal %u", parameter.signal);
UNIMPLEMENTED();
// TODO(Subv): Find the right error code
@@ -44,7 +44,7 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p
// Send the response message with the newly created SharedMemory
Service::APT::MessageParameter result;
- result.signal = static_cast<u32>(Service::APT::SignalType::LibAppFinished);
+ result.signal = static_cast<u32>(Service::APT::SignalType::Response);
result.buffer.clear();
result.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
result.sender_id = static_cast<u32>(id);
@@ -73,7 +73,7 @@ ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& pa
Service::APT::MessageParameter message;
message.buffer.resize(sizeof(MiiResult));
std::memcpy(message.buffer.data(), &result, message.buffer.size());
- message.signal = static_cast<u32>(Service::APT::SignalType::LibAppClosed);
+ message.signal = static_cast<u32>(Service::APT::SignalType::WakeupByExit);
message.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
message.sender_id = static_cast<u32>(id);
Service::APT::SendParameter(message);
diff --git a/src/core/hle/applets/swkbd.cpp b/src/core/hle/applets/swkbd.cpp
index 06ddf538b..1e21337f5 100644
--- a/src/core/hle/applets/swkbd.cpp
+++ b/src/core/hle/applets/swkbd.cpp
@@ -22,7 +22,7 @@ namespace HLE {
namespace Applets {
ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter const& parameter) {
- if (parameter.signal != static_cast<u32>(Service::APT::SignalType::LibAppJustStarted)) {
+ if (parameter.signal != static_cast<u32>(Service::APT::SignalType::Request)) {
LOG_ERROR(Service_APT, "unsupported signal %u", parameter.signal);
UNIMPLEMENTED();
// TODO(Subv): Find the right error code
@@ -47,7 +47,7 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con
// Send the response message with the newly created SharedMemory
Service::APT::MessageParameter result;
- result.signal = static_cast<u32>(Service::APT::SignalType::LibAppFinished);
+ result.signal = static_cast<u32>(Service::APT::SignalType::Response);
result.buffer.clear();
result.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
result.sender_id = static_cast<u32>(id);
@@ -108,7 +108,7 @@ void SoftwareKeyboard::Finalize() {
Service::APT::MessageParameter message;
message.buffer.resize(sizeof(SoftwareKeyboardConfig));
std::memcpy(message.buffer.data(), &config, message.buffer.size());
- message.signal = static_cast<u32>(Service::APT::SignalType::LibAppClosed);
+ message.signal = static_cast<u32>(Service::APT::SignalType::WakeupByExit);
message.destination_id = static_cast<u32>(Service::APT::AppletId::Application);
message.sender_id = static_cast<u32>(id);
Service::APT::SendParameter(message);
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 1489c7002..3e116e3df 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -22,6 +22,11 @@ SharedPtr<Event> Event::Create(ResetType reset_type, std::string name) {
evt->reset_type = reset_type;
evt->name = std::move(name);
+ if (reset_type == ResetType::Pulse) {
+ LOG_ERROR(Kernel, "Unimplemented event reset type Pulse");
+ UNIMPLEMENTED();
+ }
+
return evt;
}
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
index e65fd5c41..33c165197 100644
--- a/src/core/hle/kernel/memory.cpp
+++ b/src/core/hle/kernel/memory.cpp
@@ -23,7 +23,7 @@ namespace Kernel {
static MemoryRegionInfo memory_regions[3];
-/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each sytem
+/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
/// memory configuration type.
static const u32 memory_region_sizes[8][3] = {
// Old 3DS layouts
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index c4eeeee56..84d6d24c6 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -204,7 +204,7 @@ static std::tuple<u32*, u32*> GetWaitSynchTimeoutParameterRegister(Thread* threa
}
/**
- * Updates the WaitSynchronization timeout paramter according to the difference
+ * Updates the WaitSynchronization timeout parameter according to the difference
* between ticks of the last WaitSynchronization call and the incoming one.
* @param timeout_low a pointer to the register for the low part of the timeout parameter
* @param timeout_high a pointer to the register for the high part of the timeout parameter
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index a9f98223c..eac181f4e 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -31,6 +31,11 @@ SharedPtr<Timer> Timer::Create(ResetType reset_type, std::string name) {
timer->interval_delay = 0;
timer->callback_handle = timer_callback_handle_table.Create(timer).MoveFrom();
+ if (reset_type == ResetType::Pulse) {
+ LOG_ERROR(Kernel, "Unimplemented timer reset type Pulse");
+ UNIMPLEMENTED();
+ }
+
return timer;
}
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index 12d94f37a..18026975f 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -11,11 +11,85 @@
namespace AC_U {
+struct ACConfig {
+ std::array<u8, 0x200> data;
+};
+
+static ACConfig default_config{};
+
+static bool ac_connected = false;
+
+static Kernel::SharedPtr<Kernel::Event> close_event;
+static Kernel::SharedPtr<Kernel::Event> connect_event;
+static Kernel::SharedPtr<Kernel::Event> disconnect_event;
+
+/**
+ * AC_U::CreateDefaultConfig service function
+ * Inputs:
+ * 64 : ACConfig size << 14 | 2
+ * 65 : pointer to ACConfig struct
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void CreateDefaultConfig(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 ac_config_addr = cmd_buff[65];
+
+ ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2),
+ "Output buffer size not equal ACConfig size");
+
+ Memory::WriteBlock(ac_config_addr, &default_config, sizeof(ACConfig));
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+
+/**
+ * AC_U::ConnectAsync service function
+ * Inputs:
+ * 1 : ProcessId Header
+ * 3 : Copy Handle Header
+ * 4 : Connection Event handle
+ * 5 : ACConfig size << 14 | 2
+ * 6 : pointer to ACConfig struct
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void ConnectAsync(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ connect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
+ if (connect_event) {
+ connect_event->name = "AC_U:connect_event";
+ connect_event->Signal();
+ ac_connected = true;
+ }
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+
+/**
+ * AC_U::GetConnectResult service function
+ * Inputs:
+ * 1 : ProcessId Header
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void GetConnectResult(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+
/**
* AC_U::CloseAsync service function
* Inputs:
- * 1 : Always 0x20
- * 3 : Always 0
+ * 1 : ProcessId Header
+ * 3 : Copy Handle Header
* 4 : Event handle, should be signaled when AC connection is closed
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
@@ -23,16 +97,37 @@ namespace AC_U {
static void CloseAsync(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
+ if (ac_connected && disconnect_event) {
+ disconnect_event->Signal();
+ }
- if (evt) {
- evt->name = "AC_U:close_event";
- evt->Signal();
+ close_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
+ if (close_event) {
+ close_event->name = "AC_U:close_event";
+ close_event->Signal();
}
+
+ ac_connected = false;
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+
+/**
+ * AC_U::GetCloseResult service function
+ * Inputs:
+ * 1 : ProcessId Header
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void GetCloseResult(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
LOG_WARNING(Service_AC, "(STUBBED) called");
}
+
/**
* AC_U::GetWifiStatus service function
* Outputs:
@@ -52,6 +147,75 @@ static void GetWifiStatus(Service::Interface* self) {
}
/**
+ * AC_U::GetInfraPriority service function
+ * Inputs:
+ * 1 : ACConfig size << 14 | 2
+ * 2 : pointer to ACConfig struct
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Infra Priority
+ */
+static void GetInfraPriority(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = 0; // Infra Priority, default 0
+
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+
+/**
+ * AC_U::SetRequestEulaVersion service function
+ * Inputs:
+ * 1 : Eula Version major
+ * 2 : Eula Version minor
+ * 3 : ACConfig size << 14 | 2
+ * 4 : Input pointer to ACConfig struct
+ * 64 : ACConfig size << 14 | 2
+ * 65 : Output pointer to ACConfig struct
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : Infra Priority
+ */
+static void SetRequestEulaVersion(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 major = cmd_buff[1] & 0xFF;
+ u32 minor = cmd_buff[2] & 0xFF;
+
+ ASSERT_MSG(cmd_buff[3] == (sizeof(ACConfig) << 14 | 2),
+ "Input buffer size not equal ACConfig size");
+ ASSERT_MSG(cmd_buff[64] == (sizeof(ACConfig) << 14 | 2),
+ "Output buffer size not equal ACConfig size");
+
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = 0; // Infra Priority
+
+ LOG_WARNING(Service_AC, "(STUBBED) called, major=%u, minor=%u", major, minor);
+}
+
+/**
+ * AC_U::RegisterDisconnectEvent service function
+ * Inputs:
+ * 1 : ProcessId Header
+ * 3 : Copy Handle Header
+ * 4 : Event handle, should be signaled when AC connection is closed
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+static void RegisterDisconnectEvent(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ disconnect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
+ if (disconnect_event) {
+ disconnect_event->name = "AC_U:disconnect_event";
+ }
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+
+ LOG_WARNING(Service_AC, "(STUBBED) called");
+}
+
+/**
* AC_U::IsConnected service function
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
@@ -61,26 +225,29 @@ static void IsConnected(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- cmd_buff[2] = false; // Not connected to ac:u service
+ cmd_buff[2] = ac_connected;
LOG_WARNING(Service_AC, "(STUBBED) called");
}
const Interface::FunctionInfo FunctionTable[] = {
- {0x00010000, nullptr, "CreateDefaultConfig"},
- {0x00040006, nullptr, "ConnectAsync"},
- {0x00050002, nullptr, "GetConnectResult"},
+ {0x00010000, CreateDefaultConfig, "CreateDefaultConfig"},
+ {0x00040006, ConnectAsync, "ConnectAsync"},
+ {0x00050002, GetConnectResult, "GetConnectResult"},
+ {0x00070002, nullptr, "CancelConnectAsync"},
{0x00080004, CloseAsync, "CloseAsync"},
- {0x00090002, nullptr, "GetCloseResult"},
+ {0x00090002, GetCloseResult, "GetCloseResult"},
{0x000A0000, nullptr, "GetLastErrorCode"},
+ {0x000C0000, nullptr, "GetStatus"},
{0x000D0000, GetWifiStatus, "GetWifiStatus"},
{0x000E0042, nullptr, "GetCurrentAPInfo"},
{0x00100042, nullptr, "GetCurrentNZoneInfo"},
{0x00110042, nullptr, "GetNZoneApNumService"},
+ {0x001D0042, nullptr, "ScanAPs"},
{0x00240042, nullptr, "AddDenyApType"},
- {0x00270002, nullptr, "GetInfraPriority"},
- {0x002D0082, nullptr, "SetRequestEulaVersion"},
- {0x00300004, nullptr, "RegisterDisconnectEvent"},
+ {0x00270002, GetInfraPriority, "GetInfraPriority"},
+ {0x002D0082, SetRequestEulaVersion, "SetRequestEulaVersion"},
+ {0x00300004, RegisterDisconnectEvent, "RegisterDisconnectEvent"},
{0x003C0042, nullptr, "GetAPSSIDList"},
{0x003E0042, IsConnected, "IsConnected"},
{0x00400042, nullptr, "SetClientVersion"},
@@ -91,6 +258,18 @@ const Interface::FunctionInfo FunctionTable[] = {
Interface::Interface() {
Register(FunctionTable);
+
+ ac_connected = false;
+
+ close_event = nullptr;
+ connect_event = nullptr;
+ disconnect_event = nullptr;
+}
+
+Interface::~Interface() {
+ close_event = nullptr;
+ connect_event = nullptr;
+ disconnect_event = nullptr;
}
} // namespace
diff --git a/src/core/hle/service/ac_u.h b/src/core/hle/service/ac_u.h
index f1d26ebe8..6592b21c9 100644
--- a/src/core/hle/service/ac_u.h
+++ b/src/core/hle/service/ac_u.h
@@ -16,6 +16,7 @@ namespace AC_U {
class Interface : public Service::Interface {
public:
Interface();
+ ~Interface();
std::string GetPortName() const override {
return "ac:u";
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index c4bd65986..c7198293e 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -523,7 +523,7 @@ void Init() {
notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification");
parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Start");
- next_parameter.signal = static_cast<u32>(SignalType::AppJustStarted);
+ next_parameter.signal = static_cast<u32>(SignalType::Wakeup);
next_parameter.destination_id = 0x300;
}
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index a118cda1f..cbcba96a5 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -46,12 +46,23 @@ static_assert(sizeof(CaptureBufferInfo) == 0x20, "CaptureBufferInfo struct has i
/// Signals used by APT functions
enum class SignalType : u32 {
None = 0x0,
- AppJustStarted = 0x1,
- LibAppJustStarted = 0x2,
- LibAppFinished = 0x3,
- LibAppClosed = 0xA,
- ReturningToApp = 0xB,
- ExitingApp = 0xC,
+ Wakeup = 0x1,
+ Request = 0x2,
+ Response = 0x3,
+ Exit = 0x4,
+ Message = 0x5,
+ HomeButtonSingle = 0x6,
+ HomeButtonDouble = 0x7,
+ DspSleep = 0x8,
+ DspWakeup = 0x9,
+ WakeupByExit = 0xA,
+ WakeupByPause = 0xB,
+ WakeupByCancel = 0xC,
+ WakeupByCancelAll = 0xD,
+ WakeupByPowerButtonClick = 0xE,
+ WakeupToJumpHome = 0xF,
+ RequestForSysApplet = 0x10,
+ WakeupToLaunchApplication = 0x11,
};
/// App Id's used by APT functions
diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp
index 757a8c2c7..6ab16ccd5 100644
--- a/src/core/hle/service/boss/boss.cpp
+++ b/src/core/hle/service/boss/boss.cpp
@@ -10,11 +10,978 @@
namespace Service {
namespace BOSS {
+static u32 new_arrival_flag;
+static u32 ns_data_new_flag;
+static u32 output_flag;
+
+void InitializeSession(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u64 unk_param = ((u64)cmd_buff[1] | ((u64)cmd_buff[2] << 32));
+ u32 translation = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+
+ if (translation != IPC::CallingPidDesc()) {
+ cmd_buff[0] = IPC::MakeHeader(0, 0x1, 0); // 0x40
+ cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
+ ErrorSummary::WrongArgument, ErrorLevel::Permanent)
+ .raw;
+ LOG_ERROR(Service_BOSS, "The translation was invalid, translation=0x%08X", translation);
+ return;
+ }
+
+ cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param=0x%016X, translation=0x%08X, unk_param4=0x%08X",
+ unk_param, translation, unk_param4);
+}
+
+void RegisterStorage(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_flag = cmd_buff[4] & 0xFF;
+
+ cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(
+ Service_BOSS,
+ "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, unk_flag=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_flag);
+}
+
+void UnregisterStorage(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x3, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) called");
+}
+
+void GetStorageInfo(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x4, 0x2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) called");
+}
+
+void RegisterPrivateRootCa(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x5, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ translation, buff_addr, buff_size);
+}
+
+void RegisterPrivateClientCert(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 translation1 = cmd_buff[3];
+ u32 buff1_addr = cmd_buff[4];
+ u32 buff1_size = (translation1 >> 4);
+ u32 translation2 = cmd_buff[5];
+ u32 buff2_addr = cmd_buff[6];
+ u32 buff2_size = (translation2 >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x6, 0x1, 0x4);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff1_size << 4 | 0xA);
+ cmd_buff[3] = buff1_addr;
+ cmd_buff[2] = (buff2_size << 4 | 0xA);
+ cmd_buff[3] = buff2_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, "
+ "translation1=0x%08X, buff1_addr=0x%08X, buff1_size=0x%08X, "
+ "translation2=0x%08X, buff2_addr=0x%08X, buff2_size=0x%08X",
+ unk_param1, unk_param2, translation1, buff1_addr, buff1_size, translation2,
+ buff2_addr, buff2_size);
+}
+
+void GetNewArrivalFlag(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x7, 0x2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = new_arrival_flag;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) new_arrival_flag=%u", new_arrival_flag);
+}
+
+void RegisterNewArrivalEvent(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+
+ cmd_buff[0] = IPC::MakeHeader(0x8, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X", unk_param1,
+ unk_param2);
+}
+
+void SetOptoutFlag(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ output_flag = cmd_buff[1] & 0xFF;
+
+ cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "output_flag=%u", output_flag);
+}
+
+void GetOptoutFlag(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0xA, 0x2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = output_flag;
+
+ LOG_WARNING(Service_BOSS, "output_flag=%u", output_flag);
+}
+
+void RegisterTask(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 unk_param3 = cmd_buff[3] & 0xFF;
+ u32 translation = cmd_buff[4];
+ u32 buff_addr = cmd_buff[5];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0xB, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, translation, buff_addr, buff_size);
+}
+
+void UnregisterTask(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0xC, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, translation, buff_addr, buff_size);
+}
+
+void ReconfigureTask(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0xD, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, translation, buff_addr, buff_size);
+}
+
+void GetTaskIdList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0xE, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) called");
+}
+
+void GetStepIdList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0xF, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ translation, buff_addr, buff_size);
+}
+
+void GetNsDataIdList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+ u32 translation = cmd_buff[5];
+ u32 buff_addr = cmd_buff[6];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x10, 0x3, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (16 bit value)
+ cmd_buff[3] = 0; // stub 0 (16 bit value)
+ cmd_buff[4] = (buff_size << 4 | 0xC);
+ cmd_buff[5] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "unk_param4=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4, translation, buff_addr, buff_size);
+}
+
+void GetOwnNsDataIdList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+ u32 translation = cmd_buff[5];
+ u32 buff_addr = cmd_buff[6];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x11, 0x3, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (16 bit value)
+ cmd_buff[3] = 0; // stub 0 (16 bit value)
+ cmd_buff[4] = (buff_size << 4 | 0xC);
+ cmd_buff[5] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "unk_param4=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4, translation, buff_addr, buff_size);
+}
+
+void GetNewDataNsDataIdList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+ u32 translation = cmd_buff[5];
+ u32 buff_addr = cmd_buff[6];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x12, 0x3, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (16 bit value)
+ cmd_buff[3] = 0; // stub 0 (16 bit value)
+ cmd_buff[4] = (buff_size << 4 | 0xC);
+ cmd_buff[5] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "unk_param4=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4, translation, buff_addr, buff_size);
+}
+
+void GetOwnNewDataNsDataIdList(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+ u32 translation = cmd_buff[5];
+ u32 buff_addr = cmd_buff[6];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x13, 0x3, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (16 bit value)
+ cmd_buff[3] = 0; // stub 0 (16 bit value)
+ cmd_buff[4] = (buff_size << 4 | 0xC);
+ cmd_buff[5] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "unk_param4=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4, translation, buff_addr, buff_size);
+}
+
+void SendProperty(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x14, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, translation, buff_addr, buff_size);
+}
+
+void SendPropertyHandle(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x15, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void ReceiveProperty(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 buff_size = cmd_buff[2];
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+
+ cmd_buff[0] = IPC::MakeHeader(0x16, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32 bit value)
+ cmd_buff[2] = (buff_size << 4 | 0xC);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, buff_size=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X",
+ unk_param1, buff_size, translation, buff_addr);
+}
+
+void UpdateTaskInterval(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x17, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, translation, buff_addr, buff_size);
+}
+
+void UpdateTaskCount(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 buff_size = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+
+ cmd_buff[0] = IPC::MakeHeader(0x18, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) buff_size=0x%08X, unk_param2=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X",
+ buff_size, unk_param2, translation, buff_addr);
+}
+
+void GetTaskInterval(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x19, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 ( 32bit value)
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void GetTaskCount(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x1A, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 ( 32bit value)
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void GetTaskServiceStatus(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x1B, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 ( 8bit value)
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void StartTask(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x1C, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void StartTaskImmediate(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x1D, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void CancelTask(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x1E, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void GetTaskFinishHandle(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x1F, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0;
+ cmd_buff[3] = 0; // stub 0(This should be a handle of task_finish ?)
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) called");
+}
+
+void GetTaskState(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 buff_size = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[3];
+ u32 buff_addr = cmd_buff[4];
+
+ cmd_buff[0] = IPC::MakeHeader(0x20, 0x4, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (8 bit value)
+ cmd_buff[3] = 0; // stub 0 (32 bit value)
+ cmd_buff[4] = 0; // stub 0 (8 bit value)
+ cmd_buff[5] = (buff_size << 4 | 0xA);
+ cmd_buff[6] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) buff_size=0x%08X, unk_param2=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X",
+ buff_size, unk_param2, translation, buff_addr);
+}
+
+void GetTaskResult(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x21, 0x4, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (8 bit value)
+ cmd_buff[3] = 0; // stub 0 (32 bit value)
+ cmd_buff[4] = 0; // stub 0 (8 bit value)
+ cmd_buff[5] = (buff_size << 4 | 0xA);
+ cmd_buff[6] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void GetTaskCommErrorCode(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x22, 0x4, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32 bit value)
+ cmd_buff[3] = 0; // stub 0 (32 bit value)
+ cmd_buff[4] = 0; // stub 0 (8 bit value)
+ cmd_buff[5] = (buff_size << 4 | 0xA);
+ cmd_buff[6] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void GetTaskStatus(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 unk_param3 = cmd_buff[3] & 0xFF;
+ u32 translation = cmd_buff[4];
+ u32 buff_addr = cmd_buff[5];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x23, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (8 bit value)
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, translation, buff_addr, buff_size);
+}
+
+void GetTaskError(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[4];
+ u32 buff_addr = cmd_buff[5];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x24, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (8 bit value)
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, translation, buff_addr, buff_size);
+}
+
+void GetTaskInfo(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 translation = cmd_buff[4];
+ u32 buff_addr = cmd_buff[5];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x25, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, translation, buff_addr, buff_size);
+}
+
+void DeleteNsData(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x26, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X", unk_param1);
+}
+
+void GetNsDataHeaderInfo(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 unk_param3 = cmd_buff[3];
+ u32 translation = cmd_buff[4];
+ u32 buff_addr = cmd_buff[5];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x27, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xC);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, translation, buff_addr, buff_size);
+}
+
+void ReadNsData(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+ u32 translation = cmd_buff[5];
+ u32 buff_addr = cmd_buff[6];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x28, 0x3, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32bit value)
+ cmd_buff[3] = 0; // stub 0 (32bit value)
+ cmd_buff[4] = (buff_size << 4 | 0xC);
+ cmd_buff[5] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "unk_param4=0x%08X, translation=0x%08X, "
+ "buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4, translation, buff_addr, buff_size);
+}
+
+void SetNsDataAdditionalInfo(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+
+ cmd_buff[0] = IPC::MakeHeader(0x29, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X", unk_param1,
+ unk_param2);
+}
+
+void GetNsDataAdditionalInfo(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x2A, 0x2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32bit value)
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X", unk_param1);
+}
+
+void SetNsDataNewFlag(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ ns_data_new_flag = cmd_buff[2] & 0xFF;
+
+ cmd_buff[0] = IPC::MakeHeader(0x2B, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, ns_data_new_flag=0x%08X", unk_param1,
+ ns_data_new_flag);
+}
+
+void GetNsDataNewFlag(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x2C, 0x2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = ns_data_new_flag;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, ns_data_new_flag=0x%08X", unk_param1,
+ ns_data_new_flag);
+}
+
+void GetNsDataLastUpdate(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x2D, 0x3, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32bit value)
+ cmd_buff[3] = 0; // stub 0 (32bit value)
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X", unk_param1);
+}
+
+void GetErrorCode(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x2E, 0x2, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32bit value)
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X", unk_param1);
+}
+
+void RegisterStorageEntry(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+ u32 unk_param5 = cmd_buff[5] & 0xFF;
+
+ cmd_buff[0] = IPC::MakeHeader(0x2F, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "unk_param4=0x%08X, unk_param5=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4, unk_param5);
+}
+
+void GetStorageEntryInfo(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x30, 0x3, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32bit value)
+ cmd_buff[3] = 0; // stub 0 (16bit value)
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) called");
+}
+
+void SetStorageOption(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1] & 0xFF;
+ u32 unk_param2 = cmd_buff[2];
+ u32 unk_param3 = cmd_buff[3];
+ u32 unk_param4 = cmd_buff[4];
+
+ cmd_buff[0] = IPC::MakeHeader(0x31, 0x1, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, "
+ "unk_param3=0x%08X, unk_param4=0x%08X",
+ unk_param1, unk_param2, unk_param3, unk_param4);
+}
+
+void GetStorageOption(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ cmd_buff[0] = IPC::MakeHeader(0x32, 0x5, 0);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (32bit value)
+ cmd_buff[3] = 0; // stub 0 (8bit value)
+ cmd_buff[4] = 0; // stub 0 (16bit value)
+ cmd_buff[5] = 0; // stub 0 (16bit value)
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) called");
+}
+
+void StartBgImmediate(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x33, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff_size << 4 | 0xA);
+ cmd_buff[3] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) buff_size=0x%08X, unk_param2=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void GetTaskActivePriority(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 unk_param1 = cmd_buff[1]; // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 translation = cmd_buff[2];
+ u32 buff_addr = cmd_buff[3];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x34, 0x2, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = 0; // stub 0 (8bit value)
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) buff_size=0x%08X, unk_param2=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X",
+ unk_param1, translation, buff_addr, buff_size);
+}
+
+void RegisterImmediateTask(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2] & 0xFF;
+ u32 unk_param3 = cmd_buff[3] & 0xFF;
+ u32 translation = cmd_buff[4];
+ u32 buff_addr = cmd_buff[5];
+ u32 buff_size = (translation >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x35, 0x1, 0x2);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[3] = (buff_size << 4 | 0xA);
+ cmd_buff[4] = buff_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, unk_param3=0x%08X, "
+ "translation=0x%08X, buff_addr=0x%08X, buff_size=0x%08X",
+ unk_param1, unk_param2, unk_param3, translation, buff_addr, buff_size);
+}
+
+void SetTaskQuery(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 translation1 = cmd_buff[3];
+ u32 buff1_addr = cmd_buff[4];
+ u32 buff1_size = (translation1 >> 4);
+ u32 translation2 = cmd_buff[5];
+ u32 buff2_addr = cmd_buff[6];
+ u32 buff2_size = (translation2 >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x36, 0x1, 0x4);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff1_size << 4 | 0xA);
+ cmd_buff[3] = buff1_addr;
+ cmd_buff[2] = (buff2_size << 4 | 0xA);
+ cmd_buff[3] = buff2_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, "
+ "translation1=0x%08X, buff1_addr=0x%08X, buff1_size=0x%08X, "
+ "translation2=0x%08X, buff2_addr=0x%08X, buff2_size=0x%08X",
+ unk_param1, unk_param2, translation1, buff1_addr, buff1_size, translation2,
+ buff2_addr, buff2_size);
+}
+
+void GetTaskQuery(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+ // TODO(JamePeng): Figure out the meaning of these parameters
+ u32 unk_param1 = cmd_buff[1];
+ u32 unk_param2 = cmd_buff[2];
+ u32 translation1 = cmd_buff[3];
+ u32 buff1_addr = cmd_buff[4];
+ u32 buff1_size = (translation1 >> 4);
+ u32 translation2 = cmd_buff[5];
+ u32 buff2_addr = cmd_buff[6];
+ u32 buff2_size = (translation2 >> 4);
+
+ cmd_buff[0] = IPC::MakeHeader(0x37, 0x1, 0x4);
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ cmd_buff[2] = (buff1_size << 4 | 0xA);
+ cmd_buff[3] = buff1_addr;
+ cmd_buff[2] = (buff2_size << 4 | 0xC);
+ cmd_buff[3] = buff2_addr;
+
+ LOG_WARNING(Service_BOSS, "(STUBBED) unk_param1=0x%08X, unk_param2=0x%08X, "
+ "translation1=0x%08X, buff1_addr=0x%08X, buff1_size=0x%08X, "
+ "translation2=0x%08X, buff2_addr=0x%08X, buff2_size=0x%08X",
+ unk_param1, unk_param2, translation1, buff1_addr, buff1_size, translation2,
+ buff2_addr, buff2_size);
+}
+
void Init() {
using namespace Kernel;
AddService(new BOSS_P_Interface);
AddService(new BOSS_U_Interface);
+
+ new_arrival_flag = 0;
+ ns_data_new_flag = 0;
+ output_flag = 0;
}
void Shutdown() {}
diff --git a/src/core/hle/service/boss/boss.h b/src/core/hle/service/boss/boss.h
index d3b5d7101..8cdc663c8 100644
--- a/src/core/hle/service/boss/boss.h
+++ b/src/core/hle/service/boss/boss.h
@@ -4,9 +4,794 @@
#pragma once
+#include "core/hle/service/service.h"
+
namespace Service {
namespace BOSS {
+/**
+ * BOSS::InitializeSession service function
+ * Inputs:
+ * 0 : Header Code[0x00010082]
+ * 1 : u32 lower 64bit value
+ * 2 : u32 higher 64bit value
+ * 3 : 0x20
+ * 4 : u32 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void InitializeSession(Service::Interface* self);
+
+/**
+ * BOSS::RegisterStorage service function
+ * Inputs:
+ * 0 : Header Code[0x00020010]
+ * 1 : u32 unknown1
+ * 2 : u32 unknown2
+ * 3 : u32 unknown3
+ * 4 : u8 unknown_flag
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void RegisterStorage(Service::Interface* self);
+
+/**
+ * BOSS::UnregisterStorage service function
+ * Inputs:
+ * 0 : Header Code[0x00030000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void UnregisterStorage(Service::Interface* self);
+
+/**
+ * BOSS::GetStorageInfo service function
+ * Inputs:
+ * 0 : Header Code[0x00040000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ */
+void GetStorageInfo(Service::Interface* self);
+
+/**
+ * BOSS::RegisterPrivateRootCa service function
+ * Inputs:
+ * 0 : Header Code[0x00050042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void RegisterPrivateRootCa(Service::Interface* self);
+
+/**
+ * BOSS::RegisterPrivateClientCert service function
+ * Inputs:
+ * 0 : Header Code[0x00060084]
+ * 1 : u32 unknown value
+ * 2 : u32 unknown value
+ * 3 : MappedBufferDesc1(permission = R)
+ * 4 : u32 buff_addr1
+ * 5 : MappedBufferDesc2(permission = R)
+ * 6 : u32 buff_addr2
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff1_size << 4 | 0xA
+ * 3 : u32 buff_addr1
+ * 4 : buff2_size << 4 | 0xA
+ * 5 : u32 buff_addr2
+ */
+void RegisterPrivateClientCert(Service::Interface* self);
+
+/**
+ * BOSS::GetNewArrivalFlag service function
+ * Inputs:
+ * 0 : Header Code[0x00070000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 flag
+ */
+void GetNewArrivalFlag(Service::Interface* self);
+
+/**
+ * BOSS::RegisterNewArrivalEvent service function
+ * Inputs:
+ * 0 : Header Code[0x00080002]
+ * 1 : u32 unknown1
+ * 2 : u32 unknown2
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void RegisterNewArrivalEvent(Service::Interface* self);
+
+/**
+ * BOSS::SetOptoutFlag service function
+ * Inputs:
+ * 0 : Header Code[0x00090040]
+ * 1 : u8 output_flag
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void SetOptoutFlag(Service::Interface* self);
+
+/**
+ * BOSS::GetOptoutFlag service function
+ * Inputs:
+ * 0 : Header Code[0x000A0000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 output_flag
+ */
+void GetOptoutFlag(Service::Interface* self);
+
+/**
+ * BOSS::RegisterTask service function
+ * Inputs:
+ * 0 : Header Code[0x000B00C2]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : u8 unknown value
+ * 4 : MappedBufferDesc1(permission = R)
+ * 5 : buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void RegisterTask(Service::Interface* self);
+
+/**
+ * BOSS::UnregisterTask service function
+ * Inputs:
+ * 0 : Header Code[0x000C0082]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc1(permission = R)
+ * 4 : buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void UnregisterTask(Service::Interface* self);
+
+/**
+ * BOSS::ReconfigureTask service function
+ * Inputs:
+ * 0 : Header Code[0x000D0082]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc1(permission = R)
+ * 4 : buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void ReconfigureTask(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskIdList service function
+ * Inputs:
+ * 0 : Header Code[0x000E0000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void GetTaskIdList(Service::Interface* self);
+
+/**
+ * BOSS::GetStepIdList service function
+ * Inputs:
+ * 0 : Header Code[0x000F0042]
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ *
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void GetStepIdList(Service::Interface* self);
+
+/**
+ * BOSS::GetNsDataIdList service function
+ * Inputs:
+ * 0 : Header Code[0x00100102]
+ * 1 : u32 unknown1
+ * 2 : u32 unknown2
+ * 3 : u32 unknown3
+ * 4 : u32 unknown4
+ * 5 : MappedBufferDesc(permission = W)
+ * 6 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u16 unknown value
+ * 3 : u16 unknown value
+ * 4 : buff_size << 4 | 0xC
+ * 5 : u32 buff_addr
+ */
+void GetNsDataIdList(Service::Interface* self);
+
+/**
+ * BOSS::GetOwnNsDataIdList service function
+ * Inputs:
+ * 0 : Header Code[0x00110102]
+ * 1 : u32 unknown1
+ * 2 : u32 unknown2
+ * 3 : u32 unknown3
+ * 4 : u32 unknown4
+ * 5 : MappedBufferDesc(permission = W)
+ * 6 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u16 unknown value
+ * 3 : u16 unknown value
+ * 4 : buff_size << 4 | 0xC
+ * 5 : u32 buff_addr
+ */
+void GetOwnNsDataIdList(Service::Interface* self);
+
+/**
+ * BOSS::GetNewDataNsDataIdList service function
+ * Inputs:
+ * 0 : Header Code[0x00120102]
+ * 1 : u32 unknown1
+ * 2 : u32 unknown2
+ * 3 : u32 unknown3
+ * 4 : u32 unknown4
+ * 5 : MappedBufferDesc(permission = W)
+ * 6 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u16 unknown value
+ * 3 : u16 unknown value
+ * 4 : buff_size << 4 | 0xC
+ * 5 : u32 buff_addr
+ */
+void GetNewDataNsDataIdList(Service::Interface* self);
+
+/**
+ * BOSS::GetOwnNewDataNsDataIdList service function
+ * Inputs:
+ * 0 : Header Code[0x00130102]
+ * 1 : u32 unknown1
+ * 2 : u32 unknown2
+ * 3 : u32 unknown3
+ * 4 : u32 unknown4
+ * 5 : MappedBufferDesc(permission = W)
+ * 6 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u16 unknown value
+ * 3 : u16 unknown value
+
+ */
+void GetOwnNewDataNsDataIdList(Service::Interface* self);
+
+/**
+ * BOSS::SendProperty service function
+ * Inputs:
+ * 0 : Header Code[0x00140082]
+ * 1 : u16 unknown value
+ * 2 : u32 unknown value
+ * 3 : MappedBufferDesc(permission = R)
+ * 4 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void SendProperty(Service::Interface* self);
+
+/**
+ * BOSS::SendPropertyHandle service function
+ * Inputs:
+ * 0 : Header Code[0x00150042]
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc(permission = R)
+ * 4 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void SendPropertyHandle(Service::Interface* self);
+
+/**
+ * BOSS::ReceiveProperty service function
+ * Inputs:
+ * 0 : Header Code[0x00160082]
+ * 1 : u16 unknown1
+ * 2 : u32 buff_size
+ * 3 : MappedBufferDesc(permission = W)
+ * 4 : u32 buff addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : u16 unknown value
+ * 4 : buff_size << 4 | 0xC
+ * 5 : u32 buff_addr
+ */
+void ReceiveProperty(Service::Interface* self);
+
+/**
+ * BOSS::UpdateTaskInterval service function
+ * Inputs:
+ * 0 : Header Code[0x00170082]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc1(permission = R)
+ * 4 : buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void UpdateTaskInterval(Service::Interface* self);
+
+/**
+ * BOSS::UpdateTaskCount service function
+ * Inputs:
+ * 0 : Header Code[0x00180082]
+ * 1 : u32 buff_size
+ * 2 : u32 unknown2
+ * 3 : MappedBufferDesc(permission = R)
+ * 4 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void UpdateTaskCount(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskInterval service function
+ * Inputs:
+ * 0 : Header Code[0x00190042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : buff_size << 4 | 0xA
+ * 4 : u32 buff_addr
+ */
+void GetTaskInterval(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskCount service function
+ * Inputs:
+ * 0 : Header Code[0x001A0042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : buff_size << 4 | 0xA
+ * 4 : u32 buff_addr
+ */
+void GetTaskCount(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskServiceStatus service function
+ * Inputs:
+ * 0 : Header Code[0x001B0042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : buff_size << 4 | 0xA
+ * 4 : u32 buff_addr
+ */
+void GetTaskServiceStatus(Service::Interface* self);
+
+/**
+ * BOSS::StartTask service function
+ * Inputs:
+ * 0 : Header Code[0x001C0042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void StartTask(Service::Interface* self);
+
+/**
+ * BOSS::StartTaskImmediate service function
+ * Inputs:
+ * 0 : Header Code[0x001D0042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void StartTaskImmediate(Service::Interface* self);
+
+/**
+ * BOSS::CancelTask service function
+ * Inputs:
+ * 0 : Header Code[0x001E0042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void CancelTask(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskFinishHandle service function
+ * Inputs:
+ * 0 : Header Code[0x001F0000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : 0
+ * 3 : Task Finish Handle
+ */
+void GetTaskFinishHandle(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskState service function
+ * Inputs:
+ * 0 : Header Code[0x00200082]
+ * 1 : u32 buff_size
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc(permission = R)
+ * 4 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : u32 unknown value
+ * 4 : u8 unknown value
+ * 5 : buff_size << 4 | 0xA
+ * 6 : u32 buff_addr
+ */
+void GetTaskState(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskResult service function
+ * Inputs:
+ * 0 : Header Code[0x00210042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : u32 unknown value
+ * 4 : u8 unknown value
+ * 5 : buff_size << 4 | 0xA
+ * 6 : u32 buff_addr
+ */
+void GetTaskResult(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskCommErrorCode service function
+ * Inputs:
+ * 0 : Header Code[0x00220042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : u32 unknown value
+ * 4 : u8 unknown value
+ * 5 : buff_size << 4 | 0xA
+ * 6 : u32 buff_addr
+ */
+void GetTaskCommErrorCode(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskStatus service function
+ * Inputs:
+ * 0 : Header Code[0x002300C2]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : u8 unknown value
+ * 4 : MappedBufferDesc(permission = R)
+ * 5 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : buff_size << 4 | 0xA
+ * 4 : u32 buff_addr
+ */
+void GetTaskStatus(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskError service function
+ * Inputs:
+ * 0 : Header Code[0x00240082]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc(permission = R)
+ * 4 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : buff_size << 4 | 0xA
+ * 4 : u32 buff_addr
+ */
+void GetTaskError(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskInfo service function
+ * Inputs:
+ * 0 : Header Code[0x00250082]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : MappedBufferDesc(permission = R)
+ * 4 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void GetTaskInfo(Service::Interface* self);
+
+/**
+ * BOSS::DeleteNsData service function
+ * Inputs:
+ * 0 : Header Code[0x00260040]
+ * 1 : u32 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void DeleteNsData(Service::Interface* self);
+
+/**
+ * BOSS::GetNsDataHeaderInfo service function
+ * Inputs:
+ * 0 : Header Code[0x002700C2]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : u32 unknown value
+ * 4 : MappedBufferDesc(permission = W)
+ * 5 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xC
+ * 3 : u32 buff_addr
+ */
+void GetNsDataHeaderInfo(Service::Interface* self);
+
+/**
+ * BOSS::ReadNsData service function
+ * Inputs:
+ * 0 : Header Code[0x00280102]
+ * 1 : u32 unknown value
+ * 2 : u32 unknown value
+ * 3 : u32 unknown value
+ * 4 : u32 unknown value
+ * 5 : MappedBufferDesc(permission = W)
+ * 6 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : u32 unknown value
+ * 4 : buff_size << 4 | 0xC
+ * 5 : u32 buff_addr
+ */
+void ReadNsData(Service::Interface* self);
+
+/**
+ * BOSS::SetNsDataAdditionalInfo service function
+ * Inputs:
+ * 0 : Header Code[0x00290080]
+ * 1 : u32 unknown value
+ * 2 : u32 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void SetNsDataAdditionalInfo(Service::Interface* self);
+
+/**
+ * BOSS::GetNsDataAdditionalInfo service function
+ * Inputs:
+ * 0 : Header Code[0x002A0040]
+ * 1 : u32 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ */
+void GetNsDataAdditionalInfo(Service::Interface* self);
+
+/**
+ * BOSS::SetNsDataNewFlag service function
+ * Inputs:
+ * 0 : Header Code[0x002B0080]
+ * 1 : u32 unknown value
+ * 2 : u8 flag
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void SetNsDataNewFlag(Service::Interface* self);
+
+/**
+ * BOSS::GetNsDataNewFlag service function
+ * Inputs:
+ * 0 : Header Code[0x002C0040]
+ * 1 : u32 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 flag
+ */
+void GetNsDataNewFlag(Service::Interface* self);
+
+/**
+ * BOSS::GetNsDataLastUpdate service function
+ * Inputs:
+ * 0 : Header Code[0x002D0040]
+ * 1 : u32 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : u32 unknown value
+ */
+void GetNsDataLastUpdate(Service::Interface* self);
+
+/**
+ * BOSS::GetErrorCode service function
+ * Inputs:
+ * 0 : Header Code[0x002E0040]
+ * 1 : u8 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ */
+void GetErrorCode(Service::Interface* self);
+
+/**
+ * BOSS::RegisterStorageEntry service function
+ * Inputs:
+ * 0 : Header Code[0x002F0140]
+ * 1 : u32 unknown value
+ * 2 : u32 unknown value
+ * 3 : u32 unknown value
+ * 4 : u16 unknown value
+ * 5 : u8 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void RegisterStorageEntry(Service::Interface* self);
+
+/**
+ * BOSS::GetStorageEntryInfo service function
+ * Inputs:
+ * 0 : Header Code[0x00300000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u32 unknown value
+ * 3 : u16 unknown value
+ */
+void GetStorageEntryInfo(Service::Interface* self);
+
+/**
+ * BOSS::SetStorageOption service function
+ * Inputs:
+ * 0 : Header Code[0x00310100]
+ * 1 : u8 unknown value
+ * 2 : u32 unknown value
+ * 3 : u16 unknown value
+ * 4 : u16 unknown value
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ */
+void SetStorageOption(Service::Interface* self);
+
+/**
+ * BOSS::GetStorageOption service function
+ * Inputs:
+ * 0 : Header Code[0x00320000]
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : u32 unknown value
+ * 4 : u16 unknown value
+ * 5 : u16 unknown value
+ */
+void GetStorageOption(Service::Interface* self);
+
+/**
+ * BOSS::StartBgImmediate service function
+ * Inputs:
+ * 0 : Header Code[0x00330042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void StartBgImmediate(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskActivePriority service function
+ * Inputs:
+ * 0 : Header Code[0x00340042]
+ * 1 : u32 unknown value
+ * 2 : MappedBufferDesc(permission = R)
+ * 3 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : u8 unknown value
+ * 3 : buff_size << 4 | 0xA
+ * 4 : u32 buff_addr
+ */
+void GetTaskActivePriority(Service::Interface* self);
+
+/**
+ * BOSS::RegisterImmediateTask service function
+ * Inputs:
+ * 0 : Header Code[0x003500C2]
+ * 1 : u32 unknown value
+ * 2 : u8 unknown value
+ * 3 : u8 unknown value
+ * 4 : MappedBufferDesc(permission = R)
+ * 5 : u32 buff_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff_size << 4 | 0xA
+ * 3 : u32 buff_addr
+ */
+void RegisterImmediateTask(Service::Interface* self);
+
+/**
+ * BOSS::SetTaskQuery service function
+ * Inputs:
+ * 0 : Header Code[0x00360084]
+ * 1 : u32 unknown value
+ * 2 : u32 unknown value
+ * 3 : MappedBufferDesc1(permission = R)
+ * 4 : u32 buff1_addr
+ * 5 : MappedBufferDesc2(permission = R)
+ * 6 : u32 buff2_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff1_size << 4 | 0xA
+ * 3 : u32 buff1_addr
+ * 4 : buff2_size << 4 | 0xA
+ * 5 : u32 buff2_addr
+ */
+void SetTaskQuery(Service::Interface* self);
+
+/**
+ * BOSS::GetTaskQuery service function
+ * Inputs:
+ * 0 : Header Code[0x00370084]
+ * 1 : u32 unknown value
+ * 2 : u32 unknown value
+ * 3 : MappedBufferDesc1(permission = R)
+ * 4 : u32 buff1_addr
+ * 5 : MappedBufferDesc2(permission = W)
+ * 6 : u32 buff2_addr
+ * Outputs:
+ * 1 : Result of function, 0 on success, otherwise error code
+ * 2 : buff1_size << 4 | 0xA
+ * 3 : u32 buff1_addr
+ * 4 : buff2_size << 4 | 0xC
+ * 5 : u32 buff2_addr
+ */
+void GetTaskQuery(Service::Interface* self);
+
/// Initialize BOSS service(s)
void Init();
diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp
index 6affa23b1..371d702e0 100644
--- a/src/core/hle/service/boss/boss_u.cpp
+++ b/src/core/hle/service/boss/boss_u.cpp
@@ -2,16 +2,68 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "core/hle/service/boss/boss.h"
#include "core/hle/service/boss/boss_u.h"
namespace Service {
namespace BOSS {
const Interface::FunctionInfo FunctionTable[] = {
- {0x00020100, nullptr, "GetStorageInfo"},
- {0x000C0082, nullptr, "UnregisterTask"},
- {0x001E0042, nullptr, "CancelTask"},
- {0x00330042, nullptr, "StartBgImmediate"},
+ {0x00010082, InitializeSession, "InitializeSession"},
+ {0x00020100, RegisterStorage, "RegisterStorage"},
+ {0x00030000, UnregisterStorage, "UnregisterStorage"},
+ {0x00040000, GetStorageInfo, "GetStorageInfo"},
+ {0x00050042, RegisterPrivateRootCa, "RegisterPrivateRootCa"},
+ {0x00060084, RegisterPrivateClientCert, "RegisterPrivateClientCert"},
+ {0x00070000, GetNewArrivalFlag, "GetNewArrivalFlag"},
+ {0x00080002, RegisterNewArrivalEvent, "RegisterNewArrivalEvent"},
+ {0x00090040, SetOptoutFlag, "SetOptoutFlag"},
+ {0x000A0000, GetOptoutFlag, "GetOptoutFlag"},
+ {0x000B00C2, RegisterTask, "RegisterTask"},
+ {0x000C0082, UnregisterTask, "UnregisterTask"},
+ {0x000D0082, ReconfigureTask, "ReconfigureTask"},
+ {0x000E0000, GetTaskIdList, "GetTaskIdList"},
+ {0x000F0042, GetStepIdList, "GetStepIdList"},
+ {0x00100102, GetNsDataIdList, "GetNsDataIdList"},
+ {0x00110102, GetOwnNsDataIdList, "GetOwnNsDataIdList"},
+ {0x00120102, GetNewDataNsDataIdList, "GetNewDataNsDataIdList"},
+ {0x00130102, GetOwnNewDataNsDataIdList, "GetOwnNewDataNsDataIdList"},
+ {0x00140082, SendProperty, "SendProperty"},
+ {0x00150042, SendPropertyHandle, "SendPropertyHandle"},
+ {0x00160082, ReceiveProperty, "ReceiveProperty"},
+ {0x00170082, UpdateTaskInterval, "UpdateTaskInterval"},
+ {0x00180082, UpdateTaskCount, "UpdateTaskCount"},
+ {0x00190042, GetTaskInterval, "GetTaskInterval"},
+ {0x001A0042, GetTaskCount, "GetTaskCount"},
+ {0x001B0042, GetTaskServiceStatus, "GetTaskServiceStatus"},
+ {0x001C0042, StartTask, "StartTask"},
+ {0x001D0042, StartTaskImmediate, "StartTaskImmediate"},
+ {0x001E0042, CancelTask, "CancelTask"},
+ {0x001F0000, GetTaskFinishHandle, "GetTaskFinishHandle"},
+ {0x00200082, GetTaskState, "GetTaskState"},
+ {0x00210042, GetTaskResult, "GetTaskResult"},
+ {0x00220042, GetTaskCommErrorCode, "GetTaskCommErrorCode"},
+ {0x002300C2, GetTaskStatus, "GetTaskStatus"},
+ {0x00240082, GetTaskError, "GetTaskError"},
+ {0x00250082, GetTaskInfo, "GetTaskInfo"},
+ {0x00260040, DeleteNsData, "DeleteNsData"},
+ {0x002700C2, GetNsDataHeaderInfo, "GetNsDataHeaderInfo"},
+ {0x00280102, ReadNsData, "ReadNsData"},
+ {0x00290080, SetNsDataAdditionalInfo, "SetNsDataAdditionalInfo"},
+ {0x002A0040, GetNsDataAdditionalInfo, "GetNsDataAdditionalInfo"},
+ {0x002B0080, SetNsDataNewFlag, "SetNsDataNewFlag"},
+ {0x002C0040, GetNsDataNewFlag, "GetNsDataNewFlag"},
+ {0x002D0040, GetNsDataLastUpdate, "GetNsDataLastUpdate"},
+ {0x002E0040, GetErrorCode, "GetErrorCode"},
+ {0x002F0140, RegisterStorageEntry, "RegisterStorageEntry"},
+ {0x00300000, GetStorageEntryInfo, "GetStorageEntryInfo"},
+ {0x00310100, SetStorageOption, "SetStorageOption"},
+ {0x00320000, GetStorageOption, "GetStorageOption"},
+ {0x00330042, StartBgImmediate, "StartBgImmediate"},
+ {0x00340042, GetTaskActivePriority, "GetTaskActivePriority"},
+ {0x003500C2, RegisterImmediateTask, "RegisterImmediateTask"},
+ {0x00360084, SetTaskQuery, "SetTaskQuery"},
+ {0x00370084, GetTaskQuery, "GetTaskQuery"},
};
BOSS_U_Interface::BOSS_U_Interface() {
diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp
index fa5080535..1d16f8732 100644
--- a/src/core/hle/service/frd/frd.cpp
+++ b/src/core/hle/service/frd/frd.cpp
@@ -87,7 +87,7 @@ void GetMyFriendKey(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- Memory::WriteBlock(cmd_buff[2], &my_friend_key, sizeof(FriendKey));
+ std::memcpy(&cmd_buff[2], &my_friend_key, sizeof(FriendKey));
LOG_WARNING(Service_FRD, "(STUBBED) called");
}
diff --git a/src/core/hle/service/ldr_ro/cro_helper.cpp b/src/core/hle/service/ldr_ro/cro_helper.cpp
index b7d250312..4f0aa77eb 100644
--- a/src/core/hle/service/ldr_ro/cro_helper.cpp
+++ b/src/core/hle/service/ldr_ro/cro_helper.cpp
@@ -1227,7 +1227,7 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
// The bug itself is:
// If a relocation target is in .data segment, it will relocate to the
// user-specified buffer. But if this is linking during loading,
- // the .data segment hasn't been tranfer from CRO to the buffer,
+ // the .data segment hasn't been transfer from CRO to the buffer,
// thus the relocation will be overwritten by data transfer.
// To fix this bug, we need temporarily restore the old .data segment
// offset and apply imported symbols.
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 27e829209..80081aae2 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -97,10 +97,21 @@ static void Initialize(Service::Interface* self) {
u32 value = cmd_buff[13];
u32 handle = cmd_buff[14];
+ // Because NWM service is not implemented at all, we stub the Initialize function with an error
+ // code instead of success to prevent games from using the service and from causing more issues.
+ // The error code is from a real 3DS with wifi off, thus believed to be "network disabled".
+ /*
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = 0;
cmd_buff[3] = Kernel::g_handle_table.Create(handle_event)
.MoveFrom(); // TODO(purpasmart): Verify if this is a event handle
+ */
+ cmd_buff[0] = IPC::MakeHeader(0x1B, 1, 2);
+ cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(2), ErrorModule::UDS,
+ ErrorSummary::StatusChanged, ErrorLevel::Status)
+ .raw;
+ cmd_buff[2] = 0;
+ cmd_buff[3] = 0;
LOG_WARNING(Service_NWM, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, value=%u, handle=0x%08X",
unk1, unk2, value, handle);
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 4279b67fb..46b75db25 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -104,7 +104,9 @@ static const std::unordered_map<int, int> error_map = {{
{ERRNO(ENETUNREACH), 40},
{ENFILE, 41},
{ERRNO(ENOBUFS), 42},
+#ifdef ENODATA
{ENODATA, 43},
+#endif
{ENODEV, 44},
{ENOENT, 45},
{ENOEXEC, 46},
@@ -114,8 +116,12 @@ static const std::unordered_map<int, int> error_map = {{
{ENOMSG, 50},
{ERRNO(ENOPROTOOPT), 51},
{ENOSPC, 52},
+#ifdef ENOSR
{ENOSR, 53},
+#endif
+#ifdef ENOSTR
{ENOSTR, 54},
+#endif
{ENOSYS, 55},
{ERRNO(ENOTCONN), 56},
{ENOTDIR, 57},
@@ -136,7 +142,9 @@ static const std::unordered_map<int, int> error_map = {{
{ESPIPE, 72},
{ESRCH, 73},
{ERRNO(ESTALE), 74},
+#ifdef ETIME
{ETIME, 75},
+#endif
{ERRNO(ETIMEDOUT), 76},
}};
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index 2e4510857..fadd7b16b 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -163,7 +163,7 @@ ResultStatus AppLoader_NCCH::LoadExec() {
Kernel::g_current_process->ideal_processor =
exheader_header.arm11_system_local_caps.ideal_processor;
- // Copy data while converting endianess
+ // Copy data while converting endianness
std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps;
std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(),
begin(kernel_caps));
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h
index 04350d006..f8718d063 100644
--- a/src/core/loader/ncch.h
+++ b/src/core/loader/ncch.h
@@ -11,7 +11,7 @@
#include "core/loader/loader.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
-/// NCCH header (Note: "NCCH" appears to be a publically unknown acronym)
+/// NCCH header (Note: "NCCH" appears to be a publicly unknown acronym)
struct NCCH_Header {
u8 signature[0x100];
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 4a0969b00..05f41f798 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -7,6 +7,8 @@
#include "settings.h"
#include "video_core/video_core.h"
+#include "common/emu_window.h"
+
namespace Settings {
Values values = {};
@@ -20,6 +22,11 @@ void Apply() {
VideoCore::g_shader_jit_enabled = values.use_shader_jit;
VideoCore::g_scaled_resolution_enabled = values.use_scaled_resolution;
+ if (VideoCore::g_emu_window) {
+ auto layout = VideoCore::g_emu_window->GetFramebufferLayout();
+ VideoCore::g_emu_window->UpdateCurrentFramebufferLayout(layout.width, layout.height);
+ }
+
AudioCore::SelectSink(values.sink_id);
AudioCore::EnableStretching(values.enable_audio_stretching);
}
diff --git a/src/core/settings.h b/src/core/settings.h
index 5a64f8018..e931953d7 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -10,7 +10,15 @@
namespace Settings {
+enum class LayoutOption {
+ Default,
+ SingleScreen,
+ LargeScreen,
+ Custom,
+};
+
namespace NativeInput {
+
enum Values {
// directly mapped keys
A,
@@ -84,6 +92,9 @@ struct Values {
bool use_scaled_resolution;
bool use_vsync;
+ LayoutOption layout_option;
+ bool swap_screen;
+
float bg_red;
float bg_green;
float bg_blue;
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index bb618cacd..6bd5b281c 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -215,18 +215,17 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler;
- if (g_debug_context) {
+ if (g_debug_context && g_debug_context->recorder) {
for (int i = 0; i < 3; ++i) {
const auto texture = regs.GetTextures()[i];
if (!texture.enabled)
continue;
u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress());
- if (g_debug_context && Pica::g_debug_context->recorder)
- g_debug_context->recorder->MemoryAccessed(
- texture_data, Pica::Regs::NibblesPerPixel(texture.format) *
- texture.config.width / 2 * texture.config.height,
- texture.config.GetPhysicalAddress());
+ g_debug_context->recorder->MemoryAccessed(
+ texture_data, Pica::Regs::NibblesPerPixel(texture.format) *
+ texture.config.width / 2 * texture.config.height,
+ texture.config.GetPhysicalAddress());
}
}
@@ -292,7 +291,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) {
}
}
- // Retreive vertex from register data
+ // Retrieve vertex from register data
Shader::OutputVertex output_vertex = output_registers.ToVertex(regs.vs);
// Send to renderer
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index b2db609ec..99bd59a69 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -40,7 +40,7 @@ namespace Pica {
// field offset. Otherwise, the compiler will fail to compile this code.
#define PICA_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) \
((typename std::enable_if<backup_workaround_index == PICA_REG_INDEX(field_name), \
- size_t>::type)PICA_REG_INDEX(field_name))
+ size_t>::type) PICA_REG_INDEX(field_name))
#endif // _MSC_VER
struct Regs {
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 03a588364..93f0ac105 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -390,6 +390,8 @@ void RendererOpenGL::DrawSingleScreenRotated(const ScreenInfo& screen_info, floa
*/
void RendererOpenGL::DrawScreens() {
auto layout = render_window->GetFramebufferLayout();
+ const auto& top_screen = layout.top_screen;
+ const auto& bottom_screen = layout.bottom_screen;
glViewport(0, 0, layout.width, layout.height);
glClear(GL_COLOR_BUFFER_BIT);
@@ -403,12 +405,15 @@ void RendererOpenGL::DrawScreens() {
glActiveTexture(GL_TEXTURE0);
glUniform1i(uniform_color_texture, 0);
- DrawSingleScreenRotated(screen_infos[0], (float)layout.top_screen.left,
- (float)layout.top_screen.top, (float)layout.top_screen.GetWidth(),
- (float)layout.top_screen.GetHeight());
- DrawSingleScreenRotated(screen_infos[1], (float)layout.bottom_screen.left,
- (float)layout.bottom_screen.top, (float)layout.bottom_screen.GetWidth(),
- (float)layout.bottom_screen.GetHeight());
+ if (layout.top_screen_enabled) {
+ DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left, (float)top_screen.top,
+ (float)top_screen.GetWidth(), (float)top_screen.GetHeight());
+ }
+ if (layout.bottom_screen_enabled) {
+ DrawSingleScreenRotated(screen_infos[1], (float)bottom_screen.left,
+ (float)bottom_screen.top, (float)bottom_screen.GetWidth(),
+ (float)bottom_screen.GetHeight());
+ }
m_current_frame++;
}
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 272f3ffe1..3febe739c 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -146,10 +146,8 @@ DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_
state.debug.max_opdesc_id = 0;
// Setup input register table
+ boost::fill(state.registers.input, Math::Vec4<float24>::AssignToAll(float24::Zero()));
const auto& attribute_register_map = config.input_register_map;
- float24 dummy_register;
- boost::fill(state.registers.input, &dummy_register);
-
for (unsigned i = 0; i < num_attributes; i++)
state.registers.input[attribute_register_map.GetRegisterForAttribute(i)] = input.attr[i];
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 501d00b6b..6abb6761f 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -116,32 +116,36 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned
: state.address_registers[instr.common.address_register_index - 1];
const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) +
- (!is_inverted * address_offset));
+ (is_inverted ? 0 : address_offset));
const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) +
- (is_inverted * address_offset));
+ (is_inverted ? address_offset : 0));
const bool negate_src1 = ((bool)swizzle.negate_src1 != false);
const bool negate_src2 = ((bool)swizzle.negate_src2 != false);
float24 src1[4] = {
- src1_[(int)swizzle.GetSelectorSrc1(0)], src1_[(int)swizzle.GetSelectorSrc1(1)],
- src1_[(int)swizzle.GetSelectorSrc1(2)], src1_[(int)swizzle.GetSelectorSrc1(3)],
+ src1_[(int)swizzle.src1_selector_0.Value()],
+ src1_[(int)swizzle.src1_selector_1.Value()],
+ src1_[(int)swizzle.src1_selector_2.Value()],
+ src1_[(int)swizzle.src1_selector_3.Value()],
};
if (negate_src1) {
- src1[0] = src1[0] * float24::FromFloat32(-1);
- src1[1] = src1[1] * float24::FromFloat32(-1);
- src1[2] = src1[2] * float24::FromFloat32(-1);
- src1[3] = src1[3] * float24::FromFloat32(-1);
+ src1[0] = -src1[0];
+ src1[1] = -src1[1];
+ src1[2] = -src1[2];
+ src1[3] = -src1[3];
}
float24 src2[4] = {
- src2_[(int)swizzle.GetSelectorSrc2(0)], src2_[(int)swizzle.GetSelectorSrc2(1)],
- src2_[(int)swizzle.GetSelectorSrc2(2)], src2_[(int)swizzle.GetSelectorSrc2(3)],
+ src2_[(int)swizzle.src2_selector_0.Value()],
+ src2_[(int)swizzle.src2_selector_1.Value()],
+ src2_[(int)swizzle.src2_selector_2.Value()],
+ src2_[(int)swizzle.src2_selector_3.Value()],
};
if (negate_src2) {
- src2[0] = src2[0] * float24::FromFloat32(-1);
- src2[1] = src2[1] * float24::FromFloat32(-1);
- src2[2] = src2[2] * float24::FromFloat32(-1);
- src2[3] = src2[3] * float24::FromFloat32(-1);
+ src2[0] = -src2[0];
+ src2[1] = -src2[1];
+ src2[2] = -src2[2];
+ src2[3] = -src2[3];
}
float24* dest =
@@ -451,34 +455,40 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned
const bool negate_src3 = ((bool)swizzle.negate_src3 != false);
float24 src1[4] = {
- src1_[(int)swizzle.GetSelectorSrc1(0)], src1_[(int)swizzle.GetSelectorSrc1(1)],
- src1_[(int)swizzle.GetSelectorSrc1(2)], src1_[(int)swizzle.GetSelectorSrc1(3)],
+ src1_[(int)swizzle.src1_selector_0.Value()],
+ src1_[(int)swizzle.src1_selector_1.Value()],
+ src1_[(int)swizzle.src1_selector_2.Value()],
+ src1_[(int)swizzle.src1_selector_3.Value()],
};
if (negate_src1) {
- src1[0] = src1[0] * float24::FromFloat32(-1);
- src1[1] = src1[1] * float24::FromFloat32(-1);
- src1[2] = src1[2] * float24::FromFloat32(-1);
- src1[3] = src1[3] * float24::FromFloat32(-1);
+ src1[0] = -src1[0];
+ src1[1] = -src1[1];
+ src1[2] = -src1[2];
+ src1[3] = -src1[3];
}
float24 src2[4] = {
- src2_[(int)swizzle.GetSelectorSrc2(0)], src2_[(int)swizzle.GetSelectorSrc2(1)],
- src2_[(int)swizzle.GetSelectorSrc2(2)], src2_[(int)swizzle.GetSelectorSrc2(3)],
+ src2_[(int)swizzle.src2_selector_0.Value()],
+ src2_[(int)swizzle.src2_selector_1.Value()],
+ src2_[(int)swizzle.src2_selector_2.Value()],
+ src2_[(int)swizzle.src2_selector_3.Value()],
};
if (negate_src2) {
- src2[0] = src2[0] * float24::FromFloat32(-1);
- src2[1] = src2[1] * float24::FromFloat32(-1);
- src2[2] = src2[2] * float24::FromFloat32(-1);
- src2[3] = src2[3] * float24::FromFloat32(-1);
+ src2[0] = -src2[0];
+ src2[1] = -src2[1];
+ src2[2] = -src2[2];
+ src2[3] = -src2[3];
}
float24 src3[4] = {
- src3_[(int)swizzle.GetSelectorSrc3(0)], src3_[(int)swizzle.GetSelectorSrc3(1)],
- src3_[(int)swizzle.GetSelectorSrc3(2)], src3_[(int)swizzle.GetSelectorSrc3(3)],
+ src3_[(int)swizzle.src3_selector_0.Value()],
+ src3_[(int)swizzle.src3_selector_1.Value()],
+ src3_[(int)swizzle.src3_selector_2.Value()],
+ src3_[(int)swizzle.src3_selector_3.Value()],
};
if (negate_src3) {
- src3[0] = src3[0] * float24::FromFloat32(-1);
- src3[1] = src3[1] * float24::FromFloat32(-1);
- src3[2] = src3[2] * float24::FromFloat32(-1);
- src3[3] = src3[3] * float24::FromFloat32(-1);
+ src3[0] = -src3[0];
+ src3[1] = -src3[1];
+ src3[2] = -src3[2];
+ src3[3] = -src3[3];
}
float24* dest =