all repos — mgba @ b03412aa38b39190f475cb89d5c8a2a5e97bc32d

mGBA Game Boy Advance Emulator

Libretro: Add camera support
Vicki Pfau vi@endrift.com
Sun, 09 Sep 2018 17:43:07 -0700
commit

b03412aa38b39190f475cb89d5c8a2a5e97bc32d

parent

12c2ffb0e273f18e78d12fb419883f59bd29232b

1 files changed, 57 insertions(+), 1 deletions(-)

jump to
M src/platform/libretro/libretro.csrc/platform/libretro/libretro.c

@@ -15,6 +15,7 @@ #include <mgba/core/version.h>

#ifdef M_CORE_GB #include <mgba/gb/core.h> #include <mgba/internal/gb/gb.h> +#include <mgba/internal/gb/mbc.h> #endif #ifdef M_CORE_GBA #include <mgba/gba/core.h>

@@ -42,6 +43,10 @@ static void _postAudioBuffer(struct mAVStream*, blip_t* left, blip_t* right);

static void _setRumble(struct mRumble* rumble, int enable); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); +static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned height, size_t pitch); +static void _startImage(struct mImageSource*, unsigned w, unsigned h, int colorFormats); +static void _stopImage(struct mImageSource*); +static void _requestImage(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat); static struct mCore* core; static void* outputBuffer;

@@ -55,6 +60,12 @@ static struct mRumble rumble;

static struct GBALuminanceSource lux; static int luxLevel; static struct mLogger logger; +static struct retro_camera_callback cam; +static struct mImageSource imageSource; +static uint32_t* camData = NULL; +static unsigned camWidth; +static unsigned camHeight; +static size_t camStride; static void _reloadSettings(void) { struct mCoreOptions opts = {

@@ -264,6 +275,10 @@ stream.videoDimensionsChanged = 0;

stream.postAudioFrame = 0; stream.postAudioBuffer = _postAudioBuffer; stream.postVideoFrame = 0; + + imageSource.startRequestImage = _startImage; + imageSource.stopRequestImage = _stopImage; + imageSource.requestImage = _requestImage; } void retro_deinit(void) {

@@ -483,6 +498,14 @@ #endif

#ifdef M_CORE_GB if (core->platform(core) == PLATFORM_GB) { + memset(&cam, 0, sizeof(cam)); + cam.height = GBCAM_HEIGHT; + cam.width = GBCAM_WIDTH; + cam.caps = 1 << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER; + cam.frame_raw_framebuffer = _updateCamera; + core->setPeripheral(core, mPERIPH_IMAGE_SOURCE, &imageSource); + + environCallback(RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE, &cam); const char* modelName = mCoreConfigGetValue(&core->config, "gb.model"); struct GB* gb = core->board;

@@ -504,7 +527,7 @@ case GB_MODEL_DMG:

default: biosName = "gb_bios.bin"; break; - }; + } } #endif

@@ -740,3 +763,36 @@ value += GBA_LUX_LEVELS[luxLevel - 1];

} return 0xFF - value; } + +static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned height, size_t pitch) { + if (!camData || width != camWidth || height != camHeight) { + camData = malloc(sizeof(*buffer) * height * pitch); + camWidth = width; + camHeight = height; + camStride = pitch / sizeof(*buffer); + } + memcpy(camData, buffer, sizeof(*buffer) * height * pitch); +} + +static void _startImage(struct mImageSource* image, unsigned w, unsigned h, int colorFormats) { + UNUSED(image); + UNUSED(colorFormats); + + camData = NULL; + cam.start(); +} + +static void _stopImage(struct mImageSource* image) { + UNUSED(image); + cam.stop(); +} + +static void _requestImage(struct mImageSource* image, const void** buffer, size_t* stride, enum mColorFormat* colorFormat) { + UNUSED(image); + if (!camData) { + cam.start(); + } + *buffer = camData; + *stride = camStride; + *colorFormat = mCOLOR_XRGB8; +}