]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/custom_wave.c
Removes trailing spaces. Removes tabs.
[vlc] / modules / visualization / galaktos / custom_wave.c
1 /*****************************************************************************
2  * custom_wave.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
27 #include "common.h"
28 #include "fatal.h"
29
30 #include "param_types.h"
31 #include "param.h"
32
33 #include "expr_types.h"
34 #include "eval.h"
35
36 #include "splaytree_types.h"
37 #include "splaytree.h"
38 #include "tree_types.h"
39
40 #include "per_frame_eqn_types.h"
41 #include "per_frame_eqn.h"
42
43 #include "init_cond_types.h"
44 #include "init_cond.h"
45
46 #include "preset_types.h"
47
48 #include "custom_wave_types.h"
49 #include "custom_wave.h"
50
51 #include "init_cond_types.h"
52 #include "init_cond.h"
53
54 #include "engine_vars.h"
55 #define MAX_SAMPLE_SIZE 4096
56
57 extern int mesh_i;
58
59 custom_wave_t * interface_wave = NULL;
60 int interface_id = 0;
61 extern preset_t * active_preset;
62 inline void eval_custom_wave_init_conds(custom_wave_t * custom_wave);
63 void load_unspec_init_cond(param_t * param);
64 void destroy_per_point_eqn_tree(splaytree_t * tree);
65 void destroy_param_db_tree(splaytree_t * tree);
66 void destroy_per_frame_eqn_tree(splaytree_t * tree);
67 void destroy_per_frame_init_eqn_tree(splaytree_t * tree);
68 void destroy_init_cond_tree(splaytree_t * tree);
69 inline void evalPerPointEqn(per_point_eqn_t * per_point_eqn);
70
71 custom_wave_t * new_custom_wave(int id) {
72
73   custom_wave_t * custom_wave;
74   param_t * param;
75  
76   if ((custom_wave = (custom_wave_t*)malloc(sizeof(custom_wave_t))) == NULL)
77     return NULL;
78
79   custom_wave->id = id;
80   custom_wave->per_frame_count = 0;
81
82   custom_wave->samples = 512;
83   custom_wave->bSpectrum = 0;
84   custom_wave->enabled = 1;
85   custom_wave->sep = 1;
86   custom_wave->smoothing = 0.0;
87   custom_wave->bUseDots = 0;
88   custom_wave->bAdditive = 0;
89   custom_wave->r = custom_wave->g = custom_wave->b = custom_wave->a = 0.0;
90   custom_wave->scaling = 1.0;
91   custom_wave->per_frame_eqn_string_index = 0;
92   custom_wave->per_frame_init_eqn_string_index = 0;
93   custom_wave->per_point_eqn_string_index = 0;
94
95   custom_wave->r_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
96   custom_wave->g_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
97   custom_wave->b_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
98   custom_wave->a_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
99   custom_wave->x_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
100   custom_wave->y_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
101   custom_wave->value1 = malloc(MAX_SAMPLE_SIZE*sizeof(double));
102   custom_wave->value2 = malloc(MAX_SAMPLE_SIZE*sizeof(double));
103   custom_wave->sample_mesh = malloc(MAX_SAMPLE_SIZE*sizeof(double));
104
105   /* Initialize tree data structures */
106  
107   if ((custom_wave->param_tree =
108        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
109     free_custom_wave(custom_wave);
110     return NULL;
111   }
112
113   if ((custom_wave->per_point_eqn_tree =
114        create_splaytree(compare_int, copy_int, free_int)) == NULL) {
115     free_custom_wave(custom_wave);
116     return NULL;
117   }
118
119   if ((custom_wave->per_frame_eqn_tree =
120        create_splaytree(compare_int, copy_int, free_int)) == NULL) {
121     free_custom_wave(custom_wave);
122     return NULL;
123   }
124
125   if ((custom_wave->init_cond_tree =
126        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
127     free_custom_wave(custom_wave);
128     return NULL;
129   }
130  
131   if ((custom_wave->per_frame_init_eqn_tree =
132        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
133     free_custom_wave(custom_wave);
134     return NULL;
135   }
136
137  
138   /* Start: Load custom wave parameters */
139
140   if ((param = new_param_double("r", P_FLAG_DONT_FREE_MATRIX | P_FLAG_PER_POINT, &custom_wave->r, custom_wave->r_mesh, 1.0, 0.0, .5)) == NULL) {
141     free_custom_wave(custom_wave);
142     return NULL;
143   }
144
145   if (insert_param(param, custom_wave->param_tree) < 0) {
146     free_custom_wave(custom_wave);
147     return NULL;
148   }
149  
150   if ((param = new_param_double("g", P_FLAG_DONT_FREE_MATRIX | P_FLAG_PER_POINT, &custom_wave->g,  custom_wave->g_mesh, 1.0, 0.0, .5)) == NULL){
151     free_custom_wave(custom_wave);
152     return NULL;
153   }
154
155   if (insert_param(param, custom_wave->param_tree) < 0) {
156     free_custom_wave(custom_wave);
157     return NULL;
158   }
159
160   if ((param = new_param_double("b", P_FLAG_DONT_FREE_MATRIX | P_FLAG_PER_POINT, &custom_wave->b,  custom_wave->b_mesh, 1.0, 0.0, .5)) == NULL){
161     free_custom_wave(custom_wave);
162     return NULL;                
163   }
164
165   if (insert_param(param, custom_wave->param_tree) < 0) {
166     free_custom_wave(custom_wave);
167     return NULL;
168   }
169
170   if ((param = new_param_double("a", P_FLAG_DONT_FREE_MATRIX | P_FLAG_PER_POINT, &custom_wave->a,  custom_wave->a_mesh, 1.0, 0.0, .5)) == NULL){
171     free_custom_wave(custom_wave);
172     return NULL;
173   }
174  
175   if (insert_param(param, custom_wave->param_tree) < 0) {
176     free_custom_wave(custom_wave);
177     return NULL;
178   }
179
180   if ((param = new_param_double("x", P_FLAG_DONT_FREE_MATRIX | P_FLAG_PER_POINT, &custom_wave->x,  custom_wave->x_mesh, 1.0, 0.0, .5)) == NULL) {
181     free_custom_wave(custom_wave);
182     return NULL;
183   }
184
185   if (insert_param(param, custom_wave->param_tree) < 0) {
186     free_custom_wave(custom_wave);
187     return NULL;
188   }
189
190   if ((param = new_param_double("y", P_FLAG_DONT_FREE_MATRIX | P_FLAG_PER_POINT, &custom_wave->y,  custom_wave->y_mesh, 1.0, 0.0, .5)) == NULL) {
191     free_custom_wave(custom_wave);
192     return NULL;
193   }
194
195   if (insert_param(param, custom_wave->param_tree) < 0) {
196     free_custom_wave(custom_wave);
197     return NULL;
198   }
199
200   if ((param = new_param_bool("enabled", P_FLAG_NONE, &custom_wave->enabled, 1, 0, 0)) == NULL) {
201     free_custom_wave(custom_wave);
202     return NULL;
203   }
204
205   if (insert_param(param, custom_wave->param_tree) < 0) {
206     free_custom_wave(custom_wave);
207     return NULL;
208   }
209
210   if ((param = new_param_int("sep", P_FLAG_NONE, &custom_wave->sep, 100, -100, 0)) == NULL) {
211     free_custom_wave(custom_wave);
212     return NULL;
213   }
214
215   if (insert_param(param, custom_wave->param_tree) < 0) {
216     free_custom_wave(custom_wave);
217     return NULL;
218   }
219
220   if ((param = new_param_bool("bSpectrum", P_FLAG_NONE, &custom_wave->bSpectrum, 1, 0, 0)) == NULL) {
221     free_custom_wave(custom_wave);
222     return NULL;
223   }
224
225   if (insert_param(param, custom_wave->param_tree) < 0) {
226     free_custom_wave(custom_wave);
227     return NULL;
228   }
229
230   if ((param = new_param_bool("bDrawThick", P_FLAG_NONE, &custom_wave->bDrawThick, 1, 0, 0)) == NULL) {
231     free_custom_wave(custom_wave);
232     return NULL;
233   }
234
235   if (insert_param(param, custom_wave->param_tree) < 0) {
236     free_custom_wave(custom_wave);
237     return NULL;
238   }
239
240   if ((param = new_param_bool("bUseDots", P_FLAG_NONE, &custom_wave->bUseDots, 1, 0, 0)) == NULL) {
241     free_custom_wave(custom_wave);
242     return NULL;
243   }
244
245   if (insert_param(param, custom_wave->param_tree) < 0) {
246     free_custom_wave(custom_wave);
247     return NULL;
248   }
249  
250   if ((param = new_param_bool("bAdditive", P_FLAG_NONE, &custom_wave->bAdditive, 1, 0, 0)) == NULL) {
251     free_custom_wave(custom_wave);
252     return NULL;
253   }
254
255   if (insert_param(param, custom_wave->param_tree) < 0) {
256     free_custom_wave(custom_wave);
257     return NULL;
258   }
259
260   if ((param = new_param_int("samples", P_FLAG_NONE, &custom_wave->samples, 2048, 1, 512)) == NULL) {
261     free_custom_wave(custom_wave);
262     return NULL;
263   }
264  
265   if (insert_param(param, custom_wave->param_tree) < 0) {
266     free_custom_wave(custom_wave);
267     return NULL;
268   }
269
270   if ((param = new_param_double("sample", P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX | P_FLAG_ALWAYS_MATRIX | P_FLAG_PER_POINT,
271                 &custom_wave->sample, custom_wave->sample_mesh, 1.0, 0.0, 0.0)) == NULL) {
272     free_custom_wave(custom_wave);
273     return NULL;
274   }
275  
276  if (insert_param(param, custom_wave->param_tree) < 0) {
277     printf("failed to insert sample\n");
278     free_custom_wave(custom_wave);
279     return NULL;
280   }
281
282   if ((param = new_param_double("value1", P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX | P_FLAG_ALWAYS_MATRIX | P_FLAG_PER_POINT, &custom_wave->v1, custom_wave->value1, 1.0, -1.0, 0.0)) == NULL) {
283     free_custom_wave(custom_wave);
284     return NULL;
285   }
286
287   if (insert_param(param, custom_wave->param_tree) < 0) {
288     free_custom_wave(custom_wave);
289     return NULL;
290   }
291
292   if ((param = new_param_double("value2", P_FLAG_READONLY | P_FLAG_DONT_FREE_MATRIX | P_FLAG_ALWAYS_MATRIX | P_FLAG_PER_POINT, &custom_wave->v2, custom_wave->value2, 1.0, -1.0, 0.0)) == NULL) {
293     free_custom_wave(custom_wave);
294     return NULL;
295   }
296
297   if (insert_param(param, custom_wave->param_tree) < 0) {
298     free_custom_wave(custom_wave);
299     return NULL;
300   }
301
302   if ((param = new_param_double("smoothing", P_FLAG_NONE, &custom_wave->smoothing, NULL, 1.0, 0.0, 0.0)) == NULL) {
303     free_custom_wave(custom_wave);
304     return NULL;
305   }
306
307   if (insert_param(param, custom_wave->param_tree) < 0) {
308     free_custom_wave(custom_wave);
309     return NULL;
310   }
311
312   if ((param = new_param_double("scaling", P_FLAG_NONE, &custom_wave->scaling, NULL, MAX_DOUBLE_SIZE, 0.0, 1.0)) == NULL) {
313     free_custom_wave(custom_wave);
314     return NULL;
315   }
316
317   if (insert_param(param, custom_wave->param_tree) < 0) {
318     free_custom_wave(custom_wave);
319     return NULL;
320   }
321  
322   if ((param = new_param_double("t1", P_FLAG_PER_POINT | P_FLAG_TVAR, &custom_wave->t1, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
323     free_custom_wave(custom_wave);
324     return NULL;
325   }
326
327   if (insert_param(param, custom_wave->param_tree) < 0) {
328     free_custom_wave(custom_wave);
329     return NULL;
330   }
331
332   if ((param = new_param_double("t2",  P_FLAG_PER_POINT |P_FLAG_TVAR, &custom_wave->t2, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
333     free_custom_wave(custom_wave);
334     return NULL;
335   }
336
337   if (insert_param(param, custom_wave->param_tree) < 0) {
338     free_custom_wave(custom_wave);
339     return NULL;
340   }
341
342   if ((param = new_param_double("t3",  P_FLAG_PER_POINT |P_FLAG_TVAR, &custom_wave->t3, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
343     free_custom_wave(custom_wave);
344     return NULL;
345   }
346
347   if (insert_param(param, custom_wave->param_tree) < 0) {
348     free_custom_wave(custom_wave);
349     return NULL;
350   }
351   if ((param = new_param_double("t4",  P_FLAG_PER_POINT |P_FLAG_TVAR, &custom_wave->t4, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
352     free_custom_wave(custom_wave);
353     return NULL;
354   }
355
356   if (insert_param(param, custom_wave->param_tree) < 0) {
357     free_custom_wave(custom_wave);
358     return NULL;
359   }
360   if ((param = new_param_double("t5", P_FLAG_TVAR, &custom_wave->t5, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
361     free_custom_wave(custom_wave);
362     return NULL;
363   }
364  
365   if (insert_param(param, custom_wave->param_tree) < 0) {
366     free_custom_wave(custom_wave);
367     return NULL;
368   }
369   if ((param = new_param_double("t6", P_FLAG_TVAR | P_FLAG_PER_POINT, &custom_wave->t6, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
370     free_custom_wave(custom_wave);
371     return NULL;
372   }
373
374   if (insert_param(param, custom_wave->param_tree) < 0) {
375     free_custom_wave(custom_wave);
376     return NULL;
377   }
378   if ((param = new_param_double("t7", P_FLAG_TVAR | P_FLAG_PER_POINT, &custom_wave->t7, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
379     free_custom_wave(custom_wave);
380     return NULL;
381   }
382
383   if (insert_param(param, custom_wave->param_tree) < 0) {
384     free_custom_wave(custom_wave);
385     return NULL;
386   }
387
388   if ((param = new_param_double("t8", P_FLAG_TVAR | P_FLAG_PER_POINT, &custom_wave->t8, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
389     free_custom_wave(custom_wave);
390     return NULL;
391   }
392
393   if (insert_param(param, custom_wave->param_tree) < 0) {
394     free_custom_wave(custom_wave);
395     return NULL;
396   }
397  
398   /* End of parameter loading. Note that the read only parameters associated
399      with custom waves (ie, sample) are global variables, and not specific to
400      the custom wave datastructure. */
401
402
403   return custom_wave;
404
405 }
406
407 void destroy_per_frame_init_eqn_tree(splaytree_t * tree) {
408
409   if (!tree)
410     return;
411
412   splay_traverse(free_init_cond, tree);
413   destroy_splaytree(tree);
414
415 }
416
417
418 void destroy_per_point_eqn_tree(splaytree_t * tree) {
419
420   if (!tree)
421     return;
422
423   splay_traverse(free_per_point_eqn, tree);
424   destroy_splaytree(tree);
425
426 }
427
428 void destroy_init_cond_tree(splaytree_t * tree) {
429
430   if (!tree)
431     return;
432
433   splay_traverse(free_init_cond, tree);
434   destroy_splaytree(tree);
435
436 }
437
438 void destroy_per_frame_eqn_tree(splaytree_t * tree) {
439
440
441   if (!tree)
442     return;
443
444   splay_traverse(free_per_frame_eqn, tree);
445   destroy_splaytree(tree);
446
447 }
448
449
450 void destroy_param_db_tree(splaytree_t * tree) {
451
452   if (!tree)
453     return;
454
455   splay_traverse(free_param, tree);
456   destroy_splaytree(tree);
457
458 }
459
460 /* Frees a custom wave form object */
461 void free_custom_wave(custom_wave_t * custom_wave) {
462
463   if (custom_wave == NULL)
464     return;
465
466   if (custom_wave->param_tree == NULL)
467     return;
468
469   destroy_per_point_eqn_tree(custom_wave->per_point_eqn_tree);
470   destroy_per_frame_eqn_tree(custom_wave->per_frame_eqn_tree);
471   destroy_init_cond_tree(custom_wave->init_cond_tree);
472   destroy_param_db_tree(custom_wave->param_tree);
473   destroy_per_frame_init_eqn_tree(custom_wave->per_frame_init_eqn_tree);
474
475   free(custom_wave->r_mesh);
476   free(custom_wave->g_mesh);
477   free(custom_wave->b_mesh);
478   free(custom_wave->a_mesh);
479   free(custom_wave->x_mesh);
480   free(custom_wave->y_mesh);
481   free(custom_wave->value1);
482   free(custom_wave->value2);
483   free(custom_wave->sample_mesh);
484
485   free(custom_wave);
486
487   return;
488
489 }
490
491
492
493 int add_per_point_eqn(char * name, gen_expr_t * gen_expr, custom_wave_t * custom_wave) {
494
495   per_point_eqn_t * per_point_eqn;
496   int index;
497   param_t * param = NULL;
498
499   /* Argument checks */
500   if (custom_wave == NULL)
501       return FAILURE;
502   if (gen_expr == NULL)
503       return FAILURE;
504   if (name == NULL)
505       return FAILURE;
506  
507  if (CUSTOM_WAVE_DEBUG) printf("add_per_point_eqn: per pixel equation (name = \"%s\")\n", name);
508
509  /* Search for the parameter so we know what matrix the per pixel equation is referencing */
510
511  if ((param = find_param_db(name, custom_wave->param_tree, TRUE)) == NULL) {
512    if (CUSTOM_WAVE_DEBUG) printf("add_per_point_eqn: failed to allocate a new parameter!\n");
513    return FAILURE;
514  
515  }     
516
517  /* Find most largest index in the splaytree */
518  if ((per_point_eqn = splay_find_max(custom_wave->per_point_eqn_tree)) == NULL)
519    index = 0;
520  else
521    index = per_point_eqn->index+1;
522
523  /* Create the per pixel equation given the index, parameter, and general expression */
524  if ((per_point_eqn = new_per_point_eqn(index, param, gen_expr)) == NULL)
525      return FAILURE;
526  if (CUSTOM_WAVE_DEBUG)
527    printf("add_per_point_eqn: created new equation (index = %d) (name = \"%s\")\n", per_point_eqn->index, per_point_eqn->param->name);
528  /* Insert the per pixel equation into the preset per pixel database */
529  if (splay_insert(per_point_eqn, &per_point_eqn->index, custom_wave->per_point_eqn_tree) < 0) {
530     free_per_point_eqn(per_point_eqn);
531     return FAILURE;    
532  }
533     
534  /* Done */
535  return SUCCESS;
536 }
537
538 per_point_eqn_t * new_per_point_eqn(int index, param_t * param, gen_expr_t * gen_expr) {
539
540     per_point_eqn_t * per_point_eqn;
541     
542     if (param == NULL)
543         return NULL;
544     if (gen_expr == NULL)
545         return NULL;
546
547     if ((per_point_eqn = (per_point_eqn_t*)malloc(sizeof(per_point_eqn_t))) == NULL)
548         return NULL;
549
550  
551     per_point_eqn->index = index;
552     per_point_eqn->gen_expr = gen_expr;
553     per_point_eqn->param = param;
554     return per_point_eqn;    
555 }
556
557
558 void free_per_point_eqn(per_point_eqn_t * per_point_eqn) {
559
560     if (per_point_eqn == NULL)
561         return;
562     
563     free_gen_expr(per_point_eqn->gen_expr);
564     
565     free(per_point_eqn);
566     
567     return;
568 }
569
570 custom_wave_t * find_custom_wave(int id, preset_t * preset, int create_flag) {
571
572   custom_wave_t * custom_wave = NULL;
573
574   if (preset == NULL)
575     return NULL;
576  
577   if ((custom_wave = splay_find(&id, preset->custom_wave_tree)) == NULL) {
578
579     if (CUSTOM_WAVE_DEBUG) { printf("find_custom_wave: creating custom wave (id = %d)...", id);fflush(stdout);}
580
581     if (create_flag == FALSE) {
582       if (CUSTOM_WAVE_DEBUG) printf("you specified not to (create flag = false), returning null\n");
583        return NULL;
584     }
585
586     if ((custom_wave = new_custom_wave(id)) == NULL) {
587       if (CUSTOM_WAVE_DEBUG) printf("failed...out of memory?\n");
588       return NULL;
589     }
590
591     if  (CUSTOM_WAVE_DEBUG) {printf("success.Inserting..."); fflush(stdout);}
592
593    if (splay_insert(custom_wave, &custom_wave->id, preset->custom_wave_tree) < 0) {
594      if (CUSTOM_WAVE_DEBUG) printf("failed!\n");
595      free_custom_wave(custom_wave);
596      return NULL;
597     }
598  
599    if (CUSTOM_WAVE_DEBUG) printf("done.\n");
600   }
601  
602   return custom_wave;
603 }
604
605 inline void evalCustomWaveInitConditions() {
606   splay_traverse(eval_custom_wave_init_conds, active_preset->custom_wave_tree);
607 }
608
609 inline void eval_custom_wave_init_conds(custom_wave_t * custom_wave) {
610   splay_traverse(eval_init_cond, custom_wave->init_cond_tree);
611   splay_traverse(eval_init_cond, custom_wave->per_frame_init_eqn_tree);
612 }
613
614 /* Interface function. Makes another custom wave the current
615    concern for per frame / point equations */
616 inline custom_wave_t * nextCustomWave() {
617
618   if ((interface_wave = splay_find(&interface_id, active_preset->custom_wave_tree)) == NULL) {
619     interface_id = 0;
620     return NULL;
621   }
622
623   interface_id++;
624
625   /* Evaluate all per frame equations associated with this wave */
626   splay_traverse(eval_per_frame_eqn, interface_wave->per_frame_eqn_tree);
627   return interface_wave;
628 }
629
630
631 inline void evalPerPointEqns() {
632
633   int x;
634
635   for (x = 0; x < interface_wave->samples; x++)
636     interface_wave->r_mesh[x] = interface_wave->r;
637   for (x = 0; x < interface_wave->samples; x++)
638     interface_wave->g_mesh[x] = interface_wave->g;
639   for (x = 0; x < interface_wave->samples; x++)
640     interface_wave->b_mesh[x] = interface_wave->b;
641   for (x = 0; x < interface_wave->samples; x++)
642     interface_wave->a_mesh[x] = interface_wave->a;
643   for (x = 0; x < interface_wave->samples; x++)
644     interface_wave->x_mesh[x] = interface_wave->x;
645   for (x = 0; x < interface_wave->samples; x++)
646     interface_wave->y_mesh[x] = interface_wave->y;
647
648  
649   /* Evaluate per pixel equations */
650   splay_traverse(evalPerPointEqn, interface_wave->per_point_eqn_tree);
651
652   /* Reset index */
653   mesh_i = -1;
654 }
655
656 /* Evaluates a per point equation for the current custom wave given by interface_wave ptr */
657 inline void evalPerPointEqn(per_point_eqn_t * per_point_eqn) {
658  
659  
660   int samples, size;
661   double * param_matrix;
662   gen_expr_t * eqn_ptr;
663
664   samples = interface_wave->samples;
665   eqn_ptr = per_point_eqn->gen_expr;
666  
667   if (per_point_eqn->param->matrix == NULL) {
668     if ((param_matrix = per_point_eqn->param->matrix = malloc(size = samples*sizeof(double))) == NULL)
669       return;
670     memset(param_matrix, 0, size);
671   }
672   else
673     param_matrix = (double*)per_point_eqn->param->matrix;
674  
675   for (mesh_i = 0; mesh_i < samples; mesh_i++) {
676       param_matrix[mesh_i] = eval_gen_expr(eqn_ptr);
677   }
678  
679   /* Now that this parameter has been referenced with a per
680      point equation, we let the evaluator know by setting
681      this flag */
682   per_point_eqn->param->matrix_flag = 1;
683
684 }
685
686
687 void load_unspecified_init_conds(custom_wave_t * custom_wave) {
688
689   interface_wave = custom_wave;
690   splay_traverse(load_unspec_init_cond, interface_wave->param_tree);
691   interface_wave = NULL;
692  
693 }
694
695 void load_unspec_init_cond(param_t * param) {
696
697   init_cond_t * init_cond;
698   value_t init_val;
699
700   /* Don't count these parameters as initial conditions */
701   if (param->flags & P_FLAG_READONLY)
702     return;
703   if (param->flags & P_FLAG_QVAR)
704     return;
705   if (param->flags & P_FLAG_TVAR)
706     return;
707   if (param->flags & P_FLAG_USERDEF)
708     return;
709
710   /* If initial condition was not defined by the preset file, force a default one
711      with the following code */
712   if ((init_cond = splay_find(param->name, interface_wave->init_cond_tree)) == NULL) {
713  
714     /* Make sure initial condition does not exist in the set of per frame initial equations */
715     if ((init_cond = splay_find(param->name, interface_wave->per_frame_init_eqn_tree)) != NULL)
716       return;
717  
718     if (param->type == P_TYPE_BOOL)
719       init_val.bool_val = 0;
720  
721     else if (param->type == P_TYPE_INT)
722       init_val.int_val = *(int*)param->engine_val;
723
724     else if (param->type == P_TYPE_DOUBLE)
725       init_val.double_val = *(double*)param->engine_val;
726
727     //printf("%s\n", param->name);
728     /* Create new initial condition */
729     if ((init_cond = new_init_cond(param, init_val)) == NULL)
730       return;
731  
732     /* Insert the initial condition into this presets tree */
733     if (splay_insert(init_cond, init_cond->param->name, interface_wave->init_cond_tree) < 0) {
734       free_init_cond(init_cond);
735       return;
736     }
737  
738   }
739  
740 }