2024-12-10 12:59:49 +00:00
|
|
|
extends Node
|
|
|
|
|
2024-12-13 03:19:48 +00:00
|
|
|
@onready var sub_viewport = $room/SubViewport
|
|
|
|
@onready var texture_rect = $room/SubViewport/TextureRect
|
2024-12-27 03:00:53 +00:00
|
|
|
@onready var retro_host = Engine.get_singleton("RetroHost") # Get the RetroHost singleton
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-13 03:19:48 +00:00
|
|
|
var current_core : Object = null # The emulator core (passed dynamically)
|
|
|
|
var current_rom : String = "" # Initialize to an empty string
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-13 03:19:48 +00:00
|
|
|
func start_emulation(core_path: String, rom_path: String) -> bool:
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] Starting emulation with core: ", core_path, ", ROM: ", rom_path)
|
2024-12-27 03:00:53 +00:00
|
|
|
|
2024-12-27 04:52:03 +00:00
|
|
|
# Debug RetroHost access
|
|
|
|
print("[libretro_loader] RetroHost status: ", retro_host)
|
|
|
|
|
2024-12-27 03:00:53 +00:00
|
|
|
# Check if RetroHost is available
|
|
|
|
if not retro_host:
|
2024-12-27 04:52:03 +00:00
|
|
|
var message = "[libretro_loader] RetroHost singleton not found!"
|
|
|
|
push_error(message)
|
|
|
|
print(message)
|
2024-12-27 03:00:53 +00:00
|
|
|
return false
|
|
|
|
|
2024-12-18 06:48:50 +00:00
|
|
|
if not core_path:
|
2024-12-27 04:52:03 +00:00
|
|
|
var message = "[libretro_loader] Core path is missing."
|
|
|
|
push_error(message)
|
|
|
|
print(message)
|
2024-12-18 06:48:50 +00:00
|
|
|
return false
|
2024-12-27 04:52:03 +00:00
|
|
|
|
2024-12-18 06:48:50 +00:00
|
|
|
if not rom_path:
|
2024-12-27 04:52:03 +00:00
|
|
|
var message = "[libretro_loader] ROM path is missing."
|
|
|
|
push_error(message)
|
|
|
|
print(message)
|
2024-12-13 03:19:48 +00:00
|
|
|
return false
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-27 03:00:53 +00:00
|
|
|
# Load the core (via RetroHost)
|
|
|
|
print("[libretro_loader] Loading core using RetroHost...")
|
|
|
|
var core_loaded = retro_host.load_core(core_path)
|
|
|
|
if not core_loaded:
|
2024-12-27 01:53:34 +00:00
|
|
|
push_error("[libretro_loader] Failed to load core: " + core_path)
|
2024-12-13 03:19:48 +00:00
|
|
|
return false
|
2024-12-27 03:00:53 +00:00
|
|
|
print("[libretro_loader] Core loaded successfully.")
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-27 03:00:53 +00:00
|
|
|
# Check if ROM file exists
|
2024-12-13 03:19:48 +00:00
|
|
|
if not FileAccess.file_exists(rom_path):
|
2024-12-27 01:53:34 +00:00
|
|
|
push_error("[libretro_loader] ROM not found: " + rom_path)
|
2024-12-13 03:19:48 +00:00
|
|
|
return false
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] ROM file exists.")
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-27 03:00:53 +00:00
|
|
|
# Load the ROM
|
|
|
|
print("[libretro_loader] Opening ROM...")
|
2024-12-13 03:19:48 +00:00
|
|
|
var file = FileAccess.open(rom_path, FileAccess.READ)
|
|
|
|
if not file:
|
2024-12-27 03:00:53 +00:00
|
|
|
push_error("[libretro_loader] Failed to open ROM: " + rom_path)
|
2024-12-13 03:19:48 +00:00
|
|
|
return false
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-13 03:19:48 +00:00
|
|
|
var rom_data = file.get_buffer(file.get_length())
|
|
|
|
file.close()
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] ROM data loaded successfully.")
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-27 03:00:53 +00:00
|
|
|
# Pass ROM data to the core
|
|
|
|
if not retro_host.core.load_game(rom_data):
|
|
|
|
push_error("[libretro_loader] Failed to load ROM into core: " + rom_path)
|
2024-12-13 03:19:48 +00:00
|
|
|
return false
|
2024-12-27 01:53:34 +00:00
|
|
|
|
|
|
|
print("[libretro_loader] ROM loaded successfully.")
|
2024-12-13 03:19:48 +00:00
|
|
|
|
|
|
|
current_rom = rom_path
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] Core and ROM loaded successfully.")
|
2024-12-13 03:19:48 +00:00
|
|
|
|
2024-12-18 06:48:50 +00:00
|
|
|
# Ensure SubViewport is ready
|
2024-12-13 03:19:48 +00:00
|
|
|
sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
|
|
|
|
2024-12-18 06:48:50 +00:00
|
|
|
# Wait for the SubViewport to initialize (up to 3 seconds)
|
|
|
|
var max_wait_time = 3.0 # Maximum wait time in seconds
|
|
|
|
var elapsed_time = 0.0
|
|
|
|
while not sub_viewport.get_texture() and elapsed_time < max_wait_time:
|
|
|
|
await get_tree().idle_frame # Waits for the next frame
|
|
|
|
elapsed_time += get_process_delta_time()
|
|
|
|
if not sub_viewport.get_texture():
|
2024-12-27 01:53:34 +00:00
|
|
|
push_error("[libretro_loader] Error: SubViewport texture is not ready after waiting.")
|
2024-12-13 03:19:48 +00:00
|
|
|
return false
|
|
|
|
|
2024-12-18 06:48:50 +00:00
|
|
|
texture_rect.texture = sub_viewport.get_texture()
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] SubViewport texture assigned successfully.")
|
2024-12-13 03:19:48 +00:00
|
|
|
return true
|
2024-12-10 12:59:49 +00:00
|
|
|
|
2024-12-11 07:29:31 +00:00
|
|
|
func _process(delta):
|
2024-12-13 03:19:48 +00:00
|
|
|
"""
|
|
|
|
Dynamically updates the TextureRect's texture during runtime.
|
|
|
|
"""
|
|
|
|
if current_core:
|
|
|
|
current_core.run()
|
|
|
|
|
|
|
|
var frame_data = current_core.get_frame_buffer()
|
|
|
|
if frame_data:
|
|
|
|
var frame_width = current_core.get_frame_width()
|
|
|
|
var frame_height = current_core.get_frame_height()
|
|
|
|
|
|
|
|
if frame_width > 0 and frame_height > 0:
|
|
|
|
var image = Image.create_from_data(
|
|
|
|
frame_width,
|
|
|
|
frame_height,
|
|
|
|
false,
|
|
|
|
Image.FORMAT_RGB8,
|
|
|
|
frame_data
|
|
|
|
)
|
|
|
|
var texture = ImageTexture.create_from_image(image)
|
|
|
|
texture_rect.texture = texture
|
|
|
|
|
|
|
|
func _ready():
|
|
|
|
"""
|
2024-12-27 04:52:03 +00:00
|
|
|
Initializes the SubViewport and TextureRect and waits for RetroHost singleton.
|
2024-12-13 03:19:48 +00:00
|
|
|
"""
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] _ready: Initializing SubViewport and TextureRect.")
|
2024-12-13 03:19:48 +00:00
|
|
|
if sub_viewport and texture_rect:
|
2024-12-27 03:00:53 +00:00
|
|
|
print("[libretro_loader] SubViewport and TextureRect initialized successfully.")
|
2024-12-13 03:19:48 +00:00
|
|
|
else:
|
2024-12-27 04:52:03 +00:00
|
|
|
push_error("[libretro_loader] Error: SubViewport or TextureRect is missing.")
|
2024-12-27 03:00:53 +00:00
|
|
|
return
|
2024-12-13 03:19:48 +00:00
|
|
|
|
|
|
|
# Ensure SubViewport always renders
|
|
|
|
sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
2024-12-27 01:53:34 +00:00
|
|
|
print("[libretro_loader] SubViewport set to always update.")
|
2024-12-27 03:00:53 +00:00
|
|
|
|
2024-12-27 04:52:03 +00:00
|
|
|
print("[libretro_loader] _ready: Waiting for RetroHost singleton...")
|
|
|
|
|
|
|
|
while not Engine.get_singleton("RetroHost"):
|
|
|
|
print("[libretro_loader] Waiting for RetroHost...")
|
|
|
|
await get_tree().idle_frame
|
|
|
|
|
|
|
|
print("[libretro_loader] _ready: Wait ended")
|
|
|
|
|
|
|
|
# Assign the RetroHost singleton after it's available
|
|
|
|
retro_host = Engine.get_singleton("RetroHost")
|
|
|
|
if retro_host:
|
|
|
|
print("[libretro_loader] RetroHost singleton initialized successfully.")
|
|
|
|
else:
|
|
|
|
push_error("[libretro_loader] Failed to find RetroHost singleton!")
|
|
|
|
return
|
|
|
|
|
|
|
|
# Proceed with starting emulation
|
|
|
|
var success = await start_emulation("res://cores/genesis_plus_gx_libretro.so", "res://roms/megadrive/Sonic the Hedgehog.bin")
|
2024-12-27 03:00:53 +00:00
|
|
|
if success:
|
|
|
|
print("[libretro_loader] Emulation started successfully.")
|
|
|
|
else:
|
|
|
|
print("[libretro_loader] Failed to start emulation.")
|