
MZX 2.68 new features

The following features have been added to 2.68 from 2.65:

- Expressions
- Trigonometry
- MZM file management
- Board/overlay transfer
- Robotic sav file saving/loading
- New strings
- Various bug fixes and minor additions

-- Expressions --

Expressions allow the user to either set a counter to a mathematical expression
involving other counters and constant numbers, or embed such a number in the middle
of a message in Robotic. Take the following example:

set "a" 5
set "b" 10
set "counter" "('a' + ('b' / 'a') + 10)"

Would set counter to 5 + (10 / 5) + 10, or to 17. Note that the outer parentheses are
necessary.

The text inside single quotes may be any valid "message", and you may use ampersands
alternatively instead of single quotes; ie:

set "counter" "(&a& + (&b& / &a&) + 10)"

By message, that means anything you could put within double quotes; This means you may
further embed things inside them, however, you may only use the ampersand if the message
itself does not use ampersands; the reason is that MZX is incapable of determining nested
ampersands and will interpret the expression incorrectly. It is suggested that instead
of embedding inside messages with ampersands, you do with expressions:

set "a" 5
set "b" 10
set "a5" 20

set "counter" "('a('a')' * 2)"

Would set counter to the value in a5, which is 20, * 2, or 40.
You may nest expressions this way indefinitely; the only limit to the size of an overall
expression is that which MZX will let you write in the editor (which is about 160 characters)

In expressions, the following operators may be used:

Binary operators:
Binary operators have a value, an argument, and a value. An example of a binary expression is

'a' + 'b'

Where the first operand is a, the operator is +, and the operand value is b.

The following binary operators are present:

+		Addition
-		Subtraction
*		Multiplication
/		Division
%		Modulo
^		Exponent (a^b is a to the b order/power)
>>		Bitshift right; it is logical, not arithmetic
<<		Bitshift left
>		Greater than; evaluates to 1 if true, 0 if false
<		Less than; evaluates to 1 if true, 0 if false
>=		Greater than or equal to; evaluates to 1 if true, 0 if false
<=		Less than or equal to; evaluates to 1 if true, 0 if false
=		Equal to; evaluates to 1 if true, 0 if false
!=		Not equal to; evaluates to 1 if true, 0 if false
a		Bitwise AND (not logical AND)
o		Bitwise OR (not logical OR)
x		Bitwise XOR (not logical XOR)

Unary operators:
Unary operators have an operator followed by an argument (in prefix; the two unary operators
in MZX expressions are prefix). An example of a unary expression is

-'a'

Where the operator is -, and the operand is a.

The following unary operators are prseent:

