summaryrefslogtreecommitdiff
path: root/randtilegen.rb
blob: f77d333db18cbb9458b06b4d4ff2d0a864004641 (plain)
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