批处理文件 VT100 实施
Batch File VT100 implementation
当涉及到用于在屏幕上显示文本文件的批处理程序时,我正试图阻止屏幕闪烁。它必须更新,我想出的唯一方法是循环程序并清除屏幕。
这是我当前的代码。
::Begin the refresh loop
::---------------------------------------------------------------
:Refresh
type "%ud%\ChatTerminal\Msg.txt
Sleep 1
cls
Goto Refresh
:Break Refresh
::---------------------------------------------------------------
::Refresh Loop Ends
::---------------------------------------------------------------
经过一番研究,我得出了这个 post:
问题是我不知道从哪里开始实施。
VT 序列的转义字符可以使用以下方式定义:
For /F %%e in ('echo prompt $E^|cmd')Do set "\E=%%e"
根据每个 .txt 文件的格式和内容,无闪烁动画可以像在每个 'frame':
之间将光标返回到屏幕主页一样简单
<nul set /p "=%\E%[1;1H"
编辑
如果源 file/s 具有不同的行长度或行数,则需要读入每一行并添加 VT 序列 %\E%[K
以清除该行的其余部分,并且 %\E%[0J
在每个文件之后从光标位置清除控制台屏幕的其余部分。
创建动画文件的示例:
(注意:%\E%[E
发出换行符)
Anim.bat
@Echo off & CD /D "%~dp0"
For /f %%e in ('Echo Prompt $E^|cmd') Do set "\E=%%e"
<nul Set /P "=%\E%[?25l"
Set /A "delay=4", "Files=0","FC=1"
Setlocal EnableExtensions EnableDelayedExpansion
For %%i in (5 6 7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7 6 5)Do (
Set /A Files+=1
Call :CreateCube %%i "infile!Files!.txt"
)
For /L %%i in ()Do (
for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!") do set /a "t2=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100, tDiff=t2-t1"
if !tDiff! lss 0 set /a tDiff+=24*60*60*100
if !tDiff! geq !delay! (
Set /A "FC=FC %% Files + 1"
<nul Set /P "=%\E%[1;0H"
If !FC! GTR 10 (If !Offset! GTR 1 Set /A "Offset-=1")Else Set "offset=!FC!"
(For /f "Delims=" %%G in (infile!FC!.txt)Do <nul set /P "=%\E%[K%\E%[!offset!G%%G%\E%[E") > Con
<nul Set /P "=%\E%[0J"
set /a t1=t2
)
)
:CreateCube <size>
:# golfed script for outputting a shaded multi color cube
:# https://codegolf.stackexchange.com/a/224741/92319
@echo off&Cls&Set $=Set &CHCP 65001 > nul
If "%~1"=="" (Echo(%~n0 Integer Outfile.ext&Exit /B)
If "%~2"=="" (Echo(%~n0 Integer Outfile.ext&Exit /B)
(<Nul Set /p "=%\E%7")>"%~2"
%$%/A x=%1,h=x*2,z=0
%$%F=For /L %%a in (1 1 &%$%P=^<nul set/p &%$%C= If %%y LEQ %1
((%f:a=y%!h!)Do (%$%/a w=x-z
%F%!w!)Do %P%"=%\E%7 "
%F%!z!)Do%C%(%P%"=%\E%[38;2;0;120;%%a0m_|")Else %P%"=%\E%[4m%\E%[38;2;120;0;%%a0m\%\E%[0m"
%F%%1)Do%C%(%P%"=%\E%[38;2;120;0;%%a0m▲▼")Else %P%"=%\E%[38;2;0;120;%%a0m_\"
%C:EQ=SS%(%$%/A z+=1)Else%C:If=If not%%$%/A z-=1)&Echo(%\E%[0m))>"%~2"
注意:用于帧率的经过时间操作源自Dave Benhams snake.bat
强烈建议在重复的 for /l infinate 循环中实施帧率控制,以促进流畅的动画 - 否则会导致动画出现锯齿状/断断续续,因为它以眼睛无法跟随的速度出现
T3RR0R 的解决方案覆盖现有行而不删除旧行的其余部分。因此,当新行变短时,旧行的其余部分将继续显示。
这可以通过逐行写入文件,删除该行的其余部分来解决。遗憾的是,这会减慢速度并因此重新引入闪烁(至少对于多行文件)。
作为替代方案,如果文件已更改,则只写入文件。它仍然闪烁,但现在只是在文件更新时。显示文件后,取消设置 archive
属性。每当 Windows 写入文件时,它都会再次设置属性,我们用它来确定文件是否已更改。
@echo off
set "file=%ud%\ChatTerminal\Msg.txt"
:loop
attrib "%file%"|findstr /b "A" >nul && (
cls
type "%file%"
attrib "%file%" -a
)
timeout 1 >nul
goto :loop
奖励:这不使用转义码,因此它在每个 Windows 版本上运行(可能有一些已弃用的 Windows 版本没有 timeout
默认,但可以在需要时替换为 ping
)
似乎您要做的只是跟踪一个文件并将这些新行打印到屏幕上。您可以使用此方法来完成。
@echo off
call :Read <"file.txt"
GOTO :EOF
:Read
set "line="
set /p "line="
if defined line (
echo %line%
)
goto :Read
当涉及到用于在屏幕上显示文本文件的批处理程序时,我正试图阻止屏幕闪烁。它必须更新,我想出的唯一方法是循环程序并清除屏幕。
这是我当前的代码。
::Begin the refresh loop
::---------------------------------------------------------------
:Refresh
type "%ud%\ChatTerminal\Msg.txt
Sleep 1
cls
Goto Refresh
:Break Refresh
::---------------------------------------------------------------
::Refresh Loop Ends
::---------------------------------------------------------------
经过一番研究,我得出了这个 post:
问题是我不知道从哪里开始实施。
VT 序列的转义字符可以使用以下方式定义:
For /F %%e in ('echo prompt $E^|cmd')Do set "\E=%%e"
根据每个 .txt 文件的格式和内容,无闪烁动画可以像在每个 'frame':
之间将光标返回到屏幕主页一样简单<nul set /p "=%\E%[1;1H"
编辑
如果源 file/s 具有不同的行长度或行数,则需要读入每一行并添加 VT 序列 %\E%[K
以清除该行的其余部分,并且 %\E%[0J
在每个文件之后从光标位置清除控制台屏幕的其余部分。
创建动画文件的示例:
(注意:%\E%[E
发出换行符)
Anim.bat
@Echo off & CD /D "%~dp0"
For /f %%e in ('Echo Prompt $E^|cmd') Do set "\E=%%e"
<nul Set /P "=%\E%[?25l"
Set /A "delay=4", "Files=0","FC=1"
Setlocal EnableExtensions EnableDelayedExpansion
For %%i in (5 6 7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7 6 5)Do (
Set /A Files+=1
Call :CreateCube %%i "infile!Files!.txt"
)
For /L %%i in ()Do (
for /f "tokens=1-4 delims=:.," %%a in ("!time: =0!") do set /a "t2=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100, tDiff=t2-t1"
if !tDiff! lss 0 set /a tDiff+=24*60*60*100
if !tDiff! geq !delay! (
Set /A "FC=FC %% Files + 1"
<nul Set /P "=%\E%[1;0H"
If !FC! GTR 10 (If !Offset! GTR 1 Set /A "Offset-=1")Else Set "offset=!FC!"
(For /f "Delims=" %%G in (infile!FC!.txt)Do <nul set /P "=%\E%[K%\E%[!offset!G%%G%\E%[E") > Con
<nul Set /P "=%\E%[0J"
set /a t1=t2
)
)
:CreateCube <size>
:# golfed script for outputting a shaded multi color cube
:# https://codegolf.stackexchange.com/a/224741/92319
@echo off&Cls&Set $=Set &CHCP 65001 > nul
If "%~1"=="" (Echo(%~n0 Integer Outfile.ext&Exit /B)
If "%~2"=="" (Echo(%~n0 Integer Outfile.ext&Exit /B)
(<Nul Set /p "=%\E%7")>"%~2"
%$%/A x=%1,h=x*2,z=0
%$%F=For /L %%a in (1 1 &%$%P=^<nul set/p &%$%C= If %%y LEQ %1
((%f:a=y%!h!)Do (%$%/a w=x-z
%F%!w!)Do %P%"=%\E%7 "
%F%!z!)Do%C%(%P%"=%\E%[38;2;0;120;%%a0m_|")Else %P%"=%\E%[4m%\E%[38;2;120;0;%%a0m\%\E%[0m"
%F%%1)Do%C%(%P%"=%\E%[38;2;120;0;%%a0m▲▼")Else %P%"=%\E%[38;2;0;120;%%a0m_\"
%C:EQ=SS%(%$%/A z+=1)Else%C:If=If not%%$%/A z-=1)&Echo(%\E%[0m))>"%~2"
注意:用于帧率的经过时间操作源自Dave Benhams snake.bat
强烈建议在重复的 for /l infinate 循环中实施帧率控制,以促进流畅的动画 - 否则会导致动画出现锯齿状/断断续续,因为它以眼睛无法跟随的速度出现
T3RR0R 的解决方案覆盖现有行而不删除旧行的其余部分。因此,当新行变短时,旧行的其余部分将继续显示。
这可以通过逐行写入文件,删除该行的其余部分来解决。遗憾的是,这会减慢速度并因此重新引入闪烁(至少对于多行文件)。
作为替代方案,如果文件已更改,则只写入文件。它仍然闪烁,但现在只是在文件更新时。显示文件后,取消设置 archive
属性。每当 Windows 写入文件时,它都会再次设置属性,我们用它来确定文件是否已更改。
@echo off
set "file=%ud%\ChatTerminal\Msg.txt"
:loop
attrib "%file%"|findstr /b "A" >nul && (
cls
type "%file%"
attrib "%file%" -a
)
timeout 1 >nul
goto :loop
奖励:这不使用转义码,因此它在每个 Windows 版本上运行(可能有一些已弃用的 Windows 版本没有 timeout
默认,但可以在需要时替换为 ping
)
似乎您要做的只是跟踪一个文件并将这些新行打印到屏幕上。您可以使用此方法来完成。
@echo off
call :Read <"file.txt"
GOTO :EOF
:Read
set "line="
set /p "line="
if defined line (
echo %line%
)
goto :Read