more cleanup

This commit is contained in:
Colby 2016-07-31 14:13:28 +10:00
parent d632b015c1
commit 322cbffc3c

View file

@ -23,14 +23,11 @@ module Waterfoul
LCDC_Y_COORDINATE_MEM_LOC = 0xFF44 LCDC_Y_COORDINATE_MEM_LOC = 0xFF44
def initialize def initialize
@scanline_transfered = false
@framebuffer = Array.new FRAMEBUFFER_SIZE, 0 @framebuffer = Array.new FRAMEBUFFER_SIZE, 0
@mode = OAM_READ_STATE @mode = OAM_READ_STATE
@modeclock = 0 @modeclock = 0
@auxillary_modeclock = 0 @auxillary_modeclock = 0
@vblank_line = 0 @vblank_line = 0
@window_line = 0
@hide_frames = 0
@screen_enable_delay_cycles = 0 @screen_enable_delay_cycles = 0
end end
@ -42,13 +39,13 @@ module Waterfoul
if IO::LCDControl.screen_enabled? if IO::LCDControl.screen_enabled?
case @mode case @mode
when H_BLANK_STATE when H_BLANK_STATE
hblank hblank if @modeclock >= H_BLANK_TIME
when V_BLANK_STATE when V_BLANK_STATE
vblank vblank
when OAM_READ_STATE when OAM_READ_STATE
oam oam if @modeclock >= OAM_SCANLINE_TIME
when VMRAM_READ_STATE when VMRAM_READ_STATE
vram vram if @modeclock >= VRAM_SCANLINE_TIME
end end
else else
if @screen_enable_delay_cycles > 0 if @screen_enable_delay_cycles > 0
@ -78,163 +75,145 @@ module Waterfoul
private private
def vram def vram
if @modeclock >= VRAM_SCANLINE_TIME @modeclock -= VRAM_SCANLINE_TIME
@modeclock -= VRAM_SCANLINE_TIME @mode = H_BLANK_STATE
@mode = H_BLANK_STATE scanline
scanline update_stat_mode
update_stat_mode end
end
def oam
@modeclock -= OAM_SCANLINE_TIME
@scanline_transfered = false
@mode = VMRAM_READ_STATE
update_stat_mode
end
def hblank
@modeclock -= H_BLANK_TIME
@mode = OAM_READ_STATE
next_line
compare_lylc
if current_line == 144
@mode = V_BLANK_STATE
@auxillary_modeclock = @modeclock
@vblank = true
Interrupt.request_interrupt(Interrupt::INTERRUPT_VBLANK)
end end
def oam update_stat_mode
if @modeclock >= OAM_SCANLINE_TIME end
@modeclock -= OAM_SCANLINE_TIME
@scanline_transfered = false
@mode = VMRAM_READ_STATE
update_stat_mode
end
end
def hblank def vblank
if @modeclock >= H_BLANK_TIME if @auxillary_modeclock >= 456
@modeclock -= H_BLANK_TIME @auxillary_modeclock -= 456
@mode = OAM_READ_STATE @vblank_line += 1
if @vblank_line <= 9
next_line next_line
compare_lylc compare_lylc
if current_line == 144
@mode = V_BLANK_STATE
@vblank_line = 0
@auxillary_modeclock = @modeclock
Interrupt.request_interrupt(Interrupt::INTERRUPT_VBLANK)
if @hide_frames > 0
@hide_frames -= 1
else
@vblank = true
end
@window_line = 0
end
update_stat_mode
end end
end end
def vblank if @modeclock >= V_BLANK_TIME
if @auxillary_modeclock >= 456 @modeclock -= V_BLANK_TIME
@auxillary_modeclock -= 456 @mode = OAM_READ_STATE
@vblank_line += 1 update_stat_mode
reset_current_line
if @vblank_line <= 9 @vblank_line = 0
next_line
compare_lylc
end
end
if @modeclock >= 4104 && @auxillary_modeclock >= 4 && current_line == 153
reset_current_line
end
if @modeclock >= V_BLANK_TIME
@modeclock -= V_BLANK_TIME
@mode = OAM_READ_STATE
update_stat_mode
end
end end
end
def scanline def scanline
render_bg render_bg
end end
def update_stat_mode def update_stat_mode
stat = $mmu.read_byte 0xFF41 stat = $mmu.read_byte 0xFF41
$mmu.write_byte 0xFF41, (stat & 0xFC) | (@mode & 0x3) $mmu.write_byte 0xFF41, (stat & 0xFC) | (@mode & 0x3)
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
if IO::LCDControl.bg_display if IO::LCDControl.bg_display
# tile and map select # tile and map select
tiles_select = IO::LCDControl.bg_tile_select tiles_select = IO::LCDControl.bg_tile_select
map_select = IO::LCDControl.bg_map_select map_select = IO::LCDControl.bg_map_select
# x pixel offset # x pixel offset
scx = $mmu.read_byte 0xFF43 scx = $mmu.read_byte 0xFF43
# y pixel offset # y pixel offset
scy = $mmu.read_byte 0xFF42 scy = $mmu.read_byte 0xFF42
# line with y offset # line with y offset
line_adjusted = (line + scy) & 0xFF line_adjusted = (line + scy) & 0xFF
# get position of tile row to read # get position of tile row to read
y_offset = (line_adjusted / 8) * 32 y_offset = (line_adjusted / 8) * 32
# relative line number in tile # relative line number in tile
tile_line = line_adjusted % 8 tile_line = line_adjusted % 8
# relative line number offset # relative line number offset
tile_line_offset = tile_line * 2 tile_line_offset = tile_line * 2
0.upto(31) do |x| 0.upto(31) do |x|
tile = 0 tile = 0
if tiles_select == 0x8800 if tiles_select == 0x8800
tile = signed_value $mmu.read_byte(map_select + y_offset + x) tile = signed_value $mmu.read_byte(map_select + y_offset + x)
tile += 128 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 - scx
next if buffer_addr >= Screen::SCREEN_WIDTH
pixel = (byte_1 & (0x1 << (7 - pixelx)) > 0) ? 1 : 0
pixel |= (byte_2 & (0x1 << (7 - pixelx)) > 0) ? 2 : 0
position = line_width + buffer_addr
palette = $mmu.read_byte 0xFF47
color = (palette >> (pixel * 2)) & 0x3
@framebuffer[position] = color
end
end
else
0.upto(Screen::SCREEN_WIDTH) do |i|
@framebuffer[line_width + i] = 0
end
end
end
def compare_lylc
unless IO::LCDControl.screen_enabled?
lyc = $mmu.read_byte 0xFF45
stat = $mmu.read_byte 0xFF41
if lyc == current_line
# set BIT 2
stat |= BIT_2
else else
# reset BIT 2 tile = $mmu.read_byte map_select + y_offset + x
state &= BIT_2 ^ 0xFF
end end
$mmu.write_byte 0xFF41, stat 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 - scx
next if buffer_addr >= Screen::SCREEN_WIDTH
pixel = (byte_1 & (0x1 << (7 - pixelx)) > 0) ? 1 : 0
pixel |= (byte_2 & (0x1 << (7 - pixelx)) > 0) ? 2 : 0
position = line_width + buffer_addr
palette = $mmu.read_byte 0xFF47
color = (palette >> (pixel * 2)) & 0x3
@framebuffer[position] = color
end
end
else
0.upto(Screen::SCREEN_WIDTH) do |i|
@framebuffer[line_width + i] = 0
end end
end end
end
def current_line def compare_lylc
$mmu.read_byte LCDC_Y_COORDINATE_MEM_LOC lyc = $mmu.read_byte 0xFF45
stat = $mmu.read_byte 0xFF41
if lyc == current_line
stat |= BIT_2
else
stat = stat & 0xFB
end end
def reset_current_line $mmu.write_byte 0xFF41, stat
$mmu.write_byte LCDC_Y_COORDINATE_MEM_LOC, 0 end
end
def next_line def current_line
$mmu.write_byte LCDC_Y_COORDINATE_MEM_LOC, current_line + 1 $mmu.read_byte LCDC_Y_COORDINATE_MEM_LOC
end end
def reset_current_line
$mmu.write_byte LCDC_Y_COORDINATE_MEM_LOC, 0
end
def next_line
$mmu.write_byte LCDC_Y_COORDINATE_MEM_LOC, current_line + 1
end
end end
end end