The ZX Ecosystem v5.1.0;_GUI_v3.1.0
Loading...
Searching...
No Matches
ZXKeyboard.h
Go to the documentation of this file.
1
2/* *************************************************************************/
24#ifndef ZXKEYBOARD
25#define ZXKEYBOARD
26
27#include <cstdint>
28#include <string>
29#include <utility>
30#include <set>
31#include <map>
32#include <chrono>
33#include <functional>
36
37
38namespace zxeco
39{
40
41/*****************************************************************************
42*
43* Class: Key
44*
45******************************************************************************/
46
48enum class Key { // Must follow the order in which keys are in halfrows (see
49 // Membrane)
51 CAPS_SHIFT = 0, Z, X, C, V,
54 A, S, D, F, G,
57 Q, W, E, R, T,
60 N1, N2, N3, N4, N5,
63 N0, N9, N8, N7, N6,
66 P, O, I, U, Y,
69 ENTER, L, K, J, H,
72 SPACE, SYMBOL_SHIFT, M, N, B,
75 LAST = B,
76 NUMKEYS = B+1,
78 }; // enum class for forcing explicit qualification.
79
81
82extern const std::map<Key,std::string> KeyNames;
83
85
87extern const char KeyLetters[2][static_cast<int>(Key::NUMKEYS)];
88
90
95extern const char KeySymbols[2][static_cast<int>(Key::NUMKEYS)];
96
98constexpr char keyToNumber(Key k)
99 { return( ((k>=Key::N1)&&(k<=Key::N5)) ? static_cast<int>(k)-
100 static_cast<int>(Key::N1)+1 :
101 (
102 ((k>=Key::N9)&&(k<=Key::N6)) ? static_cast<int>(Key::N6)-
103 static_cast<int>(k)+6 :
104 (
105 (k==Key::N0) ? 0 : -1
106 ) ) ); }
107
109constexpr bool keyIsShift(Key k)
110 { return((k==Key::CAPS_SHIFT)||(k==Key::SYMBOL_SHIFT)); }
111
113
118
119
120/*****************************************************************************
121*
122* Class: KeyComb
123*
124******************************************************************************/
125
127
131{
132 public:
133
134 KeyComb(void) noexcept:ok_{false} {}
136
139
146 virtual ~KeyComb(void) = default;
148
149 bool valid(void) const noexcept { return(ok_); }
151
152 bool is(Key shift, Key other) const;
154
158 Key shift(void) const;
160
161 Key other(void) const;
163
164 std::string to_string(void) const noexcept;
166
167 private:
168
169 bool ok_;
170 Key kshift_{Key::NO_KEY};
171 Key kother_{Key::NO_KEY};
172};
173
174
175/*****************************************************************************
176*
177* Class: SetOfKeys
178*
179******************************************************************************/
180
182class SetOfKeys: public std::set<Key>
183{
184 public:
185
186 typedef std::set<Key> Base;
187
188 SetOfKeys(void) = default;
190
191 SetOfKeys(const KeyComb &kc);
193
194 SetOfKeys(const Base &b):Base{b} {}
196
199 KeyComb toKeyComb(void) const noexcept;
201
205 std::string to_string(void) const noexcept;
207
208};
209
210
211/*****************************************************************************
212*
213* Class: Membrane
214*
215******************************************************************************/
216
219{
220 public:
221
222 /* ---------------- Types, consts, etc. ------------------- */
223
226 enum HalfRow { CAPS_V = 0,
234 NUMHALFROWS };
235
238 static constexpr unsigned char KEYSPERROW = 5;
239
242 enum RowMask: unsigned char { MK1 = 1,
243 MK2 = 1 << 1,
244 MK3 = 1 << 2,
245 MK4 = 1 << 3,
246 MK5 = 1 << 4
247 };
248
251
252 static constexpr uint8_t MASKKEYS = 0x1F;
253
255
258 class KeyInRow: public std::pair<HalfRow,RowMask>
259 {
260 public:
261
262 typedef std::pair<HalfRow,RowMask> Base;
263
264 static void checkPair(const Base & b);
266
271 KeyInRow(const Base &b):KeyInRow{b.first,b.second} {}
273
274 virtual ~KeyInRow(void) = default;
276
277 // leave the rest of constructors, move and copies by default
278
279 operator Key(void) const;
281 };
282
283
284 /* ---------------- Attributes ---------------------- */
285
287
290 unsigned char krows[NUMHALFROWS];
291
292
295 // Leave the compiler to generate default copies and moves
296
297 Membrane(void) noexcept { fill_byte(krows,0,NUMHALFROWS); }
299
300 virtual ~Membrane(void) = default;
302
309 void clear(void) noexcept { fill_byte(krows,0,NUMHALFROWS); }
311
312 unsigned char numKeysPressed(void) const noexcept;
314
317 bool someKeyUnpressed(const Membrane & oth) const noexcept;
319
322 bool someKeyPressed(const Membrane & oth) const noexcept;
324
327 bool someNewKeyPressed(const Membrane & oth) const noexcept;
329
338 void setKeyState(Key k, bool pressed = true);
340
341 void setKeyState(const SetOfKeys & soks, bool pressed = true);
343 void setKeyState(const KeyComb & kc, bool pressed = true);
345
346 bool keyState(Key k) const noexcept;
348
349 SetOfKeys keysPressed(void) const noexcept;
351
352 KeyComb combinationPressed(void) const noexcept;
354
365 bool operator!=(const Membrane & oth) const noexcept;
366 bool operator==(const Membrane & oth) const noexcept
367 { return(!(operator!=(oth))); }
368
375 // friends defined inside class are inline and hidden from non-ADL lookup
376 // (http://en.cppreference.com/w/cpp/language/operators)
377
378 Membrane & operator^=(const Membrane & oth) noexcept;
380 friend Membrane operator^(Membrane lhs, // passing lhs by value helps
381 // optimize chained a+b+c
382 const Membrane & rhs) noexcept
383 // otherwise, both parameters may
384 // be const references
385 { lhs ^= rhs; // reuse compound assignment
386 return lhs; } // return the result by value (uses move constructor)
388
389 Membrane & operator&=(const Membrane & oth) noexcept;
391
392 friend Membrane operator&(Membrane lhs, const Membrane & rhs) noexcept
393 { lhs &= rhs; return lhs; }
395
396 Membrane & operator|=(const Membrane & oth) noexcept;
398
399 friend Membrane operator|(Membrane lhs, const Membrane & rhs) noexcept
400 { lhs |= rhs; return lhs; }
402
403 Membrane operator~(void) noexcept;
405
406 std::string to_string(void) const noexcept;
408
411};
412
413
414/*****************************************************************************
415*
416* Class: Keyboard
417*
418******************************************************************************/
419
421
427{
428 public:
429
430 /* ---------------- Consts, types, etc. ----------------- */
431
434 enum class Mode {
435 NORMAL = 0,
436 EXTENDED,
437 GRAPHICS,
438 NUMMODES
439 };
440
441 static uint8_t keyToASCII(Mode km, bool capslock, Key shift, Key k);
443
451 Keyboard(const Membrane & mem0 = Membrane{})
452 { reset(); lastmembrane_ = mem0; }
454
456 virtual ~Keyboard(void) = default;
458
464 void reset(void);
468 std::chrono::steady_clock::duration repdel =
469 std::chrono::milliseconds{700},
470 std::chrono::steady_clock::duration repper =
471 std::chrono::milliseconds{100}) noexcept
472 { keyrepdel_ = repdel; keyrepper_ = repper; }
474
479 bool newMembrane(const Membrane & newmembrane,
480 std::string * lastprstr = nullptr);
482
501 void keyRepetitions(std::chrono::steady_clock::duration & repdel,
502 std::chrono::steady_clock::duration & repper)
503 const noexcept
504 { repdel = keyrepdel_; repper = keyrepper_; }
506
507 Mode mode(void) const noexcept { return(kmode_); }
509
510 bool capsLock(void) const noexcept { return(capslock_); }
512
513 std::chrono::steady_clock::time_point lastEffectiveChange(void) const
514 noexcept
515 { return(lasteffectivechange_); }
517
521 const Membrane & lastMembrane(void) const noexcept
522 { return(lastmembrane_); }
524
525 Key lastKey(void) const noexcept
526 { return(lastpressed_.keyorkeycomb ? lastpressed_.key : Key::NO_KEY); }
532 KeyComb lastKeyComb(void) const noexcept
533 { return(lastpressed_.keyorkeycomb ? KeyComb{} : lastpressed_.keycomb);}
540 bool anyKey(void) const noexcept
541 { return((lastKey() != zxeco::Key::NO_KEY) || (lastKeyComb().valid()));}
543
549 std::string to_string(void) const noexcept;
551
554 private:
555
556 Membrane lastmembrane_;
557 struct {
558 bool keyorkeycomb;
559 Key key;
560 KeyComb keycomb;
561 } lastpressed_;
562 bool repeating_;
563 Mode kmode_;
564 bool capslock_;
565 std::chrono::steady_clock::time_point lasteffectivechange_;
566 std::chrono::steady_clock::duration keyrepdel_,keyrepper_;
567
568 bool changeMode(void);
569 bool changeModeAfter(void) noexcept;
570 bool updateReps(void) noexcept;
571 const std::string lastAsZXString(void) const noexcept;
572};
573
574
575} // end namespace zxeco
576
577#endif
578 // ZXKeyboard
580
A generic enum for adding iteration capabilities to C++11 enum class.
Definition: CppAddons.h:600
bool anyKey(void) const noexcept
Return TRUE if a key or combination of keys were pressed in last membr.
Definition: ZXKeyboard.h:535
RowMask
Constants that are useful to select a key within a half row.
Definition: ZXKeyboard.h:242
@ MK2
Second key.
Definition: ZXKeyboard.h:243
@ MK4
Fourth key.
Definition: ZXKeyboard.h:245
@ MK1
First key (outer) in a HalfRow.
Definition: ZXKeyboard.h:242
@ MK3
Third key.
Definition: ZXKeyboard.h:244
@ MK5
Fifth key (inner).
Definition: ZXKeyboard.h:246
static constexpr uint8_t MASKKEYS
Constant that serves to mask out non-keys bits from a half row status.
Definition: ZXKeyboard.h:252
KeyComb(void) noexcept
Default constructor: an invalid combination.
Definition: ZXKeyboard.h:134
Membrane & operator^=(const Membrane &oth) noexcept
XOR + assignment.
virtual ~Membrane(void)=default
Destructor.
bool someNewKeyPressed(const Membrane &oth) const noexcept
Check if OTH keys pressed that are not pressed in this.
Membrane & operator|=(const Membrane &oth) noexcept
OR + assignment.
void keyRepetitions(std::chrono::steady_clock::duration &repdel, std::chrono::steady_clock::duration &repper) const noexcept
Fill both arguments with the current repetition parameters.
Definition: ZXKeyboard.h:499
Keyboard(const Membrane &mem0=Membrane{})
Default constructor. No key pressed, no capslock, NORMAL mode.
Definition: ZXKeyboard.h:451
SetOfKeys(const KeyComb &kc)
Constructor from a given combination, or empty if KC is invalid.
unsigned char krows[NUMHALFROWS]
The membrane status.
Definition: ZXKeyboard.h:290
Mode mode(void) const noexcept
Return the current keyboard mode.
Definition: ZXKeyboard.h:505
Key shift(void) const
Return the shift key if valid; raise an exception otherwise.
bool someKeyUnpressed(const Membrane &oth) const noexcept
Check if this has keys of OTH unpressed.
std::string to_string(void) const noexcept
Return a string representing the whole keyboard state.
virtual ~KeyComb(void)=default
Destructor.
KeyComb combinationPressed(void) const noexcept
Get the combination that is currently pressed in the membrane, if any.
KeyComb toKeyComb(void) const noexcept
Conversion to a combination of keys.
void reset(void)
Reset the keyboard to its initial state: key pressed, NO_KEY.
std::set< Key > Base
Just syntactic sugar.
Definition: ZXKeyboard.h:186
void setKeyState(const KeyComb &kc, bool pressed=true)
Change the press state of the combination KC to PRESSED.
virtual ~KeyInRow(void)=default
Destructor.
std::pair< HalfRow, RowMask > Base
Just sugar.
Definition: ZXKeyboard.h:262
KeyInRow(const Base &b)
Constructor from base object. Exception if invalid.
Definition: ZXKeyboard.h:271
friend Membrane operator&(Membrane lhs, const Membrane &rhs) noexcept
AND.
Definition: ZXKeyboard.h:392
bool capsLock(void) const noexcept
Return the current capslock state.
Definition: ZXKeyboard.h:508
static uint8_t keyToASCII(Mode km, bool capslock, Key shift, Key k)
Return the ASCII code correponding to the given key pressing SHIFT + K.
friend Membrane operator^(Membrane lhs, const Membrane &rhs) noexcept
XOR + assignment.
Definition: ZXKeyboard.h:380
unsigned char numKeysPressed(void) const noexcept
Get number of keys pressed.
bool valid(void) const noexcept
Return TRUE if the combination is a valid one.
Definition: ZXKeyboard.h:149
void setKeyState(Key k, bool pressed=true)
Change the press state of K to PRESSED. Exception if K is invalid.
KeyComb lastKeyComb(void) const noexcept
Get the combination of keys pressed in the last membrane fed into this.
Definition: ZXKeyboard.h:528
Key other(void) const
Return the other key if valid; raise an exception otherwise.
KeyInRow(Key k)
Constructor from a key id. Exception if K is invalid.
Key lastKey(void) const noexcept
Get the key pressed in the last membrane fed into this keyboard.
Definition: ZXKeyboard.h:522
KeyComb(Key shift, Key other)
Constructor of a combination with the given SHIFT and OTHER keys.
std::chrono::steady_clock::time_point lastEffectiveChange(void) const noexcept
Get the time of the last change that was recognized by the keyboard.
Definition: ZXKeyboard.h:511
Mode
The keyboard modes recognized by the zx operating system.
Definition: ZXKeyboard.h:434
@ EXTENDED
Extended mode (E).
@ NORMAL
Normal mode (C or L).
@ GRAPHICS
Graphics mode (G).
Membrane(void) noexcept
Default constructor: the entire membrane is set to 0.
Definition: ZXKeyboard.h:297
HalfRow
Half-rows that form the membrane of the zx, in the same order as ZX port.
Definition: ZXKeyboard.h:226
@ CAPS_V
Keys (outer to inner): CAPSSHIFT, Z, X, C, V.
Definition: ZXKeyboard.h:226
@ P_Y
Keys: P, O, I, U, Y.
Definition: ZXKeyboard.h:231
@ ZERO_SIX
Keys: 0, 9, 8, 7, 6.
Definition: ZXKeyboard.h:230
@ Q_T
Keys: Q, W, E, R, T.
Definition: ZXKeyboard.h:228
@ SPC_B
Keys: SPACE, SYMBOLSHIFT, M, N, B.
Definition: ZXKeyboard.h:233
@ A_G
Keys: A, S, D, F, G.
Definition: ZXKeyboard.h:227
@ ENTER_H
Keys: ENTER, L, K, J, H.
Definition: ZXKeyboard.h:232
@ ONE_FIVE
Keys: 1, 2, 3, 4, 5.
Definition: ZXKeyboard.h:229
bool newMembrane(const Membrane &newmembrane, std::string *lastprstr=nullptr)
Update state of the keyboard from the given Membrane.
std::string to_string(void) const noexcept
Return a string representing the Membrane.
void setKeyRepetitions(std::chrono::steady_clock::duration repdel=std::chrono::milliseconds{700}, std::chrono::steady_clock::duration repper=std::chrono::milliseconds{100}) noexcept
Set key repetition parameters.
Definition: ZXKeyboard.h:466
static constexpr unsigned char KEYSPERROW
Number of keys per half row.
Definition: ZXKeyboard.h:238
bool someKeyPressed(const Membrane &oth) const noexcept
Check if this has keys additionaly pressed to the ones of OTH.
void setKeyState(const SetOfKeys &soks, bool pressed=true)
Change the press state of the entire set SOKS to PRESSED.
virtual ~Keyboard(void)=default
Destructor.
Membrane & operator&=(const Membrane &oth) noexcept
< XOR.
SetOfKeys(const Base &b)
Constructor from an initialized set of keys.
Definition: ZXKeyboard.h:194
friend Membrane operator|(Membrane lhs, const Membrane &rhs) noexcept
OR.
Definition: ZXKeyboard.h:399
SetOfKeys keysPressed(void) const noexcept
Return the set of keys that are pressed currently in the membrane.
std::string to_string(void) const noexcept
Return a string describing the set of keys.
void clear(void) noexcept
Clear all keys pressed.
Definition: ZXKeyboard.h:309
bool is(Key shift, Key other) const
Whether this combination is composed concretely of SHIFT + OTHER.
const Membrane & lastMembrane(void) const noexcept
Return the last membrane that this Keyboard is aware of.
Definition: ZXKeyboard.h:518
SetOfKeys(void)=default
Default constructor: an empty set of keys.
KeyInRow(HalfRow h=CAPS_V, RowMask m=MK1)
Default constructor, and from row and mask. Exception if invalid.
std::string to_string(void) const noexcept
Convert the combination to a string.
bool keyState(Key k) const noexcept
Return the state of key K in the membrane. FALSE if K is invalid.
Membrane operator~(void) noexcept
NOT.
static void checkPair(const Base &b)
Throw an exception if B contains an invalid half row or mask.
A combination of 2 keys.
Definition: ZXKeyboard.h:131
The ZX keyboard as it behaves (for typing) under the ZX operating system.
Definition: ZXKeyboard.h:427
The zx keyboard as a membrane. Useful for games and those sort of things.
Definition: ZXKeyboard.h:219
Complete definition of a key in the membrane.
Definition: ZXKeyboard.h:259
A set of several keys, not repeated.
Definition: ZXKeyboard.h:183
The main namespace of the library, that spans across all the zx modules.
Definition: ZXChars.h:31
const std::map< Key, std::string > KeyNames
This constant holds printable/descriptive names for the keys.
constexpr char keyToNumber(Key k)
Return the number of the key [0..9] if K is a number key; -1 if it is not.
Definition: ZXKeyboard.h:98
const char KeySymbols[2][static_cast< int >(Key::NUMKEYS)]
This constant holds the symbols printed in the keys.
const char KeyLetters[2][static_cast< int >(Key::NUMKEYS)]
This constant holds the single letters printed in the keys.
IterableEnum< Key > ItKey
Enhanced Key type.
Definition: ZXKeyboard.h:117
Key
A single key in the zx keyboard.
Definition: ZXKeyboard.h:48
@ X
Key in the 1st half-row.
@ CAPS_SHIFT
Key in the 1st half-row.
@ C
Key in the 1st half-row.
@ NO_KEY
Null key id.
@ Z
Key in the 1st half-row.
@ FIRST
Needed for enhancing the enum.
@ ENTER
Key in the 7th half-row.
@ E
Key in the 3rd half-row.
@ N6
Key in the 5th half-row.
@ P
Key in the 6th half-row.
@ U
Key in the 6th half-row.
@ V
Key in the 1st half-row.
@ Y
Key in the 6th half-row.
@ S
Key in the 2nd half-row.
@ W
Key in the 3rd half-row.
@ SPACE
Key in the 8th half-row.
@ M
Key in the 8th half-row.
@ N0
Key in the 5th half-row.
@ N8
Key in the 5th half-row.
@ A
Key in the 2nd half-row.
@ F
Key in the 2nd half-row.
@ N1
Key in the 4th half-row.
@ SYMBOL_SHIFT
Key in the 8th half-row.
@ N
Key in the 8th half-row.
@ B
Key in the 8th half-row.
@ K
Key in the 7th half-row.
@ N3
Key in the 4th half-row.
@ N4
Key in the 4th half-row.
@ T
Key in the 3rd half-row.
@ N5
Key in the 4th half-row.
@ N7
Key in the 5th half-row.
@ H
Key in the 7th half-row.
@ N2
Key in the 4th half-row.
@ L
Key in the 7th half-row.
@ NUMKEYS
Number of keys.
@ I
Key in the 6th half-row.
@ G
Key in the 2nd half-row.
@ R
Key in the 3rd half-row.
@ Q
Key in the 3rd half-row.
@ O
Key in the 6th half-row.
@ LAST
Needed for enhancing the enum.
@ D
Key in the 2nd half-row.
@ N9
Key in the 5th half-row.
@ J
Key in the 7th half-row.
constexpr bool keyIsShift(Key k)
Return TRUE if K is caps or symbol.
Definition: ZXKeyboard.h:109