Note that MXPM is an unstable format! I'm not sure how good the parser I wrote is. The only way to find out is to try using it, so bang on it, and write me mail if you have problems.
This is gonna get technical, but bear with me.
The first thing in an MXPM file is the preamble, which should look exactly like this:
/* MXPM */Other comments
/* */
can be freely sprinkled
throughout the file, most
anywhere a space would be accepted.
Following the preamble comes a set of #define
s, which
determine the direction the file will be played and the number of
frames in the file. The number of frames is mandatory; the
direction is optional.
The number of frames is given by a line that looks like this:
#define <name>_frames 2where
<name>
is replaced by some name, consisting
of letters, numbers, and spaces. THIS NAME IS IMPORTANT!! The first
<name>
that the parser finds will be assumed to be
the name for the entire file. Thus, any later information which
contains a <name>
must match the first
<name>
encountered.The direction is given by something like this:
#define <name>_direction MXPM_WHATEVERwhere
MXPM_WHATEVER
can be one of
MXPM_FORWARD
, MXPM_BACKWARD
,
MXPM_ALTERNATE
, and MXPM_RANDOM
. (These
directions are the same as the directions the drumming fingers can go
in the sender window.)
Following the #define
s is however many comments and C
statements you like. Each C statement must be terminated by a
semicolon. A good use of C statements is to declare XPM's to be
defined later on in the MXPM file; see the example below for how to do
that.
After all this comes the MXPM definition itself. It looks like this:
static MXPMSequenceItem <name>_items[] = { /* comment comment comment if you want one */ < one item definition for each frame > };Each item definition looks like this:
{ <number of ticks>, <either &<name of in-file XPM> or NULL>, <either "<name of external file>" or NULL> },The
<number of ticks>
is the number of ticks that
xzewd will display that frame of the sequence for. Normally, one tick
equals one second, but the user can change that tick value for herself
with the xzewd-snapshots*tickTime
resource (value in
milliseconds).
The next thing is either NULL
if the picture for that
frame is in an external file, or
&<name-of-XPM>
if the picture for that
frame is an XPM file contained later on
in the MXPM file.
The next thing is either NULL
if the picture for that
frame is in an internal XPM, or
"<pathname>"
if the picture for that frame
is an external file.
Following the MXPM definition itself comes, optionally, definitions
for any internal XPM's specified in the MXPM section. They can come in
any order; xzewd matches frame to XPM by the name. This does mean,
though, that the <name-of-XPM>
specified
in the MXPM sequences must match the name of the XPM. To find the name
of an XPM file, just look for a line that looks like this near the top
of the XPM file:
static char * this_is_the_name_of_the_xpm[] = {To stick an XPM file into an MXPM file, just insert it at the end. Nothing more special is needed.
As for external files, xzewd can understand any of the formats it normally understands for snapshots. If the pathname of an external file doesn't begin with a "/", xzewd will append it to the directory it found the MXPM file in.
Here's a sample MXPM file. Note that all 3 frames of the animation are stored within the file itself.
/* MXPM */ #define thing_direction MXPM_RANDOM #define thing_frames 3 extern char *thing1[], *thing2[], *thing3[]; /* That line was optional. So is this one. */ static MXPMSequenceItem thing_items[] = { /* ticks, */ { 1, &thing1, NULL}, { 1, &thing2, NULL}, { 1, &thing3, NULL}}; /* I had to write everything above by hand. Everything below here, though, was copied straight from XPM's generated by xpaint. */ /* XPM */ static char *thing1[] = { "20 20 11 1", " c #000000000000", ". c #F9006900A700", "X c #9A000000FF00", "o c #FF00FF00FF00", "O c #FF0000009A00", "+ c #00000000DE00", "@ c #B2002900F900", "# c #FF00FF003300", "$ c #FF0000000000", "% c #14002900F900", "& c #0000FF000000", " ..XoooooooooooooOoo", "...oooXooooo++oooooo", ".. oXoooooo++oooooo", ". @ oooooooooo#####", " @@@ ooooooooooooooo", " @@@ oooo$ooo$oooXo", " @@@ o$ooo$ooooXo", " % @@@ oo$oooooXo", " %%% @@@ ..$ooooooXo", "%%% @ ... ooooooXo", "%% ... oooooooo", "% & ... @ ooo+ooo", " &&& ... @@@ oooo+oo", " &&& . @@@ oooo+o", " &&& @@@ ooo+", " . &&& % @@@ ooo", " ... &&& %%% @@@ .oo", "... & %%% @ ..+o", ".. %%% ... +", ". @ %%% & ... @o"}; /* XPM */ static char * thing2[] = { "20 20 3 1", " c #FFFF00000000", ". c #00000000FFFF", "X c #FFFF0000FFFF", " .......", " ........", " ........", " ........", " .........", " .........", " .........", " ..........", " ..........", " XXXX ...........", " XXXXXXXX..........", " XXXXXXXXXXX........", "XXXXXXXXXXXXXX......", "XXXXXXXXXXXXXXX.....", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX"}; /* XPM */ static char * thing3[] = { "20 20 3 1", ". c #FFFF00000000", "X c #00000000FFFF", " c #FFFF0000FFFF", " .......", " ........", " ........", " ........", " .........", " .........", " .........", " ..........", " ..........", " XXXX ...........", " XXXXXXXX..........", " XXXXXXXXXXX........", "XXXXXXXXXXXXXX......", "XXXXXXXXXXXXXXX.....", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXX"};Enjoy. Write if you have any questions.