Reading from keyboard without waiting in a portable way

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
Fabrizio
Member
Posts: 116
Joined: Tue Jul 11, 2017 9:28 pm

Reading from keyboard without waiting in a portable way

Post by Fabrizio »

Hi everyone,

First of all, thanks to the support I have received so far!
(I am porting my CC65 open source game to Z88DK: https://github.com/Fabrizio-Caruso/ASCII-CHASE).
The goal is to make it as portable as possible. I am now trying to get it to work for the ZX Spectrum.

The game now starts and (sort of) works instead for the keyboard input.
The remaining major issue is that I do not know how to reading the keyboard input without waiting.
I have tried getch(), getche() and getchar() with no success.
(In CC65 conio.h cgetc() does what I expect.)

So far I use:
...
if(kbhit())
{
kbInput = getch(); // or getche() or getchar(), which is worse (getchar displays the character)
movePlayerByKeyboard(kbInput);
}
...

where:
void movePlayerByKeyboard(char kbInput)
{
if(kbInput=='w')
{
...
}
else if(kbInput=='s')
{
...
}
else if(kbInput=='a')
{
...
}
else if(kbInput=='d')
{
...
}
else
if(kbInput==' ' ...)
{
...
}
...
}


I have tried similar functions such as getche, getc with little success. The game either waits for my input....

Fabrizio
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

The most cross-platform way to read an instantaneous keypress in the classic lib is to use kbhit().

kbhit() **consumes** any keypress so you should do something like:

Code: Select all

if (k = kbhit()) 
{
   if (k == 'a')
     ...
}
kbhit() returns zero if no key is pressed and the ascii code otherwise.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

Scratch that... the function I am thinking of is getk().

For most targets kbhit() is using getk() which behaves as described. Unfortunately kbhit() turns the keypress into a true/false value (conio.h) which loses the keypress. This is probably a bug which maybe dom or stefano can have a look at.
Fabrizio
Member
Posts: 116
Joined: Tue Jul 11, 2017 9:28 pm

Post by Fabrizio »

@alvin

Do you mean that I should do?

if (k = getk())
{
if (k == 'a')
...
}
Fabrizio
Member
Posts: 116
Joined: Tue Jul 11, 2017 9:28 pm

Post by Fabrizio »

Remark: In CC65 conio.h implementation, kbhit() does not consume the input. It would be nice to have the same behavior in Z88dk.
Post Reply