File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / console.h
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:06:00 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
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);
}

unix.superglobalmegacorp.com

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