diff --git a/.gitignore b/.gitignore index cea6c0e..29cdb72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ -error.glsl -forge_default_save.txt +*.log +.venv +__pycache__ build -tmp* debug.png -forge_default_save.txt.bck +error.glsl +forge_default_save.* +tmp* diff --git a/Makefile b/Makefile index 6bd0d36..beec35d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ PROJECT_DIR ?= $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) BUILD_DIR ?= $(PROJECT_DIR)/build FORGE_SRC ?= $(PROJECT_DIR)/forge-steel TARGET ?= forge -RUN_ARGS ?= --project=$(PROJECT_DIR)/project --internal-size=576 -nmr -t=10 --auto-save +SCREEN_HEIGHT ?= 480 +RUN_ARGS ?= --project=$(PROJECT_DIR)/project -is=$(SCREEN_HEIGHT) -nmr -t=10 --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 @@ -12,7 +13,7 @@ LDLIBS ?= -lm -lGL -lglfw -lasound # FILES -$(BUILD_DIR)/$(TARGET): forge-steel/src/main.c forge-steel/hashmap.c/hashmap.c forge-steel/log.c/src/log.c forge-steel/include/linmath.h +$(BUILD_DIR)/$(TARGET): mkdir -p $(BUILD_DIR) $(CC) $(SOURCES) $(CFLAGS) $(LDLIBS) -o $(BUILD_DIR)/$(TARGET) @@ -31,14 +32,6 @@ apt-install: pip-install: pip3 install luma.oled --break-system-packages -.PHONY: setup-weston -setup-weston: - ln -fs $(PROJECT_DIR)/system/weston.ini $(HOME)/.config/weston.ini - -.PHONY: remove-motd -remove-motd: - sudo rm -rf /etc/motd - .PHONY: disable-cloud-init disable-cloud-init: sudo systemctl disable cloud-init.service @@ -51,12 +44,8 @@ setup-services: sudo systemctl daemon-reload sudo systemctl enable getty@tty1.service seatd.service -.PHONY: setup-bashrc -setup-bashrc: - $(PROJECT_DIR)/scripts/line_in_file.sh "make -C $(PROJECT_DIR) --no-print-directory start" "$(HOME)/.bashrc" - .PHONY: install -install: remove-passwd apt-install pip-install setup-weston remove-motd disable-cloud-init setup-services setup-bashrc +install: remove-passwd apt-install pip-install disable-cloud-init setup-services .PHONY: clean clean: @@ -67,61 +56,15 @@ build: $(BUILD_DIR)/$(TARGET) .PHONY: run run: $(BUILD_DIR)/$(TARGET) - $(BUILD_DIR)/$(TARGET) $(RUN_ARGS) + @$(BUILD_DIR)/$(TARGET) $(RUN_ARGS) 2>&1 >> $(PROJECT_DIR)/forge.log .PHONY: start-bg start-bg: - @python3 $(PROJECT_DIR)/__main__.py &> $(PROJECT_DIR)/python.log & + @python3 $(PROJECT_DIR)/__main__.py 2>&1 >> $(PROJECT_DIR)/python.log 2>&1 .PHONY: start-fg start-fg: - @echo "on" | sudo tee /sys/class/drm/card1-Composite-1/status || true - @/usr/bin/weston --shell=kiosk-shell.so --xwayland --log=$(PROJECT_DIR)/weston.log -- kitty --hold make --no-print-directory -C $(PROJECT_DIR) run + @/usr/bin/weston --shell=kiosk-shell.so --xwayland --log=$(PROJECT_DIR)/weston.log -- kitty --hold make --silent --no-print-directory -C $(PROJECT_DIR) run 2>&1 > /dev/null .PHONY: start start: start-bg start-fg - -# HOST ONLY - -.PHONY: host-submodule-update -host-submodule-update: - git submodule update --init --recursive - -.PHONY: host-chmod-opt -host-chmod-opt: - sudo chmod a+rwx /run/media/$(shell whoami)/rootfs/opt/ - -.PHONY: host-rsync -host-rsync: host-chmod-opt - rsync -a $(PWD) /run/media/$(shell whoami)/rootfs/opt/ - -.PHONY: host-setup-custom -host-setup-custom: - cp $(PROJECT_DIR)/system/config.ini /run/media/$(shell whoami)/bootfs/custom.txt - -.PHONY: host-reset-config -host-reset-config: - sed -i '/include custom.txt/d' /run/media/$(shell whoami)/bootfs/config.txt - -.PHONY: host-setup-config -host-setup-config: host-setup-custom host-reset-config - echo "include custom.txt" >> /run/media/$(shell whoami)/bootfs/config.txt - -.PHONY: host-reset-cmdline -host-reset-cmdline: - sed -i '2,$$d' /run/media/$(shell whoami)/bootfs/cmdline.txt - -.PHONY: host-setup-cmdline -host-setup-cmdline: host-reset-cmdline - cat $(PROJECT_DIR)/system/cmdline.txt >> /run/media/$(shell whoami)/bootfs/cmdline.txt - -.PHONY: host-unmount -host-unmount: - sudo umount -R /run/media/$(shell whoami)/rootfs - sudo umount -R /run/media/$(shell whoami)/bootfs - -.PHONY: host-install -host-install: host-submodule-update host-rsync host-setup-config host-setup-cmdline host-unmount - -.PHONY: host-install-reset -host-install-reset: host-submodule-update host-rsync host-reset-config host-reset-cmdline host-unmount diff --git a/Makefile.dev b/Makefile.dev new file mode 100644 index 0000000..161bdad --- /dev/null +++ b/Makefile.dev @@ -0,0 +1,163 @@ +# ENV + +ifeq (,$(shell which uv)) + ifeq (,$(shell python3 -m uv --help||python3 -m pip install --user uv)) # detect uv install + UV ?= false + endif + UV ?= python3 -m uv +endif + +UV ?= uv +RUFF ?= $(UV) run --active ruff +TY ?= $(UV) run --active ty + +RASP_USER ?= forge +RASP_BOOTFS ?= /run/media/$(shell whoami)/bootfs +RASP_ROOTFS ?= /run/media/$(shell whoami)/rootfs +RELATIVE_PROJECT_PATH ?= /opt/forge-invar +RASP_PROJECT_PATH ?= $(RASP_ROOTFS)$(RELATIVE_PROJECT_PATH) + +# DOCS + +.PHONY: help +help: ## show this message + @echo "Usage: $(MAKE) [target1] [target2] ..." + @echo "" + @echo "Commands/Targets:" + @cat $(MAKEFILE_LIST) | grep -E '(^[a-zA-Z0-9_%-]+:.*?##.*$$)|(^##)' | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-20s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/' + @echo "" + @echo "Environment:" + @cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z0-9_-]+\s*\??=.*$$' | grep -Eo '^[a-zA-Z0-9_-]+' | xargs -I {} $(MAKE) -s print-{} 2> /dev/null + +.PHONY: print-% +print-%: + @echo -e '\033[32m$*\033[0m = $($*)' + +# FILES + +.venv: uv.lock + $(MAKE) -s uv-sync + +# ACTIONS + +.PHONY: init +init: uv-sync git-submodule-init git-submodule-update ## install project + +.PHONY: update +update: uv-upgrade ## update project dependencies + +.PHONY: format +format: ruff-fix ruff-format ## format project + +.PHONY: lint +lint: ruff ruff-format-check ty ## lint project + +.PHONY: rasp-init +rasp-init: rasp-chmod-opt rasp-rsync rasp-unmount ## init raspberry + +.PHONY: rasp-install +rasp-install: rasp-install-pal ## setup raspberry + +.PHONY: rasp-install-% +rasp-install-%: ## setup raspberry (PAL/NTSC/HDMI) + make git-submodule-update rasp-rsync rasp-setup-config-$* rasp-setup-cmdline-$* rasp-setup-start-$* rasp-unmount + +.PHONY: rasp-reset +rasp-reset: rasp-reset-config rasp-reset-cmdline rasp-reset-start rasp-unmount ## reset raspberry to console mode + +# TOOLS + +.PHONY: uv-sync +uv-sync: ## uv sync + $(UV) sync --active + +.PHONY: uv-update +uv-upgrade: ## uv sync upgrade + $(UV) sync --active --upgrade + +.PHONY: ruff +ruff: .venv ## ruff check + $(RUFF) check + +.PHONY: ruff-fix +ruff-fix: .venv ## ruff check (and fix) + $(RUFF) check --fix --unsafe-fixes + +.PHONY: ruff-format +ruff-format: .venv ## ruff format + $(RUFF) format + +.PHONY: ruff-format-check +ruff-format-check: .venv ## ruff format (check only) + $(RUFF) format --check + +.PHONY: ty +ty: .venv ## ty check + $(TY) check + +.PHONY: git-submodule-update +git-submodule-update: ## prepare git submodules + git submodule update --init --recursive + +.PHONY: rasp-chmod-opt +rasp-chmod-opt: ## chmod remote project + sudo chmod -R a+rwx $(RASP_ROOTFS)/opt + +.PHONY: rasp-remove-motd +rasp-remove-motd: ## + sudo rm -rf $(RASP_ROOTFS)/etc/motd + sudo rm -rf $(RASP_ROOTFS)/etc/issue + sudo rm -rf $(RASP_ROOTFS)/etc/update-motd.d/* + +.PHONY: rasp-rsync +rasp-rsync: ## sync remote project + rsync -av --del --exclude='*/.git/*' --exclude-from=.gitignore $(PWD) $(RASP_ROOTFS)/opt + +.PHONY: rasp-setup-custom-% +rasp-setup-custom-%: ## setup custom remote config.txt + cp $(PROJECT_DIR)/system/$*/config.ini $(RASP_BOOTFS)/custom.txt + +.PHONY: rasp-reset-config +rasp-reset-config: ## remove include in remote config.txt + sed -i '/include custom.txt/d' $(RASP_BOOTFS)/config.txt + +.PHONY: rasp-setup-config-% +rasp-setup-config-%: ## setup include in remote config.txt + make rasp-setup-custom-$* rasp-reset-config + echo "include custom.txt" >> $(RASP_BOOTFS)/config.txt + +.PHONY: rasp-reset-cmdline +rasp-reset-cmdline: ## remove custom line from remove cmdline.txt + sed -i '2,$$d' $(RASP_BOOTFS)/cmdline.txt + sed -i 's/console=tty3/console=tty1/g' $(RASP_BOOTFS)/cmdline.txt + +.PHONY: rasp-setup-cmdline-% +rasp-setup-cmdline-%: rasp-reset-cmdline ## add custom line to remove cmdline.txt + sed -i 's/console=tty1/console=tty3/g' $(RASP_BOOTFS)/cmdline.txt + cat $(PROJECT_DIR)/system/$*/cmdline.txt >> $(RASP_BOOTFS)/cmdline.txt + +.PHONY: rasp-reset-start +rasp-reset-start: ## remove custom .bashrc start + rm -f $(RASP_ROOTFS)/home/$(RASP_USER)/.bash_aliases + +.PHONY: rasp-setup-start +rasp-setup-start: rasp-reset-start ## install custom .bashrc start + echo "touch $(RELATIVE_PROJECT_PATH)/*" >> $(RASP_ROOTFS)/home/$(RASP_USER)/.bash_aliases + echo "make -C $(RELATIVE_PROJECT_PATH) --silent --no-print-directory start" >> $(RASP_ROOTFS)/home/$(RASP_USER)/.bash_aliases + +.PHONY: rasp-setup-start-hmdi +rasp-setup-start-%: rasp-reset-start ## install custom .bashrc start + cp -f $(PROJECT_DIR)/system/$*/start.sh $(RASP_ROOTFS)/home/$(RASP_USER)/.bash_aliases + +.PHONY: rasp-unmount +rasp-unmount: ## unmount rootfs/bootfs + sudo umount -R $(RASP_BOOTFS) + sudo umount -R $(RASP_ROOTFS) + +.PHONY: rasp-force-rebuild +rasp-force-rebuild: ## rm remote project/build + rm -rf $(RASP_PROJECT_PATH)/build + +.PHONY: rasp-import-logs +rasp-import-logs: ## import remote logs + cp -f $(RASP_PROJECT_PATH)/*.log . diff --git a/README.md b/README.md index 80da000..ba14446 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,40 @@ ## Install +## 1. Prepare raspberry SD card + +Use [raspi-imager](https://www.raspberrypi.com/software/) and select "Raspberry Pi OS Lite" (in other options) + +## 2. Add project to rasp + +Re-mount SD card (auto unmounted by raspi-imager) + ```bash -sudo apt update -sudo apt install -y git -sudo chmod a+rwx /opt -cd /opt -git clone --recursive https://git.klemek.fr/klemek/forge-invar -cd forge-invar -make install build -echo 'make -C /opt/forge-invar start-weston' >> ~/.bashrc +# host +make -f Makefile.dev rasp-init ``` +## 3. Install dependencies in raspberry + +Boot raspberry + +```bash +# raspberry +cd /opt/forge-invar +make install build +``` + +## 4. Setup PAL output + +Re-mount SD card + +```bash +# host +make -f Makefile.dev rasp-install +``` + +## 5. Enjoy + ## Links * https://www.raspberrypi.com/documentation/computers/config_txt.html @@ -34,20 +57,24 @@ echo 'make -C /opt/forge-invar start-weston' >> ~/.bashrc * https://electricalflux.com/mcu-raspberry/i2c-oled-display-raspberry-pi-5-wiring-code * https://www.raspberrypi.com/documentation/computers/configuration.html * https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios +* https://raspberrypihq.com/use-a-push-button-with-raspberry-pi-gpio/ ## TODO Logical * [x] Play on start -* [ ] disable services for faster boot +* [x] disable services for faster boot +* [x] remove texts on boot * [ ] special texts in demo vs classic * [x] Save while running -* [ ] I2C monitor screen write +* [x] I2C monitor screen write +* [ ] fix logs on machine Physical -* [ ] PAL/NTSC switch -* [ ] Sync in -> fake keyboard +* [x] I2C screen +* [ ] Sync in +* [ ] buttons input (save/load states, random, reset, demo) * [ ] rasp compute -* [ ] I2C screen +* [ ] PAL/NTSC switch (hard) diff --git a/scripts/append_to_file.sh b/scripts/append_to_file.sh deleted file mode 100755 index cd48097..0000000 --- a/scripts/append_to_file.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -e - -LINE=$1 -FILE=$2 -DETECT=${3:-$LINE} - -if [[ -z $(grep "$DETECT" "$FILE") ]]; then - echo "Line not found in $FILE" - echo -n "$LINE" >> "$FILE" -else - echo "Fragment already exists in $FILE" -fi diff --git a/scripts/line_in_file.sh b/scripts/line_in_file.sh deleted file mode 100755 index deb0ed7..0000000 --- a/scripts/line_in_file.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -e - -LINE=$1 -FILE=$2 -DETECT=${3:-$LINE} - -if [[ -z $(grep "$DETECT" "$FILE") ]]; then - echo "Line not found in $FILE" - echo "$LINE" >> "$FILE" -else - echo "Line already exists in $FILE" -fi diff --git a/system/cmdline.txt b/system/cmdline.txt deleted file mode 100644 index 48f080e..0000000 --- a/system/cmdline.txt +++ /dev/null @@ -1 +0,0 @@ -vc4.tv_norm=PAL video=Composite-1:720x576ie,tv_mode=PAL quiet loglevel=0 consoleblank=1 diff --git a/system/getty@tty1.service b/system/getty@tty1.service index c6d9e1a..cb98517 100644 --- a/system/getty@tty1.service +++ b/system/getty@tty1.service @@ -21,7 +21,7 @@ Before=rescue.service ConditionPathExists=/dev/tty0 [Service] -ExecStart=-/sbin/agetty --autologin forge --noreset --noclear %I ${TERM} +ExecStart=-/sbin/agetty --autologin forge --noissue --nohints --nohostname --noreset --noclear %I ${TERM} Type=idle Restart=always RestartSec=0 diff --git a/system/hdmi/cmdline.txt b/system/hdmi/cmdline.txt new file mode 100644 index 0000000..689422d --- /dev/null +++ b/system/hdmi/cmdline.txt @@ -0,0 +1 @@ +quiet loglevel=3 quiet logo.nologo vt.global_cursor_default=0 diff --git a/system/hdmi/config.ini b/system/hdmi/config.ini new file mode 100644 index 0000000..85d4e80 --- /dev/null +++ b/system/hdmi/config.ini @@ -0,0 +1,22 @@ +[all] +# --- overclocking --- +# ARM core frequency in MHz +arm_freq=3000 +# VideoCore VII frequency in MHz +gpu_freq=1000 +# Voltage offset in microvolts +over_voltage_delta=50000 + +# --- opengl --- +# Enable DRM VC4 V3D driver +dtoverlay=vc4-kms-v3d +# Increase the memory reserved for the GPU +gpu_mem=64 +# Avoid GPU down-clocking below 500 MHz that slows FPS down +# v3d_freq_min=500 + +# --- composite --- +enable_tvout=0 + +# --- I2C --- +dtparam=i2c_arm=on diff --git a/system/hdmi/start.sh b/system/hdmi/start.sh new file mode 100755 index 0000000..ca16021 --- /dev/null +++ b/system/hdmi/start.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +export PROJECT_DIR=/opt/forge-invar +export SCREEN_HEIGHT=576 + +ln -fs $PROJECT_DIR/system/hdmi/weston.ini $HOME/.config/weston.ini + +rm -rf $PROJECT_DIR/*.log +touch $PROJECT_DIR/* +make -C /opt/forge-invar --silent --no-print-directory start diff --git a/system/hdmi/weston.ini b/system/hdmi/weston.ini new file mode 100644 index 0000000..1fa5a68 --- /dev/null +++ b/system/hdmi/weston.ini @@ -0,0 +1,3 @@ +[core] +idle-time=0 +require-input=false diff --git a/system/ntsc/cmdline.txt b/system/ntsc/cmdline.txt new file mode 100644 index 0000000..62a2b7c --- /dev/null +++ b/system/ntsc/cmdline.txt @@ -0,0 +1,2 @@ +vc4.tv_norm=NTSC video=Composite-1:720x480ie,tv_mode=NTSC +quiet loglevel=0 quiet logo.nologo vt.global_cursor_default=0 diff --git a/system/config.ini b/system/ntsc/config.ini similarity index 97% rename from system/config.ini rename to system/ntsc/config.ini index c225e8b..ead2069 100644 --- a/system/config.ini +++ b/system/ntsc/config.ini @@ -17,7 +17,7 @@ gpu_mem=64 # --- composite --- enable_tvout=1 -sdtv_mode=2 +sdtv_mode=0 sdtv_aspect=1 # --- I2C --- diff --git a/system/ntsc/start.sh b/system/ntsc/start.sh new file mode 100755 index 0000000..a685d07 --- /dev/null +++ b/system/ntsc/start.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +export PROJECT_DIR=/opt/forge-invar +export SCREEN_HEIGHT=480 + +ln -fs $PROJECT_DIR/system/ntsc/weston.ini $HOME/.config/weston.ini + +rm -rf $PROJECT_DIR/*.log +touch $PROJECT_DIR/* +make -C /opt/forge-invar --silent --no-print-directory start diff --git a/system/ntsc/weston.ini b/system/ntsc/weston.ini new file mode 100644 index 0000000..7e1f255 --- /dev/null +++ b/system/ntsc/weston.ini @@ -0,0 +1,8 @@ +[core] +idle-time=0 +require-input=false + +[output] +name=Composite-1 +mode=720x480i +force-on=true diff --git a/system/pal/cmdline.txt b/system/pal/cmdline.txt new file mode 100644 index 0000000..00c4cf6 --- /dev/null +++ b/system/pal/cmdline.txt @@ -0,0 +1,2 @@ +vc4.tv_norm=PAL video=Composite-1:720x576ie,tv_mode=PAL +quiet loglevel=0 quiet logo.nologo vt.global_cursor_default=0 diff --git a/system/pal/config.ini b/system/pal/config.ini new file mode 100644 index 0000000..59b0d2f --- /dev/null +++ b/system/pal/config.ini @@ -0,0 +1,22 @@ +[all] +# --- overclocking --- +# ARM core frequency in MHz +arm_freq=3000 +# VideoCore VII frequency in MHz +gpu_freq=1000 +# Voltage offset in microvolts +over_voltage_delta=50000 + +# --- opengl --- +# Enable DRM VC4 V3D driver +dtoverlay=vc4-kms-v3d,composite +# Increase the memory reserved for the GPU +gpu_mem=64 +# Avoid GPU down-clocking below 500 MHz that slows FPS down +# v3d_freq_min=500 + +# --- composite --- +enable_tvout=1 + +# --- I2C --- +dtparam=i2c_arm=on diff --git a/system/pal/start.sh b/system/pal/start.sh new file mode 100755 index 0000000..73427b6 --- /dev/null +++ b/system/pal/start.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +export PROJECT_DIR=/opt/forge-invar +export SCREEN_HEIGHT=576 + +ln -fs $PROJECT_DIR/system/pal/weston.ini $HOME/.config/weston.ini + +rm -rf $PROJECT_DIR/*.log +touch $PROJECT_DIR/* +make -C /opt/forge-invar --silent --no-print-directory start diff --git a/system/weston.ini b/system/pal/weston.ini similarity index 100% rename from system/weston.ini rename to system/pal/weston.ini