Mercurial > fife-parpg
comparison utils/frminfo/make_xml.py @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4a0efb7baf70 |
---|---|
1 #! /usr/bin/env python | |
2 import os,sys,string | |
3 SUFFIX_LIST = [ "aa","ab","at","ae","ak","al","an","ao","ap","ar","as","aq" ] | |
4 IDLE,WALK,RUN,CLIMB,PICKUP,USE,DODGE,HITFRONT,HITBACK,KICK,THROW,PUNCH = range(len(SUFFIX_LIST)) | |
5 ACTION_IDS = range(len(SUFFIX_LIST)) | |
6 ACTION_NAMES = [ | |
7 "IDLE","WALK","RUN","CLIMB","PICKUP","USE","DODGE","HITFRONT","HITBACK","KICK","THROW","PUNCH" | |
8 ] | |
9 SUFFIX_DICT = dict(zip(SUFFIX_LIST,ACTION_IDS)) | |
10 | |
11 USAGE=""" | |
12 *** make_xml.py *** | |
13 Generates XML Critter information from frm info in critter.dat | |
14 --list List all critters | |
15 --to-xml CRITTER Output XML generated for a critter CRITTER | |
16 into a file in the current directory | |
17 --all-xml DIRECTORY Output XML files for all critters in the list | |
18 into the directory DIRECTORY | |
19 """ | |
20 | |
21 CRITTER_XML = string.Template("""\ | |
22 <!-- | |
23 This is an auto-generated XML file | |
24 defining the animation actions a | |
25 critter can perform. | |
26 | |
27 Generator: make_xml.py | |
28 --> | |
29 <complex-animation name="$name" geometry="1"> | |
30 $actions | |
31 </complex-animation>""") | |
32 | |
33 ACTION_XML = string.Template("""\ | |
34 <!-- ACTION: $name FRAMES: $numFrames FPS: $fps --> | |
35 <action id="$id" direction="255"> | |
36 <animation src="$filename"/> | |
37 $partialActions | |
38 </action> | |
39 """) | |
40 | |
41 PARTIAL_ACTION_XML=string.Template("""\ | |
42 <partial-action number="$number"> | |
43 <frames start="$startFrame" number="$endFrame"/> | |
44 <step number="$stepNumber"/> | |
45 <partial-action action="$nextActionId" number="$nextNumber" direction="255"/> | |
46 </partial-action> | |
47 """) | |
48 | |
49 MOTION_XML = string.Template("""\ | |
50 <motion distance="$distance"/> | |
51 """) | |
52 | |
53 class Action(object): | |
54 def __init__(self,critter,suffix): | |
55 self.critter = critter | |
56 self.suffix = suffix | |
57 self.id = SUFFIX_DICT[ suffix ] | |
58 self.filename = "art/critters/" + self.critter.basename + self.suffix +".frm" | |
59 self.frminfo_parsed = False | |
60 | |
61 def __str__(self): | |
62 if self.frminfo_parsed: | |
63 return self.suffix + "[nframes="+str(self.numframes)+",fps="+str(self.fps)+"]" | |
64 return self.suffix + "[id="+str(self.id)+"]" | |
65 | |
66 def parseFrmInfo(self): | |
67 if self.frminfo_parsed: | |
68 return | |
69 frminfo = os.popen("./frminfo -t " + self.filename).read() | |
70 print >> sys.stderr, "Parsing FRMINFO: ",self.filename | |
71 frminfo = [tuple(line.replace(" ","").split("=")) for line in frminfo.split("\n")[:-1]] | |
72 values = dict(frminfo) | |
73 self.numframes = int(values['num_frames']) | |
74 self.fps = int(values['frames_per_second']) | |
75 self.shiftx = int(values["shift_xy"].split(',')[0]) | |
76 self.frminfo_parsed = True | |
77 def measureDistance(self): | |
78 cmd ="./frminfo -t " +self.filename + " -i " + str(self.numframes-1)+ " -d 1" | |
79 frminfo = os.popen(cmd).read() | |
80 frminfo = [tuple(line.replace(" ","").split("=")) for line in frminfo.split("\n")[:-1]] | |
81 values = dict(frminfo) | |
82 x,y = map(int,values["shift_xy"].split(",")) | |
83 distance = (x - self.shiftx+ 16) / 32 | |
84 print >> sys.stderr, ACTION_NAMES[self.id],"distance:",distance | |
85 return distance | |
86 | |
87 def generatePartialActions(self,actionId): | |
88 partialActions = "" | |
89 npas=1 | |
90 if actionId in [WALK,RUN]: | |
91 npas = self.measureDistance() | |
92 partialActions += MOTION_XML.substitute(distance=npas) | |
93 | |
94 if npas==0: | |
95 npas=1 | |
96 | |
97 delta = (self.numframes/npas) | |
98 startFrame=0 | |
99 endFrame = delta | |
100 nextActionId = actionId | |
101 for number in range(npas): | |
102 nextNumber = (number+1) % npas | |
103 stepNumber=number | |
104 partialActions += PARTIAL_ACTION_XML.safe_substitute(locals()) | |
105 startFrame += delta | |
106 return partialActions | |
107 | |
108 def buildXML(self): | |
109 #if self.id not in [RUN,WALK]: return "" | |
110 self.parseFrmInfo() | |
111 id = self.id | |
112 name = ACTION_NAMES[id] | |
113 fps = self.fps | |
114 numFrames = self.numframes | |
115 filename = self.filename | |
116 partialActions = self.generatePartialActions(id) | |
117 return ACTION_XML.safe_substitute(locals()) | |
118 | |
119 class Critter(object): | |
120 def __init__(self,basename): | |
121 self.basename = basename | |
122 self.actions = {} | |
123 self.xml="" | |
124 def __str__(self): | |
125 return self.basename +"("+",".join(map(str,self.actions.values()))+")" | |
126 | |
127 def addAction(self,suffix): | |
128 action = Action(self,suffix) | |
129 self.actions[ action.id ] = action | |
130 | |
131 def buildXML(self): | |
132 if self.xml: return self.xml | |
133 name = self.basename | |
134 actions = "" | |
135 for action in self.actions.values(): | |
136 actions += action.buildXML() | |
137 | |
138 return CRITTER_XML.safe_substitute(locals()) | |
139 | |
140 def readCritters(): | |
141 critters = os.popen("./frminfo -l 14").read().split("\n")[1:] | |
142 critter_types = {} | |
143 for critter in critters: | |
144 basename = os.path.basename(critter).split('.')[0][:6] | |
145 if not basename: | |
146 continue | |
147 | |
148 action = os.path.basename(critter).split('.')[0][6:] | |
149 if not critter_types.has_key(basename): | |
150 critter_types[ basename ] = Critter(basename) | |
151 critter = critter_types[ basename ] | |
152 critter.addAction( action ) | |
153 | |
154 return critter_types | |
155 | |
156 | |
157 def exportToXML(critter_name,critters,directory="./"): | |
158 if not critters.has_key(critter_name): | |
159 print >> sys.stderr, "Critter ",critter_name," not found." | |
160 sys.exit(1) | |
161 | |
162 critter = critters[critter_name] | |
163 | |
164 xml= critter.buildXML() | |
165 fname = os.path.join(directory,critter.basename + ".xml") | |
166 file =open(fname,"w") | |
167 file.write(xml) | |
168 print >> sys.stderr, "Wrote to ",fname | |
169 | |
170 def main(): | |
171 if len(sys.argv) == 1: | |
172 print USAGE | |
173 sys.exit(1) | |
174 print >> sys.stderr, "Reading Critter List" | |
175 critters = readCritters() | |
176 if sys.argv[1] == '--list': | |
177 for name,critter in critters.items(): | |
178 name_getter = lambda x: ACTION_NAMES[x] | |
179 print name," actions = ",map(name_getter,critter.actions.keys()) | |
180 sys.exit(0) | |
181 | |
182 if len(sys.argv) == 2: | |
183 print USAGE | |
184 sys.exit(1) | |
185 | |
186 if sys.argv[1] == '--to-xml': | |
187 exportToXML( sys.argv[2], critters) | |
188 if sys.argv[1]=='--all-xml': | |
189 for critter_name in critters.keys(): | |
190 exportToXML(critter_name,critters,sys.argv[2]) | |
191 | |
192 if __name__=="__main__": main(); |