skyfloogle / red-viper

A Virtual Boy emulator for the 3DS
795 stars 18 forks source link

Add option to toggle shoulder buttons #39

Closed vaguerant closed 8 months ago

vaguerant commented 8 months ago

This does what I talked about in issue #32.

It adds a new option and on-screen toggle for tVBOpt.ZLZR_MODE, which tracks the user's shoulder button preference. Using this setting, whichever input is currently mapped to the touch screen also gets mapped to the user's chosen shoulder buttons, which means players on New models aren't forced to use the touch screen in games which have more complicated control schemes (at least Jack Bros., Red Alarm, Teleroboxer and Virtual Bowling).

This setting has four possible values, which map to the following layouts:

ZLZR_MODE L ZL ZR R
D-pad on screen/shoulders
0-1 L D-pad Left D-pad Right R
2-3 D-pad Left L R D-pad Right
A and B buttons on screen/shoulders
0 L B A R
1 L A B R
2 B L R A
3 A L R B

I promise it's less complicated than it looks. I do some tricksy stuff in the menu toggle so that it jumps two options ahead when you toggle it while in D-pad mode rather than having you toggle between options that don't change the config:

tVBOpt.ZLZR_MODE = (tVBOpt.ZLZR_MODE + (buttons_on_screen ? 1 : 2)) % 4;

Reasons for draft status

  1. [x] Do you want a way to disable this option entirely on original 3DS models? Done

    EDIT: The second build below attempts to check that this is a New 3DS before enabling the shoulder button toggles, but I don't own an original 3DS (and my PC can't run Citra) so I'm not able to actually confirm that it works. If somebody with an o3DS feels like testing that build to check whether the Controls screen looks like the screenshot above or if the top section is removed as I intended, I'll update this PR with that fix.

    EDIT2: Confirmed via Citra Android that the New 3DS check is working and updated this PR to add it in.

  2. [x] C2D_DrawText does some kinda weird stuff with some glyphs, it feels like it doesn't leave enough padding for anti-aliasing of the text? See the way the (B) buttons look slightly clipped on each side. Not sure if this is fixable in C2D? Fixed

    EDIT3: This is an upstream bug with C2D_AlignCenter, using different alignments prevents this clipping from occurring (but obviously complicates the process of laying out text when the center is what you need).

    EDIT4: I have filed upstream issue devkitPro/citro2d#47 about this apparent oversight.

    In the meantime, I have implemented a workaround for the text rendering bug by shifting each glyph by a half pixel. Build 3 below includes this fix.

Without workaround: ![image](https://github.com/skyfloogle/red-viper/assets/5259025/565e2ce4-f0f8-465b-9655-84cf2b987ea0) With workaround: ![image](https://github.com/skyfloogle/red-viper/assets/5259025/34fdca57-bb5e-4218-b605-2432df8638fe)

Test builds

  1. red-viper_shoulders-pr_hotfix.zip
  2. red-viper_shoulders-pr_old-3ds-check.zip
  3. red-viper_shoulders-pr_old-3ds-check-citro2d-fix.zip
skyfloogle commented 8 months ago

Works fine on my o3DS.

By default, the D-Pad is on the touchscreen. With the current setup, this corresponds to the D-Pad being on the triggers, so there's no distinction between the A/B mapping. It's not very obvious that the A/B mapping is relevant here as well.

In my opinion, it would be simplest to just omit the D-Pad trigger assignment and always use the face buttons. Having the D-Pad on the triggers would only help games that need left/right but not up/down, which IIRC is only Virtual Bowling. Given that there's not really any reaction speed involved in that game, I think it's a worthy sacrifice for the improved general UX. At least for now; I would still like to implement a more detailed control configurator in the long term.

LGTM otherwise! I like the button icons :)

vaguerant commented 8 months ago

Works fine on my o3DS.

:tada:

By default, the D-Pad is on the touchscreen. With the current setup, this corresponds to the D-Pad being on the triggers, so there's no distinction between the A/B mapping. It's not very obvious that the A/B mapping is relevant here as well.

In my opinion, it would be simplest to just omit the D-Pad trigger assignment and always use the face buttons. Having the D-Pad on the triggers would only help games that need left/right but not up/down, which IIRC is only Virtual Bowling. Given that there's not really any reaction speed involved in that game, I think it's a worthy sacrifice for the improved general UX.

That's fair. Having the D-pad on the shoulders was requested by one user in the related issue, but it has such a niche benefit, in Virtual Bowling as you mention and being sort of usable in Red Alarm but inferior to just playing properly with the D-pad on the face buttons. I've just removed that feature in a force push, so the shoulder buttons are always in LBAR/LABR/BLRA/ALRB mode.

At least for now; I would still like to implement a more detailed control configurator in the long term.

This makes sense. In the short term, a setup that just works for everything, which this does, seems appropriate.

LGTM otherwise! I like the button icons :)

Nice, yeah, benefits of using the system font! :D

Test build

  1. red-viper_shoulders-pr_final.zip