Sign in to follow this  
Followers 0
mikew

Interpretation of SSD files

101 posts in this topic

Thank you!

What he says sounds very much like my job. But it is indeed helpful, because I can now switch from find the pattern in that file mode to just make it work mode …

Share this post


Link to post
Share on other sites

There's exactly 502 entries which are preceeded by two words of unknown meaning. I'll try skipping all others.

Edit: Got it! It looks great; without any rotation, though. Need to go drinking now. I'll post snapshots tomorrow.

Share this post


Link to post
Share on other sites

I see. Some TFX2 shapes do have a block 5 (e.g. 737), others don't (e.g. 707_vip).

This issue of Block5 has me curious.

If I look at the SSD files in their parsed-runtime state, is seems to suggest a possible alternate means of shape file indexing.

It involves the 6th and 7th header bytes:


Bytes 6 & 7 = always has value 0xFFFF

I'll use echo1r.ssd as an example:

00 01 e8 03 01 1c ff ff 04 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00

0b 00 0d 00 0d 00 7a 00 50 00 ff ff 03 00 00 00

50 00 01 00 05 00 07 00 00 00 00 00 00 00 00 00


In memory, it looks like this:

00 00 01 E8 03 01 1C 9A 01 04 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04

00 0B 00 0D 00 0D 00 7A 00 50 00 FF FF 03 00 00

00 50 00 01 00 05 00 07 00 00 00 00 00 00 00 00

00 00 1A 00 19 21 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 1C 00 1B 21 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 11 00 00 00 65 63 68 6F 31 72 00

07 04 00 00 00 51 00 00 00 43 00 00 00 00 00 00

00 00 9B 01 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 50 00 FF FF

In perhaps a form of logical block addressing, 9A 01 @ bytes 6/7, addresses the shape file for echo1r.ssd. Also note 7A 00, if considered a simple pointer, points to the next block: 9B 01.

The same process is in effect for the terrain tiles and, in-game, I can swap terrain tile shape files for a given terrain tile SSD by simply swapping the value at the 6th and 7th SSD header bytes

This may all be SSD-subtype specific, as although, all TFX3 SSD files have a Block 5, not all seem to folllow this pattern. :popcornsmilie:

Share this post


Link to post
Share on other sites

:whoa: I'm not sure what to make of that. :)

echo1r.ssd only has one shape, what happens with multiple shapes?

The 7a00 does seem to point to the 9b01, but is that just a coincidence in this one case? Wouldn't bigger ssd files take up more space in memory and thus mess up that theory?

Share this post


Link to post
Share on other sites

There's exactly 502 entries which are preceeded by two words of unknown meaning. I'll try skipping all others.

Edit: Got it! It looks great; without any rotation, though. Need to go drinking now. I'll post snapshots tomorrow.

:thumbsup: Look forward to the pictures...

The first of the two words is the rotation:

00 00 =0 deg

40 00 = 90 deg

80 00 =180 deg

c0 00 =270 deg

The second is the 'randomization' number, followed by that number of filenames. This explains why there are 573 filenames but only 502 indices. Totally forgot about that. :doh2:

Share this post


Link to post
Share on other sites

:whoa: I'm not sure what to make of that. :)

echo1r.ssd only has one shape, what happens with multiple shapes?

The 7a00 does seem to point to the 9b01, but is that just a coincidence in this one case? Wouldn't bigger ssd files take up more space in memory and thus mess up that theory?

It's still early in the investigation, however, at this point my working theory is fairly basic. Just as only some of the TFX2 files have a Block 5, not all TFX3 files utilize their Block 5. It seems this system is used by single-shape-associated SSD's (mostly terrain tiles). The larger SSD files maintain their FFFF and access their shape files differently. It is almost stereotypical in that it reminds me of one of the processes the shape files, with header textures (mostly terrain tiles), uses to acquire its single-texture header texture, by patching the corresponding texture index code into the 27th header word at game loading...

Share this post


Link to post
Share on other sites

That's a bit scary :superscare:

Not my job on TFX modding, but my real-life job. No reason to be scared ;)

:thumbsup: Look forward to the pictures...

Here's one:

120929firstef2000terrai.png

Sorry it's so small, but I'm working with my Eee PC again, and it is pretty slow even for that. Also, there is no sky and the fog color is wrong and the sea tiles are still missing because …

I don't see anything 'wrong' with sea.ssd, it 's as simple as they come:

… the size check still assumes block 2 occurs even though we now know TFX2 shapes have no block 2. I'll need to fix that tomorrow …

The first of the two words is the rotation:

00 00 =0 deg

40 00 = 90 deg

80 00 =180 deg

c0 00 =270 deg

The second is the 'randomization' number, followed by that number of filenames. This explains why there are 573 filenames but only 502 indices. Totally forgot about that. :doh2:

I already suspected this for rotation, but I didn't consider randomization. This makes the structure pretty clear; I'll implement it tomorrow.

There's sooo much to get right, but there's also lots of new progress. Before I go to sleep, I want to thank both of you for your help — this week really feels like a leap forward :thumbsup:

Share this post


Link to post
Share on other sites

Thanks for the clarification.

It's best not to mistake speculation for clarification. The pattern is consistent in some sections and not in others, arguing more in favor of coincidental findings than a 00 7A elucidation. The problem I'm having is I have not yet been able to find the shape index reflected in the header 3rd word values.

Krycztij,

Nice Picture :thumbsup:

Share this post


Link to post
Share on other sites

Thank you! Fixed the size check:

120930ef2000terrainwith.png

I hate to say so, but one tile is still completely messed up:

120930scalingproblem.png

There seems to be a general problem with how TFX2 handles scale factors in contrast to TFX3 (notice how the planes are scaled differently). I can see two or three other tiles being too small, too. Sadly, I cannot say what tiles these are right now … I'll be back for investigation this evening.

Also: The color palette documentation in the TAW Wiki proved extremely useful in development of 3View for TAW. Is there similar documentation for EF2000? I need to get the sky colors right …

Share this post


Link to post
Share on other sites

Looking good!

Sadly, I don't believe there is any extra palette data forTFX2. We're breaking new ground here.

Although, I'd expect it to be broadly similar to TFX3, one differernce is that the palette is defined in the lev folder, and not in a 'redXXXX.ini' file.

There were some different shape opcodes for TFX2 as well, which may explain the scaling.

Share this post


Link to post
Share on other sites

I've just been on a sorting frenzy, and of the 502 indices only 409 are actually used.

So, only taking those 409 into account, we end up with 202 unique supershape files:

List of 'active' TFX2 Supershapes


sea

cm3_p

cm3_p2

cm3_p3

cm3_p4

cm3_s

cm3_c

cm3_i

cm2_p

cm2_p2

cm2_p3

cm2_p4

cm2_s

cm2_i

cm2_c

cm1_p

cm1_p2

cm1_p3

cm1_s

cm1_i

cm1_c

cm0_g

cm0_g2

cm0_g3

cm0_g4

cm0_g5

cm0_g6

cm0_g7

fcm1_p

fcm1_p2

fcm1_pc

fcm1_ps

fcm1_pi

coast_s

coast_s1

coast_s2

coast_i

coast_c

coclconl

coclconr

clif1s2s

clif1s_s

clif1s2w

clif1s_w

clif1s2n

clif1s_n

clif1s2e

clif1s_e

clifc_se

clifc_sw

clifc_nw

clifc_ne

clifi_se

clifi_sw

clifi_nw

clifi_ne

clif2s2s

clif2s_s

clif2s2w

clif2s_w

clif2s2n

clif2s_n

clif21s2

clif2s_e

clf2c_se

clf2c_sw

clf2c_nw

clf2c_ne

clf2i_se

clf2i_sw

clf2i_nw

clf2i_ne

fcm1_s

fcm1_c

fcm1_i

cmg_i

cmg_c

cmg_s

cmg_m

rrval_s

rrval_cr

rrvalxcr

rrval_cl

rrvalxcl

rrjunc_2

rrjunc_4

rrjunc_3

rrjunc_1

rrflt_s

rrflt_cr

rrfltxcr

rrflt_cl

rrfltxcl

rrfltc_2

rrfltc_4

rrfltc_3

rrfltc_1

rrval_e2

rrval_e

fyord_s

fyord_e

fyord_c

fy_start

clifcosl

clifcowl

clifconl

clifcoel

clifcosr

clifcowr

clifconr

clifcoer

past0_s

past0_c

past0_i

past0_m

marsh_m

marsh_m2

marsh_m3

marsh_m4

vpast0_s

vpast0_c

vpas0_st

vpast0_e

valley_s

start

valley_e

valley_c

river_s

river_c

estsouth

estwest

estnorth

esteast

river_st

bridge1

dam

rig_1

ryggeq

bardu

bodo

trond

oslo

orland

airfld_1

