mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Implement green swap (fixes #1609)
This commit is contained in:
parent
6a97b1dbf5
commit
c825c57281
1
CHANGES
1
CHANGES
|
@ -42,6 +42,7 @@ Emulation fixes:
|
|||
- GBA Video: Fix Hblank timing
|
||||
- GBA Video: Invalidate map cache when modifying BGCNT (fixes mgba.io/i/1846)
|
||||
- GBA Video: Don't draw sprites using unmapped VRAM in GL renderer (fixes mgba.io/i/1865)
|
||||
- GBA Video: Implement green swap (fixes mgba.io/i/1609)
|
||||
- SM83: Emulate HALT bug
|
||||
Other fixes:
|
||||
- 3DS: Redo video sync to be more precise
|
||||
|
|
|
@ -36,6 +36,23 @@ typedef uint32_t color_t;
|
|||
#define M_RGB8_TO_BGR5(X) ((((X) & 0xF8) >> 3) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 9))
|
||||
#define M_RGB8_TO_RGB5(X) ((((X) & 0xF8) << 7) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 19))
|
||||
|
||||
#ifndef COLOR_16_BIT
|
||||
#define M_COLOR_RED 0x000000FF
|
||||
#define M_COLOR_GREEN 0x0000FF00
|
||||
#define M_COLOR_BLUE 0x00FF0000
|
||||
#define M_COLOR_ALPHA 0xFF000000
|
||||
#elif defined(COLOR_5_6_5)
|
||||
#define M_COLOR_RED 0x001F
|
||||
#define M_COLOR_GREEN 0x07E0
|
||||
#define M_COLOR_BLUE 0xF800
|
||||
#define M_COLOR_ALPHA 0x0000
|
||||
#else
|
||||
#define M_COLOR_RED 0x001F
|
||||
#define M_COLOR_GREEN 0x03E0
|
||||
#define M_COLOR_BLUE 0x7C00
|
||||
#define M_COLOR_ALPHA 0x1000
|
||||
#endif
|
||||
|
||||
#ifndef PYCPARSE
|
||||
static inline color_t mColorFrom555(uint16_t value) {
|
||||
#ifdef COLOR_16_BIT
|
||||
|
|
|
@ -114,6 +114,7 @@ struct GBAVideoSoftwareRenderer {
|
|||
uint16_t bldy;
|
||||
|
||||
GBAMosaicControl mosaic;
|
||||
bool greenswap;
|
||||
|
||||
struct WindowN {
|
||||
struct GBAVideoWindowRegion h;
|
||||
|
|
|
@ -341,7 +341,7 @@ void GBAIOInit(struct GBA* gba) {
|
|||
}
|
||||
|
||||
void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
|
||||
if (address < REG_SOUND1CNT_LO && (address > REG_VCOUNT || address == REG_DISPCNT)) {
|
||||
if (address < REG_SOUND1CNT_LO && (address > REG_VCOUNT || address < REG_DISPSTAT)) {
|
||||
value = gba->video.renderer->writeVideoRegister(gba->video.renderer, address, value);
|
||||
} else {
|
||||
switch (address) {
|
||||
|
|
|
@ -122,6 +122,7 @@ static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer) {
|
|||
softwareRenderer->oamMax = 0;
|
||||
|
||||
softwareRenderer->mosaic = 0;
|
||||
softwareRenderer->greenswap = false;
|
||||
softwareRenderer->nextY = 0;
|
||||
|
||||
softwareRenderer->objOffsetX = 0;
|
||||
|
@ -179,6 +180,9 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
softwareRenderer->dispcnt = value;
|
||||
GBAVideoSoftwareRendererUpdateDISPCNT(softwareRenderer);
|
||||
break;
|
||||
case REG_GREENSWP:
|
||||
softwareRenderer->greenswap = value & 1;
|
||||
break;
|
||||
case REG_BG0CNT:
|
||||
value &= 0xDFFF;
|
||||
GBAVideoSoftwareRendererWriteBGCNT(softwareRenderer, &softwareRenderer->bg[0], value);
|
||||
|
@ -389,9 +393,6 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
|
|||
case REG_MOSAIC:
|
||||
softwareRenderer->mosaic = value;
|
||||
break;
|
||||
case REG_GREENSWP:
|
||||
mLOG(GBA_VIDEO, STUB, "Stub video register write: 0x%03X", address);
|
||||
break;
|
||||
default:
|
||||
mLOG(GBA_VIDEO, GAME_ERROR, "Invalid video register: 0x%03X", address);
|
||||
}
|
||||
|
@ -675,16 +676,30 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render
|
|||
}
|
||||
}
|
||||
|
||||
if (softwareRenderer->greenswap) {
|
||||
for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) {
|
||||
row[x] = softwareRenderer->row[x] & (M_COLOR_RED | M_COLOR_BLUE);
|
||||
row[x] |= softwareRenderer->row[x + 1] & M_COLOR_GREEN;
|
||||
row[x + 1] = softwareRenderer->row[x + 1] & (M_COLOR_RED | M_COLOR_BLUE);
|
||||
row[x + 1] |= softwareRenderer->row[x] & M_COLOR_GREEN;
|
||||
row[x + 2] = softwareRenderer->row[x + 2] & (M_COLOR_RED | M_COLOR_BLUE);
|
||||
row[x + 2] |= softwareRenderer->row[x + 3] & M_COLOR_GREEN;
|
||||
row[x + 3] = softwareRenderer->row[x + 3] & (M_COLOR_RED | M_COLOR_BLUE);
|
||||
row[x + 3] |= softwareRenderer->row[x + 2] & M_COLOR_GREEN;
|
||||
|
||||
}
|
||||
} else {
|
||||
#ifdef COLOR_16_BIT
|
||||
for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) {
|
||||
row[x] = softwareRenderer->row[x];
|
||||
row[x + 1] = softwareRenderer->row[x + 1];
|
||||
row[x + 2] = softwareRenderer->row[x + 2];
|
||||
row[x + 3] = softwareRenderer->row[x + 3];
|
||||
}
|
||||
for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) {
|
||||
row[x] = softwareRenderer->row[x];
|
||||
row[x + 1] = softwareRenderer->row[x + 1];
|
||||
row[x + 2] = softwareRenderer->row[x + 2];
|
||||
row[x + 3] = softwareRenderer->row[x + 3];
|
||||
}
|
||||
#else
|
||||
memcpy(row, softwareRenderer->row, GBA_VIDEO_HORIZONTAL_PIXELS * sizeof(*row));
|
||||
memcpy(row, softwareRenderer->row, GBA_VIDEO_HORIZONTAL_PIXELS * sizeof(*row));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* renderer) {
|
||||
|
|
Loading…
Reference in New Issue