×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

How to use 2+ keys at once to do 2+ thing at once
2

How to use 2+ keys at once to do 2+ thing at once

How to use 2+ keys at once to do 2+ thing at once

(OP)
I'm writing a top down scroller I would like to use the up arrow and the left arrow to make my sprite go diagonal.
I already know how CHAR numbers but I can only use one at a time my code:

PRESS$=INKEY$
IF PRESS$= CHR$(116) THEN GOSUB FORWARD
IF PRESS$= CHR$(71) THEN GOSUB BACK
IF PRESS$= CHR$(70) THEN GOSUB LEFT
IF PRESS$= CHR$(73) THEN GOSUB RIGHT
(Also this setup is very laggy it takes a second to respond)
any help would be great.

RE: How to use 2+ keys at once to do 2+ thing at once

check out the thread faster inkey$ in qbasic in this forum

RE: How to use 2+ keys at once to do 2+ thing at once

Forget inkey$...
use this...


DECLARE SUB SETKEYS ()
DECLARE SUB CLEARBUF ()
DECLARE SUB GETKEYS ()

CONST TRUE = -1: FALSE = 0

Dim SHARED KB(128), lastk

'THESE ARE OPTIONAL ALONG WITH THE SETKEYS SUB...
Dim SHARED KBUP, KBDOWN, KBLEFT, KBRIGHT, KBESC, KBLSHIFT, KBRSHIFT, KBCTRL, KBSPACE, KBALT
SETKEYS


'USAGE EXAMPLE...
Do
  GETKEYS   'GET KEYBOARD INPUT
  LOCATE 3, 1: Print "KEYBOARD: UP KB(72)="; KB(72); " DOWN KB(80)="; KB(80); " LEFT KB(75)="; KB(75); " RIGHT KB(77)="; KB(77)
  LOCATE 4, 1: Print "          ALT KB(56)="; KB(56); " CTRL KB(29)="; KB(29); " SPACE KB(57)="; KB(57); "        "
Loop Until KB(KBESC) 'END ON ESC
End

Sub CLEARBUF()
  DEF SEG = &H40
  POKE &H1A, PEEK(&H1A + 2)
'  or use this...
'  FOR N = 0 TO 10: S$ = INKEY$: NEXT
End Sub

'This Is the Main Sub that does all the work
Sub GETKEYS()
  K = INP(96)
  If K Then                  'KEY CHANGED
    If K < 128 Then          'KEY PRESSED
      KB(K) = True           'SET THE KEY
      lastk = K              'SET THE LAST KEY PRESSED MARKER
    Else                     '....ELSE...LAST KEY RELEASED
      If K = 170 Then        'NOTE: (SC) 170 IS RELEASE LAST KEY PRESSED
        KB(lastk) = False    'CLEAR LAST KEY PRESSED
      Else                   '...ELSE...OTHER KEY RELEASED
        KB(K - 128) = False  'CLEAR RELEASED KEY
      End If
    End If
  End If
  CLEARBUF 'CLEAR REGULAR KEY BUFFER KEY BUFFER (NO BEEPS)
End Sub

'These are optional
Sub LEARNKEY()
  'THIS SUB IS FOR USE IN THE IMMEDIATE WINDOW
  '*** NOTE YOU MUST RUN THE PROGRAM FIRST
  KB(1) = 0
  Do
  GETKEYS
  LOCATE 1, 1: Print "PRESS A KEY FOR SCAN CODE BELOW"
  LOCATE 2, 1: Print lastk
  Loop Until KB(1)
End Sub

Sub SETKEYS()
  KBUP = 72
  KBDOWN = 80
  KBLEFT = 75
  KBRIGHT = 77
  KBESC = 1
  KBLSHIFT = 42
  KBRSHIFT = 54
  KBCTRL = 29
  KBSPACE = 57
  KBALT = 56
End Sub

Gotta LuV multiKey Input...
Visit my site for full input program including mouse and some gamepad input...
http://cubee.topcities.com
this file is located at:
http://cubee.topcities.com/bas/mmsinput.bas

Thanks,
-Josh Stribling

RE: How to use 2+ keys at once to do 2+ thing at once

very easy to do.

here's a very basic scroller.  i'm assuming you have all the subs.

common shared press as integer


press = inp(&h60) '(&h60) points to the keyboard buffer or something like that...

select case press
case 72
pressupkey

case 80
pressdownkey

case 75
pressleftkey

case 77
pressrightkey

end select
loop until press = chr$(27) 'esc key


that's for the four keys.  add this after your all those cases.

case 77 and 72
pressupandrightkey

and so on.

subpressupandrightkey


'assuming that this is a tile scrolling engine...

px = px + 1 'player x position on screen
py = py - 1 'player y position on screen

'i'm assuming that the tiles are 20*20. if they're something else,
'change the twenty on the bottom to what the dimensions are in order.
redrawscreen 'so you don't get an after image.
put (px * 20, py * 20)player, pset

'or if you're using masks...

put (px * 20, py * 20)playermask, and
put (px * 20, py * 20)player, or

'changing px and py at the same time moves the player diagonally.  if you're using a pixel*tile scroller...


'zy is the movement of the player's y coordinates, pixel by pixel.
'zx is the movement of the player's x coordinates, pixel by pixel.

submoveplayerupright
do
zy = zy + 1
zx = zx + 1

if zy = 20 and zx = 20 then
px = px + 1 'px takes over from zx
py = py - 1 'py takes over from zy
zy = 0 'put zy to zero so we can exitthe loop
zx = 0 'put the zx to zero so we can exit the loop
endif

redrawscreen
put (px + 20 + zx, py * 20 - zy)player, pset

loop until zy = 0 and zx = 0
endsub


