Snippets

新妻浩光 メガドライブミニにiBuffaloのアーケードスティックをつなぐ

You are viewing an old version of this snippet. View the current version.
Revised by 新妻浩光 663d9e3
#include <SDL2/SDL.h>
#include <errno.h> 
#include <fcntl.h>
#include <linux/input.h> 
#include <linux/uinput.h>
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h>
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h>


#define die(str)                                                               \
  do {                                                                         \
    perror(str);                                                               \
    exit(EXIT_FAILURE);                                                        \
  } while (0)
struct uinput_user_dev uidev = {0};

void make_output(int fd) {

  ioctl(fd, UI_SET_EVBIT, EV_KEY);
  ioctl(fd, UI_SET_KEYBIT, BTN_TRIGGER);
  ioctl(fd, UI_SET_KEYBIT, BTN_THUMB);
  ioctl(fd, UI_SET_KEYBIT, BTN_THUMB2);
  ioctl(fd, UI_SET_KEYBIT, BTN_TOP);
  ioctl(fd, UI_SET_KEYBIT, BTN_TOP2);
  ioctl(fd, UI_SET_KEYBIT, BTN_PINKIE);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE2);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE3);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE4);

  ioctl(fd, UI_SET_KEYBIT, KEY_L);
  ioctl(fd, UI_SET_KEYBIT, KEY_R);


  ioctl(fd, UI_SET_EVBIT, EV_ABS);
  ioctl(fd, UI_SET_ABSBIT, ABS_X);
  ioctl(fd, UI_SET_ABSBIT, ABS_Y);
  


  snprintf(uidev.name, UINPUT_MAX_NAME_SIZE,"ev from sdl");
  uidev.id.bustype = BUS_USB;
  uidev.id.vendor = 0x7777;
  uidev.id.product = 0x7777;
  uidev.id.version = 1;

  uidev.absmin[ABS_X] = 0;
  uidev.absmax[ABS_X] = 255;
  uidev.absflat[ABS_X] = 15;

  uidev.absmin[ABS_Y] = 0;
  uidev.absmax[ABS_Y] = 255;
  uidev.absflat[ABS_Y] = 15;

  if (write(fd, &uidev, sizeof(uidev)) < 0)
    die("Fail to write uinput_user_dev");

  if (ioctl(fd, UI_DEV_CREATE) < 0)
    die("Fail to set UI_DEV_CREATE");
}

void emit(int output, int type, int code, int value) {
  struct input_event event = {.type = type, .code = code, .value = value};
  event.time.tv_sec = 0;
  event.time.tv_usec = 0;
  write(output, &event, sizeof(event));
}



int main(int argc, char* argv[])
{

  int output = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
  if (output == -1)
    die("Cannot open the output device");





    SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER );
	int i;
	const char *name;
	int ret;
	ret=SDL_GameControllerAddMapping("03000000a30c00002400000011010000,6B controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,");
	if( ret < 0 ){
		printf("add mapping error. %s\n",SDL_GetError());
	}
	for (i = 0; i < SDL_NumJoysticks(); ++i) {
		printf("[%d] %s\n",i,SDL_JoystickNameForIndex(i));
		SDL_GameController *g=SDL_GameControllerOpen(i);
		if( g ){
			printf("game controller.\n");
			break;
		}else{
			printf("not game controller. %s\n",SDL_GetError());

		}
	}

  make_output(output);

	SDL_Event e;
	while(1){
	SDL_Delay(10);
		while(SDL_PollEvent(&e)){
			int code;
			if( e.type!= SDL_CONTROLLERBUTTONDOWN &&
				e.type!= SDL_CONTROLLERBUTTONUP &&
				e.type!= SDL_CONTROLLERAXISMOTION) continue;

			if( e.type==SDL_CONTROLLERAXISMOTION ){
				int v=127;
				if( e.caxis.value > 0 ) v=255;
				if( e.caxis.value < 0 ) v=0;

				printf("axis=%d value=%d\n",e.caxis.axis,e.caxis.value);
				switch(e.caxis.axis){
					case 0:
						emit(output, EV_ABS, ABS_X, v ); 
						break;
					case 1:
						emit(output, EV_ABS, ABS_Y, v ); 
						break;

				}
				emit(output, EV_SYN, SYN_REPORT, 0);
				continue;
			}
			printf("type=0x%x btn=%d state=%d\n",e.type,e.cbutton.button,e.cbutton.state);
			switch(e.cbutton.button){
				case SDL_CONTROLLER_BUTTON_A:
					code=BTN_THUMB2;
					break;
				case SDL_CONTROLLER_BUTTON_B:
					code=BTN_THUMB;
					break;
				case SDL_CONTROLLER_BUTTON_X:
					code=BTN_TOP;
					break;
				case SDL_CONTROLLER_BUTTON_Y:
					code=BTN_TRIGGER;
					break;
				
				case SDL_CONTROLLER_BUTTON_START:
					code=BTN_BASE4;
					break;
				case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
					code=BTN_TOP2;
					break;
				case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
					code=BTN_PINKIE;
					break;

				case SDL_CONTROLLER_BUTTON_BACK:
					code=BTN_BASE3;
					break;

				
			}
			emit(output,EV_KEY,code,e.cbutton.state==SDL_PRESSED?1:0);
			emit(output, EV_SYN, SYN_REPORT, 0);
			
		}
	}

    SDL_Quit();
    return 0;
}
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>


