mirror of
https://github.com/mattrberry/crab.git
synced 2024-11-16 19:49:30 +01:00
very rough start to affine sprites
This commit is contained in:
parent
99ac277ca0
commit
480f4b181b
1 changed files with 25 additions and 10 deletions
|
@ -167,23 +167,38 @@ class PPU
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_sprites(scanline : Slice(UInt16), row : Int, priority : Int) : Nil
|
def render_sprites(scanline : Slice(UInt16), row : Int, priority : Int) : Nil
|
||||||
# todo: need to touch all of this up at some point for affine sprites
|
|
||||||
base = 0x10000_u32
|
base = 0x10000_u32
|
||||||
Slice(Sprite).new(@oam.to_unsafe.as(Sprite*), 128).each do |sprite|
|
sprites = Slice(Sprite).new(@oam.to_unsafe.as(Sprite*), 128)
|
||||||
|
sprites.each do |sprite|
|
||||||
next unless sprite.priority == priority
|
next unless sprite.priority == priority
|
||||||
next if sprite.obj_shape == 3 # prohibited
|
next if sprite.obj_shape == 3 # prohibited
|
||||||
# Treating these as signed integers to support wrapping. Note: Won't necessarily work for affine sprites. Thanks, Tonc.
|
|
||||||
x_coord, y_coord = (sprite.x_coord << 7).to_i16! >> 7, sprite.y_coord.to_i8!.to_i16!
|
x_coord, y_coord = (sprite.x_coord << 7).to_i16! >> 7, sprite.y_coord.to_i8!.to_i16!
|
||||||
width, height = SIZES[sprite.obj_shape][sprite.obj_size]
|
width, height = SIZES[sprite.obj_shape][sprite.obj_size]
|
||||||
|
if sprite.affine
|
||||||
|
oam_affine_entry = sprite.attr1_bits_9_13
|
||||||
|
# signed 8.8 fixed-point numbers, need to shr 8
|
||||||
|
pa = sprites[oam_affine_entry * 4].aff_param.to_i32
|
||||||
|
pb = sprites[oam_affine_entry * 4 + 1].aff_param.to_i32
|
||||||
|
pc = sprites[oam_affine_entry * 4 + 2].aff_param.to_i32
|
||||||
|
pd = sprites[oam_affine_entry * 4 + 3].aff_param.to_i32
|
||||||
|
if sprite.attr0_bit_9 # double-size (rotated sprites won't clip unless scaled)
|
||||||
|
x_coord += width >> 1
|
||||||
|
y_coord += height >> 1
|
||||||
|
width <<= 1
|
||||||
|
height <<= 1
|
||||||
|
end
|
||||||
|
else # identity matrix if sprite isn't affine (shifted left 8 to match the 8.8 fixed-point)
|
||||||
|
pa, pb, pc, pd = 0x100, 0, 0, 0x100
|
||||||
|
end
|
||||||
if y_coord <= row < y_coord + height
|
if y_coord <= row < y_coord + height
|
||||||
sprite_y = row - y_coord
|
sprite_y = row - y_coord
|
||||||
sprite_y = height - sprite_y - 1 if bit?(sprite.attr1, 13)
|
sprite_y = height - sprite_y - 1 if bit?(sprite.attr1, 13) && !sprite.affine
|
||||||
y = sprite_y & 7
|
y = sprite_y & 7
|
||||||
x_min, x_max = x_coord, Math.min(240, x_coord + width)
|
(x_coord...x_coord + width).each_with_index do |col, sprite_x|
|
||||||
(x_min...x_max).each_with_index do |col, sprite_x|
|
next unless 0 <= col < 240
|
||||||
next if col < 0
|
|
||||||
next if scanline[col] > 0
|
next if scanline[col] > 0
|
||||||
sprite_x = width - sprite_x - 1 if bit?(sprite.attr1, 12)
|
# puts "#{sprite_x},#{sprite_y} #{pa},#{pb},#{pc},#{pd} #{row},#{col} #{sprite.affine}"
|
||||||
|
sprite_x = width - sprite_x - 1 if bit?(sprite.attr1, 12) && !sprite.affine
|
||||||
x = sprite_x & 7
|
x = sprite_x & 7
|
||||||
tile_id = sprite.character_name
|
tile_id = sprite.character_name
|
||||||
if sprite.color_mode # 8bpp
|
if sprite.color_mode # 8bpp
|
||||||
|
@ -353,7 +368,7 @@ SIZES = [
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
record Sprite, attr0 : UInt16, attr1 : UInt16, attr2 : UInt16, unused_space : UInt16 do
|
record Sprite, attr0 : UInt16, attr1 : UInt16, attr2 : UInt16, aff_param : Int16 do
|
||||||
# OBJ Attribute 0
|
# OBJ Attribute 0
|
||||||
|
|
||||||
def obj_shape
|
def obj_shape
|
||||||
|
@ -376,7 +391,7 @@ record Sprite, attr0 : UInt16, attr1 : UInt16, attr2 : UInt16, unused_space : UI
|
||||||
bit?(attr0, 9)
|
bit?(attr0, 9)
|
||||||
end
|
end
|
||||||
|
|
||||||
def scaling_flag
|
def affine
|
||||||
bit?(attr0, 8)
|
bit?(attr0, 8)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue