Compare commits
7 Commits
main
...
podakinos_
Author | SHA1 | Date |
---|---|---|
wheremyfoodat | 0a689270b3 | |
georgemoralis | 03a95ecadd | |
georgemoralis | 7cfcd952d2 | |
georgemoralis | 40a3868cbc | |
georgemoralis | 51260ca6ce | |
georgemoralis | 6bd5bfd500 | |
wheremyfoodat | fda578a625 |
|
@ -51,6 +51,8 @@ set(FILESYSTEM_SOURCES src/Emulator/HLE/Libraries/LibKernel/FileSystem/file_syst
|
|||
|
||||
set(HOST_SOURCES src/Emulator/Host/controller.cpp
|
||||
src/Emulator/Host/controller.h
|
||||
src/Emulator/Host/fs.cpp
|
||||
src/Emulator/Host/fs.h
|
||||
)
|
||||
|
||||
set(UTIL_SOURCES src/Emulator/Util/singleton.h
|
||||
|
@ -98,7 +100,7 @@ add_executable(shadps4
|
|||
src/Core/PS4/HLE/Kernel/cpu_management.cpp
|
||||
src/Core/PS4/HLE/Kernel/cpu_management.h
|
||||
|
||||
"src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h" "src/emulator.cpp" "src/emulator.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h" "src/Core/PS4/HLE/Graphics/graphics_ctx.h" "src/vulkan_util.cpp" "src/vulkan_util.h" "src/Core/PS4/GPU/video_out_buffer.cpp" "src/Core/PS4/GPU/video_out_buffer.h" "src/Core/PS4/HLE/Graphics/graphics_render.cpp" "src/Core/PS4/HLE/Graphics/graphics_render.h" "src/Core/PS4/GPU/tile_manager.cpp" "src/Core/PS4/GPU/tile_manager.h" "src/version.h" "src/Emulator/HLE/Libraries/LibSystemService/system_service.cpp" "src/Emulator/HLE/Libraries/LibSystemService/system_service.h" "src/Emulator/HLE/Libraries/LibKernel/FileSystem/meta_file_system.h" "src/Emulator/HLE/Libraries/LibKernel/FileSystem/meta_file_system.cpp")
|
||||
"src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h" "src/emulator.cpp" "src/emulator.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h" "src/Core/PS4/HLE/Graphics/graphics_ctx.h" "src/vulkan_util.cpp" "src/vulkan_util.h" "src/Core/PS4/GPU/video_out_buffer.cpp" "src/Core/PS4/GPU/video_out_buffer.h" "src/Core/PS4/HLE/Graphics/graphics_render.cpp" "src/Core/PS4/HLE/Graphics/graphics_render.h" "src/Core/PS4/GPU/tile_manager.cpp" "src/Core/PS4/GPU/tile_manager.h" "src/version.h")
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
target_link_libraries(shadps4 PUBLIC fmt mincore spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY} vulkan-1 spirv-tools-opt spirv-tools)
|
||||
|
|
|
@ -4,7 +4,9 @@ constexpr int SCE_OK = 0;
|
|||
constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009;
|
||||
constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000c; // Insufficient memory
|
||||
constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000e; // Invalid address pointer
|
||||
constexpr int SCE_KERNEL_ERROR_ENOTDIR = 0x80020014;
|
||||
constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; // null or invalid states
|
||||
constexpr int SCE_KERNEL_ERROR_EMFILE = 0x80020018; // Limit on the number of file descriptors that can be open has been reached
|
||||
constexpr int SCE_KERNEL_ERROR_EAGAIN = 0x80020023; // Memory cannot be allocated
|
||||
constexpr int SCE_KERNEL_ERROR_ENAMETOOLONG = 0x8002003f; // character strings exceeds valid size
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ void LibKernel_Register(SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
||||
// fs
|
||||
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, Emulator::HLE::Libraries::LibKernel::FileSystem::sceKernelOpen);
|
||||
LIB_FUNCTION("UK2Tl2DWUns", "libkernel", 1, "libkernel", 1, 1, Emulator::HLE::Libraries::LibKernel::FileSystem::sceKernelClose);
|
||||
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, Emulator::HLE::Libraries::LibKernel::FileSystem::POSIX::open);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,55 @@
|
|||
#include "file_system.h"
|
||||
#include <debug.h>
|
||||
|
||||
#include <Core/PS4/HLE/ErrorCodes.h>
|
||||
#include <Emulator/Util/singleton.h>
|
||||
#include <Util/log.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "Emulator/Host/fs.h"
|
||||
|
||||
namespace Emulator::HLE::Libraries::LibKernel::FileSystem {
|
||||
constexpr bool log_file_fs = true; // disable it to disable logging
|
||||
|
||||
int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||
LOG_INFO_IF(log_file_fs, "sceKernelOpen path = {} flags = {} mode = {}\n", path, log_hex_full(flags), log_hex_full(mode));
|
||||
return 0;
|
||||
|
||||
bool isDirectory = (flags & SCE_KERNEL_O_DIRECTORY) != 0;
|
||||
bool create = (flags & SCE_KERNEL_O_CREAT) != 0;
|
||||
|
||||
auto* h = singleton<Emulator::Host::Fs::HandleTable>::instance();
|
||||
auto* mnt = singleton<Emulator::Host::Fs::MntPoints>::instance();
|
||||
u32 handle = 0;
|
||||
if (h->createHandle().has_value()) {
|
||||
handle = h->createHandle().value();
|
||||
} else {
|
||||
return SCE_KERNEL_ERROR_EMFILE; // file descriptors is full error(?)
|
||||
}
|
||||
Emulator::Host::Fs::File* file = h->getFile(handle);
|
||||
|
||||
file->guest_path = path;
|
||||
if (isDirectory) {
|
||||
file->host_path = mnt->getHostDirectory(path);
|
||||
if (!std::filesystem::is_directory(file->host_path)) { // directory doesn't exist
|
||||
if (create) { // if we have a create flag create it
|
||||
if (std::filesystem::create_directories(file->host_path)) {
|
||||
return handle;
|
||||
} else {
|
||||
return SCE_KERNEL_ERROR_ENOTDIR;
|
||||
}
|
||||
} else {
|
||||
return SCE_KERNEL_ERROR_ENOTDIR;
|
||||
}
|
||||
}
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelClose(int handle) {
|
||||
LOG_INFO_IF(log_file_fs, "sceKernelClose descriptor = {}\n", handle);
|
||||
auto* h = singleton<Emulator::Host::Fs::HandleTable>::instance();
|
||||
Emulator::Host::Fs::File* file = h->getFile(handle);
|
||||
file->valid = false;
|
||||
h->freeHandle(handle);
|
||||
return SCE_OK;
|
||||
}
|
||||
} // namespace Emulator::HLE::Libraries::LibKernel::FileSystem
|
|
@ -2,6 +2,11 @@
|
|||
#include <types.h>
|
||||
|
||||
namespace Emulator::HLE::Libraries::LibKernel::FileSystem {
|
||||
int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
||||
|
||||
}
|
||||
constexpr u32 SCE_KERNEL_O_CREAT = 0x0200;
|
||||
constexpr u32 SCE_KERNEL_O_DIRECTORY = 0x00020000;
|
||||
|
||||
int PS4_SYSV_ABI sceKernelOpen(const char *path, int flags, /* SceKernelMode*/ u16 mode);
|
||||
int PS4_SYSV_ABI sceKernelClose(int handle);
|
||||
|
||||
} // namespace Emulator::HLE::Libraries::LibKernel::FileSystem
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Emulator::Host::GenericFS {
|
||||
|
||||
enum FileAccess {
|
||||
FILEACCESS_READ = 0,
|
||||
FILEACCESS_WRITE = 1,
|
||||
FILEACCESS_READWRITE = 2
|
||||
|
||||
};
|
||||
|
||||
class GenericHandleAllocator {
|
||||
public:
|
||||
virtual u32 requestHandle() = 0;
|
||||
virtual void releaseHandle(u32 handle) = 0;
|
||||
};
|
||||
|
||||
class AbstractFileSystem {
|
||||
public:
|
||||
virtual bool ownsHandle(u32 handle) = 0;
|
||||
virtual u32 openFile(std::string filename, FileAccess access) = 0;
|
||||
virtual void closeFile(u32 handle) = 0;
|
||||
};
|
||||
} // namespace Emulator::Host::GenericFS
|
|
@ -1,52 +0,0 @@
|
|||
#include "meta_file_system.h"
|
||||
|
||||
namespace Emulator::Host::GenericFS {
|
||||
|
||||
void MetaFileSystem::mount(std::string prefix, AbstractFileSystem* system) {
|
||||
System x;
|
||||
x.prefix = prefix;
|
||||
x.system = system;
|
||||
fileSystems.push_back(x);
|
||||
}
|
||||
|
||||
void MetaFileSystem::unMount(AbstractFileSystem* system) {}
|
||||
|
||||
void MetaFileSystem::unMountAll() { fileSystems.clear(); }
|
||||
|
||||
AbstractFileSystem* MetaFileSystem::getHandleOwner(u32 handle) {
|
||||
for (u32 i = 0; i < fileSystems.size(); i++) {
|
||||
if (fileSystems[i].system->ownsHandle(handle)) return fileSystems[i].system; // got it!
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
bool MetaFileSystem::mapFilePath(std::string inpath, std::string* outpath, AbstractFileSystem** system) {
|
||||
for (unsigned int i = 0; i < fileSystems.size(); i++) {
|
||||
int prefLen = fileSystems[i].prefix.size();
|
||||
if (fileSystems[i].prefix == inpath.substr(0, prefLen))
|
||||
{
|
||||
*outpath = inpath.substr(prefLen);
|
||||
*system = fileSystems[i].system;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 MetaFileSystem::openFile(std::string filename, FileAccess access) {
|
||||
AbstractFileSystem* system;
|
||||
std::string of;
|
||||
if (mapFilePath(filename, &of, &system)) {
|
||||
return system->openFile(of, access);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MetaFileSystem::closeFile(u32 handle) {
|
||||
AbstractFileSystem* sys = getHandleOwner(handle);
|
||||
if (sys) sys->closeFile(handle);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Emulator::Host::GenericFS
|
|
@ -1,40 +0,0 @@
|
|||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "generic_file_system.h"
|
||||
|
||||
namespace Emulator::Host::GenericFS {
|
||||
|
||||
class MetaFileSystem : public GenericHandleAllocator, AbstractFileSystem {
|
||||
struct System {
|
||||
std::string prefix;
|
||||
AbstractFileSystem *system;
|
||||
};
|
||||
|
||||
u32 current;
|
||||
std::vector<System> fileSystems;
|
||||
std::string currentDirectory;
|
||||
std::vector<u32> handler;
|
||||
|
||||
public:
|
||||
MetaFileSystem() : current(0) {}
|
||||
|
||||
void mount(std::string prefix, AbstractFileSystem *system);
|
||||
void unMount(AbstractFileSystem *system);
|
||||
void unMountAll();
|
||||
AbstractFileSystem *getHandleOwner(u32 handle);
|
||||
bool mapFilePath(std::string inpath, std::string *outpath, AbstractFileSystem **system);
|
||||
u32 requestHandle() {
|
||||
handler.push_back(current);
|
||||
current++;
|
||||
return handler.back();
|
||||
}
|
||||
void releaseHandle(u32 handle) { handler.erase(std::remove(handler.begin(), handler.end(), handle), handler.end()); }
|
||||
bool ownsHandle(u32 handle) { return false; }
|
||||
u32 openFile(std::string filename, FileAccess access);
|
||||
void closeFile(u32 handle);
|
||||
};
|
||||
} // namespace Emulator::Host::GenericFS
|
|
@ -1,11 +1,14 @@
|
|||
#include "posix_file_system.h"
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <Util/log.h>
|
||||
#include "file_system.h"
|
||||
|
||||
namespace Emulator::HLE::Libraries::LibKernel::FileSystem::POSIX {
|
||||
constexpr bool log_file_pfs = true; // disable it to disable logging
|
||||
|
||||
int PS4_SYSV_ABI open(const char* path, int flags, /* SceKernelMode*/ u16 mode) {
|
||||
LOG_INFO_IF(log_file_pfs, "posix open redirect to sceKernelOpen\n");
|
||||
int result = sceKernelOpen(path, flags, mode);
|
||||
if (result < 0) {
|
||||
BREAKPOINT(); // posix calls different only for their return values
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#include "fs.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Emulator::Host::Fs {
|
||||
void MntPoints::mount(const std::string& host_folder, const std::string& guest_folder) {
|
||||
Lib::LockMutexGuard lock(m_mutex);
|
||||
|
||||
MntPair pair;
|
||||
pair.host_path = host_folder;
|
||||
pair.guest_path = guest_folder;
|
||||
|
||||
m_mnt_pairs.push_back(pair);
|
||||
}
|
||||
void MntPoints::unMount(const std::string& path) {}
|
||||
void MntPoints::unmountAll() {}
|
||||
std::string MntPoints::getHostDirectory(const std::string& guest_directory) {
|
||||
Lib::LockMutexGuard lock(m_mutex);
|
||||
for (auto& pair : m_mnt_pairs) {
|
||||
if (pair.guest_path.starts_with(guest_directory)) {
|
||||
return pair.host_path + guest_directory;
|
||||
}
|
||||
}
|
||||
// hack for relative path , get app0 and assuming it goes from there
|
||||
for (auto& pair : m_mnt_pairs) {
|
||||
if (pair.guest_path.starts_with("/app0")) {
|
||||
std::replace(pair.host_path.begin(), pair.host_path.end(), '\\', '/');
|
||||
return pair.host_path + guest_directory;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
} // namespace Emulator::Host::Fs
|
|
@ -0,0 +1,108 @@
|
|||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "Lib/Threads.h"
|
||||
|
||||
namespace Emulator::Host::Fs {
|
||||
|
||||
class MntPoints {
|
||||
public:
|
||||
struct MntPair {
|
||||
std::string host_path;
|
||||
std::string guest_path; // e.g /app0/
|
||||
};
|
||||
|
||||
MntPoints() {}
|
||||
virtual ~MntPoints() {}
|
||||
void mount(const std::string& host_folder, const std::string& guest_folder);
|
||||
void unMount(const std::string& path);
|
||||
void unmountAll();
|
||||
std::string getHostDirectory(const std::string& guest_directory);
|
||||
|
||||
private:
|
||||
std::vector<MntPair> m_mnt_pairs;
|
||||
Lib::Mutex m_mutex;
|
||||
};
|
||||
struct File {
|
||||
bool valid = false; // Ôï descriptor åéíáé ïíôùò áíïé÷ôï;
|
||||
FILE* file; // File handle ôïõ áñ÷åéï
|
||||
std::filesystem::path host_path; // Path in host FS
|
||||
std::string guest_path; // Path in PS4 FS
|
||||
|
||||
File() : valid(true) {}
|
||||
};
|
||||
|
||||
class HandleTable {
|
||||
std::vector<File> files;
|
||||
u32 openFileCount = 0; // Ðïóá descriptors å÷ïõìå áíïé÷ôá;
|
||||
|
||||
public:
|
||||
static constexpr u32 MAX_FILE_DESCRIPTORS = 65536;
|
||||
|
||||
HandleTable() {
|
||||
files.reserve(128); // Êáíïõìå reserve ÷ùñï ãéá ìåñéêá áñ÷åéá ãéá íá áðïöõãïõìå allocations
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
for (auto& f : files) {
|
||||
if (f.valid) {
|
||||
// Êáíïõìå fclose ôï áñ÷åéï êáé ï,ôé áëëï åéíáé íá ãéíåé
|
||||
}
|
||||
}
|
||||
|
||||
files.clear();
|
||||
openFileCount = 0;
|
||||
}
|
||||
|
||||
// Åðéóôñåöåé handle ãéá íá äçìéïõñãçóïõìå íåï áñ÷åßï
|
||||
std::optional<u32> createHandle() {
|
||||
if (openFileCount >= MAX_FILE_DESCRIPTORS) {
|
||||
// Äåí ìðïñïõìå íá áíïéîïõìå áëëá descriptors, å÷ïõìå âáñåóåé ôï max
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Ìðïñïõìå óéãïõñá íá äçìéïõñãçóïõìå handle, ïðïôå áõîáíïõìå ôï handle count
|
||||
openFileCount += 1;
|
||||
|
||||
// Êïéôáìå áí êáíåíá áðôá files óôï vector åéíáé åëåõèåñï ãéá íá ôï êáíïõìå reuse
|
||||
for (size_t i = 0; i < files.size(); i++) {
|
||||
// Âñçêáìå åëåõèåñï áñ÷åéï, åðéóôñåöïõìå ôï index ôïõ
|
||||
if (!files[i].valid) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Äåí õðáñ÷åé åëåõèåñï óôï vector áëëá äåí å÷ïõìå åîáíôëçóåé ôï cap, ïðïôå ìåãáëùíïõìå ôï vector
|
||||
// Êáé åðéóôñåöïõìå ôï index ôïõ êáéíïõñãéïõ
|
||||
u32 handle = files.size();
|
||||
files.push_back(File());
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
File* getFile(u32 handle) { return &files[handle]; }
|
||||
|
||||
void freeHandle(u32 handle) {
|
||||
if (handle >= files.size()) {
|
||||
// Óôáíôáñ invalid
|
||||
printf("POUTSA\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (files[handle].valid) {
|
||||
// Ðáëé êáíïõìå fclose êáé ðéðåò êáé ôï ìáñêáñïõìå ãéá reuse
|
||||
files[handle].valid = false;
|
||||
// Ìåéïí åíá áíïé÷ôï áñ÷åéï
|
||||
openFileCount -= 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Emulator::Host::Fs
|
10
src/main.cpp
10
src/main.cpp
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
|
@ -35,7 +35,8 @@
|
|||
#include "Core/PS4/HLE/Libs.h"
|
||||
#include "Core/PS4/Linker.h"
|
||||
#include "Lib/Threads.h"
|
||||
#include "Emulator/Util\singleton.h"
|
||||
#include "Emulator\Util\singleton.h"
|
||||
#include "Emulator\Host\fs.h"
|
||||
#include "discord.h"
|
||||
|
||||
// Main code
|
||||
|
@ -51,9 +52,12 @@ int main(int argc, char* argv[]) {
|
|||
Emu::emuInit(width, height);
|
||||
HLE::Libs::Graphics::VideoOut::videoOutInit(width, height);
|
||||
Lib::InitThreads();
|
||||
|
||||
const char* const path = argv[1]; // argument 1 is the path of self file to boot
|
||||
|
||||
auto* mnt = singleton<Emulator::Host::Fs::MntPoints>::instance();
|
||||
std::filesystem::path p = std::string(path);
|
||||
mnt->mount(p.parent_path().string(), "/app0");
|
||||
|
||||
auto* linker = singleton<Linker>::instance();
|
||||
HLE::Libs::Init_HLE_Libs(linker->getHLESymbols());
|
||||
auto* module = linker->LoadModule(path); // load main executable
|
||||
|
|
Loading…
Reference in New Issue