386 lines
13 KiB
C++
386 lines
13 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <linux/input.h>
|
|
#include <linux/uinput.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include "keys.h"
|
|
|
|
//The path to the keyboard (should look something like /dev/input/eventX)
|
|
char KEYBOARD_PATH[] = "PATH_HERE";
|
|
|
|
int absXLEFT = 0;
|
|
int absXRIGHT = 0;
|
|
int absYUP = 0;
|
|
int absYDOWN = 0;
|
|
|
|
void exitFunc(int keyboard_fd, int gamepad_fd)
|
|
{
|
|
close(keyboard_fd);
|
|
if (ioctl(gamepad_fd, UI_DEV_DESTROY) < 0)
|
|
{
|
|
printf("Error destroying gamepad! \n");
|
|
}
|
|
close(gamepad_fd);
|
|
}
|
|
|
|
void send_sync_event(int gamepad_fd, struct input_event gamepad_event)
|
|
{
|
|
memset(&gamepad_event, 0, sizeof(struct input_event));
|
|
gamepad_event.type = EV_SYN;
|
|
gamepad_event.code = 0;
|
|
gamepad_event.value = 0;
|
|
|
|
if(write(gamepad_fd, &gamepad_event, sizeof(struct input_event)) < 0)
|
|
{
|
|
printf("error writing sync event\n");
|
|
}
|
|
}
|
|
|
|
void send_keyboard_event(int gamepad_fd, struct input_event gamepad_event, int TYPE, int CODE, int VALUE) // TYPE Is The event to write to the gamepad and CODE is an integer value for the button on the gamepad
|
|
{
|
|
memset(&gamepad_event, 0, sizeof(struct input_event));
|
|
gamepad_event.type = TYPE;
|
|
gamepad_event.code = CODE;
|
|
gamepad_event.value = VALUE;
|
|
|
|
if(write(gamepad_fd, &gamepad_event, sizeof(struct input_event)) < 0)
|
|
{
|
|
printf("Error writing keyboard event to gamepad!\n");
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int rcode = 0;
|
|
|
|
char keyboard_name[256] = "Unknown";
|
|
int keyboard_fd = open(KEYBOARD_PATH, O_RDONLY | O_NONBLOCK);
|
|
if (keyboard_fd == -1)
|
|
{
|
|
printf("Failed to open keyboard.\n");
|
|
exit(1);
|
|
}
|
|
rcode = ioctl(keyboard_fd, EVIOCGNAME(sizeof(keyboard_name)), keyboard_name);
|
|
printf("Reading From : %s \n", keyboard_name);
|
|
|
|
// printf("Getting exclusive access: ");
|
|
// rcode = ioctl(keyboard_fd, EVIOCGRAB, 1);
|
|
// printf("%s\n", (rcode == 0) ? "SUCCESS" : "FAILURE");>>
|
|
struct input_event keyboard_event;
|
|
|
|
// Now, create gamepad
|
|
|
|
int gamepad_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
|
if (gamepad_fd < 0)
|
|
{
|
|
printf("Opening of input failed! \n");
|
|
return 1;
|
|
}
|
|
|
|
ioctl(gamepad_fd, UI_SET_EVBIT, EV_KEY); // setting Gamepad keys
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_A);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_B);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_X);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_Y);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_TL);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_TR);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_TL2);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_TR2);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_START);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_SELECT);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_MODE);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_THUMBL);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_THUMBR);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_DPAD_UP);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_DPAD_DOWN);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_DPAD_LEFT);
|
|
ioctl(gamepad_fd, UI_SET_KEYBIT, BTN_DPAD_RIGHT);
|
|
|
|
ioctl(gamepad_fd, UI_SET_EVBIT, EV_ABS); // setting Gamepad thumbsticks
|
|
ioctl(gamepad_fd, UI_SET_ABSBIT, ABS_X);
|
|
ioctl(gamepad_fd, UI_SET_ABSBIT, ABS_Y);
|
|
ioctl(gamepad_fd, UI_SET_ABSBIT, ABS_RX);
|
|
ioctl(gamepad_fd, UI_SET_ABSBIT, ABS_RY);
|
|
ioctl(gamepad_fd, UI_SET_ABSBIT, ABS_TILT_X);
|
|
ioctl(gamepad_fd, UI_SET_ABSBIT, ABS_TILT_Y);
|
|
|
|
struct uinput_user_dev uidev;
|
|
|
|
memset(&uidev, 0, sizeof(uidev));
|
|
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "Gamepad"); // Name of Gamepad
|
|
uidev.id.bustype = BUS_USB;
|
|
uidev.id.vendor = 0x3;
|
|
uidev.id.product = 0x3;
|
|
uidev.id.version = 2;
|
|
uidev.absmax[ABS_X] = 32767; // Parameters of thumbsticks
|
|
uidev.absmin[ABS_X] = -32768;
|
|
uidev.absfuzz[ABS_X] = 0;
|
|
uidev.absflat[ABS_X] = 15;
|
|
uidev.absmax[ABS_Y] = 32767;
|
|
uidev.absmin[ABS_Y] = -32768;
|
|
uidev.absfuzz[ABS_Y] = 0;
|
|
uidev.absflat[ABS_Y] = 15;
|
|
uidev.absmax[ABS_RX] = 32767;
|
|
uidev.absmin[ABS_RX] = -32768;
|
|
uidev.absfuzz[ABS_RX] = 0;
|
|
uidev.absflat[ABS_RX] = 15;
|
|
uidev.absmax[ABS_RY] = 32767;
|
|
uidev.absmin[ABS_RY] = -32768;
|
|
uidev.absfuzz[ABS_RY] = 0;
|
|
uidev.absflat[ABS_RY] = 15;
|
|
|
|
if (write(gamepad_fd, &uidev, sizeof(uidev)) < 0)
|
|
{
|
|
printf("Failed to write! \n");
|
|
return 1;
|
|
}
|
|
if (ioctl(gamepad_fd, UI_DEV_CREATE) < 0)
|
|
{
|
|
printf("Failed to create gamepad! \n");
|
|
return 1;
|
|
}
|
|
|
|
struct input_event gamepad_ev;
|
|
|
|
// Constantly do this
|
|
while (1)
|
|
{
|
|
if (read(keyboard_fd, &keyboard_event, sizeof(keyboard_event)) != -1)
|
|
{
|
|
// printf("keyboard event: type %d code %d value %d \n", keyboard_event.type, keyboard_event.code, keyboard_event.value);
|
|
// quit on Keypad Enter
|
|
if (keyboard_event.code == KEY_KPENTER && keyboard_event.value != 2)
|
|
{
|
|
exitFunc(keyboard_fd, gamepad_fd);
|
|
break;
|
|
}
|
|
|
|
// Tab to Y (top face button)
|
|
if (keyboard_event.code == KEY_TAB && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_Y, keyboard_event.value);
|
|
}
|
|
|
|
// X to X (left face button)
|
|
if (keyboard_event.code == KEY_X && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_X, keyboard_event.value);
|
|
}
|
|
|
|
// Space bar to A (bottom face button)
|
|
if (keyboard_event.code == KEY_SPACE && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_A, keyboard_event.value);
|
|
}
|
|
|
|
// Left Alt to B (right face button)
|
|
if (keyboard_event.code == KEY_LEFTALT && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_B, keyboard_event.value);
|
|
}
|
|
|
|
// L to X-axis right stick full speed right
|
|
if (keyboard_event.code == KEY_L)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = 32768;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_RX, toWrite);
|
|
}
|
|
|
|
// J to X-axis right stick full speed left
|
|
if (keyboard_event.code == KEY_J)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = -32768;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_RX, toWrite);
|
|
}
|
|
|
|
// I to Y-axis right stick full speed up
|
|
if (keyboard_event.code == KEY_I)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = -32768;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_RY, toWrite);
|
|
}
|
|
|
|
// K to Y-axis right stick full speed down
|
|
if (keyboard_event.code == KEY_K)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = 32768;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_RY, toWrite);
|
|
}
|
|
|
|
// W to Y-axis left stick full speed up
|
|
if (keyboard_event.code == KEY_W)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = -32768;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_Y, toWrite);
|
|
}
|
|
|
|
// S to Y-axis left stick full speed down
|
|
if (keyboard_event.code == KEY_S)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = 32767;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_Y, toWrite);
|
|
}
|
|
|
|
// A to X-axis left stick full speed left
|
|
if (keyboard_event.code == KEY_A)
|
|
{
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = -32768;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_X, toWrite);
|
|
}
|
|
|
|
// D to X-axis left stick full speed right
|
|
if (keyboard_event.code == KEY_D)
|
|
{
|
|
|
|
int toWrite = 0;
|
|
if (keyboard_event.value == 2 || keyboard_event.value == 1) // on pressed or on hold key
|
|
toWrite = 32767;
|
|
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_ABS, ABS_X, toWrite);
|
|
}
|
|
|
|
// left shift to click left stick
|
|
if (keyboard_event.code == KEY_LEFTSHIFT && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_THUMBL, keyboard_event.value);
|
|
}
|
|
|
|
// Right Shift to click right stick
|
|
if (keyboard_event.code == KEY_RIGHTSHIFT && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_THUMBR, keyboard_event.value);
|
|
}
|
|
|
|
// G to D-pad Up
|
|
if (keyboard_event.code == KEY_G && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_DPAD_UP, keyboard_event.value);
|
|
}
|
|
|
|
// B to D-pad Down
|
|
if (keyboard_event.code == KEY_B && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_DPAD_DOWN, keyboard_event.value);
|
|
}
|
|
|
|
// V to D-pad Left
|
|
if (keyboard_event.code == KEY_V && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_DPAD_LEFT, keyboard_event.value);
|
|
}
|
|
|
|
// N to D-pad Right
|
|
if (keyboard_event.code == KEY_N && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_DPAD_RIGHT, keyboard_event.value);
|
|
}
|
|
|
|
// F to Left Bumper
|
|
if (keyboard_event.code == KEY_F && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_TL, keyboard_event.value);
|
|
}
|
|
|
|
// H to Right Bumper
|
|
if (keyboard_event.code == KEY_H && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_TR, keyboard_event.value);
|
|
}
|
|
|
|
// R to Left Bumper
|
|
if (keyboard_event.code == KEY_R && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_TL2, keyboard_event.value);
|
|
}
|
|
|
|
// Y to Right Trigger
|
|
if (keyboard_event.code == KEY_Y && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_TR2, keyboard_event.value);
|
|
}
|
|
|
|
// F1 to Select Button
|
|
if (keyboard_event.code == KEY_F1 && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_SELECT, keyboard_event.value);
|
|
}
|
|
|
|
// F2 to Start Button
|
|
if (keyboard_event.code == KEY_F2 && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_START, keyboard_event.value);
|
|
}
|
|
|
|
// F3 to Mode Button
|
|
if (keyboard_event.code == KEY_F3 && keyboard_event.value != 2) // only care about button press
|
|
{
|
|
//send keyboard event to gamepad
|
|
send_keyboard_event(gamepad_fd, gamepad_ev, EV_KEY, BTN_MODE, keyboard_event.value);
|
|
}
|
|
|
|
// send sync
|
|
send_sync_event(gamepad_fd, gamepad_ev);
|
|
}
|
|
}
|
|
|
|
printf("Exiting.\n");
|
|
rcode = ioctl(keyboard_fd, EVIOCGRAB, 1);
|
|
close(keyboard_fd);
|
|
return 0;
|
|
}
|