|
|
nono 1.7.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// キーボード (基本クラス)
//
#pragma once
#include "device.h"
#include "fixedqueue.h"
#include "message.h"
class Syncer;
class UIMessage;
// 文字入力しか持たないキーボードの下位クラス。
class DumbKeyboard : public Device
{
using inherited = Device;
public:
DumbKeyboard();
~DumbKeyboard() override;
// 文字入力によるキーエミュレーション (外部から呼ばれる)
virtual void CharInput(uint charcode) = 0;
};
// 通常のキーボード
class Keyboard : public DumbKeyboard
{
using inherited = DumbKeyboard;
protected:
Keyboard();
public:
~Keyboard() override;
bool Init() override;
void ResetHard(bool poweron) override;
void PowerOff() override;
// キーを押した (外部から呼ばれる)
void MakeKey(uint keycode);
// キーを離した (外部から呼ばれる)
void BreakKey(uint keycode);
// 文字入力によるキーエミュレーション (外部から呼ばれる)
void CharInput(uint charcode) override;
// マウス入力。
// x, y は X, Y の前回からの移動量。
// X は画面右に動く方向をプラス、Y は画面下に動く方向をプラスとする。
// 移動量が VM で扱える範囲内か、それを越えていたらどうするかは
// 継承クラスが処理する。
// rb, lb, mb はボタンの状態。true なら押下中。
virtual void MouseInput(int x, int y, bool rb, bool lb, bool mb) = 0;
// マウスデータを VM に送信する MD 処理
virtual void MouseSendStart() = 0;
// ホストからの制御コマンド
virtual void Command(uint32 data) = 0;
// 指定のキーの押し下げ状態取得 (ソフトウェアキーボードなどから)
bool IsPressed(uint keycode) const {
assert(keycode < pressed.size());
return pressed[keycode];
}
// LED 状態取得 (ソフトウェアキーボードなどから)
const std::vector<bool>& GetLED() const { return led; }
// シフト状態なら true を返す
// シフトキーは機種によって処理が異なるため、この関数を使って
// 状態を取得すること。
virtual bool IsShift() const = 0;
// キーボードを接続する
void Connect(bool connect);
// キーボードが接続されていれば true を返す
bool IsConnected() const { return is_connected; }
// キー名を返す (主にデバッグ表示用)
static const std::string GetKeyName(uint code);
protected:
// キーボードの接続処理の実体
void DoConnect();
void DoDisconnect();
virtual void MDConnect() = 0;
virtual void MDDisconnect() = 0;
// キーコードには、
// o 共通キーコード(コードのみ)、
// o 共通キーコード(コードと Make/Break フラグあり)、
// o 機種依存キーコード
// の3つがあり、どれも uint なので変数名で区別することにする。
// o keycode .. 共通キーコード
// o keystat .. フラグ付き共通キーコード
// o mdkey .. 機種依存キーコード
// 共通キーコードを機種別のキーコードに変換する
virtual uint KeyToMDKey(uint keycode) const = 0;
// キーを1つ処理する
virtual void KeyInput(uint keystat) = 0;
// キーの押し下げ状態を設定する
void SetPressed(uint keycode, bool ismake);
// キーを処理する (共通部分)
bool KeyInputCommon(uint keystat);
// キーが1つでも押されていれば true
bool Any() const;
// キーを VM に送信する MD 処理
virtual void SendStart() = 0;
// キーボードが接続されているとき true
bool is_connected {};
// どのキーが押されているか (共通キーコード)
std::vector<bool> pressed {};
// 入力されたキーを VM へ送信するときのバッファ。
FixedQueue<uint, 8> sendqueue {};
// LED (true で点灯)。
// GetLED() あたりが同じ形式で済むのでここにあるけど、機種によって
// LED 数が違うので、何番がどのキーに対応するかの取り決めや、初期化も
// 含めたコードはすべて派生クラス側で用意すること。
std::vector<bool> led {};
// マウス状態
int mouse_x {}; // 前回送信から現在までの積算値
int mouse_y {};
bool mouse_r {}; // 現在値
bool mouse_l {};
bool mouse_m {};
bool prev_r {}; // 前回送信時の値
bool prev_l {};
bool prev_m {};
Syncer *syncer {};
UIMessage *uimessage {};
private:
void KeyInputMessage(MessageID, uint32);
static std::vector<const char *> keyname;
static std::vector<uint> char_key;
};
// フルキーボードの取得 (シリアルキーボードは含まない)
inline Keyboard *GetKeyboard() {
return Object::GetObject<Keyboard>(OBJ_KEYBOARD);
}
// keystat は下位 8bit がキーコード。
// 上位(今の所 8bit) は各種フラグ。
//
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// |M/B|UI | LED | 0 | KM_* | Keycode |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// | | | |
// | | | +-- キャラクタ入力でのモディファイヤフラグ
// | | +------------------ LUNA の LED キー送信フラグ
// | +------------------------ char 入力モードでキーコードを UI に通知
// | (inputqueue 内で使用する)
// +---------------------------- キーの Make/Break
#define KM_SHIFT (0x0100) // char モードで SHIFT 押下
#define KM_CTRL (0x0200) // char モードで CTRL 押下
#define KC_FLAG_LED_MAKE (0x1000) // LUNA LED キーの押下を送信
#define KC_FLAG_LED_BREAK (0x2000) // LUNA LED キーの開放を送信
#define KC_FLAG_LED_DROP (0x3000) // LUNA LED キーを送信しない
#define KC_FLAG_POST (0x4000) // キーコードを UI に通知
#define KC_FLAG_MAKE (0x0000) // キー押下 (値は 0 だが便宜上)
#define KC_FLAG_BREAK (0x8000) // キー開放
// keystat のアクセスマクロ
#define KC_CODE(x) ((x) & 0x00ff) // keycode を取得
#define KC_FLAG_LED(x) ((x) & 0x3000) // LUNA LED キー動作を取得
#define KC_IS_POST(x) (((x) & KC_FLAG_POST) != 0) // UI に通知なら true
#define KC_IS_MAKE(x) (((x) & KC_FLAG_BREAK) == 0) // キー押下なら true
#define KC_IS_BREAK(x) (((x) & KC_FLAG_BREAK) != 0) // キー開放なら true
// 抽象化キーボードレイヤーでのキーコード。
// wxWidgets で受け取ったキーコードをこれに変換して VM に入力する。
// VM のキーボードデバイスがこれを当該機種ごとのキーコードなり何なりに
// 変換して入力する。
#define KC_none (0)
#define KC_BREAK (0x01) // [X68k] BREAK
#define KC_romaji (0x03) // [X68k] ローマ字
#define KC_code (0x04) // [X68k] コード入力
#define KC_kigou (0x05) // [X68k] 記号入力
#define KC_touroku (0x06) // [X68k] 登録
#define KC_HELP (0x07) // [X68k] HELP
#define KC_SHIFT (0x08) // [X68k] SHIFT (左右の区別なし)
#define KC_TAB (0x09)
#define KC_CTRL (0x0a)
#define KC_kana (0x0b) // かな
#define KC_SHIFT_L (0x0c) // SHIFT(左) / [LUNA-88K] (右)
#define KC_SHIFT_R (0x0d) // SHIFT(右) / [LUNA-88K] (左)
#define KC_CAPS (0x0e)
#define KC_SF (0x0f) // [LUNA-I] S.F / [LUNA-88K] META
#define KC_ESC (0x10)
#define KC_BS (0x11) // BackSpace
#define KC_enter (0x12) // Enter (Return)
#define KC_space (0x14)
#define KC_DEL (0x15)
#define KC_XFER (0x16) // [LUNA] XFER (変換)
#define KC_VALID (0x17) // [LUNA] VALID(確定)
#define KC_PF11 (0x18) // [LUNA] PF11
#define KC_PF12 (0x19) // [LUNA] PF12
#define KC_PF13 (0x1a) // [LUNA] PF13
#define KC_PF14 (0x1b) // [LUNA] PF14
#define KC_up (0x1c) // cursor up
#define KC_left (0x1d) // cursor left
#define KC_right (0x1e) // cursor right
#define KC_down (0x1f) // cursor down
#define KC_INS (0x20) // [LUNA-88K] INSERT / [X68k] INS
#define KC_COPY (0x21) // [LUNA-88K] [X68k]
#define KC_1 (0x22)
#define KC_2 (0x23)
#define KC_3 (0x24)
#define KC_4 (0x25)
#define KC_5 (0x26)
#define KC_6 (0x27)
#define KC_7 (0x28)
#define KC_8 (0x29)
#define KC_9 (0x2a)
#define KC_0 (0x2b)
#define KC_minus (0x2c)
#define KC_circum (0x2d) // ^~
#define KC_backslash (0x2e) // \|
#define KC_buzzer (0x2f) // [LUNA] ブザー発声 (キーではない)
#define KC_CUT (0x30) // [LUNA-88K]
#define KC_PASTE (0x31) // [LUNA-88K]
#define KC_Q (0x32)
#define KC_W (0x33)
#define KC_E (0x34)
#define KC_R (0x35)
#define KC_T (0x36)
#define KC_Y (0x37)
#define KC_U (0x38)
#define KC_I (0x39)
#define KC_O (0x3a)
#define KC_P (0x3b)
#define KC_at (0x3c)
#define KC_bracketleft (0x3d) // '['
#define KC_hira (0x3e) // [X68k] ひらがな
#define KC_zenkaku (0x3f) // [X68k] 全角
#define KC_UNDO (0x41) // [X68k] UNDO
#define KC_A (0x42)
#define KC_S (0x43)
#define KC_D (0x44)
#define KC_F (0x45)
#define KC_G (0x46)
#define KC_H (0x47)
#define KC_J (0x48)
#define KC_K (0x49)
#define KC_L (0x4a)
#define KC_semicolon (0x4b)
#define KC_colon (0x4c)
#define KC_bracketright (0x4d) // ']'
#define KC_OPT1 (0x4e) // [X68k] OPT.1
#define KC_OPT2 (0x4f) // [X68k] OPT.2
#define KC_XF1 (0x50) // [X68k] XF1
#define KC_XF2 (0x51) // [X68k] XF2
#define KC_Z (0x52)
#define KC_X (0x53)
#define KC_C (0x54)
#define KC_V (0x55)
#define KC_B (0x56)
#define KC_N (0x57)
#define KC_M (0x58)
#define KC_comma (0x59)
#define KC_period (0x5a)
#define KC_slash (0x5b)
#define KC_underscore (0x5c)
#define KC_XF3 (0x5d) // [X68k] XF3
#define KC_XF4 (0x5e) // [X68k] XF4
#define KC_XF5 (0x5f) // [X68k] XF5
#define KC_HOME (0x60) // [LUNA-88K] [X68k]
#define KC_PAD_plus (0x61)
#define KC_PAD_minus (0x62)
#define KC_PAD_7 (0x63)
#define KC_PAD_8 (0x64)
#define KC_PAD_9 (0x65)
#define KC_PAD_4 (0x66)
#define KC_PAD_5 (0x67)
#define KC_PAD_6 (0x68)
#define KC_PAD_1 (0x69)
#define KC_PAD_2 (0x6a)
#define KC_PAD_3 (0x6b)
#define KC_PAD_0 (0x6c)
#define KC_PAD_decimal (0x6d) // .
#define KC_PAD_enter (0x6e)
#define KC_PAD_CLR (0x6f) // [X68k] CLR
#define KC_ROLLUP (0x70) // [X68k] ROLL UP
#define KC_ROLLDOWN (0x71) // [X68k] ROLL DOWN
#define KC_F1 (0x72)
#define KC_F2 (0x73)
#define KC_F3 (0x74)
#define KC_F4 (0x75)
#define KC_F5 (0x76)
#define KC_F6 (0x77)
#define KC_F7 (0x78)
#define KC_F8 (0x79)
#define KC_F9 (0x7a)
#define KC_F10 (0x7b)
#define KC_PAD_multiply (0x7c)
#define KC_PAD_divide (0x7d)
#define KC_PAD_equal (0x7e)
#define KC_PAD_comma (0x7f)
#define KC_max (0x80)
// 文字入力モードの拡張部分
#define CC_NUL (0x80) // NUL (Ctrl + @)
#define CC_F1 (0x81)
#define CC_F2 (0x82)
#define CC_F3 (0x83)
#define CC_F4 (0x84)
#define CC_F5 (0x85)
#define CC_F6 (0x86)
#define CC_F7 (0x87)
#define CC_F8 (0x88)
#define CC_F9 (0x89)
#define CC_F10 (0x8a)
#define CC_up (0x8c)
#define CC_left (0x8d)
#define CC_right (0x8e)
#define CC_down (0x8f)
#define CC_disconnect (0x90) // キーボードを取り外す
#define CC_connect (0x91) // キーボードを接続する
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.