that should clear things up... if it doesn't, tell me.  i haven't tested it.  i am not certain what it'll do... if it doesn't work, try assigning a second PRESS and do the same thing with the original press
(press = inp(&h60): press2 = inp(&h60)

that MIGHT work... e-mail me at marshall_7ca@yahoo.ca and we can talk.

RE: How to use 2+ keys at once to do 2+ thing at once

No... You're leaving a few things out...

You are only checking for key presses... No releases (key + 128)...
And you are not saving the last Key Pressed and releasing it with the 170 event... (when press = 170)

with this Code it will continue to scroll until you press another button... (plus... ESC is key 1, not chr$(27))

Not to mention the fact that you are NOT clearing the keyboard buffer wich WILL result in annoying beeps...

Using the same code, and my sub from above, this is what it needs to look like this...


DECLARE SUB SETKEYS ()
DECLARE SUB CLEARBUF ()
DECLARE SUB GETKEYS ()

CONST TRUE = -1: FALSE = 0

Dim SHARED KB(128), lastk

Dim SHARED KBUP, KBDOWN, KBLEFT, KBRIGHT, KBESC, KBLSHIFT, KBRSHIFT, KBCTRL, KBSPACE, KBALT
SETKEYS

px = 160
py = 100
Do
  ox = px
  oy = py
  GETKEYS   'GET KEYBOARD INPUT

  if KB(KBUP) then
    py = py - 1
  end if

  if KB(KBDOWN) then
    py = py + 1
  end if

  if KB(KBLEFT) then
    px = px - 1
  end if

  if KB(KBRIGHT) then
    px = px + 1
  end if

  if (px <> ox) or (py <> oy) then
    'move the character
    'draw the screen...
  end if

  'all your other code here...

Loop Until KB(KBESC) 'END ON ESC
End

Sub CLEARBUF()
  DEF SEG = &H40
  POKE &H1A, PEEK(&H1A + 2)
End Sub

'This Is the Main Sub that does all the work
Sub GETKEYS()
  K = INP(96)
  If K Then                  'KEY CHANGED
    If K < 128 Then          'KEY PRESSED
      KB(K) = True           'SET THE KEY
      lastk = K              'SET THE LAST KEY PRESSED MARKER
    Else                     '....ELSE...LAST KEY RELEASED
      If K = 170 Then        'NOTE: (SC) 170 IS RELEASE LAST KEY PRESSED
        KB(lastk) = False    'CLEAR LAST KEY PRESSED
      Else                   '...ELSE...OTHER KEY RELEASED
        KB(K - 128) = False  'CLEAR RELEASED KEY
      End If
    End If
  End If
  CLEARBUF 'CLEAR REGULAR KEY BUFFER KEY BUFFER (NO BEEPS)
End Sub

Sub SETKEYS()
  'These are common keys...
  KBUP = 72     'Up Arrow
  KBDOWN = 80   'Down Arrow
  KBLEFT = 75   'Left Arrow
  KBRIGHT = 77  'right Arrow
  KBESC = 1     'Esc Key
  KBLSHIFT = 42 'Left Shift
  KBRSHIFT = 54 'Right Shift
  KBCTRL = 29   'Ctrl Key
  KBSPACE = 57  'Space Bar
  KBALT = 56    'Alt Key
End Sub


with that code, you can:
press right to scroll over...
press up at the same time to change directions to diagonal...
release right to just scroll up...
etc...

This is the way you NEED to write the code to make it work CORRECTLY...

Sometimes... the BASIC things in life are the best...

or at least the most fun
-Josh Stribling

RE: How to use 2+ keys at once to do 2+ thing at once

I HOPE IT WORKS BUT YOU CAN USE THIS LITTLE PROGRAM
PSET(0,0)
DO
DO
KEY$ =INKEY$
LOOP UNTIL KEY$ <>""
NUMKEY%=ASC(RIGHT$(KEY$,1))
SELECT CASE NUMKEY%
CASE 72 upkey
y =y+1
CASE 80 downkey
y = y-1
CASE 75 leftkey
x = x-1
CASE 77 rightkey
x =x+1
CASE ELSE
END SELECT
PSET (X,Y)
LOOP UNTIL NUMKEY% = 27 (esc key)

RE: How to use 2+ keys at once to do 2+ thing at once

Inkey$ is a single key function...

to use multikey you have to write your own...

to write your own you have to use INP(96) aka INP(&H60)... (&H60 = 96)

to use INP(96) you have to know EVERYTHING that is going on...

What is returned when, and why it is returned...

your best bet is to use the code I placed above...

If you don't understand a part of it, just let me know...

THNX,
Josh

Have Fun, Be Young... Code BASIC
-Josh Stribling

http://cubee.topcities.com

RE: How to use 2+ keys at once to do 2+ thing at once

I've used INP(96) for along time now for the input from the keyboard buffer and I've only been able to do multikey inputs buy saving the last key and I used press = inkey$ to get rid of those stupid beeps, but I've been wondering is there a way to monitor the keyboard with the Peek command? If anyone knows please tell me. THX

RE: How to use 2+ keys at once to do 2+ thing at once

I don't think there is...

INP function, if you read the help file, is a function that reads a byte from a device I/O port... (not memory)

PEEK/POKE read/write to and from memory...

just like an interupt can not be accessed with peek/poke...

they are all different parts of the processor...

Now you might be able to write some sort of Assembly routine to use, if you are worried about speed... but I believe the answer to the Peek question is NO...

Sorry

But... If I am wrong, and someone does know a way, I would also like to know...

Have Fun, Be Young... Code BASIC
-Josh Stribling

http://cubee.topcities.com

RE: How to use 2+ keys at once to do 2+ thing at once

Well, I did find a way to monitor the ctrl, alt, caps, num lock, scroll lock, and insert keys using

DEF SEG = 0  
DO
A = PEEK(1047)
B = INP(96)
LOCATE 1
PRINT A
LOOP UNTIL B = 1
DEF SEG

This works well. I also found a way to montor te rest of the keyboard using PEEK (It took me forever after testing and testing), but it doesn't work that good (all it can do is tell if a key has been pressed):

DEF SEG = 0
DO
A = PEEK(1050)
B = PEEK(1052)
C = INP(96)
LOCATE 1
PRINT A
LOCATE 2
PRINT B
LOOP UNTIL C = 1
DEF SEG

PEEK(1050) and PEEK(1052) I think do the same thing.
The problem with this is that it only tells if a key (other than ctrl, alt, caps, etc...) has beenn pressed and not which one.

RE: How to use 2+ keys at once to do 2+ thing at once

I was doin experiments and found out PEEK(1050) and PEEK(1052) is just the keyboard buffer thing because if you add INKEY$ anywhere in the code the numbers reset (because INKEY$ clears out the keyboard buffer). So all that is is the keyboard buffer I think.

RE: How to use 2+ keys at once to do 2+ thing at once

(OP)
Well thanks guys that's what I needed

RE: How to use 2+ keys at once to do 2+ thing at once

*reads old post up top, hits his head*
god, what a noob i was.  I can't stand to read that!  *bangs head some more*

good call cube.  just wish you took a bit more out of me, like calling me a noob and making fun of my pretend multikey knowledge.  ;)  

oh, your welcome icaerus, although i never did squat ;)

RE: How to use 2+ keys at once to do 2+ thing at once

Lol...
Yeah, I was looking at those dates earlier today also...

Man, It doesn't seem like a year ago...

But the programming scene is always changing and people are constantly finding better ways of doing things...

So you are always learning...

And I (still) think the best way to learn is by trial and error (and other people correcting your errors )

I think I even had a typo up there...

I don't think this line is entirely true...
with this Code it will continue to scroll until you press another button

Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com

RE: How to use 2+ keys at once to do 2+ thing at once

who wrote that originally?  if it was me, i'm banging my head some more :P

yes, the memories... tek-tips was fairly popular back then as well.  too bad people don't stay long...

maybe tek tip's a bit too strict for them? (you know, the policy of only making code related topics,  deleting posts that don't fit or advertise or whatever (i agree witht he ad and homework policy though!)  

RE: How to use 2+ keys at once to do 2+ thing at once

Yeah, I have developed my skills quite a bit since I have been using Tek-Tips...

You get some people asking how to do some off the wall stuff and it gets your gears spinning...
Before you know it you have a solution figured out and you are able to answer the person's question and also learn something at the same time

I agree with the Ad & HomeWork Policy too...

I am glad to see the Qbasic comunity growing again...

It seemed like there were no posts at all for about 6 months or so...

Qbasic is a good stepping stone for jumping into VB, which is a VERY powerful tool...

I have managed to link just about Every Program that we use at work together via Visual Basic
Which in turn saves alot of time from repeating stuff...

(Not to mention the challenge of pushing a dos interpreter to the limits for games and stuff )

Have Fun, Be Young... Code BASIC
-Josh

http://cubee.topcities.com

RE: How to use 2+ keys at once to do 2+ thing at once

If you use INKEY$ or INP(96) it will pause before repeating, so screw them both, this multikey routine uses assembly, it DOES NOT PAUSE, and you can use as many keys at a time as you want.

DECLARE SUB offkb ()
DECLARE SUB onkb ()
DECLARE SUB readassembly ()
REDIM kbcontrol%(128), kbmatrix%(128)
readassembly
onkb
DO
CLS
LOCATE 1
FOR a% = 0 TO 128
    IF kbmatrix%(a%) THEN PRINT a%    '<- tells you which key(s) are being pressed
    IF kbmatrix%(1) THEN offkb: END    '<- Press Esc to leave
NEXT
LOOP

