pgtools 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +25 -25
  3. data/bin/bxm_decoder +2 -2
  4. data/bin/bxm_encoder +2 -2
  5. data/bin/clh_convert +2 -2
  6. data/bin/clp_convert +2 -2
  7. data/bin/clw_convert +2 -2
  8. data/bin/dat_creator +2 -2
  9. data/bin/dat_extractor +2 -2
  10. data/bin/dat_ls +2 -2
  11. data/bin/eff_idd_creator +2 -2
  12. data/bin/eff_idd_extractor +2 -2
  13. data/bin/exp_convert_wiiu_pc +2 -2
  14. data/bin/exp_tool +2 -2
  15. data/bin/mot_convert_wiiu_pc +2 -2
  16. data/bin/mot_tool +2 -2
  17. data/bin/pkz_extractor +2 -2
  18. data/bin/scr_creator +2 -2
  19. data/bin/scr_extractor +2 -2
  20. data/bin/wmb_cleanup +2 -2
  21. data/bin/wmb_common_bones +2 -2
  22. data/bin/wmb_convert_pc_switch +2 -2
  23. data/bin/wmb_convert_wiiu_pc +2 -2
  24. data/bin/wmb_export_assimp +2 -2
  25. data/bin/wmb_get_bone_map +2 -2
  26. data/bin/wmb_import_assimp +2 -2
  27. data/bin/wmb_import_nier +2 -2
  28. data/bin/wmb_import_wiiu +2 -2
  29. data/bin/wtb_convert_wiiu_pc +2 -2
  30. data/bin/wtx_creator +2 -2
  31. data/bin/wtx_extractor +2 -2
  32. data/lib/bayonetta/alignment.rb +0 -0
  33. data/lib/bayonetta/bone.rb +0 -0
  34. data/lib/bayonetta/bxm.rb +180 -180
  35. data/lib/bayonetta/clh.rb +159 -159
  36. data/lib/bayonetta/clp.rb +212 -212
  37. data/lib/bayonetta/clw.rb +166 -166
  38. data/lib/bayonetta/dat.rb +261 -261
  39. data/lib/bayonetta/eff.rb +314 -314
  40. data/lib/bayonetta/endianness.rb +0 -0
  41. data/lib/bayonetta/exp.rb +768 -768
  42. data/lib/bayonetta/linalg.rb +416 -416
  43. data/lib/bayonetta/material_database.yaml +2581 -2581
  44. data/lib/bayonetta/mot.rb +763 -763
  45. data/lib/bayonetta/pkz.rb +63 -63
  46. data/lib/bayonetta/scr.rb +0 -0
  47. data/lib/bayonetta/tools/bxm_decoder.rb +23 -23
  48. data/lib/bayonetta/tools/bxm_encoder.rb +37 -37
  49. data/lib/bayonetta/tools/clh_convert.rb +60 -60
  50. data/lib/bayonetta/tools/clp_convert.rb +70 -70
  51. data/lib/bayonetta/tools/clw_convert.rb +60 -60
  52. data/lib/bayonetta/tools/dat_creator.rb +57 -57
  53. data/lib/bayonetta/tools/dat_extractor.rb +94 -94
  54. data/lib/bayonetta/tools/dat_ls.rb +106 -106
  55. data/lib/bayonetta/tools/eff_idd_creator.rb +66 -66
  56. data/lib/bayonetta/tools/eff_idd_extractor.rb +73 -73
  57. data/lib/bayonetta/tools/exp_convert_wiiu_pc.rb +33 -33
  58. data/lib/bayonetta/tools/exp_tool.rb +48 -48
  59. data/lib/bayonetta/tools/mot_convert_wiiu_pc.rb +33 -33
  60. data/lib/bayonetta/tools/mot_tool.rb +0 -0
  61. data/lib/bayonetta/tools/pkz_extractor.rb +75 -75
  62. data/lib/bayonetta/tools/scr_creator.rb +63 -63
  63. data/lib/bayonetta/tools/scr_extractor.rb +78 -78
  64. data/lib/bayonetta/tools/wmb_cleanup.rb +250 -250
  65. data/lib/bayonetta/tools/wmb_common_bones.rb +45 -45
  66. data/lib/bayonetta/tools/wmb_convert_pc_switch.rb +35 -35
  67. data/lib/bayonetta/tools/wmb_convert_wiiu_pc.rb +33 -33
  68. data/lib/bayonetta/tools/wmb_export_assimp.rb +479 -479
  69. data/lib/bayonetta/tools/wmb_get_bone_map.rb +50 -50
  70. data/lib/bayonetta/tools/wmb_import_assimp.rb +735 -735
  71. data/lib/bayonetta/tools/wmb_import_geometry_wiiu_pc.rb +472 -472
  72. data/lib/bayonetta/tools/wmb_import_nier.rb +309 -309
  73. data/lib/bayonetta/tools/wtb_convert_wiiu_pc.rb +95 -95
  74. data/lib/bayonetta/tools/wtb_import_textures.rb +103 -103
  75. data/lib/bayonetta/tools/wtx_creator.rb +69 -69
  76. data/lib/bayonetta/tools/wtx_extractor.rb +85 -85
  77. data/lib/bayonetta/vertex_types.yaml +0 -0
  78. data/lib/bayonetta/vertex_types2.yaml +0 -0
  79. data/lib/bayonetta/vertex_types_nier.yaml +145 -145
  80. data/lib/bayonetta/wmb.rb +2455 -2443
  81. data/lib/bayonetta/wmb3.rb +759 -759
  82. data/lib/bayonetta/wtb.rb +481 -481
  83. data/lib/bayonetta.rb +60 -60
  84. metadata +2 -2
data/lib/bayonetta/exp.rb CHANGED
@@ -1,768 +1,768 @@
1
- module Bayonetta
2
-
3
- module ExpQuantizedValues
4
- def get_p(i)
5
- @p + @keys[i].cp * @dp
6
- end
7
-
8
- def get_m1(i)
9
- @m1 + @keys[i].cm1 * @dm1
10
- end
11
-
12
- def get_m0(i)
13
- @m0 + @keys[i].cm0 * @dm0
14
- end
15
- end
16
-
17
- module ExpDirectValues
18
- def get_p(i)
19
- @keys[i].p
20
- end
21
-
22
- def get_m1(i)
23
- @keys[i].m1
24
- end
25
-
26
- def get_m0(i)
27
- @keys[i].m0
28
- end
29
- end
30
-
31
- module ExpAbsolutePositions
32
- def key_positions
33
- @key_positions ||= @keys.collect { |k| k.v }
34
- end
35
- end
36
-
37
- module ExpRelativePositions
38
- def key_positions
39
- @key_positions ||= begin
40
- sum = 0
41
- @keys.collect { |k| sum += k.v }
42
- end
43
- end
44
- end
45
-
46
- module ExpKeyInterpolate
47
- def interpol(position, start, stop, key_index)
48
- p_0 = get_p(key_index)
49
- p_1 = get_p(key_index + 1)
50
- m_0 = get_m1(key_index)
51
- m_1 = get_m0(key_index + 1)
52
- t = (value - start).to_f / (stop - start)
53
- t3 = t*t*t
54
- t2 = t*t
55
- (2 * t3 - 3 * t2 + 1)*p_0 + (t3 - 2 * t2 + t)*m_0 + (-2 * t3 + 3 * t2)*p_1 + (t3 - t2)*m_1
56
- end
57
-
58
- def interpolate(position)
59
- if positions <= key_positions.first
60
- get_p(0)
61
- elsif positions >= key_positions.last
62
- get_p(key_positions.length -1)
63
- else
64
- key_positions.each_cons(2).each_with_index { |(start, stop), i|
65
- if position <= stop && position >= start
66
- return interpol(position, start, stop)
67
- end
68
- }
69
- end
70
- end
71
- end
72
-
73
- class EXPFile2 < LibBin::Structure
74
-
75
- class EXPFileHeader < LibBin::Structure
76
- int8 :id, count: 4
77
- int32 :version
78
- uint32 :offset_records
79
- uint32 :num_records
80
- uint32 :offset_interpolations
81
- uint32 :num_interpolations
82
-
83
- def initialize
84
- @id = "exp\0".b
85
- @version = 0x20110714
86
- @offset_records = 0
87
- @num_records = 0
88
- @offset_interpolations = 0
89
- @num_interpolations = 0
90
- end
91
- end
92
-
93
- class Record < LibBin::Structure
94
- int16 :bone_index
95
- int8 :animation_track
96
- int8 :padding
97
- int16 :num_operations
98
- int16 :unknown
99
- uint32 :offset
100
-
101
- def initialize
102
- @bone_index = 0
103
- @animation_track = 0
104
- @padding = 0
105
- @num_operations = 0
106
- @unknown = 0
107
- @offset = 0
108
- end
109
-
110
- end
111
-
112
- class Operation < LibBin::Structure
113
- int8 :type
114
- int8 :info
115
- int16 :number
116
- float :value
117
-
118
- def initialize
119
- @type = 0
120
- @info = 0
121
- @number = 0
122
- @value = 0.0
123
- end
124
-
125
- end
126
-
127
- class Entry < LibBin::Structure
128
- register_field :operations, Operation, count: '..\records[__index]\num_operations'
129
-
130
- def initialize
131
- @operations = []
132
- end
133
-
134
- def abs(v)
135
- v.abs
136
- end
137
-
138
- def get_value(tracks, table, interpolation_entries)
139
- s = ""
140
- @operations.each { |o|
141
- case o.type
142
- when 0
143
- nil
144
- when 1
145
- s << "("
146
- when 2
147
- s << ")"
148
- when 3
149
- s << "tracks[table[#{o.number}]][#{o.info}]"
150
- when 4
151
- s << "#{o.value}"
152
- when 5
153
- case o.number
154
- when 0
155
- s << " + "
156
- when 2
157
- s << " * "
158
- else
159
- raise "Unknown arithmetic operation: #{o.number}!"
160
- end
161
- when 6
162
- raise "Unknown function argument number: #{o.info}!" if o.info != 1
163
- case o.number
164
- when 1
165
- s << "abs("
166
- else
167
- raise "Unknown function: #{o.number}!"
168
- end
169
- when 7
170
- s << ")"
171
- when 8
172
- s << "interpolation_entries[#{o.number}].get_value("
173
- else
174
- raise "Unknown operation: #{o.type}!"
175
- end
176
- }
177
- eval s
178
- end
179
-
180
- end
181
-
182
- class Interpolation < LibBin::Structure
183
- int16 :num_points
184
- int16 :padding
185
- uint32 :offset
186
-
187
- def initialize
188
- @num_points = 0
189
- @padding = 0
190
- @offset = 0
191
- end
192
-
193
- end
194
-
195
- class Point < LibBin::Structure
196
- float :v
197
- float :p
198
- float :m0
199
- float :m1
200
-
201
- def initialize
202
- @v = 0.0
203
- @p = 0.0
204
- @m0 = 0.0
205
- @m1 = 0.0
206
- end
207
-
208
- end
209
-
210
- class InterpolationEntry < LibBin::Structure
211
- register_field :points, Point, count: '..\interpolations[__index]\num_points'
212
-
213
- def get_value(val)
214
- @points.each_cons(2) { |left, right|
215
- if left.v <= val && right.v >= val
216
- p0 = left.p
217
- p1 = right.p
218
- m0 = left.m1
219
- m1 = right.m0
220
- t = (val - left.v).to_f / (right.v - left.v)
221
- return (2 * t*t*t - 3 * t*t + 1)*p0 + (t*t*t - 2 * t*t + t)*m0 + (-2 * t*t*t + 3 * t*t)*p1 + (t*t*t - t * t)*m1
222
- end
223
-
224
- }
225
- return 0.0
226
- end
227
-
228
- end
229
-
230
- register_field :header, EXPFileHeader
231
- register_field :records, Record, count: 'header\num_records', offset: 'header\offset_records'
232
- register_field :entries, Entry, count: 'header\num_records', sequence: true,
233
- offset: 'records[__iterator]\offset + header\offset_records + 12*__iterator'
234
- register_field :interpolations, Interpolation, count: 'header\num_interpolations', offset: 'header\offset_interpolations'
235
- register_field :interpolation_entries, InterpolationEntry, count: 'header\num_interpolations', sequence: true,
236
- offset: 'interpolations[__iterator]\offset + header\offset_interpolations + 8*__iterator'
237
-
238
- def apply(tracks, table)
239
- rad_to_deg = 180.0 / Math::PI
240
- deg_to_rad = Math::PI / 180.0
241
- tracks.each { |tr|
242
- tr[0] *= 10.0
243
- tr[1] *= 10.0
244
- tr[2] *= 10.0
245
- tr[3] *= rad_to_deg
246
- tr[4] *= rad_to_deg
247
- tr[5] *= rad_to_deg
248
- }
249
- @records.each_with_index { |r, i|
250
- bone_index = table[r.bone_index]
251
- next unless bone_index
252
- animation_track = r.animation_track
253
- if @entries[i]
254
- value = @entries[i].get_value(tracks, table, interpolation_entries)
255
- end
256
- tracks[bone_index][animation_track] = value
257
- }
258
- tracks.each { |tr|
259
- tr[0] *= 0.1
260
- tr[1] *= 0.1
261
- tr[2] *= 0.1
262
- tr[3] *= deg_to_rad
263
- tr[4] *= deg_to_rad
264
- tr[5] *= deg_to_rad
265
- }
266
- end
267
-
268
- def recompute_layout
269
- self
270
- end
271
-
272
- def was_big?
273
- @__was_big
274
- end
275
-
276
- def dump(output_name, output_big = false)
277
- if output_name.respond_to?(:write) && output_name.respond_to?(:seek)
278
- output = output_name
279
- else
280
- output = File.open(output_name, "wb")
281
- end
282
- output.rewind
283
-
284
- __set_dump_state(output, output_big, nil, nil)
285
- __dump_fields
286
- __unset_dump_state
287
- output.close unless output_name.respond_to?(:write) && output_name.respond_to?(:seek)
288
- self
289
- end
290
-
291
- end
292
-
293
- class EXPFile < LibBin::Structure
294
-
295
- class EXPFileHeader < LibBin::Structure
296
- int8 :id, count: 4
297
- int32 :version
298
- uint32 :offset_records
299
- uint32 :num_records
300
-
301
- def initialize
302
- @id = "exp\0".b
303
- @version = 0
304
- @offset_records = 0
305
- @num_records = 0
306
- end
307
-
308
- end
309
-
310
- class Record < LibBin::Structure
311
- int16 :u_a
312
- int16 :bone_index
313
- int8 :animation_track
314
- int8 :entry_type
315
- int8 :u_b
316
- int8 :interpolation_type
317
- int16 :num_points
318
- int16 :u_c
319
- uint32 :offset
320
- uint32 :offset_interpolation
321
-
322
- def initialize
323
- @u_a = 0
324
- @bone_index = 0
325
- @animation_track = 0
326
- @entry_type = 0
327
- @u_b = 0
328
- @interpolation_type = 0
329
- @num_points = 0
330
- @offset = 0
331
- @offset_interpolation = 0
332
- end
333
-
334
- end
335
-
336
- class Operation < LibBin::Structure
337
- uint32 :flags
338
- float :value
339
-
340
- def initialize
341
- @flags = 0
342
- @value = 0.0
343
- end
344
-
345
- def transform_value( v )
346
- if @flags == 0x4
347
- v *= @value
348
- elsif @flags == 0x20004
349
- v = v.abs * @value
350
- elsif @flags == 0x1
351
- v += @value
352
- else
353
- raise "Unknown operation #{ "%x" % @flags }, please report!"
354
- end
355
- v
356
- end
357
-
358
- end
359
-
360
- class Entry1 < LibBin::Structure
361
- uint32 :flags
362
- int16 :bone_index
363
- int8 :animation_track
364
- int8 :padding
365
-
366
- def initialize
367
- @flags = 0x80000001
368
- @bone_index = 0
369
- @animation_track = 0
370
- @padding = 0
371
- end
372
-
373
- def get_value(pose, table)
374
- pose[table[@bone_index]][@animation_track]
375
- end
376
-
377
- end
378
-
379
- class Entry2 < LibBin::Structure
380
- uint32 :flags
381
- int16 :bone_index
382
- int8 :animation_track
383
- int8 :padding
384
- register_field :operation, Operation
385
-
386
- def initialize
387
- @flags = 0x80000001
388
- @bone_index = 0
389
- @animation_track = 0
390
- @padding = 0
391
- @operation = Operation::new
392
- end
393
-
394
- def get_value(pose, table)
395
- @operation.transform_value( pose[table[@bone_index]][@animation_track] )
396
- end
397
-
398
- end
399
-
400
- class Entry3 < LibBin::Structure
401
- uint32 :flags
402
- int16 :bone_index
403
- int8 :animation_track
404
- int8 :padding
405
- register_field :operations, Operation, count: 2
406
-
407
- def initialize
408
- @flags = 0x80000001
409
- @bone_index = 0
410
- @animation_track = 0
411
- @padding = 0
412
- @operations = [Operation::new, Operation::new]
413
- end
414
-
415
- def get_value(pose, table)
416
- v = @operations[0].transform_value( pose[table[@bone_index]][@animation_track] )
417
- v = @operations[1].transform_value( v )
418
- end
419
-
420
- end
421
-
422
- class Entry < LibBin::Structure
423
-
424
- def self.convert(input, output, input_big, output_big, parent, index, length = nil)
425
- entry_type = parent.records[index].entry_type
426
- entry = nil
427
- case entry_type
428
- when 1
429
- entry = Entry1::convert(input, output, input_big, output_big, parent, index, length)
430
- when 2
431
- entry = Entry2::convert(input, output, input_big, output_big, parent, index, length)
432
- when 3
433
- entry = Entry3::convert(input, output, input_big, output_big, parent, index, length)
434
- end
435
- entry
436
- end
437
-
438
- def self.load(input, input_big, parent, index, length = nil)
439
- entry_type = parent.records[index].entry_type
440
- entry = nil
441
- case entry_type
442
- when 1
443
- entry = Entry1::load(input, input_big, parent, index, length)
444
- when 2
445
- entry = Entry2::load(input, input_big, parent, index, length)
446
- when 3
447
- entry = Entry3::load(input, input_big, parent, index, length)
448
- end
449
- entry
450
- end
451
-
452
- end
453
-
454
- class Key2 < LibBin::Structure
455
- float :v
456
- float :p
457
- float :m0
458
- float :m1
459
-
460
- def initialize
461
- @v = 0.0
462
- @p = 0.0
463
- @m0 = 0.0
464
- @m1 = 0.0
465
- end
466
-
467
- def size
468
- 3 * 4
469
- end
470
- end
471
-
472
- class Interpolation2 < LibBin::Structure
473
- include ExpDirectValues
474
- include ExpAbsolutePositions
475
- include ExpKeyInterpolate
476
- register_field :keys, Key2, count: '..\records[__index]\num_points'
477
-
478
- def size
479
- @keys.collect(&:size).reduce(:+)
480
- end
481
- end
482
-
483
- class Key4 < LibBin::Structure
484
- float :v
485
- uint16 :dummy
486
- uint16 :cp
487
- uint16 :cm0
488
- uint16 :cm1
489
-
490
- def initialize
491
- @v = 0.0
492
- @dummy = 0
493
- @cp = 0
494
- @cm0 = 0
495
- @cm1 = 0
496
- end
497
-
498
- def size
499
- 3 * 4
500
- end
501
- end
502
-
503
- class Interpolation4 < LibBin::Structure
504
- include ExpQuantizedValues
505
- include ExpAbsolutePositions
506
- include ExpKeyInterpolate
507
- float :p
508
- float :dp
509
- float :m0
510
- float :dm0
511
- float :m1
512
- float :dm1
513
- register_field :keys, Key4, count: '..\records[__index]\num_points'
514
-
515
- def size
516
- 4 * 6 + @keys.collect(&:size).reduce(:+)
517
- end
518
- end
519
-
520
- class Key6 < LibBin::Structure
521
- uint8 :v
522
- uint8 :cp
523
- uint8 :cm0
524
- uint8 :cm1
525
-
526
- def initialize
527
- @v = 0
528
- @cp = 0
529
- @cm0 = 0
530
- @cm1 = 0
531
- end
532
-
533
- def size
534
- 4
535
- end
536
- end
537
-
538
- class Interpolation6 < LibBin::Structure
539
- include ExpQuantizedValues
540
- include ExpRelativePositions
541
- include ExpKeyInterpolate
542
- pghalf :p
543
- pghalf :dp
544
- pghalf :m0
545
- pghalf :dm0
546
- pghalf :m1
547
- pghalf :dm1
548
- register_field :keys, Key6, count: '..\records[__index]\num_points'
549
-
550
- def size
551
- 2 * 6 + @keys.collect(&:size).reduce(:+)
552
- end
553
- end
554
-
555
- class Interpolation < LibBin::Structure
556
-
557
- def self.convert(input, output, input_big, output_big, parent, index, length = nil)
558
- case parent.records[index].interpolation_type
559
- when 2
560
- Interpolation2::convert(input, output, input_big, output_big, parent, index, length)
561
- when 4
562
- Interpolation4::convert(input, output, input_big, output_big, parent, index, length)
563
- when 6
564
- Interpolation6::convert(input, output, input_big, output_big, parent, index, length)
565
- when -1
566
- nil
567
- else
568
- raise "Unknown Interpolation type: #{interpolation_type}, please report!"
569
- end
570
- end
571
-
572
- def self.load(input, input_big, parent, index, length = nil)
573
- case parent.records[index].interpolation_type
574
- when 2
575
- Interpolation2::load(input, input_big, parent, index, length)
576
- when 4
577
- Interpolation4::load(input, input_big, parent, index, length)
578
- when 6
579
- Interpolation6::load(input, input_big, parent, index, length)
580
- when -1
581
- nil
582
- else
583
- raise "Unknown Interpolation type: #{interpolation_type}, please report!"
584
- end
585
- end
586
-
587
- end
588
-
589
- register_field :header, EXPFileHeader
590
- register_field :records, Record, count: 'header\num_records', offset: 'header\offset_records'
591
- register_field :entries, Entry, count: 'header\num_records', sequence: true,
592
- offset: 'records[__iterator]\offset'
593
- register_field :interpolations, Interpolation, count: 'header\num_records', sequence: true,
594
- offset: 'records[__iterator]\offset_interpolation'
595
-
596
- def was_big?
597
- @__was_big
598
- end
599
-
600
- def apply(tracks, table)
601
- rad_to_deg = 180.0 / Math::PI
602
- deg_to_rad = Math::PI / 180.0
603
- tracks.each { |tr|
604
- tr[3] *= rad_to_deg
605
- tr[4] *= rad_to_deg
606
- tr[5] *= rad_to_deg
607
- }
608
- @records.each_with_index { |r, i|
609
- bone_index = table[r.bone_index]
610
- next unless bone_index
611
- animation_track = r.animation_track
612
- if @entries[i]
613
- value = @entries[i].get_value(tracks, table)
614
- end
615
- if @interpolations[i]
616
- value = @interpolations[i].interpolate(value)
617
- end
618
- tracks[bone_index][animation_track] = value
619
- }
620
- tracks.each { |tr|
621
- tr[3] *= deg_to_rad
622
- tr[4] *= deg_to_rad
623
- tr[5] *= deg_to_rad
624
- }
625
- end
626
-
627
- def add_entries(hash)
628
- hash.each { |k, v|
629
- raise "Invalid entry type #{k}!" if k>3 || k<1
630
- v.times {
631
- r = Record::new
632
- r.entry_type = k
633
- r.u_c = -1
634
- @records.insert(-2, r)
635
- case k
636
- when 1
637
- entry = Entry1::new
638
- when 2
639
- entry = Entry2::new
640
- when 3
641
- entry = Entry3::new
642
- end
643
- @entries.insert(-2, entry)
644
- }
645
- }
646
- self
647
- end
648
-
649
- def recompute_layout
650
- @header.num_records = @records.length
651
- last_offset = @header.offset_records
652
- last_offset += @records.collect(&:__size).reduce(:+)
653
-
654
- table = @records.zip(@entries).to_h
655
- reverse_table = table.invert
656
- interpolation_table = @records.zip(@interpolations).to_h
657
- reverse_interpolation_table = interpolation_table.invert
658
-
659
- @records.sort_by! { |r| [r.bone_index, r.animation_track] }
660
- @entries.sort_by! { |e| e ? [e.bone_index, e.animation_track] : [32767, -1] }
661
-
662
- @entries.each { |e|
663
- if e
664
- reverse_table[e].offset = last_offset
665
- last_offset += e.__size
666
- else
667
- reverse_table[e].offset = 0
668
- end
669
- }
670
- @interpolations.each { |i|
671
- if i
672
- reverse_interpolation_table[i].offset_interpolation = last_offset
673
- last_offset += i.size
674
- end
675
- }
676
-
677
- @entries = @records.collect { |r| table[r] }
678
- @interpolation = @records.collect { |r| interpolation_table[r] }
679
- self
680
- end
681
-
682
- def self.is_big?(f)
683
- f.rewind
684
- block = lambda { |int|
685
- id = f.read(4)
686
- raise "Invalid id #{id.inspect}!" if id != "exp\0".b
687
- u_a = f.read(4).unpack(int).first
688
- offset_record = f.read(4).unpack(int).first
689
- num_record = f.read(4).unpack(int).first
690
-
691
- num_record >= 0 && offset_record > 0 && offset_record < f.size
692
- }
693
- big = block.call("l>")
694
- f.rewind
695
- small = block.call("l<")
696
- f.rewind
697
- raise "Invalid data!" unless big ^ small
698
- return big
699
- end
700
-
701
- def self.is_bayo2?(f, big)
702
- f.rewind
703
- id = f.read(4)
704
- uint = "L<"
705
- uint = "L>" if big
706
- version = f.read(4).unpack(uint).first
707
- f.rewind
708
- return version == 0x20110714
709
- end
710
-
711
- def self.convert(input_name, output_name, input_big = true, output_big = false)
712
- input = File.open(input_name, "rb")
713
- id = input.read(4).unpack("a4").first
714
- raise "Invalid file type #{id}!" unless id == "exp\0".b
715
- output = File.open(output_name, "wb")
716
- output.write("\x00"*input.size)
717
- input.seek(0);
718
- output.seek(0);
719
-
720
- if is_bayo2?(input, input_big)
721
- exp = EXPFile2::new
722
- else
723
- exp = self::new
724
- end
725
- exp.__convert(input, output, input_big, output_big)
726
-
727
- input.close
728
- output.close
729
- end
730
-
731
- def self.load(input_name)
732
- if input_name.respond_to?(:read) && input_name.respond_to?(:seek)
733
- input = input_name
734
- else
735
- input = File.open(input_name, "rb")
736
- end
737
- input_big = is_big?(input)
738
-
739
- if is_bayo2?(input, input_big)
740
- exp = EXPFile2::new
741
- else
742
- exp = self::new
743
- end
744
- exp.instance_variable_set(:@__was_big, input_big)
745
- exp.__load(input, input_big)
746
- input.close unless input_name.respond_to?(:read) && input_name.respond_to?(:seek)
747
-
748
- exp
749
- end
750
-
751
- def dump(output_name, output_big = false)
752
- if output_name.respond_to?(:write) && output_name.respond_to?(:seek)
753
- output = output_name
754
- else
755
- output = File.open(output_name, "wb")
756
- end
757
- output.rewind
758
-
759
- __set_dump_state(output, output_big, nil, nil)
760
- __dump_fields
761
- __unset_dump_state
762
- output.close unless output_name.respond_to?(:write) && output_name.respond_to?(:seek)
763
- self
764
- end
765
-
766
- end
767
-
768
- end
1
+ module Bayonetta
2
+
3
+ module ExpQuantizedValues
4
+ def get_p(i)
5
+ @p + @keys[i].cp * @dp
6
+ end
7
+
8
+ def get_m1(i)
9
+ @m1 + @keys[i].cm1 * @dm1
10
+ end
11
+
12
+ def get_m0(i)
13
+ @m0 + @keys[i].cm0 * @dm0
14
+ end
15
+ end
16
+
17
+ module ExpDirectValues
18
+ def get_p(i)
19
+ @keys[i].p
20
+ end
21
+
22
+ def get_m1(i)
23
+ @keys[i].m1
24
+ end
25
+
26
+ def get_m0(i)
27
+ @keys[i].m0
28
+ end
29
+ end
30
+
31
+ module ExpAbsolutePositions
32
+ def key_positions
33
+ @key_positions ||= @keys.collect { |k| k.v }
34
+ end
35
+ end
36
+
37
+ module ExpRelativePositions
38
+ def key_positions
39
+ @key_positions ||= begin
40
+ sum = 0
41
+ @keys.collect { |k| sum += k.v }
42
+ end
43
+ end
44
+ end
45
+
46
+ module ExpKeyInterpolate
47
+ def interpol(position, start, stop, key_index)
48
+ p_0 = get_p(key_index)
49
+ p_1 = get_p(key_index + 1)
50
+ m_0 = get_m1(key_index)
51
+ m_1 = get_m0(key_index + 1)
52
+ t = (value - start).to_f / (stop - start)
53
+ t3 = t*t*t
54
+ t2 = t*t
55
+ (2 * t3 - 3 * t2 + 1)*p_0 + (t3 - 2 * t2 + t)*m_0 + (-2 * t3 + 3 * t2)*p_1 + (t3 - t2)*m_1
56
+ end
57
+
58
+ def interpolate(position)
59
+ if positions <= key_positions.first
60
+ get_p(0)
61
+ elsif positions >= key_positions.last
62
+ get_p(key_positions.length -1)
63
+ else
64
+ key_positions.each_cons(2).each_with_index { |(start, stop), i|
65
+ if position <= stop && position >= start
66
+ return interpol(position, start, stop)
67
+ end
68
+ }
69
+ end
70
+ end
71
+ end
72
+
73
+ class EXPFile2 < LibBin::Structure
74
+
75
+ class EXPFileHeader < LibBin::Structure
76
+ int8 :id, count: 4
77
+ int32 :version
78
+ uint32 :offset_records
79
+ uint32 :num_records
80
+ uint32 :offset_interpolations
81
+ uint32 :num_interpolations
82
+
83
+ def initialize
84
+ @id = "exp\0".b
85
+ @version = 0x20110714
86
+ @offset_records = 0
87
+ @num_records = 0
88
+ @offset_interpolations = 0
89
+ @num_interpolations = 0
90
+ end
91
+ end
92
+
93
+ class Record < LibBin::Structure
94
+ int16 :bone_index
95
+ int8 :animation_track
96
+ int8 :padding
97
+ int16 :num_operations
98
+ int16 :unknown
99
+ uint32 :offset
100
+
101
+ def initialize
102
+ @bone_index = 0
103
+ @animation_track = 0
104
+ @padding = 0
105
+ @num_operations = 0
106
+ @unknown = 0
107
+ @offset = 0
108
+ end
109
+
110
+ end
111
+
112
+ class Operation < LibBin::Structure
113
+ int8 :type
114
+ int8 :info
115
+ int16 :number
116
+ float :value
117
+
118
+ def initialize
119
+ @type = 0
120
+ @info = 0
121
+ @number = 0
122
+ @value = 0.0
123
+ end
124
+
125
+ end
126
+
127
+ class Entry < LibBin::Structure
128
+ register_field :operations, Operation, count: '..\records[__index]\num_operations'
129
+
130
+ def initialize
131
+ @operations = []
132
+ end
133
+
134
+ def abs(v)
135
+ v.abs
136
+ end
137
+
138
+ def get_value(tracks, table, interpolation_entries)
139
+ s = ""
140
+ @operations.each { |o|
141
+ case o.type
142
+ when 0
143
+ nil
144
+ when 1
145
+ s << "("
146
+ when 2
147
+ s << ")"
148
+ when 3
149
+ s << "tracks[table[#{o.number}]][#{o.info}]"
150
+ when 4
151
+ s << "#{o.value}"
152
+ when 5
153
+ case o.number
154
+ when 0
155
+ s << " + "
156
+ when 2
157
+ s << " * "
158
+ else
159
+ raise "Unknown arithmetic operation: #{o.number}!"
160
+ end
161
+ when 6
162
+ raise "Unknown function argument number: #{o.info}!" if o.info != 1
163
+ case o.number
164
+ when 1
165
+ s << "abs("
166
+ else
167
+ raise "Unknown function: #{o.number}!"
168
+ end
169
+ when 7
170
+ s << ")"
171
+ when 8
172
+ s << "interpolation_entries[#{o.number}].get_value("
173
+ else
174
+ raise "Unknown operation: #{o.type}!"
175
+ end
176
+ }
177
+ eval s
178
+ end
179
+
180
+ end
181
+
182
+ class Interpolation < LibBin::Structure
183
+ int16 :num_points
184
+ int16 :padding
185
+ uint32 :offset
186
+
187
+ def initialize
188
+ @num_points = 0
189
+ @padding = 0
190
+ @offset = 0
191
+ end
192
+
193
+ end
194
+
195
+ class Point < LibBin::Structure
196
+ float :v
197
+ float :p
198
+ float :m0
199
+ float :m1
200
+
201
+ def initialize
202
+ @v = 0.0
203
+ @p = 0.0
204
+ @m0 = 0.0
205
+ @m1 = 0.0
206
+ end
207
+
208
+ end
209
+
210
+ class InterpolationEntry < LibBin::Structure
211
+ register_field :points, Point, count: '..\interpolations[__index]\num_points'
212
+
213
+ def get_value(val)
214
+ @points.each_cons(2) { |left, right|
215
+ if left.v <= val && right.v >= val
216
+ p0 = left.p
217
+ p1 = right.p
218
+ m0 = left.m1
219
+ m1 = right.m0
220
+ t = (val - left.v).to_f / (right.v - left.v)
221
+ return (2 * t*t*t - 3 * t*t + 1)*p0 + (t*t*t - 2 * t*t + t)*m0 + (-2 * t*t*t + 3 * t*t)*p1 + (t*t*t - t * t)*m1
222
+ end
223
+
224
+ }
225
+ return 0.0
226
+ end
227
+
228
+ end
229
+
230
+ register_field :header, EXPFileHeader
231
+ register_field :records, Record, count: 'header\num_records', offset: 'header\offset_records'
232
+ register_field :entries, Entry, count: 'header\num_records', sequence: true,
233
+ offset: 'records[__iterator]\offset + header\offset_records + 12*__iterator'
234
+ register_field :interpolations, Interpolation, count: 'header\num_interpolations', offset: 'header\offset_interpolations'
235
+ register_field :interpolation_entries, InterpolationEntry, count: 'header\num_interpolations', sequence: true,
236
+ offset: 'interpolations[__iterator]\offset + header\offset_interpolations + 8*__iterator'
237
+
238
+ def apply(tracks, table)
239
+ rad_to_deg = 180.0 / Math::PI
240
+ deg_to_rad = Math::PI / 180.0
241
+ tracks.each { |tr|
242
+ tr[0] *= 10.0
243
+ tr[1] *= 10.0
244
+ tr[2] *= 10.0
245
+ tr[3] *= rad_to_deg
246
+ tr[4] *= rad_to_deg
247
+ tr[5] *= rad_to_deg
248
+ }
249
+ @records.each_with_index { |r, i|
250
+ bone_index = table[r.bone_index]
251
+ next unless bone_index
252
+ animation_track = r.animation_track
253
+ if @entries[i]
254
+ value = @entries[i].get_value(tracks, table, interpolation_entries)
255
+ end
256
+ tracks[bone_index][animation_track] = value
257
+ }
258
+ tracks.each { |tr|
259
+ tr[0] *= 0.1
260
+ tr[1] *= 0.1
261
+ tr[2] *= 0.1
262
+ tr[3] *= deg_to_rad
263
+ tr[4] *= deg_to_rad
264
+ tr[5] *= deg_to_rad
265
+ }
266
+ end
267
+
268
+ def recompute_layout
269
+ self
270
+ end
271
+
272
+ def was_big?
273
+ @__was_big
274
+ end
275
+
276
+ def dump(output_name, output_big = false)
277
+ if output_name.respond_to?(:write) && output_name.respond_to?(:seek)
278
+ output = output_name
279
+ else
280
+ output = File.open(output_name, "wb")
281
+ end
282
+ output.rewind
283
+
284
+ __set_dump_state(output, output_big, nil, nil)
285
+ __dump_fields
286
+ __unset_dump_state
287
+ output.close unless output_name.respond_to?(:write) && output_name.respond_to?(:seek)
288
+ self
289
+ end
290
+
291
+ end
292
+
293
+ class EXPFile < LibBin::Structure
294
+
295
+ class EXPFileHeader < LibBin::Structure
296
+ int8 :id, count: 4
297
+ int32 :version
298
+ uint32 :offset_records
299
+ uint32 :num_records
300
+
301
+ def initialize
302
+ @id = "exp\0".b
303
+ @version = 0
304
+ @offset_records = 0
305
+ @num_records = 0
306
+ end
307
+
308
+ end
309
+
310
+ class Record < LibBin::Structure
311
+ int16 :u_a
312
+ int16 :bone_index
313
+ int8 :animation_track
314
+ int8 :entry_type
315
+ int8 :u_b
316
+ int8 :interpolation_type
317
+ int16 :num_points
318
+ int16 :u_c
319
+ uint32 :offset
320
+ uint32 :offset_interpolation
321
+
322
+ def initialize
323
+ @u_a = 0
324
+ @bone_index = 0
325
+ @animation_track = 0
326
+ @entry_type = 0
327
+ @u_b = 0
328
+ @interpolation_type = 0
329
+ @num_points = 0
330
+ @offset = 0
331
+ @offset_interpolation = 0
332
+ end
333
+
334
+ end
335
+
336
+ class Operation < LibBin::Structure
337
+ uint32 :flags
338
+ float :value
339
+
340
+ def initialize
341
+ @flags = 0
342
+ @value = 0.0
343
+ end
344
+
345
+ def transform_value( v )
346
+ if @flags == 0x4
347
+ v *= @value
348
+ elsif @flags == 0x20004
349
+ v = v.abs * @value
350
+ elsif @flags == 0x1
351
+ v += @value
352
+ else
353
+ raise "Unknown operation #{ "%x" % @flags }, please report!"
354
+ end
355
+ v
356
+ end
357
+
358
+ end
359
+
360
+ class Entry1 < LibBin::Structure
361
+ uint32 :flags
362
+ int16 :bone_index
363
+ int8 :animation_track
364
+ int8 :padding
365
+
366
+ def initialize
367
+ @flags = 0x80000001
368
+ @bone_index = 0
369
+ @animation_track = 0
370
+ @padding = 0
371
+ end
372
+
373
+ def get_value(pose, table)
374
+ pose[table[@bone_index]][@animation_track]
375
+ end
376
+
377
+ end
378
+
379
+ class Entry2 < LibBin::Structure
380
+ uint32 :flags
381
+ int16 :bone_index
382
+ int8 :animation_track
383
+ int8 :padding
384
+ register_field :operation, Operation
385
+
386
+ def initialize
387
+ @flags = 0x80000001
388
+ @bone_index = 0
389
+ @animation_track = 0
390
+ @padding = 0
391
+ @operation = Operation::new
392
+ end
393
+
394
+ def get_value(pose, table)
395
+ @operation.transform_value( pose[table[@bone_index]][@animation_track] )
396
+ end
397
+
398
+ end
399
+
400
+ class Entry3 < LibBin::Structure
401
+ uint32 :flags
402
+ int16 :bone_index
403
+ int8 :animation_track
404
+ int8 :padding
405
+ register_field :operations, Operation, count: 2
406
+
407
+ def initialize
408
+ @flags = 0x80000001
409
+ @bone_index = 0
410
+ @animation_track = 0
411
+ @padding = 0
412
+ @operations = [Operation::new, Operation::new]
413
+ end
414
+
415
+ def get_value(pose, table)
416
+ v = @operations[0].transform_value( pose[table[@bone_index]][@animation_track] )
417
+ v = @operations[1].transform_value( v )
418
+ end
419
+
420
+ end
421
+
422
+ class Entry < LibBin::Structure
423
+
424
+ def self.convert(input, output, input_big, output_big, parent, index, length = nil)
425
+ entry_type = parent.records[index].entry_type
426
+ entry = nil
427
+ case entry_type
428
+ when 1
429
+ entry = Entry1::convert(input, output, input_big, output_big, parent, index, length)
430
+ when 2
431
+ entry = Entry2::convert(input, output, input_big, output_big, parent, index, length)
432
+ when 3
433
+ entry = Entry3::convert(input, output, input_big, output_big, parent, index, length)
434
+ end
435
+ entry
436
+ end
437
+
438
+ def self.load(input, input_big, parent, index, length = nil)
439
+ entry_type = parent.records[index].entry_type
440
+ entry = nil
441
+ case entry_type
442
+ when 1
443
+ entry = Entry1::load(input, input_big, parent, index, length)
444
+ when 2
445
+ entry = Entry2::load(input, input_big, parent, index, length)
446
+ when 3
447
+ entry = Entry3::load(input, input_big, parent, index, length)
448
+ end
449
+ entry
450
+ end
451
+
452
+ end
453
+
454
+ class Key2 < LibBin::Structure
455
+ float :v
456
+ float :p
457
+ float :m0
458
+ float :m1
459
+
460
+ def initialize
461
+ @v = 0.0
462
+ @p = 0.0
463
+ @m0 = 0.0
464
+ @m1 = 0.0
465
+ end
466
+
467
+ def size
468
+ 3 * 4
469
+ end
470
+ end
471
+
472
+ class Interpolation2 < LibBin::Structure
473
+ include ExpDirectValues
474
+ include ExpAbsolutePositions
475
+ include ExpKeyInterpolate
476
+ register_field :keys, Key2, count: '..\records[__index]\num_points'
477
+
478
+ def size
479
+ @keys.collect(&:size).reduce(:+)
480
+ end
481
+ end
482
+
483
+ class Key4 < LibBin::Structure
484
+ float :v
485
+ uint16 :dummy
486
+ uint16 :cp
487
+ uint16 :cm0
488
+ uint16 :cm1
489
+
490
+ def initialize
491
+ @v = 0.0
492
+ @dummy = 0
493
+ @cp = 0
494
+ @cm0 = 0
495
+ @cm1 = 0
496
+ end
497
+
498
+ def size
499
+ 3 * 4
500
+ end
501
+ end
502
+
503
+ class Interpolation4 < LibBin::Structure
504
+ include ExpQuantizedValues
505
+ include ExpAbsolutePositions
506
+ include ExpKeyInterpolate
507
+ float :p
508
+ float :dp
509
+ float :m0
510
+ float :dm0
511
+ float :m1
512
+ float :dm1
513
+ register_field :keys, Key4, count: '..\records[__index]\num_points'
514
+
515
+ def size
516
+ 4 * 6 + @keys.collect(&:size).reduce(:+)
517
+ end
518
+ end
519
+
520
+ class Key6 < LibBin::Structure
521
+ uint8 :v
522
+ uint8 :cp
523
+ uint8 :cm0
524
+ uint8 :cm1
525
+
526
+ def initialize
527
+ @v = 0
528
+ @cp = 0
529
+ @cm0 = 0
530
+ @cm1 = 0
531
+ end
532
+
533
+ def size
534
+ 4
535
+ end
536
+ end
537
+
538
+ class Interpolation6 < LibBin::Structure
539
+ include ExpQuantizedValues
540
+ include ExpRelativePositions
541
+ include ExpKeyInterpolate
542
+ pghalf :p
543
+ pghalf :dp
544
+ pghalf :m0
545
+ pghalf :dm0
546
+ pghalf :m1
547
+ pghalf :dm1
548
+ register_field :keys, Key6, count: '..\records[__index]\num_points'
549
+
550
+ def size
551
+ 2 * 6 + @keys.collect(&:size).reduce(:+)
552
+ end
553
+ end
554
+
555
+ class Interpolation < LibBin::Structure
556
+
557
+ def self.convert(input, output, input_big, output_big, parent, index, length = nil)
558
+ case parent.records[index].interpolation_type
559
+ when 2
560
+ Interpolation2::convert(input, output, input_big, output_big, parent, index, length)
561
+ when 4
562
+ Interpolation4::convert(input, output, input_big, output_big, parent, index, length)
563
+ when 6
564
+ Interpolation6::convert(input, output, input_big, output_big, parent, index, length)
565
+ when -1
566
+ nil
567
+ else
568
+ raise "Unknown Interpolation type: #{interpolation_type}, please report!"
569
+ end
570
+ end
571
+
572
+ def self.load(input, input_big, parent, index, length = nil)
573
+ case parent.records[index].interpolation_type
574
+ when 2
575
+ Interpolation2::load(input, input_big, parent, index, length)
576
+ when 4
577
+ Interpolation4::load(input, input_big, parent, index, length)
578
+ when 6
579
+ Interpolation6::load(input, input_big, parent, index, length)
580
+ when -1
581
+ nil
582
+ else
583
+ raise "Unknown Interpolation type: #{interpolation_type}, please report!"
584
+ end
585
+ end
586
+
587
+ end
588
+
589
+ register_field :header, EXPFileHeader
590
+ register_field :records, Record, count: 'header\num_records', offset: 'header\offset_records'
591
+ register_field :entries, Entry, count: 'header\num_records', sequence: true,
592
+ offset: 'records[__iterator]\offset'
593
+ register_field :interpolations, Interpolation, count: 'header\num_records', sequence: true,
594
+ offset: 'records[__iterator]\offset_interpolation'
595
+
596
+ def was_big?
597
+ @__was_big
598
+ end
599
+
600
+ def apply(tracks, table)
601
+ rad_to_deg = 180.0 / Math::PI
602
+ deg_to_rad = Math::PI / 180.0
603
+ tracks.each { |tr|
604
+ tr[3] *= rad_to_deg
605
+ tr[4] *= rad_to_deg
606
+ tr[5] *= rad_to_deg
607
+ }
608
+ @records.each_with_index { |r, i|
609
+ bone_index = table[r.bone_index]
610
+ next unless bone_index
611
+ animation_track = r.animation_track
612
+ if @entries[i]
613
+ value = @entries[i].get_value(tracks, table)
614
+ end
615
+ if @interpolations[i]
616
+ value = @interpolations[i].interpolate(value)
617
+ end
618
+ tracks[bone_index][animation_track] = value
619
+ }
620
+ tracks.each { |tr|
621
+ tr[3] *= deg_to_rad
622
+ tr[4] *= deg_to_rad
623
+ tr[5] *= deg_to_rad
624
+ }
625
+ end
626
+
627
+ def add_entries(hash)
628
+ hash.each { |k, v|
629
+ raise "Invalid entry type #{k}!" if k>3 || k<1
630
+ v.times {
631
+ r = Record::new
632
+ r.entry_type = k
633
+ r.u_c = -1
634
+ @records.insert(-2, r)
635
+ case k
636
+ when 1
637
+ entry = Entry1::new
638
+ when 2
639
+ entry = Entry2::new
640
+ when 3
641
+ entry = Entry3::new
642
+ end
643
+ @entries.insert(-2, entry)
644
+ }
645
+ }
646
+ self
647
+ end
648
+
649
+ def recompute_layout
650
+ @header.num_records = @records.length
651
+ last_offset = @header.offset_records
652
+ last_offset += @records.collect(&:__size).reduce(:+)
653
+
654
+ table = @records.zip(@entries).to_h
655
+ reverse_table = table.invert
656
+ interpolation_table = @records.zip(@interpolations).to_h
657
+ reverse_interpolation_table = interpolation_table.invert
658
+
659
+ @records.sort_by! { |r| [r.bone_index, r.animation_track] }
660
+ @entries.sort_by! { |e| e ? [e.bone_index, e.animation_track] : [32767, -1] }
661
+
662
+ @entries.each { |e|
663
+ if e
664
+ reverse_table[e].offset = last_offset
665
+ last_offset += e.__size
666
+ else
667
+ reverse_table[e].offset = 0
668
+ end
669
+ }
670
+ @interpolations.each { |i|
671
+ if i
672
+ reverse_interpolation_table[i].offset_interpolation = last_offset
673
+ last_offset += i.size
674
+ end
675
+ }
676
+
677
+ @entries = @records.collect { |r| table[r] }
678
+ @interpolation = @records.collect { |r| interpolation_table[r] }
679
+ self
680
+ end
681
+
682
+ def self.is_big?(f)
683
+ f.rewind
684
+ block = lambda { |int|
685
+ id = f.read(4)
686
+ raise "Invalid id #{id.inspect}!" if id != "exp\0".b
687
+ u_a = f.read(4).unpack(int).first
688
+ offset_record = f.read(4).unpack(int).first
689
+ num_record = f.read(4).unpack(int).first
690
+
691
+ num_record >= 0 && offset_record > 0 && offset_record < f.size
692
+ }
693
+ big = block.call("l>")
694
+ f.rewind
695
+ small = block.call("l<")
696
+ f.rewind
697
+ raise "Invalid data!" unless big ^ small
698
+ return big
699
+ end
700
+
701
+ def self.is_bayo2?(f, big)
702
+ f.rewind
703
+ id = f.read(4)
704
+ uint = "L<"
705
+ uint = "L>" if big
706
+ version = f.read(4).unpack(uint).first
707
+ f.rewind
708
+ return version == 0x20110714
709
+ end
710
+
711
+ def self.convert(input_name, output_name, input_big = true, output_big = false)
712
+ input = File.open(input_name, "rb")
713
+ id = input.read(4).unpack("a4").first
714
+ raise "Invalid file type #{id}!" unless id == "exp\0".b
715
+ output = File.open(output_name, "wb")
716
+ output.write("\x00"*input.size)
717
+ input.seek(0);
718
+ output.seek(0);
719
+
720
+ if is_bayo2?(input, input_big)
721
+ exp = EXPFile2::new
722
+ else
723
+ exp = self::new
724
+ end
725
+ exp.__convert(input, output, input_big, output_big)
726
+
727
+ input.close
728
+ output.close
729
+ end
730
+
731
+ def self.load(input_name)
732
+ if input_name.respond_to?(:read) && input_name.respond_to?(:seek)
733
+ input = input_name
734
+ else
735
+ input = File.open(input_name, "rb")
736
+ end
737
+ input_big = is_big?(input)
738
+
739
+ if is_bayo2?(input, input_big)
740
+ exp = EXPFile2::new
741
+ else
742
+ exp = self::new
743
+ end
744
+ exp.instance_variable_set(:@__was_big, input_big)
745
+ exp.__load(input, input_big)
746
+ input.close unless input_name.respond_to?(:read) && input_name.respond_to?(:seek)
747
+
748
+ exp
749
+ end
750
+
751
+ def dump(output_name, output_big = false)
752
+ if output_name.respond_to?(:write) && output_name.respond_to?(:seek)
753
+ output = output_name
754
+ else
755
+ output = File.open(output_name, "wb")
756
+ end
757
+ output.rewind
758
+
759
+ __set_dump_state(output, output_big, nil, nil)
760
+ __dump_fields
761
+ __unset_dump_state
762
+ output.close unless output_name.respond_to?(:write) && output_name.respond_to?(:seek)
763
+ self
764
+ end
765
+
766
+ end
767
+
768
+ end