PneumaticPlaything/Scripts/EditorScreen.gd

327 lines
12 KiB
GDScript

extends Control
var playing : bool = false
var recording : bool = false
var index : int = 0
var playback_rate : int = 1
var transport_enabled : bool = false
var erase_validated : bool = false
var showtape_loaded : bool = false
var show_name : String
var current_stage : String = "Helen House"
var stages_info = {
# stage name, custom (bool), bits, flyout path, movement row table path, base scene path, ust character flag, ust stage flag
"Helen House": [true, 32, "res://Scenes/Stages/Helen House/HelenHouseFlyout.tscn", "res://Scenes/Stages/Helen House/HelenHouseMovementRows.tscn", "res://Scenes/Stages/Helen House/HelenHouse.tscn", "Mitzi/Helen", "Rockafire Explosion/3-Stage (Single Character)"]
}
signal step(amount: int)
signal start_recording()
signal end_recording()
signal return_to_zero()
signal erase_all()
func update_time_label() -> void:
var frames = index % 60
var seconds = floori(index/60) % 60
var minutes = floori(index/3600) % 60
var hours = floori(index/216000)
$SequencerPanel/TransportControls/TimeLabel.text = "%d:%02d:%02d:%02d" % [hours, minutes, seconds, frames]
#$SequencerPanel/TransportControls/TimeLabel.text = str(index)
func set_transport_enabled(enabled: bool):
$SequencerPanel/TransportControls/Centered/StepBackwardsButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/FastBackwardsButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/PlayBackwardsButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/PauseButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/StopButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/PlayButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/FastForwardButton.disabled = !enabled
$SequencerPanel/TransportControls/Centered/StepForwardButton.disabled = !enabled
$SequencerPanel/TransportControls/RecordButton.disabled = !enabled
transport_enabled = enabled
func _ready() -> void:
get_tree().get_root().size_changed.connect(_on_size_changed)
erase_all.connect(_erase_all)
$MenuBar/MenuButton.get_popup().id_pressed.connect(_showtape_menu_button_pressed)
func _showtape_menu_button_pressed(id: int) -> void:
match (id):
0: #new
if (showtape_loaded): $NewOverwriteConfirmationDialog.show()
else: $ShowtapeNewScreen.visible = true
1: #load
if (showtape_loaded): $LoadOverwriteConfirmationDialog.show()
else: $ShowtapeLoadScreen.visible = true
2: #save
if (showtape_loaded): $ShowtapeSaveScreen.visible = true
else: $NoShowtapeLoadedDialog.show()
func _on_showtape_new_audio_browse_button_pressed() -> void:
$OpenAudioFileDialog.show()
func _on_open_audio_file_dialog_file_selected(path: String) -> void:
$ShowtapeNewScreen/DialogPanel/AudioFilePath.text = path
func _on_showtape_new_cancel_button_pressed() -> void:
$ShowtapeNewScreen/DialogPanel/AudioFilePath.text = ""
$ShowtapeNewScreen/DialogPanel/ShowNameTextBox.text = ""
$ShowtapeNewScreen.visible = false
func _on_showtape_new_create_button_pressed() -> void:
if (!FileAccess.file_exists($ShowtapeNewScreen/DialogPanel/AudioFilePath.text.strip_edges())):
$FileDoesntExistDialog.show()
return
if ($ShowtapeNewScreen/DialogPanel/ShowNameTextBox.text.strip_edges() == ""):
$EmptyStringDialog.show()
return
show_name = $ShowtapeNewScreen/DialogPanel/ShowNameTextBox.text.strip_edges()
$AudioStreamPlayer.stream = load_audio($ShowtapeNewScreen/DialogPanel/AudioFilePath.text.strip_edges())
set_transport_enabled(true)
showtape_loaded = true
$MenuBar/EditingLabel.text = "Editing: " + show_name
$ShowtapeNewScreen/DialogPanel/AudioFilePath.text = ""
$ShowtapeNewScreen/DialogPanel/ShowNameTextBox.text = ""
$ShowtapeNewScreen.visible = false
func _on_new_overwrite_confirmation_dialog_confirmed() -> void:
erase_all.emit()
$ShowtapeNewScreen.visible = true
func _on_open_showtape_file_dialog_file_selected(path: String) -> void:
$ShowtapeLoadScreen/DialogPanel/InFilePath.text = path
func _on_showtape_load_in_browse_button_pressed() -> void:
$OpenShowtapeFileDialog.show()
func _on_showtape_load_cancel_button_pressed() -> void:
$ShowtapeLoadScreen/DialogPanel/InFilePath.text = ""
$ShowtapeLoadScreen.visible = false
func _on_showtape_load_open_button_pressed() -> void:
if (!FileAccess.file_exists($ShowtapeLoadScreen/DialogPanel/InFilePath.text.strip_edges())):
$FileDoesntExistDialog.show()
return
var file = FileAccess.open($ShowtapeLoadScreen/DialogPanel/InFilePath.text.strip_edges(), FileAccess.READ)
var content = file.get_as_text()
var header = content.split(";")[0].split(",")
if ((int(header[3]) != stages_info[current_stage][1]) || (header[4] != stages_info[current_stage][6])|| (header[5] != stages_info[current_stage][5])):
$IncorrectShowtapeDialog.dialog_text = "This showtape is not compatible with the currently selected stage.\nShowtape stage type: %s\nShowtape character(s): %s" % [header[4], header[5]]
$IncorrectShowtapeDialog.show()
return
show_name = header[2]
plot_data(content.split(";")[1])
$AudioStreamPlayer.stream = load_audio_from_buffer(Marshalls.base64_to_raw(content.split(";")[2]))
set_transport_enabled(true)
showtape_loaded = true
$MenuBar/EditingLabel.text = "Editing: " + show_name
$ShowtapeLoadScreen/DialogPanel/InFilePath.text = ""
$ShowtapeLoadScreen.visible = false
func _on_load_overwrite_confirmation_dialog_confirmed() -> void:
erase_all.emit()
$ShowtapeLoadScreen.visible = true
func _on_showtape_save_out_browse_button_pressed() -> void:
$SaveShowtapeFileDialog.show()
func _on_showtape_save_create_button_pressed() -> void:
var header = "UST,1,"+show_name.replace(",", "_").replace(";", "_")+","+str(stages_info[current_stage][1])+","+stages_info[current_stage][6]+","+stages_info[current_stage][5]+";"
var data_out_string = save_data()
var file = FileAccess.open($ShowtapeSaveScreen/DialogPanel/OutFilePath.text, FileAccess.WRITE)
file.store_string(header+data_out_string+";"+Marshalls.raw_to_base64($AudioStreamPlayer.stream.data))
file.close()
$ShowtapeSaveScreen/DialogPanel/OutFilePath.text = ""
$ShowtapeSaveScreen.visible = false
func _on_showtape_save_cancel_button_pressed() -> void:
$ShowtapeSaveScreen/DialogPanel/OutFilePath.text = ""
$ShowtapeSaveScreen.visible = false
func _on_save_showtape_file_dialog_file_selected(path: String) -> void:
$ShowtapeSaveScreen/DialogPanel/OutFilePath.text = path
func _input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_editor_screen"):
$CameraPreview.visible = !$CameraPreview.visible;
$CameraFullScreen.visible = !$CameraFullScreen.visible;
if (transport_enabled):
if event.is_action_pressed("sequencer_play_pause"):
if (playing): _on_pause_button_pressed()
else: _on_play_button_pressed()
elif event.is_action_pressed("sequencer_play_reverse"):
_on_play_backwards_button_pressed()
elif event.is_action_pressed("sequencer_fast_reverse"):
_on_fast_backwards_button_pressed()
elif event.is_action_pressed("sequencer_fast_forward"):
_on_fast_forward_button_pressed()
elif event.is_action_pressed("sequencer_step_backward"):
_on_step_backwards_button_pressed()
elif event.is_action_pressed("sequencer_step_forward"):
_on_step_forward_button_pressed()
elif event.is_action_pressed("sequencer_home"):
_on_stop_button_pressed()
func _physics_process(_delta: float) -> void:
if (playing):
step.emit(playback_rate)
index += playback_rate
if (index <= 0): _on_stop_button_pressed()
update_time_label()
func load_audio(path: String) -> AudioStream:
var sound
match (path.split(".")[-1]):
"mp3":
sound = AudioStreamMP3.load_from_file(path)
"wav":
sound = AudioStreamWAV.load_from_file(path)
"ogg":
sound = AudioStreamOggVorbis.load_from_file(path)
return sound
func load_audio_from_buffer(data: PackedByteArray) -> AudioStream:
var sound
match (data[0]):
73:
sound = AudioStreamMP3.load_from_buffer(data)
82:
sound = AudioStreamWAV.load_from_buffer(data)
79:
sound = AudioStreamOggVorbis.load_from_buffer(data)
return sound
func _on_size_changed() -> void:
$SubViewport.size = $ColorRect.size
func _on_controls_button_pressed() -> void:
$ControlsScreen.visible = true
func _on_credits_button_pressed() -> void:
$CreditsScreen.visible = true
func _on_input_eater_pressed() -> void:
$ControlsScreen.visible = false
$CreditsScreen.visible = false
$ShowtapeNewScreen.visible = false
$ShowtapeLoadScreen.visible = false
$ShowtapeSaveScreen.visible = false
func _on_v_scroll_bar_value_changed(value: float) -> void:
$SequencerPanel/TimelinePanel/InvisibleMask/RowsHandle.position.y = value * -44
func _erase_all() -> void:
playing = false
$AudioStreamPlayer.stop()
$AudioStreamPlayer.seek(0)
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
index = 0
update_time_label()
show_name = ""
$AudioStreamPlayer.stream = null
set_transport_enabled(false)
showtape_loaded = false
$MenuBar/EditingLabel.text = "No showtape loaded."
func _on_play_button_pressed() -> void:
playback_rate = 1
$AudioStreamPlayer.pitch_scale = 1
$AudioStreamPlayer.play(float(index)/60.0)
playing = true
func _on_pause_button_pressed() -> void:
$AudioStreamPlayer.stop()
playing = false
func _on_play_backwards_button_pressed() -> void:
playback_rate = -1
$AudioStreamPlayer.stop() # cant play backwards :(
playing = true
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
func _on_fast_backwards_button_pressed() -> void:
playback_rate = -2
$AudioStreamPlayer.stop() # cant play backwards :(
playing = true
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
func _on_step_backwards_button_pressed() -> void:
playing = false
$AudioStreamPlayer.stop()
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
if (index != 0):
step.emit(-1)
index -= 1
update_time_label()
func _on_fast_forward_button_pressed() -> void:
playback_rate = 2
$AudioStreamPlayer.pitch_scale = 2
$AudioStreamPlayer.play(float(index)/60.0)
playing = true
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
func _on_step_forward_button_pressed() -> void:
playing = false
$AudioStreamPlayer.stop()
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
step.emit(1)
index += 1
update_time_label()
func _on_record_button_toggled(toggled_on: bool) -> void:
recording = toggled_on
if (toggled_on): start_recording.emit()
else: end_recording.emit()
func _on_stop_button_pressed() -> void:
playing = false
$AudioStreamPlayer.stop()
$AudioStreamPlayer.seek(0)
$SequencerPanel/TransportControls/RecordButton.button_pressed = false
index = 0
return_to_zero.emit()
update_time_label()
func save_data() -> String:
var write_out : String = ""
var temp_data = []
var longest_channel = 0
for movement_row in $SequencerPanel/TimelinePanel/InvisibleMask/RowsHandle.get_child(0).get_children():
temp_data.append(movement_row.movements)
if (movement_row.movements.size() > longest_channel): longest_channel = movement_row.movements.size()
for i in range(longest_channel+1):
var frame_byte = 0
for j in range(stages_info[current_stage][1]):
if (index_get_safe(i, temp_data[j])): frame_byte += 1 << j;
write_out += ("%0"+str(stages_info[current_stage][1]/4)+"X,") % frame_byte
return write_out
func plot_data(data: String):
start_recording.emit()
for frame_string in data.split(","):
if (frame_string == ""): continue
var frame_byte = frame_string.hex_to_int()
for i in range(stages_info[current_stage][1]):
var er = false
if ((frame_byte & int(pow(2, i))) >> i == 1):
er = true
$SequencerPanel/TimelinePanel/InvisibleMask/RowsHandle.get_child(0).get_child(i).etching = er
step.emit(1)
for movement_row in $SequencerPanel/TimelinePanel/InvisibleMask/RowsHandle.get_child(0).get_children():
movement_row.etching = false
end_recording.emit()
return_to_zero.emit()
func index_get_safe(cindex: int, data: Array[bool]) -> bool:
if (cindex > data.size()-1): return false
if (cindex < 0): return false
var out = data.get(cindex)
if (out == null): return false
return out