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,314 @@
1
+ require 'stringio'
2
+
3
+ module Bayonetta
4
+
5
+ class EFFFile
6
+ include Endianness
7
+ include Alignment
8
+
9
+ class Directory
10
+ include Endianness
11
+ include Alignment
12
+
13
+ private :get_uint
14
+ attr_accessor :file_number
15
+ attr_accessor :file_infos
16
+ attr_accessor :files
17
+ attr_reader :big
18
+ attr_reader :name
19
+
20
+ EXTENSIONS = {
21
+ "TEX\0".b => "wtb",
22
+ "MOD\0".b => "dat"
23
+ }
24
+ ALIGNMENT = {
25
+ "TEX\0".b => 0x1000,
26
+ "MOD\0".b => 0x1000,
27
+ "EST\0".b => 0x10,
28
+ "IDT\0".b => 0x10
29
+ }
30
+ KNOWN_DIRECTORIES = [
31
+ "SAD\0".b,
32
+ "SST\0".b,
33
+ "TUV\0".b,
34
+ "TEX\0".b,
35
+ "MOD\0".b,
36
+ "EST\0".b
37
+ ]
38
+ KNOWN_STRUCTURE = [
39
+ "TEX\0".b,
40
+ "MOD\0".b,
41
+ "EST\0".b,
42
+ "IDT\0".b
43
+ ]
44
+
45
+ UNKNOWN_STRUCTURE = KNOWN_DIRECTORIES - KNOWN_STRUCTURE
46
+
47
+ def initialize(f, big)
48
+ @big = big
49
+ if f
50
+ @name = f.read(4)
51
+ case @name
52
+ when *UNKNOWN_STRUCTURE
53
+ f.rewind
54
+ @file_number = 1
55
+ @file_infos = [[0, 0, f.size]]
56
+ @files = [f]
57
+ when *KNOWN_STRUCTURE
58
+ uint = get_uint
59
+ @file_number = f.read(4).unpack(uint).first
60
+ @file_infos = @file_number.times.collect { |i|
61
+ f.read(8).unpack("#{uint}2")
62
+ }
63
+ sorted_file_infos = @file_infos.sort { |e1, e2| e1[1] <=> e2[1] }
64
+ sorted_file_infos.each_with_index { |info, i|
65
+ id, offset = info
66
+ if sorted_file_infos[i+1]
67
+ size = sorted_file_infos[i+1][1] - offset
68
+ else
69
+ size = f.size - offset
70
+ end
71
+ info.push(size)
72
+ }
73
+ @files = @file_infos.collect { |id, offset, size|
74
+ f.seek(offset)
75
+ of = StringIO::new( f.read(size), "rb")
76
+ }
77
+ else
78
+ raise "Unknown directory type: #{@name}!"
79
+ end
80
+ @extname = EXTENSIONS[@name]
81
+ @extname = @name.delete("\x00").downcase unless @extname
82
+ else
83
+ @name = nil
84
+ @file_number = 0
85
+ @file_infos = []
86
+ @files = []
87
+ end
88
+ end
89
+
90
+ def each
91
+ if block_given?
92
+ @file_number.times { |i|
93
+ yield ("%010d." % @file_infos[i][0])+@extname, @files[i]
94
+ }
95
+ else
96
+ to_enum(:each)
97
+ end
98
+ end
99
+
100
+ def push(id, f)
101
+ f.rewind
102
+ sz = f.size
103
+ of = StringIO::new( f.read, "rb")
104
+ @file_number += 1
105
+ @files.push of
106
+ @file_infos.push [id, nil, sz]
107
+ self
108
+ end
109
+
110
+ def name
111
+ @name.delete("\x00")
112
+ end
113
+
114
+ def name=(s)
115
+ s = s + "\x00"
116
+ @name = s
117
+ end
118
+
119
+ def compute_layout
120
+ case @name
121
+ when *UNKNOWN_STRUCTURE
122
+ raise "Unsupported file number #{@file_number}!" unless @file_number == 1
123
+ @file_infos[0][1] = 0x0
124
+ @file_infos[0][2]
125
+ when *KNOWN_STRUCTURE
126
+ current_offset = align(4 + 4 + @file_infos.length * 8, ALIGNMENT[@name])
127
+ @file_infos = @file_infos.collect { |id, _, size|
128
+ ret = [id, current_offset, size]
129
+ current_offset += size
130
+ current_offset = align(current_offset, ALIGNMENT[@name])
131
+ ret
132
+ }
133
+ current_offset
134
+ else
135
+ raise "Invalid directory #{@name}!"
136
+ end
137
+ end
138
+
139
+ def size
140
+ compute_layout
141
+ end
142
+
143
+ def to_stringio
144
+ total_size = compute_layout
145
+ str = StringIO::new("\x00".b*total_size, "w+b")
146
+ str.rewind
147
+
148
+ case @name
149
+ when *UNKNOWN_STRUCTURE
150
+ f = @files[0]
151
+ f.rewind
152
+ str.write f.read
153
+ f.rewind
154
+ when *KNOWN_STRUCTURE
155
+ uint = get_uint
156
+ str.write @name
157
+ str.write [@file_number].pack(uint)
158
+ @file_infos.each { |id, offset, _|
159
+ str.write [id, offset].pack("#{uint}*")
160
+ }
161
+ @file_number.times { |i|
162
+ str.seek(@file_infos[i][1])
163
+ f = @files[i]
164
+ f.rewind
165
+ str.write f.read
166
+ f.rewind
167
+ }
168
+ end
169
+ str.rewind
170
+ str.close_write
171
+ str
172
+ end
173
+
174
+ end #Directory
175
+
176
+ attr_reader :big
177
+ attr_accessor :layout
178
+ attr_accessor :id
179
+
180
+ def self.check_id(id)
181
+ raise "Invalid id #{id.inspect}!" unless id == "EF2\0".b || id == "IDD\0".b
182
+ end
183
+
184
+ def self.is_big?(f)
185
+ f.rewind
186
+ block = lambda { |int|
187
+ id = f.read(4)
188
+ self.check_id(id)
189
+ directory_number = f.read(4).unpack(int).first
190
+ if directory_number * 8 + 8 < f.size
191
+ directory_infos = directory_number.times.collect {
192
+ f.read(8).unpack("#{int}2")
193
+ }
194
+ ( directory_number >= 0 ) && directory_infos.reduce(true) { |memo, (index, offset)|
195
+ memo && index >= 0 && offset > 0 && offset < f.size
196
+ }
197
+ else
198
+ false
199
+ end
200
+ }
201
+ big = block.call("l>")
202
+ f.rewind
203
+ small = block.call("l<")
204
+ f.rewind
205
+ raise "Invalid data!" unless big ^ small
206
+ return big
207
+ end
208
+
209
+ def check_id
210
+ EFFFile.check_id(@id)
211
+ end
212
+
213
+ def initialize(f = nil, big = false, id = "EF2\0".b)
214
+ @big = big
215
+ if f
216
+ file_name_input = false
217
+ unless f.respond_to?(:read) && f.respond_to?(:seek)
218
+ file_name_input = true
219
+ f = File::new(f, "rb")
220
+ end
221
+ @big = EFFFile.is_big?(f)
222
+ uint = get_uint
223
+ @id = f.read(4)
224
+ check_id
225
+ @directory_number = f.read(4).unpack(uint).first
226
+ @directory_number += 1 if @id == "IDD\0".b
227
+ @directory_infos = @directory_number.times.collect {
228
+ f.read(8).unpack("#{uint}2")
229
+ }
230
+ sorted_directory_infos = @directory_infos.sort { |e1, e2| e1[1] <=> e2[1] }
231
+ sorted_directory_infos.each_with_index { |info, i|
232
+ id, offset = info
233
+ if sorted_directory_infos[i+1]
234
+ size = sorted_directory_infos[i+1][1] - offset
235
+ else
236
+ size = f.size - offset
237
+ end
238
+ info.push(size)
239
+ }
240
+ @directories = @directory_infos.collect { |id, offset, size|
241
+ f.seek(offset)
242
+ of = StringIO::new( f.read(size), "rb")
243
+ Directory::new(of, @big)
244
+ }
245
+ @layout = @directories.each_with_index.collect { |d, i|
246
+ [ @directory_infos[i][0] , d.name]
247
+ }
248
+ else
249
+ @id = id
250
+ @directory_number = 0
251
+ @directory_infos = []
252
+ @directories = []
253
+ @layout = nil
254
+ end
255
+
256
+ end
257
+
258
+ def push(id, d)
259
+ @directories.push(d)
260
+ @directory_infos.push [id, nil]
261
+ @directory_number += 1
262
+ self
263
+ end
264
+
265
+ def compute_layout
266
+ current_offset = 0x1000
267
+ @directory_number.times { |i|
268
+ @directory_infos[i][1] = current_offset
269
+ current_offset += @directories[i].size
270
+ current_offset = align(current_offset, 0x1000)
271
+ }
272
+ current_offset
273
+ end
274
+
275
+ def to_stringio
276
+ total_size = compute_layout
277
+ str = StringIO::new("\x00".b*total_size, "w+b")
278
+ str.rewind
279
+
280
+ uint = get_uint
281
+
282
+ str.write @id
283
+ if @id == "IDD\0".b
284
+ str.write [@directory_number-1].pack(uint)
285
+ else
286
+ str.write [@directory_number].pack(uint)
287
+ end
288
+ @directory_infos.each { |inf|
289
+ str.write inf.pack("#{uint}*")
290
+ }
291
+ @directory_number.times { |i|
292
+ str.seek(@directory_infos[i][1])
293
+ f = @directories[i].to_stringio
294
+ str.write f.read
295
+ }
296
+
297
+ str.rewind
298
+ str.close_write
299
+ str
300
+ end
301
+
302
+ def each_directory
303
+ if block_given?
304
+ @directory_number.times { |i|
305
+ yield @directory_infos[i][0], @directories[i]
306
+ }
307
+ else
308
+ to_enum(:each_directory)
309
+ end
310
+ end
311
+
312
+ end
313
+
314
+ end
@@ -0,0 +1,53 @@
1
+ module Bayonetta
2
+
3
+ module Endianness
4
+
5
+ def get_uint(big = @big)
6
+ uint = "L"
7
+ if big
8
+ uint <<= ">"
9
+ else
10
+ uint <<= "<"
11
+ end
12
+ uint
13
+ end
14
+ private :get_uint
15
+
16
+ def get_float(big = @big)
17
+ if big
18
+ flt = "g"
19
+ else
20
+ flt = "e"
21
+ end
22
+ flt
23
+ end
24
+
25
+ private :get_float
26
+
27
+ def get_short(big = @big)
28
+ sh = "s"
29
+ if big
30
+ sh <<= ">"
31
+ else
32
+ sh <<="<"
33
+ end
34
+ sh
35
+ end
36
+
37
+ private :get_short
38
+
39
+ def get_ushort(big = @big)
40
+ sh = "S"
41
+ if big
42
+ sh <<= ">"
43
+ else
44
+ sh <<="<"
45
+ end
46
+ sh
47
+ end
48
+
49
+ private :get_ushort
50
+
51
+ end
52
+
53
+ end