mirror of
https://github.com/mattrberry/crab.git
synced 2024-12-26 09:58:25 +01:00
temp push for changing computers
This commit is contained in:
parent
4cfd5b6fa7
commit
71dba46e8b
4 changed files with 92 additions and 6 deletions
|
@ -81,3 +81,9 @@ macro log(value, newline = true)
|
|||
{% end %}
|
||||
{% end %}
|
||||
end
|
||||
|
||||
struct Slice(T)
|
||||
def [](index : Int, t : R.class, index_r : Int) : R forall R
|
||||
Pointer(R).new((self.to_unsafe + index).address)[index_r]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -325,15 +325,83 @@ module GBA
|
|||
end
|
||||
|
||||
def calculate_color(col : Int) : UInt16
|
||||
enables, effects = get_enables(col)
|
||||
enable_flags, effects_enabled = get_enables(col)
|
||||
top_color = nil
|
||||
colors = uninitialized Color[5]
|
||||
sprite_pixel = @sprite_pixels[col]
|
||||
colors[0] = Color.new(
|
||||
sprite_pixel.priority,
|
||||
sprite_pixel.palette,
|
||||
sprite_pixel.blends,
|
||||
4, # sprites are bit 4 in the enable flags
|
||||
true, # sprite
|
||||
)
|
||||
4.times do |bg|
|
||||
colors[bg + 1] = Color.new(
|
||||
@bgcnt[bg].priority,
|
||||
@layer_palettes[bg][col],
|
||||
true, # backgrounds always blend
|
||||
bg,
|
||||
false, # not a sprite
|
||||
)
|
||||
end
|
||||
4.times do |priority|
|
||||
if bit?(enables, 4)
|
||||
colors.each do |color|
|
||||
if bit?(enable_flags, color.target_bit) # check that layer is enabled
|
||||
if color.priority == priority # check that priority matches (effectively orders backgrounds)
|
||||
if top_color.nil?
|
||||
if color.palette > 0 # check that color is opaque
|
||||
if !effects_enabled || !color.blends # if effects are disabled, always take the first opaque color
|
||||
return BGR16.new(@pram, color).value
|
||||
elsif @bldcnt.is_bg_target(color.target_bit, target: 1)
|
||||
top_color = color
|
||||
end
|
||||
end
|
||||
else # top color has been selected
|
||||
top_color_u16 = BGR16.new(@pram, top_color).value
|
||||
if !@bldcnt.is_bg_target(color.target_bit, target: 2) # second layer isn't set in bldcnt, don't blend
|
||||
return top_color_u16
|
||||
elsif color.palette > 0 # is a target and color is opaque
|
||||
if @bldcnt.blending_mode == 1 || top_color.sprite
|
||||
return (BGR16.new(@pram, top_color) * (Math.min(16, @bldalpha.eva_coefficient) / 16) +
|
||||
BGR16.new(@pram, color) * (Math.min(16, @bldalpha.evb_coefficient) / 16)).value
|
||||
elsif @bldcnt.blending_mode == 0
|
||||
return top_color_u16
|
||||
elsif @bldcnt.blending_mode == 2
|
||||
# blend with white
|
||||
return top_color_u16 # todo
|
||||
elsif @bldcnt.blending_mode == 3
|
||||
# blend with black
|
||||
return top_color_u16 # todo
|
||||
end
|
||||
else # is a target and color is transparent
|
||||
if @bldcnt.blending_mode == 0
|
||||
return top_color_u16
|
||||
elsif @bldcnt.blending_mode == 1
|
||||
return top_color_u16
|
||||
elsif @bldcnt.blending_mode == 2
|
||||
# blend with white
|
||||
return top_color_u16 # todo
|
||||
elsif @bldcnt.blending_mode == 3
|
||||
# blend with black
|
||||
return top_color_u16 # todo
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
backdrop_color = @pram.to_unsafe.as(UInt16*)[0]
|
||||
return top_color.nil? ? backdrop_color : BGR16.new(@pram, top_color).value
|
||||
|
||||
4.times do |priority|
|
||||
if bit?(enable_flags, 4)
|
||||
sprite_pixel = @sprite_pixels[col]
|
||||
if sprite_pixel.priority == priority && sprite_pixel.palette > 0
|
||||
selected_color = (@pram + 0x200).to_unsafe.as(UInt16*)[sprite_pixel.palette]
|
||||
if top_color.nil? # todo: brightness for sprites
|
||||
if !(sprite_pixel.blends || (@bldcnt.is_bg_target(4, target: 1) && effects))
|
||||
if !(sprite_pixel.blends || (@bldcnt.is_bg_target(4, target: 1) && effects_enabled))
|
||||
return selected_color
|
||||
elsif @bldcnt.color_special_effect == 1 # alpha blending
|
||||
top_color = selected_color
|
||||
|
@ -355,13 +423,13 @@ module GBA
|
|||
end
|
||||
end
|
||||
4.times do |bg|
|
||||
if bit?(enables, bg)
|
||||
if bit?(enable_flags, bg)
|
||||
if @bgcnt[bg].priority == priority
|
||||
palette = @layer_palettes[bg][col]
|
||||
next if palette == 0
|
||||
selected_color = @pram.to_unsafe.as(UInt16*)[palette]
|
||||
if top_color.nil?
|
||||
if @bldcnt.color_special_effect == 0 || !@bldcnt.is_bg_target(bg, target: 1) || !effects
|
||||
if @bldcnt.color_special_effect == 0 || !@bldcnt.is_bg_target(bg, target: 1) || !effects_enabled
|
||||
return selected_color
|
||||
elsif @bldcnt.color_special_effect == 1 # alpha blending
|
||||
top_color = selected_color
|
||||
|
@ -427,6 +495,8 @@ module GBA
|
|||
when 0x052..0x053 then @bldalpha.read_byte(io_addr & 1)
|
||||
when 0x054..0x055 then @bldy.read_byte(io_addr & 1)
|
||||
else log "Unmapped PPU read ~ addr:#{hex_str io_addr.to_u8}"; 0_u8 # todo: open bus
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ module GBA
|
|||
bool bg2_2nd_target_pixel
|
||||
bool bg1_2nd_target_pixel
|
||||
bool bg0_2nd_target_pixel
|
||||
num color_special_effect, 2
|
||||
num blending_mode, 2
|
||||
bool bd_1st_target_pixel
|
||||
bool obj_1st_target_pixel
|
||||
bool bg3_1st_target_pixel
|
||||
|
|
|
@ -3,6 +3,10 @@ module GBA
|
|||
alias HalfWord = UInt16
|
||||
alias Word = UInt32
|
||||
alias Words = Slice(UInt32)
|
||||
|
||||
record Color, priority : Int32, palette : Int32, blends : Bool, target_bit : Int32, sprite : Bool do
|
||||
end
|
||||
|
||||
record BGR16, value : UInt16 do # xBBBBBGGGGGRRRRR
|
||||
# Create a new BGR16 struct with the given values. Trucates at 5 bits.
|
||||
def initialize(blue : Number, green : Number, red : Number)
|
||||
|
@ -11,6 +15,12 @@ module GBA
|
|||
(red <= 0x1F ? red.to_u16 : 0x1F_u16)
|
||||
end
|
||||
|
||||
def initialize(pram : Slice(UInt8), color : Color)
|
||||
palette_base = pram.to_unsafe
|
||||
palette_base += 0x200 if color.sprite
|
||||
@value = palette_base.as(UInt16*)[color.palette]
|
||||
end
|
||||
|
||||
def blue : UInt16
|
||||
bits(value, 0xA..0xE)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue