0

I am currently trying to make a simple choice RPG game that will have a lot of dialogue, and i want the dialogue to appear in different colors, but also share the same screen (like a chat room, if you will"), for a while, the code i've found in This video has helped me a lot, but i quickly ran into a problem, i can't seem to write special characters like !?'*^<>,. and they are essential in dialogue, anyone knows of a way i can come around this problem? using "^" before each character didn't work, maybe changing the code would help?

@echo off
MODE 60,20
title Mage's Adventure 
color 0F
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
goto :SplashScreen

:ColorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof

:SplashScreen
cls
call :ColorText 0B "Welcome!, Welcome^!"
pause>nul
Cosmo
  • 1
  • 1
  • Welcome to stack overflow! Could you write a [minimal, complete, verifiable example](https://stackoverflow.com/help/mcve)? Here that would involve one line of code that you expect to print some dialogue with a special character, the output you're getting, and the output you expect. – De Novo Mar 18 '18 at 01:31
  • Please edit the body of your question, and use [the appropriate formatting](https://meta.stackexchange.com/help/formatting) – De Novo Mar 18 '18 at 01:50
  • edited the post to include the code because i am still new here so i don't know how to add code on comments, sorry about that – Cosmo Mar 18 '18 at 01:58
  • It's good that you edited your post because you can't add code to comments. – SomethingDark Mar 18 '18 at 02:05
  • @SomethingDark You can always comment on your own question, just not on others. – De Novo Mar 18 '18 at 02:13
  • 2
    Possible duplicate of [Can't get the ä, ç, or ã to print correctly using colorEcho in batch](https://stackoverflow.com/questions/49307854/cant-get-the-%c3%a4-%c3%a7-or-%c3%a3-to-print-correctly-using-colorecho-in-batch) – Squashman Mar 18 '18 at 02:37
  • @DanHall - I mean larges amount of code (anything over a single line) do not display properly in comments. – SomethingDark Mar 18 '18 at 03:15

1 Answers1

1

There are a couple solutions.


carlos' color v23c

Playing around with it it has some strange outputs. Test using

call :color 04 "Test poison '&|<>!()" \n
call :color 06 ""
call :color 0A " can be printed if you use empty strings" \n

produced (german console):

">" kann syntaktisch an dieser Stelle nicht verarbeitet werden.

" can be printed if you use empty strings

it produces some major errors sometimes and is a bit slow...


VT100 alternative (Win10+)

@echo off
for /f "delims=" %%E in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x1B"') do (
    set "ESC=%%E["
)

call :vtEcho 93 "No escaping needed for most characters: '&|<>!()"
call :vtEcho 94 "Problems occur with '^' and '"' though"

:vtEcho   [VT100 colorcode] [message]
<NUL set /P "=%ESC%%1m%~2%ESC%0m"
echo+
exit /B 0

Output:

No escaping needed for most characters: '&|<>!()
Problems occur with '^^' and '"'

So how does this work? Basically echoing using set /P solves almost every poison character, and VT sequences make the color using the color codes. We first generate the ESC character using forfiles and then use it in the function. But since we try to give this as a single flag to a subroutine we need to double quote it... and that means we have problems displaying that. Also set /P can only print single ^ if you make it <NUL set /P^"=^^", which will fail in any other case.

Workaround for " and ^ using flag shifting:

:vtEcho   [VT100 colorcode] [message] [message] [message] ...
:: Use """" for displaying a '"'
:: Use "^" for displaying a '^'
:: Use "\n" to make a new line
<NUL set /P "=%ESC%%1m"
:__vtEcho
shift
if not "%~1" == "" (
    if "%~1" == """" (
        <NUL set /P ^"="""^"
        goto __vtEcho
    )
    if "%~1" == "^^" (
        <NUL set /P ^"=^^"
        goto __vtEcho
    )
    if "%~1" == "\n" (
        echo+
        goto __vtEcho
    )
    <NUL set /P "=%~1"
    goto __vtEcho
)
echo %ESC%0m
exit /B 0

Test with:

call :vtEcho 96 "No problems with '" """" "' and '" "^" "' and has" \n "support for '\n'"`

result in:

No problems with '"' and '^' and has
support for '\n'

To compensate for " and ^ we check the individual parts of the flags if they are their wrong counterpart ("" / ^^) and print the right output instead.

HOWEVER

Using set /P makes it so you cannot start your line with spaces. To do this there is no nice wrapper function. If you dont need that you can use disappearing qoutes:

@echo off
set ""="
for /f "delims=" %%E in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x1B"') do (
    set "BLUE=echo !"!%%E[94m"
    set "CYAN=echo !"!%%E[96m"
    set "END=%%E[0m"
)

setlocal EnableDelayedExpansion
%BLUE%Has no problems with '&|<>" characters%END%
%CYAN%'^^' and "^^!" need to be escaped%END%

Results in:

Has no problems with '&|<>" characters
'^' and "!" need to be escaped

I hope you are able to make something out of this. Thx for reading


References:

Community
  • 1
  • 1
Grub4K
  • 101
  • 6