raziel23x / skyrim-plugin-decoding-project

Automatically exported from code.google.com/p/skyrim-plugin-decoding-project
1 stars 3 forks source link

Decode of MHDT subrecords in WRLD and CELL records #187

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This is not a complete decode in the sense that I've not yet matched the 
results up against in-game height map data, but decoding these on Linux 
produces ASCII art that looks undeniably like iso-bar maps.

For WRLD records, the MHDT subrecord is:

x1 = sint16()
y1 = sint16()
x2 = sint16()
y2 = sint16()

for x in [x1, x2 + 1]:
  for y in [y1, y2 + 1]:
     m1[x][y] = uint8()
     m2[x][y] = uint8()
     m3[x][y] = uint8()
     m4[x][y] = uint8()

The four matrices are very similar and obviously describe the same terrain 
grid.  Perhaps m1 through m4 represent quadrants of each (x,y) cell?  The value 
zero may have special significance, since it is frequently adjacent to values 
that are much larger (steep slopes?).  The primary evidence for a correct 
decoding is that the x and y values predict the correct subrecord size, and the 
four resulting iso-bar maps are very similar.

For the CELL record, the format is very similar to the WRLD records, except 
that the size appears to be hard-coded for x1=0, x2=32, y1=0, y2=32 and there's 
only one matrix.  There's also 4 bytes of extra data at the beginning of the 
subrecord.  

unknown1 = uint16()
unknown2 = uint16()

for x in [0, 32]:
  for y in [0, 32]:
     m[x][y] = uint8()

The value of unknown1 is 0x0000 in all but ten cases.  Four of those records 
have 0x8000 suggesting a flag of some sort, and decode correctly.  The 
remaining six values are 0xFFFF (3 times), 0x019d, 0x091b, and 0x0b91.  These 
records all appear to be corrupt in the sense that the decoding above does not 
produce identifiable "map terain".

The significance of unknown2 is unclear, but I suspect a base elevation.  The 
value 0xC65A occurs 3466 times and 0xC400 occurs 1796 times.  Many other values 
cluster around 0xC500 and 0x4600.  Simply printing the 32x32 matrix as 
two-digit hex bytes will easily reveal identifiable terrain because most 
adjacent cells only have a delta of 0 or 1 from their neighbors.  The lowest 
point in any cell appears to always be zero, and the full byte range for the 
matrix values is rarely used.  Only 0.2% of the values are greater than 100, 
and 98.3% are less than 60.

Visualizing the WRLD results is a little more difficult, since each (x,y) cell 
differs more significantly from it's neighbor, the worlds are often larger than 
32x32, and the full range of the byte is used more frequently.  What worked 
best for me was to scale each byte into the range 0-9 and then print the matrix 
as before.

Since I'm unable to correlate the terrain data with actual game terrain, I 
thought I'd describe the results briefly here in case someone else recognizes 
something.  Scaled height values (0-9) are in parentheses.

Riften has a low northwest corner (0), highly varied terrain and a high mount 
(9) in the upper center.  Markarth is basically flat (0), with the high point 
(6) in northeast corner.  Whiterun undulates gently (1-3), with the highest 
point (9) in the southwest corner. Skuldafn has a low northwest corner (0), and 
is mostly flat (2), with some terrain in the southern portion (5).  Deepwood 
Redoubt has a low northwest corner (0) and is otherwise flat (2).  Sovengarde 
has a low northwest corner (0), is generally flat (2) and has a peanut-shaped 
mount (5-9).  Solitude is most flat (0-1) with a couple of higher spots (2-3).

It seems suspicious that there are so many low northwest corners.  It's 
possible that there's some row delta encoding in use like in the LAND records, 
but there's no evidence of signed values in the data, and I can't find a 
working scheme.

Original issue reported on code.google.com by cfcohe...@gmail.com on 25 Jan 2015 at 4:28

GoogleCodeExporter commented 9 years ago
see r1886 , kind of

Original comment by HuguesLe...@gmail.com on 2 Feb 2015 at 11:45