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)
find_package(X11 REQUIRED)
find_package(GTK3 REQUIRED)
endif()
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
GamePatch_scan();
}
LatteGPUState.alwaysDisplayDRC = ActiveSettings::DisplayDRCEnabled();
InfoLog_PrintActiveSettings();
Latte_Start();
// check for debugger entrypoint bp
@ -864,4 +865,4 @@ namespace CafeSystem
return currentUpdatedApplicationHash;
}
}
}

View file

@ -50,6 +50,7 @@ struct LatteGPUState_t
uint32 gx2InitCalled; // incremented every time GX2Init() is called
// OpenGL control
uint32 glVendor; // GLVENDOR_*
bool alwaysDisplayDRC = false;
// temporary (replace with proper solution later)
bool tvBufferUsesSRGB;
bool drcBufferUsesSRGB;
@ -172,4 +173,4 @@ void LatteRenderTarget_updateViewport();
// Latte emulation control
void Latte_Start();
void Latte_Stop();
bool Latte_IsActive();
bool Latte_IsActive();

View file

@ -1004,7 +1004,6 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
g_renderer->ImguiEnd();
}
bool alwaysDisplayDRC = 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)
@ -1016,9 +1015,11 @@ void LatteRenderTarget_itHLECopyColorBufferToScanBuffer(MPTR colorBufferPtr, uin
return;
}
const bool tabPressed = gui_isKeyDown(WXK_TAB);
const bool ctrlPressed = gui_isKeyDown(0xA2); // VK_LCONTROL
const bool tabPressed = gui_isKeyDown(PlatformKeyCodes::TAB);
const bool ctrlPressed = gui_isKeyDown(PlatformKeyCodes::LCONTROL);
bool showDRC = swkbd_hasKeyboardInputHook() == false && tabPressed;
bool& alwaysDisplayDRC = LatteGPUState.alwaysDisplayDRC;
if (ctrlPressed && tabPressed)
{
@ -1131,4 +1132,4 @@ void LatteRenderTarget_unloadAll()
LatteMRT::DeleteCachedFBO(g_emptyFBO);
g_emptyFBO = nullptr;
}
}
}

View file

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

View file

@ -147,6 +147,11 @@ target_link_libraries(CemuGui PRIVATE
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)
target_link_libraries(CemuGui PRIVATE cubeb::cubeb)
endif()

View file

@ -218,9 +218,11 @@ int CemuApp::FilterEvent(wxEvent& event)
const auto& key_event = (wxKeyEvent&)event;
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);

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/guiWrapper.h"
#include "gui/CemuApp.h"
@ -156,19 +163,10 @@ bool gui_isPadWindowOpen()
}
#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)
{
return gdk_keyval_name(keyCode);
}
#endif
void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw)
@ -176,43 +174,15 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
#if BOOST_OS_WINDOWS
handleInfoOut.hwnd = wxw->GetHWND();
#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
GtkWidget* gtkWidget = (GtkWidget*)wxw->GetHandle(); // returns GtkWidget
dyn_gtk_widget_realize(gtkWidget);
GdkWindow* gdkWindow = dyn_gtk_widget_get_window(gtkWidget);
handleInfoOut.xlib_window = dyn_gdk_x11_window_get_xid(gdkWindow);
gtk_widget_realize(gtkWidget);
GdkWindow* gdkWindow = gtk_widget_get_window(gtkWidget);
handleInfoOut.xlib_window = gdk_x11_window_get_xid(gdkWindow);
// get display
GdkDisplay* gdkDisplay = dyn_gdk_window_get_display(gdkWindow);
handleInfoOut.xlib_display = dyn_gdk_x11_display_get_xdisplay(gdkDisplay);
GdkDisplay* gdkDisplay = gdk_window_get_display(gdkWindow);
handleInfoOut.xlib_display = gdk_x11_display_get_xdisplay(gdkDisplay);
if(!handleInfoOut.xlib_display)
{
cemuLog_log(LogType::Force, "Unable to get xlib display");
@ -222,11 +192,16 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
#endif
}
bool gui_isKeyDown(int key)
bool gui_isKeyDown(uint32 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()
{
std::shared_lock lock(g_mutex);
@ -311,4 +286,4 @@ void debuggerWindow_notifyModuleUnloaded(void* module)
evt->SetClientData(module);
wxQueueEvent(g_debugger_window, evt);
}
}
}

View file

@ -4,6 +4,7 @@
#if BOOST_OS_LINUX
#include "xcb/xproto.h"
#include <gdk/gdkkeysyms.h>
#endif
struct WindowHandleInfo
@ -25,6 +26,23 @@ struct WindowHandleInfo
#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
{
std::atomic_bool app_active; // our app is active/has focus
@ -56,7 +74,7 @@ struct WindowInfo
return result->second;
}
void set_keystatesdown()
void set_keystatesup()
{
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; });
@ -89,7 +107,8 @@ void gui_updateWindowTitles(bool isIdle, bool isLoading, double fps);
void gui_getWindowSize(int* w, int* h);
void gui_getPadWindowSize(int* w, int* h);
bool gui_isPadWindowOpen();
bool gui_isKeyDown(int key);
bool gui_isKeyDown(uint32 key);
bool gui_isKeyDown(PlatformKeyCodes key);
void gui_notifyGameLoaded();
void gui_notifyGameExited();
@ -114,4 +133,4 @@ void debuggerWindow_notifyDebugBreakpointHit2();
void debuggerWindow_notifyRun();
void debuggerWindow_moveIP();
void debuggerWindow_notifyModuleLoaded(void* module);
void debuggerWindow_notifyModuleUnloaded(void* module);
void debuggerWindow_notifyModuleUnloaded(void* module);

View file

@ -50,11 +50,8 @@ extern WindowInfo g_window_info;
ControllerState KeyboardController::raw_state()
{
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); });
result.buttons.SetPressedButtons(pressedKeys);
}
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); });
result.buttons.SetPressedButtons(pressedKeys);
return result;
}