sceKernelGetdents implementation
This commit is contained in:
parent
429d7deb29
commit
fc14a8a707
|
@ -59,13 +59,25 @@ u64 File::tell() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DirEntry> File::getDirectoryEntries(const std::string& path) {
|
std::vector<DirEntry> File::getDirectoryEntries(const std::string& path) {
|
||||||
|
std::string curpath = path;
|
||||||
|
if (!curpath.ends_with("/"))
|
||||||
|
{
|
||||||
|
curpath = std::string(curpath + "/");
|
||||||
|
}
|
||||||
std::vector < DirEntry> files;
|
std::vector < DirEntry> files;
|
||||||
|
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(path)) {
|
for (const auto& entry : std::filesystem::directory_iterator(curpath)) {
|
||||||
if (std::filesystem::is_regular_file(path)) {
|
if (std::filesystem::is_regular_file( entry.path().string())) {
|
||||||
|
DirEntry e = {};
|
||||||
|
e.name = entry.path().filename().string();
|
||||||
|
e.isFile = true;
|
||||||
|
files.push_back(e);
|
||||||
|
} else {
|
||||||
|
DirEntry e = {};
|
||||||
|
e.name = entry.path().filename().string() + "/"; //hmmm not sure if it has to be like this...
|
||||||
|
e.isFile = false;
|
||||||
|
files.push_back(e);
|
||||||
}
|
}
|
||||||
//entry.path()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
#include <cstdio>
|
|
||||||
#include <string>
|
|
||||||
#include <magic_enum.hpp>
|
|
||||||
#include "common/log.h"
|
|
||||||
#include "common/debug.h"
|
|
||||||
#include "core/loader/symbols_resolver.h"
|
|
||||||
#include "core/PS4/HLE/Graphics/video_out.h"
|
#include "core/PS4/HLE/Graphics/video_out.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <magic_enum.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Objects/video_out_ctx.h"
|
||||||
|
#include "Util/config.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
#include "core/PS4/GPU/gpu_memory.h"
|
#include "core/PS4/GPU/gpu_memory.h"
|
||||||
#include "core/PS4/GPU/video_out_buffer.h"
|
#include "core/PS4/GPU/video_out_buffer.h"
|
||||||
#include "core/hle/error_codes.h"
|
#include "core/hle/error_codes.h"
|
||||||
#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h"
|
|
||||||
#include "core/hle/libraries/libs.h"
|
#include "core/hle/libraries/libs.h"
|
||||||
|
#include "core/hle/libraries/libscegnmdriver/libscegnmdriver.h"
|
||||||
#include "core/hle/libraries/libuserservice/usr_mng_codes.h"
|
#include "core/hle/libraries/libuserservice/usr_mng_codes.h"
|
||||||
#include "Util/config.h"
|
#include "core/loader/symbols_resolver.h"
|
||||||
#include "Objects/video_out_ctx.h"
|
|
||||||
#include "common/singleton.h"
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#include "graphics_render.h"
|
#include "graphics_render.h"
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) {
|
s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) {
|
||||||
PRINT_FUNCTION_NAME();
|
// PRINT_FUNCTION_NAME();
|
||||||
auto* videoOut = Common::Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
|
auto* videoOut = Common::Singleton<HLE::Graphics::Objects::VideoOutCtx>::Instance();
|
||||||
s32 pending = videoOut->getCtx(handle)->m_flip_status.flipPendingNum;
|
s32 pending = videoOut->getCtx(handle)->m_flip_status.flipPendingNum;
|
||||||
return pending;
|
return pending;
|
||||||
|
@ -234,8 +236,8 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode
|
||||||
auto* ctx = videoOut->getCtx(handle);
|
auto* ctx = videoOut->getCtx(handle);
|
||||||
|
|
||||||
if (flipMode != 1) {
|
if (flipMode != 1) {
|
||||||
// BREAKPOINT(); // only flipmode==1 is supported
|
// BREAKPOINT(); // only flipmode==1 is supported
|
||||||
LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flipmode {}\n", bufferIndex);//openBOR needs 2 but seems to work
|
LOG_TRACE_IF(log_file_videoout, "sceVideoOutSubmitFlip flipmode {}\n", bufferIndex); // openBOR needs 2 but seems to work
|
||||||
}
|
}
|
||||||
if (bufferIndex == -1) {
|
if (bufferIndex == -1) {
|
||||||
BREAKPOINT(); // blank output not supported
|
BREAKPOINT(); // blank output not supported
|
||||||
|
|
|
@ -32,8 +32,8 @@ struct File {
|
||||||
std::string m_host_name;
|
std::string m_host_name;
|
||||||
std::string m_guest_name;
|
std::string m_guest_name;
|
||||||
Common::FS::File f;
|
Common::FS::File f;
|
||||||
std::vector<Common::FS::DirEntry> dents;
|
std::vector<Common::FS::DirEntry> dirents;
|
||||||
u32 dents_index;
|
u32 dirents_index;
|
||||||
};
|
};
|
||||||
class HandleTable {
|
class HandleTable {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -40,8 +40,8 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
return SCE_KERNEL_ERROR_ENOTDIR;
|
return SCE_KERNEL_ERROR_ENOTDIR;
|
||||||
}
|
}
|
||||||
return SCE_KERNEL_ERROR_ENOTDIR;*/
|
return SCE_KERNEL_ERROR_ENOTDIR;*/
|
||||||
//there is seems to be a bug with create_directories return false even if the directory creates so don't check until we find
|
// there is seems to be a bug with create_directories return false even if the directory creates so don't check until we find
|
||||||
//a better solution
|
// a better solution
|
||||||
std::filesystem::create_directories(file->m_host_name);
|
std::filesystem::create_directories(file->m_host_name);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,12 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
if (create) {
|
if (create) {
|
||||||
return handle; // directory already exists
|
return handle; // directory already exists
|
||||||
} else {
|
} else {
|
||||||
BREAKPOINT(); // here we should handle open directory mode
|
file->dirents = Common::FS::File::getDirectoryEntries(file->m_host_name);
|
||||||
|
file->dirents_index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file->isOpened = true;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +67,30 @@ int PS4_SYSV_ABI sceKernelClose(int handle) {
|
||||||
return SCE_OK;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelGetdents(int fd, char* buf, int nbytes) {
|
||||||
|
PRINT_FUNCTION_NAME();
|
||||||
|
//TODO error codes
|
||||||
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
|
auto* file = h->getFile(fd);
|
||||||
|
|
||||||
|
if (file->dirents_index == file->dirents.size()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& entry = file->dirents.at(file->dirents_index++);
|
||||||
|
auto str = entry.name;
|
||||||
|
auto str_size = str.size() - 1;
|
||||||
|
|
||||||
|
SceKernelDirent* sce_ent = (SceKernelDirent*)buf;
|
||||||
|
sce_ent->d_fileno = fd; //TODO this should be unique but atm it changes maybe switch to a hash or something?
|
||||||
|
sce_ent->d_reclen = sizeof(SceKernelDirent);
|
||||||
|
sce_ent->d_type = (entry.isFile ? 8 : 4);
|
||||||
|
sce_ent->d_namlen = str_size;
|
||||||
|
strcpy_s(sce_ent->d_name, SCE_MAX_PATH, str.data());
|
||||||
|
|
||||||
|
return sizeof(SceKernelDirent);
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
||||||
LOG_INFO_IF(log_file_fs, "posix open redirect to sceKernelOpen\n");
|
LOG_INFO_IF(log_file_fs, "posix open redirect to sceKernelOpen\n");
|
||||||
int result = sceKernelOpen(path, flags, mode);
|
int result = sceKernelOpen(path, flags, mode);
|
||||||
|
@ -78,6 +103,7 @@ int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16
|
||||||
void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym) {
|
void fileSystemSymbolsRegister(Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
|
||||||
LIB_FUNCTION("UK2Tl2DWUns", "libkernel", 1, "libkernel", 1, 1, sceKernelClose);
|
LIB_FUNCTION("UK2Tl2DWUns", "libkernel", 1, "libkernel", 1, 1, sceKernelClose);
|
||||||
|
LIB_FUNCTION("j2AIqSqJP0w", "libkernel", 1, "libkernel", 1, 1, sceKernelGetdents);
|
||||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,16 @@ class SymbolsResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Core::Libraries::LibKernel {
|
namespace Core::Libraries::LibKernel {
|
||||||
|
constexpr int SCE_MAX_PATH = 255;
|
||||||
|
|
||||||
|
struct SceKernelDirent {
|
||||||
|
uint32_t d_fileno; /* file number of entry */
|
||||||
|
uint16_t d_reclen; /* length of this record */
|
||||||
|
uint8_t d_type; /* file type, see below */
|
||||||
|
uint8_t d_namlen; /* length of string in d_name */
|
||||||
|
char d_name[SCE_MAX_PATH + 1]; /* name must be no longer than this */
|
||||||
|
};
|
||||||
|
|
||||||
// open flags
|
// open flags
|
||||||
constexpr u32 SCE_KERNEL_O_RDONLY = 0x0000; // Open as read-only
|
constexpr u32 SCE_KERNEL_O_RDONLY = 0x0000; // Open as read-only
|
||||||
constexpr u32 SCE_KERNEL_O_WRONLY = 0x0001; // Open as write-only
|
constexpr u32 SCE_KERNEL_O_WRONLY = 0x0001; // Open as write-only
|
||||||
|
@ -24,6 +34,7 @@ constexpr u32 SCE_KERNEL_O_DIRECTORY = 0x00020000; // Error will occur if not a
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
||||||
int PS4_SYSV_ABI sceKernelClose(int handle);
|
int PS4_SYSV_ABI sceKernelClose(int handle);
|
||||||
|
int PS4_SYSV_ABI sceKernelGetdents(int fd, char *buf, int nbytes);
|
||||||
int PS4_SYSV_ABI posix_open(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
int PS4_SYSV_ABI posix_open(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
||||||
|
|
||||||
void fileSystemSymbolsRegister(Loader::SymbolsResolver *sym);
|
void fileSystemSymbolsRegister(Loader::SymbolsResolver *sym);
|
||||||
|
|
Loading…
Reference in New Issue