mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-29 12:15:39 +00:00
214 lines
14 KiB
C++
214 lines
14 KiB
C++
#include "prx/libSceCamera/libSceCamera.hpp"
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
using GetU32 = int(APS5_VABI*)(std::int32_t, std::uint32_t, std::uint32_t*, void*);
|
|
using SetU32 = int(APS5_VABI*)(std::int32_t, std::uint32_t, std::uint32_t, const void*);
|
|
|
|
namespace {
|
|
|
|
constexpr int ErrorParam = static_cast<int>(0x802E0000u);
|
|
constexpr int ErrorNotInit = static_cast<int>(0x802E0002u);
|
|
constexpr int ErrorNotOpen = static_cast<int>(0x802E0004u);
|
|
constexpr int ErrorNotConnected = static_cast<int>(0x802E0010u);
|
|
constexpr int ErrorFatal = static_cast<int>(0x802E00FFu);
|
|
constexpr std::uint32_t Channel0 = 1;
|
|
constexpr std::uint32_t Channel1 = 2;
|
|
constexpr std::uint32_t ChannelBoth = 3;
|
|
|
|
void Require(bool condition, const char* message) {
|
|
if (!condition) {
|
|
std::fprintf(stderr, "Camera settings: %s\n", message);
|
|
std::abort();
|
|
}
|
|
}
|
|
|
|
CameraConfig SizedConfig() {
|
|
CameraConfig config;
|
|
std::memset(&config, 0x5a, sizeof(config));
|
|
config.sizeThis = sizeof(CameraConfig);
|
|
return config;
|
|
}
|
|
|
|
void CheckBeforeOpen() {
|
|
std::uint32_t value = 0;
|
|
CameraConfig config = SizedConfig();
|
|
const CameraDeviceInfo info{sizeof(CameraDeviceInfo), 1, 0, 0};
|
|
Require(sceCameraGetContrast(1, Channel0, &value, nullptr) == ErrorNotOpen, "a getter before open must report NOT_OPEN");
|
|
Require(sceCameraSetContrast(1, Channel0, 1, nullptr) == ErrorNotOpen, "a setter before open must report NOT_OPEN");
|
|
Require(sceCameraGetConfig(1, &config) == ErrorNotOpen, "reading the configuration before open must report NOT_OPEN");
|
|
Require(sceCameraGetDeviceConfigWithoutHandle(&config) == ErrorNotOpen, "reading the device configuration before open must report NOT_OPEN");
|
|
Require(sceCameraGetMmapConnectedCount(&value) == ErrorNotOpen, "the mapped device count before open must report NOT_OPEN");
|
|
Require(sceCameraGetDeviceInfo(0, &info) == ErrorNotInit, "device info before open must report NOT_INIT");
|
|
Require(sceCameraGetProductInfo(&value) == ErrorNotInit, "product info before open must report NOT_INIT");
|
|
Require(sceCameraGetRegistryInfo(&value) == ErrorNotInit, "registry info before open must report NOT_INIT");
|
|
}
|
|
|
|
void CheckGetter(GetU32 get, std::uint32_t expected, const char* message) {
|
|
std::uint32_t value = 0x5a5a5a5a;
|
|
Require(get(1, Channel1, &value, nullptr) == 0 && value == expected, message);
|
|
value = 0x5a5a5a5a;
|
|
std::uint32_t option = 0;
|
|
Require(get(0, Channel0, &value, nullptr) == ErrorParam, "a getter must reject handle 0");
|
|
Require(get(99, Channel0, &value, nullptr) == ErrorNotOpen && value == 0x5a5a5a5a, "a fabricated handle must not read settings");
|
|
Require(get(1, 0, &value, nullptr) == ErrorParam, "a getter must reject channel 0");
|
|
Require(get(1, ChannelBoth, &value, nullptr) == ErrorParam, "a getter must reject both channels");
|
|
Require(get(1, Channel0, nullptr, nullptr) == ErrorParam, "a getter must reject a null result");
|
|
Require(get(1, Channel0, &value, &option) == ErrorParam, "a getter must reject an option");
|
|
Require(value == 0x5a5a5a5a, "a refused getter must not write its result");
|
|
}
|
|
|
|
void CheckGetters() {
|
|
CheckGetter(sceCameraGetAutoWhiteBalance, 0, "automatic white balance must be off");
|
|
CheckGetter(sceCameraGetDefectivePixelCancellation, 0, "defective pixel cancellation must be off");
|
|
CheckGetter(sceCameraGetLensCorrection, 0, "lens correction must be off");
|
|
CheckGetter(sceCameraGetContrast, 32, "the contrast must be 32");
|
|
CheckGetter(sceCameraGetSaturation, 64, "the saturation must be 64");
|
|
CheckGetter(sceCameraGetSharpness, 1, "the sharpness must be 1");
|
|
std::int32_t hue = 0;
|
|
Require(sceCameraGetHue(1, Channel0, &hue, nullptr) == 0 && hue == 1, "the hue must be 1");
|
|
CameraExposureGain exposure{9, 9, 9, 9};
|
|
Require(sceCameraGetExposureGain(1, Channel0, &exposure, nullptr) == 0, "the exposure must be readable");
|
|
Require(exposure.exposureControl == 0 && exposure.exposure == 20 && exposure.gain == 100 && exposure.mode == 0, "the exposure defaults are wrong");
|
|
CameraWhiteBalance balance{9, 9, 9, 9};
|
|
Require(sceCameraGetWhiteBalance(1, Channel0, &balance, nullptr) == 0, "the white balance must be readable");
|
|
Require(balance.whiteBalanceControl == 0 && balance.gainRed == 768 && balance.gainBlue == 768 && balance.gainGreen == 512, "the white balance defaults are wrong");
|
|
CameraGamma gamma;
|
|
std::memset(&gamma, 0x5a, sizeof(gamma));
|
|
Require(sceCameraGetGamma(1, Channel0, &gamma, nullptr) == 0 && gamma.gammaControl == 0 && gamma.value == 4 && gamma.reserved[15] == 0, "the gamma defaults are wrong");
|
|
std::uint32_t enable = 9;
|
|
CameraAutoExposureGainTarget target{sizeof(CameraAutoExposureGainTarget), 0x10};
|
|
Require(sceCameraGetAutoExposureGain(1, Channel0, &enable, &target) == 0 && enable == 0, "automatic exposure must be off");
|
|
Require(target.sizeThis == 0 && target.target == 0, "the automatic exposure target must be cleared");
|
|
target.sizeThis = 4;
|
|
Require(sceCameraGetAutoExposureGain(1, Channel0, &enable, &target) == ErrorParam, "a target of the wrong size must be rejected");
|
|
Require(sceCameraGetAutoExposureGain(1, Channel0, &enable, nullptr) == 0, "automatic exposure must be readable without a target");
|
|
}
|
|
|
|
void CheckAttribute() {
|
|
CameraAttribute attribute;
|
|
std::memset(&attribute, 0x5a, sizeof(attribute));
|
|
attribute.sizeThis = sizeof(CameraAttribute);
|
|
attribute.channel = Channel1;
|
|
Require(sceCameraGetAttribute(1, &attribute) == 0, "the attributes must be readable");
|
|
Require(attribute.sizeThis == sizeof(CameraAttribute) && attribute.channel == Channel1, "the attribute header must be kept");
|
|
Require(attribute.framePosition.x == 0 && attribute.exposureGain.exposure == 83 && attribute.exposureGain.gain == 100, "the attribute exposure is wrong");
|
|
Require(attribute.whiteBalance.gainRed == 768 && attribute.whiteBalance.gainGreen == 512 && attribute.gamma.value == 4, "the attribute colour defaults are wrong");
|
|
Require(attribute.saturation == 64 && attribute.contrast == 32 && attribute.sharpness == 1 && attribute.hue == 1 && attribute.reserved[3] == 0, "the attribute levels are wrong");
|
|
attribute.channel = ChannelBoth;
|
|
Require(sceCameraGetAttribute(1, &attribute) == ErrorParam, "reading both channels at once must be rejected");
|
|
Require(sceCameraSetAttribute(1, &attribute) == ErrorNotConnected, "writing both channels must report NOT_CONNECTED");
|
|
attribute.channel = 4;
|
|
Require(sceCameraSetAttribute(1, &attribute) == ErrorParam, "an unknown channel must be rejected");
|
|
attribute.channel = Channel0;
|
|
attribute.sizeThis = sizeof(CameraAttribute) - 4;
|
|
Require(sceCameraGetAttribute(1, &attribute) == ErrorParam && sceCameraSetAttribute(1, &attribute) == ErrorParam, "an attribute of the wrong size must be rejected");
|
|
Require(sceCameraGetAttribute(1, nullptr) == ErrorParam && sceCameraSetAttribute(1, nullptr) == ErrorParam, "a null attribute must be rejected");
|
|
}
|
|
|
|
void CheckSetter(SetU32 set, std::uint32_t largestValue) {
|
|
std::uint32_t option = 0;
|
|
Require(set(1, ChannelBoth, largestValue, nullptr) == ErrorNotConnected, "a setter must report NOT_CONNECTED");
|
|
Require(set(0, Channel0, 0, nullptr) == ErrorParam, "a setter must reject handle 0");
|
|
Require(set(1, 4, 0, nullptr) == ErrorParam, "a setter must reject channel 4");
|
|
Require(set(1, Channel0, 0, &option) == ErrorParam, "a setter must reject an option");
|
|
if (largestValue != UINT32_MAX) Require(set(1, Channel0, largestValue + 1, nullptr) == ErrorParam, "a setter must reject a value past its range");
|
|
}
|
|
|
|
void CheckSetters() {
|
|
CheckSetter(sceCameraSetAutoWhiteBalance, UINT32_MAX);
|
|
CheckSetter(sceCameraSetContrast, UINT32_MAX);
|
|
CheckSetter(sceCameraSetSaturation, UINT32_MAX);
|
|
CheckSetter(sceCameraSetDefectivePixelCancellation, 1);
|
|
CheckSetter(sceCameraSetDefectivePixelCancellationInternal, 2);
|
|
CheckSetter(sceCameraSetLensCorrection, 1);
|
|
CheckSetter(sceCameraSetLensCorrectionInternal, 2);
|
|
CheckSetter(sceCameraSetSharpness, 10);
|
|
Require(sceCameraSetHue(1, Channel0, -5, nullptr) == ErrorNotConnected, "a hue change must report NOT_CONNECTED");
|
|
const CameraExposureGain exposure{};
|
|
const CameraWhiteBalance balance{};
|
|
const CameraGamma gamma{};
|
|
Require(sceCameraSetExposureGain(1, Channel0, &exposure, nullptr) == ErrorNotConnected, "an exposure change must report NOT_CONNECTED");
|
|
Require(sceCameraSetWhiteBalance(1, Channel0, &balance, nullptr) == ErrorNotConnected, "a white balance change must report NOT_CONNECTED");
|
|
Require(sceCameraSetGamma(1, Channel0, &gamma, nullptr) == ErrorNotConnected, "a gamma change must report NOT_CONNECTED");
|
|
Require(sceCameraSetExposureGain(1, Channel0, nullptr, nullptr) == ErrorParam, "a null exposure must be rejected");
|
|
Require(sceCameraSetWhiteBalance(1, Channel0, nullptr, nullptr) == ErrorParam, "a null white balance must be rejected");
|
|
Require(sceCameraSetGamma(1, Channel0, nullptr, nullptr) == ErrorParam, "a null gamma must be rejected");
|
|
CameraAutoExposureGainTarget target{sizeof(CameraAutoExposureGainTarget), 0x20};
|
|
Require(sceCameraSetAutoExposureGain(1, Channel0, 1, &target) == ErrorNotConnected, "the largest exposure target must be accepted");
|
|
Require(sceCameraSetAutoExposureGain(1, Channel0, 1, nullptr) == ErrorNotConnected, "automatic exposure without a target must be accepted");
|
|
for (const std::uint32_t accepted : {0x0u, 0x2u, 0x4u, 0x6u, 0x8u, 0x10u, 0x12u, 0x14u, 0x16u, 0x20u}) {
|
|
target.target = accepted;
|
|
Require(sceCameraSetAutoExposureGain(1, Channel0, 1, &target) == ErrorNotConnected, "a listed exposure target must be accepted");
|
|
}
|
|
for (const std::uint32_t refused : {0x1u, 0xAu, 0xCu, 0xEu, 0x11u, 0x18u, 0x1Au, 0x1Cu, 0x1Eu, 0x22u}) {
|
|
target.target = refused;
|
|
Require(sceCameraSetAutoExposureGain(1, Channel0, 1, &target) == ErrorParam, "an unlisted exposure target must be rejected");
|
|
}
|
|
target = {4, 0x10};
|
|
Require(sceCameraSetAutoExposureGain(1, Channel0, 1, &target) == ErrorParam, "an exposure target of the wrong size must be rejected");
|
|
}
|
|
|
|
void CheckConfig() {
|
|
CameraConfig config = SizedConfig();
|
|
Require(sceCameraGetConfig(1, &config) == 0 && config.configType == 1, "the configuration must be type 1");
|
|
for (const CameraConfigExtension& extension : config.extension) {
|
|
Require(extension.formatLevel[0] == 0 && extension.formatLevel[1] == 4 && extension.formatLevel[3] == 4, "the default formats are wrong");
|
|
Require(extension.resolution == 0 && extension.framerate == 60 && extension.width == 0 && extension.baseOption == nullptr, "the default mode is wrong");
|
|
}
|
|
Require(sceCameraSetConfig(1, &config) == ErrorNotConnected, "a new configuration must report NOT_CONNECTED");
|
|
Require(sceCameraSetConfigInternal(1, &config) == ErrorNotConnected, "an internal configuration must report NOT_CONNECTED");
|
|
config = SizedConfig();
|
|
Require(sceCameraGetDeviceConfig(1, &config) == 0 && config.sizeThis == sizeof(CameraConfig) && config.configType == 0, "the device configuration must be empty");
|
|
Require(config.extension[1].baseOption == nullptr, "the device configuration must be cleared");
|
|
config = SizedConfig();
|
|
Require(sceCameraGetDeviceConfigWithoutHandle(&config) == 0 && config.sizeThis == 0 && config.configType == 0, "the handleless device configuration must be cleared");
|
|
config = SizedConfig();
|
|
config.sizeThis = 96;
|
|
Require(sceCameraGetConfig(1, &config) == ErrorParam && sceCameraSetConfig(1, &config) == ErrorParam, "a configuration of the wrong size must be rejected");
|
|
Require(sceCameraGetDeviceConfig(1, &config) == ErrorParam && sceCameraGetDeviceConfigWithoutHandle(&config) == ErrorParam, "a device configuration of the wrong size must be rejected");
|
|
Require(sceCameraGetConfig(0, nullptr) == ErrorParam && sceCameraSetConfigInternal(1, nullptr) == ErrorParam, "a missing configuration must be rejected");
|
|
}
|
|
|
|
void CheckDevice() {
|
|
CameraDeviceInfo info{sizeof(CameraDeviceInfo), 1, 0, 0};
|
|
std::array<std::uint8_t, 64> out{};
|
|
Require(sceCameraGetDeviceInfo(0, &info) == ErrorNotConnected, "device info must report NOT_CONNECTED");
|
|
Require(sceCameraGetDeviceInfo(1, &info) == ErrorParam, "a reserved value other than 0 must be rejected");
|
|
info.infoRevision = 2;
|
|
Require(sceCameraGetDeviceInfo(0, &info) == ErrorParam, "an unknown info revision must be rejected");
|
|
Require(sceCameraGetDeviceInfo(0, nullptr) == ErrorParam, "null device info must be rejected");
|
|
Require(sceCameraGetProductInfo(out.data()) == ErrorNotConnected && sceCameraGetRegistryInfo(out.data()) == ErrorNotConnected, "product and registry info must report NOT_CONNECTED");
|
|
Require(sceCameraGetProductInfo(nullptr) == ErrorParam && sceCameraGetRegistryInfo(nullptr) == ErrorParam, "null product or registry info must be rejected");
|
|
std::uint32_t count = 9;
|
|
Require(sceCameraGetMmapConnectedCount(&count) == 0 && count == 0, "no camera may be mapped");
|
|
Require(sceCameraGetMmapConnectedCount(nullptr) == ErrorParam, "a null count must be rejected");
|
|
Require(sceCameraGetCalibDataFromDevice() == ErrorNotConnected, "device calibration must report NOT_CONNECTED");
|
|
CameraGetCalibrationDataParameter param{sizeof(CameraGetCalibrationDataParameter), 0, 1};
|
|
Require(sceCameraGetCalibrationData(¶m, out.data()) == ErrorNotConnected, "calibration data must report NOT_CONNECTED");
|
|
Require(sceCameraGetCalibrationData(¶m, nullptr) == ErrorParam && sceCameraGetCalibrationData(nullptr, out.data()) == ErrorParam, "missing calibration arguments must be rejected");
|
|
for (const CameraGetCalibrationDataParameter refused : {CameraGetCalibrationDataParameter{8, 0, 0}, CameraGetCalibrationDataParameter{12, 1, 0}, CameraGetCalibrationDataParameter{12, 0, 2}}) {
|
|
Require(sceCameraGetCalibrationData(&refused, out.data()) == ErrorParam, "a bad calibration request must be rejected");
|
|
}
|
|
Require(sceCameraAudioOpen() == ErrorFatal, "camera audio must fail with FATAL");
|
|
}
|
|
|
|
}
|
|
|
|
int main() {
|
|
CheckBeforeOpen();
|
|
Require(sceCameraOpen(0xFF, 0, 0, nullptr) == 1, "the camera must open");
|
|
CheckGetters();
|
|
CheckAttribute();
|
|
CheckSetters();
|
|
CheckConfig();
|
|
CheckDevice();
|
|
Require(sceCameraClose(1) == 0, "the camera must close");
|
|
std::uint32_t value = 0;
|
|
Require(sceCameraGetSharpness(1, Channel0, &value, nullptr) == ErrorNotOpen, "a getter after close must report NOT_OPEN");
|
|
return 0;
|
|
}
|