kodi-game / game.libretro.pcsx-rearmed

PCSX ReARMed game client for XBMC
https://github.com/libretro/pcsx_rearmed
4 stars 11 forks source link

buttonmap #2

Closed zach-morris closed 8 years ago

zach-morris commented 8 years ago

buttonmap.xml mapping error:

        <feature name="l1" mapto="l"/>
        <feature name="r1" mapto="r"/>
        <feature name="l2" mapto="l2"/>
        <feature name="r2" mapto="r2"/>

should be

        <feature name="l1" mapto="leftbumper"/>
        <feature name="r1" mapto="rightbumper"/>
        <feature name="l2" mapto="lefttrigger"/>
        <feature name="r2" mapto="righttrigger"/>
garbear commented 8 years ago

The "mapto" options are hard-coded into the libretro API. The string-to-libretro mapping is:


  if (strFeatureName == "a")            return RETRO_DEVICE_ID_JOYPAD_A;
  if (strFeatureName == "b")            return RETRO_DEVICE_ID_JOYPAD_B;
  if (strFeatureName == "x")            return RETRO_DEVICE_ID_JOYPAD_X;
  if (strFeatureName == "y")            return RETRO_DEVICE_ID_JOYPAD_Y;
  if (strFeatureName == "start")        return RETRO_DEVICE_ID_JOYPAD_START;
  if (strFeatureName == "select")       return RETRO_DEVICE_ID_JOYPAD_SELECT;
  if (strFeatureName == "up")           return RETRO_DEVICE_ID_JOYPAD_UP;
  if (strFeatureName == "down")         return RETRO_DEVICE_ID_JOYPAD_DOWN;
  if (strFeatureName == "right")        return RETRO_DEVICE_ID_JOYPAD_RIGHT;
  if (strFeatureName == "left")         return RETRO_DEVICE_ID_JOYPAD_LEFT;
  if (strFeatureName == "l")            return RETRO_DEVICE_ID_JOYPAD_L;
  if (strFeatureName == "r")            return RETRO_DEVICE_ID_JOYPAD_R;
  if (strFeatureName == "l2")           return RETRO_DEVICE_ID_JOYPAD_L2;
  if (strFeatureName == "r2")           return RETRO_DEVICE_ID_JOYPAD_R2;
  if (strFeatureName == "l3")           return RETRO_DEVICE_ID_JOYPAD_L3;
  if (strFeatureName == "r3")           return RETRO_DEVICE_ID_JOYPAD_R3;
  if (strFeatureName == "leftstick")    return RETRO_DEVICE_INDEX_ANALOG_LEFT;
  if (strFeatureName == "rightstick")   return RETRO_DEVICE_INDEX_ANALOG_RIGHT;
  if (strFeatureName == "leftmouse")    return RETRO_DEVICE_ID_MOUSE_LEFT;
  if (strFeatureName == "rightmouse")   return RETRO_DEVICE_ID_MOUSE_RIGHT;
  if (strFeatureName == "trigger")      return RETRO_DEVICE_ID_LIGHTGUN_TRIGGER;
  if (strFeatureName == "cursor")       return RETRO_DEVICE_ID_LIGHTGUN_CURSOR;
  if (strFeatureName == "turbo")        return RETRO_DEVICE_ID_LIGHTGUN_TURBO;
  if (strFeatureName == "pause")        return RETRO_DEVICE_ID_LIGHTGUN_PAUSE;
  if (strFeatureName == "start")        return RETRO_DEVICE_ID_LIGHTGUN_START;

so each "mapto" must be one of those.

The libretro API says:

The JOYPAD is called RetroPad. It is essentially a Super Nintendo controller,
but with additional L2/R2/L3/R3 buttons, similar to a PS1 DualShock.
The placement of these is equivalent to placements on the Super Nintendo controller.
L2/R2/L3/R3 buttons correspond to the PS1 DualShock.

From this, can you figure out which buttons correspond to libretro's L, R, L2, R2, L3, R3? I made a guess, but apparently wasn't correct.

zach-morris commented 8 years ago

OK, I think I understand it all now. Thats somewhat confusing... Anyway, here's what I've found: strings.po should be updated to include:

msgctxt "#30015"
msgid "R Thumb Button"
msgstr ""

msgctxt "#30016"
msgid "L Thumb Button"
msgstr ""