#define die(str)                                                               \
  do {                                                                         \
    perror(str);                                                               \
    exit(EXIT_FAILURE);                                                        \
  } while (0)
struct uinput_user_dev uidev = {0};

void make_output(int fd) {

  ioctl(fd, UI_SET_EVBIT, EV_KEY);
  ioctl(fd, UI_SET_KEYBIT, BTN_TRIGGER);
  ioctl(fd, UI_SET_KEYBIT, BTN_THUMB);
  ioctl(fd, UI_SET_KEYBIT, BTN_THUMB2);
  ioctl(fd, UI_SET_KEYBIT, BTN_TOP);
  ioctl(fd, UI_SET_KEYBIT, BTN_TOP2);
  ioctl(fd, UI_SET_KEYBIT, BTN_PINKIE);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE2);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE3);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE4);

  ioctl(fd, UI_SET_KEYBIT, KEY_L);
  ioctl(fd, UI_SET_KEYBIT, KEY_R);


  ioctl(fd, UI_SET_EVBIT, EV_ABS);
  ioctl(fd, UI_SET_ABSBIT, ABS_X);
  ioctl(fd, UI_SET_ABSBIT, ABS_Y);
  


  snprintf(uidev.name, UINPUT_MAX_NAME_SIZE,"evfrom23");
  uidev.id.bustype = BUS_USB;
  uidev.id.vendor = 0x7777;
  uidev.id.product = 0x7777;
  uidev.id.version = 1;

  uidev.absmin[ABS_X] = 0;
  uidev.absmax[ABS_X] = 255;
  uidev.absflat[ABS_X] = 15;

  uidev.absmin[ABS_Y] = 0;
  uidev.absmax[ABS_Y] = 255;
  uidev.absflat[ABS_Y] = 15;

  if (write(fd, &uidev, sizeof(uidev)) < 0)
    die("Fail to write uinput_user_dev");

  if (ioctl(fd, UI_DEV_CREATE) < 0)
    die("Fail to set UI_DEV_CREATE");
}

void emit(int output, int type, int code, int value) {
  struct input_event event = {.type = type, .code = code, .value = value};
  event.time.tv_sec = 0;
  event.time.tv_usec = 0;
  write(output, &event, sizeof(event));
}

#define NAME_ELEMENT(element) [element] = #element
static const char * const absval[6] = { "Value", "Min  ", "Max  ", "Fuzz ", "Flat ", "Resolution "};

int abs_max[10];
int abs_min[10];
static void print_absdata(int fd, int axis)
{
	int abs[6] = {0};
	int k;

	ioctl(fd, EVIOCGABS(axis), abs);
	for (k = 0; k < 6; k++){
		if ((k < 3) || abs[k]){
			printf("      %s %6d\n", absval[k], abs[k]);
    }
  }
  if( axis == ABS_X) {

  }
  abs_min[axis]=abs[1];
  abs_max[axis]=abs[2];

}
#define BITS_PER_LONG (sizeof(long) * 8)
#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
#define OFF(x)  ((x)%BITS_PER_LONG)
#define BIT(x)  (1UL<<OFF(x))
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array)	((array[LONG(bit)] >> OFF(bit)) & 1)

