Core: Color formats

This commit is contained in:
Vicki Pfau 2017-07-27 12:59:06 -07:00
parent c7e65ff621
commit e0f04a0d5a
3 changed files with 73 additions and 12 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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;
};
}