1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
7 * Authors: Cyril Deguet <asmax@videolan.org>
8 * code from projectM http://xmms-projectm.sourceforge.net
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.
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.
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 *****************************************************************************/
33 #include "param_types.h"
34 #include "func_types.h"
35 #include "expr_types.h"
37 #include "engine_vars.h"
38 #include "builtin_funcs.h"
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;
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);
51 static inline double eval_gen_expr(gen_expr_t * gen_expr) {
57 switch(gen_expr->type) {
59 return eval_val_expr(gen_expr->item);
61 l = eval_prefun_expr(gen_expr->item);
62 //if (EVAL_DEBUG) printf("eval_gen_expr: prefix function return value: %f\n", l);
65 return eval_tree_expr(gen_expr->item);
68 printf("eval_gen_expr: general expression matched no cases!\n");
75 /* Evaluates functions in prefix form */
76 static inline double eval_prefun_expr(prefun_expr_t * prefun_expr) {
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];
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]);
93 if (i < (prefun_expr->num_args - 1))
104 /* Now we call the function, passing a list of
105 doubles as its argument */
109 return (prefun_expr->func_ptr)(arg_list);
112 /* Evaluates a value expression */
113 static inline double eval_val_expr(val_expr_t * val_expr) {
115 /* Shouldn't happen */
116 if (val_expr == NULL)
119 /* Value is a constant, return the double value */
120 if (val_expr->type == CONSTANT_TERM_T) {
122 printf("%.4f", val_expr->term.constant);
125 return (val_expr->term.constant);
128 /* Value is variable, dereference it */
129 if (val_expr->type == PARAM_TERM_T) {
130 switch (val_expr->term.param->type) {
134 printf("(%s:%.4f)", val_expr->term.param->name, (double)(*((int*)(val_expr->term.param->engine_val))));
139 return (double)(*((int*)(val_expr->term.param->engine_val)));
142 printf("(%s:%.4f)", val_expr->term.param->name, (double)(*((int*)(val_expr->term.param->engine_val))));
147 return (double)(*((int*)(val_expr->term.param->engine_val)));
150 printf("(%s:%.4f)", val_expr->term.param->name, (*((double*)val_expr->term.param->engine_val)));
154 if (val_expr->term.param->matrix_flag | (val_expr->term.param->flags & P_FLAG_ALWAYS_MATRIX)) {
156 return (((double**)val_expr->term.param->matrix)[mesh_i][mesh_j]);
159 return (((double*)val_expr->term.param->matrix)[mesh_i]);
162 return *((double*)(val_expr->term.param->engine_val));
167 /* Unknown type, return failure */
171 /* Evaluates an expression tree */
172 static inline double eval_tree_expr(tree_expr_t * tree_expr) {
174 double left_arg, right_arg;
175 infix_op_t * infix_op;
177 /* Shouldn't happen */
178 if (tree_expr == NULL)
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)
186 return eval_gen_expr(tree_expr->gen_expr);
189 /* Otherwise, this node is an infix operator. Evaluate
192 infix_op = (infix_op_t*)tree_expr->infix_op;
198 left_arg = eval_tree_expr(tree_expr->left);
202 switch (infix_op->type) {
231 right_arg = eval_tree_expr(tree_expr->right);
238 switch (infix_op->type) {
240 return (left_arg + right_arg);
242 return (left_arg - right_arg);
244 return (left_arg * right_arg);
246 if ((int)right_arg == 0) {
248 printf("eval_tree_expr: modulo zero!\n");
252 return ((int)left_arg % (int)right_arg);
254 return ((int)left_arg | (int)right_arg);
256 return ((int)left_arg & (int)right_arg);
258 if (right_arg == 0) {
260 printf("eval_tree_expr: division by zero!\n");
262 return MAX_DOUBLE_SIZE;
264 return (left_arg / right_arg);
267 printf("eval_tree_expr: unknown infix operator!\n");
275 /* Converts a double value to a general expression */
276 gen_expr_t * const_to_expr(double val) {
278 gen_expr_t * gen_expr;
279 val_expr_t * val_expr;
284 if ((val_expr = new_val_expr(CONSTANT_TERM_T, term)) == NULL)
287 gen_expr = new_gen_expr(VAL_T, (void*)val_expr);
289 if (gen_expr == NULL) {
290 free_val_expr(val_expr);
296 /* Converts a regular parameter to an expression */
297 gen_expr_t * param_to_expr(param_t * param) {
299 gen_expr_t * gen_expr = NULL;
300 val_expr_t * val_expr = NULL;
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 */
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. */
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
321 if ((val_expr = new_val_expr(PARAM_TERM_T, term)) == NULL)
324 if ((gen_expr = new_gen_expr(VAL_T, (void*)val_expr)) == NULL) {
325 free_val_expr(val_expr);
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) {
334 gen_expr_t * gen_expr;
335 prefun_expr_t * prefun_expr;
338 /* Malloc a new prefix function expression */
339 prefun_expr = (prefun_expr_t*)malloc(sizeof(prefun_expr_t));
341 if (prefun_expr == NULL)
344 prefun_expr->num_args = num_args;
345 prefun_expr->func_ptr = func_ptr;
346 prefun_expr->expr_list = expr_list;
348 gen_expr = new_gen_expr(PREFUN_T, (void*)prefun_expr);
350 if (gen_expr == NULL)
351 free_prefun_expr(prefun_expr);
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) {
359 tree_expr_t * tree_expr;
360 tree_expr = (tree_expr_t*)malloc(sizeof(tree_expr_t));
362 if (tree_expr == 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;
372 /* Creates a new value expression */
373 val_expr_t * new_val_expr(int type, term_t term) {
375 val_expr_t * val_expr;
376 val_expr = (val_expr_t*)malloc(sizeof(val_expr_t));
378 if (val_expr == NULL)
381 val_expr->type = type;
382 val_expr->term = term;
387 /* Creates a new general expression */
388 gen_expr_t * new_gen_expr(int type, void * item) {
390 gen_expr_t * gen_expr;
392 gen_expr = (gen_expr_t*)malloc(sizeof(gen_expr_t));
393 if (gen_expr == NULL)
395 gen_expr->type = type;
396 gen_expr->item = item;
401 /* Frees a general expression */
402 int free_gen_expr(gen_expr_t * gen_expr) {
404 if (gen_expr == NULL)
407 switch (gen_expr->type) {
409 free_val_expr(gen_expr->item);
412 free_prefun_expr(gen_expr->item);
415 free_tree_expr(gen_expr->item);
427 /* Frees a function in prefix notation */
428 int free_prefun_expr(prefun_expr_t * prefun_expr) {
431 if (prefun_expr == NULL)
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]);
443 /* Frees values of type VARIABLE and CONSTANT */
444 int free_val_expr(val_expr_t * val_expr) {
446 if (val_expr == NULL)
453 /* Frees a tree expression */
454 int free_tree_expr(tree_expr_t * tree_expr) {
456 if (tree_expr == NULL)
460 free_tree_expr(tree_expr->left);
462 /* free general expression object */
463 free_gen_expr(tree_expr->gen_expr);
465 /* Note that infix operators are always
466 stored in memory unless the program
467 exits, so we don't remove them here */
469 /* free right tree */
470 free_tree_expr(tree_expr->right);
473 /* finally, free the struct itself */
480 /* Initializes all infix operators */
481 int init_infix_ops() {
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);
491 /* Prefix operators */
492 infix_positive = new_infix_op(INFIX_ADD, 0);
493 infix_negative = new_infix_op(INFIX_MINUS, 0);
498 /* Destroys the infix operator list. This should
499 be done on program exit */
500 int destroy_infix_ops()
510 free(infix_positive);
511 free(infix_negative);
516 /* Initializes an infix operator */
517 infix_op_t * new_infix_op(int type, int precedence) {
519 infix_op_t * infix_op;
521 infix_op = (infix_op_t*)malloc(sizeof(infix_op_t));
523 if (infix_op == NULL)
526 infix_op->type = type;
527 infix_op->precedence = precedence;
535 /* Clones a general expression */
536 gen_expr_t * clone_gen_expr(gen_expr_t * gen_expr) {
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;
543 /* Null argument check */
544 if (gen_expr == NULL)
548 if ((new_gen_expr = (gen_expr_t*)malloc(sizeof(gen_expr_t))) == NULL)
551 /* Case on the type of general expression */
552 switch (new_gen_expr->type = gen_expr->type) {
554 case VAL_T: /* val expression */
555 if ((val_expr = clone_val_expr((val_expr_t*)gen_expr->item)) == NULL) {
559 new_gen_expr->item = (void*)val_expr;
562 case PREFUN_T: /* prefix function expression */
563 if ((prefun_expr = clone_prefun_expr((prefun_expr_t*)gen_expr->item)) == NULL) {
567 new_gen_expr->item = (void*)prefun_expr;
570 case TREE_T: /* tree expression */
571 if ((tree_expr = clone_tree_expr((tree_expr_t*)gen_expr->item)) == NULL) {
575 new_gen_expr->item = (void*)tree_expr;
578 default: /* unknown type, ut oh.. */
583 return new_gen_expr; /* Return the new (cloned) general expression */
587 /* Clones a tree expression */
588 tree_expr_t * clone_tree_expr(tree_expr_t * tree_expr) {
590 tree_expr_t * new_tree_expr;
593 if (tree_expr == NULL)
597 if ((new_tree_expr = (tree_expr_t*)malloc(sizeof(tree_expr_t))) == NULL)
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 */
606 return new_tree_expr; /* Return the new (cloned) tree expression */
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) {
613 val_expr_t * new_val_expr;
616 if (val_expr == NULL)
619 /* Allocate space, check for out of memory */
620 if ((new_val_expr = (val_expr_t*)malloc(sizeof(val_expr_t))) == NULL)
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;
627 /* Return the new (cloned) value expression */
631 /* Clones a prefix function with its arguments */
632 prefun_expr_t * clone_prefun_expr(prefun_expr_t * prefun_expr) {
635 prefun_expr_t * new_prefun_expr;
638 if (prefun_expr == NULL)
642 if ((new_prefun_expr = (prefun_expr_t*)malloc(sizeof(prefun_expr_t))) == NULL)
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;
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);
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]);
659 /* Finally, return the new (cloned) prefix function expression */
660 return new_prefun_expr;
663 /* Reinitializes the engine variables to a default (conservative and sane) value */
664 void reset_engine_vars() {
725 /* PER_FRAME CONSTANTS END */
728 fVideoEchoZoom = 1.0;
730 nVideoEchoOrientation = 0;
736 bModWaveAlphaByVolume = 0;
737 bMaximizeWaveColor = 0;
745 bMotionVectorsOn = 1;
751 fModWaveAlphaStart = 0;
752 fModWaveAlphaEnd = 0;
758 /* PER_PIXEL CONSTANTS BEGIN */
764 /* PER_PIXEL CONSTANT END */
767 /* Q VARIABLES START */
779 /* Q VARIABLES END */