aboutsummaryrefslogtreecommitdiffstats
path: root/SL0P.md
blob: 28c2df168518478dd8f129e57d48fccdd36648a2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# POKéMON SL0P EDITION

A cheeky romhack of Pokémon Yellow, built on the [pret/pokeyellow](https://github.com/pret/pokeyellow)
disassembly. All the mods live in a handful of files and are toggled/used
entirely in-game — no external cheat device.

## Features

### ⚡ Fastboot
If a save exists, the game skips the GameFreak intro, the title screen, and the
CONTINUE menu, and drops you straight into your save. (New game still shows the
normal flow.)
- `home/init.asm` / `engine/movie/intro.asm` — skip the intro
- `engine/movie/title.asm` — skip the title
- `engine/menus/main_menu.asm` — autoload + splash

### 🎬 Custom intro splash
A brief **POKéMON / SL0P / EDITION** graphic (a real 2bpp image, not text) is
shown for ~2s on boot.
- `engine/slop_intro.asm` + `gfx/slop/intro.png` (built with a custom rgbgfx
  Makefile rule → deduped tiles + tilemap)

### 🎛️ SL0P MENU — press **SELECT** in the overworld
A table-driven cheat menu. Cursor + A to pick, B to back out / close.

| Entry | Effect |
|-------|--------|
| **WARP** | submenu: fly-warp to any of 13 destinations (all towns + Route 4/10) |
| **HEAL** | full HP + clear status for the whole party |
| **MONEY** | ¥999,999 |
| **COINS** | 9,999 game-corner coins |
| **BADGES** | all 8 gym badges |
| **DEX** | mark every Pokémon owned + seen |
| **MAXTEAM** | whole party → Lv100, perfect DVs, maxed EVs, 999 stats/HP |
| **TEACH** | give every party member Hyper Beam / Earthquake / Ice Beam / Thunderbolt |
| **HMS** | give all five HMs (Cut/Fly/Surf/Strength/Flash) |
| **ITEMS** | submenu: give ×99 of balls, Rare Candy, Full Restore, Max Revive, Max Elixer, PP Up, and all five evolution stones |
| **NOWILD** | toggle wild encounters off (shows `ON`) |
| **REPEL** | refill repel steps |
| **EXPLORE** | a screen-paging overworld camera: each d-pad press smooth-scrolls the next screenful of the world (no walking), gliding across the connected map at each edge. **▲▼◀▶ arrows** show which directions you can move; **A** warps the player onto the tile you're looking at; **B** returns to the menu. |
| **SAVER** | screensaver: EXPLORE on autopilot. Drifts the camera across the overworld on its own (persistent direction, DFS-ish: keeps going, turns when blocked or occasionally at a junction). Arrows and the player/Pikachu sprites are hidden. Any button wakes it back to the menu. |

Everything is in `engine/slop_menu.asm`. Adding a new entry = add a name to
`SlopMenuText`, a `dw Handler` to `SlopMenuHandlers`, and bump `SLOP_MENU_COUNT`.
Handlers return carry set (a warp/exit was started) or clear (back to the menu),
and can be submenus or one-shot actions.

Persistent flags (reused unused WRAM): `wUnusedFlag` (NOWILD),
`wUnusedCreditsByte` aliased as `wSlopSaverDir` (screensaver: 0 = off, else the
current auto-scroll `PAD_*` direction).

**EXPLORE** is a self-contained camera loop in `engine/slop_menu.asm`. It renders
straight out of the map block buffer (`wOverworldMap`): compute a view pointer
`wOverworldMap + (by+1)*stride + bx` (by/bx = player block, stride = width+6),
`LoadCurrentMapView`, push to VRAM, OBJ off. A d-pad press moves the camera coords
by ~one screen (`SLOP_PAGE_X/Y`). Movement is a real hardware smooth-scroll built
on the walk engine's own machinery: `SlopScroll{Up,Down,Left,Right}` ramp
`hSCX/hSCY` `SLOP_SCROLL_PX` px/frame, advance `wMapViewVRAMPointer`, and inject
the newly exposed edge with the `Schedule*Redraw` helpers (applied in VBlank). At
a map edge it smooth-scrolls the remaining distance up to the boundary, then
crosses using that connection's `*Alignment` offset and `LoadMapData`s the
neighbour (one unavoidable load), or stops if there's no connection.

**SAVER** is the same loop with `wSlopSaverDir` set: instead of reading the
d-pad, `SlopSaverPickDir` synthesises a direction into the normal dispatch (so it
inherits smooth scroll + edge crossing), keeping a persistent heading and only
turning when blocked or occasionally at a junction (never an immediate U-turn).
Arrows are skipped, and OAM is cleared + frozen right after every `LoadMapData`
so the reloaded player/Pikachu are never drawn. Any real button exits.

- **Direction arrows** are 4 OBJ sprites in `wShadowOAM` using the font's down/
  right glyphs (`$ee`/`$ed`) plus CGB OBJ X/Y-flip for up/left; set
  `wUpdateSpritesEnabled=$ff` after building them so the vblank `PrepareOAMData`
  leaves shadow OAM alone. Shown per-direction when a move is possible.
- **A warps here:** scans `wTileMap` outward from the view centre (col 8,row 9)
  for the nearest `IsTilePassable` tile, sets `wYCoord/wXCoord`, `wDestinationWarpID=$ff`,
  `LoadMapData` (enters at those coords), returns carry set.

See `~/dev/gbc/tools/render_overworld.py` for the ground-truth map that proved
connections join maps along shared edges with an offset -- the same math this
camera uses to cross seams.

## Build

```sh
make            # -> pokeyellow.gbc  (rgbds 1.0.1)
```

The build is reproducible; the intro graphic regenerates from `gfx/slop/intro.png`.