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.3 by root, Wed Aug 30 16:30:36 2006 UTC vs.
Revision 1.11 by root, Wed Dec 13 21:27:09 2006 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines