mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Implement mosaic for modes 2 - 5, untested with windows
This commit is contained in:
parent
eb51195769
commit
81b85d1843
|
@ -1249,9 +1249,17 @@ static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BACKGROUND_BITMAP_INIT \
|
#define BACKGROUND_BITMAP_INIT \
|
||||||
UNUSED(unused); \
|
|
||||||
int32_t x = background->sx + (renderer->start - 1) * background->dx; \
|
int32_t x = background->sx + (renderer->start - 1) * background->dx; \
|
||||||
int32_t y = background->sy + (renderer->start - 1) * background->dy; \
|
int32_t y = background->sy + (renderer->start - 1) * background->dy; \
|
||||||
|
int mosaicH = 0; \
|
||||||
|
int mosaicWait = 0; \
|
||||||
|
if (background->mosaic) { \
|
||||||
|
int mosaicV = GBAMosaicControlGetBgV(renderer->mosaic) + 1; \
|
||||||
|
y -= (inY % mosaicV) * background->dmy; \
|
||||||
|
x -= (inY % mosaicV) * background->dmx; \
|
||||||
|
mosaicH = GBAMosaicControlGetBgH(renderer->mosaic); \
|
||||||
|
mosaicWait = renderer->start % (mosaicH + 1); \
|
||||||
|
} \
|
||||||
int32_t localX; \
|
int32_t localX; \
|
||||||
int32_t localY; \
|
int32_t localY; \
|
||||||
\
|
\
|
||||||
|
@ -1279,7 +1287,7 @@ static void _drawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
localY = y; \
|
localY = y; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int unused) {
|
static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
|
||||||
int sizeAdjusted = 0x8000 << background->size;
|
int sizeAdjusted = 0x8000 << background->size;
|
||||||
|
|
||||||
BACKGROUND_BITMAP_INIT;
|
BACKGROUND_BITMAP_INIT;
|
||||||
|
@ -1287,7 +1295,7 @@ static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
uint32_t screenBase = background->screenBase;
|
uint32_t screenBase = background->screenBase;
|
||||||
uint32_t charBase = background->charBase;
|
uint32_t charBase = background->charBase;
|
||||||
uint8_t mapData;
|
uint8_t mapData;
|
||||||
uint8_t tileData;
|
uint8_t tileData = 0;
|
||||||
|
|
||||||
int outX;
|
int outX;
|
||||||
uint32_t* pixel;
|
uint32_t* pixel;
|
||||||
|
@ -1295,17 +1303,23 @@ static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
x += background->dx;
|
x += background->dx;
|
||||||
y += background->dy;
|
y += background->dy;
|
||||||
|
|
||||||
if (background->overflow) {
|
if (!mosaicWait) {
|
||||||
localX = x & (sizeAdjusted - 1);
|
if (background->overflow) {
|
||||||
localY = y & (sizeAdjusted - 1);
|
localX = x & (sizeAdjusted - 1);
|
||||||
} else if ((x | y) & ~(sizeAdjusted - 1)) {
|
localY = y & (sizeAdjusted - 1);
|
||||||
continue;
|
} else if ((x | y) & ~(sizeAdjusted - 1)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
localX = x;
|
||||||
|
localY = y;
|
||||||
|
}
|
||||||
|
mapData = ((uint8_t*)renderer->d.vram)[screenBase + (localX >> 11) + (((localY >> 7) & 0x7F0) << background->size)];
|
||||||
|
tileData = ((uint8_t*)renderer->d.vram)[charBase + (mapData << 6) + ((localY & 0x700) >> 5) + ((localX & 0x700) >> 8)];
|
||||||
|
|
||||||
|
mosaicWait = mosaicH;
|
||||||
} else {
|
} else {
|
||||||
localX = x;
|
--mosaicWait;
|
||||||
localY = y;
|
|
||||||
}
|
}
|
||||||
mapData = ((uint8_t*)renderer->d.vram)[screenBase + (localX >> 11) + (((localY >> 7) & 0x7F0) << background->size)];
|
|
||||||
tileData = ((uint8_t*)renderer->d.vram)[charBase + (mapData << 6) + ((localY & 0x700) >> 5) + ((localX & 0x700) >> 8)];
|
|
||||||
|
|
||||||
uint32_t current = *pixel;
|
uint32_t current = *pixel;
|
||||||
if (tileData && IS_WRITABLE(current)) {
|
if (tileData && IS_WRITABLE(current)) {
|
||||||
|
@ -1319,25 +1333,30 @@ static void _drawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawBackgroundMode3(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int unused) {
|
static void _drawBackgroundMode3(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
|
||||||
BACKGROUND_BITMAP_INIT;
|
BACKGROUND_BITMAP_INIT;
|
||||||
|
|
||||||
uint32_t color;
|
uint32_t color = renderer->normalPalette[0];
|
||||||
|
|
||||||
int outX;
|
int outX;
|
||||||
uint32_t* pixel;
|
uint32_t* pixel;
|
||||||
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
|
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
|
||||||
BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
|
BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
|
||||||
|
|
||||||
LOAD_16(color, ((localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vram);
|
if (!mosaicWait) {
|
||||||
|
LOAD_16(color, ((localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vram);
|
||||||
#ifndef COLOR_16_BIT
|
#ifndef COLOR_16_BIT
|
||||||
unsigned color32;
|
unsigned color32;
|
||||||
color32 = 0;
|
color32 = 0;
|
||||||
color32 |= (color << 3) & 0xF8;
|
color32 |= (color << 3) & 0xF8;
|
||||||
color32 |= (color << 6) & 0xF800;
|
color32 |= (color << 6) & 0xF800;
|
||||||
color32 |= (color << 9) & 0xF80000;
|
color32 |= (color << 9) & 0xF80000;
|
||||||
color = color32;
|
color = color32;
|
||||||
#endif
|
#endif
|
||||||
|
mosaicWait = mosaicH;
|
||||||
|
} else {
|
||||||
|
--mosaicWait;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t current = *pixel;
|
uint32_t current = *pixel;
|
||||||
if (!objwinSlowPath || !(current & FLAG_OBJWIN) != objwinOnly) {
|
if (!objwinSlowPath || !(current & FLAG_OBJWIN) != objwinOnly) {
|
||||||
|
@ -1352,10 +1371,10 @@ static void _drawBackgroundMode3(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawBackgroundMode4(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int unused) {
|
static void _drawBackgroundMode4(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
|
||||||
BACKGROUND_BITMAP_INIT;
|
BACKGROUND_BITMAP_INIT;
|
||||||
|
|
||||||
uint16_t color;
|
uint16_t color = renderer->normalPalette[0];
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
|
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
|
||||||
offset = 0xA000;
|
offset = 0xA000;
|
||||||
|
@ -1366,7 +1385,13 @@ static void _drawBackgroundMode4(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
|
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
|
||||||
BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
|
BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
|
||||||
|
|
||||||
color = ((uint8_t*)renderer->d.vram)[offset + (localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS];
|
if (!mosaicWait) {
|
||||||
|
color = ((uint8_t*)renderer->d.vram)[offset + (localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS];
|
||||||
|
|
||||||
|
mosaicWait = mosaicH;
|
||||||
|
} else {
|
||||||
|
--mosaicWait;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t current = *pixel;
|
uint32_t current = *pixel;
|
||||||
if (color && IS_WRITABLE(current)) {
|
if (color && IS_WRITABLE(current)) {
|
||||||
|
@ -1380,10 +1405,10 @@ static void _drawBackgroundMode4(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int unused) {
|
static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
|
||||||
BACKGROUND_BITMAP_INIT;
|
BACKGROUND_BITMAP_INIT;
|
||||||
|
|
||||||
uint32_t color;
|
uint32_t color = renderer->normalPalette[0];
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
|
if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
|
||||||
offset = 0xA000;
|
offset = 0xA000;
|
||||||
|
@ -1394,14 +1419,19 @@ static void _drawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, stru
|
||||||
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
|
for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
|
||||||
BACKGROUND_BITMAP_ITERATE(160, 128);
|
BACKGROUND_BITMAP_ITERATE(160, 128);
|
||||||
|
|
||||||
LOAD_16(color, (offset + (localX >> 8) + (localY >> 8) * 160) << 1, renderer->d.vram);
|
if (!mosaicWait) {
|
||||||
|
LOAD_16(color, (offset + (localX >> 8) + (localY >> 8) * 160) << 1, renderer->d.vram);
|
||||||
#ifndef COLOR_16_BIT
|
#ifndef COLOR_16_BIT
|
||||||
unsigned color32 = 0;
|
unsigned color32 = 0;
|
||||||
color32 |= (color << 9) & 0xF80000;
|
color32 |= (color << 9) & 0xF80000;
|
||||||
color32 |= (color << 3) & 0xF8;
|
color32 |= (color << 3) & 0xF8;
|
||||||
color32 |= (color << 6) & 0xF800;
|
color32 |= (color << 6) & 0xF800;
|
||||||
color = color32;
|
color = color32;
|
||||||
#endif
|
#endif
|
||||||
|
mosaicWait = mosaicH;
|
||||||
|
} else {
|
||||||
|
--mosaicWait;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t current = *pixel;
|
uint32_t current = *pixel;
|
||||||
if (!objwinSlowPath || !(current & FLAG_OBJWIN) != objwinOnly) {
|
if (!objwinSlowPath || !(current & FLAG_OBJWIN) != objwinOnly) {
|
||||||
|
|
Loading…
Reference in New Issue