static const char * const events[EV_MAX + 1] = {
	[0 ... EV_MAX] = NULL,
	NAME_ELEMENT(EV_SYN),			NAME_ELEMENT(EV_KEY),
	NAME_ELEMENT(EV_REL),			NAME_ELEMENT(EV_ABS),
	NAME_ELEMENT(EV_MSC),			NAME_ELEMENT(EV_LED),
	NAME_ELEMENT(EV_SND),			NAME_ELEMENT(EV_REP),
	NAME_ELEMENT(EV_FF),			NAME_ELEMENT(EV_PWR),
	NAME_ELEMENT(EV_FF_STATUS),		NAME_ELEMENT(EV_SW),
};

static inline const char* typename(unsigned int type)
{
	return (type <= EV_MAX && events[type]) ? events[type] : "?";
}


int main(int argc,char **argv) {

	unsigned int type, code;
	int version;
	unsigned short id[4];
	char name[256] = "Unknown";
	unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
  char INPUT_DEVICE[255];
  int x;
  int replace_code;
  for(x=0;x<argc;x++){
    printf("argv[%d]=%s\n",x,argv[x]);
  }
  if( argc > 1 ){
    strcpy(INPUT_DEVICE,argv[1]);
  }

  int input = open(INPUT_DEVICE, O_RDWR);
  if (input == -1)
    die("Cannot open the input device");

  int fd=input;

	ioctl(fd, EVIOCGNAME(sizeof(name)), name);
	printf("Input device name: \"%s\"\n", name);

	memset(bit, 0, sizeof(bit));
	ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
	printf("Supported events:\n");

	for (type = 0; type < EV_MAX; type++) {
		if (test_bit(type, bit[0]) && type != EV_REP) {
			printf("  Event type %d (%s)\n", type, typename(type));
			if (type == EV_SYN) continue;
			ioctl(fd, EVIOCGBIT(type, KEY_MAX), bit[type]);
			for (code = 0; code < KEY_MAX; code++)
				if (test_bit(code, bit[type])) {
					printf("    Event code %d\n", code);
					if (type == EV_ABS){
						print_absdata(fd, code);
          }
				}
		}
	}

  int output = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
  if (output == -1)
    die("Cannot open the output device");

  make_output(output);

  emit(output, EV_ABS, ABS_X, 127);
  emit(output, EV_ABS, ABS_Y, 127);

  // Disable the input device
  // ioctl(input, EVIOCGRAB, 1);
  printf("abs_x [%d - %d] abs_y [%d - %d] \n",abs_min[ABS_X],abs_max[ABS_X],abs_min[ABS_Y],abs_max[ABS_Y]);
  while (1) {
    struct input_event event;

    ssize_t result = read(input, &event, sizeof(event));
    if (result == -1) {
      perror("Stopping");
      return 0;
    } else if (result != sizeof(event)) {
      die("Inconsistent event size");
    }
    printf("tv_sec: %lu, type: %04x, code: %04x, value: %08x\n", event.time.tv_sec, event.type, event.code, event.value);
    fflush(stdout);
    
    switch (event.type) {
    case EV_ABS:
      if( event.code==ABS_X ){
        printf("ABS X : value=%d\n",event.value);
      }
      if( event.code==ABS_Y ){
        printf("ABS Y : value=%d\n",event.value);
      }

      if( event.value == abs_max[event.code]) {
        emit(output, EV_ABS, event.code, 255);

      }else if( event.value== abs_min[event.code]){
        emit(output, EV_ABS, event.code, 0);
      }else{
        emit(output, EV_ABS, event.code, 127);
      }
      emit(output, EV_SYN, SYN_REPORT, 0);


    case EV_KEY:
      switch(event.code){
        case BTN_B: // 1
          replace_code=BTN_THUMB2;  // MD A
          break;
        case BTN_C: // 2
          replace_code=BTN_THUMB;   // MD B
          break;
        case BTN_TR: // 3
          replace_code=BTN_PINKIE;  // MD C
          break;

        case BTN_TL:  // 4
          break;  // MD no use

        case BTN_A:  // 5
          replace_code=BTN_TOP;   // MD X
          break;
        case BTN_X:  // 6
          replace_code=BTN_TOP;   // MD Y
          break;
        case BTN_Z:  // 7
          replace_code=BTN_TOP;   // MD Z
          break;

        case BTN_Y: // 8
          break;  // MD no use



        case BTN_SELECT: // L3
          replace_code=BTN_BASE3;
          break;
        case BTN_START: // R3
          replace_code=BTN_BASE4;
          break;
      }
      emit(output, event.type, replace_code, event.value);
      emit(output, EV_SYN, SYN_REPORT, 0);
    }
  }

  // Never reach here...
  // Enable the mouse
  ioctl(input, EVIOCGRAB, 0);
  close(input);
  close(output);
  return (EXIT_SUCCESS);
}
#include <SDL2/SDL.h>
#include <errno.h> 
#include <fcntl.h>
#include <linux/input.h> 
#include <linux/uinput.h>
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h> 
#include <sys/types.h> 
#include <sys/ioctl.h>


