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