Mercurial > touhou
annotate pytouhou/resource/loader.py @ 262:8fa660da5f0c
Automatically search data files using different names.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Mon, 23 Jan 2012 00:58:03 +0100 |
parents | c417bb6c98bf |
children | ac677dd0ffe0 |
rev | line source |
---|---|
231
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
1 import os |
262
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
2 from glob import glob |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
3 from itertools import chain |
97 | 4 from io import BytesIO |
5 | |
6 from pytouhou.formats.pbg3 import PBG3 | |
7 from pytouhou.formats.std import Stage | |
8 from pytouhou.formats.ecl import ECL | |
9 from pytouhou.formats.anm0 import Animations | |
133
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
10 from pytouhou.formats.msg import MSG |
220
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
11 from pytouhou.formats.sht import SHT |
229
5afc75f71fed
Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
220
diff
changeset
|
12 from pytouhou.formats.exe import SHT as EoSDSHT |
97 | 13 |
14 | |
15 from pytouhou.resource.anmwrapper import AnmWrapper | |
16 | |
17 | |
18 class ArchiveDescription(object): | |
19 _formats = {'PBG3': PBG3} | |
20 | |
21 def __init__(self, path, format_class, file_list=None): | |
22 self.path = path | |
23 self.format_class = format_class | |
24 self.file_list = file_list or [] | |
25 | |
26 | |
27 def open(self): | |
28 file = open(self.path, 'rb') | |
29 instance = self.format_class.read(file) | |
30 return instance | |
31 | |
32 | |
33 @classmethod | |
34 def get_from_path(cls, path): | |
35 with open(path, 'rb') as file: | |
36 magic = file.read(4) | |
37 file.seek(0) | |
38 format_class = cls._formats[magic] | |
39 instance = format_class.read(file) | |
40 file_list = instance.list_files() | |
41 return cls(path, format_class, file_list) | |
42 | |
43 | |
44 | |
45 class Loader(object): | |
231
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
46 def __init__(self, game_dir=None): |
262
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
47 self.exe = None |
231
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
48 self.game_dir = game_dir |
97 | 49 self.known_files = {} |
50 self.instanced_ecls = {} | |
51 self.instanced_anms = {} | |
52 self.instanced_stages = {} | |
133
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
53 self.instanced_msgs = {} |
220
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
54 self.instanced_shts = {} |
97 | 55 |
56 | |
262
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
57 def scan_archives(self, paths_lists): |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
58 for paths in paths_lists: |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
59 def _expand_paths(): |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
60 for path in paths.split(':'): |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
61 if self.game_dir and not os.path.isabs(path): |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
62 path = os.path.join(self.game_dir, path) |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
63 yield glob(path) |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
64 paths = list(chain(*_expand_paths())) |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
65 path = paths[0] |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
66 if os.path.splitext(path)[1] == '.exe': |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
67 self.exe = path |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
68 else: |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
69 archive_description = ArchiveDescription.get_from_path(path) |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
70 for name in archive_description.file_list: |
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
71 self.known_files[name] = archive_description |
97 | 72 |
73 | |
74 def get_file_data(self, name): | |
75 with self.known_files[name].open() as archive: | |
76 content = archive.extract(name) | |
77 return content | |
78 | |
79 | |
80 def get_file(self, name): | |
81 with self.known_files[name].open() as archive: | |
82 content = archive.extract(name) | |
83 return BytesIO(content) | |
84 | |
85 | |
86 def get_anm(self, name): | |
87 if name not in self.instanced_anms: | |
88 file = self.get_file(name) | |
89 self.instanced_anms[name] = Animations.read(file) #TODO: modular | |
90 return self.instanced_anms[name] | |
91 | |
92 | |
93 def get_stage(self, name): | |
94 if name not in self.instanced_stages: | |
95 file = self.get_file(name) | |
96 self.instanced_stages[name] = Stage.read(file) #TODO: modular | |
97 return self.instanced_stages[name] | |
98 | |
99 | |
100 def get_ecl(self, name): | |
101 if name not in self.instanced_ecls: | |
102 file = self.get_file(name) | |
103 self.instanced_ecls[name] = ECL.read(file) #TODO: modular | |
104 return self.instanced_ecls[name] | |
105 | |
106 | |
133
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
107 def get_msg(self, name): |
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
108 if name not in self.instanced_msgs: |
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
109 file = self.get_file(name) |
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
110 self.instanced_msgs[name] = MSG.read(file) #TODO: modular |
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
111 return self.instanced_msgs[name] |
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
112 |
2cad2e84a49e
Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
97
diff
changeset
|
113 |
220
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
114 def get_sht(self, name): |
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
115 if name not in self.instanced_shts: |
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
116 file = self.get_file(name) |
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
117 self.instanced_shts[name] = SHT.read(file) #TODO: modular |
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
118 return self.instanced_shts[name] |
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
119 |
0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
133
diff
changeset
|
120 |
262
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
121 def get_eosd_characters(self): |
231
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
122 #TODO: Move to pytouhou.games.eosd? |
262
8fa660da5f0c
Automatically search data files using different names.
Thibaut Girka <thib@sitedethib.com>
parents:
231
diff
changeset
|
123 path = self.exe |
231
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
124 if self.game_dir and not os.path.isabs(path): |
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
125 path = os.path.join(self.game_dir, path) |
c417bb6c98bf
Search for 102h.exe in the game directory instead of the current directory.
Thibaut Girka <thib@sitedethib.com>
parents:
229
diff
changeset
|
126 with open(path, 'rb') as file: |
229
5afc75f71fed
Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
220
diff
changeset
|
127 characters = EoSDSHT.read(file) #TODO: modular |
5afc75f71fed
Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
220
diff
changeset
|
128 return characters |
5afc75f71fed
Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
220
diff
changeset
|
129 |
5afc75f71fed
Add “SHT” support to EoSD, and do a little cleanup.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
220
diff
changeset
|
130 |
97 | 131 def get_anm_wrapper(self, names): |
132 return AnmWrapper(self.get_anm(name) for name in names) | |
133 | |
134 | |
135 def get_anm_wrapper2(self, names): | |
136 anims = [] | |
137 try: | |
138 for name in names: | |
139 anims.append(self.get_anm(name)) | |
140 except KeyError: | |
141 pass | |
142 | |
143 return AnmWrapper(anims) | |
144 |