early1

armydok

politdok

powerdok

oil_dok

suplydok

portdok

v_amytwn

v_c4twn

v_poltwn

v_pwrtwn

v_oil

v_suptwn

f_amytwn

f_c4twn

f_poltwn

f_pwrtwn

f_oiltwn

f_suptwn

ctydoc_c

ctydoccl

ctydoccr

ctydoc_i

s_oslo

s_helsin

s_stock

stpete_s

isl_1

isl_2

isl_3

isl_4

isl_5

isl_6

treeisl1

treeisl2

treeisl3

treeisl4

treeisl5

pasriv_e

marsh_s

marsh_c

marsh_i

marshcol

marshcor

tun_rl1

tun_rr1

iceberg1

iceberg2

iceberg3

iceberg4

iceberg5

rrfor_s

rrfor_cr

rrforxcr

rrfor_cl

rrforxcl

rrfor_e2

rrfor_e
...and these supershapes in turn reference 267 shapes:
267 Active TFX2 terrain shapes

genarfld

rwyend34

rwyend16

rwymid

b_gble_1

b_tube_1

bhang1

bhanf1

bhang3

bhanf3

vasi

bfire

bfirf

bhang2

bhanf2

bcontwr1

awind

adisper1

b_dubl_1

airgrnd

townc_1

base7

base2

hq

b_aich_1

b_cube_1

b_glob_1

b_dock

b_duel_1

b_chmn_1

smallfac

b_cran_1

lig02

bardfoss

rwyend29

rwyend11

bodo

rwyend08

rwyend26

bhard11

bharf11

bcontwr3

nx_road

girder

susp_br

clif2cne

clif2cnw

clif2cse

clif2csw

clif2ine

clif2inw

clif2ise

clif2isw

clif1s2d

clif1s2l

clif1s_d

clif1s_l

clif2s2d

clif2s2l

clif2s_d

clif2s_l

conl_d

conr_d

conl_l

conr_l

clif1cne

clif1cnw

clif1cse

clif1csw

clif1ine

clif1inw

clif1ise

clif1isw

cm0_g

cm0_g2

cm0_g3

cm0_g5

cm0_g6

cm1_c

cm1_i

cm1_p

cm1_p2

cm1_p3

cm1_s

cm2_c

cm2_i

cm2_p

cm2_p2

cm2_p3

cm2_s

cm3_c

cm3_i

cm3_p

cm3_p2

cm3_p3

cm3_p4

cm3_s

cmg_c

cmg_i

cmg_m

cmg_s

coast_c

coast_i

coast_s

coast_s1

coast_s2

coclconl

coclconr

city_cl

base6

base8

combunk

ammodepo

camowh

b_tent_1

dishes2

dishes

commsbui

lig03

city_cr

base9

lig04

city_c

b_corn_1

b_pwst_1

power

b_cool_1

multi

lig01

city_i

largew

smallwh

hware

cracker1

oil_rfny

pump_stn

b_tank_1

clump_4l

dam

base5

ewrmount

darkest

lightest

fcm1_c

fcm1_i

fcm1_p

fcm1_p2

fcm1_pc

fcm1_pi

fcm1_ps

fcm1_s

fyord_c

fyord_e

fyord_s

fy_start

rrflt_s

base1

hospital

b_town_2

tiles

b_cort_1

politic

b_peak_1

b_fact_1

cylindri

silo2

chirch

b_town_1

bigfact

tiles_3

base3

base4

sea

iceberg1

iceberg3

iceberg2

iceberg4

isl_2

isl_5

isl_1

isl_6

isl_4a

isl_3a

isl_4

marshcol

marshcor

marsh_c

marsh_i

marsh_m

marsh_s

townc_3

b_silo_1

orland

gardmoen

rwyend19

bhard1

rwyend01

npasrive

past0_c

past0_i

past0_m

past0_s

townc_4

townc_2

b_plat

nriver_c

nriver_s

nriv_st

rrfltc1

ft_bridg

gates

cros_box

b_crater

trainsta

rrfltc2

rrfltc3

rrfltc4

rrfltxcl

rrfltxcr

rrflt_cl

rrflt_cr

rrforxcl

rrforxcr

rrfor_cl

rrfor_cr

rrfor_e

rrfor_e2

rrfor_s

nrrjunc1

nrrjunc2

nrrjunc3

nrrjunc4

nrvalxcl

nrvalxcr

nrrvalcl

nrrvalcr

nrrval_e

nrrvale2

