Seite 1 von 1
[code] HitKey() : Erster Druck auf Taste per KeyboardLib
Verfasst: 13.09.2007 00:51
von Kaeru Gaman
[ScreenMode, OpenScreen, Keyboard Lib, InitKeyboard, KeyboardPushed]
um einen ersten tastendruck zu verarbeiten, muss man mit Flags arbeiten.
für die Flags kann man genauso ein Array anlegen wie intern für die Tastendrücke selber angelegt wird.
Code: Alles auswählen
Global Dim KeyOld.l(255)
Procedure.l KeyHit( Key.l )
Protected HIT = #False
If KeyboardPushed(Key)
If Not KeyOld(Key) ; first press
KeyOld(Key) = #True ; set KeyFlag
HIT = #True
EndIf
Else
KeyOld(Key) = #False ; reset KeyFlag
EndIf
ProcedureReturn HIT
EndProcedure
funktioniert genauso wie KeyboardPushed(#Key), gibt aber nur beim ersten Aufruf #True zurück, falls die Taste gedrückt bleibt.
Verfasst: 13.09.2007 08:39
von NicTheQuick
Man könnte das Array auch mit in die Procedure nehmen und 'Hit' weglassen.
Code: Alles auswählen
Procedure.l KeyHit( Key.l )
Static Dim KeyOld.l(255)
If KeyboardPushed(Key)
If Not KeyOld(Key) ; first press
KeyOld(Key) = #True ; set KeyFlag
ProcedureReturn #True
EndIf
Else
KeyOld(Key) = #False
EndIf
ProcedureReturn #False
EndProcedure
Das ist zwar nicht besser, aber mir würde es so besser gefallen. Wenn man dann ganz wild
darauf is, Speicher zu sparen, kann man statt des Long-Arrays auch ein Byte-Array nutzen.
Verfasst: 13.09.2007 11:23
von Kaeru Gaman
> kann man statt des Long-Arrays auch ein Byte-Array nutzen.
richtig, wird ja von GetKeyboardState_() auch gemacht.
mich störte das jetzt nicht, ein ganzes KB zu benutzen statt eines Viertels,
und der Array-Zugriff ist möglicherweise minimal performanter, weil Long.
> Man könnte das Array auch mit in die Procedure nehmen
auch richtig. ich weiß aber noch nicht, ob ich das nicht noch in ner anderen Proc brauchen könnte.
> und 'Hit' weglassen.
ich war mir nicht mehr sicher, ob das "ProcedureReturn #False" wirklich außerhalb aller Ifs stehen darf...
war schon spät...
im endeffekt ist das "gewachsener Code".
zuerst kam die Idee, dieses Array anzulegen, um nicht für jede Taste mit nem Flag rumdaddeln zu müssen.
dann erst kam die idee, eine Proc draus zu machen, um nicht die Ifs bei jedem Key stehen zu haben.
...und dann war es SO spät in der nacht, dass ich nicht mal mehr ne schleife mit drei verschiedenen transformationen hinbekommen hab, und ich bin in die kiste...
Verfasst: 13.09.2007 11:57
von Shardik
NicTheQuick hat geschrieben:
Wenn man dann ganz wild darauf is, Speicher zu sparen, kann man statt des Long-Arrays auch ein Byte-Array nutzen.
Nur einmal zum Vergleich:
- ein Long-Array benötigt 255 * 4 Bytes = 1020 Bytes, um 255 Bits zu speichern
- ein Byte-Array benötigt nur 255 Bytes
- eigentlich benötigt man ja nur 8 Bytes (= 256 Bits) zur platzsparendsten Speicherung
Ich habe daher einmal ein Code-Beispiel erstellt, das mit den 8 Bytes auskommt und das ganze in Assembler realisiert, um durch den Umrechnungsaufwand nicht zu sehr Performance zu verlieren. Letztendlich muß jeder selbst entscheiden, was ihm wichtiger ist: Platzverbrauch oder Performance
Code: Alles auswählen
Procedure ReadKeyBit(ByteOffset.L, BitOffset.L)
!PUSH EBX
!XOR EAX,EAX
!MOV EBX,DWORD[ESP+12]
!BT DWORD[ESP+8],EBX
!JNC $+3
!INC EAX
!POP EBX
ProcedureReturn
EndProcedure
Procedure ClearKeyBit(ByteOffset.L, BitOffset.L)
!MOV EAX,DWORD[ESP+8]
!BTR DWORD[ESP+4],EAX
EndProcedure
Procedure SetKeyBit(ByteOffset.L, BitOffset.L)
!MOV EAX,[ESP+8]
!BTS DWORD[ESP+4],EAX
EndProcedure
Procedure.L KeyHit(KeyCode.L)
Static KeyBuffer.S{8}
Protected BitOffset.L = KeyCode % 32
Protected ByteOffset.L = @KeyBuffer + KeyCode / 32
If KeyboardPushed(KeyCode)
If ReadKeyBit(ByteOffset, BitOffset) = 0
SetKeyBit(ByteOffset, BitOffset)
ProcedureReturn #True
EndIf
Else
ClearKeyBit(ByteOffset, BitOffset)
ProcedureReturn #False
EndIf
EndProcedure
Verfasst: 13.09.2007 12:07
von Kaeru Gaman
in diesem falle ja, es würde auch ein Bit genügen.
aber die Keyboard-API nutzt einen 256byte-buffer dafür.
dafür will ich es letztendlich auch kompatibel halten.
außerdem vermute ich, dass die Keyboard-Lib auch intern einen 256byte-Buffer benutzt.
ob da noch andere infos drinstecken als nur ein einzelnes Bit, muss ich noch testen...
in diesem Falle ist es nur eine zwischenlösung, um die ganzen Flags für die Tasten bequemer zu verwalten.
letztendlich aber ist es ein Ansatz, später mit den Tabellen der API und der Lib herumzuwerkeln.