Joyfunc problems

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
Timmy
Well known member
Posts: 392
Joined: Sat Mar 10, 2012 4:18 pm

Joyfunc problems

Post by Timmy »

Hi, I'm currenty trying to see if I could post some of my (5+ years) old joystick code here, but it seems that they don't work anymore in the newer versions of z88dk.

The problem looks like the one I found in github https://github.com/z88dk/z88dk/issues/1103 but I use sccz80 and not the newlib. (sorry I don't use github yet, so I'm posting it here.)

Code: Select all

#include <input.h>
#include <spectrum.h>
unsigned char joys;
void *joyfunc;
struct in_UDK joykeys;

void setupkeyboard() 
{
	joykeys.fire  = in_LookupKey(' ');
	joykeys.left  = in_LookupKey('o');
	joykeys.right = in_LookupKey('p');
	joykeys.up    = in_LookupKey('q');
	joykeys.down  = in_LookupKey('a');

	joyfunc = in_JoyKeyboard;
}

unsigned char *screen = 16384;

main()
{
	joys = 0;
	setupkeyboard();
	while (1)
	{
		joys = (joyfunc) (&joykeys);
		*(screen) = joys;
	}

	return 0;
}
If I compile this, I get the following:

Code: Select all

C:\z88dk\SPECJOY>zcc +zx -vn -startup=31 a2.c -o a2b -create-app
a2.c:26:21: warning: Calling via non-function pointer [-Wincompatible-pointer-types]
a2.c:26:30: warning: Assigning from a void expression [-Wvoid]
If I then run the file, none of the QAOP keys are working.

Is there something I can do to make it working again? I don't mind rewriting code, but I'd like something that can work now, and perhaps even for all the different configurations (zsdcc, newlib, oldlib, sccz80). (I don't want to write 4 tutorials, for example.)
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: Joyfunc problems

Post by dom »

Try changing:

Code: Select all

void *joyfunc;
to:

Code: Select all

uint (*joyfunc)(struct in_UDK *) __z88dk_fastcall;
With that annotation, sccz80 will now jump through hoops to ensure that hl holds the fastcall parameter - I think your code must've been written when function pointers couldn't be prototyped (i.e. the arguments couldn't be specified) which ended up as being understood as "function pointers can't be defined, so use a void * pointer).

I might actually revisit this in the compiler and try to call through an index register which would make the code a lot nicer, but that's for another day.
Timmy
Well known member
Posts: 392
Joined: Sat Mar 10, 2012 4:18 pm

Re: Joyfunc problems

Post by Timmy »

dom wrote: Thu Jan 28, 2021 11:44 pm

Code: Select all

uint (*joyfunc)(struct in_UDK *) __z88dk_fastcall;
Thanks! This works for me.
I think your code must've been written when function pointers couldn't be prototyped (i.e. the arguments couldn't be specified) which ended up as being understood as "function pointers can't be defined, so use a void * pointer).
I basically copied the information that was (and is) still in input.h.
It can also be found in https://github.com/z88dk/z88dk/wiki/Cla ... ut-library

To be honest I thought this was still the way to do joyfunc. So glad you found out this has been changed. Perhaps I should check other parts of my old codes as well. Thanks.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: Joyfunc problems

Post by dom »

Timmy wrote: Fri Jan 29, 2021 2:43 amI basically copied the information that was (and is) still in input.h.
It can also be found in https://github.com/z88dk/z88dk/wiki/Cla ... ut-library

To be honest I thought this was still the way to do joyfunc. So glad you found out this has been changed. Perhaps I should check other parts of my old codes as well. Thanks.
Thank you, that's another couple of bits of incorrect docs fixed. I have to admit I had forgetten that the joystick functions in input.h exist: I'm so used to using joystick() from games.h since it's more portable.

I'm sure there's been a few changes that will cause problems with older codebases - sccz80 used to accept a lot of dubious code!
Timmy
Well known member
Posts: 392
Joined: Sat Mar 10, 2012 4:18 pm

Re: Joyfunc problems

Post by Timmy »

Another question, as you can see in the code in my map editor thread https://www.z88dk.org/forum/viewtopic.php?f=2&t=11506, I'm also using joyfunc in this way:

Code: Select all

joyfunc = in_JoySinclair1;
joyfunc = in_JoySinclair2;
joyfunc = in_JoyKempston;
I get this warning from the compiler:

Code: Select all

w3.c:150:28: warning: Assigning 'joyfunc', type: unsigned int uint(struct in_UDK * )* joyfunc from u
nsigned int in_JoySinclair1()*  [-Wincompatible-pointer-types]
w3.c:153:28: warning: Assigning 'joyfunc', type: unsigned int uint(struct in_UDK * )* joyfunc from u
nsigned int in_JoySinclair2()*  [-Wincompatible-pointer-types]
w3.c:158:28: warning: Assigning 'joyfunc', type: unsigned int uint(struct in_UDK * )* joyfunc from u
nsigned int in_JoyKempston()*  [-Wincompatible-pointer-types]
How should I recast those library functions to get rid of the warnings?
(It's not urgent, the compilation still succeeds, but I'm not good at casting variables. :p )
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: Joyfunc problems

Post by dom »

Yes, this is an annoying warning - it's come out of the old misbelief that function pointers didn't exist and "anything" can be assigned to a void *

However, I do need to look into this - I think that warning is actually errant and we're being a bit too strict with checking. However the newlib definitions might actually be wrong.

Another "fun" evening awaits me!
Timmy
Well known member
Posts: 392
Joined: Sat Mar 10, 2012 4:18 pm

Re: Joyfunc problems

Post by Timmy »

Just in case, I'm still using the "old" lib, I think. So I'm not sure if it's newlib related.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: Joyfunc problems

Post by dom »

As usual, the "simple" problems seem to open not just to a rabbit warren, but to entire subterranean cave systems.

This one is interesting, testing with 3 different compilers and I get 3 different behaviours which is always a fun result.

So, we've got this code:

Code: Select all

typedef struct udk_s udk_t;

unsigned int in_Key(udk_t *u);
unsigned int in_Joy();

unsigned int (*joyfunc)(udk_t *);

joyfunc = in_Joy;
joyfunc(123);
Now, how many parameters should in_Joy() take? None? 1? As many as you like?

The answer (thanks to K&R prototypes) is all of the above.

So, compiler results:

* clang behaves correctly and doesn't warn for any of the test lines
* sdcc assumes that in_Joy() takes no parameters and errors for both test lines (sdcc doesn't support K&R syntax, so assumes in_Joy(void))
* sccz80 warns on the assignment and issues no warning on the call

So, I think I'm going to make sccz80 not issue the warning, it'll take a while because I don't want to get it wrong and the validation is a recursive routine. However in the interim I've added support for disabling warnings, so you can use the -Wno-incompatible-pointer-types option to disable the diagnostic.
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: Joyfunc problems

Post by dom »

I do like it when things turn out easier than first thought.

There's now no warning when the joystick function is assigned to the function pointer.
Timmy
Well known member
Posts: 392
Joined: Sat Mar 10, 2012 4:18 pm

Re: Joyfunc problems

Post by Timmy »

I assumed that you just skip showing the warnings instead right? Thanks!

I'll just assume that it works for now and wait until 2.1.1 until I upgrade again. :p
Post Reply