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
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 |
| -- | ------- | ------ | ---------------- |
| a | 61 01 | 353 | 1 |
| b | 25 01 | 293 | 3312 |
| d | 19 01 | 281 | 11600 |
| c | 16 01 | 278 | 11948 |
Considering sprites with a 1,1 x,y.
```
u0 u1 u2 u3 X Y pixeldata
bgtree_m 24 : ee 00 5e 01 01 01 01 1f 00
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
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
def decompress(filename)
puts "\nAttempting RLE decompression of #{filename}..."
puts "\nAttempting custom decompression of #{filename}..."
obj = load_obj(filename)
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 = []
data = sprite.data.bytes
hdr = sprite.header
(0...hdr.height).each do |i|
# npackets = data.shift(1)[0] # ignore the packet byte
decompressed_line = []
loop do
break if data.empty?
count = 0
loop do
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
type = data.shift(1)[0]
right = data.index(0)
if decompressed_line.size == hdr.width
print "Done line! "
break
end
# if npackets > 0 && count == npackets
# print "Done packets! "
# break
# end
count+=1
if right.nil?
print "error! end of chunk not found"
break
end
raise "Bad length for line #{i}! #{decompressed_line.size} (Expected #{hdr.width})" if decompressed_line.size != hdr.width
decompressed << decompressed_line
rec = data.shift(right)
_ = data.shift(1) # drop the record separator
decompressed << [ type, rec[0] ]
end
puts "Decompressed: #{decompressed.flatten.size} bytes. Sprite pixels: #{hdr.width*hdr.height}"
#display(decompressed.map(&:chr).join(""))
puts ": #{data.size} bytes remaining. Decompressed: #{decompressed.size} bytes. Sprite pixels: #{hdr.width*hdr.height}"
pp decompressed
# display(decompressed.map(&:chr).join(""))
end
end
@@ -318,23 +302,47 @@ def compare(filenames)
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)
obj = load_obj(filename)
puts filename + ":"
puts "\ti X Y Px bytes bits/px"
obj.sprites.each_with_index do |spr, i|
hdr = spr.header
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,
hdr.unknown0 & 0x000000ff,
(hdr.unknown0 & 0x0000ff00) >> 8,
(hdr.unknown0 & 0x00ff0000) >> 16,
(hdr.unknown0 & 0xff000000) >> 24,
hdr.width,
hdr.height,
px,
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
@@ -345,9 +353,11 @@ when "sprites" then
when "dump" then
ARGV.each { |filename| dump(filename) }
when "compare" then
compare(filenames)
compare(ARGV)
when "decompress" then
ARGV.each { |filename| decompress(filename) }
when "correlate" then
correlate(ARGV)
else
puts "Unrecognized command #{command}"
exit(1)