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

MPL Documentation

From The Bottomless Abyss BBS Wiki
Revision as of 23:22, 25 February 2019 by StackFault (talk | contribs) (Created page with "   The Mystic BBS Programming Language Documentation    Copyright (C) 1998-2015 By James Coyle.  All Rights Reserved    All mentioned programs are copyrighted by thei...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

   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