#define die(str)                                                               \
  do {                                                                         \
    perror(str);                                                               \
    exit(EXIT_FAILURE);                                                        \
  } while (0)
struct uinput_user_dev uidev = {0};

void make_output(int fd,int ev) {

  ioctl(fd, UI_SET_EVBIT, EV_KEY);
  ioctl(fd, UI_SET_KEYBIT, BTN_TRIGGER);
  ioctl(fd, UI_SET_KEYBIT, BTN_THUMB);
  ioctl(fd, UI_SET_KEYBIT, BTN_THUMB2);
  ioctl(fd, UI_SET_KEYBIT, BTN_TOP);
  ioctl(fd, UI_SET_KEYBIT, BTN_TOP2);
  ioctl(fd, UI_SET_KEYBIT, BTN_PINKIE);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE2);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE3);
  ioctl(fd, UI_SET_KEYBIT, BTN_BASE4);

  ioctl(fd, UI_SET_KEYBIT, KEY_L);
  ioctl(fd, UI_SET_KEYBIT, KEY_R);


  ioctl(fd, UI_SET_EVBIT, EV_ABS);
  ioctl(fd, UI_SET_ABSBIT, ABS_X);
  ioctl(fd, UI_SET_ABSBIT, ABS_Y);
  

  snprintf(uidev.name, UINPUT_MAX_NAME_SIZE,"linkmeevent%d",ev-10);
  uidev.id.bustype = BUS_USB;
  uidev.id.vendor = 0x7777;
  uidev.id.product = 0x7777;
  uidev.id.version = 1;

  uidev.absmin[ABS_X] = 0;
  uidev.absmax[ABS_X] = 255;
  uidev.absflat[ABS_X] = 15;

  uidev.absmin[ABS_Y] = 0;
  uidev.absmax[ABS_Y] = 255;
  uidev.absflat[ABS_Y] = 15;

  if (write(fd, &uidev, sizeof(uidev)) < 0)
    die("Fail to write uinput_user_dev");

  if (ioctl(fd, UI_DEV_CREATE) < 0)
    die("Fail to set UI_DEV_CREATE");
}

void emit(int output, int type, int code, int value) {
  struct input_event event = {.type = type, .code = code, .value = value};
  event.time.tv_sec = 0;
  event.time.tv_usec = 0;
  write(output, &event, sizeof(event));
}

///// Their code are copied from SYS_Joystick for touch raw structure data

struct SDL_joylist_item;

/* The private structure used to keep track of a joystick */
struct joystick_hwdata
{
    int fd;
    struct SDL_joylist_item *item;
    SDL_JoystickGUID guid;
    char *fname;                /* Used in haptic subsystem */

    /* The current Linux joystick driver maps hats to two axes */
    struct hwdata_hat
    {
        int axis[2];
    } *hats;
    /* The current Linux joystick driver maps balls to two axes */
    struct hwdata_ball
    {
        int axis[2];
    } *balls;

