GBA Video: Implement layer placement for OpenGL renderer (fixes #1962)

This commit is contained in:
Vicki Pfau 2022-02-20 19:45:13 -08:00
parent 5f3cb2f72f
commit 7c8a06816b
4 changed files with 39 additions and 16 deletions

View File

@ -48,6 +48,7 @@ Misc:
- GB Video: Add default SGB border - GB Video: Add default SGB border
- GBA: Automatically skip BIOS if ROM has invalid logo - GBA: Automatically skip BIOS if ROM has invalid logo
- GBA DMA: Enhanced logging (closes mgba.io/i/2454) - GBA DMA: Enhanced logging (closes mgba.io/i/2454)
- GBA Video: Implement layer placement for OpenGL renderer (fixes mgba.io/i/1962)
- mGUI: Add margin to right-aligned menu text (fixes mgba.io/i/871) - mGUI: Add margin to right-aligned menu text (fixes mgba.io/i/871)
- Qt: Rearrange menus some - Qt: Rearrange menus some
- Qt: Clean up cheats dialog - Qt: Clean up cheats dialog

View File

@ -60,6 +60,8 @@ struct GBAVideoGLBackground {
uint16_t y; uint16_t y;
int32_t refx; int32_t refx;
int32_t refy; int32_t refy;
int32_t offsetX;
int32_t offsetY;
struct GBAVideoGLAffine affine; struct GBAVideoGLAffine affine;
@ -142,6 +144,8 @@ struct GBAVideoGLRenderer {
int oamMax; int oamMax;
bool oamDirty; bool oamDirty;
struct GBAVideoRendererSprite sprites[128]; struct GBAVideoRendererSprite sprites[128];
int16_t objOffsetX;
int16_t objOffsetY;
GLuint fbo[GBA_GL_FBO_MAX]; GLuint fbo[GBA_GL_FBO_MAX];
GLuint layers[GBA_GL_TEX_MAX]; GLuint layers[GBA_GL_TEX_MAX];
@ -183,6 +187,8 @@ struct GBAVideoGLRenderer {
struct GBAVideoWindowRegion h; struct GBAVideoWindowRegion h;
struct GBAVideoWindowRegion v; struct GBAVideoWindowRegion v;
GBAWindowControl control; GBAWindowControl control;
int16_t offsetX;
int16_t offsetY;
} winN[2]; } winN[2];
GLint winNHistory[2][GBA_VIDEO_VERTICAL_PIXELS * 4]; GLint winNHistory[2][GBA_VIDEO_VERTICAL_PIXELS * 4];

View File

@ -1105,15 +1105,29 @@ static void _GBACoreAdjustVideoLayer(struct mCore* core, size_t id, int32_t x, i
case GBA_LAYER_BG3: case GBA_LAYER_BG3:
gbacore->renderer.bg[id].offsetX = x; gbacore->renderer.bg[id].offsetX = x;
gbacore->renderer.bg[id].offsetY = y; gbacore->renderer.bg[id].offsetY = y;
#ifdef BUILD_GLES3
gbacore->glRenderer.bg[id].offsetX = x;
gbacore->glRenderer.bg[id].offsetY = y;
#endif
break; break;
case GBA_LAYER_OBJ: case GBA_LAYER_OBJ:
gbacore->renderer.objOffsetX = x; gbacore->renderer.objOffsetX = x;
gbacore->renderer.objOffsetY = y; gbacore->renderer.objOffsetY = y;
gbacore->renderer.oamDirty = 1; gbacore->renderer.oamDirty = 1;
#ifdef BUILD_GLES3
gbacore->glRenderer.objOffsetX = x;
gbacore->glRenderer.objOffsetY = y;
gbacore->glRenderer.oamDirty = 1;
#endif
break; break;
case GBA_LAYER_WIN0: case GBA_LAYER_WIN0:
case GBA_LAYER_WIN1:
gbacore->renderer.winN[id - GBA_LAYER_WIN0].offsetX = x; gbacore->renderer.winN[id - GBA_LAYER_WIN0].offsetX = x;
gbacore->renderer.winN[id - GBA_LAYER_WIN0].offsetY = y; gbacore->renderer.winN[id - GBA_LAYER_WIN0].offsetY = y;
#ifdef BUILD_GLES3
gbacore->glRenderer.winN[id - GBA_LAYER_WIN0].offsetX = x;
gbacore->glRenderer.winN[id - GBA_LAYER_WIN0].offsetY = y;
#endif
break; break;
default: default:
return; return;

View File

@ -1331,27 +1331,27 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
} }
glRenderer->regsDirty = 0; glRenderer->regsDirty = 0;
glRenderer->winNHistory[0][y * 4 + 0] = glRenderer->winN[0].h.start; glRenderer->winNHistory[0][y * 4 + 0] = glRenderer->winN[0].h.start + glRenderer->winN[0].offsetX;
glRenderer->winNHistory[0][y * 4 + 1] = glRenderer->winN[0].h.end; glRenderer->winNHistory[0][y * 4 + 1] = glRenderer->winN[0].h.end + glRenderer->winN[0].offsetX;
glRenderer->winNHistory[0][y * 4 + 2] = glRenderer->winN[0].v.start; glRenderer->winNHistory[0][y * 4 + 2] = glRenderer->winN[0].v.start + glRenderer->winN[0].offsetY;
glRenderer->winNHistory[0][y * 4 + 3] = glRenderer->winN[0].v.end; glRenderer->winNHistory[0][y * 4 + 3] = glRenderer->winN[0].v.end + glRenderer->winN[0].offsetY;
glRenderer->winNHistory[1][y * 4 + 0] = glRenderer->winN[1].h.start; glRenderer->winNHistory[1][y * 4 + 0] = glRenderer->winN[1].h.start + glRenderer->winN[1].offsetX;
glRenderer->winNHistory[1][y * 4 + 1] = glRenderer->winN[1].h.end; glRenderer->winNHistory[1][y * 4 + 1] = glRenderer->winN[1].h.end + glRenderer->winN[1].offsetX;
glRenderer->winNHistory[1][y * 4 + 2] = glRenderer->winN[1].v.start; glRenderer->winNHistory[1][y * 4 + 2] = glRenderer->winN[1].v.start + glRenderer->winN[1].offsetY;
glRenderer->winNHistory[1][y * 4 + 3] = glRenderer->winN[1].v.end; glRenderer->winNHistory[1][y * 4 + 3] = glRenderer->winN[1].v.end + glRenderer->winN[1].offsetY;
glRenderer->bg[0].scanlineOffset[y] = glRenderer->bg[0].x; glRenderer->bg[0].scanlineOffset[y] = (glRenderer->bg[0].x - glRenderer->bg[0].offsetX) & 0x1FF;
glRenderer->bg[0].scanlineOffset[y] |= glRenderer->bg[0].y << 12; glRenderer->bg[0].scanlineOffset[y] |= ((glRenderer->bg[0].y - glRenderer->bg[0].offsetY) & 0x1FF) << 12;
glRenderer->bg[1].scanlineOffset[y] = glRenderer->bg[1].x; glRenderer->bg[1].scanlineOffset[y] = (glRenderer->bg[1].x - glRenderer->bg[1].offsetX) & 0x1FF;
glRenderer->bg[1].scanlineOffset[y] |= glRenderer->bg[1].y << 12; glRenderer->bg[1].scanlineOffset[y] |= ((glRenderer->bg[1].y - glRenderer->bg[1].offsetY) & 0x1FF) << 12;
glRenderer->bg[2].scanlineOffset[y] = glRenderer->bg[2].x; glRenderer->bg[2].scanlineOffset[y] = (glRenderer->bg[2].x - glRenderer->bg[2].offsetX) & 0x1FF;
glRenderer->bg[2].scanlineOffset[y] |= glRenderer->bg[2].y << 12; glRenderer->bg[2].scanlineOffset[y] |= ((glRenderer->bg[2].y - glRenderer->bg[2].offsetY) & 0x1FF) << 12;
glRenderer->bg[2].scanlineAffine[y * 4] = glRenderer->bg[2].affine.dx; glRenderer->bg[2].scanlineAffine[y * 4] = glRenderer->bg[2].affine.dx;
glRenderer->bg[2].scanlineAffine[y * 4 + 1] = glRenderer->bg[2].affine.dy; glRenderer->bg[2].scanlineAffine[y * 4 + 1] = glRenderer->bg[2].affine.dy;
glRenderer->bg[2].scanlineAffine[y * 4 + 2] = glRenderer->bg[2].affine.sx; glRenderer->bg[2].scanlineAffine[y * 4 + 2] = glRenderer->bg[2].affine.sx;
glRenderer->bg[2].scanlineAffine[y * 4 + 3] = glRenderer->bg[2].affine.sy; glRenderer->bg[2].scanlineAffine[y * 4 + 3] = glRenderer->bg[2].affine.sy;
glRenderer->bg[3].scanlineOffset[y] = glRenderer->bg[3].x; glRenderer->bg[3].scanlineOffset[y] = (glRenderer->bg[3].x - glRenderer->bg[3].offsetX) & 0x1FF;
glRenderer->bg[3].scanlineOffset[y] |= glRenderer->bg[3].y << 12; glRenderer->bg[3].scanlineOffset[y] |= ((glRenderer->bg[3].y - glRenderer->bg[3].offsetY) & 0x1FF) << 12;
glRenderer->bg[3].scanlineAffine[y * 4] = glRenderer->bg[3].affine.dx; glRenderer->bg[3].scanlineAffine[y * 4] = glRenderer->bg[3].affine.dx;
glRenderer->bg[3].scanlineAffine[y * 4 + 1] = glRenderer->bg[3].affine.dy; glRenderer->bg[3].scanlineAffine[y * 4 + 1] = glRenderer->bg[3].affine.dy;
glRenderer->bg[3].scanlineAffine[y * 4 + 2] = glRenderer->bg[3].affine.sx; glRenderer->bg[3].scanlineAffine[y * 4 + 2] = glRenderer->bg[3].affine.sx;
@ -1686,6 +1686,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][1]; int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][1];
int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23; int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23;
x >>= 23; x >>= 23;
x += renderer->objOffsetX;
if (GBARegisterDISPCNTGetMode(renderer->dispcnt) >= 3 && GBAObjAttributesCGetTile(sprite->c) < 512) { if (GBARegisterDISPCNTGetMode(renderer->dispcnt) >= 3 && GBAObjAttributesCGetTile(sprite->c) < 512) {
return; return;
@ -1702,6 +1703,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
totalHeight <<= 1; totalHeight <<= 1;
} }
spriteY += renderer->objOffsetY;
if (spriteY + totalHeight >= 256) { if (spriteY + totalHeight >= 256) {
spriteY -= 256; spriteY -= 256;
} }