kbdata:
DATA &HE9,&H1D,&H00,&HE9,&H3C,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00,&H00
DATA &H00,&H00,&H00,&H00,&H1E,&H31,&HC0,&H8E,&HD8,&HBE,&H24,&H00,&H0E,&H07
DATA &HBF,&H14,&H00,&HFC,&HA5,&HA5,&H8C,&HC3,&H8E,&HC0,&HBF,&H24,&H00,&HB8
DATA &H56,&H00,&HFA,&HAB,&H89,&HD8,&HAB,&HFB,&H1F,&HCB,&H1E,&H31,&HC0,&H8E
DATA &HC0,&HBF,&H24,&H00,&HBE,&H14,&H00,&H0E,&H1F,&HFC,&HFA,&HA5,&HA5,&HFB
DATA &H1F,&HCB,&HFB,&H9C,&H50,&H53,&H51,&H52,&H1E,&H56,&H06,&H57,&HE4,&H60
DATA &HB4,&H01,&HA8,&H80,&H74,&H04,&HB4,&H00,&H24,&H7F,&HD0,&HE0,&H88,&HC3
DATA &HB7,&H00,&HB0,&H00,&H2E,&H03,&H1E,&H12,&H00,&H2E,&H8E,&H1E,&H10,&H00
DATA &H86,&HE0,&H89,&H07,&HE4,&H61,&H0C,&H82,&HE6,&H61,&H24,&H7F,&HE6,&H61
DATA &HB0,&H20,&HE6,&H20,&H5F,&H07,&H5E,&H1F,&H5A,&H59,&H5B,&H58,&H9D,&HCF,-1

SUB offkb
SHARED keyboardonflag%, kbcontrol%()
IF (keyboardonflag% = 0) THEN EXIT SUB
keyboardonflag% = 0
DEF SEG = VARSEG(kbcontrol%(0))
CALL Absolute(3)
DEF SEG
END SUB

SUB onkb
SHARED kbcontrol%(), keyboardonflag%
IF keyboardonflag% THEN EXIT SUB
keyboardonflag% = 1
DEF SEG = VARSEG(kbcontrol%(0))
CALL Absolute(0)
DEF SEG
END SUB

SUB readassembly
SHARED kbcontrol%(), kbmatrix%()
RESTORE kbdata
DEF SEG = VARSEG(kbcontrol%(0))
I& = 0
GOTO skip0
DO
POKE I&, q%
I& = I& + 1
skip0:
READ q%
LOOP WHILE q% > -1
I& = 16
n& = VARSEG(kbmatrix%(0))
l& = n& AND 255
h& = ((n& AND &HFF00) \ 256)
POKE I&, l&
POKE I& + 1, h&
I& = I& + 2
n& = VARPTR(kbmatrix%(0))
l& = n& AND 255
h& = ((n& AND &HFF00) \ 256)
POKE I&, l&
POKE I& + 1, h&
I& = I& + 2
DEF SEG
END SUB

This is the same code that is in my FAQ, for future reference.

RE: How to use 2+ keys at once to do 2+ thing at once

