Skip to content
Merged
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
49 changes: 49 additions & 0 deletions ports/scavengerofdunomini/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Match-3 trash pile defender by PUNKCAKE Delicieux. You're a scavenger
droid bound to a trash pit — organize tiles with per-type matching
rules, recycle trash into automated defenses, and keep rival
scavengers from stealing your pile. Single-player plus couch co-op /
versus, 10-30 minute runs.

## Thank You
Thanks again to PUNKCAKE Delicieux for such a fun little handheld
diversion. Also thanks to the Darling project for the basis of the
machismo loader.

## Installation
You'll need a legitimate Mac build of the game.

### itch.io
1. Buy Scavenger of Dunomini on [itch.io](https://punkcake.itch.io/scavenger-of-dunomini)
2. From your itch library (or the itch desktop app), download the **macOS** build. You'll get a `.zip` containing `scavenger_of_dunomini.app`.
3. Unzip and drop `scavenger_of_dunomini.app` into the port's `gamedata/` directory

### Steam
1. Buy Scavenger of Dunomini on [Steam](https://store.steampowered.com/app/2320410/Scavenger_of_Dunomini/).
2. Open the Steam console by entering `steam://open/console` in your browser, then run:
```
download_depot 2320410 2320412
```
Steam will print the path where files were saved.
3. Place the game's `.app` bundle in the port's `gamedata/` directory:

## How to Play
Defend your trash pile in a match-3 where every tile type has its own rule. Pick tiles up, carry them around, and group them to recycle into resources. Spend resources from the construction menu to build turrets and upgrades. Meanwhile rival scavengers raid the pile to steal tiles and escape; kick or block them.
Keep the pile below the red laser line at the top. Run ends when your 3hp are exhausted.

## Controls
```
| Pad | Action |
|-------------------------|--------------------------------------|
| D-pad Left / Right | Move your Scavenger |
| D-pad Down | Pick up the tile under you |
| D-pad Up (holding tile) | Drop tile beneath you |
| D-pad Up (empty-handed) | Open construction menu |
| A | Pick up a tile next to you / toss it |
| X | Kick (wall-jump while climbing) |
```

## Technical Details
This port uses [Machismo](https://github.com/bmdhacks/machismo) to load the arm64 Mach-O binary on aarch64 Linux.

## License
The Machismo loader is licensed under GPL v3.0. Game assets are proprietary and must be purchased from itch.io or Steam.
74 changes: 74 additions & 0 deletions ports/scavengerofdunomini/Scavenger of Dunomini.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash

XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}

if [ -d "/opt/system/Tools/PortMaster/" ]; then
controlfolder="/opt/system/Tools/PortMaster"
elif [ -d "/opt/tools/PortMaster/" ]; then
controlfolder="/opt/tools/PortMaster"
elif [ -d "$XDG_DATA_HOME/PortMaster/" ]; then
controlfolder="$XDG_DATA_HOME/PortMaster"
else
controlfolder="/roms/ports/PortMaster"
fi

source $controlfolder/control.txt
[ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt"
get_controls

# Variables
GAMEDIR="/$directory/ports/scavengerofdunomini"
BINARY="gamedata/scavenger_of_dunomini.app/Contents/MacOS/scavenger_of_dunomini"

# Check for game files
if [ ! -f "$GAMEDIR/$BINARY" ]; then
pm_message "Game files not found. See README.md for installation instructions."
sleep 15
exit 1
fi

cd "$GAMEDIR"
> "$GAMEDIR/log.txt" && exec > >(tee "$GAMEDIR/log.txt") 2>&1

# Redirect game save data to port directory
mkdir -p "$GAMEDIR/userdata"

# Display loading splash while game initializes
[ "$CFW_NAME" == "muOS" ] && $ESUDO "$GAMEDIR/tools/splash" "$GAMEDIR/splash.png" 1
$ESUDO "$GAMEDIR/tools/splash" "$GAMEDIR/splash.png" 8000 &

# Run game via machismo (Mach-O loader)
# Scavenger of Dunomini has native SDL2 gamepad support — gptokeyb runs without an
# .ini so it only provides the PortMaster hotkey/exit combo; all other pad
# input passes through to SDL.
# gl4es is loaded with DEFERRED: in dylib_map — machismo defers the dlopen
# until SDL_GL_CreateContext, when a valid EGL display exists on KMSDRM.
#
# ROCKNIX ships Mesa with Panfrost (real desktop GL) and gl4es's FPE path
# crashes in sugar::gfx::_shader_flip during the engine boot_anim. Use the
# Mesa dylib_map on that CFW, and drop the `shaderless` game arg so the
# engine can compile its real shaders.
if [ "$CFW_NAME" = "ROCKNIX" ]; then
MACHISMO_CONF="$GAMEDIR/conf/machismo_mesa.conf"
GAME_ARGS=""
else
MACHISMO_CONF="$GAMEDIR/conf/machismo.conf"
GAME_ARGS="shaderless"
fi

$GPTOKEYB "machismo" &
pm_platform_helper "$GAMEDIR/bin/machismo" > /dev/null
$ESUDO env \
SDL_GAMEPADMAPPINGS="$sdl_controllerconfig" \
LD_LIBRARY_PATH="$GAMEDIR/libs:${LD_LIBRARY_PATH:-}" \
MACHISMO_CONFIG="$MACHISMO_CONF" \
MACHISMO_HOME="$GAMEDIR/userdata" \
XDG_DATA_HOME="$GAMEDIR/userdata" \
XDG_CONFIG_HOME="$GAMEDIR/userdata" \
MESA_NO_ERROR=1 \
LIBGL_GL=32 \
LIBGL_ES=2 \
LIBGL_NOERROR=1 \
"$GAMEDIR/bin/machismo" "$BINARY" $GAME_ARGS

pm_finish
Binary file added ports/scavengerofdunomini/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions ports/scavengerofdunomini/gameinfo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<gameList>
<game>
<path>./Scavenger of Dunomini.sh</path>
<name>Scavenger of Dunomini</name>
<desc></desc>
<image>./scavengerofdunomini/cover.png</image>
<releasedate>20211222</releasedate>
<developer>PUNKCAKE Délicieux</developer>
<genre>Puzzle, Arcade</genre>
</game>
</gameList>
45 changes: 45 additions & 0 deletions ports/scavengerofdunomini/port.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"version": 4,
"name": "scavengerofdunomini.zip",
"items": [
"Scavenger of Dunomini.sh",
"scavengerofdunomini"
],
"items_opt": [],
"attr": {
"title": "Scavenger of Dunomini",
"porter": [
"bmdhacks"
],
"desc": "Wall-E meets tetris meets tower-defense game. Match tiles, build resources, defend your trash pile!",
"desc_md": null,
"inst": "Requires MAC game files from itch.io or Steam. See README.md for install instructions.",
"inst_md": null,
"genres": [
"arcade",
"puzzle"
],
"image": null,
"rtr": false,
"exp": false,
"runtime": [],
"store": [
{
"name": "itch.io",
"gameurl": "https://punkcake.itch.io/scavenger-of-dunomini",
"developerurl": "https://punkcake.itch.io/"
},
{
"name": "Steam",
"gameurl": "https://store.steampowered.com/app/2320410/Scavenger_of_Dunomini/",
"developerurl": "https://punkcake.itch.io/"
}
],
"availability": "paid",
"reqs": [],
"arch": [
"aarch64"
],
"min_glibc": ""
}
}
88 changes: 88 additions & 0 deletions ports/scavengerofdunomini/scavengerofdunomini/BUILDING.txt

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build check wasn't happy with this BUILDING.md file. Perhaps renaming it to .txt and/or moving it into the game's subfolder (ports/scavengerofduomini/scavengerofduomini/BUILDING.md) will do the trick.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I saw the build failure, I will get to it shortly when I get home

Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Building the Scavenger of Dunomini Port

The port ships pre-built aarch64 Linux binaries. These must be built on a
**Debian Bullseye (11)** aarch64 system (or chroot) for glibc compatibility
with handheld Linux distributions (ArkOS, ROCKNIX, etc.).

## Prerequisites

### Bullseye chroot setup

If you don't have a native Bullseye aarch64 system, create a chroot:

```bash
sudo debootstrap --arch=arm64 bullseye /path/to/chroot
sudo chroot /path/to/chroot
```

### Build dependencies

Inside the chroot, install:

```bash
apt-get update
apt-get install build-essential cmake ninja-build clang git \
libsdl2-dev libfreetype-dev libluajit-5.1-dev \
libegl-dev libgles-dev
```

## Build steps

### 1. machismo + libsystem_shim.so + libsugar_patches.so

```bash
cd machismo/build && cmake -S .. -B . && make
```

Output: `machismo`, `libsystem_shim.so`, `libsugar_patches.so`

### 2. Apple-ABI libc++

```bash
cd machismo && ./scripts/build-libcxx.sh
cd build-libcxx && ninja cxx cxxabi
```

Output: `build-libcxx/lib/libc++.so.1`, `build-libcxx/lib/libc++abi.so.1`

### 3. LuaJIT

```bash
cd machismo && ./scripts/build-luajit.sh
```

Output: `build-luajit/lib/libluajit-5.1.so.2`

### 4. gl4es

```bash
cd machismo && ./scripts/build-gl4es.sh
```

Output: `build-gl4es/gl4es/lib/libGL.so.1`

## Packaging

```bash
DEST=/path/to/port/scavengerofdunomini

# Loader
cp machismo/build/machismo "$DEST/bin/"

# Libraries
cp machismo/build/libsystem_shim.so "$DEST/libs/"
cp machismo/build/libsugar_patches.so "$DEST/libs/"
cp machismo/build-libcxx/lib/libc++.so.1 "$DEST/libs/"
cp machismo/build-libcxx/lib/libc++abi.so.1 "$DEST/libs/"
cp machismo/build-luajit/lib/libluajit-5.1.so.2 "$DEST/libs/"
cp machismo/build-gl4es/gl4es/lib/libGL.so.1 "$DEST/libs/libgl4es.so.1"
```

### Repackage zip

```bash
cd port
rm -f scavengerofdunomini.zip
zip -r scavengerofdunomini.zip scavengerofdunomini/ "The Scavenger of Dunomini.sh" \
-x "scavengerofdunomini/gamedata/*" "scavengerofdunomini/userdata/*"
```
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Sugar engine dylib mappings — SDL2 version (Scavenger of Dunomini)
#
# Paths relative to CWD (port directory).

# System shims
libSystem.B = libs/libsystem_shim.so

# Apple-ABI libc++ (alternate SSO + Darwin pthread padding)
libc++.1 = libs/libc++.so.1

# SDL2 — native Linux SDL2 (same C ABI as macOS build)
libSDL2-2.0.0 = libSDL2-2.0.so.0
libfreetype.6 = libfreetype.so.6

# OpenGL — gl4es (GLES 2.0 backend for Mali handhelds)
# DEFERRED: delays dlopen until SDL_GL_CreateContext so gl4es constructor
# finds a valid EGL display (required on KMSDRM).
OpenGL = DEFERRED:libgl4es.so.1

# Steam API — stubbed (return 0/NULL for all calls)
libsteam_api = STUB
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Sugar engine dylib mappings — SDL2, Mesa/Panfrost variant (desktop GL).
#
# Used on devices with real desktop OpenGL (e.g. ROCKNIX on RK3566 via
# Panfrost). gl4es's FPE crashes in sugar::gfx::_shader_flip during boot_anim
# on this engine, and Mesa compiles the engine's shaders directly — so we
# skip the translation layer and also drop the `shaderless` game arg.
#
# Paths relative to CWD (port directory).

# System shims
libSystem.B = libs/libsystem_shim.so

# Apple-ABI libc++ (alternate SSO + Darwin pthread padding)
libc++.1 = libs/libc++.so.1

# SDL2 — native Linux SDL2 (same C ABI as macOS build)
libSDL2-2.0.0 = libSDL2-2.0.so.0
libfreetype.6 = libfreetype.so.6

# OpenGL — system Mesa libGL (Panfrost on Mali-G52).
# DEFERRED: delays dlopen until SDL_GL_CreateContext has a valid display.
OpenGL = DEFERRED:libGL.so.1

# Steam API — stubbed (return 0/NULL for all calls)
libsteam_api = STUB
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Machismo configuration for Scavenger of Dunomini
#
# Paths are relative to CWD (set by launch script to the port directory).

[general]
dylib_map = conf/dylib_map.conf
patches = conf/patches/scavenger-of-dunomini.conf

[trampoline.luajit]
lib = libluajit-5.1.so.2
prefix = _lua

# Sugar engine function replacements — mmap'd PCM cache for _mp3_fromfile.
# Scavenger of Dunomini is SDL2, so no SDL3 _flip override.
# Cache files land in gamedata/scavenger_of_dunomini.app/Contents/MacOS/.machismo-pcm-cache/.
[trampoline.game]
override_lib = libs/libsugar_patches_sdl2.so
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Machismo configuration for Scavenger of Dunomini (Mesa/Panfrost variant).
#
# Used on devices with real desktop OpenGL (e.g. ROCKNIX). Differs from
# machismo.conf only in the dylib_map it points at.
#
# Paths are relative to CWD (set by launch script to the port directory).

[general]
dylib_map = conf/dylib_map_mesa.conf
patches = conf/patches/scavenger-of-dunomini.conf

[trampoline.luajit]
lib = libluajit-5.1.so.2
prefix = _lua

# Sugar engine function replacements — mmap'd PCM cache for _mp3_fromfile.
# Scavenger of Dunomini is SDL2, so no SDL3 _flip override.
# Cache files land in gamedata/scavenger_of_dunomini.app/Contents/MacOS/.machismo-pcm-cache/.
[trampoline.game]
override_lib = libs/libsugar_patches_sdl2.so
Loading
Loading