Class: Feh::HSDArcWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/feh/hsdarc_writer.rb,
lib/feh/hsdarc_writer/version.rb,
lib/feh/hsdarc_writer/xor_keys.rb

Overview

A class that builds well-formed HSDArc files used in Fire Emblem Heroes.

Duplicate strings are currently stored like any other sub-block and not optimized; the compiled HSDArc data might not be byte-for-byte identical to the original asset files.

Defined Under Namespace

Modules: XORKeys

Constant Summary collapse

VERSION =

Version number.

"0.1.2"

Instance Method Summary collapse

Constructor Details

#initializeHSDArcWriter

Returns a new instance of HSDArcWriter.



13
14
15
16
# File 'lib/feh/hsdarc_writer.rb', line 13

def initialize
  @buf = []
  @subblocks = []
end

Instance Method Details

#align(x) ⇒ HSDArcWriter

Aligns the data pointer.

Parameters:

  • x (Integer)

    alignment byte count

Returns:



124
125
126
127
# File 'lib/feh/hsdarc_writer.rb', line 124

def align(x)
  @buf += [0] * ((-@buf.size) % x)
  self
end

#bool(b, xor = 0) ⇒ HSDArcWriter

Writes boolean values.

Parameters:

  • b (Object, Array<Object>)

    the boolean value(s), only truthiness is considered

  • xor (Integer) (defaults to: 0)

    XOR value

Returns:



60
61
62
# File 'lib/feh/hsdarc_writer.rb', line 60

def bool(b, xor = 0)
  i8(b ? 1 : 0, xor)
end

#compileArray<Integer>

Compiles the data section of the HSDArc file.

Returns:

  • (Array<Integer>)

    Content of the data section



107
108
109
# File 'lib/feh/hsdarc_writer.rb', line 107

def compile
  hsdarc_impl.first
end

#hsdarcArray<Integer>

Compiles the whole HSDArc file.

Returns:

  • (Array<Integer>)

    Content of the HSDArc file



113
114
115
116
117
118
119
# File 'lib/feh/hsdarc_writer.rb', line 113

def hsdarc
  bin, reloc = hsdarc_impl
  total_size = 0x20 + bin.size + reloc.size * 8
  header = [total_size, reloc.empty? ? 0 : bin.size, reloc.size, 0, 0, 1, 0, 0]
    .pack('l<*').bytes
  header + bin + reloc.pack('q<*').bytes
end

#i16(x, xor = 0) ⇒ HSDArcWriter

Writes 16-bit integers.

Parameters:

  • x (Integer, Array<Integer>)

    the integer value(s)

  • xor (Integer) (defaults to: 0)

    XOR value

Returns:



35
36
37
# File 'lib/feh/hsdarc_writer.rb', line 35

def i16(x, xor = 0)
  int(x, 2, xor)
end

#i32(x, xor = 0) ⇒ HSDArcWriter

Writes 32-bit integers.

Parameters:

  • x (Integer, Array<Integer>)

    the integer value(s)

  • xor (Integer) (defaults to: 0)

    XOR value

Returns:



43
44
45
# File 'lib/feh/hsdarc_writer.rb', line 43

def i32(x, xor = 0)
  int(x, 4, xor)
end

#i64(x, xor = 0) ⇒ HSDArcWriter

Writes 64-bit integers.

Parameters:

  • x (Integer, Array<Integer>)

    the integer value(s)

  • xor (Integer) (defaults to: 0)

    XOR value

Returns:



51
52
53
# File 'lib/feh/hsdarc_writer.rb', line 51

def i64(x, xor = 0)
  int(x, 8, xor)
end

#i8(x, xor = 0) ⇒ HSDArcWriter

Writes 8-bit integers.

Parameters:

  • x (Integer, Array<Integer>)

    the integer value(s)

  • xor (Integer) (defaults to: 0)

    XOR value

Returns:



27
28
29
# File 'lib/feh/hsdarc_writer.rb', line 27

def i8(x, xor = 0)
  int(x, 1, xor)
end

#nullptrHSDArcWriter

Writes a null pointer.

Returns:



90
91
92
# File 'lib/feh/hsdarc_writer.rb', line 90

def nullptr
  i64(0)
end

#ptr {|blk| ... } ⇒ HSDArcWriter

Writes a pointer that points to a new block.

Yield Parameters:

Returns:



97
98
99
100
101
102
103
# File 'lib/feh/hsdarc_writer.rb', line 97

def ptr(&block)
  blk = self.class.new
  block.(blk)
  align(8)
  @subblocks << [@buf.size, blk]
  nullptr
end

#reloc_ptrsArray<Integer>

Returns the relocatable pointer list.

Returns:

  • (Array<Integer>)

    the relocatable pointer list



19
20
21
# File 'lib/feh/hsdarc_writer.rb', line 19

def reloc_ptrs
  @subblocks.map(&:first)
end

#string(str, xor = [0]) ⇒ HSDArcWriter

Creates a pointer to an XOR-encrypted string.

Parameters:

  • str (String, nil)

    UTF-8 string, writes a null pointer instead if equal to nil

  • xor (Array<Integer>) (defaults to: [0])

    optional XOR cipher to use, writes unencrypted strings by default

Returns:



84
85
86
# File 'lib/feh/hsdarc_writer.rb', line 84

def string(str, xor = [0])
  str.nil? ? nullptr : ptr {|blk| blk.xor_str(str, xor)}
end

#xor_str(str, xor = [0]) ⇒ HSDArcWriter

Writes an XOR-encrypted string. The resulting string is always zero-padded to align on 64-bit boundaries.

Parameters:

  • str (String)

    UTF-8 string

  • xor (Array<Integer>) (defaults to: [0])

    optional XOR cipher to use, writes unencrypted strings by default

Returns:



70
71
72
73
74
75
76
# File 'lib/feh/hsdarc_writer.rb', line 70

def xor_str(str, xor = [0])
  align(8)
  bytes = str.bytes.zip(xor.cycle).map {|x, y| x != y ? x ^ y : x}
  bytes += [0] * (8 - bytes.size % 8)
  @buf += bytes
  self
end