in_KeyPressed() for non-Sinclair targets?
in_KeyPressed() for non-Sinclair targets?
I am currently porting a ZX81 game I have written to some other Z80 systems, and I have basically solved all issues, except for this one:
My game has a two-player-mode where both players should be able to press a key simultaneously (the keys are always pressed briefly, but not held). On the ZX81 and the other Sinclair computers this can be achieved by using the in_KeyPressed() function, which returns the current state of a specific key.
For the other targets I have provisionally implemented standardized ANSI VT100 keyboard input with kbhit() and getch(), but this does not allow two buttons to be pressed simultaneously - the keypress of one player momentarily blocks the other player's keys.
Is there any equivalent for the in_KeyPressed() function, at least for some other targets? Or is there any workaround?
My game is basically finished for Jupiter Ace, Mattel Aquarius and Robotron Z1013, so any target-specific solution for these targets would be most interesting to me.
My game has a two-player-mode where both players should be able to press a key simultaneously (the keys are always pressed briefly, but not held). On the ZX81 and the other Sinclair computers this can be achieved by using the in_KeyPressed() function, which returns the current state of a specific key.
For the other targets I have provisionally implemented standardized ANSI VT100 keyboard input with kbhit() and getch(), but this does not allow two buttons to be pressed simultaneously - the keypress of one player momentarily blocks the other player's keys.
Is there any equivalent for the in_KeyPressed() function, at least for some other targets? Or is there any workaround?
My game is basically finished for Jupiter Ace, Mattel Aquarius and Robotron Z1013, so any target-specific solution for these targets would be most interesting to me.
I'm afraid there isn't. kbhit/getch go through getk() which normally calls the ROM so only picks up a single keypress.
We'd need to write alternate keyboard handlers for all the ports and there's not usually masses of information available on the ports and scancodes.
Having said that, I've just found: http://www.forums1.jupiter-ace.co.uk/pr ... dread.html for the Jupiter Ace which looks suspiciously Sinclair like and probably easy-ish to add as a result.
We'd need to write alternate keyboard handlers for all the ports and there's not usually masses of information available on the ports and scancodes.
Having said that, I've just found: http://www.forums1.jupiter-ace.co.uk/pr ... dread.html for the Jupiter Ace which looks suspiciously Sinclair like and probably easy-ish to add as a result.
this kind of problems is addressed with joystick() in games.h, but I'm afraid the current implementation on zx81 and J.ace is the generic one, which is a quick placeholder based on getk() 
a way to test joystick() is to try snakes.c in examples/graphics. it is also a nice way to test the ym chip sound..

