1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004 VideoLAN (Centrale Réseaux) and its contributors
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
34 #include "expr_types.h"
37 #include "splaytree_types.h"
38 #include "splaytree.h"
40 #include "param_types.h"
43 #include "per_pixel_eqn.h"
44 #include "per_pixel_eqn_types.h"
46 #include "engine_vars.h"
49 extern preset_t * active_preset;
56 /* Evaluates a per pixel equation */
57 inline void evalPerPixelEqn(per_pixel_eqn_t * per_pixel_eqn) {
59 double ** param_matrix = NULL;
60 gen_expr_t * eqn_ptr = NULL;
63 eqn_ptr = per_pixel_eqn->gen_expr;
64 if (per_pixel_eqn->param->matrix == NULL) {
65 if (PER_PIXEL_EQN_DEBUG) printf("evalPerPixelEqn: [begin initializing matrix] (index = %d) (name = %s)\n",
66 per_pixel_eqn->index, per_pixel_eqn->param->name);
68 param_matrix = per_pixel_eqn->param->matrix = (double**)malloc(gx*sizeof(double*));
70 for(x = 0; x < gx; x++)
71 param_matrix[x] = (double *)malloc(gy * sizeof(double));
73 for (x = 0; x < gx; x++)
74 for (y = 0; y < gy; y++)
75 param_matrix[x][y] = 0.0;
77 if (per_pixel_eqn->param->name == NULL)
78 printf("null parameter?\n");
80 // printf("PARAM MATRIX: \"%s\" initialized.\n", per_pixel_eqn->param->name);
83 param_matrix = (double**)per_pixel_eqn->param->matrix;
86 printf("something is seriously wrong...\n");
87 for (mesh_i = 0; mesh_i < gx; mesh_i++) {
88 for (mesh_j = 0; mesh_j < gy; mesh_j++) {
89 param_matrix[mesh_i][mesh_j] = eval_gen_expr(eqn_ptr);
93 /* Now that this parameter has been referenced with a per
94 pixel equation, we let the evaluator know by setting
96 per_pixel_eqn->param->matrix_flag = 1;
99 inline void evalPerPixelEqns() {
101 /* Evaluate all per pixel equations using splay traversal */
102 splay_traverse(evalPerPixelEqn, active_preset->per_pixel_eqn_tree);
104 /* Set mesh i / j values to -1 so engine vars are used by default again */
105 mesh_i = mesh_j = -1;
108 /* Adds a per pixel equation according to its string name. This
109 will be used only by the parser */
111 int add_per_pixel_eqn(char * name, gen_expr_t * gen_expr, preset_t * preset) {
113 per_pixel_eqn_t * per_pixel_eqn;
115 param_t * param = NULL;
117 /* Argument checks */
120 if (gen_expr == NULL)
125 if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: per pixel equation (name = \"%s\")\n", name);
127 if (!strncmp(name, "dx", strlen("dx")))
128 preset->per_pixel_flag[DX_OP] = TRUE;
129 else if (!strncmp(name, "dy", strlen("dy")))
130 preset->per_pixel_flag[DY_OP] = TRUE;
131 else if (!strncmp(name, "cx", strlen("cx")))
132 preset->per_pixel_flag[CX_OP] = TRUE;
133 else if (!strncmp(name, "cy", strlen("cy")))
134 preset->per_pixel_flag[CX_OP] = TRUE;
135 else if (!strncmp(name, "zoom", strlen("zoom")))
136 preset->per_pixel_flag[ZOOM_OP] = TRUE;
137 else if (!strncmp(name, "zoomexp", strlen("zoomexp")))
138 preset->per_pixel_flag[ZOOMEXP_OP] = TRUE;
139 else if (!strncmp(name, "rot", strlen("rot")))
140 preset->per_pixel_flag[ROT_OP] = TRUE;
141 else if (!strncmp(name, "sx", strlen("sx")))
142 preset->per_pixel_flag[SX_OP] = TRUE;
143 else if (!strncmp(name, "sy", strlen("sy")))
144 preset->per_pixel_flag[SY_OP] = TRUE;
147 /* Search for the parameter so we know what matrix the per pixel equation is referencing */
149 if ((param = find_param(name, preset, TRUE)) == NULL) {
150 if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: failed to allocate a new parameter!\n");
155 /* Find most largest index in the splaytree */
156 // if ((per_pixel_eqn = splay_find_max(active_preset->per_pixel_eqn_tree)) == NULL)
159 index = splay_size(preset->per_pixel_eqn_tree);
161 /* Create the per pixel equation given the index, parameter, and general expression */
162 if ((per_pixel_eqn = new_per_pixel_eqn(index, param, gen_expr)) == NULL) {
163 if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: failed to create new per pixel equation!\n");
168 if (PER_PIXEL_EQN_DEBUG) printf("add_per_pixel_eqn: new equation (index = %d) (param = \"%s\")\n",
169 per_pixel_eqn->index, per_pixel_eqn->param->name);
170 /* Insert the per pixel equation into the preset per pixel database */
171 if (splay_insert(per_pixel_eqn, &per_pixel_eqn->index, preset->per_pixel_eqn_tree) < 0) {
172 free_per_pixel_eqn(per_pixel_eqn);
173 printf("failed to add per pixel eqn!\n");
181 per_pixel_eqn_t * new_per_pixel_eqn(int index, param_t * param, gen_expr_t * gen_expr) {
183 per_pixel_eqn_t * per_pixel_eqn;
189 if (gen_expr == NULL)
192 if ((per_pixel_eqn = (per_pixel_eqn_t*)malloc(sizeof(per_pixel_eqn_t))) == NULL)
196 per_pixel_eqn->index = index;
197 per_pixel_eqn->param = param;
198 per_pixel_eqn->gen_expr = gen_expr;
200 return per_pixel_eqn;
204 void free_per_pixel_eqn(per_pixel_eqn_t * per_pixel_eqn) {
206 if (per_pixel_eqn == NULL)
209 free_gen_expr(per_pixel_eqn->gen_expr);
216 inline int isPerPixelEqn(int op) {
218 return active_preset->per_pixel_flag[op];
222 inline int resetPerPixelEqnFlags(preset_t * preset) {
225 for (i = 0; i < NUM_OPS;i++)
226 preset->per_pixel_flag[i] = FALSE;