kodi-game / game.libretro

Libretro compatibility layer for the Kodi Game API
GNU General Public License v2.0
37 stars 26 forks source link

Allow topology to specify device type and subclass #105

Closed garbear closed 1 year ago

garbear commented 1 year ago

Description

This PR allows topology.xml to specify a libretro device type and subclass. The attributes are optional, and if specified will override the values in buttonmap.xml.

The goal is to have a buttonmap like the following:

<?xml version="1.0" encoding="UTF-8"?>
<logicaltopology>
  <port type="controller" id="1">
    <accepts controller="game.controller.genesis.3button"/>
    <accepts controller="game.controller.genesis.6button"/>
    <accepts controller="game.controller.genesis.teamplayer">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" type="RETRO_DEVICE_JOYPAD" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" type="RETRO_DEVICE_JOYPAD" subclass="6"/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" type="RETRO_DEVICE_JOYPAD" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" type="RETRO_DEVICE_JOYPAD" subclass="6"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" type="RETRO_DEVICE_JOYPAD" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" type="RETRO_DEVICE_JOYPAD" subclass="6"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" type="RETRO_DEVICE_JOYPAD" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" type="RETRO_DEVICE_JOYPAD" subclass="6"/>
      </port>
    </accepts>
    <accepts controller="game.controller.genesis.mouse"/>
  </port>
  ...
</logicaltopology>

Motiviation and context

Discussed with @KOPRajs here: https://github.com/kodi-game/controller-topology-project/pull/206#issuecomment-1423039687

How has this been tested?

Compiles successfully.

Test builds: https://github.com/garbear/xbmc/releases

KOPRajs commented 1 year ago

@garbear You probably don't have a build for LibreELEC (32-bit ARM, preferably RK3399), do you?

garbear commented 1 year ago

I can do LE builds, I'll try to pop out a 32 bit RK3399 image

KOPRajs commented 1 year ago

I can do LE builds, I'll try to pop out a 32 bit RK3399 image

Do I need to reflash the whole image to test this or would it be enough to install the game.libretro addon?

garbear commented 1 year ago

I can probably extract the .so file. Or provide an update file that will keep your userdata. I'll see what I end up with after the build.

It might take a day or two to set up my build server again, but I'll post back here when it's done.

garbear commented 1 year ago

@KOPRajs game.libretro-20.3.0.1.zip

It requires the achievements PR to be in the core code build Do you need a game.libretro without?

KOPRajs commented 1 year ago

It requires the achievements PR to be in the core code build. Do you need a game.libretro without?

That's what I was afraid of.

Ok, so here are my testing possibilities:

  1. I've got a test system with the Rockchip RK3399 at work, but it cannot connect 4 controllers (there is no working Bluetooth).
  2. My main system is Amlogic S922X (running CoreELEC 20.0 with the vendor kernel). This one has 4 controllers ready as well as the big screen and the kids are always around and ready to play.

The second system is binary compatible with the first one (both are ARMv8), so it can install and use a library from the RK3399 build, but it is using the stable Nexus 20.0 (no achievements PR there). So yes, if you can provide a game.libretro for ARMv8, which is compatible with Nexus, it would be the easiest way for me to test the new mapping. I can also setup the build system and create the build myself, it will just take some time.

FYI. Current LE can use the compressed image files for update as well. Just place it in the .update folder as usual, it will extract it on its own.

garbear commented 1 year ago

Ask and ye shall receive. game.libretro-20.2.3.1.zip

KOPRajs commented 1 year ago

@garbear I've finally done some testing:

  1. Unfortunately, I don't know any game where I could actually see, if the subclass override works. There are games where you can see, if the connected controller is 3 button or 6 button (e.g. Comix Zone), but I don't know any, that could also use the multitap at the same time.
  2. I've found out, that the Genesis Plus GX doesn't allow mixed controllers connected to the multitap. All controllers connected to any type of multitap need to be of the same type. So do we set the subclass override only for the first controller? The only other way around this I can think of would be to have 4 multitaps (for 3 and 6 button controllers separately).
  3. I've also tested the 4 Way Play multitap (e.g. with FIFA 97). It seems that it is working only when it is connected to the port 2. The real hardware actually connects to both port 1 and port 2 at the same time, but we can't do that in the port setup dialog. We can allow connecting 2 of them, but it would resolve in 8 controllers (only 4 of them working), so I would only allow it for port 2 to avoid frustrated users trying to connect it to port 1 first, where it is not actually doing anything.

Here is my current buttonmap.xml for the Genesis Plus GX:

