mirror of
https://github.com/mattrberry/crab.git
synced 2024-11-16 19:49:30 +01:00
affine sprites seem to be working in emerald / tonc obj_aff
This commit is contained in:
parent
ea2d4ce50e
commit
e6035a9c01
1 changed files with 18 additions and 24 deletions
|
@ -173,7 +173,9 @@ class PPU
|
|||
next unless sprite.priority == priority
|
||||
next if sprite.obj_shape == 3 # prohibited
|
||||
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]
|
||||
orig_width, orig_height = SIZES[sprite.obj_shape][sprite.obj_size]
|
||||
width, height = orig_width, orig_height
|
||||
center_x, center_y = x_coord + width // 2, y_coord + height // 2 # off of center
|
||||
if sprite.affine
|
||||
oam_affine_entry = sprite.attr1_bits_9_13
|
||||
# signed 8.8 fixed-point numbers, need to shr 8
|
||||
|
@ -182,8 +184,8 @@ class PPU
|
|||
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
|
||||
center_x += width >> 1
|
||||
center_y += height >> 1
|
||||
width <<= 1
|
||||
height <<= 1
|
||||
end
|
||||
|
@ -191,42 +193,34 @@ class PPU
|
|||
pa, pb, pc, pd = 0x100, 0, 0, 0x100
|
||||
end
|
||||
if y_coord <= row < y_coord + height
|
||||
(x_coord...x_coord + width).each_with_index do |col, sprite_x|
|
||||
next unless 0 <= col < 240
|
||||
iy = row.to_i16 - center_y
|
||||
min_x, max_x = Math.max(0, x_coord), Math.min(240, x_coord + width)
|
||||
(-center_x...center_x).each do |ix|
|
||||
col = center_x + ix
|
||||
next unless min_x <= col < max_x
|
||||
next if scanline[col] > 0
|
||||
sprite_y = row - y_coord
|
||||
|
||||
# at this point, sprite_x and sprite_y represent the x,y coordinates inside the sprite
|
||||
|
||||
# ix,iy have an origin at the center of the sprite
|
||||
ix = sprite_x.to_i32 - (width // 2)
|
||||
iy = sprite_y.to_i32 - (height // 2)
|
||||
# transform to texture coordinates
|
||||
px = (pa * ix + pb * iy) >> 8
|
||||
py = (pc * ix + pd * iy) >> 8
|
||||
# bring origin back to top-left of sprite
|
||||
px += (width // 2)
|
||||
py += (height // 2)
|
||||
# bring origin back to top-left of the sprite
|
||||
px += (orig_width // 2)
|
||||
py += (orig_height // 2)
|
||||
|
||||
next unless 0 <= px < width && 0 <= py < height
|
||||
next unless 0 <= px < orig_width && 0 <= py < orig_height
|
||||
|
||||
px = width - px - 1 if bit?(sprite.attr1, 12) && !sprite.affine
|
||||
py = height - py - 1 if bit?(sprite.attr1, 13) && !sprite.affine
|
||||
px = orig_width - px - 1 if bit?(sprite.attr1, 12) && !sprite.affine
|
||||
py = orig_height - py - 1 if bit?(sprite.attr1, 13) && !sprite.affine
|
||||
|
||||
tile_x = px >> 3
|
||||
tile_y = py >> 3
|
||||
x = px & 7
|
||||
y = py & 7
|
||||
|
||||
# puts "#{sprite_x},#{sprite_y} #{pa},#{pb},#{pc},#{pd} #{row},#{col} #{ix},#{iy} #{px},#{py} #{sprite.affine}"
|
||||
|
||||
tile_id = sprite.character_name
|
||||
if sprite.color_mode # 8bpp
|
||||
tile_id += (px >> 2) + (py >> 3) * (@dispcnt.obj_character_vram_mapping ? width >> 3 : 0x20)
|
||||
tile_id += (px >> 2) + (py >> 3) * (@dispcnt.obj_character_vram_mapping ? orig_width >> 3 : 0x20)
|
||||
tile_id &= ~1 unless @dispcnt.obj_character_vram_mapping # bottom bit is ignored in 2D mapping mode
|
||||
pal_idx = @vram[base + tile_id * 0x20 + y * 8 + x]
|
||||
else # 4bpp
|
||||
tile_id += (px >> 3) + (py >> 3) * (@dispcnt.obj_character_vram_mapping ? width >> 3 : 0x20)
|
||||
tile_id += (px >> 3) + (py >> 3) * (@dispcnt.obj_character_vram_mapping ? orig_width >> 3 : 0x20)
|
||||
palettes = @vram[base + tile_id * 0x20 + y * 4 + (x >> 1)]
|
||||
pal_idx = ((palettes >> ((x & 1) * 4)) & 0xF)
|
||||
pal_idx += (sprite.palette_number << 4) if pal_idx > 0
|
||||
|
|
Loading…
Reference in a new issue