diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra_qt/bootmanager.cpp | 2 | ||||
| -rw-r--r-- | src/citra_qt/debugger/disassembler.cpp | 2 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 2 | ||||
| -rw-r--r-- | src/citra_qt/main.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/applets/applet.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/applets/applet.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/am/am_net.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt.cpp | 53 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt.h | 30 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt_a.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt_s.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt_u.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ldr_ro.cpp | 6 | ||||
| -rw-r--r-- | src/core/hw/y2r.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 80 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/vertex_shader.cpp | 6 |
19 files changed, 148 insertions, 71 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index b12bd858b..a96fbea5f 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -94,7 +94,7 @@ private: | |||
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : | 96 | GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : |
| 97 | QWidget(parent), emu_thread(emu_thread), keyboard_id(0) { | 97 | QWidget(parent), keyboard_id(0), emu_thread(emu_thread) { |
| 98 | 98 | ||
| 99 | std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); | 99 | std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); |
| 100 | setWindowTitle(QString::fromStdString(window_title)); | 100 | setWindowTitle(QString::fromStdString(window_title)); |
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp index 1e5ef5299..d3629bbf6 100644 --- a/src/citra_qt/debugger/disassembler.cpp +++ b/src/citra_qt/debugger/disassembler.cpp | |||
| @@ -159,7 +159,7 @@ void DisassemblerModel::SetNextInstruction(unsigned int address) { | |||
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread) : | 161 | DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread) : |
| 162 | QDockWidget(parent), emu_thread(emu_thread), base_addr(0) { | 162 | QDockWidget(parent), base_addr(0), emu_thread(emu_thread) { |
| 163 | 163 | ||
| 164 | disasm_ui.setupUi(this); | 164 | disasm_ui.setupUi(this); |
| 165 | 165 | ||
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 34831f2ec..e93e8ebb8 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp | |||
| @@ -207,7 +207,7 @@ void GMainWindow::OnDisplayTitleBars(bool show) | |||
| 207 | } | 207 | } |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | void GMainWindow::BootGame(std::string filename) { | 210 | void GMainWindow::BootGame(const std::string& filename) { |
| 211 | LOG_INFO(Frontend, "Citra starting...\n"); | 211 | LOG_INFO(Frontend, "Citra starting...\n"); |
| 212 | 212 | ||
| 213 | // Initialize the core emulation | 213 | // Initialize the core emulation |
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 242b08c39..9fe9e0c9c 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h | |||
| @@ -55,7 +55,7 @@ signals: | |||
| 55 | void EmulationStopping(); | 55 | void EmulationStopping(); |
| 56 | 56 | ||
| 57 | private: | 57 | private: |
| 58 | void BootGame(std::string filename); | 58 | void BootGame(const std::string& filename); |
| 59 | void ShutdownGame(); | 59 | void ShutdownGame(); |
| 60 | 60 | ||
| 61 | void closeEvent(QCloseEvent* event) override; | 61 | void closeEvent(QCloseEvent* event) override; |
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 759ef7285..b88b74752 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -3886,7 +3886,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3886 | #endif | 3886 | #endif |
| 3887 | arm_inst* inst_base; | 3887 | arm_inst* inst_base; |
| 3888 | unsigned int addr; | 3888 | unsigned int addr; |
| 3889 | unsigned int phys_addr; | ||
| 3890 | unsigned int num_instrs = 0; | 3889 | unsigned int num_instrs = 0; |
| 3891 | 3890 | ||
| 3892 | int ptr; | 3891 | int ptr; |
| @@ -3905,8 +3904,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3905 | else | 3904 | else |
| 3906 | cpu->Reg[15] &= 0xfffffffc; | 3905 | cpu->Reg[15] &= 0xfffffffc; |
| 3907 | 3906 | ||
| 3908 | phys_addr = cpu->Reg[15]; | ||
| 3909 | |||
| 3910 | // Find the cached instruction cream, otherwise translate it... | 3907 | // Find the cached instruction cream, otherwise translate it... |
| 3911 | auto itr = cpu->instruction_cache.find(cpu->Reg[15]); | 3908 | auto itr = cpu->instruction_cache.find(cpu->Reg[15]); |
| 3912 | if (itr != cpu->instruction_cache.end()) { | 3909 | if (itr != cpu->instruction_cache.end()) { |
diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp index 826f6cbb6..bc2a1829e 100644 --- a/src/core/hle/applets/applet.cpp +++ b/src/core/hle/applets/applet.cpp | |||
| @@ -89,12 +89,21 @@ ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) | |||
| 89 | return result; | 89 | return result; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | bool IsLibraryAppletRunning() { | ||
| 93 | // Check the applets map for instances of any applet | ||
| 94 | for (auto itr = applets.begin(); itr != applets.end(); ++itr) | ||
| 95 | if (itr->second != nullptr) | ||
| 96 | return true; | ||
| 97 | return false; | ||
| 98 | } | ||
| 99 | |||
| 92 | void Init() { | 100 | void Init() { |
| 93 | // Register the applet update callback | 101 | // Register the applet update callback |
| 94 | applet_update_event = CoreTiming::RegisterEvent("HLE Applet Update Event", AppletUpdateEvent); | 102 | applet_update_event = CoreTiming::RegisterEvent("HLE Applet Update Event", AppletUpdateEvent); |
| 95 | } | 103 | } |
| 96 | 104 | ||
| 97 | void Shutdown() { | 105 | void Shutdown() { |
| 106 | CoreTiming::RemoveEvent(applet_update_event); | ||
| 98 | } | 107 | } |
| 99 | 108 | ||
| 100 | } | 109 | } |
diff --git a/src/core/hle/applets/applet.h b/src/core/hle/applets/applet.h index b235d0b8a..af442f81d 100644 --- a/src/core/hle/applets/applet.h +++ b/src/core/hle/applets/applet.h | |||
| @@ -67,6 +67,9 @@ protected: | |||
| 67 | Service::APT::AppletId id; ///< Id of this Applet | 67 | Service::APT::AppletId id; ///< Id of this Applet |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | /// Returns whether a library applet is currently running | ||
| 71 | bool IsLibraryAppletRunning(); | ||
| 72 | |||
| 70 | /// Initializes the HLE applets | 73 | /// Initializes the HLE applets |
| 71 | void Init(); | 74 | void Init(); |
| 72 | 75 | ||
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 7332478fb..7ae4859a7 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | 6 | ||
| 7 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 8 | #include "core/hle/service/am/am.h" | ||
| 8 | #include "core/hle/service/am/am_app.h" | 9 | #include "core/hle/service/am/am_app.h" |
| 9 | #include "core/hle/service/am/am_net.h" | 10 | #include "core/hle/service/am/am_net.h" |
| 10 | #include "core/hle/service/am/am_sys.h" | 11 | #include "core/hle/service/am/am_sys.h" |
| @@ -35,7 +36,7 @@ void GetTitleIDList(Service::Interface* self) { | |||
| 35 | cmd_buff[1] = RESULT_SUCCESS.raw; | 36 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 36 | cmd_buff[2] = 0; | 37 | cmd_buff[2] = 0; |
| 37 | 38 | ||
| 38 | LOG_WARNING(Service_AM, "(STUBBED) Requested %u titles from media type %u", num_titles, media_type); | 39 | LOG_WARNING(Service_AM, "(STUBBED) Requested %u titles from media type %u. Address=0x%08X", num_titles, media_type, addr); |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | void GetNumContentInfos(Service::Interface* self) { | 42 | void GetNumContentInfos(Service::Interface* self) { |
diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index b1af0e9d8..aa391f3b2 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp | |||
| @@ -28,7 +28,8 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 28 | {0x08130000, nullptr, "GetTotalContents"}, | 28 | {0x08130000, nullptr, "GetTotalContents"}, |
| 29 | {0x08140042, nullptr, "GetContentIndexes"}, | 29 | {0x08140042, nullptr, "GetContentIndexes"}, |
| 30 | {0x08150044, nullptr, "GetContentsInfo"}, | 30 | {0x08150044, nullptr, "GetContentsInfo"}, |
| 31 | {0x08190108, nullptr, "Unknown"}, | 31 | {0x08180042, nullptr, "GetCTCert"}, |
| 32 | {0x08190108, nullptr, "SetCertificates"}, | ||
| 32 | {0x081B00C2, nullptr, "InstallTitlesFinish"}, | 33 | {0x081B00C2, nullptr, "InstallTitlesFinish"}, |
| 33 | }; | 34 | }; |
| 34 | 35 | ||
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 7b6ab4ce0..35402341b 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp | |||
| @@ -101,18 +101,19 @@ void NotifyToWait(Service::Interface* self) { | |||
| 101 | 101 | ||
| 102 | void GetLockHandle(Service::Interface* self) { | 102 | void GetLockHandle(Service::Interface* self) { |
| 103 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 103 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 104 | u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field | 104 | // Bits [0:2] are the applet type (System, Library, etc) |
| 105 | // Bit 5 tells the application that there's a pending APT parameter, | ||
| 106 | // this will cause the app to wait until parameter_event is signaled. | ||
| 107 | u32 applet_attributes = cmd_buff[1]; | ||
| 105 | 108 | ||
| 106 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 109 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 107 | 110 | ||
| 108 | // Not sure what these parameters are used for, but retail apps check that they are 0 after | 111 | cmd_buff[2] = applet_attributes; // Applet Attributes, this value is passed to Enable. |
| 109 | // GetLockHandle has been called. | 112 | cmd_buff[3] = 0; // Least significant bit = power button state |
| 110 | cmd_buff[2] = 0; // Applet Attributes, this value is passed to Enable. | 113 | cmd_buff[4] = IPC::CopyHandleDesc(); |
| 111 | cmd_buff[3] = 0; | ||
| 112 | cmd_buff[4] = 0; | ||
| 113 | |||
| 114 | cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom(); | 114 | cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom(); |
| 115 | LOG_TRACE(Service_APT, "called handle=0x%08X", cmd_buff[5]); | 115 | |
| 116 | LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", cmd_buff[5], applet_attributes); | ||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | void Enable(Service::Interface* self) { | 119 | void Enable(Service::Interface* self) { |
| @@ -139,13 +140,16 @@ void IsRegistered(Service::Interface* self) { | |||
| 139 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 140 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 140 | u32 app_id = cmd_buff[1]; | 141 | u32 app_id = cmd_buff[1]; |
| 141 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 142 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 142 | /// TODO(Subv): It is currently unknown what this value (0x400) means, | 143 | |
| 143 | /// but i believe it is used as a global "LibraryApplet" id, to verify if there's | 144 | // TODO(Subv): An application is considered "registered" if it has already called APT::Enable |
| 144 | /// any LibApplet currently running. This is not verified. | 145 | // handle this properly once we implement multiprocess support. |
| 145 | if (app_id != 0x400) | 146 | cmd_buff[2] = 0; // Set to not registered by default |
| 147 | |||
| 148 | if (app_id == static_cast<u32>(AppletId::AnyLibraryApplet)) { | ||
| 149 | cmd_buff[2] = HLE::Applets::IsLibraryAppletRunning() ? 1 : 0; | ||
| 150 | } else if (auto applet = HLE::Applets::Applet::Get(static_cast<AppletId>(app_id))) { | ||
| 146 | cmd_buff[2] = 1; // Set to registered | 151 | cmd_buff[2] = 1; // Set to registered |
| 147 | else | 152 | } |
| 148 | cmd_buff[2] = 0; // Set to not registered | ||
| 149 | LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); | 153 | LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); |
| 150 | } | 154 | } |
| 151 | 155 | ||
| @@ -330,7 +334,26 @@ void GetAppCpuTimeLimit(Service::Interface* self) { | |||
| 330 | void PrepareToStartLibraryApplet(Service::Interface* self) { | 334 | void PrepareToStartLibraryApplet(Service::Interface* self) { |
| 331 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 335 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 332 | AppletId applet_id = static_cast<AppletId>(cmd_buff[1]); | 336 | AppletId applet_id = static_cast<AppletId>(cmd_buff[1]); |
| 333 | cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw; | 337 | auto applet = HLE::Applets::Applet::Get(applet_id); |
| 338 | if (applet) { | ||
| 339 | LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); | ||
| 340 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 341 | } else { | ||
| 342 | cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw; | ||
| 343 | } | ||
| 344 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 345 | } | ||
| 346 | |||
| 347 | void PreloadLibraryApplet(Service::Interface* self) { | ||
| 348 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 349 | AppletId applet_id = static_cast<AppletId>(cmd_buff[1]); | ||
| 350 | auto applet = HLE::Applets::Applet::Get(applet_id); | ||
| 351 | if (applet) { | ||
| 352 | LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); | ||
| 353 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 354 | } else { | ||
| 355 | cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw; | ||
| 356 | } | ||
| 334 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | 357 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); |
| 335 | } | 358 | } |
| 336 | 359 | ||
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 72972d05b..4a72b6b5c 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h | |||
| @@ -62,6 +62,7 @@ enum class AppletId : u32 { | |||
| 62 | Extrapad = 0x208, | 62 | Extrapad = 0x208, |
| 63 | Memolib = 0x209, | 63 | Memolib = 0x209, |
| 64 | Application = 0x300, | 64 | Application = 0x300, |
| 65 | AnyLibraryApplet = 0x400, | ||
| 65 | SoftwareKeyboard2 = 0x401, | 66 | SoftwareKeyboard2 = 0x401, |
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| @@ -96,8 +97,26 @@ void GetSharedFont(Service::Interface* self); | |||
| 96 | */ | 97 | */ |
| 97 | void NotifyToWait(Service::Interface* self); | 98 | void NotifyToWait(Service::Interface* self); |
| 98 | 99 | ||
| 100 | /** | ||
| 101 | * APT::GetLockHandle service function | ||
| 102 | * Inputs: | ||
| 103 | * 1 : Applet attributes | ||
| 104 | * Outputs: | ||
| 105 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 106 | * 2 : Applet attributes | ||
| 107 | * 3 : Power button state | ||
| 108 | * 4 : IPC handle descriptor | ||
| 109 | * 5 : APT mutex handle | ||
| 110 | */ | ||
| 99 | void GetLockHandle(Service::Interface* self); | 111 | void GetLockHandle(Service::Interface* self); |
| 100 | 112 | ||
| 113 | /** | ||
| 114 | * APT::Enable service function | ||
| 115 | * Inputs: | ||
| 116 | * 1 : Applet attributes | ||
| 117 | * Outputs: | ||
| 118 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 119 | */ | ||
| 101 | void Enable(Service::Interface* self); | 120 | void Enable(Service::Interface* self); |
| 102 | 121 | ||
| 103 | /** | 122 | /** |
| @@ -284,6 +303,17 @@ void GetAppCpuTimeLimit(Service::Interface* self); | |||
| 284 | void PrepareToStartLibraryApplet(Service::Interface* self); | 303 | void PrepareToStartLibraryApplet(Service::Interface* self); |
| 285 | 304 | ||
| 286 | /** | 305 | /** |
| 306 | * APT::PreloadLibraryApplet service function | ||
| 307 | * Inputs: | ||
| 308 | * 0 : Command header [0x00160040] | ||
| 309 | * 1 : Id of the applet to start | ||
| 310 | * Outputs: | ||
| 311 | * 0 : Return header | ||
| 312 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 313 | */ | ||
| 314 | void PreloadLibraryApplet(Service::Interface* self); | ||
| 315 | |||
| 316 | /** | ||
| 287 | * APT::StartLibraryApplet service function | 317 | * APT::StartLibraryApplet service function |
| 288 | * Inputs: | 318 | * Inputs: |
| 289 | * 0 : Command header [0x001E0084] | 319 | * 0 : Command header [0x001E0084] |
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 88de339f9..22800c56f 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp | |||
| @@ -21,6 +21,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 21 | {0x000D0080, ReceiveParameter, "ReceiveParameter"}, | 21 | {0x000D0080, ReceiveParameter, "ReceiveParameter"}, |
| 22 | {0x000E0080, GlanceParameter, "GlanceParameter"}, | 22 | {0x000E0080, GlanceParameter, "GlanceParameter"}, |
| 23 | {0x000F0100, CancelParameter, "CancelParameter"}, | 23 | {0x000F0100, CancelParameter, "CancelParameter"}, |
| 24 | {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, | ||
| 24 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, | 25 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, |
| 25 | {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, | 26 | {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, |
| 26 | {0x003B0040, nullptr, "CancelLibraryApplet?"}, | 27 | {0x003B0040, nullptr, "CancelLibraryApplet?"}, |
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 396d1f04a..3ac6ff94f 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp | |||
| @@ -32,9 +32,9 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 32 | {0x00130000, nullptr, "GetPreparationState"}, | 32 | {0x00130000, nullptr, "GetPreparationState"}, |
| 33 | {0x00140040, nullptr, "SetPreparationState"}, | 33 | {0x00140040, nullptr, "SetPreparationState"}, |
| 34 | {0x00150140, nullptr, "PrepareToStartApplication"}, | 34 | {0x00150140, nullptr, "PrepareToStartApplication"}, |
| 35 | {0x00160040, nullptr, "PreloadLibraryApplet"}, | 35 | {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, |
| 36 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, | 36 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, |
| 37 | {0x00180040, nullptr, "PrepareToStartLibraryApplet"}, | 37 | {0x00180040, PrepareToStartLibraryApplet,"PrepareToStartLibraryApplet"}, |
| 38 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, | 38 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, |
| 39 | {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, | 39 | {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, |
| 40 | {0x001B00C4, nullptr, "StartApplication"}, | 40 | {0x001B00C4, nullptr, "StartApplication"}, |
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index b724cd72b..146bfd595 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp | |||
| @@ -33,7 +33,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 33 | {0x00130000, nullptr, "GetPreparationState"}, | 33 | {0x00130000, nullptr, "GetPreparationState"}, |
| 34 | {0x00140040, nullptr, "SetPreparationState"}, | 34 | {0x00140040, nullptr, "SetPreparationState"}, |
| 35 | {0x00150140, nullptr, "PrepareToStartApplication"}, | 35 | {0x00150140, nullptr, "PrepareToStartApplication"}, |
| 36 | {0x00160040, nullptr, "PreloadLibraryApplet"}, | 36 | {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, |
| 37 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, | 37 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, |
| 38 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, | 38 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, |
| 39 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, | 39 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, |
diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 155b97f69..f84ce4d72 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp | |||
| @@ -40,7 +40,8 @@ static void Initialize(Service::Interface* self) { | |||
| 40 | 40 | ||
| 41 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 41 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 42 | 42 | ||
| 43 | LOG_WARNING(Service_LDR, "(STUBBED) called"); | 43 | LOG_WARNING(Service_LDR, "(STUBBED) called. crs_buffer_ptr=0x%08X, crs_size=0x%08X, address=0x%08X, value=0x%08X, process=0x%08X", |
| 44 | crs_buffer_ptr, crs_size, address, value, process); | ||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | /** | 47 | /** |
| @@ -69,7 +70,8 @@ static void LoadCRR(Service::Interface* self) { | |||
| 69 | 70 | ||
| 70 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 71 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 71 | 72 | ||
| 72 | LOG_WARNING(Service_LDR, "(STUBBED) called"); | 73 | LOG_WARNING(Service_LDR, "(STUBBED) called. crs_buffer_ptr=0x%08X, crs_size=0x%08X, value=0x%08X, process=0x%08X", |
| 74 | crs_buffer_ptr, crs_size, value, process); | ||
| 73 | } | 75 | } |
| 74 | 76 | ||
| 75 | const Interface::FunctionInfo FunctionTable[] = { | 77 | const Interface::FunctionInfo FunctionTable[] = { |
diff --git a/src/core/hw/y2r.cpp b/src/core/hw/y2r.cpp index f80e26ecd..082a4db82 100644 --- a/src/core/hw/y2r.cpp +++ b/src/core/hw/y2r.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/vector_math.h" | 14 | #include "common/vector_math.h" |
| 15 | 15 | ||
| 16 | #include "core/hle/service/y2r_u.h" | 16 | #include "core/hle/service/y2r_u.h" |
| 17 | #include "core/hw/y2r.h" | ||
| 17 | #include "core/memory.h" | 18 | #include "core/memory.h" |
| 18 | 19 | ||
| 19 | namespace HW { | 20 | namespace HW { |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index ef9584abd..36c3b9947 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -221,57 +221,53 @@ static inline void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 221 | // Initialize data for the current vertex | 221 | // Initialize data for the current vertex |
| 222 | VertexShader::InputVertex input; | 222 | VertexShader::InputVertex input; |
| 223 | 223 | ||
| 224 | // Load a debugging token to check whether this gets loaded by the running | ||
| 225 | // application or not. | ||
| 226 | static const float24 debug_token = float24::FromRawFloat24(0x00abcdef); | ||
| 227 | input.attr[0].w = debug_token; | ||
| 228 | |||
| 229 | for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) { | 224 | for (int i = 0; i < attribute_config.GetNumTotalAttributes(); ++i) { |
| 230 | // Load the default attribute if we're configured to do so, this data will be overwritten by the loader data if it's set | 225 | if (vertex_attribute_elements[i] != 0) { |
| 231 | if (attribute_config.IsDefaultAttribute(i)) { | 226 | // Default attribute values set if array elements have < 4 components. This |
| 227 | // is *not* carried over from the default attribute settings even if they're | ||
| 228 | // enabled for this attribute. | ||
| 229 | static const float24 zero = float24::FromFloat32(0.0f); | ||
| 230 | static const float24 one = float24::FromFloat32(1.0f); | ||
| 231 | input.attr[i] = Math::Vec4<float24>(zero, zero, zero, one); | ||
| 232 | |||
| 233 | // Load per-vertex data from the loader arrays | ||
| 234 | for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | ||
| 235 | u32 source_addr = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]; | ||
| 236 | const u8* srcdata = Memory::GetPhysicalPointer(source_addr); | ||
| 237 | |||
| 238 | if (g_debug_context && Pica::g_debug_context->recorder) { | ||
| 239 | memory_accesses.AddAccess(source_addr, | ||
| 240 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) ? 4 | ||
| 241 | : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1); | ||
| 242 | } | ||
| 243 | |||
| 244 | const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : | ||
| 245 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : | ||
| 246 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata : | ||
| 247 | *(float*)srcdata; | ||
| 248 | |||
| 249 | input.attr[i][comp] = float24::FromFloat32(srcval); | ||
| 250 | LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", | ||
| 251 | comp, i, vertex, index, | ||
| 252 | attribute_config.GetPhysicalBaseAddress(), | ||
| 253 | vertex_attribute_sources[i] - base_address, | ||
| 254 | vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i], | ||
| 255 | input.attr[i][comp].ToFloat32()); | ||
| 256 | } | ||
| 257 | } else if (attribute_config.IsDefaultAttribute(i)) { | ||
| 258 | // Load the default attribute if we're configured to do so | ||
| 232 | input.attr[i] = g_state.vs.default_attributes[i]; | 259 | input.attr[i] = g_state.vs.default_attributes[i]; |
| 233 | LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", | 260 | LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", |
| 234 | i, vertex, index, | 261 | i, vertex, index, |
| 235 | input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), | 262 | input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), |
| 236 | input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); | 263 | input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); |
| 237 | } | 264 | } else { |
| 238 | 265 | // TODO(yuriks): In this case, no data gets loaded and the vertex remains | |
| 239 | // Load per-vertex data from the loader arrays | 266 | // with the last value it had. This isn't currently maintained |
| 240 | for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { | 267 | // as global state, however, and so won't work in Cita yet. |
| 241 | u32 source_addr = vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i]; | ||
| 242 | const u8* srcdata = Memory::GetPhysicalPointer(source_addr); | ||
| 243 | |||
| 244 | if (g_debug_context && Pica::g_debug_context->recorder) { | ||
| 245 | memory_accesses.AddAccess(source_addr, | ||
| 246 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) ? 4 | ||
| 247 | : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1); | ||
| 248 | } | ||
| 249 | |||
| 250 | const float srcval = (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::BYTE) ? *(s8*)srcdata : | ||
| 251 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::UBYTE) ? *(u8*)srcdata : | ||
| 252 | (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? *(s16*)srcdata : | ||
| 253 | *(float*)srcdata; | ||
| 254 | |||
| 255 | input.attr[i][comp] = float24::FromFloat32(srcval); | ||
| 256 | LOG_TRACE(HW_GPU, "Loaded component %x of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08lx + 0x%04lx: %f", | ||
| 257 | comp, i, vertex, index, | ||
| 258 | attribute_config.GetPhysicalBaseAddress(), | ||
| 259 | vertex_attribute_sources[i] - base_address, | ||
| 260 | vertex_attribute_strides[i] * vertex + comp * vertex_attribute_element_size[i], | ||
| 261 | input.attr[i][comp].ToFloat32()); | ||
| 262 | } | 268 | } |
| 263 | } | 269 | } |
| 264 | 270 | ||
| 265 | // HACK: Some games do not initialize the vertex position's w component. This leads | ||
| 266 | // to critical issues since it messes up perspective division. As a | ||
| 267 | // workaround, we force the fourth component to 1.0 if we find this to be the | ||
| 268 | // case. | ||
| 269 | // To do this, we additionally have to assume that the first input attribute | ||
| 270 | // is the vertex position, since there's no information about this other than | ||
| 271 | // the empiric observation that this is usually the case. | ||
| 272 | if (input.attr[0].w == debug_token) | ||
| 273 | input.attr[0].w = float24::FromFloat32(1.0); | ||
| 274 | |||
| 275 | if (g_debug_context) | 271 | if (g_debug_context) |
| 276 | g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); | 272 | g_debug_context->OnEvent(DebugContext::Event::VertexLoaded, (void*)&input); |
| 277 | 273 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2db845da6..1fc4e56b1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/color.h" | 8 | #include "common/color.h" |
| 9 | #include "common/math_util.h" | 9 | #include "common/math_util.h" |
| 10 | #include "common/profiler.h" | ||
| 10 | 11 | ||
| 11 | #include "core/hw/gpu.h" | 12 | #include "core/hw/gpu.h" |
| 12 | #include "core/memory.h" | 13 | #include "core/memory.h" |
| @@ -873,11 +874,15 @@ void RasterizerOpenGL::ReloadDepthBuffer() { | |||
| 873 | state.Apply(); | 874 | state.Apply(); |
| 874 | } | 875 | } |
| 875 | 876 | ||
| 877 | Common::Profiling::TimingCategory buffer_commit_category("Framebuffer Commit"); | ||
| 878 | |||
| 876 | void RasterizerOpenGL::CommitColorBuffer() { | 879 | void RasterizerOpenGL::CommitColorBuffer() { |
| 877 | if (last_fb_color_addr != 0) { | 880 | if (last_fb_color_addr != 0) { |
| 878 | u8* color_buffer = Memory::GetPhysicalPointer(last_fb_color_addr); | 881 | u8* color_buffer = Memory::GetPhysicalPointer(last_fb_color_addr); |
| 879 | 882 | ||
| 880 | if (color_buffer != nullptr) { | 883 | if (color_buffer != nullptr) { |
| 884 | Common::Profiling::ScopeTimer timer(buffer_commit_category); | ||
| 885 | |||
| 881 | u32 bytes_per_pixel = Pica::Regs::BytesPerColorPixel(fb_color_texture.format); | 886 | u32 bytes_per_pixel = Pica::Regs::BytesPerColorPixel(fb_color_texture.format); |
| 882 | 887 | ||
| 883 | std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]); | 888 | std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]); |
| @@ -913,6 +918,8 @@ void RasterizerOpenGL::CommitDepthBuffer() { | |||
| 913 | u8* depth_buffer = Memory::GetPhysicalPointer(last_fb_depth_addr); | 918 | u8* depth_buffer = Memory::GetPhysicalPointer(last_fb_depth_addr); |
| 914 | 919 | ||
| 915 | if (depth_buffer != nullptr) { | 920 | if (depth_buffer != nullptr) { |
| 921 | Common::Profiling::ScopeTimer timer(buffer_commit_category); | ||
| 922 | |||
| 916 | u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format); | 923 | u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format); |
| 917 | 924 | ||
| 918 | // OpenGL needs 4 bpp alignment for D24 | 925 | // OpenGL needs 4 bpp alignment for D24 |
diff --git a/src/video_core/vertex_shader.cpp b/src/video_core/vertex_shader.cpp index 960ae5779..5f66f3455 100644 --- a/src/video_core/vertex_shader.cpp +++ b/src/video_core/vertex_shader.cpp | |||
| @@ -609,6 +609,12 @@ OutputVertex RunShader(const InputVertex& input, int num_attributes, const Regs: | |||
| 609 | } | 609 | } |
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | // The hardware takes the absolute and saturates vertex colors like this, *before* doing interpolation | ||
| 613 | for (int i = 0; i < 4; ++i) { | ||
| 614 | ret.color[i] = float24::FromFloat32( | ||
| 615 | std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); | ||
| 616 | } | ||
| 617 | |||
| 612 | LOG_TRACE(Render_Software, "Output vertex: pos (%.2f, %.2f, %.2f, %.2f), col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f)", | 618 | LOG_TRACE(Render_Software, "Output vertex: pos (%.2f, %.2f, %.2f, %.2f), col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f)", |
| 613 | ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), | 619 | ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), |
| 614 | ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), | 620 | ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), |