Skip to content

Open the retro menu from the guide button in the 3D engine, and impor… - #683

Merged
maxjivi05 merged 3 commits into
WinNative-Emu:mainfrom
maxjivi05:voxel-3d-menu-fix
Aug 5, 2026
Merged

Open the retro menu from the guide button in the 3D engine, and impor…#683
maxjivi05 merged 3 commits into
WinNative-Emu:mainfrom
maxjivi05:voxel-3d-menu-fix

Conversation

@maxjivi05

Copy link
Copy Markdown
Contributor

…t the Stadium ROM

The guide button opened the in-game menu everywhere except the voxel engine. RetroActivity, ARMSX2's MainActivityRuntime and Dolphin's EmulationActivity all handle KEYCODE_BUTTON_MODE; Gen1EngineActivity handled only BACK, and onButton drops anything that is not A, B, START or SELECT, so a physical guide press reached nothing. It now toggles the drawer the way the libretro path does, gated on a gamepad source so a TV remote cannot trip it. Dolphin's Wii branch is left alone: it maps that button to the Wiimote HOME key on purpose.

STADIUM ROM is a row the mod publishes on every platform, but its import only works where LOVE has a file dialog, which on Android is nowhere -- so the row could only ever print a folder path. The mod already watches for picked_stadium.z64 in its save directory on every frame and builds from it (main.lua calls StadiumRomPick.poll for exactly this), so the row now opens the system picker, stages the file under that name and lets the mod do the rest. No engine or mod change, and no restart: the build starts within a frame and the mod shows its own progress.

Once the models exist the row reads READY and opens a Keep/Delete prompt rather than importing again; Delete drops the built pack and any base ROM left behind. The ROM is checked for an N64 magic and a plausible size before it is staged, and it is written to a .part file and renamed so the mod's poll can never see a half-written file.

Selecting STADIUM A or B without a ROM was not reachable to begin with: the mod gates those two rungs off the 3D-BTL ladder behind StadiumInstall.available(), so they appear on their own once the import finishes.

…t the Stadium ROM

The guide button opened the in-game menu everywhere except the voxel
engine. RetroActivity, ARMSX2's MainActivityRuntime and Dolphin's
EmulationActivity all handle KEYCODE_BUTTON_MODE; Gen1EngineActivity
handled only BACK, and onButton drops anything that is not A, B, START or
SELECT, so a physical guide press reached nothing. It now toggles the
drawer the way the libretro path does, gated on a gamepad source so a TV
remote cannot trip it. Dolphin's Wii branch is left alone: it maps that
button to the Wiimote HOME key on purpose.

STADIUM ROM is a row the mod publishes on every platform, but its import
only works where LOVE has a file dialog, which on Android is nowhere -- so
the row could only ever print a folder path. The mod already watches for
picked_stadium.z64 in its save directory on every frame and builds from it
(main.lua calls StadiumRomPick.poll for exactly this), so the row now
opens the system picker, stages the file under that name and lets the mod
do the rest. No engine or mod change, and no restart: the build starts
within a frame and the mod shows its own progress.

Once the models exist the row reads READY and opens a Keep/Delete prompt
rather than importing again; Delete drops the built pack and any base ROM
left behind. The ROM is checked for an N64 magic and a plausible size
before it is staged, and it is written to a .part file and renamed so the
mod's poll can never see a half-written file.

Selecting STADIUM A or B without a ROM was not reachable to begin with:
the mod gates those two rungs off the 3D-BTL ladder behind
StadiumInstall.available(), so they appear on their own once the import
finishes.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

…ettings

Deleting the Stadium models left the row reading READY and re-offering the
same prompt. StadiumInstall.ready() memoises its answer in readyCache for
the life of the process, so nothing WinNative removes from disk can change
what the mod reports. The row now reads the pack marker itself rather than
trusting the mod's cached value, and rebuilds the menu after a delete. The
running engine keeps its cached answer either way, so the toast says to
restart; StadiumInstall.forget() exists for this but nothing reachable
calls it.

The confirm prompt was a stock platform dialog sitting inside a Compose
drawer that looks nothing like it. RetroConfirmPrompt and
RetroConfirmDialog match RetroConflictDialog exactly. Keep sits on the
left, Delete on the right in the theme's danger colour, and a tap outside
the card cancels.

A physical stick or d-pad could not drive the 3D engine's menu: the axis
path reached the game instead. RetroActivity has a dispatchGenericMotionEvent
for this and Gen1EngineActivity had none, so its handleAxis only ever ran
for the on-screen pad. Joystick motion now feeds the menu while it is open
and is swallowed rather than passed to the game.

Shortcut Settings showed the wrong things under the 3D toggle. The video
filter, SGSR and upscale rows are libretrodroid's and the engine does not
use libretrodroid; the core-option group is gambatte's and the engine is
not gambatte. Both are hidden, and a VOXEL 3D group takes their place with
the Stadium ROM row, which works with no engine running because it is only
files on disk.

Two rows were lying: the engine reads neither KEY_AUDIO nor
KEY_ADAPTIVE_STICKS, and its onStick and onRightStick are Unit, so it has
no analog input at all. Adaptive sticks is hidden and the sound switch is
replaced by a line pointing at the in-game Sound tab, which is where the
engine's own per-channel volumes live. Mirroring those here would mean a
second copy of state the engine owns and would drift the moment it gains
an option.
Shortcut Settings showed nothing the engine actually runs on. The engine
publishes fourteen rows over the bridge -- colors, tilt, gbcfx, zoom,
voidFill, videoMode, animations, the three volumes and the music filter,
fpsCap, speed, controls -- plus whatever the mod adds, and none of them
reached the screen.

Embedded emulators already have this: RetroCoreOptions carries
GAMECUBE_OPTIONS and WII_OPTIONS for standalone Dolphin, and
DolphinEmbedLaunch resolves them into EXTRA_VARIABLES at launch. The 3D
engine had no equivalent.

A hand-written catalogue would not survive here. Several ladders are built
at runtime -- zoom's legal range follows the window's fit scale and changes
on rotation, colors comes from PaletteFX.MODES, controls from the ruleset
registry -- so a copy in Kotlin would be wrong the moment the engine moved.
Instead the rows the engine already publishes are cached as it runs, and
that cache is what the screen renders. The labels come from the engine, so
there is no second list to maintain and a new option appears on its own
after one launch.

Choices are stored as the retro_var_ extras the libretro path already
uses, resolved at launch, and applied through the bridge once the engine
reports booted. Every row keeps a leave-as-set entry so a shortcut only
pins what the player actually chose, and a game that has never run says so
rather than showing an empty screen.
@maxjivi05
maxjivi05 merged commit 89daef3 into WinNative-Emu:main Aug 5, 2026
5 checks passed
@maxjivi05
maxjivi05 deleted the voxel-3d-menu-fix branch August 5, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant