Page 8 of 8

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 28 Jun 2019 14:32
by misol101
Aacini wrote:
28 Jun 2019 12:15
Wow! The writing of text is fantastic! This remembers me my old method to write text in pixel mode. Where do you get the definition of the raster fonts, so you can read them?
Glad you like it!

If you clone the git repo (link in first post), you will find a file called cmdfonts.h, which contains all the data necessary for the 10 raster fonts. It is embedded in cmdgfx_gdi.exe and cmdgfx_RGB.exe. On page 3 of this thread I have posted some C code showing how to use (one of) the font data arrays in cmdfonts.h.

The data itself (if I remember correctly) was retrieved using a combo of a batch script (to write characters in ASCII order at the top of the cmd line), a screengrab tool (to save the text as bitmap), ImageMagick to print out the pixels in the bitmap as text data, and a little C code to organize the data into 1-bit-per-pixel data arrays (finally producing cmdfonts.h)

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 03 Feb 2020 17:08
by misol101
Stability update to version 1.5.

Wasn't planning on updating this, but then my WIndows 10 started mis-behaving, because I can no longer open a cmd.com window without it hanging! The only fix I found was to enable legacy console mode (some info at https://www.guidingtech.com/cant-type-in-cmd-error/)

Then I noticed that in legacy mode it was no longer possible to exit fullscreen from my scripts , and it also annoyed me that screensaver scripts did not cover the entire screen (taskbar still visible). So, for v1.5 we have these changes:

1. Fix of cmdwiz fullscreen op for legacy mode
2. Complete fullscreen also for legacy mode for all fullscreen scripts, plus proof-of-concept for Ctrl-Enter for windowed script RGB-Balls2.bat (another method used in RGB-Balls3.bat, and RGB-Balls.bat without fullscreen, just restoring size/position)
3. Image op: allow setting width/height as a single percentage value (aspect ratio corrected)
4. Bug fix: buffer range check for block when using new width and height
5. Added geq and leq to block expressions
6. If frame split into several stages with "n" flag, any error messages are now shown as expected

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 08 Feb 2020 21:45
by DQ2000
There are mistakes when approaching sprites a lot and then moving them away is no longer formed.

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 09 Feb 2020 03:20
by misol101
DQ2000 wrote:
08 Feb 2020 21:45
There are mistakes when approaching sprites a lot and then moving them away is no longer formed.
Ok, can you give an example? (of a line that does not work as expected?). Do you know if this worked in earlier versions?

Or, PM me the code of yours that doesn’t work as expected.

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 19 May 2020 17:26
by scavenger
this is positively awesome!

is it possible to render a jpeg and let user type in the console after it or does cmdwiz and the other programs render only in full command window?

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 19 May 2020 20:00
by scavenger
never mind.
cannot print jpeg, only 16 colors pcx
command is:

Code: Select all

cmdgfx_vt "image whatever.pcx 0 0 O -1 0,0 0 0"

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 20 May 2020 02:39
by misol101
scavenger wrote:
19 May 2020 20:00
never mind.
cannot print jpeg, only 16 colors pcx
command is:

Code: Select all

cmdgfx_vt "image whatever.pcx 0 0 O -1 0,0 0 0"
Hi scavenger, that is (partly) incorrect: cmdgfx_VT and cmdgfx_RGB can print full color BMP images:

cmdgfx_vt "image whatever.bmp 0 0 O -1 0,0”

However you are correct that it doesn’t support JPG. Use your favorite image editor or converter to turn the JPG images you need into BMP before using them. If you need to do it on-the-fly, use ImageMagick from command line/script to convert the JPG into BMP, then delete the file once the script/command is finished.

The full list of file types supported by ”image” (as well as for textures) is: BMP(32 bit), PCX(actually 256 color but only 16 first colors used), BXY (internal cmdgfx_RGB/VT full-color image which also saves the background color and character at each position), GXY (as BXY, but supports 16 color only and is in human-readable text format), TXT

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 20 May 2020 03:59
by misol101
This script can be used to show any jpg file in the command line once ImageMagick is installed:

Code: Select all

