libretro / RetroArch

Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
http://www.libretro.com
GNU General Public License v3.0
10.09k stars 1.81k forks source link

(3DS) Games with vertical orientation are mirrored #4817

Closed danieljg closed 7 years ago

danieljg commented 7 years ago

Description:

When choosing a game with vertical screen orientation, the game appears not rotated, but mirrored. The image appears at the wrong aspect ratio, too, even with integer scaling ON. I have observed this while using the final burn alpha 2012 core, although in troubleshooting I found that this was previously reported as issue #2838 in the mame 2003 core. This is using the cia release of a Februrary nightly on a N3DS with A9LH and Luma running the 11.2 system software version. Examples are 19XX (cps2 game) and DonPachi (cave game), but every vertical game seems to show this issue.

Expected behavior

I expected the game to appear neither rotated, nor mirrored, and with integer scaling. Rotating the image of the game wouldn't make very good use of the screen real estate in a portable. It's easier to just rotate the portable.

Steps to reproduce the bug

  1. Start the FBA2012 retroarch core from the 3ds home menu
  2. Start a vertically oriented game
  3. Try to read the text and notice it's all mirrored.

Bisect Results

I didn't actually bisect this, but rather I had a look at the code. It seems the error is found in the function ctr_set_screen_coords, which starts in line 93 of the gfx/drivers/ctr_gfx.c. The cases for 90 degrees and 270 degrees are in error. The limits of the x0/x1 and y0/y1 run with the opposite 'handedness' as they should in those two cases I mentioned. It's not clear what the author intented there, but I think this was probably a copy/paste error that went unnoticed for a while.

In my opinion, it makes little sense to rotate the screen of vertical games in a portable system, since you can always rotate the system itself. I suggest that the contents of the 'if' blocks corresponding to cases rotation==1 and rotation==3 (the 'else' case) be set as in the cases of rotation==0 and rotation==2, respectively.

Workaround

As a workaround, one can modify the "retroarch.cfg" file to set "video_allow_rotation=false". This removes the mirroring and keeps the image horizontal in vertical games.

Once this has been done, in order to get 1:1 pixel mapping, one has to manually change to a custom screen resolution, set integer scaling to OFF, set the resolution and offsets to the correct values (224x384 for cps and cps2 with 8 offset, 224x320 for DonPachi with 40 offset in x, 224x256 for 1943 Kai, etc), since retroarch reports wrong values for these. Save 'per game overrides' after this.

Finally, go to the control options under the quick menu, set your controller to be rotated (up is right, right is down, down is left, left is up) and save the 'per game controller remap'.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/44003930-3ds-games-with-vertical-orientation-are-mirrored?utm_campaign=plugin&utm_content=tracker%2F296058&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F296058&utm_medium=issues&utm_source=github).
vaguerant commented 7 years ago

For reference, that pull request prevents the image becoming mirrored when games are rotated, but doesn't fix the underlying issue of rotation not working. Mirroring was really only a side-effect of rotation not working, not the real issue.

This still means that platforms like WonderSwan (a piece of hardware which relies on being physically rotated) are largely broken on 3DS. The WonderSwan specifically has three sets of inputs, of which two are used at any given time depending on the current rotation. Just rotating the system doesn't work on any handheld which doesn't share this feature, so RetroArch has a feature to rotate the screen and remap the inputs upon pressing RetroPad Select. The WonderSwan was designed to have useful, comfortable inputs in two (or more) different orientations. A 3DS is not designed for holding sideways--even when games do involve sideways play, they tend to be based around the touch screen, not using the button inputs which are now horridly uncomfortable.

Furthermore, it doesn't make sense not to allow rotation on 3DS, because any number of issues roll on from it. For one thing, try BurgerTime, the arcade game. This uses a vertical monitor and a game that runs at 240*240 pixels. Rotating the screen does zero to help or hurt the amount of real estate on the screen, nor is it convenient to physically rotate the 3DS to play a game that already fits perfectly on the screen. Rotation is an important feature of RetroArch for usability purposes. The fact that you can physically rotate a 3DS if absolutely necessary doesn't mean it's ideal in all situations or that features can or should be left out of RetroArch because of it.

All that said, I personally play games like Pac-Man horizontally on the 3DS screen for the sake of 1:1 pixels, but games like the commercial Pac-Man & Galaga Dimensions displays Pac-Man in a scaled, vertical orientation. The desire is clearly there for people to play games vertically, whether you or I plan to do so.

danieljg commented 7 years ago

To be fair, the mirroring was an altogheter different issue to rotation not being implemented. That's why the image was rotated even if the user had set "Allow rotation=false" in their config file.

I agree with @vaguerant that implementing screen rotation for the 3ds would be rather fantastic, but I haven't been succesful in my own attempts in doing so. The video driver has few comments, and those which are there are usually TODO markers... so it's somewhat confusing to work on it.

Since the mirroring for all vertical games is fixed, I'll be closing this issue report now.