Wow even i was on this way back in May when I was a complete and stupid newbie (not that I'm not now cause i still am). its funny people have been replying to posts from years back lately.

RE: How to use 2+ keys at once to do 2+ thing at once

Well there is always discussion about the best ways to do something, that the only way to make advances.

RE: How to use 2+ keys at once to do 2+ thing at once

Hey, I'm a noob here.  I'm using qbasicking's keyboard routine for a platform game, and it works great except for one strange problem.  Using the arrow keys (but NOT the numpad arrow keys) turns on not only 72, 75, 77, and 80, but 42 (left shift) as well.  Since I wanted to use left shift as a speed control (hold to run), this obviously presents a problem, in that the player runs regardless of whether shift is pressed.  It's worth mentioning that pressing and releasing the left shift key fixes the problem, at least until the next time the arrow key is pressed.

Since I haven't seen any mention of this kind of problem before, I'm seriously wondering if it's just my keyboard acting weird.  I tried Cube's code and had the same problem.  But if there's any help to be had, I'd appreciate it.

RE: How to use 2+ keys at once to do 2+ thing at once

I noticed that too, but not in the original coding, it only started to happen after I added some more code, It must do something to it.  You can fix it by when you turn the keyboard function on simply saying kbmatrix%(42) = 0 in the sub onkb, it fixes the problem.

RE: How to use 2+ keys at once to do 2+ thing at once

when you run the code by itself, it runs very fast.  when you add more code to it (a game) i find that multi-key routines seem to stick a bit (at least pure qb....) maybe because it takes so long to loop again or something...

RE: How to use 2+ keys at once to do 2+ thing at once

Pure QB multikey routines will stick in an intensive program because it will miss one of the key release scan codes when two keys are released almost simultaneously.

Speaking of scan codes, I figured out where my problem is.  The arrow keys are rather unusual: they send an extended key scan code (E0) in addition to the normal code, but they also constantly send left Shift press and release scan codes. Turning NumLock on (or holding Shift) makes it stop doing that, but I'm not sure how to turn NumLock on and off within the program, because POKE(1047), PEEK(1047) OR 32 doesn't work after onkb is called.

RE: How to use 2+ keys at once to do 2+ thing at once

Any extra code slows a program down, the code that you added is what is making the program slower.  The multikey routine doesn't stick at all, its designed specifically not to.

If the arrow keys are doing strange things then is it possible to use the numeric keypad?  There you not only can use up, down, left, and right, but also the octo-cardinal directions.

RE: How to use 2+ keys at once to do 2+ thing at once

http://disc.server.com/discussion.cgi?disc=190399;artic...

Davs QB Code post is an invaluable resource. The above link is an ASM keyhandler like the others in this thread, but it includes an inkey$ substitute, as well as a couple other commands I can't live without. :)

RE: How to use 2+ keys at once to do 2+ thing at once

DPhrygian, try toggling the numlock. I can almost guarantee that it should fix many problems.

RE: How to use 2+ keys at once to do 2+ thing at once

Yes, as I said in my second post, turning numlock on fixes the problem (or I can just use the numpad keys, either way).  Thanks for the response (that goes for qbking as well!)

Incidentally, I'm wondering whether there's a way to turn numlock on (via QB, I mean) using the ASM keyhandler.  The usual method of POKEing 1047 apparently doesn't work once the keyhandler has been called, and just forcing the numlock key to be pressed (with a statement like kbmatrix%(69) = 1) won't actually turn numlock on.

But again, it's not really a big deal, since the user can just use the numpad keys or turn numlock on himself.

RE: How to use 2+ keys at once to do 2+ thing at once

The keyboard handler that I posted only tells you which key is pressed, not the state of it.  Meaning it makes no disguishment between a and A if caps lock is on or and up arrow and an 8 if num lock is on.

But you can determine if it is on or not by using PEEK 1047.
IF PEEK 1047 = <on> THEN key$ = "8" ELSE key$ = "up arrow"


Not having used the numlock in a long time I don't know which pattern tells you if it is on or off.

RE: How to use 2+ keys at once to do 2+ thing at once

Just turn it off before you activate the handler. Put it in the init routine for it even. :)

RE: How to use 2+ keys at once to do 2+ thing at once

what is a buffer

RE: How to use 2+ keys at once to do 2+ thing at once

There are two reasons to use buffers.  One way is to use a block of RAM to store a bit of memory from a file from quicker access.
Or the type of buffer used here is for quicker memory "dumps"  it is easier to more large amount of memory around.

RE: How to use 2+ keys at once to do 2+ thing at once

k thanks

RE: How to use 2+ keys at once to do 2+ thing at once

This seems to be a popular toppic again... (lets see if it will float to the top again... from like the 5th page...)

Have Fun, Be Young... Code BASIC
-Josh


http://cubee.topcities.com

PROGRAMMER: (n) Red-eyed, mumbling mammal capable of conversing with inanimate objects.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close