You've already forked emulationstation-next
mirror of
https://github.com/archr-linux/emulationstation-next.git
synced 2026-07-13 03:19:12 -07:00
Gun refactorings + preliminary aim cursor
This commit is contained in:
+6
-1
@@ -304,7 +304,6 @@ set(COMMON_LIBRARIES
|
||||
${FREETYPE_LIBRARIES}
|
||||
${FreeImage_LIBRARIES}
|
||||
${SDL2_LIBRARY}
|
||||
${UDEV_LIBRARY}
|
||||
# batocera / background musics
|
||||
${SDLMIXER_LIBRARY}
|
||||
# batocera / customisations
|
||||
@@ -316,6 +315,12 @@ set(COMMON_LIBRARIES
|
||||
libcheevos
|
||||
)
|
||||
|
||||
if(UDEV_FOUND)
|
||||
LIST(APPEND COMMON_LIBRARIES
|
||||
${UDEV_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_PULSE)
|
||||
LIST(APPEND COMMON_LIBRARIES
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
|
||||
+3
-9
@@ -668,7 +668,7 @@ int main(int argc, char* argv[])
|
||||
while(SDL_PollEvent(&event));
|
||||
|
||||
// check guns
|
||||
InputManager::getInstance()->parseGuns(&window);
|
||||
InputManager::getInstance()->updateGuns(&window);
|
||||
|
||||
// triggered if exiting from SDL_WaitEvent due to event
|
||||
if (ps_standby)
|
||||
@@ -685,17 +685,11 @@ int main(int argc, char* argv[])
|
||||
// ps_time = SDL_GetTicks();
|
||||
|
||||
// check guns
|
||||
InputManager::getInstance()->parseGuns(&window);
|
||||
InputManager::getInstance()->updateGuns(&window);
|
||||
}
|
||||
|
||||
// just to test
|
||||
float perx, pery;
|
||||
for (auto iter = InputManager::getInstance()->getGuns().begin(); iter != InputManager::getInstance()->getGuns().end(); iter++) {
|
||||
InputManager::getInstance()->getGunPosition(iter->second, perx, pery);
|
||||
printf("gun %i : %.2f %.2f\n", iter->first, perx, pery);
|
||||
}
|
||||
|
||||
if(window.isSleeping())
|
||||
if (window.isSleeping())
|
||||
{
|
||||
lastTime = SDL_GetTicks();
|
||||
SDL_Delay(1); // this doesn't need to be accurate, we're just giving up our CPU time until something wakes us up
|
||||
|
||||
@@ -10,6 +10,7 @@ set(CORE_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ImageIO.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputConfig.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/GunManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Log.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/MameNames.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/gettext.h # batocera
|
||||
@@ -126,6 +127,7 @@ set(CORE_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ImageIO.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputConfig.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/InputManager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/GunManager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Log.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/MameNames.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/LocaleES.cpp # batocera
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
#include "GunManager.h"
|
||||
#include "Log.h"
|
||||
#include "platform.h"
|
||||
#include "Window.h"
|
||||
#include <SDL.h>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include "utils/StringUtil.h"
|
||||
#include "LocaleES.h"
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/input.h>
|
||||
#include <unistd.h>
|
||||
#define test_bit(array, bit) (array[bit/8] & (1<<(bit%8)))
|
||||
#endif
|
||||
|
||||
#if WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
GunManager::GunManager()
|
||||
{
|
||||
#ifdef HAVE_UDEV
|
||||
udev = udev_new();
|
||||
if (udev != NULL)
|
||||
{
|
||||
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
if (udev_monitor)
|
||||
{
|
||||
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input", NULL);
|
||||
udev_monitor_enable_receiving(udev_monitor);
|
||||
}
|
||||
}
|
||||
udev_initial_gunsList();
|
||||
#endif
|
||||
}
|
||||
|
||||
GunManager::~GunManager()
|
||||
{
|
||||
#ifdef HAVE_UDEV
|
||||
if (udev != NULL)
|
||||
{
|
||||
// close guns
|
||||
for (auto gun : mGuns)
|
||||
{
|
||||
udev_removeGun(gun->dev, NULL);
|
||||
delete gun;
|
||||
}
|
||||
|
||||
mGuns.clear();
|
||||
|
||||
if (udev_monitor)
|
||||
udev_monitor_unref(udev_monitor);
|
||||
|
||||
udev_unref(udev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GunManager::updateGuns(Window* window)
|
||||
{
|
||||
#ifdef HAVE_UDEV
|
||||
const char* val_gun;
|
||||
const char* action;
|
||||
|
||||
while (udev_monitor && udev_input_poll_hotplug_available(udev_monitor))
|
||||
{
|
||||
struct udev_device *dev = udev_monitor_receive_device(udev_monitor);
|
||||
bool dev_handled = false;
|
||||
|
||||
if (dev != NULL)
|
||||
{
|
||||
val_gun = udev_device_get_property_value(dev, "ID_INPUT_GUN"); // ID_INPUT_GUN and ID_INPUT_MOUSE for some tests
|
||||
action = udev_device_get_action(dev);
|
||||
|
||||
if (val_gun != NULL && strncmp(val_gun, "1", 1) == 0)
|
||||
{
|
||||
if (strncmp(action, "add", 3) == 0)
|
||||
{
|
||||
if (udev_addGun(dev, window))
|
||||
dev_handled = true;
|
||||
}
|
||||
else if (strncmp(action, "remove", 6) == 0)
|
||||
{
|
||||
if (udev_removeGun(dev, window))
|
||||
dev_handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev_handled)
|
||||
udev_device_unref(dev); // not handled, clean it
|
||||
}
|
||||
}
|
||||
#elif WIN32
|
||||
if (mGuns.size() == 0)
|
||||
{
|
||||
Gun* newgun = new Gun();
|
||||
newgun->mIndex = mGuns.size();
|
||||
newgun->mName = "Mouse";
|
||||
mGuns.push_back(newgun);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (Gun* gun : mGuns)
|
||||
updateGunPosition(gun);
|
||||
}
|
||||
|
||||
bool GunManager::updateGunPosition(Gun* gun)
|
||||
{
|
||||
#ifdef HAVE_UDEV
|
||||
struct input_absinfo absinfo;
|
||||
|
||||
if (ioctl(gun->fd, EVIOCGABS(ABS_X), &absinfo) == -1)
|
||||
return false;
|
||||
|
||||
gun->mX = ((float)(absinfo.value - absinfo.minimum)) / ((float)(absinfo.maximum - absinfo.minimum));
|
||||
|
||||
if (ioctl(gun->fd, EVIOCGABS(ABS_Y), &absinfo) == -1)
|
||||
return false;
|
||||
|
||||
gun->mY = ((float)(absinfo.value - absinfo.minimum)) / ((float)(absinfo.maximum - absinfo.minimum));
|
||||
|
||||
return true;
|
||||
#elif WIN32
|
||||
int x, y;
|
||||
SDL_GetMouseState(&x, &y);
|
||||
gun->mX = x;
|
||||
gun->mY = y;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
// function from retroarch
|
||||
bool GunManager::udev_input_poll_hotplug_available(struct udev_monitor *dev)
|
||||
{
|
||||
struct pollfd fds;
|
||||
|
||||
fds.fd = udev_monitor_get_fd(dev);
|
||||
fds.events = POLLIN;
|
||||
fds.revents = 0;
|
||||
|
||||
return (poll(&fds, 1, 0) == 1) && (fds.revents & POLLIN);
|
||||
}
|
||||
|
||||
void GunManager::udev_initial_gunsList()
|
||||
{
|
||||
struct udev_list_entry *devs = NULL;
|
||||
struct udev_list_entry *item = NULL;
|
||||
|
||||
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
|
||||
udev_enumerate_add_match_property(enumerate, "ID_INPUT_GUN", "1");
|
||||
udev_enumerate_add_match_subsystem(enumerate, "input");
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
devs = udev_enumerate_get_list_entry(enumerate);
|
||||
|
||||
for (item = devs; item; item = udev_list_entry_get_next(item))
|
||||
{
|
||||
const char *name = udev_list_entry_get_name(item);
|
||||
struct udev_device *dev = udev_device_new_from_syspath(udev, name);
|
||||
|
||||
if (udev_addGun(dev, NULL) == false) udev_device_unref(dev); // unhandled device
|
||||
}
|
||||
}
|
||||
|
||||
bool GunManager::udev_addGun(struct udev_device *dev, Window* window)
|
||||
{
|
||||
char ident[256];
|
||||
const char* devnode;
|
||||
unsigned char abscaps[(ABS_MAX / 8) + 1] = { '\0' };
|
||||
|
||||
// check that devnode is of form /dev/input/eventXX (to not include devices aliases)
|
||||
devnode = udev_device_get_devnode(dev);
|
||||
if (devnode == NULL) return false;
|
||||
if (strncmp(devnode, "/dev/input/event", 16) != 0) return false;
|
||||
|
||||
int fd = open(devnode, O_RDONLY | O_NONBLOCK);
|
||||
if (fd < 0) return false;
|
||||
|
||||
// check absolute capabilities
|
||||
if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abscaps)), abscaps) == -1) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check absolute capabilities x and y
|
||||
if (((test_bit(abscaps, ABS_X)) && (test_bit(abscaps, ABS_Y))) == false) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(LogInfo) << "Gun found at " << devnode;
|
||||
|
||||
if (ioctl(fd, EVIOCGNAME(sizeof(ident)), ident) < 0)
|
||||
ident[0] = '\0';
|
||||
|
||||
Gun* newgun = new Gun();
|
||||
newgun->mIndex = mGuns.size();
|
||||
newgun->mName = std::string(ident);
|
||||
newgun->devpath = devnode;
|
||||
newgun->dev = dev;
|
||||
newgun->fd = fd;
|
||||
|
||||
if (!newgun->mName.empty() && window != NULL)
|
||||
window->displayNotificationMessage(_U("\uF05B ") + Utils::String::format(_("%s connected").c_str(), Utils::String::trim(newgun->mName).c_str()));
|
||||
|
||||
mGuns.push_back(newgun);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GunManager::udev_removeGun(struct udev_device *dev, Window* window)
|
||||
{
|
||||
const char* devnode;
|
||||
LOG(LogInfo) << "Gun removed at " << devnode;
|
||||
|
||||
devnode = udev_device_get_devnode(dev);
|
||||
if (devnode == NULL) return false;
|
||||
|
||||
for (auto iter = mGuns.begin(); iter != mGuns.end(); iter++)
|
||||
{
|
||||
if (iter->devpath == devnode)
|
||||
{
|
||||
LOG(LogInfo) << "Gun removed found at " << devnode;
|
||||
if (window != NULL)
|
||||
window->displayNotificationMessage(_U("\uF05B ") + Utils::String::format(_("%s disconnected").c_str(), Utils::String::trim(iter->mName).c_str()));
|
||||
|
||||
close(iter->fd);
|
||||
udev_device_unref(iter->dev);
|
||||
delete *iter;
|
||||
mGuns.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#ifndef ES_CORE_GUNMANAGER_H
|
||||
#define ES_CORE_GUNMANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
#include <libudev.h>
|
||||
#endif
|
||||
|
||||
class InputConfig;
|
||||
class Window;
|
||||
union SDL_Event;
|
||||
|
||||
class Gun
|
||||
{
|
||||
friend class GunManager;
|
||||
|
||||
public:
|
||||
Gun()
|
||||
{
|
||||
mIndex = 0;
|
||||
mX = -1;
|
||||
mY = -1;
|
||||
}
|
||||
|
||||
int index() { return mIndex; }
|
||||
std::string& name() { return mName; }
|
||||
|
||||
float x() { return mX; }
|
||||
float y() { return mY; }
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
|
||||
float mX;
|
||||
float mY;
|
||||
|
||||
int mIndex;
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
std::string devpath;
|
||||
udev_device* dev;
|
||||
int fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
//you should only ever instantiate one of these, by the way
|
||||
class GunManager
|
||||
{
|
||||
public:
|
||||
GunManager();
|
||||
virtual ~GunManager();
|
||||
|
||||
std::vector<Gun*>& getGuns() { return mGuns; }
|
||||
void updateGuns(Window* window);
|
||||
|
||||
private:
|
||||
bool updateGunPosition(Gun* gun);
|
||||
|
||||
std::vector<Gun*> mGuns;
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
struct udev *udev;
|
||||
struct udev_monitor *udev_monitor;
|
||||
|
||||
static bool udev_input_poll_hotplug_available(struct udev_monitor *dev);
|
||||
void udev_initial_gunsList();
|
||||
bool udev_addGun(struct udev_device *dev, Window* window);
|
||||
bool udev_removeGun(struct udev_device *dev, Window* window);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // ES_CORE_GUNMANAGER_H
|
||||
+13
-180
@@ -16,15 +16,7 @@
|
||||
#include "utils/StringUtil.h"
|
||||
#include "LocaleES.h"
|
||||
#include "Paths.h"
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/input.h>
|
||||
#include <unistd.h>
|
||||
#define test_bit(array, bit) (array[bit/8] & (1<<(bit%8)))
|
||||
#endif
|
||||
#include "GunManager.h"
|
||||
|
||||
#define KEYBOARD_GUID_STRING "-1"
|
||||
#define CEC_GUID_STRING "-2"
|
||||
@@ -60,7 +52,7 @@ InputManager::~InputManager()
|
||||
|
||||
InputManager* InputManager::getInstance()
|
||||
{
|
||||
if(!mInstance)
|
||||
if (!mInstance)
|
||||
mInstance = new InputManager();
|
||||
|
||||
return mInstance;
|
||||
@@ -87,17 +79,7 @@ void InputManager::init()
|
||||
mMouseButtonsInputConfig->mapInput(BUTTON_OK, Input(DEVICE_MOUSE, TYPE_BUTTON, 1, 1, true));
|
||||
mMouseButtonsInputConfig->mapInput(BUTTON_BACK, Input(DEVICE_MOUSE, TYPE_BUTTON, 3, 1, true));
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
udev = udev_new();
|
||||
if(udev != NULL) {
|
||||
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
if (udev_monitor){
|
||||
udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input", NULL);
|
||||
udev_monitor_enable_receiving(udev_monitor);
|
||||
}
|
||||
}
|
||||
udev_initial_gunsList();
|
||||
#endif
|
||||
mGunManager = new GunManager();
|
||||
}
|
||||
|
||||
void InputManager::deinit()
|
||||
@@ -130,20 +112,11 @@ void InputManager::deinit()
|
||||
SDL_JoystickEventState(SDL_DISABLE);
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
if(udev != NULL) {
|
||||
// close guns
|
||||
for (auto iter = mGuns.begin(); iter != mGuns.end(); iter++) {
|
||||
udev_removeGun(iter->second->dev, NULL);
|
||||
delete iter->second;
|
||||
}
|
||||
mGuns.clear();
|
||||
if (udev_monitor) {
|
||||
udev_monitor_unref(udev_monitor);
|
||||
}
|
||||
udev_unref(udev);
|
||||
if (mGunManager != nullptr)
|
||||
{
|
||||
delete mGunManager;
|
||||
mGunManager = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int InputManager::getNumJoysticks()
|
||||
@@ -256,152 +229,6 @@ void InputManager::rebuildAllJoysticks(bool deinit)
|
||||
SDL_JoystickEventState(SDL_ENABLE);
|
||||
}
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
// function from retroarch
|
||||
bool InputManager::udev_input_poll_hotplug_available(struct udev_monitor *dev)
|
||||
{
|
||||
struct pollfd fds;
|
||||
|
||||
fds.fd = udev_monitor_get_fd(dev);
|
||||
fds.events = POLLIN;
|
||||
fds.revents = 0;
|
||||
|
||||
return (poll(&fds, 1, 0) == 1) && (fds.revents & POLLIN);
|
||||
}
|
||||
|
||||
void InputManager::udev_initial_gunsList() {
|
||||
struct udev_list_entry *devs = NULL;
|
||||
struct udev_list_entry *item = NULL;
|
||||
|
||||
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
|
||||
udev_enumerate_add_match_property(enumerate, "ID_INPUT_GUN", "1");
|
||||
udev_enumerate_add_match_subsystem(enumerate, "input");
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
devs = udev_enumerate_get_list_entry(enumerate);
|
||||
|
||||
for (item = devs; item; item = udev_list_entry_get_next(item)) {
|
||||
const char *name = udev_list_entry_get_name(item);
|
||||
struct udev_device *dev = udev_device_new_from_syspath(udev, name);
|
||||
|
||||
if(udev_addGun(dev, NULL) == false) udev_device_unref(dev); // unhandled device
|
||||
}
|
||||
}
|
||||
|
||||
bool InputManager::udev_addGun(struct udev_device *dev, Window* window) {
|
||||
char ident[256];
|
||||
const char* devnode;
|
||||
unsigned char abscaps[(ABS_MAX / 8) + 1] = {'\0'};
|
||||
|
||||
// check that devnode is of form /dev/input/eventXX (to not include devices aliases)
|
||||
devnode = udev_device_get_devnode(dev);
|
||||
if(devnode == NULL) return false;
|
||||
if(strncmp(devnode, "/dev/input/event", 16) != 0) return false;
|
||||
|
||||
int fd = open(devnode, O_RDONLY | O_NONBLOCK);
|
||||
if(fd < 0) return false;
|
||||
|
||||
// check absolute capabilities
|
||||
if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abscaps)), abscaps) == -1) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check absolute capabilities x and y
|
||||
if( ( (test_bit(abscaps, ABS_X)) && (test_bit(abscaps, ABS_Y)) ) == false) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(LogInfo) << "Gun found at " << devnode;
|
||||
|
||||
if (ioctl(fd, EVIOCGNAME(sizeof(ident)), ident) < 0)
|
||||
ident[0] = '\0';
|
||||
|
||||
Gun* newgun = new Gun();
|
||||
newgun->name = std::string(ident);
|
||||
newgun->devpath = devnode;
|
||||
newgun->dev = dev;
|
||||
newgun->fd = fd;
|
||||
|
||||
if (!newgun->name.empty() && window != NULL)
|
||||
window->displayNotificationMessage(_U("\uF05B ") + Utils::String::format(_("%s connected").c_str(), Utils::String::trim(newgun->name).c_str()));
|
||||
|
||||
mGuns[mGuns.size()] = newgun;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputManager::udev_removeGun(struct udev_device *dev, Window* window) {
|
||||
const char* devnode;
|
||||
LOG(LogInfo) << "Gun removed at " << devnode;
|
||||
|
||||
devnode = udev_device_get_devnode(dev);
|
||||
if(devnode == NULL) return false;
|
||||
|
||||
for (auto iter = mGuns.begin(); iter != mGuns.end(); iter++) {
|
||||
if(iter->second->devpath == devnode) {
|
||||
LOG(LogInfo) << "Gun removed found at " << devnode;
|
||||
if(window != NULL)
|
||||
window->displayNotificationMessage(_U("\uF05B ") + Utils::String::format(_("%s disconnected").c_str(), Utils::String::trim(iter->second->name).c_str()));
|
||||
|
||||
close(iter->second->fd);
|
||||
udev_device_unref(iter->second->dev);
|
||||
delete iter->second;
|
||||
mGuns.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void InputManager::parseGuns(Window* window) {
|
||||
#ifdef HAVE_UDEV
|
||||
const char* val_gun;
|
||||
const char* action;
|
||||
|
||||
while (udev_monitor && udev_input_poll_hotplug_available(udev_monitor)) {
|
||||
struct udev_device *dev = udev_monitor_receive_device(udev_monitor);
|
||||
bool dev_handled = false;
|
||||
|
||||
if(dev != NULL) {
|
||||
val_gun = udev_device_get_property_value(dev, "ID_INPUT_GUN"); // ID_INPUT_GUN and ID_INPUT_MOUSE for some tests
|
||||
action = udev_device_get_action(dev);
|
||||
|
||||
if(val_gun != NULL && strncmp(val_gun, "1", 1) == 0) {
|
||||
if(strncmp(action, "add", 3) == 0) {
|
||||
if(udev_addGun(dev, window)) dev_handled = true;
|
||||
|
||||
} else if(strncmp(action, "remove", 6) == 0) {
|
||||
if(udev_removeGun(dev, window)) dev_handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(dev_handled == false) udev_device_unref(dev); // not handled, clean it
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool InputManager::getGunPosition(Gun* gun, float& perx, float& pery) {
|
||||
#ifdef HAVE_UDEV
|
||||
struct input_absinfo absinfo;
|
||||
|
||||
if (ioctl(gun->fd, EVIOCGABS(ABS_X), &absinfo) == -1) {
|
||||
return false;
|
||||
}
|
||||
perx = ((float)(absinfo.value - absinfo.minimum)) / ((float)(absinfo.maximum - absinfo.minimum));
|
||||
|
||||
if (ioctl(gun->fd, EVIOCGABS(ABS_Y), &absinfo) == -1) {
|
||||
return false;
|
||||
}
|
||||
pery = ((float)(absinfo.value - absinfo.minimum)) / ((float)(absinfo.maximum - absinfo.minimum));
|
||||
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
|
||||
{
|
||||
bool causedEvent = false;
|
||||
@@ -965,3 +792,9 @@ std::vector<InputConfig*> InputManager::getInputConfigs()
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InputManager::updateGuns(Window* window)
|
||||
{
|
||||
if (mGunManager)
|
||||
mGunManager->updateGuns(window);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
#include <pugixml/src/pugixml.hpp>
|
||||
#include <utils/Delegate.h>
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
#include <libudev.h>
|
||||
#endif
|
||||
#include "GunManager.h"
|
||||
|
||||
class InputConfig;
|
||||
class Window;
|
||||
class GunManager;
|
||||
|
||||
union SDL_Event;
|
||||
|
||||
struct PlayerDeviceInfo
|
||||
@@ -27,15 +27,6 @@ public:
|
||||
virtual void onJoystickChanged() = 0;
|
||||
};
|
||||
|
||||
struct Gun {
|
||||
std::string name;
|
||||
#ifdef HAVE_UDEV
|
||||
std::string devpath;
|
||||
udev_device* dev;
|
||||
int fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
//you should only ever instantiate one of these, by the way
|
||||
class InputManager
|
||||
{
|
||||
@@ -58,9 +49,8 @@ public:
|
||||
|
||||
bool parseEvent(const SDL_Event& ev, Window* window);
|
||||
|
||||
void parseGuns(Window* window);
|
||||
bool getGunPosition(Gun* gun, float& perx, float& pery);
|
||||
std::map<int, Gun*>& getGuns() { return mGuns; }
|
||||
void updateGuns(Window* window);
|
||||
std::vector<Gun*>& getGuns() { return mGunManager->getGuns(); }
|
||||
|
||||
std::string configureEmulators();
|
||||
|
||||
@@ -72,9 +62,13 @@ public:
|
||||
|
||||
static Delegate<IJoystickChangedEvent> joystickChanged;
|
||||
|
||||
GunManager* getGunManager() { return mGunManager; }
|
||||
|
||||
private:
|
||||
InputManager();
|
||||
|
||||
GunManager* mGunManager;
|
||||
|
||||
static InputManager* mInstance;
|
||||
static const int DEADZONE = 23000;
|
||||
static std::string getTemporaryConfigPath();
|
||||
@@ -85,8 +79,6 @@ private:
|
||||
std::map<SDL_JoystickID, SDL_Joystick*> mJoysticks;
|
||||
std::map<SDL_JoystickID, InputConfig*> mInputConfigs;
|
||||
|
||||
std::map<int, Gun*> mGuns;
|
||||
|
||||
InputConfig* mMouseButtonsInputConfig;
|
||||
InputConfig* mKeyboardInputConfig;
|
||||
InputConfig* mCECInputConfig;
|
||||
@@ -104,16 +96,6 @@ private:
|
||||
|
||||
void clearJoysticks();
|
||||
void rebuildAllJoysticks(bool deinit = true);
|
||||
|
||||
#ifdef HAVE_UDEV
|
||||
struct udev *udev;
|
||||
struct udev_monitor *udev_monitor;
|
||||
|
||||
static bool udev_input_poll_hotplug_available(struct udev_monitor *dev);
|
||||
void udev_initial_gunsList();
|
||||
bool udev_addGun(struct udev_device *dev, Window* window);
|
||||
bool udev_removeGun(struct udev_device *dev, Window* window);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // ES_CORE_INPUT_MANAGER_H
|
||||
|
||||
+36
-9
@@ -502,13 +502,13 @@ void Window::render()
|
||||
mRenderedHelpPrompts = false;
|
||||
|
||||
// draw only bottom and top of GuiStack (if they are different)
|
||||
if(mGuiStack.size())
|
||||
if (mGuiStack.size())
|
||||
{
|
||||
auto& bottom = mGuiStack.front();
|
||||
auto& top = mGuiStack.back();
|
||||
|
||||
bottom->render(transform);
|
||||
if(bottom != top)
|
||||
if (bottom != top)
|
||||
{
|
||||
if ((top->getTag() == "GuiLoading") && mGuiStack.size() > 2)
|
||||
{
|
||||
@@ -534,21 +534,21 @@ void Window::render()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mGuiStack.size() < 2 || !Renderer::isSmallScreen())
|
||||
if(!mRenderedHelpPrompts)
|
||||
if (!mRenderedHelpPrompts)
|
||||
mHelp->render(transform);
|
||||
|
||||
if(Settings::DrawFramerate() && mFrameDataText)
|
||||
if (Settings::DrawFramerate() && mFrameDataText)
|
||||
{
|
||||
Renderer::setMatrix(Transform4x4f::Identity());
|
||||
mDefaultFonts.at(1)->renderTextCache(mFrameDataText.get());
|
||||
}
|
||||
|
||||
// clock
|
||||
// clock
|
||||
if (Settings::DrawClock() && mClock && (mGuiStack.size() < 2 || !Renderer::isSmallScreen()))
|
||||
mClock->render(transform);
|
||||
|
||||
|
||||
if (Settings::ShowControllerActivity() && mControllerActivity != nullptr && (mGuiStack.size() < 2 || !Renderer::isSmallScreen()))
|
||||
mControllerActivity->render(transform);
|
||||
|
||||
@@ -569,7 +569,7 @@ void Window::render()
|
||||
|
||||
renderAsyncNotifications(transform);
|
||||
}
|
||||
|
||||
|
||||
// Always call the screensaver render function regardless of whether the screensaver is active
|
||||
// or not because it may perform a fade on transition
|
||||
renderScreenSaver();
|
||||
@@ -580,7 +580,7 @@ void Window::render()
|
||||
if (mVolumeInfo && Settings::VolumePopup())
|
||||
mVolumeInfo->render(transform);
|
||||
|
||||
if(mTimeSinceLastInput >= screensaverTime && screensaverTime != 0)
|
||||
if (mTimeSinceLastInput >= screensaverTime && screensaverTime != 0)
|
||||
{
|
||||
if (!isProcessing() && mAllowSleep && (!mScreenSaver || mScreenSaver->allowSleep()))
|
||||
{
|
||||
@@ -591,6 +591,33 @@ void Window::render()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// just to test
|
||||
for (auto gun : InputManager::getInstance()->getGuns())
|
||||
{
|
||||
if (mGunAimTexture == nullptr)
|
||||
mGunAimTexture = TextureResource::get(":/gun.png", false, false, true, false);
|
||||
|
||||
if (mGunAimTexture->bind())
|
||||
{
|
||||
int pointerSize = 24;
|
||||
|
||||
const Vector2f topLeft = { gun->x() - pointerSize, gun->y() - pointerSize };
|
||||
const Vector2f bottomRight = { gun->x() + pointerSize, gun->y() + pointerSize };
|
||||
|
||||
Renderer::Vertex vertices[4];
|
||||
vertices[0] = { { topLeft.x() , topLeft.y() }, { 0.0f, 0.0f }, 0xFFFFFFFF };
|
||||
vertices[1] = { { topLeft.x() , bottomRight.y() }, { 0.0f, 1.0f }, 0xFFFFFFFF };
|
||||
vertices[2] = { { bottomRight.x(), topLeft.y() }, { 1.0f, 0.0f }, 0xFFFFFFFF };
|
||||
vertices[3] = { { bottomRight.x(), bottomRight.y() }, { 1.0f, 1.0f }, 0xFFFFFFFF };
|
||||
|
||||
Renderer::drawTriangleStrips(&vertices[0], 4);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
// auto output = Utils::String::format("gun %i : %.2f %.2f\n", gun->index(), gun->x(), gun->y());
|
||||
|
||||
}
|
||||
|
||||
void Window::normalizeNextUpdate()
|
||||
|
||||
@@ -159,6 +159,8 @@ private:
|
||||
bool mRenderedHelpPrompts;
|
||||
|
||||
int mTransitionOffset;
|
||||
|
||||
std::shared_ptr<TextureResource> mGunAimTexture;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_WINDOW_H
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
Reference in New Issue
Block a user