diff --git a/README.md b/README.md index ceb0bd0..6e553f5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,95 @@ -# Dostalgia +# DOSTalgia đŸ•šī¸ -A nostalgic DOS game hub. Upload your old DOS games, scrape artwork, and play them directly in the browser via js-dos (WebAssembly DOSBox). +A nostalgic DOS game hub. Upload your old DOS games, auto-scrape artwork and metadata from IGDB, and play them directly in your browser via js-dos (DOSBox compiled to WebAssembly). + +## Features + +### 🎮 Play in the browser +Every uploaded game is packaged into a `.jsdos` bundle — a standard ZIP with embedded DOSBox configuration. When you hit **Play**, js-dos v8 is loaded from CDN and starts the emulator instantly in your browser. No plugins, no native installs. + +**Save states are automatic** — js-dos persists your game progress to the browser's storage. Come back anytime and pick up where you left off. + +### 📡 IGDB metadata & media +Dostalgia integrates with [IGDB](https://www.igdb.com/) (via Twitch OAuth2) to auto-populate game info: + +- **Auto Scrape** — On upload, Dostalgia searches IGDB by title and fills in year, genre, developer, publisher, description, and cover art. If IGDB finds a DOS result, it prioritises it. +- **Manual Search** — From the game detail page you can search IGDB by any query, browse results with cover thumbnails and DOS badges, and apply the one you want. +- **Media** — Videos (YouTube embeds) and screenshots (1080p) are fetched and displayed in a scrollable media gallery with a preview player. + +Everything degrades gracefully — if Twitch credentials aren't configured, uploads and editing work fine, just without auto-scrape. + +### đŸ“Ļ Handles any file structure +DOS games come in all shapes. Dostalgia handles them transparently: + +- **Flattening** — If your ZIP has a single root directory (e.g. `doom/` with all files inside), the extractor flattens it so the game files sit at the bundle root. No extra nesting. +- **Subdirectory games** — If files are deeper, the autoexec automatically `cd`s to the right directory before launching the executable. +- **CD images** — Games shipped on CD-ROM often need the disc mounted. Dostalgia detects `.iso`, `.cue`, `.img`, `.ccd`, and `.bin` files, fixes broken CloneCD `.cue` references (where the referenced `.bin` is actually `.img`), and mounts them in both `dosbox.conf` and `jsdos.json`. +- **CD-only games** — If the archive contains only CD images with no executable, a CD-only bundle is created that mounts the disc and drops you at the DOS prompt. +- **Hardcoded paths** — `ConfigPatcher` scans game config files for hardcoded absolute paths (e.g. `C:\FALLOUT1\MASTER.DAT`) that broke after flattening, and rewrites them to relative paths. + +### 🔍 Smart executable detection +On upload, Dostalgia scans every `.exe`, `.com`, and `.bat` file and picks the best candidate as the main executable using a scoring system: + +1. **Not an installer** — INSTALL/SETUP/CONFIG executables are deprioritised +2. **DOS executables** — Pure DOS apps are preferred over Windows ones +3. **Larger files** — Bigger executables are more likely to be the game +4. **Shallow depth** — Files closer to the root are preferred +5. **Self-extractor filtering** — PKZIP/PKSFX stubs are filtered out + +All discovered executables are stored and available in the **Edit** page, where you can pick a different one via radio buttons. + +> **âš ī¸ Cache note:** If you change the executable, the `.jsdos` bundle is patched in-place. Your browser may serve a cached version of the old bundle — if the game doesn't launch with the new executable, **hard-refresh** the play page (Ctrl+Shift+R / Cmd+Shift+R). + +### 🛠 One-click Setup launcher +Many DOS games include a `SETUP.EXE`, `INSTALL.EXE`, or `CONFIG.EXE` used to configure sound, controls, and graphics. When Dostalgia detects one: + +- A **🛠 Setup** button appears on the game detail page +- Clicking it launches the setup executable *without modifying the main game bundle* +- The setup bundle is generated **on-the-fly** by the server — a modified `.jsdos` is streamed with the setup executable in the autoexec, then discarded. Nothing is written to disk. + +### đŸĒŸ Windows game detection +DOSBox can't run Windows executables. Dostalgia's `PlatformDetector` reads MZ/PE/NE headers to detect Windows executables: + +- The game detail page shows a **đŸĒŸ Requires Windows 3.1** badge +- The **Play** button is disabled with "Unplayable" text +- If you click Play anyway, a warning overlay explains the limitation with a **Try anyway** fallback +- Setup executables that are Windows-native are also filtered out from the Setup button + +## How it works + +``` + ┌──────────────────────────────────────────┐ + │ Upload ZIP (multipart) │ + └────────────â”Ŧ─────────────────────────────┘ + â–ŧ + ┌──────────────────────────┐ + │ Unzip & flatten dirs │ + │ Fix .cue references │ + │ Fix absolute paths │ + └────────────â”Ŧ─────────────┘ + â–ŧ + ┌──────────────────────────┐ + │ Detect executables │ + │ Detect CD images │ + │ Detect platform (DOS/W) │ + └────────────â”Ŧ─────────────┘ + â–ŧ + ┌──────────────────────────┐ + │ Build .jsdos bundle │ + │ (ZIP + dosbox.conf + │ + │ jsdos.json) │ + └────────────â”Ŧ─────────────┘ + â–ŧ + ┌──────────────────────────┐ + │ Auto-scrape IGDB │ + │ (year, genre, cover, │ + │ videos, screenshots) │ + └────────────â”Ŧ─────────────┘ + â–ŧ + ┌──────────────────────────┐ + │ Save game.json │ + └──────────────────────────┘ +``` ## Quick Start @@ -50,22 +139,27 @@ java -jar target/quarkus-app/quarkus-run.jar ## Architecture -- **Backend**: Quarkus (Java 21, JAX-RS) — ~5 REST resource classes, zero database +- **Backend**: Quarkus (Java 21, JAX-RS) — REST endpoints, zero external database - **Frontend**: Svelte 5 SPA with hash-based routing - **Emulation**: js-dos v8 loaded from CDN, runs DOSBox in WebAssembly - **Storage**: JSON-per-game under `/data/games/{id}/game.json` +- **Saves**: Browser localStorage / indexedDB (managed by js-dos) ## API -| Method | Path | Description | -|--------|------|-------------| -| GET | `/api/games` | List all games | -| GET | `/api/games/:id` | Get game details | -| PATCH | `/api/games/:id` | Update game metadata | -| DELETE | `/api/games/:id` | Delete a game | -| POST | `/api/upload` | Upload a game ZIP (multipart) | -| POST | `/api/games/:id/cover` | Upload cover art | -| GET | `/api/igdb/search?q=` | Search IGDB (placeholder) | +Method | Path | Description +--- | --- | --- +GET | `/api/games` | List all games +GET | `/api/games/:id` | Get game details +PATCH | `/api/games/:id` | Update game metadata +DELETE | `/api/games/:id` | Delete a game +POST | `/api/upload` | Upload a game ZIP (multipart) +POST | `/api/games/:id/cover` | Upload cover art +GET | `/api/games/:id/setup-bundle` | Stream a setup .jsdos bundle (on-the-fly) +GET | `/api/games/:id/download` | Download the game's .jsdos bundle +GET | `/api/igdb/status` | Check if IGDB is configured +GET | `/api/igdb/search?q=` | Search IGDB for a game +POST | `/api/igdb/scrape/:id` | Auto-scrape or apply specific IGDB result ## Game JSON Schema @@ -76,15 +170,28 @@ java -jar target/quarkus-app/quarkus-run.jar "year": 1993, "genre": "FPS", "developer": "id Software", - "bundle_file": "doom.jsdos", + "publisher": "id Software", + "description": "You've signed up for...", + "bundle_file": "doom/doom.jsdos", + "executable": "DOOM.EXE", + "executables": ["DOOM.EXE", "SETUP.EXE"], + "setup_exe": "SETUP.EXE", + "has_setup": true, + "platform": "dos", + "bundle_size": 4194304, "has_cover": true, - "ready": true + "screenshots": ["https://..."], + "videos": ["dQw4w9WgXcQ"], + "igdb_id": 3498, + "ready": true, + "created_at": "2026-05-27T10:00:00Z", + "updated_at": "2026-05-27T10:00:00Z" } ``` ## IGDB Metadata (Optional) -Dostalgia can auto-populate game metadata (year, genre, developer, cover art, screenshots, videos) from the [IGDB](https://www.igdb.com/) database. This requires a Twitch API application. +Dostalgia can auto-populate game metadata (year, genre, developer, publisher, cover art, screenshots, videos) from the [IGDB](https://www.igdb.com/) database. This requires a Twitch API application. **Setup:** @@ -93,10 +200,46 @@ Dostalgia can auto-populate game metadata (year, genre, developer, cover art, sc 3. Copy the **Client ID** and generate a **Client Secret** 4. Provide them via environment variables: -| Method | How | -|--------|-----| -| Docker run | `-e TWITCH_CLIENT_ID=xxx -e TWITCH_CLIENT_SECRET=yyy` | -| Docker Compose | Copy `.env.example` to `.env` and fill in the values | -| Local dev | `export TWITCH_CLIENT_ID=xxx TWITCH_CLIENT_SECRET=yyy` | +Method | How +--- | --- +Docker run | `-e TWITCH_CLIENT_ID=xxx -e TWITCH_CLIENT_SECRET=yyy` +Docker Compose | Copy `.env.example` to `.env` and fill in the values +Local dev | `export TWITCH_CLIENT_ID=xxx TWITCH_CLIENT_SECRET=yyy` IGDB features degrade gracefully — if credentials aren't set, uploads and metadata editing still work, just without auto-scrape. + +## Comparison with RomM + +[RomM](https://www.romm.app/) is a popular ROM manager with web-based emulation. Here's how Dostalgia compares specifically for MS-DOS games: + +| Feature | Dostalgia | RomM | +|---|---|---| +| **Emulator** | js-dos v8 (dedicated DOSBox WebAssembly) | EmulatorJS with dosbox-pure core | +| **Bundle format** | Auto-generated .jsdos with embedded config | Raw ZIP + manual .conf file | +| **Executable detection** | Automatic (smart scoring: depth, size, platform, installer filtering) | Manual — user must type `mount`, `cd`, and `exe` commands or write a .conf | +| **CD mounting** | Automatic — detects .iso/.cue/.img/.ccd/.bin, fixes broken cues, mounts in config | Manual — user must write `imgmount` commands in .conf | +| **Setup executable** | Auto-detected, one-click launch via on-the-fly streaming bundle | Not supported — user must run setup manually from DOS prompt | +| **Windows detection** | PE/NE header analysis, UI badge, disabled play button with fallback | Not supported | +| **IGDB integration** | Yes — auto-scrape, manual search, cover, genre, dev, publisher, videos, screenshots | Not for DOS specifically | +| **Config patching** | Automatic — `ConfigPatcher` rewrites hardcoded `C:\` paths in game configs | Not available | +| **GOG DOS games** | Supported (after flattening + path patching) | Explicitly NOT supported | +| **Database** | None — JSON files per game | PostgreSQL | +| **Upload size** | 2 GB limit | Depends on configuration | +| **Save states** | Yes (browser storage via js-dos) | Yes (via EmulatorJS) | +| **Target audience** | DOS-only, streamlined | Multi-platform, general-purpose | + +**When to use RomM:** If you're managing ROMs across many platforms (NES, SNES, Genesis, PS1, etc.) alongside DOS games. + +**When to use Dostalgia:** If you have a focused DOS collection and want a zero-fuss experience where you upload a ZIP and everything just works — executable detection, CD mounting, metadata, screenshots. + +## Publishing the Docker image + +The Docker image is fully self-contained (Java JAR + static frontend, no database). To publish: + +```bash +docker build -t dostalgia . +docker tag dostalgia ghcr.io/yourname/dostalgia:latest +docker push ghcr.io/yourname/dostalgia:latest +``` + +Secrets are never baked into the image — users provide `TWITCH_CLIENT_ID` / `TWITCH_CLIENT_SECRET` at runtime via environment variables (or skip IGDB entirely).