<?xml version="1.0" encoding="UTF-8"?>
<buttonmap version="2">
  <controller id="game.controller.genesis.3button" type="RETRO_DEVICE_JOYPAD" subclass="0">
    <feature name="a" mapto="RETRO_DEVICE_ID_JOYPAD_Y"/>
    <feature name="b" mapto="RETRO_DEVICE_ID_JOYPAD_B"/>
    <feature name="c" mapto="RETRO_DEVICE_ID_JOYPAD_A"/>
    <feature name="start" mapto="RETRO_DEVICE_ID_JOYPAD_START"/>
    <feature name="mode" mapto="RETRO_DEVICE_ID_JOYPAD_SELECT"/>
    <feature name="up" mapto="RETRO_DEVICE_ID_JOYPAD_UP"/>
    <feature name="down" mapto="RETRO_DEVICE_ID_JOYPAD_DOWN"/>
    <feature name="right" mapto="RETRO_DEVICE_ID_JOYPAD_RIGHT"/>
    <feature name="left" mapto="RETRO_DEVICE_ID_JOYPAD_LEFT"/>
  </controller>
  <controller id="game.controller.genesis.6button" type="RETRO_DEVICE_JOYPAD" subclass="1">
    <feature name="a" mapto="RETRO_DEVICE_ID_JOYPAD_Y"/>
    <feature name="b" mapto="RETRO_DEVICE_ID_JOYPAD_B"/>
    <feature name="c" mapto="RETRO_DEVICE_ID_JOYPAD_A"/>
    <feature name="x" mapto="RETRO_DEVICE_ID_JOYPAD_L"/>
    <feature name="y" mapto="RETRO_DEVICE_ID_JOYPAD_X"/>
    <feature name="z" mapto="RETRO_DEVICE_ID_JOYPAD_R"/>
    <feature name="start" mapto="RETRO_DEVICE_ID_JOYPAD_START"/>
    <feature name="mode" mapto="RETRO_DEVICE_ID_JOYPAD_SELECT"/>
    <feature name="up" mapto="RETRO_DEVICE_ID_JOYPAD_UP"/>
    <feature name="down" mapto="RETRO_DEVICE_ID_JOYPAD_DOWN"/>
    <feature name="right" mapto="RETRO_DEVICE_ID_JOYPAD_RIGHT"/>
    <feature name="left" mapto="RETRO_DEVICE_ID_JOYPAD_LEFT"/>
  </controller>
  <controller id="game.controller.genesis.mouse" type="RETRO_DEVICE_MOUSE">
    <feature name="left" mapto="RETRO_DEVICE_ID_MOUSE_LEFT"/>
    <feature name="right" mapto="RETRO_DEVICE_ID_MOUSE_RIGHT"/>
    <feature name="middle" mapto="RETRO_DEVICE_ID_MOUSE_WHEELDOWN"/>
    <feature name="start" mapto="RETRO_DEVICE_ID_MOUSE_MIDDLE"/>
    <feature name="pointer" mapto="RETRO_DEVICE_MOUSE"/>
  </controller>
  <controller id="game.controller.genesis.4wayplay" type="RETRO_DEVICE_JOYPAD" subclass="3"/>
  <controller id="game.controller.genesis.teamplayer" type="RETRO_DEVICE_JOYPAD" subclass="5"/>
</buttonmap>

And the topology.xml:

<?xml version="1.0" encoding="UTF-8"?>
<logicaltopology>
  <port type="controller" id="1" connectionPort="0">
    <accepts controller="game.controller.genesis.3button"/>
    <accepts controller="game.controller.genesis.6button"/>
    <accepts controller="game.controller.genesis.mouse"/>
    <accepts controller="game.controller.genesis.teamplayer">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
    </accepts>
  </port>
  <port type="controller" id="2" connectionPort="1">
    <accepts controller="game.controller.genesis.3button"/>
    <accepts controller="game.controller.genesis.6button"/>
    <accepts controller="game.controller.genesis.mouse"/>
    <accepts controller="game.controller.genesis.4wayplay">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button subclass="4""/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
    </accepts>
    <accepts controller="game.controller.genesis.teamplayer">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button"/>
        <accepts controller="game.controller.genesis.6button"/>
      </port>
    </accepts>
  </port>
</logicaltopology>

Please note that the 4 Way Play is only allowed in port 2 and that only the first controller in every multitap can set the subclass override.

