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

midi

开发平台:

Unix_Linux

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