or whatever english text you think makes sense.

layout.xml for pcsx-rearmed should be updated to:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<layout name="PS" label="30000" image="layout.png">
    <face>
        <button name="cross" type="digital" label="30001"/>
        <button name="circle" type="digital" label="30002"/>
        <button name="square" type="digital" label="30003"/>
        <button name="triangle" type="digital" label="30004"/>
        <button name="start" type="digital" label="30005"/>
        <button name="select" type="digital" label="30006"/>
        <button name="up" type="digital" label="30007" direction="up"/>
        <button name="down" type="digital" label="30008" direction="down"/>
        <button name="right" type="digital" label="30009" direction="right"/>
        <button name="left" type="digital" label="30010" direction="left"/>
        <button name="r3" type="digital" label="30015"/>
        <button name="l3" type="digital" label="30016"/>
    </face>
    <shoulder>
        <button name="leftbumper" type="digital" label="30011"/>
        <button name="rightbumper" type="digital" label="30012"/>
    </shoulder>
    <triggers>
        <button name="lefttrigger" type="digital" label="30013"/>
        <button name="righttrigger" type="digital" label="30014"/>
    </triggers>
</layout>

buttonmap.xml should be updated to:

<?xml version="1.0" encoding="UTF-8"?>
<buttonmap>
    <controller id="game.controller.ps" type="analog">
        <feature name="cross" mapto="b"/>
        <feature name="circle" mapto="a"/>
        <feature name="square" mapto="y"/>
        <feature name="triangle" mapto="x"/>
        <feature name="start" mapto="start"/>
        <feature name="select" mapto="select"/>
        <feature name="up" mapto="up"/>
        <feature name="down" mapto="down"/>
        <feature name="right" mapto="right"/>
        <feature name="left" mapto="left"/>
        <feature name="leftbumper" mapto="l"/>
        <feature name="rightbumper" mapto="r"/>
        <feature name="lefttrigger" mapto="l2"/>
        <feature name="righttrigger" mapto="r2"/>
        <feature name="l3" mapto="l3"/>
        <feature name="r3" mapto="r3"/>
    </controller>
</buttonmap>

Tested this change with your latest OSX build and works. All buttons appear to be mapped in game correctly with this update.

Thanks!

garbear commented 8 years ago

To be consistent with game.controller.default, I named them "Left thumb" and "Right thumb". Some people were kind of confused by that, so we could certainly change it. Would "R thumb button" or "R. thumb button" be better in the GUI?

garbear commented 8 years ago

Also, there's a missing piece to this puzzle. From game.libretro,


    // Handle default controller unless it appears in buttonmap.xml
    if (strControllerId == DEFAULT_CONTROLLER_ID && GetControllerNode(DEFAULT_CONTROLLER_ID) == NULL)
    {
      if (strFeatureName == "a")            return RETRO_DEVICE_ID_JOYPAD_A;
      if (strFeatureName == "b")            return RETRO_DEVICE_ID_JOYPAD_B;
      if (strFeatureName == "x")            return RETRO_DEVICE_ID_JOYPAD_X;
      if (strFeatureName == "y")            return RETRO_DEVICE_ID_JOYPAD_Y;
      if (strFeatureName == "start")        return RETRO_DEVICE_ID_JOYPAD_START;
      if (strFeatureName == "back")         return RETRO_DEVICE_ID_JOYPAD_SELECT;
      if (strFeatureName == "leftbumber")   return RETRO_DEVICE_ID_JOYPAD_L2;
      if (strFeatureName == "rightbumper")  return RETRO_DEVICE_ID_JOYPAD_R2;
      if (strFeatureName == "leftthumb")    return RETRO_DEVICE_ID_JOYPAD_L;
      if (strFeatureName == "rightthumb")   return RETRO_DEVICE_ID_JOYPAD_R;
      if (strFeatureName == "up")           return RETRO_DEVICE_ID_JOYPAD_UP;
      if (strFeatureName == "down")         return RETRO_DEVICE_ID_JOYPAD_DOWN;
      if (strFeatureName == "right")        return RETRO_DEVICE_ID_JOYPAD_RIGHT;
      if (strFeatureName == "left")         return RETRO_DEVICE_ID_JOYPAD_LEFT;
      if (strFeatureName == "lefttrigger")  return RETRO_DEVICE_ID_JOYPAD_L3;
      if (strFeatureName == "righttrigger") return RETRO_DEVICE_ID_JOYPAD_R3;
      if (strFeatureName == "leftstick")    return RETRO_DEVICE_INDEX_ANALOG_LEFT;
      if (strFeatureName == "rightstick")   return RETRO_DEVICE_INDEX_ANALOG_RIGHT;
    }

