feat: added XBNotif to D3D11x via wd::common::GUI

This commit is contained in:
CT5
2026-02-09 18:59:24 +11:00
parent 0bd49b15bb
commit c1fee9fb79
15 changed files with 1415 additions and 5 deletions

View File

@@ -6,6 +6,16 @@ include(FetchContent)
set(VERSION_SUFFIX "-dev.5") # used for non-stable versions, otherwise blank
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
FetchContent_Declare(
imgui
GIT_REPOSITORY https://github.com/ocornut/imgui.git
GIT_TAG docking
)
FetchContent_MakeAvailable(imgui)
add_compile_definitions(WD_API_EXPORTS)
set(FILES
@@ -17,6 +27,13 @@ set(FILES
src/WinDurango.cpp
src/Config.cpp
src/Logging.cpp
src/GUI.cpp
thirdparty/imgui_impl_uwp.cpp
${imgui_SOURCE_DIR}/imgui.cpp
${imgui_SOURCE_DIR}/imgui_draw.cpp
${imgui_SOURCE_DIR}/imgui_tables.cpp
${imgui_SOURCE_DIR}/imgui_widgets.cpp
${imgui_SOURCE_DIR}/backends/imgui_impl_dx11.cpp
)
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz)
@@ -29,6 +46,8 @@ add_library(WinDurango.Common SHARED ${FILES})
target_include_directories(WinDurango.Common PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.Common/>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/thirdparty>
${imgui_SOURCE_DIR}
)
target_link_libraries(WinDurango.Common PUBLIC nlohmann_json::nlohmann_json spdlog::spdlog)

View File

@@ -1,14 +1,20 @@
#pragma once
#include <d3d11.h>
#include <dxgi1_2.h>
namespace wd::common
{
class GUI
{
public:
void Initialize();
void Initialize(ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain1* pSwapchain);
void Render();
private:
void XBNotif(const char* notif_text = "Game Ready", const char* icon = "\xEE\x9F\xBC", const char* bottom_tip = "Hold \xEE\xBB\x8A to Launch");
ID3D11Device* m_pDevice = nullptr;
ID3D11DeviceContext* m_pContext = nullptr;
IDXGISwapChain1* m_pSwapchain = nullptr;
ID3D11RenderTargetView* m_pRenderTargetView;
};
}

View File

@@ -7,6 +7,7 @@
#include "Interfaces/Storage/Directory.h"
#include "Logging.h"
#include "exports.h"
#include "GUI.h"
#include <ctime>
namespace wd::common
@@ -24,6 +25,7 @@ namespace wd::common
Config config;
Logging log;
std::shared_ptr<interfaces::storage::Directory> rootDir;
GUI gui;
private:
bool _inited = false;

View File

@@ -0,0 +1,124 @@
#include <backends/imgui_impl_dx11.h>
#include <imgui_impl_uwp.h>
#include <imgui.h>
#include "GUI.h"
namespace wd::common
{
void GUI::Initialize(ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain1* pSwapchain)
{
m_pDevice = pDevice;
m_pContext = pContext;
m_pSwapchain = pSwapchain;
ID3D11Texture2D* pBackBuffer = nullptr;
m_pSwapchain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
m_pDevice->CreateRenderTargetView(pBackBuffer, nullptr, &m_pRenderTargetView);
if (pBackBuffer) pBackBuffer->Release();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.IniFilename = "imgui.ini";
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
ImFont* mainFont = io.Fonts->AddFontFromFileTTF("C:/Windows/Fonts/Bahnschrift.ttf", 18.0f);
ImFontConfig config;
config.MergeMode = true;
config.GlyphOffset.y = 4.0f;
static const ImWchar icon_ranges[] = { 0xE7FC, 0xF11B, 0 };
static const ImWchar icon_ranges2[] = { 0xE782, 0xE782, 0 };
static const ImWchar icon_ranges3[] = { 0xE2AF, 0xE2AF, 0 };
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segmdl2.ttf", 18.0f, &config, icon_ranges);
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segmdl2.ttf", 30.0f, &config, icon_ranges3);
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\holomdl2.ttf", 30.0f, &config, icon_ranges2);
io.Fonts->Build( );
ImGui_ImplUwp_InitForCurrentView();
ImGui_ImplDX11_Init(m_pDevice, m_pContext);
}
void GUI::Render()
{
ImGui_ImplDX11_NewFrame();
ImGui_ImplUwp_NewFrame();
ImGui::NewFrame();
XBNotif();
ImGui::Render();
m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, nullptr);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
}
void GUI::XBNotif(const char* notif_text, const char* icon, const char* bottom_tip)
{
ImVec4 tipColor = ImVec4(64.0f/255.0f, 158.0f/255.0f, 254.0f/255.0f, 1.0f);
ImVec4 color = ImVec4(38/255.0f, 145/255.0f, 253/255.0f, 1.0f);
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoDecoration;
ImGuiViewport* vp = ImGui::GetMainViewport();
ImVec2 windowPos;
windowPos.x = vp->Pos.x + (vp->Size.x - 370) * 0.5f;
windowPos.y = vp->Pos.y + vp->Size.y - 60 - 60;
ImGui::SetNextWindowPos(windowPos);
ImGui::PushStyleColor(ImGuiCol_WindowBg, tipColor);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12, 12));
ImGui::SetNextWindowSize(ImVec2(370, 60));
ImGui::Begin("NotificationTip", nullptr, flags);
ImVec2 pos = ImGui::GetWindowPos();
ImVec2 p = ImGui::GetCursorScreenPos();
float size = 38.0f;
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddRectFilled(p, ImVec2(p.x + size, p.y + size), IM_COL32(31, 73, 117, 255));
const char* text = icon;
ImVec2 text_size = ImGui::CalcTextSize(text);
ImVec2 text_pos = ImVec2(
p.x + (size - text_size.x) / 2,
p.y + (size - text_size.y) / 2
);
draw_list->AddText(text_pos, IM_COL32(255, 255, 255, 255), text);
ImVec2 notif_pos = ImVec2(
text_pos.x + 40,
text_pos.y
);
draw_list->AddText(notif_pos, IM_COL32(255, 255, 255, 255), notif_text);
ImGui::End();
ImGui::PopStyleColor();
ImGui::PopStyleVar(3);
float windowEndY = pos.y + 50;
ImGui::SetNextWindowPos({pos.x, windowEndY});
ImGui::PushStyleColor(ImGuiCol_WindowBg, color);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(15, 15));
ImGui::SetNextWindowSize(ImVec2(370, 40));
ImGui::Begin("Notification", nullptr, flags);
ImGui::Text(bottom_tip);
ImGui::End();
ImGui::PopStyleColor();
ImGui::PopStyleVar(3);
}
}

