mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-03-04 22:45:17 +00:00
@ -16,7 +16,9 @@ script:
|
||||
- test -e dist_install/share/projectM/shaders/blur.cg
|
||||
- test -d dist_install/share/projectM/presets
|
||||
- test -e dist_install/lib/libprojectM.la
|
||||
- test -e dist_install/include/projectM.hpp
|
||||
- test -e dist_install/include/libprojectM/projectM.hpp
|
||||
- test -e dist_install/include/libprojectM/Common.hpp
|
||||
- test -e dist_install/include/libprojectM/PCM.hpp
|
||||
|
||||
# test on GCC and Clang
|
||||
matrix:
|
||||
|
||||
@ -19,6 +19,7 @@ AC_CONFIG_FILES([
|
||||
src/libprojectM/Renderer/Makefile
|
||||
src/libprojectM/NativePresetFactory/Makefile
|
||||
src/libprojectM/MilkdropPresetFactory/Makefile
|
||||
src/libprojectM/libprojectM.pc
|
||||
src/NativePresets/Makefile
|
||||
src/projectM-sdl/Makefile
|
||||
src/projectM-qt/Makefile
|
||||
|
||||
@ -7,3 +7,7 @@ if ENABLE_QT
|
||||
endif
|
||||
|
||||
SUBDIRS=libprojectM NativePresets ${PROJECTM_SDL_SUBDIR} ${PROJECTM_QT_SUBDIR}
|
||||
|
||||
# system headers/libraries/data to install
|
||||
# for compatibility reasons here as nobase_include
|
||||
nobase_include_HEADERS = libprojectM/projectM.hpp libprojectM/Common.hpp libprojectM/dlldefs.h libprojectM/event.h libprojectM/fatal.h libprojectM/PCM.hpp
|
||||
|
||||
30
src/README
30
src/README
@ -1,30 +0,0 @@
|
||||
PROJECTM README
|
||||
------------------------------
|
||||
NOTE: The projectM wiki at http://projectm.wiki.sourceforge.net/ is the official source for build instructions. What lies below is just a terse review of how to build the source yourself.
|
||||
|
||||
(1) How to configure the projectM build
|
||||
|
||||
In the top level directory from where you extracted projectM, run
|
||||
|
||||
ccmake .
|
||||
|
||||
This will present you with a simple console based gui of options for projectM. First press "c" to run the configure script. Review the options and change what you think is necessary. Press 'g' to generate the make files and exit.
|
||||
|
||||
(2) Compiling and installing
|
||||
|
||||
|
||||
As usual, type
|
||||
|
||||
make
|
||||
|
||||
followed by
|
||||
|
||||
make install
|
||||
|
||||
If any problems go to the web page at
|
||||
|
||||
http://projectm.sf.net
|
||||
|
||||
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
#include <typeinfo>
|
||||
#include <cstdarg>
|
||||
#include <cassert>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _MSC_sVER
|
||||
#define strcasecmp(s, t) _strcmpi(s, t)
|
||||
#endif
|
||||
|
||||
@ -11,8 +11,6 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libprojectM/Renderer \
|
||||
$(FTGL_CFLAGS) $(CG_CFLAGS)
|
||||
|
||||
# system headers/libraries/data to install
|
||||
include_HEADERS = projectM.hpp
|
||||
lib_LTLIBRARIES = libprojectM.la # public, possibly-shared library
|
||||
|
||||
# link flags
|
||||
@ -48,6 +46,6 @@ libprojectM_la_SOURCES = ConfigFile.cpp Preset.cpp PresetLoader.cpp timer.cpp \
|
||||
omptl/omptl_algorithm
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
# pkgconfig_DATA = src/libprojectM.pc
|
||||
# EXTRA_DIST += src/libprojectM.pc.in
|
||||
# CLEANFILES += src/libprojectM.pc
|
||||
pkgconfig_DATA = libprojectM.pc
|
||||
EXTRA_DIST += libprojectM.pc.in
|
||||
CLEANFILES += libprojectM.pc
|
||||
|
||||
@ -367,8 +367,8 @@ int BuiltinParams::load_all_builtin_param(const PresetInputs & presetInputs, Pre
|
||||
load_builtin_param_float("mv_x", (void*)&presetOutputs.mv.x_num, NULL,P_FLAG_NONE, 0.0, 64.0, 0.0, "nmotionvectorsx");
|
||||
load_builtin_param_float("mv_y", (void*)&presetOutputs.mv.y_num, NULL,P_FLAG_NONE, 0.0, 48.0, 0.0, "nmotionvectorsy");
|
||||
load_builtin_param_float("mv_l", (void*)&presetOutputs.mv.length, NULL,P_FLAG_NONE, 0.0, 5.0, 0.0, "");
|
||||
load_builtin_param_float("mv_dy", (void*)&presetOutputs.mv.x_offset, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, "");
|
||||
load_builtin_param_float("mv_dx", (void*)&presetOutputs.mv.y_offset, NULL,P_FLAG_NONE, 0.0, 1.0, -1.0, "");
|
||||
load_builtin_param_float("mv_dx", (void*)&presetOutputs.mv.x_offset, NULL, P_FLAG_NONE, 0.0, 1.0, -1.0, "");
|
||||
load_builtin_param_float("mv_dy", (void*)&presetOutputs.mv.y_offset, NULL,P_FLAG_NONE, 0.0, 1.0, -1.0, "");
|
||||
load_builtin_param_float("mv_a", (void*)&presetOutputs.mv.a, NULL,P_FLAG_NONE, 0.0, 1.0, 0.0, "");
|
||||
|
||||
load_builtin_param_float("time", (void*)&presetInputs.time, NULL,P_FLAG_READONLY, 0.0, MAX_DOUBLE_SIZE, 0.0, "");
|
||||
|
||||
@ -450,7 +450,7 @@ CustomWave::~CustomWave()
|
||||
|
||||
|
||||
// Comments: index is not passed, so we assume monotonic increment by 1 is ok here
|
||||
int CustomWave::add_per_point_eqn(char * name, GenExpr * gen_expr)
|
||||
int CustomWave::add_per_point_eqn(char * name, Expr * gen_expr)
|
||||
{
|
||||
|
||||
PerPointEqn * per_point_eqn;
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
#define CUSTOM_WAVE_DEBUG 0
|
||||
|
||||
class CustomWave;
|
||||
class GenExpr;
|
||||
class Expr;
|
||||
class PerPointEqn;
|
||||
class Preset;
|
||||
|
||||
@ -115,7 +115,7 @@ public:
|
||||
int per_frame_eqn_string_index;
|
||||
int per_frame_init_eqn_string_index;
|
||||
|
||||
int add_per_point_eqn(char * name, GenExpr * gen_expr);
|
||||
int add_per_point_eqn(char * name, Expr * gen_expr);
|
||||
void evalCustomWaveInitConditions(Preset *preset);
|
||||
|
||||
|
||||
|
||||
@ -69,25 +69,22 @@ public:
|
||||
*infix_negative,
|
||||
*infix_positive;
|
||||
|
||||
float eval_gen_expr(GenExpr * gen_expr);
|
||||
inline GenExpr * opt_gen_expr(GenExpr * gen_expr, int ** param_list);
|
||||
float eval_gen_expr(Expr * gen_expr);
|
||||
inline Expr * opt_gen_expr(Expr * gen_expr, int ** param_list);
|
||||
|
||||
GenExpr * const_to_expr(float val);
|
||||
GenExpr * param_to_expr(Param * param);
|
||||
GenExpr * prefun_to_expr(float (*func_ptr)(), GenExpr ** expr_list, int num_args);
|
||||
|
||||
static TreeExpr * new_tree_expr(InfixOp * infix_op, GenExpr * gen_expr, TreeExpr * left, TreeExpr * right);
|
||||
static GenExpr * new_gen_expr(int type, void * item);
|
||||
static ValExpr * new_val_expr(int type, Term *term);
|
||||
Expr * const_to_expr(float val);
|
||||
Expr * param_to_expr(Param * param);
|
||||
Expr * prefun_to_expr(float (*func_ptr)(), Expr ** expr_list, int num_args);
|
||||
|
||||
static TreeExpr * new_tree_expr(InfixOp * infix_op, Expr * gen_expr, TreeExpr * left, TreeExpr * right);
|
||||
static Expr * new_gen_expr(int type, void * item);
|
||||
|
||||
static InfixOp * new_infix_op(int type, int precedence);
|
||||
static int init_infix_ops();
|
||||
static int destroy_infix_ops();
|
||||
void reset_engine_vars();
|
||||
|
||||
GenExpr * clone_gen_expr(GenExpr * gen_expr);
|
||||
|
||||
TreeExpr * clone_tree_expr(TreeExpr * tree_expr);
|
||||
ValExpr * clone_val_expr(ValExpr * val_expr);
|
||||
PrefunExpr * clone_prefun_expr(PrefunExpr * prefun_expr);
|
||||
};
|
||||
|
||||
|
||||
@ -27,40 +27,16 @@
|
||||
#include <iostream>
|
||||
#include "Eval.hpp"
|
||||
|
||||
float GenExpr::eval_gen_expr ( int mesh_i, int mesh_j )
|
||||
{
|
||||
float l;
|
||||
|
||||
if (item == 0)
|
||||
return EVAL_ERROR;
|
||||
|
||||
switch ( this->type )
|
||||
{ /* N.B. this code is responsible for 75% of all CPU time. making it faster will help a lot. */
|
||||
case VAL_T:
|
||||
return ( ( ValExpr* ) item )->eval_val_expr ( mesh_i, mesh_j );
|
||||
case PREFUN_T:
|
||||
l = ( ( PrefunExpr * ) item )->eval_prefun_expr ( mesh_i, mesh_j );
|
||||
//if (EVAL_DEBUG) DWRITE( "eval_gen_expr: prefix function return value: %f\n", l);
|
||||
return l;
|
||||
case TREE_T:
|
||||
return ( ( TreeExpr* ) ( item ) )->eval_tree_expr ( mesh_i, mesh_j );
|
||||
default:
|
||||
return EVAL_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Evaluates functions in prefix form */
|
||||
float PrefunExpr::eval_prefun_expr ( int mesh_i, int mesh_j )
|
||||
float PrefunExpr::eval ( int mesh_i, int mesh_j )
|
||||
{
|
||||
|
||||
|
||||
assert ( func_ptr );
|
||||
float arg_list_stk[10];
|
||||
|
||||
float * arg_list;
|
||||
float * argp;
|
||||
GenExpr **expr_listp = expr_list;
|
||||
Expr **expr_listp = expr_list;
|
||||
|
||||
|
||||
if (this->num_args > 10) {
|
||||
@ -77,7 +53,7 @@ float PrefunExpr::eval_prefun_expr ( int mesh_i, int mesh_j )
|
||||
/* Evaluate each argument before calling the function itself */
|
||||
for ( int i = 0; i < num_args; i++ )
|
||||
{
|
||||
*(argp++) = (*(expr_listp++))->eval_gen_expr ( mesh_i, mesh_j );
|
||||
*(argp++) = (*(expr_listp++))->eval ( mesh_i, mesh_j );
|
||||
//printf("numargs %x", arg_list[i]);
|
||||
}
|
||||
/* Now we call the function, passing a list of
|
||||
@ -92,102 +68,243 @@ float PrefunExpr::eval_prefun_expr ( int mesh_i, int mesh_j )
|
||||
}
|
||||
|
||||
|
||||
/* Evaluates a value expression */
|
||||
float ValExpr::eval_val_expr ( int mesh_i, int mesh_j )
|
||||
class PrefunExprOne : public PrefunExpr
|
||||
{
|
||||
|
||||
|
||||
/* Value is a constant, return the float value */
|
||||
if ( type == CONSTANT_TERM_T )
|
||||
float eval ( int mesh_i, int mesh_j )
|
||||
{
|
||||
return ( term.constant );
|
||||
float val = expr_list[0]->eval ( mesh_i, mesh_j );
|
||||
return (func_ptr)(&val);
|
||||
}
|
||||
};
|
||||
|
||||
/* Value is variable, dereference it */
|
||||
if ( type == PARAM_TERM_T )
|
||||
|
||||
class ConstantExpr : public Expr
|
||||
{
|
||||
float constant;
|
||||
public:
|
||||
ConstantExpr( float value ) : Expr(CONSTANT), constant(value) {}
|
||||
ConstantExpr( int type, Term *term ) : Expr(CONSTANT), constant(term->constant) {}
|
||||
bool isConstant()
|
||||
{
|
||||
switch ( term.param->type )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
float eval(int mesh_i, int mesh_j )
|
||||
{
|
||||
return constant;
|
||||
}
|
||||
std::ostream &to_string(std::ostream &out)
|
||||
{
|
||||
out << constant; return out;
|
||||
}
|
||||
};
|
||||
|
||||
case P_TYPE_BOOL:
|
||||
class ParameterExpr : public Expr
|
||||
{
|
||||
protected:
|
||||
Term term;
|
||||
public:
|
||||
ParameterExpr( int _type, Term *_term ) : Expr(PARAMETER), term(*_term) {}
|
||||
float eval(int mesh_i, int mesh_j );
|
||||
std::ostream& to_string(std::ostream& out)
|
||||
{
|
||||
out << term.param->name;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
class BoolParameterExpr : public ParameterExpr
|
||||
{
|
||||
public:
|
||||
BoolParameterExpr( int _type, Term *_term ) : ParameterExpr(_type,_term) {}
|
||||
float eval ( int mesh_i, int mesh_j ) { return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) ); }
|
||||
};
|
||||
class IntParameterExpr : public ParameterExpr
|
||||
{
|
||||
public:
|
||||
IntParameterExpr( int _type, Term *_term ) : ParameterExpr(_type,_term) {}
|
||||
float eval ( int mesh_i, int mesh_j ) { return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) ); }
|
||||
};
|
||||
class FloatParameterExpr : public ParameterExpr
|
||||
{
|
||||
public:
|
||||
FloatParameterExpr( int _type, Term *_term ) : ParameterExpr(_type,_term) {}
|
||||
float eval ( int mesh_i, int mesh_j ) { return ( * ( ( float* ) ( term.param->engine_val ) ) ); }
|
||||
};
|
||||
|
||||
return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) );
|
||||
case P_TYPE_INT:
|
||||
/* Evaluates a value expression */
|
||||
float ParameterExpr::eval ( int mesh_i, int mesh_j )
|
||||
{
|
||||
switch ( term.param->type )
|
||||
{
|
||||
case P_TYPE_BOOL:
|
||||
return ( float ) ( * ( ( bool* ) ( term.param->engine_val ) ) );
|
||||
case P_TYPE_INT:
|
||||
return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) );
|
||||
case P_TYPE_DOUBLE:
|
||||
if ( term.param->matrix_flag | ( term.param->flags & P_FLAG_ALWAYS_MATRIX ) )
|
||||
{
|
||||
|
||||
/* Sanity check the matrix is there... */
|
||||
assert ( term.param->matrix != NULL );
|
||||
|
||||
return ( float ) ( * ( ( int* ) ( term.param->engine_val ) ) );
|
||||
case P_TYPE_DOUBLE:
|
||||
|
||||
|
||||
if ( term.param->matrix_flag | ( term.param->flags & P_FLAG_ALWAYS_MATRIX ) )
|
||||
/// @slow boolean check could be expensive in this critical (and common) step of evaluation
|
||||
if ( mesh_i >= 0 )
|
||||
{
|
||||
|
||||
/* Sanity check the matrix is there... */
|
||||
assert ( term.param->matrix != NULL );
|
||||
|
||||
/// @slow boolean check could be expensive in this critical (and common) step of evaluation
|
||||
if ( mesh_i >= 0 )
|
||||
if ( mesh_j >= 0 )
|
||||
{
|
||||
if ( mesh_j >= 0 )
|
||||
{
|
||||
return ( ( ( float** ) term.param->matrix ) [mesh_i][mesh_j] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( ( ( float* ) term.param->matrix ) [mesh_i] );
|
||||
}
|
||||
return ( ( ( float** ) term.param->matrix ) [mesh_i][mesh_j] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( ( ( float* ) term.param->matrix ) [mesh_i] );
|
||||
}
|
||||
//assert(mesh_i >=0);
|
||||
}
|
||||
//std::cout << term.param->name << ": " << (*((float*)term.param->engine_val)) << std::endl;
|
||||
return * ( ( float* ) ( term.param->engine_val ) );
|
||||
default:
|
||||
return EVAL_ERROR;
|
||||
}
|
||||
//assert(mesh_i >=0);
|
||||
}
|
||||
//std::cout << term.param->name << ": " << (*((float*)term.param->engine_val)) << std::endl;
|
||||
return * ( ( float* ) ( term.param->engine_val ) );
|
||||
default:
|
||||
return EVAL_ERROR;
|
||||
}
|
||||
/* Unknown type, return failure */
|
||||
return PROJECTM_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
class MultAndAddExpr : public Expr
|
||||
{
|
||||
Expr *a, *b, *c;
|
||||
public:
|
||||
MultAndAddExpr(Expr *_a, Expr *_b, Expr *_c) : Expr(OTHER),
|
||||
a(_a), b(_b), c(_c)
|
||||
{
|
||||
}
|
||||
float eval(int mesh_i, int mesh_j)
|
||||
{
|
||||
float a_value = a->eval(mesh_i,mesh_j);
|
||||
float b_value = b->eval(mesh_i,mesh_j);
|
||||
float c_value = c->eval(mesh_i,mesh_j);
|
||||
return a_value * b_value + c_value;
|
||||
}
|
||||
std::ostream &to_string(std::ostream &out)
|
||||
{
|
||||
out << "(" << a << " * " << b << ") + " << c;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream &TreeExpr::to_string(std::ostream &out)
|
||||
{
|
||||
if (NULL == infix_op)
|
||||
{
|
||||
out << gen_expr;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "(" << left << " ";
|
||||
switch ( infix_op->type )
|
||||
{
|
||||
case INFIX_ADD:
|
||||
out << "+"; break;
|
||||
case INFIX_MINUS:
|
||||
out << "-"; break;
|
||||
case INFIX_MULT:
|
||||
out << "*"; break;
|
||||
case INFIX_MOD:
|
||||
out << "%"; break;
|
||||
case INFIX_OR:
|
||||
out << "|"; break;
|
||||
case INFIX_AND:
|
||||
out << "&"; break;
|
||||
case INFIX_DIV:
|
||||
out << "/"; break;
|
||||
default:
|
||||
out << "infix_op_ERROR"; break;
|
||||
}
|
||||
out << " " << right << ")";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* NOTE: Parser.cpp directly manipulates TreeExpr, so it is easier to optimizer AFTER parsing
|
||||
* than while building up the tree initially
|
||||
*/
|
||||
Expr *TreeExpr::optimize()
|
||||
{
|
||||
if (infix_op == NULL)
|
||||
{
|
||||
Expr *opt = gen_expr->optimize();
|
||||
if (opt != gen_expr)
|
||||
delete gen_expr;
|
||||
gen_expr = NULL;
|
||||
return opt;
|
||||
}
|
||||
if (left != NULL)
|
||||
{
|
||||
Expr *l = left->optimize();
|
||||
if (l != left)
|
||||
delete left;
|
||||
left = l;
|
||||
}
|
||||
if (right != NULL)
|
||||
{
|
||||
Expr *r = right->optimize();
|
||||
if (r != right)
|
||||
delete right;
|
||||
right = r;
|
||||
}
|
||||
if (left == NULL)
|
||||
{
|
||||
Expr *opt = right;
|
||||
right = NULL;
|
||||
return opt;
|
||||
}
|
||||
if (right == NULL)
|
||||
{
|
||||
Expr *opt = left;
|
||||
left = NULL;
|
||||
return opt;
|
||||
}
|
||||
if (left->isConstant() && right->isConstant())
|
||||
return Expr::const_to_expr(eval(-1, -1));
|
||||
|
||||
// this is gratuitious, but a*b+c is super common, so as proof-of-concept, let's make a special Expr
|
||||
if (infix_op->type == INFIX_ADD &&
|
||||
((left->clazz == TREE && ((TreeExpr *)left)->infix_op->type == INFIX_MULT) ||
|
||||
(right->clazz == TREE && ((TreeExpr *)right)->infix_op->type == INFIX_MULT)))
|
||||
{
|
||||
Expr *a, *b, *c;
|
||||
if (left->clazz == TREE && ((TreeExpr *)left)->infix_op->type == INFIX_MULT)
|
||||
{
|
||||
a = ((TreeExpr *)left)->left;
|
||||
b = ((TreeExpr *)left)->right;
|
||||
c = right;
|
||||
((TreeExpr *)left)->left = NULL;
|
||||
((TreeExpr *)left)->right = NULL;
|
||||
right = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = ((TreeExpr *)right)->left;
|
||||
b = ((TreeExpr *)right)->right;
|
||||
c = left;
|
||||
((TreeExpr *)right)->left = NULL;
|
||||
((TreeExpr *)right)->right = NULL;
|
||||
left = NULL;
|
||||
}
|
||||
return new MultAndAddExpr(a,b,c);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/* Evaluates an expression tree */
|
||||
float TreeExpr::eval_tree_expr ( int mesh_i, int mesh_j )
|
||||
float TreeExpr::eval ( int mesh_i, int mesh_j )
|
||||
{
|
||||
|
||||
float left_arg, right_arg;
|
||||
|
||||
/* A leaf node, evaluate the general expression. If the expression is null as well, return zero */
|
||||
if ( infix_op == NULL )
|
||||
{
|
||||
if ( gen_expr == NULL )
|
||||
return 0;
|
||||
else
|
||||
return gen_expr->eval_gen_expr ( mesh_i, mesh_j );
|
||||
}
|
||||
|
||||
/* Otherwise, this node is an infix operator. Evaluate
|
||||
accordingly */
|
||||
|
||||
/* Safe guard in case the user gave a partially written expression */
|
||||
if (left == NULL) {
|
||||
if (infix_op == Eval::infix_mult)
|
||||
left_arg = 1;
|
||||
else
|
||||
left_arg = 0;
|
||||
}
|
||||
else
|
||||
left_arg = left->eval_tree_expr ( mesh_i, mesh_j );
|
||||
|
||||
/* Safe guard in case the user gave a partially written expression */
|
||||
if (right == NULL) {
|
||||
if (infix_op == Eval::infix_mult)
|
||||
right_arg = 1;
|
||||
else
|
||||
right_arg = 0;
|
||||
}
|
||||
else
|
||||
right_arg = right->eval_tree_expr ( mesh_i, mesh_j );
|
||||
/* shouldn't be null if we've called optimize() */
|
||||
assert(NULL != infix_op);
|
||||
|
||||
left_arg = left->eval ( mesh_i, mesh_j );
|
||||
right_arg = right->eval ( mesh_i, mesh_j );
|
||||
|
||||
switch ( infix_op->type )
|
||||
{
|
||||
@ -221,34 +338,16 @@ float TreeExpr::eval_tree_expr ( int mesh_i, int mesh_j )
|
||||
}
|
||||
|
||||
/* Converts a float value to a general expression */
|
||||
GenExpr * GenExpr::const_to_expr ( float val )
|
||||
Expr * Expr::const_to_expr ( float val )
|
||||
{
|
||||
|
||||
GenExpr * gen_expr;
|
||||
ValExpr * val_expr;
|
||||
Term term;
|
||||
|
||||
term.constant = val;
|
||||
|
||||
if ( ( val_expr = new ValExpr ( CONSTANT_TERM_T, &term ) ) == NULL )
|
||||
return NULL;
|
||||
|
||||
gen_expr = new GenExpr ( VAL_T, ( void* ) val_expr );
|
||||
|
||||
if ( gen_expr == NULL )
|
||||
{
|
||||
delete val_expr;
|
||||
}
|
||||
|
||||
return gen_expr;
|
||||
return new ConstantExpr( CONSTANT_TERM_T, &term );
|
||||
}
|
||||
|
||||
/* Converts a regular parameter to an expression */
|
||||
GenExpr * GenExpr::param_to_expr ( Param * param )
|
||||
Expr * Expr::param_to_expr ( Param * param )
|
||||
{
|
||||
|
||||
GenExpr * gen_expr = NULL;
|
||||
ValExpr * val_expr = NULL;
|
||||
Term term;
|
||||
|
||||
if ( param == NULL )
|
||||
@ -267,87 +366,93 @@ GenExpr * GenExpr::param_to_expr ( Param * param )
|
||||
making the parser handle the case where parameters are essentially per pixel equation
|
||||
substitutions */
|
||||
|
||||
|
||||
term.param = param;
|
||||
if ( ( val_expr = new ValExpr ( PARAM_TERM_T, &term ) ) == NULL )
|
||||
return NULL;
|
||||
|
||||
if ( ( gen_expr = new GenExpr ( VAL_T, ( void* ) val_expr ) ) == NULL )
|
||||
switch ( param->type )
|
||||
{
|
||||
delete val_expr;
|
||||
return NULL;
|
||||
case P_TYPE_BOOL:
|
||||
return new BoolParameterExpr( PARAM_TERM_T, &term );
|
||||
case P_TYPE_INT:
|
||||
return new IntParameterExpr( PARAM_TERM_T, &term );
|
||||
case P_TYPE_DOUBLE:
|
||||
// TODO are these flags constant??? can I check them now?
|
||||
if ( param->matrix_flag | ( param->flags & P_FLAG_ALWAYS_MATRIX ) )
|
||||
return new ParameterExpr( PARAM_TERM_T, &term );
|
||||
return new FloatParameterExpr( PARAM_TERM_T, &term );
|
||||
}
|
||||
return gen_expr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Converts a prefix function to an expression */
|
||||
GenExpr * GenExpr::prefun_to_expr ( float ( *func_ptr ) ( void * ), GenExpr ** expr_list, int num_args )
|
||||
Expr * Expr::prefun_to_expr ( float ( *func_ptr ) ( void * ), Expr ** expr_list, int num_args )
|
||||
{
|
||||
|
||||
GenExpr * gen_expr;
|
||||
PrefunExpr * prefun_expr;
|
||||
|
||||
prefun_expr = new PrefunExpr();
|
||||
|
||||
if ( prefun_expr == NULL )
|
||||
return NULL;
|
||||
|
||||
if (num_args == 1)
|
||||
prefun_expr = new PrefunExprOne();
|
||||
else
|
||||
prefun_expr = new PrefunExpr();
|
||||
prefun_expr->num_args = num_args;
|
||||
prefun_expr->func_ptr = ( float ( * ) ( void* ) ) func_ptr;
|
||||
prefun_expr->expr_list = expr_list;
|
||||
|
||||
gen_expr = new GenExpr ( PREFUN_T, ( void* ) prefun_expr );
|
||||
|
||||
if ( gen_expr == NULL )
|
||||
delete prefun_expr;
|
||||
|
||||
return gen_expr;
|
||||
return prefun_expr;
|
||||
}
|
||||
|
||||
/* Creates a new tree expression */
|
||||
TreeExpr::TreeExpr ( InfixOp * _infix_op, GenExpr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) :
|
||||
TreeExpr::TreeExpr ( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) :
|
||||
Expr( TREE ),
|
||||
infix_op ( _infix_op ), gen_expr ( _gen_expr ),
|
||||
left ( _left ), right ( _right ) {}
|
||||
|
||||
|
||||
/* Creates a new value expression */
|
||||
ValExpr::ValExpr ( int _type, Term * _term ) :type ( _type )
|
||||
class TreeExprAdd : public TreeExpr
|
||||
{
|
||||
|
||||
|
||||
//val_expr->type = _type;
|
||||
term.constant = _term->constant;
|
||||
term.param = _term->param;
|
||||
|
||||
//return val_expr;
|
||||
}
|
||||
|
||||
/* Creates a new general expression */
|
||||
|
||||
GenExpr::GenExpr ( int _type, void * _item ) :type ( _type ), item ( _item ) {}
|
||||
|
||||
/* Frees a general expression */
|
||||
GenExpr::~GenExpr()
|
||||
{
|
||||
|
||||
switch ( type )
|
||||
public:
|
||||
TreeExprAdd( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) :
|
||||
TreeExpr( _infix_op, _gen_expr, _left, _right) {}
|
||||
float eval( int mesh_i, int mesh_j)
|
||||
{
|
||||
case VAL_T:
|
||||
delete ( ( ValExpr* ) item );
|
||||
break;
|
||||
case PREFUN_T:
|
||||
delete ( ( PrefunExpr* ) item );
|
||||
break;
|
||||
case TREE_T:
|
||||
delete ( ( TreeExpr* ) item );
|
||||
break;
|
||||
return left->eval(mesh_i, mesh_j) + right->eval(mesh_i, mesh_j);
|
||||
}
|
||||
};
|
||||
|
||||
class TreeExprMinus : public TreeExpr
|
||||
{
|
||||
public:
|
||||
TreeExprMinus( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) :
|
||||
TreeExpr( _infix_op, _gen_expr, _left, _right) {}
|
||||
float eval( int mesh_i, int mesh_j)
|
||||
{
|
||||
return left->eval(mesh_i, mesh_j) - right->eval(mesh_i, mesh_j);
|
||||
}
|
||||
};
|
||||
|
||||
class TreeExprMult : public TreeExpr
|
||||
{
|
||||
public:
|
||||
TreeExprMult( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right ) :
|
||||
TreeExpr( _infix_op, _gen_expr, _left, _right) {}
|
||||
float eval( int mesh_i, int mesh_j)
|
||||
{
|
||||
return left->eval(mesh_i, mesh_j) * right->eval(mesh_i, mesh_j);
|
||||
}
|
||||
};
|
||||
|
||||
TreeExpr * TreeExpr::create( InfixOp * _infix_op, Expr * _gen_expr, TreeExpr * _left, TreeExpr * _right )
|
||||
{
|
||||
if ( NULL != _infix_op )
|
||||
{
|
||||
if ( _infix_op->type == INFIX_ADD )
|
||||
return new TreeExprAdd( _infix_op, _gen_expr, _left, _right);
|
||||
if ( _infix_op->type == INFIX_MINUS )
|
||||
return new TreeExprMinus( _infix_op, _gen_expr, _left, _right);
|
||||
if ( _infix_op->type == INFIX_MULT )
|
||||
return new TreeExprMult( _infix_op, _gen_expr, _left, _right);
|
||||
}
|
||||
return new TreeExpr( _infix_op, _gen_expr, _left, _right );
|
||||
}
|
||||
|
||||
/* Frees a function in prefix notation */
|
||||
PrefunExpr::~PrefunExpr()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
/* Free every element in expression list */
|
||||
@ -358,10 +463,6 @@ PrefunExpr::~PrefunExpr()
|
||||
free ( expr_list );
|
||||
}
|
||||
|
||||
/* Frees values of type VARIABLE and CONSTANT */
|
||||
ValExpr::~ValExpr()
|
||||
{}
|
||||
|
||||
/* Frees a tree expression */
|
||||
TreeExpr::~TreeExpr()
|
||||
{
|
||||
@ -390,13 +491,41 @@ TreeExpr::~TreeExpr()
|
||||
}
|
||||
|
||||
/* Initializes an infix operator */
|
||||
InfixOp::InfixOp ( int type, int precedence )
|
||||
InfixOp::InfixOp ( int _type, int _precedence )
|
||||
{
|
||||
|
||||
this->type = type;
|
||||
this->precedence = precedence;
|
||||
this->type = _type;
|
||||
this->precedence = _precedence;
|
||||
}
|
||||
|
||||
PrefunExpr::PrefunExpr() : Expr(FUNCTION)
|
||||
{
|
||||
}
|
||||
|
||||
Expr *PrefunExpr::optimize()
|
||||
{
|
||||
bool constant_args = true;
|
||||
for (int i=0 ; i < num_args ; i++)
|
||||
{
|
||||
Expr *orig = expr_list[i];
|
||||
expr_list[i] = orig->optimize();
|
||||
if (orig != expr_list[i])
|
||||
delete orig;
|
||||
constant_args &= expr_list[i]->isConstant();
|
||||
}
|
||||
// TODO most functions can be pre-evaluated if inputs are constant, but not all
|
||||
return this;
|
||||
}
|
||||
|
||||
PrefunExpr::PrefunExpr() {}
|
||||
std::ostream& PrefunExpr::to_string(std::ostream& out)
|
||||
{
|
||||
char comma = ' ';
|
||||
out << "<function>(";
|
||||
for (int i=0 ; i < num_args ; i++)
|
||||
{
|
||||
out << comma;
|
||||
out << expr_list[i];
|
||||
comma = ',';
|
||||
}
|
||||
out << ")";
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
#include "dlldefs.h"
|
||||
#include "CValue.hpp"
|
||||
#include <iostream>
|
||||
|
||||
class Param;
|
||||
|
||||
@ -58,65 +59,79 @@ public:
|
||||
|
||||
Term() { this->constant = 0; this->param = 0; }
|
||||
};
|
||||
|
||||
/* General Expression Type */
|
||||
class GenExpr
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
void * item;
|
||||
|
||||
~GenExpr();
|
||||
|
||||
GenExpr( int type, void *item );
|
||||
float eval_gen_expr(int mesh_i, int mesh_j);
|
||||
|
||||
static GenExpr *const_to_expr( float val );
|
||||
static GenExpr *param_to_expr( Param *param );
|
||||
static GenExpr *prefun_to_expr( float (*func_ptr)(void *), GenExpr **expr_list, int num_args );
|
||||
|
||||
enum ExprClass
|
||||
{
|
||||
TREE, CONSTANT, PARAMETER, FUNCTION, OTHER
|
||||
};
|
||||
|
||||
/* Value expression, contains a term union */
|
||||
class ValExpr
|
||||
class Expr
|
||||
{
|
||||
public:
|
||||
int type;
|
||||
Term term;
|
||||
ExprClass clazz;
|
||||
Expr(ExprClass c) : clazz(c) {};
|
||||
virtual ~Expr() {};
|
||||
virtual Expr *optimize() { return this; };
|
||||
virtual bool isConstant() { return false; };
|
||||
virtual float eval(int mesh_i, int mesh_j) = 0;
|
||||
virtual std::ostream& to_string(std::ostream &out)
|
||||
{
|
||||
std::cout << "nyi"; return out;
|
||||
}
|
||||
|
||||
~ValExpr();
|
||||
ValExpr( int type, Term *term );
|
||||
|
||||
float eval_val_expr(int mesh_i, int mesh_j);
|
||||
static Expr *const_to_expr( float val );
|
||||
static Expr *param_to_expr( Param *param );
|
||||
static Expr *prefun_to_expr( float (*func_ptr)(void *), Expr **expr_list, int num_args );
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, Expr *expr)
|
||||
{
|
||||
if (NULL == expr)
|
||||
out << "NULL";
|
||||
else
|
||||
expr->to_string(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/* A binary expression tree ordered by operator precedence */
|
||||
class TreeExpr
|
||||
class TreeExpr : public Expr
|
||||
{
|
||||
protected:
|
||||
TreeExpr( InfixOp *infix_op, Expr *gen_expr,
|
||||
TreeExpr *left, TreeExpr *right );
|
||||
public:
|
||||
static TreeExpr *create( InfixOp *infix_op, Expr *gen_expr,
|
||||
TreeExpr *left, TreeExpr *right );
|
||||
InfixOp * infix_op; /* null if leaf */
|
||||
GenExpr * gen_expr;
|
||||
TreeExpr *left, *right;
|
||||
Expr * gen_expr;
|
||||
// NOTE: before optimize() left and right will always be TreeExpr
|
||||
Expr *left, *right;
|
||||
// these are for type-safe access in Parser.cpp
|
||||
TreeExpr *&leftTree() { return *(TreeExpr **)&left; };
|
||||
TreeExpr *&rightTree() { return *(TreeExpr **)&right; };
|
||||
|
||||
~TreeExpr();
|
||||
TreeExpr( InfixOp *infix_op, GenExpr *gen_expr,
|
||||
TreeExpr *left, TreeExpr *right );
|
||||
|
||||
float eval_tree_expr(int mesh_i, int mesh_j);
|
||||
Expr *optimize();
|
||||
float eval(int mesh_i, int mesh_j);
|
||||
std::ostream& to_string(std::ostream &out);
|
||||
};
|
||||
|
||||
/* A function expression in prefix form */
|
||||
class PrefunExpr
|
||||
class PrefunExpr : public Expr
|
||||
{
|
||||
public:
|
||||
float (*func_ptr)(void*);
|
||||
int num_args;
|
||||
GenExpr **expr_list;
|
||||
Expr **expr_list;
|
||||
PrefunExpr();
|
||||
~PrefunExpr();
|
||||
|
||||
/* Evaluates functions in prefix form */
|
||||
float eval_prefun_expr(int mesh_i, int mesh_j);
|
||||
|
||||
Expr *optimize();
|
||||
float eval(int mesh_i, int mesh_j);
|
||||
std::ostream& to_string(std::ostream &out);
|
||||
};
|
||||
|
||||
#endif /** _EXPR_H */
|
||||
|
||||
@ -103,7 +103,7 @@ MilkdropPreset::~MilkdropPreset()
|
||||
/* Adds a per pixel equation according to its string name. This
|
||||
will be used only by the parser */
|
||||
|
||||
int MilkdropPreset::add_per_pixel_eqn(char * name, GenExpr * gen_expr)
|
||||
int MilkdropPreset::add_per_pixel_eqn(char * name, Expr * gen_expr)
|
||||
{
|
||||
|
||||
PerPixelEqn * per_pixel_eqn = NULL;
|
||||
|
||||
@ -95,7 +95,7 @@ public:
|
||||
|
||||
/// Used by parser
|
||||
/// @bug refactor
|
||||
int add_per_pixel_eqn( char *name, GenExpr *gen_expr );
|
||||
int add_per_pixel_eqn( char *name, Expr *gen_expr );
|
||||
|
||||
/// Accessor method to retrieve the absolute file path of the loaded MilkdropPreset
|
||||
/// \returns a file path string
|
||||
|
||||
@ -251,15 +251,15 @@ token_t Parser::parseToken(std::istream & fs, char * string)
|
||||
/* Parse input in the form of "exp, exp, exp, ...)"
|
||||
Returns a general expression list */
|
||||
|
||||
GenExpr **Parser::parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset)
|
||||
Expr **Parser::parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset)
|
||||
{
|
||||
|
||||
int i, j;
|
||||
GenExpr ** expr_list; /* List of arguments to function */
|
||||
GenExpr * gen_expr;
|
||||
Expr ** expr_list; /* List of arguments to function */
|
||||
Expr * gen_expr;
|
||||
|
||||
/* Malloc the expression list */
|
||||
expr_list = (GenExpr**)wipemalloc(sizeof(GenExpr*)*num_args);
|
||||
expr_list = (Expr**)wipemalloc(sizeof(Expr*)*num_args);
|
||||
|
||||
/* Malloc failed */
|
||||
if (expr_list == NULL)
|
||||
@ -331,7 +331,7 @@ int Parser::parse_per_pixel_eqn(std::istream & fs, MilkdropPreset * preset, cha
|
||||
|
||||
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
|
||||
|
||||
if (init_string != 0)
|
||||
@ -715,19 +715,17 @@ int Parser::parse_line(std::istream & fs, MilkdropPreset * preset)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Parses a general expression, this function is the meat of the parser */
|
||||
GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset)
|
||||
Expr * Parser::_parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset)
|
||||
{
|
||||
|
||||
int i;
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
token_t token;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
float val;
|
||||
Param * param = NULL;
|
||||
Func * func;
|
||||
GenExpr ** expr_list;
|
||||
Expr ** expr_list;
|
||||
|
||||
switch (token = parseToken(fs,string))
|
||||
{
|
||||
@ -759,7 +757,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
}
|
||||
|
||||
/* Convert function to expression */
|
||||
if ((gen_expr = GenExpr::prefun_to_expr((float (*)(void *))func->func_ptr, expr_list, func->getNumArgs())) == NULL)
|
||||
if ((gen_expr = Expr::prefun_to_expr((float (*)(void *))func->func_ptr, expr_list, func->getNumArgs())) == NULL)
|
||||
{
|
||||
if (PARSE_DEBUG) printf("parse_prefix_args: failed to convert prefix function to general expression (LINE %d) \n",
|
||||
line_count);
|
||||
@ -818,7 +816,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
if (PARSE_DEBUG) printf("parse_gen_expr: plus used as prefix (LINE %d)\n", line_count);
|
||||
|
||||
/* Treat prefix plus as implict 0 preceding operator */
|
||||
gen_expr = GenExpr::const_to_expr(0);
|
||||
gen_expr = Expr::const_to_expr(0);
|
||||
|
||||
return parse_infix_op(fs, tPositive, insert_gen_expr(gen_expr, &tree_expr), preset);
|
||||
}
|
||||
@ -829,7 +827,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
{
|
||||
|
||||
/* Use the negative infix operator, but first add an implicit zero to the operator tree */
|
||||
gen_expr = GenExpr::const_to_expr(0);
|
||||
gen_expr = Expr::const_to_expr(0);
|
||||
//return parse_gen_expr(fs, insert_gen_expr(gen_expr, &tree_expr), preset);
|
||||
return parse_infix_op(fs, tNegative, insert_gen_expr(gen_expr, &tree_expr), preset);
|
||||
}
|
||||
@ -863,7 +861,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
/* CASE 1: Check if string is a just a floating point number */
|
||||
if (string_to_float(string, &val) != PROJECTM_PARSE_ERROR)
|
||||
{
|
||||
if ((gen_expr = GenExpr::const_to_expr(val)) == NULL)
|
||||
if ((gen_expr = Expr::const_to_expr(val)) == NULL)
|
||||
{
|
||||
if (tree_expr)
|
||||
delete tree_expr;
|
||||
@ -898,7 +896,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
|
||||
|
||||
/* Convert parameter to an expression */
|
||||
if ((gen_expr = GenExpr::param_to_expr(param)) == NULL)
|
||||
if ((gen_expr = Expr::param_to_expr(param)) == NULL)
|
||||
{
|
||||
delete tree_expr;
|
||||
return NULL;
|
||||
@ -932,7 +930,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
}
|
||||
|
||||
/* Convert parameter to an expression */
|
||||
if ((gen_expr = GenExpr::param_to_expr(param)) == NULL)
|
||||
if ((gen_expr = Expr::param_to_expr(param)) == NULL)
|
||||
{
|
||||
delete tree_expr;
|
||||
return NULL;
|
||||
@ -955,7 +953,7 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
}
|
||||
|
||||
/* Convert parameter to an expression */
|
||||
if ((gen_expr = GenExpr::param_to_expr(param)) == NULL)
|
||||
if ((gen_expr = Expr::param_to_expr(param)) == NULL)
|
||||
{
|
||||
delete tree_expr;
|
||||
return NULL;
|
||||
@ -981,6 +979,17 @@ GenExpr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, Mil
|
||||
}
|
||||
|
||||
|
||||
Expr * Parser::parse_gen_expr ( std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset)
|
||||
{
|
||||
Expr *gen_expr = _parse_gen_expr( fs, tree_expr, preset );
|
||||
if (NULL == gen_expr)
|
||||
return NULL;
|
||||
//std::cout << gen_expr << std::endl;
|
||||
Expr *opt = gen_expr->optimize();
|
||||
//std::cout << opt << std::endl << std::endl;
|
||||
return opt;
|
||||
}
|
||||
|
||||
|
||||
/* Inserts expressions into tree according to operator precedence.
|
||||
If root is null, a new tree is created, with infix_op as only element */
|
||||
@ -999,7 +1008,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root)
|
||||
|
||||
if (*root == NULL)
|
||||
{
|
||||
new_root = new TreeExpr(infix_op, NULL, NULL, NULL);
|
||||
new_root = TreeExpr::create(infix_op, NULL, NULL, NULL);
|
||||
*root = new_root;
|
||||
return new_root;
|
||||
}
|
||||
@ -1009,7 +1018,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root)
|
||||
|
||||
if ((*root)->infix_op == NULL)
|
||||
{
|
||||
new_root = new TreeExpr(infix_op, NULL, *root, NULL);
|
||||
new_root = TreeExpr::create(infix_op, NULL, *root, NULL);
|
||||
(*root) = new_root;
|
||||
return new_root;
|
||||
}
|
||||
@ -1020,7 +1029,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root)
|
||||
|
||||
if (infix_op->precedence >= (*root)->infix_op->precedence)
|
||||
{
|
||||
new_root = new TreeExpr(infix_op, NULL, *root, NULL);
|
||||
new_root = TreeExpr::create(infix_op, NULL, *root, NULL);
|
||||
(*root) = new_root;
|
||||
return new_root;
|
||||
}
|
||||
@ -1035,7 +1044,7 @@ TreeExpr * Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root)
|
||||
}
|
||||
|
||||
|
||||
TreeExpr * Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root)
|
||||
TreeExpr * Parser::insert_gen_expr(Expr * gen_expr, TreeExpr ** root)
|
||||
{
|
||||
|
||||
TreeExpr * new_root;
|
||||
@ -1053,7 +1062,7 @@ TreeExpr * Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root)
|
||||
|
||||
if (*root == NULL)
|
||||
{
|
||||
new_root = new TreeExpr(NULL, gen_expr, NULL, NULL);
|
||||
new_root = TreeExpr::create(NULL, gen_expr, NULL, NULL);
|
||||
*root = new_root;
|
||||
return new_root;
|
||||
}
|
||||
@ -1067,7 +1076,7 @@ TreeExpr * Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root)
|
||||
}
|
||||
|
||||
/* A recursive helper function to insert general expression elements into the operator tree */
|
||||
int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root)
|
||||
int Parser::insert_gen_rec(Expr * gen_expr, TreeExpr * root)
|
||||
{
|
||||
|
||||
/* Trivial Case: root is null */
|
||||
@ -1085,7 +1094,7 @@ int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root)
|
||||
|
||||
if ((root->left == NULL) && (root->infix_op != NULL))
|
||||
{
|
||||
root->left = new TreeExpr(NULL, gen_expr, NULL, NULL);
|
||||
root->left = TreeExpr::create(NULL, gen_expr, NULL, NULL);
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1095,7 +1104,7 @@ int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root)
|
||||
|
||||
if ((root->right == NULL) && (root->infix_op != NULL))
|
||||
{
|
||||
root->right = new TreeExpr(NULL, gen_expr, NULL, NULL);
|
||||
root->right = TreeExpr::create(NULL, gen_expr, NULL, NULL);
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1103,8 +1112,8 @@ int Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root)
|
||||
this succeeds then return. If it fails, try
|
||||
recursing down to the right */
|
||||
|
||||
if (insert_gen_rec(gen_expr, root->left) == PROJECTM_FAILURE)
|
||||
return insert_gen_rec(gen_expr, root->right);
|
||||
if (insert_gen_rec(gen_expr, root->leftTree()) == PROJECTM_FAILURE)
|
||||
return insert_gen_rec(gen_expr, root->rightTree());
|
||||
|
||||
/* Impossible for control flow to reach here, but in
|
||||
the world of C programming, who knows... */
|
||||
@ -1131,14 +1140,14 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root)
|
||||
I don't think this will ever happen */
|
||||
if (root->left == NULL)
|
||||
{
|
||||
root->left = new TreeExpr(infix_op, NULL, root->left, NULL);
|
||||
root->left = TreeExpr::create(infix_op, NULL, root->leftTree(), NULL);
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Right tree is empty, attach this operator to it */
|
||||
if (root->right == NULL)
|
||||
{
|
||||
root->right = new TreeExpr(infix_op, NULL, root->right, NULL);
|
||||
root->right = TreeExpr::create(infix_op, NULL, root->rightTree(), NULL);
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1149,29 +1158,29 @@ int Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root)
|
||||
then insert the expression here, attaching the old right branch
|
||||
to the left of the new expression */
|
||||
|
||||
if (root->right->infix_op == NULL)
|
||||
if (root->rightTree()->infix_op == NULL)
|
||||
{
|
||||
root->right = new TreeExpr(infix_op, NULL, root->right, NULL);
|
||||
root->right = TreeExpr::create(infix_op, NULL, root->rightTree(), NULL);
|
||||
return PROJECTM_SUCCESS;
|
||||
}
|
||||
|
||||
/* Traverse deeper if the inserting operator precedence is less than the
|
||||
the root's right operator precedence */
|
||||
if (infix_op->precedence < root->right->infix_op->precedence)
|
||||
return insert_infix_rec(infix_op, root->right);
|
||||
if (infix_op->precedence < root->rightTree()->infix_op->precedence)
|
||||
return insert_infix_rec(infix_op, root->rightTree());
|
||||
|
||||
/* Otherwise, insert the operator here */
|
||||
|
||||
root->right = new TreeExpr(infix_op, NULL, root->right, NULL);
|
||||
root->right = TreeExpr::create(infix_op, NULL, root->rightTree(), NULL);
|
||||
return PROJECTM_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/* Parses an infix operator */
|
||||
GenExpr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset)
|
||||
Expr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset)
|
||||
{
|
||||
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
|
||||
switch (token)
|
||||
{
|
||||
@ -1212,7 +1221,7 @@ GenExpr * Parser::parse_infix_op(std::istream & fs, token_t token, TreeExpr * t
|
||||
case tRPr:
|
||||
case tComma:
|
||||
if (PARSE_DEBUG) printf("parse_infix_op: terminal found (LINE %d)\n", line_count);
|
||||
gen_expr = new GenExpr(TREE_T, (void*)tree_expr);
|
||||
gen_expr = tree_expr;
|
||||
assert(gen_expr);
|
||||
return gen_expr;
|
||||
default:
|
||||
@ -1358,7 +1367,7 @@ PerFrameEqn * Parser::parse_per_frame_eqn(std::istream & fs, int index, Milkdro
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
Param * param;
|
||||
PerFrameEqn * per_frame_eqn;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
|
||||
|
||||
if (parseToken(fs, string) != tEq)
|
||||
@ -1408,7 +1417,7 @@ PerFrameEqn * Parser::parse_implicit_per_frame_eqn(std::istream & fs, char * pa
|
||||
|
||||
Param * param;
|
||||
PerFrameEqn * per_frame_eqn;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
|
||||
if (fs.fail())
|
||||
return NULL;
|
||||
@ -1558,7 +1567,7 @@ InitCond * Parser::parse_per_frame_init_eqn(std::istream & fs, MilkdropPreset *
|
||||
Param * param = NULL;
|
||||
CValue init_val;
|
||||
InitCond * init_cond;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
float val;
|
||||
token_t token;
|
||||
|
||||
@ -1604,7 +1613,7 @@ InitCond * Parser::parse_per_frame_init_eqn(std::istream & fs, MilkdropPreset *
|
||||
}
|
||||
|
||||
/* Compute initial condition value */
|
||||
val = gen_expr->eval_gen_expr(-1,-1);
|
||||
val = gen_expr->eval(-1,-1);
|
||||
|
||||
/* Free the general expression now that we are done with it */
|
||||
delete gen_expr;
|
||||
@ -2192,7 +2201,7 @@ int Parser::parse_wave_helper(std::istream & fs, MilkdropPreset * preset, int
|
||||
{
|
||||
|
||||
Param * param;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
PerFrameEqn * per_frame_eqn;
|
||||
CustomWave * custom_wave;
|
||||
@ -2458,7 +2467,7 @@ int Parser::parse_shape_per_frame_eqn(std::istream & fs, CustomShape * custom_sh
|
||||
{
|
||||
|
||||
Param * param;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
PerFrameEqn * per_frame_eqn;
|
||||
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
@ -2520,7 +2529,7 @@ int Parser::parse_wave_per_frame_eqn(std::istream & fs, CustomWave * custom_wav
|
||||
{
|
||||
|
||||
Param * param;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
PerFrameEqn * per_frame_eqn;
|
||||
|
||||
char string[MAX_TOKEN_SIZE];
|
||||
|
||||
@ -122,7 +122,7 @@ typedef enum {
|
||||
|
||||
class CustomShape;
|
||||
class CustomWave;
|
||||
class GenExpr;
|
||||
class Expr;
|
||||
class InfixOp;
|
||||
class PerFrameEqn;
|
||||
class MilkdropPreset;
|
||||
@ -155,17 +155,17 @@ public:
|
||||
static int parse_line( std::istream & fs, MilkdropPreset * preset );
|
||||
|
||||
static int get_string_prefix_len(char * string);
|
||||
static TreeExpr * insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root);
|
||||
static TreeExpr * insert_gen_expr(Expr * gen_expr, TreeExpr ** root);
|
||||
static TreeExpr * insert_infix_op(InfixOp * infix_op, TreeExpr ** root);
|
||||
static token_t parseToken(std::istream & fs, char * string);
|
||||
static GenExpr ** parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset);
|
||||
static GenExpr * parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset);
|
||||
static GenExpr * parse_sign_arg(std::istream & fs);
|
||||
static Expr ** parse_prefix_args(std::istream & fs, int num_args, MilkdropPreset * preset);
|
||||
static Expr * parse_infix_op(std::istream & fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset);
|
||||
static Expr * parse_sign_arg(std::istream & fs);
|
||||
static int parse_float(std::istream & fs, float * float_ptr);
|
||||
static int parse_int(std::istream & fs, int * int_ptr);
|
||||
static int insert_gen_rec(GenExpr * gen_expr, TreeExpr * root);
|
||||
static int insert_gen_rec(Expr * gen_expr, TreeExpr * root);
|
||||
static int insert_infix_rec(InfixOp * infix_op, TreeExpr * root);
|
||||
static GenExpr * parse_gen_expr(std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset);
|
||||
static Expr * parse_gen_expr(std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset);
|
||||
static PerFrameEqn * parse_implicit_per_frame_eqn(std::istream & fs, char * param_string, int index, MilkdropPreset * preset);
|
||||
static InitCond * parse_per_frame_init_eqn(std::istream & fs, MilkdropPreset * preset, std::map<std::string,Param*> * database);
|
||||
static int parse_wavecode_prefix(char * token, int * id, char ** var_string);
|
||||
@ -186,6 +186,8 @@ public:
|
||||
static int parse_shape_per_frame_eqn(std::istream & fs, CustomShape * custom_shape, MilkdropPreset * preset);
|
||||
static int parse_wave_per_frame_eqn(std::istream & fs, CustomWave * custom_wave, MilkdropPreset * preset);
|
||||
static bool wrapsToNextLine(const std::string & str);
|
||||
private:
|
||||
static Expr * _parse_gen_expr(std::istream & fs, TreeExpr * tree_expr, MilkdropPreset * preset);
|
||||
};
|
||||
|
||||
#endif /** !_PARSER_H */
|
||||
|
||||
@ -43,10 +43,10 @@ void PerFrameEqn::evaluate() {
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
//*((float*)per_frame_eqn->param->engine_val) = eval_gen_expr(per_frame_eqn->gen_expr);
|
||||
//*((float*)per_frame_eqn->param->engine_val) = eval(per_frame_eqn->gen_expr);
|
||||
assert(gen_expr);
|
||||
assert(param);
|
||||
param->set_param(gen_expr->eval_gen_expr(-1,-1));
|
||||
param->set_param(gen_expr->eval(-1,-1));
|
||||
|
||||
if (PER_FRAME_EQN_DEBUG) printf(" = %.4f\n", *((float*)param->engine_val));
|
||||
|
||||
@ -63,5 +63,5 @@ PerFrameEqn::~PerFrameEqn() {
|
||||
}
|
||||
|
||||
/* Create a new per frame equation */
|
||||
PerFrameEqn::PerFrameEqn(int _index, Param * _param, GenExpr * _gen_expr) :
|
||||
PerFrameEqn::PerFrameEqn(int _index, Param * _param, Expr * _gen_expr) :
|
||||
index(_index), param(_param), gen_expr(_gen_expr) {}
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
|
||||
#define PER_FRAME_EQN_DEBUG 0
|
||||
|
||||
class GenExpr;
|
||||
class Expr;
|
||||
class Param;
|
||||
class PerFrameEqn;
|
||||
|
||||
@ -39,9 +39,9 @@ class PerFrameEqn {
|
||||
public:
|
||||
int index; /* a unique id for each per frame eqn (generated by order in preset files) */
|
||||
Param *param; /* parameter to be assigned a value */
|
||||
GenExpr *gen_expr; /* expression that paremeter is equal to */
|
||||
Expr *gen_expr; /* expression that paremeter is equal to */
|
||||
|
||||
PerFrameEqn(int index, Param * param, GenExpr * gen_expr);
|
||||
PerFrameEqn(int index, Param * param, Expr * gen_expr);
|
||||
~PerFrameEqn();
|
||||
|
||||
/// Evaluate the per frame equation
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
/* Evaluates a per pixel equation */
|
||||
void PerPixelEqn::evaluate(int mesh_i, int mesh_j) {
|
||||
|
||||
GenExpr * eqn_ptr = 0;
|
||||
Expr * eqn_ptr = 0;
|
||||
|
||||
|
||||
eqn_ptr = this->gen_expr;
|
||||
@ -47,13 +47,13 @@ void PerPixelEqn::evaluate(int mesh_i, int mesh_j) {
|
||||
|
||||
if (param_matrix == 0) {
|
||||
assert(param->engine_val);
|
||||
(*(float*)param->engine_val) = eqn_ptr->eval_gen_expr(mesh_i, mesh_j);
|
||||
(*(float*)param->engine_val) = eqn_ptr->eval(mesh_i, mesh_j);
|
||||
|
||||
} else {
|
||||
|
||||
assert(!(eqn_ptr == NULL || param_matrix == NULL));
|
||||
|
||||
param_matrix[mesh_i][mesh_j] = eqn_ptr->eval_gen_expr(mesh_i, mesh_j);
|
||||
param_matrix[mesh_i][mesh_j] = eqn_ptr->eval(mesh_i, mesh_j);
|
||||
|
||||
/* Now that this parameter has been referenced with a per
|
||||
pixel equation, we let the evaluator know by setting
|
||||
@ -64,7 +64,7 @@ void PerPixelEqn::evaluate(int mesh_i, int mesh_j) {
|
||||
}
|
||||
}
|
||||
|
||||
PerPixelEqn::PerPixelEqn(int _index, Param * _param, GenExpr * _gen_expr):index(_index), param(_param), gen_expr(_gen_expr) {
|
||||
PerPixelEqn::PerPixelEqn(int _index, Param * _param, Expr * _gen_expr):index(_index), param(_param), gen_expr(_gen_expr) {
|
||||
|
||||
assert(index >= 0);
|
||||
assert(param != 0);
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
#define WARP_OP 9
|
||||
#define NUM_OPS 10 /* obviously, this number is dependent on the number of existing per pixel operations */
|
||||
|
||||
class GenExpr;
|
||||
class Expr;
|
||||
class Param;
|
||||
class PerPixelEqn;
|
||||
class Preset;
|
||||
@ -53,13 +53,13 @@ public:
|
||||
int index; /* used for splay tree ordering. */
|
||||
int flags; /* primarily to specify if this variable is user-defined */
|
||||
Param *param;
|
||||
GenExpr *gen_expr;
|
||||
Expr *gen_expr;
|
||||
|
||||
void evalPerPixelEqns( Preset *preset );
|
||||
void evaluate(int mesh_i, int mesh_j);
|
||||
virtual ~PerPixelEqn();
|
||||
|
||||
PerPixelEqn(int index, Param * param, GenExpr * gen_expr);
|
||||
PerPixelEqn(int index, Param * param, Expr * gen_expr);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ void PerPointEqn::evaluate(int i)
|
||||
{
|
||||
|
||||
float * param_matrix;
|
||||
GenExpr * eqn_ptr;
|
||||
Expr * eqn_ptr;
|
||||
|
||||
// samples = CustomWave::interface_wave->samples;
|
||||
|
||||
@ -51,8 +51,7 @@ void PerPointEqn::evaluate(int i)
|
||||
if (param->matrix == NULL)
|
||||
{
|
||||
assert(param->matrix_flag == false);
|
||||
(*(float*)param->engine_val) = eqn_ptr->eval_gen_expr(i,-1);
|
||||
|
||||
(*(float*)param->engine_val) = eqn_ptr->eval(i,-1);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -62,7 +61,7 @@ void PerPointEqn::evaluate(int i)
|
||||
param_matrix = (float*)param->matrix;
|
||||
|
||||
// -1 is because per points only use one dimension
|
||||
param_matrix[i] = eqn_ptr->eval_gen_expr(i, -1);
|
||||
param_matrix[i] = eqn_ptr->eval(i, -1);
|
||||
|
||||
|
||||
/* Now that this parameter has been referenced with a per
|
||||
@ -76,7 +75,7 @@ void PerPointEqn::evaluate(int i)
|
||||
|
||||
}
|
||||
|
||||
PerPointEqn::PerPointEqn(int _index, Param * _param, GenExpr * _gen_expr, int _samples):
|
||||
PerPointEqn::PerPointEqn(int _index, Param * _param, Expr * _gen_expr, int _samples):
|
||||
index(_index),
|
||||
samples(_samples),
|
||||
param(_param),
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
#define _PER_POINT_EQN_H
|
||||
|
||||
class CustomWave;
|
||||
class GenExpr;
|
||||
class Expr;
|
||||
class Param;
|
||||
class PerPointEqn;
|
||||
|
||||
@ -39,10 +39,10 @@ public:
|
||||
int index;
|
||||
int samples; // the number of samples to iterate over
|
||||
Param *param;
|
||||
GenExpr * gen_expr;
|
||||
Expr * gen_expr;
|
||||
~PerPointEqn();
|
||||
void evaluate(int i);
|
||||
PerPointEqn( int index, Param *param, GenExpr *gen_expr, int samples);
|
||||
PerPointEqn( int index, Param *param, Expr *gen_expr, int samples);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=@CMAKE_INSTALL_PREFIX@
|
||||
libdir=@LIB_INSTALL_DIR@
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/include
|
||||
pkgdatadir=@CMAKE_INSTALL_PREFIX@/@RESOURCE_PREFIX@
|
||||
sysconfdir=@CMAKE_INSTALL_PREFIX@/@RESOURCE_PREFIX@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
pkgdatadir=@datadir@/@PACKAGE_NAME@
|
||||
sysconfdir=@datadir@/@PACKAGE_NAME@
|
||||
|
||||
Name: libprojectM
|
||||
Version: @PROJECTM_VERSION@
|
||||
Version: @PACKAGE_VERSION@
|
||||
Description: projectM - OpenGL Milkdrop
|
||||
Requires:
|
||||
Libs: -L${libdir} -lprojectM
|
||||
|
||||
@ -107,6 +107,7 @@ int main(int argc, char *argv[]) {
|
||||
last_time = SDL_GetTicks();
|
||||
}
|
||||
|
||||
app->endAudioCapture();
|
||||
delete app;
|
||||
|
||||
return PROJECTM_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user