1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
class RandTileGenerator
def initialize
@sections = {}
end
def section(name)
@sections[name] ||= {entries: []}
@current_section = @sections[name]
yield
end
def random(range, type=:both, numbers=nil)
numbers = range if numbers.nil?
@current_section[:entries] << {range: range, type: type, numbers: numbers.to_a}
end
def pack
# first, work out an offset for every section and entry
# also, collect the data for each individual entry into an Array
current_offset = 8 + (@sections.count * 4)
all_entry_data = []
@sections.each_pair do |name, section|
section[:offset] = current_offset
current_offset += 8
section[:entries].each do |entry|
entry[:offset] = current_offset
all_entry_data << entry[:numbers]
current_offset += 8
end
end
# assign an offset to each piece of entry data
data_offsets = {}
all_entry_data.uniq!
all_entry_data.each do |data|
data_offsets[data] = current_offset
current_offset += data.size
end
# assign an offset to each section name
name_offsets = {}
@sections.keys.each do |name|
name_offsets[name] = current_offset
current_offset += name.size + 1
end
# now pack it all together
header = ['NwRT', @sections.count].pack('a4 N')
offsets = @sections.each_value.map{|s| s[:offset]}.pack('N*')
section_data = @sections.each_pair.map do |name, section|
name_offset = name_offsets[name] - section[:offset]
entry_count = section[:entries].count
entry_data = section[:entries].map do |entry|
lower_bound = entry[:range].min
upper_bound = entry[:range].max
count = entry[:numbers].count
type = [:none, :horz, :vert, :both].index(entry[:type])
num_offset = data_offsets[entry[:numbers]] - entry[:offset]
[lower_bound, upper_bound, count, type, num_offset].pack('CCCC N')
end
[name_offset, entry_count].pack('NN') + entry_data.join
end
output = [header, offsets]
output += section_data
output += all_entry_data.map{|data| data.pack('C*')}
output << @sections.keys.join("\0")
output << "\0"
output.join
end
end
g = RandTileGenerator.new
g.section('TestTileset') do
g.random(1..20)
g.random(21..24, :none)
g.random(250..255, :vert, 0..5)
end
File.open('/home/me/Games/Newer/DolphinPatch/NewerRes/RandTiles.bin', 'wb') do |f|
f.write g.pack
end
|