Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

custom_shape.c

00001 /*****************************************************************************
00002  * custom_shape.c:
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: custom_shape.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Cyril Deguet <[email protected]>
00008  *          code from projectM http://xmms-projectm.sourceforge.net
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 //
00026 
00027 
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 
00032 #include "common.h"
00033 #include "fatal.h"
00034 
00035 #include "param_types.h"
00036 #include "param.h"
00037 
00038 #include "expr_types.h"
00039 #include "eval.h"
00040 
00041 #include "splaytree_types.h"
00042 #include "splaytree.h"
00043 #include "tree_types.h"
00044 
00045 #include "per_frame_eqn_types.h"
00046 #include "per_frame_eqn.h"
00047 
00048 #include "init_cond_types.h"
00049 #include "init_cond.h"
00050 
00051 #include "preset_types.h"
00052 
00053 #include "custom_shape_types.h"
00054 #include "custom_shape.h"
00055 
00056 #include "init_cond_types.h"
00057 #include "init_cond.h"
00058 
00059 custom_shape_t * interface_shape = NULL;
00060 int cwave_interface_id = 0;
00061 extern preset_t * active_preset;
00062 inline void eval_custom_shape_init_conds(custom_shape_t * custom_shape);
00063 void load_unspec_init_cond_shape(param_t * param);
00064 
00065 void destroy_param_db_tree_shape(splaytree_t * tree);
00066 void destroy_per_frame_eqn_tree_shape(splaytree_t * tree);
00067 void destroy_per_frame_init_eqn_tree_shape(splaytree_t * tree);
00068 void destroy_init_cond_tree_shape(splaytree_t * tree);
00069 
00070 custom_shape_t * new_custom_shape(int id) {
00071 
00072   custom_shape_t * custom_shape;
00073   param_t * param;
00074 
00075   if ((custom_shape = (custom_shape_t*)malloc(sizeof(custom_shape_t))) == NULL)
00076     return NULL;
00077 
00078   custom_shape->id = id;
00079   custom_shape->per_frame_count = 0;
00080   custom_shape->per_frame_eqn_string_index = 0;
00081   custom_shape->per_frame_init_eqn_string_index = 0;
00082 
00083   /* Initialize tree data structures */
00084 
00085   if ((custom_shape->param_tree = 
00086        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
00087     free_custom_shape(custom_shape);
00088     return NULL;
00089   }
00090 
00091   if ((custom_shape->per_frame_eqn_tree = 
00092        create_splaytree(compare_int, copy_int, free_int)) == NULL) {
00093     free_custom_shape(custom_shape);
00094     return NULL;
00095   }
00096 
00097   if ((custom_shape->init_cond_tree = 
00098        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
00099     free_custom_shape(custom_shape);
00100     return NULL;
00101   }
00102   
00103   if ((custom_shape->per_frame_init_eqn_tree = 
00104        create_splaytree(compare_string, copy_string, free_string)) == NULL) {
00105     free_custom_shape(custom_shape);
00106     return NULL;
00107   }
00108 
00109   /* Start: Load custom shape parameters */
00110 
00111   if ((param = new_param_double("r", P_FLAG_NONE, &custom_shape->r, NULL, 1.0, 0.0, .5)) == NULL) {
00112     free_custom_shape(custom_shape);
00113     return NULL;
00114   }
00115 
00116   if (insert_param(param, custom_shape->param_tree) < 0) {
00117     free_custom_shape(custom_shape);
00118     return NULL;
00119   }
00120  
00121   if ((param = new_param_double("g", P_FLAG_NONE, &custom_shape->g, NULL, 1.0, 0.0, .5)) == NULL){
00122     free_custom_shape(custom_shape);
00123     return NULL;
00124   }
00125 
00126   if (insert_param(param, custom_shape->param_tree) < 0) {
00127     free_custom_shape(custom_shape);
00128     return NULL;
00129   }
00130 
00131   if ((param = new_param_double("b", P_FLAG_NONE, &custom_shape->b, NULL, 1.0, 0.0, .5)) == NULL){
00132     free_custom_shape(custom_shape);
00133     return NULL;                                       
00134   }
00135 
00136   if (insert_param(param, custom_shape->param_tree) < 0) {
00137     free_custom_shape(custom_shape);
00138     return NULL;
00139   }
00140 
00141   if ((param = new_param_double("a", P_FLAG_NONE, &custom_shape->a, NULL, 1.0, 0.0, .5)) == NULL){
00142     free_custom_shape(custom_shape);
00143     return NULL;
00144   }
00145 
00146   if (insert_param(param, custom_shape->param_tree) < 0) {
00147     free_custom_shape(custom_shape);
00148     return NULL;
00149   }
00150 
00151   if ((param = new_param_double("border_r", P_FLAG_NONE, &custom_shape->border_r, NULL, 1.0, 0.0, .5)) == NULL) {
00152     free_custom_shape(custom_shape);
00153     return NULL;
00154   }
00155 
00156   if (insert_param(param, custom_shape->param_tree) < 0) {
00157     free_custom_shape(custom_shape);
00158     return NULL;
00159   }
00160  
00161   if ((param = new_param_double("border_g", P_FLAG_NONE, &custom_shape->border_g, NULL, 1.0, 0.0, .5)) == NULL){
00162     free_custom_shape(custom_shape);
00163     return NULL;
00164   }
00165 
00166   if (insert_param(param, custom_shape->param_tree) < 0) {
00167     free_custom_shape(custom_shape);
00168     return NULL;
00169   }
00170 
00171   if ((param = new_param_double("border_b", P_FLAG_NONE, &custom_shape->border_b, NULL, 1.0, 0.0, .5)) == NULL){
00172     free_custom_shape(custom_shape);
00173     return NULL;                                       
00174   }
00175 
00176   if (insert_param(param, custom_shape->param_tree) < 0) {
00177     free_custom_shape(custom_shape);
00178     return NULL;
00179   }
00180 
00181   if ((param = new_param_double("border_a", P_FLAG_NONE, &custom_shape->border_a, NULL, 1.0, 0.0, .5)) == NULL){
00182     free_custom_shape(custom_shape);
00183     return NULL;
00184   }
00185 
00186   if (insert_param(param, custom_shape->param_tree) < 0) {
00187     free_custom_shape(custom_shape);
00188     return NULL;
00189   }
00190 
00191   if ((param = new_param_double("r2", P_FLAG_NONE, &custom_shape->r2, NULL, 1.0, 0.0, .5)) == NULL) {
00192     free_custom_shape(custom_shape);
00193     return NULL;
00194   }
00195 
00196   if (insert_param(param, custom_shape->param_tree) < 0) {
00197     free_custom_shape(custom_shape);
00198     return NULL;
00199   }
00200  
00201   if ((param = new_param_double("g2", P_FLAG_NONE, &custom_shape->g2, NULL, 1.0, 0.0, .5)) == NULL){
00202     free_custom_shape(custom_shape);
00203     return NULL;
00204   }
00205 
00206   if (insert_param(param, custom_shape->param_tree) < 0) {
00207     free_custom_shape(custom_shape);
00208     return NULL;
00209   }
00210 
00211   if ((param = new_param_double("b2", P_FLAG_NONE, &custom_shape->b2, NULL, 1.0, 0.0, .5)) == NULL){
00212     free_custom_shape(custom_shape);
00213     return NULL;                                       
00214   }
00215 
00216   if (insert_param(param, custom_shape->param_tree) < 0) {
00217     free_custom_shape(custom_shape);
00218     return NULL;
00219   }
00220 
00221   if ((param = new_param_double("a2", P_FLAG_NONE, &custom_shape->a2, NULL, 1.0, 0.0, .5)) == NULL){
00222     free_custom_shape(custom_shape);
00223     return NULL;
00224   }
00225   
00226   if (insert_param(param, custom_shape->param_tree) < 0) {
00227     free_custom_shape(custom_shape);
00228     return NULL;
00229   }
00230 
00231   if ((param = new_param_double("x", P_FLAG_NONE, &custom_shape->x, NULL, 1.0, 0.0, .5)) == NULL) {
00232     free_custom_shape(custom_shape);
00233     return NULL;
00234   }
00235 
00236   if (insert_param(param, custom_shape->param_tree) < 0) {
00237     free_custom_shape(custom_shape);
00238     return NULL;
00239   }
00240 
00241   if ((param = new_param_double("y", P_FLAG_NONE, &custom_shape->y, NULL, 1.0, 0.0, .5)) == NULL) {
00242     free_custom_shape(custom_shape);
00243     return NULL;
00244   }
00245 
00246   if (insert_param(param, custom_shape->param_tree) < 0) {
00247     free_custom_shape(custom_shape);
00248     return NULL;
00249   }
00250 
00251   if ((param = new_param_bool("thickOutline", P_FLAG_NONE, &custom_shape->thickOutline, 1, 0, 0)) == NULL) {
00252     free_custom_shape(custom_shape);
00253     return NULL;
00254   }
00255 
00256   if (insert_param(param, custom_shape->param_tree) < 0) {
00257     free_custom_shape(custom_shape);
00258     return NULL;
00259   }
00260 
00261   if ((param = new_param_bool("enabled", P_FLAG_NONE, &custom_shape->enabled, 1, 0, 0)) == NULL) {
00262     free_custom_shape(custom_shape);
00263     return NULL;
00264   }
00265 
00266   if (insert_param(param, custom_shape->param_tree) < 0) {
00267     free_custom_shape(custom_shape);
00268     return NULL;
00269   }
00270 
00271   if ((param = new_param_int("sides", P_FLAG_NONE, &custom_shape->sides, 100, 3, 3)) == NULL) {
00272     free_custom_shape(custom_shape);
00273     return NULL;
00274   }
00275 
00276   if (insert_param(param, custom_shape->param_tree) < 0) {
00277     free_custom_shape(custom_shape);
00278     return NULL;
00279   }
00280 
00281   if ((param = new_param_bool("additive", P_FLAG_NONE, &custom_shape->additive, 1, 0, 0)) == NULL) {
00282     free_custom_shape(custom_shape);
00283     return NULL;
00284   }
00285 
00286   if (insert_param(param, custom_shape->param_tree) < 0) {
00287     free_custom_shape(custom_shape);
00288     return NULL;
00289   }
00290 
00291   if ((param = new_param_bool("textured", P_FLAG_NONE, &custom_shape->textured, 1, 0, 0)) == NULL) {
00292     free_custom_shape(custom_shape);
00293     return NULL;
00294   }
00295 
00296   if (insert_param(param, custom_shape->param_tree) < 0) {
00297     free_custom_shape(custom_shape);
00298     return NULL;
00299   }
00300 
00301    if ((param = new_param_double("rad", P_FLAG_NONE, &custom_shape->rad, NULL, MAX_DOUBLE_SIZE, 0, 0.0)) == NULL) {
00302     free_custom_shape(custom_shape);
00303     return NULL;
00304   }
00305 
00306    if (insert_param(param, custom_shape->param_tree) < 0) {
00307     free_custom_shape(custom_shape);
00308     return NULL;
00309   }
00310 
00311    if ((param = new_param_double("ang", P_FLAG_NONE, &custom_shape->ang, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00312     free_custom_shape(custom_shape);
00313     return NULL;
00314   }
00315 
00316    if (insert_param(param, custom_shape->param_tree) < 0) {
00317     free_custom_shape(custom_shape);
00318     return NULL;
00319   }
00320 
00321    if ((param = new_param_double("tex_zoom", P_FLAG_NONE, &custom_shape->tex_zoom, NULL, MAX_DOUBLE_SIZE, .00000000001, 0.0)) == NULL) {
00322     free_custom_shape(custom_shape);
00323     return NULL;
00324   }
00325 
00326    if (insert_param(param, custom_shape->param_tree) < 0) {
00327     free_custom_shape(custom_shape);
00328     return NULL;
00329   }
00330    
00331    if ((param = new_param_double("tex_ang", P_FLAG_NONE, &custom_shape->tex_ang, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00332     free_custom_shape(custom_shape);
00333     return NULL;
00334   }
00335 
00336    if (insert_param(param, custom_shape->param_tree) < 0) {
00337     free_custom_shape(custom_shape);
00338     return NULL;
00339   }
00340    if ((param = new_param_double("t1", P_FLAG_TVAR, &custom_shape->t1, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00341     free_custom_shape(custom_shape);
00342     return NULL;
00343   }
00344 
00345   if (insert_param(param, custom_shape->param_tree) < 0) {
00346     free_custom_shape(custom_shape);
00347     return NULL;
00348   }
00349 
00350   if ((param = new_param_double("t2", P_FLAG_TVAR, &custom_shape->t2, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00351     free_custom_shape(custom_shape);
00352     return NULL;
00353   }
00354 
00355   if (insert_param(param, custom_shape->param_tree) < 0) {
00356     free_custom_shape(custom_shape);
00357     return NULL;
00358   }
00359 
00360   if ((param = new_param_double("t3", P_FLAG_TVAR, &custom_shape->t3, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00361     free_custom_shape(custom_shape);
00362     return NULL;
00363   }
00364 
00365   if (insert_param(param, custom_shape->param_tree) < 0) {
00366     free_custom_shape(custom_shape);
00367     return NULL;
00368   }
00369   if ((param = new_param_double("t4", P_FLAG_TVAR, &custom_shape->t4, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00370     free_custom_shape(custom_shape);
00371     return NULL;
00372   }
00373 
00374   if (insert_param(param, custom_shape->param_tree) < 0) {
00375     free_custom_shape(custom_shape);
00376     return NULL;
00377   }
00378   if ((param = new_param_double("t5", P_FLAG_TVAR, &custom_shape->t5, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00379     free_custom_shape(custom_shape);
00380     return NULL;
00381   }
00382  
00383   if (insert_param(param, custom_shape->param_tree) < 0) {
00384     free_custom_shape(custom_shape);
00385     return NULL;
00386   }
00387   if ((param = new_param_double("t6", P_FLAG_TVAR, &custom_shape->t6, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00388     free_custom_shape(custom_shape);
00389     return NULL;
00390   }
00391 
00392   if (insert_param(param, custom_shape->param_tree) < 0) {
00393     free_custom_shape(custom_shape);
00394     return NULL;
00395   }
00396   if ((param = new_param_double("t7", P_FLAG_TVAR, &custom_shape->t7, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00397     free_custom_shape(custom_shape);
00398     return NULL;
00399   }
00400 
00401   if (insert_param(param, custom_shape->param_tree) < 0) {
00402     free_custom_shape(custom_shape);
00403     return NULL;
00404   }
00405 
00406   if ((param = new_param_double("t8", P_FLAG_TVAR, &custom_shape->t8, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL) {
00407     free_custom_shape(custom_shape);
00408     return NULL;
00409   }
00410 
00411   if (insert_param(param, custom_shape->param_tree) < 0) {
00412     free_custom_shape(custom_shape);
00413     return NULL;
00414   }
00415  
00416   /* End of parameter loading. Note that the read only parameters associated
00417      with custom shapes (ie, sample) are global variables, and not specific to 
00418      the custom shape datastructure. */
00419 
00420 
00421 
00422   return custom_shape;
00423 
00424 }
00425 
00426 void destroy_per_frame_init_eqn_tree_shape(splaytree_t * tree) {
00427 
00428   if (!tree)
00429     return;
00430 
00431   splay_traverse(free_init_cond, tree);
00432   destroy_splaytree(tree);
00433 
00434 }
00435 
00436 
00437 
00438 void destroy_init_cond_tree_shape(splaytree_t * tree) {
00439 
00440   if (!tree)
00441     return;
00442 
00443   splay_traverse(free_init_cond, tree);
00444   destroy_splaytree(tree);
00445 
00446 }
00447 
00448 void destroy_per_frame_eqn_tree_shape(splaytree_t * tree) {
00449 
00450 
00451   if (!tree)
00452     return;
00453 
00454   splay_traverse(free_per_frame_eqn, tree);
00455   destroy_splaytree(tree);
00456 
00457 }
00458 
00459 
00460 void destroy_param_db_tree_shape(splaytree_t * tree) {
00461 
00462   if (!tree)
00463     return;
00464 
00465   splay_traverse(free_param, tree);
00466   destroy_splaytree(tree);
00467 
00468 }
00469 
00470 /* Frees a custom shape form object */
00471 void free_custom_shape(custom_shape_t * custom_shape) {
00472 
00473   if (custom_shape == NULL)
00474     return;
00475 
00476   if (custom_shape->param_tree == NULL)
00477     return;
00478 
00479   destroy_per_frame_eqn_tree_shape(custom_shape->per_frame_eqn_tree);
00480   destroy_init_cond_tree_shape(custom_shape->init_cond_tree);
00481   destroy_param_db_tree_shape(custom_shape->param_tree);
00482   destroy_per_frame_init_eqn_tree_shape(custom_shape->per_frame_init_eqn_tree);
00483   
00484   free(custom_shape);
00485 
00486   return;
00487 
00488 }
00489 
00490 
00491 custom_shape_t * find_custom_shape(int id, preset_t * preset, int create_flag) {
00492 
00493   custom_shape_t * custom_shape = NULL;
00494 
00495   if (preset == NULL)
00496     return NULL;
00497   
00498   if ((custom_shape = splay_find(&id, preset->custom_shape_tree)) == NULL) {
00499     
00500     if (CUSTOM_SHAPE_DEBUG) { printf("find_custom_shape: creating custom shape (id = %d)...", id);fflush(stdout);}
00501     
00502     if (create_flag == FALSE) {
00503       if (CUSTOM_SHAPE_DEBUG) printf("you specified not to (create flag = false), returning null\n");
00504       return NULL;
00505     }
00506     
00507     if ((custom_shape = new_custom_shape(id)) == NULL) {
00508       if (CUSTOM_SHAPE_DEBUG) printf("failed...out of memory?\n");
00509       return NULL;
00510     }
00511     
00512     if (CUSTOM_SHAPE_DEBUG) { printf("success.Inserting..."); fflush(stdout);}
00513     
00514     if (splay_insert(custom_shape, &custom_shape->id, preset->custom_shape_tree) < 0) {
00515       if (CUSTOM_SHAPE_DEBUG) printf("failed, probably a duplicated!!\n");
00516       free_custom_shape(custom_shape);
00517       return NULL;
00518     }
00519     
00520     if (CUSTOM_SHAPE_DEBUG) printf("done.\n");
00521   }
00522   
00523   return custom_shape;
00524 }
00525 
00526 inline void evalCustomShapeInitConditions() {
00527   splay_traverse(eval_custom_shape_init_conds, active_preset->custom_shape_tree);
00528 
00529 }
00530 
00531 inline void eval_custom_shape_init_conds(custom_shape_t * custom_shape) {
00532   splay_traverse(eval_init_cond, custom_shape->init_cond_tree);
00533   splay_traverse(eval_init_cond, custom_shape->per_frame_init_eqn_tree);
00534 }
00535 
00536 
00537 void load_unspecified_init_conds_shape(custom_shape_t * custom_shape) {
00538 
00539   interface_shape = custom_shape;
00540   splay_traverse(load_unspec_init_cond_shape, interface_shape->param_tree);
00541   interface_shape = NULL;
00542  
00543 }
00544 
00545 void load_unspec_init_cond_shape(param_t * param) {
00546 
00547   init_cond_t * init_cond;
00548   value_t init_val;
00549 
00550   /* Don't count read only parameters as initial conditions */
00551   if (param->flags & P_FLAG_READONLY)
00552     return;
00553  if (param->flags & P_FLAG_QVAR)
00554     return;
00555  if (param->flags & P_FLAG_TVAR)
00556     return;
00557  if (param->flags & P_FLAG_USERDEF)
00558     return;
00559 
00560   /* If initial condition was not defined by the preset file, force a default one
00561      with the following code */
00562   if ((init_cond = splay_find(param->name, interface_shape->init_cond_tree)) == NULL) {
00563     
00564     /* Make sure initial condition does not exist in the set of per frame initial equations */
00565     if ((init_cond = splay_find(param->name, interface_shape->per_frame_init_eqn_tree)) != NULL)
00566       return;
00567     
00568     if (param->type == P_TYPE_BOOL)
00569       init_val.bool_val = 0;
00570     
00571     else if (param->type == P_TYPE_INT)
00572       init_val.int_val = *(int*)param->engine_val;
00573 
00574     else if (param->type == P_TYPE_DOUBLE)
00575       init_val.double_val = *(double*)param->engine_val;
00576 
00577     //printf("%s\n", param->name);
00578     /* Create new initial condition */
00579     if ((init_cond = new_init_cond(param, init_val)) == NULL)
00580       return;
00581     
00582     /* Insert the initial condition into this presets tree */
00583     if (splay_insert(init_cond, init_cond->param->name, interface_shape->init_cond_tree) < 0) {
00584       free_init_cond(init_cond);
00585       return;
00586     }
00587     
00588   }
00589  
00590 }
00591 
00592 
00593 /* Interface function. Makes another custom shape the current
00594    concern for per frame / point equations */
00595 inline custom_shape_t * nextCustomShape() {
00596 
00597   if ((interface_shape = splay_find(&cwave_interface_id, active_preset->custom_shape_tree)) == NULL) {
00598     cwave_interface_id = 0;
00599     return NULL;
00600   }
00601 
00602   cwave_interface_id++;
00603 
00604   /* Evaluate all per frame equations associated with this shape */
00605   splay_traverse(eval_per_frame_eqn, interface_shape->per_frame_eqn_tree);
00606   return interface_shape;
00607 }

Generated on Tue Dec 20 10:14:56 2005 for vlc-0.8.4a by  doxygen 1.4.2