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

Add support for more controllers: maracas (Samba de Amigo), Pop'n Music, ... #681

Closed
AltoRetrato opened this issue Jul 3, 2022 · 16 comments
Labels
enhancement New feature or request good first issue Good for newcomers input Related to input controllers and devices

Comments

@AltoRetrato
Copy link
Contributor

Hi there!

On a quick glance at the source of flycast, it seems to support several Dreamcast peripherals (even lightguns!), but it doesn't seem to support maracas for Samba de Amigo and Samba de Amigo: Ver. 2000 or the Pop'n Music controller.


(Images from https://bordersdown.net/content/400-Dreamcast-Peripherals-and-Hardware-List-with-photos&new_comment)

Would it be possible to add support for at least the maracas controllers in flycast?

Of course, there is also the issue of connecting those peripherals to the computer running flycast, but they can also be emulated with other devices (e.g., VR controllers).

@AltoRetrato AltoRetrato added the enhancement New feature or request label Jul 3, 2022
@AltoRetrato AltoRetrato changed the title Add support for more specialty controllers: maracas (Samba de Amigo), Pop'n Music, ... Add support for more controllers: maracas (Samba de Amigo), Pop'n Music, ... Jul 3, 2022
@flyinghead flyinghead added good first issue Good for newcomers input Related to input controllers and devices labels Jul 3, 2022
@AltoRetrato
Copy link
Contributor Author

AltoRetrato commented Apr 17, 2023

If possible, I would like to get some guidance about how I could implement maracas support in Flycast.

I read the Samba de Amigo US Dreamcast US manual and the maracas US Patent US 7331856 B1. Each maraca has (patent pg 31, pg. 60 col 18 line 37, pg 62 col 22 line 16):

  • 1 button
  • 1 internal vibration switch
  • Y & X (height and lateral positions)

This DC Emulation post gives more details:

  • left maraca position shows up as 1st analog stick, right maraca is 2nd
  • maracas position range from 0, 0 (bottom left) to 255, 255 (top right)
  • right maraca shake = A button
  • left maraca shake = B button
  • right maraca button = Start
  • left maraca button = ?

I'm new to Libretro, so I read all the Libretro Docs for Developers. From that, I think maracas can be implemented as an Analog RetroPad (RETRO_DEVICE_ANALOG).

Now I'm reading the files in https://github.com/flyinghead/flycast/tree/master/core/hw/maple , and I'm wondering how much low level information I need to know / get from the maple bus about the maracas - and how to get it.

Could / should I write a program using DreamSDK / KallistiOS to get that info? What exactly would I need to get? (maple function ID, device name, capabilities, ...)

In which branch should I work / make a PR?

Any comments or suggestions are welcome. Thanks!

@AltoRetrato
Copy link
Contributor Author

And I think I've found another GPL project that might have most (or all) the information needed to support maracas and fishing rod: 240p Test Suite - e.g., see https://github.com/ArtemioUrbina/240pTestSuite/blob/master/240psuite/Dreamcast/PVR/controller.c

@flyinghead
Copy link
Owner

flyinghead commented Apr 17, 2023

This is the document you need for this task:
https://github.com/Kochise/dreamcast-docs/blob/master/CONTROLR/DOCS/14_marah099e.doc

Some suggestions:

  • Maracas will need to be supported in both standalone and libretro, so it might be easier to make it work with standalone first, then add support and button/axes mapping for libretro.
  • Please fork the devbranch and make a PR for this branch.
  • The tasks to do this implementation are:
    • Add a new maple device type for maracas in hw/maple/maple_cfg.h (Do NOT change existing types, so add it between MDT_None and MDT_Count)
    • Add a new device class in maple_dev.cpp for the maracas. Derive from maple_base or perhaps even maple_sega_controller (after all maracas is just a controller with analog axes and buttons)
    • Add a new savestate version in serialize.h (which should be V36 and update Current to point to it). This is required to avoid older flycast versions to crash if they load a savestate with a maracas attached.
    • Add maracas to the list of maple devices available in rend/gui.cpp

At this point maracas should work in standalone. Then for libretro you need to add maracas to the list of controller available (shell/libretro.cpp) probably as a subtype of retropad (like twin stick and ascii stick), and do the button and axes mapping (RETRO_DEVICE_ANALOG and RETRO_DEVICE_JOYPAD)

@AltoRetrato
Copy link
Contributor Author

I got the Pop'n Music functioning properly (I guess), and I'm trying to implement other controllers as well.

I just could not understand one part so far. In core\hw\maple\maple_devs.cpp, how did you get the value 0xF901?

struct maple_sega_controller: maple_base
{
	virtual u32 transform_kcode(u32 kcode)
	{
		mutualExclusion(kcode, DC_DPAD_UP | DC_DPAD_DOWN);
		mutualExclusion(kcode, DC_DPAD_LEFT | DC_DPAD_RIGHT);
		return kcode | 0xF901;		// mask off DPad2, C, D and Z;
	}

@AltoRetrato
Copy link
Contributor Author

The Maracas have four analog axes (two for each maraca)... I can map two axes (Thumbstick U/D & &L/R) to a controller, and they seem to be working. Is there any way to map the other two axes?

@flyinghead
Copy link
Owner

The F901 value is used to force some buttons in the released state. The standard dreamcast controller doesn't have a second DPad or C, D and Z buttons. Reporting these buttons as pressed could confuse some games.
You can look at other classes derived from maple_sega_controller and they use a different mask: F800 for ascii stick (no DPad2 and no D button), 0101 for twinstick (no C or Z button)
The maracas likely have a different set of buttons so you may have to figure out the proper mask.

There are 6 analog axes slots in the maple standard. The dreamcast controller puts the analog stick values in the first 2 slots and the trigger values in the following. The last 2 aren't used. The Atomiswave controller has 4 analog axes and puts them in slots 3 to 6 (the first 2 aren't used).
According to the Maracas technical specs, you should do the same and put the analog axes values in slots 3 to 6.

@AltoRetrato
Copy link
Contributor Author

Thanks!

I already knew the function of the mask, but I was making confusion with the buttons and could not get the correct values. Doh!

But I should have been clearer about the analog mapping: I want to know how can I use the Flycast GUI to map a PC controller axes to virtual Dreamcast axes. I can map the Left or Right stick of the PC controller to the Dreamcast "Thumbstick". By changing "Dreamcast Controls" to "Arcade Controls" I can also map to the "R.Thumbstick".

image

Using the 240p Test Suite, I can see the two analog axes, but only the left one is working.

image

BTW, I just tested the original Pop'n Music controller with two different PC adapters and the Flycast on Windows 11:

  • The EMS Trio Linker Plus II requires a driver. It works mostly fine, except U+D or L+R are not registered when simultaneously pressed. Seems to be an adapter or driver issue, I might try a workaround with vjoystick + triolinker-vjoy.
  • The Mayflash DC Controller Adapter for PC USB works on Windows 11 without any drivers. It allows all buttons to be pressed simultaneously, but it doesn't register the last controller button (C). Also an adapter issue.

Despite the issues, it was pretty cool! Thanks for all the help! :)

