// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/elf_info.h" #include "common/logging/log.h" #include "core/emulator_settings.h" #include "core/libraries/camera/camera.h" #include "core/libraries/camera/camera_error.h" #include "core/libraries/error_codes.h" #include "core/libraries/kernel/process.h" #include "core/libraries/libs.h" #include #include #include "SDL3/SDL_camera.h" namespace Libraries::Camera { static bool g_library_opened = false; static s32 g_firmware_version = 0; static s32 g_handles = 0; static constexpr s32 c_width = 1280, c_height = 800; SDL_Camera* sdl_camera = nullptr; OrbisCameraConfigExtention output_config0, output_config1; s32 PS4_SYSV_ABI sceCameraAccGetData() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraAudioClose() { LOG_DEBUG(Lib_Camera, "called"); // Returns ORBIS_OK while internally failing return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraAudioGetData(void* data) { LOG_DEBUG(Lib_Camera, "called"); if (data == nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } // Returns ORBIS_OK while internally failing return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraAudioGetData2(void* data) { LOG_DEBUG(Lib_Camera, "called"); if (data == nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } // Returns ORBIS_OK while internally failing return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraAudioOpen() { LOG_DEBUG(Lib_Camera, "called"); // Returns error fatal as a side effect of not having a camera attached. return ORBIS_CAMERA_ERROR_FATAL; } s32 PS4_SYSV_ABI sceCameraAudioReset() { LOG_DEBUG(Lib_Camera, "called"); // Returns ORBIS_OK while internally failing return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraChangeAppModuleState() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraClose(s32 handle) { LOG_INFO(Lib_Camera, "called, handle: {}", handle); if (handle < 1) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } // Decrement handles on close. // If no handles remain, then the library itself is considered closed. if (--g_handles == 0) { g_library_opened = false; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraCloseByHandle(s32 handle) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } // Decrement handles on close. // If no handles remain, then the library itself is considered closed. if (--g_handles == 0) { g_library_opened = false; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraDeviceOpen() { // Stubbed on real hardware return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetAttribute(s32 handle, OrbisCameraAttribute* attribute) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || attribute == nullptr || attribute->sizeThis != sizeof(OrbisCameraAttribute) || attribute->channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || attribute->channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } auto channel = attribute->channel; // Set default attributes memset(attribute, 0, sizeof(OrbisCameraAttribute)); attribute->sizeThis = sizeof(OrbisCameraAttribute); attribute->channel = channel; attribute->exposureGain.exposure = 83; attribute->exposureGain.gain = 100; attribute->whiteBalance.gainRed = 768; attribute->whiteBalance.gainBlue = 768; attribute->whiteBalance.gainGreen = 512; attribute->gamma.value = 4; attribute->saturation = 64; attribute->contrast = 32; attribute->sharpness = 1; attribute->hue = 1; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetAutoExposureGain(s32 handle, OrbisCameraChannel channel, u32* enable, OrbisCameraAutoExposureGainTarget* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable == nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (option != nullptr && (g_firmware_version < Common::ElfInfo::FW_300 || option->sizeThis != sizeof(OrbisCameraAutoExposureGainTarget))) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *enable = 0; if (option != nullptr) { option->sizeThis = 0; option->target = OrbisCameraAecAgcTarget::ORBIS_CAMERA_ATTRIBUTE_AECAGC_TARGET_DEF; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetAutoWhiteBalance(s32 handle, OrbisCameraChannel channel, u32* enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *enable = 0; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetCalibData() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraGetCalibDataFromDevice() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraGetCalibrationData(const OrbisCameraGetCalibrationDataParameter* param, OrbisCameraCalibrationData* calibration_data) { LOG_DEBUG(Lib_Camera, "called"); if (param == nullptr || calibration_data == nullptr || param->size != sizeof(OrbisCameraGetCalibrationDataParameter) || param->format_type != 0 || param->function_type < OrbisCameraCalibrationDataFunctionType:: ORBIS_CAMERA_CALIBRATION_DATA_FUNCTION_TYPE_IMAGE_RECTIFICATION || param->function_type > OrbisCameraCalibrationDataFunctionType:: ORBIS_CAMERA_CALIBRATION_DATA_FUNCTION_TYPE_IMAGE_INVERSE_RECTIFICATION) { return ORBIS_CAMERA_ERROR_PARAM; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraGetConfig(s32 handle, OrbisCameraConfig* config) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || config == nullptr || config->sizeThis != sizeof(OrbisCameraConfig)) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } // Set default config config->configType = ORBIS_CAMERA_CONFIG_TYPE1; config->sizeThis = 0; OrbisCameraConfigExtention default_extension; default_extension.format.formatLevel0 = ORBIS_CAMERA_FORMAT_YUV422; default_extension.format.formatLevel1 = ORBIS_CAMERA_SCALE_FORMAT_Y8; default_extension.format.formatLevel2 = ORBIS_CAMERA_SCALE_FORMAT_Y8; default_extension.format.formatLevel3 = ORBIS_CAMERA_SCALE_FORMAT_Y8; default_extension.resolution = ORBIS_CAMERA_RESOLUTION_1280X800; default_extension.framerate = ORBIS_CAMERA_FRAMERATE_60; default_extension.width = 0; default_extension.height = 0; default_extension.reserved1 = 0; memcpy(&config->configExtention[0], &default_extension, sizeof(OrbisCameraConfigExtention)); memcpy(&config->configExtention[1], &default_extension, sizeof(OrbisCameraConfigExtention)); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetContrast(s32 handle, OrbisCameraChannel channel, u32* contrast, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || contrast == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *contrast = 32; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetDefectivePixelCancellation(s32 handle, OrbisCameraChannel channel, u32* enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *enable = 0; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetDeviceConfig(s32 handle, OrbisCameraConfig* config) { if (handle < 1 || config == nullptr || config->sizeThis != sizeof(OrbisCameraConfig)) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } memset(config, 0, sizeof(OrbisCameraConfig)); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetDeviceConfigWithoutHandle(OrbisCameraConfig* config) { if (config == nullptr || config->sizeThis != sizeof(OrbisCameraConfig)) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } memset(config, 0, sizeof(OrbisCameraConfig)); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetDeviceID() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetDeviceIDWithoutOpen() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetDeviceInfo(s32 reserved, OrbisCameraDeviceInfo* device_info) { LOG_DEBUG(Lib_Camera, "called"); if (reserved != 0 || device_info == nullptr || device_info->sizeThis != sizeof(OrbisCameraDeviceInfo) || device_info->infoRevision != 1) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_INIT; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraGetExposureGain(s32 handle, OrbisCameraChannel channel, OrbisCameraExposureGain* exposure_gain, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || exposure_gain == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } // Return default parameters exposure_gain->exposureControl = 0; exposure_gain->exposure = 20; exposure_gain->gain = 100; exposure_gain->mode = 0; return ORBIS_OK; } static std::vector raw16_buffer1, raw16_buffer2; static std::vector raw8_buffer1, raw8_buffer2; static void ConvertRGBA8888ToRAW16(const u8* src, u16* dst, int width, int height) { for (int y = 0; y < height; ++y) { const u8* row = src + y * width * 4; u16* outRow = dst + y * width; for (int x = 0; x < width; ++x) { const u8* px = row + x * 4; u16 b = u16(px[1]) << 4; u16 g = u16(px[2]) << 4; u16 r = u16(px[3]) << 4; // BGGR Bayer layout // B G // G R bool evenRow = (y & 1) == 0; bool evenCol = (x & 1) == 0; if (evenRow && evenCol) { outRow[x] = b; } else if (evenRow && !evenCol) { outRow[x] = g; } else if (!evenRow && evenCol) { outRow[x] = g; } else { outRow[x] = r; } } } } static void ConvertRGBA8888ToRAW8(const u8* src, u8* dst, int width, int height) { for (int y = 0; y < height; ++y) { const u8* row = src + y * width * 4; u8* outRow = dst + y * width; for (int x = 0; x < width; ++x) { const u8* px = row + x * 4; u8 b = px[1]; u8 g = px[2]; u8 r = px[3]; // BGGR Bayer layout // B G // G R bool evenRow = (y & 1) == 0; bool evenCol = (x & 1) == 0; if (evenRow && evenCol) { outRow[x] = b; } else if (evenRow && !evenCol) { outRow[x] = g; } else if (!evenRow && evenCol) { outRow[x] = g; } else { outRow[x] = r; } } } } s32 PS4_SYSV_ABI sceCameraGetFrameData(s32 handle, OrbisCameraFrameData* frame_data) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || frame_data == nullptr || frame_data->sizeThis > 584) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened || !sdl_camera) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } if (EmulatorSettings.GetCameraId() == -1) { return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } Uint64 timestampNS = 0; static SDL_Surface* frame = nullptr; if (frame) { // release previous frame, if it exists SDL_ReleaseCameraFrame(sdl_camera, frame); } frame = SDL_AcquireCameraFrame(sdl_camera, ×tampNS); if (!frame) { return ORBIS_CAMERA_ERROR_BUSY; } switch (output_config0.format.formatLevel0) { case ORBIS_CAMERA_FORMAT_YUV422: frame_data->pFramePointerList[0][0] = frame->pixels; break; case ORBIS_CAMERA_FORMAT_RAW16: ConvertRGBA8888ToRAW16((u8*)frame->pixels, raw16_buffer1.data(), c_width, c_height); frame_data->pFramePointerList[0][0] = raw16_buffer1.data(); break; case ORBIS_CAMERA_FORMAT_RAW8: ConvertRGBA8888ToRAW8((u8*)frame->pixels, raw8_buffer1.data(), c_width, c_height); frame_data->pFramePointerList[0][0] = raw8_buffer1.data(); break; default: UNREACHABLE(); } switch (output_config1.format.formatLevel0) { case ORBIS_CAMERA_FORMAT_YUV422: frame_data->pFramePointerList[1][0] = frame->pixels; break; case ORBIS_CAMERA_FORMAT_RAW16: ConvertRGBA8888ToRAW16((u8*)frame->pixels, raw16_buffer2.data(), c_width, c_height); frame_data->pFramePointerList[1][0] = raw16_buffer2.data(); break; case ORBIS_CAMERA_FORMAT_RAW8: ConvertRGBA8888ToRAW8((u8*)frame->pixels, raw8_buffer2.data(), c_width, c_height); frame_data->pFramePointerList[1][0] = raw8_buffer2.data(); break; default: UNREACHABLE(); } frame_data->meta.format[0][0] = output_config0.format.formatLevel0; frame_data->meta.format[1][0] = output_config1.format.formatLevel0; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetGamma(s32 handle, OrbisCameraChannel channel, OrbisCameraGamma* gamma, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || gamma == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } // Return default parameters memset(gamma, 0, sizeof(OrbisCameraGamma)); gamma->value = 4; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetHue(s32 handle, OrbisCameraChannel channel, s32* hue, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || hue == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *hue = 1; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetLensCorrection(s32 handle, OrbisCameraChannel channel, u32* enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *enable = 0; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetMmapConnectedCount(u32* count) { LOG_ERROR(Lib_Camera, "(STUBBED) called"); if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } if (count == nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } *count = 0; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetProductInfo(void* product_info) { LOG_DEBUG(Lib_Camera, "(STUBBED) called"); if (product_info == nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_INIT; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraGetRegister() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetRegistryInfo(void* registry_info) { LOG_DEBUG(Lib_Camera, "(STUBBED) called"); if (registry_info == nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_INIT; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraGetSaturation(s32 handle, OrbisCameraChannel channel, u32* saturation, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || saturation == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *saturation = 64; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetSharpness(s32 handle, OrbisCameraChannel channel, u32* sharpness, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || sharpness == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } *sharpness = 1; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetVrCaptureInfo() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraGetWhiteBalance(s32 handle, OrbisCameraChannel channel, OrbisCameraWhiteBalance* white_balance, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel >= OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || white_balance == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } // Set default parameters white_balance->whiteBalanceControl = 0; white_balance->gainRed = 768; white_balance->gainBlue = 768; white_balance->gainGreen = 512; return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraInitializeRegistryCalibData() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_INIT; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraIsAttached(s32 index) { static bool first_log = true; if (first_log) { LOG_INFO(Lib_Camera, "called"); first_log = false; } else { LOG_DEBUG(Lib_Camera, "called"); } if (index != 0) { return ORBIS_CAMERA_ERROR_PARAM; } // 0 = disconnected, 1 = connected return EmulatorSettings.GetCameraId() == -1 ? 0 : 1; } s32 PS4_SYSV_ABI sceCameraIsConfigChangeDone() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraIsValidFrameData(s32 handle, OrbisCameraFrameData* frame_data) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || frame_data == nullptr || frame_data->sizeThis > 584) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return 1; // valid } s32 PS4_SYSV_ABI sceCameraOpen(Libraries::UserService::OrbisUserServiceUserId user_id, s32 type, s32 index, OrbisCameraOpenParameter* param) { LOG_INFO(Lib_Camera, "called"); if (user_id != Libraries::UserService::ORBIS_USER_SERVICE_USER_ID_SYSTEM || type != 0 || index != 0) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_PARAM"); return ORBIS_CAMERA_ERROR_PARAM; } g_library_opened = true; return ++g_handles; } s32 PS4_SYSV_ABI sceCameraOpenByModuleId() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraRemoveAppModuleFocus() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetAppModuleFocus() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetAttribute(s32 handle, OrbisCameraAttribute* attribute) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || attribute == nullptr || attribute->sizeThis != sizeof(OrbisCameraAttribute) || attribute->channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || attribute->channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetAttributeInternal() { // Stubbed on real hardware return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetAutoExposureGain(s32 handle, OrbisCameraChannel channel, u32 enable, OrbisCameraAutoExposureGainTarget* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0) { return ORBIS_CAMERA_ERROR_PARAM; } if (option != nullptr) { if (g_firmware_version < Common::ElfInfo::FW_300 || option->sizeThis != sizeof(OrbisCameraAutoExposureGainTarget)) { return ORBIS_CAMERA_ERROR_PARAM; } if (option->target % 2 == 1 || option->target < ORBIS_CAMERA_ATTRIBUTE_AECAGC_TARGET_DEF || option->target > ORBIS_CAMERA_ATTRIBUTE_AECAGC_TARGET_2_0) { return ORBIS_CAMERA_ERROR_PARAM; } } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetAutoWhiteBalance(s32 handle, OrbisCameraChannel channel, u32 enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetCalibData() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetConfig(s32 handle, OrbisCameraConfig* config) { LOG_INFO(Lib_Camera, "called"); if (handle < 1 || config == nullptr || config->sizeThis != sizeof(OrbisCameraConfig)) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_PARAM"); return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_NOT_OPEN"); return ORBIS_CAMERA_ERROR_NOT_OPEN; } if (EmulatorSettings.GetCameraId() == -1) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_NOT_CONNECTED"); return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } switch (config->configType) { case ORBIS_CAMERA_CONFIG_TYPE1: case ORBIS_CAMERA_CONFIG_TYPE2: case ORBIS_CAMERA_CONFIG_TYPE3: case ORBIS_CAMERA_CONFIG_TYPE4: output_config0 = camera_config_types[config->configType - 1][0]; output_config1 = camera_config_types[config->configType - 1][1]; break; case ORBIS_CAMERA_CONFIG_TYPE5: int sdk_ver; Libraries::Kernel::sceKernelGetCompiledSdkVersion(&sdk_ver); if (sdk_ver < Common::ElfInfo::FW_450) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_UNKNOWN_CONFIG"); return ORBIS_CAMERA_ERROR_UNKNOWN_CONFIG; } output_config0 = camera_config_types[config->configType - 1][0]; output_config1 = camera_config_types[config->configType - 1][1]; break; case ORBIS_CAMERA_CONFIG_EXTENTION: output_config0 = config->configExtention[0]; output_config1 = config->configExtention[1]; break; default: LOG_ERROR(Lib_Camera, "Invalid config type {}", std::to_underlying(config->configType)); return ORBIS_CAMERA_ERROR_PARAM; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetConfigInternal(s32 handle, OrbisCameraConfig* config) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || config == nullptr || config->sizeThis != sizeof(OrbisCameraConfig)) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetContrast(s32 handle, OrbisCameraChannel channel, u32 contrast, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetDebugStop(u32 debug_stop_enable) { LOG_ERROR(Lib_Camera, "(STUBBED) called"); if (debug_stop_enable > 1) { return ORBIS_CAMERA_ERROR_PARAM; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetDefectivePixelCancellation(s32 handle, OrbisCameraChannel channel, u32 enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable > 1 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetDefectivePixelCancellationInternal(s32 handle, OrbisCameraChannel channel, u32 enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable > 2 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetExposureGain(s32 handle, OrbisCameraChannel channel, OrbisCameraExposureGain* exposure_gain, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || exposure_gain != nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetForceActivate() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetGamma(s32 handle, OrbisCameraChannel channel, OrbisCameraGamma* gamma, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || gamma != nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetHue(s32 handle, OrbisCameraChannel channel, s32 hue, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetLensCorrection(s32 handle, OrbisCameraChannel channel, u32 enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable > 1 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetLensCorrectionInternal(s32 handle, OrbisCameraChannel channel, u32 enable, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || enable > 2 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetProcessFocus() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetProcessFocusByHandle() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetRegister() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetSaturation(s32 handle, OrbisCameraChannel channel, u32 saturation, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetSharpness(s32 handle, OrbisCameraChannel channel, u32 sharpness, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (g_firmware_version >= Common::ElfInfo::FW_350 && sharpness > 10) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraSetTrackerMode() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetUacModeInternal() { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetVideoSync(s32 handle, OrbisCameraVideoSyncParameter* video_sync) { LOG_ERROR(Lib_Camera, "(STUBBED) called"); if (handle < 1 || video_sync == nullptr || video_sync->sizeThis != sizeof(OrbisCameraVideoSyncParameter) || video_sync->videoSyncMode > 1 || video_sync->pModeOption != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetVideoSyncInternal(s32 handle, OrbisCameraVideoSyncParameter* video_sync) { LOG_ERROR(Lib_Camera, "(STUBBED) called"); return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraSetWhiteBalance(s32 handle, OrbisCameraChannel channel, OrbisCameraWhiteBalance* white_balance, void* option) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || channel > OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_BOTH || channel < OrbisCameraChannel::ORBIS_CAMERA_CHANNEL_0 || white_balance == nullptr || option != nullptr) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } s32 PS4_SYSV_ABI sceCameraStart(s32 handle, OrbisCameraStartParameter* param) { LOG_INFO(Lib_Camera, "called"); if (handle < 1 || param == nullptr || param->sizeThis != sizeof(OrbisCameraStartParameter)) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_PARAM"); return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_NOT_OPEN"); return ORBIS_CAMERA_ERROR_NOT_OPEN; } if (g_firmware_version >= Common::ElfInfo::FW_250 && (param->formatLevel[0] > 0xf || param->formatLevel[1] > 0xf || (param->formatLevel[0] | param->formatLevel[1]) == 0)) { LOG_ERROR(Lib_Camera, "ORBIS_CAMERA_ERROR_FORMAT_UNKNOWN"); return ORBIS_CAMERA_ERROR_FORMAT_UNKNOWN; } if (param->formatLevel[0] > 1 || param->formatLevel[1] > 1) { LOG_ERROR(Lib_Camera, "Downscaled image retrieval isn't supported yet!"); } SDL_CameraID* devices = NULL; int devcount = 0; devices = SDL_GetCameras(&devcount); if (devices == NULL) { LOG_ERROR(Lib_Camera, "Couldn't enumerate camera devices: {}", SDL_GetError()); return ORBIS_CAMERA_ERROR_FATAL; } else if (devcount == 0) { LOG_INFO(Lib_Camera, "No camera devices connected"); return ORBIS_CAMERA_ERROR_NOT_CONNECTED; } raw8_buffer1.resize(c_width * c_height); raw16_buffer1.resize(c_width * c_height); raw8_buffer2.resize(c_width * c_height); raw16_buffer2.resize(c_width * c_height); SDL_CameraSpec cam_spec{}; switch (output_config0.format.formatLevel0) { case ORBIS_CAMERA_FORMAT_YUV422: cam_spec.format = SDL_PIXELFORMAT_YUY2; break; case ORBIS_CAMERA_FORMAT_RAW8: cam_spec.format = SDL_PIXELFORMAT_RGBA8888; // to be swizzled break; case ORBIS_CAMERA_FORMAT_RAW16: cam_spec.format = SDL_PIXELFORMAT_RGBA8888; // to be swizzled break; default: LOG_ERROR(Lib_Camera, "Invalid format {}", std::to_underlying(output_config0.format.formatLevel0)); break; } cam_spec.height = c_height; cam_spec.width = c_width; cam_spec.framerate_numerator = 60; cam_spec.framerate_denominator = 1; sdl_camera = SDL_OpenCamera(devices[EmulatorSettings.GetCameraId()], &cam_spec); LOG_INFO(Lib_Camera, "SDL backend in use: {}", SDL_GetCurrentCameraDriver()); char const* camera_name = SDL_GetCameraName(devices[EmulatorSettings.GetCameraId()]); if (camera_name) LOG_INFO(Lib_Camera, "SDL camera name: {}", camera_name); SDL_CameraSpec spec; SDL_GetCameraFormat(sdl_camera, &spec); LOG_INFO(Lib_Camera, "SDL camera format: {:#x}", std::to_underlying(spec.format)); LOG_INFO(Lib_Camera, "SDL camera framerate: {}", (float)spec.framerate_numerator / (float)spec.framerate_denominator); LOG_INFO(Lib_Camera, "SDL camera dimensions: {}x{}", spec.width, spec.height); SDL_free(devices); // "warm up" the device, as recommended by SDL u64 timestamp; SDL_Surface* frame = nullptr; frame = SDL_AcquireCameraFrame(sdl_camera, ×tamp); if (!frame) { for (int i = 0; i < 1000; i++) { frame = SDL_AcquireCameraFrame(sdl_camera, ×tamp); if (frame) { SDL_ReleaseCameraFrame(sdl_camera, frame); break; } std::this_thread::sleep_for(std::chrono::nanoseconds(10)); } } if (!sdl_camera) { LOG_ERROR(Lib_Camera, "Failed to open camera: {}", SDL_GetError()); return ORBIS_CAMERA_ERROR_FATAL; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraStartByHandle(s32 handle, OrbisCameraStartParameter* param) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1 || param == nullptr || param->sizeThis != sizeof(OrbisCameraStartParameter)) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraStop(s32 handle) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_OK; } s32 PS4_SYSV_ABI sceCameraStopByHandle(s32 handle) { LOG_DEBUG(Lib_Camera, "called"); if (handle < 1) { return ORBIS_CAMERA_ERROR_PARAM; } if (!g_library_opened) { return ORBIS_CAMERA_ERROR_NOT_OPEN; } return ORBIS_OK; } void RegisterLib(Core::Loader::SymbolsResolver* sym) { Libraries::Kernel::sceKernelGetCompiledSdkVersion(&g_firmware_version); LIB_FUNCTION("QhjrPkRPUZQ", "libSceCamera", 1, "libSceCamera", sceCameraAccGetData); LIB_FUNCTION("UFonL7xopFM", "libSceCamera", 1, "libSceCamera", sceCameraAudioClose); LIB_FUNCTION("fkZE7Hup2ro", "libSceCamera", 1, "libSceCamera", sceCameraAudioGetData); LIB_FUNCTION("hftC5A1C8OQ", "libSceCamera", 1, "libSceCamera", sceCameraAudioGetData2); LIB_FUNCTION("DhqqFiBU+6g", "libSceCamera", 1, "libSceCamera", sceCameraAudioOpen); LIB_FUNCTION("wyU98EXAYxU", "libSceCamera", 1, "libSceCamera", sceCameraAudioReset); LIB_FUNCTION("Y0pCDajzkVQ", "libSceCamera", 1, "libSceCamera", sceCameraChangeAppModuleState); LIB_FUNCTION("OMS9LlcrvBo", "libSceCamera", 1, "libSceCamera", sceCameraClose); LIB_FUNCTION("ztqH5qNTpTk", "libSceCamera", 1, "libSceCamera", sceCameraCloseByHandle); LIB_FUNCTION("nBH6i2s4Glc", "libSceCamera", 1, "libSceCamera", sceCameraDeviceOpen); LIB_FUNCTION("0btIPD5hg5A", "libSceCamera", 1, "libSceCamera", sceCameraGetAttribute); LIB_FUNCTION("oEi6vM-3E2c", "libSceCamera", 1, "libSceCamera", sceCameraGetAutoExposureGain); LIB_FUNCTION("qTPRMh4eY60", "libSceCamera", 1, "libSceCamera", sceCameraGetAutoWhiteBalance); LIB_FUNCTION("hHA1frlMxYE", "libSceCamera", 1, "libSceCamera", sceCameraGetCalibData); LIB_FUNCTION("5Oie5RArfWs", "libSceCamera", 1, "libSceCamera", sceCameraGetCalibDataFromDevice); LIB_FUNCTION("RHYJ7GKOSMg", "libSceCamera", 1, "libSceCamera", sceCameraGetCalibrationData); LIB_FUNCTION("ZaqmGEtYuL0", "libSceCamera", 1, "libSceCamera", sceCameraGetConfig); LIB_FUNCTION("a5xFueMZIMs", "libSceCamera", 1, "libSceCamera", sceCameraGetContrast); LIB_FUNCTION("tslCukqFE+E", "libSceCamera", 1, "libSceCamera", sceCameraGetDefectivePixelCancellation); LIB_FUNCTION("DSOLCrc3Kh8", "libSceCamera", 1, "libSceCamera", sceCameraGetDeviceConfig); LIB_FUNCTION("n+rFeP1XXyM", "libSceCamera", 1, "libSceCamera", sceCameraGetDeviceConfigWithoutHandle); LIB_FUNCTION("jTJCdyv9GLU", "libSceCamera", 1, "libSceCamera", sceCameraGetDeviceID); LIB_FUNCTION("-H3UwGQvNZI", "libSceCamera", 1, "libSceCamera", sceCameraGetDeviceIDWithoutOpen); LIB_FUNCTION("WZpxnSAM-ds", "libSceCamera", 1, "libSceCamera", sceCameraGetDeviceInfo); LIB_FUNCTION("ObIste7hqdk", "libSceCamera", 1, "libSceCamera", sceCameraGetExposureGain); LIB_FUNCTION("mxgMmR+1Kr0", "libSceCamera", 1, "libSceCamera", sceCameraGetFrameData); LIB_FUNCTION("WVox2rwGuSc", "libSceCamera", 1, "libSceCamera", sceCameraGetGamma); LIB_FUNCTION("zrIUDKZx0iE", "libSceCamera", 1, "libSceCamera", sceCameraGetHue); LIB_FUNCTION("XqYRHc4aw3w", "libSceCamera", 1, "libSceCamera", sceCameraGetLensCorrection); LIB_FUNCTION("B260o9pSzM8", "libSceCamera", 1, "libSceCamera", sceCameraGetMmapConnectedCount); LIB_FUNCTION("ULxbwqiYYuU", "libSceCamera", 1, "libSceCamera", sceCameraGetProductInfo); LIB_FUNCTION("olojYZKYiYs", "libSceCamera", 1, "libSceCamera", sceCameraGetRegister); LIB_FUNCTION("hawKak+Auw4", "libSceCamera", 1, "libSceCamera", sceCameraGetRegistryInfo); LIB_FUNCTION("RTDOsWWqdME", "libSceCamera", 1, "libSceCamera", sceCameraGetSaturation); LIB_FUNCTION("c6Fp9M1EXXc", "libSceCamera", 1, "libSceCamera", sceCameraGetSharpness); LIB_FUNCTION("IAz2HgZQWzE", "libSceCamera", 1, "libSceCamera", sceCameraGetVrCaptureInfo); LIB_FUNCTION("HX5524E5tMY", "libSceCamera", 1, "libSceCamera", sceCameraGetWhiteBalance); LIB_FUNCTION("0wnf2a60FqI", "libSceCamera", 1, "libSceCamera", sceCameraInitializeRegistryCalibData); LIB_FUNCTION("p6n3Npi3YY4", "libSceCamera", 1, "libSceCamera", sceCameraIsAttached); LIB_FUNCTION("wQfd7kfRZvo", "libSceCamera", 1, "libSceCamera", sceCameraIsConfigChangeDone); LIB_FUNCTION("U3BVwQl2R5Q", "libSceCamera", 1, "libSceCamera", sceCameraIsValidFrameData); LIB_FUNCTION("BHn83xrF92E", "libSceCamera", 1, "libSceCamera", sceCameraOpen); LIB_FUNCTION("eTywOSWsEiI", "libSceCamera", 1, "libSceCamera", sceCameraOpenByModuleId); LIB_FUNCTION("py8p6kZcHmA", "libSceCamera", 1, "libSceCamera", sceCameraRemoveAppModuleFocus); LIB_FUNCTION("j5isFVIlZLk", "libSceCamera", 1, "libSceCamera", sceCameraSetAppModuleFocus); LIB_FUNCTION("doPlf33ab-U", "libSceCamera", 1, "libSceCamera", sceCameraSetAttribute); LIB_FUNCTION("96F7zp1Xo+k", "libSceCamera", 1, "libSceCamera", sceCameraSetAttributeInternal); LIB_FUNCTION("yfSdswDaElo", "libSceCamera", 1, "libSceCamera", sceCameraSetAutoExposureGain); LIB_FUNCTION("zIKL4kZleuc", "libSceCamera", 1, "libSceCamera", sceCameraSetAutoWhiteBalance); LIB_FUNCTION("LEMk5cTHKEA", "libSceCamera", 1, "libSceCamera", sceCameraSetCalibData); LIB_FUNCTION("VQ+5kAqsE2Q", "libSceCamera", 1, "libSceCamera", sceCameraSetConfig); LIB_FUNCTION("9+SNhbctk64", "libSceCamera", 1, "libSceCamera", sceCameraSetConfigInternal); LIB_FUNCTION("3i5MEzrC1pg", "libSceCamera", 1, "libSceCamera", sceCameraSetContrast); LIB_FUNCTION("vejouEusC7g", "libSceCamera", 1, "libSceCamera", sceCameraSetDebugStop); LIB_FUNCTION("jMv40y2A23g", "libSceCamera", 1, "libSceCamera", sceCameraSetDefectivePixelCancellation); LIB_FUNCTION("vER3cIMBHqI", "libSceCamera", 1, "libSceCamera", sceCameraSetDefectivePixelCancellationInternal); LIB_FUNCTION("wgBMXJJA6K4", "libSceCamera", 1, "libSceCamera", sceCameraSetExposureGain); LIB_FUNCTION("jeTpU0MqKU0", "libSceCamera", 1, "libSceCamera", sceCameraSetForceActivate); LIB_FUNCTION("lhEIsHzB8r4", "libSceCamera", 1, "libSceCamera", sceCameraSetGamma); LIB_FUNCTION("QI8GVJUy2ZY", "libSceCamera", 1, "libSceCamera", sceCameraSetHue); LIB_FUNCTION("K7W7H4ZRwbc", "libSceCamera", 1, "libSceCamera", sceCameraSetLensCorrection); LIB_FUNCTION("eHa3vhGu2rQ", "libSceCamera", 1, "libSceCamera", sceCameraSetLensCorrectionInternal); LIB_FUNCTION("lS0tM6n+Q5E", "libSceCamera", 1, "libSceCamera", sceCameraSetProcessFocus); LIB_FUNCTION("NVITuK83Z7o", "libSceCamera", 1, "libSceCamera", sceCameraSetProcessFocusByHandle); LIB_FUNCTION("8MjO05qk5hA", "libSceCamera", 1, "libSceCamera", sceCameraSetRegister); LIB_FUNCTION("bSKEi2PzzXI", "libSceCamera", 1, "libSceCamera", sceCameraSetSaturation); LIB_FUNCTION("P-7MVfzvpsM", "libSceCamera", 1, "libSceCamera", sceCameraSetSharpness); LIB_FUNCTION("3VJOpzKoIeM", "libSceCamera", 1, "libSceCamera", sceCameraSetTrackerMode); LIB_FUNCTION("nnR7KAIDPv8", "libSceCamera", 1, "libSceCamera", sceCameraSetUacModeInternal); LIB_FUNCTION("wpeyFwJ+UEI", "libSceCamera", 1, "libSceCamera", sceCameraSetVideoSync); LIB_FUNCTION("8WtmqmE4edw", "libSceCamera", 1, "libSceCamera", sceCameraSetVideoSyncInternal); LIB_FUNCTION("k3zPIcgFNv0", "libSceCamera", 1, "libSceCamera", sceCameraSetWhiteBalance); LIB_FUNCTION("9EpRYMy7rHU", "libSceCamera", 1, "libSceCamera", sceCameraStart); LIB_FUNCTION("cLxF1QtHch0", "libSceCamera", 1, "libSceCamera", sceCameraStartByHandle); LIB_FUNCTION("2G2C0nmd++M", "libSceCamera", 1, "libSceCamera", sceCameraStop); LIB_FUNCTION("+X1Kgnn3bzg", "libSceCamera", 1, "libSceCamera", sceCameraStopByHandle); }; } // namespace Libraries::Camera