有没有办法使用低电平输出来输出ANSI转义序列?

时间:2019-04-07 16:01:53

标签: c windows cmd system-calls ansi-escape

我正在尝试在控制台中创建图形引擎。我不使用任何GL,但希望很快就可以开始使用。它是用C语言编写的,到目前为止,它能够在颜色中构建半3D环境,但是我发现win cmd使用ANSI转义序列支持True配色方案。

在对这个主题的研究中,我发现WriteFile(),所有printfs和putcs都基于Win10。但是对于所有商品,它仍然不能提供缓慢的速度。如内部代码所示,writefile本质上是基于以下代码的:

NtWriteFile:

mov r10,rcx 
mov eax,8 
test byte ptr [7FFE0308h],1 
jne NtWriteFile+15h (07FFBA80CAAA5h) 
syscall                                 
ret

这很好,但速度慢且效率低下。 我的意思是:我将控制台的输出句柄传递给WriteFile()和缓冲区,但是对于160 * 60的屏幕(考虑到每个字符都有自己的ESC [48; 2; r; g; bm,长度为20个字节),我们得到192000个字节。系统调用的执行时间为 84ms

然后,我使用WriteConsoleOutputW()返回到之前的设置。它使用与控制台相同的输出ptr,但是这次使用320 * 84的缓冲区(它使用CHAR_INFO ptr作为缓冲区,因此每个缓冲区4个字节)-107 520字节,仅持续 1ms

WriteConsoleOutputW()基于相似的系统调用代码:

NtDeviceIoControlFile:

mov r10,rcx 
mov eax,7                           ; notice here is the 7 instead of 8 
test byte ptr [7FFE0308h],1 
jne NtDeviceIoControlFile+15h (07FFBA80CAAA5h) 
syscall                                 
ret

但是这一次它输出的信息量差不多快80倍!我的假设是,它只是重新分配一个指向控制台缓冲区的指针,因为当我用单个字符的缓冲区启动它时,它会输出一些带有颜色的奇怪符号

我尝试将ESC序列输出为CHAR_INFO,但将其输出为文本。所以问题是:我可以使用WriteConsoleOutput或NtDeviceIoControlFile()

以某种方式输出转义序列

此外:我的帧缓冲区将仅由转义序列和其后的空格组成。缓冲区的宽度和高度以及一个矩形已定义,我要做的就是在每个空格上输出正确的前景色。(因此长度将为20 *高度*宽度)

1 个答案:

答案 0 :(得分:0)

CMD是VT100仿真器(该信息来自Telnet服务器应用程序帮助)。

我不确定您为什么一直在谈论ANSI和该功能没有功能。

除最新版本的Windows 10外,不支持

ANSI。

不使用ANSI的人使用SetConsoleTextAttribute(表示颜色)。还有其他移动光标的功能。

    Dim hOut as IntPtr
    Dim Ret as Integer
    hOut  = GetStdHandle(STD_OUTPUT_HANDLE)
    Ret = SetConsoleTextAttribute(hOut,  &hfA)
    Console.Out.Write("*")
    Ret = SetConsoleTextAttribute(hOut, &hfC)
    Console.Out.Write("WARNING")
    Ret = SetConsoleTextAttribute(hOut, &hfA)
    Console.Out.Write("*" & vbcrlf)

要移动光标,请使用

Pos.X = CInt(Xpos)
Pos.Y= CInt(Ypos)
Ret = SetConsoleCursorPosition(hOut,  Pos)

writefile(有三种写方法)的行为由SetConsoleMode(也可以打开ANSI)控制。参见https://docs.microsoft.com/en-us/windows/console/setconsolemode

两个高级模式是writefilewriteconsole。最低级别为writeconsoleoutputcharacter