@flyinghead
Copy link
Owner

You need to make changes to the UI in order for the Right Thumbstick to appear in console mode and be able to bind it. Right now it doesn't appear because none of the supported Dreamcast controllers has a right joystick, until now.
SImply copy the DC_AXIS2_* entries from arcadeButtons to dcButtons in rend/gui.cpp.

@AltoRetrato
Copy link
Contributor Author

Maracas are working! I haven't tested them extensively (yet!), but the only "issue" I've seem so far is that they are only detected / recognized in Samba de Amigo and Samba de Amigo Ver. 2000 when connected to ports A or B (even though they work in the 240p Test Suite on ports C & D).

Now I'm trying to implement support for the fishing controller, but it has built-in vibration. Do you have any tips on how I can do it?

@flyinghead
Copy link
Owner

flyinghead commented Apr 25, 2023

This is the spec document for the fishing controller: https://github.com/Kochise/dreamcast-docs/blob/master/CONTROLR/DOCS/10_tsurih080e.doc
It includes a vibration function which should be similar to the purupuru/vibration pack (see maple_sega_purupuru in maple_devs.cpp)

@AltoRetrato
Copy link
Contributor Author

AltoRetrato commented Apr 25, 2023

I've seen the document and the maple_sega_purupuru before, but the fishing controller have two device IDs, type FT0 (the "device", that I've already implemented) and FT8 ("expansion device"), and the dma function in the structure seems to be relative to a single device.

So one way to solve it (I guess) would be creating a purupuru in createDreamcastDevices() (maple_cfg.cpp):

		case MDT_FishingController:
			mcfg_Create(MDT_FishingController, bus, 5);
			mcfg_Create(MDT_PurupuruPack, bus, 0);
			break;

... but I'm not sure if that is the correct way.

Another issue is that it has 6 analog axes:

3rd : Analog axis 1 (A1) data. Reel handle.
4th : Analog axis 2 (A2) data. Acceleration sensor Z axis.
5th : Analog axis 3 (A3) data. Analog key Xa axis.
6th : Analog axis 4 (A4) data. Analog key Ya axis.
7th : Analog axis 5 (A5) data. Acceleration sensor X axis.
8th : Analog axis 6 (A6) data. Acceleration sensor Y axis.

PlainJoystickState has 4 axes and 2 triggers.

I can map A1 (reel) to the left or right trigger, since it outputs 0 at rest, but the remaining 5 axes range from 0 to 0xFF with 0x80 at rest. I could hack one axis (e.g., Z) to the right trigger, but it would eliminate motion detection in one direction in that axis.

u32 z;
if (index == 1) {
	// hack: this eliminates motion in the Z axis in the backward direction!
	z = 0x80 + pjs.trigger[PJTI_L];
	return z > 0xFF ? 0xFF : z;		// A2: acceleration sensor Z
}

A "cleaner" solution could be adding a 3 axes acceleration sensor to the PlainJoystickState.

What would you suggest?

@flyinghead
Copy link
Owner

None of the maple devices currently uses it but the function type is sent with the GetCondition command. Call r32() when handling MDCF_GetCondition and compare with MFID_0_Input or MFID_8_Vibration to figure out which function is called.
To avoid code duplication you can use a private maple_sega_purupuru instance to which you delegate the vibration features.

Regarding the missing full axis in PlainJoystickState, you could add it where needed (PlainJoystickState, UI, InputMapping, etc.) and let the user map it the way he wants. Having additional generic axes could help some arcade games that need more than 4.

@flyinghead
Copy link
Owner

I added support for vibration to the fishing controller. Contrary to what I wrote above, the vibration device is distinct from the input controller and has its own maple bus address. So it was just a matter of adding a vibration pack at this address along with the fishing controller. See 231a1b6

@AltoRetrato
Copy link
Contributor Author

Awesome! Thank you! :D

Now I'll soon take a look at the libretro interface.

@AltoRetrato
Copy link
Contributor Author

Thank you SO MUCH for your help and patience! Thanks to you, today I played Samba de Amigo in VR (my first VR project as well) and it felt just like old days (really old, almost 20 years ago)! 😄 I'll give it some polish and publish it later for anyone who wants to give it a try.

And with #1123 , I think we can close this!

@flyinghead
Copy link
Owner

Thanks a million for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers input Related to input controllers and devices
Projects
None yet
Development

No branches or pull requests

2 participants