feat: working gpio buttons

This commit is contained in:
2026-11-06 23:40:02 +01:00
parent 84310ed364
commit 93fca80829
7 changed files with 72 additions and 73 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ BUILD_DIR ?= $(PROJECT_DIR)/build
FORGE_SRC ?= $(PROJECT_DIR)/forge-steel
TARGET ?= forge
SCREEN_HEIGHT ?= 480
RUN_ARGS ?= --project=$(PROJECT_DIR)/project -is=$(SCREEN_HEIGHT) -nmr -t=10 --auto-save
RUN_ARGS ?= --project=$(PROJECT_DIR)/project -is=$(SCREEN_HEIGHT) -nmr --auto-save
VERSION ?= invar-$(shell grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' $(FORGE_SRC)/configure.ac)
SOURCES ?= $(FORGE_SRC)/src/*.h $(FORGE_SRC)/src/*.c $(FORGE_SRC)/hashmap.c/hashmap.c $(FORGE_SRC)/log.c/src/log.c
CFLAGS ?= -Ofast -Ofast -march=native -flto -funroll-loops -fprefetch-loop-arrays -fno-exceptions -fopenmp -I$(FORGE_SRC)/include -DGLFW_INCLUDE_NONE -DGLFW_NATIVE_INCLUDE_NONE -DLOG_USE_COLOR -DVERSION=\"$(VERSION)\" -DOPENGL_MAJOR_VERSION=3 -DOPENGL_MINOR_VERSION=1
+2 -1
View File
@@ -63,6 +63,7 @@ make -f Makefile.dev rasp-install
* https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
* https://gpiozero.readthedocs.io/en/stable/
* https://python-evdev.readthedocs.io/en/latest/tutorial.html#injecting-input
* https://forums.raspberrypi.com/viewtopic.php?t=22841
## TODO
@@ -80,6 +81,6 @@ Physical
* [x] I2C screen
* [ ] Sync in
* [ ] buttons input (save/load states, random, reset, demo)
* [x] buttons input (save/load states, random, reset, demo)
* [ ] rasp compute
* [ ] PAL/NTSC switch (hard)
+30 -57
View File
@@ -256,62 +256,35 @@ SAVE_FILE_PREFIX=forge_default_save
# === HOTKEYS
# You can change the default keycodes used on runtime
# KP ENTER
KEY_RANDOMIZE=1335
# SHIFT+KP ENTER
KEY_RESET=11335
# BACKSPACE
KEY_DEMO=1259
# KP SLASH
KEY_AUTORAND_DOWN=1331
# KP TIMES
KEY_AUTORAND_UP=1332
# KP MINUS
KEY_TEMPO_DOWN=1333
# KP PLUS
KEY_TEMPO_UP=1334
# R on (qwerty)
KEY_RANDOMIZE=1082
# SHIFT+R (qwerty)
KEY_RESET=11082
# D (qwerty)
KEY_DEMO=1068
# A (qwerty)
KEY_AUTORAND=1065
# Left arrow
KEY_AUTORAND_DOWN=1263
# Right arrow
KEY_AUTORAND_UP=1262
# Down arrow
KEY_TEMPO_DOWN=1264
# Up arrow
KEY_TEMPO_UP=1265
KEY_LOAD_COUNT=6
# KP 1 to 6
KEY_LOAD_1=1321
KEY_LOAD_2=1322
KEY_LOAD_3=1323
KEY_LOAD_4=1324
KEY_LOAD_5=1325
KEY_LOAD_6=1326
# Number of load states keys
KEY_LOAD_COUNT=16
# 1 to 9 then 0 keys
KEY_LOAD_1=1320
KEY_LOAD_2=1321
KEY_LOAD_3=1322
KEY_LOAD_4=1323
KEY_LOAD_5=1324
KEY_LOAD_6=1325
KEY_LOAD_7=1326
KEY_LOAD_8=1327
KEY_LOAD_9=1328
KEY_LOAD_10=1329
KEY_LOAD_11=1331
KEY_LOAD_12=1332
KEY_LOAD_13=1333
KEY_LOAD_14=1334
KEY_LOAD_15=1259
KEY_LOAD_16=1330
# Number of save states keys
KEY_SAVE_COUNT=16
# 1 to 9 then 0 keys with shift
KEY_SAVE_1=11320
KEY_SAVE_2=11321
KEY_SAVE_3=11322
KEY_SAVE_4=11323
KEY_SAVE_5=11324
KEY_SAVE_6=11325
KEY_SAVE_7=11326
KEY_SAVE_8=11327
KEY_SAVE_9=11328
KEY_SAVE_10=11329
KEY_SAVE_11=11331
KEY_SAVE_12=11332
KEY_SAVE_13=11333
KEY_SAVE_14=11334
KEY_SAVE_15=11259
KEY_SAVE_16=11330
KEY_SAVE_COUNT=6
# SHIFT + KP 1 to 6
KEY_SAVE_1=11321
KEY_SAVE_2=11322
KEY_SAVE_3=11323
KEY_SAVE_4=11324
KEY_SAVE_5=11325
KEY_SAVE_6=11326
+15 -2
View File
@@ -17,7 +17,7 @@ FONT_2_PATH = RESOURCES_PATH / "Px437_IBM_BIOS.ttf"
LOADING_IMG_PATH = RESOURCES_PATH / "loading.png"
BACKGROUND_IMG_PATH = RESOURCES_PATH / "background.png"
ESTIMATED_BOOT_TIME_SECONDS = 5.0
ESTIMATED_BOOT_TIME_SECONDS = 1.0
SELECTED_RECT_BOUNDS = [
(0, 0, 0, 0),
@@ -57,4 +57,17 @@ GROUPS_DELTA = [0, 12, 33]
GROUPS_SIZE = [6, 7, 2]
GPIO_BOUNCE = 0.05
GPIO_BUTTONS = [(21, [ecodes.KEY_R])]
GPIO_BUTTONS = [
(21, ecodes.KEY_LEFTSHIFT),
(12, ecodes.KEY_KP1),
(7, ecodes.KEY_KP2),
(25, ecodes.KEY_KP3),
(16, ecodes.KEY_KP4),
(1, ecodes.KEY_KP5),
(8, ecodes.KEY_KP6),
(24, ecodes.KEY_KPENTER),
]
DEMO_KEYCODE = ecodes.KEY_BACKSPACE
DEMO_GPIO = 21
DEMO_HOLD = 5.0
+1
View File
@@ -62,6 +62,7 @@ class ForgeData:
def __enter__(self) -> typing.Self:
if self.__data.try_restore_backup() or self.__data.read():
self.state = ForgeState.RESTORED
self.state = ForgeState.RUNNING # TODO temporary
return self
def __exit__(self, *_) -> None:
+22 -11
View File
@@ -3,38 +3,49 @@ import typing
import gpiozero
from evdev import ecodes, uinput
from .constants import GPIO_BOUNCE, GPIO_BUTTONS
from .constants import DEMO_GPIO, DEMO_HOLD, DEMO_KEYCODE, GPIO_BOUNCE, GPIO_BUTTONS
class Button:
def __init__(self, ui: uinput.UInput, gpio_pin: int, keycodes: list[int]) -> None:
def __init__(self, ui: uinput.UInput, gpio_pin: int, keycode: int) -> None:
self.__ui = ui
self.__btn = gpiozero.Button(gpio_pin, pull_up=True, bounce_time=GPIO_BOUNCE)
self.__keycodes = keycodes
self.__btn = gpiozero.Button(
gpio_pin,
pull_up=True,
hold_time=DEMO_HOLD,
hold_repeat=False,
bounce_time=GPIO_BOUNCE,
)
self.__keycode = keycode
self.__btn.when_activated = self.press
self.__btn.when_deactivated = self.release
if gpio_pin == DEMO_GPIO:
self.__btn.when_held = self.demo_hold
def press(self) -> None:
for keycode in self.__keycodes:
self.__ui.write(ecodes.EV_KEY, keycode, 1)
self.__ui.write(ecodes.EV_KEY, self.__keycode, 1)
self.__ui.syn()
def release(self) -> None:
for keycode in self.__keycodes:
self.__ui.write(ecodes.EV_KEY, keycode, 0)
self.__ui.write(ecodes.EV_KEY, self.__keycode, 0)
self.__ui.syn()
def demo_hold(self) -> None:
self.__ui.write(ecodes.EV_KEY, self.__keycode, 0)
self.__ui.write(ecodes.EV_KEY, DEMO_KEYCODE, 1)
self.__ui.write(ecodes.EV_KEY, DEMO_KEYCODE, 0)
self.__ui.syn()
class Inputs:
def __init__(self):
self.__buttons: list[Button] = []
self.__ui: uinput.UInput | None = None
def __enter__(self) -> typing.Self:
self.__ui = uinput.UInput()
for gpio_pin, keycodes in GPIO_BUTTONS:
self.__buttons += [Button(self.__ui, gpio_pin, keycodes)]
for gpio_pin, keycode in GPIO_BUTTONS:
Button(self.__ui, gpio_pin, keycode)
return self
+1 -1
View File
@@ -14,4 +14,4 @@ sudo chmod a+rw /dev/uinput
weston --shell=kiosk-shell.so --xwayland --config=${PROJECT_DIR}/system/${WESTON_MOD}/weston.ini --log=${PROJECT_DIR}/weston.log \
-- make --silent start 2>&1 > /dev/null
# sudo reboot 2>&1 /dev/null
sudo reboot 2>&1 /dev/null