mirror of
				https://github.com/JHDev2006/Super-Mario-Bros.-Remastered-Public.git
				synced 2025-11-04 08:35:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			197 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			GDScript
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			GDScript
		
	
	
	
	
	
class_name SelectableInputOption
 | 
						|
extends HBoxContainer
 | 
						|
 | 
						|
@export var settings_category := "video"
 | 
						|
@export var selected := false
 | 
						|
@export var can_bind_escape := false
 | 
						|
 | 
						|
@export var action_names := [""]
 | 
						|
@export var title := ""
 | 
						|
 | 
						|
@export_enum("Keyboard", "Controller") var type := 0
 | 
						|
@export var player_idx := 0
 | 
						|
 | 
						|
signal input_changed(action_name: String, input_event: InputEvent)
 | 
						|
 | 
						|
var awaiting_input := false
 | 
						|
 | 
						|
static var rebinding_input := false
 | 
						|
 | 
						|
var event_name := ""
 | 
						|
 | 
						|
var can_remap := true
 | 
						|
 | 
						|
var current_device_brand := 0
 | 
						|
 | 
						|
var current_binding_idx := 0
 | 
						|
 | 
						|
var input_events: Array[InputEvent] = [null, null]
 | 
						|
 | 
						|
const button_id_translation := [
 | 
						|
	["A", "B", "✕"],
 | 
						|
	["B", "A", "○"],
 | 
						|
	["X", "Y", "□"],
 | 
						|
	["Y", "X", "△"],
 | 
						|
	["Select", "-", "Share"],
 | 
						|
	"Home",
 | 
						|
	["Start", "+", "Options"],
 | 
						|
	["LS Push", "LS Push", "L3"],
 | 
						|
	["RS Push", "RS Push", "R3"],
 | 
						|
	["LB", "L", "L1"],
 | 
						|
	["RB", "R", "R1"],
 | 
						|
	"DPad U",
 | 
						|
	"DPad D",
 | 
						|
	"DPad L",
 | 
						|
	"DPad R" 
 | 
						|
]
 | 
						|
 | 
						|
func _ready() -> void:
 | 
						|
	update_value()
 | 
						|
 | 
						|
func _process(_delta: float) -> void:
 | 
						|
	if selected:
 | 
						|
		handle_inputs()
 | 
						|
	$Cursor.modulate.a = int(selected)
 | 
						|
 | 
						|
func update_value() -> void:
 | 
						|
	$Title.text = tr(title) + ":"
 | 
						|
	if awaiting_input:
 | 
						|
		$Value.text = "Press Any..."
 | 
						|
	else:
 | 
						|
		if current_binding_idx == 0:
 | 
						|
			$Value.text = "(" + get_event_string(input_events[0]) + "), " + get_event_string(input_events[1]) + " "
 | 
						|
		else:
 | 
						|
			$Value.text = " " + get_event_string(input_events[0]) + " ,(" + get_event_string(input_events[1]) + ")"
 | 
						|
 | 
						|
func handle_inputs() -> void:
 | 
						|
	if can_remap:
 | 
						|
		if selected:
 | 
						|
			if Input.is_action_just_pressed("ui_accept"):
 | 
						|
				begin_remap()
 | 
						|
		if Input.is_action_just_pressed("ui_right"):
 | 
						|
			current_binding_idx = 1
 | 
						|
			update_value()
 | 
						|
		elif Input.is_action_just_pressed("ui_left"):
 | 
						|
			current_binding_idx = 0
 | 
						|
			update_value()
 | 
						|
 | 
						|
func begin_remap() -> void:
 | 
						|
	$Timer.stop()
 | 
						|
	$Timer.start()
 | 
						|
	rebinding_input = true
 | 
						|
	can_remap = false
 | 
						|
	get_parent().can_input = false
 | 
						|
	await get_tree().create_timer(0.1).timeout
 | 
						|
	awaiting_input = true
 | 
						|
	update_value()
 | 
						|
 | 
						|
func _input(event: InputEvent) -> void:
 | 
						|
	if awaiting_input == false: return
 | 
						|
	
 | 
						|
	if event.is_pressed() == false:
 | 
						|
		return
 | 
						|
	
 | 
						|
	if event is InputEventKey and not can_bind_escape:
 | 
						|
		if event.as_text_physical_keycode() == "Escape":
 | 
						|
			map_event_to_action(null, current_binding_idx)
 | 
						|
			return
 | 
						|
	
 | 
						|
	if type == 0 and event is InputEventKey:
 | 
						|
		map_event_to_action(event, current_binding_idx)
 | 
						|
	elif type == 1 and (event is InputEventJoypadButton or event is InputEventJoypadMotion):
 | 
						|
		if event is InputEventJoypadMotion:
 | 
						|
			event.axis_value = sign(event.axis_value)
 | 
						|
		map_event_to_action(event, current_binding_idx)
 | 
						|
 | 
						|
func map_event_to_action(event, idx := 0) -> void:
 | 
						|
	for action_name in action_names:
 | 
						|
		var action = action_name
 | 
						|
		if action.contains("ui_") == false and action != "pause":
 | 
						|
			action = action_name + "_" + str(player_idx)
 | 
						|
		var replace_event = null
 | 
						|
		var events = InputMap.action_get_events(action).duplicate()
 | 
						|
		var matching_type_events := []
 | 
						|
		for i in events:
 | 
						|
			if type == 0 and i is InputEventKey:
 | 
						|
				matching_type_events.append(i)
 | 
						|
			elif type == 1 and (i is InputEventJoypadButton or i is InputEventJoypadMotion):
 | 
						|
				matching_type_events.append(i)
 | 
						|
		if matching_type_events.size() - 1 < idx or matching_type_events.is_empty():
 | 
						|
			events.append(event)
 | 
						|
		else:
 | 
						|
			replace_event = matching_type_events[clamp(idx, 0, matching_type_events.size() - 1)]
 | 
						|
			var itr := 0
 | 
						|
			for i in events:
 | 
						|
				if i == replace_event:
 | 
						|
					events[itr] = event
 | 
						|
				itr += 1
 | 
						|
		InputMap.action_erase_events(action)
 | 
						|
		for i in events:
 | 
						|
			InputMap.action_add_event(action, i)
 | 
						|
		input_changed.emit(action, event)
 | 
						|
		input_events[idx] = event
 | 
						|
	awaiting_input = false
 | 
						|
	await get_tree().create_timer(0.1).timeout
 | 
						|
	rebinding_input = false
 | 
						|
	get_parent().can_input = true
 | 
						|
	can_remap = true
 | 
						|
	update_value()
 | 
						|
 | 
						|
func get_event_string(event: InputEvent) -> String:
 | 
						|
	var event_string := ""
 | 
						|
	if event == null:
 | 
						|
		return "---"
 | 
						|
	if event is InputEventKey:
 | 
						|
		event_string = OS.get_keycode_string(event.keycode)
 | 
						|
	elif event is InputEventJoypadButton:
 | 
						|
		var translation = button_id_translation[event.button_index]
 | 
						|
		if translation is Array:
 | 
						|
			translation = translation[current_device_brand]
 | 
						|
		event_string = translation
 | 
						|
	elif event is InputEventJoypadMotion:
 | 
						|
		var stick = "LS"
 | 
						|
		var direction = "Left"
 | 
						|
		if event.axis == JOY_AXIS_TRIGGER_LEFT:
 | 
						|
			return ["LT", "ZL", "L2"][current_device_brand]
 | 
						|
		elif event.axis == JOY_AXIS_TRIGGER_RIGHT:
 | 
						|
			return ["RT", "ZR", "R2"][current_device_brand]
 | 
						|
		
 | 
						|
		if event.axis == JOY_AXIS_RIGHT_X or event.axis == JOY_AXIS_RIGHT_Y:
 | 
						|
			stick = "RS"
 | 
						|
		if (event.axis == JOY_AXIS_LEFT_X or event.axis == JOY_AXIS_RIGHT_X):
 | 
						|
			if event.axis_value < 0:
 | 
						|
				direction = "Left"
 | 
						|
			else:
 | 
						|
				direction = "Right"
 | 
						|
		elif (event.axis == JOY_AXIS_LEFT_Y or event.axis == JOY_AXIS_RIGHT_Y):
 | 
						|
			if event.axis_value < 0:
 | 
						|
				direction = "Up"
 | 
						|
			else:
 | 
						|
				direction = "Down"
 | 
						|
		event_string = stick + " " + direction
 | 
						|
	else:
 | 
						|
		pass
 | 
						|
	return event_string
 | 
						|
 | 
						|
func _unhandled_input(event: InputEvent) -> void:
 | 
						|
	if event is not InputEventJoypadButton and event is not InputEventJoypadMotion:
 | 
						|
		return
 | 
						|
	var device_name = Input.get_joy_name(event.device)
 | 
						|
	var old_brand = current_device_brand
 | 
						|
	if device_name.to_upper().contains("NINTENDO") or device_name.to_upper().contains("SWITCH") or device_name.to_upper().contains("WII"):
 | 
						|
		current_device_brand = 1
 | 
						|
	elif device_name.to_upper().contains("PS") or device_name.to_upper().contains("PLAYSTATION"):
 | 
						|
		current_device_brand = 2
 | 
						|
	else:
 | 
						|
		current_device_brand = 0
 | 
						|
	if old_brand != current_device_brand:
 | 
						|
		update_value()
 | 
						|
 | 
						|
func cancel_remap() -> void:
 | 
						|
	awaiting_input = false
 | 
						|
	await get_tree().create_timer(0.1).timeout
 | 
						|
	rebinding_input = false
 | 
						|
	get_parent().can_input = true
 | 
						|
	can_remap = true
 | 
						|
	update_value()
 |