// RSilAA.Bcpl -- File stuff
get "sysdefs.d"
get "Sil.defs"
static
[
AltS=0; fpAlt; InitS=0; fpSilInit
@AltFilePos =0; @LastAltFilePos =0; @AltLineCnt=0; @LastLineCnt=0
@AltXCoord=0; @AltYCoord=0
]
static
[
PrintPressFile
hncopies
OldVersion = false
]
let FileOut(str) =valof
[
PrintPressFile =0
hncopies = 0
if not str then
[
if not FileName(true,"Output File: ") then resultis false
str = lv(FNameObject>>item.string.length)
]
// now check for direct hardcopy to the printer
if HardCopySwitch(str) then hncopies = getCopyNumber(str)
let S = OpenSilFile(str,0,ksTypeWriteOnly,wordItem)
if S eq 0 then
[
FixFName("Bad Open:")
resultis false
]
//write password
if Changed ne 0 then RemoveBuildMark()
Puts(S,#134562+(VirginSinceBuild? 1,0))
//write out macros
for i = 0 to 127 do //font 4 macros (user) only
[
let link = Mact!i
until link eq 0 do
[
Puts(S,i) //the macro name
WriteItem(S,link)
link = link>>item.link
]
]
// end of macro definitions
let link = FirstItem
until link eq 0 do
[
let line = link>>item.line eq 1
let area = link>>item.area eq 1
if (link>>item.state le Selected)&(link>>item.ymin ge 0)& (link>>item.xmax le 2*ScreenXmax)& (link>>item.ymax le 2*ScreenYmax)& (link>>item.ymax gr link>>item.ymin)& (link>>item.xmax gr link>>item.xmin)& ( area % line % ( link>>item.string.length gr 0)) then //only write out good stuff
[
Puts(S,-1) //block header
WriteItem(S,link)
]
link = link>>item.link
]
Closes(S)
FixFName(" ")
//
if PrintPressFile then
[ // Now write command on Rem.Cm and preserve old contents.
MakeRemFile(str, hncopies)
]
//
resultis true
]
and WriteItem(s,link) be
[
for i = 1 to 4 do Puts(s,link!i)
if link>>item.line % link>>item.area then return
if link>>item.font ls 14 % link>>item.macro then
for i = 5 to 5+(link>>item.string.length/2) do Puts(s,link!i)
]
and ReadItem(s) =valof
[
if OldVersion then resultis ReadOldVersionItem(s)
for i = 1 to 4 do NewItem!i = Gets(s)
NewItem>>item.state = Active
let line = NewItem>>item.line eq 1
let area = NewItem>>item.area eq 1
if not line & not area then //read in the string
[
NewItem!5 = Gets(s)
if NewItem>>item.string.length gr 1 then
for j = 1 to (NewItem>>item.string.length)/2 do
NewItem!(5+j) = Gets(s)
]
resultis NewItem>>item.font
]
and ReadOldVersionItem(s) =valof
[
for i = 1 to 4 do NewItem!i = Gets(s)
NewItem>>item.state = Active
let f = NewItem>>item.font
test f ls 14
ifso [ //read in the string
NewItem!5 = Gets(s)
if NewItem>>item.string.length gr 1 then
for j = 1 to (NewItem>>item.string.length)/2 do
NewItem!(5+j) = Gets(s)
// map lib # 9 to 13 to new lib # 8 to 12
if f gr 8 then [ NewItem>>item.macro = 1; NewItem>>item.font = f -1 ]
if f eq 8 then [ NewItem>>item.macro = 1; NewItem>>item.font = 14 ]
]
ifnot [ // line % area
NewItem>>item.line = f eq 14
NewItem>>item.area = f eq 15
]
resultis NewItem>>item.font
]
and FileIn(confirm) be
[
if not FileName(confirm,"Input From: ") then return
let stkend = NewItem //end of storage at start of input
let S = OpenSilFile(lv(FNameObject>>item.string.length),0,ksTypeReadOnly,wordItem)
if S eq 0 then
[
FixFName("Can’t Open File ") //remove filename
return
]
let pw = Gets(S)
if VirginSinceBuild then RemoveBuildMark()
VirginSinceBuild = false
OldVersion = false
if pw eq 34563B % pw eq 34562B then OldVersion = true
test pw eq 134563B then VirginSinceBuild = true
or if pw ne 134562B & not OldVersion then
[
Closes(S)
FixFName("Password not 134562B")
return
]
Changed = (NewItem ne SpaceBase)// If reading in on top of something, changed.
let prev=(lv FirstItem)-offset item.link//find the end of current "Item" list
while prev>>item.link ne 0 do prev=prev>>item.link
until Endofs(S) do //read file
[
let mname = Gets(S)
let font = ReadItem(S) //reads item into NewItem
let macro = NewItem>>item.macro
//if (font ls 14)&(font gr 8) then//ck for any library macros used in this block
if macro then
[
// font is from 8 to 13
// Mact 0-127 is for lib font 7; 128-255 is for lib font 8 etc
let mfont = 0
if font le 13 & font ge 8 then mfont = font - 7
let mindex = Mact+(mfont)*128
for i = 1 to NewItem>>item.string.length do
if mindex!(NewItem>>item.string.char↑i) eq 0 then
mindex!(NewItem>>item.string.char↑i) = -1
]
test mname eq -1
ifso //this is a picture element.
[
if ((NewItem>>item.xmin eq NewItem>>item.xmax) % (NewItem>>item.ymin eq NewItem>>item.ymax)) % (NewItem>>item.ymin ls 0) then loop
//prev = AddToListEnd(prev)//this call inverts order of items read
//the following does the same as AddToList except the order
//of items will be inverted
//this stops SIL output/input from inverting the order of items
//The order is important in press mode so that backgrounds overlap right
test DisplayArea eq 0 //hardcopy mode or screen mode
ifso AddToList(prev) //normal read - dont invert order of items
ifnot //reading into screen mode - invert order of items
[
let l=NewItem
if Usc(l,SpaceTop) gr 0 then CallSwat("No Room")
NewItem>>item.link=0
prev>>item.link=NewItem
NewItem=l+Length(NewItem)
prev = l
//end of code substitute
]
loop
]
ifnot //this block is part of a macro definition in the user’s private macros
[
let m = Mact!mname
if (m ne 0)&(m ls stkend) then //there is a previous definition. We either flush it or loop
[
//for the moment, ALWAYS OVERWRITE CONFLICTING DEFS.
FlushList(m) //remove previous definition
Mact!mname = 0
]
//add the definition to the list
if ((NewItem>>item.xmin eq NewItem>>item.xmax) % (NewItem>>item.ymin eq NewItem>>item.ymax)) then loop
AddToList(lv (Mact!mname))
]
]
Closes(S)
//update any libraries required; LibUpdate takes parameter font(5-9)
for font = 5 to 9 do LibUpdate(font)
if DisplayArea ne 0 then ZapRebuilder() //rebuild the display
FixFName(" ")
]
and AddToList(lvptr) be
[
let l = Length(NewItem)+NewItem
if Usc(l,SpaceTop)gr 0 then
[
Paint(NewItem,toWhite)
Message = "Space Exhausted - item lost"
return
]
NewItem>>item.link = @lvptr
@lvptr = NewItem
NewItem=l
]
and FileName(confirm, str) =valof
[
if DisplayArea eq 0 then resultis true
let xHardCopy = HardCopy
HardCopy=0
Update(str)
Update(str)
// switch back to the previous mode for filename
HardCopy = xHardCopy
// Check for StatusObject Font Orientation
let StatusObjectFont = (StatusObject>>item.font)/2
let Rotation = FontOrientation!StatusObjectFont & #377
test Rotation eq 0
ifso
[
FNameObject>>item.xmin = StatusObject>>item.xmax
]
ifnot
[
FNameObject>>item.ymin = StatusObject>>item.ymax
]
FNameObject>>item.state = Active //show filename
DisplayObject(FNameObject)//show string
ReWriteObj(FNameObject)
let Doit = confirm? AddText(FNameObject,Gets(keys)), true
//ZapRebuilderItem(FNameObject)//repaint behind string
if not Doit then
[
FixFName(" ")
resultis false
]
resultis true
]
// Remove the mark left by the BUILD program that indicates virgin drawing.
and RemoveBuildMark() be
[
let p = FirstItem
while p ne 0 do
[
if p>>item.font eq 14 &
p>>item.ymax eq BuildYmax & p>>item.ymin eq BuildYmax-7 then
[
Paint(p,toWhite)//Erase it
ZapRebuilderItem(p)//And zap rebuilder
p>>item.state=Dead
]
p = p>>item.link
]
VirginSinceBuild = false
]
//now the code for handeling "Alternate text" files ( alias "Analize" files)
//and OpenAltText() =valof
//[
//let NameVec = vec FNameLength
//Zero(fpAlt,5)
//MoveBlock(NameVec,lv FNameObject>>item.string,FNameLength)
//test FileName(true, "Alternate input: ") ifnot Message = " " ifso
//[
//AltS=OpenSilFile(lv(FNameObject>>item.string),fpAlt,ksTypeReadOnly,charItem)
//Message = "Can’t Open File "//set incase open failed
//]
//MoveBlock(lv FNameObject>>item.string, NameVec,FNameLength)
//FixFName(Message) //remove filename
//if not AltS then resultis -1
//LastAltFilePos = 0
//LastLineCnt = 1
//resultis 0
//]
and FindAnalyzeLine() be
[
if AltLineCnt eq 0 do //no file open, so ask for name of file
[
let NameVec = vec FNameLength
Zero(fpAlt,5)
MoveBlock(NameVec,lv FNameObject>>item.string,FNameLength)
test FileName(true, "Alternate input: ") ifnot Message = " " ifso
[
AltS=OpenSilFile(lv(FNameObject>>item.string),fpAlt,ksTypeReadOnly,charItem)
Message = "Can’t Open File "//set incase open failed
]
MoveBlock(lv FNameObject>>item.string, NameVec,FNameLength)
FixFName(Message) //remove filename
if not AltS then return
LastAltFilePos = 0
LastLineCnt = 1
]
if AltS eq 0 do //stream must have been closed for I/O, so open it again
AltS = OpenSilFile(0,fpAlt,ksTypeReadOnly,charItem)
if CtrlShift then [ Message = 1; AltFilePos = LastAltFilePos; AltLineCnt = LastLineCnt ]
if Message eq 0 then [ LastAltFilePos = AltFilePos; LastLineCnt =AltLineCnt ]
[
test (Message eq 0) % (AltLineCnt eq 0)
ifso [ AltFilePos = FilePos(AltS); AltLineCnt = AltLineCnt+1 ]
ifnot SetFilePos(AltS,0,AltFilePos)
NewItem!0=0 //int message to empty
AltXCoord=-1 //init new coordinates to "don’t update"
AppendN(AltLineCnt,NewItem) //enter line number into string
AppendS(": ",NewItem)
let Char = ReadChar(0) //read the first character in the line
if Char eq true then
[
Closes(AltS); AltS=0; AltLineCnt=0
Message = "Done"
return //end of file, restore state
]
if Char eq $*n then loop //don’t display blank lines
if Char eq $( then //get x,y coordinates if applicable
[ AltXCoord = ExtractVal(); AltYCoord = ExtractVal() ]
Char = ReadChar(true) //reads all remaining characters in current line
if (Char eq $;) then loop //don’t display lines starting with ";"
//now display the line
if AltXCoord ge 0 then
[
mx=AltXCoord
my=AltYCoord
PushCoords(mx,my)
MoveObjectTo(MarkObject,mx,my)
]
Update(NewItem); Message = 0
return
] repeat
]
and ExtractVal() =valof //get the X,Y coordinates from a line
[
let val = 0
[
let char = ReadChar(0)
if char ls $0 % char gr $9 then resultis val//non zero if char ls 0 or gr 9
val = val*10 + char-$0
] repeat
]
//read the next character from the file, and append to the Message string if the length
//is small enough not to over run the StatusObject space allocation
and ReadChar(fullLine) =valof
[
if Endofs(AltS) then resultis true
let char =Gets(AltS)
if char eq $*n then resultis $*n
if (NewItem>>str.length le 128) & (char ge #40) then AppendC(char,NewItem)
unless fullLine then resultis char
] repeat
and FixFName(str) be //turn off filename
[
if DisplayArea then //don’t do this in press print mode
[
FNameObject>>item.state = 2
Paint(FNameObject,toWhite)
ZapRebuilderItem(FNameObject)
]
Message = str
]
and OpenSilFile(name,hint,direction,itemsize) =valof //turn off filename
[
if InitS ne 0 then [ Closes(InitS); InitS = 0 ]
if AltS ne 0 then [ Closes(AltS); AltS = 0 ]
resultis OpenFile(name,direction,itemsize,0,hint,0,SilZone)
]
and HardCopySwitch(str) = valof
[
let len = str>>str.length
for i = 1 to len do
[
let c0 = str>>str.char↑i
let c1 = str>>str.char↑(i+1)
if c0 eq 40b then resultis false
if c0 eq $/ & ( c1 eq $H % c1 eq $h) then
[
PrintPressFile = true
resultis true
]
]
resultis false
]
and getCopyNumber(str) = valof
[
let n = 0
let len = str>>str.length
for i = 1 to len do
[
let c0 = str>>str.char↑i
let c1 = str>>str.char↑(i+1)
if c0 eq 40b then resultis false
if c0 eq $/ & ( c1 eq $H % c1 eq $h) then
[
//str>>str.length = i - 1
let newstr = str + (i+1)/2
newstr>>str.length = len - i + 1
n = ProcessNum(newstr,0)
str>>str.length = i - 1
resultis n
]
]
resultis n
]
and ProcessNum(str,initval) =valof
[
if str>>str.length eq 0 then resultis initval
let minus=false
let val=0
if str>>str.char↑1 eq $- then minus = true
for cnt = 1 to str>>str.length do
[
let char =str>>str.char↑cnt
if char ge $0 & char le $9 then val = val*10 + char - $0
]
val = val & #77777 //make sure val is positive
resultis minus? -val,val //and assign sign
]
and MakeRemFile(str, hncopies) be
[
let remcm = OpenFile("REM.CM",ksTypeWriteOnly,1,0,fpRemCm,0,SilZone)
if remcm eq 0 then finish
let nc=0
until Endofs(remcm) do [ SpaceBase!nc=Gets(remcm); nc=nc+1 ]
Resets(remcm)
let v = vec 50
v!0 = 0
AppendS("Rsil/h ",v)
if hncopies gr 1 then [ AppendN(hncopies,v); AppendS("/c ",v) ]
AppendS(str,v)
AppendS(" ; Rsil",v)
if TiltedScreen then AppendS("/L",v)
if not HardCopy then AppendS("/Z",v)
AppendS(" ",v);AppendS(str,v);AppendS("*n",v)
for i = 1 to v>>str.length do
[
Puts(remcm, v>>str.char↑i)
]
//Wss(remcm,v)
for i=0 to nc-1 do
[
Puts(remcm, SpaceBase!i)
]
Closes(remcm)
finish
]