Qbasicnews.com

Full Version: Cobra
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
The pureQB trick uses a 127 indexes array to store keyboard info. For example, key Enter has scancode # &H1D, so keys%(&H1D) will be -1 (TRUE) if Enter is pressed, otherwise 0 (FALSE).

To do the trick, the array is written inside a loop, for example the vertical retrace loop or your timing loop. Port &H60 is read, and the value returned is set in the array, then the buffer is cleared. In the next loop, a new key will be read from the buffer if you are pressing several.

At the end of the loop, all your multiple keypresses have been read and you just have to check the correct indexes in the array keys%(), for example, keys%(72) to read the "UP" key.

When you've checked all the keypresses, you just put all key%() array indexes to 0, to clear your virtual keyboard handler.

Check this snipped by Eric Carr to understand how it works

Code:
'===========================================================================
' Subject: SIMULTANEOUS KEY DEMO             Date: 03-18-96 (13:12)      
' Author:  Eric Carr                         Code: QB, QBasic, PDS        
' Origin:  FidoNet QUIK_BAS Echo           Packet: KEYBOARD.ABC
'===========================================================================
'Ok..Here is the sample keyboard routine I promised..I haven't tested it on any
'other computer excpet mine, but it should work for anyone..  This program lets
'you move a box around by pressing the arrow keys..The acual routine in only 4
'lines as i have marked..This program requires a minimum of a 486sx 25mhz if
'not compiled to run fast enough for all the keys to be updated..I also
'reprogrammed the internal timer from 18.2 to 30, so I could time it to 30 fps.
'To see if a key is being currently pressed, the variable KS is used (IF
'KS(75)=1 THEN button is pressed). Instead of ASCII, this uses scan codes,
'which you can look at in the QB help..Hope you can understand it! :)

DEFINT A-Z: DIM B(300): CLS

N& = 39772                  'Reprogram the timer to 30hz
LB& = N& AND &HFF           'instead of 18.2 (for 30 frames
HB& = (N& / 256) AND &HFF   'per second.)
OUT &H43, &H3C: OUT &H40, LB&: OUT &H40, HB&

DIM KS(255), SC(255), DU(255)
FOR E = 0 TO 127      ' Setup key data table KSC()
SC(E) = E: DU(E) = 1
NEXT
FOR E = 128 TO 255
SC(E) = E - 128: DU(E) = 0
NEXT

SCREEN 13: COLOR 4
LOCATE 10, 3: PRINT "Keyboard input routine by Eric Carr"
COLOR 7: PRINT : COLOR 2
PRINT "  Use the arrow keys to move the box."
PRINT "Note that you can press two or more keys"
PRINT "    at once for diagnal movement!"
PRINT : COLOR 8: PRINT "          Press [Esc] to quit"
X = 150: Y = 100: BX = X: BY = Y
DEF SEG = 0
POKE (1132), 0
GET (X, Y)-(X + 15, Y + 15), B
DO  'main loop

' __ By NATHAN __ : This is the loop where KS array is
' filled with values depending on the keypresses:

T:
I$ = INKEY$       ' So the keyb buffer don't get full     \routine/
I = INP(&H60)     ' Get keyboard scan code from port 60h   \lines/
OUT &H61, INP(&H61) OR &H82: OUT &H20, &H20       '         \!!!/
KS(SC(I)) = DU(I) ' This says what keys are pressed          \!/

IF PEEK(1132) < 1 THEN GOTO T  'If not enough time was passed goto T



POKE (1132), 0  'reset timer again
BX = X: BY = Y

' __ By NATHAN __ See how we check inside the array for
' keypresses:

IF KS(75) = 1 THEN XC = XC - 2: IF XC < -15 THEN XC = -15
IF KS(77) = 1 THEN XC = XC + 2: IF XC > 15 THEN XC = 15
IF KS(72) = 1 THEN YC = YC - 2: IF YC < -15 THEN YC = -15
IF KS(80) = 1 THEN YC = YC + 2: IF YC > 15 THEN YC = 15
IF XC > 0 THEN XC = XC - 1 ELSE IF XC < 0 THEN XC = XC + 1
IF YC > 0 THEN YC = YC - 1 ELSE IF YC < 0 THEN YC = YC + 1
Y = Y + YC: X = X + XC
IF X > 300 THEN X = 300 ELSE IF X < 0 THEN X = 0
IF Y > 180 THEN Y = 180 ELSE IF Y < 0 THEN Y = 0
IF X <> BX OR Y <> BY THEN
WAIT 936, 8: PUT (BX, BY), B, PSET
GET (X, Y)-(X + 15, Y + 15), B: LINE (X, Y)-(X + 15, Y + 15), 9, BF
END IF
LOOP UNTIL KS(1) = 1 'loop until [Esc] (scan code 1) is pressed

