Mercurial > touhou
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 |