As most of you know, I've been porting UMoria over to BBC BASIC bit by
bit for the last couple of years. I'm now at the point of sorting out
the keyboard input code. The game uses the ESCape key and various CTRL
combinations to perform actions. I've got the ESCape key to behave
using OS_Byte &E5 (229). Is there any way of neutering the CTRL key in
a similar fashion so that it sets a bit, rather than performing any
other action defined by the VDU drivers?
I need to be able to distinguish between uppercase & lowercase as both
are used as CTRL combos.
I seem to remember a way of doing this on the Beeb, though I can't for
the life of me remember what it was.
Your help would be much appreciated.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/22/2012 3:42:28 PM |
|
In message <4802cf78-e210-4afa-acf0-a751668b03bb@hq4g2000vbb.googlegro
ups.com>
Gazza <usenet@garethlock.com> wrote:
> As most of you know, I've been porting UMoria over to BBC BASIC bit by
> bit for the last couple of years. I'm now at the point of sorting out
> the keyboard input code. The game uses the ESCape key and various CTRL
> combinations to perform actions. I've got the ESCape key to behave
> using OS_Byte &E5 (229). Is there any way of neutering the CTRL key in
> a similar fashion so that it sets a bit, rather than performing any
> other action defined by the VDU drivers?
In contrast to Esc, the Ctrl key does not have any associated action,
so there is no need to suppress it. You can enquire about the state of
the Ctrl key at any time using OS_Byte 121. Whatever code you use to
accept keyboard input might do specific things when it sees Ctrl
keypresses, so in order to answer your question you need to tell us
how you accept and interpret keyboard input in your program.
OS_ReadLine, for instance, interprets certain Ctrl keypresses.
--
Martin
---------------------------------------------------------------------
Martin Wuerthner MW Software http://www.mw-software.com/
RISC OS Software for Design, Printing and Publishing
---------------------------------------------------------------------
|
|
0
|
|
|
|
Reply
|
spamtrap3075 (2284)
|
5/22/2012 4:09:48 PM
|
|
On May 22, 5:09=A0pm, Martin Wuerthner <spamt...@mw-software.com> wrote:
> In message <4802cf78-e210-4afa-acf0-a751668b0...@hq4g2000vbb.googlegro
> ups.com>
> =A0 =A0 =A0 =A0 =A0 Gazza <use...@garethlock.com> wrote:
>
> > As most of you know, I've been porting UMoria over to BBC BASIC bit by
> > bit for the last couple of years. I'm now at the point of sorting out
> > the keyboard input code. The game uses the ESCape key and various CTRL
> > combinations to perform actions. I've got the ESCape key to behave
> > using OS_Byte &E5 (229). Is there any way of neutering the CTRL key in
> > a similar fashion so that it sets a bit, rather than performing any
> > other action defined by the VDU drivers?
>
> In contrast to Esc, the Ctrl key does not have any associated action,
> so there is no need to suppress it. You can enquire about the state of
> the Ctrl key at any time using OS_Byte 121. Whatever code you use to
> accept keyboard input might do specific things when it sees Ctrl
> keypresses, so in order to answer your question you need to tell us
> how you accept and interpret keyboard input in your program.
> OS_ReadLine, for instance, interprets certain Ctrl keypresses.
>
> --
> Martin
> ---------------------------------------------------------------------
> Martin Wuerthner =A0 =A0 =A0 =A0 MW Software =A0 =A0 =A0http://www.mw-sof=
tware.com/
> =A0 =A0 =A0 =A0 RISC OS Software for Design, Printing and Publishing
> ---------------------------------------------------------------------
Well... I was running a test program that just read from the keyboard
and displayed both the ASCII codes and the character/string
representation on the screen. The idea being I could trap CTRL+<key>
and display the character on the screen, manually prefixed with "^" if
it was part of a CTRL combo. However, I was stumbling across special
cases such as CTRL+U and others which of course do funny things with
the VDU drivers. What I want to do is to intercept this set a flag if
CTRL was pressed and return the ASCII code of just the character
pressed. I'm using GET to return ASCII codes with OS_Byte 229 set to a
non-zero value to supress Escape.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/22/2012 6:33:59 PM
|
|
In message <125e67a9-7565-4a7b-8439-53c951ff140b@l17g2000vbj.googlegro
ups.com>
Gazza <usenet@garethlock.com> wrote:
> On May 22, 5:09�pm, Martin Wuerthner <spamt...@mw-software.com> wrote:
>> In message <4802cf78-e210-4afa-acf0-a751668b0...@hq4g2000vbb.googlegro
>> ups.com>
>> � � � � � Gazza <use...@garethlock.com> wrote:
>>
>>> [...] Is there any way of neutering the CTRL key in
>>> a similar fashion so that it sets a bit, rather than performing any
>>> other action defined by the VDU drivers?
>>
>> In contrast to Esc, the Ctrl key does not have any associated action,
>> so there is no need to suppress it. You can enquire about the state of
>> the Ctrl key at any time using OS_Byte 121. Whatever code you use to
>> accept keyboard input might do specific things when it sees Ctrl
>> keypresses, so in order to answer your question you need to tell us
>> how you accept and interpret keyboard input in your program.
>> OS_ReadLine, for instance, interprets certain Ctrl keypresses.
> Well... I was running a test program that just read from the keyboard
> and displayed both the ASCII codes and the character/string
> representation on the screen. The idea being I could trap CTRL+<key>
> and display the character on the screen, manually prefixed with "^" if
> it was part of a CTRL combo. However, I was stumbling across special
> cases such as CTRL+U and others which of course do funny things with
> the VDU drivers.
Of course. Simply do not display characters with a code < 32 to the
screen.
> What I want to do is to intercept this set a flag if
> CTRL was pressed and return the ASCII code of just the character
> pressed. I'm using GET to return ASCII codes with OS_Byte 229 set to a
> non-zero value to supress Escape.
There is no need to do anything special. This is just a question of
interpreting the values you get. If you look at the returned codes it
should not be difficult to work out that Ctrl+A is 1, Ctrl+B is 2,
etc. If you want Ctrl+Shift as well, you need to test the shift key
explicitly.
--
Martin
---------------------------------------------------------------------
Martin Wuerthner MW Software http://www.mw-software.com/
RISC OS Software for Design, Printing and Publishing
---------------------------------------------------------------------
|
|
0
|
|
|
|
Reply
|
spamtrap3075 (2284)
|
5/22/2012 8:45:32 PM
|
|
On May 22, 9:45=A0pm, Martin Wuerthner <spamt...@mw-software.com> wrote:
> In message <125e67a9-7565-4a7b-8439-53c951ff1...@l17g2000vbj.googlegro
> ups.com>
> =A0 =A0 =A0 =A0 =A0 Gazza <use...@garethlock.com> wrote:
>
>
>
>
>
> > On May 22, 5:09=A0pm, Martin Wuerthner <spamt...@mw-software.com> wrote=
:
> >> In message <4802cf78-e210-4afa-acf0-a751668b0...@hq4g2000vbb.googlegro
> >> ups.com>
> >> =A0 =A0 =A0 =A0 =A0 Gazza <use...@garethlock.com> wrote:
>
> >>> [...] Is there any way of neutering the CTRL key in
> >>> a similar fashion so that it sets a bit, rather than performing any
> >>> other action defined by the VDU drivers?
>
> >> In contrast to Esc, the Ctrl key does not have any associated action,
> >> so there is no need to suppress it. You can enquire about the state of
> >> the Ctrl key at any time using OS_Byte 121. Whatever code you use to
> >> accept keyboard input might do specific things when it sees Ctrl
> >> keypresses, so in order to answer your question you need to tell us
> >> how you accept and interpret keyboard input in your program.
> >> OS_ReadLine, for instance, interprets certain Ctrl keypresses.
> > Well... I was running a test program that just read from the keyboard
> > and displayed both the ASCII codes and the character/string
> > representation on the screen. The idea being I could trap CTRL+<key>
> > and display the character on the screen, manually prefixed with "^" if
> > it was part of a CTRL combo. However, I was stumbling across special
> > cases such as CTRL+U and others which of course do funny things with
> > the VDU drivers.
>
> Of course. Simply do not display characters with a code < 32 to the
> screen.
>
> > What I want to do is to intercept this set a flag if
> > CTRL was pressed and return the ASCII code of just the character
> > pressed. I'm using GET to return ASCII codes with OS_Byte 229 set to a
> > non-zero value to supress Escape.
>
> There is no need to do anything special. This is just a question of
> interpreting the values you get. If you look at the returned codes it
> should not be difficult to work out that Ctrl+A is 1, Ctrl+B is 2,
> etc. If you want Ctrl+Shift as well, you need to test the shift key
> explicitly.
>
> --
> Martin
> ---------------------------------------------------------------------
> Martin Wuerthner =A0 =A0 =A0 =A0 MW Software =A0 =A0 =A0http://www.mw-sof=
tware.com/
> =A0 =A0 =A0 =A0 RISC OS Software for Design, Printing and Publishing
> ---------------------------------------------------------------------- Hi=
de quoted text -
>
> - Show quoted text -
So as long as I don't try to PRINT it until I figure out what I've
got, then all should be OK... Yes?
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/22/2012 11:03:09 PM
|
|
OK... As I suspected... I was doing dopey things. I was PRINTing CHR$
(<key>) before I'd worked out whether CTRL was pressed, therefore
PRINTing control codes. DUH!! Well... My excuse, it was gone midnight
last night when I was trying to figure this out!
Anyhow... Got the ESCape part of it nailed and the CTRL part half
nailed. In his last post, Martin hinted at having to test the SHIFT
key explicitly. Whilst I don't have CTRL+SHIFT+<key> combinations, I
do need to differentiate between CTRL+u & CTRL+U for example. This
could be achieved by using CTRL+SHIFT+u or having CapsLock on when CTRL
+u is pressed, whichever of these it doesn't matter, it's just the
character's case that's important.
Thanks again in advance...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/23/2012 6:42:11 AM
|
|
Well... After another little play, I've got no further than I had when
I'd made the last post, probably lost a little ground if the truth be
known. I'm starting to think about tossing GET altogether and scanning
for a keypress with OS_Byte 121 and then reading the keyboard status
byte using OS_Byte 202 and interpreting the CTRL, SHIFT & CAPS status
from that. Will need to take a long look at this.
Any help or advice would be appreciated here.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/23/2012 11:20:02 PM
|
|
In message <1f7f4803-c3ca-4c50-b063-d07b7f61a0f3@b1g2000vbb.googlegrou
ps.com>
Gazza <usenet@garethlock.com> wrote:
> OK... As I suspected... I was doing dopey things. I was PRINTing CHR$
> (<key>) before I'd worked out whether CTRL was pressed, therefore
> PRINTing control codes. DUH!! Well... My excuse, it was gone midnight
> last night when I was trying to figure this out!
> Anyhow... Got the ESCape part of it nailed and the CTRL part half
> nailed. In his last post, Martin hinted at having to test the SHIFT
> key explicitly. Whilst I don't have CTRL+SHIFT+<key> combinations, I
> do need to differentiate between CTRL+u & CTRL+U for example. This
> could be achieved by using CTRL+SHIFT+u or having CapsLock on when CTRL
> +u is pressed, whichever of these it doesn't matter, it's just the
> character's case that's important.
Taking CapsLock into account when interpreting Ctrl keypresses sounds
unusual to me. I think CapsLock should only be relevant when entering
real characters. However, if you really want to take CapsLock into
account, then that would be easy enough. Simply read both the Shift
and the CapsLock status.
--
Martin
---------------------------------------------------------------------
Martin Wuerthner MW Software http://www.mw-software.com/
RISC OS Software for Design, Printing and Publishing
---------------------------------------------------------------------
|
|
0
|
|
|
|
Reply
|
spamtrap3075 (2284)
|
5/24/2012 9:07:07 AM
|
|
Gazza wrote:
> Any help or advice would be appreciated here.
REPEAT
K%=GET:S%=INKEY-1:C%=INKEY-2
IF S%:PRINT" Shift:";
IF C%:PRINT" Ctrl:";
IF K%<32 OR K%=127 PRINT "^";CHR$(K% EOR 64); ELSE PRINT CHR$K
%;
UNTIL FALSE
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/24/2012 8:59:51 PM
|
|
In message <f85b54c4-eccd-4b57-9a8e-6bdd30435c9b@w24g2000vby.googlegroups.com>
on 24 May 2012 jgharston wrote:
> Gazza wrote:
> > Any help or advice would be appreciated here.
>
> REPEAT
> K%=GET:S%=INKEY-1:C%=INKEY-2
> IF S%:PRINT" Shift:";
> IF C%:PRINT" Ctrl:";
> IF K%<32 OR K%=127 PRINT "^";CHR$(K% EOR 64); ELSE PRINT CHR$K
> %;
> UNTIL FALSE
That will work nicely if the processing you do on the key presses is swift.
If a keypress results in some long-winded processing, the user can press
further keys which will be buffered (remembered). While the character that
the key would generate is remembered and buffered properly, the above code is
reading the state of the shift and ctrl keys *now*, not what they were when
the character you have just read with GET was actually generated by the
keyboard.
If the user changes the state of the shift or ctrl key while your program is
caught up in some heavy task and is not responding, then when it catches up
with the buffered input you might end up thinking the user pressed the "a"
key at the same time as shift, when actually the "a" had been buffered and
the shift key was pressed later.
If all that could cause a problem you have various options. One is to run
through all the keys using negative INKEY values and read the keyboard state
as it is at that instant. You can then detect any combination of keys the
ham-fisted user might be pressing all at once. But it's not a good method
for handling ordinary typing, as you would have to deal with keyboard
auto-repeat and all that malarky yourself.
The other option is something like the DeepKeys module, which I think only
applies with the Wimp's key pressed messages. That manages (I think) to
store the state of various modifier keys as they were at the time of the
actual keypress.
--
Matthew Phillips
Durham
|
|
0
|
|
|
|
Reply
|
spam2011m (148)
|
5/24/2012 9:51:40 PM
|
|
Turns out that character case isn't important. Funny... I could have
sworn it was... Anyway... This is what I currently have...
REM
*******************************************************************************************************
REM Debug code...
REM
*******************************************************************************************************
REM Return "TRUE" if value is boolean TRUE, or "FALSE" otherwise...
DEFFNbool2txt(flag%)
IF flag% THEN ="TRUE"
="FALSE"
REM Parse an 8 bit mask and return a text representation of bit
status...
DEFFNbits2txt(mask%)
LOCAL i%,byte$:byte$=""
FOR i%=0 TO 7
IF FNbbc_tstbit(i%,mask%) THEN byte$+="1" ELSE byte$+="0"
NEXT
=byte$
REM
*******************************************************************************************************
REM Exported code...
REM
*******************************************************************************************************
REM Get keyboard input...
REM This behaves just like GET in basic usage. When taken advantage of
it will return the character in
REM char$ and the state of the CTRL key in flag%. Bit 6 of keyboard
status byte is CTRL key state
REM according to OS3 PRM. Bit set, CTRL key down. Bit clear, CTRL key
up. Var. debug% is here for use
REM in test prog. only...
DEFFNbbc_getkey(RETURN char$,RETURN flag%,debug%)
LOCAL code%,kbflags%:kbflags%=0
flag%=FALSE :REM Clear CTRL key flag on
entry...
code%=GET:SYS"OS_Byte",&CA,kbflags%,&FF :REM OS_Byte (R0=&CA (202)),
(R2=&FF (255)). Read kbd status byte.
flag%=FNbbc_tstbit(6,kbflags%) :REM If CTRL key down then
set flag% TRUE...
REM Debug code. Why OS_Byte is returning zero here ?!?!?
IF debug% THEN
PRINT"Bit position : 01234567" :REM Create a
meaningful table for next line...
PRINT"Keyboard status byte : "+FNbits2txt(kbflags%) :REM Debug...
Display kbd status byte...
PRINT
PRINT"CTRL key status : "+FNbool2txt(flag%) :REM Debug... Is
CTRL key down...
ENDIF
REM Deal with special cases, such as NULL, TAB, ENTER, ESCAPE &
SPACE. There may be more...
REM Otherwise, if code% < 65, add 64 to take it out of CTRL character
range before getting it's character
REM representation, then RETURN that on exit.
CASE code% OF
WHEN 0 : char$="NULL"
WHEN 9 : char$="TAB"
WHEN 13 : char$="ENTER"
WHEN 27 : char$="ESCAPE"
WHEN 32 : char$="SPACE"
OTHERWISE : IF code%<65 THEN code%+=64:char$=CHR$(code%)
ENDCASE
REM Finally return ASCII code read. This will be offset to uppercase
if regular CTRL character.
=code%
REM Test a bit at pos% in bitmask mask%. Return TRUE if set.
DEFFNbbc_tstbit(pos%,mask%)
=((mask% AND 1<<pos%)=(1<<pos%))
REM
*******************************************************************************************************
View code with fixed width font. Sorry if it wraps... Calling program
disables ESCape key with OS_Byte 229 (&E5) before this is called.
Can't get anything meaningful back from OS_Byte 202 (&CA). Always
returns zero even if CTRL key held down. My debug routines are
included here for completeness, but finished code will not have debug%
passed to it, or call any of the debug routines bool2txt() or
bits2txt().
Any help would be appreciated...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/25/2012 2:04:42 PM
|
|
Gazza wrote:
> REM Parse an 8 bit mask and return a text representation of bit
> status...
> DEFFNbits2txt(mask%)
> =A0LOCAL i%,byte$:byte$=3D""
> =A0FOR i%=3D0 TO 7
> =A0 IF FNbbc_tstbit(i%,mask%) THEN byte$+=3D"1" ELSE byte$+=3D"0"
> =A0NEXT
> =3Dbyte$
errr..? Return the binary string value of a number?
REM Binary padded with zeros (mdfs.net/blib/Number)
DEFFNb0(A%,N%):LOCAL A$,B$,L%:B$=3D"0":IFA%<0:B$=3D"1":A%=3DA
%AND&7FFFFFFF
REPEATA$=3DSTR$(A%AND1)+A$:A%=3DA%DIV2:L%=3DL%+1:UNTILL%>30:=3DRIGHT$(B$=
+A
$,N%)
Ok, that's a bit dense, because it's a library function, but the
first rule of programming is "find and reuse pre-existing code".
> =A0code%=3DGET:SYS"OS_Byte",&CA,kbflags%,&FF
> =A0flag%=3DFNbbc_tstbit(6,kbflags%)
> =A0REM Why OS_Byte is returning zero here ?!?!?
You haven't returned *anything* from the osbyte call. All you've
done is pass values *top* the osbyte call.
SYS "OS_Byte",&CA,0,&FF TO ,kbflags%
And, as you've looking at the state of the Ctrl key 'now', you
may as well just use INKEY-2.
> =A0CASE code% OF
> =A0 WHEN =A00 =A0 : char$=3D"NULL"
> =A0 WHEN =A09 =A0 : char$=3D"TAB"
> =A0 WHEN 13 =A0 : char$=3D"ENTER"
> =A0 WHEN 27 =A0 : char$=3D"ESCAPE"
> =A0 WHEN 32 =A0 : char$=3D"SPACE"
> =A0 OTHERWISE : IF code%<65 THEN code%+=3D64:char$=3DCHR$(code%)
> =A0ENDCASE
Ctrl-I returns "TAB", Ctrl-M returns "ENTER". Is that what you want?
Don't you want to distinguish between Ctrl-M and Enter, between
Ctrl-I and TAB?
> Any help would be appreciated...
REM Return a string with the keypress, and returns Shift and Ctrl
status
:
DEFFNbbc_getkey(RETURN shift%, RETURN ctrl%)
LOCAL key%, char$
key%=3DGET:shift%=3DINKEY-1:ctrl%=3DINKEY-2 :REM Read keypress, shift and
ctrl keys
char$=3DCHR$key% :REM Prepare to return
keypress as a character
IF key%<32 OR key%=3D127 THEN char$=3D"^"+CHR$(key% EOR 64)
: :REM If a Ctrl+key, prepare to
return "^X"
IF ctrl%=3D0 THEN
: :REM If Ctrl was /not/
pressed...
CASE key% OF
: :REM Translate to key names
WHEN 8 : char$=3D"BACKSPACE"
WHEN 9 : char$=3D"TAB"
WHEN 13 : char$=3D"ENTER"
WHEN 27 : char$=3D"ESCAPE"
WHEN 30 : char$=3D"HOME"
WHEN 32 : char$=3D"SPACE"
WHEN 127 : char$=3D"DELETE"
ENDCASE
ENDIF
=3Dchar$ :REM Return keypress string
Can be optimised quite a bit.
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/25/2012 2:48:09 PM
|
|
jgharston wrote:
> Gazza wrote:
>> REM Parse an 8 bit mask and return a text representation of bit
>> status...
>> DEFFNbits2txt(mask%)
>> LOCAL i%,byte$:byte$=""
>> FOR i%=0 TO 7
>> IF FNbbc_tstbit(i%,mask%) THEN byte$+="1" ELSE byte$+="0"
>> NEXT
>> =byte$
>
> errr..? Return the binary string value of a number?
>
> REM Binary padded with zeros (mdfs.net/blib/Number)
> DEFFNb0(A%,N%):LOCAL A$,B$,L%:B$="0":IFA%<0:B$="1":A%=A
> %AND&7FFFFFFF
> REPEATA$=STR$(A%AND1)+A$:A%=A%DIV2:L%=L%+1:UNTILL%>30:=RIGHT$(B$+A
> $,N%)
>
> Ok, that's a bit dense, because it's a library function, but the
> first rule of programming is "find and reuse pre-existing code".
errr..?
SYS"OS_ConvertBinary1",mask%,END+255,255 TO byte$
or, with Basalt:
byte$=NUM$(mask%,4,1)
|
|
0
|
|
|
|
Reply
|
steve3677 (307)
|
5/25/2012 3:30:09 PM
|
|
On Fri, 25 May 2012 07:48:09 -0700 (PDT), jgharston
<jgh@arcade.demon.co.uk> wrote:
>> � IF FNbbc_tstbit(i%,mask%) THEN byte$+="1" ELSE byte$+="0"
> errr..? Return the binary string value of a number?
Isn't there an OS_ConvertBlahBlah SWI that can do this?
Best wishes,
Rick.
|
|
0
|
|
|
|
Reply
|
heyrickmail-usenet (853)
|
5/26/2012 2:08:51 PM
|
|
On Thu, 24 May 2012 22:51:40 +0100, Matthew Phillips
<spam2011m@yahoo.co.uk> wrote:
> That will work nicely if the processing you do on the key presses
is swift.
> If a keypress results in some long-winded processing, the user can
press
[...]
> reading the state of the shift and ctrl keys *now*, not what they
were when
I guess the important factor is how long something *actually* takes.
Keypress entry is remarkably slow, a computer can build a display
from data in less time than between keydown and keyup (with triangles
on an older machine, damn near raytraced in realtime on a newer one).
Remember Chocks Away! and the like? Not only was the game logic
running, but the world was being redrawn in realtime (that's why it
is kinda basic, there's only so much an 8MHz processor can do).
Alternatives - write a small bit of code to hang on key events to
record the state of keys and modifiers to a circular buffer. Or flush
the keyboard buffer before reading so we know we'll only get fresh
data. The latter is easy but nasty, the former is hard but the most
useful.
Best wishes,
Rick.
|
|
0
|
|
|
|
Reply
|
heyrickmail-usenet (853)
|
5/26/2012 2:16:19 PM
|
|
On Thu, 24 May 2012 11:07:07 +0200, Martin Wuerthner
<spamtrap@mw-software.com> wrote:
> account, then that would be easy enough. Simply read both the Shift
> and the CapsLock status.
Be aware, however, the the configurations Caps, NoCaps, and ShCaps
subtly alter how Caps Lock behaves.
Best wishes,
Rick.
|
|
0
|
|
|
|
Reply
|
heyrickmail-usenet (853)
|
5/26/2012 2:18:55 PM
|
|
Thanks JGH... I've grafted parts of what you had into my latest
routine and have something sort of working. Still however, can't tell
the difference between CTRL+ESC & CTRL+[ for example. This is just the
one I tried, there were others you mentioned previously.
What I have now looks like this. In it's most basic form, I need it to
return an ASCII code as a result, like GET, with one, or both of the
other values RETURNed, so I've messed it about a bit to return the
values in the correct places. Again, you'll need to use a fixed width
font and sorry if code wraps...
REM Get keyboard input...
REM This behaves just like GET in basic usage. When taken advantage of
it will return the character in
REM char$ and the state of the CTRL key in flag%. Bit 6 of keyboard
status byte is CTRL key state
REM according to OS3 PRM. Bit set, CTRL key down. Bit clear, CTRL key
up.
DEFFNbbc_getkey(RETURN char$,RETURN flag%)
LOCAL code%,shift%,ctrl%,caps%,kbflags%
char$="":flag%=0 :REM Clear all
values on entry...
shift%=3:caps%=4:ctrl%=6
code%=GET:SYS"OS_Byte",&CA,0,&FF TO void%,kbflags% :REM OS_Byte
(R0=&CA (202)), (R2=&FF (255)). Read status.
flag%=FNbbc_tstbit(ctrl%,kbflags%)
IF (code%<32 OR code%=127) AND flag% THEN char$=CHR$(code% EOR 64)
REM Deal with special cases, such as NULL, TAB, ENTER, ESCAPE &
SPACE. There may be more...
IF (NOT flag%) THEN
CASE code% OF
WHEN 0 : char$="NULL"
WHEN 8 : char$="BACKSPACE"
WHEN 9 : char$="TAB"
WHEN 13 : char$="ENTER"
WHEN 27 : char$="ESCAPE"
WHEN 30 : char$="HOME"
WHEN 32 : char$="SPACE"
WHEN 127 : char$="DELETE"
OTHERWISE : char$=CHR$(code%)
ENDCASE
ENDIF
=code%
REM Test a bit at pos% in bitmask mask%. Return TRUE if set.
DEFFNbbc_tstbit(pos%,mask%)
=((mask% AND 1<<pos%)=(1<<pos%))
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/27/2012 9:25:17 AM
|
|
Steve Drain wrote:
> > errr..? Return the binary string value of a number?
>
> =A0 =A0SYS"OS_ConvertBinary1",mask%,END+255,255 TO byte$
Doh! Of course. Zero'th law of programming: can the underlying
system do it?
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/27/2012 12:43:01 PM
|
|
Gazza wrote:
> Thanks JGH... I've grafted parts of what you had into my latest
> routine and have something sort of working. Still however, can't tell
> the difference between CTRL+ESC & CTRL+[ for example.
Do you /need/ to be able to tell between Ctrl-Esc and Ctrl-[ ?
The more raw information you need the more detatched you are
becoming from using the keyboard as an input stream and more
towards reading it as a raw device. You it looks like you want
is a non-Wimp DeepKeys, which returns a keypress identifier
and the state of the modifier keys.
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/27/2012 5:00:48 PM
|
|
Gazza wrote:
> Still however, can't tell the difference between
> CTRL+ESC & CTRL+[ for example.
Ok, how about this.
REM FNkey_get - waits for and returns a "deep" keypress
REM ---------------------------------------------------
REM Returns: b0-b8: keypress character
REM b12-b23: modifier key pressed:
REM b12: Left mouse button
REM b13: Middle mouse button
REM b14: Right mouse button
REM b15: Right ALT key
REM b16: Right CTRL key
REM b17: Right SHIFT key
REM b18: Left ALT key
REM b19: Left CTRL key
REM b20: Left SHIFT key
REM b21: Either ALT key
REM b22: Either CTRL key
REM b23: Either SHIFT key
REM b24-b31: physical key pressed
REM
REM 33222222 222211111111 11
REM 10987654 321098765432 109 876543210
REM physical modifierkeys --- character
:
DEFFNkey_get
LOCAL char%, key%, shift%
char%=3DGET :REM Keypress character
shift%=3D0
FOR key%=3D1 TO 12
shift%=3D(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier keys
NEXT
SYS"OS_Byte",122 TO ,key% :REM Read physical keypress
=3Dchar% OR (key%<<24) OR (shift%<<13)
This returns a combination of the character returned by the
keypress, the physical key pressed, and the modifier keys
pressed. This lets you tell apart, for instance, Ctrl-M and
Ctrl-Enter and Ctrl-Return:
Ctrl-M &6590000D
Ctrl-Enter: &3C90000D
Ctrl-Return: &4990000D
The top byte is the physical key pressed, the bottom byte
is the character returned by that key. Actually, the bottom
*nine* bits are the character returned by the key, as that
will allow me to add in the code that distinguishes between
top-bit-set keys (eg '=A3', &0A3) and function/editing keys
(eg Ctrl-f3, &1A3) as in my 'C' console library, and the
RISC OS Wimp.
Demo code:
REPEAT
A%=3DFNkey_get
PRINT "Character: ";~A% AND 511
PRINT "Modifiers: ";~A% AND &00FFF000
PRINT "Keypress: ";~A% >>> 24
UNTIL FALSE
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/27/2012 5:55:23 PM
|
|
On May 27, 6:55=A0pm, jgharston <j...@arcade.demon.co.uk> wrote:
> Ok, how about this.
>
>
> JGH
Got it sort of working... I mean the code works OK, I just ran out of
time towards the end to completely develop the wrapper code and modify
the test program to use it... I've added a return parameter which
returns TRUE if caps-lock is active, this I've implemented by calling
OS_Byte 202 as before, otherwise it's exactly as you posted. Call is
now
FNkey_get(*<caps>)
I don't know whether OS_Byte 202 might be a more convenient way of
returning all the modifier keys in the long run. Anyhow... It seems to
work as far as I've pushed it so far. I'm planning on releasing it,
along with the wrapper code and a couple of other keyboard related
routines I've developed as a library, if you approve, I'll post it on
the Moria progress page (http://www.garethlock.com/acorn/umoria/
index.html) where you can download a copy once it's complete.
Thanks
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/29/2012 5:30:44 PM
|
|
Gazza wrote:
> Call is now
> FNkey_get(*<caps>)
Might be more useful to return the CapLock status as part of the
return value, giving one return value.
DEFFNkey_get
LOCAL char%, key%, shift%
char%=GET :REM Keypress character
shift%=0
FOR key%=1 TO 12
shift%=(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier keys
NEXT
SYS "OS_Byte",202,0,255 TO ,key%
shift%=(shift%<<1) OR ((key% AND 16)>>4)
SYS"OS_Byte",122 TO ,key%
=char% OR (key%<<24) OR (shift%<<12)
REM b11=CapLock status (if I've counted correctly)
There's a programming convention that doesn't like multiple
return values. As with many conventions, it's a convention,
how useful it is depends on the situations it's used in.
> I don't know whether OS_Byte 202 might be a more convenient way
> of returning all the modifier keys in the long run.
Depends if knowing /which/ Shift key, /which/ Ctrl key, etc. is
useful or not. Having a function that returns the state of left
and right modifier keys gives information that can be ignored
which can't be unignored the other way around.
DEFFNkey_get
LOCAL char%, key%, shift%
char%=GET :REM Keypress character
SYS "OS_Byte",202,0,255 TO ,shift%
SYS "OS_Byte",122 TO ,key%
=char% OR (key%<<24) OR ((shift%EOR&14)<<16)
REM b0-b8 =char value
REM b16 =Pending Alt
REM b17 =ScrollLock
REM b18 =NumLock
REM b19 =Shift
REM b20 =CapsLock
REM b21 =reserved
REM b22 =Ctrl
REM b23 =ShiftLock
REM b24-b31=keypress
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/29/2012 9:14:40 PM
|
|
On May 29, 10:14=A0pm, jgharston <j...@arcade.demon.co.uk> wrote:
> Gazza wrote:
> > Call is now
> > FNkey_get(*<caps>)
>
> Might be more useful to return the CapLock status as part of the
> return value, giving one return value.
>
> =A0DEFFNkey_get
> =A0LOCAL char%, key%, shift%
> =A0char%=3DGET =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0:REM Keypress character
> =A0shift%=3D0
> =A0FOR key%=3D1 TO 12
> =A0 =A0shift%=3D(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier ke=
ys
> =A0NEXT
> =A0SYS "OS_Byte",202,0,255 TO ,key%
> =A0shift%=3D(shift%<<1) OR ((key% AND 16)>>4)
> =A0SYS"OS_Byte",122 TO ,key%
> =A0=3Dchar% OR (key%<<24) OR (shift%<<12)
> =A0REM b11=3DCapLock status (if I've counted correctly)
>
> There's a programming convention that doesn't like multiple
> return values. As with many conventions, it's a convention,
> how useful it is depends on the situations it's used in.
>
> > I don't know whether OS_Byte 202 might be a more convenient way
> > of returning all the modifier keys in the long run.
>
> Depends if knowing /which/ Shift key, /which/ Ctrl key, etc. is
> useful or not. Having a function that returns the state of left
> and right modifier keys gives information that can be ignored
> which can't be unignored the other way around.
>
> =A0DEFFNkey_get
> =A0LOCAL char%, key%, shift%
> =A0char%=3DGET =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0:REM Keypress character
> =A0SYS "OS_Byte",202,0,255 TO ,shift%
> =A0SYS "OS_Byte",122 TO ,key%
> =A0=3Dchar% OR (key%<<24) OR ((shift%EOR&14)<<16)
> =A0REM =A0b0-b8 =3Dchar value
> =A0REM =A0 b16 =A0=3DPending Alt
> =A0REM =A0 b17 =A0=3DScrollLock
> =A0REM =A0 b18 =A0=3DNumLock
> =A0REM =A0 b19 =A0=3DShift
> =A0REM =A0 b20 =A0=3DCapsLock
> =A0REM =A0 b21 =A0=3Dreserved
> =A0REM =A0 b22 =A0=3DCtrl
> =A0REM =A0 b23 =A0=3DShiftLock
> =A0REM b24-b31=3Dkeypress
>
> JGH
OK... I couldn't remember whether OS_Byte 202 distinguished between
left and right modifiers, obviously not. That is a better way of
working in the caps-lock status though... Will integrate that change
when I get in front of the machine tomorrow...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/29/2012 11:32:52 PM
|
|
> > =A0DEFFNkey_get
> > =A0LOCAL char%, key%, shift%
> > =A0char%=3DGET
> > =A0SYS "OS_Byte",202,0,255 TO ,shift%
> > =A0SYS "OS_Byte",122 TO ,key%
> > =A0=3Dchar% OR (key%<<24) OR ((shift%EOR&14)<<16)
Hmmm. Every time I add more functionality to this subroutine,
it gets shorter! ;)
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/30/2012 12:34:35 AM
|
|
On May 29, 10:14=A0pm, jgharston <j...@arcade.demon.co.uk> wrote:
> Gazza wrote:
> > Call is now
> > FNkey_get(*<caps>)
>
> Might be more useful to return the CapLock status as part of the
> return value, giving one return value.
>
> =A0DEFFNkey_get
> =A0LOCAL char%, key%, shift%
> =A0char%=3DGET =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0:REM Keypress character
> =A0shift%=3D0
> =A0FOR key%=3D1 TO 12
> =A0 =A0shift%=3D(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier ke=
ys
> =A0NEXT
> =A0SYS "OS_Byte",202,0,255 TO ,key%
> =A0shift%=3D(shift%<<1) OR ((key% AND 16)>>4)
> =A0SYS"OS_Byte",122 TO ,key%
> =A0=3Dchar% OR (key%<<24) OR (shift%<<12)
> =A0REM b11=3DCapLock status (if I've counted correctly)
> JGH
If it's not to much trouble, could you provide me with the updated
demo code that returns b11 as part of the modifiers...
PRINT "Modifiers: ";~A% AND &00FFF000
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/30/2012 11:06:16 AM
|
|
Gazza wrote:
> If it's not to much trouble, could you provide me with the updated
> demo code that returns b11 as part of the modifiers...
PRINT "Modifiers: ";~A% AND &00FFFC00
REM . . . . . . . . . . . . . . . ^
Or, for the OSBYTE 202 version:
REPEAT
A%=FNkey_get
PRINT "Character: ";~A% AND 511
PRINT "Keypress: ";~A% >>> 24
PRINT "Alt: ";~A% AND (1<<16)
PRINT "ScrollLock: ";~A% AND (1<<17)
PRINT "NumLock: ";~A% AND (1<<18)
PRINT "Shift: ";~A% AND (1<<19)
PRINT "CapsLock: ";~A% AND (1<<20)
PRINT "Ctrl: ";~A% AND (1<<22)
PRINT "ShiftLock: ";~A% AND (1<<23)
UNTIL FALSE
DEFFNkey_get
LOCAL char%, key%, shift%
char%=GET
SYS "OS_Byte",202,0,255 TO ,shift%
SYS "OS_Byte",122 TO ,key%
=char% OR (key%<<24) OR ((shift%EOR&14)<<16)
REM b0-b8 =char value
REM b16 =Pending Alt
REM b17 =ScrollLock
REM b18 =NumLock
REM b19 =Shift
REM b20 =CapsLock
REM b21 =reserved
REM b22 =Ctrl
REM b23 =ShiftLock
REM b24-b31=keypress
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
5/30/2012 11:35:18 AM
|
|
On May 30, 12:35=A0pm, jgharston <j...@arcade.demon.co.uk> wrote:
> Gazza wrote:
> > If it's not to much trouble, could you provide me with the updated
> > demo code that returns b11 as part of the modifiers...
>
> PRINT "Modifiers: ";~A% AND &00FFFC00
> REM . . . . . . . . . . . . . . . ^
>
So...
modifier%=3DA% AND &00FFFC00
.... Would return Caps-Lock in b0? If so, then I'll use this, as I've
already virtually completed most of the library with this assumption.
Whilst the ability to detect which SHIFT/CTRL/ALT key is depressed is
not particularly relevant in my Moria port, having this capability as
part of a generic library makes sense in the long run, to me anyway.
Thanks for your help, with your permission, I'll post the library on
my Moria progress page (linked in a previous post) when completed...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/30/2012 12:40:14 PM
|
|
Since my last post this afternoon, I've been playing around a little
more and integrated GET & INKEY (timeout) functionality into the core
deepscan code, and this is what I've come up with. <timeout> is in
secs. INKEY() takes it's values as secs/100 IIRC, if not, then this
needs adjusting accordingly. I wasn't sure how a negative number was
going to be handled with all that shifting, so if the timeout period
expires (INKEY(<timeout>) returns -1) then I make char% zero and
ultimately set b9 before we exit. I haven't tested this yet, but this
should still return the modifier key status even if a regular key
hasn't been pressed within the timeout period.
DEFFNkeyb_deepscan(timeout%)
LOCAL char%, key%, shift%, mask%, flag%
IF timeout%=0 THEN
char%=GET :REM Keypress character
ELSE
char%=INKEY(timeout%*100)
IF char%=-1 THEN char%=0:flag%=TRUE
ENDIF
shift%=0
FOR key%=1 TO 12
shift%=(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier keys
NEXT
SYS "OS_Byte",202,0,255 TO ,key%
shift%=(shift%<<1) OR ((key% AND 16)>>4)
SYS"OS_Byte",122 TO ,key%
mask%=(char% OR (key%<<24) OR (shift%<<12))
IF flag% THEN PROCkeyb_setbit(9,mask%)
=mask%
keyb_scan() : Which in effect calls the above code and returns raw
data, as required by the Demo Code.
keyb_get(*<char>,*<modifier>,*<scan>) : This is the one I'll be using
most in the Moria port. Just calls the above code and performs some
post-processing. The ASCII code is returned by the function.
keyb_inkey(<timeout>,*<char>,*<modifier>,*<scan>) : This is exactly
the same as keyb_get(), except it takes an extra parameter that
specifies a timeout period in seconds. Like the above, the function
returns the ASCII code of the key pressed, or -1 if the timeout has
expired.
keyb_querycase(<modifier>) : Implements CAPS & SHIFT behaviour...
I've also added some extra stuff including a full scan -> ASCII code
LUT which returns the correct ASCII code depending on CAPS & SHIFT key
status and defined behaviour (See Below...)
keyb_querycase(<modifier>) Examines modifier flags. If CAPS & SHIFT
active then we return FALSE (lowercase). If CAPS or SHIFT active then
return TRUE (uppercase). If neither active then return FALSE.
Just got the LUT to fully implement now, this is based on the old
Archimedes type keyboard scan-codes as found in the RISC OS 3 PRMs, as
that is all I have access to. If anyone has access to a keyboard
layout with scan-codes for a modern PC type keyboard, and other common
derivatives and a method to detect the different hardware types on the
fly, then I'll try to implement the differences.
For each keyboard type, I need the physical keyboard layout with both
key-top symbols and the scan-codes, a la the Diagram showing the
Archimedes type keyboard in the OS 3 PRMs.
With your permission, I'll post a link to this library on the progress
page when finalised...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/30/2012 5:26:35 PM
|
|
Been developing a bit more last night. Couldn't post at the time,
because the net went down. I think I've interpreted this correctly, to
use b9 as a timeout flag for INKEY functionality and b10 for Num-Lock
state. I'm including the modified code below. Can JGH please verify
that I've interpreted his code correctly...
Thanks
REM FNkeyb_deepscan(<100th secs>) - waits for and returns a "deep"
keypress
REM
-----------------------------------------------------------------------
REM Returns: b00-b08 : Keypress character
REM b09 : Timeout flag (Set if timeout expired in INKEY
variant.)
REM b10-b11 : Toggle state modifier keys:
REM b10 : Num-Lock state
REM b11 : Caps-Lock state
REM b12-b23 : Momentary state modifier keys:
REM b12 : Left mouse button
REM b13 : Middle mouse button
REM b14 : Right mouse button
REM b15 : Right ALT key
REM b16 : Right CTRL key
REM b17 : Right SHIFT key
REM b18 : Left ALT key
REM b19 : Left CTRL key
REM b20 : Left SHIFT key
REM b21 : Either ALT key
REM b22 : Either CTRL key
REM b23 : Either SHIFT key
REM b24-b31 : Physical key pressed
REM 00000000 11100000000000 000000000
REM 76543210 32109876543210 876543210
REM physical modifier__keys character
REM 33222222 22221111111111 0 000000000
REM 10987654 32109876543210 9 876543210
REM Need to check this with -JGH-. Have I interpreted what he's doing
correctly when shifting Num-Lock status
REM into b10?
DEFFNkeyb_deepscan(timeout%)
LOCAL char%,key%,shift%,void%,fl%,mask%
IF timeout%=0 THEN
char%=GET :REM Keypress character. (No
timeout)
ELSE
char%=INKEY(timeout%) :REM Keypress character.
(With timeout)
IF char%<0 THEN char%=0:fl%=TRUE :REM Make char% 0 if negative
and set flag for later.
ENDIF
shift%=0
FOR key%=1 TO 12
shift%=(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier keys
NEXT
SYS"OS_Byte",&CA,0,&FF TO void%,key% :REM OS_Byte (R0=&CA (202),
R1=0, R2=&FF (255)). Read keybd status.
shift%=(shift%<<1)OR((key%AND16)>>4) :REM Extract Caps-Lock state
from key% shift into b11.
shift%=(shift%<<1)OR((key%AND16)>>2) :REM Extract Num-Lock state
from key% shift into b10. Is this correct?
SYS"OS_Byte",&7A TO void%,key% :REM OS_Byte (R0=&7A (122)).
Read physical keypress.
mask%=(char% OR (key%<<24) OR (shift%<<11)) :REM Was mask%=(char% OR
(key%<<24) OR (shift%<<12)). See top.
IF fl% THEN PROCkeyb_setbit(9,mask%)
=mask%
Needs to be viewed in a fixed-width font, sorry if the code wraps...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
5/31/2012 1:56:16 PM
|
|
Messed around with it a little more and got it to work and return Caps
in b11 and Num in b10. I'm using b9 for timeout expired when using
INKEY rather than GET is an input method. I've had to hack in Caps and
Num-Lock status for the time being using an extra variable and
manually setting bits after the 32bit mask has been assembled. Both
Caps & Num-Lock state are actually the INVERSE of the bit values
returned after the call to OS_Byte 202 (Bit Clear = ON) for some
reason, so I'm checking the inverse and setting bits accordingly.
The other minor change was that JGH got the left and right mouse
buttons swapped. Starting at b12, it's Adjust, Menu, Select, not
Select, Menu, Adjust. I've included a verbose and hacky version of the
demo code that expands all 32 bits of the returned datastream into a
text string along with significance.
I've not bothered to use OS calls to convert the mask to a string,
just a variation of the debug code I posted the other day. The code
follows. It needs to be view in a fixed width font and as always,
sorry if the code wraps...
REM Demo code:
REPEAT
PRINT
A%=FNkeyb_scan
PRINT "Character: ";A% AND 511
PRINT "Modifiers: &";~A% AND &00FFFC00 :REM This mask is doesn't take
into account Num-Lock state in b10
PRINT " T C RRRLLL "
PRINT " ONaAMSACSACSACS"
PRINT " uupdneltfltfltf"
PRINT "<-char-->tmsjultlttlttlt<-scan->"
PRINT "--------------------------------"
PRINT FNkeyb_bits2txt(A%,31)
PRINT "Keypress: ";A% >>> 24
PRINT
UNTIL FALSE
REM FNkeyb_deepscan(<100th secs>) - waits for and returns a "deep"
keypress
REM
-----------------------------------------------------------------------
REM Returns: b00-b08 : Keypress character
REM b09 : Timeout flag (Set if timeout expired in INKEY
variant.)
REM b10-b11 : Toggle state modifier keys:
REM b10 : Num-Lock state
REM b11 : Caps-Lock state
REM b12-b23 : Momentary state modifier keys:
REM b12 : Right mouse button
REM b13 : Middle mouse button
REM b14 : Left mouse button
REM b15 : Right ALT key
REM b16 : Right CTRL key
REM b17 : Right SHIFT key
REM b18 : Left ALT key
REM b19 : Left CTRL key
REM b20 : Left SHIFT key
REM b21 : Either ALT key
REM b22 : Either CTRL key
REM b23 : Either SHIFT key
REM b24-b31 : Physical key pressed
REM 00000000 11100000000000 000000000
REM 76543210 32109876543210 876543210
REM physical modifier__keys character
REM 33222222 22221111111111 0 000000000
REM 10987654 32109876543210 9 876543210
DEFFNkeyb_deepscan(timeout%)
LOCAL char%,key%,shift%,void%,fl%,mask%
IF timeout%=0 THEN
char%=GET :REM Keypress character. (No
timeout)
ELSE
char%=INKEY(timeout%) :REM Keypress character.
(With timeout)
IF char%<0 THEN
char%=0:PROCkeyb_setbit(0,fl%) :REM Make char% 0 if negative
and set flag for later.
ENDIF
ENDIF
shift%=0
FOR key%=1 TO 12
shift%=(shift%<<1)OR(INKEY-key% AND 1) :REM Read all modifier keys
NEXT
SYS"OS_Byte",&CA,0,&FF TO void%,key% :REM OS_Byte (R0=&CA (202),
R1=0, R2=&FF (255)). Read keybd status.
shift%=(shift%<<1)
IF NOT FNkeyb_tstbit(2,key%) THEN PROCkeyb_setbit(1,fl%) :REM b2
Clear = Num-Lock ON.
IF NOT FNkeyb_tstbit(4,key%) THEN PROCkeyb_setbit(2,fl%) :REM b4
Clear = Caps-Lock ON.
SYS"OS_Byte",&7A TO void%,key% :REM OS_Byte (R0=&7A (122)).
Read physical keypress.
mask%=(char% OR (key%<<24) OR (shift%<<11))
IF FNkeyb_tstbit(0,fl%) THEN PROCkeyb_setbit(9,mask%) :REM If b0
set, INKEY timeout...
IF FNkeyb_tstbit(1,fl%) THEN PROCkeyb_setbit(10,mask%) :REM If b1
set, Num-Lock ON...
IF FNkeyb_tstbit(2,fl%) THEN PROCkeyb_setbit(11,mask%) :REM If b2
set, Caps-Lock ON...
=mask%
REM Calls keyb_deepscan() with no timeout and returns raw data...
DEFFNkeyb_scan
=FNkeyb_deepscan(0)
REM Returns TRUE if given bit is set in mask...
DEFFNkeyb_tstbit(p%,m%)
=((m% AND 1<<p%)=(1<<p%))
REM Sets a given bit in a bitmask...
DEFPROCkeyb_setbit(p%,RETURN m%)
m%=m% OR (1<<p%)
ENDPROC
REM Build a text representation of a binary number... (Debug only.)
DEFFNkeyb_bits2txt(mask%,len%)
LOCAL i%,bits$
FOR i%=0 TO len%
IF FNkeyb_tstbit(i%,mask%) THEN bits$+="1" ELSE bits$+="0"
NEXT
=bits$
Yes... I know it's not the most elegant solution, but it does the job.
If someone would like the challenge of tidying it up a bit then go
ahead, and post it on here afterwards... lol
Many thanks for all your help
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/1/2012 12:02:41 PM
|
|
Think I've finally got it sorted. Another hack to Demo Code got the
modifiers returning correctly...
modifier%=A%AND&00FFFC00
modifier%=modifier%>>10
FIXED...
Am posting another copy of the Demo Code with both keyb_deepscan() RAW
data expanded along with Caps-Lock & Num-Lock test stings and the
modifier flags expanded in the same way as the RAW data from
keyb_deepscan()
As before, you'll need a fixed-width font to make sense of it,
especially the expanded stuff...
10 : REM Demo code:
20 : REPEAT
30 : PRINT
40 : mask%=FNkeyb_getraw:modmask%=&00FFFC00
50 : char%=mask% AND 511
60 : modifier%=mask% AND modmask%:modifier%=modifier%>>10
70 : scan%=mask% >>> 24
80 :
90 : PRINT"Character: ";char%
100 : PRINT"Modifiers: &";~modifier%
110 : PRINT"Keypress: ";scan%
120 : PRINT
130 : PRINT" T C RRRLLL "
140 : PRINT" ONaAMSACSACSACS"
150 : PRINT" uupdneltfltfltf"
160 : PRINT"<-char-->tmsjultlttlttlt<-scan->"
170 : PRINT"--------------------------------"
180 : PRINTFNkeyb_bits2txt(mask%,31)
190 : PRINTFNkeyb_bits2txt(modmask%,31)
200 : PRINT
210 : PRINT"Reading from Modifiers... (mask% AND &";~modmask
%;" )"
220 : PRINT"Num-Lock : "+FNkeyb_iifs(FNkeyb_tstbit(0,modifier
%),"ON","OFF")
230 : PRINT"Caps-Lock : "+FNkeyb_iifs(FNkeyb_tstbit(1,modifier
%),"ON","OFF")
240 : PRINT
250 : PRINT" C RRRLLL"
260 : PRINT"NaAMSACSACSACS"
270 : PRINT"updneltfltfltf"
280 : PRINT"msjultlttlttlt"
290 : PRINT"--------------"
300 : PRINTFNkeyb_bits2txt(modifier%,13)
310 : PRINT
320 : UNTIL FALSE
Refer to previous post for most of the DEFs, the only new one is...
DEFFNkeyb_iifs(cond%,true$,false$)
IF cond% THEN =true$
=false$
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/1/2012 2:01:54 PM
|
|
Already changed...
60 : modifier%=mask% AND modmask%:modifier%=modifier%>>10
to...
60 : modifier%=(mask% AND modmask%)>>10
.... Was doing it this way until I was sure I was doing the right
thing... Easier to REM out.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/1/2012 2:54:12 PM
|
|
Gazza wrote:
> ... Was doing it this way until I was sure I was doing the right
> thing... Easier to REM out.
Sorry, I've been busy with a funeral, I'll have a play with the code
tomorrow.
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
6/3/2012 1:18:31 AM
|
|
On Jun 3, 2:18=A0am, jgharston <j...@arcade.demon.co.uk> wrote:
> Gazza wrote:
> > ... Was doing it this way until I was sure I was doing the right
> > thing... Easier to REM out.
>
> Sorry, I've been busy with a funeral, I'll have a play with the code
> tomorrow.
>
> JGH
My condolences to you and the family.
I can provide the whole lot as a ZIPped file with the rest of the
library to the e-mail address you use to log in to csap if you think
it would help
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/3/2012 8:02:11 AM
|
|
Some points on your code.
> IF FNkeyb_tstbit(0,fl%) THEN ...
just do: IF (fl% AND (1<<0)) THEN ...
> PROCkeyb_setbit(9,mask%)
just do: mask%=3Dmask% OR (1<<9)
> SYS "OS_Byte",&7A TO void%,key%
just do: SYS "OS_Byte",&7A TO ,key%
Any returned values you want to ignore can be just ignored
by skipping the variable to deposit it into after the TO,
just as any parameters you want to ignore when calling can
also be skipped by skipping the variable before the TO, and
zero will be used instead.
I've tidied up the code and draft documentation into a library
at mdfs.net/blib#deepkey
Here is an uncrunched version with demo code. The demo code also
defines the function and editing keys to return their keycodes
so they can be distinguished from top-bit-set characters such as
'=A3' in a similar manner to the Wimp. (Using *FX221-228,2 sets
function and editing keys to return CHR$00,CHR$keynumber.)
REM > BLib.Develop.DeepKeys
:
MODE 40:PROCdemo:END
:
:
REM FNdeep_inkey(time%) and FNdeep_get
REM ----------------------------------
REM Returns -1 if no key pressed within time% in centiseconds
REM or b0-b8 : character code (b8=3D1 if function/editing key)
REM b9 : reserved
REM b10 : RightAlt
REM b11 : RightCtrl
REM b12 : RightShift
REM b13 : LeftAlt
REM b14 : LeftCtrl
REM b15 : LeftShift
REM b16 : Alt pending
REM b17 : Scroll Lock
REM b18 : NumLock
REM b19 : Shift
REM b20 : Caps Lock
REM b21 : reserved
REM b22 : Ctrl
REM b23 : Shift Lock
REM b24-b31: physical key pressed
:
DEFFNdeep_inkey(time%)
LOCAL char%,mod%,key%,shift%
char%=3DINKEY(time%):IFchar%=3D-1:=3D-1
IF char%=3D0:char%=3DGET:IF char%:char%=3D(char% OR &100) EOR ((char
%AND15)>9 AND &40)
shift%=3D0
FOR key%=3D4 TO 9
shift%=3D(shift%<<1)OR(INKEY-key% AND 1)
NEXT
SYS "OS_Byte",&CA,,&FF TO ,mod%
SYS "OS_Byte",&7A TO ,key%
=3Dchar% OR (shift%<<10) OR ((mod%EOR&14)<<16) OR (key%<<24)
:
DEFFNdeep_get
LOCAL A%
REPEAT
A%=3DFNdeep_inkey(10)
UNTIL A%<>-1
=3DA%
:
:
:
DEFPROCdemo
FOR A%=3D221 TO 228:SYS "OS_Byte",A%,2:NEXT:*FX4,2
PRINT "physicalmodifier.......character char key ";
PRINT "ShLk Ctrl Caps Shift NumLk Scroll Alt ";
PRINT "LeftSg LeftCt RightSh RightCt"
REPEAT
A%=3DFNdeep_inkey(100)
:
PRINT FNb0(A%,32);
PRINT " ";FNh0(A% AND &1FF,3);" ";FNc(A% AND &FF);
PRINT " ";FNh0((A%>>24),2);
:
PRINT " ";FNonf(A% AND (1<<23),"ShLk");
PRINT " ";FNonf(A% AND (1<<22),"Ctrl");
PRINT " ";FNonf(A% AND (1<<20),"Caps");
PRINT " ";FNonf(A% AND (1<<19),"Shift");
PRINT " ";FNonf(A% AND (1<<18),"NumLk");
PRINT " ";FNonf(A% AND (1<<17),"Scroll");
PRINT " ";FNonf(A% AND (1<<16),"Alt");
:
PRINT " ";FNonf(A% AND (1<<15),"LeftSh");
PRINT " ";FNonf(A% AND (1<<14),"LeftCt");
PRINT " ";FNonf(A% AND (1<<12),"RightSh");
PRINT " ";FNonf(A% AND (1<<11),"RightCt");
:
PRINT
UNTIL0
:
:
DEFFNb0(A%,N%):LOCAL A$,B$,L%:B$=3D"0":IFA%<0:B$=3D"1":A%=3DA%AND&7FFFFFFF
REPEATA$=3DSTR$(A%AND1)+A$:A%=3DA%DIV2:L%=3DL%+1:UNTILL%>30:=3DRIGHT$(B$+A$=
,N
%)
:
DEFFNh0(A%,N%)=3DRIGHT$("00000000"+STR$~A%,N%)
:
DEFFNc(A%):IF A%<32 OR A%=3D127:=3D"^"+CHR$(A%EOR64) ELSE =3DCHR$A%+" "
:
DEFFNonf(A%,A$):IFA%:=3DA$ ELSE =3DSTRING$(LENA$,"-")
:
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
6/7/2012 12:29:37 AM
|
|
>> SYS "OS_Byte",&7A TO void%,key%
>just do: SYS "OS_Byte",&7A TO ,key%
>Any returned values you want to ignore can be just ignored
>by skipping the variable to deposit it into after the TO,
>just as any parameters you want to ignore when calling can
>also be skipped by skipping the variable before the TO, and
>zero will be used instead.
That's OK when you've only got a single comma like that I suppose, but
counting commas with tired eyes causes mistakes to be made in my
experience, so I always use something like void%, especially when I'm
still coding stuff... Once development is complete, I may well remove
stuff like that on production code so to speak, but I just find
actually specifying something makes it easier to understand what's
going on. Maybe that's just me!
Again... The setbit() / clrbit() & tstbit() routines are just there to
aid development. I originally encapsulated them like that, as my first
use for them was part of a tutorial I was planning, but never actually
materialised. The idea being that they, themselves, were a library
that could be loaded by the pupil's code and be referenced by names
that actually meant something to them. I had planned to explain what
their purpose was as part of the particular lesson, but, like I said,
nothing ever came of it. Once I have a set of building blocks like
that I tend to be a bit lazy, and just re-use code. So it was
something that just got re-used.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/7/2012 11:37:11 PM
|
|
On 25 May 2012 as I do recall,
Gazza wrote:
> Turns out that character case isn't important. Funny... I could have
> sworn it was...
[snip]
*I* could have sworn that character case was important in Moria... how
else do you tell the difference between a bat and a Balrog?
In a turn-based dungeon crawl, on the other hand, I shouldn't have
thought that keyboard scanning speed was terribly significant.
--
Harriet Bazley == Loyaulte me lie ==
One man tells a falsehood, a hundred repeat it as true.
|
|
0
|
|
|
|
Reply
|
bazley (1301)
|
6/8/2012 7:55:12 AM
|
|
On Jun 8, 8:55=A0am, Harriet Bazley <baz...@feathermail.co.uk> wrote:
> On 25 May 2012 as I do recall,
> =A0 =A0 =A0 =A0 =A0 Gazza =A0wrote:
>
> > Turns out that character case isn't important. Funny... I could have
> > sworn it was...
>
> [snip]
>
> *I* could have sworn that character case was important in Moria... how
> else do you tell the difference between a bat and a Balrog?
>
> In a turn-based dungeon crawl, on the other hand, I shouldn't have
> thought that keyboard scanning speed was terribly significant.
>
> --
> Harriet Bazley =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D=3D =A0Loyaulte=
me lie =3D=3D
>
> One man tells a falsehood, a hundred repeat it as true.
What I meant when I said character case didn't matter was that there
were no lowercase CTRL combos used, so from a keyboard scanning
perspective scanning for lowercase CTRL combos wasn't req'd
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/8/2012 8:16:16 AM
|
|
On 07/06/2012 01:29, jgharston wrote:
> REM FNdeep_inkey(time%) and FNdeep_get
> REM ----------------------------------
> REM Returns -1 if no key pressed within time% in centiseconds
> REM or b0-b8 : character code (b8=1 if function/editing key)
> REM b9 : reserved
> REM b10 : RightAlt
> REM b11 : RightCtrl
> REM b12 : RightShift
> REM b13 : LeftAlt
> REM b14 : LeftCtrl
> REM b15 : LeftShift
> REM b16 : Alt pending
> REM b17 : Scroll Lock
> REM b18 : NumLock
> REM b19 : Shift
> REM b20 : Caps Lock
> REM b21 : reserved
> REM b22 : Ctrl
> REM b23 : Shift Lock
> REM b24-b31: physical key pressed
I was stimulated by the earlier discussion to look into this as a
possible extension to Basalt, and I wrote an INKEYS keyword that as a
statement does:
INKEYS delay TO charcode%,status%,modifiers%,internalkey%
or as a function does:
deepkey%=INKEYS(delay)
The format of deepkey% is almost exactly the same as your specification
above. ;-)
Because it takes little code to do in assembler, these also activate the
function/cursor keys and restore the previous state on completion, as
well as disabling Esc and Break so that these can return values. I
looked at doing this in BASIC alone, but it would be horribly extended.
|
|
0
|
|
|
|
Reply
|
steve3677 (307)
|
6/8/2012 11:00:45 AM
|
|
Finally got something working. I'm now using the <code>=<code>EOR64
method as a catch all, but still using scan-codes where ASCII codes
cause conflicts. E.g ^TAB and ^I or ^ENTER and ^M. I'm sure there are
others, I'll add these as I test what I've coded today.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/8/2012 4:00:24 PM
|
|
If JGH is reading this, can I have permission to publish his code
please? Then I can post the finished library.
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/11/2012 11:14:07 PM
|
|
Gazza <usenet@garethlock.com> wrote:
> SYS"OS_Byte",&CA,0,&FF TO void%,key%
> shift%=(shift%<<1)OR((key%AND16)>>4)
> shift%=(shift%<<1)OR((key%AND16)>>2)
> SYS"OS_Byte",&7A TO void%,key%
> mask%=(char% OR (key%<<24) OR (shift%<<11))
Just a brief comment here; I don't know how this routine copes if someone is
typing as it runs, but I would have thought it would be better practice to
keep the time-delay between the two SYS"OS_Byte" calls as brief as possible.
Also I'd have used SYS calls with SWI numbers rather than names, so as to
avoid wasting time looking those up on every call, ie have something like
SYS os_byte% ... (having set the swi numbers earlier)
and I'd have coded:
SYSos_byte%,&CA,0,&FF TO void%,ky1%
SYSos_byte%,&7A TO void%,ky2%
shift%=(shift%<<1)OR((ky1%AND16)>>4)
shift%=(shift%<<1)OR((ky1%AND16)>>2)
mask%=(char% OR (ky2%<<24) OR (shift%<<11))
--
Jeremy C B Nicoll - my opinions are my own.
Email sent to my from-address will be deleted. Instead, please reply
to newsreplyaaa@wingsandbeaks.org.uk replacing "aaa" by "284".
|
|
0
|
|
|
|
Reply
|
jn.nntp.scrap007 (392)
|
6/16/2012 7:18:15 PM
|
|
On 16 June, 20:18, Jeremy Nicoll - news posts
<jn.nntp.scrap...@wingsandbeaks.org.uk> wrote:
> Just a brief comment here; I don't know how this routine copes if someone=
is
> typing as it runs, but I would have thought it would be better practice t=
o
> keep the time-delay between the two SYS"OS_Byte" calls as brief as possib=
le.
>
> Also I'd have used SYS calls with SWI numbers rather than names, so as to
> avoid wasting time looking those up on every call, ie have something like
>
> =A0SYS os_byte% ... =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(having set the swi nu=
mbers earlier)
>
> and I'd have coded:
>
> =A0SYSos_byte%,&CA,0,&FF TO void%,ky1%
> =A0SYSos_byte%,&7A TO void%,ky2%
> =A0shift%=3D(shift%<<1)OR((ky1%AND16)>>4)
> =A0shift%=3D(shift%<<1)OR((ky1%AND16)>>2)
> =A0mask%=3D(char% OR (ky2%<<24) OR (shift%<<11))
>
> --
> Jeremy C B Nicoll - my opinions are my own.
>
> Email sent to my from-address will be deleted. Instead, please reply
> to newsreply...@wingsandbeaks.org.uk replacing "aaa" by "284".
I understand where you're coming from... The reason that it was coded
this way, was that it was going in a library. By doing it this way,
you reduce the number of variables required, and therefore defined.
Lowering the memory footprint. As far as coping with typing is
concerned, we're dealing with INKEY< or GET. Both return one value at
a time. In theory, crude typing can be achieved by looping with the
GET variation of the call and processing the resulting bitmask for
each iteration of the loop. This routine however, is only part of the
story.
I hope to be able to make the library available from the UMoria
progress page (http://www.garethlock.com/acorn/umoria ) in time...
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/17/2012 11:08:24 PM
|
|
Gazza wrote:
> If JGH is reading this, can I have permission to publish his code
> please? Then I can post the finished library.
Yes, go ahead. Library version available at mdfs.net/blib/DeepKey and
mdfs.net/blib/DeepKey.txt
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
6/18/2012 12:12:30 AM
|
|
Gazza <usenet@garethlock.com> wrote:
> I understand where you're coming from... The reason that it was coded this
> way, was that it was going in a library. By doing it this way, you reduce
> the number of variables required, and therefore defined. Lowering the
> memory footprint.
You must mean something different from what I'd expect by "memory footprint"
then. The local vars in a FN or PROC are allocated from the stack for the
duration of the FN/PROC's execution and freed when it returns, so it makes
no difference.
Of course allocating an extra variable will take fractionally longer, but
there are lots of other things in your code which will be slow, eg the time
taken by the interpreter to locate long-named variables, rather than ones
with shorter names. Using the built in vars like A% B% C% etc might make
more sense (though not aid understanding).
(Maybe you're going to crunch the code which would help speed it up.)
> As far as coping with typing is concerned, we're dealing with INKEY< or
> GET. Both return one value at a time. In theory, crude typing can be
> achieved by looping with the GET variation of the call and processing the
> resulting bitmask for each iteration of the loop. This routine however, is
> only part of the story.
I think you misunderstand my point. I'm not asking how your code would work
if it was intended to read multiple characters, but pointing out that a user
making unwanted keypresses (pressing or releasing Caps-Lock or Num-Lock)
while the code is between OS-Byte calls will (I think) cause a problem. It
just seemed to me that shortening the time interval between the OS_Byte
calls would be sensible.
--
Jeremy C B Nicoll - my opinions are my own.
Email sent to my from-address will be deleted. Instead, please reply
to newsreplyaaa@wingsandbeaks.org.uk replacing "aaa" by "284".
|
|
0
|
|
|
|
Reply
|
jn.nntp.scrap007 (392)
|
6/18/2012 3:45:47 AM
|
|
On 18/06/2012 00:08, Gazza wrote:
> I understand where you're coming from... The reason that it was coded
> this way, was that it was going in a library. By doing it this way,
> you reduce the number of variables required, and therefore defined.
> Lowering the memory footprint.
Always get the functionality right before optimising, whether it's for
speed or memory use.
---druck
|
|
0
|
|
|
|
Reply
|
news5802 (523)
|
6/18/2012 5:41:18 PM
|
|
jgharston wrote:
> Yes, go ahead. Library version available at mdfs.net/blib/DeepKey and
> mdfs.net/blib/DeepKey.txt
Grr. That should be mdfs.net/blib/DeepKey and mdfs.net/blib/Docs/
DeepKey.txt
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
6/18/2012 8:24:14 PM
|
|
druck wrote:
> Always get the functionality right before optimising, whether it's for
> speed or memory use.
Rules of optimisation:
i) Don't.
ii) Don't yet.
JGH
|
|
0
|
|
|
|
Reply
|
jgh2 (974)
|
6/18/2012 8:26:36 PM
|
|
On Jun 18, 4:45=A0am, Jeremy Nicoll - news posts
<jn.nntp.scrap...@wingsandbeaks.org.uk> wrote:
>
> I think you misunderstand my point. =A0I'm not asking how your code would=
work
> if it was intended to read multiple characters, but pointing out that a u=
ser
> making unwanted keypresses (pressing or releasing Caps-Lock or Num-Lock)
> while the code is between OS-Byte calls will (I think) cause a problem. =
=A0It
> just seemed to me that shortening the time interval between the OS_Byte
> calls would be sensible.
>
> --
> Jeremy C B Nicoll - my opinions are my own.
>
> Email sent to my from-address will be deleted. Instead, please reply
> to newsreply...@wingsandbeaks.org.uk replacing "aaa" by "284".
Made a few minor changes based on your suggestions, shortened variable
names, added an extra variable and moved the two OS_Byte calls next to
each other. I'd actually manually shortened variable names in other
parts of the library already. I think I left that routine as it was,
as I was posting it, or parts of it here. So... In order for it to be
easily followed, I maintained the longer, more descriptive names.
Doing it this way, I've also managed to reduce the manual bit zapping
towards the end of the routine a bit too.
The completed library can be found here...
http://www.garethlock.com/acorn/umoria/libkeyb.zip
|
|
0
|
|
|
|
Reply
|
usenet9920 (358)
|
6/18/2012 9:49:55 PM
|
|
|
48 Replies
44 Views
(page loaded in 0.671 seconds)
|