home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
xbase
/
library
/
clipper
/
ansisys
/
ansiclip.prg
next >
Wrap
Text File
|
1992-01-29
|
12KB
|
327 lines
// ANSICLIP.PRG Copyright 1992 Robert Greenlee Released for unlimited use.
//
// SHOWANSI()
// This function will display an ANSI encoded picture file. ANSI.SYS
// does not need to be loaded as the display is handled using Clipper
// screen functions only.
//
// This is a rewrite of the SHOWANSI() function which was released into
// the public domain by Ken LaCapria on 11/10/91 in the file SHOWANSI.PRG.
// Ken's 11/10/91 version didn't work well enough to display any of the ANSI
// pictures I wanted to look at so I continued its development until I
// came up with this version which properly displays most of the ANSI pictures
// I've found on BBS's. I am using Clipper 5.01. Note that I've commented
// out a line below which uses the posalpha() function in the Nantucket
// Tools Library and put a FOR/NEXT loop in its place. If you have
// the Nantucket Tools Library or a posalpha() equivalent you might want
// to drop the FOR/NEXT. Also the ANSI SetMode functions can be enabled
// by uncommenting the line with the FT_SETMODE() function on it but you'll
// need the Nanforum ToolKit NANFOR.LIB when you link (or you could use
// SCRSETMODE() in Nantucket Tools). This entire function could stand
// alot more work but I'm tired of working on it for now.
// Hopefully someone else will get interested. Currently if it detects any
// unsupported ANSI sequences such as keyboard or music commands it will
// display them on the screen along with an "Unsupported ANSI sequence" message.
// I tried DO CASEing everything and taking out the LOOP's but it became slower.
// I've added a timeron equate that can be set .t. to display how long it takes
// to display each picture so you can see how your changes effect display speed.
// I'm leaving my debug code in so that anyone interested can continue
// development and I'm including a demo, ansidemo.prg, which uses this function
// to display .ANS files in the current directory. I can be reached on the
// Sabaline (619-692-1961) and Mushin (619-222-3097) BBS's in San Diego. I
// don't know where Ken LaCapria can be reached, apparently he didn't leave
// any info on that in SHOWANSI.PRG/.ZIP.
//
// HISTORY:
// 1/28/92 - ANSICLIP.ZIP - First Release of SHOWANSI.PRG rewrite.
// 1/29/92 - ANSICL52.ZIP - Second Release. Recoded Change-Color handler
// to substantially increase display speed.
//
#include "inkey.ch"
//
// SHOWANSI returns a null string
// Syntax: SHOWANSI(memvar)
//
FUNCTION showansi (ansitext)
local textlen,onechar,charpos,tempstrng,sf,sb,ef,eb,uf,ub,temprow
local tempcol,colnpos,tempchar,tempsubstr,X,savrow,savcol,oldcolor
local valtempstr,nextcharpos,oldsf,mposalpha,showesc,debugansi,x1
local mrow,mcol,gtimeons,gdateon,valtemp,timeron,templen
local secson,minuteson,dayson,hourson,secsleft,arcolors
timeron = .f. // If this is .t. then the time it takes to display the
// picture will be displayed in the lower left corner.
IF timeron
gtimeons = SECONDS()
gdateon = DATE()
ENDI
oldcolor = setcolor()
showesc = .t. // Display an Escape code not part of ANSI as a left arrow
debugansi = .f. // Crude debug mode that stops at every Escape sequence and
// displays various info. You hold the Enter key down
// until you get to the spot that's screwing up and then
// you try to see which Escape sequence is causing the problem
// and what's happening that's wrong and then you fix it.
IF debugansi
SET CURSOR ON // let's see where cursor is after each Escape sequence
ENDI
STOR 'W' TO sf,ef,uf
STOR 'N' TO sb,eb,ub
arcolors = {'N','R','G','GR','B','RB','BG','W'}
STOR 0 TO temprow,tempcol,colnpos,savrow,savcol,charpos
// Trim off any EOF markers like zeroes & Control-Z's
DO WHIL SUBS(ansitext,LEN(ansitext),1) $ CHR(0)+CHR(26)
ansitext = SUBS(ansitext,1,LEN(ansitext)-1)
ENDD
textlen=LEN(ansitext)
DO WHIL charpos+1<=textlen
IF debugansi
MROW = ROW()
MCOL = COL()
@ maxrow(),60 SAY 'savrow='+LTRIM(STR(savrow,3))+' savcol='+LTRIM(STR(savcol,3))
@ MROW,MCOL SAY ''
ENDI
charpos++
STOR '' TO tempstrng,tempsubstr
nextcharpos = charpos+AT(CHR(K_ESC),SUBS(ansitext,charpos))-1
// If no more Esc's send rest of string and exit
IF nextcharpos < charpos
?? SUBS(ansitext,charpos)
EXIT
ENDI
// If not an Esc send out up to next Esc
IF nextcharpos > charpos
?? SUBS(ansitext,charpos,nextcharpos-charpos) // send to next ESC
ENDI
charpos = nextcharpos + 1
// Process Esc command. If valid next char is [
onechar=SUBS(ansitext,charpos,1) // probably pointing to [
IF onechar<>'['
IF onechar = CHR(K_ESC) .AND. showesc
?? CHR(K_ESC)
ENDI
charpos-- // point back to Escape, charpos gets bumped above
LOOP
ENDIF
charpos++ // skip past [
// mposalpha = posalpha(ansitext,.F.,charpos-1) + charpos-1
mposalpha = 0
FOR x = charpos TO textlen
x1 = SUBS(ansitext,x,1)
IF !(x1==LOWER(x1) .AND. x1==UPPER(x1))
mposalpha = x
EXIT
ENDI
NEXT
IF mposalpha = 0
EXIT // Picture ends with incomplete Esc sequence - stop now
ENDI
tempstrng = SUBS(ansitext,charpos,mposalpha-charpos)
charpos = mposalpha
onechar=SUBS(ansitext,charpos,1)
IF debugansi
// here we display the ANSI command about to be processed and the
// row & col before, the command parameters (tempstrng), and a 40
// character chunk of the code string with the current command
// in the middle of it (Escape codes are changed to ! and carriage
// returns and line feeds are changed to ^.)
MROW = ROW()
MCOL = COL()
@ maxrow()-5,10 SAY ''
?? 'row='+LTRIM(STR(MROW,3))+', '
?? 'col='+LTRIM(STR(MCOL,3))+', '
?? 'command='+onechar+' '
@ maxrow()-4,10 SAY 'tempstrng= '+tempstrng+' '
@ maxrow()-3,10 SAY 'ansitext-20= '+ STRTRAN(STRTRAN(STRTRAN(SUBS(ansitext,charpos-20,40),CHR(27),'!'),CHR(13),'^'),CHR(10),'^')
@ MROW,MCOL SAY ''
SET CONS OFF
wait
SET CONS ON
ENDI
IF ! onechar $ 'ABCDHJKfhlmsu'
MROW=ROW()
MCOL=COL()
@ maxrow(),0 SAY 'Unsupported ANSI sequence '
?? STRTRAN(STRTRAN(STRTRAN(SUBS(ansitext,charpos,30),CHR(27),'!'),CHR(13),'^'),CHR(10),'^')
@ MROW,MCOL SAY ''
SET CONS OFF
wait
SET CONS ON
LOOP
ENDI
IF !onechar == 'm' // This improves display time
valtemp = VAL(tempstrng)
IF onechar='K' // Clear to End of Line
DO CASE
CASE valtemp=0
@ ROW(),COL()-1 CLEAR TO ROW(),maxcol()
CASE valtemp=1
@ ROW(),0 CLEAR TO ROW(),COL()-1
CASE valtemp=2
@ ROW(),0 CLEAR TO ROW(),maxcol()
ENDC
LOOP
ENDIF
IF onechar $ 'ABCD' // Cursor Up/Down/Right/Left
DO CASE
CASE onechar='A'
temprow=ROW()-MAX(valtemp,1)
tempcol = COL()
CASE onechar='B'
temprow=ROW()+MAX(valtemp,1)
tempcol = COL()
CASE onechar='C'
tempcol=COL()+MAX(valtemp,1)
temprow = ROW()
CASE onechar='D'
tempcol=COL()-MAX(valtemp,1)
temprow = ROW()
ENDC
@ MIN(maxrow(),MAX(0,temprow)),MIN(maxcol(),MAX(0,tempcol)) SAY ''
LOOP
ENDIF
IF onechar $ 'Hf' // Absolute Cursor Positioning (Both same)
colnpos=AT(';',tempstrng)
IF colnpos > 0
temprow=VAL(SUBS(tempstrng,1,colnpos-1))-1
ELSE
temprow = valtemp-1
ENDI
IF colnpos > 0 .AND. LEN(SUBS(tempstrng,colnpos+1)) > 0
tempcol=VAL(SUBS(tempstrng,colnpos+1))-1
ELSE
tempcol = 0
ENDI
@ MIN(maxrow(),MAX(0,temprow)),MIN(maxcol(),MAX(0,tempcol)) SAY ''
LOOP
ENDIF
IF onechar='s' // Save Current Cursor Location
savrow=ROW()
savcol=COL()
LOOP
ENDIF
IF onechar='u' // Return to last Saved Cursor Location
@ savrow,savcol SAY ''
LOOP
ENDIF
IF onechar='J' // Clear Screen - Cursor to upper left corner
DO CASE
CASE valtemp=0
@ ROW(),MAX(COL()-1,0) CLEAR TO ROW(),maxcol()
@ ROW()+1,0 CLEAR
CASE valtemp=1
@ ROW(),0 CLEAR
CASE valtemp=2
@ 0,0 CLEAR TO maxrow(),maxcol()
ENDC
LOOP
ENDIF
IF onechar$'lh' // Set screen width/height commands.
// Esc[=#h sets screen mode
// Esc[=#l resets screen mode
// 0 = 40x25 black & white
// 1 = 40x25 color
// 2 = 80x25 black & white
// 3 = 80x25 color
// 4 = 320x200 color graphics
// 5 = 320x200 black & white graphics
// 6 = 640x200 black & white graphics
// 7 = line-wrap on/off (Esc[=7h/Esc[=7l)
// 84 = 132x43 Paradise VGA
// 85 = 132x25 Paradise VGA
//
IF SUBS(tempstrng,1,1) == '=' // You need NanForum TookKit's
IF SUBS(tempstrng,2,1) $ '012345689' // NANFOR.LIB for FT_SETMODE()
// FT_SETMODE(VAL(SUBS(tempstrng,2))) // or you could use SETSCRMODE()
ENDI // in Nantucket Tools.
ENDI
// Esc[?7l or Esc[=7l turns line-wrap off Not Supported yet
// Esc[?7h or Esc[=7h turns line-wrap on Not Supported yet
LOOP
ENDIF
ENDIF // .NOT. onechar == 'm'
// at this point onechar is ASSUMED to be 'm' since all the IF's above LOOP
X=0
templen = LEN(tempstrng)
DO WHILE .t. // EXITS at bottom of DO/WHIL when !(x <= templen)
tempsubstr=''
x++
tempsubstr = SUBS(tempstrng,x,AT(';',SUBS(tempstrng,x)+';')-1)
x=x+LEN(tempsubstr)
IF debugansi
// here we display each part of the screen color sequence before
// it is processed.
MROW = ROW()
MCOL = COL()
@ maxrow()-1,10 SAY 'tempsubstr= '+tempsubstr+' '
@ MROW,MCOL SAY ''
SET CONS OFF
wait
SET CONS ON
ENDI
oldsf = sf
valtempstr = VAL(tempsubstr)
DO CASE
CASE valtempstr=0
STOR 'W' TO sf,ef,uf
STOR 'N' TO sb,eb,ub
CASE valtempstr=1
sf=STRTRAN(sf+'+','++','+')
CASE valtempstr=2
sf=STRTRAN(sf,'+')
CASE valtempstr=4
sf='U'
CASE valtempstr=5 .AND. .NOT. '*' $ sf
sf=sf+'*'
CASE valtempstr=7
sf='I'
CASE valtempstr=8
sf='X'
CASE valtempstr > 29 .AND. valtempstr < 38
sf = arcolors[valtempstr-29]
IF '+' $ oldsf
sf = sf+'+'
ENDI
IF '*' $ oldsf
sf = sf+'*'
ENDI
CASE valtempstr > 39 .AND. valtempstr < 48
sb = arcolors[valtempstr-39]
ENDC
IF ! x <= templen
setcolor(sf+'/'+sb+','+ef+'/'+eb+',,,'+uf+'/'+ub)
EXIT
ENDI
ENDD
ENDD
setcolor(oldcolor)
IF timeron
@ maxrow(),0 SAY 'Time: '
secson = ((DATE()-gdateon)*86400)+(SECONDS()-gtimeons)
dayson = INT(secson/86400)
hourson = INT((secson-(dayson*86400))/3600)
minuteson = INT((secson-(dayson*86400)-(hourson*3600))/60)
secsleft = secson - (dayson*86400) - (hourson*3600) - (minuteson*60)
?? IIF(dayson>0,LTRIM(STR(dayson))+ ' days, ','')
?? IIF(hourson>0,LTRIM(STR(hourson))+ ' hours, ','')
?? IIF(minuteson>0,LTRIM(STR(minuteson))+ ' minute'+IIF(minuteson=1,'','s')+', ','')
?? LTRIM(STR(secsleft))
?? ' second'+IIF(secsleft=1,'','s')+'.'
ENDI
RETURN ''
//: EOF: ANSICLIP.PRG