@echo off & setlocal
if "%~1"=="" echo Error: no input. Usage: showjpg file.jpg [x] [y] [char] [xFlip] [yFlip]& goto :eof
if not "%~x1"==".jpg" echo Error: not a jpg file& goto :eof
if not exist %1 echo Error: no such file& goto :eof
set fileName=tempImage.bmp
set /a xPos=0 & if not "%~2"=="" set /a xPos=%~2
set /a yPos=0 & if not "%~3"=="" set /a yPos=%~3
set char=0 & if not "%~4"=="" set char=%~4
magick convert %1 %fileName%

cmdwiz setcursorpos 0 0 & cmdwiz getconsoledim w
set /a W=%errorlevel%-2 & for /F "tokens=2,4" %%a in ('cmdwiz gxyinfo %fileName%') do set /a H=%%b
cmdgfx_VT "image %fileName% 0 0 %char% -1 %xPos%,%yPos% %5 %6" pf:0,0,%W%,%H%

del /Q %fileName%>nul 2>nul
endlocal
Use like:

Code: Select all

::shows jpg at 0,0 with character 0
showjpg file.jpg

::shows jpg at 5,5 with character k
showjpg file.jpg 5 5 k

::shows jpg at 0,0 with whatever character is there at the moment
cls & type someFile.txt
showjpg file.jpg 0 0 ?

::shows jpg at 0,0 with hex character B1 and flipped in both x and y
showjpg file.jpg 0 0 b1 1 1
If you want to print the image relative to the current cursor position, remove this in the script: cmdwiz setcursorpos 0 0

Note that displaying the image with cmdgfx_RGB is a LOT faster than cmdgfx_VT. Replace the 3 lines ending with a call to cmdgfx_VT in the script with:

Code: Select all

for /F "tokens=2,4" %%a in ('cmdwiz gxyinfo %fileName%') do set /a W=%%a,H=%%b
cmdgfx_RGB "image %fileName% 0 0 %char% -1 %xPos%,%yPos% %5 %6" Kf0:0,0,%W%,%H%p
However it has a number of drawbacks, like:
1.Can only use 10 raster fonts or pixel fonts, and need to specify which one
2.On Windows10, image disappears after being shown when not running as server (due to Windows removing all bitmap content after a call is finished). Because of this I use the K flag here to wait for keypress before image is removed
3.No characters are actually put in the buffer (and there is no concept of a buffer at all, like scrolling etc)
On the plus side:
1. It is MUCH faster (on my machine around 200(!) times faster. Try putting VT-Texture-Cube-Rough.bat and RGB-Texture-Cube.bat next to each other and compare...)
2. Unlike cmdgfx_VT, it works in Windows versions earlier than Windows 10, and it also works in the legacy console in Windows 10
3. You can (easily) use pixel fonts. Change f0 to fa in call to cmdgfx_RGB to try that. (cmdgfx_VT could also use pixel fonts if you use carlos pixelfnt.exe program first to set a pixel font in the current cmd window)

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 21 May 2020 20:57
by scavenger
awesome

what i want to do is use part of cmdgfx to print pictures/animations during installer batches i write
i already have a solution that involves printing windows 8-10 colors with spaces and preset ascii art converted pictures but, well, too much work

image magick is indeed the solution but then you also need to resize it to fit the command window. I think i can will make it with static pictures but how do you do with animations?
i tried and opened most of the batch given as examples in cmdgfx i downloaded and for the life of me, I can't understand how they work. it looks like some variables are set then the script calls itself and magically, stuff that is echo'ed becomes commands?

how an i write an interactive menu like the one i posted with the ludicrous refresh rate offered by cmdgfx??

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 22 May 2020 09:38
by misol101
scavenger wrote:
21 May 2020 20:57

1. image magick is indeed the solution but then you also need to resize it to fit the command window.

2. I think i can will make it with static pictures but how do you do with animations?

3. i tried and opened most of the batch given as examples in cmdgfx i downloaded and for the life of me, I can't understand how they work. it looks like some variables are set then the script calls itself and magically, stuff that is echo'ed becomes commands?

4. how an i write an interactive menu like the one i posted with the ludicrous refresh rate offered by cmdgfx??
Let me try to address that.

1. Resizing the image can be done with the image operation itself with its last parameter(s), e.g.:

Code: Select all

::for simplicity, first make sure cmd window is a set size without scroll bars
mode 100,50

::draw image resized to width 60 and height 20. Not aspect ratio corrected
cmdgfx_vt "image whatever.bmp 0 0 O -1 0,0 0 0 60,20”

::draw image at 33% of its original size. Aspect ratio corrected
cmdgfx_vt "image whatever.bmp 0 0 O -1 0,0 0 0 33”

::get the console window's width and height, then draw the image to cover the entire area 
cmdwiz getconsoledim sw
set consW=%errorlevel%
cmdwiz getconsoledim sh
set consH=%errorlevel%
cmdgfx_vt "image whatever.bmp 0 0 O -1 0,0 0 0 %consW%,%consH%”

::it is also possible to draw the image so that it covers the entire width of the console, while maintaining aspect ratio in height, or vice versa
::it is slightly complicated, but let me know if you would like to know how. (I should perhaps add a new cmdgfx option to do this automatically) 

2. Animations get a bit trickier, especially if you need typed input, like with set /p. Basically this is not possible because set /p blocks, so you would have to roll your own input function in that case, or use some awkward solution such as opening a new window for typed input.
If you are ok with making a choice by pressing a single key or navigating between choices with cursor keys then it's doable.

3. Hmm, yes :) In order to get "ludicrous refresh rate", and also, stable refresh rate, cmdgfx should be run as server, in which case it typically sits as the last layer in a pipe chain, like this: cmdgfx_input -> batch_script -> cmdgfx. Hence the batch script echoes commands to cmdgfx to do the drawing (and cmdgfx_input sends key/mouse event info to the batch script)

But actually in many cases it's ok to run without server(s). The main issue is without server you really have little control over how fast the animation runs (could be too slow or too fast depending on various factors of your system). But often it works ok.

For info, here is a minimal script just to show how a cmdgfx server is setup. It animates a single ellipse.

Code: Select all

@echo off
setlocal
if not defined _ (
	mode 40,42
	set _=.
	cmdgfx_input.exe knW20 | call %0 %* | cmdgfx_VT "" S
	goto :eof
)
set /a size=0

:rep
	set /a size+=1
	if %size% gtr 20 set /a size=1
	echo "cmdgfx: fbox 7 0 20 & fellipse 9 0 K 20,20,%size%,%size%" F

	set /p input=
	for /f "tokens=1,2,4,6" %%a in ("%input%") do ( set /a key=%%d )
if not %key% == 27 goto rep

echo "cmdgfx: quit"
title input:Q
endlocal
The line where the "magic " happens is: cmdgfx_input.exe knW20 | call %0 %* | cmdgfx_VT "" S
First we start cmdgfx_input and say that we want to listen to key events (the "k" flag), that we want to send non-events to drive the animation if there are no key events (the "n" flag), and that we want to send these events at a rate of one for every 20 ms (the "W20" flag) (which means we aim for an FPS of 1000/20=50 FPS)
Then the script calls itself (but when it is run the second time it will pass this part of the code, because _ has been set)
Finally cmdgfx_VT is started last in the pipe chain, with option "S", which means stay running as server, don't quit, and take commands via echo from the batch script

These lines get the input events from cmdgx_input: set /p input= for /f "tokens=1,2,4,6" %%a in ("%input%") do ( set /a key=%%d ) Why ”set/p”, didn’t I just write set /p won’t work with cmdgfx and animations? True, but here we don’t use it to get input from the user, we use it to get input data from cmdgfx_input, sent over the pipe.

Perhaps this made using a cmdgfx server somewhat clearer, atleast the script is a decent starting point to tinker with. Also, try running cmdgfx_input on its own in command line to understand the output it produces, e.g "cmdgfx_input k", then start pressing some keys :)


4. Not sure which menu you posted about or how it looks (link?), but let me show some examples in the next post.

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 22 May 2020 10:35
by misol101
I will focus mostly on making interactive menus *without* using a server, as it is significantly simpler and possibly good enough.

I am using an image (img\123.bmp) that is in the cmdgfx archive, so it should be possible to run these scripts straight from the cmdgfx folder if you create them there.

Example 1:

