r1sc / Open76

Interstate '76 engine reimplementation
GNU General Public License v3.0
55 stars 3 forks source link

Load car components #13

Open r1sc opened 6 years ago

r1sc commented 6 years ago

The Vehicle Configuration Files (.VCF) references component files for weapons (.GDF). For example WEPN........goilslck.gdf. These are parsed by the VcfParser, but they are not used anywhere at the moment. Some GDF-files are not directly referenced by the VCF-files (e.g. Cup Holders). Open76 should parse these GDF-files, including the geometry (if any) and attach them to the vehicle loaded.

  1. Figure out how to parse GDF-files and write a corresponding GdfParser.
  2. Discuss how the components should be attached to vehicles and finally implement this.
JJJohan commented 6 years ago

From what I've figured out so far..

GDF format - my test file is glandmin.gdf (i.e. landmine dropper - first GDF file processed in a01.msn)

Typical BWD2 format.

❗️❗️ Asterisk before the offset indicates this extra data only appears in the GoG version. ❗️❗️

GDFC block - 128 bytes (164 in GoG version)

Offset Type Length Description Value (in glandmin.gdf)
0 String 16 Weapon name Landmines
16 Int32 4 6
20 Int32 4 3
24 Float 4 160.0
28 Float 4 100.0
32 Float 4 70.0
36 ? 8
44 Int32 4 240
48 Int32 4 Fireproofing 200
52 Float 4 60.0
56 String 13 drp05
69 ? 9
78 Float 4 Firing Rate 1.0
82 Int32 4 Fire Amount 1
86 Float 4 1.0
90 Float 4 2.101948E-44
94 Int32 4 Ammo Count 25
98 Float 4 0.7
102 String 13 Firing sprite null
115 String 13 Sound Filename mines1.wav
*128 Int32 4 1
*132 String 16 Enabled Sprite 3landmines_on
*148 String 16 Disabled Sprite 3landmines_off

GPOF block - 192 bytes

Offset Type Length Description Value (in glandmin.gdf)
0 ? 192

GGEO block - 4 bytes if no geometry, else 2404 bytes)

❗️❗️ This is the same data layout as the SDF file - you can re-use the SdfPart class. ❗️❗️

Offset Type Length Description Value (in glandmin.gdf)
0 Int32 4 Number of parts 0

ORDF block - 133 bytes (137 in GoG version)

Offset Type Length Description Value (in glandmin.gdf)
0 ? 16
16 String 13 null
29 String 13 null
42 String 13 null
55 String 13 xmine1.xdf
68 String 12 xemt1.wav
80 Byte 1 132
81 String 12 xmine1.xdf
93 Byte 1 130
94 String 13 null
107 String 13 xmine1.xdf
120 String 12 null
132 Byte 1 130
*133 ? 4

OGEO - 104 bytes

Offset Type Length Description Value (in glandmin.gdf)
0 Int32 4 1
4 String 10 MLNDMINE
14 ? 46
60 String 12 WORLD
72 ? 32
Parapsycho commented 6 years ago

"Specials" or Special Equipment (Cup Holders for example) are considered internal components, as they affect the actual handling of the car or other aspects of the game, so it would make sense that they aren't referenced if the VCF is concerned with just defining weapons. I would expect them to be referenced under whatever file references components like the engine, brakes, etc.

For a list of what they do, you can go here: http://www.localditch.com/interstate-76/strategy/tips.html

Also looking at component hacking guides might provide some clues. http://www.oocities.org/timessquare/cave/3628/hackguides.htm

I know it's not code, but hope that it helps in some way. :/

r1sc commented 6 years ago

@JJJohan GEO-tags are probably references to .GEO-files (geometry) or actual geometry data. It might be worth comparing the data of a .GEO-file with the data in those GEO-blocks to see if they follow the same format.

JJJohan commented 6 years ago

Not sure if you get e-mails from comment edits (apologies for the spam otherwise lol) but I've taken another look at the format and laid out some tables above. What worries me is that there is a difference between the retail version and the GoG version of the game - there's extra data in both the GDFC block and the ORDF block (albeit only 4 bytes on the latter).

There is no text in the GPOF block - it looks like it might contain mtrices - it's not unlikely the entire block consists of floating point numbers as viewing it in a hex editor none of the values would go out of range.

I haven't really inspected the GGEO block for now - it's empty in the dropper weapons so for simplicity's sake I'm ignoring until these smaller files are figured out.

