Fastest way to get Keyboard presses

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Fastest way to get Keyboard presses

Post by Sinuvoid »

Ok, It been awhile but here goes...

I've made a sound program that uses PLAY and INKEY commands to make sound with key presses. Is there a faster method for it to cycle through the keys in a DO LOOP? Heres the structure of what my code would look like.

Code: Select all

CLS

DO
k$ = INKEY$

CASE SELECT k$ 'or is it SELECT CASE :P

CASE "q"
PLAY "E"

CASE "w"
PLAY "F"

CASE "e"
PLAY "b"

SELECT END
LOOP
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

You again!

Post by burger2227 »

Actually PLAY causes the delay, not INKEY$. The PLAY notes are actual musical frequencies for certain tones, but the internal speaker does not work well enough for musicians.

ON PLAY can actually be used as a crude delay in programs too.

I suggest you PLAY around with it. You probably have already used SOUND. It delays loops some too, but code after it may execute before the sound is done.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

Yeah burger, I know that if you use "E8" that it waits around have a second
(half note) But What I want is for it to cycle through the CASE's really fast so it can pick up the key presses fast. Like lets say I had 100 CASE's. And I needed it to cycle through them really fast, how could I do that? And maybe speeding it up with something other than INKEY$.

(BTW, What CHR$'s are the arrow keys and the SHIFT button?)
BDZ
Coder
Posts: 49
Joined: Sun Nov 20, 2005 5:41 pm
Location: Wisconsin
Contact:

Post by BDZ »

I'm not exactly sure what you are shooting for, but try putting PLAY "MB" before the rest of your PLAY statements. That will make the notes play in the background while the program keeps executing.
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

OK, sounds good, and I found a solution. Use INP command. But I need someoen to explain more about it to me and how to find the numbers(ASCII?). Example, I want it to use the arrow keys. What are they're numbers(ASCII?)?

EDIT:Nevermind, found it. Thanks for tips guys :P
Patz QuickBASIC Creations
Veteran
Posts: 399
Joined: Wed Mar 02, 2005 9:01 pm
Location: Nashville, Tennessee
Contact:

Post by Patz QuickBASIC Creations »

Though not entirely better, you could do:

Code: Select all

CLS 
DO

DO 
k$ = INKEY$ 
LOOP UNTIL K$ <> ""

SELECT CASE k$

CASE "q" 
PLAY "mbE" 

CASE "w" 
PLAY "mbF" 

CASE "e" 
PLAY "mbB" 

END SELECT
LOOP
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

OK, its giving me a weird error. Paste this code into Qbasic and run, and you'll see. Is this cause its in Hex and I should convert it into decimal?

Code: Select all

DO
k = INP(&H60)

SELECT CASE k

CASE 48
PRINT CHR$(24); " ";
PLAY "MB"
PLAY ">d32<"

CASE 21
PRINT CHR$(22); " ";
PLAY "MB"
PLAY "<d32>"

CASE 50
PRINT CHR$(25); " ";
PLAY "MB"
PLAY "f32"


CASE 4B
PRINT CHR$(26); " ";
PLAY "MB"
PLAY "a32"

CASE 4D
PRINT CHR$(27); " ";
PLAY "MB"
PLAY "b32"

SELECT END

kp$ = INKEY$
IF kp$ = "1" THEN GOTO MAINM
LOOP
Patz QuickBASIC Creations
Veteran
Posts: 399
Joined: Wed Mar 02, 2005 9:01 pm
Location: Nashville, Tennessee
Contact:

Post by Patz QuickBASIC Creations »

First off, you can't use characters in CASE, ie CASE 4B, unless they are hexadecimal, in which case you need to tell it so. And, you don't need to have the INP in there, just use the one I posted, it works fine.
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

1, how do I tell it???
2, I use INP because its fast :) and plus ive never used it Before so its good practise :P

EDIT: Ok, the INP isnt working for me. I've tried tut's but no luck. Can you guys explain it for me please :D

2, How can I make letters typed in the INPUT command come out as *'s (exmaple, password program)
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

New thread?

Post by burger2227 »

Don't use INPUT...........use an INKEY$ loop that runs until a user presses the enter key. INKEY can also filter out certain key entries, such a only number or letter presses. Look up the ASCII codes for the type of entry you need.

When a valid key is pressed, just print an asterisk. You can also allow backspacing by checking for Character code 8.

Apparently you cannot use CHR$ and (8) in a text here LOL.

INP(&H60) reads the keyboard scancodes. A key release is 128 more than the press value returned. Make a DO loop and just PRINT it. Use LOOP UNTIL code = 1, the escape key. Few of the scancodes are the same as ASCII.

