home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
ANSIFUN.ZIP
/
ANSIFUN.CMD
Wrap
OS/2 REXX Batch file
|
1990-09-18
|
17KB
|
523 lines
/************************************************************************
*
* AnsiFun Fun with ANSI escape sequences and REXX.
*
* Programmer: Michael J Antonio (MikeA) 713221.1742@CompuServe.com
*
* A series of general routines for manipulating the OS/2
* screen by means of ANSI graphics. The user must have
* set ANSI ON for this program to work.
*
* This program also shows some interesting features of the REXX
* language, and its usefulness in the OS/2 environment.
*
* Feel free to use this program and share it with your friends.
* If you do any wholesale copying of this code, just mention
* my name in the comments.
*
***********************************************************************/
"@"ECHO OFF
'ANSI ON | RXQUEUE'
'RXQUEUE /clear'
/* TRACE A; /* TRACE R; */ TRACE I */
PARSE ARG length height border
border = strip(border)
IF border = "" THEN
border = 22
Ansi. = ""; Box. = ""
CALL SetAnsi; CALL SetBox
rc=AnsiSay(Ansi.UnWrap)
/* Blank out the screen */
rc=AnsiSay(Ansi.plain || Ansi.cls)
rc=MoveCursor(3,3)
/* There is rather a long pause before the box is drawn. */
rc=Write("Loading program - please wait...")
/* Draw a box */
IF \datatype(length, "W") | length = 0 THEN
length = 75
IF \datatype(height, "W") | height = 0 THEN
height = 20
/* Buffer the box to Ansi.string, write it when it is done */
Ansi.buf = 'on'
rc=DrawBox(1, 1, length, height, border, Ansi.bblack||Ansi.fred, Ansi.bcyan||Ansi.fblue, ' ')
CALL FlushBuf
/* Ego boost time (as if I need it) */
rc=MoveCursor(length-35,height+1)
rc=Write("Ansifun. (C) 1990, Michael Antonio.")
rc=MoveCursor(3,3)
rc=Write("Some fun stuff you can do with ANSI and REXX!")
CALL Wait 1
/* Show off screen I/O stuff. */
rc=MoveCursor(3,5)
rc=AnsiSay(Ansi.plain||Ansi.bold||Ansi.fblue)
rc=Write("Enter your name here:")
foo = GetInfo(25, 5, 25)
rc=MoveCursor(3,7)
rc=AnsiSay(Ansi.plain||Ansi.fmagenta||Ansi.bblack)
rc=Write("Hello ")
rc=AnsiSay(Ansi.blink)
rc=Write(strip(foo))
rc=AnsiSay(Ansi.plain||Ansi.fmagenta||Ansi.bblack)
rc=AnsiSay(", and welcome to the world of ANSI!")
CALL Wait 1
/* Mindless fun */
rc=MoveCursor(3, 9)
rc=AnsiSay(Ansi.plain || Ansi.fred ||Ansi.bold)
rc=Write("This is the world of ANSI"copies( " ", 9)"!")
rc=MoveCursor("<14")
CALL Wait 1
rc=AnsiSay(Ansi.bgreen || Ansi.fmagenta || Ansi.blink)
rc=Write("Extended Ansi")
rc=AnsiSay(Ansi.plain)
rc=MoveCursor("-11")
/* Show off relative line drawing. */
rc=DrawBox(3,12,12,3,Box.shadow,,1,'03'x)
CALL Wait .5
rc=DrawBox(3,12,12,3,12,Ansi.fmagenta)
CALL Wait .5
rc=DrawBox(3,12,12,3,21,Ansi.fgreen)
rc=AnsiSay(Ansi.plain||Ansi.bblue||Ansi.fyellow)
rc=DrawLine(40,15,"-3","-")
rc=DrawLine(40,13,"+3","+")
rc=DrawLine(39,14,"<7","<")
rc=DrawLine(41,14,"7",">")
rc=DrawLine(40,14,">1","*",Ansi.blink||Ansi.rev)
/* Get the cursor out of the way */
rc=MoveCursor(1, 23)
CALL Wait 2
EXIT
/************************************************************************
*
* GetInfo: Prompts the user for information and returns the user
* input to the caller. Prompt is done at screen position
* (oCol, oRow) and the prompt goes for a length of (length)
*
* Unfortunatly, there is nothing to prevent the user from
* typing beyond the end of field.
*
***********************************************************************/
GetInfo: PROCEDURE EXPOSE Ansi.
PARSE ARG oCol, oRow, length
rc=DrawLine(oCol, oRow, length,' ',Ansi.plain)
rc = MoveCursor("<"||length)
input = linein()
RETURN substr(input,1,length,' ')
/************************************************************************
*
* DrawBox: Draws a box to the screen at position (top, left) of
* dimensions (length x height).
*
* A box type may be specified. If (boxType) is a 2 digit
* numeric, then the values in the stem variable (Box.boxType)
* are used. If boxType is a single character, then that
* character is used when drawing the box.
*
* Unless (borderColor) is specified, the current color is
* used to draw the box. A (fillColor) can also be specified,
* or 1 to use the current color. Otherwise, the inside of
* the box is not erased. A (fillChar) may be specified,
* but " " is used as the default.
*
* Some characters are pre-defined in the (Box.) stem
* variable.
*
***********************************************************************/
DrawBox: PROCEDURE EXPOSE Ansi. Box.
PARSE ARG oCol,oRow,length,height,boxType,borderColor,fillColor,fillChar
/* Check parameters */
IF \datatype(height, "W") THEN RETURN 1
IF \datatype(length, "W") THEN RETURN 1
IF \datatype(oCol, "W") THEN oCol = 1
IF \datatype(oRow, "W") THEN oRow = 1
/* Set rectangle of box */
oCol = MAX(oCol, 1)
oRow = MAX(oRow,1)
height = MAX(height,1)
length = MAX(length,1)
/* Position Cursor */
rc=MoveCursor(oCol, oRow)
/* Set box type */
IF boxType = "" THEN
c = 22
ELSE IF length(strip(boxType)) = 2 & datatype(boxType, "W") THEN
c = boxType
ELSE
DO
c = substr(strip(boxType),1,1)
CALL SetBStem c
END
/* Set border color */
IF borderColor <> "" THEN
rc=AnsiSay(borderColor)
/* Draw box top */
rc=Write(Box.c.UpLc || copies(Box.c.HSide, Length) || Box.c.UpRc)
/* Draw box side */
DO Height
rc=MoveCursor("-1", "<"||(Length+2))
rc=Write(Box.c.VSide)
rc=MoveCursor(">"||Length)
rc=Write(Box.c.VSide)
END
/* Draw box Bottom */
rc=MoveCursor("-1", "<"||(Length+2))
rc=Write(Box.c.LoLc || copies(Box.c.HSide, Length) || Box.c.LoRc)
/* If a fill color was specified, fill the box */
IF fillColor <> "" THEN
DO
IF fillColor = 1 THEN
fillColor = borderColor
IF fillChar <> "" THEN
fChar = substr(strip(fillChar),1,1)
ELSE
fChar = " "
rc=AnsiSay(fillColor)
rc=MoveCursor("+"||Height, "<"||(Length+1))
DO i = 1 TO height
rc=Write(copies(fChar, Length))
rc=MoveCursor("-1", "<"||Length)
END
END
RETURN rc
/*************************************************************************
*
* DrawLine: Draws a line to the screen at position (oRow, oCol) for
* a length of (length). It draws in the direction
* indicated by (+-<>) (up, down, left, right). Direction
* should be the first charactor of (length). Right is the
* assumed direction of the line.
*
************************************************************************/
DrawLine: PROCEDURE EXPOSE Ansi.
PARSE ARG oCol, oRow, length, lChar, lColor
IF datatype(oRow, "W") & datatype(oCol, "W") THEN
rc=MoveCursor(oCol, oRow)
length = strip(length)
way = substr(length,1,1)
amount = substr(length,2)
IF Pos(way, Ansi.userTable) = 0 THEN
DO
amount = way||amount
way = ">"
END
IF lChar = "" THEN
lChar = " "
ELSE
lChar = substr(strip(lChar),1,1)
IF lColor <> "" THEN
rc=AnsiSay(lColor)
IF way = ">" THEN
rc=Write(copies(lChar, amount))
IF way = "<" THEN
DO amount
rc=Write(lChar)
rc=MoveCursor("<2")
END
IF way = "-" | way = "+" THEN
DO amount
rc=Write(lChar)
rc=MoveCursor("<1",way"1")
END
RETURN rc
/*************************************************************************
*
* MoveCursor: Moves the cursor around the terminal screen.
* MoveCursor accepts:
*
* 1) Two arguments, designating a colunm and row
*
* 2) A variable number of numeric arguments
* preceded by one of '+-<>' where:
* +n : Move cursor up n lines.
* -n : Move cursor down n lines.
* <n : Move cursor left n columns.
* >n : Move cursor right n columns.
*
* Note: If all cursor movement is done with MoveCursor,
* then MoveCursor will update Ansi.cRow and Ansi.cCol
* and not allow you to write outside the screen.
*
************************************************************************/
MoveCursor: PROCEDURE EXPOSE Ansi.
PARSE UPPER ARG oCol, oRow
oCol=strip(oCol)
oRow=strip(oRow)
/* Initialize return code */
retCd=0
/* Absolute move */
IF Pos(SubStr(oCol,1,1), Ansi.userTable) = 0 THEN
DO
IF \datatype(oCol,"W") | \datatype(oRow,"W") THEN
RETURN
Ansi.col = MIN(oCol, Ansi.cols)
Ansi.row = MIN(oRow, Ansi.rows)
rc=AnsiSay(Ansi.esc || Ansi.row";"Ansi.col"f")
RETURN \((oCol=Ansi.col) & (oRow=Ansi.row))
END
ELSE
moves = oCol","oRow
/* Relative move(s) */
DO UNTIL moves = ""
PARSE VAR moves move "," moves
move = strip(move)
way = substr(move,1,1)
amount = substr(move,2)
IF \datatype(amount, "W") THEN ITERATE
SELECT
WHEN way = "+" THEN
DO
IF Ansi.row-amount < 0 THEN
amount = Ansi.row
Ansi.row = Ansi.row - amount
END
WHEN way = "-" THEN
DO
IF Ansi.row+amount > Ansi.rows THEN
amount = (Ansi.row+amount) - (Ansi.rows+1)
Ansi.row = MAX(Ansi.row + amount,1)
END
WHEN way = "<" THEN
DO
IF Ansi.col-amount < 0 THEN
amount = Ansi.col
Ansi.col = MAX(Ansi.col - amount,1)
END
WHEN way = ">" THEN
DO
IF Ansi.col+amount > Ansi.cols THEN
amount = (Ansi.col+amount) - (Ansi.cols+1)
Ansi.col = Ansi.col + amount
END
OTHERWISE ITERATE
END
IF amount = 0 THEN
ITERATE
theWay = translate(way, Ansi.moveTable, Ansi.userTable)
rc=AnsiSay(Ansi.esc || amount || theWay)
END /* End DO UNTIL moves = "" */
RETURN retCd
/*************************************************************************
*
* AnsiSay: Writes Ansi screen attributes to the screen
* so that it can be modified easily. If Ansi.cls is
* written, then Ansi.row and Ansi.col are set to 1.
*
* If Ansi.buf = 'on', then the output is sent to a buffer.
*
************************************************************************/
AnsiSay: PROCEDURE EXPOSE Ansi.
PARSE ARG attribs
IF pos(Ansi.cls, attribs) <> 0 THEN
DO
Ansi.row=1; Ansi.col=1
END
IF Ansi.buf = 'on' THEN
Ansi.string = Ansi.string || attribs
ELSE
rc = charout(, attribs)
RETURN 0
/*************************************************************************
*
* Write: Writes a string to the screen. Returns number of chars
* written.
*
* If Ansi.buf = 'on', then the output is sent to a buffer.
*
************************************************************************/
Write: PROCEDURE EXPOSE Ansi.
PARSE ARG oStr
Ansi.col = Ansi.col + length(oStr)
IF Ansi.col > Ansi.cols THEN
DO
amt=length(oStr)-(Ansi.col-Ansi.cols)
oStr = substr(oStr,1,amt)
Ansi.col = Ansi.cols
END
IF Ansi.buf = 'on' THEN
Ansi.string = Ansi.string || oStr
ELSE
rc = charout(, oStr)
RETURN rc
/*************************************************************************
*
* FlushBuf: Flushes the Ansi.string buffer to the screen.
*
************************************************************************/
FlushBuf: PROCEDURE EXPOSE Ansi.
rc=charout(,Ansi.string)
Ansi.string=""
Ansi.buf = ''
RETURN
/*************************************************************************
*
* Wait: Pauses for (delay) seconds.
*
************************************************************************/
Wait: PROCEDURE
PARSE ARG delay
IF \datatype(delay, "N") THEN
delay = 1
CALL Time("R")
DO WHILE Time("E") < delay
NOP
END
RETURN
/*************************************************************************
*
* SetAnsi: Puts the ANSI escape codes and a few usefull constants
* in the Ansi. stem variable
*
************************************************************************/
SetAnsi: PROCEDURE EXPOSE Ansi.
escCd = '1B'x || "["
/** Constants **/
Ansi.esc = escCd
/* Row and column variables */
Ansi.rows=25; Ansi.cols=80
Ansi.row=1; Ansi.col=1
/* Move charactos - Up, Down, Left, Right */
Ansi.moveTable = "ABDC"
Ansi.userTable = '+-<>'
/** Escape codes : NS = Not Supported under OS/2 **/
Ansi.cls = escCd || "2J" /* Clears the screen */
Ansi.erase = escCd || "K" /* Erase to End-Of-Line */
/** Screen Attributes: Used with ScrAttr */
/* Styles */
Ansi.plain = escCd || "0m" /* All attributes off */
Ansi.bold = escCd || "1m" /* Bold type */
Ansi.faint = escCd || "2m" /* Faint type -NS */
Ansi.italic = escCd || "3m" /* Italic type */
Ansi.blink = escCd || "5m" /* Blink type */
Ansi.rblink = escCd || "6m" /* Rapid-Blink type - NS */
Ansi.rev = escCd || "7m" /* Reverse video */
Ansi.hidden = escCd || "8m" /* Concealed type */
Ansi.subscr = escCd || "48m" /* Subscript */
Ansi.supscr = escCd || "49m" /* Superscript */
/* Colors, (b)ackground and (f)oreground */
Ansi.bblack = escCd || "30m"; Ansi.fblack = escCd || "40m"
Ansi.bred = escCd || "31m"; Ansi.fred = escCd || "41m"
Ansi.bgreen = escCd || "32m"; Ansi.fgreen = escCd || "42m"
Ansi.byellow = escCd || "33m"; Ansi.fyellow = escCd || "43m"
Ansi.bblue = escCd || "34m"; Ansi.fblue = escCd || "44m"
Ansi.bmagneta = escCd || "35m"; Ansi.fmagenta = escCd || "45m"
Ansi.bcyan = escCd || "36m"; Ansi.fcyan = escCd || "46m"
/* Screen modes 40x25 = 40 X 25, B = Black and White. C = Color */
Ansi.40x25B = escCd || "=0h"; Ansi.40x25C = escCd || "=1h"
Ansi.80x25B = escCd || "=2h"; Ansi.80x25C = escCd || "=3h"
Ansi.320x200B = escCd || "=4h"
Ansi.640x200B = escCd || "=5h"; Ansi.640x200C = escCd || "=6h"
Ansi.Wrap = escCd || "=7h"; Ansi.UnWrap = escCd || "=7I"
RETURN
/*************************************************************************
*
* SetBox: Sets up borders for the different kinds of boxes DrawBox
* can draw.
*
************************************************************************/
SetBox: PROCEDURE EXPOSE Box.
Box.space = ' '
Box.LShadow = 'B0'x
Box.Shadow = 'B1'x
Box.DShadow = 'B2'x
/* Single border */
Box.11.UpLc = 'DA'x; Box.11.LoLc = 'C0'x
Box.11.UpRc = 'BF'x; Box.11.LoRc = 'D9'x
Box.11.HSide = 'C4'x; Box.11.VSide = 'B3'x
/* Double border */
Box.22.UpLc = 'C9'x; Box.22.LoLc = 'C8'x
Box.22.UpRc = 'BB'x; Box.22.LoRc = 'BC'x
Box.22.HSide = 'CD'x; Box.22.VSide = 'BA'x
/* Single top+bot, double sides */
Box.12.UpLc = 'D6'x;Box.12.LoLc = 'D3'x
Box.12.UpRc = 'B7'x;Box.12.LoRc = 'BD'x
Box.12.HSide = 'C4'x;Box.12.VSide = 'BA'x
/* Double top+bot, single sides */
Box.21.UpLc = 'D5'x;Box.21.LoLc = 'D4'x
Box.21.UpRc = 'B8'x;Box.21.LoRc = 'BE'x
Box.21.HSide = 'CD'x;Box.21.VSide = 'B3'x
RETURN
/*************************************************************************
*
* SetBStem: Sets up border to draw the user defined charactor.
*
************************************************************************/
SetBStem: PROCEDURE EXPOSE Box.
PARSE ARG char
Box.char.UpLc = char;Box.char.LoLc = char
Box.char.UpRc = char;Box.char.LoRc = char
Box.char.HSide = char;Box.char.VSide = char
RETURN
/* END */