-		Unary negation; returns the negative value of the operand (two's complement)
~		Binary negation; returns the bitwise NOT value of the operand (one's complement)


-- Trigonometry --

You may set counters to a trionometrically derived value. Since counters are integers and
the primary trigonometric functions (sine and cosine) are typically less than 1, you must
set the counter "multiplier" to determine how much the value is multiplied by; ie, if you
set multiplier to 1000, and the value was .9, you would get 900.

You must also set the counter "c_divisions", this determines how the circle is divided. This
is to allow for maximum precision for the user; to set a system that uses degrees, simply
set "c_divisions" to 360.

There is also a "divider" counter that works in inverse trigonometric functions to reverse
the operation of the "muliplier" counter. Using divider and multiplier of same values you
can go back and forth between sin/asin and the like without losing much.

The following trigonometric functions in MZX are:

sin	- sine
cos	- cosine
tan	- tangent
asin	- arcsine or inverse sine
acos	- arccosine or inverse cosine
atan	- arctangent or inverse tangent

To use the counters you put the argument after the counter name.

To find the value of a sin for a 30 degree angle, multiplied by 1000, you would do the
following:

set "c_divisions" 360
set "multiplier" 1000
* "&sin30&"

Would display sin(30) in degrees, * 1000, or 500 (.5 * 1000).

-- MZM file management --

MZM files are a new addition to MZX that are similar in purpose to ANSI files, but much
less prone to error and limitation and more powerful. You may also save/load them in
game, through Robotic.

An MZM file is composed of precisely what a board is composed of, saving the color,
parameter, ID, under color, under parameter, and under ID of all chars saved. Some
things, however, are NOT saved (instead you will get a customblock likeness of it),
and those things are the player, robots, scrolls, and sensors.

When loading an MZM file to the overlay, the character used is the parameter stored.
It is possible when saving from Robotic to save the character in the parameter slot
instead of the actual parameter of the coordinate. With customblocks, customfloors,
and other types, the parameter already is the character.

You may save/load MZM files in the editor as you would ANSI files; a new option appears
below where ANSI is. When saving something in the editor it is always saved as is; so if 
you save something on the board and load it in the overlay it may not look the same if
the board information was not only customs.

In Robotic, you may save an MZM file the following way:

copy block x y w h "@filename" p
copy overlay block x y w h "@filename" p

Where x/y are the coordinates on the board/overlay, w/h are the dimensions of the block,
filename is the name of the file (the @ is necessary) and p determines if the char is
copied to the parameter slot or not. If 0 it is not, if 1 it is. The usefulness of
setting p to 1 is that if you save something and load it to the overlay it will appear
in the overlay exactly as it did on the board, regardless of the types in it.

To load an MZX file in Robotic do the following:

put "@filename" image_file pNN x y

Where filename is the name of the .mzm file (again, @ is necessary), x and y are the
coordinates to place it at, and N is 0 for board, 1 for overlay.

Note that NO attempt is made to clip the MZM files if they're taken from or loaded over
the edge; in such a scenario the operation will simply NOT happen.

-- Board/overlay transfer --

You may now copy a block from the board to the overlay and vice-versa.
To copy from board to overlay, set "overlay_x" and "overlay_y" to the coordinates you'd
like to copy to, and do the following:

copy block x y w h "overlay_x" "overlay_y"

Alternatively, you may copy from the overlay to the board in the following fashion:

copy overlay block x y w h "board_x" "board_y"

-- Robotic sav file saving/loading --

You may now save an MZX SAV file from Robotic, and load one, in the following way:

set "filename" "save_game"
set "filename" "load_game"

If the filename already exists when saving it WILL overwrite without prompting; use
at your own risk. It will also display a progress bar briefly, but nothing else.
If the filename doesn't exist when loading, the load will be unsuccessful; to check
for this it may be a good idea to put a clause after the load to see if the robot
is still running.

-- New strings --

Strings have been completely redone, although they are compatable with the 2.62b
implementation. Note that when loading a 2.62b save game file you will _not_
inherit the strings from the game.

Strings are denoted as "$stringN", where N is a decimal (not hex) number 0 thru 15 (there
are 16 strings total).

You may set a string in the following three ways:

set "$stringX" "literal"
Will set the string to the text in the quotes following.

set "$stringX" "$stringY"
Will set the string to the contents of $stringY.

set "$stringX" number
Will set the string to the numeric equivilent of the number (is the same as set "$stringX" 
"number")

You may display strings in &&, in other strings, such as:
* "~f&$string0&"

You may limit strings or offset them when using them:

$stringN#X
Will cap the string to X characters.
$stringN+X
Will offset the start of the string to X characters.
$stringN+X#Y
Will offset and cap the string to X, Y characters (not you may not use #X+Y)

You may set or get the value of a certain character in a string; this is treated like a
counter as it has a single integer value:

$stringX.Y

Represents the Yth character of the string. Please take note that the strings are null
terminated, and beyond the null terminator there may be garbage. Keep in mind the
potential structure of the string while editing them directly like this.

The following operations may be used on strings:

inc "$stringX" "$stringY"
inc "$stringX" "literal"
Will add either the contents of $stringY or the literal string to the end of $stringX.

dec "$stringX" number
Will decrease number characters off the end of $stringX.

The following special operations may be used with strings:

set "$stringX" "fread"
set "$stringX" "freadN"
Will read from the open read file to the string. The first will read up to a terminator
that is an asterisk. The second will read exactly N characters (N must be no more than
63, or it simply won't happen)

set "$stringX" "fwrite"
set "$stringX" "fwriteN"
Will write the string to the open read file. Will write it with a * at the end, or will
write exactly N characters with no * at the end. Again, N may not be more than 63.

set "$stringX" "board_name"
Sets the string to the name of the current board.

set "$stringX" "mod_name"
Sets the string to the name of the current module playing.

set "$stringX" "input"
Sets the string to the "input" string used with the input string command.

set "$stringX" "board_scan"
Reads the string, up to an *, from the board, at board_x, board_y (set these counters to
the coordinates you wish to read from to activate it.)

Alternatively, instead of using board_scan you may use the more powerful (and convenient)
copy board/overlay to string forms.

copy block x y w h "$stringX" t
copy overlay block x y w h "$stringX" t

x and y are x/y coordinates, w/h are the width and height of the block you're copying,
and t is a terminating char. The lines read from the block are run next to each other,
and the block is truncated to 63 characters if it's over. t is a terminating character;
if used in the block the string will stop reading there. Note that what is read is
either the param (for the board) or the char for the overlay. If the value read is 0,
it will always be terminated, regardless of what t is.

Strings in general may be up to 63 characters large. Anything written larger than that
will either cause the operation to not happen or the string will be cut off there.

-- Various bug fixes and minor additions --

Things may have been changed, fixed, or added that I don't completely remember, some of the
prevelant bug fixes are the following:

Now, instead of using value/sqrt_value/abs_value you may use a value with the counter
directly as such:

sqrtN
absN

fread_pos/fwrite_pos and page should work correctly now; when you increase the pos it should
bump up the page too.

pixel_x, pixel_y, char were broken in 2.65; fixed in 2.68

strings had some bugs in 2.62b+, should be fixed now because of a seperate implementation.

MZX Robot files are now saved to save files; so if you have a read and/or write file open
and the game is saved, if the game is loaded the file will be restored at the position it
was at.

-- Known Issues --

Using subroutines with a stack 1 large may generate problems sometimes, try to always use a
stack that's at least two entries large.

-- Contact --

Please report any problems to me at kutnick@andrews.edu or exophase@adelphia.net. I may be
found on AIM as Exophase, Exophase on irc.esper.net on IRC, and may be PM'd on DigitalMZX
or ZeuxWorld.