home *** CD-ROM | disk | FTP | other *** search
- The PowerBASIC Wizard's Library
- =-----------------------------=
- Version 1.0
-
- PBWIZ Copyright (c) 1991 Thomas G. Hanlin III
-
-
-
- This is PBWiz, a library of assembly language and BASIC routines for use with
- PowerBASIC version 2.0. Full source code is available with registration. The
- PBWiz collection is copyrighted and may be distributed only under the
- following conditions:
-
- 1) No fee of over $10.00 may be charged for distribution. This
- restriction applies only to physical copies and is not meant to
- prevent distribution by telecommunication services.
-
- 2) All PBWiz files must be distributed together in original, unaltered
- form. This includes BIBLIO.TXT, CATALOG.TXT, PBWIZ.DOC, PBWIZ.NEW,
- REGISTER.TXT, WHERE.BBS, and the two archives, INCLUDES and UNITS.
-
- 3) No files may be added to the PBWiz collection. This applies most
- specifically to the practice of adding BBS ads to archives, which I
- find seriously offensive.
-
- You use this library at your own risk. It has been tested by me on my own
- computer, but I will not assume any responsibility for any problems which
- PBWiz may cause you. If you do encounter a problem, please let me know
- about it, and I will do my best to verify and repair the error.
-
- It is expected that if you find PBWiz useful, you will register your copy.
- You may not use PBWiz routines in programs intended for sale unless you have
- registered. Registration entitles you to receive the latest version of
- PBWiz, complete with full source code in assembly language and BASIC. The
- assembly code is designed for the MASM 6.0 assembler and may require minor
- modifications if you wish to use it with OPTASM, TASM, or earlier versions of
- MASM.
-
- Warning: Use of PBWiz for more than 30 days without registering has been
- determined to cause fatal nose warts in penguins! It may also encourage the
- author to practice the tuba under your window at night.
-
- Table of Contents page 2
-
-
-
- Overview and Legal Info .................................................. 1
-
- Table of Contents ........................................................ 2
-
- Archives ................................................................. 3
-
- Dates and Times .......................................................... 5
-
- Equipment Info ........................................................... 6
-
- Extended Math ............................................................ 9
-
- Graphics ................................................................ 12
-
- Mouse Support ........................................................... 15
-
- Strings ................................................................. 18
-
- Credits ................................................................. 21
-
- Archives page 3
-
-
-
- When I started in the microcomputer industry, there were a variety of file
- archivers, all (more or less) compatible. They did not provide compression,
- which was relegated to another large selection of more-or-less compatible
- utilities. Then came SEA's ARC. It was very slow, but it did compression as
- well as archiving, and included CRC checks so you could know whether the
- files were intact. It swept the BBS scene in short order, becoming the new
- standard. A few other archivers competed on about a level footing, providing
- only minor variances on the ARC theme. Then SEA decided to sue one of the
- more successful competitors, Phil Katz (PKARC). The end result was the ZIP
- standard... but in the chaos resulting from the breaking of the ARC standard,
- many other archivers came into being: ARJ, LZH, PAK, ZOO, and so forth.
-
- PBWiz helps resolve the confusion by providing a single set of routines which
- allow you to view the contents of archives in any of the above-mentioned
- formats: ARC, ARJ, LZH, PAK, ZIP, or ZOO. Only archive directories are
- provided at this time. Other formats will also be added as they arise. If
- you have details on the format of an archive that you'd like me to add,
- please send them my way. I'll do what I can to get it into PBWiz.
-
- This unit requires the STRING unit (discussed later) as well. To use it in
- your program, you need to include both units:
-
- $INCLUDE "string.inc" ' (only if you need STRING in your programs)
- $INCLUDE "archives.inc"
- $LINK "stringa.obj"
- $LINK "stringb.pbu"
- $LINK "archives.pbu"
-
- Viewing archive directories is handled in roughly the same fashion as you
- might view a DOS file directory. This makes it possible to treat an archive
- and a subdirectory in a similar manner.
-
- When you're looking for the first file in an archive, use the FindFirstA
- function. You must specify the archive name and a file name. The archive
- name may include a drive and path specification, and does not need to have
- the archive extension. If you leave off the extension, FindFirstA will use
- the first archive it comes across that matches the rest of the specification.
- Note that the archive specification may not contain wildcards. In contrast,
- the search file name may not contain drive or path specs, but may contain
- wildcards.
-
- CALL FindFirstA (Archive$, Filename$, ErrCode%)
-
- Archives page 4
-
-
-
- If there are no files to be found, or if the archive specification was bad,
- an error code will be returned. If there was no error, there may well be
- more files to be found. You can find each of them with FindNextA:
-
- CALL FindNextA (ErrCode%)
-
- Of course, just finding a matching file doesn't do you much good unless you
- can retrieve information about it. You can use any of the following routines
- to provide information about a matched file:
-
- Nam$ = GetNameA$
- Dat$ = GetDateA$
- Tim$ = GetTimeA$
- CRC$ = GetCRCA$
- StorageMethod$ = GetStoreA$
-
- CALL GetSizeA (OriginalSize&, CurrentSize&)
-
- When you're done viewing an archive, be sure to close it:
-
- CALL CloseA
-
- Let's try an example. Given that you've already written the $INCLUDE and
- $LINK lines as specified on the previous page, you could see all of the files
- in an archive using a program like this:
-
- CALL FindFirstA (Archive$, "*.*", ErrCode%)
- DO UNTIL ErrCode%
- PRINT GetNameA$
- CALL FindNextA (ErrCode%)
- LOOP
- CALL FCloseA
-
- This program fragment also assumes that you have set Archive$ to the name of
- an archive. It might be convenient to set it to the command line for testing
- purposes:
-
- Archive$ = UCASE$(LTRIM$(RTRIM$(COMMAND$)))
-
- Dates and Times page 5
-
-
-
- This unit allows you to validate and compare dates. It also provides the day
- of the week, given the date. Dates may not be before the year 1900. Date
- strings may be in the form "01/01/91" or "01-01-1991" (the delimiter is not
- significant and years may be two or four digits; two-digit years will be
- assumed to be in the 20th century).
-
- To use the routines in this unit, include the following lines at the top of
- your program:
-
- $INCLUDE "timedate.inc"
- $LINK "timedate.pbu"
-
- Let's start off with date validation. It's often important to know if a date
- entered into your program is a valid date.
-
- IF GoodDate%(DateSt$) THEN PRINT "The date is valid."
-
- It can also be helpful to know on which day of the week a given date falls.
-
- Day$ = WeekDay$(DateSt$)
-
- There are many useful things you can accomplish by turning a date into a
- number which represents that date (or vice versa). This allows you to
- compare two dates, which is important if you want to sort by date; find out
- what the date will be in a given number of days, or what it was some number
- of days ago; find the number of days between two dates; display a calendar;
- and so forth. This is easy to do with PBWiz:
-
- DateNr& = Date2Num&(DateSt$)
-
- DateSt$ = Num2Date$(DateNr&)
-
- The DateNr& represents the number of days since January 1, 1900. This is
- less than 65,535 for dates that go up to around the year 2070 or so, so you
- may wish to store the dates in compressed two-byte form if your required
- range of dates is not that large:
-
- CrunchDate% = CVI(LEFT$(MKL$(DateNr&), 2))
-
- This can be reversed simply:
-
- DateNr& = CVL(MKI$(CrunchDate%) + STRING$(2, 0))
-
- Note that dates crunched this way are only useful for storage purposes, since
- the numbers greater than 32,767 are stored as negative numbers due to the
- signed integer format BASIC uses. You must uncompress them before doing any
- comparisons or date calculations. Still, at half the size, it can be worth
- the hassle to convert back and forth.
-
- Equipment Info page 6
-
-
-
- The equipment unit gives you information about the computing environment.
- This includes both installed software and hardware. You can use the
- equipment information routines by including these lines in your program:
-
- $INCLUDE "equipmen.inc"
- $LINK "equipmen.obj"
-
- The first function allows you to determine if an "enhanced" keyboard
- (101-key) is installed. It may not be able to figure out what the keyboard
- is on some older not-quite-clone PCs, in which case it will take the safe way
- out and report that there is no enhanced keyboard. This function returns -1
- if there is an enhanced keyboard present, 0 if not.
-
- Enhanced% = KbdType%
-
- Want to know the type of processor (CPU) being used? Can do!
-
- CPU% = Processor%
-
- The results will be reported as a number which can be decoded as follow:
-
- 0 NEC V20
- 1 8088 or 8086
- 2 80186
- 3 80286
- 4 80386 or 80486
-
- If anyone knows how to differentiate between an 80386 and an 80486, please
- let me know. I've only seen one test which could do it, and it wasn't
- reliable.
-
- Maybe you'd like to check for a CD-ROM drive:
-
- Drives% = CDROM%
-
- This tells you how many logical drives exist, if there is a CD-ROM available.
- If not, it will return 0. Note that the CD-ROM installation check conflicts
- with the GRAPHICS.COM installation check for DOS 4.0, due to some screw-up at
- IBM or Microsoft. I'm not yet sure whether DOS 5.0 is similarly afflicted.
-
- The number of floppy drives installed is retrieved like this:
-
- Drives% = Floppies%
-
- Equipment Info page 7
-
-
-
- Now, there may be up to four floppy drives in a system; however, the AT CMOS
- data area only directly supports two. This makes it easy to find out what
- kind of drives the first two are, but not the second two. Oh well, guess
- we'll have to settle for what we can get, right?
-
- CALL FloppyType (Drive1, Drive2)
-
- The results from FloppyType are returned as follows:
-
- 0 no drive
- 1 5 1/4" 360K
- 2 5 1/4" 1.2M
- 3 3 1/2" 720K
- 4 3 1/2" 1.44M
-
- Result codes of 5-7 are available, but not yet defined. One might guess that
- the 2.88M drive supported by DOS 5.0 will be drive type 5. Has anybody seen
- one of those puppies yet?
-
- New memory types sure have burgeoned over the years... expanded, extended,
- and now XMS. There are routines to check all of these:
-
- BaseExt& = AllExtMem& ' amount of extended memory actually installed
- NowExt& = GetExtM& ' amount of BIOS extended memory available
-
- CALL GetEMSm (TotalPages%, FreePages%) ' amount of expanded memory
-
- CALL GetXMSm (LargestFree&, TotalFree&) ' amount of XMS memory
-
- When you're dealing with extended memory, whether it be BIOS-type or using
- the XMS standard, the results are returned in kilobytes. Multiply 'em by
- 1024 to convert to bytes. When you're dealing with expanded memory (EMS),
- the results are in pages of 16,384 bytes.
-
- I might note, by the way, that Microsoft seems to have intentionally crippled
- the XMS standard. It can only support a maximum of 64 megabytes. This may
- seem like a lot now, but I can remember when my first PC (a Compaq portable)
- was the awe of the neighborhood with 384K RAM! A few years down the road,
- the artificial limitations of XMS are going to be a real nuisance.
-
- A few more routines to get the versions of the EMS and XMS drivers, if any:
-
- CALL GetEMSv (MajorV%, MinorV%)
- CALL GetXMSv (MajorV%, MinorV%)
-
- These return the major and minor version numbers as two separate integers.
- For example, EMS 4.0 would return major version 4, minor version 0.
-
- Equipment Info page 8
-
-
-
- It's nice to know a little about the operating environment. With the below
- routines, you can find out what the DOS version is; what version of 4DOS, if
- any, is in use; and whether Microsoft Windows is running.
-
- CALL GetDOSv (MajorV%, MinorV%)
- CALL Get4DOSv (MajorV%, MinorV%)
- CALL WinCheck (MajorV%, MinorV%)
-
- These return results as major and minor version numbers, as discussed on the
- previous page. The Get4DOSv and WinCheck routines return zeroes if 4DOS and
- Windows, respectively, are not available.
-
- There are a couple of curious features of GetDOSv to keep in mind. If the
- version is 10 or higher, you're running in OS/2 compatibility mode. DOS
- version 10 is actually OS/2 1.0, version 20 is OS/2 2.0, and so on.
- Secondly, if you're using DOS 5.0, the version reported may not be 5.0-- DOS
- 5.0 can be told to reply with a lower version number to allow some older
- software (which checks for a specific DOS version) to run properly.
-
- One final routine that should be of some value is the one that allows you to
- find out what kind of display is available. It tells you the specific
- adapter and whether the display is color or monochrome. There is one case in
- which it can be confused, however-- if the adapter is CGA, the display is
- assumed to be color, since there is no way for the computer to know any
- differently. So, although this routine provides a good idea of what is
- available, it would be a good idea to provide an option to tell the program
- that a monochrome display is attached. Microsoft normally uses "/B" for this
- purpose, so that might be a good standard to stick with.
-
- CALL GetDisplay (Adapter%, Mono%)
- IF Mono% THEN
- PRINT "Monochrome monitor"
- ELSE
- PRINT "Color monitor"
- END IF
- SELECT CASE Adapter%
- CASE 1: PRINT "MDA"
- CASE 2: PRINT "Hercules"
- CASE 3: PRINT "CGA"
- CASE 4: PRINT "EGA"
- CASE 5: PRINT "MCGA"
- CASE 6: PRINT "VGA"
- END SELECT
-
- Extended Math page 9
-
-
-
- The extended math unit provides an expression evaluator and extensions to
- BASIC's math. The math extensions include hyperbolic and inverse trig
- functions, a few handy constants, conversions, and more. You can use the new
- math routines by including this at the top of your program:
-
- $INCLUDE "extmath.inc"
- $LINK "extmath.pbu"
-
- The expression evaluator allows you to find the result of an expression
- contained in a string. Normal algebraic precedence is used, e.g. 4+3*5
- evaluates to 19. The usual numeric operators (*, /, +, -, ^) are supported
- (multiply, divide, add, subtract, and raise to a power). Use of negative
- numbers is just fine, of course. Parentheses for overriding the default
- order of operations are also supported.
-
- You may use either a double asterisk ("**") or a caret ("^") symbols to
- indicate exponentiation.
-
- To evaluate an expression, you pass it to the evaluator as a string. You
- will get back either an error code or a single-precision result. Try this
- example to see how the expression evaluator works:
-
- $STACK 4096
- $INCLUDE "extmath.inc"
- $LINK "extmath.pbu"
- DO
- INPUT "Expression? "; Expr$
- IF LEN(Expr$) THEN
- CALL Evaluate (Expr$, Result!, ErrCode%)
- IF ErrCode% THEN
- PRINT "Invalid expression. Error = "; ErrCode%
- ELSE
- PRINT "Result: "; Result!
- END IF
- END IF
- LOOP WHILE LEN(Expr$)
- END
-
- An expression evaluator adds convenience to any program that needs to accept
- numbers. Why make someone reach for a calculator when number crunching is
- what a computer does best?
-
- NOTE: The expression evaluator uses recursion and will require more than the
- default amount of stack space. That's why the $STACK metacommand is used.
-
- Extended Math page 10
-
-
-
- The new math functions are pretty much self-explanatory, so I'll just list
- them here. A few general notes are given on the next page.
-
- Result% = GCDI%(Nr1%, Nr2%) ' greatest common denominator
-
- Result& = GCDL&(Nr1&, Nr2&) ' greatest common denominator
-
- Result! = ArcCosHS!(Nr!) ' inverse hyperbolic cosine
- Result! = ArcSinHS!(Nr!) ' inverse hyperbolic sine
- Result! = ArcTanHS!(Nr!) ' inverse hyperbolic tangent
- Result! = ArcCosS!(Nr!) ' arc cosine (1 >= Nr >= -1)
- Result! = ArcSinS!(Nr!) ' arc sine (1 >= Nr >= -1)
- Result! = ErfS!(Nr!) ' error function
- Result! = FactS!(Nr%) ' factorial
- Result! = CotS!(Nr!) ' cotangent
- Result! = CscS!(Nr!) ' cosecant
- Result! = SecS!(Nr!) ' secant
- Result! = CosHS!(Nr!) ' hyperbolic cosine
- Result! = SinHS!(Nr!) ' hyperbolic sine
- Result! = TanHS!(Nr!) ' hyperbolic tangent
- Result! = Deg2RadS!(Nr!) ' convert degrees to radians
- Result! = Rad2DegS!(Nr!) ' convert radians to degrees
- Result! = Cent2Fahr!(Nr!) ' convert centigrade to Fahrenheit
- Result! = Fahr2Cent!(Nr!) ' convert Fahrenheit to centigrade
- Result! = Kg2Pound!(Nr!) ' convert kilograms to pounds
- Result! = Pound2Kg!(Nr!) ' convert pounds to kilograms
- Pi! = PiS! ' the constant "pi"
- e! = eS! ' the constant "e"
-
- Result# = ArcCosHD#(Nr#) ' inverse hyperbolic cosine
- Result# = ArcSinHD#(Nr#) ' inverse hyperbolic sine
- Result# = ArcTanHD#(Nr#) ' inverse hyperbolic tangent
- Result# = ArcCosD#(Nr#) ' arc cosine (1 >= Nr >= -1)
- Result# = ArcSinD#(Nr#) ' arc sine (1 >= Nr >= -1)
- Result# = ErfD#(Nr#) ' error function
- Result# = FactD#(Nr%) ' factorial
- Result# = CotD#(Nr#) ' cotangent
- Result# = CscD#(Nr#) ' cosecant
- Result# = SecD#(Nr#) ' secant
- Result# = CosHD#(Nr#) ' hyperbolic cosine
- Result# = SinHD#(Nr#) ' hyperbolic sine
- Result# = TanHD#(Nr#) ' hyperbolic tangent
- Result# = Deg2RadD#(Nr#) ' convert degrees to radians
- Result# = Rad2DegD#(Nr#) ' convert radians to degrees
- Pi# = PiD# ' the constant "pi"
- e# = eD# ' the constant "e"
-
- Extended Math page 11
-
-
-
- Like BASIC's trig functions, these trig functions expect the angle to be in
- radians. Conversion functions are provided in case you prefer degrees.
-
- Note that there is no ArcTanS! or ArcTanD# function for the simple reason
- that BASIC supplies an ATN function.
-
- Constants are expressed to the maximum precision available.
-
- If you are not familiar with variable postfix symbols, here's a summary:
-
- Symbol Meaning Range (approximate)
- ------ -------- -----------------------------------
- % integer +- 32767
- & long integer +- 2 * 10^9
- ! single precision +- 1 * 10^38 (7-digit precision)
- # double precision +- 1 * 10^308 (15-digit precision)
-
- See your BASIC manual or PowerBASIC's online help for further details.
-
- Graphics Support page 12
-
-
-
- I was rather surprised to find that PowerBASIC lacks support for one of the
- standard VGA modes-- SCREEN 13, the 320x200 256-color mode. I immediately
- decided to add support for that mode: dots, lines, boxes, polygons, and (of
- course) text. While I was at it, I thought I'd add support for a nonstandard
- VGA mode: 360x480 in 256 colors. This mode will work on almost any plain VGA
- system, although it might not work on some older not-quite-compatible setups.
- I'll be adding other modes as I go along, including SuperVGA modes. For now,
- there are only two modes:
-
- 13 320x200, 256 colors, 40x25 text, standard (any VGA)
- N0 360x480, 256 colors, 45x30 text, nonstandard (almost any VGA)
-
- The graphics routines all use the same nomenclature: a G, followed by a mode
- number, followed by the specific name. This generic naming convention is
- used so that this chapter can refer to all available modes. For example, if
- I say "G#Color" and you're using mode 13, you'd actually use "G13Color" in
- your program. Ok?
-
- There are two sets of routines for each mode-- the ones written in ASM and
- the ones written in BASIC. The file names for these will be suffixed with
- "A" for ASM and "B" for BASIC. For instance, to use the SCREEN 13 routines,
- you would add the following at the top of your program:
-
- $INCLUDE "g13.inc"
- $LINK "g13a.obj"
- $LINK "g13b.pbu"
-
- The first thing you will always have to do is to put the screen into the
- proper mode. This is done with the G#Mode routine:
-
- CALL G#Mode (Graphics%)
-
- Use 0 to switch to text mode or any other value to switch to graphics mode.
-
- One difference between BASIC and BasWiz is that, instead of each "draw"
- command requiring a color parameter as in BASIC, the PBWiz library provides
- a separate color command:
-
- CALL G#Color (Foreground%, Background%)
-
- The "foreground" color is used by all graphics routines. The background
- color is used by the G#Cls routine. Both foreground and background colors
- are used in the G#Write and G#WriteLn routines.
-
- Graphics Support page 13
-
-
-
- Here is a list of the corresponding routines, first BASIC, then PBWiz
- (replace the "#" with the appropriate mode number):
-
- ' get the color of a specified point
- colour% = POINT(x%, y%)
- colour% = G#GetPel%(x%, y%)
-
- ' set the color of a specified point
- PSET (x%, y%), colour%
- CALL G#Color (colour%, backgnd%): CALL G#Plot (x%, y%)
-
- ' draw a line of a specified color
- LINE (x1%, y1%) - (x2%, y2%), colour%
- CALL G#Color (colour%, backgnd%): CALL G#Line (x1%, y1%, x2%, y2%)
-
- ' draw a box frame of a specified color
- LINE (x1%, y1%) - (x2%, y2%), colour%, B
- CALL G#Color (colour%, backgnd%): CALL G#Box (x1%, y1%, x2%, y2%, 0)
-
- ' draw a box of a specified color and fill it in
- LINE (x1%, y1%) - (x2%, y2%), colour%, BF
- CALL G#Color (colour%, backgnd%): CALL G#Box (x1%, y1%, x2%, y2%, 1)
-
- ' clear the screen and home the cursor
- CLS
- CALL G#Cls
-
- ' get the current cursor position
- Row% = CSRLIN: Column% = POS(0)
- CALL G#GetLocate (Row%, Column%)
-
- ' set the current cursor position
- LOCATE Row%, Column%
- CALL G#Locate (Row%, Column%)
-
- ' display a string without a carriage return and linefeed
- PRINT St$;
- CALL G#Write (St$)
-
- ' display a string with a carriage return and linefeed
- PRINT St$
- CALL G#WriteLn (St$)
-
- Note that PBWiz, unlike BASIC, allows both foreground and background colors
- for text in graphics mode.
-
- Graphics Support page 14
-
-
-
- If you need to print a number rather than a string, just use the BASIC
- function STR$ to convert it. If you don't want a leading space, use this
- approach:
-
- St$ = LTRIM$(STR$(Number))
-
- The PBWiz library has other routines which have no BASIC equivalent. One
- allows you to get the current colors:
-
- CALL G#GetColor (Foreground%, Background%)
-
- Circles and ellipses can be drawn with the Ellipse routine. This is similar
- to the BASIC CIRCLE statement. You specify the center of the ellipse (X,Y),
- plus the X and Y radius values:
-
- CALL G#Ellipse (CenterX%, CenterY%, XRadius%, YRadius%)
-
- A circle is an ellipse with a constant radius. So, to draw a circle, just
- set both radius values to the same value.
-
- As well as the usual points, lines, and ellipses, PBWiz also allows you to
- draw regular polygons: triangles, squares, pentagons, hexagons, and so on.
-
- CALL G#Polygon (X%, Y%, Radius%, Vertices%, Angle!)
-
- The X% and Y% values represent the coordinates of the center of the polygon.
- The Radius% is the radius of the polygon (as if you were fitting it into a
- circle). Vertices% is the number of angles (also the number of sides) for
- the polygon to have. Angle! specifies the rotation of the polygon, and is
- specified in radians.
-
- Mouse Support page 15
-
-
-
- The mouse unit provides full-featured mouse support. You can see if a mouse
- is available and how many buttons it has, get the cursor position (either the
- current position or the position at the last press or release of a specified
- button), set the cursor position, change the cursor, set the mouse range, get
- hardware information about the mouse, and so on.
-
- This unit is called MOUSE, so you access it by including the following lines
- at the top of your program:
-
- $INCLUDE "mouse.inc"
- $LINK "mouse.obj"
-
- There are two unusual mouse modes to be aware of. One is text mode, which is
- mapped to a 640x200 virtual display. So, to convert the results to text
- format, you need to divide the cursor position by eight and add one. To
- convert from text format, subtract one and multiply by eight.
-
- The second unusual mode is 320x200 CGA mode, which is also mapped to 640x200.
- To convert the coordinates to this mode, divide X by two. To convert from
- this mode, multiply the X coordinate by two.
-
- All other modes use the actual display coordinates instead of a bizarro
- virtual screen. Why the peculiar CGA and text modes? Well, evidently
- Microsoft never thought there'd be any video adapters besides MDA and CGA,
- and decided to create a single virtual screen size that worked for all modes.
- Not a bad idea, I guess, but rather shortsighted. Oh well.
-
- One other nuisance that you may run into is that the mouse cursor can't be
- directly turned on or off. A "cursor visibility" count is maintained-- if
- the mouse cursor was turned on twice, you'll need to turn it off twice before
- it will actually disappear.
-
- Before using the mouse, you must initialize it. The initialization routine
- also checks to make sure that a mouse is installed and tells you how many
- buttons it has. It's best to initialize the mouse after setting the screen
- mode, so the mouse driver understands what mode you're using. Not all mouse
- drivers support all screen modes, but you can reasonably expect any current
- mouse driver to support MDA, CGA, EGA, and VGA. Hercules graphics mode is
- rarely supported, as it must be set through direct hardware access rather
- than the standard techniques, so the mouse driver has little way of knowing
- that you've changed the mode.
-
- The mouse routines will work equally well with two-button or three-button
- rodents. The middle button functions will return 0 with two-button mice.
-
- I won't go into great detail on these routines, because they're pretty much
- self-explanatory. The mouse is a fairly easy device to deal with.
-
- Mouse Support page 16
-
-
-
- You can initialize the mouse driver like so:
-
- Buttons% = MouseInit%
-
- This returns the number of mouse buttons available. If there is no mouse,
- zero will be returned. Initialize the mouse after setting the screen mode.
-
- You can make the mouse cursor visible or invisible. It will function just as
- well in either state. See the previous page for some quirks.
-
- CALL MouseShow ' show the cursor
- CALL MouseHide ' hide the cursor
-
- There are many ways to get the mouse cursor position. You can get the
- current position, the position at which the mouse was located when a
- particular button was pressed, or the position when a button was released.
- If you choose a past position, you can also find out how many presses or
- releases of the button have taken place since you last checked.
-
- X% = MouseWhereX% ' return current X coordinate
- Y% = MouseWhereY% ' return current Y coordinate
-
- CALL MouseLClick (Count%, X%, Y%) ' left presses and posn at last press
- CALL MouseMClick (Count%, X%, Y%) ' middle presses & posn at last press
- CALL MouseRClick (Count%, X%, Y%) ' right presses & posn at last press
-
- CALL MouseLRelease (Count%, X%, Y%) ' left releases and posn at last rel.
- CALL MouseMRelease (Count%, X%, Y%) ' middle releases & posn at last rel.
- CALL MouseRRelease (Count%, X%, Y%) ' right releases & posn at last rel.
-
- If you'd prefer to find out which buttons are currently pressed, no problem:
-
- Pressed% = MouseLButton% ' whether the left button is pressed
- Pressed% = MouseMButton% ' whether the middle button is pressed
- Pressed% = MouseRButton% ' whether the right button is pressed
-
- Of course, if you can get the cursor position, you must be able to set it:
-
- CALL MouseLocate (X%, Y%) ' set the mouse cursor position
-
- The mouse cursor range can be restricted to a given area of the screen. This
- area is expressed by giving the upper left corner and lower right corner of
- the rectangular area to which to restrict the cursor.
-
- CALL MouseWindow (X1%, Y1%, X2%, Y2%)
-
- Mouse Support page 17
-
-
-
- There are a variety of cursor shapes available for graphics mode:
-
- 0 hourglass (standard "please wait, I'm working" symbol)
- 1 pointing arrow (default)
- 2 pointing hand
- 3 crosshair
- 4 target (box in a box)
- 5 grabbing hand
-
- If you have ideas for more, let me know and I'll see what I can do.
-
- The cursor image is set like so:
-
- CALL MouseCursorG (CursorNr%)
-
- Strings page 18
-
-
-
- One of the true strengths of BASIC lies in its powerful string handling
- capability. I'd be remiss if I didn't provide extensions which improve it
- even further. This unit can be accessed by including these lines at the top
- of your program:
-
- $INCLUDE "string.inc"
- $LINK "stringa.obj"
- $LINK "stringb.pbu"
-
- The simplest of the PBWiz string routines may seem somewhat whimsical, but it
- has proven useful to me on several occasions in the past. It reverses the
- order of characters in a string.
-
- CALL Reverse (St$)
-
- One of the places this has come in useful is in searching a string from the
- end-- a reverse INSTR routine:
-
- CALL RInstr (MainSt$, SubSt$, Posn%)
-
- Rather than returning the first occurrence of a substring within a main
- string, it returns the last occurrence. Another handy string search allows
- you to search for various types of characters, rather than a specific
- substring:
-
- CALL TInstr (MainSt$, Types%, Posn%)
-
- The type(s) may be specified using any combination of the following. Just
- add them together.
-
- 1 alphabetic
- 2 numeric
- 4 symbolic
- 8 control
- 16 graphics
- 32 space
-
- Since you can search for any specific types, you can also readily invert the
- search to look for any characters that are NOT of a given type or types:
-
- Types% = NOT Types%
-
- This gives you complete control. A typical use for TInstr might be to clean
- up user input and make sure that it's valid. It's also good for parsing.
-
- Strings page 19
-
-
-
- Another routine that is useful for cleaning up and parsing user input is
- called Crunch. It allows you to eliminate adjacent duplicates of a character
- or list of characters. One use for this, for instance, would be to eliminate
- repeated spaces, converting an input string from "*.* *.BAK /B" to a more
- manageable "*.* *.BAK /B".
-
- Result$ = Crunch$(St$, CharList$)
-
- There are a pair of routines that you'll find valuable if you need to check
- the validity of a string. These are designed to be compatible with the
- Xmodem and Ymodem file transfer protocols, so you can use them for error
- checking in telecommunications as well.
-
- Chk% = CheckSum% (St$)
-
- CALL CRC16 (St$, HiCRC%, LoCRC%)
-
- Another pair of string routines provide a simple encryption/decryption system
- for text. The method used is not particularly secure but are very fast and
- will be adequate for many purposes. As always, it helps to use a long and/or
- complex password.
-
- CALL Cipher (St$, Password$)
- CALL CipherP (St$, Password$)
-
- Both of these routines will encipher text on the first run-through and
- decipher on the second, so you can use the same routine either to encrypt or
- decrypt a message. They are different in one respect: the encrypted result
- of Cipher may contain control characters, so it can't be used in a plain
- sequential-access file. The CipherP routine does not allow use of extended
- ASCII characters (CHR$(128) - CHR$(255)), as it sets the high bit on each
- character after encrypting it. This causes the results of CipherP to be
- printable (and useful in sequential-access files), although they will look
- very strange.
-
- The strings are encrypted (or decrypted) in place. This provides a certain
- extra measure of security for encryption-- the original plaintext strings are
- not left floating around in memory where someone might see them.
-
- One function is as much a file manipulation routine as it is a string
- function. It allows you to compare a file name to a file pattern (which may
- contain wildcards) to see if they match. Only bare filespecs are supported--
- you may not use drive or path specifications in the names.
-
- IF MatchFile%(Pattern$, Filename$) THEN PRINT Filename$
-
- This can be used in creating your own DOS-style utilities: DIR, COPY, and so
- forth. Besides the usual "accept file if it matches" approach, it can also
- be used to implement the opposite: "exclude file if it matches." This gives
- you more flexibility than DOS itself supplies.
-
- Strings page 20
-
-
-
- The PowerBASIC compiler provides a very nice function called Extract$. This
- allows you to retrieve a substring running from the left side of a main
- string to a specified character delimiter. Not bad, but it might be handy to
- be able to grab a numbered substring from any part of a main string, and to
- be able to use a substring delimiter. For instance, you might load a record
- from a database which contains an address, where each line is delimited by a
- carriage return and linefeed. Rather than mucking around with Extract$,
- which really wasn't designed with that sort of thing in mind, you'd do better
- to use the PBWiz function called DelimExtract$:
-
- SubSt$ = DelimExtract$(St$, Delimiter$, Index%)
-
- The index starts at 1 with the first substring. If you choose the index of a
- substring which doesn't actually exist, a null string will be returned.
-
- Credits page 21
-
-
-
- I'd like to thank Dave Navarro for letting me in on the world of PowerBASIC.
- His assistance has been most valuable to me in many respects. Without him,
- this library would have taken much longer to get off the ground or would
- perhaps not even exist. Dave runs the excellent Bard's Lair BBS-- see my
- WHERE.BBS file for more details.
-
- I would also like to thank Spectra, publishers of PowerBASIC, for sending me
- the evaluation copy which led to my decision to write this library.
-
-