Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions buildroot-external/configs/retrostone2_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ BR2_PACKAGE_MESA3D=y
BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_LIMA=y
BR2_PACKAGE_MESA3D_OPENGL_EGL=y
BR2_PACKAGE_MESA3D_OPENGL_ES=y
# SDL2 on KMS/DRM + GLES2 and ALSA, for native games (docs/native-games.md)
BR2_PACKAGE_SDL2=y
BR2_PACKAGE_SDL2_KMSDRM=y
BR2_PACKAGE_SDL2_OPENGLES=y
BR2_PACKAGE_KMSCUBE=y

# Bring-up tools
Expand Down
4 changes: 4 additions & 0 deletions buildroot-external/configs/retrostone2_release_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ BR2_PACKAGE_MESA3D=y
BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_LIMA=y
BR2_PACKAGE_MESA3D_OPENGL_EGL=y
BR2_PACKAGE_MESA3D_OPENGL_ES=y
# SDL2 on KMS/DRM + GLES2 and ALSA, for native games (docs/native-games.md)
BR2_PACKAGE_SDL2=y
BR2_PACKAGE_SDL2_KMSDRM=y
BR2_PACKAGE_SDL2_OPENGLES=y
BR2_PACKAGE_KMSCUBE=y

# Bring-up tools
Expand Down
55 changes: 55 additions & 0 deletions docs/native-games.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Native games

A native game is a program built for the console itself (ARM, Linux), started without an emulator: an
open-source game engine, a source port, a homebrew game. The menu lists them as the system **Native games**.

## On the SD card

One launch script per game in `roms/native/` (subfolders are fine), with the game's own files next to it:

```
roms/native/
My Game.sh <- the entry in the menu ("My Game")
mygame/
mygame <- the program (ARM, linked against this system's libraries)
data files...
```

The script runs with `/bin/sh` in **its own folder** (the working directory), so it can use relative paths. It
should end with `exec` so the game is the process the menu watches:

```sh
#!/bin/sh
cd mygame
exec ./mygame
```

A program that the exFAT partition does not mark executable can be started through the dynamic loader:
`exec /lib/ld-linux-armhf.so.3 ./mygame`.

## What the game gets

* The display, the sound and the pads, as a libretro game does: the menu drops DRM master before the launch and
takes it back afterwards. **SDL2** is installed with the KMS/DRM video driver (GLES2 on the Mali-400 through
Mesa's lima) and ALSA; the menu sets `SDL_VIDEODRIVER=kmsdrm` and `SDL_AUDIODRIVER=alsa`.
* `HOME=/data/rsos/native-home` (the root file system is read-only), with `XDG_CONFIG_HOME` and
`XDG_DATA_HOME` under it. A game that saves next to itself (its working directory) keeps its saves on the card.
* `RSOS_GAME_DIR` (the script's folder) and `RSOS_LANG` (the menu's language, e.g. `en`).
* Its output goes to `/run/rsos/game.log`, copied to `rsos/logs/` on the SD card at the next start.

The built-in controls are three input devices (the buttons, the shoulder buttons, the optional analog stick):
a game that reads only one SDL game controller sees only one of them. Read every `/dev/input/event*` device
whose name starts with "RetroStone2", or merge them.

## What the menu does around it

* **Select + Start** held for one second quits the game (SIGTERM to its process group, SIGKILL if it is still
there 5 s later). A native game has no in-game menu of ours.
* **Sleep** (power key): the game is frozen (SIGSTOP) and the backlight goes off; waking continues it.
* **Power-off**: the game gets SIGTERM, then SIGKILL after 8 s. There is no save state: the game must save on
its own.
* The **idle power-off** waits while a native game runs (it could not resume it).
* An exit code other than 0 (and other than a stop by Select+Start or the menu) shows "The game ended with an
error".

`make check-frontend` (steps 2a-2c) covers the launch, the environment, the error message and the process group.
32 changes: 32 additions & 0 deletions frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,38 @@ check-frontend: $(FRONTEND) $(HOST_TESTCORE) $(SPLASH)
grep -q 'crashed' $(FE_LOG)
grep -q 'signal 15: exiting' $(FE_LOG)
grep -q 'exit 0 after' $(FE_LOG)
@echo "check-frontend: 2a. a native game: its script runs in its folder, HOME on /data, SDL on KMS"
@# the native games only: the menu starts on them
mv $(FE_CHECK_DIR)/data/roms/nes $(FE_CHECK_DIR)/data/nes.aside
rm -f $(FE_CHECK_DIR)/data/rsos/cache/systems.idx
printf 'language = en\nlast_system = native\n' > $(FE_SETTINGS)
rm -f $(FE_LOG)
mkdir -p $(FE_CHECK_DIR)/data/roms/native/files
printf 'echo "$$PWD|$$HOME|$$SDL_VIDEODRIVER|$$RSOS_GAME_DIR" > files/ran.txt\nexit $${RSOS_TEST_NATIVE_EXIT:-0}\n' \
> "$(FE_CHECK_DIR)/data/roms/native/Native Test.sh"
$(FE_RUN) --script "wait:600 a wait:500 a wait:1500 shot:$(FE_CHECK_DIR)/native.png term"
grep -q 'launch native Native Test' $(FE_LOG)
grep -q 'native game ended: 0' $(FE_LOG)
test "$$(cat $(FE_CHECK_DIR)/data/roms/native/files/ran.txt)" = \
"$(FE_CHECK_DIR)/data/roms/native|$(FE_CHECK_DIR)/data/rsos/native-home|kmsdrm|$(FE_CHECK_DIR)/data/roms/native"
grep -q '^=== \[.*\] launch native: .*Native Test.sh' $(FE_GAME_LOG)
@echo "check-frontend: 2b. a native game that fails: its exit code is shown"
printf 'language = en\nlast_system = native\n' > $(FE_SETTINGS)
rm -f $(FE_LOG)
RSOS_TEST_NATIVE_EXIT=3 $(FE_RUN) --script "wait:600 a wait:500 a wait:1500 term"
grep -q 'native game ended: 3' $(FE_LOG)
@echo "check-frontend: 2c. the menu stops: the native game and what it started go too"
printf 'language = en\nlast_system = native\n' > $(FE_SETTINGS)
rm -f $(FE_LOG) $(FE_CHECK_DIR)/data/roms/native/files/bg.pid
printf 'sleep 300 &\necho $$! > files/bg.pid\nwait\n' > "$(FE_CHECK_DIR)/data/roms/native/Native Test.sh"
$(FE_RUN) --script "wait:600 a wait:500 a game:wait:1000 game:term"
grep -q 'signal 15: asking the game to quit' $(FE_LOG)
grep -q 'native game ended: 143' $(FE_LOG)
test -s $(FE_CHECK_DIR)/data/roms/native/files/bg.pid
! kill -0 $$(cat $(FE_CHECK_DIR)/data/roms/native/files/bg.pid) 2> /dev/null
rm -rf $(FE_CHECK_DIR)/data/roms/native
mv $(FE_CHECK_DIR)/data/nes.aside $(FE_CHECK_DIR)/data/roms/nes
rm -f $(FE_CHECK_DIR)/data/rsos/cache/systems.idx
@echo "check-frontend: 3. charge mode, charger already unplugged: power-off"
rm -f $(FE_LOG)
printf 'charger\n' > $(FE_CHECK_DIR)/run/rsos/bootreason
Expand Down
Loading
Loading