[Z88dk-users] Joysticks?

Bridge to the z88dk-users mailing list
Post Reply
thricenightly
Member
Posts: 28
Joined: Thu Jun 01, 2017 5:46 pm

[Z88dk-users] Joysticks?

Post by thricenightly »

I was about to move on from the keyboard to joysticks. I looked at the API in input_zx.h and was immediately rather baffled.

I'm going to do this research in the next day or two, but since it's non-obvious I thought I'd cheat and ask here first. :) I have a Kempston joystick to work with. How do you use the API to establish it's present and read from it? Is there an example to examine?



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I'm going to do this research in the next day or two, but since it's non-obvious I thought I'd cheat and ask here first. :) I have a Kempston joystick to work with. How do you use the API to establish it's present and read from it? Is there an example to examine?
I don't think I have a ready open source example except for Pietro Bros in line 29 of globals.c:
https://bitbucket.org/CmGonzalez/pietro ... obals.c-29

In those data structures, he's putting every joystick function into an array and he's using two function pointers to hold the control method for each player. A menu allows you to select control method for each player which just cycles through that control method array and the associated text names in joynames[].

As you can see the idea is that you can assign a joystick function to a function pointer so that the control method can be defined in game.

These are the joystick functions you can choose from:

uint16_t in_stick_keyboard(udk_t *u);
uint16_t in_stick_cursor(void);
uint16_t in_stick_fuller(void);
uint16_t in_stick_kempston(void);
uint16_t in_stick_sinclair1(void);
uint16_t in_stick_sinclair2(void);

All of these functions can be called directly and they will return the same format return value which is documented on line 39 in input.h as F000RLDU active high.

To read kempston you could do:

Code: Select all

#include <input.h>

unsigned char j;

j = in_stick_kempson();
if (j & IN_STICK_FIRE) printf("FIRE!\n");
if (j & IN_STICK_LEFT) printf("LEFT!\n");
...
And similarly (except for the joystick function) for every other joystick.

The keyboard joystick is a little different. It takes a single udk_t struct parameter that maps which keys are assigned to up, down, left, right, fire. This struct is define on line 25 of input.h. The values defining keys are the same scan codes you've already been using to read the keyboard.


In order for all these joystick functions to be used with a single function pointer, we define a function pointer that is compatible with the keyboard joystick, ie one that takes a parameter:

Code: Select all

typedef uint16_t (*JOYFUNC)(udk_t *u);

udk_t joy_keys = { IN_KEY_SCANCODE_SPACE, IN_KEY_SCANCODE_p, IN_KEY_SCANCODE_o, IN_KEY_SCANCODE_a, IN_KEY_SCANCODE_q };

JOYFUNC joy;

switch (control_method)
{
case 0:
joy = (JOYFUNC)in_stick_kempston;
break;

case 1:
joy = (JOYFUNC)in_stick_sinclair1;
break;

case 2:
joy = (JOYFUNC)in_stick_sinclair2;
break;

case 3:
joy = (JOYFUNC)in_stick_cursor;
break;

case 4:
joy = (JOYFUNC)in_stick_fuller;   // fuller has compatibility issues with some hardware
break;

default:
joy = (JOYFUNC)in_stick_keyboard;
break;
}

...

in = (joy)(&joy_keys);
if (in & IN_STICK_FIRE) printf("FIRE!\n");
...
The joystick function is always called with the user defined keys struct that the keyboard joystick needs. It's okay to pass this extra parameter to the other joystick functions because they won't even look at it. This only works because function pointer calls are always done with standard linkage, which means the single parameter is pushed onto the stack and the caller is responsible for clearing it.

Hopefully that clears up how to use these functions.


About detecting joysticks :- this is not usually reliable and you will end up on some clones or machines where software will erroneously detect a joystick and the game won't work on such machines because the user doesn't get a chance to select control method.

The newlib does not have any detection functions but if you want to borrow some code you can have a look at the classic library:
https://github.com/z88dk/z88dk/tree/mas ... diagnostic

However I can see, eg, the kempston joystick detection will not work for clones of the spectrum and may not work on some spectrum models due to floating bus and whatnot. I have seen more careful detectors for kempston so a web search may turn them up. However, as an original owner of a ts2068, I can say I have been burned a couple of times by commercial games that auto-detected kempston when no kempston was present causing said games not to work.



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Post Reply