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;
|
||||
CVarCommons& m_cvarCommons;
|
||||
ImGuiConsole m_imGuiConsole;
|
||||
std::string m_errorString;
|
||||
|
||||
std::string m_deferredProject;
|
||||
bool m_projectInitialized = false;
|
||||
|
@ -166,7 +165,7 @@ private:
|
|||
bool m_fullscreenToggleRequested = false;
|
||||
bool m_quitRequested = false;
|
||||
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
|
||||
// is built, i.e during initialization
|
||||
|
@ -224,9 +223,9 @@ public:
|
|||
m_projectInitialized = true;
|
||||
} else {
|
||||
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_deferredProject.clear();
|
||||
m_imGuiConsole.m_errorString = fmt::format(FMT_STRING("Failed to open disc image '{}'"), m_deferredProject);
|
||||
}
|
||||
m_deferredProject.clear();
|
||||
}
|
||||
|
||||
const auto targetFrameTime = getTargetFrameTime();
|
||||
|
@ -266,7 +265,14 @@ public:
|
|||
|
||||
if (!g_mainMP1 && m_projectInitialized) {
|
||||
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;
|
||||
|
@ -274,8 +280,8 @@ public:
|
|||
dt = std::min(realDt, 1 / 30.f);
|
||||
}
|
||||
|
||||
m_imGuiConsole.PreUpdate();
|
||||
if (g_mainMP1) {
|
||||
m_imGuiConsole.PreUpdate();
|
||||
if (m_voiceEngine) {
|
||||
m_voiceEngine->lockPump();
|
||||
}
|
||||
|
@ -285,15 +291,15 @@ public:
|
|||
if (m_voiceEngine) {
|
||||
m_voiceEngine->unlockPump();
|
||||
}
|
||||
m_imGuiConsole.PostUpdate();
|
||||
} else {
|
||||
auto result = m_imGuiConsole.ShowAboutWindow(false, m_errorString, true);
|
||||
if (result) {
|
||||
m_deferredProject = std::move(*result);
|
||||
}
|
||||
}
|
||||
m_imGuiConsole.PostUpdate();
|
||||
if (!g_mainMP1 && m_imGuiConsole.m_gameDiscSelected) {
|
||||
std::optional<std::string> result;
|
||||
m_imGuiConsole.m_gameDiscSelected.swap(result);
|
||||
m_deferredProject = std::move(*result);
|
||||
}
|
||||
|
||||
if (m_quitRequested) {
|
||||
if (m_quitRequested || m_imGuiConsole.m_quitRequested || m_cvarManager.restartRequired()) {
|
||||
if (g_mainMP1) {
|
||||
g_mainMP1->Quit();
|
||||
} else {
|
||||
|
@ -489,7 +495,7 @@ public:
|
|||
|
||||
} // namespace metaforce
|
||||
|
||||
static void SetupBasics(bool logging) {
|
||||
static void SetupBasics() {
|
||||
#if _WIN32
|
||||
if (logging && GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_UNKNOWN)
|
||||
logvisor::CreateWin32Console();
|
||||
|
@ -509,10 +515,6 @@ static void SetupBasics(bool logging) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
logvisor::RegisterStandardExceptions();
|
||||
if (logging)
|
||||
logvisor::RegisterConsoleLogger();
|
||||
|
||||
#if SENTRY_ENABLED
|
||||
FileStoreManager fileMgr{"sentry-native-metaforce"};
|
||||
std::string cacheDir{fileMgr.getStoreRoot()};
|
||||
|
@ -531,7 +533,6 @@ static bool IsClientLoggingEnabled(int argc, char** argv) {
|
|||
|
||||
#if !WINDOWS_STORE
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// TODO: This seems to fix a lot of weird issues with rounding
|
||||
// but breaks animations, need to research why this is the case
|
||||
// for now it's disabled
|
||||
|
@ -541,36 +542,49 @@ int main(int argc, char** argv) {
|
|||
return 100;
|
||||
}
|
||||
|
||||
SetupBasics(IsClientLoggingEnabled(argc, argv));
|
||||
SetupBasics();
|
||||
metaforce::FileStoreManager fileMgr{"AxioDL", "metaforce"};
|
||||
metaforce::CVarManager cvarMgr{fileMgr};
|
||||
metaforce::CVarCommons cvarCmns{cvarMgr};
|
||||
|
||||
std::vector<std::string> args;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
args.emplace_back(argv[i]);
|
||||
cvarMgr.parseCommandLine(args);
|
||||
|
||||
std::string logFile = cvarCmns.getLogFile();
|
||||
std::string logFilePath;
|
||||
if (!logFile.empty()) {
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
char buf[100];
|
||||
std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time));
|
||||
logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile);
|
||||
logvisor::RegisterFileLogger(logFilePath.c_str());
|
||||
}
|
||||
|
||||
auto app = std::make_unique<metaforce::Application>(fileMgr, cvarMgr, cvarCmns);
|
||||
auto icon = metaforce::GetIcon();
|
||||
auto data = aurora::Icon{
|
||||
.data = std::move(icon.data),
|
||||
.width = icon.width,
|
||||
.height = icon.height,
|
||||
};
|
||||
aurora::app_run(std::move(app), std::move(data), argc, argv, fileMgr.getStoreRoot(),
|
||||
aurora::translate_backend(cvarCmns.getGraphicsApi()), cvarCmns.getSamples(),
|
||||
cvarCmns.getAnisotropy());
|
||||
bool restart = false;
|
||||
do {
|
||||
metaforce::CVarManager cvarMgr{fileMgr};
|
||||
metaforce::CVarCommons cvarCmns{cvarMgr};
|
||||
if (!restart) {
|
||||
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 logFilePath;
|
||||
if (!logFile.empty()) {
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
char buf[100];
|
||||
std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time));
|
||||
logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile);
|
||||
logvisor::RegisterFileLogger(logFilePath.c_str());
|
||||
}
|
||||
}
|
||||
auto app = std::make_unique<metaforce::Application>(fileMgr, cvarMgr, cvarCmns);
|
||||
auto icon = metaforce::GetIcon();
|
||||
auto data = aurora::Icon{
|
||||
.data = std::move(icon.data),
|
||||
.width = icon.width,
|
||||
.height = icon.height,
|
||||
};
|
||||
aurora::app_run(std::move(app), std::move(data), argc, argv, fileMgr.getStoreRoot(),
|
||||
aurora::backend_from_string(cvarCmns.getGraphicsApi()), cvarCmns.getSamples(),
|
||||
cvarCmns.getAnisotropy(), cvarCmns.getFullscreen());
|
||||
restart = cvarMgr.restartRequired();
|
||||
} while (restart);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,8 +37,8 @@ enum class EGameplayResult { None, Win, Lose, Playing };
|
|||
class IMain {
|
||||
public:
|
||||
virtual ~IMain() = default;
|
||||
virtual void Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr,
|
||||
boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) = 0;
|
||||
virtual std::string Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
|
||||
amuse::IBackendVoiceAllocator& backend) = 0;
|
||||
virtual void Draw() = 0;
|
||||
virtual bool Proc(float dt) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
|
|
@ -41,6 +41,9 @@ std::array<ImGuiEntityEntry, kMaxEntities> ImGuiConsole::entities;
|
|||
std::set<TUniqueId> ImGuiConsole::inspectingEntities;
|
||||
ImGuiPlayerLoadouts ImGuiConsole::loadouts;
|
||||
|
||||
ImGuiConsole::ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons)
|
||||
: m_cvarMgr(cvarMgr), m_cvarCommons(cvarCommons) {}
|
||||
|
||||
void ImGuiStringViewText(std::string_view text) {
|
||||
// begin()/end() do not work on MSVC
|
||||
ImGui::TextUnformatted(text.data(), text.data() + text.size());
|
||||
|
@ -137,8 +140,10 @@ static void Warp(const CAssetId worldId, TAreaId aId) {
|
|||
}
|
||||
|
||||
void ImGuiConsole::ShowMenuGame() {
|
||||
m_paused = g_Main->IsPaused();
|
||||
if (ImGui::MenuItem("Paused", "F5", &m_paused)) {
|
||||
if (g_Main != nullptr) {
|
||||
m_paused = g_Main->IsPaused();
|
||||
}
|
||||
if (ImGui::MenuItem("Paused", "F5", &m_paused, g_Main != nullptr)) {
|
||||
g_Main->SetPaused(m_paused);
|
||||
}
|
||||
if (ImGui::MenuItem("Step Frame", "F6", &m_stepFrame, m_paused)) {
|
||||
|
@ -159,7 +164,7 @@ void ImGuiConsole::ShowMenuGame() {
|
|||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::MenuItem("Quit", "Alt+F4")) {
|
||||
g_Main->Quit();
|
||||
m_quitRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,12 +645,10 @@ void ImGuiConsole::ShowConsoleVariablesWindow() {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::string_view errorString, bool preLaunch) {
|
||||
std::optional<std::string> result{};
|
||||
|
||||
void ImGuiConsole::ShowAboutWindow(bool preLaunch) {
|
||||
// Center window
|
||||
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];
|
||||
ImGui::PushStyleColor(ImGuiCol_TitleBg, windowBg);
|
||||
|
@ -654,10 +657,10 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
|||
bool* open = nullptr;
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_NoSavedSettings;
|
||||
if (canClose) {
|
||||
open = &m_showAboutWindow;
|
||||
} else {
|
||||
if (preLaunch) {
|
||||
flags |= ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove;
|
||||
} else {
|
||||
open = &m_showAboutWindow;
|
||||
}
|
||||
if (ImGui::Begin("About", open, flags)) {
|
||||
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;
|
||||
ImGui::Dummy(padding);
|
||||
if (preLaunch) {
|
||||
if (ImGuiButtonCenter("Settings")) {
|
||||
m_showPreLaunchSettingsWindow = true;
|
||||
}
|
||||
ImGui::Dummy(padding);
|
||||
#ifdef NATIVEFILEDIALOG_SUPPORTED
|
||||
if (ImGuiButtonCenter("Select Game Disc")) {
|
||||
nfdchar_t* outPath = nullptr;
|
||||
nfdresult_t nfdResult = NFD_OpenDialog(nullptr, nullptr, &outPath);
|
||||
if (nfdResult == NFD_OKAY) {
|
||||
result = outPath;
|
||||
m_gameDiscSelected = outPath;
|
||||
free(outPath);
|
||||
} else if (nfdResult != NFD_CANCEL) {
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
if (!errorString.empty()) {
|
||||
if (m_errorString) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{0.77f, 0.12f, 0.23f, 1.f});
|
||||
ImGuiTextCenter(errorString);
|
||||
ImGuiTextCenter(*m_errorString);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Dummy(padding);
|
||||
}
|
||||
|
@ -764,7 +771,6 @@ std::optional<std::string> ImGuiConsole::ShowAboutWindow(bool canClose, std::str
|
|||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleColor(2);
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string BytesToString(size_t bytes) {
|
||||
|
@ -932,7 +938,7 @@ void ImGuiConsole::ShowDebugOverlay() {
|
|||
ImGuiStringViewText(
|
||||
fmt::format(FMT_STRING("CRandom16::Next calls: {}\n"), metaforce::CRandom16::GetNumNextCalls()));
|
||||
}
|
||||
if (m_resourceStats) {
|
||||
if (m_resourceStats && g_SimplePool != nullptr) {
|
||||
if (hasPrevious) {
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
@ -1168,7 +1174,7 @@ void ImGuiConsole::SetOverlayWindowLocation(int corner) const {
|
|||
ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, windowPosPivot);
|
||||
}
|
||||
|
||||
void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
|
||||
void ImGuiConsole::ShowAppMainMenuBar(bool canInspect, bool preLaunch) {
|
||||
if (ImGui::BeginMainMenuBar()) {
|
||||
if (ImGui::BeginMenu("Game")) {
|
||||
ShowMenuGame();
|
||||
|
@ -1221,7 +1227,7 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
|
|||
}
|
||||
ImGui::Spacing();
|
||||
if (ImGui::BeginMenu("Help")) {
|
||||
ImGui::MenuItem("About", nullptr, &m_showAboutWindow);
|
||||
ImGui::MenuItem("About", nullptr, &m_showAboutWindow, !preLaunch);
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu("ImGui")) {
|
||||
if (ImGui::MenuItem("Clear Settings")) {
|
||||
|
@ -1240,6 +1246,7 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
|
|||
|
||||
void ImGuiConsole::PreUpdate() {
|
||||
OPTICK_EVENT();
|
||||
bool preLaunch = g_Main == nullptr;
|
||||
if (!m_isInitialized) {
|
||||
m_isInitialized = true;
|
||||
m_cvarCommons.m_debugOverlayShowFrameCounter->addListener([this](CVar* c) { m_frameCounter = c->toBoolean(); });
|
||||
|
@ -1255,33 +1262,38 @@ void ImGuiConsole::PreUpdate() {
|
|||
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("cheats")->addListener([this](CVar* c) { m_cheats = c->toBoolean(); });
|
||||
}
|
||||
if (!preLaunch && !m_isLaunchInitialized) {
|
||||
if (m_developer) {
|
||||
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) {
|
||||
g_StateManager->SetActiveRandomToDefault();
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_GraveAccent)) {
|
||||
m_isVisible ^= 1;
|
||||
}
|
||||
if (m_stepFrame) {
|
||||
g_Main->SetPaused(true);
|
||||
m_stepFrame = false;
|
||||
}
|
||||
if (m_paused && !m_stepFrame && ImGui::IsKeyPressed(ImGuiKey_F6)) {
|
||||
g_Main->SetPaused(false);
|
||||
m_stepFrame = true;
|
||||
}
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_F5)) {
|
||||
m_paused ^= 1;
|
||||
g_Main->SetPaused(m_paused);
|
||||
if (!preLaunch) {
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_GraveAccent)) {
|
||||
m_isVisible ^= 1;
|
||||
}
|
||||
if (m_stepFrame) {
|
||||
g_Main->SetPaused(true);
|
||||
m_stepFrame = false;
|
||||
}
|
||||
if (m_paused && !m_stepFrame && ImGui::IsKeyPressed(ImGuiKey_F6)) {
|
||||
g_Main->SetPaused(false);
|
||||
m_stepFrame = true;
|
||||
}
|
||||
if (ImGui::IsKeyReleased(ImGuiKey_F5)) {
|
||||
m_paused ^= 1;
|
||||
g_Main->SetPaused(m_paused);
|
||||
}
|
||||
}
|
||||
bool canInspect = g_StateManager != nullptr && g_StateManager->GetObjectList();
|
||||
if (m_isVisible) {
|
||||
ShowAppMainMenuBar(canInspect);
|
||||
if (preLaunch || m_isVisible) {
|
||||
ShowAppMainMenuBar(canInspect, preLaunch);
|
||||
}
|
||||
ShowToasts();
|
||||
if (canInspect && (m_showInspectWindow || !inspectingEntities.empty())) {
|
||||
|
@ -1304,8 +1316,8 @@ void ImGuiConsole::PreUpdate() {
|
|||
if (canInspect && m_showLayersWindow) {
|
||||
ShowLayersWindow();
|
||||
}
|
||||
if (m_showAboutWindow) {
|
||||
ShowAboutWindow(true);
|
||||
if (preLaunch || m_showAboutWindow) {
|
||||
ShowAboutWindow(preLaunch);
|
||||
}
|
||||
if (m_showDemoWindow) {
|
||||
ImGui::ShowDemoWindow(&m_showDemoWindow);
|
||||
|
@ -1318,6 +1330,9 @@ void ImGuiConsole::PreUpdate() {
|
|||
ShowPlayerTransformEditor();
|
||||
ShowPipelineProgress();
|
||||
m_controllerConfig.show(m_controllerConfigVisible);
|
||||
if (preLaunch && m_showPreLaunchSettingsWindow) {
|
||||
ShowPreLaunchSettingsWindow();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// 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();
|
||||
m_currentRoom = static_cast<const void*>(g_StateManager->GetCurrentArea());
|
||||
m_lastRoomTime = igt - m_currentRoomStart;
|
||||
|
@ -1781,4 +1796,66 @@ void ImGuiConsole::ControllerAdded(uint32_t idx) {
|
|||
void ImGuiConsole::ControllerRemoved(uint32_t idx) {
|
||||
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
|
||||
|
|
|
@ -51,12 +51,10 @@ public:
|
|||
static std::array<ImGuiEntityEntry, kMaxEntities> entities;
|
||||
static ImGuiPlayerLoadouts loadouts;
|
||||
|
||||
ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons) : m_cvarMgr(cvarMgr), m_cvarCommons(cvarCommons) {}
|
||||
ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons);
|
||||
void PreUpdate();
|
||||
void PostUpdate();
|
||||
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 EndEntityRow(const ImGuiEntityEntry& entry);
|
||||
|
@ -64,6 +62,10 @@ public:
|
|||
void ControllerAdded(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:
|
||||
CVarManager& m_cvarMgr;
|
||||
CVarCommons& m_cvarCommons;
|
||||
|
@ -75,6 +77,7 @@ private:
|
|||
bool m_showLayersWindow = false;
|
||||
bool m_showConsoleVariablesWindow = false;
|
||||
bool m_showPlayerTransformEditor = false;
|
||||
bool m_showPreLaunchSettingsWindow = false;
|
||||
std::optional<zeus::CVector3f> m_savedLocation;
|
||||
std::optional<zeus::CEulerAngles> m_savedRotation;
|
||||
|
||||
|
@ -113,6 +116,7 @@ private:
|
|||
bool m_developer = m_cvarMgr.findCVar("developer")->toBoolean();
|
||||
bool m_cheats = m_cvarMgr.findCVar("cheats")->toBoolean();
|
||||
bool m_isInitialized = false;
|
||||
bool m_isLaunchInitialized = false;
|
||||
|
||||
int m_debugOverlayCorner = 2; // bottom-left
|
||||
int m_inputOverlayCorner = 3; // bottom-right
|
||||
|
@ -126,7 +130,8 @@ private:
|
|||
bool m_controllerConfigVisible = false;
|
||||
ImGuiControllerConfig m_controllerConfig;
|
||||
|
||||
void ShowAppMainMenuBar(bool canInspect);
|
||||
void ShowAboutWindow(bool preLaunch);
|
||||
void ShowAppMainMenuBar(bool canInspect, bool preLaunch);
|
||||
void ShowMenuGame();
|
||||
bool ShowEntityInfoWindow(TUniqueId uid);
|
||||
void ShowInspectWindow(bool* isOpen);
|
||||
|
@ -142,5 +147,6 @@ private:
|
|||
void ShowCornerContextMenu(int& corner, int avoidCorner) const;
|
||||
void ShowPlayerTransformEditor();
|
||||
void ShowPipelineProgress();
|
||||
void ShowPreLaunchSettingsWindow();
|
||||
};
|
||||
} // namespace metaforce
|
||||
|
|
|
@ -240,6 +240,8 @@ CMain::CMain(IFactory* resFactory, CSimplePool* resStore)
|
|||
g_Main = this;
|
||||
}
|
||||
|
||||
CMain::~CMain() { g_Main = nullptr; }
|
||||
|
||||
void CMain::RegisterResourceTweaks() {}
|
||||
|
||||
void CGameGlobalObjects::AddPaksAndFactories() {
|
||||
|
@ -516,15 +518,14 @@ void CMain::HandleDiscordErrored(int errorCode, const char* message) {
|
|||
DiscordLog.report(logvisor::Error, FMT_STRING("Discord Error: {}"), message);
|
||||
}
|
||||
|
||||
void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
|
||||
amuse::IBackendVoiceAllocator& backend) {
|
||||
InitializeDiscord();
|
||||
std::string CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IAudioVoiceEngine* voiceEngine,
|
||||
amuse::IBackendVoiceAllocator& backend) {
|
||||
m_cvarMgr = cvarMgr;
|
||||
|
||||
{
|
||||
const auto discInfo = CDvdFile::DiscInfo();
|
||||
auto discInfo = CDvdFile::DiscInfo();
|
||||
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) {
|
||||
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.platform = EPlatform::Wii;
|
||||
} 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]) {
|
||||
case 'E':
|
||||
|
@ -562,13 +563,13 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IA
|
|||
m_version.region = ERegion::PAL;
|
||||
break;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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());
|
||||
u32 readLen = file.SyncRead(buf.get(), file.Length());
|
||||
const char* buildInfo = static_cast<char*>(memmem(buf.get(), readLen, "MetroidBuildInfo", 16)) + 19;
|
||||
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;
|
||||
}
|
||||
MainLog.report(logvisor::Level::Info, FMT_STRING("Loading data from {} {} ({})"), GetGameTitle(),
|
||||
magic_enum::enum_name(GetRegion()), GetVersionString());
|
||||
|
||||
InitializeDiscord();
|
||||
if (m_version.game == EGame::MetroidPrimeTrilogy) {
|
||||
CDvdFile::SetRootDirectory("MP1");
|
||||
} else if (m_version.platform == EPlatform::Wii) {
|
||||
|
@ -657,6 +659,7 @@ void CMain::Init(const FileStoreManager& storeMgr, CVarManager* cvarMgr, boo::IA
|
|||
x164_archSupport->PreloadAudio();
|
||||
std::srand(static_cast<u32>(CBasics::GetTime()));
|
||||
// g_TweakManager->ReadFromMemoryCard("AudioTweaks");
|
||||
return {};
|
||||
}
|
||||
|
||||
bool CMain::Proc(float dt) {
|
||||
|
|
|
@ -236,6 +236,7 @@ private:
|
|||
|
||||
public:
|
||||
CMain(IFactory* resFactory, CSimplePool* resStore);
|
||||
~CMain();
|
||||
void RegisterResourceTweaks();
|
||||
void AddWorldPaks();
|
||||
void AddOverridePaks();
|
||||
|
@ -251,8 +252,8 @@ public:
|
|||
|
||||
// int RsMain(int argc, char** argv, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator&
|
||||
// backend);
|
||||
void Init(const FileStoreManager& storeMgr, CVarManager* cvarManager, boo::IAudioVoiceEngine* voiceEngine,
|
||||
amuse::IBackendVoiceAllocator& backend) override;
|
||||
std::string Init(const FileStoreManager& storeMgr, CVarManager* cvarManager, boo::IAudioVoiceEngine* voiceEngine,
|
||||
amuse::IBackendVoiceAllocator& backend) override;
|
||||
bool Proc(float dt) override;
|
||||
void Draw() override;
|
||||
void Shutdown() 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,
|
||||
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]] WindowSize get_window_size() noexcept;
|
||||
void set_window_title(zstring_view title) noexcept;
|
||||
[[nodiscard]] Backend get_backend() noexcept;
|
||||
[[nodiscard]] std::vector<Backend> get_available_backends() 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;
|
||||
bool is_fullscreen() noexcept;
|
||||
[[nodiscard]] uint32_t get_which_controller_for_player(int32_t index) noexcept;
|
||||
[[nodiscard]] int32_t get_controller_player_index(uint32_t which) noexcept;
|
||||
void set_controller_player_index(uint32_t which, int32_t index) noexcept;
|
||||
|
|
|
@ -48,6 +48,24 @@ static void set_window_icon(Icon icon) noexcept {
|
|||
SDL_FreeSurface(iconSurface);
|
||||
}
|
||||
|
||||
static bool g_paused = false;
|
||||
|
||||
static void resize_swapchain(bool force) noexcept {
|
||||
const auto size = get_window_size();
|
||||
if (!force && size == g_windowSize) {
|
||||
return;
|
||||
}
|
||||
if (size.scale != g_windowSize.scale) {
|
||||
if (g_windowSize.scale > 0.f) {
|
||||
Log.report(logvisor::Info, FMT_STRING("Display scale changed to {}"), size.scale);
|
||||
}
|
||||
g_AppDelegate->onAppDisplayScaleChanged(size.scale);
|
||||
}
|
||||
g_windowSize = size;
|
||||
gpu::resize_swapchain(size.fb_width, size.fb_height);
|
||||
g_AppDelegate->onAppWindowResized(size);
|
||||
}
|
||||
|
||||
static bool poll_events() noexcept {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event) != 0) {
|
||||
|
@ -56,69 +74,22 @@ static bool poll_events() noexcept {
|
|||
switch (event.type) {
|
||||
case SDL_WINDOWEVENT: {
|
||||
switch (event.window.event) {
|
||||
case SDL_WINDOWEVENT_SHOWN: {
|
||||
case SDL_WINDOWEVENT_MINIMIZED: {
|
||||
// Android/iOS: Application backgrounded
|
||||
g_paused = true;
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_HIDDEN: {
|
||||
case SDL_WINDOWEVENT_RESTORED: {
|
||||
// Android/iOS: Application focused
|
||||
g_paused = false;
|
||||
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();
|
||||
if (size == g_windowSize) {
|
||||
break;
|
||||
}
|
||||
if (size.scale != g_windowSize.scale) {
|
||||
if (g_windowSize.scale > 0.f) {
|
||||
Log.report(logvisor::Info, FMT_STRING("Display scale changed to {}"), size.scale);
|
||||
}
|
||||
g_AppDelegate->onAppDisplayScaleChanged(size.scale);
|
||||
}
|
||||
g_windowSize = size;
|
||||
gpu::resize_swapchain(size.fb_width, size.fb_height);
|
||||
g_AppDelegate->onAppWindowResized(size);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_RESTORED: {
|
||||
// TODO: handle restored event
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_ENTER: {
|
||||
// TODO: handle enter event (mouse focus)
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_LEAVE: {
|
||||
// TODO: handle leave event (mouse focus)
|
||||
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?
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED: {
|
||||
resize_swapchain(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +127,12 @@ static bool poll_events() noexcept {
|
|||
break;
|
||||
}
|
||||
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) {
|
||||
SpecialKey specialKey{};
|
||||
ModifierKey modifierKey{};
|
||||
|
@ -226,12 +203,15 @@ static bool poll_events() noexcept {
|
|||
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;
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV || defined(__SWITCH__)
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
flags |= SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||
if (fullscreen) {
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
#endif
|
||||
switch (type) {
|
||||
#ifdef DAWN_ENABLE_BACKEND_VULKAN
|
||||
|
@ -252,7 +232,13 @@ static SDL_Window* create_window(wgpu::BackendType type) {
|
|||
default:
|
||||
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) {
|
||||
|
@ -272,12 +258,11 @@ wgpu::BackendType to_wgpu_backend(Backend backend) {
|
|||
case Backend::OpenGLES:
|
||||
return wgpu::BackendType::OpenGLES;
|
||||
default:
|
||||
case Backend::Null:
|
||||
return wgpu::BackendType::Null;
|
||||
}
|
||||
}
|
||||
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);
|
||||
/* Lets gather arguments skipping the program filename */
|
||||
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 */
|
||||
if (desiredBackend != Backend::Invalid) {
|
||||
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)) {
|
||||
g_window = nullptr;
|
||||
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) {
|
||||
for (const auto backendType : gpu::PreferredBackendOrder) {
|
||||
auto* window = create_window(backendType);
|
||||
auto* window = create_window(backendType, fullscreen);
|
||||
if (window == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
@ -365,12 +350,22 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
|||
g_AppDelegate->onAppWindowResized(size);
|
||||
|
||||
while (poll_events()) {
|
||||
if (g_paused) {
|
||||
continue;
|
||||
}
|
||||
|
||||
imgui::new_frame(g_windowSize);
|
||||
if (!g_AppDelegate->onAppIdle(ImGui::GetIO().DeltaTime)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const wgpu::TextureView view = g_swapChain.GetCurrentTextureView();
|
||||
if (!view) {
|
||||
ImGui::EndFrame();
|
||||
// Force swapchain recreation
|
||||
resize_swapchain(true);
|
||||
continue;
|
||||
}
|
||||
gfx::begin_frame();
|
||||
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_DestroyWindow(g_window);
|
||||
g_window = nullptr;
|
||||
SDL_EnableScreenSaver();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
@ -468,14 +464,39 @@ Backend get_backend() noexcept {
|
|||
return Backend::OpenGL;
|
||||
case wgpu::BackendType::OpenGLES:
|
||||
return Backend::OpenGLES;
|
||||
case wgpu::BackendType::Null:
|
||||
return Backend::Null;
|
||||
default:
|
||||
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); }
|
||||
|
||||
Backend translate_backend(std::string_view backend) {
|
||||
Backend backend_from_string(std::string_view backend) {
|
||||
if (backend.empty()) {
|
||||
return Backend::Invalid;
|
||||
}
|
||||
|
@ -524,10 +545,35 @@ Backend translate_backend(std::string_view backend) {
|
|||
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 {
|
||||
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); }
|
||||
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() {
|
||||
// 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_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_serializedPipelines.data()), g_serializedPipelines.size());
|
||||
}
|
||||
g_serializedPipelines.clear();
|
||||
g_serializedPipelineCount = 0;
|
||||
}
|
||||
|
||||
gx::shutdown();
|
||||
|
||||
g_resolvedTextures.clear();
|
||||
g_textureUploads.clear();
|
||||
g_cachedBindGroups.clear();
|
||||
g_cachedSamplers.clear();
|
||||
g_pipelines.clear();
|
||||
g_queuedPipelines.clear();
|
||||
g_vertexBuffer = {};
|
||||
g_uniformBuffer = {};
|
||||
g_indexBuffer = {};
|
||||
g_storageBuffer = {};
|
||||
g_stagingBuffers.fill({});
|
||||
g_renderPasses.clear();
|
||||
g_currentRenderPass = 0;
|
||||
|
||||
g_state = {};
|
||||
|
||||
queuedPipelines = 0;
|
||||
createdPipelines = 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"));
|
||||
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
|
||||
// g_Instance->EnableBackendValidation(backendType != wgpu::BackendType::D3D12);
|
||||
g_Instance->EnableBackendValidation(backendType != wgpu::BackendType::D3D12);
|
||||
#endif
|
||||
if (!utils::DiscoverAdapter(g_Instance.get(), window, backendType)) {
|
||||
return false;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 369c345a2d40e46b926a1ec5ae75720f2c188247
|
||||
Subproject commit 8341499b8627f9123b14158dbeeeadef9c9e7f4d
|
Loading…
Reference in New Issue