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