This way it seems to cover all use cases I have tried:

  1. 2x 3 button controller as default for most of the games.
  2. 2x 6 button controller for the 6 button games.
  3. The 4 Way Play controller in port 2 (with port 1 having no effect at all) for EA games.
  4. Any combination of any multitap type for Bomberman (every combination worked in every port).
  5. 1x 3 button controller in port 1 and the Team Player in port 2 for J-Cart games (this is the only combination that worked).

The J-Cart is a special format of game cartridge with 2 more controller ports on the cartridge itself. I've tested Micro Machines (J-Cart) and it works for 4 players with the above settings.

The limits of the current solution:

  1. The 4 Way Play is somewhat "hidden" under the port 2 and when it is selected, the port 1 setting is having no effect at all (it is being overridden by the 4 Way Play in port 2).
  2. Only the first controller connected to multitap can override the controller type.

With all that being said, it works and it covers every kind of setup I can think of, so I'm happy with it.

garbear commented 1 year ago

Unfortunately, I don't know any game where I could actually see, if the subclass override works.

Our choices are either to merge it on faith, or find a game to test. Do you know of any game databases that would let us find a game to test?

I've found out, that the Genesis Plus GX doesn't allow mixed controllers connected to the multitap… The only other way around this I can think of would be to have 4 multitaps (for 3 and 6 button controllers separately).

Let's not contort the GUI to handle idiosyncratic emulators. Requiring all controllers to be of the same time is a simple constraint to add. I'll code up a PR for this when I get a chance.

garbear commented 1 year ago

The real hardware actually connects to both port 1 and port 2 at the same time, but we can't do that in the port setup dialog.

I introduced a feature called "player limit" to solve this problem. fceumm specifies a player limit of 4. When a NES 4 Score is connected, the second controller (now the 5th port, because the game API is depth first) exceeds the four player limit and isn't shown. You can see the approach in https://github.com/kodi-game/game.libretro.fceumm/pull/7.

However, I discovered the player limit was broke in the Port Dialog, so I prepared a quick PR for that: https://github.com/garbear/xbmc/commit/68356db611bec963b4785d5d2728173fc976f2b3. I'll send this upstream.

Would the player limit approach work for genesis?

garbear commented 1 year ago

I've found out, that the Genesis Plus GX doesn't allow mixed controllers connected to the multitap. All controllers connected to any type of multitap need to be of the same type. So do we set the subclass override only for the first controller?

I think we should set subclass for every controller and then at the multitap level specify that only matching controllers are allowed.

In the UI, you could select any of the children and get an option to change from 3button to 6button, and whichever you select will cause all 4 ports to change. That way they're always in sync.

Something like this:

<?xml version="1.0" encoding="UTF-8"?>
<logicaltopology>
  <port type="controller" id="1" connectionPort="0">
    <accepts controller="game.controller.genesis.3button"/>
    <accepts controller="game.controller.genesis.6button"/>
    <accepts controller="game.controller.genesis.mouse"/>
    <accepts controller="game.controller.genesis.teamplayer" matchingControllers="true">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
    </accepts>
  </port>
  <port type="controller" id="2" connectionPort="1">
    <accepts controller="game.controller.genesis.3button"/>
    <accepts controller="game.controller.genesis.6button"/>
    <accepts controller="game.controller.genesis.mouse"/>
    <accepts controller="game.controller.genesis.4wayplay" matchingControllers="true">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="3"/>
        <accepts controller="game.controller.genesis.6button" subclass="4"/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="3"/>
        <accepts controller="game.controller.genesis.6button" subclass="4"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="3"/>
        <accepts controller="game.controller.genesis.6button" subclass="4"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="3"/>
        <accepts controller="game.controller.genesis.6button" subclass="4"/>
      </port>
    </accepts>
    <accepts controller="game.controller.genesis.teamplayer" matchingControllers="true">
      <port type="controller" id="1" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="2" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="3" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
      <port type="controller" id="4" connectionPort="-1" forceConnected="true">
        <accepts controller="game.controller.genesis.3button" subclass="5"/>
        <accepts controller="game.controller.genesis.6button" subclass="6"/>
      </port>
    </accepts>
  </port>
</logicaltopology>
garbear commented 1 year ago

Another possible solution is how I solved Nestopia: Always force a multitap to be attached, and four independent controllers can be used at all times. This is the approach I took in https://github.com/kodi-game/game.libretro.nestopia/pull/12.

KOPRajs commented 1 year ago

Do you know of any game databases that would let us find a game to test?

