Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
f0e00ba
fix: adapt the public Gen2 naming screen contract for mods
Roxas2712 Oct 23, 2026
fb22e4a
Publish Gen2 palette row metadata for native atlas renderers
Oct 24, 2026
b3ea11d
Implement native GSC mail and PC core over existing saves
Roxas2712 Oct 25, 2026
a70e34b
Expose the native Gen2 PC menu under its legacy module name
Roxas2712 Oct 25, 2026
7a2efa9
fix: adapt the public Gen2 naming screen contract for mods
Roxas2712 Oct 23, 2026
1077ef9
Connect native GSC PC and mail menus to authoritative transactions
Roxas2712 Oct 25, 2026
0cd5b7a
Run native GSC bedroom decorations through ROM tables, PC and room ca…
Roxas2712 Oct 26, 2026
e49446d
Complete native bedroom acquisition through Mom savings and original …
Roxas2712 Oct 26, 2026
87f6959
Retain native non-trainer phone identity for original Mom purchase calls
Roxas2712 Oct 26, 2026
d0024cd
Expose legacy decoration contracts over native GSC records and room s…
Roxas2712 Oct 26, 2026
4ab09ca
Merge commit 'ed5189c247ee7a2ccca666784e21fd4fba8df781' into codex/up…
Roxas2712 Oct 26, 2026
3b170ce
Expose raw RTC daytime alongside native Gen2 map palette queries
Roxas2712 Oct 26, 2026
f50726a
Share native per-map palettes, roof rules and entered world context
Roxas2712 Oct 26, 2026
75aa131
Use shared native saved RTC for GSC world scripts and clock card
Roxas2712 Oct 26, 2026
d2cfa4d
Include native RTC contract regression in upstream test archive
Roxas2712 Oct 26, 2026
5cd6128
Resolve AUTO neighbour palettes from shared RTC outside pinned scenes
Roxas2712 Oct 26, 2026
a11d4e9
Expose native clock card parts to existing external presenters
Roxas2712 Oct 26, 2026
ccdf628
Add native Pokemon palette queries and typed indexed draw compatibility
Roxas2712 Oct 26, 2026
287f6fa
Expose native palette mode to preserve already-coloured evolution pic…
Roxas2712 Oct 26, 2026
529fa59
Keep native Gen2 daily services on the saved RTC midnight
Roxas2712 Oct 26, 2026
5c1eafa
Set the Gen2 clock through the native introduction and weekday screen
Roxas2712 Oct 26, 2026
b2572b8
Register native clock fallback prompts for translation extraction
Roxas2712 Oct 26, 2026
5fb4cc1
Keep native clock text separators outside translatable prompts
Roxas2712 Oct 26, 2026
d4f6aa5
Preserve other editions intro music and build-hook ordering
Roxas2712 Oct 26, 2026
ae0384d
Keep clock picker hints inside their panel and hide inactive controls
Roxas2712 Oct 26, 2026
d3d0581
Merge commit 'ed5189c247ee7a2ccca666784e21fd4fba8df781' into codex/up…
Roxas2712 Oct 26, 2026
ef434b2
Add native Gen2 shared menu chrome with native palette/font ownership
Roxas2712 Oct 25, 2026
72faf08
Bind Gen2 name entry to its native keyboard and class owner
Roxas2712 Oct 26, 2026
9bd7727
Keep native naming roles, mail layout and cursor resource ownership
Roxas2712 Oct 26, 2026
7f73de8
Own native Gen2 player name choice and blocking portrait movement
Roxas2712 Oct 26, 2026
2c891ba
Suppress decorated keyboard drawing until name entry is active
Roxas2712 Oct 26, 2026
9db5531
Share native BGP ownership and remap already-coloured palette frames
Roxas2712 Oct 26, 2026
ab7c750
Apply native Gen2 display selection and complete-frame palette presen…
Roxas2712 Oct 26, 2026
cff1662
Give native Gen2 saving its own confirmed, timed state
Roxas2712 Oct 26, 2026
b4ebb7a
Keep native Gen2 START as the owner of its submenus
Roxas2712 Oct 26, 2026
f35c6df
Scale native menu fallbacks on their own cartridge grid
Roxas2712 Oct 26, 2026
2383d84
Draw native Gen2 menu owners at output resolution
Roxas2712 Oct 26, 2026
8024f7d
Merge branch 'main' of https://github.com/UNDERdecoded/Gen2Recomped i…
Roxas2712 Oct 26, 2026
be59a4e
Merge commit '8d5b4387420cc1fdcadf58ad4ca78a7d8596e41d' into codex/up…
Roxas2712 Oct 26, 2026
30c72b0
Preserve subscription order for equally ranked native UI events
Roxas2712 Oct 26, 2026
e5230c1
Expose native save summaries without legacy clock assumptions
Roxas2712 Oct 26, 2026
2d6ad50
Combine native UI and PC mail prerequisites
Roxas2712 Oct 26, 2026
cdc08e6
Combine native decoration and mail stores for PC owners
Roxas2712 Oct 26, 2026
e3bc81f
Combine qualified native presentation prerequisites for PC screens
Roxas2712 Oct 26, 2026
f5490be
Provide native Gen2 PC and pack owners with shared storage
Roxas2712 Oct 26, 2026
3156e4d
Retain native world and data context across PC and pack exits
Roxas2712 Oct 26, 2026
0796574
Adapt PC owner dependencies and retain upstream API test scope
Roxas2712 Oct 26, 2026
0f86f7a
Exercise native PC owners and END confirmation in upstream tests
Roxas2712 Oct 26, 2026
4dd65b6
Read the authoritative native map in save summaries
Roxas2712 Oct 26, 2026
174df95
Keep native save summary locations with the offered PC stack
Roxas2712 Oct 26, 2026
7bddc5a
Keep native script callbacks alive while foreground overlays await input
Roxas2712 Oct 26, 2026
7167d02
Route native Gen2 HP beats through the owned presentation callback
Roxas2712 Oct 26, 2026
3dc815d
Clarify the independently offered native HP owner scope
Roxas2712 Oct 26, 2026
27010e5
Expose the actual native display hold before queue dispatch
Roxas2712 Oct 26, 2026
fa37045
Render native Gen2 HP pixel beats and cartridge palette boundaries
Roxas2712 Oct 26, 2026
3637fe5
Exercise real GPU output of native Gen2 HP beats
Roxas2712 Oct 26, 2026
ca9e46b
Expose native Gen2 option window presentation
Roxas2712 Oct 27, 2026
bf0539a
Use the native Gen2 PACK for battle item selection
Roxas2712 Oct 27, 2026
1fc5122
Expose live party data and native Gen2 submenu ownership
Roxas2712 Oct 27, 2026
09cc4bb
Bind Gen2 presentation to actual native battle Pokemon and extensible…
Roxas2712 Oct 27, 2026
0e6109d
Preserve actual Gen2 summary, page and move-management ownership
Roxas2712 Oct 27, 2026
f894816
Route native Gen2 move-swap audio through imported cue ownership
Roxas2712 Oct 27, 2026
13d1e97
Keep native Gen2 item targets and medicine text on the actual battle …
Roxas2712 Oct 27, 2026
1dc6158
Publish native Gen2 resolving and message fields from the actual queue
Roxas2712 Oct 27, 2026
2727365
Connect native Gen2 classic and wide scenes to the battle window owner
Roxas2712 Oct 27, 2026
4f54ab3
Complete native Gen2 party item results on available upstream owners
Roxas2712 Oct 27, 2026
8cd70cf
Include native party result regression in upstream qualification
Roxas2712 Oct 27, 2026
463ce60
Prove item result regression against preceding upstream adaptation
Roxas2712 Oct 27, 2026
89e265a
Resolve native audio owner and collect every candidate suite
Roxas2712 Oct 27, 2026
03c0534
Restore native Gen2 PP selection using available upstream producers
Roxas2712 Oct 27, 2026
850e647
Freeze only source directories available in upstream
Roxas2712 Oct 27, 2026
db989ed
Resume the actual upstream item turn after native party confirmation
Roxas2712 Oct 27, 2026
2c52125
Select native finite enemy PP by default while preserving explicit rules
Roxas2712 Oct 27, 2026
49c1c13
Qualify native PP defaults alongside party result owners
Roxas2712 Oct 27, 2026
1aa9c1f
Document the bounded native Gen2 PP default scope
Roxas2712 Oct 27, 2026
99534ce
Qualify wide animation anchors and continuous capture motion
Roxas2712 Oct 27, 2026
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
47 changes: 47 additions & 0 deletions .github/workflows/gen2-queue-screen-contract.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: native Gen2 queue screen contract
on:
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: gen2-queue-screen-contract-${{ github.ref }}
cancel-in-progress: true
jobs:
contract:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Install ROM-free runtime
run: sudo apt-get update && sudo apt-get install -y luajit
- name: Previous native source exposes the item-result regressions
shell: bash
run: |
git -c gc.auto=0 fetch --no-tags --depth=1 origin 2727365b0c38495717c688708d521cf8150cfec4
baseline="$RUNNER_TEMP/gen2-party-result-baseline"
mkdir -p "$baseline"
git archive 2727365b0c38495717c688708d521cf8150cfec4 src tests data tools | tar -x -C "$baseline"
cp src/render/NativeScreenOverlay.lua "$baseline/src/render/NativeScreenOverlay.lua"
cp src/ui/Gen2PartyItemResult.lua "$baseline/src/ui/Gen2PartyItemResult.lua"
cp src/ui/Gen2MoveDeleter.lua src/ui/Gen2ForgetMoveList.lua "$baseline/src/ui/"
cp src/pokemon/Gen2PP.lua "$baseline/src/pokemon/Gen2PP.lua"
cp src/battle/rulesets/gen2_finite_pp.lua "$baseline/src/battle/rulesets/gen2_finite_pp.lua"
cp tests/engine/gen2_pp_selection.lua tests/engine/gen2_pp_defaults.lua "$baseline/tests/engine/"
cp tests/engine/gen2_battle_pack.lua tests/engine/gen2_party_item_result.lua "$baseline/tests/engine/"
for suite in gen2_party_item_result gen2_battle_pack gen2_pp_selection; do
if (cd "$baseline" && luajit "tests/engine/$suite.lua") > "$RUNNER_TEMP/$suite-baseline.log" 2>&1; then
cat "$RUNNER_TEMP/$suite-baseline.log"
echo "Previous source unexpectedly passed $suite"
exit 1
fi
cat "$RUNNER_TEMP/$suite-baseline.log"
grep -q '^FAIL' "$RUNNER_TEMP/$suite-baseline.log"
done
- name: Native queue, screen and available menu owners
run: |
failed=0
for suite in gen2_battle_queue_view gen2_battle_window gen2_battle_scene wide_battle_layout wide_battle_shake_bug562 gen2_battle_pack gen2_party_item_result gen2_pp_selection gen2_pp_defaults screen_space_ui party_live_data gen2_battle_live_view gen2_battle_submenu gen2_summary_contract frlg_battle_gender; do
if ! luajit "tests/engine/$suite.lua"; then failed=1; fi
done
exit "$failed"
64 changes: 64 additions & 0 deletions docs/NATIVE-GEN2-DISPLAY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Native Gen2 display selection

