From e9c393b8767aa0656359ffe5df43777d47ed31b2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 27 Jul 2017 17:35:18 -0700 Subject: [PATCH] PSP2: Support camera --- src/platform/psp2/CMakeLists.txt | 2 +- src/platform/psp2/main.c | 14 +++- src/platform/psp2/psp2-context.c | 109 +++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 2 deletions(-) diff --git a/src/platform/psp2/CMakeLists.txt b/src/platform/psp2/CMakeLists.txt index 8c127f735..eb8f31d75 100644 --- a/src/platform/psp2/CMakeLists.txt +++ b/src/platform/psp2/CMakeLists.txt @@ -13,7 +13,7 @@ source_group("PS Vita-specific code" FILES ${OS_SRC}) list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sce-vfs.c) set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) -set(OS_LIB -lvita2d -lSceAppMgr_stub -lSceCtrl_stub -lScePgf_stub -lSceGxm_stub -lSceDisplay_stub -lSceAudio_stub -lSceCommonDialog_stub -lSceMotion_stub -lScePhotoExport_stub -lScePower_stub -lSceSysmodule_stub -lSceTouch_stub -l${M_LIBRARY}) +set(OS_LIB -lvita2d -lSceAppMgr_stub -lSceCtrl_stub -lSceAudio_stub -lSceCamera_stub -lSceCommonDialog_stub -lSceDisplay_stub -lSceGxm_stub -lSceMotion_stub -lScePgf_stub -lScePhotoExport_stub -lScePower_stub -lSceSysmodule_stub -lSceTouch_stub -l${M_LIBRARY}) set(OBJCOPY_CMD ${OBJCOPY} -I binary -O elf32-littlearm -B arm) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index d41ae49c6..40068e700 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -105,6 +105,18 @@ int main() { "Fit Aspect Ratio", }, .nStates = 4 + }, + { + .title = "Camera", + .data = "camera", + .submenu = 0, + .state = 1, + .validStates = (const char*[]) { + "None", + "Front", + "Back", + }, + .nStates = 3 } }, .keySources = (struct GUIInputKeys[]) { @@ -133,7 +145,7 @@ int main() { }, { .id = 0 } }, - .nConfigExtra = 1, + .nConfigExtra = 2, .setup = mPSP2Setup, .teardown = mPSP2Teardown, .gameLoaded = mPSP2LoadROM, diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index b2bef2bae..278c7419d 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #define RUMBLE_PWM 8 +#define CDRAM_ALIGN 0x40000 static enum ScreenMode { SM_BACKDROP, @@ -49,15 +51,26 @@ static void* outputBuffer; static vita2d_texture* tex; static vita2d_texture* screenshot; static Thread audioThread; + static struct mSceRotationSource { struct mRotationSource d; struct SceMotionSensorState state; } rotation; + static struct mSceRumble { struct mRumble d; struct CircleBuffer history; int current; } rumble; + +static struct mSceImageSource { + struct mImageSource d; + SceUID memblock; + void* buffer; + unsigned cam; + size_t bufferOffset; +} camera; + bool frameLimiter = true; extern const uint8_t _binary_backdrop_png_start[]; @@ -143,6 +156,79 @@ static void _setRumble(struct mRumble* source, int enable) { sceCtrlSetActuator(1, &state); } +static void _resetCamera(struct mSceImageSource* imageSource) { + if (!imageSource->cam) { + return; + } + + sceCameraOpen(imageSource->cam - 1, &(SceCameraInfo) { + .size = sizeof(SceCameraInfo), + .format = 5, // SCE_CAMERA_FORMAT_ABGR + .resolution = SCE_CAMERA_RESOLUTION_176_144, + .framerate = SCE_CAMERA_FRAMERATE_30_FPS, + .sizeIBase = 176 * 144 * 4, + .pitch = 0, + .pIBase = imageSource->buffer, + }); + sceCameraStart(imageSource->cam - 1); +} + +static void _startRequestImage(struct mImageSource* source, unsigned w, unsigned h, int colorFormats) { + UNUSED(colorFormats); + struct mSceImageSource* imageSource = (struct mSceImageSource*) source; + + if (!imageSource->buffer) { + imageSource->memblock = sceKernelAllocMemBlock("camera", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, CDRAM_ALIGN, NULL); + sceKernelGetMemBlockBase(imageSource->memblock, &imageSource->buffer); + } + + if (!imageSource->cam) { + return; + } + + _resetCamera(imageSource); + imageSource->bufferOffset = (176 - w) / 2 + (144 - h) * 176 / 2; + + SceCameraRead read = { + sizeof(SceCameraRead), + 1 + }; + sceCameraRead(imageSource->cam - 1, &read); +} + +static void _stopRequestImage(struct mImageSource* source) { + struct mSceImageSource* imageSource = (struct mSceImageSource*) source; + if (imageSource->cam) { + sceCameraStop(imageSource->cam - 1); + sceCameraClose(imageSource->cam - 1); + } + sceKernelFreeMemBlock(imageSource->memblock); + imageSource->buffer = NULL; +} + + +static void _requestImage(struct mImageSource* source, const void** buffer, size_t* stride, enum mColorFormat* colorFormat) { + struct mSceImageSource* imageSource = (struct mSceImageSource*) source; + + if (!imageSource->cam) { + memset(imageSource->buffer, 0, 176 * 144 * 4); + *buffer = (uint32_t*) imageSource->buffer; + *stride = 176; + *colorFormat = mCOLOR_XBGR8; + return; + } + + *buffer = (uint32_t*) imageSource->buffer + imageSource->bufferOffset; + *stride = 176; + *colorFormat = mCOLOR_XBGR8; + + SceCameraRead read = { + sizeof(SceCameraRead), + 1 + }; + sceCameraRead(imageSource->cam - 1, &read); +} + uint16_t mPSP2PollInput(struct mGUIRunner* runner) { SceCtrlData pad; sceCtrlPeekBufferPositive(0, &pad, 1); @@ -210,6 +296,13 @@ void mPSP2Setup(struct mGUIRunner* runner) { CircleBufferInit(&rumble.history, RUMBLE_PWM); runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); + camera.d.startRequestImage = _startRequestImage; + camera.d.stopRequestImage = _stopRequestImage; + camera.d.requestImage = _requestImage; + camera.buffer = NULL; + camera.cam = 1; + runner->core->setPeripheral(runner->core, mPERIPH_IMAGE_SOURCE, &camera.d); + frameLimiter = true; backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start); @@ -217,6 +310,9 @@ void mPSP2Setup(struct mGUIRunner* runner) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; } + if (mCoreConfigGetUIntValue(&runner->config, "camera", &mode)) { + camera.cam = mode; + } } void mPSP2LoadROM(struct mGUIRunner* runner) { @@ -313,6 +409,19 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) { screenMode = mode; } + + if (mCoreConfigGetUIntValue(&runner->config, "camera", &mode)) { + if (mode != camera.cam) { + if (camera.buffer) { + sceCameraStop(camera.cam - 1); + sceCameraClose(camera.cam - 1); + } + camera.cam = mode; + if (camera.buffer) { + _resetCamera(&camera); + } + } + } } void mPSP2Teardown(struct mGUIRunner* runner) {