    /* Support for the Linux 2.4 unified input interface */
    Uint8 key_map[KEY_MAX];
    Uint8 abs_map[ABS_MAX];
    struct axis_correct
    {
        int used;
        int coef[3];
    } abs_correct[ABS_MAX];

    int fresh;

    /* Steam Controller support */
    SDL_bool m_bSteamController;
};
typedef struct _SDL_JoystickAxisInfo
{
    Sint16 initial_value;       /* Initial axis state */
    Sint16 value;               /* Current axis state */
    Sint16 zero;                /* Zero point on the axis (-32768 for triggers) */
    SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */
    SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */
} SDL_JoystickAxisInfo;


struct _SDL_Joystick
{
    SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
    char *name;                 /* Joystick name - system dependent */

    int naxes;                  /* Number of axis controls on the joystick */
    SDL_JoystickAxisInfo *axes;

    int nhats;                  /* Number of hats on the joystick */
    Uint8 *hats;                /* Current hat states */

    int nballs;                 /* Number of trackballs on the joystick */
    struct balldelta {
        int dx;
        int dy;
    } *balls;                   /* Current ball motion deltas */

    int nbuttons;               /* Number of buttons on the joystick */
    Uint8 *buttons;             /* Current button states */

    struct joystick_hwdata *hwdata;     /* Driver dependent information */

    int ref_count;              /* Reference count for multiple opens */

    SDL_bool is_game_controller;
};


int is_event_device(const struct dirent *dir)
{
	return strncmp("event", dir->d_name, 5) == 0;
}

