f3f7442849
release / build (push) Failing after 0s
(semver drives Android versionCode/versionName and package.json). The build-image/ Dockerfile pins the same toolchain for a portable, containerized Gitea Actions runner (build-image.sh builds and pushes it) so releases don't depend on any one machine's local setup. Pushing vX.Y.Z now builds and publishes a Gitea Release automatically.
178 lines
6.8 KiB
Markdown
178 lines
6.8 KiB
Markdown
<p align="center">
|
||
<img src="SchwertUndMagieOnPebbleCompanionApp/res/app-icon-round.png" width="290" alt="App icon">
|
||
</p>
|
||
|
||
# Schwert und Magie on Pebble
|
||
|
||
A port of the classic German C64 text-adventure RPG series **Schwert und Magie**
|
||
(German Design Group, 1989–1992) to the Pebble Time 2 smartwatch.
|
||
|
||
## Architecture
|
||
|
||
The phone runs VICE 3.8 as a companion app and streams the C64 text screen to
|
||
the watch. Button presses on the watch flow back to VICE via Bluetooth.
|
||
|
||

|
||
|
||
## The game
|
||
|
||
*Schwert und Magie* is an 8-episode text-adventure / RPG series for the
|
||
Commodore 64, published in German by boeder-Verlag. Two episodes share one
|
||
disk:
|
||
|
||
| Disk | Episodes |
|
||
|------|----------|
|
||
| I | Folge 1: Das geheimnisvolle Kraut · Folge 2: Der unheimliche Tempel |
|
||
| II | Folge 3: Das Piratenhaus · Folge 4: Die Burg des Magiers |
|
||
| III | Folge 5: Das Haus des Vampirs · Folge 6: Der Turm des Todes |
|
||
| IV | Folge 7: Unter Wasser · Folge 8: Insel der Wunder |
|
||
|
||
The copy-protection scheme asks for a word from the printed *Anleitung*
|
||
(manual). The app includes the full manual text with a look-up button (📖) so
|
||
you can answer the prompt without keeping the paper around.
|
||
|
||
## Repository layout
|
||
|
||
```
|
||
SchwertUndMagieOnPebbleWatchApp/ Pebble watchapp (C + PebbleKit JS)
|
||
SchwertUndMagieOnPebbleCompanionApp/ Android companion app (Kotlin + NDK)
|
||
versions/ Original .d64 disk images (4 disks)
|
||
docs/ Architecture notes and diagrams
|
||
build-image/ Dockerfile for the release build environment
|
||
dist/ Build artifacts (gitignored) — see dist.sh
|
||
```
|
||
|
||
Run `./dist.sh` to build release artifacts for both apps in one step:
|
||
`dist/schwert-und-magie-<version>.{aab,apk,pbw}` — the signed Android AAB
|
||
(Play Store), APK (sideload), and Pebble `.pbw` (Rebble / direct install).
|
||
Requires the Android release keystore to already be configured
|
||
(`docs/publish.md` §2.1-2.3). The version comes from the current git tag by
|
||
default (`git tag v1.2.3`); see `docs/publish.md` §4 for pushing that tag to
|
||
trigger an automated, containerized build via Gitea Actions instead.
|
||
|
||
## How it works
|
||
|
||
Three processes cooperate across two devices:
|
||
|
||
```
|
||
Pebble watch
|
||
│ Bluetooth AppMessage
|
||
▼
|
||
Core for Pebble (on phone) — PebbleKit JS bridge
|
||
│ HTTP on 127.0.0.1:8888
|
||
▼
|
||
Android companion app — NanoHTTPD server
|
||
│ JNI
|
||
▼
|
||
VICE 3.8 (C64 emulator, cross-compiled for ARM64/x86_64)
|
||
```
|
||
|
||
The watch displays the C64 text screen (40×25 cells) in a scroll view and
|
||
provides a key wheel for the number keys most used by the game. The companion
|
||
app renders VICE's 320×200 framebuffer on-screen and also provides a virtual
|
||
C64 keyboard for direct input.
|
||
|
||
See [`docs/architecture.md`](docs/architecture.md) for the full design.
|
||
|
||
## Requirements
|
||
|
||
- **Android phone** running Android 7.0+ (API 24)
|
||
- **Pebble Time 2** (or any Pebble running firmware 3.x — the `.pbw` targets
|
||
all SDK 3 platforms)
|
||
- **Core for Pebble** installed on the phone (the community Pebble app)
|
||
- **C64 ROM files** — `kernal`, `basic`, `chargen`, `1541` — legally obtained
|
||
from your own C64 or from Cloanto's C64 Forever. The app prompts you to
|
||
import them on first launch; they are never bundled.
|
||
- **Disk images** — `.d64` or `.g64` files for the four game disks. You can
|
||
import your own or use the in-app **Fetch Disks** button to download
|
||
community-preserved dumps from the Internet Archive's C64 Preservation
|
||
Project (requires nibtools, which is cross-compiled automatically).
|
||
|
||
## Building
|
||
|
||
### Android companion app
|
||
|
||
```bash
|
||
cd SchwertUndMagieOnPebbleCompanionApp
|
||
./gradlew assembleDebug # debug build
|
||
./gradlew assembleRelease # signed release build (requires keystore.properties)
|
||
./gradlew installDebug # build + install on connected device
|
||
```
|
||
|
||
VICE 3.8 and nibtools are cross-compiled automatically the first time — the
|
||
Gradle `buildVice` and `buildNibtools` tasks unpack the source tarballs from
|
||
`res/` and build `libvice.a` / `libnibtools.a` for ARM64 and x86_64. The NDK
|
||
must be installed (Android Studio → SDK Manager → SDK Tools → NDK (Side by
|
||
side)).
|
||
|
||
### Pebble watch app
|
||
|
||
```bash
|
||
cd SchwertUndMagieOnPebbleWatchApp
|
||
pebble build
|
||
pebble install --phone <phone-ip>
|
||
```
|
||
|
||
In headless / CI environments add `--vnc` to every emulator command.
|
||
|
||
## Getting disk images onto the device
|
||
|
||
**Option A — Fetch Disks button** (in-app)
|
||
Opens a dialog, downloads all 8 episode disks as `.nbz` files from the
|
||
Internet Archive C64 Preservation Project, and converts them to G64 using
|
||
nibtools. Requires a network connection; conversion runs on-device.
|
||
|
||
**Option B — manual copy**
|
||
Copy `.d64` or `.g64` files to the app's external files directory via USB or
|
||
`adb push`, matching the names expected by the drawer (e.g. `SCHWUM1A.D64`).
|
||
|
||
## Hero saves
|
||
|
||
Hero characters are stored on separate hero disks (up to 3 slots). The app
|
||
manages these from the drawer — create a new hero disk, load an episode disk,
|
||
then swap to the hero disk when the game asks for it. A built-in stat editor
|
||
lets you inspect and edit a saved hero's attributes directly.
|
||
|
||
## Save states
|
||
|
||
The 💾 button saves or restores a full VICE snapshot (CPU registers, RAM,
|
||
VICII, SID, CIA) to one of three slots. Snapshots go through a CPU trap to
|
||
ensure register consistency — see `docs/architecture.md §4.4`.
|
||
|
||
## Publishing
|
||
|
||
See [`docs/publish.md`](docs/publish.md) for keystore setup, Google Play,
|
||
F-Droid, and Rebble submission.
|
||
|
||
### Automated releases (Gitea Actions)
|
||
|
||
Pushing a tag `vX.Y.Z` builds both apps in a containerized runner and
|
||
publishes a Gitea Release with the versioned artifacts attached — see
|
||
`docs/publish.md` §4. One-time setup:
|
||
|
||
1. Build and push the build environment image (`./build-image.sh`, needs
|
||
`registry.env` — copy from `registry.env.example`).
|
||
2. Register a self-hosted `act_runner` with a Docker executor.
|
||
3. Add repo secrets under **Settings → Actions → Secrets**:
|
||
|
||
| Secret | Value |
|
||
|---|---|
|
||
| `RELEASE_KEYSTORE_B64` | `base64 -w0 SchwertUndMagieOnPebbleCompanionApp/release.keystore` |
|
||
| `RELEASE_KEYSTORE_PROPERTIES` | full contents of `SchwertUndMagieOnPebbleCompanionApp/keystore.properties` |
|
||
|
||
`GITEA_TOKEN` is injected automatically per job — nothing to add for it.
|
||
4. `git tag v1.2.3 && git push origin v1.2.3`.
|
||
|
||
Full details, including runner registration commands, are in
|
||
`docs/publish.md` §4.
|
||
|
||
## License
|
||
|
||
The watch app and companion app source code in this repository are released
|
||
under the **MIT License**.
|
||
|
||
The *Schwert und Magie* game content (disk images, manual text) remains the
|
||
property of its original authors and is not part of this license. VICE and
|
||
nibtools are GPLv2 and are built from source at compile time; their source
|
||
tarballs in `res/` are not covered by this repository's MIT license.
|