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)
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <mgba-util/platform/psp2/sce-vfs.h>
|
||||
|
||||
#include <psp2/audioout.h>
|
||||
#include <psp2/camera.h>
|
||||
#include <psp2/ctrl.h>
|
||||
#include <psp2/display.h>
|
||||
#include <psp2/gxm.h>
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include <vita2d.h>
|
||||
|
||||
#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) {
|
||||
|
|
Loading…
Reference in New Issue