home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Plus SuperCD 1
/
SuperCD_1.iso
/
pcplus
/
wilf
/
showbmp.bas
< prev
Wrap
BASIC Source File
|
1996-10-14
|
34KB
|
1,601 lines
DEFINT A-Z
DECLARE SUB ziDragging ()
' Return if mouse active and still dragging, or else exhausted
DECLARE SUB ziDrawBank (FromButton, ToButton)
' Draw a bank of buttons (using Bank array)
DECLARE SUB ziExhaust ()
' Return when no keystrokes and no mouse buttons
DECLARE SUB ziLoadFont (Font$)
' Load a specified font
DECLARE SUB ziLocateMCursor (Xcoord, YCoord)
' Locate mouse cursor to a named point
DECLARE SUB ziMouseOnButton (FromButton, ToButton)
' Sets FoundButton
DECLARE SUB ziPublish (PrintString$, Size, Italic)
' Print a string
' Size = magnitude (per 8 pixels)
' Italic = +1 to make italic
' = +2 to make overprint (no background)
DECLARE SUB ziRadio (Button, FromButton, ToButton)
' Set one button in a Bank, resetting the rest
DECLARE SUB ziReadField (Min, Max, Permitted$)
' Read a field at the current TCursor location
' Permitted$ contains:
' * - any characters
' . - allow one full-stop (as decimal)
' A - auto-enter (when filled)
' C - capitalise letters
' E - ESC allowed to finish (skip) field
' J - justify (especially for numeric)
' N - numerics
' P - password-type display
' S - space
' X - alphabetic
' Y - Y or N (upper or lower)
DECLARE SUB ziSetMCursorVis (Status)
' Set visibility of mouse cursor
' Status = 0 for OFF
' 1 for ON
' 2 for ENQUIRE (set MCursorVis)
' 10 for TEMPORARILY OFF
' 11 for RESTORED (set MCursorVis)
DECLARE SUB ziWander (Timeout!)
' Timeout = in seconds (0 = none)
' Response = 0 = (0:00) timed out
' n = (0:n) displacement into Allowed$
' key &h01xx &h02xx &h04xx &h08xx &h10xx &h20xx &h40xx
' plain CTRL shift Mouse Fn CTRL-Fn shift-Fn
' Enter 0 * * - double - - -
' (left) 1 * * - left F1 ^F1 +F1
' (right) 2 * * - right F2 ^F2 +F2
' (up) 3 * - - both F3 ^F3 +F3
' (down) 4 * - - leftdrag F4 ^F4 +F4
' Backspace 5 * * - rightdrag F5 ^F5 +F5
' Home 6 * * - bothdrag F6 ^F6 +F6
' End 7 * * - - F7 ^F7 +F7
' PgUP 8 * * - - F8 ^F8 +F8
' PgDN 9 * * - - F9 ^F9 +F9
' Tab 10 * - * - F10 ^F10 +F10
' Escape 11 * - - - F11 ^F11 +F11
' 12 - - - - F12 ^F12 +F12
' Allowed$ = other allowed strokes
' (Note: DClick is a flag permitting Double-clicks of mouse - slower!)
DEFINT A-Z
DECLARE SUB zsAlignGCursor ()
' Align graphic cursor to same as text cursor
' - sets Row, Col, GXloc, GYloc
DECLARE SUB zsAlignTCursor ()
' Align text cursor to same as graphic cursor
' - sets Row, Col, GXloc, GYloc
DECLARE SUB zsLocateGCursor (Xcoord, YCoord)
' Locate graphic cursor to a named point
DECLARE SUB zsPastel (Xcoord, YCoord, Wide, Deep, Colour1, Colour2)
' Colour the defined oblong with a pastel mix of two colours
' Deep = 0 or 1 - square
' = n - Y-pixel depth
DECLARE SUB zsSetScrnMode (Mode, HiRows, HiCols)
' Mode = 9 or 12
' HiRows = 1 to make high number of rows
' HiCols = 1 to make high number of cols (80)
' Set SCREEN parameters and blank the screen
' - sets ScrnMode, Xmax, Ymax, Rows, Cols, XYRatio!
' - uses FG and optionally BG (colours)
DECLARE SUB zsSubstitute (Xcoord, YCoord, Wide, Deep, Colour1, Colour2)
' Substitute one colour with another within the defined oblong
' Deep = 0 or 1 - square
' = n - Y-pixel depth
DECLARE SUB zzBasicInt (IntType)
' Execute interrupt (params in REGS.AX etc)
DECLARE SUB zzInPath (Field$)
' Return full path to a file (in same string)
'================================================
'/ UK copyright (c) 1996 by Future Publishing
'/
'/
'/
'/
'================================================
TYPE REGISTERS
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
DS AS INTEGER
SI AS INTEGER
ES AS INTEGER
DI AS INTEGER
FL AS INTEGER
END TYPE
TYPE Buttons
Xloc AS INTEGER
Yloc AS INTEGER
Wide AS INTEGER
Deep AS INTEGER
' 0 = checkbutton
' 1 = square sculptured
' n = Y-pixels deep
State AS INTEGER
' 0 = off
' 1 = on
Active AS INTEGER
' 0 = inactive
' 1 = active
END TYPE
CONST Pi! = 3.14159
CONST Ex! = 2.71828
CONST DegToRad! = .0174533
CONST RadToDeg! = 57.2958
CONST ziNoShift = &H1
CONST ziCTRL = &H2
CONST ziShift = &H4
CONST ziMouse = &H8
CONST ziFn = &H10
CONST ziCTRLFn = &H20
CONST ziShiftFn = &H40
CONST ziL = 1
CONST ziR = 2
CONST ziUp = 3
CONST ziDn = 4
CONST ziBS = 5
CONST ziHome = 6
CONST ziEnd = 7
CONST ziPgUp = 8
CONST ziPgDn = 9
CONST ziTab = 10
CONST ziEsc = 11
CONST ziDbl = 0
CONST ziBoth = 3
CONST ziLDrag = 4
CONST ziRDrag = 5
CONST ziBothDrag = 6
DIM SHARED regs AS REGISTERS
DIM SHARED Bank(20) AS Buttons
DIM SHARED bad, Module$
DIM SHARED Mouse, MCursorVis, MXloc, MYloc
DIM SHARED DClick
DIM SHARED ScrnMode, BG, FG, TCursor
DIM SHARED Xmax, Ymax, GXloc, GYloc, XYratio!
DIM SHARED Rows, Cols, Row, Col
DIM SHARED Allowed$, Field$
DIM SHARED FoundButton
DIM SHARED Font(255, 7)
DIM SHARED Response, HResponse, LResponse
'++++++++++++++++++++++++
RANDOMIZE TIMER
ON ERROR GOTO RESUMENEXT
RESUMENEXT:
IF ERR = 255 THEN
CLS
BEEP
PRINT "Cannot find module "; Module$
SLEEP
SYSTEM
END IF
IF ERR THEN
bad = ERR
RESUME NEXT
END IF
'++++++++++++++++++++++++
' Test for presence of a mouse
Mouse = 0
regs.AX = 0
CALL zzBasicInt(&H33)
IF regs.AX THEN
Mouse = 1
CALL ziSetMCursorVis(0)
END IF
'++++++++++++++++++++++++
' Load the ASCII font
CALL ziLoadFont("Ascii8x8")
'/==================================/'
'/ End of Standard Piecrust code /'
'/==================================/'
'/********************************************************************
'/********************************************************************
TYPE WINHeader
MustBeBM AS STRING * 2
MustBeFileSize AS LONG
dummy6 AS STRING * 4
ImageOffset AS LONG
HeaderSize AS LONG
'/ if HeaderSize = 40 this is a WIN type BMP
WINXPixels AS LONG
WINYPixels AS LONG
WINdummy26 AS STRING * 2
WINBitCount AS INTEGER
WINCompression AS LONG
WINdummy34 AS STRING * 12
WINColoursUsed AS LONG
END TYPE
DIM BMP AS WINHeader
'/ if HeaderSize = 12 this is an OS/2 type BMP
TYPE OS2Header
OS2dummy0 AS STRING * 18
OS2XPixels AS INTEGER
OS2YPixels AS INTEGER
OS2dummy22 AS STRING * 2
OS2BitCount AS INTEGER
END TYPE
DIM OS2 AS OS2Header
DIM FileName AS STRING * 50
DIM Block AS STRING * 256
DIM Memory AS STRING * 768
'/*****************************
'/ This is the "main" program, running the MENU
DO
NewFile = 0
DO
SCREEN 0
SCREEN 13
GOSUB OpenFile
CLS
LOOP WHILE bad <> 0
DO
GOSUB MenuProcess
LOOP UNTIL NewFile = 1
LOOP
'/********************************************************************
'/********************************************************************
'/*****************************
'/ Subroutines
'/*****************************
'/*****************************
'/ Colour BIOS call
'/
'/ Input: regs.AX
ColourBIOS:
regs.BX = 0
regs.CX = 256
regs.ES = VARSEG(Memory)
regs.DX = VARPTR(Memory)
CALL zzBasicInt(&H10)
RETURN
'/*****************************
'/ Handle a COMPRESSED Image
Compressed:
RowDisp = 0
ColDisp = 0
Offset! = ImageLoc!
'/ ImageStart = 0 if on even boundary
ImageStart = ImageLoc! AND 1
Brake = 0
DO
GOSUB ReadBlock
IF IntegerValue = 0 THEN
Offset! = Offset! + 1
GOSUB ReadBlock
SELECT CASE IntegerValue
'/ new row
CASE 0
RowDisp = RowDisp + 1
ColDisp = 0
'/ end of image
CASE 1
Brake = 1
'/ position delta
CASE 2
Offset! = Offset! + 1
GOSUB ReadBlock
ColDisp = ColDisp + IntegerValue
Offset! = Offset! + 1
GOSUB ReadBlock
RowDisp = RowDisp - IntegerValue
'/ string quoted
CASE ELSE
StartString! = Offset! + 1
StringLength = IntegerValue
FOR i = 0 TO StringLength - 1
Xfactor = Xmargin + ColDisp
Yfactor = 199 - Ymargin - RowDisp
IF MaxColours = 256 THEN
Offset! = i + StartString!
GOSUB ReadBlock
ColourFactor = IntegerValue
ELSE
Offset! = i \ 2 + StartString!
GOSUB ReadBlock
IF i MOD 2 = 0 THEN
ColourFactor = IntegerValue \ 16
ELSE
ColourFactor = IntegerValue MOD 16
END IF
END IF
GOSUB PixelPaint
ColDisp = ColDisp + 1
NEXT
END SELECT
ELSE
'/ if not zero, this is a "repeat" function
RepeatValue = IntegerValue
Offset! = Offset! + 1
GOSUB ReadBlock
IF MaxColours = 256 THEN
Colour1 = IntegerValue
Colour2 = IntegerValue
ELSE
Colour1 = IntegerValue \ 16
Colour2 = IntegerValue MOD 16
END IF
Repeat1 = (RepeatValue + 1) \ 2
Repeat2 = RepeatValue \ 2
FOR i = 1 TO Repeat1
Xfactor = Xmargin + ColDisp
Yfactor = 199 - Ymargin - RowDisp
ColourFactor = Colour1
GOSUB PixelPaint
IF Repeat2 >= i THEN
ColDisp = ColDisp + 1
Xfactor = Xfactor + 1
ColourFactor = Colour2
GOSUB PixelPaint
END IF
ColDisp = ColDisp + 1
NEXT
END IF
'/ make sure we are at an "even" boundary
Offset! = Offset! + 1
i = Offset! AND 1
IF i <> ImageStart THEN Offset! = Offset! + 1
LOOP UNTIL Brake = 1
RETURN
'/*****************************
'/ Colour displayer
Displayer:
CLS
FOR i = 0 TO 239
j = (i \ 15) * 16
FOR k = 0 TO 191
PSET (i, k), j + (k \ 12)
NEXT
NEXT
RETURN
'/*****************************
'/ Fade
Fade:
FOR i = 62 TO 0 STEP -2
x$ = CHR$(i)
FOR j = 1 TO 768
Y$ = MID$(Memory, j, 1)
IF ASC(Y$) > i THEN
MID$(Memory, j, 1) = x$
END IF
NEXT
regs.AX = &H1012
GOSUB ColourBIOS
FOR k = 1 TO 1000: NEXT
NEXT
RETURN
'/*****************************
'/ Fetch colours from table
FetchColours:
GET #1, 1, Block
CurrentRec = 1
GOSUB SetColours
RETURN
'/*****************************
'/ Intervention by pressing ESC key
Intervene:
bad = 0
x$ = INKEY$
IF LEN(x$) = 1 THEN
IF ASC(x$) = 27 THEN
bad = 1
RETURN
END IF
END IF
RETURN
'/*****************************
'/ Menu
MenuProcess:
SCREEN 0
SCREEN 13
PRINT " ShowBMP"
PRINT
PRINT "Current file: "; FileName
PRINT "Size:"; LOF(1)
PRINT "RLE compression ";
IF Compression = 0 THEN
PRINT "not used"
ELSE
PRINT "used"
END IF
PRINT MaxColours; "Colour image "; Xpixels; "x"; Ypixels
PRINT
PRINT
PRINT " 1. Select a new file"
IF ReverseHorizontal = 0 THEN
PRINT " 2. Flip Horizontal"
ELSE
PRINT " 2. Reset Horizontal"
END IF
IF ReverseVertical = 0 THEN
PRINT " 3. Flip Vertical"
ELSE
PRINT " 3. Reset Vertical"
END IF
IF GreyScaling = 0 THEN
PRINT " 4. Render in Grey"
ELSE
PRINT " 4. Render in Colour"
END IF
PRINT " 5. Display Colour scheme"
PRINT " 6. Display Image"
PRINT " 7. Display then Fade"
PRINT " 8. Exit"
PRINT
PRINT
PRINT " ";
IF ReverseHorizontal = 0 THEN
PRINT "Normal ";
ELSE
PRINT "Flipped ";
END IF
PRINT "horizontal"
PRINT " ";
IF ReverseVertical = 0 THEN
PRINT "Normal ";
ELSE
PRINT "Flipped ";
END IF
PRINT "vertical"
PRINT " ";
PRINT "Rendered in ";
IF GreyScaling = 0 THEN
PRINT "colour"
ELSE
PRINT "shades of grey"
END IF
GOSUB SleeperSound
x$ = "X"
WHILE LEN(x$) > 0: x$ = INKEY$: WEND
WHILE LEN(x$) = 0
WHILE LEN(x$) = 0: x$ = INKEY$: WEND
'/ convert Fx to x
IF LEN(x$) = 2 THEN
i = ASC(MID$(x$, 2, 1))
IF i > 58 AND i < 67 THEN
x$ = CHR$(i - 10)
END IF
END IF
SELECT CASE x$
CASE CHR$(27)
NewFile = 1
CASE "1"
NewFile = 1
CASE "2"
ReverseHorizontal = 1 - ReverseHorizontal
CASE "3"
ReverseVertical = 1 - ReverseVertical
CASE "4"
GreyScaling = 1 - GreyScaling
CASE "5"
GOSUB FetchColours
GOSUB Displayer
GOSUB Sleeper
CASE "6"
GOSUB FetchColours
GOSUB ShowPicture
GOSUB Sleeper
CASE "7"
GOSUB FetchColours
GOSUB ShowPicture
GOSUB Sleeper
GOSUB Fade
CASE "8"
SCREEN 0
SCREEN 13
LOCATE 12
PRINT SPC(12); "PROGRAM END"
SLEEP (2)
CLS
SYSTEM
CASE ELSE
x$ = ""
END SELECT
WEND
RETURN
'/*****************************
'/ Open a File
OpenFile:
CLOSE #1
bad = 0
INPUT "Which file"; FileName
FileName = UCASE$(FileName)
IF FileName = SPACE$(50) THEN SYSTEM
OPEN FileName FOR INPUT AS #1
IF bad <> 0 THEN
PRINT
PRINT "Cannot find "; FileName
GOSUB Proceed
RETURN
END IF
CLOSE #1
SCREEN 0
SCREEN 13
OPEN FileName FOR RANDOM AS #1 LEN = 256
GET #1, 1, BMP
PRINT FileName
PRINT "File size"; LOF(1)
IF BMP.MustBeBM <> "BM" THEN
bad = 1
PRINT "This is not a BMP file"
ELSE
IF BMP.MustBeFileSize <> LOF(1) THEN
bad = 1
PRINT "File size is not correct"
ELSE
ImageLoc! = BMP.ImageOffset
BMPtype = BMP.HeaderSize
SELECT CASE BMPtype
CASE 12
PRINT "This is an OS/2-type BMP file"
GET #1, 1, OS2
MapOffset = 26
ColourDisp = 3
Compression = 0
Xpixels = OS2.OS2XPixels
Ypixels = OS2.OS2YPixels
BitCount = OS2.OS2BitCount
ColoursUsed = 0
CASE 40
PRINT "This is a WINDOWS-type BMP file"
MapOffset = 54
ColourDisp = 4
Xpixels = BMP.WINXPixels
Ypixels = BMP.WINYPixels
BitCount = BMP.WINBitCount
ColoursUsed = BMP.WINColoursUsed
IF BMP.WINCompression <> 0 THEN
PRINT "RLE used"
Compression = 1
ELSE
PRINT "RLE not used"
Compression = 0
END IF
CASE ELSE
bad = 1
PRINT "This is an unknown type of BMP file"
END SELECT
END IF
END IF
IF bad = 0 THEN
SELECT CASE BitCount
CASE 1
MaxColours = 2
CASE 4
MaxColours = 16
CASE 8
MaxColours = 256
CASE ELSE
bad = 0
PRINT "More than 256 colours not supported"
END SELECT
END IF
IF bad > 0 THEN
PRINT "I cannot proceed with this file"
GOSUB Proceed
END IF
ReverseHorizontal = 0
ReverseVertical = 0
GreyScaling = 0
RETURN
'/*****************************
'/ PixelPaint
'/
'/ Xfactor, Yfactor, Colourfactor
PixelPaint:
IF ReverseHorizontal = 0 THEN
Xfactor2 = Xfactor
ELSE
Xfactor2 = 320 - Xfactor
END IF
IF ReverseVertical = 0 THEN
Yfactor2 = Yfactor
ELSE
Yfactor2 = 200 - Yfactor
END IF
PSET (Xfactor2, Yfactor2), ColourFactor
RETURN
'/*****************************
'/ Proceed
Proceed:
LOCATE 23, 30
PRINT "Press a key to proceed";
GOSUB Sleeper
LOCATE 24, 30
PRINT SPACE$(23);
RETURN
'/*****************************
'/ Read a particular record from the file
'/
'/ input: offset!
'/ output: IntegerValue - value at the desired offset
'/ disp - displacement within block
'/ Block - current block
ReadBlock:
RecWanted = 1 + Offset! \ 256
IF CurrentRec <> RecWanted THEN
GET #1, RecWanted, Block
CurrentRec = RecWanted
END IF
disp = Offset! MOD 256 + 1
IntegerValue = ASC(MID$(Block, disp, 1))
RETURN
'/*****************************
'/ set colours
'/
'/ this method will work both for "quads" used by Windows BMP format
'/ and for "triples" used by OS/2 BMP format.
SetColours:
'/ fetch existing colours
regs.AX = &H1017
GOSUB ColourBIOS
'/ fetch colour table from the file
FOR ColourNumber = 0 TO MaxColours - 1
Offset! = MapOffset + ColourNumber * ColourDisp
GOSUB ReadBlock
GreySum = IntegerValue * 11
BlueVal$ = CHR$(IntegerValue \ 4)
Offset! = Offset! + 1
GOSUB ReadBlock
GreySum = GreySum + IntegerValue * 59
GreenVal$ = CHR$(IntegerValue \ 4)
Offset! = Offset! + 1
GOSUB ReadBlock
GreySum = GreySum + IntegerValue * 30
RedVal$ = CHR$(IntegerValue \ 4)
IF GreyScaling = 1 THEN
x$ = CHR$(GreySum \ 400)
Vals$ = x$ + x$ + x$
ELSE
Vals$ = RedVal$ + GreenVal$ + BlueVal$
END IF
MID$(Memory, ColourNumber * 3 + 1, 3) = Vals$
NEXT
'/ store new values
regs.AX = &H1012
GOSUB ColourBIOS
RETURN
'/*****************************
'/ Show a Picture
ShowPicture:
CLS
RedCounter# = 0
GreenCounter# = 0
BlueCounter# = 0
PixelCounter# = 0
Xmax = (Xpixels + 320 - ABS(Xpixels - 320)) / 2
Xmargin = (320 - Xmax) / 2
Ymax = (Ypixels + 200 - ABS(Ypixels - 200)) / 2
Ymargin = (200 - Ymax) / 2
IF Compression = 0 THEN
GOSUB Uncompressed
ELSE
GOSUB Compressed
END IF
RETURN
'/*****************************
'/ Sleeper
Sleeper:
GOSUB SleeperSound
x$ = "X"
WHILE LEN(x$) > 0: x$ = INKEY$: WEND
WHILE LEN(x$) = 0: x$ = INKEY$: WEND
RETURN
'/*****************************
'/ Sleeper Sound
SleeperSound:
FOR i = 300 TO 380 STEP 8
SOUND i, 1
NEXT
RETURN
'/*****************************
'/ Handle an UNCOMPRESSED Image
Uncompressed:
'/ calculate length of bitmap pertaining to one row
i = 32 / BitCount
OneRow! = 4 * ((Xpixels + i - 1) \ i)
FOR j = 0 TO Ymax - 1
ThisRow! = j * OneRow!
Stepping = 8 / BitCount
FOR i = 0 TO Xmax - 1 STEP Stepping
Offset! = ImageLoc! + i / Stepping + ThisRow!
GOSUB ReadBlock
Repeat = 0
Yfactor = Ymargin + Ypixels - j - 1
RepeatFactor = 256 / MaxColours
DO
k = (IntegerValue \ RepeatFactor) MOD MaxColours
PixelCounter# = PixelCounter# + 1
x$ = MID$(Memory, k * 3 + 1, 1)
RedCounter# = RedCounter# + ASC(x$)
x$ = MID$(Memory, k * 3 + 2, 1)
GreenCounter# = GreenCounter# + ASC(x$)
x$ = MID$(Memory, k * 3 + 3, 1)
BlueCounter# = BlueCounter# + ASC(x$)
Xfactor = Xmargin + i + Repeat
ColourFactor = k
GOSUB PixelPaint
Repeat = Repeat + 1
RepeatFactor = RepeatFactor / MaxColours
IF i + Repeat = Xmax THEN EXIT FOR
LOOP UNTIL Repeat = Stepping
NEXT
GOSUB Intervene
IF bad > 0 THEN EXIT FOR
NEXT
sum# = (RedCounter# + GreenCounter# + BlueCounter#) / 100
RedPortion! = RedCounter# / sum#
GreenPortion! = GreenCounter# / sum#
BluePortion! = BlueCounter# / sum#
Intensity! = RedPortion! * 30 + GreenPortion! * 59 + BluePortion! * 11
Intensity! = Intensity! / 63
RETURN
'++++++++++++++++++++++++
SUB ziDragging
IF Mouse AND MCursorVis THEN
SELECT CASE Response
CASE 2052 TO 2054
regs.AX = 3
CALL zzBasicInt(&H33)
IF regs.BX = Response - 2051 THEN
EXIT SUB
END IF
END SELECT
END IF
CALL ziExhaust
END SUB
'++++++++++++++++++++++++
SUB ziDrawBank (FromButton, ToButton)
CALL ziSetMCursorVis(10)
FOR i = FromButton TO ToButton
IF Bank(i).Active THEN
IF Bank(i).State THEN
Colour1 = 8
ELSE
Colour1 = 15
END IF
Colour2 = Colour1 XOR 7
Xcoord = Bank(i).Xloc
YCoord = Bank(i).Yloc
XWidth = Bank(i).Wide
YDepth = Bank(i).Deep
X2Coord = Xcoord + XWidth
IF YDepth THEN
IF YDepth = 1 THEN
Y2Coord = YCoord + XWidth / XYratio!
ELSE
Y2Coord = YCoord + YDepth
END IF
LINE (Xcoord, YCoord)-(X2Coord - 1, YCoord), Colour1
LINE (Xcoord, YCoord)-(Xcoord, Y2Coord - 1), Colour1
LINE (Xcoord + 1, Y2Coord)-(X2Coord, Y2Coord), Colour2
LINE (X2Coord, YCoord)-(X2Coord, Y2Coord), Colour2
ELSE
a = XWidth \ 2
b = a / XYratio!
c = Xcoord + a
d = YCoord + b
LINE (Xcoord, YCoord)-(c + a, d + b), 7, BF
CIRCLE (c, d), a, 8
CIRCLE (c, d), a - 1, 8
PAINT (c, d), 7, 7
IF Bank(i).State THEN
CIRCLE (c, d), XWidth \ 3, 8
PAINT (c, d), 8, 8
END IF
END IF
END IF
NEXT
CALL ziSetMCursorVis(11)
END SUB
'++++++++++++++++++++++++
SUB ziExhaust
DO
x$ = INKEY$
LOOP WHILE LEN(x$)
IF Mouse AND MCursorVis THEN
DO
regs.AX = 3
CALL zzBasicInt(&H33)
LOOP WHILE (regs.BX AND 3)
END IF
Response = 0
END SUB
'++++++++++++++++++++++++
SUB ziLoadFont (Font$)
DEF SEG = VARSEG(Font(0, 0))
Module$ = Font$ + ".OVL"
CALL zzInPath(Module$)
IF Module$ = "" THEN
Module$ = Font$ + ".OVL"
ERROR 255
ELSE
BLOAD Module$, VARPTR(Font(0, 0))
END IF
DEF SEG
END SUB
'++++++++++++++++++++++++
SUB ziLocateMCursor (Xcoord, YCoord)
IF Mouse THEN
MXloc = Xcoord
MYloc = YCoord
regs.AX = 4
regs.CX = Xcoord
regs.DX = YCoord
CALL zzBasicInt(&H33)
CALL ziSetMCursorVis(1)
END IF
END SUB
'++++++++++++++++++++++++
SUB ziMouseOnButton (FromButton, ToButton)
FoundButton = 0
FOR i = FromButton TO ToButton
IF Bank(i).Active THEN
IF Bank(i).Deep < 2 THEN
j = Bank(i).Wide / XYratio!
ELSE
j = Bank(i).Deep
END IF
IF MXloc > Bank(i).Xloc THEN
IF MXloc < Bank(i).Xloc + Bank(i).Wide THEN
IF MYloc > Bank(i).Yloc THEN
IF MYloc < Bank(i).Yloc + j THEN
FoundButton = i
EXIT SUB
END IF
END IF
END IF
END IF
ELSE
EXIT SUB
END IF
NEXT
END SUB
'++++++++++++++++++++++++
SUB ziPublish (PrintString$, Size, Italic)
CALL ziSetMCursorVis(10)
xx = POINT(0)
yy = POINT(1)
IF Size THEN
Scale = Size
ELSE
Scale = 1
END IF
LenString = LEN(PrintString$)
ExpScale = 8 * Scale
limxx = xx + ExpScale * LenString - 1
limyy = yy + ExpScale - 1
IF Italic AND 1 THEN
limxx = limxx + 4 * Scale
END IF
IF Italic AND 2 THEN
ELSE
LINE (xx, yy)-(limxx, limyy), BG, BF
END IF
FOR a = 0 TO LenString - 1
x = ASC(MID$(PrintString$, a + 1, 1))
b = xx + ExpScale * a
FOR Y = 0 TO 7
c = Font(x, Y)
d = Y * Scale
e = yy + d
IF Italic AND 1 THEN
f = b + 4 * Scale - (d + Scale - 1) \ 2 - 1
ELSE
f = b
END IF
g = 128
DO
IF c AND g THEN
FOR h = 0 TO Scale - 1
FOR i = 0 TO Scale - 1
PSET (f + h, e + i), FG
NEXT
NEXT
END IF
f = f + Scale
g = g \ 2
LOOP UNTIL g = 0
NEXT
NEXT
CALL zsLocateGCursor(limxx + 1, yy)
CALL ziSetMCursorVis(11)
END SUB
'++++++++++++++++++++++++
SUB ziRadio (Button, FromButton, ToButton)
IF Button >= FromButton THEN
IF Button <= ToButton THEN
FOR a = FromButton TO ToButton
Bank(a).State = 0
NEXT
END IF
END IF
Bank(Button).State = 1
CALL ziDrawBank(FromButton, ToButton)
END SUB
'++++++++++++++++++++++++
SUB ziReadField (Min, Max, Permitted$)
CALL ziSetMCursorVis(10)
atRow = CSRLIN
atCol = POS(x)
Field$ = ""
PRINT CHR$(219); SPACE$(Max);
Rules$ = UCASE$(Permitted$)
Brake = 1
WHILE Brake
x$ = ""
WHILE LEN(x$) = 0
x$ = INKEY$
WEND
IF INSTR(Rules$, "C") THEN x$ = UCASE$(x$)
oldLen = LEN(Field$)
Good = 0
IF INSTR(Rules$, ".") THEN
IF x$ = "." THEN
IF INSTR(Field$, ".") = 0 THEN
Good = 1
END IF
END IF
END IF
IF INSTR(Rules$, "N") THEN
IF INSTR("0123456789", x$) THEN
Good = 1
END IF
END IF
IF INSTR(Rules$, "S") THEN
IF x$ = " " THEN
Good = 1
END IF
END IF
IF INSTR(Rules$, "X") THEN
IF INSTR("ABCDEFGHIJKLMNOPQRSTUVWXYZ", UCASE$(x$)) THEN
Good = 1
END IF
END IF
IF INSTR(Rules$, "Y") THEN
IF INSTR("YyNy", x$) THEN
Good = 1
END IF
END IF
IF Good THEN
Field$ = Field$ + x$
IF INSTR(Field$, ".") THEN
NewMax = Max + 1
ELSE
NewMax = Max
END IF
Field$ = MID$(Field$, 1, NewMax)
END IF
' handle Bkspace
IF ASC(x$) = 8 AND LEN(Field$) THEN
Field$ = MID$(Field$, 1, LEN(Field$) - 1)
END IF
Signif$ = Field$ + "X"
WHILE INSTR(" 0", MID$(Signif$, 1, 1))
Signif$ = MID$(Signif$, 2)
WEND
IF INSTR(Signif$, ".") THEN
SignifLen = LEN(Signif$) - 2
ELSE
SignifLen = LEN(Signif$) - 1
END IF
' handle Enter
IF ASC(x$) = 13 AND SignifLen >= Min THEN
oldLen = LEN(Field$) + 1
Brake = 0
END IF
' handle Esc
IF ASC(x$) = 27 THEN
LOCATE atRow, atCol
PRINT CHR$(219); SPACE$(Max);
Field$ = ""
IF INSTR(Rules$, "E") THEN
RETURN
END IF
END IF
' reprint if change, or beep if no change
IF oldLen = LEN(Field$) THEN
BEEP
ELSE
LOCATE atRow, atCol
IF INSTR(Rules$, "P") THEN
PRINT STRING$(LEN(Field$), 254); CHR$(219); " ";
ELSE
PRINT Field$; CHR$(219); " ";
END IF
END IF
' check for auto-Enter
IF INSTR(Rules$, "A") THEN
IF SignifLen = Max THEN
Brake = 0
END IF
END IF
WEND
' justify if required
IF INSTR(Rules$, "J") THEN
WHILE MID$(Field$, 1, 1) = "0"
Field$ = MID$(Field$, 2)
WEND
Field$ = RIGHT$(SPACE$(NewMax) + Field$, NewMax)
END IF
' reprint, deleting the cursor
LOCATE atRow, atCol
IF INSTR(Rules$, "P") THEN
PRINT STRING$(LEN(Field$), 254); " ";
ELSE
PRINT Field$; " ";
END IF
CALL ziSetMCursorVis(11)
END SUB
'++++++++++++++++++++++++
SUB ziSetMCursorVis (Status) STATIC
IF Mouse THEN
SELECT CASE Status
CASE 0
IF MCursorVis THEN
regs.AX = 2
CALL zzBasicInt(&H33)
END IF
CASE 1
regs.AX = 1
CALL zzBasicInt(&H33)
CASE 10
regs.AX = &H2A
CALL zzBasicInt(&H33)
IF regs.AX = 0 THEN
TempFlag = 1
regs.AX = 2
CALL zzBasicInt(&H33)
ELSE
TempFlag = 0
END IF
CASE 11
IF TempFlag THEN
regs.AX = 1
CALL zzBasicInt(&H33)
END IF
END SELECT
regs.AX = &H2A
CALL zzBasicInt(&H33)
IF regs.AX = 0 THEN
MCursorVis = 1
ELSE
MCursorVis = 0
END IF
END IF
END SUB
'++++++++++++++++++++++++
SUB ziWander (Timeout!)
IF Timeout! = 0 THEN
WatchFor! = TIMER + 3600
ELSE
WatchFor! = TIMER + Timeout!
END IF
Response = 0
DO
x$ = INKEY$
IF LEN(x$) THEN
SELECT CASE LEN(x$)
CASE 1
a = INSTR(Allowed$, x$)
IF a THEN
Response = a
EXIT DO
END IF
SELECT CASE ASC(x$)
CASE 8: Response = 261
CASE 9: Response = 266
CASE 10: Response = 512
CASE 13: Response = 256
CASE 27: Response = 267
CASE 127: Response = 517
END SELECT
IF Response THEN
EXIT DO
END IF
CASE 2
Rightmost = ASC(RIGHT$(x$, 1))
SELECT CASE Rightmost
CASE 15: Response = 1019
CASE 59 TO 68
Response = 4038
CASE 72: Response = 187
CASE 71 TO 73
Response = 191
CASE 75: Response = 182
CASE 77: Response = 181
CASE 80: Response = 180
CASE 79 TO 81
Response = 184
CASE 84 TO 93
Response = 16301
CASE 94 TO 103
Response = 8099
CASE 115 TO 116
Response = 398
CASE 117: Response = 402
CASE 118: Response = 403
CASE 119: Response = 399
CASE 127: Response = 390
CASE 132: Response = 388
CASE 133 TO 134
Response = 3974
CASE 135 TO 136
Response = 16260
CASE 137 TO 138
Response = 8066
END SELECT
IF Response THEN
Response = Response + Rightmost
EXIT DO
END IF
END SELECT
END IF
IF Mouse AND MCursorVis THEN
regs.AX = 3
CALL zzBasicInt(&H33)
SELECT CASE regs.BX
CASE 1 TO 3
Response = 2048 + regs.BX
nowtime! = TIMER
DO
regs.AX = 3
CALL zzBasicInt(&H33)
IF regs.BX = 0 THEN EXIT DO
LOOP UNTIL TIMER - nowtime! > .3
IF regs.BX = Response - 2048 THEN
Response = Response + 3
ELSE
IF regs.BX = 0 AND Response = 2049 AND DClick THEN
nowtime! = TIMER
DO
regs.AX = 3
CALL zzBasicInt(&H33)
IF regs.BX = 1 THEN EXIT DO
LOOP UNTIL TIMER - nowtime! > .3
IF regs.BX = 1 THEN
Response = 2048
CALL ziExhaust
END IF
END IF
IF regs.BX = 3 THEN
Response = 2051
END IF
END IF
END SELECT
IF Response THEN
MXloc = regs.CX
MYloc = regs.DX
EXIT DO
END IF
END IF
LOOP UNTIL WatchFor! < TIMER
HResponse = Response \ 256
LResponse = Response MOD 256
END SUB
'++++++++++++++++++++++++
SUB zsAlignGCursor
Row = CSRLIN
Col = POS(0)
GXloc = (Col - 1) * ((Xmax + 1) \ Cols)
GYloc = (Row - 1) * (((Ymax \ Rows) * Rows + 1) \ Rows)
CALL zsLocateGCursor(GXloc, GYloc)
END SUB
'++++++++++++++++++++++++
SUB zsAlignTCursor
GXloc = POINT(0)
GYloc = POINT(1)
a = (Xmax + 1) / Cols
b = (Ymax + 1) / Rows
Col = (GXloc + a - 1) \ a + 1
Row = (GYloc + b - 1) \ b + 1
LOCATE Row, Col
CALL zsAlignGCursor
END SUB
'++++++++++++++++++++++++
SUB zsLocateGCursor (Xcoord, YCoord)
GXloc = Xcoord
GYloc = YCoord
PSET (GXloc, GYloc), POINT(GXloc, GYloc)
END SUB
'++++++++++++++++++++++++
SUB zsPastel (Xcoord, YCoord, Wide, Deep, Colour1, Colour2)
CALL ziSetMCursorVis(10)
IF Deep < 2 THEN
a = Wide / XYratio!
ELSE
a = Deep
END IF
LINE (Xcoord, YCoord)-(Xcoord + Wide - 1, YCoord + a - 1), Colour1, BF
FOR b = Xcoord TO Xcoord + Wide - 1 STEP 2
LINE (b, YCoord)-(b, YCoord + a - 1), Colour2, , &H5555
NEXT
FOR b = Xcoord + 1 TO Xcoord + Wide - 1 STEP 2
LINE (b, YCoord)-(b, YCoord + a - 1), Colour2, , &HAAAA
NEXT
CALL ziSetMCursorVis(11)
END SUB
'++++++++++++++++++++++++
SUB zsSetScrnMode (Mode, HiRows, HiCols)
CALL ziSetMCursorVis(10)
ScrnMode = Mode
IF Mode = 9 THEN
SCREEN 9
IF HiRows THEN
Rows = 43
ELSE
Rows = 25
END IF
Xmax = 639
Ymax = 349
END IF
IF Mode = 12 THEN
SCREEN 12
IF HiRows THEN
Rows = 60
ELSE
Rows = 30
END IF
Xmax = 639
Ymax = 479
END IF
IF HiCols THEN
Cols = 80
ELSE
Cols = 40
END IF
WIDTH Cols, Rows
CLS
IF Mode = 9 THEN
COLOR FG, BG
ELSE
COLOR FG
END IF
LINE (0, 0)-(Xmax, Ymax), BG, BF
LOCATE 1, 1, 0
PSET (0, 0), BG
XYratio! = .75 * (Xmax + 1) / (Ymax + 1)
CALL ziSetMCursorVis(11)
END SUB
'++++++++++++++++++++++++
SUB zsSubstitute (Xcoord, YCoord, Wide, Deep, Colour1, Colour2)
CALL ziSetMCursorVis(10)
IF Deep < 2 THEN
a = Wide / XYratio!
ELSE
a = Deep
END IF
FOR b = Xcoord TO Xcoord + Wide - 1
FOR c = YCoord TO YCoord + a - 1
IF POINT(b, c) = Colour1 THEN
PSET (b, c), Colour2
END IF
NEXT
NEXT
CALL ziSetMCursorVis(11)
END SUB
'++++++++++++++++++++++++
SUB zzBasicInt (IntType) STATIC
DIM ASM(54)
DEF SEG = VARSEG(ASM(0))
IF ASM(1) = 0 THEN
Module$ = "BASICINT.OVL"
CALL zzInPath(Module$)
IF Module$ = "" THEN
Module$ = "BASICINT.OVL"
ERROR 255
ELSE
BLOAD Module$, VARPTR(ASM(0))
END IF
END IF
CALL ABSOLUTE(regs, IntType, VARPTR(ASM(0)))
DEF SEG
END SUB
'++++++++++++++++++++++++
SUB zzInPath (Field$)
x$ = ".;" + ENVIRON$("PATH")
IF RIGHT$(x$, 1) <> ";" THEN x$ = x$ + ";"
i = 1
DO
j = INSTR(i, x$, ";")
IF j THEN
Y$ = UCASE$(MID$(x$, i, j - i))
i = j + 1
IF RIGHT$(Y$, 1) <> "\" THEN Y$ = Y$ + "\"
f$ = Y$ + Field$
bad = 0
OPEN "I", 1, f$
IF bad = 0 THEN
CLOSE 1
EXIT DO
END IF
f$ = ""
END IF
LOOP WHILE j
bad = 0
Field$ = f$
END SUB