Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Maracas & Pop'n Music controllers, WIP for others #1035

Merged
merged 22 commits into from May 29, 2023
Merged

Support for Maracas & Pop'n Music controllers, WIP for others #1035

merged 22 commits into from May 29, 2023

Conversation

AltoRetrato
Copy link
Contributor

@AltoRetrato AltoRetrato commented Apr 26, 2023

I tested Maracas and Pop'n Music controllers, they are detected by their respective games and seem to work fine, as long as they are connected to ports A or B.

Issues:

  • Built and tested only on Windows 11
  • Fishing controller "works" in 240pTestSuite but is not detected by a game (tested with Sega Bass Fishing 2)
  • Racing controller "works" in 240pTestSuite but is not detected by a game (tested with Metropolis Street Racer, Test Drive Le Mans)
  • Densha controller "works" in 240pTestSuite but is not detected by Densha de Go! 2
  • Maracas & Pop'n Music controllers are detected by their respective games only on ports A & B, but should also work on ports C & D (AFAIK)
  • Triggers "2" and "3" (added to support the 4 levers in the racing controller) can be mapped and are saved in the mapping .cfg file, but those mappings are not loaded when Flycast is restarted
  • I have probably missed a few required changes, and might not have implemented a few things the correct way
  • Still missing libretro mappings
  • Dreameye can't see a thing! :P
  • Sega Karaoke not implemented yet!

Please feel free to comment and suggest changes.

Thanks!

@flyinghead
Copy link
Owner

Great work!

@flyinghead
Copy link
Owner

There's a build error with the libretro core. Support for libretro can come in a later PR but it needs to build at least.

@AltoRetrato
Copy link
Contributor Author

Fixed.

@flyinghead
Copy link
Owner

I tested Samba de Amigo and I'm having a hard time navigating the menus. It seems to only react correctly to very small deviations of the thumbstick. I noticed that there is a SetCondition for this device that's not currently implemented. It sets values related to the ultrasonic sensors and one of them is the update interval of anaiog inputs. Samba de Amigo sets it to 2, which means that GetCondition will only return updated analog value every 2 calls. However after implementing this function, it's not really any better.

I tested the Densha de go!2 controller and it's recognized by the corresponding game.
Same for the racing controller with Sega Rally 2, although the triggers (axis 5 and 6) aren't working.

The triggers 2 and 3 bindings aren't being saved because the _2 and _3 suffixes have a special meaning when parsing the mapping file. Renaming them to btn_trigger2_left, btn_trigger2_right, axis_trigger2_left and axis_trigger2_right fixes the issue.

@AltoRetrato
Copy link
Contributor Author

AltoRetrato commented May 2, 2023

I tested Samba de Amigo and I'm having a hard time navigating the menus. It seems to only react correctly to very small deviations of the thumbstick.

I agree that it is a bit hard to navigate the menus, but in part that's just how it works. I don't know if you have used real maraca controllers before, but in my recollection it was kind of hit-and-miss, and a bit frustrating. In this video, you can see someone navigating the menu in the arcade version: https://www.youtube.com/watch?v=HGxzxoAt-QQ

When using maracas, we hold them considerably apart and off center, so their positions are quite distinct. With thumbsticks, they are both centered by default, and that also causes issues navigating the game menu. We should raise or lower the left maraca to select a menu item, but there is no direct connection between the left and right thumbstick with the left and right maraca: the left maraca is any maraca that we hold on the "left side" (or the "leftmost" one). So, in order to navigate the menus without issues, we must point any thumbstick to the left to make it be recognized as the left maraca, and then move it up or down to select an item. Leaving both thumbsticks vertically centered can make the game suddenly change which thumbstick it considers the left maraca.

But another issue seems to be saturation: a small thumbstick displacement reaches 0x00 or 0xFF very soon.

The best way to test the maracas implementation might be with Samba de Amigo Ver. 2000 - it has a volleyball minigame that seems to translates 1:1 the maracas position to the "virtual hands" on screen, and you can "feel" both deadzone and saturation effects. Here's a video I recorded, moving the thumbstick to cover all the play area perimeter: https://youtu.be/q7CyQRe0LUI?t=7

Reducing saturation helps considerably - I just divided the maracas position by two:

	u32 get_analog_axis(int index, const PlainJoystickState &pjs) override {
		if (index < 2 || index > 5)
			return 0;
		u8 maracas_saturation_reduction = 2;
		s32 axis_val = (pjs.joy[index -2] - 0x80) / maracas_saturation_reduction + 0x80;
		if      (axis_val <    0) axis_val = 0;
		else if (axis_val > 0xff) axis_val = 0xFF;
		return axis_val;
	}

Now, in the volleyball minigame, I have to move the thumbstick almost all the way to reach the corners (and menu navigation is less finicky).

The downside is that, if we were using real maracas, we would have to move them twice farther as well, which might not translate to how the game was originally played.

A middle ground (or more versatile solution) might be making maracas_saturation_reduction a configuration setting that the user can adjust to their preference (maybe even a float instead of an integer).

@flyinghead
Copy link
Owner

flyinghead commented May 2, 2023

I must admit I have no experience with real maracas, connected or otherwise ;) so I'll trust your word on this.
Unfortunately I had to bump up the savestate version number on the dev branch so this PR must be updated accordingly.
EDIT: and I also added a new maple device.
Can you also have a look at my other comments? Thank you

