re-enable drawing sprites and windows

This commit is contained in:
Colby 2016-08-01 20:21:06 +10:00
parent 03de70423b
commit 84c90c4665

View file

@ -29,6 +29,7 @@ module Waterfoul
@vblank_line = 0 @vblank_line = 0
@auxillary_modeclock = 0 @auxillary_modeclock = 0
@screen_enabled = true @screen_enabled = true
@window_line = 0
end end
def step(cycles = 1) def step(cycles = 1)
@ -53,6 +54,7 @@ module Waterfoul
@modeclock = 0 @modeclock = 0
@mode = 0 @mode = 0
@auxillary_modeclock = 0 @auxillary_modeclock = 0
@window_line = 0
reset_current_line reset_current_line
update_stat_mode update_stat_mode
compare_lylc compare_lylc
@ -92,6 +94,7 @@ module Waterfoul
@mode = V_BLANK_STATE @mode = V_BLANK_STATE
@auxillary_modeclock = @modeclock @auxillary_modeclock = @modeclock
@vblank = true @vblank = true
@window_line = 0
Interrupt.request_interrupt(Interrupt::INTERRUPT_VBLANK) Interrupt.request_interrupt(Interrupt::INTERRUPT_VBLANK)
end end
@ -120,6 +123,8 @@ module Waterfoul
def scanline def scanline
render_bg render_bg
render_window
render_sprites
end end
def update_stat_mode def update_stat_mode
@ -128,6 +133,133 @@ module Waterfoul
$mmu.write_byte 0xFF41, new_stat $mmu.write_byte 0xFF41, new_stat
end end
def render_window
line = current_line
line_width = line * Screen::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
return if @window_line > 143 || !IO::LCDControl.window_enabled?
window_pos_x = $mmu.read_byte(0xFF4B) - 7
window_pos_y = $mmu.read_byte(0xFF4A)
# don't render if the window is outside the bounds of the screen
return if window_pos_x > 159 || window_pos_y > 143 || window_pos_y > line
map_select = IO::LCDControl.window_map_select
tiles_select = IO::LCDControl.bg_tile_select
line_adjusted = @window_line
y_offset = (line_adjusted / 8) * 32
tile_line = line_adjusted % 8
tile_line_offset = tile_line * 2
0.upto(31) do |x|
tile = 0
if tiles == 0x8800
tile = signed_value $mmu.read_byte(map_select + y_offset + x)
tile += 128
else
tile = $mmu.read_byte map_select + y_offset + x
end
line_pixel_offset = x * 8
tile_select_offset = tile * 16
tile_address = tiles_select + tile_select_offset + tile_line_offset
byte_1 = $mmu.read_byte tile_address
byte_2 = $mmu.read_byte (tile_address + 1)
0.upto(7) do |pixelx|
buffer_addr = line_pixel_offset + pixelx + wx
next if buffer_addr < 0 || buffer_addr >= SCREEN_WIDTH
shift 0x1 << (7 - pixelx)
pixel = 0
if (byte_1 & shift == shift) && (byte_2 & shift == shift)
pixel = 3
elsif (byte_1 & shift == 0x0) && (byte_2 & shift == shift)
pixel = 1
elsif (byte_1 & shift == shift) && (byte_2 & shift == 0x0)
pixel = 2
elsif (byte_1 & shift == 0x0) && (byte_2 & shift == 0x00)
pixel = 0
end
position = line_width + buffer_addr
@framebuffer[position] = pixel
end
end
@window_line += 1
end
def render_sprites
line = current_line
line_width = line * Screen::SCREEN_WIDTH
return unless IO::LCDControl.obj_display
sprite_size = IO::LCDControl.obj_size
39.downto(0) do |sprite|
sprite_offset = sprite * 4
sprite_y = $mmu.read_byte(0xFE00 + sprite_offset) - 16
next if sprite_y > line || (sprite_y + sprite_size) <= line
sprite_x = $mmu.read_byte(0xFE00 + sprite_offset + 1) - 8
next if sprite_x < -7 || sprite_x >= SCREEN_WIDTH
sprite_tile_offset = ($mmu.read_byte(0xFE00 + sprite_offset + 2) & (sprite_size == 16 ? 0xFE : 0xFF)) * 16
sprite_flags = $mmu.read_byte(0xFE00 + sprite_offset + 3)
x_flip = sprite_flags & 0x20 == 0x20 ? true : false
y_flip = sprite_flags & 0x40 == 0x40 ? true : false
#above_bg = sprite_flags & 0x80 == 0x80 ? true : false
tiles = 0x8000
pixel_y = y_flip ? (sprite_size == 16 ? 15 : 7) - (line - sprite_y) : line - sprite_y
pixel_y_2 = 0
offset = 0
if sprite_size == 16 && (pixel_y >= 8)
pixel_y_2 = (pixel_y - 8) * 2
offset = 16
else
pixel_y_2 = pixel_y * 2
end
tile_address = tiles + sprite_tile_offset + pixel_y_2 + offset
byte_1 = $mmu.read_byte tile_address
byte_2 = $mmu.read_byte (tile_address + 1)
0.upto(7) do |pixelx|
shift = 0x1 << (x_flip ? pixelx : 7 - pixelx)
pixel = 0
if (byte_1 & shift == shift) && (byte_2 & shift == shift)
pixel = 3
elsif (byte_1 & shift == 0x0) && (byte_2 & shift == shift)
pixel = 1
elsif (byte_1 & shift == shift) && (byte_2 & shift == 0x0)
pixel = 2
elsif (byte_1 & shift == 0x0) && (byte_2 & shift == 0x00)
pixel = 0
end
buffer_x = sprite_x + pixelx
next if buffer_x < 0 || buffer_x >= Screen::SCREEN_WIDTH
position = line_width + buffer_x
@framebuffer[position] = pixel
end
end
end
def render_bg def render_bg
line = current_line line = current_line
line_width = line * Screen::SCREEN_WIDTH line_width = line * Screen::SCREEN_WIDTH