custom_wave.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:21k
源码类别:

midi

开发平台:

Unix_Linux

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