mirror of
https://github.com/mattrberry/crab.git
synced 2025-01-19 10:26:44 +01:00
basic sprite implementation
This commit is contained in:
parent
8d34375d72
commit
0c5be3a7ed
1 changed files with 113 additions and 1 deletions
114
src/crab/ppu.cr
114
src/crab/ppu.cr
|
@ -77,6 +77,7 @@ class PPU
|
|||
case @dispcnt.bg_mode
|
||||
when 0
|
||||
4.times do |priority|
|
||||
render_sprites(scanline, row, priority)
|
||||
4.times do |bg|
|
||||
render_background(scanline, row, bg) if @bgcnt[bg].priority == priority
|
||||
end
|
||||
|
@ -138,13 +139,13 @@ class PPU
|
|||
screen_entry = @vram[screen_base + se_idx * 2 + 1].to_u16 << 8 | @vram[screen_base + se_idx * 2]
|
||||
|
||||
tile_id = bits(screen_entry, 0..9)
|
||||
palette_bank = bits(screen_entry, 12..15)
|
||||
y = (effective_row & 7) ^ (7 * (screen_entry >> 11 & 1))
|
||||
x = (effective_col & 7) ^ (7 * (screen_entry >> 10 & 1))
|
||||
|
||||
if @bgcnt[bg].color_mode # 8bpp
|
||||
pal_idx = @vram[character_base + tile_id * 0x40 + y * 8 + x]
|
||||
else # 4bpp
|
||||
palette_bank = bits(screen_entry, 12..15)
|
||||
palettes = @vram[character_base + tile_id * 0x20 + y * 4 + (x >> 1)]
|
||||
pal_idx = (palette_bank << 4) + ((palettes >> ((x & 1) * 4)) & 0xF)
|
||||
end
|
||||
|
@ -152,6 +153,35 @@ class PPU
|
|||
end
|
||||
end
|
||||
|
||||
def render_sprites(scanline : Slice(UInt16), row : Int, priority : Int) : Nil
|
||||
base = 0x10000_u32
|
||||
Slice(Sprite).new(@oam.to_unsafe.as(Sprite*), 128).each do |sprite|
|
||||
next unless sprite.priority == priority
|
||||
next if sprite.obj_shape == 3 # prohibited
|
||||
width, height = SIZES[sprite.obj_shape][sprite.obj_size]
|
||||
if sprite.y_coord <= row < sprite.y_coord + height
|
||||
sprite_y = row - sprite.y_coord
|
||||
y = sprite_y & 7
|
||||
x_min, x_max = sprite.x_coord, Math.min(240, sprite.x_coord + width)
|
||||
(x_min...x_max).each_with_index do |col, sprite_x|
|
||||
next if scanline[col] > 0
|
||||
x = sprite_x & 7
|
||||
tile_id = sprite.character_name
|
||||
if @dispcnt.obj_character_vram_mapping
|
||||
tile_id += (sprite_y >> 3) * (width >> 3)
|
||||
tile_id += sprite_x >> 3
|
||||
else
|
||||
tile_id += (sprite_y >> 3) * 0x20
|
||||
tile_id += sprite_x >> 3
|
||||
end
|
||||
palettes = @vram[base + tile_id * 0x20 + y * 4 + (x >> 1)]
|
||||
pal_idx = (sprite.palette_number << 4) + ((palettes >> ((x & 1) * 4)) & 0xF)
|
||||
scanline[col] = (@pram.to_unsafe + 0x200).as(UInt16*)[pal_idx]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_io(io_addr : Int) : Byte
|
||||
case io_addr
|
||||
when 0x000..0x001 then @dispcnt.read_byte(io_addr & 1)
|
||||
|
@ -228,3 +258,85 @@ class PPU
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# SIZES[SHAPE][SIZE]
|
||||
SIZES = [
|
||||
[ # square
|
||||
{8, 8},
|
||||
{16, 16},
|
||||
{32, 32},
|
||||
{64, 64},
|
||||
],
|
||||
[ # horizontal rectangle
|
||||
{16, 8},
|
||||
{32, 8},
|
||||
{32, 16},
|
||||
{64, 32},
|
||||
],
|
||||
[ # vertical rectangle
|
||||
{8, 16},
|
||||
{8, 32},
|
||||
{16, 32},
|
||||
{32, 64},
|
||||
],
|
||||
]
|
||||
|
||||
record Sprite, attr0 : UInt16, attr1 : UInt16, attr2 : UInt16, unused_space : UInt16 do
|
||||
# OBJ Attribute 0
|
||||
|
||||
def obj_shape
|
||||
bits(attr0, 14..15)
|
||||
end
|
||||
|
||||
def colors
|
||||
bit?(attr0, 13)
|
||||
end
|
||||
|
||||
def obj_mosaic
|
||||
bit?(attr0, 12)
|
||||
end
|
||||
|
||||
def obj_mode
|
||||
bits(attr0, 10..11)
|
||||
end
|
||||
|
||||
def attr0_bit_9
|
||||
bit?(attr0, 9)
|
||||
end
|
||||
|
||||
def scaling_flag
|
||||
bit?(attr0, 8)
|
||||
end
|
||||
|
||||
def y_coord
|
||||
bits(attr0, 0..7)
|
||||
end
|
||||
|
||||
# OBJ Attribute 1
|
||||
|
||||
def obj_size
|
||||
bits(attr1, 14..15)
|
||||
end
|
||||
|
||||
def attr1_bits_9_13
|
||||
bits(attr1, 9..13)
|
||||
end
|
||||
|
||||
def x_coord
|
||||
bits(attr1, 0..8)
|
||||
end
|
||||
|
||||
# OBJ Attribute 2
|
||||
|
||||
def character_name
|
||||
bits(attr2, 0..9)
|
||||
end
|
||||
|
||||
def priority
|
||||
bits(attr2, 10..11)
|
||||
end
|
||||
|
||||
def palette_number
|
||||
bits(attr2, 12..15)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue