dart/tty/demo_tty.dart · 12474 字节 · 下载原文
// demo_tty.dart —— **第 2 层:彩色命令行**(`tty_*`)
// demo_tty.dart — **Layer 2: colored command line** (`tty_*`)
//
// ⚠ **新程序用 `tty_*`,老程序才用 `conio` / `Crt`**(用户定的分层标准:
// ⚠ **New programs use `tty_*`; only old programs use `conio` / `Crt`** (the layering standard the user set:
// 「新版程序,文字模式用 tty 库,图像模式用 ui 库;旧版老程序才用 conio、graphics 等库」)。
// "new programs use the tty library in text mode and the ui library in graphics mode; only old programs use conio, graphics and the like").
// `tty_*` 只有字符、没有任何图形功能;要画图用 BGI 或 `ui_*`。
// `tty_*` is characters only, with no graphics capability whatsoever; to draw, use BGI or `ui_*`.
// 坐标 **1 起算**、颜色 **0–15 索引色**。
// Coordinates are **1-based**; colors are **indexed 0–15**.
//
// ## ✅ 本份**已跑通**(2026-10-04 复验)—— 下面那两处阻塞都已消除,"跑不起来"的说法作废
// ## ✅ This one **runs now** (re-checked 2026-10-04) — both blockers below are gone; the "does not run" notes are obsolete
//
// 实测:`vmlcli demo_tty.dart` → **编译完成(dart,67214 条指令)→ 运行完成**,整屏彩色面板 /
// Measured: `vmlcli demo_tty.dart` → **compile complete (dart, 67214 instructions) → run complete**; the whole
// 单线框 / 16 色色带 / `tty_put_int` 都按 `demo_tty.java` 的版面画了出来(画完即退出,不等按键)。
// colored panel / single-line box / 16-color bar / `tty_put_int` are drawn per `demo_tty.java`'s layout (draws and exits, no key wait).
//
// ~~① **`Libs=` 里没有 `tty.vml`** —— 曾经成立,但只解释得了 Java / C# / Swift 那三份;Dart 这两份不是这个原因。~~
// ~~① **`tty.vml` is not in `Libs=`** — this once held, but it only explained the Java / C# / Swift copies;
// the two Dart copies were not for that reason.~~
// ✅ **已消除**:`vmltool.config.xml` 现在**每一门**的 `Libs=` 都带 `tty.vml`(dart / java / csharp / swift / kotlin / d 全是 `…,tty.vml,…`)。
// ✅ **Gone**: every language's `Libs=` in `vmltool.config.xml` now carries `tty.vml` (dart / java / csharp / swift / kotlin / d all read `…,tty.vml,…`).
//
// ~~② **`--lib` 与 `Libs=` 对 Dart 根本不生效** —— 真因不是"拿不到 `--lib`"。~~
// ~~② **`--lib` and `Libs=` had no effect for Dart** — the real cause was not a missing `--lib`.~~
// (当年 `DartCompiler.Compile` 里先自己调了一次 `LinkStandardLibrary(prog, "dart", null)`(库清单是 **null**):
// (back then `DartCompiler.Compile` first called `LinkStandardLibrary(prog, "dart", null)` itself (a null library list):
// `tty_*` 当场被判「未定义的函数」硬错误抛出,后面那次带着真清单的链接根本没机会跑。)
// `tty_*` was judged "undefined function" and thrown as a hard error, so the later link with the real list never ran.)
// ✅ **已消除**:`DartCompiler.Compile` 现在**不再预链接**(注释写着「不在这里链接标准库」),
// ✅ **Gone**: `DartCompiler.Compile` no longer pre-links (its comment now reads "do not link the standard library here"),
// 与 Java / C# / C / C++ 同一条约定("LinkStandardLibrary 由调用方统一处理")。
// the same convention as Java / C# / C / C++ ("handled uniformly by the caller").
//
// 历史(2026-09-24 量的,留档):卡点是**更早的一步** —— `DartCompiler.cs:34` 那次预链接只认
// History (measured 2026-09-24, kept for the record): the blocker was an **earlier step** — that pre-link in
// `builtins.vml` + `SharedPrefixMap` 自动探测(`ui_` → vmlui,所以 `demo_ui` 能跑);对照
// `DartCompiler.cs:34` only knew `builtins.vml` + `SharedPrefixMap` (`ui_` → vmlui, which is why `demo_ui` ran);
// `JavaCompiler.cs:37` / `CSharpCompiler.cs:38` **不做**这次预链接。最小复现(两步都跑过):
// by contrast `JavaCompiler.cs:37` / `CSharpCompiler.cs:38` did **not** pre-link. Minimal reproduction (both run):
//
// // K2.java(同形,对照用)
// class K2 { static native int tty_init(int w,int h,int c);
// public static void main(String[] a){ tty_init(80,25,1); } }
// $ vmlcli Examples/java/K2.java
// → ✔ 编译完成(java,59338 条指令) // 不需要 --lib
// → ✔ compile complete (java, 59338 instructions) // no --lib needed
//
// ⚠ 与「`LIB.vml` 有没有挂上」**无关**:`tty.vml` 自提交 9b5e1aa7 起已在 22 门语言的 `Libs=` 里。
// ⚠ This was **unrelated** to whether `LIB.vml` is hooked up: since commit 9b5e1aa7 `tty.vml` has been in all 22 languages' `Libs=`.
// 修法(`tty.vml` 进 `Libs=` + 去掉那次预链接)**已落地**,本份例程无需代改。
// The fix (`tty.vml` into `Libs=` plus removing that pre-link) **has landed**; this example needed no change.
//
// ## 本文件的状态:**已跑通**(2026-10-04)
// ## Status of this file: **verified running** (2026-10-04)
//
// · 版面与调用串与 `Examples/java/demo_tty.java`(已跑通出画面)**逐句同构**。
// · The layout and the call sequences are **sentence-for-sentence isomorphic** to `Examples/java/demo_tty.java` (which already runs and draws).
// · 实测编译 67214 条指令、正常结束(画完即退出,不等按键)。
// · Measured: compiles to 67214 instructions and terminates normally (draws and exits, no key wait).
//
// ## ⚠ Dart 前端的写法约束(见 demo_std.dart 的文件头)
// ## ⚠ Style constraints of the Dart frontend (see the header of demo_std.dart)
//
// · 调库函数的声明由顶部 `import 'vml_ui.dart';` 提供(该文件由 `tools/GenLib` 产出,勿手改);
// · Declarations come from the top-of-file `import 'vml_ui.dart';` (generated by `tools/GenLib`; do not hand-edit);
// · **没有 `println`**(`func_println` 不在链接进来的库里);
// · **There is no `println`** (`func_println` is not in the linked libraries);
// · 字符串拼接 `+` 与 `.toString()` **2026-10-01 起可用了**(此前会编成整数加法 / 报未定义函数);
// · String concatenation `+` and `.toString()` **work since 2026-10-01** (previously they compiled to integer addition / an undefined function).
// (✅ 2026-10-04 复验仍成立:`"AB" + "CD"` 在 trace 里落成 `str="ABCD"`;`"n=" + n.toString()` 落成 `str="n=42"`。)
// (✅ Re-checked 2026-10-04, still true: `"AB" + "CD"` traces as `str="ABCD"`; `"n=" + n.toString()` traces as `str="n=42"`.)
//
// ## ⚠ UTF-8 的字节预算
// ## ⚠ The UTF-8 byte budget
//
// `conio.c` 的 `putch()` 把**字节**当**列**计数(到 80 折行),一个汉字/框线字符 3 字节
// `putch()` in `conio.c` counts **bytes** as **columns** (wrapping at 80), and one Chinese character / box-drawing char is 3 bytes
// ⇒ 某段连续输出跨过第 80 列时折行落在字符中间,宿主按字节重组 UTF-8 的校验随即失败
// ⇒ when a continuous run of output crosses column 80 the wrap lands mid-character, the host's byte-wise UTF-8 reassembly check then fails
// 并**粘性**切成单字节老编码 ⇒ 之后整份输出全乱。版面遵守「起始列 + 3×字符数 ≤ 80」。
// and **stickily** switches to a single-byte legacy encoding ⇒ everything after that is garbled. The layout obeys "start column + 3×chars ≤ 80".
// 细节与最小复现见 `Examples/c/demo_tty.c` 文件头。
// For details and a minimal reproduction see the header of `Examples/c/demo_tty.c`.
// 在第 (x,y) 处用指定前景/背景打一串
// Print a string at (x,y) with the given foreground/background
#include "../../../Lib/dart/vml_ui.dart"
import 'vml_ui.dart'; // UI library declarations (generated by GenLib, do not hand-edit)
void say(int x, int y, int fg, int bg, String s) {
tty_print_at(x, y, s, fg, bg);
}
void main() {
int i = 0;
// 界面语言:开局查一次(`ui_scr_get_language` 是 syscall,别每处都调)
// UI language: queried once at start (`ui_scr_get_language` is a syscall, do not call it everywhere)
int lang = ui_scr_get_language();
// ── 1. 初始化 + 清屏 ──
// ── 1. Init + clear screen ──
tty_init(0, 0, 0);
tty_cls();
// ── 2. 标题栏:亮黄字 + 蓝底,铺满第 1 行 ──
// ── 2. Title bar: bright yellow on blue, filling row 1 ──
tty_color(14, 1);
tty_goto(1, 1);
tty_puts(" ");
tty_goto(3, 1);
tty_puts("Dolaima tty_* demo (Dart) -- color / cursor / box / int");
tty_color(8, 0);
tty_goto(3, 2);
tty_puts("tty.h: tty_init / tty_cls / tty_color / tty_goto / tty_box / tty_put_int");
// ── 3. ASCII 面板(61 列,安全)──
// ── 3. ASCII panel (61 columns, safe) ──
tty_color(7, 0);
tty_box(2, 3, 62, 12, 0); // style 0 = ASCII(`+ - |`)
// 面板里的内容:每行一种前景色
// Panel contents: one foreground color per line
say(4, 4, 7, 0, lang == 0 ? "color 7 lightgray 普通正文" : "color 7 lightgray body text");
say(4, 5, 11, 0, lang == 0 ? "color 11 lightcyan 次要信息" : "color 11 lightcyan secondary");
say(4, 6, 10, 0, lang == 0 ? "color 10 lightgreen ok / 成功" : "color 10 lightgreen ok / success");
say(4, 7, 14, 0, lang == 0 ? "color 14 yellow 状态栏高亮" : "color 14 yellow status bar");
say(4, 8, 12, 0, lang == 0 ? "color 12 lightred 错误 / 警告" : "color 12 lightred error / warn");
say(4, 9, 13, 0, lang == 0 ? "color 13 lightmagenta 强调" : "color 13 lightmagenta emphasis");
// 反白一行("选中项"的长相):黑字白底
// Reverse-video one line (what a "selected item" looks like): black on white
say(4, 11, 0, 7, " > Open (reversed: fg=0 bg=7) ");
// ── 4. UTF-8 单线框(19 格宽 × 3 字节 = 57,从第 4 列起 ⇒ 61 字节,安全)──
// ── 4. UTF-8 single-line frame (19 cells wide × 3 bytes = 57, starting at column 4 ⇒ 61 bytes, safe) ──
tty_color(11, 0);
tty_box(4, 14, 22, 19, 1); // style 1 = ┌ ─ │ ┐ └ ┘ 单线框
// style 1 = single-line box ┌ ─ │ ┐ └ ┘
say(6, 16, 14, 0, lang == 0 ? "中文也" : "CJK too");
say(6, 17, 10, 0, lang == 0 ? "没问题" : "works");
// ── 5. 右侧说明(ASCII,列 26 起)──
// ── 5. Right-hand notes (ASCII, starting at column 26) ──
say(26, 14, 11, 0, "tty_box(..., style=1)");
say(26, 15, 7, 0, " = UTF-8 single-line box");
say(26, 17, 11, 0, "tty_box(..., style=0)");
say(26, 18, 7, 0, " = ASCII box (used above)");
// ── 6. 16 色色带 ──
// ── 6. 16-color bar ──
i = 0;
while (i < 16) {
tty_color(0, i);
tty_goto(3 + i * 4, 21);
tty_puts(" ");
i = i + 1;
}
tty_color(7, 0);
tty_goto(3, 22);
tty_puts("index 0..15: black blue green cyan red magenta brown gray / +8 = bright");
// ── 7. 数字与光标 ──
// ── 7. Numbers and the cursor ──
tty_color(11, 0);
tty_goto(3, 24);
tty_puts("tty_put_int: ");
tty_color(14, 0);
tty_put_int(2026);
tty_color(11, 0);
tty_puts(" / ");
tty_color(14, 0);
tty_put_int(-42);
tty_color(11, 0);
tty_puts(" cursor=");
tty_put_int(tty_wherex());
tty_puts(",");
tty_put_int(tty_wherey());
tty_puts(" screen=");
tty_put_int(tty_width());
tty_puts("x");
tty_put_int(tty_height());
// ── 8. 状态栏 + 收尾 ──
// ── 8. Status bar + wrap-up ──
tty_color(0, 3);
tty_goto(1, 24);
tty_puts(" tty_* demo done -- no key wait, exits by itself ");
tty_color(8, 0);
tty_goto(3, 25);
tty_puts(lang == 0 ? "demo_tty (Dart) 结束 —— 画完即退出" : "demo_tty (Dart) done -- draws and exits");
tty_color(7, 0);
}