mirror of
https://github.com/RetroDECK/RetroQUEST.git
synced 2025-04-21 01:24:06 +00:00
Checkpoint - Issue: singleton cannot be loaded
This commit is contained in:
parent
70432207db
commit
d8ce8263b9
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -8,50 +8,70 @@
|
|||
|
||||
#include "RetroHost.hpp"
|
||||
|
||||
// Singleton instance pointer
|
||||
static RetroHost *retro_host_singleton = nullptr;
|
||||
|
||||
namespace {
|
||||
|
||||
// Initialize the extension and register the singleton
|
||||
void initialize_extension(godot::ModuleInitializationLevel p_level) {
|
||||
if (p_level != godot::MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
|
||||
godot::ClassDB::register_class<RetroHost>();
|
||||
|
||||
godot::UtilityFunctions::print("[RetroHost] Initializing extension...");
|
||||
|
||||
// Register the RetroHost class
|
||||
godot::ClassDB::register_class<RetroHost>();
|
||||
godot::UtilityFunctions::print("[RetroHost] RetroHost class registered.");
|
||||
|
||||
// Create the singleton instance
|
||||
retro_host_singleton = memnew(RetroHost());
|
||||
if (!retro_host_singleton) {
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Failed to allocate memory for singleton.");
|
||||
return;
|
||||
} else {
|
||||
godot::UtilityFunctions::print("[RetroHost] Singleton created successfully.");
|
||||
}
|
||||
|
||||
// Register the singleton with the engine
|
||||
godot::Engine::get_singleton()->register_singleton("RetroHost", RetroHost::get_singleton());
|
||||
godot::UtilityFunctions::print("[RetroHost] Singleton registered successfully.");
|
||||
|
||||
}
|
||||
|
||||
// Uninitialize the extension and unregister the singleton
|
||||
void uninitialize_extension(godot::ModuleInitializationLevel p_level) {
|
||||
if (p_level != godot::MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
godot::Engine::get_singleton()->unregister_singleton("RetroHost");
|
||||
memdelete(retro_host_singleton);
|
||||
|
||||
godot::UtilityFunctions::print("[RetroHost] Uninitializing extension...");
|
||||
|
||||
// Unregister and delete the singleton instance
|
||||
if (retro_host_singleton) {
|
||||
godot::Engine::get_singleton()->unregister_singleton("RetroHost");
|
||||
memdelete(retro_host_singleton);
|
||||
retro_host_singleton = nullptr;
|
||||
godot::UtilityFunctions::print("[RetroHost] Singleton unregistered and memory released.");
|
||||
} else {
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Singleton instance was null during uninitialization.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Entry point for the GDExtension system
|
||||
extern "C" {
|
||||
GDExtensionBool GDE_EXPORT GDExtensionInit(
|
||||
GDExtensionInterfaceGetProcAddress p_get_proc_address,
|
||||
GDExtensionClassLibraryPtr p_library,
|
||||
GDExtensionInitialization *r_initialization) {
|
||||
//godot::UtilityFunctions::print("[LibRetroHost] GDExtensionInit called");
|
||||
|
||||
|
||||
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
|
||||
|
||||
// Register the initializer and terminator functions
|
||||
init_obj.register_initializer(initialize_extension);
|
||||
init_obj.register_terminator(uninitialize_extension);
|
||||
init_obj.set_minimum_library_initialization_level(godot::MODULE_INITIALIZATION_LEVEL_SCENE);
|
||||
|
||||
//godot::UtilityFunctions::print("[LibRetroHost] Initialization setup completed.");
|
||||
return init_obj.init();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,15 +47,23 @@ std::string GetLastErrorAsStr()
|
|||
|
||||
RetroHost::RetroHost()
|
||||
{
|
||||
godot::UtilityFunctions::print("[RetroHost] Constructor");
|
||||
godot::UtilityFunctions::print("[RetroHost] Constructor called. Initializing singleton.");
|
||||
singleton = this;
|
||||
this->vfs.init_vfs_interface();
|
||||
|
||||
// Initialize core variables
|
||||
this->core.handle = nullptr;
|
||||
this->core.initialized = false;
|
||||
this->frame_buffer.unref(); // Reset the Ref<godot::Image> properly
|
||||
godot::UtilityFunctions::print("[RetroHost] Initialization complete.");
|
||||
}
|
||||
|
||||
RetroHost::~RetroHost()
|
||||
{
|
||||
godot::UtilityFunctions::print("[RetroHost] Destructor");
|
||||
godot::UtilityFunctions::print("[RetroHost] Destructor called. Cleaning up resources.");
|
||||
this->unload_core();
|
||||
singleton = nullptr;
|
||||
godot::UtilityFunctions::print("[RetroHost] Resources cleaned up and singleton destroyed.");
|
||||
}
|
||||
|
||||
RetroHost *RetroHost::singleton = nullptr;
|
||||
|
@ -77,15 +85,15 @@ RetroHost *RetroHost::get_singleton()
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
bool RetroHost::load_core(godot::String name) {
|
||||
bool RetroHost::load_core(godot::String name)
|
||||
{
|
||||
this->unload_core();
|
||||
godot::UtilityFunctions::print("[RetroHost] Starting load_core with name: ", name);
|
||||
|
||||
godot::String lib_path;
|
||||
if (godot::OS::get_singleton()->has_feature("editor")) {
|
||||
this->cwd =
|
||||
godot::ProjectSettings::get_singleton()->globalize_path("res://") + "libretro-cores/";
|
||||
lib_path = cwd + name + ".dll"; // Editor path (Windows assumed default)
|
||||
this->cwd = godot::ProjectSettings::get_singleton()->globalize_path("res://") + "libretro-cores/";
|
||||
lib_path = cwd + name;
|
||||
godot::UtilityFunctions::print("[RetroHost] Editor mode detected. Core path: ", lib_path);
|
||||
} else {
|
||||
this->cwd = godot::OS::get_singleton()->get_executable_path().get_base_dir();
|
||||
|
@ -96,14 +104,13 @@ bool RetroHost::load_core(godot::String name) {
|
|||
#ifdef PLATFORM_WINDOWS
|
||||
this->core.handle = LoadLibrary(lib_path.utf8().get_data());
|
||||
if (this->core.handle == NULL) {
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Failed to load core \"", lib_path, "\". Error: ", GetLastErrorAsStr().c_str());
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Failed to load core \"", lib_path, "\". Error: ", GetLastErrorAsStr().c_str());
|
||||
return false;
|
||||
}
|
||||
#elif defined(PLATFORM_LINUX) || defined(PLATFORM_ANDROID)
|
||||
this->core.handle = dlopen(lib_path.utf8().get_data(), RTLD_LAZY);
|
||||
if (this->core.handle == nullptr) {
|
||||
godot::UtilityFunctions::printerr("[RetroHost] dlopen failed: ", dlerror());
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Failed to load core \"", lib_path, "\". Error: ", GetLastErrorAsStr().c_str());
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Failed to load core \"", lib_path, "\". Error: ", dlerror());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -131,46 +138,25 @@ bool RetroHost::load_core(godot::String name) {
|
|||
this->core.retro_init();
|
||||
godot::UtilityFunctions::print("[RetroHost] Core initialized successfully.");
|
||||
|
||||
godot::UtilityFunctions::print("[RetroHost] Attempting to load game...");
|
||||
if (!this->core.retro_load_game(nullptr)) {
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Failed to load game.");
|
||||
return false;
|
||||
}
|
||||
godot::UtilityFunctions::print("[RetroHost] Game loaded successfully.");
|
||||
|
||||
struct retro_system_av_info av;
|
||||
this->core.retro_get_system_av_info(&av);
|
||||
godot::UtilityFunctions::print("[RetroHost] Retrieved system AV info.");
|
||||
|
||||
this->core_video_init(&av.geometry);
|
||||
godot::UtilityFunctions::print("[RetroHost] Video initialized.");
|
||||
|
||||
this->core_audio_init(av);
|
||||
godot::UtilityFunctions::print("[RetroHost] Audio initialized.");
|
||||
|
||||
this->core.initialized = true;
|
||||
godot::UtilityFunctions::print("[RetroHost] Core fully initialized and ready.");
|
||||
return true;
|
||||
}
|
||||
|
||||
void RetroHost::unload_core()
|
||||
{
|
||||
if (this->core.initialized)
|
||||
{
|
||||
if (this->core.initialized) {
|
||||
godot::UtilityFunctions::print("[RetroHost] Deinitializing core...");
|
||||
this->core.retro_deinit();
|
||||
this->core.initialized = false;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
if (this->core.handle != NULL)
|
||||
{
|
||||
if (this->core.handle != NULL) {
|
||||
FreeLibrary(this->core.handle);
|
||||
this->core.handle = NULL;
|
||||
}
|
||||
#elif defined(PLATFORM_LINUX) || defined(PLATFORM_ANDROID)
|
||||
if (this->core.handle != nullptr)
|
||||
{
|
||||
if (this->core.handle != nullptr) {
|
||||
dlclose(this->core.handle);
|
||||
this->core.handle = nullptr;
|
||||
}
|
||||
|
@ -178,17 +164,14 @@ void RetroHost::unload_core()
|
|||
godot::UtilityFunctions::print("[RetroHost] Core unloaded successfully.");
|
||||
}
|
||||
|
||||
void RetroHost::run(){
|
||||
|
||||
godot::UtilityFunctions::print("[RetroHost] Starting core run...");
|
||||
|
||||
if (!this->core.initialized)
|
||||
{
|
||||
void RetroHost::run()
|
||||
{
|
||||
if (!this->core.initialized) {
|
||||
godot::UtilityFunctions::printerr("[RetroHost] Cannot run. Core not initialized.");
|
||||
return;
|
||||
}
|
||||
godot::UtilityFunctions::print("[RetroHost] Running core...");
|
||||
this->core.retro_run();
|
||||
godot::UtilityFunctions::print("[RetroHost] Core ran successfully.");
|
||||
}
|
||||
|
||||
void RetroHost::_bind_methods()
|
||||
|
@ -196,4 +179,4 @@ void RetroHost::_bind_methods()
|
|||
godot::ClassDB::bind_method(godot::D_METHOD("load_core", "name"), &RetroHost::load_core);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("unload_core"), &RetroHost::unload_core);
|
||||
godot::ClassDB::bind_method(godot::D_METHOD("run"), &RetroHost::run);
|
||||
}
|
||||
}
|
4
main.gd
4
main.gd
|
@ -23,10 +23,10 @@ func _ready():
|
|||
|
||||
var success = await loader.start_emulation(core_path, rom_path) # Use await to call the coroutine
|
||||
if success:
|
||||
print("[main] Game started successfully.")
|
||||
print("[main] Game started successfully")
|
||||
start_emulation_loop()
|
||||
else:
|
||||
print("[main] Failed to start the game.")
|
||||
print("[main] Failed to start the game")
|
||||
|
||||
func start_emulation_loop():
|
||||
"""
|
||||
|
|
27
prompt.sh
27
prompt.sh
|
@ -33,16 +33,23 @@ done
|
|||
write ""
|
||||
write "My issue now is the following, can you help me to fix it?"
|
||||
write '
|
||||
When I load godot I get this crash:
|
||||
My issue is that I am not able to start the emulated game, I am getting the following error:
|
||||
|
||||
godot .
|
||||
Godot Engine v4.3.stable.flathub.77dcf97d8 - https://godotengine.org
|
||||
OpenGL API 4.6 (Core Profile) Mesa 24.2.7 (git-3900828265) - Compatibility - Using Device: Intel - Mesa Intel(R) Graphics (ADL GT2)
|
||||
|
||||
================================================================
|
||||
handle_crash: Program crashed with signal 11
|
||||
Engine version: Godot Engine v4.2.2.rc2.mono.official (c61a68614e5b030a4a1e11abaa5a893b8017f78d)
|
||||
Dumping the backtrace. Please include this when reporting the bug to the project developer.
|
||||
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x45250) [0x7ea94c445250] (??:0)
|
||||
-- END OF BACKTRACE --
|
||||
================================================================
|
||||
Annullato (core dump creato)
|
||||
[RetroHost] Initializing extension...
|
||||
[RetroHost] RetroHost class registered.
|
||||
[RetroHost] Constructor called. Initializing singleton.
|
||||
[RetroHost] Initialization complete.
|
||||
[RetroHost] Singleton registered successfully.
|
||||
[main] Entering _ready function
|
||||
[main] File res://cores/genesis_plus_gx_libretro.so exists
|
||||
[main] File res://roms/megadrive/Sonic the Hedgehog.bin exists
|
||||
[main] Core path: res://cores/genesis_plus_gx_libretro.so
|
||||
[main] ROM path: res://roms/megadrive/Sonic the Hedgehog.bin
|
||||
[libretro_loader] Starting emulation with core: res://cores/genesis_plus_gx_libretro.so, ROM: res://roms/megadrive/Sonic the Hedgehog.bin
|
||||
[libretro_loader] RetroHost status: <null>
|
||||
[libretro_loader] RetroHost singleton not found!
|
||||
[main] Failed to start the game
|
||||
'
|
|
@ -10,17 +10,26 @@ var current_rom : String = "" # Initialize to an empty string
|
|||
func start_emulation(core_path: String, rom_path: String) -> bool:
|
||||
print("[libretro_loader] Starting emulation with core: ", core_path, ", ROM: ", rom_path)
|
||||
|
||||
# Debug RetroHost access
|
||||
print("[libretro_loader] RetroHost status: ", retro_host)
|
||||
|
||||
# Check if RetroHost is available
|
||||
if not retro_host:
|
||||
push_error("[libretro_loader] RetroHost singleton not found!")
|
||||
var message = "[libretro_loader] RetroHost singleton not found!"
|
||||
push_error(message)
|
||||
print(message)
|
||||
return false
|
||||
|
||||
if not core_path:
|
||||
push_error("[libretro_loader] Core path is missing.")
|
||||
var message = "[libretro_loader] Core path is missing."
|
||||
push_error(message)
|
||||
print(message)
|
||||
return false
|
||||
|
||||
|
||||
if not rom_path:
|
||||
push_error("[libretro_loader] ROM path is missing.")
|
||||
var message = "[libretro_loader] ROM path is missing."
|
||||
push_error(message)
|
||||
print(message)
|
||||
return false
|
||||
|
||||
# Load the core (via RetroHost)
|
||||
|
@ -100,26 +109,37 @@ func _process(delta):
|
|||
|
||||
func _ready():
|
||||
"""
|
||||
Initializes the SubViewport and TextureRect.
|
||||
Initializes the SubViewport and TextureRect and waits for RetroHost singleton.
|
||||
"""
|
||||
print("[libretro_loader] _ready: Initializing SubViewport and TextureRect.")
|
||||
if sub_viewport and texture_rect:
|
||||
print("[libretro_loader] SubViewport and TextureRect initialized successfully.")
|
||||
else:
|
||||
push_error("Error: SubViewport or TextureRect is missing.")
|
||||
push_error("[libretro_loader] Error: SubViewport or TextureRect is missing.")
|
||||
return
|
||||
|
||||
if not retro_host:
|
||||
push_error("[libretro_loader] RetroHost singleton not found! Emulation cannot proceed.")
|
||||
return
|
||||
print("[libretro_loader] RetroHost singleton initialized successfully.")
|
||||
|
||||
# Ensure SubViewport always renders
|
||||
sub_viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
||||
print("[libretro_loader] SubViewport set to always update.")
|
||||
|
||||
# Use await to call the coroutine
|
||||
var success = await start_emulation("res://cores/genesis_plus_gx_libretro.so", "res://roms/megadrive/Sonic")
|
||||
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")
|
||||
if success:
|
||||
print("[libretro_loader] Emulation started successfully.")
|
||||
else:
|
||||
|
|
Loading…
Reference in a new issue