Skip to content

Commit

Permalink
Rewrite cursor tracking, stop mouse warping
Browse files Browse the repository at this point in the history
  • Loading branch information
Sumandora committed Sep 12, 2023
1 parent f35ae89 commit 9cd6083
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 33 deletions.
7 changes: 6 additions & 1 deletion Source/Features/General/Menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ void Menu::MenuKey::onChange()
{
Gui::visible = !Gui::visible;
eventLog.createReport("%s the menu", Gui::visible ? "Opened" : "Closed");
reinterpret_cast<int (*)(SDL_bool)>(Hooks::SDL::SetRelativeMouseMode::hook->proxy)(Gui::visible ? SDL_FALSE : Hooks::SDL::relativeMouseMode);
if (Gui::visible) {
ImGuiIO& io = ImGui::GetIO();
reinterpret_cast<void (*)(SDL_Window*, int, int)>(Hooks::SDL::WarpMouseInWindow::hook->proxy)(Hooks::SDL::windowPtr, (int)io.MousePos.x, (int)io.MousePos.y);
}
}

void Menu::imGuiLoop()
void Menu::imGuiLoop() const
{
switch (style) {
case 0:
Expand Down
2 changes: 1 addition & 1 deletion Source/Features/General/Menu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ inline class Menu : public Feature {
bool isShowingUserGuide = false;
#endif

void imGuiLoop();
void imGuiLoop() const;

virtual void setupGUI() override;
virtual SERIALIZER() override;
Expand Down
55 changes: 26 additions & 29 deletions Source/GUI/GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <mutex>
#include <unordered_map>

#include "Elements/Keybind.hpp"
#include "imgui.h"
Expand All @@ -14,8 +11,6 @@
#include "backends/imgui_impl_opengl3.h"
#include "backends/imgui_impl_sdl2.h"

#include "../Hooks/SDL/SDLFunctions.hpp"

#include "../Features/General/EventLog.hpp"
#include "../Features/General/Menu.hpp"
#include "../Features/General/Watermark.hpp"
Expand All @@ -26,8 +21,6 @@
#include "../Features/Visuals/ESP/ESP.hpp"
#include "../Features/Visuals/SpectatorList.hpp"

#include "../Serialization/Serialization.hpp"

bool Gui::visible = true;

void Gui::create()
Expand Down Expand Up @@ -119,6 +112,8 @@ void Gui::swapWindow(SDL_Window* window)
esp.imGuiRender(ImGui::GetBackgroundDrawList());
spectatorList.imGuiRender(ImGui::GetBackgroundDrawList());

ImGui::GetForegroundDrawList()->AddRectFilled({ io.MousePos.x - 5, io.MousePos.y - 5 }, { io.MousePos.x + 5, io.MousePos.y + 5 }, ImGuiColors::red);

io.MouseDrawCursor = visible;
io.WantCaptureMouse = visible;
io.WantCaptureKeyboard = visible;
Expand All @@ -127,37 +122,39 @@ void Gui::swapWindow(SDL_Window* window)
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

// I don't even want to know why I have to do this
static Uint32 lastTextInput;

bool Gui::pollEvent(SDL_Event* event)
{
if (event->type == SDL_TEXTINPUT && lastTextInput >= event->text.timestamp)
return visible;

ImGuiIO& io = ImGui::GetIO();
// Emulate these 2 events, because ImGui is broken... :c
if (event->type == SDL_MOUSEMOTION) {
int x, y;
SDL_GetMouseState(&x, &y);
static Uint32 lastEvent;
if (event->type == SDL_TEXTINPUT) {
if (event->text.timestamp <= lastEvent)
return visible; // Not quite sure, why I have to do this
lastEvent = event->text.timestamp;
}

io.MousePos.x = (float)x;
io.MousePos.y = (float)y;
if (visible && SDL_GetMouseFocus() == Hooks::SDL::windowPtr)
reinterpret_cast<void (*)(SDL_Window*, int, int)>(Hooks::SDL::WarpMouseInWindow::hook->proxy)(Hooks::SDL::windowPtr, (int)io.MousePos.x, (int)io.MousePos.y);
} else if (event->type == SDL_MOUSEWHEEL) {
io.MouseWheelH += (float)event->wheel.x;
io.MouseWheel += (float)event->wheel.y;
#if SDL_VERSION_ATLEAST(2, 0, 18)
// CS:GOs SDL is 2.0.15, however we can't realistically expect users to download this ancient version, so just do this
// preciseX/Y got introduced in 2.0.18
if (event->type == SDL_MOUSEWHEEL) {
SDL_MouseWheelEvent sdlMouseWheelEvent{};
sdlMouseWheelEvent.type = SDL_MOUSEWHEEL;
sdlMouseWheelEvent.preciseX = (float)event->wheel.x;
sdlMouseWheelEvent.preciseY = (float)event->wheel.y;
SDL_Event newEvent;
newEvent.wheel = sdlMouseWheelEvent;
ImGui_ImplSDL2_ProcessEvent(&newEvent);
} else
#endif
ImGui_ImplSDL2_ProcessEvent(event);

if (event->type == SDL_TEXTINPUT)
lastTextInput = event->text.timestamp;

return visible;
}

bool Gui::warpMouseInWindow()
bool Gui::warpMouseInWindow(int x, int y)
{
if (!visible) {
ImGuiIO& io = ImGui::GetIO();
io.MousePos.x = (float)x;
io.MousePos.y = (float)y;
}
return visible;
}
2 changes: 1 addition & 1 deletion Source/GUI/GUI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Gui {

void swapWindow(SDL_Window* window);
bool pollEvent(SDL_Event* event);
bool warpMouseInWindow();
bool warpMouseInWindow(int x, int y);
}

#endif
11 changes: 11 additions & 0 deletions Source/Hooks/SDL/Functions/SetRelativeMouseMode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "../SDLFunctions.hpp"

#include "../../../GUI/GUI.hpp"

int Hooks::SDL::SetRelativeMouseMode::hookFunc(SDL_bool enabled)
{
relativeMouseMode = enabled;
if(!Gui::visible)
return reinterpret_cast<int (*)(SDL_bool enabled)>(hook->proxy)(enabled);
return 0; // :thumbsup:
}
2 changes: 1 addition & 1 deletion Source/Hooks/SDL/Functions/WarpMouseInWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

void Hooks::SDL::WarpMouseInWindow::hookFunc(SDL_Window* window, int x, int y)
{
if (Gui::warpMouseInWindow())
if (Gui::warpMouseInWindow(x, y))
return;

return reinterpret_cast<void (*)(SDL_Window*, int, int)>(hook->proxy)(window, x, y);
Expand Down
2 changes: 2 additions & 0 deletions Source/Hooks/SDL/SDLFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ void Hooks::SDL::hook()
WarpMouseInWindow::hook = new SDLHook(reinterpret_cast<void*>(SDL_WarpMouseInWindow), reinterpret_cast<void*>(WarpMouseInWindow::hookFunc));
SwapWindow::hook = new SDLHook(reinterpret_cast<void*>(SDL_GL_SwapWindow), reinterpret_cast<void*>(SwapWindow::hookFunc));
PollEvent::hook = new SDLHook(reinterpret_cast<void*>(SDL_PollEvent), reinterpret_cast<void*>(PollEvent::hookFunc));
SetRelativeMouseMode::hook = new SDLHook(reinterpret_cast<void*>(SDL_SetRelativeMouseMode), reinterpret_cast<void*>(SetRelativeMouseMode::hookFunc));
}

void Hooks::SDL::unhook()
{
delete SetRelativeMouseMode::hook;
delete PollEvent::hook;
delete SwapWindow::hook;
delete WarpMouseInWindow::hook;
Expand Down
19 changes: 19 additions & 0 deletions Source/Hooks/SDL/SDLFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ namespace Hooks::SDL {
inline SDL_Window* windowPtr = nullptr;
inline bool shuttingDown = false;

inline struct BackupVariable {
SDL_bool enabled = SDL_GetRelativeMouseMode();
~BackupVariable() { SDL_SetRelativeMouseMode(enabled); }

inline SDL_bool& operator=(SDL_bool other) {
enabled = other;
return enabled;
}
inline operator SDL_bool() const {
return enabled;
}
} relativeMouseMode;

namespace SwapWindow {
inline SDLHook* hook;

Expand All @@ -33,6 +46,12 @@ namespace Hooks::SDL {
void hookFunc(SDL_Window* window);
}

namespace SetRelativeMouseMode {
inline SDLHook* hook;

int hookFunc(SDL_bool enabled);
}

void hook();
void unhook();
}
Expand Down

0 comments on commit 9cd6083

Please sign in to comment.