More .obj investigation. Looking for records in sprite data
This commit is contained in:
@@ -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.
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user