Dusklight mod API core

Co-authored-by: qwertyquerty <qwertytrogi@gmail.com>
Co-authored-by: PJB3005 <pieterjan.briers+git@gmail.com>
This commit is contained in:
Luke Street
2026-07-07 01:21:01 -06:00
parent b474aafe9d
commit 5c9c76cc0b
35 changed files with 3645 additions and 147 deletions
+57 -1
View File
@@ -60,6 +60,7 @@
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/imgui/ImGuiEngine.hpp"
#include "dusk/iso_validate.hpp"
#include "dusk/mod_loader.hpp"
#include "dusk/logging.h"
#include "dusk/main.h"
#include "dusk/ui/menu_bar.hpp"
@@ -363,6 +364,7 @@ void main01(void) {
} while (dusk::IsRunning);
exit:;
dusk::mods::ModLoader::instance().shutdown();
dusk::ui::shutdown();
}
@@ -512,6 +514,7 @@ int game_main(int argc, char* argv[]) {
("h,help", "Print usage")
("console", "Show the Windows console window for logs", cxxopts::value<bool>()->default_value("false")->implicit_value("true"))
("dvd", "Path to DVD image file", cxxopts::value<std::string>())
("mods", "Path to mods directory", cxxopts::value<std::string>())
("backend", "Graphics API backend to use (auto, d3d12, d3d11, metal, vulkan, null)", cxxopts::value<std::string>())
("cvar", "Override configuration variables without modifying config", cxxopts::value<std::vector<std::string>>());
@@ -785,8 +788,61 @@ int game_main(int argc, char* argv[]) {
// mDoMain::developmentMode = 1; // Force Dev Mode for Debugging
mDoDvdThd::SyncWidthSound = false;
OSReport("Starting main01 (Game Loop)...\n");
// Mod search directories, highest priority first: user dir (--mods replaces it), then
// mods/ next to the app, then install-bundled mods inside the app bundle.
{
std::vector<dusk::mods::ModSearchDir> modDirs;
if (parsed_arg_options.contains("mods") &&
!parsed_arg_options["mods"].as<std::string>().empty())
{
modDirs.push_back({.path = parsed_arg_options["mods"].as<std::string>()});
} else {
modDirs.push_back({.path = dusk::ConfigPath / "mods"});
}
#if TARGET_ANDROID
// APK-bundled mods are extracted to internal storage
// by DuskActivity before SDL_main runs.
modDirs.push_back({
.path = dusk::CachePath / "bundled_mods",
});
#elif defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)
modDirs.push_back({
.path = dusk::data::base_path_relative("mods"),
.inPlaceNative = true,
.nativeLibDir = dusk::data::base_path_relative("Frameworks"),
});
#else
#if defined(__APPLE__)
// Base path is Contents/Resources; search up for dev mods
// TODO: scope to non-CI builds
modDirs.push_back({
.path = dusk::data::base_path_relative("../../../mods").lexically_normal(),
.inPlaceNative = true,
});
// Contents/Resources/mods
modDirs.push_back({
.path = dusk::data::base_path_relative("mods"),
.inPlaceNative = true,
});
#else
modDirs.push_back({
.path = dusk::data::base_path_relative("mods"),
.inPlaceNative = true,
});
#endif
#endif
dusk::mods::ModLoader::instance().set_search_dirs(std::move(modDirs));
}
#if TARGET_ANDROID
// A user-relocated data dir can live on external storage, which is mounted noexec.
// Native mod libraries must be extracted to internal storage.
dusk::mods::ModLoader::instance().set_cache_dir(dusk::CachePath / "mod_cache");
#endif
DuskLog.info("Initializing mods...");
dusk::mods::ModLoader::instance().init();
OSReport("Starting main01 (Game Loop)...\n");
main01();