home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Killer
/
Game_Killer.bin
/
709.FSDECODE.TXT
< prev
next >
Wrap
Text File
|
1993-02-04
|
44KB
|
827 lines
FSDECODE
DECODER FOR MICROSOFT FLIGHT SIMULATOR
DATA FILES
Version Beta 2; Release date: 4 February 1993
Updates:
∙ Link table increased to 240 entries
∙ Added the scale factor in register 'S'
∙ Added ASCII text to dump fields
∙ Added quotes (") to dump and string fields
∙ Added the undefined record procedure
∙ Added the absolute and relative link directives (#@, #$)
∙ Added the "mark routine" and the "call marked" directives (#M, #N)
∙ Updated SD-DEF.DES
∙ Added SCN.DES
∙ Documented the #S directive and the ERRORLEVEL return codes.
Version Beta 1; Release date: 8 December 1992
-----------
FSDECODE REFERENCE
-----------
WHAT FSDECODE DOES
FSDECODE reads a Flight Simulator data file (.SC1, .SCN, .DY1, .DYN, .DEM,
.MOD...), chops it in fields each containing a single value and outputs a field
contents description to an ASCII text file. To do that, FSDECODE, which has
almost no specific knowlegde about FS data file structures, uses a description
file (thereafter called ".DES file") which tells the program how long each data
field is, what it contains and how it has to be formatted in the output. By
default, FSDECODE selects a description file according to the input file exten-
sion, but a specific description file can be indicated.
HOW INSTALL FSDECODE
Copy the program file (FSDECODE.EXE) and all the .DES files to the same
directory. This directory can be the Flight Simulator directory or a different
one.
HOW TO RUN FSDECODE
The syntax for FSDECODE command line is:
FSDECODE InputFileName OutpuFileName [/FfromOffset] [/TtoOffset]
[/DdescrFileName] [/WoutputWidth] [/U] [/X[o][x][t]]
where:
<InputFileName> is the name of the data file to be read
<OutputFIleName> is the name of the ASCII file to be created.
These 2 arguments are required.
<fromOffset> is the input file offset from where to start (either a decimal or
an hex number; the latter in the format 0x.... es.: 1024 = 0x400)
<toOffset> is the input file offset at where to stop (either a decimal or an
hex number)
<descrFileName> is the name of the description file to use
<outputWidth> is the maximum line width for the output file
/U forces the program to unconditionally scan the input file from <fromOffset>
and not from the beginning
/Xo or /Xx or /Xt exclude one of the three output columns (offset, hex and
text, see below); they can be combined up to /Xoxt
These 6 arguments are optional, and can appear in any order but AFTER the two
file names.
Defaults:
<fromOffset> defaults to 0
<toOffset> defaults to the file end
<descrFileName> defaults to a file name equal to the input file extension, and
a .DES extension
<outputWidth> defaults to 132, legal values are in the range 80-197; values
lower than 80 are converted to 80 and values greater than 197 are converted
to 197.
If a fromOffset parameter greater than 0 is given, the input file is scanned
from the beginning to set possible link points and to follow the record struc-
ture (see below), however no output is generated until the <fromOffset> point
is reached; when the <toOffset> point is reached, the program ends.
If, however, the /U option is used, scanning begins directly from
<fromOffset>; this can exclude some of the cross-check possibilities and has to
be used only when the user is sure that <fromOffset> is exactly the initial
point of a record.
If <toOffset> is equal to or lower than <fromOffset>, the program ends with
an error message.
All file names can include a full drive:\path\ indication.
The description file (both default or given by the user) is looked for in the
current directory; if it is not found, it is looked for in the directory where
FSDECODE itself resides. This permits to automatically use, for each input
file kind, specialized .DES files for data files in different directories,
resorting to a generic .DES file for that type if none is found.
If no suitable .DES file is found, the program aborts with an error message.
During the run, FSDECODE displays the current input file offset and, at the
end, the offset of the last accessed field and record; these are not neces-
sarily the last DECODED field or record, if they fall beyond the <toOfset>
limit.
By pressing the ESC key while the program is running, the user can interrupt
the program at any moment.
ERRORLEVEL RETURN CODE
If run in a batch file, FSDECODE returns the following ERRORLEVEL codes:
0 success
1 invalid or missing parameter(s)
2 I/O error
3 other errors (out of memory, description file syntax...)
MEMORY CONSIDERATION
The input file is read a field at a time, and then input file size is not an
issue. The description file, however, is kept in memory in its entirety and
cannot be longer than ca. 53 kB. If there is not enough memory to hold the des-
cription file, the program aborts with an error message.
Given that FSDECODE uses the small memory model, the program can run in about
100 kB of memory, but there is nothing you can do if you hit the small memory
limit other than trying to simplify the description file, no matter how many MB
of extended/expanded memory you have.
Each description file line takes 7+strlen(caption) bytes of memory.
OUTPUT FILE LAYOUT
Output files are organized in three columns:
1) at the left margin, the current file offset as a 6-digit hex number
2) at position 8, hex dump of the field values (hex column)
3) at position 62, field descriptions and values (text column)
If any column is excluded with /X option, the column at its right takes over
its width.
Many fields can fit in a line and is the description file which tells
FSDECODE when to start a new output line. One blank space is automatically
inserted before any hex dump and field description.
If the hex dump or the field description do not fit in the remaining portion
of their columns, a new output line is generated; if they are longer than the
corresponding column width, they are truncated.
Hex dumps are always in hex, but all the digits of a field are given in the
'right' order (MSB first) and not in the Intel format (LSB first) actually used
in the files. Some kinds of field (primarily geographic coordinates) generate a
formatted hex dump (see below for details). Field description format is almost
entirely dictated by the description file.
When the decoding is over, a record count list is appended, detailing the
occurrences of each record found at least once in the input file and the total
occurrences of undefined records.
NOTE: please be aware that output files generated by FSDECODE can be HUGE, a
reasonable guess being about 20 times the length of the input file.
------------
LINK POINTS AND REGISTERS
------------
LINK POINTS
The program maintains a table of up to 64 link points. Link points are set
by specific instructions in .DES files. If the program is unable to correctly
parse a point of the input file, it dumps an unformatted hex listing up to next
link point. If the next link point is more than 2 kB after the current point,
FSDECODE assumes to have lost syncronism with the input file, dumps 1024 bytes
in hex and aborts.
The link table is updated (and elapsed link points are removed) every time a
link is inserted and at each new record.
REGISTERS
The program maintains a set of 27 registers. Registers can be set and
checked with appropriate directives; checks can trigger jump to other descrip-
tion lines. All registers are signed long values (32 bits) and all register
assignments are casted to (signed long).
Registers are addressed with a single character name from '@' to 'Z'.
The following registers are somewhat special:
'@': this is actually a sort of pseudo-register; when read, it yields the next
link value, when set it inserts the given value into the link table; as the
link table is kept in ascending order, a new value can occupy any position
and is not necessarily the value returned when the register is read back.
'Q': holds the file offset of the record being decoded and is internally used
to compute relative offset addresses (see below); it can be read and writ-
ten, but it is overwritten every time the program enters a new record.
'R': holds the code of the current record; it can be read and written, but it
is overwritten every time the program enters a new record.
'S': holds the current scale factor for FS delta coordinates and is internally
used to convert delta coordinates to actual FS coordinates. It is not set
by the program, but it is left to the user to be sure that the .DES file
sets it when required.
'V': holds the current field value; it can be read and written, but it is over-
written every time a new field is read. If the current field is shorter
than 32 bits, the value is 0-extended for unsigned fields and sign-extended
for signed fields. Strings and hex dump fields do not affect this register.
'W': holds the file offset of the current field; it can be read and written,
but it is overwritten at each .DES line execution.
Registers X, Y, Z are not reserved by the program, but are consistently used
in the supplied .DES files to store the current East, North, Alt. coordinates
of the current object or plane position. It is recommended that this practice
will be observed.
Other registers can be freely read and set with .DES instructions.
------------
DESCRIPTION FILE REFERENCE
------------
GENERAL STRUCTURE
Description files are ASCII text files which tell FSDECODE how to interpret
the input file and how to format the output. .DES files are made of lines,
each describing a field (i.e. a single value).
.DES lines are made of three columns:
1) a number: the length in bytes of the field
2) one or two characters: field value type and optional command
3) caption (a text string, optional): what to print before and/or after the
field value output.
Columns can be separed by any combination of blanks (spaces and/or tabs) and
do not need to be actually drawn up in column. However, the first column MUST
begin at the first line character and the caption column CANNOT contain blanks
(but see below).
Line length is limited to a maximum of 197 characters.
For example, the follwing .DES line:
2 I file_length:_
tells FSDECODE that the next field is 2 bytes long, its value has to be
printed as an I(nteger) number and the string "file length: " has to be
prepended at the field value (underscore characters will be replaced by
spaces).
Given that many FS data files (as, for instance, .SC1, .DY1, .DEM) are made
of records, each characterized by an initial byte code and each with its own
structure and meaning, FSDECODE description files are also built around the
record concept:
a record line states for which record code the following description is
intended, and subsequent lines describes the various record fields.
Lines pertaining to the many fields of a record have to appear in the same
order in which the fields appear in the record, one for each field, but des-
criptions for the different record codes can appear in any order within the
description file; however it is recommended to keep them sorted by record code.
If some lines appear in the description file before the first record line,
they are intended to describe a file header and are executed to decode the
input file initial portion, until the first record line is met.
See also section "NOTES" for details on record selection.
COMMENTS
Lines starting with a semicolon (;) are considered comment lines and are
entirely disregarded.
Any text after the caption, separated by at least one blank, is considered a
comment and is entirely disregarded.
Comments do not occupy memory.
FIELD CAPTIONS
The caption contains a descriptive text which is output with the field
value. Within captions, 3 characters have a special meaning:
'#': if a caption starts with a pound sign, a new output line is generated;
otherwise output for the current field will follow output for the previous
field in the same line, if it fits. If the symbol occurs in other positions
it is printed normally (but see below the note about the 'E' field type).
'|': if a pipe symbol appears anywhere in the caption, the field value is
inserted at this point of the caption; if no pipe symbol occur, the caption
is output entirely before the field value.
'_': all undescore symbols are replaced by space characters. Always remember
to add to captions the required leading or trailing underscores to separate
caption text from field value. Captions stop at the first space or tab
character they contain.
FIELD VALUE TYPES
Field value type tells FSDECODE how to interpret the field and how to print
its value in the text column.
As a general rule, upper case types are unsigned, lower case types are
signed; if this distinction does not apply (as for non-numeric fields, like
strings), case makes no difference.
The following table lists the field types supported by FSDECODE Beta 2. For
each type, the supported field lengths, a pattern of hex output and of text
output as well as a description are given.
┌──────┬───┬───────────┬──────────────┬──────────────────────────────┐
│ type │len│ hex dump │ value output │ description │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ B/b │ 1 │ hh │ bbbbbbbb │ binary number │
│ │ 2 │ hhhh │ 2x bbbbbbbb │ │
│ │ 3 │ hhhhhh │ 3x bbbbbbbb │ │
│ │ 4 │ hhhhhhhh │ 4x bbbbbbbb │ │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ C │ 2 │ hhhh │ ddddd │ int. FS coord (-0xC000) │
│ │ 4 │ hhhh.hhhh │ ddddd.dddd │ fract. FS coord (-0xC000) │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ c │ 2 │ hhhh │ +dddddd │ delta FS co., scale factor 8 │
│ │ │ │ +dddd.d │ " , scale factor 6-7 │
│ │ │ │ +ddd.dd │ " , scale factor 2-5 │
│ │ │ │ +d.dddd │ " , scale factor 0-1 │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ D/d │any│ hh hh hh..│ "ASCII text" │ hex dump │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ E/e │1-4│as for b/B │ see below │ enumeration (see below) │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ G │ 1 │ hh │ ddd.dd° │ degrees (0 - 360) │
│ │ 2 │ hhhh │ ddd.dd° │ " │
│ g │ 1 │ hh │ +ddd.dd° │ signed degrees (-180 - +180) │
│ │ 2 │ hhhh │ +ddd.dd° │ " │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ I │ 1 │ hh │ *** │ decimal integer │
│ │ 2 │ hhhh │ *** │ " │
│ │ 4 │ hhhhhhhh │ *** │ " │
│ i │ 1 │ hh │ +*** │ signed decimal integer │
│ │ 2 │ hhhh │ +*** │ " │
│ │ 4 │ hhhhhhhh │ +*** │ " │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ J │ 2 │ hh.hh │ ddd.dd │ decimal with 1 fract. byte │
│ │ 4 │ hhhhhh.hh │ ddddd.dd │ │
│ j │ 2 │ hh.hh │ +ddd.dd │sign. dec. with 1 fract. byte │
│ │ 4 │ hhhhhh.hh │ +ddddd.dd │ │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ K │ 4 │ hhhh.hhhh │ ddddd.dddd │ decimal with 2 fract. bytes │
│ k │ 4 │ hhhh.hhhh │ +ddddd.dddd │sign. dec. with 2 fract. bytes│
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ O/o │1-4│as for b/B │ "off"/"on" │ on / off switch: │
│ │ │ │ │ "off" printed if LSB == 0 │
│ │ │ │ │ "on" otherwise │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ S/s │any│hh hh hh.. │ "ASCII text" │ textual string │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ X/x │ 1 │ hh │ hh │ hex number │
│ │ 2 │ hhhh │ hhhh │ │
│ │ 3 │ hhhhhh │ hhhhhh │ │
│ │ 4 │ hhhhhhhh │ hhhhhhhh │ │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ Y/y │ 2 │ hh.hh │ hh.hh │ hex number with 1 fract. byte│
│ │ 4 │ hhhhhh.hh │ hhhhhh.hh │ │
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ X/x │ 4 │ hhhh.hhhh │ hhhh.hhhh │hex number with 2 fract. bytes│
├──────┼───┼───────────┼──────────────┼──────────────────────────────┤
│ '-' │1-4│as for b/B │ none │ empty value │
├──────┼───┴───────────┴──────────────┴──────────────────────────────┤
│ # │ Command directive; see next section │
└──────┴─────────────────────────────────────────────────────────────┘
Symbols:
'b', 'd', 'h' stand for one binary, decimal or hex digit resp.
'+' stands for a sign character (either '+' or '-')
'***' stands for the amount of decimal digits necessary for expressing the
number (output is left justified; other field outputs are right justified).
Notes:
'C': the field value is corrected by the -0xC000 base shift after hex output.
2-byte 'C' fields are aligned with int FSu decimal point (<< 16) after value
output. These modifications show up in the 'V' register also.
'c': the field value is corrected by the current value of register 'S' (scale
factor) after hex output, so that the field is aligned with int FSu decimal
point and is ready to be added to current reference coordinate to calculate
resulting point. These modifications show up in the 'V' register also.
Text output has a variable number of decimal digits to make it to fit in 7
characters.
'E': enumerations provide a way to convert coded values to text labels. They
are intended for fields that can assume a small number of consecutive
values. For enumerations, the caption column must have a precise structure:
"[pre_label]|text_for_value_0#text_for_value_1#....[|post_label]"
the program prints in the text column the text corresponding to the field
value, with the optional pre_ and post_labels before and after. Note that
the final '|' is required only if the post_label is present, but the first
'|' is ALWAYS required. If the field value is greater than the number of
supplied texts, a 2-digit hex number is printed. Only the LSB of the field
is tested and printed, whatever the declared length of the field.
'G': for degree fields, value output is converted in degrees, calculating
10000h (for 2-byte fields) or 100h (for 1-byte fields) = 360°. This calcula-
tion does not affect the V register which keeps its value. For 1-byte
fields, however, after value output, V is shifted 1 byte to the left to keep
the value aligned with 2-byte fields. Value outputs have a final '°'.
'D': strings are output in text chunks up to 16 bytes long, each surrounded by
a pair of quotes ("); control characters are replaced by the '^' symbol; new
output lines are generated until the field length is exhausted. If the
field length is not known in advance, a length of -1 can be declared and the
file will be hex-dumped up to next link point.
'S': strings are output in text chunks up to 16 bytes long, each surrounded by
a pair of quotes ("); control characters are replaced by the '^' symbol; new
output lines are generated until the field length is exhausted. If the
field length is not known in advance, a length of -1 can be declared and
text will be output up to the next NULL character included.
'-': no value output. Hex dump is generated, but value output is not. Used to
read a field while deferring value output if it requires special manipula-
tions or avoiding it when caption text is enough.
String and hex dump fields can have any length between 1 and 32677. Other
fields can be only 1 to 4 bytes long; if the declared field length is greater,
the program stops with an error during description file check.
If a field length unsupported for that field type is declared, hex output
will be usually correct, but no text output will be generated. No messages are
issued by the program.
FIELD COMMANDS
To the field type character, another character can be added addressing one
of the internal registers. If the character is upper case ('@' or 'A'-'Z') the
corresponding register is set to the current field value; if it is lower case
('$' or 'a'-'z') the current value is added to the register (algebraically
added, if the field was declared as signed). Any other command will be simply
ignored. Commands do not affect hex or text output in any way.
The following commands require some comments:
Link points:
'@': the field value is declared as an absolute link point; the field value
is considered an absolute file offset and inserted into the link point table as
it is.
'$': the field value is declared as a relative link point; the field value
is added to the current record offset and inserted into the link point table.
Record line
'R': declares the line as a record line; for record lines, field length
column does not indicate the length of the field, but the code of the record; a
record code field is always considered 1 byte long. The R register is set to
the field value and the value is output according to the field type. NOTE:
Record codes lesser than -1 or greater than 255 are ignored. See also ".DES
execution flow" in section "NOTES" below.
Undefined record procedure
A record line with a code of -1 marks a special record procedure wich will
be invoked to process undefined records, overriding the default procedure (dump
to next link point) built in the program.
No field loading
'-': outputs the current field value (V register) without loading it from
the file; it is used to output a field value (usually previously read with a '-
' field type) that has been manipulated through directives (see below). Value
is formatted according to field type. No hex output is generated.
COMMAND DIRECTIVES
A line with a '#' field type is not considered a field description but a
directive for the program. Directives tell FSDECODE to perform certain
actions. They permit a rudimentary form of programmed file parsing.
Directives are recognized by the command character. As a general rule,
directive case is irrelevant.
Within directives, field length column and caption column have special mean-
ing.
The following table lists directive supported by FSDECODE Beta 2. For each,
the meanings of various columns and a description are given.
┌─────┬───────────────┬─────────────┬─────────────────────────────────┐
│ dir │ field length │ caption │ description │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #D │ line offset │ arithmetic │ count Down on reg: │
│ │ │ expression │ decrement reg and jump to │
│ │ │ │ [line offset] if reg > value │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #U │ line offset │ arithmetic │ count Up on reg: │
│ │ │ expression │ increment reg and jump to │
│ │ │ │ [line offset] if reg < value │
╞═════╪═══════════════╪═════════════╪═════════════════════════════════╡
│ #I │ line offset │ boolean │ jump If: │
│ │ │ expression │ jump to [line offset] if │
│ │ │ │ [expression] is true │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #J │ line offset │ (standard) │ Jump: │
│ │ │ │ jump to [line offset] │
╞═════╪═══════════════╪═════════════╪═════════════════════════════════╡
│ #C │ line offset │ (standard) │ Call subroutine: │
│ │ │ │ store current description line │
│ │ │ │ and jump to [line offset] │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #E │ (ignored) │ (standard) │ End subroutine: │
│ │ │ │ go back to the calling point │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #M │ line offset │ (standard) │ mark a subroutine for later │
│ │ │ │ execution │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #N │ (ignored) │ (standard) │ call marked subroutine │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #S │ bytes │ (standard) │ skip the given amount of bytes │
│ │ │ │ in the input file │
╞═════╪═══════════════╪═════════════╪═════════════════════════════════╡
│ #R │ (ignored) │ arithmetic │ Register operation │
│ │ │ expression │ │
╞═════╪═══════════════╪═════════════╪═════════════════════════════════╡
│ #F │ (ignored) │ description │ execute description File: │
│ │ │ file name │ load and execute [filename] │
│ │ │ │ (must include path and .ext) │
╞═════╪═══════════════╪═════════════╪═════════════════════════════════╡
│ #H │ (ignored) │ heading │ Heading: │
│ │ │ │ output [heading] at hex column │
│ │ │ │ in a line of its own │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #T │ (ignored) │ text │ Text: │
│ │ │ │ output [text] at value column │
│ │ │ │ (same spec. char. as captions) │
╞═════╪═══════════════╪═════════════╪═════════════════════════════════╡
│ #@ │ line offset │ (ignored) │ link procedure to current value │
│ │ │ │ intended a file offset │
├─────┼───────────────┼─────────────┼─────────────────────────────────┤
│ #$ │ line offset │ (ignored) │ link procedure to current value │
│ │ │ │ intended as an offset from the │
│ │ │ │ current file offset │
└─────┴───────────────┴─────────────┴─────────────────────────────────┘
Notes:
[line offset] is a signed short integer which gives the target line offset
relatively to the current line; comment lines are not counted. Even when the
field is ignored, it MUST contain a number.
Line offsets can be substituted with label references (see below).
[arithmetic expression] is in the form "R?VALUE", where:
∙ 'R' can be any register name ('@'-'Z')
∙ '?' can be any of the following operators: + - * / % & | = which are equi-
valent to the following C operators:
+ +=
- -=
* *=
/ /= (integral division)
% %= (modulus)
& &= (bitwise AND)
| |= (bitwise OR)
= =
The operator is not checked for #D and #U directives, but it MUST be there.
∙ 'VALUE' can be a signed long integer (decimal or "0x...." hex) or a
register name ('@'-'Z').
[boolean expression] is in the form "R?VALUE", where:
∙ 'R' can be any register name ('@'-'Z')
∙ '?' can be any of the following operators: > < = ! (greater than, lesser
than, equal, not equal). Other operators are considered as '!'.
∙ 'VALUE' can be a signed long integer (decimal or "0x...." hex) or a
register name ('@'-'Z').
'#D', '#U': implement a sort of "do...while" counted loop. They are intended
to be used at the end ("while") of repeating part to conditionally branch to
the initial point ("do"). The lines between "do" and "while" are always
executed at least 1 time.
'#C': execution continues with the called subroutine; FSDECODE returns to the
calling point only when an '#E' directive is executed. There is no limit,
memory availability excepted, to multiple subroutine nesting.
'#E': returns execution to the calling point, either from a subroutine or
from a nested .DES file. Upon returning from a nested .DES, memory occupied by
the called .DES is freed and its record definitions are lost. If executed when
no subroutine and no nested .DES is being called, it stops the program.
'M': marks the routine targeted by the line offset (or label reference) for
later execution through the 'N' directive.
'N': calls a routine previously marked by the last 'M' directive. It is a
normal subroutine call, with returns only when an 'E' directive is found. If
no routine has been 'M'arked, the directive is ignored.
The directive pair 'M' - 'N' is used to select among several specific
routines according to contingent conditions and to call the selected routine at
a later point without the need to repeat the tests or keep memory of the
previous conditions.
'#F': execution continues with the given .DES file. The file is looked for
in the current directory and then in the FSDECODE directory, as for any .DES
file; if it is not found, the program aborts with an error. File name cannot
include an underscore character ('_') because it would be replaced by a space.
FSDECODE returns to the calling point and frees the memory occupied by the
called file only when an '#E' directive is executed.
Record definitions and labels are local to the called file and do not inter-
fere with the records and labels defined in the caller.
Registers, undefined record procedure, marked procedure and link point proce-
dures, however, are global and the called file shares the register with the
caller or inherits the procedures if they have been set by the caller.
There is no limit, memory availability excepted, to multiple file nesting.
'#H': generates an output line containing only the given text aligned with
output hex column. Text cannot contain spaces, which can be indicated by the
'_' special character. New line text prefix ('#') and field value place holder
('|') are printed as regular characters. This directive is ignored if text
output has been suppressed with the /Xt option.
This directive is used to insert titles or separators in the output.
'#T': outputs the given text at the current output value position. Text can-
not contain spaces, which can be indicated by the '_' special character. New
line text prefix ('#') is observed and field value place holder ('|') is
printed as a regular characters. This directive is ignored if text output has
been suppressed with the /Xt option.
This directive is used to insert a caption that cannot be easily inserted in
the caption column.
'#@': links the procedure targeted by the line offset (or the label
reference) to the current field value, intended as a file offset; when decoding
arrives at this file offset the procedure is executed. The procedure has to be
closed by an #E directive, as for any subroutine call.
This directive is useful for inserting headings at given file offsets or for
derouting execution during file sections with a particular structure.
'#$': it similar to the previous directive, but the current field value is
considered a delta from the current record offset, i.e.: the current field
value is added to the current record offset, the result is considered a file
offset and is linked to the targeted procedure.
Any other directive will be simply ignored.
Note that directives #C, #E, #J, #M, #N, #S can have a standard caption which
will be output into the text column in the usual way.
Refer to the supplied .DES files and to the "NOTES" section below for exam-
ples and tips of using directives.
LABELS
Lines starting with a colon (':') are considered labels definitions and mark
the following line. Only the first 8 characters (':' excluded) are sig-
nificant; labels are case-sensitive and may contain any caracter from '!'
(ASCII 33) to '■' ('ASCII' 254). Each .DES file can contain up to ca 3,000
different labels.
A label can be referenced in directives, substituting the line offset with
the label preceded by a '>'. Again, see the supplied .DES for examples.
Labels do not count as lines and do not occupy .DES memory.
------------
NOTES
------------
.DES EXECUTION FLOW and RECORD SELECTON MECHANISM
If a .DES file does not contain record lines (like, for instance, MOD.DES),
it is executed linearly from the first line onward, of course taking into
account possible flow control directives like #J, #C, etc, until:
a) the input file is finished OR
b) the .DES file is finished OR
c) a #E directive is met which is not within a subroutine or #F call.
If however it does contain record definitions, its execution is linear until
the first record line is met. At this point, FSDECODE assumes to have entered
an input file section made of records, and the .DES file is no more executed
sequentially but somewhat asynchronously: a record code is read from the input
file and the routine associated with this code is retrieved and executed. If
the code has no associated routine, the undefined record mechanism is trig-
gered.
When the routine is finished (i.e. when FSDECODE arrives at another record
line), another record code is read from the input file and the selection
process is repeated.
In 'C' terms, the record definition block of a .DES file can be described as
a big "switch" within which each record line is a "case" (and at the same time
it "break"s the previous "case") and the undefined record proc (either built-in
or DES-defined) is the "default"; the entire "switch" is enclosed in a
"while(TRUE)" block.
Thee is no way to stop this process and revert to plain sequential execution;
if an input file portion is known to have a non-record structure, its address
(either hard-coded in the .DES or derived from the file contents) can be
inserted in the link point table and associated with an appropriate decoding
subroutine through the #@ or #$ directives: when the decoding arrives at that
file address, the associated routine will be triggered and the special section
properly decoded. After that, upon returning from the subroutine, the asyn-
chronous record selection process resumes.
Note that a .DES containing record definitions will never stop or, if called
from antother .DES, will never return to the caller, until one the following
condition is satisfied:
a) the input file is finished
c) one of record definition, thought to mark the end of the file, purposely
contains an '#E', in which case execution of the .DES will stop after the first
occurrence of this record in the input file.
Condition b) (end of .DES) is no more possible, because record selection is
repeated until there are records to decode.
NOTE ON THE '#E' DIRECTIVE AND CALLS
.DES files that do not contain record definitions can, or even should, safely
end with an '#E' directive. If the file is called from another .DES with the
'#F' directive, execution will return to the caller when the '#E' directive is
reached; if there is no '#E', FSDECODE cannot anymore tell how to parse the
file and usually aborts with an error.
.DES files that contain record definitions, however, cannot simply end with
an '#E', because it will necessarily appear at the end of record definition and
will cause FSDECODE to stop whenever a record of that kind is parsed. The same
apply to the code of a subroutine: if it follows a record definition, it will
be executed whenever a record of that kind is parsed. The solution is to group
all subroutines, each terminated by its own '#E', at the beginning of the file
and to add before them a #J directive jumping over all of them.
'-' NULL FIELD TYPE AND '-' NULL FIELD COMMAND
It is important to distinguish between these two instructions:
'-c' (where 'c' can be any field command, even empty) reads a field (of given
length) and outputs its hex value but does not perform any text output. The
field value is stored in the 'V' register, as with any field read-in. It prac-
tically tells FSDECODE that there is no need for a value output because the
caption is enough or that there is no simple way to output the field value and
that the next .DES instructions will take care of it. It can be associated
with any field command.
't-' (where 't' can be any field type) does not read anything from the input
file nor output any hex value, but outputs in the text column whatever value
happens to be in the 'V' register, formatted according to the accompanying
field length and type. Practically, it tells FSDECODE that a suitable field
value has been built in the 'V' register and that it can output this value in a
standard format. It can be associated with any field type but there has to be
one, because the field command is always the second character.
It is also important to properly pair, when required, the null field type and
the null field command, each in its .DES line, avoiding having two read-in for
a single field (which would put the .DES out of synchronism with the input
file) or no read-in at all. Even more care has to be put when one of the two
instructions is a sub-routine; for example:
a) when an instruction reads a field with the null field type and then calls
a sub-routine, practically 'passing' to it the value in the 'V' register, the
called sub-routine must not read the field again;
b) when a sub-routine is supposed to read the fields it works on, the caller
must not read them in advance.
The most delicate points are sub-routines which can be executed asynchron-
ously, like the undefined record procedure, procedures associated with link
points and any 'marked' procedure: the .DES programmer has to be sure that
these sub-routines will be executed with the right alignment with the input
file.
------------
FILE LIST
------------
The package contains the following files:
FSDECODE.EXE the program
FSDECODE.TXT this documentation file
Sample .DES files:
DEM.DES for .DEM files
DY1.DES for .DY1 files
MOD.DES for .MOD files
SC1.DES for .SC1 files
SC-DEF.DES for the default scenery F1 or other sceneries with the same
structure (as Mallard's *.SCN)
SCN.DES tentative .DES file for alternate sceneries (subLogic's *.SCN)
STATRECS.DES .DES containing static scenery record definitions, used by
SC1.DES, SC-DEF.DES and SCN.DES and callable by any .DES dealing
with static scenery.
Notes on supplied .DES:
SCN.DEF: scenery sections of *.SCN files are not contiguous but, when a sec-
tion ends, the file is padded to the next kilobyte boundary, where the next
section begins; also, at sector 116 (offset 59,392) there is a special section
containing some of the items found in the header of F1. While the supplied
SCN.DES makes no attempt to deal properly with this special section, it tries
to reduce the problems posed by the padding garbage with a custom undefined
record procedure, which outputs an hex dump up to the next kB boundary and then
resume record decoding. This way, assuming that all real record types are
properly defined, no significant portion is lost, but the initial part of each
pad can be misleadingly decoded as scenery records, if it happens to follow the
structure of some of the known records; therefore, records before the message
"Undefined record, dumping to next kB boundary" back to the last END (79h) or
RET (19h) record have to be discarded, potentially.
STATRECS.DES: this .DES includes all records of which I know at least the
length. Some records (like the runway record, 50h) have a simplified descrip-
tion and no attempt as been made to analyze building records (code 53h); only
some FS variables are converted to plain labels. Detailed description of all
known records can be found in the file FSSTRUCT.TXT, available on request.
------------
COPYRIGHT NOTICE AND DISCLAIMER
------------
FSDECODE is distributed to encourage research and knowledge acquisition on
the Flight Simulator environment. It is intended as KnowledgeWare: it is free,
but anyone is invited to let me know discoveries obtained with it. I
explicitly renounce to any copyright I may have on it.
The FS4/ASD community as a whole has spent way too much time decoding this
information in order to generate useful utilities. It would be nice if the
original authors chose to publish an "official" documentation of FS data files.
However, FSDECODE is not distributed with an eye towards enabling anyone to rob
the original authors of any rightful profits and should be used only for the
common good of the FS4 community and to encourage availability and sales of FS4
and related products and utilities.
Flight Simulator is a registered trademark of SubLOGIC Corp.
Microsoft Flight Simulator is copyright of Microsoft Corp. and Bruce A.
Artwick.
Aircraft and Scenery Designer is copyright of Microsoft Corp. and The Bruce
Artwick Organization.
FSDECODE has been realized by:
Maurizio M. Gavioli - BoGaRT sas.
via Mino 1
50122 FIRENZE
ITALY
CompuServe: 100021,2335
InterNet: "Maurizio M. Gavioli" <VINCIGLI@idg.fi.cnr.it>
Last, but not least: I want to thank Dan Samuel, Andrew Tuline and Steve Tur-
ley for their suggestions and friendly support.