That says, "If a game imports game.controller.default and doesn't provide a buttonmap.xml, use this mapping."

That's why, if no buttonmap.xml exists, the game can still receive input. The controller falls back to game.controller.default, and game.libretro knows how to handle this because the buttonmap.xml is hard-coded into the wrapper.

OFC, an add-on can still provide a buttonmap for game.controller.default. game.controller.2048 provides a gimped buttonmap.xml that overrides the hardcoded one so that the game only uses the 6 buttons in the buttonmap file.

zach-morris commented 8 years ago

Shouldn't the above be?

      if (strFeatureName == "lefttrigger")   return RETRO_DEVICE_ID_JOYPAD_L2;
      if (strFeatureName == "righttrigger")  return RETRO_DEVICE_ID_JOYPAD_R2;
      if (strFeatureName == "leftbumper")    return RETRO_DEVICE_ID_JOYPAD_L;
      if (strFeatureName == "rightbumper")   return RETRO_DEVICE_ID_JOYPAD_R;
      if (strFeatureName == "up")           return RETRO_DEVICE_ID_JOYPAD_UP;
      if (strFeatureName == "down")         return RETRO_DEVICE_ID_JOYPAD_DOWN;
      if (strFeatureName == "right")        return RETRO_DEVICE_ID_JOYPAD_RIGHT;
      if (strFeatureName == "left")         return RETRO_DEVICE_ID_JOYPAD_LEFT;
      if (strFeatureName == "leftthumb")  return RETRO_DEVICE_ID_JOYPAD_L3;
      if (strFeatureName == "rightthumb") return RETRO_DEVICE_ID_JOYPAD_R3;

Left and Right thumb work for naming (a picture will eventually say all thats needed I think). As someone who grew up with a PS, L3 and R3 have always been what they've been called for me.

Also, take a look at these images as they do a pretty good job of showing the controller and at the same time showing what they should map to in libretro.

garbear commented 8 years ago

noticed that after I posted ;) https://github.com/kodi-game/game.libretro/commit/9f57c5a

the change made it into the build from last night (I'll upload it soon). When it's up, can you try removing buttonmap.xml? With this change, it should fall back to the libretro mappings in your link and work correctly.

zach-morris commented 8 years ago

No joy. Doesn't seem any buttons work after the buttonmap.xml is not there. Here's a log both with and without the xml, but I don't see anything that shows a problem. Without the xml it also says it's loading the xml, but doesn't say anything to the effect of failing.

Also curious, I restored the XML but it didn't work again right away. I tried remapping and still didn't work. I took a look in my userdata/peripheral_data folder and see a file application_0000_0000.xml that was created that is essentially empty minus the line:

<settings />

I delete it, restart Kodi and the controller magically works again. Not sure if one has anything to do with the other or not...

garbear commented 8 years ago

I forgot, you'll also need to remove the <import name="game.controller.ps"/> line from addon.xml. RetroPlayer fails to fall back to the default otherwise. game.libretro.beetle-psx is still missing this buttonmap stuff, can you test beetle-psx and see if the new default map fixes things?

The peripheral_data thing was weird. My code doesn't use the peripheral_data folder, but it touches some that does, so this might be an issue I need to look into.

zach-morris commented 8 years ago

Still no joy. I see in the log its now only logging events for game.controller.default, but still doesn't work.

garbear commented 8 years ago

The logging in the last build broke slightly in the last refactor, so we can't trust it. The next build will be fixed to not generate so many erroneous "pressed" log messages. The issue might be a little more clear then

zach-morris commented 8 years ago

OK, I tried this latest version, and default mostly worked with buttonmap removed and the import call removed (not sure if you actually changed anything or if I just didn't get it correct the first time). All buttons appear to work except: L1, L2 - both don't register in game R2 doesn't register in game R3 and L3 I couldn't verify in game since I can't seem to find a PS1 game that actually uses them.