Fix gamepad hotkey and game profile setting (#510)

This commit is contained in:
goeiecool9999 2022-11-24 12:29:29 +01:00 committed by GitHub
parent c43fc81f8e
commit cbdf381b31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 79 additions and 64 deletions

View File

@ -114,6 +114,7 @@ endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
find_package(GTK3 REQUIRED)
endif() endif()
if (ENABLE_VULKAN) if (ENABLE_VULKAN)

16
cmake/FindGTK3.cmake Normal file
View File

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2022 Andrea Pappacoda <andrea@pappacoda.it>
# SPDX-License-Identifier: ISC
include(FindPackageHandleStandardArgs)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_search_module(GTK3 IMPORTED_TARGET gtk+-3.0)
if (GTK3_FOUND)
add_library(GTK3::gtk ALIAS PkgConfig::GTK3)
endif()
find_package_handle_standard_args(GTK3
REQUIRED_VARS GTK3_LINK_LIBRARIES
VERSION_VAR GTK3_VERSION
)
endif()

View File

@ -394,6 +394,7 @@ void cemu_initForGame()
// replace any known function signatures with our HLE implementations and patch bugs in the games // replace any known function signatures with our HLE implementations and patch bugs in the games
GamePatch_scan(); GamePatch_scan();
} }
LatteGPUState.alwaysDisplayDRC = ActiveSettings::DisplayDRCEnabled();
InfoLog_PrintActiveSettings(); InfoLog_PrintActiveSettings();
Latte_Start(); Latte_Start();
// check for debugger entrypoint bp // check for debugger entrypoint bp

View File

@ -50,6 +50,7 @@ struct LatteGPUState_t
uint32 gx2InitCalled; // incremented every time GX2Init() is called uint32 gx2InitCalled; // incremented every time GX2Init() is called
// OpenGL control // OpenGL control
uint32 glVendor; // GLVENDOR_* uint32 glVendor; // GLVENDOR_*
bool alwaysDisplayDRC = false;
// temporary (replace with proper solution later) // temporary (replace with proper solution later)
bool tvBufferUsesSRGB; bool tvBufferUsesSRGB;
bool drcBufferUsesSRGB; bool drcBufferUsesSRGB;

View File

