Skip to content

Commit

Permalink
Merge pull request shadps4-emu#320 from shadps4-emu/miscFixes7
Browse files Browse the repository at this point in the history
Misc Fixes 7
  • Loading branch information
georgemoralis authored Jul 26, 2024
2 parents a2cd166 + 600a13c commit 14e7859
Show file tree
Hide file tree
Showing 17 changed files with 187 additions and 43 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ set(CORE src/core/aerolib/stubs.cpp
src/core/file_format/pkg_type.h
src/core/file_format/psf.cpp
src/core/file_format/psf.h
src/core/file_format/playgo_chunk.cpp
src/core/file_format/playgo_chunk.h
src/core/file_format/trp.cpp
src/core/file_format/trp.h
src/core/file_format/splash.h
Expand Down
2 changes: 1 addition & 1 deletion src/common/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ void load(const std::filesystem::path& path) {
auto general = generalResult.unwrap();

isNeo = toml::find_or<toml::boolean>(general, "isPS4Pro", false);
isFullscreen = toml::find_or<toml::boolean>(general, "Fullscreen", true);
isFullscreen = toml::find_or<toml::boolean>(general, "Fullscreen", false);
logFilter = toml::find_or<toml::string>(general, "logFilter", "");
logType = toml::find_or<toml::string>(general, "logType", "sync");
isShowSplash = toml::find_or<toml::boolean>(general, "showSplash", true);
Expand Down
1 change: 1 addition & 0 deletions src/common/path_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ static auto UserPaths = [] {
create_path(PathType::GameDataDir, user_dir / GAMEDATA_DIR);
create_path(PathType::TempDataDir, user_dir / TEMPDATA_DIR);
create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR);
create_path(PathType::DownloadDir, user_dir / DOWNLOAD_DIR);

return paths;
}();
Expand Down
2 changes: 2 additions & 0 deletions src/common/path_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum class PathType {
TempDataDir, // Where game temp data is stored.
GameDataDir, // Where game data is stored.
SysModuleDir, // Where system modules are stored.
DownloadDir, // Where downloads/temp files are stored.
};

constexpr auto PORTABLE_DIR = "user";
Expand All @@ -31,6 +32,7 @@ constexpr auto SAVEDATA_DIR = "savedata";
constexpr auto GAMEDATA_DIR = "data";
constexpr auto TEMPDATA_DIR = "temp";
constexpr auto SYSMODULES_DIR = "sys_modules";
constexpr auto DOWNLOAD_DIR = "download";

// Filenames
constexpr auto LOG_FILE = "shad_log.txt";
Expand Down
16 changes: 16 additions & 0 deletions src/core/file_format/playgo_chunk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "common/io_file.h"

#include "playgo_chunk.h"

bool PlaygoChunk::Open(const std::filesystem::path& filepath) {
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
if (!file.IsOpen()) {
return false;
}
file.Read(playgoHeader);

return true;
}
31 changes: 31 additions & 0 deletions src/core/file_format/playgo_chunk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once
#include <filesystem>
#include "common/types.h"

struct PlaygoHeader {
u32 magic;

u16 version_major;
u16 version_minor;
u16 image_count;
u16 chunk_count;
u16 mchunk_count;
u16 scenario_count;
// TODO fill the rest
};
class PlaygoChunk {
public:
PlaygoChunk() = default;
~PlaygoChunk() = default;

bool Open(const std::filesystem::path& filepath);
PlaygoHeader GetPlaygoHeader() {
return playgoHeader;
}

private:
PlaygoHeader playgoHeader;
};
22 changes: 13 additions & 9 deletions src/core/file_sys/fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,27 @@ void MntPoints::UnmountAll() {
}

std::filesystem::path MntPoints::GetHostPath(const std::string& guest_directory) {
const MntPair* mount = GetMount(guest_directory);
// Evil games like Turok2 pass double slashes e.g /app0//game.kpf
auto corrected_path = guest_directory;
size_t pos = corrected_path.find("//");
while (pos != std::string::npos) {
corrected_path.replace(pos, 2, "/");
pos = corrected_path.find("//", pos + 1);
}

const MntPair* mount = GetMount(corrected_path);
if (!mount) {
return guest_directory;
return "";
}

// Nothing to do if getting the mount itself.
if (guest_directory == mount->mount) {
if (corrected_path == mount->mount) {
return mount->host_path;
}

// Remove device (e.g /app0) from path to retrieve relative path.
u32 pos = mount->mount.size() + 1;
// Evil games like Turok2 pass double slashes e.g /app0//game.kpf
if (guest_directory[pos] == '/') {
pos++;
}
const auto rel_path = std::string_view(guest_directory).substr(pos);
pos = mount->mount.size() + 1;
const auto rel_path = std::string_view(corrected_path).substr(pos);
const auto host_path = mount->host_path / rel_path;
if (!NeedsCaseInsensiveSearch) {
return host_path;
Expand Down
8 changes: 2 additions & 6 deletions src/core/libraries/app_content/app_content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,9 @@ int PS4_SYSV_ABI sceAppContentTemporaryDataMount() {

int PS4_SYSV_ABI sceAppContentTemporaryDataMount2(OrbisAppContentTemporaryDataOption option,
OrbisAppContentMountPoint* mountPoint) {
if (std::string_view(mountPoint->data).empty()) // causing issues with save_data.
if (mountPoint == nullptr)
return ORBIS_APP_CONTENT_ERROR_PARAMETER;
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::TempDataDir) / id;
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, mountPoint->data);
strncpy(mountPoint->data, "/temp0", 16);
LOG_INFO(Lib_AppContent, "sceAppContentTemporaryDataMount2: option = {}, mountPoint = {}",
option, mountPoint->data);
return ORBIS_OK;
Expand Down
14 changes: 14 additions & 0 deletions src/core/libraries/kernel/file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
if (std::string_view{path} == "/dev/stdout") {
return 2002;
}
if (std::string_view{path} == "/dev/urandom") {
return 2003;
}
u32 handle = h->CreateHandle();
auto* file = h->GetFile(handle);
if (directory) {
Expand Down Expand Up @@ -113,6 +116,9 @@ int PS4_SYSV_ABI sceKernelClose(int d) {
if (d < 3) { // d probably hold an error code
return ORBIS_KERNEL_ERROR_EPERM;
}
if (d == 2003) { // dev/urandom case
return SCE_OK;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
if (file == nullptr) {
Expand Down Expand Up @@ -223,6 +229,13 @@ s64 PS4_SYSV_ABI posix_lseek(int d, s64 offset, int whence) {
}

s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) {
if (d == 2003) // dev urandom case
{
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++)
rbuf[i] = std::rand() & 0xFF;
return nbytes;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
if (file == nullptr) {
Expand Down Expand Up @@ -460,6 +473,7 @@ s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset) {
}

void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
std::srand(std::time(nullptr));
LIB_FUNCTION("1G3lF1Gg1k8", "libkernel", 1, "libkernel", 1, 1, sceKernelOpen);
LIB_FUNCTION("wuCroIGjt2g", "libScePosix", 1, "libkernel", 1, 1, posix_open);
LIB_FUNCTION("UK2Tl2DWUns", "libkernel", 1, "libkernel", 1, 1, sceKernelClose);
Expand Down
7 changes: 4 additions & 3 deletions src/core/libraries/kernel/memory_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ int PS4_SYSV_ABI sceKernelGetDirectMemoryType(u64 addr, int* directMemoryTypeOut

s32 PS4_SYSV_ABI sceKernelBatchMap(OrbisKernelBatchMapEntry* entries, int numEntries,
int* numEntriesOut) {
return sceKernelBatchMap2(entries, numEntries, numEntriesOut, 0x10); // 0x10 : Fixed / 0x410
return sceKernelBatchMap2(entries, numEntries, numEntriesOut,
MemoryFlags::SCE_KERNEL_MAP_FIXED); // 0x10, 0x410?
}

int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len);
Expand All @@ -243,7 +244,7 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn
break; // break and assign a value to numEntriesOut.
}

if (entries[i].operation == 0) { // MAP_DIRECT
if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_DIRECT) {
result = sceKernelMapNamedDirectMemory(&entries[i].start, entries[i].length,
entries[i].protection, flags,
static_cast<s64>(entries[i].offset), 0, "");
Expand All @@ -256,7 +257,7 @@ s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEn

if (result == 0)
processed++;
} else if (entries[i].operation == 1) {
} else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_UNMAP) {
result = sceKernelMunmap(entries[i].start, entries[i].length);
LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}",
i, entries[i].operation, entries[i].length, result);
Expand Down
8 changes: 8 additions & 0 deletions src/core/libraries/kernel/memory_management.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ enum MemoryProtection : u32 {
SCE_KERNEL_PROT_GPU_RW = 0x30 // Permit reads/writes from the GPU
};

enum MemoryOpTypes : u32 {
ORBIS_KERNEL_MAP_OP_MAP_DIRECT = 0,
ORBIS_KERNEL_MAP_OP_UNMAP = 1,
ORBIS_KERNEL_MAP_OP_PROTECT = 2,
ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE = 3,
ORBIS_KERNEL_MAP_OP_TYPE_PROTECT = 4
};

struct OrbisQueryInfo {
uintptr_t start;
uintptr_t end;
Expand Down
40 changes: 40 additions & 0 deletions src/core/libraries/kernel/thread_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1336,10 +1336,23 @@ int PS4_SYSV_ABI posix_sem_wait(sem_t* sem) {
return sem_wait(sem);
}

int PS4_SYSV_ABI posix_sem_timedwait(sem_t* sem, const timespec* t) {
#ifndef __APPLE__
return sem_timedwait(sem, t);
#else
LOG_ERROR(Kernel_Pthread, "Apple doesn't support sem_timedwait yet");
return 0; // unsupported for apple yet
#endif
}

int PS4_SYSV_ABI posix_sem_post(sem_t* sem) {
return sem_post(sem);
}

int PS4_SYSV_ABI posix_sem_destroy(sem_t* sem) {
return sem_destroy(sem);
}

int PS4_SYSV_ABI posix_sem_getvalue(sem_t* sem, int* sval) {
return sem_getvalue(sem, sval);
}
Expand Down Expand Up @@ -1403,6 +1416,26 @@ int PS4_SYSV_ABI posix_pthread_condattr_setclock(ScePthreadCondattr* attr, clock
return SCE_OK;
}

int PS4_SYSV_ABI posix_pthread_getschedparam(ScePthread thread, int* policy,
SceKernelSchedParam* param) {
return scePthreadGetschedparam(thread, policy, param);
}

int PS4_SYSV_ABI posix_pthread_setschedparam(ScePthread thread, int policy,
const SceKernelSchedParam* param) {
return scePthreadSetschedparam(thread, policy, param);
}

int PS4_SYSV_ABI posix_pthread_attr_getschedpolicy(const ScePthreadAttr* attr, int* policy) {
return scePthreadAttrGetschedpolicy(attr, policy);
}

int PS4_SYSV_ABI scePthreadRename(ScePthread thread, const char* name) {
thread->name = name;
LOG_INFO(Kernel_Pthread, "scePthreadRename: name = {}", thread->name);
return SCE_OK;
}

void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate);
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
Expand All @@ -1427,6 +1460,7 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, scePthreadGetthreadid);
LIB_FUNCTION("1tKyG7RlMJo", "libkernel", 1, "libkernel", 1, 1, scePthreadGetprio);
LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, scePthreadSetprio);
LIB_FUNCTION("GBUY7ywdULE", "libkernel", 1, "libkernel", 1, 1, scePthreadRename);

LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_self);
Expand Down Expand Up @@ -1498,6 +1532,8 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("EjllaAqAPZo", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_condattr_setclock);
LIB_FUNCTION("Z4QosVuAsA0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_once);
LIB_FUNCTION("RtLRV-pBTTY", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_attr_getschedpolicy);

// openorbis weird functions
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
Expand All @@ -1512,9 +1548,13 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("+U1R4WtXvoc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_detach);
LIB_FUNCTION("CBNtXOoef-E", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_max);
LIB_FUNCTION("m0iS6jNsXds", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_min);
LIB_FUNCTION("FIs3-UQT9sg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getschedparam);
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
LIB_FUNCTION("pDuPEf3m4fI", "libScePosix", 1, "libkernel", 1, 1, posix_sem_init);
LIB_FUNCTION("YCV5dGGBcCo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_wait);
LIB_FUNCTION("w5IHyvahg-o", "libScePosix", 1, "libkernel", 1, 1, posix_sem_timedwait);
LIB_FUNCTION("IKP8typ0QUk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_post);
LIB_FUNCTION("cDW233RAwWo", "libScePosix", 1, "libkernel", 1, 1, posix_sem_destroy);
LIB_FUNCTION("Bq+LRV-N6Hk", "libScePosix", 1, "libkernel", 1, 1, posix_sem_getvalue);
// libs
RwlockSymbolsRegister(sym);
Expand Down
18 changes: 13 additions & 5 deletions src/core/libraries/playgo/playgo.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <core/file_format/playgo_chunk.h>
#include "common/logging/log.h"
#include "common/singleton.h"
#include "core/libraries/error_codes.h"
Expand Down Expand Up @@ -50,9 +51,16 @@ s32 PS4_SYSV_ABI scePlayGoGetLocus(OrbisPlayGoHandle handle, const OrbisPlayGoCh
uint32_t numberOfEntries, OrbisPlayGoLocus* outLoci) {
LOG_ERROR(Lib_PlayGo, "(STUBBED)called handle = {}, chunkIds = {}, numberOfEntries = {}",
handle, *chunkIds, numberOfEntries);
// assign all now so that scePlayGoGetLocus is not called again for every single entry
std::fill(outLoci, outLoci + numberOfEntries,
OrbisPlayGoLocusValue::ORBIS_PLAYGO_LOCUS_LOCAL_FAST);

auto* playgo = Common::Singleton<PlaygoChunk>::Instance();

for (uint32_t i = 0; i < numberOfEntries; i++) {
if (chunkIds[i] <= playgo->GetPlaygoHeader().mchunk_count) {
outLoci[i] = OrbisPlayGoLocusValue::ORBIS_PLAYGO_LOCUS_LOCAL_FAST;
} else {
return ORBIS_PLAYGO_ERROR_BAD_CHUNK_ID;
}
}
return ORBIS_OK;
}

Expand All @@ -68,7 +76,7 @@ s32 PS4_SYSV_ABI scePlayGoGetProgress(OrbisPlayGoHandle handle, const OrbisPlayG
s32 PS4_SYSV_ABI scePlayGoGetToDoList(OrbisPlayGoHandle handle, OrbisPlayGoToDo* outTodoList,
u32 numberOfEntries, u32* outEntries) {
LOG_ERROR(Lib_PlayGo, "(STUBBED)called");
if (handle != shadMagic)
if (handle != 1)
return ORBIS_PLAYGO_ERROR_BAD_HANDLE;
if (outTodoList == nullptr)
return ORBIS_PLAYGO_ERROR_BAD_POINTER;
Expand All @@ -86,7 +94,7 @@ s32 PS4_SYSV_ABI scePlayGoInitialize(OrbisPlayGoInitParams* param) {
}

s32 PS4_SYSV_ABI scePlayGoOpen(OrbisPlayGoHandle* outHandle, const void* param) {
*outHandle = shadMagic;
*outHandle = 1;
LOG_INFO(Lib_PlayGo, "(STUBBED)called");
return ORBIS_OK;
}
Expand Down
Loading

0 comments on commit 14e7859

Please sign in to comment.