Exemple #1
0
    def render_background(self, line: int):
        line_width = (Window.SCREEN_HEIGHT - line - 1) * Window.SCREEN_WIDTH

        if self.lcdControlRegister.bg_window_display_priority():
            # tile and map select
            tiles_select = self.lcdControlRegister.bg_and_window_tile_data_select(
            )
            map_select = self.lcdControlRegister.bg_tile_map_display_select()
            # x pixel offset
            scx = self.mmu.read_byte(IO_Registers.SCX)
            # y pixel offset
            scy = self.mmu.read_byte(IO_Registers.SCY)
            # line with y offset
            line_adjusted = (line + scy) & 0xff
            # get position of tile row to read
            y_offset = int(line_adjusted / 8) * 32
            # relative line number in tile
            tile_line = line_adjusted % 8
            # relative line number offset
            tile_line_offset = tile_line * 2
            palette = self.mmu.read_byte(IO_Registers.BGP)
            x = 0
            while x < 32:
                tile = 0
                if tiles_select == 0x8800:
                    tile = signed_value(
                        self.mmu.read_byte(map_select + y_offset + x))
                    tile += 128
                else:
                    tile = self.mmu.read_byte(map_select + y_offset + x)
                line_pixel_offset = x * 8
                tile_select_offset = tile * 16
                tile_address = tiles_select + tile_select_offset + tile_line_offset
                byte_1 = self.mmu.read_byte(tile_address)
                byte_2 = self.mmu.read_byte(tile_address + 1)
                pixelx = 0
                buffer_addr = (line_pixel_offset - scx)
                while pixelx < 8:
                    buffer_addr = buffer_addr & 0xff
                    shift = 0x1 << (7 - pixelx)
                    pixel = 1 if (byte_1 & shift > 0) else 0
                    pixel |= 2 if (byte_2 & shift > 0) else 0
                    color = (palette >> (pixel * 2)) & 0x3
                    pixelx += 1
                    if 0 <= buffer_addr < Window.SCREEN_WIDTH:
                        position = line_width + buffer_addr
                        self.framebuffer[position] = self.rgb(color)
                        buffer_addr = (line_pixel_offset + pixelx - scx)
                x += 1
        else:
            for i in range(0, Window.SCREEN_WIDTH):
                self.framebuffer[line_width + i] = self.rgb(0)
