Controller-Emulator/Keyboard-To-Controller.cpp
2025-04-15 10:51:37 -07:00

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;
}