Getchar not reading arrows
BlitzMax Forums/BlitzMax Module Tweaks/Getchar not reading arrows
| ||
I have managed a way to correctly catch special keys (i.e.: arrow, F1, etc.) in a way very similar to GetChar. The main benefit is that with this method, you get system keyboard repeat and a sequential key buffer! Great for several uses! Background information on this topic: KeyHit() is not particularly useful since it 'loses' key press order. Furthermore, it doesn't support key repeat. Its best use would be to catch simple things, like KEY_ESCAPE to quit. KeyDown() is great for a game, because you detect the actual status of a key. No need for buffering or repeat here. GetChar() is perfect for string input, because it supports localisation, uppercase and lowercase, backspace, etc. And it is buffered, and stored sequentially in the order the user pressed the keys. However, it does NOT record special keys! Let's say for example that you want to allow a player to enter his name. You would like to allow left and right arrow keys to move the cursor. This cursor movement should support key repeat, just like in any Mac or Windows gui application. This is where this small bit of code comes to help. The function is called SpecialGetKey. Please note that it returns scancodes, not ascii codes. I have posted here in module tweak because this function could be added to polledinput very easily and I think would be appreciated. Graphics 800,600,0 ' Mimic the way 'GetChar' works: Global charGet,charPut,charQueue[256] AddHook EmitEventHook,KeyboardHook,Null,0 Function SpecialGetKey() If charGet=charPut Return 0 Local n=charQueue[charGet & 255] charGet:+1 Return n End Function While Not KeyHit(KEY_ESCAPE) And Not AppTerminate() Cls Local c2 = SpecialGetKey() If(c2 <> 0) Then DrawText "scancode "+c2, 100, 100 Flip Delay(1) Wend End Function KeyboardHook:Object( id,data:Object,context:Object ) Local ev:TEvent=TEvent(data) If Not ev Return data ' In this hook, we'll catch only KEYDOWN and KEYREPEAT events: ' KEYDOWN occurs immediately when a key is pressed, ' and KEYREPEAT occurs repeatedly if the key is held for a certain time. If ev.id = EVENT_KEYDOWN Or ev.id = EVENT_KEYREPEAT Then If(ev.data < 256) Then If charPut-charGet<256 charQueue[charPut & 255]=ev.data charPut:+1 EndIf EndIf EndIf Return data End Function |