Turns out the palette is actually identical to that in wh40k.pcx
This commit is contained in:
@@ -18,7 +18,7 @@ module Obj
|
||||
)
|
||||
|
||||
def self.parse(data)
|
||||
hdr = new(*data[0..SIZE - 1].unpack("V*"))
|
||||
hdr = new(*data[0..SIZE - 1].unpack("VVVVV"))
|
||||
pp hdr
|
||||
hdr.validate!(data.bytes.size)
|
||||
hdr
|
||||
@@ -28,6 +28,16 @@ module Obj
|
||||
@num_sprites, @dir_offset, @dir_size, @data_offset, @data_size = *entries
|
||||
end
|
||||
|
||||
def to_data
|
||||
[
|
||||
@num_sprites,
|
||||
@dir_offset,
|
||||
@dir_size,
|
||||
@data_offset,
|
||||
@data_size,
|
||||
].pack("VVVVV")
|
||||
end
|
||||
|
||||
def validate!(overall_size)
|
||||
raise "Directory overlaps EOF" if overall_size < dir_size + dir_offset
|
||||
raise "Data overlaps EOF" if overall_size < data_offset + data_size
|
||||
@@ -62,6 +72,10 @@ module Obj
|
||||
@sprite_size = sprite_size
|
||||
end
|
||||
|
||||
def to_data
|
||||
[rel_offset, sprite_size].pack("VV")
|
||||
end
|
||||
|
||||
def sprite_range
|
||||
rel_offset...(rel_offset+sprite_size)
|
||||
end
|
||||
@@ -91,8 +105,11 @@ module Obj
|
||||
@entries = entries
|
||||
end
|
||||
|
||||
# Convert the directory into an Array of bytes. Until we work out how to
|
||||
# parse sprites, anyway...
|
||||
def to_data
|
||||
entries.map(&:to_data).join("")
|
||||
end
|
||||
|
||||
# Convert the directory into an Array of sprites
|
||||
def realize(rel_data)
|
||||
entries.map { |entry| Sprite.parse(rel_data[entry.sprite_range]) }
|
||||
end
|
||||
@@ -125,6 +142,18 @@ module Obj
|
||||
@unknown20 = *args
|
||||
end
|
||||
|
||||
def to_data
|
||||
[
|
||||
@unknown0,
|
||||
@width,
|
||||
@height,
|
||||
@unknown8,
|
||||
@size,
|
||||
@unknown16,
|
||||
@unknown20
|
||||
].pack("VvvVVVV")
|
||||
end
|
||||
|
||||
def pixel_range
|
||||
SIZE...(SIZE+size)
|
||||
end
|
||||
@@ -148,6 +177,15 @@ module Obj
|
||||
@records = records
|
||||
@raw = raw
|
||||
end
|
||||
|
||||
# raw is optional, so don't use it here
|
||||
def to_data
|
||||
header.to_data + records.join("")
|
||||
end
|
||||
|
||||
def total_size
|
||||
SpriteHeader::SIZE + records.join("").size
|
||||
end
|
||||
end
|
||||
|
||||
class Parsed
|
||||
@@ -161,6 +199,19 @@ module Obj
|
||||
@directory = directory
|
||||
@sprites = sprites
|
||||
end
|
||||
|
||||
def to_data
|
||||
dir_padding = "\x00"*(header.dir_offset - Header::SIZE)
|
||||
data_padding = "" # for now, assume all is well
|
||||
|
||||
[
|
||||
header.to_data,
|
||||
dir_padding,
|
||||
directory.to_data,
|
||||
data_padding,
|
||||
sprites.map { |sprite| sprite.to_data },
|
||||
].join("")
|
||||
end
|
||||
end
|
||||
|
||||
def self.parse(data)
|
||||
@@ -383,6 +434,70 @@ def sprite(filename, i)
|
||||
end
|
||||
end
|
||||
|
||||
# Build a test sprite to investigate the color palette
|
||||
def build(filename)
|
||||
sprite_records = [
|
||||
# 63 in each sprite except the last, which has just 3
|
||||
1.upto(63).map { |b| "\x01#{b.chr}\x00" },
|
||||
64.upto(126).map { |b| "\x01#{b.chr}\x00" },
|
||||
127.upto(189).map { |b| "\x01#{b.chr}\x00" },
|
||||
190.upto(252).map { |b| "\x01#{b.chr}\x00" },
|
||||
253.upto(255).map { |b| "\x01#{b.chr}\x00" },
|
||||
]
|
||||
|
||||
sprites = sprite_records.map do |records|
|
||||
data = records.join("")
|
||||
header = Obj::SpriteHeader.new(
|
||||
0, # Stolen from blank.obj
|
||||
1, # width of 1
|
||||
records.size, # height = number of records
|
||||
0, # padding?
|
||||
data.size,
|
||||
0, # padding?
|
||||
0, # padding?
|
||||
)
|
||||
|
||||
Obj::Sprite.new(
|
||||
header,
|
||||
records,
|
||||
header.to_data + data,
|
||||
)
|
||||
end
|
||||
|
||||
dir_block_offset = 32 # hardcoded
|
||||
dir_block_size = 8 *sprites.size
|
||||
data_block_offset = dir_block_offset + dir_block_size
|
||||
data_block_size = sprites.inject(0) { |x, spr| x + spr.total_size }
|
||||
|
||||
header = Obj::Header.new(
|
||||
sprites.size,
|
||||
dir_block_offset,
|
||||
dir_block_size,
|
||||
data_block_offset,
|
||||
data_block_size,
|
||||
)
|
||||
|
||||
offset = 0
|
||||
directory = Obj::SpriteDir.new(
|
||||
sprites.map { |sprite|
|
||||
puts "offset #{offset} => #{sprite.total_size}"
|
||||
entry = Obj::DirEntry.new(offset, sprite.total_size)
|
||||
offset += sprite.total_size
|
||||
entry
|
||||
}
|
||||
)
|
||||
|
||||
pp directory
|
||||
|
||||
built = Obj::Parsed.new(
|
||||
header,
|
||||
directory,
|
||||
sprites
|
||||
)
|
||||
|
||||
File.open(filename, "w") { |f| f.write(built.to_data) }
|
||||
end
|
||||
|
||||
case command = ARGV.shift
|
||||
when "sprites" then
|
||||
ARGV.each { |filename| sprites(filename) }
|
||||
@@ -396,6 +511,8 @@ when "decompress" then
|
||||
ARGV.each { |filename| decompress(filename) }
|
||||
when "correlate" then
|
||||
correlate(ARGV)
|
||||
when "build" then
|
||||
build(ARGV[0])
|
||||
else
|
||||
puts "Unrecognized command #{command}"
|
||||
exit(1)
|
||||
|
Reference in New Issue
Block a user