Compare commits
41 commits
mcp_and_co
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89b32aff4e | ||
|
|
e00b1e42b3 | ||
|
|
e1211cc3b3 | ||
|
|
b96271899d | ||
|
|
1fd4547a84 | ||
|
|
f01d6cbd20 | ||
|
|
02fe5c5e54 | ||
|
|
0f5a63e148 | ||
|
|
d5378c9fae | ||
|
|
7232ce30ed | ||
|
|
e59c447387 | ||
|
|
6ba9dbd2b1 | ||
|
|
e1e26388b7 | ||
|
|
2c7bf8394b | ||
|
|
959ae84491 | ||
|
|
ce3b56f6fa | ||
|
|
8af8cef703 | ||
|
|
2b1a3c3a20 | ||
|
|
229a2aba5c | ||
|
|
dd7ef1d972 | ||
|
|
ee2b692971 | ||
|
|
067c0eaf35 | ||
|
|
90c984278a | ||
|
|
801a8fa5c6 | ||
|
|
7bae96f09a | ||
|
|
2d8b238f1f | ||
|
|
371704e2df | ||
|
|
e6759becba | ||
|
|
eb23e0710b | ||
|
|
67a447ea59 | ||
|
|
5e36073db9 | ||
|
|
c27f3d00f1 | ||
|
|
05fdceb064 | ||
|
|
8da6665a29 | ||
|
|
7285e79fb3 | ||
|
|
0e6ef48ffd | ||
|
|
17889814ec | ||
|
|
db879735d9 | ||
|
|
01df65c954 | ||
|
|
fd4f28a419 | ||
|
|
4d59757aa8 |
20 changed files with 2451 additions and 376 deletions
23
Makefile
23
Makefile
|
|
@ -1,12 +1,25 @@
|
|||
EXECS = retrogame gamera
|
||||
CC = gcc $(CFLAGS) -Wall -O3 -fomit-frame-pointer -funroll-loops -s
|
||||
#EXECS = retrogame gamera
|
||||
EXECS = retrogame
|
||||
CFLAGS = -Wall -Ofast -fomit-frame-pointer -funroll-loops -s \
|
||||
-I/opt/vc/include \
|
||||
-I/opt/vc/include/interface/vcos/pthreads \
|
||||
-I/opt/vc/include/interface/vmcs_host \
|
||||
-I/opt/vc/include/interface/vmcs_host/linux \
|
||||
-L/opt/vc/lib
|
||||
LIBS = -lbcm_host
|
||||
CC = gcc $(CFLAGS)
|
||||
|
||||
all: $(EXECS)
|
||||
|
||||
retrogame: retrogame.c
|
||||
$(CC) $< -o $@
|
||||
retrogame: retrogame.c keyTable.h
|
||||
$(CC) $< $(LIBS) -o $@
|
||||
strip $@
|
||||
|
||||
# KEYFILE = /usr/include/linux/input.h
|
||||
KEYFILE = /usr/include/linux/input-event-codes.h
|
||||
keyTable.h: keyTableGen.sh $(KEYFILE)
|
||||
sh $^ >$@
|
||||
|
||||
gamera: gamera.c
|
||||
$(CC) $< -lncurses -lmenu -lexpat -o $@
|
||||
strip $@
|
||||
|
|
@ -15,4 +28,4 @@ install:
|
|||
mv $(EXECS) /usr/local/bin
|
||||
|
||||
clean:
|
||||
rm -f $(EXECS)
|
||||
rm -f $(EXECS) keyTable.h
|
||||
|
|
|
|||
26
README.md
26
README.md
|
|
@ -1,11 +1,23 @@
|
|||
Adafruit-Retrogame
|
||||
==================
|
||||
|
||||
Raspberry Pi GPIO-to-USB utility for classic game emulators.
|
||||
Raspberry Pi GPIO-to-virtual-keyboard utility for classic game emulators.
|
||||
|
||||
How-to: http://learn.adafruit.com/retro-gaming-with-raspberry-pi
|
||||
How-to: https://learn.adafruit.com/retro-gaming-with-raspberry-pi
|
||||
|
||||
Pre-built version supports the default pin/key mapping shown in the tutorial. For other layouts, edit retrogame.c.
|
||||
### NEED HELP?
|
||||
|
||||
__Visit forums.adafruit.com (General Project Help) for retrogame-related questions.__ GitHub's "Issues" tab is for bug reports and feature requests. __99% of retrogame problems are configuration, not bugs.__ Make sure to follow the "RetroPie 2.0+ Compatibility" directions below. Also, use Broadcom GPIO numbers, _not_ the physical pin index.
|
||||
|
||||
When requesting help, please be thorough in your description. Which model of Raspberry Pi, what release of RetroPie (or other OS image), and (if the trouble is localized) which system emulator exactly? For hardware-related issues, photos are extremely helpful. Thanks!
|
||||
|
||||
__For emulation-related questions (e.g. individual games not working), please use a support forum relevant to the software in use, e.g. the RetroPie Forum at https://retropie.org.uk/forum/ if using that package.__ Adafruit does not develop these emulators or the EmulationStation front-end.
|
||||
|
||||
### NEW: Configuration file
|
||||
|
||||
retrogame now loads its pin/key settings from a file; no code editing required. An example file 'retrogame.cfg' is included in the 'configs' directory, copy this file to the /boot directory so retrogame can find it (/boot makes it easier to edit with the card in a reader on another system). Alternately, an absolute pathname to a settings file can be passed on the command line. This file can be edited live, no need to restart retrogame after making changes.
|
||||
|
||||
__THE ioStandard[] AND ioTFT[] TABLES NO LONGER EXIST IN THE SOURCE CODE. You should not need to edit ANY source code to make retrogame work.__ Everything is handled through the configuration file now. Some guides may be out of date and still refer to the old way; these will be updated over time.
|
||||
|
||||
### RetroPie 2.0+ Compatibility
|
||||
|
||||
|
|
@ -24,3 +36,11 @@ SUBSYSTEM=="input", ATTRS{name}=="retrogame", ENV{ID_INPUT_KEYBOARD}="1"
|
|||
````
|
||||
|
||||
Save the file by pressing Ctrl-O and enter, then press Ctrl-x to exit. Restart your Raspberry Pi and run retrogame again, now button presses should register in SDL2 applications like the EmulationStation frontend to RetroPie
|
||||
|
||||
---
|
||||
|
||||
### Roadmap
|
||||
|
||||
Development of the C retrogame program at this point is in maintenance mode -- bugs will be looked at and corrected where possible, but don't expect significant new features (such as support for more I/O port expander types), nor will pull requests for such be merged. The code has grown untenably complex.
|
||||
|
||||
retrogame is a product of its time; first-generation Raspberry Pi devices with sub-optimal emulation software were common and obtuse C code was used to minimize memory use and CPU load. There's little benefit to such an approach now. For the Arcade Bonnet and Joy Bonnet, you'll see there are now simpler, device-specific Python scripts being used...either one consumes just a fraction of a percent of a system's resources. Rather than wrestling the retrogame code into doing Yet Another Thing, consider using one of these Python scripts as a starting point, and focus on just that one task.
|
||||
|
|
|
|||
95
arcadeBonnet.py
Normal file
95
arcadeBonnet.py
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Somewhat minimal Adafruit Arcade Bonnet handler. Runs in background,
|
||||
# translates inputs from MCP23017 port expander to virtual USB keyboard
|
||||
# events. Not -quite- as efficient or featuretastic as retrogame, but
|
||||
# still reasonably lightweight and may be easier and/or more reliable than
|
||||
# retrogame for some users. Supports ONE port expander, no regular GPIO
|
||||
# (non-port-expander) or "Vulcan nerve pinch" features.
|
||||
# Prerequisites:
|
||||
# sudo apt-get install python-pip python-smbus python-dev
|
||||
# sudo pip install evdev
|
||||
# Be sure to enable I2C via raspi-config. Also, udev rules will need to
|
||||
# be set up per retrogame directions.
|
||||
# Credit to Pimoroni for Picade HAT scripts as starting point.
|
||||
|
||||
import os
|
||||
import time
|
||||
import RPi.GPIO as gpio
|
||||
from evdev import uinput, UInput, ecodes as e
|
||||
from smbus import SMBus
|
||||
|
||||
key = [ # EDIT KEYCODES IN THIS TABLE TO YOUR PREFERENCES:
|
||||
# See /usr/include/linux/input.h for keycode names
|
||||
# Keyboard Bonnet EmulationStation
|
||||
e.KEY_LEFTCTRL, # 1A 'A' button
|
||||
e.KEY_LEFTALT, # 1B 'B' button
|
||||
e.KEY_A, # 1C 'X' button
|
||||
e.KEY_S, # 1D 'Y' button
|
||||
e.KEY_5, # 1E 'Select' button
|
||||
e.KEY_1, # 1F 'Start' button
|
||||
0, # Bit 6 NOT CONNECTED on Bonnet
|
||||
0, # Bit 7 NOT CONNECTED on Bonnet
|
||||
e.KEY_DOWN, # 4-way down D-pad down
|
||||
e.KEY_UP, # 4-way up D-pad up
|
||||
e.KEY_RIGHT, # 4-way right D-pad right
|
||||
e.KEY_LEFT, # 4-way left D-pad left
|
||||
e.KEY_L, # Analog right
|
||||
e.KEY_H, # Analog left
|
||||
e.KEY_J, # Analog down
|
||||
e.KEY_K # Analog up
|
||||
]
|
||||
|
||||
addr = 0x26 # I2C Address of MCP23017
|
||||
irqPin = 17 # IRQ pin for MCP23017
|
||||
|
||||
os.system("sudo modprobe uinput")
|
||||
|
||||
ui = UInput({e.EV_KEY: key}, name="retrogame", bustype=e.BUS_USB)
|
||||
bus = SMBus(1)
|
||||
IODIRA = 0x00
|
||||
IOCONA = 0x0A
|
||||
INTCAPA = 0x10
|
||||
|
||||
# Initial MCP23017 config:
|
||||
bus.write_byte_data(addr, 0x05 , 0x00) # If bank 1, switch to 0
|
||||
bus.write_byte_data(addr, IOCONA, 0x44) # Bank 0, INTB=A, seq, OD IRQ
|
||||
|
||||
# Read/modify/write remaining MCP23017 config:
|
||||
cfg = bus.read_i2c_block_data(addr, IODIRA, 14)
|
||||
cfg[ 0] = 0xFF # Input bits
|
||||
cfg[ 1] = 0xFF
|
||||
cfg[ 2] = 0x00 # Polarity
|
||||
cfg[ 3] = 0x00
|
||||
cfg[ 4] = 0xFF # Interrupt pins
|
||||
cfg[ 5] = 0xFF
|
||||
cfg[12] = 0xFF # Pull-ups
|
||||
cfg[13] = 0xFF
|
||||
bus.write_i2c_block_data(addr, IODIRA, cfg)
|
||||
|
||||
# Clear interrupt by reading INTCAP and GPIO registers
|
||||
x = bus.read_i2c_block_data(addr, INTCAPA, 4)
|
||||
oldState = x[2] | (x[3] << 8)
|
||||
|
||||
# Callback for MCP23017 interrupt request
|
||||
def mcp_irq(pin):
|
||||
global oldState
|
||||
x = bus.read_i2c_block_data(addr, INTCAPA, 4)
|
||||
newState = x[2] | (x[3] << 8)
|
||||
for i in range(16):
|
||||
bit = 1 << i
|
||||
lvl = newState & bit
|
||||
if lvl != (oldState & bit):
|
||||
ui.write(e.EV_KEY, key[i], 0 if lvl else 1)
|
||||
ui.syn()
|
||||
oldState = newState
|
||||
|
||||
# GPIO init
|
||||
gpio.setwarnings(False)
|
||||
gpio.setmode(gpio.BCM)
|
||||
|
||||
# Enable pullup and callback on MCP23017 IRQ pin
|
||||
gpio.setup(irqPin, gpio.IN, pull_up_down=gpio.PUD_UP)
|
||||
gpio.add_event_detect(irqPin, gpio.FALLING, callback=mcp_irq)
|
||||
|
||||
while True: time.sleep(1)
|
||||
84
arcade_bonnet_test.sh
Executable file
84
arcade_bonnet_test.sh
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
#/bin/bash
|
||||
|
||||
# Arcade Bonnet troubleshooting tool. Checks whether prerequisite
|
||||
# config and tools are present, and runs live status of inputs.
|
||||
|
||||
# Test if primary I2C enabled, offer help if needed
|
||||
if [ ! -c /dev/i2c-1 ]
|
||||
then
|
||||
echo "I2C not present. Enable with:"
|
||||
echo " sudo raspi-config nonint do_i2c 0"
|
||||
echo "or use raspi-config 'Interface Options' menu"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test if i2ctools installed, offer help if needed
|
||||
if ! type i2cset >/dev/null 2>&1
|
||||
then
|
||||
echo "i2c-tools not present. Install with:"
|
||||
echo " sudo apt-get install i2c-tools"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# MCP23017 I2C address default is 0x20, Arcade Bonnet uses 0x26:
|
||||
MCP_ADDR=0x26
|
||||
|
||||
# registers
|
||||
IODIRA=0x00
|
||||
IODIRB=0x01
|
||||
GPPUA=0x0C
|
||||
GPPUB=0x0D
|
||||
GPIOA=0x12
|
||||
GPIOB=0x13
|
||||
|
||||
# set all pins to input
|
||||
i2cset -y 1 $MCP_ADDR $IODIRA 0xFF
|
||||
i2cset -y 1 $MCP_ADDR $IODIRB 0xFF
|
||||
|
||||
# enable internal pull up on all pins
|
||||
i2cset -y 1 $MCP_ADDR $GPPUA 0xFF
|
||||
i2cset -y 1 $MCP_ADDR $GPPUB 0xFF
|
||||
|
||||
# Display one input state, showing '*' if currently active
|
||||
disp() {
|
||||
if [ $(($2 >> $3 & 0x01)) -ne 0 ]
|
||||
then
|
||||
echo " $1 :"
|
||||
else
|
||||
echo " $1 : *"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test all Arcade Bonnet inputs in a loop
|
||||
while :
|
||||
do
|
||||
# read pin state
|
||||
GPA=$(i2cget -y 1 $MCP_ADDR $GPIOA)
|
||||
GPB=$(i2cget -y 1 $MCP_ADDR $GPIOB)
|
||||
|
||||
# report
|
||||
clear
|
||||
echo "===== BUTTONS ====="
|
||||
echo "raw value = $GPA"
|
||||
disp "1A" $GPA 0
|
||||
disp "1B" $GPA 1
|
||||
disp "1C" $GPA 2
|
||||
disp "1D" $GPA 3
|
||||
disp "1E" $GPA 4
|
||||
disp "1F" $GPA 5
|
||||
|
||||
echo "==== JOYSTICKS ===="
|
||||
echo "raw value = $GPB"
|
||||
echo "4-WAY"
|
||||
disp "L" $GPB 3
|
||||
disp "R" $GPB 2
|
||||
disp "U" $GPB 1
|
||||
disp "D" $GPB 0
|
||||
echo "ANALOG"
|
||||
disp "L" $GPB 5
|
||||
disp "R" $GPB 4
|
||||
disp "U" $GPB 6
|
||||
disp "D" $GPB 7
|
||||
|
||||
echo "== CTRL-C TO EXIT =="
|
||||
done
|
||||
34
configs/retrogame.cfg
Executable file
34
configs/retrogame.cfg
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the PiGRRL 2 project:
|
||||
|
||||
LEFT 4 # Joypad left
|
||||
RIGHT 19 # Joypad right
|
||||
UP 16 # Joypad up
|
||||
DOWN 26 # Joypad down
|
||||
LEFTCTRL 14 # 'A' button
|
||||
LEFTALT 15 # 'B' button
|
||||
Z 20 # 'X' button
|
||||
X 18 # 'Y' button
|
||||
SPACE 5 # 'Select' button
|
||||
ENTER 6 # 'Start' button
|
||||
A 12 # Left shoulder button
|
||||
S 13 # Right shoulder button
|
||||
ESC 17 # Exit ROM; PiTFT Button 1
|
||||
1 22 # PiTFT Button 2
|
||||
2 23 # PiTFT Button 3
|
||||
3 27 # PiTFT Button 4
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
26
configs/retrogame.cfg.2button
Executable file
26
configs/retrogame.cfg.2button
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a minimal config for the "Retro Gaming" guide,
|
||||
# 4-way stick + 2 buttons; have keyboard handy for other functions.
|
||||
|
||||
LEFTCTRL 23 # Left control key = fire/jump/primary/'A' button
|
||||
LEFTALT 7 # Left alt key = thrust/seconady/'B' button
|
||||
UP 10
|
||||
DOWN 17
|
||||
LEFT 25
|
||||
RIGHT 9
|
||||
ESC 23 7 # Esc key = hold 'A'+'B' buttons (exit ROM)
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
30
configs/retrogame.cfg.6button
Executable file
30
configs/retrogame.cfg.6button
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a 6-button configuration:
|
||||
|
||||
LEFT 10 # Joypad left
|
||||
RIGHT 22 # Joypad right
|
||||
UP 23 # Joypad up
|
||||
DOWN 27 # Joypad down
|
||||
LEFTCTRL 4 # 'A' button
|
||||
LEFTALT 25 # 'B' button
|
||||
Z 11 # 'X' button
|
||||
X 5 # 'Y' button
|
||||
GND 6 # Spare ground point for 'Y' button
|
||||
SPACE 16 # 'Select' button
|
||||
ENTER 26 # 'Start' button
|
||||
ESC 16 26 # Hold Start+Select to exit ROM
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
48
configs/retrogame.cfg.bonnet
Executable file
48
configs/retrogame.cfg.bonnet
Executable file
|
|
@ -0,0 +1,48 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the Adafruit Arcade Bonnet. This board is
|
||||
# based on the MCP23017 I2C port expander, with a default address of 0x26
|
||||
# (solder jumper selects 0x27 if needed). retrogame treats port expanders
|
||||
# as their own GPIO pin numbers beyond the normal 0-31:
|
||||
|
||||
# 0 - 31 GPIO header 'P5' (Broadcom pin numbers)
|
||||
# 32 - 47 MCP23017 at address 0x20
|
||||
# 48 - 63 MCP23017 at address 0x21
|
||||
# 64 - 79 MCP23017 at address 0x22
|
||||
# 80 - 95 MCP23017 at address 0x23
|
||||
# 96 - 111 MCP23017 at address 0x24
|
||||
# 112 - 127 MCP23017 at address 0x25
|
||||
# 128 - 143 MCP23017 at address 0x26 *** Arcade Bonnet default address
|
||||
# 144 - 159 MCP23017 at address 0x27 *** Arcade Bonnet alt address
|
||||
|
||||
# The Arcade Bonnet MUST be enabled with the IRQ command to
|
||||
# assign an interrupt request GPIO pin and I2C bus address.
|
||||
# IRQ pin for this board is hardwired as 17.
|
||||
|
||||
IRQ 17 0x26 # Arcade Bonnet default address, use GPIO 128-143
|
||||
|
||||
# Keyboard Bonnet EmulationStation
|
||||
LEFTCTRL 128 # Left control key 1A 'A' button
|
||||
LEFTALT 129 # Left alt key 1B 'B' button
|
||||
Z 130 # Z key 1C 'X' button
|
||||
X 131 # X key 1D 'Y' button
|
||||
SPACE 132 # Space bar 1E 'Select' button
|
||||
ENTER 133 # Enter key 1F 'Start' button
|
||||
ESC 132 133 # Escape key N/A Select + Start
|
||||
# 134, 135 not connected on Bonnet
|
||||
DOWN 136 # Down arrow 4-way down D-pad down
|
||||
UP 137 # Up arrow 4-way up D-pad up
|
||||
RIGHT 138 # Right arrow 4-way right D-pad right
|
||||
LEFT 139 # Left arrow 4-way left D-pad left
|
||||
L 140 # L key Analog right
|
||||
H 141 # H key Analog left
|
||||
J 142 # J key Analog down
|
||||
K 143 # K key Analog up
|
||||
28
configs/retrogame.cfg.cupcade-orig
Executable file
28
configs/retrogame.cfg.cupcade-orig
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the original Cupdade project:
|
||||
|
||||
LEFT 2 # Joystick (4 pins)
|
||||
RIGHT 3
|
||||
DOWN 4
|
||||
UP 17
|
||||
LEFTCTRL 27 # Fire/jump/primary
|
||||
LEFTALT 22 # Bomb/secondary
|
||||
5 23 # Credit
|
||||
1 18 # Start 1P
|
||||
ESC 23 18 # Credit + Start = exit emulator
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
|
||||
34
configs/retrogame.cfg.pigrrl2
Executable file
34
configs/retrogame.cfg.pigrrl2
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the PiGRRL 2 project:
|
||||
|
||||
LEFT 4 # Joypad left
|
||||
RIGHT 19 # Joypad right
|
||||
UP 16 # Joypad up
|
||||
DOWN 26 # Joypad down
|
||||
LEFTCTRL 14 # 'A' button
|
||||
LEFTALT 15 # 'B' button
|
||||
Z 20 # 'X' button
|
||||
X 18 # 'Y' button
|
||||
SPACE 5 # 'Select' button
|
||||
ENTER 6 # 'Start' button
|
||||
A 12 # Left shoulder button
|
||||
S 13 # Right shoulder button
|
||||
ESC 17 # Exit ROM; PiTFT Button 1
|
||||
1 22 # PiTFT Button 2
|
||||
2 23 # PiTFT Button 3
|
||||
3 27 # PiTFT Button 4
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
29
configs/retrogame.cfg.pocket
Executable file
29
configs/retrogame.cfg.pocket
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the Pocket PiGRRL project:
|
||||
|
||||
LEFT 4 # Joypad left
|
||||
RIGHT 17 # Joypad right
|
||||
UP 18 # Joypad up
|
||||
DOWN 27 # Joypad down
|
||||
LEFTCTRL 22 # 'A' button
|
||||
LEFTALT 23 # 'B' button
|
||||
Z 5 # 'X' button
|
||||
ESC 6 # Exit ROM; PiTFT Button 1
|
||||
ENTER 12 # 'Start' button
|
||||
SPACE 13 # 'Select' button
|
||||
X 16 # 'Y' button
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
30
configs/retrogame.cfg.super
Executable file
30
configs/retrogame.cfg.super
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the Super Game Pi project:
|
||||
|
||||
LEFT 22 # Joypad left
|
||||
RIGHT 23 # Joypad right
|
||||
UP 17 # Joypad up
|
||||
DOWN 27 # Joypad down
|
||||
Z 24 # 'A' button
|
||||
X 10 # 'B' button
|
||||
ESC 18 # 'Select' button
|
||||
ENTER 4 # 'Start' button
|
||||
S 9 # 'X' button
|
||||
A 25 # 'Y' button
|
||||
Q 11 # Left shoulder button
|
||||
W 8 # Right shoulder button
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
32
configs/retrogame.cfg.zero
Executable file
32
configs/retrogame.cfg.zero
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
# Sample configuration file for retrogame.
|
||||
# Really minimal syntax, typically two elements per line w/space delimiter:
|
||||
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
|
||||
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
|
||||
# Uses Broadcom pin numbers for GPIO.
|
||||
# If first element is GND, the corresponding pin (or pins, multiple can be
|
||||
# given) is a LOW-level output; an extra ground pin for connecting buttons.
|
||||
# A '#' character indicates a comment to end-of-line.
|
||||
# File can be edited "live," no need to restart retrogame!
|
||||
|
||||
# Here's a pin configuration for the PiGRRL Zero project:
|
||||
|
||||
LEFT 18 # Joypad left
|
||||
RIGHT 24 # Joypad right
|
||||
DOWN 5 # Joypad down
|
||||
UP 6 # Joypad up
|
||||
Z 12 # 'A' button
|
||||
X 13 # 'B' button
|
||||
A 16 # 'X' button
|
||||
S 19 # 'Y' button
|
||||
Q 20 # Left shoulder button
|
||||
W 21 # Right shoulder button
|
||||
ESC 17 # Exit ROM; PiTFT Button 1
|
||||
LEFTCTRL 22 # 'Select' button; PiTFT Button 2
|
||||
ENTER 23 # 'Start' button; PiTFT Button 3
|
||||
4 27 # PiTFT Button 4
|
||||
|
||||
# For configurations with few buttons (e.g. Cupcade), a key can be followed
|
||||
# by multiple pin numbers. When those pins are all held for a few seconds,
|
||||
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
|
||||
# Only ONE such combo is supported within the file though; later entries
|
||||
# will override earlier.
|
||||
5
gamera.c
5
gamera.c
|
|
@ -1,4 +1,9 @@
|
|||
/*
|
||||
DEPRECATED CODE - better handled by EmulationStation now.
|
||||
This code was a ROM file selector for MAME + fceu.
|
||||
Keeping it here for now in case any Cupcade users need it.
|
||||
|
||||
|
||||
gamera (Game Rom Aggregator): simple game selection interface for the
|
||||
advmame (arcade) and fceu (NES) emulators (maybe others in the future).
|
||||
|
||||
|
|
|
|||
195
joyBonnet.py
Normal file
195
joyBonnet.py
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Somewhat minimal Adafruit Joy Bonnet handler. Runs in background,
|
||||
# translates inputs from buttons and ADC joystick to virtual USB keyboard
|
||||
# events.
|
||||
# Prerequisites:
|
||||
# sudo apt-get install python-pip python-smbus python-dev
|
||||
# sudo pip install evdev
|
||||
# Be sure to enable I2C via raspi-config. Also, udev rules will need to
|
||||
# be set up per retrogame directions.
|
||||
# Credit to Pimoroni for Picade HAT scripts as starting point.
|
||||
|
||||
import time
|
||||
import signal
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from evdev import uinput, UInput, ecodes as e
|
||||
except ImportError:
|
||||
exit("This library requires the evdev module\nInstall with: sudo pip install evdev")
|
||||
|
||||
try:
|
||||
import RPi.GPIO as gpio
|
||||
except ImportError:
|
||||
exit("This library requires the RPi.GPIO module\nInstall with: sudo pip install RPi.GPIO")
|
||||
|
||||
try:
|
||||
from smbus import SMBus
|
||||
except ImportError:
|
||||
exit("This library requires the smbus module\nInstall with: sudo pip install smbus")
|
||||
|
||||
DEBUG = False
|
||||
BOUNCE_TIME = 0.01 # Debounce time in seconds
|
||||
|
||||
BUTTON_A = 12
|
||||
BUTTON_B = 6
|
||||
BUTTON_X = 16
|
||||
BUTTON_Y = 13
|
||||
SELECT = 20
|
||||
START = 26
|
||||
PLAYER1 = 23
|
||||
PLAYER2 = 22
|
||||
BUTTONS = [BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y, SELECT, START, PLAYER1, PLAYER2]
|
||||
|
||||
ANALOG_THRESH_NEG = -600
|
||||
ANALOG_THRESH_POS = 600
|
||||
analog_states = [False, False, False, False] # up down left right
|
||||
|
||||
KEYS= { # EDIT KEYCODES IN THIS TABLE TO YOUR PREFERENCES:
|
||||
# See /usr/include/linux/input.h for keycode names
|
||||
# Keyboard Bonnet EmulationStation
|
||||
BUTTON_A: e.KEY_LEFTCTRL, # 'A' button
|
||||
BUTTON_B: e.KEY_LEFTALT, # 'B' button
|
||||
BUTTON_X: e.KEY_Z, # 'X' button
|
||||
BUTTON_Y: e.KEY_X, # 'Y' button
|
||||
SELECT: e.KEY_SPACE, # 'Select' button
|
||||
START: e.KEY_ENTER, # 'Start' button
|
||||
PLAYER1: e.KEY_1, # '#1' button
|
||||
PLAYER2: e.KEY_2, # '#2' button
|
||||
1000: e.KEY_UP, # Analog up
|
||||
1001: e.KEY_DOWN, # Analog down
|
||||
1002: e.KEY_LEFT, # Analog left
|
||||
1003: e.KEY_RIGHT, # Analog right
|
||||
}
|
||||
|
||||
###################################### ADS1015 microdriver #################################
|
||||
# Register and other configuration values:
|
||||
ADS1x15_DEFAULT_ADDRESS = 0x48
|
||||
ADS1x15_POINTER_CONVERSION = 0x00
|
||||
ADS1x15_POINTER_CONFIG = 0x01
|
||||
|
||||
ADS1015_REG_CONFIG_CQUE_NONE = 0x0003 # Disable the comparator and put ALERT/RDY in high state (default)
|
||||
ADS1015_REG_CONFIG_CLAT_NONLAT = 0x0000 # Non-latching comparator (default)
|
||||
ADS1015_REG_CONFIG_CPOL_ACTVLOW = 0x0000 # ALERT/RDY pin is low when active (default)
|
||||
ADS1015_REG_CONFIG_CMODE_TRAD = 0x0000 # Traditional comparator with hysteresis (default)
|
||||
ADS1015_REG_CONFIG_DR_1600SPS = 0x0080 # 1600 samples per second (default)
|
||||
ADS1015_REG_CONFIG_MODE_SINGLE = 0x0100 # Power-down single-shot mode (default)
|
||||
ADS1015_REG_CONFIG_GAIN_ONE = 0x0200 # gain of 1
|
||||
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_0 = 0x4000 # channel 0
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_1 = 0x5000 # channel 1
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_2 = 0x6000 # channel 2
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_3 = 0x7000 # channel 3
|
||||
|
||||
ADS1015_REG_CONFIG_OS_SINGLE = 0x8000 # start a single conversion
|
||||
|
||||
ADS1015_REG_CONFIG_CHANNELS = (ADS1015_REG_CONFIG_MUX_SINGLE_0, ADS1015_REG_CONFIG_MUX_SINGLE_1,
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_2, ADS1015_REG_CONFIG_MUX_SINGLE_3)
|
||||
|
||||
def ads_read(channel):
|
||||
#configdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, 2)
|
||||
#print("Getting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
|
||||
configword = ADS1015_REG_CONFIG_CQUE_NONE | ADS1015_REG_CONFIG_CLAT_NONLAT | ADS1015_REG_CONFIG_CPOL_ACTVLOW | ADS1015_REG_CONFIG_CMODE_TRAD | ADS1015_REG_CONFIG_DR_1600SPS | ADS1015_REG_CONFIG_MODE_SINGLE | ADS1015_REG_CONFIG_GAIN_ONE | ADS1015_REG_CONFIG_CHANNELS[channel] | ADS1015_REG_CONFIG_OS_SINGLE
|
||||
configdata = [configword >> 8, configword & 0xFF]
|
||||
|
||||
#print("Setting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
bus.write_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, configdata)
|
||||
|
||||
configdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, 2)
|
||||
#print("Getting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
|
||||
while True:
|
||||
try:
|
||||
configdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, 2)
|
||||
#print("Getting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
if (configdata[0] & 0x80):
|
||||
break
|
||||
except:
|
||||
pass
|
||||
# read data out!
|
||||
analogdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONVERSION, 2)
|
||||
#print(analogdata),
|
||||
retval = (analogdata[0] << 8) | analogdata[1]
|
||||
retval /= 16
|
||||
#print("-> %d" %retval)
|
||||
return retval
|
||||
|
||||
######################## main program
|
||||
|
||||
os.system("sudo modprobe uinput")
|
||||
|
||||
bus = SMBus(1)
|
||||
|
||||
# GPIO init
|
||||
gpio.setwarnings(False)
|
||||
gpio.setmode(gpio.BCM)
|
||||
gpio.setup(BUTTONS, gpio.IN, pull_up_down=gpio.PUD_UP)
|
||||
|
||||
try:
|
||||
ui = UInput({e.EV_KEY: KEYS.values()}, name="retrogame", bustype=e.BUS_USB)
|
||||
except uinput.UInputError as e:
|
||||
sys.stdout.write(e.message)
|
||||
sys.stdout.write("Have you tried running as root? sudo {}".format(sys.argv[0]))
|
||||
sys.exit(0)
|
||||
|
||||
def log(msg):
|
||||
sys.stdout.write(str(datetime.now()))
|
||||
sys.stdout.write(": ")
|
||||
sys.stdout.write(msg)
|
||||
sys.stdout.write("\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
def handle_button(pin):
|
||||
key = KEYS[pin]
|
||||
time.sleep(BOUNCE_TIME)
|
||||
if pin >= 1000:
|
||||
state = analog_states[pin-1000]
|
||||
else:
|
||||
state = 0 if gpio.input(pin) else 1
|
||||
ui.write(e.EV_KEY, key, state)
|
||||
ui.syn()
|
||||
if DEBUG:
|
||||
log("Pin: {}, KeyCode: {}, Event: {}".format(pin, key, 'press' if state else 'release'))
|
||||
|
||||
|
||||
for button in BUTTONS:
|
||||
gpio.add_event_detect(button, gpio.BOTH, callback=handle_button, bouncetime=1)
|
||||
|
||||
while True:
|
||||
try:
|
||||
y = 800 - ads_read(0)
|
||||
x = ads_read(1) - 800
|
||||
except IOError:
|
||||
continue
|
||||
#print("(%d , %d)" % (x, y))
|
||||
|
||||
if (y > ANALOG_THRESH_POS) and not analog_states[0]:
|
||||
analog_states[0] = True
|
||||
handle_button(1000) # send UP press
|
||||
if (y < ANALOG_THRESH_POS) and analog_states[0]:
|
||||
analog_states[0] = False
|
||||
handle_button(1000) # send UP release
|
||||
if (y < ANALOG_THRESH_NEG) and not analog_states[1]:
|
||||
analog_states[1] = True
|
||||
handle_button(1001) # send DOWN press
|
||||
if (y > ANALOG_THRESH_NEG) and analog_states[1]:
|
||||
analog_states[1] = False
|
||||
handle_button(1001) # send DOWN release
|
||||
if (x < ANALOG_THRESH_NEG) and not analog_states[2]:
|
||||
analog_states[2] = True
|
||||
handle_button(1002) # send LEFT press
|
||||
if (x > ANALOG_THRESH_NEG) and analog_states[2]:
|
||||
analog_states[2] = False
|
||||
handle_button(1002) # send LEFT release
|
||||
if (x > ANALOG_THRESH_POS) and not analog_states[3]:
|
||||
analog_states[3] = True
|
||||
handle_button(1003) # send RIGHT press
|
||||
if (x < ANALOG_THRESH_POS) and analog_states[3]:
|
||||
analog_states[3] = False
|
||||
handle_button(1003) # send RIGHT release
|
||||
|
||||
time.sleep(0.01)
|
||||
178
joyBonnetAsMouse.py
Normal file
178
joyBonnetAsMouse.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# Somewhat minimal Adafruit Joy Bonnet handler. Runs in background,
|
||||
# translates inputs from buttons and ADC joystick to virtual USB keyboard
|
||||
# events.
|
||||
# Prerequisites:
|
||||
# sudo apt-get install python-pip python-smbus python-dev
|
||||
# sudo pip install evdev
|
||||
# Be sure to enable I2C via raspi-config. Also, udev rules will need to
|
||||
# be set up per retrogame directions.
|
||||
# Credit to Pimoroni for Picade HAT scripts as starting point.
|
||||
|
||||
import time
|
||||
import signal
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from evdev import uinput, UInput, ecodes as e
|
||||
except ImportError:
|
||||
exit("This library requires the evdev module\nInstall with: sudo pip install evdev")
|
||||
|
||||
try:
|
||||
import RPi.GPIO as gpio
|
||||
except ImportError:
|
||||
exit("This library requires the RPi.GPIO module\nInstall with: sudo pip install RPi.GPIO")
|
||||
|
||||
try:
|
||||
from smbus import SMBus
|
||||
except ImportError:
|
||||
exit("This library requires the smbus module\nInstall with: sudo pip install smbus")
|
||||
|
||||
DEBUG = False
|
||||
BOUNCE_TIME = 0.01 # Debounce time in seconds
|
||||
|
||||
BUTTON_A = 12
|
||||
BUTTON_B = 6
|
||||
BUTTON_X = 16
|
||||
BUTTON_Y = 13
|
||||
SELECT = 20
|
||||
START = 26
|
||||
PLAYER1 = 23
|
||||
PLAYER2 = 22
|
||||
BUTTONS = [BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y, SELECT, START, PLAYER1, PLAYER2]
|
||||
|
||||
MOUSE_SENSITIVITY = 4 # 0-10
|
||||
MOUSE_DEADZONE = 40 # Values under this are zeroed
|
||||
|
||||
|
||||
KEYS= { # EDIT KEYCODES IN THIS TABLE TO YOUR PREFERENCES:
|
||||
# See /usr/include/linux/input.h for keycode names
|
||||
# Keyboard Bonnet EmulationStation
|
||||
BUTTON_A: e.KEY_RIGHT, # 'A' button as mouse click
|
||||
BUTTON_B: e.KEY_DOWN, # 'B' button as right click
|
||||
BUTTON_X: e.KEY_UP, # 'X' button
|
||||
BUTTON_Y: e.KEY_LEFT, # 'Y' button
|
||||
SELECT: e.BTN_RIGHT, # 'Select' button
|
||||
START: e.BTN_MOUSE, # 'Start' button
|
||||
PLAYER1: e.KEY_PAGEUP, # '#1' button
|
||||
PLAYER2: e.KEY_PAGEDOWN, # '#2' button
|
||||
}
|
||||
|
||||
|
||||
|
||||
###################################### ADS1015 microdriver #################################
|
||||
# Register and other configuration values:
|
||||
ADS1x15_DEFAULT_ADDRESS = 0x48
|
||||
ADS1x15_POINTER_CONVERSION = 0x00
|
||||
ADS1x15_POINTER_CONFIG = 0x01
|
||||
|
||||
ADS1015_REG_CONFIG_CQUE_NONE = 0x0003 # Disable the comparator and put ALERT/RDY in high state (default)
|
||||
ADS1015_REG_CONFIG_CLAT_NONLAT = 0x0000 # Non-latching comparator (default)
|
||||
ADS1015_REG_CONFIG_CPOL_ACTVLOW = 0x0000 # ALERT/RDY pin is low when active (default)
|
||||
ADS1015_REG_CONFIG_CMODE_TRAD = 0x0000 # Traditional comparator with hysteresis (default)
|
||||
ADS1015_REG_CONFIG_DR_1600SPS = 0x0080 # 1600 samples per second (default)
|
||||
ADS1015_REG_CONFIG_MODE_SINGLE = 0x0100 # Power-down single-shot mode (default)
|
||||
ADS1015_REG_CONFIG_GAIN_ONE = 0x0200 # gain of 1
|
||||
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_0 = 0x4000 # channel 0
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_1 = 0x5000 # channel 1
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_2 = 0x6000 # channel 2
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_3 = 0x7000 # channel 3
|
||||
|
||||
ADS1015_REG_CONFIG_OS_SINGLE = 0x8000 # start a single conversion
|
||||
|
||||
ADS1015_REG_CONFIG_CHANNELS = (ADS1015_REG_CONFIG_MUX_SINGLE_0, ADS1015_REG_CONFIG_MUX_SINGLE_1,
|
||||
ADS1015_REG_CONFIG_MUX_SINGLE_2, ADS1015_REG_CONFIG_MUX_SINGLE_3)
|
||||
|
||||
def ads_read(channel):
|
||||
#configdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, 2)
|
||||
#print("Getting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
|
||||
configword = ADS1015_REG_CONFIG_CQUE_NONE | ADS1015_REG_CONFIG_CLAT_NONLAT | ADS1015_REG_CONFIG_CPOL_ACTVLOW | ADS1015_REG_CONFIG_CMODE_TRAD | ADS1015_REG_CONFIG_DR_1600SPS | ADS1015_REG_CONFIG_MODE_SINGLE | ADS1015_REG_CONFIG_GAIN_ONE | ADS1015_REG_CONFIG_CHANNELS[channel] | ADS1015_REG_CONFIG_OS_SINGLE
|
||||
configdata = [configword >> 8, configword & 0xFF]
|
||||
|
||||
#print("Setting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
bus.write_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, configdata)
|
||||
|
||||
configdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, 2)
|
||||
#print("Getting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
|
||||
while True:
|
||||
try:
|
||||
configdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONFIG, 2)
|
||||
#print("Getting config byte = 0x%02X%02X" % (configdata[0], configdata[1]))
|
||||
if (configdata[0] & 0x80):
|
||||
break
|
||||
except:
|
||||
pass
|
||||
# read data out!
|
||||
analogdata = bus.read_i2c_block_data(ADS1x15_DEFAULT_ADDRESS, ADS1x15_POINTER_CONVERSION, 2)
|
||||
#print(analogdata),
|
||||
retval = (analogdata[0] << 8) | analogdata[1]
|
||||
retval /= 16
|
||||
#print("-> %d" %retval)
|
||||
return retval
|
||||
|
||||
######################## main program
|
||||
|
||||
os.system("sudo modprobe uinput")
|
||||
|
||||
bus = SMBus(1)
|
||||
|
||||
# GPIO init
|
||||
gpio.setwarnings(False)
|
||||
gpio.setmode(gpio.BCM)
|
||||
gpio.setup(BUTTONS, gpio.IN, pull_up_down=gpio.PUD_UP)
|
||||
|
||||
try:
|
||||
caps= {e.EV_KEY: KEYS.values(),
|
||||
e.EV_REL: [e.REL_X, e.REL_Y],
|
||||
}
|
||||
ui = UInput(caps, name="retrogame", bustype=e.BUS_USB)
|
||||
except uinput.UInputError as e:
|
||||
sys.stdout.write(e.message)
|
||||
sys.stdout.write("Have you tried running as root? sudo {}".format(sys.argv[0]))
|
||||
sys.exit(0)
|
||||
|
||||
def log(msg):
|
||||
sys.stdout.write(str(datetime.now()))
|
||||
sys.stdout.write(": ")
|
||||
sys.stdout.write(msg)
|
||||
sys.stdout.write("\n")
|
||||
sys.stdout.flush()
|
||||
|
||||
def handle_button(pin):
|
||||
key = KEYS[pin]
|
||||
time.sleep(BOUNCE_TIME)
|
||||
state = 0 if gpio.input(pin) else 1
|
||||
ui.write(e.EV_KEY, key, state)
|
||||
ui.syn()
|
||||
if DEBUG:
|
||||
log("Pin: {}, KeyCode: {}, Event: {}".format(pin, key, 'press' if state else 'release'))
|
||||
|
||||
|
||||
for button in BUTTONS:
|
||||
gpio.add_event_detect(button, gpio.BOTH, callback=handle_button, bouncetime=1)
|
||||
|
||||
while True:
|
||||
try:
|
||||
y = 800 - ads_read(0)
|
||||
x = ads_read(1) - 800
|
||||
except IOError:
|
||||
continue
|
||||
# print("(%d , %d)" % (x, y))
|
||||
|
||||
|
||||
if abs(x) < MOUSE_DEADZONE:
|
||||
x=0
|
||||
if abs(y) < MOUSE_DEADZONE:
|
||||
y=0
|
||||
x = x >> (10 - MOUSE_SENSITIVITY)
|
||||
y = y >> (10 - MOUSE_SENSITIVITY)
|
||||
ui.write(e.EV_REL, e.REL_X, x)
|
||||
ui.write(e.EV_REL, e.REL_Y, -y)
|
||||
ui.syn()
|
||||
time.sleep(0.01)
|
||||
457
keyTable.h
Normal file
457
keyTable.h
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
// This file is software-generated; do not edit. See keyTableGen.sh instead.
|
||||
|
||||
#include </usr/include/linux/input-event-codes.h>
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int value;
|
||||
} dict;
|
||||
|
||||
dict keyTable[] = {
|
||||
{ "RESERVED", KEY_RESERVED },
|
||||
{ "ESC", KEY_ESC },
|
||||
{ "1", KEY_1 },
|
||||
{ "2", KEY_2 },
|
||||
{ "3", KEY_3 },
|
||||
{ "4", KEY_4 },
|
||||
{ "5", KEY_5 },
|
||||
{ "6", KEY_6 },
|
||||
{ "7", KEY_7 },
|
||||
{ "8", KEY_8 },
|
||||
{ "9", KEY_9 },
|
||||
{ "0", KEY_0 },
|
||||
{ "MINUS", KEY_MINUS },
|
||||
{ "EQUAL", KEY_EQUAL },
|
||||
{ "BACKSPACE", KEY_BACKSPACE },
|
||||
{ "TAB", KEY_TAB },
|
||||
{ "Q", KEY_Q },
|
||||
{ "W", KEY_W },
|
||||
{ "E", KEY_E },
|
||||
{ "R", KEY_R },
|
||||
{ "T", KEY_T },
|
||||
{ "Y", KEY_Y },
|
||||
{ "U", KEY_U },
|
||||
{ "I", KEY_I },
|
||||
{ "O", KEY_O },
|
||||
{ "P", KEY_P },
|
||||
{ "LEFTBRACE", KEY_LEFTBRACE },
|
||||
{ "RIGHTBRACE", KEY_RIGHTBRACE },
|
||||
{ "ENTER", KEY_ENTER },
|
||||
{ "LEFTCTRL", KEY_LEFTCTRL },
|
||||
{ "A", KEY_A },
|
||||
{ "S", KEY_S },
|
||||
{ "D", KEY_D },
|
||||
{ "F", KEY_F },
|
||||
{ "G", KEY_G },
|
||||
{ "H", KEY_H },
|
||||
{ "J", KEY_J },
|
||||
{ "K", KEY_K },
|
||||
{ "L", KEY_L },
|
||||
{ "SEMICOLON", KEY_SEMICOLON },
|
||||
{ "APOSTROPHE", KEY_APOSTROPHE },
|
||||
{ "GRAVE", KEY_GRAVE },
|
||||
{ "LEFTSHIFT", KEY_LEFTSHIFT },
|
||||
{ "BACKSLASH", KEY_BACKSLASH },
|
||||
{ "Z", KEY_Z },
|
||||
{ "X", KEY_X },
|
||||
{ "C", KEY_C },
|
||||
{ "V", KEY_V },
|
||||
{ "B", KEY_B },
|
||||
{ "N", KEY_N },
|
||||
{ "M", KEY_M },
|
||||
{ "COMMA", KEY_COMMA },
|
||||
{ "DOT", KEY_DOT },
|
||||
{ "SLASH", KEY_SLASH },
|
||||
{ "RIGHTSHIFT", KEY_RIGHTSHIFT },
|
||||
{ "KPASTERISK", KEY_KPASTERISK },
|
||||
{ "LEFTALT", KEY_LEFTALT },
|
||||
{ "SPACE", KEY_SPACE },
|
||||
{ "CAPSLOCK", KEY_CAPSLOCK },
|
||||
{ "F1", KEY_F1 },
|
||||
{ "F2", KEY_F2 },
|
||||
{ "F3", KEY_F3 },
|
||||
{ "F4", KEY_F4 },
|
||||
{ "F5", KEY_F5 },
|
||||
{ "F6", KEY_F6 },
|
||||
{ "F7", KEY_F7 },
|
||||
{ "F8", KEY_F8 },
|
||||
{ "F9", KEY_F9 },
|
||||
{ "F10", KEY_F10 },
|
||||
{ "NUMLOCK", KEY_NUMLOCK },
|
||||
{ "SCROLLLOCK", KEY_SCROLLLOCK },
|
||||
{ "KP7", KEY_KP7 },
|
||||
{ "KP8", KEY_KP8 },
|
||||
{ "KP9", KEY_KP9 },
|
||||
{ "KPMINUS", KEY_KPMINUS },
|
||||
{ "KP4", KEY_KP4 },
|
||||
{ "KP5", KEY_KP5 },
|
||||
{ "KP6", KEY_KP6 },
|
||||
{ "KPPLUS", KEY_KPPLUS },
|
||||
{ "KP1", KEY_KP1 },
|
||||
{ "KP2", KEY_KP2 },
|
||||
{ "KP3", KEY_KP3 },
|
||||
{ "KP0", KEY_KP0 },
|
||||
{ "KPDOT", KEY_KPDOT },
|
||||
{ "ZENKAKUHANKAKU", KEY_ZENKAKUHANKAKU },
|
||||
{ "102ND", KEY_102ND },
|
||||
{ "F11", KEY_F11 },
|
||||
{ "F12", KEY_F12 },
|
||||
{ "RO", KEY_RO },
|
||||
{ "KATAKANA", KEY_KATAKANA },
|
||||
{ "HIRAGANA", KEY_HIRAGANA },
|
||||
{ "HENKAN", KEY_HENKAN },
|
||||
{ "KATAKANAHIRAGANA", KEY_KATAKANAHIRAGANA },
|
||||
{ "MUHENKAN", KEY_MUHENKAN },
|
||||
{ "KPJPCOMMA", KEY_KPJPCOMMA },
|
||||
{ "KPENTER", KEY_KPENTER },
|
||||
{ "RIGHTCTRL", KEY_RIGHTCTRL },
|
||||
{ "KPSLASH", KEY_KPSLASH },
|
||||
{ "SYSRQ", KEY_SYSRQ },
|
||||
{ "RIGHTALT", KEY_RIGHTALT },
|
||||
{ "LINEFEED", KEY_LINEFEED },
|
||||
{ "HOME", KEY_HOME },
|
||||
{ "UP", KEY_UP },
|
||||
{ "PAGEUP", KEY_PAGEUP },
|
||||
{ "LEFT", KEY_LEFT },
|
||||
{ "RIGHT", KEY_RIGHT },
|
||||
{ "END", KEY_END },
|
||||
{ "DOWN", KEY_DOWN },
|
||||
{ "PAGEDOWN", KEY_PAGEDOWN },
|
||||
{ "INSERT", KEY_INSERT },
|
||||
{ "DELETE", KEY_DELETE },
|
||||
{ "MACRO", KEY_MACRO },
|
||||
#if 0 // Esoteric keys disabled, smaller program size; edit if needed
|
||||
{ "MUTE", KEY_MUTE },
|
||||
{ "VOLUMEDOWN", KEY_VOLUMEDOWN },
|
||||
{ "VOLUMEUP", KEY_VOLUMEUP },
|
||||
{ "POWER", KEY_POWER },
|
||||
{ "KPEQUAL", KEY_KPEQUAL },
|
||||
{ "KPPLUSMINUS", KEY_KPPLUSMINUS },
|
||||
{ "PAUSE", KEY_PAUSE },
|
||||
{ "SCALE", KEY_SCALE },
|
||||
{ "KPCOMMA", KEY_KPCOMMA },
|
||||
{ "HANGEUL", KEY_HANGEUL },
|
||||
{ "HANGUEL", KEY_HANGUEL },
|
||||
{ "HANJA", KEY_HANJA },
|
||||
{ "YEN", KEY_YEN },
|
||||
{ "LEFTMETA", KEY_LEFTMETA },
|
||||
{ "RIGHTMETA", KEY_RIGHTMETA },
|
||||
{ "COMPOSE", KEY_COMPOSE },
|
||||
{ "STOP", KEY_STOP },
|
||||
{ "AGAIN", KEY_AGAIN },
|
||||
{ "PROPS", KEY_PROPS },
|
||||
{ "UNDO", KEY_UNDO },
|
||||
{ "FRONT", KEY_FRONT },
|
||||
{ "COPY", KEY_COPY },
|
||||
{ "OPEN", KEY_OPEN },
|
||||
{ "PASTE", KEY_PASTE },
|
||||
{ "FIND", KEY_FIND },
|
||||
{ "CUT", KEY_CUT },
|
||||
{ "HELP", KEY_HELP },
|
||||
{ "MENU", KEY_MENU },
|
||||
{ "CALC", KEY_CALC },
|
||||
{ "SETUP", KEY_SETUP },
|
||||
{ "SLEEP", KEY_SLEEP },
|
||||
{ "WAKEUP", KEY_WAKEUP },
|
||||
{ "FILE", KEY_FILE },
|
||||
{ "SENDFILE", KEY_SENDFILE },
|
||||
{ "DELETEFILE", KEY_DELETEFILE },
|
||||
{ "XFER", KEY_XFER },
|
||||
{ "PROG1", KEY_PROG1 },
|
||||
{ "PROG2", KEY_PROG2 },
|
||||
{ "WWW", KEY_WWW },
|
||||
{ "MSDOS", KEY_MSDOS },
|
||||
{ "COFFEE", KEY_COFFEE },
|
||||
{ "SCREENLOCK", KEY_SCREENLOCK },
|
||||
{ "ROTATE_DISPLAY", KEY_ROTATE_DISPLAY },
|
||||
{ "DIRECTION", KEY_DIRECTION },
|
||||
{ "CYCLEWINDOWS", KEY_CYCLEWINDOWS },
|
||||
{ "MAIL", KEY_MAIL },
|
||||
{ "BOOKMARKS", KEY_BOOKMARKS },
|
||||
{ "COMPUTER", KEY_COMPUTER },
|
||||
{ "BACK", KEY_BACK },
|
||||
{ "FORWARD", KEY_FORWARD },
|
||||
{ "CLOSECD", KEY_CLOSECD },
|
||||
{ "EJECTCD", KEY_EJECTCD },
|
||||
{ "EJECTCLOSECD", KEY_EJECTCLOSECD },
|
||||
{ "NEXTSONG", KEY_NEXTSONG },
|
||||
{ "PLAYPAUSE", KEY_PLAYPAUSE },
|
||||
{ "PREVIOUSSONG", KEY_PREVIOUSSONG },
|
||||
{ "STOPCD", KEY_STOPCD },
|
||||
{ "RECORD", KEY_RECORD },
|
||||
{ "REWIND", KEY_REWIND },
|
||||
{ "PHONE", KEY_PHONE },
|
||||
{ "ISO", KEY_ISO },
|
||||
{ "CONFIG", KEY_CONFIG },
|
||||
{ "HOMEPAGE", KEY_HOMEPAGE },
|
||||
{ "REFRESH", KEY_REFRESH },
|
||||
{ "EXIT", KEY_EXIT },
|
||||
{ "MOVE", KEY_MOVE },
|
||||
{ "EDIT", KEY_EDIT },
|
||||
{ "SCROLLUP", KEY_SCROLLUP },
|
||||
{ "SCROLLDOWN", KEY_SCROLLDOWN },
|
||||
{ "KPLEFTPAREN", KEY_KPLEFTPAREN },
|
||||
{ "KPRIGHTPAREN", KEY_KPRIGHTPAREN },
|
||||
{ "NEW", KEY_NEW },
|
||||
{ "REDO", KEY_REDO },
|
||||
{ "F13", KEY_F13 },
|
||||
{ "F14", KEY_F14 },
|
||||
{ "F15", KEY_F15 },
|
||||
{ "F16", KEY_F16 },
|
||||
{ "F17", KEY_F17 },
|
||||
{ "F18", KEY_F18 },
|
||||
{ "F19", KEY_F19 },
|
||||
{ "F20", KEY_F20 },
|
||||
{ "F21", KEY_F21 },
|
||||
{ "F22", KEY_F22 },
|
||||
{ "F23", KEY_F23 },
|
||||
{ "F24", KEY_F24 },
|
||||
{ "PLAYCD", KEY_PLAYCD },
|
||||
{ "PAUSECD", KEY_PAUSECD },
|
||||
{ "PROG3", KEY_PROG3 },
|
||||
{ "PROG4", KEY_PROG4 },
|
||||
{ "DASHBOARD", KEY_DASHBOARD },
|
||||
{ "SUSPEND", KEY_SUSPEND },
|
||||
{ "CLOSE", KEY_CLOSE },
|
||||
{ "PLAY", KEY_PLAY },
|
||||
{ "FASTFORWARD", KEY_FASTFORWARD },
|
||||
{ "BASSBOOST", KEY_BASSBOOST },
|
||||
{ "PRINT", KEY_PRINT },
|
||||
{ "HP", KEY_HP },
|
||||
{ "CAMERA", KEY_CAMERA },
|
||||
{ "SOUND", KEY_SOUND },
|
||||
{ "QUESTION", KEY_QUESTION },
|
||||
{ "EMAIL", KEY_EMAIL },
|
||||
{ "CHAT", KEY_CHAT },
|
||||
{ "SEARCH", KEY_SEARCH },
|
||||
{ "CONNECT", KEY_CONNECT },
|
||||
{ "FINANCE", KEY_FINANCE },
|
||||
{ "SPORT", KEY_SPORT },
|
||||
{ "SHOP", KEY_SHOP },
|
||||
{ "ALTERASE", KEY_ALTERASE },
|
||||
{ "CANCEL", KEY_CANCEL },
|
||||
{ "BRIGHTNESSDOWN", KEY_BRIGHTNESSDOWN },
|
||||
{ "BRIGHTNESSUP", KEY_BRIGHTNESSUP },
|
||||
{ "MEDIA", KEY_MEDIA },
|
||||
{ "SWITCHVIDEOMODE", KEY_SWITCHVIDEOMODE },
|
||||
{ "KBDILLUMTOGGLE", KEY_KBDILLUMTOGGLE },
|
||||
{ "KBDILLUMDOWN", KEY_KBDILLUMDOWN },
|
||||
{ "KBDILLUMUP", KEY_KBDILLUMUP },
|
||||
{ "SEND", KEY_SEND },
|
||||
{ "REPLY", KEY_REPLY },
|
||||
{ "FORWARDMAIL", KEY_FORWARDMAIL },
|
||||
{ "SAVE", KEY_SAVE },
|
||||
{ "DOCUMENTS", KEY_DOCUMENTS },
|
||||
{ "BATTERY", KEY_BATTERY },
|
||||
{ "BLUETOOTH", KEY_BLUETOOTH },
|
||||
{ "WLAN", KEY_WLAN },
|
||||
{ "UWB", KEY_UWB },
|
||||
{ "UNKNOWN", KEY_UNKNOWN },
|
||||
{ "VIDEO_NEXT", KEY_VIDEO_NEXT },
|
||||
{ "VIDEO_PREV", KEY_VIDEO_PREV },
|
||||
{ "BRIGHTNESS_CYCLE", KEY_BRIGHTNESS_CYCLE },
|
||||
{ "BRIGHTNESS_AUTO", KEY_BRIGHTNESS_AUTO },
|
||||
{ "BRIGHTNESS_ZERO", KEY_BRIGHTNESS_ZERO },
|
||||
{ "DISPLAY_OFF", KEY_DISPLAY_OFF },
|
||||
{ "WWAN", KEY_WWAN },
|
||||
{ "WIMAX", KEY_WIMAX },
|
||||
{ "RFKILL", KEY_RFKILL },
|
||||
{ "MICMUTE", KEY_MICMUTE },
|
||||
{ "OK", KEY_OK },
|
||||
{ "SELECT", KEY_SELECT },
|
||||
{ "GOTO", KEY_GOTO },
|
||||
{ "CLEAR", KEY_CLEAR },
|
||||
{ "POWER2", KEY_POWER2 },
|
||||
{ "OPTION", KEY_OPTION },
|
||||
{ "INFO", KEY_INFO },
|
||||
{ "TIME", KEY_TIME },
|
||||
{ "VENDOR", KEY_VENDOR },
|
||||
{ "ARCHIVE", KEY_ARCHIVE },
|
||||
{ "PROGRAM", KEY_PROGRAM },
|
||||
{ "CHANNEL", KEY_CHANNEL },
|
||||
{ "FAVORITES", KEY_FAVORITES },
|
||||
{ "EPG", KEY_EPG },
|
||||
{ "PVR", KEY_PVR },
|
||||
{ "MHP", KEY_MHP },
|
||||
{ "LANGUAGE", KEY_LANGUAGE },
|
||||
{ "TITLE", KEY_TITLE },
|
||||
{ "SUBTITLE", KEY_SUBTITLE },
|
||||
{ "ANGLE", KEY_ANGLE },
|
||||
{ "ZOOM", KEY_ZOOM },
|
||||
{ "MODE", KEY_MODE },
|
||||
{ "KEYBOARD", KEY_KEYBOARD },
|
||||
{ "SCREEN", KEY_SCREEN },
|
||||
{ "PC", KEY_PC },
|
||||
{ "TV", KEY_TV },
|
||||
{ "TV2", KEY_TV2 },
|
||||
{ "VCR", KEY_VCR },
|
||||
{ "VCR2", KEY_VCR2 },
|
||||
{ "SAT", KEY_SAT },
|
||||
{ "SAT2", KEY_SAT2 },
|
||||
{ "CD", KEY_CD },
|
||||
{ "TAPE", KEY_TAPE },
|
||||
{ "RADIO", KEY_RADIO },
|
||||
{ "TUNER", KEY_TUNER },
|
||||
{ "PLAYER", KEY_PLAYER },
|
||||
{ "TEXT", KEY_TEXT },
|
||||
{ "DVD", KEY_DVD },
|
||||
{ "AUX", KEY_AUX },
|
||||
{ "MP3", KEY_MP3 },
|
||||
{ "AUDIO", KEY_AUDIO },
|
||||
{ "VIDEO", KEY_VIDEO },
|
||||
{ "DIRECTORY", KEY_DIRECTORY },
|
||||
{ "LIST", KEY_LIST },
|
||||
{ "MEMO", KEY_MEMO },
|
||||
{ "CALENDAR", KEY_CALENDAR },
|
||||
{ "RED", KEY_RED },
|
||||
{ "GREEN", KEY_GREEN },
|
||||
{ "YELLOW", KEY_YELLOW },
|
||||
{ "BLUE", KEY_BLUE },
|
||||
{ "CHANNELUP", KEY_CHANNELUP },
|
||||
{ "CHANNELDOWN", KEY_CHANNELDOWN },
|
||||
{ "FIRST", KEY_FIRST },
|
||||
{ "LAST", KEY_LAST },
|
||||
{ "AB", KEY_AB },
|
||||
{ "NEXT", KEY_NEXT },
|
||||
{ "RESTART", KEY_RESTART },
|
||||
{ "SLOW", KEY_SLOW },
|
||||
{ "SHUFFLE", KEY_SHUFFLE },
|
||||
{ "BREAK", KEY_BREAK },
|
||||
{ "PREVIOUS", KEY_PREVIOUS },
|
||||
{ "DIGITS", KEY_DIGITS },
|
||||
{ "TEEN", KEY_TEEN },
|
||||
{ "TWEN", KEY_TWEN },
|
||||
{ "VIDEOPHONE", KEY_VIDEOPHONE },
|
||||
{ "GAMES", KEY_GAMES },
|
||||
{ "ZOOMIN", KEY_ZOOMIN },
|
||||
{ "ZOOMOUT", KEY_ZOOMOUT },
|
||||
{ "ZOOMRESET", KEY_ZOOMRESET },
|
||||
{ "WORDPROCESSOR", KEY_WORDPROCESSOR },
|
||||
{ "EDITOR", KEY_EDITOR },
|
||||
{ "SPREADSHEET", KEY_SPREADSHEET },
|
||||
{ "GRAPHICSEDITOR", KEY_GRAPHICSEDITOR },
|
||||
{ "PRESENTATION", KEY_PRESENTATION },
|
||||
{ "DATABASE", KEY_DATABASE },
|
||||
{ "NEWS", KEY_NEWS },
|
||||
{ "VOICEMAIL", KEY_VOICEMAIL },
|
||||
{ "ADDRESSBOOK", KEY_ADDRESSBOOK },
|
||||
{ "MESSENGER", KEY_MESSENGER },
|
||||
{ "DISPLAYTOGGLE", KEY_DISPLAYTOGGLE },
|
||||
{ "BRIGHTNESS_TOGGLE", KEY_BRIGHTNESS_TOGGLE },
|
||||
{ "SPELLCHECK", KEY_SPELLCHECK },
|
||||
{ "LOGOFF", KEY_LOGOFF },
|
||||
{ "DOLLAR", KEY_DOLLAR },
|
||||
{ "EURO", KEY_EURO },
|
||||
{ "FRAMEBACK", KEY_FRAMEBACK },
|
||||
{ "FRAMEFORWARD", KEY_FRAMEFORWARD },
|
||||
{ "CONTEXT_MENU", KEY_CONTEXT_MENU },
|
||||
{ "MEDIA_REPEAT", KEY_MEDIA_REPEAT },
|
||||
{ "10CHANNELSUP", KEY_10CHANNELSUP },
|
||||
{ "10CHANNELSDOWN", KEY_10CHANNELSDOWN },
|
||||
{ "IMAGES", KEY_IMAGES },
|
||||
{ "DEL_EOL", KEY_DEL_EOL },
|
||||
{ "DEL_EOS", KEY_DEL_EOS },
|
||||
{ "INS_LINE", KEY_INS_LINE },
|
||||
{ "DEL_LINE", KEY_DEL_LINE },
|
||||
{ "FN", KEY_FN },
|
||||
{ "FN_ESC", KEY_FN_ESC },
|
||||
{ "FN_F1", KEY_FN_F1 },
|
||||
{ "FN_F2", KEY_FN_F2 },
|
||||
{ "FN_F3", KEY_FN_F3 },
|
||||
{ "FN_F4", KEY_FN_F4 },
|
||||
{ "FN_F5", KEY_FN_F5 },
|
||||
{ "FN_F6", KEY_FN_F6 },
|
||||
{ "FN_F7", KEY_FN_F7 },
|
||||
{ "FN_F8", KEY_FN_F8 },
|
||||
{ "FN_F9", KEY_FN_F9 },
|
||||
{ "FN_F10", KEY_FN_F10 },
|
||||
{ "FN_F11", KEY_FN_F11 },
|
||||
{ "FN_F12", KEY_FN_F12 },
|
||||
{ "FN_1", KEY_FN_1 },
|
||||
{ "FN_2", KEY_FN_2 },
|
||||
{ "FN_D", KEY_FN_D },
|
||||
{ "FN_E", KEY_FN_E },
|
||||
{ "FN_F", KEY_FN_F },
|
||||
{ "FN_S", KEY_FN_S },
|
||||
{ "FN_B", KEY_FN_B },
|
||||
{ "BRL_DOT1", KEY_BRL_DOT1 },
|
||||
{ "BRL_DOT2", KEY_BRL_DOT2 },
|
||||
{ "BRL_DOT3", KEY_BRL_DOT3 },
|
||||
{ "BRL_DOT4", KEY_BRL_DOT4 },
|
||||
{ "BRL_DOT5", KEY_BRL_DOT5 },
|
||||
{ "BRL_DOT6", KEY_BRL_DOT6 },
|
||||
{ "BRL_DOT7", KEY_BRL_DOT7 },
|
||||
{ "BRL_DOT8", KEY_BRL_DOT8 },
|
||||
{ "BRL_DOT9", KEY_BRL_DOT9 },
|
||||
{ "BRL_DOT10", KEY_BRL_DOT10 },
|
||||
{ "NUMERIC_0", KEY_NUMERIC_0 },
|
||||
{ "NUMERIC_1", KEY_NUMERIC_1 },
|
||||
{ "NUMERIC_2", KEY_NUMERIC_2 },
|
||||
{ "NUMERIC_3", KEY_NUMERIC_3 },
|
||||
{ "NUMERIC_4", KEY_NUMERIC_4 },
|
||||
{ "NUMERIC_5", KEY_NUMERIC_5 },
|
||||
{ "NUMERIC_6", KEY_NUMERIC_6 },
|
||||
{ "NUMERIC_7", KEY_NUMERIC_7 },
|
||||
{ "NUMERIC_8", KEY_NUMERIC_8 },
|
||||
{ "NUMERIC_9", KEY_NUMERIC_9 },
|
||||
{ "NUMERIC_STAR", KEY_NUMERIC_STAR },
|
||||
{ "NUMERIC_POUND", KEY_NUMERIC_POUND },
|
||||
{ "NUMERIC_A", KEY_NUMERIC_A },
|
||||
{ "NUMERIC_B", KEY_NUMERIC_B },
|
||||
{ "NUMERIC_C", KEY_NUMERIC_C },
|
||||
{ "NUMERIC_D", KEY_NUMERIC_D },
|
||||
{ "CAMERA_FOCUS", KEY_CAMERA_FOCUS },
|
||||
{ "WPS_BUTTON", KEY_WPS_BUTTON },
|
||||
{ "TOUCHPAD_TOGGLE", KEY_TOUCHPAD_TOGGLE },
|
||||
{ "TOUCHPAD_ON", KEY_TOUCHPAD_ON },
|
||||
{ "TOUCHPAD_OFF", KEY_TOUCHPAD_OFF },
|
||||
{ "CAMERA_ZOOMIN", KEY_CAMERA_ZOOMIN },
|
||||
{ "CAMERA_ZOOMOUT", KEY_CAMERA_ZOOMOUT },
|
||||
{ "CAMERA_UP", KEY_CAMERA_UP },
|
||||
{ "CAMERA_DOWN", KEY_CAMERA_DOWN },
|
||||
{ "CAMERA_LEFT", KEY_CAMERA_LEFT },
|
||||
{ "CAMERA_RIGHT", KEY_CAMERA_RIGHT },
|
||||
{ "ATTENDANT_ON", KEY_ATTENDANT_ON },
|
||||
{ "ATTENDANT_OFF", KEY_ATTENDANT_OFF },
|
||||
{ "ATTENDANT_TOGGLE", KEY_ATTENDANT_TOGGLE },
|
||||
{ "LIGHTS_TOGGLE", KEY_LIGHTS_TOGGLE },
|
||||
{ "ALS_TOGGLE", KEY_ALS_TOGGLE },
|
||||
{ "BUTTONCONFIG", KEY_BUTTONCONFIG },
|
||||
{ "TASKMANAGER", KEY_TASKMANAGER },
|
||||
{ "JOURNAL", KEY_JOURNAL },
|
||||
{ "CONTROLPANEL", KEY_CONTROLPANEL },
|
||||
{ "APPSELECT", KEY_APPSELECT },
|
||||
{ "SCREENSAVER", KEY_SCREENSAVER },
|
||||
{ "VOICECOMMAND", KEY_VOICECOMMAND },
|
||||
{ "BRIGHTNESS_MIN", KEY_BRIGHTNESS_MIN },
|
||||
{ "BRIGHTNESS_MAX", KEY_BRIGHTNESS_MAX },
|
||||
{ "KBDINPUTASSIST_PREV", KEY_KBDINPUTASSIST_PREV },
|
||||
{ "KBDINPUTASSIST_NEXT", KEY_KBDINPUTASSIST_NEXT },
|
||||
{ "KBDINPUTASSIST_PREVGROUP", KEY_KBDINPUTASSIST_PREVGROUP },
|
||||
{ "KBDINPUTASSIST_NEXTGROUP", KEY_KBDINPUTASSIST_NEXTGROUP },
|
||||
{ "KBDINPUTASSIST_ACCEPT", KEY_KBDINPUTASSIST_ACCEPT },
|
||||
{ "KBDINPUTASSIST_CANCEL", KEY_KBDINPUTASSIST_CANCEL },
|
||||
{ "RIGHT_UP", KEY_RIGHT_UP },
|
||||
{ "RIGHT_DOWN", KEY_RIGHT_DOWN },
|
||||
{ "LEFT_UP", KEY_LEFT_UP },
|
||||
{ "LEFT_DOWN", KEY_LEFT_DOWN },
|
||||
{ "ROOT_MENU", KEY_ROOT_MENU },
|
||||
{ "MEDIA_TOP_MENU", KEY_MEDIA_TOP_MENU },
|
||||
{ "NUMERIC_11", KEY_NUMERIC_11 },
|
||||
{ "NUMERIC_12", KEY_NUMERIC_12 },
|
||||
{ "AUDIO_DESC", KEY_AUDIO_DESC },
|
||||
{ "3D_MODE", KEY_3D_MODE },
|
||||
{ "NEXT_FAVORITE", KEY_NEXT_FAVORITE },
|
||||
{ "STOP_RECORD", KEY_STOP_RECORD },
|
||||
{ "PAUSE_RECORD", KEY_PAUSE_RECORD },
|
||||
{ "VOD", KEY_VOD },
|
||||
{ "UNMUTE", KEY_UNMUTE },
|
||||
{ "FASTREVERSE", KEY_FASTREVERSE },
|
||||
{ "SLOWREVERSE", KEY_SLOWREVERSE },
|
||||
{ "DATA", KEY_DATA },
|
||||
{ "MIN_INTERESTING", KEY_MIN_INTERESTING },
|
||||
{ "MAX", KEY_MAX },
|
||||
{ "CNT", KEY_CNT },
|
||||
#endif
|
||||
{ NULL, -1 } // END-OF-LIST
|
||||
};
|
||||
13
keyTableGen.sh
Normal file
13
keyTableGen.sh
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
echo "// This file is software-generated; do not edit. See $0 instead."
|
||||
echo
|
||||
echo "#include <$1>"
|
||||
echo
|
||||
echo "typedef struct {"
|
||||
echo "\tchar *name;"
|
||||
echo "\tint value;"
|
||||
echo "} dict;"
|
||||
echo
|
||||
echo "dict keyTable[] = {"
|
||||
grep '#define* KEY_' $1 | awk '{ print "\t{ \"" substr($2,5) "\", " $2 " }," }' | sed '/MACRO/a#if 0 // Esoteric keys disabled, smaller program size; edit if needed'
|
||||
echo "#endif\n\t{ NULL, -1 } // END-OF-LIST"
|
||||
echo "};"
|
||||
BIN
retrogame
BIN
retrogame
Binary file not shown.
1380
retrogame.c
1380
retrogame.c
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue