libretro / libretro-atari800

atari800 3.1.0 for libretro/libco WIP
17 stars 45 forks source link

[Feature Request] - Lightgun Support #82

Open Widge-5 opened 2 years ago

Widge-5 commented 2 years ago

Not much more to add. Please add lightgun support to this emulator so that games such as Crime Buster can be playable. Thank you.

edit - I use a Raspberry Pi and a Sinden Lightgun, which is a pointer device treated as a mouse using absolute coordinates (comparable I suppose to a touchscreen).

Darknior commented 2 years ago

Here is the list of lightgun games we will can play if it is added :)

Gun XG-1

StormedBubbles commented 2 years ago

I have a basic understanding of the Libretro lightgun/pointer API. I can offer some aid with coordinate scaling if help is needed. I also have a Sinden lightgun and can help test.

Darknior commented 2 years ago

I have a basic understanding of the Libretro lightgun/pointer API. I can offer some aid with coordinate scaling if help is needed. I also have a Sinden lightgun and can help test.

Thanks a lot for your help, if you can it be excellent.

Widge-5 commented 2 years ago

From the little I understand by looking at the source code, the backend emulator seems to have some level of lightgun support. There are multiple references to light guns and pens as mouse-like devices in the following files:

And I tried the standalone (non-libretro) version of Atarti800 in windows to test the idea and I was able to use a mouse as a lightgun. But it is the libretro side of things that doesn't have lightgun controls hooked up. In fact I'd say that there is no mouse input defined at all - look at https://github.com/libretro/libretro-atari800/blob/master/libretro/core-mapper.c Thanks @StormedBubbles for showing me that file.

Hopefully somebody with the right knowledge will be able to add in the necessary input definitions? Is it possible to adapt something that was used in another core?

StormedBubbles commented 2 years ago

The lightgun API uses RETRO_DEVICE_LIGHTGUN as the device type and would need the following inputs for Atari 800:

RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X and RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y, which are absolute coordinates that range from -0x7fff to 0x7fff on each axis (-32767 to 32767), with 0 at the center of the axis, positive X being right, and positive Y being down. These should be mapped to the emulator's absolute coordinates. The centers would have to match first, and then scaling could be done to align the two. After offsetting to match the center points between Libretro and the emulator, other emulators divide the raw SCREEN_X and SCREEN_Y variables by the total units on the axis (0xfffe or 65534) and then multiply by a scaling factor for each axis (usually the width and height in the resolution).

RETRO_DEVICE_ID_LIGHTGUN_TRIGGER is the trigger button and can just be mapped to the emulator's internal trigger input just like a joypad button. There are extra gun buttons that can be used, but I am unfamiliar with the actual hardware. Does this gun only have a trigger?

Port numbers and device indices should work the same as they do for digital joypads.

Does Atari 800 recognize the difference between onscreen shots and offscreen shots? Libretro has a check RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN that recognizes if X or Y is hitting a min or max value and can aid with offscreen reloading, but what actually happens when the gun is "pointed offscreen" has to be defined in the emulator itself.

StormedBubbles commented 2 years ago

Here is how Stella handled the coordinate scaling for Atari 2600 (the same lightgun). Adding 0x8000 puts the coordinate range at [0,65535] (Libretro technically has a lower bound of -0x8000 for each axis that accounts for an offscreen position, but I don't know how that works). Then, dividing by 65535 makes the range [0,1]. Finally, multiplying by the width and height measures the coordinates as a percentage of the game's width and height and allows them to be scaled appropriately regardless of display resolution.

wn2000 commented 1 year ago

I took a stab at this: https://github.com/wn2000/libretro-atari800/commit/2f0f8753a6096d5a2fbc2c2dad1eade9e749d8ee

With this change, mouse starts working. But I feel this is just a start. There needs to be more changes to handle abs_x/y inputs, core options to select analog device types, change sensitivity etc.