|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
1.1.1.3 root 9: #include "header.h"
1.1.1.7 ! root 10: #include <vector>
1.1.1.3 root 11:
1.1 root 12: // 属性
1.1.1.3 root 13: class TA
14: {
15: public:
16: enum TextAttr : uint {
17: Normal = 0x00 << 8,
1.1.1.7 ! root 18: // スイッチ用機能ビット
! 19: // On, Off, Disable は2ビットを使った3状態値。
1.1.1.3 root 20: // これらが実際どう表現されるかはデバイスによる。
21: On = 0x01 << 8, // ビットとかがオンであることを示す
22: Off = 0x02 << 8, // ビットとかがオフであることを示す
23: Disable = 0x03 << 8, // 機能などが無効であることを示す
1.1.1.7 ! root 24: // On, Off, Disable のスイッチ用機能のビットマスク
! 25: SwitchMask = 0x03 << 8,
! 26:
! 27: // Em は独立したビットによる状態。
1.1.1.3 root 28: Em = 0x04 << 8, // 値の変化など強調することを示す
29: } attr {};
30:
31: TA() { }
32: TA(TextAttr attr_) : attr(attr_) { }
1.1.1.7 ! root 33: // uint からのコンストラクタ
! 34: TA(uint attr_) : TA((TextAttr)attr_) { }
1.1.1.3 root 35:
36: // uint へのキャスト
37: operator uint() const {
38: return (uint)attr;
39: }
40:
1.1.1.7 ! root 41: // スイッチ用機能ビット部を返す。
! 42: TextAttr GetSwitch() const {
! 43: return (TextAttr)(attr & SwitchMask);
! 44: }
! 45:
! 46: // スイッチ用機能ビット部を設定する。
! 47: void SetSwitch(TextAttr a) {
! 48: attr = (TextAttr)((attr & ~SwitchMask) | (a & SwitchMask));
! 49: }
! 50:
! 51: // スイッチ用機能ビットの状態を調べる。
! 52: bool IsOn() const { return GetSwitch() == TA::On; }
! 53: bool IsOff() const { return GetSwitch() == TA::Off; }
! 54: bool IsDisable() const { return GetSwitch() == TA::Disable; }
! 55:
! 56: // static member
1.1.1.3 root 57: // val によって On か Off を返す
58: static const TA OnOff(bool val) {
59: return (val) ? TA::On : TA::Off;
60: }
1.1 root 61: };
62:
63: //
64: // テキストスクリーン
65: //
66: // col × row で指定されるテキスト画面。
67: // 表示可能なのは 0x20..0x7e の printable 文字。
1.1.1.7 ! root 68: // 及び \n (0x0a) は復帰改行する。
! 69: // それ以外の 0x20 未満と 0x7f の動作は未定。
1.1 root 70: // 漢字は 2桁占有する。文字列として指定する時は UTF-8 だが、内部コードは
71: // Shift_JIS なので、第一水準、第二水準の文字だけを指定すること。
72: //
73: // TextScreen() コンストラクタで作成して Init(col, row) するか、
74: // TextScreen(col, row) コンストラクタを呼ぶかどちらか選択。
75: // チェックとかはしていないので併用しないこと。
76: //
1.1.1.7 ! root 77: // Locate などにより範囲外にカーソルを移動することはできる。
! 78: // ただしその位置を始点としての文字出力は無視される。
1.1 root 79: class TextScreen
80: {
81: public:
1.1.1.7 ! root 82: // 文字の送りモード
! 83: enum ModeKind {
! 84: // 右端は無視される
! 85: Fixed,
! 86: // 右端は次の行に改行し、最終行だったときは上スクロールする
! 87: Console,
! 88: // 右端は次の行に改行し、最終行右端は左上に戻る
! 89: Ring,
! 90: } Mode { Fixed };
! 91:
1.1 root 92: TextScreen();
93: TextScreen(int col, int row);
94: virtual ~TextScreen();
95:
96: // 初期化
97: void Init(int col, int row);
98:
1.1.1.4 root 99: // 画面をクリアして、カーソルをホームポジションに移動
1.1 root 100: void Clear();
101:
1.1.1.2 root 102: // 現在位置を移動
1.1.1.3 root 103: void Locate(int x, int y) {
104: X = x;
105: Y = y;
1.1.1.7 ! root 106: OutOfScreen = (X < 0 || X >= col || Y < 0 || Y >= row);
! 107: }
! 108:
! 109: // 文字出力後の右移動
! 110: void Ascend() {
! 111: X++;
! 112: if (X >= col) {
! 113: switch (Mode) {
! 114: case Fixed:
! 115: OutOfScreen = true;
! 116: break;
! 117: case Console:
! 118: case Ring:
! 119: CRLF();
! 120: break;
! 121: }
! 122: }
1.1.1.3 root 123: }
1.1.1.2 root 124:
1.1.1.7 ! root 125: // 復帰改行
! 126: void CRLF()
! 127: {
! 128: X = 0;
! 129: Y++;
! 130: switch (Mode) {
! 131: case Fixed:
! 132: break;
! 133: case Console:
! 134: if (Y >= row) {
! 135: ScrollUp();
! 136: Y = row - 1;
! 137: }
! 138: break;
! 139: case Ring:
! 140: if (Y >= row) {
! 141: Y = 0;
! 142: }
! 143: break;
! 144: }
! 145: // どのモードであっても OutOfScreen を更新
! 146: // (Y=-1 から CRLF したら表示可能になるべき)
! 147: OutOfScreen = (Y < 0 || Y >= row);
! 148: }
! 149:
! 150: // 1行の上スクロール
! 151: void ScrollUp();
! 152:
! 153: //
! 154: // 出力関数群
! 155: // 出力関数はカーソル位置を更新する。
! 156: //
! 157:
1.1 root 158: // 現在位置に1文字出力 (上位バイトは属性)
1.1.1.7 ! root 159: void Putc(uint16 ch);
1.1 root 160:
1.1.1.3 root 161: // 現在位置に文字列を出力
1.1 root 162: void Puts(const char *str);
163:
164: // 現在位置に指定の属性で文字列を出力
1.1.1.3 root 165: void Puts(TA attr, const char *str);
166:
167: // 座標を指定して文字列を出力
168: void Puts(int x, int y, const char *str) {
169: Locate(x, y);
170: Puts(str);
171: }
172:
173: // 座標と属性を指定して、文字列を出力
174: void Puts(int x, int y, TA attr, const char *str) {
175: Locate(x, y);
176: Puts(attr, str);
177: }
1.1 root 178:
1.1.1.2 root 179: // 現在位置に属性なしで書式付き文字列を出力
180: void Print(const char *fmt, ...) __printflike(2, 3);
181:
1.1 root 182: // 座標を指定して属性なしで書式付き文字列を出力
183: void Print(int x, int y, const char *fmt, ...) __printflike(4, 5);
184:
185: // 座標と属性を指定して、書式付き文字列を出力
1.1.1.3 root 186: void Print(int x, int y, TA attr, const char *fmt, ...)
1.1 root 187: __printflike(5, 6);
188:
1.1.1.7 ! root 189: // 現在のカーソル位置の文字を取得
! 190: // カーソルは移動する。
! 191: uint16 Getc();
! 192:
! 193: // 現在位置の属性を取得
! 194: TA GetAttr() const;
! 195:
! 196: // 現在位置の属性を attr に設定
! 197: // カーソルは移動しない。
! 198: void SetAttr(TA attr);
1.1 root 199:
1.1.1.7 ! root 200: // バッファを取得。(描画デバイス向け)
! 201: const std::vector<uint16>& GetBuf() const { return textbuf; }
1.1.1.2 root 202:
203: // 現在の X 座標を取得
204: int GetX() const { return X; }
205: // 現在の Y 座標を取得
206: int GetY() const { return Y; }
1.1 root 207:
208: // 桁数を取得
209: int GetCol() const { return col; }
210:
211: // 行数を取得
212: int GetRow() const { return row; }
213:
1.1.1.4 root 214: // ユーザ定義の引数
215: // ご自由にお使いください。例えばモニタの出力開始オフセットやアドレス
216: // など、呼び出し側が設定して書き出す側がそれに従った内容を出力する
217: // ような用途。
1.1.1.5 root 218: uint64 userdata {};
1.1.1.2 root 219:
1.1.1.4 root 220: protected:
1.1 root 221: // バッファ (幅x高さちょうどの長さ、ゼロ終端文字列ではない)
222: // 上位8ビットは属性、下位8ビットが文字コード。
1.1.1.7 ! root 223: std::vector<uint16> textbuf {};
1.1 root 224:
225: // 幅
1.1.1.5 root 226: int col {};
1.1 root 227:
228: // 高さ
1.1.1.5 root 229: int row {};
1.1 root 230:
231: // カーソル X 座標
1.1.1.5 root 232: int X {};
1.1 root 233:
234: // カーソル Y 座標
1.1.1.5 root 235: int Y {};
1.1.1.7 ! root 236:
! 237: // カーソルが画面外に位置するとき true
! 238: bool OutOfScreen {};
1.1 root 239: };
1.1.1.4 root 240:
241: //
242: // テキストコンソール
243: //
244: class TextConsole : public TextScreen
245: {
246: using inherited = TextScreen;
247: public:
248: TextConsole();
249: };
250:
251: //
252: // モニターインタフェース
253: //
254: // モニターされる側はこのインタフェースを実装すること。
255: //
256: class IMonitor
257: {
258: public:
1.1.1.6 root 259: virtual ~IMonitor();
260:
1.1.1.4 root 261: // 自身の現在の状態を TextScreen に書き出す
262: virtual void MonitorUpdate(TextScreen&) = 0;
263:
264: // このモニターが必要とするサイズ(桁数×行数)を取得する
265: virtual nnSize GetMonitorSize() = 0;
266: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.