Code: Select all

@echo off
setlocal
cmdwiz setfont 2 & cls & mode 41,50

set /a size=1
set text=_The_menu:\n\n1._Option_A\n2._Option_B\n3._Option_C\n\c0Esc._\rCancel

:rep
	set /a size+=1
	if %size% gtr 40 set /a size=1
	set /a xp=20-size/2, yp=20-size/2
	cmdgfx_VT "fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size% & text 7 0 0 %text% 15,41" k

	set /a key=%errorlevel%

	if %key% == 27 set /a choice=0, stop=1
	if %key% geq 49 if %key% leq 51 set /a choice=%key%-48, stop=1
if not defined stop goto rep

cls & echo Your choice was %choice%
cmdwiz getch
endlocal
This creates the following menu, with an animated image (by size):
Image

Ok, what to say about this script? :)

1. I force a fixed size of the console window and set a specific font (raster font 2). Especially the latter part is not at all necessary. However the first part, forcing a size and removing scroll bars, typically makes things easier to deal with

2. I prepare a text which is used to print the menu by the "text" operation. _ must be used instead of spaces, \n means new line, \c0 means use foreground color c(12), background color 0, \r means use previous color

3. In the loop, we calculate the size of the image and where we should put it, then call cmdgfx_VT with the "k" flag, which means it should return a key code if a key press was made

4. "fbox" is used to clear the buffer, then "image" is used with resizing to draw the image, and finally "text" prints the text we prepared earlier

5. If we pressed escape (key code 27), then exit with choice 0, if we pressed key 1-3 exit with choice 1-3. How to get these key codes? There are basically two ways: Either run "getchloop.bat" in the cmdgfx folder, start pressing keys of interest and note down their numbers, OR look up "decimal Ascii table" on google (however, for special keys like cursor keys etc you will still need to run getchloop.bat)

6. Finally we print the choice



Example 2: a variant of the previous script where we use cursor keys and Return to select a choice.

Code: Select all

@echo off
setlocal
cmdwiz setfont 2 & cls & mode 41,50

set /a size=1, pos=0, nofchoice=3
set text=The_menu:\n\nOption_A\nOption_B\nOption_C\n\n\c0Esc=Cancel

:rep
	set /a size+=1
	if %size% gtr 40 set /a size=1
	set /a xp=20-size/2, yp=20-size/2, barpos=pos+43
	cmdgfx_VT "fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size% & text 7 0 0 %text% 16,41 & line f 9 ? 14,%barpos%,25,%barpos%" k

	set /a key=%errorlevel%

	if %key% == 27 set /a choice=0, stop=1
	if %key% == 328 set /a pos-=1
	if %key% == 336 set /a pos+=1
	if %key% == 13 set /a choice=pos+1, stop=1
	if %pos% lss 0 set /a pos=%nofchoice%-1
	if %pos% geq %nofchoice% set /a pos=0
	set /a key=0
if not defined stop goto rep

cls & echo Your choice was %choice%
cmdwiz getch
endlocal
Image

There actually isn't that much to say about it as it is quite similar, but we use a little trick to draw the "selected" choice: line f 9 ? 14,%barpos%,25,%barpos% . Here we draw a line with white text color and blue background, but use ? to mean that whatever text is currently in the buffer should not be changed, only the colors.