Gen2 display selection belongs to `PaletteFX`, the same owner used by the
native tile, sprite and battle renderers. `GbcPalette` exposes the Gen1Recomp
public vocabulary over that state: `gbc`, `dmg`, `classic`, and `custom`.
The generic native ID for DMG remains `og`, preserving existing option files.

GBC uses the cartridge's indexed palettes. DMG retains the four original
indexed shades as grayscale. Classic uses that same grayscale intermediate
and maps the completed frame through the green ramp once. A custom ramp
replaces indexed palette rows; already-coloured art keeps its existing
true-colour contract. The unrelated Gen1 colourization packs and Gen3
display behaviour retain their existing paths.

`setMode`, `cycle(delta)`, `setCustomRamp`, `applyOptions`, `modeLabel`, and
`presentColors` are available through `GbcPalette`. The mode, custom ramp and
byte BGP all share native state. Raw indexed drawing bypasses display/BGP
selection. A custom ramp takes priority over the selected indexed mode, as
in the reference protocol; Classic's final presentation remains a separate
operation. Missing custom ramps fall back to grayscale.

`PaletteFX.setDisplay(mode, ramp)` applies a selection atomically. It invalidates
tile and animation textures, OBJ images, battle images and cached maps, then
reloads the entered map. The shared `Assets.register` invalidation bus also
notifies external texture producers, including repeated ramps with the same mode
ID. Retained battle image references resolve through their
original palette and crop on the next draw. Reapplying an edited ramp table
also updates its key and invalidates dependent caches. Transient BGP writes do
not enter static atlas cache keys. Mono/custom world bakes retain cave darkness;
battle palette permutations and blackout apply after display selection.

