pgtools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +25 -0
  3. data/bin/bxm_decoder +2 -0
  4. data/bin/bxm_encoder +2 -0
  5. data/bin/clh_convert +2 -0
  6. data/bin/clp_convert +2 -0
  7. data/bin/clw_convert +2 -0
  8. data/bin/dat_creator +2 -0
  9. data/bin/dat_extractor +2 -0
  10. data/bin/dat_ls +2 -0
  11. data/bin/eff_idd_creator +2 -0
  12. data/bin/eff_idd_extractor +2 -0
  13. data/bin/exp_convert_wiiu_pc +2 -0
  14. data/bin/exp_tool +2 -0
  15. data/bin/mot_convert_wiiu_pc +2 -0
  16. data/bin/mot_tool +2 -0
  17. data/bin/pkz_extractor +2 -0
  18. data/bin/scr_creator +2 -0
  19. data/bin/scr_extractor +2 -0
  20. data/bin/wmb_cleanup +2 -0
  21. data/bin/wmb_common_bones +2 -0
  22. data/bin/wmb_convert_pc_switch +2 -0
  23. data/bin/wmb_convert_wiiu_pc +2 -0
  24. data/bin/wmb_export_assimp +2 -0
  25. data/bin/wmb_get_bone_map +2 -0
  26. data/bin/wmb_import_assimp +2 -0
  27. data/bin/wmb_import_nier +2 -0
  28. data/bin/wmb_import_wiiu +2 -0
  29. data/bin/wtb_convert_wiiu_pc +2 -0
  30. data/bin/wtx_creator +2 -0
  31. data/bin/wtx_extractor +2 -0
  32. data/lib/bayonetta/alignment.rb +14 -0
  33. data/lib/bayonetta/bone.rb +55 -0
  34. data/lib/bayonetta/bxm.rb +180 -0
  35. data/lib/bayonetta/clh.rb +159 -0
  36. data/lib/bayonetta/clp.rb +212 -0
  37. data/lib/bayonetta/clw.rb +166 -0
  38. data/lib/bayonetta/dat.rb +261 -0
  39. data/lib/bayonetta/eff.rb +314 -0
  40. data/lib/bayonetta/endianness.rb +53 -0
  41. data/lib/bayonetta/exp.rb +768 -0
  42. data/lib/bayonetta/linalg.rb +416 -0
  43. data/lib/bayonetta/material_database.yaml +2581 -0
  44. data/lib/bayonetta/mot.rb +763 -0
  45. data/lib/bayonetta/pkz.rb +63 -0
  46. data/lib/bayonetta/scr.rb +393 -0
  47. data/lib/bayonetta/tools/bxm_decoder.rb +23 -0
  48. data/lib/bayonetta/tools/bxm_encoder.rb +37 -0
  49. data/lib/bayonetta/tools/clh_convert.rb +60 -0
  50. data/lib/bayonetta/tools/clp_convert.rb +70 -0
  51. data/lib/bayonetta/tools/clw_convert.rb +60 -0
  52. data/lib/bayonetta/tools/dat_creator.rb +57 -0
  53. data/lib/bayonetta/tools/dat_extractor.rb +94 -0
  54. data/lib/bayonetta/tools/dat_ls.rb +106 -0
  55. data/lib/bayonetta/tools/eff_idd_creator.rb +66 -0
  56. data/lib/bayonetta/tools/eff_idd_extractor.rb +73 -0
  57. data/lib/bayonetta/tools/exp_convert_wiiu_pc.rb +33 -0
  58. data/lib/bayonetta/tools/exp_tool.rb +48 -0
  59. data/lib/bayonetta/tools/mot_convert_wiiu_pc.rb +33 -0
  60. data/lib/bayonetta/tools/mot_tool.rb +60 -0
  61. data/lib/bayonetta/tools/pkz_extractor.rb +75 -0
  62. data/lib/bayonetta/tools/scr_creator.rb +63 -0
  63. data/lib/bayonetta/tools/scr_extractor.rb +78 -0
  64. data/lib/bayonetta/tools/wmb_cleanup.rb +250 -0
  65. data/lib/bayonetta/tools/wmb_common_bones.rb +45 -0
  66. data/lib/bayonetta/tools/wmb_convert_pc_switch.rb +35 -0
  67. data/lib/bayonetta/tools/wmb_convert_wiiu_pc.rb +33 -0
  68. data/lib/bayonetta/tools/wmb_export_assimp.rb +479 -0
  69. data/lib/bayonetta/tools/wmb_get_bone_map.rb +50 -0
  70. data/lib/bayonetta/tools/wmb_import_assimp.rb +735 -0
  71. data/lib/bayonetta/tools/wmb_import_geometry_wiiu_pc.rb +472 -0
  72. data/lib/bayonetta/tools/wmb_import_nier.rb +309 -0
  73. data/lib/bayonetta/tools/wtb_convert_wiiu_pc.rb +95 -0
  74. data/lib/bayonetta/tools/wtb_import_textures.rb +103 -0
  75. data/lib/bayonetta/tools/wtx_creator.rb +69 -0
  76. data/lib/bayonetta/tools/wtx_extractor.rb +85 -0
  77. data/lib/bayonetta/vertex_types.yaml +213 -0
  78. data/lib/bayonetta/vertex_types2.yaml +164 -0
  79. data/lib/bayonetta/vertex_types_nier.yaml +145 -0
  80. data/lib/bayonetta/wmb.rb +2443 -0
  81. data/lib/bayonetta/wmb3.rb +759 -0
  82. data/lib/bayonetta/wtb.rb +481 -0
  83. data/lib/bayonetta.rb +60 -0
  84. metadata +254 -0
