
1 - DDF file format
2 - Character conversions
3 - Invoking

--------------------------------------------------------------------------
1) DDF file format

Those files are used to define, how disasm / asm are supposed to treat
L2's dat files. A DDF file is common for both disasm and asm. Also,
its format is a bit similar to C language.

Double slash denotes comment up to the end of the line. At the top you
can control few of disasm's variables. All these fields are optional.
Their default values are below. Certain literals have numeric value:
NO = 0, YES = 1, OFF = -1. You can use them as well.

FS = "\t";      

FS is a literal string (like in C) used as a field separator. You can
use any string. \t and \" are detected and replaced by tabulation and
doublequote char. L2asm ignores this field and always assumes "\t"
(for now).

RECCNT = OFF;

RECCNT is a variable used to specify numer of the fields. Pretty much
all the files except chargrp.dat include this information. If you
specify it, l2disasm will explicitely read only RECCNT rows and assume
that the usual dword value at the beginning is not there. L2asm will
not write it then.

MTXCNT_OUT = YES;

This boolean variable controls output of counters in MTX pairs. L2asm
silently assumes it to be YES.

MATCNT_OUT = YES;

Similary to above, but for MAT fields. L2asm silently assumes it to be
YES.

ORD_IGNORE = NO;

A variable controlling if output is to ignore ORD property, specified
at the fields. L2asm always ignore ORD properties.

HEADER = YES;

For l2disasm - controls if the first row is to be the line with tag
names. For l2asm - if to skip this line. -q command line option always
override this variable (check section #1).

Now, the main body of the file looks like (fictional file) this:

{
        UINT ID;
        UINT val1;
        UINT val_enb;
        UINT cnt;
        ASCF str1;
                ORD = 1;
        UINT val2[10];
                SKIPIF = [(1, 3), (4 .. 8, -4 .. -2)];
        ASCF str2;
        ASCF str3;
	CNTR cntc;
	UINT tabc[cntc];
        CHAR c;
        UINT val3[val1];
                SOFT = 4;
        MTX tab[cnt];
                SOFT = 4;
                SOFTM = 2;
                SOFTT = 3;
                ENBBY = [(val_enb,1)];
                
}

Each field consists of the type and ident. Ident must start with a
non-number. Then it can consists of anything except whitspace, '[', ']',
and ';', Type must be one of the following (in round brackets - C's
counterparts): UINT (uint32_t), INT (int32_t), UCHAR (uint8_t), CHAR
(int8_t), HEX (uint32_t printed as hex), CHEX  (uint8_t printed as
hex), FLOAT (float), UNICODE, ASCF, MAT, MTX, CNTR.

ASCF is specific half-ascii/half-unicode format used commonly in dat
files. UNICODE is just a plain unicode with int size in front of the
string. Both of them are written as a plain, cultural ascii strings
by l2disasm. See section #2 for more info about character conversions.

CNTR is a special 1-3 bytes "packed" counter (similar counter is used by
ASCF internally).

The other fields can be described as (as you can see, you can easily
emulate MTX, but not MAT):

MTX {
        INT cntm;
        UNICODE mesh[cntm];
        INT cntt;
        UNICODE mesh[cntt];
}

MAT {
        INT cnt;
        {
                INT id;
                INT val;
        } mats[cnt];
}

Square brackets denote a table - its counter can be controlled by a
direct number (we'll call it a static table), or by the name of some
other field (we'll call it a dynamic table). In the latter case, the
field must be of numeric type.

Every field can also have certain properties:

ENBBY controls what other fields "enable" this one. This is primarily
a feature for weapongrp.dat - that has more fields for 2H weapons. In
the example above, MTX dynamic table 'tab' will be read from the dat
file only, if previously read val_enb field has a value of 1.

ORD controls order. ORD == OFF makes the l2disasm not output the whole
column at all. Any other integer sets the relative order. The remaining
fields are written in the default order at the end. In the example
above the first field will be ASCF str1. The rest will come after in
their default order. Mentioned earlier ORD_IGNORE variable can disable
the custom order globally. L2asm ignores both order properties and
global variable.

SOFT, SOFTM, SOFTT - are properties that control, how many columns are
to be printed, when a dynamic table is used. SOFT is for regular field
like UINT val3[val1] in the example above. SOFTM and SOFTT control the
internals of MTX (respectively UNICODE mesh[cntm] and UNICODE
tex[cntt] in MTX pseudo-struct). SOFTM also controls MAT
( {...} mats[cnt] in MAT pseudo-struct). L2disasm updates the fields
in the first pass, if they are not specified, or are too low. L2asm
REQUIRES these properties to be set on all MTX, MAT and dynamic
table fields. For easy generating DDF files for l2asm - please
use l2disasm's -e option.

SKIPIF

Looking at the example above:

        UINT val2[10];
                SKIPIF = [(1, 3), (4 .. 8, -4 .. -2)];

val2's certain columns will be not printed. Those will be:

val2[1] if it equals 3
val2[4] to val[8] if current column's value is in [-4 .. -2] inclusive.

You can use float ranges for float fields, and integer ranges for integer-like
fields. Specifying one number is like specifing the range 'number .. number'.
Don't forget spaces around '..' (or range will be mistaken for invalid float
number).

--------------------------------------------------------------------------
2) Character conversions

Why is my file different after conversions dat->text and text->dat ? T_T

Few reasons:

- all ASCF unicode strings are written back as ASCF ascii

- certain unicode characters might be replaced by their proper ascii code
  (http://www.unicode.org/charts/symbols.html#CombiningDiacriticalMarks)

- remaining "unknown" unicode characters (both ASCF and UNICODE) are 
  replaced by '-', and reported by l2disasm

- for dat->text, all CRs NLs and tabulations are replaced by AB, AC and BB.
  They are changed back to their real values during text->dat. It shouldn't be
  worrying though - the only file explicitely using 0x0A / 0x0A is eula-e.dat
  and classinfo-e.dat. I have yet to see any file using tabulations.

- float conversions may by "minimally" different (please read about machine
  representation of float numbers and don't ask me why)

--------------------------------------------------------------------------
3) Invoking 

l2disam <-d ddf_file> [-q] [-e export] input_file output_file

-d is mandatory, and so are input and output files

-e is optional, and outputs beautified ddf file with automatically
updated options (particualry useful for SOFT* options for l2asm).

-q overrides HEADER variable, and surpresses printing header line


l2sam <-d ddf_file> [-q] input_file output_file

-q overrides HEADER variable - l2asm will assume header line is not
present
