custom_shape.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:17k
源码类别:

多媒体

开发平台:

MultiPlatform

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