More .obj investigation. Looking for records in sprite data

This commit is contained in:
2018-03-21 21:26:07 +00:00
parent 2af6a4a500
commit 1ea123a201
2 changed files with 64 additions and 46 deletions

View File

@@ -251,16 +251,24 @@ d: 116 * 100 = 11600. 7368 - 24 = 7344. 5.1 bits / pixel
We still don't know what the first 32 bits are all about. Perhaps they can help We still don't know what the first 32 bits are all about. Perhaps they can help
to explain the differences in putative bpp. to explain the differences in putative bpp.
0x002-0x003 changes in step with total number of pixels? 0x002-0x003 changes in step with total number of pixels, but that doesn't seem
to account for the difference.
| ID | 0x2-0x3 | dec LE | Number of pixels | Considering sprites with a 1,1 x,y.
| -- | ------- | ------ | ---------------- |
| a | 61 01 | 353 | 1 | ```
| b | 25 01 | 293 | 3312 | u0 u1 u2 u3 X Y pixeldata
| d | 19 01 | 281 | 11600 | bgtree_m 24 : ee 00 5e 01 01 01 01 1f 00
| c | 16 01 | 278 | 11948 | blank 0 : 10 01 61 01 01 01 01 fd 00
transpix 0 : 11 01 3c 01 01 01 01 ae 00
```
Sprites seem to end with a \x00 byte in-general, but we *only* see 0x01 in the
first byte of data for these 1x1 tiles.
Sprites with `X= 128 Y=63` *almost always* seem to have a u0..u3 of
`d1 00 42 01` with a few exceptions, e.g. `treemac{1,2}.obj`
Not clear what it means. If anything!
WH40K_TD.exe loops around "ReadInMissionFLCs", incl. address 0x0041dd10, where WH40K_TD.exe loops around "ReadInMissionFLCs", incl. address 0x0041dd10, where
it loads in all the .asc and .obj files in a set. it loads in all the .asc and .obj files in a set.

View File

@@ -251,55 +251,39 @@ end
# * RLE8: https://www.fileformat.info/format/bmp/corion-rle8.htm # * RLE8: https://www.fileformat.info/format/bmp/corion-rle8.htm
def decompress(filename) def decompress(filename)
puts "\nAttempting RLE decompression of #{filename}..." puts "\nAttempting custom decompression of #{filename}..."
obj = load_obj(filename) obj = load_obj(filename)
obj.sprites.each_with_index do |sprite, i| obj.sprites.each_with_index do |sprite, i|
print "Sprite %02d..."%i hdr = sprite.header
print "Sprite %02d... x=#{hdr.width} y=#{hdr.height}"%i
decompressed = [] decompressed = []
data = sprite.data.bytes data = sprite.data.bytes
hdr = sprite.header hdr = sprite.header
(0...hdr.height).each do |i| loop do
# npackets = data.shift(1)[0] # ignore the packet byte break if data.empty?
decompressed_line = []
count = 0 type = data.shift(1)[0]
loop do right = data.index(0)
cmd = data.shift(1)[0]
if cmd == 0 # end of stream
print "Done! #{data.size} bytes left. "
break
elsif cmd == nil
print "Ran out of data! "
break
elsif cmd > 128 # "negative" bytes say "copy abs(X) bytes unmodified from input to output"
decompressed_line.concat(data.shift(cmd-128))
else # "positive" bytes say "repeat the next byte X times"
decompressed_line.concat(data.shift(1)*cmd)
end
if decompressed_line.size == hdr.width if right.nil?
print "Done line! " print "error! end of chunk not found"
break break
end
# if npackets > 0 && count == npackets
# print "Done packets! "
# break
# end
count+=1
end end
raise "Bad length for line #{i}! #{decompressed_line.size} (Expected #{hdr.width})" if decompressed_line.size != hdr.width rec = data.shift(right)
decompressed << decompressed_line _ = data.shift(1) # drop the record separator
decompressed << [ type, rec[0] ]
end end
puts "Decompressed: #{decompressed.flatten.size} bytes. Sprite pixels: #{hdr.width*hdr.height}" puts ": #{data.size} bytes remaining. Decompressed: #{decompressed.size} bytes. Sprite pixels: #{hdr.width*hdr.height}"
#display(decompressed.map(&:chr).join("")) pp decompressed
# display(decompressed.map(&:chr).join(""))
end end
end end
@@ -318,23 +302,47 @@ def compare(filenames)
end end
end end
require 'set'
def correlate(filenames)
objs = filenames.map { |f| load_obj(f) }
results = Hash.new { |h,k| h[k] = Set.new }
objs.each do |obj|
obj.sprites.each do |spr|
results[spr.header.unknown0 & 0xffff] << spr.header.width
end
end
puts "Unique widths for u0,1"
pp results
end
def sprites(filename) def sprites(filename)
obj = load_obj(filename) obj = load_obj(filename)
puts filename + ":" puts filename + ":"
puts "\ti X Y Px bytes bits/px"
obj.sprites.each_with_index do |spr, i| obj.sprites.each_with_index do |spr, i|
hdr = spr.header hdr = spr.header
px = hdr.width * hdr.height px = hdr.width * hdr.height
puts "\t%02d: %03d %03d %04d %04d %.2f"%[ puts "%s %03d: %02x %02x %02x %02x %3d %3d %5d %5d %.2f %02x %02x ... %02x"%[
filename,
i, i,
hdr.unknown0 & 0x000000ff,
(hdr.unknown0 & 0x0000ff00) >> 8,
(hdr.unknown0 & 0x00ff0000) >> 16,
(hdr.unknown0 & 0xff000000) >> 24,
hdr.width, hdr.width,
hdr.height, hdr.height,
px, px,
hdr.size, hdr.size,
(hdr.size*8) / px.to_f (hdr.size*8) / px.to_f,
spr.data.bytes[0],
spr.data.bytes[1],
spr.data.bytes[-1],
] ]
end end
end end
@@ -345,9 +353,11 @@ when "sprites" then
when "dump" then when "dump" then
ARGV.each { |filename| dump(filename) } ARGV.each { |filename| dump(filename) }
when "compare" then when "compare" then
compare(filenames) compare(ARGV)
when "decompress" then when "decompress" then
ARGV.each { |filename| decompress(filename) } ARGV.each { |filename| decompress(filename) }
when "correlate" then
correlate(ARGV)
else else
puts "Unrecognized command #{command}" puts "Unrecognized command #{command}"
exit(1) exit(1)