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