Seite 1 von 1

Flush Key Include

Verfasst: 24.10.2006 17:27
von Kekskiller
Mich hats immer gestört, dass man bei PB bei den DirectX-Tastaturanweisungen kein FlushKeys, wie z.b. bei Blitzbasic hatte. Für alle, die nicht wissen was gemeint ist: Originale FlushKey-Erklärung

Mein FlushKey funktioniert etwas anders. Man kann wesentlich mehr einstellen und hat ne ganzen Stange an Funktionen, man kann auch einzelne Keys flushen. So lässt sich z.b. das KeyboardReleased() mit Hilfe eins Flags bei einem meiner Keys gegen ein genaueres 1-mal-Abfragen ersetzen. Ich weiß, die Hilfe ist nicht der Hammer... Aber ich denke, man bekommt alles recht fix raus :D ...

Ein Beispiel habe ich auch (für euch zum testen), ihr benötigt die folgende Include-Datei:

Code: Alles auswählen

;FlushKeyLib
;---------------------------------
;by Kekskiller
;to flush keys

Structure fk_key
  key.l ;key-code des keys
  flags.b ;flags, enthalten #FK_STATE_... und #FK_PROPERTY_...
  lock_function.l ;function, die nach einem flushen aufgerufen wird
  unlock_function.l ;function, die nach einem ent-flushen aufgerufen wird
EndStructure

#FK_NULL = 0

#FK_PROPERTY_AUTOFLUSH = 1 ;wird nach einmaliger key-abfrage den key flushen
#FK_PROPERTY_LOCKFUNCTION_DISABLED = 2 ;es wird kein lock_function call ausgeführt
#FK_PROPERTY_UNLOCKFUNCTION_DISABLED = 4 ;es wird kein unlock_function call ausgeführt

#FK_STATE_PRESSED = 8 ;ob der key zuletzt gedrückt wurde
#FK_STATE_IGNORED = 16 ;ignore-flag, trotz tasten druck wird 0 zurückgegeben (durch flushen gesetzt)

Global NewList fk_KeyList.fk_key()