@@ -0,0 +1,63 @@
1
+ module Bayonetta
2
+
3
+ class PKZFile < LibBin::Structure
4
+
5
+ class FileDescriptor < LibBin::Structure
6
+ uint32 :offset_name
7
+ uint32 :offset_compression
8
+ uint64 :size
9
+ uint64 :offset
10
+ uint64 :compressed_size
11
+ string :name, offset: 'offset_name + ..\header.offset_file_descriptors + ..\header.num_files * 0x20'
12
+ string :compression, offset: 'offset_compression + ..\header.offset_file_descriptors + ..\header.num_files * 0x20'
13
+ end
14
+
15
+ class Header < LibBin::Structure
16
+ uint32 :id
17
+ int32 :unknown
18
+ uint64 :size
19
+ uint32 :num_files
20
+ uint32 :offset_file_descriptors
21
+ uint32 :length_file_name_table
22
+ uint32 :unknown
23
+ end
24
+
25
+ register_field :header, Header
26
+ register_field :file_descriptors, FileDescriptor, count: 'header.num_files',
27
+ offset: 'header.offset_file_descriptors + __iterator * 0x20', sequence: true
28
+
29
+ def self.is_big?(f)
30
+ f.rewind
31
+ block = lambda { |int64|
32
+ id = f.read(4)
33
+ raise "Invalid id #{id.inspect}!" if id != "pkzl".b
34
+ f.read(4)
35
+ size = f.read(8).unpack(int64).first
36
+ size == f.size
37
+ }
38
+ big = block.call("q>")
39
+ f.rewind
40
+ small = block.call("q<")
41
+ f.rewind
42
+ raise "Invalid data!" unless big ^ small
43
+ return big
44
+ end
45
+
46
+ def self.load(input_name)
47
+ if input_name.respond_to?(:read) && input_name.respond_to?(:seek)
48
+ input = input_name
49
+ else
50
+ input = File.open(input_name, "rb")
51
+ end
52
+ input_big = is_big?(input)
53
+ pkz = self::new
54
+ pkz.instance_variable_set(:@__was_big, input_big)
55
+ pkz.__load(input, input_big)
56
+ input.close unless input_name.respond_to?(:read) && input_name.respond_to?(:seek)
57
+
58
+ pkz
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,393 @@
1
+ module Bayonetta
2
+ class SCR2File
3
+ include Alignment
4
+ include Endianness
5
+ attr_reader :big
6
+ attr_accessor :unknown
7
+ attr_accessor :models_metadata
8
+
9
+ ALIGNMENTS = {
10
+ 'wmb' => 0x80,
11
+ }
12
+
13
+ def bayo2?
14
+ true
15
+ end
16
+
17
+ def self.is_bayo?(f)
18
+ f.rewind
19
+ id = f.read(4)
20
+ raise "Invalid id #{id.inspect}!" if id != "SCR\0".b
21
+ a, b = f.read(4).unpack("S2")
22
+ f.rewind
23
+ a == 0 || b == 0
24
+ end
25
+
26
+ def self.is_big?(f)
27
+ f.rewind
28
+ block = lambda { |int, short|
29
+ id = f.read(4)
30
+ raise "Invalid id #{id.inspect}!" if id != "SCR\0".b
31
+ unknown = f.read(2).unpack(short).first
32
+ model_number = f.read(2).unpack(short).first
33
+ offset_model_offsets = f.read(4).unpack(int).first
34
+ unknown >= 0 && model_number >=0 && (model_number * 0x8c + 0x10) < f.size &&
35
+ offset_model_offsets >= 0 && offset_model_offsets < f.size
36
+ }
37
+ big = block.call("l>", "s>")
38
+ f.rewind
39
+ small = block.call("l<", "s<")
40
+ f.rewind
41
+ raise "Invalid data!" unless big ^ small
42
+ return big
43
+ end
44
+
45
+ def initialize(f = nil, big = false)
46
+ @big = big
47
+ if f
48
+ file_name_input = false
49
+ unless f.respond_to?(:read) && f.respond_to?(:seek)
50
+ file_name_input = true
51
+ f = File::new(f, "rb")
52
+ end
53
+ @big = SCR2File.is_big?(f)
54
+
55
+ f.rewind
56
+ uint = get_uint
57
+ ushort = get_ushort
58
+ float = get_float
59
+ short = get_short
60
+
61
+ @id = f.read(4)
62
+ raise "Invalid id #{id.inspect}!" if @id != "SCR\0".b
63
+ @unknown, @num_models = f.read(4).unpack("#{ushort}2")
64
+ @offset_offsets_models = f.read(4).unpack(uint).first
65
+
66
+ f.seek(@offset_offsets_models)
67
+ @offsets_models_meta = f.read(4*@num_models).unpack("#{uint}#{@num_models}")
68
+ @offsets_models = []
69
+ @sizes_models = []
70
+
71
+
72
+ @models_metadata = @num_models.times.collect { |i|
73
+ f.seek(@offsets_models_meta[i])
74
+ offset = f.read(4).unpack(uint).first
75
+ name = f.read(64)
76
+ transform = f.read(4*9).unpack("#{float}9")
77
+ u_a = f.read(18*2).unpack("#{short}18")
78
+ @offsets_models.push(offset)
79
+ {
80
+ name: name,
81
+ transform: transform,
82
+ u_a: u_a
83
+ }
84
+ }
85
+ @num_models.times { |i|
86
+ if i == ( @num_models - 1 )
87
+ @sizes_models.push( f.size - @offsets_models[i] )
88
+ else
89
+ @sizes_models.push( @offsets_models_meta[i+1] - @offsets_models[i] )
90
+ end
91
+ }
92
+ @models = @num_models.times.collect { |i|
93
+ f.seek(@offsets_models[i])
94
+ StringIO::new( f.read(@sizes_models[i]), "rb")
95
+ }
96
+ @total_size = f.size
97
+ f.close if file_name_input
98
+ else
99
+ @id = "SCR\0".b
100
+ @unknown = 0x12
101
+ @num_models = 0
102
+ @offsets_models = []
103
+ @sizes_models = []
104
+ @models_metadata = []
105
+ @offsets_models_meta = []
106
+ @models = []
107
+ @total_size = 0
108
+ @offset_offsets_models = 0x10
109
+ end
110
+ end
111
+
112
+ def each_model
113
+ if block_given? then
114
+ @num_models.times { |i|
115
+ yield @models[i]
116
+ }
117
+ else
118
+ to_enum(:each_model)
119
+ end
120
+ end
121
+
122
+ def [](i)
123
+ return @models[i]
124
+ end
125
+
126
+ def invalidate_layout
127
+ @offsets_models = []
128
+ @offsets_models_meta = []
129
+ @total_size = 0
130
+ self
131
+ end
132
+
133
+ def compute_layout
134
+ invalidate_layout
135
+ current_offset = @offset_offsets_models + 0x4 * @num_models
136
+ @num_models.times { |i|
137
+ current_offset = align(current_offset, 0x20)
138
+ @offsets_models_meta.push(current_offset)
139
+ current_offset += 0x8c
140
+ current_offset = align(current_offset, ALIGNMENTS["wmb"])
141
+ @offsets_models.push(current_offset)
142
+ current_offset += @sizes_models[i]
143
+ }
144
+ @total_size = align(current_offset, 0x20)
145
+ self
146
+ end
147
+
148
+ def push_model(file)
149
+ invalidate_layout
150
+ @models.push file
151
+ @sizes_models.push file.size
152
+ @num_models += 1
153
+ self
154
+ end
155
+
156
+ def textures
157
+ nil
158
+ end
159
+
160
+ def dump(name)
161
+ compute_layout
162
+ uint = get_uint
163
+ ushort = get_ushort
164
+ File.open(name,"wb") { |f|
165
+ f.write("\0"*@total_size)
166
+ f.rewind
167
+ f.write([@id].pack("a4"))
168
+ f.write([@unknown].pack(ushort))
169
+ f.write([@num_models].pack(ushort))
170
+ f.write([@offset_offsets_models].pack(uint))
171
+ f.seek(@offset_offsets_models)
172
+ f.write(@offsets_models_meta.pack("#{uint}#{@num_models}"))
173
+ @num_models.times { |i|
174
+ f.seek(@offsets_models_meta[i])
175
+ f.write([@offsets_models[i]].pack(uint))
176
+ f.write([@models_metadata[i][:name]].pack("a64"))
177
+ f.write(@models_metadata[i][:transform].pack("#{get_float}9"))
178
+ f.write(@models_metadata[i][:u_a].pack("#{get_short}18"))
179
+ f.seek(@offsets_models[i])
180
+ @models[i].rewind
181
+ f.write(@models[i].read)
182
+ }
183
+ }
184
+ self
185
+ end
186
+
187
+ end
188
+
189
+ class SCRFile
190
+ include Alignment
191
+ include Endianness
192
+ attr_reader :big
193
+ attr_accessor :unknown
194
+ attr_accessor :models_metadata
195
+
196
+ ALIGNMENTS = {
197
+ 'wmb' => 0x20,
198
+ 'wtb' => 0x1000,
199
+ }
200
+
201
+ def bayo2?
202
+ false
203
+ end
204
+
205
+ def self.is_big?(f)
206
+ f.rewind
207
+ block = lambda { |int|
208
+ id = f.read(4)
209
+ raise "Invalid id #{id.inspect}!" if id != "SCR\0".b
210
+ model_number = f.read(4).unpack(int).first
211
+ offset_texture = f.read(4).unpack(int).first
212
+ ( model_number >= 0 ) && ( (model_number * 0x8c + 0x10) < f.size ) && ( offset_texture >= 0 ) && ( offset_texture < f.size )
213
+ }
214
+ big = block.call("l>")
215
+ f.rewind
216
+ small = block.call("l<")
217
+ f.rewind
218
+ raise "Invalid data!" unless big ^ small
219
+ return big
220
+ end
221
+
222
+ def self.is_bayo2?(f)
223
+ f.rewind
224
+ id = f.read(4)
225
+ raise "Invalid id #{id.inspect}!" if id != "SCR\0".b
226
+ a, b = f.read(4).unpack("S2")
227
+ f.rewind
228
+ a > 0 && b > 0
229
+ end
230
+
231
+ def self.load(f)
232
+ file_name_input = false
233
+ unless f.respond_to?(:read) && f.respond_to?(:seek)
234
+ f = File::new(f, "rb")
235
+ file_name_input = true
236
+ end
237
+ if is_bayo2?(f)
238
+ scr = SCR2File::new(f)
239
+ else
240
+ scr = SCRFile::new(f)
241
+ end
242
+ f.close if file_name_input
243
+ scr
244
+ end
245
+
246
+ def initialize(f = nil, big = false)
247
+ @big = big
248
+ if f
249
+ file_name_input = false
250
+ unless f.respond_to?(:read) && f.respond_to?(:seek)
251
+ file_name_input = true
252
+ f = File::new(f, "rb")
253
+ end
254
+ @big = SCRFile.is_big?(f)
255
+
256
+ f.rewind
257
+ uint = get_uint
258
+
259
+ @id = f.read(4)
260
+ raise "Invalid id #{id.inspect}!" if @id != "SCR\0".b
261
+ @num_models = f.read(4).unpack(uint).first
262
+ @offset_texture = f.read(4).unpack(uint).first
263
+ @unknown = f.read(4)
264
+ flt = get_float
265
+ sh = get_short
266
+ @offsets_models = []
267
+ @sizes_models = []
268
+ @models_metadata = @num_models.times.collect {
269
+ pos = f.tell
270
+ name = f.read(16)
271
+ offset = f.read(4).unpack(uint).first
272
+ transform = f.read(4*9).unpack("#{flt}9")
273
+ u_a = f.read(42*2).unpack("#{sh}42")
274
+ @offsets_models.push(pos + offset)
275
+ {
276
+ name: name,
277
+ transform: transform,
278
+ u_a: u_a
279
+ }
280
+ }
281
+ @num_models.times { |i|
282
+ if i == ( @num_models - 1 )
283
+ @sizes_models.push( @offset_texture - @offsets_models[i] )
284
+ else
285
+ @sizes_models.push( @offsets_models[i+1] - @offsets_models[i] )
286
+ end
287
+ }
288
+ @size_textures = f.size - @offset_texture
289
+ @models = @num_models.times.collect { |i|
290
+ f.seek(@offsets_models[i])
291
+ StringIO::new( f.read(@sizes_models[i]), "rb")
292
+ }
293
+ f.seek(@offset_texture)
294
+ @textures = StringIO::new( f.read(@size_textures), "rb")
295
+ @total_size = f.size
296
+ f.close if file_name_input
297
+ else
298
+ @id = "SCR\0".b
299
+ @num_models = 0
300
+ @offset_texture = 0
301
+ @size_textures = 0
302
+ @unknown = "\1\0\0\0".b
303
+ @offsets_models = []
304
+ @sizes_models = []
305
+ @models_metadata = []
306
+ @models = []
307
+ @textures = nil
308
+ @total_size = 0
309
+ end
310
+ end
311
+
312
+ def each_model
313
+ if block_given? then
314
+ @num_models.times { |i|
315
+ yield @models[i]
316
+ }
317
+ else
318
+ to_enum(:each_model)
319
+ end
320
+ end
321
+
322
+ def [](i)
323
+ return @models[i]
324
+ end
325
+
326
+ def invalidate_layout
327
+ @offsets_models = []
328
+ @offset_texture = 0
329
+ @total_size = 0
330
+ self
331
+ end
332
+
333
+ def compute_layout
334
+ current_offset = 0x10 + 0x8c * @num_models
335
+ @offsets_models = @num_models.times.collect { |i|
336
+ tmp = align(current_offset, ALIGNMENTS["wmb"])
337
+ current_offset = tmp + @sizes_models[i]
338
+ tmp
339
+ }
340
+ @offset_texture = align(current_offset, ALIGNMENTS["wtb"])
341
+ @total_size = @offset_texture + @size_textures
342
+ self
343
+ end
344
+
345
+ def push_model(file)
346
+ invalidate_layout
347
+ @models.push file
348
+ @sizes_models.push file.size
349
+ @num_models += 1
350
+ self
351
+ end
352
+
353
+ def textures=(file)
354
+ invalidate_layout
355
+ @textures = file
356
+ @size_textures = file.size
357
+ self
358
+ end
359
+
360
+ def textures
361
+ @textures
362
+ end
363
+
364
+ def dump(name)
365
+ compute_layout
366
+ uint = get_uint
367
+ File.open(name,"wb") { |f|
368
+ f.write("\0"*@total_size)
369
+ f.rewind
370
+ f.write([@id].pack("a4"))
371
+ f.write([@num_models].pack(uint))
372
+ f.write([@offset_texture].pack(uint))
373
+ f.write([@unknown].pack("a4"))
374
+ @num_models.times { |i|
375
+ pos = f.tell
376
+ f.write([@models_metadata[i][:name]].pack("a16"))
377
+ f.write([@offsets_models[i] - pos].pack(uint))
378
+ f.write(@models_metadata[i][:transform].pack("#{get_float}9"))
379
+ f.write(@models_metadata[i][:u_a].pack("#{get_short}42"))
380
+ }
381
+ @offsets_models.each_with_index { |off, i|
382
+ f.seek(off)
383
+ @models[i].rewind
384
+ f.write(@models[i].read)
385
+ }
386
+ f.seek(@offset_texture)
387
+ @textures.rewind
388
+ f.write(@textures.read)
389
+ }
390
+ self
391
+ end
392
+ end
393
+ end
@@ -0,0 +1,23 @@
1
+ require 'optparse'
2
+ require_relative '../../bayonetta'
3
+ include Bayonetta
4
+
5
+ OptionParser.new do |opts|
6
+ opts.banner = <<EOF
7
+ Usage: bxm_decoder target_file
8
+ Decode the target bxm file into xml
9
+
10
+ EOF
11
+ opts.on("-h", "--help", "Prints this help") do
12
+ puts opts
13
+ exit
14
+ end
15
+
16
+ end.parse!
17
+
18
+ input_file = ARGV[0]
19
+
20
+ File::open(input_file, "rb") { |f|
21
+ bxm = BXMFile::load(f)
22
+ print bxm.to_xml
23
+ }
@@ -0,0 +1,37 @@
1
+ require 'optparse'
2
+ require 'nokogiri'
3
+ require_relative '../../bayonetta'
4
+ include Bayonetta
5
+
6
+ options = {
7
+ tag: :BXM,
8
+ output: nil
9
+ }
10
+
11
+ opts = OptionParser.new do |parser|
12
+ parser.banner = <<EOF
13
+ Usage: bxm_encoder [options] [XML_FILE]
14
+ Encode the pecified xml file int binary xml format. Unlessspecified
15
+ output will be along with the original file with a bxm extension.
16
+ If no file is given use stdin, but --output must be specified.
17
+ EOF
18
+ parser.on("-t", "--tag TAG", [:XML, :BXM], "Select tag to use (BXM, XML) default BXM")
19
+ parser.on("-o", "--output filename", "Select output file name")
20
+ end
21
+ opts.parse!(into: options)
22
+
23
+ tag = (options[:tag].to_s + "\0").b
24
+
25
+ output_name = options[:output]
26
+ if ARGV[0]
27
+ ouput_name = File.join(File.dirname(ARGV[0]), File.basename(ARGV[0], File.extname(ARGV[0])))+".bxm" unless output_name
28
+ input_file = File::open(ARGV[0], "rb")
29
+ else
30
+ raise "unspecified output file" unless output_name
31
+ input_file = $stdin
32
+ end
33
+
34
+ bxm = BXMFile::from_xml(Nokogiri::XML(input_file.read), tag)
35
+ bxm.dump(output_name)
36
+
37
+ input_file.close if ARGV[0]
@@ -0,0 +1,60 @@
1
+ require 'optparse'
2
+ require_relative '../../bayonetta'
3
+ require 'yaml'
4
+ include Bayonetta
5
+ $bone_map = { }
6
+ $options = {
7
+ remap_bones: false,
8
+ output: nil
9
+ }
10
+ OptionParser.new do |opts|
11
+ opts.banner = <<EOF
12
+ Usage: clh_convert target_file [options]
13
+ Convert a Bayonetta 2 _clh.bxm file to bayonetta format, optionally
14
+ remapping the bones, or remap a Bayonetta 1 clh file. By default
15
+ output will be in the ./clx_output folder.
16
+ EOF
17
+
18
+ opts.on("-r", "--remap-bones=BONELISTS", "Remap specified bones, either lists separated by / or a yaml hash table") do |bone_lists|
19
+ $options[:remap_bones] = true
20
+ if File::exist?(bone_lists)
21
+ $bone_map.merge! YAML::load_file(bone_lists)
22
+ else
23
+ lists = bone_lists.split("/")
24
+ p input_list = eval(lists.first).to_a
25
+ p output_list = eval(lists.last).to_a
26
+ $bone_map.merge! input_list.zip(output_list).to_h
27
+ end
28
+ end
29
+
30
+ opts.on("-o", "--output=filename", "file to output result") do |name|
31
+ $options[:output] = name
32
+ end
33
+
34
+ opts.on("-h", "--help", "Prints this help") do
35
+ puts opts
36
+ exit
37
+ end
38
+
39
+ end.parse!
40
+
41
+ $bone_map.merge!( { 4095 => 4095 } )
42
+
43
+ Dir.mkdir("clx_output") unless Dir.exist?("clx_output")
44
+
45
+ input_file = ARGV[0]
46
+ raise "Invalid file #{input_file}" unless input_file && File::file?(input_file)
47
+
48
+ output_file = $options[:output]
49
+
50
+ if File.extname(ARGV[0]) == ".bxm"
51
+ raise "Invalid clh file #{input_file}" unless File.basename(ARGV[0]).end_with?("_clh.bxm")
52
+ output_file = File.join("clx_output", File.basename(ARGV[0]).gsub("_clh.bxm",".clh")) unless output_file
53
+ clh = CLHFile::load_bxm(input_file)
54
+ else
55
+ raise "Invalid clh file #{input_file}" unless File.basename(ARGV[0]).end_with?(".clh")
56
+ output_file = File.join("clx_output", File.basename(ARGV[0])) unless output_file
57
+ clh = CLHFile::load(input_file)
58
+ end
59
+ clh.remap($bone_map) if $options[:remap_bones]
60
+ clh.dump(output_file)
@@ -0,0 +1,70 @@
1
+ require 'optparse'
2
+ require_relative '../../bayonetta'
3
+ require 'yaml'
4
+ include Bayonetta
5
+ $bone_map = { }
6
+ $options = {
7
+ remap_bones: false,
8
+ fix: true,
9
+ poly: true,
10
+ output: nil
11
+ }
12
+ OptionParser.new do |opts|
13
+ opts.banner = <<EOF
14
+ Usage: clp_convert target_file [options]
15
+ Convert a Bayonetta 2 _clp.bxm file to bayonetta format, optionally
16
+ remapping the bones, or remap a Bayonetta 1 clp file. By default
17
+ output will be in the ./clx_output folder.
18
+ EOF
19
+
20
+ opts.on("-r", "--remap-bones=BONELISTS", "Remap specified bones, either lists separated by / or a yaml hash table") do |bone_lists|
21
+ $options[:remap_bones] = true
22
+ if File::exist?(bone_lists)
23
+ $bone_map.merge! YAML::load_file(bone_lists)
24
+ else
25
+ lists = bone_lists.split("/")
26
+ p input_list = eval(lists.first).to_a
27
+ p output_list = eval(lists.last).to_a
28
+ $bone_map.merge! input_list.zip(output_list).to_h
29
+ end
30
+ end
31
+
32
+ opts.on("-f", "--[no-]fix", "Map no_fix values (default true)") do |fix|
33
+ $options[:fix] = fix
34
+ end
35
+
36
+ opts.on("-p", "--[no-]poly", "Map no_poly values (default true)") do |poly|
37
+ $options[:poly] = poly
38
+ end
39
+
40
+ opts.on("-o", "--output=filename", "file to output result") do |name|
41
+ $options[:output] = name
42
+ end
43
+
44
+ opts.on("-h", "--help", "Prints this help") do
45
+ puts opts
46
+ exit
47
+ end
48
+
49
+ end.parse!
50
+
51
+ $bone_map.merge!( { 4095 => 4095 } )
52
+
53
+ Dir.mkdir("clx_output") unless Dir.exist?("clx_output")
54
+
55
+ input_file = ARGV[0]
56
+ raise "Invalid file #{input_file}" unless input_file && File::file?(input_file)
57
+
58
+ output_file = $options[:output]
59
+
60
+ if File.extname(ARGV[0]) == ".bxm"
61
+ raise "Invalid clp file #{input_file}" unless File.basename(ARGV[0]).end_with?("_clp.bxm")
62
+ output_file = File.join("clx_output", File.basename(ARGV[0]).gsub("_clp.bxm",".clp")) unless output_file
63
+ clp = CLPFile::load_bxm(input_file)
64
+ else
65
+ raise "Invalid clp file #{input_file}" unless File.basename(ARGV[0]).end_with?(".clp")
66
+ output_file = File.join("clx_output", File.basename(ARGV[0])) unless output_file
67
+ clp = CLPFile::load(input_file)
68
+ end
69
+ clp.remap($bone_map, $options[:poly], $options[:fix]) if $options[:remap_bones]
70
+ clp.dump(output_file)
@@ -0,0 +1,60 @@
1
+ require 'optparse'
2
+ require_relative '../../bayonetta'
3
+ require 'yaml'
4
+ include Bayonetta
5
+ $bone_map = { }
6
+ $options = {
7
+ remap_bones: false,
8
+ output: nil
9
+ }
10
+ OptionParser.new do |opts|
11
+ opts.banner = <<EOF
12
+ Usage: clw_convert target_file [options]
13
+ Convert a Bayonetta 2 _clw.bxm file to bayonetta format, optionally
14
+ remapping the bones, or remap a Bayonetta 1 clw file. By default
15
+ output will be in the ./clx_output folder.
16
+ EOF
17
+
18
+ opts.on("-r", "--remap-bones=BONELISTS", "Remap specified bones, either lists separated by / or a yaml hash table") do |bone_lists|
19
+ $options[:remap_bones] = true
20
+ if File::exist?(bone_lists)
21
+ $bone_map.merge! YAML::load_file(bone_lists)
22
+ else
23
+ lists = bone_lists.split("/")
24
+ p input_list = eval(lists.first).to_a
25
+ p output_list = eval(lists.last).to_a
26
+ $bone_map.merge! input_list.zip(output_list).to_h
27
+ end
28
+ end
29
+
30
+ opts.on("-o", "--output=filename", "file to output result") do |name|
31
+ $options[:output] = name
32
+ end
33
+
34
+ opts.on("-h", "--help", "Prints this help") do
35
+ puts opts
36
+ exit
37
+ end
38
+
39
+ end.parse!
40
+
41
+ $bone_map.merge!( { -1 => -1 } )
42
+
43
+ Dir.mkdir("clx_output") unless Dir.exist?("clx_output")
44
+
45
+ input_file = ARGV[0]
46
+ raise "Invalid file #{input_file}" unless input_file && File::file?(input_file)
47
+
48
+ output_file = $options[:output]
49
+
50
+ if File.extname(ARGV[0]) == ".bxm"
51
+ raise "Invalid clw file #{input_file}" unless File.basename(ARGV[0]).end_with?("_clw.bxm")
52
+ output_file = File.join("clx_output", File.basename(ARGV[0]).gsub("_clw.bxm",".clw")) unless output_file
53
+ clw = CLWFile::load_bxm(input_file)
54
+ else
55
+ raise "Invalid clw file #{input_file}" unless File.basename(ARGV[0]).end_with?(".clw")
56
+ output_file = File.join("clx_output", File.basename(ARGV[0])) unless output_file
57
+ clw = CLWFile::load(input_file)
58
+ end
59
+ clw.remap($bone_map) if $options[:remap_bones]
60
+ clw.dump(output_file)