mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-08 13:50:20 +00:00
Merge pull request #14954 from BunnyFl/feat/videoout-fw1342-sysmode
feat(libSceVideoOut): answer the mode helpers as firmware 13.42 does
This commit is contained in:
4 files changed
+80
-24
No files matched your search
@@ -9,6 +9,12 @@
|
||||
namespace {
|
||||
constexpr int VideoOutErrorCurveSamplePoints = static_cast<int>(0x8029001Cu);
|
||||
constexpr int VideoOutErrorLatestEopHandle = static_cast<int>(0x802900FFu);
|
||||
|
||||
std::uint32_t ModeFlags(const void* mode) {
|
||||
std::uint32_t flags;
|
||||
std::memcpy(&flags, static_cast<const std::uint8_t*>(mode) + 0x20, sizeof(flags));
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
@@ -425,8 +431,10 @@ int APS5_VABI sceVideoOutSysHdmiMonitorInfoIsMorpheus() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysInitMode() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
void APS5_VABI sceVideoOutSysInitMode(void* mode) {
|
||||
std::memset(mode, 0xFF, 0x20);
|
||||
const std::uint32_t size = 0x20;
|
||||
std::memcpy(mode, &size, sizeof(size));
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysIsModeS3d() {
|
||||
@@ -453,26 +461,25 @@ int APS5_VABI sceVideoOutSysIsUserStatusVr() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysModeIsHdr() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
int APS5_VABI sceVideoOutSysModeIsHdr(const void* mode) {
|
||||
const auto value = static_cast<const std::uint8_t*>(mode)[6];
|
||||
return static_cast<std::uint8_t>(value - 12u) < 6u ? 1 : 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysModeIsSystemDefault() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
int APS5_VABI sceVideoOutSysModeIsSystemDefault(const void* mode) {
|
||||
return static_cast<int>(~ModeFlags(mode) & 1u);
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysModeIsVrLegacy() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
int APS5_VABI sceVideoOutSysModeIsVrLegacy(const void* mode) {
|
||||
return (ModeFlags(mode) & 6u) == 6u ? 1 : 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysModeIsVrNative() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
int APS5_VABI sceVideoOutSysModeIsVrNative(const void* mode) {
|
||||
return (ModeFlags(mode) & 6u) == 2u ? 1 : 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysModeIsVr(const void* mode) {
|
||||
std::uint32_t flags;
|
||||
std::memcpy(&flags, static_cast<const std::uint8_t*>(mode) + 0x20, sizeof(flags));
|
||||
return static_cast<int>((flags >> 1) & 1u);
|
||||
return static_cast<int>((ModeFlags(mode) >> 1) & 1u);
|
||||
}
|
||||
|
||||
int APS5_VABI sceVideoOutSysOpenInternal() {
|
||||
|
||||
@@ -107,17 +107,17 @@ int APS5_VABI sceVideoOutSysGetVblankStatus2();
|
||||
int APS5_VABI sceVideoOutSysGetVblankStatus();
|
||||
int APS5_VABI sceVideoOutSysGetVideoOutModeByBusSpecifier();
|
||||
int APS5_VABI sceVideoOutSysHdmiMonitorInfoIsMorpheus();
|
||||
int APS5_VABI sceVideoOutSysInitMode();
|
||||
void APS5_VABI sceVideoOutSysInitMode(void* mode);
|
||||
int APS5_VABI sceVideoOutSysIsModeS3d();
|
||||
int APS5_VABI sceVideoOutSysIsOutputSupported();
|
||||
int APS5_VABI sceVideoOutSysIsSupportedByMonitorInfo_();
|
||||
int APS5_VABI sceVideoOutSysIsUserStatusHdr();
|
||||
int APS5_VABI sceVideoOutSysIsUserStatusSystemDefault();
|
||||
int APS5_VABI sceVideoOutSysIsUserStatusVr();
|
||||
int APS5_VABI sceVideoOutSysModeIsHdr();
|
||||
int APS5_VABI sceVideoOutSysModeIsSystemDefault();
|
||||
int APS5_VABI sceVideoOutSysModeIsVrLegacy();
|
||||
int APS5_VABI sceVideoOutSysModeIsVrNative();
|
||||
int APS5_VABI sceVideoOutSysModeIsHdr(const void* mode);
|
||||
int APS5_VABI sceVideoOutSysModeIsSystemDefault(const void* mode);
|
||||
int APS5_VABI sceVideoOutSysModeIsVrLegacy(const void* mode);
|
||||
int APS5_VABI sceVideoOutSysModeIsVrNative(const void* mode);
|
||||
int APS5_VABI sceVideoOutSysModeIsVr(const void* mode);
|
||||
int APS5_VABI sceVideoOutSysOpenInternal();
|
||||
int APS5_VABI sceVideoOutSysOpenVrNative();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "prx/libSceVideoOut/include/InventoryExports.hpp"
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
@@ -19,6 +20,54 @@ static int ModeIsVr(std::uint32_t flags, std::uint8_t fill) {
|
||||
return sceVideoOutSysModeIsVr(mode.data());
|
||||
}
|
||||
|
||||
static std::array<std::uint8_t, 0x40> Mode(std::uint32_t flags, std::uint8_t fill) {
|
||||
std::array<std::uint8_t, 0x40> mode;
|
||||
mode.fill(fill);
|
||||
std::memcpy(mode.data() + 0x20, &flags, sizeof(flags));
|
||||
return mode;
|
||||
}
|
||||
|
||||
static std::array<std::uint8_t, 0x40> ModeWithByte6(std::uint8_t value, std::uint8_t fill) {
|
||||
std::array<std::uint8_t, 0x40> mode;
|
||||
mode.fill(fill);
|
||||
mode[6] = value;
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void CheckInitMode() {
|
||||
std::array<std::uint8_t, 0x40> mode;
|
||||
mode.fill(0x5A);
|
||||
sceVideoOutSysInitMode(mode.data());
|
||||
std::uint32_t size;
|
||||
std::memcpy(&size, mode.data(), sizeof(size));
|
||||
Require(size == 0x20, "sceVideoOutSysInitMode did not store 0x20 in the first dword");
|
||||
for (std::size_t i = 4; i < 0x20; ++i) Require(mode[i] == 0xFF, "sceVideoOutSysInitMode did not fill bytes 4 to 0x1F with 0xFF");
|
||||
for (std::size_t i = 0x20; i < mode.size(); ++i) Require(mode[i] == 0x5A, "sceVideoOutSysInitMode wrote past 0x20 bytes");
|
||||
}
|
||||
|
||||
static void CheckModeFlags() {
|
||||
for (std::uint8_t fill : {std::uint8_t{0}, std::uint8_t{0xFF}}) {
|
||||
for (std::uint32_t flags = 0; flags < 8; ++flags) {
|
||||
for (std::uint32_t high : {0u, 0xFFFFFFF8u}) {
|
||||
const auto mode = Mode(flags | high, fill);
|
||||
Require(sceVideoOutSysModeIsSystemDefault(mode.data()) == ((flags & 1u) ? 0 : 1), "sceVideoOutSysModeIsSystemDefault did not report bit 0 of the dword at 0x20 clear");
|
||||
Require(sceVideoOutSysModeIsVrNative(mode.data()) == ((flags & 6u) == 2u ? 1 : 0), "sceVideoOutSysModeIsVrNative did not report bits 1 and 2 of the dword at 0x20 as 1 and 0");
|
||||
Require(sceVideoOutSysModeIsVrLegacy(mode.data()) == ((flags & 6u) == 6u ? 1 : 0), "sceVideoOutSysModeIsVrLegacy did not report bits 1 and 2 of the dword at 0x20 both set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckModeIsHdr() {
|
||||
for (unsigned value = 0; value < 256; ++value) {
|
||||
const int expected = value >= 12 && value <= 17 ? 1 : 0;
|
||||
for (std::uint8_t fill : {std::uint8_t{0}, std::uint8_t{0xFF}}) {
|
||||
const auto mode = ModeWithByte6(static_cast<std::uint8_t>(value), fill);
|
||||
Require(sceVideoOutSysModeIsHdr(mode.data()) == expected, "sceVideoOutSysModeIsHdr did not report byte 6 from 12 to 17");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
Require(sceVideoOutAddBufferHdrPrivilege() == 0, "sceVideoOutAddBufferHdrPrivilege did not return 0");
|
||||
Require(sceVideoOutRazorRecallCallbacks() == 0, "sceVideoOutRazorRecallCallbacks did not return 0");
|
||||
@@ -30,5 +79,8 @@ int main() {
|
||||
Require(ModeIsVr(0xFFFFFFFFu, 0xFF) == 1, "a mode with every bit set did not report VR");
|
||||
Require(ModeIsVr(0xFFFFFFFDu, 0xFF) == 0, "the other bits of the dword at 0x20 reported VR");
|
||||
Require(ModeIsVr(0u, 0xFF) == 0, "bytes outside the dword at 0x20 reported VR");
|
||||
CheckInitMode();
|
||||
CheckModeFlags();
|
||||
CheckModeIsHdr();
|
||||
return 0;
|
||||
}
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
- The [revision-pinned identity inventory](https://gist.github.com/kyon-eth/ea0a096e6231dbe7b98b5a308e2ac91e/00f8422a1ae71e32816d72ae579c2f2d097f63a0) records module, logical library, symbol type and NIDs for [InventoryExports.cpp](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp); it is a metadata summary rather than independent verification. Some NIDs belong to multiple logical libraries within the module.
|
||||
|
||||
- [Additional callable exports](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp) - 175 entries observed in a 3.20-labelled image and a later 13.60-labelled image; of the original 182, 107 match the public 3.20 catalogue and 75 do not. These are import-resolution declarations only. Neither image label authenticates a retail firmware version. Parameter lists, return types and behavior are unverified; parameterless `int` declarations are placeholders, not verified ABI contracts. Every entry throws through `NotImplemented_nid_no_patch`. Unidentified names use literal NID aliases. No runtime functionality is implemented; data exports need separate analysis. Identified candidate names match their NIDs in the [public symbol database](https://github.com/zecoxao/sce_symbols/blob/2883963a0a514ba6e77407a08ef4730a65e88254/aerolib.csv) or [supplemental catalog](https://github.com/claimore22/ps5rs/blob/2304be5131221bae0dac24b9767cabffda33f747/data/nids.csv).
|
||||
- [Additional callable exports](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp) - 170 entries observed in a 3.20-labelled image and a later 13.60-labelled image; of the original 182, 107 match the public 3.20 catalogue and 75 do not. These are import-resolution declarations only. Neither image label authenticates a retail firmware version. Parameter lists, return types and behavior are unverified; parameterless `int` declarations are placeholders, not verified ABI contracts. Every entry throws through `NotImplemented_nid_no_patch`. Unidentified names use literal NID aliases. No runtime functionality is implemented; data exports need separate analysis. Identified candidate names match their NIDs in the [public symbol database](https://github.com/zecoxao/sce_symbols/blob/2883963a0a514ba6e77407a08ef4730a65e88254/aerolib.csv) or [supplemental catalog](https://github.com/claimore22/ps5rs/blob/2304be5131221bae0dac24b9767cabffda33f747/data/nids.csv).
|
||||
|
||||
| Name | NID |
|
||||
| --- | --- |
|
||||
@@ -167,17 +167,12 @@
|
||||
| `sceVideoOutSysGetVblankStatus` | `d1AjT2uZJn0` |
|
||||
| `sceVideoOutSysGetVideoOutModeByBusSpecifier` | `AAELy8Yc3Mc` |
|
||||
| `sceVideoOutSysHdmiMonitorInfoIsMorpheus` | `3-9DXFGVg0M` |
|
||||
| `sceVideoOutSysInitMode` | `9cmjhjqa7Sg` |
|
||||
| `sceVideoOutSysIsModeS3d` | `iUigHJ2op4M` |
|
||||
| `sceVideoOutSysIsOutputSupported` | `Z0EyU29WqOg` |
|
||||
| `sceVideoOutSysIsSupportedByMonitorInfo_` | `mfxElr79O7Q` |
|
||||
| `sceVideoOutSysIsUserStatusHdr` | `q+vWPvYIh8o` |
|
||||
| `sceVideoOutSysIsUserStatusSystemDefault` | `O57F5ikhGxo` |
|
||||
| `sceVideoOutSysIsUserStatusVr` | `4XsQdhiOaAc` |
|
||||
| `sceVideoOutSysModeIsHdr` | `I7-lGGvFgBM` |
|
||||
| `sceVideoOutSysModeIsSystemDefault` | `5Y8uUbGMio0` |
|
||||
| `sceVideoOutSysModeIsVrLegacy` | `zecl8Gox+P0` |
|
||||
| `sceVideoOutSysModeIsVrNative` | `SgA2MtojPto` |
|
||||
| `sceVideoOutSysOpenInternal` | `kP4l+nyBjRA` |
|
||||
| `sceVideoOutSysOpenVrNative` | `WUU+ufqgLJg` |
|
||||
| `sceVideoOutSysReadCrc64` | `eBvoaLwfBBQ` |
|
||||
@@ -247,6 +242,8 @@
|
||||
|
||||
- [Firmware 13.42 answers](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp) (libSceVideoOut) - `sceVideoOutAddBufferHdrPrivilege`, `sceVideoOutRazorRecallCallbacks` and `sceVideoOutSysUpdateRenderingMode` return 0, `sceVideoOutCurveSamplePointsCalc_` returns 0x8029001C, `sceVideoOutDriverGetLatestEopHandle` 0x802900FF and `sceVideoOutSysGetMonitorInfo_` -1, and `sceVideoOutSysModeIsVr` returns bit 1 of the dword at offset 0x20 of its argument, as firmware 13.42's libSceVideoOut does: read to the return, disassembly only, not measured on a console. Their parameter lists are unverified beyond what the code reads; the layout of the structure `sceVideoOutSysModeIsVr` reads is unknown apart from that dword. The module reads that dword without checking the pointer, so a null argument faults on the console as it does here
|
||||
|
||||
- [Firmware 13.42 mode helpers](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp) (libSceVideoOut) - `sceVideoOutSysInitMode` fills the first 0x20 bytes of its argument with 0xFF and then stores 0x20 in the first dword. Of the dword at offset 0x20, `sceVideoOutSysModeIsSystemDefault` reports bit 0 clear, `sceVideoOutSysModeIsVrNative` bits 2:1 equal to 01 and `sceVideoOutSysModeIsVrLegacy` both bits set; `sceVideoOutSysModeIsHdr` reports byte 6 from 12 to 17. As firmware 13.42's libSceVideoOut does: read to the return, disassembly only, not measured on a console. The init function leaves EAX unset, so it is declared `void`. Field meanings are unknown, and none of them checks the pointer.
|
||||
|
||||
- [sceVideoOutSetConfigurationMode](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp): the name hashes to NID `N1+j0RymMUQ`, a function export in both older and later version-labelled images. Its signature and behavior are unverified; this import-resolution declaration throws.
|
||||
|
||||
- [Older callable NIDs](../../../core/libs/prx/libSceVideoOut/InventoryExports.cpp): 7 unidentified exports have unverified names, signatures and behavior. These are throwing import-resolution placeholders; no functionality is implemented. No matching NIDs were found in the later module inventory. Six use the primary library qualifier and one uses the nosubmission qualifier; qualified guest import resolution is unverified.
|
||||
|
||||
Reference in new issue
Block a user