Mdl-file format The Flight Simulator FS95/98 Model File Format MDL
The MDL file format seem to follow some parts of the BGL-file format. This is
not very surprising. The same flight simulator program is using them. I have
tried to describe the records that I found in mdl-files, using the same naming convention that I have found in notes on the BGL-file format. I have not copied information but confirmed the records before adding them to my file.
STATIC RECORDS IN SCENERY DESCRIPTION LANGUAGE
0Fh MoveToPoint(4 bytes)
10h LineToPoint(4 bytes)
18h Texture(24 bytes)
1Ah DefPoints(6 bytes + 6*NumOfPoints)
20h TexturePolygon (14 bytes + 6*NumOfVertices)
22h Return(2 bytes)
23h SDLCall(4 bytes)
24h JumpOnVar(10 bytes)
25h JumpOnVect(14 bytes)
29h DefVectPoints(6 bytes + 12*NumOfPoints)
2Ah GradPolygon(14 bytes + 2*NumOfPoints)
38h Concave(2 bytes)
39h TestVar(8bytes) ????
3Eh Polygon(14 bytes + 2*NumOfVertices)
50h GradColor(4 bytes)
51h LineColor(4 bytes)
52h SurfColor(4 bytes)
7Ah TexturedPolygon7A(14 bytes + 6*NumOfPoints)
THE MDL-file format : Overview
When creating a aircraft in Flight Shop, at least three different types of objects can be used: parts, structures and components. When found in the binary mdl-file format they have of course change form a bit. But the part and structure still use different type of records. All objects are built in a fashion very well known to 3d graphics. The object record start with a list of points or vertices, each with 3 coordinates, for x, y and z component of the vertex. Then follow a list of polygons used to build that object, each polygon consist of 3 or more vertices refereed to in the polygon list with the number of vertex.
This is a example of triangle in this form:
Points:
-15, 0, 0
0,15,0
15,0,0
Polygon
1,2,3
There are quit a lot of help function that go into each object, vector lists for point and polygon to keep track of how they are facing. Offset pointer to the next object or the next variant of the current object, in case anything would read to false before the drawing process. Color or bitmap instruction, instruction if the object is always visible or if it has some special function. Example of such special objects are retractable landinggear, rotating propeller e t c.
----
Object records
These are the main types:
record starting with 1A-pointrecord. Part, always visible
record starting with 24-visibility check. Part, special view effect
record starting with29-pointrecord. Structure, always visible
record starting with 39-record. Structure, with view check.
Part always
is built of following components
1A DefPoints
52 Color
38,3E Polygon
Example of a part record
record start at
DefPoints(1A) - 7137
SurfColor(52) - 7167
Concave(38) - 7171
Polygon(3E) - 7173
Concave(38) - 7195
Polygon(3E) - 7197
Return 7219
Part with special view effect
24 JumpOnVar, give the condition under which this part can be seen.
1A DefPoints, a list of x,y,z coordinates for the points making this part
52 Color , surface color
38,3E Polygon, one or more polygon records.
22 Return
Example of a complete part record
record starting at
JumpOnVar(24) - 7221
DefPoints(1A) - 7235
SurfColor(52) - 7265
Concave(38) - 7269
Polygon(3E) - 7271
Concave(38) - 7293
Polygon(3E) - 7295
Return 7317
Structure, always visible
is built of following components
29 DefVectPoints, the list of x,y,z coordinates for all points in the structure.
39 TestVar 8 byte long record
18 Bitmap, record that tell which .nAF file that will paint the following 7A-pologons.
50 GradColor, the base-color that will be used by the 7A-polygon.
7A TexturedPolygon, repeated several times. Each define one polygon.
22 Return statement end the list of 7A-records.
50 GradColor, give the color for the following 2A-polygons.
2A GradPolygon, repeated several times. Each define one polygon.
Example of a complete structure record
record starting at
DefVecPoints(29) - 10005
TestVar(39) - 10203
Texture(18) - 10211
GradColor(50) - 10235
TexturedPolygon7A 10239
TexturedPolygon7A 10277
TexturedPolygon7A 10309
TexturedPolygon7A 10347
TexturedPolygon7A 10379
TexturedPolygon7A 10417
TexturedPolygon7A 10455
TexturedPolygon7A 10493
TexturedPolygon7A 10531
TexturedPolygon7A 10569
TexturedPolygon7A 10607
TexturedPolygon7A 10645
TexturedPolygon7A 10683
TexturedPolygon7A 10721
TexturedPolygon7A 10753
TexturedPolygon7A 10791
Return 10823
GradColor(50) - 10825
GradPolygon(2A) - 10829
GradPolygon(2A) - 10851
GradPolygon(2A) - 10871
GradPolygon(2A) - 10893
GradPolygon(2A) - 10913
GradPolygon(2A) - 10935
GradPolygon(2A) - 10957
GradPolygon(2A) - 10979
GradPolygon(2A) - 11001
GradPolygon(2A) - 11023
GradPolygon(2A) - 11045
GradPolygon(2A) - 11067
GradPolygon(2A) - 11089
GradPolygon(2A) - 11111
GradPolygon(2A) - 11131
GradPolygon(2A) - 11153
Return - 11173
Structure with a preceding 39h-record
seen when a structure has a special view condition
39 Test
29 DefVectPoints
(39,48,18 Bitmap)
(7A TexturedPolygon)
50 GradColor
2A GradPolygon
Example:
| Record | Start at | |
| TestVar(39) | 7999 | Start of a complex object |
| DefVecPoints(29) | 8007 | List of points |
| GradColor(50) | 8109 | Color |
| GradPolygon(2A) | 8113 | Polygon |
| GradPolygon(2A) | 8135 | |
| GradPolygon(2A) | 8157 | |
| GradPolygon(2A) | 8179 | |
| Return | 8201 |
RECORD DESCRIPTION
I will try to describe the different BGL-records that is used in a MDL-file. The format is: 1st column the offset within the record, 2nd column the length of each field, 3rd column a description of the field.
--0Fh---- MoveToPoint(4 bytes)
| 2 | 2 | point no |
Start of a line drawing routine. It is followed by one or more 10h records. Example: f 0 1 0
--10h---- LineToPoint(4 bytes)
| 2 | 2 | point no |
f 0 1 0 10 0 2 0 10 0 3 0 10 0 4 0 10 0 5 0 10 0 6 0 10 0 7 0 10 0 8 0 10 0 9 0 10 0 a 0 10 0 b 0 10 0 c 0 10 0 1 0 22 0
--18h---- Texture(24 bytes)
| 2 | 8 | always 00h |
| 10 | 8 | texture file name(often the same as the mdl-file) |
| 18 | 4 | texture file extension (.nAF) |
Example: 18 0 0 0 0 0 0 0 0 0 43 68 65 72 6f 31 34 30 2e 33 41 46 0 0
where: 43 68 65 72 6f 31 34 30 2e 33 41 46 = Chero140.3AF
--1Ah---- DefPoints(6 bytes + 6*NumOfPoints)
| 2 | 2 | first point number |
| 4 | 2 | number of points |
then for each point:
| x | 2 | x cord |
| x+2 | 2 | y cord |
| x+4 | 2 | z cord |
Example:
| 1a 0 1 0 4 0 | record 1A, first point no 1, number of points 4. |
| f1 ff a9 0 bd 1 | -15 169 445 coordinate for the first point |
| f1 ff 52 1 b8 0 | -15 338 184 |
| f 0 52 1 b8 0 | 15 338 184 |
| f 0 a9 0 bd 1 | 15 169 445 |
--22h---- Return(2 bytes)
Used to identify the end of one and beginning of a new record. Not used between all the mentioned record. Example: 22 00 29 00 is a signal that a point list is following.
--23h---- SDLCall(4 bytes)
Not yet checked. There are a lot of these records in the beginning of the file, 5000-7000 bytes into the file.
--24h---- JumpOnVar
| 2 | 2 | byte offset |
| 4 | 2 | view effect |
| 6 | different lengths recorded |
Used by parts with special view selections, landinggear, flaps, propeller.
24 0 e 0 52 0 0 0 0 40 d 0 56 0
52 sign, visible when flap down is selected. If flaps not visible, this objects will be invisible, not moved to another position as flaps in real life aircraft.
24 0 70 0 5a 0 0 0 a4 0
24 0 70 0 5a 0 0 0 a4 0
24 0 90 0 5a 0 a4 0 ff 7f
The sign 24 00, is followed by a offset that point to the next object, byte 3 and 4. 5a sign, tell that this is a propeller or more correct that the visual condition is set by the RPM factor. If rpm is below a certain level, set at design time, the two first parts will be true (shown). They are propellerblade that will be visible when the prop not is rotating. If rpm is above level, then record number three will be true. This is a line that represent the perimeter of rotating disk.
--25h---- JumpOnVect(14 bytes)
| 2 | 2 | offset |
| 4 | 2 | vector x component |
| 6 | 2 | vector y component |
| 8 | 2 | vector z component |
| 10 | 4 | distance from the ref point |
A type of record that is use in the table. Not ready for description yet.
--29h---- DefVectPoints(6 bytes + 12*NumOfPoints)
| 2 | 2 | first point number(=1) |
| 4 | 2 | number of points |
Then, for each point:
| x | 2 | x cord |
| x+2 | 2 | y cord |
| x+4 | 2 | z cord |
| x+6 | 2 | x vect |
| x+8 | 2 | y vect |
| x+10 | 2 | z vect |
Example:
| 29 0 1 0 8 0 | This line tell that it will be 8 points in the list |
| f 0 3d 3 6c f7 ff 3f ff 3f 0 0 | 15 829 -2196 16383 16383 0 |
| f 0 3d 3 4d f7 ff 3f ff 3f 0 0 | 15 829 -2227 16383 16383 0 |
| f1 ff 3d 3 4d f7 1 c0 ff 3f 0 0 | -15 829 -2227 -16383 16383 0 |
| f1 ff 3d 3 6c f7 1 c0 ff 3f 0 0 | -15 829 -2196 -16383 16383 0 |
| f1 ff 1f 3 4d f7 1 c0 1 c0 0 0 | -15 799 -2227 -16383 -16383 0 |
| f1 ff 1f 3 6c f7 1 c0 1 c0 0 0 | -15 799 -2196 -16383 -16383 0 |
| f 0 1f 3 4d f7 ff 3f 1 c0 0 0 | 15 799 -2227 16383 -16383 0 |
| f 0 1f 3 6c f7 ff 3f 1 c0 0 0 | 15 799 -2196 16383 -16383 0 |
--2Ah---- GradPolygon(14 bytes + 2*NumOfPoints)
| 2 | 2 | number of vertices |
| 4 | 2 | vector x cord |
| 6 | 2 | vector y cord |
| 8 | 2 | vector z cord |
| 10 | 2 | ??? |
followed by list of point numbers, points have been created by a 1A or 29 record.
| 2a 00 04 00 | Polygon with 4 points |
| 01 80 00 00 00 00 | Vector x, y z 32769,0,0 |
| f1 7f 07 00 | Unknown |
| 04 00 03 00 05 00 06 00 | Polygon drawn between points 4,3,5,6 |
--38h---- Concave(2 bytes)
Always used combined with 3Eh. This is used before the 3Eh record
--39h---- TestVar(8bytes)
Used by structures with special view conditions.
| 2 | 2 | byte offset |
| 4 | 2 | view effect |
| 6 | 2 | unknown |
Two type have been seen. The first type precede the 29h point record, for structures. They contain a offset record, byte 3 and 4 which point to the next object (ca 00) followed by a visibility test, in this case 5e 00, which in this case read to: visible if light is on.
39 0 ca 0 5e 0 1 0
The second type is followed by a bitmap statement (18). The offset record point past the 7A-polygon structure, to the 50-color record preceding the 2A-polygon structure. It can be seen that this contain a record 48h 00h which may be used to determine the size of the bitmap 256x256 (ff ff). I have not found bitmap-record of this type with a visibility-check.
| 2 | 2 | byte offset |
| 4 | 2 | bitmap size record |
| 6 | 2 | bitmap x size, bitmap y size |
Example: 39 0 56 2 48 0 ff ff
--3Eh---- Polygon(14 bytes + 2*NumOfVertices)
| 2 | 2 | number of vertices |
| 4 | 2 | vector x cord |
| 6 | 2 | vector y cord |
| 8 | 2 | vector z cord |
| 10 | 4 | ??? |
followed by list of point numbers, points have been created by a 1A or 29 record. Example:
| 38 0 3e 0 4 0 | Polygon with 4 corners |
| ff 7f 0 0 0 0 | Vector for the polygon |
| 0 0 0 0 | Unknown |
| 1 0 2 0 3 0 4 0 | The polygon |
--50h---- GradColor(4 bytes)
--51h---- LineColor(4 bytes)
--52h---- SurfColor(4 bytes)
| 2 | 1 | color |
| 3 | 1 | F0h |
50 00 0 4 f0 polygon 4=white
--7Ah---- TexturedPolygon7A(14 bytes + 6*NumOfPoints)
| 2 | 2 | number of vertices |
| 4 | 2 | vector x cord |
| 6 | 2 | vector y cord |
| 8 | 2 | vector z cord |
| 10 | 2 | ??? |
| x | 2 | point no |
| x+2 | 2 | texture x cord(0-256) |
| x+4 | 2 | texture y cord(0-256) |
| 7a 0 3 0 | this is a triangle |
| 0 0 d6 80 93 e | vector for the polygon |
| d1 5d 48 ff | unknown |
| 1 0 80 0 7f 0 | point 1, bitmap |
| 4 0 75 0 2b 0 | point 4, bitmap |
| 5 0 8a 0 2b 0 | point 5, bitmap |
Values for the 24h record, offset 5: visibility
| Fs 95 | Fs98 | |
| Flaps | 52 | 6c |
| Propeller(rpm) | 5a | 74 |
| Landinggear | 54 | |
| Strobe, on | 5e | 78 |
| Spoiler | 62 |
Color values 50h-52h record, offset 2, examples:
2 gray, 4 white, 5 red, 9 yellow, 29 red, light, 2a green, light
These records give a visual model of the aircraft. There are more records that could be of interest. There is noting very interesting in the first 5135 byte (in Fs95), they are identical from file to file. Then byte 5000 - 7000 are worth having a look at, when the file sets record of objects, parts and structures. There might be something useful in this area, but I have left this unattended. Then from byte 7000 and until the EOF are part and structures. This is the part that I try to cover in my description.
Malmberget, Sweden, October 6, 1999
Henry Väppling
henry.veppling@swipnet.se
http://home5.swipnet.se/~w-50954/hv/