stella-emu / stella

A multi-platform Atari 2600 Emulator
https://stella-emu.github.io
GNU General Public License v2.0
611 stars 112 forks source link

(libretro) lightgun/analog support #865

Closed StormedBubbles closed 2 years ago

StormedBubbles commented 2 years ago

Hello again,

I recently became aware of the libretro port of Stella, and I have it up and running on my Raspberry Pi. RetroArch's built-in ability to apply overlays allows me to easily apply a border to the game area and use my Sinden lightguns in emulators that have lightgun support.

I browsed through stella/src/libretro/libretro.cxx and noticed that the lightgun appears to not be mapped to any control input in lr-stella.

RetroArch has a lightgun API (as mentioned in stella/src/libretro/libretro.h) that can grab a mouse cursor and allow mouse devices to act as a lightgun. I am curious if the lightgun feature could be brought over to the libretro port from standalone Stella.

thrust26 commented 2 years ago

I am having a joystick with two d-pads and two hats. What confuses me is, that there seem to be two controller menus. In one you can map the controller. And this works well. But when I play the game I cannot change the analog mapping there. When I try to map e.g. Y-up, this causes the cursor to move to the previous mapping. When I try to map a button, this works. Weird.

Anyway, I am getting closer now. It is a mix of changing settings and changing my own code. With some trial and error. A bit complex...

thrust26 commented 2 years ago

I finally managed to map left analog hat X to the left paddle. At first it behaved erratic, but then when I mapped the D-pad to something else than left, right it started working as expected. Paddle sensitivity is set to 7.

For whatever reason I can successfully map left/right difficulty to the controller, but not select/start.

StormedBubbles commented 2 years ago

Ah, right, there is a second input menu in Main Menu -> Quick Menu -> Controls.

It is a bit convoluted, but the first menu I mentioned is for assigning buttons from a physical controller to in-game functions. The second menu mentioned here is for rearranging the inputs assigned by the RetroArch control scheme. For example, a user could use this menu to switch which analog axis he wants to use for paddle movement. The emulator tells him Right Analog Y is for paddle, but he can swap Right Analog Y with another axis.

StormedBubbles commented 2 years ago

Also, I believe regular controllers already have Game Select and Game Reset mapped to the RetroPad select and start buttons, respectively. That's how I remember it working when I tested yesterday.

thrust26 commented 2 years ago

Thanks. Meanwhile I managed to get most things right.

thrust26 commented 2 years ago

The issue is that one 2600daptor + one set of paddles is recognized as a single device. The inputs are all separate (2 independent buttons and 2 independent axes), but I'm having trouble figuring out how to divide those between two separate players.

Yes, the paddles are very special here. Is RetroArch flexible enough to handle that?

The way regular controllers behave now is great. Each individual controller controls an independent player. The only thing people might want changed is which stick (L/R) or axis (X/Y) is the one to use.

I could define 4 different controller types (LX, LY, RX, RY). But maybe this can be solved better on RetroArch/Libretro side. No clue.

I know that we're probably not here yet in terms of this sort of granular setting, but I think this is where the different input choices in RetroArch will be a benefit. Perhaps what would solve this is a "Core Option" of "Paddle Mode" that would work like this:

  • "Paddle Mode = Controller" means one player per controller like it is now (maybe map to a single axis of both L + R analog)
  • "Paddle Mode = Paddles" means two players per controller (single axis of L analog = player 1, single axis of R analog = player 2)

Paddles are even more complex. You have one axis per controller. This can be mapped to X or Y axis, left or right stick. On top of that, many games use swapped paddles or swapped ports (also for joystick games) or both. This is a per game setting and define in Stella's game properties. Does Libretro somehow utilize these?

BTW: I cannot map two inputs to the same Stella event. They will either conflict with each other or only the last one checked will work.

StormedBubbles commented 2 years ago

Lightgun support seems great now! Thanks! 😃

I don't need a cursor on screen because the sight on the gun shell I use is aligned with the mouse cursor. That stays consistent in Sentinel. An eventual option to enable a mouse cursor would be great for those using mice or similar devices without a consistent calibration point.

One of the recent updates appears to have messed with the displayed devices in RetroArch's input menus for Sentinel. It shows "Unknown" as the chosen device, with Joystick, Analog, and Lightgun as the other choices.

I am looking at the paddles now.

StormedBubbles commented 2 years ago

Ah, quick comment on lightgun. It appears that the accuracy deteriorates as I get closer to the edge of the screen. This could be caused by how I have the game scaled to fit within a white border. What is the proper equivalent of a digital resolution for Sentinel? The below image shows what I see on screen. The game area is on top of a flat, gray background.

image

thrust26 commented 2 years ago

Lightgun support seems great now! Thanks! 😃

I don't need a cursor on screen because the sight on the gun shell I use is aligned with the mouse cursor. That stays consistent in Sentinel. An eventual option to enable a mouse cursor would be great for those using mice or similar devices without a consistent calibration point.

