Create the rendering engine when game is starting

This commit is contained in:
N3xoX1 2025-08-25 10:16:40 +09:30
parent 10cc2e5763
commit 39710f2974
7 changed files with 123 additions and 39 deletions

View File

@ -221,14 +221,16 @@ hr
font-weight: 100;
}
#StatusBar #volume
#StatusBar #volume,
#StatusBar #renderer
{
border: 1px solid transparent;
padding: 0.2em;
display: inline-block;
}
#StatusBar #volume:hover
#StatusBar #volume:hover,
#StatusBar #renderer:hover
{
border: 1px solid #76797c;
}

View File

@ -13,7 +13,7 @@
</header>
<mainmenu id="MainMenu" />
<div id="MainContents" />
<div id="StatusBar" ><span id="volume" /></div>
<div id="StatusBar" ><span id="renderer" /><span id="volume" /></div>
</html>
<popup id="VolumePopup">
<div>

View File

@ -33,29 +33,34 @@ public:
{
return;
}
PIXELFORMATDESCRIPTOR pfd = {0};
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cAuxBuffers = 1;
int pfm = ChoosePixelFormat(m_hdc, &pfd);
int pfm = GetPixelFormat(m_hdc);
if (pfm == 0)
{
pfd.cAuxBuffers = 0;
pfm = ChoosePixelFormat(m_hdc, &pfd);
}
if (pfm == 0)
{
return;
}
if (SetPixelFormat(m_hdc, pfm, &pfd) == 0)
{
return;
PIXELFORMATDESCRIPTOR pfd = { 0 };
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cAuxBuffers = 1;
int pfm = ChoosePixelFormat(m_hdc, &pfd);
if (pfm == 0)
{
pfd.cAuxBuffers = 0;
pfm = ChoosePixelFormat(m_hdc, &pfd);
}
if (pfm == 0)
{
return;
}
if (SetPixelFormat(m_hdc, pfm, &pfd) == 0)
{
return;
}
}
m_glrc = wglCreateContext(m_hdc);

View File

@ -43,6 +43,16 @@ VideoManager::~VideoManager()
void VideoManager::EmulationStarting(void)
{
Layout::FramebufferLayout layout;
if (impl->m_emuWindow)
{
layout = impl->m_emuWindow->GetFramebufferLayout();
}
impl->m_emuWindow = nullptr;
impl->m_emuWindow = std::make_unique<RenderWindow>(impl->m_window);
impl->m_emuWindow->UpdateCurrentFramebufferLayout(layout.width, layout.height);
impl->m_gpuCore = nullptr;
impl->m_gpuCore = VideoCore::CreateGPU(impl->m_system, *(impl->m_emuWindow.get()), *impl->m_host1x);
impl->m_gpuCore->Start();
}

View File

@ -24,7 +24,7 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)external\vulkan-headers\include;$(SolutionDir)external\sciterui\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)external\fmt\include;$(SolutionDir)external\vulkan-headers\include;$(SolutionDir)external\sciterui\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<UseStandardPreprocessor>true</UseStandardPreprocessor>
</ClCompile>
<PreBuildEvent>
@ -52,7 +52,7 @@
<ClInclude Include="settings\ui_settings.h" />
<ClInclude Include="settings\ui_settings_identifiers.h" />
<ClInclude Include="startup_checks.h" />
<ClInclude Include="user_interface\notification.h" />
<ClInclude Include="user_interface\notification.h" />
<ClInclude Include="user_interface\resource.h" />
<ClInclude Include="user_interface\sciter_main_window.h" />
<ClInclude Include="user_interface\settings\config_setting.h" />

View File