nrrval_s

rygge

rwyend90

rwyend27

adisper2

nstart

city_s4

city_s1

city_s2

city_s3

treeisl1

treeisl2

treeisl3

treeisl4

treeisl5

vaernes2

rwyend09

bcontwr2

rwyend14

rwyend32

tun_rl

tun_rr

nval_c

nval_e

nval_s

vpas0_st

nvpast_c

nvpast_e

nvpast_s

This should cut down the number of files we need to look at....

Share this post


Link to post
Share on other sites

Something strange with the 'Block7's of airfield SSDs...

There is a '1300' that appears either before or after the '0a00' opcode which sets local variables.

eg, these:


airfld_1.ssd


;Block7 Starts 678 Length.126

140017000f000000000000010001000200020003000300040004000500050400f3ff

140001000700000101000305feff0400fbff

15000100030000010500

140002000700000101000305feff0400fbff

14001d00030000080500

140011000700000001000312feff0400fbff

0a000000030000000000ff7f

1300

0100c309


bardu.ssd


;Block7 Starts 642 Length.98

140001000700000101000305feff0400fbff

140002000700000101000305feff0400fbff

15000200030000010500

140012000f000000000000010001000200020003000300040004000500050400f3ff

1300

0a00000003000000000000c0

01008209


bodo.ssd


;Block7 Starts 710 Length.98

140001000700000101000305feff0400fbff

140002000700000101000305feff0400fbff

15000200030000010500

140013000f000000000000010001000200020003000300040004000500050400f3ff

1300

0a00000003000000000000c0

01000e0a

Don't know what it does, but it's been screwing up my counting. :angry:

Some of the 1400 opcodes set the runway end animations. That's something TFX3 doesn't have. :)

Share this post


Link to post
Share on other sites

Something strange with the 'Block7's of airfield SSDs...

There is a '1300' that appears either before or after the '0a00' opcode which sets local variables.

eg, these:

:)

Well the TFX3 airfields dropped the Block 7 "1300". In TFX3 it occurs as 13001100 and exclusively in the aircraft supershapes. 1100 does not appear to relate to the shape indices so I'll have to look elsewhere <_<

Share this post


Link to post
Share on other sites

In TFX2, it's only the airfields that have this isolated '1300' in their Block7

In TFX3, all (I think) aircraft have this sequence at the start of their Block7s:

130011000a0012000100

This is slightly different to how I've interpreted it before (as 13001100), as then we'd have a 0a00 opcode that doesn't make sense.

When reading the SSD file, we need to know what type we're dealing with when we handle opcode '1300'.

Share this post


Link to post
Share on other sites

That's not quite true, as there are some 'actions' set up in the initiation process in what we call Block7. So, we have to deal with these sooner rather than later.

For example, in this ship model, the wake is set up to simulate movement:

From oliver.ssd

1a00 Manipulate Parameter 0006 of shape

0100 Shape = IB_WAKE.3

0600 Number of words following in 'action'

000001000308feff0500

....and in this airbase, the windsock moves up and down.

gen_1rwy.ssd

1400 Manipulate Parameter 0000 of shape

1100 Shape = AWIND.3

2400 Number of words following in 'action'

0000000100020003000400050005000500050005

0005000500050005000400030002000100000000

0000000000000000000000000000000000000000

0000000000000400deff

At least in the second example, the bytecode can be interpreted as change parameter 0000 of awind.3 from value 0->1->2 etc until we reach the 0400 which may mean repeat with a jump backwards of deff (-34) words.

What's interesting is the mix of big-endian and little-endian words. I've done some trial and error measurements, and these types of actions run at a fixed speed of about 60ms per step, giving about 2 seconds per windsock cycle.

I do not yet have a theory of how to interpret the bytecode in the first wake example...

Any ideas?

.

I think one of the questions for this wake “action” sequence, is, from where does the slightly seemingly randomized frame-to-frame process come?

Looking at the sixth word, I would interpret the bytecode this way:

1a00 Manipulate Parameter 0006 of shape

0100 Shape = IB_WAKE.3

0600 Number of words following in 'action'

0000 initial value

0100 increment value +1 (+1/pass)

0308 repeat for 8 passes

feff jump –2 words for each pass

0500 end

In IB_WAKE.3, the corresponding ‘action’ parameter code:


00480006

00210001002E

002100020040

002100030068

0021000400A6

0021000500FA

002100060164

0021000701E4

00220007027A

0000

Share this post


Link to post
Share on other sites

