RG34XX and RG35XXSP
Selium
A package manager and tweak loader. A fresh card starts from the RG34XX or RG35XXSP download on the home page.
- 2
- Consoles
- 9
- Packages
- 720
- RG34XX wide
- 640
- SP wide
Purpose
Selium installs apps and small modifications onto the ROMs card of an RG34XX or an RG35XXSP, then runs the Python tweaks you installed. The console menu already launches anything in Roms/APPS. This app adds a repo browser, a local package list, and a loader that calls load on each installed tweak. The program folder on the card stays jailbreak.
The built-in repo lists one example, Note. It writes a short file the first time you turn it on. Nothing is marked Essential, so the first launch does not install it. Cask, Launcher colors, the GIF background, Wave, RGB, Terminal, RiftBoard, RGTorrent, and Chrome are in the DevCasp Repo folder, not in this built-in list. Pulse, pop, rise, and skew stay inside Cask. They are not packages.
There is no default remote repo. The word local means the Packages file shipped inside the app. Add an address only when you trust the person who published it. A tweak is ordinary Python. The path checks stop a zip from walking out of the card. They are not a sandbox against a program you decided to run.
Install
The home page has a download for each console. RG34XX-fresh.zip is the 720 by 480 pack. RG35XXSP-fresh.zip is the 640 by 480 pack. The apps inside match. Each zip places the launcher script at dmenu.bin and copies Selium, RGOpus, RiftBoard, RGTorrent, Terminal, DevSearch, and the DevCasp Repo onto the ROMs card. You can also copy Selium by itself.
| Console | Screen | Download |
|---|---|---|
| RG34XX | 720 by 480, horizontal | RG34XX-fresh.zip |
| RG35XXSP | 640 by 480, clamshell | RG35XXSP-fresh.zip |
Copy dmenu.bin to the root of the large card, beside the anbernic folder, and merge Roms. The small card named Volumn is the boot logo. Leave it alone. The classic theme starts the launcher. The MU theme ignores dmenu.bin, so open Launcher from Apps. The RG35XXSP has no analog sticks. Button test and joystick calibration stay in the stock menu.
| On the computer | On the card |
|---|---|
Selium.sh | Roms/APPS/Selium.sh |
jailbreak/ | Roms/APPS/jailbreak/ |
Imgs/Jailbreak.png | Roms/APPS/Imgs/Jailbreak.png |
This page lives in the project folder on the computer. Leave it there. The console does not need it.
Eject the card, boot the handheld, and open Selium from Jailbreak Tools. Jailbreak.sh still starts the same program. The launcher sets the SDL library path, starts the volume helper when that helper exists, and writes jailbreak/log.txt.
The install root is the parent of APPS when jailbreak/ sits inside a directory named APPS. On the card that parent is Roms. A copy that is still on the computer, outside a folder named APPS, does nothing until the files are on the card. Setting RG34_ROMS to a folder overrides that detection on Windows, Mac, and Linux.
Install ROMs
Copy each game into its folder on the large ROMs card. The launcher lists that folder. Leave the Volumn card alone.
| System | Folder | File |
|---|---|---|
| NES | Roms/FC | .nes |
| Super NES | Roms/SFC | .sfc or .smc |
| Game Boy | Roms/GB | .gb |
| Game Boy Color | Roms/GBC | .gbc |
| Game Boy Advance | Roms/GBA | .gba |
| Mega Drive | Roms/MD | .md or .gen |
| PlayStation | Roms/PS | .chd, .cue, or .pbp |
| PSP | Roms/PSP | .iso, .cso, or .pbp |
| Nintendo DS | Roms/NDS | .nds |
Other stock folders, such as N64, MAME, and FBNEO, work the same way. A zip or 7z in a cartridge folder can stay packed. Open it in the launcher and start one file inside. Arcade sets stay zipped. Music goes in Music, video in Video, and books in Ebook or PDF, at the card root. Eject the card and boot. The game is under Consoles or Arcade.
Launcher
The classic theme starts dmenu.bin from the card root. That file is the launcher. The original menu stays at /mnt/vendor/bin/dmenu.bin and is not replaced. On the MU theme, open Launcher from Apps.
Settings, Wi-Fi, turns the radio on before it looks for networks. You do not open the stock Wi-Fi page first. A saved network is joined again when the radio comes up. A protected network asks for the password. If nothing is in range, the list says no networks were found.
Settings, Boot menu, remembers Launcher or Stock in launcher/data/boot.txt. Choosing Stock opens the original menu and the next boots stay there. Open Launcher from Apps and set Boot menu back to Launcher when you want the new menu again. The switch does not power the device off. Leaving the original menu still powers the device off, because that is how the stock firmware ends its own session.
Settings, Jailbreak, is hidden until a tweak is installed. Each installed tweak is its own row. A opens that tweak. The first line turns it on or off, and it stays on until you turn it off. Cask's screen has style, duration, fresh lists, game titles, and other lists. Launcher colors has the named themes and a custom color such as #3366cc. The image rows are on the GIF background screen. RGB is on and off only.
Restart and Power off ask first. Restart restarts the device. Power off powers it off. The launcher stays purple until Launcher colors is installed and turned on. While that tweak is on, Selium, RGOpus, RiftBoard, RGTorrent, Terminal, and Chrome use the same color. List motion runs only while Cask is installed and turned on. A saved GIF, PNG, or JPEG is drawn behind the launcher lists. The original menu does not show that picture.
The launcher, Selium, RGOpus, RiftBoard, RGTorrent, Terminal, and DevSearch read the panel when they open. The RG34XX and the RG34XXSP are 720 by 480. The RG34XXSP is the clamshell with the same panel. The RG35XXSP is a clamshell at 640 by 480. Buttons are read from every gamepad port, so the lid switch does not hide the d-pad.
Controls
| Button | Action |
|---|---|
| Up / Down | Move. Up is a negative hat step, so the list moves up. |
| A | Open, install, upgrade, or reinstall. |
| B | Back. On the home screen, B leaves the app. |
| X | Remove the selected package or source. On the keyboard, X deletes. |
| Y | Add a source. On the keyboard, Y types a space. |
| Select | On the keyboard, toggle capitals. |
| Start | Refresh the package list, or confirm the keyboard. |
The panel font draws capitals only. A web address is still stored in the case you typed. Letters are lowercase until CASE is on.
Screens
Home
Installed, Packages, Search, Sources, and Apply tweaks. Tweak switches live in the launcher under Settings, Jailbreak.
Installed
Packages recorded in state/installed.json. A opens the detail. X removes the package and, if it was a tweak, calls unload first.
Packages
The merged list from every source. A newer version of the same id replaces an older one. The screen shows the section, the name, and the version. An installed row is marked On.
Search
Filters the list you already have. It matches the name, description, id, and section. It does not search the web.
Detail
Shows the name, section, version, and about eight lines of description. A installs, upgrades, or reinstalls. X removes. If the package asks for another package that is not installed, the install stops and names it.
Sources
Starts as the single line local. Y opens the keyboard. Type local, an http:// or https:// address, or a folder on the card such as repos/DevCasp Repo. An address that ends in /Packages is stored as the directory that contains that file. A folder source has to stay on the card. file:// is refused. X removes a source. An empty list is allowed. Type local again to put the built-in repo back. Start reads every source.
Busy and notices
Reading sources, installing, removing, and applying tweaks each paint a working screen before the call. Errors and finished actions use a notice. A or B continues. The same line is printed to log.txt.
Included packages
The built-in list has one package.
| Id | What it does |
|---|---|
com.example.note | Example tweak. Off until you turn it on. The first time it loads, it writes APPS/jailbreak/data/note.txt. Turning it off deletes that file. |
DevCasp Repo, in the fresh card pack at Roms/repos/DevCasp Repo, has the rest. Add the source repos/DevCasp Repo when you want that copy.
| Id | What it does |
|---|---|
com.devcasp.cask | Animates game titles and other lists. Writes cask.txt only when that file is missing. Turn it on under Jailbreak settings. |
com.devcasp.colors | Colors the launcher and the other jailbreak apps. The screens stay on their own colors until this is installed and turned on. Jailbreak settings can pick a named theme or a hex color such as #3366cc. |
com.rg34.wall | Writes APPS/jailbreak/data/wall.txt when that file is missing. The launcher downloads that address and plays it behind its lists. Set the address in Jailbreak settings. Turning it off deletes the address and the saved GIF. |
com.devcasp.wave | Sets the list style to wave. Duration and the other switches stay. Turning it off restores the previous style. |
com.devcasp.rgb | 1.2 paints every launcher list in a moving RGB gradient and fills the bar behind the text. The selected row uses that gradient instead of the theme color. Turning it off removes the mod. Installed shows the version inside the package file. Upgrade when that version is older than Packages, then choose Apply tweaks. |
com.devcasp.terminal | Installs Terminal. After Selium installs it, the launcher lists it under Jailbreak Tools. A script copied onto the card by itself stays under Apps. |
com.devcasp.riftboard | Installs RiftBoard. It sets the launcher font from an address or a .ttf or .bdf file. Theme zips already on the card stay. |
com.devcasp.rgtorrent | Installs RGTorrent. The torrent inbox stays. |
com.devcasp.chrome | Installs Chrome. After Selium installs it, the launcher lists it under Jailbreak Tools. Pages show images, colors, scripts, and PHP output. Words in the address bar search Google. Downloads land in chrome/downloads. |
Hello tweak, Tweak banner, and Launch wrap are not in either repo. GIF background plays inside the launcher. The stock menu does not show it.
Cask scroll animation
Cask is in DevCasp Repo, with Launcher colors, GIF background, Wave, RGB, Terminal, RiftBoard, RGTorrent, and Chrome. That folder is in the fresh card pack at Roms/repos/DevCasp Repo. Add the source repos/DevCasp Repo when you want that copy. You can also host the folder and add its http address. The built-in repo is only the Note example.
Copying that folder does not update Jailbreak itself. If installing Cask says the size does not match, copy jailbreak/repo.py to Roms/APPS/jailbreak/repo.py. If Apply tweaks says com.devcasp.cask has no attribute exists, copy jailbreak/inject.py the same way and choose Apply tweaks again. Apply replaces the installed Cask file that called the missing method, and it keeps the style already saved in cask.txt.
After Cask is installed, package titles and source rows animate inside Jailbreak. The Jailbreak home menu, title bar, and hint bar stay still. The stock menu is a separate program. Its lists use the same animation only when that program loads the hook. The styles are fade, flip, bounce, color, permanent color, glitch, helix, rotate, zoom, drop, stretch, slide, shake, swing, jiggle, wave, pulse, rise, skew, and pop. It starts on bounce, at 250 ms. Rows below the first one start a little later.
Tweak settings are in the launcher. Open Launcher, Settings, Jailbreak. That row is hidden until a tweak is installed. Each installed tweak is its own row. A opens that tweak. The first line turns it on or off, and it stays on until you turn it off. Cask's screen has style, duration, fresh lists, game titles, and other lists. Launcher colors has the named themes and a custom color such as #3366cc. The image rows are on the GIF background screen. RGB is on and off only. The launcher and the other jailbreak apps stay on their own colors until Launcher colors is installed and turned on. Cask animations run only while Cask is installed and turned on. Pulse, pop, rise, and skew stay in that style list. They are not separate packages. The id is saved in jailbreak/state/enabled.txt, and the next launch loads it again until you turn it off. A or left and right changes the highlighted line on that tweak's screen. Game titles are the wide rows. Other lists are the narrower ones, including source rows in Selium. Fresh lists plays the animation again when a list opens. The style none keeps Cask turned on and stops the motion. The launcher stores its own copy in launcher/data/look.txt. Applying tweaks again does not reset a file that is already there, and it does not turn a tweak on by itself. Removing Cask deletes cask.txt, and the rows move instantly, the way they did before. An app installed from Selium shows under Jailbreak Tools. A tweak can install APPS/launcher/mods/package.id.py to change a list row or the highlighted keyboard key, write a file inside an app folder, or leave a note in APPS/launcher/design/. It does not replace the launcher program or the vendor menu.
On the console, opening Jailbreak or choosing Apply tweaks also writes dmenu.bin on the card root, next to the anbernic folder, when that file is missing or is already the Cask wrapper. That file is a short script. It starts /mnt/vendor/bin/dmenu.bin. The vendor file is not replaced. A card-root dmenu.bin that is the launcher, marked RG34_LAUNCHER, is left alone. The earlier Cask script only set LD_PRELOAD, and the menu log never showed dmenu.bin loading the hook, so preload alone cannot animate that menu. The script now points the menu at libcaskhook.so in three ways. SDL_DYNAMIC_API is set so a menu built with SDL2's dynamic table can enter the hook. If the menu opens libSDL-1.2.so.0 by name, that name resolves to the hook and the hook forwards the rest of SDL 1.2 to the real library. If the menu names that library by a full path, the script runs a private copy under /tmp with that path rewritten, and the vendor binary stays untouched. Preload is added only when the menu file is a dynamic executable, and the hook clears it inside the menu so a game does not keep it. If the hook cannot be loaded, the script starts the stock menu without it. If the menu stops twice in one boot before the first frame, the next start is the stock menu with the hook left out, until the next boot. The boot-logo partition is not modified. Copying the DevCasp Repo folder does not install this hook. Copy the jailbreak folder, including libcaskhook.so and caskwrap.py, and keep state/installed.json and state/sources.txt. Removing Cask deletes the script when the script is the Cask launcher. After the next boot, jailbreak/data/caskhook.log shows a menu comm= or dynapi comm= line when the menu loaded the hook.
Terminal, RiftBoard, and RGTorrent install from the DevCasp Repo. Theme Studio and the pages on this site stay on the computer.
Tweak injection
A package zip may contain three kinds of members: control, an optional tweak.py, and files under payload/. The payload paths are relative to the ROMs root, and every one of them must stay under APPS/.
These paths are refused:
.., an absolute path, or a symlinkAPPS/Jailbreak.sh,APPS/Selium.sh,APPS/RGOpus.sh, andAPPS/Launcher.sh- the launcher program under
APPS/launcher/:main.py,menu.sh,ui.py,library.py,colors.py,anim.py,mods.py,tweaks.py,device.py,screen.py,font.py,board.py,wall.py,launch.py, andarchive.py - anything under
APPS/jailbreak/other thanAPPS/jailbreak/data/andAPPS/jailbreak/tweaks/ - a path containing
Stock_theme_bak - a zip member that is not
control,tweak.py, orpayload/...
A .sh file is marked executable after it is written. tweak.py is stored as APPS/jailbreak/tweaks/<package id>.py. The id may contain letters, digits, and .-+. A package may add APPS/launcher/mods/<package id>.py, a file in APPS/launcher/design/, or files inside another app folder. A top-level app script such as APPS/Terminal.sh is a normal payload file.
Apply tweaks, and each later launch of Selium on the card, calls load(api) for tweaks listed in state/enabled.txt. A tweak that is installed but off is left as it is. One failure is recorded and the rest still run. Turning a tweak off, or removing it, calls unload(api). Remove also deletes the files the package recorded, drops its id from the enabled list, and removes empty folders under data/ and tweaks/ only.
The first-launch flag is jailbreak/state/bootstrapped. It is written only when a ROMs root exists, so opening the project on Windows, Mac, or Linux does not create that flag and does not copy a skip onto the card. The built-in repo has no Essential package, so a missing flag does not install one.
Tweak API
A tweak defines load and, when it has something to undo, unload. Both receive an api object.
def load(api):
api.write("APPS/jailbreak/data/note.txt", "Tweaks are on\n")
def unload(api):
api.remove("APPS/jailbreak/data/note.txt")
| Call | Effect |
|---|---|
api.write(path, text) | Writes text or bytes under APPS/jailbreak/data/ or APPS/jailbreak/tweaks/, a mod at APPS/launcher/mods/<package id>.py, a file that is not Python in APPS/launcher/design/, or a file inside an app folder such as APPS/chrome/extra.txt. APPS/Other.sh and the launcher program files are refused. |
api.remove(path) | Deletes one file on those same paths. |
api.launchers() | Lists APPS/*.sh files. Skips .sh.stock and symlinks. |
api.wrap_launcher(name) | If the script is not already wrapped, copies it to name.stock and writes a wrapper marked RG34_JAILBREAK_WRAP. Doing it twice does not copy the wrapper over the stock script. |
api.unwrap_launcher(name) | Restores name.stock only when the current file contains that marker. |
The wrapper looks like this:
#!/bin/bash # RG34_JAILBREAK_WRAP here="$(cd "$(dirname "$0")" || exit; pwd)" export RG34_TWEAKS=1 exec "$here/Name.stock" "$@"
A launcher mod can define paint_list_row(canvas, x, y, width, height, message, scale, phase, selected) and return true after it draws that row's bar and label. It can also define paint_selected(canvas, x, y, message, scale, phase) for the highlighted keyboard key. The first mod that returns true is the one the launcher keeps. import ui, then ui.text_rgb and ui.gradient_rect, paint a moving gradient. Phase runs from 0 to 1. RGB 1.2 writes APPS/launcher/mods/com.devcasp.rgb.py when it is turned on and deletes that file when it is turned off. An older RGB package wrote rgb.txt and left the lists alone. Upgrade it, choose Apply tweaks, and use a launcher that calls paint_list_row.
Tweak tool
The tweak tool builds a package in the browser on Windows, Mac, or Linux. The example writes APPS/jailbreak/data/note.txt the first time it loads and deletes that file when the package is removed. Load launcher mod fills the boxes with a package that writes APPS/launcher/mods/com.example.paint.py. The Note example stays the default. Edit the code boxes, then export the repo folder. Unzip it and copy the folder to Roms/repos/. In Selium, add the source repos/ plus the folder name.
Package zip
Layout of one package, before makerepo.py zips it:
examples/com.example.thing/ control tweak.py optional payload/APPS/Thing.sh optional files under APPS/
control is plain text:
Package: com.example.thing Version: 1.0 Name: Thing Section: Apps Description: One sentence about the package. Essential: yes
Essential: yes means the first launch on the card installs it. Leave that line off for a package the user should choose. Depends is an optional comma-separated list of package ids. A parenthesized version is ignored. The built-in package does not depend on another package.
Packages index
repo/Packages is a Debian-style index. Blank lines separate packages. A line that starts with a space continues the previous field.
Package: com.rg34.wall Version: 1.0 Name: GIF background Section: Tweaks Description: Plays a GIF link behind the launcher lists. Size: 1234 MD5sum: abcdef... Filename: pool/com.rg34.wall.zip
Filename is relative to the repo directory. .., a leading slash, and a URL are ignored. Size and MD5sum describe the zip file. Extra bytes wrapped around that zip are ignored when the listed size and checksum still match the zip inside. A rebuilt zip whose listed size is stale is installed when its control file names the same package and the Version inside is missing, the same, or newer than the index. An older Version is refused, so a stale copy is not recorded as the current package. A package zip packed inside the downloaded file is used the same way. A file that is a different package is refused. The checksum tells you the file arrived intact. It does not tell you the publisher is honest.
Versions compare by dotted numbers. 1.10 is newer than 1.9. 1 and 1.0 are the same. The Installed screen shows the Version line from the package file that was installed, not the version printed in an index that did not match that file.
Hosting a repo
Put Packages and the pool/ folder on any plain web server. In Sources, add the directory address, for example http://192.168.1.20/rg34. The app requests Packages under that directory, then each Filename.
Use http:// or https://. file:// is refused. The User-Agent is RG34Jailbreak/1.0. HTTPS tries the bundled certificate file, then opens once without checking the certificate if the console clock or CA store is wrong. If the console DNS cannot resolve the name, Selium asks 1.1.1.1 and then 8.8.8.8, and connects to that address while keeping the original host name. A printed line says Certificate check failed, opening anyway. HTTP 403 stays an error. The app does not switch to a browser identity, and it does not send cookies.
Redirects are followed only when the final address is still http or https. An index may be up to 2 MB. A package zip may be up to 64 MB.
makerepo.py
After you edit a package folder inside jailbreak/examples/, rebuild the index on Windows, Mac, or Linux. Open a terminal in that jailbreak folder.
Windows
cd path\to\jailbreak py -3 makerepo.py
Mac
cd path/to/jailbreak python3 makerepo.py
Linux
cd path/to/jailbreak python3 makerepo.py
The script walks each example, writes repo/pool/<id>.zip, and rewrites repo/Packages with Size, MD5sum, and Filename. Copy the updated jailbreak folder to the card when you want the console to see the new packages. The console does not run makerepo.py. The tweak tool exports one package without this script.
Safety and limits
- Only add repos you trust. Tweaks run as normal Python.
- A package may hold 200 payload files and 64 MB unpacked.
- Downloads use 64 KB reads. An oversized body is discarded.
- Page and index requests wait 20 seconds. A package zip waits 30 seconds.
- The app does not ship remote repos, ROM catalogs, or links to other people's software.
- Device Python is 3.9 with no pip. The app uses the standard library only.
- The RG34XX screen is 720 by 480. The RG35XXSP screen is 640 by 480. SDL is used when it is present. Otherwise the app writes
/dev/fb0, then/dev/fb1.
Updating
Before you replace Roms/APPS/jailbreak, copy these two files somewhere safe:
jailbreak/state/installed.jsonjailbreak/state/sources.txt
Copy the new Jailbreak.sh, jailbreak/, and icon over the old ones, then put those two files back. installed.json is the list the app removes from. If it is replaced with an empty file, the files already on the card stay, but the app no longer knows they belong to a package.
Leave state/bootstrapped in place. The built-in repo has no Essential package, so a missing flag does not install one by itself.
Self-test
From the app folder on Windows, Mac, or Linux:
Windows
cd path\to\jailbreak py -3 main.py --self-test
Mac and Linux
cd path/to/jailbreak python3 main.py --self-test
The test checks package parsing, version order, zip paths that try to leave the card, launcher wrap and restore, the GIF background package, a repo served on 127.0.0.1, the Up direction, and one pixel of the home screen. It does not open a screen device and it does not contact archive.org. A good run prints jailbreak self-test ok.