--- nono/lib/textscreen.h 2026/04/29 17:04:40 1.1.1.5 +++ nono/lib/textscreen.h 2026/04/29 17:05:30 1.1.1.15 @@ -4,32 +4,55 @@ // Licensed under nono-license.txt // +// +// テキストスクリーン +// + #pragma once -#include "header.h" +#include "nono.h" +#include // 属性 class TA { public: enum TextAttr : uint { - Normal = 0x00 << 8, - // On, Off, Disable は3ビットを使った状態値。 - // これらが実際どう表現されるかはデバイスによる。 - On = 0x01 << 8, // ビットとかがオンであることを示す - Off = 0x02 << 8, // ビットとかがオフであることを示す - Disable = 0x03 << 8, // 機能などが無効であることを示す - Em = 0x04 << 8, // 値の変化など強調することを示す + // 文字(2バイト)の上位バイトが属性。 + // + // 15 14 13 12 11 10 9 8 + // +---+---+---+---+---+---+---+---+ + // | B | - | Color Code | + // +---+---+---+---+---+---+---+---+ + // + // B はボールド。 + // Color Code は 4bit の前景色・背景色ペアの固定パレット。 + Normal = 0x00 << 8, // 通常描画色 + Reverse = 0x01 << 8, // 反転、背景黒 + Off = 0x02 << 8, // オフを示す + Disable = 0x03 << 8, // 無効を示す + ReverseRed = 0x04 << 8, // 反転、背景赤 + ReverseGreen = 0x05 << 8, // 反転、背景緑 + ReverseOrange = 0x06 << 8, // 反転、背景オレンジ + + Bold = 0x80 << 8, // ボールド + + // エイリアス + On = Reverse, // オンは反転で表現している + Em = Bold | Normal, // 通常色 + 強調のショートカット } attr {}; TA() { } TA(TextAttr attr_) : attr(attr_) { } + // uint からのコンストラクタ + TA(uint attr_) : TA((TextAttr)attr_) { } // uint へのキャスト operator uint() const { return (uint)attr; } + // static member // val によって On か Off を返す static const TA OnOff(bool val) { return (val) ? TA::On : TA::Off; @@ -41,7 +64,8 @@ class TA // // col × row で指定されるテキスト画面。 // 表示可能なのは 0x20..0x7e の printable 文字。 -// 0x20 未満と 0x7f の動作は未定。 +// 及び \n (0x0a) は復帰改行する。 +// それ以外の 0x20 未満と 0x7f の動作は未定。 // 漢字は 2桁占有する。文字列として指定する時は UTF-8 だが、内部コードは // Shift_JIS なので、第一水準、第二水準の文字だけを指定すること。 // @@ -49,15 +73,27 @@ class TA // TextScreen(col, row) コンストラクタを呼ぶかどちらか選択。 // チェックとかはしていないので併用しないこと。 // -class TextScreen +// Locate などにより範囲外にカーソルを移動することはできる。 +// ただしその位置を始点としての文字出力は無視される。 +class TextScreen final { public: + // 文字の送りモード + enum ModeKind { + // 右端は無視される + Fixed, + // 右端は次の行に改行し、最終行だったときは上スクロールする + Console, + // 右端は次の行に改行し、最終行右端は左上に戻る + Ring, + } Mode { Fixed }; + TextScreen(); TextScreen(int col, int row); - virtual ~TextScreen(); + ~TextScreen(); // 初期化 - void Init(int col, int row); + void Init(int col, int row, ModeKind mode = ModeKind::Fixed); // 画面をクリアして、カーソルをホームポジションに移動 void Clear(); @@ -66,65 +102,120 @@ class TextScreen void Locate(int x, int y) { X = x; Y = y; + OutOfScreen = (X < 0 || X >= col || Y < 0 || Y >= row); + } + void SetX(int x) { + X = x; + OutOfScreen = (X < 0 || X >= col); + } + void SetY(int y) { + Y = y; + OutOfScreen = (Y < 0 || Y >= row); + } + + // 文字出力後の右移動 + void Ascend(); + + // 復帰 + void CR() noexcept { + X = 0; + } + + // 改行 + void LF(); + + // 復帰改行 + void CRLF() { + CR(); + LF(); } + // 1行の上スクロール + void ScrollUp(); + + // + // 出力関数群 + // 出力関数はカーソル位置を更新する。 + // + // 現在位置に1文字出力 (上位バイトは属性) - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 - virtual void Putc(uint16 ch); + void Putc(uint16 ch); + + // 座標を指定して1文字出力 (上位バイトは属性) + void Putc(int x, int y, uint16 ch) { + Locate(x, y); + Putc(ch); + } + + // 座標と属性を指定して1文字出力 + void Putc(int x, int y, TA attr, uint16 ch) { + Locate(x, y); + Putc((uint)attr | ch); + } // 現在位置に文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Puts(const char *str); // 現在位置に指定の属性で文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Puts(TA attr, const char *str); // 座標を指定して文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Puts(int x, int y, const char *str) { Locate(x, y); Puts(str); } // 座標と属性を指定して、文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Puts(int x, int y, TA attr, const char *str) { Locate(x, y); Puts(attr, str); } // 現在位置に属性なしで書式付き文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Print(const char *fmt, ...) __printflike(2, 3); // 座標を指定して属性なしで書式付き文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Print(int x, int y, const char *fmt, ...) __printflike(4, 5); // 座標と属性を指定して、書式付き文字列を出力 - // 出力後カーソルは移動する。移動後画面からはみ出しても何もしない。 void Print(int x, int y, TA attr, const char *fmt, ...) __printflike(5, 6); - // バッファアドレスを取得。(描画デバイス向け) - const uint16 *GetBuf() const { return textbuf.get(); } + // 現在のカーソル位置の文字を取得 + // カーソルは移動しない。 + uint16 Getc(); + + // 現在のカーソル位置に文字を出力。 + // カーソルは移動しない。ch がカーソル移動を伴う制御文字なら動作不定。 + void Setc(uint16 ch); + + // 指定のカーソル位置に文字を出力。 + // カーソルは移動しない。ch がカーソル移動を伴う制御文字なら動作不定。 + void Setc(int x, int y, uint16 ch); + + // 現在位置の属性を取得 + TA GetAttr() const; + + // 現在位置の属性を attr に設定 + // カーソルは移動しない。 + void SetAttr(TA attr); - // XXX 生バッファを取得 - // バッファの内部構造を変えた場合はこれを呼んでる人については - // 見直しをすること。そのうちなんとかするかも - uint16 *GetRawBuf() { return textbuf.get(); } + // バッファを取得。(描画デバイス向け) + const std::vector& GetBuf() const { return textbuf; } // 現在の X 座標を取得 - int GetX() const { return X; } + int GetX() const noexcept { return X; } // 現在の Y 座標を取得 - int GetY() const { return Y; } + int GetY() const noexcept { return Y; } // 桁数を取得 - int GetCol() const { return col; } + int GetCol() const noexcept { return col; } // 行数を取得 - int GetRow() const { return row; } + int GetRow() const noexcept { return row; } + + // 行単位のコピー + void CopyRowsFrom(int dst_y, int row, const TextScreen& src, int src_y); // ユーザ定義の引数 // ご自由にお使いください。例えばモニタの出力開始オフセットやアドレス @@ -132,10 +223,10 @@ class TextScreen // ような用途。 uint64 userdata {}; - protected: + private: // バッファ (幅x高さちょうどの長さ、ゼロ終端文字列ではない) // 上位8ビットは属性、下位8ビットが文字コード。 - std::unique_ptr textbuf {}; + std::vector textbuf {}; // 幅 int col {}; @@ -148,41 +239,7 @@ class TextScreen // カーソル Y 座標 int Y {}; -}; - -// -// テキストコンソール -// -class TextConsole : public TextScreen -{ - using inherited = TextScreen; - public: - TextConsole(); - virtual ~TextConsole() override; - - // 現在位置に1文字出力 (上位バイトは属性) - // 出力後カーソルは移動する。右端で改行、下端で行スクロールが起きる。 - void Putc(uint16 ch) override; - - private: - // 改行(次の行の左端に移動) - void CRLF(); -}; - -// -// モニターインタフェース -// -// モニターされる側はこのインタフェースを実装すること。 -// -class IMonitor -{ - public: - // 自身の現在の状態を TextScreen に書き出す - virtual void MonitorUpdate(TextScreen&) = 0; - - // このモニターが必要とするサイズ(桁数×行数)を取得する - virtual nnSize GetMonitorSize() = 0; - // デストラクタ - virtual ~IMonitor() { } + // カーソルが画面外に位置するとき true + bool OutOfScreen {}; };