Skip to content

Portrait layout for iPhone: picture in the top half, touch controls in the bottom half #557

Closed

Description

@earths-voluble

What is missing

On iPhone the app is landscape only, with the touch controls drawn over the picture. On the iPhone Duo's inner display (unfolded, roughly 7:10 when held upright), landscape leaves large black bars, and the controls still cover the game. Held upright, the screen has room for a full-width 16:9 picture with the controls below it. The Duo's fold appears to run across the middle of the upright screen, so the picture can stay clear of it when the phone is half folded.

What you propose

An opt-in launcher setting, off by default, so nothing changes for anyone who leaves it alone:

  • DM_PORTRAIT (Controls → "Portrait layout", iOS only, one row in dm/games/settings.tsv). When it is on, the app also accepts portrait once the game starts (application:supportedInterfaceOrientationsForWindow: in main.m and the root view controller). The settings screen stays in landscape, and Info.plist is unchanged.
  • Held upright: the picture fills the width of the top half, centred vertically in it. The existing 2D / 3D touch controls are laid out in the bottom half with the same code as in landscape. Their unit is limited by the area's width as well as its height, and they are drawn slightly stronger because they sit on black. Only touches on the picture reach the game's touch screen.
  • DM_PORTRAIT_INSET (env.txt, 0–25, default 6): moves the controls in from the sides and the bottom by that percentage of their area.
  • In landscape, everything is laid out as before.

The change is about 100 lines, mostly in front_ios.m and DmGamepad.m (one shared function gives the picture rect and the controls' area), plus docs/settings.md and docs/env_switches.tsv. env_switches.py --check and the launcher settings tests pass.

Tested on an iPhone Duo (iOS 27.2), built and run with Xcode from 3950976, with Rhythm Heaven Groove: upright and landscape, with the setting on and off.

Known limit: upside-down portrait does not rotate on the Duo's inner display, even with every orientation allowed in the app and in Info.plist. Apple's "Prepare your app for iPhone Duo" tech talk says the inner display doesn't honor an app's supported interface orientations, so this looks like system behaviour. Rotating the view manually on UIDevice orientation changes didn't help either, so the layout stays at all orientations except upside down.

Related: I couldn't find an existing issue or PR for a portrait layout. #482 (iPhone Duo iOS shell items) doesn't touch the in-game layout. #433, #500 and #258 also change DmGamepad.m, so I'd rebase onto whichever lands first. #433's DM_TOUCH_EDGE is similar in spirit to DM_PORTRAIT_INSET, and I'm happy to merge the two ideas if you prefer.

The code was written with help from an AI assistant (Claude) and tested by me on the device. I have a branch ready and can open a PR if this scope looks right to you.

Platforms

iPhone (opt-in; tested on iPhone Duo)

Activity

  1. Silverhza commented on Oct 29, 2026

    @Silverhza

    This is a great feature. I look forward to seeing this code merged.

  2. earths-voluble commented on Oct 31, 2026

    @earths-voluble
    Author

    Rebased onto current main (6d880d2); the only conflict was one line next to the new Cloud saves call in startGame. Retested on the iPhone Duo (iOS 27.2) with Rhythm Heaven Groove, upright and landscape.

  3. earths-voluble commented on Nov 3, 2026

    @earths-voluble
    Author

    Opened #1082 on top of b64a5ff. The known limit above is lifted in its second commit: upside-down portrait now works on the Duo's inner display. iOS never turns an iPhone's interface upside down, and the inner display's device orientation is a quarter turn from the picture (as in #569), so the front end turns its own stage instead. Details and what is not checked yet are in the PR.

  4. earths-voluble commented on Nov 3, 2026

    @earths-voluble
    Author

    The portrait layout landed in e2fadf2 (#683). Upside-down portrait on the Duo's inner display will follow in a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions