mirror of https://github.com/AxioDL/metaforce.git
Add pre-launch settings, graphics API switching & more
This commit is contained in:
parent
a3c2638cce
commit
97357146f5
|
@ -153,7 +153,6 @@ private:
|
||||||
CVarManager& m_cvarManager;
|
CVarManager& m_cvarManager;
|
||||||
CVarCommons& m_cvarCommons;
|
CVarCommons& m_cvarCommons;
|
||||||
ImGuiConsole m_imGuiConsole;
|
ImGuiConsole m_imGuiConsole;
|
||||||
std::string m_errorString;
|
|
||||||
|
|
||||||
std::string m_deferredProject;
|
std::string m_deferredProject;
|
||||||
bool m_projectInitialized = false;
|
bool m_projectInitialized = false;
|
||||||
|
@ -166,7 +165,7 @@ private:
|
||||||
bool m_fullscreenToggleRequested = false;
|
bool m_fullscreenToggleRequested = false;
|
||||||
bool m_quitRequested = false;
|
bool m_quitRequested = false;
|
||||||
using delta_clock = std::chrono::high_resolution_clock;
|
using delta_clock = std::chrono::high_resolution_clock;
|
||||||
std::chrono::time_point<delta_clock> m_prevFrameTime;
|
delta_clock::time_point m_prevFrameTime;
|
||||||
|
|
||||||
std::vector<u32> m_deferredControllers; // used to capture controllers added before CInputGenerator
|
std::vector<u32> m_deferredControllers; // used to capture controllers added before CInputGenerator
|
||||||
// is built, i.e during initialization
|
// is built, i.e during initialization
|
||||||
|
@ -224,9 +223,9 @@ public:
|
||||||
m_projectInitialized = true;
|
m_projectInitialized = true;
|
||||||
} else {
|
} else {
|
||||||
Log.report(logvisor::Error, FMT_STRING("Failed to open disc image '{}'"), m_deferredProject);
|
Log.report(logvisor::Error, FMT_STRING("Failed to open disc image '{}'"), m_deferredProject);
|
||||||
m_errorString = fmt::format(FMT_STRING("Failed to open disc image '{}'"), m_deferredProject);
|
m_imGuiConsole.m_errorString = fmt::format(FMT_STRING("Failed to open disc image '{}'"), m_deferredProject);
|
||||||
m_deferredProject.clear();
|
|
||||||
}
|
}
|
||||||
|
m_deferredProject.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto targetFrameTime = getTargetFrameTime();
|
const auto targetFrameTime = getTargetFrameTime();
|
||||||
|
@ -266,7 +265,14 @@ public:
|
||||||
|
|
||||||
if (!g_mainMP1 && m_projectInitialized) {
|
if (!g_mainMP1 && m_projectInitialized) {
|
||||||
g_mainMP1.emplace(nullptr, nullptr);
|
g_mainMP1.emplace(nullptr, nullptr);
|
||||||
g_mainMP1->Init(m_fileMgr, &m_cvarManager, m_voiceEngine.get(), *m_amuseAllocWrapper);
|
auto result = g_mainMP1->Init(m_fileMgr, &m_cvarManager, m_voiceEngine.get(), *m_amuseAllocWrapper);
|
||||||
|
if (!result.empty()) {
|
||||||
|
Log.report(logvisor::Error, FMT_STRING("{}"), result);
|
||||||
|
m_imGuiConsole.m_errorString = result;
|
||||||
|
g_mainMP1.reset();
|
||||||
|
CDvdFile::Shutdown();
|
||||||
|
m_projectInitialized = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float dt = 1 / 60.f;
|
float dt = 1 / 60.f;
|
||||||
|
@ -274,8 +280,8 @@ public:
|
||||||
dt = std::min(realDt, 1 / 30.f);
|
dt = std::min(realDt, 1 / 30.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_mainMP1) {
|
|
||||||
m_imGuiConsole.PreUpdate();
|
m_imGuiConsole.PreUpdate();
|
||||||
|
if (g_mainMP1) {
|
||||||
if (m_voiceEngine) {
|
if (m_voiceEngine) {
|
||||||
m_voiceEngine->lockPump();
|
m_voiceEngine->lockPump();
|
||||||
}
|
}
|
||||||
|
@ -285,15 +291,15 @@ public:
|
||||||
if (m_voiceEngine) {
|
if (m_voiceEngine) {
|
||||||
m_voiceEngine->unlockPump();
|
m_voiceEngine->unlockPump();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_imGuiConsole.PostUpdate();
|
m_imGuiConsole.PostUpdate();
|
||||||
} else {
|
if (!g_mainMP1 && m_imGuiConsole.m_gameDiscSelected) {
|
||||||
auto result = m_imGuiConsole.ShowAboutWindow(false, m_errorString, true);
|
std::optional<std::string> result;
|
||||||
if (result) {
|
m_imGuiConsole.m_gameDiscSelected.swap(result);
|
||||||
m_deferredProject = std::move(*result);
|
m_deferredProject = std::move(*result);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (m_quitRequested) {
|
if (m_quitRequested || m_imGuiConsole.m_quitRequested || m_cvarManager.restartRequired()) {
|
||||||
if (g_mainMP1) {
|
if (g_mainMP1) {
|
||||||
g_mainMP1->Quit();
|
g_mainMP1->Quit();
|
||||||
} else {
|
} else {
|
||||||
|
@ -489,7 +495,7 @@ public:
|
||||||
|
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
||||||
static void SetupBasics(bool logging) {
|
static void SetupBasics() {
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
if (logging && GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_UNKNOWN)
|
if (logging && GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_UNKNOWN)
|
||||||
logvisor::CreateWin32Console();
|
logvisor::CreateWin32Console();
|
||||||
|
@ -509,10 +515,6 @@ static void SetupBasics(bool logging) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
logvisor::RegisterStandardExceptions();
|
|
||||||
if (logging)
|
|
||||||
logvisor::RegisterConsoleLogger();
|
|
||||||
|
|
||||||
#if SENTRY_ENABLED
|
#if SENTRY_ENABLED
|
||||||
FileStoreManager fileMgr{"sentry-native-metaforce"};
|
FileStoreManager fileMgr{"sentry-native-metaforce"};
|
||||||
std::string cacheDir{fileMgr.getStoreRoot()};
|
std::string cacheDir{fileMgr.getStoreRoot()};
|
||||||
|
@ -531,7 +533,6 @@ static bool IsClientLoggingEnabled(int argc, char** argv) {
|
||||||
|
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
// TODO: This seems to fix a lot of weird issues with rounding
|
// TODO: This seems to fix a lot of weird issues with rounding
|
||||||
// but breaks animations, need to research why this is the case
|
// but breaks animations, need to research why this is the case
|
||||||
// for now it's disabled
|
// for now it's disabled
|
||||||
|
@ -541,16 +542,27 @@ int main(int argc, char** argv) {
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupBasics(IsClientLoggingEnabled(argc, argv));
|
SetupBasics();
|
||||||
metaforce::FileStoreManager fileMgr{"AxioDL", "metaforce"};
|
metaforce::FileStoreManager fileMgr{"AxioDL", "metaforce"};
|
||||||
metaforce::CVarManager cvarMgr{fileMgr};
|
|
||||||
metaforce::CVarCommons cvarCmns{cvarMgr};
|
|
||||||
|
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
for (int i = 1; i < argc; ++i)
|
for (int i = 1; i < argc; ++i) {
|
||||||
args.emplace_back(argv[i]);
|
args.emplace_back(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restart = false;
|
||||||
|
do {
|
||||||
|
metaforce::CVarManager cvarMgr{fileMgr};
|
||||||
|
metaforce::CVarCommons cvarCmns{cvarMgr};
|
||||||
|
if (!restart) {
|
||||||
cvarMgr.parseCommandLine(args);
|
cvarMgr.parseCommandLine(args);
|
||||||
|
|
||||||
|
// TODO add clear loggers func to logvisor so we can recreate loggers on restart
|
||||||
|
logvisor::RegisterStandardExceptions();
|
||||||
|
if (IsClientLoggingEnabled(argc, argv)) {
|
||||||
|
logvisor::RegisterConsoleLogger();
|
||||||
|
}
|
||||||
|
|
||||||
std::string logFile = cvarCmns.getLogFile();
|
std::string logFile = cvarCmns.getLogFile();
|
||||||
std::string logFilePath;
|
std::string logFilePath;
|
||||||
if (!logFile.empty()) {
|
if (!logFile.empty()) {
|
||||||
|
@ -560,7 +572,7 @@ int main(int argc, char** argv) {
|
||||||
logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile);
|
logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile);
|
||||||
logvisor::RegisterFileLogger(logFilePath.c_str());
|
logvisor::RegisterFileLogger(logFilePath.c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
auto app = std::make_unique<metaforce::Application>(fileMgr, cvarMgr, cvarCmns);
|
auto app = std::make_unique<metaforce::Application>(fileMgr, cvarMgr, cvarCmns);
|
||||||
auto icon = metaforce::GetIcon();
|
auto icon = metaforce::GetIcon();
|
||||||
auto data = aurora::Icon{
|
auto data = aurora::Icon{
|
||||||
|
@ -569,8 +581,10 @@ int main(int argc, char** argv) {
|
||||||
.height = icon.height,
|
.height = icon.height,
|
||||||
};
|
};
|
||||||
aurora::app_run(std::move(app), std::move(data), argc, argv, fileMgr.getStoreRoot(),
|
aurora::app_run(std::move(app), std::move(data), argc, argv, fileMgr.getStoreRoot(),
|
||||||
aurora::translate_backend(cvarCmns.getGraphicsApi()), cvarCmns.getSamples(),
|
aurora::backend_from_string(cvarCmns.getGraphicsApi()), cvarCmns.getSamples(),
|
||||||
cvarCmns.getAnisotropy());
|
cvarCmns.getAnisotropy(), cvarCmns.getFullscreen());
|
||||||
|
restart = cvarMgr.restartRequired();
|
||||||
|
} while (restart);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,8 +37,8 @@ enum class EGameplayResult { None, Win, Lose, Playing };
|
||||||
class IMain {
|
class IMain {
|
||||||
public:
|
public:
|
||||||
virtual ~IMain() = default;
|
virtual ~IMain() = default;
|
||||||
virtual void Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr,
|
virtual std::string Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
|
||||||
boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) = 0;
|
amuse::IBackendVoiceAllocator& backend) = 0;
|
||||||
virtual void Draw() = 0;
|
virtual void Draw() = 0;
|
||||||
virtual bool Proc(float dt) = 0;
|
virtual bool Proc(float dt) = 0;
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
|
|
|
@ -41,6 +41,9 @@ std::array<ImGuiEntityEntry, kMaxEntities> ImGuiConsole::entities;
|
||||||
std::set<TUniqueId> ImGuiConsole::inspectingEntities;
|
std::set<TUniqueId> ImGuiConsole::inspectingEntities;
|
||||||
ImGuiPlayerLoadouts ImGuiConsole::loadouts;
|
ImGuiPlayerLoadouts ImGuiConsole::loadouts;
|
||||||
|
|
||||||
|
ImGuiConsole::ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons)
|
||||||
|
: m_cvarMgr(cvarMgr), m_cvarCommons(cvarCommons) {}
|
||||||
|
|
||||||
void ImGuiStringViewText(std::string_view text) {
|
void ImGuiStringViewText(std::string_view text) {
|
||||||
// begin()/end() do not work on MSVC
|
// begin()/end() do not work on MSVC
|
||||||
ImGui::TextUnformatted(text.data(), text.data() + text.size());
|
ImGui::TextUnformatted(text.data(), text.data() + text.size());
|
||||||
|
@ -137,8 +140,10 @@ static void Warp(const CAssetId worldId, TAreaId aId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiConsole::ShowMenuGame() {
|
void ImGuiConsole::ShowMenuGame() {
|
||||||
|
if (g_Main != nullptr) {
|
||||||
m_paused = g_Main->IsPaused();
|
m_paused = g_Main->IsPaused();
|
||||||
if (ImGui::MenuItem("Paused", "F5", &m_paused)) {
|
}
|
||||||
|
if (ImGui::MenuItem("Paused", "F5", &m_paused, g_Main != nullptr)) {
|
||||||
g_Main->SetPaused(m_paused);
|
g_Main->SetPaused(m_paused);
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Step Frame", "F6", &m_stepFrame, m_paused)) {
|
if (ImGui::MenuItem("Step Frame", "F6", &m_stepFrame, m_paused)) {
|
||||||
|
@ -159,7 +164,7 @@ void ImGuiConsole::ShowMenuGame() {
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Quit", "Alt+F4")) {
|
if (ImGui::MenuItem("Quit", "Alt+F4")) {
|
||||||
g_Main->Quit();
|
m_quitRequested = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,12 +645,10 @@ void ImGuiConsole::ShowConsoleVariablesWindow() {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::string_view errorString, bool preLaunch) {
|
void ImGuiConsole::ShowAboutWindow(bool preLaunch) {
|
||||||
std::optional<std::string> result{};
|
|
||||||
|
|
||||||
// Center window
|
// Center window
|
||||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||||
ImGui::SetNextWindowPos(center, canClose ? ImGuiCond_Appearing : ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
ImGui::SetNextWindowPos(center, preLaunch ? ImGuiCond_Always : ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||||
|
|
||||||
ImVec4& windowBg = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
|
ImVec4& windowBg = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
|
||||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, windowBg);
|
ImGui::PushStyleColor(ImGuiCol_TitleBg, windowBg);
|
||||||
|
@ -654,10 +657,10 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
||||||
bool* open = nullptr;
|
bool* open = nullptr;
|
||||||
ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNav |
|
ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNav |
|
||||||
ImGuiWindowFlags_NoSavedSettings;
|
ImGuiWindowFlags_NoSavedSettings;
|
||||||
if (canClose) {
|
if (preLaunch) {
|
||||||
open = &m_showAboutWindow;
|
|
||||||
} else {
|
|
||||||
flags |= ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove;
|
flags |= ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove;
|
||||||
|
} else {
|
||||||
|
open = &m_showAboutWindow;
|
||||||
}
|
}
|
||||||
if (ImGui::Begin("About", open, flags)) {
|
if (ImGui::Begin("About", open, flags)) {
|
||||||
float iconSize = 128.f * aurora::get_window_size().scale;
|
float iconSize = 128.f * aurora::get_window_size().scale;
|
||||||
|
@ -670,12 +673,16 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
||||||
const ImVec2& padding = ImGui::GetStyle().WindowPadding;
|
const ImVec2& padding = ImGui::GetStyle().WindowPadding;
|
||||||
ImGui::Dummy(padding);
|
ImGui::Dummy(padding);
|
||||||
if (preLaunch) {
|
if (preLaunch) {
|
||||||
|
if (ImGuiButtonCenter("Settings")) {
|
||||||
|
m_showPreLaunchSettingsWindow = true;
|
||||||
|
}
|
||||||
|
ImGui::Dummy(padding);
|
||||||
#ifdef NATIVEFILEDIALOG_SUPPORTED
|
#ifdef NATIVEFILEDIALOG_SUPPORTED
|
||||||
if (ImGuiButtonCenter("Select Game Disc")) {
|
if (ImGuiButtonCenter("Select Game Disc")) {
|
||||||
nfdchar_t* outPath = nullptr;
|
nfdchar_t* outPath = nullptr;
|
||||||
nfdresult_t nfdResult = NFD_OpenDialog(nullptr, nullptr, &outPath);
|
nfdresult_t nfdResult = NFD_OpenDialog(nullptr, nullptr, &outPath);
|
||||||
if (nfdResult == NFD_OKAY) {
|
if (nfdResult == NFD_OKAY) {
|
||||||
result = outPath;
|
m_gameDiscSelected = outPath;
|
||||||
free(outPath);
|
free(outPath);
|
||||||
} else if (nfdResult != NFD_CANCEL) {
|
} else if (nfdResult != NFD_CANCEL) {
|
||||||
Log.report(logvisor::Error, FMT_STRING("nativefiledialog error: {}"), NFD_GetError());
|
Log.report(logvisor::Error, FMT_STRING("nativefiledialog error: {}"), NFD_GetError());
|
||||||
|
@ -684,9 +691,9 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
||||||
ImGui::Dummy(padding);
|
ImGui::Dummy(padding);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!errorString.empty()) {
|
if (m_errorString) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{0.77f, 0.12f, 0.23f, 1.f});
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{0.77f, 0.12f, 0.23f, 1.f});
|
||||||
ImGuiTextCenter(errorString);
|
ImGuiTextCenter(*m_errorString);
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::Dummy(padding);
|
ImGui::Dummy(padding);
|
||||||
}
|
}
|
||||||
|
@ -764,7 +771,6 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string BytesToString(size_t bytes) {
|
static std::string BytesToString(size_t bytes) {
|
||||||
|
@ -932,7 +938,7 @@ void ImGuiConsole::ShowDebugOverlay() {
|
||||||
ImGuiStringViewText(
|
ImGuiStringViewText(
|
||||||
fmt::format(FMT_STRING("CRandom16::Next calls: {}\n"), metaforce::CRandom16::GetNumNextCalls()));
|
fmt::format(FMT_STRING("CRandom16::Next calls: {}\n"), metaforce::CRandom16::GetNumNextCalls()));
|
||||||
}
|
}
|
||||||
if (m_resourceStats) {
|
if (m_resourceStats && g_SimplePool != nullptr) {
|
||||||
if (hasPrevious) {
|
if (hasPrevious) {
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
}
|
}
|
||||||
|
@ -1168,7 +1174,7 @@ void ImGuiConsole::SetOverlayWindowLocation(int corner) const {
|
||||||
ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, windowPosPivot);
|
ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, windowPosPivot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
|
void ImGuiConsole::ShowAppMainMenuBar(bool canInspect, bool preLaunch) {
|
||||||
if (ImGui::BeginMainMenuBar()) {
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
if (ImGui::BeginMenu("Game")) {
|
if (ImGui::BeginMenu("Game")) {
|
||||||
ShowMenuGame();
|
ShowMenuGame();
|
||||||
|
@ -1221,7 +1227,7 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
|
||||||
}
|
}
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
if (ImGui::BeginMenu("Help")) {
|
if (ImGui::BeginMenu("Help")) {
|
||||||
ImGui::MenuItem("About", nullptr, &m_showAboutWindow);
|
ImGui::MenuItem("About", nullptr, &m_showAboutWindow, !preLaunch);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::BeginMenu("ImGui")) {
|
if (ImGui::BeginMenu("ImGui")) {
|
||||||
if (ImGui::MenuItem("Clear Settings")) {
|
if (ImGui::MenuItem("Clear Settings")) {
|
||||||
|
@ -1240,6 +1246,7 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
|
||||||
|
|
||||||
void ImGuiConsole::PreUpdate() {
|
void ImGuiConsole::PreUpdate() {
|
||||||
OPTICK_EVENT();
|
OPTICK_EVENT();
|
||||||
|
bool preLaunch = g_Main == nullptr;
|
||||||
if (!m_isInitialized) {
|
if (!m_isInitialized) {
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
m_cvarCommons.m_debugOverlayShowFrameCounter->addListener([this](CVar* c) { m_frameCounter = c->toBoolean(); });
|
m_cvarCommons.m_debugOverlayShowFrameCounter->addListener([this](CVar* c) { m_frameCounter = c->toBoolean(); });
|
||||||
|
@ -1255,15 +1262,19 @@ void ImGuiConsole::PreUpdate() {
|
||||||
m_cvarCommons.m_debugOverlayShowInput->addListener([this](CVar* c) { m_showInput = c->toBoolean(); });
|
m_cvarCommons.m_debugOverlayShowInput->addListener([this](CVar* c) { m_showInput = c->toBoolean(); });
|
||||||
m_cvarMgr.findCVar("developer")->addListener([this](CVar* c) { m_developer = c->toBoolean(); });
|
m_cvarMgr.findCVar("developer")->addListener([this](CVar* c) { m_developer = c->toBoolean(); });
|
||||||
m_cvarMgr.findCVar("cheats")->addListener([this](CVar* c) { m_cheats = c->toBoolean(); });
|
m_cvarMgr.findCVar("cheats")->addListener([this](CVar* c) { m_cheats = c->toBoolean(); });
|
||||||
|
}
|
||||||
|
if (!preLaunch && !m_isLaunchInitialized) {
|
||||||
if (m_developer) {
|
if (m_developer) {
|
||||||
m_toasts.emplace_back("Press ` to toggle menu"s, 5.f);
|
m_toasts.emplace_back("Press ` to toggle menu"s, 5.f);
|
||||||
}
|
}
|
||||||
|
m_isLaunchInitialized = true;
|
||||||
}
|
}
|
||||||
// We ned to make sure we have a valid CRandom16 at all times, so lets do that here
|
// We need to make sure we have a valid CRandom16 at all times, so let's do that here
|
||||||
if (g_StateManager != nullptr && g_StateManager->GetActiveRandom() == nullptr) {
|
if (g_StateManager != nullptr && g_StateManager->GetActiveRandom() == nullptr) {
|
||||||
g_StateManager->SetActiveRandomToDefault();
|
g_StateManager->SetActiveRandomToDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preLaunch) {
|
||||||
if (ImGui::IsKeyReleased(ImGuiKey_GraveAccent)) {
|
if (ImGui::IsKeyReleased(ImGuiKey_GraveAccent)) {
|
||||||
m_isVisible ^= 1;
|
m_isVisible ^= 1;
|
||||||
}
|
}
|
||||||
|
@ -1279,9 +1290,10 @@ void ImGuiConsole::PreUpdate() {
|
||||||
m_paused ^= 1;
|
m_paused ^= 1;
|
||||||
g_Main->SetPaused(m_paused);
|
g_Main->SetPaused(m_paused);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bool canInspect = g_StateManager != nullptr && g_StateManager->GetObjectList();
|
bool canInspect = g_StateManager != nullptr && g_StateManager->GetObjectList();
|
||||||
if (m_isVisible) {
|
if (preLaunch || m_isVisible) {
|
||||||
ShowAppMainMenuBar(canInspect);
|
ShowAppMainMenuBar(canInspect, preLaunch);
|
||||||
}
|
}
|
||||||
ShowToasts();
|
ShowToasts();
|
||||||
if (canInspect && (m_showInspectWindow || !inspectingEntities.empty())) {
|
if (canInspect && (m_showInspectWindow || !inspectingEntities.empty())) {
|
||||||
|
@ -1304,8 +1316,8 @@ void ImGuiConsole::PreUpdate() {
|
||||||
if (canInspect && m_showLayersWindow) {
|
if (canInspect && m_showLayersWindow) {
|
||||||
ShowLayersWindow();
|
ShowLayersWindow();
|
||||||
}
|
}
|
||||||
if (m_showAboutWindow) {
|
if (preLaunch || m_showAboutWindow) {
|
||||||
ShowAboutWindow(true);
|
ShowAboutWindow(preLaunch);
|
||||||
}
|
}
|
||||||
if (m_showDemoWindow) {
|
if (m_showDemoWindow) {
|
||||||
ImGui::ShowDemoWindow(&m_showDemoWindow);
|
ImGui::ShowDemoWindow(&m_showDemoWindow);
|
||||||
|
@ -1318,6 +1330,9 @@ void ImGuiConsole::PreUpdate() {
|
||||||
ShowPlayerTransformEditor();
|
ShowPlayerTransformEditor();
|
||||||
ShowPipelineProgress();
|
ShowPipelineProgress();
|
||||||
m_controllerConfig.show(m_controllerConfigVisible);
|
m_controllerConfig.show(m_controllerConfigVisible);
|
||||||
|
if (preLaunch && m_showPreLaunchSettingsWindow) {
|
||||||
|
ShowPreLaunchSettingsWindow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiConsole::PostUpdate() {
|
void ImGuiConsole::PostUpdate() {
|
||||||
|
@ -1345,7 +1360,7 @@ void ImGuiConsole::PostUpdate() {
|
||||||
|
|
||||||
// Always calculate room time regardless of if the overlay is displayed, this allows us have an accurate display if
|
// Always calculate room time regardless of if the overlay is displayed, this allows us have an accurate display if
|
||||||
// the user chooses to display it later on during gameplay
|
// the user chooses to display it later on during gameplay
|
||||||
if (g_StateManager && m_currentRoom != g_StateManager->GetCurrentArea()) {
|
if (g_StateManager != nullptr && m_currentRoom != g_StateManager->GetCurrentArea()) {
|
||||||
const double igt = g_GameState->GetTotalPlayTime();
|
const double igt = g_GameState->GetTotalPlayTime();
|
||||||
m_currentRoom = static_cast<const void*>(g_StateManager->GetCurrentArea());
|
m_currentRoom = static_cast<const void*>(g_StateManager->GetCurrentArea());
|
||||||
m_lastRoomTime = igt - m_currentRoomStart;
|
m_lastRoomTime = igt - m_currentRoomStart;
|
||||||
|
@ -1781,4 +1796,66 @@ void ImGuiConsole::ControllerAdded(uint32_t idx) {
|
||||||
void ImGuiConsole::ControllerRemoved(uint32_t idx) {
|
void ImGuiConsole::ControllerRemoved(uint32_t idx) {
|
||||||
m_toasts.emplace_back(fmt::format(FMT_STRING("Controller {} disconnected"), idx), 5.f);
|
m_toasts.emplace_back(fmt::format(FMT_STRING("Controller {} disconnected"), idx), 5.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImGuiCVarCheckbox(CVarManager& mgr, std::string_view cvarName, const char* label, bool* ptr = nullptr) {
|
||||||
|
auto* cvar = mgr.findOrMakeCVar(cvarName, ""sv, false, CVar::EFlags::Game | CVar::EFlags::Archive);
|
||||||
|
if (cvar != nullptr) {
|
||||||
|
bool value = cvar->toBoolean();
|
||||||
|
bool modified = false;
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
modified = ImGui::Checkbox(label, &value);
|
||||||
|
} else {
|
||||||
|
modified = ImGui::Checkbox(label, ptr);
|
||||||
|
value = *ptr;
|
||||||
|
}
|
||||||
|
if (modified) {
|
||||||
|
cvar->unlock();
|
||||||
|
cvar->fromBoolean(value);
|
||||||
|
cvar->lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiConsole::ShowPreLaunchSettingsWindow() {
|
||||||
|
if (ImGui::Begin("Settings", &m_showPreLaunchSettingsWindow, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
if (ImGui::BeginTabBar("Settings")) {
|
||||||
|
if (ImGui::BeginTabItem("Graphics")) {
|
||||||
|
static auto AvailableBackends = aurora::get_available_backends();
|
||||||
|
ImGuiStringViewText(fmt::format(FMT_STRING("Current backend: {}"), aurora::get_backend_string()));
|
||||||
|
auto desiredBackend = static_cast<int>(aurora::Backend::Invalid);
|
||||||
|
if (auto* cvar = m_cvarMgr.findCVar("graphicsApi")) {
|
||||||
|
bool valid = false;
|
||||||
|
const auto name = cvar->toLiteral(&valid);
|
||||||
|
if (valid) {
|
||||||
|
desiredBackend = static_cast<int>(aurora::backend_from_string(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool modified = false;
|
||||||
|
modified = ImGui::RadioButton("Auto", &desiredBackend, static_cast<int>(aurora::Backend::Invalid));
|
||||||
|
for (const auto& item : AvailableBackends) {
|
||||||
|
modified = ImGui::RadioButton(magic_enum::enum_name(item).data(), &desiredBackend, static_cast<int>(item)) ||
|
||||||
|
modified;
|
||||||
|
}
|
||||||
|
if (modified) {
|
||||||
|
m_cvarCommons.m_graphicsApi->fromLiteral(
|
||||||
|
aurora::backend_to_string(static_cast<aurora::Backend>(desiredBackend)));
|
||||||
|
}
|
||||||
|
ImGuiCVarCheckbox(m_cvarMgr, "fullscreen", "Fullscreen");
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginTabItem("Game")) {
|
||||||
|
ImGuiCVarCheckbox(m_cvarMgr, "tweak.game.SplashScreensDisabled", "Skip Splash Screens");
|
||||||
|
ImGuiCVarCheckbox(m_cvarMgr, "developer", "Developer Mode", &m_developer);
|
||||||
|
ImGuiCVarCheckbox(m_cvarMgr, "cheats", "Enable Cheats", &m_cheats);
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
if (ImGui::BeginTabItem("Experimental")) {
|
||||||
|
ImGuiCVarCheckbox(m_cvarMgr, "variableDt", "Variable Delta Time (broken)");
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
ImGui::EndTabBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -51,12 +51,10 @@ public:
|
||||||
static std::array<ImGuiEntityEntry, kMaxEntities> entities;
|
static std::array<ImGuiEntityEntry, kMaxEntities> entities;
|
||||||
static ImGuiPlayerLoadouts loadouts;
|
static ImGuiPlayerLoadouts loadouts;
|
||||||
|
|
||||||
ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons) : m_cvarMgr(cvarMgr), m_cvarCommons(cvarCommons) {}
|
ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons);
|
||||||
void PreUpdate();
|
void PreUpdate();
|
||||||
void PostUpdate();
|
void PostUpdate();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
std::optional<std::string> ShowAboutWindow(bool canClose, std::string_view errorString = ""sv,
|
|
||||||
bool preLaunch = false);
|
|
||||||
|
|
||||||
static void BeginEntityRow(const ImGuiEntityEntry& entry);
|
static void BeginEntityRow(const ImGuiEntityEntry& entry);
|
||||||
static void EndEntityRow(const ImGuiEntityEntry& entry);
|
static void EndEntityRow(const ImGuiEntityEntry& entry);
|
||||||
|
@ -64,6 +62,10 @@ public:
|
||||||
void ControllerAdded(uint32_t idx);
|
void ControllerAdded(uint32_t idx);
|
||||||
void ControllerRemoved(uint32_t idx);
|
void ControllerRemoved(uint32_t idx);
|
||||||
|
|
||||||
|
std::optional<std::string> m_errorString;
|
||||||
|
std::optional<std::string> m_gameDiscSelected;
|
||||||
|
bool m_quitRequested = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CVarManager& m_cvarMgr;
|
CVarManager& m_cvarMgr;
|
||||||
CVarCommons& m_cvarCommons;
|
CVarCommons& m_cvarCommons;
|
||||||
|
@ -75,6 +77,7 @@ private:
|
||||||
bool m_showLayersWindow = false;
|
bool m_showLayersWindow = false;
|
||||||
bool m_showConsoleVariablesWindow = false;
|
bool m_showConsoleVariablesWindow = false;
|
||||||
bool m_showPlayerTransformEditor = false;
|
bool m_showPlayerTransformEditor = false;
|
||||||
|
bool m_showPreLaunchSettingsWindow = false;
|
||||||
std::optional<zeus::CVector3f> m_savedLocation;
|
std::optional<zeus::CVector3f> m_savedLocation;
|
||||||
std::optional<zeus::CEulerAngles> m_savedRotation;
|
std::optional<zeus::CEulerAngles> m_savedRotation;
|
||||||
|
|
||||||
|
@ -113,6 +116,7 @@ private:
|
||||||
bool m_developer = m_cvarMgr.findCVar("developer")->toBoolean();
|
bool m_developer = m_cvarMgr.findCVar("developer")->toBoolean();
|
||||||
bool m_cheats = m_cvarMgr.findCVar("cheats")->toBoolean();
|
bool m_cheats = m_cvarMgr.findCVar("cheats")->toBoolean();
|
||||||
bool m_isInitialized = false;
|
bool m_isInitialized = false;
|
||||||
|
bool m_isLaunchInitialized = false;
|
||||||
|
|
||||||
int m_debugOverlayCorner = 2; // bottom-left
|
int m_debugOverlayCorner = 2; // bottom-left
|
||||||
int m_inputOverlayCorner = 3; // bottom-right
|
int m_inputOverlayCorner = 3; // bottom-right
|
||||||
|
@ -126,7 +130,8 @@ private:
|
||||||
bool m_controllerConfigVisible = false;
|
bool m_controllerConfigVisible = false;
|
||||||
ImGuiControllerConfig m_controllerConfig;
|
ImGuiControllerConfig m_controllerConfig;
|
||||||
|
|
||||||
void ShowAppMainMenuBar(bool canInspect);
|
void ShowAboutWindow(bool preLaunch);
|
||||||
|
void ShowAppMainMenuBar(bool canInspect, bool preLaunch);
|
||||||
void ShowMenuGame();
|
void ShowMenuGame();
|
||||||
bool ShowEntityInfoWindow(TUniqueId uid);
|
bool ShowEntityInfoWindow(TUniqueId uid);
|
||||||
void ShowInspectWindow(bool* isOpen);
|
void ShowInspectWindow(bool* isOpen);
|
||||||
|
@ -142,5 +147,6 @@ private:
|
||||||
void ShowCornerContextMenu(int& corner, int avoidCorner) const;
|
void ShowCornerContextMenu(int& corner, int avoidCorner) const;
|
||||||
void ShowPlayerTransformEditor();
|
void ShowPlayerTransformEditor();
|
||||||
void ShowPipelineProgress();
|
void ShowPipelineProgress();
|
||||||
|
void ShowPreLaunchSettingsWindow();
|
||||||
};
|
};
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -240,6 +240,8 @@ CMain::CMain(IFactory* resFactory, CSimplePool* resStore)
|
||||||
g_Main = this;
|
g_Main = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMain::~CMain() { g_Main = nullptr; }
|
||||||
|
|
||||||
void CMain::RegisterResourceTweaks() {}
|
void CMain::RegisterResourceTweaks() {}
|
||||||
|
|
||||||
void CGameGlobalObjects::AddPaksAndFactories() {
|
void CGameGlobalObjects::AddPaksAndFactories() {
|
||||||
|
@ -516,15 +518,14 @@ void CMain::HandleDiscordErrored(int errorCode, const char* message) {
|
||||||
DiscordLog.report(logvisor::Error, FMT_STRING("Discord Error: {}"), message);
|
DiscordLog.report(logvisor::Error, FMT_STRING("Discord Error: {}"), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
|
std::string CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
|
||||||
amuse::IBackendVoiceAllocator& backend) {
|
amuse::IBackendVoiceAllocator& backend) {
|
||||||
InitializeDiscord();
|
|
||||||
m_cvarMgr = cvarMgr;
|
m_cvarMgr = cvarMgr;
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto discInfo = CDvdFile::DiscInfo();
|
auto discInfo = CDvdFile::DiscInfo();
|
||||||
if (discInfo.gameId[4] != '0' || discInfo.gameId[5] != '1') {
|
if (discInfo.gameId[4] != '0' || discInfo.gameId[5] != '1') {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Unknown game ID {}"), std::string_view{discInfo.gameId.data(), 6});
|
return fmt::format(FMT_STRING("Unknown game ID {}"), std::string_view{discInfo.gameId.data(), 6});
|
||||||
}
|
}
|
||||||
if (strncmp(discInfo.gameId.data(), "GM8", 3) == 0) {
|
if (strncmp(discInfo.gameId.data(), "GM8", 3) == 0) {
|
||||||
m_version.game = EGame::MetroidPrime1;
|
m_version.game = EGame::MetroidPrime1;
|
||||||
|
@ -545,7 +546,7 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IA
|
||||||
m_version.game = EGame::MetroidPrimeTrilogy;
|
m_version.game = EGame::MetroidPrimeTrilogy;
|
||||||
m_version.platform = EPlatform::Wii;
|
m_version.platform = EPlatform::Wii;
|
||||||
} else {
|
} else {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Unknown game ID {}"), std::string_view{discInfo.gameId.data(), 6});
|
return fmt::format(FMT_STRING("Unknown game ID {}"), std::string_view{discInfo.gameId.data(), 6});
|
||||||
}
|
}
|
||||||
switch (discInfo.gameId[3]) {
|
switch (discInfo.gameId[3]) {
|
||||||
case 'E':
|
case 'E':
|
||||||
|
@ -562,13 +563,13 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IA
|
||||||
m_version.region = ERegion::PAL;
|
m_version.region = ERegion::PAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Unknown region {}"), discInfo.gameId[3]);
|
return fmt::format(FMT_STRING("Unknown region {}"), discInfo.gameId[3]);
|
||||||
}
|
}
|
||||||
m_version.gameTitle = std::move(discInfo.gameTitle);
|
m_version.gameTitle = std::move(discInfo.gameTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_version.game != EGame::MetroidPrime1 && m_version.game != EGame::MetroidPrimeTrilogy) {
|
if (m_version.game != EGame::MetroidPrime1 && m_version.game != EGame::MetroidPrimeTrilogy) {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Unsupported game {}"), magic_enum::enum_name(m_version.game));
|
return fmt::format(FMT_STRING("Unsupported game {}"), magic_enum::enum_name(m_version.game));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -580,19 +581,20 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IA
|
||||||
}
|
}
|
||||||
CDvdFile file(dolFile);
|
CDvdFile file(dolFile);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Failed to open {}"), dolFile);
|
return fmt::format(FMT_STRING("Failed to open {}"), dolFile);
|
||||||
}
|
}
|
||||||
std::unique_ptr<u8[]> buf = std::make_unique<u8[]>(file.Length());
|
std::unique_ptr<u8[]> buf = std::make_unique<u8[]>(file.Length());
|
||||||
u32 readLen = file.SyncRead(buf.get(), file.Length());
|
u32 readLen = file.SyncRead(buf.get(), file.Length());
|
||||||
const char* buildInfo = static_cast<char*>(memmem(buf.get(), readLen, "MetroidBuildInfo", 16)) + 19;
|
const char* buildInfo = static_cast<char*>(memmem(buf.get(), readLen, "MetroidBuildInfo", 16)) + 19;
|
||||||
if (buildInfo == nullptr) {
|
if (buildInfo == nullptr) {
|
||||||
Log.report(logvisor::Fatal, FMT_STRING("Failed to locate MetroidBuildInfo"));
|
return fmt::format(FMT_STRING("Failed to locate MetroidBuildInfo"));
|
||||||
}
|
}
|
||||||
m_version.version = buildInfo;
|
m_version.version = buildInfo;
|
||||||
}
|
}
|
||||||
MainLog.report(logvisor::Level::Info, FMT_STRING("Loading data from {} {} ({})"), GetGameTitle(),
|
MainLog.report(logvisor::Level::Info, FMT_STRING("Loading data from {} {} ({})"), GetGameTitle(),
|
||||||
magic_enum::enum_name(GetRegion()), GetVersionString());
|
magic_enum::enum_name(GetRegion()), GetVersionString());
|
||||||
|
|
||||||
|
InitializeDiscord();
|
||||||
if (m_version.game == EGame::MetroidPrimeTrilogy) {
|
if (m_version.game == EGame::MetroidPrimeTrilogy) {
|
||||||
CDvdFile::SetRootDirectory("MP1");
|
CDvdFile::SetRootDirectory("MP1");
|
||||||
} else if (m_version.platform == EPlatform::Wii) {
|
} else if (m_version.platform == EPlatform::Wii) {
|
||||||
|
@ -657,6 +659,7 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IA
|
||||||
x164_archSupport->PreloadAudio();
|
x164_archSupport->PreloadAudio();
|
||||||
std::srand(static_cast<u32>(CBasics::GetTime()));
|
std::srand(static_cast<u32>(CBasics::GetTime()));
|
||||||
// g_TweakManager->ReadFromMemoryCard("AudioTweaks");
|
// g_TweakManager->ReadFromMemoryCard("AudioTweaks");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMain::Proc(float dt) {
|
bool CMain::Proc(float dt) {
|
||||||
|
|
|
@ -236,6 +236,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMain(IFactory* resFactory, CSimplePool* resStore);
|
CMain(IFactory* resFactory, CSimplePool* resStore);
|
||||||
|
~CMain();
|
||||||
void RegisterResourceTweaks();
|
void RegisterResourceTweaks();
|
||||||
void AddWorldPaks();
|
void AddWorldPaks();
|
||||||
void AddOverridePaks();
|
void AddOverridePaks();
|
||||||
|
@ -251,7 +252,7 @@ public:
|
||||||
|
|
||||||
// int RsMain(int argc, char** argv, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator&
|
// int RsMain(int argc, char** argv, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator&
|
||||||
// backend);
|
// backend);
|
||||||
void Init(const FileStoreManager& storeMgr, CVarManager* cvarManager, boo::IAudioVoiceEngine* voiceEngine,
|
std::string Init(const FileStoreManager& storeMgr, CVarManager* cvarManager, boo::IAudioVoiceEngine* voiceEngine,
|
||||||
amuse::IBackendVoiceAllocator& backend) override;
|
amuse::IBackendVoiceAllocator& backend) override;
|
||||||
bool Proc(float dt) override;
|
bool Proc(float dt) override;
|
||||||
void Draw() override;
|
void Draw() override;
|
||||||
|
|
|
@ -243,14 +243,18 @@ struct AppDelegate {
|
||||||
};
|
};
|
||||||
|
|
||||||
void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv, std::string_view configPath,
|
void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv, std::string_view configPath,
|
||||||
Backend desiredBackend = Backend::Invalid, uint32_t msaa = 1, uint16_t aniso = 16) noexcept;
|
Backend desiredBackend = Backend::Invalid, uint32_t msaa = 1, uint16_t aniso = 16,
|
||||||
|
bool fullscreen = false) noexcept;
|
||||||
[[nodiscard]] std::vector<std::string> get_args() noexcept;
|
[[nodiscard]] std::vector<std::string> get_args() noexcept;
|
||||||
[[nodiscard]] WindowSize get_window_size() noexcept;
|
[[nodiscard]] WindowSize get_window_size() noexcept;
|
||||||
void set_window_title(zstring_view title) noexcept;
|
void set_window_title(zstring_view title) noexcept;
|
||||||
[[nodiscard]] Backend get_backend() noexcept;
|
[[nodiscard]] Backend get_backend() noexcept;
|
||||||
|
[[nodiscard]] std::vector<Backend> get_available_backends() noexcept;
|
||||||
[[nodiscard]] std::string_view get_backend_string() noexcept;
|
[[nodiscard]] std::string_view get_backend_string() noexcept;
|
||||||
[[nodiscard]] Backend translate_backend(std::string_view name);
|
[[nodiscard]] Backend backend_from_string(std::string_view name);
|
||||||
|
[[nodiscard]] std::string_view backend_to_string(Backend backend);
|
||||||
void set_fullscreen(bool fullscreen) noexcept;
|
void set_fullscreen(bool fullscreen) noexcept;
|
||||||
|
bool is_fullscreen() noexcept;
|
||||||
[[nodiscard]] uint32_t get_which_controller_for_player(int32_t index) noexcept;
|
[[nodiscard]] uint32_t get_which_controller_for_player(int32_t index) noexcept;
|
||||||
[[nodiscard]] int32_t get_controller_player_index(uint32_t which) noexcept;
|
[[nodiscard]] int32_t get_controller_player_index(uint32_t which) noexcept;
|
||||||
void set_controller_player_index(uint32_t which, int32_t index) noexcept;
|
void set_controller_player_index(uint32_t which, int32_t index) noexcept;
|
||||||
|
|
|
@ -48,35 +48,12 @@ static void set_window_icon(Icon icon) noexcept {
|
||||||
SDL_FreeSurface(iconSurface);
|
SDL_FreeSurface(iconSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool poll_events() noexcept {
|
static bool g_paused = false;
|
||||||
SDL_Event event;
|
|
||||||
while (SDL_PollEvent(&event) != 0) {
|
|
||||||
imgui::process_event(event);
|
|
||||||
|
|
||||||
switch (event.type) {
|
static void resize_swapchain(bool force) noexcept {
|
||||||
case SDL_WINDOWEVENT: {
|
|
||||||
switch (event.window.event) {
|
|
||||||
case SDL_WINDOWEVENT_SHOWN: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_HIDDEN: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_MOVED: {
|
|
||||||
g_AppDelegate->onAppWindowMoved(event.window.data1, event.window.data2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
|
||||||
case SDL_WINDOWEVENT_DISPLAY_CHANGED:
|
|
||||||
#endif
|
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
||||||
case SDL_WINDOWEVENT_MINIMIZED:
|
|
||||||
case SDL_WINDOWEVENT_MAXIMIZED: {
|
|
||||||
const auto size = get_window_size();
|
const auto size = get_window_size();
|
||||||
if (size == g_windowSize) {
|
if (!force && size == g_windowSize) {
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
if (size.scale != g_windowSize.scale) {
|
if (size.scale != g_windowSize.scale) {
|
||||||
if (g_windowSize.scale > 0.f) {
|
if (g_windowSize.scale > 0.f) {
|
||||||
|
@ -87,38 +64,32 @@ static bool poll_events() noexcept {
|
||||||
g_windowSize = size;
|
g_windowSize = size;
|
||||||
gpu::resize_swapchain(size.fb_width, size.fb_height);
|
gpu::resize_swapchain(size.fb_width, size.fb_height);
|
||||||
g_AppDelegate->onAppWindowResized(size);
|
g_AppDelegate->onAppWindowResized(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool poll_events() noexcept {
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event) != 0) {
|
||||||
|
imgui::process_event(event);
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_WINDOWEVENT: {
|
||||||
|
switch (event.window.event) {
|
||||||
|
case SDL_WINDOWEVENT_MINIMIZED: {
|
||||||
|
// Android/iOS: Application backgrounded
|
||||||
|
g_paused = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_WINDOWEVENT_RESTORED: {
|
case SDL_WINDOWEVENT_RESTORED: {
|
||||||
// TODO: handle restored event
|
// Android/iOS: Application focused
|
||||||
|
g_paused = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_WINDOWEVENT_ENTER: {
|
case SDL_WINDOWEVENT_MOVED: {
|
||||||
// TODO: handle enter event (mouse focus)
|
g_AppDelegate->onAppWindowMoved(event.window.data1, event.window.data2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_WINDOWEVENT_LEAVE: {
|
case SDL_WINDOWEVENT_SIZE_CHANGED: {
|
||||||
// TODO: handle leave event (mouse focus)
|
resize_swapchain(false);
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_FOCUS_GAINED: {
|
|
||||||
// TODO: handle focus gained event
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST: {
|
|
||||||
// TODO: handle focus lost event
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_CLOSE: {
|
|
||||||
// TODO: handle window close event
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_TAKE_FOCUS: {
|
|
||||||
// TODO: handle take focus event
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT_HIT_TEST: {
|
|
||||||
// TODO: handle hit test?
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,6 +127,12 @@ static bool poll_events() noexcept {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_KEYDOWN: {
|
case SDL_KEYDOWN: {
|
||||||
|
// ALT+ENTER for fullscreen toggle
|
||||||
|
if (event.key.repeat == 0u && event.key.keysym.scancode == SDL_SCANCODE_RETURN &&
|
||||||
|
(event.key.keysym.mod & (KMOD_RALT | KMOD_LALT)) != 0u) {
|
||||||
|
set_fullscreen(!is_fullscreen());
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!ImGui::GetIO().WantCaptureKeyboard) {
|
if (!ImGui::GetIO().WantCaptureKeyboard) {
|
||||||
SpecialKey specialKey{};
|
SpecialKey specialKey{};
|
||||||
ModifierKey modifierKey{};
|
ModifierKey modifierKey{};
|
||||||
|
@ -226,12 +203,15 @@ static bool poll_events() noexcept {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_Window* create_window(wgpu::BackendType type) {
|
static SDL_Window* create_window(wgpu::BackendType type, bool fullscreen) {
|
||||||
Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI;
|
Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
#if TARGET_OS_IOS || TARGET_OS_TV || defined(__SWITCH__)
|
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||||
flags |= SDL_WINDOW_FULLSCREEN;
|
flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
#else
|
#else
|
||||||
flags |= SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
flags |= SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||||
|
if (fullscreen) {
|
||||||
|
flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||||
|
@ -252,7 +232,13 @@ static SDL_Window* create_window(wgpu::BackendType type) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return SDL_CreateWindow("Metaforce", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 960, flags);
|
return SDL_CreateWindow("Metaforce", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280,
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
720,
|
||||||
|
#else
|
||||||
|
960,
|
||||||
|
#endif
|
||||||
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
wgpu::BackendType to_wgpu_backend(Backend backend) {
|
wgpu::BackendType to_wgpu_backend(Backend backend) {
|
||||||
|
@ -272,12 +258,11 @@ wgpu::BackendType to_wgpu_backend(Backend backend) {
|
||||||
case Backend::OpenGLES:
|
case Backend::OpenGLES:
|
||||||
return wgpu::BackendType::OpenGLES;
|
return wgpu::BackendType::OpenGLES;
|
||||||
default:
|
default:
|
||||||
case Backend::Null:
|
|
||||||
return wgpu::BackendType::Null;
|
return wgpu::BackendType::Null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv, std::string_view configPath,
|
void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv, std::string_view configPath,
|
||||||
Backend desiredBackend, uint32_t msaa, uint16_t aniso) noexcept {
|
Backend desiredBackend, uint32_t msaa, uint16_t aniso, bool fullscreen) noexcept {
|
||||||
g_AppDelegate = std::move(app);
|
g_AppDelegate = std::move(app);
|
||||||
/* Lets gather arguments skipping the program filename */
|
/* Lets gather arguments skipping the program filename */
|
||||||
for (size_t i = 1; i < argc; ++i) {
|
for (size_t i = 1; i < argc; ++i) {
|
||||||
|
@ -307,7 +292,7 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
/* Attempt to create a window using the calling application's desired backend */
|
/* Attempt to create a window using the calling application's desired backend */
|
||||||
if (desiredBackend != Backend::Invalid) {
|
if (desiredBackend != Backend::Invalid) {
|
||||||
auto wgpuBackend = to_wgpu_backend(desiredBackend);
|
auto wgpuBackend = to_wgpu_backend(desiredBackend);
|
||||||
g_window = create_window(wgpuBackend);
|
g_window = create_window(wgpuBackend, fullscreen);
|
||||||
if (g_window != nullptr && !gpu::initialize(g_window, wgpuBackend, msaa, aniso)) {
|
if (g_window != nullptr && !gpu::initialize(g_window, wgpuBackend, msaa, aniso)) {
|
||||||
g_window = nullptr;
|
g_window = nullptr;
|
||||||
SDL_DestroyWindow(g_window);
|
SDL_DestroyWindow(g_window);
|
||||||
|
@ -316,7 +301,7 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
|
|
||||||
if (g_window == nullptr) {
|
if (g_window == nullptr) {
|
||||||
for (const auto backendType : gpu::PreferredBackendOrder) {
|
for (const auto backendType : gpu::PreferredBackendOrder) {
|
||||||
auto* window = create_window(backendType);
|
auto* window = create_window(backendType, fullscreen);
|
||||||
if (window == nullptr) {
|
if (window == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -365,12 +350,22 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
g_AppDelegate->onAppWindowResized(size);
|
g_AppDelegate->onAppWindowResized(size);
|
||||||
|
|
||||||
while (poll_events()) {
|
while (poll_events()) {
|
||||||
|
if (g_paused) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
imgui::new_frame(g_windowSize);
|
imgui::new_frame(g_windowSize);
|
||||||
if (!g_AppDelegate->onAppIdle(ImGui::GetIO().DeltaTime)) {
|
if (!g_AppDelegate->onAppIdle(ImGui::GetIO().DeltaTime)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wgpu::TextureView view = g_swapChain.GetCurrentTextureView();
|
const wgpu::TextureView view = g_swapChain.GetCurrentTextureView();
|
||||||
|
if (!view) {
|
||||||
|
ImGui::EndFrame();
|
||||||
|
// Force swapchain recreation
|
||||||
|
resize_swapchain(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
gfx::begin_frame();
|
gfx::begin_frame();
|
||||||
g_AppDelegate->onAppDraw();
|
g_AppDelegate->onAppDraw();
|
||||||
|
|
||||||
|
@ -421,6 +416,7 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
}
|
}
|
||||||
SDL_DestroyWindow(g_window);
|
SDL_DestroyWindow(g_window);
|
||||||
|
g_window = nullptr;
|
||||||
SDL_EnableScreenSaver();
|
SDL_EnableScreenSaver();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
@ -468,14 +464,39 @@ Backend get_backend() noexcept {
|
||||||
return Backend::OpenGL;
|
return Backend::OpenGL;
|
||||||
case wgpu::BackendType::OpenGLES:
|
case wgpu::BackendType::OpenGLES:
|
||||||
return Backend::OpenGLES;
|
return Backend::OpenGLES;
|
||||||
|
case wgpu::BackendType::Null:
|
||||||
|
return Backend::Null;
|
||||||
default:
|
default:
|
||||||
return Backend::Invalid;
|
return Backend::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Backend> get_available_backends() noexcept {
|
||||||
|
return {
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_D3D12
|
||||||
|
Backend::D3D12,
|
||||||
|
#endif
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_METAL
|
||||||
|
Backend::Metal,
|
||||||
|
#endif
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||||
|
Backend::Vulkan,
|
||||||
|
#endif
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_DESKTOP_GL
|
||||||
|
Backend::OpenGL,
|
||||||
|
#endif
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_OPENGLES
|
||||||
|
Backend::OpenGLES,
|
||||||
|
#endif
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_NULL
|
||||||
|
Backend::Null,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::string_view get_backend_string() noexcept { return magic_enum::enum_name(gpu::g_backendType); }
|
std::string_view get_backend_string() noexcept { return magic_enum::enum_name(gpu::g_backendType); }
|
||||||
|
|
||||||
Backend translate_backend(std::string_view backend) {
|
Backend backend_from_string(std::string_view backend) {
|
||||||
if (backend.empty()) {
|
if (backend.empty()) {
|
||||||
return Backend::Invalid;
|
return Backend::Invalid;
|
||||||
}
|
}
|
||||||
|
@ -524,10 +545,35 @@ Backend translate_backend(std::string_view backend) {
|
||||||
return Backend::Invalid;
|
return Backend::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view backend_to_string(Backend backend) {
|
||||||
|
switch (backend) {
|
||||||
|
case Backend::Null:
|
||||||
|
return "null"sv;
|
||||||
|
case Backend::WebGPU:
|
||||||
|
return "webgpu"sv;
|
||||||
|
case Backend::D3D11:
|
||||||
|
return "d3d11"sv;
|
||||||
|
case Backend::D3D12:
|
||||||
|
return "d3d12"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::Invalid:
|
||||||
|
return "auto";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void set_fullscreen(bool fullscreen) noexcept {
|
void set_fullscreen(bool fullscreen) noexcept {
|
||||||
SDL_SetWindowFullscreen(g_window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
|
SDL_SetWindowFullscreen(g_window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_fullscreen() noexcept { return (SDL_GetWindowFlags(g_window) & SDL_WINDOW_FULLSCREEN) != 0u; }
|
||||||
|
|
||||||
uint32_t get_which_controller_for_player(int32_t index) noexcept { return input::get_instance_for_player(index); }
|
uint32_t get_which_controller_for_player(int32_t index) noexcept { return input::get_instance_for_player(index); }
|
||||||
int32_t get_controller_player_index(uint32_t instance) noexcept { return input::player_index(instance); }
|
int32_t get_controller_player_index(uint32_t instance) noexcept { return input::player_index(instance); }
|
||||||
|
|
||||||
|
|
|
@ -313,7 +313,10 @@ static void pipeline_worker() {
|
||||||
|
|
||||||
void initialize() {
|
void initialize() {
|
||||||
// No async pipelines for OpenGL (ES)
|
// No async pipelines for OpenGL (ES)
|
||||||
if (gpu::g_backendType != wgpu::BackendType::OpenGL && gpu::g_backendType != wgpu::BackendType::OpenGLES) {
|
if (gpu::g_backendType == wgpu::BackendType::OpenGL || gpu::g_backendType == wgpu::BackendType::OpenGLES) {
|
||||||
|
g_hasPipelineThread = false;
|
||||||
|
} else {
|
||||||
|
g_pipelineThreadEnd = false;
|
||||||
g_pipelineThread = std::thread(pipeline_worker);
|
g_pipelineThread = std::thread(pipeline_worker);
|
||||||
g_hasPipelineThread = true;
|
g_hasPipelineThread = true;
|
||||||
}
|
}
|
||||||
|
@ -425,21 +428,30 @@ void shutdown() {
|
||||||
file.write(reinterpret_cast<const char*>(&g_serializedPipelineCount), sizeof(g_serializedPipelineCount));
|
file.write(reinterpret_cast<const char*>(&g_serializedPipelineCount), sizeof(g_serializedPipelineCount));
|
||||||
file.write(reinterpret_cast<const char*>(g_serializedPipelines.data()), g_serializedPipelines.size());
|
file.write(reinterpret_cast<const char*>(g_serializedPipelines.data()), g_serializedPipelines.size());
|
||||||
}
|
}
|
||||||
|
g_serializedPipelines.clear();
|
||||||
|
g_serializedPipelineCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gx::shutdown();
|
gx::shutdown();
|
||||||
|
|
||||||
g_resolvedTextures.clear();
|
g_resolvedTextures.clear();
|
||||||
|
g_textureUploads.clear();
|
||||||
g_cachedBindGroups.clear();
|
g_cachedBindGroups.clear();
|
||||||
g_cachedSamplers.clear();
|
g_cachedSamplers.clear();
|
||||||
g_pipelines.clear();
|
g_pipelines.clear();
|
||||||
|
g_queuedPipelines.clear();
|
||||||
g_vertexBuffer = {};
|
g_vertexBuffer = {};
|
||||||
g_uniformBuffer = {};
|
g_uniformBuffer = {};
|
||||||
g_indexBuffer = {};
|
g_indexBuffer = {};
|
||||||
g_storageBuffer = {};
|
g_storageBuffer = {};
|
||||||
g_stagingBuffers.fill({});
|
g_stagingBuffers.fill({});
|
||||||
|
g_renderPasses.clear();
|
||||||
|
g_currentRenderPass = 0;
|
||||||
|
|
||||||
g_state = {};
|
g_state = {};
|
||||||
|
|
||||||
|
queuedPipelines = 0;
|
||||||
|
createdPipelines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t currentStagingBuffer = 0;
|
static size_t currentStagingBuffer = 0;
|
||||||
|
|
|
@ -245,9 +245,10 @@ bool initialize(SDL_Window* window, wgpu::BackendType backendType, uint32_t msaa
|
||||||
Log.report(logvisor::Info, FMT_STRING("Creating Dawn instance"));
|
Log.report(logvisor::Info, FMT_STRING("Creating Dawn instance"));
|
||||||
g_Instance = std::make_unique<dawn::native::Instance>();
|
g_Instance = std::make_unique<dawn::native::Instance>();
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
Log.report(logvisor::Info, FMT_STRING("Attempting to initialize {}"), magic_enum::enum_name(backendType));
|
||||||
|
#if 0
|
||||||
// D3D12's debug layer is very slow
|
// D3D12's debug layer is very slow
|
||||||
// g_Instance->EnableBackendValidation(backendType != wgpu::BackendType::D3D12);
|
g_Instance->EnableBackendValidation(backendType != wgpu::BackendType::D3D12);
|
||||||
#endif
|
#endif
|
||||||
if (!utils::DiscoverAdapter(g_Instance.get(), window, backendType)) {
|
if (!utils::DiscoverAdapter(g_Instance.get(), window, backendType)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 369c345a2d40e46b926a1ec5ae75720f2c188247
|
Subproject commit 8341499b8627f9123b14158dbeeeadef9c9e7f4d
|
Loading…
Reference in New Issue