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.5 by root, Sun Sep 3 07:57:54 2006 UTC vs.
Revision 1.13 by pippijn, Tue Jan 2 23:39:21 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines