|
|
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: //
8: // テキストスクリーン
9: //
10:
1.1.1.9 root 11: #include "textscreen.h"
12:
1.1 root 13: // コンストラクタ
14: TextScreen::TextScreen()
15: {
16: }
17:
18: // コンストラクタ
19: TextScreen::TextScreen(int arg_col, int arg_row)
20: {
21: Init(arg_col, arg_row);
22: }
23:
24: // デストラクタ
25: TextScreen::~TextScreen()
26: {
27: }
28:
29: // 初期化
30: void
1.1.1.7 root 31: TextScreen::Init(int arg_col, int arg_row, ModeKind mode)
1.1 root 32: {
1.1.1.6 root 33: assert(arg_col > 0);
34: assert(arg_row > 0);
35:
1.1 root 36: col = arg_col;
37: row = arg_row;
1.1.1.7 root 38: Mode = mode;
1.1 root 39:
1.1.1.6 root 40: textbuf.resize(col * row);
1.1 root 41: X = 0;
42: Y = 0;
43:
44: Clear();
45: }
46:
47: // クリア
48: void
49: TextScreen::Clear()
50: {
51: for (int i = 0; i < col * row; i++) {
52: textbuf[i] = 0x0020;
53: }
1.1.1.2 root 54:
1.1.1.4 root 55: // ホームポジション
56: Locate(0, 0);
1.1.1.2 root 57: }
58:
1.1.1.12! root 59: // 文字出力後の右移動。
! 60: void
! 61: TextScreen::Ascend()
! 62: {
! 63: X++;
! 64: if (X >= col) {
! 65: switch (Mode) {
! 66: case Fixed:
! 67: OutOfScreen = true;
! 68: break;
! 69: case Console:
! 70: case Ring:
! 71: CRLF();
! 72: break;
! 73: }
! 74: }
! 75: }
! 76:
! 77: // 改行。
! 78: void
! 79: TextScreen::LF()
! 80: {
! 81: Y++;
! 82: switch (Mode) {
! 83: case Fixed:
! 84: break;
! 85: case Console:
! 86: if (Y >= row) {
! 87: ScrollUp();
! 88: Y = row - 1;
! 89: }
! 90: break;
! 91: case Ring:
! 92: if (Y >= row) {
! 93: Y = 0;
! 94: }
! 95: break;
! 96: }
! 97:
! 98: // どのモードであっても OutOfScreen を更新
! 99: // (Y=-1 から CRLF したら表示可能になるべき)
! 100: OutOfScreen = (Y < 0 || Y >= row);
! 101: }
! 102:
1.1.1.6 root 103: // 1 行上スクロール
104: void
105: TextScreen::ScrollUp()
106: {
107: memmove(&textbuf[0], &textbuf[col],
108: (row - 1) * col * sizeof(textbuf[0]));
109: for (int i = 0; i < col; i++) {
110: textbuf[(row - 1) * col + i] = 0x0020;
111: }
112: }
113:
114:
1.1 root 115: // 現在のカーソル位置に1文字出力する。
116: void
117: TextScreen::Putc(uint16 ch)
118: {
1.1.1.8 root 119: if (ch == '\n') {
120: CRLF();
1.1 root 121: return;
122: }
123:
1.1.1.8 root 124: if (OutOfScreen) {
125: return;
1.1.1.6 root 126: }
1.1.1.8 root 127:
128: textbuf[(Y * col) + X] = ch;
129: Ascend();
1.1.1.6 root 130: }
131:
1.1.1.12! root 132: // 現在のカーソル位置の文字を取得。
! 133: // カーソルは移動しない。
1.1.1.6 root 134: // カーソルが範囲外だったときは 0 を返す。
135: uint16
136: TextScreen::Getc()
137: {
138: if (OutOfScreen) {
139: return 0;
140: }
141:
1.1.1.12! root 142: return textbuf[(Y * col) + X];
1.1 root 143: }
144:
145: // テキストスクリーンに文字列を出力する。
146: void
147: TextScreen::Puts(const char *str)
148: {
149: while (*str != '\0') {
1.1.1.11 root 150: uint16 ch = (uint8)*str++;
151: Putc(ch);
1.1 root 152: }
153: }
154:
155: // テキストスクリーンに文字列を出力する。
156: void
1.1.1.3 root 157: TextScreen::Puts(TA attr, const char *str)
1.1 root 158: {
159: while (*str != '\0') {
1.1.1.3 root 160: Putc(((uint)attr) | *str++);
1.1 root 161: }
162: }
163:
1.1.1.2 root 164: // テキストスクリーンの現在位置から書式付き文字列を出力する。
165: void
166: TextScreen::Print(const char *fmt, ...)
167: {
168: char buf[1024];
169: va_list ap;
170:
171: va_start(ap, fmt);
172: vsnprintf(buf, sizeof(buf), fmt, ap);
173: va_end(ap);
174:
175: Puts(buf);
176: }
177:
1.1 root 178: // テキストスクリーンに座標を指定して書式付き文字列を出力する。
179: void
180: TextScreen::Print(int x, int y, const char *fmt, ...)
181: {
182: char buf[1024];
183: va_list ap;
184:
185: va_start(ap, fmt);
186: vsnprintf(buf, sizeof(buf), fmt, ap);
187: va_end(ap);
188:
1.1.1.2 root 189: Locate(x, y);
1.1 root 190: Puts(buf);
191: }
192:
193: // テキストスクリーンに座標と属性を指定して、書式付き文字列を出力する。
194: void
1.1.1.3 root 195: TextScreen::Print(int x, int y, TA attr, const char *fmt, ...)
1.1 root 196: {
197: char buf[1024];
198: va_list ap;
199:
200: va_start(ap, fmt);
201: vsnprintf(buf, sizeof(buf), fmt, ap);
202: va_end(ap);
203:
1.1.1.2 root 204: Locate(x, y);
1.1 root 205: Puts(attr, buf);
206: }
1.1.1.2 root 207:
1.1.1.12! root 208: // 現在のカーソル位置に文字を出力。
! 209: // カーソルは移動しない。ch がカーソル移動を伴う制御文字なら動作不定。
! 210: void
! 211: TextScreen::Setc(uint16 ch)
! 212: {
! 213: textbuf[(Y * col) + X] = ch;
! 214: }
! 215:
! 216: // 指定のカーソル位置に文字を出力。
! 217: // カーソルは移動しない。ch がカーソル移動を伴う制御文字なら動作不定。
! 218: void
! 219: TextScreen::Setc(int x, int y, uint16 ch)
! 220: {
! 221: textbuf[(y * col) + x] = ch;
! 222: }
! 223:
1.1.1.6 root 224: // 現在位置の属性を取得
225: // カーソルが画面外の場合は TA::Normal を返す。
226: TA
227: TextScreen::GetAttr() const
1.1.1.4 root 228: {
1.1.1.6 root 229: if (OutOfScreen) {
230: return TA::Normal;
231: }
1.1.1.4 root 232:
1.1.1.6 root 233: return TA(textbuf[(Y * col) + X] & 0xff00);
1.1.1.4 root 234: }
235:
1.1.1.6 root 236: // 現在位置の属性を attr に設定する。
237: // カーソルは移動しない。
1.1.1.4 root 238: void
1.1.1.6 root 239: TextScreen::SetAttr(TA attr)
1.1.1.4 root 240: {
1.1.1.6 root 241: if (OutOfScreen) {
1.1.1.4 root 242: return;
243: }
244:
1.1.1.6 root 245: auto& ch = textbuf[(Y * col) + X];
246: ch = (ch & 0xff) | (uint)attr;
1.1.1.4 root 247: }
1.1.1.10 root 248:
249: // src の src_y 行目から rows 行をこのスクリーンの dst_y 行目以降にコピーする。
250: // 双方のカーソルは移動しない。
251: // もし row がどちらかではみ出た場合はコピーをそこで終了する。
252: // src と dst (この screen) の桁数が違うと assert する。
253: void
254: TextScreen::CopyRowsFrom(int dst_y, int rows, const TextScreen& src, int src_y)
255: {
256: assert(GetCol() == src.GetCol());
257:
258: const auto& srcbuf = src.GetBuf();
259:
260: // rows を小さいほうに揃える。
261: if (rows > GetRow() - dst_y) {
262: rows = GetRow() - dst_y;
263: }
264: if (rows > src.GetRow() - src_y) {
265: rows = src.GetRow() - src_y;
266: }
267:
268: // 内部構造を知っているので一気にコピー。
269: memcpy(&textbuf[dst_y * col], &srcbuf[src_y * col],
270: sizeof(textbuf[0]) * col * rows);
271: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.