Exemple #1
0
int main(int argc, char *argv[]) {

	uint8_t ctr = 0;
	GPAD_ST gpads[GPADSNUM];
	BTN_DEV_ST button;
	int16_t clockpin;
	int16_t strobepin;
	int16_t data1pin;
	int16_t data2pin;
	int16_t clockpin_v2;
	int16_t strobepin_v2;
	int16_t data1pin_v2;
	int16_t data2pin_v2;

	if (!bcm2835_init())
		return 1;
	
	if (readConfigurationfile() != 0 ) {
		return 1;
	}

	if (strcmp(confres.adapter_version,"1x")==0) {
		clockpin = RPI_GPIO_P1_19;
		strobepin = RPI_GPIO_P1_23;
		data1pin = RPI_GPIO_P1_05;
		data2pin = RPI_GPIO_P1_07;
		clockpin_v2 = RPI_V2_GPIO_P1_19;
		strobepin_v2 = RPI_V2_GPIO_P1_23;
		data1pin_v2 = RPI_V2_GPIO_P1_05;
		data2pin_v2 = RPI_V2_GPIO_P1_07;
		printf("[SNESDev-Rpi] Using pin setup for RetroPie GPIO-Adapter Version 1.X\n");

	} else if (strcmp(confres.adapter_version,"2x")==0) {
		clockpin = RPI_GPIO_P1_16;
		strobepin = RPI_GPIO_P1_18;
		data1pin = RPI_GPIO_P1_15;
		data2pin = RPI_GPIO_P1_13;
		clockpin_v2 = RPI_V2_GPIO_P1_16;
		strobepin_v2 = RPI_V2_GPIO_P1_18;
		data1pin_v2 = RPI_V2_GPIO_P1_15;
		data2pin_v2 = RPI_V2_GPIO_P1_13;
		printf("[SNESDev-Rpi] Using pin setup for RetroPie GPIO-Adapter Version 2.X\n");

	} else {
		clockpin = RPI_GPIO_P1_16;
		strobepin = RPI_GPIO_P1_18;
		data1pin = RPI_GPIO_P1_15;
		data2pin = RPI_GPIO_P1_13;
		clockpin_v2 = RPI_V2_GPIO_P1_16;
		strobepin_v2 = RPI_V2_GPIO_P1_18;
		data1pin_v2 = RPI_V2_GPIO_P1_15;
		data2pin_v2 = RPI_V2_GPIO_P1_13;
		printf("[SNESDev-Rpi] Using pin setup for RetroPie GPIO-Adapter Version 2.X\n");
	}


	if (confres.gamepad1_enabled || confres.gamepad2_enabled) {

		gpads[0].port = 1;
		gpads[1].port = 1;
		// check board revision and set pins to be used
		// these are acutally also used by the gamecon driver
		if (get_rpi_revision()==1)
		{
			gpads[0].pin_clock = clockpin;
			gpads[0].pin_strobe = strobepin;
			gpads[0].pin_data = data1pin;
			gpads[1].pin_clock = clockpin;
			gpads[1].pin_strobe = strobepin;
			gpads[1].pin_data = data2pin;		
		} else {
			gpads[0].pin_clock = clockpin_v2;
			gpads[0].pin_strobe = strobepin_v2;
			gpads[0].pin_data = data1pin_v2;
			gpads[1].pin_clock = clockpin_v2;
			gpads[1].pin_strobe = strobepin_v2;
			gpads[1].pin_data = data2pin_v2;		
		}
		if (strcmp(confres.gamepad1_type,"nes")==0) {
			gpads[0].type = GPAD_TYPE_NES;
		} else {
			gpads[0].type = GPAD_TYPE_SNES;
		}
		if (strcmp(confres.gamepad2_type,"nes")==0) {
			gpads[1].type = GPAD_TYPE_NES;
		} else {
			gpads[1].type = GPAD_TYPE_SNES;
		}

		if (confres.gamepad1_enabled) {
			printf("[SNESDev-Rpi] Enabling game pad 1 with type '%s'.\n", confres.gamepad1_type);
			gpad_open(&gpads[0]);
			switch (gpads->type) {
			case GPAD_TYPE_SNES:
				uinput_gpad_open(&uinp_gpads[0], UINPUT_GPAD_TYPE_SNES);
				break;
			case GPAD_TYPE_NES:
				uinput_gpad_open(&uinp_gpads[0], UINPUT_GPAD_TYPE_NES);
				break;
			default:
				break;
			}
		}
		if (confres.gamepad2_enabled) {
			printf("[SNESDev-Rpi] Enabling game pad 2 with type '%s'.\n", confres.gamepad2_type);
			gpad_open(&gpads[1]);
			switch (gpads->type) {
			case GPAD_TYPE_SNES:
				uinput_gpad_open(&uinp_gpads[1], UINPUT_GPAD_TYPE_SNES);
				break;
			case GPAD_TYPE_NES:
				uinput_gpad_open(&uinp_gpads[1], UINPUT_GPAD_TYPE_NES);
				break;
			default:
				break;
			}
		}
	}

	if (confres.button_enabled) {
		printf("[SNESDev-Rpi] Enabling button.\n");
		button.port = 1;
		if (get_rpi_revision()==1) {
			button.pin = BUTTONPIN;
		} else {
			button.pin = BUTTONPIN_V2;
		}		
		btn_open(&button);
		uinput_kbd_open(&uinp_kbd);
	}

	register_signalhandlers();

	///* enter the main loop */
	doRun = 1;
	while (doRun) {
		if (confres.gamepad1_enabled || confres.gamepad2_enabled) {						
			/* read states of the buttons */
			for (ctr = 0; ctr < GPADSNUM; ctr++) {
				gpad_read(&gpads[ctr]);
			}

			///* send an event (pressed or released) for each button */
			for (ctr = 0; ctr < GPADSNUM; ctr++) {
				if ((ctr==0 && !(confres.gamepad1_enabled)) || 
					(ctr==1 && !(confres.gamepad2_enabled))) {
					continue;
				}

				gpad_read(&gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_A, BTN_A,
						&uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_B, BTN_B,
						&uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_X, BTN_X,
						&uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_Y, BTN_Y,
						&uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_L, BTN_TL,
						&uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_R, BTN_TR,
						&uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_SELECT,
						BTN_SELECT, &uinp_gpads[ctr]);
				processPadBtn(gpads[ctr].state, EV_KEY, GPAD_SNES_START,
						BTN_START, &uinp_gpads[ctr]);

				if ((gpads[ctr].state & GPAD_SNES_LEFT) == GPAD_SNES_LEFT) {
					uinput_gpad_write(&uinp_gpads[ctr], ABS_X, 0, EV_ABS);
				} else if ((gpads[ctr].state & GPAD_SNES_RIGHT) == GPAD_SNES_RIGHT) {
					uinput_gpad_write(&uinp_gpads[ctr], ABS_X, 4, EV_ABS);
				} else {
					uinput_gpad_write(&uinp_gpads[ctr], ABS_X, 2, EV_ABS);
				}
				if ((gpads[ctr].state & GPAD_SNES_UP) == GPAD_SNES_UP) {
					uinput_gpad_write(&uinp_gpads[ctr], ABS_Y, 0, EV_ABS);
				} else if ((gpads[ctr].state & GPAD_SNES_DOWN) == GPAD_SNES_DOWN) {
					uinput_gpad_write(&uinp_gpads[ctr], ABS_Y, 4, EV_ABS);
				} else {
					uinput_gpad_write(&uinp_gpads[ctr], ABS_Y, 2, EV_ABS);
				}
			}
		}

		if (confres.button_enabled) {
			btn_read(&button);

			switch (button.state) {
			case BTN_STATE_IDLE:
				break;
			case BTN_STATE_PRESSED:
				if (button.pressedCtr == 1 && button.duration >= 1) {
					uinput_kbd_write(&uinp_kbd, KEY_R, 1, EV_KEY);
				}
				break;
			case BTN_STATE_RELEASED:
					if (button.pressedCtr == 1 && button.duration >= 1) {
						uinput_kbd_write(&uinp_kbd, KEY_R, 0, EV_KEY);
					} else if (button.pressedCtr == 3 && button.duration >= 1) {
						// Sending ESC
						uinput_kbd_write(&uinp_kbd, KEY_ESC, 1, EV_KEY);
						usleep(50000);
						uinput_kbd_write(&uinp_kbd, KEY_ESC, 0, EV_KEY);
					} else if (button.pressedCtr == 5 && button.duration >= 1) {
						uinput_kbd_write(&uinp_kbd, KEY_F4, 1, EV_KEY);
						usleep(50000);
						uinput_kbd_write(&uinp_kbd, KEY_F4, 0, EV_KEY);
						// shutting down
						system("shutdown -t 3 -h now");
					}
				break;
			}
		}

		/* wait for some time to keep the CPU load low */
		if (confres.button_enabled && !(confres.gamepad1_enabled || confres.gamepad2_enabled)) {
			bcm2835_delay(FRAMEWAITLONG);
		} else {
			bcm2835_delay(FRAMEWAIT);
		}
	}

	return 0;

}
Exemple #2
0
int main(int argc, char* argv[]) {
	int result = 0;
	int rd, ctr, combo = 0, use_combos = 1;
	char keyStates[256];

	int detach = 0;
	int opt;
	while ((opt = getopt(argc, argv, "+dsc")) != -1) {
		switch (opt) {
			case 'd':
				detach = 1;
				break;
			case 's':
				use_syslog = 1;
				break;
			case 'c':
				printf("Combos disabled\n");
				use_combos = 0;
				break;
			default:
				fprintf(stderr, "Usage: %s [-d] [-s]\n", argv[0]);
				exit(EXIT_FAILURE);
				break;
		}
	}

	SYSLOG(LOG_NOTICE, "Starting.");

	printf("[Xarcade2Joystick] Getting exclusive access: ");
	result = input_xarcade_open(&xarcdev, INPUT_XARC_TYPE_TANKSTICK);
	if (result != 0) {
		if (errno == 0) {
			printf("Not found.\n");
			SYSLOG(LOG_ERR, "Xarcade not found, exiting.");
		} else {
			printf("Failed to get exclusive access to Xarcade: %d (%s)\n", errno, strerror(errno));
			SYSLOG(LOG_ERR, "Failed to get exclusive access to Xarcade, exiting: %d (%s)", errno, strerror(errno));
		}
		exit(EXIT_FAILURE);
	}

	SYSLOG(LOG_NOTICE, "Got exclusive access to Xarcade.");

	uinput_gpad_open(&uinp_gpads[0], UINPUT_GPAD_TYPE_XARCADE, 1);
	uinput_gpad_open(&uinp_gpads[1], UINPUT_GPAD_TYPE_XARCADE, 2);
	uinput_kbd_open(&uinp_kbd);

	if (detach) {
		if (daemon(0, 1)) {
			perror("daemon");
			return 1;
		}
	}
	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);

	SYSLOG(LOG_NOTICE, "Running.");

	while (1) {
		rd = input_xarcade_read(&xarcdev);
		if (rd < 0) {
			break;
		}

		for (ctr = 0; ctr < rd; ctr++) {
			if (xarcdev.ev[ctr].type == 0)
				continue;
			if (xarcdev.ev[ctr].type == EV_MSC)
				continue;
			if (EV_KEY == xarcdev.ev[ctr].type) {

				keyStates[xarcdev.ev[ctr].code] = xarcdev.ev[ctr].value;

				switch (xarcdev.ev[ctr].code) {

				/* ----------------  Player 1 controls ------------------- */
				/* buttons */
				case KEY_LEFTCTRL:
					uinput_gpad_write(&uinp_gpads[0], BTN_A,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_LEFTALT:
					uinput_gpad_write(&uinp_gpads[0], BTN_B,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_SPACE:
					uinput_gpad_write(&uinp_gpads[0], BTN_C,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_LEFTSHIFT:
					uinput_gpad_write(&uinp_gpads[0], BTN_X,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_Z:
					uinput_gpad_write(&uinp_gpads[0], BTN_Y,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_X:
					uinput_gpad_write(&uinp_gpads[0], BTN_Z,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_C:
					uinput_gpad_write(&uinp_gpads[0], BTN_TL,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_5:
					uinput_gpad_write(&uinp_gpads[0], BTN_TR,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_1:
					if (!use_combos)
						uinput_gpad_write(&uinp_gpads[0], BTN_START, xarcdev.ev[ctr].value > 0, EV_KEY);
					else {
						/* handle combination */
						if (keyStates[KEY_3] && xarcdev.ev[ctr].value) {
							uinput_kbd_write(&uinp_kbd, KEY_TAB, 1, EV_KEY);
							uinput_kbd_sleep();
							uinput_kbd_write(&uinp_kbd, KEY_TAB, 0, EV_KEY);
							combo = 2;
							continue;
						}
						/* it's a key down, ignore */
						if (xarcdev.ev[ctr].value)
							continue;
						if (!combo) {
							uinput_gpad_write(&uinp_gpads[0], BTN_START, 1, EV_KEY);
							uinput_gpad_sleep();
							uinput_gpad_write(&uinp_gpads[0], BTN_START, 0, EV_KEY);
						} else
							combo--;
					}
					break;
				case KEY_3:
					if (!use_combos)
						uinput_gpad_write(&uinp_gpads[0], BTN_SELECT,
								xarcdev.ev[ctr].value > 0, EV_KEY);
					else {
						/* it's a key down, ignore */
						if (xarcdev.ev[ctr].value)
							continue;
						if (!combo) {
							uinput_gpad_write(&uinp_gpads[0], BTN_SELECT, 1, EV_KEY);
							uinput_gpad_sleep();
							uinput_gpad_write(&uinp_gpads[0], BTN_SELECT, 0, EV_KEY);
						} else
							combo--;
					}
					break;

					/* joystick */
				case KEY_KP4:
				case KEY_LEFT:
					uinput_gpad_write(&uinp_gpads[0], ABS_X,
							xarcdev.ev[ctr].value == 0 ? 2 : 0, EV_ABS); // center or left
					break;
				case KEY_KP6:
				case KEY_RIGHT:
					uinput_gpad_write(&uinp_gpads[0], ABS_X,
							xarcdev.ev[ctr].value == 0 ? 2 : 4, EV_ABS); // center or right
					break;
				case KEY_KP8:
				case KEY_UP:
					uinput_gpad_write(&uinp_gpads[0], ABS_Y,
							xarcdev.ev[ctr].value == 0 ? 2 : 0, EV_ABS); // center or up
					break;
				case KEY_KP2:
				case KEY_DOWN:
					uinput_gpad_write(&uinp_gpads[0], ABS_Y,
							xarcdev.ev[ctr].value == 0 ? 2 : 4, EV_ABS); // center or down
					break;

					/* ----------------  Player 2 controls ------------------- */
					/* buttons */
				case KEY_A:
					uinput_gpad_write(&uinp_gpads[1], BTN_A,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_S:
					uinput_gpad_write(&uinp_gpads[1], BTN_B,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_Q:
					uinput_gpad_write(&uinp_gpads[1], BTN_C,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_W:
					uinput_gpad_write(&uinp_gpads[1], BTN_X,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_E:
					uinput_gpad_write(&uinp_gpads[1], BTN_Y,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_LEFTBRACE:
					uinput_gpad_write(&uinp_gpads[1], BTN_Z,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_RIGHTBRACE:
					uinput_gpad_write(&uinp_gpads[1], BTN_TL,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_6:
					uinput_gpad_write(&uinp_gpads[1], BTN_TR,
							xarcdev.ev[ctr].value > 0, EV_KEY);
					break;
				case KEY_2:
					if (!use_combos)
						uinput_gpad_write(&uinp_gpads[1], BTN_START, xarcdev.ev[ctr].value > 0, EV_KEY);
					else {
						/* handle combination */
						if (keyStates[KEY_4] && xarcdev.ev[ctr].value) {
							uinput_kbd_write(&uinp_kbd, KEY_ESC, 1, EV_KEY);
							uinput_kbd_sleep();
							uinput_kbd_write(&uinp_kbd, KEY_ESC, 0, EV_KEY);
							combo = 2;
							continue;
						}
						/* it's a key down, ignore */
						if (xarcdev.ev[ctr].value)
							continue;
						if (!combo) {
							uinput_gpad_write(&uinp_gpads[1], BTN_START, 1, EV_KEY);
							uinput_gpad_sleep();
							uinput_gpad_write(&uinp_gpads[1], BTN_START, 0, EV_KEY);
						} else
							combo--;
					}
					break;
				case KEY_4:
					if (!use_combos)
						uinput_gpad_write(&uinp_gpads[1], BTN_SELECT, xarcdev.ev[ctr].value > 0, EV_KEY);
					else {
						/* it's a key down, ignore */
						if (xarcdev.ev[ctr].value)
							continue;
						if (!combo) {
							uinput_gpad_write(&uinp_gpads[1], BTN_SELECT, 1, EV_KEY);
							uinput_gpad_sleep();
							uinput_gpad_write(&uinp_gpads[1], BTN_SELECT, 0, EV_KEY);
						} else
							combo--;
					}
					break;

					/* joystick */
				case KEY_D:
					uinput_gpad_write(&uinp_gpads[1], ABS_X,
							xarcdev.ev[ctr].value == 0 ? 2 : 0, EV_ABS); // center or left
					break;
				case KEY_G:
					uinput_gpad_write(&uinp_gpads[1], ABS_X,
							xarcdev.ev[ctr].value == 0 ? 2 : 4, EV_ABS); // center or right
					break;
				case KEY_R:
					uinput_gpad_write(&uinp_gpads[1], ABS_Y,
							xarcdev.ev[ctr].value == 0 ? 2 : 0, EV_ABS); // center or up
					break;
				case KEY_F:
					uinput_gpad_write(&uinp_gpads[1], ABS_Y,
							xarcdev.ev[ctr].value == 0 ? 2 : 4, EV_ABS); // center or down
					break;

				default:
					break;
				}
			}
		}
	}

	teardown();
	return EXIT_SUCCESS;
}