Page 1 of 1

Paint & Animation Studio

Posted: 20 Jun 2020 10:02
by T3RRY
Digging through history again, I encountered this topic viewtopic.php?f=3&t=7860, and of course, my reaction is:
Hey - There's something to waste some time on...
(Now more than) Half an hour later...
Download Link V.3.0 - https://drive.google.com/uc?export=down ... XdVB7BYSPq
Youtube Demo: https://youtu.be/HasHBx1uAe8E (V1.0)
*Update* 07 July 2020 Archive updated with Version 3.0
- Animate.Bat added to the Archive **Improved version: viewtopic.php?p=62302#p62302**
- Palettes moved from main program to components folder to facilitate lasting palette editing.

[/u][/b]
  • Archive Contents:
    +BatchPaint\
    - painter.bat v 3.0
    -+ _Components\
    - BG.EXE
    - cursorsize.exe
    - GetFontSize.exe
    - GetKey.exe
    --+ Palettes\
    - Palette[0].bat
    - ~ Palette[18].bat
    --+ Sound\
    - Kai_Engel_-_05_-_When_the_World_Falls_Down.mp3
    - Kai_Engel_-_07_-_Downpour_Pon_X.mp3
    - Kai_Engel_-_07_-_modum.mp3
    - Kai_Engel_-_08_-_daemones.mp3
    - Kai_Engel_-_08_-_Downfall.mp3
    - Sentinel.mp3
    --+ Paintings\
    - readme.txt
    - Animate.bat
For Windows 10 Systems supporting ASCII escape codes
---------------------------------------------------------------------------------------------------------------------------
! New ! + Features added for all you out there with ideas of creating batch animations the easy way!
  • Features:
    07/07/2020
    Load multiple objects as layers in the Animate subprogram using {Insert} to name an object group to choose from, and switch between selected layers using {Tab}.
    28/06/2020
    Cells can now be individually deleted from the object file
    Rotation and Mirroring of Image added to Animate.bat
    Painting are now seperate objects from the canvas, And a new program has been added to the archive - Animate.bat,
    which allows the paiting to be moved and repositioned - This isn't just a visual move, the X,Y values of each 'bit' are recalculated for
    the desired direction of movement and the painting is replaced with the 'bits' in their new positions.
    Paintings can be cloned using {INSERT}
    'Draw' Mode is switched off automatically when cloning, switching paintings, or Moving paintings around the canvas.
    When draw mode is off, the cursor will write to the screen, but not the file- Allowing you to see it's position without
    affecting the painting. Simply TAB / SPACE to refresh the painting
    Autosaves current painting - quickselect with {TAB} or {SPACE} to switch paintings and view / resume
    Draw On/Off key {END} to selectively apply the brush
    Customisable self saving Palette. Store the current color in index 1~8 using {ENTER}.. Select custom index 1-8 using {HOME} key
    Move brush with Arrow Keys
    18 Quickselect Color Palettes - {PAGE UP} or {PAGE DOWN} to scroll palettes, 1-8 to select a color in that Palette index
    5 chill Background Music Tracks - use 't' 0-5 during painting to change track #
    24 Bit Color, Selected by R G B values that can be independently adjusted using: R G B + -
    Dynamic Display conveying current paint settings and all options
    Single Press Maximisation / Reduction of Active Color Min:0 Max:9
    5 Predefined Character Sets
    2 stage selection of Character or Character Set by Index value
    Single Press Color Inversion
    Screen Size selection
---------------------------------------------------------------------------------------------------------------------------
Bug Fix 23 June 2020 - Monitor.vbs Now supports Directories containing spaces
Note: Script uses external .exe scripts. Download is Required for components
Painter.bat will be updated in the below code to reduce the need to download for minor revisions

Code: Select all

@REM:::::::::::::::::::::::::::: 24 Bit Batch Animation Studio  by T3RRY ::::::::::::::::::::::::::::::::::
::: Download contains companion files required to run painter.bat This script is newest version         :::
::: V3.0 07 July 2020                                                                                   :::
::: Multiple Object Support added to Animate Mode. 'Insert' Key to select objects from an existing      :::
::: project to add to the object to the layer group. 'Tab' Key to switch between layers.                :::
::: V2.3 01 Jujy 2020                                                                                   :::
:::         Suite of features added for Animation creation:                                             :::
:::            - Painting and Canvas are now independent Objects.                                       :::
:::            - Single press cloning of current painting (Insert Key)                                  :::
:::            - *** Repositioning of Painting Coordinates ****   ('P': 1  2  3  4  6  7  8  9  )       :::
:::                  Axis:                                              SW S  SE E  W  NW N  NE         :::
:::                - As the painting is now an independent object, It can be 'Moved' to new coordinates :::
:::                - The Axis positions for all 'bits' of the painting are recalculated and shifted     :::
:::                - Along the desired axis of movement - Horizontal, Vertical or Diagonal.             :::
:::            - *** Rotate (90 Degrees): 5. Mirror - Horizontal: M Vertical: F ***                     :::
:::            - Cell Delete: 'K' Current cell position if present in file, Disables Draw Mode          :::
:::            - Refresh (Paint Studio): 'BackSpace'
:::         Changed way paths of songs are set to allow users to replace with their own mp3 files       :::
:::         Supports up to 10 Custom Songs                                                              :::
::: V2.2 25 June 2020                                                                                   :::
:::         Implemented Autosave Custom Palette colors.                                                 :::
:::         Images can be scrolled sing [Tab <<] or [Space >>]                                          :::
:::         Added Draw On/Off switch [End] to reposition cursor without modifying screen content        :::
::: V2.1 23 June 2020                                                                                   :::
:::         monitor.vbs path quoting corrected to support directories with spaces                       :::
::: V2.0 22 June 2020                                                                                   :::
:::         Paintings now autosaved in indexed form and can be reloaded and resumed with Tab / Space    :::
:::         Primary input now uses GetKey.Exe                                                           :::
:::         Canvas Background changed to white                                                          :::
:::         Palette expansion. 18 color palettes selectable with spacebar                               :::
:::         Removed forced cursor size by adjusting lines and columns calculation to compenstate for    :::
:::         Cursor size                                                                                 :::
::: V1.1 21 Sound Tracks may now be changed with 't' Key                                                :::
::: 20 June 2020                                                                                        :::
:::  - Painter Program Adapted from my Matrix Scipt.                                                    :::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@Echo Off & CD "%~dp0"
CHCP 65001 >nul & REM Used for menu border characters
	Set "ProgName=Painter by T3RRY"
::: - Hide Cursor
	(For /F "Delims=" %%C in ('dir BG.exe /B /S') Do (Set "MOVECURSOR=%%C mouse" & "%%C" Cursor 0)) 2> Nul
	(For /F "Delims=" %%C in ('dir GetKey.exe /B /S') Do (Set "GetKey="%%C" /n")) 2> Nul
	(For /F "Delims=" %%C in ('dir GetKey.exe /B /S') Do (Set GetString="%%C")) 2> Nul
::: { Variable used in calling this script from the Self created resizing Batch.	
	Set "ThisFile=%~F0"
::: }
::: { Get screen Dimensions
	For /f "delims=" %%# in  ('"wmic path Win32_VideoController get CurrentHorizontalResolution,CurrentVerticalResolution /format:value"') do (
		Set "%%#">nul
	)
::: - Calculate scale Factor in effect. Registry value requires restart to update if scale has changed.
	For /F "Tokens=3 Delims= " %%A in ('REG QUERY "HKCU\Control Panel\Desktop\WindowMetrics" /V AppliedDPI') Do Set /A SF=%%A / 100 + 1
::: Use the below to confirm values of screen resolution and scaling factor if screen is is not correctly centered
rem (For %%A ib (Current SF) Do Set %%A) & Pause
::: - Get Font Size
	(For /F "Delims=" %%S in ('dir GetFontSize.exe /B /S') Do "%%S") 2> Nul
	Set /A "Font.H=%errorlevel% >> 16, Font.W=%errorlevel% & 0xFF"
	Set /A FH.Comp=4,FW.Comp=0
	For /L %%# in (%Font.H%,1,16) Do Set /A FH.Comp+=1
	For /L %%# in (%Font.W%,1,8) Do Set /A FW.Comp+=3
	Set /A Max.Width= ( CurrentHorizontalResolution / ( Font.W * SF ) ) + FW.Comp
	Set /A Max.hieght= ( ( CurrentVerticalResolution / Font.H ) / SF ) - FH.Comp
