Add simple NTO viewer
[dormin.git] / reeng / anb.py
blob9d17f59d9759db5dca68d0dcf84e716704c17e9a
1 #!/usr/bin/python
2 from struct import unpack
3 import xff2, sys, math
5 def cstr (s, p):
6 return s[p:p+s[p:].find ("\x00")]
8 def sub1 (s, p, n):
9 return s[p:p+n]
11 def sub4 (s, p, n):
12 return s[p:p+n*4]
14 def magn (F):
15 return math.sqrt (reduce (lambda a,b:b*b+a, F,0))
17 def bits (b, l):
18 return reduce(lambda s,v:str(v)+s,[(b>>i)&1for i in range(l)],"")
20 def bits1 (d, s, l):
21 return reduce(lambda s,v:str(v)+s,[(d>>(i+s))&1for i in range(l)],"")
23 def bit9 (d, s, l):
24 if l == 9:
25 lut = [-256, +128, +64, +32, +16, +8, +4, +2, +1]
26 a = 0
27 for i in range (l):
28 if d & (1 << (s+i)):
29 a += lut[8-i]
30 else:
31 lut = [-16, +8, +4, +2, +1]
32 a = 0
33 for i in range (l):
34 if d & (1 << (s+i)):
35 a += lut[4-i]
36 return a+(1<<(l-1))
37 # return (a + (1 << (l-1))) / float (1 << l)
38 # return (a) / float (1 << (l))
41 def bytes(D):
42 b0 = (D >> 24) & 0xff
43 b1 = (D >> 16) & 0xff
44 b2 = (D >> 8) & 0xff
45 b3 = (D) & 0xff
46 return (b0, b1, b2, b3)
48 def signb (b):
49 if b & 0x80:
50 b -= 0x100
51 return b
53 def signbs (D):
54 return map (signb, bytes (D))
56 def flts (D):
57 sbs = signbs (D)
58 return map (lambda b: b, sbs)
60 def strfs (F):
61 return "[" + ", ".join (map (lambda f: "% f" % f, F)) + "]"
63 class ANB:
64 def readsome (self):
65 data = self.data[self.xff.off_sign+17*4:]
66 self.some = []
67 x = self.xff.off_sign+17*4
68 print "hdr at %08x" % (x + self.roff)
69 while True:
70 D = unpack ("<2I", data[:8])
71 if D[1] <> 0x102:
72 print "%08x %08x" % (D[0], D[1])
73 break
74 data = data[8:]
75 self.some.append ((x + self.roff, D[0]))
76 x += 8
78 print "hdr at %08x" % (x + self.roff)
79 self.some1 = []
80 for _ in self.some:
81 D = unpack ("<2I", data[:8])
82 if D[1] <> 0:
83 print "%08x %08x" % (D[0], D[1])
84 break
85 data = data[8:]
86 self.some1.append ((x + self.roff, D[0]))
87 x += 8
89 def __init__ (self, file, xff):
90 self.xff = xff
91 rodata = xff.sections[1]
92 self.rodata = rodata
93 self.roff = rodata[1][7]
94 file.seek (self.roff)
95 data = file.read ()#rodata[1][2])
96 self.data = data
97 self.D = unpack ("<17I", data[self.xff.off_sign:self.xff.off_sign+17*4])
99 self.bone_count = self.D[5]
100 self.boneD = unpack ("<%dI" % self.bone_count,
101 sub4 (data, self.D[4], self.bone_count))
102 self.boneB = unpack ("<%dB" % (self.bone_count + 3),
103 sub1 (data, self.D[2], self.bone_count + 3))
104 self.readsome ()
106 # F = unpack ("<4f", data[0x13c:0x14c])
107 # print "magn %f" % magn (F)
109 def bone (self, n):
110 b = self.boneB[n]
111 d = self.boneD[n]
112 data = self.data
113 incr = 0
114 print "_"*70
115 print "[%2d] %d %08x %08x" % (n, b, d, d + self.roff)
116 if b == 0:
117 F = unpack ("<4f", data[d:d+16])
118 print " magn % f" % magn (F)
119 incr = 16
120 i = 0
121 for f in F:
122 print " (%d) % 13.13f (% e)" % (i, f, f)
123 i += 1
124 elif b == 13:
125 F = unpack ("<5f", data[d:d+20])
126 print " magn % f" % magn (F[2:])
127 i = 0
128 for f in F:
129 print " (%d) % 13.13f (% e)" % (i, f, f)
130 i += 1
131 incr = 20
132 elif b == 12:
133 F = unpack ("<6f", data[d:d+24])
134 for i, f in enumerate (F):
135 print " (%d) % 13.13f (% e)" % (i, f, f)
136 incr = 24
137 elif b == 2:
138 raise "MOO"
139 else:
140 F = unpack ("<8f", data[d:d+32])
141 print " magn % f" % magn (F[:])
142 for i, f in enumerate (F):
143 if f == 0.0:
144 sys.stderr.write ("fuck it %d\n" % n)
145 print " (%d) % 13.13f (% e)" % (i, f, f)
146 f = math.fabs (F[4]) + math.fabs (F[5]) + math.fabs (F[6]) + math.fabs (F[7])
147 print " add % f" % f
148 incr = 32
150 print " end at %08x %08x" % (d+incr, d+incr+self.roff)
151 if b:
152 buf = data[d+incr:d+incr+4]
153 d1 = unpack ("<I", buf)[0]
154 print " %08x %08x %d" % (d1, d1 + self.roff, d1)
155 count = self.D[1] & 0xffff
156 pos = d1
157 else:
158 pos = d+incr
160 if b == 13:
161 subd = data[d1:d1+count*2]
162 D = unpack ("<%dH" % count, subd)
163 for i in range (count):
164 print " [%2d] %04x %d" % (i, D[i], D[i])
165 pos += count*2
166 elif b == 12:
167 subd = data[d1:d1+count*6]
168 for i in range (count):
169 data = unpack ("<3H", subd[:6])
170 subd = subd[6:]
171 print " [%2d] %04x %04x %04x" % (i, data[0], data[1], data[2])
172 pos += count*6
173 elif b == 6 or b == 3 or b == 4 or b == 5:
174 if False:
175 subd = data[d1:d1+count*4]
176 D = unpack ("<%dI" % count, subd)
177 for i in range (count):
178 d = D[i]
179 w = d & ((1<<9)-1)
180 z = (d>>9) & ((1<<9)-1)
181 y = (d>>18) & ((1<<9)-1)
182 x = (d>>27)
183 if b == 3:
184 starts = [27, 18, 9, 0]
185 lengths = [5, 9, 9, 9]
186 elif b == 4:
187 starts = [23, 18, 9, 0]
188 lengths = [9, 5, 9, 9]
189 elif b == 5:
190 starts = [23, 14, 9, 0]
191 lengths = [9, 9, 5, 9]
192 elif b == 6:
193 starts = [23, 14, 5, 0]
194 lengths = [9, 9, 9, 5]
196 ## print " [%2d] %08x %10d (%s %s %s %s)" % (i, D[i], D[i],
197 ## bits (x, 5),
198 ## bits (y, 9),
199 ## bits (z, 9),
200 ## bits (w, 9))
201 # print " %s" % bits (D[i], 32)
202 # print " [%2d] %08x %10d (% 4d, % 4d, % 4d, % 4d) (%s %s %s %s)" % \
203 x = bit9 (D[i], starts[0], lengths[0])
204 y = bit9 (D[i], starts[1], lengths[1])
205 z = bit9 (D[i], starts[2], lengths[2])
206 w = bit9 (D[i], starts[3], lengths[3])
208 # print " [%2d] %08x %10d (% f, % f, % f, % f: %f) (%s %s %s %s)" % \
209 print " [%2d] %08x %10d (%4d, %4d, %4d, %4d) (%s %s %s %s)" % \
210 (i, D[i], D[i], x, y, z, w,
211 bits1 (D[i], starts[0], lengths[0]),
212 bits1 (D[i], starts[1], lengths[1]),
213 bits1 (D[i], starts[2], lengths[2]),
214 bits1 (D[i], starts[3], lengths[3]))
215 pos += count*4
216 elif b == 0:
217 pass
218 else:
219 subd = data[d1:d1+count*4]
220 D = unpack ("<%dI" % count, subd)
221 F = unpack ("<%df" % count, subd)
222 for i in range (count):
223 print " [%2d] %08x %f %d" % (i, D[i], F[i], D[i])
224 pos += count*4
226 print " end2 at %08x %08x" % (pos, pos + self.roff)
228 def proff (self, n, s):
229 d = self.D[n]
230 print "D[%2d] %08x %08x %d (%s)" % (n, d, d+self.roff, d, s)
232 def pr (self):
233 print "roff %08x" % self.roff
234 print "off_sign %08x" % self.xff.off_sign
235 print "at %08x" % (self.roff + self.xff.off_sign)
236 print "D[ 0] %08x" % self.D[0]
237 print "D[ 1] %08x" % self.D[1]
238 self.proff (2, "per bone byte")
239 for i in range (3, 4):
240 d = self.D[i]
241 print "D[%2d] %08x %08x %d" % (i, d, d+self.roff, d)
243 self.proff (4, "per bone dword")
244 print "D[ 5] %d (bone count)" % self.D[5]
246 if self.xff.off_sign != self.D[10]:
247 print "D[10] !!! %08x %d" % (self.D[10], self.D[10])
249 # print "%d" % (self.D[10] - self.D[7])
251 for i in range (6, 9) + range (10, 17):
252 d = self.D[i]
253 print "D[%2d] %08x %08x %d" % (i, d, d+self.roff, d)
255 for i in range (self.bone_count):
256 d = self.boneD[i]
257 if i == self.bone_count - 1:
258 diff = "????"
259 else:
260 diff = "%4d" % (self.boneD[i+1] - d)
261 print "boneD[%2d] %08x %08x %4d(%s)" % (i, d, d + self.roff, d, diff),
262 b = self.boneB[i]
263 print "FLAG %3d %02x" % (b, b)
265 for i in range (len (self.some)):
266 (off, d) = self.some[i]
267 x = unpack ('<I', self.data[d:d+4])[0]
268 print "[%2d] %08x %08x (%04x) |" % (i, d, d + self.roff, x),
269 (off, d) = self.some1[i]
270 print "[%2d] %08x %08x" % (i, d, d + self.roff)
272 for i in range (self.bone_count):
273 self.bone (i)
275 print sys.argv[1]
276 f = open (sys.argv[1], "rb")
277 x = xff2.XFF (f, 0)
278 a = ANB (f, x)
279 a.pr ()