Меню
Категории
Рисование на языке BAT
16 июня, 2009 Интересное

Рисование на языке BAT. Вот эта картинка создана .bat файлом:

resultq - Рисование на языке BAT

Многие не знают, но если приложить немного усилий, то командный процессор MS Windows становится способен на многое. В принципе, это обычный императивный язык программирования, немного со странностями, но именно они превращают программирование на нём в своеобразное развлечение. Многие действия, не предусмотренные в конструкции языка, надо придумать как имитировать, порой какими-то фантастическими способами.

Например, как сделать паузу на заданное количество секунд? Команда pause тут бессильна. В место неё паузу удобно организовать через ping.
Пауза на 5 секунд будет выглядеть вот так:
ping 127.0.0.1 -n 6 -w 1000 > nul

Вот как узнать, содержит ли строка подстроку? Опять же, на первый взгляд ничего подходящего нет. На помощь приходит замена подстроки в строке:
set string=SOME TEXT
if not "%string%"=="%string:TEXT=%" echo YES

Ещё на .bat можно организовать вычисления с плавающей точкой (изначально плавающая точка не поддерживается), распараллеленные вычисления, синхронизацию между «процессами», распараллеленное вычисление на нескольких компьютерах и т.п. Я как-то раз видел исходники полиморфного(!) вируса, который полностью написан на bat-файле :)

В общем, время от времени я пишу что-нибудь на .bat, не могу пройти мимо такого вызова :)
Cейчас выкладываю одну из своих работ: батник, который рендерит множество Мандельброта в bmp.

@echo off
set /a xPixels = 180
set /a yPixels = 120
set /a xStart = -22000
set /a yStart = -10000
set /a xSize = 32000
set /a ySize = 20000
set /a maxIter = 32
call ::make_bmp_header

set /a xStep = xSize/xPixels
set /a yStep = ySize/yPixels

set /a iy = 0
:iyLoop

  set /a ix = 0
  :ixLoop

    set /a x = xStart + ix * xStep
    set /a y = yStart + iy * yStep
    set /a x0 = x
    set /a y0 = y

    set /a iteration = 0

    :formula
      set /a xtemp = x*x/10000 - y*y/10000 + x0
      set /a y = 2*x*y/10000 + y0
      set /a x = xtemp
      set /a iteration+=1

      set /a dist = x*x/10000 + y*y/10000
      if [%iteration%]==[%maxIter%] goto breakFormula
    if /I %dist% LEQ 40000 goto :formula
    :breakFormula

    if [%iteration%]==[%maxIter%] (call :plot_black)
else (call :plot_color %iteration%)

  set /a ix += 1
  if not [%ix%]==[%xPixels%] goto ixLoop

  set /a progress = yPixels - iy
  echo.%progress%

set /a iy += 1
if not [%iy%]==[%yPixels%] goto iyLoop

call ::make_bin
ren file$ result.bmp
mspaint result.bmp
exit/b

:plot_black
call :write_byte 0
call :write_byte 0
call :write_byte 0
exit/b

:plot_color
set /a rc=%1*5 + 32
set /a gc=%1*7 + 6
set /a bc=128 - (%1*3 + 4)
call :write_byte %rc%
call :write_byte %gc%
call :write_byte %bc%
exit/b

:make_bmp_header

set /a dataSize = xPixels * yPixels * 3 + 54
set /a dataSize0 = dataSize%%256
set /a dataSize1 = (dataSize/256)%%256
set /a dataSize2 = (dataSize/(256*256))%%256
set /a dataSize3 = (dataSize/(256*256*256))%%256

call :init_bin

call :write_byte 66
call :write_byte 77

call :write_byte 118
call :write_byte 56
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 54
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 40
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte %xPixels%
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte %yPixels%
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 1
call :write_byte 0
call :write_byte 24
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte %dataSize0%
call :write_byte %dataSize1%
call :write_byte %dataSize2%
call :write_byte %dataSize3%
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0
call :write_byte 0

exit /b

:init_bin
echo.n file$>bin$
set /a addr=0x0100
call set "hstr=e "
call :write_word %addr%
set mustflush=0
exit /b

:write_byte
set /a a=%1
set hexs=0123456789ABCDEF
set /a a0=a/16
set /a a1=a%%16
call set res= %%hexs:~%a0%,1%%%%hexs:~%a1%,1%%
set hstr=%hstr%%res%
set /a addr+=1
set /a mod16=addr%%16
set mustflush=1
if not %mod16%==0 exit /b
echo.%hstr%>>bin$
call set "hstr=e "
call :write_word %addr%
set mustflush=0
exit /b

:write_word
set /a a=%1
set hexs=0123456789ABCDEF
set /a a0=a/4096
set /a a1=a/256%%16
set /a a2=a/16%%16
set /a a3=a%%16
call set res=%%hexs:~%a0%,1%%%%hexs:~%a1%,1%%%%hexs:~%a2%,1%%%%hexs:~%a3%,1%%
set hstr=%hstr%%res%
exit /b

:make_bin
if "%mustflush%"=="1" echo.%hstr%>>bin$
set /a filesz=addr-0x0100
echo.r cx>>bin$
set hstr=
call :write_word %filesz%
echo %hstr%>>bin$
echo.w>>bin$
echo.q>>bin$
debug<bin$
del bin$
exit /b

Источник https://habrahabr.ru/blogs/crazydev/62043/

2 комментария
  1. Много чего видел даже псевдо графику в окне командной строки похожую на видео , но чтоб такое :))
    Респект, весело ))

  2. а у меня вообще чё то не пашет((((((((((((

Добавить комментарий




*