Skip to content

Commit

Permalink
Add support for GBA sprite frame type with separate hitbox and hurtbox
Browse files Browse the repository at this point in the history
  • Loading branch information
LagoLunatic committed Jan 19, 2022
1 parent f52015e commit 6d826ee
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
17 changes: 10 additions & 7 deletions dsvedit/sprite_editor_dialog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

class SpriteEditor < Qt::Dialog
RED_PEN_COLOR = Qt::Pen.new(Qt::Color.new(255, 0, 0))
GREEN_PEN_COLOR = Qt::Pen.new(Qt::Color.new(0, 255, 0))
GREY_PEN_COLOR = Qt::Pen.new(Qt::Color.new(128, 128, 128))

attr_reader :game, :fs
Expand Down Expand Up @@ -695,7 +696,7 @@ def frame_changed(i, do_not_change_current_part: false)
@ui.frame_number_of_parts.text = "%02X" % frame.part_indexes.length

if @ui.show_hitbox.checked
frame.hitboxes.each do |hitbox|
frame.hitboxes.each_with_index do |hitbox, i|
hitbox_item = Qt::GraphicsRectItem.new
hitbox_item.setPen(RED_PEN_COLOR)
hitbox_item.setRect(hitbox.x_pos, hitbox.y_pos, hitbox.width, hitbox.height)
Expand All @@ -705,12 +706,14 @@ def frame_changed(i, do_not_change_current_part: false)
# Also handle hitboxes stored in the animation itself (used by HoD).
if SYSTEM == :gba && !@current_animation.nil?
frame_delay = @current_animation.frame_delays[@current_animation_frame_index]
if frame_delay.frame_index == @current_frame_index && !frame_delay.hitbox.nil?
hitbox = frame_delay.hitbox
hitbox_item = Qt::GraphicsRectItem.new
hitbox_item.setPen(RED_PEN_COLOR)
hitbox_item.setRect(hitbox.x_pos, hitbox.y_pos, hitbox.width, hitbox.height)
@frame_graphics_scene.addItem(hitbox_item)
if frame_delay.frame_index == @current_frame_index
frame_delay.hitboxes.each_with_index do |hitbox, i|
hitbox_item = Qt::GraphicsRectItem.new
hitbox_item.setPen(RED_PEN_COLOR) if i == 0
hitbox_item.setPen(GREEN_PEN_COLOR) if i == 1
hitbox_item.setRect(hitbox.x_pos, hitbox.y_pos, hitbox.width, hitbox.height)
@frame_graphics_scene.addItem(hitbox_item)
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions dsvlib/darkfunction_interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ def self.export(output_path, name, sprite_info, fs, renderer, transparent_trails
xml.anim(:name => hash[:name], :loops => 0) {
hash[:frame_delays].each_with_index do |frame_delay, i|
# TODO: save animation's GBA function index
# TODO: save animation's GBA hitboxes
xml.cell(:index => "%02X" % i,
:delay => frame_delay.delay
) {
Expand Down
23 changes: 15 additions & 8 deletions dsvlib/sprite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -918,11 +918,11 @@ class FrameDelay
attr_accessor :frame_index,
:delay,
:unknown,
:hitbox
:hitboxes

def initialize
@frame_index = @delay = @unknown = 0
@hitbox = nil
@hitboxes = []
end

def from_data(frame_delay_data)
Expand Down Expand Up @@ -991,14 +991,16 @@ def self.data_size
class FrameDelayGBAType2 < FrameDelay
def from_data(frame_delay_data)
@frame_index, @delay = frame_delay_data[0,4].unpack("vv")

@hitboxes = []
hitbox_data = frame_delay_data[4,4]
@hitbox = Hitbox.new.from_data(hitbox_data)
@hitboxes << Hitbox.new.from_data(hitbox_data)

return self
end

def to_data
[@frame_index, @delay].pack("vv") + @hitbox.to_data
[@frame_index, @delay].pack("vv") + @hitboxes.first.to_data
end

def self.data_size
Expand All @@ -1008,15 +1010,19 @@ def self.data_size

class FrameDelayGBAType3 < FrameDelay
def from_data(frame_delay_data)
@frame_index, @delay, @unknown = frame_delay_data[0,8].unpack("vvV")
hitbox_data = frame_delay_data[8,4]
@hitbox = Hitbox.new.from_data(hitbox_data)
@frame_index, @delay, @unknown = frame_delay_data[0,4].unpack("vv")

@hitboxes = []
hitbox_data = frame_delay_data[4,4]
hurtbox_data = frame_delay_data[8,4]
@hitboxes << Hitbox.new.from_data(hitbox_data)
@hitboxes << Hitbox.new.from_data(hurtbox_data)

return self
end

def to_data
[@frame_index, @delay, @unknown].pack("vvV") + @hitbox.to_data
[@frame_index, @delay].pack("vv") + @hitboxes[0].to_data + @hitboxes[1].to_data
end

def self.data_size
Expand Down Expand Up @@ -1048,6 +1054,7 @@ def from_data(animation_data, offset=nil)
case @function_index
#when 0
# TODO need to read from FS to get the first_frame_delay_offset pointer
# @first_frame_delay_offset = fs.read(offset + 4, 4).unpack("V").first
when 1..3
@first_frame_delay_offset = offset + 4
else
Expand Down

0 comments on commit 6d826ee

Please sign in to comment.