Gotoxy - advanced color text output and cursor control - now with server!

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
misol101
Posts: 475
Joined: 02 May 2016 18:20

Gotoxy - advanced color text output and cursor control - now with server!

#1 Post by misol101 » 02 May 2016 18:26

Hi everyone, first post here.

Some time ago last year I had a need for a utility to position the cursor and write text in the Windows command prompt. So, instead of properly googling and finding what I needed (I later learned there are several similar programs like bg.exe), I foolishly decided to write my own... Anyway, it grew into a bit more full-featured thing over time, including another utility called cmdwiz, and now has some features that similar programs do not, so I thought I'd share it for some comments.

Download at http://www.mediafire.com/download/8xywd ... gotoxy.zip

Or clone the repo at https://github.com/misol1/gotoxy

There are quite a few batch file examples included, which is good because documentation is severely lacking.

Try running l.bat (a file explorer, inspired by List for DOS), or games.bat or fx.bat and go from there.


Any suggestions and comments welcome, would be interesting to hear of compability/speed on different machines.
Last edited by misol101 on 27 Aug 2020 02:28, edited 4 times in total.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#2 Post by misol101 » 03 May 2016 04:59

Syntax is (same as you get from executing the exes without arguments):

gotoxy.exe

Code: Select all

Usage: gotoxy x(1) y(1) [text|file.gxy] [fgcol(2)] [bgcol(2)] [flags(3)] [wrapxpos]

Cols: 0=Black 1=Blue 2=Green 3=Aqua 4=Red 5=Purple 6=Yellow 7=LGray
      8=Gray 9=LBlue 10=LGreen 11=LAqua 12=LRed 13=LPurple 14=LYellow 15=White

[text] supports control codes:
    \px;y;: cursor position x y (1)
       \xx: fgcol and bgcol in hex, eg \A0 (4)
        \r: restore old color
      \gxx: ascii character in hex
   \TxxXXm: set character xx with col XX as transparent with mode m (5)
        \n: newline
      \Nxx: fill screen with hex character xx
        \-: skip character (transparent)
        \\: print \
        \G: print existing character at position
  \I:file;: insert contents of file
      \wx;: delay x ms
      \Wx;: delay up to x ms
        \K: wait for key press; last key value is returned
        \R: read/refresh buffer for v/V/Z/z/Y/X/\G (faster but not updated)
\ox;y;w;h;: copy/write to offscreen buffer, copy back at end or next \o
\Ox;y;w;h;: clear/write to offscreen buffer, copy back at end or next \O
   \\Mx{T}: repeat T x times (only if 'x' flag set). Use \} to produce } for next run
\Sx;y;w;h;: set active scroll zone (only if 's' flag set)

(1)   Use 'k' to keep current. Precede with '+' or '/' to move from current position
(2)   Use 'u/U' for console fgcol/bgcol, 'v/V' to use existing fgcol/bgcol at current
      position. 'x/y/z/q' and 'X/Y/Z/Q' to xor/and/or/add with fgcol/bgcol at current
      position. Precede with '-' to force color and ignore color codes in [text]
(3)   One or more of: 'r/c/C' to restore/follow/visibly-follow cursor position,
      'w/W/z' to wrap/wordwrap/wrap-0 text, 'i' to ignore all control codes,
      's' to enable vertical scrolling, 'x' to enable support for expressions,
      'n' to ignore newline characters, 'k' to check for key press(es) and return last
      key value, 'S' to enable (and disable) server mode
(4)   Same as (2) for both values, but '-' to force is not supported. In addition, use
      'k' to keep current color, 'H/h' to start/stop forcing current color, '+' for
      next color, '/' for previous color
(5)   Use 'k' to ignore color, 'u/U' for console fgcol/bgcol. Mode 0 skips characters
      (same as \-), mode 1 writes them back (faster if using \R)     
gotoxy_extended.exe

Code: Select all

Separate executable due to lower speed. There are currently two extensions:

1. Control code \L[:xx..;]: check for key xx, yy etc, don't wait; return keystate(s)

2. Correctly prints extended ascii characters as input when written as-is
cmdwiz.exe

Code: Select all

CmdWiz (Unicode) v1.7 : Mikael Sollenborn 2015-2020
With contributions from Steffen Ilhardt and Carlos Montiers Aguilera

Usage: cmdwiz operation [arguments]


Console window: fullscreen getconsoledim getfullscreen getpalette setbuffersize setpalette

Window and display: getdisplaydim getdisplayscale getwindowbounds getwindowstyle setwindowpos setwindowsize setwindowstyle setwindowtransparency showwindow windowlist

