PageRenderTime 167ms CodeModel.GetById 12ms app.highlight 141ms RepoModel.GetById 1ms app.codeStats 1ms

/xbmc/visualizations/Milkdrop/vis_milkdrop/state.cpp

http://github.com/xbmc/xbmc
C++ | 1797 lines | 1229 code | 159 blank | 409 comment | 124 complexity | 0424d2390e76cb14efe62fe81527dd3c MD5 | raw file
   1
   2/*
   3  LICENSE
   4  -------
   5Copyright 2005 Nullsoft, Inc.
   6All rights reserved.
   7
   8Redistribution and use in source and binary forms, with or without modification, 
   9are permitted provided that the following conditions are met:
  10
  11  * Redistributions of source code must retain the above copyright notice,
  12    this list of conditions and the following disclaimer. 
  13
  14  * Redistributions in binary form must reproduce the above copyright notice,
  15    this list of conditions and the following disclaimer in the documentation
  16    and/or other materials provided with the distribution. 
  17
  18  * Neither the name of Nullsoft nor the names of its contributors may be used to 
  19    endorse or promote products derived from this software without specific prior written permission. 
  20 
  21THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
  22IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
  23FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
  24CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
  28OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29*/
  30#include "state.h"
  31#include "support.h"
  32#include "evallib/compiler.h"
  33#include "plugin.h"
  34#include "utility.h"
  35
  36//#include <stdlib.h>
  37//#include <windows.h>
  38#include <stdio.h>
  39#include <math.h>
  40
  41extern CPlugin* g_plugin;		// declared in main.cpp
  42
  43
  44
  45CState::CState()
  46{
  47	//Default();
  48
  49	// this is the list of variables that can be used for a PER-FRAME calculation;
  50	// it is a SUBSET of the per-vertex calculation variable list.
  51	m_pf_codehandle = NULL;
  52	m_pp_codehandle = NULL;
  53    for (int i=0; i<MAX_CUSTOM_WAVES; i++)
  54    {
  55        m_wave[i].m_pf_codehandle = NULL;
  56        m_wave[i].m_pp_codehandle = NULL;
  57    }
  58    for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
  59    {
  60        m_shape[i].m_pf_codehandle = NULL;
  61        //m_shape[i].m_pp_codehandle = NULL;
  62    }
  63	//RegisterBuiltInVariables();
  64}
  65
  66CState::~CState()
  67{
  68	FreeVarsAndCode();
  69}
  70
  71//--------------------------------------------------------------------------------
  72
  73void CState::RegisterBuiltInVariables(int flags)
  74{
  75    if (flags & RECOMPILE_PRESET_CODE)
  76    {
  77	    resetVars(m_pf_vars);
  78        var_pf_zoom		= registerVar("zoom");		// i/o
  79	    var_pf_zoomexp  = registerVar("zoomexp");	// i/o
  80	    var_pf_rot		= registerVar("rot");		// i/o
  81	    var_pf_warp		= registerVar("warp");		// i/o
  82	    var_pf_cx		= registerVar("cx");		// i/o
  83	    var_pf_cy		= registerVar("cy");		// i/o
  84	    var_pf_dx		= registerVar("dx");		// i/o
  85	    var_pf_dy		= registerVar("dy");		// i/o
  86	    var_pf_sx		= registerVar("sx");		// i/o
  87	    var_pf_sy		= registerVar("sy");		// i/o
  88	    var_pf_time		= registerVar("time");		// i
  89	    var_pf_fps      = registerVar("fps");       // i
  90	    var_pf_bass		= registerVar("bass");		// i
  91	    var_pf_mid		= registerVar("mid");		// i
  92	    var_pf_treb		= registerVar("treb");		// i
  93	    var_pf_bass_att	= registerVar("bass_att");	// i
  94	    var_pf_mid_att	= registerVar("mid_att");	// i
  95	    var_pf_treb_att	= registerVar("treb_att");	// i
  96	    var_pf_frame    = registerVar("frame");
  97	    var_pf_decay	= registerVar("decay");
  98	    var_pf_wave_a	= registerVar("wave_a");
  99	    var_pf_wave_r	= registerVar("wave_r");
 100	    var_pf_wave_g	= registerVar("wave_g");
 101	    var_pf_wave_b	= registerVar("wave_b");
 102	    var_pf_wave_x	= registerVar("wave_x");
 103	    var_pf_wave_y	= registerVar("wave_y");
 104	    var_pf_wave_mystery = registerVar("wave_mystery");
 105	    var_pf_wave_mode = registerVar("wave_mode");
 106	    var_pf_q1       = registerVar("q1");
 107	    var_pf_q2       = registerVar("q2");
 108	    var_pf_q3       = registerVar("q3");
 109	    var_pf_q4       = registerVar("q4");
 110	    var_pf_q5       = registerVar("q5");
 111	    var_pf_q6       = registerVar("q6");
 112	    var_pf_q7       = registerVar("q7");
 113	    var_pf_q8       = registerVar("q8");
 114	    var_pf_progress = registerVar("progress");
 115	    var_pf_ob_size	= registerVar("ob_size");
 116	    var_pf_ob_r		= registerVar("ob_r");
 117	    var_pf_ob_g		= registerVar("ob_g");
 118	    var_pf_ob_b		= registerVar("ob_b");
 119	    var_pf_ob_a		= registerVar("ob_a");
 120	    var_pf_ib_size	= registerVar("ib_size");
 121	    var_pf_ib_r		= registerVar("ib_r");
 122	    var_pf_ib_g		= registerVar("ib_g");
 123	    var_pf_ib_b		= registerVar("ib_b");
 124	    var_pf_ib_a		= registerVar("ib_a");
 125	    var_pf_mv_x		= registerVar("mv_x");
 126	    var_pf_mv_y		= registerVar("mv_y");
 127	    var_pf_mv_dx	= registerVar("mv_dx");
 128	    var_pf_mv_dy	= registerVar("mv_dy");
 129	    var_pf_mv_l		= registerVar("mv_l");
 130	    var_pf_mv_r		= registerVar("mv_r");
 131	    var_pf_mv_g		= registerVar("mv_g");
 132	    var_pf_mv_b		= registerVar("mv_b");
 133	    var_pf_mv_a		= registerVar("mv_a");
 134	    var_pf_monitor  = registerVar("monitor");
 135	    var_pf_echo_zoom   = registerVar("echo_zoom");
 136	    var_pf_echo_alpha  = registerVar("echo_alpha");
 137	    var_pf_echo_orient = registerVar("echo_orient");
 138        var_pf_wave_usedots  = registerVar("wave_usedots");
 139        var_pf_wave_thick    = registerVar("wave_thick");
 140        var_pf_wave_additive = registerVar("wave_additive");
 141        var_pf_wave_brighten = registerVar("wave_brighten");
 142        var_pf_darken_center = registerVar("darken_center");
 143        var_pf_gamma         = registerVar("gamma");
 144        var_pf_wrap          = registerVar("wrap");
 145        var_pf_invert        = registerVar("invert");
 146        var_pf_brighten      = registerVar("brighten");
 147        var_pf_darken        = registerVar("darken");
 148        var_pf_solarize      = registerVar("solarize");
 149        var_pf_meshx         = registerVar("meshx");
 150        var_pf_meshy         = registerVar("meshy");
 151
 152	    resetVars(NULL);
 153
 154	    // this is the list of variables that can be used for a PER-VERTEX calculation:
 155	    // ('vertex' meaning a vertex on the mesh) (as opposed to a once-per-frame calculation)
 156	    
 157        resetVars(m_pv_vars);
 158
 159        var_pv_zoom		= registerVar("zoom");		// i/o
 160	    var_pv_zoomexp  = registerVar("zoomexp");	// i/o
 161	    var_pv_rot		= registerVar("rot");		// i/o
 162	    var_pv_warp		= registerVar("warp");		// i/o
 163	    var_pv_cx		= registerVar("cx");		// i/o
 164	    var_pv_cy		= registerVar("cy");		// i/o
 165	    var_pv_dx		= registerVar("dx");		// i/o
 166	    var_pv_dy		= registerVar("dy");		// i/o
 167	    var_pv_sx		= registerVar("sx");		// i/o
 168	    var_pv_sy		= registerVar("sy");		// i/o
 169	    var_pv_time		= registerVar("time");		// i
 170	    var_pv_fps 		= registerVar("fps");		// i
 171	    var_pv_bass		= registerVar("bass");		// i
 172	    var_pv_mid		= registerVar("mid");		// i
 173	    var_pv_treb		= registerVar("treb");		// i
 174	    var_pv_bass_att	= registerVar("bass_att");	// i
 175	    var_pv_mid_att	= registerVar("mid_att");	// i
 176	    var_pv_treb_att	= registerVar("treb_att");	// i
 177	    var_pv_frame    = registerVar("frame");
 178	    var_pv_x		= registerVar("x");			// i
 179	    var_pv_y		= registerVar("y");			// i
 180	    var_pv_rad		= registerVar("rad");		// i
 181	    var_pv_ang		= registerVar("ang");		// i
 182	    var_pv_q1       = registerVar("q1");
 183	    var_pv_q2       = registerVar("q2");
 184	    var_pv_q3       = registerVar("q3");
 185	    var_pv_q4       = registerVar("q4");
 186	    var_pv_q5       = registerVar("q5");
 187	    var_pv_q6       = registerVar("q6");
 188	    var_pv_q7       = registerVar("q7");
 189	    var_pv_q8       = registerVar("q8");
 190	    var_pv_progress = registerVar("progress");
 191        var_pv_meshx    = registerVar("meshx");
 192        var_pv_meshy    = registerVar("meshy");
 193	    resetVars(NULL);
 194    }
 195
 196    if (flags & RECOMPILE_WAVE_CODE)
 197    {
 198        for (int i=0; i<MAX_CUSTOM_WAVES; i++)
 199        {
 200	        resetVars(m_wave[i].m_pf_vars);
 201	        m_wave[i].var_pf_time		= registerVar("time");		// i
 202	        m_wave[i].var_pf_fps 		= registerVar("fps");		// i
 203	        m_wave[i].var_pf_frame      = registerVar("frame");     // i
 204	        m_wave[i].var_pf_progress   = registerVar("progress");  // i
 205	        m_wave[i].var_pf_q1         = registerVar("q1");        // i
 206	        m_wave[i].var_pf_q2         = registerVar("q2");        // i
 207	        m_wave[i].var_pf_q3         = registerVar("q3");        // i
 208	        m_wave[i].var_pf_q4         = registerVar("q4");        // i
 209	        m_wave[i].var_pf_q5         = registerVar("q5");        // i
 210	        m_wave[i].var_pf_q6         = registerVar("q6");        // i
 211	        m_wave[i].var_pf_q7         = registerVar("q7");        // i
 212	        m_wave[i].var_pf_q8         = registerVar("q8");        // i
 213	        m_wave[i].var_pf_t1         = registerVar("t1");        // i/o
 214	        m_wave[i].var_pf_t2         = registerVar("t2");        // i/o
 215	        m_wave[i].var_pf_t3         = registerVar("t3");        // i/o
 216	        m_wave[i].var_pf_t4         = registerVar("t4");        // i/o
 217	        m_wave[i].var_pf_t5         = registerVar("t5");        // i/o
 218	        m_wave[i].var_pf_t6         = registerVar("t6");        // i/o
 219	        m_wave[i].var_pf_t7         = registerVar("t7");        // i/o
 220	        m_wave[i].var_pf_t8         = registerVar("t8");        // i/o
 221	        m_wave[i].var_pf_bass		= registerVar("bass");		// i
 222	        m_wave[i].var_pf_mid		= registerVar("mid");		// i
 223	        m_wave[i].var_pf_treb		= registerVar("treb");		// i
 224	        m_wave[i].var_pf_bass_att	= registerVar("bass_att");	// i
 225	        m_wave[i].var_pf_mid_att	= registerVar("mid_att");	// i
 226	        m_wave[i].var_pf_treb_att	= registerVar("treb_att");	// i
 227	        m_wave[i].var_pf_r          = registerVar("r");         // i/o
 228	        m_wave[i].var_pf_g          = registerVar("g");         // i/o
 229	        m_wave[i].var_pf_b          = registerVar("b");         // i/o
 230	        m_wave[i].var_pf_a          = registerVar("a");         // i/o
 231	        resetVars(NULL);
 232
 233	        resetVars(m_wave[i].m_pp_vars);
 234	        m_wave[i].var_pp_time		= registerVar("time");		// i
 235	        m_wave[i].var_pp_fps 		= registerVar("fps");		// i
 236	        m_wave[i].var_pp_frame      = registerVar("frame");     // i
 237	        m_wave[i].var_pp_progress   = registerVar("progress");  // i
 238	        m_wave[i].var_pp_q1         = registerVar("q1");        // i
 239	        m_wave[i].var_pp_q2         = registerVar("q2");        // i
 240	        m_wave[i].var_pp_q3         = registerVar("q3");        // i
 241	        m_wave[i].var_pp_q4         = registerVar("q4");        // i
 242	        m_wave[i].var_pp_q5         = registerVar("q5");        // i
 243	        m_wave[i].var_pp_q6         = registerVar("q6");        // i
 244	        m_wave[i].var_pp_q7         = registerVar("q7");        // i
 245	        m_wave[i].var_pp_q8         = registerVar("q8");        // i
 246	        m_wave[i].var_pp_t1         = registerVar("t1");        // i
 247	        m_wave[i].var_pp_t2         = registerVar("t2");        // i
 248	        m_wave[i].var_pp_t3         = registerVar("t3");        // i
 249	        m_wave[i].var_pp_t4         = registerVar("t4");        // i
 250	        m_wave[i].var_pp_t5         = registerVar("t5");        // i
 251	        m_wave[i].var_pp_t6         = registerVar("t6");        // i
 252	        m_wave[i].var_pp_t7         = registerVar("t7");        // i
 253	        m_wave[i].var_pp_t8         = registerVar("t8");        // i
 254	        m_wave[i].var_pp_bass		= registerVar("bass");		// i
 255	        m_wave[i].var_pp_mid		= registerVar("mid");		// i
 256	        m_wave[i].var_pp_treb		= registerVar("treb");		// i
 257	        m_wave[i].var_pp_bass_att	= registerVar("bass_att");	// i
 258	        m_wave[i].var_pp_mid_att	= registerVar("mid_att");	// i
 259	        m_wave[i].var_pp_treb_att	= registerVar("treb_att");	// i
 260            m_wave[i].var_pp_sample     = registerVar("sample");    // i
 261            m_wave[i].var_pp_value1     = registerVar("value1");    // i
 262            m_wave[i].var_pp_value2     = registerVar("value2");    // i
 263	        m_wave[i].var_pp_x          = registerVar("x");         // i/o
 264	        m_wave[i].var_pp_y          = registerVar("y");         // i/o
 265	        m_wave[i].var_pp_r          = registerVar("r");         // i/o
 266	        m_wave[i].var_pp_g          = registerVar("g");         // i/o
 267	        m_wave[i].var_pp_b          = registerVar("b");         // i/o
 268	        m_wave[i].var_pp_a          = registerVar("a");         // i/o
 269	        resetVars(NULL);
 270        }
 271    }
 272
 273    if (flags & RECOMPILE_SHAPE_CODE)
 274    {
 275        for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
 276        {
 277	        resetVars(m_shape[i].m_pf_vars);
 278	        m_shape[i].var_pf_time		= registerVar("time");		// i
 279	        m_shape[i].var_pf_fps 		= registerVar("fps");		// i
 280	        m_shape[i].var_pf_frame      = registerVar("frame");     // i
 281	        m_shape[i].var_pf_progress   = registerVar("progress");  // i
 282	        m_shape[i].var_pf_q1         = registerVar("q1");        // i
 283	        m_shape[i].var_pf_q2         = registerVar("q2");        // i
 284	        m_shape[i].var_pf_q3         = registerVar("q3");        // i
 285	        m_shape[i].var_pf_q4         = registerVar("q4");        // i
 286	        m_shape[i].var_pf_q5         = registerVar("q5");        // i
 287	        m_shape[i].var_pf_q6         = registerVar("q6");        // i
 288	        m_shape[i].var_pf_q7         = registerVar("q7");        // i
 289	        m_shape[i].var_pf_q8         = registerVar("q8");        // i
 290	        m_shape[i].var_pf_t1         = registerVar("t1");        // i/o
 291	        m_shape[i].var_pf_t2         = registerVar("t2");        // i/o
 292	        m_shape[i].var_pf_t3         = registerVar("t3");        // i/o
 293	        m_shape[i].var_pf_t4         = registerVar("t4");        // i/o
 294	        m_shape[i].var_pf_t5         = registerVar("t5");        // i/o
 295	        m_shape[i].var_pf_t6         = registerVar("t6");        // i/o
 296	        m_shape[i].var_pf_t7         = registerVar("t7");        // i/o
 297	        m_shape[i].var_pf_t8         = registerVar("t8");        // i/o
 298	        m_shape[i].var_pf_bass		= registerVar("bass");		// i
 299	        m_shape[i].var_pf_mid		= registerVar("mid");		// i
 300	        m_shape[i].var_pf_treb		= registerVar("treb");		// i
 301	        m_shape[i].var_pf_bass_att	= registerVar("bass_att");	// i
 302	        m_shape[i].var_pf_mid_att	= registerVar("mid_att");	// i
 303	        m_shape[i].var_pf_treb_att	= registerVar("treb_att");	// i
 304	        m_shape[i].var_pf_x          = registerVar("x");         // i/o
 305	        m_shape[i].var_pf_y          = registerVar("y");         // i/o
 306	        m_shape[i].var_pf_rad        = registerVar("rad");         // i/o
 307	        m_shape[i].var_pf_ang        = registerVar("ang");         // i/o
 308	        m_shape[i].var_pf_tex_ang    = registerVar("tex_ang");         // i/o
 309	        m_shape[i].var_pf_tex_zoom   = registerVar("tex_zoom");         // i/o
 310	        m_shape[i].var_pf_sides      = registerVar("sides");         // i/o
 311	        m_shape[i].var_pf_textured   = registerVar("textured");         // i/o
 312	        m_shape[i].var_pf_additive   = registerVar("additive");         // i/o
 313	        m_shape[i].var_pf_thick      = registerVar("thick");         // i/o
 314	        m_shape[i].var_pf_r          = registerVar("r");         // i/o
 315	        m_shape[i].var_pf_g          = registerVar("g");         // i/o
 316	        m_shape[i].var_pf_b          = registerVar("b");         // i/o
 317	        m_shape[i].var_pf_a          = registerVar("a");         // i/o
 318	        m_shape[i].var_pf_r2         = registerVar("r2");         // i/o
 319	        m_shape[i].var_pf_g2         = registerVar("g2");         // i/o
 320	        m_shape[i].var_pf_b2         = registerVar("b2");         // i/o
 321	        m_shape[i].var_pf_a2         = registerVar("a2");         // i/o
 322	        m_shape[i].var_pf_border_r   = registerVar("border_r");         // i/o
 323	        m_shape[i].var_pf_border_g   = registerVar("border_g");         // i/o
 324	        m_shape[i].var_pf_border_b   = registerVar("border_b");         // i/o
 325	        m_shape[i].var_pf_border_a   = registerVar("border_a");         // i/o
 326	        resetVars(NULL);
 327
 328            /*
 329	        resetVars(m_shape[i].m_pp_vars);
 330	        m_shape[i].var_pp_time		= registerVar("time");		// i
 331	        m_shape[i].var_pp_fps 		= registerVar("fps");		// i
 332	        m_shape[i].var_pp_frame      = registerVar("frame");     // i
 333	        m_shape[i].var_pp_progress   = registerVar("progress");  // i
 334	        m_shape[i].var_pp_q1         = registerVar("q1");        // i
 335	        m_shape[i].var_pp_q2         = registerVar("q2");        // i
 336	        m_shape[i].var_pp_q3         = registerVar("q3");        // i
 337	        m_shape[i].var_pp_q4         = registerVar("q4");        // i
 338	        m_shape[i].var_pp_q5         = registerVar("q5");        // i
 339	        m_shape[i].var_pp_q6         = registerVar("q6");        // i
 340	        m_shape[i].var_pp_q7         = registerVar("q7");        // i
 341	        m_shape[i].var_pp_q8         = registerVar("q8");        // i
 342	        m_shape[i].var_pp_t1         = registerVar("t1");        // i/o
 343	        m_shape[i].var_pp_t2         = registerVar("t2");        // i/o
 344	        m_shape[i].var_pp_t3         = registerVar("t3");        // i/o
 345	        m_shape[i].var_pp_t4         = registerVar("t4");        // i/o
 346	        m_shape[i].var_pp_t5         = registerVar("t5");        // i/o
 347	        m_shape[i].var_pp_t6         = registerVar("t6");        // i/o
 348	        m_shape[i].var_pp_t7         = registerVar("t7");        // i/o
 349	        m_shape[i].var_pp_t8         = registerVar("t8");        // i/o
 350	        m_shape[i].var_pp_bass		= registerVar("bass");		// i
 351	        m_shape[i].var_pp_mid		= registerVar("mid");		// i
 352	        m_shape[i].var_pp_treb		= registerVar("treb");		// i
 353	        m_shape[i].var_pp_bass_att	= registerVar("bass_att");	// i
 354	        m_shape[i].var_pp_mid_att	= registerVar("mid_att");	// i
 355	        m_shape[i].var_pp_treb_att	= registerVar("treb_att");	// i
 356	        m_shape[i].var_pp_x          = registerVar("x");         // i/o
 357	        m_shape[i].var_pp_y          = registerVar("y");         // i/o
 358	        m_shape[i].var_pp_rad        = registerVar("rad");         // i/o
 359	        m_shape[i].var_pp_ang        = registerVar("ang");         // i/o
 360	        m_shape[i].var_pp_sides      = registerVar("sides");         // i/o
 361	        m_shape[i].var_pp_r          = registerVar("r");         // i/o
 362	        m_shape[i].var_pp_g          = registerVar("g");         // i/o
 363	        m_shape[i].var_pp_b          = registerVar("b");         // i/o
 364	        m_shape[i].var_pp_a          = registerVar("a");         // i/o
 365	        m_shape[i].var_pp_r          = registerVar("r2");         // i/o
 366	        m_shape[i].var_pp_g          = registerVar("g2");         // i/o
 367	        m_shape[i].var_pp_b          = registerVar("b2");         // i/o
 368	        m_shape[i].var_pp_a          = registerVar("a2");         // i/o
 369	        m_shape[i].var_pp_border_r   = registerVar("border_r");         // i/o
 370	        m_shape[i].var_pp_border_g   = registerVar("border_g");         // i/o
 371	        m_shape[i].var_pp_border_b   = registerVar("border_b");         // i/o
 372	        m_shape[i].var_pp_border_a   = registerVar("border_a");         // i/o
 373	        resetVars(NULL);
 374            */
 375        }
 376    }
 377}
 378void CState::Default()
 379{
 380	// DON'T FORGET TO ADD NEW VARIABLES TO BLEND FUNCTION, IMPORT, and EXPORT AS WELL!!!!!!!!
 381
 382	strcpy(m_szDesc, "<no description>");
 383	//strcpy(m_szSection, "n/a");
 384
 385	m_fRating				= 3.0f;
 386	m_bBlending				= false;
 387
 388	m_fGammaAdj				= 2.0f;		// 1.0 = reg; +2.0 = double, +3.0 = triple...
 389	m_fVideoEchoZoom		= 2.0f;
 390	m_fVideoEchoAlpha		= 0.0f;
 391	m_nVideoEchoOrientation	= 0;		// 0-3
 392	
 393	m_fDecay				= 0.98f;	// 1.0 = none, 0.95 = heavy decay
 394
 395	m_nWaveMode				= 0;
 396	m_nOldWaveMode			= -1;
 397	m_bAdditiveWaves		= false;
 398	m_fWaveAlpha			= 0.8f;
 399	m_fWaveScale			= 1.0f;
 400	m_fWaveSmoothing		= 0.75f;	// 0 = no smoothing, 0.9 = HEAVY smoothing
 401	m_bWaveDots				= false;
 402	m_bWaveThick            = false;
 403	m_fWaveParam			= 0.0f;
 404	m_bModWaveAlphaByVolume = false;
 405	m_fModWaveAlphaStart	= 0.75f;		// when relative volume hits this level, alpha -> 0
 406	m_fModWaveAlphaEnd		= 0.95f;		// when relative volume hits this level, alpha -> 1
 407
 408	m_fWarpAnimSpeed		= 1.0f;		// additional timescaling for warp animation
 409	m_fWarpScale			= 1.0f;
 410	m_fZoomExponent			= 1.0f;
 411	m_fShader				= 0.0f;
 412	m_bMaximizeWaveColor	= true;
 413	m_bTexWrap				= true;
 414	m_bDarkenCenter			= false;
 415	m_bRedBlueStereo		= false;
 416	m_fMvX				  	= 12.0f;
 417	m_fMvY					= 9.0f;
 418	m_fMvDX                 = 0.0f;
 419	m_fMvDY                 = 0.0f;
 420	m_fMvL				  	= 0.9f;
 421	m_fMvR                  = 1.0f;
 422	m_fMvG                  = 1.0f;
 423	m_fMvB                  = 1.0f;
 424	m_fMvA                  = 1.0f;
 425	m_bBrighten				= false;
 426	m_bDarken				= false;
 427	m_bSolarize				= false;
 428	m_bInvert				= false;
 429
 430	// DON'T FORGET TO ADD NEW VARIABLES TO BLEND FUNCTION, IMPORT, and EXPORT AS WELL!!!!!!!!
 431	// ALSO BE SURE TO REGISTER THEM ON THE MAIN MENU (SEE MILKDROP.CPP)
 432
 433	// time-varying variables:   base,  var,   varFreq1, varFreq2
 434	m_fZoom			= 1.0f;
 435	m_fRot 			= 0.0f;
 436	m_fRotCX		= 0.5f;
 437	m_fRotCY		= 0.5f;
 438	m_fXPush		= 0.0f;
 439	m_fYPush		= 0.0f;
 440	m_fWarpAmount	= 1.0f;
 441	m_fStretchX     = 1.0f;
 442	m_fStretchY     = 1.0f;
 443	m_fWaveR		= 1.0f;
 444	m_fWaveG		= 1.0f;
 445	m_fWaveB		= 1.0f;
 446	m_fWaveX		= 0.5f;
 447	m_fWaveY		= 0.5f;
 448	m_fOuterBorderSize = 0.01f;
 449	m_fOuterBorderR	= 0.0f;
 450	m_fOuterBorderG	= 0.0f;
 451	m_fOuterBorderB	= 0.0f;
 452	m_fOuterBorderA	= 0.0f;
 453	m_fInnerBorderSize = 0.01f;
 454	m_fInnerBorderR	= 0.25f;
 455	m_fInnerBorderG	= 0.25f;
 456	m_fInnerBorderB	= 0.25f;
 457	m_fInnerBorderA	= 0.0f;
 458
 459    for (int i=0; i<MAX_CUSTOM_WAVES; i++)
 460    {
 461        m_wave[i].enabled = 0;
 462        m_wave[i].samples = 512;
 463        m_wave[i].sep = 0;
 464        m_wave[i].scaling = 1.0f;
 465        m_wave[i].smoothing = 0.5f;
 466        m_wave[i].r = 1.0f;
 467        m_wave[i].g = 1.0f;
 468        m_wave[i].b = 1.0f;
 469        m_wave[i].a = 1.0f;
 470        m_wave[i].bSpectrum = 0;
 471        m_wave[i].bUseDots = 0;
 472        m_wave[i].bDrawThick = 0;
 473        m_wave[i].bAdditive = 0;
 474    }
 475
 476    for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
 477    {
 478        m_shape[i].enabled = 0;
 479        m_shape[i].sides   = 4;
 480        m_shape[i].additive = 0;
 481        m_shape[i].thickOutline = 0;
 482        m_shape[i].textured = 0;
 483        m_shape[i].tex_zoom = 1.0f;
 484        m_shape[i].tex_ang  = 0.0f;
 485        m_shape[i].x = 0.5f;
 486        m_shape[i].y = 0.5f;
 487        m_shape[i].rad = 0.1f;
 488        m_shape[i].ang = 0.0f;
 489        m_shape[i].r = 1.0f;
 490        m_shape[i].g = 0.0f;
 491        m_shape[i].b = 0.0f;
 492        m_shape[i].a = 1.0f;
 493        m_shape[i].r2 = 0.0f;
 494        m_shape[i].g2 = 1.0f;
 495        m_shape[i].b2 = 0.0f;
 496        m_shape[i].a2 = 0.0f;
 497        m_shape[i].border_r = 1.0f;
 498        m_shape[i].border_g = 1.0f;
 499        m_shape[i].border_b = 1.0f;
 500        m_shape[i].border_a = 0.1f;
 501    }
 502
 503    // clear all code strings:
 504    m_szPerFrameInit[0] = 0;
 505    m_szPerFrameExpr[0] = 0;
 506    m_szPerPixelExpr[0] = 0;
 507    for (int i=0; i<MAX_CUSTOM_WAVES; i++)
 508    {
 509        m_wave[i].m_szInit[0] = 0;
 510        m_wave[i].m_szPerFrame[0] = 0;
 511        m_wave[i].m_szPerPoint[0] = 0;
 512    }
 513    for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
 514    {
 515        m_shape[i].m_szInit[0] = 0;
 516        m_shape[i].m_szPerFrame[0] = 0;
 517        //m_shape[i].m_szPerPoint[0] = 0;
 518    }
 519	
 520	FreeVarsAndCode();
 521}
 522
 523void CState::StartBlendFrom(CState *s_from, float fAnimTime, float fTimespan)
 524{
 525	CState *s_to = this;
 526
 527	// bools, ints, and strings instantly change
 528
 529	s_to->m_fVideoEchoAlphaOld		 = s_from->m_fVideoEchoAlpha.eval(-1);
 530	s_to->m_nVideoEchoOrientationOld = s_from->m_nVideoEchoOrientation;
 531	s_to->m_nOldWaveMode			 = s_from->m_nWaveMode;
 532
 533	/*
 534	s_to->m_fVideoEchoAlphaOld		 = s_from->m_fVideoEchoAlpha.eval(-1);
 535	s_to->m_nVideoEchoOrientationOld = s_from->m_nVideoEchoOrientation;
 536
 537	s_to->m_nOldWaveMode			= s_from->m_nWaveMode;
 538	s_to->m_nWaveMode				= s_from->m_nWaveMode;
 539	s_to->m_bAdditiveWaves			= s_from->m_bAdditiveWaves;
 540	s_to->m_nVideoEchoOrientation	= s_from->m_nVideoEchoOrientation;
 541	s_to->m_fWarpAnimSpeed			= s_from->m_fWarpAnimSpeed;	// would req. 10 phase-matches to blend this one!!!
 542	s_to->m_bWaveDots				= s_from->m_bWaveDots;
 543	s_to->m_bWaveThick				= s_from->m_bWaveThick;
 544	s_to->m_bModWaveAlphaByVolume	= s_from->m_bModWaveAlphaByVolume;
 545	s_to->m_bMaximizeWaveColor		= s_from->m_bMaximizeWaveColor;
 546	s_to->m_bTexWrap				= s_from->m_bTexWrap;			
 547	s_to->m_bDarkenCenter			= s_from->m_bDarkenCenter;
 548	s_to->m_bRedBlueStereo			= s_from->m_bRedBlueStereo;
 549	s_to->m_bBrighten				= s_from->m_bBrighten;
 550	s_to->m_bDarken					= s_from->m_bDarken;
 551	s_to->m_bSolarize				= s_from->m_bSolarize;
 552	s_to->m_bInvert					= s_from->m_bInvert;
 553	s_to->m_fRating					= s_from->m_fRating;
 554	*/
 555
 556	// expr. eval. also copies over immediately (replaces prev.)
 557	m_bBlending = true;
 558	m_fBlendStartTime = fAnimTime;
 559	m_fBlendDuration = fTimespan;
 560	
 561	/*
 562	//for (int e=0; e<MAX_EVALS; e++)
 563	{
 564		char szTemp[8192];
 565
 566		strcpy(szTemp, m_szPerFrameExpr);
 567		strcpy(m_szPerFrameExpr, s_to->m_szPerFrameExpr);
 568		strcpy(s_to->m_szPerFrameExpr, szTemp);
 569
 570		strcpy(szTemp, m_szPerPixelExpr);
 571		strcpy(m_szPerPixelExpr, s_to->m_szPerPixelExpr);
 572		strcpy(s_to->m_szPerPixelExpr, szTemp);
 573
 574		strcpy(szTemp, m_szPerFrameInit);
 575		strcpy(m_szPerFrameInit, s_to->m_szPerFrameInit);
 576		strcpy(s_to->m_szPerFrameInit, szTemp);
 577	}
 578	RecompileExpressions();
 579	s_to->RecompileExpressions();
 580
 581	strcpy(m_szDesc,    s_to->m_szDesc);
 582	//strcpy(m_szSection, s_to->m_szSection);
 583	*/
 584	
 585	// CBlendableFloats & SuperValues blend over time 
 586	m_fGammaAdj      .StartBlendFrom(&s_from->m_fGammaAdj      , fAnimTime, fTimespan);
 587	m_fVideoEchoZoom .StartBlendFrom(&s_from->m_fVideoEchoZoom , fAnimTime, fTimespan);
 588	m_fVideoEchoAlpha.StartBlendFrom(&s_from->m_fVideoEchoAlpha, fAnimTime, fTimespan);
 589	m_fDecay         .StartBlendFrom(&s_from->m_fDecay         , fAnimTime, fTimespan);
 590	m_fWaveAlpha     .StartBlendFrom(&s_from->m_fWaveAlpha     , fAnimTime, fTimespan);
 591	m_fWaveScale     .StartBlendFrom(&s_from->m_fWaveScale     , fAnimTime, fTimespan);
 592	m_fWaveSmoothing .StartBlendFrom(&s_from->m_fWaveSmoothing , fAnimTime, fTimespan);
 593	m_fWaveParam     .StartBlendFrom(&s_from->m_fWaveParam     , fAnimTime, fTimespan);
 594	m_fWarpScale     .StartBlendFrom(&s_from->m_fWarpScale     , fAnimTime, fTimespan);
 595	m_fZoomExponent  .StartBlendFrom(&s_from->m_fZoomExponent  , fAnimTime, fTimespan);
 596	m_fShader        .StartBlendFrom(&s_from->m_fShader        , fAnimTime, fTimespan);
 597	m_fModWaveAlphaStart.StartBlendFrom(&s_from->m_fModWaveAlphaStart, fAnimTime, fTimespan);
 598	m_fModWaveAlphaEnd  .StartBlendFrom(&s_from->m_fModWaveAlphaEnd, fAnimTime, fTimespan);
 599
 600	m_fZoom		.StartBlendFrom(&s_from->m_fZoom		, fAnimTime, fTimespan);
 601	m_fRot 		.StartBlendFrom(&s_from->m_fRot 		, fAnimTime, fTimespan);
 602	m_fRotCX	.StartBlendFrom(&s_from->m_fRotCX		, fAnimTime, fTimespan);
 603	m_fRotCY	.StartBlendFrom(&s_from->m_fRotCY		, fAnimTime, fTimespan);
 604	m_fXPush	.StartBlendFrom(&s_from->m_fXPush		, fAnimTime, fTimespan);
 605	m_fYPush	.StartBlendFrom(&s_from->m_fYPush		, fAnimTime, fTimespan);
 606	m_fWarpAmount.StartBlendFrom(&s_from->m_fWarpAmount,fAnimTime, fTimespan);
 607	m_fStretchX .StartBlendFrom(&s_from->m_fStretchX	, fAnimTime, fTimespan);
 608	m_fStretchY .StartBlendFrom(&s_from->m_fStretchY	, fAnimTime, fTimespan);
 609	m_fWaveR	.StartBlendFrom(&s_from->m_fWaveR		, fAnimTime, fTimespan);
 610	m_fWaveG	.StartBlendFrom(&s_from->m_fWaveG		, fAnimTime, fTimespan);
 611	m_fWaveB	.StartBlendFrom(&s_from->m_fWaveB		, fAnimTime, fTimespan);
 612	m_fWaveX	.StartBlendFrom(&s_from->m_fWaveX		, fAnimTime, fTimespan);
 613	m_fWaveY	.StartBlendFrom(&s_from->m_fWaveY		, fAnimTime, fTimespan);
 614	m_fOuterBorderSize	.StartBlendFrom(&s_from->m_fOuterBorderSize	, fAnimTime, fTimespan);
 615	m_fOuterBorderR		.StartBlendFrom(&s_from->m_fOuterBorderR	, fAnimTime, fTimespan);
 616	m_fOuterBorderG		.StartBlendFrom(&s_from->m_fOuterBorderG	, fAnimTime, fTimespan);
 617	m_fOuterBorderB		.StartBlendFrom(&s_from->m_fOuterBorderB	, fAnimTime, fTimespan);
 618	m_fOuterBorderA		.StartBlendFrom(&s_from->m_fOuterBorderA	, fAnimTime, fTimespan);
 619	m_fInnerBorderSize	.StartBlendFrom(&s_from->m_fInnerBorderSize	, fAnimTime, fTimespan);
 620	m_fInnerBorderR		.StartBlendFrom(&s_from->m_fInnerBorderR	, fAnimTime, fTimespan);
 621	m_fInnerBorderG		.StartBlendFrom(&s_from->m_fInnerBorderG	, fAnimTime, fTimespan);
 622	m_fInnerBorderB		.StartBlendFrom(&s_from->m_fInnerBorderB	, fAnimTime, fTimespan);
 623	m_fInnerBorderA		.StartBlendFrom(&s_from->m_fInnerBorderA	, fAnimTime, fTimespan);
 624	m_fMvX				.StartBlendFrom(&s_from->m_fMvX				, fAnimTime, fTimespan);
 625	m_fMvY				.StartBlendFrom(&s_from->m_fMvY				, fAnimTime, fTimespan);
 626	m_fMvDX				.StartBlendFrom(&s_from->m_fMvDX			, fAnimTime, fTimespan);
 627	m_fMvDY				.StartBlendFrom(&s_from->m_fMvDY			, fAnimTime, fTimespan);
 628	m_fMvL				.StartBlendFrom(&s_from->m_fMvL				, fAnimTime, fTimespan);
 629	m_fMvR				.StartBlendFrom(&s_from->m_fMvR				, fAnimTime, fTimespan);
 630	m_fMvG				.StartBlendFrom(&s_from->m_fMvG				, fAnimTime, fTimespan);
 631	m_fMvB				.StartBlendFrom(&s_from->m_fMvB				, fAnimTime, fTimespan);
 632	m_fMvA				.StartBlendFrom(&s_from->m_fMvA				, fAnimTime, fTimespan);
 633
 634	// if motion vectors were transparent before, don't morph the # in X and Y - just
 635	// start in the right place, and fade them in.
 636	bool bOldStateTransparent = (s_from->m_fMvA.eval(-1) < 0.001f);
 637	bool bNewStateTransparent = (s_to->m_fMvA.eval(-1) < 0.001f);
 638	if (!bOldStateTransparent && bNewStateTransparent)
 639	{
 640		s_from->m_fMvX = s_to->m_fMvX.eval(fAnimTime);
 641		s_from->m_fMvY = s_to->m_fMvY.eval(fAnimTime);
 642		s_from->m_fMvDX = s_to->m_fMvDX.eval(fAnimTime);
 643		s_from->m_fMvDY = s_to->m_fMvDY.eval(fAnimTime);
 644		s_from->m_fMvL = s_to->m_fMvL.eval(fAnimTime);
 645		s_from->m_fMvR = s_to->m_fMvR.eval(fAnimTime);
 646		s_from->m_fMvG = s_to->m_fMvG.eval(fAnimTime);
 647		s_from->m_fMvB = s_to->m_fMvB.eval(fAnimTime);
 648	}
 649	if (bNewStateTransparent && !bOldStateTransparent)
 650	{
 651		s_to->m_fMvX = s_from->m_fMvX.eval(fAnimTime);
 652		s_to->m_fMvY = s_from->m_fMvY.eval(fAnimTime);
 653		s_to->m_fMvDX = s_from->m_fMvDX.eval(fAnimTime);
 654		s_to->m_fMvDY = s_from->m_fMvDY.eval(fAnimTime);
 655		s_to->m_fMvL = s_from->m_fMvL.eval(fAnimTime);
 656		s_to->m_fMvR = s_from->m_fMvR.eval(fAnimTime);
 657		s_to->m_fMvG = s_from->m_fMvG.eval(fAnimTime);
 658		s_to->m_fMvB = s_from->m_fMvB.eval(fAnimTime);
 659	}
 660
 661}
 662
 663void WriteCode(FILE* fOut, int i, char* pStr, char* prefix)
 664{
 665	char szLineName[32];
 666	int line = 1;
 667	int start_pos = 0;
 668	int char_pos = 0;
 669
 670	while (pStr[start_pos] != 0)
 671	{
 672		while (	pStr[char_pos] != 0 &&
 673				pStr[char_pos] != LINEFEED_CONTROL_CHAR)
 674			char_pos++;
 675
 676		sprintf(szLineName, "%s%d", prefix, line);
 677
 678		char ch = pStr[char_pos];
 679		pStr[char_pos] = 0;
 680		//if (!WritePrivateProfileString(szSectionName,szLineName,&pStr[start_pos],szIniFile)) return false;
 681		fprintf(fOut, "%s=%s\n", szLineName, &pStr[start_pos]);
 682		pStr[char_pos] = ch;
 683
 684		if (pStr[char_pos] != 0) char_pos++;
 685		start_pos = char_pos;
 686		line++;
 687	}
 688}
 689
 690bool CState::Export(char *szSectionName, char *szIniFile)
 691{
 692	FILE *fOut = fopen(szIniFile, "w");
 693	if (!fOut) return false;
 694
 695	fprintf(fOut, "[%s]\n", szSectionName);
 696
 697	fprintf(fOut, "%s=%f\n", "fRating",                m_fRating);         
 698	fprintf(fOut, "%s=%f\n", "fGammaAdj",              m_fGammaAdj.eval(-1));         
 699	fprintf(fOut, "%s=%f\n", "fDecay",                 m_fDecay.eval(-1));            
 700	fprintf(fOut, "%s=%f\n", "fVideoEchoZoom",         m_fVideoEchoZoom.eval(-1));    
 701	fprintf(fOut, "%s=%f\n", "fVideoEchoAlpha",        m_fVideoEchoAlpha.eval(-1));   
 702	fprintf(fOut, "%s=%d\n", "nVideoEchoOrientation",  m_nVideoEchoOrientation);      
 703
 704	fprintf(fOut, "%s=%d\n", "nWaveMode",              m_nWaveMode);                  
 705	fprintf(fOut, "%s=%d\n", "bAdditiveWaves",         m_bAdditiveWaves);             
 706	fprintf(fOut, "%s=%d\n", "bWaveDots",              m_bWaveDots);                  
 707	fprintf(fOut, "%s=%d\n", "bWaveThick",             m_bWaveThick);                  
 708	fprintf(fOut, "%s=%d\n", "bModWaveAlphaByVolume",  m_bModWaveAlphaByVolume);      
 709	fprintf(fOut, "%s=%d\n", "bMaximizeWaveColor",     m_bMaximizeWaveColor);         
 710	fprintf(fOut, "%s=%d\n", "bTexWrap",               m_bTexWrap			);         
 711	fprintf(fOut, "%s=%d\n", "bDarkenCenter",          m_bDarkenCenter		);         
 712	fprintf(fOut, "%s=%d\n", "bRedBlueStereo",         m_bRedBlueStereo     );
 713	fprintf(fOut, "%s=%d\n", "bBrighten",              m_bBrighten			);         
 714	fprintf(fOut, "%s=%d\n", "bDarken",                m_bDarken			);         
 715	fprintf(fOut, "%s=%d\n", "bSolarize",              m_bSolarize			);         
 716	fprintf(fOut, "%s=%d\n", "bInvert",                m_bInvert			);         
 717
 718	fprintf(fOut, "%s=%f\n", "fWaveAlpha",             m_fWaveAlpha.eval(-1)); 		  
 719	fprintf(fOut, "%s=%f\n", "fWaveScale",             m_fWaveScale.eval(-1));        
 720	fprintf(fOut, "%s=%f\n", "fWaveSmoothing",         m_fWaveSmoothing.eval(-1));    
 721	fprintf(fOut, "%s=%f\n", "fWaveParam",             m_fWaveParam.eval(-1));        
 722	fprintf(fOut, "%s=%f\n", "fModWaveAlphaStart",     m_fModWaveAlphaStart.eval(-1));
 723	fprintf(fOut, "%s=%f\n", "fModWaveAlphaEnd",       m_fModWaveAlphaEnd.eval(-1));  
 724	fprintf(fOut, "%s=%f\n", "fWarpAnimSpeed",         m_fWarpAnimSpeed);             
 725	fprintf(fOut, "%s=%f\n", "fWarpScale",             m_fWarpScale.eval(-1));        
 726	fprintf(fOut, "%s=%f\n", "fZoomExponent",          m_fZoomExponent.eval(-1));     
 727	fprintf(fOut, "%s=%f\n", "fShader",                m_fShader.eval(-1));           
 728
 729	fprintf(fOut, "%s=%f\n", "zoom",                   m_fZoom      .eval(-1));       
 730	fprintf(fOut, "%s=%f\n", "rot",                    m_fRot       .eval(-1));       
 731	fprintf(fOut, "%s=%f\n", "cx",                     m_fRotCX     .eval(-1));       
 732	fprintf(fOut, "%s=%f\n", "cy",                     m_fRotCY     .eval(-1));       
 733	fprintf(fOut, "%s=%f\n", "dx",                     m_fXPush     .eval(-1));       
 734	fprintf(fOut, "%s=%f\n", "dy",                     m_fYPush     .eval(-1));       
 735	fprintf(fOut, "%s=%f\n", "warp",                   m_fWarpAmount.eval(-1));       
 736	fprintf(fOut, "%s=%f\n", "sx",                     m_fStretchX  .eval(-1));       
 737	fprintf(fOut, "%s=%f\n", "sy",                     m_fStretchY  .eval(-1));       
 738	fprintf(fOut, "%s=%f\n", "wave_r",                 m_fWaveR     .eval(-1));       
 739	fprintf(fOut, "%s=%f\n", "wave_g",                 m_fWaveG     .eval(-1));       
 740	fprintf(fOut, "%s=%f\n", "wave_b",                 m_fWaveB     .eval(-1));       
 741	fprintf(fOut, "%s=%f\n", "wave_x",                 m_fWaveX     .eval(-1));       
 742	fprintf(fOut, "%s=%f\n", "wave_y",                 m_fWaveY     .eval(-1));       
 743
 744	fprintf(fOut, "%s=%f\n", "ob_size",             m_fOuterBorderSize.eval(-1));       
 745	fprintf(fOut, "%s=%f\n", "ob_r",                m_fOuterBorderR.eval(-1));       
 746	fprintf(fOut, "%s=%f\n", "ob_g",                m_fOuterBorderG.eval(-1));       
 747	fprintf(fOut, "%s=%f\n", "ob_b",                m_fOuterBorderB.eval(-1));       
 748	fprintf(fOut, "%s=%f\n", "ob_a",                m_fOuterBorderA.eval(-1));       
 749	fprintf(fOut, "%s=%f\n", "ib_size",             m_fInnerBorderSize.eval(-1));       
 750	fprintf(fOut, "%s=%f\n", "ib_r",                m_fInnerBorderR.eval(-1));       
 751	fprintf(fOut, "%s=%f\n", "ib_g",                m_fInnerBorderG.eval(-1));       
 752	fprintf(fOut, "%s=%f\n", "ib_b",                m_fInnerBorderB.eval(-1));       
 753	fprintf(fOut, "%s=%f\n", "ib_a",                m_fInnerBorderA.eval(-1));       
 754	fprintf(fOut, "%s=%f\n", "nMotionVectorsX",     m_fMvX.eval(-1));         
 755	fprintf(fOut, "%s=%f\n", "nMotionVectorsY",     m_fMvY.eval(-1));         
 756	fprintf(fOut, "%s=%f\n", "mv_dx",               m_fMvDX.eval(-1));         
 757	fprintf(fOut, "%s=%f\n", "mv_dy",               m_fMvDY.eval(-1));         
 758	fprintf(fOut, "%s=%f\n", "mv_l",                m_fMvL.eval(-1));         
 759	fprintf(fOut, "%s=%f\n", "mv_r",                m_fMvR.eval(-1));       
 760	fprintf(fOut, "%s=%f\n", "mv_g",                m_fMvG.eval(-1));       
 761	fprintf(fOut, "%s=%f\n", "mv_b",                m_fMvB.eval(-1));       
 762	fprintf(fOut, "%s=%f\n", "mv_a",                m_fMvA.eval(-1));
 763
 764  int i=0;
 765
 766    for (i=0; i<MAX_CUSTOM_WAVES; i++)
 767        m_wave[i].Export("", szIniFile, i, fOut);
 768
 769    for (i=0; i<MAX_CUSTOM_SHAPES; i++)
 770        m_shape[i].Export("", szIniFile, i, fOut);
 771
 772	// write out arbitrary expressions, one line at a time
 773    WriteCode(fOut, i, m_szPerFrameInit, "per_frame_init_");
 774    WriteCode(fOut, i, m_szPerFrameExpr, "per_frame_"); 
 775    WriteCode(fOut, i, m_szPerPixelExpr, "per_pixel_"); 
 776
 777    /*
 778    int n2 = 3 + MAX_CUSTOM_WAVES*3 + MAX_CUSTOM_SHAPES*2;
 779	for (int n=0; n<n2; n++)
 780	{
 781		char *pStr;
 782        char prefix[64];
 783		switch(n)
 784		{
 785		case 0: pStr = m_szPerFrameExpr; strcpy(prefix, "per_frame_"); break;
 786		case 1: pStr = m_szPerPixelExpr; strcpy(prefix, "per_pixel_"); break;
 787		case 2: pStr = m_szPerFrameInit; strcpy(prefix, "per_frame_init_"); break;
 788        default:
 789            if (n < 3 + 3*MAX_CUSTOM_WAVES)
 790            {
 791                int i = (n-3) / 3;
 792                int j = (n-3) % 3;
 793                switch(j)
 794                {
 795                case 0: pStr = m_wave[i].m_szInit;     sprintf(prefix, "wave_%d_init",      i); break;
 796                case 1: pStr = m_wave[i].m_szPerFrame; sprintf(prefix, "wave_%d_per_frame", i); break;
 797                case 2: pStr = m_wave[i].m_szPerPoint; sprintf(prefix, "wave_%d_per_point", i); break;
 798                }
 799            }
 800            else
 801            {
 802                int i = (n-3-3*MAX_CUSTOM_WAVES) / 2;
 803                int j = (n-3-3*MAX_CUSTOM_WAVES) % 2;
 804                switch(j)
 805                {
 806                case 0: pStr = m_shape[i].m_szInit;     sprintf(prefix, "shape_%d_init",      i); break;
 807                case 1: pStr = m_shape[i].m_szPerFrame; sprintf(prefix, "shape_%d_per_frame", i); break;
 808                }
 809            }
 810		}
 811
 812		char szLineName[32];
 813		int line = 1;
 814		int start_pos = 0;
 815		int char_pos = 0;
 816
 817		while (pStr[start_pos] != 0)
 818		{
 819			while (	pStr[char_pos] != 0 &&
 820					pStr[char_pos] != LINEFEED_CONTROL_CHAR)
 821				char_pos++;
 822
 823			sprintf(szLineName, "%s%d", prefix, line);
 824
 825			char ch = pStr[char_pos];
 826			pStr[char_pos] = 0;
 827			//if (!WritePrivateProfileString(szSectionName,szLineName,&pStr[start_pos],szIniFile)) return false;
 828			fprintf(fOut, "%s=%s\n", szLineName, &pStr[start_pos]);
 829			pStr[char_pos] = ch;
 830
 831			if (pStr[char_pos] != 0) char_pos++;
 832			start_pos = char_pos;
 833			line++;
 834		}
 835	}	
 836    */
 837
 838	fclose(fOut);
 839
 840	return true;
 841}
 842
 843int  CWave::Export(char* szSection, char *szFile, int i, FILE* fOut)
 844{
 845    FILE* f2 = fOut;
 846    if (!fOut)
 847    {
 848	    f2 = fopen(szFile, "w");
 849        if (!f2) return 0;
 850	    fprintf(f2, "[%s]\n", szSection);
 851    }
 852
 853	fprintf(f2, "wavecode_%d_%s=%d\n", i, "enabled",    enabled);
 854	fprintf(f2, "wavecode_%d_%s=%d\n", i, "samples",    samples);
 855	fprintf(f2, "wavecode_%d_%s=%d\n", i, "sep",        sep    );
 856	fprintf(f2, "wavecode_%d_%s=%d\n", i, "bSpectrum",  bSpectrum);
 857	fprintf(f2, "wavecode_%d_%s=%d\n", i, "bUseDots",   bUseDots);
 858	fprintf(f2, "wavecode_%d_%s=%d\n", i, "bDrawThick", bDrawThick);
 859	fprintf(f2, "wavecode_%d_%s=%d\n", i, "bAdditive",  bAdditive);
 860	fprintf(f2, "wavecode_%d_%s=%f\n", i, "scaling",    scaling);
 861	fprintf(f2, "wavecode_%d_%s=%f\n", i, "smoothing",  smoothing);
 862	fprintf(f2, "wavecode_%d_%s=%f\n", i, "r",          r);
 863	fprintf(f2, "wavecode_%d_%s=%f\n", i, "g",          g);
 864	fprintf(f2, "wavecode_%d_%s=%f\n", i, "b",          b);
 865	fprintf(f2, "wavecode_%d_%s=%f\n", i, "a",          a);
 866
 867    // READ THE CODE IN
 868    char prefix[64];
 869    sprintf(prefix, "wave_%d_init",      i); WriteCode(f2, i, m_szInit,     prefix);
 870    sprintf(prefix, "wave_%d_per_frame", i); WriteCode(f2, i, m_szPerFrame, prefix);
 871    sprintf(prefix, "wave_%d_per_point", i); WriteCode(f2, i, m_szPerPoint, prefix);
 872
 873    if (!fOut)
 874	    fclose(f2); // [sic]
 875
 876    return 1;
 877}
 878
 879int  CShape::Export(char* szSection, char *szFile, int i, FILE* fOut)
 880{
 881    FILE* f2 = fOut;
 882    if (!fOut)
 883    {
 884	    f2 = fopen(szFile, "w");
 885        if (!f2) return 0;
 886	    fprintf(f2, "[%s]\n", szSection);
 887    }
 888
 889	fprintf(f2, "shapecode_%d_%s=%d\n", i, "enabled",    enabled);
 890	fprintf(f2, "shapecode_%d_%s=%d\n", i, "sides",      sides);
 891	fprintf(f2, "shapecode_%d_%s=%d\n", i, "additive",   additive);
 892	fprintf(f2, "shapecode_%d_%s=%d\n", i, "thickOutline",thickOutline);
 893	fprintf(f2, "shapecode_%d_%s=%d\n", i, "textured",   textured);
 894	fprintf(f2, "shapecode_%d_%s=%f\n", i, "x",          x);
 895	fprintf(f2, "shapecode_%d_%s=%f\n", i, "y",          y);
 896	fprintf(f2, "shapecode_%d_%s=%f\n", i, "rad",        rad);
 897	fprintf(f2, "shapecode_%d_%s=%f\n", i, "ang",        ang);
 898	fprintf(f2, "shapecode_%d_%s=%f\n", i, "tex_ang",    tex_ang);
 899	fprintf(f2, "shapecode_%d_%s=%f\n", i, "tex_zoom",   tex_zoom);
 900	fprintf(f2, "shapecode_%d_%s=%f\n", i, "r",          r);
 901	fprintf(f2, "shapecode_%d_%s=%f\n", i, "g",          g);
 902	fprintf(f2, "shapecode_%d_%s=%f\n", i, "b",          b);
 903	fprintf(f2, "shapecode_%d_%s=%f\n", i, "a",          a);
 904	fprintf(f2, "shapecode_%d_%s=%f\n", i, "r2",         r2);
 905	fprintf(f2, "shapecode_%d_%s=%f\n", i, "g2",         g2);
 906	fprintf(f2, "shapecode_%d_%s=%f\n", i, "b2",         b2);
 907	fprintf(f2, "shapecode_%d_%s=%f\n", i, "a2",         a2);
 908	fprintf(f2, "shapecode_%d_%s=%f\n", i, "border_r",   border_r);
 909	fprintf(f2, "shapecode_%d_%s=%f\n", i, "border_g",   border_g);
 910	fprintf(f2, "shapecode_%d_%s=%f\n", i, "border_b",   border_b);
 911	fprintf(f2, "shapecode_%d_%s=%f\n", i, "border_a",   border_a);
 912
 913    char prefix[64];
 914    sprintf(prefix, "shape_%d_init",      i); WriteCode(f2, i, m_szInit,     prefix);
 915    sprintf(prefix, "shape_%d_per_frame", i); WriteCode(f2, i, m_szPerFrame, prefix);
 916    //sprintf(prefix, "shape_%d_per_point", i); WriteCode(f2, i, m_szPerPoint, prefix);
 917
 918    if (!fOut)
 919	    fclose(f2); // [sic]
 920
 921    return 1;
 922}
 923
 924void ReadCode(char* szSectionName, char* szIniFile, char* pStr, char* prefix)
 925{
 926	// read in & compile arbitrary expressions
 927	char szLineName[32];
 928	char szLine[8192];
 929	int len;
 930
 931	int line = 1;
 932	int char_pos = 0;
 933	bool bDone = false;
 934
 935	while (!bDone)
 936	{
 937		sprintf(szLineName, "%s%d", prefix, line); 
 938
 939		InternalGetPrivateProfileString(szSectionName, szLineName, "~!@#$", szLine, 8192, szIniFile);	// fixme
 940		len = strlen(szLine);
 941
 942		if ((strcmp(szLine, "~!@#$")==0) ||		// if the key was missing,
 943			(len >= 8191-char_pos-1))			// or if we're out of space
 944		{
 945			bDone = true;
 946		}
 947		else 
 948		{
 949			sprintf(&pStr[char_pos], "%s%c", szLine, LINEFEED_CONTROL_CHAR);
 950		}
 951	
 952		char_pos += len + 1;
 953		line++;
 954	}
 955	pStr[char_pos++] = 0;	// null-terminate
 956
 957	// read in & compile arbitrary expressions
 958    /*
 959    int n2 = 3 + MAX_CUSTOM_WAVES*3 + MAX_CUSTOM_SHAPES*2;
 960	for (int n=0; n<n2; n++)
 961	{
 962		char *pStr;
 963        char prefix[64];
 964		char szLineName[32];
 965		char szLine[8192];
 966		int len;
 967
 968		int line = 1;
 969		int char_pos = 0;
 970		bool bDone = false;
 971
 972		switch(n)
 973		{
 974		case 0: pStr = m_szPerFrameExpr; strcpy(prefix, "per_frame_"); break;
 975		case 1: pStr = m_szPerPixelExpr; strcpy(prefix, "per_pixel_"); break;
 976		case 2: pStr = m_szPerFrameInit; strcpy(prefix, "per_frame_init_"); break;
 977        default:
 978            if (n < 3 + 3*MAX_CUSTOM_WAVES)
 979            {
 980                int i = (n-3) / 3;
 981                int j = (n-3) % 3;
 982                switch(j)
 983                {
 984                case 0: pStr = m_wave[i].m_szInit;     sprintf(prefix, "wave_%d_init",      i); break;
 985                case 1: pStr = m_wave[i].m_szPerFrame; sprintf(prefix, "wave_%d_per_frame", i); break;
 986                case 2: pStr = m_wave[i].m_szPerPoint; sprintf(prefix, "wave_%d_per_point", i); break;
 987                }
 988            }
 989            else
 990            {
 991                int i = (n-3-3*MAX_CUSTOM_WAVES) / 2;
 992                int j = (n-3-3*MAX_CUSTOM_WAVES) % 2;
 993                switch(j)
 994                {
 995                case 0: pStr = m_shape[i].m_szInit;     sprintf(prefix, "shape_%d_init",      i); break;
 996                case 1: pStr = m_shape[i].m_szPerFrame; sprintf(prefix, "shape_%d_per_frame", i); break;
 997                }
 998            }
 999		}
1000		
1001		while (!bDone)
1002		{
1003			sprintf(szLineName, "%s%d", prefix, line); 
1004
1005			InternalGetPrivateProfileString(szSectionName, szLineName, "~!@#$", szLine, 8192, szIniFile);	// fixme
1006			len = strlen(szLine);
1007
1008			if ((strcmp(szLine, "~!@#$")==0) ||		// if the key was missing,
1009				(len >= 8191-char_pos-1))			// or if we're out of space
1010			{
1011				bDone = true;
1012			}
1013			else 
1014			{
1015				sprintf(&pStr[char_pos], "%s%c", szLine, LINEFEED_CONTROL_CHAR);
1016			}
1017		
1018			char_pos += len + 1;
1019			line++;
1020		}
1021		pStr[char_pos++] = 0;	// null-terminate
1022	}
1023    */
1024}
1025
1026int CWave::Import(char* szSectionName, char *szIniFile, int i)
1027{
1028//    if (GetFileAttributes(szIniFile)==0xFFFFFFFF)
1029//        return 0;
1030
1031    char buf[64];
1032    sprintf(buf, "wavecode_%d_%s", i, "enabled"   ); enabled    = InternalGetPrivateProfileInt  (szSectionName, buf, enabled   , szIniFile);
1033    sprintf(buf, "wavecode_%d_%s", i, "samples"   ); samples    = InternalGetPrivateProfileInt  (szSectionName, buf, samples   , szIniFile);
1034    sprintf(buf, "wavecode_%d_%s", i, "sep"       ); sep        = InternalGetPrivateProfileInt  (szSectionName, buf, sep       , szIniFile);
1035    sprintf(buf, "wavecode_%d_%s", i, "bSpectrum" ); bSpectrum  = InternalGetPrivateProfileInt  (szSectionName, buf, bSpectrum , szIniFile);
1036    sprintf(buf, "wavecode_%d_%s", i, "bUseDots"  ); bUseDots   = InternalGetPrivateProfileInt  (szSectionName, buf, bUseDots  , szIniFile);
1037    sprintf(buf, "wavecode_%d_%s", i, "bDrawThick"); bDrawThick = InternalGetPrivateProfileInt  (szSectionName, buf, bDrawThick, szIniFile);
1038    sprintf(buf, "wavecode_%d_%s", i, "bAdditive" ); bAdditive  = InternalGetPrivateProfileInt  (szSectionName, buf, bAdditive , szIniFile);
1039    sprintf(buf, "wavecode_%d_%s", i, "scaling"   ); scaling    = InternalGetPrivateProfileFloat(szSectionName, buf, scaling   , szIniFile);
1040    sprintf(buf, "wavecode_%d_%s", i, "smoothing" ); smoothing  = InternalGetPrivateProfileFloat(szSectionName, buf, smoothing , szIniFile);
1041    sprintf(buf, "wavecode_%d_%s", i, "r"         ); r          = InternalGetPrivateProfileFloat(szSectionName, buf, r         , szIniFile);
1042    sprintf(buf, "wavecode_%d_%s", i, "g"         ); g          = InternalGetPrivateProfileFloat(szSectionName, buf, g         , szIniFile);
1043    sprintf(buf, "wavecode_%d_%s", i, "b"         ); b          = InternalGetPrivateProfileFloat(szSectionName, buf, b         , szIniFile);
1044    sprintf(buf, "wavecode_%d_%s", i, "a"         ); a          = InternalGetPrivateProfileFloat(szSectionName, buf, a         , szIniFile);
1045
1046    // READ THE CODE IN
1047    char prefix[64];
1048    sprintf(prefix, "wave_%d_init",      i); ReadCode(szSectionName, szIniFile, m_szInit,     prefix);
1049    sprintf(prefix, "wave_%d_per_frame", i); ReadCode(szSectionName, szIniFile, m_szPerFrame, prefix);
1050    sprintf(prefix, "wave_%d_per_point", i); ReadCode(szSectionName, szIniFile, m_szPerPoint, prefix);
1051
1052    return 1;
1053}
1054
1055int  CShape::Import(char* szSectionName, char *szIniFile, int i)
1056{
1057//    if (GetFileAttributes(szIniFile)==0xFFFFFFFF)
1058//        return 0;
1059
1060    char buf[64];
1061	sprintf(buf, "shapecode_%d_%s", i, "enabled"     ); enabled      = InternalGetPrivateProfileInt  (szSectionName, buf, enabled     , szIniFile);
1062	sprintf(buf, "shapecode_%d_%s", i, "sides"       ); sides        = InternalGetPrivateProfileInt  (szSectionName, buf, sides       , szIniFile);
1063	sprintf(buf, "shapecode_%d_%s", i, "additive"    ); additive     = InternalGetPrivateProfileInt  (szSectionName, buf, additive    , szIniFile);
1064	sprintf(buf, "shapecode_%d_%s", i, "thickOutline"); thickOutline = InternalGetPrivateProfileInt  (szSectionName, buf, thickOutline, szIniFile);
1065	sprintf(buf, "shapecode_%d_%s", i, "textured"    ); textured     = InternalGetPrivateProfileInt  (szSectionName, buf, textured    , szIniFile);
1066	sprintf(buf, "shapecode_%d_%s", i, "x"           ); x            = InternalGetPrivateProfileFloat(szSectionName, buf, x           , szIniFile);
1067	sprintf(buf, "shapecode_%d_%s", i, "y"           ); y            = InternalGetPrivateProfileFloat(szSectionName, buf, y           , szIniFile);
1068	sprintf(buf, "shapecode_%d_%s", i, "rad"         ); rad          = InternalGetPrivateProfileFloat(szSectionName, buf, rad         , szIniFile);
1069	sprintf(buf, "shapecode_%d_%s", i, "ang"         ); ang          = InternalGetPrivateProfileFloat(szSectionName, buf, ang         , szIniFile);
1070	sprintf(buf, "shapecode_%d_%s", i, "tex_ang"     ); tex_ang      = InternalGetPrivateProfileFloat(szSectionName, buf, tex_ang     , szIniFile);
1071	sprintf(buf, "shapecode_%d_%s", i, "tex_zoom"    ); tex_zoom     = InternalGetPrivateProfileFloat(szSectionName, buf, tex_zoom    , szIniFile);
1072	sprintf(buf, "shapecode_%d_%s", i, "r"           ); r            = InternalGetPrivateProfileFloat(szSectionName, buf, r           , szIniFile);
1073	sprintf(buf, "shapecode_%d_%s", i, "g"           ); g            = InternalGetPrivateProfileFloat(szSectionName, buf, g           , szIniFile);
1074	sprintf(buf, "shapecode_%d_%s", i, "b"           ); b            = InternalGetPrivateProfileFloat(szSectionName, buf, b           , szIniFile);
1075	sprintf(buf, "shapecode_%d_%s", i, "a"           ); a            = InternalGetPrivateProfileFloat(szSectionName, buf, a           , szIniFile);
1076	sprintf(buf, "shapecode_%d_%s", i, "r2"          ); r2           = InternalGetPrivateProfileFloat(szSectionName, buf, r2          , szIniFile);
1077	sprintf(buf, "shapecode_%d_%s", i, "g2"          ); g2           = InternalGetPrivateProfileFloat(szSectionName, buf, g2          , szIniFile);
1078	sprintf(buf, "shapecode_%d_%s", i, "b2"          ); b2           = InternalGetPrivateProfileFloat(szSectionName, buf, b2          , szIniFile);
1079	sprintf(buf, "shapecode_%d_%s", i, "a2"          ); a2           = InternalGetPrivateProfileFloat(szSectionName, buf, a2          , szIniFile);
1080	sprintf(buf, "shapecode_%d_%s", i, "border_r"    ); border_r     = InternalGetPrivateProfileFloat(szSectionName, buf, border_r    , szIniFile);
1081	sprintf(buf, "shapecode_%d_%s", i, "border_g"    ); border_g     = InternalGetPrivateProfileFloat(szSectionName, buf, border_g    , szIniFile);
1082	sprintf(buf, "shapecode_%d_%s", i, "border_b"    ); border_b     = InternalGetPrivateProfileFloat(szSectionName, buf, border_b    , szIniFile);
1083	sprintf(buf, "shapecode_%d_%s", i, "border_a"    ); border_a     = InternalGetPrivateProfileFloat(szSectionName, buf, border_a    , szIniFile);
1084
1085    // READ THE CODE IN
1086    char prefix[64];
1087    sprintf(prefix, "shape_%d_init",      i); ReadCode(szSectionName, szIniFile, m_szInit,     prefix);
1088    sprintf(prefix, "shape_%d_per_frame", i); ReadCode(szSectionName, szIniFile, m_szPerFrame, prefix);
1089
1090    return 1;
1091}
1092
1093void CState::Import(char *szSectionName, char *szIniFile)
1094{
1095
1096	Default();
1097
1098	//strcpy(m_szSection, szSectionName);
1099	//InternalGetPrivateProfileString(szSectionName, "szDesc", "<no description>", m_szDesc, sizeof(m_szDesc), szIniFile);
1100	
1101	// extract a description of the preset from the filename
1102	{
1103		// copy get the filename (without the path)
1104		char *p = strrchr(szIniFile, '/');
1105		if (p==NULL) p = szIniFile;
1106		strcpy(m_szDesc, p+1);		
1107
1108		// next remove the extension
1109		RemoveExtension(m_szDesc);
1110	}
1111	
1112	m_fRating				= InternalGetPrivateProfileFloat(szSectionName,"fRating",m_fRating,szIniFile);
1113	m_fDecay                = InternalGetPrivateProfileFloat(szSectionName,"fDecay",m_fDecay.eval(-1),szIniFile);
1114	m_fGammaAdj             = InternalGetPrivateProfileFloat(szSectionName,"fGammaAdj" ,m_fGammaAdj.eval(-1),szIniFile);
1115	m_fVideoEchoZoom        = InternalGetPrivateProfileFloat(szSectionName,"fVideoEchoZoom",m_fVideoEchoZoom.eval(-1),szIniFile);
1116	m_fVideoEchoAlpha       = InternalGetPrivateProfileFloat(szSectionName,"fVideoEchoAlpha",m_fVideoEchoAlpha.eval(-1),szIniFile);
1117	m_nVideoEchoOrientation = InternalGetPrivateProfileInt  (szSectionName,"nVideoEchoOrientation",m_nVideoEchoOrientation,szIniFile);
1118
1119	m_nWaveMode             = InternalGetPrivateProfileInt  (szSectionName,"nWaveMode",m_nWaveMode,szIniFile);
1120	m_bAdditiveWaves		= (InternalGetPrivateProfileInt (szSectionName,"bAdditiveWaves",m_bAdditiveWaves,szIniFile) != 0);
1121	m_bWaveDots		        = (InternalGetPrivateProfileInt (szSectionName,"bWaveDots",m_bWaveDots,szIniFile) != 0);
1122	m_bWaveThick            = (InternalGetPrivateProfileInt (szSectionName,"bWaveThick",m_bWaveThick,szIniFile) != 0);
1123	m_bModWaveAlphaByVolume	= (InternalGetPrivateProfileInt (szSectionName,"bModWaveAlphaByVolume",m_bModWaveAlphaByVolume,szIniFile) != 0);
1124	m_bMaximizeWaveColor    = (InternalGetPrivateProfileInt (szSectionName,"bMaximizeWaveColor" ,m_bMaximizeWaveColor,szIniFile) != 0);
1125	m_bTexWrap			    = (InternalGetPrivateProfileInt (szSectionName,"bTexWrap", m_bTexWrap,szIniFile) != 0);
1126	m_bDarkenCenter			= (InternalGetPrivateProfileInt (szSectionName,"bDarkenCenter", m_bDarkenCenter,szIniFile) != 0);
1127	m_bRedBlueStereo        = (InternalGetPrivateProfileInt (szSectionName,"bRedBlueStereo", m_bRedBlueStereo,szIniFile) != 0);
1128	m_bBrighten				= (InternalGetPrivateProfileInt (szSectionName,"bBrighten",m_bBrighten	,szIniFile) != 0);
1129	m_bDarken				= (InternalGetPrivateProfileInt (szSectionName,"bDarken"  ,m_bDarken	,szIniFile) != 0);
1130	m_bSolarize				= (InternalGetPrivateProfileInt (szSectionName,"bSolarize",m_bSolarize	,szIniFile) != 0);
1131	m_bInvert				= (InternalGetPrivateProfileInt (szSectionName,"bInvert"  ,m_bInvert	,szIniFile) != 0);
1132
1133	m_fWaveAlpha            = InternalGetPrivateProfileFloat(szSectionName,"fWaveAlpha",m_fWaveAlpha.eval(-1),szIniFile);
1134	m_fWaveScale            = InternalGetPrivateProfileFloat(szSectionName,"fWaveScale",m_fWaveScale.eval(-1),szIniFile);
1135	m_fWaveSmoothing        = InternalGetPrivateProfileFloat(szSectionName,"fWaveSmoothing",m_fWaveSmoothing.eval(-1),szIniFile);
1136	m_fWaveParam            = InternalGetPrivateProfileFloat(szSectionName,"fWaveParam",m_fWaveParam.eval(-1),szIniFile);
1137	m_fModWaveAlphaStart    = InternalGetPrivateProfileFloat(szSectionName,"fModWaveAlphaStart",m_fModWaveAlphaStart.eval(-1),szIniFile);
1138	m_fModWaveAlphaEnd      = InternalGetPrivateProfileFloat(szSectionName,"fModWaveAlphaEnd",m_fModWaveAlphaEnd.eval(-1),szIniFile);
1139	m_fWarpAnimSpeed        = InternalGetPrivateProfileFloat(szSectionName,"fWarpAnimSpeed",m_fWarpAnimSpeed,szIniFile);
1140	m_fWarpScale            = InternalGetPrivateProfileFloat(szSectionName,"fWarpScale",m_fWarpScale.eval(-1),szIniFile);
1141	m_fZoomExponent         = InternalGetPrivateProfileFloat(szSectionName,"fZoomExponent",m_fZoomExponent.eval(-1),szIniFile);
1142	m_fShader               = InternalGetPrivateProfileFloat(szSectionName,"fShader",m_fShader.eval(-1),szIniFile);
1143
1144	m_fZoom					= InternalGetPrivateProfileFloat(szSectionName,"zoom",m_fZoom.eval(-1),szIniFile);	
1145	m_fRot					= InternalGetPrivateProfileFloat(szSectionName,"rot",m_fRot.eval(-1),szIniFile);	
1146	m_fRotCX				= InternalGetPrivateProfileFloat(szSectionName,"cx",m_fRotCX.eval(-1),szIniFile);	
1147	m_fRotCY				= InternalGetPrivateProfileFloat(szSectionName,"cy",m_fRotCY.eval(-1),szIniFile);	
1148	m_fXPush				= InternalGetPrivateProfileFloat(szSectionName,"dx",m_fXPush.eval(-1),szIniFile);	
1149	m_fYPush				= InternalGetPrivateProfileFloat(szSectionName,"dy",m_fYPush.eval(-1),szIniFile);	
1150	m_fWarpAmount			= InternalGetPrivateProfileFloat(szSectionName,"warp",m_fWarpAmount.eval(-1),szIniFile);	
1151	m_fStretchX				= InternalGetPrivateProfileFloat(szSectionName,"sx",m_fStretchX.eval(-1),szIniFile);	
1152	m_fStretchY				= InternalGetPrivateProfileFloat(szSectionName,"sy",m_fStretchY.eval(-1),szIniFile);	
1153	m_fWaveR				= InternalGetPrivateProfileFloat(szSectionName,"wave_r",m_fRot.eval(-1),szIniFile);	
1154	m_fWaveG				= InternalGetPrivateProfileFloat(szSectionName,"wave_g",m_fRot.eval(-1),szIniFile);	
1155	m_fWaveB				= InternalGetPrivateProfileFloat(szSectionName,"wave_b",m_fRot.eval(-1),szIniFile);	
1156	m_fWaveX				= InternalGetPrivateProfileFloat(szSectionName,"wave_x",m_fRot.eval(-1),szIniFile);	
1157	m_fWaveY				= InternalGetPrivateProfileFloat(szSectionName,"wave_y",m_fRot.eval(-1),szIniFile);	
1158
1159	m_fOuterBorderSize	= InternalGetPrivateProfileFloat(szSectionName,"ob_size",m_fOuterBorderSize.eval(-1),szIniFile);	
1160	m_fOuterBorderR		= InternalGetPrivateProfileFloat(szSectionName,"ob_r",   m_fOuterBorderR.eval(-1),szIniFile);	
1161	m_fOuterBorderG		= InternalGetPrivateProfileFloat(szSectionName,"ob_g",   m_fOuterBorderG.eval(-1),szIniFile);	
1162	m_fOuterBorderB		= InternalGetPrivateProfileFloat(szSectionName,"ob_b",   m_fOuterBorderB.eval(-1),szIniFile);	
1163	m_fOuterBorderA		= InternalGetPrivateProfileFloat(szSectionName,"ob_a",   m_fOuterBorderA.eval(-1),szIniFile);	
1164	m_fInnerBorderSize	= InternalGetPrivateProfileFloat(szSectionName,"ib_size",m_fInnerBorderSize.eval(-1),szIniFile);	
1165	m_fInnerBorderR		= InternalGetPrivateProfileFloat(szSectionName,"ib_r",   m_fInnerBorderR.eval(-1),szIniFile);	
1166	m_fInnerBorderG		= InternalGetPrivateProfileFloat(szSectionName,"ib_g",   m_fInnerBorderG.eval(-1),szIniFile);	
1167	m_fInnerBorderB		= InternalGetPrivateProfileFloat(szSectionName,"ib_b",   m_fInnerBorderB.eval(-1),szIniFile);	
1168	m_fInnerBorderA		= InternalGetPrivateProfileFloat(szSectionName,"ib_a",   m_fInnerBorderA.eval(-1),szIniFile);	
1169	m_fMvX				= InternalGetPrivateProfileFloat(szSectionName,"nMotionVectorsX",  m_fMvX.eval(-1),szIniFile);
1170	m_fMvY           	= InternalGetPrivateProfileFloat(szSectionName,"nMotionVectorsY",  m_fMvY.eval(-1),szIniFile);
1171	m_fMvDX				= InternalGetPrivateProfileFloat(szSectionName,"mv_dx",  m_fMvDX.eval(-1),szIniFile);
1172	m_fMvDY				= InternalGetPrivateProfileFloat(szSectionName,"mv_dy",  m_fMvDY.eval(-1),szIniFile);
1173	m_fMvL				= InternalGetPrivateProfileFloat(szSectionName,"mv_l",   m_fMvL.eval(-1),szIniFile);
1174	m_fMvR				= InternalGetPrivateProfileFloat(szSectionName,"mv_r",   m_fMvR.eval(-1),szIniFile);	
1175	m_fMvG				= InternalGetPrivateProfileFloat(szSectionName,"mv_g",   m_fMvG.eval(-1),szIniFile);	
1176	m_fMvB				= InternalGetPrivateProfileFloat(szSectionName,"mv_b",   m_fMvB.eval(-1),szIniFile);	
1177	m_fMvA				= (InternalGetPrivateProfileInt (szSectionName,"bMotionVectorsOn",false,szIniFile) == 0) ? 0.0f : 1.0f; // for backwards compatibility
1178	m_fMvA				= InternalGetPrivateProfileFloat(szSectionName,"mv_a",   m_fMvA.eval(-1),szIniFile);	
1179
1180    for (int i=0; i<MAX_CUSTOM_WAVES; i++)
1181    {
1182        m_wave[i].Import(szSectionName, szIniFile, i);
1183    }
1184
1185    for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
1186    {
1187        m_shape[i].Import(szSectionName, szIniFile, i);
1188    }
1189
1190    ReadCode(szSectionName, szIniFile, m_szPerFrameInit, "per_frame_init_");
1191    ReadCode(szSectionName, szIniFile, m_szPerFrameExpr, "per_frame_");
1192    ReadCode(szSectionName, szIniFile, m_szPerPixelExpr, "per_pixel_");
1193
1194    /*
1195	// read in & compile arbitrary expressions
1196    int n2 = 3 + MAX_CUSTOM_WAVES*3 + MAX_CUSTOM_SHAPES*2;
1197	for (int n=0; n<n2; n++)
1198	{
1199		char *pStr;
1200        char prefix[64];
1201		char szLineName[32];
1202		char szLine[8192];
1203		int len;
1204
1205		int line = 1;
1206		int char_pos = 0;
1207		bool bDone = false;
1208
1209		switch(n)
1210		{
1211		case 0: pStr = m_szPerFrameExpr; strcpy(prefix, "per_frame_"); break;
1212		case 1: pStr = m_szPerPixelExpr; strcpy(prefix, "per_pixel_"); break;
1213		case 2: pStr = m_szPerFrameInit; strcpy(prefix, "per_frame_init_"); break;
1214        default:
1215            if (n < 3 + 3*MAX_CUSTOM_WAVES)
1216            {
1217                int i = (n-3) / 3;
1218                int j = (n-3) % 3;
1219                switch(j)
1220                {
1221                case 0: pStr = m_wave[i].m_szInit;     sprintf(prefix, "wave_%d_init",      i); break;
1222                case 1: pStr = m_wave[i].m_szPerFrame; sprintf(prefix, "wave_%d_per_frame", i); break;
1223                case 2: pStr = m_wave[i].m_szPerPoint; sprintf(prefix, "wave_%d_per_point", i); break;
1224                }
1225            }
1226            else
1227            {
1228                int i = (n-3-3*MAX_CUSTOM_WAVES) / 2;
1229                int j = (n-3-3*MAX_CUSTOM_WAVES) % 2;
1230                switch(j)
1231                {
1232                case 0: pStr = m_shape[i].m_szInit;     sprintf(prefix, "shape_%d_init",      i); break;
1233                case 1: pStr = m_shape[i].m_szPerFrame; sprintf(prefix, "shape_%d_per_frame", i); break;
1234                }
1235            }
1236		}
1237		
1238		while (!bDone)
1239		{
1240			sprintf(szLineName, "%s%d", prefix, line); 
1241
1242			InternalGetPrivateProfileString(szSectionName, szLineName, "~!@#$", szLine, 8192, szIniFile);	// fixme
1243			len = strlen(szLine);
1244
1245			if ((strcmp(szLine, "~!@#$")==0) ||		// if the key was missing,
1246				(len >= 8191-char_pos-1))			// or if we're out of space
1247			{
1248				bDone = true;
1249			}
1250			else 
1251			{
1252				sprintf(&pStr[char_pos], "%s%c", szLine, LINEFEED_CONTROL_CHAR);
1253			}
1254		
1255			char_pos += len + 1;
1256			line++;
1257		}
1258		pStr[char_pos++] = 0;	// null-terminate
1259	}
1260    */
1261
1262	RecompileExpressions();
1263}
1264
1265void CState::FreeVarsAndCode()
1266{
1267	// free the compiled expressions
1268	if (m_pf_codehandle)
1269	{
1270		freeCode(m_pf_codehandle);
1271		m_pf_codehandle = NULL;
1272	}
1273	if (m_pp_codehandle)
1274	{
1275		freeCode(m_pp_codehandle);
1276		m_pp_codehandle = NULL;
1277	}
1278
1279    for (int i=0; i<MAX_CUSTOM_WAVES; i++)
1280    {
1281	    if (m_wave[i].m_pf_codehandle)
1282        {
1283            freeCode(m_wave[i].m_pf_codehandle);
1284            m_wave[i].m_pf_codehandle = NULL;
1285        }
1286	    if (m_wave[i].m_pp_codehandle)
1287        {
1288            freeCode(m_wave[i].m_pp_codehandle);
1289            m_wave[i].m_pp_codehandle = NULL;
1290        }
1291    }
1292
1293    for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
1294    {
1295	    if (m_shape[i].m_pf_codehandle)
1296        {
1297            freeCode(m_shape[i].m_pf_codehandle);
1298            m_shape[i].m_pf_codehandle = NULL;
1299        }
1300	    /*if (m_shape[i].m_pp_codehandle)
1301        {
1302            freeCode(m_shape[i].m_pp_codehandle);
1303            m_shape[i].m_pp_codehandle = NULL;
1304        }*/
1305    }
1306
1307	// free our text version of the expressions? - no!
1308	//m_szPerFrameExpr[0] = 0;
1309	//m_szPerPixelExpr[0] = 0;
1310
1311	// free the old variable names & reregister the built-in variables (since they got nuked too)
1312	memset(m_pv_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1313	memset(m_pf_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1314    for (int i=0; i<MAX_CUSTOM_WAVES; i++)
1315    {
1316	    memset(m_wave[i].m_pf_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1317	    memset(m_wave[i].m_pp_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1318    }
1319    for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
1320    {
1321	    memset(m_shape[i].m_pf_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1322	    //memset(m_shape[i].m_pp_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1323    }
1324	RegisterBuiltInVariables(0xFFFFFFFF);
1325}
1326
1327void CState::StripLinefeedCharsAndComments(char *src, char *dest)
1328{
1329	// replaces all LINEFEED_CONTROL_CHAR characters in src with a space in dest;
1330	// also strips out all comments (beginning with '//' and going til end of line).
1331	// Restriction: sizeof(dest) must be >= sizeof(src).
1332
1333	int i2 = 0;
1334	int len = strlen(src);
1335	int bComment = false;
1336	for (int i=0; i<len; i++)		
1337	{
1338		if (bComment)
1339		{
1340			if (src[i] == LINEFEED_CONTROL_CHAR)	
1341				bComment = false;
1342		}
1343		else
1344		{
1345			if ((src[i] =='\\' && src[i+1] =='\\') || (src[i] =='/' && src[i+1] =='/'))
1346				bComment = true;
1347			else if (src[i] != LINEFEED_CONTROL_CHAR)
1348				dest[i2++] = src[i];
1349		}
1350	}
1351	dest[i2] = 0;
1352}
1353
1354void CState::RecompileExpressions(int flags, int bReInit)
1355{
1356    // before we get started, if we redo the init code for the preset, we have to redo
1357    // other things too, because q1-q8 could change.
1358    if ((flags & RECOMPILE_PRESET_CODE) && bReInit)
1359    {
1360        flags |= RECOMPILE_WAVE_CODE;
1361        flags |= RECOMPILE_SHAPE_CODE;
1362    }
1363
1364    // free old code handles
1365    if (flags & RECOMPILE_PRESET_CODE)
1366    {
1367	    if (m_pf_codehandle)
1368	    {
1369		    freeCode(m_pf_codehandle);
1370		    m_pf_codehandle = NULL;
1371	    }
1372	    if (m_pp_codehandle)
1373	    {
1374		    freeCode(m_pp_codehandle);
1375		    m_pp_codehandle = NULL;
1376	    }
1377    }
1378    if (flags & RECOMPILE_WAVE_CODE)
1379    {
1380        for (int i=0; i<MAX_CUSTOM_WAVES; i++)
1381        {
1382		    if (m_wave[i].m_pf_codehandle)
1383		    {
1384			    freeCode(m_wave[i].m_pf_codehandle);
1385			    m_wave[i].m_pf_codehandle = NULL;
1386		    }
1387		    if (m_wave[i].m_pp_codehandle)
1388		    {
1389			    freeCode(m_wave[i].m_pp_codehandle);
1390			    m_wave[i].m_pp_codehandle = NULL;
1391		    }
1392        }
1393    }
1394    if (flags & RECOMPILE_SHAPE_CODE)
1395    {
1396        for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
1397        {
1398		    if (m_shape[i].m_pf_codehandle)
1399		    {
1400			    freeCode(m_shape[i].m_pf_codehandle);
1401			    m_shape[i].m_pf_codehandle = NULL;
1402		    }
1403		    /*if (m_shape[i].m_pp_codehandle)
1404		    {
1405			    freeCode(m_shape[i].m_pp_codehandle);
1406			    m_shape[i].m_pp_codehandle = NULL;
1407		    }*/
1408        }
1409    }
1410
1411    // if we're recompiling init code, clear vars to zero, and re-register built-in variables.
1412	if (bReInit)
1413	{
1414        if (flags & RECOMPILE_PRESET_CODE)
1415        {
1416    		memset(m_pv_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1417		    memset(m_pf_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1418        }
1419        if (flags & RECOMPILE_WAVE_CODE)
1420        {
1421            for (int i=0; i<MAX_CUSTOM_WAVES; i++)
1422            {
1423	            memset(m_wave[i].m_pf_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1424	            memset(m_wave[i].m_pp_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1425            }
1426        }
1427        if (flags & RECOMPILE_SHAPE_CODE)
1428        {
1429            for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
1430            {
1431	            memset(m_shape[i].m_pf_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1432	            //memset(m_shape[i].m_pp_vars, 0, sizeof(varType)*EVAL_MAX_VARS);
1433            }
1434        }
1435		RegisterBuiltInVariables(flags);
1436	}
1437
1438	// QUICK FIX: if the code strings ONLY have spaces and linefeeds, erase them, 
1439	// because for some strange reason this causes errors in compileCode().
1440    int n2 = 3 + MAX_CUSTOM_WAVES*3 + MAX_CUSTOM_SHAPES*2; 
1441	for (int n=0; n<n2; n++)
1442	{
1443		char *pOrig;
1444		switch(n)
1445		{
1446		case 0: pOrig = m_szPerFrameExpr; break;
1447		case 1: pOrig = m_szPerPixelExpr; break;
1448		case 2: pOrig = m_szPerFrameInit; break;
1449        default:
1450            if (n < 3 + 3*MAX_CUSTOM_WAVES)
1451            {
1452                int i = (n-3) / 3;
1453                int j = (n-3) % 3;
1454                switch(j)
1455                {
1456                case 0: pOrig = m_wave[i].m_szInit;     break;
1457                case 1: pOrig = m_wave[i].m_szPerFrame; break;
1458                case 2: pOrig = m_wave[i].m_szPerPoint; break;
1459                }
1460            }
1461            else
1462            {
1463                int i = (n-3-3*MAX_CUSTOM_WAVES) / 2;
1464                int j = (n-3-3*MAX_CUSTOM_WAVES) % 2;
1465                switch(j)
1466                {
1467                case 0: pOrig = m_shape[i].m_szInit;     break;
1468                case 1: pOrig = m_shape[i].m_szPerFrame; break;
1469                }
1470            }
1471		}
1472		char *p = pOrig;
1473		while (*p==' ' || *p==LINEFEED_CONTROL_CHAR) p++;
1474		if (*p == 0) pOrig[0] = 0;
1475	}
1476
1477    // COMPILE NEW CODE.
1478	#ifndef _NO_EXPR_   
1479    {
1480    	// clear any old error msg.:
1481    	g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime();	
1482
1483	    char buf[8192*3];
1484
1485        if (flags & RECOMPILE_PRESET_CODE)
1486        {
1487	        resetVars(m_pf_vars);
1488
1489            // 1. compile AND EXECUTE preset init code
1490		    StripLinefeedCharsAndComments(m_szPerFrameInit, buf);
1491	        if (buf[0] && bReInit)
1492	        {
1493		        int	pf_codehandle_init;	
1494
1495			    if ( ! (pf_codehandle_init = compileCode(buf)))
1496			    {
1497				    sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in 'per_frame_init' code", m_szDesc);
1498				    g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1499
1500				    q_values_after_init_code[0] = 0;
1501				    q_values_after_init_code[1] = 0;
1502				    q_values_after_init_code[2] = 0;
1503				    q_values_after_init_code[3] = 0;
1504				    q_values_after_init_code[4] = 0;
1505				    q_values_after_init_code[5] = 0;
1506				    q_values_after_init_code[6] = 0;
1507				    q_values_after_init_code[7] = 0;
1508                    monitor_after_init_code = 0;
1509			    }
1510			    else
1511			    {
1512				    // now execute the code, save the values of q1..q8, and clean up the code!
1513
1514                    g_plugin->LoadPerFrameEvallibVars(g_plugin->m_pState);
1515
1516				    executeCode(pf_codehandle_init);
1517
1518				    q_values_after_init_code[0] = *var_pf_q1;
1519				    q_values_after_init_code[1] = *var_pf_q2;
1520				    q_values_after_init_code[2] = *var_pf_q3;
1521				    q_values_after_init_code[3] = *var_pf_q4;
1522				    q_values_after_init_code[4] = *var_pf_q5;
1523				    q_values_after_init_code[5] = *var_pf_q6;
1524				    q_values_after_init_code[6] = *var_pf_q7;
1525				    q_values_after_init_code[7] = *var_pf_q8;
1526                    monitor_after_init_code = *var_pf_monitor;
1527
1528				    freeCode(pf_codehandle_init);
1529				    pf_codehandle_init = NULL;
1530			    }
1531	        }
1532
1533            // 2. compile preset per-frame code
1534            StripLinefeedCharsAndComments(m_szPerFrameExpr, buf);
1535	        if (buf[0])
1536	        {
1537			    if ( ! (m_pf_codehandle = compileCode(buf)))
1538			    {
1539				    sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in 'per_frame' code", m_szDesc);
1540				    g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1541			    }
1542	        }
1543
1544	        resetVars(NULL);
1545    	    resetVars(m_pv_vars);
1546
1547            // 3. compile preset per-pixel code
1548		    StripLinefeedCharsAndComments(m_szPerPixelExpr, buf);
1549	        if (buf[0])
1550	        {
1551			    if ( ! (m_pp_codehandle = compileCode(buf)))
1552			    {
1553				    sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in 'per_pixel' code", m_szDesc);
1554				    g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1555			    }
1556	        }
1557	        
1558            resetVars(NULL);
1559        }
1560
1561        if (flags & RECOMPILE_WAVE_CODE)
1562        {
1563            for (int i=0; i<MAX_CUSTOM_WAVES; i++)
1564            {
1565                // 1. compile AND EXECUTE custom waveform init code
1566		        StripLinefeedCharsAndComments(m_wave[i].m_szInit, buf);
1567	            if (buf[0] && bReInit)
1568                {
1569                    resetVars(m_wave[i].m_pf_vars);
1570		            {
1571		                int	codehandle_temp;	
1572			            if ( ! (codehandle_temp = compileCode(buf)))
1573			            {
1574				            sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in wave %d init code", m_szDesc, i);
1575				            g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1576
1577                            *m_wave[i].var_pf_q1 = q_values_after_init_code[0];
1578                            *m_wave[i].var_pf_q2 = q_values_after_init_code[1];
1579                            *m_wave[i].var_pf_q3 = q_values_after_init_code[2];
1580                            *m_wave[i].var_pf_q4 = q_values_after_init_code[3];
1581                            *m_wave[i].var_pf_q5 = q_values_after_init_code[4];
1582                            *m_wave[i].var_pf_q6 = q_values_after_init_code[5];
1583                            *m_wave[i].var_pf_q7 = q_values_after_init_code[6];
1584                            *m_wave[i].var_pf_q8 = q_values_after_init_code[7];
1585				            m_wave[i].t_values_after_init_code[0] = 0;
1586				            m_wave[i].t_values_after_init_code[1] = 0;
1587				            m_wave[i].t_values_after_init_code[2] = 0;
1588				            m_wave[i].t_values_after_init_code[3] = 0;
1589				            m_wave[i].t_values_after_init_code[4] = 0;
1590				            m_wave[i].t_values_after_init_code[5] = 0;
1591				            m_wave[i].t_values_after_init_code[6] = 0;
1592				            m_wave[i].t_values_after_init_code[7] = 0;
1593			            }
1594			            else
1595			            {
1596				            // now execute the code, save the values of q1..q8, and clean up the code!
1597                    
1598                            g_plugin->LoadCustomWavePerFrameEvallibVars(g_plugin->m_pState, i);
1599
1600				            executeCode(codehandle_temp);
1601
1602				            m_wave[i].t_values_after_init_code[0] = *m_wave[i].var_pf_t1;
1603				            m_wave[i].t_values_after_init_code[1] = *m_wave[i].var_pf_t2;
1604				            m_wave[i].t_values_after_init_code[2] = *m_wave[i].var_pf_t3;
1605				            m_wave[i].t_values_after_init_code[3] = *m_wave[i].var_pf_t4;
1606				            m_wave[i].t_values_after_init_code[4] = *m_wave[i].var_pf_t5;
1607				            m_wave[i].t_values_after_init_code[5] = *m_wave[i].var_pf_t6;
1608				            m_wave[i].t_values_after_init_code[6] = *m_wave[i].var_pf_t7;
1609				            m_wave[i].t_values_after_init_code[7] = *m_wave[i].var_pf_t8;
1610
1611				            freeCode(codehandle_temp);
1612				            codehandle_temp = NULL;
1613			            }
1614		            }
1615                    resetVars(NULL);
1616                }
1617
1618                // 2. compile custom waveform per-frame code
1619		        StripLinefeedCharsAndComments(m_wave[i].m_szPerFrame, buf);
1620	            if (buf[0])
1621                {
1622                    resetVars(m_wave[i].m_pf_vars);
1623			        if ( ! (m_wave[i].m_pf_codehandle = compileCode(buf)))
1624			        {
1625				        sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in wave %d per-frame code", m_szDesc, i);
1626				        g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1627			        }
1628                    resetVars(NULL);
1629                }
1630
1631                // 3. compile custom waveform per-point code
1632		        StripLinefeedCharsAndComments(m_wave[i].m_szPerPoint, buf);
1633	            if (buf[0])
1634                {
1635                    resetVars(m_wave[i].m_pp_vars);
1636			        if ( ! (m_wave[i].m_pp_codehandle = compileCode(buf)))
1637			        {
1638				        sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in wave %d per-point code", m_szDesc, i);
1639				        g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1640			        }
1641                    resetVars(NULL);
1642                }
1643            }
1644        }
1645
1646        if (flags & RECOMPILE_SHAPE_CODE)
1647        {
1648            for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
1649            {
1650                // 1. compile AND EXECUTE custom shape init code
1651		        StripLinefeedCharsAndComments(m_shape[i].m_szInit, buf);
1652	            if (buf[0] && bReInit)
1653                {
1654                    resetVars(m_shape[i].m_pf_vars);
1655		            #ifndef _NO_EXPR_
1656		            {
1657		                int	codehandle_temp;	
1658			            if ( ! (codehandle_temp = compileCode(buf)))
1659			            {
1660				            sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in shape %d init code", m_szDesc, i);
1661				            g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1662
1663                            *m_shape[i].var_pf_q1 = q_values_after_init_code[0];
1664                            *m_shape[i].var_pf_q2 = q_values_after_init_code[1];
1665                            *m_shape[i].var_pf_q3 = q_values_after_init_code[2];
1666                            *m_shape[i].var_pf_q4 = q_values_after_init_code[3];
1667                            *m_shape[i].var_pf_q5 = q_values_after_init_code[4];
1668                            *m_shape[i].var_pf_q6 = q_values_after_init_code[5];
1669                            *m_shape[i].var_pf_q7 = q_values_after_init_code[6];
1670                            *m_shape[i].var_pf_q8 = q_values_after_init_code[7];
1671				            m_shape[i].t_values_after_init_code[0] = 0;
1672				            m_shape[i].t_values_after_init_code[1] = 0;
1673				            m_shape[i].t_values_after_init_code[2] = 0;
1674				            m_shape[i].t_values_after_init_code[3] = 0;
1675				            m_shape[i].t_values_after_init_code[4] = 0;
1676				            m_shape[i].t_values_after_init_code[5] = 0;
1677				            m_shape[i].t_values_after_init_code[6] = 0;
1678				            m_shape[i].t_values_after_init_code[7] = 0;
1679			            }
1680			            else
1681			            {
1682				            // now execute the code, save the values of q1..q8, and clean up the code!
1683                    
1684                            g_plugin->LoadCustomShapePerFrameEvallibVars(g_plugin->m_pState, i);
1685
1686				            executeCode(codehandle_temp);
1687
1688                            m_shape[i].t_values_after_init_code[0] = *m_shape[i].var_pf_t1;
1689				            m_shape[i].t_values_after_init_code[1] = *m_shape[i].var_pf_t2;
1690				            m_shape[i].t_values_after_init_code[2] = *m_shape[i].var_pf_t3;
1691				            m_shape[i].t_values_after_init_code[3] = *m_shape[i].var_pf_t4;
1692				            m_shape[i].t_values_after_init_code[4] = *m_shape[i].var_pf_t5;
1693				            m_shape[i].t_values_after_init_code[5] = *m_shape[i].var_pf_t6;
1694				            m_shape[i].t_values_after_init_code[6] = *m_shape[i].var_pf_t7;
1695				            m_shape[i].t_values_after_init_code[7] = *m_shape[i].var_pf_t8;
1696
1697				            freeCode(codehandle_temp);
1698				            codehandle_temp = NULL;
1699			            }
1700		            }
1701		            #endif
1702                    resetVars(NULL);
1703                }
1704
1705                // 2. compile custom shape per-frame code
1706		        StripLinefeedCharsAndComments(m_shape[i].m_szPerFrame, buf);
1707	            if (buf[0])
1708                {
1709                    resetVars(m_shape[i].m_pf_vars);
1710		            #ifndef _NO_EXPR_
1711			            if ( ! (m_shape[i].m_pf_codehandle = compileCode(buf)))
1712			            {
1713				            sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in shape %d per-frame code", m_szDesc, i);
1714				            g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1715			            }
1716		            #endif
1717                    resetVars(NULL);
1718                }
1719
1720                /*
1721                // 3. compile custom shape per-point code
1722		        StripLinefeedCharsAndComments(m_shape[i].m_szPerPoint, buf);
1723	            if (buf[0])
1724                {
1725                    resetVars(m_shape[i].m_pp_vars);
1726		            #ifndef _NO_EXPR_
1727			            if ( ! (m_shape[i].m_pp_codehandle = compileCode(buf)))
1728			            {
1729				            sprintf(g_plugin->m_szUserMessage, "warning: preset \"%s\": error in shape %d per-point code", m_szDesc, i);
1730				            g_plugin->m_fShowUserMessageUntilThisTime = g_plugin->GetTime() + 6.0f;
1731			            }
1732		            #endif
1733                    resetVars(NULL);
1734                }
1735                */
1736            }
1737        }
1738    }
1739    #endif
1740}
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752CBlendableFloat::CBlendableFloat()
1753{
1754	m_bBlending  = false;
1755}
1756
1757CBlendableFloat::~CBlendableFloat()
1758{
1759}
1760
1761//--------------------------------------------------------------------------------
1762
1763float CBlendableFloat::eval(float fTime)
1764{
1765	if (fTime < 0)
1766	{
1767		return val;
1768	}
1769
1770	if (m_bBlending && (fTime > m_fBlendStartTime + m_fBlendDuration) || (fTime < m_fBlendStartTime))
1771	{
1772		m_bBlending = false;
1773	}
1774
1775	if (!m_bBlending)
1776	{
1777		return val;
1778	}
1779	else
1780	{
1781		float mix = (fTime - m_fBlendStartTime) / m_fBlendDuration;
1782		return (m_fBlendFrom*(1.0f - mix) + val*mix);
1783	}
1784}
1785
1786//--------------------------------------------------------------------------------
1787
1788void CBlendableFloat::StartBlendFrom(CBlendableFloat *f_from, float fAnimTime, float fDuration)
1789{
1790	if (fDuration < 0.001f)
1791		return;
1792
1793	m_fBlendFrom		= f_from->eval(fAnimTime);
1794	m_bBlending			= true;
1795	m_fBlendStartTime	= fAnimTime;
1796	m_fBlendDuration	= fDuration;
1797}