Post-merge cleanup and improvements for #655
This commit is contained in:
@@ -508,16 +508,14 @@ float Input::GetGamepadAxis(InputGamepadIndex gamepad, GamepadAxis axis)
|
|||||||
{
|
{
|
||||||
if (gamepad == InputGamepadIndex::All)
|
if (gamepad == InputGamepadIndex::All)
|
||||||
{
|
{
|
||||||
float val = 0;
|
float result = 0.0f;
|
||||||
for (auto g : Gamepads)
|
for (auto g : Gamepads)
|
||||||
{
|
{
|
||||||
val += g->GetAxis(axis);
|
float v = g->GetAxis(axis);
|
||||||
if(val >= 1)
|
if (Math::Abs(v) > Math::Abs(result))
|
||||||
return 1;
|
result = v;
|
||||||
if (val <= -1)
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return val;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void WindowsManagerService::Update()
|
|||||||
WindowsManager::WindowsLocker.Lock();
|
WindowsManager::WindowsLocker.Lock();
|
||||||
for (auto& win : WindowsManager::Windows)
|
for (auto& win : WindowsManager::Windows)
|
||||||
{
|
{
|
||||||
if (win->IsVisible())
|
if (win && win->IsVisible())
|
||||||
win->OnUpdate(deltaTime);
|
win->OnUpdate(deltaTime);
|
||||||
}
|
}
|
||||||
WindowsManager::WindowsLocker.Unlock();
|
WindowsManager::WindowsLocker.Unlock();
|
||||||
|
|||||||
@@ -1,42 +1,41 @@
|
|||||||
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#if PLATFORM_LINUX
|
#if PLATFORM_LINUX
|
||||||
|
|
||||||
|
#include "LinuxInput.h"
|
||||||
|
#include "Engine/Core/Log.h"
|
||||||
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "LinuxInput.h"
|
|
||||||
#include "Engine/Core/Log.h"
|
|
||||||
|
|
||||||
using namespace std;
|
struct LinuxInputDevice
|
||||||
|
{
|
||||||
struct LinuxInputDevice {
|
uint32 uid[4];
|
||||||
u_int32_t uid[4];
|
std::string name;
|
||||||
string name;
|
std::string handler;
|
||||||
string handler;
|
|
||||||
bool isGamepad;
|
bool isGamepad;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int foundGamepads;
|
static int foundGamepads;
|
||||||
static float lastUpdateTime;
|
static float lastUpdateTime;
|
||||||
static LinuxInputDevice inputDevices[LINUXINPUT_MAX_GAMEPADS];
|
static LinuxInputDevice inputDevices[LINUXINPUT_MAX_GAMEPADS];
|
||||||
static LinuxGamepad *linuxGamepads[LINUXINPUT_MAX_GAMEPADS];
|
|
||||||
|
|
||||||
void LinuxInput::Init() {
|
void LinuxInput::Init()
|
||||||
for (int i = 0; i < LINUXINPUT_MAX_GAMEPADS; i++)
|
{
|
||||||
{
|
|
||||||
linuxGamepads[i] = nullptr;
|
|
||||||
}
|
|
||||||
foundGamepads = 0;
|
foundGamepads = 0;
|
||||||
// this will delay gamepad detection
|
lastUpdateTime = -1000;
|
||||||
lastUpdateTime = Platform::GetTimeSeconds();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinuxInput::DetectGamePads()
|
void LinuxInput::DetectGamePads()
|
||||||
{
|
{
|
||||||
string line;
|
std::string line;
|
||||||
std::ifstream devs("/proc/bus/input/devices");
|
std::ifstream devs("/proc/bus/input/devices");
|
||||||
|
|
||||||
foundGamepads = 0;
|
foundGamepads = 0;
|
||||||
if (devs.is_open())
|
if (devs.is_open())
|
||||||
{
|
{
|
||||||
@@ -46,31 +45,39 @@ void LinuxInput::DetectGamePads()
|
|||||||
{
|
{
|
||||||
int quoteIndex = line.find('"');
|
int quoteIndex = line.find('"');
|
||||||
inputDevices[foundGamepads].name = line.substr(quoteIndex+1, line.length() - quoteIndex - 2);
|
inputDevices[foundGamepads].name = line.substr(quoteIndex+1, line.length() - quoteIndex - 2);
|
||||||
} else if (line[0] == 'I')
|
}
|
||||||
|
else if (line[0] == 'I')
|
||||||
{
|
{
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
int equalsIndex = line.find('=', startIndex);
|
int equalsIndex = line.find('=', startIndex);
|
||||||
if (equalsIndex > 0) {
|
if (equalsIndex > 0)
|
||||||
istringstream part(line.substr(equalsIndex+1, 4));
|
{
|
||||||
|
std::istringstream part(line.substr(equalsIndex + 1, 4));
|
||||||
part >> std::hex >> inputDevices[foundGamepads].uid[i];
|
part >> std::hex >> inputDevices[foundGamepads].uid[i];
|
||||||
}
|
}
|
||||||
startIndex = equalsIndex+1;
|
startIndex = equalsIndex + 1;
|
||||||
}
|
}
|
||||||
} else if (line[0] == 'H')
|
}
|
||||||
|
else if (line[0] == 'H')
|
||||||
{
|
{
|
||||||
int eventIndex = line.find("event");
|
int eventIndex = line.find("event");
|
||||||
if (eventIndex > 0) {
|
if (eventIndex > 0)
|
||||||
|
{
|
||||||
int end = line.find(' ', eventIndex);
|
int end = line.find(' ', eventIndex);
|
||||||
if (end > 0) {
|
if (end > 0)
|
||||||
|
{
|
||||||
inputDevices[foundGamepads].handler = "/dev/input/" + line.substr(eventIndex, end - eventIndex);
|
inputDevices[foundGamepads].handler = "/dev/input/" + line.substr(eventIndex, end - eventIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (line[0] == 'B')
|
}
|
||||||
|
else if (line[0] == 'B')
|
||||||
{
|
{
|
||||||
int keyIndex = line.find("KEY=");
|
int keyIndex = line.find("KEY=");
|
||||||
if (keyIndex >= 0) {
|
if (keyIndex >= 0)
|
||||||
// there should be five groups of 64 bits each
|
{
|
||||||
|
// There should be five groups of 64 bits each
|
||||||
std::istringstream group(line.substr(keyIndex+4));
|
std::istringstream group(line.substr(keyIndex+4));
|
||||||
unsigned long int n64, msb;
|
unsigned long int n64, msb;
|
||||||
int foundGroups = 0;
|
int foundGroups = 0;
|
||||||
@@ -85,42 +92,56 @@ void LinuxInput::DetectGamePads()
|
|||||||
inputDevices[foundGamepads].isGamepad = (msb & 1lu<<48) > 0;
|
inputDevices[foundGamepads].isGamepad = (msb & 1lu<<48) > 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (line.length() == 0)
|
}
|
||||||
|
else if (line.length() == 0)
|
||||||
{
|
{
|
||||||
if (inputDevices[foundGamepads].isGamepad && foundGamepads < (LINUXINPUT_MAX_GAMEPADS-1))
|
if (inputDevices[foundGamepads].isGamepad && foundGamepads < (LINUXINPUT_MAX_GAMEPADS-1))
|
||||||
{
|
{
|
||||||
foundGamepads++;
|
foundGamepads++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
devs.close();
|
devs.close();
|
||||||
}
|
}
|
||||||
//DumpDevices();
|
//DumpDevices();
|
||||||
};
|
}
|
||||||
|
|
||||||
void LinuxInput::UpdateState()
|
void LinuxInput::UpdateState()
|
||||||
{
|
{
|
||||||
const float time = (float)Platform::GetTimeSeconds();
|
const float time = (float)Platform::GetTimeSeconds();
|
||||||
if (time - lastUpdateTime > 5.0f)
|
if (time - lastUpdateTime > 1.0f)
|
||||||
{
|
{
|
||||||
|
PROFILE_CPU_NAMED("Input.ScanGamepads");
|
||||||
DetectGamePads();
|
DetectGamePads();
|
||||||
lastUpdateTime = time;
|
lastUpdateTime = time;
|
||||||
for (int i = 0; i < foundGamepads; i++)
|
for (int i = 0; i < foundGamepads; i++)
|
||||||
{
|
{
|
||||||
if (linuxGamepads[i] == nullptr)
|
auto& inputDevice = inputDevices[i];
|
||||||
|
|
||||||
|
// Skip duplicates
|
||||||
|
bool duplicate = false;
|
||||||
|
for (Gamepad* g : Input::Gamepads)
|
||||||
{
|
{
|
||||||
linuxGamepads[i] = new LinuxGamepad(inputDevices[i].uid, inputDevices[i].name);
|
if (((LinuxGamepad*)g)->dev == inputDevice.handler.c_str())
|
||||||
linuxGamepads[i]->dev = inputDevices[i].handler;
|
{
|
||||||
linuxGamepads[i]->fd = -1;
|
duplicate = true;
|
||||||
Input::Gamepads.Add(linuxGamepads[i]);
|
break;
|
||||||
Input::OnGamepadsChanged();
|
}
|
||||||
LOG(Info, "Gamepad {} added", linuxGamepads[i]->GetName());
|
|
||||||
}
|
}
|
||||||
|
if (duplicate)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Add gamepad
|
||||||
|
auto linuxGamepad = New<LinuxGamepad>(inputDevice.uid, String(inputDevice.name.c_str()));
|
||||||
|
linuxGamepad->dev = StringAnsi(inputDevice.handler.c_str());
|
||||||
|
linuxGamepad->fd = -1;
|
||||||
|
Input::Gamepads.Add(linuxGamepad);
|
||||||
|
Input::OnGamepadsChanged();
|
||||||
|
LOG(Info, "Added gamepad '{}'", linuxGamepad->GetName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from WindowsInput.cpp
|
|
||||||
float NormalizeInputAxis(const int axisVal)
|
float NormalizeInputAxis(const int axisVal)
|
||||||
{
|
{
|
||||||
// Normalize [-32768..32767] -> [-1..1]
|
// Normalize [-32768..32767] -> [-1..1]
|
||||||
@@ -134,7 +155,8 @@ float NormalizeInputTrigger(const int axisVal)
|
|||||||
return float(axisVal) / 1023.0f;
|
return float(axisVal) / 1023.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxGamepad::LinuxGamepad(u_int32_t uid[4], string name) : Gamepad(Guid(uid[0], uid[1], uid[2], uid[3]), String(name.c_str()))
|
LinuxGamepad::LinuxGamepad(uint32 uid[4], const String& name)
|
||||||
|
: Gamepad(Guid(uid[0], uid[1], uid[2], uid[3]), name)
|
||||||
{
|
{
|
||||||
fd = -1;
|
fd = -1;
|
||||||
for (int i = 0; i < (int32)GamepadButton::MAX; i++)
|
for (int i = 0; i < (int32)GamepadButton::MAX; i++)
|
||||||
@@ -149,15 +171,16 @@ LinuxGamepad::LinuxGamepad(u_int32_t uid[4], string name) : Gamepad(Guid(uid[0],
|
|||||||
|
|
||||||
LinuxGamepad::~LinuxGamepad()
|
LinuxGamepad::~LinuxGamepad()
|
||||||
{
|
{
|
||||||
if (fd >= 0) close(fd);
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinuxGamepad::UpdateState()
|
bool LinuxGamepad::UpdateState()
|
||||||
{
|
{
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
fd = open(dev.c_str(), O_RDONLY|O_NONBLOCK);
|
fd = open(dev.Get(), O_RDONLY | O_NONBLOCK);
|
||||||
//cout << "opened " << dev << endl;
|
//std::cout << "opened " << dev.Get() << std::endl;
|
||||||
}
|
}
|
||||||
input_event event;
|
input_event event;
|
||||||
int caughtEvents = 0;
|
int caughtEvents = 0;
|
||||||
@@ -166,29 +189,32 @@ bool LinuxGamepad::UpdateState()
|
|||||||
ssize_t r = read(fd, &event, sizeof(event));
|
ssize_t r = read(fd, &event, sizeof(event));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
{
|
{
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN)
|
||||||
LOG(Warning, "Lost connection to gamepad, errno={0}", errno);
|
{
|
||||||
|
LOG(Warning, "Lost connection to gamepad '{1}', errno={0}", errno, GetName());
|
||||||
close(fd);
|
close(fd);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (r == 0) break;
|
if (r == 0) break;
|
||||||
if (r < sizeof(event) || r != 24)
|
if (r < sizeof(event) || r != 24)
|
||||||
{
|
{
|
||||||
LOG(Warning, "got a shortened package from the kernel {0}", r);
|
LOG(Warning, "Gamepad '{1}' got a shortened package from the kernel {0}", r, GetName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (event.type > EV_MAX)
|
if (event.type > EV_MAX)
|
||||||
{
|
{
|
||||||
LOG(Warning, "got an invalid event type from the kernel {0}", event.type);
|
LOG(Warning, "Gamepad '{1}' got an invalid event type from the kernel {0}", event.type, GetName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
caughtEvents++;
|
caughtEvents++;
|
||||||
//cout << "got an event " << event.type << ", code " << event.code << ", value " << event.value << endl;
|
//std::cout << "got an event " << event.type << ", code " << event.code << ", value " << event.value << std::endl;
|
||||||
if (event.type == EV_KEY)
|
if (event.type == EV_KEY)
|
||||||
{
|
{
|
||||||
switch (event.code) {
|
switch (event.code)
|
||||||
|
{
|
||||||
case BTN_A: _state.Buttons[(int32)GamepadButton::A] = !!event.value; break;
|
case BTN_A: _state.Buttons[(int32)GamepadButton::A] = !!event.value; break;
|
||||||
case BTN_B: _state.Buttons[(int32)GamepadButton::B] = !!event.value; break;
|
case BTN_B: _state.Buttons[(int32)GamepadButton::B] = !!event.value; break;
|
||||||
case BTN_X: _state.Buttons[(int32)GamepadButton::X] = !!event.value; break;
|
case BTN_X: _state.Buttons[(int32)GamepadButton::X] = !!event.value; break;
|
||||||
@@ -204,9 +230,11 @@ bool LinuxGamepad::UpdateState()
|
|||||||
case BTN_DPAD_LEFT: _state.Buttons[(int32)GamepadButton::DPadLeft] = !!event.value; break;
|
case BTN_DPAD_LEFT: _state.Buttons[(int32)GamepadButton::DPadLeft] = !!event.value; break;
|
||||||
case BTN_DPAD_RIGHT: _state.Buttons[(int32)GamepadButton::DPadRight] = !!event.value; break;
|
case BTN_DPAD_RIGHT: _state.Buttons[(int32)GamepadButton::DPadRight] = !!event.value; break;
|
||||||
}
|
}
|
||||||
} else if (event.type == EV_ABS)
|
}
|
||||||
|
else if (event.type == EV_ABS)
|
||||||
{
|
{
|
||||||
switch (event.code) {
|
switch (event.code)
|
||||||
|
{
|
||||||
case ABS_X:
|
case ABS_X:
|
||||||
_state.Axis[(int32)GamepadAxis::LeftStickX] = NormalizeInputAxis(event.value);
|
_state.Axis[(int32)GamepadAxis::LeftStickX] = NormalizeInputAxis(event.value);
|
||||||
_state.Buttons[(int32)GamepadButton::LeftStickLeft] = event.value < -TRIGGER_THRESHOLD;
|
_state.Buttons[(int32)GamepadButton::LeftStickLeft] = event.value < -TRIGGER_THRESHOLD;
|
||||||
@@ -238,33 +266,38 @@ bool LinuxGamepad::UpdateState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (caughtEvents > 0)
|
/*if (caughtEvents > 0)
|
||||||
{
|
{
|
||||||
LOG(Info, "Caught events: {}", caughtEvents);
|
LOG(Info, "Caught events: {}", caughtEvents);
|
||||||
cout << "left stick x: " << _state.Axis[(int32)GamepadAxis::LeftStickX] << endl;
|
std::cout << "left stick x: " << _state.Axis[(int32)GamepadAxis::LeftStickX] << std::endl;
|
||||||
cout << "left stick y: " << _state.Axis[(int32)GamepadAxis::LeftStickY] << endl;
|
std::cout << "left stick y: " << _state.Axis[(int32)GamepadAxis::LeftStickY] << std::endl;
|
||||||
cout << "left trigger: " << _state.Axis[(int32)GamepadAxis::LeftTrigger] << endl;
|
std::cout << "left trigger: " << _state.Axis[(int32)GamepadAxis::LeftTrigger] << std::endl;
|
||||||
cout << "right stick x: " << _state.Axis[(int32)GamepadAxis::RightStickX] << endl;
|
std::cout << "right stick x: " << _state.Axis[(int32)GamepadAxis::RightStickX] << std::endl;
|
||||||
cout << "right stick y: " << _state.Axis[(int32)GamepadAxis::RightStickY] << endl;
|
std::cout << "right stick y: " << _state.Axis[(int32)GamepadAxis::RightStickY] << std::endl;
|
||||||
cout << "right trigger: " << _state.Axis[(int32)GamepadAxis::RightTrigger] << endl;
|
std::cout << "right trigger: " << _state.Axis[(int32)GamepadAxis::RightTrigger] << std::endl;
|
||||||
cout << "button A: " << _state.Buttons[(int32)GamepadButton::A] << endl;
|
std::cout << "button A: " << _state.Buttons[(int32)GamepadButton::A] << std::endl;
|
||||||
cout << "layout A: " << (int32)Layout.Buttons[(int32)GamepadButton::A] << endl;
|
std::cout << "layout A: " << (int32)Layout.Buttons[(int32)GamepadButton::A] << std::endl;
|
||||||
}
|
}*/
|
||||||
*/
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
|
||||||
void LinuxInput::DumpDevices()
|
void LinuxInput::DumpDevices()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < foundGamepads; i++) {
|
for (int i = 0; i < foundGamepads; i++)
|
||||||
|
{
|
||||||
char buf[36];
|
char buf[36];
|
||||||
snprintf(buf, 36, "%04x %04x %04x %04x", inputDevices[i].uid[0], inputDevices[i].uid[1], inputDevices[i].uid[2], inputDevices[i].uid[3]);
|
snprintf(buf, 36, "%04x %04x %04x %04x", inputDevices[i].uid[0], inputDevices[i].uid[1], inputDevices[i].uid[2], inputDevices[i].uid[3]);
|
||||||
cout << buf << endl;
|
std::cout << buf << std::endl;
|
||||||
cout << inputDevices[i].name << endl;
|
std::cout << inputDevices[i].name << std::endl;
|
||||||
cout << inputDevices[i].handler << endl;
|
std::cout << inputDevices[i].handler << std::endl;
|
||||||
cout << (inputDevices[i].isGamepad ? "Gamepad" : "other") << endl;
|
std::cout << (inputDevices[i].isGamepad ? "Gamepad" : "other") << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,39 +1,34 @@
|
|||||||
|
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#if PLATFORM_LINUX
|
#if PLATFORM_LINUX
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "/usr/include/linux/input-event-codes.h"
|
|
||||||
#include "/usr/include/linux/input.h"
|
|
||||||
#include "Engine/Input/Input.h"
|
#include "Engine/Input/Input.h"
|
||||||
#include "Engine/Input/Gamepad.h"
|
#include "Engine/Input/Gamepad.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#define LINUXINPUT_MAX_GAMEPADS 8
|
#define LINUXINPUT_MAX_GAMEPADS 8
|
||||||
#define LINUXINPUT_MAX_GAMEPAD_EVENTS_PER_FRAME 32
|
#define LINUXINPUT_MAX_GAMEPAD_EVENTS_PER_FRAME 32
|
||||||
#define TRIGGER_THRESHOLD 1000
|
#define TRIGGER_THRESHOLD 1000
|
||||||
|
|
||||||
class LinuxGamepad : public Gamepad
|
class LinuxGamepad : public Gamepad
|
||||||
{
|
{
|
||||||
struct State {
|
public:
|
||||||
bool Buttons[32];
|
|
||||||
float Axis[32];
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
LinuxGamepad(u_int32_t uid[], string name);
|
|
||||||
~LinuxGamepad();
|
|
||||||
int fd;
|
int fd;
|
||||||
string dev;
|
StringAnsi dev;
|
||||||
State _state;
|
|
||||||
|
LinuxGamepad(uint32 uid[], const String& name);
|
||||||
|
~LinuxGamepad();
|
||||||
bool UpdateState();
|
bool UpdateState();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LinuxInput
|
class LinuxInput
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void UpdateState();
|
static void UpdateState();
|
||||||
static void DetectGamePads();
|
static void DetectGamePads();
|
||||||
|
#if BUILD_DEBUG
|
||||||
static void DumpDevices();
|
static void DumpDevices();
|
||||||
|
#endif
|
||||||
static void Init();
|
static void Init();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user