diff --git a/src/projectM-engine/CustomShape.cpp b/src/projectM-engine/CustomShape.cpp index 1731bf142..79864dde0 100755 --- a/src/projectM-engine/CustomShape.cpp +++ b/src/projectM-engine/CustomShape.cpp @@ -37,7 +37,7 @@ #include "wipemalloc.h" -CustomShape *CustomShape::interface_shape = NULL; + void eval_custom_shape_init_conds(CustomShape * custom_shape); void load_unspec_init_cond_shape(Param * param); @@ -254,40 +254,6 @@ CustomShape::~CustomShape() { } -CustomShape * CustomShape::find_custom_shape(int id, Preset * preset, int create_flag) { - - CustomShape * custom_shape = NULL; - - if (preset == NULL) - return NULL; - - if ((custom_shape = (CustomShape*)preset->custom_shape_tree->splay_find(&id)) == NULL) { - - if (CUSTOM_SHAPE_DEBUG) { printf("find_custom_shape: creating custom shape (id = %d)...", id);fflush(stdout);} - - if (create_flag == FALSE) { - if (CUSTOM_SHAPE_DEBUG) printf("you specified not to (create flag = false), returning null\n"); - return NULL; - } - - if ((custom_shape = new CustomShape(id)) == NULL) { - if (CUSTOM_SHAPE_DEBUG) printf("failed...out of memory?\n"); - return NULL; - } - - if (CUSTOM_SHAPE_DEBUG) { printf("success.Inserting..."); fflush(stdout);} - - if (preset->custom_shape_tree->splay_insert(custom_shape, &custom_shape->id) < 0) { - if (CUSTOM_SHAPE_DEBUG) printf("failed, probably a duplicated!!\n"); - delete custom_shape; - return NULL; - } - - if (CUSTOM_SHAPE_DEBUG) printf("done.\n"); - } - - return custom_shape; -} void CustomShape::load_custom_shape_init() { load_unspecified_init_conds_shape(); @@ -300,9 +266,10 @@ void CustomShape::eval_custom_shape_init_conds() { void CustomShape::load_unspecified_init_conds_shape() { param_tree->splay_traverse((void (*)(void*))load_unspec_init_cond_shape_helper); - interface_shape = NULL; + } +/// @bug BROKEN: FIX ME (carm) void CustomShape::load_unspec_init_cond_shape() { abort(); #if 0 diff --git a/src/projectM-engine/CustomShape.h b/src/projectM-engine/CustomShape.h index 73cebfe05..d7c4a0555 100755 --- a/src/projectM-engine/CustomShape.h +++ b/src/projectM-engine/CustomShape.h @@ -40,10 +40,6 @@ public: int id; int per_frame_count; - /** Shape currently being processed */ - static CustomShape *interface_shape; - static int cwave_interface_id; - /* Parameter tree associated with this custom shape */ SplayTree * param_tree; @@ -106,7 +102,7 @@ public: int checkTrees(); /** Checks all internal trees are built correctly */ - static CustomShape *find_custom_shape(int id, Preset * preset, int create_flag ); + void evalCustomShapeInitConditions( Preset *preset ); void load_custom_shape_init(); void load_unspecified_init_conds_shape(); diff --git a/src/projectM-engine/InitCond.cpp b/src/projectM-engine/InitCond.cpp index e90663bdc..426ca2a7e 100755 --- a/src/projectM-engine/InitCond.cpp +++ b/src/projectM-engine/InitCond.cpp @@ -117,7 +117,7 @@ void InitCond::init_cond_to_string() { break; default: return; - } + } /* Compute the length of the string */ string_length = strlen(string); diff --git a/src/projectM-engine/Parser.cpp b/src/projectM-engine/Parser.cpp index 1985ba35f..f16c35e84 100755 --- a/src/projectM-engine/Parser.cpp +++ b/src/projectM-engine/Parser.cpp @@ -203,8 +203,8 @@ int Parser::parse_top_comment(FILE * fs) { } /* Done, return success */ - return PROJECTM_SUCCESS; -} + return PROJECTM_SUCCESS; +} /* Right Bracket is parsed by this function. puts a new string into name */ @@ -431,8 +431,8 @@ int Parser::parse_line(FILE * fs, Preset * preset) { if (parse_per_pixel_eqn(fs, preset, 0) < 0) return PROJECTM_PARSE_ERROR; - - + + if (update_string_buffer(preset->per_pixel_eqn_string_buffer, &preset->per_pixel_eqn_string_index) < 0) return PROJECTM_FAILURE; @@ -458,12 +458,12 @@ int Parser::parse_line(FILE * fs, Preset * preset) { Note added by Carmelo Piccione (cep@andrew.cmu.edu) 10/19/03 */ - + /* Per frame line mode previously, try to parse the equation implicitly */ if (line_mode == PER_FRAME_LINE_MODE) { if ((per_frame_eqn = parse_implicit_per_frame_eqn(fs, eqn_string, ++per_frame_eqn_count, preset)) == NULL) return PROJECTM_PARSE_ERROR; - + /* Insert the equation in the per frame equation tree */ if (preset->per_frame_eqn_tree->splay_insert(per_frame_eqn, &per_frame_eqn_count) < 0) { if (PARSE_DEBUG) printf("parse_line: failed to add a perframe equation (ERROR)\n"); @@ -481,7 +481,7 @@ int Parser::parse_line(FILE * fs, Preset * preset) { if (PARSE_DEBUG) printf("parse_line: parsing impliict per frame init eqn)\n"); if ((init_cond = parse_per_frame_init_eqn(fs, preset, NULL)) == NULL) return PROJECTM_PARSE_ERROR; - + ++per_frame_init_eqn_count; /* Insert the equation in the per frame equation tree */ @@ -506,23 +506,22 @@ int Parser::parse_line(FILE * fs, Preset * preset) { if (PARSE_DEBUG) printf("parse_line: implicit cwave ppoint eqn found (LINE %d)\n", line_count); //int len = strlen(eqn_string); - - + if (parse_wave_helper(fs, preset, last_custom_wave_id, last_eqn_type, eqn_string) < 0) { if (PARSE_DEBUG) printf("parse_line: failed to parse an implicit custom wave per point eqn\n"); return PROJECTM_FAILURE; } return PROJECTM_SUCCESS; } else if (line_mode == CUSTOM_WAVE_PER_FRAME_LINE_MODE) { + //Added by PJS. I hope I did it right CustomWave * custom_wave; - + /* Retrieve custom shape associated with this id */ if ((custom_wave = CustomWave::find_custom_wave(last_custom_wave_id, preset, TRUE)) == NULL) return PROJECTM_FAILURE; return parse_wave_per_frame_eqn(fs, custom_wave, preset); - - + } else if (line_mode == CUSTOM_WAVE_WAVECODE_LINE_MODE) { if (PARSE_DEBUG) printf("unsupported line mode: CUSTOM_WAVE_WAVECODE_LINE_MODE\n"); return PROJECTM_FAILURE; @@ -534,29 +533,30 @@ int Parser::parse_line(FILE * fs, Preset * preset) { CustomShape * custom_shape; /* Retrieve custom shape associated with this id */ - if ((custom_shape = CustomShape::find_custom_shape(last_custom_shape_id, preset, TRUE)) == NULL) + if ((custom_shape = preset->find_custom_shape(last_custom_shape_id, TRUE)) == NULL) return PROJECTM_FAILURE; + return parse_shape_per_frame_eqn(fs, custom_shape, preset); + } else if (line_mode == CUSTOM_SHAPE_PER_FRAME_INIT_LINE_MODE) { CustomShape * custom_shape; /* Retrieve custom shape associated with this id */ - if ((custom_shape = CustomShape::find_custom_shape(last_custom_shape_id, preset, TRUE)) == NULL) + if ((custom_shape = preset->find_custom_shape(last_custom_shape_id, TRUE)) == NULL) return PROJECTM_FAILURE; return parse_shape_per_frame_init_eqn(fs, custom_shape, preset); } - + //if (PARSE_DEBUG) printf("parse_line: found initial condition: name = \"%s\" (LINE %d)\n", eqn_string, line_count); - /* Evaluate the initial condition */ if ((init_cond = parse_init_cond(fs, eqn_string, preset)) == NULL) { if (PARSE_DEBUG) printf("parse_line: failed to parse initial condition (LINE %d)\n", line_count); return PROJECTM_PARSE_ERROR; - } - + } + /* Add equation to initial condition tree */ if (preset->init_cond_tree->splay_insert(init_cond, init_cond->param->name) < 0) { if (PARSE_DEBUG) printf("parse_line: failed to add initial condition \"%s\" to equation tree (LINE %d)\n", @@ -564,20 +564,19 @@ int Parser::parse_line(FILE * fs, Preset * preset) { delete init_cond; return PROJECTM_FAILURE; } - + /* Finished with initial condition line */ // if (PARSE_DEBUG) printf("parse_line: initial condition parsed successfully\n"); - + return PROJECTM_SUCCESS; - + /* END INITIAL CONDITIONING PARSING */ - - + default: /* an uncaught type or an error has occurred */ if (PARSE_DEBUG) printf("parse_line: uncaught case, token val = %d\n", token); return PROJECTM_PARSE_ERROR; } - + /* Because of the default in the case statement, control flow should never actually reach here */ return PROJECTM_PARSE_ERROR; @@ -1102,7 +1101,7 @@ int Parser::string_to_float(char * string, float * float_ptr) { error_ptr = NULL; return PROJECTM_SUCCESS; } - + (*float_ptr) = 0; free(error_ptr); error_ptr = NULL; @@ -1155,14 +1154,12 @@ int Parser::parse_float(FILE * fs, float * float_ptr) { free(error_ptr); error_ptr = NULL; return PROJECTM_PARSE_ERROR; - - } /* Parses a per frame equation. That is, interprets a stream of data as a per frame equation */ PerFrameEqn * Parser::parse_per_frame_eqn(FILE * fs, int index, Preset * preset) { - + char string[MAX_TOKEN_SIZE]; Param * param; PerFrameEqn * per_frame_eqn; @@ -1183,34 +1180,34 @@ PerFrameEqn * Parser::parse_per_frame_eqn(FILE * fs, int index, Preset * preset) //if (PARSE_DEBUG) printf("parse_per_frame_eqn: parameter %s is marked as read only (LINE %d)\n", param->name, line_count); return NULL; } - + /* Parse right side of equation as an expression */ if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) { //if (PARSE_DEBUG) printf("parse_per_frame_eqn: equation evaluated to null (LINE %d)\n", line_count); return NULL; } - + //if (PARSE_DEBUG) printf("parse_per_frame_eqn: finished per frame equation evaluation (LINE %d)\n", line_count); - + /* Create a new per frame equation */ if ((per_frame_eqn = PerFrameEqn::new_per_frame_eqn(index, param, gen_expr)) == NULL) { //if (PARSE_DEBUG) printf("parse_per_frame_eqn: failed to create a new per frame eqn, out of memory?\n"); delete gen_expr; return NULL; } - + //if (PARSE_DEBUG) printf("parse_per_frame_eqn: per_frame eqn parsed succesfully\n"); - + return per_frame_eqn; } /* Parses an 'implicit' per frame equation. That is, interprets a stream of data as a per frame equation without a prefix */ PerFrameEqn * Parser::parse_implicit_per_frame_eqn(FILE * fs, char * param_string, int index, Preset * preset) { - + Param * param; PerFrameEqn * per_frame_eqn; GenExpr * gen_expr; - + if (fs == NULL) return NULL; if (param_string == NULL) @@ -1223,7 +1220,7 @@ PerFrameEqn * Parser::parse_implicit_per_frame_eqn(FILE * fs, char * param_strin if ((param = Param::find_param(param_string, preset, P_CREATE)) == NULL) { return NULL; } - + //printf("parse_implicit_per_frame_eqn: param is %s\n", param->name); /* Make sure parameter is writable */ @@ -1231,15 +1228,15 @@ PerFrameEqn * Parser::parse_implicit_per_frame_eqn(FILE * fs, char * param_strin //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: parameter %s is marked as read only (LINE %d)\n", param->name, line_count); return NULL; } - + /* Parse right side of equation as an expression */ if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL) { //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: equation evaluated to null (LINE %d)\n", line_count); return NULL; } - + //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: finished per frame equation evaluation (LINE %d)\n", line_count); - + /* Create a new per frame equation */ if ((per_frame_eqn = PerFrameEqn::new_per_frame_eqn(index, param, gen_expr)) == NULL) { //if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: failed to create a new per frame eqn, out of memory?\n"); @@ -1441,7 +1438,7 @@ int Parser::parse_wavecode(char * token, FILE * fs, Preset * preset) { return PROJECTM_PARSE_ERROR; } } - + /* float value */ else if (param->type == P_TYPE_DOUBLE) { if ((parse_float(fs, (float*)&init_val.float_val)) == PROJECTM_PARSE_ERROR) { @@ -1449,7 +1446,7 @@ int Parser::parse_wavecode(char * token, FILE * fs, Preset * preset) { return PROJECTM_PARSE_ERROR; } } - + /* Unknown value */ else { //if (PARSE_DEBUG) printf("parse_wavecode: unknown parameter type!\n"); @@ -1491,18 +1488,19 @@ int Parser::parse_shapecode(char * token, FILE * fs, Preset * preset) { return PROJECTM_FAILURE; /* token should be in the form shapecode_N_var, such as shapecode_1_samples */ - + /* Get id and variable name from token string */ if (parse_shapecode_prefix(token, &id, &var_string) < 0) return PROJECTM_PARSE_ERROR; - + last_custom_shape_id = id; - + //if (PARSE_DEBUG) printf("parse_shapecode: shapecode id = %d, parameter = \"%s\"\n", id, var_string); /* Retrieve custom shape information from preset. The 3rd argument if true creates a custom shape if one does not exist */ - if ((custom_shape = CustomShape::find_custom_shape(id, preset, TRUE)) == NULL) { + + if ((custom_shape = preset->find_custom_shape(id, TRUE)) == NULL) { //if (PARSE_DEBUG) printf("parse_shapecode: failed to load (or create) custom shape (id = %d)!\n", id); return PROJECTM_FAILURE; } @@ -1530,7 +1528,7 @@ int Parser::parse_shapecode(char * token, FILE * fs, Preset * preset) { return PROJECTM_PARSE_ERROR; } } - + /* Unknown value */ else { //if (PARSE_DEBUG) printf("parse_shapecode: unknown parameter type!\n"); @@ -1904,7 +1902,7 @@ int Parser::parse_wave_helper(FILE * fs, Preset * preset, int id, char * eqn_ty /* Parses custom shape equations */ int Parser::parse_shape(char * token, FILE * fs, Preset * preset) { - + int id; char * eqn_type; char string[MAX_TOKEN_SIZE]; @@ -1926,7 +1924,7 @@ int Parser::parse_shape(char * token, FILE * fs, Preset * preset) { } /* Retrieve custom shape associated with this id */ - if ((custom_shape = CustomShape::find_custom_shape(id, preset, TRUE)) == NULL) + if ((custom_shape = preset->find_custom_shape(id, TRUE)) == NULL) return PROJECTM_FAILURE; @@ -2000,14 +1998,13 @@ int Parser::update_string_buffer(char * buffer, int * index) { */ int Parser::get_string_prefix_len(char * string) { - + int i = 0; /* Null argument check */ if (string == NULL) return PROJECTM_FAILURE; - /* First find the equal sign */ while (string[i] != '=') { if (string[i] == 0) @@ -2044,8 +2041,8 @@ int Parser::parse_shape_per_frame_init_eqn(FILE * fs, CustomShape * custom_shape if ((init_cond = parse_per_frame_init_eqn(fs, preset, custom_shape->param_tree)) == NULL) { //if (PARSE_DEBUG) printf("parse_shape (per frame init): equation parsing failed (LINE %d)\n", line_count); return PROJECTM_PARSE_ERROR; - } - + } + /* Insert the equation in the per frame equation tree */ if (custom_shape->per_frame_init_eqn_tree->splay_insert(init_cond, init_cond->param->name) < 0) { //if (PARSE_DEBUG) printf("parse_shape (per frame init): failed to add equation (ERROR)\n"); @@ -2101,7 +2098,7 @@ char string[MAX_TOKEN_SIZE]; current_shape = NULL; //if (PARSE_DEBUG) printf("parse_shape (per_frame): [finished parsing equation] (LINE %d)\n", line_count); - + /* Create a new per frame equation */ if ((per_frame_eqn = PerFrameEqn::new_per_frame_eqn(custom_shape->per_frame_count++, param, gen_expr)) == NULL) { //if (PARSE_DEBUG) printf("parse_shape (per_frame): failed to create a new per frame eqn, out of memory?\n"); @@ -2113,14 +2110,14 @@ char string[MAX_TOKEN_SIZE]; delete per_frame_eqn; return PROJECTM_FAILURE; } - + //if (PARSE_DEBUG) printf("parse_shape (per_frame): equation %d associated with custom shape %d [success]\n", // per_frame_eqn->index, custom_shape->id); - + /* Need to add stuff to string buffer so the editor can read the equations. Why not make a nice little helper function for this? - here it is: */ - + if (update_string_buffer(custom_shape->per_frame_eqn_string_buffer, &custom_shape->per_frame_eqn_string_index) < 0) return PROJECTM_FAILURE; diff --git a/src/projectM-engine/PerFrameEqn.h b/src/projectM-engine/PerFrameEqn.h index c1a34350f..ea591f1e3 100755 --- a/src/projectM-engine/PerFrameEqn.h +++ b/src/projectM-engine/PerFrameEqn.h @@ -40,7 +40,7 @@ public: int index; Param *param; /* parameter to be assigned a value */ GenExpr *gen_expr; /* expression that paremeter is equal to */ - + ~PerFrameEqn(); static PerFrameEqn * new_per_frame_eqn(int index, Param *param, GenExpr * gen_expr); void eval_per_frame_eqn(); diff --git a/src/projectM-engine/Preset.cpp b/src/projectM-engine/Preset.cpp index d2a864bb8..44392a2d3 100755 --- a/src/projectM-engine/Preset.cpp +++ b/src/projectM-engine/Preset.cpp @@ -85,6 +85,25 @@ void Preset::evalCustomWaveInitConditions() { custom_wave_tree->splay_traverse( eval_custom_wave_init_conds_helper ); } + +void Preset::evalCustomWavePerFrameEquations() { + + for (cwave_container::iterator pos = customWaves.begin(); pos != customWaves.end(); ++pos) { + (*pos)->init_cond_tree->splay_traverse((void (*)(void*))eval_init_cond_helper); + (*pos)->per_frame_eqn_tree->splay_traverse((void (*)(void*))eval_per_frame_eqn_helper); + } + +} + +void Preset::evalCustomShapePerFrameEquations() { + + for (cshape_container::iterator pos = customShapes.begin(); pos != customShapes.end(); ++pos) { + (*pos)->init_cond_tree->splay_traverse((void (*)(void*))eval_init_cond_helper); + (*pos)->per_frame_eqn_tree->splay_traverse((void (*)(void*))eval_per_frame_eqn_helper); + } + +} + void Preset::evalInitConditions() { per_frame_init_eqn_tree->splay_traverse((void (*)(void*))eval_init_cond_helper); } @@ -406,47 +425,12 @@ void Preset::load_custom_wave_init_conditions() { } void Preset::load_custom_shape_init_conditions() { + /// @bug busted abort(); //custom_shape_tree->splay_traverse((void (*)(void*))load_custom_shape_init_helper); } -/** Returns the next custom waveform in the wave database */ -CustomWave * Preset::nextCustomWave() { - CustomWave * interface_wave = NULL; - - if ( (interface_wave = (CustomWave *)custom_wave_tree->splay_find(&interface_id) ) == NULL ) { - interface_id = 0; - return interface_wave; - } - - interface_id++; - - /** Evaluate all per frame equations associated with this wave */ - interface_wave->init_cond_tree->splay_traverse((void (*)(void*))eval_init_cond_helper); - interface_wave->per_frame_eqn_tree->splay_traverse((void (*)(void*))eval_per_frame_eqn_helper); - - return interface_wave; - } - -/** Returns the next custom shape in the shape database */ -CustomShape * Preset::nextCustomShape() { - - CustomShape *interface_shape = NULL; - - if ( (interface_shape = (CustomShape *)custom_shape_tree->splay_find(&cwave_interface_id) ) == NULL ) { - cwave_interface_id = 0; - return interface_shape; - } - - cwave_interface_id++; - - /** Evaluate all per frame equations associated with this wave */ - interface_shape->init_cond_tree->splay_traverse((void (*)(void*))eval_init_cond_helper); - interface_shape->per_frame_eqn_tree->splay_traverse((void (*)(void*))eval_per_frame_eqn_helper); - - return interface_shape; - } /** Evaluates all per-pixel equations */ void Preset::evalPerPixelEqns() { @@ -552,7 +536,7 @@ int Preset::add_per_pixel_eqn(char * name, GenExpr * gen_expr) { return PROJECTM_SUCCESS; } -/* Finds / Creates (if necessary) initial condition associated with passed parameter */ +/** Finds / Creates (if necessary) initial condition associated with passed parameter */ InitCond * Preset::get_init_cond( Param *param ) { InitCond * init_cond; @@ -670,9 +654,33 @@ int Preset::load_preset_file(const char * pathname) { void Preset::load_init_conditions() { builtinParams.traverse(load_init_cond_helper); +} + + +CustomShape * Preset::find_custom_shape(int id, int create_flag) { + + CustomShape * custom_shape = NULL; + + if ((custom_shape = (CustomShape*)this->customShapes[id]) == NULL) { + + if (CUSTOM_SHAPE_DEBUG) { printf("find_custom_shape: creating custom shape (id = %d)...", id);fflush(stdout);} + + if (create_flag == FALSE) { + if (CUSTOM_SHAPE_DEBUG) printf("you specified not to (create flag = false), returning null\n"); + return NULL; + } + + if ((custom_shape = new CustomShape(id)) == NULL) { + if (CUSTOM_SHAPE_DEBUG) printf("failed...out of memory?\n"); + return NULL; + } + + customShapes.push_back(custom_shape); } + return custom_shape; +} /* Find a parameter given its name, will create one if not found */ Param * Preset::find_param(char * name, int flags) { @@ -680,8 +688,7 @@ Param * Preset::find_param(char * name, int flags) { Param * param = NULL; /* Null argument checks */ - if (name == NULL) - return NULL; + assert(name); /* First look in the builtin database */ param = (Param *)this->builtinParams.find_builtin_param(name); @@ -690,6 +697,7 @@ Param * Preset::find_param(char * name, int flags) { if (param == NULL) { param = (Param*)this->user_param_tree->splay_find(name); } + /* If it doesn't exist in the user (or builtin) database and create_flag is set, then make it and insert into the database */ diff --git a/src/projectM-engine/Preset.hpp b/src/projectM-engine/Preset.hpp index 0ee58413f..d82b99d36 100644 --- a/src/projectM-engine/Preset.hpp +++ b/src/projectM-engine/Preset.hpp @@ -44,6 +44,8 @@ #include "PresetFrameIO.hpp" #include "SplayTree.h" #include "InitCond.h" +#include +#include "StaticArray.hpp" class CustomWave; class InitCond; @@ -53,39 +55,29 @@ class InitCond; class Preset { protected: - /// @idea dynamically allocate this instead (allow pointer to one in constructor, or blank to - /// allocate separately) - /// Benefits: lighter weight presets, but "heavier" ones are still supported too - /// Negatives: heap is slower, extra pointer dereference - //PresetOutputs * presetOutputs; - //PresetOutputs * presetOutputs; - /* preset name as parsed in file */ public: /** Default constructor is *not* a properly initalized preset **/ Preset(); - - /** Load a preset by filename with input and output buffers specified. * Most common way to allocate new preset */ Preset(const PresetInputs * presetInputs, PresetOutputs * presetOutputs, const std::string & filename); ~Preset(); + /** Evaluates the preset for a frame given the current values of preset inputs / outputs */ + void evaluateFrame(); + BuiltinParams builtinParams; std::string name; std::string file_path; int mesh_i,mesh_j; - /** IDs of current waves/shapes */ - int interface_id, cwave_interface_id; - CustomWave * active_wave; - CustomShape * active_shape; - void load_init_conditions(); - + CustomShape * find_custom_shape(int id, int create_flag); + int per_pixel_eqn_string_index; int per_frame_eqn_string_index; int per_frame_init_eqn_string_index; @@ -108,24 +100,12 @@ public: SplayTree * custom_wave_tree; /* custom wave forms for this preset */ SplayTree * custom_shape_tree; /* custom shapes for this preset */ - /** Methods */ - void evalInitConditions(); - void evalCustomWaveInitConditions(); - void evalCustomShapeInitConditions(); - - void evalPerFrameEquations(); - int add_per_pixel_eqn( char *name, GenExpr *gen_expr ); int isPerPixelEqn( int op ); - void evalPerPixelEqns(); + int resetPerPixelEqns(); int resetPerPixelEqnFlags(); - void evalPerPointEqns(); - - CustomWave *nextCustomWave(); - CustomShape *nextCustomShape(); - InitCond *get_init_cond( Param *param ); void load_custom_wave_init_conditions(); @@ -146,16 +126,37 @@ public: int write_per_frame_init_equations( FILE *fs ); int write_per_frame_equations( FILE *fs ); int write_per_pixel_equations( FILE *fs ); - Param * find_param(char * name, int flags) ; + Param * find_param(char * name, int flags) ; int destroy(); -void load_init_cond(char *name, int flags); + void load_init_cond(char *name, int flags); + /** Splaytree traversal helpers */ inline void load_custom_shape_init_helper( void *custom_shape ) { ((CustomShape *)custom_shape)->load_custom_shape_init(); } - + private: + static const std::size_t ARRAY_MAX_SIZE; + + //typedef StaticArray cwave_container; + //typedef StaticArray cshape_container; + typedef std::vector cwave_container; + + typedef std::vector cshape_container; + + void evalPerPointEqns(); + void evalCustomWavePerFrameEquations(); + void evalCustomShapePerFrameEquations(); + void evalInitConditions(); + void evalCustomWaveInitConditions(); + void evalCustomShapeInitConditions(); + void evalPerPixelEqns(); + void evalPerFrameEquations(); + + cwave_container customWaves; + cshape_container customShapes; + }; #endif /** !_PRESET_HPP */ diff --git a/src/projectM-engine/PresetFrameIO.hpp b/src/projectM-engine/PresetFrameIO.hpp index 7b89e9402..2879384f2 100644 --- a/src/projectM-engine/PresetFrameIO.hpp +++ b/src/projectM-engine/PresetFrameIO.hpp @@ -9,7 +9,7 @@ public: /// @bug should this be here? //int mesh_i, mesh_j; - /* PER FRAME CONSTANTS BEGIN */ + /* PER FRAME VARIABLES BEGIN */ float zoom; float zoomexp; float rot; @@ -54,7 +54,7 @@ public: float mv_dy; float mv_dx; - /* PER_FRAME CONSTANTS END */ + /* PER_FRAME VARIABLES END */ float fRating; float fGammaAdj; @@ -133,16 +133,16 @@ public: class PresetInputs { public: - /* PER_PIXEL CONSTANTS BEGIN */ + /* PER_PIXEL VARIBLES BEGIN */ float x_per_pixel; float y_per_pixel; float rad_per_pixel; float ang_per_pixel; - - /* PER_PIXEL CONSTANT END */ - int fps; + /* PER_PIXEL VARIBLES END */ + + int fps; float time; @@ -155,14 +155,14 @@ public: float progress; - /* variables added in 1.04 */ + /* variables were added in milkdrop 1.04 */ int gx,gy; /// @bug are these in use? /// @bugfix YES, presets reference meshx and meshy int meshx; int meshy; -float **x_mesh; + float **x_mesh; float **y_mesh; float **rad_mesh; float **theta_mesh; diff --git a/src/projectM-engine/StaticArray.hpp b/src/projectM-engine/StaticArray.hpp new file mode 100644 index 000000000..a14908d18 --- /dev/null +++ b/src/projectM-engine/StaticArray.hpp @@ -0,0 +1,214 @@ +#ifndef PROJECTM_STATIC_ARRAY_HPP +#define PROJECTM_STATIC_ARRAY_HPP +#include +/** +* A simple array implementation with a few important features: + * (1) static array length, resulting in compile time optimizations + * (2) bounds checking when compiling with assertions + * Note that this data structure is generally useful only for smaller sized arrays. +*/ + +template +class StaticArray { +public: + + typedef T * iterator; + typedef const T * const_iterator; + + StaticArray(); + StaticArray(const std::size_t logical_size); + StaticArray(const std::size_t logical_size, const T & defaultValue); + const T & operator[] (std::size_t index) const; + T & operator[] (std::size_t index); + + iterator begin(); + iterator end(); + + const_iterator begin() const; + const_iterator end() const; + + void clear(); + bool empty() const; + + bool operator==(const StaticArray & rhs) const; + bool operator!=(const StaticArray & rhs) const; + bool operator<(const StaticArray & rhs) const; + bool operator>(const StaticArray & rhs) const; + + /// Do nothing implementation that will be optimized out. Bit of a hack to make it interface with vector. + void reserve(const std::size_t amount) const {} + + void push_back(const T & element); + void pop_back(); + + void erase(iterator first, iterator last); + + std::size_t size() const; + std::size_t capacity() const; + +private: + std::size_t m_logical_size; + T m_array[STATIC_ARRAY_MAX_SIZE+1]; +}; + + +template +StaticArray::StaticArray():m_logical_size(0) {} + +template +StaticArray::StaticArray(const std::size_t logical_size):m_logical_size(logical_size) { + assert(logical_size <= STATIC_ARRAY_MAX_SIZE); +} + +template +StaticArray::StaticArray(const std::size_t logical_size, const T & defaultValue):m_logical_size(logical_size) { + assert(logical_size <= STATIC_ARRAY_MAX_SIZE); + for (iterator pos = begin(); pos != end();++pos) + *pos = defaultValue; +} + +template +inline const T & StaticArray::operator[] (std::size_t index) const { + assert(index <= (m_logical_size-1)); + return m_array[index]; +} + +template +inline T & StaticArray::operator[] (std::size_t index) { + assert(index <= (m_logical_size-1)); + return m_array[index]; +} + +template +inline std::size_t StaticArray::size() const { + return m_logical_size; +} + + +template +inline std::size_t StaticArray::capacity() const { + return STATIC_ARRAY_MAX_SIZE; +} + + +template +inline bool StaticArray::empty() const { + return m_logical_size == 0; +} + +template +inline void StaticArray::clear() { + m_logical_size = 0; +} + +template +inline typename StaticArray::const_iterator StaticArray::begin() const { + return m_array; +} + + +template +inline typename StaticArray::iterator StaticArray::begin() { + return m_array; +} + + +template +inline typename StaticArray::const_iterator StaticArray::end() const { + return m_array+m_logical_size; +} + + +template +inline void StaticArray::push_back(const T & element) { + (*this)[m_logical_size++] = element; +} + + +template +inline void StaticArray::pop_back() { + assert(m_logical_size > 0); + m_logical_size--; +} + + +/// @slow worst case is around N^2 + N. +template +inline void StaticArray::erase(iterator first, iterator last) { + + StaticArray tmpArray; + + for (iterator pos = begin(); pos != end();++pos) { + for (iterator spos = first; spos != last;++spos) { + if (pos != spos) + tmpArray.push_back(*pos); + } + } + (*this) =tmpArray; +} + +template +inline typename StaticArray::iterator StaticArray::end() { + return m_array+m_logical_size; +} + + +/// Lexographic comparison +template +inline bool StaticArray::operator< (const StaticArray & rhs) const { + + const StaticArray & lhs = *this; + + std::size_t len = rhs.size() < lhs.size() ? rhs.size(): lhs.size(); + + for (std::size_t i = 0; i < len;i++) { + if (lhs[i] < rhs[i]) + return true; + else if (!(lhs[i] == rhs[i])) + return false; + } + + // rhs has less elements than lhs + if (len < lhs.size()) + return false; + + // lhs has less elements than rhs + if (len < rhs.size()) + return true; + + // Equal + return false; + +} + + +template +inline bool StaticArray::operator!=(const StaticArray & rhs) const { + return !(*this == rhs); +} + +template +inline bool StaticArray::operator==(const StaticArray & rhs) const { + + const StaticArray & lhs = *this; + + if (rhs.size() != lhs.size()) + return false; + + for (std::size_t i = 0; i < rhs.size() ;i++) { + if (!(rhs[i] == lhs[i])) + return false; + } + return true; + +} + + +template +inline bool StaticArray ::operator> (const StaticArray & rhs) const { + return ((!((*this) == rhs)) && (!((*this) < rhs))); +} + + + +#endif \ No newline at end of file diff --git a/src/projectM-engine/projectM.cpp b/src/projectM-engine/projectM.cpp index d9a478f91..ccbcdfbd8 100755 --- a/src/projectM-engine/projectM.cpp +++ b/src/projectM-engine/projectM.cpp @@ -103,8 +103,8 @@ int x, y; // printf("start:%d at:%d min:%d stop:%d on:%d %d\n",startframe, frame frame-startframe,avgtime, noSwitch,progress); // this->activePreset->evalInitConditions(); - this->activePreset->evalPerFrameEquations(); - this->activePreset->evalPerPixelEqns(); + this->activePreset->evaluateFrame(); + // this->activePreset->evalCustomWaveInitConditions(); // this->activePreset->evalCustomShapeInitConditions(); @@ -647,9 +647,10 @@ DLLEXPORT void projectM::projectM_setTitle( char *title ) { -/* initPresetLoader: initializes the preset +/// @bug:move to header file +/** initPresetTools: initializes the preset loading library. this should be done before - any parsing */ + any parsing. function in limbo, may be dumped */ int projectM::initPresetTools() { /* Initializes the builtin function database */