Compare commits
15 Commits
main
...
kernel_and
Author | SHA1 | Date |
---|---|---|
raziel1000 | cbf6a62ef5 | |
raziel1000 | 5cf24a8be3 | |
georgemoralis | 95ea2ce3d1 | |
georgemoralis | d1f6df5d82 | |
raziel1000 | e8ecf14f68 | |
raziel1000 | a34fcc4678 | |
raziel1000 | b3c77ba835 | |
georgemoralis | b380a0751e | |
raziel1000 | a6bd198d52 | |
georgemoralis | 84467efe51 | |
georgemoralis | 8bae44a90b | |
georgemoralis | ae9a779369 | |
georgemoralis | 4c8719d33d | |
georgemoralis | edc9543590 | |
georgemoralis | c49c2f6c70 |
|
@ -100,7 +100,12 @@ set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
|
|||
src/core/libraries/gnmdriver/gnmdriver.h
|
||||
)
|
||||
|
||||
set(KERNEL_LIB src/core/libraries/kernel/cpu_management.cpp
|
||||
set(KERNEL_LIB src/core/libraries/kernel/event_flag/event_flag.cpp
|
||||
src/core/libraries/kernel/event_flag/event_flag.h
|
||||
src/core/libraries/kernel/event_flag/event_flag_codes.h
|
||||
src/core/libraries/kernel/event_flag/event_flag_obj.cpp
|
||||
src/core/libraries/kernel/event_flag/event_flag_obj.h
|
||||
src/core/libraries/kernel/cpu_management.cpp
|
||||
src/core/libraries/kernel/cpu_management.h
|
||||
src/core/libraries/kernel/event_queue.cpp
|
||||
src/core/libraries/kernel/event_queue.h
|
||||
|
@ -147,6 +152,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
|||
src/core/libraries/system/systemservice.h
|
||||
src/core/libraries/system/userservice.cpp
|
||||
src/core/libraries/system/userservice.h
|
||||
src/core/libraries/rtc/rtc.cpp
|
||||
src/core/libraries/rtc/rtc.h
|
||||
)
|
||||
|
||||
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||
|
|
|
@ -101,6 +101,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
|||
SUB(Lib, NpTrophy) \
|
||||
SUB(Lib, Screenshot) \
|
||||
SUB(Lib, LibCInternal) \
|
||||
SUB(Lib, Rtc) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Vulkan) \
|
||||
|
|
|
@ -68,6 +68,7 @@ enum class Class : u8 {
|
|||
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
||||
Lib_Screenshot, ///< The LibSceScreenshot implementation
|
||||
Lib_LibCInternal, ///< The LibCInternal implementation.
|
||||
Lib_Rtc, ///< The LibSceRtc implementation.
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Video Core
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <common/assert.h>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "event_flag.h"
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
int PS4_SYSV_ABI sceKernelCreateEventFlag(OrbisKernelEventFlag* ef, const char* pName, u32 attr,
|
||||
u64 initPattern,
|
||||
const OrbisKernelEventFlagOptParam* pOptParam) {
|
||||
LOG_INFO(Kernel_Event, "called name = {} attr = {:#x} initPattern = {:#x}", pName, attr,
|
||||
initPattern);
|
||||
if (ef == nullptr || pName == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (pOptParam || !pName ||
|
||||
attr > (ORBIS_KERNEL_EVF_ATTR_MULTI | ORBIS_KERNEL_EVF_ATTR_TH_PRIO)) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
if (strlen(pName) >= 32) {
|
||||
return ORBIS_KERNEL_ERROR_ENAMETOOLONG;
|
||||
}
|
||||
|
||||
bool single = true;
|
||||
bool fifo = true;
|
||||
|
||||
switch (attr) {
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
single = true;
|
||||
fifo = true;
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
single = false;
|
||||
fifo = true;
|
||||
break;
|
||||
case 0x22:
|
||||
single = false;
|
||||
fifo = false;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
*ef = new EventFlagInternal(std::string(pName), single, fifo, initPattern);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelDeleteEventFlag(OrbisKernelEventFlag ef) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelOpenEventFlag() {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelCloseEventFlag() {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelClearEventFlag(OrbisKernelEventFlag ef, u64 bitPattern) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPattern,
|
||||
int* pNumWaitThreads) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelSetEventFlag(OrbisKernelEventFlag ef, u64 bitPattern) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelPollEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
|
||||
u64* pResultPat) {
|
||||
LOG_ERROR(Kernel_Event, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
|
||||
u64* pResultPat, OrbisKernelUseconds* pTimeout) {
|
||||
LOG_INFO(Kernel_Event, "called bitPattern = {:#x} waitMode = {:#x}", bitPattern, waitMode);
|
||||
if (ef == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
if (bitPattern == 0) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
EventFlagInternal::WaitMode wait = EventFlagInternal::WaitMode::And;
|
||||
EventFlagInternal::ClearMode clear = EventFlagInternal::ClearMode::None;
|
||||
|
||||
switch (waitMode & 0xf) {
|
||||
case 0x01:
|
||||
wait = EventFlagInternal::WaitMode::And;
|
||||
break;
|
||||
case 0x02:
|
||||
wait = EventFlagInternal::WaitMode::Or;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
switch (waitMode & 0xf0) {
|
||||
case 0x00:
|
||||
clear = EventFlagInternal::ClearMode::None;
|
||||
break;
|
||||
case 0x10:
|
||||
clear = EventFlagInternal::ClearMode::All;
|
||||
break;
|
||||
case 0x20:
|
||||
clear = EventFlagInternal::ClearMode::Bits;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
auto result = ef->Wait(bitPattern, wait, clear, pResultPat, pTimeout);
|
||||
|
||||
if (result != ORBIS_OK) {
|
||||
LOG_ERROR(Kernel_Event, "returned {}", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
void RegisterKernelEventFlag(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("PZku4ZrXJqg", "libkernel", 1, "libkernel", 1, 1, sceKernelCancelEventFlag);
|
||||
LIB_FUNCTION("7uhBFWRAS60", "libkernel", 1, "libkernel", 1, 1, sceKernelClearEventFlag);
|
||||
LIB_FUNCTION("s9-RaxukuzQ", "libkernel", 1, "libkernel", 1, 1, sceKernelCloseEventFlag);
|
||||
LIB_FUNCTION("BpFoboUJoZU", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEventFlag);
|
||||
LIB_FUNCTION("8mql9OcQnd4", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteEventFlag);
|
||||
LIB_FUNCTION("1vDaenmJtyA", "libkernel", 1, "libkernel", 1, 1, sceKernelOpenEventFlag);
|
||||
LIB_FUNCTION("9lvj5DjHZiA", "libkernel", 1, "libkernel", 1, 1, sceKernelPollEventFlag);
|
||||
LIB_FUNCTION("IOnSvHzqu6A", "libkernel", 1, "libkernel", 1, 1, sceKernelSetEventFlag);
|
||||
LIB_FUNCTION("JTvBflhYazQ", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitEventFlag);
|
||||
}
|
||||
} // namespace Libraries::Kernel
|
|
@ -0,0 +1,40 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
#include "event_flag_codes.h"
|
||||
#include "event_flag_obj.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
using OrbisKernelUseconds = u32;
|
||||
using OrbisKernelEventFlag = EventFlagInternal*;
|
||||
|
||||
struct OrbisKernelEventFlagOptParam {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
int PS4_SYSV_ABI sceKernelCreateEventFlag(OrbisKernelEventFlag* ef, const char* pName, u32 attr,
|
||||
u64 initPattern,
|
||||
const OrbisKernelEventFlagOptParam* pOptParam);
|
||||
int PS4_SYSV_ABI sceKernelDeleteEventFlag(OrbisKernelEventFlag ef);
|
||||
int PS4_SYSV_ABI sceKernelOpenEventFlag();
|
||||
int PS4_SYSV_ABI sceKernelCloseEventFlag();
|
||||
int PS4_SYSV_ABI sceKernelClearEventFlag(OrbisKernelEventFlag ef, u64 bitPattern);
|
||||
int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPattern,
|
||||
int* pNumWaitThreads);
|
||||
int PS4_SYSV_ABI sceKernelSetEventFlag(OrbisKernelEventFlag ef, u64 bitPattern);
|
||||
int PS4_SYSV_ABI sceKernelPollEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
|
||||
u64* pResultPat);
|
||||
int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
|
||||
u64* pResultPat, OrbisKernelUseconds* pTimeout);
|
||||
|
||||
void RegisterKernelEventFlag(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
} // namespace Libraries::Kernel
|
|
@ -0,0 +1,14 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
constexpr int ORBIS_KERNEL_EVF_ATTR_TH_FIFO = 0x01;
|
||||
constexpr int ORBIS_KERNEL_EVF_ATTR_TH_PRIO = 0x02;
|
||||
constexpr int ORBIS_KERNEL_EVF_ATTR_SINGLE = 0x10;
|
||||
constexpr int ORBIS_KERNEL_EVF_ATTR_MULTI = 0x20;
|
||||
|
||||
constexpr int ORBIS_KERNEL_EVF_WAITMODE_AND = 0x01;
|
||||
constexpr int ORBIS_KERNEL_EVF_WAITMODE_OR = 0x02;
|
||||
constexpr int ORBIS_KERNEL_EVF_WAITMODE_CLEAR_ALL = 0x10;
|
||||
constexpr int ORBIS_KERNEL_EVF_WAITMODE_CLEAR_PAT = 0x20;
|
|
@ -0,0 +1,73 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <core/libraries/error_codes.h>
|
||||
#include "event_flag_obj.h"
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
int EventFlagInternal::Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result,
|
||||
u32* ptr_micros) {
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
uint32_t micros = 0;
|
||||
bool infinitely = true;
|
||||
if (ptr_micros != nullptr) {
|
||||
micros = *ptr_micros;
|
||||
infinitely = false;
|
||||
}
|
||||
|
||||
if (m_single_thread && m_waiting_threads > 0) {
|
||||
return ORBIS_KERNEL_ERROR_EPERM;
|
||||
}
|
||||
|
||||
auto const start = std::chrono::system_clock::now();
|
||||
m_waiting_threads++;
|
||||
auto waitFunc = [this, wait_mode, bits] {
|
||||
return (m_status == Status::Canceled || m_status == Status::Deleted ||
|
||||
(wait_mode == WaitMode::And && (m_bits & bits) == bits) ||
|
||||
(wait_mode == WaitMode::Or && (m_bits & bits) != 0));
|
||||
};
|
||||
|
||||
if (infinitely) {
|
||||
m_cond_var.wait(lock, waitFunc);
|
||||
} else {
|
||||
if (!m_cond_var.wait_for(lock, std::chrono::microseconds(micros), waitFunc)) {
|
||||
if (result != nullptr) {
|
||||
*result = m_bits;
|
||||
}
|
||||
*ptr_micros = 0;
|
||||
--m_waiting_threads;
|
||||
return ORBIS_KERNEL_ERROR_ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
--m_waiting_threads;
|
||||
if (result != nullptr) {
|
||||
*result = m_bits;
|
||||
}
|
||||
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::system_clock::now() - start)
|
||||
.count();
|
||||
if (result != nullptr) {
|
||||
*result = m_bits;
|
||||
}
|
||||
|
||||
if (ptr_micros != nullptr) {
|
||||
*ptr_micros = (elapsed >= micros ? 0 : micros - elapsed);
|
||||
}
|
||||
|
||||
if (m_status == Status::Canceled) {
|
||||
return ORBIS_KERNEL_ERROR_ECANCELED;
|
||||
} else if (m_status == Status::Deleted) {
|
||||
return ORBIS_KERNEL_ERROR_EACCES;
|
||||
}
|
||||
|
||||
if (clear_mode == ClearMode::All) {
|
||||
m_bits = 0;
|
||||
} else if (clear_mode == ClearMode::Bits) {
|
||||
m_bits &= ~bits;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
} // namespace Libraries::Kernel
|
|
@ -0,0 +1,34 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
class EventFlagInternal {
|
||||
public:
|
||||
enum class ClearMode { None, All, Bits };
|
||||
|
||||
enum class WaitMode { And, Or };
|
||||
|
||||
EventFlagInternal(const std::string& name, bool single, bool fifo, uint64_t bits)
|
||||
: m_name(name), m_single_thread(single), m_fifo(fifo), m_bits(bits){};
|
||||
|
||||
int Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result, u32* ptr_micros);
|
||||
|
||||
private:
|
||||
enum class Status { Set, Canceled, Deleted };
|
||||
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cond_var;
|
||||
Status m_status = Status::Set;
|
||||
int m_waiting_threads = 0;
|
||||
std::string m_name;
|
||||
bool m_single_thread = false;
|
||||
bool m_fifo = false;
|
||||
u64 m_bits = 0;
|
||||
};
|
||||
} // namespace Libraries::Kernel
|
|
@ -82,6 +82,15 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, void* buf, size_t nbytes) {
|
|||
if (buf == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EFAULT;
|
||||
}
|
||||
if (d == 1) {
|
||||
// temp, just to print the message. not a file?
|
||||
// CUSA00402 - Crimsonland and probably other games.
|
||||
char* msg = reinterpret_cast<char*>(buf);
|
||||
size_t length = std::strlen(msg);
|
||||
LOG_INFO(Kernel_Fs, "sceKernelWrite fd = 1, str = {}, length = {}", msg, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* file = h->GetFile(d);
|
||||
if (file == nullptr) {
|
||||
|
@ -159,7 +168,12 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) {
|
|||
return SCE_KERNEL_ERROR_EEXIST;
|
||||
}
|
||||
|
||||
if (!std::filesystem::create_directory(dir_name)) {
|
||||
if (!std::filesystem::create_directories(dir_name)) {
|
||||
// check me on saveDataMount.
|
||||
// CUSA02456: calls sceSaveDataMount then mkdir
|
||||
// CUSA00402: calls mkdir first before sceSaveDataMount
|
||||
// maybe consider mounting save data at emu start? (added in main)
|
||||
|
||||
return SCE_KERNEL_ERROR_EIO;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "common/singleton.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/cpu_management.h"
|
||||
#include "core/libraries/kernel/event_flag/event_flag.h"
|
||||
#include "core/libraries/kernel/event_queues.h"
|
||||
#include "core/libraries/kernel/file_system.h"
|
||||
#include "core/libraries/kernel/libkernel.h"
|
||||
|
@ -22,6 +23,7 @@
|
|||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <core/file_format/psf.h>
|
||||
|
||||
|
@ -50,8 +52,19 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) {
|
|||
return SCE_OK;
|
||||
}
|
||||
|
||||
void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) {
|
||||
int PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_usleep(unsigned int microseconds) {
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
u32 PS4_SYSV_ABI sceKernelSleep(unsigned int seconds) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
struct iovec {
|
||||
|
@ -197,6 +210,26 @@ s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {
|
|||
strlen(std::fgets(static_cast<char*>(buf), static_cast<int>(nbytes), stdin)));
|
||||
}
|
||||
|
||||
s64 PS4_SYSV_ABI posix_getpagesize() {
|
||||
return 4096;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelGetCpumode() {
|
||||
return SCE_KERNEL_CPUMODE_7CPU_NORMAL;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadGetthreadid() {
|
||||
#ifdef _WIN64
|
||||
return GetCurrentProcessId();
|
||||
#else
|
||||
return getpid();
|
||||
#endif
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_getpid() {
|
||||
return scePthreadGetthreadid();
|
||||
}
|
||||
|
||||
void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||
// obj
|
||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||
|
@ -220,15 +253,23 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
||||
LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, posix_mmap);
|
||||
LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep);
|
||||
LIB_FUNCTION("QcteRwbsnV0", "libScePosix", 1, "libkernel", 1, 1, posix_usleep);
|
||||
LIB_FUNCTION("-ZR+hG7aDHw", "libkernel", 1, "libkernel", 1, 1, sceKernelSleep);
|
||||
LIB_FUNCTION("0wu33hunNdE", "libScePosix", 1, "libkernel", 1, 1, sceKernelSleep);
|
||||
LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
|
||||
LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcParam);
|
||||
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
||||
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
|
||||
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
||||
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||
LIB_FUNCTION("VOx8NGmHXTs", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCpumode);
|
||||
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, scePthreadGetthreadid);
|
||||
LIB_FUNCTION("HoLVWNanBBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpid);
|
||||
|
||||
Libraries::Kernel::fileSystemSymbolsRegister(sym);
|
||||
Libraries::Kernel::timeSymbolsRegister(sym);
|
||||
Libraries::Kernel::pthreadSymbolsRegister(sym);
|
||||
Libraries::Kernel::RegisterKernelEventFlag(sym);
|
||||
|
||||
// temp
|
||||
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
|
||||
|
|
|
@ -12,6 +12,10 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
constexpr int SCE_KERNEL_CPUMODE_6CPU = 0;
|
||||
constexpr int SCE_KERNEL_CPUMODE_7CPU_LOW = 1;
|
||||
constexpr int SCE_KERNEL_CPUMODE_7CPU_NORMAL = 5;
|
||||
|
||||
struct OrbisTimesec {
|
||||
time_t t;
|
||||
u64 west_sec;
|
||||
|
|
|
@ -31,6 +31,10 @@ void init_pthreads() {
|
|||
ScePthreadAttr default_attr = nullptr;
|
||||
scePthreadAttrInit(&default_attr);
|
||||
g_pthread_cxt->SetDefaultAttr(default_attr);
|
||||
// default rwlock init
|
||||
ScePthreadRwAttr default_rwattr = nullptr;
|
||||
scePthreadRwlockattrInit(&default_rwattr);
|
||||
g_pthread_cxt->setDefaultRwattr(default_rwattr);
|
||||
|
||||
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
||||
}
|
||||
|
@ -173,6 +177,22 @@ int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachst
|
|||
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(ScePthreadAttr* attr, int detachstate) {
|
||||
int result = scePthreadAttrSetdetachstate(attr, detachstate);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_attr_destroy(ScePthreadAttr* attr) {
|
||||
int result = scePthreadAttrDestroy(attr);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched) {
|
||||
if (attr == nullptr || *attr == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
|
@ -710,7 +730,7 @@ int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, SceKernelTimespec* tp) {
|
|||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI clock_gettime(s32 clock_id, SceKernelTimespec* time) {
|
||||
int PS4_SYSV_ABI ps4_clock_gettime(s32 clock_id, SceKernelTimespec* time) {
|
||||
int result = sceKernelClockGettime(clock_id, time);
|
||||
if (result < 0) {
|
||||
UNREACHABLE(); // TODO return posix error code
|
||||
|
@ -719,23 +739,24 @@ int PS4_SYSV_ABI clock_gettime(s32 clock_id, SceKernelTimespec* time) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelNanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
|
||||
|
||||
if (rqtp == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EFAULT;
|
||||
}
|
||||
|
||||
if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
u64 nanos = rqtp->tv_sec * 1000000000 + rqtp->tv_nsec;
|
||||
std::this_thread::sleep_for(std::chrono::nanoseconds(nanos));
|
||||
if (rmtp != nullptr) {
|
||||
UNREACHABLE(); // not supported yet
|
||||
auto const end = std::chrono::high_resolution_clock::now();
|
||||
auto const diff = std::chrono::duration_cast<std::chrono::nanoseconds>(start - end).count();
|
||||
rmtp->tv_sec = (diff / 1000000000l);
|
||||
rmtp->tv_nsec = (diff % 1000000000l);
|
||||
}
|
||||
return SCE_OK;
|
||||
}
|
||||
int PS4_SYSV_ABI nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
|
||||
int PS4_SYSV_ABI posix_nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
|
||||
int result = sceKernelNanosleep(rqtp, rmtp);
|
||||
if (result < 0) {
|
||||
UNREACHABLE(); // TODO return posix error code
|
||||
|
@ -894,7 +915,13 @@ void PS4_SYSV_ABI scePthreadYield() {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) {
|
||||
LOG_INFO(Kernel_Pthread, "thread create name = {}", thread->name);
|
||||
LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name);
|
||||
thread->is_detached = true;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_detach(ScePthread thread) {
|
||||
LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name);
|
||||
thread->is_detached = true;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -903,6 +930,88 @@ ScePthread PS4_SYSV_ABI pthread_self() {
|
|||
return g_pthread_self;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadJoin(ScePthread thread, void** res) {
|
||||
if (thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
int result = pthread_join(thread->pth, res);
|
||||
LOG_DEBUG(Kernel_Pthread, "scePthreadJoin: result = {}", result);
|
||||
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadRename(ScePthread thread, const char* name) {
|
||||
LOG_DEBUG(Kernel_Pthread, "scePthreadRename: name = {}", name);
|
||||
thread->name = std::string(name);
|
||||
return SCE_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadKeyCreate(pthread_key_t* key, void (*dest)(void*)) {
|
||||
int result = pthread_key_create(key, dest); // Does dest really need sysv_abi?
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadKeyCreate: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case ENOMEM:
|
||||
return SCE_KERNEL_ERROR_ENOMEM;
|
||||
case EAGAIN:
|
||||
return SCE_KERNEL_ERROR_EAGAIN;
|
||||
case EINVAL:
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_key_create(pthread_key_t* key, void (*dest)(void*)) {
|
||||
int result = scePthreadKeyCreate(key, dest);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_setspecific(pthread_key_t key, void* ptr) {
|
||||
int result = pthread_setspecific(key, ptr);
|
||||
LOG_DEBUG(Kernel_Pthread, "posix_pthread_setspecific: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case ENOMEM:
|
||||
return SCE_KERNEL_ERROR_ENOMEM;
|
||||
case EAGAIN:
|
||||
return SCE_KERNEL_ERROR_EAGAIN;
|
||||
case EINVAL:
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy,
|
||||
const SceKernelSchedParam* param) {
|
||||
int ppolicy;
|
||||
if (policy != SCHED_OTHER)
|
||||
ppolicy = SCHED_OTHER;
|
||||
int result = pthread_setschedparam(thread->pth, ppolicy, param);
|
||||
// 0 only on win?
|
||||
LOG_INFO(Kernel_Pthread, "Todo? scePthreadSetschedparam: policy = {}, result = {}", policy,
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_setschedparam(ScePthread thread, int policy,
|
||||
const SceKernelSchedParam* param) {
|
||||
int result = scePthreadSetschedparam(thread, policy, param);
|
||||
LOG_INFO(Kernel_Pthread, "Todo? posix_pthread_setschedparam: policy = {}, result = {}", policy,
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_sched_get_priority_max(int algo) {
|
||||
LOG_INFO(Kernel_Pthread, "posix_sched_get_priority_max: algo = {}", algo);
|
||||
return SCE_KERNEL_PRIO_FIFO_HIGHEST;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
|
||||
if (cond == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
|
@ -923,9 +1032,9 @@ int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex) {
|
||||
cond = static_cast<ScePthreadCond*>(createCond(cond));
|
||||
if (cond == nullptr || *cond == nullptr) {
|
||||
// return SCE_KERNEL_ERROR_EINVAL;
|
||||
cond = static_cast<ScePthreadCond*>(createCond(cond)); // check this. Kero Blaster.
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (mutex == nullptr || *mutex == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
|
@ -946,6 +1055,53 @@ int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex
|
|||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec) {
|
||||
cond = static_cast<ScePthreadCond*>(createCond(cond));
|
||||
if (cond == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (mutex == nullptr || *mutex == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
timespec time{};
|
||||
time.tv_sec = usec / 1000000;
|
||||
time.tv_nsec = ((usec % 1000000) * 1000);
|
||||
int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time);
|
||||
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case ETIMEDOUT:
|
||||
return SCE_KERNEL_ERROR_ETIMEDOUT;
|
||||
case EINTR:
|
||||
return SCE_KERNEL_ERROR_EINTR;
|
||||
case EAGAIN:
|
||||
return SCE_KERNEL_ERROR_EAGAIN;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond) {
|
||||
if (cond == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
int result = pthread_cond_destroy(&(*cond)->cond);
|
||||
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadCondDestroy, result={}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case EBUSY:
|
||||
return SCE_KERNEL_ERROR_EBUSY;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr) {
|
||||
if (attr == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
|
@ -991,26 +1147,307 @@ int PS4_SYSV_ABI scePthreadEqual(ScePthread thread1, ScePthread thread2) {
|
|||
return (thread1 == thread2 ? 1 : 0);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI ps4_gettimeofday(SceKernelTimespec* tp /*, timezone */) {
|
||||
if (tp == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
LOG_INFO(Kernel_Pthread, "ps4_gettimeofday");
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto duration = now.time_since_epoch();
|
||||
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
|
||||
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds);
|
||||
|
||||
tp->tv_sec = static_cast<long>(seconds.count());
|
||||
tp->tv_nsec = static_cast<long>(nanoseconds.count());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI ps4_clock_getres(u32 clock_id, SceKernelTimespec* res) {
|
||||
if (res == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EFAULT;
|
||||
}
|
||||
clockid_t pclock_id = CLOCK_REALTIME;
|
||||
switch (clock_id) {
|
||||
case 0:
|
||||
pclock_id = CLOCK_REALTIME;
|
||||
break;
|
||||
case 13:
|
||||
case 4:
|
||||
pclock_id = CLOCK_MONOTONIC;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
timespec t{};
|
||||
int result = clock_getres(pclock_id, &t);
|
||||
res->tv_sec = t.tv_sec;
|
||||
res->tv_nsec = t.tv_nsec;
|
||||
if (result == 0) {
|
||||
return SCE_OK;
|
||||
}
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) {
|
||||
int result = scePthreadMutexattrInit(attr);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_destroy(ScePthreadMutexattr* attr) {
|
||||
int result = scePthreadMutexattrDestroy(attr);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_settype(ScePthreadMutexattr* attr, int type) {
|
||||
int result = scePthreadMutexattrSettype(attr, type);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg) {
|
||||
int result = scePthreadCreate(thread, attr, start_routine, arg, "");
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_cond_init(ScePthreadCond* cond, const ScePthreadCondattr* attr) {
|
||||
int result = scePthreadCondInit(cond, attr, "");
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_attr_init(ScePthreadAttr* attr) {
|
||||
int result = scePthreadAttrInit(attr);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_attr_setstacksize(ScePthreadAttr* attr, size_t stack_size) {
|
||||
int result = scePthreadAttrSetstacksize(attr, stack_size);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_cond_wait(ScePthreadCond* cond, ScePthreadMutex* mutex) {
|
||||
int result = scePthreadCondWait(cond, mutex);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(ScePthreadMutexattr* attr, u32 protocol) {
|
||||
int result = scePthreadMutexattrSetprotocol(attr, protocol);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_mutex_trylock(ScePthreadMutex* mutex) {
|
||||
int result = scePthreadMutexTrylock(mutex);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_condattr_init(ScePthreadCondattr* attr) {
|
||||
int result = scePthreadCondattrInit(attr);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_condattr_destroy(ScePthreadCondattr* attr) {
|
||||
int result = scePthreadCondattrDestroy(attr);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/****
|
||||
* rwlock
|
||||
*/
|
||||
int PS4_SYSV_ABI scePthreadRwlockInit(ScePthreadRw* thread, ScePthreadRwAttr* attr,
|
||||
const char* name) {
|
||||
*thread = new PthreadRwInternal{};
|
||||
if (thread == nullptr || *thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
if (attr == nullptr || *attr == nullptr) {
|
||||
attr = g_pthread_cxt->getDefaultRwattr();
|
||||
}
|
||||
|
||||
int result = pthread_rwlock_init(&(*thread)->pth_rwlock, &(*attr)->attr_rwlock);
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadRwlockInit: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case ENOMEM:
|
||||
return SCE_KERNEL_ERROR_ENOMEM;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadRwlockRdlock(ScePthreadRw* thread) {
|
||||
if (thread == nullptr || *thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
int result = pthread_rwlock_rdlock(&(*thread)->pth_rwlock);
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadRwlockRdlock: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case EBUSY:
|
||||
return SCE_KERNEL_ERROR_EBUSY;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadRwlockWrlock(ScePthreadRw* thread) {
|
||||
if (thread == nullptr || *thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
int result = pthread_rwlock_wrlock(&(*thread)->pth_rwlock);
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadRwlockWrlock: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case EBUSY:
|
||||
return SCE_KERNEL_ERROR_EBUSY;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadRwlockUnlock(ScePthreadRw* thread) {
|
||||
if (thread == nullptr || *thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
int result = pthread_rwlock_unlock(&(*thread)->pth_rwlock);
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadRwlockUnlock: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case EBUSY:
|
||||
return SCE_KERNEL_ERROR_EBUSY;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadRwlockDestroy(ScePthreadRw* thread) {
|
||||
if (thread == nullptr || *thread == nullptr) {
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
int result = pthread_rwlock_destroy(&(*thread)->pth_rwlock);
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadRwlockDestroy: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case EBUSY:
|
||||
return SCE_KERNEL_ERROR_EBUSY;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePthreadRwlockattrInit(ScePthreadRwAttr* attr) {
|
||||
*attr = new PthreadRwLockAttrInernal{};
|
||||
|
||||
int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock);
|
||||
LOG_INFO(Kernel_Pthread, "scePthreadRwlockattrInit: result = {}", result);
|
||||
|
||||
switch (result) {
|
||||
case 0:
|
||||
return SCE_OK;
|
||||
case ENOMEM:
|
||||
return SCE_KERNEL_ERROR_ENOMEM;
|
||||
default:
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_rwlock_rdlock(ScePthreadRw* thread) {
|
||||
int result = scePthreadRwlockRdlock(thread);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
int PS4_SYSV_ABI posix_pthread_rwlock_unlock(ScePthreadRw* thread) {
|
||||
int result = scePthreadRwlockUnlock(thread);
|
||||
if (result < 0) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||
// pthreadattr calls
|
||||
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
|
||||
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
|
||||
LIB_FUNCTION("eXbUSpEaTsA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetinheritsched);
|
||||
LIB_FUNCTION("DzES9hQF4f4", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedparam);
|
||||
LIB_FUNCTION("nsYoNRywwNg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrInit);
|
||||
LIB_FUNCTION("62KCwEMmzcM", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrDestroy);
|
||||
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
|
||||
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual);
|
||||
|
||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
|
||||
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, pthread_self);
|
||||
LIB_FUNCTION("3qxgM4ezETA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetaffinity);
|
||||
LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetaffinity);
|
||||
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
|
||||
LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetstacksize);
|
||||
LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_attr_setdetachstate);
|
||||
LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_destroy);
|
||||
|
||||
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
|
||||
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual);
|
||||
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
|
||||
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, pthread_self);
|
||||
LIB_FUNCTION("EotR8a3ASf4", "libScePosix", 1, "libkernel", 1, 1, scePthreadSelf);
|
||||
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadSetaffinity);
|
||||
LIB_FUNCTION("6UgtwV+0zb4", "libkernel", 1, "libkernel", 1, 1, scePthreadCreate);
|
||||
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, scePthreadYield);
|
||||
LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, scePthreadKeyCreate);
|
||||
LIB_FUNCTION("oIRFTjoILbg", "libkernel", 1, "libkernel", 1, 1, scePthreadSetschedparam);
|
||||
LIB_FUNCTION("mqULNdimTn0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_create);
|
||||
LIB_FUNCTION("mqULNdimTn0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_key_create);
|
||||
LIB_FUNCTION("WrOLvHU0yQM", "libkernel", 1, "libkernel", 1, 1, posix_pthread_setspecific);
|
||||
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
|
||||
LIB_FUNCTION("CBNtXOoef-E", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_max);
|
||||
LIB_FUNCTION("+U1R4WtXvoc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_detach);
|
||||
|
||||
// mutex calls
|
||||
LIB_FUNCTION("cmo1RIYva9o", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexInit);
|
||||
|
@ -1027,23 +1464,62 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit);
|
||||
LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast);
|
||||
LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", 1, 1, scePthreadCondWait);
|
||||
LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait);
|
||||
LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy);
|
||||
LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal);
|
||||
LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", 1, 1, scePthreadCondDestroy);
|
||||
|
||||
// Rwlock funstions
|
||||
LIB_FUNCTION("6ULAa0fq4jA", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockInit);
|
||||
LIB_FUNCTION("yOfGg-I1ZII", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrInit);
|
||||
LIB_FUNCTION("Ox9i0c7L5w0", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockRdlock);
|
||||
LIB_FUNCTION("mqdNorrB+gI", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockWrlock);
|
||||
LIB_FUNCTION("+L98PIbGttk", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockUnlock);
|
||||
LIB_FUNCTION("BB+kb08Tl9A", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockDestroy);
|
||||
LIB_FUNCTION("iGjsr1WAtI0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_rdlock);
|
||||
LIB_FUNCTION("EgmLo6EWgso", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_unlock);
|
||||
|
||||
// posix calls
|
||||
LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_init);
|
||||
LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
||||
LIB_FUNCTION("K-jXhbt2gn4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_trylock);
|
||||
LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock);
|
||||
LIB_FUNCTION("mkx2fVhNMsg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast);
|
||||
|
||||
LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime);
|
||||
LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, clock_gettime);
|
||||
LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, clock_gettime);
|
||||
LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, nanosleep);
|
||||
LIB_FUNCTION("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutexattr_init);
|
||||
LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_mutexattr_destroy);
|
||||
LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_mutexattr_settype);
|
||||
LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create);
|
||||
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
|
||||
LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init);
|
||||
LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_attr_setstacksize);
|
||||
LIB_FUNCTION("Op8TBGY5KHg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_wait);
|
||||
LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init);
|
||||
LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_condattr_destroy);
|
||||
LIB_FUNCTION("5txKfcMUAok", "libScePosix", 1, "libkernel", 1, 1,
|
||||
posix_pthread_mutexattr_setprotocol);
|
||||
|
||||
// openorbis weird functions
|
||||
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
||||
LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock);
|
||||
LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast);
|
||||
|
||||
// time
|
||||
LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime);
|
||||
LIB_FUNCTION("QvsZxomvUHs", "libkernel", 1, "libkernel", 1, 1, sceKernelNanosleep);
|
||||
LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, ps4_clock_gettime);
|
||||
LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, ps4_clock_gettime);
|
||||
LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, posix_nanosleep);
|
||||
LIB_FUNCTION("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1,
|
||||
posix_nanosleep); // CUSA18841
|
||||
LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, ps4_gettimeofday);
|
||||
LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, ps4_gettimeofday);
|
||||
LIB_FUNCTION("ejekcaNQNq0", "libkernel", 1, "libkernel", 1, 1,
|
||||
ps4_gettimeofday); // sceKernelGettimeofday
|
||||
LIB_FUNCTION("smIj7eqzZE8", "libScePosix", 1, "libkernel", 1, 1, ps4_clock_getres);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -17,12 +17,21 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
/* sceKernelSchedGetPriorityMax/Min */
|
||||
constexpr int SCE_KERNEL_SCHED_FIFO = SCHED_FIFO;
|
||||
constexpr int SCE_KERNEL_SCHED_RR = SCHED_RR;
|
||||
constexpr int SCE_KERNEL_PRIO_FIFO_DEFAULT = 700;
|
||||
constexpr int SCE_KERNEL_PRIO_FIFO_HIGHEST = 256;
|
||||
constexpr int SCE_KERNEL_PRIO_FIFO_LOWEST = 767;
|
||||
|
||||
struct PthreadInternal;
|
||||
struct PthreadAttrInternal;
|
||||
struct PthreadMutexInternal;
|
||||
struct PthreadMutexattrInternal;
|
||||
struct PthreadCondInternal;
|
||||
struct PthreadCondAttrInternal;
|
||||
struct PthreadRwInternal;
|
||||
struct PthreadRwLockAttrInernal;
|
||||
|
||||
using SceKernelSchedParam = ::sched_param;
|
||||
using ScePthread = PthreadInternal*;
|
||||
|
@ -31,13 +40,12 @@ using ScePthreadMutex = PthreadMutexInternal*;
|
|||
using ScePthreadMutexattr = PthreadMutexattrInternal*;
|
||||
using ScePthreadCond = PthreadCondInternal*;
|
||||
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
||||
using ScePthreadRw = PthreadRwInternal*;
|
||||
using ScePthreadRwAttr = PthreadRwLockAttrInernal*;
|
||||
|
||||
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
||||
|
||||
struct SceKernelTimespec {
|
||||
int64_t tv_sec;
|
||||
int64_t tv_nsec;
|
||||
};
|
||||
typedef struct timespec SceKernelTimespec;
|
||||
|
||||
struct PthreadInternal {
|
||||
u8 reserved[4096];
|
||||
|
@ -84,6 +92,19 @@ struct PthreadCondAttrInternal {
|
|||
pthread_condattr_t cond_attr;
|
||||
};
|
||||
|
||||
struct PthreadRwLockAttrInernal {
|
||||
u64 initialized = 1;
|
||||
u8 reserved[64];
|
||||
pthread_rwlockattr_t attr_rwlock;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct PthreadRwInternal {
|
||||
u64 initialized = 1;
|
||||
pthread_rwlock_t pth_rwlock;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class PThreadPool {
|
||||
public:
|
||||
ScePthread Create();
|
||||
|
@ -113,6 +134,12 @@ public:
|
|||
void SetDefaultAttr(ScePthreadAttr attr) {
|
||||
m_default_attr = attr;
|
||||
}
|
||||
ScePthreadRwAttr* getDefaultRwattr() {
|
||||
return &m_default_Rwattr;
|
||||
}
|
||||
void setDefaultRwattr(ScePthreadRwAttr attr) {
|
||||
m_default_Rwattr = attr;
|
||||
}
|
||||
PThreadPool* GetPthreadPool() {
|
||||
return m_pthread_pool;
|
||||
}
|
||||
|
@ -123,6 +150,7 @@ public:
|
|||
private:
|
||||
ScePthreadMutexattr m_default_mutexattr = nullptr;
|
||||
ScePthreadCondattr m_default_condattr = nullptr;
|
||||
ScePthreadRwAttr m_default_Rwattr = nullptr;
|
||||
ScePthreadAttr m_default_attr = nullptr;
|
||||
PThreadPool* m_pthread_pool = nullptr;
|
||||
};
|
||||
|
@ -142,6 +170,13 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
|
|||
int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask);
|
||||
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg, const char* name);
|
||||
int PS4_SYSV_ABI scePthreadJoin(ScePthread thread, void** res);
|
||||
int PS4_SYSV_ABI scePthreadRename(ScePthread thread, const char* name);
|
||||
int PS4_SYSV_ABI scePthreadKeyCreate(pthread_key_t* key, void (*dest)(void*));
|
||||
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
|
||||
pthreadEntryFunc start_routine, void* arg);
|
||||
int PS4_SYSV_ABI posix_pthread_key_create(pthread_key_t* key, void (*dest)(void*));
|
||||
int PS4_SYSV_ABI posix_pthread_setspecific(pthread_key_t key, void* ptr);
|
||||
|
||||
/***
|
||||
* Mutex calls
|
||||
|
@ -160,6 +195,23 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat
|
|||
const char* name);
|
||||
int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr);
|
||||
int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond);
|
||||
int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex);
|
||||
int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec);
|
||||
int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr);
|
||||
int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond);
|
||||
/****
|
||||
* rwlock calls
|
||||
*/
|
||||
int PS4_SYSV_ABI scePthreadRwlockInit(ScePthreadRw* thread, ScePthreadRwAttr* attr,
|
||||
const char* name);
|
||||
int PS4_SYSV_ABI scePthreadRwlockRdlock(ScePthreadRw* thread);
|
||||
int PS4_SYSV_ABI scePthreadRwlockWrlock(ScePthreadRw* thread);
|
||||
int PS4_SYSV_ABI scePthreadRwlockUnlock(ScePthreadRw* thread);
|
||||
int PS4_SYSV_ABI scePthreadRwlockDestroy(ScePthreadRw* thread);
|
||||
int PS4_SYSV_ABI scePthreadRwlockattrInit(ScePthreadRwAttr* attr);
|
||||
int PS4_SYSV_ABI posix_pthread_rwlock_rdlock(ScePthreadRw* thread);
|
||||
int PS4_SYSV_ABI posix_pthread_rwlock_unlock(ScePthreadRw* thread);
|
||||
|
||||
/****
|
||||
* Posix calls
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "core/libraries/np_score/np_score.h"
|
||||
#include "core/libraries/np_trophy/np_trophy.h"
|
||||
#include "core/libraries/pad/pad.h"
|
||||
#include "core/libraries/rtc/rtc.h"
|
||||
#include "core/libraries/save_data/savedata.h"
|
||||
#include "core/libraries/screenshot/screenshot.h"
|
||||
#include "core/libraries/system/commondialog.h"
|
||||
|
@ -59,6 +60,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
|||
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
|
||||
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
|
||||
Libraries::LibcInternal::RegisterlibSceLibcInternal(sym);
|
||||
Libraries::Rtc::RegisterlibSceRtc(sym);
|
||||
}
|
||||
|
||||
} // namespace Libraries
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include <chrono>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "rtc.h"
|
||||
|
||||
namespace Libraries::Rtc {
|
||||
|
||||
int PS4_SYSV_ABI sceRtcCheckValid() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcCompareTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcEnd() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC2822() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339LocalTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339Precise() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentClock() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime) {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto now_ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(now);
|
||||
auto epoch = now_ns.time_since_epoch();
|
||||
auto micros = std::chrono::duration_cast<std::chrono::microseconds>(epoch);
|
||||
|
||||
std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm local_tm = *std::localtime(&now_time_t);
|
||||
|
||||
pTime->year = local_tm.tm_year + 1900;
|
||||
pTime->month = local_tm.tm_mon + 1;
|
||||
pTime->day = local_tm.tm_mday;
|
||||
pTime->hour = local_tm.tm_hour;
|
||||
pTime->minute = local_tm.tm_min;
|
||||
pTime->second = local_tm.tm_sec;
|
||||
pTime->microsecond = micros.count() % 1000000;
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) {
|
||||
pTick->tick = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::high_resolution_clock::now().time_since_epoch())
|
||||
.count();
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) {
|
||||
std::tm timeinfo = {0};
|
||||
timeinfo.tm_year = year - 1900;
|
||||
timeinfo.tm_mon = month - 1;
|
||||
timeinfo.tm_mday = day;
|
||||
std::mktime(&timeinfo);
|
||||
return timeinfo.tm_wday;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetDaysInMonth() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetDosTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetTickResolution() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetTime_t() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcGetWin32FileTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcInit() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcIsLeapYear() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcParseDateTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcParseRFC3339() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetConf() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetDosTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetTick() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetTime_t() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcSetWin32FileTime() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddDays() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddHours() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddMicroseconds() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddMinutes() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddMonths() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddSeconds() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddTicks() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddWeeks() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRtcTickAddYears() {
|
||||
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("lPEBYdVX0XQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcCheckValid);
|
||||
LIB_FUNCTION("fNaZ4DbzHAE", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcCompareTick);
|
||||
LIB_FUNCTION("8Yr143yEnRo", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcConvertLocalTimeToUtc);
|
||||
LIB_FUNCTION("M1TvFst-jrM", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcConvertUtcToLocalTime);
|
||||
LIB_FUNCTION("8SljQx6pDP8", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcEnd);
|
||||
LIB_FUNCTION("eiuobaF-hK4", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC2822);
|
||||
LIB_FUNCTION("AxHBk3eat04", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC2822LocalTime);
|
||||
LIB_FUNCTION("WJ3rqFwymew", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC3339);
|
||||
LIB_FUNCTION("DwuHIlLGW8I", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC3339LocalTime);
|
||||
LIB_FUNCTION("lja0nNPWojg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC3339Precise);
|
||||
LIB_FUNCTION("tOZ6fwwHZOA", "libSceRtc", 1, "libSceRtc", 1, 1,
|
||||
sceRtcFormatRFC3339PreciseLocalTime);
|
||||
LIB_FUNCTION("LN3Zcb72Q0c", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentAdNetworkTick);
|
||||
LIB_FUNCTION("8lfvnRMqwEM", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentClock);
|
||||
LIB_FUNCTION("ZPD1YOKI+Kw", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentClockLocalTime);
|
||||
LIB_FUNCTION("Ot1DE3gif84", "libSceRtc", 1, "libSceRtc", 1, 1,
|
||||
sceRtcGetCurrentDebugNetworkTick);
|
||||
LIB_FUNCTION("zO9UL3qIINQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentNetworkTick);
|
||||
LIB_FUNCTION("HWxHOdbM-Pg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentRawNetworkTick);
|
||||
LIB_FUNCTION("18B2NS1y9UU", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentTick);
|
||||
LIB_FUNCTION("CyIK-i4XdgQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetDayOfWeek);
|
||||
LIB_FUNCTION("3O7Ln8AqJ1o", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetDaysInMonth);
|
||||
LIB_FUNCTION("E7AR4o7Ny7E", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetDosTime);
|
||||
LIB_FUNCTION("8w-H19ip48I", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetTick);
|
||||
LIB_FUNCTION("jMNwqYr4R-k", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetTickResolution);
|
||||
LIB_FUNCTION("BtqmpTRXHgk", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetTime_t);
|
||||
LIB_FUNCTION("jfRO0uTjtzA", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetWin32FileTime);
|
||||
LIB_FUNCTION("LlodCMDbk3o", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcInit);
|
||||
LIB_FUNCTION("Ug8pCwQvh0c", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcIsLeapYear);
|
||||
LIB_FUNCTION("NxEI1KByvCI", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcParseDateTime);
|
||||
LIB_FUNCTION("99bMGglFW3I", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcParseRFC3339);
|
||||
LIB_FUNCTION("fFLgmNUpChg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetConf);
|
||||
LIB_FUNCTION("sV2tK+yOhBU", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetCurrentAdNetworkTick);
|
||||
LIB_FUNCTION("VLDUPKmw5L8", "libSceRtc", 1, "libSceRtc", 1, 1,
|
||||
sceRtcSetCurrentDebugNetworkTick);
|
||||
LIB_FUNCTION("qhDBtIo+auw", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetCurrentNetworkTick);
|
||||
LIB_FUNCTION("d4fHLCGmY80", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetCurrentTick);
|
||||
LIB_FUNCTION("aYPCd1cChyg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetDosTime);
|
||||
LIB_FUNCTION("ueega6v3GUw", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetTick);
|
||||
LIB_FUNCTION("bDEVVP4bTjQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetTime_t);
|
||||
LIB_FUNCTION("n5JiAJXsbcs", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetWin32FileTime);
|
||||
LIB_FUNCTION("NR1J0N7L2xY", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddDays);
|
||||
LIB_FUNCTION("MDc5cd8HfCA", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddHours);
|
||||
LIB_FUNCTION("XPIiw58C+GM", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddMicroseconds);
|
||||
LIB_FUNCTION("mn-tf4QiFzk", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddMinutes);
|
||||
LIB_FUNCTION("CL6y9q-XbuQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddMonths);
|
||||
LIB_FUNCTION("07O525HgICs", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddSeconds);
|
||||
LIB_FUNCTION("AqVMssr52Rc", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddTicks);
|
||||
LIB_FUNCTION("gI4t194c2W8", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddWeeks);
|
||||
LIB_FUNCTION("-5y2uJ62qS8", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddYears);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Rtc
|
|
@ -0,0 +1,77 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::Rtc {
|
||||
|
||||
struct OrbisRtcTick {
|
||||
u64 tick;
|
||||
};
|
||||
|
||||
struct OrbisRtcDateTime {
|
||||
u16 year;
|
||||
u16 month;
|
||||
u16 day;
|
||||
u16 hour;
|
||||
u16 minute;
|
||||
u16 second;
|
||||
u16 microsecond;
|
||||
};
|
||||
|
||||
int PS4_SYSV_ABI sceRtcCheckValid();
|
||||
int PS4_SYSV_ABI sceRtcCompareTick();
|
||||
int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc();
|
||||
int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime();
|
||||
int PS4_SYSV_ABI sceRtcEnd();
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC2822();
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime();
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339();
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339LocalTime();
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339Precise();
|
||||
int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime();
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentClock();
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime);
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick);
|
||||
int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day);
|
||||
int PS4_SYSV_ABI sceRtcGetDaysInMonth();
|
||||
int PS4_SYSV_ABI sceRtcGetDosTime();
|
||||
int PS4_SYSV_ABI sceRtcGetTick();
|
||||
int PS4_SYSV_ABI sceRtcGetTickResolution();
|
||||
int PS4_SYSV_ABI sceRtcGetTime_t();
|
||||
int PS4_SYSV_ABI sceRtcGetWin32FileTime();
|
||||
int PS4_SYSV_ABI sceRtcInit();
|
||||
int PS4_SYSV_ABI sceRtcIsLeapYear();
|
||||
int PS4_SYSV_ABI sceRtcParseDateTime();
|
||||
int PS4_SYSV_ABI sceRtcParseRFC3339();
|
||||
int PS4_SYSV_ABI sceRtcSetConf();
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick();
|
||||
int PS4_SYSV_ABI sceRtcSetCurrentTick();
|
||||
int PS4_SYSV_ABI sceRtcSetDosTime();
|
||||
int PS4_SYSV_ABI sceRtcSetTick();
|
||||
int PS4_SYSV_ABI sceRtcSetTime_t();
|
||||
int PS4_SYSV_ABI sceRtcSetWin32FileTime();
|
||||
int PS4_SYSV_ABI sceRtcTickAddDays();
|
||||
int PS4_SYSV_ABI sceRtcTickAddHours();
|
||||
int PS4_SYSV_ABI sceRtcTickAddMicroseconds();
|
||||
int PS4_SYSV_ABI sceRtcTickAddMinutes();
|
||||
int PS4_SYSV_ABI sceRtcTickAddMonths();
|
||||
int PS4_SYSV_ABI sceRtcTickAddSeconds();
|
||||
int PS4_SYSV_ABI sceRtcTickAddTicks();
|
||||
int PS4_SYSV_ABI sceRtcTickAddWeeks();
|
||||
int PS4_SYSV_ABI sceRtcTickAddYears();
|
||||
|
||||
void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::Rtc
|
|
@ -4,5 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMETER = 0x809f0000;
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED =
|
||||
0x809f0001; // save data library not initialized yet
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809f0008; // save data doesn't exist
|
||||
constexpr int ORBIS_SAVE_DATA_ERROR_EXISTS = 0x809f0007; // save data directory,same name exists
|
|
@ -13,7 +13,7 @@
|
|||
#include "error_codes.h"
|
||||
|
||||
namespace Libraries::SaveData {
|
||||
|
||||
static bool initialized = false;
|
||||
static std::string g_mount_point = "/savedata0"; // temp mount point (todo)
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataAbort() {
|
||||
|
@ -241,8 +241,11 @@ int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountInfo() {
|
||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountInfo(OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataMountInfo* info) {
|
||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called, mount = {}", mountPoint->data);
|
||||
info->blocks = 100000;
|
||||
info->freeBlocks = 100000;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -296,17 +299,20 @@ int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize() {
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize(const OrbisSaveDataInitParams* initParam) {
|
||||
initialized = true; // todo.
|
||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize2() {
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize2(const OrbisSaveDataInitParams* initParam) {
|
||||
initialized = true; // todo.
|
||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize3() {
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize3(const OrbisSaveDataInitParams* initParam) {
|
||||
initialized = true; // todo.
|
||||
LOG_ERROR(Lib_SaveData, "(DUMMY) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
@ -331,32 +337,25 @@ int PS4_SYSV_ABI sceSaveDataLoadIcon() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataMount() {
|
||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
||||
OrbisSaveDataMountResult* mount_result) {
|
||||
LOG_INFO(Lib_SaveData, "called user_id = {} dir_name = {} blocks = {} mount_mode = {}",
|
||||
mount->user_id, mount->dir_name->data, mount->blocks, mount->mount_mode);
|
||||
|
||||
s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
|
||||
OrbisSaveDataMountResult* mount_result) {
|
||||
auto* param_sfo = Common::Singleton<PSF>::Instance();
|
||||
std::string id(param_sfo->GetString("CONTENT_ID"), 7, 9);
|
||||
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
|
||||
std::to_string(mount->user_id) / "savedata" / id /
|
||||
std::string(mount->dir_name->data);
|
||||
switch (mount->mount_mode) {
|
||||
std::to_string(user_id) / "savedata" / id / dir_name;
|
||||
switch (mount_mode) {
|
||||
case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
|
||||
case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: {
|
||||
if (!std::filesystem::exists(mount_dir)) {
|
||||
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
|
||||
if (!initialized /* !std::filesystem::exists(mount_dir)*/) {
|
||||
// check this. example: CUSA02456
|
||||
return ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
mnt->Mount(mount_dir, g_mount_point);
|
||||
|
||||
mount_result->mount_status = 0;
|
||||
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
||||
LOG_ERROR(Lib_SaveData, "mount = {}", mount_result->mount_point.data);
|
||||
} break;
|
||||
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
|
||||
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
|
||||
|
@ -372,6 +371,18 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
|||
mount_result->mount_status = 1;
|
||||
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
||||
} break;
|
||||
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
|
||||
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: {
|
||||
if (!std::filesystem::exists(mount_dir)) {
|
||||
std::filesystem::create_directories(mount_dir);
|
||||
}
|
||||
|
||||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
mnt->Mount(mount_dir, g_mount_point);
|
||||
|
||||
mount_result->mount_status = 1;
|
||||
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
||||
} break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -380,6 +391,28 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
|
||||
OrbisSaveDataMountResult* mount_result) {
|
||||
if (mount == nullptr) {
|
||||
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
|
||||
}
|
||||
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data,
|
||||
mount->mount_mode, mount->blocks);
|
||||
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode,
|
||||
mount_result);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
||||
OrbisSaveDataMountResult* mount_result) {
|
||||
if (mount == nullptr) {
|
||||
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
|
||||
}
|
||||
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data,
|
||||
mount->mount_mode, mount->blocks);
|
||||
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode,
|
||||
mount_result);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataMount5() {
|
||||
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
|
|
@ -29,6 +29,30 @@ struct OrbisSaveDataMount2 {
|
|||
s32 unk2;
|
||||
};
|
||||
|
||||
constexpr int SCE_SAVE_DATA_TITLE_ID_DATA_SIZE = 10;
|
||||
typedef struct OrbisSaveDataTitleId {
|
||||
char data[SCE_SAVE_DATA_TITLE_ID_DATA_SIZE];
|
||||
char padding[6];
|
||||
|
||||
} OrbisSaveDataTitleId;
|
||||
|
||||
constexpr int SCE_SAVE_DATA_FINGERPRINT_DATA_SIZE = 65;
|
||||
typedef struct OrbisSaveDataFingerprint {
|
||||
char data[SCE_SAVE_DATA_FINGERPRINT_DATA_SIZE];
|
||||
char padding[15];
|
||||
} OrbisSaveDataFingerprint;
|
||||
|
||||
typedef struct OrbisSaveDataMount {
|
||||
s32 user_id;
|
||||
s32 pad;
|
||||
const OrbisSaveDataTitleId* titleId;
|
||||
const OrbisSaveDataDirName* dir_name;
|
||||
const OrbisSaveDataFingerprint* fingerprint;
|
||||
u64 blocks;
|
||||
u32 mount_mode;
|
||||
u8 reserved[32];
|
||||
} OrbisSaveDataMount;
|
||||
|
||||
struct OrbisSaveDataMountPoint {
|
||||
char data[ORBIS_SAVE_DATA_MOUNT_POINT_DATA_MAXSIZE];
|
||||
};
|
||||
|
@ -42,6 +66,14 @@ struct OrbisSaveDataMountResult {
|
|||
s32 unk1;
|
||||
};
|
||||
|
||||
typedef struct OrbisSaveDataMountInfo {
|
||||
u64 blocks; // total num of blocks
|
||||
u64 freeBlocks; // free num of blocks
|
||||
uint8_t reserved[32];
|
||||
} OrbisSaveDataMountInfo;
|
||||
|
||||
typedef struct _OrbisSaveDataInitParams OrbisSaveDataInitParams;
|
||||
|
||||
// savedataMount2 mountModes (ORed values)
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1;
|
||||
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDWR = 2;
|
||||
|
@ -95,7 +127,8 @@ int PS4_SYSV_ABI sceSaveDataGetEventInfo();
|
|||
int PS4_SYSV_ABI sceSaveDataGetEventResult();
|
||||
int PS4_SYSV_ABI sceSaveDataGetFormat();
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount();
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountInfo();
|
||||
int PS4_SYSV_ABI sceSaveDataGetMountInfo(OrbisSaveDataMountPoint* mountPoint,
|
||||
OrbisSaveDataMountInfo* info);
|
||||
int PS4_SYSV_ABI sceSaveDataGetParam();
|
||||
int PS4_SYSV_ABI sceSaveDataGetProgress();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSaveDataCount();
|
||||
|
@ -106,14 +139,15 @@ int PS4_SYSV_ABI sceSaveDataGetSaveDataRootPath();
|
|||
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootUsbPath();
|
||||
int PS4_SYSV_ABI sceSaveDataGetSavePoint();
|
||||
int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize2();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize3();
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize(const OrbisSaveDataInitParams* initParam);
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize2(const OrbisSaveDataInitParams* initParam);
|
||||
int PS4_SYSV_ABI sceSaveDataInitialize3(const OrbisSaveDataInitParams* initParam);
|
||||
int PS4_SYSV_ABI sceSaveDataInitializeForCdlg();
|
||||
int PS4_SYSV_ABI sceSaveDataIsDeletingUsbDb();
|
||||
int PS4_SYSV_ABI sceSaveDataIsMounted();
|
||||
int PS4_SYSV_ABI sceSaveDataLoadIcon();
|
||||
int PS4_SYSV_ABI sceSaveDataMount();
|
||||
int PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
|
||||
OrbisSaveDataMountResult* mount_result);
|
||||
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
|
||||
OrbisSaveDataMountResult* mount_result);
|
||||
int PS4_SYSV_ABI sceSaveDataMount5();
|
||||
|
|
|
@ -63,6 +63,13 @@ int main(int argc, char* argv[]) {
|
|||
u32 fw_version = param_sfo->GetInteger("SYSTEM_VER");
|
||||
std::string app_version = param_sfo->GetString("APP_VER");
|
||||
LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version);
|
||||
|
||||
// Just testing for now.
|
||||
// Working fine, one case only so far (CUSA00402 - Crimsonland)
|
||||
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
|
||||
"1" / "savedata" / id;
|
||||
mnt->Mount(mount_dir, "/savedata0");
|
||||
|
||||
} else if (entry.path().filename() == "pic0.png" ||
|
||||
entry.path().filename() == "pic1.png") {
|
||||
auto* splash = Common::Singleton<Splash>::Instance();
|
||||
|
|
Loading…
Reference in New Issue