@ -2,16 +2,19 @@
#include "settings/input_config.h"
#include "settings/system_config.h"
#include "settings/ui_settings.h"
#include <Windows.h>
#include <common/std_string.h>
#include <nxemu-core/machine/switch_system.h>
#include <nxemu-core/settings/identifiers.h>
#include <nxemu-core/settings/settings.h>
#include <nxemu-core/version.h>
#include <nxemu-os/os_settings_identifiers.h>
#include <nxemu-video/video_settings_identifiers.h>
#include <sciter_element.h>
#include <widgets/menubar.h>
#include <yuzu_common/settings_input.h>
#include <yuzu_common/settings.h>
#include <Windows.h>
SciterMainWindow::SciterMainWindow(ISciterUI & sciterUI, const char * windowTitle) :
m_sciterUI(sciterUI),
@ -22,6 +25,7 @@ SciterMainWindow::SciterMainWindow(ISciterUI & sciterUI, const char * windowTitl
m_volumePopup(false)
{
SettingsStore & settings = SettingsStore::GetInstance();
settings.RegisterCallback(NXCoreSetting::EmulationRunning, SciterMainWindow::EmulationRunning, this);
settings.RegisterCallback(NXCoreSetting::GameFile, SciterMainWindow::GameFileChanged, this);
settings.RegisterCallback(NXCoreSetting::GameName, SciterMainWindow::GameNameChanged, this);
settings.RegisterCallback(NXCoreSetting::RomLoading, SciterMainWindow::RomLoadingChanged, this);
@ -101,21 +105,12 @@ bool SciterMainWindow::Show(void)
rect = mainContents.GetLocation();
}
uint32_t width = rect.right - rect.left;
uint32_t height = rect.bottom - rect.top;
m_renderWindow = CreateWindowExW(0, L"Static", L"", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
rect.left, rect.top, width, height, (HWND)m_window->GetHandle(), nullptr, GetModuleHandle(nullptr), nullptr);
ShowWindow((HWND)m_renderWindow, SW_HIDE);
CreateRenderWindow();
SwitchSystem::Create(*this);
SwitchSystem* system = SwitchSystem::GetInstance();
if (system != nullptr)
{
IVideo & video = system->Video();
video.UpdateFramebufferLayout(rect.right - rect.left, rect.bottom - rect.top);
}
UpdateStatusbar();
m_sciterUI.AttachHandler(rootElement, IID_IMOUSEUPDOWNSINK, (IMouseUpDownSink*)this);
m_sciterUI.AttachHandler(rootElement.GetElementByID("renderer"), IID_ICLICKSINK, (IClickSink*)this);
m_sciterUI.AttachHandler(rootElement.GetElementByID("volume"), IID_ICLICKSINK, (IClickSink*)this);
m_sciterUI.AttachHandler(rootElement.GetElementByID("audioVolume"), IID_ISTATECHANGESINK, (IStateChangeSink*)this);
@ -300,8 +295,12 @@ void SciterMainWindow::UpdateStatusbar()
{
SettingsStore & settings = SettingsStore::GetInstance();
SciterElement rootElement(m_window->GetRootElement());
SciterElement renderer(rootElement.GetElementByID("renderer"));
stdstr_f text("%s", Settings::CanonicalizeEnum((Settings::RendererBackend)settings.GetInt(NXVideoSetting::GraphicsAPI)).c_str());
renderer.SetHTML((const uint8_t*)text.c_str(), text.size());
SciterElement volume(rootElement.GetElementByID("volume"));
stdstr_f text("VOLUME: %d %%", settings.GetInt(NXOsSetting::AudioVolume));
text.Format("VOLUME: %d %%", settings.GetInt(NXOsSetting::AudioVolume));
volume.SetHTML((const uint8_t *)text.c_str(), text.size());
}
@ -326,6 +325,25 @@ void SciterMainWindow::DismissvolumePopup(SCITER_ELEMENT source, int32_t x, int3
m_volumePopup = false;
}
void SciterMainWindow::CreateRenderWindow(void)
{
SciterElement rootElement(m_window->GetRootElement());
SciterElement mainContents(rootElement.GetElementByID("MainContents"));
SciterElement::RECT rect = mainContents.GetLocation();
uint32_t width = rect.right - rect.left;
uint32_t height = rect.bottom - rect.top;
m_renderWindow = CreateWindowExW(0, L"Static", L"", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
rect.left, rect.top, width, height, (HWND)m_window->GetHandle(), nullptr, GetModuleHandle(nullptr), nullptr);
ShowWindow((HWND)m_renderWindow, SW_HIDE);
SwitchSystem * system = SwitchSystem::GetInstance();
if (system != nullptr)
{
IVideo & video = system->Video();
video.UpdateFramebufferLayout(rect.right - rect.left, rect.bottom - rect.top);
}
}
void SciterMainWindow::SetCaption(const std::string & caption)
{
SciterElement rootElement(m_window->GetRootElement());
@ -337,6 +355,27 @@ void SciterMainWindow::SetCaption(const std::string & caption)
}
}
void SciterMainWindow::EmulationRunning(const char * /*setting*/, void * userData)
{
bool emulationRunning = SettingsStore::GetInstance().GetBool(NXCoreSetting::EmulationRunning);
SciterMainWindow * impl = (SciterMainWindow*)userData;
if (emulationRunning)
{
if (impl->m_renderWindow != nullptr)
{
DestroyWindow((HWND)impl->m_renderWindow);
impl->m_renderWindow = nullptr;
}
impl->CreateRenderWindow();
}
SciterElement rootElement(impl->m_window->GetRootElement());
SciterElement renderer(rootElement.GetElementByID("renderer"));
if (renderer)
{
renderer.SetState(emulationRunning ? SciterElement::STATE_DISABLED : 0, emulationRunning ? 0 : SciterElement::STATE_DISABLED, true);
}
}
void SciterMainWindow::GameFileChanged(const char * /*setting*/, void * userData)
{
SciterMainWindow * impl = (SciterMainWindow *)userData;
@ -533,7 +572,28 @@ bool SciterMainWindow::OnSizeChanged(SCITER_ELEMENT elem)
bool SciterMainWindow::OnClick(SCITER_ELEMENT /*element*/, SCITER_ELEMENT source, uint32_t /*reason*/)
{
SciterElement rootElement(m_window->GetRootElement());
if (source == rootElement.GetElementByID("volume"))
if (source == rootElement.GetElementByID("renderer"))
{
SettingsStore & settings = SettingsStore::GetInstance();
Settings::RendererBackend graphicsAPI = (Settings::RendererBackend)settings.GetInt(NXVideoSetting::GraphicsAPI);
if (graphicsAPI == Settings::RendererBackend::Vulkan)
{
graphicsAPI = Settings::RendererBackend::OpenGL;
}
else if (graphicsAPI == Settings::RendererBackend::OpenGL)
{
graphicsAPI = Settings::RendererBackend::Vulkan;
}
settings.SetInt(NXVideoSetting::GraphicsAPI, (int32_t)graphicsAPI);
stdstr_f text("%s", Settings::CanonicalizeEnum((Settings::RendererBackend)settings.GetInt(NXVideoSetting::GraphicsAPI)).c_str());
SciterElement(source).SetHTML((const uint8_t*)text.c_str(), text.size());
SwitchSystem * system = SwitchSystem::GetInstance();
if (system != nullptr)
{
system->FlushSettings();
}
}
else if (source == rootElement.GetElementByID("volume"))
{
m_sciterUI.PopupShow(rootElement.GetElementByID("VolumePopup"), rootElement.GetElementByID("volume"), 8);
m_volumePopup = true;
@ -563,6 +623,11 @@ bool SciterMainWindow::OnStateChange(SCITER_ELEMENT elem, uint32_t /*eventReason
{
SettingsStore& settings = SettingsStore::GetInstance();
settings.SetInt(NXOsSetting::AudioVolume, value.GetValueInt());
SwitchSystem * system = SwitchSystem::GetInstance();
if (system != nullptr)
{
system->FlushSettings();
}
}
}
return false;

View File

@ -47,7 +47,9 @@ private:
SciterMainWindow(const SciterMainWindow &) = delete;
SciterMainWindow & operator=(const SciterMainWindow &) = delete;
void CreateRenderWindow(void);
void SetCaption(const std::string & caption);
static void EmulationRunning(const char * setting, void * userData);
static void GameFileChanged(const char * setting, void * userData);
static void GameNameChanged(const char * setting, void * userData);
static void RomLoadingChanged(const char * setting, void * userData);