Input: flushkeys getch getch_and_mouse getch_or_mouse getkeystate getmouse getquickedit setquickedit

Fonts and buffer: getcharat getcolorat getconsolecolor setfont savefont

Cursor and printing: getcursorpos print setcursorpos showcursor

String and delay: await delay gettime stringfind stringlen

Mouse and keyboard: getmousecursorpos sendkey setmousecursorpos showmousecursor

Block: copyblock inspectblock moveblock saveblock

Misc: cache getexetype gettaskbarinfo gettitle gxyinfo insertbmp playsound server


Use "cmdwiz operation /?" for info on an operation's arguments and return values, for example cmdwiz delay /?

See https://www.dostips.com/forum/viewtopic.php?t=7402 for full documentation.

Simple use of gotoxy:

gotoxy 10 5
Position cursor at column 10, row 5

gotoxy 10 5 "Hello" 10 1
Position cursor at column 10, row 5, print "Hello" with text color 10 and background color 1

gotoxy 10 5 "\M10{Hello World\g21 \+0}" 7 0 x
Print "Hello World!" 10 times in colors 7 and up, 'x' flag to enable expressions

gotoxy 0 0 "\N21\p10;5;\f0H\c4ello\n\e6world\g21\n" 10 1
Print multicolor "Hello world" at column 10, row 5, in a sea of exclamation marks

gotoxy k k watch.gxy 0 0 cs
Print gxy file (a gotoxy string saved in a file) from current cursor position, 'c' flag to follow cursor position, 's' flag to scroll at bottom of screen

gotoxy k k watch.gxy -9 -1 cs
Same as above, force text color 9 and background color 1

etc...
Last edited by misol101 on 23 Aug 2020 03:43, edited 11 times in total.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#3 Post by misol101 » 03 May 2016 05:04

By the way, this is the first time I'm browsing these forums and I must say I'm humbled by what some of you guys can do in the command line with no use of external programs at all! 3d raycasting, that's insane! :)

Anyway, hope this program is still good for something... it's useful to me, anyway...

SirJosh3917
Posts: 36
Joined: 02 May 2016 18:59

Re: Gotoxy

#4 Post by SirJosh3917 » 03 May 2016 06:06

It's amazing what you've done! But one thing...
It takes a while for the batch files to load ( roughly 15 secs for huge ones, 5 for little ones ), but after they've loaded, they're fast.
But if I were to use gotoxy or cmdwiz, I'd like to know all the things you can use it for, because the examples dont clearly show that. It looks like a bunch of for loops, variables, and gibberish.
Code from one of the examples:

Code: Select all

@echo off
setlocal ENABLEDELAYEDEXPANSION
mode con lines=50 cols=80
cmdwiz showcursor 0
cmdwiz quickedit 0
color 07
cls

set CNT=0&for %%a in (00,10,10,10,10,10,80,80,80,80,b0,b0,f0) do set TRAILCOL!CNT!=%%a&set /A CNT+=1
set /a TRAIL_LEN=%CNT%
set /a TRAIL_LEN_M=%CNT%-1
for /L %%a in (0,1,%TRAIL_LEN%) do set TRAILPX%%a=-1&set TRAILPY%%a=-100
set TRAIL_I=0
set STRING=\kk    \gB2\gB0\gDB\gB2\gB0    \n  \gB0\gB0     \gB0\gB0  \n \gB0         \gB0 \n\gB0           \gB2\n\gB2           \gDB\n\gB2           \gB1\n \gB0         \gB0 \n  \gB0\gB2     \gB2\gB0  \n    \gB0\gB2\gB2\gDB\gB0    \n
::set STRING=This string has got a tail...
::set STRING=\kk   ####    \n  #    #  \n  #    #  \n   ####   \n

set DL=0
set DR=0
set KEY=0
set MX=-1&set MY=-100

:LOOP
cmdwiz getch_and_mouse 20
set MR=%ERRORLEVEL%
if %MR%==-1 goto NOINPUT
set SI=0
set /a KEY=(%MR%^>^>21)
set /a MT=%MR% ^& 1 &if !MT! == 0 goto NOINPUT
set /a MT=%MR% ^& 2 &if !MT! geq 1 set DL=1
set /a MT=%MR% ^& 2 &if !MT! equ 0 set DL=0
set /a MT=%MR% ^& 4 &if !MT! geq 1 set DR=1
set /a MT=%MR% ^& 4 &if !MT! equ 0 set DR=0
set /a MT=%MR% ^& 32 &if !MT! geq 1 goto LOOP
set /a MT=%MR% ^& 64 &if !MT! geq 1 goto LOOP
set /a MX=(%MR%^>^>7) ^& 127
set /a MY=(%MR%^>^>14) ^& 127
if %DL% geq 1 rem
if %DR% geq 1 rem