There are games with the 6 button controller support listed here: https://segaretro.org/Six_Button_Control_Pad_(Mega_Drive) You would have to find some, that also supports more than 2 players through multitap (e.g. some of them supports more players, but they are turn based and so using only 1 controller for all players). Then get the game and try, if the gameplay actually changes relative to the controller type being set (3 vs. 6 buttons). It might be not so easy in some games (especially if you don't know the game). The best scenario is when the game explicitly shows the connected controller type (usually in the player selection or in the control options).

Requiring all controllers to be of the same type is a simple constraint to add. I'll code up a PR for this when I get a chance.

I'm not sure if this is actually needed. Currently the internal type is being set for all controllers by the controller 1, but you can still choose different button mapping for individual players (I have different mappings set for the 3 button and for the 6 button controllers). We would loose this ability if we force all controllers being the same type.

Would the player limit approach work for genesis?

I guess it depends on what would you pass to libretro for the "hidden" controller. The following configuration doesn't work (the game gets no input at all): Port 1 - 4 Way Play (4 controllers) Port 2 - Disconnected

This works: Port 1 - Disconnected (or a 3 button controller or whatever) Port 2 - 4 Way Play (4 controllers)

Also there is actually no 4 player limit. Genesis supports up to 8 players using 2 Team Players, the 4 player limit applies only for the 4 Way Play adapter.

If we really have to deal with this "cosmetic" issue, we can tell the 4 Way Play to disable the port 1 (or even show the 4 Way Play in the disabled port) by setting something like this: <accepts controller="game.controller.genesis.4wayplay" occuppiedConnectionPort="0,1">

Port 1 (grayed out or hidden) - Empty (or 4 Way Play) Port 2 - 4 Way Play (4 controllers)

But I think it is too much hassle for a very little cosmetic benefit. I'm happy with how it works now. The biggest issue is to properly test the subclass override option.

garbear commented 1 year ago

but you can still choose different button mapping for individual players (I have different mappings set for the 3 button and for the 6 button controllers)

How does this work for you? What are the maps, and should they be default?

I'm happy with how it works now.

I think this approach is perfectly fine for the UI.

For the XML, I want to capture the complete topology. Unless it's too much work, can you list all the possibilities? And the expected ports of the libretro API?

especially if you don't know the game

This is my main issue, growing up I had to sneak over to a friend's house to play his SNES and Genesis so I didn't get much exposure to that generation. A little older I got a car and unlimited freedom but by then we both had N64s.

KOPRajs commented 1 year ago

How does this work for you? What are the maps?

Both mappings are based on a suggestions from users in Retroarch forum:

6 buttons: A->A B->B C->R X->X Y->Y Z->L

That is the current default and it seems to be the best for 6 button games so lets keep it.

3 buttons: A->X B->A C->B

For a 3 button games lets keep it as close to the original ergonomy as possible by using only the face buttons.

When playing a 4 player game which supports 3 buttons only (which is the majority of them), currently every player can choose wheter he wants to use "X, A, B" or "A, B, R" on the multitap. My kids are already used to plant a bomb in Bomberman by "R", while I prefer to use "B".

And should they be default?

I plan to use them in the "base buttonmap" for the default translation from controller.default to other controllers. Again, we need to keep the current buttonmap.xml of the emulator itself the same as it is defined in the libretro. The new default can be set by the "most popular" mapping in peripheral.joystick.

Unless it's too much work, can you list all the possibilities?

I haven't had a Genesis back in the 90's (I was also sneaking to friends house to play), so I'm exploring the possibilities as we speak, but here's what I've found so far:

  1. You need flat topology for games without the multitap support, otherwise you get no input for player 2.
  2. Some games do support the 6 button controllers, but the majority of all games is designed for 3 buttons only. However the 6 button controller is backward compatible with 3 button games.
  3. The Team Player can be connected anywhere and it allows for up to 8 players.
  4. The 4 Way Play currently has to be set on port 2 and it overrides the setting of port 1. Possibly if we set it to port 1 and don't set anything for port 2, it should work as well (guessing from the source code), but it can't be done with the current implementation of the port setup dialog (to "do not set port 2" is different from setting it to "Disconnected").
garbear commented 1 year ago

The new default can be set by the "most popular" mapping in peripheral.joystick.

Yes, and my intention is for all buttonmaps to have a single profile, and one buttonmap to have all profiles. The most popular of a plurality of 1 wins

The 4 Way Play currently has to be set on port 2 and it overrides the setting of port 1. Possibly if we set it to port 1 and don't set anything for port 2, it should work as well (guessing from the source code), but it can't be done with the current implementation of the port setup dialog (to "do not set port 2" is different from setting it to "Disconnected").

