changeset 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 13dcde917083
children b6c068c8f7f2
files pytouhou/formats/anm0.py pytouhou/game/enemy.py pytouhou/resource/anmwrapper.py pytouhou/resource/loader.py
diffstat 4 files changed, 42 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/formats/anm0.py
+++ b/pytouhou/formats/anm0.py
@@ -36,7 +36,7 @@ class Script(list):
 
 
 
-class Animations(object):
+class ANM0(object):
     _instructions = {0: ('', 'delete'),
                      1: ('I', 'set_sprite'),
                      2: ('ff', 'set_scale'),
@@ -82,44 +82,44 @@ class Animations(object):
         nb_sprites, nb_scripts, zero1 = unpack('<III', file.read(12))
         width, height, format, zero2 = unpack('<IIII', file.read(16))
         first_name_offset, unused, secondary_name_offset = unpack('<III', file.read(12))
-        version, unknown1, thtxoffset, hasdata, nextoffset = unpack('<IIIII', file.read(20))
+        version, unknown1, thtxoffset, hasdata, nextoffset, zero3 = unpack('<IIIIII', file.read(24))
         if version != 0:
             raise Exception #TODO
-        file.read(4) #TODO
+        if (zero1, zero2, zero3) != (0, 0, 0):
+            raise Exception #TODO
 
         sprite_offsets = [unpack('<I', file.read(4))[0] for i in range(nb_sprites)]
         script_offsets = [unpack('<II', file.read(8)) for i in range(nb_scripts)]
 
-        anm = Animations()
+        self = cls()
 
-        anm.size = (width, height)
+        self.size = (width, height)
 
         # Names
         if first_name_offset:
             file.seek(first_name_offset)
-            anm.first_name = read_string(file, 32, 'ascii') #TODO: 32, really?
+            self.first_name = read_string(file, 32, 'ascii') #TODO: 32, really?
         if secondary_name_offset:
             file.seek(secondary_name_offset)
-            anm.secondary_name = read_string(file, 32, 'ascii') #TODO: 32, really?
+            self.secondary_name = read_string(file, 32, 'ascii') #TODO: 32, really?
 
 
         # Sprites
         file.seek(64)
-        anm.sprites = {}
+        self.sprites = {}
         for offset in sprite_offsets:
             file.seek(offset)
             idx, x, y, width, height = unpack('<Iffff', file.read(20))
-            anm.sprites[idx] = x, y, width, height
+            self.sprites[idx] = x, y, width, height
 
 
         # Scripts
-        anm.scripts = {}
+        self.scripts = {}
         for i, offset in script_offsets:
-            anm.scripts[i] = Script()
+            self.scripts[i] = Script()
             instruction_offsets = []
             file.seek(offset)
             while True:
-                #TODO
                 instruction_offsets.append(file.tell() - offset)
                 time, opcode, size = unpack('<HBB', file.read(4))
                 data = file.read(size)
@@ -129,20 +129,19 @@ class Animations(object):
                     args = (data,)
                     logger.warn('unknown opcode %d', opcode)
 
-                anm.scripts[i].append((time, opcode, args))
+                self.scripts[i].append((time, opcode, args))
                 if opcode == 0:
                     break
 
             # Translate offsets to instruction pointers and register interrupts
-            for instr_offset, (j, instr) in zip(instruction_offsets, enumerate(anm.scripts[i])):
+            for instr_offset, (j, instr) in zip(instruction_offsets, enumerate(self.scripts[i])):
                 time, opcode, args = instr
                 if opcode == 5:
                     args = (instruction_offsets.index(args[0]),)
                 elif opcode == 22:
                     interrupt = args[0]
-                    anm.scripts[i].interrupts[interrupt] = j + 1
-                anm.scripts[i][j] = time, opcode, args
-        #TODO
+                    self.scripts[i].interrupts[interrupt] = j + 1
+                self.scripts[i][j] = time, opcode, args
 
-        return anm
+        return self
 
--- a/pytouhou/game/enemy.py
+++ b/pytouhou/game/enemy.py
@@ -387,8 +387,7 @@ class Enemy(object):
 
         for anm in self.aux_anm:
             if anm:
-                anm.x = self.x
-                anm.y = self.y
+                anm.x, anm.y = self.x, self.y
                 anm.update()
 
         self.frame += 1
--- a/pytouhou/resource/anmwrapper.py
+++ b/pytouhou/resource/anmwrapper.py
@@ -1,17 +1,22 @@
+from itertools import izip, chain, repeat
+
+
 class AnmWrapper(object):
-    def __init__(self, anm_files):
-        self.anm_files = list(anm_files)
+    def __init__(self, anm_files, offsets=()):
+        self.scripts = {}
+        self.sprites = {}
+
+        for anm, offset in izip(anm_files, chain(offsets, repeat(0))):
+            for script_id, script in anm.scripts.iteritems():
+                self.scripts[script_id + offset] = (anm, script) #TODO: check
+            for sprite_id, sprite in anm.sprites.iteritems():
+                self.sprites[sprite_id + offset] = (anm, sprite)
 
 
     def get_sprite(self, sprite_index):
-        for anm in self.anm_files:
-            if sprite_index in anm.sprites:
-                return anm, anm.sprites[sprite_index]
-        raise IndexError
+        return self.sprites[sprite_index]
 
 
     def get_script(self, script_index):
-        for anm in self.anm_files:
-            if script_index in anm.scripts:
-                return anm, anm.scripts[script_index]
-        raise IndexError
+        return self.scripts[script_index]
+
--- a/pytouhou/resource/loader.py
+++ b/pytouhou/resource/loader.py
@@ -6,7 +6,7 @@ from io import BytesIO
 from pytouhou.formats.pbg3 import PBG3
 from pytouhou.formats.std import Stage
 from pytouhou.formats.ecl import ECL
-from pytouhou.formats.anm0 import Animations
+from pytouhou.formats.anm0 import ANM0
 from pytouhou.formats.msg import MSG
 from pytouhou.formats.sht import SHT
 from pytouhou.formats.exe import SHT as EoSDSHT
@@ -121,7 +121,7 @@ class Loader(object):
     def get_anm(self, name):
         if name not in self.instanced_anms:
             file = self.get_file(name)
-            self.instanced_anms[name] = Animations.read(file) #TODO: modular
+            self.instanced_anms[name] = ANM0.read(file) #TODO: modular
         return self.instanced_anms[name]
 
 
@@ -163,17 +163,18 @@ class Loader(object):
         return characters
 
 
-    def get_anm_wrapper(self, names):
-        return AnmWrapper(self.get_anm(name) for name in names)
+    def get_anm_wrapper(self, names, offsets=()):
+        return AnmWrapper((self.get_anm(name) for name in names), offsets)
 
 
-    def get_anm_wrapper2(self, names):
-        anims = []
+    def get_anm_wrapper2(self, names, offsets=()):
+        anms = []
+
         try:
             for name in names:
-                anims.append(self.get_anm(name))
+                anms.append(self.get_anm(name))
         except KeyError:
             pass
 
-        return AnmWrapper(anims)
+        return AnmWrapper(anms, offsets)