|
|
1.1 root 1: //
2: // nono
1.1.1.4 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
9: #include "device.h"
1.1.1.6 ! root 10: #include "event.h"
! 11: #include "fixedqueue.h"
! 12: #include <mutex>
1.1 root 13:
14: class Keyboard : public Device
15: {
1.1.1.4 root 16: using inherited = Device;
1.1 root 17: protected:
18: Keyboard();
19: public:
1.1.1.5 root 20: virtual ~Keyboard() override;
1.1 root 21:
1.1.1.6 ! root 22: virtual void ResetHard() override;
! 23:
! 24: // キーを押した (外部から呼ばれる)
! 25: void MakeKey(uint keycode);
! 26: // キーを離した (外部から呼ばれる)
! 27: void BreakKey(uint keycode);
1.1 root 28:
1.1.1.2 root 29: // マウス入力
30: // x, y は X, Y の前回からの移動量。
31: // X は画面右に動く方向をプラス、Y は画面下に動く方向をプラスとする。
32: // 移動量が VM で扱える範囲内か、それを越えていたらどうするかは
33: // 継承クラスが処理する。
34: // rb, lb, mb はボタンの状態。true なら押下中。
35: virtual void MouseInput(int x, int y, bool rb, bool lb, bool mb) = 0;
36:
1.1.1.4 root 37: // ホストからの制御コマンド
38: virtual void Command(uint32 data) = 0;
39:
1.1.1.6 ! root 40: // 指定のキーの押し下げ状態取得 (ソフトウェアキーボードなどから)
! 41: bool IsPressed(uint keycode) const {
! 42: assert(keycode < pressed.size());
! 43: return pressed[keycode];
! 44: }
! 45:
! 46: // 全てのキーの押し下げ状態取得 (ソフトウェアキーボードなどから)
! 47: const std::vector<bool>& GetPressed() const { return pressed; }
! 48:
1.1.1.4 root 49: // LED 状態取得 (ソフトウェアキーボードなどから)
50: const std::vector<bool>& GetLED() const { return led; }
51:
1.1.1.6 ! root 52: // シフト状態なら true を返す
! 53: // シフトキーは機種によって処理が異なるため、この関数を使って
! 54: // 状態を取得すること。
! 55: virtual bool IsShift() const = 0;
! 56:
1.1 root 57: // キー名を返す (主にデバッグ表示用)
58: static const std::string GetName(uint code);
59:
1.1.1.4 root 60: protected:
1.1.1.6 ! root 61: // キーコードには、
! 62: // o 共通キーコード(コードのみ)、
! 63: // o 共通キーコード(コードと Make/Break フラグあり)、
! 64: // o 機種依存キーコード
! 65: // の3つがあり、どれも uint なので変数名で区別することにする。
! 66: // o keycode .. 共通キーコード
! 67: // o keystat .. フラグ付き共通キーコード
! 68: // o mdkey .. 機種依存キーコード
! 69:
! 70: // 共通キーコードを機種別のキーコードに変換する
! 71: virtual uint KeyToMDKey(uint keycode) const = 0;
! 72:
! 73: // 入力されたキーを前処理し、フィルタする。
! 74: // デフォルトは何もせず通過。
! 75: virtual uint PreprocessKey(uint keystat) { return keystat; }
! 76:
! 77: // キーを押した/離した時の MD 固有処理。
! 78: // 処理を継続するなら true、このキーの処理をここでやめるなら false。
! 79: // デフォルトは何もせず通過。
! 80: virtual bool ProcessKey(uint keystat) { return true; }
! 81:
! 82: // キーを VM に送信する MD 処理
! 83: virtual void SendStart() = 0;
! 84:
! 85: // どのキーが押されているか (共通キーコード)
! 86: std::vector<bool> pressed {};
! 87:
! 88: // 現在押されているキーの総数
! 89: int num_of_pressed {};
! 90:
! 91: // ホストから来たキー入力をバッファする。
! 92: // 実際には固定長でない普通のキューで構わないんだけど、モニタ用に中身を
! 93: // 覗き見したいとか思うと、ほぼそのための FixedQueue を使うほうがいい。
! 94: // 固定長である必要はないけど、無限に可変長である必要もないので。
! 95:
! 96: // UI からの入力を VM スレッドへ引き渡すためのバッファ。
! 97: FixedQueue<uint, 8> inputqueue {};
! 98:
! 99: // 入力されたキーを VM へ送信するときのバッファ。
! 100: FixedQueue<uint, 8> sendqueue {};
! 101:
1.1.1.4 root 102: // LED (true で点灯)。
103: // GetLED() あたりが同じ形式で済むのでここにあるけど、機種によって
104: // LED 数が違うので、何番がどのキーに対応するかの取り決めや、初期化も
105: // 含めたコードはすべて派生クラス側で用意すること。
106: std::vector<bool> led {};
107:
1.1 root 108: private:
1.1.1.6 ! root 109: // キー入力を VM スレッドで処理するためのイベント
! 110: void KeyInputCallback(Event& ev);
! 111: void KeyInput(uint keystat);
! 112: Event keyinput_event {};
! 113: std::mutex mtx {};
! 114:
1.1 root 115: static std::vector<const char *> keyname;
116: };
117:
1.1.1.3 root 118: extern std::unique_ptr<Keyboard> gKeyboard;
1.1 root 119:
120: // 抽象化キーボードレイヤーでのキーコード。
121: // wxWidgets で受け取ったキーコードをこれに変換して VM に入力する。
122: // VM のキーボードデバイスがこれを当該機種ごとのキーコードなり何なりに
123: // 変換して入力する。
124:
1.1.1.6 ! root 125: // keystat のフラグ
! 126: #define KC_FLAG_MAKE (0x0000) // 押した
! 127: #define KC_FLAG_BREAK (0x8000) // 離した
! 128: #define KC_IS_MAKE(x) (((x) & KC_FLAG_BREAK) == 0)
! 129: #define KC_IS_BREAK(x) (((x) & KC_FLAG_BREAK) != 0)
! 130:
! 131: // keystat からフラグだけ取り出す
! 132: #define KC_FLAG(x) ((x) & 0x8000)
! 133:
! 134: // keystat からキーコードだけ取り出す
! 135: #define KC_CODE(x) ((x) & 0x7fff)
! 136:
1.1 root 137: #define KC_none (0)
138:
139: #define KC_BREAK (0x01) // [X68k] BREAK
140: #define KC_COPY (0x02) // [X68k] COPY
141: #define KC_romaji (0x03) // [X68k] ローマ字
142: #define KC_code (0x04) // [X68k] コード入力
143: #define KC_kigou (0x05) // [X68k] 記号入力
144: #define KC_touroku (0x06) // [X68k] 登録
145: #define KC_HELP (0x07) // [X68k] HELP
146: #define KC_HOME (0x08) // [X68k] HOME
147: #define KC_TAB (0x09)
148: #define KC_CTRL (0x0a)
149: #define KC_kana (0x0b) // かな
150: #define KC_SHIFT_L (0x0c) // SHIFT(左)
151: #define KC_SHIFT_R (0x0d) // SHIFT(右)
152: #define KC_CAPS (0x0e)
153: #define KC_SF (0x0f) // [LUNA] S.F
154:
155: #define KC_ESC (0x10)
156: #define KC_BS (0x11) // BackSpace
157: #define KC_enter (0x12) // Enter (Return)
158: #define KC_INS (0x13) // [X68k] INS
159: #define KC_space (0x14)
160: #define KC_DEL (0x15)
161: #define KC_XFER (0x16) // [LUNA] XFER
162: #define KC_VALID (0x17) // [LUNA] VALID
163: #define KC_PF11 (0x18) // [LUNA] PF11
164: #define KC_PF12 (0x19) // [LUNA] PF12
165: #define KC_PF13 (0x1a) // [LUNA] PF13
166: #define KC_PF14 (0x1b) // [LUNA] PF14
167: #define KC_up (0x1c) // cursor up
168: #define KC_left (0x1d) // cursor left
169: #define KC_right (0x1e) // cursor right
170: #define KC_down (0x1f) // cursor down
171:
172: #define KC_ROLLUP (0x20) // [X68k] ROLL UP
173: #define KC_ROLLDOWN (0x21) // [X68k] ROLL DOWN
174: #define KC_1 (0x22)
175: #define KC_2 (0x23)
176: #define KC_3 (0x24)
177: #define KC_4 (0x25)
178: #define KC_5 (0x26)
179: #define KC_6 (0x27)
180: #define KC_7 (0x28)
181: #define KC_8 (0x29)
182: #define KC_9 (0x2a)
183: #define KC_0 (0x2b)
184: #define KC_minus (0x2c)
185: #define KC_circum (0x2d) // ^~
186: #define KC_backslash (0x2e) // \|
187: #define KC_UNDO (0x2f) // [X68k] UNDO
188:
189: #define KC_OPT1 (0x30) // [X68k] OPT.1
190: #define KC_OPT2 (0x31) // [X68k] OPT.2
191: #define KC_Q (0x32)
192: #define KC_W (0x33)
193: #define KC_E (0x34)
194: #define KC_R (0x35)
195: #define KC_T (0x36)
196: #define KC_Y (0x37)
197: #define KC_U (0x38)
198: #define KC_I (0x39)
199: #define KC_O (0x3a)
200: #define KC_P (0x3b)
201: #define KC_at (0x3c)
202: #define KC_bracketleft (0x3d) // '['
203: #define KC_hira (0x3e) // [X68k] ひらがな
204: #define KC_zenkaku (0x3f) // [X68k] 全角
205:
206: #define KC_A (0x42)
207: #define KC_S (0x43)
208: #define KC_D (0x44)
209: #define KC_F (0x45)
210: #define KC_G (0x46)
211: #define KC_H (0x47)
212: #define KC_J (0x48)
213: #define KC_K (0x49)
214: #define KC_L (0x4a)
215: #define KC_semicolon (0x4b)
216: #define KC_colon (0x4c)
217: #define KC_bracketright (0x4d) // ']'
218:
219: #define KC_Z (0x52)
220: #define KC_X (0x53)
221: #define KC_C (0x54)
222: #define KC_V (0x55)
223: #define KC_B (0x56)
224: #define KC_N (0x57)
225: #define KC_M (0x58)
226: #define KC_comma (0x59)
227: #define KC_period (0x5a)
228: #define KC_slash (0x5b)
229: #define KC_underscore (0x5c)
230:
231: #define KC_PAD_plus (0x61)
232: #define KC_PAD_minus (0x62)
233: #define KC_PAD_7 (0x63)
234: #define KC_PAD_8 (0x64)
235: #define KC_PAD_9 (0x65)
236: #define KC_PAD_4 (0x66)
237: #define KC_PAD_5 (0x67)
238: #define KC_PAD_6 (0x68)
239: #define KC_PAD_1 (0x69)
240: #define KC_PAD_2 (0x6a)
241: #define KC_PAD_3 (0x6b)
242: #define KC_PAD_0 (0x6c)
243: #define KC_PAD_decimal (0x6d) // .
244: #define KC_PAD_enter (0x6e)
245: #define KC_PAD_CLR (0x6f) // [X68k] CLR
246:
247: #define KC_F1 (0x72)
248: #define KC_F2 (0x73)
249: #define KC_F3 (0x74)
250: #define KC_F4 (0x75)
251: #define KC_F5 (0x76)
252: #define KC_F6 (0x77)
253: #define KC_F7 (0x78)
254: #define KC_F8 (0x79)
255: #define KC_F9 (0x7a)
256: #define KC_F10 (0x7b)
257: #define KC_PAD_multiply (0x7c)
258: #define KC_PAD_divide (0x7d)
259: #define KC_PAD_equal (0x7e)
260: #define KC_PAD_comma (0x7f)
261:
262: #define KC_XF1 (0x80) // [X68k] XF1
263: #define KC_XF2 (0x81) // [X68k] XF2
264: #define KC_XF3 (0x82) // [X68k] XF3
265: #define KC_XF4 (0x83) // [X68k] XF4
266: #define KC_XF5 (0x84) // [X68k] XF5
1.1.1.6 ! root 267: #define KC_SHIFT (0x85) // [X68k] SHIFT (左右の区別なし)
1.1 root 268:
1.1.1.6 ! root 269: #define KC_max (0x86)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.