--- nono/vm/console.cpp 2026/04/29 17:05:36 1.1.1.2 +++ nono/vm/console.cpp 2026/04/29 17:05:54 1.1.1.5 @@ -11,6 +11,7 @@ #include "console.h" #include "bitmap.h" #include "builtinrom.h" +#include "event.h" #include "comdriver_cons.h" #include "mainapp.h" #include "scheduler.h" @@ -28,20 +29,12 @@ } \ } while (0) -// v[] がいずれかでも true なら true を返す。 -static bool -AnyOf(const std::vector& v) -{ - return std::any_of(v.begin(), v.end(), [](bool x) { return x; }); -} - // コンストラクタ ConsoleDevice::ConsoleDevice() : inherited(OBJ_CONSOLE) { screen.resize(width * height); - dirty.resize(height); - pending.resize(height); + SetPalette(false); } // デストラクタ @@ -57,7 +50,7 @@ ConsoleDevice::~ConsoleDevice() bool ConsoleDevice::Init() { - renderer = GetRenderer(); + renderer = GetVideoRenderer(); // ログファイル。 if (gMainApp.console_logfile) { @@ -68,21 +61,23 @@ ConsoleDevice::Init() } } - vsync_event.func = ToEventCallback(&ConsoleDevice::VSyncCallback); - vsync_event.time = 16666.667_usec; - vsync_event.SetName("Console V-Sync"); - scheduler->RegistEvent(vsync_event); + auto evman = GetEventManager(); + vsync_event = evman->Regist(this, + ToEventCallback(&ConsoleDevice::VSyncCallback), + "Console V-Sync"); + vsync_event->time = 16666.667_usec; return true; } // COM ドライバを接続。 -// NULL を指定すると解除。 // (HostCOM の cons ドライバが呼ぶ) void ConsoleDevice::Attach(COMDriver *comdriver_) { comdriver = comdriver_; + + SetPalette((comdriver != NULL)); } void @@ -97,30 +92,22 @@ ConsoleDevice::ResetHard(bool poweron) Locate(0, 0); } - if (comdriver) { - scheduler->RestartEvent(vsync_event); - } + scheduler->RestartEvent(vsync_event); ResetTerminal(); } void -ConsoleDevice::VSyncCallback(Event& ev) +ConsoleDevice::VSyncCallback(Event *ev) { bool update_needed; // 更新 (dirty[]) があれば pending[] に重ねる。 { - std::unique_lock lock(mtx); - for (int y = 0; y < height; y++) { - // std::vector には operator|=() がない。 - if (__predict_false(dirty[y])) { - pending[y] = true; - dirty[y] = false; - } - } - - update_needed = AnyOf(pending); + std::lock_guard lock(mtx); + pending |= dirty; + dirty.reset(); + update_needed = pending.any(); } // 更新の必要があれば Render に作画指示。 @@ -131,6 +118,27 @@ ConsoleDevice::VSyncCallback(Event& ev) scheduler->StartEvent(ev); } +// パレットの状態を変更する。 +void +ConsoleDevice::SetPalette(bool console_is_active) +{ + if (console_is_active) { + palette[0] = UD_LIGHT_GREY; // BG + palette[1] = UD_BLACK; // FG + } else { + palette[0] = UD_LIGHT_GREY; // BG + palette[1] = UD_GREY; // FG + } + // 反転色。 + palette[2] = palette[0]; + + // 画面に即反映させる。 + { + std::lock_guard lock(mtx); + pending.set(); + } +} + // 端末の状態をリセットする。 // (画面のクリアはここではしない?) void @@ -787,7 +795,7 @@ void ConsoleDevice::Clear() { std::fill(screen.begin(), screen.end(), ' ' | cur_attr); - std::fill(dirty.begin(), dirty.end(), true); + dirty.set(); } // カーソルの X 座標を移動。(画面をはみ出さないようにクリップされる) @@ -801,7 +809,7 @@ ConsoleDevice::LocateX(int x) x = width - 1; } cur_x = x; - dirty[cur_y] = true; + dirty.set(cur_y); } // カーソルの Y 座標を移動。(画面をはみ出さないようにクリップされる) @@ -814,9 +822,9 @@ ConsoleDevice::LocateY(int y) if (__predict_false(y > height - 1)) { y = height - 1; } - dirty[cur_y] = true; + dirty.set(cur_y); cur_y = y; - dirty[cur_y] = true; + dirty.set(cur_y); } // 文字出力後のカーソル移動。 @@ -824,7 +832,7 @@ void ConsoleDevice::Ascend() { cur_x++; - dirty[cur_y] = true; + dirty.set(cur_y); if (cur_x >= width) { CRLF(); } @@ -841,13 +849,13 @@ ConsoleDevice::CR() void ConsoleDevice::LF() { - dirty[cur_y] = true; + dirty.set(cur_y); cur_y++; if (cur_y >= scroll_btm) { ScrollUp(); cur_y = scroll_btm; } - dirty[cur_y] = true; + dirty.set(cur_y); } // 全画面を1行上にスクロール。(DECSTBM の影響を受ける) @@ -863,7 +871,7 @@ ConsoleDevice::ScrollUp() for (int x = 0; x < width; x++) { Setc(x, scroll_btm, ch); } - std::fill(dirty.begin(), dirty.end(), true); + dirty.set(); } // 全画面を1行下にスクロール。(DECSTBM の影響を受ける) @@ -879,7 +887,7 @@ ConsoleDevice::ScrollDown() for (int x = 0; x < width; x++) { Setc(x, scroll_top, ch); } - std::fill(dirty.begin(), dirty.end(), true); + dirty.set(); } // 現在位置に、現在の属性で文字 ch を出力する。 @@ -959,10 +967,6 @@ ConsoleDevice::SetAttr(uint32 new_attr) bool ConsoleDevice::Render(BitmapRGBX& dst) { - if (comdriver == NULL) { - return false; - } - bool updated = false; // フチも含めて再描画。 @@ -973,17 +977,17 @@ ConsoleDevice::Render(BitmapRGBX& dst) } // 行ごとに更新があるか調べる。 - std::vector modified(height); + bitsetH modified; { - std::unique_lock lock(mtx); + std::lock_guard lock(mtx); modified = pending; - std::fill(pending.begin(), pending.end(), false); + pending.reset(); } - updated |= AnyOf(modified); + updated |= modified.any(); const uint8 *cgrom8x16 = Builtin::CGROM8x16(0); for (uint y = 0; y < height; y++) { - if (__predict_false(modified[y])) { + if (__predict_false(modified.test(y))) { uint py = Padding + y * font_height; const uint32 *s = &screen[y * width]; for (uint x = 0; x < width; x++) { @@ -1298,14 +1302,6 @@ ConsoleDevice::Render(BitmapRGBX& dst) B(00010000), }; -// パレット。 -// [0] からだと通常色、[1] からだと反転色になる。 -/*static*/ const Color ConsoleDevice::palette[3] = { - UD_LIGHT_GREY, // BG - UD_BLACK, // FG - UD_LIGHT_GREY, // BG -}; - // // 入力担当デバイス @@ -1325,7 +1321,7 @@ ConsoleKeyboard::~ConsoleKeyboard() // COM ドライバを接続。 // (HostCOM の cons ドライバが呼ぶ) void -ConsoleKeyboard::Attach(COMDriverCons *comdriver_) +ConsoleKeyboard::Attach(COMDriverConsole *comdriver_) { comdriver = comdriver_; }