有没有办法使用低电平输出来输出ANSI转义序列? [英] Is there a way to output ANSI escape sequences using low level output?

查看:143
本文介绍了有没有办法使用低电平输出来输出ANSI转义序列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a graphical engine in console. I don't use any of the GLs, but soon hoping to start. It is written in C and as for now, it is capable of building semi-3D environment in color, but I found, that win cmd supports True color scheme, using ANSI escape sequences.

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

Throughout my research on this topic I've found WriteFile(), on which all the printfs and putcs are based in Win10. But for all goods it does not provide it is still slow. As internal code shows, writefile is essentially based on this code:

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

it is good, but slow and inefficient. What do I mean: I'm passing output handle of my console to WriteFile() and the buffer, but for the screen of 160*60 (considering every character has its own ESC[48;2;r;g;bm, which is 20 bytes long) we get 192000 bytes. The system call has 84ms of execution.

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

Then I returned to my previous setup with WriteConsoleOutputW(). It uses the same output ptr of the console, but this time for the buffer of 320*84 (it uses CHAR_INFO ptr as a buffer, so 4 bytes each)-107 520 bytes it lasts only 1ms!

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

WriteConsoleOutputW() is based on similar looking syscall code:

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倍!我的假设是,它只是重新分配一个指向控制台缓冲区的指针,因为当我用单个字符的缓冲区启动它时,它会输出一些带有颜色的奇怪符号

but this time it outputs roughly similar amounts of info 80 times faster! My assumption, that it's just reallocating a pointer to console buffer, because when I start it with buffer of single character it outputs some strange symbols with colors

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

I've tried to output ESC sequences as a CHAR_INFO but it outputs them as a text. So the question is: Can I somehow output an escape sequence using WriteConsoleOutput or NtDeviceIoControlFile()

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

In Addition: my frame buffer will consist only of escape sequences and space symbol after it. The Width and Height of the buffer, as well as a rectangle is defined, all I need to do is output correct foreground colors on each of spaces.(so the length will be 20 * Height*Width)

推荐答案

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

CMD is a VT100 emulator (that information is from the Telnet server app help).

我不确定为什么您会继续谈论ANSI和该功能没有功能。

I'm not sure why you keep talking about ANSI and the function not having features.

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

ANSI is not supported except for very recent versions of Windows 10.

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

Not using ANSI one uses SetConsoleTextAttribute (which means colour). And there are other functions to move the cursor.

    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 控制。 code>(也可以打开ANSI)。请参见 https://docs.microsoft.com/en-us/windows/console / setconsolemode

The behaviour of writefile (and there are three ways to write) is controlled by SetConsoleMode (which also can turn ANSI on). See https://docs.microsoft.com/en-us/windows/console/setconsolemode.

两个高级模式是 writefile writeconsole 。最低级别是 writeconsoleoutputcharacter

The two high level modes are writefile and writeconsole. The low level is writeconsoleoutputcharacter.

这篇关于有没有办法使用低电平输出来输出ANSI转义序列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