Native Gen2 options and hotkey 2 use the GBC → DMG → Classic ladder, with a
backward step supported. Cycling clears a selected custom ramp and saved
palette ID. Native `options.colors` and legacy `options.color` record the same
selection. Applying legacy mode plus `options.palette` performs one rebuild.

`src.render.Palette` supplies the public palette ID/library operations. Mono IDs
are `m:rrggbb`; named IDs are `p:group/name`. An optional authored
`data.gb_palettes` module supplies named entries; no palette catalogue is
invented or extracted by this library. Categories, labels, lookup, swatches,
ramp caching and invalidation use the reference vocabulary.

## Completed-frame zones and composition

For native Gen2 gameplay, `render.zones` receives the final display zones once,
after native drawing has settled its palettes. Classic starts with one green
whole-frame zone; other modes start with nil. Consumers can replace, remove or
extend those zones. Each dispatch gets its own list. This final pass uses raw
palette destinations so Classic cannot resolve its own green ramp back to gray.

The native Gen2 compositor first combines world and UI into one scene. Its
window-menu callback includes a window-resolution drawer when one is supplied;
this offer does not add the separate native window-menu classes or a palette-picker UI. `render.compose` then receives that completed texture in
`sceneCanvas`, `worldCanvas` and `uiCanvas`, with `generation = 2`, the native
renderer and an explicit `game` owner. The render target is different from the
source texture. A consumer taking composition ownership also owns presentation
of the supplied final zones; `Renderer:blitZones` provides the raw zone blit.
Otherwise the engine applies final zones before present/output effects. HUD and
touch controls retain their screen-space placement outside this game scene.

