Hex Editing

"Cracking the Code!"

The FSDS-generated object source code file (.sca) contains only the SCASM code needed to render the physical model. It does not contain the code for stock animation or keyframe animation. The only way to create animated parts using the object source code is to use a good hex editor and transfer the animation code in the MDL file back into the SCASM language of the SCA file.

The first time you open a MDL or BGL file with a hex editor, the screen will seem like a daunting array of random numbers. Don't let it overwhelm you. It isn't difficult to get around in this code when you know what you're looking for and what you're looking at.

Where to Begin

A simple model was built to test and verify the process of transferring animation code from a model file (fxtailhook.mdl) to an object source code file (fxtailhook.sca). The model, built with FSDS Pro v2.20, contains only two parts ... a rectangular box representing the fuselage and an animated tailhook.


TailHook Retracted


TailHook Extended

The tailhook animation was extracted from the MDL file using a hex editor and coded into the SCA file. The edited SCA file was then compiled with SCASM and the resulting BGL code was copied and pasted back into the MDL file. When the model was flown in CFS2, the tailhook worked exactly as it did in the original FSDS-generated model!

Using this process, you can add bullet holes and texture swapping to your model and keep all the work you put into creating the many stock/keyframe animations in your model.

NOTE
Before you start changing things, make copies of your original FSDS-generated MDL file and SCA file. Save these files in the same folders as the originals and add the text 'ORG" to the end of the filename, e.g. "myairplaneORG.mdl" and "myairplaneORG.sca." This way, if something gets screwed up, you can always recover your original files.

The BGL code of your FSDS-generated MDL File starts with the ASCII text "BGL ."

Load your MDL file in your hex editor and search for the ASCII text BGL, which marks the beginning of the model's BGL code.

Next, search for the hex value BD00, which is the SCASM opcode for "EndVersion." This opcode is used only once in the entire MDL file and appears near the top of the BGL code.

Now, load your SCA file in your text editor. Scroll down to the line

";Draw Main Model"
which is the first line of text after the end of the VertexList ( ... ) command. This is the beginning of the SCASM code that renders your model.

Finally, open the SCASMOpCodes reference file, which is your key to interpreting the hex code in the MDL file.

Your task is to map every hex word in the MDL file to its corresponding SCASM command in the SCA file. Use the SCA file as your roadmap and the SCASM OpCodes page as a list of road signs.

There are a lot of hex words in the model file, particularly in a complex model, but he process is very straightforward and with a little patience and perseverance you'll get through it just fine.

Fortunately, much of the SCASM code in a MDL file is redundant. A small group of commands appear frequently and you'll soon get to where you can spot them quickly.

NOTE
"Bits, Bytes and Words"
4 bits = 1 nibble = A single character ... "F"
8 bits = 1 byte = A pair of characters ... "FF"
16 bits = 1 hex word = A pair of bytes ... "FFFF"
32 bits = 1 double hex word = Two pairs of bytes ... "FFFF FFFF"

When reading hex codes from the MDL file, you won't see any labelnames. They exist only for your benefit to help you read the SCA file. When the model file is generated, lablenames exist only as hex offsets to the next piece of code referred to by the labelname.

To help in this process, I strongly recommend that you add a remarks tag to each SCASM command line in your SCA file that contains the hex code(s) associated with that command. It makes things easier to understand and leaves "bookmarks" in the SCA file to remind you where you are in the process.

The following example shows the hex code listing for fxtailhook.mdl and the corresponding code from fxtailhook.sca. SCASM opcodes are highlighted in blue to show you the relationship between the two files.

fxtailhook.mdl
 Address      Hex Code
00006108   80BF 0000 0000 0000 0000 8A00 0A00 0000 BD00 2200
0000611C   3900 0C00 9000 0800 0D00 0600 2200 AF00 0000 0000
fxtailhook.sca

; Draw Main Model
Call32( :Part000000 )
EndVersion   ;BD00
Return   ;2200
Drawing the model starts with the part at the top of the parts hierarchy, in this case, a rectangular box representing the fuselage.

