mirror of https://github.com/mgba-emu/mgba.git
PSP2: Support camera
This commit is contained in:
parent
22400e336f
commit
e9c393b876
|
@ -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)
|
list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sce-vfs.c)
|
||||||
set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE)
|
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)
|
set(OBJCOPY_CMD ${OBJCOPY} -I binary -O elf32-littlearm -B arm)
|
||||||
|
|
||||||
list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c)
|
list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c)
|
||||||
|
|
|
@ -105,6 +105,18 @@ int main() {
|
||||||
"Fit Aspect Ratio",
|
"Fit Aspect Ratio",
|
||||||
},
|
},
|
||||||
.nStates = 4
|
.nStates = 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.title = "Camera",
|
||||||
|
.data = "camera",
|
||||||
|
.submenu = 0,
|
||||||
|
.state = 1,
|
||||||
|
.validStates = (const char*[]) {
|
||||||
|
"None",
|
||||||
|
"Front",
|
||||||
|
"Back",
|
||||||
|
},
|
||||||
|
.nStates = 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.keySources = (struct GUIInputKeys[]) {
|
.keySources = (struct GUIInputKeys[]) {
|
||||||
|
@ -133,7 +145,7 @@ int main() {
|
||||||
},
|
},
|
||||||
{ .id = 0 }
|
{ .id = 0 }
|
||||||
},
|
},
|
||||||
.nConfigExtra = 1,
|
.nConfigExtra = 2,
|
||||||
.setup = mPSP2Setup,
|
.setup = mPSP2Setup,
|
||||||
.teardown = mPSP2Teardown,
|
.teardown = mPSP2Teardown,
|
||||||
.gameLoaded = mPSP2LoadROM,
|
.gameLoaded = mPSP2LoadROM,
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <mgba-util/platform/psp2/sce-vfs.h>
|
#include <mgba-util/platform/psp2/sce-vfs.h>
|
||||||
|
|
||||||
#include <psp2/audioout.h>
|
#include <psp2/audioout.h>
|
||||||
|
#include <psp2/camera.h>
|
||||||
#include <psp2/ctrl.h>
|
#include <psp2/ctrl.h>
|
||||||
#include <psp2/display.h>
|
#include <psp2/display.h>
|
||||||
#include <psp2/gxm.h>
|
#include <psp2/gxm.h>
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
#include <vita2d.h>
|
#include <vita2d.h>
|
||||||
|
|
||||||
#define RUMBLE_PWM 8
|
#define RUMBLE_PWM 8
|
||||||
|
#define CDRAM_ALIGN 0x40000
|
||||||
|
|
||||||
static enum ScreenMode {
|
static enum ScreenMode {
|
||||||
SM_BACKDROP,
|
SM_BACKDROP,
|
||||||
|
@ -49,15 +51,26 @@ static void* outputBuffer;
|
||||||
static vita2d_texture* tex;
|
static vita2d_texture* tex;
|
||||||
static vita2d_texture* screenshot;
|
static vita2d_texture* screenshot;
|
||||||
static Thread audioThread;
|
static Thread audioThread;
|
||||||
|
|
||||||
static struct mSceRotationSource {
|
static struct mSceRotationSource {
|
||||||
struct mRotationSource d;
|
struct mRotationSource d;
|
||||||
struct SceMotionSensorState state;
|
struct SceMotionSensorState state;
|
||||||
} rotation;
|
} rotation;
|
||||||
|
|
||||||
static struct mSceRumble {
|
static struct mSceRumble {
|
||||||
struct mRumble d;
|
struct mRumble d;
|
||||||
struct CircleBuffer history;
|
struct CircleBuffer history;
|
||||||
int current;
|
int current;
|
||||||
} rumble;
|
} rumble;
|
||||||
|
|
||||||
|
static struct mSceImageSource {
|
||||||
|
struct mImageSource d;
|
||||||
|
SceUID memblock;
|
||||||
|
void* buffer;
|
||||||
|
unsigned cam;
|
||||||
|
size_t bufferOffset;
|
||||||
|
} camera;
|
||||||
|
|
||||||
bool frameLimiter = true;
|
bool frameLimiter = true;
|
||||||
|
|
||||||
extern const uint8_t _binary_backdrop_png_start[];
|
extern const uint8_t _binary_backdrop_png_start[];
|
||||||
|
@ -143,6 +156,79 @@ static void _setRumble(struct mRumble* source, int enable) {
|
||||||
sceCtrlSetActuator(1, &state);
|
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) {
|
uint16_t mPSP2PollInput(struct mGUIRunner* runner) {
|
||||||
SceCtrlData pad;
|
SceCtrlData pad;
|
||||||
sceCtrlPeekBufferPositive(0, &pad, 1);
|
sceCtrlPeekBufferPositive(0, &pad, 1);
|
||||||
|
@ -210,6 +296,13 @@ void mPSP2Setup(struct mGUIRunner* runner) {
|
||||||
CircleBufferInit(&rumble.history, RUMBLE_PWM);
|
CircleBufferInit(&rumble.history, RUMBLE_PWM);
|
||||||
runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d);
|
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;
|
frameLimiter = true;
|
||||||
backdrop = vita2d_load_PNG_buffer(_binary_backdrop_png_start);
|
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) {
|
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) {
|
||||||
screenMode = mode;
|
screenMode = mode;
|
||||||
}
|
}
|
||||||
|
if (mCoreConfigGetUIntValue(&runner->config, "camera", &mode)) {
|
||||||
|
camera.cam = mode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mPSP2LoadROM(struct mGUIRunner* runner) {
|
void mPSP2LoadROM(struct mGUIRunner* runner) {
|
||||||
|
@ -313,6 +409,19 @@ void mPSP2Unpaused(struct mGUIRunner* runner) {
|
||||||
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) {
|
if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode != screenMode) {
|
||||||
screenMode = mode;
|
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) {
|
void mPSP2Teardown(struct mGUIRunner* runner) {
|
||||||
|
|
Loading…
Reference in New Issue