mirror of
https://github.com/RetroDECK/RetroDECK.git
synced 2025-01-29 19:45:38 +00:00
On branch feat/godot-configurator
Changes to be committed: modified: tools/configurator/components/logs.tscn renamed: tools/configurator/components/logs/logs_popup_content.tscn -> tools/configurator/components/logs_view/logs_popup_content.tscn new file: tools/configurator/components/logs_view/view_log.gd modified: tools/configurator/components/popup.gd modified: tools/configurator/components/popup.tscn modified: tools/configurator/data_list.json modified: tools/configurator/main.gd modified: tools/configurator/res/pixel_ui_theme/RetroDECKTheme.tres new file: tools/configurator/retrodeck.json modified: tools/configurator/scripts/class_functions.gd modified: tools/configurator/scripts/data_handler.gd modified: tools/configurator/tk_about.gd
This commit is contained in:
parent
7f9531aaf7
commit
e47b3116b8
|
@ -1,3 +1,3 @@
|
|||
[gd_scene format=3 uid="uid://1xnw3mdwvg8o"]
|
||||
[gd_scene format=3 uid="uid://bysbnp1spj1s1"]
|
||||
|
||||
[node name="Logs" type="Node2D"]
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
[gd_scene format=3 uid="uid://db4ibvxq5wnxe"]
|
||||
[gd_scene load_steps=2 format=3 uid="uid://db4ibvxq5wnxe"]
|
||||
|
||||
[ext_resource type="Script" path="res://components/logs_view/view_log.gd" id="1_kk2pw"]
|
||||
|
||||
[node name="PopupContent" type="Control"]
|
||||
layout_mode = 3
|
||||
|
@ -7,8 +9,10 @@ anchor_right = 1.0
|
|||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_kk2pw")
|
||||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
|
@ -16,7 +20,6 @@ anchor_bottom = 1.0
|
|||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
focus_mode = 2
|
||||
fit_content = true
|
||||
scroll_following = true
|
||||
context_menu_enabled = true
|
||||
selection_enabled = true
|
5
tools/configurator/components/logs_view/view_log.gd
Normal file
5
tools/configurator/components/logs_view/view_log.gd
Normal file
|
@ -0,0 +1,5 @@
|
|||
extends Control
|
||||
|
||||
|
||||
func _ready():
|
||||
pass
|
|
@ -10,9 +10,9 @@ func _ready():
|
|||
|
||||
func set_content(new_content):
|
||||
content = load(new_content).instantiate()
|
||||
|
||||
func set_title(new_title):
|
||||
$Panel/MarginContainer/VBoxContainer/MarginContainer/HBoxContainer/Label.text = new_title
|
||||
|
||||
func set_display_text(new_display_text):
|
||||
$Panel/MarginContainer/VBoxContainer/ContentContainer/MarginContainer/RichTextLabel.text=new_display_text
|
||||
func _on_back_pressed():
|
||||
queue_free()
|
||||
|
|
|
@ -70,5 +70,10 @@ theme_override_constants/margin_bottom = 6
|
|||
|
||||
[node name="RichTextLabel" type="RichTextLabel" parent="Panel/MarginContainer/VBoxContainer/ContentContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
focus_mode = 2
|
||||
scroll_active = false
|
||||
scroll_following = true
|
||||
context_menu_enabled = true
|
||||
selection_enabled = true
|
||||
|
||||
[connection signal="pressed" from="Panel/MarginContainer/VBoxContainer/MarginContainer/HBoxContainer/BackButton" to="." method="_on_back_pressed"]
|
||||
|
|
|
@ -405,4 +405,4 @@
|
|||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ var emu_pick_option: OptionButton
|
|||
var log_option: OptionButton
|
||||
var tab_container: TabContainer
|
||||
var anim_logo: AnimatedSprite2D
|
||||
var anim_rekku: AnimatedSprite2D
|
||||
var rd_logs: String
|
||||
|
||||
var app_data = AppData.new()
|
||||
func _ready():
|
||||
|
@ -33,11 +33,21 @@ func _ready():
|
|||
var website_data = app_data.about_links["rd_web"]
|
||||
print (website_data.name,"-",website_data.url,"-",website_data.description)
|
||||
"""
|
||||
var emulator_list = class_functions.get_text_file_from_system_path("../../tools/configurator.sh","sed -n '/local emulator_list=(/,/)/{s/.*local emulator_list=\\(.*\\)/\\1/; /)/q; p}' ","emulist")
|
||||
#print (emulator_list)
|
||||
var abxy_button_list = class_functions.get_text_file_from_system_path("/var/config/retrodeck/retrodeck.cfg","sed -n '/\\[abxy_button_swap\\]/,/^$/p' ","normal")
|
||||
#print(abxy_button_list)
|
||||
# set current startup tab to match IDE
|
||||
var console: bool = false
|
||||
var test = class_functions.execute_command("cat",["/var/config/retrodeck/retrodeck.cfg"],console)
|
||||
#print (test)
|
||||
var config_file_path = "/var/config/retrodeck/retrodeck.cfg"
|
||||
var json_file_path = "/var/config/retrodeck/retrodeck.json"
|
||||
var config = data_handler.parse_config_to_json(config_file_path)
|
||||
data_handler.config_save_json(config, json_file_path)
|
||||
rd_logs = config["paths"]["logs_folder"]
|
||||
#var log_file = class_functions.import_text_file(rd_logs +"/retrodeck.log")
|
||||
|
||||
#for id in config.paths:
|
||||
# var path_data = config.paths[id]
|
||||
# print (id)
|
||||
|
||||
# set current startup tab to match IDE
|
||||
tab_container.current_tab = 3
|
||||
#add_child(class_functions) # Needed for threaded results Not need autoload?
|
||||
var children = findElements(self, "Control")
|
||||
|
@ -55,7 +65,6 @@ func _get_nodes() -> void:
|
|||
emu_pick_option = get_node("%emu_pick_option")
|
||||
tab_container = get_node("%TabContainer")
|
||||
anim_logo = get_node("%logo_animated")
|
||||
anim_rekku = get_node("%rekku_animated")
|
||||
log_option = get_node("%logs_button")
|
||||
|
||||
func _connect_signals() -> void:
|
||||
|
@ -79,15 +88,13 @@ func _emu_pick(index: int) -> void:
|
|||
_play_main_animations()
|
||||
|
||||
func _load_log(index: int) -> void:
|
||||
var log_content:String
|
||||
match index:
|
||||
1:
|
||||
#https://docs.godotengine.org/en/stable/tutorials/scripting/singletons_autoload.html
|
||||
#https://docs.godotengine.org/en/stable/classes/class_os.html
|
||||
#https://docs.godotengine.org/en/stable/classes/class_os.html#class-os-method-get-environment
|
||||
print ("Load log via dos and ref rdhome? or use Enviornment variable from godot")
|
||||
load_popup("RetroDeck Log", "res://components/logs/logs_popup_content.tscn")
|
||||
log_content = class_functions.import_text_file(rd_logs +"/retrodeck.log")
|
||||
load_popup("RetroDeck Log", "res://components/logs_view/logs_popup_content.tscn", log_content)
|
||||
2:
|
||||
load_popup("ES-DE Log", "res://components/logs/logs_popup_content.tscn")
|
||||
load_popup("ES-DE Log", "res://components/logs_view/logs_popup_content.tscn","")
|
||||
|
||||
func _play_main_animations() -> void:
|
||||
anim_logo.play()
|
||||
|
@ -119,21 +126,22 @@ func findElements(node: Node, className: String, result: Array = []) -> Array:
|
|||
func _on_control_mouse_entered(control: Node):
|
||||
control.grab_focus()
|
||||
|
||||
func load_popup(title:String, content_path:String):
|
||||
func load_popup(title:String, content_path:String, display_text: String):
|
||||
var popup = load("res://components/popup.tscn").instantiate() as Control
|
||||
popup.set_title(title)
|
||||
popup.set_content(content_path)
|
||||
popup.set_display_text(display_text)
|
||||
$Background.add_child(popup)
|
||||
|
||||
func _on_quickresume_advanced_pressed():
|
||||
load_popup("Quick Resume Advanced", "res://components/popups_content/popup_content_test.tscn")
|
||||
load_popup("Quick Resume Advanced", "res://components/popups_content/popup_content_test.tscn","")
|
||||
|
||||
func _on_bios_button_pressed():
|
||||
_play_main_animations()
|
||||
bios_type = 0
|
||||
log_parameters[2] = log_text + "Bios_Check"
|
||||
log_results = class_functions.execute_command(wrapper_command, log_parameters, false)
|
||||
load_popup("BIOS File Check", "res://components/bios_check/bios_popup_content.tscn")
|
||||
load_popup("BIOS File Check", "res://components/bios_check/bios_popup_content.tscn","")
|
||||
status_code_label.text = str(log_results["exit_code"])
|
||||
|
||||
func _on_bios_button_expert_pressed():
|
||||
|
@ -141,7 +149,7 @@ func _on_bios_button_expert_pressed():
|
|||
bios_type = 1
|
||||
log_parameters[2] = log_text + "Advanced_Bios_Check"
|
||||
log_results = class_functions.execute_command(wrapper_command, log_parameters, false)
|
||||
load_popup("BIOS File Check", "res://components/bios_check/bios_popup_content.tscn")
|
||||
load_popup("BIOS File Check", "res://components/bios_check/bios_popup_content.tscn","")
|
||||
status_code_label.text = str(log_results["exit_code"])
|
||||
|
||||
func _on_exit_button_pressed():
|
||||
|
|
File diff suppressed because one or more lines are too long
87
tools/configurator/retrodeck.json
Normal file
87
tools/configurator/retrodeck.json
Normal file
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
"abxy_button_swap": {
|
||||
"citra": false,
|
||||
"gb": false,
|
||||
"gba": false,
|
||||
"gbc": false,
|
||||
"n64": false,
|
||||
"snes": false
|
||||
},
|
||||
"ask_to_exit": {
|
||||
"citra": false,
|
||||
"dolphin": false,
|
||||
"duckstation": false,
|
||||
"pcsx2": false,
|
||||
"primehack": false,
|
||||
"rpcs3": false
|
||||
},
|
||||
"borders": {
|
||||
"gb": false,
|
||||
"gba": false,
|
||||
"gbc": false,
|
||||
"genesis": false,
|
||||
"gg": false,
|
||||
"n64": false,
|
||||
"psx_ra": false,
|
||||
"snes": false
|
||||
},
|
||||
"cheevos": {
|
||||
"duckstation": false,
|
||||
"pcsx2": false,
|
||||
"retroarch": false
|
||||
},
|
||||
"cheevos_hardcore": {
|
||||
"duckstation": false,
|
||||
"pcsx2": false,
|
||||
"retroarch": false
|
||||
},
|
||||
"options": {
|
||||
"akai_ponzu": false,
|
||||
"ask_default_user": true,
|
||||
"branch": "",
|
||||
"cloud_saves": false,
|
||||
"default_user": "",
|
||||
"desktop_mode_warning": true,
|
||||
"developer_options": false,
|
||||
"kiroi_ponzu": false,
|
||||
"low_space_warning": true,
|
||||
"multi_user_mode": false,
|
||||
"power_user_warning": true,
|
||||
"update_check": true,
|
||||
"update_ignore": "",
|
||||
"update_repo": "RetroDECK"
|
||||
},
|
||||
"paths": {
|
||||
"bios_folder": "/run/media/tim/DATA/retrodeck/bios",
|
||||
"borders_folder": "/run/media/tim/DATA/retrodeck/borders",
|
||||
"logs_folder": "/run/media/tim/DATA/retrodeck/logs",
|
||||
"media_folder": "/run/media/tim/DATA/retrodeck/downloaded_media",
|
||||
"mods_folder": "/run/media/tim/DATA/retrodeck/mods",
|
||||
"rdhome": "/home/tim/retrodeck",
|
||||
"roms_folder": "/run/media/tim/DATA/retrodeck/roms",
|
||||
"saves_folder": "/run/media/tim/DATA/retrodeck/saves",
|
||||
"screenshots_folder": "/run/media/tim/DATA/retrodeck/screenshots",
|
||||
"sdcard": "/run/media/mmcblk0p1",
|
||||
"states_folder": "/run/media/tim/DATA/retrodeck/states",
|
||||
"texture_packs_folder": "/run/media/tim/DATA/retrodeck/texture_packs",
|
||||
"themes_folder": "/run/media/tim/DATA/retrodeck/themes"
|
||||
},
|
||||
"quick_resume": {
|
||||
"retroarch": true
|
||||
},
|
||||
"rewind": {
|
||||
"gb": false,
|
||||
"gba": false,
|
||||
"gbc": false,
|
||||
"genesis": false,
|
||||
"gg": false,
|
||||
"snes": false
|
||||
},
|
||||
"version": "0.8.2b",
|
||||
"widescreen": {
|
||||
"genesis": false,
|
||||
"n64": false,
|
||||
"psx_ra": false,
|
||||
"snes": false
|
||||
}
|
||||
}
|
|
@ -32,52 +32,6 @@ func _threaded_command_execution(command: String, parameters: Array, console: bo
|
|||
var result = execute_command(command, parameters, console)
|
||||
return result
|
||||
|
||||
# Make this generic for command, path and naming
|
||||
func get_text_file_from_system_path(file_path: String, command: String, etype: String) -> Dictionary:
|
||||
var output: Array
|
||||
var data_dict: Dictionary
|
||||
command += file_path
|
||||
var exit_code = OS.execute("sh", ["-c", command], output)
|
||||
if exit_code == 0:
|
||||
var content = array_to_string(output)
|
||||
if etype == "emulist":
|
||||
data_dict = parse_file_list(content)
|
||||
elif etype == "normal":
|
||||
data_dict = parse_imported_string(content)
|
||||
else:
|
||||
print ("Error in get text function")
|
||||
return data_dict
|
||||
else:
|
||||
print("Error reading file: ", exit_code)
|
||||
return {}
|
||||
|
||||
func parse_imported_string(input_string: String) -> Dictionary:
|
||||
var _result: Dictionary
|
||||
var _current_dict_key: String
|
||||
var lines = input_string.strip_edges().split("\n", false)
|
||||
#if lines.size() > 0:
|
||||
# lines = lines.slice(1, lines.size()) # Skip the first line
|
||||
for line in lines:
|
||||
_current_dict_key = line
|
||||
var parts = line.split("=", false)
|
||||
if parts.size() == 2:
|
||||
var key = parts[0]
|
||||
var value_str = parts[1]
|
||||
_result[key] = {"KEY": key, "Value": value_str}
|
||||
return _result
|
||||
|
||||
func parse_file_list(content: String) -> Dictionary:
|
||||
var file_dict = {}
|
||||
var regex = RegEx.new()
|
||||
regex.compile(r'"([^"]+)"\s*"([^"]+)"')
|
||||
var matches = regex.search_all(content)
|
||||
|
||||
for match in matches:
|
||||
var name = match.get_string(1)
|
||||
var description = match.get_string(2)
|
||||
file_dict[name] = description
|
||||
return file_dict
|
||||
|
||||
func process_url_image(body) -> Texture:
|
||||
var image = Image.new()
|
||||
image.load_png_from_buffer(body)
|
||||
|
@ -116,3 +70,14 @@ func _import_data_lists(file_path: String) -> void:
|
|||
print("URL: " + entry["URL"])
|
||||
print("Description: " + entry["Description"])
|
||||
print("---")
|
||||
|
||||
func import_text_file(file_path: String) -> String:
|
||||
var content: String
|
||||
var file = FileAccess.open(file_path, FileAccess.READ)
|
||||
if file == null:
|
||||
print("Failed to open file")
|
||||
return content
|
||||
while not file.eof_reached():
|
||||
content += file.get_line() + "\n"
|
||||
file.close
|
||||
return content
|
||||
|
|
|
@ -7,9 +7,9 @@ var app_data: AppData
|
|||
|
||||
func _ready():
|
||||
# Load the data when the scene is ready
|
||||
app_data = load_data()
|
||||
app_data = load_base_data()
|
||||
|
||||
func load_data() -> AppData:
|
||||
func load_base_data() -> AppData:
|
||||
var file = FileAccess.open(data_file_path, FileAccess.READ)
|
||||
if file:
|
||||
var json_data = file.get_as_text()
|
||||
|
@ -62,7 +62,7 @@ func load_data() -> AppData:
|
|||
print("Error opening file")
|
||||
return null
|
||||
|
||||
func save_data(app_data: AppData):
|
||||
func save_base_data(app_data: AppData):
|
||||
var file = FileAccess.open(data_file_path, FileAccess.READ)
|
||||
var existing_data = {}
|
||||
if file:
|
||||
|
@ -142,21 +142,21 @@ func save_data(app_data: AppData):
|
|||
print("Data appended successfully")
|
||||
# Function to modify an existing link
|
||||
func modify_link(key: String, new_name: String, new_url: String, new_description: String):
|
||||
var app_data = load_data()
|
||||
var app_data = load_base_data()
|
||||
if app_data and app_data.about_links.has(key):
|
||||
var link = app_data.about_links[key]
|
||||
link.name = new_name
|
||||
link.url = new_url
|
||||
link.description = new_description
|
||||
app_data.about_links[key] = link
|
||||
save_data(app_data)
|
||||
save_base_data(app_data)
|
||||
print("Link modified successfully")
|
||||
else:
|
||||
print("Link not found")
|
||||
|
||||
# Function to modify an existing emulator
|
||||
func modify_emulator(key: String, new_name: String, new_description: String, new_options: Array, new_properties: Array):
|
||||
var app_data = load_data()
|
||||
var app_data = load_base_data()
|
||||
if app_data and app_data.emulators.has(key):
|
||||
var emulator = app_data.emulators[key]
|
||||
emulator.name = new_name
|
||||
|
@ -178,7 +178,7 @@ func modify_emulator(key: String, new_name: String, new_description: String, new
|
|||
emulator.properties.append(new_property)
|
||||
|
||||
app_data.emulators[key] = emulator
|
||||
save_data(app_data)
|
||||
save_base_data(app_data)
|
||||
print("Emulator modified successfully")
|
||||
else:
|
||||
print("Emulator not found")
|
||||
|
@ -202,7 +202,7 @@ func add_emaultor() -> void:
|
|||
property.abxy_button_status = false
|
||||
emulator.properties.append(property)
|
||||
app_data.emulators["example_emulator"] = emulator
|
||||
data_handler.save_data(app_data)
|
||||
data_handler.save_base_data(app_data)
|
||||
|
||||
func modify_emulator_test() -> void:
|
||||
data_handler.modify_link("example_site", "Updated Site", "https://updated-example.com", "Updated description.")
|
||||
|
@ -220,3 +220,55 @@ func modify_emulator_test() -> void:
|
|||
|
||||
data_handler.modify_emulator("example_emulator", "Updated Emulator", "Updated description", new_options, new_properties)
|
||||
|
||||
|
||||
func parse_config_to_json(file_path: String) -> Dictionary:
|
||||
var config = {}
|
||||
var current_section = ""
|
||||
|
||||
var file = FileAccess.open(file_path, FileAccess.READ)
|
||||
if file == null:
|
||||
print("Failed to open file")
|
||||
return config
|
||||
|
||||
while not file.eof_reached():
|
||||
var line = file.get_line().strip_edges()
|
||||
|
||||
if line.begins_with("[") and line.ends_with("]"):
|
||||
# Start a new section
|
||||
current_section = line.substr(1, line.length() - 2)
|
||||
config[current_section] = {}
|
||||
elif line != "" and not line.begins_with("#"):
|
||||
# Add key-value pair to the current section
|
||||
var parts = line.split("=")
|
||||
if parts.size() == 2:
|
||||
var key = parts[0].strip_edges()
|
||||
var value = parts[1].strip_edges()
|
||||
|
||||
# Convert value to proper type
|
||||
if value == "true":
|
||||
value = true
|
||||
elif value == "false":
|
||||
value = false
|
||||
|
||||
if key == "version":
|
||||
config[key] = value
|
||||
else:
|
||||
if current_section == "":
|
||||
config[key] = value
|
||||
else:
|
||||
config[current_section][key] = value
|
||||
|
||||
file.close()
|
||||
return config
|
||||
|
||||
|
||||
func config_save_json(config: Dictionary, json_file_path: String) -> void:
|
||||
var json = JSON.new()
|
||||
var json_string = json.stringify(config, "\t")
|
||||
|
||||
var file = FileAccess.open(json_file_path, FileAccess.WRITE)
|
||||
if file != null:
|
||||
file.store_string(json_string)
|
||||
file.close()
|
||||
else:
|
||||
print("Failed to open JSON file for writing")
|
||||
|
|
|
@ -15,7 +15,7 @@ var app_data = AppData.new()
|
|||
|
||||
func _ready():
|
||||
#tk_about = class_functions.import_csv_data("res://tk_about.txt")
|
||||
app_data = data_handler.load_data()
|
||||
app_data = data_handler.load_base_data()
|
||||
_get_nodes()
|
||||
_connect_signals()
|
||||
|
||||
|
|
Loading…
Reference in a new issue