diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb88266791..042303f79a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2298,6 +2298,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/HLE/scePower.h
Core/HLE/scePsmf.cpp
Core/HLE/scePsmf.h
+ Core/HLE/sceReg.cpp
+ Core/HLE/sceReg.h
Core/HLE/sceRtc.cpp
Core/HLE/sceRtc.h
Core/HLE/sceSas.cpp
diff --git a/Common/StringUtils.h b/Common/StringUtils.h
index e2424ba1b8..1bfccb2521 100644
--- a/Common/StringUtils.h
+++ b/Common/StringUtils.h
@@ -63,6 +63,10 @@ inline bool endsWithNoCase(std::string_view str, std::string_view key) {
return strncasecmp(str.data() + offset, key.data(), key.size()) == 0;
}
+inline bool equals(std::string_view str, std::string_view key) {
+ return str == key;
+}
+
inline bool equalsNoCase(std::string_view str, std::string_view key) {
if (str.size() != key.size())
return false;
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 9fb5aab8aa..b8160f184e 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -578,6 +578,7 @@
+
@@ -1201,6 +1202,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 496f07b415..4ef4ec1600 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -1348,6 +1348,9 @@
Core
+
+ HLE\Libraries
+
@@ -2181,6 +2184,9 @@
HLE\Kernel
+
+ HLE\Libraries
+
diff --git a/Core/HLE/AtracCtx2.cpp b/Core/HLE/AtracCtx2.cpp
index 655a074b4b..1457083199 100644
--- a/Core/HLE/AtracCtx2.cpp
+++ b/Core/HLE/AtracCtx2.cpp
@@ -1048,7 +1048,7 @@ void Atrac2::CheckForSas() {
if (info.state != 0x10) {
WARN_LOG(Log::ME, "Caller forgot to set state to 0x10");
}
- sas_.isStreaming = info.fileDataEnd > info.bufferByte;
+ sas_.isStreaming = info.fileDataEnd > (s32)info.bufferByte;
if (sas_.isStreaming) {
INFO_LOG(Log::ME, "SasAtrac stream mode");
} else {
diff --git a/Core/HLE/ErrorCodes.h b/Core/HLE/ErrorCodes.h
index a443ca8b81..afbc2eabbb 100644
--- a/Core/HLE/ErrorCodes.h
+++ b/Core/HLE/ErrorCodes.h
@@ -495,4 +495,10 @@ enum PSPErrorCode : u32 {
SCE_SAS_ERROR_NOT_INIT = 0x80420100,
SCE_AVCODEC_ERROR_INVALID_DATA = 0x807f00fd,
+
+ // These are inferred from behavior.
+ SCE_REG_ERROR_CATEGORY_INACCESSIBLE = 0x80082712,
+ SCE_REG_ERROR_REGISTRY_NOT_FOUND = 0x80082715,
+ SCE_REG_ERROR_ROOT_NOT_ACCESSIBLE = 0x80082716,
+ SCE_REG_ERROR_CATEGORY_NOT_FOUND = 0x80082718,
};
diff --git a/Core/HLE/FunctionWrappers.h b/Core/HLE/FunctionWrappers.h
index 3f6351a529..8bfc6e9fcd 100644
--- a/Core/HLE/FunctionWrappers.h
+++ b/Core/HLE/FunctionWrappers.h
@@ -523,6 +523,21 @@ template void WrapI_ICIU() {
RETURN(retval);
}
+template void WrapI_ICUU() {
+ int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3));
+ RETURN(retval);
+}
+
+template void WrapI_ICUUU() {
+ int retval = func(PARAM(0), Memory::GetCharPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4));
+ RETURN(retval);
+}
+
+template void WrapI_IIUU() {
+ int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3));
+ RETURN(retval);
+}
+
template void WrapI_CIU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2));
RETURN(retval);
diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp
index ec896920ad..0439520898 100644
--- a/Core/HLE/HLETables.cpp
+++ b/Core/HLE/HLETables.cpp
@@ -64,6 +64,7 @@
#include "scePower.h"
#include "scePspNpDrm_user.h"
#include "scePsmf.h"
+#include "sceReg.h"
#include "sceRtc.h"
#include "sceSas.h"
#include "sceSircs.h"
@@ -323,6 +324,7 @@ void RegisterAllModules() {
Register_InterruptManagerForKernel();
Register_sceSircs();
Register_sceNet_lib();
+ Register_sceReg();
// Not ready to enable this due to apparent softlocks in Patapon 3.
// Register_sceNpMatching2();
diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp
index 8b0f8ae2d5..afd5d48f87 100644
--- a/Core/HLE/sceKernel.cpp
+++ b/Core/HLE/sceKernel.cpp
@@ -75,6 +75,7 @@
#include "scePower.h"
#include "sceUtility.h"
#include "sceUmd.h"
+#include "sceReg.h"
#include "sceRtc.h"
#include "sceSsl.h"
#include "sceSas.h"
@@ -164,6 +165,7 @@ void __KernelInit()
__OpenPSIDInit();
__HttpInit();
__NpInit();
+ __RegInit();
SaveState::Init(); // Must be after IO, as it may create a directory
Reporting::Init();
@@ -188,6 +190,7 @@ void __KernelShutdown()
hleCurrentThreadName = NULL;
kernelObjects.Clear();
+ __RegShutdown();
__HttpShutdown();
__OpenPSIDShutdown();
__UsbCamShutdown();
@@ -303,6 +306,7 @@ void __KernelDoState(PointerWrap &p)
__AACDoState(p);
__UsbGpsDoState(p);
__UsbMicDoState(p);
+ __RegDoState(p);
// IMPORTANT! Add new sections last!
}
@@ -1492,6 +1496,10 @@ const char *KernelErrorToString(u32 err) {
case SCE_AVCODEC_ERROR_INVALID_DATA: return "SCE_AVCODEC_ERROR_INVALID_DATA";
+ case SCE_REG_ERROR_CATEGORY_INACCESSIBLE: return "SCE_REG_ERROR_CATEGORY_INACCESSIBLE";
+ case SCE_REG_ERROR_CATEGORY_NOT_FOUND: return "SCE_REG_ERROR_CATEGORY_NOT_FOUND";
+ case SCE_REG_ERROR_REGISTRY_NOT_FOUND: return "SCE_REG_ERROR_REGISTRY_NOT_FOUND";
+
default:
return nullptr;
}
diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp
index ecb81fa31c..9a7b596a48 100644
--- a/Core/HLE/sceKernelModule.cpp
+++ b/Core/HLE/sceKernelModule.cpp
@@ -715,7 +715,7 @@ void ExportFuncSymbol(const FuncSymbolExport &func) {
for (SceUID moduleId : loadedModules) {
PSPModule *module = kernelObjects.Get(moduleId, error);
if (!module || !module->ImportsOrExportsModuleName(func.moduleName)) {
- continue;
+ continue;
}
// Look for imports currently loaded modules already have, hook it up right away.
diff --git a/Core/HLE/sceReg.cpp b/Core/HLE/sceReg.cpp
new file mode 100644
index 0000000000..0750aceba9
--- /dev/null
+++ b/Core/HLE/sceReg.cpp
@@ -0,0 +1,699 @@
+#include