a way to test joystick() is to try snakes.c in examples/graphics. it is also a nice way to test the ym chip sound..
Ok, that's a pity, I'll have to live with that.
Thanks for the info about games.h, I didn't know that yet and that's certainly useful, although it does not solve my problem.
A quick test shows that on the ZX81 it allows simulatenous key presses, while on the Jupiter Ace it does not, as expected.
It would be great if you could implement in_KeyPressed() for that system as well. The Jupiter Ace is such a great little machine, it would certainly deserve more software.dom wrote:Having said that, I've just found: http://www.forums1.jupiter-ace.co.uk/pr ... dread.html for the Jupiter Ace which looks suspiciously Sinclair like and probably easy-ish to add as a result.
BTW, this is exactly the game I am working on (minus the AI opponent) :-)stefano wrote:a way to test joystick() is to try snakes.c in examples/graphics.
Thanks for the info about games.h, I didn't know that yet and that's certainly useful, although it does not solve my problem.
A quick test shows that on the ZX81 it allows simulatenous key presses, while on the Jupiter Ace it does not, as expected.
Code: Select all
// joytest.c
// games.h joystick test (based on snakes.c)
// zcc +zx81 -create-app -startup=2 -o joytest_ZX81 joytest.c
// zcc +ace -vn -create-app joytest.c -o jt.bin
// load the game on the Jupiter Ace by typing
// 0 0 bload jt.bin
#include <games.h>
#include <stdio.h>
void main(void) {
int joyType1;
int joyType2;
int joy1;
int joy2;
int x;
printf("%c",12); // clear the screen
printf("*** joystick test ***");
printf("\n\njoystick 1:\n");
for (x = 0; x != GAME_DEVICES; x++)
printf("%u - %s\n", x + 1, joystick_type[x]);
joyType1 = 0;
while ((joyType1 < 1) || (joyType1 > GAME_DEVICES))
joyType1 = getk() - 48;
while (getk())
;
printf("\n\njoystick 2:\n");
for (x = 0; x != GAME_DEVICES; x++)
printf("%u - %s\n", x + 1, joystick_type[x]);
joyType2 = 0;
while ((joyType2 < 1) || (joyType2 > GAME_DEVICES))
joyType2 = getk() - 48;
printf("\n\nwaiting for joystick input...\n");
while(1)
{
joy1=joystick(joyType1);
joy2=joystick(joyType2);
printf("joy 1: %d, joy 2: %d\n",joy1,joy2);
}
}
I've recently added in_Inkey() support for: Jupiter Ace, Casio PV-2000, Sega SC-3000 and the VZ machines. This is addition to the ZX Spectrum, ZX81 and X1 support that was already present.
To easily add support for more, getting hold of the keyboard matrix is essential, examples of what's needed can be found on issues: https://github.com/z88dk/z88dk/issues/7 ... -391503455 and https://github.com/z88dk/z88dk/issues/6 ... -313274380
To easily add support for more, getting hold of the keyboard matrix is essential, examples of what's needed can be found on issues: https://github.com/z88dk/z88dk/issues/7 ... -391503455 and https://github.com/z88dk/z88dk/issues/6 ... -313274380
Thanks for these additions, I have successfully tested in_KeyPressed() on the Jupiter Ace and the VZ.
My joystick test program above now shows that both "joysticks" can be used simultaneously on the Jupiter Ace, that's great. On the VZ however, the result is not the best: you hear a beep every time you "move" the joystick, and there seems to be some sort of auto repeat function, so for example when you briefly press Q for "Up", you see the value 8 that joystick() correctly returned, but when you press and hold Q, this keyboard input is also displayed on the screen, so you see either Q8 or 8Q.
Another thing about the VZ is the "Visible Cursor Problem". I am not sure if Fabrizio's issue is really completely solved, and I doubt that it is at all connected to the keyboard input method used in the program. I have exactly the same problem in my program on the VZ, and it also occurs on every "nth" startup, but long before the program waits for any keyboard input. You notice that it's there when you see a blinking pixel on the startup screen. The 6x4 text output is rather slow, so it takes some time until the entire text is on the screen, but the blinking cursor is there right from the beginning. And as Fabrizio described it, when you reload the game program, the problem is usually gone (and if it isn't, you have to try reloading it again until it's gone).

My joystick test program above now shows that both "joysticks" can be used simultaneously on the Jupiter Ace, that's great. On the VZ however, the result is not the best: you hear a beep every time you "move" the joystick, and there seems to be some sort of auto repeat function, so for example when you briefly press Q for "Up", you see the value 8 that joystick() correctly returned, but when you press and hold Q, this keyboard input is also displayed on the screen, so you see either Q8 or 8Q.
Another thing about the VZ is the "Visible Cursor Problem". I am not sure if Fabrizio's issue is really completely solved, and I doubt that it is at all connected to the keyboard input method used in the program. I have exactly the same problem in my program on the VZ, and it also occurs on every "nth" startup, but long before the program waits for any keyboard input. You notice that it's there when you see a blinking pixel on the startup screen. The 6x4 text output is rather slow, so it takes some time until the entire text is on the screen, but the blinking cursor is there right from the beginning. And as Fabrizio described it, when you reload the game program, the problem is usually gone (and if it isn't, you have to try reloading it again until it's gone).

There's definitely something causing problems in the VZ firmware - given that you've got these problems and you're not calling fgetc or you've redirected that routines to the inkey routines, then it may be the interrupt code that's causing trouble.
As an experiment it might be worth sticking in an asm("di") at the start of main to see if that clears things up.
As an experiment it might be worth sticking in an asm("di") at the start of main to see if that clears things up.
I have no idea what it does
, but I have now added
at the start of main(), and on ten attempts I couldn't reproduce the problem anymore!
I will keep on trying, but currently it looks as if this has solved the problem...

