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

Kempston joystick no longer working since upgrade of Fuse to version 1.6.0 #111

Open
cawidtu opened this issue Jul 7, 2021 · 13 comments
Open

Comments

@cawidtu
Copy link

cawidtu commented Jul 7, 2021

I am running RetroPie, commit 1e26817647d9a97a220eeda1394c955efcbb2c7f, on an Raspberry Pi 4B with Raspbian OS Buster. This framework compiles the latest fuse-libretro core from https://github.com/libretro/fuse-libretro. Unfortunately, the Kempston joystick does not work for me with these builds: for example, in Jet Set Willy the character is constantly jumping; on the other hand, Cursor joystick works fine.

It seems that the issue can be traced back to the upgrade of the underlying fuse to version 1.6.0. When I manually set the desired commit of fuse-libretro to 25d8f17 and compile the emulator, then it shows up as version 1.1.1 in RetroArch and works fine with Kempston. However, commit 21c8ffb, which leads to version 1.6.0 of fuse, already shows the faulty behavior of the Kempston joystick.

@tomconte
Copy link
Collaborator

Hi and thanks for your report!

I have investigated similar reports with Jet Set Willy and Solomon's Key before. The issue happened when using .z80 versions of these games, and the same issue actually appears in standalone Fuse 1.6.0 as well... So, the conclusion was that some change in Fuse broke the .z80 versions of these games, and libretro-fuse is just a port of Fuse to libretro, so the same issues appear in RetroArch.

If you try a .tap or .tzx version it should work fine.

If you believe you are seeing something different, please link to the game files showing the problem!

@zzedmore
Copy link

@tomconte
I think the issue with z80's are that they use the joystick that was selected when the snapshot was saved. There is an option in standalone Fuse called 'snap joystick prompt'. So when loading a z80 it will show a window saying what joystick was used and give an option to select a device to use that joystick type. Not sure if that could be easily implemented into Retroarch ? Maybe force change the joystick when loading z80's ?

@tomconte
Copy link
Collaborator

Thanks @zzedmore, I did not know about that! I will check it out.

@roslof
Copy link

roslof commented Jul 25, 2022

Good day all. Wanted to note that this reported issue still presents huge compatibility issues for a large number of .z80 files. The only workarounds for affected games are 1) to leverage non-.z80 images (which don't exist in some cases) or 2) to use an older version of libretro fuse (1.1.1 25d8f17 as an example works perfectly fine). Any hope we can better understand what changed in this core and resolve the control/incompatibility issue?

EDIT: I read above that this is an upstream issue. Will investigate there. Cheers!

@Chips-fr
Copy link
Contributor

I tried to understand why controls/joystick is globally broken (which cover z80 snapshot case) with retroarch frontend.

At retro_init, the core initialize a default configuration:

retro_set_controller_port_device( 0, RETRO_DEVICE_CURSOR_JOYSTICK );
retro_set_controller_port_device( 1, RETRO_DEVICE_KEMPSTON_JOYSTICK );
retro_set_controller_port_device( 2, RETRO_DEVICE_SPECTRUM_KEYBOARD );

So settings_current.joystick_1_output & input_devices variables will be set with correct/default values.

Then at retro_load_game, in case of z80 file a specific joystick is read from the header and saved in "snap" structure.
This information will be treated by joystick_enabled_snapshot for updating settings_current variable (but no input_devices on which the libretro core rely on. Unsure if it's an issue)

settings_current.joystick_1_output = fuse_type;

Then just before starting emulation, retroarch anyway send it's own default configuration, which overwrite config in the core. I don't think we can avoid it nor tell the frontend that we want a specific default configuration (i haven't found how to do this from the core).
This default configuration is just the RetroPad (default joystick in retroarch frontend) with id 1 set to all the 3 ports. Since the core hasn't redifined this id (but only defined new id), the core store it but this value is not meaningfull for the core so input treatment is completly screwed.

This configuration by retroarch is done by calling 3 times retro_set_controller_port_device with id 1 for the 3 ports.
You can see it the log if you retrieve it by looking at thoses lines:

[libretro INFO] port 0 device 00000001
[libretro INFO] port 1 device 00000001
[libretro INFO] port 2 device 00000001

Due to this, i see at least two end-user issue:
Keyboard doesn't show if start is pressed.
joystick is globally broken.

As a quick workaround, i just add a return if device == 1 at the beginning of retro_set_controller_port_device function if order to avoid the retroarch frontend default configuration. Since device 1 has no meaning in the core implementation it's not big issue for testing to throw such config.
I was able to play the game and the "virtual" keyboard was showing if i press start on my joystick. The game was a V1 Z80 snapshot with a Z80_JOYSTICK_CURSOR_V1 in it's header (i need to find z80 image with other joystick configuration to test more).
This is just a workaround so i'm unsure it could solve all the different configuration but definitly the default configuration from the frontend is a big part of this problem.
I'm thinking of a better solution but will see later...

@Chips-fr
Copy link
Contributor

Chips-fr commented Jan 20, 2023

I continue on the z80 joystick type loading issue but this time with z80 snapshot redefining joystick to kempston on port 1.
I confirm the kempston gets not selected, however i have same kind of issue with core based either on 1.1.1 or 1.6.0.

This non-selection is done for good reason by fuse code: if any of the port emulate already the kempston joystick then it refuse to affect it one more time:

settings_current.joystick_2_output != fuse_type &&

Since we have in default configuration kempston on port 2 it is no more accepted for port 1.
This code was there from the beginning, even in 1.1.1.

Anyway this can be modified:

  • Remove the check so that the two port use same kempston joystick emulation (not the best solution but seems to works for single player games).
  • Switch configuration between port 1 & port 2 in this case (could be confusing anyway for end user).
  • Don't set any joystick default configuration for port 2, just set it to none. Not sure many people plays two players games with two controllers. User could anyway change the configuration in "inputs" retroarch menu. Impact is not big but files inherited from fuse emulator needs to be modified.

@Chips-fr
Copy link
Contributor

Chips-fr commented Jan 29, 2023

I have look at retro distributions and found that some of them force the joystick type to kempston ( recalbox & batocera for example). This config coming from the frontend should be the highest priority.

Anyway i tried to improve the limitation i've seen for snapshot in my repo:

https://github.com/Chips-fr/fuse-libretro

If you keep default retroarch frontend config (which i called "Core defined Input") it will automatically switch the 1st port to the type of joystick specified in the z80 snapshot. Otherwise default core config will be cursor (as it was before). If the front end specify a joystick type (different to default "Core defined Input") it will be applied whatever indicated the snapshot.

Since there is no way to know which joystick the z80 snapshot selected, i add a popup at startup to display the joystick type selected.

I'm interested feedback to know if it really solve original issue, since the whole joystick management is quite complex in this core...

@cawidtu
Copy link
Author

cawidtu commented Jan 30, 2023

Thank you. I compiled your repository into RetroPie and can see that version 1.60 is displayed and there is a popup at startup, in my case saying "Cursor selected". However, I cannot get Jet Set Willy to work, even after trying Kempston and other settings. The guy is just constantly jumping and cannot be controlled with any setting I [tried. The problematic file is attached.
JetSetWilly.z80.zip
As mentioned above, it works fine with lr-fuse 1.1.1.

@Chips-fr
Copy link
Contributor

Chips-fr commented Feb 5, 2023

I confirm with this z80 file i have joystick issue with 1.6.0 but it's ok with 1.1.1

This snapshot seems to works with quite some different joystick type (cursor, kempston etc...) but in it's header it indicate to use cursor (which is not wrong since cursor config works). It reads anyway the kempston interface.
However in latest 1.6.0 the kempston interface get deactivated because not needed according to header (this deactivation was not there on 1.1.1):

periph_disable_optional();

Strange behavior when a snapshot read kempston interface while not activated seems a well know issue:

/* If the snap was configured for a Kempston joystick, enable

Basically we need to ensure settings_current.joy_kempston is set to 1 when this kind of snapshot is used. I choose to always have this variable set to 1 in case of snapshot:

https://github.com/Chips-fr/fuse-libretro/blob/9aea3c45aed3af9e5ba4a39d8f39b56a3a0d29b8/fuse/peripherals/joystick.c#L323

You can re-fetch my repo, i've added this patch.

https://github.com/Chips-fr/fuse-libretro

@roslof
Copy link

roslof commented Feb 5, 2023

You can re-fetch my repo, i've added this patch.

@Chips-fr while I cannot validate your code (too junior) I'm happy to report that after compiling from your repo, the joystick controls for every .z80 game that used to fail for me are now working correctly. Perhaps somebody could validate and get this sent upstream. Great work!

@cawidtu
Copy link
Author

cawidtu commented Feb 5, 2023

Thank you. The fix works for me as well.

@Chips-fr
Copy link
Contributor

Chips-fr commented Feb 5, 2023

I opened a pull request, we will see if it get merged... (i always get pull merged but i modified quite the code since i found quite some limitations/bugs with the current implementation)
You can add a reaction on the pull request if you want.

@roslof
Copy link

roslof commented Apr 21, 2024

This issue was resolved with merge 847dbbd

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

No branches or pull requests

5 participants