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