Exemple #2
0
    def render_window(cls, line : int):
        line_width = (Window.SCREEN_HEIGHT - line -1) * Window.SCREEN_WIDTH
        # dont render if the window is outside the bounds of the screen or
        # if the LCDC window enable bit flag is not set
        if cls.window_line > 143 or not LCDControlRegister.window_display_enable(cls.lcdc):
            return

        window_pos_x = cls.wx - 7
        window_pos_y = cls.wy

        # don't render if the window is outside the bounds of the screen
        if window_pos_x > 159 or window_pos_y > 143 or window_pos_y > line:
            return 

        tiles_select = LCDControlRegister.bg_and_window_tile_data_select(cls.lcdc)
        map_select = LCDControlRegister.window_tile_map_display_select(cls.lcdc)

        line_adjusted = cls.window_line
        y_offset = (line_adjusted // 8) * 32
        tile_line = line_adjusted % 8
        tile_line_offset = tile_line * 2

        for x in range(32):
            tile = 0
            if tiles_select == 0x800:
                tile = signed_value(cls.vram[0][map_select + y_offset + x])
                tile += 128
            else:
                tile = cls.vram[0][map_select + y_offset + x]
            
            line_pixel_offset = x * 8
            tile_select_offset = tile * 16
            tile_address = tiles_select + tile_select_offset + tile_line_offset
            

            
            tile_attributes = TileAttributes(cls.vram[1][map_select + y_offset + x])
            
            if not cls.cgb_mode:
                byte_1 = cls.vram[0][tile_address]
                byte_2 = cls.vram[0][tile_address + 1]
            else:
                if tile_attributes.is_vertical_flip():
                    tile_address = tile_address - tile_line_offset + ( 7 - tile_line ) * 2
                byte_1 = cls.vram[tile_attributes.get_vram_bank()][tile_address]
                byte_2 = cls.vram[tile_attributes.get_vram_bank()][tile_address + 1]
                if tile_attributes.is_horizontal_flip():
                    byte_1 = flip_byte(byte_1)
                    byte_2 = flip_byte(byte_2)


            for pixelx in range(8):
                buffer_addr = line_pixel_offset + pixelx + window_pos_x

                if buffer_addr < 0 or buffer_addr >= Window.SCREEN_WIDTH:
                    continue

                shift = 0x1 << (7 - pixelx)

                pixel = 0
                if (byte_1 & shift == shift) and (byte_2 & shift == shift):
                    pixel = 3
                elif (byte_1 & shift == 0x0) and (byte_2 & shift == shift):
                    pixel = 2
                elif (byte_1 & shift == shift) and (byte_2 & shift == 0x0):
                    pixel = 1
                elif (byte_1 & shift == 0x0) and (byte_2 & shift == 0x00):
                    pixel = 0
                position = line_width + buffer_addr
                color = (cls.bgp >> (pixel * 2)) & 0x3
                if not cls.cgb_mode:
                    Window.framebuffer[position] = cls.rgb(color)
                    cls.original_color[position] = color
                else:
                    if cls.mmu.bootstrap_enabled or cls.mmu.rom.is_cgb():
                        color = pixel
                    Window.framebuffer[position] = cls.mmu.cgb_palette.get_bg_rgba_palette_color(tile_attributes.get_palette(), color)
                    cls.bg_priority[position] = tile_attributes.is_bg_priority()
                    cls.original_color[position] = color

        cls.window_line += 1
Exemple #3
0
    def render_background(cls, line : int):
        line_width = (Window.SCREEN_HEIGHT - line -1) * Window.SCREEN_WIDTH

        if LCDControlRegister.bg_window_display_priority(cls.lcdc):
            # tile and map select
            tiles_select = LCDControlRegister.bg_and_window_tile_data_select(cls.lcdc)
            map_select = LCDControlRegister.bg_tile_map_display_select(cls.lcdc)
            # line with y offset
            line_adjusted = (line + cls.scy) & 0xff
            # get position of tile row to read
            y_offset = (line_adjusted // 8) * 32
            # relative line number in tile
            tile_line = line_adjusted % 8
            # relative line number offset
            tile_line_offset = tile_line * 2
            x = 0
            while x < 32:
                tile = 0
                if tiles_select == 0x800:
                    tile = signed_value(cls.vram[0][map_select + y_offset + x])
                    tile += 128
                else:
                    tile = cls.vram[0][map_select + y_offset + x]
                    

                line_pixel_offset = x * 8
                tile_select_offset = tile * 16
                tile_address = tiles_select + tile_select_offset + tile_line_offset

                
                
                if not cls.cgb_mode:
                    byte_1 = cls.vram[0][tile_address]
                    byte_2 = cls.vram[0][tile_address + 1]
                else:
                    tile_attributes = TileAttributes(cls.vram[0][map_select + y_offset + x])
                    if tile_attributes.is_vertical_flip():
                        tile_address = tile_address - tile_line_offset + ( 7 - tile_line ) * 2
                    byte_1 = cls.vram[tile_attributes.get_vram_bank()][tile_address]
                    byte_2 = cls.vram[tile_attributes.get_vram_bank()][tile_address + 1]
                    if tile_attributes.is_horizontal_flip():
                        byte_1 = flip_byte(byte_1)
                        byte_2 = flip_byte(byte_2)

                pixelx = 0
                buffer_addr = (line_pixel_offset - cls.scx)
                while pixelx < 8:

                    shift = 0x1 << (7 - pixelx)
                    pixelx += 1

                    buffer_addr &= 0xff

                    if 0 <= buffer_addr < Window.SCREEN_WIDTH:

                        pixel = 1 if (byte_1 & shift > 0) else 0
                        pixel |= 2 if (byte_2 & shift > 0) else 0
                        color = (cls.bgp >> (pixel * 2)) & 0x3
                        

                        position = line_width + buffer_addr % Window.SCREEN_WIDTH
                        cls.original_color[position] = color
                        if not cls.cgb_mode:
                            Window.framebuffer[position] = cls.rgb(color)
                            
                        else:
                            """
                            if cls.mmu.bootstrap_enabled or cls.mmu.rom.is_cgb():
                                color = pixel
                            """
                            
                            #Window.framebuffer[position] = cls.mmu.cgb_palette.get_bg_rgba_palette_color(tile_attributes.get_palette(), color)
                            Window.framebuffer[position] = cls.rgb(color) #FIXME
                            
                            cls.bg_priority[position] = tile_attributes.is_bg_priority()
                            
                    buffer_addr = ( line_pixel_offset + pixelx - cls.scx )
                            
                x += 1
        else:
            for i in range(0, Window.SCREEN_WIDTH):
                Window.framebuffer[line_width + i] = cls.rgb(0)
                cls.original_color[line_width + i] = 0
Exemple #4
0
    def render_window(self, line: int):
        line_width = (Window.SCREEN_HEIGHT - line - 1) * Window.SCREEN_WIDTH
        # dont render if the window is outside the bounds of the screen or
        # if the LCDC window enable bit flag is not set
        if self.window_line > 143 or not self.lcdControlRegister.window_display_enable(
        ):
            return

        window_pos_x = self.mmu.read_byte(IO_Registers.WX) - 7
        window_pos_y = self.mmu.read_byte(IO_Registers.WY)

        # don't render if the window is outside the bounds of the screen
        if window_pos_x > 159 or window_pos_y > 143 or window_pos_y > line:
            return

        tiles_select = self.lcdControlRegister.bg_and_window_tile_data_select()
        map_select = self.lcdControlRegister.window_tile_map_display_select()

        line_adjusted = self.window_line
        y_offset = int(line_adjusted / 8) * 32
        tile_line = line_adjusted % 8
        tile_line_offset = tile_line * 2

        for x in range(32):
            tile = 0
            if tiles_select == 0x8800:
                tile = signed_value(
                    self.mmu.vram.read_value(map_select + y_offset + x, 0))
                tile += 128
            else:
                tile = self.mmu.vram.read_value(map_select + y_offset + x, 0)

            line_pixel_offset = x * 8
            tile_select_offset = tile * 16
            tile_address = tiles_select + tile_select_offset + tile_line_offset

            tile_attributes = TileAttributes(
                self.mmu.vram.read_value(map_select + y_offset + x, 1))

            if not self.cgb_mode:
                byte_1 = self.mmu.read_byte(tile_address)
                byte_2 = self.mmu.read_byte(tile_address + 1)
            else:
                if tile_attributes.is_vertical_flip():
                    tile_address = tile_address - tile_line_offset + (
                        7 - tile_line) * 2
                byte_1 = self.mmu.vram.read_value(
                    tile_address, tile_attributes.get_vram_bank())
                byte_2 = self.mmu.vram.read_value(
                    tile_address + 1, tile_attributes.get_vram_bank())
                if tile_attributes.is_horizontal_flip():
                    byte_1 = flip_byte(byte_1)
                    byte_2 = flip_byte(byte_2)

            palette = self.mmu.read_byte(IO_Registers.BGP)

            for pixelx in range(8):
                buffer_addr = line_pixel_offset + pixelx + window_pos_x

                if buffer_addr < 0 or buffer_addr >= Window.SCREEN_WIDTH:
                    continue

                shift = 0x1 << (7 - pixelx)

                pixel = 0
                if (byte_1 & shift == shift) and (byte_2 & shift == shift):
                    pixel = 3
                elif (byte_1 & shift == 0x0) and (byte_2 & shift == shift):
                    pixel = 2
                elif (byte_1 & shift == shift) and (byte_2 & shift == 0x0):
                    pixel = 1
                elif (byte_1 & shift == 0x0) and (byte_2 & shift == 0x00):
                    pixel = 0
                position = line_width + buffer_addr
                color = (palette >> (pixel * 2)) & 0x3
                if not self.cgb_mode:
                    self.framebuffer[position] = self.rgb(color)
                    self.original_color[position] = color
                else:
                    if self.mmu.bootstrap_enabled or self.mmu.rom.is_cgb():
                        color = pixel
                    self.framebuffer[
                        position] = self.mmu.cgb_palette.get_bg_rgba_palette_color(
                            tile_attributes.get_palette(), color)
                    self.bg_priority[
                        position] = tile_attributes.is_bg_priority()
                    self.original_color[position] = color

        self.window_line += 1
Exemple #5
0
    def render_background(self, line: int):
        line_width = (Window.SCREEN_HEIGHT - line - 1) * Window.SCREEN_WIDTH

        if self.lcdControlRegister.bg_window_display_priority():
            # tile and map select
            tiles_select = self.lcdControlRegister.bg_and_window_tile_data_select(
            )
            map_select = self.lcdControlRegister.bg_tile_map_display_select()
            # x pixel offset
            scx = self.mmu.read_byte(IO_Registers.SCX)
            # y pixel offset
            scy = self.mmu.read_byte(IO_Registers.SCY)
            # line with y offset
            line_adjusted = (line + scy) & 0xff
            # get position of tile row to read
            y_offset = int(line_adjusted / 8) * 32
            # relative line number in tile
            tile_line = line_adjusted % 8
            # relative line number offset
            tile_line_offset = tile_line * 2
            palette = self.mmu.read_byte(IO_Registers.BGP)
            x = 0
            while x < 32:
                tile = 0
                if tiles_select == 0x8800:
                    tile = signed_value(
                        self.mmu.vram.read_value(map_select + y_offset + x, 0))
                    tile += 128
                else:
                    tile = self.mmu.vram.read_value(map_select + y_offset + x,
                                                    0)

                line_pixel_offset = x * 8
                tile_select_offset = tile * 16
                tile_address = tiles_select + tile_select_offset + tile_line_offset

                tile_attributes = TileAttributes(
                    self.mmu.vram.read_value(map_select + y_offset + x, 1))

                if not self.cgb_mode:
                    byte_1 = self.mmu.read_byte(tile_address)
                    byte_2 = self.mmu.read_byte(tile_address + 1)
                else:
                    if tile_attributes.is_vertical_flip():
                        tile_address = tile_address - tile_line_offset + (
                            7 - tile_line) * 2
                    byte_1 = self.mmu.vram.read_value(
                        tile_address, tile_attributes.get_vram_bank())
                    byte_2 = self.mmu.vram.read_value(
                        tile_address + 1, tile_attributes.get_vram_bank())
                    if tile_attributes.is_horizontal_flip():
                        byte_1 = flip_byte(byte_1)
                        byte_2 = flip_byte(byte_2)

                pixelx = 0
                buffer_addr = (line_pixel_offset - scx)
                while pixelx < 8:

                    shift = 0x1 << (7 - pixelx)
                    pixelx += 1

                    buffer_addr &= 0xff

                    if 0 <= buffer_addr < Window.SCREEN_WIDTH:

                        pixel = 1 if (byte_1 & shift > 0) else 0
                        pixel |= 2 if (byte_2 & shift > 0) else 0
                        color = (palette >> (pixel * 2)) & 0x3

                        position = line_width + buffer_addr % Window.SCREEN_WIDTH
                        self.original_color[position] = color
                        if not self.cgb_mode:
                            self.framebuffer[position] = self.rgb(color)
                        else:
                            if self.mmu.bootstrap_enabled or self.mmu.rom.is_cgb(
                            ):
                                color = pixel
                            self.framebuffer[
                                position] = self.mmu.cgb_palette.get_bg_rgba_palette_color(
                                    tile_attributes.get_palette(), color)
                            self.bg_priority[
                                position] = tile_attributes.is_bg_priority()

                    buffer_addr = (line_pixel_offset + pixelx - scx)

                x += 1
        else:
            for i in range(0, Window.SCREEN_WIDTH):
                self.framebuffer[line_width + i] = self.rgb(0)
                self.original_color[line_width + i] = 0
Exemple #6
0
    def render_window(self, line: int):
        line_width = (Window.SCREEN_HEIGHT - line - 1) * Window.SCREEN_WIDTH
        # dont render if the window is outside the bounds of the screen or
        # if the LCDC window enable bit flag is not set
        if self.window_line > 143 or not self.lcdControlRegister.window_display_enable(
        ):
            return

        window_pos_x = self.mmu.read_byte(IO_Registers.WX) - 7
        window_pos_y = self.mmu.read_byte(IO_Registers.WY)

        # don't render if the window is outside the bounds of the screen
        if window_pos_x > 159 or window_pos_y > 143 or window_pos_y > line:
            return

        tiles_select = self.lcdControlRegister.bg_and_window_tile_data_select()
        map_select = self.lcdControlRegister.window_tile_map_display_select()

        line_adjusted = self.window_line
        y_offset = int(line_adjusted / 8) * 32
        tile_line = line_adjusted % 8
        tile_line_offset = tile_line * 2

        for x in range(0, 32):
            tile = 0
            if tiles_select == 0x8800:
                tile = signed_value(
                    self.mmu.read_byte(map_select + y_offset + x))
                tile += 128
            else:
                tile = self.mmu.read_byte(map_select + y_offset + x)
            line_pixel_offset = x * 8
            tile_select_offset = tile * 16
            tile_address = tiles_select + tile_select_offset + tile_line_offset

            byte_1 = self.mmu.read_byte(tile_address)
            byte_2 = self.mmu.read_byte(tile_address + 1)

            palette = self.mmu.read_byte(IO_Registers.BGP)

            for pixelx in range(0, 8):
                buffer_addr = line_pixel_offset + pixelx + window_pos_x

                if buffer_addr < 0 or buffer_addr >= Window.SCREEN_WIDTH:
                    continue

                shift = 0x1 << (7 - pixelx)

                pixel = 0
                if (byte_1 & shift == shift) and (byte_2 & shift == shift):
                    pixel = 3
                elif (byte_1 & shift == 0x0) and (byte_2 & shift == shift):
                    pixel = 2
                elif (byte_1 & shift == shift) and (byte_2 & shift == 0x0):
                    pixel = 1
                elif (byte_1 & shift == 0x0) and (byte_2 & shift == 0x00):
                    pixel = 0
                position = line_width + buffer_addr
                color = (palette >> (pixel * 2)) & 0x3
                self.framebuffer[position] = self.rgb(color)

        self.window_line += 1