1 /*
2   LICENSE
3   -------
4 Copyright 2005-2013 Nullsoft, Inc.
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9 
10   * Redistributions of source code must retain the above copyright notice,
11     this list of conditions and the following disclaimer.
12 
13   * Redistributions in binary form must reproduce the above copyright notice,
14     this list of conditions and the following disclaimer in the documentation
15     and/or other materials provided with the distribution.
16 
17   * Neither the name of Nullsoft nor the names of its contributors may be used to
18     endorse or promote products derived from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #ifndef _MILKDROP_STATE_
31 #define _MILKDROP_STATE_ 1
32 
33 #include <memory.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include "gstring.h"
37 #include "texmgr.h"
38 
39 #include <d3dx9math.h> // for D3DXVECTOR3
40 
41 //#include "evallib/eval.h"
42 #include "../ns-eel2/ns-eel.h"
43 #include "md_defines.h"
44 
45 // flags for CState::RecompileExpressions():
46 #define RECOMPILE_PRESET_CODE  1
47 #define RECOMPILE_WAVE_CODE    2
48 #define RECOMPILE_SHAPE_CODE   4
49 
50 #define NUM_Q_VAR 32
51 #define NUM_T_VAR 8
52 
53 #define MAX_BIGSTRING_LEN    32768
54 
55 class CBlendableFloat
56 {
57 public:
58 	CBlendableFloat();
59 	~CBlendableFloat();
60 
61 	float operator = (float f) {
62 		val = f;
63 		m_bBlending = false;
64         return val;
65 	};
66 	float operator *= (float f) {
67 		val *= f;
68 		m_bBlending = false;
69         return val;
70 	};
71 	float operator /= (float f) {
72 		val /= f;
73 		m_bBlending = false;
74         return val;
75 	};
76 	float operator -= (float f) {
77 		val -= f;
78 		m_bBlending = false;
79         return val;
80 	};
81 	float operator += (float f) {
82 		val += f;
83 		m_bBlending = false;
84         return val;
85 	};
86 
87 	float eval(float fTime);	// call this from animation code.  if fTime < 0, it will return unblended 'val'.
88 	void  StartBlendFrom(CBlendableFloat *f_from, float fAnimTime, float fDuration);
89 
90 protected:
91 	float val;
92 	bool  m_bBlending;
93 	float m_fBlendStartTime;
94 	float m_fBlendDuration;
95 	float m_fBlendFrom;
96 };
97 
98 class CShape
99 {
100 public:
101     int  Import(FILE* f, const wchar_t* szFile, int i);
102     int  Export(FILE* f, const wchar_t* szFile, int i);
103 
104     int   enabled;
105     int   sides;
106     int   additive;
107     int   thickOutline;
108     int   textured;
109     int   instances;
110     float x,y,rad,ang;
111     float r,g,b,a;
112     float r2,g2,b2,a2;
113     float border_r,border_g,border_b,border_a;
114     float tex_ang, tex_zoom;
115 
116     char  m_szInit[MAX_BIGSTRING_LEN]; // note: only executed once -> don't need to save codehandle
117     char  m_szPerFrame[MAX_BIGSTRING_LEN];
118     //char  m_szPerPoint[MAX_BIGSTRING_LEN];
119     NSEEL_CODEHANDLE m_pf_codehandle;
120     //int   m_pp_codehandle;
121 
122 
123 	// for per-frame expression evaluation:
124 		NSEEL_VMCTX m_pf_eel;
125 	double *var_pf_time, *var_pf_fps;
126 	double *var_pf_frame;
127 	double *var_pf_progress;
128 	//double *var_pf_q1, *var_pf_q2, *var_pf_q3, *var_pf_q4, *var_pf_q5, *var_pf_q6, *var_pf_q7, *var_pf_q8;
129 	//double *var_pf_t1, *var_pf_t2, *var_pf_t3, *var_pf_t4, *var_pf_t5, *var_pf_t6, *var_pf_t7, *var_pf_t8;
130     double* var_pf_q[NUM_Q_VAR];
131     double* var_pf_t[NUM_T_VAR];
132 	double *var_pf_bass, *var_pf_mid, *var_pf_treb, *var_pf_bass_att, *var_pf_mid_att, *var_pf_treb_att;
133 	double *var_pf_r, *var_pf_g, *var_pf_b, *var_pf_a;
134 	double *var_pf_r2, *var_pf_g2, *var_pf_b2, *var_pf_a2;
135 	double *var_pf_border_r, *var_pf_border_g, *var_pf_border_b, *var_pf_border_a;
136     double *var_pf_x, *var_pf_y, *var_pf_rad, *var_pf_ang;
137     double *var_pf_sides, *var_pf_textured, *var_pf_additive, *var_pf_thick, *var_pf_instances, *var_pf_instance;
138     double *var_pf_tex_zoom, *var_pf_tex_ang;
139 
140 	// for per-point expression evaluation:
141     /*
142 		NSEEL_VMCTX m_pp_eel;
143 	double *var_pp_time, *var_pp_fps;
144 	double *var_pp_frame;
145 	double *var_pp_progress;
146 	double *var_pp_q1, *var_pp_q2, *var_pp_q3, *var_pp_q4, *var_pp_q5, *var_pp_q6, *var_pp_q7, *var_pp_q8;
147 	double *var_pp_t1, *var_pp_t2, *var_pp_t3, *var_pp_t4, *var_pp_t5, *var_pp_t6, *var_pp_t7, *var_pp_t8;
148 	double *var_pp_bass, *var_pp_mid, *var_pp_treb, *var_pp_bass_att, *var_pp_mid_att, *var_pp_treb_att;
149 	double *var_pp_r, *var_pp_g, *var_pp_b, *var_pp_a;
150 	double *var_pp_r2, *var_pp_g2, *var_pp_b2, *var_pp_a2;
151 	double *var_pp_border_r, *var_pp_border_g, *var_pp_border_b, *var_pp_border_a;
152     double *var_pp_x, *var_pp_y, *var_pp_rad, *var_pp_ang, *var_pp_sides;
153     */
154 
155 	double t_values_after_init_code[NUM_T_VAR];
156 };
157 
158 class CWave
159 {
160 public:
161     int  Import(FILE* f, const wchar_t *szFile, int i);
162     int  Export(FILE* f, const wchar_t* szFile, int i);
163 
164     int   enabled;
165     int   samples;
166     int   sep;
167     float scaling;
168     float smoothing;
169     float x,y,r,g,b,a;
170     int   bSpectrum;
171     int   bUseDots;
172     int   bDrawThick;
173     int   bAdditive;
174 
175     char  m_szInit[MAX_BIGSTRING_LEN]; // note: only executed once -> don't need to save codehandle
176     char  m_szPerFrame[MAX_BIGSTRING_LEN];
177     char  m_szPerPoint[MAX_BIGSTRING_LEN];
178     NSEEL_CODEHANDLE   m_pf_codehandle;
179     NSEEL_CODEHANDLE   m_pp_codehandle;
180 
181 	// for per-frame expression evaluation:
182 		NSEEL_VMCTX m_pf_eel;
183 	double *var_pf_time, *var_pf_fps;
184 	double *var_pf_frame;
185 	double *var_pf_progress;
186 	//double *var_pf_q1, *var_pf_q2, *var_pf_q3, *var_pf_q4, *var_pf_q5, *var_pf_q6, *var_pf_q7, *var_pf_q8;
187 	//double *var_pf_t1, *var_pf_t2, *var_pf_t3, *var_pf_t4, *var_pf_t5, *var_pf_t6, *var_pf_t7, *var_pf_t8;
188     double* var_pf_q[NUM_Q_VAR];
189     double* var_pf_t[NUM_T_VAR];
190 	double *var_pf_bass, *var_pf_mid, *var_pf_treb, *var_pf_bass_att, *var_pf_mid_att, *var_pf_treb_att;
191 	double *var_pf_r, *var_pf_g, *var_pf_b, *var_pf_a;
192     double *var_pf_samples;
193 
194 	// for per-point expression evaluation:
195 		NSEEL_VMCTX m_pp_eel;
196 	double *var_pp_time, *var_pp_fps;
197 	double *var_pp_frame;
198 	double *var_pp_progress;
199 	//double *var_pp_q1, *var_pp_q2, *var_pp_q3, *var_pp_q4, *var_pp_q5, *var_pp_q6, *var_pp_q7, *var_pp_q8;
200 	//double *var_pp_t1, *var_pp_t2, *var_pp_t3, *var_pp_t4, *var_pp_t5, *var_pp_t6, *var_pp_t7, *var_pp_t8;
201     double* var_pp_q[NUM_Q_VAR];
202     double* var_pp_t[NUM_T_VAR];
203 	double *var_pp_bass, *var_pp_mid, *var_pp_treb, *var_pp_bass_att, *var_pp_mid_att, *var_pp_treb_att;
204     double *var_pp_sample, *var_pp_value1, *var_pp_value2;
205 	double *var_pp_x, *var_pp_y, *var_pp_r, *var_pp_g, *var_pp_b, *var_pp_a;
206 
207 	double t_values_after_init_code[NUM_T_VAR];
208 };
209 
210 typedef struct
211 {
212 	int   type;
213 	int   in_var;
214 	int   out_var;
215 	float constant;
216 	float min;
217 	float max;
218 	float in_scale;
219 	float amp;		// for sine functions
220 	float freq;		// for sine functions
221 	float freq2;	// for sine functions
222 	float phase;	// for sine functions
223 	float phase2;	// for sine functions
224 } td_modifier;
225 
226 //#define MAX_EVALS 8
227 
228 #define INVALID_PRESET_DESC L"<no description>"  // this should contain invalid filename chars, so there is never a conflict...
229 
230 #define STATE_GENERAL 1  // and postproc (old presets) or blur, etc. (new presets)
231 #define STATE_MOTION  2  // and equations
232 #define STATE_WAVE    4  // waves, shapes, motion vectors
233 #define STATE_WARP    8
234 #define STATE_COMP   16
235 #define STATE_ALL   (32-1)
236 
237 #define CUR_MILKDROP_PRESET_VERSION 201
238 // 200: milkdrop 2
239 // 201: instead of just 1 variable for shader version, it tracks 2 (comp and warp) separately.
240 
241 class CState
242 {
243 public:
244 	CState();
245 	~CState();
246 
247 	void Default(DWORD ApplyFlags=STATE_ALL);
248 	void Randomize(int nMode);
249 	void StartBlendFrom(CState *s_from, float fAnimTime, float fTimespan);
250 	bool Import(const wchar_t *szIniFile, float fTime, CState* pOldState, DWORD ApplyFlags=STATE_ALL);
251 	bool Export(const wchar_t *szIniFile);
252 	void RecompileExpressions(int flags=0xFFFFFFFF, int bReInit=1);
253     void GenDefaultWarpShader();
254     void GenDefaultCompShader();
255 
256 	wchar_t m_szDesc[512];		// this is just the filename, without a path or extension.
257 	//char m_szSection[256];
258 
259     int                 m_nMinPSVersion;  // the min of the warp & comp values...
260     int                 m_nMaxPSVersion;  // the max of the warp & comp values...
261 	int                 m_nWarpPSVersion;  // 0 = milkdrop 1 era (no PS), 2 = ps_2_0, 3 = ps_3_0
262 	int                 m_nCompPSVersion;  // 0 = milkdrop 1 era (no PS), 2 = ps_2_0, 3 = ps_3_0
263 	float				m_fRating;		// 0..5
264 	// post-processing:
265 	CBlendableFloat		m_fGammaAdj;	// +0 -> +1.0 (double), +2.0 (triple)...
266 	CBlendableFloat		m_fVideoEchoZoom;
267 	CBlendableFloat 	m_fVideoEchoAlpha;
268 	float				m_fVideoEchoAlphaOld;
269 	int					m_nVideoEchoOrientation;
270 	int					m_nVideoEchoOrientationOld;
271 
272 	// fps-dependant:
273 	CBlendableFloat		m_fDecay;			// 1.0 = none, 0.95 = heavy decay
274 
275 	// other:
276 	int					m_nWaveMode;
277 	int					m_nOldWaveMode;
278 	bool				m_bAdditiveWaves;
279 	CBlendableFloat		m_fWaveAlpha;
280 	CBlendableFloat		m_fWaveScale;
281 	CBlendableFloat		m_fWaveSmoothing;
282 	bool				m_bWaveDots;
283 	bool                m_bWaveThick;
284 	CBlendableFloat		m_fWaveParam;		// -1..1; 0 is normal
285 	bool				m_bModWaveAlphaByVolume;
286 	CBlendableFloat		m_fModWaveAlphaStart;	// when relative volume hits this level, alpha -> 0
287 	CBlendableFloat		m_fModWaveAlphaEnd;		// when relative volume hits this level, alpha -> 1
288 	float				m_fWarpAnimSpeed;	// 1.0 = normal, 2.0 = double, 0.5 = half, etc.
289 	CBlendableFloat		m_fWarpScale;
290 	CBlendableFloat		m_fZoomExponent;
291 	CBlendableFloat		m_fShader;			// 0 = no color shader, 1 = full color shader
292 	bool				m_bMaximizeWaveColor;
293 	bool				m_bTexWrap;
294 	bool				m_bDarkenCenter;
295 	bool				m_bRedBlueStereo;
296 	bool				m_bBrighten;
297 	bool				m_bDarken;
298 	bool				m_bSolarize;
299 	bool				m_bInvert;
300 	/*
301 	bool				m_bPlates;
302 	int					m_nPlates;
303 	CBlendableFloat		m_fPlateAlpha;		// 0 = off, 0.1 = barely visible, 1.0 = solid
304 	CBlendableFloat		m_fPlateR;
305 	CBlendableFloat		m_fPlateG;
306 	CBlendableFloat		m_fPlateB;
307 	CBlendableFloat		m_fPlateWidth;		// 1.0=normal, 2.0=double, etc.
308 	CBlendableFloat		m_fPlateLength;		// 1.0=normal, 2.0=double, etc.
309 	float				m_fPlateSpeed;		// 1.0=normal, 2.0=double, etc.
310 	bool				m_bPlatesAdditive;
311 	*/
312 
313 	// map controls:
314 	CBlendableFloat		m_fZoom;
315 	CBlendableFloat		m_fRot;
316 	CBlendableFloat		m_fRotCX;
317 	CBlendableFloat		m_fRotCY;
318 	CBlendableFloat		m_fXPush;
319 	CBlendableFloat		m_fYPush;
320 	CBlendableFloat		m_fWarpAmount;
321 	CBlendableFloat		m_fStretchX;
322 	CBlendableFloat		m_fStretchY;
323 	CBlendableFloat		m_fWaveR;
324 	CBlendableFloat		m_fWaveG;
325 	CBlendableFloat		m_fWaveB;
326 	CBlendableFloat		m_fWaveX;
327 	CBlendableFloat		m_fWaveY;
328 	CBlendableFloat		m_fOuterBorderSize;
329 	CBlendableFloat		m_fOuterBorderR;
330 	CBlendableFloat		m_fOuterBorderG;
331 	CBlendableFloat		m_fOuterBorderB;
332 	CBlendableFloat		m_fOuterBorderA;
333 	CBlendableFloat		m_fInnerBorderSize;
334 	CBlendableFloat		m_fInnerBorderR;
335 	CBlendableFloat		m_fInnerBorderG;
336 	CBlendableFloat		m_fInnerBorderB;
337 	CBlendableFloat		m_fInnerBorderA;
338 	CBlendableFloat		m_fMvX;
339 	CBlendableFloat		m_fMvY;
340 	CBlendableFloat		m_fMvDX;
341 	CBlendableFloat		m_fMvDY;
342 	CBlendableFloat		m_fMvL;
343 	CBlendableFloat		m_fMvR;
344 	CBlendableFloat		m_fMvG;
345 	CBlendableFloat		m_fMvB;
346 	CBlendableFloat		m_fMvA;
347 	CBlendableFloat		m_fBlur1Min;
348 	CBlendableFloat		m_fBlur2Min;
349 	CBlendableFloat		m_fBlur3Min;
350 	CBlendableFloat		m_fBlur1Max;
351 	CBlendableFloat		m_fBlur2Max;
352 	CBlendableFloat		m_fBlur3Max;
353 	CBlendableFloat		m_fBlur1EdgeDarken;
354 
355     CShape              m_shape[MAX_CUSTOM_SHAPES];
356     CWave               m_wave[MAX_CUSTOM_WAVES];
357 
358     // some random stuff for driving shaders:
359     void         RandomizePresetVars();
360     D3DXVECTOR4  m_rand_preset; // 4 random floats (0..1); randomized @ preset load; fed to pixel shaders.  --FIXME (blending)
361     D3DXVECTOR3  m_xlate[20];
362     D3DXVECTOR3  m_rot_base[20];
363     D3DXVECTOR3  m_rot_speed[20];
364 
365 	//COscillator			m_waveR;
366 	//COscillator			m_waveG;
367 	//COscillator			m_waveB;
368 	//COscillator			m_wavePosX;		// 0 = centered
369 	//COscillator			m_wavePosY;		// 0 = centered
370 
371 	// for arbitrary function evaluation:
372     NSEEL_CODEHANDLE				m_pf_codehandle;
373     NSEEL_CODEHANDLE				m_pp_codehandle;
374     char			m_szPerFrameInit[MAX_BIGSTRING_LEN];
375     char			m_szPerFrameExpr[MAX_BIGSTRING_LEN];
376     char			m_szPerPixelExpr[MAX_BIGSTRING_LEN];
377     char            m_szWarpShadersText[MAX_BIGSTRING_LEN]; // pixel shader code
378     char            m_szCompShadersText[MAX_BIGSTRING_LEN]; // pixel shader code
379 	void			FreeVarsAndCode(bool bFree = true);
380 	void			RegisterBuiltInVariables(int flags);
381 	void			StripLinefeedCharsAndComments(char *src, char *dest);
382 
383 	bool  m_bBlending;
384 	float m_fBlendStartTime;
385 	float m_fBlendDuration;
386 	float m_fBlendProgress;	// 0..1; updated every frame based on StartTime and Duration.
387 
388 	// for once-per-frame expression evaluation: [although, these vars are also shared w/preset init expr eval]
389 		NSEEL_VMCTX m_pf_eel;
390     double *var_pf_zoom, *var_pf_zoomexp, *var_pf_rot, *var_pf_warp, *var_pf_cx, *var_pf_cy, *var_pf_dx, *var_pf_dy, *var_pf_sx, *var_pf_sy;
391 	double *var_pf_time, *var_pf_fps;
392 	double *var_pf_bass, *var_pf_mid, *var_pf_treb, *var_pf_bass_att, *var_pf_mid_att, *var_pf_treb_att;
393 	double *var_pf_wave_a, *var_pf_wave_r, *var_pf_wave_g, *var_pf_wave_b, *var_pf_wave_x, *var_pf_wave_y, *var_pf_wave_mystery, *var_pf_wave_mode;
394 	double *var_pf_decay;
395 	double *var_pf_frame;
396 	//double *var_pf_q1, *var_pf_q2, *var_pf_q3, *var_pf_q4, *var_pf_q5, *var_pf_q6, *var_pf_q7, *var_pf_q8;
397     double* var_pf_q[NUM_Q_VAR];
398 	double *var_pf_progress;
399 	double *var_pf_ob_size, *var_pf_ob_r, *var_pf_ob_g, *var_pf_ob_b, *var_pf_ob_a;
400 	double *var_pf_ib_size, *var_pf_ib_r, *var_pf_ib_g, *var_pf_ib_b, *var_pf_ib_a;
401 	double *var_pf_mv_x;
402 	double *var_pf_mv_y;
403 	double *var_pf_mv_dx;
404 	double *var_pf_mv_dy;
405 	double *var_pf_mv_l;
406 	double *var_pf_mv_r;
407 	double *var_pf_mv_g;
408 	double *var_pf_mv_b;
409 	double *var_pf_mv_a;
410 	double *var_pf_monitor;
411 	double *var_pf_echo_zoom, *var_pf_echo_alpha, *var_pf_echo_orient;
412     // new in v1.04:
413 	double *var_pf_wave_usedots, *var_pf_wave_thick, *var_pf_wave_additive, *var_pf_wave_brighten;
414     double *var_pf_darken_center, *var_pf_gamma, *var_pf_wrap;
415     double *var_pf_invert, *var_pf_brighten, *var_pf_darken, *var_pf_solarize;
416     double *var_pf_meshx, *var_pf_meshy;
417     double *var_pf_pixelsx, *var_pf_pixelsy;
418     double *var_pf_aspectx, *var_pf_aspecty;
419     double *var_pf_blur1min;
420     double *var_pf_blur2min;
421     double *var_pf_blur3min;
422     double *var_pf_blur1max;
423     double *var_pf_blur2max;
424     double *var_pf_blur3max;
425     double *var_pf_blur1_edge_darken;
426 
427 	// for per-vertex expression evaluation:
428 		NSEEL_VMCTX m_pv_eel;
429     double *var_pv_zoom, *var_pv_zoomexp, *var_pv_rot, *var_pv_warp, *var_pv_cx, *var_pv_cy, *var_pv_dx, *var_pv_dy, *var_pv_sx, *var_pv_sy;
430 	double *var_pv_time, *var_pv_fps;
431 	double *var_pv_bass, *var_pv_mid, *var_pv_treb, *var_pv_bass_att, *var_pv_mid_att, *var_pv_treb_att;
432 	double *var_pv_x, *var_pv_y, *var_pv_rad, *var_pv_ang;
433 	double *var_pv_frame;
434 	//double *var_pv_q1, *var_pv_q2, *var_pv_q3, *var_pv_q4, *var_pv_q5, *var_pv_q6, *var_pv_q7, *var_pv_q8;
435     double* var_pv_q[NUM_Q_VAR];
436 	double *var_pv_progress;
437     double *var_pv_meshx, *var_pv_meshy;
438     double *var_pv_pixelsx, *var_pv_pixelsy;
439     double *var_pv_aspectx, *var_pv_aspecty;
440 
441 	double q_values_after_init_code[NUM_Q_VAR];
442     double monitor_after_init_code;
443 
GetPresetStartTime()444     float GetPresetStartTime() { return m_fPresetStartTime; }
445     float m_fPresetStartTime;
446 };
447 
448 #endif