static void handle_icade_event(unsigned keycode) { static const struct { bool up; int button; } icade_map[0x20] = { { false, -1 }, { false, -1 }, { false, -1 }, { false, -1 }, // 0 { false, 2 }, { false, -1 }, { true , 3 }, { false, 3 }, // 4 { true , 0 }, { true, 5 }, { true , 7 }, { false, 8 }, // 8 { false, 6 }, { false, 9 }, { false, 10 }, { false, 11 }, // C { true , 6 }, { true , 9 }, { false, 7 }, { true, 10 }, // 0 { true , 2 }, { true , 8 }, { false, -1 }, { true , 4 }, // 4 { false, 5 }, { true , 11 }, { false, 0 }, { false, 1 }, // 8 { false, 4 }, { true , 1 }, { false, -1 }, { false, -1 } // C }; driver_t *driver = driver_get_ptr(); apple_input_data_t *apple = (apple_input_data_t*)driver->input_data; if (apple->icade_enabled && (keycode < 0x20) && (icade_map[keycode].button >= 0)) { const int button = icade_map[keycode].button; if (icade_map[keycode].up) BIT32_CLEAR(apple->icade_buttons, button); else BIT32_SET(apple->icade_buttons, button); } }
static void handle_icade_event(unsigned keycode) { static const struct { bool up; int button; } icade_map[0x20] = { { false, -1 }, { false, -1 }, { false, -1 }, { false, -1 }, // 0 { false, 2 }, { false, -1 }, { true , 3 }, { false, 3 }, // 4 { true , 0 }, { true, 5 }, { true , 7 }, { false, 8 }, // 8 { false, 6 }, { false, 9 }, { false, 10 }, { false, 11 }, // C { true , 6 }, { true , 9 }, { false, 7 }, { true, 10 }, // 0 { true , 2 }, { true , 8 }, { false, -1 }, { true , 4 }, // 4 { false, 5 }, { true , 11 }, { false, 0 }, { false, 1 }, // 8 { false, 4 }, { true , 1 }, { false, -1 }, { false, -1 } // C }; if (icade_enabled && (keycode < 0x20) && (icade_map[keycode].button >= 0)) { const int button = icade_map[keycode].button; if (icade_map[keycode].up) BIT32_CLEAR(icade_buttons, button); else BIT32_SET(icade_buttons, button); } }
static void parport_poll_pad(struct parport_joypad *pad) { /* RetroArch uses an extended version of the Linux * Multisystem 2-button joystick protocol for parallel port * joypads: * * | Function | Pin | Register | Bit | Active | * |-------------|-----|----------|-----|--------| * | Up | 2 | Data | 0 | Low | * | Down | 3 | Data | 1 | Low | * | Left | 4 | Data | 2 | Low | * | Right | 5 | Data | 3 | Low | * | A | 6 | Data | 4 | Low | * | B | 7 | Data | 5 | Low | * | Start | 8 | Data | 6 | Low | * | Select | 9 | Data | 7 | Low | * | Menu toggle | 10 | Status | 6 | Low | * | X | 11 | Status | 7 | Low* | * | Y | 12 | Status | 5 | Low | * | L1 | 13 | Status | 4 | Low | * | R1 | 15 | Status | 3 | Low | * * (*) Pin is hardware inverted, but RetroArch inverts it * back again so the same pullup scheme may be used for * all pins. * * Pin 1 is set high so it can be used for pullups. * * RetroArch does not perform debouncing, and so long as * the button settling time is less than the frame time * no bouncing will be observed. This replicates the latching * behavior common in old games consoles. For optimum latency * and jitter a high performance debouncing routine should be * implemented in the controller hardware. */ int i; char data; char status; if (ioctl(pad->fd, PPRDATA, &data) < 0) return; if (ioctl(pad->fd, PPRSTATUS, &status) < 0) return; for (i = 0; i < 8; i++) { if (!(data & UINT8_C(1 << i)) && pad->button_enable[i]) BIT32_SET(pad->buttons, i); else BIT32_CLEAR(pad->buttons, i); } for (i = 3; i < 8; i++) { if (!(status & UINT8_C(1 << i)) && pad->button_enable[i + 5]) BIT32_SET(pad->buttons, i + 5); else BIT32_CLEAR(pad->buttons, i + 5); } if (BIT32_GET(pad->buttons, 12) && pad->button_enable[12]) BIT32_CLEAR(pad->buttons, 12); else BIT32_SET(pad->buttons, 12); }