From a preservation standpoint, I'd like the XML to look like the historical connections. Your visualization of the Port Dialog is fine too. I'll try to figure out a way to map the historical topology to your Port Dialog view, and might come up with a different approach depending on what I discover.

garbear commented 1 year ago

@KOPRajs Any progress in mapping every controller? I shipped a base button map in my last round of builds and it was pretty quick to create, though I'd like your special touch in case I mixed up some buttons.

KOPRajs commented 1 year ago

@garbear Sorry, I'm out for one more week from now. But I can look at the provided base button map at least.

KOPRajs commented 1 year ago

@garbear I've briefly checked the base buttonmap (https://github.com/garbear/peripheral.joystick/commit/e853d762429b9f919130cd4b4212b00ee39ccece).

Looks good, both 3 and 6 button Genesis controllers, SMS controller, NES and SNES controllers, all of them preserves the ergonomic mapping as suggested.

garbear commented 1 year ago

I took the Genesis mappings from https://github.com/kodi-game/controller-topology-project/pull/206 so they should be good.

I'll merge my not-fully-complete map for now, so there's no pressure on uploading your complete map.

I had problems with some controllers that were ergonomically incompatible, like the tv remote:

tv remote

For this we probably want a logical mapping instead of a physical one, because you expect A to be select and B to be back, regardless of whether it's a 360 or SNES controller. What do you think?

KOPRajs commented 1 year ago

For this we probably want a logical mapping instead of a physical one, because you expect A to be select and B to be back, regardless of whether it's a 360 or SNES controller. What do you think?

I'm not sure if I understand. IMHO the ergonomic vs. logical mapping only applies to mapping for the game specific controller profiles to the default Xbox controller. The TV remote usually acts like a keyboard and not like a joystick.

garbear commented 1 year ago

IMHO the ergonomic vs. logical mapping only applies to mapping for the game specific controller profiles to the default Xbox controller. The TV remote usually acts like a keyboard and not like a joystick.

I think that's my point. Keyboards act logically (doesn't matter where the keys are) so the challenge is how to map a controller to the TV Remote controller profile. This question applies to keyboards as well.

The challenge is mapping between keyboards and controllers, and I don't really have a solution for that right now. So I guess I just leave TV remote and the keyboards out of the universal map.

garbear commented 1 year ago

At this point, I've gotten everything into v20.1 and we've done the release. I think the only two items left are this PR and the button maps for the genesis controllers. Can you PR the files you've made?

KOPRajs commented 1 year ago

@garbear Which files do you mean? The topology.xml for the Genesis emulators?

garbear commented 1 year ago

Yes, topology.xml and buttonmap.xml

KOPRajs commented 1 year ago

I will do it, but it'll take few days, as I'm currently out-of-order due to some kind of sickness.

garbear commented 1 year ago

Nothing's blocked so take your time and be less sick soon!

garbear commented 1 year ago

@KOPRajs Got time to PR? If not you can just paste the XML here and I'll take care of everything

KOPRajs commented 1 year ago

I'll make the PRs this week, sorry for being late. I got a little excited by the possibility to get the shaders working on my main HW (Amlogic), so I played with that for a while.

garbear commented 1 year ago

Thanks to a forum report, I discovered a c/p error, which I've fixed:

--- a/src/input/ControllerTopology.cpp
+++ b/src/input/ControllerTopology.cpp
@@ -576,7 +576,7 @@ libretro_device_t CControllerTopology::TypeOverride(const std::vector<Controller

 libretro_subclass_t CControllerTopology::SubclassOverride(const std::string& portAddress, const std::string& controllerId) const
 {
-  return TypeOverride(m_ports, JoinAddress(portAddress, controllerId));
+  return SubclassOverride(m_ports, JoinAddress(portAddress, controllerId));
 }

 libretro_subclass_t CControllerTopology::SubclassOverride(const std::vector<PortPtr>& ports, const std::string &controllerAddress)
@@ -613,7 +613,7 @@ libretro_subclass_t CControllerTopology::SubclassOverride(const std::vector<Cont
       });

     if (it != controllers.end())
-      return (*it)->type;
+      return (*it)->subclass;
   }
   else
   {
garbear commented 1 year ago

I have a report that games work with the latest fix: https://forum.kodi.tv/showthread.php?tid=373721&pid=3159734#pid3159734

Merging now, to avoid having to rebase this change often. In the future, if we never need to configure ports per-topology, support will exist in the Omega branch.

garbear commented 1 year ago

@KOPRajs Got time to PR the genesis maps? If you can't until later this summer, no worries.