diff --git a/external/sciterui b/external/sciterui index ae16bf64..a6b88385 160000 --- a/external/sciterui +++ b/external/sciterui @@ -1 +1 @@ -Subproject commit ae16bf646df94d1bd15a9a5fd63335ed56deceb0 +Subproject commit a6b88385f3e903011502d8257ffb08035b6c49cb diff --git a/lang/english/css/main_window.css b/lang/english/css/main_window.css index 474c6f3a..09bad0f0 100644 --- a/lang/english/css/main_window.css +++ b/lang/english/css/main_window.css @@ -199,3 +199,9 @@ menu li:has-child-of-type(menu):rtl foreground-repeat: no-repeat; foreground-position: top 50% left 2px; } + +#MainContents +{ + width: 100%%; + height: 100%%; +} \ No newline at end of file diff --git a/lang/english/html/loading.html b/lang/english/html/loading.html new file mode 100644 index 00000000..7d18d4d5 --- /dev/null +++ b/lang/english/html/loading.html @@ -0,0 +1,64 @@ + +
+
Loading +
+
+
+
+
+
+
diff --git a/lang/english/html/main_window.html b/lang/english/html/main_window.html index 7126cc37..12e378e6 100644 --- a/lang/english/html/main_window.html +++ b/lang/english/html/main_window.html @@ -11,4 +11,5 @@ +
diff --git a/src/nxemu-core/settings/core_settings.cpp b/src/nxemu-core/settings/core_settings.cpp index 45ec8f2c..7baf256d 100644 --- a/src/nxemu-core/settings/core_settings.cpp +++ b/src/nxemu-core/settings/core_settings.cpp @@ -19,6 +19,9 @@ struct CoreSettingsDefaults static constexpr const char * defaultModuleOperatingSystem = "operating_system\\nxemu-os.dll"; #endif static constexpr bool defaultShowConsole = false; + static constexpr bool defaultRomLoading = false; + static constexpr bool defaultEmulationRunning = false; + static constexpr bool defaultDisplayedFrames = false; static Path GetDefaultModuleDir(); }; @@ -63,6 +66,10 @@ void LoadCoreSetting(void) settings.SetDefaultString(NXCoreSetting::ModuleOsSelected, CoreSettingsDefaults::defaultModuleOperatingSystem); settings.SetDefaultBool(NXCoreSetting::ShowConsole, CoreSettingsDefaults::defaultShowConsole); + settings.SetDefaultBool(NXCoreSetting::RomLoading, CoreSettingsDefaults::defaultRomLoading); + settings.SetDefaultBool(NXCoreSetting::EmulationRunning, CoreSettingsDefaults::defaultEmulationRunning); + settings.SetDefaultBool(NXCoreSetting::DisplayedFrames, CoreSettingsDefaults::defaultDisplayedFrames); + coreSettings.moduleCpuSelected = CoreSettingsDefaults::defaultModuleCpu; coreSettings.moduleVideoSelected = CoreSettingsDefaults::defaultModuleVideo; coreSettings.moduleOsSelected = CoreSettingsDefaults::defaultModuleOperatingSystem; diff --git a/src/nxemu-core/settings/identifiers.h b/src/nxemu-core/settings/identifiers.h index 4ea61740..c605b272 100644 --- a/src/nxemu-core/settings/identifiers.h +++ b/src/nxemu-core/settings/identifiers.h @@ -8,4 +8,8 @@ constexpr const char * ModuleCpuSelected = "nxcore:ModuleCpuSelected"; constexpr const char * ModuleVideoSelected = "nxcore:ModuleVideoSelected"; constexpr const char * ModuleOsSelected = "nxcore:ModuleOsSelected"; constexpr const char * ShowConsole = "nxcore:ShowConsole"; +constexpr const char * RomLoading = "nxcore:RomLoading"; +constexpr const char * EmulationRunning = "nxcore:EmulationRunning"; +constexpr const char * DisplayedFrames = "nxcore:DisplayedFrames"; + } // namespace NXCoreSetting \ No newline at end of file diff --git a/src/nxemu-core/switch_rom.cpp b/src/nxemu-core/switch_rom.cpp index 596df0ff..1c504ab8 100644 --- a/src/nxemu-core/switch_rom.cpp +++ b/src/nxemu-core/switch_rom.cpp @@ -1,8 +1,17 @@ -#include "switch_rom.h" +#include #include "machine/switch_system.h" +#include "settings/settings.h" +#include "switch_rom.h" bool LaunchSwitchRom(IRenderWindow & window, const char * romFile) { + Settings & settings = Settings::GetInstance(); + settings.SetBool(NXCoreSetting::RomLoading, true); + // settings on rom loading, emulation running, content rendering + // + // hide rom list, show loading screen + // hide loading screen on first frame + if (!SwitchSystem::Create(window)) { return false; @@ -12,6 +21,8 @@ bool LaunchSwitchRom(IRenderWindow & window, const char * romFile) { return false; } + settings.SetBool(NXCoreSetting::RomLoading, false); + settings.SetBool(NXCoreSetting::EmulationRunning, true); system->StartEmulation(); return true; } \ No newline at end of file diff --git a/src/nxemu-video/render_window.cpp b/src/nxemu-video/render_window.cpp index 3267e911..0d7e2672 100644 --- a/src/nxemu-video/render_window.cpp +++ b/src/nxemu-video/render_window.cpp @@ -4,6 +4,9 @@ #include #include #include +#include + +extern IModuleSettings * g_settings; class OpenGLSharedContext : public Core::Frontend::GraphicsContext { @@ -93,7 +96,8 @@ class DummyContext : public Core::Frontend::GraphicsContext }; RenderWindow::RenderWindow(IRenderWindow & renderWindow) : - m_renderWindow(renderWindow) + m_renderWindow(renderWindow), + m_firstFrame(false) { NotifyClientAreaSizeChanged({ 0,0 }); UpdateCurrentFramebufferLayout(640, 480); @@ -106,6 +110,11 @@ RenderWindow::RenderWindow(IRenderWindow & renderWindow) : void RenderWindow::OnFrameDisplayed() { + if (!m_firstFrame) + { + m_firstFrame = true; + g_settings->SetBool(NXCoreSetting::DisplayedFrames, true); + } } std::unique_ptr RenderWindow::CreateSharedContext() const diff --git a/src/nxemu-video/render_window.h b/src/nxemu-video/render_window.h index b912780b..1bc3bd33 100644 --- a/src/nxemu-video/render_window.h +++ b/src/nxemu-video/render_window.h @@ -19,4 +19,5 @@ private: void LoadOpenGL(); IRenderWindow & m_renderWindow; + bool m_firstFrame; }; \ No newline at end of file diff --git a/src/nxemu/main.cpp b/src/nxemu/main.cpp index c43a1838..8deb4785 100644 --- a/src/nxemu/main.cpp +++ b/src/nxemu/main.cpp @@ -29,7 +29,7 @@ int WINAPI WinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInsta if (Res) { RegisterWidgets(*sciterUI); - SciterMainWindow window(*sciterUI); + SciterMainWindow window(*sciterUI, stdstr_f("NXEmu %s", VER_FILE_VERSION_STR).c_str()); window.Show(); sciterUI->Run(); } diff --git a/src/nxemu/settings/ui_settings.cpp b/src/nxemu/settings/ui_settings.cpp index c06de8c6..e076a9f0 100644 --- a/src/nxemu/settings/ui_settings.cpp +++ b/src/nxemu/settings/ui_settings.cpp @@ -93,7 +93,14 @@ void SaveUISetting(void) { json["EnableModuleConfiguration"] = JsonValue(uiSettings.enableModuleConfiguration); } - + if (uiSettings.sciterUI != UISettingsDefaults::sciterUI) + { + json["SciterUI"] = JsonValue(uiSettings.sciterUI); + } + if (uiSettings.languageDirValue != UISettingsDefaults::defaultLanguageDirValue) + { + json["LanguageDirectory"] = JsonValue(uiSettings.languageDirValue); + } Settings & settings = Settings::GetInstance(); settings.SetSettings("UI", json); settings.Save(); diff --git a/src/nxemu/user_interface/main_window.cpp b/src/nxemu/user_interface/main_window.cpp index b2443587..19e47d9a 100644 --- a/src/nxemu/user_interface/main_window.cpp +++ b/src/nxemu/user_interface/main_window.cpp @@ -226,7 +226,7 @@ void * MainWindow::RenderSurface(void) const void MainWindow::GameNameChanged(void) { - std::string gameName = Settings::GetInstance().GetString("nxcore:GameName"); + std::string gameName = Settings::GetInstance().GetString(NXCoreSetting::GameName); if (gameName.length() > 0) { std::wstring Caption; diff --git a/src/nxemu/user_interface/sciter_main_window.cpp b/src/nxemu/user_interface/sciter_main_window.cpp index c896f7a6..63fe819a 100644 --- a/src/nxemu/user_interface/sciter_main_window.cpp +++ b/src/nxemu/user_interface/sciter_main_window.cpp @@ -1,16 +1,26 @@ #include "sciter_main_window.h" +#include "settings/settings_config.h" #include "settings/ui_settings.h" +#include #include +#include +#include #include #include #include #include -SciterMainWindow::SciterMainWindow(ISciterUI & SciterUI) : +SciterMainWindow::SciterMainWindow(ISciterUI & SciterUI, const char * windowTitle) : m_sciterUI(SciterUI), m_window(nullptr), - m_renderWindow(nullptr) + m_renderWindow(nullptr), + m_windowTitle(windowTitle) { + Settings & settings = Settings::GetInstance(); + settings.RegisterCallback(NXCoreSetting::GameFile, std::bind(&SciterMainWindow::GameFileChanged, this)); + settings.RegisterCallback(NXCoreSetting::GameName, std::bind(&SciterMainWindow::GameNameChanged, this)); + settings.RegisterCallback(NXCoreSetting::RomLoading, std::bind(&SciterMainWindow::RomLoadingChanged, this)); + settings.RegisterCallback(NXCoreSetting::DisplayedFrames, std::bind(&SciterMainWindow::DisplayedFramesChanged, this)); } void SciterMainWindow::ResetMenu() @@ -63,27 +73,113 @@ bool SciterMainWindow::Show(void) { return false; } - + SciterElement rootElement(m_window->GetRootElement()); m_window->OnDestroySinkAdd(this); m_window->CenterWindow(); - stdstr_f windowTitle("NxEmu - %s", VER_FILE_VERSION_STR); - SciterElement rootElement(m_window->GetRootElement()); - rootElement.Eval(stdstr_f("Window.this.caption = \"%s\";", windowTitle.c_str()).c_str()); - SciterElement caption(rootElement.FindFirst("[role='window-caption'] > span")); - if (caption.IsValid()) - { - caption.SetHTML((uint8_t *)windowTitle.data(), windowTitle.size()); - } + SetCaption(m_windowTitle); SciterElement menuElement(rootElement.GetElementByID("MainMenu")); void * interfacePtr = nullptr; if (menuElement.IsValid() && m_sciterUI.GetElementInterface(menuElement, IID_IMENUBAR, &interfacePtr)) { - m_menuBar = std::shared_ptr(reinterpret_cast(interfacePtr), [](IMenuBar *) {}); + m_menuBar = std::shared_ptr(reinterpret_cast(interfacePtr), [](IMenuBar*) {}); ResetMenu(); } + m_sciterUI.UpdateWindow(rootElement.GetElementHwnd(true)); + SciterElement::RECT rect = { 20, 20, 660, 500 }; + SciterElement mainContents(rootElement.GetElementByID("MainContents")); + if (mainContents.IsValid()) + { + rect = mainContents.GetLocation(); + } + + m_renderWindow = CreateWindowExW(0, L"Static", L"", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, + rect.left, rect.top, rect.right, rect.bottom, (HWND)m_window->GetHandle(), nullptr, GetModuleHandle(nullptr), nullptr); + ShowWindow((HWND)m_renderWindow, SW_HIDE); + return true; } +void SciterMainWindow::ShowLoadingScreen() +{ + SciterElement rootElement(m_window->GetRootElement()); + SciterElement mainContents(rootElement.GetElementByID("MainContents")); + if (mainContents.IsValid()) + { + m_sciterUI.SetElementHtmlFromResource(mainContents, "loading.html"); + } +} + +void SciterMainWindow::SetCaption(const std::string & caption) +{ + SciterElement rootElement(m_window->GetRootElement()); + rootElement.Eval(stdstr_f("Window.this.caption = \"%s\";", caption.c_str()).c_str()); + SciterElement captionElement(rootElement.FindFirst("[role='window-caption'] > span")); + if (captionElement.IsValid()) + { + captionElement.SetHTML((uint8_t*)caption.data(), caption.size()); + } +} + +void SciterMainWindow::GameFileChanged(void) +{ + enum + { + maxRememberedFiles = 10 + }; + + Stringlist& recentFiles = uiSettings.recentFiles; + std::string gameFile = Settings::GetInstance().GetString(NXCoreSetting::GameFile); + for (Stringlist::const_iterator itr = recentFiles.begin(); itr != recentFiles.end(); itr++) + { + if (_stricmp(gameFile.c_str(), itr->c_str()) != 0) + { + continue; + } + recentFiles.erase(itr); + break; + } + recentFiles.insert(recentFiles.begin(), gameFile); + if (recentFiles.size() > maxRememberedFiles) + { + recentFiles.resize(maxRememberedFiles); + } + ResetMenu(); + SaveUISetting(); +} + +void SciterMainWindow::GameNameChanged(void) +{ + std::string gameName = Settings::GetInstance().GetString(NXCoreSetting::GameName); + if (gameName.length() > 0) + { + std::string caption; + caption += gameName; + caption += " | "; + caption += m_windowTitle; + SetCaption(caption); + } +} + +void SciterMainWindow::RomLoadingChanged(void) +{ + bool loading = Settings::GetInstance().GetBool(NXCoreSetting::RomLoading); + if (loading) + { + ShowLoadingScreen(); + } +} + +void SciterMainWindow::DisplayedFramesChanged(void) +{ + SciterElement rootElement(m_window->GetRootElement()); + SciterElement mainContents(rootElement.GetElementByID("MainContents")); + if (mainContents.IsValid()) + { + mainContents.SetHTML((uint8_t*)"", 0, SciterElement::SIH_REPLACE_CONTENT); + } + ShowWindow((HWND)m_renderWindow, SW_SHOW); +} + void SciterMainWindow::OnOpenGame(void) { Path fileToOpen; @@ -101,10 +197,16 @@ void SciterMainWindow::OnFileExit(void) void SciterMainWindow::OnSettings(void) { + SettingConfig().Display((HWND)m_window->GetHandle()); } void SciterMainWindow::OnRecetGame(uint32_t fileIndex) { + Stringlist & recentFiles = uiSettings.recentFiles; + if (fileIndex < recentFiles.size()) + { + LaunchSwitchRom(*this, recentFiles[fileIndex].c_str()); + } } void SciterMainWindow::OnWindowDestroy(HWINDOW /*hWnd*/) @@ -112,7 +214,7 @@ void SciterMainWindow::OnWindowDestroy(HWINDOW /*hWnd*/) m_sciterUI.Stop(); } -void SciterMainWindow::OnMenuItem(int32_t id, SCITER_ELEMENT item) +void SciterMainWindow::OnMenuItem(int32_t id, SCITER_ELEMENT /*item*/) { switch (id) { diff --git a/src/nxemu/user_interface/sciter_main_window.h b/src/nxemu/user_interface/sciter_main_window.h index 981defe1..6f9e48b8 100644 --- a/src/nxemu/user_interface/sciter_main_window.h +++ b/src/nxemu/user_interface/sciter_main_window.h @@ -24,7 +24,7 @@ class SciterMainWindow : }; public: - SciterMainWindow(ISciterUI & SciterUI); + SciterMainWindow(ISciterUI & SciterUI, const char * windowTitle); void ResetMenu(); bool Show(void); @@ -34,6 +34,13 @@ private: SciterMainWindow(const SciterMainWindow &) = delete; SciterMainWindow & operator=(const SciterMainWindow &) = delete; + void SetCaption(const std::string& caption); + void GameFileChanged(void); + void GameNameChanged(void); + void RomLoadingChanged(void); + void DisplayedFramesChanged(void); + void ShowLoadingScreen(void); + void OnOpenGame(void); void OnFileExit(void); void OnSettings(void); @@ -52,4 +59,5 @@ private: ISciterWindow * m_window; std::shared_ptr m_menuBar; void * m_renderWindow; + std::string m_windowTitle; };