Annotation of nono/lib/textscreen.cpp, revision 1.1.1.12

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.