char *find_device(char *p)
{
	struct dirent **namelist;
	int i, ndev;

	ndev = scandir("/dev/input", &namelist, is_event_device, alphasort);
	if (ndev <= 0)
		return 0;

	for (i = 0; i < ndev; i++) {
		char fname[64];
		int fd = -1;
		char name[256] = "";
		char phys[256] = "";
		char uniq[256] = "";
		char prop[256] = "";

		snprintf(fname, sizeof(fname), "/dev/input/%s",
				namelist[i]->d_name);
		fd = open(fname, O_RDONLY);
		if (fd < 0)
			continue;

		ioctl(fd, EVIOCGNAME(sizeof(name)), name);
		ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys);
		ioctl(fd, EVIOCGUNIQ(sizeof(uniq)), uniq);
		ioctl(fd, EVIOCGPROP(sizeof(prop)), prop);
#if 0
		printf("%s:\n", fname);
		printf("\tname: %s\n", name);
		printf("\tphys: %s\n", phys);
		printf("\tuniq: %s\n", uniq);
		printf("\tprop: %s\n", prop);
#endif
		close(fd);
		if( strcmp(p,name)==0 ){
			return strdup(fname);
		}
		free(namelist[i]);
	}
	return NULL;
}
int handle_as_joystick(int output,SDL_Event e){
	if( e.type==SDL_JOYAXISMOTION ){
		int v=127;
		if( e.caxis.value > 0 ) v=255;
		if( e.caxis.value < 0 ) v=0;

		printf("axis=%d value=%d\n",e.jaxis.axis,e.jaxis.value);
		switch(e.jaxis.axis){
			case 0:
				emit(output, EV_ABS, ABS_X, v ); 
				break;
			case 1:
				emit(output, EV_ABS, ABS_Y, v ); 
				break;

		}
		emit(output, EV_SYN, SYN_REPORT, 0);
	}

	if (e.type==SDL_JOYBUTTONDOWN || e.type==SDL_JOYBUTTONUP) {
		printf("type=0x%x btn=%d state=%d\n",e.type,e.cbutton.button,e.cbutton.state);

	}

	return 0;
}
int handle_as_controller(int output,SDL_Event e){

	switch(e.type)
	{
		case SDL_CONTROLLERAXISMOTION:
		{
			int v=127;
			if( e.caxis.value > 0 ) v=255;
			if( e.caxis.value < 0 ) v=0;

			printf("axis=%d value=%d\n",e.caxis.axis,e.caxis.value);
			switch(e.caxis.axis){
				case 0:
					emit(output, EV_ABS, ABS_X, v ); 
					break;
				case 1:
					emit(output, EV_ABS, ABS_Y, v ); 
					break;

			}
			emit(output, EV_SYN, SYN_REPORT, 0);
		}
			break;
		case SDL_CONTROLLERBUTTONDOWN:
		case SDL_CONTROLLERBUTTONUP:
		{
			int code=0;
			// buttons
			printf("type=0x%x btn=%d state=%d\n",e.type,e.cbutton.button,e.cbutton.state);
			switch(e.cbutton.button){
				case SDL_CONTROLLER_BUTTON_A:
					code=BTN_THUMB2;
					break;
				case SDL_CONTROLLER_BUTTON_B:
					code=BTN_THUMB;
					break;

				case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
					code=BTN_PINKIE;
					break;


				case SDL_CONTROLLER_BUTTON_X:
					code=BTN_TOP;
					break;
				case SDL_CONTROLLER_BUTTON_Y:
					code=BTN_TRIGGER;
					break;
				
				case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
					code=BTN_TOP2;
					break;

				case SDL_CONTROLLER_BUTTON_START:
					code=BTN_BASE4;
					break;

				case SDL_CONTROLLER_BUTTON_BACK:
					code=BTN_BASE3;
					break;
			}
			if( code > 0){
				emit(output,EV_KEY,code,e.cbutton.state==SDL_PRESSED?1:0);
				emit(output, EV_SYN, SYN_REPORT, 0);
			}
		}
		break;
	}
	return 0;
}
int main(int argc, char* argv[])
{
	int joysticktype=-1;	// not opened
	int i;
	int n_event_input;
	int ret;

	if( argc < 2 ){
		fprintf(stderr,"%s : </dev/input/eventx>\n",argv[0]);
		exit(-1);
	}

	int output = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
	if (output == -1)
		die("Cannot open the output device");

	// Initialize SDL
    SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER );

	// MD Mini 6B pad mapping
	ret=SDL_GameControllerAddMapping("03000000a30c00002400000011010000,6B controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,");
	printf("add mapping returns<%d>, %s\n",ret,SDL_GetError());

	// get /dev/input/event[number]


	// open joystick or mapped pad
	SDL_Joystick *j=NULL;
	for (i = 0; i < SDL_NumJoysticks(); ++i) {
		printf("[%d] %s ",i,SDL_JoystickNameForIndex(i));
		SDL_GameController *g=SDL_GameControllerOpen(i);
		if( g ){		
			printf("is game controller.\n");

			j=SDL_GameControllerGetJoystick(g);

			// check joystick is target event 
			if( strcmp(j->hwdata->fname,argv[1])==0 ){
				// yes
				joysticktype=0;
				break;
			}else{
				// no

				SDL_GameControllerClose(g);
				// next input
			}
		}else{
			printf("is not game controller. treat as simple joystick.%s\n",SDL_GetError());
			joysticktype=1;

			j=SDL_JoystickOpen(i);

			// check joystick is target event 
			if( strcmp(j->hwdata->fname,argv[1])==0 ){
				// yes
				joysticktype=1;
				break;
			}else{
				SDL_JoystickClose(j);
				//next input
			}
		}
	}

	if( joysticktype < 0 ){
		fprintf(stderr,"could not found js on %s\n",argv[1]);
		die("fatal error.");
	}
	
	n_event_input=atoi(j->hwdata->fname+strlen("/dev/input/event"));

	// make virtual input event with "linkmeevent[4-13]"
	make_output(output,n_event_input);
	
	// find new virtual/input and link to event4-13
	char target[255];
	sprintf(target,"linkmeevent%d",n_event_input-10);

	char *dev=find_device(target);		
	if( dev ){
		char cmdline[255];
		sprintf(cmdline,"ln -s %s /dev/input/event%d",dev,n_event_input-10);
		puts(cmdline);
~		system(cmdline);
	}else{
		die("fatal error. linkmeevent device not found.");
	}

	
	while(1){
		SDL_Event e;
		SDL_Delay(10);
		while(SDL_PollEvent(&e)){

			switch(joysticktype){
				case 0:
					handle_as_controller(output,e);
					break;
				case 1:
					handle_as_joystick(output,e);
					break;
			}
		}

	}

    SDL_Quit();
    return 0;
}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.