:NOINPUT
set OUT="\O0;0;80;50;\T20kk"
set /a TRAILPX%TRAIL_I%=%MX%-6
set /a TRAILPY%TRAIL_I%=%MY%-4

set TCNT=%TRAIL_I%
set /A TCNT+=1&if !TCNT! geq %TRAIL_LEN% set TCNT=0
for /L %%a in (0,1,%TRAIL_LEN_M%) do for %%b in (!TCNT!) do set OUT="!OUT:~1,-1!\!TRAILCOL%%a!\p!TRAILPX%%b!;!TRAILPY%%b!;%STRING%"&set /A TCNT+=1&if !TCNT! geq %TRAIL_LEN% set TCNT=0

gotoxy 0 0 %OUT% 9 0

set /a TRAIL_I+=1
if %TRAIL_I% geq %TRAIL_LEN% set /a TRAIL_I=0

if not %KEY% == 27 goto LOOP

setlocal
cmdwiz quickedit 1
cmdwiz showcursor 1

Can't understand much but the last part.
The github provides some help, but if you were to make examples that had easy-to-read code, it'd also help.

All in all though, great job!

ShadowThief
Expert
Posts: 1166
Joined: 06 Sep 2013 21:28
Location: Virginia, United States

Re: Gotoxy

#5 Post by ShadowThief » 03 May 2016 08:27

Cool! I've been embedding this Powershell code in any scripts that need cursor manipulation:

Code: Select all

set "pos_cmd=$U=$Host.ui.rawui;$CursorPosition=$U.CursorPosition;"
set "pos_cmd=%pos_cmd%$CursorPosition.X=35;$CursorPosition.Y=2;"
set "pos_cmd=%pos_cmd%$U.CursorPosition=$CursorPosition;"
powershell -command "&{%pos_cmd%}"


but yours seems way more versatile.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#6 Post by misol101 » 03 May 2016 13:02

ShadowThief: yeah it's possible to do a lot of things with gotoxy/cmdwiz actually (including bitwise operations mixing colors etc), but of course it has the disadvantage of being an external tool unlike Powershell.

SirJosh3917: It takes 5-15 seconds for the batch files to load? That's horrible, what Windows version are you running? They run pretty much instantaneously on my machine (Windows 7)

I agree that the documentation is no good/nonexisting... and you also picked one of the more cryptic commands in that example (getch_and_mouse and its siblings), because it returns an int in the errorlevel which has its bits set or not depending on the state of mouse buttons etc. If you're not familiar with operations like bitwise AND and bitwise shifting then it will look very cryptic indeed. On the other hand you could basically just copy/paste the code handling the mouse there and reuse it if you need mouse support for a script.

Here is an explanation for that part of the code:

Code: Select all

cmdwiz getch_and_mouse 20   :: check for key and mouse input, wait maximum 20 ms
set MR=%ERRORLEVEL%          :: result returned in ERRORLEVEL
if %MR%==-1 goto NOINPUT    :: if result was -1 we got no input (ie. we timed out before that)
set /a KEY=(%MR%^>^>21)   :: the key pressed (if any) is contained in the upper part of the result, we need to shift down 21 bits to get it
set /a MT=%MR% ^& 1 &if !MT! == 0 goto NOINPUT  :: if first bit is not set we had no mouse input
set /a MT=%MR% ^& 2 &if !MT! geq 1 set DL=1  :: if second bit is set, left mouse button was pressed
set /a MT=%MR% ^& 2 &if !MT! equ 0 set DL=0  :: if not, then it was not pressed :)
set /a MT=%MR% ^& 4 &if !MT! geq 1 set DR=1  :: if third bit is set, right mouse button was pressed
set /a MT=%MR% ^& 4 &if !MT! equ 0 set DR=0
:: bit 4 and bit 5 are set if left/right mouse button was double-clicked, not checked here
set /a MT=%MR% ^& 32 &if !MT! geq 1 goto LOOP :: bit 6 checks for mouse wheel (up), result is ignored here
set /a MT=%MR% ^& 64 &if !MT! geq 1 goto LOOP :: bit 7 checks for mouse wheel (down), result is ignored here
set /a MX=(%MR%^>^>7) ^& 255  :: the mouse X column are in bits 8-15, shift it down and mask out values above 127
set /a MY=(%MR%^>^>15) ^& 127 :: the mouse Y row are in bits 16-22, shift it down and mask out values above 127
if %DL% geq 1 rem :: in this example pressing left mouse button does nothing, only the mouse coordinates are used
if %DR% geq 1 rem :: right mouse button neither