This is display work toward Gen1 parity. It does not establish complete UI
raster parity, a full unchanged-mod playthrough, save/link acceptance, hardware
performance or full engine parity. Existing upstream/Gen1 licences and the
[Roxas2712 contribution permission](https://github.com/Roxas2712/Gen2Recomped/blob/7867399c753186778bd4b8816ba37573357e4b40/LICENSE-ROXAS2712.md) remain applicable.
45 changes: 45 additions & 0 deletions docs/NATIVE-GEN2-HP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Native Gen2 HP presentation

The shared battle engine resolves damage and queues the presentation of each
damage or healing beat. Gen2 now dispatches that actual queue row through
`BattleState:stepHpAnim()`, with `hpAnim.side` and `hpAnim.to` describing the
active beat. `shownHp.player` and `shownHp.enemy` read the real battlers'
displayed HP. Writes are admitted only inside that callback, for its actual
side and Pokemon, with finite values within the Pokemon's maximum HP.

The default callback retains the Gen1Recomp Gen2 implementation's 48-pixel
short/long loops, two-frame pixel cadence and high-HP integer division. A
decorator may choose different display increments for a wider HUD. The native
queue still waits for the actual target and retirement of `hpAnim`; returning
early cannot grant the next battle command. Display writes never mutate the
Pokemon's resolved HP. Queued multi-hit stops and battler switches preserve
their native owners. Gen1 and Gen3 retain their existing drain path.

`tests/engine/gen2_hp_presentation.lua` exercises the real shared battle class,
queue dispatch, multi-hit floors, healing, fainting, fractional display steps,
invalid writes, callback failure cleanup, battler replacement and the other
generations' unchanged path. These tests do not prove full mod playability,
move animation or capture rendering; those require separate implementation
and gameplay acceptance. This upstream contribution binds the HP view directly
in the native constructor; the fork's additional live battle-model and sprite
capture view is a separate integration. The HP regression stands on its own.

`hudHp` and `hudHpPixels` expose the displayed number and the independent
animated pixel cursor. Both native HUD tile output and its color-zone selection
read that cursor, including short-loop frames whose HP number repeats. Party
and summary bars use GSC's high-HP byte division and half-HP green boundary;
explicit imported hack geometry and other generations retain their defaults.
Changing between a wider decorated HUD and the native step discards a stale
pixel cursor, so returning to the native HUD cannot reverse displayed damage.

`gen2_hp_pixels.lua` checks actual native HUD tile output, palette boundaries
and display-owner handoff. `tests/gpu/gen2_hp_pixels.lua` reads actual GPU pixels
from the native queue and tile renderer using a generated test atlas in Gold,
Silver and Crystal, with color and grayscale output. It does not establish
whole-mod or final OS-window acceptance.

Pixel stepping adapts Gen1Recomp's `src/battle/gen2/HpBar.lua` and
`src/ui/gen2/BattleState.lua`. Existing upstream and Gen1Recomp rights and
credits remain applicable; see `NOTICE.md`. Native-owner integration and
regressions are contributions by Roxas2712, under `LICENSE-ROXAS2712.md` to the
extent of rights held.
66 changes: 66 additions & 0 deletions docs/NATIVE-GEN2-PALETTE-REGISTER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Native palette register and frame remapping

The public `src.render.GbcPalette` module resolves to the engine's
`Gen2PaletteDraw`. Its byte-register API shares `PaletteFX`'s native shade map;
there is no second register owned by a compatibility facade.

## Forward drawing

`BGP_IDENTITY` is `0xe4`. `bgpShades(byte)` returns the four two-bit fields,
with colour zero first, in a one-based array. `remap(colors, byte)` applies
those indices to a four-row RGB palette. Nil and identity preserve the original
palette table.

`setBgp(byte)` returns the previous byte. Identity is represented by nil.
Reading or assigning `GbcPalette.bgp` accesses this same native state; native
`PaletteFX.setShadeMap` writes are immediately visible through it. The existing
native frame reset clears it as well.

`resolve(colors)` selects the display palette without applying the register.
`color`, `use`, `with` and keyed draws apply the current register once.
`useRaw` and `withRaw` bypass display selection and the register. Native
`PaletteFX.sendColors` consumes the same state. The separate palette-upload
optimization uses this owner when present.

## Already-coloured frames

`remapTable(bgPalettes, byte, objPalettes, ramp, objRamped)` returns source
colours, destination colours, a live count and an ambiguity count. Tables hold
0–255 RGB triples, padded to `REMAP_MAX` (64) with detached rows. BG palettes
take the explicit byte permutation. OBJ palettes normally retain their colours.
An optional forced ramp supplies BG destinations; selected `objRamped` entries
take its unpermuted colours.

Shared RGB values can no longer identify the original palette after composition.
The first BG interpretation wins; conflicting destinations increase the ambiguity
count. This is a limitation of remapping RGB frames, not proof of indexed
per-pixel equivalence. Extra entries beyond 64 are omitted with BG slots first.

`remapUniforms(...)` builds normalized shader inputs, or returns nil for an empty
table. `useRemapUniforms(inputs)` and `useRemap(...)` bind the actual remap shader
and return `true, ambiguityCount` on success. Matching uses squared RGB distance
below `(3/255)^2`; unmatched pixels retain their RGB. Alpha and draw tint are
preserved. Compilation/upload failure returns false, retaining the previous
shader. A failed remap shader can recover when the graphics compiler changes.

Public uniform uploads are unconditional. Nested `with`, `withRaw` and
`keyedWith` restore both shader identity and prior palette/remap uniforms,
including after a callback or partial upload fails.

## Verification and remaining display work

`tests/engine/gen2_palette_register.lua` checks all 256 bytes against independent
field decoding in Red, Gold, Silver and Crystal, native/public register ownership,
BG/OBJ remapping, collisions, forced ramps, bounds, uniform ownership and failures.
`tests/gpu/gen2_palette_register.lua` verifies actual pixels for all 256 bytes
through public and native shaders, including the optimized native upload path,
OBJ preservation, unrelated RGB, alpha and tint. Run `run()` from an isolated
LÖVE host separately on each backend. It requires no cartridge or private mod.

This register change alone does not establish full Gen1 display parity. See
`NATIVE-GEN2-DISPLAY.md` for the native display-selection and cache/presentation
owners. Full unchanged-mod story/save/link acceptance and wider engine parity
remain separate requirements.

The public method protocol follows the Gen1Recomp reference interface. Existing
Gen1Recomp and upstream credits and licences remain applicable; see `NOTICE.md`.
23 changes: 23 additions & 0 deletions docs/mod-naming-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Gen1Recomp Gen-2 naming screen compatibility

API-2 mods may open `mod.ui.push(game, "Gen2NamingScreen", opts)`, the public
screen ID used by Anytime Rename 1.2.1. The adapter uses Gen2Recomped's native
keyboard and supports `type` (player, rival, mom, box, nickname), `prompt`,
`maxLength`, `initial`, `mon`, `monName` and `onDone(name)`.

The completion callback owns closing this screen. It runs while the naming
state is still on the stack; a caller may pop it and return to its existing
parent menu. The ordinary `NamingScreen` API remains different: it pops itself
before calling `onDone`. Mapping the ID directly to that class would pop two
states when an existing Gen1Recomp mod closes its own screen.

`text` reflects the editable name and may also be assigned. Initial values and
assignments are limited by glyph count, preserving UTF-8 and charmap tokens.
The adapter keeps the native keyboard's input, drawing and `ui.naming.grid`
hook; it does not reproduce Gen1Recomp's separate Gen-2 keyboard layout or
change native game save fields. Mods should use the native naming screen for
their target host when they do not need this compatibility contract.

Regression coverage: `tests/engine/gen2_mod_naming.lua`. External verification
uses the unchanged Anytime Rename 1.2.1 entry point and its 55-check suite;
its native-menu flow suite additionally runs six games in two languages.
23 changes: 23 additions & 0 deletions docs/native-gen2-battle-item-presentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Native Gen2 battle item presentation ownership

BattlePack must close before constructing a party-item target. Leaving it
underneath the picker makes a resolved presentation see the PACK's boolean
battle flag where the native battle model should be. The Gen2 controller now
closes the actual PACK first and lends its real battle context to the picker.
Cancellation queues a new native PACK, restoring its session pocket/cursor
without consuming inventory, PP or a turn.

Successful medicine and no-effect refusals now use the existing native battle
text queue. A standalone field TextBox has no battlefield composition owner
and produced a white backing over the decorated battle. Effects still run
through BagMenu's existing item-use dispatch; success delegates to itemUsed
once, while refusal queues text without a native enemy action. Other
cartridges keep their existing field-text path.

The updated native PACK regression fails 35 assertions on the preceding
implementation and passes 191 after the change. Live native model, submenu, summary and FireRed
regressions also pass on this independently adapted upstream-PR composition
(976 checks together). These ROM-free source/input
checks do not establish unchanged-client GPU, full Gen1 visual/story parity
or final package acceptance. Native party-result animation/timing and broader
item-family presentation remain subject to reference acceptance.
16 changes: 16 additions & 0 deletions docs/native-gen2-battle-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Live native Gen2 battle model

A Gen2 screen exposes actual current Pokemon, parties, save, catalog and outcome
through a live model view rather than treating the shared battler-wrapper screen
as that model. HP presentation remains on the existing native drain owner.
Pokemon picture captures use their real native slots, source image, crop, status
and effects without replacing a live rear sprite with its isolated front view.

Native model reader keys remain protected. Presentation consumers may attach and
release transient metadata on the view, without writing to commands or saves.

Independent checks on this PR composition pass: 366 live-model/HP/sprite-capture,
84 submenu-owner, 111 PACK and 9 FireRed checks (570 total). The new model test
fails before integration. These are ROM-free tests; no unchanged-consumer GPU,
release, full-PR or complete Gen1 parity acceptance is claimed. Existing engine
and Gen1 rights and attribution are retained.
24 changes: 24 additions & 0 deletions docs/native-gen2-battle-window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Native Gen2 scene/window owner

Expose `drawWidescreen` and explicit Gen2-only compositor admission on the actual
shared battle class. This upstream adaptation also splits the existing Gen2
classic/wide BG, objects and final-overlay composition into `drawPanel`,
`drawSceneBody` and `drawScene`; the older branch did not provide them. The
same native scene, chrome, layout and fixed/fill setting remain authoritative.
The graphics guard restores caller canvas/state even after leaked pushes.
Other editions retain the original classic/wide route. No mod or game data
is changed or included.

The public contract was checked against Gen1Recomp
`535a5ec088c1ae1bf4d91dd3e35a56f64cf46d91`,
`src/ui/gen2/BattleState.lua`. The extracted native composition retains the
existing BattleState/WideBattle provenance and applicable project rights.
The additional graphics guard is an independently owned Roxas2712 contribution
offered under the permission described in this PR.

Source tests cover native window admission, multiple viewport/DPI sizes,
classic/wide scene ownership, fixed/fill options, caller-state restoration
and native menu/model/summary regressions. The separate fork's earlier
54 functional Metal checks and12 inspected captures diagnose a missing native
drawer and a white fallback on an older source; they do not qualify this
upstream composition, current visual parity, packages or a release.
Loading