fxtailhook.mdl
 Address      Hex Code
00006108   80BF 0000 0000 0000 0000 8A00 0A00 0000 BD00 2200
0000611C   3900 0C00 9000 0800 0D00 0600 2200 AF00 0000 0000

fxtailhook.sca

; Part: Box
:Part000000
IfVarAnd( :RET0 90 8 )   ;3900 0C00 9000 0800
Jump( :GO0 )   ;0D00 0600
There is no label ":GO0" in the model file, only an offset to the first byte of the code identified by the label ":GO0." BGL uses relative addresses to jump or call around to other opcodes. These offsets are relative to the beginning of the opcode (command) in which they are contained.

Count'em ... 6 bytes from the start of the Jump command is the hex word "AF00," which is the opcode for the "Transform_Mat( .. ) command.
:RET0
Return   ;2200

fxtailhook.mdl
 Address      Hex Code
0000611C   3900 0C00 9000 0800 0D00 0600 2200 AF00 0000 0000
00006130   0000 0000 0000 0000 0000 803F 0000 0000 0000 0000
00006144   0000 0000 0000 803F 0000 0000 0000 0000 0000 0000
00006158   0000 803F B800 0000 FFFF B900 0000 1800 2400 0000
0000616C   0100 0200 0000 0200 0300 0400 0500 0600 0400 0600
00006180   0700 0800 0900 0A00 0800 0A00 0B00 0C00 0D00 0E00
00006194   0C00 0E00 0F00 1000 1100 1200 1000 1200 1300 1400
000061A8   1500 1600 1400 1600 1700 8A00 0A00 0000 AE00 2200

fxtailhook.sca

:GO0
Transform_Mat(   ;AF00
0.000000 0.000000 0.000000   ;0000 0000 0000 0000 0000 0000
1.000000 0.000000 0.000000   ;0000 803F 0000 0000 0000 0000
0.000000 1.000000 0.000000   ;0000 0000 0000 803F 0000 0000
0.000000 0.000000 1.000000   ;0000 0000 0000 0000 0000 803F
)

SetMaterial( 0 -1 )   ;B800 0000 FFFF
DrawTriList( 0   ;B900 0000 1800 2400
0 1 2   ;0000 0100 0200
0 2 3   ;0000 0200 0300
4 5 6   ;0400 0500 0600
4 6 7   ;0400 0600 0700
8 9 10   ;0800 0900 0A00
8 10 11   ;0800 0A00 0B00
12 13 14   ;0C00 0D00 0E00
12 14 15   ;0C00 0E00 0F00
16 17 18   ;1000 1100 1200
16 18 19   ;1000 1200 1300
20 21 22   ;1400 1500 1600
20 22 23   ;1400 1600 1700
)

NOTE
In the hex code for DrawTriList( ... ), there are two hex words present in the MDL file that do not appear in the SCA file. From the above code sequence for DrawTriList( ... ), B900 0000 1800 2400 0000 0100 0200 ...., 1800 hex (24 dec) is the next vertex index after this list and 2400 hex (36 dec) is the total number of points in this list. These two values are set when the SCA file is compiled.

fxtailhook.mdl
 Address      Hex Code
000061A8   1500 1600 1400 1600 1700 8A00 0A00 0000 AE00 2200
000061BC   3900 0C00 9000 0800 0D00 0600 2200 0D00 2401 0100

fxtailhook.sca

Call32( :Part000001 )   ;8A00 0A00 0000
TransformEnd   ;AE00
Return   ;2200

; Part: tailhook
:Part000001
IfVarAnd( :RET1 90 8 )   ;3900 0C00 9000 0800
Jump( :GO1 )   ;0D00 0600
:RET1
Return   ;2200
:GO1
Jump( :next )   ;0D00 2401
When you reach the first animated part in your model, you'll discover that the hex code in the MDL file no longer matches up with the code in the SCA file. In the original FSDS-generated SCA file, the label ":GO1" marked a Transform_Mat( ... ) command for the part "tailhook." The model file has a Jump command at this point. This marks the beginning of the MDL file's animation data table for an animated part.