@AltoRetrato
Copy link
Contributor Author

Hi there! Sorry for the late reply.

  • I merged my changes to the latest dev and I'll solve the PR conflicts soon.
  • In serialize.h, I already set Current = V37.
  • Pop'n Music controller is detected in the respective games on all ports, so I consider it done! :D
  • Maracas seem to work fine on ports A & B, so I also consider them done! :D
  • Densha de GO! controller:
    • Previously, I was testing the controller on port B and expecting it to navigate game menus, but it seems it only works that way on port A. My bad! I tested it again on port A, and it seems to be detected and working fine.
    • Since it uses a combination of digital keys to function, using a gamepad isn't the best way to test it. Ideally, it should be done by someone with the original controller and a USB adapter...
    • ... but FWIW, I think I'll consider this one done as well! :D
  • Fishing controller:
    • Again, I was testing the controller only on port B, but on port A it was detected and worked mostly fine.
    • I'm sure I haven't fully or correctly implemented it. I'll take another look at the hardware specifications and review the code.
    • Also, I'm not sure I understood how to add a PuruPuru to it. Could you please explain it again?
  • Racing controller:
    • Similarly, when I tested on port A, it was detected and worked fine.
    • Mappings for triggers 2 & 3 are now saved and loaded correctly.
    • To make triggers 2 & 3 work, I simply mapped them to the gamepad's L2+ & R2+. They work fine in 240pTestSuite. Axis 5 & 6 were created to support the fishing controller.
    • The racing controller should have a slot for a VMU, but it doesn't appear in the settings. How can I solve this?
  • Dreameye: I won't fully implement it. It would be nice to be able to run Visual Park (AFAIK, the only software compatible with it) and help preserve another obscure part of videogame history, but I'm not sure if it's worth the hassle or the time (at least for me). Do you want me to leave it as is, remove / comment the code from the UI, or remove/comment out everything?
  • Soon, I'll try to implement the libretro mappings.
  • You've never played with maracas? Of ANY kind? Σ(°ロ°) I hate to break it to you, but playing Samba de Amigo without maracas is like eating pizza without any toppings! It's just not right! XD

@flyinghead
Copy link
Owner

  • Fishing controller: to avoid duplicating code, I was thinking of having a purupuru device as a member variable and delegate to it the vibration functions:
struct maple_fishing_controller: maple_sega_controller
{
	maple_sega_purupuru vibrator;

	void OnSetup() override {
		maple_sega_controller::OnSetup();
		vibrator.Setup(maple_port, player_num);
	};

and there are other changes to do as well.
But this doesn't have to be done in this PR. I'd rather merge this one first without the vibration feature.

  • Racing controller: The number of expansion ports for devices is set in core/rend/gui.cpp at line 1650:
    int port_count = config::MapleMainDevices[bus] == MDT_SegaController ? 2
        : config::MapleMainDevices[bus] == MDT_LightGun || config::MapleMainDevices[bus] == MDT_TwinStick
            || config::MapleMainDevices[bus] == MDT_AsciiStick ? 1
        : 0;

You need to add the racing controller since it has one expansion port.

  • Dreameye, libretro: Again, I would prefer a feature freeze on this PR and merge it as soon as it's ready. Other features and improvements can be done in future PRs.

Thanks

@AltoRetrato
Copy link
Contributor Author

Done?

@AltoRetrato
Copy link
Contributor Author

AltoRetrato commented May 27, 2023

The C/C++ CI / x86_64-w64-mingw32 (pull_request) Failing seems to be the same issued I had after fetching the changes you made in the dev branch: I had to #include <cstdint> in core/cfg/ini.h and core/deps/glslang/glslang/MachineIndependent/SymbolTable.h to be able to build. I started to write a comment here about it but lost it due to a crash.

@flyinghead
Copy link
Owner

Right, I had to do the same changes on the dev branch. I guess something has changed in the build environment.

Can you check my last comments in gamepad_device.cpp and ggpo.cpp?

Then we should be good to go.

@AltoRetrato
Copy link
Contributor Author

Can you check my last comments in gamepad_device.cpp and ggpo.cpp?

Sorry, but I could not find comments in the Files changed (gamepad_device.cpp, ggpo.cpp), and I could not see any comments I thought were relevant in the files in the dev branch (gamepad_device.cpp, ggpo.cpp) - or anywhere else. Could you tell me where are your last comments?

@flyinghead
Copy link
Owner

My comments are in this thread. Simply scroll up:
image

@AltoRetrato
Copy link
Contributor Author

AltoRetrato commented May 28, 2023

Oddly enough, your comments don't appear to me anywhere in this thread (except in your screenshot).

Full thread screenshot

screencapture-github-flyinghead-flycast-pull-1035-2023-05-28-19_24_38

ui: "Axis 2" -> "R.Thumbstick" for consistency with arcade mappings
@flyinghead flyinghead linked an issue May 29, 2023 that may be closed by this pull request
@flyinghead flyinghead merged commit 885714e into flyinghead:dev May 29, 2023
13 checks passed
@flyinghead
Copy link
Owner

I renamed some identifiers for consistency but it's now merged. Thanks!

@AltoRetrato
Copy link
Contributor Author

Awesome! Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants