mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 11:18:40 +00:00
font rendering fixed, input (WASD and camera rotation) still a little bit buggy
This commit is contained in:
parent
c7db2069c0
commit
c2f4862f22
|
|
@ -186,6 +186,14 @@ void font_from_file(
|
|||
|
||||
memcpy(font->glyphs, pos, font->glyph_count * sizeof(Glyph));
|
||||
|
||||
#if OPENGL
|
||||
for (int32 i = 0; i < font->glyph_count; ++i) {
|
||||
float temp = font->glyphs[i].coords.y1;
|
||||
font->glyphs[i].coords.y1 = 1.0f - font->glyphs[i].coords.y2;
|
||||
font->glyphs[i].coords.y2 = 1.0f - temp;
|
||||
}
|
||||
#endif
|
||||
|
||||
SWAP_ENDIAN_LITTLE_SIMD(
|
||||
(int32 *) font->glyphs,
|
||||
(int32 *) font->glyphs,
|
||||
|
|
|
|||
|
|
@ -105,107 +105,4 @@ uint32 hash_ejb(const char* str)
|
|||
return h % PRIME2;
|
||||
}
|
||||
|
||||
// CONSTEXPR
|
||||
|
||||
constexpr
|
||||
uint64 hash_djb2_const(const char* key) {
|
||||
uint64 hash = 5381;
|
||||
int32 c;
|
||||
|
||||
while ((c = *key++)) {
|
||||
hash = ((hash << 5) + hash) + c;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr
|
||||
uint64 hash_sdbm_const(const byte* key)
|
||||
{
|
||||
uint64 hash = 0;
|
||||
int32 c;
|
||||
|
||||
while (c = *key++) {
|
||||
hash = c + (hash << 6) + (hash << 16) - hash;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr
|
||||
uint64 hash_lose_lose_const(const byte* key)
|
||||
{
|
||||
uint64 hash = 0;
|
||||
int32 c;
|
||||
|
||||
while (c = *key++) {
|
||||
hash += c;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr
|
||||
uint64 hash_polynomial_rolling_const(const char* str) {
|
||||
const int32 p = 31;
|
||||
const int32 m = 1000000009;
|
||||
uint64 hash = 0;
|
||||
uint64 p_pow = 1;
|
||||
|
||||
while (*str) {
|
||||
hash = (hash + (*str - 'a' + 1) * p_pow) % m;
|
||||
p_pow = (p_pow * p) % m;
|
||||
str++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr
|
||||
uint64 hash_fnv1a_const(const char* str) {
|
||||
const uint64 FNV_OFFSET_BASIS = 14695981039346656037UL;
|
||||
const uint64 FNV_PRIME = 1099511628211UL;
|
||||
uint64 hash = FNV_OFFSET_BASIS;
|
||||
|
||||
while (*str) {
|
||||
hash ^= (byte) *str;
|
||||
hash *= FNV_PRIME;
|
||||
str++;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr
|
||||
uint32 hash_oat_const(const char* str)
|
||||
{
|
||||
uint32 h = 0;
|
||||
|
||||
while(*str) {
|
||||
h += *str++;
|
||||
h += (h << 10);
|
||||
h ^= (h >> 6);
|
||||
}
|
||||
|
||||
h += (h << 3);
|
||||
h ^= (h >> 11);
|
||||
h += (h << 15);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
constexpr
|
||||
uint32 hash_ejb_const(const char* str)
|
||||
{
|
||||
const uint32 PRIME1 = 37;
|
||||
const uint32 PRIME2 = 1048583;
|
||||
uint32 h = 0;
|
||||
|
||||
while (*str) {
|
||||
h = h * PRIME1 ^ (*str++ - ' ');
|
||||
}
|
||||
|
||||
return h % PRIME2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
struct Image {
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 pixel_count;
|
||||
uint32 pixel_count; // @question Do we even need this?
|
||||
|
||||
// Image settings
|
||||
bool has_alpha;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "../utils/BitUtils.h"
|
||||
#include "../memory/BufferMemory.h"
|
||||
#include "ControllerInput.h"
|
||||
#include "InputConnectionType.h"
|
||||
|
||||
// How many concurrent mouse/secondary input device presses to we recognize
|
||||
#define MAX_MOUSE_PRESSES 3
|
||||
|
|
@ -50,6 +51,7 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
|
||||
typedef void (*InputCallback)(void* data);
|
||||
|
|
@ -117,14 +119,18 @@ struct InputState {
|
|||
|
||||
struct Input {
|
||||
// Device
|
||||
bool is_connected;
|
||||
InputConnectionType connection_type;
|
||||
|
||||
#ifdef _WIN32
|
||||
// @question maybe replace with id?!
|
||||
// -> remove _WIN32 section?
|
||||
HANDLE handle_keyboard;
|
||||
HANDLE handle_mouse;
|
||||
HANDLE handle_controller;
|
||||
|
||||
// @todo support all three versions
|
||||
int32 controller_id; // used by XInput
|
||||
HANDLE handle_controller; // used by raw input controller
|
||||
LPDIRECTINPUTDEVICE8* direct_controller; // used by direct input controller
|
||||
#endif
|
||||
|
||||
bool state_change_button;
|
||||
|
|
|
|||
21
input/InputConnectionType.h
Normal file
21
input/InputConnectionType.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_INPUT_CONNECTION_TYPE_H
|
||||
#define TOS_PLATFORM_WIN32_INPUT_CONNECTION_TYPE_H
|
||||
|
||||
// Important, since some connection protocols differ between for example USB and Bluetooth (see Playstation DualSense)
|
||||
enum InputConnectionType {
|
||||
INPUT_CONNECTION_TYPE_NONE,
|
||||
INPUT_CONNECTION_TYPE_USB,
|
||||
INPUT_CONNECTION_TYPE_BLUETOOTH,
|
||||
INPUT_CONNECTION_TYPE_WIRELESS,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#include "../../platform/win32/input/controller/ControllerHandler.h"
|
||||
#else __linux__
|
||||
#include <linux/limits.h>
|
||||
#define MAX_PATH PATH_MAX
|
||||
|
|
@ -352,6 +353,8 @@ struct CSettings {
|
|||
byte game_interact_radius = 1;
|
||||
|
||||
// Game pad settings
|
||||
byte input_device_types = SETTING_INPUT_DEVICE_TYPE_MOUSE_KEYBOARD;
|
||||
byte input_controller_handler = CONTROLLER_HANDLER_TYPE_AUTO;
|
||||
byte stick_left_deadzone = 0;
|
||||
byte stick_right_deadzone = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,4 +78,7 @@
|
|||
#define SETTING_UI_VISIBILITY_DEBUG 2
|
||||
#define SETTING_UI_VISIBILITY_WIREFRAME 4
|
||||
|
||||
#define SETTING_INPUT_DEVICE_TYPE_MOUSE_KEYBOARD 1
|
||||
#define SETTING_INPUT_DEVICE_TYPE_CONTROLLER 2
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_INPUT_DIRECTINPUT_H
|
||||
#define TOS_PLATFORM_WIN32_INPUT_DIRECTINPUT_H
|
||||
|
||||
#include <dinput.h>
|
||||
#include "../../../input/Input.h"
|
||||
#include "../../../input/ControllerInput.h"
|
||||
#include "../../../stdlib/Types.h"
|
||||
|
||||
BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* instance, void* pDevicePtr)
|
||||
{
|
||||
LPDIRECTINPUT8 pDirectInput = (LPDIRECTINPUT8)pDevicePtr;
|
||||
LPDIRECTINPUTDEVICE8* pDIDevice = (LPDIRECTINPUTDEVICE8*)pDevicePtr;
|
||||
|
||||
if (SUCCEEDED(pDirectInput->CreateDevice(instance->guidInstance, pDIDevice, NULL))) {
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
int32 directinput_init_controllers(HWND hwnd, Input* __restrict states)
|
||||
{
|
||||
LPDIRECTINPUT8* pDirectInput = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
// Initialize DirectInput interface if it’s not already initialized
|
||||
hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)pDirectInput, NULL);
|
||||
if (FAILED(hr)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Enumerate devices to find a connected game controller
|
||||
hr = (*pDirectInput)->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, states->direct_controller, DIEDFL_ATTACHEDONLY);
|
||||
if (FAILED(hr) || *states->direct_controller == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set data format for the device to use the joystick state format
|
||||
hr = (*states->direct_controller)->SetDataFormat(&c_dfDIJoystick2);
|
||||
if (FAILED(hr)) {
|
||||
(*states->direct_controller)->Release();
|
||||
*states->direct_controller = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the cooperative level for the device
|
||||
hr = (*states->direct_controller)->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
|
||||
if (FAILED(hr)) {
|
||||
(*states->direct_controller)->Release();
|
||||
*states->direct_controller = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Acquire the device for use
|
||||
hr = (*states->direct_controller)->Acquire();
|
||||
if (FAILED(hr)) {
|
||||
(*states->direct_controller)->Release();
|
||||
*states->direct_controller = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline void input_map_directinput(ControllerInput* controller, LPDIRECTINPUTDEVICE8 pDIDevice)
|
||||
{
|
||||
if (FAILED(pDIDevice->Poll())) {
|
||||
if (FAILED(pDIDevice->Acquire())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Define a buffer for DirectInput state
|
||||
DIJOYSTATE2 controller_state;
|
||||
if (FAILED(pDIDevice->GetDeviceState(sizeof(DIJOYSTATE2), &controller_state))) {
|
||||
return;
|
||||
}
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = (controller_state.rgdwPOV[0] == 0) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = (controller_state.rgdwPOV[0] == 9000) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = (controller_state.rgdwPOV[0] == 18000) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = (controller_state.rgdwPOV[0] == 27000) ? 127 : 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_0] = (controller_state.rgbButtons[7] & 0x80) ? 127 : 0; // Start
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_1] = (controller_state.rgbButtons[6] & 0x80) ? 127 : 0; // Back
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_BUTTON] = (controller_state.rgbButtons[5] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_BUTTON] = (controller_state.rgbButtons[4] & 0x80) ? 127 : 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = controller_state.lZ > 0 ? controller_state.lZ : 0;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = controller_state.lZ < 0 ? -controller_state.lZ : 0;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_T] = (controller_state.rgbButtons[3] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_C] = (controller_state.rgbButtons[1] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_X] = (controller_state.rgbButtons[0] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_S] = (controller_state.rgbButtons[2] & 0x80) ? 127 : 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = controller_state.lX;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = controller_state.lY;
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = true;
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = true;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_BUTTON] = (controller_state.rgbButtons[8] & 0x80) ? 127 : 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] = controller_state.lRx;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = controller_state.lRy;
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] = true;
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = true;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_BUTTON] = (controller_state.rgbButtons[9] & 0x80) ? 127 : 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_2] = (controller_state.rgbButtons[10] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_3] = (controller_state.rgbButtons[11] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_4] = (controller_state.rgbButtons[12] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_5] = (controller_state.rgbButtons[13] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_6] = (controller_state.rgbButtons[14] & 0x80) ? 127 : 0;
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_7] = (controller_state.rgbButtons[15] & 0x80) ? 127 : 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
// Even if it is nowhere documented (at least not to our knowledge) the GetRawInputDeviceInfoA, GetRawInputBuffer functions requried
|
||||
// aligned memory. So far we only figured out that 4 bytes works, maybe this needs to be 8 in the future?!
|
||||
|
||||
int input_raw_init(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
||||
int rawinput_init_mousekeyboard(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
||||
{
|
||||
uint32 device_count;
|
||||
GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
|
@ -66,7 +66,7 @@ int input_raw_init(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
|||
}
|
||||
|
||||
states[mouse_found].handle_mouse = pRawInputDeviceList[i].hDevice;
|
||||
states[mouse_found].is_connected = true;
|
||||
states[mouse_found].connection_type = INPUT_CONNECTION_TYPE_USB;
|
||||
|
||||
// Mouse
|
||||
rid[0].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
|
||||
|
|
@ -85,7 +85,7 @@ int input_raw_init(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
|||
}
|
||||
|
||||
states[keyboard_found].handle_keyboard = pRawInputDeviceList[i].hDevice;
|
||||
states[keyboard_found].is_connected = true;
|
||||
states[keyboard_found].connection_type = INPUT_CONNECTION_TYPE_USB;
|
||||
|
||||
// Keyboard
|
||||
rid[0].usUsagePage = 0x01; // @todo doesn't work with 0x05 for games?
|
||||
|
|
@ -98,6 +98,40 @@ int input_raw_init(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
|||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int rawinput_init_controllers(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
||||
{
|
||||
uint32 device_count;
|
||||
GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST));
|
||||
PRAWINPUTDEVICELIST pRawInputDeviceList = (PRAWINPUTDEVICELIST) ring_get_memory(ring, sizeof(RAWINPUTDEVICELIST) * device_count, 4);
|
||||
device_count = GetRawInputDeviceList(pRawInputDeviceList, &device_count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
// We always want at least one empty input device slot
|
||||
// @todo Change so that we store the actual number of devices
|
||||
if (device_count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 cb_size = 256;
|
||||
|
||||
int32 mouse_found = 0;
|
||||
int32 keyboard_found = 0;
|
||||
int32 controller_found = 0;
|
||||
|
||||
int32 i;
|
||||
for (i = 0; i < device_count; ++i) {
|
||||
cb_size = sizeof(RID_DEVICE_INFO);
|
||||
RID_DEVICE_INFO rdi;
|
||||
GetRawInputDeviceInfoA(pRawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &rdi, &cb_size);
|
||||
|
||||
RAWINPUTDEVICE rid[1];
|
||||
|
||||
switch (rdi.dwType) {
|
||||
case RIM_TYPEHID: {
|
||||
if (rdi.hid.usUsage == 0x05) {
|
||||
if (states[controller_found].handle_controller != NULL) {
|
||||
|
|
@ -105,7 +139,8 @@ int input_raw_init(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
|||
}
|
||||
|
||||
states[controller_found].handle_controller = pRawInputDeviceList[i].hDevice;
|
||||
states[controller_found].is_connected = true;
|
||||
// @bug This is not always true, how to check?
|
||||
states[controller_found].connection_type = INPUT_CONNECTION_TYPE_USB;
|
||||
|
||||
// Gamepad
|
||||
rid[0].usUsagePage = 0x01;
|
||||
|
|
@ -123,7 +158,8 @@ int input_raw_init(HWND hwnd, Input* __restrict states, RingMemory* ring)
|
|||
}
|
||||
|
||||
states[controller_found].handle_controller = pRawInputDeviceList[i].hDevice;
|
||||
states[controller_found].is_connected = true;
|
||||
// @bug This is not always true, how to check?
|
||||
states[controller_found].connection_type = INPUT_CONNECTION_TYPE_USB;
|
||||
|
||||
// Joystick
|
||||
rid[0].usUsagePage = 0x01;
|
||||
|
|
@ -155,11 +191,11 @@ void input_mouse_position(HWND hwnd, v2_int32* pos)
|
|||
}
|
||||
}
|
||||
|
||||
int32 input_raw_handle(RAWINPUT* __restrict raw, Input* states, int state_count, uint64 time)
|
||||
int32 input_raw_handle(RAWINPUT* __restrict raw, Input* states, int32 state_count, uint64 time)
|
||||
{
|
||||
int32 input_count = 0;
|
||||
|
||||
uint32 i = 0;
|
||||
int32 i = 0;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE) {
|
||||
// @performance Change so we can directly access the correct state (maybe map handle address to index?)
|
||||
while (i < state_count
|
||||
|
|
@ -168,7 +204,7 @@ int32 input_raw_handle(RAWINPUT* __restrict raw, Input* states, int state_count,
|
|||
++i;
|
||||
}
|
||||
|
||||
if (i >= state_count || !states[i].is_connected) {
|
||||
if (i >= state_count || !states[i].connection_type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -273,7 +309,7 @@ int32 input_raw_handle(RAWINPUT* __restrict raw, Input* states, int state_count,
|
|||
++i;
|
||||
}
|
||||
|
||||
if (i >= state_count || !states[i].is_connected) {
|
||||
if (i >= state_count || !states[i].connection_type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -294,27 +330,28 @@ int32 input_raw_handle(RAWINPUT* __restrict raw, Input* states, int state_count,
|
|||
states[i].state_change_button = true;
|
||||
} else if (raw->header.dwType == RIM_TYPEHID) {
|
||||
if (raw->header.dwSize > sizeof(RAWINPUT)) {
|
||||
// @todo Find a way to handle most common controllers
|
||||
// DualSense
|
||||
// Xbox
|
||||
|
||||
// @performance This shouldn't be done every time, it should be polling based
|
||||
// Controllers often CONSTANTLY send data -> really bad
|
||||
// Maybe we can add timer usage
|
||||
// Maybe we can add timer usage instead of polling?
|
||||
while (i < state_count
|
||||
&& states[i].handle_controller != raw->header.hDevice
|
||||
) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (i >= state_count || !states[i].is_connected
|
||||
if (i >= state_count || !states[i].connection_type
|
||||
|| time - states[i].time_last_input_check < 5
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @todo Find a way to handle most common controllers
|
||||
// DualSense
|
||||
// Xbox
|
||||
// Xinput
|
||||
// Best way would probably to define the controller type in the input
|
||||
ControllerInput controller = {};
|
||||
input_map_dualshock4(&controller, raw->data.hid.bRawData);
|
||||
input_map_dualshock4(&controller, states[i].connection_type, raw->data.hid.bRawData);
|
||||
input_set_controller_state(&states[i], &controller, time);
|
||||
|
||||
states[i].time_last_input_check = time;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ void xinput_load() {
|
|||
}
|
||||
// END: Dynamically load XInput
|
||||
|
||||
ControllerInput* init_controllers()
|
||||
ControllerInput* xinput_init_controllers()
|
||||
{
|
||||
uint32 c = 0;
|
||||
for (uint32 controller_index = 0; controller_index < XUSER_MAX_COUNT; ++controller_index) {
|
||||
|
|
@ -85,49 +85,45 @@ ControllerInput* init_controllers()
|
|||
return controllers;
|
||||
}
|
||||
|
||||
void handle_controller_input(ControllerInput* states)
|
||||
inline
|
||||
void input_map_xinput(ControllerInput* controller, int32 controller_id)
|
||||
{
|
||||
/*
|
||||
uint32 controller_index = 0;
|
||||
while(states[controller_index].is_connected) {
|
||||
XINPUT_STATE controller_state;
|
||||
if (XInputGetState(controller_index, &controller_state) != ERROR_SUCCESS) {
|
||||
++controller_index;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
states[controller_index].up = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP;
|
||||
states[controller_index].down = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN;
|
||||
states[controller_index].left = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT;
|
||||
states[controller_index].right = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT;
|
||||
states[controller_index].button[6] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_START;
|
||||
states[controller_index].button[7] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK;
|
||||
|
||||
states[controller_index].button[4] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER;
|
||||
states[controller_index].button[5] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER;
|
||||
|
||||
states[controller_index].trigger[0] = controller_state.Gamepad.bLeftTrigger;
|
||||
states[controller_index].trigger[1] = controller_state.Gamepad.bRightTrigger;
|
||||
|
||||
states[controller_index].button[0] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_A;
|
||||
states[controller_index].button[1] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_B;
|
||||
states[controller_index].button[2] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_X;
|
||||
states[controller_index].button[3] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_Y;
|
||||
|
||||
states[controller_index].stickl_x = controller_state.Gamepad.sThumbLX;
|
||||
states[controller_index].stickl_y = controller_state.Gamepad.sThumbLY;
|
||||
states[controller_index].stickl_press = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB;
|
||||
|
||||
states[controller_index].stickr_x = controller_state.Gamepad.sThumbRX;
|
||||
states[controller_index].stickr_y = controller_state.Gamepad.sThumbRY;
|
||||
states[controller_index].stickr_press = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB;
|
||||
|
||||
|
||||
++controller_index;
|
||||
XINPUT_STATE controller_state;
|
||||
if (XInputGetState(controller_id, &controller_state) != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = (controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) * 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = (controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) * 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = (controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) * 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = (controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) * 127;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_0] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_START;
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_1] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_BUTTON] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? 1: 0;
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_BUTTON] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? 1: 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = controller_state.Gamepad.bRightTrigger;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = controller_state.Gamepad.bLeftTrigger;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_T] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_Y ? 1: 0;
|
||||
controller->button[CONTROLLER_BUTTON_C] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_B ? 1: 0;
|
||||
controller->button[CONTROLLER_BUTTON_X] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_A ? 1: 0;
|
||||
controller->button[CONTROLLER_BUTTON_S] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_X ? 1: 0;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = (byte) OMS_MIN(controller_state.Gamepad.sThumbLX, 127);
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = (byte) OMS_MIN(controller_state.Gamepad.sThumbLY, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = true;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_BUTTON] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] = (byte) OMS_MIN(controller_state.Gamepad.sThumbRX, 127);
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = (byte) OMS_MIN(controller_state.Gamepad.sThumbRY, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = true;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_BUTTON] = controller_state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB;
|
||||
}
|
||||
|
||||
#endif
|
||||
21
platform/win32/input/controller/ControllerHandler.h
Normal file
21
platform/win32/input/controller/ControllerHandler.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_INPUT_CONTROLLER_HANDLER_H
|
||||
#define TOS_PLATFORM_WIN32_INPUT_CONTROLLER_HANDLER_H
|
||||
|
||||
enum ControllerHandlerType {
|
||||
CONTROLLER_HANDLER_TYPE_AUTO, // Automatically picks a handler based on the device info and hard coded preferences
|
||||
CONTROLLER_HANDLER_TYPE_XINPUT,
|
||||
CONTROLLER_HANDLER_TYPE_DIRECTINPUT,
|
||||
CONTROLLER_HANDLER_TYPE_RAWINPUT_DS,
|
||||
CONTROLLER_HANDLER_TYPE_RAWINPUT_DS4,
|
||||
CONTROLLER_HANDLER_TYPE_RAWINPUT_XBOXS,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
* @see https://dsremap.readthedocs.io/en/latest/reverse.html
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_INPUT_CONTROLLER_DUALSENSE_H
|
||||
#define TOS_PLATFORM_WIN32_INPUT_CONTROLLER_DUALSENSE_H
|
||||
|
||||
#include "../../../../stdlib/Types.h"
|
||||
#include "../../../../input/ControllerInput.h"
|
||||
#include "../../../../input/InputConnectionType.h"
|
||||
#include "../../../../utils/BitUtils.h"
|
||||
#include "../../../../utils/MathUtils.h"
|
||||
|
||||
// @bug bluetooth and USB have different formats?!
|
||||
// https://github.com/nondebug/dualsense
|
||||
inline
|
||||
void input_map_dualsense(ControllerInput* controller, InputConnectionType connection_type, byte* data)
|
||||
{
|
||||
// 0 is not the origin -> need to shift
|
||||
++data;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = *data++;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = OMS_MIN(controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] - 128, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = *data++;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = OMS_MIN(controller->button[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] - 128, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_LEFT_VERTICAL] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] = *data++;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] = OMS_MIN(controller->button[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] - 128, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_RIGHT_HORIZONTAL] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = *data++;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = OMS_MIN(controller->button[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] - 128, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_RIGHT_VERTICAL] = true;
|
||||
|
||||
if (connection_type == INPUT_CONNECTION_TYPE_USB) {
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = *data++;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = *data++;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = true;
|
||||
|
||||
// Some counter
|
||||
++data;
|
||||
}
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_T] = BITS_GET_8_L2R(*data, 0, 1);
|
||||
controller->button[CONTROLLER_BUTTON_C] = BITS_GET_8_L2R(*data, 1, 1);
|
||||
controller->button[CONTROLLER_BUTTON_X] = BITS_GET_8_L2R(*data, 2, 1);
|
||||
controller->button[CONTROLLER_BUTTON_S] = BITS_GET_8_L2R(*data, 3, 1);
|
||||
|
||||
uint32 d_pad_state = BITS_GET_8_L2R(*data, 4, 4);
|
||||
if (d_pad_state == 8) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 0;
|
||||
} else if (d_pad_state == 0) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 0;
|
||||
} else if (d_pad_state == 1) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 0;
|
||||
} else if (d_pad_state == 2) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 0;
|
||||
} else if (d_pad_state == 3) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 127;
|
||||
} else if (d_pad_state == 4) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 127;
|
||||
} else if (d_pad_state == 5) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 127;
|
||||
} else if (d_pad_state == 6) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 0;
|
||||
} else if (d_pad_state == 7) {
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_LEFT] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_RIGHT] = 0;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_UP] = 127;
|
||||
controller->button[CONTROLLER_BUTTON_DPAD_DOWN] = 0;
|
||||
}
|
||||
|
||||
++data;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_RIGHT_BUTTON] = BITS_GET_8_L2R(*data, 0, 1);
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_BUTTON] = BITS_GET_8_L2R(*data, 1, 1);
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_0] = BITS_GET_8_L2R(*data, 2, 1); // option
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_1] = BITS_GET_8_L2R(*data, 3, 1); // share
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_BUTTON] = BITS_GET_8_L2R(*data, 6, 1);
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_BUTTON] = BITS_GET_8_L2R(*data, 7, 1);
|
||||
|
||||
++data;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_2] = BITS_GET_8_L2R(*data, 5, 1); // mute
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_3] = BITS_GET_8_L2R(*data, 6, 1); // tpad
|
||||
controller->button[CONTROLLER_BUTTON_OTHER_4] = BITS_GET_8_L2R(*data, 7, 1); // ps
|
||||
|
||||
++data;
|
||||
|
||||
if (connection_type == INPUT_CONNECTION_TYPE_BLUETOOTH) {
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = *data++;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_LEFT_TRIGGER] = true;
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = *data++;
|
||||
controller->is_analog[CONTROLLER_BUTTON_SHOULDER_RIGHT_TRIGGER] = true;
|
||||
}
|
||||
|
||||
data += 22;
|
||||
|
||||
// @question pure guess
|
||||
controller->gyro_x = *data++;
|
||||
controller->gyro_y = *data++;
|
||||
controller->gyro_z = *data++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -5,20 +5,28 @@
|
|||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
* @see https://dsremap.readthedocs.io/en/latest/reverse.html
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_INPUT_CONTROLLER_DUALSHOCK4_H
|
||||
#define TOS_PLATFORM_WIN32_INPUT_CONTROLLER_DUALSHOCK4_H
|
||||
|
||||
#include "../../../../stdlib/Types.h"
|
||||
#include "../../../../input/ControllerInput.h"
|
||||
#include "../../../../input/InputConnectionType.h"
|
||||
#include "../../../../utils/BitUtils.h"
|
||||
#include "../../../../utils/MathUtils.h"
|
||||
|
||||
inline
|
||||
void input_map_dualshock4(ControllerInput* controller, byte* data)
|
||||
void input_map_dualshock4(ControllerInput* controller, InputConnectionType connection_type, byte* data)
|
||||
{
|
||||
// 0 is not the origin -> need to shift
|
||||
++data;
|
||||
|
||||
// 0 is not the origin -> need to shift
|
||||
// @question Do we even need this? This might not be send on Windows
|
||||
if (connection_type == INPUT_CONNECTION_TYPE_BLUETOOTH) {
|
||||
++data;
|
||||
}
|
||||
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = *data++;
|
||||
controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = OMS_MIN(controller->button[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] - 128, 127);
|
||||
controller->is_analog[CONTROLLER_BUTTON_STICK_LEFT_HORIZONTAL] = true;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#define BIT_UNSET_R2L(num, pos) ((num) & ~((uint32) 1 << (pos)))
|
||||
#define BIT_FLIP_R2L(num, pos) ((num) ^ ((uint32) 1 << (pos)))
|
||||
#define BIT_SET_TO_R2L(num, pos, x) ((num) & ~((uint32) 1 << (pos)) | ((uint32) (x) << (pos)))
|
||||
// @performance Try to use this version over the L2R version for performance reasons
|
||||
#define BITS_GET_8_R2L(num, pos, to_read) (((num) >> (pos)) & ((1U << (to_read)) - 1))
|
||||
#define BITS_GET_16_R2L(num, pos, to_read) (((num) >> (pos)) & ((1U << (to_read)) - 1))
|
||||
#define BITS_GET_32_R2L(num, pos, to_read) (((num) >> (pos)) & ((1U << (to_read)) - 1))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user