Starting here, and for each animated part in your model, you have to delete the Transform_Mat( ... ) command and insert new code to match the MDL file.

fxtailhook.mdl
 Address      Hex Code
000061BC   3900 0C00 9000 0800 0D00 0600 2200 0D00 2401 0100
000061D0   0000 80BF 0000 0000 0000 0000 0000 0000 0000 0000
000061E4   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
000061F8   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000620C   0000 0000 0000 0000 0400 0000 0000 0000 0000 5439
00006220   2DC3 90B3 61C3 0000 C842 0000 0000 5439 2DC3 90B3
00006234   61C3 0000 CA42 0000 0000 5439 2DC3 90B3 61C3 0000
00006248   4843 0000 0000 5439 2DC3 90B3 61C3 0300 0000 80BF
0000625C   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

fxtailhook.sca

; Animate Translation Data Table
:TailhookTranslationDataTable Dwd( 1 )   ;0100
Dr4( -1.00 )   ;0000 80BF
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dwx( 0x0004 )   ;4 rows
Dr4( 0.0000000E+000 0.0000000E+000 -173.22394E+000 -225.70142E+000 )
Dr4( 100.00 0.0000000E+000 -173.22394E+000 -225.70142E+000 )
Dr4( 101.00 0.0000000E+000 -173.22394E+000 -225.70142E+000 )
Dr4( 200.00 0.0000000E+000 -173.22394E+000 -225.70142E+000 )

fxtailhook.mdl
 Address      Hex Code
00006248   4843 0000 0000 5439 2DC3 90B3 61C3 0300 0000 80BF
0000625C   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
00006270   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
00006284   0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
00006298   0000 0000 0400 0000 0000 0000 0000 0000 0000 0000
000062AC   0000 0000 803F 0000 C842 15EF C33E 0000 0000 0000
000062C0   0000 5F83 6C3F 0000 CA42 15EF C33E 0000 0000 0000
000062D4   0000 5F83 6C3F 0000 4843 15EF C33E 0000 0000 0000
000062E8   0000 5F83 6C3F 8900 E0FE FFFF AD00 FFFF FFFF DE00

fxtailhook.sca

; Animate Rotation Data Table   Angle = 0.00 to 135.00 deg
:TailhookRotationDataTable
Dwd( 3 )   ;0300
Dr4( -1.00 )   ;Angle = 0.00 to 135.00 deg
0000 80BF
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 )
Dwx( 0x0004 )   ;4 rows
Dr4( 0.0000000E+000 0.0000000E+000 0.0000000E+000 0.0000000E+000 1.0000000E+000 )
Dr4( 100.00 0.38268343E+000 0.0000000E+000 0.0000000E+000 0.92387956E+000)
Dr4( 101.00 0.38268343E+000 0.0000000E+000 0.0000000E+000 0.92387956E+000)
Dr4( 200.00 0.38268343E+000 0.0000000E+000 0.0000000E+000 0.92387956E+000)

fxtailhook.mdl
 Address      Hex Code
000062E8   0000 5F83 6C3F 8900 E0FE FFFF AD00 FFFF FFFF DE00
000062FC   0000 0100 0000 0000 0000 0000 0000 0000 0000 0000
00006310   0000 8900 FFFF FFFF 8900 3EFF FFFF AD00 FFFF FFFF
00006324   DE00 0000 0100 0000 0000 0000 0000 0000 0000 0000
00006338   0000 0000 8900 FFFF FFFF B800 0100 FFFF B900 1800

fxtailhook.sca