That's like in Stella. There only is the OS mouse cursor.

One of the recent updates appears to have messed with the displayed devices in RetroArch's input menus for Sentinel. It shows "Unknown" as the chosen device, with Joystick, Analog, and Lightgun as the other choices.

That's probably because I renamed Paddle into Analog. Wanted to align with Libretro terminology.

thrust26 commented 2 years ago

Ah, quick comment on lightgun. It appears that the accuracy deteriorates as I get closer to the edge of the screen. This could be caused by how I have the game scaled to fit within a white border. What is the proper equivalent of a digital resolution for Sentinel? The below image shows what I see on screen. The game area is on top of a flat, gray background.

The cursor position is scaled to the current screen size. Your screenshot seems to show the correct size (320 x 240). Since I currently cannot test myself (see below), does it deteriorate in horizontal and vertical direction?

BTW: Argh, I am in RetroArch's controller hell again! Suddenly my mouse doesn't work in lightgun games anymore. Any idea what I could have done wrong?

StormedBubbles commented 2 years ago

Sorry, after testing some more, I have a better handle on the lightgun alignment. Here's my exact experience:

At the bottom of the screen, the alignment is really good. On a horizontal line through the center of the screen, my shots end up a little above my sight. Near the top of the screen, the shots are really far above my sight. It seems that accuracy is good at the bottom of the screen but deteriorates the further you go up. This doesn't seem to change with horizontal movement, i.e., I experience the same vertical accuracy loss along any vertical line through the screen.

You may have more than one mouse device plugged in when playing the game. If you go to Main Menu -> Quick Menu -> Input -> Port 1, you should be able to choose the mouse you want to use.

And in standalone Stella, if I go to:

TAB menu -> Input Settings -> Mouse

I see a dropdown menu for displaying the mouse in the menu, the game, neither, or both. This is in the Linux version.

thrust26 commented 2 years ago

If you go to Main Menu -> Quick Menu -> Input -> Port 1, you should be able to choose the mouse you want to use.

You mean Controls (not Input) right? There is no Input. And in Controls, there is Port 1 Controls which then offers Joypad, Analog or Lightgun. No mouse anywhere.

Anyway, I played around with some settings and suddenly it started working again. On my PC there is no deviation. Judging from your description, I suppose Libretro/RA are doing some kind of vertical scaling.

StormedBubbles commented 2 years ago

Oops, I meant Main Menu -> Settings -> Input -> Port 1

I will do some more testing. The likely culprit is that I just need to let the emulator auto-output the resolution and then fit the border around that instead of trying to fit the game inside of the border. I probably stretched the game in a non-uniform way.

thrust26 commented 2 years ago

That shouldn't be a problem as long as Stella is doing the stretching. I am scaling both axis independently.

StormedBubbles commented 2 years ago

Okay; thanks! I tried Shooting Arcade and had much better accuracy all around, so maybe I was using a "bad dump" of Sentinel. I'll try a different file another time. I will try out some paddle games on the next go-around.

thrust26 commented 2 years ago

I tried Shooting Arcade and had much better accuracy all around, so maybe I was using a "bad dump" of Sentinel. I'll try a different file another time.

It cannot be a bad dump. What exactly are you doing to get your white bezels and which causes scaling? Maybe I can adjust my scaling code.

StormedBubbles commented 2 years ago

All of the below is for a TV with a 1920x1080 resolution. For the gun games on other systems, I play in a 4:3 aspect ratio. The border is applied via an overlay in RetroArch. The border is a 1920x1080 .png that encloses a 1400x1050 space via 15pixel-thick white lines. The rest is transparent.

