------------------------------------------------------------------------------- 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 . 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 to the length of . 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. is the menu command, and 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 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;