N& = 65535                      'Program the timer back to
LB& = N& AND &HFF               '18.2hz before exiting!
HB& = (N& / 256) AND &HFF
OUT &H43, &H3C: OUT &H40, LB&: OUT &H40, HB&

OUT &H61, INP(&H61) OR &H82: OUT &H20, &H20
CLEAR   'need to have this if reprograming the timer
END      'I think this ends the program. I'm not quite sure.. :)

This code snipped uses timer. Windoze doesn't like that, so maybe you'll like to code a VGA retrace wait loop:

Code:
' Missing initialization code, just line in Carr's routine

' This is the same as WAIT &H3DA,8: WAIT &H3DA,8,8
' Nathan's code, untested but likely to work

' while bit 3 of port 3DAh is 0 do keyboard stuff;
WHILE (INP(&H3DA) AND 8 ) = 0
   ' Put here the ks stuff and so:
   I$ = INKEY$       ' So the keyb buffer don't get full     \routine/
   I = INP(&H60)     ' Get keyboard scan code from port 60h   \lines/
   OUT &H61, INP(&H61) OR &H82: OUT &H20, &H20       '         \!!!/
   KS(SC(I)) = DU(I) ' This says what keys are pressed          \!/
WEND

' while bit 3 of port 3DAh is 1 no opperation;
WHILE (INP(&H3DA) AND 8 ) = 8
WEND

Hope this works TongueTongueTongueBig Grin
here. what port 60h [inp (&H60)] does is it fires off whenever a key is pressed or released. this keeps track of the keypresses, and the key releases and stores them into kbd(). scan codes are slightly different than with inkey$, so test some of the keys with this demo

Code:
DIM kbd(140)  AS INTEGER

DEF SEG = &H40: POKE &H1C, PEEK(&H1A): POKE &H17, PEEK(&H17) AND NOT 32
'frames loop
DO
    'keyboard input
    K% = INP(&H60): kbd(K% AND 127) = -((K% AND 128) = 0)
    DEF SEG = &H40: POKE &H1C, PEEK(&H1A)
    IF kbd(1) THEN EXIT DO

    LOCATE 1, 40: PRINT K%
    LOCATE 1, 1
    FOR i = 0 TO 19
     PRINT kbd%(i); "  ";
     PRINT kbd%(i + 20); "  ";
     PRINT kbd%(i + 40); "  ";
     PRINT kbd%(i + 60); "  ";
     PRINT kbd%(i + 80); "  ";
     PRINT kbd%(i + 100); "  ";
     PRINT kbd%(i + 120); "  "
    NEXT
LOOP
gash dernit, nate, ya beat me to it! :evil: :evil: :evil:

oh well. i should mention i got the core code for above demo from an antoni gual raycaster.
Our codes do the same in different manners, but I think yours is way better.
good point. just check and clear the buffer...

y'know, i've been finding more and more useful "pure" qb alternatives to libs. first seav's timer, now antoni's multikey, really the only thing worth getting a lib for is multimedia (sound and graphics)... i'm kinda glad cosmox lets you build the objs yourself...
Yeah, the best thing is to build up your own lib peeking here and there.

About PQB alternatives, QMIDI 4.1 and DMAPlay work good together and give a good sound engine, if MIDI music and 1 channel digital sound are enough for you Tongue
i always thought qmidi was a qlb... hmm.. then i wonder why i didnt use it before... *shrugs*. i hear the subshock team, whenever they are rescued from their cryogenic status are producing a pure qb mod player suitable for games. that oughta be interesting... and hey, remember mk jamz?
Nope, What's that?

About Qmidi... Yeah, you have seen the QLB version, but Jesse Dorland made that one in pure QB first, then someone compiled it into a QLB. I think you can find it in the alypha URL I gave before in this same thread.
*nods* i would prefer some of the bigger libs (ds4qb, bwswb[sp?]) if you could compartmentalize them.
My problem with DS4QB is the huge lag (I have a slow compter) and that it takes so many resources. I have to stick with DOS lil'libs.

Anyhow, I never got BWSB to work... Can you give me some help?
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19