mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-30 08:01:13 -04:00
Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer
This commit is contained in:
@@ -253,3 +253,9 @@ void dusk::ImGuiMenuTools::ShowAudioDebug() {
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void dusk::ImGuiMenuTools::ShowSaveEditor() {
|
||||
if (m_showSaveEditor) {
|
||||
m_saveEditor.draw(m_showSaveEditor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace dusk {
|
||||
windowFlags |= ImGuiWindowFlags_NoMove;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
// ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
if (!ImGui::Begin("Camera Debug", nullptr, windowFlags)) {
|
||||
ImGui::End();
|
||||
|
||||
+112
-31
@@ -14,6 +14,7 @@
|
||||
#include "JSystem/JUtility/JUTGamePad.h"
|
||||
#include "SDL3/SDL_mouse.h"
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "dusk/audio/DuskAudioSystem.h"
|
||||
#include "dusk/dusk.h"
|
||||
@@ -35,6 +36,21 @@ namespace dusk {
|
||||
ImGui::TextUnformatted(text.data(), text.data() + text.size());
|
||||
}
|
||||
|
||||
void ImGuiTextCenter(std::string_view text) {
|
||||
ImGui::NewLine();
|
||||
float fontSize = ImGui::CalcTextSize(text.data(), text.data() + text.size()).x;
|
||||
ImGui::SameLine(ImGui::GetWindowSize().x / 2 - fontSize + fontSize / 2);
|
||||
ImGuiStringViewText(text);
|
||||
}
|
||||
|
||||
bool ImGuiButtonCenter(std::string_view text) {
|
||||
ImGui::NewLine();
|
||||
float fontSize = ImGui::CalcTextSize(text.data(), text.data() + text.size()).x;
|
||||
fontSize += ImGui::GetStyle().FramePadding.x;
|
||||
ImGui::SameLine(ImGui::GetWindowSize().x / 2 - fontSize + fontSize / 2);
|
||||
return ImGui::Button(text.data());
|
||||
}
|
||||
|
||||
std::string BytesToString(size_t bytes) {
|
||||
constexpr std::array suffixes{ "B"sv, "KB"sv, "MB"sv, "GB"sv, "TB"sv, "PB"sv, "EB"sv };
|
||||
uint32_t s = 0;
|
||||
@@ -184,33 +200,19 @@ namespace dusk {
|
||||
|
||||
ImGuiConsole::ImGuiConsole() {}
|
||||
|
||||
void ImGuiConsole::InitSettings() {
|
||||
bool lockAspect = getSettings().video.lockAspectRatio;
|
||||
if (lockAspect) {
|
||||
VILockAspectRatio(defaultAspectRatioW, defaultAspectRatioH);
|
||||
} else {
|
||||
VIUnlockAspectRatio();
|
||||
}
|
||||
|
||||
dusk::audio::SetMasterVolume(getSettings().audio.masterVolume / 100.0f);
|
||||
dusk::audio::SetEnableReverb(getSettings().audio.enableReverb);
|
||||
}
|
||||
|
||||
void ImGuiConsole::UpdateSettings() {
|
||||
getTransientSettings().skipFrameRateLimit = getSettings().game.enableTurboKeybind && ImGui::IsKeyDown(ImGuiKey_Tab);
|
||||
}
|
||||
|
||||
void ImGuiConsole::PreDraw() {
|
||||
ZoneScoped;
|
||||
if (!m_isLaunchInitialized) {
|
||||
InitSettings();
|
||||
|
||||
if (dusk::IsGameLaunched && !m_isLaunchInitialized) {
|
||||
m_toasts.emplace_back("Press F1 to toggle menu"s, 5.f);
|
||||
m_isLaunchInitialized = true;
|
||||
}
|
||||
|
||||
UpdateSettings();
|
||||
|
||||
|
||||
if ((ImGui::IsKeyDown(ImGuiKey_LeftCtrl) || ImGui::IsKeyDown(ImGuiKey_RightCtrl)) &&
|
||||
ImGui::IsKeyPressed(ImGuiKey_R))
|
||||
{
|
||||
@@ -221,24 +223,11 @@ namespace dusk {
|
||||
ImGuiMenuGame::ToggleFullscreen();
|
||||
}
|
||||
|
||||
if (CheckMenuViewToggle(ImGuiKey_F1, m_isHidden)) {
|
||||
ShowToasts();
|
||||
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
|
||||
SDL_HideCursor();
|
||||
return;
|
||||
}
|
||||
bool showMenu = !dusk::IsGameLaunched || !CheckMenuViewToggle(ImGuiKey_F1, m_isHidden);
|
||||
|
||||
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
|
||||
// Imgui will re-show cursor.
|
||||
|
||||
// TODO: we need to be able to render the menu bar & any overlays separately
|
||||
// The code currently ties them all together, so hiding the menu hides all windows
|
||||
|
||||
if (ImGui::BeginMainMenuBar()) {
|
||||
if (showMenu && ImGui::BeginMainMenuBar()) {
|
||||
m_menuGame.draw();
|
||||
m_menuEnhancements.draw();
|
||||
|
||||
// Keep always last
|
||||
m_menuTools.draw();
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 80.0f * ImGuiScale());
|
||||
@@ -248,6 +237,34 @@ namespace dusk {
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
if (!dusk::IsGameLaunched) {
|
||||
m_preLaunchWindow.draw();
|
||||
}
|
||||
|
||||
m_menuGame.windowControllerConfig();
|
||||
m_menuGame.windowInputViewer();
|
||||
if (dusk::IsGameLaunched) {
|
||||
m_menuTools.ShowDebugOverlay();
|
||||
m_menuTools.ShowCameraOverlay();
|
||||
m_menuTools.ShowProcessManager();
|
||||
m_menuTools.ShowHeapOverlay();
|
||||
m_menuTools.ShowStubLog();
|
||||
m_menuTools.ShowMapLoader();
|
||||
m_menuTools.ShowPlayerInfo();
|
||||
m_menuTools.ShowAudioDebug();
|
||||
m_menuTools.ShowSaveEditor();
|
||||
}
|
||||
DuskDebugPad(); // temporary, remove later
|
||||
|
||||
// Only show cursor when menu or any windows are open
|
||||
if (showMenu || ImGui::GetIO().MetricsRenderWindows > 0) {
|
||||
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange;
|
||||
// Imgui will re-show cursor.
|
||||
} else {
|
||||
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
|
||||
SDL_HideCursor();
|
||||
}
|
||||
|
||||
ShowToasts();
|
||||
}
|
||||
|
||||
@@ -287,6 +304,70 @@ namespace dusk {
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view backend_id(AuroraBackend backend) {
|
||||
switch (backend) {
|
||||
default:
|
||||
return "auto"sv;
|
||||
case BACKEND_D3D12:
|
||||
return "d3d12"sv;
|
||||
case BACKEND_D3D11:
|
||||
return "d3d11"sv;
|
||||
case BACKEND_METAL:
|
||||
return "metal"sv;
|
||||
case BACKEND_VULKAN:
|
||||
return "vulkan"sv;
|
||||
case BACKEND_OPENGL:
|
||||
return "opengl"sv;
|
||||
case BACKEND_OPENGLES:
|
||||
return "opengles"sv;
|
||||
case BACKEND_WEBGPU:
|
||||
return "webgpu"sv;
|
||||
case BACKEND_NULL:
|
||||
return "null"sv;
|
||||
}
|
||||
}
|
||||
|
||||
bool try_parse_backend(std::string_view backend, AuroraBackend& outBackend) {
|
||||
if (backend == "auto") {
|
||||
outBackend = BACKEND_AUTO;
|
||||
return true;
|
||||
}
|
||||
if (backend == "d3d11") {
|
||||
outBackend = BACKEND_D3D11;
|
||||
return true;
|
||||
}
|
||||
if (backend == "d3d12") {
|
||||
outBackend = BACKEND_D3D12;
|
||||
return true;
|
||||
}
|
||||
if (backend == "metal") {
|
||||
outBackend = BACKEND_METAL;
|
||||
return true;
|
||||
}
|
||||
if (backend == "vulkan") {
|
||||
outBackend = BACKEND_VULKAN;
|
||||
return true;
|
||||
}
|
||||
if (backend == "opengl") {
|
||||
outBackend = BACKEND_OPENGL;
|
||||
return true;
|
||||
}
|
||||
if (backend == "opengles") {
|
||||
outBackend = BACKEND_OPENGLES;
|
||||
return true;
|
||||
}
|
||||
if (backend == "webgpu") {
|
||||
outBackend = BACKEND_WEBGPU;
|
||||
return true;
|
||||
}
|
||||
if (backend == "null") {
|
||||
outBackend = BACKEND_NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImGuiConsole::ShowToasts() {
|
||||
if (m_toasts.empty()) {
|
||||
return;
|
||||
|
||||
@@ -4,17 +4,18 @@
|
||||
#include <aurora/aurora.h>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "ImGuiMenuEnhancements.hpp"
|
||||
#include "ImGuiMenuGame.hpp"
|
||||
#include "ImGuiMenuTools.hpp"
|
||||
#include "ImGuiPreLaunchWindow.hpp"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace dusk {
|
||||
class ImGuiConsole {
|
||||
public:
|
||||
ImGuiConsole();
|
||||
void InitSettings();
|
||||
void UpdateSettings();
|
||||
void PreDraw();
|
||||
void PostDraw();
|
||||
@@ -36,6 +37,7 @@ private:
|
||||
|
||||
ImGuiMenuGame m_menuGame;
|
||||
ImGuiMenuEnhancements m_menuEnhancements;
|
||||
ImGuiPreLaunchWindow m_preLaunchWindow;
|
||||
|
||||
// Keep always last
|
||||
ImGuiMenuTools m_menuTools;
|
||||
@@ -47,12 +49,16 @@ private:
|
||||
extern ImGuiConsole g_imguiConsole;
|
||||
|
||||
std::string_view backend_name(AuroraBackend backend);
|
||||
std::string_view backend_id(AuroraBackend backend);
|
||||
bool try_parse_backend(std::string_view backend, AuroraBackend& outBackend);
|
||||
std::string BytesToString(size_t bytes);
|
||||
void SetOverlayWindowLocation(int corner);
|
||||
bool ShowCornerContextMenu(int& corner, int avoidCorner);
|
||||
void ImGuiStringViewText(std::string_view text);
|
||||
void ImGuiBeginGroupPanel(const char* name, const ImVec2& size);
|
||||
void ImGuiEndGroupPanel();
|
||||
void ImGuiTextCenter(std::string_view text);
|
||||
bool ImGuiButtonCenter(std::string_view text);
|
||||
float ImGuiScale();
|
||||
} // namespace dusk
|
||||
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
#include "ImGuiMenuGame.hpp"
|
||||
|
||||
namespace dusk {
|
||||
void TextCenter(const std::string& text) {
|
||||
float font_size = ImGui::GetFontSize() * text.size() / 2;
|
||||
ImGui::SameLine(ImGui::GetWindowSize().x / 2 - font_size + (font_size / 2));
|
||||
|
||||
ImGui::TextUnformatted(text.c_str());
|
||||
}
|
||||
|
||||
void ImGuiMenuGame::windowInputViewer() {
|
||||
if (!m_showInputViewer) {
|
||||
return;
|
||||
@@ -35,7 +28,7 @@ namespace dusk {
|
||||
if (ImGui::Begin("Input Viewer", nullptr, windowFlags)) {
|
||||
float scale = ImGuiScale();
|
||||
if (!m_controllerName.empty()) {
|
||||
TextCenter(m_controllerName);
|
||||
ImGuiTextCenter(m_controllerName);
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <aurora/imgui.h>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
|
||||
#include "dusk/logging.h"
|
||||
@@ -32,66 +33,64 @@ bool AssetExists(const std::string& path) {
|
||||
|
||||
ImFont* ImGuiEngine::fontNormal;
|
||||
ImFont* ImGuiEngine::fontLarge;
|
||||
ImTextureID ImGuiEngine::duskIcon;
|
||||
ImFont* ImGuiEngine::fontExtraLarge;
|
||||
ImFont* ImGuiEngine::fontMono;
|
||||
ImTextureID ImGuiEngine::duskIcon = 0;
|
||||
|
||||
inline ImFont* CreateFont(float size, const std::string& fontPath, std::string_view fontName) {
|
||||
bool fontFileExists = !fontPath.empty() && AssetExists(fontPath);
|
||||
ImFontConfig fontConfig{};
|
||||
fontConfig.SizePixels = size;
|
||||
auto name = fmt::format_to_n(fontConfig.Name, sizeof(fontConfig.Name) - 1, "{}, {}px", fontName,
|
||||
static_cast<int>(fontConfig.SizePixels));
|
||||
*name.out = '\0';
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
ImFont* outFont =
|
||||
fontFileExists ?
|
||||
io.Fonts->AddFontFromFileTTF(fontPath.c_str(), fontConfig.SizePixels, &fontConfig) :
|
||||
nullptr;
|
||||
if (outFont == nullptr) {
|
||||
if (fontFileExists) {
|
||||
DuskLog.warn("Failed to load font '{}': {}", fontPath, SDL_GetError());
|
||||
}
|
||||
outFont = io.Fonts->AddFontDefault(&fontConfig);
|
||||
}
|
||||
return outFont;
|
||||
}
|
||||
|
||||
void ImGuiEngine_Initialize(float scale) {
|
||||
// Round font scale to nearest integer
|
||||
scale = std::ceilf(scale);
|
||||
|
||||
ImGui::GetCurrentContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->Clear();
|
||||
io.FontGlobalScale = scale > 0.0f ? 1.0f / scale : 1.0f;
|
||||
|
||||
const std::string fontPath = GetAssetPath("NotoMono-Regular.ttf");
|
||||
const bool hasFontFile = AssetExists(fontPath);
|
||||
|
||||
ImFontConfig fontConfig{};
|
||||
fontConfig.SizePixels = std::floor(15.f * scale);
|
||||
snprintf(static_cast<char*>(fontConfig.Name), sizeof(fontConfig.Name),
|
||||
"Noto Mono Regular, %dpx", static_cast<int>(fontConfig.SizePixels));
|
||||
ImGuiEngine::fontNormal =
|
||||
hasFontFile ?
|
||||
io.Fonts->AddFontFromFileTTF(fontPath.c_str(), fontConfig.SizePixels, &fontConfig) :
|
||||
nullptr;
|
||||
if (ImGuiEngine::fontNormal == nullptr) {
|
||||
if (hasFontFile) {
|
||||
DuskLog.warn("Failed to load font '{}': {}", fontPath, SDL_GetError());
|
||||
}
|
||||
ImGuiEngine::fontNormal = io.Fonts->AddFontDefault(&fontConfig);
|
||||
}
|
||||
|
||||
fontConfig.SizePixels = std::floor(26.f * scale);
|
||||
#ifdef IMGUI_ENABLE_FREETYPE
|
||||
fontConfig.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold;
|
||||
snprintf(static_cast<char*>(fontConfig.Name), sizeof(fontConfig.Name), "Noto Mono Bold, %dpx",
|
||||
static_cast<int>(fontConfig.SizePixels));
|
||||
#else
|
||||
snprintf(static_cast<char*>(fontConfig.Name), sizeof(fontConfig.Name),
|
||||
"Noto Mono Regular, %dpx", static_cast<int>(fontConfig.SizePixels));
|
||||
#endif
|
||||
CreateFont(std::floor(18.f * scale), GetAssetPath("Inter-Regular.ttf"), "Inter Regular");
|
||||
ImGuiEngine::fontLarge =
|
||||
hasFontFile ?
|
||||
io.Fonts->AddFontFromFileTTF(fontPath.c_str(), fontConfig.SizePixels, &fontConfig) :
|
||||
nullptr;
|
||||
if (ImGuiEngine::fontLarge == nullptr) {
|
||||
if (hasFontFile) {
|
||||
DuskLog.warn("Failed to load font '{}': {}", fontPath, SDL_GetError());
|
||||
}
|
||||
ImGuiEngine::fontLarge = io.Fonts->AddFontDefault(&fontConfig);
|
||||
}
|
||||
CreateFont(std::floor(26.f * scale), GetAssetPath("Inter-Regular.ttf"), "Inter Regular");
|
||||
ImGuiEngine::fontExtraLarge =
|
||||
CreateFont(std::floor(40.f * scale), GetAssetPath("Inter-Bold.ttf"), "Inter Bold");
|
||||
ImGuiEngine::fontMono =
|
||||
CreateFont(std::floor(16.f * scale), GetAssetPath("NotoMono-Regular.ttf"),
|
||||
"Noto Mono Regular");
|
||||
|
||||
auto& style = ImGui::GetStyle();
|
||||
style = {}; // Reset sizes
|
||||
style.WindowPadding = ImVec2(15, 15);
|
||||
style.WindowRounding = 5.0f;
|
||||
style.FrameBorderSize = 1.f;
|
||||
style.FramePadding = ImVec2(5, 5);
|
||||
style.FramePadding = ImVec2(8, 5);
|
||||
style.FrameRounding = 4.0f;
|
||||
style.ItemSpacing = ImVec2(12, 8);
|
||||
style.ItemInnerSpacing = ImVec2(8, 6);
|
||||
style.IndentSpacing = 25.0f;
|
||||
style.ScrollbarSize = 15.0f;
|
||||
style.ScrollbarRounding = 9.0f;
|
||||
style.GrabMinSize = 5.0f;
|
||||
style.GrabRounding = 3.0f;
|
||||
style.GrabMinSize = 20.0f;
|
||||
style.GrabRounding = 5.0f;
|
||||
style.PopupBorderSize = 1.f;
|
||||
style.PopupRounding = 7.0;
|
||||
style.TabBorderSize = 1.f;
|
||||
@@ -146,25 +145,23 @@ void ImGuiEngine_Initialize(float scale) {
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
|
||||
}
|
||||
|
||||
Icon GetIcon() {
|
||||
const std::string iconPath = GetAssetPath("icon.png");
|
||||
if (!AssetExists(iconPath)) {
|
||||
Image GetImage(const std::string& path) {
|
||||
if (!AssetExists(path)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
SDL_Surface* loadedSurface = SDL_LoadPNG(iconPath.c_str());
|
||||
SDL_Surface* loadedSurface = SDL_LoadPNG(path.c_str());
|
||||
if (loadedSurface == nullptr) {
|
||||
DuskLog.warn("Failed to load icon '{}': {}", iconPath, SDL_GetError());
|
||||
DuskLog.warn("Failed to load image '{}': {}", path, SDL_GetError());
|
||||
return {};
|
||||
}
|
||||
|
||||
SDL_Surface* rgbaSurface = SDL_ConvertSurface(loadedSurface, SDL_PIXELFORMAT_RGBA32);
|
||||
SDL_DestroySurface(loadedSurface);
|
||||
if (rgbaSurface == nullptr) {
|
||||
DuskLog.warn("Failed to convert icon '{}': {}", iconPath, SDL_GetError());
|
||||
DuskLog.warn("Failed to convert image '{}': {}", path, SDL_GetError());
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -181,7 +178,7 @@ Icon GetIcon() {
|
||||
}
|
||||
|
||||
SDL_DestroySurface(rgbaSurface);
|
||||
return Icon{
|
||||
return Image{
|
||||
std::move(ptr),
|
||||
size,
|
||||
iconWidth,
|
||||
@@ -190,12 +187,13 @@ Icon GetIcon() {
|
||||
}
|
||||
|
||||
void ImGuiEngine_AddTextures() {
|
||||
auto icon = GetIcon();
|
||||
if (icon.data == nullptr || icon.width == 0 || icon.height == 0) {
|
||||
ImGuiEngine::duskIcon = 0;
|
||||
return;
|
||||
if (ImGuiEngine::duskIcon == 0) {
|
||||
auto icon = GetImage(GetAssetPath("icon.png"));
|
||||
if (icon.data == nullptr || icon.width == 0 || icon.height == 0) {
|
||||
ImGuiEngine::duskIcon = 0;
|
||||
return;
|
||||
}
|
||||
ImGuiEngine::duskIcon = aurora_imgui_add_texture(icon.width, icon.height, icon.data.get());
|
||||
}
|
||||
|
||||
ImGuiEngine::duskIcon = aurora_imgui_add_texture(icon.width, icon.height, icon.data.get());
|
||||
}
|
||||
} // namespace dusk
|
||||
|
||||
@@ -9,17 +9,19 @@ class ImGuiEngine {
|
||||
public:
|
||||
static ImFont* fontNormal;
|
||||
static ImFont* fontLarge;
|
||||
static ImFont* fontExtraLarge;
|
||||
static ImFont* fontMono;
|
||||
static ImTextureID duskIcon;
|
||||
};
|
||||
|
||||
void ImGuiEngine_Initialize(float scale);
|
||||
void ImGuiEngine_AddTextures();
|
||||
|
||||
struct Icon {
|
||||
struct Image {
|
||||
std::unique_ptr<uint8_t[]> data;
|
||||
size_t size;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
Icon GetIcon();
|
||||
Image GetImage(std::string_view path);
|
||||
} // namespace dusk
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace dusk {
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
// ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
if (!ImGui::Begin("Map Loader", &m_showMapLoader, windowFlags)) {
|
||||
ImGui::End();
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <aurora/gfx.h>
|
||||
|
||||
#include "dusk/main.h"
|
||||
|
||||
namespace dusk {
|
||||
void ImGuiMenuGame::ToggleFullscreen() {
|
||||
getSettings().video.enableFullscreen.setValue(!getSettings().video.enableFullscreen);
|
||||
@@ -28,12 +30,6 @@ namespace dusk {
|
||||
|
||||
void ImGuiMenuGame::draw() {
|
||||
if (ImGui::BeginMenu("Game")) {
|
||||
if (ImGui::MenuItem("Reset", hotkeys::DO_RESET)) {
|
||||
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginMenu("Graphics")) {
|
||||
if (ImGui::MenuItem("Toggle Fullscreen", hotkeys::TOGGLE_FULLSCREEN)) {
|
||||
ToggleFullscreen();
|
||||
@@ -107,11 +103,24 @@ namespace dusk {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Misc")) {
|
||||
config::ImGuiCheckbox("Skip Pre-Launch UI", getSettings().backend.skipPreLaunchUI);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Reset", hotkeys::DO_RESET)) {
|
||||
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Exit")) {
|
||||
dusk::IsRunning = false;
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
windowInputViewer();
|
||||
windowControllerConfig();
|
||||
}
|
||||
|
||||
static void drawVirtualStick(const char* id, const ImVec2& stick) {
|
||||
@@ -176,7 +185,7 @@ namespace dusk {
|
||||
ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_AlwaysAutoResize;
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
// ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
if (!ImGui::Begin("Controller Config", &m_showControllerConfig, windowFlags)) {
|
||||
ImGui::End();
|
||||
@@ -259,6 +268,7 @@ namespace dusk {
|
||||
|
||||
// buttons panel
|
||||
const float uiButtonSize = 40 * scale;
|
||||
ImVec2 btnSize(110.0f * scale, 30.0f * scale);
|
||||
|
||||
ImGuiBeginGroupPanel("Buttons", ImVec2(150 * scale, 20 * scale));
|
||||
|
||||
@@ -281,10 +291,14 @@ namespace dusk {
|
||||
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingButtonMapping == &btnMappingList[i]) {
|
||||
dispName = fmt::format("Press a Key...##{}", btnName);
|
||||
} else {
|
||||
dispName = fmt::format("{0}##-{1}", PADGetNativeButtonName(btnMappingList[i].nativeButton), i);
|
||||
const char* nativeName = PADGetNativeButtonName(btnMappingList[i].nativeButton);
|
||||
if (nativeName == nullptr) {
|
||||
nativeName = "[unbound]";
|
||||
}
|
||||
dispName = fmt::format("{0}##-{1}", nativeName, i);
|
||||
}
|
||||
bool pressed = ImGui::Button(dispName.c_str(),
|
||||
ImVec2(100.0f * scale, 20.0f * scale));
|
||||
btnSize);
|
||||
|
||||
if (pressed) {
|
||||
m_controllerConfig.m_isReading = true;
|
||||
@@ -324,7 +338,7 @@ namespace dusk {
|
||||
dispName = fmt::format("{0}##-{1}", PADGetNativeAxisName(axisMappingList[trigger].nativeAxis), trigger);
|
||||
}
|
||||
bool pressed = ImGui::Button(dispName.c_str(),
|
||||
ImVec2(100.0f * scale, 20.0f * scale));
|
||||
btnSize);
|
||||
|
||||
if (pressed) {
|
||||
m_controllerConfig.m_isReading = true;
|
||||
@@ -401,7 +415,7 @@ namespace dusk {
|
||||
dispName = fmt::format("{0}##-{1}", PADGetNativeButtonName(axisMappingList[axis].nativeButton), axis);
|
||||
}
|
||||
}
|
||||
bool pressed = ImGui::Button(dispName.c_str(), ImVec2(100.0f * scale, 20.0f * scale));
|
||||
bool pressed = ImGui::Button(dispName.c_str(), btnSize);
|
||||
|
||||
if (pressed) {
|
||||
m_controllerConfig.m_isReading = true;
|
||||
@@ -463,7 +477,7 @@ namespace dusk {
|
||||
dispName = fmt::format("{0}##-{1}", PADGetNativeButtonName(axisMappingList[axis].nativeButton), axis);
|
||||
}
|
||||
}
|
||||
bool pressed = ImGui::Button(fmt::format("{0}##sub{1}", dispName, label).c_str(), ImVec2(100.0f * scale, 20.0f * scale));
|
||||
bool pressed = ImGui::Button(fmt::format("{0}##sub{1}", dispName, label).c_str(), btnSize);
|
||||
|
||||
if (pressed) {
|
||||
m_controllerConfig.m_isReading = true;
|
||||
|
||||
@@ -7,21 +7,22 @@
|
||||
#include "ImGuiConsole.hpp"
|
||||
#include "ImGuiMenuTools.hpp"
|
||||
|
||||
#include "ImGuiEngine.hpp"
|
||||
#include "d/actor/d_a_alink.h"
|
||||
#include "d/actor/d_a_horse.h"
|
||||
#include "d/d_com_inf_game.h"
|
||||
#include "dusk/dusk.h"
|
||||
#include "dusk/main.h"
|
||||
#include "m_Do/m_Do_main.h"
|
||||
|
||||
namespace dusk {
|
||||
ImGuiMenuTools::ImGuiMenuTools() {}
|
||||
|
||||
void ImGuiMenuTools::draw() {
|
||||
bool isToggleDevelopmentMode = false;
|
||||
|
||||
if (ImGui::BeginMenu("Debug")) {
|
||||
if (ImGui::Checkbox("Development Mode", &m_isDevelopmentMode)) {
|
||||
isToggleDevelopmentMode = true;
|
||||
bool developmentMode = mDoMain::developmentMode == 1;
|
||||
if (ImGui::Checkbox("Development Mode", &developmentMode)) {
|
||||
mDoMain::developmentMode = developmentMode ? 1 : -1;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
@@ -40,6 +41,10 @@ namespace dusk {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (!dusk::IsGameLaunched) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
ImGui::MenuItem("Process Management", hotkeys::SHOW_PROCESS_MANAGEMENT, &m_showProcessManagement);
|
||||
ImGui::MenuItem("Debug Overlay", hotkeys::SHOW_DEBUG_OVERLAY, &m_showDebugOverlay);
|
||||
ImGui::MenuItem("Heap Viewer", hotkeys::SHOW_HEAP_VIEWER, &m_showHeapOverlay);
|
||||
@@ -49,28 +54,14 @@ namespace dusk {
|
||||
ImGui::MenuItem("Player Info", nullptr, &m_showPlayerInfo);
|
||||
ImGui::MenuItem("Save Editor", nullptr, &m_showSaveEditor);
|
||||
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
|
||||
|
||||
if (!dusk::IsGameLaunched) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::MenuItem("OSReport Force", nullptr, &OSReportReallyForceEnable);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (isToggleDevelopmentMode) {
|
||||
mDoMain::developmentMode = m_isDevelopmentMode ? 1 : -1;
|
||||
}
|
||||
|
||||
ShowDebugOverlay();
|
||||
ShowCameraOverlay();
|
||||
ShowProcessManager();
|
||||
ShowHeapOverlay();
|
||||
ShowStubLog();
|
||||
ShowMapLoader();
|
||||
ShowPlayerInfo();
|
||||
ShowAudioDebug();
|
||||
|
||||
if (m_showSaveEditor) {
|
||||
m_saveEditor.draw(m_showSaveEditor);
|
||||
}
|
||||
|
||||
DuskDebugPad(); // temporary, remove later
|
||||
}
|
||||
|
||||
void ImGuiMenuTools::ShowDebugOverlay() {
|
||||
@@ -78,6 +69,8 @@ namespace dusk {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::PushFont(ImGuiEngine::fontMono);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
@@ -90,26 +83,14 @@ namespace dusk {
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
if (ImGui::Begin("Debug Overlay", nullptr, windowFlags)) {
|
||||
bool hasPrevious = false;
|
||||
if (hasPrevious) {
|
||||
ImGui::Separator();
|
||||
}
|
||||
hasPrevious = true;
|
||||
|
||||
ImGuiStringViewText(fmt::format(FMT_STRING("FPS: {:.2f}\n"), io.Framerate));
|
||||
ImGuiStringViewText(fmt::format(FMT_STRING("Frame usage: {:.1f}%\n"), frameUsagePct));
|
||||
|
||||
if (hasPrevious) {
|
||||
ImGui::Separator();
|
||||
}
|
||||
hasPrevious = true;
|
||||
ImGui::Separator();
|
||||
|
||||
ImGuiStringViewText(fmt::format(FMT_STRING("Backend: {}\n"), backend_name(aurora_get_backend())));
|
||||
|
||||
if (hasPrevious) {
|
||||
ImGui::Separator();
|
||||
}
|
||||
hasPrevious = true;
|
||||
ImGui::Separator();
|
||||
|
||||
const auto& stats = lastFrameAuroraStats;
|
||||
|
||||
@@ -141,6 +122,8 @@ namespace dusk {
|
||||
ShowCornerContextMenu(m_debugOverlayCorner, m_cameraOverlayCorner);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
void ImGuiMenuTools::ShowPlayerInfo() {
|
||||
@@ -148,13 +131,20 @@ namespace dusk {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiWindowFlags windowFlags =
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize;
|
||||
ImGui::PushFont(ImGuiEngine::fontMono);
|
||||
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoNav;
|
||||
if (m_playerInfoOverlayCorner != -1) {
|
||||
SetOverlayWindowLocation(m_playerInfoOverlayCorner);
|
||||
windowFlags |= ImGuiWindowFlags_NoMove;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
if (ImGui::Begin("Player Info", &m_showPlayerInfo, windowFlags)) {
|
||||
if (ImGui::Begin("Player Info", nullptr, windowFlags)) {
|
||||
daAlink_c* player = (daAlink_c*)dComIfGp_getPlayer(0);
|
||||
daHorse_c* horse = dComIfGp_getHorseActor();
|
||||
|
||||
@@ -196,8 +186,11 @@ namespace dusk {
|
||||
? fmt::format("Speed: {0}\n", horse->speedF)
|
||||
: "Speed: ?\n"
|
||||
);
|
||||
|
||||
ShowCornerContextMenu(m_playerInfoOverlayCorner, m_debugOverlayCorner);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopFont();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace dusk {
|
||||
void ShowMapLoader();
|
||||
void ShowPlayerInfo();
|
||||
void ShowAudioDebug();
|
||||
void ShowSaveEditor();
|
||||
|
||||
private:
|
||||
bool m_showDebugOverlay = false;
|
||||
@@ -51,8 +52,8 @@ namespace dusk {
|
||||
bool showInternalNames = false;
|
||||
} m_mapLoaderInfo;
|
||||
|
||||
bool m_isDevelopmentMode = false;
|
||||
bool m_showPlayerInfo = false;
|
||||
int m_playerInfoOverlayCorner = 1; // top-right
|
||||
|
||||
bool m_showSaveEditor = false;
|
||||
ImGuiSaveEditor m_saveEditor;
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "imgui.h"
|
||||
|
||||
#include "ImGuiConfig.hpp"
|
||||
#include "ImGuiEngine.hpp"
|
||||
#include "ImGuiPreLaunchWindow.hpp"
|
||||
|
||||
#include "ImGuiConsole.hpp"
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/settings.h"
|
||||
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
|
||||
#include "aurora/lib/internal.hpp"
|
||||
#include "aurora/lib/window.hpp"
|
||||
|
||||
namespace dusk {
|
||||
|
||||
typedef void (ImGuiPreLaunchWindow::*drawFunc)();
|
||||
|
||||
drawFunc drawTable[2] = {&ImGuiPreLaunchWindow::drawMainMenu, &ImGuiPreLaunchWindow::drawOptions};
|
||||
|
||||
static constexpr std::array<SDL_DialogFileFilter, 2> skGameDiscFileFilters{{
|
||||
{"Game Disc Images", "iso;gcm;ciso;gcz;nfs;rvz;wbfs;wia;tgc"},
|
||||
{"All Files", "*"},
|
||||
}};
|
||||
|
||||
void fileDialogCallback(void* userdata, const char* const* filelist, [[maybe_unused]] int filter) {
|
||||
auto* self = static_cast<ImGuiPreLaunchWindow*>(userdata);
|
||||
if (filelist != nullptr) {
|
||||
if (filelist[0] == nullptr) {
|
||||
// Cancelled
|
||||
self->m_selectedIsoPath.clear();
|
||||
} else {
|
||||
self->m_selectedIsoPath = filelist[0];
|
||||
getSettings().backend.isoPath.setValue(self->m_selectedIsoPath);
|
||||
config::Save();
|
||||
}
|
||||
} else {
|
||||
// Error occurred
|
||||
self->m_selectedIsoPath.clear();
|
||||
self->m_errorString = fmt::format("File dialog error: {}", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
ImGuiPreLaunchWindow::ImGuiPreLaunchWindow() = default;
|
||||
|
||||
bool ImGuiPreLaunchWindow::isSelectedPathValid() const {
|
||||
return !m_selectedIsoPath.empty() && SDL_GetPathInfo(m_selectedIsoPath.c_str(), nullptr);
|
||||
}
|
||||
|
||||
void ImGuiPreLaunchWindow::draw() {
|
||||
if (m_IsFirstDraw) {
|
||||
m_selectedIsoPath = getSettings().backend.isoPath;
|
||||
m_initialGraphicsBackend = getSettings().backend.graphicsBackend;
|
||||
m_IsFirstDraw = false;
|
||||
}
|
||||
|
||||
if (isSelectedPathValid() && getSettings().backend.skipPreLaunchUI) {
|
||||
dusk::IsGameLaunched = true;
|
||||
return;
|
||||
}
|
||||
|
||||
auto& io = ImGui::GetIO();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x, io.DisplaySize.y));
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
ImGui::Begin("Pre Launch Window", nullptr,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
|
||||
const auto& windowSize = ImGui::GetWindowSize();
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
ImGui::NewLine();
|
||||
|
||||
float iconSize = 150.f;
|
||||
ImGui::SameLine(windowSize.x / 2 - iconSize + (iconSize / 2));
|
||||
if (ImGuiEngine::duskIcon != 0)
|
||||
ImGui::Image(ImGuiEngine::duskIcon, ImVec2{iconSize, iconSize});
|
||||
ImGuiTextCenter("Twilit Realm presents");
|
||||
ImGui::PushFont(ImGuiEngine::fontExtraLarge);
|
||||
ImGuiTextCenter("Dusk");
|
||||
ImGui::PopFont();
|
||||
|
||||
(this->*drawTable[m_CurMenu])();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ImGuiPreLaunchWindow::drawMainMenu() {
|
||||
const auto& windowSize = ImGui::GetWindowSize();
|
||||
ImGui::SetCursorPosY(windowSize.y - 200);
|
||||
|
||||
ImGui::PushFont(ImGuiEngine::fontLarge);
|
||||
|
||||
if (m_selectedIsoPath.empty() || !SDL_GetPathInfo(m_selectedIsoPath.c_str(), nullptr)) {
|
||||
if (ImGuiButtonCenter("Select disc image...")) {
|
||||
SDL_ShowOpenFileDialog(&fileDialogCallback, this, aurora::window::get_sdl_window(),
|
||||
skGameDiscFileFilters.data(), int(skGameDiscFileFilters.size()),
|
||||
nullptr, false);
|
||||
}
|
||||
} else {
|
||||
if (ImGuiButtonCenter("Start game")) {
|
||||
dusk::IsGameLaunched = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGuiButtonCenter("Options")) {
|
||||
m_CurMenu = 1;
|
||||
}
|
||||
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
void ImGuiPreLaunchWindow::drawOptions() {
|
||||
const auto& windowSize = ImGui::GetWindowSize();
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::PushFont(ImGuiEngine::fontLarge);
|
||||
ImGuiTextCenter("Options");
|
||||
ImGui::Separator();
|
||||
ImGui::PopFont();
|
||||
|
||||
auto cursorY = ImGui::GetCursorPosY();
|
||||
float endCursorY = windowSize.y - 100;
|
||||
|
||||
float childWidth = windowSize.x - 400;
|
||||
|
||||
ImGui::SetCursorPosX(windowSize.x / 2 - (childWidth / 2));
|
||||
if (ImGui::BeginChild("OptionsChild", ImVec2(childWidth, endCursorY - cursorY),
|
||||
ImGuiChildFlags_None, ImGuiWindowFlags_NoBackground))
|
||||
{
|
||||
ImGui::InputText("Game ISO Path", &m_selectedIsoPath, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Set")) {
|
||||
SDL_ShowOpenFileDialog(&fileDialogCallback, this, aurora::window::get_sdl_window(),
|
||||
skGameDiscFileFilters.data(), int(skGameDiscFileFilters.size()),
|
||||
nullptr, false);
|
||||
}
|
||||
|
||||
AuroraBackend configuredBackend = BACKEND_AUTO;
|
||||
const std::string& configuredBackendId = getSettings().backend.graphicsBackend;
|
||||
if (!try_parse_backend(configuredBackendId, configuredBackend)) {
|
||||
configuredBackend = BACKEND_AUTO;
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Graphics Backend", backend_name(configuredBackend).data())) {
|
||||
if (ImGui::Selectable("Auto", configuredBackend == BACKEND_AUTO)) {
|
||||
getSettings().backend.graphicsBackend.setValue("auto");
|
||||
config::Save();
|
||||
}
|
||||
|
||||
size_t backendCount = 0;
|
||||
const AuroraBackend* availableBackends = aurora_get_available_backends(&backendCount);
|
||||
for (size_t i = 0; i < backendCount; ++i) {
|
||||
const AuroraBackend backend = availableBackends[i];
|
||||
const bool isSelected = configuredBackend == backend;
|
||||
if (ImGui::Selectable(backend_name(backend).data(), isSelected)) {
|
||||
getSettings().backend.graphicsBackend.setValue(
|
||||
std::string(backend_id(backend)));
|
||||
config::Save();
|
||||
}
|
||||
if (isSelected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (configuredBackendId != m_initialGraphicsBackend) {
|
||||
ImGui::TextDisabled("Restart Required");
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::SetCursorPosY(endCursorY);
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushFont(ImGuiEngine::fontLarge);
|
||||
if (ImGuiButtonCenter("Back")) {
|
||||
m_CurMenu = 0;
|
||||
}
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
} // namespace dusk
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
namespace dusk {
|
||||
class ImGuiPreLaunchWindow {
|
||||
private:
|
||||
int m_CurMenu = 0;
|
||||
bool m_IsFirstDraw = true;
|
||||
std::string m_initialGraphicsBackend;
|
||||
|
||||
bool isSelectedPathValid() const;
|
||||
|
||||
public:
|
||||
ImGuiPreLaunchWindow();
|
||||
void draw();
|
||||
|
||||
void drawMainMenu();
|
||||
void drawOptions();
|
||||
|
||||
std::string m_selectedIsoPath;
|
||||
std::string m_errorString;
|
||||
};
|
||||
} // namespace dusk
|
||||
@@ -287,7 +287,7 @@ namespace dusk {
|
||||
ImGuiWindowFlags windowFlags =
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize;
|
||||
|
||||
ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
// ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
if (ImGui::Begin("Save Editor", &open, windowFlags)) {
|
||||
if (ImGui::BeginTabBar("SaveEditorTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
|
||||
|
||||
@@ -58,6 +58,12 @@ UserSettings g_userSettings = {
|
||||
// Controls
|
||||
.enableTurboKeybind {"game.enableTurboKeybind", true},
|
||||
},
|
||||
|
||||
.backend = {
|
||||
.isoPath {"backend.isoPath", ""},
|
||||
.graphicsBackend {"backend.graphicsBackend", "auto"},
|
||||
.skipPreLaunchUI {"backend.skipPreLaunchUI", false}
|
||||
}
|
||||
};
|
||||
|
||||
UserSettings& getSettings() {
|
||||
@@ -103,6 +109,10 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.midnasLamentNonStop);
|
||||
Register(g_userSettings.game.enableTurboKeybind);
|
||||
Register(g_userSettings.game.fastSpinner);
|
||||
|
||||
Register(g_userSettings.backend.isoPath);
|
||||
Register(g_userSettings.backend.graphicsBackend);
|
||||
Register(g_userSettings.backend.skipPreLaunchUI);
|
||||
}
|
||||
|
||||
// Transient settings
|
||||
|
||||
+110
-34
@@ -61,7 +61,9 @@
|
||||
|
||||
#include "SDL3/SDL_filesystem.h"
|
||||
#include "cxxopts.hpp"
|
||||
#include "dusk/audio/DuskAudioSystem.h"
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/imgui/ImGuiConsole.hpp"
|
||||
#include "tracy/Tracy.hpp"
|
||||
|
||||
#if RANDOMIZER_ONLY
|
||||
@@ -87,7 +89,9 @@ const int audioHeapSize = 0x14D800;
|
||||
#define COPYDATE_PATH "/str/Final/Release/COPYDATE"
|
||||
|
||||
#if TARGET_PC
|
||||
bool dusk::IsRunning = true;
|
||||
bool dusk::IsShuttingDown = false;
|
||||
bool dusk::IsGameLaunched = false;
|
||||
#endif
|
||||
|
||||
s32 LOAD_COPYDATE(void*) {
|
||||
@@ -122,6 +126,41 @@ AuroraStats dusk::lastFrameAuroraStats;
|
||||
float dusk::frameUsagePct = 0.0f;
|
||||
const char* configPath;
|
||||
|
||||
AuroraWindowSize preLaunchUIWindowSize;
|
||||
|
||||
bool launchUILoop() {
|
||||
while (dusk::IsRunning && !dusk::IsGameLaunched) {
|
||||
const AuroraEvent* event = aurora_update();
|
||||
while (event != nullptr && event->type != AURORA_NONE) {
|
||||
switch (event->type) {
|
||||
case AURORA_WINDOW_RESIZED:
|
||||
preLaunchUIWindowSize = event->windowSize;
|
||||
break;
|
||||
case AURORA_DISPLAY_SCALE_CHANGED:
|
||||
dusk::ImGuiEngine_Initialize(event->windowSize.scale);
|
||||
break;
|
||||
case AURORA_EXIT:
|
||||
return false;
|
||||
}
|
||||
|
||||
event++;
|
||||
}
|
||||
|
||||
if (!aurora_begin_frame()) {
|
||||
DuskLog.debug("aurora_begin_frame returned false, skipping draw this frame");
|
||||
continue;
|
||||
}
|
||||
|
||||
dusk::g_imguiConsole.PreDraw();
|
||||
|
||||
dusk::g_imguiConsole.PostDraw();
|
||||
|
||||
aurora_end_frame();
|
||||
}
|
||||
|
||||
return dusk::IsRunning;
|
||||
}
|
||||
|
||||
void main01(void) {
|
||||
OS_REPORT("\x1b[m");
|
||||
|
||||
@@ -160,6 +199,8 @@ void main01(void) {
|
||||
|
||||
OSReport("Entering Main Loop (main01)...\n");
|
||||
|
||||
if (preLaunchUIWindowSize.width != 0)
|
||||
mDoGph_gInf_c::setWindowSize(preLaunchUIWindowSize);
|
||||
|
||||
do {
|
||||
// 1. Update Window Events
|
||||
@@ -208,46 +249,57 @@ void main01(void) {
|
||||
aurora_end_frame();
|
||||
|
||||
FrameMark;
|
||||
} while (true);
|
||||
} while (dusk::IsRunning);
|
||||
|
||||
exit:;
|
||||
}
|
||||
|
||||
static AuroraBackend ParseAuroraBackend(const std::string& value) {
|
||||
if (value == "auto") {
|
||||
return BACKEND_AUTO;
|
||||
}
|
||||
if (value == "d3d11") {
|
||||
return BACKEND_D3D11;
|
||||
}
|
||||
if (value == "d3d12") {
|
||||
return BACKEND_D3D12;
|
||||
}
|
||||
if (value == "metal") {
|
||||
return BACKEND_METAL;
|
||||
}
|
||||
if (value == "vulkan") {
|
||||
return BACKEND_VULKAN;
|
||||
}
|
||||
if (value == "opengl") {
|
||||
return BACKEND_OPENGL;
|
||||
}
|
||||
if (value == "opengles") {
|
||||
return BACKEND_OPENGLES;
|
||||
}
|
||||
if (value == "webgpu") {
|
||||
return BACKEND_WEBGPU;
|
||||
}
|
||||
if (value == "null") {
|
||||
return BACKEND_NULL;
|
||||
static bool IsBackendAvailable(AuroraBackend backend) {
|
||||
if (backend == BACKEND_AUTO) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fmt::print(stderr, "Unknown backend: {}", value);
|
||||
exit(1);
|
||||
size_t availableBackendCount = 0;
|
||||
const AuroraBackend* availableBackends = aurora_get_available_backends(&availableBackendCount);
|
||||
for (size_t i = 0; i < availableBackendCount; ++i) {
|
||||
if (availableBackends[i] == backend) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static AuroraBackend ResolveDesiredBackend(const cxxopts::ParseResult& parsedArgOptions) {
|
||||
AuroraBackend desiredBackend = BACKEND_AUTO;
|
||||
|
||||
if (parsedArgOptions.count("backend") != 0) {
|
||||
const std::string backendArg = parsedArgOptions["backend"].as<std::string>();
|
||||
if (!dusk::try_parse_backend(backendArg, desiredBackend)) {
|
||||
fmt::print(stderr, "Unknown backend: {}\n", backendArg);
|
||||
exit(1);
|
||||
}
|
||||
} else if (!dusk::try_parse_backend(
|
||||
static_cast<const std::string&>(dusk::getSettings().backend.graphicsBackend),
|
||||
desiredBackend))
|
||||
{
|
||||
DuskLog.warn("Unknown configured backend '{}', falling back to Auto",
|
||||
static_cast<const std::string&>(dusk::getSettings().backend.graphicsBackend));
|
||||
desiredBackend = BACKEND_AUTO;
|
||||
}
|
||||
|
||||
if (!IsBackendAvailable(desiredBackend)) {
|
||||
DuskLog.warn("Requested backend '{}' is unavailable, falling back to Auto",
|
||||
dusk::backend_name(desiredBackend));
|
||||
desiredBackend = BACKEND_AUTO;
|
||||
}
|
||||
|
||||
return desiredBackend;
|
||||
}
|
||||
|
||||
static void aurora_imgui_init_callback(const AuroraWindowSize* size) {
|
||||
dusk::ImGuiEngine_Initialize(size->scale);
|
||||
dusk::ImGuiEngine_AddTextures();
|
||||
}
|
||||
|
||||
static void ApplyCVarOverrides(const cxxopts::OptionValue& option) {
|
||||
@@ -346,7 +398,7 @@ int game_main(int argc, char* argv[]) {
|
||||
("l,log-level", "Log level from " + std::to_string(AuroraLogLevel::LOG_DEBUG) + " to " + std::to_string(AuroraLogLevel::LOG_FATAL), cxxopts::value<uint8_t>()->default_value("0"))
|
||||
("h,help", "Print usage")
|
||||
("dvd", "Path to DVD image file", cxxopts::value<std::string>()->default_value("game.iso"))
|
||||
("backend", "Graphics API backend to use (auto, d3d11, d3d12, metal, vulkan, opengl, opengles, webgpu, null)", cxxopts::value<std::string>()->default_value("auto"))
|
||||
("backend", "Graphics API backend to use (auto, d3d12, metal, vulkan, null)", cxxopts::value<std::string>())
|
||||
("cvar", "Override configuration variables without modifying config", cxxopts::value<std::vector<std::string>>());
|
||||
|
||||
arg_options.parse_positional({"dvd"});
|
||||
@@ -380,7 +432,7 @@ int game_main(int argc, char* argv[]) {
|
||||
config.windowPosY = -1;
|
||||
config.windowWidth = defaultWindowWidth * 2;
|
||||
config.windowHeight = defaultWindowHeight * 2;
|
||||
config.desiredBackend = ParseAuroraBackend(parsed_arg_options["backend"].as<std::string>());
|
||||
config.desiredBackend = ResolveDesiredBackend(parsed_arg_options);
|
||||
config.logCallback = &aurora_log_callback;
|
||||
config.logLevel = (AuroraLogLevel)parsed_arg_options["log-level"].as<uint8_t>();
|
||||
config.mem1Size = 256 * 1024 * 1024;
|
||||
@@ -394,9 +446,33 @@ int game_main(int argc, char* argv[]) {
|
||||
|
||||
VISetWindowTitle(
|
||||
fmt::format("Dusk {} [{}]", DUSK_WC_DESCRIBE, dusk::backend_name(auroraInfo.backend))
|
||||
.c_str());
|
||||
.c_str());
|
||||
|
||||
const auto& dvd_path = parsed_arg_options["dvd"].as<std::string>();
|
||||
if (dusk::getSettings().video.lockAspectRatio) {
|
||||
VILockAspectRatio(defaultAspectRatioW, defaultAspectRatioH);
|
||||
} else {
|
||||
VIUnlockAspectRatio();
|
||||
}
|
||||
|
||||
dusk::audio::SetMasterVolume(dusk::getSettings().audio.masterVolume / 100.0f);
|
||||
dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb);
|
||||
|
||||
// pre game launch ui main loop
|
||||
if (!launchUILoop()) {
|
||||
aurora_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string dvd_path;
|
||||
if (parsed_arg_options.count("dvd")) {
|
||||
dvd_path = parsed_arg_options["dvd"].as<std::string>();
|
||||
} else {
|
||||
dvd_path = dusk::getSettings().backend.isoPath;
|
||||
|
||||
if (dvd_path.empty()) {
|
||||
DuskLog.fatal("No DVD image specified, unable to boot!");
|
||||
}
|
||||
}
|
||||
DuskLog.info("Loading DVD image: {}", dvd_path);
|
||||
if (!aurora_dvd_open(dvd_path.c_str())) {
|
||||
DuskLog.fatal("Failed to open DVD image: {}", dvd_path);
|
||||
|
||||
Reference in New Issue
Block a user