]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/custom_shape.c
Remove stdio while we're at it.
[vlc] / modules / visualization / galaktos / custom_shape.c
1 /*****************************************************************************
2  * custom_shape.c:
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet <asmax@videolan.org>
8  *          code from projectM http://xmms-projectm.sourceforge.net
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 //
26
27
28
29 #include "common.h"
30 #include "fatal.h"
31
32 #include "param_types.h"
33 #include "param.h"
34
35 #include "expr_types.h"
36 #include "eval.h"
37
38 #include "splaytree_types.h"
39 #include "splaytree.h"
40 #include "tree_types.h"
41
42 #include "per_frame_eqn_types.h"
43 #include "per_frame_eqn.h"
44
45 #include "init_cond_types.h"
46 #include "init_cond.h"
47
48 #include "preset_types.h"
49
50 #include "custom_shape_types.h"
51 #include "custom_shape.h"
52
53 #include "init_cond_types.h"
54 #include "init_cond.h"
55
56 custom_shape_t * interface_shape = NULL;
57 int cwave_interface_id = 0;
58 extern preset_t * active_preset;
59 inline void eval_custom_shape_init_conds(custom_shape_t * custom_shape);
60 void load_unspec_init_cond_shape(param_t * param);
61
62 void destroy_param_db_tree_shape(splaytree_t * tree);
63 void destroy_per_frame_eqn_tree_shape(splaytree_t * tree);
64 void destroy_per_frame_init_eqn_tree_shape(splaytree_t * tree);
65 void destroy_init_cond_tree_shape(splaytree_t * tree);
66
67 custom_shape_t * new_custom_shape(int id) {
68
69   custom_shape_t * custom_shape;
70   param_t * param;
71
72   if ((custom_shape = (custom_shape_t*)malloc(sizeof(custom_shape_t))) == NULL)
73     return NULL;
74
75   custom_shape->id = id;
76   custom_shape->per_frame_count = 0;
77   custom_shape->per_frame_eqn_string_index = 0;
78   custom_shape->per_frame_init_eqn_string_index = 0;
79
80   /* Initialize tree data structures */
81
82   if ((custom_shape->param_tree = 
83        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
84     free_custom_shape(custom_shape);
85     return NULL;
86   }
87
88   if ((custom_shape->per_frame_eqn_tree = 
89        create_splaytree(compare_int, copy_int, free_int)) == NULL) {
90     free_custom_shape(custom_shape);
91     return NULL;
92   }
93
94   if ((custom_shape->init_cond_tree = 
95        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
96     free_custom_shape(custom_shape);
97     return NULL;
98   }
99   
100   if ((custom_shape->per_frame_init_eqn_tree = 
101        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
102     free_custom_shape(custom_shape);
103     return NULL;
104   }
105
106   /* Start: Load custom shape parameters */
107
108   if ((param = new_param_double("r", P_FLAG_NONE, &custom_shape->r, NULL, 1.0, 0.0, .5)) == NULL) {
109     free_custom_shape(custom_shape);
110     return NULL;
111   }
112
113   if (insert_param(param, custom_shape->param_tree) < 0) {
114     free_custom_shape(custom_shape);
115     return NULL;
116   }
117  
118   if ((param = new_param_double("g", P_FLAG_NONE, &custom_shape->g, NULL, 1.0, 0.0, .5)) == NULL){
119     free_custom_shape(custom_shape);
120     return NULL;
121   }
122
123   if (insert_param(param, custom_shape->param_tree) < 0) {
124     free_custom_shape(custom_shape);
125     return NULL;
126   }
127
128   if ((param = new_param_double("b", P_FLAG_NONE, &custom_shape->b, NULL, 1.0, 0.0, .5)) == NULL){
129     free_custom_shape(custom_shape);
130     return NULL;                                       
131   }
132
133   if (insert_param(param, custom_shape->param_tree) < 0) {
134     free_custom_shape(custom_shape);
135     return NULL;
136   }
137
138   if ((param = new_param_double("a", P_FLAG_NONE, &custom_shape->a, NULL, 1.0, 0.0, .5)) == NULL){
139     free_custom_shape(custom_shape);
140     return NULL;
141   }
142
143   if (insert_param(param, custom_shape->param_tree) < 0) {
144     free_custom_shape(custom_shape);
145     return NULL;
146   }
147
148   if ((param = new_param_double("border_r", P_FLAG_NONE, &custom_shape->border_r, NULL, 1.0, 0.0, .5)) == NULL) {
149     free_custom_shape(custom_shape);
150     return NULL;
151   }
152
153   if (insert_param(param, custom_shape->param_tree) < 0) {
154     free_custom_shape(custom_shape);
155     return NULL;
156   }
157  
158   if ((param = new_param_double("border_g", P_FLAG_NONE, &custom_shape->border_g, NULL, 1.0, 0.0, .5)) == NULL){
159     free_custom_shape(custom_shape);
160     return NULL;
161   }
162
163   if (insert_param(param, custom_shape->param_tree) < 0) {
164     free_custom_shape(custom_shape);
165     return NULL;
166   }
167
168   if ((param = new_param_double("border_b", P_FLAG_NONE, &custom_shape->border_b, NULL, 1.0, 0.0, .5)) == NULL){
169     free_custom_shape(custom_shape);
170     return NULL;                                       
171   }
172
173   if (insert_param(param, custom_shape->param_tree) < 0) {
174     free_custom_shape(custom_shape);
175     return NULL;
176   }
177
178   if ((param = new_param_double("border_a", P_FLAG_NONE, &custom_shape->border_a, NULL, 1.0, 0.0, .5)) == NULL){
179     free_custom_shape(custom_shape);
180     return NULL;
181   }
182
183   if (insert_param(param, custom_shape->param_tree) < 0) {
184     free_custom_shape(custom_shape);
185     return NULL;
186   }
187
188   if ((param = new_param_double("r2", P_FLAG_NONE, &custom_shape->r2, NULL, 1.0, 0.0, .5)) == NULL) {
189     free_custom_shape(custom_shape);
190     return NULL;
191   }
192
193   if (insert_param(param, custom_shape->param_tree) < 0) {
194     free_custom_shape(custom_shape);
195     return NULL;
196   }
197  
198   if ((param = new_param_double("g2", P_FLAG_NONE, &custom_shape->g2, NULL, 1.0, 0.0, .5)) == NULL){
199     free_custom_shape(custom_shape);
200     return NULL;
201   }
202
203   if (insert_param(param, custom_shape->param_tree) < 0) {
204     free_custom_shape(custom_shape);
205     return NULL;
206   }
207
208   if ((param = new_param_double("b2", P_FLAG_NONE, &custom_shape->b2, NULL, 1.0, 0.0, .5)) == NULL){
209     free_custom_shape(custom_shape);
210     return NULL;                                       
211   }
212
213   if (insert_param(param, custom_shape->param_tree) < 0) {
214     free_custom_shape(custom_shape);
215     return NULL;
216   }
217
218   if ((param = new_param_double("a2", P_FLAG_NONE, &custom_shape->a2, NULL, 1.0, 0.0, .5)) == NULL){
219     free_custom_shape(custom_shape);
220     return NULL;
221   }
222   
223   if (insert_param(param, custom_shape->param_tree) < 0) {
224     free_custom_shape(custom_shape);
225     return NULL;
226   }
227
228   if ((param = new_param_double("x", P_FLAG_NONE, &custom_shape->x, NULL, 1.0, 0.0, .5)) == NULL) {
229     free_custom_shape(custom_shape);
230     return NULL;
231   }
232
233   if (insert_param(param, custom_shape->param_tree) < 0) {
234     free_custom_shape(custom_shape);
235     return NULL;
236   }
237
238   if ((param = new_param_double("y", P_FLAG_NONE, &custom_shape->y, NULL, 1.0, 0.0, .5)) == NULL) {
239     free_custom_shape(custom_shape);
240     return NULL;
241   }
242
243   if (insert_param(param, custom_shape->param_tree) < 0) {
244     free_custom_shape(custom_shape);
245     return NULL;
246   }
247
248   if ((param = new_param_bool("thickOutline", P_FLAG_NONE, &custom_shape->thickOutline, 1, 0, 0)) == NULL) {
249     free_custom_shape(custom_shape);
250     return NULL;
251   }
252
253   if (insert_param(param, custom_shape->param_tree) < 0) {
254     free_custom_shape(custom_shape);
255     return NULL;
256   }
257
258   if ((param = new_param_bool("enabled", P_FLAG_NONE, &custom_shape->enabled, 1, 0, 0)) == NULL) {
259     free_custom_shape(custom_shape);
260     return NULL;
261   }
262
263   if (insert_param(param, custom_shape->param_tree) < 0) {
264     free_custom_shape(custom_shape);
265     return NULL;
266   }
267
268   if ((param = new_param_int("sides", P_FLAG_NONE, &custom_shape->sides, 100, 3, 3)) == NULL) {
269     free_custom_shape(custom_shape);
270     return NULL;
271   }
272
273   if (insert_param(param, custom_shape->param_tree) < 0) {
274     free_custom_shape(custom_shape);
275     return NULL;
276   }
277
278   if ((param = new_param_bool("additive", P_FLAG_NONE, &custom_shape->additive, 1, 0, 0)) == NULL) {
279     free_custom_shape(custom_shape);
280     return NULL;
281   }
282
283   if (insert_param(param, custom_shape->param_tree) < 0) {
284     free_custom_shape(custom_shape);
285     return NULL;
286   }
287
288   if ((param = new_param_bool("textured", P_FLAG_NONE, &custom_shape->textured, 1, 0, 0)) == NULL) {
289     free_custom_shape(custom_shape);
290     return NULL;
291   }
292
293   if (insert_param(param, custom_shape->param_tree) < 0) {
294     free_custom_shape(custom_shape);
295     return NULL;
296   }
297
298    if ((param = new_param_double("rad", P_FLAG_NONE, &custom_shape->rad, NULL, MAX_DOUBLE_SIZE, 0, 0.0)) == NULL) {
299     free_custom_shape(custom_shape);
300     return NULL;
301   }
302
303    if (insert_param(param, custom_shape->param_tree) < 0) {
304     free_custom_shape(custom_shape);
305     return NULL;
306   }
307
308    if ((param = new_param_double("ang", P_FLAG_NONE, &custom_shape->ang, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
309     free_custom_shape(custom_shape);
310     return NULL;
311   }
312
313    if (insert_param(param, custom_shape->param_tree) < 0) {
314     free_custom_shape(custom_shape);
315     return NULL;
316   }
317
318    if ((param = new_param_double("tex_zoom", P_FLAG_NONE, &custom_shape->tex_zoom, NULL, MAX_DOUBLE_SIZE, .00000000001, 0.0)) == NULL) {
319     free_custom_shape(custom_shape);
320     return NULL;
321   }
322
323    if (insert_param(param, custom_shape->param_tree) < 0) {
324     free_custom_shape(custom_shape);
325     return NULL;
326   }
327    
328    if ((param = new_param_double("tex_ang", P_FLAG_NONE, &custom_shape->tex_ang, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
329     free_custom_shape(custom_shape);
330     return NULL;
331   }
332
333    if (insert_param(param, custom_shape->param_tree) < 0) {
334     free_custom_shape(custom_shape);
335     return NULL;
336   }
337    if ((param = new_param_double("t1", P_FLAG_TVAR, &custom_shape->t1, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
338     free_custom_shape(custom_shape);
339     return NULL;
340   }
341
342   if (insert_param(param, custom_shape->param_tree) < 0) {
343     free_custom_shape(custom_shape);
344     return NULL;
345   }
346
347   if ((param = new_param_double("t2", P_FLAG_TVAR, &custom_shape->t2, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
348     free_custom_shape(custom_shape);
349     return NULL;
350   }
351
352   if (insert_param(param, custom_shape->param_tree) < 0) {
353     free_custom_shape(custom_shape);
354     return NULL;
355   }
356
357   if ((param = new_param_double("t3", P_FLAG_TVAR, &custom_shape->t3, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
358     free_custom_shape(custom_shape);
359     return NULL;
360   }
361
362   if (insert_param(param, custom_shape->param_tree) < 0) {
363     free_custom_shape(custom_shape);
364     return NULL;
365   }
366   if ((param = new_param_double("t4", P_FLAG_TVAR, &custom_shape->t4, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
367     free_custom_shape(custom_shape);
368     return NULL;
369   }
370
371   if (insert_param(param, custom_shape->param_tree) < 0) {
372     free_custom_shape(custom_shape);
373     return NULL;
374   }
375   if ((param = new_param_double("t5", P_FLAG_TVAR, &custom_shape->t5, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
376     free_custom_shape(custom_shape);
377     return NULL;
378   }
379  
380   if (insert_param(param, custom_shape->param_tree) < 0) {
381     free_custom_shape(custom_shape);
382     return NULL;
383   }
384   if ((param = new_param_double("t6", P_FLAG_TVAR, &custom_shape->t6, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
385     free_custom_shape(custom_shape);
386     return NULL;
387   }
388
389   if (insert_param(param, custom_shape->param_tree) < 0) {
390     free_custom_shape(custom_shape);
391     return NULL;
392   }
393   if ((param = new_param_double("t7", P_FLAG_TVAR, &custom_shape->t7, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
394     free_custom_shape(custom_shape);
395     return NULL;
396   }
397
398   if (insert_param(param, custom_shape->param_tree) < 0) {
399     free_custom_shape(custom_shape);
400     return NULL;
401   }
402
403   if ((param = new_param_double("t8", P_FLAG_TVAR, &custom_shape->t8, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
404     free_custom_shape(custom_shape);
405     return NULL;
406   }
407
408   if (insert_param(param, custom_shape->param_tree) < 0) {
409     free_custom_shape(custom_shape);
410     return NULL;
411   }
412  
413   /* End of parameter loading. Note that the read only parameters associated
414      with custom shapes (ie, sample) are global variables, and not specific to 
415      the custom shape datastructure. */
416
417
418
419   return custom_shape;
420
421 }
422
423 void destroy_per_frame_init_eqn_tree_shape(splaytree_t * tree) {
424
425   if (!tree)
426     return;
427
428   splay_traverse(free_init_cond, tree);
429   destroy_splaytree(tree);
430
431 }
432
433
434
435 void destroy_init_cond_tree_shape(splaytree_t * tree) {
436
437   if (!tree)
438     return;
439
440   splay_traverse(free_init_cond, tree);
441   destroy_splaytree(tree);
442
443 }
444
445 void destroy_per_frame_eqn_tree_shape(splaytree_t * tree) {
446
447
448   if (!tree)
449     return;
450
451   splay_traverse(free_per_frame_eqn, tree);
452   destroy_splaytree(tree);
453
454 }
455
456
457 void destroy_param_db_tree_shape(splaytree_t * tree) {
458
459   if (!tree)
460     return;
461
462   splay_traverse(free_param, tree);
463   destroy_splaytree(tree);
464
465 }
466
467 /* Frees a custom shape form object */
468 void free_custom_shape(custom_shape_t * custom_shape) {
469
470   if (custom_shape == NULL)
471     return;
472
473   if (custom_shape->param_tree == NULL)
474     return;
475
476   destroy_per_frame_eqn_tree_shape(custom_shape->per_frame_eqn_tree);
477   destroy_init_cond_tree_shape(custom_shape->init_cond_tree);
478   destroy_param_db_tree_shape(custom_shape->param_tree);
479   destroy_per_frame_init_eqn_tree_shape(custom_shape->per_frame_init_eqn_tree);
480   
481   free(custom_shape);
482
483   return;
484
485 }
486
487
488 custom_shape_t * find_custom_shape(int id, preset_t * preset, int create_flag) {
489
490   custom_shape_t * custom_shape = NULL;
491
492   if (preset == NULL)
493     return NULL;
494   
495   if ((custom_shape = splay_find(&id, preset->custom_shape_tree)) == NULL) {
496     
497     if (CUSTOM_SHAPE_DEBUG) { printf("find_custom_shape: creating custom shape (id = %d)...", id);fflush(stdout);}
498     
499     if (create_flag == FALSE) {
500       if (CUSTOM_SHAPE_DEBUG) printf("you specified not to (create flag = false), returning null\n");
501       return NULL;
502     }
503     
504     if ((custom_shape = new_custom_shape(id)) == NULL) {
505       if (CUSTOM_SHAPE_DEBUG) printf("failed...out of memory?\n");
506       return NULL;
507     }
508     
509     if (CUSTOM_SHAPE_DEBUG) { printf("success.Inserting..."); fflush(stdout);}
510     
511     if (splay_insert(custom_shape, &custom_shape->id, preset->custom_shape_tree) < 0) {
512       if (CUSTOM_SHAPE_DEBUG) printf("failed, probably a duplicated!!\n");
513       free_custom_shape(custom_shape);
514       return NULL;
515     }
516     
517     if (CUSTOM_SHAPE_DEBUG) printf("done.\n");
518   }
519   
520   return custom_shape;
521 }
522
523 inline void evalCustomShapeInitConditions() {
524   splay_traverse(eval_custom_shape_init_conds, active_preset->custom_shape_tree);
525
526 }
527
528 inline void eval_custom_shape_init_conds(custom_shape_t * custom_shape) {
529   splay_traverse(eval_init_cond, custom_shape->init_cond_tree);
530   splay_traverse(eval_init_cond, custom_shape->per_frame_init_eqn_tree);
531 }
532
533
534 void load_unspecified_init_conds_shape(custom_shape_t * custom_shape) {
535
536   interface_shape = custom_shape;
537   splay_traverse(load_unspec_init_cond_shape, interface_shape->param_tree);
538   interface_shape = NULL;
539  
540 }
541
542 void load_unspec_init_cond_shape(param_t * param) {
543
544   init_cond_t * init_cond;
545   value_t init_val;
546
547   /* Don't count read only parameters as initial conditions */
548   if (param->flags & P_FLAG_READONLY)
549     return;
550  if (param->flags & P_FLAG_QVAR)
551     return;
552  if (param->flags & P_FLAG_TVAR)
553     return;
554  if (param->flags & P_FLAG_USERDEF)
555     return;
556
557   /* If initial condition was not defined by the preset file, force a default one
558      with the following code */
559   if ((init_cond = splay_find(param->name, interface_shape->init_cond_tree)) == NULL) {
560     
561     /* Make sure initial condition does not exist in the set of per frame initial equations */
562     if ((init_cond = splay_find(param->name, interface_shape->per_frame_init_eqn_tree)) != NULL)
563       return;
564     
565     if (param->type == P_TYPE_BOOL)
566       init_val.bool_val = 0;
567     
568     else if (param->type == P_TYPE_INT)
569       init_val.int_val = *(int*)param->engine_val;
570
571     else if (param->type == P_TYPE_DOUBLE)
572       init_val.double_val = *(double*)param->engine_val;
573
574     //printf("%s\n", param->name);
575     /* Create new initial condition */
576     if ((init_cond = new_init_cond(param, init_val)) == NULL)
577       return;
578     
579     /* Insert the initial condition into this presets tree */
580     if (splay_insert(init_cond, init_cond->param->name, interface_shape->init_cond_tree) < 0) {
581       free_init_cond(init_cond);
582       return;
583     }
584     
585   }
586  
587 }
588
589
590 /* Interface function. Makes another custom shape the current
591    concern for per frame / point equations */
592 inline custom_shape_t * nextCustomShape() {
593
594   if ((interface_shape = splay_find(&cwave_interface_id, active_preset->custom_shape_tree)) == NULL) {
595     cwave_interface_id = 0;
596     return NULL;
597   }
598
599   cwave_interface_id++;
600
601   /* Evaluate all per frame equations associated with this shape */
602   splay_traverse(eval_per_frame_eqn, interface_shape->per_frame_eqn_tree);
603   return interface_shape;
604 }