View File

@@ -3,6 +3,8 @@
//
#include "WinDurango.Common/WinDurango.h"
#undef CreateFile
namespace wd::common
{
std::shared_ptr<WinDurango> WinDurango::GetInstance()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
// dear imgui: Platform Backend for Universal Windows Platform
// This needs to be used along with a Renderer (e.g. DirectX11, DirectX12, SDL2..)
// Implemented features:
// [X] Platform: Clipboard support (for Win32 & UWP this is actually part of core dear imgui)
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Configs:
// #define IMGUI_DISABLE_UWP_DEFAULT_CLIPBOARD_FUNCTIONS // Don't implement default WinRT clipboard handler.
// #define IMGUI_IMPL_UWP_DISABLE_GAMEPAD // Don't implement default XInput gamepad handler.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
IMGUI_IMPL_API bool ImGui_ImplUwp_Init(void* core_window); // ABI::Windows::UI::Core::ICoreWindow*
IMGUI_IMPL_API bool ImGui_ImplUwp_InitForCurrentView();
IMGUI_IMPL_API bool ImGui_ImplUwp_InitForSwapChainPanel(void* swapchain_panel); // ABI::Windows::UI::Xaml::Controls::ISwapChainPanel*
IMGUI_IMPL_API void ImGui_ImplUwp_Shutdown();
IMGUI_IMPL_API void ImGui_ImplUwp_NewFrame();

View File

@@ -4,7 +4,7 @@ project(WinDurango.D3D11X VERSION 1.0.0)
set(VERSION_SUFFIX "-dev.1") # used for non-stable versions, otherwise blank
set(CMAKE_CXX_STANDARD 20)
find_package(directxtex CONFIG REQUIRED HINTS "${CMAKE_SOURCE_DIR}/../../vcpkg_installed/vcpkg/pkgs/directxtex_x64-windows/share/directxtex")
find_package(directxtex CONFIG REQUIRED HINTS "${CMAKE_SOURCE_DIR}/vcpkg_installed/vcpkg/pkgs/directxtex_x64-windows/share/directxtex")
set(FILES
src/d3d11.x.cpp

View File

@@ -13,6 +13,9 @@
#include <algorithm>
#include <cstdint>
#include <DirectXTex.h>
#include "WinDurango.Common/WinDurango.h"
extern std::shared_ptr<wd::common::WinDurango> p_wd;
// We use that to know the OS version.
abi_t g_ABI{};

View File

@@ -7,6 +7,7 @@
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/windows.storage.provider.h>
#include "ID3D11Runtime.h"
#include "d3d11.x.h"
//
// IUnknown
@@ -208,6 +209,15 @@ HRESULT DXGIFactory2<ABI>::CreateSwapChainForCoreWindow(xbox::IGraphicsUnknown<A
IDXGISwapChain1 *SwapChain{};
hr = m_pFunction->CreateSwapChainForHwnd(dev, hwnd, &pDesc2, NULL, NULL, &SwapChain);
auto* realDevice = static_cast<D3D11DeviceX<ABI>*>(pDevice);
gfx::ID3D11DeviceContext<ABI>* ctx = nullptr;
realDevice->GetImmediateContext(&ctx);
ID3D11DeviceContext* dxCtx = nullptr;
hr = ctx->QueryInterface(__uuidof(ID3D11DeviceContext), reinterpret_cast<void**>(&dxCtx));
ctx->Release();
p_wd->gui.Initialize(realDevice->m_pFunction, dxCtx, SwapChain);
if (SwapChain)
{
*ppSwapChain = new DXGISwapChain1<ABI>(SwapChain);

View File

@@ -1,4 +1,5 @@
#include "IDXGISwapChain.h"
#include "d3d11.x.h"
//
// IUnknown
@@ -72,6 +73,7 @@ template <abi_t ABI> HRESULT DXGISwapChain1<ABI>::GetDevice(REFIID riid, void **
//
template <abi_t ABI> HRESULT DXGISwapChain1<ABI>::Present(uint32_t SyncInterval, uint32_t Flags)
{
p_wd->gui.Render();
return m_pFunction->Present(SyncInterval, Flags);
}
@@ -182,9 +184,9 @@ HRESULT DXGISwapChain1<ABI>::Present1(uint32_t SyncInterval, uint32_t PresentFla
DXGI_PRESENT_PARAMETERS const *pPresentParameters)
{
if (!pPresentParameters)
return Present(SyncInterval, PresentFlags);
return m_pFunction->Present(SyncInterval, PresentFlags);
else
return Present1(SyncInterval, PresentFlags, pPresentParameters);
return m_pFunction->Present1(SyncInterval, PresentFlags, pPresentParameters);
}
template <abi_t ABI> bool DXGISwapChain1<ABI>::IsTemporaryMonoSupported()

View File

@@ -1,9 +1,12 @@
#include "d3d11.x.h"
std::shared_ptr<wd::common::WinDurango> p_wd;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved) // reserved
{
GetCombaseVersion();
p_wd = wd::common::WinDurango::GetInstance();
return TRUE;
}

View File

@@ -68,6 +68,7 @@ set(FILES
"src/Windows/Xbox/Storage/Windows.Xbox.Storage.ConnectedStorageContainer.cpp"
"src/Windows/Xbox/Storage/Windows.Xbox.Storage.ConnectedStorageSpace.cpp"
"src/Windows/Xbox/Storage/Windows.Xbox.Storage.ContainerInfoQueryResult.cpp"
"src/Windows/Xbox/Services/Windows.Xbox.Services.XboxLiveConfiguration.cpp"
"src/WinDurangoWinRT.cpp"
)
@@ -90,6 +91,7 @@ target_include_directories(WinDurango.WinRT PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.WinRT/Windows/Xbox/ApplicationModel/Store"
"${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.WinRT/Windows/Xbox/Multiplayer"
"${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.WinRT/Windows/Xbox/Storage"
"${CMAKE_CURRENT_SOURCE_DIR}/include/WinDurango.WinRT/Windows/Xbox/Services"
"${CMAKE_CURRENT_SOURCE_DIR}/Generated Files"
"${CMAKE_SOURCE_DIR}/projects/WinDurango.Common/include"
)

View File

@@ -0,0 +1,20 @@
#pragma once
#include "Windows.Xbox.Services.XboxLiveConfiguration.g.h"
namespace winrt::Windows::Xbox::Services::implementation
{
struct XboxLiveConfiguration : XboxLiveConfigurationT<XboxLiveConfiguration>
{
XboxLiveConfiguration() = default;
static hstring TitleId();
static hstring PrimaryServiceConfigId();
static hstring SandboxId();
};
}
namespace winrt::Windows::Xbox::Services::factory_implementation
{
struct XboxLiveConfiguration : XboxLiveConfigurationT<XboxLiveConfiguration, implementation::XboxLiveConfiguration>
{
};
}

View File

@@ -0,0 +1,21 @@
#include "Windows.Xbox.Services.XboxLiveConfiguration.h"
#include "WinDurangoWinRT.h"
namespace winrt::Windows::Xbox::Services::implementation
{
hstring XboxLiveConfiguration::TitleId()
{
p_wd->log.Warn("WinDurango::WinRT::Windows::Xbox::Services", "Unimplemented: TitleId");
throw hresult_not_implemented();
}
hstring XboxLiveConfiguration::PrimaryServiceConfigId()
{
p_wd->log.Warn("WinDurango::WinRT::Windows::Xbox::Services", "Unimplemented: PrimaryServiceConfigId");
throw hresult_not_implemented();
}
hstring XboxLiveConfiguration::SandboxId()
{
p_wd->log.Warn("WinDurango::WinRT::Windows::Xbox::Services", "Unimplemented: SandboxId");
throw hresult_not_implemented();
}
}