mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
modules/SceRegistryMgr: Initial implement of regmgr functions.
This commit is contained in:
@@ -134,6 +134,7 @@ add_subdirectory(module)
|
||||
add_subdirectory(modules)
|
||||
add_subdirectory(motion)
|
||||
add_subdirectory(nids)
|
||||
add_subdirectory(regmgr)
|
||||
add_subdirectory(renderer)
|
||||
add_subdirectory(rtc)
|
||||
add_subdirectory(shader)
|
||||
|
||||
@@ -5,4 +5,4 @@ add_library(
|
||||
|
||||
target_include_directories(emuenv INTERFACE include)
|
||||
target_link_libraries(emuenv PUBLIC mem)
|
||||
target_link_libraries(emuenv PRIVATE app audio config ctrl dialog display ime io kernel lang miniz motion net ngs nids np renderer touch gdbstub codec packages http)
|
||||
target_link_libraries(emuenv PRIVATE app audio config ctrl dialog display ime io kernel lang miniz motion net ngs nids np regmgr renderer touch gdbstub codec packages http)
|
||||
|
||||
@@ -53,6 +53,7 @@ struct NpState;
|
||||
struct DisplayState;
|
||||
struct DialogState;
|
||||
struct Ime;
|
||||
struct RegMgrState;
|
||||
struct SfoFile;
|
||||
struct GDBState;
|
||||
struct HTTPState;
|
||||
@@ -96,6 +97,7 @@ private:
|
||||
std::unique_ptr<DisplayState> _display;
|
||||
std::unique_ptr<DialogState> _common_dialog;
|
||||
std::unique_ptr<Ime> _ime;
|
||||
std::unique_ptr<RegMgrState> _regmgr;
|
||||
std::unique_ptr<SfoFile> _sfo_handle;
|
||||
std::unique_ptr<GDBState> _gdb;
|
||||
std::unique_ptr<HTTPState> _http;
|
||||
@@ -151,6 +153,7 @@ public:
|
||||
DisplayState &display;
|
||||
DialogState &common_dialog;
|
||||
Ime &ime;
|
||||
RegMgrState ®mgr;
|
||||
SfoFile &sfo_handle;
|
||||
NIDSet missing_nids;
|
||||
float dpi_scale = 1.f;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <nids/types.h>
|
||||
#include <np/state.h>
|
||||
#include <packages/sfo.h>
|
||||
#include <regmgr/state.h>
|
||||
#include <renderer/state.h>
|
||||
#include <touch/state.h>
|
||||
|
||||
@@ -76,6 +77,8 @@ EmuEnvState::EmuEnvState()
|
||||
, common_dialog(*_common_dialog)
|
||||
, _ime(new Ime)
|
||||
, ime(*_ime)
|
||||
, _regmgr(new RegMgrState)
|
||||
, regmgr(*_regmgr)
|
||||
, _sfo_handle(new SfoFile)
|
||||
, sfo_handle(*_sfo_handle)
|
||||
, _gdb(new GDBState)
|
||||
|
||||
@@ -50,6 +50,6 @@ add_library(
|
||||
)
|
||||
|
||||
target_include_directories(gui PUBLIC include ${CMAKE_SOURCE_DIR}/vita3k)
|
||||
target_link_libraries(gui PUBLIC app compat config dialog emuenv https ime imgui glutil lang np)
|
||||
target_link_libraries(gui PUBLIC app compat config dialog emuenv https ime imgui glutil lang regmgr np)
|
||||
target_link_libraries(gui PRIVATE audio ctrl kernel miniz psvpfsparser pugixml::pugixml stb renderer packages sdl2 vkutil host::dialog)
|
||||
target_link_libraries(gui PUBLIC tracy)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <io/vfs.h>
|
||||
#include <lang/functions.h>
|
||||
#include <packages/sfo.h>
|
||||
#include <regmgr/functions.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/log.h>
|
||||
#include <util/string_utils.h>
|
||||
@@ -711,6 +712,7 @@ void init(GuiState &gui, EmuEnvState &emuenv) {
|
||||
get_sys_apps_title(gui, emuenv);
|
||||
|
||||
init_home(gui, emuenv);
|
||||
regmgr::init_regmgr(emuenv.regmgr, emuenv.pref_path);
|
||||
|
||||
// Initialize trophy callback
|
||||
emuenv.np.trophy_state.trophy_unlock_callback = [&gui](NpTrophyUnlockCallbackData &callback_data) {
|
||||
|
||||
@@ -750,7 +750,7 @@ void draw_home_screen(GuiState &gui, EmuEnvState &emuenv) {
|
||||
const auto display_app = [&](const std::vector<gui::App> &apps_list, std::map<std::string, ImGui_Texture> &apps_icon) {
|
||||
for (const auto &app : apps_list) {
|
||||
bool selected = false;
|
||||
const auto is_not_sys_app = app.title_id.find("NPXS") == std::string::npos;
|
||||
const auto is_not_sys_app = app.path.find("NPXS") == std::string::npos;
|
||||
|
||||
if (is_not_sys_app) {
|
||||
// Filter app by region and type
|
||||
|
||||
@@ -110,8 +110,13 @@ bool init(IOState &io, const fs::path &base_path, const fs::path &pref_path, boo
|
||||
const fs::path ux0_data{ ux0 / "data" };
|
||||
const fs::path uma0_data{ uma0 / "data" };
|
||||
const fs::path ux0_app{ ux0 / "app" };
|
||||
const fs::path ux0_picture{ ux0 / "picture" };
|
||||
const fs::path ux0_theme{ ux0 / "theme" };
|
||||
const fs::path ux0_video{ ux0 / "video" };
|
||||
const fs::path ux0_user{ ux0 / "user" };
|
||||
const fs::path vd0{ pref_path / (+VitaIoDevice::vd0)._to_string() };
|
||||
const fs::path vd0_registry{ vd0 / "registry" };
|
||||
const fs::path vd0_network{ vd0 / "network" };
|
||||
|
||||
if (!fs::exists(ux0))
|
||||
fs::create_directories(ux0);
|
||||
@@ -119,14 +124,22 @@ bool init(IOState &io, const fs::path &base_path, const fs::path &pref_path, boo
|
||||
fs::create_directory(ux0_data);
|
||||
if (!fs::exists(ux0_app))
|
||||
fs::create_directory(ux0_app);
|
||||
if (!fs::exists(ux0_picture))
|
||||
fs::create_directory(ux0_picture);
|
||||
if (!fs::exists(ux0_theme))
|
||||
fs::create_directory(ux0_theme);
|
||||
if (!fs::exists(ux0_video))
|
||||
fs::create_directory(ux0_video);
|
||||
if (!fs::exists(ux0_user))
|
||||
fs::create_directory(ux0_user);
|
||||
if (!fs::exists(uma0))
|
||||
fs::create_directory(uma0);
|
||||
if (!fs::exists(uma0_data))
|
||||
fs::create_directory(uma0_data);
|
||||
if (!fs::exists(vd0_registry))
|
||||
fs::create_directories(vd0_registry);
|
||||
if (!fs::exists(vd0_network))
|
||||
fs::create_directories(vd0_network);
|
||||
|
||||
fs::create_directories(base_path / "cache/shaders");
|
||||
fs::create_directory(base_path / "shaderlog");
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include "SceRegMgr.h"
|
||||
|
||||
#include <regmgr/functions.h>
|
||||
|
||||
#include <util/tracy.h>
|
||||
TRACY_MODULE_NAME(SceRegMgr);
|
||||
|
||||
@@ -40,30 +42,34 @@ EXPORT(int, sceRegMgrGetInitVals) {
|
||||
return UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrGetKeyBin) {
|
||||
TRACY_FUNC(sceRegMgrGetKeyBin);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrGetKeyBin, const char *category, const char *name, void *buf, SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrGetKeyBin, category, name, buf, bufSize);
|
||||
memcpy(buf, regmgr::get_str_value(emuenv.regmgr, category, name).c_str(), bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrGetKeyInt, const char *category, const char *name, int *buf) {
|
||||
EXPORT(int, sceRegMgrGetKeyInt, const char *category, const char *name, SceInt32 *buf) {
|
||||
TRACY_FUNC(sceRegMgrGetKeyInt, category, name, buf);
|
||||
if ((std::string(category) == "/CONFIG/PSPEMU") && (std::string(name) == "emu_list_flag")) {
|
||||
STUBBED("Stubbed");
|
||||
*buf = 1;
|
||||
*buf = regmgr::get_int_value(emuenv.regmgr, category, name);
|
||||
|
||||
return 0;
|
||||
} else
|
||||
return UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrGetKeyStr) {
|
||||
TRACY_FUNC(sceRegMgrGetKeyStr);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrGetKeyStr, const char *category, const char *name, char *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrGetKeyStr, category, name, buf, bufSize);
|
||||
strncpy(buf, regmgr::get_str_value(emuenv.regmgr, category, name).c_str(), bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrGetKeys) {
|
||||
TRACY_FUNC(sceRegMgrGetKeys);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrGetKeys, const char *category, Keys *keys, const SceUInt32 elementsNumber) {
|
||||
TRACY_FUNC(sceRegMgrGetKeys, category, keys, elementsNumber);
|
||||
for (SceUInt32 i = 0; i < elementsNumber; i++) {
|
||||
keys[i].value = regmgr::get_int_value(emuenv.regmgr, category, keys[i].name.get(emuenv.mem));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrGetKeysInfo) {
|
||||
@@ -96,24 +102,34 @@ EXPORT(int, sceRegMgrResetRegistryLv) {
|
||||
return UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSetKeyBin) {
|
||||
TRACY_FUNC(sceRegMgrSetKeyBin);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSetKeyBin, const char *category, const char *name, const void *buf, SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrSetKeyBin, category, name, buf, bufSize);
|
||||
regmgr::set_bin_value(emuenv.regmgr, emuenv.pref_path, category, name, buf, bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSetKeyInt, const char *category, const char *name, int buf) {
|
||||
EXPORT(int, sceRegMgrSetKeyInt, const char *category, const char *name, const SceInt32 buf) {
|
||||
TRACY_FUNC(sceRegMgrSetKeyInt, category, name, buf);
|
||||
return UNIMPLEMENTED();
|
||||
regmgr::set_int_value(emuenv.regmgr, emuenv.pref_path, category, name, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSetKeyStr) {
|
||||
TRACY_FUNC(sceRegMgrSetKeyStr);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSetKeyStr, const char *category, const char *name, char *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrSetKeyStr, category, name, buf, bufSize);
|
||||
regmgr::set_str_value(emuenv.regmgr, emuenv.pref_path, category, name, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSetKeys) {
|
||||
TRACY_FUNC(sceRegMgrSetKeys);
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSetKeys, const char *category, const Keys *keys, const SceInt32 elementsNumber) {
|
||||
TRACY_FUNC(sceRegMgrSetKeys, category, keys, elementsNumber);
|
||||
for (auto i = 0; i < elementsNumber; i++) {
|
||||
regmgr::set_int_value(emuenv.regmgr, emuenv.pref_path, category, keys[i].name.get(emuenv.mem), keys[i].value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrStartCallback) {
|
||||
|
||||
@@ -17,32 +17,61 @@
|
||||
|
||||
#include "SceRegMgrForGame.h"
|
||||
|
||||
#include <regmgr/functions.h>
|
||||
|
||||
#include <util/tracy.h>
|
||||
TRACY_MODULE_NAME(SceRegMgrForGame);
|
||||
|
||||
EXPORT(int, sceRegMgrSystemIsBlueScreen) {
|
||||
return UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSystemParamGetBin) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSystemParamGetBin, const int id, void *buf, SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrSystemParamGetBin, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
memcpy(buf, regmgr::get_str_value(emuenv.regmgr, category, name).c_str(), bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSystemParamGetInt) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSystemParamGetInt, const int id, SceInt32 *buf) {
|
||||
TRACY_FUNC(sceRegMgrSystemParamGetInt, id, buf);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
*buf = regmgr::get_int_value(emuenv.regmgr, category, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSystemParamGetStr) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSystemParamGetStr, const int id, char *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrSystemParamGetStr, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
strncpy(buf, regmgr::get_str_value(emuenv.regmgr, category, name).c_str(), bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSystemParamSetBin) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSystemParamSetBin, const int id, const void *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrSystemParamSetBin, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
regmgr::set_bin_value(emuenv.regmgr, emuenv.pref_path, category, name, buf, bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSystemParamSetInt) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSystemParamSetInt, const int id, const SceInt32 buf) {
|
||||
TRACY_FUNC(sceRegMgrSystemParamSetInt, id, buf);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
regmgr::set_int_value(emuenv.regmgr, emuenv.pref_path, category, name, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrSystemParamSetStr) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrSystemParamSetStr, const int id, const char *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrSystemParamSetStr, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
regmgr::set_str_value(emuenv.regmgr, emuenv.pref_path, category, name, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BRIDGE_IMPL(sceRegMgrSystemIsBlueScreen)
|
||||
|
||||
@@ -17,28 +17,57 @@
|
||||
|
||||
#include "SceRegMgrForSDK.h"
|
||||
|
||||
EXPORT(int, sceRegMgrUtilityGetBin) {
|
||||
return UNIMPLEMENTED();
|
||||
#include <regmgr/functions.h>
|
||||
|
||||
#include <util/tracy.h>
|
||||
TRACY_MODULE_NAME(SceRegMgrForSdk);
|
||||
|
||||
EXPORT(int, sceRegMgrUtilityGetBin, const int id, void *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrUtilityGetBin, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
memcpy(buf, regmgr::get_str_value(emuenv.regmgr, category, name).c_str(), bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrUtilityGetInt) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrUtilityGetInt, const int id, SceInt32 *buf) {
|
||||
TRACY_FUNC(sceRegMgrUtilityGetInt, id, buf);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
*buf = regmgr::get_int_value(emuenv.regmgr, category, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrUtilityGetStr) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrUtilityGetStr, const int id, char *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrUtilityGetStr, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
strncpy(buf, regmgr::get_str_value(emuenv.regmgr, category, name).c_str(), bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrUtilitySetBin) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrUtilitySetBin, const int id, const void *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrUtilitySetBin, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
regmgr::set_bin_value(emuenv.regmgr, emuenv.pref_path, category, name, buf, bufSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrUtilitySetInt) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrUtilitySetInt, const int id, SceInt32 buf) {
|
||||
TRACY_FUNC(sceRegMgrUtilitySetInt, id, buf);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
regmgr::set_int_value(emuenv.regmgr, emuenv.pref_path, category, name, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT(int, sceRegMgrUtilitySetStr) {
|
||||
return UNIMPLEMENTED();
|
||||
EXPORT(int, sceRegMgrUtilitySetStr, const int id, const char *buf, const SceSize bufSize) {
|
||||
TRACY_FUNC(sceRegMgrUtilitySetStr, id, buf, bufSize);
|
||||
const auto [category, name] = regmgr::get_category_and_name_by_id(id, export_name);
|
||||
regmgr::set_str_value(emuenv.regmgr, emuenv.pref_path, category, name, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BRIDGE_IMPL(sceRegMgrUtilityGetBin)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
add_library(
|
||||
regmgr
|
||||
STATIC
|
||||
include/regmgr/functions.h
|
||||
include/regmgr/state.h
|
||||
include/regmgr/types.h
|
||||
src/regmgr.cpp
|
||||
)
|
||||
|
||||
target_include_directories(regmgr PUBLIC include)
|
||||
target_include_directories(regmgr PRIVATE)
|
||||
target_link_libraries(regmgr PUBLIC util)
|
||||
@@ -0,0 +1,43 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2023 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <regmgr/state.h>
|
||||
#include <regmgr/types.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace regmgr {
|
||||
|
||||
void init_regmgr(RegMgrState ®mgr, const std::wstring &pref_path);
|
||||
|
||||
// Setters for binary values
|
||||
void set_bin_value(RegMgrState ®mgr, const std::wstring &pref_path, const std::string &category, const std::string &name, const void *buf, uint32_t bufSize);
|
||||
|
||||
// Geters and setters for int values
|
||||
int32_t get_int_value(RegMgrState ®mgr, const std::string &category, const std::string &name);
|
||||
void set_int_value(RegMgrState ®mgr, const std::wstring &pref_path, const std::string &category, const std::string &name, int32_t value);
|
||||
|
||||
// Getters and setters for string values
|
||||
std::string get_str_value(RegMgrState ®mgr, const std::string &category, const std::string &name);
|
||||
void set_str_value(RegMgrState ®mgr, const std::wstring &pref_path, const std::string &category, const std::string &name, const std::string &value);
|
||||
|
||||
//
|
||||
std::pair<std::string, std::string> get_category_and_name_by_id(const int id, const std::string &export_name);
|
||||
|
||||
} // namespace regmgr
|
||||
@@ -0,0 +1,35 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2023 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct RegValue {
|
||||
std::string name;
|
||||
uint32_t size;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
struct RegMgrState {
|
||||
std::mutex mutex;
|
||||
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, std::string>> system_dreg;
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2023 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mem/ptr.h>
|
||||
#include <util/types.h>
|
||||
|
||||
struct Keys {
|
||||
int size; // sizeof(this)
|
||||
Ptr<const char> name;
|
||||
int type; // todo
|
||||
SceInt32 value;
|
||||
};
|
||||
@@ -0,0 +1,366 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2023 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#include <regex>
|
||||
#include <regmgr/functions.h>
|
||||
|
||||
#include <util/log.h>
|
||||
|
||||
namespace regmgr {
|
||||
|
||||
const std::array<unsigned char, 16> xorKey = { 0x89, 0xFA, 0x95, 0x48, 0xCB, 0x6D, 0x77, 0x9D, 0xA2, 0x25, 0x34, 0xFD, 0xA9, 0x35, 0x59, 0x6E };
|
||||
|
||||
static std::string decryptRegistryFile(const fs::path reg_path) {
|
||||
std::ifstream file(reg_path.string(), std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
LOG_WARN("Error while opening file: {}, install firmware for solve this!", reg_path.string());
|
||||
return {};
|
||||
}
|
||||
|
||||
// Read the data from the file encrypted
|
||||
std::vector<uint8_t> encryptedData((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
// Check if file is empty
|
||||
if (encryptedData.empty()) {
|
||||
LOG_DEBUG("File is empty: {}", reg_path.string());
|
||||
return {};
|
||||
}
|
||||
|
||||
// Remove the header of the file (138 bytes)
|
||||
encryptedData.erase(encryptedData.begin(), encryptedData.begin() + 138);
|
||||
|
||||
// Decrypt the data with the xor key
|
||||
for (size_t i = 0; i < encryptedData.size(); i++) {
|
||||
encryptedData[i] ^= xorKey[i & 0xF];
|
||||
}
|
||||
|
||||
// Convert the data to a string
|
||||
std::string res;
|
||||
for (const auto &byte : encryptedData) {
|
||||
res += byte;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, std::vector<RegValue>> reg_template;
|
||||
|
||||
void init_reg_template(RegMgrState ®mgr, const std::string ®) {
|
||||
std::unordered_map<int, std::string> reg_map;
|
||||
|
||||
std::istringstream iss(reg);
|
||||
std::string line;
|
||||
while (std::getline(iss, line)) {
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
// Found the base register
|
||||
if (line.find("[BASE") != std::string::npos) {
|
||||
// Register the names with their numbers
|
||||
while (std::getline(iss, line) && (line != "[REG-BAS")) {
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
size_t pos = line.find('=');
|
||||
if (pos != std::string::npos) {
|
||||
const auto num = std::stoi(line.substr(0, pos));
|
||||
const auto name = line.substr(pos + 1);
|
||||
reg_map[num] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line == "[REG-BAS") {
|
||||
// Register the base register
|
||||
while (std::getline(iss, line) && (line != ("[REG-J1"))) {
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
size_t pos = line.find('=');
|
||||
if (pos != std::string::npos) {
|
||||
std::string entry = line.substr(0, pos);
|
||||
std::string value = line.substr(pos + 1);
|
||||
|
||||
std::string name = "/";
|
||||
std::istringstream f(entry);
|
||||
std::string s;
|
||||
while (std::getline(f, s, '/')) {
|
||||
if (!s.empty())
|
||||
name += reg_map[std::stoi(s)];
|
||||
}
|
||||
|
||||
const auto last_slash_pos = name.find_last_of('/') + 1;
|
||||
const auto valueName = name.substr(last_slash_pos);
|
||||
const auto category = name.substr(0, last_slash_pos);
|
||||
|
||||
std::istringstream v(value);
|
||||
std::vector<std::string> values;
|
||||
while (std::getline(v, s, ':')) {
|
||||
if (!s.empty())
|
||||
values.push_back(s);
|
||||
}
|
||||
|
||||
const auto valueSize = static_cast<uint32_t>(std::stoi(values[1]));
|
||||
const std::regex categoryRangePattern(R"((.*\/)([0-9]{2})-([0-9]{2})(\/.*))");
|
||||
std::smatch matches;
|
||||
if (std::regex_search(category, matches, categoryRangePattern)) {
|
||||
const auto cat_begin = matches[1].str();
|
||||
const auto firstNum = std::stoi(matches[2].str());
|
||||
const auto secondNum = std::stoi(matches[3].str());
|
||||
const auto cat_end = matches[4].str();
|
||||
|
||||
for (int i = firstNum; i <= secondNum; i++) {
|
||||
const std::string categoryName = fmt::format("{}{:0>2d}{}", cat_begin, i, cat_end);
|
||||
reg_template[categoryName].push_back({ valueName, valueSize, values.back() });
|
||||
}
|
||||
} else
|
||||
reg_template[category].push_back({ valueName, valueSize, values.back() });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t get_space_size(const uint32_t str_size) {
|
||||
const uint32_t spaceSize = 32;
|
||||
const uint32_t line = 16;
|
||||
|
||||
return spaceSize > str_size ? spaceSize - str_size : ((str_size / line) + 1) * line - str_size;
|
||||
}
|
||||
|
||||
static bool load_system_dreg(RegMgrState ®mgr, const std::wstring &pref_path) {
|
||||
const auto system_dreg_path{ fs::path(pref_path) / "vd0/registry/system.dreg" };
|
||||
fs::ifstream file(system_dreg_path, std::ios::in | std::ios::binary);
|
||||
if (file.is_open()) {
|
||||
char buf = 0;
|
||||
|
||||
// Skip the space
|
||||
for (uint32_t i = 0; i < 33; i++) {
|
||||
file.read(&buf, 1);
|
||||
}
|
||||
|
||||
for (const auto ® : reg_template) {
|
||||
// Read the category
|
||||
const uint32_t cat_size = static_cast<uint32_t>(reg.first.size());
|
||||
std::vector<char> category(cat_size);
|
||||
file.read(category.data(), cat_size);
|
||||
const auto category_str = std::string(category.begin(), category.end());
|
||||
if (category_str != reg.first) {
|
||||
LOG_ERROR("Invalid category: {}, expected: {}", category_str, reg.first);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the space
|
||||
const auto diff_cat = get_space_size(cat_size);
|
||||
for (uint32_t i = 0; i < diff_cat; i++) {
|
||||
file.read(&buf, 1);
|
||||
}
|
||||
|
||||
for (const auto &entry : reg.second) {
|
||||
// Read the name
|
||||
const uint32_t name_size = static_cast<uint32_t>(entry.name.size());
|
||||
std::vector<char> name(name_size);
|
||||
file.read(name.data(), name_size);
|
||||
const auto name_str = std::string(name.begin(), name.end());
|
||||
if (name_str != entry.name) {
|
||||
LOG_ERROR("Invalid entry name: {}, expected: {}", name_str, entry.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the space
|
||||
const auto diff_name = get_space_size(name_size + 1);
|
||||
for (uint32_t i = 0; i < diff_name; i++) {
|
||||
file.read(&buf, 1);
|
||||
}
|
||||
|
||||
// Read the value
|
||||
const uint32_t value_size = entry.size;
|
||||
std::vector<char> value(value_size);
|
||||
file.read(value.data(), value_size);
|
||||
const auto value_str = std::string(value.begin(), value.end());
|
||||
regmgr.system_dreg[reg.first][entry.name] = value_str;
|
||||
|
||||
// Skip the space
|
||||
const auto diff_value = get_space_size(value_size);
|
||||
for (uint32_t i = 0; i < (diff_value + 1); i++) {
|
||||
file.read(&buf, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
} else
|
||||
LOG_WARN("Registry file not found: {}, attempting to create it", system_dreg_path.string());
|
||||
|
||||
return !regmgr.system_dreg.empty();
|
||||
}
|
||||
|
||||
static void save_system_dreg(RegMgrState ®mgr, const std::wstring pref_path) {
|
||||
const auto system_dreg_path{ fs::path(pref_path) / "vd0/registry/system.dreg" };
|
||||
fs::ofstream file(system_dreg_path, std::ios::out | std::ios::binary);
|
||||
if (file.is_open()) {
|
||||
const char buf = 0;
|
||||
|
||||
// Write the space
|
||||
for (uint32_t i = 0; i < 33; i++) {
|
||||
file.write(&buf, 1);
|
||||
}
|
||||
|
||||
// Write each category
|
||||
for (const auto ® : reg_template) {
|
||||
// Write the category
|
||||
const uint32_t cat_size = static_cast<uint32_t>(reg.first.size());
|
||||
std::vector<char> category(cat_size);
|
||||
strncpy(category.data(), reg.first.c_str(), cat_size);
|
||||
file.write(reg.first.c_str(), cat_size);
|
||||
|
||||
// Write the space
|
||||
const auto diff_cat = get_space_size(cat_size);
|
||||
for (uint32_t i = 0; i < diff_cat; i++) {
|
||||
file.write(&buf, 1);
|
||||
}
|
||||
|
||||
// Write each entry
|
||||
for (const auto &entry : reg.second) {
|
||||
// Write the name
|
||||
const uint32_t name_size = static_cast<uint32_t>(entry.name.size());
|
||||
std::vector<char> name(name_size);
|
||||
strncpy(name.data(), entry.name.c_str(), name_size);
|
||||
file.write(name.data(), name_size);
|
||||
|
||||
// Write the space
|
||||
const auto diff_name = get_space_size(name_size + 1);
|
||||
for (uint32_t i = 0; i < diff_name; i++) {
|
||||
file.write(&buf, 1);
|
||||
}
|
||||
|
||||
// Write the value
|
||||
const uint32_t value_size = entry.size;
|
||||
std::vector<char> value(value_size);
|
||||
regmgr.system_dreg[reg.first][entry.name].copy(value.data(), value_size);
|
||||
file.write(value.data(), value_size);
|
||||
|
||||
// Write the space
|
||||
const auto diff_value = get_space_size(value_size);
|
||||
for (uint32_t i = 0; i < (diff_value + 1); i++) {
|
||||
file.write(&buf, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
static void init_system_dreg(RegMgrState ®mgr, const std::wstring pref_path) {
|
||||
regmgr.system_dreg.clear();
|
||||
|
||||
for (const auto ® : reg_template) {
|
||||
for (const auto &entry : reg.second) {
|
||||
regmgr.system_dreg[reg.first][entry.name] = entry.value;
|
||||
}
|
||||
}
|
||||
|
||||
save_system_dreg(regmgr, pref_path);
|
||||
}
|
||||
|
||||
static std::string fix_category(const std::string& category) {
|
||||
return category.back() == '/' ? category : category + '/';
|
||||
}
|
||||
|
||||
void set_bin_value(RegMgrState ®mgr, const std::wstring &pref_path, const std::string &category, const std::string &name, const void *buf, const uint32_t size) {
|
||||
std::lock_guard<std::mutex> lock(regmgr.mutex);
|
||||
|
||||
const char *data = reinterpret_cast<const char *>(buf);
|
||||
const std::vector<char> bin(data, data + size);
|
||||
regmgr.system_dreg[fix_category(category)][name] = std::string(bin.begin(), bin.end());
|
||||
|
||||
save_system_dreg(regmgr, pref_path);
|
||||
}
|
||||
|
||||
int32_t get_int_value(RegMgrState ®mgr, const std::string &category, const std::string &name) {
|
||||
std::lock_guard<std::mutex> lock(regmgr.mutex);
|
||||
|
||||
return std::stoi(regmgr.system_dreg[fix_category(category)][name]);
|
||||
}
|
||||
|
||||
void set_int_value(RegMgrState ®mgr, const std::wstring &pref_path, const std::string &category, const std::string &name, int32_t value) {
|
||||
std::lock_guard<std::mutex> lock(regmgr.mutex);
|
||||
regmgr.system_dreg[fix_category(category)][name] = std::to_string(value);
|
||||
|
||||
save_system_dreg(regmgr, pref_path);
|
||||
}
|
||||
|
||||
std::string get_str_value(RegMgrState ®mgr, const std::string &category, const std::string &name) {
|
||||
std::lock_guard<std::mutex> lock(regmgr.mutex);
|
||||
|
||||
return regmgr.system_dreg[fix_category(category)][name];
|
||||
}
|
||||
|
||||
void set_str_value(RegMgrState ®mgr, const std::wstring &pref_path, const std::string &category, const std::string &name, const std::string &value) {
|
||||
std::lock_guard<std::mutex> lock(regmgr.mutex);
|
||||
regmgr.system_dreg[fix_category(category)][name] = value;
|
||||
|
||||
save_system_dreg(regmgr, pref_path);
|
||||
}
|
||||
|
||||
void init_regmgr(RegMgrState ®mgr, const std::wstring &pref_path) {
|
||||
const auto reg = decryptRegistryFile(fs::path(pref_path) / "os0/kd/registry.db0");
|
||||
if (reg.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the registry template
|
||||
init_reg_template(regmgr, reg);
|
||||
|
||||
// Initialize the system.dreg
|
||||
if (!load_system_dreg(regmgr, pref_path)) {
|
||||
init_system_dreg(regmgr, pref_path);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> get_category_and_name_by_id(const int id, const std::string &export_name) {
|
||||
switch (id) {
|
||||
case 0x00023fc2:
|
||||
return { "/CONFIG/ACCESSIBILITY/", "large_text" };
|
||||
case 0x00037502:
|
||||
return { "/CONFIG/SYSTEM/", "language" };
|
||||
case 0x00088776:
|
||||
return { "/CONFIG/DATE/", "date_format" };
|
||||
case 0x00186122:
|
||||
return { "/CONFIG/SECURITY/PARENTAL/", "passcode" };
|
||||
case 0x00229142:
|
||||
return { "/CONFIG/SYSTEM/", "button_assign" };
|
||||
case 0x00450F32:
|
||||
return { "/CONFIG/NP/", "account_id" };
|
||||
case 0x00598438:
|
||||
return { "/CONFIG/SYSTEM/", "username" };
|
||||
case 0x00611DC9:
|
||||
return { "/CONFIG/ACCESSIBILITY/", "bold_text" };
|
||||
case 0x00668503:
|
||||
return { "/CONFIG/DATE/", "time_format" };
|
||||
case 0x00683DCD:
|
||||
return { "/CONFIG/SYSTEM/", "key_pad" };
|
||||
case 0x008A2AD7:
|
||||
return { "/CONFIG/ACCESSIBILITY/", "contrast" };
|
||||
default:
|
||||
LOG_WARN("{}: unknown id: {}", export_name, log_hex(id));
|
||||
return { "", "" };
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace regmgr
|
||||
Reference in New Issue
Block a user