Use bin_tools from rubygems

This commit is contained in:
Madeline Lim 2018-05-23 23:19:46 -07:00
parent 079b397482
commit c983a3fbc7
3 changed files with 5 additions and 282 deletions

View file

@ -1,123 +0,0 @@
16# 8 16 32 64
# C S L Q - unsigned
# c s l q - unsigned
# < LE
# > BE
# A - binary string
# z - null terminated
# H - hex string
class BinWriter
def initialize fn
@f = File.new fn, "wb"
end
def self.open fn, &block
f = BinWriter.new fn
block.call f
f.close
end
def seek pos
@f.seek pos
end
def tell
@f.tell
end
def write_str str
@f.write str
end
def write_str_varlen str
write_varlen_le str.size
@f.write str
end
def write_byte val
@f.write [val].pack("C")
end
def write_bool val
write_byte val ? 1 : 0
end
def write_u16_le val
@f.write [val].pack("S<")
end
def write_s16_le val
@f.write [val].pack("s<")
end
def write_u16_be val
@f.write [val].pack("S>")
end
def write_u32_le val
@f.write [val].pack("L<")
end
def write_s32_le val
@f.write [val].pack("l<")
end
def write_u32_be val
@f.write [val].pack("L>")
end
def write_f32_le val
@f.write [val].pack("e")
end
def write_u24_be val
write_byte val >> 16
write_u16_be val & 0xFFFF
end
def write_bin str
@f.write str
end
def write_varlen_be val
out = [val & 0x7F]
val = val >> 7
while val > 0
out << (val & 0x7f) + 0x80
val = val >> 7
end
out.reverse.each do |x|
write_byte x
end
end
def write_varlen_le val
out = [val & 0x7F]
val = val >> 7
while val > 0
out << (val & 0x7f)
val = val >> 7
end
out.each_with_index do |x, i|
write_byte(x + ((i == out.size - 1) ? 0 : 0x80))
end
end
def write_binswap str
togo = str.size
pos = 0
while togo > 0
r = @rom[pos..(pos+3)].unpack('L>')
d = r.pack('L<')
write_bin d
pos += 4
togo -= 4
end
end
def close
@f.close
end
end

View file

@ -1,7 +1,6 @@
require './rom' require 'bin_tools'
require './binwriter'
require 'json' require 'json'
require 'pry'
# Value Types # Value Types
# :boolean, :u8, :s16, :s32, :float, :lookup, :bin, :rle # :boolean, :u8, :s16, :s32, :float, :lookup, :bin, :rle
@ -167,7 +166,7 @@ class CelesteMap
@debug = debug @debug = debug
case fmt case fmt
when :bin when :bin
@rom = ROM.from_file(fn) @rom = BinTools::Reader.from_file(fn)
raise "Not a celeste map" unless rom.read_str_varlen == 'CELESTE MAP' raise "Not a celeste map" unless rom.read_str_varlen == 'CELESTE MAP'
@package = rom.read_str_varlen @package = rom.read_str_varlen
@string_lookup = (0...rom.read_u16_le).map { rom.read_str_varlen } @string_lookup = (0...rom.read_u16_le).map { rom.read_str_varlen }
@ -184,7 +183,7 @@ class CelesteMap
end end
def write fn def write fn
@writer = BinWriter.new(fn) @writer = BinTools::BinWriter.new(fn)
@string_lookup = root.strings @string_lookup = root.strings
writer.write_str_varlen 'CELESTE MAP' writer.write_str_varlen 'CELESTE MAP'
writer.write_str_varlen root.package writer.write_str_varlen root.package
@ -271,8 +270,6 @@ class CelesteMap
element.children.each do |child| element.children.each do |child|
write_element child write_element child
end end
rescue => e
binding.pry
end end
def read_element pre=0 def read_element pre=0
@ -501,7 +498,7 @@ class EntityElement < Element
e e
end end
def self.parse_crush_block obj def self.parse_kevin obj
e = self.new e = self.new
e.name = 'crushBlock' e.name = 'crushBlock'
e.set_gen_id 'entity' e.set_gen_id 'entity'

151
rom.rb
View file

@ -1,151 +0,0 @@
# General purpose binary reader
# 8 16 32 64
# C S L Q - unsigned
# c s l q - unsigned
# < LE
# > BE
# A - binary string
# z - null terminated
# H - hex string
class ROM
def initialize str
@rom = str
@cur = 0
@base = 0
end
def self.from_file fn
data = File.open(fn, "rb") { |io| io.read }
ROM.new data
end
def set_base pos
@base = pos
end
def seek pos
@cur = pos + @base
end
def seek_rel pos
@cur += pos
end
def tell
@cur - @base
end
def read_str len
r = @rom[@cur..(@cur + len - 1)].unpack("A#{len}").first
@cur += len
r
end
def read_str_varlen
len = read_varlen_le
r = @rom[@cur..(@cur + len - 1)].unpack("A#{len}").first
@cur += len
r
end
def read_byte
r = @rom[@cur].ord
@cur += 1
r
end
def read_bool
read_byte == 1
end
def read_s8
r = @rom[@cur].unpack("c").first
@cur += 1
r
end
def read_u16_le
r = @rom[@cur..(@cur + 3)].unpack('S<').first
@cur += 2
r
end
def read_s16_le
r = @rom[@cur..(@cur + 3)].unpack('s<').first
@cur += 2
r
end
def read_u16_be
r = @rom[@cur..(@cur + 3)].unpack('S>').first
@cur += 2
r
end
def read_u32_le
r = @rom[@cur..(@cur + 3)].unpack('L<').first
@cur += 4
r
end
def read_s32_le
r = @rom[@cur..(@cur + 3)].unpack('l<').first
@cur += 4
r
end
def read_u32_be
r = @rom[@cur..(@cur + 3)].unpack('L>').first
@cur += 4
r
end
def read_f32_le
r = @rom[@cur..(@cur + 3)].unpack('e').first
@cur += 4
r
end
def read_bin len
r = @rom[@cur..(@cur + len - 1)]
@cur += len
r
end
def read_binswap len
togo = len
bin_data = "".b
while togo > 0
r = @rom[@cur..(@cur + 3)].unpack('L>')
bin_data += r.pack('L<')
@cur += 4
togo -= 4
end
bin_data
end
def read_varlen_le
val = 0
r = read_byte
val = r & 0x7F
return val if r < 0x80
r = read_byte << 7
val + r
end
def read_varlen_be
val = 0
r = read_byte
val = r & 0x7F
return val if r < 0x80
r = read_byte
val = (val << 8) + r
val
end
def msg str
puts "%08X(%08X): %s" % [@cur, tell, str]
end
end