Code: Select all
#asm
di
#endasm
I will keep on trying, but currently it looks as if this has solved the problem...
Great! But should in_keypressed() already work with the current nightly build?dom wrote:I've just committed VG5k support. I've updated the joystick() function to use the actual joysticks as well (https://github.com/z88dk/z88dk/issues/779)
Here is a little test, on the VG5k the behaviour is not as expected...
Code: Select all
// Compile with
// zcc +zx81 -startup=2 -o inkeypressedtest_ZX81 -create-app inkeypressedtest.c
// zcc +vg5k -lm -o inkeypressedtest_vg5000 -create-app inkeypressedtest.c
#include <stdio.h>
void main()
{
int exitLoop;
printf("\ninkeypressed() test\n");
printf("\npress x to exit\n");
exitLoop=0;
while(exitLoop==0)
{
printf("key s pressed: %d\n",in_KeyPressed(in_LookupKey('S')));
if (in_KeyPressed(in_LookupKey('X'))) exitLoop=1;
}
return;
}
Thanks for the latest additions. On VG5k, TRS-80 and EG2000 in_KeyPressed() works perfectly.
However, on the Aquarius there is the problem that two buttons cannot be pressed simultaneously. And if you press and hold one button and then press another, the first button (that you are still holding) gets "unpressed".
Is this a feature of this machine, or is this maybe a bug that can be fixed?
I have modified my little test program so that it checks the status of two buttons (s and d).
However, on the Aquarius there is the problem that two buttons cannot be pressed simultaneously. And if you press and hold one button and then press another, the first button (that you are still holding) gets "unpressed".
Is this a feature of this machine, or is this maybe a bug that can be fixed?
I have modified my little test program so that it checks the status of two buttons (s and d).
Code: Select all
// Compile with
// zcc +zx81 -startup=2 -o inkeypressedtest_ZX81 -create-app inkeypressedtest.c
// zcc +vg5k -lm -o inkeypressedtest_vg5000 -create-app inkeypressedtest.c
// zcc +aquarius -lm -o inkeypressedtest_aquarius -create-app inkeypressedtest.c
#include <stdio.h>
void main()
{
int exitLoop;
printf("%c",12); // clear the screen
printf("\ninkeypressed() test\n");
printf("\npress x to exit\n");
exitLoop=0;
while(exitLoop==0)
{
printf("key s / d pressed: %d / %d\n", in_KeyPressed(in_LookupKey('s')), in_KeyPressed(in_LookupKey('d')));
if (in_KeyPressed(in_LookupKey('x'))) exitLoop=1;
}
printf("%c",12); // clear the screen
return;
}
I'm wondering if it's an issue with the emulator (I presume you're using VirtualAquarius). I can't spot anything in the code that would lead to this behaviour.
I'm not sure how to load tapes into mame, but that's obviously a good sanity check, though looking at the code there I think multiple key presses are supported.
I'm not sure how to load tapes into mame, but that's obviously a good sanity check, though looking at the code there I think multiple key presses are supported.
Hmm, after loading the compiled ROM image into Aquarius or MAME, the screen shows nothing and you only hear frequent beeping sounds. Maybe the new ROM image generator is not working as it should.
BTW, there is another very old Aquarius emulator named "AqEmu", this one also supports ROM loading and shows the same result.
BTW, there is another very old Aquarius emulator named "AqEmu", this one also supports ROM loading and shows the same result.
I've adjusted some memory pointers so cartridges now load correctly. The start of RAM (used for variables) is now 0x3900 and REGISTER_SP=0x3fff REGISTER_SP can be adjusted with -pragma-define:REGISTER_SP=nnnn to support the different RAM configurations. Though I can't spot the option in mame to change the memory configuration.
Cartridges now load and run in both Mame and VirtualAquarius first time. The good news is that mame supports multiple keypresses!
Cartridges now load and run in both Mame and VirtualAquarius first time. The good news is that mame supports multiple keypresses!
Yes, on mame a default compile of plottest resets itself repeatedly.
My hunch is that we're calling a ROM routine but we've overwritten the memory so it ends up resetting. Using -pragma-redirect:fputc_cons=fputc_cons_generic means that we avoid calling the ROM and it successfully works.
If you can confirm I'll document it as a gotcha.
My hunch is that we're calling a ROM routine but we've overwritten the memory so it ends up resetting. Using -pragma-redirect:fputc_cons=fputc_cons_generic means that we avoid calling the ROM and it successfully works.
If you can confirm I'll document it as a gotcha.
With that parameter added the cartridge ROM file works both in MAME and in Virtual Aquarius, thanks.
And now I can also confirm that in MAME in_keypressed() works as expected, that means that two buttons can be presses simultaneously. So that keyboard problem is really a feature of the Virtual Aquarius emulator.
And now I can also confirm that in MAME in_keypressed() works as expected, that means that two buttons can be presses simultaneously. So that keyboard problem is really a feature of the Virtual Aquarius emulator.