1 #include "XFireworksP.h"
2
3 #include <signal.h>
4
5 #include "etc.h"
6 #include "Piece.h"
7 #include "AfterImage.h"
8
9 #include "xfireworks_conf.h"
10
11 /*===========================================================================*/
12 /* �����ǻ��Ѥ���ؿ� */
13 /*===========================================================================*/
14
15 /*---------------------------------------------------------------------------*/
16 /* ����ե�����졼������ѤΥե������õ����̵����Хǥե���ȤΥǡ����� */
17 /* �ɤ߹��ࡥ */
18 /*---------------------------------------------------------------------------*/
19
Stream_CreateFromFileOrCharacters(char * dirname,char * filename,char * default_xfireworks_conf)20 static Stream Stream_CreateFromFileOrCharacters(char * dirname,
21 char * filename,
22 char * default_xfireworks_conf)
23 {
24 Stream stream;
25 char * work;
26
27 stream = Stream_CreateFromFile(filename);
28 if (stream != NULL) return (stream);
29
30 /* dirname �� "" ���ä��Ȥ��ˡ�./[filename] �Τ褦�ʥե������ */
31 /* Ĵ�٤�Τǡ�1 �ǤϤʤ� 3 ��ä��Ƥ��롥 */
32 work = (char *)malloc(sizeof(char)
33 * (StringLen(dirname) + StringLen(filename) + 3));
34
35 StringCpy(work, "./");
36 StringCat(work, filename);
37
38 stream = Stream_CreateFromFile(work);
39 if (stream != NULL) goto stream_return;
40
41 StringCpy(work, dirname);
42 StringCat(work, "/");
43 StringCat(work, filename);
44
45 stream = Stream_CreateFromFile(work);
46 if (stream != NULL) goto stream_return;
47
48 stream = Stream_CreateFromCharacters(default_xfireworks_conf);
49
50 stream_return:
51
52 free(work);
53 return (stream);
54 }
55
56 /*===========================================================================*/
57 /* ���֥������Ȥ������Ⱥ�� */
58 /*===========================================================================*/
59
60 /*---------------------------------------------------------------------------*/
61 /* ���֥������Ȥ����� */
62 /*---------------------------------------------------------------------------*/
63
XFireworks_Create(char * display_name,int direct_draw,char * background_color,char * dirname,char * filename,int studying_flag,int cache_flag,int cache_size,int hash_number,int fine,int gradation,int probability_magnification,int size_magnification,int air_magnification,int gravity_magnification,int transmission_magnification,int after_image_magnification,int color_length_magnification,int next_power_magnification,int next_number_magnification)64 XFireworks XFireworks_Create(char * display_name,
65 int direct_draw,
66 char * background_color,
67 char * dirname,
68 char * filename,
69 int studying_flag,
70 int cache_flag,
71 int cache_size,
72 int hash_number,
73 int fine,
74 int gradation,
75 int probability_magnification,
76 int size_magnification,
77 int air_magnification,
78 int gravity_magnification,
79 int transmission_magnification,
80 int after_image_magnification,
81 int color_length_magnification,
82 int next_power_magnification,
83 int next_number_magnification)
84 {
85 XFireworks xfireworks;
86 Stream stream;
87 ColorGC color_gc;
88
89 xfireworks = (XFireworks)malloc(sizeof(_XFireworks));
90 if (!xfireworks) Error("XFireworks_Create", "Cannot allocate mamory");
91
92 /* �������� */
93 InitializeRand();
94
95 /* �ǥ����ץ쥤����� */
96 xfireworks->disp = Disp_Create(display_name, direct_draw);
97
98 /* GC�Υǡ����١�������� */
99 xfireworks->color_gc_database = ColorGCDatabase_Create(xfireworks->disp,
100 studying_flag,
101 cache_flag,
102 cache_size,
103 hash_number,
104 background_color,
105 gradation);
106
107 /* �ǥ����ץ쥤�Υ��ꥢ */
108 color_gc =
109 ColorGCDatabase_GetBackgroundColorGC(xfireworks->color_gc_database);
110 if (!direct_draw)
111 Disp_ClearPixmap(xfireworks->disp, ColorGC_GetGC(color_gc));
112 Disp_ClearDisplay(xfireworks->disp, ColorGC_GetPixel(color_gc));
113
114 /* PieceClass ���ɤ߹��� */
115 stream =
116 Stream_CreateFromFileOrCharacters(dirname, filename,
117 default_xfireworks_conf);
118 xfireworks->piece_class_list =
119 PieceClassList_CreateFromStream(xfireworks->disp,
120 xfireworks->color_gc_database,
121 stream,
122 fine,
123 probability_magnification,
124 size_magnification,
125 air_magnification,
126 gravity_magnification,
127 transmission_magnification,
128 after_image_magnification,
129 color_length_magnification,
130 next_power_magnification,
131 next_number_magnification);
132 Stream_Destroy(stream);
133
134 xfireworks->pieces_list = ObjList_Create();
135 xfireworks->free_pieces_list = ObjList_Create();
136 xfireworks->after_images_list = ObjList_Create();
137 xfireworks->free_after_images_list = ObjList_Create();
138
139 /* �ϥå����������ɽ��(���塼�˥���) */
140 #ifdef OUTPUT_HASH_STATUS
141 ColorGCDatabase_OutputHashStatus(xfireworks->color_gc_database);
142 #endif
143
144 xfireworks->calculator = Calculator_Create(CALCULATOR_DEFAULT_DEGREE);
145
146 return (xfireworks);
147 }
148
149 /*---------------------------------------------------------------------------*/
150 /* ���֥������Ȥκ�� */
151 /*---------------------------------------------------------------------------*/
152
XFireworks_Destroy(XFireworks xfireworks)153 XFireworks XFireworks_Destroy(XFireworks xfireworks)
154 {
155 ColorGC color_gc;
156
157 if (!xfireworks) return (NULL);
158
159 /* �ǥ����ץ쥤�Υ��ꥢ */
160 color_gc =
161 ColorGCDatabase_GetBackgroundColorGC(xfireworks->color_gc_database);
162 Disp_ClearDisplay(xfireworks->disp, ColorGC_GetPixel(color_gc));
163
164 if (xfireworks->calculator) Calculator_Destroy(xfireworks->calculator);
165
166 if (xfireworks->free_after_images_list)
167 ObjList_Destroy(xfireworks->free_after_images_list);
168 if (xfireworks->after_images_list)
169 ObjList_Destroy(xfireworks->after_images_list);
170 if (xfireworks->free_pieces_list)
171 ObjList_Destroy(xfireworks->free_pieces_list);
172 if (xfireworks->pieces_list)
173 ObjList_Destroy(xfireworks->pieces_list);
174
175 if (xfireworks->piece_class_list)
176 ObjList_Destroy(xfireworks->piece_class_list);
177
178 if (xfireworks->color_gc_database)
179 ColorGCDatabase_Destroy(xfireworks->color_gc_database);
180 if (xfireworks->disp) Disp_Destroy(xfireworks->disp);
181
182 free(xfireworks);
183
184 return (NULL);
185 }
186
187 /*===========================================================================*/
188 /* �ֲФΥ������� */
189 /*===========================================================================*/
190
191 /*---------------------------------------------------------------------------*/
192 /* PieceClass ��ɽ��(�ǥХå���) */
193 /*---------------------------------------------------------------------------*/
194
XFireworks_DrawAllPieceClasses(XFireworks xfireworks)195 static int XFireworks_DrawAllPieceClasses(XFireworks xfireworks)
196 {
197 PieceClass piece_class;
198 ObjList gc_list_list;
199 ObjList gc_list;
200 ObjListData a, b, c;
201 GC gc;
202
203 int x, y;
204
205 x = 10;
206 y = 10;
207
208 for (a = ObjList_GetStart(xfireworks->piece_class_list);
209 !ObjList_IsEndEdge(xfireworks->piece_class_list, a);
210 a = ObjListData_GetNext(a)) {
211 piece_class = (PieceClass)ObjListData_GetObj(a);
212 gc_list_list = PieceClass_GetGCListList(piece_class);
213
214 for (b = ObjList_GetStart(gc_list_list);
215 !ObjList_IsEndEdge(gc_list_list, b);
216 b = ObjListData_GetNext(b)) {
217
218 gc_list = ObjListData_GetObj(b);
219
220 x = 10;
221 for (c = ObjList_GetStart(gc_list);
222 !ObjList_IsEndEdge(gc_list, c);
223 c = ObjListData_GetNext(c)) {
224 gc = ColorGC_GetGC(ObjListData_GetObj(c));
225 Disp_DrawFilledCircle(xfireworks->disp, gc, x, y, 5);
226 Disp_Flush(xfireworks->disp);
227 x += 10;
228 }
229 y += 10;
230 }
231 }
232 return (0);
233 }
234
235 /*---------------------------------------------------------------------------*/
236 /* �����ʥ���� */
237 /*---------------------------------------------------------------------------*/
238
239 static int end_flag;
240
InterruptTrap(int n)241 static void InterruptTrap(int n)
242 {
243 end_flag = 1;
244 }
245
246 /*---------------------------------------------------------------------------*/
247 /* ̤���Ѥ� Pieces �Υꥹ�Ȥ��顤�Ȥ��� Pieces ���֥������Ȥ����� */
248 /* ��������롥���Ĥ���ʤ��ä����ˤϡ�create ���롥 */
249 /*---------------------------------------------------------------------------*/
250
SearchOrCreateUsablePieces(XFireworks xfireworks,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)251 static int SearchOrCreateUsablePieces(XFireworks xfireworks,
252 PieceClass piece_class, double power,
253 int number, int n,
254 XArc * positions, double * z,
255 double * vx, double * vy, double * vz,
256 int x_min, int y_min,
257 int x_max, int y_max)
258 {
259 Pieces pieces;
260 ObjListData current;
261
262 for (current = ObjList_GetStart(xfireworks->free_pieces_list);
263 !ObjList_IsEndEdge(xfireworks->free_pieces_list, current);
264 current = ObjListData_GetNext(current)) {
265 pieces = (Pieces)ObjListData_GetObj(current);
266 if (Pieces_GetArraySize(pieces) >= number * n) {
267 Pieces_Initialize(pieces, piece_class, power, number, n,
268 positions, z, vx, vy, vz,
269 x_min, y_min, x_max, y_max,
270 xfireworks->calculator);
271 ObjList_MoveObjToEndOfOtherList(xfireworks->free_pieces_list, current,
272 xfireworks->pieces_list);
273 return (0);
274 }
275 }
276
277 /* ���ѤǤ��� Pieces ���֥������Ȥ�̵���ä��顤�������������� */
278 pieces = Pieces_Create(piece_class, power, number, n,
279 positions, z, vx, vy, vz, x_min, y_min, x_max, y_max,
280 xfireworks->calculator);
281 if (pieces == NULL) return (0);
282 ObjList_InsertObjToEnd(xfireworks->pieces_list, pieces,
283 (ObjDestructor)Pieces_Destroy);
284
285 return (1);
286 }
287
288 /*---------------------------------------------------------------------------*/
289 /* ̤���Ѥ� AfterImages �Υꥹ�Ȥ��顤�Ȥ��� AfterImages ���֥������Ȥ� */
290 /* ����������������롥���Ĥ���ʤ��ä����ˤϡ�create ���롥 */
291 /*---------------------------------------------------------------------------*/
292
SearchOrCreateUsableAfterImages(XFireworks xfireworks,int number,XArc * positions,int x_min,int y_min,int x_max,int y_max,ObjList list)293 static int SearchOrCreateUsableAfterImages(XFireworks xfireworks,
294 int number,
295 XArc * positions,
296 int x_min, int y_min,
297 int x_max, int y_max,
298 ObjList list)
299 {
300 AfterImages after_images;
301 ObjListData current;
302
303 for (current = ObjList_GetStart(xfireworks->free_after_images_list);
304 !ObjList_IsEndEdge(xfireworks->free_after_images_list, current);
305 current = ObjListData_GetNext(current)) {
306 after_images = (AfterImages)ObjListData_GetObj(current);
307 if (AfterImages_GetArraySize(after_images) >= number) {
308 AfterImages_Initialize(after_images, number, positions,
309 x_min, y_min, x_max, y_max, list);
310 ObjList_MoveObjToEndOfOtherList(xfireworks->free_after_images_list,
311 current,
312 xfireworks->after_images_list);
313 return (0);
314 }
315 }
316
317 /* ���ѤǤ��� AfterImages ���֥������Ȥ�̵���ä��顤�������������� */
318 after_images = AfterImages_Create(number, positions,
319 x_min, y_min, x_max, y_max, list);
320 if (after_images == NULL) return (0);
321 ObjList_InsertObjToEnd(xfireworks->after_images_list, after_images,
322 (ObjDestructor)AfterImages_Destroy);
323
324 return (1);
325 }
326
327 /*---------------------------------------------------------------------------*/
328 /* �ֲФΥ������� */
329 /*---------------------------------------------------------------------------*/
330
XFireworks_Start(XFireworks xfireworks,int pieces_max_number,int wait_time)331 int XFireworks_Start(XFireworks xfireworks,
332 int pieces_max_number,
333 int wait_time)
334 {
335 PieceClass piece_class;
336 PieceNext piece_next;
337 Pieces pieces;
338 Pieces pieces2;
339 ObjList next_list;
340 ObjListData current;
341 ObjListData current2;
342 AfterImages after_images;
343 XArc position;
344 double z, vx, vy, vz;
345 GC gc;
346 int ret;
347
348 #if 0
349 XFireworks_DrawAllPieceClasses(xfireworks);
350 while(1) { /* None */ }
351 #endif
352
353 end_flag = 0;
354 signal(SIGINT , InterruptTrap);
355 signal(SIGTERM, InterruptTrap);
356
357 while (end_flag == 0) {
358
359 /* ������ Pieces ������ */
360 if (ObjList_GetLength(xfireworks->pieces_list) < pieces_max_number) {
361
362 for (current = ObjList_GetStart(xfireworks->piece_class_list);
363 !ObjList_IsEndEdge(xfireworks->piece_class_list, current);
364 current = ObjListData_GetNext(current)) {
365 piece_class = (PieceClass)ObjListData_GetObj(current);
366 if (PieceClass_GetProbability(piece_class) > 0.0) {
367 if (PieceClass_GetProbability(piece_class) > DoubleRand(100.0)) {
368 position.x = (double)Rand(Disp_GetWidth( xfireworks->disp));
369 position.y = (double)Rand(Disp_GetHeight(xfireworks->disp));
370 position.width = PieceClass_GetSize(piece_class);
371 position.height = PieceClass_GetSize(piece_class);
372 position.angle1 = 0;
373 position.angle2 = 360*64;
374 z = DoubleRand(400.0) - 200.0;
375 vx = 0.0;
376 vy = 0.0;
377 vz = 0.0;
378 position.y -= Disp_GetHeight(xfireworks->disp) * 0.25;
379
380 SearchOrCreateUsablePieces(xfireworks,
381 piece_class, 0.0, 1, 1,
382 &position, &z, &vx, &vy, &vz,
383 0, 0,
384 Disp_GetWidth( xfireworks->disp) - 1,
385 Disp_GetHeight(xfireworks->disp) - 1);
386 }
387 }
388 }
389 }
390
391 /* Pieces ��� */
392 for (current = ObjList_GetStart(xfireworks->pieces_list);
393 !ObjList_IsEndEdge(xfireworks->pieces_list, current);
394 current = ObjListData_GetNext(current)) {
395
396 pieces = (Pieces)ObjListData_GetObj(current);
397 piece_class = Pieces_GetPieceClass(pieces);
398
399 ret = Pieces_Move(pieces, 0, 0,
400 Disp_GetWidth( xfireworks->disp) - 1,
401 Disp_GetHeight(xfireworks->disp) - 1,
402 Disp_GetWidth( xfireworks->disp));
403 if (ret) { /* dz���Ԥ������ */
404 next_list = PieceClass_GetNextList(piece_class);
405 if ((Pieces_GetNumber(pieces) > 0) && (next_list != NULL)) {
406 for (current2 = ObjList_GetStart(next_list);
407 !ObjList_IsEndEdge(next_list, current2);
408 current2 = ObjListData_GetNext(current2)) {
409 piece_next = (PieceNext)ObjListData_GetObj(current2);
410
411 SearchOrCreateUsablePieces(xfireworks,
412 PieceNext_GetPieceClass(piece_next),
413 PieceNext_GetPower(piece_next),
414 PieceNext_GetNumber(piece_next),
415 Pieces_GetNumber(pieces),
416 Pieces_GetPositions(pieces),
417 Pieces_GetZ(pieces),
418 Pieces_GetVx(pieces),
419 Pieces_GetVy(pieces),
420 Pieces_GetVz(pieces),
421 0, 0,
422 Disp_GetWidth( xfireworks->disp) - 1,
423 Disp_GetHeight(xfireworks->disp) - 1);
424 }
425 }
426 current2 = ObjListData_GetPrev(current);
427 ObjList_MoveObjToStartOfOtherList(xfireworks->pieces_list,
428 current,
429 xfireworks->free_pieces_list);
430 current = current2;
431 } else {
432 SearchOrCreateUsableAfterImages(xfireworks,
433 Pieces_GetNumber(pieces),
434 Pieces_GetPositions(pieces),
435 0, 0,
436 Disp_GetWidth( xfireworks->disp) - 1,
437 Disp_GetHeight(xfireworks->disp) - 1,
438 Pieces_GetGCList(pieces));
439 }
440 }
441
442 /* ������� */
443 for (current = ObjList_GetStart(xfireworks->after_images_list);
444 !ObjList_IsEndEdge(xfireworks->after_images_list, current);
445 current = ObjListData_GetNext(current)) {
446 after_images = (AfterImages)ObjListData_GetObj(current);
447
448 gc = AfterImages_GetGC(after_images);
449
450 if (gc == NULL) {
451 current2 = ObjListData_GetPrev(current);
452 ObjList_MoveObjToStartOfOtherList(xfireworks->after_images_list,
453 current,
454 xfireworks->free_after_images_list);
455 current = current2;
456 } else {
457 if (AfterImages_GetNumber(after_images) > 0)
458 Disp_DrawFilledCircles(xfireworks->disp, gc,
459 AfterImages_GetArcs(after_images),
460 AfterImages_GetNumber(after_images));
461
462 /* X �����Ф�Ϣ³����٤�Ϳ���ʤ�����Υ������� */
463 #if 0
464 usleep(10);
465 #endif
466 }
467 }
468
469 /* X�����Ф˻Ż��Ƥ�餤�� */
470 /* X�����Ф��Ż���λ����Τ��Ԥ� */
471 Disp_Sync(xfireworks->disp);
472
473 /* usleep() �� Disp_Sync() �θ���֤����ȡ� */
474 /* (Disp_Sync() �Ǥ�X�����ФλŻ���λ�Ԥ��ǥ֥�å�����Τǡ� */
475 /* Disp_Sync() ������ usleep() ���֤��Ƥ⤢�ޤ��̣��̵��) */
476 usleep(1000 + wait_time);
477 }
478
479 return (0);
480 }
481
482 /*****************************************************************************/
483 /* End of File. */
484 /*****************************************************************************/
485