Skip to content

Commit

Permalink
Libretro: Add camera support
Browse files Browse the repository at this point in the history
  • Loading branch information
endrift committed Sep 10, 2018
1 parent 12c2ffb commit b03412a
Showing 1 changed file with 57 additions and 1 deletion.
58 changes: 57 additions & 1 deletion src/platform/libretro/libretro.c
Expand Up @@ -15,6 +15,7 @@
#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>
Expand Down Expand Up @@ -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;
Expand All @@ -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 = {
Expand Down Expand Up @@ -264,6 +275,10 @@ void retro_init(void) {
stream.postAudioFrame = 0;
stream.postAudioBuffer = _postAudioBuffer;
stream.postVideoFrame = 0;

imageSource.startRequestImage = _startImage;
imageSource.stopRequestImage = _stopImage;
imageSource.requestImage = _requestImage;
}

void retro_deinit(void) {
Expand Down Expand Up @@ -483,6 +498,14 @@ bool retro_load_game(const struct retro_game_info* game) {

#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;

Expand All @@ -504,7 +527,7 @@ bool retro_load_game(const struct retro_game_info* game) {
default:
biosName = "gb_bios.bin";
break;
};
}
}
#endif

Expand Down Expand Up @@ -740,3 +763,36 @@ static uint8_t _readLux(struct GBALuminanceSource* lux) {
}
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;
}

0 comments on commit b03412a

Please sign in to comment.