]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/eval.c
4ad7bc28676e1da682bc823e2eb82f770670178f
[vlc] / modules / visualization / galaktos / eval.c
1 /*****************************************************************************
2  * eval.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 <stdlib.h>
26
27 /* Evaluation Code */
28
29 #include "common.h"
30 #include "fatal.h"
31
32 #include "param_types.h"
33 #include "func_types.h"
34 #include "expr_types.h"
35 #include "eval.h"
36 #include "engine_vars.h"
37 #include "builtin_funcs.h"
38 #define EVAL_ERROR -1
39
40 /* All infix operators (except '=') are prototyped here */
41 infix_op_t * infix_add, * infix_minus, * infix_div, * infix_mult,
42   * infix_or, * infix_and, * infix_mod, * infix_negative, * infix_positive;
43 int mesh_i=-1, mesh_j=-1;
44
45 static inline double eval_tree_expr(tree_expr_t * tree_expr);
46 static inline double eval_prefun_expr(prefun_expr_t * prefun_expr);
47 static inline double eval_val_expr(val_expr_t * val_expr);
48
49
50 inline double eval_gen_expr(gen_expr_t * gen_expr) {
51   double l;
52
53   if (gen_expr == NULL) 
54         return 0;
55         
56   switch(gen_expr->type) {
57   case VAL_T:  
58     return eval_val_expr(gen_expr->item);
59   case PREFUN_T:
60     l = eval_prefun_expr(gen_expr->item);
61     //if (EVAL_DEBUG) printf("eval_gen_expr: prefix function return value: %f\n", l);
62     return l;           
63   case TREE_T:
64     return eval_tree_expr(gen_expr->item);
65   default:
66     #ifdef EVAL_DEBUG
67     printf("eval_gen_expr: general expression matched no cases!\n");
68     #endif
69     return EVAL_ERROR;
70   }  
71         
72 }
73
74 /* Evaluates functions in prefix form */
75 static inline double eval_prefun_expr(prefun_expr_t * prefun_expr) {
76         int i;
77        
78         
79         /* This is slightly less than safe, since
80            who knows if the passed argument is valid. For 
81            speed purposes we'll go with this */
82         double arg_list[prefun_expr->num_args];
83         
84         #ifdef EVAL_DEBUG 
85                 printf("fn[");
86                 fflush(stdout);
87         #endif
88         /* Evaluate each argument before calling the function itself */
89         for (i = 0; i < prefun_expr->num_args; i++) {
90                 arg_list[i] = eval_gen_expr(prefun_expr->expr_list[i]);
91                 #ifdef EVAL_DEBUG 
92                         if (i < (prefun_expr->num_args - 1))
93                                 printf(", ");
94                         fflush(stdout);
95                 #endif
96         }
97         
98         #ifdef EVAL_DEBUG 
99                 printf("]");
100                 fflush(stdout);
101         #endif
102         
103         /* Now we call the function, passing a list of  
104            doubles as its argument */
105      
106
107      
108         return (prefun_expr->func_ptr)(arg_list);       
109 }       
110
111 /* Evaluates a value expression */
112 static inline double eval_val_expr(val_expr_t * val_expr) {
113
114   /* Shouldn't happen */
115   if (val_expr == NULL)
116     return EVAL_ERROR;
117
118   /* Value is a constant, return the double value */
119   if (val_expr->type == CONSTANT_TERM_T) {
120     #ifdef EVAL_DEBUG 
121                 printf("%.4f", val_expr->term.constant);
122                 fflush(stdout);
123     #endif
124     return (val_expr->term.constant);
125   }
126
127   /* Value is variable, dereference it */
128   if (val_expr->type == PARAM_TERM_T) {
129         switch (val_expr->term.param->type) {
130                 
131         case P_TYPE_BOOL:
132                 #ifdef EVAL_DEBUG 
133                         printf("(%s:%.4f)", val_expr->term.param->name, (double)(*((int*)(val_expr->term.param->engine_val))));
134                         fflush(stdout);
135                 #endif
136                
137                   
138                 return (double)(*((int*)(val_expr->term.param->engine_val)));
139         case P_TYPE_INT:
140                 #ifdef EVAL_DEBUG 
141                         printf("(%s:%.4f)", val_expr->term.param->name, (double)(*((int*)(val_expr->term.param->engine_val))));
142                         fflush(stdout);
143                 #endif
144
145              
146                 return (double)(*((int*)(val_expr->term.param->engine_val)));
147         case P_TYPE_DOUBLE:             
148                 #ifdef EVAL_DEBUG 
149                         printf("(%s:%.4f)", val_expr->term.param->name, (*((double*)val_expr->term.param->engine_val)));
150                         fflush(stdout);
151                 #endif
152                         
153                 if (val_expr->term.param->matrix_flag | (val_expr->term.param->flags & P_FLAG_ALWAYS_MATRIX)) {
154                   if (mesh_j >= 0) {
155                     return (((double**)val_expr->term.param->matrix)[mesh_i][mesh_j]);
156                   }
157                   else {
158                     return (((double*)val_expr->term.param->matrix)[mesh_i]);
159                   }
160                 }
161                 return *((double*)(val_expr->term.param->engine_val));
162         default:
163           return ERROR; 
164     }
165   }
166   /* Unknown type, return failure */
167   return FAILURE;
168 }
169
170 /* Evaluates an expression tree */
171 static inline double eval_tree_expr(tree_expr_t * tree_expr) {
172                 
173         double left_arg, right_arg;     
174         infix_op_t * infix_op;
175         
176         /* Shouldn't happen */
177         if (tree_expr == NULL)
178           return EVAL_ERROR;
179
180         /* A leaf node, evaluate the general expression. If the expression is null as well, return zero */
181         if (tree_expr->infix_op == NULL) {
182                 if (tree_expr->gen_expr == NULL)
183                         return 0;
184                 else
185                         return eval_gen_expr(tree_expr->gen_expr);
186         }
187         
188         /* Otherwise, this node is an infix operator. Evaluate
189            accordingly */
190         
191         infix_op = (infix_op_t*)tree_expr->infix_op;    
192         #ifdef EVAL_DEBUG 
193                 printf("(");
194                 fflush(stdout);
195         #endif
196         
197         left_arg = eval_tree_expr(tree_expr->left);
198
199         #ifdef EVAL_DEBUG 
200                 
201                 switch (infix_op->type) {
202                 case INFIX_ADD:
203                         printf("+");
204                         break;          
205                 case INFIX_MINUS:
206                         printf("-");
207                         break;
208                 case INFIX_MULT:
209                         printf("*");
210                         break;
211                 case INFIX_MOD:
212                         printf("%%");
213                         break;
214                 case INFIX_OR:
215                         printf("|");
216                         break;
217                 case INFIX_AND:
218                         printf("&");
219                         break;
220                 case INFIX_DIV:
221                         printf("/");
222                         break;
223                 default:
224                         printf("?");
225                 }
226         
227         fflush(stdout); 
228         #endif
229         
230         right_arg = eval_tree_expr(tree_expr->right);
231         
232         #ifdef EVAL_DEBUG
233                 printf(")");
234                 fflush(stdout);
235         #endif
236         
237         switch (infix_op->type) {               
238         case INFIX_ADD:
239           return (left_arg + right_arg);                
240         case INFIX_MINUS:
241                 return (left_arg - right_arg);
242         case INFIX_MULT:
243                 return (left_arg * right_arg);
244         case INFIX_MOD:
245           if ((int)right_arg == 0) {
246             #ifdef EVAL_DEBUG 
247             printf("eval_tree_expr: modulo zero!\n");
248             #endif
249             return DIV_BY_ZERO; 
250           }
251           return ((int)left_arg % (int)right_arg);
252         case INFIX_OR:
253                 return ((int)left_arg | (int)right_arg);
254         case INFIX_AND:
255                 return ((int)left_arg & (int)right_arg);
256         case INFIX_DIV:
257           if (right_arg == 0) {
258             #ifdef EVAL_DEBUG 
259             printf("eval_tree_expr: division by zero!\n");
260             #endif
261             return MAX_DOUBLE_SIZE;
262           }             
263           return (left_arg / right_arg);
264         default:
265           #ifdef EVAL_DEBUG 
266             printf("eval_tree_expr: unknown infix operator!\n");
267           #endif
268                 return ERROR;
269         }
270         
271         return ERROR;
272 }       
273
274 /* Converts a double value to a general expression */
275 gen_expr_t * const_to_expr(double val) {
276
277   gen_expr_t * gen_expr;
278   val_expr_t * val_expr;
279   term_t term;
280   
281   term.constant = val;
282     
283   if ((val_expr = new_val_expr(CONSTANT_TERM_T, term)) == NULL)
284     return NULL;
285
286   gen_expr = new_gen_expr(VAL_T, (void*)val_expr);
287
288   if (gen_expr == NULL) {
289         free_val_expr(val_expr);
290   }
291   
292   return gen_expr;
293 }
294
295 /* Converts a regular parameter to an expression */
296 gen_expr_t * param_to_expr(param_t * param) {
297
298   gen_expr_t * gen_expr = NULL;
299   val_expr_t * val_expr = NULL;
300   term_t term;
301
302   if (param == NULL)
303     return NULL;
304  
305   /* This code is still a work in progress. We need
306      to figure out if the initial condition is used for 
307      each per frame equation or not. I am guessing that
308      it isn't, and it is thusly implemented this way */
309   
310   /* Current guess of true behavior (08/01/03) note from carm
311      First try to use the per_pixel_expr (with cloning). 
312      If it is null however, use the engine variable instead. */
313   
314   /* 08/20/03 : Presets are now objects, as well as per pixel equations. This ends up
315      making the parser handle the case where parameters are essentially per pixel equation
316      substitutions */
317        
318   
319   term.param = param;
320   if ((val_expr = new_val_expr(PARAM_TERM_T, term)) == NULL)
321     return NULL;
322   
323   if ((gen_expr = new_gen_expr(VAL_T, (void*)val_expr)) == NULL) {
324     free_val_expr(val_expr);
325         return NULL;      
326   } 
327   return gen_expr;
328 }
329
330 /* Converts a prefix function to an expression */
331 gen_expr_t * prefun_to_expr(double (*func_ptr)(), gen_expr_t ** expr_list, int num_args) {
332
333   gen_expr_t * gen_expr;
334   prefun_expr_t * prefun_expr;
335   
336
337   /* Malloc a new prefix function expression */
338   prefun_expr = (prefun_expr_t*)malloc(sizeof(prefun_expr_t));
339
340   if (prefun_expr == NULL)
341           return NULL;
342   
343   prefun_expr->num_args = num_args;
344   prefun_expr->func_ptr = func_ptr;
345   prefun_expr->expr_list = expr_list;
346
347   gen_expr = new_gen_expr(PREFUN_T, (void*)prefun_expr);
348
349   if (gen_expr == NULL)
350           free_prefun_expr(prefun_expr);
351   
352   return gen_expr;
353 }
354
355 /* Creates a new tree expression */
356 tree_expr_t * new_tree_expr(infix_op_t * infix_op, gen_expr_t * gen_expr, tree_expr_t * left, tree_expr_t * right) {
357
358                 tree_expr_t * tree_expr;
359                 tree_expr = (tree_expr_t*)malloc(sizeof(tree_expr_t));
360         
361                 if (tree_expr == NULL)
362                         return NULL;
363                 tree_expr->infix_op = infix_op;
364                 tree_expr->gen_expr = gen_expr;
365                 tree_expr->left = left;
366                 tree_expr->right = right;
367                 return tree_expr;
368 }
369
370
371 /* Creates a new value expression */
372 val_expr_t * new_val_expr(int type, term_t term) {
373
374   val_expr_t * val_expr;
375   val_expr = (val_expr_t*)malloc(sizeof(val_expr_t));
376
377   if (val_expr == NULL)
378     return NULL;
379
380   val_expr->type = type;
381   val_expr->term = term;
382
383   return val_expr;
384 }
385
386 /* Creates a new general expression */
387 gen_expr_t * new_gen_expr(int type, void * item) {
388
389         gen_expr_t * gen_expr;
390
391         gen_expr = (gen_expr_t*)malloc(sizeof(gen_expr_t));
392         if (gen_expr == NULL)
393                 return NULL;
394         gen_expr->type = type;
395         gen_expr->item = item;  
396
397         return gen_expr;
398 }
399
400 /* Frees a general expression */
401 int free_gen_expr(gen_expr_t * gen_expr) {
402
403         if (gen_expr == NULL)
404                 return SUCCESS;
405         
406         switch (gen_expr->type) {
407         case VAL_T:
408                 free_val_expr(gen_expr->item);
409                 break;
410         case PREFUN_T:
411                 free_prefun_expr(gen_expr->item);
412                 break;
413         case TREE_T:
414                 free_tree_expr(gen_expr->item);
415                 break;
416         default:
417                 return FAILURE;
418         }       
419
420         free(gen_expr);
421         return SUCCESS;
422
423 }
424
425
426 /* Frees a function in prefix notation */
427 int free_prefun_expr(prefun_expr_t * prefun_expr) {
428
429         int i;
430         if (prefun_expr == NULL)
431                 return SUCCESS;
432         
433         /* Free every element in expression list */
434         for (i = 0 ; i < prefun_expr->num_args; i++) {
435                 free_gen_expr(prefun_expr->expr_list[i]);
436         }
437
438         free(prefun_expr);
439         return SUCCESS;
440 }
441
442 /* Frees values of type VARIABLE and CONSTANT */
443 int free_val_expr(val_expr_t * val_expr) {
444
445         if (val_expr == NULL)
446                 return SUCCESS; 
447         
448         free(val_expr);
449         return SUCCESS;
450 }
451
452 /* Frees a tree expression */
453 int free_tree_expr(tree_expr_t * tree_expr) {
454
455         if (tree_expr == NULL)
456                 return SUCCESS;
457         
458         /* free left tree */
459         free_tree_expr(tree_expr->left);
460         
461         /* free general expression object */
462         free_gen_expr(tree_expr->gen_expr);
463         
464         /* Note that infix operators are always
465            stored in memory unless the program 
466            exits, so we don't remove them here */
467         
468         /* free right tree */
469         free_tree_expr(tree_expr->right);
470         
471         
472         /* finally, free the struct itself */
473         free(tree_expr);
474         return SUCCESS;
475 }
476
477
478
479 /* Initializes all infix operators */
480 int init_infix_ops() {
481
482         infix_add = new_infix_op(INFIX_ADD, 4);
483         infix_minus = new_infix_op(INFIX_MINUS, 3);
484         infix_div = new_infix_op(INFIX_DIV, 2);
485         infix_or = new_infix_op(INFIX_OR, 5);
486         infix_and = new_infix_op(INFIX_AND,4);
487         infix_mod = new_infix_op(INFIX_MOD, 1);
488         infix_mult = new_infix_op(INFIX_MULT, 2);
489         
490         /* Prefix operators */
491         infix_positive = new_infix_op(INFIX_ADD, 0);
492         infix_negative = new_infix_op(INFIX_MINUS, 0);
493
494         return SUCCESS;
495 }
496
497 /* Destroys the infix operator list. This should
498    be done on program exit */
499 int destroy_infix_ops()
500 {
501
502   free(infix_add);
503   free(infix_minus);
504   free(infix_div);
505   free(infix_or);
506   free(infix_and);
507   free(infix_mod);
508   free(infix_mult);
509   free(infix_positive);
510   free(infix_negative);
511
512   return SUCCESS;
513 }
514
515 /* Initializes an infix operator */
516 infix_op_t * new_infix_op(int type, int precedence) {
517
518         infix_op_t * infix_op;
519         
520         infix_op = (infix_op_t*)malloc(sizeof(infix_op_t));
521         
522         if (infix_op == NULL)
523                 return NULL;
524         
525         infix_op->type = type;
526         infix_op->precedence = precedence;
527         
528         return infix_op;
529 }
530
531
532
533
534 /* Clones a general expression */
535 gen_expr_t * clone_gen_expr(gen_expr_t * gen_expr) {
536
537   gen_expr_t * new_gen_expr;
538   val_expr_t * val_expr;
539   tree_expr_t * tree_expr;
540   prefun_expr_t * prefun_expr;
541
542   /* Null argument check */
543   if (gen_expr == NULL)
544     return NULL;
545
546   /* Out of memory */
547   if ((new_gen_expr = (gen_expr_t*)malloc(sizeof(gen_expr_t))) == NULL)
548     return NULL;
549
550   /* Case on the type of general expression */
551   switch (new_gen_expr->type = gen_expr->type) {
552
553   case VAL_T: /* val expression */
554     if ((val_expr = clone_val_expr((val_expr_t*)gen_expr->item)) == NULL) {
555       free(new_gen_expr);
556       return NULL;
557     }
558     new_gen_expr->item = (void*)val_expr;
559     break;
560     
561   case PREFUN_T: /* prefix function expression */
562     if ((prefun_expr = clone_prefun_expr((prefun_expr_t*)gen_expr->item)) == NULL) {
563       free(new_gen_expr);
564       return NULL;
565     }
566     new_gen_expr->item = (void*)prefun_expr;
567     break;
568     
569   case TREE_T:  /* tree expression */
570     if ((tree_expr = clone_tree_expr((tree_expr_t*)gen_expr->item)) == NULL) {
571       free(new_gen_expr);
572       return NULL;
573     }
574     new_gen_expr->item = (void*)tree_expr;
575     break;
576     
577   default: /* unknown type, ut oh.. */
578     free(new_gen_expr);
579     return NULL;
580   }
581   
582   return new_gen_expr; /* Return the new (cloned) general expression */
583 }
584
585
586 /* Clones a tree expression */
587 tree_expr_t * clone_tree_expr(tree_expr_t * tree_expr) {
588
589   tree_expr_t * new_tree_expr;
590
591   /* Null argument */
592   if (tree_expr == NULL)
593     return NULL;
594   
595   /* Out of memory */
596   if ((new_tree_expr = (tree_expr_t*)malloc(sizeof(tree_expr_t))) == NULL) 
597     return NULL;
598   
599   /* Set each argument in tree_expr_t struct */
600   new_tree_expr->infix_op = tree_expr->infix_op;  /* infix operators are in shared memory */
601   new_tree_expr->gen_expr = clone_gen_expr(tree_expr->gen_expr); /* clone the general expression */
602   new_tree_expr->left = clone_tree_expr(tree_expr->left); /* clone the left tree expression */
603   new_tree_expr->right = clone_tree_expr(tree_expr->right); /* clone the right tree expression */
604
605   return new_tree_expr; /* Return the new (cloned) tree expression */
606 }
607
608 /* Clones a value expression, currently only passes the pointer to 
609    the value that this object represents, not a pointer to a copy of the value */
610 val_expr_t * clone_val_expr(val_expr_t * val_expr) {
611
612   val_expr_t * new_val_expr;
613
614   /* Null argument */
615   if (val_expr == NULL)
616     return NULL;
617   
618   /* Allocate space, check for out of memory */
619   if ((new_val_expr = (val_expr_t*)malloc(sizeof(val_expr_t))) == NULL) 
620     return NULL;
621
622   /* Set the values in the val_expr_t struct */
623   new_val_expr->type = val_expr->type;
624   new_val_expr->term = val_expr->term;
625   
626   /* Return the new (cloned) value expression */
627   return new_val_expr;
628 }
629
630 /* Clones a prefix function with its arguments */
631 prefun_expr_t * clone_prefun_expr(prefun_expr_t * prefun_expr) {
632
633   int i;
634   prefun_expr_t * new_prefun_expr;
635   
636   /* Null argument */
637   if (prefun_expr == NULL)
638     return NULL;
639   
640   /* Out of memory */
641   if ((new_prefun_expr = (prefun_expr_t*)malloc(sizeof(prefun_expr_t))) == NULL) 
642     return NULL;
643   
644   /* Set the function argument paired with its number of arguments */
645   new_prefun_expr->num_args = prefun_expr->num_args;
646   new_prefun_expr->func_ptr = prefun_expr->func_ptr;
647
648   /* Allocate space for the expression list pointers */
649   if ((new_prefun_expr->expr_list = (gen_expr_t**)malloc(sizeof(gen_expr_t*)*new_prefun_expr->num_args)) == NULL) {
650     free(new_prefun_expr);
651     return NULL;
652   }
653
654   /* Now copy each general expression from the argument expression list */
655   for (i = 0; i < new_prefun_expr->num_args;i++) 
656     new_prefun_expr->expr_list[i] = clone_gen_expr(prefun_expr->expr_list[i]);
657   
658   /* Finally, return the new (cloned) prefix function expression */
659   return new_prefun_expr;
660 }
661
662 /* Reinitializes the engine variables to a default (conservative and sane) value */
663 void reset_engine_vars() {
664
665   zoom=1.0;
666   zoomexp= 1.0;
667   rot= 0.0;
668   warp= 0.0;
669   
670   sx= 1.0;
671   sy= 1.0;
672   dx= 0.0;
673   dy= 0.0;
674   cx= 0.5;
675   cy= 0.5;
676
677   
678   decay=.98;
679   
680   wave_r= 1.0;
681   wave_g= 0.2;
682   wave_b= 0.0;
683   wave_x= 0.5;
684   wave_y= 0.5;
685   wave_mystery= 0.0;
686
687   ob_size= 0.0;
688   ob_r= 0.0;
689   ob_g= 0.0;
690   ob_b= 0.0;
691   ob_a= 0.0;
692
693   ib_size = 0.0;
694   ib_r = 0.0;
695   ib_g = 0.0;
696   ib_b = 0.0;
697   ib_a = 0.0;
698
699   mv_a = 0.0;
700   mv_r = 0.0;
701   mv_g = 0.0;
702   mv_b = 0.0;
703   mv_l = 1.0;
704   mv_x = 16.0;
705   mv_y = 12.0;
706   mv_dy = 0.02;
707   mv_dx = 0.02;
708   
709   meshx = 0;
710   meshy = 0;
711  
712   Time = 0;
713   treb = 0;
714   mid = 0;
715   bass = 0;
716   treb_att = 0;
717   mid_att = 0;
718   bass_att = 0;
719   progress = 0;
720   frame = 0;
721
722 // bass_thresh = 0;
723
724 /* PER_FRAME CONSTANTS END */
725   fRating = 0;
726   fGammaAdj = 1.0;
727   fVideoEchoZoom = 1.0;
728   fVideoEchoAlpha = 0;
729   nVideoEchoOrientation = 0;
730  
731   nWaveMode = 7;
732   bAdditiveWaves = 0;
733   bWaveDots = 0;
734   bWaveThick = 0;
735   bModWaveAlphaByVolume = 0;
736   bMaximizeWaveColor = 0;
737   bTexWrap = 0;
738   bDarkenCenter = 0;
739   bRedBlueStereo = 0;
740   bBrighten = 0;
741   bDarken = 0;
742   bSolarize = 0;
743  bInvert = 0;
744  bMotionVectorsOn = 1;
745  
746   fWaveAlpha =1.0;
747   fWaveScale = 1.0;
748   fWaveSmoothing = 0;
749   fWaveParam = 0;
750   fModWaveAlphaStart = 0;
751   fModWaveAlphaEnd = 0;
752   fWarpAnimSpeed = 0;
753   fWarpScale = 0;
754   fShader = 0;
755
756
757 /* PER_PIXEL CONSTANTS BEGIN */
758  x_per_pixel = 0;
759  y_per_pixel = 0;
760  rad_per_pixel = 0;
761  ang_per_pixel = 0;
762
763 /* PER_PIXEL CONSTANT END */
764
765
766 /* Q VARIABLES START */
767
768  q1 = 0;
769  q2 = 0;
770  q3 = 0;
771  q4 = 0;
772  q5 = 0;
773  q6 = 0;
774  q7 = 0;
775  q8 = 0;
776
777
778  /* Q VARIABLES END */
779
780
781 }
782
783