Moved mouse-state code to a separate file, enabled mouse-look camera-mode for DXGI (#86)

This commit is contained in:
Radek Krzyśków 2024-06-30 21:44:40 +02:00 committed by GitHub
parent 06a57eb367
commit 4713219388
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 169 additions and 91 deletions

View file

@ -12,13 +12,6 @@
// moved these from sdl controller implementations
int mouse_x;
int mouse_y;
int mouse_window_buttons;
int mouse_window_x;
int mouse_window_y;
static struct ControllerAPI *controller_implementations[] = {
#if defined(CAPI_SDL2) || defined(CAPI_SDL1)
&controller_sdl,

View file

@ -0,0 +1,121 @@
#include "controller_mouse.h"
#ifdef WAPI_DXGI
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern HWND gfx_dxgi_get_h_wnd(void);
static bool mouse_relative_prev_cursor_state;
#elif defined(CAPI_SDL1)
#include <SDL/SDL.h>
#elif defined(CAPI_SDL2)
#include <SDL2/SDL.h>
#endif
bool mouse_init_ok;
u32 mouse_buttons;
s32 mouse_x;
s32 mouse_y;
u32 mouse_window_buttons;
s32 mouse_window_x;
s32 mouse_window_y;
static bool mouse_relative_enabled;
void controller_mouse_read_window(void) {
if (!mouse_init_ok) { return; }
#if defined(WAPI_DXGI)
mouse_window_buttons =
(GetAsyncKeyState(VK_LBUTTON) ? (1 << 0) : 0) |
(GetAsyncKeyState(VK_MBUTTON) ? (1 << 1) : 0) |
(GetAsyncKeyState(VK_RBUTTON) ? (1 << 2) : 0);
POINT p;
if (GetCursorPos(&p) && ScreenToClient(gfx_dxgi_get_h_wnd(), &p)) {
mouse_window_x = p.x;
mouse_window_y = p.y;
}
#elif defined(CAPI_SDL1) || defined(CAPI_SDL2)
mouse_window_buttons = SDL_GetMouseState(&mouse_window_x, &mouse_window_y);
#endif
}
void controller_mouse_read_relative(void) {
if (!mouse_init_ok) { return; }
#if defined(WAPI_DXGI)
mouse_buttons =
(GetAsyncKeyState(VK_LBUTTON) ? (1 << 0) : 0) |
(GetAsyncKeyState(VK_MBUTTON) ? (1 << 1) : 0) |
(GetAsyncKeyState(VK_RBUTTON) ? (1 << 2) : 0);
if (mouse_relative_enabled) {
static POINT p0;
POINT p1;
RECT rect;
if (GetWindowRect(gfx_dxgi_get_h_wnd(), &rect) && GetCursorPos(&p1)) {
mouse_x = p1.x - p0.x;
mouse_y = p1.y - p0.y;
p0.x = rect.left + (rect.right - rect.left) / 2;
p0.y = rect.top + (rect.bottom - rect.top) / 2;
SetCursorPos(p0.x, p0.y);
}
} else {
mouse_x = 0;
mouse_y = 0;
}
#elif defined(CAPI_SDL1) || defined(CAPI_SDL2)
mouse_buttons = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
#endif
}
void controller_mouse_enter_relative(void) {
if (!mouse_relative_enabled) {
mouse_relative_enabled = true;
#if defined(WAPI_DXGI)
CURSORINFO ci;
ci.cbSize = sizeof(CURSORINFO);
if (GetCursorInfo(&ci)) {
mouse_relative_prev_cursor_state = (0 != ci.flags);
} else {
mouse_relative_prev_cursor_state = false;
}
ShowCursor(FALSE);
#elif defined(CAPI_SDL1)
SDL_WM_GrabInput(SDL_GRAB_ON);
#elif defined(CAPI_SDL2)
SDL_SetRelativeMouseMode(SDL_TRUE);
#endif
}
}
void controller_mouse_leave_relative(void) {
if (mouse_relative_enabled) {
mouse_relative_enabled = false;
#if defined(WAPI_DXGI)
ShowCursor(mouse_relative_prev_cursor_state);
#elif defined(CAPI_SDL1)
SDL_WM_GrabInput(SDL_GRAB_OFF);
#elif defined(CAPI_SDL2)
SDL_SetRelativeMouseMode(SDL_FALSE);
#endif
}
}

View file

@ -1,18 +1,23 @@
#ifndef CONTROLLER_MOUSE_H
#define CONTROLLER_MOUSE_H
#include "controller_api.h"
#include "controller_sdl.h"
#include <stdbool.h>
extern int mouse_x;
extern int mouse_y;
extern bool mouse_init_ok;
extern int mouse_window_buttons;
extern int mouse_window_x;
extern int mouse_window_y;
extern u32 mouse_buttons;
extern s32 mouse_x;
extern s32 mouse_y;
extern u32 mouse_window_buttons;
extern s32 mouse_window_x;
extern s32 mouse_window_y;
#define VK_BASE_MOUSE 0x2000
void controller_mouse_read_window(void);
void controller_mouse_read_relative(void);
extern struct ControllerAPI controller_mouse;
void controller_mouse_enter_relative(void);
void controller_mouse_leave_relative(void);
#endif

View file

@ -5,12 +5,10 @@
#define VK_BASE_SDL_GAMEPAD 0x1000
// mouse buttons are also in the controller namespace (why), just offset 0x100
// mouse buttons are also in the controller namespace, just offset 0x100
#define VK_OFS_SDL_MOUSE 0x0100
#define VK_BASE_SDL_MOUSE (VK_BASE_SDL_GAMEPAD + VK_OFS_SDL_MOUSE)
extern struct ControllerAPI controller_sdl;
void controller_sdl_read_mouse_window(void);
#endif

View file

@ -124,14 +124,16 @@ static void controller_sdl_init(void) {
if (i >= num_joy_axes)
joy_axis_binds[i] = -1;
}
if (newcam_mouse == 1 && gMenuMode == -1 && !gDjuiChatBoxFocus && !gDjuiConsoleFocus)
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
if (newcam_mouse == 1 && gMenuMode == -1 && !gDjuiChatBoxFocus && !gDjuiConsoleFocus) {
controller_mouse_enter_relative();
}
controller_mouse_read_relative();
controller_sdl_bind();
init_ok = true;
mouse_init_ok = true;
}
static inline void update_button(const int i, const bool new) {
@ -151,12 +153,15 @@ extern s16 gMenuMode;
static void controller_sdl_read(OSContPad *pad) {
if (!init_ok) return;
if (newcam_mouse == 1 && gMenuMode == -1 && !gDjuiChatBoxFocus && !gDjuiConsoleFocus)
SDL_WM_GrabInput(SDL_GRAB_ON);
else
SDL_WM_GrabInput(SDL_GRAB_OFF);
u32 mouse = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
if (newcam_mouse == 1 && gMenuMode == -1 && !gDjuiChatBoxFocus && !gDjuiConsoleFocus) {
controller_mouse_enter_relative();
} else {
controller_mouse_leave_relative();
}
u32 mouse_prev = mouse_buttons;
controller_mouse_read_relative();
u32 mouse = mouse_buttons;
if (!gInteractableOverridePad) {
for (u32 i = 0; i < num_mouse_binds; ++i)
@ -165,8 +170,7 @@ static void controller_sdl_read(OSContPad *pad) {
}
// remember buttons that changed from 0 to 1
last_mouse = (mouse_buttons ^ mouse) & mouse;
mouse_buttons = mouse;
last_mouse = (mouse_prev ^ mouse) & mouse;
if (configDisableGamepads) { return; }
if (!sdl_joy) return;
@ -229,25 +233,6 @@ static void controller_sdl_read(OSContPad *pad) {
}
}
void controller_sdl_read_mouse_window(void) {
if (!init_ok) { return; }
#if defined(_WIN32) && (defined(RAPI_D3D12) || defined(RAPI_D3D11))
mouse_window_buttons = 0;
mouse_window_buttons |= (GetAsyncKeyState(VK_LBUTTON) ? (1 << 0) : 0);
mouse_window_buttons |= (GetAsyncKeyState(VK_RBUTTON) ? (1 << 1) : 0);
POINT p;
if (GetCursorPos(&p) && ScreenToClient(GetActiveWindow(), &p))
{
mouse_window_x = p.x;
mouse_window_y = p.y;
}
#else
mouse_window_buttons = SDL_GetMouseState(&mouse_window_x, &mouse_window_y);
#endif
}
static void controller_sdl_rumble_play(f32 strength, f32 length) { }
static void controller_sdl_rumble_stop(void) { }
@ -279,6 +264,7 @@ static void controller_sdl_shutdown(void) {
}
init_ok = false;
mouse_init_ok = false;
}
struct ControllerAPI controller_sdl = {

View file

@ -48,7 +48,6 @@ static u32 joy_binds[MAX_JOYBINDS][2] = { 0 };
static u32 mouse_binds[MAX_JOYBINDS][2] = { 0 };
static bool joy_buttons[MAX_JOYBUTTONS] = { false };
static u32 mouse_buttons = 0;
static u32 last_mouse = VK_INVALID;
static u32 last_joybutton = VK_INVALID;
static u32 last_gamepad = 0;
@ -124,13 +123,13 @@ static void controller_sdl_init(void) {
free(gcdata);
}
if (newcam_mouse == 1)
SDL_SetRelativeMouseMode(SDL_TRUE);
SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
if (newcam_mouse == 1) { controller_mouse_enter_relative(); }
controller_mouse_read_relative();
controller_sdl_bind();
init_ok = true;
mouse_init_ok = true;
}
static SDL_Haptic *controller_sdl_init_haptics(const int joy) {
@ -169,17 +168,17 @@ static inline void update_button(const int i, const bool new) {
extern s16 gMenuMode;
static void controller_sdl_read(OSContPad *pad) {
if (!init_ok) {
return;
}
if (!init_ok) { return; }
if ((newcam_mouse == 1 || gFirstPersonCamera.enabled || gDjuiHudLockMouse) && gMenuMode == -1 && !gDjuiInMainMenu && !gDjuiChatBoxFocus && !gDjuiConsoleFocus && WAPI.has_focus()) {
SDL_SetRelativeMouseMode(SDL_TRUE);
controller_mouse_enter_relative();
} else {
SDL_SetRelativeMouseMode(SDL_FALSE);
controller_mouse_leave_relative();
}
u32 mouse = SDL_GetRelativeMouseState(&mouse_x, &mouse_y);
u32 mouse_prev = mouse_buttons;
controller_mouse_read_relative();
u32 mouse = mouse_buttons;
if (!gInteractableOverridePad) {
for (u32 i = 0; i < num_mouse_binds; ++i)
@ -187,8 +186,7 @@ static void controller_sdl_read(OSContPad *pad) {
pad->button |= mouse_binds[i][1];
}
// remember buttons that changed from 0 to 1
last_mouse = (mouse_buttons ^ mouse) & mouse;
mouse_buttons = mouse;
last_mouse = (mouse_prev ^ mouse) & mouse;
if (configBackgroundGamepad != sBackgroundGamepad) {
sBackgroundGamepad = configBackgroundGamepad;
@ -221,7 +219,7 @@ static void controller_sdl_read(OSContPad *pad) {
return;
}
}
int16_t leftx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_LEFTX);
int16_t lefty = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_LEFTY);
int16_t rightx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTX);
@ -278,24 +276,6 @@ static void controller_sdl_read(OSContPad *pad) {
}
}
void controller_sdl_read_mouse_window(void) {
if (!init_ok) { return; }
#if defined(_WIN32) && (defined(RAPI_D3D12) || defined(RAPI_D3D11))
mouse_window_buttons = 0;
mouse_window_buttons |= (GetAsyncKeyState(VK_LBUTTON) ? (1 << 0) : 0);
mouse_window_buttons |= (GetAsyncKeyState(VK_RBUTTON) ? (1 << 1) : 0);
POINT p;
if (GetCursorPos(&p) && ScreenToClient(GetActiveWindow(), &p))
{
mouse_window_x = p.x;
mouse_window_y = p.y;
}
#else
mouse_window_buttons = SDL_GetMouseState(&mouse_window_x, &mouse_window_y);
#endif
}
static void controller_sdl_rumble_play(f32 strength, f32 length) {
if (sdl_haptic)
SDL_HapticRumblePlay(sdl_haptic, strength, (u32)(length * 1000.0f));
@ -342,6 +322,7 @@ static void controller_sdl_shutdown(void) {
haptics_enabled = false;
init_ok = false;
mouse_init_ok = false;
}
struct ControllerAPI controller_sdl = {

View file

@ -1,7 +1,6 @@
#include "djui.h"
#include "djui_panel.h"
#include "pc/controller/controller_mouse.h"
#include "pc/controller/controller_sdl.h"
#include "pc/gfx/gfx_window_manager_api.h"
#include "pc/pc_main.h"
@ -118,7 +117,7 @@ void djui_cursor_update(void) {
if (sMouseCursor == NULL) { return; }
if (!djui_panel_is_active()) { return; }
controller_sdl_read_mouse_window();
controller_mouse_read_window();
// check if mouse is in control again
static bool sFirstUpdate = true;

View file

@ -3,7 +3,6 @@
#include <PR/gbi.h>
#include <string.h>
#include "pc/controller/controller_sdl.h"
#include "pc/controller/controller_mouse.h"
#include "pc/gfx/gfx_pc.h"
#include "pc/gfx/gfx_window_manager_api.h"
@ -235,16 +234,12 @@ u32 djui_hud_get_screen_height(void) {
}
f32 djui_hud_get_mouse_x(void) {
#ifdef HAVE_SDL2
controller_sdl_read_mouse_window();
#endif
controller_mouse_read_window();
return mouse_window_x / djui_gfx_get_scale();
}
f32 djui_hud_get_mouse_y(void) {
#ifdef HAVE_SDL2
controller_sdl_read_mouse_window();
#endif
controller_mouse_read_window();
return mouse_window_y / djui_gfx_get_scale();
}

View file

@ -708,7 +708,7 @@ static bool gfx_dxgi_has_focus(void) {
return GetFocus() == dxgi.h_wnd;
}
HWND gfx_dxgi_get_h_wnd(void) {
extern "C" HWND gfx_dxgi_get_h_wnd(void) {
return dxgi.h_wnd;
}

View file

@ -6,7 +6,7 @@
#ifdef DECLARE_GFX_DXGI_FUNCTIONS
void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only));
Microsoft::WRL::ComPtr<IDXGISwapChain1> gfx_dxgi_create_swap_chain(IUnknown *device);
HWND gfx_dxgi_get_h_wnd(void);
extern "C" HWND gfx_dxgi_get_h_wnd(void);
void ThrowIfFailed(HRESULT res);
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message);
#endif