INP is for reading a port value. OUT changes the values.

Ted
Last edited by burger2227 on Fri Jan 25, 2008 6:37 pm, edited 3 times in total.
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

Can you tell me in depth how to use the INP command please burger :D I've looked at tuts and QB help but no luck :(

EDIT: CHR$(what??)
User avatar
Seb McClouth
Veteran
Posts: 342
Joined: Wed Nov 09, 2005 7:47 am
Location: Inside the Matrix...
Contact:

Post by Seb McClouth »

Lee wrote:2, How can I make letters typed in the INPUT command come out as *'s (exmaple, password program)
I'm used this routine in a older vrsion of QBinux:

Code: Select all

        DO 
          PRINT tdspl$;"   " 'Display storing variable 
          press$ = INKEY$ 
          IF press$ <THEN> 0 THEN 
                sb = LEN(dspl$) 
                Ndspl$ = MID$(dspl$, 1, (sb - 1)) 
                dspl$ = Ndspl$ 
            ELSEIF press$ = CHR$(13) THEN 
                EXIT DO 
         ELSE 
                dspl$ = dspl$ + press$ 
                tdspl$=tdspl$ + "*"
         END IF 
  END IF 
  LOOP 
I use locate to print it on the same line. The code is not written by me, just adapted by me. The code was written by Rattrapmax6.

Here's his code:
Rattrapmax6 wrote:]Right.. I sat back and wrote a more simulated Password system, it asks for username, then the password.. and while you type the pasword it displays it as: "******"..

Very nice, and something you can play with, look over, and learn from maybe.. :wink:

Psssys.bas (Made in FreeBasic, Tested in QBasic.. Runs well in both..)

Code: Select all

'Username/Password system by Rattrapmax6(Kevin(x.t.r.GRAPHICS))
' Two test usernames: User1 and Admin
'Passwords: User1 = Enter || Admin = LetMeIn
' System is case-insensitive.. :)

CLS 'Clear screen
PRINT "Welcome!"
PRINT "Enter User:";
DO
    LOCATE 2, 12: PRINT dspl$; "   " 'Display storing varible
    press$ = INKEY$
    IF press$ <THEN> 0 THEN
            sb = LEN(dspl$)
            Ndspl$ = MID$(dspl$, 1, (sb - 1))
            dspl$ = Ndspl$
        'Filter Enter, Exit for checking
        ELSEIF press$ = CHR$(13) THEN
            EXIT DO
        'Add up user input to varible
        ELSE
            dspl$ = dspl$ + press$
        END IF
    END IF
LOOP

SELECT CASE UCASE$(dspl$)
CASE "USER1"
    PRINT "Enter Pasword:";
    usr$ = dspl$
    dspl$ = ""
    DO
        LOCATE 3, 15: PRINT pss$; "   "' NEW, print the ** for the varible
        press$ = INKEY$
        IF press$ <THEN> 0 THEN
                sb = LEN(dspl$)
                Ndspl$ = MID$(dspl$, 1, (sb - 1))
                Npss$ = MID$(pss$, 1, (sb - 1)) 'NEW, Subtract ***
                dspl$ = Ndspl$
                pss$ = Npss$ 'Restore the ***
            ELSEIF press$ = CHR$(13) THEN
                EXIT DO
            ELSE
               dspl$ = dspl$ + press$
               pss$ = pss$ + "*" 'NEW, calculate how many ***
            END IF
        END IF
    LOOP
    IF UCASE$(dspl$) = "ENTER" THEN 
        PRINT "Welcome to our servers, "; usr$; "!"
        PRINT "Press any key to end..."
        SLEEP
        END
    ELSE
        PRINT "Username and password to not compute!"
        PRINT "Press any key do end..."
        SLEEP
        END
    END IF
CASE "ADMIN"
    PRINT "Enter Pasword:";
    usr$ = dspl$
    dspl$ = ""
    DO
        LOCATE 3, 15: PRINT pss$; "   "
        press$ = INKEY$
        IF press$ <THEN> 0 THEN
                sb = LEN(dspl$)
                Ndspl$ = MID$(dspl$, 1, (sb - 1))
                Npss$ = MID$(pss$, 1, (sb - 1))
                dspl$ = Ndspl$
                pss$ = Npss$
            ELSEIF press$ = CHR$(13) THEN
                EXIT DO
            ELSE
               dspl$ = dspl$ + press$
               pss$ = pss$ + "*"
            END IF
        END IF
    LOOP
    IF UCASE$(dspl$) = "LETMEIN" THEN 
        PRINT "Welcome to our servers, "; usr$; "!"
        PRINT "Press any key to end..."
        SLEEP
        END
    ELSE
        PRINT "Username and password do not compute!"
        PRINT "Press any key to end..."
        SLEEP
        END
    END IF
CASE ELSE
    PRINT "No user under that name: Try again..."
    PRINT "Press any key to end..."
    SLEEP
    END
END SELECT 
[/quote]
QBinux is a Linux distribution with the aim of integrating the work of the vast community of free software developers at Pete's QBASIC Site in order to create a modern, performant, safe and easy to use system for system administrators and desktop users.
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

thanks McClouth! Sure that'll help :)

Now, can someone explain teh INP command in some detail please.
I'm using it to get input from the keyboard but when I use it, it like prints out 8 "Hey's" or whatever. What Im I doing wrong? Here's an example:

Code: Select all

CLS
DO
k = INP(&H60)

CASE SELECT k

CASE 2
PRINT "This is number 2";

CASE 3
PRINT "This is number 3";

END SELECT
LOOP
User avatar
Seb McClouth
Veteran
Posts: 342
Joined: Wed Nov 09, 2005 7:47 am
Location: Inside the Matrix...
Contact:

Post by Seb McClouth »

I suspect that INP(&H60) doesn't work the same as INKEY$.

I'll check it out later for you.
QBinux is a Linux distribution with the aim of integrating the work of the vast community of free software developers at Pete's QBASIC Site in order to create a modern, performant, safe and easy to use system for system administrators and desktop users.
User avatar
burger2227
Veteran
Posts: 2466
Joined: Mon Aug 21, 2006 12:40 am
Location: Pittsburgh, PA

Your silly

Post by burger2227 »

This will show you the codes returned when you press most any keys. Save this routine in case you try to use the codes in a program for reference:

Code: Select all

DO 
   scancode = INP(&H60)
   LOCATE 5, 10: PRINT scancode
LOOP UNTIL scancode = 1  'escape key press
Notice that the release code is 128 more than the press code. The codes do not change for upper or lower cases either.

Ted
Please acknowledge and thank members who answer your questions!
QB64 is a FREE QBasic compiler for WIN, MAC(OSX) and LINUX : https://www.qb64.org/forum/index.php
Get my Q-Basics demonstrator: https://www.dropbox.com/s/fdmgp91d6h8ps ... s.zip?dl=0
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

Thanks Burger and McClouth. Question Burger, Why when I make a program (like my last post) and press 2 or 3 it prints out like 8 of them?
Patz QuickBASIC Creations
Veteran
Posts: 399
Joined: Wed Mar 02, 2005 9:01 pm
Location: Nashville, Tennessee
Contact:

Post by Patz QuickBASIC Creations »

I made this a long time ago... Hopefully you can get it to work without too much work. I've commented it so you can see exactly what's going on and exactly how to use it... Basic knowledge of LOCATE a major plus.

http://pastebin.ca/874102
Sinuvoid
Veteran
Posts: 155
Joined: Wed Jul 25, 2007 8:20 am

Post by Sinuvoid »

Complicated, but useful :P So to back space I guess, it involves messing around with the LOCATE command...btw, do you know my problem? (With the INP command in my previous post :P )
Patz QuickBASIC Creations
Veteran
Posts: 399
Joined: Wed Mar 02, 2005 9:01 pm
Location: Nashville, Tennessee
Contact:

Post by Patz QuickBASIC Creations »

I don't recommend using INP, as if you make the program correctly, INKEY$ should be enough for most purposes.

To use backspace, you have to print a blank space (CHR$(32) or " "), and then locate back to that space. That's the most simple way to do it.

Edit: To do something similar to the pssys program above, just make a program with the PInput$ function, and then do the following code.

Code: Select all

DO UNTIL UserAllowed%
 CLS
 PRINT "Username:"
 User$ = PINPUT$(15,1,30,0,"")
 PRINT "Password:"
 Pass$ = PINPUT$(15,2,30,ASC("*"),"")
 IF User$ = "USER1" AND Pass$ = "ENTER" THEN UserAllowed% = 1
 IF User$ = "ADMIN" AND Pass$ = "LETMEIN" THEN UserAllowed% = 1
LOOP
User avatar
Seb McClouth
Veteran
Posts: 342
Joined: Wed Nov 09, 2005 7:47 am
Location: Inside the Matrix...
Contact:

Post by Seb McClouth »

I had posted a big post with some links concerning &H60 and INP but indeed like Pats said, better use Inkey$.

I guess the post got lost somehow, well no worries.
QBinux is a Linux distribution with the aim of integrating the work of the vast community of free software developers at Pete's QBASIC Site in order to create a modern, performant, safe and easy to use system for system administrators and desktop users.
Post Reply