okay.. group effort. fixing keyboardinkey...post your fixes

Advanced game related topics
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

okay.. group effort. fixing keyboardinkey...post your fixes

Post by dracflamloc »

Okay everyone knows keyboard inkey is pretty crappy for use in a game when you are trying to implement chatting. It only detects on keyboard RELEASED and isnt 100% accurate with the Shift key down.

Here we should all post our fixes for this problem.

My fix has a problem, that keys repeat way too fast, and the only way to stop that is to change the #KeyTypeDelayMs to something so large you have to type the speed of a 2 year old to not miss key presses.

Here it is, see if you can fix it or if you already have a working one just post it:

Code: Select all

Procedure.s GetKeyboardASCII()
  kchar.s=""
  
  If ElapsedMilliseconds()-lastKeyTypeMs >= #KeyTypeDelayMs
    If KeyboardPushed(#PB_Key_0) Or KeyboardPushed(#PB_Key_Pad0)
      kchar="0"
    ElseIf KeyboardPushed(#PB_Key_1) Or KeyboardPushed(#PB_Key_Pad1)
      kchar="1"
    ElseIf KeyboardPushed(#PB_Key_2) Or KeyboardPushed(#PB_Key_Pad2)
      kchar="2"
    ElseIf KeyboardPushed(#PB_Key_3) Or KeyboardPushed(#PB_Key_Pad3)
      kchar="3"
    ElseIf KeyboardPushed(#PB_Key_4) Or KeyboardPushed(#PB_Key_Pad4)
      kchar="4"
    ElseIf KeyboardPushed(#PB_Key_5) Or KeyboardPushed(#PB_Key_Pad5)
      kchar="5"
    ElseIf KeyboardPushed(#PB_Key_6) Or KeyboardPushed(#PB_Key_Pad6)
      kchar="6"
    ElseIf KeyboardPushed(#PB_Key_7) Or KeyboardPushed(#PB_Key_Pad7)
      kchar="7"
    ElseIf KeyboardPushed(#PB_Key_8) Or KeyboardPushed(#PB_Key_Pad8)
      kchar="8"
    ElseIf KeyboardPushed(#PB_Key_9) Or KeyboardPushed(#PB_Key_Pad9)
      kchar="9"
    ElseIf KeyboardPushed(#PB_Key_Minus)
      kchar="-"
    ElseIf KeyboardPushed(#PB_Key_Equals)
      kchar="="
    ElseIf KeyboardPushed(#PB_Key_Slash)
      kchar="/"
    ElseIf KeyboardPushed(#PB_Key_BackSlash)
      kchar="\"
    ElseIf KeyboardPushed(#PB_Key_LeftBracket)
      kchar="["
    ElseIf KeyboardPushed(#PB_Key_RightBracket)
      kchar="]"
    ElseIf KeyboardPushed(#PB_Key_SemiColon)
      kchar=";"
    ElseIf KeyboardPushed(#PB_Key_Apostrophe)
      kchar="'"
    ElseIf KeyboardPushed(#PB_Key_Period) Or KeyboardPushed(#PB_Key_PadComma)
      kchar="."
    ElseIf KeyboardPushed(#PB_Key_Comma)
      kchar=","
    ElseIf KeyboardPushed(#PB_Key_Q)
      kchar="q"
    ElseIf KeyboardPushed(#PB_Key_W)
      kchar="w"
    ElseIf KeyboardPushed(#PB_Key_E)
      kchar="e"
    ElseIf KeyboardPushed(#PB_Key_R)
      kchar="r"
    ElseIf KeyboardPushed(#PB_Key_T)
      kchar="t"
    ElseIf KeyboardPushed(#PB_Key_Y)
      kchar="y"
    ElseIf KeyboardPushed(#PB_Key_U)
      kchar="u"
    ElseIf KeyboardPushed(#PB_Key_I)
      kchar="i"
    ElseIf KeyboardPushed(#PB_Key_O)
      kchar="o"
    ElseIf KeyboardPushed(#PB_Key_P)
      kchar="p"
    ElseIf KeyboardPushed(#PB_Key_A)
      kchar="a"
    ElseIf KeyboardPushed(#PB_Key_S)
      kchar="s"
    ElseIf KeyboardPushed(#PB_Key_D)
      kchar="d"
    ElseIf KeyboardPushed(#PB_Key_F)
      kchar="f"
    ElseIf KeyboardPushed(#PB_Key_G)
      kchar="g"
    ElseIf KeyboardPushed(#PB_Key_H)
      kchar="h"
    ElseIf KeyboardPushed(#PB_Key_J)
      kchar="j"
    ElseIf KeyboardPushed(#PB_Key_K)
      kchar="k"
    ElseIf KeyboardPushed(#PB_Key_L)
      kchar="l"
    ElseIf KeyboardPushed(#PB_Key_Z)
      kchar="z"
    ElseIf KeyboardPushed(#PB_Key_X)
      kchar="x"
    ElseIf KeyboardPushed(#PB_Key_C)
      kchar="c"
    ElseIf KeyboardPushed(#PB_Key_V)
      kchar="v"
    ElseIf KeyboardPushed(#PB_Key_B)
      kchar="b"
    ElseIf KeyboardPushed(#PB_Key_N)
      kchar="n"
    ElseIf KeyboardPushed(#PB_Key_M)
      kchar="m" 
    ElseIf KeyboardPushed(#PB_Key_Space)
      kchar=" "      
    EndIf 
  EndIf   
    
  If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift)
    Select kchar
      Case "/"
        kchar="?"
      Case "."
        kchar=">"
      Case ","
        kchar="<"
      Case ";"
        kchar=":"
      Case "'"
        kchar=Chr(34)
      Case "["
        kchar="{"
      Case "]"
        kchar="}"
      Case "\"
        kchar="|"
      Case "`"
        kchar="~"
      Case "1"
        kchar="!"
      Case "2"
        kchar="@"
      Case "3"
        kchar="#"
      Case "4"
        kchar="$"
      Case "5"
        kchar="%"
      Case "6"
        kchar="^"
      Case "7"
        kchar="&"
      Case "8"
        kchar="*"
      Case "9"
        kchar="("
      Case "0"
        kchar=")"
      Case "-"
        kchar="_"
      Case "="
        kchar="+"
    EndSelect
    
    If Asc(kchar) >= $61 And Asc(kchar) <= $7A
      kchar=UCase(kchar)
    EndIf   
  EndIf 
  
  If kchar<>""
    lastKeyTypeMs=ElapsedMilliseconds()
  EndIf  
  
  ProcedureReturn kchar
EndProcedure
The challenge:
1. Must be 3.94 compatible (Optional 4.0)
2. Must work similar to how normal textgadgets work when detecting each key
3. Must be cross-platform
4. Must detect keypresses on pushed, not released.

[edit] had to disable html in this post
Fred
Administrator
Administrator
Posts: 16681
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

What's the problem exactly with the released and chatting ?
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Its annoying and a-typical for the way normal users work on thier pc when typing and doesnt allow for repeating characters when holding a key down. Also the fact that special cases needed to be added for the shift-key and things like !@#$ etc.
Fred
Administrator
Administrator
Posts: 16681
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

On my v4, the @$^ etc. are correctly handled, it was changed during the beta testing. About the repeating stuff, for a chat program i won't see why it's useful. You won't hold down a key during 15 secs unless you want to add some "Ho noooooo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ;). But that's a good point, i will see if it's possible to handle the repeat thing.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Also visual feedback. When people press a key in they expect it to immediately reflect on the screen. With inkey() it only shows on the screen after they've released the key. Perhaps it should be renamed to KeyboardOutkey() :)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

You're doing good work there, dracflamloc, you only lack some logic for the timing and a backspace. I made some additions, here's a modified version to try. It includes a little test program at the end:

Code: Select all

Procedure.s GetKeyboardASCII() 

  Static oldkey.s 
  Static timer_on.l 
  Static start.l 

  kchar.s="" 
  If KeyboardPushed(#PB_Key_0) Or KeyboardPushed(#PB_Key_Pad0) 
    kchar="0" 
  ElseIf KeyboardPushed(#PB_Key_1) Or KeyboardPushed(#PB_Key_Pad1) 
    kchar="1" 
  ElseIf KeyboardPushed(#PB_Key_2) Or KeyboardPushed(#PB_Key_Pad2) 
    kchar="2" 
  ElseIf KeyboardPushed(#PB_Key_3) Or KeyboardPushed(#PB_Key_Pad3) 
    kchar="3" 
  ElseIf KeyboardPushed(#PB_Key_4) Or KeyboardPushed(#PB_Key_Pad4) 
    kchar="4" 
  ElseIf KeyboardPushed(#PB_Key_5) Or KeyboardPushed(#PB_Key_Pad5) 
    kchar="5" 
  ElseIf KeyboardPushed(#PB_Key_6) Or KeyboardPushed(#PB_Key_Pad6) 
    kchar="6" 
  ElseIf KeyboardPushed(#PB_Key_7) Or KeyboardPushed(#PB_Key_Pad7) 
    kchar="7" 
  ElseIf KeyboardPushed(#PB_Key_8) Or KeyboardPushed(#PB_Key_Pad8) 
    kchar="8" 
  ElseIf KeyboardPushed(#PB_Key_9) Or KeyboardPushed(#PB_Key_Pad9) 
    kchar="9" 
  ElseIf KeyboardPushed(#PB_Key_Minus) 
    kchar="-" 
  ElseIf KeyboardPushed(#PB_Key_Equals) 
    kchar="=" 
  ElseIf KeyboardPushed(#PB_Key_Slash) 
    kchar="/" 
  ElseIf KeyboardPushed(#PB_Key_BackSlash) 
    kchar="\" 
  ElseIf KeyboardPushed(#PB_Key_LeftBracket) 
    kchar="[" 
  ElseIf KeyboardPushed(#PB_Key_RightBracket) 
    kchar="]" 
  ElseIf KeyboardPushed(#PB_Key_SemiColon) 
    kchar=";" 
  ElseIf KeyboardPushed(#PB_Key_Apostrophe) 
    kchar="'" 
  ElseIf KeyboardPushed(#PB_Key_Period) Or KeyboardPushed(#PB_Key_PadComma) 
    kchar="." 
  ElseIf KeyboardPushed(#PB_Key_Comma) 
    kchar="," 
  ElseIf KeyboardPushed(#PB_Key_Q) 
    kchar="q" 
  ElseIf KeyboardPushed(#PB_Key_W) 
    kchar="w" 
  ElseIf KeyboardPushed(#PB_Key_E) 
    kchar="e" 
  ElseIf KeyboardPushed(#PB_Key_R) 
    kchar="r" 
  ElseIf KeyboardPushed(#PB_Key_T) 
    kchar="t" 
  ElseIf KeyboardPushed(#PB_Key_Y) 
    kchar="y" 
  ElseIf KeyboardPushed(#PB_Key_U) 
    kchar="u" 
  ElseIf KeyboardPushed(#PB_Key_I) 
    kchar="i" 
  ElseIf KeyboardPushed(#PB_Key_O) 
    kchar="o" 
  ElseIf KeyboardPushed(#PB_Key_P) 
    kchar="p" 
  ElseIf KeyboardPushed(#PB_Key_A) 
    kchar="a" 
  ElseIf KeyboardPushed(#PB_Key_S) 
    kchar="s" 
  ElseIf KeyboardPushed(#PB_Key_D) 
    kchar="d" 
  ElseIf KeyboardPushed(#PB_Key_F) 
    kchar="f" 
  ElseIf KeyboardPushed(#PB_Key_G) 
    kchar="g" 
  ElseIf KeyboardPushed(#PB_Key_H) 
    kchar="h" 
  ElseIf KeyboardPushed(#PB_Key_J) 
    kchar="j" 
  ElseIf KeyboardPushed(#PB_Key_K) 
    kchar="k" 
  ElseIf KeyboardPushed(#PB_Key_L) 
    kchar="l" 
  ElseIf KeyboardPushed(#PB_Key_Z) 
    kchar="z" 
  ElseIf KeyboardPushed(#PB_Key_X) 
    kchar="x" 
  ElseIf KeyboardPushed(#PB_Key_C) 
    kchar="c" 
  ElseIf KeyboardPushed(#PB_Key_V) 
    kchar="v" 
  ElseIf KeyboardPushed(#PB_Key_B) 
    kchar="b" 
  ElseIf KeyboardPushed(#PB_Key_N) 
    kchar="n" 
  ElseIf KeyboardPushed(#PB_Key_M) 
    kchar="m" 
  ElseIf KeyboardPushed(#PB_Key_Space) 
    kchar=" " 
  ElseIf KeyboardPushed(#PB_Key_Back) 
    kchar=Chr(14)      
  EndIf 
    
  If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift) 
    Select kchar 
      Case "/" 
        kchar="?" 
      Case "." 
        kchar=">" 
      Case "," 
        kchar="<" 
      Case ";" 
        kchar=":" 
      Case "'" 
        kchar=Chr(34) 
      Case "[" 
        kchar="{" 
      Case "]" 
        kchar="}" 
      Case "\" 
        kchar="|" 
      Case "`" 
        kchar="~" 
      Case "1" 
        kchar="!" 
      Case "2" 
        kchar="@" 
      Case "3" 
        kchar="#" 
      Case "4" 
        kchar="$" 
      Case "5" 
        kchar="%" 
      Case "6" 
        kchar="^" 
      Case "7" 
        kchar="&" 
      Case "8" 
        kchar="*" 
      Case "9" 
        kchar="(" 
      Case "0" 
        kchar=")" 
      Case "-" 
        kchar="_" 
      Case "=" 
        kchar="+" 
    EndSelect 
    
    If Asc(kchar) >= $61 And Asc(kchar) <= $7A 
      kchar=UCase(kchar) 
    EndIf    
  EndIf 
  
  If UCase(kchar)=UCase(oldkey)
    If timer_on 
      If ElapsedMilliseconds()-start < 700 
        ProcedureReturn "" 
      Else 
        Delay(80) 
        ProcedureReturn kchar 
      EndIf 
    Else 
      timer_on = #True 
      start=ElapsedMilliseconds() 
      ProcedureReturn "" 
    EndIf 
  Else 
    oldkey=kchar 
    timer_on = #False 
    ProcedureReturn kchar 
  EndIf 
  
EndProcedure 

; Test program 

InitSprite():InitKeyboard() 
OpenScreen(800,600,32,"") 
Repeat 
  ExamineKeyboard() 
  tmp.s = GetKeyboardASCII() 
  If tmp <> "" 
    If tmp = Chr(14) ; backspace 
      a$=Left(a$,Len(a$)-1) 
    Else 
      a$+tmp 
    EndIf 
  EndIf 
  ClearScreen(0) 
  StartDrawing(ScreenOutput()) 
    DrawText(50,280, a$ + "_",#White,0) 
  StopDrawing() 
  FlipBuffers() 
  Delay(1) 
Until KeyboardPushed(#PB_Key_Escape) 

End
Last edited by netmaestro on Fri Jun 30, 2006 6:11 am, edited 1 time in total.
BERESHEIT
Phoenix
Enthusiast
Enthusiast
Posts: 141
Joined: Sun Sep 04, 2005 2:25 am

Re: okay.. group effort. fixing keyboardinkey...post your fi

Post by Phoenix »

dracflamloc wrote:

Code: Select all

If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift)
    Select kchar
      Case "/"
        kchar="?"
You know this won't work with different keyboard layouts.... don't you???? The slash key on an English keyboard won't produce a ? on a non-English keyboard.... just something for you to be aware of....
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Yes I know but theres really nothing I can do about that with PBs commandset.
DarkDragon
Addict
Addict
Posts: 2228
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

dracflamloc wrote:Yes I know but theres really nothing I can do about that with PBs commandset.
Receiving the #WM_CHAR windowevent on a screen would help very lot.
bye,
Daniel
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Sure if i was only using windows
DarkDragon
Addict
Addict
Posts: 2228
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

dracflamloc wrote:Sure if i was only using windows
On Linux there's most often a gtk version of the windows api command, like you can see for example here:

http://www.purebasic.fr/english/viewtop ... ousebutton
bye,
Daniel
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Yea I'll probably look that up
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I tested the code above on PB 3.94, the procedure itself runs fine but the test program needed a couple minor tweaks. The test program isn't staying with it anyway so I think (-hope?) the procedure should more or less meet the conditions. As far as keyboard language goes, the procedure could be modified to choose the uppercase chars based on a languageID parameter passed, I guess for any really professional offering you'd probably have parsed that before the code ever got to this proc.
BERESHEIT
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

It works except that delay cant be there. It would mess up the rest of the game.
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

i just removed the delay altogether. the repeating is pretty fast this way but its much better than the other one i had.
Post Reply