diff --git a/pyboy/core/lcd.py b/pyboy/core/lcd.py index b460f52a0..21b76a77a 100644 --- a/pyboy/core/lcd.py +++ b/pyboy/core/lcd.py @@ -478,12 +478,12 @@ def scanline(self, lcd, y): x += self.scanline_background(y, x, bx, by, wx, lcd) # Window hit - x += self.scanline_window(y, x, wx, wy, COLS - x, lcd) + self.scanline_window(y, x, wx, wy, COLS - x, lcd) elif lcd._LCDC.background_enable: # No window - x += self.scanline_background(y, x, bx, by, COLS, lcd) + self.scanline_background(y, x, bx, by, COLS, lcd) else: - x += self.scanline_blank(y, x, COLS, lcd) + self.scanline_blank(y, x, COLS, lcd) else: if lcd._LCDC.window_enable and wy <= y and wx < COLS: # Before window @@ -491,10 +491,10 @@ def scanline(self, lcd, y): x += self.scanline_background_cgb(y, x, bx, by, wx, lcd) # Window hit - x += self.scanline_window_cgb(y, x, wx, wy, COLS - x, lcd) - else: + self.scanline_window_cgb(y, x, wx, wy, COLS - x, lcd) + else: # background_enable doesn't exist for CGB. It works as master priority instead # No window - x += self.scanline_background_cgb(y, x, bx, by, COLS, lcd) + self.scanline_background_cgb(y, x, bx, by, COLS, lcd) if y == 143: # Reset at the end of a frame. We set it to -1, so it will be 0 after the first increment @@ -502,9 +502,8 @@ def scanline(self, lcd, y): def scanline_window(self, y, _x, wx, wy, cols, lcd): for x in range(_x, _x + cols): - bg_priority_apply = 0 - w_xx = (x-wx) % 8 - if w_xx == 0 or x == 0: + xx = (x-wx) % 8 + if xx == 0 or x == _x: tile_addr = lcd._LCDC.windowmap_offset + (self.ly_window) // 8 * 32 % 0x400 + (x-wx) // 8 % 32 wt = lcd.VRAM0[tile_addr] @@ -514,26 +513,22 @@ def scanline_window(self, y, _x, wx, wy, cols, lcd): # add 256 for offset (reduces to + 128) wt = (wt ^ 0x80) + 128 - w_yy = 8*wt + (self.ly_window) % 8 + yy = 8*wt + (self.ly_window) % 8 self.update_tilecache0(lcd, wt, 0) - xx = w_xx - yy = w_yy - # TODO: Dynamic direct mapping? pixel = lcd.BGP.palette_mem_rgb[lcd.BGP.lookup[self._tilecache0[yy, xx]]] col0 = (self._tilecache0[yy, xx] == 0) & 1 self._screenbuffer[y, x] = pixel # COL0_FLAG is 1 - self._screenbuffer_attributes[y, x] = bg_priority_apply | col0 + self._screenbuffer_attributes[y, x] = col0 return cols def scanline_window_cgb(self, y, _x, wx, wy, cols, lcd): for x in range(_x, _x + cols): - bg_priority_apply = 0 - w_xx = (x-wx) % 8 - if w_xx == 0 or x == 0: + xx = (x-wx) % 8 + if xx == 0 or x == _x: tile_addr = lcd._LCDC.windowmap_offset + (self.ly_window) // 8 * 32 % 0x400 + (x-wx) // 8 % 32 wt = lcd.VRAM0[tile_addr] @@ -543,8 +538,6 @@ def scanline_window_cgb(self, y, _x, wx, wy, cols, lcd): # add 256 for offset (reduces to + 128) wt = (wt ^ 0x80) + 128 - w_yy = 8*wt + (self.ly_window) % 8 - w_palette, w_vbank, w_horiflip, w_vertflip, w_bg_priority = self._cgb_get_background_map_attributes( lcd, tile_addr ) @@ -555,15 +548,16 @@ def scanline_window_cgb(self, y, _x, wx, wy, cols, lcd): self.update_tilecache0(lcd, wt, w_vbank) w_tilecache = self._tilecache0 - xx = w_xx - yy = w_yy + if w_vertflip: + yy = (8*wt + (7 - (self.ly_window) % 8)) + else: + yy = 8*wt + (self.ly_window) % 8 if w_horiflip: xx = 7 - xx - if w_vertflip: - yy = (8*wt + (7 - (self.ly_window) % 8)) pixel = lcd.bcpd.palette_mem_rgb[w_palette*4 + w_tilecache[yy, xx]] + bg_priority_apply = 0 if w_bg_priority: # We hide extra rendering information in the lower 8 bits (A) of the 32-bit RGBA format bg_priority_apply = BG_PRIORITY_FLAG @@ -575,7 +569,6 @@ def scanline_window_cgb(self, y, _x, wx, wy, cols, lcd): return cols def scanline_background(self, y, _x, bx, by, cols, lcd): - # background_enable doesn't exist for CGB. It works as master priority instead for x in range(_x, _x + cols): # bx mask used for the half tile at the left side when scrolling b_xx = (x + (bx & 0b111)) % 8 @@ -604,11 +597,10 @@ def scanline_background(self, y, _x, bx, by, cols, lcd): return cols def scanline_background_cgb(self, y, _x, bx, by, cols, lcd): - # background_enable doesn't exist for CGB. It works as master priority instead for x in range(_x, _x + cols): # bx mask used for the half tile at the left side when scrolling - b_xx = (x + (bx & 0b111)) % 8 - if b_xx == 0 or x == 0: + xx = (x + (bx & 0b111)) % 8 + if xx == 0 or x == 0: tile_addr = lcd._LCDC.backgroundmap_offset + (y+by) // 8 * 32 % 0x400 + (x+bx) // 8 % 32 bt = lcd.VRAM0[tile_addr] @@ -618,8 +610,6 @@ def scanline_background_cgb(self, y, _x, bx, by, cols, lcd): # add 256 for offset (reduces to + 128) bt = (bt ^ 0x80) + 128 - b_yy = 8*bt + (y+by) % 8 - b_palette, b_vbank, b_horiflip, b_vertflip, b_bg_priority = self._cgb_get_background_map_attributes( lcd, tile_addr ) @@ -630,13 +620,13 @@ def scanline_background_cgb(self, y, _x, bx, by, cols, lcd): self.update_tilecache0(lcd, bt, b_vbank) b_tilecache = self._tilecache0 - xx = b_xx - yy = b_yy + if b_vertflip: + yy = (8*bt + (7 - (y+by) % 8)) + else: + yy = 8*bt + (y+by) % 8 if b_horiflip: xx = 7 - xx - if b_vertflip: - yy = (8*bt + (7 - (y+by) % 8)) pixel = lcd.bcpd.palette_mem_rgb[b_palette*4 + b_tilecache[yy, xx]] bg_priority_apply = 0