diff options
Diffstat (limited to 'src')
182 files changed, 2282 insertions, 1111 deletions
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp index 49260de7c..ba6acf28e 100644 --- a/src/audio_core/audio_core.cpp +++ b/src/audio_core/audio_core.cpp @@ -23,9 +23,9 @@ static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles static void AudioTickCallback(u64 /*userdata*/, int cycles_late) { if (DSP::HLE::Tick()) { // TODO(merry): Signal all the other interrupts as appropriate. - DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Audio); + Service::DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Audio); // HACK(merry): Added to prevent regressions. Will remove soon. - DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Binary); + Service::DSP_DSP::SignalPipeInterrupt(DSP::HLE::DspPipe::Binary); } // Reschedule recurrent event @@ -56,22 +56,17 @@ void AddAddressSpace(Kernel::VMManager& address_space) { } void SelectSink(std::string sink_id) { - if (sink_id == "auto") { - // Auto-select. - // g_sink_details is ordered in terms of desirability, with the best choice at the front. - const auto& sink_detail = g_sink_details.front(); - DSP::HLE::SetSink(sink_detail.factory()); - return; - } - auto iter = std::find_if(g_sink_details.begin(), g_sink_details.end(), [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); - if (iter == g_sink_details.end()) { - LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id"); - DSP::HLE::SetSink(std::make_unique<NullSink>()); - return; + if (sink_id == "auto" || iter == g_sink_details.end()) { + if (sink_id != "auto") { + LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id %s", sink_id.c_str()); + } + // Auto-select. + // g_sink_details is ordered in terms of desirability, with the best choice at the front. + iter = g_sink_details.begin(); } DSP::HLE::SetSink(iter->factory()); diff --git a/src/audio_core/hle/pipe.cpp b/src/audio_core/hle/pipe.cpp index bc69acbc2..24074a514 100644 --- a/src/audio_core/hle/pipe.cpp +++ b/src/audio_core/hle/pipe.cpp @@ -104,7 +104,7 @@ static void AudioPipeWriteStructAddresses() { WriteU16(DspPipe::Audio, addr); } // Signal that we have data on this pipe. - DSP_DSP::SignalPipeInterrupt(DspPipe::Audio); + Service::DSP_DSP::SignalPipeInterrupt(DspPipe::Audio); } void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) { diff --git a/src/audio_core/time_stretch.h b/src/audio_core/time_stretch.h index fa81718ed..e3e4dc353 100644 --- a/src/audio_core/time_stretch.h +++ b/src/audio_core/time_stretch.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include <cstddef> #include <memory> #include <vector> diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index f9387e61c..3114a71db 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -18,7 +18,7 @@ #endif #ifdef _WIN32 -#include <Windows.h> +#include <windows.h> #endif #include "citra/config.h" diff --git a/src/citra/citra.rc b/src/citra/citra.rc index b0edb2e6b..fea603004 100644 --- a/src/citra/citra.rc +++ b/src/citra/citra.rc @@ -5,5 +5,5 @@ // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -GLFW_ICON ICON "..\\..\\dist\\citra.ico" +CITRA_ICON ICON "../../dist/citra.ico" diff --git a/src/citra/config.cpp b/src/citra/config.cpp index fe74fcd72..29462c982 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -66,6 +66,8 @@ void Config::ReadValues() { Settings::values.use_scaled_resolution = sdl2_config->GetBoolean("Renderer", "use_scaled_resolution", false); Settings::values.use_vsync = sdl2_config->GetBoolean("Renderer", "use_vsync", false); + Settings::values.toggle_framelimit = + sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true); Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 1.0); Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 1.0); diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index b98dc4d83..001b18ac2 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -64,6 +64,10 @@ use_vsync = # 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen layout_option = +#Whether to toggle frame limiter on or off. +# 0: Off , 1 (default): On +toggle_framelimit = + # 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 diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 384875450..a9dacd5f1 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -65,7 +65,6 @@ set(HEADERS hotkeys.h main.h ui_settings.h - version.h ) set(UIS diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index 67228b94f..af52f369b 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include <atomic> #include <condition_variable> #include <mutex> @@ -21,7 +23,7 @@ class EmuThread : public QThread { Q_OBJECT public: - EmuThread(GRenderWindow* render_window); + explicit EmuThread(GRenderWindow* render_window); /** * Start emulation (on new thread) diff --git a/src/citra_qt/citra-qt.rc b/src/citra_qt/citra-qt.rc index 3c7239853..fea603004 100644 --- a/src/citra_qt/citra-qt.rc +++ b/src/citra_qt/citra-qt.rc @@ -5,5 +5,5 @@ // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_ICON1 ICON "..\\..\\dist\\citra.ico" +CITRA_ICON ICON "../../dist/citra.ico" diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp index 3cdfe6443..06a4e9d25 100644 --- a/src/citra_qt/config.cpp +++ b/src/citra_qt/config.cpp @@ -47,6 +47,7 @@ void Config::ReadValues() { Settings::values.use_scaled_resolution = qt_config->value("use_scaled_resolution", false).toBool(); Settings::values.use_vsync = qt_config->value("use_vsync", false).toBool(); + Settings::values.toggle_framelimit = qt_config->value("toggle_framelimit", true).toBool(); Settings::values.bg_red = qt_config->value("bg_red", 1.0).toFloat(); Settings::values.bg_green = qt_config->value("bg_green", 1.0).toFloat(); @@ -152,6 +153,7 @@ void Config::SaveValues() { qt_config->setValue("use_shader_jit", Settings::values.use_shader_jit); qt_config->setValue("use_scaled_resolution", Settings::values.use_scaled_resolution); qt_config->setValue("use_vsync", Settings::values.use_vsync); + qt_config->setValue("toggle_framelimit", Settings::values.toggle_framelimit); // Cast to double because Qt's written float values are not human-readable qt_config->setValue("bg_red", (double)Settings::values.bg_red); diff --git a/src/citra_qt/configure_graphics.cpp b/src/citra_qt/configure_graphics.cpp index 29834e11b..36f10c8d7 100644 --- a/src/citra_qt/configure_graphics.cpp +++ b/src/citra_qt/configure_graphics.cpp @@ -23,6 +23,7 @@ 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->toggle_framelimit->setChecked(Settings::values.toggle_framelimit); ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option)); ui->swap_screen->setChecked(Settings::values.swap_screen); } @@ -32,6 +33,7 @@ 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.toggle_framelimit = ui->toggle_framelimit->isChecked(); Settings::values.layout_option = static_cast<Settings::LayoutOption>(ui->layout_combobox->currentIndex()); Settings::values.swap_screen = ui->swap_screen->isChecked(); diff --git a/src/citra_qt/configure_graphics.ui b/src/citra_qt/configure_graphics.ui index af16a4292..964aa0bbd 100644 --- a/src/citra_qt/configure_graphics.ui +++ b/src/citra_qt/configure_graphics.ui @@ -50,6 +50,13 @@ </property> </widget> </item> + <item> + <widget class="QCheckBox" name="toggle_framelimit"> + <property name="text"> + <string>Limit framerate</string> + </property> + </widget> + </item> </layout> </widget> </item> diff --git a/src/citra_qt/configure_input.cpp b/src/citra_qt/configure_input.cpp index d321db71f..3e6803b8a 100644 --- a/src/citra_qt/configure_input.cpp +++ b/src/citra_qt/configure_input.cpp @@ -5,15 +5,33 @@ #include <memory> #include <utility> #include <QTimer> +#include "citra_qt/config.h" #include "citra_qt/configure_input.h" +static QString getKeyName(Qt::Key key_code) { + switch (key_code) { + case Qt::Key_Shift: + return QObject::tr("Shift"); + case Qt::Key_Control: + return QObject::tr("Ctrl"); + case Qt::Key_Alt: + return QObject::tr("Alt"); + case Qt::Key_Meta: + case -1: + return ""; + default: + return QKeySequence(key_code).toString(); + } +} + ConfigureInput::ConfigureInput(QWidget* parent) - : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) { + : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()), + timer(std::make_unique<QTimer>()) { ui->setupUi(this); + setFocusPolicy(Qt::ClickFocus); - // Initialize mapping of input enum to UI button. - input_mapping = { + button_map = { {Settings::NativeInput::Values::A, ui->buttonA}, {Settings::NativeInput::Values::B, ui->buttonB}, {Settings::NativeInput::Values::X, ui->buttonX}, @@ -40,114 +58,89 @@ ConfigureInput::ConfigureInput(QWidget* parent) {Settings::NativeInput::Values::CIRCLE_MODIFIER, ui->buttonCircleMod}, }; - // Attach handle click method to each button click. - for (const auto& entry : input_mapping) { - connect(entry.second, SIGNAL(released()), this, SLOT(handleClick())); + for (const auto& entry : button_map) { + const Settings::NativeInput::Values input_id = entry.first; + connect(entry.second, &QPushButton::released, + [this, input_id]() { handleClick(input_id); }); } - connect(ui->buttonRestoreDefaults, SIGNAL(released()), this, SLOT(restoreDefaults())); - setFocusPolicy(Qt::ClickFocus); - timer = new QTimer(this); + + connect(ui->buttonRestoreDefaults, &QPushButton::released, [this]() { restoreDefaults(); }); + timer->setSingleShot(true); - connect(timer, &QTimer::timeout, this, [&]() { - key_pressed = Qt::Key_Escape; - setKey(); + connect(timer.get(), &QTimer::timeout, [this]() { + releaseKeyboard(); + releaseMouse(); + current_input_id = boost::none; + updateButtonLabels(); }); - this->setConfiguration(); -} -void ConfigureInput::handleClick() { - QPushButton* sender = qobject_cast<QPushButton*>(QObject::sender()); - previous_mapping = sender->text(); - sender->setText(tr("[waiting]")); - sender->setFocus(); - grabKeyboard(); - grabMouse(); - changing_button = sender; - timer->start(5000); // Cancel after 5 seconds + this->loadConfiguration(); } void ConfigureInput::applyConfiguration() { - for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { - int value = getKeyValue(input_mapping[Settings::NativeInput::Values(i)]->text()); - Settings::values.input_mappings[Settings::NativeInput::All[i]] = value; + for (const auto& input_id : Settings::NativeInput::All) { + const size_t index = static_cast<size_t>(input_id); + Settings::values.input_mappings[index] = static_cast<int>(key_map[input_id]); } Settings::Apply(); } -void ConfigureInput::setConfiguration() { - for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { - QString keyValue = getKeyName(Settings::values.input_mappings[i]); - input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue); +void ConfigureInput::loadConfiguration() { + for (const auto& input_id : Settings::NativeInput::All) { + const size_t index = static_cast<size_t>(input_id); + key_map[input_id] = static_cast<Qt::Key>(Settings::values.input_mappings[index]); } + updateButtonLabels(); } -void ConfigureInput::keyPressEvent(QKeyEvent* event) { - if (!changing_button) - return; - if (!event || event->key() == Qt::Key_unknown) - return; - key_pressed = event->key(); - timer->stop(); - setKey(); +void ConfigureInput::restoreDefaults() { + for (const auto& input_id : Settings::NativeInput::All) { + const size_t index = static_cast<size_t>(input_id); + key_map[input_id] = static_cast<Qt::Key>(Config::defaults[index].toInt()); + } + updateButtonLabels(); + applyConfiguration(); } -void ConfigureInput::setKey() { - const QString key_value = getKeyName(key_pressed); - if (key_pressed == Qt::Key_Escape) - changing_button->setText(previous_mapping); - else - changing_button->setText(key_value); - removeDuplicates(key_value); - key_pressed = Qt::Key_unknown; - releaseKeyboard(); - releaseMouse(); - changing_button = nullptr; - previous_mapping = nullptr; +void ConfigureInput::updateButtonLabels() { + for (const auto& input_id : Settings::NativeInput::All) { + button_map[input_id]->setText(getKeyName(key_map[input_id])); + } } -QString ConfigureInput::getKeyName(int key_code) const { - if (key_code == Qt::Key_Shift) - return tr("Shift"); - if (key_code == Qt::Key_Control) - return tr("Ctrl"); - if (key_code == Qt::Key_Alt) - return tr("Alt"); - if (key_code == Qt::Key_Meta) - return ""; - if (key_code == -1) - return ""; +void ConfigureInput::handleClick(Settings::NativeInput::Values input_id) { + QPushButton* button = button_map[input_id]; + button->setText(tr("[press key]")); + button->setFocus(); - return QKeySequence(key_code).toString(); -} + current_input_id = input_id; -Qt::Key ConfigureInput::getKeyValue(const QString& text) const { - if (text == "Shift") - return Qt::Key_Shift; - if (text == "Ctrl") - return Qt::Key_Control; - if (text == "Alt") - return Qt::Key_Alt; - if (text == "Meta") - return Qt::Key_unknown; - if (text == "") - return Qt::Key_unknown; - - return Qt::Key(QKeySequence(text)[0]); + grabKeyboard(); + grabMouse(); + timer->start(5000); // Cancel after 5 seconds } -void ConfigureInput::removeDuplicates(const QString& newValue) { - for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { - if (changing_button != input_mapping[Settings::NativeInput::Values(i)]) { - const QString oldValue = input_mapping[Settings::NativeInput::Values(i)]->text(); - if (newValue == oldValue) - input_mapping[Settings::NativeInput::Values(i)]->setText(""); - } - } +void ConfigureInput::keyPressEvent(QKeyEvent* event) { + releaseKeyboard(); + releaseMouse(); + + if (!current_input_id || !event) + return; + + if (event->key() != Qt::Key_Escape) + setInput(*current_input_id, static_cast<Qt::Key>(event->key())); + + updateButtonLabels(); + current_input_id = boost::none; + timer->stop(); } -void ConfigureInput::restoreDefaults() { - for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { - const QString keyValue = getKeyName(Config::defaults[i].toInt()); - input_mapping[Settings::NativeInput::Values(i)]->setText(keyValue); +void ConfigureInput::setInput(Settings::NativeInput::Values input_id, Qt::Key key_pressed) { + // Remove duplicates + for (auto& pair : key_map) { + if (pair.second == key_pressed) + pair.second = Qt::Key_unknown; } + + key_map[input_id] = key_pressed; } diff --git a/src/citra_qt/configure_input.h b/src/citra_qt/configure_input.h index 5183b904d..bc343db83 100644 --- a/src/citra_qt/configure_input.h +++ b/src/citra_qt/configure_input.h @@ -7,7 +7,7 @@ #include <memory> #include <QKeyEvent> #include <QWidget> -#include "citra_qt/config.h" +#include <boost/optional.hpp> #include "core/settings.h" #include "ui_configure_input.h" @@ -30,35 +30,28 @@ public: private: std::unique_ptr<Ui::ConfigureInput> ui; - std::map<Settings::NativeInput::Values, QPushButton*> input_mapping; - int key_pressed; - QPushButton* changing_button = nullptr; ///< button currently waiting for key press. - QString previous_mapping; - QTimer* timer; - /// Load configuration settings into button text - void setConfiguration(); + /// This input is currently awaiting configuration. + /// (i.e.: its corresponding QPushButton has been pressed.) + boost::optional<Settings::NativeInput::Values> current_input_id; + std::unique_ptr<QTimer> timer; - /// Check all inputs for duplicate keys. Clears out any other button with the same value as this - /// button's new value. - void removeDuplicates(const QString& newValue); - - /// Handle key press event for input tab when a button is 'waiting'. - void keyPressEvent(QKeyEvent* event) override; - - /// Convert key ASCII value to its' letter/name - QString getKeyName(int key_code) const; - - /// Convert letter/name of key to its ASCII value. - Qt::Key getKeyValue(const QString& text) const; - - /// Set button text to name of key pressed. - void setKey(); - -private slots: - /// Event handler for all button released() event. - void handleClick(); + /// Each input is represented by a QPushButton. + std::map<Settings::NativeInput::Values, QPushButton*> button_map; + /// Each input is configured to respond to the press of a Qt::Key. + std::map<Settings::NativeInput::Values, Qt::Key> key_map; + /// Load configuration settings. + void loadConfiguration(); /// Restore all buttons to their default values. void restoreDefaults(); + /// Update UI to reflect current configuration. + void updateButtonLabels(); + + /// Called when the button corresponding to input_id was pressed. + void handleClick(Settings::NativeInput::Values input_id); + /// Handle key press events. + void keyPressEvent(QKeyEvent* event) override; + /// Configure input input_id to respond to key key_pressed. + void setInput(Settings::NativeInput::Values input_id, Qt::Key key_pressed); }; diff --git a/src/citra_qt/debugger/callstack.h b/src/citra_qt/debugger/callstack.h index 765757986..f04ab9c7e 100644 --- a/src/citra_qt/debugger/callstack.h +++ b/src/citra_qt/debugger/callstack.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include <QDockWidget> #include "ui_callstack.h" @@ -11,7 +13,7 @@ class CallstackWidget : public QDockWidget { Q_OBJECT public: - CallstackWidget(QWidget* parent = nullptr); + explicit CallstackWidget(QWidget* parent = nullptr); public slots: void OnDebugModeEntered(); diff --git a/src/citra_qt/debugger/disassembler.h b/src/citra_qt/debugger/disassembler.h index 2ca6c2bd4..895f6ac89 100644 --- a/src/citra_qt/debugger/disassembler.h +++ b/src/citra_qt/debugger/disassembler.h @@ -17,7 +17,7 @@ class DisassemblerModel : public QAbstractListModel { Q_OBJECT public: - DisassemblerModel(QObject* parent); + explicit DisassemblerModel(QObject* parent); int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; diff --git a/src/citra_qt/debugger/graphics.cpp b/src/citra_qt/debugger/graphics.cpp index ef6712bfa..ef337827a 100644 --- a/src/citra_qt/debugger/graphics.cpp +++ b/src/citra_qt/debugger/graphics.cpp @@ -22,15 +22,15 @@ QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) con return QVariant(); int command_index = index.row(); - const GSP_GPU::Command& command = GetDebugger()->ReadGXCommandHistory(command_index); + const Service::GSP::Command& command = GetDebugger()->ReadGXCommandHistory(command_index); if (role == Qt::DisplayRole) { - std::map<GSP_GPU::CommandId, const char*> command_names = { - {GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA"}, - {GSP_GPU::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST"}, - {GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL"}, - {GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER"}, - {GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY"}, - {GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH"}, + std::map<Service::GSP::CommandId, const char*> command_names = { + {Service::GSP::CommandId::REQUEST_DMA, "REQUEST_DMA"}, + {Service::GSP::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST"}, + {Service::GSP::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL"}, + {Service::GSP::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER"}, + {Service::GSP::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY"}, + {Service::GSP::CommandId::CACHE_FLUSH, "CACHE_FLUSH"}, }; const u32* command_data = reinterpret_cast<const u32*>(&command); QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9") diff --git a/src/citra_qt/debugger/graphics.h b/src/citra_qt/debugger/graphics.h index bedf3e596..8837fb792 100644 --- a/src/citra_qt/debugger/graphics.h +++ b/src/citra_qt/debugger/graphics.h @@ -13,7 +13,7 @@ class GPUCommandStreamItemModel : public QAbstractListModel, Q_OBJECT public: - GPUCommandStreamItemModel(QObject* parent); + explicit GPUCommandStreamItemModel(QObject* parent); int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; diff --git a/src/citra_qt/debugger/graphics_breakpoints.h b/src/citra_qt/debugger/graphics_breakpoints.h index 5fc40c916..bec72a2db 100644 --- a/src/citra_qt/debugger/graphics_breakpoints.h +++ b/src/citra_qt/debugger/graphics_breakpoints.h @@ -20,8 +20,8 @@ class GraphicsBreakPointsWidget : public QDockWidget, Pica::DebugContext::BreakP using Event = Pica::DebugContext::Event; public: - GraphicsBreakPointsWidget(std::shared_ptr<Pica::DebugContext> debug_context, - QWidget* parent = nullptr); + explicit GraphicsBreakPointsWidget(std::shared_ptr<Pica::DebugContext> debug_context, + QWidget* parent = nullptr); void OnPicaBreakPointHit(Pica::DebugContext::Event event, void* data) override; void OnPicaResume() override; diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index 8a784d108..98b619dea 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp @@ -21,7 +21,8 @@ #include "video_core/pica.h" #include "video_core/pica_state.h" -QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { +namespace { +QImage LoadTexture(const u8* src, const Pica::DebugUtils::TextureInfo& info) { QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); for (int y = 0; y < info.height; ++y) { for (int x = 0; x < info.width; ++x) { @@ -35,7 +36,8 @@ QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { class TextureInfoWidget : public QWidget { public: - TextureInfoWidget(u8* src, const Pica::DebugUtils::TextureInfo& info, QWidget* parent = nullptr) + TextureInfoWidget(const u8* src, const Pica::DebugUtils::TextureInfo& info, + QWidget* parent = nullptr) : QWidget(parent) { QLabel* image_widget = new QLabel; QPixmap image_pixmap = QPixmap::fromImage(LoadTexture(src, info)); @@ -47,6 +49,7 @@ public: setLayout(layout); } }; +} // Anonymous namespace GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(parent) {} @@ -65,7 +68,6 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const { const auto& write = pica_trace.writes[index.row()]; if (role == Qt::DisplayRole) { - QString content; switch (index.column()) { case 0: return QString::fromLatin1(Pica::Regs::GetCommandName(write.cmd_id).c_str()); @@ -122,19 +124,21 @@ void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || COMMAND_IN_RANGE(command_id, texture2)) { - unsigned index; + unsigned texture_index; if (COMMAND_IN_RANGE(command_id, texture0)) { - index = 0; + texture_index = 0; } else if (COMMAND_IN_RANGE(command_id, texture1)) { - index = 1; + texture_index = 1; } else if (COMMAND_IN_RANGE(command_id, texture2)) { - index = 2; + texture_index = 2; } else { UNREACHABLE_MSG("Unknown texture command"); } - auto config = Pica::g_state.regs.GetTextures()[index].config; - auto format = Pica::g_state.regs.GetTextures()[index].format; - auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); + + const auto texture = Pica::g_state.regs.GetTextures()[texture_index]; + const auto config = texture.config; + const auto format = texture.format; + const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); // TODO: Open a surface debugger } @@ -148,19 +152,21 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || COMMAND_IN_RANGE(command_id, texture2)) { - unsigned index; + unsigned texture_index; if (COMMAND_IN_RANGE(command_id, texture0)) { - index = 0; + texture_index = 0; } else if (COMMAND_IN_RANGE(command_id, texture1)) { - index = 1; + texture_index = 1; } else { - index = 2; + texture_index = 2; } - auto config = Pica::g_state.regs.GetTextures()[index].config; - auto format = Pica::g_state.regs.GetTextures()[index].format; - auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); - u8* src = Memory::GetPhysicalPointer(config.GetPhysicalAddress()); + const auto texture = Pica::g_state.regs.GetTextures()[texture_index]; + const auto config = texture.config; + const auto format = texture.format; + + const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config, format); + const u8* src = Memory::GetPhysicalPointer(config.GetPhysicalAddress()); new_info_widget = new TextureInfoWidget(src, info); } if (command_info_widget) { diff --git a/src/citra_qt/debugger/graphics_cmdlists.h b/src/citra_qt/debugger/graphics_cmdlists.h index fa2b9122b..8f40b94c5 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.h +++ b/src/citra_qt/debugger/graphics_cmdlists.h @@ -20,7 +20,7 @@ public: CommandIdRole = Qt::UserRole, }; - GPUCommandListModel(QObject* parent); + explicit GPUCommandListModel(QObject* parent); int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; @@ -39,7 +39,7 @@ class GPUCommandListWidget : public QDockWidget { Q_OBJECT public: - GPUCommandListWidget(QWidget* parent = nullptr); + explicit GPUCommandListWidget(QWidget* parent = nullptr); public slots: void OnToggleTracing(); diff --git a/src/citra_qt/debugger/graphics_surface.h b/src/citra_qt/debugger/graphics_surface.h index 21e6b5b8b..19ffb55fb 100644 --- a/src/citra_qt/debugger/graphics_surface.h +++ b/src/citra_qt/debugger/graphics_surface.h @@ -18,7 +18,8 @@ class SurfacePicture : public QLabel { Q_OBJECT public: - SurfacePicture(QWidget* parent = 0, GraphicsSurfaceWidget* surface_widget = nullptr); + explicit SurfacePicture(QWidget* parent = nullptr, + GraphicsSurfaceWidget* surface_widget = nullptr); ~SurfacePicture(); protected slots: @@ -71,8 +72,8 @@ class GraphicsSurfaceWidget : public BreakPointObserverDock { static unsigned int NibblesPerPixel(Format format); public: - GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, - QWidget* parent = nullptr); + explicit GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, + QWidget* parent = nullptr); void Pick(int x, int y); public slots: diff --git a/src/citra_qt/debugger/graphics_tracing.h b/src/citra_qt/debugger/graphics_tracing.h index e04a3dac3..20acc91e7 100644 --- a/src/citra_qt/debugger/graphics_tracing.h +++ b/src/citra_qt/debugger/graphics_tracing.h @@ -12,8 +12,8 @@ class GraphicsTracingWidget : public BreakPointObserverDock { Q_OBJECT public: - GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, - QWidget* parent = nullptr); + explicit GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, + QWidget* parent = nullptr); private slots: void StartRecording(); diff --git a/src/citra_qt/debugger/graphics_vertex_shader.h b/src/citra_qt/debugger/graphics_vertex_shader.h index ec42f24bb..6e62fbb9b 100644 --- a/src/citra_qt/debugger/graphics_vertex_shader.h +++ b/src/citra_qt/debugger/graphics_vertex_shader.h @@ -19,7 +19,7 @@ class GraphicsVertexShaderModel : public QAbstractTableModel { Q_OBJECT public: - GraphicsVertexShaderModel(GraphicsVertexShaderWidget* parent); + explicit GraphicsVertexShaderModel(GraphicsVertexShaderWidget* parent); int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h index d8c6487aa..c8912fd5a 100644 --- a/src/citra_qt/debugger/profiler.h +++ b/src/citra_qt/debugger/profiler.h @@ -15,7 +15,7 @@ class ProfilerModel : public QAbstractItemModel { Q_OBJECT public: - ProfilerModel(QObject* parent); + explicit ProfilerModel(QObject* parent); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; @@ -37,7 +37,7 @@ class ProfilerWidget : public QDockWidget { Q_OBJECT public: - ProfilerWidget(QWidget* parent = nullptr); + explicit ProfilerWidget(QWidget* parent = nullptr); private slots: void setProfilingInfoUpdateEnabled(bool enable); @@ -53,7 +53,7 @@ class MicroProfileDialog : public QWidget { Q_OBJECT public: - MicroProfileDialog(QWidget* parent = nullptr); + explicit MicroProfileDialog(QWidget* parent = nullptr); /// Returns a QAction that can be used to toggle visibility of this dialog. QAction* toggleViewAction(); diff --git a/src/citra_qt/debugger/ramview.h b/src/citra_qt/debugger/ramview.h index 8043c59e8..d01cea93b 100644 --- a/src/citra_qt/debugger/ramview.h +++ b/src/citra_qt/debugger/ramview.h @@ -2,13 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include "qhexedit.h" class GRamView : public QHexEdit { Q_OBJECT public: - GRamView(QWidget* parent = nullptr); + explicit GRamView(QWidget* parent = nullptr); public slots: void OnCPUStepped(); diff --git a/src/citra_qt/debugger/registers.h b/src/citra_qt/debugger/registers.h index 54c9a8155..55bda5b59 100644 --- a/src/citra_qt/debugger/registers.h +++ b/src/citra_qt/debugger/registers.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include <QDockWidget> #include "ui_registers.h" @@ -13,7 +15,7 @@ class RegistersWidget : public QDockWidget { Q_OBJECT public: - RegistersWidget(QWidget* parent = nullptr); + explicit RegistersWidget(QWidget* parent = nullptr); public slots: void OnDebugModeEntered(); diff --git a/src/citra_qt/debugger/wait_tree.h b/src/citra_qt/debugger/wait_tree.h index 5d1d964d1..ee9708fc1 100644 --- a/src/citra_qt/debugger/wait_tree.h +++ b/src/citra_qt/debugger/wait_tree.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + #include <boost/container/flat_set.hpp> #include <QAbstractItemModel> @@ -49,7 +51,7 @@ private: class WaitTreeText : public WaitTreeItem { Q_OBJECT public: - WaitTreeText(const QString& text); + explicit WaitTreeText(const QString& text); QString GetText() const override; private: @@ -65,7 +67,7 @@ public: class WaitTreeWaitObject : public WaitTreeExpandableItem { Q_OBJECT public: - WaitTreeWaitObject(const Kernel::WaitObject& object); + explicit WaitTreeWaitObject(const Kernel::WaitObject& object); static std::unique_ptr<WaitTreeWaitObject> make(const Kernel::WaitObject& object); QString GetText() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; @@ -92,7 +94,7 @@ private: class WaitTreeThread : public WaitTreeWaitObject { Q_OBJECT public: - WaitTreeThread(const Kernel::Thread& thread); + explicit WaitTreeThread(const Kernel::Thread& thread); QString GetText() const override; QColor GetColor() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; @@ -101,35 +103,37 @@ public: class WaitTreeEvent : public WaitTreeWaitObject { Q_OBJECT public: - WaitTreeEvent(const Kernel::Event& object); + explicit WaitTreeEvent(const Kernel::Event& object); std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; class WaitTreeMutex : public WaitTreeWaitObject { Q_OBJECT public: - WaitTreeMutex(const Kernel::Mutex& object); + explicit WaitTreeMutex(const Kernel::Mutex& object); std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; class WaitTreeSemaphore : public WaitTreeWaitObject { Q_OBJECT public: - WaitTreeSemaphore(const Kernel::Semaphore& object); + explicit WaitTreeSemaphore(const Kernel::Semaphore& object); std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; class WaitTreeTimer : public WaitTreeWaitObject { Q_OBJECT public: - WaitTreeTimer(const Kernel::Timer& object); + explicit WaitTreeTimer(const Kernel::Timer& object); std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; }; class WaitTreeMutexList : public WaitTreeExpandableItem { Q_OBJECT public: - WaitTreeMutexList(const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list); + explicit WaitTreeMutexList( + const boost::container::flat_set<Kernel::SharedPtr<Kernel::Mutex>>& list); + QString GetText() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; @@ -140,7 +144,7 @@ private: class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: - WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list); + explicit WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list); QString GetText() const override; std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override; @@ -152,7 +156,7 @@ class WaitTreeModel : public QAbstractItemModel { Q_OBJECT public: - WaitTreeModel(QObject* parent = nullptr); + explicit WaitTreeModel(QObject* parent = nullptr); QVariant data(const QModelIndex& index, int role) const override; QModelIndex index(int row, int column, const QModelIndex& parent) const override; @@ -171,7 +175,7 @@ class WaitTreeWidget : public QDockWidget { Q_OBJECT public: - WaitTreeWidget(QWidget* parent = nullptr); + explicit WaitTreeWidget(QWidget* parent = nullptr); public slots: void OnDebugModeEntered(); diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 07bc35308..e536628dd 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -13,7 +13,7 @@ #include "game_list_p.h" #include "ui_settings.h" -GameList::GameList(QWidget* parent) { +GameList::GameList(QWidget* parent) : QWidget{parent} { QVBoxLayout* layout = new QVBoxLayout; tree_view = new QTreeView; @@ -34,8 +34,7 @@ GameList::GameList(QWidget* parent) { item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type"); item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size"); - connect(tree_view, SIGNAL(activated(const QModelIndex&)), this, - SLOT(ValidateEntry(const QModelIndex&))); + connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry); // We must register all custom types with the Qt Automoc system so that we are able to use it // with @@ -50,7 +49,7 @@ GameList::~GameList() { emit ShouldCancelWorker(); } -void GameList::AddEntry(QList<QStandardItem*> entry_items) { +void GameList::AddEntry(const QList<QStandardItem*>& entry_items) { item_model->invisibleRootItem()->appendRow(entry_items); } @@ -86,12 +85,13 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { emit ShouldCancelWorker(); GameListWorker* worker = new GameListWorker(dir_path, deep_scan); - connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this, - SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection); - connect(worker, SIGNAL(Finished()), this, SLOT(DonePopulating()), Qt::QueuedConnection); + connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); + connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating, + Qt::QueuedConnection); // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel // without delay. - connect(this, SIGNAL(ShouldCancelWorker()), worker, SLOT(Cancel()), Qt::DirectConnection); + connect(this, &GameList::ShouldCancelWorker, worker, &GameListWorker::Cancel, + Qt::DirectConnection); QThreadPool::globalInstance()->start(worker); current_worker = std::move(worker); @@ -151,6 +151,6 @@ void GameListWorker::run() { } void GameListWorker::Cancel() { - disconnect(this, 0, 0, 0); + disconnect(this, nullptr, nullptr, nullptr); stop_processing = true; } diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h index a22e9bc60..30b2c79a8 100644 --- a/src/citra_qt/game_list.h +++ b/src/citra_qt/game_list.h @@ -25,7 +25,7 @@ public: COLUMN_COUNT, // Number of columns }; - GameList(QWidget* parent = nullptr); + explicit GameList(QWidget* parent = nullptr); ~GameList() override; void PopulateAsync(const QString& dir_path, bool deep_scan); @@ -33,18 +33,15 @@ public: void SaveInterfaceLayout(); void LoadInterfaceLayout(); -public slots: - void AddEntry(QList<QStandardItem*> entry_items); - -private slots: - void ValidateEntry(const QModelIndex& item); - void DonePopulating(); - signals: void GameChosen(QString game_path); void ShouldCancelWorker(); private: + void AddEntry(const QList<QStandardItem*>& entry_items); + void ValidateEntry(const QModelIndex& item); + void DonePopulating(); + QTreeView* tree_view = nullptr; QStandardItemModel* item_model = nullptr; GameListWorker* current_worker = nullptr; diff --git a/src/citra_qt/hotkeys.h b/src/citra_qt/hotkeys.h index 350103c6f..46f48c2d8 100644 --- a/src/citra_qt/hotkeys.h +++ b/src/citra_qt/hotkeys.h @@ -55,7 +55,7 @@ class GHotkeysDialog : public QWidget { Q_OBJECT public: - GHotkeysDialog(QWidget* parent = nullptr); + explicit GHotkeysDialog(QWidget* parent = nullptr); private: Ui::hotkeys ui; diff --git a/src/citra_qt/util/spinbox.h b/src/citra_qt/util/spinbox.h index a57355cd6..2fa1db3a4 100644 --- a/src/citra_qt/util/spinbox.h +++ b/src/citra_qt/util/spinbox.h @@ -42,7 +42,7 @@ class CSpinBox : public QAbstractSpinBox { Q_OBJECT public: - CSpinBox(QWidget* parent = nullptr); + explicit CSpinBox(QWidget* parent = nullptr); void stepBy(int steps) override; StepEnabled stepEnabled() const override; diff --git a/src/citra_qt/version.h b/src/citra_qt/version.h deleted file mode 100644 index 9d5a2b1a2..000000000 --- a/src/citra_qt/version.h +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -// TODO: Supposed to be generated... -// GENERATED - Do not edit! -#ifndef VERSION_H_ -#define VERSION_H_ -#define __BUILD__ "40" -#define VERSION __BUILD__ -#endif // VERSION_H_ diff --git a/src/common/bit_set.h b/src/common/bit_set.h index c48b3b769..3059d0cb0 100644 --- a/src/common/bit_set.h +++ b/src/common/bit_set.h @@ -16,7 +16,7 @@ namespace Common { // Helper functions: -#ifdef _WIN32 +#ifdef _MSC_VER template <typename T> static inline int CountSetBits(T v) { // from https://graphics.stanford.edu/~seander/bithacks.html diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp index d61c1696b..9d423766f 100644 --- a/src/common/logging/text_formatter.cpp +++ b/src/common/logging/text_formatter.cpp @@ -7,7 +7,7 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#include <Windows.h> +#include <windows.h> #endif #include "common/assert.h" diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index df1008180..bad311793 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -14,7 +14,7 @@ #ifdef _WIN32 #include <codecvt> -#include <Windows.h> +#include <windows.h> #include "common/common_funcs.h" #else #include <iconv.h> diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 9bb2f4e1d..9e207118f 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -6,7 +6,7 @@ #ifdef __APPLE__ #include <mach/mach.h> #elif defined(_WIN32) -#include <Windows.h> +#include <windows.h> #else #if defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) #include <pthread_np.h> diff --git a/src/common/timer.cpp b/src/common/timer.cpp index e843cbd9c..c9803109e 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp @@ -4,7 +4,8 @@ #include <time.h> #ifdef _WIN32 -#include <Windows.h> +#include <windows.h> +// windows.h needs to be included before other windows headers #include <mmsystem.h> #include <sys/timeb.h> #else diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5d2537202..7b3b4389a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -18,10 +18,12 @@ set(SRCS file_sys/archive_backend.cpp file_sys/archive_extsavedata.cpp file_sys/archive_ncch.cpp + file_sys/archive_other_savedata.cpp file_sys/archive_romfs.cpp file_sys/archive_savedata.cpp file_sys/archive_sdmc.cpp file_sys/archive_sdmcwriteonly.cpp + file_sys/archive_source_sd_savedata.cpp file_sys/archive_systemsavedata.cpp file_sys/disk_archive.cpp file_sys/ivfc_archive.cpp @@ -76,6 +78,7 @@ set(SRCS hle/service/cecd/cecd_u.cpp hle/service/cfg/cfg.cpp hle/service/cfg/cfg_i.cpp + hle/service/cfg/cfg_nor.cpp hle/service/cfg/cfg_s.cpp hle/service/cfg/cfg_u.cpp hle/service/csnd_snd.cpp @@ -104,8 +107,13 @@ set(SRCS hle/service/ldr_ro/ldr_ro.cpp hle/service/ldr_ro/memory_synchronizer.cpp hle/service/mic_u.cpp + hle/service/mvd/mvd.cpp + hle/service/mvd/mvd_std.cpp hle/service/ndm/ndm.cpp hle/service/ndm/ndm_u.cpp + hle/service/nfc/nfc.cpp + hle/service/nfc/nfc_m.cpp + hle/service/nfc/nfc_u.cpp hle/service/news/news.cpp hle/service/news/news_s.cpp hle/service/news/news_u.cpp @@ -117,9 +125,15 @@ set(SRCS hle/service/nwm_uds.cpp hle/service/pm_app.cpp hle/service/ptm/ptm.cpp + hle/service/ptm/ptm_gets.cpp hle/service/ptm/ptm_play.cpp + hle/service/ptm/ptm_sets.cpp hle/service/ptm/ptm_sysm.cpp hle/service/ptm/ptm_u.cpp + hle/service/qtm/qtm.cpp + hle/service/qtm/qtm_s.cpp + hle/service/qtm/qtm_sp.cpp + hle/service/qtm/qtm_u.cpp hle/service/service.cpp hle/service/soc_u.cpp hle/service/srv.cpp @@ -164,10 +178,12 @@ set(HEADERS file_sys/archive_backend.h file_sys/archive_extsavedata.h file_sys/archive_ncch.h + file_sys/archive_other_savedata.h file_sys/archive_romfs.h file_sys/archive_savedata.h file_sys/archive_sdmc.h file_sys/archive_sdmcwriteonly.h + file_sys/archive_source_sd_savedata.h file_sys/archive_systemsavedata.h file_sys/directory_backend.h file_sys/disk_archive.h @@ -227,6 +243,7 @@ set(HEADERS hle/service/cecd/cecd_u.h hle/service/cfg/cfg.h hle/service/cfg/cfg_i.h + hle/service/cfg/cfg_nor.h hle/service/cfg/cfg_s.h hle/service/cfg/cfg_u.h hle/service/csnd_snd.h @@ -255,8 +272,13 @@ set(HEADERS hle/service/ldr_ro/ldr_ro.h hle/service/ldr_ro/memory_synchronizer.h hle/service/mic_u.h + hle/service/mvd/mvd.h + hle/service/mvd/mvd_std.h hle/service/ndm/ndm.h hle/service/ndm/ndm_u.h + hle/service/nfc/nfc.h + hle/service/nfc/nfc_m.h + hle/service/nfc/nfc_u.h hle/service/news/news.h hle/service/news/news_s.h hle/service/news/news_u.h @@ -268,9 +290,15 @@ set(HEADERS hle/service/nwm_uds.h hle/service/pm_app.h hle/service/ptm/ptm.h + hle/service/ptm/ptm_gets.h hle/service/ptm/ptm_play.h + hle/service/ptm/ptm_sets.h hle/service/ptm/ptm_sysm.h hle/service/ptm/ptm_u.h + hle/service/qtm/qtm.h + hle/service/qtm/qtm_s.h + hle/service/qtm/qtm_sp.h + hle/service/qtm/qtm_u.h hle/service/service.h hle/service/soc_u.h hle/service/srv.h diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index ca8a94ee9..fc4254670 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstring> #include <dynarmic/dynarmic.h> #include "common/assert.h" #include "common/microprofile.h" diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index e1c4931ec..5b172df4a 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -64,7 +64,7 @@ private: */ class ExtSaveDataArchive : public SaveDataArchive { public: - ExtSaveDataArchive(const std::string& mount_point) : SaveDataArchive(mount_point) {} + explicit ExtSaveDataArchive(const std::string& mount_point) : SaveDataArchive(mount_point) {} std::string GetName() const override { return "ExtSaveDataArchive: " + mount_point; diff --git a/src/core/file_sys/archive_ncch.h b/src/core/file_sys/archive_ncch.h index 66b8ce75d..753b91f96 100644 --- a/src/core/file_sys/archive_ncch.h +++ b/src/core/file_sys/archive_ncch.h @@ -17,7 +17,7 @@ namespace FileSys { /// File system interface to the NCCH archive class ArchiveFactory_NCCH final : public ArchiveFactory { public: - ArchiveFactory_NCCH(const std::string& mount_point); + explicit ArchiveFactory_NCCH(const std::string& mount_point); std::string GetName() const override { return "NCCH"; diff --git a/src/core/file_sys/archive_other_savedata.cpp b/src/core/file_sys/archive_other_savedata.cpp new file mode 100644 index 000000000..d3cf080da --- /dev/null +++ b/src/core/file_sys/archive_other_savedata.cpp @@ -0,0 +1,145 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <tuple> +#include "core/file_sys/archive_other_savedata.h" +#include "core/file_sys/errors.h" +#include "core/hle/kernel/process.h" +#include "core/hle/service/fs/archive.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +// TODO(wwylele): The storage info in exheader should be checked before accessing these archives + +using Service::FS::MediaType; + +namespace { + +template <typename T> +ResultVal<std::tuple<MediaType, u64>> ParsePath(const Path& path, T program_id_reader) { + if (path.GetType() != Binary) { + LOG_ERROR(Service_FS, "Wrong path type %d", static_cast<int>(path.GetType())); + return ERROR_INVALID_PATH; + } + + std::vector<u8> vec_data = path.AsBinary(); + + if (vec_data.size() != 12) { + LOG_ERROR(Service_FS, "Wrong path length %zu", vec_data.size()); + return ERROR_INVALID_PATH; + } + + const u32* data = reinterpret_cast<const u32*>(vec_data.data()); + auto media_type = static_cast<MediaType>(data[0]); + + if (media_type != MediaType::SDMC && media_type != MediaType::GameCard) { + LOG_ERROR(Service_FS, "Unsupported media type %u", static_cast<u32>(media_type)); + + // Note: this is strange, but the error code was verified with a real 3DS + return ERROR_UNSUPPORTED_OPEN_FLAGS; + } + + return MakeResult<std::tuple<MediaType, u64>>(media_type, program_id_reader(data)); +} + +ResultVal<std::tuple<MediaType, u64>> ParsePathPermitted(const Path& path) { + return ParsePath(path, + [](const u32* data) -> u64 { return (data[1] << 8) | 0x0004000000000000ULL; }); +} + +ResultVal<std::tuple<MediaType, u64>> ParsePathGeneral(const Path& path) { + return ParsePath( + path, [](const u32* data) -> u64 { return data[1] | (static_cast<u64>(data[2]) << 32); }); +} + +} // namespace + +ArchiveFactory_OtherSaveDataPermitted::ArchiveFactory_OtherSaveDataPermitted( + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata) + : sd_savedata_source(sd_savedata) {} + +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataPermitted::Open( + const Path& path) { + MediaType media_type; + u64 program_id; + CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path)); + + if (media_type == MediaType::GameCard) { + LOG_WARNING(Service_FS, "(stubbed) Unimplemented media type GameCard"); + return ERROR_GAMECARD_NOT_INSERTED; + } + + return sd_savedata_source->Open(program_id); +} + +ResultCode ArchiveFactory_OtherSaveDataPermitted::Format( + const Path& path, const FileSys::ArchiveFormatInfo& format_info) { + LOG_ERROR(Service_FS, "Attempted to format a OtherSaveDataPermitted archive."); + return ERROR_INVALID_PATH; +} + +ResultVal<ArchiveFormatInfo> ArchiveFactory_OtherSaveDataPermitted::GetFormatInfo( + const Path& path) const { + MediaType media_type; + u64 program_id; + CASCADE_RESULT(std::tie(media_type, program_id), ParsePathPermitted(path)); + + if (media_type == MediaType::GameCard) { + LOG_WARNING(Service_FS, "(stubbed) Unimplemented media type GameCard"); + return ERROR_GAMECARD_NOT_INSERTED; + } + + return sd_savedata_source->GetFormatInfo(program_id); +} + +ArchiveFactory_OtherSaveDataGeneral::ArchiveFactory_OtherSaveDataGeneral( + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata) + : sd_savedata_source(sd_savedata) {} + +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_OtherSaveDataGeneral::Open( + const Path& path) { + MediaType media_type; + u64 program_id; + CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); + + if (media_type == MediaType::GameCard) { + LOG_WARNING(Service_FS, "(stubbed) Unimplemented media type GameCard"); + return ERROR_GAMECARD_NOT_INSERTED; + } + + return sd_savedata_source->Open(program_id); +} + +ResultCode ArchiveFactory_OtherSaveDataGeneral::Format( + const Path& path, const FileSys::ArchiveFormatInfo& format_info) { + MediaType media_type; + u64 program_id; + CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); + + if (media_type == MediaType::GameCard) { + LOG_WARNING(Service_FS, "(stubbed) Unimplemented media type GameCard"); + return ERROR_GAMECARD_NOT_INSERTED; + } + + return sd_savedata_source->Format(program_id, format_info); +} + +ResultVal<ArchiveFormatInfo> ArchiveFactory_OtherSaveDataGeneral::GetFormatInfo( + const Path& path) const { + MediaType media_type; + u64 program_id; + CASCADE_RESULT(std::tie(media_type, program_id), ParsePathGeneral(path)); + + if (media_type == MediaType::GameCard) { + LOG_WARNING(Service_FS, "(stubbed) Unimplemented media type GameCard"); + return ERROR_GAMECARD_NOT_INSERTED; + } + + return sd_savedata_source->GetFormatInfo(program_id); +} + +} // namespace FileSys diff --git a/src/core/file_sys/archive_other_savedata.h b/src/core/file_sys/archive_other_savedata.h new file mode 100644 index 000000000..d80725158 --- /dev/null +++ b/src/core/file_sys/archive_other_savedata.h @@ -0,0 +1,52 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/file_sys/archive_source_sd_savedata.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +/// File system interface to the OtherSaveDataPermitted archive +class ArchiveFactory_OtherSaveDataPermitted final : public ArchiveFactory { +public: + explicit ArchiveFactory_OtherSaveDataPermitted( + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source); + + std::string GetName() const override { + return "OtherSaveDataPermitted"; + } + + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; + +private: + std::string mount_point; + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; +}; + +/// File system interface to the OtherSaveDataGeneral archive +class ArchiveFactory_OtherSaveDataGeneral final : public ArchiveFactory { +public: + explicit ArchiveFactory_OtherSaveDataGeneral( + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source); + + std::string GetName() const override { + return "OtherSaveDataGeneral"; + } + + ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; + ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; + ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; + +private: + std::string mount_point; + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; +}; + +} // namespace FileSys diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index 8a8082a05..1eaf99b54 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -20,7 +20,7 @@ namespace FileSys { /// File system interface to the RomFS archive class ArchiveFactory_RomFS final : public ArchiveFactory { public: - ArchiveFactory_RomFS(Loader::AppLoader& app_loader); + explicit ArchiveFactory_RomFS(Loader::AppLoader& app_loader); std::string GetName() const override { return "RomFS"; diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index ecb44a215..61f7654f7 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -2,96 +2,29 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <algorithm> -#include <memory> -#include "common/common_types.h" -#include "common/file_util.h" -#include "common/logging/log.h" -#include "common/string_util.h" #include "core/file_sys/archive_savedata.h" -#include "core/file_sys/savedata_archive.h" #include "core/hle/kernel/process.h" -#include "core/hle/service/fs/archive.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace namespace FileSys { -static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { - return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(), - SYSTEM_ID.c_str(), SDCARD_ID.c_str()); -} - -static std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) { - u32 high = (u32)(program_id >> 32); - u32 low = (u32)(program_id & 0xFFFFFFFF); - return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, - low); -} - -static std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 program_id) { - u32 high = (u32)(program_id >> 32); - u32 low = (u32)(program_id & 0xFFFFFFFF); - return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(), - high, low); -} - -ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory) - : mount_point(GetSaveDataContainerPath(sdmc_directory)) { - LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); -} +ArchiveFactory_SaveData::ArchiveFactory_SaveData( + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata) + : sd_savedata_source(sd_savedata) {} ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { - std::string concrete_mount_point = - GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); - if (!FileUtil::Exists(concrete_mount_point)) { - // When a SaveData archive is created for the first time, it is not yet formatted and the - // save file/directory structure expected by the game has not yet been initialized. - // Returning the NotFormatted error code will signal the game to provision the SaveData - // archive with the files and folders that it expects. - return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, - ErrorSummary::InvalidState, ErrorLevel::Status); - } - - auto archive = std::make_unique<SaveDataArchive>(std::move(concrete_mount_point)); - return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); + return sd_savedata_source->Open(Kernel::g_current_process->codeset->program_id); } ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { - std::string concrete_mount_point = - GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); - FileUtil::DeleteDirRecursively(concrete_mount_point); - FileUtil::CreateFullPath(concrete_mount_point); - - // Write the format metadata - std::string metadata_path = - GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); - FileUtil::IOFile file(metadata_path, "wb"); - - if (file.IsOpen()) { - file.WriteBytes(&format_info, sizeof(format_info)); - return RESULT_SUCCESS; - } - return RESULT_SUCCESS; + return sd_savedata_source->Format(Kernel::g_current_process->codeset->program_id, format_info); } ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { - std::string metadata_path = - GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); - FileUtil::IOFile file(metadata_path, "rb"); - - if (!file.IsOpen()) { - LOG_ERROR(Service_FS, "Could not open metadata information for archive"); - // TODO(Subv): Verify error code - return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, - ErrorSummary::InvalidState, ErrorLevel::Status); - } - - ArchiveFormatInfo info = {}; - file.ReadBytes(&info, sizeof(info)); - return MakeResult<ArchiveFormatInfo>(info); + return sd_savedata_source->GetFormatInfo(Kernel::g_current_process->codeset->program_id); } } // namespace FileSys diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 6a372865a..41aa6f189 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -4,10 +4,7 @@ #pragma once -#include <memory> -#include <string> -#include "core/file_sys/archive_backend.h" -#include "core/hle/result.h" +#include "core/file_sys/archive_source_sd_savedata.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // FileSys namespace @@ -17,7 +14,7 @@ namespace FileSys { /// File system interface to the SaveData archive class ArchiveFactory_SaveData final : public ArchiveFactory { public: - ArchiveFactory_SaveData(const std::string& mount_point); + explicit ArchiveFactory_SaveData(std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source); std::string GetName() const override { return "SaveData"; @@ -30,6 +27,7 @@ public: private: std::string mount_point; + std::shared_ptr<ArchiveSource_SDSaveData> sd_savedata_source; }; } // namespace FileSys diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 9d99b110c..f6c70bfcc 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -17,7 +17,7 @@ namespace FileSys { /// Archive backend for SDMC archive class SDMCArchive : public ArchiveBackend { public: - SDMCArchive(const std::string& mount_point_) : mount_point(mount_point_) {} + explicit SDMCArchive(const std::string& mount_point_) : mount_point(mount_point_) {} std::string GetName() const override { return "SDMCArchive: " + mount_point; @@ -43,7 +43,7 @@ protected: /// File system interface to the SDMC archive class ArchiveFactory_SDMC final : public ArchiveFactory { public: - ArchiveFactory_SDMC(const std::string& mount_point); + explicit ArchiveFactory_SDMC(const std::string& mount_point); /** * Initialize the archive. diff --git a/src/core/file_sys/archive_sdmcwriteonly.h b/src/core/file_sys/archive_sdmcwriteonly.h index ed977485a..9cd38d96f 100644 --- a/src/core/file_sys/archive_sdmcwriteonly.h +++ b/src/core/file_sys/archive_sdmcwriteonly.h @@ -19,7 +19,7 @@ namespace FileSys { */ class SDMCWriteOnlyArchive : public SDMCArchive { public: - SDMCWriteOnlyArchive(const std::string& mount_point) : SDMCArchive(mount_point) {} + explicit SDMCWriteOnlyArchive(const std::string& mount_point) : SDMCArchive(mount_point) {} std::string GetName() const override { return "SDMCWriteOnlyArchive: " + mount_point; @@ -34,7 +34,7 @@ public: /// File system interface to the SDMC write-only archive class ArchiveFactory_SDMCWriteOnly final : public ArchiveFactory { public: - ArchiveFactory_SDMCWriteOnly(const std::string& mount_point); + explicit ArchiveFactory_SDMCWriteOnly(const std::string& mount_point); /** * Initialize the archive. diff --git a/src/core/file_sys/archive_source_sd_savedata.cpp b/src/core/file_sys/archive_source_sd_savedata.cpp new file mode 100644 index 000000000..2d8a950a3 --- /dev/null +++ b/src/core/file_sys/archive_source_sd_savedata.cpp @@ -0,0 +1,93 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/file_util.h" +#include "common/logging/log.h" +#include "common/string_util.h" +#include "core/file_sys/archive_source_sd_savedata.h" +#include "core/file_sys/savedata_archive.h" +#include "core/hle/service/fs/archive.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +namespace { + +std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { + return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(), + SYSTEM_ID.c_str(), SDCARD_ID.c_str()); +} + +std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) { + u32 high = static_cast<u32>(program_id >> 32); + u32 low = static_cast<u32>(program_id & 0xFFFFFFFF); + return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, + low); +} + +std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 program_id) { + u32 high = static_cast<u32>(program_id >> 32); + u32 low = static_cast<u32>(program_id & 0xFFFFFFFF); + return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(), + high, low); +} + +} // namespace + +ArchiveSource_SDSaveData::ArchiveSource_SDSaveData(const std::string& sdmc_directory) + : mount_point(GetSaveDataContainerPath(sdmc_directory)) { + LOG_INFO(Service_FS, "Directory %s set as SaveData.", mount_point.c_str()); +} + +ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 program_id) { + std::string concrete_mount_point = GetSaveDataPath(mount_point, program_id); + if (!FileUtil::Exists(concrete_mount_point)) { + // When a SaveData archive is created for the first time, it is not yet formatted and the + // save file/directory structure expected by the game has not yet been initialized. + // Returning the NotFormatted error code will signal the game to provision the SaveData + // archive with the files and folders that it expects. + return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, + ErrorSummary::InvalidState, ErrorLevel::Status); + } + + auto archive = std::make_unique<SaveDataArchive>(std::move(concrete_mount_point)); + return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); +} + +ResultCode ArchiveSource_SDSaveData::Format(u64 program_id, + const FileSys::ArchiveFormatInfo& format_info) { + std::string concrete_mount_point = GetSaveDataPath(mount_point, program_id); + FileUtil::DeleteDirRecursively(concrete_mount_point); + FileUtil::CreateFullPath(concrete_mount_point); + + // Write the format metadata + std::string metadata_path = GetSaveDataMetadataPath(mount_point, program_id); + FileUtil::IOFile file(metadata_path, "wb"); + + if (file.IsOpen()) { + file.WriteBytes(&format_info, sizeof(format_info)); + return RESULT_SUCCESS; + } + return RESULT_SUCCESS; +} + +ResultVal<ArchiveFormatInfo> ArchiveSource_SDSaveData::GetFormatInfo(u64 program_id) const { + std::string metadata_path = GetSaveDataMetadataPath(mount_point, program_id); + FileUtil::IOFile file(metadata_path, "rb"); + + if (!file.IsOpen()) { + LOG_ERROR(Service_FS, "Could not open metadata information for archive"); + // TODO(Subv): Verify error code + return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, + ErrorSummary::InvalidState, ErrorLevel::Status); + } + + ArchiveFormatInfo info = {}; + file.ReadBytes(&info, sizeof(info)); + return MakeResult<ArchiveFormatInfo>(info); +} + +} // namespace FileSys diff --git a/src/core/file_sys/archive_source_sd_savedata.h b/src/core/file_sys/archive_source_sd_savedata.h new file mode 100644 index 000000000..b33126c31 --- /dev/null +++ b/src/core/file_sys/archive_source_sd_savedata.h @@ -0,0 +1,30 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include <string> +#include "core/file_sys/archive_backend.h" +#include "core/hle/result.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// FileSys namespace + +namespace FileSys { + +/// A common source of SD save data archive +class ArchiveSource_SDSaveData { +public: + explicit ArchiveSource_SDSaveData(const std::string& mount_point); + + ResultVal<std::unique_ptr<ArchiveBackend>> Open(u64 program_id); + ResultCode Format(u64 program_id, const FileSys::ArchiveFormatInfo& format_info); + ResultVal<ArchiveFormatInfo> GetFormatInfo(u64 program_id) const; + +private: + std::string mount_point; +}; + +} // namespace FileSys diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index a24b89f2b..52eb6c630 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -18,7 +18,7 @@ namespace FileSys { /// File system interface to the SystemSaveData archive class ArchiveFactory_SystemSaveData final : public ArchiveFactory { public: - ArchiveFactory_SystemSaveData(const std::string& mount_point); + explicit ArchiveFactory_SystemSaveData(const std::string& mount_point); ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; diff --git a/src/core/file_sys/errors.h b/src/core/file_sys/errors.h index fd1b07df0..4d5f62b08 100644 --- a/src/core/file_sys/errors.h +++ b/src/core/file_sys/errors.h @@ -36,5 +36,8 @@ const ResultCode ERROR_ALREADY_EXISTS(ErrorDescription::FS_AlreadyExists, ErrorM ErrorSummary::NothingHappened, ErrorLevel::Status); const ResultCode ERROR_DIRECTORY_NOT_EMPTY(ErrorDescription::FS_DirectoryNotEmpty, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); +const ResultCode ERROR_GAMECARD_NOT_INSERTED(ErrorDescription::FS_GameCardNotInserted, + ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Status); } // namespace FileSys diff --git a/src/core/file_sys/path_parser.h b/src/core/file_sys/path_parser.h index 990802579..b9f52f65d 100644 --- a/src/core/file_sys/path_parser.h +++ b/src/core/file_sys/path_parser.h @@ -17,7 +17,7 @@ namespace FileSys { */ class PathParser { public: - PathParser(const Path& path); + explicit PathParser(const Path& path); /** * Checks if the Path is valid. diff --git a/src/core/file_sys/savedata_archive.h b/src/core/file_sys/savedata_archive.h index 2fb6c452a..176d35710 100644 --- a/src/core/file_sys/savedata_archive.h +++ b/src/core/file_sys/savedata_archive.h @@ -18,7 +18,7 @@ namespace FileSys { /// Archive backend for general save data archive type (SaveData and SystemSaveData) class SaveDataArchive : public ArchiveBackend { public: - SaveDataArchive(const std::string& mount_point_) : mount_point(mount_point_) {} + explicit SaveDataArchive(const std::string& mount_point_) : mount_point(mount_point_) {} std::string GetName() const override { return "SaveDataArchive: " + mount_point; diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index aea43e92b..21d941363 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -15,8 +15,8 @@ #include <fcntl.h> #ifdef _WIN32 -#include <WinSock2.h> -#include <common/x64/abi.h> +#include <winsock2.h> +// winsock2.h needs to be included first to prevent winsock.h being included by other includes #include <io.h> #include <iphlpapi.h> #include <ws2tcpip.h> diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp index 4311d9897..645b2d5fe 100644 --- a/src/core/hle/applets/applet.cpp +++ b/src/core/hle/applets/applet.cpp @@ -101,6 +101,10 @@ ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) return result; } +bool Applet::IsRunning() const { + return is_running; +} + bool IsLibraryAppletRunning() { // Check the applets map for instances of any applet for (auto itr = applets.begin(); itr != applets.end(); ++itr) diff --git a/src/core/hle/applets/applet.h b/src/core/hle/applets/applet.h index bfdcad126..ebeed9813 100644 --- a/src/core/hle/applets/applet.h +++ b/src/core/hle/applets/applet.h @@ -13,8 +13,7 @@ namespace Applets { class Applet { public: - virtual ~Applet() {} - Applet(Service::APT::AppletId id) : id(id) {} + virtual ~Applet() = default; /** * Creates an instance of the Applet subclass identified by the parameter. @@ -48,7 +47,7 @@ public: /** * Whether the applet is currently executing instead of the host application or not. */ - virtual bool IsRunning() const = 0; + bool IsRunning() const; /** * Handles an update tick for the Applet, lets it update the screen, send commands, etc. @@ -56,6 +55,8 @@ public: virtual void Update() = 0; protected: + explicit Applet(Service::APT::AppletId id) : id(id) {} + /** * Handles the Applet start event, triggered from the application. * @param parameter Parameter data to handle. @@ -65,6 +66,9 @@ protected: Service::APT::AppletId id; ///< Id of this Applet std::shared_ptr<std::vector<u8>> heap_memory; ///< Heap memory for this Applet + + /// Whether this applet is currently running instead of the host application or not. + bool is_running = false; }; /// Returns whether a library applet is currently running diff --git a/src/core/hle/applets/erreula.cpp b/src/core/hle/applets/erreula.cpp index e1379ac4d..75d7fd9fc 100644 --- a/src/core/hle/applets/erreula.cpp +++ b/src/core/hle/applets/erreula.cpp @@ -47,7 +47,7 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param } ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parameter) { - started = true; + is_running = true; // TODO(Subv): Set the expected fields in the response buffer before resending it to the // application. @@ -62,7 +62,7 @@ ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parame message.sender_id = static_cast<u32>(id); Service::APT::SendParameter(message); - started = false; + is_running = false; return RESULT_SUCCESS; } diff --git a/src/core/hle/applets/erreula.h b/src/core/hle/applets/erreula.h index a7ec7ec01..681bbea0c 100644 --- a/src/core/hle/applets/erreula.h +++ b/src/core/hle/applets/erreula.h @@ -17,18 +17,12 @@ public: ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; void Update() override; - bool IsRunning() const override { - return started; - } +private: /// This SharedMemory will be created when we receive the LibAppJustStarted message. /// It holds the framebuffer info retrieved by the application with /// GSPGPU::ImportDisplayCaptureInfo Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; - -private: - /// Whether this applet is currently running instead of the host application or not. - bool started = false; }; } // namespace Applets diff --git a/src/core/hle/applets/mii_selector.cpp b/src/core/hle/applets/mii_selector.cpp index 3455b9201..07c7f5b99 100644 --- a/src/core/hle/applets/mii_selector.cpp +++ b/src/core/hle/applets/mii_selector.cpp @@ -55,7 +55,7 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p } ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& parameter) { - started = true; + is_running = true; // TODO(Subv): Set the expected fields in the response buffer before resending it to the // application. @@ -78,7 +78,7 @@ ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& pa message.sender_id = static_cast<u32>(id); Service::APT::SendParameter(message); - started = false; + is_running = false; return RESULT_SUCCESS; } diff --git a/src/core/hle/applets/mii_selector.h b/src/core/hle/applets/mii_selector.h index e3ab9f0cd..ec00e29d2 100644 --- a/src/core/hle/applets/mii_selector.h +++ b/src/core/hle/applets/mii_selector.h @@ -65,23 +65,18 @@ ASSERT_REG_POSITION(unk_6C, 0x6C); class MiiSelector final : public Applet { public: - MiiSelector(Service::APT::AppletId id) : Applet(id), started(false) {} + MiiSelector(Service::APT::AppletId id) : Applet(id) {} ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; void Update() override; - bool IsRunning() const override { - return started; - } +private: /// This SharedMemory will be created when we receive the LibAppJustStarted message. /// It holds the framebuffer info retrieved by the application with /// GSPGPU::ImportDisplayCaptureInfo Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; - /// Whether this applet is currently running instead of the host application or not. - bool started; - MiiConfig config; }; } diff --git a/src/core/hle/applets/swkbd.cpp b/src/core/hle/applets/swkbd.cpp index 1e21337f5..059297fbc 100644 --- a/src/core/hle/applets/swkbd.cpp +++ b/src/core/hle/applets/swkbd.cpp @@ -70,7 +70,7 @@ ResultCode SoftwareKeyboard::StartImpl(Service::APT::AppletStartupParameter cons DrawScreenKeyboard(); - started = true; + is_running = true; return RESULT_SUCCESS; } @@ -94,13 +94,13 @@ void SoftwareKeyboard::Update() { } void SoftwareKeyboard::DrawScreenKeyboard() { - auto bottom_screen = GSP_GPU::GetFrameBufferInfo(0, 1); + auto bottom_screen = Service::GSP::GetFrameBufferInfo(0, 1); auto info = bottom_screen->framebuffer_info[bottom_screen->index]; // TODO(Subv): Draw the HLE keyboard, for now just zero-fill the framebuffer Memory::ZeroBlock(info.address_left, info.stride * 320); - GSP_GPU::SetBufferSwap(1, info); + Service::GSP::SetBufferSwap(1, info); } void SoftwareKeyboard::Finalize() { @@ -113,7 +113,7 @@ void SoftwareKeyboard::Finalize() { message.sender_id = static_cast<u32>(id); Service::APT::SendParameter(message); - started = false; + is_running = false; } } } // namespace diff --git a/src/core/hle/applets/swkbd.h b/src/core/hle/applets/swkbd.h index ea0b1fba9..cc92a8f19 100644 --- a/src/core/hle/applets/swkbd.h +++ b/src/core/hle/applets/swkbd.h @@ -52,14 +52,11 @@ static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software Keyboard Config class SoftwareKeyboard final : public Applet { public: - SoftwareKeyboard(Service::APT::AppletId id) : Applet(id), started(false) {} + SoftwareKeyboard(Service::APT::AppletId id) : Applet(id) {} ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; void Update() override; - bool IsRunning() const override { - return started; - } /** * Draws a keyboard to the current bottom screen framebuffer. @@ -72,6 +69,7 @@ public: */ void Finalize(); +private: /// This SharedMemory will be created when we receive the LibAppJustStarted message. /// It holds the framebuffer info retrieved by the application with /// GSPGPU::ImportDisplayCaptureInfo @@ -82,9 +80,6 @@ public: /// Configuration of this instance of the SoftwareKeyboard, as received from the application SoftwareKeyboardConfig config; - - /// Whether this applet is currently running instead of the host application or not. - bool started; }; } } // namespace diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 20562aed6..53864a3a7 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -23,6 +23,7 @@ enum class ErrorDescription : u32 { FS_ArchiveNotMounted = 101, FS_FileNotFound = 112, FS_PathNotFound = 113, + FS_GameCardNotInserted = 141, FS_NotFound = 120, FS_FileAlreadyExists = 180, FS_DirectoryAlreadyExists = 185, diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index fe367aca5..36204db4d 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -2,14 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <array> + #include "common/logging/log.h" #include "core/hle/kernel/event.h" #include "core/hle/service/ac_u.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace AC_U - -namespace AC_U { +namespace Service { +namespace AC { struct ACConfig { std::array<u8, 0x200> data; @@ -31,7 +31,7 @@ static Kernel::SharedPtr<Kernel::Event> disconnect_event; * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void CreateDefaultConfig(Service::Interface* self) { +static void CreateDefaultConfig(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 ac_config_addr = cmd_buff[65]; @@ -56,7 +56,7 @@ static void CreateDefaultConfig(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void ConnectAsync(Service::Interface* self) { +static void ConnectAsync(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); connect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); @@ -77,7 +77,7 @@ static void ConnectAsync(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void GetConnectResult(Service::Interface* self) { +static void GetConnectResult(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -94,7 +94,7 @@ static void GetConnectResult(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void CloseAsync(Service::Interface* self) { +static void CloseAsync(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); if (ac_connected && disconnect_event) { @@ -120,7 +120,7 @@ static void CloseAsync(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void GetCloseResult(Service::Interface* self) { +static void GetCloseResult(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -134,7 +134,7 @@ static void GetCloseResult(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Output connection type, 0 = none, 1 = Old3DS Internet, 2 = New3DS Internet. */ -static void GetWifiStatus(Service::Interface* self) { +static void GetWifiStatus(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // TODO(purpasmart96): This function is only a stub, @@ -155,7 +155,7 @@ static void GetWifiStatus(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Infra Priority */ -static void GetInfraPriority(Service::Interface* self) { +static void GetInfraPriority(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -177,7 +177,7 @@ static void GetInfraPriority(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Infra Priority */ -static void SetRequestEulaVersion(Service::Interface* self) { +static void SetRequestEulaVersion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 major = cmd_buff[1] & 0xFF; @@ -203,7 +203,7 @@ static void SetRequestEulaVersion(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void RegisterDisconnectEvent(Service::Interface* self) { +static void RegisterDisconnectEvent(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); disconnect_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); @@ -221,7 +221,7 @@ static void RegisterDisconnectEvent(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : bool, is connected */ -static void IsConnected(Service::Interface* self) { +static void IsConnected(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -237,7 +237,7 @@ static void IsConnected(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetClientVersion(Service::Interface* self) { +static void SetClientVersion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); const u32 version = cmd_buff[1]; @@ -271,10 +271,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00400042, SetClientVersion, "SetClientVersion"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +AC_U::AC_U() { Register(FunctionTable); ac_connected = false; @@ -284,10 +281,11 @@ Interface::Interface() { disconnect_event = nullptr; } -Interface::~Interface() { +AC_U::~AC_U() { close_event = nullptr; connect_event = nullptr; disconnect_event = nullptr; } -} // namespace +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/ac_u.h b/src/core/hle/service/ac_u.h index 6592b21c9..573c32d7e 100644 --- a/src/core/hle/service/ac_u.h +++ b/src/core/hle/service/ac_u.h @@ -6,21 +6,18 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace AC_U +namespace Service { +namespace AC { -// socket service "ac:u" - -namespace AC_U { - -class Interface : public Service::Interface { +class AC_U final : public Interface { public: - Interface(); - ~Interface(); + AC_U(); + ~AC_U(); std::string GetPortName() const override { return "ac:u"; } }; -} // namespace +} // namespace AC +} // namespace Service diff --git a/src/core/hle/service/act_a.cpp b/src/core/hle/service/act_a.cpp index 3a775fa90..9880aafff 100644 --- a/src/core/hle/service/act_a.cpp +++ b/src/core/hle/service/act_a.cpp @@ -4,23 +4,26 @@ #include "core/hle/service/act_a.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace ACT_A - -namespace ACT_A { +namespace Service { +namespace ACT { const Interface::FunctionInfo FunctionTable[] = { + // act:u shared commands + {0x00010084, nullptr, "Initialize"}, + {0x00020040, nullptr, "GetErrorCode"}, + {0x000600C2, nullptr, "GetAccountDataBlock"}, + {0x000B0042, nullptr, "AcquireEulaList"}, + {0x000D0040, nullptr, "GenerateUuid"}, + // act:a {0x041300C2, nullptr, "UpdateMiiImage"}, {0x041B0142, nullptr, "AgreeEula"}, {0x04210042, nullptr, "UploadMii"}, {0x04230082, nullptr, "ValidateMailAddress"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +ACT_A::ACT_A() { Register(FunctionTable); } -} // namespace +} // namespace ACT +} // namespace Service diff --git a/src/core/hle/service/act_a.h b/src/core/hle/service/act_a.h index 765cae644..e3adb03e5 100644 --- a/src/core/hle/service/act_a.h +++ b/src/core/hle/service/act_a.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace ACT_A +namespace Service { +namespace ACT { -namespace ACT_A { - -class Interface : public Service::Interface { +class ACT_A final : public Service::Interface { public: - Interface(); + ACT_A(); std::string GetPortName() const override { return "act:a"; } }; -} // namespace +} // namespace ACT +} // namespace Service diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp index 05de4d002..b4f69c57d 100644 --- a/src/core/hle/service/act_u.cpp +++ b/src/core/hle/service/act_u.cpp @@ -4,23 +4,22 @@ #include "core/hle/service/act_u.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace ACT_U - -namespace ACT_U { +namespace Service { +namespace ACT { const Interface::FunctionInfo FunctionTable[] = { + // clang-format off {0x00010084, nullptr, "Initialize"}, {0x00020040, nullptr, "GetErrorCode"}, {0x000600C2, nullptr, "GetAccountDataBlock"}, + {0x000B0042, nullptr, "AcquireEulaList"}, {0x000D0040, nullptr, "GenerateUuid"}, + // clang-format on }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +ACT_U::ACT_U() { Register(FunctionTable); } -} // namespace +} // namespace ACT +} // namespace Service diff --git a/src/core/hle/service/act_u.h b/src/core/hle/service/act_u.h index be41454a4..9d8538fbf 100644 --- a/src/core/hle/service/act_u.h +++ b/src/core/hle/service/act_u.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace ACT_U +namespace Service { +namespace ACT { -namespace ACT_U { - -class Interface : public Service::Interface { +class ACT_U final : public Interface { public: - Interface(); + ACT_U(); std::string GetPortName() const override { return "act:u"; } }; -} // namespace +} // namespace ACT +} // namespace Service diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index f7a990d69..d344a622f 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -20,7 +20,7 @@ static std::array<u32, 3> am_titles_list_count = {0, 0, 0}; static u32 am_ticket_count = 0; static u32 am_ticket_list_count = 0; -void GetTitleCount(Service::Interface* self) { +void GetNumPrograms(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 media_type = cmd_buff[1] & 0xFF; @@ -81,7 +81,7 @@ void DeleteContents(Service::Interface* self) { media_type, title_id, am_content_count[media_type], content_ids_pointer); } -void GetTitleList(Service::Interface* self) { +void GetProgramList(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 media_type = cmd_buff[2] & 0xFF; @@ -97,7 +97,7 @@ void GetTitleList(Service::Interface* self) { media_type, am_titles_list_count[media_type], title_ids_output_pointer); } -void GetTitleInfo(Service::Interface* self) { +void GetProgramInfos(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 media_type = cmd_buff[1] & 0xFF; @@ -113,7 +113,7 @@ void GetTitleInfo(Service::Interface* self) { } void GetDataTitleInfos(Service::Interface* self) { - GetTitleInfo(self); + GetProgramInfos(self); LOG_WARNING(Service_AM, "(STUBBED) called"); } @@ -151,7 +151,7 @@ void DeleteTicket(Service::Interface* self) { LOG_WARNING(Service_AM, "(STUBBED) called title_id=0x%016" PRIx64 "", title_id); } -void GetTicketCount(Service::Interface* self) { +void GetNumTickets(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 5676cdd5f..9bc2ca305 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -11,7 +11,7 @@ class Interface; namespace AM { /** - * AM::GetTitleCount service function + * AM::GetNumPrograms service function * Gets the number of installed titles in the requested media type * Inputs: * 0 : Command header (0x00010040) @@ -20,7 +20,7 @@ namespace AM { * 1 : Result, 0 on success, otherwise error code * 2 : The number of titles in the requested media type */ -void GetTitleCount(Service::Interface* self); +void GetNumPrograms(Service::Interface* self); /** * AM::FindContentInfos service function @@ -62,7 +62,7 @@ void ListContentInfos(Service::Interface* self); void DeleteContents(Service::Interface* self); /** - * AM::GetTitleList service function + * AM::GetProgramList service function * Loads information about the desired number of titles from the desired media type into an array * Inputs: * 1 : Title count @@ -72,10 +72,10 @@ void DeleteContents(Service::Interface* self); * 1 : Result, 0 on success, otherwise error code * 2 : The number of titles loaded from the requested media type */ -void GetTitleList(Service::Interface* self); +void GetProgramList(Service::Interface* self); /** - * AM::GetTitleInfo service function + * AM::GetProgramInfos service function * Inputs: * 1 : u8 Mediatype * 2 : Total titles @@ -84,11 +84,11 @@ void GetTitleList(Service::Interface* self); * Outputs: * 1 : Result, 0 on success, otherwise error code */ -void GetTitleInfo(Service::Interface* self); +void GetProgramInfos(Service::Interface* self); /** * AM::GetDataTitleInfos service function - * Wrapper for AM::GetTitleInfo + * Wrapper for AM::GetProgramInfos * Inputs: * 1 : u8 Mediatype * 2 : Total titles @@ -135,12 +135,12 @@ void GetNumContentInfos(Service::Interface* self); void DeleteTicket(Service::Interface* self); /** - * AM::GetTicketCount service function + * AM::GetNumTickets service function * Outputs: * 1 : Result, 0 on success, otherwise error code - * 2 : Total titles + * 2 : Number of tickets */ -void GetTicketCount(Service::Interface* self); +void GetNumTickets(Service::Interface* self); /** * AM::GetTicketList service function diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index bfc1ca6bd..218375c8f 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -14,9 +14,14 @@ const Interface::FunctionInfo FunctionTable[] = { {0x10030142, ListContentInfos, "ListContentInfos"}, {0x10040102, DeleteContents, "DeleteContents"}, {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"}, + {0x10060080, nullptr, "GetNumDataTitleTickets"}, {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"}, + {0x100801C2, nullptr, "GetItemRights"}, {0x100900C0, nullptr, "IsDataTitleInUse"}, {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, + {0x100B00C0, nullptr, "GetNumExistingContentInfos"}, + {0x100C0142, nullptr, "ListExistingContentInfos"}, + {0x100D0084, nullptr, "GetPatchTitleInfos"}, }; AM_APP_Interface::AM_APP_Interface() { diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index 3a597a34c..f3cd1d23f 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -9,61 +9,116 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetTitleCount, "GetTitleCount"}, - {0x00020082, GetTitleList, "GetTitleList"}, - {0x00030084, GetTitleInfo, "GetTitleInfo"}, - {0x000400C0, nullptr, "DeleteApplicationTitle"}, - {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00010040, GetNumPrograms, "GetNumPrograms"}, + {0x00020082, GetProgramList, "GetProgramList"}, + {0x00030084, GetProgramInfos, "GetProgramInfos"}, + {0x000400C0, nullptr, "DeleteUserProgram"}, + {0x000500C0, nullptr, "GetProductCode"}, + {0x000600C0, nullptr, "GetStorageId"}, {0x00070080, DeleteTicket, "DeleteTicket"}, - {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00080000, GetNumTickets, "GetNumTickets"}, {0x00090082, GetTicketList, "GetTicketList"}, {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "GetPendingTitleInfo"}, - {0x000E00C0, nullptr, "DeletePendingTitle"}, - {0x00140040, nullptr, "FinalizePendingTitles"}, - {0x00150040, nullptr, "DeleteAllPendingTitles"}, + {0x000B0040, nullptr, "GetNumImportTitleContexts"}, + {0x000C0082, nullptr, "GetImportTitleContextList"}, + {0x000D0084, nullptr, "GetImportTitleContexts"}, + {0x000E00C0, nullptr, "DeleteImportTitleContext"}, + {0x000F00C0, nullptr, "GetNumImportContentContexts"}, + {0x00100102, nullptr, "GetImportContentContextList"}, + {0x00110104, nullptr, "GetImportContentContexts"}, + {0x00120102, nullptr, "DeleteImportContentContexts"}, + {0x00130040, nullptr, "NeedsCleanup"}, + {0x00140040, nullptr, "DoCleanup"}, + {0x00150040, nullptr, "DeleteAllImportContexts"}, + {0x00160000, nullptr, "DeleteAllTemporaryPrograms"}, + {0x00170044, nullptr, "ImportTwlBackupLegacy"}, {0x00180080, nullptr, "InitializeTitleDatabase"}, - {0x00190040, nullptr, "ReloadDBS"}, - {0x001A00C0, nullptr, "GetDSiWareExportSize"}, - {0x001B0144, nullptr, "ExportDSiWare"}, - {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "TitleIDListGetTotal2"}, - {0x002400C2, nullptr, "GetTitleIDList2"}, - {0x04010080, nullptr, "InstallFIRM"}, - {0x04020040, nullptr, "StartInstallCIADB0"}, - {0x04030000, nullptr, "StartInstallCIADB1"}, - {0x04040002, nullptr, "AbortCIAInstall"}, - {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, - {0x04060002, nullptr, "CloseCIA"}, - {0x040700C2, nullptr, "FinalizeTitlesInstall"}, - {0x04080042, nullptr, "GetCiaFileInfo"}, - {0x040E00C2, nullptr, "InstallTitlesFinish"}, - {0x040F0000, nullptr, "InstallNATIVEFIRM"}, - {0x041000C0, nullptr, "DeleteTitle"}, - {0x04120000, nullptr, "Initialize"}, - {0x041700C0, nullptr, "MigrateAGBtoSAV"}, - {0x08010000, nullptr, "OpenTicket"}, - {0x08020002, nullptr, "TicketAbortInstall"}, - {0x08030002, nullptr, "TicketFinalizeInstall"}, - {0x08040100, nullptr, "InstallTitleBegin"}, - {0x08050000, nullptr, "InstallTitleAbort"}, - {0x080600C0, nullptr, "InstallTitleResume"}, - {0x08070000, nullptr, "InstallTitleAbortTMD"}, - {0x08080000, nullptr, "InstallTitleFinish"}, - {0x080A0000, nullptr, "OpenTMD"}, - {0x080B0002, nullptr, "TMDAbortInstall"}, - {0x080C0042, nullptr, "TMDFinalizeInstall"}, - {0x080E0040, nullptr, "OpenContentCreate"}, - {0x080F0002, nullptr, "ContentAbortInstall"}, - {0x08100040, nullptr, "OpenContentResume"}, - {0x08120002, nullptr, "ContentFinalizeInstall"}, - {0x08130000, nullptr, "GetTotalContents"}, - {0x08140042, nullptr, "GetContentIndexes"}, - {0x08150044, nullptr, "GetContentsInfo"}, - {0x08180042, nullptr, "GetCTCert"}, - {0x08190108, nullptr, "SetCertificates"}, - {0x081B00C2, nullptr, "InstallTitlesFinish"}, + {0x00190040, nullptr, "QueryAvailableTitleDatabase"}, + {0x001A00C0, nullptr, "CalcTwlBackupSize"}, + {0x001B0144, nullptr, "ExportTwlBackup"}, + {0x001C0084, nullptr, "ImportTwlBackup"}, + {0x001D0000, nullptr, "DeleteAllTwlUserPrograms"}, + {0x001E00C8, nullptr, "ReadTwlBackupInfo"}, + {0x001F0040, nullptr, "DeleteAllExpiredUserPrograms"}, + {0x00200000, nullptr, "GetTwlArchiveResourceInfo"}, + {0x00210042, nullptr, "GetPersonalizedTicketInfoList"}, + {0x00220080, nullptr, "DeleteAllImportContextsFiltered"}, + {0x00230080, nullptr, "GetNumImportTitleContextsFiltered"}, + {0x002400C2, nullptr, "GetImportTitleContextListFiltered"}, + {0x002500C0, nullptr, "CheckContentRights"}, + {0x00260044, nullptr, "GetTicketLimitInfos"}, + {0x00270044, nullptr, "GetDemoLaunchInfos"}, + {0x00280108, nullptr, "ReadTwlBackupInfoEx"}, + {0x00290082, nullptr, "DeleteUserProgramsAtomically"}, + {0x002A00C0, nullptr, "GetNumExistingContentInfosSystem"}, + {0x002B0142, nullptr, "ListExistingContentInfosSystem"}, + {0x002C0084, nullptr, "GetProgramInfosIgnorePlatform"}, + {0x002D00C0, nullptr, "CheckContentRightsIgnorePlatform"}, + {0x04010080, nullptr, "UpdateFirmwareTo"}, + {0x04020040, nullptr, "BeginImportProgram"}, + {0x04030000, nullptr, "BeginImportProgramTemporarily"}, + {0x04040002, nullptr, "CancelImportProgram"}, + {0x04050002, nullptr, "EndImportProgram"}, + {0x04060002, nullptr, "EndImportProgramWithoutCommit"}, + {0x040700C2, nullptr, "CommitImportPrograms"}, + {0x04080042, nullptr, "GetProgramInfoFromCia"}, + {0x04090004, nullptr, "GetSystemMenuDataFromCia"}, + {0x040A0002, nullptr, "GetDependencyListFromCia"}, + {0x040B0002, nullptr, "GetTransferSizeFromCia"}, + {0x040C0002, nullptr, "GetCoreVersionFromCia"}, + {0x040D0042, nullptr, "GetRequiredSizeFromCia"}, + {0x040E00C2, nullptr, "CommitImportProgramsAndUpdateFirmwareAuto"}, + {0x040F0000, nullptr, "UpdateFirmwareAuto"}, + {0x041000C0, nullptr, "DeleteProgram"}, + {0x04110044, nullptr, "GetTwlProgramListForReboot"}, + {0x04120000, nullptr, "GetSystemUpdaterMutex"}, + {0x04130002, nullptr, "GetMetaSizeFromCia"}, + {0x04140044, nullptr, "GetMetaDataFromCia"}, + {0x04150080, nullptr, "CheckDemoLaunchRights"}, + {0x041600C0, nullptr, "GetInternalTitleLocationInfo"}, + {0x041700C0, nullptr, "PerpetuateAgbSaveData"}, + {0x04180040, nullptr, "BeginImportProgramForOverWrite"}, + {0x04190000, nullptr, "BeginImportSystemProgram"}, + {0x08010000, nullptr, "BeginImportTicket"}, + {0x08020002, nullptr, "CancelImportTicket"}, + {0x08030002, nullptr, "EndImportTicket"}, + {0x08040100, nullptr, "BeginImportTitle"}, + {0x08050000, nullptr, "StopImportTitle"}, + {0x080600C0, nullptr, "ResumeImportTitle"}, + {0x08070000, nullptr, "CancelImportTitle"}, + {0x08080000, nullptr, "EndImportTitle"}, + {0x080900C2, nullptr, "CommitImportTitles"}, + {0x080A0000, nullptr, "BeginImportTmd"}, + {0x080B0002, nullptr, "CancelImportTmd"}, + {0x080C0042, nullptr, "EndImportTmd"}, + {0x080D0042, nullptr, "CreateImportContentContexts"}, + {0x080E0040, nullptr, "BeginImportContent"}, + {0x080F0002, nullptr, "StopImportContent"}, + {0x08100040, nullptr, "ResumeImportContent"}, + {0x08110002, nullptr, "CancelImportContent"}, + {0x08120002, nullptr, "EndImportContent"}, + {0x08130000, nullptr, "GetNumCurrentImportContentContexts"}, + {0x08140042, nullptr, "GetCurrentImportContentContextList"}, + {0x08150044, nullptr, "GetCurrentImportContentContexts"}, + {0x08160146, nullptr, "Sign"}, + {0x08170146, nullptr, "Verify"}, + {0x08180042, nullptr, "GetDeviceCert"}, + {0x08190108, nullptr, "ImportCertificates"}, + {0x081A0042, nullptr, "ImportCertificate"}, + {0x081B00C2, nullptr, "CommitImportTitlesAndUpdateFirmwareAuto"}, + {0x081C0100, nullptr, "DeleteTicketId"}, + {0x081D0080, nullptr, "GetNumTicketIds"}, + {0x081E0102, nullptr, "GetTicketIdList"}, + {0x081F0080, nullptr, "GetNumTicketsOfProgram"}, + {0x08200102, nullptr, "ListTicketInfos"}, + {0x08210142, nullptr, "GetRightsOnlyTicketData"}, + {0x08220000, nullptr, "GetNumCurrentContentInfos"}, + {0x08230044, nullptr, "FindCurrentContentInfos"}, + {0x08240082, nullptr, "ListCurrentContentInfos"}, + {0x08250102, nullptr, "CalculateContextRequiredSize"}, + {0x08260042, nullptr, "UpdateImportContentContexts"}, + {0x08270000, nullptr, "DeleteAllDemoLaunchInfos"}, + {0x082800C0, nullptr, "BeginImportTitleForOverWrite"}, }; AM_NET_Interface::AM_NET_Interface() { diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index a2268303c..949b3591d 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -9,27 +9,64 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetTitleCount, "GetTitleCount"}, - {0x00020082, GetTitleList, "GetTitleList"}, - {0x00030084, GetTitleInfo, "GetTitleInfo"}, - {0x000400C0, nullptr, "DeleteApplicationTitle"}, - {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00010040, GetNumPrograms, "GetNumPrograms"}, + {0x00020082, GetProgramList, "GetProgramList"}, + {0x00030084, GetProgramInfos, "GetProgramInfos"}, + {0x000400C0, nullptr, "DeleteUserProgram"}, + {0x000500C0, nullptr, "GetProductCode"}, + {0x000600C0, nullptr, "GetStorageId"}, {0x00070080, DeleteTicket, "DeleteTicket"}, - {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00080000, GetNumTickets, "GetNumTickets"}, {0x00090082, GetTicketList, "GetTicketList"}, {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "GetPendingTitleInfo"}, - {0x000E00C0, nullptr, "DeletePendingTitle"}, - {0x00140040, nullptr, "FinalizePendingTitles"}, - {0x00150040, nullptr, "DeleteAllPendingTitles"}, + {0x000B0040, nullptr, "GetNumImportTitleContexts"}, + {0x000C0082, nullptr, "GetImportTitleContextList"}, + {0x000D0084, nullptr, "GetImportTitleContexts"}, + {0x000E00C0, nullptr, "DeleteImportTitleContext"}, + {0x000F00C0, nullptr, "GetNumImportContentContexts"}, + {0x00100102, nullptr, "GetImportContentContextList"}, + {0x00110104, nullptr, "GetImportContentContexts"}, + {0x00120102, nullptr, "DeleteImportContentContexts"}, + {0x00130040, nullptr, "NeedsCleanup"}, + {0x00140040, nullptr, "DoCleanup"}, + {0x00150040, nullptr, "DeleteAllImportContexts"}, + {0x00160000, nullptr, "DeleteAllTemporaryPrograms"}, + {0x00170044, nullptr, "ImportTwlBackupLegacy"}, {0x00180080, nullptr, "InitializeTitleDatabase"}, - {0x00190040, nullptr, "ReloadDBS"}, - {0x001A00C0, nullptr, "GetDSiWareExportSize"}, - {0x001B0144, nullptr, "ExportDSiWare"}, - {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "GetPendingTitleCount"}, - {0x002400C2, nullptr, "GetPendingTitleList"}, + {0x00190040, nullptr, "QueryAvailableTitleDatabase"}, + {0x001A00C0, nullptr, "CalcTwlBackupSize"}, + {0x001B0144, nullptr, "ExportTwlBackup"}, + {0x001C0084, nullptr, "ImportTwlBackup"}, + {0x001D0000, nullptr, "DeleteAllTwlUserPrograms"}, + {0x001E00C8, nullptr, "ReadTwlBackupInfo"}, + {0x001F0040, nullptr, "DeleteAllExpiredUserPrograms"}, + {0x00200000, nullptr, "GetTwlArchiveResourceInfo"}, + {0x00210042, nullptr, "GetPersonalizedTicketInfoList"}, + {0x00220080, nullptr, "DeleteAllImportContextsFiltered"}, + {0x00230080, nullptr, "GetNumImportTitleContextsFiltered"}, + {0x002400C2, nullptr, "GetImportTitleContextListFiltered"}, + {0x002500C0, nullptr, "CheckContentRights"}, + {0x00260044, nullptr, "GetTicketLimitInfos"}, + {0x00270044, nullptr, "GetDemoLaunchInfos"}, + {0x00280108, nullptr, "ReadTwlBackupInfoEx"}, + {0x00290082, nullptr, "DeleteUserProgramsAtomically"}, + {0x002A00C0, nullptr, "GetNumExistingContentInfosSystem"}, + {0x002B0142, nullptr, "ListExistingContentInfosSystem"}, + {0x002C0084, nullptr, "GetProgramInfosIgnorePlatform"}, + {0x002D00C0, nullptr, "CheckContentRightsIgnorePlatform"}, + {0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, + {0x10020104, FindContentInfos, "FindContentInfos"}, + {0x10030142, ListContentInfos, "ListContentInfos"}, + {0x10040102, DeleteContents, "DeleteContents"}, + {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"}, + {0x10060080, nullptr, "GetNumDataTitleTickets"}, + {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"}, + {0x100801C2, nullptr, "GetItemRights"}, + {0x100900C0, nullptr, "IsDataTitleInUse"}, + {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, + {0x100B00C0, nullptr, "GetNumExistingContentInfos"}, + {0x100C0142, nullptr, "ListExistingContentInfos"}, + {0x100D0084, nullptr, "GetPatchTitleInfos"}, }; AM_SYS_Interface::AM_SYS_Interface() { diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index 151b5e42b..354d51610 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -9,40 +9,76 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetTitleCount, "GetTitleCount"}, - {0x00020082, GetTitleList, "GetTitleList"}, - {0x00030084, GetTitleInfo, "GetTitleInfo"}, - {0x000400C0, nullptr, "DeleteApplicationTitle"}, - {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00010040, GetNumPrograms, "GetNumPrograms"}, + {0x00020082, GetProgramList, "GetProgramList"}, + {0x00030084, GetProgramInfos, "GetProgramInfos"}, + {0x000400C0, nullptr, "DeleteUserProgram"}, + {0x000500C0, nullptr, "GetProductCode"}, + {0x000600C0, nullptr, "GetStorageId"}, {0x00070080, DeleteTicket, "DeleteTicket"}, - {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00080000, GetNumTickets, "GetNumTickets"}, {0x00090082, GetTicketList, "GetTicketList"}, {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "GetPendingTitleInfo"}, - {0x000E00C0, nullptr, "DeletePendingTitle"}, - {0x00140040, nullptr, "FinalizePendingTitles"}, - {0x00150040, nullptr, "DeleteAllPendingTitles"}, + {0x000B0040, nullptr, "GetNumImportTitleContexts"}, + {0x000C0082, nullptr, "GetImportTitleContextList"}, + {0x000D0084, nullptr, "GetImportTitleContexts"}, + {0x000E00C0, nullptr, "DeleteImportTitleContext"}, + {0x000F00C0, nullptr, "GetNumImportContentContexts"}, + {0x00100102, nullptr, "GetImportContentContextList"}, + {0x00110104, nullptr, "GetImportContentContexts"}, + {0x00120102, nullptr, "DeleteImportContentContexts"}, + {0x00130040, nullptr, "NeedsCleanup"}, + {0x00140040, nullptr, "DoCleanup"}, + {0x00150040, nullptr, "DeleteAllImportContexts"}, + {0x00160000, nullptr, "DeleteAllTemporaryPrograms"}, + {0x00170044, nullptr, "ImportTwlBackupLegacy"}, {0x00180080, nullptr, "InitializeTitleDatabase"}, - {0x00190040, nullptr, "ReloadDBS"}, - {0x001A00C0, nullptr, "GetDSiWareExportSize"}, - {0x001B0144, nullptr, "ExportDSiWare"}, - {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "TitleIDListGetTotal2"}, - {0x002400C2, nullptr, "GetTitleIDList2"}, - {0x04010080, nullptr, "InstallFIRM"}, - {0x04020040, nullptr, "StartInstallCIADB0"}, - {0x04030000, nullptr, "StartInstallCIADB1"}, - {0x04040002, nullptr, "AbortCIAInstall"}, - {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, - {0x04060002, nullptr, "CloseCIA"}, - {0x040700C2, nullptr, "FinalizeTitlesInstall"}, - {0x04080042, nullptr, "GetCiaFileInfo"}, - {0x040E00C2, nullptr, "InstallTitlesFinish"}, - {0x040F0000, nullptr, "InstallNATIVEFIRM"}, - {0x041000C0, nullptr, "DeleteTitle"}, - {0x04120000, nullptr, "Initialize"}, - {0x041700C0, nullptr, "MigrateAGBtoSAV"}, + {0x00190040, nullptr, "QueryAvailableTitleDatabase"}, + {0x001A00C0, nullptr, "CalcTwlBackupSize"}, + {0x001B0144, nullptr, "ExportTwlBackup"}, + {0x001C0084, nullptr, "ImportTwlBackup"}, + {0x001D0000, nullptr, "DeleteAllTwlUserPrograms"}, + {0x001E00C8, nullptr, "ReadTwlBackupInfo"}, + {0x001F0040, nullptr, "DeleteAllExpiredUserPrograms"}, + {0x00200000, nullptr, "GetTwlArchiveResourceInfo"}, + {0x00210042, nullptr, "GetPersonalizedTicketInfoList"}, + {0x00220080, nullptr, "DeleteAllImportContextsFiltered"}, + {0x00230080, nullptr, "GetNumImportTitleContextsFiltered"}, + {0x002400C2, nullptr, "GetImportTitleContextListFiltered"}, + {0x002500C0, nullptr, "CheckContentRights"}, + {0x00260044, nullptr, "GetTicketLimitInfos"}, + {0x00270044, nullptr, "GetDemoLaunchInfos"}, + {0x00280108, nullptr, "ReadTwlBackupInfoEx"}, + {0x00290082, nullptr, "DeleteUserProgramsAtomically"}, + {0x002A00C0, nullptr, "GetNumExistingContentInfosSystem"}, + {0x002B0142, nullptr, "ListExistingContentInfosSystem"}, + {0x002C0084, nullptr, "GetProgramInfosIgnorePlatform"}, + {0x002D00C0, nullptr, "CheckContentRightsIgnorePlatform"}, + {0x04010080, nullptr, "UpdateFirmwareTo"}, + {0x04020040, nullptr, "BeginImportProgram"}, + {0x04030000, nullptr, "BeginImportProgramTemporarily"}, + {0x04040002, nullptr, "CancelImportProgram"}, + {0x04050002, nullptr, "EndImportProgram"}, + {0x04060002, nullptr, "EndImportProgramWithoutCommit"}, + {0x040700C2, nullptr, "CommitImportPrograms"}, + {0x04080042, nullptr, "GetProgramInfoFromCia"}, + {0x04090004, nullptr, "GetSystemMenuDataFromCia"}, + {0x040A0002, nullptr, "GetDependencyListFromCia"}, + {0x040B0002, nullptr, "GetTransferSizeFromCia"}, + {0x040C0002, nullptr, "GetCoreVersionFromCia"}, + {0x040D0042, nullptr, "GetRequiredSizeFromCia"}, + {0x040E00C2, nullptr, "CommitImportProgramsAndUpdateFirmwareAuto"}, + {0x040F0000, nullptr, "UpdateFirmwareAuto"}, + {0x041000C0, nullptr, "DeleteProgram"}, + {0x04110044, nullptr, "GetTwlProgramListForReboot"}, + {0x04120000, nullptr, "GetSystemUpdaterMutex"}, + {0x04130002, nullptr, "GetMetaSizeFromCia"}, + {0x04140044, nullptr, "GetMetaDataFromCia"}, + {0x04150080, nullptr, "CheckDemoLaunchRights"}, + {0x041600C0, nullptr, "GetInternalTitleLocationInfo"}, + {0x041700C0, nullptr, "PerpetuateAgbSaveData"}, + {0x04180040, nullptr, "BeginImportProgramForOverWrite"}, + {0x04190000, nullptr, "BeginImportSystemProgram"}, }; AM_U_Interface::AM_U_Interface() { diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 31e5e07b2..615fe31ea 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -458,12 +458,16 @@ void GetStartupArgument(Service::Interface* self) { return; } - LOG_WARNING(Service_APT, "(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , " - "parameter_value=0x%08x", - startup_argument_type, parameter_size, Memory::Read32(cmd_buff[41])); + u32 addr = cmd_buff[65]; + if (addr && parameter_size) { + Memory::ZeroBlock(addr, parameter_size); + } + + LOG_WARNING(Service_APT, "(stubbed) called startup_argument_type=%u , parameter_size=0x%08x", + startup_argument_type, parameter_size); cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = (parameter_size > 0) ? 1 : 0; + cmd_buff[2] = 0; } void CheckNew3DSApp(Service::Interface* self) { diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index bcc437f93..80325361f 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -410,9 +410,11 @@ void CancelLibraryApplet(Service::Interface* self); * Inputs: * 1 : Parameter Size (capped to 0x300) * 2 : StartupArgumentType + * 65 : Output buffer for startup argument * Outputs: * 0 : Return header - * 1 : u8, Exists (0 = does not exist, 1 = exists) + * 1 : Result of function, 0 on success, otherwise error code + * 2 : u8, Exists (0 = does not exist, 1 = exists) */ void GetStartupArgument(Service::Interface* self); diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 7f37a7f54..62dc2d61d 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -9,34 +9,97 @@ namespace Service { namespace APT { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle?"}, - {0x00020080, Initialize, "Initialize?"}, - {0x00030040, Enable, "Enable?"}, - {0x00040040, nullptr, "Finalize?"}, + {0x00010040, GetLockHandle, "GetLockHandle"}, + {0x00020080, Initialize, "Initialize"}, + {0x00030040, Enable, "Enable"}, + {0x00040040, nullptr, "Finalize"}, {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, {0x00060040, GetAppletInfo, "GetAppletInfo"}, + {0x00070000, nullptr, "GetLastSignaledAppletId"}, + {0x00080000, nullptr, "CountRegisteredApplet"}, {0x00090040, IsRegistered, "IsRegistered"}, + {0x000A0040, nullptr, "GetAttribute"}, {0x000B0040, InquireNotification, "InquireNotification"}, {0x000C0104, SendParameter, "SendParameter"}, {0x000D0080, ReceiveParameter, "ReceiveParameter"}, {0x000E0080, GlanceParameter, "GlanceParameter"}, {0x000F0100, CancelParameter, "CancelParameter"}, + {0x001000C2, nullptr, "DebugFunc"}, + {0x001100C0, nullptr, "MapProgramIdForDebug"}, + {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, nullptr, "GetPreparationState"}, + {0x00140040, nullptr, "SetPreparationState"}, {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x00190040, nullptr, "PrepareToStartSystemApplet"}, + {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, nullptr, "StartApplication"}, + {0x001C0000, nullptr, "WakeupApplication"}, + {0x001D0000, nullptr, "CancelApplication"}, {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, + {0x001F0084, nullptr, "StartSystemApplet"}, + {0x00200044, nullptr, "StartNewestHomeMenu"}, + {0x00210000, nullptr, "OrderToCloseApplication"}, + {0x00220040, nullptr, "PrepareToCloseApplication"}, + {0x00230040, nullptr, "PrepareToJumpToApplication"}, + {0x00240044, nullptr, "JumpToApplication"}, + {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, + {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, + {0x00270044, nullptr, "CloseApplication"}, + {0x00280044, nullptr, "CloseLibraryApplet"}, + {0x00290044, nullptr, "CloseSystemApplet"}, + {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, + {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, + {0x002C0044, nullptr, "JumpToHomeMenu"}, + {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, + {0x002E0044, nullptr, "LeaveHomeMenu"}, + {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, + {0x00300044, nullptr, "LeaveResidentApplet"}, + {0x00310100, nullptr, "PrepareToDoApplicationJump"}, + {0x00320084, nullptr, "DoApplicationJump"}, + {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, + {0x00340084, nullptr, "SendDeliverArg"}, + {0x00350080, nullptr, "ReceiveDeliverArg"}, + {0x00360040, nullptr, "LoadSysMenuArg"}, + {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00380040, nullptr, "PreloadResidentApplet"}, + {0x00390040, nullptr, "PrepareToStartResidentApplet"}, + {0x003A0044, nullptr, "StartResidentApplet"}, {0x003B0040, CancelLibraryApplet, "CancelLibraryApplet"}, + {0x003C0042, nullptr, "SendDspSleep"}, + {0x003D0042, nullptr, "SendDspWakeUp"}, {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x00430040, NotifyToWait, "NotifyToWait?"}, - {0x00440000, GetSharedFont, "GetSharedFont?"}, - {0x004B00C2, AppletUtility, "AppletUtility?"}, + {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, + {0x00400042, nullptr, "SendCaptureBufferInfo"}, + {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, + {0x00420080, nullptr, "SleepSystem"}, + {0x00430040, NotifyToWait, "NotifyToWait"}, + {0x00440000, GetSharedFont, "GetSharedFont"}, + {0x00450040, nullptr, "GetWirelessRebootInfo"}, + {0x00460104, nullptr, "Wrap"}, + {0x00470104, nullptr, "Unwrap"}, + {0x00480100, nullptr, "GetProgramInfo"}, + {0x00490180, nullptr, "Reboot"}, + {0x004A0040, nullptr, "GetCaptureInfo"}, + {0x004B00C2, AppletUtility, "AppletUtility"}, + {0x004C0000, nullptr, "SetFatalErrDispMode"}, + {0x004D0080, nullptr, "GetAppletProgramInfo"}, + {0x004E0000, nullptr, "HardwareResetAsync"}, {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, {0x00510080, GetStartupArgument, "GetStartupArgument"}, + {0x00520104, nullptr, "Wrap1"}, + {0x00530104, nullptr, "Unwrap1"}, {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x00570044, nullptr, "WakeupApplication2"}, + {0x00580002, nullptr, "GetProgramID"}, {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, {0x01020000, CheckNew3DS, "CheckNew3DS"}, + {0x01040000, nullptr, "IsStandardMemoryLayout"}, + {0x01050100, nullptr, "IsTitleAllowed"}, }; APT_A_Interface::APT_A_Interface() : Interface(MaxAPTSessions) { diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 933f26e60..effd23dce 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -94,9 +94,12 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00530104, nullptr, "Unwrap1"}, {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x00570044, nullptr, "WakeupApplication2"}, {0x00580002, nullptr, "GetProgramID"}, {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, {0x01020000, CheckNew3DS, "CheckNew3DS"}, + {0x01040000, nullptr, "IsStandardMemoryLayout"}, + {0x01050100, nullptr, "IsTitleAllowed"}, }; APT_S_Interface::APT_S_Interface() : Interface(MaxAPTSessions) { diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index dfee8d055..ee941e228 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -2,16 +2,81 @@ // 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_p.h" namespace Service { namespace BOSS { -// Empty arrays are illegal -- commented out until an entry is added. -// const Interface::FunctionInfo FunctionTable[] = { }; +const Interface::FunctionInfo FunctionTable[] = { + // boss:u shared commands + {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:p + {0x04040080, nullptr, "GetAppNewFlag"}, + {0x04130082, nullptr, "SendPropertyPrivileged"}, + {0x041500C0, nullptr, "DeleteNsDataPrivileged"}, + {0x04160142, nullptr, "GetNsDataHeaderInfoPrivileged"}, + {0x04170182, nullptr, "ReadNsDataPrivileged"}, + {0x041A0100, nullptr, "SetNsDataNewFlagPrivileged"}, + {0x041B00C0, nullptr, "GetNsDataNewFlagPrivileged"}, +}; BOSS_P_Interface::BOSS_P_Interface() { - // Register(FunctionTable); + Register(FunctionTable); } } // namespace BOSS diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp index 4b747de7b..7d98ba6e9 100644 --- a/src/core/hle/service/cecd/cecd_u.cpp +++ b/src/core/hle/service/cecd/cecd_u.cpp @@ -9,10 +9,22 @@ namespace Service { namespace CECD { static const Interface::FunctionInfo FunctionTable[] = { + {0x000100C2, nullptr, "OpenRawFile"}, + {0x00020042, nullptr, "ReadRawFile"}, + {0x00030104, nullptr, "ReadMessage"}, + {0x00040106, nullptr, "ReadMessageWithHMAC"}, + {0x00050042, nullptr, "WriteRawFile"}, + {0x00060104, nullptr, "WriteMessage"}, + {0x00070106, nullptr, "WriteMessageWithHMAC"}, + {0x00080102, nullptr, "Delete"}, + {0x000A00C4, nullptr, "GetSystemInfo"}, + {0x000B0040, nullptr, "RunCommand"}, + {0x000C0040, nullptr, "RunCommandAlt"}, {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"}, {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"}, {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"}, - {0x00120104, nullptr, "ReadSavedData"}, + {0x00110104, nullptr, "OpenAndWrite"}, + {0x00120104, nullptr, "OpenAndRead"}, }; CECD_U_Interface::CECD_U_Interface() { diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index d554c3f54..65655f45d 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -12,6 +12,7 @@ #include "core/hle/result.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" +#include "core/hle/service/cfg/cfg_nor.h" #include "core/hle/service/cfg/cfg_s.h" #include "core/hle/service/cfg/cfg_u.h" #include "core/hle/service/fs/archive.h" @@ -528,9 +529,10 @@ ResultCode LoadConfigNANDSaveFile() { } void Init() { - AddService(new CFG_I_Interface); - AddService(new CFG_S_Interface); - AddService(new CFG_U_Interface); + AddService(new CFG_I); + AddService(new CFG_NOR); + AddService(new CFG_S); + AddService(new CFG_U); LoadConfigNANDSaveFile(); } diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 2ff52c8b8..e8db0fc42 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -20,6 +20,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00080080, nullptr, "GoThroughTable"}, {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, + {0x000B0000, nullptr, "IsFangateSupported"}, // cfg:i {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, @@ -55,7 +56,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x08180042, nullptr, "SecureInfoGetSerialNo"}, }; -CFG_I_Interface::CFG_I_Interface() { +CFG_I::CFG_I() { Register(FunctionTable); } diff --git a/src/core/hle/service/cfg/cfg_i.h b/src/core/hle/service/cfg/cfg_i.h index d0a2cce39..8cfd47633 100644 --- a/src/core/hle/service/cfg/cfg_i.h +++ b/src/core/hle/service/cfg/cfg_i.h @@ -9,9 +9,9 @@ namespace Service { namespace CFG { -class CFG_I_Interface : public Service::Interface { +class CFG_I final : public Interface { public: - CFG_I_Interface(); + CFG_I(); std::string GetPortName() const override { return "cfg:i"; diff --git a/src/core/hle/service/cfg/cfg_nor.cpp b/src/core/hle/service/cfg/cfg_nor.cpp new file mode 100644 index 000000000..4ce02d115 --- /dev/null +++ b/src/core/hle/service/cfg/cfg_nor.cpp @@ -0,0 +1,23 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/cfg/cfg.h" +#include "core/hle/service/cfg/cfg_nor.h" + +namespace Service { +namespace CFG { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010040, nullptr, "Initialize"}, + {0x00020000, nullptr, "Shutdown"}, + {0x00050082, nullptr, "ReadData"}, + {0x00060082, nullptr, "WriteData"}, +}; + +CFG_NOR::CFG_NOR() { + Register(FunctionTable); +} + +} // namespace CFG +} // namespace Service diff --git a/src/core/hle/service/cfg/cfg_nor.h b/src/core/hle/service/cfg/cfg_nor.h new file mode 100644 index 000000000..c337718e7 --- /dev/null +++ b/src/core/hle/service/cfg/cfg_nor.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace CFG { + +class CFG_NOR final : public Interface { +public: + CFG_NOR(); + + std::string GetPortName() const override { + return "cfg:nor"; + } +}; + +} // namespace CFG +} // namespace Service diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index eed26dec7..9386fe33d 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -20,6 +20,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00080080, nullptr, "GoThroughTable"}, {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, + {0x000B0000, nullptr, "IsFangateSupported"}, // cfg:s {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, @@ -32,7 +33,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x04090000, nullptr, "UpdateConfigBlk00040003"}, }; -CFG_S_Interface::CFG_S_Interface() { +CFG_S::CFG_S() { Register(FunctionTable); } diff --git a/src/core/hle/service/cfg/cfg_s.h b/src/core/hle/service/cfg/cfg_s.h index 5568d6485..99fea46ee 100644 --- a/src/core/hle/service/cfg/cfg_s.h +++ b/src/core/hle/service/cfg/cfg_s.h @@ -9,9 +9,9 @@ namespace Service { namespace CFG { -class CFG_S_Interface : public Service::Interface { +class CFG_S final : public Interface { public: - CFG_S_Interface(); + CFG_S(); std::string GetPortName() const override { return "cfg:s"; diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index f28217134..7b66fee22 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -20,9 +20,10 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00080080, nullptr, "GoThroughTable"}, {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, + {0x000B0000, nullptr, "IsFangateSupported"}, }; -CFG_U_Interface::CFG_U_Interface() { +CFG_U::CFG_U() { Register(FunctionTable); } diff --git a/src/core/hle/service/cfg/cfg_u.h b/src/core/hle/service/cfg/cfg_u.h index 5303d8ac6..fc7844714 100644 --- a/src/core/hle/service/cfg/cfg_u.h +++ b/src/core/hle/service/cfg/cfg_u.h @@ -9,9 +9,9 @@ namespace Service { namespace CFG { -class CFG_U_Interface : public Service::Interface { +class CFG_U final : public Interface { public: - CFG_U_Interface(); + CFG_U(); std::string GetPortName() const override { return "cfg:u"; diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index 20c759ad7..6544e89a2 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp @@ -9,10 +9,8 @@ #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/csnd_snd.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace CSND_SND - -namespace CSND_SND { +namespace Service { +namespace CSND { const Interface::FunctionInfo FunctionTable[] = { {0x00010140, Initialize, "Initialize"}, @@ -29,17 +27,14 @@ const Interface::FunctionInfo FunctionTable[] = { {0x000C0000, nullptr, "Reset"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +CSND_SND::CSND_SND() { Register(FunctionTable); } static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr; static Kernel::SharedPtr<Kernel::Mutex> mutex = nullptr; -void Initialize(Service::Interface* self) { +void Initialize(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 size = Common::AlignUp(cmd_buff[1], Memory::PAGE_SIZE); @@ -56,7 +51,7 @@ void Initialize(Service::Interface* self) { cmd_buff[4] = Kernel::g_handle_table.Create(shared_memory).MoveFrom(); } -void ExecuteType0Commands(Service::Interface* self) { +void ExecuteType0Commands(Interface* self) { u32* const cmd_buff = Kernel::GetCommandBuffer(); u8* const ptr = shared_memory->GetPointer(cmd_buff[1]); @@ -74,15 +69,16 @@ void ExecuteType0Commands(Service::Interface* self) { } } -void AcquireSoundChannels(Service::Interface* self) { +void AcquireSoundChannels(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = 0; cmd_buff[2] = 0xFFFFFF00; } -void Shutdown(Service::Interface* self) { +void Shutdown(Interface* self) { shared_memory = nullptr; mutex = nullptr; } -} // namespace +} // namespace CSND +} // namespace Service diff --git a/src/core/hle/service/csnd_snd.h b/src/core/hle/service/csnd_snd.h index a146d116b..c8d83fa7d 100644 --- a/src/core/hle/service/csnd_snd.h +++ b/src/core/hle/service/csnd_snd.h @@ -6,14 +6,12 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace CSND_SND +namespace Service { +namespace CSND { -namespace CSND_SND { - -class Interface : public Service::Interface { +class CSND_SND final : public Interface { public: - Interface(); + CSND_SND(); std::string GetPortName() const override { return "csnd:SND"; @@ -28,9 +26,10 @@ struct Type0Command { u8 parameters[20]; }; -void Initialize(Service::Interface* self); -void ExecuteType0Commands(Service::Interface* self); -void AcquireSoundChannels(Service::Interface* self); -void Shutdown(Service::Interface* self); +void Initialize(Interface* self); +void ExecuteType0Commands(Interface* self); +void AcquireSoundChannels(Interface* self); +void Shutdown(Interface* self); -} // namespace +} // namespace CSND +} // namespace Service diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index 49d5b8d1c..25c07f401 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp @@ -22,7 +22,14 @@ static void unk_0x000E0040(Interface* self) { const Interface::FunctionInfo FunctionTable[] = { {0x00010183, nullptr, "Initialize"}, {0x00020000, nullptr, "Finalize"}, + {0x00030000, nullptr, "GetServerState"}, + {0x00050080, nullptr, "StartAccepting"}, + {0x00070000, nullptr, "StartDistribution"}, {0x000800C0, nullptr, "SendWirelessRebootPassphrase"}, + {0x00090040, nullptr, "AcceptClient"}, + {0x000B0042, nullptr, "GetConnectingClients"}, + {0x000C0040, nullptr, "GetClientInfo"}, + {0x000D0040, nullptr, "GetClientState"}, {0x000E0040, unk_0x000E0040, "unk_0x000E0040"}, }; diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index a15aa3696..fe8a6c2d6 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -12,9 +12,7 @@ using DspPipe = DSP::HLE::DspPipe; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace DSP_DSP - +namespace Service { namespace DSP_DSP { static Kernel::SharedPtr<Kernel::Event> semaphore_event; @@ -582,4 +580,5 @@ Interface::~Interface() { interrupt_events = {}; } -} // namespace +} // namespace DSP_DSP +} // namespace Service diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h index 3e97da6eb..691d6f716 100644 --- a/src/core/hle/service/dsp_dsp.h +++ b/src/core/hle/service/dsp_dsp.h @@ -13,12 +13,10 @@ enum class DspPipe; } } -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace DSP_DSP - +namespace Service { namespace DSP_DSP { -class Interface : public Service::Interface { +class Interface final : public Service::Interface { public: Interface(); ~Interface() override; @@ -35,3 +33,4 @@ public: void SignalPipeInterrupt(DSP::HLE::DspPipe pipe); } // namespace DSP_DSP +} // namespace Service diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 9905757c7..cd0a1a598 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -13,10 +13,8 @@ #include "core/hle/result.h" #include "core/hle/service/err_f.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace ERR_F - -namespace ERR_F { +namespace Service { +namespace ERR { enum class FatalErrType : u32 { Generic = 0, @@ -167,7 +165,7 @@ static void LogGenericInfo(const ErrInfo::ErrInfoCommon& errinfo_common) { * 0 : Header code * 1 : Result code */ -static void ThrowFatalError(Service::Interface* self) { +static void ThrowFatalError(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); LOG_CRITICAL(Service_ERR, "Fatal error"); @@ -256,11 +254,9 @@ const Interface::FunctionInfo FunctionTable[] = { // clang-format on }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +ERR_F::ERR_F() { Register(FunctionTable); } -} // namespace +} // namespace ERR +} // namespace Service diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index 892d8af9b..5b27fc871 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace ERR_F +namespace Service { +namespace ERR { -namespace ERR_F { - -class Interface : public Service::Interface { +class ERR_F final : public Interface { public: - Interface(); + ERR_F(); std::string GetPortName() const override { return "err:f"; } }; -} // namespace +} // namespace ERR +} // namespace Service diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 6184e6f1b..f21934108 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -16,6 +16,7 @@ #include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_ncch.h" +#include "core/file_sys/archive_other_savedata.h" #include "core/file_sys/archive_savedata.h" #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/archive_sdmcwriteonly.h" @@ -537,8 +538,17 @@ void RegisterArchiveTypes() { sdmc_directory.c_str()); // Create the SaveData archive - auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); + auto sd_savedata_source = std::make_shared<FileSys::ArchiveSource_SDSaveData>(sdmc_directory); + auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sd_savedata_source); RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); + auto other_savedata_permitted_factory = + std::make_unique<FileSys::ArchiveFactory_OtherSaveDataPermitted>(sd_savedata_source); + RegisterArchiveType(std::move(other_savedata_permitted_factory), + ArchiveIdCode::OtherSaveDataPermitted); + auto other_savedata_general_factory = + std::make_unique<FileSys::ArchiveFactory_OtherSaveDataGeneral>(sd_savedata_source); + RegisterArchiveType(std::move(other_savedata_general_factory), + ArchiveIdCode::OtherSaveDataGeneral); auto extsavedata_factory = std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false); diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 82d591897..7ba62ede0 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -34,10 +34,12 @@ enum class ArchiveIdCode : u32 { SDMC = 0x00000009, SDMCWriteOnly = 0x0000000A, NCCH = 0x2345678A, + OtherSaveDataGeneral = 0x567890B2, + OtherSaveDataPermitted = 0x567890B4, }; /// Media types for the archives -enum class MediaType : u32 { NAND = 0, SDMC = 1 }; +enum class MediaType : u32 { NAND = 0, SDMC = 1, GameCard = 2 }; typedef u64 ArchiveHandle; diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 0b03bea22..337da1387 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -1022,6 +1022,8 @@ const Interface::FunctionInfo FunctionTable[] = { {0x08680000, nullptr, "GetMediaType"}, {0x08690000, nullptr, "GetNandEraseCount"}, {0x086A0082, nullptr, "ReadNandReport"}, + {0x087A0180, nullptr, "AddSeed"}, + {0x088600C0, nullptr, "CheckUpdatedDat"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 710e0e485..947958703 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -18,13 +18,11 @@ // Main graphics debugger object - TODO: Here is probably not the best place for this GraphicsDebugger g_debugger; -// Beginning address of HW regs -const static u32 REGS_BEGIN = 0x1EB00000; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace GSP_GPU +namespace Service { +namespace GSP { -namespace GSP_GPU { +// Beginning address of HW regs +const u32 REGS_BEGIN = 0x1EB00000; const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED( ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, ErrorSummary::InvalidArgument, @@ -179,7 +177,7 @@ static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr * 2 : number of registers to write sequentially * 4 : pointer to source data array */ -static void WriteHWRegs(Service::Interface* self) { +static void WriteHWRegs(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 reg_addr = cmd_buff[1]; u32 size = cmd_buff[2]; @@ -199,7 +197,7 @@ static void WriteHWRegs(Service::Interface* self) { * 4 : pointer to source data array * 6 : pointer to mask array */ -static void WriteHWRegsWithMask(Service::Interface* self) { +static void WriteHWRegsWithMask(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 reg_addr = cmd_buff[1]; u32 size = cmd_buff[2]; @@ -211,7 +209,7 @@ static void WriteHWRegsWithMask(Service::Interface* self) { } /// Read a GSP GPU hardware register -static void ReadHWRegs(Service::Interface* self) { +static void ReadHWRegs(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 reg_addr = cmd_buff[1]; u32 size = cmd_buff[2]; @@ -298,7 +296,7 @@ ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { * Outputs: * 1: Result code */ -static void SetBufferSwap(Service::Interface* self) { +static void SetBufferSwap(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 screen_id = cmd_buff[1]; FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2]; @@ -319,7 +317,7 @@ static void SetBufferSwap(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void FlushDataCache(Service::Interface* self) { +static void FlushDataCache(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 address = cmd_buff[1]; u32 size = cmd_buff[2]; @@ -340,13 +338,13 @@ static void FlushDataCache(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetAxiConfigQoSMode(Service::Interface* self) { +static void SetAxiConfigQoSMode(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 mode = cmd_buff[1]; cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_GSP, "(STUBBED) called mode=0x%08X", mode); + LOG_DEBUG(Service_GSP, "(STUBBED) called mode=0x%08X", mode); } /** @@ -359,7 +357,7 @@ static void SetAxiConfigQoSMode(Service::Interface* self) { * 2 : Thread index into GSP command buffer * 4 : Handle to GSP shared memory */ -static void RegisterInterruptRelayQueue(Service::Interface* self) { +static void RegisterInterruptRelayQueue(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 flags = cmd_buff[1]; @@ -391,7 +389,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void UnregisterInterruptRelayQueue(Service::Interface* self) { +static void UnregisterInterruptRelayQueue(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); g_thread_id = 0; @@ -592,7 +590,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { * Outputs: * 1: Result code */ -static void SetLcdForceBlack(Service::Interface* self) { +static void SetLcdForceBlack(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); bool enable_black = cmd_buff[1] != 0; @@ -609,7 +607,7 @@ static void SetLcdForceBlack(Service::Interface* self) { } /// This triggers handling of the GX command written to the command buffer in shared memory. -static void TriggerCmdReqQueue(Service::Interface* self) { +static void TriggerCmdReqQueue(Interface* self) { // Iterate through each thread's command queue... for (unsigned thread_id = 0; thread_id < 0x4; ++thread_id) { CommandBuffer* command_buffer = (CommandBuffer*)GetCommandBuffer(thread_id); @@ -638,6 +636,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) { * Inputs: * 0: Header 0x00180000 * Outputs: + * 0: Header Code[0x00180240] * 1: Result code * 2: Left framebuffer virtual address for the main screen * 3: Right framebuffer virtual address for the main screen @@ -648,7 +647,7 @@ static void TriggerCmdReqQueue(Service::Interface* self) { * 8: Bottom screen framebuffer format * 9: Bottom screen framebuffer width */ -static void ImportDisplayCaptureInfo(Service::Interface* self) { +static void ImportDisplayCaptureInfo(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // TODO(Subv): We're always returning the framebuffer structures for thread_id = 0, @@ -660,18 +659,19 @@ static void ImportDisplayCaptureInfo(Service::Interface* self) { FrameBufferUpdate* top_screen = GetFrameBufferInfo(thread_id, 0); FrameBufferUpdate* bottom_screen = GetFrameBufferInfo(thread_id, 1); + cmd_buff[0] = IPC::MakeHeader(0x18, 0x9, 0); + cmd_buff[1] = RESULT_SUCCESS.raw; + // Top Screen cmd_buff[2] = top_screen->framebuffer_info[top_screen->index].address_left; cmd_buff[3] = top_screen->framebuffer_info[top_screen->index].address_right; cmd_buff[4] = top_screen->framebuffer_info[top_screen->index].format; cmd_buff[5] = top_screen->framebuffer_info[top_screen->index].stride; - + // Bottom Screen cmd_buff[6] = bottom_screen->framebuffer_info[bottom_screen->index].address_left; cmd_buff[7] = bottom_screen->framebuffer_info[bottom_screen->index].address_right; cmd_buff[8] = bottom_screen->framebuffer_info[bottom_screen->index].format; cmd_buff[9] = bottom_screen->framebuffer_info[bottom_screen->index].stride; - cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_GSP, "called"); } @@ -680,7 +680,7 @@ static void ImportDisplayCaptureInfo(Service::Interface* self) { * Outputs: * 1: Result code */ -static void AcquireRight(Service::Interface* self) { +static void AcquireRight(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); gpu_right_acquired = true; @@ -695,7 +695,7 @@ static void AcquireRight(Service::Interface* self) { * Outputs: * 1: Result code */ -static void ReleaseRight(Service::Interface* self) { +static void ReleaseRight(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); gpu_right_acquired = false; @@ -739,10 +739,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x001F0082, nullptr, "StoreDataCache"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +GSP_GPU::GSP_GPU() { Register(FunctionTable); g_interrupt_event = nullptr; @@ -757,10 +754,11 @@ Interface::Interface() { first_initialization = true; } -Interface::~Interface() { +GSP_GPU::~GSP_GPU() { g_interrupt_event = nullptr; g_shared_memory = nullptr; gpu_right_acquired = false; } -} // namespace +} // namespace GSP +} // namespace Service diff --git a/src/core/hle/service/gsp_gpu.h b/src/core/hle/service/gsp_gpu.h index 79a72f77d..c6e24073b 100644 --- a/src/core/hle/service/gsp_gpu.h +++ b/src/core/hle/service/gsp_gpu.h @@ -11,10 +11,8 @@ #include "core/hle/result.h" #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace GSP_GPU - -namespace GSP_GPU { +namespace Service { +namespace GSP { /// GSP interrupt ID enum class InterruptId : u8 { @@ -176,11 +174,10 @@ struct CommandBuffer { }; static_assert(sizeof(CommandBuffer) == 0x200, "CommandBuffer struct has incorrect size"); -/// Interface to "srv:" service -class Interface : public Service::Interface { +class GSP_GPU final : public Interface { public: - Interface(); - ~Interface() override; + GSP_GPU(); + ~GSP_GPU() override; std::string GetPortName() const override { return "gsp::Gpu"; @@ -203,4 +200,6 @@ ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info); * @returns FramebufferUpdate Information about the specified framebuffer. */ FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index); -} // namespace + +} // namespace GSP +} // namespace Service diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp index b916dd759..89cb4a3cc 100644 --- a/src/core/hle/service/gsp_lcd.cpp +++ b/src/core/hle/service/gsp_lcd.cpp @@ -4,26 +4,26 @@ #include "core/hle/service/gsp_lcd.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace GSP_LCD - -namespace GSP_LCD { +namespace Service { +namespace GSP { const Interface::FunctionInfo FunctionTable[] = { // clang-format off + {0x000A0080, nullptr, "SetBrightnessRaw"}, + {0x000B0080, nullptr, "SetBrightness"}, {0x000F0000, nullptr, "PowerOnAllBacklights"}, {0x00100000, nullptr, "PowerOffAllBacklights"}, {0x00110040, nullptr, "PowerOnBacklight"}, {0x00120040, nullptr, "PowerOffBacklight"}, {0x00130040, nullptr, "SetLedForceOff"}, + {0x00140000, nullptr, "GetVendor"}, + {0x00150040, nullptr, "GetBrightness"}, // clang-format on }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +GSP_LCD::GSP_LCD() { Register(FunctionTable); } -} // namespace +} // namespace GSP +} // namespace Service diff --git a/src/core/hle/service/gsp_lcd.h b/src/core/hle/service/gsp_lcd.h index 56b3cfe86..e9686a5e7 100644 --- a/src/core/hle/service/gsp_lcd.h +++ b/src/core/hle/service/gsp_lcd.h @@ -6,19 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace GSP_LCD +namespace Service { +namespace GSP { -namespace GSP_LCD { - -/// Interface to "gsp::Lcd" service -class Interface : public Service::Interface { +class GSP_LCD final : public Interface { public: - Interface(); + GSP_LCD(); std::string GetPortName() const override { return "gsp::Lcd"; } }; -} // namespace +} // namespace GSP +} // namespace Service diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index 3cf62a4b8..b01d6e031 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -4,10 +4,8 @@ #include "core/hle/service/http_c.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace HTTP_C - -namespace HTTP_C { +namespace Service { +namespace HTTP { const Interface::FunctionInfo FunctionTable[] = { {0x00010044, nullptr, "Initialize"}, @@ -55,6 +53,10 @@ const Interface::FunctionInfo FunctionTable[] = { {0x002E0040, nullptr, "DestroyRootCertChain"}, {0x002F0082, nullptr, "RootCertChainAddCert"}, {0x00300080, nullptr, "RootCertChainAddDefaultCert"}, + {0x00310080, nullptr, "RootCertChainRemoveCert"}, + {0x00320084, nullptr, "OpenClientCertContext"}, + {0x00330040, nullptr, "OpenDefaultClientCertContext"}, + {0x00340040, nullptr, "CloseClientCertContext"}, {0x00350186, nullptr, "SetDefaultProxy"}, {0x00360000, nullptr, "ClearDNSCache"}, {0x00370080, nullptr, "SetKeepAlive"}, @@ -62,11 +64,9 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00390000, nullptr, "Finalize"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +HTTP_C::HTTP_C() { Register(FunctionTable); } -} // namespace +} // namespace HTTP +} // namespace Service diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h index 5ea3d1df3..cff279c02 100644 --- a/src/core/hle/service/http_c.h +++ b/src/core/hle/service/http_c.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace HTTP_C +namespace Service { +namespace HTTP { -namespace HTTP_C { - -class Interface : public Service::Interface { +class HTTP_C final : public Interface { public: - Interface(); + HTTP_C(); std::string GetPortName() const override { return "http:C"; } }; -} // namespace +} // namespace HTTP +} // namespace Service diff --git a/src/core/hle/service/ldr_ro/cro_helper.cpp b/src/core/hle/service/ldr_ro/cro_helper.cpp index 4f0aa77eb..f78545f37 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.cpp +++ b/src/core/hle/service/ldr_ro/cro_helper.cpp @@ -7,10 +7,8 @@ #include "common/scope_exit.h" #include "core/hle/service/ldr_ro/cro_helper.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace LDR_RO - -namespace LDR_RO { +namespace Service { +namespace LDR { static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, @@ -1493,4 +1491,5 @@ std::tuple<VAddr, u32> CROHelper::GetExecutablePages() const { return std::make_tuple(0, 0); } -} // namespace +} // namespace LDR +} // namespace Service diff --git a/src/core/hle/service/ldr_ro/cro_helper.h b/src/core/hle/service/ldr_ro/cro_helper.h index 6a0d0d3bf..060d5a55f 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.h +++ b/src/core/hle/service/ldr_ro/cro_helper.h @@ -11,10 +11,8 @@ #include "core/hle/result.h" #include "core/memory.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace LDR_RO - -namespace LDR_RO { +namespace Service { +namespace LDR { // GCC versions < 5.0 do not implement std::is_trivially_copyable. // Excluding MSVC because it has weird behaviour for std::is_trivially_copyable. @@ -710,4 +708,5 @@ private: ResultCode ApplyExitRelocations(VAddr crs_address); }; -} // namespace +} // namespace LDR +} // namespace Service diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index ec183d1f5..9e5d6a318 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -12,10 +12,8 @@ #include "core/hle/service/ldr_ro/ldr_ro.h" #include "core/hle/service/ldr_ro/memory_synchronizer.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace LDR_RO - -namespace LDR_RO { +namespace Service { +namespace LDR { static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, @@ -71,7 +69,7 @@ static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void Initialize(Service::Interface* self) { +static void Initialize(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr crs_buffer_ptr = cmd_buff[1]; u32 crs_size = cmd_buff[2]; @@ -196,7 +194,7 @@ static void Initialize(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void LoadCRR(Service::Interface* self) { +static void LoadCRR(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 crr_buffer_ptr = cmd_buff[1]; u32 crr_size = cmd_buff[2]; @@ -229,7 +227,7 @@ static void LoadCRR(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void UnloadCRR(Service::Interface* self) { +static void UnloadCRR(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 crr_buffer_ptr = cmd_buff[1]; u32 descriptor = cmd_buff[2]; @@ -276,7 +274,7 @@ static void UnloadCRR(Service::Interface* self) { * unified one of two, with an additional parameter link_on_load_bug_fix. * There is a dispatcher template below. */ -static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { +static void LoadCRO(Interface* self, bool link_on_load_bug_fix) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_buffer_ptr = cmd_buff[1]; VAddr cro_address = cmd_buff[2]; @@ -469,7 +467,7 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { } template <bool link_on_load_bug_fix> -static void LoadCRO(Service::Interface* self) { +static void LoadCRO(Interface* self) { LoadCRO(self, link_on_load_bug_fix); } @@ -486,7 +484,7 @@ static void LoadCRO(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void UnloadCRO(Service::Interface* self) { +static void UnloadCRO(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; u32 zero = cmd_buff[2]; @@ -580,7 +578,7 @@ static void UnloadCRO(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void LinkCRO(Service::Interface* self) { +static void LinkCRO(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; u32 descriptor = cmd_buff[2]; @@ -642,7 +640,7 @@ static void LinkCRO(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void UnlinkCRO(Service::Interface* self) { +static void UnlinkCRO(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; u32 descriptor = cmd_buff[2]; @@ -704,7 +702,7 @@ static void UnlinkCRO(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void Shutdown(Service::Interface* self) { +static void Shutdown(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr crs_buffer_ptr = cmd_buff[1]; u32 descriptor = cmd_buff[2]; @@ -762,14 +760,12 @@ const Interface::FunctionInfo FunctionTable[] = { // clang-format on }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +LDR_RO::LDR_RO() { Register(FunctionTable); loaded_crs = 0; memory_synchronizer.Clear(); } -} // namespace +} // namespace LDR +} // namespace Service diff --git a/src/core/hle/service/ldr_ro/ldr_ro.h b/src/core/hle/service/ldr_ro/ldr_ro.h index 331637cde..0f6fe7b60 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.h +++ b/src/core/hle/service/ldr_ro/ldr_ro.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace LDR_RO +namespace Service { +namespace LDR { -namespace LDR_RO { - -class Interface : public Service::Interface { +class LDR_RO final : public Interface { public: - Interface(); + LDR_RO(); std::string GetPortName() const override { return "ldr:ro"; } }; -} // namespace +} // namespace LDR +} // namespace Service diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp index 989887264..0d44bf6bd 100644 --- a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp +++ b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp @@ -6,10 +6,8 @@ #include "common/assert.h" #include "core/hle/service/ldr_ro/memory_synchronizer.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace LDR_RO - -namespace LDR_RO { +namespace Service { +namespace LDR { auto MemorySynchronizer::FindMemoryBlock(VAddr mapping, VAddr original) { auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(), @@ -40,4 +38,5 @@ void MemorySynchronizer::SynchronizeOriginalMemory() { } } -} // namespace +} // namespace LDR +} // namespace Service diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.h b/src/core/hle/service/ldr_ro/memory_synchronizer.h index 883ee4acf..438293a58 100644 --- a/src/core/hle/service/ldr_ro/memory_synchronizer.h +++ b/src/core/hle/service/ldr_ro/memory_synchronizer.h @@ -7,10 +7,8 @@ #include <vector> #include "core/memory.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace LDR_RO - -namespace LDR_RO { +namespace Service { +namespace LDR { /** * This is a work-around before we implement memory aliasing. @@ -40,4 +38,5 @@ private: auto FindMemoryBlock(VAddr mapping, VAddr original); }; -} // namespace +} // namespace LDR +} // namespace Service diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 1f851d328..7ced36439 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -7,10 +7,8 @@ #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/mic_u.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace MIC_U - -namespace MIC_U { +namespace Service { +namespace MIC { enum class Encoding : u8 { PCM8 = 0, @@ -49,7 +47,7 @@ static bool audio_buffer_loop; * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void MapSharedMem(Service::Interface* self) { +static void MapSharedMem(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 size = cmd_buff[1]; Handle mem_handle = cmd_buff[3]; @@ -68,7 +66,7 @@ static void MapSharedMem(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void UnmapSharedMem(Service::Interface* self) { +static void UnmapSharedMem(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -87,7 +85,7 @@ static void UnmapSharedMem(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void StartSampling(Service::Interface* self) { +static void StartSampling(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); encoding = static_cast<Encoding>(cmd_buff[1] & 0xFF); @@ -111,7 +109,7 @@ static void StartSampling(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void AdjustSampling(Service::Interface* self) { +static void AdjustSampling(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); sample_rate = static_cast<SampleRate>(cmd_buff[1] & 0xFF); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -125,7 +123,7 @@ static void AdjustSampling(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void StopSampling(Service::Interface* self) { +static void StopSampling(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error is_sampling = false; @@ -140,7 +138,7 @@ static void StopSampling(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : 0 = sampling, non-zero = sampling */ -static void IsSampling(Service::Interface* self) { +static void IsSampling(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = is_sampling; @@ -155,7 +153,7 @@ static void IsSampling(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 3 : Event handle */ -static void GetBufferFullEvent(Service::Interface* self) { +static void GetBufferFullEvent(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[3] = Kernel::g_handle_table.Create(buffer_full_event).MoveFrom(); @@ -170,7 +168,7 @@ static void GetBufferFullEvent(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetGain(Service::Interface* self) { +static void SetGain(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); mic_gain = cmd_buff[1] & 0xFF; cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -185,7 +183,7 @@ static void SetGain(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Gain */ -static void GetGain(Service::Interface* self) { +static void GetGain(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = mic_gain; @@ -200,7 +198,7 @@ static void GetGain(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetPower(Service::Interface* self) { +static void SetPower(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); mic_power = static_cast<bool>(cmd_buff[1] & 0xFF); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -215,7 +213,7 @@ static void SetPower(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Power */ -static void GetPower(Service::Interface* self) { +static void GetPower(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = mic_power; @@ -232,7 +230,7 @@ static void GetPower(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetIirFilterMic(Service::Interface* self) { +static void SetIirFilterMic(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 size = cmd_buff[1]; @@ -250,7 +248,7 @@ static void SetIirFilterMic(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetClamp(Service::Interface* self) { +static void SetClamp(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); clamp = static_cast<bool>(cmd_buff[1] & 0xFF); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -265,7 +263,7 @@ static void SetClamp(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Clamp (0 = don't clamp, non-zero = clamp) */ -static void GetClamp(Service::Interface* self) { +static void GetClamp(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = clamp; @@ -280,7 +278,7 @@ static void GetClamp(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetAllowShellClosed(Service::Interface* self) { +static void SetAllowShellClosed(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); allow_shell_closed = static_cast<bool>(cmd_buff[1] & 0xFF); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -294,7 +292,7 @@ static void SetAllowShellClosed(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetClientVersion(Service::Interface* self) { +static void SetClientVersion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); const u32 version = cmd_buff[1]; @@ -324,10 +322,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00100040, SetClientVersion, "SetClientVersion"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +MIC_U::MIC_U() { Register(FunctionTable); shared_memory = nullptr; buffer_full_event = @@ -338,9 +333,10 @@ Interface::Interface() { clamp = false; } -Interface::~Interface() { +MIC_U::~MIC_U() { shared_memory = nullptr; buffer_full_event = nullptr; } -} // namespace +} // namespace MIC +} // namespace Service diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h index 1cff7390e..ec2b67ab8 100644 --- a/src/core/hle/service/mic_u.h +++ b/src/core/hle/service/mic_u.h @@ -6,21 +6,18 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace MIC_U +namespace Service { +namespace MIC { -// mic service - -namespace MIC_U { - -class Interface : public Service::Interface { +class MIC_U final : public Interface { public: - Interface(); - ~Interface(); + MIC_U(); + ~MIC_U(); std::string GetPortName() const override { return "mic:u"; } }; -} // namespace +} // namespace MIC +} // namespace Service diff --git a/src/core/hle/service/mvd/mvd.cpp b/src/core/hle/service/mvd/mvd.cpp new file mode 100644 index 000000000..9416fe5d6 --- /dev/null +++ b/src/core/hle/service/mvd/mvd.cpp @@ -0,0 +1,17 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/mvd/mvd.h" +#include "core/hle/service/mvd/mvd_std.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace MVD { + +void Init() { + AddService(new MVD_STD()); +} + +} // namespace MVD +} // namespace Service diff --git a/src/core/hle/service/mvd/mvd.h b/src/core/hle/service/mvd/mvd.h new file mode 100644 index 000000000..7b212e839 --- /dev/null +++ b/src/core/hle/service/mvd/mvd.h @@ -0,0 +1,14 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service { +namespace MVD { + +/// Initializes all MVD services. +void Init(); + +} // namespace MVD +} // namespace Service diff --git a/src/core/hle/service/mvd/mvd_std.cpp b/src/core/hle/service/mvd/mvd_std.cpp new file mode 100644 index 000000000..fd7ca87d3 --- /dev/null +++ b/src/core/hle/service/mvd/mvd_std.cpp @@ -0,0 +1,32 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/mvd/mvd_std.h" + +namespace Service { +namespace MVD { + +const Interface::FunctionInfo FunctionTable[] = { + // clang-format off + {0x00010082, nullptr, "Initialize"}, + {0x00020000, nullptr, "Shutdown"}, + {0x00030300, nullptr, "CalculateWorkBufSize"}, + {0x000400C0, nullptr, "CalculateImageSize"}, + {0x00080142, nullptr, "ProcessNALUnit"}, + {0x00090042, nullptr, "ControlFrameRendering"}, + {0x000A0000, nullptr, "GetStatus"}, + {0x000B0000, nullptr, "GetStatusOther"}, + {0x001D0042, nullptr, "GetConfig"}, + {0x001E0044, nullptr, "SetConfig"}, + {0x001F0902, nullptr, "SetOutputBuffer"}, + {0x00210100, nullptr, "OverrideOutputBuffers"} + // clang-format on +}; + +MVD_STD::MVD_STD() { + Register(FunctionTable); +} + +} // namespace MVD +} // namespace Service diff --git a/src/core/hle/service/mvd/mvd_std.h b/src/core/hle/service/mvd/mvd_std.h new file mode 100644 index 000000000..7db9e2e50 --- /dev/null +++ b/src/core/hle/service/mvd/mvd_std.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace MVD { + +class MVD_STD final : public Interface { +public: + MVD_STD(); + + std::string GetPortName() const override { + return "mvd:std"; + } +}; + +} // namespace MVD +} // namespace Service diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp new file mode 100644 index 000000000..d9738c6a1 --- /dev/null +++ b/src/core/hle/service/nfc/nfc.cpp @@ -0,0 +1,18 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/nfc/nfc.h" +#include "core/hle/service/nfc/nfc_m.h" +#include "core/hle/service/nfc/nfc_u.h" + +namespace Service { +namespace NFC { + +void Init() { + AddService(new NFC_M()); + AddService(new NFC_U()); +} + +} // namespace NFC +} // namespace Service diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h new file mode 100644 index 000000000..cd65a5fdc --- /dev/null +++ b/src/core/hle/service/nfc/nfc.h @@ -0,0 +1,14 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service { +namespace NFC { + +/// Initialize all NFC services. +void Init(); + +} // namespace NFC +} // namespace Service diff --git a/src/core/hle/service/nfc/nfc_m.cpp b/src/core/hle/service/nfc/nfc_m.cpp new file mode 100644 index 000000000..717335c11 --- /dev/null +++ b/src/core/hle/service/nfc/nfc_m.cpp @@ -0,0 +1,44 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/nfc/nfc_m.h" + +namespace Service { +namespace NFC { + +const Interface::FunctionInfo FunctionTable[] = { + // clang-format off + // nfc:u shared commands + {0x00010040, nullptr, "Initialize"}, + {0x00020040, nullptr, "Shutdown"}, + {0x00030000, nullptr, "StartCommunication"}, + {0x00040000, nullptr, "StopCommunication"}, + {0x00050040, nullptr, "StartTagScanning"}, + {0x00060000, nullptr, "StopTagScanning"}, + {0x00070000, nullptr, "LoadAmiiboData"}, + {0x00080000, nullptr, "ResetTagScanState"}, + {0x00090002, nullptr, "UpdateStoredAmiiboData"}, + {0x000D0000, nullptr, "GetTagState"}, + {0x000F0000, nullptr, "CommunicationGetStatus"}, + {0x00100000, nullptr, "GetTagInfo2"}, + {0x00110000, nullptr, "GetTagInfo"}, + {0x00120000, nullptr, "CommunicationGetResult"}, + {0x00130040, nullptr, "OpenAppData"}, + {0x00140384, nullptr, "InitializeWriteAppData"}, + {0x00150040, nullptr, "ReadAppData"}, + {0x00160242, nullptr, "WriteAppData"}, + {0x00170000, nullptr, "GetAmiiboSettings"}, + {0x00180000, nullptr, "GetAmiiboConfig"}, + {0x00190000, nullptr, "GetAppDataInitStruct"}, + // nfc:m + {0x04040A40, nullptr, "SetAmiiboSettings"} + // clang-format on +}; + +NFC_M::NFC_M() { + Register(FunctionTable); +} + +} // namespace NFC +} // namespace Service diff --git a/src/core/hle/service/nfc/nfc_m.h b/src/core/hle/service/nfc/nfc_m.h new file mode 100644 index 000000000..fae75535b --- /dev/null +++ b/src/core/hle/service/nfc/nfc_m.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace NFC { + +class NFC_M final : public Interface { +public: + NFC_M(); + + std::string GetPortName() const override { + return "nfc:m"; + } +}; + +} // namespace NFC +} // namespace Service diff --git a/src/core/hle/service/nfc/nfc_u.cpp b/src/core/hle/service/nfc/nfc_u.cpp new file mode 100644 index 000000000..deffb0b4f --- /dev/null +++ b/src/core/hle/service/nfc/nfc_u.cpp @@ -0,0 +1,41 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/nfc/nfc_u.h" + +namespace Service { +namespace NFC { + +const Interface::FunctionInfo FunctionTable[] = { + // clang-format off + {0x00010040, nullptr, "Initialize"}, + {0x00020040, nullptr, "Shutdown"}, + {0x00030000, nullptr, "StartCommunication"}, + {0x00040000, nullptr, "StopCommunication"}, + {0x00050040, nullptr, "StartTagScanning"}, + {0x00060000, nullptr, "StopTagScanning"}, + {0x00070000, nullptr, "LoadAmiiboData"}, + {0x00080000, nullptr, "ResetTagScanState"}, + {0x00090002, nullptr, "UpdateStoredAmiiboData"}, + {0x000D0000, nullptr, "GetTagState"}, + {0x000F0000, nullptr, "CommunicationGetStatus"}, + {0x00100000, nullptr, "GetTagInfo2"}, + {0x00110000, nullptr, "GetTagInfo"}, + {0x00120000, nullptr, "CommunicationGetResult"}, + {0x00130040, nullptr, "OpenAppData"}, + {0x00140384, nullptr, "InitializeWriteAppData"}, + {0x00150040, nullptr, "ReadAppData"}, + {0x00160242, nullptr, "WriteAppData"}, + {0x00170000, nullptr, "GetAmiiboSettings"}, + {0x00180000, nullptr, "GetAmiiboConfig"}, + {0x00190000, nullptr, "GetAppDataInitStruct"}, + // clang-format on +}; + +NFC_U::NFC_U() { + Register(FunctionTable); +} + +} // namespace NFC +} // namespace Service diff --git a/src/core/hle/service/nfc/nfc_u.h b/src/core/hle/service/nfc/nfc_u.h new file mode 100644 index 000000000..eb7507314 --- /dev/null +++ b/src/core/hle/service/nfc/nfc_u.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace NFC { + +class NFC_U final : public Interface { +public: + NFC_U(); + + std::string GetPortName() const override { + return "nfc:u"; + } +}; + +} // namespace NFC +} // namespace Service diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp index e2ba693c9..28b87e6f7 100644 --- a/src/core/hle/service/nim/nim_s.cpp +++ b/src/core/hle/service/nim/nim_s.cpp @@ -10,6 +10,7 @@ namespace NIM { const Interface::FunctionInfo FunctionTable[] = { {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"}, {0x0016020A, nullptr, "ListTitles"}, + {0x00290000, nullptr, "AccountCheckBalanceSOAP"}, {0x002D0042, nullptr, "DownloadTickets"}, {0x00420240, nullptr, "StartDownload"}, }; diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp index 7e07d02e8..7664bad60 100644 --- a/src/core/hle/service/nim/nim_u.cpp +++ b/src/core/hle/service/nim/nim_u.cpp @@ -15,6 +15,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00050000, nullptr, "CheckForSysUpdateEvent"}, {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"}, {0x000A0000, nullptr, "GetState"}, + {0x000B0000, nullptr, "GetSystemTitleHash"}, }; NIM_U_Interface::NIM_U_Interface() { diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp index 6693f7c08..215c9aacc 100644 --- a/src/core/hle/service/ns_s.cpp +++ b/src/core/hle/service/ns_s.cpp @@ -4,10 +4,8 @@ #include "core/hle/service/ns_s.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace NS_S - -namespace NS_S { +namespace Service { +namespace NS { const Interface::FunctionInfo FunctionTable[] = { {0x000100C0, nullptr, "LaunchFIRM"}, @@ -27,11 +25,9 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00160000, nullptr, "RebootSystemClean"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +NS_S::NS_S() { Register(FunctionTable); } -} // namespace +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/ns_s.h b/src/core/hle/service/ns_s.h index 8d8e849b8..90288a521 100644 --- a/src/core/hle/service/ns_s.h +++ b/src/core/hle/service/ns_s.h @@ -6,19 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace NS_S +namespace Service { +namespace NS { -namespace NS_S { - -/// Interface to "NS:S" service -class Interface : public Service::Interface { +class NS_S final : public Interface { public: - Interface(); + NS_S(); std::string GetPortName() const override { return "ns:s"; } }; -} // namespace +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index 80081aae2..e3160d4b4 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp @@ -7,10 +7,8 @@ #include "core/hle/kernel/event.h" #include "core/hle/service/nwm_uds.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace NWM_UDS - -namespace NWM_UDS { +namespace Service { +namespace NWM { static Kernel::SharedPtr<Kernel::Event> handle_event; @@ -22,7 +20,7 @@ static Kernel::SharedPtr<Kernel::Event> handle_event; * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void Shutdown(Service::Interface* self) { +static void Shutdown(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // TODO(purpasmart): Verify return header on HW @@ -50,7 +48,7 @@ static void Shutdown(Service::Interface* self) { * 0 : Return header * 1 : Result of function, 0 on success, otherwise error code */ -static void RecvBeaconBroadcastData(Service::Interface* self) { +static void RecvBeaconBroadcastData(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 out_buffer_size = cmd_buff[1]; u32 unk1 = cmd_buff[2]; @@ -90,7 +88,7 @@ static void RecvBeaconBroadcastData(Service::Interface* self) { * 2 : Value 0 * 3 : Output handle */ -static void Initialize(Service::Interface* self) { +static void InitializeWithVersion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 unk1 = cmd_buff[1]; u32 unk2 = cmd_buff[12]; @@ -120,24 +118,26 @@ static void Initialize(Service::Interface* self) { const Interface::FunctionInfo FunctionTable[] = { {0x00020000, nullptr, "Scrap"}, {0x00030000, Shutdown, "Shutdown"}, - {0x00040402, nullptr, "CreateNetwork"}, + {0x00040402, nullptr, "CreateNetwork (deprecated)"}, {0x00050040, nullptr, "EjectClient"}, {0x00060000, nullptr, "EjectSpectator"}, {0x00070080, nullptr, "UpdateNetworkAttribute"}, {0x00080000, nullptr, "DestroyNetwork"}, + {0x00090442, nullptr, "ConnectNetwork (deprecated)"}, {0x000A0000, nullptr, "DisconnectNetwork"}, {0x000B0000, nullptr, "GetConnectionStatus"}, {0x000D0040, nullptr, "GetNodeInformation"}, + {0x000E0006, nullptr, "DecryptBeaconData (deprecated)"}, {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, - {0x00100042, nullptr, "SetBeaconAdditionalData"}, + {0x00100042, nullptr, "SetApplicationData"}, {0x00110040, nullptr, "GetApplicationData"}, {0x00120100, nullptr, "Bind"}, {0x00130040, nullptr, "Unbind"}, - {0x001400C0, nullptr, "RecvBroadcastDataFrame"}, + {0x001400C0, nullptr, "PullPacket"}, {0x00150080, nullptr, "SetMaxSendDelay"}, {0x00170182, nullptr, "SendTo"}, {0x001A0000, nullptr, "GetChannel"}, - {0x001B0302, Initialize, "Initialize"}, + {0x001B0302, InitializeWithVersion, "InitializeWithVersion"}, {0x001D0044, nullptr, "BeginHostingNetwork"}, {0x001E0084, nullptr, "ConnectToNetwork"}, {0x001F0006, nullptr, "DecryptBeaconData"}, @@ -146,17 +146,15 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00220402, nullptr, "ScanOnConnection"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +NWM_UDS::NWM_UDS() { handle_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "NWM_UDS::handle_event"); Register(FunctionTable); } -Interface::~Interface() { +NWM_UDS::~NWM_UDS() { handle_event = nullptr; } -} // namespace +} // namespace NWM +} // namespace Service diff --git a/src/core/hle/service/nwm_uds.h b/src/core/hle/service/nwm_uds.h index 0ced2359c..55db748f6 100644 --- a/src/core/hle/service/nwm_uds.h +++ b/src/core/hle/service/nwm_uds.h @@ -6,21 +6,20 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace NWM_UDS +// Local-WLAN service -// local-WLAN service +namespace Service { +namespace NWM { -namespace NWM_UDS { - -class Interface : public Service::Interface { +class NWM_UDS final : public Interface { public: - Interface(); - ~Interface() override; + NWM_UDS(); + ~NWM_UDS() override; std::string GetPortName() const override { return "nwm::UDS"; } }; -} // namespace +} // namespace NWM +} // namespace Service diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp index 7d91694f6..caa16f952 100644 --- a/src/core/hle/service/pm_app.cpp +++ b/src/core/hle/service/pm_app.cpp @@ -4,31 +4,30 @@ #include "core/hle/service/pm_app.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace PM_APP - -namespace PM_APP { +namespace Service { +namespace PM { const Interface::FunctionInfo FunctionTable[] = { + // clang-format off {0x00010140, nullptr, "LaunchTitle"}, - {0x00020082, nullptr, "LaunchFIRMSetParams"}, - {0x00030080, nullptr, "TerminateProcesse"}, - {0x00040100, nullptr, "TerminateProcessTID"}, - {0x000500C0, nullptr, "TerminateProcessTID_unknown"}, + {0x00020082, nullptr, "LaunchFIRM"}, + {0x00030080, nullptr, "TerminateApplication"}, + {0x00040100, nullptr, "TerminateTitle"}, + {0x000500C0, nullptr, "TerminateProcess"}, + {0x00060082, nullptr, "PrepareForReboot"}, {0x00070042, nullptr, "GetFIRMLaunchParams"}, {0x00080100, nullptr, "GetTitleExheaderFlags"}, {0x00090042, nullptr, "SetFIRMLaunchParams"}, - {0x000A0140, nullptr, "SetResourceLimit"}, - {0x000B0140, nullptr, "GetResourceLimitMax"}, + {0x000A0140, nullptr, "SetAppResourceLimit"}, + {0x000B0140, nullptr, "GetAppResourceLimit"}, {0x000C0080, nullptr, "UnregisterProcess"}, {0x000D0240, nullptr, "LaunchTitleUpdate"}, + // clang-format on }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +PM_APP::PM_APP() { Register(FunctionTable); } -} // namespace +} // namespace PM +} // namespace Service diff --git a/src/core/hle/service/pm_app.h b/src/core/hle/service/pm_app.h index c1fb1f9da..151c69f3d 100644 --- a/src/core/hle/service/pm_app.h +++ b/src/core/hle/service/pm_app.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace PM_APP +namespace Service { +namespace PM { -namespace PM_APP { - -class Interface : public Service::Interface { +class PM_APP final : public Interface { public: - Interface(); + PM_APP(); std::string GetPortName() const override { return "pm:app"; } }; -} // namespace +} // namespace PM +} // namespace Service diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index cc859c14c..8ff808fd9 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -6,7 +6,9 @@ #include "core/file_sys/file_backend.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/ptm/ptm.h" +#include "core/hle/service/ptm/ptm_gets.h" #include "core/hle/service/ptm/ptm_play.h" +#include "core/hle/service/ptm/ptm_sets.h" #include "core/hle/service/ptm/ptm_sysm.h" #include "core/hle/service/ptm/ptm_u.h" #include "core/hle/service/service.h" @@ -81,7 +83,7 @@ void GetTotalStepCount(Service::Interface* self) { LOG_WARNING(Service_PTM, "(STUBBED) called"); } -void IsLegacyPowerOff(Service::Interface* self) { +void GetSoftwareClosedFlag(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; @@ -106,9 +108,12 @@ void CheckNew3DS(Service::Interface* self) { } void Init() { - AddService(new PTM_Play_Interface); - AddService(new PTM_Sysm_Interface); - AddService(new PTM_U_Interface); + AddService(new PTM_Gets); + AddService(new PTM_Play); + AddService(new PTM_S); + AddService(new PTM_Sets); + AddService(new PTM_Sysm); + AddService(new PTM_U); shell_open = true; battery_is_charging = true; @@ -137,7 +142,7 @@ void Init() { Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); if (gamecoin_result.Succeeded()) { auto gamecoin = gamecoin_result.MoveFrom(); - gamecoin->backend->Write(0, sizeof(GameCoin), 1, + gamecoin->backend->Write(0, sizeof(GameCoin), true, reinterpret_cast<const u8*>(&default_game_coin)); gamecoin->backend->Close(); } diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index 6e163a6f9..a1a628012 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -82,12 +82,13 @@ void GetBatteryChargeState(Interface* self); void GetTotalStepCount(Interface* self); /** - * PTM::IsLegacyPowerOff service function + * PTM::GetSoftwareClosedFlag service function * Outputs: * 1: Result code, 0 on success, otherwise error code - * 2: Whether the system is going through a power off + * 2: Whether or not the "software closed" dialog was requested by the last FIRM + * and should be displayed. */ -void IsLegacyPowerOff(Interface* self); +void GetSoftwareClosedFlag(Interface* self); /** * PTM::CheckNew3DS service function diff --git a/src/core/hle/service/ptm/ptm_gets.cpp b/src/core/hle/service/ptm/ptm_gets.cpp new file mode 100644 index 000000000..b23e508d6 --- /dev/null +++ b/src/core/hle/service/ptm/ptm_gets.cpp @@ -0,0 +1,37 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/ptm/ptm.h" +#include "core/hle/service/ptm/ptm_gets.h" + +namespace Service { +namespace PTM { + +const Interface::FunctionInfo FunctionTable[] = { + // ptm:u common commands + {0x00010002, nullptr, "RegisterAlarmClient"}, + {0x00020080, nullptr, "SetRtcAlarm"}, + {0x00030000, nullptr, "GetRtcAlarm"}, + {0x00040000, nullptr, "CancelRtcAlarm"}, + {0x00050000, GetAdapterState, "GetAdapterState"}, + {0x00060000, GetShellState, "GetShellState"}, + {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, + {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"}, + {0x00090000, nullptr, "GetPedometerState"}, + {0x000A0042, nullptr, "GetStepHistoryEntry"}, + {0x000B00C2, nullptr, "GetStepHistory"}, + {0x000C0000, GetTotalStepCount, "GetTotalStepCount"}, + {0x000D0040, nullptr, "SetPedometerRecordingMode"}, + {0x000E0000, nullptr, "GetPedometerRecordingMode"}, + {0x000F0084, nullptr, "GetStepHistoryAll"}, + // ptm:gets + {0x04010000, nullptr, "GetSystemTime"}, +}; + +PTM_Gets::PTM_Gets() { + Register(FunctionTable); +} + +} // namespace PTM +} // namespace Service diff --git a/src/core/hle/service/ptm/ptm_gets.h b/src/core/hle/service/ptm/ptm_gets.h new file mode 100644 index 000000000..5552c9eff --- /dev/null +++ b/src/core/hle/service/ptm/ptm_gets.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace PTM { + +class PTM_Gets final : public Interface { +public: + PTM_Gets(); + + std::string GetPortName() const override { + return "ptm:gets"; + } +}; + +} // namespace PTM +} // namespace Service diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp index 2e0c6e1a3..bcb00e0d4 100644 --- a/src/core/hle/service/ptm/ptm_play.cpp +++ b/src/core/hle/service/ptm/ptm_play.cpp @@ -2,19 +2,37 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/service/ptm/ptm.h" #include "core/hle/service/ptm/ptm_play.h" namespace Service { namespace PTM { const Interface::FunctionInfo FunctionTable[] = { + // ptm:u common commands + {0x00010002, nullptr, "RegisterAlarmClient"}, + {0x00020080, nullptr, "SetRtcAlarm"}, + {0x00030000, nullptr, "GetRtcAlarm"}, + {0x00040000, nullptr, "CancelRtcAlarm"}, + {0x00050000, GetAdapterState, "GetAdapterState"}, + {0x00060000, GetShellState, "GetShellState"}, + {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, + {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"}, + {0x00090000, nullptr, "GetPedometerState"}, + {0x000A0042, nullptr, "GetStepHistoryEntry"}, + {0x000B00C2, nullptr, "GetStepHistory"}, + {0x000C0000, GetTotalStepCount, "GetTotalStepCount"}, + {0x000D0040, nullptr, "SetPedometerRecordingMode"}, + {0x000E0000, nullptr, "GetPedometerRecordingMode"}, + {0x000F0084, nullptr, "GetStepHistoryAll"}, + // ptm:play {0x08070082, nullptr, "GetPlayHistory"}, {0x08080000, nullptr, "GetPlayHistoryStart"}, {0x08090000, nullptr, "GetPlayHistoryLength"}, {0x080B0080, nullptr, "CalcPlayHistoryStart"}, }; -PTM_Play_Interface::PTM_Play_Interface() { +PTM_Play::PTM_Play() { Register(FunctionTable); } diff --git a/src/core/hle/service/ptm/ptm_play.h b/src/core/hle/service/ptm/ptm_play.h index 47f229581..663faabee 100644 --- a/src/core/hle/service/ptm/ptm_play.h +++ b/src/core/hle/service/ptm/ptm_play.h @@ -9,9 +9,9 @@ namespace Service { namespace PTM { -class PTM_Play_Interface : public Service::Interface { +class PTM_Play final : public Interface { public: - PTM_Play_Interface(); + PTM_Play(); std::string GetPortName() const override { return "ptm:play"; diff --git a/src/core/hle/service/ptm/ptm_sets.cpp b/src/core/hle/service/ptm/ptm_sets.cpp new file mode 100644 index 000000000..a8c6cf227 --- /dev/null +++ b/src/core/hle/service/ptm/ptm_sets.cpp @@ -0,0 +1,20 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/ptm/ptm_sets.h" + +namespace Service { +namespace PTM { + +const Interface::FunctionInfo FunctionTable[] = { + // Note that this service does not have access to ptm:u's common commands + {0x00010080, nullptr, "SetSystemTime"}, +}; + +PTM_Sets::PTM_Sets() { + Register(FunctionTable); +} + +} // namespace PTM +} // namespace Service diff --git a/src/core/hle/service/ptm/ptm_sets.h b/src/core/hle/service/ptm/ptm_sets.h new file mode 100644 index 000000000..d33b047e5 --- /dev/null +++ b/src/core/hle/service/ptm/ptm_sets.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace PTM { + +class PTM_Sets final : public Interface { +public: + PTM_Sets(); + + std::string GetPortName() const override { + return "ptm:sets"; + } +}; + +} // namespace PTM +} // namespace Service diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index 693158dbf..f95dfdbb1 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -9,6 +9,23 @@ namespace Service { namespace PTM { const Interface::FunctionInfo FunctionTable[] = { + // ptm:u common commands + {0x00010002, nullptr, "RegisterAlarmClient"}, + {0x00020080, nullptr, "SetRtcAlarm"}, + {0x00030000, nullptr, "GetRtcAlarm"}, + {0x00040000, nullptr, "CancelRtcAlarm"}, + {0x00050000, GetAdapterState, "GetAdapterState"}, + {0x00060000, GetShellState, "GetShellState"}, + {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, + {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"}, + {0x00090000, nullptr, "GetPedometerState"}, + {0x000A0042, nullptr, "GetStepHistoryEntry"}, + {0x000B00C2, nullptr, "GetStepHistory"}, + {0x000C0000, GetTotalStepCount, "GetTotalStepCount"}, + {0x000D0040, nullptr, "SetPedometerRecordingMode"}, + {0x000E0000, nullptr, "GetPedometerRecordingMode"}, + {0x000F0084, nullptr, "GetStepHistoryAll"}, + // ptm:sysm {0x040100C0, nullptr, "SetRtcAlarmEx"}, {0x04020042, nullptr, "ReplySleepQuery"}, {0x04030042, nullptr, "NotifySleepPreparationComplete"}, @@ -33,8 +50,8 @@ const Interface::FunctionInfo FunctionTable[] = { {0x080C0080, nullptr, "SetUserTime"}, {0x080D0000, nullptr, "InvalidateSystemTime"}, {0x080E0140, nullptr, "NotifyPlayEvent"}, - {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"}, - {0x08100000, nullptr, "ClearLegacyPowerOff"}, + {0x080F0000, GetSoftwareClosedFlag, "GetSoftwareClosedFlag"}, + {0x08100000, nullptr, "ClearSoftwareClosedFlag"}, {0x08110000, GetShellState, "GetShellState"}, {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, {0x08130000, nullptr, "FormatSavedata"}, @@ -42,7 +59,11 @@ const Interface::FunctionInfo FunctionTable[] = { {0x08180040, nullptr, "ConfigureNew3DSCPU"}, }; -PTM_Sysm_Interface::PTM_Sysm_Interface() { +PTM_S::PTM_S() { + Register(FunctionTable); +} + +PTM_Sysm::PTM_Sysm() { Register(FunctionTable); } diff --git a/src/core/hle/service/ptm/ptm_sysm.h b/src/core/hle/service/ptm/ptm_sysm.h index e37f20546..8afcebbba 100644 --- a/src/core/hle/service/ptm/ptm_sysm.h +++ b/src/core/hle/service/ptm/ptm_sysm.h @@ -9,9 +9,18 @@ namespace Service { namespace PTM { -class PTM_Sysm_Interface : public Interface { +class PTM_S final : public Interface { public: - PTM_Sysm_Interface(); + PTM_S(); + + std::string GetPortName() const override { + return "ptm:s"; + } +}; + +class PTM_Sysm final : public Interface { +public: + PTM_Sysm(); std::string GetPortName() const override { return "ptm:sysm"; diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp index 65e868393..e0b65ba89 100644 --- a/src/core/hle/service/ptm/ptm_u.cpp +++ b/src/core/hle/service/ptm/ptm_u.cpp @@ -26,7 +26,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x000F0084, nullptr, "GetStepHistoryAll"}, }; -PTM_U_Interface::PTM_U_Interface() { +PTM_U::PTM_U() { Register(FunctionTable); } diff --git a/src/core/hle/service/ptm/ptm_u.h b/src/core/hle/service/ptm/ptm_u.h index bf132f610..7b75d6e49 100644 --- a/src/core/hle/service/ptm/ptm_u.h +++ b/src/core/hle/service/ptm/ptm_u.h @@ -9,9 +9,9 @@ namespace Service { namespace PTM { -class PTM_U_Interface : public Interface { +class PTM_U final : public Interface { public: - PTM_U_Interface(); + PTM_U(); std::string GetPortName() const override { return "ptm:u"; diff --git a/src/core/hle/service/qtm/qtm.cpp b/src/core/hle/service/qtm/qtm.cpp new file mode 100644 index 000000000..f11542263 --- /dev/null +++ b/src/core/hle/service/qtm/qtm.cpp @@ -0,0 +1,21 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/qtm/qtm.h" +#include "core/hle/service/qtm/qtm_s.h" +#include "core/hle/service/qtm/qtm_sp.h" +#include "core/hle/service/qtm/qtm_u.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace QTM { + +void Init() { + AddService(new QTM_S()); + AddService(new QTM_SP()); + AddService(new QTM_U()); +} + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm.h b/src/core/hle/service/qtm/qtm.h new file mode 100644 index 000000000..33b774c79 --- /dev/null +++ b/src/core/hle/service/qtm/qtm.h @@ -0,0 +1,14 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Service { +namespace QTM { + +/// Initializes all QTM services. +void Init(); + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm_s.cpp b/src/core/hle/service/qtm/qtm_s.cpp new file mode 100644 index 000000000..ad7df24a0 --- /dev/null +++ b/src/core/hle/service/qtm/qtm_s.cpp @@ -0,0 +1,23 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/qtm/qtm_s.h" + +namespace Service { +namespace QTM { + +const Interface::FunctionInfo FunctionTable[] = { + // clang-format off + // qtm common commands + {0x00010080, nullptr, "GetHeadtrackingInfoRaw"}, + {0x00020080, nullptr, "GetHeadtrackingInfo"}, + // clang-format on +}; + +QTM_S::QTM_S() { + Register(FunctionTable); +} + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm_s.h b/src/core/hle/service/qtm/qtm_s.h new file mode 100644 index 000000000..e66138ed0 --- /dev/null +++ b/src/core/hle/service/qtm/qtm_s.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace QTM { + +class QTM_S final : public Interface { +public: + QTM_S(); + + std::string GetPortName() const override { + return "qtm:s"; + } +}; + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm_sp.cpp b/src/core/hle/service/qtm/qtm_sp.cpp new file mode 100644 index 000000000..6e0695d34 --- /dev/null +++ b/src/core/hle/service/qtm/qtm_sp.cpp @@ -0,0 +1,23 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/qtm/qtm_sp.h" + +namespace Service { +namespace QTM { + +const Interface::FunctionInfo FunctionTable[] = { + // clang-format off + // qtm common commands + {0x00010080, nullptr, "GetHeadtrackingInfoRaw"}, + {0x00020080, nullptr, "GetHeadtrackingInfo"}, + // clang-format on +}; + +QTM_SP::QTM_SP() { + Register(FunctionTable); +} + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm_sp.h b/src/core/hle/service/qtm/qtm_sp.h new file mode 100644 index 000000000..0ae0618fc --- /dev/null +++ b/src/core/hle/service/qtm/qtm_sp.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace QTM { + +class QTM_SP final : public Interface { +public: + QTM_SP(); + + std::string GetPortName() const override { + return "qtm:sp"; + } +}; + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm_u.cpp b/src/core/hle/service/qtm/qtm_u.cpp new file mode 100644 index 000000000..a0f808432 --- /dev/null +++ b/src/core/hle/service/qtm/qtm_u.cpp @@ -0,0 +1,23 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/qtm/qtm_u.h" + +namespace Service { +namespace QTM { + +const Interface::FunctionInfo FunctionTable[] = { + // clang-format off + // qtm common commands + {0x00010080, nullptr, "GetHeadtrackingInfoRaw"}, + {0x00020080, nullptr, "GetHeadtrackingInfo"}, + // clang-format on +}; + +QTM_U::QTM_U() { + Register(FunctionTable); +} + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/qtm/qtm_u.h b/src/core/hle/service/qtm/qtm_u.h new file mode 100644 index 000000000..1ed4c0adc --- /dev/null +++ b/src/core/hle/service/qtm/qtm_u.h @@ -0,0 +1,22 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace QTM { + +class QTM_U final : public Interface { +public: + QTM_U(); + + std::string GetPortName() const override { + return "qtm:u"; + } +}; + +} // namespace QTM +} // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 9f68898db..2bc3fdc82 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -30,13 +30,16 @@ #include "core/hle/service/ir/ir.h" #include "core/hle/service/ldr_ro/ldr_ro.h" #include "core/hle/service/mic_u.h" +#include "core/hle/service/mvd/mvd.h" #include "core/hle/service/ndm/ndm.h" #include "core/hle/service/news/news.h" +#include "core/hle/service/nfc/nfc.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/ns_s.h" #include "core/hle/service/nwm_uds.h" #include "core/hle/service/pm_app.h" #include "core/hle/service/ptm/ptm.h" +#include "core/hle/service/qtm/qtm.h" #include "core/hle/service/service.h" #include "core/hle/service/soc_u.h" #include "core/hle/service/srv.h" @@ -132,41 +135,44 @@ void AddService(Interface* interface_) { /// Initialize ServiceManager void Init() { - AddNamedPort(new SRV::Interface); - AddNamedPort(new ERR_F::Interface); - - Service::FS::ArchiveInit(); - Service::AM::Init(); - Service::APT::Init(); - Service::BOSS::Init(); - Service::CAM::Init(); - Service::CECD::Init(); - Service::CFG::Init(); - Service::DLP::Init(); - Service::FRD::Init(); - Service::HID::Init(); - Service::IR::Init(); - Service::NEWS::Init(); - Service::NDM::Init(); - Service::NIM::Init(); - Service::PTM::Init(); - - AddService(new AC_U::Interface); - AddService(new ACT_A::Interface); - AddService(new ACT_U::Interface); - AddService(new CSND_SND::Interface); + AddNamedPort(new SRV::SRV); + AddNamedPort(new ERR::ERR_F); + + FS::ArchiveInit(); + AM::Init(); + APT::Init(); + BOSS::Init(); + CAM::Init(); + CECD::Init(); + CFG::Init(); + DLP::Init(); + FRD::Init(); + HID::Init(); + IR::Init(); + MVD::Init(); + NDM::Init(); + NEWS::Init(); + NFC::Init(); + NIM::Init(); + PTM::Init(); + QTM::Init(); + + AddService(new AC::AC_U); + AddService(new ACT::ACT_A); + AddService(new ACT::ACT_U); + AddService(new CSND::CSND_SND); AddService(new DSP_DSP::Interface); - AddService(new GSP_GPU::Interface); - AddService(new GSP_LCD::Interface); - AddService(new HTTP_C::Interface); - AddService(new LDR_RO::Interface); - AddService(new MIC_U::Interface); - AddService(new NS_S::Interface); - AddService(new NWM_UDS::Interface); - AddService(new PM_APP::Interface); - AddService(new SOC_U::Interface); - AddService(new SSL_C::Interface); - AddService(new Y2R_U::Interface); + AddService(new GSP::GSP_GPU); + AddService(new GSP::GSP_LCD); + AddService(new HTTP::HTTP_C); + AddService(new LDR::LDR_RO); + AddService(new MIC::MIC_U); + AddService(new NS::NS_S); + AddService(new NWM::NWM_UDS); + AddService(new PM::PM_APP); + AddService(new SOC::SOC_U); + AddService(new SSL::SSL_C); + AddService(new Y2R::Y2R_U); LOG_DEBUG(Service, "initialized OK"); } @@ -174,21 +180,21 @@ void Init() { /// Shutdown ServiceManager void Shutdown() { - Service::PTM::Shutdown(); - Service::NDM::Shutdown(); - Service::NIM::Shutdown(); - Service::NEWS::Shutdown(); - Service::IR::Shutdown(); - Service::HID::Shutdown(); - Service::FRD::Shutdown(); - Service::DLP::Shutdown(); - Service::CFG::Shutdown(); - Service::CECD::Shutdown(); - Service::CAM::Shutdown(); - Service::BOSS::Shutdown(); - Service::APT::Shutdown(); - Service::AM::Shutdown(); - Service::FS::ArchiveShutdown(); + PTM::Shutdown(); + NIM::Shutdown(); + NEWS::Shutdown(); + NDM::Shutdown(); + IR::Shutdown(); + HID::Shutdown(); + FRD::Shutdown(); + DLP::Shutdown(); + CFG::Shutdown(); + CECD::Shutdown(); + CAM::Shutdown(); + BOSS::Shutdown(); + APT::Shutdown(); + AM::Shutdown(); + FS::ArchiveShutdown(); g_srv_services.clear(); g_kernel_named_ports.clear(); diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 2e8b2fc00..c3918cdd0 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -53,12 +53,10 @@ #define closesocket(x) close(x) #endif -static const s32 SOCKET_ERROR_VALUE = -1; +namespace Service { +namespace SOC { -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace SOC_U - -namespace SOC_U { +const s32 SOCKET_ERROR_VALUE = -1; /// Holds the translation from system network errors to 3DS network errors static const std::unordered_map<int, int> error_map = {{ @@ -339,7 +337,7 @@ static void CleanupSockets() { open_sockets.clear(); } -static void Socket(Service::Interface* self) { +static void Socket(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 domain = cmd_buffer[1]; // Address family u32 type = cmd_buffer[2]; @@ -378,7 +376,7 @@ static void Socket(Service::Interface* self) { cmd_buffer[2] = socket_handle; } -static void Bind(Service::Interface* self) { +static void Bind(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 len = cmd_buffer[2]; @@ -406,7 +404,7 @@ static void Bind(Service::Interface* self) { cmd_buffer[2] = res; } -static void Fcntl(Service::Interface* self) { +static void Fcntl(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 ctr_cmd = cmd_buffer[2]; @@ -475,7 +473,7 @@ static void Fcntl(Service::Interface* self) { } } -static void Listen(Service::Interface* self) { +static void Listen(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 backlog = cmd_buffer[2]; @@ -490,7 +488,7 @@ static void Listen(Service::Interface* self) { cmd_buffer[2] = ret; } -static void Accept(Service::Interface* self) { +static void Accept(Interface* self) { // TODO(Subv): Calling this function on a blocking socket will block the emu thread, // preventing graceful shutdown when closing the emulator, this can be fixed by always // performing nonblocking operations and spinlock until the data is available @@ -518,7 +516,7 @@ static void Accept(Service::Interface* self) { cmd_buffer[3] = IPC::StaticBufferDesc(static_cast<u32>(max_addr_len), 0); } -static void GetHostId(Service::Interface* self) { +static void GetHostId(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); char name[128]; @@ -536,7 +534,7 @@ static void GetHostId(Service::Interface* self) { freeaddrinfo(res); } -static void Close(Service::Interface* self) { +static void Close(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; @@ -553,7 +551,7 @@ static void Close(Service::Interface* self) { cmd_buffer[1] = result; } -static void SendTo(Service::Interface* self) { +static void SendTo(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 len = cmd_buffer[2]; @@ -597,7 +595,7 @@ static void SendTo(Service::Interface* self) { cmd_buffer[1] = result; } -static void RecvFrom(Service::Interface* self) { +static void RecvFrom(Interface* self) { // TODO(Subv): Calling this function on a blocking socket will block the emu thread, // preventing graceful shutdown when closing the emulator, this can be fixed by always // performing nonblocking operations and spinlock until the data is available @@ -654,7 +652,7 @@ static void RecvFrom(Service::Interface* self) { cmd_buffer[3] = total_received; } -static void Poll(Service::Interface* self) { +static void Poll(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 nfds = cmd_buffer[1]; int timeout = cmd_buffer[2]; @@ -692,7 +690,7 @@ static void Poll(Service::Interface* self) { cmd_buffer[2] = ret; } -static void GetSockName(Service::Interface* self) { +static void GetSockName(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; socklen_t ctr_len = cmd_buffer[2]; @@ -720,7 +718,7 @@ static void GetSockName(Service::Interface* self) { cmd_buffer[1] = result; } -static void Shutdown(Service::Interface* self) { +static void Shutdown(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; int how = cmd_buffer[2]; @@ -733,7 +731,7 @@ static void Shutdown(Service::Interface* self) { cmd_buffer[1] = result; } -static void GetPeerName(Service::Interface* self) { +static void GetPeerName(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; socklen_t len = cmd_buffer[2]; @@ -761,7 +759,7 @@ static void GetPeerName(Service::Interface* self) { cmd_buffer[1] = result; } -static void Connect(Service::Interface* self) { +static void Connect(Interface* self) { // TODO(Subv): Calling this function on a blocking socket will block the emu thread, // preventing graceful shutdown when closing the emulator, this can be fixed by always // performing nonblocking operations and spinlock until the data is available @@ -790,7 +788,7 @@ static void Connect(Service::Interface* self) { cmd_buffer[2] = ret; } -static void InitializeSockets(Service::Interface* self) { +static void InitializeSockets(Interface* self) { // TODO(Subv): Implement #ifdef _WIN32 WSADATA data; @@ -802,7 +800,7 @@ static void InitializeSockets(Service::Interface* self) { cmd_buffer[1] = RESULT_SUCCESS.raw; } -static void ShutdownSockets(Service::Interface* self) { +static void ShutdownSockets(Interface* self) { // TODO(Subv): Implement CleanupSockets(); @@ -814,7 +812,7 @@ static void ShutdownSockets(Service::Interface* self) { cmd_buffer[1] = 0; } -static void GetSockOpt(Service::Interface* self) { +static void GetSockOpt(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 level = cmd_buffer[2]; @@ -849,7 +847,7 @@ static void GetSockOpt(Service::Interface* self) { cmd_buffer[3] = optlen; } -static void SetSockOpt(Service::Interface* self) { +static void SetSockOpt(Interface* self) { u32* cmd_buffer = Kernel::GetCommandBuffer(); u32 socket_handle = cmd_buffer[1]; u32 level = cmd_buffer[2]; @@ -916,18 +914,16 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00230040, nullptr, "AddGlobalSocket"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +SOC_U::SOC_U() { Register(FunctionTable); } -Interface::~Interface() { +SOC_U::~SOC_U() { CleanupSockets(); #ifdef _WIN32 WSACleanup(); #endif } -} // namespace +} // namespace SOC +} // namespace Service diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h index 8d02ed30f..5f829fc1c 100644 --- a/src/core/hle/service/soc_u.h +++ b/src/core/hle/service/soc_u.h @@ -7,19 +7,18 @@ #include <string> #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace SOC_U +namespace Service { +namespace SOC { -namespace SOC_U { - -class Interface : public Service::Interface { +class SOC_U final : public Interface { public: - Interface(); - ~Interface(); + SOC_U(); + ~SOC_U(); std::string GetPortName() const override { return "soc:U"; } }; -} // namespace +} // namespace SOC +} // namespace Service diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 18d0a699d..3bd787147 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -11,9 +11,7 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/service/srv.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace SRV - +namespace Service { namespace SRV { static Kernel::SharedPtr<Kernel::Event> event_handle; @@ -27,7 +25,7 @@ static Kernel::SharedPtr<Kernel::Event> event_handle; * 0: 0x00010040 * 1: ResultCode */ -static void RegisterClient(Service::Interface* self) { +static void RegisterClient(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); if (cmd_buff[1] != IPC::CallingPidDesc()) { @@ -52,7 +50,7 @@ static void RegisterClient(Service::Interface* self) { * 2: Translation descriptor: 0x20 * 3: Handle to semaphore signaled on process notification */ -static void EnableNotification(Service::Interface* self) { +static void EnableNotification(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // TODO(bunnei): Change to a semaphore once these have been implemented @@ -77,7 +75,7 @@ static void EnableNotification(Service::Interface* self) { * 1: ResultCode * 3: Service handle */ -static void GetServiceHandle(Service::Interface* self) { +static void GetServiceHandle(Interface* self) { ResultCode res = RESULT_SUCCESS; u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -111,7 +109,7 @@ static void GetServiceHandle(Service::Interface* self) { * 0: 0x00090040 * 1: ResultCode */ -static void Subscribe(Service::Interface* self) { +static void Subscribe(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 notification_id = cmd_buff[1]; @@ -130,7 +128,7 @@ static void Subscribe(Service::Interface* self) { * 0: 0x000A0040 * 1: ResultCode */ -static void Unsubscribe(Service::Interface* self) { +static void Unsubscribe(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 notification_id = cmd_buff[1]; @@ -150,7 +148,7 @@ static void Unsubscribe(Service::Interface* self) { * 0: 0x000C0040 * 1: ResultCode */ -static void PublishToSubscriber(Service::Interface* self) { +static void PublishToSubscriber(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 notification_id = cmd_buff[1]; @@ -179,16 +177,14 @@ const Interface::FunctionInfo FunctionTable[] = { {0x000E00C0, nullptr, "IsServiceRegistered"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +SRV::SRV() { Register(FunctionTable); event_handle = nullptr; } -Interface::~Interface() { +SRV::~SRV() { event_handle = nullptr; } } // namespace SRV +} // namespace Service diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h index 96c89b025..6041ca42d 100644 --- a/src/core/hle/service/srv.h +++ b/src/core/hle/service/srv.h @@ -4,20 +4,19 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace SRV - +namespace Service { namespace SRV { /// Interface to "srv:" service -class Interface : public Service::Interface { +class SRV final : public Interface { public: - Interface(); - ~Interface() override; + SRV(); + ~SRV() override; std::string GetPortName() const override { return "srv:"; } }; -} // namespace +} // namespace SRV +} // namespace Service diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index abab1d271..09ced9d7a 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -6,15 +6,13 @@ #include "common/common_types.h" #include "core/hle/service/ssl_c.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace SSL_C - -namespace SSL_C { +namespace Service { +namespace SSL { // TODO: Implement a proper CSPRNG in the future when actual security is needed static std::mt19937 rand_gen; -static void Initialize(Service::Interface* self) { +static void Initialize(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // Seed random number generator when the SSL service is initialized @@ -25,7 +23,7 @@ static void Initialize(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; } -static void GenerateRandomData(Service::Interface* self) { +static void GenerateRandomData(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 size = cmd_buff[1]; @@ -66,6 +64,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00050082, nullptr, "AddTrustedRootCA"}, {0x00060080, nullptr, "RootCertChainAddDefaultCert"}, {0x00070080, nullptr, "RootCertChainRemoveCert"}, + {0x000D0084, nullptr, "OpenClientCertContext"}, {0x000E0040, nullptr, "OpenDefaultClientCertContext"}, {0x000F0040, nullptr, "CloseClientCertContext"}, {0x00110042, GenerateRandomData, "GenerateRandomData"}, @@ -73,19 +72,19 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00130040, nullptr, "StartConnection"}, {0x00140040, nullptr, "StartConnectionGetOut"}, {0x00150082, nullptr, "Read"}, + {0x00160082, nullptr, "ReadPeek"}, {0x00170082, nullptr, "Write"}, {0x00180080, nullptr, "ContextSetRootCertChain"}, {0x00190080, nullptr, "ContextSetClientCert"}, {0x001B0080, nullptr, "ContextClearOpt"}, + {0x001C00C4, nullptr, "ContextGetProtocolCipher"}, {0x001E0040, nullptr, "DestroyContext"}, {0x001F0082, nullptr, "ContextInitSharedmem"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +SSL_C::SSL_C() { Register(FunctionTable); } -} // namespace +} // namespace SSL_C +} // namespace Service diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h index 58e87c1cb..fc50a2eb2 100644 --- a/src/core/hle/service/ssl_c.h +++ b/src/core/hle/service/ssl_c.h @@ -6,18 +6,17 @@ #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace SSL_C +namespace Service { +namespace SSL { -namespace SSL_C { - -class Interface : public Service::Interface { +class SSL_C final : public Interface { public: - Interface(); + SSL_C(); std::string GetPortName() const override { return "ssl:C"; } }; -} // namespace +} // namespace SSL +} // namespace Service diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index 097e09d28..a20194107 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -11,10 +11,8 @@ #include "core/hle/service/y2r_u.h" #include "core/hw/y2r.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace Y2R_U - -namespace Y2R_U { +namespace Service { +namespace Y2R { struct ConversionParameters { InputFormat input_format; @@ -83,7 +81,7 @@ ResultCode ConversionConfiguration::SetStandardCoefficient( return RESULT_SUCCESS; } -static void SetInputFormat(Service::Interface* self) { +static void SetInputFormat(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.input_format = static_cast<InputFormat>(cmd_buff[1]); @@ -94,7 +92,7 @@ static void SetInputFormat(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called input_format=%hhu", conversion.input_format); } -static void GetInputFormat(Service::Interface* self) { +static void GetInputFormat(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x2, 2, 0); @@ -104,7 +102,7 @@ static void GetInputFormat(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called input_format=%hhu", conversion.input_format); } -static void SetOutputFormat(Service::Interface* self) { +static void SetOutputFormat(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.output_format = static_cast<OutputFormat>(cmd_buff[1]); @@ -115,7 +113,7 @@ static void SetOutputFormat(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called output_format=%hhu", conversion.output_format); } -static void GetOutputFormat(Service::Interface* self) { +static void GetOutputFormat(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x4, 2, 0); @@ -125,7 +123,7 @@ static void GetOutputFormat(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called output_format=%hhu", conversion.output_format); } -static void SetRotation(Service::Interface* self) { +static void SetRotation(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.rotation = static_cast<Rotation>(cmd_buff[1]); @@ -136,7 +134,7 @@ static void SetRotation(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called rotation=%hhu", conversion.rotation); } -static void GetRotation(Service::Interface* self) { +static void GetRotation(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x6, 2, 0); @@ -146,7 +144,7 @@ static void GetRotation(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called rotation=%hhu", conversion.rotation); } -static void SetBlockAlignment(Service::Interface* self) { +static void SetBlockAlignment(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.block_alignment = static_cast<BlockAlignment>(cmd_buff[1]); @@ -157,7 +155,7 @@ static void SetBlockAlignment(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called block_alignment=%hhu", conversion.block_alignment); } -static void GetBlockAlignment(Service::Interface* self) { +static void GetBlockAlignment(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x8, 2, 0); @@ -174,7 +172,7 @@ static void GetBlockAlignment(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetSpacialDithering(Service::Interface* self) { +static void SetSpacialDithering(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); spacial_dithering_enabled = cmd_buff[1] & 0xF; @@ -190,7 +188,7 @@ static void SetSpacialDithering(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : u8, 0 = Disabled, 1 = Enabled */ -static void GetSpacialDithering(Service::Interface* self) { +static void GetSpacialDithering(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0xA, 2, 0); @@ -207,7 +205,7 @@ static void GetSpacialDithering(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetTemporalDithering(Service::Interface* self) { +static void SetTemporalDithering(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); temporal_dithering_enabled = cmd_buff[1] & 0xF; @@ -223,7 +221,7 @@ static void SetTemporalDithering(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : u8, 0 = Disabled, 1 = Enabled */ -static void GetTemporalDithering(Service::Interface* self) { +static void GetTemporalDithering(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0); @@ -240,7 +238,7 @@ static void GetTemporalDithering(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -static void SetTransferEndInterrupt(Service::Interface* self) { +static void SetTransferEndInterrupt(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); transfer_end_interrupt_enabled = cmd_buff[1] & 0xf; @@ -256,7 +254,7 @@ static void SetTransferEndInterrupt(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : u8, 0 = Disabled, 1 = Enabled */ -static void GetTransferEndInterrupt(Service::Interface* self) { +static void GetTransferEndInterrupt(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0xE, 2, 0); @@ -272,7 +270,7 @@ static void GetTransferEndInterrupt(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 3 : The handle of the completion event */ -static void GetTransferEndEvent(Service::Interface* self) { +static void GetTransferEndEvent(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0xF, 2, 0); @@ -282,7 +280,7 @@ static void GetTransferEndEvent(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void SetSendingY(Service::Interface* self) { +static void SetSendingY(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.src_Y.address = cmd_buff[1]; @@ -299,7 +297,7 @@ static void SetSendingY(Service::Interface* self) { cmd_buff[6]); } -static void SetSendingU(Service::Interface* self) { +static void SetSendingU(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.src_U.address = cmd_buff[1]; @@ -316,7 +314,7 @@ static void SetSendingU(Service::Interface* self) { cmd_buff[6]); } -static void SetSendingV(Service::Interface* self) { +static void SetSendingV(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.src_V.address = cmd_buff[1]; @@ -333,7 +331,7 @@ static void SetSendingV(Service::Interface* self) { cmd_buff[6]); } -static void SetSendingYUYV(Service::Interface* self) { +static void SetSendingYUYV(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.src_YUYV.address = cmd_buff[1]; @@ -356,7 +354,7 @@ static void SetSendingYUYV(Service::Interface* self) { * 1 : Result of the function, 0 on success, otherwise error code * 2 : u8, 0 = Not Finished, 1 = Finished */ -static void IsFinishedSendingYuv(Service::Interface* self) { +static void IsFinishedSendingYuv(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x14, 2, 0); @@ -372,7 +370,7 @@ static void IsFinishedSendingYuv(Service::Interface* self) { * 1 : Result of the function, 0 on success, otherwise error code * 2 : u8, 0 = Not Finished, 1 = Finished */ -static void IsFinishedSendingY(Service::Interface* self) { +static void IsFinishedSendingY(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x15, 2, 0); @@ -388,7 +386,7 @@ static void IsFinishedSendingY(Service::Interface* self) { * 1 : Result of the function, 0 on success, otherwise error code * 2 : u8, 0 = Not Finished, 1 = Finished */ -static void IsFinishedSendingU(Service::Interface* self) { +static void IsFinishedSendingU(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x16, 2, 0); @@ -404,7 +402,7 @@ static void IsFinishedSendingU(Service::Interface* self) { * 1 : Result of the function, 0 on success, otherwise error code * 2 : u8, 0 = Not Finished, 1 = Finished */ -static void IsFinishedSendingV(Service::Interface* self) { +static void IsFinishedSendingV(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x17, 2, 0); @@ -414,7 +412,7 @@ static void IsFinishedSendingV(Service::Interface* self) { LOG_WARNING(Service_Y2R, "(STUBBED) called"); } -static void SetReceiving(Service::Interface* self) { +static void SetReceiving(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.dst.address = cmd_buff[1]; @@ -437,7 +435,7 @@ static void SetReceiving(Service::Interface* self) { * 1 : Result of the function, 0 on success, otherwise error code * 2 : u8, 0 = Not Finished, 1 = Finished */ -static void IsFinishedReceiving(Service::Interface* self) { +static void IsFinishedReceiving(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x19, 2, 0); @@ -447,7 +445,7 @@ static void IsFinishedReceiving(Service::Interface* self) { LOG_WARNING(Service_Y2R, "(STUBBED) called"); } -static void SetInputLineWidth(Service::Interface* self) { +static void SetInputLineWidth(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x1A, 1, 0); @@ -456,7 +454,7 @@ static void SetInputLineWidth(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called input_line_width=%u", cmd_buff[1]); } -static void GetInputLineWidth(Service::Interface* self) { +static void GetInputLineWidth(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x1B, 2, 0); @@ -466,7 +464,7 @@ static void GetInputLineWidth(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called input_line_width=%u", conversion.input_line_width); } -static void SetInputLines(Service::Interface* self) { +static void SetInputLines(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x1C, 1, 0); @@ -475,7 +473,7 @@ static void SetInputLines(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called input_lines=%u", cmd_buff[1]); } -static void GetInputLines(Service::Interface* self) { +static void GetInputLines(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x1D, 2, 0); @@ -485,7 +483,7 @@ static void GetInputLines(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called input_lines=%u", conversion.input_lines); } -static void SetCoefficient(Service::Interface* self) { +static void SetCoefficient(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); const u16* coefficients = reinterpret_cast<const u16*>(&cmd_buff[1]); @@ -499,7 +497,7 @@ static void SetCoefficient(Service::Interface* self) { coefficients[5], coefficients[6], coefficients[7]); } -static void GetCoefficient(Service::Interface* self) { +static void GetCoefficient(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x1F, 5, 0); @@ -509,7 +507,7 @@ static void GetCoefficient(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void SetStandardCoefficient(Service::Interface* self) { +static void SetStandardCoefficient(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 index = cmd_buff[1]; @@ -520,7 +518,7 @@ static void SetStandardCoefficient(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called standard_coefficient=%u", index); } -static void GetStandardCoefficient(Service::Interface* self) { +static void GetStandardCoefficient(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 index = cmd_buff[1]; @@ -539,7 +537,7 @@ static void GetStandardCoefficient(Service::Interface* self) { } } -static void SetAlpha(Service::Interface* self) { +static void SetAlpha(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.alpha = cmd_buff[1]; @@ -550,7 +548,7 @@ static void SetAlpha(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called alpha=%hu", conversion.alpha); } -static void GetAlpha(Service::Interface* self) { +static void GetAlpha(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x23, 2, 0); @@ -560,7 +558,7 @@ static void GetAlpha(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called alpha=%hu", conversion.alpha); } -static void SetDitheringWeightParams(Service::Interface* self) { +static void SetDitheringWeightParams(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); std::memcpy(&dithering_weight_params, &cmd_buff[1], sizeof(DitheringWeightParams)); @@ -570,7 +568,7 @@ static void SetDitheringWeightParams(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void GetDitheringWeightParams(Service::Interface* self) { +static void GetDitheringWeightParams(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x25, 9, 0); @@ -580,7 +578,7 @@ static void GetDitheringWeightParams(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void StartConversion(Service::Interface* self) { +static void StartConversion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( @@ -599,7 +597,7 @@ static void StartConversion(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void StopConversion(Service::Interface* self) { +static void StopConversion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x27, 1, 0); @@ -614,7 +612,7 @@ static void StopConversion(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : 1 if there's a conversion running, otherwise 0. */ -static void IsBusyConversion(Service::Interface* self) { +static void IsBusyConversion(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x28, 2, 0); @@ -627,7 +625,7 @@ static void IsBusyConversion(Service::Interface* self) { /** * Y2R_U::SetPackageParameter service function */ -static void SetPackageParameter(Service::Interface* self) { +static void SetPackageParameter(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); auto params = reinterpret_cast<const ConversionParameters*>(&cmd_buff[1]); @@ -668,7 +666,7 @@ cleanup: params->padding, params->alpha); } -static void PingProcess(Service::Interface* self) { +static void PingProcess(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x2A, 2, 0); @@ -678,7 +676,7 @@ static void PingProcess(Service::Interface* self) { LOG_WARNING(Service_Y2R, "(STUBBED) called"); } -static void DriverInitialize(Service::Interface* self) { +static void DriverInitialize(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); conversion.input_format = InputFormat::YUV422_Indiv8; @@ -704,7 +702,7 @@ static void DriverInitialize(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void DriverFinalize(Service::Interface* self) { +static void DriverFinalize(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x2C, 1, 0); @@ -713,7 +711,7 @@ static void DriverFinalize(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } -static void GetPackageParameter(Service::Interface* self) { +static void GetPackageParameter(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[0] = IPC::MakeHeader(0x2D, 4, 0); @@ -771,18 +769,16 @@ const Interface::FunctionInfo FunctionTable[] = { {0x002D0000, GetPackageParameter, "GetPackageParameter"}, }; -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Interface class - -Interface::Interface() { +Y2R_U::Y2R_U() { completion_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "Y2R:Completed"); std::memset(&conversion, 0, sizeof(conversion)); Register(FunctionTable); } -Interface::~Interface() { +Y2R_U::~Y2R_U() { completion_event = nullptr; } -} // namespace +} // namespace Y2R +} // namespace Service
\ No newline at end of file diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h index 1b47b5322..dddeed0be 100644 --- a/src/core/hle/service/y2r_u.h +++ b/src/core/hle/service/y2r_u.h @@ -10,10 +10,8 @@ #include "core/hle/result.h" #include "core/hle/service/service.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Namespace Y2R_U - -namespace Y2R_U { +namespace Service { +namespace Y2R { enum class InputFormat : u8 { /// 8-bit input, with YUV components in separate planes and 4:2:2 subsampling. @@ -127,14 +125,15 @@ struct DitheringWeightParams { u16 w3_xOdd_yOdd; }; -class Interface : public Service::Interface { +class Y2R_U final : public Interface { public: - Interface(); - ~Interface() override; + Y2R_U(); + ~Y2R_U() override; std::string GetPortName() const override { return "y2r:u"; } }; -} // namespace +} // namespace Y2R +} // namespace Service diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 45dedea68..1a1ee90b2 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -8,7 +8,10 @@ #include "common/color.h" #include "common/common_types.h" #include "common/logging/log.h" +#include "common/math_util.h" #include "common/microprofile.h" +#include "common/thread.h" +#include "common/timer.h" #include "common/vector_math.h" #include "core/core_timing.h" #include "core/hle/service/gsp_gpu.h" @@ -35,6 +38,14 @@ const u64 frame_ticks = 268123480ull / 60; static int vblank_event; /// Total number of frames drawn static u64 frame_count; +/// Start clock for frame limiter +static u32 time_point; +/// Total delay caused by slow frames +static float time_delay; +constexpr float FIXED_FRAME_TIME = 1000.0f / 60; +// Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher +// values increases time needed to limit frame rate after spikes +constexpr float MAX_LAG_TIME = 18; template <typename T> inline void Read(T& var, const u32 raw_addr) { @@ -419,9 +430,9 @@ inline void Write(u32 addr, const T data) { // TODO: hwtest this if (config.GetStartAddress() != 0) { if (!is_second_filler) { - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); + Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PSC0); } else { - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); + Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PSC1); } } @@ -462,7 +473,7 @@ inline void Write(u32 addr, const T data) { } g_regs.display_transfer_config.trigger = 0; - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); + Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PPF); } break; } @@ -476,8 +487,8 @@ inline void Write(u32 addr, const T data) { u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->MemoryAccessed( - (u8*)buffer, config.size * sizeof(u32), config.GetPhysicalAddress()); + Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, config.size, + config.GetPhysicalAddress()); } Pica::CommandProcessor::ProcessCommandList(buffer, config.size); @@ -512,6 +523,21 @@ template void Write<u32>(u32 addr, const u32 data); template void Write<u16>(u32 addr, const u16 data); template void Write<u8>(u32 addr, const u8 data); +static void FrameLimiter() { + time_delay += FIXED_FRAME_TIME; + time_delay = MathUtil::Clamp(time_delay, -MAX_LAG_TIME, MAX_LAG_TIME); + s32 desired_time = static_cast<s32>(time_delay); + s32 elapsed_time = static_cast<s32>(Common::Timer::GetTimeMs() - time_point); + + if (elapsed_time < desired_time) { + Common::SleepCurrentThread(desired_time - elapsed_time); + } + + u32 frame_time = Common::Timer::GetTimeMs() - time_point; + + time_delay -= frame_time; +} + /// Update hardware static void VBlankCallback(u64 userdata, int cycles_late) { frame_count++; @@ -522,12 +548,18 @@ static void VBlankCallback(u64 userdata, int cycles_late) { // screen, or if both use the same interrupts and these two instead determine the // beginning and end of the VBlank period. If needed, split the interrupt firing into // two different intervals. - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC0); - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); + Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC0); + Service::GSP::SignalInterrupt(Service::GSP::InterruptId::PDC1); // Check for user input updates Service::HID::Update(); + if (!Settings::values.use_vsync && Settings::values.toggle_framelimit) { + FrameLimiter(); + } + + time_point = Common::Timer::GetTimeMs(); + // Reschedule recurrent event CoreTiming::ScheduleEvent(frame_ticks - cycles_late, vblank_event); } @@ -563,6 +595,7 @@ void Init() { framebuffer_sub.active_fb = 0; frame_count = 0; + time_point = Common::Timer::GetTimeMs(); vblank_event = CoreTiming::RegisterEvent("GPU::VBlankCallback", VBlankCallback); CoreTiming::ScheduleEvent(frame_ticks, vblank_event); diff --git a/src/core/hw/y2r.cpp b/src/core/hw/y2r.cpp index 6a6c707a2..e697f84b3 100644 --- a/src/core/hw/y2r.cpp +++ b/src/core/hw/y2r.cpp @@ -18,7 +18,7 @@ namespace HW { namespace Y2R { -using namespace Y2R_U; +using namespace Service::Y2R; static const size_t MAX_TILES = 1024 / 8; static const size_t TILE_SIZE = 8 * 8; diff --git a/src/core/hw/y2r.h b/src/core/hw/y2r.h index 6b6e71bec..25fcd781c 100644 --- a/src/core/hw/y2r.h +++ b/src/core/hw/y2r.h @@ -2,13 +2,16 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -namespace Y2R_U { +#pragma once + +namespace Service { +namespace Y2R { struct ConversionConfiguration; } +} namespace HW { namespace Y2R { - -void PerformConversion(Y2R_U::ConversionConfiguration& cvt); +void PerformConversion(Service::Y2R::ConversionConfiguration& cvt); } } diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 05f41f798..626e06cd9 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -21,6 +21,7 @@ void Apply() { VideoCore::g_hw_renderer_enabled = values.use_hw_renderer; VideoCore::g_shader_jit_enabled = values.use_shader_jit; VideoCore::g_scaled_resolution_enabled = values.use_scaled_resolution; + VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; if (VideoCore::g_emu_window) { auto layout = VideoCore::g_emu_window->GetFramebufferLayout(); diff --git a/src/core/settings.h b/src/core/settings.h index 7470fdbeb..db4c8fada 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -90,6 +90,7 @@ struct Values { bool use_shader_jit; bool use_scaled_resolution; bool use_vsync; + bool toggle_framelimit; LayoutOption layout_option; bool swap_screen; diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 89237e477..b47156ca4 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -13,6 +13,6 @@ include_directories(../../externals/catch/single_include/) add_executable(tests ${SRCS} ${HEADERS}) target_link_libraries(tests core video_core audio_core common) -target_link_libraries(tests ${PLATFORM_LIBRARIES}) +target_link_libraries(tests ${PLATFORM_LIBRARIES} Threads::Threads) add_test(NAME tests COMMAND $<TARGET_FILE:tests>) diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index c80c96762..0495a9fac 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -68,7 +68,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { switch (id) { // Trigger IRQ case PICA_REG_INDEX(trigger_irq): - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); + Service::GSP::SignalInterrupt(Service::GSP::InterruptId::P3D); break; case PICA_REG_INDEX_WORKAROUND(triangle_topology, 0x25E): diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h index 3c6636d66..c1f9b43c2 100644 --- a/src/video_core/gpu_debugger.h +++ b/src/video_core/gpu_debugger.h @@ -28,7 +28,8 @@ public: * @note All methods in this class are called from the GSP thread */ virtual void GXCommandProcessed(int total_command_count) { - const GSP_GPU::Command& cmd = observed->ReadGXCommandHistory(total_command_count - 1); + const Service::GSP::Command& cmd = + observed->ReadGXCommandHistory(total_command_count - 1); LOG_TRACE(Debug_GPU, "Received command: id=%x", (int)cmd.id.Value()); } @@ -48,16 +49,16 @@ public: return; gx_command_history.emplace_back(); - GSP_GPU::Command& cmd = gx_command_history.back(); + Service::GSP::Command& cmd = gx_command_history.back(); - memcpy(&cmd, command_data, sizeof(GSP_GPU::Command)); + memcpy(&cmd, command_data, sizeof(Service::GSP::Command)); ForEachObserver([this](DebuggerObserver* observer) { observer->GXCommandProcessed(static_cast<int>(this->gx_command_history.size())); }); } - const GSP_GPU::Command& ReadGXCommandHistory(int index) const { + const Service::GSP::Command& ReadGXCommandHistory(int index) const { // TODO: Is this thread-safe? return gx_command_history[index]; } @@ -80,5 +81,5 @@ private: std::vector<DebuggerObserver*> observers; - std::vector<GSP_GPU::Command> gx_command_history; + std::vector<Service::GSP::Command> gx_command_history; }; diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 99bd59a69..b2db609ec 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/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 1b734aaa5..cc7e782a4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -189,10 +189,6 @@ void RasterizerOpenGL::DrawTriangles() { GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, (has_stencil && depth_surface != nullptr) ? depth_surface->texture.handle : 0, 0); - if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return; - } - // Sync the viewport // These registers hold half-width and half-height, so must be multiplied by 2 GLsizei viewport_width = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_x).ToFloat32() * 2; @@ -715,7 +711,11 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe CachedSurface src_params; src_params.addr = config.GetPhysicalInputAddress(); - src_params.width = config.output_width; + // It's important to use the correct source input width to properly skip over parts of the input + // image which will be cropped from the output but still affect the stride of the input image. + src_params.width = config.input_width; + // Using the output's height is fine because we don't read or skip over the remaining part of + // the image, and it allows for smaller texture cache lookup rectangles. src_params.height = config.output_height; src_params.is_tiled = !config.input_linear; src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.input_format); @@ -736,6 +736,11 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe return false; } + // Adjust the source rectangle to take into account parts of the input lines being cropped + if (config.input_width > config.output_width) { + src_rect.right -= (config.input_width - config.output_width) * src_surface->res_scale_width; + } + // Require destination surface to have same resolution scale as source to preserve scaling dst_params.res_scale_width = src_surface->res_scale_width; dst_params.res_scale_height = src_surface->res_scale_height; @@ -798,10 +803,6 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; - } - GLfloat color_values[4] = {0.0f, 0.0f, 0.0f, 0.0f}; // TODO: Handle additional pixel format and fill value size combinations to accelerate more @@ -886,10 +887,6 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) dst_surface->texture.handle, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; - } - GLfloat value_float; if (dst_surface->pixel_format == CachedSurface::PixelFormat::D16) { value_float = config.value_32bit / 65535.0f; // 2^16 - 1 @@ -905,10 +902,6 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst_surface->texture.handle, 0); - if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; - } - GLfloat value_float = (config.value_32bit & 0xFFFFFF) / 16777215.0f; // 2^24 - 1 GLint value_int = (config.value_32bit >> 24); @@ -938,7 +931,7 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con src_params.addr = framebuffer_addr; src_params.width = config.width; src_params.height = config.height; - src_params.stride = pixel_stride; + src_params.pixel_stride = pixel_stride; src_params.is_tiled = false; src_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.color_format); @@ -1074,7 +1067,9 @@ void RasterizerOpenGL::SetShader() { GLint block_size; glGetActiveUniformBlockiv(current_shader->shader.handle, block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &block_size); - ASSERT_MSG(block_size == sizeof(UniformData), "Uniform block size did not match!"); + ASSERT_MSG(block_size == sizeof(UniformData), + "Uniform block size did not match! Got %d, expected %zu", + static_cast<int>(block_size), sizeof(UniformData)); glUniformBlockBinding(current_shader->shader.handle, block_index, 0); // Update uniforms diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 5cbad9b43..0b2e48407 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -103,7 +103,7 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, } } -bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, +void RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, const MathUtil::Rectangle<int>& src_rect, const MathUtil::Rectangle<int>& dst_rect) { @@ -158,14 +158,6 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; } - if (OpenGLState::CheckFBStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; - } - - if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - return false; - } - glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); @@ -174,8 +166,6 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, cur_state.draw.read_framebuffer = old_fbs[0]; cur_state.draw.draw_framebuffer = old_fbs[1]; cur_state.Apply(); - - return true; } bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, @@ -189,9 +179,9 @@ bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, return false; } - return BlitTextures(src_surface->texture.handle, dst_surface->texture.handle, - CachedSurface::GetFormatType(src_surface->pixel_format), src_rect, - dst_rect); + BlitTextures(src_surface->texture.handle, dst_surface->texture.handle, + CachedSurface::GetFormatType(src_surface->pixel_format), src_rect, dst_rect); + return true; } static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format, @@ -291,6 +281,9 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo MICROPROFILE_SCOPE(OpenGL_SurfaceUpload); + // Stride only applies to linear images. + ASSERT(params.pixel_stride == 0 || !params.is_tiled); + std::shared_ptr<CachedSurface> new_surface = std::make_shared<CachedSurface>(); new_surface->addr = params.addr; @@ -299,7 +292,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo new_surface->texture.Create(); new_surface->width = params.width; new_surface->height = params.height; - new_surface->stride = params.stride; + new_surface->pixel_stride = params.pixel_stride; new_surface->res_scale_width = params.res_scale_width; new_surface->res_scale_height = params.res_scale_height; @@ -325,14 +318,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo cur_state.Apply(); glActiveTexture(GL_TEXTURE0); - glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->stride); if (!new_surface->is_tiled) { // TODO: Ensure this will always be a color format, not a depth or other format ASSERT((size_t)new_surface->pixel_format < fb_format_tuples.size()); const FormatTuple& tuple = fb_format_tuples[(unsigned int)params.pixel_format]; + glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->pixel_stride); glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, tuple.format, tuple.type, texture_src_data); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else { SurfaceType type = CachedSurface::GetFormatType(new_surface->pixel_format); if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { @@ -391,7 +385,6 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo 0, tuple.format, tuple.type, temp_fb_depth_buffer.data()); } } - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // If not 1x scale, blit 1x texture to a new scaled texture and replace texture in surface if (new_surface->res_scale_width != 1.f || new_surface->res_scale_height != 1.f) { @@ -701,13 +694,14 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { cur_state.Apply(); glActiveTexture(GL_TEXTURE0); - glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->stride); if (!surface->is_tiled) { // TODO: Ensure this will always be a color format, not a depth or other format ASSERT((size_t)surface->pixel_format < fb_format_tuples.size()); const FormatTuple& tuple = fb_format_tuples[(unsigned int)surface->pixel_format]; + glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->pixel_stride); glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, dst_buffer); + glPixelStorei(GL_PACK_ROW_LENGTH, 0); } else { SurfaceType type = CachedSurface::GetFormatType(surface->pixel_format); if (type != SurfaceType::Depth && type != SurfaceType::DepthStencil) { @@ -750,7 +744,6 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { false); } } - glPixelStorei(GL_PACK_ROW_LENGTH, 0); surface->dirty = false; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 849530d86..b50e8292b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -171,7 +171,8 @@ struct CachedSurface { OGLTexture texture; u32 width; u32 height; - u32 stride = 0; + /// Stride between lines, in pixels. Only valid for images in linear format. + u32 pixel_stride = 0; float res_scale_width = 1.f; float res_scale_height = 1.f; @@ -186,7 +187,7 @@ public: ~RasterizerCacheOpenGL(); /// Blits one texture to another - bool BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, + void BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, const MathUtil::Rectangle<int>& src_rect, const MathUtil::Rectangle<int>& dst_rect); diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index fe07aa6eb..4da241d83 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -4,6 +4,7 @@ #include <vector> #include <glad/glad.h> +#include "common/assert.h" #include "common/logging/log.h" #include "video_core/renderer_opengl/gl_shader_util.h" @@ -31,7 +32,7 @@ GLuint LoadProgram(const char* vertex_shader, const char* fragment_shader) { if (info_log_length > 1) { std::vector<char> vertex_shader_error(info_log_length); glGetShaderInfoLog(vertex_shader_id, info_log_length, nullptr, &vertex_shader_error[0]); - if (result) { + if (result == GL_TRUE) { LOG_DEBUG(Render_OpenGL, "%s", &vertex_shader_error[0]); } else { LOG_ERROR(Render_OpenGL, "Error compiling vertex shader:\n%s", &vertex_shader_error[0]); @@ -51,7 +52,7 @@ GLuint LoadProgram(const char* vertex_shader, const char* fragment_shader) { if (info_log_length > 1) { std::vector<char> fragment_shader_error(info_log_length); glGetShaderInfoLog(fragment_shader_id, info_log_length, nullptr, &fragment_shader_error[0]); - if (result) { + if (result == GL_TRUE) { LOG_DEBUG(Render_OpenGL, "%s", &fragment_shader_error[0]); } else { LOG_ERROR(Render_OpenGL, "Error compiling fragment shader:\n%s", @@ -75,13 +76,20 @@ GLuint LoadProgram(const char* vertex_shader, const char* fragment_shader) { if (info_log_length > 1) { std::vector<char> program_error(info_log_length); glGetProgramInfoLog(program_id, info_log_length, nullptr, &program_error[0]); - if (result) { + if (result == GL_TRUE) { LOG_DEBUG(Render_OpenGL, "%s", &program_error[0]); } else { LOG_ERROR(Render_OpenGL, "Error linking shader:\n%s", &program_error[0]); } } + // If the program linking failed at least one of the shaders was probably bad + if (result == GL_FALSE) { + LOG_ERROR(Render_OpenGL, "Vertex shader:\n%s", vertex_shader); + LOG_ERROR(Render_OpenGL, "Fragment shader:\n%s", fragment_shader); + } + ASSERT_MSG(result == GL_TRUE, "Shader not linked"); + glDeleteShader(vertex_shader_id); glDeleteShader(fragment_shader_id); diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 2a731f483..3c03b424a 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -232,19 +232,6 @@ void OpenGLState::Apply() const { cur_state = *this; } -GLenum OpenGLState::CheckFBStatus(GLenum target) { - GLenum fb_status = glCheckFramebufferStatus(target); - if (fb_status != GL_FRAMEBUFFER_COMPLETE) { - const char* fb_description = - (target == GL_READ_FRAMEBUFFER ? "READ" - : (target == GL_DRAW_FRAMEBUFFER ? "DRAW" : "UNK")); - LOG_CRITICAL(Render_OpenGL, "OpenGL %s framebuffer check failed, status %X", fb_description, - fb_status); - } - - return fb_status; -} - void OpenGLState::ResetTexture(GLuint handle) { for (auto& unit : cur_state.texture_units) { if (unit.texture_2d == handle) { diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 01dead883..aee3c2946 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -90,9 +90,6 @@ public: /// Apply this state as the current OpenGL state void Apply() const; - /// Check the status of the current OpenGL read or draw framebuffer configuration - static GLenum CheckFBStatus(GLenum target); - /// Resets and unbinds any references to the given resource in the current OpenGL state static void ResetTexture(GLuint handle); static void ResetSampler(GLuint handle); diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp index 211c703ab..c96110bb2 100644 --- a/src/video_core/shader/shader_jit_x64.cpp +++ b/src/video_core/shader/shader_jit_x64.cpp @@ -102,11 +102,11 @@ static const X64Reg SETUP = R9; /// The two 32-bit VS address offset registers set by the MOVA instruction static const X64Reg ADDROFFS_REG_0 = R10; static const X64Reg ADDROFFS_REG_1 = R11; -/// VS loop count register +/// VS loop count register (Multiplied by 16) static const X64Reg LOOPCOUNT_REG = R12; /// Current VS loop iteration number (we could probably use LOOPCOUNT_REG, but this quicker) static const X64Reg LOOPCOUNT = RSI; -/// Number to increment LOOPCOUNT_REG by on each loop iteration +/// Number to increment LOOPCOUNT_REG by on each loop iteration (Multiplied by 16) static const X64Reg LOOPINC = RDI; /// Result of the previous CMP instruction for the X-component comparison static const X64Reg COND0 = R13; @@ -491,7 +491,7 @@ void JitShader::Compile_FLR(Instruction instr) { if (Common::GetCPUCaps().sse4_1) { ROUNDFLOORPS(SRC1, R(SRC1)); } else { - CVTPS2DQ(SRC1, R(SRC1)); + CVTTPS2DQ(SRC1, R(SRC1)); CVTDQ2PS(SRC1, R(SRC1)); } @@ -718,15 +718,18 @@ void JitShader::Compile_LOOP(Instruction instr) { looping = true; + // This decodes the fields from the integer uniform at index instr.flow_control.int_uniform_id. + // The Y (LOOPCOUNT_REG) and Z (LOOPINC) component are kept multiplied by 16 (Left shifted by + // 4 bits) to be used as an offset into the 16-byte vector registers later int offset = ShaderSetup::UniformOffset(RegisterType::IntUniform, instr.flow_control.int_uniform_id); MOV(32, R(LOOPCOUNT), MDisp(SETUP, offset)); MOV(32, R(LOOPCOUNT_REG), R(LOOPCOUNT)); - SHR(32, R(LOOPCOUNT_REG), Imm8(8)); - AND(32, R(LOOPCOUNT_REG), Imm32(0xff)); // Y-component is the start + SHR(32, R(LOOPCOUNT_REG), Imm8(4)); + AND(32, R(LOOPCOUNT_REG), Imm32(0xFF0)); // Y-component is the start MOV(32, R(LOOPINC), R(LOOPCOUNT)); - SHR(32, R(LOOPINC), Imm8(16)); - MOVZX(32, 8, LOOPINC, R(LOOPINC)); // Z-component is the incrementer + SHR(32, R(LOOPINC), Imm8(12)); + AND(32, R(LOOPINC), Imm32(0xFF0)); // Z-component is the incrementer MOVZX(32, 8, LOOPCOUNT, R(LOOPCOUNT)); // X-component is iteration count ADD(32, R(LOOPCOUNT), Imm8(1)); // Iteration count is X-component + 1 diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 83e33dfc2..8db882f59 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -21,6 +21,7 @@ std::atomic<bool> g_hw_renderer_enabled; std::atomic<bool> g_shader_jit_enabled; std::atomic<bool> g_scaled_resolution_enabled; std::atomic<bool> g_vsync_enabled; +std::atomic<bool> g_toggle_framelimit_enabled; /// Initialize the video core bool Init(EmuWindow* emu_window) { diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index e2d725ab1..c397c1974 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -38,6 +38,7 @@ extern EmuWindow* g_emu_window; ///< Emu window extern std::atomic<bool> g_hw_renderer_enabled; extern std::atomic<bool> g_shader_jit_enabled; extern std::atomic<bool> g_scaled_resolution_enabled; +extern std::atomic<bool> g_toggle_framelimit_enabled; /// Start the video core void Start(); |