Author Topic: ON KEY(n) is using ON TIMER(n)'s subroutine sometimes  (Read 80 times)

ON KEY(n) is using ON TIMER(n)'s subroutine sometimes
« on: December 06, 2018, 05:53:06 PM »
This problem was first reported back in May of 2014 on the QB64.net forum, but I wanted to repost it here since QB64.net isn't available anymore and new users of QB64 may not be aware of it.

ON KEY(n) and ON TIMER(n) both work, but if they are used together in the same program there _will_ be unexpected results.


For some reason, after the "ON TIMER(n)" statement has been used and then "TIMER ON" activates it and then "TIMER OFF" disables it, the subroutine that it uses gets called by the "ON KEY(n)" statement instead of the subroutine that "ON KEY(n)" is supposed to use.

I am including an example program that demonstrates this odd behavior if anyone wants to check into it.

The example program works in QB4.5 without any problems, but QB64 has a problem with it.

Basically, if/after ON TIMER(n) GOSUB is used, then : 
After TIMER ON (and then TIMER OFF) is used XX number of times, then
ON KEY(n) will use the ON TIMER(n) subroutine XX number of times before
it starts to use it's own subroutine.

I'm currently running Windows XP Home Edition SP3 (using QB64GL version 1.2) and I've also tested this as far back as SDL version 0.954 and it has the same problem.


As I recall, back in 2014, the verdict was that there IS a problem BUT the section of code that handles these events was written by Galleon and he would have to check into it himself.


Code: [Select]
   'ON TIMER will be used to erase a message
   'five seconds after it has been printed.
   '
   ON TIMER(5) GOSUB 5000



   'Set up "K" to use the ON KEY(n) statement.
   '
   KEY 15, CHR$(&H0) + CHR$(&H25) '<K>
   ON KEY(15) GOSUB 6000
   KEY 16, CHR$(&H20) + CHR$(&H25) '<NUMLOCK> + <K>
   ON KEY(16) GOSUB 6000
   KEY 17, CHR$(&H40) + CHR$(&H25) '<CAPSLOCK> + <K>
   ON KEY(17) GOSUB 6000
   KEY 18, CHR$(&H60) + CHR$(&H25) '<NUMLOCK> + <CAPSLOCK> + <K>
   ON KEY(18) GOSUB 6000



   KEY(15) ON: KEY(16) ON: KEY(17) ON: KEY(18) ON





   SCREEN 0: WIDTH 80, 50
   _FONT 14
   _DELAY .5: _SCREENMOVE _SCREENX, -4

   CLS
   PRINT
   PRINT
   COLOR 15
   PRINT "         THIS IS USED TO DEMONSTRATE A PROBLEM THAT EXISTS IN QB64 WHEN"
   PRINT "         'ON TIMER' AND 'ON KEY' ARE USED TOGETHER IN THE SAME PROGRAM."
   PRINT
   PRINT
   PRINT
   COLOR 2
   PRINT "    Press 'T' for a message to appear and a 5 second TIMER cycle to start."
   PRINT
   PRINT "    After 5 seconds the message is replaced and a counter will be updated."
   PRINT
   PRINT "    Do this 2 or 3 times and wait for the counter to update each time."
   PRINT
   PRINT
   PRINT
   COLOR 3
   PRINT "    Next, press 'K' and a differnt message and counter SHOULD appear..."
   PRINT
   PRINT "    ...but the counter for the timer routine counts up INSTEAD."
   PRINT
   PRINT "    This will happen for as many times as 'T' was pressed earlier,"
   PRINT "    and THEN the correct subroutine for 'ON KEY' will be used."
   PRINT
   PRINT
   PRINT
   COLOR 7
   PRINT "        The steps above can be repeated without restarting the program."
   PRINT
   PRINT "        This demo works without any problems in QB4.5 but not in QB64."
   PRINT
   PRINT
   PRINT



   COLOR 14
   PRINT
   PRINT
   PRINT "Press 'T' to use the ON TIMER subroutine."
   PRINT
   PRINT "Press 'K' to use the ON KEY subroutine."
   PRINT
   PRINT "Press 'Q' to quit."

   LN = CSRLIN + 2


30 K$ = UCASE$(INKEY$)
   IF K$ = "T" THEN GOSUB 100
   IF K$ = "Q" THEN 200

   _LIMIT 10
   GOTO 30




    REM ----- (SUBROUTINE) -- Display a message and turn on the timer.
    '
100 TIMER ON

    LOCATE LN, 1
    COLOR 15, 4
    PRINT " --> The TIMER ON command has just been used. ";
    PRINT "                                              ";
    PRINT " After 5 seconds the counter will be updated  ";
    PRINT " and the TIMER OFF command will be used.      ";
    COLOR 7, 0

    RETURN




    REM -- Quit this program.
200 COLOR 7, 0: CLS: SYSTEM









     REM ----- (SUBROUTINE) -- for ON TIMER.
     '
     'Disable the TIMER and erase the message after 5 seconds is up.
     '
5000 TIMER OFF

     TIMERnum = TIMERnum + 1
     IF C = 10 THEN C = 15 ELSE C = 10
     COLOR C

     LOCATE LN, 1
     PRINT TAB(80); " "
     PRINT "The TIMER OFF command was just used ---------> this counter ="; TIMERnum
     PRINT TAB(80); " "
     PRINT TAB(80); " "

     SOUND 1000, .4
     RETURN



     REM ----- (SUBROUTINE) -- for ON KEY.
     '
6000 KEYnum = KEYnum + 1

     IF CC = 11 THEN CC = 15 ELSE CC = 11
     COLOR CC

     LOCATE LN + 5, 1
     PRINT "You are in the ON KEY subroutine ------------> this counter ="; KEYnum

     SOUND 500, .4
     RETURN


 

Re: ON KEY(n) is using ON TIMER(n)'s subroutine sometimes
« Reply #1 on: December 09, 2018, 10:22:52 PM »
HI
running your code I get these results:

each time  I press  T then pressing K at the first time it increases T counter and then the K counter each time I repeat this sequence of Keys...
it seems like the offset of subroutine Timer is stored and it lasts in memory when the control passes to the On Key event...
as the first time there is no adjournment of Offset for ON event routines.