Example 3: As example 1, but this is just to show that we can mix the output of cmdgfx_VT with text previously put in the buffer. In this case we must specify the position/size of the cmdgfx buffer, as it normally uses the entire cmd window buffer (even the parts off-sceen, hence why it's good to have a fixed console size and no scrollbars)

Code: Select all

@echo off
setlocal
cmdwiz setfont 2 & cls & mode 41,50

set /a size=1
cmdwiz setcursorpos 0 41
echo My menu: & echo. & echo 1. Option A & echo 2. Option B & echo 3. Option C & echo Esc. Cancel

:rep
	set /a size+=1
	if %size% gtr 40 set /a size=1
	set /a xp=20-size/2, yp=20-size/2
	cmdgfx_VT "fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size%" kf:0,0,41,41

	set /a key=%errorlevel%

	if %key% == 27 set /a choice=0, stop=1
	if %key% geq 49 if %key% leq 51 set /a choice=%key%-48, stop=1
if not defined stop goto rep

cls & echo Your choice was %choice%
cmdwiz getch
endlocal
Notable things:
1. we start by using normal echo commands to put the menu text on screen without cmdgfx
2. In the call to cmdgfx, we specify flag "f:0,0,41,41" to say that the buffer should be put as position 0,0 with width 41 and height 41 (leaving lines 42-50 free for our previously echoed text)


Finally, example 4, which is like example 2, except it runs cmdgfx as server:

Code: Select all

@echo off
setlocal
if not defined _ (
	cmdwiz setfont 2 & cls & mode 41,50
	set _=.
	cmdgfx_input.exe knW20 | call %0 %* | cmdgfx_VT "" S
	set _=
)
if not defined _ set /p choice=<tempFile
if not defined _ cls & echo Your choice was %choice% & cmdwiz getch & goto :eof

set /a size=1, pos=0
set text=The_menu:\n\nOption_A\nOption_B\nOption_C\n\n\c0Esc=Cancel

:rep
	set /a size+=1
	if %size% gtr 40 set /a size=1
	set /a xp=20-size/2, yp=20-size/2, barpos=pos+43
	echo "cmdgfx: fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size% & text 7 0 0 %text% 16,41 & line f 9 ? 14,%barpos%,25,%barpos%" F

	set /p input=
	for /f "tokens=1,2,4,6" %%a in ("%input%") do ( set ev_base=%%a & set /a key=%%d )

	if %key% == 27 set /a choice=0, stop=1
	if %key% == 328 set /a pos-=1
	if %key% == 336 set /a pos+=1
	if %key% == 13 set /a choice=pos+1, stop=1
	if %pos% lss 0 set /a pos=2
	if %pos% geq 3 set /a pos=0
	set /a key=0
if not defined stop goto rep

echo "cmdgfx: quit"
title input:Q
echo %choice% >tempFile
endlocal
The structure is similar to the minimal server example in my previous post.

Notable:
Since we call the script a second time from the pipe chain, we can't get the user's choice through a variable once we return. Instead, I write the choice to a temporary file which is then read by the calling script.


In all these examples we can replace cmdgfx_VT with cmdgfx_RGB for faster output. In this case we also need to specify f2 as a flag in the call, or else cmdgfx_RGB will use its default, raster font 6.
In the (last) server example, this will work fine.
In the non-server examples though, we get a pretty horrible flicker (unless running a legacy console). Why? Because as I mentioned in my previous post, Windows 10 clears any bitmaps from the console after a command finishes! However when we run as server, cmdgfx does not quit until the entire script finishes.


For simplicity, I didn't use delayed expansion in these examples, and I used a standard goto for the loop. To speed things up, most of the cmdgfx example scripts actually typically have this loop structure instead:

Code: Select all

setlocal EnableDelayedExpansion
:REP
for /l %%1 in (1,1,300) do if not defined STOP (
...code using delayed expansion
)
if not defined STOP goto REP


instead of simply:
:REP
...code not using delayed expansion
if not defined STOP goto REP

Re: Cmdgfx - draw 3d and graphic primitives (polygons,circles etc) in cmd window (now with 24-bit RGB support!)

Posted: 28 May 2020 11:48
by misol101
Well, hope that was helpful.

Just a follow-up because I realized I forgot about another method of achieving a high(er) frame rate without cmdgfx server: using start /B to run cmdgfx. Unfortunately it doesn't work well with cmdgfx_VT because it results in concurrent access, leading to possible screen artifacts. It does work well with cmdgfx_RGB though (and we can avoid the flicker this way)

Also, just for fun I added 9 different animation effects to the menu (accessible by pressing keys 0-9), all achieved using the block operation with expressions.
Effects are stuff like rotation, waving, color changing, adding noise etc.

Image

Here is the cmdgfx_VT version:

Code: Select all

@echo off
setlocal EnableDelayedExpansion
cmdwiz setfont 2 & cls & mode 41,50 & cmdwiz showcursor 0

set /a count=1, count2=0, pos=0, nofchoice=3, rad=0, FX=0, delta=1, key=0
set text=The_menu:\n\nOption_A\nOption_B\nOption_C\n\n\c00-9_:_FX

:rep
for /l %%1 in (1,1,300) do if not defined stop (
	set /a count+=delta, count2+=1
	if !count! gtr 39 set /a delta=-1
	if !count! lss 2 set /a delta=1
	set /a "xp=20-count/2, yp=20-count/2, barpos=pos+43, shade=(40-count)*-7, size=count"
	
	set SFX=""
	if !FX! == 1 set /a size=40,xp=0,yp=0 & set SFX="shade(fgcol(x,y),!shade!,!shade!,!shade!)"
	if !FX! == 2 set SFX="- store(!count2!/12,0)+(x-20)*cos(s0)-(y-20)*sin(s0)+20 (y-20)*cos(s0)+(x-20)*sin(s0)+20 from"
	if !FX! == 3 set /a size=40,xp=0,yp=0 & set SFX="- store(!count2!/12,0)+(x-20)*cos(s0)-(y-20)*sin(s0)+20 (y-20)*cos(s0)+(x-20)*sin(s0)+20 from"
	if !FX! == 4 set /a size=40,xp=0,yp=0 & set SFX="fgcol(x,y)*leq(y,!count!)+fgcol(x,!count!)*gtr(y,!count!)"
	if !FX! == 5 set /a size=40,xp=0,yp=0 & set SFX="- sin((x+!count2!/2)/10)*20+20 cos(y/15-!count2!/16)*(15+sin(!count2!/6)*5)+20 from"
	if !FX! == 6 set /a size=36,xp=2,yp=2 & set SFX="- x+sin((x/100+y/2+!count2!/1.8)/3)*6+1 y+0 from"
	if !FX! == 7 set /a size=40,xp=0,yp=0 & set SFX="store(fgcol(x,y),0)+makecol255(fgr(s0)*(1+!count!/20),fgg(s0),fgb(s0)*(1+!count!/60))"
	if !FX! == 8 set /a size=40,xp=0,yp=0 & set SFX="store(fgcol(x,y),0)+store(!count!/40,1)+store(1-s1,2)+makecol(fgr(s0)*s1,fgg(s0)*s1,fgb(s0)*s1)+makecol(fgr(s0)*s2,fgr(s0)*s2,fgr(s0)*s2)"
	if !FX! == 9 set /a size=40,xp=0,yp=0 & set SFX="store(random()*70-10,0)+store(fgcol(x,y),1)+shade(s1,s0,s0,s0)"

	cmdgfx_VT "fbox 7 0 20 0,0,40,40 & image img/123.bmp 0 0 0 -1 !xp!,!yp! 0 0 !size!,!size! & block 0 0,0,41,41 0,0 -1 0 0 - !SFX:~1,-1! & text 7 0 0 %text% 16,41 & line f 9 ? 14,!barpos!,25,!barpos!" k

	set /a key=!errorlevel!

	if !key! == 27 set /a choice=0, stop=1
	if !key! == 328 set /a pos-=1
	if !key! == 336 set /a pos+=1
	if !key! == 13 set /a choice=pos+1, stop=1
	
	if !key! geq 48 if !key! leq 57 set /a FX=!key!-48
	
	if !pos! lss 0 set /a pos=!nofchoice!-1
	if !pos! geq !nofchoice! set /a pos=0
	set /a key=0
	)
)
if not defined stop goto rep