... use MX and MY, and quit script if escape key (27) was pressed


Actually come to think of it, printing to stdio as output from getch_and_mouse would probably be better, and much less cryptic... seems "ugly" to me though somehow (I guess as a C programmer), having to redirect output to a file and then reading that file and parsing it when you can just return an int... But in this case it was probably the wrong choice (also, in this case, max value for MX and MY are 127... so won't work for big screens... though you can use "getch_or_mouse" instead and get values up to 511... There's another example of that in testmouse.bat.

But apart from the mouse commands (and getkeystate, which uses a similar return strategy), I don't think most cmdwiz commands are too cryptic. Starting from one of the smaller examples like sprite3.bat or transpscroll.bat it should be possible to get started, if you look at the syntax for gotoxy and cmdwiz above at the same time.

Atleast there are no "^don't remove this empty line above!!" lines in my bat files, I'm scratching my head when the batch wizards around here are doing that... magic :mrgreen:
Last edited by misol101 on 16 Jun 2016 16:43, edited 1 time in total.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#7 Post by misol101 » 03 May 2016 13:51

As for the "gibberish", I assume you mean this line:

set STRING=\kk \gB2\gB0\gDB\gB2\gB0 \n \gB0\gB0 \gB0\gB0 \n \gB0 \gB0 \n\gB0 \gB2\n\gB2 \gDB\n\gB2 \gB1\n \gB0 \gB0 \n \gB0\gB2 \gB2\gB0 \n \gB0\gB2\gB2\gDB\gB0 \n

This is simpy copy/pasted "graphics" from a gxy file which I drew and saved in editor.bat (it's the circle drawn when you move the mouse).
So in the prompt you could print this like:
gotoxy 0 0 "\kk \gB2\gB0\gDB\gB2\gB0 \n \gB0\gB0 \gB0\gB0 \n \gB0 \gB0 \n\gB0 \gB2\n\gB2 \gDB\n\gB2 \gB1\n \gB0 \gB0 \n \gB0\gB2 \gB2\gB0 \n \gB0\gB2\gB2\gDB\gB0 \n" 9 0

...and see a blue circle


And this part is the colors used for the circles, going from dark blue (10), to white (f0)

set CNT=0&for %%a in (00,10,10,10,10,10,80,80,80,80,b0,b0,f0) do set TRAILCOL!CNT!=%%a&set /A CNT+=1

...and later used in the for loop to print out all the circles:

for /L %%a in (0,1,%TRAIL_LEN_M%) do for %%b in (!TCNT!) do set OUT="!OUT:~1,-1!\!TRAILCOL%%a!\p!TRAILPX%%b!;!TRAILPY%%b!;%STRING%"&set /A TCNT+=1&if !TCNT! geq %TRAIL_LEN% set TCNT=0

Basically since gotoxy is an external command it takes time every time it's executed so you want to minimize the number of times you call it to once per frame, so that's why I build up a long string first with all the circles and then print it all at once

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#8 Post by misol101 » 04 May 2016 07:03

** Updated link and repo, download again! **

After realizing yesterday how cryptic the ERRORLEVEL output from some cmdwiz functions might seem, I decided to add printed output to the following cmdwiz commands:

getmouse, getch_or_mouse, getch_and_mouse, getkeystate

This means the output should be redirected to >nul if the printed output is not needed (the commands also still return the ERRORLEVEL same as before)

I changed the testmouse2.bat example to parse output instead of ERRORLEVEL. It's hopefully easier to understand:

Code: Select all

cmdwiz getch_and_mouse 20>mouse_out.txt

for /F "tokens=1,3,5,7,9,11,13,15,17,19,21 delims= " %%a in (mouse_out.txt) do set EVENT=%%a&set KEY=%%b&set MOUSE_EVENT=%%c&set NEW_MX=%%d&set NEW_MY=%%e&set LMB=%%f&set RMB=%%g&set LDBL=%%h&set RDBL=%%i&set MWHEEL=%%j
if "%EVENT%"=="NO_EVENT" set KEY=0&goto NOINPUT
if "%MOUSE_EVENT%"=="0" goto NOINPUT
if not "%MWHEEL%"=="0" goto LOOP
set MX=%NEW_MX%&set MY=%NEW_MY%


...where output, if there is a mouse event, looks something like "EVENT KEY_EVENT 0 MOUSE_EVENT 1 MOUSE_X 2 MOUSE_Y 3 LEFT_BUTTON 0 RIGHT_BUTTON 0 LEFT_DOUBLE_CLICK 0 RIGHT_DOUBLE_CLICK 0 MOUSE_WHEEL 0".

It also has the added real advantage of not having a limit for the value of Mouse X and Y coordinates.

If you want to see this in action, try this from the shell (break with ctrl-c):
for /L %a in (1,1,100000) do @cmdwiz getch_and_mouse

Or for getkeystate (checks for pressed state of ctrl,alt,shift and escape):
for /L %a in (1,1,100000) do @cmdwiz getkeystate ctrl alt shift 27

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#9 Post by misol101 » 06 May 2016 04:43

*Links and repo updated again!*

I added the following to gotoxy:

1. Inlining of files in string
2. New transparency mode

Inlining (any file works, not just gxy files):
\I:filename; (note the semicolon)

Example:
gotoxy 10 10 "\I:goomba.gxy;"

Or why not:
gotoxy -16 -13 "\I:circles.gxy;\p10;6;\I:watch.gxy;\p60;5;\M10{\I:hero.gxy;\n}" 1 0 x


New transparency mode:
I don't like this one too much as it's kind of implementation specific, but it does increase speed a lot in certain cases.

\TxxXXm: set character xx with col XX as transparent with mode m

Note the new m option. If m is 0, old mode is used, which skips writing the character if it is the transparent one. In mode 1, the character is instead written back to the screen. Basically this limits the number of calls to the Windows function WriteConsoleOutput (which is veeery slow, actually the main speed hog when trying to do text stuff in cmd line), so it can be faster, but only if the \R code is used (\R creates a copy of the current screen in memory)


Starfield2.bat and the new interference3.bat use both these new features.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#10 Post by misol101 » 10 May 2016 15:38

Apparently Dropbox hates me and shut down downloads due to "heavy traffic" (I'm sure it must have been enormous :roll: ).

All files were moved to Mediafire, sorry if anybody tried to get the files earlier and failed.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Gotoxy

#11 Post by foxidrive » 10 May 2016 16:28

Read here for the likely reason Dropbox did that:

viewtopic.php?f=3&t=7138&view=unread#p46575

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#12 Post by misol101 » 14 May 2016 11:46

Archive and repo were updated. See top for links.

For changes to listb, see viewtopic.php?f=3&t=7147

Key codes are changed for certain keys, following advice from aGerman. See above thread for more info.

Cmdwiz was extended with a new operation called "cache". It takes a path to a text file containing filenames, then simply reads these files without doing nothing. Why? This puts the files in Windows file cache, speeding up later operations with them. Admittedly, it was mostly added for my mov2txt utility (http://www.dostips.com/forum/viewtopic.php?f=3&t=7138), but could be useful for other file operations too.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#13 Post by misol101 » 16 Jun 2016 16:41

Archive and repo were updated, minor change only.

The getch_and_mouse operation of cmdwiz.exe now uses that extra bit that was freed by making the key codes always smaller than 512. This means the x value of the mouse can now be up to 255 instead of 127. To get the key, right shift by 22, to get mouse x right shift by 7 and AND with 255, to get mouse y right shift by 15 and AND with 127.

Also, a classic image fade effect was recently added, you can see it by running fx.bat and starting 'Image'


By the way, I recently ran some of my scripts on a friend's computer where it was really slow. Turns out it was the antivirus running in some kind of sandbox mode, slowing down the execution of my external programs gotoxy.exe and cmdwiz.exe horribly. Turning off the antivirus temporarily speeded things up enormously.

So just in case these things move like syrup, don't blame me, blame your antivirus (probably) :mrgreen:

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#14 Post by misol101 » 28 Jun 2016 08:20

Updated the archive and repo.

Added a new flag, 'n', for gotoxy. If set, gotoxy ignores newline characters in input files.

I realized this could be handy if creating gxy files with 'echo' on the fly in a bat script, because echo adds newlines whether you want to or not.

misol101
Posts: 475
Joined: 02 May 2016 18:20

Re: Gotoxy

#15 Post by misol101 » 05 Jul 2016 20:11

Another archive update.

This time cmdwiz got a new operation called getexetype. This one was stolen with permission from aGerman, and checks what kind of executable a file is (if any). I needed this for the listb explorer.

Also, cmdwiz documentation was improved. Return values are now described along with the arguments if typing "cmdwiz operation", and in the case when an operation doesn't need any arguments to run, it is now possible to write "cmdwiz operation /?" and get the info anyway.

Post Reply