Merge branch 'main' into Feature/initial-ps4-ime-keyboard

This commit is contained in:
Valdis Bogdāns 2025-04-27 12:07:37 +03:00 committed by GitHub
commit 642dc9db99
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 102 additions and 21 deletions

View file

@ -61,6 +61,18 @@ struct SceKernelEvent {
void* udata = nullptr; /* opaque user data identifier */
};
struct OrbisVideoOutEventHint {
u64 event_id : 8;
u64 video_id : 8;
u64 flip_arg : 48;
};
struct OrbisVideoOutEventData {
u64 time : 12;
u64 count : 4;
u64 flip_arg : 48;
};
struct EqueueEvent {
SceKernelEvent event;
void* data = nullptr;
@ -84,19 +96,18 @@ struct EqueueEvent {
void TriggerDisplay(void* data) {
is_triggered = true;
auto hint = reinterpret_cast<u64>(data);
if (hint != 0) {
auto hint_h = static_cast<u32>(hint >> 8) & 0xFFFFFF;
auto ident_h = static_cast<u32>(event.ident >> 40);
if ((static_cast<u32>(hint) & 0xFF) == event.ident && event.ident != 0xFE &&
((hint_h ^ ident_h) & 0xFF) == 0) {
if (data != nullptr) {
auto event_data = static_cast<OrbisVideoOutEventData>(event.data);
auto event_hint_raw = reinterpret_cast<u64>(data);
auto event_hint = static_cast<OrbisVideoOutEventHint>(event_hint_raw);
if (event_hint.event_id == event.ident && event.ident != 0xfe) {
auto time = Common::FencedRDTSC();
auto mask = 0xF000;
if ((static_cast<u32>(event.data) & 0xF000) != 0xF000) {
mask = (static_cast<u32>(event.data) + 0x1000) & 0xF000;
auto counter = event_data.count;
if (counter != 0xf) {
counter++;
}
event.data = (mask | static_cast<u64>(static_cast<u32>(time) & 0xFFF) |
(hint & 0xFFFFFFFFFFFF0000));
event.data =
(time & 0xfff) | (counter << 0xc) | (event_hint_raw & 0xffffffffffff0000);
}
}
}

View file

@ -127,6 +127,62 @@ int PS4_SYSV_ABI sceKernelGetModuleInfoFromAddr(VAddr addr, int flags,
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceKernelGetModuleInfo(s32 handle, Core::OrbisKernelModuleInfo* info) {
if (info == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (info->st_size != sizeof(Core::OrbisKernelModuleInfo)) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
auto* linker = Common::Singleton<Core::Linker>::Instance();
auto* module = linker->GetModule(handle);
if (module == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
*info = module->GetModuleInfo();
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceKernelGetModuleInfoInternal(s32 handle, Core::OrbisKernelModuleInfoEx* info) {
if (info == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (info->st_size != sizeof(Core::OrbisKernelModuleInfoEx)) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
auto* linker = Common::Singleton<Core::Linker>::Instance();
auto* module = linker->GetModule(handle);
if (module == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
*info = module->GetModuleInfoEx();
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceKernelGetModuleList(s32* handles, u64 num_array, u64* out_count) {
if (handles == nullptr || out_count == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
auto* linker = Common::Singleton<Core::Linker>::Instance();
u64 count = 0;
auto* module = linker->GetModule(count);
while (module != nullptr && count < num_array) {
handles[count] = count;
count++;
module = linker->GetModule(count);
}
if (count == num_array && module != nullptr) {
return ORBIS_KERNEL_ERROR_ENOMEM;
}
*out_count = count;
return ORBIS_OK;
}
s32 PS4_SYSV_ABI exit(s32 status) {
UNREACHABLE_MSG("Exiting with status code {}", status);
return 0;
@ -141,6 +197,9 @@ void RegisterProcess(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym);
LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoForUnwind);
LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoFromAddr);
LIB_FUNCTION("kUpgrXIrz7Q", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfo);
LIB_FUNCTION("HZO7xOos4xc", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoInternal);
LIB_FUNCTION("IuxnUuXk6Bg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleList);
LIB_FUNCTION("6Z83sYWFlA8", "libkernel", 1, "libkernel", 1, 1, exit);
}

View file

@ -220,7 +220,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64*
if (ev->ident != static_cast<s32>(OrbisVideoOutInternalEventId::Flip) || ev->data == 0) {
*data = event_data;
} else {
*data = event_data | 0xFFFF000000000000;
*data = event_data | 0xffff000000000000;
}
return ORBIS_OK;
}
@ -233,7 +233,8 @@ s32 PS4_SYSV_ABI sceVideoOutGetEventCount(const Kernel::SceKernelEvent* ev) {
return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT;
}
return (ev->data >> 0xc) & 0xf;
auto event_data = static_cast<OrbisVideoOutEventData>(ev->data);
return event_data.count;
}
s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) {

View file

@ -111,6 +111,12 @@ struct SceVideoOutColorSettings {
u32 reserved[3];
};
struct OrbisVideoOutEventData {
u64 time : 12;
u64 count : 4;
u64 flip_arg : 48;
};
void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat,
u32 tilingMode, u32 aspectRatio, u32 width,
u32 height, u32 pitchInPixel);
@ -128,8 +134,8 @@ s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutio
s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index,
const void* param);
s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle);
int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev);
int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data);
s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev);
s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64* data);
s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma);
s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings);

View file

@ -83,7 +83,7 @@ public:
}
Module* GetModule(s32 index) const {
if (index >= 0 || index < m_modules.size()) {
if (index >= 0 && index < m_modules.size()) {
return m_modules.at(index).get();
}
return nullptr;

View file

@ -135,10 +135,14 @@ void Module::LoadModuleToMemory(u32& max_tls_index) {
if (do_map) {
elf.LoadSegment(segment_addr, phdr.p_offset, phdr.p_filesz);
}
if (info.num_segments < 4) {
auto& segment = info.segments[info.num_segments++];
segment.address = segment_addr;
segment.prot = phdr.p_flags;
segment.size = GetAlignedSize(phdr);
} else {
LOG_ERROR(Core_Linker, "Attempting to add too many segments!");
}
};
for (u16 i = 0; i < elf_header.e_phnum; i++) {

View file

@ -154,7 +154,7 @@ int main(int argc, char* argv[]) {
// If no game directory is set and no command line argument, prompt for it
if (Config::getGameInstallDirs().empty()) {
std::cout << "Warning: No game folder set, please set it by calling shadps4"
" with the --add-game-folder <folder_name> argument";
" with the --add-game-folder <folder_name> argument\n";
}
if (!has_game_argument) {