in_Inkey() is too fast

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
zx81ultra
Member
Posts: 38
Joined: Thu Feb 13, 2020 1:56 am

in_Inkey() is too fast

Post by zx81ultra »

Hello,

This code prints 5 or 6 times the same key for each keypress (zx81), it's too fast. Any idea on the correct technique to process keys inside a game loop ?

Code: Select all

Loop:

while(!(Key=in_Inkey()));
printf("%d ", Key);

goto Loop;
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The in_Inkey() function reads the instantaneous state of the hardware - i.e. what keys are currently being pressed.

Looking at your code it's going to loop quickly - 5 times in the time it takes to press one key it appears! - as soon as you add some game logic in things will slow down.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

Just add

msleep(40);

in your test program after the printf() line, this will make the program wait for 40 milliseconds before reading the next keyboard input.

For cross-development, you will have to adjust the delay value for each target. See my cross-platform game Mastermind RK for example:

Code: Select all

#if defined(__LYNX__) || defined(__NASCOM__)
        #define DELAY_AFTER_KEYPRESS 20
#elif defined(__ZX81__) || defined(__ZX80__) || defined(__PC6001__) || defined(__EXCALIBUR64__)
        #define DELAY_AFTER_KEYPRESS 40
#elif defined(__PV1000__)
        #define DELAY_AFTER_KEYPRESS 50        
#elif defined(__GAL__)
        #define DELAY_AFTER_KEYPRESS 60
#elif defined(__SUPER80__) || defined(__KAYPRO83__) || defined(__SORCERER__) || defined(__EINSTEIN__) || defined(__ABC80__)
        #define DELAY_AFTER_KEYPRESS 100
#elif defined(__ALPHATRO__) || defined(__TRS80__)
        #define DELAY_AFTER_KEYPRESS 130
#elif defined(__SPC1000__)
        #define DELAY_AFTER_KEYPRESS 250
#elif defined(__Z1013__)
        #define DELAY_AFTER_KEYPRESS 300
#elif defined(__PC88__)
        #define DELAY_AFTER_KEYPRESS 400
#else
        // default value: OK for PV2000, Coleco, KC, Spectrum, VG5000, VZ200, Laser 500, etc.
        #define DELAY_AFTER_KEYPRESS 200
#endif
and after keyboard input is handled:

Code: Select all

msleep(DELAY_AFTER_KEYPRESS);
For each target I had to find the correct balance between avoiding multiple keypresses and allowing the player to easily move through the available colours (using up and down).
zx81ultra
Member
Posts: 38
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

Thank you ! it's also better now with all the game logic inside the loop.
zx81ultra
Member
Posts: 38
Joined: Thu Feb 13, 2020 1:56 am

Post by zx81ultra »

Robert, I checked your MM source code, interesting method of seeding the RNG with srand():

// we use this counter to every time get a different random seed value,
// depending on how long it took until the user pressed a button
randomSeed++;
if (randomSeed>32766) randomSeed=0; // reset counter to avoid overflow

Is this the preferred way to seed or is there anything else ? I remember reading something about the TV frame number or something like that being also ok.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

We previously had a randomize() function in z88dk, but it was later dropped because it was not working properly, see here.

So we have to feed srand() with some "random" number.

I think Dom gave me the idea to feed it with a counter value based on the time until the first user input, and this does the job for me. Maybe there is some other way to achive true randomness.
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: in_Inkey() is too fast

Post by cborn »

Hi
the above link
viewtopic.php?pid=16026#p16026
is not functioning, maybe its not yet indexed?
meanwhile i had on zx the same speed problem after use of in_Inkey() and found this thread
both key = getchar( );
and scanf( "%d", &key ) ;
insist of printing the result on screen/terminal unless i redirect to a file which is a lot for just capturing a single key input.
If the 'random' link is found again i can show my primitieve solution in asm. (can do it here but its in_inkey now)
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: in_Inkey() is too fast

Post by dom »

I've fixed up the link, it should be: https://z88dk.org/forum/viewtopic.php?p=16039#p16039 - I've added compatibility in for most google links now though.

If you can provide the zcc line you're using then that would be helpful - I think you've switched between classic and newlib in the past and behaviour in this area is different in the two libraries.
Post Reply