:next
VarBase(:TailhookTranslationDataTable )   ;8900 E0FE FFFF
Animate(:[-1] 0xDE 0 1   ;AD00 FFFF FFFF DE00 0000 0100 0000 0000 0000
0.0000000E+000 0.0000000E+000 0.0000000E+000 );0000 0000 0000 0000 0000 0000
VarBase( :[-1] )   ;8900 FFFF FFFF
VarBase(:TailhookRotationDataTable )   ;8900 nnnn nnnn
Animate(:[-1] 0xDE 0 1   ;AD00 FFFF FFFF DE00 0000 0100 0000 0000 0000
0.0000000E+000 0.0000000E+000 0.0000000E+000 );0000 0000 0000 0000 0000 0000
VarBase( :[-1] )   ;8900 FFFF FFFF

fxtailhook.mdl
 Address      Hex Code
00006338   0000 0000 8900 FFFF FFFF B800 0100 FFFF B900 1800
0000634C   4000 6600 0000 0100 0200 0000 0200 0300 0400 0500
00006360   0600 0400 0600 0700 0800 0900 0A00 0800 0A00 0B00
00006374   0C00 0D00 0E00 0C00 0E00 0F00 1000 1100 1200 1000
00006388   1200 1300 1400 1500 1600 1400 1600 1700 1800 1900
0000639C   1A00 1800 1A00 1B00 1C00 1D00 1E00 1C00 1E00 1F00
000063B0   2000 2100 2200 2000 2200 2300 2000 2300 2400 2000
000063C4   2400 2500 2000 2500 2600 2000 2600 2700 2800 2900
000063D8   2A00 2800 2A00 2B00 2C00 2D00 2E00 2C00 2E00 2F00
000063EC   3000 3100 3200 3000 3200 3300 3400 3500 3600 3400
00006400   3600 3700 3800 3900 3A00 3800 3A00 3B00 3C00 3D00
00006414   3E00 3C00 3E00 3F00 AE00 AE00 2200 2200 2200 2200
00006428   0000 ..

fxtailhook.sca

SetMaterial( 1 -1 )   ;B800 0100 FFFF
DrawTriList( 24   ;1800 4000 6600
0 1 2   ;0000 0100 0200
0 2 3   ;0000 0200 0300
4 5 6   ;0400 0500 0600
4 6 7   ;0400 0600 0700
8 9 10   ;0800 0900 0A00
8 10 11   ;0800 0A00 0B00
12 13 14   ;0C00 0D00 0E00
12 14 15   ;0C00 0E00 0F00
16 17 18   ;1000 1100 1200
16 18 19   ;1000 1200 1300
20 21 22   ;1400 1500 1600
20 22 23   ;1400 1600 1700
24 25 26   ;1800 1900 1A00
24 26 27   ;1800 1A00 1B00
28 29 30   ;1C00 1D00 1E00
28 30 31   ;1C00 1E00 1F00
32 33 34   ;2000 2100 2200
32 34 35   ;2000 2200 2300
32 35 36   ;2000 2300 2400
32 36 37   ;2000 2400 2500
32 37 38   ;2000 2500 2600
32 38 39   ;2000 2600 2700
40 41 42   ;2800 2900 2A00
40 42 43   ;2800 2A00 2B00
44 45 46   ;2C00 2D00 2E00
44 46 47   ;2C00 2E00 2F00
48 49 50   ;3000 3100 3200
48 50 51   ; 3000 3200 3300
52 53 54   ;3400 3500 3600
52 54 55   ;3400 3600 3700
56 57 58   ;3800 3900 3A00
56 58 59   ;3800 3A00 3B00
60 61 62   ;3C00 3D00 3E00
60 62 63   ;3C00 3E00 3F00
)
TransformEnd   ;AE00
TransformEnd   ;AE00
Return   ;2200
Return   ;2200
Return   ;2200
Return   ;2200
:Exit
EndA   ;0000

That completes the transformation of the SCASM code in fxtailhook.sca to match the binary code in fxtailhook.mdl. After you compile this edited SCA file with SCASM and copy and paste the resulting BGL code into the MDL file, you will have all of your original animations in place, just the way you designed them.