fsxNet Wiki

BBS Development & Resources

User Tools

Site Tools


programming:mplfunc

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

programming:mplfunc [2018/10/03 14:11] (current)
xqtr created
Line 1: Line 1:
 +<​code>​
 +-------------------------------------------------------------------------------
 +    MPL Functions, Variables, Constants, Records and more
 +-------------------------------------------------------------------------------
 +    ​
 +  INDEX
 +  ​
 +  1. Date Functions
 +  2. String Manipulation
 +  3. Theme Related
 +  4. Screen Manipulation ​
 +  ​
 +-------------------------------------------------------------------------------
 +    ​
  
 +1. Date Functions
 +-------------------------------------------------------------------------------
 +
 +  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.
 +
 +  ​
 +  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 DATE2DOS (Str : String) : LongInt
 +        ​
 +        This function takes a MM/DD/YY format date and converts it to DOS 
 +        packed datetime format. ​
 +  ​
 +  ​
 +  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 DateValid(S:​ String) : Boolean
 +  ​
 +        Takes a MM/DD/YY date and returns true or false depending on if the 
 +        date is valid (ie, month is 01-12, etc).
 +  ​
 +
 +  DateJulian:​LongInt;​
 +        Returns the longint Julian value of the current date.
 +        ​
 +  ​
 +  Function DATESTR (DT: LongInt, dType: Byte)
 +
 +         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:
 +
 +              ​
 +              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. ​
 +          No longer accepts 0 as the users current date format. ​ Pass the 
 +          user's actual date format to it if you want that.  For example:
 +          Str := DateStr(MyDateTime,​ UserDateType);​
 +         The other parameters (ie 1 = MM/DD/YY) work as they used to.
 +  ​
 +  Function DateStrJulian(DT:​ LongInt, dType: Byte)
 +  ​
 +        Works just like DateStr but accepts a Julian date.
 +        ​
 +  ​
 +  Function DayOfWeek:​Byte;​
 +
 +        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(J:​LongInt) : LongInt
 +
 +        This function takes a Julian date value and returns the number of days
 +        between the current date and the passed date.
 +        ​
 +  ​
 +  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 TimerMS : LongInt
 +      ​
 +        This may or may not stay but it provides a way to do millsecond timing ​
 +        of things.
 +  ​
 +  ​
 +  Function TimerMin : LongInt
 +          ​
 +        Same as TimerMS, but gives time in Minutes
 +          ​
 +  ​
 +  Procedure FormatDate(dosDate,​ mask) : String;
 +  ​
 +        Allows you to convert a DOS format date to a string using the mask:
 +            YYYY - 4 digit year
 +              YY - 2 digit year
 +              MM - 2 digit month
 +             DDD - 3 char weekday (ie Mon Tue)
 +              DD - 2 digit day
 +              HH - 2 digit hour
 +              II - 2 digit minute
 +              SS - 2 digit second
 +             NNN - 3 char month (ie Jan, Feb, Mar)
 +       
 +       
 +  Function datedos2str(D:​Longint;​ T:Byte) : String
 +        ​
 +        4 = MM/DD/YYYY
 +        5 = DD/MM/YYYY
 +        6 = YYYY/MM/DD
 +        ​
 +        ​
 +  Function datejulian2str(D:​Longint;​ T:Byte) : String
 +  ​
 +        4 = MM/DD/YYYY
 +        5 = DD/MM/YYYY
 +        6 = YYYY/MM/DD
 +  ​
 +
 +
 +2. String Manipulation
 +-------------------------------------------------------------------------------
 +  ​
 +  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 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"​
 +
 +  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 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 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.
 +
 +         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? ')
 +              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? ')
 +              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 ​                   # Is key returned an arrow key?
 +           If Ch = '​H'​
 +             ​WriteLn ('Up arrow'​)
 +           Else If Ch = Chr(80)
 +             ​WriteLn ('Down arrow'​)
 +         ​Else ​                         # No arrow key.  A normal character
 +           ​WriteLn ('You entered character: ', Ch)
 +         End
 +
 +         The above example reads a key with READKEY and then uses the
 +         ​ISARROW function to process the Up Arrow and Down Arrow keys.
 +  ​
 +
 +  Function StrMci(Str:​String) : String; ​  ​[mci2str also works]
 +  ​
 +        StrMci takes an entire string and attempts to translate any MCI codes 
 +        found in it, returning the entire result. Ex:
 +            S := StrMci('​Hello |UH');
 +            ​
 +  ​
 +  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 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 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 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 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 StrComma(L:​LongInt) : String;
 +  ​
 +        Accepts a longint and returns it as a string, with commas added where
 +        applicable: Ex:
 +            WriteLn (strComma(1000000)); ​ // will print 1,000,000
 +  ​
 +  ​
 +  Function StripL(Str1,​Str2:​String) : String;
 +
 +        Strips the left side of a string of any specified leading characters. Ex:
 +            Var S : String = ' ​   Hello';​
 +            S := StripL(S, ' ');
 +            ​
 +      ​
 +  Function StripR(Str1,​Str2:​String) : String;
 +        Strips the right side of a string of any specifcied trailing character:
 +            Var S : String = '​Hello ​    ';​
 +            S := StripR(S, ' ');
 +     
 +     
 +  Function StripB(Str1,​Str2:​String) : String;
 +  ​
 +        Strips both sides of the string if a specific character.
 +            Var S : String = ' ​    ​Hello ​    ';​
 +            S := StripB(S, ' ');
 +  ​
 +  ​
 +  Function StripLow(S: String) : String
 +  ​
 +        Strips all chracters from a string that are less than ascii code #32. Ex:
 +            Var S : String = #​12#​12#​12#​12 + '​Hello';​
 +            S := StripLow(S);​
 +  ​
 +  ​
 +  Function stripmci(S:​String) : String
 +        ​
 +        Returns a string without any MCI codes if included in the string.
 +        ​
 +  ​
 +  Function StripPipe(Str:​String) : String
 +  ​
 +      Takes a string and strips only pipe color codes from it. Ex:
 +          S := StripPipe('​|15Hello there, |UH'​); ​ //returns "Hello There, |UH"
 +          ​
 +  ​
 +  Function MCILength(Str:​String) : Byte;
 +  ​
 +        Works just like "​Length"​ except it tries to ignore MCI codes. ​ It doesn'​t ​
 +        check for actual validity of MCI codes. Ex:
 +            Var B : Byte;
 +            B := MCILength('​|15Hello|UH'​);​
 +            WriteLn ('​Length should be 5: ' + Int2Str(B));​
 +  ​
 +  Function Initials(Str:​String) : String
 +  ​
 +        Takes a user name and attempts to return one or two character initials. Ex:
 +            S := Initials('​Jack Phlash'​);​ // should return "​JP"​
 +        ​
 +        ​
 +  Function StrWrap(S:​String;​ S2:String; Pos:Byte) : String;
 +  ​
 +        strWrap takes two strings and wraps them after the word closest to the 
 +        maximum supplied length. ​ It optionally returns the actual position where it
 +        wrapped. Ex:
 +            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 Replace(S:​String;​ Find:​String;​ Rep:​String):​String;​
 +
 +        Replace 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 WordCount(S:​ String; C:​Char):​Integer;​
 +  ​
 +        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(P:​Byte;​ S:String; C:​Char):​String;​
 +  ​
 +        Returns the actual word at a specific word count. Ex:
 +            Str := 'Hello this is a test';
 +            WriteLn('​The second word was: ' + WordGet(2, Str, ' '));
 +
 +      ​
 +  Function WordPos((P:​Byte;​ S:String; C:​Char):​Integer;​
 +  ​
 +        WordPos returns the character position in the string where s specific ​
 +        word is located. ​ Ex:
 +            Str := 'Hello this is a test';
 +            WriteLn ('​Second word is at: ' + Int2Str(WordPos(2,​ Str, ' ')));
 +      ​
 +      ​
 +  Function Real2Str(R:​Real;​ D:Byte) : String;
 +  ​
 +        This takes a string and decimal place value. ​ Example:
 +            Var
 +              R : Real;
 +            Begin
 +              R := 1234.1234;
 +              WriteLn (Real2Str(R,​ 2));  // Will print 1234.12
 +            End
 +            ​
 +
 +3. Theme Related
 +-------------------------------------------------------------------------------
 +
 +  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 SetPromptInfo(D:​Byte;​ 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'​);​
 +
 +4. Screen Manipulation
 +-------------------------------------------------------------------------------
 +  ​
 +  Variables
 +  =========
 +  ​
 +  allowarrow ​ : boolean
 +  ​
 +          Undocumented
 +          ​
 +          ​
 +  textattr ​   :   Byte
 +          ​
 +          Returns the text attribute (color) of the screen.
 +          ​
 +  ​
 +  AllowMci ​       boolean
 +          ​
 +          Toggles on/off MCI code parsing. This is used outside of MPL so 
 +          adjust this with caution.
 +          ​
 +          ​
 +  Functions
 +  =========
 +  ​
 +  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
 +              WriteLn ('ANSI graphics'​)
 +         Else
 +              WriteLn ('​ASCII graphics'​)
 +         EndIf
 +
 +         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.
 +  ​
 +  ​
 +  Function PausePos : Byte
 +  ​
 +        Gives access to Mystic'​s internal line counter used for screen pauses.
 +  ​
 +  ​
 +  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'​)
 +         
 +  ​
 +  Procedure GetScreenInfo(1,​ X, Y, Attr);
 +  ​
 +        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. Example:
 +
 +           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 GetCharXY(X,​Y;​Byte) : Char;
 +  ​
 +          Returns the character located on the user's screen at the XY
 +          location. Ex:
 +              Var Ch : Char;
 +              Ch := GetCharXY(1,​ 1);
 +              WriteLn('​The user has the following character at 1,1: ' + Ch);
 +              ​
 +     
 +  Function GetAttrXY(X,​Y;​Byte) : Byte;
 +  ​
 +        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));​
 +  ​
 +
 +  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
 +        ​
 +  ​
 +  Procedure WritePipe(S:​ String);
 +  ​
 +        Works just like Write but only parses Pipe color codes instead of all 
 +        MCI codes.
 +        ​
 +  ​
 +  Procedure WritePipeLn(S:​ String);
 +  ​
 +        Is WritePipe with a CRLF at the end.
 +        ​
 +
 +  Procedure WriteRaw(S: String);
 +  ​
 +        Works just like write except it does not parse any pipe color codes OR 
 +        MCI codes.
 +
 +  WriteRawLn(S:​ String);
 +  Works just like WriteRaw except with a CRLF added to the end.
 +  ​
 +  WriteXY(X,​Y,​At:​Byte;​ Str:​String);​
 +  Writes a string of text at the defined X/Y location with a specific text
 +  attribute. ​ This of course requires the user has ANSI to function properly.
 +      WriteXY (1, 10, 8, '​Prints at X:1 Y:10 with dark grey text'​);​
 +      ​
 +  WriteXYPipe(X,​Y,​At,​F:​Byte;​ Str:​String);​
 +  This procedure writes a string of text at the defined location, similar to 
 +  WriteXY *except* it parses pipe color codes *and* requires a "​maximum field 
 +  size" of which it will always extend or restrict the length of the text 
 +  within that field. Ex:
 +        WriteXYPipe (1, 10, 8, 50, 'This pads to 50 chars at location 1,​10'​);​
 +  ​
 +  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.
 +         
 +  clrscr ​          ​none ​        none
 +  clreol ​          ​none ​        none
 +  ​
 +  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 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.
 +  ​
 +  disptemplate ​    ​s ​           None
 +  outbs            bo           None
 +  textcolor ​       bo           None
 +  outpipe ​         s            None
 +  outpipeln ​       s            None
 +  outraw ​          ​s ​           None
 +  outrawln ​        ​s ​           None
 +  bufaddstr ​       s            None
 +  ​
 +  BufFlush;
 +  This causes Mystic to immediately send whatever is in the output buffer to 
 +  the client.
 +  ​
 +
 +Program related
 +---------------
 +  Variables
 +  ​
 +  PathChar : String;
 +  Returns the Path character used, according to the system. For Linux is / and
 +  for Windows is \.
 +  ​
 +  ProgParams : String
 +  Returns any of the parameters passed to the MPL program as a single string.
 +  ​
 +  ProgName : String;
 +  Returns the path and filename of the current MPL program.
 +  ​
 +  Procedures/​Functions
 +  ​
 +  Procedure HALT
 +  This procedure will exit the program and return the user back to the BBS 
 +  immediately. ​
 +  ​
 +  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 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. ​      
 +  ​
 +  ​
 +  randomize ​       none         none
 +  ​
 +  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
 +              WriteLn ('​Invalid command line.'​)
 +              Halt
 +         EndIf
 +
 +         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.
 +  ​
 +  IgnoreGroups ​   boolean
 +  Is used to cause all group ACS evaluations to return true even if they are 
 +  not in the group. ​ This is also used outside of MPL so change it with caution.
 +  ​
 +  shutdown ​       boolean
 +  ​
 +  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).
 +  ​
 +  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? ')
 +              HangUp
 +         EndIf
 +
 +         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.
 +  ​
 +  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.
 +  ​
 +  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.'​)
 +         EndIf
 +
 +Keyboard Related
 +----------------
 +  ​
 +  Variables
 +  =========
 +  ​
 +  isarrow ​        ​boolean
 +  ​
 +  Procedures
 +  ==========
 +  ​
 +  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.
 +  ​
 +  getkey ​          ​l ​           String
 +  getyn            so           ​boolean
 +  getstr ​          ​bbhs ​        ​String
 +  pause            none         None
 +  more             ​none ​        ​String
 +  onekey ​          ​so ​          ​String
 +  ​
 +  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 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!".
 +  ​
 +  PurgeInput;
 +  This will clear out any local or remote input data.
 +  ​
 +  OneKeyRange
 +  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.
 +  ​
 +  MorePrompt;
 +  Displays the system more prompt and returns a Char value of either Y N or C 
 +  depending on what the user selected.
 +  ​
 +  Pause;
 +  Displays the system pause prompt, for those that don't like doing a 
 +  "​Write('​|PA'​)"​.
 +  ​
 +File I/O
 +--------
 +
 +  Variables
 +  ​
 +  ioresult ​       LongInt
 +  The result of the last call is now stored in the "​IoResult"​ variable. ​ Ex:
 +      fAssign (MyFile, '​myfile.txt'​ 66);
 +      fReset ​ (MyFile);
 +
 +      If IoResult <> 0 Then
 +        WriteLn('​Unable to open file!'​);​
 +  ​
 +  DIRECTORY READING VARS (FOR FINDFIRST/​NEXT/​CLOSE):​
 +
 +  doserror ​       Integer
 +  dirname ​        ​String
 +  dirsize ​        ​LongInt
 +  dirtime ​        ​LongInt
 +  dirattr ​        Byte
 +  ​
 +  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
 +
 +         FOpen (1, Text, Reset, '​BLAH.TXT'​)
 +         While Not fEOF(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.
 +  ​
 +  SizeOf(Var) : Integer;
 +  Returns the size of a variable or record type
 +  ​
 +  ​
 +  FillChar(Var;​ Size:​Integer;​ C:Char);
 +  Fills a variable/​record with a specific character. Ex:
 +       type
 +         ​myuserrecord = record
 +           ​username ​ : string[30];
 +           ​somevalue : array[1..5] of byte;
 +         end;
 +       var
 +         u : myuserrecord;​
 +       begin
 +         ​fillchar(u,​ sizeof(u), #0);
 +       end.
 +  ​
 +  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'​)
 +              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"​.
 +  ​
 +  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 FERASE
 +         ​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.
 +  ​
 +  DirExist(S:​String) : Boolean;
 +  Returns true or false if a directory exists.
 +  ​
 +  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'​)
 +         
 +
 +         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.
 +  ​
 +  JustFile(S:​String) : String;
 +  Takes a string arguement and returns only the filename. Ex:
 +      WriteLn ('This MPX filename is: ' + JustFile(ProgName));​
 +      ​
 +  JustFileName(S:​String) : String;
 +  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.
 +   
 +  JustFileExt(S:​String) : String;
 +  Takes a string arguement and returns only the file extension.
 +  ​
 +  fassign ​         Fsl          None
 +  freset ​          ​F ​           None
 +  frewrite ​        ​F ​           None
 +  fclose ​          ​F ​           None
 +  fseek            F            None
 +  feof             ​F ​           boolean
 +  ​
 +  Function FILEPOS (Handle) : 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:​
 +
 +         fOpen (1, Bin, Reset, '​TEST.DAT'​)
 +         If FilePos(1) = FileSize(1)
 +              WriteLn ('END OF FILE.'​)
 +         EndIf
 +         ​fClose (1)
 +
 +         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 "​FilePos(1) = FileSize(1)"​ is the same
 +         as "​Eof(1)"​ 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 FILESIZE (Handle) : 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:​
 +
 +         fOpen (1, Bin, Reset, '​TEST.DAT'​)
 +         ​WriteLn ('This file is ', FileSize(1),​ ' bytes in size.'​)
 +         ​fClose (1)
 +
 +         The above example opens the file "​TEST.DAT",​ writes the size of
 +         the file to the screen, and then closes the file.
 +  ​
 +  fread            F*w          None
 +  freadrec
 +  fwrite ​          ​F*w ​         None
 +  rwriterec
 +  freadln ​         FS           None
 +  fwriteln ​        ​FS ​          None
 +  pathsep ​         none         ​String
 +
 +  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
 +              WriteLn ('File Name: ', DirName)
 +              FindNext
 +         WEnd
 +         ​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:
 +
 +                      Attribute ​  ​Description
 +                      ----------- -------------------------
 +                      ReadOnly ​   Return files marked as "read only".
 +                      Hidden ​     Return files marked as "​hidden"​.
 +                      SysFile ​    ​Return files marked as "​system files"​.
 +                      VolumeID ​   Return files marked as "​volume ID".
 +                      Directory ​  ​Return files marked as "​directory"​.
 +                      Archive ​    ​Return files marked as "​archive"​.
 +                      AnyFile ​    ​Returns any and all files.
 +
 +                      These attributes can be combined when passed to
 +                      FindFirst. ​ For example: READONLY + HIDDEN will return
 +                      any files which have been marked as "​readonly"​ OR
 +                      "​hidden"​. ​ Example: 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.
 +                         ​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:​\*.*',​ ReadOnly + Archive)
 +         While DosError = 0
 +              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
 +         WEnd
 +         ​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 ('​*.*',​ Archive)
 +         While DosError = 0
 +              WriteLn ('File Name: ', DirName)
 +              FindNext
 +         WEnd
 +         ​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.
 +  ​
 +  JustPath(S: String) : String;
 +  Takes a string arguement and returns only the path (including the trailing
 +  backslash). ​ Ex:
 +      WriteLn ('This MPX is located in ' + JustPath(ProgName));​
 +      ​
 +  getsauce ​        ​sSSSS ​       boolean
 +  ​
 +  FileOpen
 +     ​FileEOF
 +     ​FileRead
 +     ​FileSeek
 +     ​FilePos
 +     ​FileSize
 +     ​FileWrite
 +     ​FileWriteBlock
 +     ​FileRead
 +     ​FileReadBlock
 +     ​FileClose
 +  ​
 +  AddSlash(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.
 +  ​
 +  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:
 +      AppendText("​c:​\test.txt',​ 'This is a line of text added to test.txt!'​)
 +  ​
 +User Related
 +------------
 +
 +  Variables
 +
 +  userid ​         LongInt
 +  username ​       String[30]
 +  userhandle ​     String[30]
 +  userpw ​         String[20]
 +  useradd ​        ​String[30]
 +  usercity ​       String[25]
 +  userzip ​        ​String[10]
 +  userhphone ​     String[15]
 +  userdphone ​     String[15]
 +  usergender ​     String[1]
 +  userbday ​       LongInt ​   // julian date
 +  useremail ​      ​String[40]
 +  userinfo ​       String[40]
 +  usersec ​        Byte
 +  userstart ​      ​String[20]
 +  userexp ​        ​String[8]
 +  userexpto ​      Byte
 +  useraf1 ​        ​LongInt
 +  useraf2 ​        ​LongInt
 +  userdtype ​      Byte
 +  userscrnsize ​   Byte
 +  userhotkey ​     Boolean
 +  userfsedit ​     Boolean
 +  userquotewin ​   Boolean
 +  userflist ​      ​Boolean
 +  usermread ​      ​Boolean
 +  usermidx ​       Boolean
 +  usermeidx ​      ​Boolean
 +  userchat ​       Boolean
 +  usersig ​        ​Boolean
 +  usersigptr ​     LongInt
 +  userarc ​        ​String[4]
 +  usertheme ​      ​String[20]
 +  usercname ​      ​String[30]
 +  userinvis ​      ​Boolean
 +  useravail ​      ​Boolean
 +  userpip ​        ​String[20]
 +  userpname ​      ​String[50]
 +  usertime ​       Integer
 +  usercmbase ​     Word
 +  usercmgroup ​    Word
 +  usercfbase ​     Word
 +  usercfgroup ​    Word
 +  usercall ​       LongInt
 +  usertcall ​      Word
 +  userdls ​        ​LongInt
 +  usertdls ​       Word
 +  userdlkb ​       LongInt
 +  usertdlkb ​      ​LongInt
 +  userfcall ​      ​LongInt ​  //dos date
 +  userlcall ​      ​LongInt ​  //dos date
 +  userposts ​      ​LongInt
 +  useremails ​     LongInt
 +  useruls ​        ​LongInt
 +  userulkb ​       LongInt
 +  userbank ​       Word
 +  userlastpw ​     String[8]
 +  uservyes ​       Byte
 +  uservno ​        Byte
 +  userdoors ​      ​LongInt
 +  userflag ​       LongInt
 +  useropts ​       Array[1..10] of String[60];
 +  UserLastOn
 +  UserFirstOn
 +  ​
 +  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.
 +  ​
 +  Function ACS (S: String) : Boolean
 +
 +         This function processes an ACS string and returns true if the user
 +         has passed.
 +
 +         ​Example:​
 +
 +         If ACS('​s10g1'​)
 +              WriteLn ('You have access to this.'​)
 +         Else
 +              WriteLn ('​Sorry,​ you do not have access.'​)
 +         EndIf
 +
 +         The above example checks to see if the user passes the ACS string
 +         of "​s10g1"​ and prints the result to the screen.
 +  ​
 +  ​
 +  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.
 +         ​USERZIP ​        ​String ​  ​User'​s ZipCode.
 +         ​USERHPHONE ​     String ​  ​User'​s home phone number.
 +         ​USERDPHONE ​     String ​  ​User'​s data phone number.
 +         ​USERBDAY ​       String ​  ​User'​s birth date.
 +         ​USERSEX ​        ​Char ​    ​User'​s gender (M = Male, F = FeMale).
 +         ​USERSEC ​        ​Byte ​    ​User'​s security level (0-255).
 +         ​USERMENU ​       String ​  ​User'​s Starting Menu (if blank, Mystic
 +                                  uses the default menu as setup in the
 +                                  configuration).
 +         ​USERFIRST ​      ​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.
 +         ​USERLAST ​       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.
 +         ​USERCALLS ​      ​LongInt ​ User's total calls to the BBS system.
 +         ​USERTCALLS ​     Integer ​ User's number of calls to the BBS today.
 +         ​USERDLS ​        ​LongInt ​ User's total # of downloaded files.
 +         ​USERTDLS ​       Integer ​ User's total # of downloaded files today.
 +         ​-------------------------------------------------------------------
 +
 +         ​Example:​
 +
 +         Var A Integer
 +
 +         A := 1
 +         While GetUser(A)
 +              WriteLn ('User Alias: ', UserAlias)
 +              A := A + 1
 +         WEnd
 +
 +         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.
 +  ​
 +  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)
 +              UserDeleted := True
 +              PutUser(1)
 +         EndIf
 +
 +         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.
 +  ​
 +  ​
 +  ​
 +  getuserbyname ​   s            boolean
 +  getuserbyid ​     l            boolean
 +  ​
 +  IsUser(Str:​String) : Boolean;
 +  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.
 +  ​
 +  settimeleft ​     i            none
 +
 +
 +FBASE Unit
 +----------
 +  ​
 +  FBaseIndex
 +  FGROUPHIDDEN
 +  MGROUPHIDDEN
 +  ​
 +  fbasefn"​ returns the file base's filename
 +  ​
 +MBASE Unit
 +----------
 +
 +  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
 + MBASEQWK ​      ​String ​   QWK name
 + MBASEFILE ​     String ​   File name
 + MBASEPATH ​     String ​   Storage Path
 + MBASEPTYPE ​    ​Byte ​     Post type: 0 = Public, 1 = Private
 + MBASEACS ​      ​String ​   ACS level
 + MBASERACS ​     String ​   Read ACS level
 + MBASEPACS ​     String ​   Post ACS level
 + MBASESACS ​     String ​   SysOp ACS level
 + MBASEPW ​       String ​   Password
 + MBASECQUOTE ​   Byte      Quote color (text attribute)
 + MBASECTEXT ​    ​Byte ​     Text color
 + MBASECTEAR ​    ​Byte ​     Tear color
 + MBASECORIG ​    ​Byte ​     Origin color
 + MBASEBTYPE ​    ​Byte ​     Base type: 0 = JAM, 1 = Squish
 + MBASEAKA ​      ​Byte ​     Network address AKA #
 + MBASEORIG ​     String ​   Origin line
 + MBASEREAL ​     Boolean ​  Use real names?
 + MBASEDNSCAN ​   Byte      New scan? 0 = no, 1 = yes, 2 = always
 + MBASEDQSCAN ​   Byte      QWK scan? 0 = no, 1 = yes, 2 = always
 + MBASEHDR ​      ​String ​   Header file
 + MBASEINDEX ​    ​Integer ​  Index number (*NEVER* change this)
 +
 +         ​Example:​
 +
 +         Var A Word
 +
 +         A := 1
 +         While GetMBase
 +              WriteLn ('Base name: ', MBaseName)
 +              A := A + 1
 +         Wend
 +
 +         The above example will list all available message base systems on
 +         the BBS.
 +
 +  GetMBStats(id:​LongInt;​ ExMsgF, ExMsgT: Boolean; total, new, yours: Longint);
 +  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;
 +          end.
 +          ​
 +  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.
 +  ​
 +  GetMailStats(Total,​ UnRead:​LongInt);​
 +  Returns the number of e-mail messages and the number of unread email messages:
 +       Var
 +         ​Total,​ UnRead: LongInt;
 +       Begin
 +         ​GetMailStats(Total,​ UnRead);
 +
 +         ​WriteLn ('You have ' + Int2Str(Total) + ' emails, ' + Int2Str(UnRead) + ' unread'​);​
 +       End;
 +       
 +  CfgNetDesc (array 1..30 of string[25] contains network descriptions) and 
 +  MBaseNetAddr (contains the network address target of the message base). ​ Ex:
 +      Uses CFG, MBASE;
 +      Begin
 +        If GetMBase(1) Then
 +          WriteLn ('Base #1 is in network: ' + CfgNetDesc[MBaseNetAddr]);​
 +      End.
 +      ​
 +  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
 +              MBaseName := '​Message Base #1'
 +              PutMBase(1)
 +         EndIf
 +
 +         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.
 +  ​
 +CFG Unit
 +--------
 +
 +  Variables
 +  ​
 +  cfgpathsys ​     string[60]
 +  cfgpathdata ​    ​string[60]
 +  cfgpathlogs ​    ​string[60]
 +  cfgpathmsgs ​    ​string[60]
 +  cfgpathfile ​    ​string[60]
 +  cfgpathmail ​    ​string[60]
 +  cfgpathmenu ​    ​string[60]
 +  cfgpathtext ​    ​string[60]
 +  cfgpathansi ​    ​string[60]
 +  cfgpathmpl ​     string[60]
 +  cfgtimeout ​     word
 +  ​
 +  CfgTNNodes
 +  Variable, which now contains the number of telnet nodes to allow. ​ These are
 +  basically interchangable in your MPL code but it is changing to more
 +  accurately reflect what Mystic is doing.
 +  ​
 +  CfgTempPath
 +  returns the location of the current node temporary directory.
 +  ​
 +  CfgChatStart and CfgChatEnd.
 +  These return the byte of the chat hour start and end variables from the 
 +  System Configuration
 +  ​
 +  CfgSeeInvis
 +  Gives you access to the "See Invisible"​ ACS value from Mystic'​s configuration
 +  ​
 +  ReadEnv(S:​String) : String;
 +  Returns the value of an environment variable of the operating system.
 +  ​
 +  menucmd ​         ss           None
 +  ​
 +  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
 +         ​CFGARCSPATH ​   : Archive 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)
 +         ​CFGMENUPATH ​   : Menu Files Path (for the current language)
 +         ​CFGSTATUSTYPE ​ : Returns status line mode (0 = 2 line, 1 = 1 line)
 +
 +         ​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.
 +  ​
 +Bit Operations
 +---------------
 +  ​
 +  BitCheck(Pos:​Byte;​ AnyVar) : Boolean
 +  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'​);​
 +  ​
 +  ​
 +  BitToggle(Pos:​Byte;​ AnyVar);
 +  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.
 +                                ​
 +                                ​
 +  BitSet(Pos:​Byte;​ AnyVar; True:​Boolean);​
 +  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
 +      ​
 +  MPL now 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;
 +
 +Math & Number Related
 +---------------------
 +
 +  Types
 +  =====
 +    Real
 +    Integer
 +    Byte
 +    Word
 +    ​
 +  Procedures
 +  ==========
 +  ​
 +  Mod (%)
 +  Gets the mod of a division. Example:
 +      A := 10 % 8;
 +
 +  POWER operator in mathmatical equations:
 +      A := 2 ^ 3;
 +
 +  Function odd(l:​LongInt):​Boolean
 +  Returns True if number is odd.
 +  ​
 +  Real2Str(R:​Real;​ D:Byte) : String;
 +  This takes a string and decimal place value. ​ Example:
 +      Var
 +        R : Real;
 +      Begin
 +        R := 1234.1234;
 +        WriteLn (Real2Str(R,​ 2));  // Will print 1234.12
 +      End
 +      ​
 +  ABS (Num: LongInt) : LongInt; ​
 +  This value takes a signed integer and returns the absolute value.  ​
 +
 +Special Things...
 +-----------------
 +
 +  Message Editor
 +
 +   ​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
 +
 +
 +  Classes
 +  =======
 +  ​
 +  MPL now has the ability to interface directly with internal Mystic BBS
 +   ​classes. ​ This opens up a whole world of new possibilities in the future
 +   (for example) sockets, full remote ANSI screen library (boxes, listboxes)
 +   data sorting, and more.
 +
 +   ​Classes must first be created and then freed after using. ​ Mystic will
 +   ​create the class instance and return a handle to that specific class to
 +   use with the functions. ​ Finally, the class is freed. ​ Two new functions
 +   go with this:
 +
 +      ClassCreate (ClassHandle,​ ClassType)
 +      ClassFree (ClassHandle)
 +
 + + MPL now supports the ANSI box class. ​ There are three functions which
 +   go along with this: BoxOpen, BoxClose, and BoxOptions. ​ The Box class
 +   will automatically save and and subsequently restore the text under the
 +   box when it is closed.
 +
 +   See TESTBOX.MPS for an example.
 +
 + + MPL now supports the ANSI input class. ​ There are several functions which
 +   go along with this: InputString,​ InputNumber,​ InputEnter, InputOptions.
 +   This class allows you more freedom over input functions than the standard
 +   MPL input functions do.
 +
 +   See TESTINPUT.MPS for an example.
 +   
 +   MPL now supports ANSI screen class. ​ This allows the ability to save and
 +   ​restore portions of the user's screen. ​ The example below saves the screen
 +   ​coordinates defined as: X1:20, Y1:5, X2:60, Y2:​10. ​ It then clears the
 +   ​screen and then restores the saved portion of the screen.
 +
 +      Var SavedScreen : LongInt;
 +
 +      ClassCreate (SavedScreen,​ '​image'​);​
 +      ImageGet ​   (SavedScreen,​ 20, 5, 60, 10);
 +
 +      ClrScr;
 +      WriteLn ('​Press a key to restore'​);​
 +
 +      Pause;
 +
 +      ImagePut (SavedScreen);​
 +      ClassFree (SavedScreen);​
 +
 +      Pause;
 +
 +</​code>​
programming/mplfunc.txt · Last modified: 2018/10/03 14:11 by xqtr