cmdwiz delay 100
cls & echo Your choice was !choice!

cmdwiz getch
cmdwiz showcursor 1
endlocal
And here is the (much faster) cmdgfx_RGB version:

Code: Select all

@echo off
setlocal EnableDelayedExpansion
cmdwiz setfont 2 & cls & mode 41,50 & cmdwiz showcursor 0

set /a count=1, count2=0, pos=0, nofchoice=3, rad=0, FX=0, delta=1, key=0
set text=The_menu:\n\nOption_A\nOption_B\nOption_C\n\n\c00-9_:_FX

set t1=!time: =0!
:rep
for /l %%1 in (1,1,300) do if not defined stop (
	for /f "tokens=1-8 delims=:.," %%a in ("!t1!:!time: =0!") do set /a "a=((((1%%e-1%%a)*60)+1%%f-1%%b)*6000+1%%g%%h-1%%c%%d),a+=(a>>31)&8640000"
	if !a! geq 2 (

		set /a count+=delta, count2+=1
		if !count! gtr 39 set /a delta=-1
		if !count! lss 2 set /a delta=1
		set /a "xp=20-count/2, yp=20-count/2, barpos=pos+43, shade=(40-count)*-7, size=count"
		
		set SFX=""
		if !FX! == 1 set /a size=40,xp=0,yp=0 & set SFX="shade(fgcol(x,y),!shade!,!shade!,!shade!)"
		if !FX! == 2 set SFX="- store(!count2!/12,0)+(x-20)*cos(s0)-(y-20)*sin(s0)+20 (y-20)*cos(s0)+(x-20)*sin(s0)+20 from"
		if !FX! == 3 set /a size=40,xp=0,yp=0 & set SFX="- store(!count2!/12,0)+(x-20)*cos(s0)-(y-20)*sin(s0)+20 (y-20)*cos(s0)+(x-20)*sin(s0)+20 from"
		if !FX! == 4 set /a size=40,xp=0,yp=0 & set SFX="fgcol(x,y)*leq(y,!count!)+fgcol(x,!count!)*gtr(y,!count!)"
		if !FX! == 5 set /a size=40,xp=0,yp=0 & set SFX="- sin((x+!count2!/2)/10)*20+20 cos(y/15-!count2!/16)*(15+sin(!count2!/6)*5)+20 from"
		if !FX! == 6 set /a size=36,xp=2,yp=2 & set SFX="- x+sin((x/100+y/2+!count2!/1.8)/3)*6+1 y+0 from"
		if !FX! == 7 set /a size=40,xp=0,yp=0 & set SFX="store(fgcol(x,y),0)+makecol255(fgr(s0)*(1+!count!/20),fgg(s0),fgb(s0)*(1+!count!/60))"
		if !FX! == 8 set /a size=40,xp=0,yp=0 & set SFX="store(fgcol(x,y),0)+store(!count!/40,1)+store(1-s1,2)+makecol(fgr(s0)*s1,fgg(s0)*s1,fgb(s0)*s1)+makecol(fgr(s0)*s2,fgr(s0)*s2,fgr(s0)*s2)"
		if !FX! == 9 set SFX="store(random()*70-10,0)+store(fgcol(x,y),1)+shade(s1,s0,s0,s0)"

		start "" /B /High cmdgfx_RGB "fbox 0 0 db 0,0,40,40 & image img/123.bmp 0 0 0 -1 !xp!,!yp! 0 0 !size!,!size! & block 0 0,0,41,41 0,0 -1 0 0 - !SFX:~1,-1! & text 7 0 0 %text% 16,41 & line f 9 ? 14,!barpos!,25,!barpos!" kOf2

		if exist EL.dat set /p KEY=<EL.dat 2>nul & del /Q EL.dat >nul 2>nul & if "!KEY!" == "" set KEY=0

		if !key! == 27 set /a choice=0, stop=1
		if !key! == 328 set /a pos-=1
		if !key! == 336 set /a pos+=1
		if !key! == 13 set /a choice=pos+1, stop=1
		
		if !key! geq 48 if !key! leq 57 set /a FX=!key!-48
		
		if !pos! lss 0 set /a pos=!nofchoice!-1
		if !pos! geq !nofchoice! set /a pos=0
		set /a key=0
		set t1=!time: =0!
	)
)
if not defined stop goto rep

cmdwiz delay 100 & cmdgfx_RGB "" & cmdgfx_VT ""
 
cls & echo Your choice was !choice!

cmdwiz getch
cmdwiz showcursor 1
endlocal
Notable things:
1. Uses start /B to run cmdgfx_RGB, specifying the O flag to say that cmdgfx_RGB should write to a file (called EL.dat) if any key presses were made (we cannot get keys through the errorlevel since start /B runs separately). This is why we look for the existence of EL.dat later in the script and read it.

2. It uses einstein1969's time-elapse macro to check how many cs that has passed since last update. If it is 2 or more a new call with start /B is made. Hopefully this should land us somewhere close to 50 fps without using a server.