In TFX2, it's only the airfields that have this isolated '1300' in their Block7

In TFX3, all (I think) aircraft have this sequence at the start of their Block7s:

130011000a0012000100

This is slightly different to how I've interpreted it before (as 13001100), as then we'd have a 0a00 opcode that doesn't make sense.

When reading the SSD file, we need to know what type we're dealing with when we handle opcode '1300'.

If we look at FX_FLAK.SSD's block7:


140000000a0000000000000007004d0001000311feff0500

14000100150000000002000400060008000a000c000e00100012001400160018001a001c001e0020002200260500

1300120088131100e803

01003600

I would parse the third line thus; 1300 12008813 1100e803 Whatever code 1300 does, it seems that 1200 and 1100 may apply parameters with values 5000 and 1000, respectively For the TFX3 aircraft, all contain the following in block7:

13001100

0a0012000100

1300

11000a00

12000100

suggest applying parameters with values 10 and 1

Just thinking out loud, because it's got to be in here somewhere :D

Share this post


Link to post
Share on other sites

I would parse the third line thus;

1300

12008813

1100e803

I'd go along with that, specially since e803=1000 and 8813=5000 decimal, which are nice round numbers.

No idea what the hell they do, but they only appear in Block7.

I think the IB_WAKE theory needs a bit more polishing, although it must be something like that.

Instead of 0100 being an increment value, it may be the opcode for a loop function.

Time permitting, I'll try and log all examples of this type of action.

Share this post


Link to post
Share on other sites

...and I'm wrong, 0100 is indeed an opcode for increment value, with 0200 being decrement value, judging by these lines from dhow.ssd


;Block4_Pointer_92 Starts 1314 Length.18

140001000600000001000314feff0500

0000

;Block4_Pointer_93 Starts 1332 Length.18

140001000600001402000300feff0500

0000
Note: object 0100 in dhow.ssd is also IB_WAKE which doesn't use Parameter 0000, so this may not do anything in game I think final proof comes from logo.ssd:
140000000700000001000347feff0400fbff

..where we not only increment Parameter 0000 of logo.3 up to 0x47, but we repeat the process forever to produce the spinning logo

Share this post


Link to post
Share on other sites

I sure hope you're up already and have the coffee brewing because we have a lot of work to do :)

I have a great number of questions generated by the wake / SSD analysis. For example, the dhow wake is in the dhow.ssd code and I can modify the shape file to render the wake from IB_wake.3 by changing the parameter used from 0006 to 0000 (Block4 Pointers 92 and 93 have 1400 opcodes). The wake is rendered when paused and the MFD shows the "shaky" animation (Take Off Training Mission). The first question is why the wake in dhow.ssd is disabled in dhow? It could be that the developers intentions to accurately simulate V.R. would suggest the dhow, which is a sailing vessel, would have little or no perceptible wake and, therefore, disabled it. It could be there is a conversion mechanism in the code, however, I doubt that... :popcornsmilie:

Share this post


Link to post
Share on other sites

No idea why the dhow wake is not used, but there are other SSDs which don't quite match the associated shapes. For example, tu300.ssd has 'action codes' to extend and retract the landing gear, but the shape tu300.3 doesn't contain the necessary opcodes to visualise it.

To fit our current understanding, 'something' would need to keep refreshing the dhow wake as we interpret the 0100 opcode as 'count to value then stop'.

I'm now trying to parse and 'run' the bytecode inside all the '1400', '1500' etc opcode blocks so that I can identify each action (without necessarily understanding what the action does) and make sure that the bytecode doesn't get stuck in a loop.

Share this post


Link to post
Share on other sites

Okay, that should be helpful. Looking at the Block4 Pointer_1 lists now, seeing if there is a pattern there to explain some of the opcode variations for same / similar actions.

Share this post


Link to post
Share on other sites

I've now been through all the non-collision related '1400' etc opcode blocks, and haven't found any new codes, so we are left with the following:

010003xxyyyyy increment as described earlier by DKD

0200 decrement, maybe never used

0400xxxx (where xxxx is a negative number) Jump back.

0500 Stop

0700xxxx GOSUB which may lead to other 1400 lines. I've followed all these to check that I always RETURN.

Any other value should be used to modify the 'Parameter' value of the indexed shape.

I've checked all TFX3 ssd files, plus the couple of hundred TFX2 files that are used for the terrain.

The collision system still needs to be sorted out and I think we will have to make some assumptions about how the game works to move forward with that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0