Procedure fkAddKey(pbkey.l, flags.l = #FK_NULL)
  AddElement(fk_KeyList())
  ;set the key to "all open"
  fk_KeyList()\key = pbkey
  fk_KeyList()\flags = flags
  ProcedureReturn ListIndex(fk_KeyList())
EndProcedure

Procedure fkFlushKey(keyNr.l)
  SelectElement(fk_KeyList(), keyNr)
  ;wenn taste gedrückt, dann flushen
  If fk_KeyList()\flags & #FK_STATE_PRESSED
    fk_KeyList()\flags | #FK_STATE_IGNORED ;wenn taste zuletzt aktiv, dann unterbrechen
    ;funktion bei sperrung rufen
    If fk_KeyList()\lock_function And fk_KeyList()\flags & #FK_PROPERTY_LOCKFUNCTION_DISABLED = 0
      CallFunctionFast(fk_KeyList()\lock_function, keyNr)
    EndIf
  EndIf
EndProcedure

Procedure fkExamineKeys()
  ForEach fk_KeyList()
    ;wenn taste wirklich unten, dann "flaggen"
    If KeyboardPushed(fk_KeyList()\key) > 0
      fk_KeyList()\flags | #FK_STATE_PRESSED
    Else
      ;ansonsten "entflaggen" <- wenn überhaupt gesetzt
      If fk_KeyList()\flags & #FK_STATE_PRESSED
        fk_KeyList()\flags ! #FK_STATE_PRESSED
      EndIf
    EndIf
    ;wenn die taste nicht mehr gedrückt, dann ignore zurücksetzen
    If fk_KeyList()\flags & #FK_STATE_PRESSED = 0 And fk_KeyList()\flags & #FK_STATE_IGNORED
      fk_KeyList()\flags ! #FK_STATE_IGNORED
      ;funktion nach freischaltung rufen
      If fk_KeyList()\unlock_function And fk_KeyList()\flags & #FK_PROPERTY_UNLOCKFUNCTION_DISABLED = 0
        CallFunctionFast(fk_KeyList()\unlock_function, ListIndex(fk_KeyList()))
      EndIf
    EndIf
  Next
EndProcedure

Procedure fkKeyState(keyNr.l)
  SelectElement(fk_KeyList(), keyNr)
  ;wenn ignore-flag gesetzt, 0 übergeben
  If fk_KeyList()\flags & #FK_STATE_IGNORED
    ProcedureReturn 0
  Else
    If fk_KeyList()\flags & #FK_STATE_PRESSED
      ;wenn autoflush aktiviert key flushen
      If fk_KeyList()\flags & #FK_PROPERTY_AUTOFLUSH
        fkFlushKey(keyNr)
      EndIf
      ProcedureReturn 1
    Else
      ProcedureReturn 0
    EndIf
  EndIf
EndProcedure

Procedure fkClearAllKeys()
  ClearList(fk_KeyList())
EndProcedure

Procedure fkFlushKeys(keyNrFrom.l, keyNrTo.l) ;keyNrTo = -1 -> last element
  Protected fk_z
  ;wenn -1 letztes element auswählen
  If keyNrTo = -1
    keyNrTo = CountList(fk_KeyList()) - 1
  EndIf
  ;tasten von ... bis ... flushen
  For fk_z = keyNrFrom To keyNrTo
    SelectElement(fk_KeyList(), fk_z)
    fkFlushKey(fk_z)
  Next
EndProcedure

Procedure fkKeyStatesCall(keyNrFrom.l, keyNrTo.l, *function) ;keyNrTo = -1 -> last element
  Protected fk_z
  ;wenn -1 letztes element auswählen
  If keyNrTo = -1
    keyNrTo = CountList(fk_KeyList()) - 1
  EndIf
  ;tasten von ... bis ... abfragen und funktion ausführen
  For fk_z = keyNrFrom To keyNrTo
    SelectElement(fk_KeyList(), fk_z)
    ;wenn taste gedrückt, dann function callen
    CallFunctionFast(*function, fk_z, fkKeyState(fk_z))
  Next
EndProcedure

Procedure fkSetKeyFunctions(keyNr.l, lock_function.l, unlock_function.l) ; -1 = no function will set
  SelectElement(fk_KeyList(), keyNr)
  If lock_function <> -1
    fk_KeyList()\lock_function = lock_function
  EndIf
  If unlock_function <> -1
    fk_KeyList()\unlock_function = unlock_function
  EndIf
EndProcedure

Procedure fkSetKeyFlags(keyNr.l, flags.l)
  SelectElement(fk_KeyList(), keyNr)
  fk_KeyList()\flags = flags
EndProcedure

Procedure fkSetKeyCode(keyNr.l, pbkey)
  SelectElement(fk_KeyList(), keyNr)
  fk_KeyList()\key = pbkey
EndProcedure

Procedure fkIsKeyLockedFlag(keyNr.l)
  SelectElement(fk_KeyList(), keyNr)
  ProcedureReturn fk_KeyList()\flags & #FK_STATE_IGNORED
EndProcedure

Procedure fkIsKeyPressedFlag(keyNr.l)
  SelectElement(fk_KeyList(), keyNr)
  ProcedureReturn fk_KeyList()\flags & #FK_STATE_PRESSED
EndProcedure
Im folgenden Beispiel sind vier Tasten eingetragen, ihr seht sie auf dem Bildschirm, hier das Beispiel:

Code: Alles auswählen

;FlushKeyLib-Example
;by Kekskiller

IncludeFile "fklib.pbi"

InitSprite()
InitKeyboard()

OpenWindow(0, 0,0, 320,240, "fkTest", #PB_Window_ScreenCentered|#PB_Window_TitleBar|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0,0, 640,480, 0,0,0)
LoadFont(0, "Courier New", 10)

Declare PrintKeyState(keyNr.l, state.b)
Declare UnLock(keyNr.l)
Declare Lock(keyNr.l)

;keys hinzufügen
Define.l
Global key_return = fkAddKey(#PB_Key_Return)
Global key_x = fkAddKey(#PB_Key_X)
Global key_c = fkAddKey(#PB_Key_C, #FK_PROPERTY_AUTOFLUSH)
Global key_space = fkAddKey(#PB_Key_Space)

Global Color_On = RGB(0,255,0)
Global Color_Off = RGB(255,55,55)
Global Color_Locked = RGB(55,55,255)

;Lock und Unlock-Nachrichten setzen für function call setzen
fkSetKeyFunctions(key_return, @Lock(), @UnLock())
fkSetKeyFunctions(key_x,  @Lock(), @UnLock())
fkSetKeyFunctions(key_c,  @Lock(), @UnLock())
fkSetKeyFunctions(key_space,  @Lock(), @UnLock())

Repeat 
  ExamineKeyboard()
  fkExamineKeys()
  If KeyboardReleased(#PB_Key_RightAlt)
    fkFlushKeys(key_return, key_space)
  EndIf
  
  ClearScreen(0)
  
  StartDrawing(ScreenOutput())
  DrawingFont(FontID(0))
  fkKeyStatesCall(0, -1, @PrintKeyState())
  DrawText(5,120, "Press right alt to flush ALL keys.", RGB(128,128,128), 0)
  DrawText(5,140, "C is an autoflush key (1-hit-only).", RGB(128,128,128), 0)
  StopDrawing()
  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

Procedure PrintKeyState(keyNr.l, state.b)
  Select keyNr
    Case key_return
      Select state
        Case #True:  DrawText(5,20, "ON  return", Color_On, 0)
        Case #False: DrawText(5,20, "OFF return", Color_Off, 0)
      EndSelect
      If fkIsKeyLockedFlag(key_return)
        DrawText(100,20, "[LOCKED]", Color_Locked, 0)
      EndIf
    Case key_x
      Select state
        Case #True:  DrawText(5,40, "ON  x", Color_On, 0)
        Case #False: DrawText(5,40, "OFF x", Color_Off, 0)
      EndSelect
      If fkIsKeyLockedFlag(key_x)
        DrawText(100,40, "[LOCKED]", Color_Locked, 0)
      EndIf
    Case key_c
      Select state
        Case #True:  DrawText(5,60, "ON  c", Color_On, 0)
        Case #False: DrawText(5,60, "OFF c", Color_Off, 0)
      EndSelect
      If fkIsKeyLockedFlag(key_c)
        DrawText(100,60, "[LOCKED]", Color_Locked, 0)
      EndIf
    Case key_space
      Select state
        Case #True:  DrawText(5,80, "ON  space", Color_On, 0)
        Case #False: DrawText(5,80, "OFF space", Color_Off, 0)
      EndSelect
      If fkIsKeyLockedFlag(key_space)
        DrawText(100,80, "[LOCKED]", Color_Locked, 0)
      EndIf
  EndSelect
EndProcedure

Procedure UnLock(keyNr.l)
  Select keyNr
    Case key_return : Debug "unlocked return"
    Case key_x : Debug "unlocked x"
    Case key_c : Debug "unlocked x"
    Case key_space : Debug "unlocked space"
  EndSelect
EndProcedure

Procedure Lock(keyNr.l)
  Select keyNr
    Case key_return : Debug "locked return"
    Case key_x : Debug "locked x"
    Case key_c : Debug "locked x"
    Case key_space : Debug "locked space"
  EndSelect
EndProcedure
Ev. wirds der eine oder andere gebrauchen können.