mirror of https://github.com/mgba-emu/mgba.git
GBA Video: Implement layer placement for OpenGL renderer (fixes #1962)
This commit is contained in:
parent
5f3cb2f72f
commit
7c8a06816b
1
CHANGES
1
CHANGES
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue