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

    buttonstates padButtons;
	snespad pads;
	pollButton = 1;
	pollPads = 1;
	doRun = 1;

	// check command line arguments
	if (argc > 1) {
		// argv[1]==1 poll controllers only
		// argv[1]==2 poll button only
		// argv[1]==3 poll controllers and button
		switch ( atoi(argv[argc-1]) ) {
			case 1:
				printf("[SNESDev-Rpi] Polling only controllers.\n");
				pollButton = 0;
				pollPads = 1;
			break;
			case 2:
				printf("[SNESDev-Rpi] Polling button only.\n");
				pollButton = 1;
				pollPads = 0;
			break;
			case 3:
				printf("[SNESDev-Rpi] Polling controllers and button.\n");
				pollButton = 1;
				pollPads = 1;
			break;
			default:
				return -1;
		}
    } else {
    	printf("[SNESDev-Rpi] Polling controllers and button.\n");
    }

    if (!bcm2835_init())
        return 1;

	// initialize button and LEDs
    bcm2835_gpio_fsel(BUTTONPIN,  BCM2835_GPIO_FSEL_INPT);

    /* initialize controller structures with GPIO pin assignments */

    // pin out used in SNESDev article on blog
	// pads.clock  = RPI_GPIO_P1_18;
	// pads.strobe = RPI_GPIO_P1_16;
	// pads.data1  = RPI_GPIO_P1_22;
	// pads.data2  = RPI_GPIO_P1_15;

    // pin out used pi gamecon GPIO driver
	pads.clock  = RPI_GPIO_P1_19;
	pads.strobe = RPI_GPIO_P1_23;
	pads.data1  = RPI_GPIO_P1_07;
	pads.data2  = RPI_GPIO_P1_05;

	/* set GPIO pins as input or output pins */
	initializePads( &pads );

	/* intialize virtual input device */
	if ((uinp_fd = setup_uinput_device()) < 0) {
		printf("[SNESDev-Rpi] Unable to find uinput device\n");
		return -1;
	}

	if (signal(SIGINT, sig_handler) == SIG_ERR)
  		printf("\n[SNESDev-Rpi] Cannot catch SIGINT\n");

	/* enter the main loop */
	while ( doRun ) {

		if (pollButton) {
			/* Check state of button. */
			checkButton(uinp_fd);
		}

		if (pollPads) {
			/* read states of the buttons */
			updateButtons(&pads, &padButtons);

			/* send an event (pressed or released) for each button */
			/* key events for first controller */
	        processPadBtn(padButtons.buttons1, SNES_A,     KEY_X,          uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_B,     KEY_Z,          uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_X,     KEY_S,          uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_Y,     KEY_A,          uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_L,     KEY_Q,          uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_R,     KEY_W,          uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_SELECT,KEY_RIGHTSHIFT, uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_START, KEY_ENTER,      uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_LEFT,  KEY_LEFT,       uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_RIGHT, KEY_RIGHT,      uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_UP,    KEY_UP,         uinp_fd);
	        processPadBtn(padButtons.buttons1, SNES_DOWN,  KEY_DOWN,       uinp_fd);

			// key events for second controller 
	        processPadBtn(padButtons.buttons2, SNES_A,     KEY_E, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_B,     KEY_R, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_X,     KEY_T, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_Y,     KEY_Y, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_L,     KEY_U, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_R,     KEY_I, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_SELECT,KEY_O, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_START, KEY_P, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_LEFT,  KEY_C, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_RIGHT, KEY_B, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_UP,    KEY_F, uinp_fd);
	        processPadBtn(padButtons.buttons2, SNES_DOWN,  KEY_V, uinp_fd);
		}

		/* wait for some time to keep the CPU load low */
		delay(FRAMEWAIT);
	}

	return 0;
}
Beispiel #2
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;

}