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