diff --git a/dlls/d3d11_x/overlay/overlay.cpp b/dlls/d3d11_x/overlay/overlay.cpp index f939640..b4ae4be 100644 --- a/dlls/d3d11_x/overlay/overlay.cpp +++ b/dlls/d3d11_x/overlay/overlay.cpp @@ -1,4 +1,4 @@ -/* +/* ================================================================================ DISCLAIMER AND LICENSE REQUIREMENT @@ -17,7 +17,7 @@ If you do not agree to these terms, you do not have permission to use this code. ================================================================================ */ #include "overlay.h" - +#define IMGUI_USE_WCHAR32 #include "../../../thirdparty/imgui/imgui.h" #include "../../../thirdparty/imgui/backends/imgui_impl_dx11.h" #include "../../../thirdparty/imgui_impl_uwp.h" @@ -66,8 +66,16 @@ void wd::Overlay::Initialize() io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; - io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); - ImGui::StyleColorsDark(); + ImFont* mainFont = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 18.0f); + + ImFontConfig config; + config.MergeMode = true; + + static const ImWchar icon_ranges[] = { 0xE000, 0xF8FF, 0 }; + io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\segmdl2.ttf", 25.0f, &config, icon_ranges); + + io.Fonts->Build( ); + ImGui::StyleColorsDark( ); ImGui_ImplUwp_InitForCurrentView(); ImGui_ImplDX11_Init(m_pDevice, m_pContext); @@ -198,7 +206,6 @@ void wd::Overlay::UpdateXInput() #undef GAMEPAD_KEY - // Left analog stick as analog navigation const float deadzone = static_cast(XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); const float maxValue = 32767.0f; @@ -239,16 +246,17 @@ void wd::Overlay::Present() ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); } -void wd::Overlay::RenderKeyboardWindow() +static int cursorPos = 0; +void wd::Overlay::RenderKeyboardWindow( ) { static bool isUppercase = false; static bool isSymbols = false; const char* keys[] = { - "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", - "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", - "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", - "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/" + "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", + "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", + "A", "S", "D", "F", "G", "H", "J", "K", "L", "'", + "Z", "X", "C", "V", "B", "N", "M", ",", ".", "?" }; const char* symbols[] = { @@ -259,35 +267,255 @@ void wd::Overlay::RenderKeyboardWindow() const char** currentKeys = isSymbols ? symbols : keys; - ImGuiIO& io = ImGui::GetIO(); - ImGui::SetNextWindowSize(ImVec2(500, 330)); - ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); - ImGui::Begin("WinDurango Keyboard", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse); + ImGuiIO& io = ImGui::GetIO( ); + ImVec2 displaySize = ImGui::GetIO( ).DisplaySize; - ImGui::InputText(" ", g_KeyboardText, IM_ARRAYSIZE(g_KeyboardText)); + ImGui::SetNextWindowPos(ImVec2(displaySize.x / 2, displaySize.y / 2), ImGuiCond_Always); - if (ImGui::Button(isUppercase ? "Lowercase" : "Uppercase")) - isUppercase = !isUppercase; - ImGui::SameLine(); - if (ImGui::Button(isSymbols ? "Letters" : "Symbols")) + ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar; + + ImGui::PushStyleColor(ImGuiCol_WindowBg, IM_COL32(0x05, 0x05, 0x05, 0xFF)); + ImGui::Begin("Keyboard", nullptr, windowFlags); + + ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0x37, 0x37, 0x37, 0xFF)); + ImGui::PushItemWidth(-FLT_MIN); + ImGui::PushStyleColor(ImGuiCol_FrameBg, IM_COL32(0x05, 0x05, 0x05, 0xFF)); + ImGui::InputText("", g_KeyboardText, IM_ARRAYSIZE(g_KeyboardText), ImGuiInputTextFlags_CallbackAlways, + [](ImGuiInputTextCallbackData* data) -> int { + data->CursorPos = cursorPos; + return 0; + }); + ImGui::PopStyleColor( ); + ImGui::PopItemWidth( ); + + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3)); + + if (ImGui::Button("##symb", ImVec2(60, 30))) isSymbols = !isSymbols; - ImGui::NewLine(); - RenderKeyboardRow(currentKeys, 0, 12, isUppercase); - RenderKeyboardRow(currentKeys, 12, 24, isUppercase); - if (!isSymbols) RenderKeyboardRow(currentKeys, 24, 35, isUppercase); - else RenderKeyboardRow(currentKeys, 24, 32, isUppercase); - if (!isSymbols) RenderKeyboardRow(currentKeys, 35, 44, isUppercase); + ImVec2 pos = ImGui::GetItemRectMin( ); + ImVec2 size = ImGui::GetItemRectSize( ); - ImGui::NewLine(); - HandleKeyboardSpecialKeys(); + if (!isSymbols) { + ImVec2 textSize = ImGui::CalcTextSize("#+="); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), ImGui::GetFontSize( ), + ImVec2((pos.x + (size.x - textSize.x) * 0.5f) - 10, pos.y + (size.y - textSize.y) * 0.5f), + IM_COL32(255, 255, 255, 255), + "#+=" + ); + } + else { + ImVec2 textSize = ImGui::CalcTextSize("ABC"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), ImGui::GetFontSize( ), + ImVec2((pos.x + (size.x - textSize.x) * 0.5f) - 10, pos.y + (size.y - textSize.y) * 0.5f), + IM_COL32(255, 255, 255, 255), + "ABC" + ); + } - ImGui::End(); + ImVec2 iconSize = ImGui::CalcTextSize("\xEF\x84\x8A"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 12, + ImVec2((pos.x + (size.x - iconSize.x) * 0.5f) + 18, (pos.y + (size.y - iconSize.y) * 0.5f) + 8), + IM_COL32(255, 255, 255, 255), + "\xEF\x84\x8A" + ); + + ImGui::SameLine( ); + RenderKeyboardRow(currentKeys, 0, 10, isUppercase); + + ImGui::PopStyleVar( ); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 3)); + ImGui::SameLine( ); + if (ImGui::Button("##del", ImVec2(60, 30)) || + ImGui::IsKeyPressed(ImGuiKey_Backspace) || + ImGui::IsKeyPressed(ImGuiKey_GamepadFaceLeft)) { + size_t len = strlen(g_KeyboardText); + if (len > 0) { + g_KeyboardText[ len - 1 ] = '\0'; + cursorPos = max(0, cursorPos - 1); + } + } + ImVec2 posa = ImGui::GetItemRectMin( ); + ImVec2 sizea = ImGui::GetItemRectSize( ); + + ImVec2 textSizea = ImGui::CalcTextSize("\xEE\x9D\x90"); + + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), + 14, + ImVec2((posa.x + (sizea.x - textSizea.x) * 0.5f) - 6, (posa.y + (sizea.y - textSizea.y) * 0.5f) + 7), + IM_COL32(255, 255, 255, 255), + "\xEE\x9D\x90" + ); + + textSizea = ImGui::CalcTextSize("\xEF\x82\x96"); + + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), + 10, + ImVec2((posa.x + (sizea.x - textSizea.x) * 0.5f) + 18, (posa.y + (sizea.y - textSizea.y) * 0.5f) + 8), + IM_COL32(0, 149, 209, 255), + "\xEF\x82\x96" + ); + ImGui::PopStyleVar( ); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3)); + + if (ImGui::Button("##bac", ImVec2(60.0f, 63)) || + ImGui::IsKeyPressed(ImGuiKey_LeftShift) || + ImGui::IsKeyPressed(ImGuiKey_GamepadL1)) + cursorPos = max(0, cursorPos - 1); + + pos = ImGui::GetItemRectMin( ); + size = ImGui::GetItemRectSize( ); + + ImFont* bigFont = ImGui::GetFont( ); + float bigFontSize = 18.0f; + ImVec2 bigTextSize = ImGui::CalcTextSize("\xEE\xA5\xAF"); + ImGui::GetWindowDrawList( )->AddText( + bigFont, bigFontSize, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 3, pos.y + 18), + IM_COL32(255, 255, 255, 255), + "\xEE\x80\x8E" + ); + + ImFont* smallFont = bigFont; + float smallFontSize = 14.0f; + ImVec2 smallTextSize = ImGui::CalcTextSize("\xEF\x84\x8C"); + ImGui::GetWindowDrawList( )->AddText( + smallFont, smallFontSize, + ImVec2(pos.x + (size.x - smallTextSize.x) * 0.5f, pos.y + 26 + bigTextSize.y), + IM_COL32(255, 255, 255, 255), + "\xEF\x84\x8C" + ); + + ImGui::SameLine( ); + ImVec2 currPos = ImGui::GetCursorPos( ); + RenderKeyboardRow(currentKeys, 10, 20, isUppercase); + + ImGui::PopStyleVar( ); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 3)); + ImGui::SameLine( ); + ImGui::SetWindowFontScale(1.5f); + if (ImGui::Button("##for", ImVec2(60.0f, 63))) + cursorPos++; + + pos = ImGui::GetItemRectMin( ); + size = ImGui::GetItemRectSize( ); + + bigTextSize = ImGui::CalcTextSize("\xEE\x80\x8F"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 18, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) + 6, pos.y + 18), + IM_COL32(255, 255, 255, 255), + "\xEE\x80\x8F" + ); + + smallTextSize = ImGui::CalcTextSize("\xEF\x84\x8D"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 14, + ImVec2((pos.x + (size.x - smallTextSize.x) * 0.5f) + 8, pos.y + 20 + bigTextSize.y), + IM_COL32(255, 255, 255, 255), + "\xEF\x84\x8D" + ); + ImGui::SetWindowFontScale(1.0f); + + ImGui::PopStyleVar( ); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(3, 3)); + + ImVec2 row2Pos = ImGui::GetCursorPos( ); + row2Pos.x = currPos.x; + row2Pos.y -= 33; + ImGui::SetCursorPos(row2Pos); + if (!isSymbols) RenderKeyboardRow(currentKeys, 20, 30, isUppercase); + else RenderKeyboardRow(currentKeys, 20, 30, isUppercase); + + if (ImGui::Button("##upper", ImVec2(60.0f, 63))) + isUppercase = !isUppercase; + + pos = ImGui::GetItemRectMin( ); + size = ImGui::GetItemRectSize( ); + + if (!isUppercase) { + bigTextSize = ImGui::CalcTextSize("\xEE\x9D\x92"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 18, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 3, pos.y + 18), + IM_COL32(255, 255, 255, 255), + "\xEE\x9D\x92" + ); + } + else { + bigTextSize = ImGui::CalcTextSize("\xEE\xA2\x96"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 18, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 3, pos.y + 18), + IM_COL32(255, 255, 255, 255), + "\xEE\xA2\x96" + ); + } + + smallTextSize = ImGui::CalcTextSize("\xEF\x84\x88"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 14, + ImVec2(pos.x + (size.x - smallTextSize.x) * 0.5f, pos.y + 26 + bigTextSize.y), + IM_COL32(255, 255, 255, 255), + "\xEF\x84\x88" + ); + + ImGui::SameLine( ); + currPos = ImGui::GetCursorPos( ); + if (!isSymbols) RenderKeyboardRow(currentKeys, 30, 40, isUppercase); + + ImGui::PopStyleVar( ); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 3)); + ImGui::SameLine( ); + if (ImGui::Button("##enter", ImVec2(60.0f, 63)) || + ImGui::IsKeyPressed(ImGuiKey_Enter) || + ImGui::IsKeyPressed(ImGuiKey_GamepadStart)) { + m_bKeyboard = false; + SetEvent(g_KeyboardFinished); + cursorPos = 0; + } + pos = ImGui::GetItemRectMin( ); + size = ImGui::GetItemRectSize( ); + + bigTextSize = ImGui::CalcTextSize("\xEE\xAF\xA7"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 18, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) + 2, pos.y + 18), + IM_COL32(255, 255, 255, 255), + "\xEE\xAF\xA7" + ); + + smallTextSize = ImGui::CalcTextSize("\xEE\xB7\xA3"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 12, + ImVec2((pos.x + (size.x - smallTextSize.x) * 0.5f) + 5, pos.y + 26 + bigTextSize.y), + IM_COL32(255, 255, 255, 255), + "\xEE\xB7\xA3" + ); + ImGui::PopStyleVar( ); + + row2Pos = ImGui::GetCursorPos( ); + row2Pos.x = currPos.x; + row2Pos.y -= 33; + ImGui::SetCursorPos(row2Pos); + + HandleKeyboardSpecialKeys( ); + + ImGui::PopStyleVar( ); + ImGui::PopStyleColor( ); + ImGui::End( ); + ImGui::PopStyleColor( ); } void wd::Overlay::RenderKeyboardRow(const char** keys, int start, int end, bool isUppercase) { - ImVec2 buttonSize(30, 30); + ImVec2 buttonSize(45, 30); for (int i = start; i < end; ++i) { ImGui::PushID(i); @@ -302,36 +530,40 @@ void wd::Overlay::RenderKeyboardRow(const char** keys, int start, int end, bool void wd::Overlay::AddKeyToBuffer(char c) { size_t len = strlen(g_KeyboardText); - if (len < 255) - { - g_KeyboardText[ len ] = c; - g_KeyboardText[ len + 1 ] = '\0'; - } + if (len >= 255 || cursorPos > len) + return; + + for (size_t i = len; i > cursorPos; --i) + g_KeyboardText[ i ] = g_KeyboardText[ i - 1 ]; + + g_KeyboardText[ cursorPos ] = c; + g_KeyboardText[ len + 1 ] = '\0'; + cursorPos++; } void wd::Overlay::HandleKeyboardSpecialKeys() { ImVec2 buttonSize(30, 30); - if (ImGui::Button("Space", ImVec2(60, 30)) || ImGui::IsKeyPressed(ImGuiKey_Space) || ImGui::IsKeyPressed(ImGuiKey_GamepadFaceUp)) + if (ImGui::Button("##space", ImVec2((ImGui::GetContentRegionAvail( ).x - 63), 30)) || ImGui::IsKeyPressed(ImGuiKey_GamepadFaceUp)) AddKeyToBuffer(' '); - ImGui::SameLine(); - if (ImGui::Button("Backspace", ImVec2(90, 30)) || - ImGui::IsKeyPressed(ImGuiKey_Backspace) || - ImGui::IsKeyPressed(ImGuiKey_GamepadFaceLeft)) - { - size_t len = strlen(g_KeyboardText); - if (len > 0) - g_KeyboardText[ len - 1 ] = '\0'; - } - ImGui::SameLine(); + ImVec2 pos = ImGui::GetItemRectMin( ); + ImVec2 size = ImGui::GetItemRectSize( ); - if (ImGui::Button("OK", buttonSize) || - ImGui::IsKeyPressed(ImGuiKey_Enter) || - ImGui::IsKeyPressed(ImGuiKey_GamepadStart)) - { - m_bKeyboard = false; - SetEvent(g_KeyboardFinished); - } -} + ImVec2 bigTextSize = ImGui::CalcTextSize("\xEE\x9D\x9D"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 18, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) - 18, pos.y + 18), + IM_COL32(255, 255, 255, 255), + "\xEE\x9D\x9D" + ); + + ImVec2 smallTextSize = ImGui::CalcTextSize("\xEF\x82\x95"); + ImGui::GetWindowDrawList( )->AddText( + ImGui::GetFont( ), 14, + ImVec2((pos.x + (size.x - bigTextSize.x) * 0.5f) + 12, pos.y + 14), + IM_COL32(250, 161, 25, 255), + "\xEF\x82\x95" + ); +} \ No newline at end of file diff --git a/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.cpp b/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.cpp index d5545fa..c9ff12c 100644 --- a/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.cpp +++ b/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.cpp @@ -9,9 +9,13 @@ #include #include #include "Windows.Xbox.System.User.h" +#include "../WinDurangoConfig.h" namespace winrt::Windows::Xbox::Input::implementation { + int Gamepad::currNeed = 0; + bool Gamepad::isMC = false; + winrt::Windows::Foundation::Collections::IVectorView Gamepad::Gamepads() { if (staticGamepads == Foundation::Collections::IVector(nullptr) || staticGamepads.Size() == 0) { @@ -48,6 +52,21 @@ namespace winrt::Windows::Xbox::Input::implementation ClipCursor(&screenRect); ShowCursor(FALSE); + if (isMC) { + auto window = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); + window.PointerWheelChanged( + winrt::Windows::Foundation::TypedEventHandler( + [&](winrt::Windows::UI::Core::CoreWindow const&, winrt::Windows::UI::Core::PointerEventArgs const& args) + { + auto delta = args.CurrentPoint().Properties().MouseWheelDelta(); + int scrollUnits = delta / 120.0f; + Gamepad::currNeed += scrollUnits; + LOG_INFO_W((L"Wheel delta: " + std::to_wstring(scrollUnits) + L"\n").c_str()); + } + ) + ); + } + return staticGamepads.GetView(); } @@ -185,17 +204,22 @@ namespace winrt::Windows::Xbox::Input::implementation if (GetAsyncKeyState(keyboardButtons[ i ].first)) { reading.Buttons |= keyboardButtons[ i ].second; + if (keyboardButtons[i].first == 'V') { + //menuOpened = true; + } else if (keyboardButtons[i].first == 'X') { + //menuOpened = false; + } } - if (GetAsyncKeyState('W') & 0x8000) { + if (GetAsyncKeyState(wdcfg.GetData().MovementThumbY) & 0x8000) { ly = 1.0f; } - if (GetAsyncKeyState('A') & 0x8000) { + if (GetAsyncKeyState(wdcfg.GetData().MovementThumbXM) & 0x8000) { lx = -1.0f; } - if (GetAsyncKeyState('S') & 0x8000) { + if (GetAsyncKeyState(wdcfg.GetData().MovementThumbYM) & 0x8000) { ly = -1.0f; } - if (GetAsyncKeyState('D') & 0x8000) { + if (GetAsyncKeyState(wdcfg.GetData().MovementThumbX) & 0x8000) { lx = 1.0f; } } @@ -204,15 +228,30 @@ namespace winrt::Windows::Xbox::Input::implementation ly = std::clamp(ly, -1.0f, 1.0f); if (lx != 0.0f || ly != 0.0f) { - reading.LeftThumbstickX = lx; - reading.LeftThumbstickY = ly; + if (wdcfg.GetData().MovementStick == "Left") { + reading.LeftThumbstickX = lx; + reading.LeftThumbstickY = ly; + } else if (wdcfg.GetData().MovementStick == "Right") { + reading.RightThumbstickX = lx; + reading.RightThumbstickY = ly; + } } - if (GetAsyncKeyState(VK_LBUTTON) & 0x8000) { - reading.RightTrigger = 1.0f; - } - if (GetAsyncKeyState(VK_RBUTTON) & 0x8000) { - reading.LeftTrigger = 1.0f; + if (menuOpened && wdcfg.GetData().game == WinDurangoConfigData::Game::Minecraft) { + if (GetAsyncKeyState(wdcfg.GetData().RTrigger) & 0x8000) { + reading.Buttons |= keyboardButtons[VK_SPACE].second; + + } + if (GetAsyncKeyState(wdcfg.GetData().LTrigger) & 0x8000) { + reading.Buttons |= keyboardButtons['V'].second; + } + } else { + if (GetAsyncKeyState(wdcfg.GetData().RTrigger) & 0x8000) { + reading.RightTrigger = 1.0f; + } + if (GetAsyncKeyState(wdcfg.GetData().LTrigger) & 0x8000) { + reading.LeftTrigger = 1.0f; + } } /* @@ -246,13 +285,51 @@ namespace winrt::Windows::Xbox::Input::implementation y *= -sign(deltasumY); if (x != 0 || y != 0) { - reading.RightThumbstickX = std::clamp(x, -1.0f, 1.0f); - reading.RightThumbstickY = std::clamp(y, -1.0f, 1.0f); + if (menuOpened && wdcfg.GetData().game == WinDurangoConfigData::Game::Minecraft) { + if (wdcfg.GetData().MouseStick == "Right") { + reading.LeftThumbstickX = std::clamp(x, -1.0f, 1.0f); + reading.LeftThumbstickY = std::clamp(y, -1.0f, 1.0f); + } + else if (wdcfg.GetData().MouseStick == "Left") { + reading.RightThumbstickX = std::clamp(x, -1.0f, 1.0f); + reading.RightThumbstickY = std::clamp(y, -1.0f, 1.0f); + } + } else { + if (wdcfg.GetData().MouseStick == "Right") { + reading.RightThumbstickX = std::clamp(x, -1.0f, 1.0f); + reading.RightThumbstickY = std::clamp(y, -1.0f, 1.0f); + } + else if (wdcfg.GetData().MouseStick == "Left") { + reading.LeftThumbstickX = std::clamp(x, -1.0f, 1.0f); + reading.LeftThumbstickY = std::clamp(y, -1.0f, 1.0f); + } + } } deltasumX = 0.0f; deltasumY = 0.0f; + if (currNeed != 0) { + if (!isCtrl) { + isCtrl = true; + if (currNeed > 0) { + reading.Buttons |= GamepadButtons::RightShoulder; + } + else if (currNeed < 0) { + reading.Buttons |= GamepadButtons::LeftShoulder; + } + } + else { + isCtrl = false; + if (currNeed > 0) { + currNeed--; + } + else if (currNeed < 0) { + currNeed++; + } + } + } + return reading; } diff --git a/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.h b/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.h index 8e5b707..9cd923b 100644 --- a/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.h +++ b/dlls/winrt_x/Implementation/Windows.Xbox.Input.Gamepad.h @@ -10,7 +10,28 @@ namespace winrt::Windows::Xbox::Input::implementation struct Gamepad : GamepadT { Gamepad() = default; - Gamepad(uint64_t id) : m_id(id) {} + Gamepad(uint64_t id) : m_id(id), wdcfg(WinDurangoConfig::Instance()) { + keyboardButtons[0].first = wdcfg.GetData().Up; + keyboardButtons[1].first = wdcfg.GetData().Down; + keyboardButtons[2].first = wdcfg.GetData().Left; + keyboardButtons[3].first = wdcfg.GetData().Right; + keyboardButtons[4].first = wdcfg.GetData().Menu; + keyboardButtons[5].first = wdcfg.GetData().View; + keyboardButtons[6].first = wdcfg.GetData().LThumb; + keyboardButtons[7].first = wdcfg.GetData().RThumb; + keyboardButtons[8].first = wdcfg.GetData().LShoulder; + keyboardButtons[9].first = wdcfg.GetData().RShoulder; + keyboardButtons[10].first = wdcfg.GetData().A; + keyboardButtons[11].first = wdcfg.GetData().B; + keyboardButtons[12].first = wdcfg.GetData().X; + keyboardButtons[13].first = wdcfg.GetData().Y; + if (wdcfg.GetData().game == WinDurangoConfigData::Game::Minecraft) { + isMC = true; + } + else { + isMC = false; + } + } static winrt::Windows::Foundation::Collections::IVectorView Gamepads(); static winrt::event_token GamepadAdded(winrt::Windows::Foundation::EventHandler const& handler); @@ -37,6 +58,12 @@ namespace winrt::Windows::Xbox::Input::implementation float deltasumX = 0.0f; float deltasumY = 0.0f; bool firstFrame = true; + bool menuOpened = false; + WinDurangoConfig& wdcfg; + bool isCtrl = false; + static int currNeed; + int currDone; + static bool isMC; inline static std::pair const gamepadButtons[] = { @@ -56,7 +83,7 @@ namespace winrt::Windows::Xbox::Input::implementation { XINPUT_GAMEPAD_Y, GamepadButtons::Y }, }; - inline static std::pair const keyboardButtons[] = + inline static std::pair keyboardButtons[] = { { VK_UP, GamepadButtons::DPadUp }, { VK_DOWN, GamepadButtons::DPadDown }, @@ -64,14 +91,14 @@ namespace winrt::Windows::Xbox::Input::implementation { VK_RIGHT, GamepadButtons::DPadRight }, { VK_RETURN, GamepadButtons::Menu }, { VK_ESCAPE, GamepadButtons::View }, - { VK_LSHIFT, GamepadButtons::LeftThumbstick }, - { VK_RSHIFT, GamepadButtons::RightThumbstick }, + { VK_RSHIFT, GamepadButtons::LeftThumbstick }, + { VK_LSHIFT, GamepadButtons::RightThumbstick }, { VK_LCONTROL, GamepadButtons::LeftShoulder }, { VK_RCONTROL, GamepadButtons::RightShoulder }, { VK_SPACE, GamepadButtons::A }, - { 'X', GamepadButtons::B}, - { 'C', GamepadButtons::X }, - { 'V', GamepadButtons::Y}, + { 'Q', GamepadButtons::B}, + { 'R', GamepadButtons::X}, + { 'E', GamepadButtons::Y}, }; }; } diff --git a/dlls/winrt_x/Implementation/Windows.Xbox.System.User.h b/dlls/winrt_x/Implementation/Windows.Xbox.System.User.h index 148a887..061a3d6 100644 --- a/dlls/winrt_x/Implementation/Windows.Xbox.System.User.h +++ b/dlls/winrt_x/Implementation/Windows.Xbox.System.User.h @@ -6,7 +6,7 @@ namespace winrt::Windows::Xbox::System::implementation struct User : UserT { User() = default; - User(uint64_t id) : m_id(id) {} + User(uint64_t id) : m_id(id), wdcfg(WinDurangoConfig::Instance()) {} static winrt::Windows::Xbox::System::UserOnlineState OnlineState(); static winrt::event_token OnlineStateChanged(winrt::Windows::Foundation::EventHandler const& handler); @@ -58,6 +58,7 @@ namespace winrt::Windows::Xbox::System::implementation inline static winrt::event> m_signOutCompletedEvent; inline static winrt::Windows::Xbox::System::User staticUser = {nullptr}; inline static winrt::Windows::Foundation::Collections::IVector staticUsers = {nullptr}; + WinDurangoConfig& wdcfg; }; } namespace winrt::Windows::Xbox::System::factory_implementation diff --git a/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.cpp b/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.cpp index 2052449..793f653 100644 --- a/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.cpp +++ b/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.cpp @@ -7,43 +7,54 @@ namespace winrt::Windows::Xbox::System::implementation hstring UserDisplayInfo::Gamertag() { LOG_INFO("UserDisplayInfo::Gamertag() called"); - - return L"HelloWorld"; + + return winrt::to_hstring(wdcfg.GetData().gamertag); } uint32_t UserDisplayInfo::GamerScore() { LOG_INFO("UserDisplayInfo::GamerScore() called"); - return 0; + return wdcfg.GetData().gamerscore; } hstring UserDisplayInfo::ApplicationDisplayName() { LOG_INFO("UserDisplayInfo::GameDisplayName() called"); - return to_hstring("WinDurango"); + return winrt::to_hstring(wdcfg.GetData().gamertag); } hstring UserDisplayInfo::GameDisplayName() { LOG_INFO("UserDisplayInfo::GameDisplayName() called"); - return L"HelloWorld"; + return winrt::to_hstring(wdcfg.GetData().gamertag); } int32_t UserDisplayInfo::Reputation() { LOG_INFO("UserDisplayInfo::Reputation() called"); - return 1; + return wdcfg.GetData().reputation; } UserAgeGroup UserDisplayInfo::AgeGroup() { LOG_INFO("UserDisplayInfo::AgeGroup() called"); - return UserAgeGroup::Unknown; + switch (wdcfg.GetData().ageGroup) { + case WinDurangoConfigData::AgeGroup::Adult: + return UserAgeGroup::Adult; + case WinDurangoConfigData::AgeGroup::Child: + return UserAgeGroup::Child; + case WinDurangoConfigData::AgeGroup::Teen: + return UserAgeGroup::Teen; + case WinDurangoConfigData::AgeGroup::Unknown: + return UserAgeGroup::Unknown; + default: + return UserAgeGroup::Unknown; + } } Foundation::Collections::IVectorView UserDisplayInfo::Privileges() diff --git a/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.h b/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.h index d0ac2ed..9d0a87c 100644 --- a/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.h +++ b/dlls/winrt_x/Implementation/Windows.Xbox.System.UserDisplayInfo.h @@ -6,7 +6,7 @@ namespace winrt::Windows::Xbox::System::implementation struct UserDisplayInfo : UserDisplayInfoT { UserDisplayInfo() = default; - UserDisplayInfo(hstring gamertag) {} + UserDisplayInfo(hstring gamertag) : wdcfg(WinDurangoConfig::Instance()) {} hstring Gamertag(); uint32_t GamerScore(); @@ -15,5 +15,6 @@ namespace winrt::Windows::Xbox::System::implementation int32_t Reputation(); UserAgeGroup AgeGroup(); Foundation::Collections::IVectorView Privileges(); + WinDurangoConfig& wdcfg; }; } diff --git a/dlls/winrt_x/Implementation/Windows.Xbox.UI.SystemUI.cpp b/dlls/winrt_x/Implementation/Windows.Xbox.UI.SystemUI.cpp index 7e92c5c..da95976 100644 --- a/dlls/winrt_x/Implementation/Windows.Xbox.UI.SystemUI.cpp +++ b/dlls/winrt_x/Implementation/Windows.Xbox.UI.SystemUI.cpp @@ -113,7 +113,23 @@ namespace winrt::Windows::Xbox::UI::implementation } winrt::Windows::Foundation::IAsyncOperation SystemUI::ShowVirtualKeyboardWithOptionsAsync(winrt::Windows::Xbox::UI::KeyboardOptions options) { - LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); + /* + * TODO: Use Options + */ + co_await resume_background(); + + if (!g_pD3D11XEventFunc && !g_pWDWaitForKeyboardFunc) + { + g_pD3D11XEventFunc = GetProcAddress(GetModuleHandle(L"d3d11_x.dll"), "WD11XNotify"); + g_pWDWaitForKeyboardFunc = GetProcAddress(GetModuleHandle(L"d3d11_x.dll"), "WDWaitForKeyboard"); + } + + reinterpret_cast(g_pD3D11XEventFunc)(1); + + const char* text = nullptr; + reinterpret_cast(g_pWDWaitForKeyboardFunc)(&text); + + co_return winrt::to_hstring(text); } void SystemUI::SetNotificationPositionHint(winrt::Windows::Xbox::UI::NotificationPositionHint const& value) { diff --git a/dlls/winrt_x/WinDurangoConfig.cpp b/dlls/winrt_x/WinDurangoConfig.cpp index d494d00..6043b5a 100644 --- a/dlls/winrt_x/WinDurangoConfig.cpp +++ b/dlls/winrt_x/WinDurangoConfig.cpp @@ -1,5 +1,9 @@ #include "pch.h" #include "WinDurangoConfig.h" +#include +#include +#include +using namespace winrt::Windows::Storage; WinDurangoConfig& WinDurangoConfig::Instance() { @@ -26,41 +30,165 @@ void WinDurangoConfig::ProcessConfigFile() Gamertag = "TheDurangler2" Gamerscore = 1500 Reputation = 5 + Game = "Minecraft" AgeGroup = "Adult" + + [KeyboardMapping] + A = 32 + B = 81 + X = 82 + Y = 69 + Up = 38 + Down = 40 + Left = 37 + Right = 39 + Menu = 13 + View = 27 + LThumb = 161 + RThumb = 160 + LShoulder = 162 + RShoulder = 163 + LTrigger = 2 + RTrigger = 1 + MovThumbY = 87 + MovThumbYM = 83 + MovThumbX = 68 + MovThumbXM = 65 + MovementStick = "Left" + MouseStick = "Right" )"sv; try { - // TODO: Try to read the config file from disk. If it doesn't exist, use the default data. + /* + * We need to use WinRT Storage APIs in UWP + */ + StorageFolder localFolder = ApplicationData::Current().LocalFolder(); + std::wstring folderPath = std::wstring(localFolder.Path()); + std::filesystem::path cfgPath = std::filesystem::path(folderPath) / L"config.toml"; + if (!std::filesystem::exists(cfgPath)) { + winrt::Windows::Storage::StorageFile file = localFolder + .CreateFileAsync(L"config.toml", winrt::Windows::Storage::CreationCollisionOption::ReplaceExisting) + .get(); - auto tbl = toml::parse(default_config_data); + std::wstring_convert> converter; + std::wstring wide = converter.from_bytes(std::string(default_config_data)); + winrt::Windows::Storage::FileIO::WriteTextAsync(file, wide).get(); + } - const auto gamertag_opt = tbl["WinDurango"]["Gamertag"].value(); - const auto gamerscore_opt = tbl["WinDurango"]["Gamerscore"].value(); - const auto reputation_opt = tbl["WinDurango"]["Reputation"].value(); - const auto agegroup_opt = tbl["WinDurango"]["AgeGroup"].value(); + StorageFile file = ApplicationData::Current().LocalFolder().GetFileAsync(L"config.toml").get(); + std::wstring cfdata = std::wstring(FileIO::ReadTextAsync(file).get()); + + std::string ConfigData(cfdata.begin(), cfdata.end()); + + auto tbl = toml::parse(ConfigData); + + auto gamertag_opt = tbl["WinDurango"]["Gamertag"].value(); + auto gamerscore_opt = tbl["WinDurango"]["Gamerscore"].value(); + auto reputation_opt = tbl["WinDurango"]["Reputation"].value(); + auto agegroup_opt = tbl["WinDurango"]["AgeGroup"].value(); + auto game_opt = tbl["WinDurango"]["Game"].value(); + + auto a_opt = tbl["KeyboardMapping"]["A"].value(); + auto b_opt = tbl["KeyboardMapping"]["B"].value(); + auto x_opt = tbl["KeyboardMapping"]["X"].value(); + auto y_opt = tbl["KeyboardMapping"]["Y"].value(); + auto up_opt = tbl["KeyboardMapping"]["Up"].value(); + auto down_opt = tbl["KeyboardMapping"]["Down"].value(); + auto left_opt = tbl["KeyboardMapping"]["Left"].value(); + auto right_opt = tbl["KeyboardMapping"]["Right"].value(); + auto menu_opt = tbl["KeyboardMapping"]["Menu"].value(); + auto view_opt = tbl["KeyboardMapping"]["View"].value(); + auto lthumb_opt = tbl["KeyboardMapping"]["LThumb"].value(); + auto rthumb_opt = tbl["KeyboardMapping"]["RThumb"].value(); + auto lshoulder_opt = tbl["KeyboardMapping"]["LShoulder"].value(); + auto rshoulder_opt = tbl["KeyboardMapping"]["RShoulder"].value(); + auto ltrigger_opt = tbl["KeyboardMapping"]["LTrigger"].value(); + auto rtrigger_opt = tbl["KeyboardMapping"]["RTrigger"].value(); + auto movthumby_opt = tbl["KeyboardMapping"]["MovThumbY"].value(); + auto movthumbym_opt = tbl["KeyboardMapping"]["MovThumbYM"].value(); + auto movthumbx_opt = tbl["KeyboardMapping"]["MovThumbX"].value(); + auto movthumbxm_opt = tbl["KeyboardMapping"]["MovThumbXM"].value(); + auto movstick_opt = tbl["KeyboardMapping"]["MovementStick"].value(); + auto mousestick_opt = tbl["KeyboardMapping"]["MouseStick"].value(); const WinDurangoConfigData data { - .gamertag = std::string(gamertag_opt.value()), - .gamerscore = gamerscore_opt.value_or(0), - .reputation = reputation_opt.value_or(0), + .gamertag = std::string(gamertag_opt.value_or("WinDurango2")), + .gamerscore = 0, + .reputation = 0, .ageGroup = agegroup_opt.has_value() - ? (agegroup_opt.value() == "Child" ? WinDurangoConfigData::AgeGroup::Child - : agegroup_opt.value() == "Teen" ? WinDurangoConfigData::AgeGroup::Teen - : agegroup_opt.value() == "Adult" ? WinDurangoConfigData::AgeGroup::Adult + ? (agegroup_opt.value_or("Adult") == "Child" ? WinDurangoConfigData::AgeGroup::Child + : agegroup_opt.value_or("Adult") == "Teen" ? WinDurangoConfigData::AgeGroup::Teen + : agegroup_opt.value_or("Adult") == "Adult" ? WinDurangoConfigData::AgeGroup::Adult : WinDurangoConfigData::AgeGroup::Unknown) - : WinDurangoConfigData::AgeGroup::Unknown + : WinDurangoConfigData::AgeGroup::Unknown, + .game = + game_opt.has_value() + ? (game_opt.value_or("") == "Minecraft" ? WinDurangoConfigData::Game::Minecraft + : game_opt.value_or("") == "Forza Horizon 2" ? WinDurangoConfigData::Game::Forza_Horizon_2 + : WinDurangoConfigData::Game::Unknown) + : WinDurangoConfigData::Game::Unknown, + .A = a_opt.value_or(32), + .B = b_opt.value_or(81), + .X = x_opt.value_or(82), + .Y = y_opt.value_or(69), + .Up = up_opt.value_or(38), + .Down = down_opt.value_or(40), + .Left = left_opt.value_or(37), + .Right = right_opt.value_or(39), + .Menu = menu_opt.value_or(13), + .View = view_opt.value_or(27), + .LThumb = lthumb_opt.value_or(161), + .RThumb = rthumb_opt.value_or(160), + .LShoulder = lshoulder_opt.value_or(162), + .RShoulder = rshoulder_opt.value_or(163), + .LTrigger = ltrigger_opt.value_or(2), + .RTrigger = rtrigger_opt.value_or(1), + .MovementThumbY = movthumby_opt.value_or(87), + .MovementThumbYM = movthumbym_opt.value_or(83), + .MovementThumbX = movthumbx_opt.value_or(68), + .MovementThumbXM = movthumbxm_opt.value_or(65), + .MovementStick = std::string(movstick_opt.value_or("left")), + .MouseStick = std::string(mousestick_opt.value_or("right")), }; - Instance().SetData(data); - - // TODO: Save the config file, if the file didn't exist before. + SetData(data); } catch (const toml::parse_error& err) { - std::cerr << "Parsing failed:\n" << err << "\n"; + LOG_INFO("WinDurangoConfig || Parsing failed: %s\n", err); + const WinDurangoConfigData data + { + .gamertag = std::string("TheDurangler2"), + .gamerscore = 1500, + .reputation = 5, + .ageGroup = WinDurangoConfigData::AgeGroup::Unknown, + .A = 0, + .B = 0, + .X = 0, + .Y = 0, + .Up = 0, + .Down = 0, + .Left = 0, + .Right = 0, + .Menu = 0, + .View = 0, + .LThumb = 0, + .RThumb = 0, + .LShoulder = 0, + .RShoulder = 0, + .LTrigger = 0, + .RTrigger = 0, + .MovementThumbY = 0, + .MovementThumbYM = 0, + .MovementThumbX = 0, + .MovementThumbXM = 0, + .MovementStick = "left", + .MouseStick = "right", + }; + SetData(data); } } diff --git a/dlls/winrt_x/WinDurangoConfig.h b/dlls/winrt_x/WinDurangoConfig.h index 5226e53..c8fdb20 100644 --- a/dlls/winrt_x/WinDurangoConfig.h +++ b/dlls/winrt_x/WinDurangoConfig.h @@ -1,6 +1,8 @@ #pragma once - #include "toml.hpp" +#include +#include +#include struct WinDurangoConfigData { @@ -14,6 +16,34 @@ struct WinDurangoConfigData Adult, Unknown } ageGroup{ AgeGroup::Unknown }; + enum class Game + { + Minecraft, + Forza_Horizon_2, + Unknown + } game{ Game::Unknown }; + int A = 0; + int B = 0; + int X = 0; + int Y = 0; + int Up = 0; + int Down = 0; + int Left = 0; + int Right = 0; + int Menu = 0; + int View = 0; + int LThumb = 0; + int RThumb = 0; + int LShoulder = 0; + int RShoulder = 0; + int LTrigger = 0; + int RTrigger = 0; + int MovementThumbY = 0; + int MovementThumbYM = 0; + int MovementThumbX = 0; + int MovementThumbXM = 0; + std::string MovementStick = "Left"; + std::string MouseStick = "Right"; }; class WinDurangoConfig @@ -33,7 +63,7 @@ private: WinDurangoConfig(); ~WinDurangoConfig() = default; - static void ProcessConfigFile(); + void ProcessConfigFile(); WinDurangoConfigData _data{};