In the RetroArch Main Menu -> Settings -> Output -> Scaling (I think that's the right menu sequence), I set the aspect ratio to custom, the resolution to 1400x1050, and the positioning in a way that allows the image to fit within the border precisely. This is all done on my computer by external configuration files, so I'm not manually doing this for each game. Some games may be slightly squished due to their non-4:3 native aspect ratios, but I am satisfied with the result.

Sentinel seems to be a strange case. The changes in resolution via the RetroArch menu seem to affect not only the game area and gray area around the actual game, but also the empty black vertical space above those. If I scale to 1400x1050 and center within the border, I get a ton of blank black space above and below the game within the border. I tried manually stretching vertically to fill the space, but the experience was the same in both cases: the placement of the shots is further away from my sight vertically the further I move the gun up the screen. Like you mentioned, the scaling done within the code typically takes care of this. I scaled Shooting Arcade the same way and don't experience any accuracy loss. With Sentinel, I can't seem to get good accuracy at any resolution.

I won't be home for another 8 hours. I can take a few pictures to show how scaling affects the two games. Shooting Arcade doesn't appear to have the same issue with extra black space.

thrust26 commented 2 years ago

Atari 2600 games tend to have black (or other single colors) areas at top and bottom.

I don't know what RetroArch is doing when you are scaling, but it cannot depend on the game. So if you do the same with Shooting Arcade as with Sentinel, then the result should be the same.

I describe the conversion in detail, maybe something rings a bell.

As you can see, it is pretty complex. If the Lightgun deviates in vertical direction, then RA is doing something with r.height which the current code is not aware of. Stella is using the height to adjust pixels to correct aspect ratio. This can be disabled. I tested that in Stella, but the results were still perfect.

Since your problem does not happen for me, one of your settings must be different. How can I setup the bezels like you do? You are testing with a real light gun, right? Can you test with a mouse too?

BTW: The vertical height of Sentinel is 268 scanlines, Shooting Arcade displays 260 scanlines. The default value for NTSC is 262 scanlines. Maybe that has an effect, no clue.

StormedBubbles commented 2 years ago

Thanks so much for the detailed explanation!

It turns out that my expanding the image to make the black portion go off screen was causing the issue. Like you suggested, if I consider that black portion as if it's part of the game area when scaling everything to fit inside of the border, the gun works perfectly. Thanks to your descriptions, I realized where I made my mistake and fixed it on my end.

Also, the "unknown" device I mentioned earlier was my error too. I had an extraneous config line causing that issue.

As far as the paddles, I can map Paddle A manually in the RetroArch menu (Kaboom! does indeed work for me), but I am unsure of how to match the awesome convenience of the auto-detection in the standalone Stella emulator or how to get the second paddle mapped to a separate device.

It seems that a paddle set can't be separated across two separate players/ports in RetroArch. Perhaps someone will come along to help at some point, but I can only describe in words how that would work :/

I can try inquiring at the Libretro forums. It appears that there is some development discussion there.

thrust26 commented 2 years ago

Thanks for the feedback. Too bad that there are still problems with the paddles. Maybe @barbudreadmon has an idea here?

Can you post me a link to the discussion(s) you are mentioning?

StormedBubbles commented 2 years ago

This is the main forum:

https://forums.libretro.com/

Within the General section is a tab for "Development," though maybe that's for development on RetroArch itself and the Libretro -> Cores section is where discussion on this would go. The Libretro system uses "cores" to refer to individual emulators.

barbudreadmon commented 2 years ago

@thrust26 i don't feel like reading all the messages, could you write me a summary of the paddle issue ?

thrust26 commented 2 years ago

Not that much to read. 😈

As far as the paddles, I can map Paddle A manually in the RetroArch menu (Kaboom! does indeed work for me), but I am unsure of how to match the awesome convenience of the auto-detection in the standalone Stella emulator or how to get the second paddle mapped to a separate device.

It seems that a paddle set can't be separated across two separate players/ports in RetroArch. Perhaps someone will come along to help at some point, but I can only describe in words how that would work :/

StormedBubbles commented 2 years ago

Hey, @barbudreadmon, thanks again. Here's my perspective:

One traditional modern controller with analog sticks per player works great for analog control of paddles. That is fine and doesn't need any changes other than possibly game-specific issues about which axis to use for control.

The complication comes in with an actual Atari/Gemini paddle set, which is two paddles per controller port and each individual paddle with a fire button. A paddle set (two paddles) is recognized by RetroArch as a single controller with two buttons and two analog axes. I believe Paddle A gets the X axis, and Paddle B gets the Y axis.

The hope is to have either a core option or input type that allows a "Paddle Mode" for Port 1 or 2 to be set between "Controller" and "Paddles." For the controller type, it would be one controller per player for up to 4 players (how it is currently). For the paddle type, it would be two paddles per RetroArch port (so port 1 would house players 1 and 2, while port 2 would house players 3 and 4).

The other issue would be how to mix and match (so if two people used paddles and one or two additional people used controllers).

barbudreadmon commented 2 years ago

RA has a setting called "mapped port" (somewhere below the device type setting), it basically allows you to merge several physical controllers into 1 retropad by saying "this physical controller is associated to player X". I don't recommend implementing something core-side.

thrust26 commented 2 years ago

@barbudreadmon I think @StormedBubbles wants exactly the opposite. Mapping a pair of paddles to two physical controllers.

StormedBubbles commented 2 years ago

Correct. The two paddles share the same controller ID but need to be mapped to two separate RetroArch ports. It would be like having a controller whose left stick is mapped to port 1 and right stick is mapped to port 2.

barbudreadmon commented 2 years ago

Not sure which one you need because i'm not sure you are using the same terms i use, so i'll list all possibilities when it comes to retropad to physical controllers relations :

They cover everything.

StormedBubbles commented 2 years ago

Thanks! That should do the trick.

thrust26 commented 2 years ago

Please let me know if anything from my side is still missing or if we can close this one.

StormedBubbles commented 2 years ago

Everything seems good to me! Thanks so much!