@ -1004,7 +1004,6 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
g_renderer->ImguiEnd(); g_renderer->ImguiEnd();
} }
bool alwaysDisplayDRC = false;
bool ctrlTabHotkeyPressed = false; bool ctrlTabHotkeyPressed = false;
void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferSliceIndex, uint32 colorBufferFormat, uint32 colorBufferPitch, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferSwizzle, uint32 renderTarget) void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uint32 colorBufferWidth, uint32 colorBufferHeight, uint32 colorBufferSliceIndex, uint32 colorBufferFormat, uint32 colorBufferPitch, Latte::E_HWTILEMODE colorBufferTilemode, uint32 colorBufferSwizzle, uint32 renderTarget)
@ -1016,9 +1015,11 @@ void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uin
return; return;
} }
const bool tabPressed = gui_isKeyDown(WXK_TAB); const bool tabPressed = gui_isKeyDown(PlatformKeyCodes::TAB);
const bool ctrlPressed = gui_isKeyDown(0xA2); // VK_LCONTROL const bool ctrlPressed = gui_isKeyDown(PlatformKeyCodes::LCONTROL);
bool showDRC = swkbd_hasKeyboardInputHook() == false && tabPressed; bool showDRC = swkbd_hasKeyboardInputHook() == false && tabPressed;
bool& alwaysDisplayDRC = LatteGPUState.alwaysDisplayDRC;
if (ctrlPressed && tabPressed) if (ctrlPressed && tabPressed)
{ {

View File

@ -11,8 +11,6 @@
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
#include "Cafe/CafeSystem.h" #include "Cafe/CafeSystem.h"
extern bool alwaysDisplayDRC;
std::set<fs::path> std::set<fs::path>
ActiveSettings::LoadOnce(const fs::path& user_data_path, ActiveSettings::LoadOnce(const fs::path& user_data_path,
const fs::path& config_path, const fs::path& config_path,
@ -57,7 +55,6 @@ bool ActiveSettings::LoadSharedLibrariesEnabled()
bool ActiveSettings::DisplayDRCEnabled() bool ActiveSettings::DisplayDRCEnabled()
{ {
alwaysDisplayDRC = g_current_game_profile->StartWithGamepadView();
return g_current_game_profile->StartWithGamepadView(); return g_current_game_profile->StartWithGamepadView();
} }

View File

@ -147,6 +147,11 @@ target_link_libraries(CemuGui PRIVATE
ZArchive::zarchive ZArchive::zarchive
) )
if(ENABLE_WXWIDGETS AND UNIX AND NOT APPLE)
# PUBLIC because gdk/gdkkeysyms.h is included in guiWrapper.h
target_link_libraries(CemuGui PUBLIC GTK3::gtk)
endif()
if(ENABLE_CUBEB) if(ENABLE_CUBEB)
target_link_libraries(CemuGui PRIVATE cubeb::cubeb) target_link_libraries(CemuGui PRIVATE cubeb::cubeb)
endif() endif()

View File

@ -218,9 +218,11 @@ int CemuApp::FilterEvent(wxEvent& event)
const auto& key_event = (wxKeyEvent&)event; const auto& key_event = (wxKeyEvent&)event;
g_window_info.set_keystate(fix_raw_keycode(key_event.GetRawKeyCode(), key_event.GetRawKeyFlags()), false); g_window_info.set_keystate(fix_raw_keycode(key_event.GetRawKeyCode(), key_event.GetRawKeyFlags()), false);
} }
else if(event.GetEventType() == wxEVT_KILL_FOCUS) else if(event.GetEventType() == wxEVT_ACTIVATE_APP)
{ {
g_window_info.set_keystatesdown(); const auto& activate_event = (wxActivateEvent&)event;
if(!activate_event.GetActive())
g_window_info.set_keystatesup();
} }
return wxApp::FilterEvent(event); return wxApp::FilterEvent(event);

View File

@ -1,3 +1,10 @@
#if BOOST_OS_LINUX
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdkx.h>
#endif
#include "gui/wxgui.h" #include "gui/wxgui.h"
#include "gui/guiWrapper.h" #include "gui/guiWrapper.h"
#include "gui/CemuApp.h" #include "gui/CemuApp.h"
@ -156,19 +163,10 @@ bool gui_isPadWindowOpen()
} }
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
#include <wx/nativewin.h>
#include <dlfcn.h>
typedef void GdkDisplay;
namespace
{
const char* (*gdk_keyval_name)(unsigned int keyval);
}
std::string gui_gtkRawKeyCodeToString(uint32 keyCode) std::string gui_gtkRawKeyCodeToString(uint32 keyCode)
{ {
return gdk_keyval_name(keyCode); return gdk_keyval_name(keyCode);
} }
#endif #endif
void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw) void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw)
@ -176,43 +174,15 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
#if BOOST_OS_WINDOWS #if BOOST_OS_WINDOWS
handleInfoOut.hwnd = wxw->GetHWND(); handleInfoOut.hwnd = wxw->GetHWND();
#elif BOOST_OS_LINUX #elif BOOST_OS_LINUX
/* dynamically retrieve GTK imports so we dont have to include and link the whole lib */
void (*dyn_gtk_widget_realize)(GtkWidget *widget);
dyn_gtk_widget_realize = (void(*)(GtkWidget* widget))dlsym(RTLD_NEXT, "gtk_widget_realize");
GdkWindow* (*dyn_gtk_widget_get_window)(GtkWidget *widget);
dyn_gtk_widget_get_window = (GdkWindow*(*)(GtkWidget* widget))dlsym(RTLD_NEXT, "gtk_widget_get_window");
GdkDisplay* (*dyn_gdk_window_get_display)(GdkWindow *widget);
dyn_gdk_window_get_display = (GdkDisplay*(*)(GdkWindow* window))dlsym(RTLD_NEXT, "gdk_window_get_display");
Display* (*dyn_gdk_x11_display_get_xdisplay)(GdkDisplay *display);
dyn_gdk_x11_display_get_xdisplay = (Display*(*)(GdkDisplay* display))dlsym(RTLD_NEXT, "gdk_x11_display_get_xdisplay");
Window (*dyn_gdk_x11_window_get_xid)(GdkWindow *window);
dyn_gdk_x11_window_get_xid = (Window(*)(GdkWindow *window))dlsym(RTLD_NEXT, "gdk_x11_window_get_xid");
gdk_keyval_name = (const char* (*)(unsigned int))dlsym(RTLD_NEXT, "gdk_keyval_name");
if(!dyn_gtk_widget_realize || !dyn_gtk_widget_get_window ||
!dyn_gdk_window_get_display || !dyn_gdk_x11_display_get_xdisplay ||
!dyn_gdk_x11_window_get_xid || !gdk_keyval_name)
{
cemuLog_log(LogType::Force, "Unable to load GDK symbols");
return;
}
/* end of imports */
// get window // get window
GtkWidget* gtkWidget = (GtkWidget*)wxw->GetHandle(); // returns GtkWidget GtkWidget* gtkWidget = (GtkWidget*)wxw->GetHandle(); // returns GtkWidget
dyn_gtk_widget_realize(gtkWidget); gtk_widget_realize(gtkWidget);
GdkWindow* gdkWindow = dyn_gtk_widget_get_window(gtkWidget); GdkWindow* gdkWindow = gtk_widget_get_window(gtkWidget);
handleInfoOut.xlib_window = dyn_gdk_x11_window_get_xid(gdkWindow); handleInfoOut.xlib_window = gdk_x11_window_get_xid(gdkWindow);
// get display // get display
GdkDisplay* gdkDisplay = dyn_gdk_window_get_display(gdkWindow); GdkDisplay* gdkDisplay = gdk_window_get_display(gdkWindow);
handleInfoOut.xlib_display = dyn_gdk_x11_display_get_xdisplay(gdkDisplay); handleInfoOut.xlib_display = gdk_x11_display_get_xdisplay(gdkDisplay);
if(!handleInfoOut.xlib_display) if(!handleInfoOut.xlib_display)
{ {
cemuLog_log(LogType::Force, "Unable to get xlib display"); cemuLog_log(LogType::Force, "Unable to get xlib display");
@ -222,11 +192,16 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
#endif #endif
} }
bool gui_isKeyDown(int key) bool gui_isKeyDown(uint32 key)
{ {
return g_window_info.get_keystate(key); return g_window_info.get_keystate(key);
} }
bool gui_isKeyDown(PlatformKeyCodes key)
{
return gui_isKeyDown((std::underlying_type_t<PlatformKeyCodes>)key);
}
void gui_notifyGameLoaded() void gui_notifyGameLoaded()
{ {
std::shared_lock lock(g_mutex); std::shared_lock lock(g_mutex);

View File

@ -4,6 +4,7 @@
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
#include "xcb/xproto.h" #include "xcb/xproto.h"
#include <gdk/gdkkeysyms.h>
#endif #endif
struct WindowHandleInfo struct WindowHandleInfo
@ -25,6 +26,23 @@ struct WindowHandleInfo
#endif #endif
}; };
enum struct PlatformKeyCodes : uint32
{
#if BOOST_OS_WINDOWS
LCONTROL = VK_LCONTROL,
RCONTROL = VK_RCONTROL,
TAB = VK_TAB,
#elif BOOST_OS_LINUX
LCONTROL = GDK_KEY_Control_L,
RCONTROL = GDK_KEY_Control_R,
TAB = GDK_KEY_Tab,
#else
LCONTROL = 0,
RCONTROL = 0,
TAB = 0,
#endif
};
struct WindowInfo struct WindowInfo
{ {
std::atomic_bool app_active; // our app is active/has focus std::atomic_bool app_active; // our app is active/has focus
@ -56,7 +74,7 @@ struct WindowInfo
return result->second; return result->second;
} }
void set_keystatesdown() void set_keystatesup()
{ {
const std::lock_guard<std::mutex> lock(keycode_mutex); const std::lock_guard<std::mutex> lock(keycode_mutex);
std::for_each(m_keydown.begin(), m_keydown.end(), [](std::pair<const uint32, bool>& el){ el.second = false; }); std::for_each(m_keydown.begin(), m_keydown.end(), [](std::pair<const uint32, bool>& el){ el.second = false; });
@ -89,7 +107,8 @@ void gui_updateWindowTitles(bool isIdle, bool isLoading, double fps);
void gui_getWindowSize(int* w, int* h); void gui_getWindowSize(int* w, int* h);
void gui_getPadWindowSize(int* w, int* h); void gui_getPadWindowSize(int* w, int* h);
bool gui_isPadWindowOpen(); bool gui_isPadWindowOpen();
bool gui_isKeyDown(int key); bool gui_isKeyDown(uint32 key);
bool gui_isKeyDown(PlatformKeyCodes key);
void gui_notifyGameLoaded(); void gui_notifyGameLoaded();
void gui_notifyGameExited(); void gui_notifyGameExited();

View File

@ -50,11 +50,8 @@ extern WindowInfo g_window_info;
ControllerState KeyboardController::raw_state() ControllerState KeyboardController::raw_state()
{ {
ControllerState result{}; ControllerState result{};
if (g_window_info.app_active) boost::container::small_vector<uint32, 16> pressedKeys;
{ g_window_info.iter_keystates([&pressedKeys](const std::pair<const uint32, bool>& keyState) { if (keyState.second) pressedKeys.emplace_back(keyState.first); });
boost::container::small_vector<uint32, 16> pressedKeys; result.buttons.SetPressedButtons(pressedKeys);
g_window_info.iter_keystates([&pressedKeys](const std::pair<const uint32, bool>& keyState) { if (keyState.second) pressedKeys.emplace_back(keyState.first); });
result.buttons.SetPressedButtons(pressedKeys);
}
return result; return result;
} }