The GDF file REV number is 7 on the retail version, and 8 on the GoG version.

@Parapsycho - Cheers for the links, the second one is particularly handy for figuring out a few bits we're still missing!

Update 1

I seem to have gotten a fair bit of information out of it now - ammo count, fire rate, etc. and even the model info. Fortunately the geometry is setup the same as the SDF files so it was easy to copy that logic.

image

You may notice something odd here.. The configuration file for the vehicle is wrong. It turns out it's loading the wrong VCF in the training mission - vppirna1.vcf, instead of vppa01.vcf. The vppa01.vcf contains the correct training loadout: 2x 30 cal mg, firerite rockets and oil slick. However I can't find where the vppa01.vcf is referenced (I've done a string search in the MSN as well as the entire ZFS archive contents with no luck 😢) - Maybe it was hard-coded for the training mission to force this VCF to load?

Update 2

After doing some testing with a hardcoded vpp01.vcf for now (just to try and recreate a one-to-one match with the training mission for reference purposes.) I've found another slight obstacle.

It appears that there is a bit of complexity to the GGEO table.. There are 24 part slots, that are 100 bytes each. Using gmlight.gdf as a reference we can get a bit of information:

The hardpoints on the piranha are setup like so:

Hardpoint (HLOC) Index Name Description Unknown 1 Unknown 2
0 PP1_GDB1 Back Dropper Hardpoint 1 2 4
1 PP1_GIB1 Back Hardpoint 1 2 5
2 PP1_GPF1 Top Hardpoint 1 1 1
3 PP1_GPF2 Top Hardpoint 2 1 1

We can see from the hardpoint's name, e.g. PP1_GDB1:

The weapons in the VCF are setup like so:

Hardpoint (HLOC) Index Name Description
0 goilslck.gdf Oilslick
1 gmlight.gdf 30 Cal
2 gmlight.gdf 30 Cal
3 gdumb.gdf Firerite Rocket

Diving deeper into gmlight.gdf we get these geometry names for the 24 slots in GGEO:

GGEO Index Name Parent Description
0 GMLP11GN WORLD Top, LOD level 0
1 NULL NULL
2 GMLP21GN WORLD Top, LOD level 1
3 NULL NULL
4 GMLP31GN WORLD Top, LOD level 2
5 NULL NULL
6 GMLS11GN WORLD Side, LOD level 0
7 NULL NULL
8 GMLS21GN WORLD Side, LOD level 1
9 NULL NULL
10 GMLS31GN WORLD Side, LOD level 2
11 NULL NULL
12 GMLT11TU WORLD Turret base, LOD level 0
13 GMLT11GN GMLT11TU Turret gun, LOD level 0
14 GMLT21TU WORLD Turret base, LOD level 1
15 GMLT21GN GMLT21TU Turret gun, LOD level 1
16 GMLT31TU WORLD Turret base, LOD level 2
17 GMLT31GN GMLT31TU Turret gun, LOD level 2
18 GMLI11MZ WORLD Inside, LOD level 0
19 NULL NULL
20 GMLI21MZ WORLD Inside, LOD level 1
21 NULL NULL
22 NULL NULL
23 NULL NULL

Note there is some more data in each slot but some of it's not relevant, or figured out.

We can see from the filename that it has a similar layout to the weapon hardpoints. [3 letter weapon name][weapon type][LOD level][Part number][Unknown]

The reason for all this information is.. I'm not sure how to determine which GGEO slot to load based on the weapon type (e.g. I can't seem to find any data to say "load the inside version of the machine gun at slot 18). The closest I can do right now is to use compare the labels which works - I'm just not sure if there is an actual byte, short or integer meant to do that for me.

JJJohan commented 6 years ago

Using the above described technique of comparing the weapon position character (I, P, T or S) works well. I haven't seen the game freak out yet, although I feel like comparing letters probably isn't the 100% correct way to do it..

I've got a suspicion that the second unknown integer in the HLOC definition is what I'm after. I just have to match it with something in the GDF.

Yep, 'unknown 2' is the weapon mesh index. Unfortunately there doesn't appear to be something similar in the GDF file so I'm still using the 3rd index in the label. The good news is the label is always 8 characters long so it's not likely this will break.

For now, some eye candy - The drone training vehicle correctly using the "inside" mesh (really just a circle) for the front weapons and the "side" mesh for the side weapon.

image