ANSI "movie" mod for RedMixer 3/15/09 WTN (updated 6/4/09) ========================================== This is a fun mod - it adds code that periodically dumps a RedMixer soup to a file in ANSI form, so when the file is displayed in a terminal that understands ANSI it shows an animation of the evolution process. Under Linux the output ANSI file can be displayed using the cat command. The Cygwin environment permits using cat to view ANSI files under Windows. Windows XP can directly display ANSI files provided ansi.sys is installed by adding the following line to the [Windows]\system32\CONFIG.NT file... device=%SystemRoot%\system32\ansi.sys (but first make sure there is an ansi.sys file in the system32 directory) For more memory my CONFIG.NT file contains... dos=high, umb device=%SystemRoot%\system32\himem.sys device=%SystemRoot%\system32\ansi.sys files=40 Afterwards, the command 'command /c type filename.ans' (without the quotes) should directly display an ansi file (assumed to have an .ans extension), provided the supplied filename is a dos-compatible short name. To view any ANSI file by double-clicking it then some trickery is needed to convert the long quoted name passed by Windows to a short name dos understands, ended up with the following batch file... :: typefile.bat - displays file in a dos window (WinXP etc) :: if ansi.sys installed in config.nt then displays ansi file :: when "run" by associating .ans files with this batch @echo off for %%a in (%1) do set file=%%~sa command /c type %file% pause > nul Associate .ans files with typefile.bat, seems to work fine with WinXP SP3. To end a "movie" early without complaints press control-C then any key. If all else fails a fairly trivial program can be used, as the format of the mod output is quite simple using only [H, [0m and [a;xxm where a is either 0 or 1 and xx is a color from 30 to 37. An example written in QBasic is provided after the mod code. ANSI colors are different than QBasic colors but I didn't want to bloat the mod with conversion, it doesn't really matter and memory is tight, especially if using a dos pmarsv program and/or running interpreted in QBasic. The mod adds a few items to the redmixer.ini file... ; ANSI movie settings... enablemovie no ;set to yes to enable ansi movie acshift 0 ;offset for all ansi colors axcadjust 45 ;multiplier for 2nd species field aycadjust 1 ;multiplier for 1st species field frameinterval 5000 ;number of battles between frames ansifile redmixer.ans ;ansi output file (appends) Set enablemovie to yes to enable outputting ANSI frames to the file specified after the ansifile setting. Frame interval specifies how many battles to do between each frame save. 5000 is conservative, for more fine-grained action (and faster file growth) set lower. 100 is quite animated but quickly generates megabytes of ANSI data. The color scheme is controlled by acshift, axcadjust and aycadjust, the defaults are guesses, looks pretty close to me. Not all the settings need to be present, all that's really needed for existing INI files is add enablemovie, frameinterval and ansifile. Note... there is no error-checking of the values, if a nonsense filename is entered or omitted a file error will occur. Misadjustment of the color variables will just make bad colors, but be careful not to set frameinterval too low or omit the value or it will quickly fill up available disk space. For safety keep it on a ram disk but for really big movies and if you promise to keep track of disk space a path can be added to point ansifile to a hard disk directory. As usual, presented as-is without warrantee, for folks who know at least a little bit about what they're doing. The following code was tested applied to the RedMixer 1.0d version (the latest at the time of this writing), provided RedMixer program structure doesn't drastically change it should apply to future versions. The mod consists of four segments which have to be copy/pasted into the indicated locations within the redmixer.bas program code. 6/4/09 - Modified to be FreeBasic-compatible by adding STR$() around prints in section 3, and commenting the RESUME in section 4. This code has not been tested yet, should be OK... Note - if applying to the QBasic version uncomment the RESUME in section 4. REM ***** ANSI Movie Mod ***** 3/3/09 WTN *************** REM Section 1 - this segment goes in the variable section REM place before the line "ON ERROR GOTO noinifile" enablemovie = 0 'if not 0 output ANSI frames acshift = 0 'offset for ANSI colors axcadjust = 45 'multiplier for X coordinate aycadjust = 1 'multiplier for Y coordinate frameinterval& = 5000 'number of battles between frames ansifile$ = "redmixer.ans" 'output file for ANSI movie (appends) ansicount& = 0 'variable used for counting battles REM ***** end section 1 of ANSI Movie Mod *************** REM ***** ANSI Movie Mod ***** 3/3/09 WTN *************** REM Section 2 - this segment goes in the INI read section REM after last "IF tag$ =" and before "WEND". IF tag$ = "enablemovie" THEN IF LCASE$(item$) = "yes" THEN enablemovie = 1 ELSE enablemovie = 0 END IF IF tag$ = "acshift" THEN acshift = VAL(item$) IF tag$ = "axcadjust" THEN axcadjust = VAL(item$) IF tag$ = "axyadjust" THEN aycadjust = VAL(item$) IF tag$ = "frameinterval" THEN frameinterval& = VAL(item$) IF tag$ = "ansifile" AND LEN(item$) > 0 THEN ansifile$ = item$ REM ***** end section 2 of ANSI Movie Mod *************** REM *** ANSI Movie Mod *** 3/3/09 WTN ** FB mod 6/4/09 ** REM Section 3 - this segment goes in the INI write section REM before the line PRINT #2, "; end of parameters" PRINT #2, "; ANSI movie settings..." PRINT #2, "enablemovie "; IF enablemovie THEN PRINT #2, "yes"; ELSE PRINT #2, "no "; PRINT #2, " ;set to yes to enable ansi movie" PRINT #2, "acshift "; STR$(acshift); PRINT #2, " ;offset for all ansi colors" PRINT #2, "axcadjust "; STR$(axcadjust); PRINT #2, " ;multiplier for 2nd species field" PRINT #2, "aycadjust "; STR$(aycadjust); PRINT #2, " ;multiplier for 1st species field" PRINT #2, "frameinterval "; STR$(frameinterval&); PRINT #2, " ;number of battles between frames" PRINT #2, "ansifile "; ansifile$; PRINT #2, " ;ansi output file (appends)" REM ***** end section 3 of ANSI Movie Mod *************** REM *** ANSI Movie Mod *** 3/3/09 WTN ** FB mod 6/4/09 ** REM Section 4 - this segment goes at the end of the main loop REM right before "GOTO mainloop" (after spacer ***********'s) IF enablemovie THEN ansicount& = ansicount& + 1 IF ansicount& > frameinterval& THEN ansicount& = 0 ON ERROR GOTO ansierror OPEN ansifile$ FOR APPEND AS #3 ON ERROR GOTO fileerror PRINT #3, CHR$(27); "[H."; FOR i = 1 TO xsize: PRINT #3, "-"; : NEXT i PRINT #3, "." FOR y = 1 TO ysize PRINT #3, "|"; FOR x = 1 TO xsize species$ = "00_00": warlen = 0 yn$ = RIGHT$("0" + LTRIM$(RTRIM$(STR$(y))), 2) xn$ = RIGHT$("0" + LTRIM$(RTRIM$(STR$(x))), 2) f$ = soupdir$ + "\" + yn$ + "_" + xn$ + ".red" ON ERROR GOTO ansinowarrior OPEN f$ FOR INPUT AS #1 ON ERROR GOTO fileerror WHILE NOT EOF(1) LINE INPUT #1, a$ IF LEFT$(a$, 9) = ";species " THEN species$ = MID$(a$, 10) IF MID$(a$, 4, 1) = "." THEN warlen = warlen + 1 WEND CLOSE #1 yc = VAL(LEFT$(species$, 2)) xc = VAL(MID$(species$, 4, 2)) ansicolor = ((acshift + yc * aycadjust + xc * axcadjust) MOD 14) + 31 s = warlen: char$ = CHR$(126) IF s > 0 AND s < 10 THEN char$ = CHR$(s + 48) IF s > 9 AND s < 36 THEN char$ = CHR$(s + 55) IF s > 35 AND s < 62 THEN char$ = CHR$(s + 61) IF s > 61 AND s < 77 THEN char$ = CHR$(s - 29) IF s > 76 AND s < 84 THEN char$ = CHR$(s - 19) IF s > 83 AND s < 87 THEN char$ = CHR$(s + 39) writeansichar: PRINT #3, CHR$(27); "["; IF ansicolor > 37 THEN PRINT #3, "1;"; : ansicolor = ansicolor - 8 ELSE PRINT #3, "0;"; END IF PRINT #3, LTRIM$(RTRIM$(STR$(ansicolor))); "m"; PRINT #3, char$; NEXT x PRINT #3, CHR$(27); "[0m"; "|" NEXT y PRINT #3, "`"; FOR i = 1 TO xsize: PRINT #3, "-"; : NEXT i PRINT #3, "'" CLOSE #3 GOTO donewithansi REM spaghetti-code error-handling... ansinowarrior: 'RESUME ansinw1 'uncomment for QBasic ansinw1: char$ = " " ansicolor = 37 ON ERROR GOTO fileerror GOTO writeansichar ansierror: CLOSE : PRINT : PRINT "Error opening ANSI file": SYSTEM donewithansi: END IF END IF REM ***** end section 4 of ANSI Movie Mod *************** Section 1 is added to the other default variable sets. Section 2 goes in the part that reads the INI file. Section 3 goes in the part that writes a default INI file if one isn't found. Section 4 goes at the end of the main loop and where the action is, the other sections are just to feed it variables. Simple ANSI viewer.... If ANSI-challenged perhaps this code can help. For now it's meant only for viewing the output of the mod and only supports a very limited subset of ANSI commands, essentially forground color sets, default colors and home. If compiled with FirstBasic etc can use command-line parameters to specify the loop and delay options and the filename, remove the REM the line containing: c$ = COMMAND$ ------- begin file SHOWANSI.BAS ------------------------------------- REM display a redmixer ansi movie 3/3/09 WTN REM not designed for any other type ansi file, REM supports only the sequence output by the movie mod. REM Comment next line if interpreted, uncomment if compiled REM c$ = COMMAND$ c$ = LTRIM$(RTRIM$(c$)) doloops = 0: framedelay = 0: filename$ = "" IF c$ = "" THEN LINE INPUT "RedMixer ANSI file: "; filename$ filename$ = LTRIM$(RTRIM$(filename$)) IF filename$ = "" GOTO done LINE INPUT "Frame delay number: "; answer$ framedelay = VAL(answer$) LINE INPUT "Loop? (Y/N) "; answer$ IF LTRIM$(UCASE$(answer$)) = "Y" THEN doloops = 1 ELSE IF LCASE$(c$) = "help" OR c$ = "/?" THEN PRINT "Simple ANSI viewer for viewing RedMixer 'movies'" PRINT "Usage: SHOWANSI [LOOP] [DELAY:n] FILENAME" PRINT "The LOOP option repeats the file until a key is pressed" PRINT "The DELAY:n option delays by n (a number) between frames" GOTO done ELSE spacepos = INSTR(c$, " ") WHILE spacepos clopt$ = LCASE$(LEFT$(c$, spacepos - 1)) c$ = LTRIM$(MID$(c$, spacepos + 1)) spacepos = INSTR(c$, " ") IF clopt$ = "loop" THEN doloops = 1 IF LEFT$(clopt$, 6) = "delay:" THEN framedelay = VAL(MID$(clopt$, 7)) END IF WEND filename$ = c$ END IF END IF IF filename$ = "" GOTO done IF INSTR(filename$, " ") THEN PRINT "Spaces not allowed, this is dos." GOTO done END IF CLS ON ERROR GOTO badfile showfile: OPEN filename$ FOR INPUT AS #1 keypressed = 0 WHILE NOT EOF(1) AND keypressed = 0 LINE INPUT #1, fileline$ linepos = 0: linelen = LEN(fileline$) WHILE linepos < linelen linepos = linepos + 1 char$ = MID$(fileline$, linepos, 1) IF char$ = CHR$(27) THEN linepos = linepos + 2 'skip [ attr$ = MID$(fileline$, linepos, 1) IF attr$ = "H" THEN LOCATE 1, 1 'home IF framedelay THEN FOR z = 0 TO framedelay FOR z2 = 1 TO 1000: NEXT z2 NEXT z END IF ELSE brite = 0: IF attr$ = "1" THEN brite = 1 linepos = linepos + 1 IF MID$(fileline$, linepos, 1) = "m" THEN COLOR 7 ELSE ansi = VAL(MID$(fileline$, linepos + 1, 2)) linepos = linepos + 3 'skip 2-digit color code and m qcolor = 7 'default if unrecognized IF ansi = 30 THEN qcolor = 0 IF ansi = 31 THEN qcolor = 4 IF ansi = 32 THEN qcolor = 2 IF ansi = 33 THEN qcolor = 6 IF ansi = 34 THEN qcolor = 1 IF ansi = 35 THEN qcolor = 5 IF ansi = 36 THEN qcolor = 3 IF ansi = 37 THEN qcolor = 7 IF brite THEN qcolor = qcolor + 8 COLOR qcolor END IF END IF ELSE PRINT char$; END IF WEND PRINT IF INKEY$ <> "" THEN keypressed = 1 WEND CLOSE #1 IF doloops AND keypressed = 0 GOTO showfile LOCATE 24, 1 GOTO done badfile: PRINT "Error." done: SYSTEM ------- end of SHOWANSI.BAS file ------------------------------------ That's it for this fun little evolver mod. If anyone needs compiled .exe's for the modified RedMixer or SHOWANSI program let me know. ------------------------------------------ Terry Newton (wtn90125 at yahoo.com)