ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/anim.C
(Generate patch)

Comparing deliantra/server/common/anim.C (file contents):
Revision 1.6 by root, Sun Sep 3 08:05:39 2006 UTC vs.
Revision 1.10 by root, Thu Sep 14 22:33:58 2006 UTC

1/*
2 * static char *rcsid_anim_c =
3 * "$Id: anim.C,v 1.6 2006/09/03 08:05:39 root Exp $";
4 */
5
6/* 1/*
7 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
8 3
9 Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002-2003 Mark Wedel & Crossfire Development Team
10 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
21 16
22 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 20
26 The authors can be reached via e-mail at crossfire-devel@real-time.com 21 The authors can be reached via e-mail at <crossfire@schmorp.de>
27*/ 22*/
28 23
29/* This file contains animation related code. */ 24/* This file contains animation related code. */
30 25
31#include <global.h> 26#include <global.h>
32#include <stdio.h> 27#include <stdio.h>
33 28
34std::vector<Animations> animations; 29std::vector<Animations> animations;
35 30
31void
36void free_all_anim(void) 32free_all_anim (void)
37{ 33{
38 for (int i=0; i<=num_animations; i++) 34 for (int i = 0; i <= num_animations; i++)
39 { 35 {
40 animations[i].name = 0; 36 animations[i].name = 0;
41 free (animations[i].faces); 37 free (animations[i].faces);
42 } 38 }
43 39
44 animations.clear (); 40 animations.clear ();
45} 41}
46 42
43void
47void init_anim(void) { 44init_anim (void)
45{
46 char
48 char buf[MAX_BUF]; 47 buf[MAX_BUF];
49 FILE *fp; 48 FILE *
50 static int anim_init=0; 49 fp;
50 static int
51 anim_init = 0;
52 int
51 int num_frames=0,faces[MAX_ANIMATIONS],i; 53 num_frames = 0, faces[MAX_ANIMATIONS], i;
52 54
53 if (anim_init) return; 55 if (anim_init)
56 return;
54 num_animations=0; 57 num_animations = 0;
55 /* Make a default. New animations start at one, so if something 58 /* Make a default. New animations start at one, so if something
56 * thinks it is animated but hasn't set the animation_id properly, 59 * thinks it is animated but hasn't set the animation_id properly,
57 * it will have a default value that should be pretty obvious. 60 * it will have a default value that should be pretty obvious.
58 */ 61 */
59 /* set the name so we don't try to dereferance null. 62 /* set the name so we don't try to dereferance null.
60 * Put # at start so it will be first in alphabetical 63 * Put # at start so it will be first in alphabetical
61 * order. 64 * order.
62 */ 65 */
63 { 66 {
64 Animations anim0; 67 Animations anim0;
65 68
66 anim0.name = "###none"; 69 anim0.name = "###none";
67 anim0.num_animations=1; 70 anim0.num_animations = 1;
68 anim0.faces = (Fontindex *) malloc(sizeof(Fontindex)); 71 anim0.faces = (Fontindex *) malloc (sizeof (Fontindex));
69 anim0.faces[0]=0; 72 anim0.faces[0] = 0;
70 anim0.facings=0; 73 anim0.facings = 0;
71 74
72 animations.push_back (anim0); 75 animations.push_back (anim0);
73 } 76 }
74 77
75 sprintf(buf,"%s/animations", settings.datadir); 78 sprintf (buf, "%s/animations", settings.datadir);
76 LOG(llevDebug,"Reading animations from %s...", buf); 79 LOG (llevDebug, "Reading animations from %s...", buf);
77 if ((fp=fopen(buf,"r")) ==NULL) { 80 if ((fp = fopen (buf, "r")) == NULL)
81 {
78 LOG(llevError, "Cannot open animations file %s: %s\n", buf, strerror(errno)); 82 LOG (llevError, "Cannot open animations file %s: %s\n", buf, strerror (errno));
79 exit(-1); 83 exit (-1);
80 } 84 }
81 while (fgets(buf, MAX_BUF-1, fp)!=NULL) { 85 while (fgets (buf, MAX_BUF - 1, fp) != NULL)
82 if (*buf=='#') continue; 86 {
87 if (*buf == '#')
88 continue;
83 /* Kill the newline */ 89 /* Kill the newline */
84 buf[strlen(buf)-1] = '\0'; 90 buf[strlen (buf) - 1] = '\0';
85 if (!strncmp(buf,"anim ", 5)) { 91 if (!strncmp (buf, "anim ", 5))
92 {
86 if (num_frames) { 93 if (num_frames)
94 {
87 LOG(llevError,"Didn't get a mina before %s\n", buf); 95 LOG (llevError, "Didn't get a mina before %s\n", buf);
88 num_frames=0; 96 num_frames = 0;
89 } 97 }
90 num_animations++; 98 num_animations++;
91 99
92 Animations anim; 100 Animations anim;
101
93 anim.name = buf + 5; 102 anim.name = buf + 5;
94 anim.num = num_animations; /* for bsearch */ 103 anim.num = num_animations; /* for bsearch */
95 anim.facings = 1; 104 anim.facings = 1;
96 animations.push_back (anim); 105 animations.push_back (anim);
97 } 106 }
98 else if (!strncmp(buf,"mina",4)) { 107 else if (!strncmp (buf, "mina", 4))
108 {
99 animations[num_animations].faces = (Fontindex *) malloc(sizeof(Fontindex)*num_frames); 109 animations[num_animations].faces = (Fontindex *) malloc (sizeof (Fontindex) * num_frames);
100 for (i=0; i<num_frames; i++) 110 for (i = 0; i < num_frames; i++)
101 animations[num_animations].faces[i]=faces[i]; 111 animations[num_animations].faces[i] = faces[i];
102 animations[num_animations].num_animations = num_frames; 112 animations[num_animations].num_animations = num_frames;
103 if (num_frames % animations[num_animations].facings) { 113 if (num_frames % animations[num_animations].facings)
114 {
104 LOG(llevDebug,"Animation %s frame numbers (%d) is not a multiple of facings (%d)\n", 115 LOG (llevDebug, "Animation %s frame numbers (%d) is not a multiple of facings (%d)\n",
105 &animations[num_animations].name, num_frames, animations[num_animations].facings); 116 &animations[num_animations].name, num_frames, animations[num_animations].facings);
106 } 117 }
107 num_frames=0; 118 num_frames = 0;
108 } 119 }
109 else if (!strncmp(buf,"facings",7)) { 120 else if (!strncmp (buf, "facings", 7))
121 {
110 if (!(animations[num_animations].facings = atoi(buf+7))) { 122 if (!(animations[num_animations].facings = atoi (buf + 7)))
123 {
111 LOG(llevDebug,"Animation %s has 0 facings, line=%s\n", 124 LOG (llevDebug, "Animation %s has 0 facings, line=%s\n", &animations[num_animations].name, buf);
112 &animations[num_animations].name, buf);
113 animations[num_animations].facings=1; 125 animations[num_animations].facings = 1;
114 } 126 }
115 127
128 }
116 } else { 129 else
130 {
117 if (!(faces[num_frames++] = FindFace(buf,0))) 131 if (!(faces[num_frames++] = FindFace (buf, 0)))
118 LOG(llevDebug,"Could not find face %s for animation %s\n", 132 LOG (llevDebug, "Could not find face %s for animation %s\n", buf, &animations[num_animations].name);
119 buf, &animations[num_animations].name);
120 } 133 }
121 } 134 }
122 fclose(fp); 135 fclose (fp);
123 LOG(llevDebug,"done. got (%d)\n", num_animations); 136 LOG (llevDebug, "done. got (%d)\n", num_animations);
124} 137}
125 138
139static int
126static int anim_compare(const Animations *a, const Animations *b) { 140anim_compare (const Animations * a, const Animations * b)
141{
127 return strcmp(a->name, b->name); 142 return strcmp (a->name, b->name);
128} 143}
129 144
130/* Tries to find the animation id that matches name. Returns an integer match 145/* Tries to find the animation id that matches name. Returns an integer match
131 * 0 if no match found (animation 0 is initialized as the 'bug' face 146 * 0 if no match found (animation 0 is initialized as the 'bug' face
132 */ 147 */
148int
133int find_animation(const char *name) 149find_animation (const char *name)
134{ 150{
135 Animations search, *match; 151 Animations
152 search, *
153 match;
136 154
137 search.name = name; 155 search.name = name;
138 156
139 match = (Animations*)bsearch(&search, &animations [0], (num_animations+1), 157 match = (Animations *) bsearch (&search, &animations[0], (num_animations + 1),
140 sizeof(Animations), (int (*)(const void*, const void*))anim_compare); 158 sizeof (Animations), (int (*)(const void *, const void *)) anim_compare);
141 159
142 160
161 if (match)
143 if (match) return match->num; 162 return match->num;
144 LOG(llevError,"Unable to find animation %s\n", name); 163 LOG (llevError, "Unable to find animation %s\n", name);
145 return 0; 164 return 0;
146} 165}
147 166
148/* 167/*
149 * animate_object(object) updates the face-variable of an object. 168 * animate_object(object) updates the face-variable of an object.
150 * If the object is the head of a multi-object, all objects are animated. 169 * If the object is the head of a multi-object, all objects are animated.
153 * op->direction, but in some cases, op->facing is used instead - the 172 * op->direction, but in some cases, op->facing is used instead - the
154 * caller has a better idea which one it really wants to be using, 173 * caller has a better idea which one it really wants to be using,
155 * so let it pass along the right one. 174 * so let it pass along the right one.
156 */ 175 */
157 176
177void
158void animate_object(object *op, int dir) { 178animate_object (object *op, int dir)
179{
180 int
159 int max_state; /* Max animation state object should be drawn in */ 181 max_state; /* Max animation state object should be drawn in */
182 int
160 int base_state; /* starting index # to draw from */ 183 base_state; /* starting index # to draw from */
161 184
162 if(!op->animation_id || !NUM_ANIMATIONS(op)) { 185 if (!op->animation_id || !NUM_ANIMATIONS (op))
186 {
163 LOG(llevError,"Object lacks animation.\n"); 187 LOG (llevError, "Object %s lacks animation.\n", op->debug_desc ());
164 dump_object(op);
165 return; 188 return;
166 } 189 }
190
167 if (op->head) { 191 if (op->head)
192 {
168 dir=op->head->direction; 193 dir = op->head->direction;
169 194
170 if (NUM_ANIMATIONS(op) == NUM_ANIMATIONS(op->head)) 195 if (NUM_ANIMATIONS (op) == NUM_ANIMATIONS (op->head))
171 op->state = op->head->state; 196 op->state = op->head->state;
172 else 197 else
173 ++op->state; 198 ++op->state;
174 } 199 }
175 else { 200 else
176 ++op->state; /* increase draw state */ 201 ++op->state; /* increase draw state */
177 }
178 202
179 /* If object is turning, then max animation state is half through the 203 /* If object is turning, then max animation state is half through the
180 * animations. Otherwise, we can use all the animations. 204 * animations. Otherwise, we can use all the animations.
181 */ 205 */
182 max_state=NUM_ANIMATIONS(op)/ NUM_FACINGS(op); 206 max_state = NUM_ANIMATIONS (op) / NUM_FACINGS (op);
183 base_state=0; 207 base_state = 0;
184 /* at least in the older aniamtions that used is_turning, the first half 208 /* at least in the older aniamtions that used is_turning, the first half
185 * of the animations were left facing, the second half right facing. 209 * of the animations were left facing, the second half right facing.
186 * Note in old the is_turning, it was set so that the animation for a monster 210 * Note in old the is_turning, it was set so that the animation for a monster
187 * was always towards the enemy - now it is whatever direction the monster 211 * was always towards the enemy - now it is whatever direction the monster
188 * is facing. 212 * is facing.
189 */ 213 */
214
190 if (NUM_FACINGS(op)==2) { 215 if (NUM_FACINGS (op) == 2)
216 {
217 if (dir < 5)
191 if (dir<5) base_state=0; 218 base_state = 0;
219 else
192 else base_state=NUM_ANIMATIONS(op)/2; 220 base_state = NUM_ANIMATIONS (op) / 2;
193 } 221 }
194 else if (NUM_FACINGS(op)==4) { 222 else if (NUM_FACINGS (op) == 4)
223 {
224 if (dir == 0)
195 if (dir==0) base_state=0; 225 base_state = 0;
226 else
196 else base_state = ((dir-1)/2) * (NUM_ANIMATIONS(op)/4); 227 base_state = ((dir - 1) / 2) * (NUM_ANIMATIONS (op) / 4);
197 } 228 }
198 else if (NUM_FACINGS(op)==8) { 229 else if (NUM_FACINGS (op) == 8)
230 {
231 if (dir == 0)
199 if (dir==0) base_state=0; 232 base_state = 0;
233 else
200 else base_state = (dir-1)*(NUM_ANIMATIONS(op)/8); 234 base_state = (dir - 1) * (NUM_ANIMATIONS (op) / 8);
201 } 235 }
202 236
203 /* If beyond drawable states, reset */ 237 /* If beyond drawable states, reset */
204 if (op->state>=max_state) op->state=0; 238 if (op->state >= max_state)
239 op->state = 0;
205 240
206 SET_ANIMATION(op, op->state + base_state); 241 SET_ANIMATION (op, op->state + base_state);
207 242
208 if(op->face==blank_face) 243 if (op->face == blank_face)
209 op->invisible=1; 244 op->invisible = 1;
210 245
211 /* This block covers monsters (eg, pixies) which are supposed to 246 /* This block covers monsters (eg, pixies) which are supposed to
212 * cycle from visible to invisible and back to being visible. 247 * cycle from visible to invisible and back to being visible.
213 * as such, disable it for players, as then players would become 248 * as such, disable it for players, as then players would become
214 * visible. 249 * visible.
215 */ 250 */
216 else if(op->type != PLAYER && QUERY_FLAG((&op->arch->clone),FLAG_ALIVE)) { 251 else if (op->type != PLAYER && QUERY_FLAG ((&op->arch->clone), FLAG_ALIVE))
252 {
217 if(op->face->number==0) { 253 if (op->face->number == 0)
254 {
218 op->invisible=1; 255 op->invisible = 1;
219 CLEAR_FLAG(op, FLAG_ALIVE); 256 CLEAR_FLAG (op, FLAG_ALIVE);
257 }
220 } else { 258 else
259 {
221 op->invisible=0; 260 op->invisible = 0;
222 SET_FLAG(op, FLAG_ALIVE); 261 SET_FLAG (op, FLAG_ALIVE);
223 } 262 }
224 } 263 }
225 264
226 if(op->more) 265 if (op->more)
227 animate_object(op->more, dir); 266 animate_object (op->more, dir);
228 267
229 /* update_object will also recursively update all the pieces. 268 /* update_object will also recursively update all the pieces.
230 * as such, we call it last, and only call it for the head 269 * as such, we call it last, and only call it for the head
231 * piece, and not for the other tail pieces. 270 * piece, and not for the other tail pieces.
232 */ 271 */
233 if (!op->head) 272 if (!op->head)
234 update_object(op, UP_OBJ_FACE); 273 update_object (op, UP_OBJ_FACE);
235} 274}
236

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines