Your code is beautiful!!! It works so much better than mine! Excellent work, Jeb! Thank you for sharing!
I replied to your other post as well!
viewtopic.php?p=56404#p56404
Moderator: DosItHelp
Your code is beautiful!!! It works so much better than mine! Excellent work, Jeb! Thank you for sharing!
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :init
:: set up colortables
set "colorTable1="0;0;0","0;255;0","255;255;255","128;196;0","196;196;196""
set "colorTable2="0;0;0","255;0;0","255;255;255","255;140;64","196;196;196""
set "colorTable3="0;0;0","0;0;255","255;255;255","0;128;196","196;196;196""
set "loadColors(table)=set "i=0" & for %%a in (!table!) do (set "c!i!=%%~a" & set /a "i+=1")"
setlocal enableDelayedExpansion
mode con cols=100 lines=52
color 17
cls
:: render sprite with different colortables
%loadColors(table):table=colorTable1%
<nul set /p "=%setCursor(x;y):x;y=5;9%%sprite%"
%loadColors(table):table=colorTable2%
<nul set /p "=%setCursor(x;y):x;y=15;29%%sprite%"
%loadColors(table):table=colorTable3%
<nul set /p "=%setCursor(x;y):x;y=25;49%%sprite%"
<nul set /p "=%setCursor(x;y):x;y=50;1%"
%statement%
endlocal
pause
goto :eof
:init
::setup escape
for /F %%a in ('echo prompt $E^| cmd') do set "ESC=%%a"
::setup escape codes
set "saveCursor()=%ESC%[s"
set "unsaveCursor()=%ESC%[u"
set "restoreCursor()=%ESC%[8"
set "setCursor(x;y)=%ESC%[x;yf"
set "up(x)=%ESC%[xA"
set "down(x)=%ESC%[xB"
set "left(x)=%ESC%[xD"
set "right(x)=%ESC%[xC"
set "setColor(r;g;b)=%ESC%[38;2;r;g;bm"
set "resetAttributes()=%ESC%[0m"
::setup artwork
:: artwork also contains an image mask with " " := "not painted"
:: artwork pixels := " XG.@-"
set /a "artwork.lastRow=21, artwork.lastColumns=43"
:: 1 2 3 4
:: 01234567890123456789012345678901234567890123
set "artwork[0]= XXXXXXXX "
set "artwork[1]= XXXXGGGGGGGGXXXX "
set "artwork[2]= XXXXGGGGGGGGGGGGGGGGXXXX "
set "artwork[3]= XXGGXXGGGGGGGGGG....GGXXGGXX "
set "artwork[4]= XXGGGGGGXXGGGGGGGGGGGGXXGGGGGGXX "
set "artwork[5]= XXGGGGGG@@XXXXXXXXXXXXGGGGGGGGXX "
set "artwork[6]= XXGGGGGGGGXX@@@@@@@@GGGGXXGGGGGGGGXX "
set "artwork[7]= XXGGGGGGXX@@@@@@@@@@GGGGGGXXGGGGGGXX "
set "artwork[8]= XXGGGGXX@@@@@@@@@@@@GGGGGG@@XXGGGGXX "
set "artwork[9]= XXGGGGXX@@GG@@@@@@@@@@GGGGGGGG@@XXGGGGXX "
set "artwork[10]= XXGGXXGGXXGGGG@@@@@@GGGGGGGGGGXXGGXXGGXX "
set "artwork[11]= XXXX@@@@GGXXGGGGGGGGGGGGGGGGXXGG@@@@XXXX "
set "artwork[12]=XXXXGGGGGGGGGGXXGGGGGGGGGGGGXXGGGGGGGGGGXXXX"
set "artwork[13]=XX..XXGGGGGGGGGGXXXXXXXXXXXX@@GGGGGGGGXX..XX"
set "artwork[14]=XX..XXGGGGGGGGXXGGGGGGGGGGGGXXGGGGGGGGXX..XX"
set "artwork[15]=XX--..XXXXGGXXGGGGGGGGGGGGGGGGXXGGXXXX..--XX"
set "artwork[16]= XX......XXXXGGGGGGGGGGGGGGGGXXXX......XX "
set "artwork[17]= XX--........XXXXXXXXXXXXXXXX........--XX "
set "artwork[18]= XX----........................----XX "
set "artwork[19]= XXXX----................----XXXX "
set "artwork[20]= XXXX----------------XXXX "
set "artwork[21]= XXXXXXXXXXXXXXXX "
:: compute sprite out of artwork
setlocal enableDelayedExpansion
rem set "ESC=^!ESC^!"
set "sprite=%saveCursor()%"
set /A "space=0"
set "lastChar= "
for /l %%r in (0, 1, %artwork.lastRow%) do (
for /l %%c in (0, 1, %artwork.lastColumns%) do (
for %%a in ("!artwork[%%~r]:~%%~c,1!") do (
if "!lastChar!" == "%%~a" (
if "%%~a" == " " ( set /a "space+=1"
) else ( set "sprite=!sprite!Û"
)
) else (
if "!lastChar!" == " " (
if !space! LSS 0 ( set "sprite=!sprite!%left(x):x=!space:~1!%"
) else if !space GTR 0 ( set "sprite=!sprite!%right(x):x=!space!%"
)
) else (
if "%%~a" == " " (
set "space=1"
if defined lastChar set "sprite=!sprite!%resetAttributes()%"
) else (
set "sprite=!sprite!%resetAttributes()%"
)
)
if "%%~a" == "X" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c0^!%Û"
) else if "%%~a" == "G" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c1^!%Û"
) else if "%%~a" == "." ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c2^!%Û"
) else if "%%~a" == "@" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c3^!%Û"
) else if "%%~a" == "-" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c4^!%Û"
)
)
set "lastChar=%%~a"
)
)
if not "!lastChar!" == " " (
set "sprite=!sprite!%resetAttributes()%"
set "lastChar= "
set "space=0"
)
if not "%%~r" == "%artwork.lastRow%" (
set "sprite=!sprite!%down(x):x=1%"
)
set /a "space-=(artwork.lastColumns+1)"
)
endlocal & set "sprite=%sprite%%restoreCursor()%%unsaveCursor()%"
goto :eof
Code: Select all
@echo off
setlocal enableExtensions disableDelayedExpansion
call :init
:: set up colortables
set "colorTable1="0;0;0","0;255;0","255;0;0","128;196;0","255;222;173","139;69;19""
set "colorTable2="0;0;0","255;0;0","0;0;255","255;140;64","255;222;173","139;69;19""
set "colorTable3="0;0;0","0;0;255","0;255;0","0;128;196","255;222;173","139;69;19""
set "loadColors(table)=set "i=0" & for %%a in (!table!) do (set "c!i!=%%~a" & set /a "i+=1")"
setlocal enableDelayedExpansion
mode con cols=100 lines=52
color 17
cls
timeout /t 5
:: render sprite with different colortables
set x=19
for /l %%b in (1,1,300) do (
set /a "a+=1", "b=a %% 5"
if !b! equ 0 set /a "x+=1"
%loadColors(table):table=colorTable1%
set "screen=!screen!!ESC![5;19H%sprite%"
%loadColors(table):table=colorTable2%
set "screen=!screen!!ESC![15;!x!H%sprite%"
<nul set /p "=!esc![2J!screen!" & <nul set /p "=!screen!" & set "screen="
%loadColors(table):table=colorTable3%
<nul set /p "=%ESC%[25;49f%sprite%"
)
<nul set /p "=%setCursor(x;y):x;y=50;1%"
endlocal
pause
goto :eof
:init
::setup escape
for /F %%a in ('echo prompt $E^| cmd') do set "ESC=%%a"
::setup escape codes
set "saveCursor()=%ESC%[s"
set "unsaveCursor()=%ESC%[u"
set "restoreCursor()=%ESC%[8"
set "setCursor(x;y)=%ESC%[x;yf"
set "up(x)=%ESC%[xA"
set "down(x)=%ESC%[xB"
set "left(x)=%ESC%[xD"
set "right(x)=%ESC%[xC"
set "setColor(r;g;b)=%ESC%[38;2;r;g;bm"
set "resetAttributes()=%ESC%[0m"
::setup artwork
:: artwork also contains an image mask with " " := "not painted"
:: artwork pixels := " XG.@-"
set /a "artwork.lastRow=16, artwork.lastColumns=11"
:: 1 2 3 4
REM :: 01234567890123456789012345678901234567890123
REM set "artwork[0]= XXXXXXXX "
REM set "artwork[1]= XXXXGGGGGGGGXXXX "
REM set "artwork[2]= XXXXGGGGGGGGGGGGGGGGXXXX "
REM set "artwork[3]= XXGGXXGGGGGGGGGG....GGXXGGXX "
REM set "artwork[4]= XXGGGGGGXXGGGGGGGGGGGGXXGGGGGGXX "
REM set "artwork[5]= XXGGGGGG@@XXXXXXXXXXXXGGGGGGGGXX "
REM set "artwork[6]= XXGGGGGGGGXX@@@@@@@@GGGGXXGGGGGGGGXX "
REM set "artwork[7]= XXGGGGGGXX@@@@@@@@@@GGGGGGXXGGGGGGXX "
REM set "artwork[8]= XXGGGGXX@@@@@@@@@@@@GGGGGG@@XXGGGGXX "
REM set "artwork[9]= XXGGGGXX@@GG@@@@@@@@@@GGGGGGGG@@XXGGGGXX "
REM set "artwork[10]= XXGGXXGGXXGGGG@@@@@@GGGGGGGGGGXXGGXXGGXX "
REM set "artwork[11]= XXXX@@@@GGXXGGGGGGGGGGGGGGGGXXGG@@@@XXXX "
REM set "artwork[12]=XXXXGGGGGGGGGGXXGGGGGGGGGGGGXXGGGGGGGGGGXXXX"
REM set "artwork[13]=XX..XXGGGGGGGGGGXXXXXXXXXXXX@@GGGGGGGGXX..XX"
REM set "artwork[14]=XX..XXGGGGGGGGXXGGGGGGGGGGGGXXGGGGGGGGXX..XX"
REM set "artwork[15]=XX--..XXXXGGXXGGGGGGGGGGGGGGGGXXGGXXXX..--XX"
REM set "artwork[16]= XX......XXXXGGGGGGGGGGGGGGGGXXXX......XX "
REM set "artwork[17]= XX--........XXXXXXXXXXXXXXXX........--XX "
REM set "artwork[18]= XX----........................----XX "
REM set "artwork[19]= XXXX----................----XXXX "
REM set "artwork[20]= XXXX----------------XXXX "
REM set "artwork[21]= XXXXXXXXXXXXXXXX "
set "artwork[1]= GGGGG "
set "artwork[2]= GGGGGGGGG "
set "artwork[3]= EEE--X- "
set "artwork[4]= E-E---X-- "
set "artwork[5]= E-EE---X---"
set "artwork[6]= EE----XXXX "
set "artwork[7]= ------- "
set "artwork[8]= GG.GGG "
set "artwork[9]= GGG.GG.GGG "
set "artwork[10]=GGGG....GGGG"
set "artwork[11]=--G.@..@.G--"
set "artwork[12]=---......---"
set "artwork[13]=--........--"
set "artwork[14]= ... ... "
set "artwork[15]= EEE EEE "
set "artwork[16]=EEEE EEEE"
:: compute sprite out of artwork
setlocal enableDelayedExpansion
rem set "ESC=^!ESC^!"
set "sprite=%saveCursor()%"
set /A "space=0"
set "lastChar= "
for /l %%r in (0, 1, %artwork.lastRow%) do (
for /l %%c in (0, 1, %artwork.lastColumns%) do (
for %%a in ("!artwork[%%~r]:~%%~c,1!") do (
if "!lastChar!" == "%%~a" (
if "%%~a" == " " ( set /a "space+=1"
) else ( set "sprite=!sprite!Û"
)
) else (
if "!lastChar!" == " " (
if !space! LSS 0 ( set "sprite=!sprite!%left(x):x=!space:~1!%"
) else if !space! GTR 0 ( set "sprite=!sprite!%right(x):x=!space!%"
)
) else (
if "%%~a" == " " (
set "space=1"
if defined lastChar set "sprite=!sprite!%resetAttributes()%"
) else (
set "sprite=!sprite!%resetAttributes()%"
)
)
if "%%~a" == "X" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c0^!%Û"
) else if "%%~a" == "G" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c1^!%Û"
) else if "%%~a" == "." ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c2^!%Û"
) else if "%%~a" == "@" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c3^!%Û"
) else if "%%~a" == "-" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c4^!%Û"
) else if "%%~a" == "E" ( set "sprite=!sprite!%setColor(r;g;b):r;g;b=^!c5^!%Û"
)
)
set "lastChar=%%~a"
)
)
if not "!lastChar!" == " " (
set "sprite=!sprite!%resetAttributes()%"
set "lastChar= "
set "space=0"
)
if not "%%~r" == "%artwork.lastRow%" (
set "sprite=!sprite!%down(x):x=1%"
)
set /a "space-=(artwork.lastColumns+1)"
)
endlocal & set "sprite=%sprite%%restoreCursor()%%unsaveCursor()%"
goto :eof
Hi Jeb,jeb wrote: ↑16 Apr 2018 09:46Hi,
I played a bit with your code.
I tried to optimize the display function, I precompute all escape sequences before the display function is called.
I used the tip of Dave to use certutil.
This should be fast enough for a game.
Only the RGB-converting time is slow (takes 7seconds on my pc)
Now the functions take arguments for the ppm file and for the output picture array.
Code: Select all
@echo off & setlocal enableDelayedExpansion REM INIT for /F %%a in ('echo prompt $E^| cmd') do set "ESC=%%a" REM *** bytesPerLine must be a multiple of 6, and bytesPerLine*20 must be less then 8191 set bytesPerLine=402 REM *** Clear Screen <nul set /p ".=%ESC%[2J" set t1=!time! call :readImage "pinkFloyd.ppm" set t2=!time! call :RGB24bitTo8bit pinkFloyd set t3=!time! REM *** Draw the image and move the start line between 0 to 6 set "dir=1" set /a "offset=0" for /L %%n in (1 1 100) do ( if defined dir ( set /a offset+=1 if !offset! GEQ 6 ( set "dir=" ) ) else ( set /a offset-=1 if !offset! EQU 0 ( set "dir=1" ) ) call :display pinkFloyd !offset! ) echo( echo time1=!t1! echo time2=!t2! echo time3=!t3! echo time4=!time! exit /b :readImage REM Parse height and width from PPM, and obtain headerSize set "image=%~1" for %%a in (%image%) do set "imageFileSize=%%~za" if exist %image% ( if /i "%image:~-3%" equ "ppm" ( for /f "tokens=*" %%a in (%image%) do ( set "str=X%%~a" & set "length=0" for /l %%b in (5,-1,0) do ( set /a "length|=1<<%%b" for /f "tokens=*" %%c in ("!length!") do if "!str:~%%c,1!" equ "" set /a "length&=~1<<%%b" ) set /a "headerSize+=length + 1" if !i! equ 1 for /f "tokens=1,2" %%b in ("%%a") do ( set "o=%%b" if "!o:~0,1!" neq "#" set /a "width=%%b", "height=%%c" ) if !i! equ 2 goto :break set /a "i+=1" )) else ( echo Format not supported & timeout /t 2 > nul & exit ) ) else ( echo File not found & timeout /t 2 > nul & exit ) :break REM Parse all data from %image% and collect in hex[] up to <maxChars> characters (divisible by 6) mode %width%,%height% set /a height+=10 REM *** Set window dimension to height * width <nul set /p ".=%ESC%[8;%height%;%width%t" certutil -f -encodehex %image% ppm.hex.tmp > nul set /a hex_max=0 set /a headerSize=headerSize*2 %= ignore this amount of hex values =% set /a maxChars=bytesPerLine*2 for /f "tokens=1,*" %%a in (ppm.hex.tmp) do ( set "line=%%b" set "line=!line:~0,48!" set "hex=!hex!!line: =!" if defined headerSize ( if "!hex:~%headerSize%,1!" NEQ "" ( set "hex=!hex:~%headerSize%!" set "headerSize=" ) ) if "!hex:~%maxChars%,1!" NEQ "" ( set "hex[!hex_max!]=!hex:~0,%maxChars%!" set /a hex_max+=1 set "hex=!hex:~%maxChars%!" ) <nul set /p ".=%ESC%[HLoading (!hex_max!)" ) if "!hex!" == "" ( set /a hex_max-=1 ) ELSE ( set "hex[!hex_max!]=!hex:~0,990!" ) exit /b REM *** Build the out[] array with color escape sequences for every pixel :RGB24bitTo8bit <pictureName> echo( set /a maxCount=bytesPerLine*2-6 for /L %%a in (0,1,%hex_max%) do ( <nul set /p ".=%ESC%7Converting RGB (%%a)%ESC%8" %= Save/restore cursor position =% set "out=" for /L %%b in (0,6,%maxCount%) do ( set "c=!hex[%%a]:~%%b,6!" if defined c ( set /a "r=0x!c:~0,2!", "g=0x!c:~2,2!", "b=0x!c:~4,2!" set "out=!out!#!r!;!g!;!b!m " ) ) set "%1[%%a]=!out!" ) exit /b :display <pictureName> <offset> REM *** Hide cursor, Set cursor to line %1 <nul set /p ".=%ESC%[?25l%ESC%[%2H" for /L %%a in (0,1,%hex_max%) do ( <nul set /p ".=!%1[%%a]:#=%ESC%[48;2;!" ) REM *** Show cursor, Reset color to default <nul set /p ".=%ESC%[?25h%ESC%[0m" exit /b