::: }
::: { Creates variable /AE = Ascii-27 escape code.
::: - http://www.dostips.com/forum/viewtopic.php?t=1733
::: - https://stackoverflow.com/a/34923514/12343998
::: - /AE (Alt 146) can be used  with and without DelayedExpansion.
    Setlocal
    For /F "tokens=2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
        Endlocal
        Set "/AE=%%a"
    )
::: }
::: { Set environment state for Macro Definitions
    Setlocal DisableDelayedExpansion

    (Set \n=^^^
%= Macro Definition Variable. Do Not Modify =%
)

::: { String length Macro %@strLen% <ResultVar> <"String">
Set @strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
	For /F "tokens=1,* delims={}" %%G in ("!argv!") do (%\n%
		Set tmpLen=%%~H%\n%
		Set result=%%G%\n%
		Set LenTrim=Start%\n%
		For /L %%a in (1,1,250) Do (%\n%
			IF NOT "!LenTrim!"=="" (%\n%
				Set LenTrim=!tmpLen:~0,-%%a!%\n%
				If "!LenTrim!"=="" (%\n%
					Set !result!=%%a%\n%
					IF "Min.Text"=="" Set "Min.Text=%%a"%\n%
					IF Not "Min.Text"=="" If Not %%a LSS !Min.Text! Set "Min.Text=%%a"%\n%
				)%\n%
			)%\n%
		) %\n%
		) %\n%
	) ELSE set argv=
::: } Used to get length of menu options and calculate position needed to centre the string Horizontally
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Input / Color output Macros
::: { %MSG|% <"Your Message Value"> <%@Con%> <Y#;X#> <ColorName>
	Set "MSG|=Set Args-In="
::: }
::: {  <%MSG|%> <"Your Message Value"> %@CON% <Y#;X#> <ColorName>
	Set @Con=^&for /L %%n in (1 1 2) do if %%n==2 (%\n%
		For /F "tokens=1,2 delims=, " %%G in ("!argv!") do (%\n%
			For %%O in (!Args-In!) do Echo(%/AE%[%%GH%/AE%[K!%%H!%%~O!Off!^&^&Endlocal%\n%
		) %\n%
	) ELSE setlocal enableDelayedExpansion ^& set argv=, 
::: } Used to output Literal strings at target coordinates in specified Color
::: { %PAINT%{!Key!}
::: - Evaluate Keypress and enact appropriate option
	Set PAINT=for /L %%n in (1 1 2) do if %%n==2 (%\n%
		For /F "tokens=1 delims={}" %%G in ("!argv!") do (%\n%
			IF /I "%%G"=="up" IF Not "!POS.Y!"=="1" Set /A Pos.Y-=1 ^> Nul%\n%
			IF /I "%%G"=="down" IF Not "!POS.Y!"=="!H.Max!" Set /A Pos.Y+=1 ^> Nul%\n%
			IF /I "%%G"=="left" IF Not "!POS.X!"=="1" Set /A Pos.X-=1 ^> Nul%\n%
			IF /I "%%G"=="right" IF Not "!POS.X!"=="!W.Max!" Set /A Pos.X+=1 ^> Nul%\n%
			IF /I "%%G"=="End" (IF "!Draw!"=="1" (Set "Draw=0") Else (Set "Draw=1"))%\n%
			IF /I "%%G"=="r" Set "Key=" ^& Set PosCol=RR%\n%
			IF /I "%%G"=="g" Set "Key=" ^& Set PosCol=GG%\n%
			IF /I "%%G"=="b" Set "Key=" ^& Set PosCol=BB%\n%
			IF /I "%%G"=="k" Set "Draw=0" ^& Call :DelCell%\n%
			IF /I "%%G"=="w" Set /A "RR=255,GG=255,BB=255" ^> Nul%\n%
			IF /I "%%G"=="PageUp" (%\n%
				 Set "Key="%\n%
				Set /A "Pal#+=1" ^> Nul%\n%
				IF !Pal#! GTR !Palettes! Set "Pal#=1"%\n%
				For %%p in (!Pal#!) Do Call "!PalPATH:Pal#=%%p!"%\n%
			)%\n%
			IF /I "%%G"=="PageDown" (%\n%
				 Set "Key="%\n%
				Set /A "Pal#-=1" ^> Nul%\n%
				IF !Pal#! LEQ 0 Set "Pal#=!Palettes!"%\n%
				For %%o in (!Pal#!) Do Call "!PalPATH:Pal#=%%o!"%\n%
			)%\n%
			IF "%%G"=="*" (CLS ^& Goto :Paint)%\n%
			IF /I "%%G"=="i" If "!II!" == "38" (Set II=48) Else (Set II=38)%\n%
			IF /I "%%G"=="p" Set "Draw=0" ^& CALL "!Animate!" "/D" "Painting[!Load#!]"%\n%
			IF /I "%%G"=="t" Set "Key=" ^& TITLE %ProgName% Select Track [!TrackOPTS!] ^& For /F "Delims=" %%a in ('choice /N /C:!TrackOPTS!') Do Call :ChangeTrack %%a%\n%
			IF /I "%%G"=="c" TITLE %ProgName% Select Character [0 - 9] ^& For /F "Delims=" %%b in ('choice /N /C:0123456789') Do Set "CHAR=!CHARACTERSET:~%%b,1!"%\n%
			IF /I "%%G"=="x" Set "Key=" ^& TITLE %ProgName% Select Character Set [!CHARSETSMIN! - !CHARSETSMAX!] ^& For /F "Delims=" %%c in ('choice /N /C:!CHAROPTS!') Do Set "CHARACTERSET=!CHARACTERSET%%c!"%\n%
			IF /I "%%G"=="plus" For %%? in (!PosCol!) Do If Not !%%?! GEQ 250 Set /A %%?+=5 ^> Nul%\n%
			IF /I "%%G"=="minus" For %%# in (!PosCol!) Do If Not !%%#! LEQ 5 Set /A %%#-=5 ^> Nul%\n%
			For /L %%d in (1,1,8) Do If "%%G"=="%%d" For %%v in (!Pal#!) Do !PalCol[%%v][%%d]! ^> Nul%\n%
			IF /I "%%G"=="Tab" Call :Load %%G%\n%
			IF /I "%%G"=="Space" Call :Load %%G%\n%
			IF /I "%%G"=="BackSpace" Call :Load%\n%
			IF /I "%%G"=="Insert" ((For %%f in (!Load#!) Do For %%P in ("!Painting[%%f]!") Do For /F "Tokens=2 Delims=_" %%N in ("%%~nP") Do For %%. in (!Copy#!) Do ( COPY "!Painting[%%f]!" /A "!Painting[%%f]:%%N=%%.!" /A ^> Nul 2^>Nul )  ) ^&^& Call :GetPaintFN ^& Set /A Copy#=!FN#!+1 ^> Nul ^& Call :Load)%\n%
			IF "%%G"=="0" Set "!PosCol!=0"%\n%
			IF /I "%%G"=="Home" TITLE %ProgName% Select Index [1 - 8] ^& For /F "Delims=" %%h in ('choice /N /C:12345678') Do !PalCol[0][%%h]! ^> Nul%\n%
			IF /I "%%G"=="Enter" Set "CpalMod=1" ^& TITLE %ProgName% Store Index [1 - 8] ^& For /F "Delims=" %%i in ('choice /N /C:12345678') Do Set "PalCol[0][%%i]=Set /A RR=!RR!,GG=!GG!,BB=!BB!"%\n%
			IF "%%G"=="9" Set "!PosCol!=255"%\n%
			IF /I "%%G"=="ESC" Exit%\n%
		) %\n%
	) ELSE set argv=
::: } Used to output substrings at target coordinates usings Substring Modification
::: { ** End Macro Definitions ** }
::: { Identify when the program has been called by the resizing batch it creates and goes to label passed by call
	If Not "%~3"=="" (
		Set "Console_Hieght=%~1"
		Set "Console_Width=%~2"
		Set "ThisFile=%~4"
		Goto :%~3
	) Else (Goto :main)
::: }
::: ***************************************** Subroutines ******************************************
:GetPaintFN <Parameter used to differentiate between initialization and count adjustment for copying paintings>
:::{ Create / update array of painting paths
	Set "Paintings=%CMP%\Paintings"
	If not Exist "%Paintings%" MD "%Paintings%"
	Set Paint#=0
	PUSHD "%Paintings%"
	(For /F "Delims=" %%A in ('dir /b !ProjectName!*.sav /O:N') Do (
		Set "Painting[!Paint#!]=%Paintings%\%%A"
		Set /A Paint#+=1
		)
	) >Nul 2> Nul
	Set /A "Load#=Paint#,FN#=Paint#"
:GetPaintFN# <ensure unique filename>
	If Exist "%Paintings%\!ProjectName!_!FN#!.sav" (Set /A FN#+=1 & Goto :GetPaintFN#)
	Set "Painting[!Paint#!]=%Paintings%\!ProjectName!_!FN#!.sav"
	POPD
If "%~1"=="" Set /A "Load#-=1,Paint#-=1,FN#-=1"
::: }
Exit /B
:Project
Set StrLen=0
TITLE Enter Project Name:
Call :GetName
Exit /B
:GetName
%GetString%
For %%F in (!Errorlevel!) Do (
	If /I "!%%F!"=="Enter" Exit /B
	If /I Not "!%%F!"=="BackSpace" (
		Set /A StrLen+=1
		If Not "!%%F!"=="" (Set "ProjectName=!ProjectName!!%%F!")
		Set "ProjectName=!ProjectName:Space=-!"
		Set "ProjectName=!ProjectName:_=-!"
	) Else (
		Set /A StrLen-=1
		For %%L in (!StrLen!) Do Set "ProjectName=!ProjectName:~0,%%L!
	)
)
TITLE Enter Project Name: !ProjectName!
Goto :GetName
::: { Subroutine to process output of wmic command into usable variables for screen dimensions (resolution)
:ChangeConsole <Lines> <Columns> <Label to Resume From> <If a 4th parameter is Defined, Aligns screen at top left>
::: - Calculation of X axis relative to screen resolution and console size. Resolution scales to Max Columns.
	Set /A XresScale= CurrentHorizontalResolution / Max.Width
	Set /A HorzCentre= CurrentHorizontalResolution / 2
	Set /A CentreX= HorzCentre - ( ( %~2 * XresScale ) / 2 )
::: - Calculation of Y axis relative to screen resolution and console size. Resolution scales to Max Lines.
	Set /A YresScale= CurrentVerticalResolution / Max.hieght
	Set /A VertCentre= CurrentVerticalResolution / 2
	Set /A CentreY= VertCentre - ( ( %~1 * YresScale ) / 2 )
::: - Optional 4th parameter can be used to align console at top left of screen instead of screen centre
	If Not "%~4"=="" (Set /A CentreY=0,CentreX=-8)
::: - Creates a batch file to reopen the main script using Call with parameters to define properties for console change and the label to resume from.
	>"%TEMP%\paintMH.sav" ECHO/%~1
	>"%TEMP%\paintMW.sav" ECHO/%~2
	(
	Echo.@Mode Con: lines=%~1 cols=%~2
	Echo.@Title %ProgName%
	Echo.@Call "%ThisFile%" "%~1" "%~2" "%~3" "%ThisFile%" 
	)>"%temp%\ChangeConsole.bat"
::: - .Vbs script creation
	(
	Echo.Set objWMIService = GetObject^("winmgmts:\\.\root\cimv2"^)
	Echo.Set objConfig = objWMIService.Get^("Win32_ProcessStartup"^)
	Echo.objConfig.SpawnInstance_
	Echo.objConfig.X = %CentreX%
	Echo.objConfig.Y = %CentreY%
	Echo.Set objNewProcess = objWMIService.Get^("Win32_Process"^)
	Echo.intReturn = objNewProcess.Create^("%temp%\ChangeConsole.bat", Null, objConfig, intProcessID^)
	)>"%temp%\Consolepos.vbs"
::: - .Vbs Starts the companion batch script to Change Console properties, ends the parent.
	Start "" "%temp%\Consolepos.vbs" & Exit
::: }
::: { creates a companion batch file thats called with arguments for trackpath, volume and loop tf values
:Sound.Components
	(
	Echo.@ECHO OFF
	Echo.Set "MusicPath=%%~1"
	ECHO.IF Not Exist "%%MusicPath%%" Goto :Eof
	Echo.Set "vol=%%~2"
	Echo.Set "Loop_TF=%%~3"
::: - Change to the Directory you want to create the Music Launcher in.
	Echo.PUSHD "%%Sounds%%"
::: - Ensure no Conflict with the Previous Script.
	Echo.IF exist PlayMusic.vbs ^(
	Echo.DEL PlayMusic.vbs
	Echo.^)
::: - Creates a vbs Script to Launch the music (Occurs without any visual indication or prompting)
	Echo.^( echo Set Sound = CreateObject^("WMPlayer.OCX.7"^^^)
	Echo.echo Sound.URL = "%%MusicPath%%"
	Echo.echo Sound.settings.volume = %%vol%%
	Echo.echo Sound.settings.setMode "loop", %%Loop_TF%%
	Echo.echo Sound.Controls.play
	Echo.echo While Sound.playState ^^^<^^^> 1
	Echo.echo      WScript.Sleep 1000
	Echo.echo Wend
	Echo.^)^>PlayMusic.vbs
	Echo.start /min PlayMusic.vbs
::: -	Return to the Previous Directory
	Echo.POPD
::: -	Exit the Launcher and return to Previous batch program.
	Echo.Goto :EOF
	)>"%Player%"
::: { Monitor checks process status of cmd.exe every 1500 ms and calls StopMusic batch file to taskill all vbs scripts when
::: - cmd.exe process count is 0. Delay is to reduce CPU usage of the WMI service
	(
	ECHO Set objWMIService = GetObject ("winmgmts:"^)
	ECHO Set proc = objWMIService.ExecQuery("select * from Win32_Process Where Name='cmd.exe'"^)
	ECHO DO while proc.count ^> 0
	ECHO Set proc = objWMIService.ExecQuery("select * from Win32_Process Where Name='cmd.exe'"^)
	ECHO if proc.count ^< 1 then exit do
	ECHO wscript.sleep 250
	ECHO loop
	ECHO Set WshShell=createobject("wscript.shell"^)
	ECHO WshShell.run """%MusicStopper%""", 0, true
	)>"%Monitor%"
::: }
::: { Simple taskkill script to terminate vbs scripts on program exit
	(
	Echo.@ECHO OFF
	Echo.taskkill /pid WScript.exe /f /t ^>nul
	Echo.Goto :EOF
	)>"%MusicStopper%"
Exit /B
::: }
:Size-T <Smallest Dimensions supported with Border>
Call :ChangeConsole %T.hieght% %T.Width% PaintMenu
:Size-S
Call :ChangeConsole %S.hieght% %S.Width% PaintMenu
:Size-M
Call :ChangeConsole %M.hieght% %M.Width% PaintMenu
:Size-L
Call :ChangeConsole %Max.hieght% %Max.Width% PaintMenu TL
:main
::: { Call Subroutine to Resize and Position the Console
	Call :ChangeConsole %Max.hieght% %Max.Width% PaintMenu TL
::: }
:Load
	CLS & Set Key=
	Set Draw=0
	If /I "%~1"=="Tab" ( If !Load#! EQU 0 (Set "Load#=!Paint#!") Else Set /A "Load#-=1" > Nul )
	If /I "%~1"=="Space" ( If !Load#! EQU !Paint#! (Set "Load#=0") Else Set /A "Load#+=1" > Nul )
	TYPE "%Paintings%\Canvas_!H.Max!.dat"
	Echo/%/AE%[0;1H!Off!
	TYPE "!Painting[%Load#%]!" || (CLS & Set Painting[%Load#% & Pause)
Exit /B
:ChangeTrack
	CALL "%MusicStopper%"
	CALL "%Player%" "!Track%1!" "%Vol%" "true"
	Start "" "%monitor%"
Exit /B
:Animate
::: { Manipulate color and characters used for border.
	Set /A aCI+=1
::: - Loop through the Character set using String Substitution to Isolate a given Character
	IF "%Char%" EQU "%Border[i]%" (Set Char=0) Else (Set /A Char+=1)
::: - Loop through the Color Array
	IF "%aCI%"=="%CI#%" Set "aCI=1"
::: - Preface the Output string with the current Color
	FOR %%A in (!C#[%aCI%]!) do Set "ANIM=Echo.!%%A!"
::: - Build the Border box
	For /L %%X in (!BorderLeft!,1,!BorderRight!) do Set "ANIM=!ANIM!%/AE%[!BorderTop!;%%XH!BorderSet:~%Char%,1!%/AE%[!BorderBase!;%%XH!BorderSet:~%Char%,1!"
	For /L %%Y in (!BorderTop!,1,!BorderBase!) Do Set "ANIM=!ANIM!%/AE%[%%Y;!BorderLeft!H!BorderSet:~%Char%,1!%/AE%[%%Y;!BorderRight!H!BorderSet:~%Char%,1!"
::: - Output the border
	%ANIM%
::: }
Exit /B
:DelCell
Set "Input=!Painting[%Load#%]!"
For %%A in ("!Input!") Do (
	Set "RenFile=Ren NewAnim.sav %%~nxA"
	PUSHD "%%~dpA"
)
	(For /F "UsebackQ Delims=" %%A in ("!Input!") Do (
		For /F "Tokens=2 Delims=[;" %%Y in ("%%A") Do For /F "Tokens=2 Delims=;H" %%X in ("%%A") Do (
			Echo/"%%Y;%%XH" | findstr "!Pos.Y!;!Pos.X!H" > Nul || Echo/%%A
		)
	    )
	)>"NewAnim.sav"
Del /Q "!Input!"
%RenFile% || (Echo Rename error in Cell Delete. & Pause)
POPD
If Not "%~1"=="Paint" (
	CLS
	Type "%Paintings%\Canvas_!H.Max!.dat" || (Echo Canvas Load Error & Pause) & rem // Display Canvas
	Type "!Input!"
)
Exit /B

::: ********************************************************* Display Elements ***********************************************************
:PaintMenu
::: { Assigns ANSI color code values to each color, then builds an Array containing those color values to be accessed using random number.
	Setlocal EnableDelayedExpansion
	Set /A Red=31,Yellow=33,Green=32,Blue=34,Purple=35,Cyan=36,White=37,Gray=90,Pink=91,Beige=93,Aqua=94,Magenta=95,Teal=96,Off=0,Black=38,CI#=0
	For %%A in (Red,Yellow,Green,Blue,Off,Pink,Beige,Gray,Purple,Cyan,White,Aqua,Magenta,Teal,Black) do (
		Set "%%A=%/AE%[!%%A!m"
		Set /A "CI#+=1"
		Set "C#[!CI#!]=%%A"
	)
::: }
::: { Define character Set to be used. Can be Selected via paint menu
::: rem // CHoice limitation restricts number of character Sets to 10 (0-9)
::: CharacterSet[N] 0,6,7,8,9 available for definition
::: CHARSETS MIN and MAX (Valid Set Ranges) must to be updated to reflect any new Sets.
	Set "CharacterSet= ░▒▓█▀▄■⌂¶"
	Set "CharacterSet1= ░▒▓█▀▄■⌂¶"
	Set "CharacterSet2=•◘○☼◙►◄▲▼▬"
	Set "CharacterSet3=☺☻♥♦♣♠♫♂♀§"
	Set "CharacterSet4=╣║╗╝╔╩╦╬═┼"
	Set "CharacterSet5=./|\_-+#Hv"
	Set /A CHARSETSMIN=1,CHARSETSMAX=5
	Set CHAROPTS=
	For /L %%N in (%CHARSETSMIN%,1,%CHARSETSMAX%) Do Set "CHAROPTS=!CHAROPTS!%%N"
%= UTF-8 Codepage 65001 - ALT + 7;9;664;719 •○ʘ¤ =%
	Set "BorderSet=•○ʘ¤"
	Set "Border[i]=3" & REM 1 less than number of Characters Due to use in Substring Offset
::: }
::: { Define Variables For mapping errorlevel to Key.
::: - Differs by Case
:::  ** Numbers within the below ranges must not be assigned as other variable Names **
	Set /A Keypos=47 & REM [48 - 57]
	For %%A in (0 1 2 3 4 5 6 7 8 9) Do (
		Set /A Keypos+=1
		Set "!Keypos!=%%A"
	)
	Set /A Keypos=64 & REM [65 - 90]
	For %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) Do (
		Set /A Keypos+=1
		Set "!Keypos!=%%A"
	)
	Set /A Keypos=96 & REM [97 - 122]
	For %%A in (a b c d e f g h i j k l m n o p q r s t u v w x y z) Do (
		Set /A Keypos+=1
		Set "!Keypos!=%%A"
	)
	Set "-82=Insert"
	Set "-80=Down"
	Set "-72=Up"
	Set "-75=Left"
	Set "-79=End"
	Set "-73=PageUp"
	Set "-81=PageDown"
	Set "-77=Right"
	Set "8=backspace"
	Set "32=space"
	Set "13=enter"
	Set "43=plus"
	Set "42=*"
	Set "45=minus"
	Set "27=ESC"
	Set "-71=Home"
	Set "9=Tab"
::: }
::: { Define pathways and create subfolders used for self generated component files
::: - calls subroutines to create component files.
	For %%A in ("%ThisFile%") Do Set "ProgDir=%%~dpA"
rem	If not exist "%ProgDir%_Components" MD "%ProgDir%_Components"
If not exist "%ProgDir%_Components" (Echo/Components required. Download full program from dostips.com to continue & Pause & Exit /B 1)
	Set "CMP=%ProgDir%_Components"
	Set "PalDir=%CMP%\Palettes"
	Set "Sounds=%CMP%\Sound"
	Set "Animate=%CMP%\Paintings\Animate.bat"
	Set "PalPATH=%PalDir%\Palette[Pal#].bat"
	Set "Player=%Sounds%\BatchMusicPlayer.bat"
	Set "MusicStopper=%Sounds%\StopMusic.bat"
	Set "Monitor=%Sounds%\BatchMonitor.vbs"
	Call :Sound.Components
::: }
::: { Initiate script to close vbs scripts on exit
	Start "" "%monitor%"
::: }
::: { Define variables for songs
	Set /A Vol=50,AVTracks=0
	Set TrackOPTS=
PUSHD "%Sounds%" || (Echo/Sound Component Folder Missing. & Pause & Exit /B 1)
(For /F "Delims=" %%A in ('dir /b *.mp3 /O:N 2^> Nul') Do (
	Set "TrackOPTS=!TrackOPTS!!AVTracks!"
	Set "TRACK!AVTracks!=%%~dpnxA"
	Set /A AVTracks+=1
	)
) || (Echo/ Songs not found in %Sounds%. & Pause & Exit /B 1)
If %AVTracks% GTR 9 Set "AVTracks=9"& REM Choice index only supports options 0-9
POPD
	CALL :ChangeTrack 0
rem	CALL "%Player%" "%Track0%" "%Vol%" "true"
::: }

::: { Variables used to define and animate Border
	Set /A BorderLeft=Console_Width / 3,BorderRight=(Console_Width / 3) * 2,BorderTop=5,BorderBase=Console_Hieght - 5,aCI=0,Char=0
::: }
::: { Calculate X Y Coordinates required to Centre Text Horizontally using String Length and Border Dimensions
:::   Define number of menu options. Used to calculate even Line spacing.
	Set /A TextHCentre=Console_Width / 2
	%@StrLen%{Line[1]}{[B]egin Painting}
	%@StrLen%{Line[2]}{[S]creen Size}
	%@StrLen%{Line[3]}{------------------------------}
	%@StrLen%{Line[4]}{Actions with [] braces require}
	%@StrLen%{Line[5]}{a second selection to complete}
	%@StrLen%{Line[6]}{Change Track [!TrackOPTS!]}
	Set "Menu.Options=6"
::: - Calculate Spacing available for Lines of text relative to border size and number of  menu options
	Set /A TextSpace.H= ( BorderBase - BorderTop ) / ( Menu.Options + 1 )
	Set /A TextSpace.W= ( BorderRight-BorderLeft ) - 2
::: - Determine Scaling to be used. Ensures border size scaled to the longest string in menu options.
	Set /A  Scale.Text.W= ( Min.Text * 3 ) + 5 ,Scale.Screen.W= ( Max.Width / 7 ) * 3
	Set /A  Scale.Text.H= ( Menu.Options * 3 ) + 1 ,Scale.Screen.H= ( Max.Hieght / 7 ) * 3
::: - Factor Screen Width using the greater scale of text space or screen size.
	If %Scale.Screen.W% GTR %Scale.Text.W% Set /A T.Width=  ( Max.Width / 7 ) * 3,S.Width= Max.Width / 2,M.Width= ( Max.Width / 3 ) * 2
	If %Scale.Text.W% GEQ %Scale.Screen.W% Set /A T.Width= ( Min.Text * 3 ) + 5,S.Width= ( Min.Text * 4 ) + 5,M.Width= ( Min.Text * 5 ) + 5
::: - Factor Screen Hieght using the greater scale of text space or screen size.
	If %Scale.Screen.H% GTR %Scale.Text.H% Set /A T.hieght= ( Max.Hieght / 7 ) * 3, S.hieght= Max.Hieght / 2, M.hieght= ( Max.Hieght / 3 ) * 2
	If %Scale.Text.H% GEQ %Scale.Screen.H% Set /A T.hieght= ( Menu.Options * 3 ) + 1,S.hieght= ( Menu.Options * 4 ) ,M.hieght= ( Menu.Options * 6 ) + 2
::: - Final Calculation of X Y values needed to centre text horizontaly and space / centre lines vertically.
	For /L %%P in (1,1,%Menu.Options%) Do Set /A Column[%%P]=TextHCentre - (Line[%%P] / 2) & Set /A Line[%%P]=BorderTop + (%%P * TextSpace.H)
::: }
::: - Psuedo-pipe Strings for display into @Con Macro at [ARG 1 calculated Y;X Position] in [ARG 2 Color]
::: %MSG|% <"Qouted String" - Accepts additional Color codes> %@Con% <%Line[n]%;%Column[n]%> <Color>
	%MSG|% "[B]egin Painting" %@Con% %Line[1]%;%Column[1]% green
	%MSG|% "[S]creen Size" %@Con% %Line[2]%;%Column[2]% magenta
	%MSG|% "------------------------------" %@Con% %Line[3]%;%Column[3]% gray
	%MSG|% "Actions!aqua! with [] braces require" %@Con% %Line[4]%;%Column[4]% yellow
	%MSG|% "a second selection to complete" %@Con% %Line[5]%;%Column[5]% aqua
	%MSG|% "Change Track [%yellow%!TrackOPTS!%Pink%]" %@Con% %Line[6]%;%Column[6]% pink
:MainMenu
Call :Animate
::: { manipulate variables for color and line position to animate the prompt, with the aid of a Loop and Choice Timeout with Default Switch.
	For /F "Delims=" %%C in ('Choice /T 1 /N /C BS%TrackOPTS%A /D A') Do (
		For /L %%# in (0,1,%AVTracks%) Do If "%%C" == "%%#" (
			CALL "%MusicStopper%"
			CALL "%Player%" "!Track%%#!" "%Vol%" "true"
			Start "" "%monitor%"
			Goto :MainMenu
		)
		Set "Selection=%%C"
		IF /I "%%C"=="A" Goto :MainMenu
	)
::: }
	CLS
	If /I "%Selection%" == "S" Goto :SetSize
	Start "" "%monitor%"
	Goto :Paint
:SetSize
	%@StrLen%{Line[1]}{Screen_Size:}
	%@StrLen%{Line[2]}{[T]iny}
	%@StrLen%{Line[3]}{[S]mall}
	%@StrLen%{Line[4]}{[M]edium}
	%@StrLen%{Line[5]}{[L]arge}
	Set "Menu.Options=5"
::: - Calculate Spacing available for Lines of text relative to border size and number of  menu options
	Set /A TextSpace.H= ( BorderBase - BorderTop ) / ( Menu.Options + 1 )
::: - Final Calculation of X Y values needed to centre text horizontaly and space / centre lines vertically.
	For /L %%P in (1,1,%Menu.Options%) Do Set /A Column[%%P]=TextHCentre - (Line[%%P] / 2) & Set /A Line[%%P]=BorderTop + (%%P * TextSpace.H)
::: }
	%MSG|%"Screen Size:"%@Con% %Line[1]%;%Column[1]% blue
	%MSG|% "[T]iny" %@Con% %Line[2]%;%Column[2]% pink
	%MSG|% "[S]mall" %@Con% %Line[3]%;%Column[3]% pink
	%MSG|% "[M]edium" %@Con% %Line[4]%;%Column[4]% magenta
	%MSG|% "[L]arge" %@Con% %Line[5]%;%Column[5]% purple
	Set Selection=
:SizeMenu
	Call :Animate
::: { manipulate variables for color and line position to animate the prompt, with the aid of a Loop and Choice Timeout with Default Switch.
	For /F "Delims=" %%C in ('Choice /T 1 /N /C:TSMLN /D N') Do (Set "Selection=%%C" & IF /I "%%C"=="N" Goto :SizeMenu)
	CALL "%MusicStopper%"
	Goto :Size-%Selection%
::: }
::: ******************************************************* Script Break ***************************************************
:Paint & REM Initialize some more Variables and Screen prep
	Call :Project
	Call :GetPaintFN InitRequired
	Set /A Copy#=FN#+1
	<"%TEMP%\paintMH.sav" (
	Set /P "H.Max="
	)
	<"%TEMP%\paintMW.sav" (
	Set /P W.Max=
	)
	Set /A H.Max-=5
	Set PalOPTS=
	PUSHD "%PalDir%"
	(For /F "Delims=" %%A in ('dir /b Palette[*.bat /O:N 2^> Nul') Do (Set /A Palettes+=1)) || (Echo/ Palettes not found in %CMP%. & Pause & Exit /B 1)
	POPD
	Set /A II=48,RR=140,GG=90,BB=90,Pos.Y=H.Max / 2,Pos.X=W.Max / 2,Info1=H.Max + 1,Info2=H.Max + 2,Info3=H.Max + 3,Pal#=1,Palettes-=1,Draw=1,LYR#=0
	Set "Draw[0]=Off"
	Set "Draw[1]=On"
	Set "CHAR=!CHARACTERSET:~0,1!"
	Set "PosCol=RR"
	Break>"!Painting[%Load#%]!"
	(For /L %%A in (1,1,!H.Max!) Do Echo/%/AE%[48;2;255;255;255m%/AE%[K%/AE%[0m)>"%Paintings%\Canvas_!H.Max!.dat"
	Type "%Paintings%\Canvas_!H.Max!.dat"& rem // Display Canvas
	Echo/%/AE%[0;1H!Off!
	Call "!PalPATH:Pal#=0!"& rem // Load customizable Palette
	Call "!PalPATH:Pal#=%Pal#%!"& rem // Load starting Palette
	For %%F in (!Painting[%Load#%]!) Do (
	    Set "ProjectLayers={%%~nxF}"
	    Set "Layer[%LYR#%]=%%~nxF"
	)
:PaintStuff
	For %%P in ("!Painting[%Load#%]!") Do For /F "Tokens=2 Delims=_" %%N in ("%%~nP") Do (TITLE * %ProgName% * Painting FN#=%%N Pos: !Pos.Y!;!Pos.X! & Set "CFN#=%%N")
	(For %%V In (0 !Pal#!) Do Set "Palette[%%V]=")& rem // variable refreshed and built into a string containing a colored index representing the current palette color options
	If /I "!Key!"=="k" (Echo/%/AE%[!Pos.Y!;!Pos.X!H!red!%/AE%[7m !Off!) Else Echo/%/AE%[!Pos.Y!;!Pos.X!H%/AE%[!II!;2;!RR!;!GG!;!BB!m!CHAR!!Off!
rem // Ensure Character not written to file unintentionally, prevent duplicate cell positions to improve animation speed
	If /I "!Draw[%Draw%]!"=="On" If Not "!Key!"=="" (
	REM	Call :DelCell Paint & REM Improves animation speed at the expense of Draw speed.
		>>"!Painting[%Load#%]!" Echo/%/AE%[!Pos.Y!;!Pos.X!H%/AE%[!II!;2;!RR!;!GG!;!BB!m!CHAR!!Off!
	)
	If /I Not "!key!"=="k" Set Key=
	Set "CpalMod="& rem // used to indicate a change has been made to custom palette and trigger save of the new palette.
	For %%V in (0 !Pal#!) Do For /L %%# in (1,1,8) Do For /F "Tokens=3,5,7 Delims==," %%i in ('Set PALcol[%%V][%%#') Do (set "PAL[%%V][%%#]=%/AE%[!II!;2;%%i;%%j;%%km%%#")
	For %%V in (0 !Pal#!) Do For /L %%# in (1,1,8) Do Set "Palette[%%V]=!Palette[%%V]!!PAL[%%V][%%#]!"
	Echo/%/AE%[!Info1!;1H%/AE%[K Move:            !yellow!◄ ▲ ▼ ►!Off!     Select Color:!PosCol! !red!R!Off!:!RR! !green!G!Off!:!GG! !blue!B!Off!:!BB! !Yellow!0!Off!/!Yellow!9!Off! Palette:{!yellow!▲PAGE▼!Off!}     !Palette[%Pal#%]!!Off! {Shift FG:!Yellow!P!Off! [!Aqua!1!Off!-!Aqua!4!Off!,!Aqua!6!Off!-!Aqua!9!Off!]}
	Echo/%/AE%[!Info2!;1H%/AE%[K Change Symbol:  {!yellow!C!Off!:%/AE%[!II!;2;!RR!;!GG!;!BB!m!CHAR!!Off! [!Aqua!0-9!Off!]}  Symbol Set: {!yellow!X!Off! [!Aqua!!CHARSETSMIN!-!CHARSETSMAX!!Off!]} %/AE%[!II!;2;!RR!;!GG!;!BB!m!CharacterSet!!Off! Edit Palette {Pick:!yellow!HOME!Off! !Palette[0]!!Off! Save:!yellow!ENTER!Off!}
	Echo/%/AE%[!Info3!;1H%/AE%[K Invert Color:    !yellow!I!Off!:!II! Change Color Intensity: !yellow!+!Off!/!yellow!-!Off! !red!Exit:!yellow!ESC!Off! {!green!^<^<!yellow!Tab!Off! Image:!Aqua!!CFN#! !yellow!Space!green!^>^>!Off!} Copy:!yellow!Insert!Off! {Draw:!Yellow!End!Aqua! !Draw[%Draw%]!!Off!}
	%GetKey%
	For %%E in (!Errorlevel!) Do Set "Key=!%%E!"
	IF Not "!Key!" == "" %PAINT%{!Key!}
	IF Not "!Key!" == "" If "!CpalMod!" == "1" (
		(For /F "Delims=" %%V in ('Set PalCol[0][') Do Echo/Set %%V)>"%PalDir%\Palette[0].bat"
		>>"%PalDir%\Palette[0].bat" Echo/Exit /B
	)
Goto :PaintStuff

Re: VT code Batch Paint

Posted: 20 Jun 2020 10:38
by Jer
My O/S is Windows 10 64bit. Any idea about these errors, displayed with echo on?
Font is set to Consolas 16.
C:\Temp\DOSBatch>Set /A Max.Width= ( CurrentHorizontalResolution / ( Font.W * SF ) )
Divide by zero error.

C:\Temp\DOSBatch>Set /A Max.hieght= ( ( CurrentVerticalResolution / Font.H ) / SF ) - 4
Divide by zero error.
Jerry

Re: VT code Batch Paint

Posted: 20 Jun 2020 10:48
by T3RRY
My very first guess would be you've copied and pasted the code as opposed to downloading the full script.

The program uses a collection of external .exe's to gather information to calculate scaling of screen size. If those .exe's aren't present, the program will return those errors as the values for those critical variables will not be assigned.

I've edited the OP to make the download requirement clearer

Re: VT code Batch Paint

Posted: 20 Jun 2020 11:44
by Jer
Supporting files were required. That was the solution. Thanks. :)

Re: VT code Batch Paint

Posted: 20 Jun 2020 12:01
by T3RRY
Good to hear it's all sorted.
Currently in the process of building in an editable color palette for quick selection - Let me know if there's other features you'd like to see.

Re: VT code Batch Paint

Posted: 20 Jun 2020 12:06
by Kvc
Nice work

Re: VT code Batch Paint

Posted: 22 Jun 2020 08:51
by T3RRY
Significant enhancements made, NOT Compatible with original Archive - Archive and Download link updated for version 2.2
See the Features in Bold in the OP for the highlights

Re: VT code Batch Paint

Posted: 25 Jun 2020 15:08
by T3RRY
T3RRY wrote:
22 Jun 2020 08:51
Significant enhancements made, NOT Compatible with original Archive - Archive and Download link updated for version 2.2
See the Features in Bold in the OP for the highlights
New Component Program added to the Archive: Animate.bat

With version 2.3, I've split the canvas and the painting into seperate objects, allowing just the 'bits' of the painting to be used very cleanly for animations. To further capatilise on this I've built a script that recalculates the position of each each 'bit' contained in the painting along a given Direction (N E S W NE NW SE SW). This script allows the painting to be 'moved around' the screen, independent of the canvas.

The below script is significantly more verbose than it's counterpart in the archive, as it accounts for potential spaces in the filepath, enacts screen wrapping, and ensures there's no modification to color code values that match either the X or Y position during the String Search and replace operation - As well as remaining in the animator script until user exits the animation

With the aid of this utility, you clone an 'image', enter the animator, shift it's position, exit animator, clone , rinse, repeat, with the freedom to also modify each frame.

If you use Painter.bat to make batch games or animations, I would love to see your results.
If anyone has the patience to coach me through what maths would be involved in rotating an Image, please Pm me
Never mind the above, I've figured out the maths needed, Next step is building a routine to efficiently calculate the mid X & Y points for the Image anchorpoint; plus come up with a faster means of calculating Sin(a) and Cos(a) values than I'm currently using. Once that's sorted, object rotation will be added the the Animation menu

Below script updated with Mirror and rotation functions.

I did toy around with Sin / Cos based rotation for any given angle, but it proved somewhat beyond my current abilities to account for distortion resulting from having to round off decimal numbers (Not to mention much, much slower).
As such, I opted for a simpler 90 degree rotation that switches X /Y positions for each cell (using the appropriate MidX/Y values to anchor the image - the lowest X or Y position present in the image), and a similar approach to Mirroring cells along the centre X axis. The combination of the two functions combines to enable 90/180/270/360 rotation and horizontal / vertical mirroring.


** Animate.bat **

Code: Select all

@echo Off & Setlocal EnableDelayedExpansion
rem // Important usage notes:
rem    mirror, flip and rotate functions DO NOT enact screen wrapping.
rem    mirror(X) and flip(Y) functions will result in movement in the event the relevent Axis is of an even length.
rem    movement will always be towards the axis 0 point. Use of Mirror / Flip with bits present at 0,0 is rejected to prevent image destruction
	Set "RenFile=Ren NewAnim.sav #.sav"
	If "%~1" == "" (
		Endlocal
		Echo/Mode Required. [/D] : Draw [/C] : Game Controller
		Pause & Exit /B 1
	)
	If "!%~2!"=="" (
		Endlocal
		Echo/File Path Required for Arg 2
		Pause &	Exit /B 1
	)
	PUSHD "%~dp0"
	If not Exist "!%~2!" (
		POPD & Endlocal
		Echo/Path Supplied Does not match existing file.
		Pause &	Exit /B 1
	)
	Set "Mode=%~1"
	Set "Mode=!Mode:~1,1!"
	Set "Input=!%~2!" & REM In both usage modes, Arg two is the Foremost layer to be repositioned
	If /I "!Mode!"=="D" (Goto :Prep)
	If /I Not "!Mode!"=="C" (Echo/Invalid Switch & Pause & exit /B)
	Call :Controller %*
Exit /B
:Controller {From args 2 onwards, Args are to be paired as Follows: [Variable containing Filepath] [Action:1 2 3 4 5 6 7 8 9 M F]}
Rem Shift Args For each object or frame to be animated
	If "%~1"=="" POPD & Exit /B
	If /I "%~1"=="/C" Shift
	For %%x in (1 2 3 4 5 6 7 8 9 M F) Do (If /I "%~1"=="%%x" (Set "Argtype=Action") Else (Set "Argtype=Filepath"))
	If "!ArgType!"=="Filepath" (
		Set "Input=!%~1!"
		For %%I in ("!input!") Do (
		PUSHD "%%~dpI"
		Set "Input=%%~nxI"
		)
		Set "Action=%~2"
		IF /I "!Action!"=="/T" (Type "!Input!" & POPD & Endlocal & Exit /B)
		Call :Dir!Action! "!Input!" || (Echo/ Parameter Mismatch: Missing animation switch For File !Input! & POPD & Pause & Exit /B 1)
		Del /Q "!Input!" || (Echo Delete Error & Pause & Exit /B 1)
		%RenFile:#.sav=!Input!%
		Type "!Input!"
		POPD
		Echo/%/AE%[0;0H
		SHIFT
		SHIFT
	) Else (
	Shift
	)
Goto :Controller
:Prep
	CLS
	Type "%Paintings%\Canvas_!H.Max!.dat" || (Echo Canvas Load Error & Pause) & rem // Display Canvas
	Type "!Input!"
	CD "%Paintings%"
	Set "Grouped=Off"
	Set ActvLYR=1
:animateloop
	TITLE %ProgName% Change Image Position and Orientation:
	Echo/%/AE%[0;0H%/AE%[38;2;255;255;255m%/AE%[7m%/AE%[K%/AE%[0m
	Type "%Paintings%\Canvas_!H.Max!.dat" || (Echo Canvas Load Error & Pause) & rem // Display Canvas
	Echo/Animation Options: [ Move: !yellow!1 2 3 4 6 7 8 9!Off! ] [Rotate: !yellow!5!Off! Mirror: !yellow!M / F!Off! ]
	Echo/Select Layers:!Yellow!Insert!Off! Grouping: [!Yellow!G!Off! !Green!%Grouped%!Off!] Active Layer: !Magenta!!Input!!Off! !Aqua!Exit!Off! animator: !yellow!E!Off!
	Echo/%/AE%[0;0H
	For /L %%I in (0,1,!LYR#!) Do Type "!Layer[%%I]!"
:KeyWait
	Set OptKey=
	%GetString%
	For %%E in (!Errorlevel!) Do Set "OptKey=!%%E!"
	If /I "!OptKey!"=="E" (POPD & Endlocal & Exit /B 0)
	Set KeySel=
	For %%K in (1 2 3 4 5 6 7 8 9 G M F ESC Tab Insert) Do (

		If /I "!OptKey!"=="%%K" (
			Set "OptKey=%%K"
			Set "KeySel=1"
		)
	)
	If /I "!OptKey!"=="ESC" EXIT
	If /I "!OptKey!"=="G" (If "!Grouped!"=="Off" (Set "Grouped=On") Else (Set "Grouped=Off")) & Goto :AnimateLoop
	If /I "!OptKey!"=="Tab" (
	    For /F "Tokens=1,2 Delims==" %%G In ('Set Layer[') Do (
	        Echo/"%%H" | Findstr "!Input!" >Nul 2>Nul && (For /F "Tokens=1 Delims=[]" %%i in ("%%G") Do Set / A "ActvLYR=%%~i")
	        If Not !ActvLYR! GEQ !LYR#! (Set /A "ActvLYR+=1") Else (Set /A "ActvLYR=1")
	        For /F "Delims=" %%O in ("!ActvLYR!") Do If not "!Layer[%%~O]!" == "" Call :ChangeLayer "!Layer[%%~O]!"
	    )>Nul 2>Nul
	    CLS
	    Goto :AnimateLoop
	)
	If /I "!OptKey!"=="Insert" (
	Call :Layer
	CLS
	Goto :AnimateLoop
	)
	If "!KeySel!" == "1" (
		If "!Grouped!"=="On" (
		    For /L %%i in (1,1,!LYR#!) Do (
		    Call :Dir!OptKey! "!Layer[%%i]!"
		    Call :Cleanup "!Layer[%%i]!"
		)
		Goto :animateloop
		) Else (For %%F in ("!Input!") Do Call :Dir!OptKey! "%%~nxF")
	) Else (Goto :KeyWait)
	Del /Q "!Input!" || (Echo Delete Error & Pause)
	For %%F in ("!Input!") Do Set "RenFile=Ren NewAnim.sav %%~nxF"
	%RenFile% || (Echo/"%RenFile%" **Error** & Pause)
Goto :animateloop
:Cleanup
	Set "RenFile=Ren NewAnim.sav %~nx1"
	Del /Q "%~1" || (Echo Delete Error & Pause)
	%RenFile% || (Echo/"%RenFile%" **Error** & Pause)
Exit /B
::: *********************************** Animation Subroutines ***********************************
:Layer
TITLE Enter Layer Name:
Set LayerID=
Set StrLen=0
Call :GetName
PUSHD "%Paintings%"
REM Set LYR#=0
For %%I in (!LayerID!*.sav) Do If exist "%%~nxI" (
	CLS
	TYPE "%%~nxI"
	TITLE Add Layer to project [A] Next [N]
	For /F "Delims=" %%O in ('Choice /N /C:AN') Do If /I "%%O"=="A" Call :AddLayer "%%~nxI"
)
POPD
Exit /B
:ChangeLayer
	Set "Input=%~1"
	Set "Painting[%Load#%]=%~dp1"
	Set "ProjectLayers=!ProjectLayers:{%~1}=!"
	Set "ProjectLayers=!ProjectLayers!{%~1}"
Exit /B
:AddLayer
	Set "ProjectLayers=!ProjectLayers:{%~1}=!"
	Set "ProjectLayers=!ProjectLayers!{%~1}"
For /F "Delims={}" %%C in ("!ProjectLayers!") Do (
	Set /A "LYR#+=1"
	Set "Layer[!LYR#!]=%~1"
	Set "Painting[%Load#%]=%~dp1"
	Set "Input=%~1"
)
Exit /B
:GetName
%GetString%
For %%F in (!Errorlevel!) Do (
	If /I "!%%F!"=="Enter" Exit /B
	If /I Not "!%%F!"=="BackSpace" (
		Set /A StrLen+=1
		(If Not "!%%F!"=="" (Echo/"!%%F!" | Findstr /R "[a-zA-Z0-9]" && Set "LayerID=!LayerID!!%%F!"))>Nul
		Set "LayerID=!LayerID:Space=-!"
		Set "LayerID=!LayerID:_=-!"
	) Else (
		Set /A StrLen-=1
		For %%L in (!StrLen!) Do Set "LayerID=!LayerID:~0,%%L!"
	)
)
TITLE Enter Layer Name: !LayerID!
Goto :GetName
:Dir1
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B+1,N.Yo=%%B"
		If !N.Y! GEQ !H.Max! Set "N.Y=1"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V-1"
		If !N.X! LEQ 0 Set "N.X=!W.Max!"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir2
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B+1,N.Yo=%%B"
		If !N.Y! GEQ !H.Max! Set "N.Y=1"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V"
		If !N.X! LEQ 0 Set "N.X=!W.Max!"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir3
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B+1,N.Yo=%%B"
		If !N.Y! GEQ !H.Max! Set "N.Y=1"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V+1"
		If !N.X! GEQ !W.Max! Set "N.X=1"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir4
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B,N.Yo=%%B"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V-1"
		If !N.X! LEQ 0 Set "N.X=!W.Max!"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir6
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B,N.Yo=%%B"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V+1"
		If !N.X! GEQ !W.Max! Set "N.X=1"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir7
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B-1,N.Yo=%%B"
		If !N.Y! LEQ 0 Set "N.Y=!H.Max!"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V-1"
		If !N.X! LEQ 0 Set "N.X=!W.Max!"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir8
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B-1,N.Yo=%%B"
		If !N.Y! LEQ 0 Set "N.Y=!H.Max!"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir9
(For /F "UsebackQ Delims=" %%A in ("%~1") Do (
	Set New=
	Set "Orig=%%A"
	For /F "Tokens=2 Delims=[;" %%B in ("%%A") Do (
		Set /A "N.Y=%%B-1,N.Yo=%%B"
		If !N.Y! LEQ 0 Set "N.Y=!H.Max!"
	)
	For /F "Tokens=2 Delims=;H" %%V in ("%%A") Do (
		Set /A "N.X=%%V+1"
		If !N.X! GEQ !W.Max! Set "N.X=1"
		For %%Y in (!N.Y!) Do For %%U in (!N.Yo!) Do For %%X in (!N.X!) Do Set "New=!Orig:[%%U;%%VH=[%%Y;%%XH!"
	)
	Echo/!New!
	)
)>"NewAnim.sav"
Exit /B
:Dir5
	Set /A midX=500,midY=500
	For /F "UsebackQ Delims=" %%A in ("%~1") Do (
		For /F "Tokens=2 Delims=[;" %%Y in ("%%A") Do Set /A "oY=%%~Y"
		For /F "Tokens=2 Delims=;H" %%X in ("%%A") Do Set /A "oX=%%~X"
		If !oY! LSS !midY! Set /A "midY=!oY!"
		If !oX! LSS !midX! Set /A "midX=!oX!"
	)
    (For /F "UsebackQ Delims=" %%A in ("%~1") Do (
		Set "Orig=%%A"
		For /F "Tokens=2 Delims=[;" %%Y in ("%%A") Do For /F "Tokens=2 Delims=;H" %%X in ("%%A") Do (
			Set /A "N.Y=(%%X-midX)+midY,N.X=(%%Y-midY)+midX"
			For %%y in (!N.Y!) Do For %%x in (!N.X!) Do Set "New=!Orig:[%%~Y;%%~XH=[%%~y;%%~xH!"
		)
		Echo/!New!
	)
    )>"NewAnim.sav"
Exit /B
:DirM
	Set /A lmidX=500,umidX=0
	For /F "UsebackQ Delims=" %%A in ("%~1") Do (
		For /F "Tokens=2 Delims=;H" %%X in ("%%A") Do Set /A "oX=%%~X"
		If !oX! LSS !lmidX! Set /A "lmidX=!oX!"
		If !oX! GTR !umidX! Set /A "umidX=!oX!"
	)
	Set /A Mid.X=( !lmidX! + !umidX! ) / 2
	If !lmidX! LEQ 1 (
		(For /F "UsebackQ Delims=" %%A in ("%~1") Do Echo/%%~A)>"NewAnim.Sav"
		Exit /B
	)
    (For /F "UsebackQ Delims=" %%A in ("%~1") Do (
		Set "Orig=%%A"
		For /F "Tokens=2 Delims=[;" %%Y in ("%%A") Do Set "oY=%%Y"
		For /F "Tokens=2 Delims=;H" %%X in ("%%A") Do (
			Set /A "N.X=%%X,oX=%%X"
			IF !N.X! LSS !Mid.X! (Set /A "N.X= %%X + ((!Mid.X!-%%X) * 2)")
			IF !N.X! GTR !Mid.X! (Set /A "N.X= %%X - ((%%X-!Mid.X!) * 2)")
		)
		For %%y in (!oY!) Do For %%x in (!oX!) Do For %%V in (!N.X!) Do Set "New=!Orig:[%%~y;%%~xH=[%%~y;%%~VH!"
		Echo/!New!
	)
    )>"NewAnim.sav"
Exit /B
:DirF
	Set "Source=%~1"
	Set /A lmidY=500,umidY=0
	For /F "UsebackQ Delims=" %%A in ("!Source!") Do (
		For /F "Tokens=2 Delims=[;" %%Y in ("%%A") Do Set /A "oY=%%Y"
		If !oY! LSS !lmidY! Set /A "lmidY=!oY!"
		If !oY! GTR !umidY! Set /A "umidY=!oY!"
	)
	Set /A Mid.Y=( !lmidY! + !umidY! ) / 2
	If !lmidY! LEQ 1 (
		(For /F "UsebackQ Delims=" %%A in ("!Source!") Do Echo/%%~A)>"NewAnim.Sav"
		Exit /B
	)
    (For /F "UsebackQ Delims=" %%A in ("!Source!") Do (
		Set "Orig=%%A"
		For /F "Tokens=2 Delims=;H" %%X in ("%%A") Do Set "oX=%%X"
		For /F "Tokens=2 Delims=[;" %%Y in ("%%A") Do (
			Set /A "N.Y=%%Y,oY=%%Y"
			IF !N.Y! LSS !Mid.Y! (Set /A "N.Y= %%Y + ((!Mid.Y!-%%Y) * 2)")
			IF !N.Y! GTR !Mid.Y! (Set /A "N.Y= %%Y - ((%%Y-!Mid.Y!) * 2)")
		)
		For %%x in (!oX!) Do For %%y in (!oY!) Do For %%V in (!N.Y!) Do Set "New=!Orig:[%%~y;%%~xH=[%%~V;%%~xH!"
		Echo/!New!
	)
    )>"NewAnim.sav"
Exit /B

Re: VT code Batch Paint

Posted: 27 Jun 2020 13:01
by T3RRY
How many of you out there would like the option to name object files ('painting's) in program, simplifying the production of Projects?
Or to be able to use the Animate.bat subscript to select and load in mulitple objects and build up layered Animations, with the ability to independently adjust objects, and a mechanism to tab through and reposition/edit the currently loaded layers?

It wouldn't take much to build in these capabilities, I'm just wondering if there's anyone who'd be interested in having them in order to be able to quickly develop graphical batch games / animations?

** Coming soon:

Named projects (all files sharing the same name quick selectable.)
Layers - display and adjust independent layers in animator, layer merging

With regards to layers, the approach I'm currently considering, which will only be available in animator.bat:
  • 'insert' key to initiate user input, define layer name from existing objects, display available object numbers (file) for selection
    'active' and 'passive' layer variables.
    active layer will be / become painting[%Load#%]
    passive layers will be all other SELECTED project images, As a LIST, structuring layer changes as follows:
    On selection of a new Active layer, substring modification will strip the file from the list (If present) and append
    it to the end of the list, ensuring it is typed to con last during for loop over list contents.
    ? A restriction on the number of layers (10), allowing for quick selection with keys 0-9 and list index# extraction technique.
    Once 10 layer limit is reached, the Active layer will be replaced with any new layer.
    Only the active layer will be adjustable.

Re: VT code Paint & Animation Studio

Posted: 06 Jul 2020 14:01
by T3RRY
Layer support now added! Load objects from different projects into the animator by pressing INSERT when in Animate mode to select objects to load. Switch between loaded objects (Layers) using TAB while in animate mode. The active layer is retained as the Editable Object when returning to paint mode.

Code For Painter.bat and Animate.bat have both been updated, as has the Archive download link.

How layer selction works:
In animate mode, Press 'Insert'.
Type in the name of an existing object from your current or previous projects.
Each object with the entered name will be displayed: Press 'A' to add the object to the layer group, or 'N' to skip Object/s.

Objects from different Projects may be added to the Same Layer Group.

Let me know If you'd like to see more Layers options Ie: Merge, Clear Layers, Layer association via a Save / Load of layer groups

08/07/2020
Layer 'Grouping' added to Animate.bat, Info Panel updated to display Layer controls, Grouping status and filename of active layer

Re: Paint & Animation Studio

Posted: 29 Aug 2021 08:40
by IcarusLives
Is %getString% never defined? Cannot seem to locate it. Just trying to read through the code to see why it's not functioning for me.

Re: Paint & Animation Studio

Posted: 01 Sep 2021 04:38
by T3RRY
IcarusLives wrote:
29 Aug 2021 08:40
Is %getString% never defined? Cannot seem to locate it. Just trying to read through the code to see why it's not functioning for me.
If you haven't downloaded the archive from the download link, GetString will not be defined, as the definition only occurs if GetKey.exe is in a subfolder of the programs parent folder.

Sorry to say at the time I wrote this I wasn't properly in the habit of verifying the presence of resources and notifying users of deficiencies.