我正在尝试在控制台中创建图形引擎。我不使用任何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 *高度*宽度)
答案 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。
两个高级模式是writefile
和writeconsole
。最低级别为writeconsoleoutputcharacter
。