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