Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MPL Documentation: Difference between revisions

From The Bottomless Abyss BBS Wiki
No edit summary
No edit summary
 
Line 79: Line 79:




1.  All text after a number sign (#) is considered a comment.  It will
'''1.  All text after a number sign (#) is considered a comment.  It will '''
   be ignored until the next line of code.  For example:
'''   be ignored until the next line of code.  For example: '''


   WriteLn ('Hello There')  # This is a comment and will be ignored.
   WriteLn ('Hello There')  # This is a comment and will be ignored.


2.  Operation types:
''' 2.  Operation types: '''


   The MPL does not follow the order of operations when doing
   The MPL does not follow the order of operations when doing
Line 107: Line 107:
       %   Modulus Operator
       %   Modulus Operator


2a. Bitwise math:
''' 2a. Bitwise math: '''


   MPL fully supports bitwise math and operators!  The following are
   MPL fully supports bitwise math and operators!  The following are
Line 198: Line 198:
<nowiki>   Var <VarName> :  ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType></nowiki>
<nowiki>   Var <VarName> :  ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType></nowiki>


   Examples:
'''   Examples: '''


<nowiki>   Var Dummy : Array[1..10] of Byte</nowiki>
<nowiki>   Var Dummy : Array[1..10] of Byte</nowiki>
Line 222: Line 222:
   If Value = $10 Then WriteLn('Value is 16 <in decimal>');
   If Value = $10 Then WriteLn('Value is 16 <in decimal>');


3b. Record structures:  Groups data in to records.  This command
''' 3b. Record structures:  '''
 
Groups data in to records.  This command


   allows you to create a datatype of multiple different variable  
   allows you to create a datatype of multiple different variable  

Latest revision as of 02:03, 26 February 2019

The Mystic BBS Programming Language Documentation

Copyright (C) 1998-2015 By James Coyle.  All Rights Reserved

All mentioned programs are copyrighted by their respective authors

-----------------------------------------------------------------------

Introduction to Mystic Programming Language (MPL)

-----------------------------------------------------------------------

The Mystic Programming Language (refered to as MPL from here on out) is

not complete.  In the state that it's in now, its still more powerful

than most BBS script languages, but its still not to the point where

it is as powerful as it should be.


The documentation for the MPL is also not complete.  This documentation

as well as the Mystic BBS documentation will be worked on as time

permits and may not be completed for quite some time.  There are some

example programs included with the distribution (found in the scripts

directory) which may help assist you in getting the hang of the MPL

structure and commands.


If you have written any useful MPL programs, please send them via e-mail

to [email protected] so they can be included for download on the

various Mystic BBS support sites.

-----------------------------------------------------------------------

General Notes About Using The MPL

-----------------------------------------------------------------------

The syntax of the Mystic BBS Programming Language follows closely to

that of the Turbo Pascal series of programming compilers.  At one time,

the language was almost 100% Turbo Pascal compatible (except for the

BBS functions) but it has been slightly changed to make it a little

more friendly to the programmer.


Two versions of the programming compiler are available in the scripts

directory.  The first one, MIDE.EXE, is a fully functional IDE for

creating and compiling MPE programs.  This program looks similar to the

Turbo Pascal IDE, including syntax highlighting of all command keywords!

The second version of the compiler is MPLC.EXE.  This is a command line

compiler supplied so you are not forced to use MIDE.EXE to write

programs.  If you do not find the MIDE interface to be satisfactory, then

you can use your favorite text editor and MPLC.EXE to create programs!

The following are some quick notes about the syntax of the language as

well as some notes about things that aren't working as they probably

should be:


1.  All text after a number sign (#) is considered a comment.  It will    be ignored until the next line of code.  For example:

   WriteLn ('Hello There')  # This is a comment and will be ignored.

2.  Operation types:

   The MPL does not follow the order of operations when doing

   mathmatical equations (ie PEMDAS - parenthesis, exponents,

   multiplication, division, addition, subtraction).  So math    functions are done in the order that they appear in the expression.    This doesn't mean its not POSSIBLE to do PEMDAS-ordered expressions,    it will just take a little more effort on the programmer's behalf.    The following operation codes are supported for mathmatical    equations:

       -   Subtract

       +   Addition

       *   Multiplication

       /   Division

       %   Modulus Operator

2a. Bitwise math:

   MPL fully supports bitwise math and operators!  The following are    implemented:

   AND - Bitwise AND

   OR  - Bitwise OR

   XOR - Bitwise exclusive OR

   SHL - Bitwise shift left

   SHR - Bitwise shift right

   Example:

   Const

   UserDeleted = $04;  // established bit for userdeleted from records.pas

                       // note: this value has changed check records.pas!

   Begin

   GetThisUser

   If UserFlags AND UserDeleted <> 0 Then

    WriteLn('User is deleted');

   End;

3.  Defining variables:  All variables are global to all of the program,

   including procedures.  The syntax for declaring a variable follows:

   Var <VarName> : <VarType>

   Examples:

   var dummy : byte

   var str   : string

   var

     dummy : byte,

     str   : string

   The following variable types are supported:

   Type            Format         Range

   --------------- -------------- -----------------------------------

   Boolean         FALSE/TRUE     0..1

   Char            Text           1 character

   String          Text           Sequence of 1..255 characters

   Byte            Numerical      0..255

   Integer         Numerical      -32767..32767

   Word            Numerical      0..65535

   LongInt         Numerical      -2147483648..214748364

   Real            Numerical      9.99

   All variables exept ARRAYs can be initialized when when defined.

   Var TotalBases : LongInt = GetMBaseTotal(False)

   Var Int        : Integer = 33

   Var Str        : String = 'This is a string'

   ARRAY multi-dimensional variables are supported.  The syntax for

   declaring an array variable is:

   Var <VarName> :  ARRAY[<Low>..<High>] of <VarType>

   Var <VarName> :  ARRAY[<L>..<H>, <L>..<H>] of <VarType>

   Var <VarName> :  ARRAY[<L>..<H>, <L>..<H>, <L>..<H>] of <VarType>

   Examples:

   Var Dummy : Array[1..10] of Byte

   Var Str   : Array[5..10] of String

   Var Int   : Array[1..10,1..10,1..10] of Integer

   HEXIDECIMAL values are supported.  They can be used in numeric

   variable assignment numerical evaluation, and in numeric constant

   variables.  A hex value must begin with a $ character.  

   Some examples:

   Const

      MyHexValue = $1F;

   Value := $10;

   If Value = $10 Then WriteLn('Value is 16 <in decimal>');

3b. Record structures: 

Groups data in to records.  This command

   allows you to create a datatype of multiple different variable

   types.

   Defining the record:

   Type

     testrec = record

     x : byte;

     y : byte;

     d : array[1..10,1..5] of string[9]

   end

   Declaring the record:

       Var struct : testrec

   Using the record:

       struct.x:=1

       struct.y:=10

       struct.d[1,1]:='abc123'

   

3c. CODE BLOCKS:  When using multiple lines (more than one line) within a

   IF/ELSE/WHILE/CASE blocks, the lines need to be grouped into

   blocks between BEGIN and END statments.  If there is only one line

   following the IF/ELSE/WHILE/CASE blocks, then no blocking statements

   are needed.

   Examples:

 

   If X = 1 Then

   Begin

      WriteLn('X = '+Int2Str(X))

      X:=X+1

      WriteLn('X = '+Int2Str(X))

   End

   The same is true for the ELSE block.

   If X = 1 Then

   Begin

      WriteLn('X = '+Int2Str(X))

      X:=X+1

      WriteLn('X = '+Int2Str(X))

   End

   Else

   Begin

      WriteLn('X = '+Int2Str(X))

      X:=X-1

      WriteLn('X = '+Int2Str(X))

   End

4.  FOR LOOPS (FOR/FEND):  The syntax for a for loop is as follows:

   For <variable> := <start number> <TO> or <DOWNTO> <end number> Do.  

   For A := 1 to 10 Do

        WriteLn (A)

   For A := 10 DownTo 1 Do

   Begin

        WriteLn (A)

        WriteLn (A)

   End

5.  REPEAT/UNTIL:  The syntax for a repeat until loop is as follows:

   Repeat

        <Code here>

   Until <Boolean Expression>

   IE:

   Repeat

        WriteLn ('Blah blah')

   Until A > 0 or A = 5

6.  WHILE:  The syntax for a while loop is as follows:

   While <Boolean Expression> Do

         <Code Here>

   IE:

   While A > 0 and A = 5 Do

       WriteLn ('Blah')

   OR:

   While A > 0 and A = 5 Do

   Begin

       WriteLn ('Blah')

       WriteLn ('More Blah')

   End

7. PROCEDURES: The syntax for defining a procedure is as follows:

  Procedure <Proc Name> (<varname vartype>, <varname vartype>)

    <Code here>

  IE:

  Procedure Hello_World

    WriteLn ('Hello World')

  OR:

  Procedure SomeProc (Str String, A Byte)

    WriteLn ('Str = ' + Str)

    WriteLn ('A   = ' + A)

  End

  OR:

  Procedure SomeProc (Str String)

  Var

    Str2 : String,

    Str3 : String

  Begin             <--- The keyword "BEGIN" is ignored by the compiler           

    WriteLn (Str)        just to maintain a "Pascal-like" feel.

  End

8. IF THEN/ELSE/END:  The syntax of an if/else/end statement:

  If <boolean statement> Then

     <True code here>

  Else If <boolean statement> Then     (optional)

     <True code here>

  Else                            (optional)

     <False code here>

  If Not fEof(fptr) Then

       WriteLn ('We''re not at the end of the file.')

  The above example is the same as the following example, except we've

  added an else statement:

  If fEof(fptr) = False Then

       WriteLn ('We''re not at the end of the file.')

  Else

       WriteLn ('This is the end of the file.')

  If A = 1 Then

       WriteLn ('A is 1')

  Else If A = 2 Then

       WriteLn ('A is 2')

  Else If A = 5 Then

       WriteLn ('A is 5')

  Else

       WriteLn ('A is not 1, 2, or 5...')

8a. CASE statements

   This has actually been expanded on

   from the Pascal standard but still follows the same syntax.  It has been

   expanded to allow CASE of more variable types, such as strings.  See

   the included MPLTEST.MPS for examples.

   Var I : Integer = 10

   Case I Of

      1 : WriteLn('I = 1')

      2 : Begin

            I:=I+1

            WriteLn('I = 3')

          End

      2,3,4,5,6,7,8,9: WriteLn('Not 1, 2, or 10')

   End

   Var S : String = 'ABCDEFG'

   Case S[3] Of

      'A': WriteLn('S[3] = '+S[3])

      'B','C','D': WriteLn('S[3] = '+S[3])

   Else

      WriteLn('This is the default choice')

   End

9.  The USES command must be declared before ANY other variables

   or your program may not function properly.  See documentation for

   the USES command for further information.

10. FUNCTIONS: The syntax for defining a function is as follows:

   Function <Function Name> (<varname vartype>) : <result type>

   IE:

   Function AddTen (Num Byte) : Byte

   Begin

     AddTen := Num + 10

   End

11. CONST VARIABLES: The syntax for a constant variable is as follows:

   String constants:

   Const

     SomeStr = 'Hello World!'

   Numerical constants:

   Const

     SomeNum = 69

   Constant variables, like regular variables, can be separated with a

   comma:

   Const

     SomeNum = 69,

     SomeStr = 'Hello World!'

   At the moment, constant variables cannot be used in certain places

   within the MPE engine.  If you are assigning a value to a variable,

   constant values will not be recongnized.

-----------------------------------------------------------------------

General Functions and Procedures

-----------------------------------------------------------------------

Function ABS (Num: LongInt) : LongInt

   This function takes a signed integer and returns the absolute value.

   Example:

   Var Int : LongInt = -1234

   WriteLn('The absolute value of '+Int2str(Int) +' is '+Abs(Int)+'.')

Function ALLOWARROW (Boolean)

   

   Used to turn on arrow key processing in the READKEY function.  It is

   also used outside of MPL so use with caution.

   Example:

   AllowArrow := True

   ReadKey

Variable ALLOWMCI (boolean)

   This function toggles on/off MCI code parsing.  This is used outside of

   MPL so adjust this with caution.

Procedure APPENDTEXT (FileName, Text: String).  

   This procedure will append a single line of text onto a text file.  If

   the file does not exist, it will be created.  Example:

Function BITCHECK (B : Byte; I : Integer) : Boolean

   This function accepts a bit position and checks it against an integer,

   returning true or false if the bit is on.  So for example in the

   Records, the third bit in UserFlags is UserDeleted:

   GetThisUser

   If BitCheck(3, UserFlags) Then WriteLn('User is marked deleted');

Procedure  BITSET (B : Byte; I : Integer)

   This procedure accepts a bit position and an integer and sets the

   bit ON/OFF based on a boolean:

   GetThisUser

   BitSet(3, UserFlags, True);  // user is marked as deleted

Procedure BITTOGGLE (B : Byte; I : Integer)

   This procedure accepts a bit position and an integer and toggles the

   bit.

   GetThisUser

   BitToggle(3, UserFlags);  // undeletes if they are deleted or deletes if

                             // they are not deleted.

Variables CFGCHATSTART CFGCHATEND.  

   These return the byte of the chat hour start and end variables from the

   System Configuration

Procedure CLRSCR

    This function will clear the screen.

    Example:

    CLRSCR

    Writeln ('The screen was just cleared.')

    The above function will clear the screen and write the text "The

    screen was just cleared." to the screen.

Function DATE2DOS (Str : String) : LongInt

    This function takes a MM/DD/YY format date and converts it to

    DOS packed datetime format.

    Var DStr : String = '01/01/14'

    Var PDt  : LongInt

    PDt := Date2Dos(DStr)

Function DATE2JULIAN (Str : String) : LongInt

    This function takes a MM/DD/YY format date and converts it to a

    Julian date format.

Function DATEG2J (Str : String) : LongInt

    This function takes a gregorian date format (MMDDYY) and converts

    it to a Julian format

Function DATEJ2G (LI : LongInt) : String

    This function takes a julian date format and converts it to a

    gregorian format (MMDDYY).

Function DATEJULIAN : LongInt

    This function returns the Julian value of the current date.

Function DATESTRJULIAN (JD : LongInt) : String

    This function returns the MM/DD/YY string value of the julian date.

Function DATEVALID (Str : String) : Boolean

    This function takes a MM/DD/YY date and returns true or false

    depending on if the date is valid (ie, month is 01-12, etc).

Function DAYOFTHEWEEK

    Returns a number between 0-6 depending on the day of the week:

    0 = Sun, 1 = Mon, 2 = Tue, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat

Function DAYSAGO (JD : LongInt) : Integer

    This function takes the Julian date value and returns the number

    of days between the current date and the passed date.

Function DAYOFWEEK : Integer

    This function will return a number between 0-6 depending on the

    day of the week:

    0 = Sun, 1 = Mon, 2 = Tue, 3 = Wed, 4 = Thu, 5 = Fri, 6 = Sat

Procedure DELAY (MS: Word)

    This procedure will delay for a specified number of milliseconds.

    Example:

    DELAY (1000)

    The above example will delay the program for one second.

Function DOSERROR : Byte

    This function returns the current DosError and is used with the

    FindFirst and FindNext functions.  The possible values which may

    be returned by DosError are as follows:

    Value  Meaning

    -----  ---------------------

      0    No error

      2    File not found

      3    Path not found

      5    Access denied

      6    Invalid handle

      8    Not enough memory

     10    Invalid environment

     11    Invalid format

     18    No more files

    -----  ---------------------

    Example:

    FindFirst ('*.*', AnyFile)

    While DosError = 0 Do Begin

         WriteLn ('File Name: ', DirName)

         FindNext

    End

    FindClose                

    The above example will list all files in the current directory.

    The DosError function is used to return when there are no more

    files to be listed.  For more information on this see the reference

    for the FindFirst and FindNext functions.

Procedure FINDCLOSE

    This function is used along with the FindFirst and FindNext

    functions.  It is called only after all "Find" procedures have

    completed.  See the "FindFirst" and "FindNext" command references

    for more information.

Procedure FINDFIRST (Mask : String, Attributes)

    This function is used to search a drive for files using a supplied

    file mask and attribute list.  The results of the search are held

    in the DIR variables as listed below.

    Mask : The mask variable must contain at least a file mask

           (ie "*.*") but can also contain a drive and directory name

           as well (ie "C:\MYSTIC\TEXT\*.*").

    Attributes : The file attributes are used to specify what type of

                 files to return in the DIR variables.  The following

                 is a list of supported file attributes:

                 Dec Description Returns

                 --- ----------- -----------------

                 001 ReadOnly    files marked as "read only".

                 002 Hidden      files marked as "hidden".

                 004 SysFile     files marked as "system files".

                 008 VolumeID    files marked as "volume ID".

                 016 Directory   files marked as "directory".

                 032 Archive     files marked as "archive".

                 066 AnyFile     any and all files.

                 These attributes can be combined when passed to

                 FindFirst.  For example: 1 + 2 will return

                 any files which have been marked as "readonly" OR

                 "hidden".  Example: 16 (DIRECTORY) will only return names

                 of directories.

    DIR Variables : The DIR variables are what contain the information

                    returned by the FindFirst command.  If your program

                    is going to use these variables, it must be declared

                    with the USES statement at the beginning of your

                    program source code.  The following DIR variables

                    are supported:

                    DirName : Holds the file name.

                    DirSize : Holds the file size.

                    DirAttr : Holds the file attributes

                    DirTime : Holds the file date and time in packed

                              date format.  The DateSTR and TimeSTR

                              functions will need to be used in order

                              to display these.

    Example:

    USES DIR

    WriteLn ('The following files are in the C:\ directory:')

    WriteLn ('')

    FindFirst ('C:\*.*', 66)

    While DosError = 0 Do

    Begin

         WriteLn ('File Name: ', DirName)

         WriteLn ('     Size: ', DirSize)

         WriteLn ('     Date: ', DateSTR(DirTime), 0)

         WriteLn ('     Time: ', TimeSTR(DirTime), 1)

         Write   ('Press a key to search for more.~PN')

         FindNext

    End

    FindClose

    WriteLn ('No more files have been found.')

    The above example will list all files which fit the file mask of

    "C:\*.*" and fit the attributes of either ReadOnly or Archive.

    The DOSERROR function is used to determine when there are no more

    files found (See the DOSERROR reference).  If a file has been

    found, it will then be printed to the screen using the DIR

    variables.  The FindNext functon is used to find the next file

    that matches the name and attributes specified in the earlier call

    to FindFirst.  FindClose is used when all "Find" functions have been

    completed.

Procedure FINDNEXT

    This procedure is used to find the next file which matches the file

    mask and attibutes specified in the last call to FindFirst.

    Example:

    Uses DIR

    FindFirst ('*.*', 32)

    While DosError = 0 Do

    Begin

         WriteLn ('File Name: ', DirName)

         FindNext

    End

    FindClose

    The above example uses the FindFirst/FindNext functions to do a

    listing of all files in the current directory.  The DosError

    function is used to determine when no more files have been found.

Procedure GOTOXY (X: Byte, Y: Byte)

    This procedure will move the cursor to a specified X and Y

    position on the screen.  This only works for users who have ANSI

    graphics.

    Example:

    CLRSCR

    GotoXY (1, 10)

    WriteLn ('Hello')

    The above example will clear the screen then goto the first column

    of the tenth line and output the text "Hello" to the screen.

Procedure HALT

    This procedure will exit the program and return the user back to

    the BBS immediately.

    Example:

    If Graphics = 0 Do

    Begin

         WriteLn ('Sorry, you do not have ANSI graphics.')

         Halt

    End

    The above example will check to see if the user has ANSI graphics

    and if not, display "Sorry, you do not have ANSI" and exit the

    program immediately by using the HALT command.

Function INITIALS (String) : String

    This function takes a user name and attempts to return one or two

    character initials.

    S := Initials('Jack Phlash'); // should return "JP"

Function INPUT (Field: Byte, Max: Byte, Mode: Byte, Default: String) : String

    This function gives input to the user, and returns the result of

    the input as a string variable.

    The Field parameter is the size of the input field (in characters)

    that the user will be able to see.  If the field size is smaller

    than the maximum number of characters allowed in the input, the

    input line will scroll when the user reaches the end.  This field

    is usually set to the same as the Max parameter.

    The Max parameter is the maximum number of characters that

    Input will allow to be entered.  Note that the Field parameter, in

    most cases, should be set to the same value as this.

    The Mode parameter is the type of input that will be accepted, and

    can be any one of the following input types:

         1 : Standard input.  All characters allowed.

         2 : Upper case input.  Allows all characters, but will convert

             any lower case letters into upper case.

         3 : Proper input.  Allows all characters, but will convert

             the first letter in each word to an upper case letter.

         4 : Phone input.  Allows only numbers and will pre-format them

             using the USA-style phone numbers.  IE: XXX-XXX-XXXX.

             Note that the length of this input should always be 12,

             as that is the length of the USA phone number format.

         5 : Date input.  Allows only numbers and will pre-format them

             using the date format (ie XX/XX/XX) that is currently

             selected by the user.  NOTE: The date input will always

             return the date in the MM/DD/YY format, regardless of what

             format the user has selected.  For example, if the user

             has selected the DD/MM/YY format, Input will expect the

             user to enter the date in that format, but will then

             convert it to MM/DD/YY when it returns the date back to

             the MPE program.

         6 : Password input.  Allows all characters, but will convert

             any lower case letters into upper case.  The character

             that is typed is NOT echoed to the screen.  Instead, it

             is replaced by the * character so that what they have

             entered will not be shown on the screen.

          7: Lowercase Allows characters but will be lowercase.

    8: User Defined Input (from system config)

          9: Standard Input with no CR

         10: Number Input numbers only and +-

    NOTE: If any of the above input values are increased by 10, Input

    will create an input field using the foreground/background color

    that has been defined for that language.  For example, input type

    11 will function the same as input type 1, but will fill an input

    field to the maximum field length.

    The Default parameter can be used to force a default text into

    the input field.  If you do not wish to have any default text in

    the buffer, supply a blank string parameter (ie '').

    EXAMPLE:

    Var Str : String

    Write ('Enter something: ')

    Str := Input (30, 30, 1, '')

    The above example will print the text "Enter something: " to the

    screen and the allow input of up to 30 characters in length, using

    input type 1 (allows all characters).  No default text has been

    supplied so the input field will be empty by default.

    Var Str : String

    Write ('Enter something: ')

    Str := Input (30, 30, 11, 'Default')

    The above example will function just like the first example, except

    it will create an input field background and stuff the text of

    "Default" into the input field.

Function INPUTNY (Text: String) : Boolean

    This function prompts the user with a Yes/No question, defaulting

    to No. TRUE will be returned if the user answered Yes, or FALSE if

    the user answered No.  The passed Text variable is the text that is

    displayed to the user asking the question.

    Example:

    If Not InputNY('Do you want to run this program? ') Then

         Halt

    The above example will prompt the user with the Yes/No question

    passed as <Text>.  This question will default to No.  If the user

    answers No, the program will halt from being executed.

Function INPUTYN (Text: String) : Boolean

    This function prompts the user with a Yes/No question, defaulting

    to Yes.  TRUE will be returned if the user answered Yes, or FALSE

    if the user answered No.  The passed Text variable is the text

    that is displayed to the user asking the question.

    Example:

    If Not InputYN('Do you want to run this program? ') Then

         Halt

    The above example will prompt the user with a Yes/No question,

    asking "Do you want to run this program?".  If the user responds

    No, the program will not run, using the Halt command.

Function ISARROW : Boolean

    This function is used along with the READKEY function.  After

    READKEY is called, this function can be checked to process various

    extended keys, such as arrow keys.  When ISARROW is true, READKEY

    will return the following:

    ASCII #     Char     Key Pressed

    -------     ----     -----------

    71          G        Home

    72          H        Up Arrow

    73          I        Page Up

    75          K        Left Arrow

    77          M        Right Arrow

    79          O        End

    80          P        Down Arrow

    81          Q        Page Down

    83          S        Delete

    The character returned by READKEY can be checked by either the

    ASCII # or the actual character.  Below is an example:

    Example:

    Var Ch : Char

    Ch := ReadKey                 # Input one key

    If IsArrow Then               # Is key returned an arrow key?

      If Ch = 'H' Then

        WriteLn ('Up arrow')

      Else If Ch = Chr(80) Then

        WriteLn ('Down arrow')

    Else                          # No arrow key.  A normal character

      WriteLn ('You entered character: ', Ch)

    The above example reads a key with READKEY and then uses the

    ISARROW function to process the Up Arrow and Down Arrow keys.

Function ISUSER (String) : Boolean

    This function takes a string value which can contain either a user

    realname, handle, or user perm index number.  If the user exists,

    it will return a TRUE result or FALSE if the user does not exist.

Function KEYPRESSED : Boolean

    This function returns TRUE if a key has been pressed either

    remotely or locally.  Keep in mind two things about this

    function:

         (1) It doesn't check for inactivity timeout.  If you are

             using this function to wait for a key to be pressed then

             you may want to use the TIMER function and check for

             inactivity.

         (2) This function only returns whether a key was PRESSED.

             It does not actually read the key out of the buffer.

             See the READKEY function for reading keys from the

             buffer.

    Example:

    Repeat

    Until KeyPressed

    WriteLn ('You pressed a key!')

    The above example will wait for a key to be pressed and then

    write to the screen "You pressed a key!".

  Function MCI2STR (String) : String

    This function will take the value of the supplied 2-character MCI

    code (without pipe) and returns the string value of that code.

    Ex:

    Var BBSName : String

    

    BBSName:=MCI2Str('BN')

    WriteLn('The name of this BBS is "'+BBSName+'"')

  Function MCILENGTH (String) : Integer

    This function works just like LENGTH except it tries to ignore MCI

    codes.  It doesn't check for actual validity of MCI codes.

    Var B : Byte;

    B := MCILength('|15Hello|UH');

    WriteLn ('Length should be 5: ' + Int2Str(B));

  Function MOREPROMPT : Char

    This function displays the system more prompt and returns a Char

    value of either Y N or C depending on what the user selected.

    Var C : Char

    C:=MorePrompt

Procedure MOVEX (Pos : Byte)

        This procedure is used to move the cursor to the passed X coordinate

        on the screen.  It only works if the user has ANSI graphics enabled.

        Example:

        MoveX (20)

        WriteLn ('This text starts on the 20th space')

Procedure MOVEY (Pos : Byte)

        This procedure is used to move the cursor to the passed Y coordinate

        on the screen.  It only works if the user has ANSI graphics enabled.

        Example:

        MoveY (10)

        WriteLn ('This is on the 10th line of the screen')

Function PARAMCOUNT : Byte

    This function is used to determine the number of command line

    options which have been passed to the MPE program.  For more

    information, see the PARAMSTR function.

    Example:

    If ParamCount < 2 Then Begin

         WriteLn ('Invalid command line.')

         Halt

    End

    The above example will check to see if less than 2 command line

    options have been passed to the MPE program.  If there are less

    than two, the program will terminal with a "invalid command line"

    message.

Function PARAMSTR (Number : Byte) : String

    This function returns the command line option specified by the

    NUMBER parameter.  A command line is the optional data which

    is passed on the "Data" field of a menu command.  For example,

    when defining a menu command which executes an MPE program in

    the menu editor, the text after the program name becomes command

    line options.

    Menu Command: GX

    Data        : BULLETIN p1 p2 p3 p4

    If the above was defined in the menu editor, the following would

    be true:

    ParamCount  would return 4

    ParanStr(0) would return "BULLETIN"

    ParamStr(1) would return "p1"

    ParamStr(2) would return "p2"

    ParamStr(3) would return "p3"

    ParamStr(4) would return "p4"

    Note that ParamStr(0) will ALWAYS return the file name of the

    MPE program being executed.  Even when there are no other

    parameters defined.

Procedure PAUSE

    Envokes the Mystic pause prompt as defined in the current

    language file.

Function PAUSEPOS : Byte

 

    This function gives access to Mystic's internal line

    counter used for screen pauses.

Function RANDOM (Max: Word) : Word

    This function will return a random number within the range

    specified.

    Example:

    Var A : Byte

    A := Random(255)

    WriteLn (A)

    The above example will generate a random number within the range

    of 0 to 255 in the variable A and then print it to the screen.

Function READKEY : Char

    This function will read a key from the buffer and return it as

    a char variable.  If there are no keys in the buffer, readkey will

    wait for a key to be pressed.

    Example:

    Var Ch : Char

    Repeat Until KeyPressed

    Ch := ReadKey

    WriteLn ('You entered: ', Ch)

    The above example will wait for a key to be pressed by using the

    KEYPRESSED function.  Afterwards, the key will be read into the

    CH variable using readkey, and then print it to the screen.

Procedure SETPROMPTINFO (N : Integer; S : String)

   This allows you to set Mystic's internal "changing" PromptInfo MCI

   codes (the |&X codes).  For example:

   SetPromptInfo(1, 'Hello!');

   WriteLn ('This MCI code would like to say: |&1');

   As a side note, there is NOT a GetPromptInfo because you can simply use

   MCI2STR:

   WriteLn('This MCI code would like to say: ' + Mci2Str('&1'));

Procedure STUFFKEY (S : String)

    This function will stuff a string of text into the keyboard

    buffer.  This can be used to force your program into thinking

    the user had actually typed <S>.

    Example:

    Var Ch : Char

    StuffKey ('A')

    Ch := ReadKey

    WriteLn ('You entered: ', Ch)

    The above example will stuff the character "A" into the input

    buffer, where it will be read into Ch using the ReadKey function.

    It is possible to stuff entire strings of text into the buffer

    too.

    Example:

    Var Str : String

    StuffKey 'Hello World'

    Str := Input (20, 20, 1, '')

    The above example will stuff "Hello World" into the input buffer.

    This will cause the input function to think the user has actually

    typed in "Hello World".  In this case, the above is the same as

    supplying "Hello World" in the <DEFAULT> field of the Input

    function.

Function TIMER : LongInt

    This function will return the current number of seconds which have

    passed since midnight.  This function can be used to time how long

    a user is doing something.

    Example:

    Var StartTime : LongInt

    Var EndTime   : LongInt

    Var Total     : LongInt

    Var Str       : String

    StartTime := Timer

    Write ('Enter something: ')

    Str := Input (40, 11, 'Nothing')

    EndTime := Timer

    Total := EndTime - StartTime

    WriteLn ('You took ', Total, ' seconds to type something!')

    The above example will prompt the user to type something and time

    how long in seconds they took.  WriteLn will then display the

    number of seconds the user took to the screen.

Function TIMERMIN : LongInt

    This function works just like TIMER except returns minues

    instead of seconds.

Function WHEREX : Byte

    This function returns the current X coordinate of the cursor.

    Example:

    Var X : Byte

    Var Y : Byte

    X := WhereX

    Y := WhereY

    WriteLn ('      World')

    GotoXY  (X, Y)

    WriteLn ('Hello')

    The above example will save the current X and Y cursor positions

    and then write the text "World" to the screen.  After which, it

    will return to the saved X and Y position and write the text

    "Hello" to the screen.  The end result will be the text of

    "Hello World" written to the screen.  Note: GotoXY can only be

    used if the user has ANSI graphics mode.

Function WHEREY : Byte

    This function returns the current Y coordinate of the cursor.

    For more information on this function, please see the definition

    of the WHEREX function.

Procedure WRITE (Text)

    This procedure is used to write text to the screen without

    going to the next line (ie, without sending a carriage return).

    All text to be printed to the screen should be enclosed inside of

    ' characters.  If you wish to print the value of a variable to

    the screen, just include the variable name without the '

    characters.  If you wish to combine multiple text and variables,

    they must be separated by commas.

    Examples:

    Write ('Hello ')

    Write ('World')

    This example will write the text "Hello World" to the screen.

    Write ('Hello World')

    This example does the exact same thing as the function above, but

    makes a little more sense.

    Var Str : String

    Str := 'Hello World'

    Write (Str)

    This example will write the value held in the variable Str to the

    screen.  The resulting output will be "Hello World"

    Var Str : String

    Str := 'Hello '

    Write (Str, 'World')

    This example will write the value of the variable Str to the

    screen, followed by the text "World".  The resulting output will

    be "Hello World".  An unlimited number of variables and text can

    be outputted with the Write statement, but they must all be

    separated by a comma, as shown above.

    If a ' character needs to be printed to the screen, it can be done

    by doubling the ' character.  For example:

    Write ('This is how it''s done.')

    The resulting screen output will be "This is how it's done", with

    only one ' character.

    All MCI display codes can be used within the Write statement.  If

    you wish to change the display colors, use the MCI color system to

    do so.  For example:

    Write ('~14Hello World')

    This example will write the text Hello World in yellow to the

    screen.  All MCI display codes are available to the write

    statement.

Procedure WRITELN (Text)

    This procedure outputs text to the screen.  It functioning is

    identical to the WRITE statement except that it goes to the next

    line after the text is printed (ie, it sends a carriage return).

    For example:

    WriteLn ('Hello')

    WriteLn ('World')

    The above example will write the text "Hello" on one line, and

    then the text of "World" on the next line.

Procedure WRITEPIPE (Text)

    This function works just like WRITE but only parses pipe color

    codes instead of all MCI codes.

Procedure WRITEPIPELN (Text)

    This procedure works just like WRITEPIPE but with a CRLF at the end.

Procedure WRITERAW (Text)

    This procedure works just like WRITE except it does not parse

    any pipe color codes OR MCI codes.

Procedure WRITERAWLN (Text)

    This procedure is the same as WRITERAW, but with a CRLF at the end.

Procedure WRITEXY (X,Y,Z: Byte; Str : String)

    This procedure writes a string of text at the defined X/Y location with a

    specific text color attribute 'Z'.  This of course requires the user has

    ANSI to function properly.  This function will NOT parse MCI pipe codes.

    Example:

    WriteXY (1, 10, 8, 'Prints at X:1 Y:10 with dark grey text');

Procedure WRITEXYPIPE (X,Y,Z: Byte; Len: Integer; Str : String)

    This procedure writes a string of text at the defined X/Y location with a

    specific text color attribute 'Z'.  This of course requires the user has

    ANSI to function properly.  This function will NOT parse MCI pipe codes.

    Example:

    WriteXYPipe (1, 10, 8, 50, 'This pads to 50 chars at location 1,10');

-----------------------------------------------------------------------

String Handling Functions and Procedures

-----------------------------------------------------------------------

Function ADDSLASH(S: String) : String

   takes a directory and appends the appropriate ending backslash or

   forward slash depending on operating system.  If the slash is already

   there, it does nothing.

Function CHR (B: Byte) : Char

    This function will take a numerical byte value and return it's

    ASCII character.  The byte value must be between 0 and 255 as

    there are only 255 characters in the ASCII character set.

    Example:

    WriteLn ('Hello', Chr(32), 'World')

    This will output the text "Hello World" to the screen.  The ASCII

    number for the space character is 32 and by passing a 32 to CHR,

    a space is returned.

Function COPY (S: String, Index: Byte, Count: Byte) : String;

    This function will copy a defined part of a string and return

    the copied portion as a string.

    Example:

    Var Str : String

    Str := 'Hello World'

    WriteLn (Copy(Str, 1, 5))

    This will output "Hello" to the screen.  The copy function takes

    the given Str and copies Count number of character from the Index.

    So the above copies 5 characters starting at the 1st character in

    Str and WriteLn outputs it to the screen.

Procedure DELETE (S: String, Index: Byte, Count: Byte)

    This procedure will delete a defined portion of a string

    variable.

    Example:

    Var Str : String

    Str := 'Hello World'

    Delete (Str, 6, 6);

    WriteLn (Str)

    This example will delete 6 characters from the string Str starting

    at the 6th character.  The resulting output from WriteLn will be

    "Hello"

Function FillChar (V: Variable; S: LongInt; C Char ): String

    Fills variable V with Char C for S size.

    type

      myuserrecord = record

      username  : string[30];

      somevalue : array[1..5] of byte;

    end;

    var

      u : myuserrecord;

    begin

      fillchar(u, sizeof(u), #0);

    end.

Procedure INSERT (Source: String, Target: String, Index: Byte)

    This procedure will insert text into a string at a specified

    location.

    Example:

    Var Str : String

    Str := 'Mystic v1.00'

    Insert ('BBS ', Str, 8)

    WriteLn (Str)

    The above example will insert the text "BBS" into the Str variable

    starting at the 8th character in the string.  The result WriteLn

    output would be "Mystic BBS v1.00"

Function INT2STR (L: LongInt) : String

    This function converts a numerical type variable to a string

    type variable.

    Example:

    Var A : Byte

    Var S : String

    A := 255

    S := Int2Str(A)

    WriteLn (S)

    The above example sets the numerical variable to the value of

    255, which is then converted to a string variable using Int2Str.

    The resulting value of S will be '255' as WriteLn will output to

    the screen.

Function LENGTH (S: String) : Byte

    This function returns the length in characters of the passed

    string variable.

    Example:

    WriteLn (Length('Hello World'))

    The above example would output "11" to the screen, which is the

    number of characters in the text passed to Length.

Function LOWER (S: String) : String

    This function converts a passed string variable to all lower

    case letters.

    Example:

    WriteLn (Lower('HELLO'))

    The above statement would output the text "hello" to the screen.

    The original text of HELLO is converted to all lower case letters

    and than displayed by WriteLn.

Function ONEKEY (Keys : String; Echo : Boolean) : Char

    This function accepts a string of uppercase letters, and wait for

    input from the user.  If the keystroke is among the characters in

    Keys, it will return that character.  If the keystroke is not among

    the Keys string, it will do nothing.  If Echo is set to TRUE, it

    will also echo the Key to the screen.

    Var Ch   : Char

    Var Keys : String = 'ABCDQ'

    Ch := OneKey(Keys,True)

    WriteLn('You selected '+Ch+'.')

Function ONEKEYRANGE (String, Int, Int ) : Char

    This function works similar to OneKey, except that it will also allow

    for a number input within a certain range.  The number value is

    stored in a variable called RangeValue and the function returns a #0

    if a number was entered.  For example:

    Var

      Ch : Char;

    Begin

      Write ('Enter letters A-G or a number between 1-50: ');

      Ch := OneKeyRange('ABCDEFG', 1, 50);

      If Ch = #0 Then

        WriteLn ('You entered a number: ' + Int2Str(RangeValue))

      Else

        WriteLn ('You entered character: ' + Ch);

    End.

Function ORD (C: Char) : Byte

    This function returns the ASCII code of the passed Char variable.

    This function works the exact opposite of the CHR function.

    Example:

    WriteLn (Ord(' '))

    The above example would output the text "32" to the screen because

    32 is the ASCII character code for space.

Function PADCT (S: String, N: Byte, C: Char) : String

    This function pads a string to the center with the specified

    character.

    Example:

    Var Str : String

    Str := PadCT('Hello World', 80, ' ')

    WriteLn (Str)

    The above example would display the text "Hello World" centered on

    the screen.  The PadCT function returns the text "Hello World"

    centered in 80 spaces with the character of " " used to fill the

    blank spaces.

Function PADLT (S: String, N: Byte, C: Char) : String

    This function returns a text string padded with spaces to the

    left side.

    Example:

    Var Str : String

    Str := PadLT('Hello World', 79, ' ')

    The above example would return a string which is 79 characters in

    length with the text "Hello World" as the leftmost part of the

    string.  The passed character is the character that is used to

    fill the blank spaces.

Function PADRT (S: String, N: Byte, C: Char) : String

    This function returns a text string padded with spaces to the

    right side.

    Example:

    Var Str : String

    Str := PadRT('Hello World', 79, ' ')

    The above example would return a string which is 79 characters in

    length with the text "Hello World" being the rightmost part of the

    string.  The empty spaces are filled with the passed charcter (in

    this case ' ').

Function POS (Sub: String, S: String) : Byte

    This function returns the starting position of a substring in a

    string.

    Example:

    Var A : Byte

    A := POS('World', 'Hello World')

    WriteLn (A)

    The above example would output "7" to the screen becase POS

    returns the position of the text "World" in the string

    "Hello World".  If POS does not find a match, a zero will be

    returned.  IE: A := POS('Blah', 'Hello World') would return a zero

    because the text "Blah" was not found in the string "Hello World".

Function REPLACE(Str1, Str2, Str3 : String) : String

    This function replaces all occurances of a supplied text and

    returns a string.  Ex:

    Var Str : String = 'Hello Hello Hello';

    Str := Replace(Str, 'Hello', 'World');  // Str is now World World World

Function STRCOMMA(LI : LongInt) : String

    This function  accepts a longint and returns it as a string, with

    commas added where applicable:

    Ex:

    WriteLn (strComma(1000000));  // will print 1,000,000

Function STR2INT (S: String) : LongInt

    This function converts a passed string variable to a numerical

    variable.  The passed string variable must contain a valid number.

    Example:

    Var A : Byte

    Var S : String

    S := '100'

    A := Str2Int(S)

    WriteLn (S)

    WriteLn (A)

    The above example will output "100" twice the screen.  The

    variable S is assigned to '100' and the function Str2Int converts

    the string into a numerical value which is assigned to variable

    A.

Function STRIPB (S1, S2 : String) : String

    This function strips both sides of the string if a specific character.

    Var S : String = '     Hello     ';

    S := StripB(S, ' ');

Function STRIPL (S1, S2 : String) : String

    This function strips the left side of a string of any specified

    leading characters.

    Var S : String = '    Hello';

    S := StripL(S, ' ');

Function STRIPR (S1, S2 : String) : String

    This function strips the right side of a string of any specifcied

    trailing character:

    Var S : String = 'Hello     ';

    S := StripR(S, ' ');

Function STRIPLOW (String) : String

    This function strips all chracters from a string that are less than

    ascii code #32.

    Var S : String = #12#12#12#12 + 'Hello';

    S := StripLow(S);

Function STRIPMCI (S : String) : String

    This function will strip the passed string variable of all MCI

    codes and return the "cleaned" version.

    Example

    Var S : String

    S := '|10|H|02ello |10W|02orld|07'

    WriteLn ('Normal   : ', S)

    WriteLn ('Stripped : ', StripMCI(S))

    The above example assigns a string with MCI codes in it to the S

    variable.  It then writes the original string and the stripped

    string to the screen, so the difference is shown.

Function STRIPPIPE (String) : String

    This function takes a string and strips only pipe color codes

    from it.

    S := StripPipe('|15Hello there, |UH');  //returns "Hello There, |UH"

Function STRMCI (String) : String

    This function takes an entire string and attempts to translate any

    MCI codes found in it, returning the entire result.

    S := StrMci('Hello |UH');

Function STRREP (Ch: Char, Num: Byte) : String

    This function returns a string filled with character <CH> to the

    length of <NUM>.

    Example:

    WriteLn (strRep('-', 60 ))

    The above example will use strRep to create a string 60 characters

    long of the character '-', then write it to the screen.  So the

    outputted text would look like:

    "------------------------------------------------------------"

Function STRWRAP(Str, Str2 : String; Len: Integer) : Byte

    This function takes two strings and wraps them after the word closest

    to the maximum supplied length.  It optionally returns the actual

    position where it wrapped.

    Var Str   : String = 'This will wrap';

    Var Str2  : String = '';

    Var Where : Byte;

    Where := strWrap(Str, Str2, 10);

    WriteLn ('It wrapped at ' + Int2Str(Where));

    WriteLn ('First string: ' + Str);

    WriteLn ('Second string: ' + Str2);

Function UPPER (S: String) : String

    This function coverts the passed string variable to all upper

    case letters.

    Example:

    WriteLn (Upper('hello'))

    The above example would output the text "HELLO" to the screen.

    The UPPER function converts the passed text of "hello" to all

    upper cased letters, which is then printed to the screen by

    WriteLn.

Function WORDCOUNT (S,C: String) : Integer

    Function WordCount returns the number of words in a string using

    the final parameter to define the character that determines what

    separates words.  Ex:

    Str := 'Hello this is a test';

    WriteLn ('Str has ' + Int2Str(WordCount(Str, ' ')) + ' words in it.');

Function WORDGET(I : Integer, S, C : String) : String

    returns the actual word at a specific word count.

    S is the inputted string value.

    I is the numerical value of the position where the word can be found.

    C is the string value used as the word separater.

    Ex:

    Str := 'Hello this is a test';

    WriteLn('The second word was: ' + WordGet(2, Str, ' '));

Function WordPos (I : Integer; S, C : String ) : Integer

    Function WordPos returns the character position in the string where

    specific word is located.

    S = Inputted string value

    I = Index value of the the desired word within S

    C = String value of the word separater.

    Ex:

    Str := 'Hello this is a test';

    WriteLn ('Second word is at: ' + Int2Str(WordPos(2, Str, ' ')));

    See Also : WordCount, WordGet

-----------------------------------------------------------------------

File Accessing Functions and Procedures

-----------------------------------------------------------------------

Function FEOF (Handle) : Boolean

    This function will return true if the file position of an opened

    file is at the End Of the File (EOF).  The passed Handle value is

    the file number of the already opened file.

    Example:

    Var Str : String

    Var Fpt : File

    FOpen (1, Text, Reset, 'BLAH.TXT')

    While Not Eof(1)

         FReadLn (1, Str)

         WriteLn (Str)

    End

    FClose (1)

    The above example will open a text file under the filename of

    BLAH.TXT.  The WHILE loop is used to repeat the code until the

    EOF (end of file) is reached.  The FCLOSE statement will close

    the file after it is done being accessed.

    The result of the above example will be (in pseudocode):

    1. Open text file.

    2. If not at the end of file, run this code:

        3. Read line from text file into string variable

        4. Print line read from text file to the screen.

        5. Goto 2.

    6. Close the text file.

    So the above example will basically write the entire text file to

    the screen.

Procedure FCLOSE (File)

    This procedure closes an already opened file.  The passed Handle

    value is the file number of the opened file.  All files which

    are opened MUST be closed after they are not being accessed any

    more.

    For example:

    Var Fptr : File

    fAssign  (Fptr, 'BLAH.TXT', 66)

    fReWrite (Fptr)

    <Code to access file goes here>

    fClose (Fptr)

    The above example opens a file using the FOPEN procedure.  When

    the file has been opened successfully, it can be accessed in

    various ways using the file I/O functions.  Afterwards, it MUST

    be closed using the FCLOSE procedure as shown above.

Function FILECOPY (Source: String, Dest: String) : Boolean

    This function will copy a file from the specified source location

    to the specified destination location.  The function will return

    as TRUE if the file was copied successfully, or FALSE if an error

    occured.  Note:  The file which is being copied should not already

    be opened for File I/O by the program.

    Example:

    Write ('Copying C:\HELLO.TXT -> D:\HELLO.TXT: ')

    If fileCopy ('C:\HELLO.TXT', 'D:\HELLO.TXT')

         WriteLn ('OK')

    Else

         WriteLn ('ERROR')

    End

    The above example will attempt to copy the file "C:\HELLO.TXT" to

    the destination of "D:\HELLO.TXT".  If the file is copied without

    any problems an "OK" will be printed to the screen.  If an error

    occured while copying, "ERROR" will be printed to the screen.

Procedure FILEERASE (FileName: String)

    This procedure is used to erase an existing file from the disk.

    The FileName variable is a string variable which contains the

    file name which is to be erased.  The result of the FILEERASE

    procedure can be checked by checking the DOSERROR function.

    DOSERROR will return a 0 if successful or a 2 if an error occured.

    Example:

    FileErase ('C:\HELLO.TXT')

    The above example will erase the file "C:\HELLO.TXT" if it exists.

Function FILEEXIST (FileName: String) : Boolean

    The above function will check to see if a file exists, and return

    TRUE if it does.  The passed FileName string if the path and file

    name of the file to check.  This file should not already be opened

    with the FOPEN procedure.

    Example:

    If FileExist('BLAH.TXT') Then

         WriteLn ('BLAH.TXT exists.')

    Else

         WriteLn ('BLAH.TXT does NOT exist.')

    The above example will check to see if the file "BLAH.TXT" exists

    and if it does, will output "BLAH.TXT exists" to the screen.  If

    BLAH.TXT does NOT exist, the output will be "BLAH.TXT does NOT

    exist".

Function FPOS (File) : LongInt

    This function returns the current file position of an opened

    file.  The passed Handle is the file handle number used when the

    file was opened.  The FilePos function only works for files that

    are opened as Binary, since Text files are read line by line.

    Example:

    Var Fptr : File

    fAssign (Fptr, 'TEST.DAT', 66)

    fReset(Fptr)

    If IORESULT = 0 Then Begin

       If fPos(Fptr) = FSize(Fptr)

          WriteLn ('END OF FILE.')

       End

       fClose (fPtr)

    End

    The above example opens the file "TEST.DAT" for binary and then

    writes to the screen if the file position is at the end of the

    file.  The above statement "fPos(Fptr) = fSize(Fptr)" is the same

    as "fEof(Fptr)" since it's stating "if the file position is equal to

    the total file size, then we're at the end of the file."

Function FSIZE (File) : LongInt

    This function returns the total file size of an opened file.  The

    passed Handle is the file handle number used when the file was

    opened.  This function only works with files that have been opened

    as Binary since Text files are read line by line.

    Example:

    Var Fptr : File

    fAssign (Fptr, 'TEST.DAT', 66)

    fReset(Fptr)

    If IoResult = 0 Then

        WriteLn ('This file is ', fSize(Fptr), ' bytes in size.')

    fClose (Fptr)

    The above example opens the file "TEST.DAT", writes the size of

    the file to the screen, and then closes the file.

Procedure FASSIGN (Fptr : File, Mask : String, Attr : Int)

    This procedure opens a text or binary file for file operations.

    Fptr  : The passed file pointer is the file reference, of type FILE

    Mask  : The path and filename of the file to open, in string format.

    Attr  : File attributes to open.  See FINDFIRST for more info.

    EXAMPLE:

    Var Fptr : File  

    fAssign (Fptr, 'BLAH.TXT', 66)

    fReWrite (Fptr)

    fWriteLn (Fptr, 'Hello World!')

    fClose (Fptr)

    The above example creates a text file under the name 'BLAH.TXT'.

    If BLAH.TXT already exists, it will be erased and replaced by a

    new BLAH.TXT file.  The FWriteLn writes the text "Hello World" to

    the file, and then FClose closes the file.

Procedure FRESET (File)

    This procedure moves the file pointer to the beginning of an already

    opened file.  This is useful for moving the file pointer to specific

    spots in the file, without having to close and reopen the file.  The

    file must have previously been opened by FASSIGN.

    Use IORESULT to determine if the freset command was successful.

    Var fPtr : File

    fAssign(Fptr,CfgDataPath+'somefile.dat',66)

    fReset(Fptr)

    If IORESULT = 0 Then Begin

       WriteLn('somefile.dat is opened for use!')

       WriteLn('closing somefile.dat!')

       fClose(Fptr)

    End Else

       WriteLn('Unable to open somefile.dat')

     

Procedure FREWRITE(File)

    This procedure will this will erase an existing file and recreate it,

    leaving the file position at the beginning of the file.  If the

    file does not already exist, MPL will create the file.  The file must

    have previously been opened by FASSIGN.

Procedure FSEEK (Fptr: File, Position: LongInt)

    This procedure seeks to a file position in a binary file.  It

    will only work on binary files, not text file.

    Fptr : The passed file pointer value of type FILE

    Position : This is the position where FSEEK will seek to.

    EXAMPLE:

    Var Str : String

    Var Fptr: File

    Str := 'Hello World!'

    fAssign   (Fptr, 'BLAH.DAT',66)

    fSeek     (Fptr, FileSize(1))

    fWriteRec (Fptr, Str, 12)

    fClose    (Fptr)

    The above example opens an already existing file under the name

    'BLAH.DAT'.  Using FSEEK, it will seek to the end of the file,

    so that "Hello World" can be added as the last record.

Procedure FREAD (File, Str, Int)

    This procedure is used to read binary data from a file.

    Type FileInfo = record

       Index : Integer

       Name  : String [50]

       Data  : Integer

    End

    Var fptr : File

    Var info : FileInfo

    Var Recno: Integer = 3

    fAssign(Fptr,'FILE.DAT',66) // Open the file

    fReset(Fptr) // Reset to the beginning of the file

   If IoResult = 0 Then Begin  // If successful...

      fSeek(Fptr,(Recno-1)*SizeOf(Info)) // Go to 3rd record in the file

      If Not fEof(Fptr) Then // If the 3rd record is there...

         fRead(Fptr,Info,SizeOf(Info)) // Read the record

         // Optionally, use FreadRec(Fptr,Info) when reading record types.

    End

    fClose(Fptr) // close the file

Procedure FREADLN(File,Str)

    This procedure will read string data from a text file.

    Var fptr : File

    Var Str  : String

    fAssign(Fptr,'somefile.txt',66)

    fReset(Fptr)

    If IoResult = 0 Then Begin

       While Not fEof(Fptr) Do Begin

          FReadLn(Fptr,Str)

          WriteLn(Str)

       End

       fClose(Fptr)

    End

Procedure FWRITE (File, Str, Int)

    This procedure is used to write binary data to a file.

    Type FileInfo = record

       Index : Integer

       Name  : String [50]

       Data  : Integer

    End

    Var fptr : File

    Var info : FileInfo

    info.Index:=1

    info.Data:=33

    info.Name:='newname'

    fAssign(Fptr,'FILE.DAT',66)

    fReWrite(Fptr)

    fWrite(Fptr,Info,SizeOf(Info))

    fClose(Fptr)

Procedure FWRITELN(File,Str)

    This procedure is used to save string data to a text file.

    Var Fptr : File

    Var Str  : String = 'I am a string value!'

    fAssign(Fptr,'flatfile.txt',66)

    fReset(Fptr)

    If IoRESULT = 0 Then Begin

       // File already exists.

       // Seek to the end of the file.  aka append to the file

       fSeek(Fptr,FSize(Fptr))

    End Else Begin

       // File is not yet created.  Create it now.

       fReWrite(Fptr)

    End

    fWriteLn(Fptr,Str)

    fClose(Fptr)

Function SIZEOF (Type) : LongInt

    This function will take any named data type as input, and return

    the size of the data.

    Type TypeOfData = Record

      N : Integer

      L : Real

      V : LongInt

      Q : String [32]

    End

    Var I : Integer

    Var S : String [50]

    Var R : Real

    Var T : TypeofData

    WriteLn('Size Of I = '+Int2Str(SizeOf(I)))

    WriteLn('Size Of S = '+Int2Str(SizeOf(S)))

    WriteLn('Size Of R = '+Int2Str(SizeOf(R)))

    WriteLn('Size Of T = '+Int2Str(SizeOf(T)))

-----------------------------------------------------------------------

BBS Related Functions and Procedures

-----------------------------------------------------------------------

Function ACS (S: String) : Boolean

    This function processes an ACS string and returns true if the user

    has passed.

    Example:

    If ACS('s10g1') Then

         WriteLn ('You have access to this.')

    Else

         WriteLn ('Sorry, you do not have access.')

    The above example checks to see if the user passes the ACS string

    of "s10g1" and prints the result to the screen.

Function DATESTR (DT: LongInt, dType: Byte) : Integer

    This function will take a packed datetime number and convert it to

    a date string.  The dType parameter is used to set the format of the

    date which is returned.  Valid types are:

         UserDateType  = Returns date in the users date format

         1 = Returns date in format: MM/DD/YY

         2 = Returns date in format: DD/MM/YY

         3 = Returns date in format: YY/DD/MM

    Example:

    GetThisUser

    WriteLn ('Welcome.  You last called on ', DateStr(UserLast))

    The above example loads the currently logged in user's information

    into the USER variables using GETTHISUSER, then displays the last

    time the user has called to the screen using the DATESTR procedure.

Function DATETIME : LongInt

    This function returns the current Date and Time in the packed

    format.  DATESTR and TIMESTR can be used to convert this value

    into strings.

    Example:

    WriteLn ('Current Date: ', DateStr(DateTime), 0)

    WriteLn ('Current Time: ', TimeStr(DateTime), 1)

    The above example outputs the current date and time to the screen

    using the DATESTR and TIMESTR functions.  The DateTime function

    which is passed to DATESTR and TIMESTR, contains the current date

    and time in the packed format.

Function DIREXIST (S : String) : Boolean

    This function returns TRUE or FALSE if a directory exists.

    If DirExist('C:/MYSTIC/TEMP46') Then

       WriteLn('Dir C:/MYSTIC/TEMP46 exists!')

    Else

       WriteLn('Dir C:/MYSTIC/TEMP46 does not exist!')

Procedure DISPFILE (FN: String)

    This procedure displays a text or ANSI file to the screen.  If a

    path not included in the passed filename, Mystic will look for

    the file in the language text file directory.  If no file

    extension is provided in the passed file name, Mystic will display

    the correct file according to the user's graphics settings

    (ie .ANS for ANSI, .ASC for non-ansi).

    Example:

    DispFile ('WELCOME')

    The above example will display the text file "WELCOME" from the

    language text file directory.  Since there is no file extension

    provided, Mystic will display "WELCOME.ANS" or "WELCOME.ASC"

    depending on what the user's terminal settings are.

Procedure FILLCHAR (R : Record; S : Integer; V : Value )

    Fillchar fills the memory starting at X with Count bytes or

    characters with value equal to Value.

    type

    myuserrecord = record

      username  : string[30];

      somevalue : array[1..5] of byte;

    end;

    var

      u : myuserrecord;

    begin

      fillchar(u, sizeof(u), #0);

    end.

Procedure GETCFG

    This procedure will load the current configuration data into the

        CFG variables.  The "USES CFG" command must be used at the start

        of your program for GETCFG to work.  The following variables will

        be loaded:

    CFGSYSPATH     : System Path

    CFGDATAPATH    : Data Path

    CFGMSGSPATH    : Message Base Path

    CFGPROTPATH    : Protocol Path

    CFGQWKPATH     : Local QWK Path

    CFGMPEPATH     : Script (MPE) Path

    CFGATTPATH     : File Attach Path

    CFGLOGSPATH    : System Logs Path

    CFGTEXTPATH    : Text Files Path (for the current language)

    CFGTEMPPATH    : Temp path for the current node

    CFGMENUPATH    : Menu Files Path (for the current language)

    CFGTIMEOUT     :

    CFGSEEINVIS    : Gives the "See Invisible" ACS value

    CFGTNNODES     : Number of max telnet nodes to allow

    CFGNETDESC[1..30]     : Give the network descriptions.

    Example:

        Uses CFG

        GetCFG

    WriteLn ('Mystic BBS is installed in ', CfgSysPath)

    The above example will load the configuration into the CFG

    variables, and then print the directory where Mystic BBS is

    installed in to the screen.

Function GETATTRXY (X, Y : Byte) : Byte

    This function returns the attribute of the character at position

    XY on the user's screen:

    Var Attr : Byte;

    Attr := GetAttrXY(1, 1);

    WriteLn ('The attribure of the character at 1,1 is: ' + strI2S(Attr));

Function GETCHARXY (X, Y : Byte) : Char

    This function returns the character located on the user's

    screen at the XY location.

    Var Ch : Char;

    Ch := GetCharXY(1, 1);

    WriteLn('The user has the following character at 1,1: ' + Ch);

    This kind of stuff could allow you to create MPL-based custom screen

    effects like TheDraw used to have, except for on-the-fly with whatever

    is on the user's screen.

Function GETMBASE (N : Word) : Boolean

    This procedure will read message base data into the MBASE variables.

    The supplied N is the record number to read.  The function will

    return TRUE if the record was read successfully, or FALSE if the

        record was not read.  The "USES MBASE" command must be called at

        the start of your program for the MBASE functions to work

        correctly.

    The following MBASE variables will be set when a record is read:

    Variable Name   Type     Description

    -------------------------------------------------------------------

    MBASENAME      String    Name

   MBASEACS       String    ACS level

   MBASERACS      String    Read ACS level

   MBASEPACS      String    Post ACS level

   MBASESACS      String    SysOp ACS level

   MBASEINDEX     Integer   Index number (*NEVER* change this)

    Example:

    Var A Word

    A := 1

    While GetMBase Do

    Begin

         WriteLn ('Base name: ', MBaseName)

         A := A + 1

    End

    The above example will list all available message base systems on

    the BBS.

Function GETMBASESTATS (Base : LongInt; B1, B2 : Boolean; Tot, New, Yours : LongInt) : Boolean

     This can be used as a function or a procedure (returning true if

     successful).  It takes 6 parameters.

     #1: Message base number

     #2: Exclude messages FROM the current user in stats

     #3: Exclude messages TO the current user that have already been read

     #4: Total messages (this is a VAR parameter)

     #5: New messages (this is a VAR parameter)

     #6: New messages to you (this is a VAR parameter)

     Example:

     uses mbase;

     var

       count, total, new, yours : longint;

     begin

     count := 1;  //start @1 to skip email base

     while getmbase(count) do begin

       getmbstats(count, true, true, total, new, yours);

       writeln('base       : ' + mbasename);

       writeln('total msgs : ' + int2str(total));

       writeln('new msgs   : ' + int2str(new));

       writeln('your msgs  : ' + int2str(yours));

       writeln('');

       count := count + 1

     end;

Function GETMBASETOTAL (Compress : Boolean) : LongInt

    This function returns the total message bases on the system.  If

    Compressed is true, then it will return the total number of message

    bases the user has access to (slower to calculate).  If it is false,

    it returns the raw total number of bases on the system.

Function GETPROMPT (N : Word) : String

    This function will return a prompt from the current user's language

    file.  The passed N varliable is the prompt number to return.

    Example:

    WriteLn(GetPrompt(1))

    The above example writes prompt #1 from the user's currently

    selected language file to the screen.

Procedure GETSCREENINFO (I, X, Y, Attr : Integer)

    This allows you to read Mystic's internal ScreenInfo codes,

    used in Templates - so your MPLs can easily have templates

    just like Mystic!  These are the |!X codes.

Var

  X, Y, Attr : Byte;

Begin

  GetScreenInfo(1, X, Y, Attr);

  WriteLn('The value of the !1 MCI code was:');

  WriteLn('   X: ' + Int2Str(X));

  WriteLn('   Y: ' + Int2Str(Y));

  WriteLn('Attr: ' + Int2Str(Attr));

End;

Function GETUSER (N: Integer) : Boolean

    This procedure will read user data into the USER variables.  The

    supplied N is the record number to read.  The function returns

    true if the record was read, or false if a record was not read.

    The following USER variables will be set when a record is read:

    Variable Name   Type     Description

    -------------------------------------------------------------------

    USERDELETED     Boolean  Is the user marked as deleted?

    USERNAME        String   User's real name.

    USERALIAS       String   User's BBS alias.

    USERPASSWORD    String   User's password.

    USERADDRESS     String   User's street address.

    USERCITY        String   User's City/State.

    USERBIRTHDAY    String   User's birth date.

    USERSEX         Char     User's gender (M = Male, F = FeMale).

    USERSEC         Byte     User's security level (0-255).

    USERFIRSTON     LongInt  User's date/time of first call to the BBS.

                             This is stored in the packed date format

                             so in order to display the date & time,

                             the functions of DATESTR and TIMESTR need

                             to be used.

    USERLASTON      LongInt  User's date/time of the last call to the

                             BBS.  This is also stored in a packed date

                             format, so the same rules for USERFIRST

                             apply to this.

    -------------------------------------------------------------------

    Example:

    Var A Integer

    A := 1

    While GetUser(A) Do

    Begin

         WriteLn ('User Alias: ', UserAlias)

         A := A + 1

    End

    The above example will list all user accounts on the BBS system.

Procedure GETTHISUSER;

    This procedure loads the user information for the currently

    logged in user into the USER variables.  See the GETUSER function

    for a reference of the USER variables.

    Example:

    GetThisUser

    WriteLn ('Welcome to this BBS, ', UserAlias)

    WriteLn ('You have called ', UserCalls, ' times!')

    The above example will load the currently logged in user

    information into the user variables, then display a line of

    text welcoming them to the BBS.

Function GRAPHICS : Byte

    This function returns the user's current graphics mode in

    numerical format:

         0 = ASCII graphics mode

         1 = ANSI graphics mode

    Example:

    If Graphics = 1 Then

         WriteLn ('ANSI graphics')

    Else

         WriteLn ('ASCII graphics')

    The above example will print the user's current graphics mode

    to the screen.  If the user has ANSI (graphics mode 1), "ANSI

    graphics" will be printed.  If the user does not have ANSI

    (graphics mode 0), "ASCII graphics" will be printed to the screen.

Procedure HANGUP

    This procedure will stop the program immediately, hangup up on the

    user, and return Mystic BBS to the waiting for caller screen.

    Example:

    If InputYN ('Do you want to hangup now? ') Then

         HangUp

    The above example will prompt the user with a Yes/No question

    asking "Do you want to hangup now?" and if the user responds

    "Yes", they will be logged off the BBS using the HangUp command.

Function JustFile (S : String) : String

    This function takes a string arguement and returns only the

    filename:

    WriteLn ('This MPX filename is: ' + JustFile(ProgName));

Function JustFileName (S : String) : String

    This function  takes a string arguement and returns only the base

    filename (ie, not the extension so it basically just removes a file

    extension).  This does not remove a path, JustFile does that.

    WriteLn ('This MPX filename is: ' + JustFileName(ProgName));

Function JustPath (S : String) : String

    This function takes a string arguement and returns only the

    path (including the trailing backslash).

    Ex:

    WriteLn ('This MPX is located in ' + JustPath(ProgName));

Function LOCAL : Boolean

    This function returns TRUE if the user is logged into the BBS

    system locally.  It will return FALSE if the user is connected

    via a remote location.

    Example:

    If Local Then

      WriteLn ('Local caller detected.')

    Else

      WriteLn ('Remote caller detected.')

Function MSGEDITOR(0,Int,Int,Int,Bool,Str,Str) : Bool

Procedure MSGEDITSET(Int,Str)

Procedure MSGEDITGET(Int,Str)

     Added 3 new MPL functions: MsgEditor, MsgEditSet, MsgEditGet.  These

     allow access to the internal Mystic msg editor (line and/or full)

     from within MPL.  It even allows you to define wrap position and

     template to completely make it look like its not the Mystic editor!

     As a little hint the MsgEditSet and MsgEditGet stuff could be used to

     post process message text on posts.  Like say for example you wanted

     to write a MPL that allows users to add Tag lines, you could do that

     by replacing the "Saving message..." prompt and using those two in

     order to modify the text before it is saved by Mystic!

     Rather than trying to explain it all, here is an example of all 3:

Var

  Lines    : Integer = 0;

  WrapPos  : Integer = 79;

  MaxLines : Integer = 200;

  Forced   : Boolean = False;

  Template : String  = 'ansiedit';

  Subject  : String  = 'My subject';

  Count    : Integer;

Begin

  MsgEditSet (1, 'this is line 1');

  MsgEditSet (2, 'this is line 2!');

  Lines := 2;

  SetPromptInfo(1, 'MsgTo');  // if template uses &1 for "To:" display

  If MsgEditor(0, Lines, WrapPos, MaxLines, Forced, Template, Subject) Then Begin

    WriteLn('User selected to save.');

    WriteLn('There are ' + Int2Str(Lines) + ' of text in buffer:');

    For Count := 1 to Lines Do

      WriteLn(MsgEditGet(Count));

    Pause;

  End Else Begin

    WriteLn('User aborted the edit.');

    Pause;

  End

End

Procedure MENUCMD (CM: String, Data: String)

    This procedure will allow menu commands to be ran from within a

    program.  <CM> is the menu command, and <DATA> is the menu command

    data.

    Example:

    MenuCmd ('NW', '')

    The above example will run the menu command "NW" with the optional

    data field set to nothing.  This example will display the Who's

    Online list.  See MYSTIC.DOC for a list of all available menu

    commands.

Function NODENUM : Byte

    This function returns the current node number which the program

    is being ran on.

    Example:

    WriteLn ('Welcome to node number ', NodeNum)

    The above example will print the text "welcome to node number x"

    to the screen, where the x will be the current node number which

    the program is being ran on.

Variable PROGNAME : String

    Returns the path and filename of the current MPL program

Variable PROGPARAMS : String

    Returns any of th eparameters passed to the MPL program as a

    single string

Procedure PUTMBASE

    This procedure will save the currently loaded MBASE variables into

    a message base record.  See the GETMBASE function for a list of

    valid MBASE variables.

    Example:

    If GetMBase(1) Then Begin

         MBaseName := 'Message Base #1'

         PutMBase(1)

    End

    The above example will read the data for message base #1, set the

    name to "Message Base #1" and write the data back to the data file.

Procedure PUTTHISUSER

    This procedure will save the USER variables into the currently

    logged in user's record.  See the GETUSER function for a list of

    the USER variables which are saved by the PutThisUser function.

    Example:

    GetThisUser

    WriteLn ('Welcome ', UserAlias, '.  Your account is being deleted.')

    UserDeleted := True

    PutThisUser

    HangUp

    The above example will load the USER variables with the currently

    logged in user's information, then mark them as deleted with the

    UserDeleted variable.  Their account is then saved with the

    PutThisUser procedure and then they are hangup on using the HangUp

    command.

Procedure PUTUSER (N: Integer)

    This procedure will save the USER variables into the user file.

    The passed N parameter is the record number to save under.  See

    the GETUSER function for a list of the USER variables which are

    saved by the PutUser procedure.

    Example:

    If GetUser(1) Then

    Begin

         UserDeleted := True

         PutUser(1)

    End

    The above example will attempt to load the data from user record

    1 into the USER variables.  If the data is loaded without any

    errors, it will mark the user as deleted using the USERDELETED

    variable, and then save the record back to the user file.

Function READENV (S : String) : String

    This function returns the value of the given environment variable

    of the operating system.

Function REAL2STR(Real,Int):String

    This takes a string and decimal place value.

    Ex:

    Var

      R : Real;

    Begin

      R := 1234.1234;

      WriteLn (Real2Str(R, 2));  // Will print 1234.12

   End

Procedure SYSOPLOG (S: String)

    This procedure will add a line into the sysop log file found in

    the logs directory.

    Example:

    SysopLog ('User ran this program.')

    The above example will write the text "User ran this program" in

    the system log file, using the same format as Mystic uses in the

    log files (ie, the date and time will automatically be added).

Function TIMESTR (DT: LongInt, Mode: Byte)

    This function converts a packed datetime number into a time

    string.  The passed mode variable defines the format of the time

    string returned.  Valid options are:

         0 = 24 hour format: HH:MM:SS

         1 = 12 hour format: HH:MMa or HH:MMp

    Example:

    WriteLn ('The current time is: ', TimeStr(DateTime, 1))

    The above example outputs the current time to the screen using the

    TIMESTR and DATETIME functions.

Procedure UPUSER (Sec: Byte)

    This procedure will upgrade the currently logged in user's

    security level using the validation system.  The passed value

    is the security level to upgrade to and must be between the

    range of 0 to 255.

    Example:

    WriteLn ('Upgrading your access to level 20')

    UpUser (20)

    The above example will do a validation upgrade to the security

    level of 20.

-----------------------------------------

Other Supported Functions and procedures:

-----------------------------------------

Commands WITHOUT the ** DONE after them have not yet been documented above.

Hopefully all the commands are listed below, but it's possible that I could

have forgot a couple...  These docs will be up-to-date as time goes on! :)

ABS        ** DONE

ACS        ** DONE

ADDSLASH   ** DONE

ALLOWARROW ** DONE

CHR        ** DONE

CLRSCR     ** DONE

CONST

COPY       ** DONE

DATESTR    ** DONE

DATETIME   ** DONE

DELAY      ** DONE

DELETE     ** DONE

DISPFILE   ** DONE

DOSERROR   ** DONE

FEOF          ** DONE

FCLOSE        ** DONE

FCOPY         ** DONE

FILEERASE     ** DONE

FILEEXIST     ** DONE

FOPEN         ** DONE

FPOS          ** DONE

FSIZE         ** DONE

FINDCLOSE     ** DONE

FINDFIRST     ** DONE

FINDNEXT      ** DONE

FREAD

FREADLN

FREADREC

FSEEK         ** DONE

FUNCTION

FWRITE

FWRITELN

FWRITEREC

GETCFG        ** DONE

GETFBASE

GETMBASE      ** DONE

GETPROMPT     ** DONE

GETUSER       ** DONE

GETTHISUSER   ** DONE

GOTOXY        ** DONE

GRAPHICS      ** DONE

HALT          ** DONE

HANGUP        ** DONE

INPUT         ** DONE

INPUTNY       ** DONE

INPUTYN       ** DONE

INSERT        ** DONE

INT2STR       ** DONE

ISARROW       ** DONE

ISNOFILE      ** DONE

KEYPRESSED    ** DONE

LENGTH        ** DONE

LOCAL         ** DONE

LOWER         ** DONE

MENUCMD       ** DONE

MOVEX         ** DONE

MOVEY         ** DONE

NODENUM       ** DONE

ONEKEY

ONEKEYRANGE   ** DONE

ORD           ** DONE

PADCT         ** DONE

PADLT         ** DONE

PADRT         ** DONE

PARAMCOUNT    ** DONE

PARAMSTR      ** DONE

POS           ** DONE

PUTFBASE

PUTMBASE      ** DONE

PUTTHISUSER   ** DONE

PUTUSER       ** DONE

RANDOM        ** DONE

READKEY       ** DONE

SETPROMPT

SETUSERTIME

STATUSMODE

STATUSUPDATE

STR2INT       ** DONE

STRIPMCI      ** DONE

STRREP        ** DONE

STUFFKEY      ** DONE

SYSOPLOG      ** DONE

TIMER         ** DONE

TIMESTR       ** DONE

UPPER         ** DONE

UPUSER        ** DONE

USES

WHEREX        ** DONE

WHEREY        ** DONE

WORDCOUNT     ** DONE

WORDGET       ** DONE

WORPOS        ** DONE

WRITE         ** DONE

WRITELN       ** DONE