|
|
nono 1.7.0
//
// nono
// Copyright (C) 2024 nono project
// Licensed under nono-license.txt
//
//
// メイン画面をコンソールにする
//
#pragma once
#include "device.h"
#include "keyboard.h"
#include "renderer.h"
#include <bitset>
#include <vector>
class BitmapRGBX;
class COMDriverConsole;
class ConsoleKeyboard;
class Syncer;
class ConsoleDevice : public Device
{
using inherited = Device;
static const uint fullwidth = 132; // 仮想画面幅
static const uint dispwidth = 80; // 表示画面幅
static const uint height = 24;
static const uint font_width = 8;
static const uint font_height = 16;
using bitsetH = std::bitset<height>;
// 1文字 32ビットのうち下位8ビットが文字コード、上位24ビットが各種属性。
//
//
// 3 2 1
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---------------+---------------+---------------+---------------+
// | bgcolor | fgcolor |R|L|D|O|S|U|I|B| 文字コード |
// +---------------+---------------+---------------+---------------+
//
// bgcolor, fgcolor はカラーパレット番号。
static const uint32 ATTR_BOLD = 0x0000'0100; // B: ボールド
static const uint32 ATTR_ITALIC = 0x0000'0200; // I: イタリック
static const uint32 ATTR_UNDERLINE = 0x0000'0400; // U: 下線
static const uint32 ATTR_STRIKE = 0x0000'0800; // S: 打ち消し線
static const uint32 ATTR_OVERLINE = 0x0000'1000; // O: 上線
static const uint32 ATTR_DECSG = 0x0000'2000; // D: DEC 特殊文字
static const uint32 ATTR_BLINK = 0x0000'4000; // L: 低速点滅
static const uint32 ATTR_REVERSE = 0x0000'8000; // R: 反転(暫定)
static const uint32 ATTR_LINEMASK = (ATTR_UNDERLINE |
ATTR_STRIKE |
ATTR_OVERLINE);
// フチ [pixel]
static const uint Padding = ConsoleRenderer::Padding;
public:
ConsoleDevice();
~ConsoleDevice() override;
bool Init() override;
void ResetHard(bool poweron) override;
void Attach(COMDriverConsole *);
void Detach() { Attach(NULL); }
void Putchar(uint32);
std::string ToString() const;
bool Render(BitmapRGBX& dst);
private:
void VSyncCallback(Event *);
void SetPalette(bool console_is_active);
void ResetTerminalSoft();
void ResetTerminalHard();
void ResetMargin();
void ResetScroll();
void ResetState();
void PutcharPlain(uint32);
void PutcharDebug(uint32);
bool PutcharESC(uint32);
bool PutcharCSI(uint32);
bool PutcharCSIQ(uint32);
bool PutcharSharp(uint32);
bool PutcharG0(uint32);
void Clear();
void LocateX(int x);
void LocateY(int y);
void Locate(int x, int y) {
LocateX(x);
LocateY(y);
}
void LocateXinMargin(int x);
void LocateYinScroll(int y);
void CopyLineWhole(int dst, int src);
void CopyLineMargin(int dst, int src);
void EraseLineWhole(int y);
void EraseLineMargin(int y);
// 現在位置に、現在の属性で文字 ch を出力する。出力後カーソルは移動する。
void PutcharNormal(uint32);
// (x, y) の位置に chattr を出力する。カーソルは移動しない。
void Setchar(int x, int y, uint32 chattr);
void HT();
void CR();
void LF();
// 現在位置に、現在の属性で文字 ch を出力する。出力後カーソルは移動する。
void Putc(uint32 ch);
// (x, y) の位置に chattr を出力する。カーソルは移動しない。
void Setc(int x, int y, uint32 chattr);
// 現在の属性を設定する。
void SetAttr(uint32 new_attr);
// 未実装シーケンス。
bool Unimpl(uint32 ch, const char *name = NULL);
int GetArgDefault(int defval);
int GetArg() { return GetArgDefault(0); }
int ParseArg();
// 送信。
void SendString(const std::string&);
std::string Dump() const;
std::string Dump(uint32 ch) const;
static std::string Dump(const std::vector<uint8>&);
// 画面は 1文字分が uint32 の [fullwidth * height] の配列。
std::vector<uint32> screen {};
// 仮想画面幅。(表示は80桁固定)
int width {};
// カーソル位置。
int cur_x {};
int cur_y {};
// 左右マージン。両閉区間で表す。
// 例えばデフォルトの [0, width) なら left=0, right=width-1。
int margin_left {};
int margin_right {};
// スクロール領域。両閉区間で表す。
// 例えばデフォルトの [0, height) なら top=0, btm=height-1。
int scroll_top {};
int scroll_btm {};
// 遅延折り返し。
bool wrap_pending {};
// 拡張オプション。
bool insert_mode {};
bool cr_on_lf {};
bool decom {};
bool cursor_visible {};
// DECSC で保存するパラメータ。
int save_x {};
int save_y {};
uint32 save_attr {};
bool save_wrap {};
bool save_decom {};
// VM スレッド内での行ごとの更新情報。
bitsetH dirty {};
// レンダラスレッドで未処理の行。
// VM スレッドからレンダラスレッドへの連絡用なので mtx で保護する。
bitsetH pending {};
std::mutex mtx {};
// 画面初期化。
bool init_screen {};
// 現在の状態。
char state {};
// 現在の属性。
uint32 cur_attr {};
// 行ごとに点滅文字を持っているか。
bitsetH has_blink {};
// 点滅の滅なら true。
bool blinking {};
// パレット。
// [0..1] だと通常色、[1..2] だと反転色になる。
Color palette[3] {};
// 現在の1文字前までのエスケープシーケンス。(現在の文字は ch)
std::vector<uint8> seq {};
// パラメータ部分。
std::string arg {};
// セミコロンで分解したもの。
std::vector<std::string> argv {};
// 処理中の位置。-1 なら分解前。
int argv_idx {};
// デバッグログ。
FILE *log {};
bool log_newline {};
Event *vsync_event {};
VideoRenderer *renderer {};
COMDriverConsole *comdriver {};
ConsoleKeyboard *keyboard {};
Syncer *syncer {};
static const uint8 decsg8x16[15 * font_height];
static const uint8 tofu8x16[font_height];
};
// 入力担当デバイス
class ConsoleKeyboard : public DumbKeyboard
{
using inherited = DumbKeyboard;
public:
ConsoleKeyboard();
~ConsoleKeyboard() override;
void Attach(COMDriverConsole *);
void Detach() { Attach(NULL); }
void CharInput(uint charcode) override;
void SetCKM(bool val);
private:
// 拡張オプション。
char ckm_char {};
COMDriverConsole *comdriver {};
};
inline ConsoleDevice *GetConsoleDevice() {
return Object::GetObject<ConsoleDevice>(OBJ_CONSOLE);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.