1 #include "PieceP.h"
2 
3 #include "configure.h"
4 
5 #include "etc.h"
6 
7 #ifndef DEFAULT_PROBABILITY
8 #define DEFAULT_PROBABILITY 0.1
9 #endif
10 
11 #ifndef DEFAULT_SIZE
12 #define DEFAULT_SIZE 3
13 #endif
14 
15 #ifndef DEFAULT_AIR
16 #define DEFAULT_AIR 0.05
17 #endif
18 
19 #ifndef DEFAULT_GRAVITY
20 #define DEFAULT_GRAVITY 0.3
21 #endif
22 
23 #ifndef DEFAULT_TRANSMISSION
24 #define DEFAULT_TRANSMISSION 60.0
25 #endif
26 
27 #ifndef DEFAULT_AFTER_IMAGE
28 #define DEFAULT_AFTER_IMAGE 10
29 #endif
30 
31 /* x, y, z �ʤɤ����������ݤ��ơ�malloc() �ο����餷����٤����� */
32 #if 1
33 #ifndef ONE_BUNDLE_ALLOCATE
34 #define ONE_BUNDLE_ALLOCATE
35 #endif
36 #else
37 #ifdef ONE_BUNDLE_ALLOCATE
38 #undef ONE_BUNDLE_ALLOCATE
39 #endif
40 #endif
41 
42 /*===========================================================================*/
43 /* ���֥������ȤΥ��Фμ���                                                */
44 /*===========================================================================*/
45 
46 /*---------------------------------------------------------------------------*/
47 /* PieceClass ���饹                                                         */
48 /*---------------------------------------------------------------------------*/
49 
PieceClass_GetName(PieceClass piece_class)50 char * PieceClass_GetName(PieceClass piece_class)
51 { return (piece_class->name); }
52 
PieceClass_GetSize(PieceClass piece_class)53 int PieceClass_GetSize(PieceClass piece_class)
54 { return (piece_class->size); }
55 
PieceClass_GetProbability(PieceClass piece_class)56 double PieceClass_GetProbability(PieceClass piece_class)
57 { return (piece_class->probability); }
58 
PieceClass_GetGCListList(PieceClass piece_class)59 ObjList PieceClass_GetGCListList(PieceClass piece_class)
60 { return (piece_class->gc_list_list); }
61 
PieceClass_GetNextList(PieceClass piece_class)62 ObjList PieceClass_GetNextList(PieceClass piece_class)
63 { return (piece_class->next_list); }
64 
65 /*---------------------------------------------------------------------------*/
66 /* PieceNext ���饹                                                          */
67 /*---------------------------------------------------------------------------*/
68 
PieceNext_GetPieceClass(PieceNext piece_next)69 PieceClass PieceNext_GetPieceClass(PieceNext piece_next)
70 { return (piece_next->piece_class); }
71 
PieceNext_GetPower(PieceNext piece_next)72 double PieceNext_GetPower(PieceNext piece_next) { return (piece_next->power); }
PieceNext_GetNumber(PieceNext piece_next)73 int PieceNext_GetNumber(PieceNext piece_next) { return (piece_next->number); }
74 
75 /*---------------------------------------------------------------------------*/
76 /* Pieces ���饹                                                             */
77 /*---------------------------------------------------------------------------*/
78 
Pieces_GetPieceClass(Pieces pieces)79 PieceClass Pieces_GetPieceClass(Pieces pieces) {return (pieces->piece_class);}
Pieces_GetArraySize(Pieces pieces)80 int Pieces_GetArraySize(Pieces pieces) { return (pieces->array_size); }
Pieces_GetNumber(Pieces pieces)81 int Pieces_GetNumber(Pieces pieces) { return (pieces->number); }
Pieces_GetPositions(Pieces pieces)82 XArc * Pieces_GetPositions(Pieces pieces) { return (pieces->positions); }
Pieces_GetZ(Pieces pieces)83 double * Pieces_GetZ(Pieces pieces) { return (pieces->z); }
Pieces_GetVx(Pieces pieces)84 double * Pieces_GetVx(Pieces pieces) { return (pieces->vx); }
Pieces_GetVy(Pieces pieces)85 double * Pieces_GetVy(Pieces pieces) { return (pieces->vy); }
Pieces_GetVz(Pieces pieces)86 double * Pieces_GetVz(Pieces pieces) { return (pieces->vz); }
87 
Pieces_GetSize(Pieces pieces)88 int Pieces_GetSize(Pieces pieces) { return (pieces->piece_class->size); }
89 
Pieces_GetGCList(Pieces pieces)90 ObjList Pieces_GetGCList(Pieces pieces)
91 {
92   return ((ObjList)ObjListData_GetObj(pieces->gc_list));
93 }
94 
95 /*===========================================================================*/
96 /* PieceClass ���֥������Ȥκ����������                                     */
97 /*===========================================================================*/
98 
PieceClass_Create(char * name,int size,double probability,double air,double gravity,double transmission,int after_image_length,int fine,ObjList gc_list_list,ObjList next_list,Disp disp)99 PieceClass PieceClass_Create(char * name,
100 			     int size,
101 			     double probability,
102 			     double air,
103 			     double gravity,
104 			     double transmission,
105 			     int after_image_length,
106 			     int fine,
107 			     ObjList gc_list_list,
108 			     ObjList next_list,
109 			     Disp disp)
110 {
111   PieceClass piece_class;
112   int i;
113 
114   piece_class = (PieceClass)malloc(sizeof(_PieceClass));
115   if (!piece_class) Error("PieceClass_Create", "Cannot allocate memory.");
116 
117   if ((name == NULL) || (name[0] == '\0')) name = "Unknown\0";
118 
119   piece_class->name = (char *)malloc(sizeof(char) * (StringLen(name) + 1));
120   if (piece_class->name == NULL)
121     Error("PieceClass_Create", "Cannot allocate memory.");
122   StringCpy(piece_class->name, name);
123 
124   piece_class->size               = size;
125   piece_class->probability        = probability;
126   piece_class->air                = air;
127   piece_class->gravity            = gravity;
128   piece_class->transmission       = transmission;
129   piece_class->after_image_length = after_image_length;
130 
131   if (fine < 1) fine = 1;
132   piece_class->fine = fine;
133   piece_class->step = 100.0 / piece_class->fine;
134 
135   if (gc_list_list) piece_class->gc_list_list = gc_list_list;
136   else              piece_class->gc_list_list = ObjList_Create();
137 
138   if (next_list) piece_class->next_list = next_list;
139   else           piece_class->next_list = ObjList_Create();
140 
141   return (piece_class);
142 }
143 
PieceClass_Destroy(PieceClass piece_class)144 PieceClass PieceClass_Destroy(PieceClass piece_class)
145 {
146   if (!piece_class) return (NULL);
147 
148   if (piece_class->name) free(piece_class->name);
149 
150   if (piece_class->gc_list_list)
151     ObjList_Destroy(piece_class->gc_list_list);
152 
153   if (piece_class->next_list)
154     ObjList_Destroy(piece_class->next_list);
155 
156   free(piece_class);
157 
158   return (NULL);
159 }
160 
161 /*===========================================================================*/
162 /* PieceNext ���֥������Ȥκ����������                                      */
163 /*===========================================================================*/
164 
PieceNext_Create(PieceClass piece_class,double power,int n)165 PieceNext PieceNext_Create(PieceClass piece_class, double power, int n)
166 {
167   PieceNext next;
168 
169   next = (PieceNext)malloc(sizeof(_PieceNext));
170   if (!next) Error("PieceNext_Create", "Cannot allocate memory.");
171 
172   next->piece_class = piece_class;
173   next->power = power;
174   next->number = n;
175 
176   return (next);
177 }
178 
PieceNext_Destroy(PieceNext next)179 PieceNext PieceNext_Destroy(PieceNext next)
180 {
181   if (!next) return (NULL);
182 
183   free(next);
184 
185   return (NULL);
186 }
187 
188 /*===========================================================================*/
189 /* �����ǻ��Ѥ���ؿ�                                                        */
190 /*===========================================================================*/
191 
192 /*---------------------------------------------------------------------------*/
193 /* PieceClass �θ���                                                         */
194 /* ���Ĥ���ʤ��ä����ˤϡ�PieceClass ���֥������Ȥ���������               */
195 /* �ꥹ�Ȥ��ɲä��롥                                                        */
196 /*---------------------------------------------------------------------------*/
197 
PieceClassList_SearchPieceClass(ObjList list,char * name,Disp disp,int default_size,double default_air,double default_gravity,double default_transmission,int default_after_image,int fine)198 static PieceClass PieceClassList_SearchPieceClass(ObjList list,
199 						  char * name,
200 						  Disp disp,
201 						  int default_size,
202 						  double default_air,
203 						  double default_gravity,
204 						  double default_transmission,
205 						  int default_after_image,
206 						  int fine)
207 {
208   ObjListData current;
209   PieceClass piece_class;
210 
211   if (!list) Error("PieceClassList_SearchPieceClass",
212 		   "PieceClassList has not created.");
213 
214   for (current = ObjList_GetStart(list);
215        !ObjList_IsEndEdge(list, current);
216        current = ObjListData_GetNext(current)) {
217     piece_class = (PieceClass)ObjListData_GetObj(current);
218     if (!StringCmp(piece_class->name, name)) {
219       return (piece_class);
220     }
221   }
222 
223   /* ���Ĥ���ʤ��ä����ˤϡ����������ꥹ�Ȥ��ɲä��� */
224   piece_class = PieceClass_Create(name,
225 				  default_size,
226 				  -1.0,
227 				  default_air,
228 				  default_gravity,
229 				  default_transmission,
230 				  default_after_image,
231 				  fine,
232 				  NULL, NULL, disp);
233   ObjList_InsertObjToEnd(list, piece_class, (ObjDestructor)PieceClass_Destroy);
234 
235   return (piece_class);
236 }
237 
238 /*---------------------------------------------------------------------------*/
239 /* ñ��μ���                                                                */
240 /*---------------------------------------------------------------------------*/
241 
GetWord(Stream stream)242 static char * GetWord(Stream stream)
243 {
244   char * word;
245   word = Stream_GetWord(stream, NULL, 0,
246 			"",     /* ����ʸ�����ڤ�ʬ���� */
247 			" \t",  /* ����ʸ���Ǥ��ڤ�ʬ���� */
248 			"!#$%", /* �����ȹԤ���Ƭʸ�� '#' �ʤ� */
249 			"\n",   /* ����ʸ�� '\n' �ʤ� */
250 			"\"\'", /* ������ʸ�� '\"' �ʤ� */
251 			"",     /* ʸ������Ƭ���ɤߤȤФ�ʸ�� */
252 			""      /* ʸ�����������ɤߤȤФ�ʸ�� */
253 			);
254   return (word);
255 }
256 
GetWord2(Stream stream)257 static char * GetWord2(Stream stream)
258 {
259   char * word;
260   word = Stream_GetWord(stream, NULL, 0,
261 			"",     /* ����ʸ�����ڤ�ʬ���� */
262 			" \t",  /* ����ʸ���Ǥ��ڤ�ʬ���� */
263 			"",     /* �����ȹԤ���Ƭʸ�� '#' �ʤ� */
264 			"\n",   /* ����ʸ�� '\n' �ʤ� */
265 			"\"\'", /* ������ʸ�� '\"' �ʤ� */
266 			"",     /* ʸ������Ƭ���ɤߤȤФ�ʸ�� */
267 			""      /* ʸ�����������ɤߤȤФ�ʸ�� */
268 			);
269   return (word);
270 }
271 
ReadNext(ObjList piece_class_list,char * word,Disp disp,int default_size,double default_air,double default_gravity,double default_transmission,int default_after_image,int fine,int next_power_mag,int next_number_mag)272 static ObjList ReadNext(ObjList piece_class_list,
273 			char * word,
274 			Disp disp,
275 			int default_size,
276 			double default_air,
277 			double default_gravity,
278 			double default_transmission,
279 			int default_after_image,
280 			int fine,
281 			int next_power_mag,
282 			int next_number_mag)
283 {
284   ObjList list;
285   Stream stream;
286   char * w1;
287   char * w2;
288   char * w3;
289   PieceClass piece_class;
290   double power;
291   int n;
292 
293   list = ObjList_Create();
294   if (!word) return (list);
295   stream = Stream_CreateFromCharacters(word);
296   if (!stream) return (list);
297 
298   while ((w1 = GetWord2(stream)) != NULL) {
299     w2 = w3 = NULL;
300     piece_class = PieceClassList_SearchPieceClass(piece_class_list, w1, disp,
301 						  default_size,
302 						  default_air,
303 						  default_gravity,
304 						  default_transmission,
305 						  default_after_image,
306 						  fine);
307     w2 = GetWord2(stream);
308     if ((w3 = GetWord2(stream)) != NULL) {
309       power = atof(w2) * next_power_mag * 0.01;
310       n = atoi(w3);
311       if (n > 0) {
312 	n = (n * next_number_mag + 50) / 100;
313 	if (n < 1) n = 1;
314       }
315       ObjList_InsertObjToEnd(list,
316 			     PieceNext_Create(piece_class, power, n),
317 			     (ObjDestructor)PieceNext_Destroy);
318     }
319     if (w1) free(w1);
320     if (w2) free(w2);
321     if (w3) free(w3);
322   }
323 
324   Stream_Destroy(stream);
325 
326   return (list);
327 }
328 
329 /*===========================================================================*/
330 /* �ǡ������ɤ߹���                                                          */
331 /*===========================================================================*/
332 
PieceClassList_CreateFromStream(Disp disp,ColorGCDatabase database,Stream stream,int fine,int probability_mag,int size_mag,int air_mag,int gravity_mag,int transmission_mag,int after_image_mag,int color_length_mag,int next_power_mag,int next_number_mag)333 ObjList PieceClassList_CreateFromStream(Disp disp,
334 					ColorGCDatabase database,
335 					Stream stream,
336 					int fine,
337 					int probability_mag,
338 					int size_mag,
339 					int air_mag,
340 					int gravity_mag,
341 					int transmission_mag,
342 					int after_image_mag,
343 					int color_length_mag,
344 					int next_power_mag,
345 					int next_number_mag)
346 {
347   ObjList piece_class_list;
348   PieceClass current = NULL;
349   char * word;
350   char * word2;
351   ObjList color_gc_list;
352   double default_probability  = DEFAULT_PROBABILITY * probability_mag * 0.01;
353   int default_size            = (DEFAULT_SIZE * size_mag + 50) / 100;
354   double default_air          = DEFAULT_AIR * air_mag * 0.01;
355   double default_gravity      = DEFAULT_GRAVITY * gravity_mag * 0.01;
356   double default_transmission = DEFAULT_TRANSMISSION * transmission_mag * 0.01;
357   int default_after_image     =
358     (DEFAULT_AFTER_IMAGE * after_image_mag + 50) / 100;
359 
360   piece_class_list = ObjList_Create();
361 
362   while ((word = GetWord(stream)) != NULL) {
363     word2 = NULL;
364 
365     if (!StringCmp(word, "Name")) {
366       if ((word2 = GetWord(stream)) != NULL) {
367 	current =
368 	  PieceClassList_SearchPieceClass(piece_class_list, word2, disp,
369 					  default_size,
370 					  default_air,
371 					  default_gravity,
372 					  default_transmission,
373 					  default_after_image,
374 					  fine);
375       }
376     } else if (!StringCmp(word, "DefaultProbability")) {
377       if ((word2 = GetWord(stream)) != NULL) {
378 	default_probability = atof(word2) * probability_mag * 0.01;
379       }
380     } else if (!StringCmp(word, "DefaultSize")) {
381       if ((word2 = GetWord(stream)) != NULL) {
382 	default_size = (atoi(word2) * size_mag + 50) / 100;
383       }
384     } else if (!StringCmp(word, "DefaultAir")) {
385       if ((word2 = GetWord(stream)) != NULL) {
386 	default_air = atof(word2) * air_mag * 0.01;
387       }
388     } else if (!StringCmp(word, "DefaultGravity")) {
389       if ((word2 = GetWord(stream)) != NULL) {
390 	default_gravity = atof(word2) * gravity_mag * 0.01;
391       }
392     } else if (!StringCmp(word, "DefaultTransmission")) {
393       if ((word2 = GetWord(stream)) != NULL) {
394 	default_transmission = atof(word2) * transmission_mag * 0.01;
395       }
396     } else if (!StringCmp(word, "DefaultAfterImage")) {
397       if ((word2 = GetWord(stream)) != NULL) {
398 	default_after_image = (atoi(word2) * after_image_mag + 50) / 100;
399       }
400     } else {
401       if (current) {
402 	if (!StringCmp(word, "Size")) {
403 	  if ((word2 = GetWord(stream)) != NULL) {
404 	    if (!StringCmp(word2, "Default") || !StringCmp(word2, "default"))
405 	      current->size = default_size;
406 	    else current->size = (atoi(word2) * size_mag + 50) / 100;
407 	  }
408 	} else if (!StringCmp(word, "Probability")) {
409 	  if ((word2 = GetWord(stream)) != NULL) {
410 	    if (!StringCmp(word2, "Default") || !StringCmp(word2, "default"))
411 	      current->probability = default_probability;
412 	    else if (!StringCmp(word2, "None") || !StringCmp(word2, "none"))
413 	      current->probability = -1.0;
414 	    else current->probability = atof(word2) * probability_mag * 0.01;
415 	  }
416 	} else if (!StringCmp(word, "Air")) {
417 	  if ((word2 = GetWord(stream)) != NULL) {
418 	    if (!StringCmp(word2, "Default") || !StringCmp(word2, "default"))
419 	      current->air = default_air;
420 	    else current->air = atof(word2) * air_mag * 0.01;
421 	  }
422 	} else if (!StringCmp(word, "Gravity")) {
423 	  if ((word2 = GetWord(stream)) != NULL) {
424 	    if (!StringCmp(word2, "Default") || !StringCmp(word2, "default"))
425 	      current->gravity = default_gravity;
426 	    else current->gravity = atof(word2) * gravity_mag * 0.01;
427 	  }
428 	} else if (!StringCmp(word, "Transmission")) {
429 	  if ((word2 = GetWord(stream)) != NULL) {
430 	    if (!StringCmp(word2, "Default") || !StringCmp(word2, "default"))
431 	      current->transmission = default_transmission;
432 	    else current->transmission = atof(word2) * transmission_mag * 0.01;
433 	  }
434 	} else if (!StringCmp(word, "AfterImage")) {
435 	  if ((word2 = GetWord(stream)) != NULL) {
436 	    if (!StringCmp(word2, "Default") || !StringCmp(word2, "default"))
437 	      current->after_image_length = default_after_image;
438 	    else current->after_image_length =
439 		   (atoi(word2) * after_image_mag + 50) / 100;
440 	  }
441 	} else if (!StringCmp(word, "Color")) {
442 	  if ((word2 = GetWord(stream)) != NULL) {
443 	    if (current->gc_list_list == NULL)
444 	      current->gc_list_list = ObjList_Create();
445 	    if (!StringEqual(word2, "None") && !StringEqual(word2, "none")) {
446 	      color_gc_list =
447 		CreateColorGCListFromCharacters(database,
448 						word2,
449 						current->after_image_length,
450 						fine,
451 						color_length_mag);
452 	      ObjList_Concatenate(current->gc_list_list, color_gc_list);
453 	    }
454 	  }
455 	} else if (!StringCmp(word, "Next")) {
456 	  if ((word2 = GetWord(stream)) != NULL) {
457 	    if (current->next_list == NULL)
458 	      current->next_list = ObjList_Create();
459 	    if (!StringEqual(word2, "None") && !StringEqual(word2, "none")) {
460 	      ObjList_Concatenate(current->next_list,
461 				  ReadNext(piece_class_list, word2, disp,
462 					   default_size,
463 					   default_air,
464 					   default_gravity,
465 					   default_transmission,
466 					   default_after_image,
467 					   fine,
468 					   next_power_mag,
469 					   next_number_mag));
470 	    }
471 	  }
472 	} else if (!StringCmp(word, "End")) {
473 	  if (word)  free(word);
474 	  if (word2) free(word2);
475 	  return (piece_class_list);
476 	} else {
477 	  fprintf(stderr, "Unknown command : %s\n", word);
478 	}
479       } else {
480 	fprintf(stderr,
481 		"Cannot specify class name. Command was ignored. : %s\n",
482 		word);
483       }
484     }
485     if (word)  free(word);
486     if (word2) free(word2);
487   }
488 
489   return (piece_class_list);
490 }
491 
492 /*===========================================================================*/
493 /* Pieces ���֥������Ȥ����                                                 */
494 /*===========================================================================*/
495 
496 /*---------------------------------------------------------------------------*/
497 /* Pieces ���֥������Ȥν����                                               */
498 /*---------------------------------------------------------------------------*/
499 
Pieces_Initialize(Pieces pieces,PieceClass piece_class,double power,int number,int n,XArc * positions,double * z,double * vx,double * vy,double * vz,int x_min,int y_min,int x_max,int y_max,Calculator calculator)500 int Pieces_Initialize(Pieces pieces,
501 		      PieceClass piece_class, double power,
502 		      int number, int n,
503 		      XArc * positions, double * z,
504 		      double * vx, double * vy, double * vz,
505 		      int x_min, int y_min, int x_max, int y_max,
506 		      Calculator calculator)
507 {
508   int i, j, a;
509   int rad, z_rad;
510   double p, t;
511 
512   pieces->piece_class = piece_class;
513   pieces->gc_list = ObjList_GetStartEdge(pieces->piece_class->gc_list_list);
514 
515   if (n * number > pieces->array_size) return (1);
516 
517   a = 0;
518   for (i = 0; i < n; i++) {
519     for (j = 0; j < number; j++) {
520       z_rad = Rand(CALCULATOR_DEFAULT_DEGREE);
521       p = Calculator_GetCos(calculator, z_rad);
522       rad = Rand(CALCULATOR_DEFAULT_DEGREE);
523       pieces->positions[a] = positions[i];
524       pieces->positions[a].width  = pieces->piece_class->size;
525       pieces->positions[a].height = pieces->piece_class->size;
526       pieces->z[a] = z[i];
527       t = pieces->piece_class->transmission * 0.01;
528       pieces->vx[a] = Calculator_GetCos(calculator,   rad) *power*p+ vx[i] * t;
529       pieces->vy[a] = Calculator_GetSin(calculator,   rad) *power*p+ vy[i] * t;
530       pieces->vz[a] = Calculator_GetSin(calculator, z_rad) * power + vz[i] * t;
531       if ( ((pieces->positions[a].x < x_min) && (pieces->vx[a] < 0.0)) ||
532 	   ((pieces->positions[a].x > x_max) && (pieces->vx[a] > 0.0)) ||
533 	   ((pieces->positions[a].y > y_max) && (pieces->vy[a] > 0.0)) ) {
534 	/* None */
535       } else {
536 	a++;
537       }
538     }
539   }
540   pieces->number = a;
541 
542   return (0);
543 }
544 
545 /*---------------------------------------------------------------------------*/
546 /* Pieces ���֥������Ȥ�����                                                 */
547 /*---------------------------------------------------------------------------*/
548 
Pieces_Create(PieceClass piece_class,double power,int number,int n,XArc * positions,double * z,double * vx,double * vy,double * vz,int x_min,int y_min,int x_max,int y_max,Calculator calculator)549 Pieces Pieces_Create(PieceClass piece_class, double power, int number, int n,
550 		     XArc * positions, double * z,
551 		     double * vx, double * vy, double * vz,
552 		     int x_min, int y_min, int x_max, int y_max,
553 		     Calculator calculator)
554 {
555   Pieces pieces;
556 
557   pieces = (Pieces)malloc(sizeof(_Pieces));
558   if (!pieces) Error("Pieces_Create", "Cannot allocate memory");
559 
560   pieces->array_size = number * n;
561 
562   /* Pieces ���֥������ȤϻȤ�������Τǡ��������������Τ�Τ�      */
563   /* �����̵�̤˿��äƤ��ޤ��Τǡ����������Τ��ᡤ���ޤ꾮���� */
564   /* �������Τ�ΤϺ��ʤ��褦�ˤ��롥                               */
565   if (pieces->array_size < 30) pieces->array_size = 30;
566 
567   if (pieces->array_size) {
568 
569     pieces->positions = (XArc *)malloc(sizeof(XArc) * pieces->array_size);
570     if (pieces->positions == NULL)
571       Error("Pieces_Create", "Cannot allocate memory");
572 
573 #ifdef ONE_BUNDLE_ALLOCATE
574     pieces->z = (double *)malloc(sizeof(double) * pieces->array_size * 4);
575     if (pieces->z == NULL) Error("Pieces_Create", "Cannot allocate memory");
576     pieces->vx = pieces->z + pieces->array_size * 1;
577     pieces->vy = pieces->z + pieces->array_size * 2;
578     pieces->vz = pieces->z + pieces->array_size * 3;
579 #else
580     pieces->z  = (double *)malloc(sizeof(double) * pieces->array_size);
581     if (pieces->z  == NULL) Error("Pieces_Create", "Cannot allocate memory");
582     pieces->vx = (double *)malloc(sizeof(double) * pieces->array_size);
583     if (pieces->vx == NULL) Error("Pieces_Create", "Cannot allocate memory");
584     pieces->vy = (double *)malloc(sizeof(double) * pieces->array_size);
585     if (pieces->vy == NULL) Error("Pieces_Create", "Cannot allocate memory");
586     pieces->vz = (double *)malloc(sizeof(double) * pieces->array_size);
587     if (pieces->vz == NULL) Error("Pieces_Create", "Cannot allocate memory");
588 #endif
589   } else {
590     pieces->positions  = NULL;
591     pieces->z  = NULL;
592     pieces->vx = NULL;
593     pieces->vy = NULL;
594     pieces->vz = NULL;
595   }
596 
597   Pieces_Initialize(pieces, piece_class, power, number, n,
598 		    positions, z, vx, vy, vz, x_min, y_min, x_max, y_max,
599 		    calculator);
600 
601   return (pieces);
602 }
603 
604 /*---------------------------------------------------------------------------*/
605 /* Piece ���֥������Ȥκ��                                                  */
606 /*---------------------------------------------------------------------------*/
607 
Pieces_Destroy(Pieces pieces)608 Pieces Pieces_Destroy(Pieces pieces)
609 {
610   if (!pieces) return (NULL);
611 
612   if (pieces->positions) free(pieces->positions);
613 
614 #ifdef ONE_BUNDLE_ALLOCATE
615   if (pieces->z ) free(pieces->z );
616 #else
617   if (pieces->z ) free(pieces->z );
618   if (pieces->vx) free(pieces->vx);
619   if (pieces->vy) free(pieces->vy);
620   if (pieces->vz) free(pieces->vz);
621 #endif
622 
623   free(pieces);
624 
625   return (NULL);
626 }
627 
628 /*---------------------------------------------------------------------------*/
629 /* Pieces ���֥������Ȥΰ�ư                                                 */
630 /*---------------------------------------------------------------------------*/
631 
Pieces_Move(Pieces pieces,int x_min,int y_min,int x_max,int y_max,int size)632 int Pieces_Move(Pieces pieces,
633 		int x_min, int y_min, int x_max, int y_max, int size)
634 {
635   int length;
636   int i, a;
637   double z;
638   double step;
639   double air, g;
640   double tmp1, tmp2;
641 
642   if (ObjList_IsEnd(pieces->piece_class->gc_list_list, pieces->gc_list))
643     return (1);
644 
645   step = pieces->piece_class->step;
646   air = 1.0 - pieces->piece_class->air * step;
647   g = pieces->piece_class->gravity * step;
648   tmp1 = step * size * 0.001;
649 
650   a = 0;
651   for (i = 0; i < pieces->number; i++) {
652     if (a) {
653       pieces->positions[i] = pieces->positions[i + a];
654       pieces->z[ i] = pieces->z[ i + a];
655       pieces->vx[i] = pieces->vx[i + a];
656       pieces->vy[i] = pieces->vy[i + a];
657       pieces->vz[i] = pieces->vz[i + a];
658     }
659 
660     pieces->vy[i] += g;
661 
662     /* �������η׻� */
663     pieces->vx[i] *= air;
664     pieces->vy[i] *= air;
665     pieces->vz[i] *= air;
666 
667     /* ���Ԥ��η׻� */
668     pieces->z[i] += pieces->vz[i] * step;
669     z = 1.0 - pieces->z[i] * (1.0 / 1000.0);
670     if (z < 0.01) z = 0.01;
671 
672     tmp2 = z * tmp1;
673     pieces->positions[i].x += pieces->vx[i] * tmp2;
674     pieces->positions[i].y += pieces->vy[i] * tmp2;
675 
676     if (((pieces->positions[i].x < x_min) && (pieces->vx[i] < 0.0)) ||
677 	((pieces->positions[i].x > x_max) && (pieces->vx[i] > 0.0)) ||
678 	(pieces->positions[i].y > y_max)) {
679       i--;
680       a++;
681       pieces->number--;
682     }
683   }
684 
685   if (pieces->number == 0) return (1);
686 
687   pieces->gc_list = ObjListData_GetNext(pieces->gc_list);
688 
689   return (0);
690 }
691 
692 /*****************************************************************************/
693 /* End of Program                                                            */
694 /*****************************************************************************/
695