mirror of https://github.com/mgba-emu/mgba.git
Core: Color formats
This commit is contained in:
parent
c7e65ff621
commit
e0f04a0d5a
|
@ -37,6 +37,29 @@ typedef uint32_t color_t;
|
|||
|
||||
struct blip_t;
|
||||
|
||||
enum mColorFormat {
|
||||
mCOLOR_XBGR8 = 0x00001,
|
||||
mCOLOR_XRGB8 = 0x00002,
|
||||
mCOLOR_BGRX8 = 0x00004,
|
||||
mCOLOR_RGBX8 = 0x00008,
|
||||
mCOLOR_ABGR8 = 0x00010,
|
||||
mCOLOR_ARGB8 = 0x00020,
|
||||
mCOLOR_BGRA8 = 0x00040,
|
||||
mCOLOR_RGBA8 = 0x00080,
|
||||
mCOLOR_RGB5 = 0x00100,
|
||||
mCOLOR_BGR5 = 0x00200,
|
||||
mCOLOR_RGB565 = 0x00400,
|
||||
mCOLOR_BGR565 = 0x00800,
|
||||
mCOLOR_ARGB5 = 0x01000,
|
||||
mCOLOR_ABGR5 = 0x02000,
|
||||
mCOLOR_RGBA5 = 0x04000,
|
||||
mCOLOR_BGRA5 = 0x08000,
|
||||
mCOLOR_RGB8 = 0x10000,
|
||||
mCOLOR_BGR8 = 0x20000,
|
||||
|
||||
mCOLOR_ANY = -1
|
||||
};
|
||||
|
||||
struct mCoreCallbacks {
|
||||
void* context;
|
||||
void (*videoFrameStarted)(void* context);
|
||||
|
@ -84,9 +107,9 @@ struct mRTCSource {
|
|||
};
|
||||
|
||||
struct mImageSource {
|
||||
void (*startRequestImage)(struct mImageSource*, unsigned w, unsigned h);
|
||||
void (*startRequestImage)(struct mImageSource*, unsigned w, unsigned h, int colorFormats);
|
||||
void (*stopRequestImage)(struct mImageSource*);
|
||||
void (*requestImage)(struct mImageSource*, const uint32_t** buffer, size_t* stride);
|
||||
void (*requestImage)(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat);
|
||||
};
|
||||
|
||||
enum mRTCGenericType {
|
||||
|
|
47
src/gb/mbc.c
47
src/gb/mbc.c
|
@ -244,7 +244,7 @@ void GBMBCInit(struct GB* gb) {
|
|||
gb->memory.mbcWrite = _GBPocketCam;
|
||||
gb->memory.mbcRead = _GBPocketCamRead;
|
||||
if (gb->memory.cam && gb->memory.cam->startRequestImage) {
|
||||
gb->memory.cam->startRequestImage(gb->memory.cam, GBCAM_WIDTH, GBCAM_HEIGHT);
|
||||
gb->memory.cam->startRequestImage(gb->memory.cam, GBCAM_WIDTH, GBCAM_HEIGHT, mCOLOR_ANY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -791,9 +791,10 @@ void _GBPocketCamCapture(struct GBMemory* memory) {
|
|||
if (!memory->cam) {
|
||||
return;
|
||||
}
|
||||
const uint32_t* image = NULL;
|
||||
const void* image = NULL;
|
||||
size_t stride;
|
||||
memory->cam->requestImage(memory->cam, &image, &stride);
|
||||
enum mColorFormat format;
|
||||
memory->cam->requestImage(memory->cam, &image, &stride, &format);
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
@ -802,8 +803,44 @@ void _GBPocketCamCapture(struct GBMemory* memory) {
|
|||
size_t x, y;
|
||||
for (y = 0; y < GBCAM_HEIGHT; ++y) {
|
||||
for (x = 0; x < GBCAM_WIDTH; ++x) {
|
||||
uint32_t color = image[y * stride + x];
|
||||
uint32_t gray = ((color & 0xFF) + ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF));
|
||||
uint32_t gray;
|
||||
uint32_t color;
|
||||
switch (format) {
|
||||
case mCOLOR_XBGR8:
|
||||
case mCOLOR_XRGB8:
|
||||
case mCOLOR_ARGB8:
|
||||
case mCOLOR_ABGR8:
|
||||
color = ((const uint32_t*) image)[y * stride + x];
|
||||
gray = (color & 0xFF) + ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF);
|
||||
break;
|
||||
case mCOLOR_BGRX8:
|
||||
case mCOLOR_RGBX8:
|
||||
case mCOLOR_RGBA8:
|
||||
case mCOLOR_BGRA8:
|
||||
color = ((const uint32_t*) image)[y * stride + x];
|
||||
gray = ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF) + ((color >> 24) & 0xFF);
|
||||
break;
|
||||
case mCOLOR_BGR5:
|
||||
case mCOLOR_RGB5:
|
||||
case mCOLOR_ARGB5:
|
||||
case mCOLOR_ABGR5:
|
||||
color = ((const uint16_t*) image)[y * stride + x];
|
||||
gray = ((color << 3) & 0xF8) + ((color >> 2) & 0xF8) + ((color >> 7) & 0xF8);
|
||||
break;
|
||||
case mCOLOR_BGR565:
|
||||
case mCOLOR_RGB565:
|
||||
color = ((const uint16_t*) image)[y * stride + x];
|
||||
gray = ((color << 3) & 0xF8) + ((color >> 3) & 0xFC) + ((color >> 8) & 0xF8);
|
||||
break;
|
||||
case mCOLOR_BGRA5:
|
||||
case mCOLOR_RGBA5:
|
||||
color = ((const uint16_t*) image)[y * stride + x];
|
||||
gray = ((color << 2) & 0xF8) + ((color >> 3) & 0xF8) + ((color >> 8) & 0xF8);
|
||||
break;
|
||||
default:
|
||||
mLOG(GB_MBC, WARN, "Unsupported pixel format: %X", format);
|
||||
return;
|
||||
}
|
||||
uint16_t exposure = (pocketCam->registers[2] << 8) | (pocketCam->registers[3]);
|
||||
gray = (gray + 1) * exposure / 0x300;
|
||||
// TODO: Additional processing
|
||||
|
|
|
@ -88,7 +88,7 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren
|
|||
#endif
|
||||
|
||||
m_image.p = this;
|
||||
m_image.startRequestImage = [](mImageSource* context, unsigned w, unsigned h) {
|
||||
m_image.startRequestImage = [](mImageSource* context, unsigned w, unsigned h, int) {
|
||||
InputControllerImage* image = static_cast<InputControllerImage*>(context);
|
||||
image->w = w;
|
||||
image->h = h;
|
||||
|
@ -109,19 +109,19 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren
|
|||
#endif
|
||||
};
|
||||
|
||||
m_image.requestImage = [](mImageSource* context, const uint32_t** buffer, size_t* stride) {
|
||||
m_image.requestImage = [](mImageSource* context, const void** buffer, size_t* stride, mColorFormat* format) {
|
||||
InputControllerImage* image = static_cast<InputControllerImage*>(context);
|
||||
QSize size;
|
||||
{
|
||||
QMutexLocker locker(&image->mutex);
|
||||
if (image->outOfDate) {
|
||||
image->resizedImage = image->image.scaled(image->w, image->h, Qt::KeepAspectRatioByExpanding);
|
||||
image->resizedImage = image->resizedImage.convertToFormat(QImage::Format_RGB32);
|
||||
image->resizedImage = image->resizedImage.convertToFormat(QImage::Format_RGB16);
|
||||
image->outOfDate = false;
|
||||
}
|
||||
}
|
||||
size = image->resizedImage.size();
|
||||
const uint32_t* bits = reinterpret_cast<const uint32_t*>(image->resizedImage.constBits());
|
||||
const uint16_t* bits = reinterpret_cast<const uint16_t*>(image->resizedImage.constBits());
|
||||
if (size.width() > image->w) {
|
||||
bits += (size.width() - image->w) / 2;
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren
|
|||
bits += ((size.height() - image->h) / 2) * size.width();
|
||||
}
|
||||
*buffer = bits;
|
||||
*stride = size.width();
|
||||
*stride = image->resizedImage.bytesPerLine() / sizeof(*bits);
|
||||
*format = mCOLOR_RGB565;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue