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