summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.travis-deps.sh2
-rwxr-xr-x.travis-upload.sh2
-rw-r--r--CMakeLists.txt35
-rw-r--r--CONTRIBUTING.md35
-rw-r--r--README.md5
-rw-r--r--dist/citra.xml24
-rw-r--r--externals/microprofile/microprofile.h12
-rw-r--r--externals/microprofile/microprofileui.h1
-rwxr-xr-xhooks/pre-commit8
-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
72 files changed, 2611 insertions, 307 deletions
diff --git a/.travis-deps.sh b/.travis-deps.sh
index 8538098c1..ab3a32382 100755
--- a/.travis-deps.sh
+++ b/.travis-deps.sh
@@ -29,5 +29,5 @@ if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
brew update
- brew install cmake qt5 sdl2 dylibbundler
+ brew install qt5 sdl2 dylibbundler
fi
diff --git a/.travis-upload.sh b/.travis-upload.sh
index 7838bf079..1bec74b3d 100755
--- a/.travis-upload.sh
+++ b/.travis-upload.sh
@@ -1,4 +1,4 @@
-if [ "$TRAVIS_BRANCH" = "master" ]; then
+if [ "$TRAVIS_EVENT_TYPE" = "push" ]&&[ "$TRAVIS_BRANCH" = "master" ]; then
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
GITREV="`git show -s --format='%h'`"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7a24f04f..56503f1ad 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,6 +68,15 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+
+ if (MINGW)
+ add_definitions(-DMINGW_HAS_SECURE_API)
+ if (MINGW_STATIC_BUILD)
+ add_definitions(-DQT_STATICPLUGIN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
+ endif()
+ endif()
else()
# Silence "deprecation" warnings
add_definitions(/D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE /D_SCL_SECURE_NO_WARNINGS)
@@ -105,6 +114,15 @@ else()
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
endif()
+# Set file offset size to 64 bits.
+#
+# On modern Unixes, this is typically already the case. The lone exception is
+# glibc, which may default to 32 bits. glibc allows this to be configured
+# by setting _FILE_OFFSET_BITS.
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ add_definitions(-D_FILE_OFFSET_BITS=64)
+endif()
+
add_definitions(-DSINGLETHREADED)
# CMake seems to only define _DEBUG on Windows
set_property(DIRECTORY APPEND PROPERTY
@@ -160,23 +178,30 @@ endif()
IF (APPLE)
FIND_LIBRARY(COCOA_LIBRARY Cocoa) # Umbrella framework for everything GUI-related
- set(PLATFORM_LIBRARIES iconv ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
+ set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
ELSEIF(MINGW)
- # GCC does not support codecvt, so use iconv instead
# PSAPI is the Process Status API
- set(PLATFORM_LIBRARIES winmm ws2_32 psapi iconv)
+ set(PLATFORM_LIBRARIES winmm ws2_32 psapi imm32 version)
# WSAPoll functionality doesn't exist before WinNT 6.x (Vista and up)
add_definitions(-D_WIN32_WINNT=0x0600)
ELSEIF(WIN32)
set(PLATFORM_LIBRARIES winmm ws2_32)
-ELSE()
+ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
set(PLATFORM_LIBRARIES rt)
ENDIF (APPLE)
+# MINGW: GCC does not support codecvt, so use iconv instead
+if (UNIX OR MINGW)
+ find_library(ICONV_LIBRARY NAMES iconv)
+ if (ICONV_LIBRARY)
+ list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY})
+ endif()
+endif()
+
if (ENABLE_QT)
if (CITRA_USE_BUNDLED_QT)
if (MSVC14 AND ARCHITECTURE_x86_64)
@@ -253,7 +278,7 @@ add_subdirectory(src)
# http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
# http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
# http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
-if(${CMAKE_SYSTEM_NAME} MATCHES "Linux|FreeBSD|OpenBSD|NetBSD")
+if(ENABLE_QT AND UNIX AND NOT APPLE)
install(FILES "${CMAKE_SOURCE_DIR}/dist/citra.desktop"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
install(FILES "${CMAKE_SOURCE_DIR}/dist/citra.svg"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c2735f564..7a21eebf8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,21 +1,19 @@
# Reporting Issues
-**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) and then either visit our IRC channel or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked.
+**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) and then either visit our IRC channel, [our forum](https://discuss.citra-emu.org/) or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked.
If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside Citra) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
-While issues about specific games not booting are valid bugs, we are currently not interested in them unless you have several games which fail with the same or similar messages. (In which case please file only a single issue about it.) There are too many non-working games right now to file individual issues for every one of them.
-
# Contributing
-Citra is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. They aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible:
+Citra is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible:
### General Rules
* A lot of code was taken from other projects (e.g. Dolphin, PPSSPP, Gekko, SkyEye). In general, when editing other people's code, follow the style of the module you're in (or better yet, fix the style if it drastically differs from our guide).
-* Line width is typically 100 characters, but this isn't strictly enforced. Please do not use 80-characters.
+* Line width is typically 100 characters. Please do not use 80-characters.
* Don't ever introduce new external dependencies into Core
* Don't use any platform specific code in Core
* Use namespaces often
-* Avoid the use of C-style casts and instead prefer C++-style `static_cast` and `reinterpret_cast`. Never use `const_cast` or `dynamic_cast` (we build with RTTI disabled). The only exception to this rule is for casting between two numeric types, where C-style casts are encouraged for brevity and readability.
+* Avoid the use of C-style casts and instead prefer C++-style `static_cast` and `reinterpret_cast`. Try to avoid using `dynamic_cast`. Never use `const_cast`. The only exception to this rule is for casting between two numeric types, where C-style casts are encouraged for brevity and readability.
### Naming Rules
* Functions: `PascalCase`
@@ -54,14 +52,14 @@ namespace Example {
// Namespace contents are not indented
// Declare globals at the top
-int g_foo = 0;
-char* g_some_pointer; // Pointer * and reference & stick to the type name
+int g_foo{}; // {} can be used to initialize types as 0, false, or nullptr
+char* g_some_pointer{}; // Pointer * and reference & stick to the type name, and make sure to initialize as nullptr!
/// A colorful enum.
enum SomeEnum {
- COLOR_RED, ///< The color of fire.
- COLOR_GREEN, ///< The color of grass.
- COLOR_BLUE, ///< Not actually the color of water.
+ ColorRed, ///< The color of fire.
+ ColorGreen, ///< The color of grass.
+ ColorBlue, ///< Not actually the color of water.
};
/**
@@ -69,17 +67,19 @@ enum SomeEnum {
* Note that the asterisks are indented by one space to align to the first line.
*/
struct Position {
- int x, y;
+ int x{}, y{}; // Always intitialize member variables!
};
// Use "typename" rather than "class" here
template <typename T>
void FooBar() {
- int some_array[] = {
+ const std::string some_string{ "prefer uniform initialization" };
+
+ int some_array[]{
5,
25,
7,
- 42
+ 42,
};
if (note == the_space_after_the_if) {
@@ -88,11 +88,8 @@ void FooBar() {
// Use a space after the // when commenting
}
- // Comment directly above code when possible
- if (some_condition) single_statement();
-
// Place a single space after the for loop semicolons, prefer pre-increment
- for (int i = 0; i != 25; ++i) {
+ for (int i{}; i != 25; ++i) {
// This is how we write loops
}
@@ -110,7 +107,7 @@ void FooBar() {
switch (var) {
// No indentation for case label
case 1: {
- int case_var = var + 3;
+ int case_var{ var + 3 };
DoSomething(case_var);
break;
}
diff --git a/README.md b/README.md
index 13919a37d..92e2d04a5 100644
--- a/README.md
+++ b/README.md
@@ -27,12 +27,11 @@ If you want to contribute please take a look at the [Contributor's Guide](CONTRI
### Support
-If you like, you can [donate by PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=K899FANUJ2ZXW) - any donation received will go towards things like:
+We happily accept monetary donations, or donated games and hardware. Please see our [donations page](https://citra-emu.org/page/donate) for more information on how you can contribute to Citra. Any donations received will go towards things like:
* 3DS consoles for developers to explore the hardware
* 3DS games for testing
* Any equipment required for homebrew
* Infrastructure setup
* Eventually 3D displays to get proper 3D output working
-* ... etc ...
-We also more than gladly accept used 3DS consoles, preferrably ones with firmware 4.5 or lower! If you would like to give yours away, don't hesitate to join our IRC channel #citra on [Freenode](http://webchat.freenode.net/?channels=citra) and talk to neobrain or bunnei. Mind you, IRC is slow-paced, so it might be a while until people reply. If you're in a hurry you can just leave contact details in the channel or via private message and we'll get back to you.
+We also more than gladly accept used 3DS consoles, preferably ones with firmware 4.5 or lower! If you would like to give yours away, don't hesitate to join our IRC channel #citra on [Freenode](http://webchat.freenode.net/?channels=citra) and talk to neobrain or bunnei. Mind you, IRC is slow-paced, so it might be a while until people reply. If you're in a hurry you can just leave contact details in the channel or via private message and we'll get back to you.
diff --git a/dist/citra.xml b/dist/citra.xml
index bcb9acd87..6d47c8760 100644
--- a/dist/citra.xml
+++ b/dist/citra.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-ctr-3dsx">
- <comment>3DS homebrew executable</comment>
- <comment xml:lang="fr">Exécutable 3DS homebrew</comment>
+ <comment>Nintendo 3DS homebrew executable</comment>
+ <comment xml:lang="fr">Exécutable non-officiel pour Nintendo 3DS </comment>
<acronym>3DSX</acronym>
<icon name="citra"/>
<glob pattern="*.3dsx"/>
@@ -10,8 +10,8 @@
</mime-type>
<mime-type type="application/x-ctr-cci">
- <comment>3DS cartridge image</comment>
- <comment xml:lang="fr">Image de cartouche 3DS</comment>
+ <comment>Nintendo 3DS cartridge image</comment>
+ <comment xml:lang="fr">Image de cartouche Nintendo 3DS</comment>
<acronym>CCI</acronym>
<expanded-acronym>CTR Cart Image</expanded-acronym>
<icon name="citra"/>
@@ -21,8 +21,8 @@
</mime-type>
<mime-type type="application/x-ctr-cxi">
- <comment>3DS executable</comment>
- <comment xml:lang="fr">Exécutable 3DS</comment>
+ <comment>Nintendo 3DS executable</comment>
+ <comment xml:lang="fr">Exécutable Nintendo 3DS</comment>
<acronym>CXI</acronym>
<expanded-acronym>CTR eXecutable Image</expanded-acronym>
<icon name="citra"/>
@@ -31,8 +31,8 @@
</mime-type>
<mime-type type="application/x-ctr-cia">
- <comment>3DS importable archive</comment>
- <comment xml:lang="fr">Archive importable 3DS</comment>
+ <comment>Nintendo 3DS importable archive</comment>
+ <comment xml:lang="fr">Archive installable Nintendo 3DS</comment>
<acronym>CIA</acronym>
<expanded-acronym>CTR Importable Archive</expanded-acronym>
<icon name="citra"/>
@@ -40,8 +40,8 @@
</mime-type>
<mime-type type="application/x-ctr-smdh">
- <comment>3DS icon</comment>
- <comment xml:lang="fr">Icône 3DS</comment>
+ <comment>Nintendo 3DS icon and metadata</comment>
+ <comment xml:lang="fr">Icône et métadonnées Nintendo 3DS</comment>
<acronym>SMDH</acronym>
<expanded-acronym>System Menu Data Header</expanded-acronym>
<glob pattern="*.smdh"/>
@@ -49,8 +49,8 @@
</mime-type>
<mime-type type="application/x-ctr-cbmd">
- <comment>3DS banner</comment>
- <comment xml:lang="fr">Bannière 3DS</comment>
+ <comment>Nintendo 3DS banner</comment>
+ <comment xml:lang="fr">Bannière Nintendo 3DS</comment>
<acronym>CBMD</acronym>
<expanded-acronym>CTR Banner Model Data</expanded-acronym>
<glob pattern="*.cbmd"/>
diff --git a/externals/microprofile/microprofile.h b/externals/microprofile/microprofile.h
index d1ae0c1c2..f45c9ba82 100644
--- a/externals/microprofile/microprofile.h
+++ b/externals/microprofile/microprofile.h
@@ -206,7 +206,7 @@ int64_t MicroProfileGetTick();
#define MP_GETCURRENTTHREADID() GetCurrentThreadId()
typedef uint32_t ThreadIdType;
-#elif defined(__linux__)
+#elif !defined(_WIN32)
#include <unistd.h>
#include <time.h>
inline int64_t MicroProfileTicksPerSecondCpu()
@@ -510,9 +510,9 @@ typedef int MpSocket;
#endif
-#if defined(__APPLE__) || defined(__linux__)
+#ifndef _WIN32
typedef pthread_t MicroProfileThread;
-#elif defined(_WIN32)
+#elif defined(_MSC_VER)
typedef HANDLE MicroProfileThread;
#else
typedef std::thread* MicroProfileThread;
@@ -907,7 +907,7 @@ int64_t MicroProfileGetTick()
typedef void* (*MicroProfileThreadFunc)(void*);
-#if defined(__APPLE__) || defined(__linux__)
+#ifndef _WIN32
typedef pthread_t MicroProfileThread;
void MicroProfileThreadStart(MicroProfileThread* pThread, MicroProfileThreadFunc Func)
{
@@ -921,7 +921,7 @@ void MicroProfileThreadJoin(MicroProfileThread* pThread)
int r = pthread_join(*pThread, 0);
MP_ASSERT(r == 0);
}
-#elif defined(_WIN32)
+#elif defined(_MSC_VER)
typedef HANDLE MicroProfileThread;
DWORD _stdcall ThreadTrampoline(void* pFunc)
{
@@ -959,7 +959,7 @@ inline void MicroProfileThreadJoin(MicroProfileThread* pThread)
#define MP_INVALID_SOCKET(f) (f == INVALID_SOCKET)
#endif
-#if defined(__APPLE__)
+#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
diff --git a/externals/microprofile/microprofileui.h b/externals/microprofile/microprofileui.h
index 45bec8af6..66a73abc5 100644
--- a/externals/microprofile/microprofileui.h
+++ b/externals/microprofile/microprofileui.h
@@ -172,6 +172,7 @@ MICROPROFILEUI_API void MicroProfileCustomGroupAddTimer(const char* pCustomName,
#ifdef _WIN32
#define snprintf _snprintf
#endif
+#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
diff --git a/hooks/pre-commit b/hooks/pre-commit
index 6dd281c4a..04fdaf8ec 100755
--- a/hooks/pre-commit
+++ b/hooks/pre-commit
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
# Enforce citra's whitespace policy
git config --local core.whitespace tab-in-indent,trailing-space
@@ -10,7 +10,7 @@ if ! git diff --cached --check -- $paths_to_check ; then
cat<<END
Error: This commit would contain trailing spaces or tabs, which is against this repo's policy.
-Please correct those issues before commiting. (Use 'git diff --check' for more details)
+Please correct those issues before committing. (Use 'git diff --check' for more details)
If you know what you are doing, you can try 'git commit --no-verify' to bypass the check
END
exit 1
@@ -32,7 +32,7 @@ for f in $(git diff --name-only --diff-filter=ACMRTUXB --cached); do
if ! echo "$f" | egrep -q "^src/"; then
continue
fi
- d=$(diff -u "$f" <(clang-format "$f"))
+ d=$(clang-format "$f" | diff -u "$f" -)
if ! [ -z "$d" ]; then
echo "!!! $f not compliant to coding style, here is the fix:"
echo "$d"
@@ -40,4 +40,4 @@ for f in $(git diff --name-only --diff-filter=ACMRTUXB --cached); do
fi
done
-exit "$fail"
+exit "${fail-0}"
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 =