1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * ©1995 Artsoft Development *
6 * 33659 Bielefeld-Senne *
7 * Telefon: (0521) 493245 *
8 * eMail: aeglos@valinor.owl.de *
9 * aeglos@uni-paderborn.de *
10 * q99492@pbhrzx.uni-paderborn.de *
11 *----------------------------------------------------------*
13 ***********************************************************/
22 #include <sys/param.h>
23 #include <sys/types.h>
25 void microsleep(unsigned long usec)
29 delay.tv_sec = usec / 1000000;
30 delay.tv_usec = usec % 1000000;
32 if (select(0,NULL,NULL,NULL,&delay)!=0)
33 fprintf(stderr,"%s: in function microsleep: select failed!\n",
37 long mainCounter(int mode)
39 static struct timeval base_time = { 0, 0 };
40 struct timeval current_time;
43 gettimeofday(¤t_time,NULL);
44 if (mode==0 || current_time.tv_sec<base_time.tv_sec)
45 base_time = current_time;
47 counter_ms = (current_time.tv_sec - base_time.tv_sec)*1000
48 + (current_time.tv_usec - base_time.tv_usec)/1000;
51 return(counter_ms/10); /* return 1/100 secs since last init */
53 return(counter_ms); /* return 1/1000 secs since last init */
56 void InitCounter() /* set counter back to zero */
61 long Counter() /* returns 1/100 secs since last call of InitCounter() */
63 return(mainCounter(1));
66 long Counter2() /* returns 1/1000 secs since last call of InitCounter() */
68 return(mainCounter(2));
71 void WaitCounter(long value) /* wait for counter to reach value */
75 while((wait=value-Counter())>0)
76 microsleep(wait*10000);
79 void WaitCounter2(long value) /* wait for counter to reach value */
83 while((wait=value-Counter2())>0)
84 microsleep(wait*1000);
87 void Delay(long value)
92 BOOL DelayReached(long *counter_var, int delay)
94 long actual_counter = Counter();
96 if (actual_counter>*counter_var+delay || actual_counter<*counter_var)
98 *counter_var = actual_counter;
105 unsigned long be2long(unsigned long *be) /* big-endian -> longword */
107 unsigned char *ptr = (unsigned char *)be;
109 return(ptr[0]<<24 | ptr[1]<<16 | ptr[2]<<8 | ptr[3]);
112 char *int2str(int ct, int nr)
116 sprintf(str,"%09d",ct);
117 return(&str[strlen(str)-nr]);
120 unsigned int RND(unsigned int max)
122 return(rand() % max);
125 unsigned int InitRND(long seed)
127 struct timeval current_time;
129 if (seed==NEW_RANDOMIZE)
131 gettimeofday(¤t_time,NULL);
132 srand((unsigned int) current_time.tv_usec);
133 return((unsigned int) current_time.tv_usec);
137 srand((unsigned int) seed);
138 return((unsigned int) seed);
146 if (!(pwd=getpwuid(getuid())))
149 return(pwd->pw_name);
154 HandleAnimation(ANIM_START);
159 HandleAnimation(ANIM_STOP);
164 HandleAnimation(ANIM_CONTINUE);
167 void HandleAnimation(int mode)
169 static long animstart_delay = -1;
170 static long animstart_delay_value = 0;
171 static BOOL anim_restart = TRUE;
172 static BOOL reset_delay = TRUE;
173 static int toon_nr = 0;
175 if (!toons_on || game_status==PLAYING)
188 redraw_mask |= REDRAW_FIELD;
198 animstart_delay = Counter();
199 animstart_delay_value = RND(500);
205 if (!DelayReached(&animstart_delay,animstart_delay_value))
208 toon_nr = RND(NUM_TOONS);
211 anim_restart = reset_delay = AnimateToon(toon_nr,anim_restart);
214 BOOL AnimateToon(int toon_nr, BOOL restart)
216 static pos_x = 0, pos_y = 0;
217 static delta_x = 0, delta_y = 0;
218 static int frame = 0, frame_step = 1;
219 static BOOL horiz_move, vert_move;
220 static long anim_delay = 0;
221 static int anim_delay_value = 0;
222 static int width,height;
223 static int pad_x,pad_y;
224 static int cut_x,cut_y;
225 static int src_x, src_y;
226 static int dest_x, dest_y;
227 static struct AnimInfo toon[NUM_TOONS] =
229 DWARF_XSIZE, DWARF_YSIZE,
238 DWARF_XSIZE, DWARF_YSIZE,
247 JUMPER_XSIZE, JUMPER_YSIZE,
256 CLOWN_XSIZE, CLOWN_YSIZE,
265 BIRD_XSIZE, BIRD_YSIZE,
274 BIRD_XSIZE, BIRD_YSIZE,
283 struct AnimInfo *anim = &toon[toon_nr];
287 horiz_move = (anim->direction & (ANIMDIR_LEFT | ANIMDIR_RIGHT));
288 vert_move = (anim->direction & (ANIMDIR_UP | ANIMDIR_DOWN));
289 anim_delay_value = 100/anim->frames_per_second;
294 if (anim->position==ANIMPOS_UP)
296 else if (anim->position==ANIMPOS_DOWN)
297 pos_y = FULL_SYSIZE-anim->height;
298 else if (anim->position==ANIMPOS_UPPER)
299 pos_y = RND((FULL_SYSIZE-anim->height)/2);
301 pos_y = RND(FULL_SYSIZE-anim->height);
303 if (anim->direction==ANIMDIR_RIGHT)
305 delta_x = anim->stepsize;
306 pos_x = -anim->width+delta_x;
310 delta_x = -anim->stepsize;
311 pos_x = FULL_SXSIZE+delta_x;
317 if (anim->position==ANIMPOS_LEFT)
319 else if (anim->position==ANIMPOS_RIGHT)
320 pos_x = FULL_SXSIZE-anim->width;
322 pos_x = RND(FULL_SXSIZE-anim->width);
324 if (anim->direction==ANIMDIR_DOWN)
326 delta_y = anim->stepsize;
327 pos_y = -anim->height+delta_y;
331 delta_y = -anim->stepsize;
332 pos_y = FULL_SYSIZE+delta_y;
338 if (pos_x <= -anim->width - anim->stepsize ||
339 pos_x >= FULL_SXSIZE + anim->stepsize ||
340 pos_y <= -anim->height - anim->stepsize ||
341 pos_y >= FULL_SYSIZE + anim->stepsize)
344 if (!DelayReached(&anim_delay,anim_delay_value))
346 if (game_status==HELPSCREEN && !restart)
347 DrawAnim(src_x+cut_x,src_y+cut_y, width,height,
348 REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
353 if (pos_x<-anim->width)
354 pos_x = -anim->width;
355 else if (pos_x>FULL_SXSIZE)
357 if (pos_y<-anim->height)
358 pos_y = -anim->height;
359 else if (pos_y>FULL_SYSIZE)
362 pad_x = (horiz_move ? anim->stepsize : 0);
363 pad_y = (vert_move ? anim->stepsize : 0);
364 src_x = anim->src_x + frame * anim->width;
370 height = anim->height;
378 else if (pos_x>FULL_SXSIZE-anim->width)
379 width -= (pos_x - (FULL_SXSIZE-anim->width));
387 else if (pos_y>FULL_SYSIZE-anim->height)
388 height -= (pos_y - (FULL_SYSIZE-anim->height));
390 DrawAnim(src_x+cut_x,src_y+cut_y, width,height,
391 REAL_SX+dest_x,REAL_SY+dest_y, pad_x,pad_y);
397 if (frame<0 || frame>=anim->frames)
402 frame = (frame<0 ? 1 : anim->frames-2);
405 frame = (frame<0 ? anim->frames-1 : 0);
411 void DrawAnim(int src_x, int src_y, int width, int height,
412 int dest_x, int dest_y, int pad_x, int pad_y)
414 int buf_x = DOOR_GFX_PAGEX3, buf_y = DOOR_GFX_PAGEY1;
417 /* special method to avoid flickering interference with BackToFront() */
418 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
419 width+2*pad_x,height+2*pad_y, buf_x,buf_y);
420 XSetClipOrigin(display,clip_gc[PIX_TOONS],dest_x-src_x,dest_y-src_y);
421 XCopyArea(display,pix[PIX_TOONS],backbuffer,clip_gc[PIX_TOONS],
422 src_x,src_y, width,height, dest_x,dest_y);
423 XCopyArea(display,backbuffer,window,gc, dest_x-pad_x,dest_y-pad_y,
424 width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
426 XCopyArea(display,pix[PIX_DB_DOOR],backbuffer,gc, buf_x,buf_y,
427 width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);
429 /* normal method, causing flickering interference with BackToFront() */
430 XCopyArea(display,backbuffer,pix[PIX_DB_DOOR],gc,dest_x-pad_x,dest_y-pad_y,
431 width+2*pad_x,height+2*pad_y, buf_x,buf_y);
432 XSetClipOrigin(display,clip_gc[PIX_TOONS],
433 buf_x-src_x+pad_x,buf_y-src_y+pad_y);
434 XCopyArea(display,pix[PIX_TOONS],pix[PIX_DB_DOOR],clip_gc[PIX_TOONS],
435 src_x,src_y, width,height, buf_x+pad_x,buf_y+pad_y);
436 XCopyArea(display,pix[PIX_DB_DOOR],window,gc, buf_x,buf_y,
437 width+2*pad_x,height+2*pad_y, dest_x-pad_x,dest_y-pad_y);