comparison pytouhou/formats/anm0.py @ 282:dbb1a86c0235

Rename Animations to ANM0 and prepare AnmWrapper for dialogs and interface.
author Thibaut Girka <thib@sitedethib.com>
date Sat, 11 Feb 2012 16:43:54 +0100
parents d3ba32a9096e
children da53bc29b94a
comparison
equal deleted inserted replaced
281:13dcde917083 282:dbb1a86c0235
34 list.__init__(self) 34 list.__init__(self)
35 self.interrupts = {} 35 self.interrupts = {}
36 36
37 37
38 38
39 class Animations(object): 39 class ANM0(object):
40 _instructions = {0: ('', 'delete'), 40 _instructions = {0: ('', 'delete'),
41 1: ('I', 'set_sprite'), 41 1: ('I', 'set_sprite'),
42 2: ('ff', 'set_scale'), 42 2: ('ff', 'set_scale'),
43 3: ('I', 'set_alpha'), 43 3: ('I', 'set_alpha'),
44 4: ('BBBx', 'set_color'), 44 4: ('BBBx', 'set_color'),
80 @classmethod 80 @classmethod
81 def read(cls, file): 81 def read(cls, file):
82 nb_sprites, nb_scripts, zero1 = unpack('<III', file.read(12)) 82 nb_sprites, nb_scripts, zero1 = unpack('<III', file.read(12))
83 width, height, format, zero2 = unpack('<IIII', file.read(16)) 83 width, height, format, zero2 = unpack('<IIII', file.read(16))
84 first_name_offset, unused, secondary_name_offset = unpack('<III', file.read(12)) 84 first_name_offset, unused, secondary_name_offset = unpack('<III', file.read(12))
85 version, unknown1, thtxoffset, hasdata, nextoffset = unpack('<IIIII', file.read(20)) 85 version, unknown1, thtxoffset, hasdata, nextoffset, zero3 = unpack('<IIIIII', file.read(24))
86 if version != 0: 86 if version != 0:
87 raise Exception #TODO 87 raise Exception #TODO
88 file.read(4) #TODO 88 if (zero1, zero2, zero3) != (0, 0, 0):
89 raise Exception #TODO
89 90
90 sprite_offsets = [unpack('<I', file.read(4))[0] for i in range(nb_sprites)] 91 sprite_offsets = [unpack('<I', file.read(4))[0] for i in range(nb_sprites)]
91 script_offsets = [unpack('<II', file.read(8)) for i in range(nb_scripts)] 92 script_offsets = [unpack('<II', file.read(8)) for i in range(nb_scripts)]
92 93
93 anm = Animations() 94 self = cls()
94 95
95 anm.size = (width, height) 96 self.size = (width, height)
96 97
97 # Names 98 # Names
98 if first_name_offset: 99 if first_name_offset:
99 file.seek(first_name_offset) 100 file.seek(first_name_offset)
100 anm.first_name = read_string(file, 32, 'ascii') #TODO: 32, really? 101 self.first_name = read_string(file, 32, 'ascii') #TODO: 32, really?
101 if secondary_name_offset: 102 if secondary_name_offset:
102 file.seek(secondary_name_offset) 103 file.seek(secondary_name_offset)
103 anm.secondary_name = read_string(file, 32, 'ascii') #TODO: 32, really? 104 self.secondary_name = read_string(file, 32, 'ascii') #TODO: 32, really?
104 105
105 106
106 # Sprites 107 # Sprites
107 file.seek(64) 108 file.seek(64)
108 anm.sprites = {} 109 self.sprites = {}
109 for offset in sprite_offsets: 110 for offset in sprite_offsets:
110 file.seek(offset) 111 file.seek(offset)
111 idx, x, y, width, height = unpack('<Iffff', file.read(20)) 112 idx, x, y, width, height = unpack('<Iffff', file.read(20))
112 anm.sprites[idx] = x, y, width, height 113 self.sprites[idx] = x, y, width, height
113 114
114 115
115 # Scripts 116 # Scripts
116 anm.scripts = {} 117 self.scripts = {}
117 for i, offset in script_offsets: 118 for i, offset in script_offsets:
118 anm.scripts[i] = Script() 119 self.scripts[i] = Script()
119 instruction_offsets = [] 120 instruction_offsets = []
120 file.seek(offset) 121 file.seek(offset)
121 while True: 122 while True:
122 #TODO
123 instruction_offsets.append(file.tell() - offset) 123 instruction_offsets.append(file.tell() - offset)
124 time, opcode, size = unpack('<HBB', file.read(4)) 124 time, opcode, size = unpack('<HBB', file.read(4))
125 data = file.read(size) 125 data = file.read(size)
126 if opcode in cls._instructions: 126 if opcode in cls._instructions:
127 args = unpack('<%s' % cls._instructions[opcode][0], data) 127 args = unpack('<%s' % cls._instructions[opcode][0], data)
128 else: 128 else:
129 args = (data,) 129 args = (data,)
130 logger.warn('unknown opcode %d', opcode) 130 logger.warn('unknown opcode %d', opcode)
131 131
132 anm.scripts[i].append((time, opcode, args)) 132 self.scripts[i].append((time, opcode, args))
133 if opcode == 0: 133 if opcode == 0:
134 break 134 break
135 135
136 # Translate offsets to instruction pointers and register interrupts 136 # Translate offsets to instruction pointers and register interrupts
137 for instr_offset, (j, instr) in zip(instruction_offsets, enumerate(anm.scripts[i])): 137 for instr_offset, (j, instr) in zip(instruction_offsets, enumerate(self.scripts[i])):
138 time, opcode, args = instr 138 time, opcode, args = instr
139 if opcode == 5: 139 if opcode == 5:
140 args = (instruction_offsets.index(args[0]),) 140 args = (instruction_offsets.index(args[0]),)
141 elif opcode == 22: 141 elif opcode == 22:
142 interrupt = args[0] 142 interrupt = args[0]
143 anm.scripts[i].interrupts[interrupt] = j + 1 143 self.scripts[i].interrupts[interrupt] = j + 1
144 anm.scripts[i][j] = time, opcode, args 144 self.scripts[i][j] = time, opcode, args
145 #TODO
146 145
147 return anm 146 return self
148 147