@@ -47,11 +47,9 @@ static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* ren
4747static void GBAVideoGLRendererDrawWindow (struct GBAVideoGLRenderer * renderer , int y );
4848
4949static void _cleanRegister (struct GBAVideoGLRenderer * renderer , int address , uint16_t value );
50- static void _drawScanlines (struct GBAVideoGLRenderer * renderer , int lastY );
50+ static void _drawScanlines (struct GBAVideoGLRenderer * renderer , int y );
5151static void _finalizeLayers (struct GBAVideoGLRenderer * renderer );
5252
53- #define TEST_LAYER_ENABLED (X ) !glRenderer->d.disableBG[X] && glRenderer->bg[X].enabled == 4
54-
5553struct GBAVideoGLUniform {
5654 const char * name ;
5755 int type ;
@@ -911,6 +909,7 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) {
911909 glRenderer -> vramDirty = 0xFFFFFF ;
912910 glRenderer -> firstAffine = -1 ;
913911 glRenderer -> firstY = -1 ;
912+ glRenderer -> lastY = -1 ;
914913 glRenderer -> dispcnt = 0x0080 ;
915914 glRenderer -> mosaic = 0 ;
916915 glRenderer -> nextPalette = 0 ;
@@ -926,7 +925,7 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) {
926925 for (i = 0 ; i < 4 ; ++ i ) {
927926 struct GBAVideoGLBackground * bg = & glRenderer -> bg [i ];
928927 bg -> index = i ;
929- bg -> enabled = 0 ;
928+ bg -> enabledAtY = INT_MAX ;
930929 bg -> priority = 0 ;
931930 bg -> charBase = 0 ;
932931 bg -> mosaic = 0 ;
@@ -1243,8 +1242,7 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t
12431242}
12441243
12451244static bool _dirtyMode0 (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , int y ) {
1246- UNUSED (y );
1247- if (!background -> enabled ) {
1245+ if (y < background -> enabledAtY ) {
12481246 return false;
12491247 }
12501248 unsigned screenBase = background -> screenBase >> 11 ; // Lops off one extra bit
@@ -1261,8 +1259,7 @@ static bool _dirtyMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa
12611259}
12621260
12631261static bool _dirtyMode2 (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , int y ) {
1264- UNUSED (y );
1265- if (!background -> enabled ) {
1262+ if (y < background -> enabledAtY ) {
12661263 return false;
12671264 }
12681265 unsigned screenBase = background -> screenBase >> 11 ; // Lops off one extra bit
@@ -1279,8 +1276,7 @@ static bool _dirtyMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa
12791276}
12801277
12811278static bool _dirtyMode3 (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , int y ) {
1282- UNUSED (y );
1283- if (!background -> enabled ) {
1279+ if (y < background -> enabledAtY ) {
12841280 return false;
12851281 }
12861282 if (renderer -> vramDirty & 0xFFFFF ) {
@@ -1290,8 +1286,7 @@ static bool _dirtyMode3(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa
12901286}
12911287
12921288static bool _dirtyMode45 (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , int y ) {
1293- UNUSED (y );
1294- if (!background -> enabled ) {
1289+ if (y < background -> enabledAtY ) {
12951290 return false;
12961291 }
12971292 int start = GBARegisterDISPCNTIsFrameSelect (renderer -> dispcnt ) ? 5 : 0 ;
@@ -1365,6 +1360,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
13651360 if (glRenderer -> firstY < 0 ) {
13661361 glRenderer -> firstY = y ;
13671362 }
1363+ glRenderer -> lastY = y ;
13681364
13691365 int i ;
13701366 for (i = 0 ; i < 0x30 ; ++ i ) {
@@ -1468,11 +1464,11 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
14681464 }
14691465
14701466 if (GBARegisterDISPCNTGetMode (glRenderer -> dispcnt ) != 0 ) {
1471- if (glRenderer -> bg [2 ].enabled == 4 ) {
1467+ if (glRenderer -> bg [2 ].enabledAtY <= y ) {
14721468 glRenderer -> bg [2 ].affine .sx += glRenderer -> bg [2 ].affine .dmx ;
14731469 glRenderer -> bg [2 ].affine .sy += glRenderer -> bg [2 ].affine .dmy ;
14741470 }
1475- if (glRenderer -> bg [3 ].enabled == 4 ) {
1471+ if (glRenderer -> bg [3 ].enabledAtY <= y ) {
14761472 glRenderer -> bg [3 ].affine .sx += glRenderer -> bg [3 ].affine .dmx ;
14771473 glRenderer -> bg [3 ].affine .sy += glRenderer -> bg [3 ].affine .dmy ;
14781474 }
@@ -1535,13 +1531,13 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) {
15351531 glDisable (GL_STENCIL_TEST );
15361532 }
15371533
1538- if (TEST_LAYER_ENABLED ( 0 ) && GBARegisterDISPCNTGetMode (glRenderer -> dispcnt ) < 2 ) {
1534+ if (glRenderer -> bg [ 0 ]. enabledAtY <= y && GBARegisterDISPCNTGetMode (glRenderer -> dispcnt ) < 2 ) {
15391535 GBAVideoGLRendererDrawBackgroundMode0 (glRenderer , & glRenderer -> bg [0 ], y );
15401536 }
1541- if (TEST_LAYER_ENABLED ( 1 ) && GBARegisterDISPCNTGetMode (glRenderer -> dispcnt ) < 2 ) {
1537+ if (glRenderer -> bg [ 1 ]. enabledAtY <= y && GBARegisterDISPCNTGetMode (glRenderer -> dispcnt ) < 2 ) {
15421538 GBAVideoGLRendererDrawBackgroundMode0 (glRenderer , & glRenderer -> bg [1 ], y );
15431539 }
1544- if (TEST_LAYER_ENABLED ( 2 ) ) {
1540+ if (glRenderer -> bg [ 2 ]. enabledAtY <= y ) {
15451541 switch (GBARegisterDISPCNTGetMode (glRenderer -> dispcnt )) {
15461542 case 0 :
15471543 GBAVideoGLRendererDrawBackgroundMode0 (glRenderer , & glRenderer -> bg [2 ], y );
@@ -1561,7 +1557,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) {
15611557 break ;
15621558 }
15631559 }
1564- if (TEST_LAYER_ENABLED ( 3 ) ) {
1560+ if (glRenderer -> bg [ 3 ]. enabledAtY <= y ) {
15651561 switch (GBARegisterDISPCNTGetMode (glRenderer -> dispcnt )) {
15661562 case 0 :
15671563 GBAVideoGLRendererDrawBackgroundMode0 (glRenderer , & glRenderer -> bg [3 ], y );
@@ -1582,6 +1578,19 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) {
15821578 glBindVertexArray (0 );
15831579 glRenderer -> firstAffine = -1 ;
15841580 glRenderer -> firstY = -1 ;
1581+ glRenderer -> lastY = -1 ;
1582+ if (glRenderer -> bg [0 ].enabledAtY < INT_MAX ) {
1583+ glRenderer -> bg [0 ].enabledAtY = 0 ;
1584+ }
1585+ if (glRenderer -> bg [1 ].enabledAtY < INT_MAX ) {
1586+ glRenderer -> bg [1 ].enabledAtY = 0 ;
1587+ }
1588+ if (glRenderer -> bg [2 ].enabledAtY < INT_MAX ) {
1589+ glRenderer -> bg [2 ].enabledAtY = 0 ;
1590+ }
1591+ if (glRenderer -> bg [3 ].enabledAtY < INT_MAX ) {
1592+ glRenderer -> bg [3 ].enabledAtY = 0 ;
1593+ }
15851594 glRenderer -> bg [2 ].affine .sx = glRenderer -> bg [2 ].refx ;
15861595 glRenderer -> bg [2 ].affine .sy = glRenderer -> bg [2 ].refy ;
15871596 glRenderer -> bg [3 ].affine .sx = glRenderer -> bg [3 ].refx ;
@@ -1610,17 +1619,18 @@ void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t strid
16101619}
16111620
16121621static void _enableBg (struct GBAVideoGLRenderer * renderer , int bg , bool active ) {
1613- int wasActive = renderer -> bg [bg ].enabled ;
1622+ int wasActive = renderer -> bg [bg ].enabledAtY ;
16141623 if (!active ) {
1615- renderer -> bg [bg ].enabled = 0 ;
1616- } else if (! wasActive && active ) {
1617- /* if (renderer->nextY == 0 || GBARegisterDISPCNTGetMode(renderer->dispcnt) > 2 ) {
1624+ renderer -> bg [bg ].enabledAtY = INT_MAX ;
1625+ } else if (wasActive == INT_MAX && active ) {
1626+ if (renderer -> lastY < 0 ) {
16181627 // TODO: Investigate in more depth how switching background works in different modes
1619- renderer->bg[bg].enabled = 4;
1628+ renderer -> bg [bg ].enabledAtY = 0 ;
1629+ } else if (GBARegisterDISPCNTGetMode (renderer -> dispcnt ) > 2 ) {
1630+ renderer -> bg [bg ].enabledAtY = renderer -> lastY + 2 ;
16201631 } else {
1621- renderer->bg[bg].enabled = 1;
1622- }*/
1623- renderer -> bg [bg ].enabled = 4 ;
1632+ renderer -> bg [bg ].enabledAtY = renderer -> lastY + 3 ;
1633+ }
16241634 }
16251635}
16261636
@@ -1885,6 +1895,10 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa
18851895void GBAVideoGLRendererDrawBackgroundMode0 (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , int y ) {
18861896 const struct GBAVideoGLShader * shader = & renderer -> bgShader [background -> multipalette ? 1 : 0 ];
18871897 const GLuint * uniforms = shader -> uniforms ;
1898+ int firstY = renderer -> firstY ;
1899+ if (firstY < background -> enabledAtY ) {
1900+ firstY = background -> enabledAtY ;
1901+ }
18881902 glUseProgram (shader -> program );
18891903 glBindVertexArray (shader -> vao );
18901904 _prepareBackground (renderer , background , uniforms );
@@ -1893,16 +1907,20 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer,
18931907 glUniform1i (uniforms [GBA_GL_BG_SIZE ], background -> size );
18941908 glUniform1iv (uniforms [GBA_GL_BG_OFFSET ], GBA_VIDEO_VERTICAL_PIXELS , background -> scanlineOffset );
18951909
1896- glScissor (0 , renderer -> firstY * renderer -> scale , GBA_VIDEO_HORIZONTAL_PIXELS * renderer -> scale , (y - renderer -> firstY + 1 ) * renderer -> scale );
1897- glUniform2i (uniforms [GBA_GL_VS_LOC ], y - renderer -> firstY + 1 , renderer -> firstY );
1910+ glScissor (0 , firstY * renderer -> scale , GBA_VIDEO_HORIZONTAL_PIXELS * renderer -> scale , (y - firstY + 1 ) * renderer -> scale );
1911+ glUniform2i (uniforms [GBA_GL_VS_LOC ], y - firstY + 1 , firstY );
18981912 glDrawArrays (GL_TRIANGLE_FAN , 0 , 4 );
18991913
19001914 glDrawBuffers (1 , (GLenum []) { GL_COLOR_ATTACHMENT0 });
19011915}
19021916
19031917void _prepareTransform (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , const GLuint * uniforms , int y ) {
1904- glScissor (0 , renderer -> firstY * renderer -> scale , GBA_VIDEO_HORIZONTAL_PIXELS * renderer -> scale , renderer -> scale * (y - renderer -> firstY + 1 ));
1905- glUniform2i (uniforms [GBA_GL_VS_LOC ], y - renderer -> firstY + 1 , renderer -> firstY );
1918+ int firstY = renderer -> firstY ;
1919+ if (firstY < background -> enabledAtY ) {
1920+ firstY = background -> enabledAtY ;
1921+ }
1922+ glScissor (0 , firstY * renderer -> scale , GBA_VIDEO_HORIZONTAL_PIXELS * renderer -> scale , renderer -> scale * (y - firstY + 1 ));
1923+ glUniform2i (uniforms [GBA_GL_VS_LOC ], y - firstY + 1 , firstY );
19061924 glUniform2i (uniforms [GBA_GL_BG_RANGE ], renderer -> firstAffine , y );
19071925
19081926 glUniform4iv (uniforms [GBA_GL_BG_TRANSFORM ], GBA_VIDEO_VERTICAL_PIXELS , background -> scanlineAffine );
@@ -1912,11 +1930,15 @@ void _prepareTransform(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBac
19121930void GBAVideoGLRendererDrawBackgroundMode2 (struct GBAVideoGLRenderer * renderer , struct GBAVideoGLBackground * background , int y ) {
19131931 const struct GBAVideoGLShader * shader = & renderer -> bgShader [background -> overflow ? 2 : 3 ];
19141932 const GLuint * uniforms = shader -> uniforms ;
1933+ int firstY = renderer -> firstY ;
1934+ if (firstY < background -> enabledAtY ) {
1935+ firstY = background -> enabledAtY ;
1936+ }
19151937 glUseProgram (shader -> program );
19161938 glBindVertexArray (shader -> vao );
19171939 _prepareTransform (renderer , background , uniforms , y );
19181940 glUniform1i (uniforms [GBA_GL_BG_SCREENBASE ], background -> screenBase );
1919- glUniform2i (uniforms [GBA_GL_BG_OLDCHARBASE ], background -> oldCharBase , renderer -> firstY );
1941+ glUniform2i (uniforms [GBA_GL_BG_OLDCHARBASE ], background -> oldCharBase , firstY );
19201942 glUniform1i (uniforms [GBA_GL_BG_CHARBASE ], background -> charBase );
19211943 glUniform1i (uniforms [GBA_GL_BG_SIZE ], background -> size );
19221944 glDrawArrays (GL_TRIANGLE_FAN , 0 , 4 );
0 commit comments