csgo-vulkan-fix: make more versatile

This commit is contained in:
Vaxry 2023-10-31 17:45:55 +00:00
parent da70bebdf1
commit 097706a6c1
2 changed files with 25 additions and 34 deletions

View File

@ -1,6 +1,9 @@
# csgo-vulkan-fix # csgo-vulkan-fix
Updated for CS2. Originally meant for csgo / cs2, but can work with any app, really.
csgo-vulkan-fix is a way to force apps to a fake resolution without
them realizing it.
If you want to play CS2, you're locked to your native res. If you want to play CS2, you're locked to your native res.
Other resolutions (especially not 16:9) are wonky. Other resolutions (especially not 16:9) are wonky.
@ -18,6 +21,9 @@ plugin {
csgo-vulkan-fix { csgo-vulkan-fix {
res_w = 1680 res_w = 1680
res_h = 1050 res_h = 1050
# NOT a regex! This is a string and has to exactly match initial_class
class = cs2
} }
} }
``` ```

View File

@ -16,43 +16,29 @@ typedef void (*origMotion)(wlr_seat*, uint32_t, double, double);
typedef void (*origSurfaceSize)(wlr_xwayland_surface*, int16_t, int16_t, uint16_t, uint16_t); typedef void (*origSurfaceSize)(wlr_xwayland_surface*, int16_t, int16_t, uint16_t, uint16_t);
typedef void (*origSurfaceDamage)(wlr_surface*, pixman_region32_t*); typedef void (*origSurfaceDamage)(wlr_surface*, pixman_region32_t*);
// store the surface for csgo. May be invalid, only compare against
inline wlr_surface* pCSGOSurface = nullptr;
inline wlr_xwayland_surface* pCSGOXWSurface = nullptr;
inline int csgoMonitor = 0;
// Do NOT change this function. // Do NOT change this function.
APICALL EXPORT std::string PLUGIN_API_VERSION() { APICALL EXPORT std::string PLUGIN_API_VERSION() {
return HYPRLAND_API_VERSION; return HYPRLAND_API_VERSION;
} }
void onNewWindow(void* self, std::any data) {
// data is guaranteed
auto* const PWINDOW = std::any_cast<CWindow*>(data);
if (g_pXWaylandManager->getAppIDClass(PWINDOW) == "cs2") {
pCSGOSurface = g_pXWaylandManager->getWindowSurface(PWINDOW);
pCSGOXWSurface = PWINDOW->m_uSurface.xwayland;
csgoMonitor = PWINDOW->m_iMonitorID;
}
}
void hkNotifyMotion(wlr_seat* wlr_seat, uint32_t time_msec, double sx, double sy) { void hkNotifyMotion(wlr_seat* wlr_seat, uint32_t time_msec, double sx, double sy) {
static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue; static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue;
static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue; static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue;
static auto* const PCLASS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->strValue;
if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_szInitialClass == "cs2" && g_pCompositor->m_pLastMonitor) { if (g_pCompositor->m_pLastWindow && g_pCompositor->m_pLastWindow->m_szInitialClass == *PCLASS && g_pCompositor->m_pLastMonitor) {
// fix the coords // fix the coords
sx *= *RESX / g_pCompositor->m_pLastMonitor->vecSize.x; sx *= (*RESX / g_pCompositor->m_pLastMonitor->vecSize.x) / g_pCompositor->m_pLastWindow->m_fX11SurfaceScaledBy;
sy *= *RESY / g_pCompositor->m_pLastMonitor->vecSize.y; sy *= (*RESY / g_pCompositor->m_pLastMonitor->vecSize.y) / g_pCompositor->m_pLastWindow->m_fX11SurfaceScaledBy;
} }
(*(origMotion)g_pMouseMotionHook->m_pOriginal)(wlr_seat, time_msec, sx, sy); (*(origMotion)g_pMouseMotionHook->m_pOriginal)(wlr_seat, time_msec, sx, sy);
} }
void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16_t width, uint16_t height) { void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16_t width, uint16_t height) {
static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue; static auto* const RESX = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w")->intValue;
static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue; static auto* const RESY = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h")->intValue;
static auto* const PCLASS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->strValue;
if (!surface) { if (!surface) {
(*(origSurfaceSize)g_pSurfaceSizeHook->m_pOriginal)(surface, x, y, width, height); (*(origSurfaceSize)g_pSurfaceSizeHook->m_pOriginal)(surface, x, y, width, height);
@ -62,7 +48,7 @@ void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16
const auto SURF = surface->surface; const auto SURF = surface->surface;
const auto PWINDOW = g_pCompositor->getWindowFromSurface(SURF); const auto PWINDOW = g_pCompositor->getWindowFromSurface(SURF);
if (PWINDOW && PWINDOW->m_szInitialClass == "cs2") { if (PWINDOW && PWINDOW->m_szInitialClass == *PCLASS) {
width = *RESX; width = *RESX;
height = *RESY; height = *RESY;
@ -75,12 +61,12 @@ void hkSetWindowSize(wlr_xwayland_surface* surface, int16_t x, int16_t y, uint16
void hkSurfaceDamage(wlr_surface* surface, pixman_region32_t* damage) { void hkSurfaceDamage(wlr_surface* surface, pixman_region32_t* damage) {
(*(origSurfaceDamage)g_pSurfaceDamageHook->m_pOriginal)(surface, damage); (*(origSurfaceDamage)g_pSurfaceDamageHook->m_pOriginal)(surface, damage);
if (surface == pCSGOSurface) { static auto* const PCLASS = &HyprlandAPI::getConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class")->strValue;
const auto PMONITOR = g_pCompositor->getMonitorFromID(csgoMonitor);
if (PMONITOR) const auto SURF = CWLSurface::surfaceFromWlr(surface);
pixman_region32_union_rect(damage, damage, 0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
} if (SURF && SURF->exists() && SURF->m_pOwner && SURF->m_pOwner->m_szInitialClass == *PCLASS)
g_pHyprRenderer->damageWindow(SURF->m_pOwner);
} }
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) { APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
@ -88,6 +74,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w", SConfigValue{.intValue = 1680}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_w", SConfigValue{.intValue = 1680});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h", SConfigValue{.intValue = 1050}); HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:res_h", SConfigValue{.intValue = 1050});
HyprlandAPI::addConfigValue(PHANDLE, "plugin:csgo-vulkan-fix:class", SConfigValue{.strValue = "cs2"});
g_pMouseMotionHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_seat_pointer_notify_motion, (void*)&hkNotifyMotion); g_pMouseMotionHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_seat_pointer_notify_motion, (void*)&hkNotifyMotion);
g_pSurfaceSizeHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_xwayland_surface_configure, (void*)&hkSetWindowSize); g_pSurfaceSizeHook = HyprlandAPI::createFunctionHook(PHANDLE, (void*)&wlr_xwayland_surface_configure, (void*)&hkSetWindowSize);
@ -96,16 +83,14 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
hkResult = hkResult && g_pSurfaceSizeHook->hook(); hkResult = hkResult && g_pSurfaceSizeHook->hook();
hkResult = hkResult && g_pSurfaceDamageHook->hook(); hkResult = hkResult && g_pSurfaceDamageHook->hook();
HyprlandAPI::registerCallbackDynamic(PHANDLE, "openWindow", [&](void* self, SCallbackInfo& info, std::any data) { onNewWindow(self, data); });
if (hkResult) if (hkResult)
HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Initialized successfully! (CS2 version)", CColor{0.2, 1.0, 0.2, 1.0}, 5000); HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Initialized successfully! (Anything version)", CColor{0.2, 1.0, 0.2, 1.0}, 5000);
else { else {
HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Failure in initialization (hook failed)!", CColor{1.0, 0.2, 0.2, 1.0}, 5000); HyprlandAPI::addNotification(PHANDLE, "[csgo-vulkan-fix] Failure in initialization (hook failed)!", CColor{1.0, 0.2, 0.2, 1.0}, 5000);
throw std::runtime_error("[csgo-vk-fix] Hooks failed"); throw std::runtime_error("[csgo-vk-fix] Hooks failed");
} }
return {"csgo-vulkan-fix", "A plugin to fix incorrect mouse offsets on csgo in Vulkan", "Vaxry", "1.1"}; return {"csgo-vulkan-fix", "A plugin to force specific apps to a fake resolution", "Vaxry", "1.2"};
} }
APICALL EXPORT void PLUGIN_EXIT() { APICALL EXPORT void PLUGIN_EXIT() {