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