mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
skins and skin studio
This commit is contained in:
+2
-20
@@ -11,28 +11,10 @@ Features intentionally added beyond the original Pokémon Red, Blue, and Yellow
|
||||
* **Persistent custom options** stored separately from game saves
|
||||
* **Optional widescreen battle layout**
|
||||
* **Mobile touch controls** with editable layouts, vibration, and orientation settings
|
||||
* **Translation and custom font support**
|
||||
* **Built-in save editor** for parties, boxes, items, events, maps, and Pokédex data
|
||||
* **Tiled map editing tools** for mod authors
|
||||
* **Touch skins** in RetroArch overlay format, with bezel art, per-button press states, and Super Game Boy borders
|
||||
* **Pokédex diploma and printer image exports**
|
||||
* **Community mod browser**
|
||||
* **Soft reset button combination**
|
||||
* **Keyboard and controller rebinding**
|
||||
* **Mod profiles** with separate mod settings and save slots
|
||||
* **Sandboxed mods**: an installed mod can read only its own folder and write only its own storage
|
||||
* **Improved launcher and save editor UI**, including background downloads and update checks
|
||||
* **Direct-launch options** for shortcuts, Steam entries, and handheld frontends
|
||||
|
||||
## Pokémon Gold (Gen 2)
|
||||
## Gen 2 Specifics
|
||||
|
||||
* **COLOR, zoom, tilt, GBC FX, and quick save/load**
|
||||
* **UI that stays fixed while the overworld zooms**
|
||||
* **Border-block surrounds** for maps smaller than the screen
|
||||
* **Gold-specific launcher options**
|
||||
* **Optional widescreen battle layout**
|
||||
* **Skippable trade animation** with B or START
|
||||
* **QUIT and EXIT GAME** from the menus
|
||||
* **Mod manager** with Gen 1 mod adapters, per-game targeting, and `modkit gen2check`
|
||||
* **Followers** for mods, plus Gen 2-only registries and hooks
|
||||
* **On-screen touch pad** and controller SELECT for registered items
|
||||
* **Older mods keep loading** after the sandbox change, through per-mod compat stand-ins for the pre-sandbox globals
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
# Touch skins and the Skin Studio
|
||||
|
||||
A **skin** replaces the on-screen controls wholesale: a bezel image, a
|
||||
control layout, and the rectangle the Game Boy screen is drawn into. Engine:
|
||||
`src/core/TouchSkin.lua` (model, parsers, zip export), `src/core/TouchControls.lua`
|
||||
(draw and input), `src/render/Renderer.lua` (the screen viewport),
|
||||
`src/ui/SkinStudio.lua` (the desktop editor). Tests:
|
||||
`tests/engine/touch_skin_test.lua`, `tests/engine/skin_studio_test.lua`,
|
||||
`tests/engine/launcher_skins_tab.lua`.
|
||||
|
||||
Skins are picked in the launcher's **Skins** tab, which also imports them and
|
||||
opens the studio. `options.touchControls.skin` holds the folder name.
|
||||
|
||||
## Formats
|
||||
|
||||
Two load. `skin.lua` wins when a folder has both.
|
||||
|
||||
**RetroArch overlay `.cfg`.** The libretro `common-overlays` collection loads
|
||||
as-is. Supported keys:
|
||||
|
||||
| Key | Meaning |
|
||||
| --- | --- |
|
||||
| `overlays` | page count |
|
||||
| `overlayN_name` | page name, the target of `next_target` |
|
||||
| `overlayN_overlay` | bezel image |
|
||||
| `overlayN_full_screen` | stretch the page to the window |
|
||||
| `overlayN_rect` | page placement, default `0,0,1,1` |
|
||||
| `overlayN_aspect_ratio` | fallback aspect when not full screen |
|
||||
| `overlayN_range_mod`, `overlayN_alpha_mod` | desc defaults |
|
||||
| `overlayN_viewport` | `x,y,w,h`, the screen cutout |
|
||||
| `overlayN_viewport_fill` | parsed; the engine always fits, see below |
|
||||
| `overlayN_descM` | `binds,x,y,shape,range_x,range_y` |
|
||||
| `overlayN_descM_overlay` | control art |
|
||||
| `overlayN_descM_next_target` | page to switch to |
|
||||
| `overlayN_descM_range_mod`, `_alpha_mod` | per-control overrides |
|
||||
| `overlayN_descM_reach_x/_y/_up/_down/_left/_right` | hitbox reach |
|
||||
|
||||
`x,y` is the centre and `range_x,range_y` are half extents, both normalized.
|
||||
Hitboxes are `radial` or `rect`. Pipe-separated binds (`left|down`) are one
|
||||
control that holds both. A `nul` desc is decoration: it draws and never
|
||||
captures a touch.
|
||||
|
||||
Alpha follows RetroArch (`input_driver.c`, `input_overlay_post_poll`): every
|
||||
image sits at the overlay opacity, and a pressed control's image swaps to
|
||||
`opacity * alpha_mod`. So `alpha_mod` above 1 lights a control up and below 1
|
||||
fades it out, and both directions read as a press animation.
|
||||
|
||||
**Native `skin.lua`.** This module's own model written back out: one Lua
|
||||
table, no flat key space, and a separate `imagePressed` per control that a
|
||||
`.cfg` cannot express. Loaded with an empty environment, so a skin authored by
|
||||
a stranger cannot reach `love` or `io`. Sizes here are full width and height
|
||||
rather than RetroArch's half extents, because that is what an editor's numeric
|
||||
fields mean.
|
||||
|
||||
```lua
|
||||
return {
|
||||
name = "my_skin",
|
||||
pages = {
|
||||
{
|
||||
name = "main",
|
||||
image = "img/bezel.png",
|
||||
fullScreen = true,
|
||||
viewport = { x = 0.0, y = 0.0, w = 1.0, h = 0.5, fill = false },
|
||||
controls = {
|
||||
{ bind = "a", x = 0.87, y = 0.72, w = 0.18, h = 0.10,
|
||||
shape = "radial", image = "img/a.png", imagePressed = "img/a_down.png" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Bindable actions
|
||||
|
||||
The eight Game Boy buttons: `a`, `b`, `start`, `select`, `up`, `down`,
|
||||
`left`, `right`.
|
||||
|
||||
Engine hotkeys, handled in `Game:touchSkinHotkey`:
|
||||
|
||||
| Bind | Effect |
|
||||
| --- | --- |
|
||||
| `overlay_next`, `overlay_previous` | switch page, honouring `next_target` |
|
||||
| `hold_fast_forward`, `fast_forward` | fast forward while held |
|
||||
| `toggle_fast_forward` | step the speed option |
|
||||
| `reset` | soft reset to the title |
|
||||
| `menu_toggle` | open OPTIONS |
|
||||
|
||||
`screenshot`, `pause_toggle` and `exit_emulator` are recognised but have no
|
||||
handler yet: a control bound to them draws and does nothing. Anything else,
|
||||
`rewind` included, is not in the bind table at all, so the control falls back
|
||||
to decoration and never captures a touch.
|
||||
|
||||
As an extension to the format, `key:<name>` presses any keyboard key, which is
|
||||
how a skin button reaches a mod hotkey.
|
||||
|
||||
## The screen viewport
|
||||
|
||||
`overlayN_viewport` is the cutout the picture is fitted into. The Game Boy
|
||||
screen keeps its whole-pixel scale and letterboxes inside that rect rather than
|
||||
stretching to it, so a bezel gets an exact 160x144 picture; `viewport_fill` is
|
||||
parsed but does not stretch. `overlayN_viewport_expand = true` is an extension
|
||||
that lets a widescreen bezel take the filling survey-zoom world view instead.
|
||||
|
||||
A viewport also implies the faithful-ratio lock. Without it the world pass
|
||||
expands to fill the cutout and you get more map instead of a Game Boy screen.
|
||||
|
||||
Border art often ships with a transparent hole and no `viewport` key. **Detect
|
||||
screen from bezel** in the studio measures the hole out of the art's alpha
|
||||
channel and writes the rect.
|
||||
|
||||
## Bezels versus pads
|
||||
|
||||
A skin whose active page binds nothing is a frame rather than a pad: a TV
|
||||
surround, a handheld shell, a Super Game Boy border. Those draw on **desktop**
|
||||
as well, where the touch overlay itself does not, and a gamepad does not hide
|
||||
them. Anything that binds a button still follows the usual mobile /
|
||||
`POKEPORT_TOUCH` rule.
|
||||
|
||||
## Installing
|
||||
|
||||
Drop a folder or a `.zip` into `skins/` in the save directory, or drop a zip on
|
||||
the launcher window while the Skins tab is open. A zip is mounted in place, so
|
||||
there is nothing to unpack. The folder needs one `skin.lua` or `.cfg`
|
||||
(`overlay.cfg` is preferred when there are several) and the images it names.
|
||||
|
||||
Two ship bundled, both from libretro's `common-overlays` under CC-BY-4.0:
|
||||
|
||||
| Skin | Source | Shape |
|
||||
| --- | --- | --- |
|
||||
| `gb_anim` | `gamepads/gb_anim_portrait` | handheld shell, working buttons, two pages |
|
||||
| `tv_crt` | `borders/tv-integer` | CRT television frame, no buttons |
|
||||
|
||||
Attribution lives in each folder's `README.md`. `tv_crt` is a photograph of a
|
||||
real television: CC-BY-4.0 upstream, but treat it as a test asset rather than
|
||||
shipping branding.
|
||||
|
||||
## The studio
|
||||
|
||||
Launcher, Skins tab, **Open Skin Studio**, or the gear on any skin row to open
|
||||
that skin. Desktop only: the launcher does not offer it on Android or iOS,
|
||||
because it wants a mouse, typed coordinates and room for an inspector.
|
||||
|
||||
**Canvas.** A mock device at a chosen preset, so a phone skin is authored at
|
||||
phone proportions on a desktop monitor.
|
||||
|
||||
| Preset | Size |
|
||||
| --- | --- |
|
||||
| Phone portrait / landscape | 1080x1920, 1920x1080 |
|
||||
| Tablet portrait / landscape | 1536x2048, 2048x1536 |
|
||||
| Steam Deck | 1280x800 |
|
||||
| Desktop 1080p | 1920x1080 |
|
||||
| Ultrawide 21:9 | 2560x1080 |
|
||||
| Super Game Boy border | 256x224 |
|
||||
|
||||
The Super Game Boy preset locks the viewport to the real screen window,
|
||||
160x144 at (48,40), so an SGB border cannot be drawn out of register.
|
||||
|
||||
**Editing.** Click a control to select it, drag to move, eight handles to
|
||||
resize. X / Y / W / H are in canvas pixels, so a control can be typed to the
|
||||
coordinate its art was drawn at. Bind, hitbox shape, hit reach and idle and
|
||||
pressed images are per control; the bezel, the pages and the screen cutout are
|
||||
per page. The cutout is itself a draggable element with a 10:9 lock. Drop a PNG
|
||||
or JPG on the window to import art into the skin.
|
||||
|
||||
**Testing.** **Test** makes the canvas live: clicking presses real Game Boy
|
||||
buttons and the footer reports what is held. **Play** saves the skin, selects
|
||||
it, and boots the game with it.
|
||||
|
||||
**Saving.** **Save** writes `skins/<name>/skin.lua` and copies every image the
|
||||
skin names, so the folder stands alone. **Export** packs it as one zip
|
||||
(`src/core/SkinZip.lua`, store-only) carrying the native `skin.lua`, the
|
||||
images, and the original `.cfg` when it came from one. An exported skin drops
|
||||
straight back into `skins/` and still opens in RetroArch.
|
||||
|
||||
## Not implemented
|
||||
|
||||
RetroArch's `analog_*`, `dpad_area`, `abxy_area` and `retrok_*` desc types.
|
||||
Image assignment cycles through art already in the skin folder; there is no
|
||||
file browser, so new art arrives by drag and drop.
|
||||
Reference in New Issue
Block a user