extends ColorRect @onready var main_window = get_tree().root @onready var character := $"vert_align/horiz_align/scale/TextureRect" @onready var osd = $"OSD" @onready var beepplayer := $"Beep" @onready var tapplayer := $"Tap" @onready var vert_align = $"vert_align" @onready var horiz_align = $"vert_align/horiz_align" @onready var scale_node = $"vert_align/horiz_align/scale" var dragging = false var dragging_start_position:Vector2i var old_window_position:Vector2i var signal_offset = false var signal_change = false var signal_beep_num = false var signal_beep_bpm = false var bpm_snap = 1 var character_opacity = 100.0 var numerator = int(GlobalConfig.tempo_numerator) var change_array = [] func _ready() -> void: horiz_align.alignment = GlobalConfig.spritesheet_anchor[0] vert_align.alignment = GlobalConfig.spritesheet_anchor[1] main_window.min_size = Vector2i(100, 100) main_window.size = character.spritesheet_parser.max_dimensions * GlobalConfig.sprite_scale character.scale = Vector2(GlobalConfig.sprite_scale, GlobalConfig.sprite_scale) character_opacity = GlobalConfig.spritesheet_default_opacity * 100 character.flip_h = GlobalConfig.sprite_flip self.color.a = GlobalConfig.background_opacity func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton: if event.get_button_index() == 1: dragging = event.is_pressed() dragging_start_position = DisplayServer.mouse_get_position() old_window_position = main_window.get_position() func _process(_delta: float) -> void: set_default_cursor_shape(Control.CURSOR_DRAG if dragging else Control.CURSOR_ARROW) if dragging: main_window.set_position(old_window_position + (DisplayServer.mouse_get_position() - dragging_start_position)) character.modulate.a = character_opacity / 100 if not GlobalConfig.anim_is_global: _anim_process(Input) if not GlobalConfig.bpm_is_global: _input_functions(Input) func _physics_process(_delta: float) -> void: if GlobalConfig.anim_is_global: _anim_process(GlobalInput) if GlobalConfig.bpm_is_global: _input_functions(GlobalInput) func _input_functions(input) -> void: if GlobalConfig.bpm_needs_enable and not input.is_action_pressed("mod_enable"): return bpm_snap = 1 if input.is_action_pressed("mod_snap_fine"): bpm_snap *= 0.5 if input.is_action_pressed("mod_snap_coarse"): bpm_snap *= 10 if input.is_action_just_pressed("bpm_decrease"): _run_bpmchange(-bpm_snap) _run_offset() if input.is_action_just_pressed("bpm_increase"): _run_bpmchange(bpm_snap) _run_offset() if input.is_action_just_pressed("bpm_opadecrease"): _run_opacitychange(-bpm_snap) if input.is_action_just_pressed("bpm_opaincrease"): _run_opacitychange(bpm_snap) if input.is_action_just_pressed("bpm_reset"): _run_offset() _run_tapper() if input.is_action_just_pressed("bpm_tsdecrease"): _run_numeratorchange(-1) if input.is_action_just_pressed("bpm_tsincrease"): _run_numeratorchange(1) var time = 0.0 func _anim_process(input) -> void: var process_key_input = input.is_action_pressed("mod_enable") or not GlobalConfig.anim_needs_enable var prev_time = time time = Time.get_ticks_msec() for animation in character.anims: if animation.key != null: var kd_before = animation.keydown animation.keydown = process_key_input and input.is_action_pressed(animation.key) if animation.keydown and not kd_before: animation.tstamp = time animation.active = animation.keydown or Tempo.beat_at_time(time - animation.tstamp, character.bpm) <= 1 var prev_active_anim = character.active_anims.front() character.active_anims = character.anims.filter(func(a): return a.active) character.active_anims.sort_custom(func(a, b): return a.tstamp > b.tstamp) var active_anim = character.active_anims.front() if active_anim and active_anim != prev_active_anim: active_anim.tstamp = time func _osd_opacity_change(): osd.show_osd("Character opacity", str(character_opacity) + "%", [ { title = "", icon = "remove", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_opacitychange(-bpm_snap)) }, { title = "", icon = "add", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_opacitychange(bpm_snap)) } ]) func _osd_bpm_change(): osd.show_osd("Tempo", str(character.bpm) + "bpm", [ { title = "", icon = "remove", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_bpmchange(-bpm_snap) _run_offset()) }, { title = "", icon = "touch_app", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_offset() _run_tapper()) }, { title = "", icon = "add", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_bpmchange(bpm_snap) _run_offset()) } ]) func _osd_num_change(): osd.show_osd("Time signature", str(numerator) + "/4", [ { title = "", icon = "remove", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_numeratorchange(-1)) }, { title = "", icon = "add", icon_pos = osd.ICON_POSITION.CENTER, toggles = false, action = (func(): _run_numeratorchange(1)) } ]) func _osd_bpm_reset(): osd.show_osd(str(numerator) + " taps for Tapper", "Sync", [ { title = "Reset/Tap", icon = "touch_app", icon_pos = osd.ICON_POSITION.RIGHT, toggles = false, action = (func(): _run_offset() _run_tapper()) } ]) func _run_opacitychange(delta: float): if character_opacity + delta < 0.0: character_opacity = 0.0 elif character_opacity + delta > 100.0: character_opacity = 100.0 else: character_opacity += delta _osd_opacity_change() func _run_bpmchange(delta: float): if character.bpm + delta < 60.0: character.bpm = 60.0 elif character.bpm + delta > 1000.0: character.bpm = 1000.0 else: character.bpm += delta beepplayer.play(0) _osd_bpm_change() func _run_numeratorchange(delta: int): if numerator + delta < 2: numerator = 2 elif numerator + delta > 16: numerator = 16 else: numerator += delta beepplayer.play(0) _osd_num_change() func _run_offset(): for anim in character.anims: if anim.type == GlobalConfig.SpritesheetAnimType.IDLE: anim.tstamp = Time.get_ticks_msec() func _run_tapper(): var time = Time.get_ticks_msec() if change_array.size() > 0: var last_time = change_array.back() var time_offset = time - last_time if time_offset <= 2000.0: change_array.append(time) else: change_array = [Time.get_ticks_msec()] else: change_array = [Time.get_ticks_msec()] var avg = MathUtils.average(change_array) if change_array.size() >= numerator: character.bpm = floor(Tempo.get_bpm(avg) / bpm_snap) * bpm_snap _osd_bpm_change() else: _osd_bpm_reset() if (change_array.size() - 1) % numerator == 0: tapplayer.pitch_scale = 1.25 else: tapplayer.pitch_scale = 1 tapplayer.play(0)