aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Visualization
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Visualization
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Visualization')
-rw-r--r--Src/Plugins/Visualization/vis_avs/FRONTEND.H370
-rw-r--r--Src/Plugins/Visualization/vis_avs/LICENSE.TXT24
-rw-r--r--Src/Plugins/Visualization/vis_avs/TIMING.C69
-rw-r--r--Src/Plugins/Visualization/vis_avs/Timing.h32
-rw-r--r--Src/Plugins/Visualization/vis_avs/VIS.H76
-rw-r--r--Src/Plugins/Visualization/vis_avs/ape.h96
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/ape.rc80
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/avs_ape.h110
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/avstut00.avsbin0 -> 485 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/avstut00.cpp294
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsp120
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsw29
-rw-r--r--Src/Plugins/Visualization/vis_avs/apesdk/resource.h19
-rw-r--r--Src/Plugins/Visualization/vis_avs/avs-hilited.pngbin0 -> 1450 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/avs-normal.pngbin0 -> 1449 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/avs-selected.pngbin0 -> 1468 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/avs_eelif.cpp235
-rw-r--r--Src/Plugins/Visualization/vis_avs/avs_eelif.h59
-rw-r--r--Src/Plugins/Visualization/vis_avs/bpm.cpp711
-rw-r--r--Src/Plugins/Visualization/vis_avs/bpm.h56
-rw-r--r--Src/Plugins/Visualization/vis_avs/bump_lig.bin22
-rw-r--r--Src/Plugins/Visualization/vis_avs/cfgwin.cpp1918
-rw-r--r--Src/Plugins/Visualization/vis_avs/cfgwnd.h47
-rw-r--r--Src/Plugins/Visualization/vis_avs/color_mo.bin11
-rw-r--r--Src/Plugins/Visualization/vis_avs/draw.cpp1476
-rw-r--r--Src/Plugins/Visualization/vis_avs/draw.h42
-rw-r--r--Src/Plugins/Visualization/vis_avs/dyn_dist.bin12
-rw-r--r--Src/Plugins/Visualization/vis_avs/dyn_move.bin1
-rw-r--r--Src/Plugins/Visualization/vis_avs/dyn_shift.bin7
-rw-r--r--Src/Plugins/Visualization/vis_avs/effect_l.bin6
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/BISON.EXEbin0 -> 91787 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/CAL_TAB.C576
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/Compiler.c747
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/Compiler.h47
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/GETTOK.C6
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LEX.EXEbin0 -> 28277 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LEX.H53
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LEXGET.C20
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LEXSWI.C23
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LEXTAB.C260
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LLSAVE.C6
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/LMOVB.C29
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/Scan.l54
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/YYLEX.C143
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.HAI334
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.SIM577
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/cal.y155
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/cal_tab.h13
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/cfunc.c901
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/eval.c238
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/eval.h41
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/makel.bat1
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/makey.bat2
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/new_eval_stuff.zipbin0 -> 23625 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/evallib/readme.txt84
-rw-r--r--Src/Plugins/Visualization/vis_avs/ff_ipc.h104
-rw-r--r--Src/Plugins/Visualization/vis_avs/help_1.bin32
-rw-r--r--Src/Plugins/Visualization/vis_avs/help_2.bin32
-rw-r--r--Src/Plugins/Visualization/vis_avs/help_3.bin133
-rw-r--r--Src/Plugins/Visualization/vis_avs/help_4.bin6
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/LD32.H964
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/laser.cpp149
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/laserline.cpp218
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/laserline.h55
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/ld32.c187
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/linelist.cpp107
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/linelist.h57
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/rl_beathold.cpp165
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/rl_bren.cpp183
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/rl_cones.cpp363
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/rl_line.cpp338
-rw-r--r--Src/Plugins/Visualization/vis_avs/laser/rl_trans.cpp338
-rw-r--r--Src/Plugins/Visualization/vis_avs/linedraw.cpp261
-rw-r--r--Src/Plugins/Visualization/vis_avs/main.cpp604
-rw-r--r--Src/Plugins/Visualization/vis_avs/matrix.cpp74
-rw-r--r--Src/Plugins/Visualization/vis_avs/movement.bin5
-rw-r--r--Src/Plugins/Visualization/vis_avs/peices.bmpbin0 -> 19844 bytes
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_avi.cpp383
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_blit.cpp557
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_blur.cpp883
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_bpm.cpp285
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_bright.cpp506
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_bspin.cpp315
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_bump.cpp562
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_chanshift.cpp362
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_clear.cpp231
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_colorfade.cpp357
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_colorreduction.cpp193
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_colorreplace.cpp159
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_comment.cpp116
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_contrast.cpp226
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_dcolormod.cpp359
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_ddm.cpp492
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_defs.h739
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_dmove.cpp780
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_dotfnt.cpp324
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_dotgrid.cpp331
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_dotpln.cpp313
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_fadeout.cpp280
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_fastbright.cpp279
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_grain.cpp406
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_interf.cpp525
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_interleave.cpp381
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_invert.cpp186
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_linemode.cpp190
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_list.cpp1401
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_list.h173
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_mirror.cpp385
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_mosaic.cpp299
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_multidelay.cpp440
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_multiplier.cpp365
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_nfclr.cpp233
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_onetone.cpp269
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_oscring.cpp356
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_oscstar.cpp365
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_parts.cpp311
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_picture.cpp372
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_rotblit.cpp327
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_rotstar.cpp271
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_scat.cpp161
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_shift.cpp391
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_simple.cpp427
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_sscope.cpp595
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_stack.cpp338
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_stack.h29
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_stars.cpp402
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_svp.cpp227
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_text.cpp1012
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_timescope.cpp289
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_trans.cpp982
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_transition.cpp632
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_transition.h63
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_unkn.cpp114
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_unkn.h55
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_videodelay.cpp365
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_water.cpp502
-rw-r--r--Src/Plugins/Visualization/vis_avs/r_waterbump.cpp439
-rw-r--r--Src/Plugins/Visualization/vis_avs/reaplay_avs.dsp641
-rw-r--r--Src/Plugins/Visualization/vis_avs/render.cpp141
-rw-r--r--Src/Plugins/Visualization/vis_avs/render.h43
-rw-r--r--Src/Plugins/Visualization/vis_avs/res.rc2329
-rw-r--r--Src/Plugins/Visualization/vis_avs/resource.h665
-rw-r--r--Src/Plugins/Visualization/vis_avs/rlib.cpp458
-rw-r--r--Src/Plugins/Visualization/vis_avs/rlib.h74
-rw-r--r--Src/Plugins/Visualization/vis_avs/supersco.bin18
-rw-r--r--Src/Plugins/Visualization/vis_avs/svp_vis.h136
-rw-r--r--Src/Plugins/Visualization/vis_avs/undo.cpp177
-rw-r--r--Src/Plugins/Visualization/vis_avs/undo.h81
-rw-r--r--Src/Plugins/Visualization/vis_avs/util.cpp536
-rw-r--r--Src/Plugins/Visualization/vis_avs/version.rc240
-rw-r--r--Src/Plugins/Visualization/vis_avs/vis_Avs.dsw29
-rw-r--r--Src/Plugins/Visualization/vis_avs/vis_avs.dsp722
-rw-r--r--Src/Plugins/Visualization/vis_avs/vis_avs.sln24
-rw-r--r--Src/Plugins/Visualization/vis_avs/vis_avs.txt228
-rw-r--r--Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj814
-rw-r--r--Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj.filters397
-rw-r--r--Src/Plugins/Visualization/vis_avs/wa_ipc.h1127
-rw-r--r--Src/Plugins/Visualization/vis_avs/whatsnew.txt233
-rw-r--r--Src/Plugins/Visualization/vis_avs/wnd.cpp1749
-rw-r--r--Src/Plugins/Visualization/vis_avs/wnd.h39
-rw-r--r--Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT1022
-rw-r--r--Src/Plugins/Visualization/vis_milk2/api__vis_milk2.h16
-rw-r--r--Src/Plugins/Visualization/vis_milk2/config.cpp1589
-rw-r--r--Src/Plugins/Visualization/vis_milk2/config2.cpp425
-rw-r--r--Src/Plugins/Visualization/vis_milk2/defines.h223
-rw-r--r--Src/Plugins/Visualization/vis_milk2/desktop_mode.cpp1097
-rw-r--r--Src/Plugins/Visualization/vis_milk2/dxcontext.cpp1419
-rw-r--r--Src/Plugins/Visualization/vis_milk2/dxcontext.h151
-rw-r--r--Src/Plugins/Visualization/vis_milk2/fft.cpp320
-rw-r--r--Src/Plugins/Visualization/vis_milk2/fft.h60
-rw-r--r--Src/Plugins/Visualization/vis_milk2/gstring.h229
-rw-r--r--Src/Plugins/Visualization/vis_milk2/icon_t.h49
-rw-r--r--Src/Plugins/Visualization/vis_milk2/manifest.xml1
-rw-r--r--Src/Plugins/Visualization/vis_milk2/md_defines.h83
-rw-r--r--Src/Plugins/Visualization/vis_milk2/menu.cpp751
-rw-r--r--Src/Plugins/Visualization/vis_milk2/menu.h126
-rw-r--r--Src/Plugins/Visualization/vis_milk2/milkdrop.nsi439
-rw-r--r--Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.dsw29
-rw-r--r--Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.sln24
-rw-r--r--Src/Plugins/Visualization/vis_milk2/milkdropfs.cpp4801
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-ppc-gcc.c1041
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x64-macho.obin0 -> 7505 bytes
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-gcc.c1566
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-msvc.c2463
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-addfuncs.h74
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-int.h227
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel.h155
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-caltab.c553
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-cfunc.c131
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-compiler.c1791
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-eval.c321
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-lextab.c277
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-ram.c320
-rw-r--r--Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-yylex.c163
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin.cpp9653
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin.dsp304
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin.h729
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin.rc1501
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin.vcxproj419
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin.vcxproj.filters164
-rw-r--r--Src/Plugins/Visualization/vis_milk2/plugin_icon.icobin0 -> 7398 bytes
-rw-r--r--Src/Plugins/Visualization/vis_milk2/pluginshell.cpp3693
-rw-r--r--Src/Plugins/Visualization/vis_milk2/pluginshell.h371
-rw-r--r--Src/Plugins/Visualization/vis_milk2/resource.h877
-rw-r--r--Src/Plugins/Visualization/vis_milk2/shell_defines.h76
-rw-r--r--Src/Plugins/Visualization/vis_milk2/state.cpp1961
-rw-r--r--Src/Plugins/Visualization/vis_milk2/state.h448
-rw-r--r--Src/Plugins/Visualization/vis_milk2/support.cpp361
-rw-r--r--Src/Plugins/Visualization/vis_milk2/support.h109
-rw-r--r--Src/Plugins/Visualization/vis_milk2/temp.icobin0 -> 7398 bytes
-rw-r--r--Src/Plugins/Visualization/vis_milk2/texmgr.cpp752
-rw-r--r--Src/Plugins/Visualization/vis_milk2/texmgr.h120
-rw-r--r--Src/Plugins/Visualization/vis_milk2/text1.binbin0 -> 948 bytes
-rw-r--r--Src/Plugins/Visualization/vis_milk2/textmgr.cpp700
-rw-r--r--Src/Plugins/Visualization/vis_milk2/textmgr.h91
-rw-r--r--Src/Plugins/Visualization/vis_milk2/utility.cpp1259
-rw-r--r--Src/Plugins/Visualization/vis_milk2/utility.h164
-rw-r--r--Src/Plugins/Visualization/vis_milk2/version.rc239
-rw-r--r--Src/Plugins/Visualization/vis_milk2/vis.cpp275
-rw-r--r--Src/Plugins/Visualization/vis_milk2/vis.h1
-rw-r--r--Src/Plugins/Visualization/vis_milk2/vms_desktop.libbin0 -> 2520 bytes
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/Svis.cpp892
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/dd.h28
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/ddraw.cpp229
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/license.txt9
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/linedraw.cpp86
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/makepal.cpp96
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/moveframe.cpp609
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/resource.h147
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/scope.cpp200
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/shitdrop.cpp318
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/tinyvis.txt54
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/version.rc239
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/vis_nsfs.rc194
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/vis_nsfs.sln24
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj372
-rw-r--r--Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj.filters53
237 files changed, 97971 insertions, 0 deletions
diff --git a/Src/Plugins/Visualization/vis_avs/FRONTEND.H b/Src/Plugins/Visualization/vis_avs/FRONTEND.H
new file mode 100644
index 00000000..b977d182
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/FRONTEND.H
@@ -0,0 +1,370 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _WAFE_H_
+#define _WAFE_H_
+/*
+** Winamp frontend/plug-in control API documentation v1.0.
+** By Justin Frankel.
+** Copyright (C) 1997-1999, Nullsoft Inc.
+** Last updated: JAN.8.1999.
+**
+** Introduction
+** -----------------------
+** This file describes a means to easily communicate to Winamp
+** via the classic Win32 Message API.
+**
+** These definitions/code assume C/C++. Porting to VB/Delphi shouldn't
+** be too hard.
+**
+** First, you find the HWND of the Winamp main window. From a plug-in
+** you can easily extract this from the plug-in structure (hMainWindow,
+** hwndParent, whatever). For external apps, use:
+**
+** HWND hwnd_winamp = FindWindow("Winamp v1.x",NULL);
+**
+** (note: I know, we're in Winamp 2.x, but it's 1.x for compatibility)
+**
+** Once you have the hwnd_winamp, it's a good idea to check the version
+** number. To do this, you send a WM_WA_IPC message to hwnd_winamp.
+** Note that WM_WA_IPC is defined as Win32's WM_USER.
+**
+** Note that sometimes you might want to use PostMessage instead of
+** SendMessage.
+*/
+
+#define WM_WA_IPC WM_USER
+
+/**************************************************************************/
+
+#define IPC_GETVERSION 0
+
+/*
+** int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
+**
+** Version will be 0x20yx for winamp 2.yx. versions previous to Winamp 2.0
+** typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know.
+**
+** The basic format for sending messages to Winamp is:
+** int result=SendMessage(hwnd_winamp,WM_WA_IPC,command_data,command);
+** (for the version check, command_data is 0).
+*/
+
+
+#define IPC_DELETE 101
+
+/*
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
+**
+** You can use IPC_DELETE to clear Winamp's internal playlist.
+*/
+
+
+#define IPC_STARTPLAY 102
+
+/*
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_STARTPLAY);
+**
+** Using IPC_STARTPLAY is like hitting 'Play' in Winamp, mostly.
+*/
+
+
+#define IPC_ISPLAYING 104
+
+/*
+** int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
+**
+** IPC_ISPLAYING returns the status of playback.
+** If it returns 1, it is playing. if it returns 3, it is paused,
+** if it returns 0, it is not playing.
+*/
+
+
+#define IPC_GETOUTPUTTIME 105
+
+/*
+** int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
+**
+** IPC_GETOUTPUTTIME returns the position in milliseconds of the
+** current song (mode = 0), or the song length, in seconds (mode = 1).
+** Returns -1 if not playing or error.
+*/
+
+
+#define IPC_JUMPTOTIME 106
+
+/* (requires Winamp 1.60+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
+** IPC_JUMPTOTIME sets the position in milliseconds of the
+** current song (approximately).
+** Returns -1 if not playing, 1 on eof, or 0 if successful
+*/
+
+
+#define IPC_WRITEPLAYLIST 120
+
+/* (requires Winamp 1.666+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
+**
+** IPC_WRITEPLAYLIST writes the current playlist to <winampdir>\\Winamp.m3u,
+** and returns the current playlist position.
+** Kinda obsoleted by some of the 2.x new stuff, but still good for when
+** using a front-end (instead of a plug-in)
+*/
+
+
+#define IPC_SETPLAYLISTPOS 121
+
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
+**
+** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'.
+*/
+
+
+#define IPC_SETVOLUME 122
+
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
+**
+** IPC_SETVOLUME sets the volume of Winamp (from 0-255).
+*/
+
+
+#define IPC_SETPANNING 123
+
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING);
+**
+** IPC_SETPANNING sets the panning of Winamp (from 0 (left) to 255 (right)).
+*/
+
+
+#define IPC_GETLISTLENGTH 124
+
+/* (requires Winamp 2.0+)
+** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
+**
+** IPC_GETLISTLENGTH returns the length of the current playlist, in
+** tracks.
+*/
+
+
+#define IPC_SETSKIN 200
+
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
+**
+** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
+** can be the name of a skin, a skin .zip file, with or without path.
+** If path isn't specified, the default search path is the winamp skins
+** directory.
+*/
+
+
+#define IPC_GETSKIN 201
+
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN);
+**
+** IPC_GETSKIN puts the directory where skin bitmaps can be found
+** into skinname_buffer.
+** skinname_buffer must be MAX_PATH characters in length.
+** When using a .zip'd skin file, it'll return a temporary directory
+** where the ZIP was decompressed.
+*/
+
+
+#define IPC_EXECPLUG 202
+
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG);
+**
+** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
+** the format of this string can be:
+** "vis_whatever.dll"
+** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir)
+** "C:\\dir\\vis_whatever.dll,1"
+*/
+
+
+#define IPC_GETPLAYLISTFILE 211
+
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
+**
+** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETPLAYLISTTITLE 212
+
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
+**
+** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETLISTPOS 125
+
+/* (requires Winamp 2.05+)
+** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
+**
+** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST
+** only faster since it doesn't have to write out the list. Heh, silly me.
+*/
+
+
+#define IPC_GETINFO 126
+
+/* (requires Winamp 2.05+)
+** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
+**
+** IPC_GETINFO returns info about the current playing song. The value
+** it returns depends on the value of 'mode'.
+** Mode Meaning
+** ------------------
+** 0 Samplerate (i.e. 44100)
+** 1 Bitrate (i.e. 128)
+** 2 Channels (i.e. 2)
+*/
+
+
+#define IPC_GETEQDATA 127
+
+/* (requires Winamp 2.05+)
+** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+**
+** IPC_GETEQDATA queries the status of the EQ.
+** The value returned depends on what 'pos' is set to:
+** Value Meaning
+** ------------------
+** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
+** 10 The preamp value. 0-63 (+20db - -20db)
+** 11 Enabled. zero if disabled, nonzero if enabled.
+** 12 Autoload. zero if disabled, nonzero if enabled.
+*/
+
+
+#define IPC_SETEQDATA 128
+
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA);
+**
+** IPC_SETEQDATA sets the value of the last position retrieved
+** by IPC_GETEQDATA.
+*/
+
+/**************************************************************************/
+
+/*
+** Some API calls tend to require that you send data via WM_COPYDATA
+** instead of WM_USER. Such as IPC_PLAYFILE:
+*/
+
+#define IPC_PLAYFILE 100
+
+/*
+** COPYDATASTRUCT cds;
+** cds.dwData = IPC_PLAYFILE;
+** cds.lpData = (void *) "file.mp3";
+** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
+**
+** This will play the file "file.mp3".
+**
+*/
+
+
+#define IPC_CHDIR 103
+
+/*
+** COPYDATASTRUCT cds;
+** cds.dwData = IPC_CHDIR;
+** cds.lpData = (void *) "c:\\download";
+** cds.cbData = strlen((char *) cds.lpData)+1; // include space for null char
+** SendMessage(hwnd_winamp,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
+**
+** This will make Winamp change to the directory C:\\download
+**
+*/
+
+
+/**************************************************************************/
+
+/*
+** Finally there are some WM_COMMAND messages that you can use to send
+** Winamp misc commands.
+**
+** To send these, use:
+**
+** SendMessage(hwnd_winamp, WM_COMMAND,command_name,0);
+*/
+
+#define WINAMP_OPTIONS_EQ 40036 // toggles the EQ window
+#define WINAMP_OPTIONS_PLEDIT 40040 // toggles the playlist window
+#define WINAMP_VOLUMEUP 40058 // turns the volume up a little
+#define WINAMP_VOLUMEDOWN 40059 // turns the volume down a little
+#define WINAMP_FFWD5S 40060 // fast forwards 5 seconds
+#define WINAMP_REW5S 40061 // rewinds 5 seconds
+
+// the following are the five main control buttons, with optionally shift
+// or control pressed
+// (for the exact functions of each, just try it out)
+#define WINAMP_BUTTON1 40044
+#define WINAMP_BUTTON2 40045
+#define WINAMP_BUTTON3 40046
+#define WINAMP_BUTTON4 40047
+#define WINAMP_BUTTON5 40048
+#define WINAMP_BUTTON1_SHIFT 40144
+#define WINAMP_BUTTON2_SHIFT 40145
+#define WINAMP_BUTTON3_SHIFT 40146
+#define WINAMP_BUTTON4_SHIFT 40147
+#define WINAMP_BUTTON5_SHIFT 40148
+#define WINAMP_BUTTON1_CTRL 40154
+#define WINAMP_BUTTON2_CTRL 40155
+#define WINAMP_BUTTON3_CTRL 40156
+#define WINAMP_BUTTON4_CTRL 40157
+#define WINAMP_BUTTON5_CTRL 40158
+
+#define WINAMP_FILE_PLAY 40029 // pops up the load file(s) box
+#define WINAMP_OPTIONS_PREFS 40012 // pops up the preferences
+#define WINAMP_OPTIONS_AOT 40019 // toggles always on top
+#define WINAMP_HELP_ABOUT 40041 // pops up the about box :)
+
+
+/*
+** EOF.. Enjoy.
+*/
+
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/LICENSE.TXT b/Src/Plugins/Visualization/vis_avs/LICENSE.TXT
new file mode 100644
index 00000000..7510f1aa
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/LICENSE.TXT
@@ -0,0 +1,24 @@
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Src/Plugins/Visualization/vis_avs/TIMING.C b/Src/Plugins/Visualization/vis_avs/TIMING.C
new file mode 100644
index 00000000..b32b8743
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/TIMING.C
@@ -0,0 +1,69 @@
+#include "timing.h"
+
+#ifdef TIMING
+#ifndef __alpha
+
+#include <stdio.h>
+
+static struct {
+ unsigned int st_time[2];
+ unsigned int cycles;
+ unsigned int calls;
+} timingInfo[64];
+
+static int timingEnters;
+
+static void rdtsc(unsigned int t[2])
+{
+ __asm
+ {
+ mov esi, t
+ _emit 0xf
+ _emit 0x31
+ mov [esi], eax
+ mov [esi+4], edx
+ }
+}
+
+void _timingInit(void)
+{
+ memset(timingInfo,0,sizeof(timingInfo));
+}
+
+void _timingEnter(int which)
+{
+ // if (!timingEnters++) __asm cli
+ rdtsc(timingInfo[which].st_time);
+}
+
+void _timingLeave(int which)
+{
+ unsigned int t[2];
+ rdtsc(t);
+// if (!--timingEnters) __asm sti
+ if (t[1]==timingInfo[which].st_time[1])
+ {
+ timingInfo[which].cycles += t[0]-timingInfo[which].st_time[0];
+ }
+ else
+ {
+ timingInfo[which].cycles += t[0]+(0xffffffff-timingInfo[which].st_time[0]);
+ }
+ timingInfo[which].calls++;
+}
+
+void _timingPrint(void)
+{
+ int x;
+ FILE *fp = fopen("C:\\timings.txt","wt");
+ for (x = 0; x < sizeof(timingInfo)/sizeof(timingInfo[0]); x ++)
+ {
+ if (timingInfo[x].calls)
+ fprintf(fp,"%d: %d calls, %d clocks/call\n",x,timingInfo[x].calls,timingInfo[x].cycles/timingInfo[x].calls);
+ }
+ timingInit();
+ fclose(fp);
+}
+
+#endif
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/Timing.h b/Src/Plugins/Visualization/vis_avs/Timing.h
new file mode 100644
index 00000000..504c9386
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/Timing.h
@@ -0,0 +1,32 @@
+
+#ifndef _TIMING_H_
+#define _TIMING_H_
+
+
+//#define TIMING
+
+
+
+#if defined(TIMING) && !defined(__alpha)
+#ifdef __cplusplus
+extern "C" {
+#endif
+void _timingInit(void);
+void _timingPrint(void);
+void _timingEnter(int);
+void _timingLeave(int);
+#ifdef __cplusplus
+}
+#endif
+#define timingPrint() _timingPrint()
+#define timingInit() _timingInit()
+#define timingLeave(x) _timingLeave(x)
+#define timingEnter(x) _timingEnter(x)
+#else
+#define timingPrint()
+#define timingInit()
+#define timingLeave(x)
+#define timingEnter(x)
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/VIS.H b/Src/Plugins/Visualization/vis_avs/VIS.H
new file mode 100644
index 00000000..98d13957
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/VIS.H
@@ -0,0 +1,76 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// notes:
+// any window that remains in foreground should optimally pass
+// keystrokes to the parent (winamp's) window, so that the user
+// can still control it. unless escape is hit, or some option
+// key specific to the vis is hit. As for storing configuration,
+// Configuration data should be stored in <dll directory>\plugin.ini
+// Look at the example plugin for a framework.
+
+// ints are 32 bits, and structure members are aligned on the default 8 byte boundaries
+// tested with VC++ 4.2 and 5.0
+
+
+typedef struct winampVisModule {
+ char *description; // description of module
+ HWND hwndParent; // parent window (filled in by calling app)
+ HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app)
+ int sRate; // sample rate (filled in by calling app)
+ int nCh; // number of channels (filled in...)
+ int latencyMs; // latency from call of RenderFrame to actual drawing
+ // (calling app looks at this value when getting data)
+ int delayMs; // delay between calls in ms
+
+ // the data is filled in according to the respective Nch entry
+ int spectrumNch;
+ int waveformNch;
+ unsigned char spectrumData[2][576];
+ unsigned char waveformData[2][576];
+
+ void (*Config)(struct winampVisModule *this_mod); // configuration dialog
+ int (*Init)(struct winampVisModule *this_mod); // 0 on success, creates window, etc
+ int (*Render)(struct winampVisModule *this_mod); // returns 0 if successful, 1 if vis should end
+ void (*Quit)(struct winampVisModule *this_mod); // call when done
+
+ void *userData; // user data, optional
+} winampVisModule;
+
+typedef struct {
+ int version; // VID_HDRVER
+ char *description; // description of library
+ winampVisModule* (*getModule)(int);
+} winampVisHeader;
+
+// exported symbols
+typedef winampVisHeader* (*winampVisGetHeaderType)();
+
+// version of current module (0x101 == 1.01)
+#define VIS_HDRVER 0x101 \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/ape.h b/Src/Plugins/Visualization/vis_avs/ape.h
new file mode 100644
index 00000000..b4bb6483
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/ape.h
@@ -0,0 +1,96 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _APE_H_
+#define _APE_H_
+
+
+//extended APE stuff
+
+// to use this, you should have:
+// APEinfo *g_extinfo;
+// void __declspec(dllexport) AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
+// {
+// g_extinfo = ptr;
+// }
+
+typedef void *VM_CONTEXT;
+typedef void *VM_CODEHANDLE;
+typedef struct
+{
+ int ver; // ver=1 to start
+ double *global_registers; // 100 of these
+
+ // lineblendmode: 0xbbccdd
+ // bb is line width (minimum 1)
+ // dd is blend mode:
+ // 0=replace
+ // 1=add
+ // 2=max
+ // 3=avg
+ // 4=subtractive (1-2)
+ // 5=subtractive (2-1)
+ // 6=multiplicative
+ // 7=adjustable (cc=blend ratio)
+ // 8=xor
+ // 9=minimum
+ int *lineblendmode;
+
+ //evallib interface
+ VM_CONTEXT (*allocVM)(); // return a handle
+ void (*freeVM)(VM_CONTEXT); // free when done with a VM and ALL of its code have been freed, as well
+
+ // you should only use these when no code handles are around (i.e. it's okay to use these before
+ // compiling code, or right before you are going to recompile your code.
+ void (*resetVM)(VM_CONTEXT);
+ double * (*regVMvariable)(VM_CONTEXT, const char *name);
+
+ // compile code to a handle
+ VM_CODEHANDLE (*compileVMcode)(VM_CONTEXT, char *code);
+
+ // execute code from a handle
+ void (*executeCode)(VM_CODEHANDLE, char visdata[2][2][576]);
+
+ // free a code block
+ void (*freeCode)(VM_CODEHANDLE);
+
+ // requires ver >= 2
+ void (*doscripthelp)(HWND hwndDlg,char *mytext); // mytext can be NULL for no custom page
+
+ /// requires ver >= 3
+ void *(*getNbuffer)(int w, int h, int n, int do_alloc); // do_alloc should be 0 if you dont want it to allocate if empty
+ // w and h should be the current width and height
+ // n should be 0-7
+
+} APEinfo;
+
+
+
+#endif//_APE_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/ape.rc b/Src/Plugins/Visualization/vis_avs/apesdk/ape.rc
new file mode 100644
index 00000000..33539d2d
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/ape.rc
@@ -0,0 +1,80 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_CONFIG DIALOG DISCARDABLE 0, 0, 137, 137
+STYLE WS_CHILD
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "Enable Tutorial Effect",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,25,86,84,10
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,39,29,
+ 53,49
+ LTEXT "Color",IDC_STATIC,56,14,17,8
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/avs_ape.h b/Src/Plugins/Visualization/vis_avs/apesdk/avs_ape.h
new file mode 100644
index 00000000..cab80a31
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/avs_ape.h
@@ -0,0 +1,110 @@
+// AVS APE (Plug-in Effect) header
+
+// base class to derive from
+class C_RBASE {
+ public:
+ C_RBASE() { }
+ virtual ~C_RBASE() { };
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)=0; // returns 1 if fbout has dest, 0 if framebuffer has dest
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent){return 0;};
+ virtual char *get_desc()=0;
+ virtual void load_config(unsigned char *data, int len) { }
+ virtual int save_config(unsigned char *data) { return 0; }
+};
+
+// if you want to support SMP rendering, you can derive from this class instead,
+// and expose the creator via: _AVS_APE_RetrFuncEXT2
+// (in general, exposing both for compatibility is a good idea)
+class C_RBASE2 : public C_RBASE {
+ public:
+ C_RBASE2() { }
+ virtual ~C_RBASE2() { };
+
+ int getRenderVer2() { return 2; }
+
+
+ virtual int smp_getflags() { return 0; } // return 1 to enable smp support
+
+ // returns # of threads you desire, <= max_threads, or 0 to not do anything
+ // default should return max_threads if you are flexible
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { return 0; }
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { };
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { return 0; }; // return value is that of render() for fbstuff etc
+
+};
+
+// lovely helper functions for blending
+static unsigned int __inline BLEND(unsigned int a, unsigned int b)
+{
+ register unsigned int r,t;
+ r=(a&255)+((b)&255);
+ t=min(r,255);
+ r=((a>>8)&255)+((b>>8)&255);
+ t|=min(r,255)<<8;
+ r=((a>>16)&255)+((b>>16)&255);
+ return t|min(r,255)<<16;
+}
+
+static unsigned int __inline BLEND_AVG(unsigned int a, unsigned int b)
+{
+ return ((a>>1)&~((1<<7)|(1<<15)|(1<<23)))+((b>>1)&~((1<<7)|(1<<15)|(1<<23)));
+}
+
+//extended APE stuff
+
+// to use this, you should have:
+// APEinfo *g_extinfo;
+// void __declspec(dllexport) AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
+// {
+// g_extinfo = ptr;
+// }
+
+typedef void *VM_CONTEXT;
+typedef void *VM_CODEHANDLE;
+typedef struct
+{
+ int ver; // ver=1 to start
+ double *global_registers; // 100 of these
+
+ // lineblendmode: 0xbbccdd
+ // bb is line width (minimum 1)
+ // dd is blend mode:
+ // 0=replace
+ // 1=add
+ // 2=max
+ // 3=avg
+ // 4=subtractive (1-2)
+ // 5=subtractive (2-1)
+ // 6=multiplicative
+ // 7=adjustable (cc=blend ratio)
+ // 8=xor
+ // 9=minimum
+ int *lineblendmode;
+
+ //evallib interface
+ VM_CONTEXT (*allocVM)(); // return a handle
+ void (*freeVM)(VM_CONTEXT); // free when done with a VM and ALL of its code have been freed, as well
+
+ // you should only use these when no code handles are around (i.e. it's okay to use these before
+ // compiling code, or right before you are going to recompile your code.
+ void (*resetVM)(VM_CONTEXT);
+ double * (*regVMvariable)(VM_CONTEXT, char *name);
+
+ // compile code to a handle
+ VM_CODEHANDLE (*compileVMcode)(VM_CONTEXT, char *code);
+
+ // execute code from a handle
+ void (*executeCode)(VM_CODEHANDLE, char visdata[2][2][576]);
+
+ // free a code block
+ void (*freeCode)(VM_CODEHANDLE);
+
+ // requires ver >= 2
+ void (*doscripthelp)(HWND hwndDlg,char *mytext); // mytext can be NULL for no custom page
+
+ /// requires ver >= 3
+ void *(*getNbuffer)(int w, int h, int n, int do_alloc); // do_alloc should be 0 if you dont want it to allocate if empty
+ // w and h should be the current width and height
+ // n should be 0-7
+
+} APEinfo; \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.avs b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.avs
new file mode 100644
index 00000000..5bb3d7d8
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.avs
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.cpp b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.cpp
new file mode 100644
index 00000000..e1c12f0f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.cpp
@@ -0,0 +1,294 @@
+
+/**
+ Example Winamp AVS plug-in
+ Copyright (c) 2000, Nullsoft Inc.
+
+ Hello, welcome to the first Advanced Visualization
+ Studio tutorial!
+ The hope is that together, we can learn to utilize
+ AVS's powerful features: Namely direct access to the
+ frame buffer, EZ beat detection, and the ability to
+ stack plug-ins written by other developers for an
+ infinite array of possible effects.
+
+ I hereby present:
+ Tutorial 0: BOX-
+ Simplicity at its finest. Displays a rectangle on
+ screen on every beat. Oh, and you can change its color
+ too... Check avstut00.avs for a demonstration of a
+ spinning rectangle's power!
+
+ good luck and have fun!
+**/
+
+#include <windows.h>
+#include "resource.h"
+#include "avs_ape.h"
+
+
+#define MOD_NAME "Tutorials / BOX v1.0"
+#define UNIQUEIDSTRING "Nullsoft Tut0: BOX"
+
+// extended APE api support
+APEinfo *g_extinfo;
+extern "C"
+{
+ void __declspec(dllexport) _AVS_APE_SetExtInfo(HINSTANCE hDllInstance, APEinfo *ptr)
+ {
+ g_extinfo = ptr;
+ }
+}
+
+
+
+class C_THISCLASS : public C_RBASE
+{
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual char *get_desc();
+
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int enabled; // toggles plug-in on and off
+ int color; // color of rectangle
+};
+
+// global configuration dialog pointer
+static C_THISCLASS *g_ConfigThis;
+// global DLL instance pointer (not needed in this example, but could be useful)
+static HINSTANCE g_hDllInstance;
+
+
+
+// this is where we deal with the configuration screen
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+
+ if (g_ConfigThis->enabled)
+ {
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ }
+ return 1;
+
+ case WM_DRAWITEM:
+
+ DRAWITEMSTRUCT *di;
+
+ di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL)
+ {
+ int w;
+ int color;
+
+ w=di->rcItem.right-di->rcItem.left;
+ color=g_ConfigThis->color;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ // paint nifty color button
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={BS_SOLID,color,0};
+ hBrush = CreateBrushIndirect(&lb);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+
+ }
+ return 0;
+
+ case WM_COMMAND:
+
+ // see if enable checkbox is checked
+ if (LOWORD(wParam) == IDC_CHECK1)
+ {
+ g_ConfigThis->enabled= (IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0);
+ }
+
+ // is colorbox is selected?
+ if (LOWORD(wParam) == IDC_DEFCOL)
+ {
+ static COLORREF custcolors[16];
+ int *a;
+ CHOOSECOLOR cs;
+
+ a=&g_ConfigThis->color;
+
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+
+ // go to windows color selection screen
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+
+
+// set up default configuration
+C_THISCLASS::C_THISCLASS()
+{
+ //set initial color
+ color=RGB(255,0,0);
+ enabled=1;
+}
+
+// virtual destructor
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+// RENDER FUNCTION:
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the-*/ width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int halfw;
+ int halfh;
+
+ // is this effect on?
+ if (!enabled)
+ {
+ return 0;
+ }
+
+ // did we just hit a beat?
+ if(isBeat)
+ {
+ // draw our magic box
+ halfw=w/2;
+ halfh=h/2;
+
+ framebuffer+=(((halfh/2)*w)+ (halfw/2));
+
+ for(int j=0;j<halfh;j++)
+ {
+ for(int i=0;i<halfw;i++)
+ {
+ framebuffer[i]=color;
+ }
+ framebuffer+=w;
+ }
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return CreateDialog(hInstance,MAKEINTRESOURCE(IDD_CONFIG),hwndParent,g_DlgProc);
+}
+
+
+char *C_THISCLASS::get_desc(void)
+{
+ return MOD_NAME;
+}
+
+
+// load_/save_config are called when saving and loading presets (.avs files)
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+
+ // always ensure there is data to be loaded
+ if (len-pos >= 4)
+ {
+ // load activation toggle
+ enabled=GET_INT();
+ pos+=4;
+ }
+
+ if (len-pos >= 4)
+ {
+ // load the box color
+ color=GET_INT();
+ pos+=4;
+ }
+}
+
+
+// write configuration to data, return length. config data should not exceed 64k.
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+
+ PUT_INT(enabled);
+ pos+=4;
+
+ PUT_INT(color);
+ pos+=4;
+
+ return pos;
+}
+
+
+
+
+
+
+
+// export stuff
+C_RBASE *R_RetrFunc(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc)
+ {
+ strcpy(desc,MOD_NAME);
+ return NULL;
+ }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+extern "C"
+{
+ __declspec (dllexport) int _AVS_APE_RetrFunc(HINSTANCE hDllInstance, char **info, int *create) // return 0 on failure
+ {
+ g_hDllInstance=hDllInstance;
+ *info=UNIQUEIDSTRING;
+ *create=(int)(void*)R_RetrFunc;
+ return 1;
+ }
+};
+
+
+/**
+ Final Thoughts:
+ Alright! Hopefully you guys can take the next step
+ and display more than just a colored rectangle ;) The
+ exciting thing is, each time you write an AVS plug-in,
+ you exponentially increase AVS's potential, unlocking
+ the possibility of an effect you never expected. Good
+ luck, I hope this has helped!
+
+ See you next time!
+**/ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsp b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsp
new file mode 100644
index 00000000..19cab2be
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsp
@@ -0,0 +1,120 @@
+# Microsoft Developer Studio Project File - Name="avstut00" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=avstut00 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "avstut00.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "avstut00.mak" CFG="avstut00 - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "avstut00 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "avstut00 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "avstut00 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"c:/program files/winamp/plugins/avs/avstut00.ape"
+
+!ELSEIF "$(CFG)" == "avstut00 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /WX /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AVSTUT00_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 msvcrt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /machine:I386 /nodefaultlib /out:"c:/program files/winamp/plugins/avs/avstut00.ape" /pdbtype:sept
+# SUBTRACT LINK32 /debug
+
+!ENDIF
+
+# Begin Target
+
+# Name "avstut00 - Win32 Release"
+# Name "avstut00 - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\ape.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\avstut00.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\avs_ape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsw b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsw
new file mode 100644
index 00000000..f15a1851
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/avstut00.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "avstut00"=".\avstut00.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Src/Plugins/Visualization/vis_avs/apesdk/resource.h b/Src/Plugins/Visualization/vis_avs/apesdk/resource.h
new file mode 100644
index 00000000..744de4f7
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/apesdk/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by ape.rc
+//
+#define IDD_CONFIG 109
+#define IDC_CHECK1 1000
+#define IDC_DEFCOL 1036
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/avs-hilited.png b/Src/Plugins/Visualization/vis_avs/avs-hilited.png
new file mode 100644
index 00000000..62cea6a3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/avs-hilited.png
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/avs-normal.png b/Src/Plugins/Visualization/vis_avs/avs-normal.png
new file mode 100644
index 00000000..f043035a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/avs-normal.png
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/avs-selected.png b/Src/Plugins/Visualization/vis_avs/avs-selected.png
new file mode 100644
index 00000000..e593769b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/avs-selected.png
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/avs_eelif.cpp b/Src/Plugins/Visualization/vis_avs/avs_eelif.cpp
new file mode 100644
index 00000000..a9141809
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/avs_eelif.cpp
@@ -0,0 +1,235 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include "../ns-eel2/ns-eel-int.h"
+#include "../ns-eel2/ns-eel-addfuncs.h"
+#include "avs_eelif.h"
+
+
+
+char last_error_string[1024];
+int g_log_errors;
+CRITICAL_SECTION g_eval_cs;
+static char *g_evallib_visdata;
+
+
+
+/////////////////////// begin AVS specific script functions
+
+
+
+static double NSEEL_CGEN_CALL getvis(unsigned char *visdata, int bc, int bw, int ch, int xorv)
+{
+ int x;
+ int accum=0;
+ if (ch && ch != 1 && ch != 2) return 0.0;
+
+ if (bw < 1) bw=1;
+ bc-=bw/2;
+ if (bc < 0)
+ {
+ bw+=bc;
+ bc=0;
+ }
+ if (bc > 575) bc=575;
+ if (bc+bw > 576) bw=576-bc;
+
+
+ if (!ch)
+ {
+ for (x = 0; x < bw; x ++)
+ {
+ accum+=(visdata[bc]^xorv)-xorv;
+ accum+=(visdata[bc+576]^xorv)-xorv;
+ bc++;
+ }
+ return (double)accum / ((double)bw*255.0);
+ }
+ else
+ {
+ if (ch == 2) visdata+=576;
+ for (x = 0; x < bw; x ++) accum+=(visdata[bc++]^xorv)-xorv;
+ return (double)accum / ((double)bw*127.5);
+ }
+}
+
+static double NSEEL_CGEN_CALL getspec_(void *_this, double *band, double *bandw, double *chan)
+{
+ if (!g_evallib_visdata) return 0.0;
+ return getvis((unsigned char *)g_evallib_visdata,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),0)*0.5;
+}
+
+static double NSEEL_CGEN_CALL getosc_(void *_this, double *band, double *bandw, double *chan)
+{
+ if (!g_evallib_visdata) return 0.0;
+ return getvis((unsigned char *)g_evallib_visdata+576*2,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),128);
+}
+
+static double NSEEL_CGEN_CALL gettime_(void *_this, double *sc)
+{
+ int ispos;
+ if ((ispos=(*sc > -1.001 && *sc < -0.999)) || (*sc > -2.001 && *sc < -1.999))
+ {
+ int pos=0;
+
+ extern HWND hwnd_WinampParent;
+ if (IsWindow(hwnd_WinampParent))
+ {
+ if (!SendMessageTimeout( hwnd_WinampParent, WM_USER,(WPARAM)!ispos,(LPARAM)105,SMTO_BLOCK,50,(LPDWORD)&pos)) pos=0;
+ }
+ if (!ispos) return (double)pos;
+ return pos / 1000.0;
+ }
+
+ return GetTickCount()/1000.0 - *sc;
+}
+
+static double NSEEL_CGEN_CALL setmousepos_(void *_this, double *x, double *y)
+{
+ //fucko: implement me
+ return 0.0;
+}
+
+
+extern double DDraw_translatePoint(POINT p, int isY);
+
+static double NSEEL_CGEN_CALL getmouse_(void *_this, double *which)
+{
+ int w=(int)(*which+0.5);
+
+ if (w > 5)
+ return (GetAsyncKeyState(w)&0x8000)?1.0:0.0;
+
+ if (w == 1 || w == 2)
+ {
+ POINT p;
+ GetCursorPos(&p);
+ return DDraw_translatePoint(p,w==2);
+ }
+ if (w == 3) return (GetAsyncKeyState(MK_LBUTTON)&0x8000)?1.0:0.0;
+ if (w == 4) return (GetAsyncKeyState(MK_RBUTTON)&0x8000)?1.0:0.0;
+ if (w == 5) return (GetAsyncKeyState(MK_MBUTTON)&0x8000)?1.0:0.0;
+ return 0.0;
+}
+
+
+
+/////////////////////// end AVS specific script functions
+
+void NSEEL_HOSTSTUB_EnterMutex()
+{
+ EnterCriticalSection(&g_eval_cs);
+}
+void NSEEL_HOSTSTUB_LeaveMutex()
+{
+ LeaveCriticalSection(&g_eval_cs);
+}
+
+void AVS_EEL_IF_init()
+{
+ InitializeCriticalSection(&g_eval_cs);
+ NSEEL_init();
+
+ // todo: check to see that parameter orders are correct
+ NSEEL_addfunctionex("getosc",3,(char *)_asm_generic3parm_retd,(char *)_asm_generic3parm_retd_end-(char *)_asm_generic3parm_retd,NSEEL_PProc_THIS,(void*)getosc_);
+ NSEEL_addfunctionex("getspec",3,(char *)_asm_generic3parm_retd,(char *)_asm_generic3parm_retd_end-(char *)_asm_generic3parm_retd,NSEEL_PProc_THIS,(void*)getspec_);
+
+ NSEEL_addfunctionex("gettime",1,(char *)_asm_generic1parm_retd,(char *)_asm_generic1parm_retd_end-(char *)_asm_generic1parm_retd,NSEEL_PProc_THIS,(void*)gettime_);
+ NSEEL_addfunctionex("getkbmouse",1,(char *)_asm_generic1parm_retd,(char *)_asm_generic1parm_retd_end-(char *)_asm_generic1parm_retd,NSEEL_PProc_THIS,(void*)getmouse_);
+
+ NSEEL_addfunctionex("setmousepos",2,(char *)_asm_generic2parm_retd,(char *)_asm_generic2parm_retd_end-(char *)_asm_generic2parm_retd,NSEEL_PProc_THIS,(void*)setmousepos_);
+}
+void AVS_EEL_IF_quit()
+{
+ DeleteCriticalSection(&g_eval_cs);
+ NSEEL_quit();
+}
+
+static void movestringover(char *str, int amount)
+{
+ char tmp[1024+8];
+
+ int l=(int)strlen(str);
+ l=min(1024-amount-1,l);
+
+ memcpy(tmp,str,l+1);
+
+ while (l >= 0 && tmp[l]!='\n') l--;
+ l++;
+
+ tmp[l]=0;//ensure we null terminate
+
+ memcpy(str+amount,tmp,l+1);
+}
+
+NSEEL_CODEHANDLE AVS_EEL_IF_Compile(void *context, char *code)
+{
+ NSEEL_CODEHANDLE ret;
+ EnterCriticalSection(&g_eval_cs);
+ ret=NSEEL_code_compile((NSEEL_VMCTX)context,code,0);
+ if (!ret)
+ {
+ if (g_log_errors)
+ {
+ char *expr = NSEEL_code_getcodeerror((NSEEL_VMCTX)context);
+ if (expr)
+ {
+ int l=strlen(expr);
+ if (l > 512) l=512;
+ movestringover(last_error_string,l+2);
+ memcpy(last_error_string,expr,l);
+ last_error_string[l]='\r';
+ last_error_string[l+1]='\n';
+ }
+ }
+ }
+ LeaveCriticalSection(&g_eval_cs);
+ return ret;
+}
+
+void AVS_EEL_IF_Execute(NSEEL_CODEHANDLE handle, char visdata[2][2][576])
+{
+ if (handle)
+ {
+ EnterCriticalSection(&g_eval_cs);
+ g_evallib_visdata=(char*)visdata;
+ NSEEL_code_execute((NSEEL_CODEHANDLE)handle);
+ g_evallib_visdata=NULL;
+ LeaveCriticalSection(&g_eval_cs);
+ }
+}
+
+
+void AVS_EEL_IF_resetvars(NSEEL_VMCTX ctx)
+{
+ NSEEL_VM_freeRAM(ctx);
+ NSEEL_VM_remove_all_nonreg_vars(ctx);
+}
+
diff --git a/Src/Plugins/Visualization/vis_avs/avs_eelif.h b/Src/Plugins/Visualization/vis_avs/avs_eelif.h
new file mode 100644
index 00000000..9bbbc9fa
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/avs_eelif.h
@@ -0,0 +1,59 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _AVS_EEL_IF_H_
+#define _AVS_EEL_IF_H_
+
+#include "../ns-eel2/ns-eel.h"
+
+void AVS_EEL_IF_init();
+void AVS_EEL_IF_quit();
+
+NSEEL_CODEHANDLE AVS_EEL_IF_Compile(void *ctx, char *code);
+void AVS_EEL_IF_Execute(NSEEL_CODEHANDLE handle, char visdata[2][2][576]);
+void AVS_EEL_IF_resetvars(NSEEL_VMCTX ctx);
+#define AVS_EEL_IF_VM_free(x) NSEEL_VM_free(x)
+extern char last_error_string[1024];
+extern int g_log_errors;
+extern CRITICAL_SECTION g_eval_cs;
+
+// our old-style interface
+#define compileCode(exp) AVS_EEL_IF_Compile(AVS_EEL_CONTEXTNAME,(exp))
+#define executeCode(x,y) AVS_EEL_IF_Execute(x,y)
+#define freeCode(h) NSEEL_code_free(h)
+#define resetVars(x) FIXME+++++++++
+#define registerVar(x) NSEEL_VM_regvar(AVS_EEL_CONTEXTNAME,(x))
+#define clearVars() AVS_EEL_IF_resetvars(AVS_EEL_CONTEXTNAME)
+
+#define AVS_EEL_INITINST() AVS_EEL_CONTEXTNAME=NSEEL_VM_alloc()
+
+#define AVS_EEL_QUITINST() NSEEL_VM_free(AVS_EEL_CONTEXTNAME)
+
+
+#endif//_AVS_EEL_IF_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/bpm.cpp b/Src/Plugins/Visualization/vis_avs/bpm.cpp
new file mode 100644
index 00000000..1ab80f79
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/bpm.cpp
@@ -0,0 +1,711 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include <stdio.h>
+#include "draw.h"
+#include "wnd.h"
+#include "r_defs.h"
+#include "render.h"
+#include "vis.h"
+#include "cfgwnd.h"
+#include "resource.h"
+#include "bpm.h"
+#include "../Agave/Language/api_language.h"
+
+int refineBeat(int isBeat);
+BOOL TCHistStep(BeatType *t, DWORD _Avg, int *_halfDiscriminated, int *_hdPos, DWORD *_lastTC, DWORD TC, int Type);
+void InsertHistStep(BeatType *t, DWORD TC, int Type, int i);
+void CalcBPM(void);
+BOOL ReadyToLearn(void);
+BOOL ReadyToGuess(void);
+void doubleBeat(void);
+void halfBeat(void);
+void ResetAdapt(void);
+void SliderStep(int Ctl, int *slide);
+void initBpm(void);
+extern int g_fakeinit;
+
+int cfg_smartbeat=0;
+int cfg_smartbeatsticky=1;
+int cfg_smartbeatresetnewsong=1;
+int cfg_smartbeatonlysticky=0;
+int sticked=0;
+int arbVal, skipVal; // Values of arbitrary beat and beat skip
+int Bpm, Confidence, Confidence1, Confidence2; // Calculated BPM (realtime), Confidence computation
+DWORD lastTC; // Last beat Tick count
+DWORD lastTC2; // Last beat tick count 2
+BeatType TCHist[8]; // History of last 8 beats
+BeatType TCHist2[8]; // History of last 8 beats
+int Smoother[8]; // History of last 8 Bpm values, used to smooth changes
+int halfDiscriminated[8]; // Discriminated beats table
+int halfDiscriminated2[8]; // Discriminated beats table
+int hdPos; // Position in discrimination table
+int hdPos2; // Position in discrimination table
+int smPtr, smSize; // Smoother pointer and size
+int TCHistPtr; // Tick count history pointer
+int TCHistSize; // Tick count history size
+int offIMax; // Max divisor/multiplier used to guess/discriminate beats
+int lastBPM; // Last calculated BPM, used by the smoother to detect new entry
+int insertionCount; // Remembers how many beats were guessed
+DWORD predictionLastTC; // Last tick count of guessed/accepted beat
+DWORD Avg; // Average tick count interval between beats
+DWORD Avg2; // Average tick count interval between beats
+int skipCount; // Beat counter used by beat skipper
+int inInc, outInc; // +1/-1, Used by the nifty beatsynced sliders
+int inSlide, outSlide; // Positions of sliders
+int oldInSlide, oldOutSlide; // Used by timer to detect changes in sliders
+int oldsticked; // Used by timer to detect changes in sticked state
+char txt[256]; // Contains txt about current BPM and confidence
+int halfCount, doubleCount; // Counter used to autodetect if double/half beat needed
+int TCUsed; // Remembers how many beats in the history were actually used for computation
+int predictionBpm; // Contains BPM actually used to prediction (eliminates Bpm driftings)
+int oldDisplayBpm, oldDisplayConfidence; // Detects stuff to redraw
+int bestConfidence; // Best confidence we had so far
+char lastSongName[256]; // Last song name, used to detect song changes in winamp
+HWND winampWnd; // Winamp window
+int forceNewBeat; // Force new bpm adoption
+int betterConfidenceCount; // Used to decide when to adpot new beat
+int topConfidenceCount; // Used to decide when to adpot new beat
+int stickyConfidenceCount; // Used to decided when to go sticky
+BOOL doResyncBpm=FALSE;
+
+// configuration dialog stuff
+BOOL CALLBACK DlgProc_Bpm(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ inInc = 1;
+ outInc = 1;
+ inSlide = 0;
+ outSlide = 0;
+ oldDisplayBpm=-1;
+ oldDisplayConfidence=-1;
+ oldInSlide=-1;
+ oldOutSlide=-1;
+ if (cfg_smartbeat) CheckDlgButton(hwndDlg,IDC_BPMADV,BST_CHECKED); else CheckDlgButton(hwndDlg,IDC_BPMSTD,BST_CHECKED);
+ if (cfg_smartbeatsticky) CheckDlgButton(hwndDlg,IDC_STICKY,BST_CHECKED);
+ if (cfg_smartbeatresetnewsong) CheckDlgButton(hwndDlg,IDC_NEWRESET,BST_CHECKED); else CheckDlgButton(hwndDlg,IDC_NEWADAPT,BST_CHECKED);
+ if (cfg_smartbeatonlysticky) CheckDlgButton(hwndDlg,IDC_ONLYSTICKY,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
+ SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
+ if (predictionBpm)
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), sticked ? SW_HIDE : SW_NORMAL);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), sticked ? SW_NORMAL : SW_HIDE);
+ }
+ else
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), SW_HIDE);
+ }
+/* ShowWindow(GetDlgItem(hwndDlg, IDC_CURBPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CURCONF), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_BPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CONFIDENCE), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RESET), cfg_smartbeat ? SW_NORMAL : SW_HIDE);*/
+ SetTimer(hwndDlg, 0, 50, NULL);
+ return 1;
+ case WM_TIMER:
+ {
+ if (oldInSlide != inSlide) {
+ SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETPOS, TRUE, inSlide); oldInSlide=inSlide; }
+ if (oldOutSlide != outSlide) {
+ SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETPOS, TRUE, outSlide); oldOutSlide=outSlide; }
+ if (oldDisplayBpm != predictionBpm || oldsticked != sticked) {
+ char lBuf[16];
+ wsprintf(txt, predictionBpm ? "%d%s"/*/%d"*/ : WASABI_API_LNGSTRING_BUF(IDS_LEARNING,lBuf,16), predictionBpm, cfg_smartbeatsticky && sticked ? WASABI_API_LNGSTRING(IDS_GOT_IT) : ""/*, Bpm*/);
+ SetDlgItemText(hwndDlg, IDC_BPM, txt);
+ oldDisplayBpm=predictionBpm;
+ oldsticked=sticked;
+ if (predictionBpm)
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), sticked ? SW_HIDE : SW_NORMAL);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), sticked ? SW_NORMAL : SW_HIDE);
+ }
+ else
+ {
+ ShowWindow(GetDlgItem(hwndDlg, IDC_STICK), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_UNSTICK), SW_HIDE);
+ }
+ }
+ if (oldDisplayConfidence != Confidence) {
+ wsprintf(txt, "%d%%"/* (%d%%/%d%% - %d)"*/, Confidence/*, Confidence1, Confidence2, TCUsed*/);
+ SetDlgItemText(hwndDlg, IDC_CONFIDENCE, txt);
+ oldDisplayConfidence=Confidence;
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_BPMSTD) ||
+ (LOWORD(wParam) == IDC_BPMADV) ||
+ (LOWORD(wParam) == IDC_NEWRESET) ||
+ (LOWORD(wParam) == IDC_NEWADAPT) ||
+ (LOWORD(wParam) == IDC_ONLYSTICKY) ||
+ (LOWORD(wParam) == IDC_STICKY))
+ {
+ cfg_smartbeat=IsDlgButtonChecked(hwndDlg,IDC_BPMADV)?1:0;
+ cfg_smartbeatsticky=IsDlgButtonChecked(hwndDlg,IDC_STICKY)?1:0;
+ cfg_smartbeatresetnewsong=IsDlgButtonChecked(hwndDlg,IDC_NEWRESET)?1:0;
+ cfg_smartbeatonlysticky=IsDlgButtonChecked(hwndDlg,IDC_ONLYSTICKY)?1:0;
+ oldsticked=-1;
+/* ShowWindow(GetDlgItem(hwndDlg, IDC_CURBPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CURCONF), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_BPM), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CONFIDENCE), cfg_smartbeat ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_RESET), cfg_smartbeat ? SW_NORMAL : SW_HIDE);*/
+ }
+ if (LOWORD(wParam) == IDC_2X)
+ doubleBeat();
+ if (LOWORD(wParam) == IDC_DIV2)
+ halfBeat();
+ if (LOWORD(wParam) == IDC_RESET)
+ ResetAdapt();
+ if (LOWORD(wParam) == IDC_STICK)
+ {
+ sticked=1;
+ stickyConfidenceCount=0;
+ }
+ if (LOWORD(wParam) == IDC_UNSTICK)
+ {
+ sticked=0;
+ stickyConfidenceCount=0;
+ }
+ return 0;
+ case WM_DESTROY:
+ KillTimer(hwndDlg, 0);
+ return 0;
+ }
+return 0;
+}
+
+void initBpm(void)
+{
+ if (g_fakeinit) return;
+ TCUsed=0;
+ *txt=0;
+ betterConfidenceCount=0;
+ topConfidenceCount=0;
+ forceNewBeat=0;
+ hdPos=0;
+ hdPos2=0;
+ inSlide=0;
+ outSlide=0;
+ oldDisplayBpm=-1;
+ oldDisplayConfidence=-1;
+ oldInSlide=0;
+ oldOutSlide=0;
+ Bpm = 0;
+ Avg = 0;
+ Avg2 = 0;
+ smPtr = 0;
+ smSize = 8;
+ offIMax = 8;
+ insertionCount = 0;
+ predictionLastTC = 0;
+ Confidence = 0;
+ Confidence1 = 0;
+ Confidence2 = 0;
+ halfCount=0;
+ doubleCount=0;
+ TCHistSize = 8;
+ predictionBpm=0;
+ lastTC=GetTickCount();
+ stickyConfidenceCount=0;
+ memset(TCHist, 0, TCHistSize*sizeof(BeatType));
+ memset(Smoother, 0, smSize*sizeof(int));
+ memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
+ memset(halfDiscriminated2, 0, TCHistSize*sizeof(int));
+ winampWnd = FindWindow("Winamp v1.x", NULL);
+ *lastSongName=0;
+ sticked=0;
+ oldsticked=-1;
+}
+
+BOOL songChanged(DWORD TCNow)
+{
+static DWORD lastCheck=0;
+if (TCNow > lastCheck+1000)
+ {
+ char songName[256];
+ lastCheck=TCNow;
+ GetWindowText(winampWnd, songName, 255);
+ if (strcmp(songName, lastSongName))
+ {
+ strcpy(lastSongName, songName);
+ return TRUE;
+ }
+ }
+return FALSE;
+}
+
+void ResetAdapt(void)
+{
+// Reset adaptive learning
+*txt=0;
+TCUsed=0;
+hdPos=0;
+Avg = 0;
+Confidence=0;
+Confidence1=0;
+Confidence2=0;
+betterConfidenceCount=0;
+topConfidenceCount=0;
+Bpm = 0;
+smPtr = 0;
+smSize = 8;
+offIMax = 8;
+insertionCount = 0;
+predictionLastTC = 0;
+halfCount=0;
+doubleCount=0;
+TCHistSize = 8;
+predictionBpm=0;
+bestConfidence=0;
+lastTC=GetTickCount();
+sticked=0;
+oldsticked=-1;
+stickyConfidenceCount=0;
+memset(TCHist, 0, TCHistSize*sizeof(BeatType));
+memset(TCHist2, 0, TCHistSize*sizeof(BeatType));
+memset(Smoother, 0, smSize*sizeof(int));
+memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
+}
+
+// Insert a beat in history table. May be either real beat or guessed
+void InsertHistStep(BeatType *t, DWORD TC, int Type, int i)
+{
+if (i >= TCHistSize) return;
+if (t == TCHist && insertionCount < TCHistSize*2) insertionCount++;
+memmove(t+i+1, t+i, sizeof(BeatType)*(TCHistSize-(i+1)));
+t[0].TC = TC;
+t[0].Type = Type;
+}
+
+// Doubles current beat
+void doubleBeat(void)
+{
+int i;
+int iv[8];
+
+if (sticked && Bpm > MIN_BPM) return;
+
+for (i=0;i<TCHistSize-1;i++)
+ iv[i] = TCHist[i].TC - TCHist[i+1].TC;
+
+for (i=1;i<TCHistSize;i++)
+ TCHist[i].TC = TCHist[i-1].TC-iv[i-1]/2;
+
+Avg /= 2;
+Bpm *= 2;
+doubleCount=0;
+memset(Smoother, 0, smSize*sizeof(int));
+memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
+//forceNewBeat=1;
+}
+
+// Halfs current beat
+void halfBeat(void)
+{
+int i;
+int iv[8];
+
+if (sticked && Bpm < MIN_BPM) return;
+
+for (i=0;i<TCHistSize-1;i++)
+ iv[i] = TCHist[i].TC - TCHist[i+1].TC;
+
+for (i=1;i<TCHistSize;i++)
+ TCHist[i].TC = TCHist[i-1].TC-iv[i-1]*2;
+
+Avg *= 2;
+Bpm /= 2;
+halfCount=0;
+memset(Smoother, 0, smSize*sizeof(int));
+memset(halfDiscriminated, 0, TCHistSize*sizeof(int));
+}
+
+// Called whenever isBeat was true in render
+BOOL TCHistStep(BeatType *t, DWORD _Avg, int *_halfDiscriminated, int *_hdPos, DWORD *_lastTC, DWORD TC, int Type)
+{
+int i=0;
+int offI;
+DWORD thisLen;
+BOOL learning = ReadyToLearn();
+thisLen = TC-lastTC;
+
+// If this beat is sooner than half the average - 20%, throw it away
+if (thisLen < Avg/2 - Avg*0.2)
+ {
+ if (learning)
+ {
+ if (labs(Avg - (TC - t[1].TC)) < labs(Avg - (t[0].TC - t[1].TC)))
+ {
+/* if (predictionLastTC && t[0].Type == BEAT_GUESSED && Type == BEAT_REAL)
+ predictionLastTC += (TC - t[0].TC)/2;*/
+ t[0].TC = TC;
+ t[0].Type = Type;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+if (learning)
+ for (offI=2;offI<offIMax;offI++) // Try to see if this beat is in the middle of our current Bpm, or maybe 1/3, 1/4 etc... to offIMax
+ if ((float)labs((Avg/offI)-thisLen) < (float)(Avg/offI)*0.2)
+ {
+ _halfDiscriminated[(*_hdPos)++]=1; // Should test if offI==2 before doing that, but seems to have better results ? I'll have to investigate this
+ (*_hdPos)%=8;
+ return FALSE;
+ }
+
+// This beat is accepted, so set this discrimination entry to false
+_halfDiscriminated[hdPos++]=0;
+(*_hdPos)%=8;
+
+// Check if we missed some beats
+/*if (learning && thisLen > 1000 || (float)abs(Avg-thisLen) > (float)Avg*0.3)
+ for (offI=2;offI<offIMax;offI++)
+ {
+ if ((float)abs((Avg*offI)-thisLen) < (float)Avg*0.2)
+ {
+ for (j=1;j<offI;j++) // Oh yeah we definitly did, add one!
+ InsertHistStep(TC - (Avg*j), BEAT_GUESSED, offI-1); // beat has been guessed so report it so confidence can be calculated
+ break;
+ }
+ }*/
+
+
+// Remember this tick count
+*_lastTC = TC;
+// Insert this beat.
+InsertHistStep(t, TC, Type, 0);
+return TRUE;
+}
+
+// Am i ready to learn ?
+BOOL ReadyToLearn(void)
+{
+int i;
+for (i=0;i<TCHistSize;i++)
+ if (TCHist[i].TC==0) return FALSE;
+return TRUE;
+}
+
+// Am i ready to guess ?
+BOOL ReadyToGuess(void)
+{
+return insertionCount == TCHistSize*2;
+}
+
+void newBpm(int thisBpm)
+{
+Smoother[smPtr++] = thisBpm;
+smPtr %= smSize;
+}
+
+int GetBpm(void)
+{
+int i;
+int smN=0;
+int smSum=0;
+// Calculate smoothed Bpm
+for (i=0;i<smSize;i++)
+ if (Smoother[i] > 0) {
+ smSum += Smoother[i];
+ smN++;
+ }
+if (smN) return smSum / smN;
+return 0;
+}
+
+// Calculate BPM according to beat history
+void CalcBPM(void)
+{
+int i;
+int hdCount=0;
+int r=0;
+int totalTC=0, totalN=0;
+float rC, etC;
+int v;
+double sc=0;
+int mx=0;
+float et;
+int smSum=0, smN=0;
+
+if (!ReadyToLearn())
+ return;
+
+// First calculate average beat
+for (i=0;i<TCHistSize-1;i++)
+ totalTC += TCHist[i].TC - TCHist[i+1].TC;
+
+Avg = totalTC/(TCHistSize-1);
+
+// Count how many of then are real as opposed to guessed
+for (i=0;i<TCHistSize;i++)
+ if (TCHist[i].Type == BEAT_REAL)
+ r++;
+
+// Calculate part 1 of confidence
+rC = (float)min((float)((float)r / (float)TCHistSize) * 2, 1);
+
+// Calculate typical drift
+for (i=0;i<TCHistSize-1;i++)
+ {
+ v = TCHist[i].TC - TCHist[i+1].TC;
+ mx = max(mx, v);
+ sc += v*v;
+ }
+et = (float)sqrt(sc / (TCHistSize-1) - Avg*Avg);
+// Calculate confidence based on typical drift and max derivation
+etC = 1 - ((float)et / (float)mx);
+
+// Calculate confidence
+Confidence = max(0, (int)(((rC * etC) * 100.0) - 50) * 2);
+Confidence1 = (int)(rC * 100);
+Confidence2 = (int)(etC * 100);
+
+// Now apply second layer, recalculate average using only beats within range of typical drift
+// Also, count how many of them we are keeping
+totalTC=0;
+for (i=0;i<TCHistSize-1;i++)
+ {
+ v += TCHist[i].TC - TCHist[i+1].TC;
+ if (labs(Avg-v) < et)
+ {
+ totalTC += v;
+ totalN++;
+ v = 0;
+ }
+ else
+ if ((float)v > Avg)
+ v = 0;
+ }
+TCUsed = totalN;
+// If no beat was within typical drift (how would it be possible? well lets cover our ass) then keep the simple
+// average calculated earlier, else recalculate average of beats within range
+if (totalN)
+ Avg = totalTC/totalN;
+
+if (ReadyToGuess())
+ {
+ if (Avg) // Avg = 0 ? Ahem..
+ Bpm = 60000 / Avg;
+
+
+ if (Bpm != lastBPM)
+ {
+ newBpm(Bpm); // If realtime Bpm has changed since last time, then insert it in the smoothing tab;e
+ lastBPM = Bpm;
+
+ if (cfg_smartbeatsticky && predictionBpm && Confidence >= ((predictionBpm < 90) ? STICKY_THRESHOLD_LOW : STICKY_THRESHOLD))
+ {
+ stickyConfidenceCount++;
+ if (stickyConfidenceCount >= MIN_STICKY)
+ sticked=1;
+ }
+ else
+ stickyConfidenceCount=0;
+ }
+
+ Bpm = GetBpm();
+
+ // Count how many beats we discriminated
+ for (i=0;i<TCHistSize;i++)
+ if (halfDiscriminated[i]) hdCount++;
+
+ if (hdCount >= TCHistSize/2) // If we removed at least half of our beats, then we are off course. We should double our bpm
+ {
+ if (Bpm * 2 < MAX_BPM) // Lets do so only if the doubled bpm is < MAX_BPM
+ {
+ doubleBeat();
+ memset(halfDiscriminated, 0, TCHistSize*sizeof(int)); // Reset discrimination table
+ }
+ }
+ if (Bpm > 500 || Bpm < 0)
+ {
+ ResetAdapt();
+ }
+ if (Bpm < MIN_BPM)
+ {
+ if (++doubleCount > 4) // We're going too slow, lets double our bpm
+ doubleBeat();
+ }
+ else
+ doubleCount=0;
+ if (Bpm > MAX_BPM) // We're going too fast, lets slow our bpm by a factor of 2
+ {
+ if (++halfCount > 4)
+ halfBeat();
+ }
+ else
+ halfCount=0;
+ }
+}
+
+void SliderStep(int Ctl, int *slide)
+{
+*slide += Ctl == IDC_IN ? inInc : outInc;
+if (!*slide || *slide == 8) (Ctl == IDC_IN ? inInc : outInc) *= -1;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int refineBeat(int isBeat)
+{
+ BOOL accepted=FALSE;
+ BOOL predicted=FALSE;
+ BOOL resyncin=FALSE;
+ BOOL resyncout=FALSE;
+
+ if (isBeat) // Show the beat received from AVS
+ SliderStep(IDC_IN, &inSlide);
+
+ DWORD TCNow = GetTickCount();
+
+ if (songChanged(TCNow))
+ {
+ bestConfidence=(int)((float)bestConfidence*0.5);
+ sticked=0;
+ stickyConfidenceCount=0;
+ if (cfg_smartbeatresetnewsong)
+ ResetAdapt();
+ }
+
+ // Try to predict if this frame should be a beat
+ if (Bpm && TCNow > predictionLastTC + (60000 / Bpm))
+ predicted = TRUE;
+
+
+ if (isBeat) // If it is a real beat, do discrimination/guessing and computations, then see if it is accepted
+ accepted = TCHistStep(TCHist, Avg, halfDiscriminated, &hdPos, &lastTC, TCNow, BEAT_REAL);
+
+ // Calculate current Bpm
+ CalcBPM();
+
+ // If prediction Bpm has not yet been set
+ // or if prediction bpm is too high or too low
+ // or if 3/4 of our history buffer contains beats within the range of typical drift
+ // the accept the calculated Bpm as the new prediction Bpm
+ // This allows keeping the beat going on when the music fades out, and readapt to the new beat as soon as
+ // the music fades in again
+ if ((accepted || predicted) && !sticked && (!predictionBpm || predictionBpm > MAX_BPM || predictionBpm < MIN_BPM))
+ {
+ if (Confidence >= bestConfidence)
+ {
+/* betterConfidenceCount++;
+ if (!predictionBpm || betterConfidenceCount == BETTER_CONF_ADOPT)
+ {*/
+ forceNewBeat=1;
+/* betterConfidenceCount=0;
+ }*/
+ }
+ if (Confidence >= 50)
+ {
+ topConfidenceCount++;
+ if (topConfidenceCount == TOP_CONF_ADOPT)
+ {
+ forceNewBeat=1;
+ topConfidenceCount=0;
+ }
+ }
+ if (forceNewBeat)
+ {
+ forceNewBeat=0;
+ bestConfidence = Confidence;
+ predictionBpm=Bpm;
+ }
+ }
+
+ if (!sticked) predictionBpm = Bpm;
+ Bpm=predictionBpm;
+
+
+/* resync = (predictionBpm &&
+ (predictionLastTC < TCNow - (30000/predictionBpm) - (60000/predictionBpm)*0.2) ||
+ (predictionLastTC < TCNow - (30000/predictionBpm) - (60000/predictionBpm)*0.2));*/
+ if (predictionBpm && accepted && !predicted)
+ {
+ int b=0;
+ if (TCNow > predictionLastTC + (60000 / predictionBpm)*0.7)
+ {
+ resyncin = TRUE;
+ b = (int)((float)predictionBpm * 1.01);
+ }
+ if (TCNow < predictionLastTC + (60000 / predictionBpm)*0.3)
+ {
+ resyncout = TRUE;
+ b = (int)((float)predictionBpm * 0.98);
+ }
+ if (!sticked && doResyncBpm && (resyncin || resyncout))
+ {
+ newBpm(b);
+ predictionBpm = GetBpm();
+ }
+ }
+
+ if (resyncin)
+ {
+ predictionLastTC = TCNow;
+ SliderStep(IDC_OUT, &outSlide);
+ doResyncBpm=TRUE;
+ return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? 1 : isBeat;
+ }
+ if (predicted)
+ {
+ predictionLastTC = TCNow;
+ if (Confidence > 25) TCHistStep(TCHist, Avg, halfDiscriminated, &hdPos, &lastTC, TCNow, BEAT_GUESSED);
+ SliderStep(IDC_OUT, &outSlide);
+ doResyncBpm=FALSE;
+ return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? 1 : isBeat;
+ }
+ if (resyncout)
+ {
+ predictionLastTC = TCNow;
+ doResyncBpm=TRUE;
+ return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? 0 : isBeat;
+ }
+
+ return ((cfg_smartbeat && !cfg_smartbeatonlysticky) || (cfg_smartbeat && cfg_smartbeatonlysticky && sticked)) ? (predictionBpm ? 0 : isBeat) : isBeat;
+}
+
+
+
diff --git a/Src/Plugins/Visualization/vis_avs/bpm.h b/Src/Plugins/Visualization/vis_avs/bpm.h
new file mode 100644
index 00000000..8b20bff7
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/bpm.h
@@ -0,0 +1,56 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef __BPM_H
+#define __BPM_H
+
+#define BEAT_REAL 1
+#define BEAT_GUESSED 2
+
+#define MAX_BPM 170
+#define MIN_BPM 60
+
+#define BETTER_CONF_ADOPT 2
+#define TOP_CONF_ADOPT 8
+#define MIN_STICKY 8
+#define STICKY_THRESHOLD 70
+#define STICKY_THRESHOLD_LOW 85
+
+typedef struct {
+ DWORD TC; // Tick count
+ int Type; // Real/guessed
+ }BeatType;
+
+
+BOOL CALLBACK DlgProc_Bpm(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+void initBpm(void);
+int refineBeat(int isBeat);
+
+
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/bump_lig.bin b/Src/Plugins/Visualization/vis_avs/bump_lig.bin
new file mode 100644
index 00000000..e7227805
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/bump_lig.bin
@@ -0,0 +1,22 @@
+How to use the custom light position evaluator:
+ * Init code will be executed each time the window size is changed
+ or when the effect loads
+ * Frame code is executed before rendering a new frame
+ * Beat code is executed when a beat is detected
+
+Predefined variables:
+ x : Light x position, ranges from 0 (left) to 1 (right) (0.5 = center)
+ y : Light y position, ranges from 0 (top) to 1 (bottom) (0.5 = center)
+ isBeat : 1 if no beat, -1 if beat (weird, but old)
+ isLBeat: same as isBeat but persists according to 'shorter/longer' settings
+ (usable only with OnBeat checked)
+ bi: Bump intensity, ranges from 0 (flat) to 1 (max specified bump, default)
+ You may also use temporary variables accross code segments
+
+Some examples:
+ Circular move
+ Init : t=0
+ Frame: x=0.5+cos(t)*0.3; y=0.5+sin(t)*0.3; t=t+0.1;
+ Nice motion:
+ Init : t=0;u=0
+ Frame: x=0.5+cos(t)*0.3; y=0.5+cos(u)*0.3; t=t+0.1; u=u+0.012; \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/cfgwin.cpp b/Src/Plugins/Visualization/vis_avs/cfgwin.cpp
new file mode 100644
index 00000000..d16a3ba2
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/cfgwin.cpp
@@ -0,0 +1,1918 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdio.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "vis.h"
+#include "cfgwnd.h"
+#include "resource.h"
+#include "render.h"
+#include "rlib.h"
+#include "draw.h"
+#include "wnd.h"
+#include "bpm.h"
+#include "avs_eelif.h"
+#include "undo.h"
+#include "../Agave/Language/api_language.h"
+#include "../WAT/WAT.h"
+
+#ifdef LASER
+extern "C" {
+#include "laser/ld32.h"
+}
+#endif
+static void _do_add(HWND hwnd, HTREEITEM h, C_RenderListClass *list);
+static int treeview_hack;
+static HTREEITEM g_hroot;
+
+extern int g_config_smp_mt,g_config_smp;
+extern struct winampVisModule *g_mod;
+extern int cfg_cancelfs_on_deactivate;
+
+HWND g_debugwnd;
+
+char g_noeffectstr[48];
+//extern char *verstr;
+static HWND cur_hwnd;
+int is_aux_wnd=0;
+int config_prompt_save_preset=1,config_reuseonresize=1;
+//int g_preset_dirty;
+
+// extern BOOL CALLBACK aboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern BOOL CALLBACK DlgProc_Bpm(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+extern int readyToLoadPreset(HWND parent, int isnew);
+
+extern char *extension(char *fn) ;
+
+int g_dlg_fps,g_dlg_w,g_dlg_h;
+
+int cfg_cfgwnd_x=50,cfg_cfgwnd_y=50,cfg_cfgwnd_open=0;
+
+int cfg_fs_w=0,cfg_fs_h=0,cfg_fs_d=2,cfg_fs_bpp=0,cfg_fs_fps=0,cfg_fs_rnd=1,
+#ifdef LASER
+cfg_fs_flip=6,
+#else
+cfg_fs_flip=0,
+#endif
+cfg_fs_height=80,cfg_speed=5,cfg_fs_rnd_time=10,cfg_fs_use_overlay=0;
+int cfg_trans=0,cfg_trans_amount=128;
+int cfg_dont_min_avs=0;
+int cfg_transitions=4;
+int cfg_transitions2=4|32;
+int cfg_transitions_speed=8;
+int cfg_transition_mode=0x8001;
+int cfg_bkgnd_render=0,cfg_bkgnd_render_color=0x1F000F;
+int cfg_render_prio=0;
+
+char config_pres_subdir[MAX_PATH];
+char last_preset[2048];
+
+static BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+HWND g_hwndDlg;
+
+extern HWND g_hwnd;
+
+#ifdef WA2_EMBED
+#include "wa_ipc.h"
+extern embedWindowState myWindowState;
+#endif
+
+/*
+HINSTANCE g_hDllInstance;
+HWND g_hwndParent;
+HANDLE hcfgThread;
+DWORD WINAPI cfgwnd_thread(LPVOID p)
+{
+ g_hwndDlg=CreateDialog(g_hDllInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,dlgProc);
+ while (1)
+ {
+ MSG msg;
+ if (!GetMessage(&msg,NULL,0,0)) break;
+ if (!IsDialogMessage(g_hwndDlg,&msg)) DispatchMessage(&msg);
+ }
+ return 0;
+}
+*/
+static int ExtractWindowsVersion(void)
+{
+ int dwVersion,dwWindowsMajorVersion,dwWindowsMinorVersion,WindowsType,dwBuild;
+
+ dwVersion = GetVersion();
+
+ // Get major and minor version numbers of Windows
+
+ dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+ dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
+
+ // Get build numbers for Windows NT or Win32s
+ if (dwVersion < 0x80000000) // Windows NT
+ {
+ dwBuild = (DWORD)(HIWORD(dwVersion));
+ WindowsType = 0x4; // VER_WINNT
+ }
+ else if (dwWindowsMajorVersion < 4) // Win32s
+ {
+ dwBuild = (DWORD)(HIWORD(dwVersion) & ~0x8000);
+ WindowsType = 0x2; // VER_WIN32S
+ }
+ else // Windows 95 -- No build numbers provided
+ {
+ dwBuild = 0;
+ WindowsType = 0x1; // VER_WIN95
+ }
+
+ return dwWindowsMajorVersion;
+}
+
+void CfgWnd_Create(struct winampVisModule *this_mod)
+{
+ WASABI_API_CREATEDIALOG(IDD_DIALOG1,this_mod->hwndParent,dlgProc);
+ //CreateDialogA(this_mod->hDllInstance,MAKEINTRESOURCE(IDD_DIALOG1),this_mod->hwndParent,dlgProc);
+}
+
+void CfgWnd_Destroy(void)
+{
+ if (g_hwndDlg && IsWindow(g_hwndDlg))
+ {
+ RECT r;
+ GetWindowRect(g_hwndDlg,&r);
+ cfg_cfgwnd_x=r.left;
+ cfg_cfgwnd_y=r.top;
+ DestroyWindow(g_hwndDlg);
+ }
+ g_hwndDlg=0;
+ if (g_debugwnd) DestroyWindow(g_debugwnd);
+ /*
+ if (hcfgThread)
+ {
+ SendMessage(g_hwndDlg,WM_USER+6,0,0);
+ g_hwndDlg=0;
+ WaitForSingleObject(hcfgThread,INFINITE);
+ CloseHandle(hcfgThread);
+ hcfgThread=0;
+ }
+ */
+}
+
+static void recursiveAddDirList(HMENU menu, UINT *id, char *path, int pathlen)
+{
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[4096];
+ wsprintf(dirmask,"%s\\*.*",path);
+
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do {
+ if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && d.cFileName[0] != '.')
+ {
+ wsprintf(dirmask,"%s\\%s",path,d.cFileName);
+
+ MENUITEMINFO i={sizeof(i),};
+ i.fType=MFT_STRING;
+ i.fMask=MIIM_TYPE|MIIM_ID;
+ i.dwTypeData = dirmask+pathlen+1;
+ i.cch = strlen(i.dwTypeData);
+ i.wID=*id;
+ InsertMenuItem(menu,*id+2-1025,TRUE,&i);
+ (*id)++;
+
+ recursiveAddDirList(menu,id,dirmask,pathlen);
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+}
+
+static BOOL CALLBACK DlgProc_Preset(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int x;
+ for (x = 0; x < 12; x ++)
+ {
+ char s[123];
+ wsprintf(s,"F%d",x+1);
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)s);
+ }
+ for (x = 0; x < 10; x ++)
+ {
+ char s[123];
+ wsprintf(s,"%d",x);
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)s);
+ }
+ for (x = 0; x < 10; x ++)
+ {
+ char s[123];
+ wsprintf(s,WASABI_API_LNGSTRING(IDS_SHIFT_X),x);
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)s);
+ }
+
+ CheckDlgButton(hwndDlg,IDC_CHECK3,cfg_fs_rnd?BST_CHECKED:BST_UNCHECKED);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,cfg_fs_rnd_time,FALSE);
+ if (config_prompt_save_preset)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+
+ if (config_pres_subdir[0])
+ SetDlgItemText(hwndDlg,IDC_BUTTON3,config_pres_subdir);
+ else
+ SetDlgItemText(hwndDlg,IDC_BUTTON3,WASABI_API_LNGSTRING(IDS_ALL));
+ }
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_BUTTON3:
+ {
+ MENUITEMINFO i={sizeof(i),};
+
+ HMENU hMenu;
+ hMenu=CreatePopupMenu();
+ i.fMask=MIIM_TYPE|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.wID = 1024;
+ i.dwTypeData=WASABI_API_LNGSTRING(IDS_ALL);
+ i.cch=strlen(i.dwTypeData);
+ InsertMenuItem(hMenu,0,TRUE,&i);
+ i.wID=0;
+ i.fType=MFT_SEPARATOR;
+ InsertMenuItem(hMenu,1,TRUE,&i);
+
+ UINT id=1025;
+ recursiveAddDirList(hMenu,&id,g_path,strlen(g_path));
+
+ RECT r;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON3),&r);
+
+ int x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.left,r.bottom,0,hwndDlg,NULL);
+ if (x == 1024)
+ {
+ config_pres_subdir[0]=0;
+ SetDlgItemText(hwndDlg,IDC_BUTTON3,WASABI_API_LNGSTRING(IDS_ALL));
+ }
+ else if (x >= 1025)
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_TYPE,};
+ mi.dwTypeData=config_pres_subdir;
+ mi.cch = sizeof(config_pres_subdir);
+ GetMenuItemInfo(hMenu,x,FALSE,&mi);
+ SetDlgItemText(hwndDlg,IDC_BUTTON3,config_pres_subdir);
+ }
+ DestroyMenu(hMenu);
+ }
+ return 0;
+ case IDC_CHECK1:
+ config_prompt_save_preset=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ return 0;
+ case IDC_CHECK3:
+ cfg_fs_rnd=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
+ #ifdef WA2_EMBED
+ SendMessage(g_mod->hwndParent,WM_WA_IPC,cfg_fs_rnd,IPC_CB_VISRANDOM);
+ #endif
+ return 0;
+ case IDC_EDIT1:
+ if (HIWORD(wParam) == EN_CHANGE)
+ {
+ BOOL f;
+ int r=GetDlgItemInt(hwndDlg,IDC_EDIT1,&f,0);
+ if (f)
+ {
+ cfg_fs_rnd_time=r;
+ }
+ }
+ return 0;
+ case IDC_BUTTON1:
+ {
+ int w=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (w != CB_ERR)
+ {
+ extern void WritePreset(int preset);
+ WritePreset(w);
+ }
+ }
+ return 0;
+ case IDC_BUTTON2:
+ if (readyToLoadPreset(hwndDlg,0))
+ {
+ int w=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (w != CB_ERR)
+ {
+ extern int LoadPreset(int preset);
+ LoadPreset(w);
+ }
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static BOOL CALLBACK DlgProc_Disp(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ if (ExtractWindowsVersion()<5)
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TRANS_CHECK),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TRANS_SLIDER),0);
+ }
+ else
+ {
+ CheckDlgButton(hwndDlg,IDC_TRANS_CHECK,cfg_trans?BST_CHECKED:BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg,IDC_TRANS_SLIDER, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(16,255));
+ SendDlgItemMessage(hwndDlg,IDC_TRANS_SLIDER, TBM_SETTICFREQ, 10, (LPARAM)0);
+ SendDlgItemMessage(hwndDlg,IDC_TRANS_SLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)cfg_trans_amount);
+ }
+#ifdef LASER
+ extern int g_laser_nomessage,g_laser_zones;
+ ShowWindow(GetDlgItem(hwndDlg,IDC_L_SUPPRESS_OUTPUT),SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_L_SYNC),SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_L_SUPPRESS_DIALOGS),SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_L_PROJZONES),SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_L_FRAME),SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_L_ACTIVEOUTPUT),SW_SHOWNA);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_THREADSBORDER),SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK4),SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_EDIT1),SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_THREADS),SW_HIDE);
+ CheckDlgButton(hwndDlg,IDC_L_SUPPRESS_DIALOGS,(g_laser_nomessage&1)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_L_SUPPRESS_OUTPUT,(g_laser_nomessage&4)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_L_SYNC,(g_laser_nomessage&8)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_L_ACTIVEOUTPUT,(g_laser_nomessage&2)?BST_CHECKED:BST_UNCHECKED);
+#else
+ CheckDlgButton(hwndDlg,IDC_CHECK4,g_config_smp?BST_CHECKED:0);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,g_config_smp_mt,FALSE);
+#endif
+ }
+#ifdef WA2_EMBED
+ {
+ HWND w = myWindowState.me;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD) w = GetParent(w);
+ char classname[256];
+ GetClassName(w, classname, 255); classname[255] = 0;
+ if (!stricmp(classname, "BaseWindow_RootWnd"))
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_ALPHA), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANS_CHECK), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_TRANS_SLIDER), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_TRANS_TOTAL), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_STATIC_TRANS_NONE), FALSE);
+ }
+ }
+#endif
+ CheckDlgButton(hwndDlg,IDC_CHECK1,(cfg_fs_d&2)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK6,(cfg_fs_flip&4)?BST_UNCHECKED:BST_CHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK3,(cfg_fs_fps&2)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK5,(cfg_fs_fps&4)?BST_CHECKED:BST_UNCHECKED);
+ //CheckDlgButton(hwndDlg,IDC_DONT_MIN_AVS,cfg_dont_min_avs?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK2,config_reuseonresize?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_BKGND_RENDER,(cfg_bkgnd_render&1)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_SETDESKTOPCOLOR,(cfg_bkgnd_render&2)?BST_CHECKED:BST_UNCHECKED);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,80);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,cfg_speed&0xff);
+ SendDlgItemMessage(hwndDlg, IDC_THREAD_PRIORITY, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_SAME_AS_WINAMP));
+ SendDlgItemMessage(hwndDlg, IDC_THREAD_PRIORITY, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_IDLE));
+ SendDlgItemMessage(hwndDlg, IDC_THREAD_PRIORITY, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_LOWEST));
+ SendDlgItemMessage(hwndDlg, IDC_THREAD_PRIORITY, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_NORMAL));
+ SendDlgItemMessage(hwndDlg, IDC_THREAD_PRIORITY, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_HIGHEST));
+ SendDlgItemMessage(hwndDlg, IDC_THREAD_PRIORITY, CB_SETCURSEL, cfg_render_prio, 0);
+ return 1;
+
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_OVERLAYCOLOR:
+ GR_DrawColoredButton(di,cfg_bkgnd_render_color);
+ break;
+ }
+ }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ cfg_speed&=~0xff;
+ cfg_speed|=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_TRANS_SLIDER))
+ {
+ cfg_trans_amount=t;
+ SetTransparency(g_hwnd,cfg_trans,cfg_trans_amount);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+#ifdef LASER
+ case IDC_L_PROJZONES:
+ {
+ extern int g_laser_zones;
+ HMENU hMenu=CreatePopupMenu();
+ int x;
+ for (x=0;x <20; x++)
+ {
+ PROJECTIONZONE pz;
+ if (ReadProjectionZone(x+1,&pz))
+ wsprintf(pz.Name,"Zone %d",x);
+ if (!pz.Name[0]) break;
+
+ MENUITEMINFO i={sizeof(i),};
+ i.wID = x+1;
+ i.fMask=MIIM_TYPE|MIIM_ID|MIIM_STATE;
+ i.fState=(g_laser_zones&(1<<x))?MFS_CHECKED:0;
+ i.fType=MFT_STRING;
+ i.dwTypeData=pz.Name;
+ i.cch=strlen(pz.Name);
+ InsertMenuItem(hMenu,x,TRUE,&i);
+ }
+
+ RECT r;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_L_PROJZONES),&r);
+
+ int v=TrackPopupMenu(hMenu,TPM_NONOTIFY|TPM_RETURNCMD,r.right,r.top,0,GetDlgItem(hwndDlg,IDC_L_PROJZONES),NULL);
+ DestroyMenu(hMenu);
+ if (v > 0)
+ {
+ g_laser_zones^=1<<(v-1);
+ if (!g_laser_zones) g_laser_zones=1;
+ }
+ }
+
+ return 0;
+ case IDC_L_SYNC:
+ {
+ extern int g_laser_nomessage;
+ g_laser_nomessage&=~8;
+ g_laser_nomessage|=IsDlgButtonChecked(hwndDlg,IDC_L_SYNC)?8:0;
+ }
+ return 0;
+ case IDC_L_SUPPRESS_OUTPUT:
+ {
+ extern int g_laser_nomessage;
+ g_laser_nomessage&=~4;
+ g_laser_nomessage|=IsDlgButtonChecked(hwndDlg,IDC_L_SUPPRESS_OUTPUT)?4:0;
+ }
+ return 0;
+ case IDC_L_SUPPRESS_DIALOGS:
+ {
+ extern int g_laser_nomessage;
+ g_laser_nomessage&=~1;
+ g_laser_nomessage|=IsDlgButtonChecked(hwndDlg,IDC_L_SUPPRESS_DIALOGS)?1:0;
+ }
+ return 0;
+ case IDC_L_ACTIVEOUTPUT:
+ {
+ extern int g_laser_nomessage;
+ g_laser_nomessage&=~2;
+ g_laser_nomessage|=IsDlgButtonChecked(hwndDlg,IDC_L_ACTIVEOUTPUT)?2:0;
+ }
+ return 0;
+#else
+ case IDC_CHECK4:
+ g_config_smp=!!IsDlgButtonChecked(hwndDlg,IDC_CHECK4);
+ return 0;
+ case IDC_EDIT1:
+ {
+ BOOL t;
+ g_config_smp_mt=GetDlgItemInt(hwndDlg,IDC_EDIT1,&t,FALSE);
+ }
+ return 0;
+#endif
+ case IDC_TRANS_CHECK:
+ cfg_trans=IsDlgButtonChecked(hwndDlg,IDC_TRANS_CHECK)?1:0;
+ SetTransparency(g_hwnd,cfg_trans,cfg_trans_amount);
+ return 0;
+ case IDC_CHECK1:
+ cfg_fs_d&=~2;
+ cfg_fs_d|=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?2:0;
+ {
+ RECT r;
+ extern void GetClientRect_adj(HWND hwnd, RECT *r);
+ GetClientRect_adj(g_hwnd,&r);
+ DDraw_Resize(r.right,r.bottom,cfg_fs_d&2);
+ }
+
+ return 0;
+ case IDC_CHECK6:
+ cfg_fs_flip&=~4;
+ cfg_fs_flip|=IsDlgButtonChecked(hwndDlg,IDC_CHECK6)?0:4;
+ return 0;
+ case IDC_CHECK3:
+ cfg_fs_fps&=~2;
+ cfg_fs_fps|=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?2:0;
+ return 0;
+ case IDC_CHECK5:
+ cfg_fs_fps&=~4;
+ cfg_fs_fps|=IsDlgButtonChecked(hwndDlg,IDC_CHECK5)?4:0;
+ return 0;
+ case IDC_CHECK2:
+ config_reuseonresize = !!IsDlgButtonChecked(hwndDlg,IDC_CHECK2);
+ return 0;
+// case IDC_DONT_MIN_AVS:
+ // cfg_dont_min_avs=IsDlgButtonChecked(hwndDlg,IDC_DONT_MIN_AVS)?1:0;
+ case IDC_DEFOVERLAYCOLOR:
+ cfg_bkgnd_render_color=0x1F000F;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_OVERLAYCOLOR),NULL,FALSE);
+ goto update_overlayshit;
+ case IDC_OVERLAYCOLOR:
+ GR_SelectColor(hwndDlg,&cfg_bkgnd_render_color);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_OVERLAYCOLOR),NULL,FALSE);
+ goto update_overlayshit;
+ case IDC_SETDESKTOPCOLOR:
+ case IDC_BKGND_RENDER:
+ cfg_bkgnd_render=(IsDlgButtonChecked(hwndDlg,IDC_BKGND_RENDER)?1:0) |
+ (IsDlgButtonChecked(hwndDlg,IDC_SETDESKTOPCOLOR)?2:0);
+ update_overlayshit:
+ {
+ RECT r;
+ extern void GetClientRect_adj(HWND hwnd, RECT *r);
+ GetClientRect_adj(g_hwnd,&r);
+ DDraw_Resize(r.right,r.bottom,cfg_fs_d&2);
+ }
+ return 0;
+ case IDC_THREAD_PRIORITY:
+ extern void main_setRenderThreadPriority();
+ cfg_render_prio=SendDlgItemMessage(hwndDlg,IDC_THREAD_PRIORITY,CB_GETCURSEL,0,0);
+ main_setRenderThreadPriority();
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+static void enableFSWindows(HWND hwndDlg, int v)
+{
+ EnableWindow(GetDlgItem(hwndDlg,IDC_BPP_CONV),v);
+ //EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),v);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK4),v);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK2),v);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),v);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK5),v);
+}
+
+extern int cfg_fs_dblclk;
+
+static BOOL CALLBACK DlgProc_FS(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int l;
+ DDraw_EnumDispModes(GetDlgItem(hwndDlg,IDC_COMBO1));
+ l=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCOUNT,0,0);
+ if (l < 1 || l == CB_ERR)
+ {
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRING(IDS_NO_SUITABLE_MODES_FOUND));
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,0,0);
+ }
+ else
+ {
+ int x;
+ for (x = 0; x < l; x ++)
+ {
+ char b[256],*p=b;
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETLBTEXT,x,(long)b);
+ int w,h,bpp;
+ w=atoi(p);
+ while (*p >= '0' && *p <= '9') p++;
+ if (!*p) continue;
+ h=atoi(++p);
+ while (*p >= '0' && *p <= '9') p++;
+ if (!*p) continue;
+ bpp=atoi(++p);
+ if (w == cfg_fs_w && h == cfg_fs_h && bpp == cfg_fs_bpp)
+ break;
+ }
+ if (x != l)
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,x,0);
+ }
+ CheckDlgButton(hwndDlg,IDC_USE_OVERLAY,cfg_fs_use_overlay?BST_CHECKED:BST_UNCHECKED);
+ enableFSWindows(hwndDlg,!cfg_fs_use_overlay);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK8), cfg_fs_use_overlay);
+ CheckDlgButton(hwndDlg,IDC_CHECK1,(cfg_fs_d&1)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK2,(cfg_fs_fps&1)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK3,(cfg_fs_fps&8)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK5,(cfg_fs_fps&16)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK4,(cfg_fs_flip&1)?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK7,(cfg_fs_flip&2)?BST_UNCHECKED:BST_CHECKED);
+ CheckDlgButton(hwndDlg,IDC_CHECK8,(cfg_cancelfs_on_deactivate)?BST_UNCHECKED:BST_CHECKED);
+ CheckDlgButton(hwndDlg,IDC_BPP_CONV,(cfg_fs_flip&8)?BST_UNCHECKED:BST_CHECKED);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,cfg_fs_height,FALSE);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,80);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,(cfg_speed>>8)&0xff);
+ CheckDlgButton(hwndDlg,IDC_CHECK6,cfg_fs_dblclk?BST_CHECKED:BST_UNCHECKED);
+ }
+ return 1;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ cfg_speed&=~0xff00;
+ cfg_speed|=(t<<8);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_BUTTON1:
+ if (IsDlgButtonChecked(hwndDlg,IDC_USE_OVERLAY) || DDraw_IsMode(cfg_fs_w,cfg_fs_h,cfg_fs_bpp))
+ {
+ SetForegroundWindow(g_hwnd);
+ PostMessage(g_hwnd,WM_USER+32,0,0);
+ } else
+ {
+ char title[32];
+ MessageBox(hwndDlg,WASABI_API_LNGSTRING(IDS_CHOOSE_A_VIDEO_MODE),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_FULLSCREEN,title,32),MB_OK);
+ }
+ return 0;
+ case IDC_BPP_CONV:
+ cfg_fs_flip&=~8;
+ cfg_fs_flip|=IsDlgButtonChecked(hwndDlg,IDC_BPP_CONV)?0:8;
+ return 0;
+ case IDC_CHECK6:
+ cfg_fs_dblclk=!!IsDlgButtonChecked(hwndDlg,IDC_CHECK6);
+ return 0;
+ case IDC_CHECK1:
+ cfg_fs_d&=~1;
+ cfg_fs_d|=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ return 0;
+ case IDC_CHECK2:
+ cfg_fs_fps&=~1;
+ cfg_fs_fps|=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
+ return 0;
+ case IDC_CHECK3:
+ cfg_fs_fps&=~8;
+ cfg_fs_fps|=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?8:0;
+ return 0;
+ case IDC_CHECK5:
+ cfg_fs_fps&=~16;
+ cfg_fs_fps|=IsDlgButtonChecked(hwndDlg,IDC_CHECK5)?16:0;
+ return 0;
+ case IDC_CHECK4:
+ cfg_fs_flip&=~1;
+ cfg_fs_flip|=IsDlgButtonChecked(hwndDlg,IDC_CHECK4)?1:0;
+ return 0;
+ case IDC_CHECK7:
+ cfg_fs_flip&=~2;
+ cfg_fs_flip|=IsDlgButtonChecked(hwndDlg,IDC_CHECK7)?0:2;
+ return 0;
+ case IDC_CHECK8:
+ cfg_cancelfs_on_deactivate = IsDlgButtonChecked(hwndDlg,IDC_CHECK8)?0:1;
+ return 0;
+ case IDC_EDIT1:
+ if (HIWORD(wParam) == EN_CHANGE) {
+ BOOL t;
+ int r=GetDlgItemInt(hwndDlg,IDC_EDIT1,&t,FALSE);
+ if (r > 0 && r <= 100 && t)
+ cfg_fs_height=r;
+ }
+ return 0;
+ case IDC_COMBO1:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int bps=-1;
+ char b[256],*p=b;
+ int l=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (l == CB_ERR) return 0;
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETLBTEXT,l,(long)b);
+ int w,h;
+ while (*p >= '0' && *p <= '9') p++;
+ if (!*p) return 0;
+ *p++=0;
+ w=atoi(b);
+ while (*p < '0' && *p > '9' && *p) p ++;
+ h=atoi(p);
+ while (*p >= '0' && *p <= '9') p++;
+ if (!*p) return 0;
+ p++;
+ bps=atoi(p);
+ if (w < 1|| h < 1 || bps < 1) return 0;
+ cfg_fs_h=h;
+ cfg_fs_w=w;
+ cfg_fs_bpp=bps;
+ }
+ return 0;
+ case IDC_USE_OVERLAY:
+ cfg_fs_use_overlay=IsDlgButtonChecked(hwndDlg,IDC_USE_OVERLAY)?1:0;
+ enableFSWindows(hwndDlg,!cfg_fs_use_overlay);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK8), cfg_fs_use_overlay);
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+static void _insertintomenu2(HMENU hMenu, int wid, int id, char *str)
+{
+ int x;
+ for (x=0; x < 4096; x ++)
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_DATA|MIIM_TYPE|MIIM_SUBMENU,MFT_STRING};
+ char c[512];
+ mi.dwTypeData=c;
+ mi.cch = 512;
+ if (!GetMenuItemInfo(hMenu,x,TRUE,&mi)) break;
+ if (strcmp(str,c)<0 && !mi.hSubMenu)
+ break;
+ }
+
+ MENUITEMINFO i={sizeof(i),};
+ i.wID = wid;
+ i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.dwItemData=id;
+ i.dwTypeData=str;
+ i.cch=strlen(str);
+ InsertMenuItem(hMenu,x,TRUE,&i);
+}
+
+static HMENU _findsubmenu(HMENU hmenu, char *str)
+{
+ int x;
+ for (x=0; x < 4096; x ++)
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_DATA|MIIM_TYPE|MIIM_SUBMENU,MFT_STRING};
+ char c[512];
+ mi.dwTypeData=c;
+ mi.cch = 512;
+ if (!GetMenuItemInfo(hmenu,x,TRUE,&mi)) break;
+ if (!strcmp(str,c) && mi.hSubMenu) return mi.hSubMenu;
+ }
+ return 0;
+}
+
+static void _insertintomenu(HMENU hMenu, int wid, int id, char *str)
+{
+ char ostr[1024];
+ strncpy(ostr,str,1023);
+ char *first=str;
+ char *second=str;
+ while (*second && *second != '/') second++;
+ if (*second) *second++=0;
+ if (*second)
+ {
+ while (*second == ' ' || *second == '/') second++;
+ if (*second)
+ {
+ HMENU hs;
+
+ if (!(hs=_findsubmenu(hMenu,first)))
+ {
+ MENUITEMINFO i={sizeof(i),};
+ i.fMask=MIIM_TYPE|MIIM_SUBMENU|MIIM_DATA|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.dwTypeData = first;
+ i.cch = strlen(first);
+ i.hSubMenu=hs=CreatePopupMenu();
+ i.wID=0;
+ InsertMenuItem(hMenu,0,TRUE,&i);
+ }
+ _insertintomenu2(hs,wid,id,second);
+ return;
+ }
+ }
+ _insertintomenu2(hMenu,wid,id,ostr);
+
+}
+static HTREEITEM g_dragsource_item,g_dragsource_parent, g_draglastdest, g_dragplace;
+static int g_dragplaceisbelow;
+extern int findInMenu(HMENU parent, HMENU sub, UINT id, char *buf, int buf_len);
+
+#define UNDO_TIMER_INTERVAL 333
+
+static WNDPROC sniffConfigWindow_oldProc;
+static BOOL CALLBACK sniffConfigWindow_newProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ bool dirty = false;
+ if (uMsg == WM_COMMAND || uMsg == WM_HSCROLL || uMsg == WM_VSCROLL)
+ {
+ if (uMsg != WM_COMMAND || HIWORD(wParam) == EN_CHANGE ||
+ HIWORD(wParam) == BN_CLICKED ||
+ HIWORD(wParam) == LBN_SELCHANGE ||
+ HIWORD(wParam) == CBN_SELCHANGE
+
+ )
+ dirty = true;
+ }
+
+ BOOL retval = CallWindowProc(sniffConfigWindow_oldProc,hwndDlg,uMsg,wParam,lParam);
+
+ // Don't save the new state until the window proc handles it. :)
+ if (dirty)
+ {
+ KillTimer(GetParent(hwndDlg),69);
+ SetTimer(GetParent(hwndDlg),69,UNDO_TIMER_INTERVAL,NULL);
+
+
+// g_preset_dirty=1;
+ }
+
+ return retval;
+}
+
+
+int dosavePreset(HWND hwndDlg)
+{
+ int r=1;
+ char temp[2048];
+ OPENFILENAME l={sizeof(l),0};
+ char buf1[2048],buf2[2048];
+ char filter[128], *ptr = filter;
+ char savePreset[64];
+
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_FILTER_STRING,filter,128);
+ while(*ptr)
+ {
+ if (*ptr=='|') *ptr=0;
+ ptr++;
+ }
+ temp[0]=0;
+ GetCurrentDirectory(sizeof(buf2),buf2);
+ strcpy(buf1,g_path);
+ l.hwndOwner = hwndDlg;
+ l.lpstrFilter = filter;
+ l.lpstrFile = temp;
+ strcpy(temp,last_preset);
+ l.nMaxFile = 2048-1;
+ l.lpstrTitle = WASABI_API_LNGSTRING_BUF(IDS_SAVE_PRESET,savePreset,64);
+ l.lpstrDefExt = "AVS";
+ l.lpstrInitialDir = buf1;
+ l.Flags = OFN_HIDEREADONLY|OFN_EXPLORER|OFN_OVERWRITEPROMPT;
+ if (GetSaveFileName(&l))
+ {
+ strcpy(last_preset,temp); // this was changed from: lstrcpyn(last_preset,temp, 2048);
+ r=g_render_effects->__SavePreset(temp);
+ if (r==1) MessageBox(hwndDlg,WASABI_API_LNGSTRING(IDS_ERROR_SAVING_PRESET),savePreset,MB_OK);
+ else if (r==2) MessageBox(hwndDlg,WASABI_API_LNGSTRING(IDS_PRESET_TOO_LARGE),savePreset,MB_OK);
+ else if (r==-1) MessageBox(hwndDlg,WASABI_API_LNGSTRING(IDS_OUT_OF_MEMORY),savePreset,MB_OK);
+ else
+ {
+ C_UndoStack::cleardirty();
+ // g_preset_dirty=0;
+ }
+ }
+ SetCurrentDirectory(buf2);
+ return r;
+}
+
+extern int g_config_seh;
+
+static BOOL CALLBACK debugProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ extern int debug_reg[8];
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int x;
+ for (x = 0; x < 8; x ++)
+ {
+ SetDlgItemInt(hwndDlg,IDC_DEBUGREG_1+x*2,debug_reg[x],FALSE);
+ }
+ SetTimer(hwndDlg,1,250,NULL);
+ }
+ if (g_log_errors) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_reset_vars_on_recompile) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ if (!g_config_seh) CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+
+ return 0;
+ case WM_TIMER:
+ if (wParam == 1)
+ {
+ int x;
+ for (x = 0; x < 8; x ++)
+ {
+ char buf[128];
+ int v=debug_reg[x];
+ if (v >=0 && v < 100)
+ sprintf(buf,"%.14f",NSEEL_getglobalregs()[v]);
+ else strcpy(buf,"?");
+ SetDlgItemText(hwndDlg,IDC_DEBUGREG_1+x*2+1,buf);
+ }
+
+ if (g_log_errors)
+ {
+ //IDC_EDIT1
+ EnterCriticalSection(&g_eval_cs);
+ char buf[1025];
+ GetDlgItemText(hwndDlg,IDC_EDIT1,buf,sizeof(buf)-1);
+ buf[sizeof(buf)-1]=0;
+ if (strcmp(buf,last_error_string))
+ SetDlgItemText(hwndDlg,IDC_EDIT1,last_error_string);
+ LeaveCriticalSection(&g_eval_cs);
+ }
+
+ {
+ char buf[512];
+ int *g_evallib_stats=NSEEL_getstats();
+ wsprintf(buf,WASABI_API_LNGSTRING(IDS_EVAL_CODE_STATS_ETC),
+ g_evallib_stats[4],g_evallib_stats[0],g_evallib_stats[1],g_evallib_stats[2],g_evallib_stats[3]);
+ SetDlgItemText(hwndDlg,IDC_EDIT2,buf);
+ }
+
+ }
+ return 0;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHECK1:
+ g_log_errors = !!IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
+ return 0;
+ case IDC_CHECK2:
+ g_reset_vars_on_recompile = !!IsDlgButtonChecked(hwndDlg,IDC_CHECK2);
+ return 0;
+ case IDC_CHECK3:
+ g_config_seh = !IsDlgButtonChecked(hwndDlg,IDC_CHECK3);
+ return 0;
+ case IDC_BUTTON1:
+ EnterCriticalSection(&g_eval_cs);
+ last_error_string[0]=0;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,"");
+ LeaveCriticalSection(&g_eval_cs);
+ return 0;
+ case IDOK:
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ return 0;
+ default:
+ if (HIWORD(wParam) == EN_CHANGE && LOWORD(wParam) >= IDC_DEBUGREG_1 && LOWORD(wParam) <= IDC_DEBUGREG_16)
+ {
+ int x=LOWORD(wParam)-IDC_DEBUGREG_1;
+ if (!(x&1))
+ {
+ x/=2;
+ if (x > 7) x= 7;
+ BOOL t;
+ int v=GetDlgItemInt(hwndDlg,IDC_DEBUGREG_1+x*2,&t,FALSE);
+ if (t) debug_reg[x]=v;
+ }
+ }
+ break;
+ }
+ return 0;
+ case WM_DESTROY:
+ g_debugwnd=0;
+ return 0;
+ }
+ return 0;
+}
+
+static BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static HMENU presetTreeMenu;
+ static int presetTreeCount;
+ extern int need_redock;
+ extern int inWharf;
+ extern void toggleWharfAmpDock(HWND hwnd);
+
+ switch (uMsg)
+ {
+ case WM_INITMENU:
+ EnableMenuItem((HMENU)wParam,IDM_UNDO,MF_BYCOMMAND|(C_UndoStack::can_undo()?MF_ENABLED:MF_GRAYED));
+ EnableMenuItem((HMENU)wParam,IDM_REDO,MF_BYCOMMAND|(C_UndoStack::can_redo()?MF_ENABLED:MF_GRAYED));
+ return 0;
+ case WM_INITMENUPOPUP:
+ if (!HIWORD(lParam) && presetTreeMenu && !GetMenuItemCount((HMENU)wParam))
+ {
+ char buf[2048];
+ buf[0]=0;
+ if (findInMenu(presetTreeMenu,(HMENU)wParam,0,buf,2048))
+ {
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[4096];
+ wsprintf(dirmask,"%s%s\\*.*",g_path,buf);
+ int directory_pos=0, insert_pos=0;
+ // build menu
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && d.cFileName[0] != '.')
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,MFS_DEFAULT };
+ mi.hSubMenu=CreatePopupMenu();
+ mi.dwTypeData=d.cFileName;
+ mi.cch = strlen(d.cFileName);
+ InsertMenuItem((HMENU)wParam,directory_pos++,TRUE,&mi);
+ insert_pos++;
+ }
+ else if (!stricmp(extension(d.cFileName),"avs"))
+ {
+ extension(d.cFileName)[-1]=0;
+ MENUITEMINFO i={sizeof(i),MIIM_TYPE|MIIM_DATA|MIIM_ID,MFT_STRING,MFS_DEFAULT };
+ i.dwTypeData = d.cFileName;
+ i.cch = strlen(d.cFileName);
+ i.dwItemData=0xFFFFFFFF;//preset
+ i.wID=presetTreeCount++;
+ InsertMenuItem((HMENU)wParam,insert_pos++,TRUE,&i);
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+ }
+ }
+ return 0;
+ case WM_USER+20:
+ CfgWnd_Unpopulate();
+ CfgWnd_Populate();
+ return 0;
+ case WM_CLOSE:
+ if (inWharf)
+ {
+#ifdef WA2_EMBED
+ toggleWharfAmpDock(g_hwnd);
+ }
+#else
+ PostMessage(g_hwnd,WM_CLOSE,0,0);
+ }
+ else
+#endif
+ {
+ cfg_cfgwnd_open=0;
+ ShowWindow(hwndDlg,SW_HIDE);
+ }
+ return 0;
+ case WM_DESTROY:
+ return 0;
+ case WM_INITDIALOG:
+ {
+ #ifdef LASER
+ HMENU m=GetMenu(hwndDlg);
+ m=GetSubMenu(m,1);
+ DeleteMenu(m,IDM_TRANSITIONS,MF_BYCOMMAND);
+ #endif
+ g_hwndDlg=hwndDlg;
+ //SetDlgItemText(hwndDlg,IDC_AVS_VER,verstr);
+ WASABI_API_LNGSTRING_BUF(IDS_NO_EFFECT_SETTING_SELECTED,g_noeffectstr,48);
+
+ TreeView_SetIndent(GetDlgItem(hwndDlg,IDC_TREE1),8);
+ SetTimer(hwndDlg,1,250,NULL);
+ if (cfg_cfgwnd_open)
+ ShowWindow(hwndDlg,SW_SHOWNA);
+ CfgWnd_Populate();
+ SetWindowPos(hwndDlg,NULL,cfg_cfgwnd_x,cfg_cfgwnd_y,0,0,SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER);
+ if (need_redock)
+ {
+ need_redock=0;
+ toggleWharfAmpDock(g_hwnd);
+ }
+ else
+ {
+ RECT r,r2;
+ // hide IDC_RRECT, resize IDC_TREE1 up
+ GetWindowRect(GetDlgItem(g_hwndDlg,IDC_RRECT),&r);
+ GetWindowRect(GetDlgItem(g_hwndDlg,IDC_TREE1),&r2);
+ ShowWindow(GetDlgItem(g_hwndDlg,IDC_RRECT),SW_HIDE);
+ SetWindowPos(GetDlgItem(g_hwndDlg,IDC_TREE1),NULL,0,0,r2.right-r2.left,r.bottom - r2.top - 2,SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
+ }
+ }
+ return TRUE;
+ case WM_TIMER:
+ if (wParam == 1)
+ {
+ char s[1024];
+ char *tp=last_preset;
+ while (*tp) tp++;
+ while (tp >= last_preset && *tp != '\\')
+ tp--;
+ tp++;
+ wsprintf(s,"%d.%d FPS @ %dx%d%s%s",g_dlg_fps/10,g_dlg_fps%10,g_dlg_w,g_dlg_h,*tp?" - ":".",tp);
+ tp=s;
+ while (*tp) tp++;
+ while (tp > s && *tp != '.' && *tp != '-') tp--;
+ if (*tp == '.') *tp=0;
+ SetDlgItemText(hwndDlg,IDC_FPS,s);
+ }
+ if (wParam == 69)
+ {
+ KillTimer(hwndDlg,69);
+ C_UndoStack::saveundo();
+ }
+ return FALSE;
+ case WM_MOUSEMOVE:
+ if (g_dragsource_item)
+ {
+ TVHITTESTINFO hti={0,};
+ HWND hwnd=GetDlgItem(hwndDlg,IDC_TREE1);
+ hti.pt.x=(int)LOWORD(lParam);
+ hti.pt.y=(int)HIWORD(lParam);
+ ClientToScreen(hwndDlg,&hti.pt);
+ ScreenToClient(hwnd,&hti.pt);
+ HTREEITEM h=TreeView_HitTest(hwnd,&hti);
+ if (hti.flags&TVHT_ABOVE)
+ {
+ SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,NULL);
+ }
+ if (hti.flags&TVHT_BELOW)
+ {
+ SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,NULL);
+ }
+ if (hti.flags&TVHT_NOWHERE)
+ {
+ h=g_hroot;
+ }
+ if ((hti.flags&(TVHT_NOWHERE|TVHT_ONITEMINDENT|TVHT_ONITEMRIGHT|TVHT_ONITEM|TVHT_ONITEMBUTTON))&&h)
+ {
+ HTREEITEM temp=h;
+ while (temp && temp != TVI_ROOT)
+ {
+ if (temp==g_dragsource_item)
+ {
+ h=g_dragsource_item;
+ break;
+ }
+ temp=TreeView_GetParent(hwnd,temp);
+ }
+ if (h == g_dragsource_item)
+ {
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)));
+ if (g_dragplace) TreeView_DeleteItem(hwnd,g_dragplace);
+ g_dragplace=0;
+ }
+ else
+ {
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,h,0,0,0,0,0};
+ TreeView_GetItem(hwnd,&i);
+ if(i.lParam)
+ {
+ RECT r;
+ TreeView_GetItemRect(hwnd,h,&r,FALSE);
+ if (hti.pt.y > r.bottom-(r.bottom-r.top)/2) g_dragplaceisbelow=1;
+ else g_dragplaceisbelow=0;
+ HTREEITEM parenth;
+ g_draglastdest=h;
+ C_RenderListClass::T_RenderListType *it=(C_RenderListClass::T_RenderListType *)i.lParam;
+
+ if (it->effect_index==LIST_ID && (hti.flags&(TVHT_ONITEMINDENT|TVHT_ONITEMBUTTON)||h==g_hroot))
+ {
+ if (g_dragplace && (TreeView_GetParent(hwnd,g_dragplace)!=h ||
+ TreeView_GetNextSibling(hwnd,g_dragplace)))
+ {
+ TreeView_DeleteItem(hwnd,g_dragplace);
+ g_dragplace=0;
+ }
+
+ g_dragplaceisbelow=2;
+ parenth=h;
+ h=TVI_LAST;
+ }
+ else
+ {
+ parenth=TreeView_GetParent(hwnd,h);
+ if (g_dragplace && ((g_dragplaceisbelow&1)?
+ TreeView_GetNextSibling(hwnd,h)!=g_dragplace:
+ TreeView_GetPrevSibling(hwnd,h)!=g_dragplace))
+ {
+ TreeView_DeleteItem(hwnd,g_dragplace);
+ g_dragplace=0;
+ }
+ if (!g_dragplaceisbelow)
+ {
+ h=TreeView_GetPrevSibling(hwnd,h);
+ if (!h) h=TVI_FIRST;
+ }
+ }
+ if (!g_dragplace)
+ {
+ TV_INSERTSTRUCT is={parenth,h,{TVIF_PARAM|TVIF_TEXT|TVIF_CHILDREN,0,0,0,
+ WASABI_API_LNGSTRING(IDS_MOVE_HERE),0,0,0,0,(int)0}};
+ g_dragplace=TreeView_InsertItem(hwnd,&is);
+ if (g_dragplaceisbelow==2)
+ SendMessage(hwnd,TVM_EXPAND,TVE_EXPAND,(long)parenth);
+ }
+ }
+ }
+ }
+ return 0;
+ }
+ break;
+ case WM_LBUTTONUP:
+ if (g_dragsource_item)
+ {
+ HWND hwnd=GetDlgItem(hwndDlg,IDC_TREE1);
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
+ if (g_dragplace)
+ {
+ TreeView_DeleteItem(hwnd,g_dragplace);
+ g_dragplace=0;
+ }
+ HTREEITEM h=g_draglastdest;
+ if (h)
+ {
+ C_RenderListClass::T_RenderListType *source, *source_parent;
+ C_RenderListClass::T_RenderListType *dest, // handle of item to insert above. NULL if end.
+ *dest_parent=NULL; // handle of parent to insert into
+ HTREEITEM dest_handle=h, // handle of item to insert above. NULL if folder.
+ dest_parent_handle=TreeView_GetParent(hwnd,h); // handle of parent
+ {
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,dest_handle,0,0,0,0,0};
+ TreeView_GetItem(hwnd,&i);
+ dest=(C_RenderListClass::T_RenderListType *)i.lParam;
+ }
+ if (dest_parent_handle)
+ {
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,dest_parent_handle,0,0,0,0,0};
+ TreeView_GetItem(hwnd,&i);
+ dest_parent=(C_RenderListClass::T_RenderListType *)i.lParam;
+ }
+ if (dest->effect_index==LIST_ID && (!dest_parent_handle||g_dragplaceisbelow==2))
+ {
+ dest_parent_handle=dest_handle;
+ dest_handle=NULL;
+ dest_parent=dest;
+ dest=NULL;
+ }
+
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM|TVIF_STATE,g_dragsource_item,0,TVIS_EXPANDED,0,0,0};
+ TreeView_GetItem(hwnd,&i);
+ int expand=i.state&TVIS_EXPANDED;
+ source=(C_RenderListClass::T_RenderListType *)i.lParam;
+
+ TV_ITEM i2={TVIF_HANDLE|TVIF_PARAM,g_dragsource_parent,0,0,0,0,0};
+ TreeView_GetItem(hwnd,&i2);
+ source_parent=(C_RenderListClass::T_RenderListType *)i2.lParam;
+
+ int recurse_okay=1;
+ {
+ HTREEITEM temp=dest_parent_handle;
+ while (temp && temp != TVI_ROOT)
+ {
+ if (temp==g_dragsource_item) recurse_okay=0;
+ temp=TreeView_GetParent(hwnd,temp);
+ }
+ }
+ if (dest_handle != g_dragsource_item && recurse_okay)
+ {
+ C_RenderListClass *s=(C_RenderListClass *)source_parent->render;
+ C_RenderListClass *d=(C_RenderListClass *)dest_parent->render;
+ int os=0;
+ int a=s->findRender(source);
+ int b=d->findRender(dest);
+ int err=1;
+ if (a >= 0)
+ {
+ EnterCriticalSection(&g_render_cs);
+ err=s->removeRender(a,0);
+ if (!err)
+ {
+ d->insertRender(source,b+(g_dragplaceisbelow&1));
+ }
+ LeaveCriticalSection(&g_render_cs);
+ }
+ if (err)
+ {
+ char title[48];
+ MessageBox(NULL,WASABI_API_LNGSTRING(IDS_ERROR_TREE_INCONSISTANCY),
+ WASABI_API_LNGSTRING_BUF(IDS_CRITICAL_ERROR_OCCURRED,title,48),MB_OK);
+ }
+
+ treeview_hack=1;
+ TreeView_DeleteItem(hwnd,g_dragsource_item);
+
+ TV_INSERTSTRUCT is={dest_parent_handle,0,{TVIF_PARAM|TVIF_TEXT|TVIF_CHILDREN,0,0,0,source->render->get_desc(),0,0,0,source->effect_index==LIST_ID?1:0,(int)source}};
+
+ if (dest_handle)
+ {
+ if (g_dragplaceisbelow&1) is.hInsertAfter=dest_handle;
+ else
+ {
+ is.hInsertAfter=TreeView_GetPrevSibling(hwnd,dest_handle);
+ if (!is.hInsertAfter) is.hInsertAfter=TVI_FIRST;
+ }
+ }
+ else is.hInsertAfter=TVI_LAST;
+
+ HTREEITEM newi=TreeView_InsertItem(hwnd,&is);
+ if (source->effect_index == LIST_ID)
+ {
+ _do_add(hwnd,newi,(C_RenderListClass *)source->render);
+ if (expand) SendMessage(hwnd,TVM_EXPAND,TVE_EXPAND,(long)newi);
+ }
+ TreeView_Select(hwnd,newi,TVGN_CARET);
+ treeview_hack=0;
+
+ // After everything is changed, then save the undo and set the dirty bit.
+ KillTimer(hwndDlg,69);
+ SetTimer(hwndDlg,69,UNDO_TIMER_INTERVAL,NULL);
+ // g_preset_dirty=1;
+ }
+ }
+ TreeView_Select(hwnd,NULL,TVGN_DROPHILITE);
+ ReleaseCapture();
+ g_dragsource_item=0;
+ return 0;
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ NM_TREEVIEW* p = (NM_TREEVIEW*)lParam;
+ if (p->hdr.hwndFrom == GetDlgItem(hwndDlg, IDC_TREE1))
+ {
+ // Element is being dragged
+ if (p->hdr.code==TVN_BEGINDRAG)
+ {
+ if (p->itemNew.hItem != g_hroot)
+ {
+ g_draglastdest=0;
+ g_dragsource_parent=TreeView_GetParent(p->hdr.hwndFrom,p->itemNew.hItem);
+ if (g_dragsource_parent)
+ {
+ SetCapture(hwndDlg);
+ g_dragsource_item=p->itemNew.hItem;
+ g_dragplace=0;
+
+ TreeView_Select(p->hdr.hwndFrom,g_dragsource_item,TVGN_CARET);
+ SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_APPSTARTING)));
+ }
+ else
+ g_dragsource_item=NULL;
+ }
+ else
+ g_dragsource_item=NULL;
+ }
+ // new element is selected selectis
+ if ((p->hdr.code== TVN_SELCHANGEDW || p->hdr.code == TVN_SELCHANGEDA) && !treeview_hack)
+ {
+ HTREEITEM hTreeItem = TreeView_GetSelection(p->hdr.hwndFrom);
+ if (hTreeItem)
+ {
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,hTreeItem,0,0,0,0,0};
+ TreeView_GetItem(p->hdr.hwndFrom,&i);
+ C_RenderListClass::T_RenderListType *tp=(C_RenderListClass::T_RenderListType *)i.lParam;
+ is_aux_wnd=0;
+ if (tp&&tp->render)
+ {
+ SetDlgItemText(hwndDlg,IDC_EFNAME,tp->render->get_desc());
+ if (cur_hwnd)
+ DestroyWindow(cur_hwnd);
+ cur_hwnd=tp->render->conf(g_render_library->GetRendererInstance(tp->effect_index,g_hInstance),hwndDlg);
+ if (cur_hwnd)
+ sniffConfigWindow_oldProc=(WNDPROC)SetWindowLong(cur_hwnd, GWLP_WNDPROC,(LONG)sniffConfigWindow_newProc);
+ }
+ if (cur_hwnd)
+ {
+ RECT r;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_EFFECTRECT),&r);
+ ScreenToClient(hwndDlg,(LPPOINT)&r);
+ SetWindowPos(cur_hwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
+ ShowWindow(cur_hwnd,SW_SHOWNA);
+ } else
+ SetDlgItemText(hwndDlg,IDC_EFNAME,g_noeffectstr);
+ }
+ }
+ // a tree view item has been clicked
+
+ }
+ }
+ break;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_RRECT:
+ if (HIWORD(wParam)==1)
+ {
+ toggleWharfAmpDock(g_hwnd);
+ }
+ return 0;
+ case IDM_HELP_DEBUGWND:
+ if (!g_debugwnd) g_debugwnd=WASABI_API_CREATEDIALOG(IDD_DEBUG,g_hwnd,debugProc);
+ ShowWindow(g_debugwnd,SW_SHOW);
+ return 0;
+ case IDM_ABOUT:
+ // DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG2),hwndDlg,aboutProc);
+ about(hwndDlg);
+ return 0;
+ case IDM_DISPLAY:
+ case IDM_FULLSCREEN:
+ case IDM_PRESETS:
+ case IDM_BPM:
+ case IDM_TRANSITIONS:
+ {
+ int name_ids[5]={IDS_DISPLAY,IDS_FULLSCREEN_SETTINGS,IDS_PRESET_HOTKEYS,IDS_BEAT_DETECTION,IDS_TRANSITIONS};
+ int x=0;
+ if (LOWORD(wParam) == IDM_DISPLAY) x=1;
+ if (LOWORD(wParam) == IDM_FULLSCREEN) x=2;
+ if (LOWORD(wParam) == IDM_PRESETS) x=3;
+ if (LOWORD(wParam) == IDM_BPM) x=4;
+ if (LOWORD(wParam) == IDM_TRANSITIONS) x=5;
+
+ if (x >= 1 && x <= 5)
+ {
+ SetDlgItemText(hwndDlg,IDC_EFNAME,WASABI_API_LNGSTRING(name_ids[x-1]));
+ TreeView_Select(GetDlgItem(hwndDlg,IDC_TREE1),NULL,TVGN_CARET);
+ if (cur_hwnd) DestroyWindow(cur_hwnd);
+ if (x==1)
+ cur_hwnd=WASABI_API_CREATEDIALOG(IDD_GCFG_DISP,hwndDlg,DlgProc_Disp);
+ if (x==2)
+ cur_hwnd=WASABI_API_CREATEDIALOG(IDD_GCFG_FS,hwndDlg,DlgProc_FS);
+ if (x==3)
+ cur_hwnd=WASABI_API_CREATEDIALOG(IDD_GCFG_PRESET,hwndDlg,DlgProc_Preset);
+ if (x==4)
+ cur_hwnd=WASABI_API_CREATEDIALOG(IDD_GCFG_BPM,hwndDlg,DlgProc_Bpm);
+ if (x==5)
+ cur_hwnd=g_render_transition->conf(g_hInstance,hwndDlg);
+ if (cur_hwnd)
+ {
+ RECT r;
+ is_aux_wnd=1;
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_EFFECTRECT),&r);
+ ScreenToClient(hwndDlg,(LPPOINT)&r);
+ SetWindowPos(cur_hwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
+ ShowWindow(cur_hwnd,SW_SHOWNA);
+ }
+ else
+ SetDlgItemText(hwndDlg,IDC_EFNAME,g_noeffectstr);
+ }
+ }
+ return 0;
+ case IDC_ADD:
+ {
+ C_RenderListClass::T_RenderListType ren={0};
+ RECT r;
+ presetTreeMenu=CreatePopupMenu();
+
+ HMENU hAddMenu=CreatePopupMenu();
+
+ // int insert_pos=0;
+ int p=64;
+ int x=0;
+ while (1)
+ {
+ char str[1024];
+ if (!g_render_library->GetRendererDesc(x,str))
+ break;
+
+ if (str[0])
+ _insertintomenu(hAddMenu,p++,x,str);
+
+ x++;
+ }
+ x=DLLRENDERBASE;
+ while (1)
+ {
+ char str[1024];
+ int id=g_render_library->GetRendererDesc(x++, str);
+ if (!id) break;
+ if (str[0]) _insertintomenu(hAddMenu,p++,id,str);
+ }
+ _insertintomenu(hAddMenu,p++,LIST_ID,WASABI_API_LNGSTRING(IDS_EFFECT_LIST));
+
+ int preset_base=presetTreeCount=p;
+ // add presets
+ {
+ MENUITEMINFO i={sizeof(i),};
+ i.hSubMenu=presetTreeMenu;
+ i.fMask=MIIM_SUBMENU|MIIM_TYPE|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.dwTypeData = WASABI_API_LNGSTRING(IDS_PRESETS);
+ i.cch = strlen((char*)i.dwTypeData);
+ InsertMenuItem(hAddMenu,0,TRUE,&i);
+ i.hSubMenu=0;
+ i.fMask=MIIM_TYPE|MIIM_ID;
+ i.fType=MFT_SEPARATOR;
+ InsertMenuItem(hAddMenu,1,TRUE,&i);
+
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[1024];
+ wsprintf(dirmask,"%s\\*.*",g_path);
+
+ int directory_pos=0,insert_pos=0;
+
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && d.cFileName[0] != '.')
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,MFS_DEFAULT};
+ mi.hSubMenu=CreatePopupMenu();
+ mi.dwTypeData=d.cFileName;
+ mi.cch = strlen(d.cFileName);
+ InsertMenuItem(presetTreeMenu,directory_pos++,TRUE,&mi);
+ insert_pos++;
+ }
+ else if (!stricmp(extension(d.cFileName),"avs"))
+ {
+ extension(d.cFileName)[-1]=0;
+ MENUITEMINFO i={sizeof(i),MIIM_DATA|MIIM_TYPE|MIIM_ID,MFT_STRING,MFS_DEFAULT };
+ i.dwTypeData = d.cFileName;
+ i.cch = strlen(d.cFileName);
+ i.dwItemData=0xffffffff;
+ i.wID=presetTreeCount++;
+ InsertMenuItem(presetTreeMenu,insert_pos++,TRUE,&i);
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+ }
+
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_ADD),&r);
+ int t=TrackPopupMenu(hAddMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON,r.right,r.top,0,hwndDlg,NULL);
+ if (t)
+ {
+ char buf[2048];
+ buf[0]=0;
+ if (t >= preset_base)
+ {
+ if (findInMenu(presetTreeMenu,0,t,buf,2048))
+ {
+ //preset
+ C_RenderListClass *r;
+ char temp[4096];
+ ren.effect_index=LIST_ID;
+ wsprintf(temp,"%s%s.avs",g_path,buf);
+ r=new C_RenderListClass();
+ if (!r->__LoadPreset(temp,1))
+ {
+ ren.render=(C_RBASE*)r;
+ }
+ else
+ {
+ delete r;
+ ren.render=NULL;
+ }
+ }
+ }
+ else
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_DATA,};
+ GetMenuItemInfo(hAddMenu,t,FALSE,&mi);
+ if (mi.dwItemData != 0xffffffff) // effect
+ {
+ ren.effect_index=mi.dwItemData;
+ ren.render=g_render_library->CreateRenderer(&ren.effect_index,&ren.has_rbase2);
+ }
+ }
+
+ if (ren.render)
+ {
+ int insert_pos=0;
+ HTREEITEM hTreeItem = TreeView_GetSelection(GetDlgItem(hwndDlg,IDC_TREE1));
+ C_RenderListClass *parentrender=g_render_effects;
+ HTREEITEM parenthandle=g_hroot;
+ if (hTreeItem)
+ {
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,hTreeItem,0,0,0,0,0};
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&i);
+ C_RenderListClass::T_RenderListType *tp=(C_RenderListClass::T_RenderListType *)i.lParam;
+ if (tp->effect_index == LIST_ID)
+ {
+ parentrender=(C_RenderListClass *)tp->render;
+ parenthandle=hTreeItem;
+ }
+ else
+ {
+ HTREEITEM hParent=TreeView_GetParent(GetDlgItem(hwndDlg,IDC_TREE1),hTreeItem);
+ if (hParent && hParent != TVI_ROOT)
+ {
+ TV_ITEM i2={TVIF_HANDLE|TVIF_PARAM,hParent,0,0,0,0,0};
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&i2);
+ C_RenderListClass::T_RenderListType *tparent=(C_RenderListClass::T_RenderListType *)i2.lParam;
+ parentrender=(C_RenderListClass *)tparent->render;
+ parenthandle=hParent;
+ }
+ for (insert_pos=0; insert_pos<parentrender->getNumRenders()
+ && parentrender->getRender(insert_pos)->render != tp->render; insert_pos++);
+ }
+ }
+
+ EnterCriticalSection(&g_render_cs);
+ parentrender->insertRender(&ren,insert_pos);
+ LeaveCriticalSection(&g_render_cs);
+ C_RenderListClass::T_RenderListType *newt=(C_RenderListClass::T_RenderListType *)GlobalAlloc(GMEM_FIXED,sizeof(C_RenderListClass::T_RenderListType));
+ *newt=ren;
+ TV_INSERTSTRUCT is={parenthandle,0,{TVIF_PARAM|TVIF_TEXT|TVIF_CHILDREN,0,0,0,ren.render->get_desc(),0,0,0,newt->effect_index==LIST_ID?1:0,(int)newt}};
+ if (!hTreeItem || parenthandle==hTreeItem)
+ {
+ is.hInsertAfter=TVI_FIRST;
+ }
+ else
+ {
+ is.hInsertAfter=TreeView_GetPrevSibling(GetDlgItem(hwndDlg,IDC_TREE1),hTreeItem);
+ if (!is.hInsertAfter) is.hInsertAfter=TVI_FIRST;
+ }
+ HTREEITEM newh=TreeView_InsertItem(GetDlgItem(hwndDlg,IDC_TREE1),&is);
+ TreeView_Select(GetDlgItem(hwndDlg,IDC_TREE1),newh,TVGN_CARET);
+ if (ren.effect_index == LIST_ID)
+ _do_add(GetDlgItem(hwndDlg,IDC_TREE1),newh,(C_RenderListClass *)ren.render);
+
+ // Always do undo last.
+ KillTimer(hwndDlg,69);
+ SetTimer(hwndDlg,69,UNDO_TIMER_INTERVAL,NULL);
+ // g_preset_dirty=1;
+ }
+ }
+ DestroyMenu(hAddMenu);
+ presetTreeMenu=0;
+ } // end of IDC_ADD
+ return 0;
+ case IDC_CLEAR:
+ if (readyToLoadPreset(hwndDlg,1))
+ {
+ if (g_render_transition->LoadPreset("",0) != 2)
+ last_preset[0]=0;
+ }
+ return 0;
+ case IDC_REMSEL:
+ {
+ HTREEITEM hTreeItem = TreeView_GetSelection(GetDlgItem(hwndDlg,IDC_TREE1));
+ if (hTreeItem == g_hroot)
+ {
+ CfgWnd_Unpopulate();
+ EnterCriticalSection(&g_render_cs);
+ g_render_effects->clearRenders();
+ LeaveCriticalSection(&g_render_cs);
+ CfgWnd_Populate();
+ }
+ else if (hTreeItem)
+ {
+ C_RenderListClass *parentrender;
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,hTreeItem,0,0,0,0,0};
+ if (TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&i))
+ {
+ C_RenderListClass::T_RenderListType *tp=(C_RenderListClass::T_RenderListType *)i.lParam;
+ HTREEITEM hParent=TreeView_GetParent(GetDlgItem(hwndDlg,IDC_TREE1),hTreeItem);
+ if (hParent != NULL)
+ {
+ TV_ITEM i2={TVIF_HANDLE|TVIF_PARAM,hParent,0,0,0,0,0};
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&i2);
+ C_RenderListClass::T_RenderListType *tparent=(C_RenderListClass::T_RenderListType *)i2.lParam;
+ parentrender=(C_RenderListClass*)tparent->render;
+ EnterCriticalSection(&g_render_cs);
+ if (!parentrender->removeRenderFrom(tp,1))
+ {
+ TreeView_DeleteItem(GetDlgItem(hwndDlg,IDC_TREE1),hTreeItem);
+ if (tp)
+ GlobalFree((HGLOBAL)tp);
+ }
+ LeaveCriticalSection(&g_render_cs);
+ }
+ }
+ }
+ // Always save undo last.
+ KillTimer(hwndDlg,69);
+ SetTimer(hwndDlg,69,UNDO_TIMER_INTERVAL,NULL);
+ // g_preset_dirty=1;
+ }
+ return 0;
+ case IDC_CLONESEL:
+ {
+ C_RenderListClass::T_RenderListType ren={0,};
+ int insert_pos=-1;
+
+ HTREEITEM hTreeItem = TreeView_GetSelection(GetDlgItem(hwndDlg,IDC_TREE1));
+ if (hTreeItem && hTreeItem != g_hroot)
+ {
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,hTreeItem,0,0,0,0,0};
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&i);
+ C_RenderListClass::T_RenderListType *tp=(C_RenderListClass::T_RenderListType *)i.lParam;
+ ren.effect_index=tp->effect_index;
+ ren.render=g_render_library->CreateRenderer(&ren.effect_index,&ren.has_rbase2);
+ if (ren.render)
+ {
+ HTREEITEM hParent=TreeView_GetParent(GetDlgItem(hwndDlg,IDC_TREE1),hTreeItem);
+ if (hParent && hParent != TVI_ROOT)
+ {
+ TV_ITEM i2={TVIF_HANDLE|TVIF_PARAM,hParent,0,0,0,0,0};
+ TreeView_GetItem(GetDlgItem(hwndDlg,IDC_TREE1),&i2);
+ C_RenderListClass::T_RenderListType *tparent=(C_RenderListClass::T_RenderListType *)i2.lParam;
+ C_RenderListClass *parentrender=(C_RenderListClass *)tparent->render;
+ for (insert_pos=0; insert_pos<parentrender->getNumRenders()
+ && parentrender->getRender(insert_pos)->render != tp->render; insert_pos++);
+ insert_pos++;
+ unsigned char *buf = (unsigned char *) GlobalAlloc(GPTR,1024*1024);
+ if (buf)
+ {
+ int len=tp->render->save_config(buf);
+ ren.render->load_config(buf,len);
+ GlobalFree((HGLOBAL)buf);
+ }
+ EnterCriticalSection(&g_render_cs);
+ parentrender->insertRender(&ren,insert_pos);
+ LeaveCriticalSection(&g_render_cs);
+
+ C_RenderListClass::T_RenderListType *newt=(C_RenderListClass::T_RenderListType *)GlobalAlloc(GMEM_FIXED,sizeof(C_RenderListClass::T_RenderListType));
+ *newt=ren;
+ TV_INSERTSTRUCT is={hParent,0,{TVIF_PARAM|TVIF_TEXT|TVIF_CHILDREN,0,0,0,ren.render->get_desc(),0,0,0,newt->effect_index==LIST_ID?1:0,(int)newt}};
+ is.hInsertAfter=hTreeItem;
+ HTREEITEM newh=TreeView_InsertItem(GetDlgItem(hwndDlg,IDC_TREE1),&is);
+ TreeView_Select(GetDlgItem(hwndDlg,IDC_TREE1),newh,TVGN_CARET);
+ if (ren.effect_index == LIST_ID)
+ _do_add(GetDlgItem(hwndDlg,IDC_TREE1),newh,(C_RenderListClass *)ren.render);
+ }
+ }
+ // Always save undo last.
+ KillTimer(hwndDlg,69);
+ SetTimer(hwndDlg,69,UNDO_TIMER_INTERVAL,NULL);
+ // g_preset_dirty=1;
+ }
+ }
+ return 0;
+ case IDC_LOAD:
+ {
+ char temp[2048];
+ OPENFILENAME l={sizeof(l),0};
+ char buf1[2048],buf2[2048];
+ char filter[128], *ptr = filter;
+ char loadPreset[64];
+
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_FILTER_STRING,filter,128);
+ while(*ptr)
+ {
+ if (*ptr=='|') *ptr=0;
+ ptr++;
+ }
+
+ GetCurrentDirectory(sizeof(buf2),buf2);
+ strcpy(buf1,g_path); // this was changed from: lstrcpyn(buf1,g_path,sizeof(buf1));
+ temp[0]=0;
+ l.lpstrInitialDir = buf1;
+ l.hwndOwner = hwndDlg;
+ l.lpstrFilter = filter;
+ l.lpstrFile = temp;
+ l.nMaxFile = 2048-1;
+ l.lpstrTitle = WASABI_API_LNGSTRING_BUF(IDS_LOAD_PRESET,loadPreset,48);
+ l.lpstrDefExt = "AVS";
+ l.Flags = OFN_HIDEREADONLY|OFN_EXPLORER;
+ if (readyToLoadPreset(hwndDlg,0) && GetOpenFileName(&l))
+ {
+ int x=g_render_transition->LoadPreset(temp,0);
+ if (x == 2)
+ MessageBox(hwndDlg,WASABI_API_LNGSTRING(IDS_STILL_INITIALIZING_PREVIOUS_PRESET),loadPreset,MB_OK);
+ else
+ lstrcpyn(last_preset,temp,sizeof(last_preset));
+ }
+ SetCurrentDirectory(buf2);
+ }
+ return 0;
+ case IDC_SAVE:
+ dosavePreset(hwndDlg);
+ return 0;
+ case IDM_UNDO:
+ C_UndoStack::undo();
+ return 0;
+ case IDM_REDO:
+ C_UndoStack::redo();
+ return 0;
+ } // end of switch(LOWORD(Param))
+ return 0;
+ }// end of switch(uMsg)
+ return 0;
+}
+
+static void _do_add(HWND hwnd, HTREEITEM h, C_RenderListClass *list)
+{
+ int x,l;
+ l=list->getNumRenders();
+ for (x = 0; x < l; x ++)
+ {
+ C_RenderListClass::T_RenderListType *t=list->getRender(x);
+ if (t)
+ {
+ C_RenderListClass::T_RenderListType *newt=(C_RenderListClass::T_RenderListType *)GlobalAlloc(GMEM_FIXED,sizeof(C_RenderListClass::T_RenderListType));
+ memcpy(newt,t,sizeof(C_RenderListClass::T_RenderListType));
+ TV_INSERTSTRUCT is;
+ memset(&is,0,sizeof(is));
+
+ is.hParent=h;
+ is.hInsertAfter=TVI_LAST;
+ is.item.mask=TVIF_PARAM|TVIF_TEXT|TVIF_CHILDREN;
+ is.item.pszText=t->render->get_desc();
+ is.item.cChildren=t->effect_index==LIST_ID?1:0;
+ is.item.lParam=(int)newt;
+
+ HTREEITEM h2=TreeView_InsertItem(hwnd,&is);
+ if (t->effect_index==LIST_ID)
+ {
+ _do_add(hwnd,h2,(C_RenderListClass *)t->render);
+ }
+ }
+ }
+ SendMessage(hwnd,TVM_EXPAND,TVE_EXPAND,(long)h);
+}
+
+static void _do_free(HWND hwnd, HTREEITEM h)
+{
+ while (h)
+ {
+ TV_ITEM i={TVIF_HANDLE|TVIF_PARAM,h,0,0,0,0,0};
+ TreeView_GetItem(hwnd,&i);
+ if (i.lParam) GlobalFree((HGLOBAL)(void*)i.lParam);
+ HTREEITEM h2=TreeView_GetChild(hwnd,h);
+ if (h2) _do_free(hwnd,h2);
+ h=TreeView_GetNextSibling(hwnd,h);
+ }
+}
+
+int need_repop;
+
+void CfgWnd_RePopIfNeeded(void)
+{
+ if (need_repop)
+ {
+ CfgWnd_Unpopulate(1);
+ CfgWnd_Populate(1);
+ need_repop=0;
+ }
+}
+
+void CfgWnd_Unpopulate(int force)
+{
+ if (force || (IsWindowVisible(g_hwndDlg)&&!DDraw_IsFullScreen()))
+ {
+ HWND hwnd=GetDlgItem(g_hwndDlg,IDC_TREE1);
+ if (!is_aux_wnd)
+ {
+ if (cur_hwnd) DestroyWindow(cur_hwnd);
+ cur_hwnd=0;
+ SetDlgItemText(g_hwndDlg,IDC_EFNAME,g_noeffectstr);
+ }
+ treeview_hack=1;
+ _do_free(hwnd,TreeView_GetChild(hwnd,TVI_ROOT));
+ TreeView_DeleteAllItems(hwnd);
+ treeview_hack=0;
+ }
+ else need_repop=1;
+}
+
+void CfgWnd_Populate(int force)
+{
+ if (force || (IsWindowVisible(g_hwndDlg)&&!DDraw_IsFullScreen()))
+ {
+ treeview_hack=1;
+ HWND hwnd=GetDlgItem(g_hwndDlg,IDC_TREE1);
+ C_RenderListClass::T_RenderListType *newt=(C_RenderListClass::T_RenderListType *)GlobalAlloc(GMEM_FIXED,sizeof(C_RenderListClass::T_RenderListType));
+ newt->render=g_render_effects;
+ newt->effect_index=LIST_ID;
+ TV_INSERTSTRUCT is;
+ memset(&is,0,sizeof(is));
+ is.hParent=TVI_ROOT;
+ is.hInsertAfter=TVI_LAST;
+ is.item.mask=TVIF_PARAM|TVIF_TEXT|TVIF_CHILDREN;
+ is.item.pszText=WASABI_API_LNGSTRING(IDS_MAIN);
+ is.item.cChildren=1;
+ is.item.lParam=(int)newt;
+ g_hroot=TreeView_InsertItem(hwnd,&is);
+ if (g_hroot)
+ {
+ _do_add(hwnd,g_hroot,g_render_effects);
+ SendMessage(hwnd,TVM_EXPAND,TVE_EXPAND,(long)g_hroot);
+ }
+ treeview_hack=0;
+ }
+ else need_repop=1;
+}
diff --git a/Src/Plugins/Visualization/vis_avs/cfgwnd.h b/Src/Plugins/Visualization/vis_avs/cfgwnd.h
new file mode 100644
index 00000000..fe6a0b9b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/cfgwnd.h
@@ -0,0 +1,47 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+void CfgWnd_Create(struct winampVisModule *this_mod);
+void CfgWnd_Destroy(void);
+
+void CfgWnd_Populate(int force=0);
+void CfgWnd_Unpopulate(int force=0);
+void CfgWnd_RePopIfNeeded(void);
+
+extern int cfg_fs_w,cfg_fs_h,cfg_fs_d,cfg_fs_bpp,cfg_fs_fps,cfg_fs_rnd,cfg_fs_flip,cfg_fs_height,cfg_speed,cfg_fs_rnd_time;
+extern int cfg_cfgwnd_x,cfg_cfgwnd_y,cfg_cfgwnd_open;
+extern int cfg_trans,cfg_trans_amount;
+extern int cfg_dont_min_avs;
+extern int cfg_smartbeat, cfg_smartbeatsticky, cfg_smartbeatresetnewsong, cfg_smartbeatonlysticky;
+extern int cfg_transitions, cfg_transitions2, cfg_transitions_speed, cfg_transition_mode;
+extern int cfg_bkgnd_render,cfg_bkgnd_render_color;
+extern int cfg_render_prio;
+
+extern char config_pres_subdir[MAX_PATH];
+extern HWND g_hwndDlg;
diff --git a/Src/Plugins/Visualization/vis_avs/color_mo.bin b/Src/Plugins/Visualization/vis_avs/color_mo.bin
new file mode 100644
index 00000000..da03dc87
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/color_mo.bin
@@ -0,0 +1,11 @@
+The color modifier allows you to modify the intensity of each color
+channel with respect to itself. For example, you could reverse the red
+channel, double the green channel, or half the blue channel.
+
+The code in the 'level' section should adjust the variables
+'red', 'green', and 'blue', whose value represent the channel
+intensity (0..1).
+Code in the 'frame' or 'level' sections can also use the variable
+'beat' to detect if it is currently a beat.
+
+Try loading an example via the 'Load Example' button for examples. \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/draw.cpp b/Src/Plugins/Visualization/vis_avs/draw.cpp
new file mode 100644
index 00000000..5eddc451
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/draw.cpp
@@ -0,0 +1,1476 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <ddraw.h>
+#include "draw.h"
+#include <stdio.h>
+#include <process.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "vis.h"
+#include "../Agave/Language/api_language.h"
+
+extern HINSTANCE g_hInstance;
+
+#define RESIZE_ONRESIZE
+int draw_title_p=0;
+int cfg_cancelfs_on_deactivate=1;
+extern int g_dlg_fps,g_dlg_w,g_dlg_h;
+extern int cfg_fs_fps,cfg_fs_flip,cfg_fs_height,cfg_fs_use_overlay;
+extern int cfg_bkgnd_render, cfg_bkgnd_render_color;
+static LPDIRECTDRAW g_lpDD;
+static LPDIRECTDRAWSURFACE g_lpRenderSurf[2], g_lpPrimSurf, g_lpPrimSurfBack;
+static int g_bpp, g_fs, g_noshoww;
+int g_w, g_h, g_dsw, g_dsh;
+extern HWND g_hwnd;
+static CRITICAL_SECTION g_cs;
+static int g_windowed_dsize;
+static int g_initted, g_fs_flip, g_fs_height, g_fs_w, g_fs_h;
+static int nodraw=0;
+extern int inWharf;
+#ifdef RESIZE_ONRESIZE
+static int last_used;
+#endif
+static LPDIRECTDRAWSURFACE g_lpddsOverlay = NULL;
+static LPDIRECTDRAWSURFACE g_lpddsPrimary = NULL;
+static int g_overlay_init_ok=0;
+typedef enum {
+ UYVY,
+ YUY2
+} fourcc_enum;
+static fourcc_enum g_overlay_fourcc=UYVY;
+static int g_saved_desktop_values=0;
+
+static char g_saved_desktop_wallpaper[256];
+static char g_saved_reg_bkgnd_color[64];
+static DWORD g_saved_bkgnd_color;
+
+extern void Wnd_GoWindowed(HWND hwnd);
+
+#define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))
+DDPIXELFORMAT g_ddpfOverlayFormats[] =
+{ {sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}, // UYVY
+ {sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0}}; // YUY2
+
+#define NUM_OVERLAY_FORMATS (sizeof(g_ddpfOverlayFormats) / sizeof(g_ddpfOverlayFormats[0]))
+
+static HWND hwndOverlayWnd;
+
+static LRESULT CALLBACK FSOverlayWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static unsigned int start_t;
+
+ if (
+
+ (((message == WM_KEYDOWN && (wParam == VK_ESCAPE || wParam == VK_RETURN)) ||
+ message == WM_LBUTTONUP) && GetTickCount()-start_t > 1000)
+
+ ||
+
+ (cfg_cancelfs_on_deactivate && ((message == WM_NCACTIVATE && !wParam) ||
+ message == WM_KILLFOCUS))
+ )
+ {
+ DestroyWindow(hwnd);
+ Wnd_GoWindowed(g_hwnd);
+ return 0;
+ }
+ switch(message)
+ {
+ case WM_CREATE:
+ start_t=GetTickCount();
+ return 0;
+ case WM_SETCURSOR:
+ SetCursor(NULL);
+ return TRUE;
+ case WM_DESTROY:
+ hwndOverlayWnd=0;
+ return 0;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdc=BeginPaint(hwnd,&ps);
+ RECT r;
+ GetClientRect(hwnd,&r);
+ int rv=0xff&(cfg_bkgnd_render_color>>16), gv=0xff&(cfg_bkgnd_render_color>>8), bv=0xff&cfg_bkgnd_render_color;
+ HBRUSH b=CreateSolidBrush(RGB(rv,gv,bv));
+ SelectObject(ps.hdc, b);
+ Rectangle(ps.hdc, r.left, r.top, r.right, r.bottom);
+ DeleteObject(b);
+ EndPaint(hwnd,&ps);
+ }
+ return 0;
+ case WM_KEYDOWN:
+ return SendMessage(g_hwnd, message, wParam, lParam);
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+static void DD_CreateFullscreenOverlayWindow()
+{
+ static int inited=0;
+ if(!inited)
+ {
+ WNDCLASSW wc={0,};
+ wc.style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW;
+ wc.lpfnWndProc = FSOverlayWndProc;
+ wc.hInstance = g_hInstance;
+ wc.hbrBackground = NULL;
+ wc.lpszClassName = L"avsfsoverlaywnd";
+ wc.hCursor=NULL;
+ if(!RegisterClassW(&wc)) return;
+ inited=1;
+ }
+ hwndOverlayWnd=CreateWindowExW(WS_EX_TOPMOST|WS_EX_TOOLWINDOW,L"avsfsoverlaywnd",L"",WS_VISIBLE|WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,g_hInstance,0);
+}
+
+static void DD_RestoreBkgndSettings()
+{
+ if (g_saved_desktop_values)
+ {
+ int e=COLOR_DESKTOP;
+ unsigned long c=g_saved_bkgnd_color;
+ SetSysColors(1, &e, &c); // FUCKING MESSAGE PUMP AND SETSYSCOLORS
+ SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, g_saved_desktop_wallpaper, NULL);
+ g_saved_desktop_values=0;
+ }
+}
+
+void DD_CreateSurfaces(int w, int h, int fsh, int fs, int fsbpp, int flip, int dbl, int fsovl) // fsh is the height to use (not screen res)
+{
+ int resize_h=8, resize_w=8;
+#ifdef RESIZE_ONRESIZE
+ int fb_save[64*65+1];
+ int fb_save_use=0;
+#endif
+ EnterCriticalSection(&g_cs);
+ nodraw=0;
+ if (g_lpDD)
+ {
+ extern int config_reuseonresize;
+#ifdef RESIZE_ONRESIZE
+ HRESULT han;
+ int ll=!!last_used;
+ DDSURFACEDESC d={sizeof(d),};
+ if (config_reuseonresize && g_w && g_h && g_lpRenderSurf[ll] &&
+ (han = g_lpRenderSurf[ll]->Lock(NULL,&d,DDLOCK_WAIT,NULL)) == DD_OK)
+ {
+ if (d.lpSurface)
+ {
+ int x,y;
+ int dxpos=(g_w<<16)/64;
+ int ypos=0;
+ int dypos=(g_h<<16)/64;
+ int *pp=((int *)d.lpSurface);
+
+ if (g_fs && g_fs_height < g_h) // adjust to use partial screen when
+ {
+ int fsy=g_h/2-g_fs_height/2;
+ dypos=(g_fs_height<<16)/64;
+ pp+=fsy * g_w;
+ }
+
+ for (y = 0; y < 64; y++)
+ {
+ int *p=pp + g_w * (ypos>>16);
+ int xpos=0;
+ for (x = 0; x < 64; x ++)
+ {
+ fb_save[(y<<6)+x]=p[xpos>>16];
+ xpos+=dxpos;
+ }
+ ypos+=dypos;
+ }
+ memset(fb_save+64*64,0,sizeof(int)*65);
+ fb_save_use=1;
+ }
+ g_lpRenderSurf[ll]->Unlock(d.lpSurface);
+ }
+#endif
+
+ if (g_lpPrimSurf)
+ {
+ g_lpPrimSurf->Release();
+ g_lpPrimSurfBack=g_lpPrimSurf=NULL;
+ }
+ if (g_lpRenderSurf[0]) g_lpRenderSurf[0]->Release();
+ if (g_lpRenderSurf[1]) g_lpRenderSurf[1]->Release();
+ g_lpRenderSurf[0]=0;
+ g_lpRenderSurf[1]=0;
+ if (g_lpddsOverlay) g_lpddsOverlay->Release();
+ if (g_lpddsPrimary) g_lpddsPrimary->Release();
+ g_lpddsOverlay=g_lpddsPrimary=NULL;
+ g_lpDD->Release();
+ g_lpDD=NULL;
+ }
+
+ if (DirectDrawCreate(NULL,&g_lpDD,NULL) != DD_OK)
+ {
+ g_lpDD=NULL;
+ MessageBox(g_hwnd,WASABI_API_LNGSTRING(IDS_ERROR_CREATING_DDRAW_OBJECT),"DDraw",0);
+ LeaveCriticalSection(&g_cs);
+ return;
+ }
+ if (fs && !fsovl)
+ {
+ g_fs_w=w;
+ g_fs_h=h;
+ g_fs_height=fsh>>dbl;
+ g_fs_flip=flip;
+ resize_w=w>>dbl;
+ resize_h=h>>dbl;
+ if (g_lpDD->SetCooperativeLevel(g_hwnd,DDSCL_NOWINDOWCHANGES|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
+ {
+ fs=0;
+ }
+ else
+ {
+ if (g_lpDD->SetDisplayMode(w,h,fsbpp) != DD_OK)
+ {
+ fs=0;
+ }
+ else
+ {
+ DDSURFACEDESC DDsd={sizeof(DDsd),};
+ DDsd.dwFlags = DDSD_CAPS;
+ DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ if (g_fs_flip&1)
+ {
+ DDsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX|DDSCAPS_FLIP;
+ DDsd.dwFlags|=DDSD_BACKBUFFERCOUNT;
+ DDsd.dwBackBufferCount = 1;
+ }
+ if (g_lpDD->CreateSurface(&DDsd, &g_lpPrimSurf, NULL) != DD_OK)
+ {
+ fs=0;
+ }
+ else
+ {
+ DDBLTFX ddbfx={sizeof(ddbfx),};
+ g_lpPrimSurf->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ if (g_fs_flip&1)
+ {
+ DDSCAPS ddscaps;
+ ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
+ if (g_lpPrimSurf->GetAttachedSurface(&ddscaps, &g_lpPrimSurfBack) != DD_OK)
+ {
+ g_lpPrimSurf->Release();
+ fs=0;
+ }
+ else g_lpPrimSurfBack->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ }
+ else
+ g_lpPrimSurfBack=g_lpPrimSurf;
+ }
+ }
+ }
+ SetForegroundWindow(g_hwnd);
+ } else {
+ g_lpDD->SetCooperativeLevel(g_hwnd,DDSCL_NOWINDOWCHANGES|DDSCL_NORMAL);
+ resize_w=(((w>>dbl)+3)&~3);
+ g_noshoww=resize_w-(w>>dbl);
+ resize_h=h>>dbl;
+ }
+ g_fs=fs;
+
+ int wh;
+ for (wh = 0; wh < 2; wh ++)
+ {
+ DDSURFACEDESC DDsd={sizeof(DDsd),};
+ DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT;
+ DDsd.dwWidth=resize_w;
+ DDsd.dwHeight=resize_h;
+ DDsd.lPitch=resize_w*sizeof(int);
+ DDsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
+ DDsd.ddpfPixelFormat.dwSize = sizeof(DDsd.ddpfPixelFormat);
+ DDsd.ddpfPixelFormat.dwFlags=DDPF_RGB;
+ DDsd.ddpfPixelFormat.dwRGBBitCount = 32;
+ DDsd.ddpfPixelFormat.dwRBitMask=0xff0000;
+ DDsd.ddpfPixelFormat.dwGBitMask=0x00ff00;
+ DDsd.ddpfPixelFormat.dwBBitMask=0x0000ff;
+ if (g_lpDD->CreateSurface(&DDsd, &g_lpRenderSurf[wh], NULL) != DD_OK)
+ {
+ if (wh)
+ {
+ g_lpRenderSurf[0]->Release();
+ g_lpRenderSurf[0]=0;
+ }
+ g_lpRenderSurf[wh]=0;
+ LeaveCriticalSection(&g_cs);
+ return;
+ }
+
+#ifdef RESIZE_ONRESIZE
+ DDSURFACEDESC d={sizeof(d),};
+ HRESULT han;
+ if (fb_save_use && g_lpRenderSurf[wh] &&
+ (han = g_lpRenderSurf[wh]->Lock(NULL,&d,DDLOCK_WAIT,NULL)) == DD_OK)
+ {
+ if (d.lpSurface)
+ {
+ int x,y;
+ int dxpos=(64<<16)/resize_w;
+ int ypos=0;
+ int *p=(int *)d.lpSurface;
+ int h=resize_h;
+
+ if (fs && (fsh>>dbl) < resize_h)
+ {
+ int fsy=resize_h/2-(((fsh>>dbl)/2));
+ p+=fsy * resize_w;
+ h -= fsy*2;
+ }
+ int dypos=(64<<16)/h;
+
+ for (y = 0; y < h; y ++)
+ {
+ int xpos=0;
+ for (x = 0; x < resize_w; x ++)
+ {
+ *p++ = BLEND4_16((unsigned int *)fb_save + ((ypos>>10)&~63) + (xpos>>16),64,xpos,ypos);
+ xpos+=dxpos;
+ }
+ ypos+=dypos;
+ }
+#ifndef NO_MMX
+ __asm emms;
+#endif
+ }
+ g_lpRenderSurf[wh]->Unlock(d.lpSurface);
+ }
+#endif
+ }
+ g_w=resize_w;
+ g_h=resize_h;
+ g_dsh=g_h<<dbl;
+ g_dsw=g_w<<dbl;
+ g_bpp=fs?fsbpp:32;
+ g_windowed_dsize=dbl;
+
+ g_overlay_init_ok=0;
+ if(!(cfg_bkgnd_render&1)) DD_RestoreBkgndSettings();
+ if((cfg_bkgnd_render&1) || (g_fs && fsovl)) {
+ // init overlay stuff
+ DDSURFACEDESC ddsdOverlay;
+ HRESULT ddrval;
+ int i;
+
+ // It's currently not possible to query for pixel formats supported by the
+ // overlay hardware (though GetFourCCCodes() usually provides a partial
+ // list). Instead you need to call CreateSurface() to try a variety of
+ // formats till one works.
+ INIT_DIRECTDRAW_STRUCT(ddsdOverlay);
+ ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
+ ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
+ ddsdOverlay.dwWidth=resize_w;
+ ddsdOverlay.dwHeight=resize_h;
+ ddsdOverlay.lPitch=resize_w*sizeof(int);
+ ddsdOverlay.dwBackBufferCount=0;
+
+ // Try to create an overlay surface using one of the pixel formats in our
+ // global list.
+ i=0;
+ do
+ {
+ ddsdOverlay.ddpfPixelFormat=g_ddpfOverlayFormats[i];
+ // Try to create the overlay surface
+ ddrval = g_lpDD->CreateSurface(&ddsdOverlay, &g_lpddsOverlay, NULL);
+ } while( FAILED(ddrval) && (++i < NUM_OVERLAY_FORMATS) );
+
+ if(!FAILED(ddrval))
+ {
+ g_overlay_fourcc=(fourcc_enum)i;
+
+ HRESULT ddrval;
+ DDSURFACEDESC ddsd;
+ INIT_DIRECTDRAW_STRUCT(ddsd);
+ ddsd.dwFlags = DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ ddrval = g_lpDD->CreateSurface(&ddsd, &g_lpddsPrimary, NULL );
+
+ RECT rs, rd;
+ DDOVERLAYFX ovfx;
+ DDCAPS capsDrv;
+ unsigned int uDestSizeAlign, uSrcSizeAlign;
+ DWORD dwUpdateFlags;
+
+ INIT_DIRECTDRAW_STRUCT(capsDrv);
+ ddrval = g_lpDD->GetCaps(&capsDrv, NULL);
+
+ uDestSizeAlign = capsDrv.dwAlignSizeDest;
+ uSrcSizeAlign = capsDrv.dwAlignSizeSrc;
+
+ dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
+
+ DEVMODE d;
+ d.dmSize=sizeof(d);
+ d.dmDriverExtra=0;
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &d);
+
+ int rv=0xff&(cfg_bkgnd_render_color>>16), gv=0xff&(cfg_bkgnd_render_color>>8), bv=0xff&cfg_bkgnd_render_color;
+
+ if(!fsovl)
+ {
+ if (cfg_bkgnd_render&2)
+ {
+ if (!g_saved_desktop_values)
+ {
+ HKEY key;
+ g_saved_desktop_wallpaper[0]=0;
+ g_saved_reg_bkgnd_color[0]=0;
+
+ // get wallpaper
+ if(RegOpenKey(HKEY_CURRENT_USER, "Control Panel\\Desktop",&key)==ERROR_SUCCESS)
+ {
+ unsigned long s=sizeof(g_saved_desktop_wallpaper),vt;
+ RegQueryValueEx(key,"Wallpaper", 0, &vt, (unsigned char *)g_saved_desktop_wallpaper, &s);
+ }
+
+ // get registry bkgnd color
+ if(RegOpenKey(HKEY_CURRENT_USER, "Control Panel\\Colors",&key)==ERROR_SUCCESS)
+ {
+ unsigned long s=sizeof(g_saved_reg_bkgnd_color),vt;
+ RegQueryValueEx(key,"Background", 0, &vt, (unsigned char *)g_saved_reg_bkgnd_color, &s);
+ }
+
+ g_saved_bkgnd_color=GetSysColor(COLOR_DESKTOP);
+ g_saved_desktop_values=1;
+ }
+ int e=COLOR_DESKTOP;
+ unsigned long c=RGB(rv,gv,bv);
+ SetSysColors(1, &e, &c);
+ SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "", NULL);
+
+ // rewrite registry settings right now so we don't fuck the user desktop if avs crashes
+ {
+ HKEY key;
+ if(RegOpenKey(HKEY_CURRENT_USER, "Control Panel\\Desktop",&key)==ERROR_SUCCESS)
+ RegSetValueEx(key,"Wallpaper", 0, REG_SZ, (unsigned char *)g_saved_desktop_wallpaper, strlen(g_saved_desktop_wallpaper)+1);
+ if(RegOpenKey(HKEY_CURRENT_USER, "Control Panel\\Colors",&key)==ERROR_SUCCESS)
+ RegSetValueEx(key,"Background", 0, REG_SZ, (unsigned char *)g_saved_reg_bkgnd_color, strlen(g_saved_reg_bkgnd_color)+1);
+ }
+ }
+ else DD_RestoreBkgndSettings();
+ }
+
+ INIT_DIRECTDRAW_STRUCT(ovfx);
+ switch(d.dmBitsPerPel)
+ {
+ case 16:
+ ovfx.dckDestColorkey.dwColorSpaceLowValue=((rv>>3) << 11) | ((gv>>2) << 5) | (bv>>3);
+ break;
+ case 15:
+ ovfx.dckDestColorkey.dwColorSpaceLowValue=((rv>>3) << 10) | ((gv>>3) << 5) | (bv>>3);
+ break;
+ case 24: case 32:
+ ovfx.dckDestColorkey.dwColorSpaceLowValue=(rv << 16) | (gv << 8) | bv;
+ break;
+ }
+ ovfx.dckDestColorkey.dwColorSpaceHighValue=ovfx.dckDestColorkey.dwColorSpaceLowValue;
+
+ rs.left=0; rs.top=0;
+ rs.right = resize_w;
+ rs.bottom = resize_h;
+ if (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC && uSrcSizeAlign)
+ rs.right -= rs.right % uSrcSizeAlign;
+ rd.left=0; rd.top=0;
+ rd.right=GetSystemMetrics(SM_CXSCREEN); rd.bottom=GetSystemMetrics(SM_CYSCREEN);
+ if (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST && uDestSizeAlign)
+ rd.right = (int)((rd.right+uDestSizeAlign-1)/uDestSizeAlign)*uDestSizeAlign;
+ // Make the call to UpdateOverlay() which actually displays the overlay on
+ // the screen.
+ ddrval = g_lpddsOverlay->UpdateOverlay(&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
+ if(!FAILED(ddrval)) g_overlay_init_ok=1;
+ }
+ }
+
+ if(g_fs && fsovl)
+ {
+ g_fs_height=fsh>>dbl;
+ DD_CreateFullscreenOverlayWindow();
+ }
+
+ LeaveCriticalSection(&g_cs);
+}
+
+#ifndef NO_MMX
+bool CopyRGBSurfaceToYUVSurfaceMMX(
+ LPDDSURFACEDESC pddsd1,
+ LPDDSURFACEDESC pddsd2,
+ fourcc_enum eOverlayFormat)
+{
+ if (pddsd1->dwWidth != pddsd2->dwWidth)
+ return false;
+ if (pddsd1->dwHeight != pddsd2->dwHeight)
+ return false;
+
+ DWORD w = pddsd1->dwWidth;
+ DWORD h = pddsd1->dwHeight;
+ LONG pitch1 = pddsd1->lPitch;
+ LONG pitch2 = pddsd2->lPitch;
+ unsigned __int32 *pPixels1 = (unsigned __int32 *)pddsd1->lpSurface;
+ unsigned __int32 *pPixels2 = (unsigned __int32 *)pddsd2->lpSurface;
+ signed __int16 cm1[4];
+ signed __int16 cm2[4];
+ signed __int16 cm3[4];
+ signed __int16 cm4[4];
+ int loops_per_scanline = w/2;
+ int extra_bytes_per_scanline_src = pitch1 - w*4;
+ int extra_bytes_per_scanline_dest = pitch2 - w*2;
+
+ if (eOverlayFormat == UYVY) // U Y V Y
+ {
+ // swap 0<->1, and 2<->3
+ cm1[1] = 77/2; cm1[0] = -38/2; cm1[3] = 77/2; cm1[2] = 110/2;
+ cm2[1] = 150/2; cm2[0] = -74/2; cm2[3] = 150/2; cm2[2] = -92/2;
+ cm3[1] = 29/2; cm3[0] = 112/2; cm3[3] = 29/2; cm3[2] = -18/2;
+ cm4[1] = 0; cm4[0] = 32768/2; cm4[3] = 0; cm4[2] = 32768/2;
+ }
+ else // Y U Y 2
+ {
+ // (laptop)
+ cm1[0] = 77/2; cm1[1] = -38/2; cm1[2] = 77/2; cm1[3] = 110/2;
+ cm2[0] = 150/2; cm2[1] = -74/2; cm2[2] = 150/2; cm2[3] = -92/2;
+ cm3[0] = 29/2; cm3[1] = 112/2; cm3[2] = 29/2; cm3[3] = -18/2;
+ cm4[0] = 0; cm4[1] = 32768/2; cm4[2] = 0; cm4[3] = 32768/2;
+ }
+
+ __asm
+ {
+ mov edx, h
+
+ mov esi, pPixels1
+ mov edi, pPixels2
+ sub edi, 4 // pre-subtract
+ movq mm4, cm4
+ movq mm5, cm1
+ movq mm6, cm2
+ movq mm7, cm3
+
+ ALIGN 8
+ yuvscanlineloop:
+
+ mov ecx, loops_per_scanline
+
+ ALIGN 8
+ yuvloop:
+
+ /*
+ // prefetch
+ test ecx, 0x000001ff
+ jnz PROCESS_PIXEL_MMX32 // every 256th pixel do some prefetches
+
+ mov ebx, 2*256 // need to prefetch 256*6 bytes
+ ALIGN 8
+ LOAD_ESI_ARRAY_MMX32:
+ mov eax, [ebx+esi]
+ mov eax, [ebx+esi+32]
+ sub ebx, 64
+ jnz LOAD_ESI_ARRAY_MMX32
+
+ ALIGN 8
+ PROCESS_PIXEL_MMX32:
+ */
+
+ // read in 2 pixels
+ movq mm0, qword ptr [esi] // -- b1 g1 r1 -- b2 g2 r2
+ movq mm1, qword ptr [esi] // -- b1 g1 r1 -- b2 g2 r2
+ movq mm2, qword ptr [esi] // -- b1 g1 r1 -- b2 g2 r2
+
+ // quick reference:
+ // punpcklbw mm7, mm7 // abcdefgh -> eeffgghh
+ // punpcklbw mm7, mm0 // abcdefgh -> 0e0f0g0h (if mm0 is zero)
+ // packuswb mm7, mm7 // 0a0b0g0r -> abgrabgr ?
+
+ // step 1: get to this state:
+ // mm0: r1 r1 r2 r2
+ // mm1: g1 g1 g2 g2
+ // mm2: b1 b1 b2 b2
+ // mm3: junk
+ // mm4: 0 32k 0 32k
+ // mm5: c1r1 c1r2 c2r1 c2r2
+ // mm6: c1g1 c1g2 c2g1 c2g2
+ // mm7: c1b1 c1b2 c2b1 c2b2
+
+ // NOTE: the shifts of 8, 16, and 24 below are
+ // correct (vs. 0-8-16) but might be in
+ // backwards order!
+
+ pslld mm0, 8
+ pslld mm1, 16
+ pslld mm2, 24
+ psrld mm0, 24 // 00 00 00 r1 00 00 00 r2
+ psrld mm1, 24 // 00 00 00 g1 00 00 00 g2
+ psrld mm2, 24 // 00 00 00 b1 00 00 00 b2
+
+ movq mm3, mm0
+ pslld mm0, 16
+ por mm0, mm3 // 00 r1 00 r1 00 r2 00 r2
+
+ movq mm3, mm1
+ pslld mm1, 16
+ por mm1, mm3 // 00 g1 00 g1 00 g2 00 g2
+
+ movq mm3, mm2
+ pslld mm2, 16
+ por mm2, mm3 // 00 b1 00 b1 00 b2 00 b2
+
+ // step 2: multiply to get to this state:
+ // mm0: r1*c1r1 r1*c1r2 r2*c2r1 r2*c2r2
+ // mm1: g1*c1g1 g1*c1g2 g2*c2g1 g2*c2g2
+ // mm2: b1*c1b1 b1*c1b2 b2*c2b1 b2*c2b2
+ // mm4: 0 32k 0 32k
+ pmullw mm0, mm5
+ add edi, 4
+ pmullw mm1, mm6
+ add esi, 8
+ pmullw mm2, mm7
+
+ // step 3: add to get to this state:
+ // mm0: d1*256 d2*256 d3*256 d4*256
+ paddsw mm0, mm4
+ paddsw mm0, mm1
+ paddsw mm0, mm2
+
+ psrlw mm0, 7
+ packuswb mm0, mm0 // bytes: abgrabgr
+ movd dword ptr [edi], mm0 // store
+
+ loop yuvloop
+
+ // scanline complete
+ add esi, extra_bytes_per_scanline_src
+ add edi, extra_bytes_per_scanline_dest
+
+ dec edx
+ jnz yuvscanlineloop
+
+ emms
+ }
+
+ return true;
+}
+#else
+bool CopyRGBSurfaceToYUVSurface(
+ LPDDSURFACEDESC pddsd1,
+ LPDDSURFACEDESC pddsd2,
+ fourcc_enum eOverlayFormat)
+{
+ if (pddsd1->dwWidth != pddsd2->dwWidth)
+ return false;
+ if (pddsd1->dwHeight != pddsd2->dwHeight)
+ return false;
+
+ DWORD w = pddsd1->dwWidth;
+ DWORD h = pddsd1->dwHeight;
+ LONG pitch1 = pddsd1->lPitch;
+ LONG pitch2 = pddsd2->lPitch;
+ unsigned __int32 *pPixels1 = (unsigned __int32 *)pddsd1->lpSurface;
+ unsigned __int32 *pPixels2 = (unsigned __int32 *)pddsd2->lpSurface;
+ unsigned __int32 color1;
+ LONG offset1 = 0;
+ LONG offset2 = 0;
+ unsigned int R, G, B, i1, i2, i3, i4;
+ BYTE yuv[4];
+
+ if (eOverlayFormat == UYVY) // U Y V Y
+ {
+ i1 = 1;
+ i2 = 0;
+ i3 = 3;
+ i4 = 2;
+ }
+ else // Y U Y 2
+ {
+ i1 = 0;
+ i2 = 1;
+ i3 = 2;
+ i4 = 3;
+ }
+
+ // Go through the image 2 pixels at a time and convert to YUV
+ for (unsigned int y=0; y<h; y++)
+ {
+ offset1 = y*pitch1/4;
+ offset2 = y*pitch2/4;
+
+ for (unsigned int x=0; x<w; x+=2)
+ {
+ color1 = pPixels1[offset1++];
+ B = (color1) & 0xFF;
+ G = (color1 >> 8) & 0xFF;
+ R = (color1 >> 16) & 0xFF;
+ yuv[i1] = (77*R + 150*G + 29*B) >> 8;
+ yuv[i2] = (32768 - 38*R - 74*G + 112*B) >> 8;
+
+ color1 = pPixels1[offset1++];
+ B = (color1) & 0xFF;
+ G = (color1 >> 8) & 0xFF;
+ R = (color1 >> 16) & 0xFF;
+ yuv[i3] = (77*R + 150*G + 29*B) >> 8;
+ yuv[i4] = (32768 + 110*R - 92*G - 18*B) >> 8;
+
+ pPixels2[offset2++] = *((unsigned __int32 *)yuv);
+ }
+ }
+ return true;
+}
+#endif
+
+int DDraw_Init()
+{
+ InitializeCriticalSection(&g_cs);
+ return 0;
+
+}
+void DDraw_Quit(void)
+{
+ if (g_lpDD)
+ {
+ if (g_lpPrimSurf)
+ {
+ g_lpPrimSurf->Release();
+ g_lpPrimSurfBack=g_lpPrimSurf=NULL;
+ }
+ if (g_lpRenderSurf[0]) g_lpRenderSurf[0]->Release();
+ if (g_lpRenderSurf[1]) g_lpRenderSurf[1]->Release();
+ g_lpRenderSurf[0]=0;
+ g_lpRenderSurf[1]=0;
+ if (g_lpddsOverlay) g_lpddsOverlay->Release();
+ if (g_lpddsPrimary) g_lpddsPrimary->Release();
+ g_lpddsOverlay=g_lpddsPrimary=NULL;
+ g_lpDD->Release();
+ g_lpDD=NULL;
+ DD_RestoreBkgndSettings();
+ }
+ DeleteCriticalSection(&g_cs);
+}
+
+
+void DDraw_BeginResize(void)
+{
+ if (!g_fs) nodraw=1;
+}
+void DDraw_Resize(int w, int h, int dsize)
+{
+ if (!g_fs) DD_CreateSurfaces(w, h, 0, 0, 0, 0, !!dsize, 0);
+}
+
+static void *g_lpsurf[2];
+
+static DDSURFACEDESC d={sizeof(d),};
+static DDSURFACEDESC d2={sizeof(d),};
+
+void DDraw_Enter(int *w, int *h, int **fb1, int **fb2)
+{
+ HRESULT han;
+ if (nodraw)
+ {
+ *fb1=*fb2=0;
+ return;
+ }
+ EnterCriticalSection(&g_cs);
+ *w=g_w;
+ *h=g_h;
+ if (!g_lpDD || !g_lpRenderSurf[0] || !g_lpRenderSurf[1])
+ {
+ *fb1=*fb2=0;
+ LeaveCriticalSection(&g_cs);
+ return;
+ }
+ if ((han = g_lpRenderSurf[0]->Lock(NULL,&d,DDLOCK_WAIT,NULL)) != DD_OK)
+ {
+ *fb1=*fb2=0;
+ LeaveCriticalSection(&g_cs);
+ return;
+ }
+ if ((han = g_lpRenderSurf[1]->Lock(NULL,&d2,DDLOCK_WAIT,NULL)) != DD_OK)
+ {
+ g_lpRenderSurf[0]->Unlock(d.lpSurface);
+ *fb1=*fb2=0;
+ LeaveCriticalSection(&g_cs);
+ return;
+ }
+ *fb1=(int*)(g_lpsurf[0]=d.lpSurface);
+ *fb2=(int*)(g_lpsurf[1]=d2.lpSurface);
+
+ if (g_fs && g_fs_height!=g_h)// && !cfg_fs_use_overlay)
+ {
+ int y=g_h/2-((g_fs_height/2));
+ *h-=y*2;
+ *fb1 += y*g_w;
+ *fb2 += y*g_w;
+ }
+}
+
+static unsigned int draw_title_time;
+static char last_title[1024];
+
+extern HWND hwnd_WinampParent;
+
+static void do_gettitle()
+{
+ if (draw_title_p < 1 && --draw_title_p < -7)
+ {
+ char this_title[2048]={0,};
+ char *p;
+ if (IsWindow(hwnd_WinampParent))
+ {
+ DWORD id;
+ if (!SendMessageTimeout( hwnd_WinampParent,WM_GETTEXT,(WPARAM)sizeof(this_title),(LPARAM)this_title,SMTO_BLOCK,50,&id) || !id) return;
+ }
+ p = this_title+strlen(this_title);
+ while (p >= this_title)
+ {
+ char buf[9];
+ memcpy(buf,p,8);
+ buf[8]=0;
+ if (!lstrcmpi(buf,"- Winamp")) break;
+ p--;
+ }
+ if (p >= this_title) p--;
+ while (p >= this_title && *p == ' ') p--;
+ *++p=0;
+ if (lstrcmpi(this_title,last_title))
+ {
+ strcpy(last_title,this_title);
+ draw_title_p=1;
+ draw_title_time=GetTickCount()+1000;
+ }
+ else draw_title_p=0;
+ }
+ if (draw_title_p == 2)
+ {
+ draw_title_p=1;
+ draw_title_time=GetTickCount()+1000;
+ }
+}
+
+
+char statustext[256];
+DWORD statustext_life;
+int statustext_len;
+
+void DDraw_SetStatusText(char *text, int life)
+{
+ strcpy(statustext,text);
+ statustext_len=life?life:2000;
+ statustext_life=1;
+
+}
+
+
+
+#ifndef NO_X86ASM
+void homemadeBlitFrom32bpp(DDSURFACEDESC *out, void *in, int w, int h, int sy, int ey)
+{
+ int mh=min(h,(int)out->dwHeight);
+ if (sy < 0) sy=0;
+ if (ey > mh) ey=mh;
+ if (out->ddpfPixelFormat.dwRGBBitCount == 15)
+ {
+ int y;
+ int mw;
+ mw=min(w,out->lPitch/2);
+ unsigned int *inptr=(unsigned int *)in + w*sy;
+ for (y = sy; y < ey; y ++)
+ {
+ unsigned char *optr = (unsigned char *)out->lpSurface + (y * out->lPitch);
+ __asm
+ {
+ mov edi, optr
+ mov esi, inptr
+ mov ecx, mw
+ mov ebx, 00000000111110001111100011111000b
+ shr ecx, 1
+ conv15_loop:
+ mov eax,[esi]
+
+ mov edx,[esi+4]
+
+ and eax, ebx
+ and edx, ebx
+
+ // 00000000RRRRR000GGGGG000BBBBB000
+ shr ah,3 // 00000000RRRRR000000GGGGGBBBBB000
+ shr dh,3
+
+ shr ax,3 // 00000000RRRRR000000000GGGGGBBBBB
+ shr dx,3
+
+ // ----------------HHHHHHHHLLLLLLLL
+ ror eax,10// GGGGGBBBBB00000000RRRRR000000000
+ ror edx,10
+
+ shr ah,1
+ shr dh,1
+
+ mov al,ah
+ mov dl,dh
+
+ rol eax,10
+
+ rol edx,10
+
+ shl edx, 16
+
+ and eax, 0x0000ffff
+ add esi,8
+
+ or eax, edx
+
+ mov [edi], eax
+
+ add edi, 4
+ dec ecx
+ jnz conv15_loop
+ }
+ inptr += w;
+ }
+
+ }
+ else if (out->ddpfPixelFormat.dwRGBBitCount == 16)
+ {
+ int y;
+ int mw;
+ mw=min(w,out->lPitch/2);
+ unsigned int *inptr=(unsigned int *)in + w*sy;
+ for (y = sy; y < ey; y ++)
+ {
+ unsigned char *optr = (unsigned char *)out->lpSurface + (y * out->lPitch);
+ __asm
+ {
+ mov edi, optr
+ mov esi, inptr
+ mov ecx, mw
+ mov ebx, 00000000111110001111110011111000b
+ shr ecx, 1
+ conv16_loop:
+ mov eax,[esi]
+
+ mov edx,[esi+4]
+
+ and eax, ebx
+ and edx, ebx
+
+ // RRRRR000GGGGGG00BBBBB000
+
+ shr ah,2 // RRRRR00000GGGGGGBBBBB000
+ shr dh,2
+
+ shr ax,3 // RRRRR00000000GGGGGGBBBBB
+ shr dx,3
+
+ ror eax,8 // GGGBBBBBRRRRR00000000GGG
+ ror edx,8
+
+ add al,ah // GGGBBBBBRRRRR000RRRRRGGG
+ add dl,dh
+
+ rol eax,8 // RRRRR000RRRRRGGGGGGBBBBB
+
+ rol edx,8
+
+ shl edx, 16
+
+ and eax, 0x0000ffff
+ add esi,8
+
+ or eax, edx
+
+ mov [edi], eax
+
+ add edi, 4
+ dec ecx
+ jnz conv16_loop
+ }
+ inptr += w;
+ }
+
+ }
+ else if (out->ddpfPixelFormat.dwRGBBitCount == 24)
+ { // very unoptimized
+ int y,x;
+ int mw;
+ unsigned int *inptr=(unsigned int *)in+sy;
+ mw=min(w,out->lPitch/3);
+ for (y = sy; y < ey; y ++)
+ {
+ unsigned char *optr = (unsigned char *)out->lpSurface + (y * out->lPitch);
+ x=mw/2;
+ while (x--)
+ {
+ int a=inptr[0];
+ int b=inptr[1];
+ optr[0]=(unsigned char) a;
+ optr[3]=(unsigned char) b;
+ optr[1]=(unsigned char) (a>>8);
+ optr[4]=(unsigned char) (b>>8);
+ optr[2]=(unsigned char) (a>>16);
+ optr[5]=(unsigned char) (b>>16);
+
+ optr+=6;
+ inptr+=2;
+ }
+ inptr += (w-mw);
+ }
+ }
+ else
+ {
+ unsigned char *outptr;
+ unsigned int *inptr;
+ int mw=min(w*4,out->lPitch);
+ int y;
+ inptr=(unsigned int*)in + (sy*w);
+ outptr=(unsigned char *)out->lpSurface + (sy*out->lPitch);
+ for (y = sy; y < ey; y ++)
+ {
+ memcpy(outptr,inptr,mw);
+ inptr+=w;
+ outptr+=out->lPitch;
+ }
+ }
+}
+#endif
+
+static int unlocksurfaces()
+{
+ int a=0;
+ if (g_lpRenderSurf[0] && g_lpRenderSurf[0]->Unlock(g_lpsurf[0]) != DD_OK) a=1;
+ if (g_lpRenderSurf[1] && g_lpRenderSurf[1]->Unlock(g_lpsurf[1]) != DD_OK) a=1;
+ return a;
+}
+
+void DDraw_Exit(int which)
+{
+ if (!g_lpRenderSurf[0] || !g_lpRenderSurf[1])
+ {
+ unlocksurfaces();
+ goto endfunc;
+ }
+#ifdef RESIZE_ONRESIZE
+ last_used=which;
+#endif
+
+ if (g_fs && !cfg_fs_use_overlay)
+ {
+ int fsy=g_h/2-((g_fs_height/2));
+ RECT r={0,0,g_w,g_h};
+ if (g_bpp != 32) // non-32bpp mode
+ {
+ if (fsy>0 && ((cfg_fs_fps&1) || (statustext_life&&!(cfg_fs_fps&8)))) // clear portions of backbuffer if necessary
+ {
+ DDBLTFX ddbfx={sizeof(ddbfx),};
+ int ty=min(fsy,16);
+ RECT r2={0,0,g_w,ty};
+ g_lpPrimSurfBack->Blt(&r2,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ r2.top=g_h-ty;
+ r2.bottom=g_h-1;
+ g_lpPrimSurfBack->Blt(&r2,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ }
+#ifndef NO_X86ASM
+ if (!(g_fs_flip&8) && !g_windowed_dsize) // homemade bltshit
+ {
+ DDSURFACEDESC d={sizeof(d),};
+ HRESULT han;
+ han = g_lpPrimSurfBack->Lock(NULL,&d,DDLOCK_WAIT,NULL);
+ if (han == DDERR_SURFACELOST)
+ {
+ DDBLTFX ddbfx={sizeof(ddbfx),};
+ g_lpPrimSurfBack->Restore();
+ g_lpPrimSurfBack->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ han = g_lpPrimSurfBack->Lock(NULL,&d,DDLOCK_WAIT,NULL);
+ }
+ if (han != DD_OK) goto slow_fs_non32bpp;
+
+ homemadeBlitFrom32bpp(&d,g_lpsurf[which],g_w,g_h,fsy,g_h-fsy);
+
+ int a=0;
+ if (g_lpPrimSurfBack->Unlock(d.lpSurface) != DD_OK ) a=1;
+ if (unlocksurfaces()||a)
+ {
+ goto endfunc;
+ }
+ }
+ else // slow (stretchblt)
+#endif
+ {
+ HDC in, out;
+#ifndef NO_X86ASM
+slow_fs_non32bpp:
+#endif
+ if (unlocksurfaces() || g_lpPrimSurfBack->GetDC(&out) != DD_OK)
+ {
+ goto endfunc;
+ }
+ if (g_lpRenderSurf[which]->GetDC(&in) != DD_OK)
+ {
+ g_lpPrimSurfBack->ReleaseDC(out);
+ goto endfunc;
+ }
+ if (g_windowed_dsize) StretchBlt(out,0,fsy*2,g_dsw,g_dsh-fsy*4,in,0,fsy,g_w,g_h-fsy*2,SRCCOPY);
+ else BitBlt(out,0,fsy,g_w,g_h-fsy*2,in,0,fsy,SRCCOPY);
+ g_lpRenderSurf[which]->ReleaseDC(in);
+ g_lpPrimSurfBack->ReleaseDC(out);
+ }
+ }
+ else // 32bpp - always just use Blt() - will scale if necessary (yay Blt!)
+ {
+ //RECT or={0,g_go_fs_h/2-g_go_fs_height/2,g_go_fs_w,g_go_fs_h/2+g_go_fs_height/2};
+ //RECT ir={0,g_h/2-g_go_fs_height/2,g_w,g_h/2+g_go_fs_height/2};
+ if (unlocksurfaces())
+ {
+ goto endfunc;
+ }
+ if (g_lpPrimSurfBack->Blt(NULL,g_lpRenderSurf[which],&r,DDBLT_WAIT,NULL) == DDERR_SURFACELOST)
+ {
+ DDBLTFX ddbfx={sizeof(ddbfx),};
+ if (g_fs_flip&1)
+ {
+ g_lpPrimSurfBack->Restore();
+ g_lpPrimSurfBack->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ }
+ g_lpPrimSurf->Restore();
+ g_lpPrimSurf->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ goto endfunc;
+ }
+ }
+ do_gettitle();
+ if ((cfg_fs_fps&1) || (draw_title_p>0&&!(cfg_fs_fps&16)) || (statustext_life&&!(cfg_fs_fps&8)))
+ {
+ HDC out;
+ if (g_lpPrimSurfBack->GetDC(&out) == DD_OK)
+ {
+ char str[2048];
+ SetBkMode(out,TRANSPARENT);
+ if (cfg_fs_fps&1)
+ {
+ RECT r={2,2,g_fs_w,g_fs_h};
+ wsprintf(str,"%d.%d",g_dlg_fps/10,g_dlg_fps%10);
+ SetTextColor(out,RGB(0,0,0));
+ DrawText(out,str,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOCLIP|DT_NOPREFIX);
+ r.left=r.top=0;
+ SetTextColor(out,RGB(255,255,255));
+ DrawText(out,str,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOCLIP|DT_NOPREFIX);
+ }
+ if (statustext_life&&!(cfg_fs_fps&8))
+ {
+ if (statustext_life==1) statustext_life=GetTickCount()+statustext_len;
+ RECT r={0,0,g_fs_w,g_fs_h};
+ if (GetTickCount() > statustext_life)
+ {
+ if (statustext_life==2) statustext_life=0;
+ else statustext_life=2;
+ }
+ else
+ {
+ SetTextColor(out,RGB(0,0,0));
+ DrawText(out,statustext,-1,&r,DT_BOTTOM|DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX);
+ SetTextColor(out,RGB(255,255,255));
+ r.right-=2;
+ r.bottom-=2;
+ DrawText(out,statustext,-1,&r,DT_BOTTOM|DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX);
+ }
+ }
+ if (draw_title_p>0&&!(cfg_fs_fps&16))
+ {
+ RECT r={4,4,g_fs_w,g_fs_h};
+ SetTextColor(out,RGB(0,0,0));
+ DrawText(out,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ r.left=r.top=0;
+ SetTextColor(out,RGB(255,255,255));
+ DrawText(out,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ }
+ g_lpPrimSurfBack->ReleaseDC(out);
+ }
+ if (draw_title_p>0 && draw_title_time < GetTickCount() && !(cfg_fs_fps&16))
+ {
+ if (g_lpRenderSurf[which]->GetDC(&out) == DD_OK)
+ {
+ RECT r={4,4,g_w,g_h};
+ SetBkMode(out,TRANSPARENT);
+ SetTextColor(out,RGB(0,0,0));
+ DrawText(out,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ r.left=r.top=0;
+ SetTextColor(out,RGB(255,255,255));
+ DrawText(out,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ g_lpRenderSurf[which]->ReleaseDC(out);
+ }
+ draw_title_p=0;
+ }
+ }
+ if (g_fs_flip&1) g_lpPrimSurf->Flip(NULL, DDFLIP_WAIT);
+ else if (!(g_fs_flip&2)) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
+ }
+ else
+ {
+ if(g_overlay_init_ok)
+ {
+ LPDDSURFACEDESC pd=(which==0?&d:&d2);
+ DDSURFACEDESC dd={sizeof(dd),};
+ if (g_fs) if (!(cfg_fs_flip&2)) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
+
+ if (g_lpddsOverlay->Lock(NULL,&dd,DDLOCK_WAIT,NULL) != DD_OK)
+ {
+ g_overlay_init_ok=0;
+ goto endfunc;
+ }
+#ifndef NO_MMX
+ CopyRGBSurfaceToYUVSurfaceMMX(pd,&dd,g_overlay_fourcc);
+#else
+ CopyRGBSurfaceToYUVSurface(pd,&dd,g_overlay_fourcc);
+#endif
+ g_lpddsOverlay->Unlock(&dd);
+ if (g_fs)
+ {
+ unlocksurfaces();
+ goto endfunc;
+ }
+ }
+
+ HDC in1, out, in2=NULL;
+ if (unlocksurfaces() || g_lpRenderSurf[which]->GetDC(&in1) != DD_OK)
+ {
+ goto endfunc;
+ }
+ do_gettitle();
+ if (draw_title_p>0&&!(cfg_fs_fps&4) && draw_title_time < GetTickCount())
+ {
+ RECT r={4,4,g_w,g_h};
+ SetBkMode(in1,TRANSPARENT);
+ SetTextColor(in1,RGB(0,0,0));
+ DrawText(in1,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ r.left=r.top=0;
+ SetTextColor(in1,RGB(255,255,255));
+ DrawText(in1,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ draw_title_p=0;
+ }
+ if ((draw_title_p > 0&&!(cfg_fs_fps&4)) || (statustext_life&&!(cfg_fs_fps&2)))
+ {
+ // draw perframe
+ RECT r={4,4,g_w,g_h};
+ if (g_lpRenderSurf[which^1]->GetDC(&in2) != DD_OK)
+ {
+ in2=NULL;
+ goto abort_thingy;
+ }
+ BitBlt(in2,0,0,g_w,g_h,in1,0,0,SRCCOPY);
+ SetBkMode(in2,TRANSPARENT);
+ if (draw_title_p > 0&&!(cfg_fs_fps&4))
+ {
+ SetTextColor(in2,RGB(0,0,0));
+ DrawText(in2,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ r.left=r.top=0;
+ SetTextColor(in2,RGB(255,255,255));
+ DrawText(in2,last_title,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_NOPREFIX);
+ }
+ if (statustext_life&&!(cfg_fs_fps&2))
+ {
+ if (statustext_life==1) statustext_life=GetTickCount()+statustext_len;
+ if (GetTickCount() > statustext_life) statustext_life=0;
+ SetTextColor(in2,RGB(0,0,0));
+ DrawText(in2,statustext,-1,&r,DT_BOTTOM|DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX);
+ r.right-=2;
+ r.bottom-=2;
+ SetTextColor(in2,RGB(255,255,255));
+ DrawText(in2,statustext,-1,&r,DT_BOTTOM|DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX);
+ }
+ }
+abort_thingy:
+ if (!(cfg_fs_flip&4)) g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
+ out=GetDC(g_hwnd);
+ if (out)
+ {
+ if (!g_windowed_dsize)
+ {
+#ifndef WA2_EMBED
+ BitBlt(out,inWharf?0:7,inWharf?0:15,g_w-g_noshoww,g_h,in2?in2:in1,0,0,SRCCOPY);
+#else
+ BitBlt(out,0,0,g_w-g_noshoww,g_h,in2?in2:in1,0,0,SRCCOPY);
+#endif
+ }
+ else
+ {
+#ifndef WA2_EMBED
+ StretchBlt(out,inWharf?0:7,inWharf?0:15,g_dsw,g_dsh,in2?in2:in1,0,0,g_w,g_h,SRCCOPY);
+#else
+ StretchBlt(out,0,0,g_dsw,g_dsh,in2?in2:in1,0,0,g_w,g_h,SRCCOPY);
+#endif
+ }
+ ReleaseDC(g_hwnd,out);
+ }
+ g_lpRenderSurf[which]->ReleaseDC(in1);
+ if (in2)
+ g_lpRenderSurf[which^1]->ReleaseDC(in2);
+ }
+endfunc:
+ LeaveCriticalSection(&g_cs);
+}
+
+
+void DDraw_SetFullScreen(int fs, int w, int h, int dbl, int bpp)
+{
+ if (!fs) DD_CreateSurfaces(w, h, 0, 0, 0, 0, !!dbl, 0);
+ else
+ {
+ DD_CreateSurfaces(w, h, (min(max(1,cfg_fs_height),100)*h)/100, 1, bpp, cfg_fs_flip, !!dbl, cfg_fs_use_overlay);
+ }
+}
+
+int DDraw_IsFullScreen(void)
+{
+ return g_fs;
+}
+
+HRESULT WINAPI _cb(
+ LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
+{
+ HWND h=(HWND)lpContext;
+ if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) &&
+ (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==32 ||
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==24 ||
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==16 ||
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==15))
+ {
+ char s[256];
+ wsprintf(s,"%dx%d@%dBPP",lpDDSurfaceDesc->dwWidth,lpDDSurfaceDesc->dwHeight,lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
+ SendMessage(h,CB_ADDSTRING,0,(long)s);
+ }
+
+ return DDENUMRET_OK;
+}
+
+
+void DDraw_EnumDispModes(HWND hwnd)
+{
+ if (g_lpDD)
+ g_lpDD->EnumDisplayModes(0,NULL,hwnd,_cb);
+}
+
+static int g_st;
+
+HRESULT WINAPI _cb2(
+ LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
+{
+ DWORD *x=(DWORD *)lpContext;
+ if (x[0]==lpDDSurfaceDesc->dwWidth &&
+ x[1]==lpDDSurfaceDesc->dwHeight &&
+ x[2]==lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount)
+ {
+ g_st=1;
+ return DDENUMRET_CANCEL;
+ }
+
+ return DDENUMRET_OK;
+}
+
+int DDraw_IsMode(int w, int h, int bpp)
+{
+ int x[3]={w,h,bpp};
+ if (!x[0] || !x[1] || !x[2]) return 0;
+ if (!g_lpDD) return 0;
+ g_st=0;
+ g_lpDD->EnumDisplayModes(0,NULL,(LPVOID)x,_cb2);
+ return g_st;
+}
+
+HRESULT WINAPI _cb3(
+ LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
+{
+ if ((lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_RGB) &&
+ (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==32 ||
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==24 ||
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==16 ||
+ lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==15))
+ {
+ int *(*x)=(int **)lpContext;
+ if (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount > (DWORD)x[2][0] ||
+ lpDDSurfaceDesc->dwWidth < (DWORD)x[0][0] ||
+ lpDDSurfaceDesc->dwHeight < (DWORD)x[1][0])
+ {
+ x[0][0]=lpDDSurfaceDesc->dwWidth;
+ x[1][0]=lpDDSurfaceDesc->dwHeight;
+ x[2][0]=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
+ }
+ }
+
+ return DDENUMRET_OK;
+}
+
+
+int DDraw_PickMode(int *w, int *h, int *bpp)
+{
+ int *(x[3])={w,h,bpp};
+ *w=0;
+ *h=0;
+ *bpp=0;
+ // return if mode found that is suitable
+ g_lpDD->EnumDisplayModes(0,NULL,(LPVOID)x,_cb3);
+ return *w && *h && *bpp;
+}
+
+double DDraw_translatePoint(POINT p, int isY)
+{
+ double v=0.0;
+ if(g_fs && g_overlay_init_ok && hwndOverlayWnd && IsWindow(hwndOverlayWnd))
+ {
+ RECT r;
+ ScreenToClient(hwndOverlayWnd,&p);
+ GetClientRect(hwndOverlayWnd,&r);
+ if (isY)
+ {
+ if (r.bottom>0)
+ v=p.y/(double)(r.bottom*0.5) - 1.0;
+ }
+ else
+ {
+ if (r.right>0)
+ v=p.x/(double)(r.right*0.5) - 1.0;
+ }
+ }
+ else
+ {
+ ScreenToClient(g_hwnd,&p);
+
+ if (isY)
+ {
+ if (g_dsh>0)
+ v=p.y/(double)(g_dsh*0.5) - 1.0;
+ }
+ else
+ {
+ if (g_dsw>0)
+ v=p.x/(double)(g_dsw*0.5) - 1.0;
+ }
+ }
+ //if (v > 1.0) v=1.0;
+ //if (v < -1.0) v=-1.0;
+ return v;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/draw.h b/Src/Plugins/Visualization/vis_avs/draw.h
new file mode 100644
index 00000000..3c42cf77
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/draw.h
@@ -0,0 +1,42 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+int DDraw_Init();
+void DDraw_Quit(void);
+void DDraw_Resize(int w, int h, int dsize);
+void DDraw_BeginResize(void);
+void DDraw_Enter(int *w, int *h, int **fb1, int **fb2);
+void DDraw_Exit(int which);
+void DDraw_SetFullScreen(int fs, int w, int h, int dbl, int bps);
+int DDraw_IsFullScreen(void);
+void DDraw_EnumDispModes(HWND);
+double DDraw_translatePoint(POINT p, int isY);
+
+void DDraw_SetStatusText(char *text, int life=0);
+int DDraw_IsMode(int w, int h, int bpp); \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/dyn_dist.bin b/Src/Plugins/Visualization/vis_avs/dyn_dist.bin
new file mode 100644
index 00000000..3bb05a44
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/dyn_dist.bin
@@ -0,0 +1,12 @@
+The dynamic distance modifier allows you to dynamically (once per frame)
+change the source pixels for each ring of pixels out from the center.
+In the 'pixel' code section, 'd' represents the distance in pixels
+the current ring is from the center, and code can modify it to
+change the distance from the center where the source pixels for
+that ring would be read. This is a terrible explanation, and if
+you want to make a better one send it to me.
+
+Examples:
+Zoom in: 'd=d*0.9'
+Zoom out: 'd=d*1.1'
+Back and forth: pixel='d=d*(1.0+0.1*cos(t));', frame='t=t+0.1' \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/dyn_move.bin b/Src/Plugins/Visualization/vis_avs/dyn_move.bin
new file mode 100644
index 00000000..f75356a7
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/dyn_move.bin
@@ -0,0 +1 @@
+Dynamic movement help goes here (send me some :) ) \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/dyn_shift.bin b/Src/Plugins/Visualization/vis_avs/dyn_shift.bin
new file mode 100644
index 00000000..30712dca
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/dyn_shift.bin
@@ -0,0 +1,7 @@
+Better Dynamic shift help goes here (send me some :)
+
+Variables:
+ x,y = amount to shift (in pixels - set these)
+ w,h = width, height (in pixels)
+ b = isBeat
+ alpha = alpha value (0.0-1.0) for blend \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/effect_l.bin b/Src/Plugins/Visualization/vis_avs/effect_l.bin
new file mode 100644
index 00000000..2541bcff
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/effect_l.bin
@@ -0,0 +1,6 @@
+Read/write 'enabled' to get/set whether the effect list is enabled for this frame
+Read/write 'beat' to get/set whether there is currently a beat
+Read/write 'clear' to get/set whether to clear the framebuffer
+If the input blend is set to adjustable, 'alphain' can be set from 0.0-1.0
+If the output blend is set to adjustable, 'alphaout' can be set from 0.0-1.0
+'w' and 'h' are set with the current width and height of the frame \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/BISON.EXE b/Src/Plugins/Visualization/vis_avs/evallib/BISON.EXE
new file mode 100644
index 00000000..1a00d0ab
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/BISON.EXE
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/CAL_TAB.C b/Src/Plugins/Visualization/vis_avs/evallib/CAL_TAB.C
new file mode 100644
index 00000000..83345693
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/CAL_TAB.C
@@ -0,0 +1,576 @@
+#include <windows.h>
+#include <stdio.h>
+#include "Compiler.h"
+#include "eval.h"
+
+#define VALUE 258
+#define IDENTIFIER 259
+#define FUNCTION1 260
+#define FUNCTION2 261
+#define FUNCTION3 262
+#define UMINUS 263
+#define UPLUS 264
+#define YYSTYPE int
+
+int yyerror(char *);
+int yylex(char **exp);
+
+extern int result;
+
+typedef struct
+{
+ int timestamp;
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ char *text;
+} yyltype;
+
+#define YYLTYPE yyltype
+
+#define YYFINAL 51
+#define YYFLAG -32768
+#define YYNTBASE 21
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 264 ? yytranslate[x] : 26)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 14, 9, 2, 18,
+ 19, 12, 10, 20, 11, 2, 13, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 17, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 8, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 15, 16
+};
+
+
+static const short yyr1[] = { 0,
+ 21, 21, 22, 23, 23, 23, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 25, 25, 25
+};
+
+static const short yyr2[] = { 0,
+ 1, 3, 1, 1, 1, 3, 1, 3, 3, 3,
+ 3, 3, 3, 3, 2, 2, 1, 4, 6, 8
+};
+
+static const short yydefact[] = { 0,
+ 3, 4, 0, 0, 0, 0, 0, 0, 5, 7,
+ 1, 17, 0, 0, 0, 0, 4, 16, 15, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 6, 14, 13, 11, 12, 8, 9, 10, 18,
+ 0, 0, 0, 0, 19, 0, 0, 20, 0, 0,
+ 0
+};
+
+static const short yydefgoto[] = { 49,
+ 9, 10, 11, 12
+};
+
+static const short yypact[] = { 19,
+-32768, -11, -7, -5, -4, 38, 38, 38,-32768,-32768,
+ 136,-32768, 38, 38, 38, 38,-32768,-32768,-32768, 88,
+ 38, 38, 38, 38, 38, 38, 38, 136, 100, 49,
+ 62,-32768, 41, 54, -9, -9,-32768,-32768,-32768,-32768,
+ 38, 38, 112, 75,-32768, 38, 124,-32768, 12, 27,
+-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768, -6,-32768
+};
+
+
+#define YYLAST 150
+
+
+static const short yytable[] = { 18,
+ 19, 20, 25, 26, 27, 13, 28, 29, 30, 31,
+ 14, 50, 15, 16, 33, 34, 35, 36, 37, 38,
+ 39, 1, 2, 3, 4, 5, 51, 0, 6, 7,
+ 0, 0, 0, 0, 43, 44, 8, 0, 0, 47,
+ 1, 17, 3, 4, 5, 0, 0, 6, 7, 22,
+ 23, 24, 25, 26, 27, 8, 21, 22, 23, 24,
+ 25, 26, 27, 23, 24, 25, 26, 27, 41, 21,
+ 22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
+ 0, 42, 21, 22, 23, 24, 25, 26, 27, 0,
+ 0, 0, 0, 0, 46, 21, 22, 23, 24, 25,
+ 26, 27, 0, 0, 0, 0, 32, 21, 22, 23,
+ 24, 25, 26, 27, 0, 0, 0, 0, 40, 21,
+ 22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
+ 45, 21, 22, 23, 24, 25, 26, 27, 0, 0,
+ 0, 0, 48, 21, 22, 23, 24, 25, 26, 27
+};
+
+static const short yycheck[] = { 6,
+ 7, 8, 12, 13, 14, 17, 13, 14, 15, 16,
+ 18, 0, 18, 18, 21, 22, 23, 24, 25, 26,
+ 27, 3, 4, 5, 6, 7, 0, -1, 10, 11,
+ -1, -1, -1, -1, 41, 42, 18, -1, -1, 46,
+ 3, 4, 5, 6, 7, -1, -1, 10, 11, 9,
+ 10, 11, 12, 13, 14, 18, 8, 9, 10, 11,
+ 12, 13, 14, 10, 11, 12, 13, 14, 20, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
+ -1, 20, 8, 9, 10, 11, 12, 13, 14, -1,
+ -1, -1, -1, -1, 20, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 8, 9, 10,
+ 11, 12, 13, 14, -1, -1, -1, -1, 19, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
+ 19, 8, 9, 10, 11, 12, 13, 14, -1, -1,
+ -1, -1, 19, 8, 9, 10, 11, 12, 13, 14
+};
+#define YYPURE 1
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYIMPURE
+#define YYLEX yylex(&exp)
+#endif
+
+#ifndef YYPURE
+#define YYLEX yylex(&yylval)//, &yylloc) MY MODIF!
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYIMPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+
+int yynerrs; /* number of parse errors so far */
+#endif /* YYIMPURE */
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#define YYINITDEPTH 5000
+#define YYMAXDEPTH 5000
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+#define __yy_bcopy(from,to,count) memcpy(to,from,(count)>0?(count):0)
+
+//#ln 131 "bison.simple"
+int yyparse(char *exp)
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+ int yystacksize = YYINITDEPTH;
+
+#ifndef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+ yylval = 0;
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("internal error: parser stack overflow");
+ return 2;
+ }
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+
+
+ if (yyssp >= yyss + yystacksize - 1) YYABORT;
+ }
+
+
+// yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+// yyStackSize = yyssp - (yyss - 1);
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+
+ switch (yyn) {
+
+case 1:
+//#ln 32 "cal.y"
+{ yyval = yyvsp[0]; result = yyvsp[0]; ;
+ break;}
+case 2:
+//#ln 34 "cal.y"
+{ {
+ int i = (int)setVar((int)yyvsp[-2], 0);
+ int v;
+
+ if (i < 0) v=createCompiledValue(0, NULL);
+ else if (i < EVAL_MAX_VARS) v= createCompiledValue(0, &(varTable[i].value));
+ else if (i < EVAL_MAX_VARS+100) v= createCompiledValue(0, globalregs+i-EVAL_MAX_VARS);
+ else v=createCompiledValue(0, NULL);
+
+ yyval = createCompiledFunction2(MATH_SIMPLE, FN_ASSIGN, v, (int)yyvsp[0]);
+ result = yyval;
+ }
+ ;
+ break;}
+case 3:
+//#ln 50 "cal.y"
+{ yyval = yyvsp[0] ;
+ break;}
+case 4:
+//#ln 55 "cal.y"
+{ yyval = getVar((int)yyvsp[0]);;
+ break;}
+case 5:
+//#ln 57 "cal.y"
+{ yyval = yyvsp[0];;
+ break;}
+case 6:
+//#ln 59 "cal.y"
+{ yyval = yyvsp[-1];;
+ break;}
+case 7:
+//#ln 64 "cal.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 8:
+//#ln 66 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_MULTIPLY, yyvsp[-2], yyvsp[0]);
+ break;}
+case 9:
+//#ln 72 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_DIVIDE, yyvsp[-2], yyvsp[0]);
+ break;}
+case 10:
+//#ln 78 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_MODULO, yyvsp[-2], yyvsp[0]);
+ break;}
+case 11:
+//#ln 84 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_ADD, yyvsp[-2], yyvsp[0]);
+ break;}
+case 12:
+//#ln 90 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_SUB, yyvsp[-2], yyvsp[0]);
+ break;}
+case 13:
+//#ln 96 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_AND, yyvsp[-2], yyvsp[0]);
+ break;}
+case 14:
+//#ln 102 "cal.y"
+{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_OR, yyvsp[-2], yyvsp[0]);
+ break;}
+case 15:
+//#ln 108 "cal.y"
+{ yyval = createCompiledFunction1(MATH_SIMPLE, FN_UMINUS, yyvsp[0]);
+ break;}
+case 16:
+//#ln 114 "cal.y"
+{ yyval = createCompiledFunction1(MATH_SIMPLE, FN_UPLUS, yyvsp[0]);
+ break;}
+case 17:
+//#ln 120 "cal.y"
+{ yyval = yyvsp[0];
+ break;}
+case 18:
+//#ln 125 "cal.y"
+{ yyval = createCompiledFunction1(MATH_FN, (int)yyvsp[-3], yyvsp[-1]);
+ break;}
+case 19:
+//#ln 131 "cal.y"
+{ yyval = createCompiledFunction2(MATH_FN, (int)yyvsp[-5], yyvsp[-3], yyvsp[-1]);
+ break;}
+case 20:
+//#ln 137 "cal.y"
+{ yyval = createCompiledFunction3(MATH_FN, (int)yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]);
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+//#ln 362 "bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+ *++yyvsp = yyval;
+
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+#error this should not compile
+ msg = (char *) xmalloc(size + 15);
+ strcpy(msg, "syntax error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("syntax error");
+ }
+
+//yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF) YYABORT;
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+ yystate = yyn;
+ goto yynewstate;
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/Compiler.c b/Src/Plugins/Visualization/vis_avs/evallib/Compiler.c
new file mode 100644
index 00000000..56d3a067
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/Compiler.c
@@ -0,0 +1,747 @@
+#include <windows.h>
+#include <stdio.h>
+#include <math.h>
+#include "Compiler.h"
+#include "eval.h"
+
+// defining this allows code to run in different threads at the same time
+// it tends however, to be slower. We leave this OFF for AVS, since most of our shit runs in one thread
+// anyhow.
+//#define NSEEL_REENTRANT_EXECUTION
+
+#ifdef NSEEL_REENTRANT_EXECUTION
+#include <malloc.h>
+#endif
+#define NSEEL_USE_CRITICAL_SECTION g_eval_cs
+
+// note that compiling can only happen in one thread at a time, always.
+
+
+
+
+int g_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
+
+#ifdef NSEEL_USE_CRITICAL_SECTION
+CRITICAL_SECTION NSEEL_USE_CRITICAL_SECTION;
+#endif
+
+
+#define LLB_DSIZE (65536-64)
+typedef struct _llBlock {
+ struct _llBlock *next;
+ int sizeused;
+ char block[LLB_DSIZE];
+} llBlock;
+
+typedef struct _startPtr {
+ struct _startPtr *next;
+ void *startptr;
+} startPtr;
+
+typedef struct {
+ int workTablePtr_size;
+
+ llBlock *blocks;
+ void *code;
+ int code_stats[4];
+} codeHandleType;
+
+static llBlock *blocks_head = NULL;
+static llBlock *tmpblocks_head = NULL; // used only during compile
+
+#define NSEEL_MAX_TEMPSPACE_ENTRIES 8192
+
+static int g_evallib_computTableTop; // make it abort on potential overflow =)
+
+static int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
+
+static void *__newBlock(llBlock **start,int size);
+
+#define newTmpBlock(x) __newBlock(&tmpblocks_head,x)
+#define newBlock(x) __newBlock(&blocks_head,x)
+
+static void freeBlocks(llBlock *start);
+
+char *g_evallib_visdata;
+
+#define DECL_ASMFUNC(x) \
+ void _asm_##x##(void); \
+ void _asm_##x##_end(void); \
+
+ DECL_ASMFUNC(sin)
+ DECL_ASMFUNC(cos)
+ DECL_ASMFUNC(tan)
+ DECL_ASMFUNC(asin)
+ DECL_ASMFUNC(acos)
+ DECL_ASMFUNC(atan)
+ DECL_ASMFUNC(atan2)
+ DECL_ASMFUNC(sqr)
+ DECL_ASMFUNC(sqrt)
+ DECL_ASMFUNC(pow)
+ DECL_ASMFUNC(exp)
+ DECL_ASMFUNC(log)
+ DECL_ASMFUNC(log10)
+ DECL_ASMFUNC(abs)
+ DECL_ASMFUNC(min)
+ DECL_ASMFUNC(min)
+ DECL_ASMFUNC(max)
+ DECL_ASMFUNC(sig)
+ DECL_ASMFUNC(sign)
+ DECL_ASMFUNC(rand)
+ DECL_ASMFUNC(band)
+ DECL_ASMFUNC(bor)
+ DECL_ASMFUNC(bnot)
+ DECL_ASMFUNC(if)
+ DECL_ASMFUNC(equal)
+ DECL_ASMFUNC(below)
+ DECL_ASMFUNC(above)
+ DECL_ASMFUNC(assign)
+ DECL_ASMFUNC(add)
+ DECL_ASMFUNC(sub)
+ DECL_ASMFUNC(mul)
+ DECL_ASMFUNC(div)
+ DECL_ASMFUNC(mod)
+ DECL_ASMFUNC(or)
+ DECL_ASMFUNC(and)
+ DECL_ASMFUNC(uplus)
+ DECL_ASMFUNC(uminus)
+ DECL_ASMFUNC(floor)
+ DECL_ASMFUNC(ceil)
+ DECL_ASMFUNC(invsqrt)
+ DECL_ASMFUNC(exec2)
+
+ DECL_ASMFUNC(getosc)
+ DECL_ASMFUNC(getspec)
+ DECL_ASMFUNC(gettime)
+ DECL_ASMFUNC(getmouse)
+ DECL_ASMFUNC(setmousepos)
+
+
+static functionType fnTable1[36] = {
+ { "if", _asm_if,_asm_if_end, 3 },
+ { "sin", _asm_sin,_asm_sin_end, 1 },
+ { "cos", _asm_cos,_asm_cos_end, 1 },
+ { "tan", _asm_tan,_asm_tan_end, 1 },
+ { "asin", _asm_asin,_asm_asin_end, 1 },
+ { "acos", _asm_acos,_asm_acos_end, 1 },
+ { "atan", _asm_atan,_asm_atan_end, 1 },
+ { "atan2", _asm_atan2,_asm_atan2_end, 2 },
+ { "sqr", _asm_sqr,_asm_sqr_end, 1 },
+ { "sqrt", _asm_sqrt,_asm_sqrt_end, 1 },
+ { "pow", _asm_pow,_asm_pow_end, 2 },
+ { "exp", _asm_exp,_asm_exp_end, 1 },
+ { "log", _asm_log,_asm_log_end, 1 },
+ { "log10", _asm_log10,_asm_log10_end, 1 },
+ { "abs", _asm_abs,_asm_abs_end, 1 },
+ { "min", _asm_min,_asm_min_end, 2 },
+ { "max", _asm_max,_asm_max_end, 2 },
+ { "sigmoid",_asm_sig,_asm_sig_end, 2 } ,
+ { "sign", _asm_sign,_asm_sign_end, 1 } ,
+ { "rand", _asm_rand,_asm_rand_end, 1 } ,
+ { "band", _asm_band,_asm_band_end, 2 } ,
+ { "bor", _asm_bor,_asm_bor_end, 2 } ,
+ { "bnot", _asm_bnot,_asm_bnot_end, 1 } ,
+ { "equal", _asm_equal,_asm_equal_end, 2 },
+ { "below", _asm_below,_asm_below_end, 2 },
+ { "above", _asm_above,_asm_above_end, 2 },
+ { "floor", _asm_floor,_asm_floor_end, 1 },
+ { "ceil", _asm_ceil,_asm_ceil_end, 1 },
+ { "invsqrt", _asm_invsqrt,_asm_invsqrt_end, 1 },
+ { "assign",_asm_assign,_asm_assign_end,2},
+ { "exec2",_asm_exec2,_asm_exec2_end,2},
+ // these will be seperated since they are AVS specific
+ { "getosc", _asm_getosc,_asm_getosc_end,3 },
+ { "getspec",_asm_getspec,_asm_getspec_end,3 },
+ { "gettime", _asm_gettime,_asm_gettime_end,1},
+ { "getkbmouse",_asm_getmouse,_asm_getmouse_end,1},
+ { "setmousepos",_asm_setmousepos,_asm_setmousepos_end,2},
+ };
+
+
+functionType *getFunctionFromTable(int idx)
+{
+ // todo: add API for adding functions to a seperate table :)
+ if (idx<0 || idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) return 0;
+ return fnTable1+idx;
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static void *realAddress(void *fn, void *fn_e, int *size)
+{
+#ifdef _DEBUG
+ // Debug Mode
+ *siiiize=0; // fucko, need to figure this out
+char *ptr = (char *)fn;
+return ptr + (*(int *)(ptr+1))+5;
+#else
+ // Release Mode
+ *size = (int)fn_e - (int) fn;
+ return fn;
+#endif
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static void freeBlocks(llBlock *start)
+{
+ while (start)
+ {
+ llBlock *llB = start->next;
+ GlobalFree(start);
+ start=llB;
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static void *__newBlock(llBlock **start, int size)
+{
+ llBlock *llb;
+ int alloc_size;
+ if (*start && (LLB_DSIZE - (*start)->sizeused) >= size)
+ {
+ void *t=(*start)->block+(*start)->sizeused;
+ (*start)->sizeused+=size;
+ return t;
+ }
+
+ alloc_size=sizeof(llBlock);
+ if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
+ llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+ // benski> CUT: llb = (llBlock *)GlobalAlloc(GMEM_FIXED,alloc_size); // grab bigger block if absolutely necessary (heh)
+ llb->sizeused=size;
+ llb->next = *start;
+ *start = llb;
+ return llb->block;
+}
+
+
+#define X86_MOV_EAX_DIRECTVALUE 0xB8
+#define X86_MOV_ESI_DIRECTVALUE 0xBE
+#define X86_MOV_ESI_DIRECTMEMVALUE 0x358B
+#define X86_PUSH_EAX 0x50
+#define X86_POP_EBX 0x5B
+#define X86_POP_ECX 0x59
+#define X86_MOV_ESI_EDI 0xF78B
+
+#define X86_PUSH_ESI 0x56
+#define X86_POP_ESI 0x5E
+
+#define X86_RET 0xC3
+
+
+//---------------------------------------------------------------------------------------------------------------
+static int *findFBlock(char *p)
+{
+ while (*(int *)p != 0xFFFFFFFF) p++;
+ return (int*)p;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------
+int createCompiledValue(double value, double *addrValue)
+{
+ unsigned char *block;
+ double *dupValue;
+
+ block=(unsigned char *)newTmpBlock(4+5);
+
+ if (addrValue == NULL)
+ {
+ l_stats[3]+=sizeof(double);
+ *(dupValue = (double *)newBlock(sizeof(double))) = value;
+ }
+ else
+ dupValue = addrValue;
+
+ ((int*)block)[0]=5;
+ block[4]=X86_MOV_EAX_DIRECTVALUE; // mov eax, <value>
+ *(int *)(block+5) = (int)dupValue;
+
+ return ((int)(block));
+
+}
+
+//---------------------------------------------------------------------------------------------------------------
+int getFunctionAddress(int fntype, int fn, int *size)
+{
+ switch (fntype)
+ {
+ case MATH_SIMPLE:
+ switch (fn)
+ {
+ case FN_ASSIGN:
+ return (int)realAddress(_asm_assign,_asm_assign_end,size);
+ case FN_ADD:
+ return (int)realAddress(_asm_add,_asm_add_end,size);
+ case FN_SUB:
+ return (int)realAddress(_asm_sub,_asm_sub_end,size);
+ case FN_MULTIPLY:
+ return (int)realAddress(_asm_mul,_asm_mul_end,size);
+ case FN_DIVIDE:
+ return (int)realAddress(_asm_div,_asm_div_end,size);
+ case FN_MODULO:
+ return (int)realAddress(_asm_mod,_asm_mod_end,size);
+ case FN_AND:
+ return (int)realAddress(_asm_and,_asm_and_end,size);
+ case FN_OR:
+ return (int)realAddress(_asm_or,_asm_or_end,size);
+ case FN_UPLUS:
+ return (int)realAddress(_asm_uplus,_asm_uplus_end,size);
+ case FN_UMINUS:
+ return (int)realAddress(_asm_uminus,_asm_uminus_end,size);
+ }
+ case MATH_FN:
+ {
+ functionType *p=getFunctionFromTable(fn);
+ if (!p)
+ {
+ if (size) *size=0;
+ return 0;
+ }
+ return (int)realAddress(p->afunc,p->func_e,size);
+ }
+ }
+ return 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------
+int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3)
+{
+ int sizes1=((int *)code1)[0];
+ int sizes2=((int *)code2)[0];
+ int sizes3=((int *)code3)[0];
+
+ if (fntype == MATH_FN && fn == 0) // special case: IF
+ {
+ void *func3;
+ int size;
+ int *ptr;
+ char *block;
+
+ unsigned char *newblock2,*newblock3;
+
+ newblock2=newBlock(sizes2+1);
+ memcpy(newblock2,(char*)code2+4,sizes2);
+ newblock2[sizes2]=X86_RET;
+
+ newblock3=newBlock(sizes3+1);
+ memcpy(newblock3,(char*)code3+4,sizes3);
+ newblock3[sizes3]=X86_RET;
+
+ l_stats[2]+=sizes2+sizes3+2;
+
+ func3 = realAddress(_asm_if,_asm_if_end,&size);
+
+ block=(char *)newTmpBlock(4+sizes1+size);
+ ((int*)block)[0]=sizes1+size;
+ memcpy(block+4,(char*)code1+4,sizes1);
+ ptr=(int *)(block+4+sizes1);
+ memcpy(ptr,func3,size);
+
+ ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
+ ptr=findFBlock((char*)ptr); *ptr=(int)newblock3;
+
+ return (int)block;
+
+ }
+ else
+ {
+ int size2;
+ unsigned char *block;
+ unsigned char *outp;
+
+ int myfunc;
+
+ myfunc = getFunctionAddress(fntype, fn, &size2);
+
+ block=(unsigned char *)newTmpBlock(4+size2+sizes1+sizes2+sizes3+4);
+
+ ((int*)block)[0]=4+size2+sizes1+sizes2+sizes3;
+ outp=block+4;
+ memcpy(outp,(char*)code1+4,sizes1);
+ outp+=sizes1;
+ *outp++ = X86_PUSH_EAX;
+ memcpy(outp,(char*)code2+4,sizes2);
+ outp+=sizes2;
+ *outp++ = X86_PUSH_EAX;
+ memcpy(outp,(char*)code3+4,sizes3);
+ outp+=sizes3;
+ *outp++ = X86_POP_EBX;
+ *outp++ = X86_POP_ECX;
+
+ memcpy(block+4+4+sizes1+sizes2+sizes3,(void*)myfunc,size2);
+ g_evallib_computTableTop++;
+
+ return ((int)(block));
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------------
+int createCompiledFunction2(int fntype, int fn, int code1, int code2)
+{
+ int size2;
+ unsigned char *block;
+ unsigned char *outp;
+
+ int myfunc;
+ int sizes1=((int *)code1)[0];
+ int sizes2=((int *)code2)[0];
+
+ myfunc = getFunctionAddress(fntype, fn, &size2);
+
+ block=(unsigned char *)newTmpBlock(2+size2+sizes1+sizes2+4);
+
+ ((int*)block)[0]=2+size2+sizes1+sizes2;
+ outp=block+4;
+ memcpy(outp,(char*)code1+4,sizes1);
+ outp+=sizes1;
+ *outp++ = X86_PUSH_EAX;
+ memcpy(outp,(char*)code2+4,sizes2);
+ outp+=sizes2;
+ *outp++ = X86_POP_EBX;
+
+ memcpy(block+4+2+sizes1+sizes2,(void*)myfunc,size2);
+
+ g_evallib_computTableTop++;
+
+ return ((int)(block));
+
+}
+
+
+//---------------------------------------------------------------------------------------------------------------
+int createCompiledFunction1(int fntype, int fn, int code)
+{
+ int size,size2;
+ char *block;
+ int myfunc;
+ void *func1;
+
+ size =((int *)code)[0];
+ func1 = (void *)(code+4);
+
+ myfunc = getFunctionAddress(fntype, fn, &size2);
+
+ block=(char *)newTmpBlock(4+size+size2);
+ ((int*)block)[0]=size+size2;
+
+ memcpy(block+4, func1, size);
+ memcpy(block+size+4,(void*)myfunc,size2);
+
+ g_evallib_computTableTop++;
+
+ return ((int)(block));
+}
+
+static char *preprocessCode(char *expression)
+{
+ int len=0;
+ int alloc_len=strlen(expression)+1+64;
+ char *buf=(char *)malloc(alloc_len);
+
+ while (*expression)
+ {
+ if (len > alloc_len-32)
+ {
+ alloc_len = len+128;
+ buf=(char*)realloc(buf,alloc_len);
+ }
+
+ if (expression[0] == '/')
+ {
+ if (expression[1] == '/')
+ {
+ expression+=2;
+ while (expression[0] && expression[0] != '\r' && expression[0] != '\n') expression++;
+ }
+ else if (expression[1] == '*')
+ {
+ expression+=2;
+ while (expression[0] && (expression[0] != '*' || expression[1] != '/')) expression++;
+ if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/
+ }
+ else
+ {
+ char c=buf[len++]=*expression++;
+ if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
+ }
+ }
+ else if (expression[0] == '$')
+ {
+ if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I')
+ {
+ static char *str="3.141592653589793";
+ expression+=3;
+ memcpy(buf+len,str,17);
+ len+=17; //strlen(str);
+ l_stats[0]+=17;
+ }
+ else if (toupper(expression[1]) == 'E')
+ {
+ static char *str="2.71828183";
+ expression+=2;
+ memcpy(buf+len,str,10);
+ len+=10; //strlen(str);
+ l_stats[0]+=10;
+ }
+ if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I')
+ {
+ static char *str="1.61803399";
+ expression+=4;
+ memcpy(buf+len,str,10);
+ len+=10; //strlen(str);
+ l_stats[0]+=10;
+ }
+ else
+ {
+ char c = buf[len++]=*expression++;
+ if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
+ }
+ }
+ else
+ {
+ char c=*expression++;
+ if (c == '\r' || c == '\n' || c == '\t') c=' ';
+ buf[len++]=c;
+ if (c != ' ') l_stats[0]++;
+ }
+ }
+ buf[len]=0;
+
+ return buf;
+}
+
+int g_log_errors;
+
+static void movestringover(char *str, int amount)
+{
+ char tmp[1024+8];
+
+ int l=(int)strlen(str);
+ l=min(1024-amount-1,l);
+
+ memcpy(tmp,str,l+1);
+
+ while (l >= 0 && tmp[l]!='\n') l--;
+ l++;
+
+ tmp[l]=0;//ensure we null terminate
+
+ memcpy(str+amount,tmp,l+1);
+}
+
+//------------------------------------------------------------------------------
+int compileCode(char *_expression)
+{
+ char *expression,*expression_start;
+ int computable_size=0;
+ codeHandleType *handle;
+ startPtr *scode=NULL;
+ startPtr *startpts=NULL;
+
+ if (!_expression || !*_expression) return 0;
+ if (!varTable) return 0;
+
+ #ifdef NSEEL_USE_CRITICAL_SECTION
+ EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+ #endif
+
+ blocks_head=0;
+ tmpblocks_head=0;
+ memset(l_stats,0,sizeof(l_stats));
+
+ handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
+
+ if (!handle)
+ {
+ #ifdef NSEEL_USE_CRITICAL_SECTION
+ LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+ #endif
+ return 0;
+ }
+
+ memset(handle,0,sizeof(codeHandleType));
+
+ expression_start=expression=preprocessCode(_expression);
+
+ while (*expression)
+ {
+ startPtr *tmp;
+ char *expr;
+ colCount=0;
+
+ // single out segment
+ while (*expression == ';' || *expression == ' ') expression++;
+ if (!*expression) break;
+ expr=expression;
+ while (*expression && *expression != ';') expression++;
+ if (*expression) *expression++ = 0;
+
+ // parse
+ tmp=(startPtr*) newTmpBlock(sizeof(startPtr));
+ if (!tmp) break;
+ g_evallib_computTableTop=0;
+ tmp->startptr=compileExpression(expr);
+ if (computable_size < g_evallib_computTableTop)
+ {
+ computable_size=g_evallib_computTableTop;
+ }
+
+ if (g_evallib_computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES-32)
+ {
+ tmp->startptr=0; // overflow in this mode
+ }
+
+ if (!tmp->startptr)
+ {
+ if (g_log_errors)
+ {
+ int l=strlen(expr);
+ if (l > 512) l=512;
+ movestringover(last_error_string,l+2);
+ memcpy(last_error_string,expr,l);
+ last_error_string[l]='\r';
+ last_error_string[l+1]='\n';
+ }
+
+ scode=NULL;
+ break;
+ }
+ tmp->next=NULL;
+ if (!scode) scode=startpts=tmp;
+ else
+ {
+ scode->next=tmp;
+ scode=tmp;
+ }
+ }
+
+ // check to see if failed on the first startingCode
+ if (!scode)
+ {
+ freeBlocks(blocks_head); // free blocks
+ handle=NULL; // return NULL (after resetting blocks_head)
+ }
+ else
+ {
+ // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item
+ unsigned char *writeptr;
+ int size=1; // for ret at end :)
+ startPtr *p;
+ p=startpts;
+ while (p)
+ {
+ size+=2; // mov esi, edi
+ size+=*(int *)p->startptr;
+ p=p->next;
+ }
+ handle->code = newBlock(size);
+ if (handle->code)
+ {
+ writeptr=(unsigned char *)handle->code;
+ p=startpts;
+ while (p)
+ {
+ int thissize=*(int *)p->startptr;
+ *(unsigned short *)writeptr= X86_MOV_ESI_EDI;
+ writeptr+=2;
+ memcpy(writeptr,(char*)p->startptr + 4,thissize);
+ writeptr += thissize;
+
+ p=p->next;
+ }
+ *writeptr=X86_RET; // ret
+ l_stats[1]=size;
+ }
+ handle->blocks = blocks_head;
+ handle->workTablePtr_size=(computable_size+4) * sizeof(double);
+ }
+ freeBlocks(tmpblocks_head); // free blocks
+ tmpblocks_head=0;
+
+ blocks_head=0;
+
+ if (handle)
+ {
+ memcpy(handle->code_stats,l_stats,sizeof(l_stats));
+ g_evallib_stats[0]+=l_stats[0];
+ g_evallib_stats[1]+=l_stats[1];
+ g_evallib_stats[2]+=l_stats[2];
+ g_evallib_stats[3]+=l_stats[3];
+ g_evallib_stats[4]++;
+ }
+ memset(l_stats,0,sizeof(l_stats));
+
+ #ifdef NSEEL_USE_CRITICAL_SECTION
+ LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+ #endif
+
+ free(expression_start);
+
+ return (int)handle;
+}
+
+//------------------------------------------------------------------------------
+void executeCode(int handle, char visdata[2][2][576])
+{
+#ifdef NSEEL_REENTRANT_EXECUTION
+ int baseptr;
+#else
+ static double _tab[NSEEL_MAX_TEMPSPACE_ENTRIES];
+ int baseptr = (int) _tab;
+#endif
+ codeHandleType *h = (codeHandleType *)handle;
+ if (!h || !h->code) return;
+#ifdef NSEEL_USE_CRITICAL_SECTION
+ EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+#endif
+ g_evallib_visdata=(char*)visdata;
+#ifdef NSEEL_REENTRANT_EXECUTION
+ baseptr = (int) alloca(h->workTablePtr_size);
+ if (!baseptr) return;
+#endif
+ {
+ int startPoint=(int)h->code;
+ __asm
+ {
+ mov ebx, baseptr
+ mov eax, startPoint
+ pushad // Lets cover our ass
+ mov edi, ebx
+ call eax
+ popad
+ }
+ }
+ g_evallib_visdata=NULL;
+ #ifdef NSEEL_USE_CRITICAL_SECTION
+ LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+ #endif
+}
+
+//------------------------------------------------------------------------------
+void freeCode(int handle)
+{
+ codeHandleType *h = (codeHandleType *)handle;
+ if (h != NULL)
+ {
+ g_evallib_stats[0]-=h->code_stats[0];
+ g_evallib_stats[1]-=h->code_stats[1];
+ g_evallib_stats[2]-=h->code_stats[2];
+ g_evallib_stats[3]-=h->code_stats[3];
+ g_evallib_stats[4]--;
+ freeBlocks(h->blocks);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+void resetVars(varType *vars)
+{
+#ifdef NSEEL_USE_CRITICAL_SECTION
+ if (vars) EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+#endif
+ varTable=vars;
+#ifdef NSEEL_USE_CRITICAL_SECTION
+ if (!vars) LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
+#endif
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/Compiler.h b/Src/Plugins/Visualization/vis_avs/evallib/Compiler.h
new file mode 100644
index 00000000..2a41d7fd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/Compiler.h
@@ -0,0 +1,47 @@
+#ifndef __COMPILER_H
+#define __COMPILER_H
+
+#define FN_ASSIGN 0
+#define FN_MULTIPLY 1
+#define FN_DIVIDE 2
+#define FN_MODULO 3
+#define FN_ADD 4
+#define FN_SUB 5
+#define FN_AND 6
+#define FN_OR 7
+#define FN_UMINUS 8
+#define FN_UPLUS 9
+
+#define MATH_SIMPLE 0
+#define MATH_FN 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int compileCode(char *exp);
+void executeCode(int handle, char visdata[2][2][576]);
+void freeCode(int handle);
+
+
+
+typedef struct {
+ char *name;
+ void *afunc;
+ void *func_e;
+ int nParams;
+ } functionType;
+
+extern functionType *getFunctionFromTable(int idx);
+
+int createCompiledValue(double value, double *addrValue);
+int createCompiledFunction1(int fntype, int fn, int code);
+int createCompiledFunction2(int fntype, int fn, int code1, int code2);
+int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/GETTOK.C b/Src/Plugins/Visualization/vis_avs/evallib/GETTOK.C
new file mode 100644
index 00000000..69428de2
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/GETTOK.C
@@ -0,0 +1,6 @@
+/*
+ * Bob Denny 28-Aug-82 Remove reference to stdio.h
+ * Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
+ */
+
+#include <lex.h>
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LEX.EXE b/Src/Plugins/Visualization/vis_avs/evallib/LEX.EXE
new file mode 100644
index 00000000..9686a99d
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LEX.EXE
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LEX.H b/Src/Plugins/Visualization/vis_avs/evallib/LEX.H
new file mode 100644
index 00000000..2a6af32b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LEX.H
@@ -0,0 +1,53 @@
+/*
+ * Bob Denny 28-Aug-82 Remove reference to FILE *lexin to
+ * eliminate dependency on standard I/O library. Only
+ * lexgetc() used it, and it's there now.
+ * Add EOF definition for standalone uses.
+ * Corrected comment for llnxtmax.
+ *
+ * Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C. Removed
+ * equivalence of yylval and lexval since
+ * a multi-typed parser wants yylval to be
+ * typed to be the union of the types (YYSTYPE).
+ */
+
+/*
+ * lex library header file -- accessed through
+ * #include <lex.h>
+ */
+
+#include <stdio.h>
+
+/*
+ * Description of scanning tables. The entries at the front of
+ * the struct must remain in place for the assembler routines to find.
+ */
+struct lextab {
+ int llendst; /* Last state number */
+ char *lldefault; /* Default state table */
+ char *llnext; /* Next state table */
+ char *llcheck; /* Check table */
+ int *llbase; /* Base table */
+ int llnxtmax; /* Last in next table */
+ int (*llmove)(); /* Move between states */
+ char *llfinal; /* Final state descriptions */
+ int (*llactr)(); /* Action routine */
+ int *lllook; /* Look ahead vector if != NULL */
+ char *llign; /* Ignore char vec if != NULL */
+ char *llbrk; /* Break char vec if != NULL */
+ char *llill; /* Illegal char vec if != NULL */
+};
+
+#define NBPW 16
+#define LEXERR 256
+#define LEXSKIP (-1)
+#define EOF (-1)
+//#define NULL (0)
+#define LEXECHO(fp) {lexecho((fp));}
+
+#define lextext llbuf
+#define lexlast llend
+
+extern FILE *lexin;
+extern llstin();
+
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LEXGET.C b/Src/Plugins/Visualization/vis_avs/evallib/LEXGET.C
new file mode 100644
index 00000000..26b70418
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LEXGET.C
@@ -0,0 +1,20 @@
+/*
+ * lexget.c
+ *
+ * Bob Denny 28-Aug-82 Move stdio dependencies to lexerr(), lexget(),
+ * lexech() and mapch(). This is one of 4 modules
+ * in lexlib which depend upon the standard I/O package.
+ *
+ * Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C.
+ */
+
+#include <stdio.h>
+#include <lex.h>
+extern char expression[4096];
+extern int pos;
+lexgetc()
+{
+char c = expression[pos];
+if (c) pos++;
+ return( c != 0 ? c : -1);
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LEXSWI.C b/Src/Plugins/Visualization/vis_avs/evallib/LEXSWI.C
new file mode 100644
index 00000000..a4c042b8
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LEXSWI.C
@@ -0,0 +1,23 @@
+/*
+ * lexswitch -- switch lex tables
+ */
+
+/*
+ * Bob Denny 28-Aug-82 Remove reference to stdio.h
+ * Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
+ */
+
+#include <lex.h>
+
+extern struct lextab *_tabp;
+
+struct lextab *
+lexswitch(lp)
+struct lextab *lp;
+{
+ register struct lextab *olp;
+
+ olp = _tabp;
+ _tabp = lp;
+ return(olp);
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LEXTAB.C b/Src/Plugins/Visualization/vis_avs/evallib/LEXTAB.C
new file mode 100644
index 00000000..247272ba
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LEXTAB.C
@@ -0,0 +1,260 @@
+/*
+ * Created by IBM PC LEX from file "scan.l"
+ * - for use with standard I/O
+ */
+
+#include <stdio.h>
+#include <lex.h>
+#define LL16BIT int
+
+int _lmovb(struct lextab *lp, int c, int st)
+{
+ int base;
+
+ while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
+ (lp->llcheck[base] & 0377) != st) {
+
+ if (st != lp->llendst) {
+ base = lp->lldefault[st] & 0377;
+ st = base;
+ }
+ else
+ return(-1);
+ }
+ return(lp->llnext[base]&0377);
+}
+
+int lexval;
+char lbuf[];
+
+#define YYSTYPE int
+#include "cal_tab.h"
+int c;
+
+extern YYSTYPE yylval;
+int translate(int type);
+void count(void);
+void setLastVar(void);
+int lookup(int *typeOfObject);
+
+
+#define INTCONST 1
+#define DBLCONST 2
+#define HEXCONST 3
+#define VARIABLE 4
+#define OTHER 5
+
+int _Alextab(__na__)
+{
+ if (__na__ >= 0 && __na__ <= 19) count();
+ switch (__na__)
+ {
+ case 0: yylval = translate(HEXCONST); return VALUE;
+ case 1: yylval = translate(INTCONST); return VALUE;
+ case 2: yylval = translate(INTCONST); return VALUE;
+ case 3: yylval = translate(DBLCONST); return VALUE;
+ case 4:
+ case 5: setLastVar(); yylval = lookup(&__na__); return __na__;
+ case 6: return '+';
+ case 7: return '-';
+ case 8: return '*';
+ case 9: return '/';
+ case 10: return '%';
+ case 11: return '&';
+ case 12: return '|';
+ case 13: return '(';
+ case 14: return ')';
+ case 15: return '=';
+ case 16: return ',';
+ case 17: return ';';
+ }
+ return (LEXSKIP);
+}
+
+
+char _Flextab[] =
+ {
+ 1, 18, 17, 16, 15, 14, 13, 12,
+ 11, 10, 9, 8, 7, 6, 4, 5,
+ 5, 4, 4, 3, 3, 3, 3, 4,
+ 0, 4, 5, 0, 5, 4, 1, 3,
+ 0, 2, -1, 1, -1,
+ };
+
+
+char _Nlextab[] =
+ {
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 1, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 1, 36, 36, 36, 36, 9, 8, 36,
+ 6, 5, 11, 13, 3, 12, 19, 10,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 36, 2, 36, 4, 36, 36,
+ 36, 29, 29, 29, 29, 29, 29, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 36, 36, 36, 36, 18,
+ 36, 29, 29, 29, 29, 29, 23, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 14, 18,
+ 18, 18, 18, 36, 7, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 36,
+ 36, 36, 36, 36, 36, 36, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 36, 36, 36, 36, 17, 36, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 36, 36, 36, 36, 36, 36,
+ 36, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 36, 36, 36, 36, 16,
+ 36, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 36,
+ 20, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 36, 36, 36, 36, 36,
+ 36, 36, 25, 25, 25, 25, 25, 25,
+ 36, 24, 36, 36, 36, 36, 36, 36,
+ 20, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 25, 25, 25, 25, 25, 25,
+ 36, 24, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 36, 36, 36, 36,
+ 36, 36, 36, 28, 28, 28, 28, 28,
+ 28, 36, 27, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 28, 28, 28, 28, 28,
+ 28, 31, 27, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 36, 36, 36,
+ 36, 36, 36, 36, 34, 34, 34, 33,
+ 34, 34, 36, 32, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 34, 34, 34, 33,
+ 34, 34, 36, 32, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 36, 36,
+ 36, 36, 36, 36, 36, 34, 34, 34,
+ 34, 34, 34, 36, 32, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 34, 34, 34,
+ 34, 34, 34, 36, 32,
+ };
+
+char _Clextab[] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 0, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, -1, -1, -1, -1, 0, 0, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -1, 0, -1, 0, -1, -1,
+ -1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -1, -1, -1, -1, 0,
+ -1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -1, 0, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, -1,
+ -1, -1, -1, -1, -1, -1, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ -1, -1, -1, -1, 14, -1, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, -1, -1, -1, -1, -1, -1,
+ -1, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, -1, -1, -1, -1, 15,
+ -1, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, -1,
+ 19, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, -1, -1, -1, -1, -1,
+ -1, -1, 23, 23, 23, 23, 23, 23,
+ -1, 23, -1, -1, -1, -1, -1, -1,
+ 19, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 23, 23, 23, 23, 23, 23,
+ -1, 23, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, -1, -1, -1, -1,
+ -1, -1, -1, 26, 26, 26, 26, 26,
+ 26, -1, 26, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 26, 26, 26, 26, 26,
+ 26, 30, 26, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, -1, -1, -1,
+ -1, -1, -1, -1, 30, 30, 30, 30,
+ 30, 30, -1, 30, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 30, 30, 30, 30,
+ 30, 30, -1, 30, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, -1, -1,
+ -1, -1, -1, -1, -1, 33, 33, 33,
+ 33, 33, 33, -1, 33, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 33, 33, 33,
+ 33, 33, 33, -1, 33,
+ };
+
+char _Dlextab[] =
+ {
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 15, 14, 14, 36, 36, 20, 19, 14,
+ 14, 23, 15, 15, 26, 23, 36, 19,
+ 36, 36, 33, 30,
+ };
+
+int _Blextab[] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 77, 152,
+ 0, 0, 0, 227, 237, 0, 0, 249,
+ 0, 0, 306, 0, 0, 0, 363, 0,
+ 0, 420, 0, 0, 0,
+ };
+
+struct lextab lextab = {
+ 36,
+ _Dlextab,
+ _Nlextab,
+ _Clextab,
+ _Blextab,
+ 524,
+ _lmovb,
+ _Flextab,
+ _Alextab,
+
+ NULL,
+ 0,
+ 0,
+ 0,
+ };
+
+
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LLSAVE.C b/Src/Plugins/Visualization/vis_avs/evallib/LLSAVE.C
new file mode 100644
index 00000000..23c5e472
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LLSAVE.C
@@ -0,0 +1,6 @@
+/*
+ * This is linked from lexlib to resolve a global in yylex which
+ * will be undefined if the user grammar has not defined any rules
+ * with right-context (look-ahead)
+ */
+char *llsave[1]; /* Look ahead buffer */
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/LMOVB.C b/Src/Plugins/Visualization/vis_avs/evallib/LMOVB.C
new file mode 100644
index 00000000..ef3a0039
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/LMOVB.C
@@ -0,0 +1,29 @@
+/*
+ * Bob Denny 28-Aug-82 Remove reference to stdio.h
+ * Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
+ */
+
+#include <lex.h>
+
+_lmovb(lp, c, st)
+register int c, st;
+register struct lextab *lp;
+{
+ int base;
+
+ while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
+ (lp->llcheck[base] & 0377) != st) {
+
+ if (st != lp->llendst) {
+/*
+ * This miscompiled on Decus C many years ago:
+ * st = lp->lldefault[st] & 0377;
+ */
+ base = lp->lldefault[st] & 0377;
+ st = base;
+ }
+ else
+ return(-1);
+ }
+ return(lp->llnext[base]&0377);
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/Scan.l b/Src/Plugins/Visualization/vis_avs/evallib/Scan.l
new file mode 100644
index 00000000..25134332
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/Scan.l
@@ -0,0 +1,54 @@
+%{
+#define YYSTYPE double
+#include "cal_tab.h"
+int c;
+
+extern YYSTYPE yylval;
+double translate(int type);
+void count(void);
+void setLastVar(void);
+int lookup(int *typeOfObject);
+struct lextab *lexswitch(struct lextab *lp);
+
+
+#define INTCONST 1
+#define DBLCONST 2
+#define HEXCONST 3
+#define VARIABLE 4
+#define OTHER 5
+
+%}
+
+digit = [0-9];
+letter = [a-zA-Z_];
+hex = [a-fA-F0-9];
+/* -- */
+space = [\40];
+/*number = (digit* | "-" digit*);*/
+number = digit*;
+exp = [Ee] number;
+doubl = number "." (digit* | digit* exp);
+
+%%
+hex hex* [hH] { count(); yylval = translate(HEXCONST); return VALUE; }
+digit* { count(); yylval = translate(INTCONST); return VALUE; }
+digit digit* [Dd] { count(); yylval = translate(INTCONST); return VALUE; }
+doubl { count(); yylval = translate(DBLCONST); return VALUE; }
+letter* { count(); { int typeOfObject; setLastVar(); yylval = lookup(&typeOfObject); return typeOfObject; }}
+letter (letter|digit)* { count(); { int typeOfObject; setLastVar(); yylval = lookup(&typeOfObject); return typeOfObject; }}
+'+' { count(); return '+'; }
+'-' { count(); return '-'; }
+'*' { count(); return '*'; }
+'/' { count(); return '/'; }
+'%' { count(); return '%'; }
+'&' { count(); return '&'; }
+'|' { count(); return '|'; }
+'(' { count(); return '('; }
+')' { count(); return ')'; }
+'=' { count(); return '='; }
+',' { count(); return ','; }
+';' { count(); return ';'; }
+[ \t\v\f] { count(); }
+. { count(); }
+
+%%
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/YYLEX.C b/Src/Plugins/Visualization/vis_avs/evallib/YYLEX.C
new file mode 100644
index 00000000..1b63f0c0
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/YYLEX.C
@@ -0,0 +1,143 @@
+#include <lex.h>
+
+#define ERROR 256 /* yacc's value */
+
+static int llset(void);
+static int llinp(char **exp);
+static int lexgetc(char **exp)
+{
+ char c= **exp;
+ if (c) (*exp)++;
+ return( c != 0 ? c : -1);
+}
+static int tst__b(register int c, char tab[])
+{
+ return (tab[(c >> 3) & 037] & (1 << (c & 07)) );
+}
+
+static char *llsave[16]; /* Look ahead buffer */
+static char llbuf[100]; /* work buffer */
+static char *llp1 = &llbuf[0]; /* pointer to next avail. in token */
+static char *llp2 = &llbuf[0]; /* pointer to end of lookahead */
+static char *llend = &llbuf[0]; /* pointer to end of token */
+static char *llebuf = &llbuf[sizeof llbuf];
+static int lleof;
+static int yyline = 0;
+extern struct lextab lextab;
+
+int gettoken(char *lltb, int lltbsiz)
+{
+ register char *lp, *tp, *ep;
+
+ tp = lltb;
+ ep = tp+lltbsiz-1;
+ for (lp = llbuf; lp < llend && tp < ep;)
+ *tp++ = *lp++;
+ *tp = 0;
+ return(tp-lltb);
+}
+
+
+int yylex(char **exp)
+{
+ register int c, st;
+ int final, l, llk, i;
+ register struct lextab *lp;
+ char *cp;
+
+ while (1)
+ {
+ llk = 0;
+ if (llset()) return(0);
+ st = 0;
+ final = -1;
+ lp = &lextab;
+
+ do {
+ if (lp->lllook && (l = lp->lllook[st])) {
+ for (c=0; c<NBPW; c++)
+ if (l&(1<<c))
+ llsave[c] = llp1;
+ llk++;
+ }
+ if ((i = lp->llfinal[st]) != -1) {
+ final = i;
+ llend = llp1;
+ }
+ if ((c = llinp(exp)) < 0)
+ break;
+ if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
+ llp1--;
+ break;
+ }
+ } while ((st = (*lp->llmove)(lp, c, st)) != -1);
+
+
+ if (llp2 < llp1)
+ llp2 = llp1;
+ if (final == -1) {
+ llend = llp1;
+ if (st == 0 && c < 0)
+ return(0);
+ if ((cp = lp->llill) && tst__b(c, cp)) {
+ continue;
+ }
+ return(ERROR);
+ }
+ if (c = (final >> 11) & 037)
+ llend = llsave[c-1];
+ if ((c = (*lp->llactr)(final&03777)) >= 0)
+ return(c);
+ }
+}
+
+void llinit(viud)
+{
+ llp1 = llp2 = llend = llbuf;
+ llebuf = llbuf + sizeof(llbuf);
+ lleof = yyline = 0;
+}
+
+
+static int llinp(char **exp)
+{
+ register c;
+ register struct lextab *lp;
+ register char *cp;
+
+ lp = &lextab;
+ cp = lp->llign; /* Ignore class */
+ for (;;) {
+ /*
+ * Get the next character from the save buffer (if possible)
+ * If the save buffer's empty, then return EOF or the next
+ * input character. Ignore the character if it's in the
+ * ignore class.
+ */
+ c = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc(exp);
+ if (c >= 0) { /* Got a character? */
+ if (cp && tst__b(c, cp))
+ continue; /* Ignore it */
+ if (llp1 >= llebuf) { /* No, is there room? */
+ return -1;
+ }
+ *llp1++ = c; /* Store in token buff */
+ } else
+ lleof = 1; /* Set EOF signal */
+ return(c);
+ }
+}
+
+static int llset(void)
+/*
+ * Return TRUE if EOF and nothing was moved in the look-ahead buffer
+ */
+{
+ register char *lp1, *lp2;
+
+ for (lp1 = llbuf, lp2 = llend; lp2 < llp2;)
+ *lp1++ = *lp2++;
+ llend = llp1 = llbuf;
+ llp2 = lp1;
+ return(lleof && lp1 == llbuf);
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.HAI b/Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.HAI
new file mode 100644
index 00000000..999b5559
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.HAI
@@ -0,0 +1,334 @@
+
+extern int timeclock;
+
+
+int yyerror; /* Yyerror and yycost are set by guards. */
+int yycost; /* If yyerror is set to a nonzero value by a */
+ /* guard, the reduction with which the guard */
+ /* is associated is not performed, and the */
+ /* error recovery mechanism is invoked. */
+ /* Yycost indicates the cost of performing */
+ /* the reduction given the attributes of the */
+ /* symbols. */
+
+
+/* YYMAXDEPTH indicates the size of the parser's state and value */
+/* stacks. */
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 500
+#endif
+
+/* YYMAXRULES must be at least as large as the number of rules that */
+/* could be placed in the rule queue. That number could be determined */
+/* from the grammar and the size of the stack, but, as yet, it is not. */
+
+#ifndef YYMAXRULES
+#define YYMAXRULES 100
+#endif
+
+#ifndef YYMAXBACKUP
+#define YYMAXBACKUP 100
+#endif
+
+
+short yyss[YYMAXDEPTH]; /* the state stack */
+YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
+YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
+short yyrq[YYMAXRULES]; /* the rule queue */
+int yychar; /* the lookahead symbol */
+
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+YYSTYPE yytval; /* the semantic value for the state */
+ /* at the top of the state stack. */
+
+YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+
+YYLTYPE yytloc; /* location data for the state at the */
+ /* top of the state stack */
+
+
+int yynunlexed;
+short yyunchar[YYMAXBACKUP];
+YYSTYPE yyunval[YYMAXBACKUP];
+YYLTYPE yyunloc[YYMAXBACKUP];
+
+short *yygssp; /* a pointer to the top of the state */
+ /* stack; only set during error */
+ /* recovery. */
+
+YYSTYPE *yygvsp; /* a pointer to the top of the value */
+ /* stack; only set during error */
+ /* recovery. */
+
+YYLTYPE *yyglsp; /* a pointer to the top of the */
+ /* location stack; only set during */
+ /* error recovery. */
+
+
+/* Yyget is an interface between the parser and the lexical analyzer. */
+/* It is costly to provide such an interface, but it avoids requiring */
+/* the lexical analyzer to be able to back up the scan. */
+
+yyget()
+{
+ if (yynunlexed > 0)
+ {
+ yynunlexed--;
+ yychar = yyunchar[yynunlexed];
+ yylval = yyunval[yynunlexed];
+ yylloc = yyunloc[yynunlexed];
+ }
+ else if (yychar <= 0)
+ yychar = 0;
+ else
+ {
+ yychar = yylex();
+ if (yychar < 0)
+ yychar = 0;
+ else yychar = YYTRANSLATE(yychar);
+ }
+}
+
+
+
+yyunlex(chr, val, loc)
+int chr;
+YYSTYPE val;
+YYLTYPE loc;
+{
+ yyunchar[yynunlexed] = chr;
+ yyunval[yynunlexed] = val;
+ yyunloc[yynunlexed] = loc;
+ yynunlexed++;
+}
+
+
+
+yyrestore(first, last)
+register short *first;
+register short *last;
+{
+ register short *ssp;
+ register short *rp;
+ register int symbol;
+ register int state;
+ register int tvalsaved;
+
+ ssp = yygssp;
+ yyunlex(yychar, yylval, yylloc);
+
+ tvalsaved = 0;
+ while (first != last)
+ {
+ symbol = yystos[*ssp];
+ if (symbol < YYNTBASE)
+ {
+ yyunlex(symbol, yytval, yytloc);
+ tvalsaved = 1;
+ ssp--;
+ }
+
+ ssp--;
+
+ if (first == yyrq)
+ first = yyrq + YYMAXRULES;
+
+ first--;
+
+ for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
+ {
+ if (symbol < YYNTBASE)
+ state = yytable[yypact[*ssp] + symbol];
+ else
+ {
+ state = yypgoto[symbol - YYNTBASE] + *ssp;
+
+ if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
+ state = yytable[state];
+ else
+ state = yydefgoto[symbol - YYNTBASE];
+ }
+
+ *++ssp = state;
+ }
+ }
+
+ if ( ! tvalsaved && ssp > yyss)
+ {
+ yyunlex(yystos[*ssp], yytval, yytloc);
+ ssp--;
+ }
+
+ yygssp = ssp;
+}
+
+
+
+int
+yyparse()
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register short *yyrq0;
+ register short *yyptr;
+ register YYSTYPE *yyvsp;
+
+ int yylen;
+ YYLTYPE *yylsp;
+ short *yyrq1;
+ short *yyrq2;
+
+ yystate = 0;
+ yyssp = yyss - 1;
+ yyvsp = yyvs - 1;
+ yylsp = yyls - 1;
+ yyrq0 = yyrq;
+ yyrq1 = yyrq0;
+ yyrq2 = yyrq0;
+
+ yychar = yylex();
+ if (yychar < 0)
+ yychar = 0;
+ else yychar = YYTRANSLATE(yychar);
+
+yynewstate:
+
+ if (yyssp >= yyss + YYMAXDEPTH - 1)
+ {
+ yyabort("Parser Stack Overflow");
+ YYABORT;
+ }
+
+ *++yyssp = yystate;
+
+yyresume:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ yyn += yychar;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ yystate = yyn;
+
+ yyptr = yyrq2;
+ while (yyptr != yyrq1)
+ {
+ yyn = *yyptr++;
+ yylen = yyr2[yyn];
+ yyvsp -= yylen;
+ yylsp -= yylen;
+
+ yyguard(yyn, yyvsp, yylsp);
+ if (yyerror)
+ goto yysemerr;
+
+ yyaction(yyn, yyvsp, yylsp);
+ *++yyvsp = yyval;
+
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->timestamp = timeclock;
+ yylsp->first_line = yytloc.first_line;
+ yylsp->first_column = yytloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+
+ if (yyptr == yyrq + YYMAXRULES)
+ yyptr = yyrq;
+ }
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ yyrq2 = yyptr;
+ yyrq1 = yyrq0;
+
+ *++yyvsp = yytval;
+ *++yylsp = yytloc;
+ yytval = yylval;
+ yytloc = yylloc;
+ yyget();
+
+ goto yynewstate;
+
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+yyreduce:
+
+ *yyrq0++ = yyn;
+
+ if (yyrq0 == yyrq + YYMAXRULES)
+ yyrq0 = yyrq;
+
+ if (yyrq0 == yyrq2)
+ {
+ yyabort("Parser Rule Queue Overflow");
+ YYABORT;
+ }
+
+ yyssp -= yyr2[yyn];
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yysemerr:
+ *--yyptr = yyn;
+ yyrq2 = yyptr;
+ yyvsp += yyr2[yyn];
+
+yyerrlab:
+
+ yygssp = yyssp;
+ yygvsp = yyvsp;
+ yyglsp = yylsp;
+ yyrestore(yyrq0, yyrq2);
+ yyrecover();
+ yystate = *yygssp;
+ yyssp = yygssp;
+ yyvsp = yygvsp;
+ yyrq0 = yyrq;
+ yyrq1 = yyrq0;
+ yyrq2 = yyrq0;
+ goto yyresume;
+}
+
+$
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.SIM b/Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.SIM
new file mode 100644
index 00000000..e318ee36
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/bison/BISON.SIM
@@ -0,0 +1,577 @@
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+//#ln 3 "bison.simple"
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* Not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
+#include <alloca.h>
+#endif /* Sparc. */
+#endif /* Not GNU C. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+ This remains here temporarily to ease the
+ transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { yychar = (token), yylval = (value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("Syntax error, cannot back up!"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYIMPURE
+#define YYLEX yylex()
+#endif
+
+#ifndef YYPURE
+#define YYLEX yylex(&yylval)//, &yylloc) MY MODIF!
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYIMPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* YYIMPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_bcopy (from, to, count)
+ char *from;
+ char *to;
+ int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+//#ln 131 "bison.simple"
+int
+yyparse()
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+
+#define YYPOPSTACK (yyvsp--, yysp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yysp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifndef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+ yyoverflow("internal error: parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+#ifdef YYLSP_NEEDED
+ &yyls1, size * sizeof (*yylsp),
+#endif
+ &yystacksize);
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("internal error: parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "entering state %d\n", yystate);
+#endif
+
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "reading a token: ");
+#endif
+ yyStackSize = yyssp - (yyss - 1);
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "next token is %d (%s)\n", yychar, yytname[yychar1]);
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ if (yylen == 1)
+ fprintf (stderr, "reducing 1 value via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+ else
+ fprintf (stderr, "reducing %d values via rule %d (line %d), ",
+ yylen, yyn, yyrline[yyn]);
+ }
+#endif
+
+$ /* the action file gets copied in in place of this dollarsign */
+//#ln 362 "bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) xmalloc(size + 15);
+ strcpy(msg, "syntax error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("syntax error");
+ }
+
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/cal.y b/Src/Plugins/Visualization/vis_avs/evallib/cal.y
new file mode 100644
index 00000000..3844ac03
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/cal.y
@@ -0,0 +1,155 @@
+
+ %{
+ #define YYSTYPE double
+ #include <malloc.h>
+ #include <memory.h>
+ #include "Compiler.h"
+ #include "eval.h"
+
+ yyerror(char *);
+ yylex();
+
+ extern int yyStackSize;
+ extern double result;
+
+ int regs[26];
+ int base;
+
+ %}
+
+ %token VALUE IDENTIFIER FUNCTION1 FUNCTION2 FUNCTION3
+
+ %left '|'
+ %left '&'
+ %left '+' '-'
+ %left '*' '/' '%'
+ %left UMINUS /*supplies precedence for unary minus */
+ %left UPLUS /*supplies precedence for unary plus */
+
+ %% /*beginning of rules section */
+
+ stat : math_expr
+ { $$ = $1; result = $1; }
+ | IDENTIFIER '=' math_expr
+ { if (parseType == PARSE_EVAL)
+ {
+ setVar((int)$1, $3);
+ $$ = $3;
+ result = $3;
+ }
+ else
+ {
+ double i = setVar((int)$1, 0);
+ double v = createCompiledValue(0, &(varTable[(int)i].value));
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_ASSIGN, v, $3);
+ result = $$;
+ }
+ }
+ ;
+
+ value : VALUE { $$ = $1 }
+
+
+ primary_expr
+ : IDENTIFIER
+ { $$ = getVar((int)$1);}
+ | value
+ { $$ = $1;}
+ | '(' math_expr ')'
+ { $$ = $2;}
+ ;
+
+ math_expr
+ : primary_expr
+ { $$ = $1; }
+ | math_expr '*' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = $1 * $3;
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_MULTIPLY, $1, $3);
+ }
+ | math_expr '/' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = $1 / $3;
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_DIVIDE, $1, $3);
+ }
+ | math_expr '%' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = (double)((int)$1 % (int)$3);
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_MODULO, $1, $3);
+ }
+ | math_expr '+' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = $1 + $3;
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_ADD, $1, $3);
+ }
+ | math_expr '-' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = $1 - $3;
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_SUB, $1, $3);
+ }
+ | math_expr '&' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = (double)((int)$1 & (int)$3);
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_AND, $1, $3);
+ }
+ | math_expr '|' math_expr
+ { if (parseType == PARSE_EVAL)
+ $$ = (double)((int)$1 | (int)$3);
+ else
+ $$ = createCompiledFunction2(MATH_SIMPLE, FN_OR, $1, $3);
+ }
+ | '-' math_expr %prec UMINUS
+ { if (parseType == PARSE_EVAL)
+ $$ = -$2;
+ else
+ $$ = createCompiledFunction1(MATH_SIMPLE, FN_UMINUS, $2);
+ }
+ | '+' math_expr %prec UPLUS
+ { if (parseType == PARSE_EVAL)
+ $$ = +$2;
+ else
+ $$ = createCompiledFunction1(MATH_SIMPLE, FN_UPLUS, $2);
+ }
+ | fonction
+ { $$ = $1; }
+ ;
+
+ fonction
+ : FUNCTION1 '(' math_expr ')'
+ { if (parseType == PARSE_EVAL)
+ $$ = calcFunction1((int)$1, $3);
+ else
+ $$ = createCompiledFunction1(MATH_FN, (int)$1, $3);
+ }
+ | FUNCTION2 '(' math_expr ',' math_expr ')'
+ { if (parseType == PARSE_EVAL)
+ $$ = calcFunction2((int)$1, $3, $5);
+ else
+ $$ = createCompiledFunction2(MATH_FN, (int)$1, $3, $5);
+ }
+ | FUNCTION3 '(' math_expr ',' math_expr ',' math_expr ')'
+ { if (parseType == PARSE_EVAL)
+ $$ = calcFunction3((int)$1, $3, $5, $7);
+ else
+ $$ = createCompiledFunction3(MATH_FN, (int)$1, $3, $5, $7);
+ }
+ ;
+
+
+
+ %%
+ main()
+ {
+ return(yyparse());
+ }
+
+ yywrap()
+ {
+ return(1);
+ }
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/cal_tab.h b/Src/Plugins/Visualization/vis_avs/evallib/cal_tab.h
new file mode 100644
index 00000000..ecf31d93
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/cal_tab.h
@@ -0,0 +1,13 @@
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define VALUE 258
+#define IDENTIFIER 259
+#define FUNCTION1 260
+#define FUNCTION2 261
+#define FUNCTION3 262
+#define UMINUS 263
+#define UPLUS 264
+
+
+extern YYSTYPE yylval;
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/cfunc.c b/Src/Plugins/Visualization/vis_avs/evallib/cfunc.c
new file mode 100644
index 00000000..f311aaad
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/cfunc.c
@@ -0,0 +1,901 @@
+#include <windows.h>
+#include <stdio.h>
+#include <math.h>
+#include "Compiler.h"
+#include "eval.h"
+
+
+// these are used by our assembly code
+static float g_cmpaddtab[2]={0.0,1.0};
+static float g_signs[2]={1.0,-1.0};
+static double g_closefact = 0.00001;
+static float g_half=0.5;
+static float negativezeropointfive=-0.5f;
+static float onepointfive=1.5f;
+
+
+
+/// functions called by built code
+#define SHITCALL __fastcall
+
+#define isnonzero(x) (fabs(x) > g_closefact)
+
+//---------------------------------------------------------------------------------------------------------------
+static double SHITCALL _rand(double *x)
+{
+ if (*x < 1.0) *x=1.0;
+ return (double)(rand()%(int)max(*x,1.0));
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static double SHITCALL _band(double *var, double *var2)
+{
+ return isnonzero(*var) && isnonzero(*var2) ? 1 : 0;
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static double SHITCALL _bor(double *var, double *var2)
+{
+ return isnonzero(*var) || isnonzero(*var2) ? 1 : 0;
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static double SHITCALL _sig(double *x, double *constraint)
+{
+ double t = (1+exp(-*x * (*constraint)));
+ return isnonzero(t) ? 1.0/t : 0;
+}
+
+extern char *g_evallib_visdata;
+
+static double SHITCALL getvis(unsigned char *visdata, int bc, int bw, int ch, int xorv)
+{
+ int x;
+ int accum=0;
+ if (ch && ch != 1 && ch != 2) return 0.0;
+
+ if (bw < 1) bw=1;
+ bc-=bw/2;
+ if (bc < 0)
+ {
+ bw+=bc;
+ bc=0;
+ }
+ if (bc > 575) bc=575;
+ if (bc+bw > 576) bw=576-bc;
+
+
+ if (!ch)
+ {
+ for (x = 0; x < bw; x ++)
+ {
+ accum+=(visdata[bc]^xorv)-xorv;
+ accum+=(visdata[bc+576]^xorv)-xorv;
+ bc++;
+ }
+ return (double)accum / ((double)bw*255.0);
+ }
+ else
+ {
+ if (ch == 2) visdata+=576;
+ for (x = 0; x < bw; x ++) accum+=(visdata[bc++]^xorv)-xorv;
+ return (double)accum / ((double)bw*127.5);
+ }
+}
+
+static double SHITCALL getspec_(double *band, double *bandw, double *chan)
+{
+ if (!g_evallib_visdata) return 0.0;
+ return getvis((unsigned char *)g_evallib_visdata,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),0)*0.5;
+}
+
+static double SHITCALL getosc_(double *band, double *bandw, double *chan)
+{
+ if (!g_evallib_visdata) return 0.0;
+ return getvis((unsigned char *)g_evallib_visdata+576*2,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),128);
+}
+
+static double SHITCALL gettime_(double *sc)
+{
+ int ispos;
+ if ((ispos=(*sc > -1.001 && *sc < -0.999)) || (*sc > -2.001 && *sc < -1.999))
+ {
+ int pos=0;
+
+ extern HWND hwnd_WinampParent;
+ if (IsWindow(hwnd_WinampParent))
+ {
+ if (!SendMessageTimeout( hwnd_WinampParent, WM_USER,(WPARAM)!ispos,(LPARAM)105,SMTO_BLOCK,50,(LPDWORD)&pos)) pos=0;
+ }
+ if (!ispos) return (double)pos;
+ return pos / 1000.0;
+ }
+
+ return GetTickCount()/1000.0 - *sc;
+}
+
+static double SHITCALL setmousepos_(double *x, double *y)
+{
+ //fucko: implement me
+ return 0.0;
+}
+
+static double SHITCALL getmouse_(double *which)
+{
+ int w=(int)(*which+0.5);
+
+ if (w > 5)
+ return (GetAsyncKeyState(w)&0x8000)?1.0:0.0;
+
+ if (w == 1 || w == 2)
+ {
+ double DDraw_translatePoint(POINT p, int isY);
+ POINT p;
+ GetCursorPos(&p);
+ return DDraw_translatePoint(p,w==2);
+ }
+ if (w == 3) return (GetAsyncKeyState(MK_LBUTTON)&0x8000)?1.0:0.0;
+ if (w == 4) return (GetAsyncKeyState(MK_RBUTTON)&0x8000)?1.0:0.0;
+ if (w == 5) return (GetAsyncKeyState(MK_MBUTTON)&0x8000)?1.0:0.0;
+ return 0.0;
+}
+// end functions called by inline code
+
+// these make room on the stack for local variables, but do not need to
+// worry about trashing ebp, since none of our code uses ebp and there's
+// a pushad+popad surrounding the call
+
+#if 0 // dont seem to need to do this
+#define CF_PUSHREGS __asm { push esi } __asm { push edi }
+#define CF_POPREGS __asm { pop edi } __asm { pop esi }
+#else
+#define CF_PUSHREGS
+#define CF_POPREGS
+#endif
+
+#define FUNC1_ENTER \
+ double *parm_a, *__nextBlock; \
+ __asm { mov ebp, esp } \
+ __asm { sub esp, __LOCAL_SIZE } \
+ __asm { mov dword ptr parm_a, eax } \
+ __asm { mov __nextBlock, esi } \
+ CF_PUSHREGS
+
+#define FUNC2_ENTER \
+ double *parm_a,*parm_b,*__nextBlock; \
+ __asm { mov ebp, esp } \
+ __asm { sub esp, __LOCAL_SIZE } \
+ __asm { mov dword ptr parm_a, eax } \
+ __asm { mov dword ptr parm_b, ebx } \
+ __asm { mov __nextBlock, esi } \
+ CF_PUSHREGS
+
+#define FUNC3_ENTER \
+ double *parm_a,*parm_b,*parm_c,*__nextBlock; \
+ __asm { mov ebp, esp } \
+ __asm { sub esp, __LOCAL_SIZE } \
+ __asm { mov dword ptr parm_a, eax } \
+ __asm { mov dword ptr parm_b, ebx } \
+ __asm { mov dword ptr parm_c, ecx } \
+ __asm { mov __nextBlock, esi } \
+ CF_PUSHREGS
+
+#define FUNC_LEAVE \
+ __asm { mov eax, esi } \
+ __asm { add esi, 8 } \
+ __asm { mov esp, ebp } \
+ CF_POPREGS
+
+
+static double (*__asin)(double) = &asin;
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_asin(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __asin(*parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_asin_end(void) {}
+
+static double (*__acos)(double) = &acos;
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_acos(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __acos(*parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_acos_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (*__atan)(double) = &atan;
+__declspec ( naked ) void _asm_atan(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __atan(*parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_atan_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (*__atan2)(double,double) = &atan2;
+__declspec ( naked ) void _asm_atan2(void)
+{
+ FUNC2_ENTER
+
+ *__nextBlock = __atan2(*parm_b, *parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_atan2_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+static double (SHITCALL * __sig)(double *,double *) = &_sig;
+__declspec ( naked ) void _asm_sig(void)
+{
+ FUNC2_ENTER
+
+ *__nextBlock = __sig(parm_b, parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_sig_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (SHITCALL *__rand)(double *) = &_rand;
+__declspec ( naked ) void _asm_rand(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __rand(parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_rand_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (SHITCALL *__band)(double *,double *) = &_band;
+__declspec ( naked ) void _asm_band(void)
+{
+ FUNC2_ENTER
+
+ *__nextBlock = __band(parm_b, parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_band_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double ( SHITCALL *__bor)(double *,double *) = &_bor;
+__declspec ( naked ) void _asm_bor(void)
+{
+ FUNC2_ENTER
+
+ *__nextBlock = __bor(parm_b, parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_bor_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (* __pow)(double,double) = &pow;
+__declspec ( naked ) void _asm_pow(void)
+{
+ FUNC2_ENTER
+
+ *__nextBlock = __pow(*parm_b, *parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_pow_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (*__exp)(double) = &exp;
+__declspec ( naked ) void _asm_exp(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __exp(*parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_exp_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+static double (*__floor)(double) = &floor;
+__declspec ( naked ) void _asm_floor(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __floor(*parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_floor_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+static double (*__ceil)(double) = &ceil;
+__declspec ( naked ) void _asm_ceil(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __ceil(*parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_ceil_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+
+
+
+static double (SHITCALL *__getosc)(double *,double *,double *) = &getosc_;
+__declspec ( naked ) void _asm_getosc(void)
+{
+ FUNC3_ENTER
+
+ *__nextBlock = __getosc(parm_c,parm_b,parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_getosc_end(void) {}
+
+
+static double (SHITCALL *__getspec)(double *,double *,double *) = &getspec_;
+__declspec ( naked ) void _asm_getspec(void)
+{
+ FUNC3_ENTER
+
+ *__nextBlock = __getspec(parm_c,parm_b,parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_getspec_end(void) {}
+
+static double (SHITCALL *__gettime)(double *) = &gettime_;
+__declspec ( naked ) void _asm_gettime(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __gettime(parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_gettime_end(void) {}
+
+// do nothing, eh
+__declspec ( naked ) void _asm_exec2(void)
+{
+}
+__declspec ( naked ) void _asm_exec2_end(void) { }
+
+
+static double (SHITCALL *__getmouse)(double *) = &getmouse_;
+__declspec ( naked ) void _asm_getmouse(void)
+{
+ FUNC1_ENTER
+
+ *__nextBlock = __getmouse(parm_a);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_getmouse_end(void) {}
+
+
+static double (SHITCALL *__setmousepos)(double *,double *) = &setmousepos_;
+__declspec ( naked ) void _asm_setmousepos(void)
+{
+ FUNC2_ENTER
+
+ *__nextBlock = __setmousepos(parm_a,parm_b);
+
+ FUNC_LEAVE
+}
+__declspec ( naked ) void _asm_setmousepos_end(void) {}
+
+
+
+__declspec ( naked ) void _asm_invsqrt(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+
+ mov edx, 0x5f3759df
+ fst dword ptr [esi]
+ // floating point stack has input, as does [eax]
+ fmul dword ptr [negativezeropointfive]
+ mov ecx, [esi]
+ sar ecx, 1
+ sub edx, ecx
+ mov [esi], edx
+
+ // st(0) = input, [eax] has x
+ fmul dword ptr [esi]
+
+ fmul dword ptr [esi]
+
+ fadd dword ptr [onepointfive]
+
+ fmul dword ptr [esi]
+ mov eax, esi
+
+ fstp qword ptr [esi]
+
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_invsqrt_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_sin(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fsin
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_sin_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_cos(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fcos
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_cos_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_tan(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fsincos
+ fdiv
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_tan_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_sqr(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fmul st(0), st(0)
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_sqr_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_sqrt(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fabs
+ fsqrt
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_sqrt_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_log(void)
+{
+ __asm
+ {
+ fld1
+ fldl2e
+ fdiv
+ fld qword ptr [eax]
+ mov eax, esi
+ fyl2x
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_log_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_log10(void)
+{
+ __asm
+ {
+ fld1
+ fldl2t
+ fdiv
+ fld qword ptr [eax]
+ mov eax, esi
+ fyl2x
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_log10_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_abs(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fabs
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_abs_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_assign(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fstp qword ptr [ebx]
+ }
+}
+__declspec ( naked ) void _asm_assign_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_add(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fadd qword ptr [ebx]
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_add_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_sub(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+ fsub qword ptr [eax]
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_sub_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_mul(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+ fmul qword ptr [eax]
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_mul_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_div(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+ fdiv qword ptr [eax]
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_div_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_mod(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+
+ fld qword ptr [eax]
+ fsub dword ptr [g_cmpaddtab+4]
+ fabs
+ fadd qword ptr [eax]
+ fadd dword ptr [g_cmpaddtab+4]
+
+ fmul dword ptr [g_half]
+
+ fistp dword ptr [esi]
+ fistp dword ptr [esi+4]
+ mov eax, [esi+4]
+ xor edx, edx
+ div dword ptr [esi]
+ mov [esi], edx
+ fild dword ptr [esi]
+ mov eax, esi
+ fstp qword ptr [esi]
+ add esi, 8
+
+ }
+}
+__declspec ( naked ) void _asm_mod_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_or(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+ fld qword ptr [eax]
+ fistp qword ptr [esi]
+ fistp qword ptr [esi+8]
+ mov ebx, [esi+8]
+ or [esi], ebx
+ mov ebx, [esi+12]
+ or [esi+4], ebx
+ fild qword ptr [esi]
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_or_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_and(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+ fld qword ptr [eax]
+
+ fistp qword ptr [esi]
+ fistp qword ptr [esi+8]
+ mov ebx, [esi+8]
+ and [esi], ebx
+ mov ebx, [esi+12]
+ and [esi+4], ebx
+ fild qword ptr [esi]
+ fstp qword ptr [esi]
+
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_and_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_uplus(void) // this is the same as doing nothing, it seems
+{
+#if 0
+ __asm
+ {
+ mov ebx, nextBlock
+ mov ecx, [eax]
+ mov [ebx], ecx
+ mov ecx, [eax+4]
+ mov [ebx+4], ecx
+ mov eax, ebx
+ add ebx, 8
+ mov nextBlock, ebx
+ }
+#endif
+}
+__declspec ( naked ) void _asm_uplus_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_uminus(void)
+{
+ __asm
+ {
+ mov ecx, [eax]
+ mov ebx, [eax+4]
+ xor ebx, 0x80000000
+ mov [esi], ecx
+ mov [esi+4], ebx
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_uminus_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_sign(void)
+{
+ __asm
+ {
+ mov ecx, [eax+4]
+
+ shr ecx, 31
+
+ fld dword ptr [g_signs+ecx*4]
+
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_sign_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_bnot(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fabs
+ fcomp qword ptr [g_closefact]
+ fstsw ax
+ shr eax, 6
+ and eax, (1<<2)
+ fld dword ptr [g_cmpaddtab+eax]
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_bnot_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_if(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fabs
+ fcomp qword ptr [g_closefact]
+ fstsw ax
+
+ shr eax, 6
+
+ mov dword ptr [esi], 0FFFFFFFFh
+ mov dword ptr [esi+4], 0FFFFFFFFh
+
+ and eax, (1<<2)
+
+ mov eax, [esi+eax]
+
+ call eax // call the proper function
+
+ // at this point, the return value will be in eax, as desired
+ }
+}
+__declspec ( naked ) void _asm_if_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_equal(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fsub qword ptr [ebx]
+ fabs
+ fcomp qword ptr [g_closefact]
+ fstsw ax
+ shr eax, 6
+ and eax, (1<<2)
+ fld dword ptr [g_cmpaddtab+eax]
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_equal_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_below(void)
+{
+ __asm
+ {
+ fld qword ptr [ebx]
+ fcomp qword ptr [eax]
+ fstsw ax
+ shr eax, 6
+ and eax, (1<<2)
+ fld dword ptr [g_cmpaddtab+eax]
+
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_below_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec ( naked ) void _asm_above(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fcomp qword ptr [ebx]
+ fstsw ax
+ shr eax, 6
+ and eax, (1<<2)
+ fld dword ptr [g_cmpaddtab+eax]
+
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_above_end(void) {}
+
+
+__declspec ( naked ) void _asm_min(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fld qword ptr [ebx]
+ fld st(1)
+ fsub st(0), st(1)
+ fabs // stack contains fabs(1-2),1,2
+ fchs
+ fadd
+ fadd
+ fmul dword ptr [g_half]
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_min_end(void) {}
+
+__declspec ( naked ) void _asm_max(void)
+{
+ __asm
+ {
+ fld qword ptr [eax]
+ fld qword ptr [ebx]
+ fld st(1)
+ fsub st(0), st(1)
+ fabs // stack contains fabs(1-2),1,2
+ fadd
+ fadd
+ fmul dword ptr [g_half]
+ fstp qword ptr [esi]
+ mov eax, esi
+ add esi, 8
+ }
+}
+__declspec ( naked ) void _asm_max_end(void) {}
+
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/eval.c b/Src/Plugins/Visualization/vis_avs/evallib/eval.c
new file mode 100644
index 00000000..44e45881
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/eval.c
@@ -0,0 +1,238 @@
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <math.h>
+#include "cal_tab.h"
+#include "compiler.h"
+#include "eval.h"
+
+#define INTCONST 1
+#define DBLCONST 2
+#define HEXCONST 3
+#define VARIABLE 4
+#define OTHER 5
+
+int yyparse(char *exp);
+void llinit(void);
+int gettoken(char *lltb, int lltbsiz);
+char yytext[256]="";
+char lastVar[256]="";
+int *errPtr;
+int result;
+int colCount=0;
+
+varType *varTable;
+
+char last_error_string[1024];
+double globalregs[100];
+
+//------------------------------------------------------------------------------
+void *compileExpression(char *exp)
+{
+ int errv=0;
+ errPtr=&errv;
+ llinit();
+ if (!yyparse(exp) && !*errPtr)
+ {
+ return (void*)result;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void setLastVar(void)
+{
+ gettoken(lastVar, sizeof lastVar);
+}
+
+//------------------------------------------------------------------------------
+int setVar(int varNum, double value)
+{
+ int i=varNum;
+ if (varNum < 0)
+ {
+ char *var=lastVar;
+ if (!_strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
+ {
+ int x=atoi(var+3);
+ if (x < 0 || x > 99) x=0;
+ i=EVAL_MAX_VARS+x;
+ }
+ else
+ {
+ for (i=0;i<EVAL_MAX_VARS;i++)
+ {
+ if (!varTable[i].name[0] || !_strnicmp(varTable[i].name,lastVar,sizeof(varTable[i].name)))
+ break;
+ }
+ if (i==EVAL_MAX_VARS) return -1;
+ }
+ }
+
+ if (i < 0 || i >= EVAL_MAX_VARS+100)
+ {
+ return -1;
+ }
+
+ if (i >= EVAL_MAX_VARS && i < EVAL_MAX_VARS+100)
+ {
+ globalregs[i - EVAL_MAX_VARS]=value;
+ }
+ else if (!varTable[i].name[0])
+ {
+ strncpy(varTable[i].name,lastVar,sizeof(varTable[i].name));
+ varTable[i].value = value;
+ }
+
+ return i;
+}
+
+//------------------------------------------------------------------------------
+int getVar(int varNum)
+{
+ if (varNum >= EVAL_MAX_VARS && varNum < EVAL_MAX_VARS+100)
+ return createCompiledValue(0, globalregs + (varNum - EVAL_MAX_VARS));
+
+ if (varNum >= 0 && varNum < EVAL_MAX_VARS)
+ return createCompiledValue(0, &(varTable[varNum].value));
+
+ return createCompiledValue(0, NULL);
+}
+
+#if 0
+//------------------------------------------------------------------------------
+double *getVarPtr(char *var)
+{
+ int i;
+
+ if (!_strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
+ {
+ int x=atoi(var+3);
+ if (x < 0 || x > 99) x=0;
+ return globalregs + x;
+ }
+
+ for (i=0;i<EVAL_MAX_VARS;i++)
+ if (!_strnicmp(varTable[i].name, yytext,sizeof(varTable[i].name)))
+ return &(varTable[i].value);
+ return NULL;
+}
+#endif
+
+//------------------------------------------------------------------------------
+double *registerVar(char *var)
+{
+ int i;
+ if (!_strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
+ {
+ int x=atoi(var+3);
+ if (x < 0 || x > 99) x=0;
+ return globalregs + x;
+ }
+
+ for (i=0;i<EVAL_MAX_VARS;i++)
+ if (!varTable[i].name[0] ||
+ !_strnicmp(varTable[i].name,var,sizeof(varTable[i].name)))
+ break;
+ if (i==EVAL_MAX_VARS) return NULL;
+
+ if (!varTable[i].name[0])
+ {
+ strncpy(varTable[i].name,var,sizeof(varTable[i].name));
+ varTable[i].value = 0.0;
+ }
+ return &(varTable[i].value);
+}
+
+//------------------------------------------------------------------------------
+int translate(int type)
+{
+ int v;
+ int n;
+ *yytext = 0;
+ gettoken(yytext, sizeof yytext);
+
+ switch (type)
+ {
+ case INTCONST: return createCompiledValue((double)atoi(yytext), NULL);
+ case DBLCONST: return createCompiledValue((double)atof(yytext), NULL);
+ case HEXCONST:
+ v=0;
+ n=0;
+ while (1)
+ {
+ int a=yytext[n++];
+ if (a >= '0' && a <= '9') v+=a-'0';
+ else if (a >= 'A' && a <= 'F') v+=10+a-'A';
+ else if (a >= 'a' && a <= 'f') v+=10+a-'a';
+ else break;
+ v<<=4;
+ }
+ return createCompiledValue((double)v, NULL);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+int objectId(int nParams)
+{
+ switch (nParams)
+ {
+ case 1: return FUNCTION1;
+ case 2: return FUNCTION2;
+ case 3: return FUNCTION3;
+ }
+ return IDENTIFIER;
+}
+
+//------------------------------------------------------------------------------
+int lookup(int *typeOfObject)
+{
+ int i;
+ gettoken(yytext, sizeof yytext);
+
+ if (!_strnicmp(yytext,"reg",3) && strlen(yytext) == 5 && isdigit(yytext[3]) && isdigit(yytext[4]) && (i=atoi(yytext+3))>=0 && i<100)
+ {
+ *typeOfObject=IDENTIFIER;
+ return i+EVAL_MAX_VARS;
+ }
+
+ for (i=0;i<EVAL_MAX_VARS;i++)
+ if (!_strnicmp(varTable[i].name, yytext,sizeof(varTable[i].name)))
+ {
+ *typeOfObject = IDENTIFIER;
+ return i;
+ }
+
+ for (i=0;getFunctionFromTable(i);i++)
+ {
+ functionType *f=getFunctionFromTable(i);
+ if (!strcmpi(f->name, yytext))
+ {
+ *typeOfObject = objectId(f->nParams);
+ return i;
+ }
+ }
+ *typeOfObject = IDENTIFIER;
+ setLastVar();
+ i = setVar(-1, 0);
+ return i;
+}
+
+
+
+//---------------------------------------------------------------------------
+void count(void)
+{
+ gettoken(yytext, sizeof yytext);
+ colCount+=strlen(yytext);
+}
+
+//---------------------------------------------------------------------------
+int yyerror(char *txt)
+{
+ *errPtr = colCount;
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/eval.h b/Src/Plugins/Visualization/vis_avs/evallib/eval.h
new file mode 100644
index 00000000..cf42fd08
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/eval.h
@@ -0,0 +1,41 @@
+#ifndef __EVAL_H
+#define __EVAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ // stuff that apps will want to use
+#define EVAL_MAX_VARS 256
+typedef struct
+{
+ char name[8];
+ double value;
+} varType;
+
+extern double globalregs[100];
+extern char last_error_string[1024];
+
+void resetVars(varType *vars);
+double *getVarPtr(char *varName);
+double *registerVar(char *varName);
+
+
+// other shat
+
+extern varType *varTable;
+extern int *errPtr;
+extern int colCount;
+extern int result;
+
+int setVar(int varNum, double value);
+int getVar(int varNum);
+void *compileExpression(char *txt);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/makel.bat b/Src/Plugins/Visualization/vis_avs/evallib/makel.bat
new file mode 100644
index 00000000..63ee3079
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/makel.bat
@@ -0,0 +1 @@
+lex -i scan.l
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/makey.bat b/Src/Plugins/Visualization/vis_avs/evallib/makey.bat
new file mode 100644
index 00000000..3cf40833
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/makey.bat
@@ -0,0 +1,2 @@
+bison -d cal.y
+
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/new_eval_stuff.zip b/Src/Plugins/Visualization/vis_avs/evallib/new_eval_stuff.zip
new file mode 100644
index 00000000..70f3b441
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/new_eval_stuff.zip
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/evallib/readme.txt b/Src/Plugins/Visualization/vis_avs/evallib/readme.txt
new file mode 100644
index 00000000..f13fb8ee
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/evallib/readme.txt
@@ -0,0 +1,84 @@
+
+ Expression evaluation library v1.0 - by lone
+ --------------------------------------------
+
+
+ How to use
+ ~~~~~~~~~~
+
+
+ ¦ resetVars
+ -----------
+
+ void resetVars(void);
+
+ Resets the variables table. It is necessary to call it prior to evaluate your first
+ expression or variables contents may be random instead of zero
+
+
+ ¦ evaluate
+ ----------
+
+ double evaluate(char *expression, int *col);
+
+ Evaluates an expression and returns the result.
+ If a syntax error was encountered during the parsing of the expression, then col will
+ be non-null and col-1 will be the index of the char which triggered the error.
+
+
+ Limitations
+ ~~~~~~~~~~~
+
+ ¦ you can set only up to 1024 variables.
+ ¦ only decimal and hexadecimal bases available
+ ¦ operators are limited to :
+ + - / * % & |
+ ¦ functions are limited to :
+ sin, cos, tan,
+ asin, acos, atan,
+ atan2, sqr, sqrt,
+ pow, exp, log, log10
+
+
+ Some examples
+ ~~~~~~~~~~~~~
+
+ - assignments :
+
+ pi=3.1415927
+ a=atan2(cos(pi/4),2)
+
+ - direct evaluations :
+
+ cos(pi/4)
+ sin(45)
+
+ - base notations :
+
+ 3bh (this is 0x3B)
+ 17d (this is 17)
+ 17dh (this is 0x17D)
+
+
+ Adding new functions
+ ~~~~~~~~~~~~~~~~~~~~
+
+ The file EVAL.C contains the functions table (fnTable). Just add an entry with the name,
+ the number of parameters, and a pointer to the function body. Implement the body and
+ you're done. If your function ahs more than 2 parameters, you'll need to extend the grammar
+ description file (CAL.Y) to add the FUNCTION3 (and eventually subsequent) token(s) and
+ parsing informations.
+
+ SCAN.L & CAL.Y
+ ~~~~~~~~~~~~~~
+
+ SCAN.L contains description for the lexical analyzer generator (LEX). Use makel.bat to rebuild
+ LEXTAB.C
+ CAL.Y contains the LALR formal grammar description for the parser generator (BISON). Use makey.bat
+ to rebuild CAL_TAB.C
+
+
+ Compiling
+ ~~~~~~~~~
+
+ Just include all source files to your project, and include EVAL.H into your main source code.
diff --git a/Src/Plugins/Visualization/vis_avs/ff_ipc.h b/Src/Plugins/Visualization/vis_avs/ff_ipc.h
new file mode 100644
index 00000000..9fe335d0
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/ff_ipc.h
@@ -0,0 +1,104 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _FF_IPC_H
+#define _FF_IPC_H
+
+// -----------------------------------------------------------------------------------------------------
+// ----- IPC_FF_GETSKINCOLOR : Ask for a skin color -- the color is filtered for the current theme -----
+// -----------------------------------------------------------------------------------------------------
+
+#define IPC_FF_GETSKINCOLOR IPC_FF_FIRST + 1 // data = ff_skincolor struct with .colorname, fills in .color
+
+typedef struct {
+ char colorname[256];
+ COLORREF color;
+} ff_skincolor;
+
+// List of default colors as of june 30, 2003. see freeform/xml/wasabi/xml/system-colors.xml for latest/complete list
+
+// Trees
+ #define SKINCOLOR_TREE_ITEMTEXT "wasabi.tree.text"
+ #define SKINCOLOR_TREE_SELITEMBKG "wasabi.tree.selected"
+ #define SKINCOLOR_TREE_HILITEDROP "wasabi.tree.hiliteddrop"
+
+// Lists
+ #define SKINCOLOR_LIST_ITEMTEXT "wasabi.list.text"
+ #define SKINCOLOR_LIST_SELITEMBKG "wasabi.list.item.selected"
+ #define SKINCOLOR_LIST_FOCUSITEMBKG "wasabi.list.item.focused"
+ #define SKINCOLOR_LIST_COLUMNBKG "wasabi.list.column.background"
+ #define SKINCOLOR_LIST_COLUMNTEXT "wasabi.list.column.text"
+ #define SKINCOLOR_LIST_SELITEMTEXT "wasabi.list.item.selected.fg"
+ #define SKINCOLOR_LIST_COLUMNSEPARATOR "wasabi.list.column.separator"
+
+// Buttons
+ #define SKINCOLOR_BUTTON_TEXT "wasabi.button.text"
+ #define SKINCOLOR_BUTTON_HILITETEXT "wasabi.button.hiliteText"
+ #define SKINCOLOR_BUTTON_DIMMEDTEXT "wasabi.button.dimmedText"
+
+
+// ----------------------------------------------------------------------------------------
+// ----- IPC_FF_GENSKINBITMAP: Ask gen_ff to create a bitmap of various skin elements -----
+// ----------------------------------------------------------------------------------------
+
+// NOTE: You should free the hbitmap eventually using DeleteObject
+
+#define IPC_FF_GENSKINBITMAP IPC_FF_FIRST + 2 // data = ff_skinbitmap with bitmap .id .w .h and .state, fills in .bitmap
+
+typedef struct {
+ int id; // see below
+ int w, h;
+ int state; // id specific, see below
+ HBITMAP bitmap;
+} ff_skinbitmap;
+
+// Bitmap IDs :
+
+#define SKINBITMAP_BUTTON 0 // Generate a button bitmap. states are as follows :
+
+ #define BUTTONSTATE_NORMAL 0
+ #define BUTTONSTATE_PUSHED 1
+
+#define SKINBITMAP_SCROLLBARUPBUTTON 1 // Generate a scrollbar up button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARDOWNBUTTON 2 // Generate a scrollbar down button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARLEFTBUTTON 3 // Generate a scrollbar left button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARRIGHTBUTTON 4 // Generate a scrollbar right button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARVBUTTON 5 // Generate a scrollbar vertical button bitmap. states are button states
+#define SKINBITMAP_SCROLLBARHBUTTON 6 // Generate a scrollbar vertical button bitmap. states are button states
+
+// -----------------------------------------------------------------------------------------------
+// ----- IPC_FF_ONCOLORTHEMECHANGED: CALLBACK - sent when the skin's color theme has changed -----
+// -----------------------------------------------------------------------------------------------
+
+#define IPC_FF_ONCOLORTHEMECHANGED IPC_FF_FIRST + 3 // data = name of the new color theme (const char *)
+#define IPC_FF_ISMAINWND IPC_FF_FIRST + 4 // data = hwnd, returns 1 if hwnd is main window or any of its windowshade
+#define IPC_FF_GETCONTENTWND IPC_FF_FIRST + 5 // data = HWND, returns the wa2 window that is embedded in the window's container (ie if hwnd is the pledit windowshade hwnd, it returns the wa2 pledit hwnd). if no content is found (ie, the window has nothing embedded) it returns the parameter you gave it
+#define IPC_FF_NOTIFYHOTKEY IPC_FF_FIRST + 6 // data = const char * to hotkey description
+
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/help_1.bin b/Src/Plugins/Visualization/vis_avs/help_1.bin
new file mode 100644
index 00000000..f69742a2
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/help_1.bin
@@ -0,0 +1,32 @@
+Many AVS effects allow you to write simple expressions to control
+visualization. Here is a brief summary of how to write AVS code.
+
+Many aspects of AVS code are similar to C (including comments).
+
+You can create new variables just by using them, and you can read
+and write predefined variables (of which each effect has its own)
+to interact with the effect. Note that variables are all floating
+point numbers (no strings), and the maximum length of a variable's
+name is 8 characters (anything longer will be ignored.
+
+So, to create a variable, you can simply use it, for example:
+ x = 5;
+
+You can also use a variety of operators and math functions to
+modify variables, see the Operators and Functions tabs above.
+
+Code can include C and C++ style comments:
+ // using the doubleslash comments until the end of the line
+ /* using the classic C comments
+ comment a block of text */
+
+You can combine operators and functions into expressions, such
+as:
+ x = 5 * cos(y) / 32.0; // this does some leetness right here
+
+You can use multiple expressions by seperating them with one or
+more semicolons, for example:
+ x = x * 17.0; x = x / 5; y = pow(x,3.0);
+
+It is worth noting that extra whitespace (spaces, newlines) is
+ignored, so if you need to space things out for clarity, you can. \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/help_2.bin b/Src/Plugins/Visualization/vis_avs/help_2.bin
new file mode 100644
index 00000000..307b2693
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/help_2.bin
@@ -0,0 +1,32 @@
+The following operators are available:
+=
+ assigns a value to a variable.
+ example: var=5;
+
++
+ adds two values, returns the sum.
+ example: var=5+var2;
+
+-
+ subtracts two values, returns the difference.
+ example: var=5-var2;
+
+*
+ multiplies two values, returns the product.
+ example: var=5*var2;
+
+/
+ divides two values, returns the quotient.
+ example: var=5/var2;
+
+%
+ converts two values to integer, performs division, returns remainder
+ example: var=var2%5;
+
+|
+ converts two values to integer, returns bitwise OR of both values
+ example: var=var2|31;
+
+&
+ converts two values to integer, returns bitwise AND of both values
+ example: var=var2&31; \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/help_3.bin b/Src/Plugins/Visualization/vis_avs/help_3.bin
new file mode 100644
index 00000000..a936f31a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/help_3.bin
@@ -0,0 +1,133 @@
+Functions available from code:
+abs(value)
+ = returns the absolute value of 'value'
+
+sin(value)
+ = returns the sine of the radian angle 'value'
+
+cos(value)
+ = returns the cosine of the radian angle 'value'
+
+tan(value)
+ = returns the tangent of the radian angle 'value'
+
+asin(value)
+ = returns the arcsine (in radians) of 'value'
+
+acos(value)
+ = returns the arccosine (in radians) of 'value'
+
+atan(value)
+ = returns the arctangent (in radians) of 'value'
+
+atan2(value,value2)
+ = returns the arctangent (in radians) of 'value'/'value2'
+
+sqr(value)
+ = returns the square of 'value'
+
+sqrt(value)
+ = returns the square root of 'value'
+
+invsqrt(value)
+ = returns the reciprocal of the square root of 'value' (1/sqrt(value))
+ (uses a fast approximation, may not always = 1/sqrt(value) :)
+
+pow(value,value2)
+ = returns 'value' to the power of 'value2'
+
+exp(value)
+ = returns e to the power of 'value'
+
+log(value)
+ = returns the log in base e of 'value'
+
+log10(value)
+ = returns the log in base 10 of 'value'
+
+floor(value)
+ = returns the largest integer less than or equal to 'value'
+
+ceil(value)
+ = returns the smallest integer greater than or equal to 'value'
+
+ "sign(value)
+ = returns the sign of 'value' (-1.0 or 1.0, or 0.0 or -0.0 for 0.0 or -0.0)
+
+ "min(value,value2)
+ = returns the smallest of 'value' and 'value2'
+
+ "max(var,var2)
+ = returns the greatest of 'value' and 'value2'
+
+ "sigmoid(value,value2)
+ = returns sigmoid function value of x='value' ('value2'=constraint)
+
+ "rand(value)
+ = returns a random integer between 0 and 'value'
+
+ "band(value,value2)
+ = returns a boolean AND of 'value' and 'value2'
+
+ "bor(value,value2)
+ = returns a boolean OR of 'value' and 'value2'
+
+ "bnot(value)
+ = returns a boolean NOT of 'value'
+
+ "if(condition,valtrue,valfalse)
+ = returns 'valtrue' if 'condition' is nonzero, returns 'valfalse' otherwise.
+ new in AVS 2.8+: only one of valtrue/valfalse is evaluated, depending on condition
+
+ "assign(dest, source)
+ = if 'dest' is a variable, assigns the value of 'source' to it. returns the value of 'source'.
+ a little trick: assign(if(v,a,b),1.0); is like if V is true, a=1.0, otherwise b=1.0. :)
+
+ "exec2(parm1, parm2)
+ = evaluates parm1, then parm2, and returns the value of parm2.
+
+ "equal(value,value2)
+ = returns 1.0 if 'value' is equal to 'value2', otherwise returns 0.0
+
+ "above(value,value2)
+ = returns 1.0 if 'value' is greater than 'value2', otherwise returns 0.0
+
+ "below(value,value2)
+ = returns 1.0 if 'value' is less than 'value2', otherwise returns 0.0
+
+ "getosc(band,width,channel)
+ = returns waveform data centered at 'band', (0..1), sampled 'width' (0..1) wide.
+ 'channel' can be: 0=center, 1=left, 2=right. return value is (-1..1)
+
+ "getspec(band,width,channel)
+ = returns spectrum data centered at 'band', (0..1), sampled 'width' (0..1) wide.
+ 'channel' can be: 0=center, 1=left, 2=right. return value is (0..1)
+
+gettime(start_time)
+ = returns time in seconds since start_time (start_time can be 0 for time since boot)
+ (start_time can be -1.0 for current play time in seconds
+ (start_time can be -2.0 for current play length in seconds
+
+getkbmouse(which_parm)
+ = returns information about the location and state of the keyboard or mouse
+ which_parm = 1: mouse X position (-1..1 is onscreen)
+ which_parm = 2: mouse Y position (-1..1 is onscreen)
+ which_parm = 3: mouse left button state (0 up, 1 down)
+ which_parm = 4: mouse right button state (0 up, 1 down)
+ which_parm = 5: mouse middle button state (0 up, 1 down)
+ which_parm > 5: (GetAsyncKeyState(which_parm)&0x8000)?1:0
+
+megabuf(index)
+ = can be used to get or set an item from the 1 million item temp buffer
+ to get, use: val=megabuf(index);
+ to set, use: assign(megabuf(index),val);
+
+gmegabuf(index)
+ = can be used to get or set an item from the global 1 million item buffer
+ to get, use: val=gmegabuf(index);
+ to set, use: assign(gmegabuf(index),val);
+
+loop(count, statement)
+ = executes <statement> <count> times. count is evaluated once and clamped
+ to 0..4096. best used with exec2() and exec3() and assign(). Note that
+ the return value of loop() is undefined and should not be used. \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/help_4.bin b/Src/Plugins/Visualization/vis_avs/help_4.bin
new file mode 100644
index 00000000..1f5888bf
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/help_4.bin
@@ -0,0 +1,6 @@
+Constants
+ '$PI' can be used in place of '3.14159'
+ '$E' can be used in place of '2.71828'
+ '$PHI' can be used in place of '1.618033'
+ Numbers can be specified as integers or as floating point
+ (i.e. '5' or '5.0' or '5.00001') \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/LD32.H b/Src/Plugins/Visualization/vis_avs/laser/LD32.H
new file mode 100644
index 00000000..b9a55cea
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/LD32.H
@@ -0,0 +1,964 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#define LDDLL_PREFIX
+/*************************************************************************
+* Helpful Stuff *
+**************************************************************************/
+
+/*
+This header file defines a prefix. This is used by C++ programs to append a prefix to the definitions.
+For C programs that use the LD2000.H file and associated library, use the following
+ #define LDDLL_PREFIX //Define the prefix in LD2000.H file as nothing
+ #include "ld2000.h"
+For C++ programs, use the following
+ #define LDDLL_PREFIX extern "C" //Define the prefix in LD2000.H file as extern "C" to indicate that the names in the lib file have not been mangled
+ #include "ld2000.h"
+*/
+
+/*************************************************************************
+* Error Codes *
+**************************************************************************/
+
+#define LDERR_OK 0 //Normal Return value
+
+//********** These can occur at any time except InitialQMCheck ****
+#define LDERR_FIFO_READ_ERROR -1 //Fifo read zero or non even number of bytes
+#define LDERR_QM32_SOFTWARE_ERROR -2 //QM32 is not responding properly
+
+
+//********** These are reported by the loaders including LoadPalette
+#define LDERR_X29_LOADED -11 //File load Successful Return
+#define LDERR_LDA_LOADED -12 //values
+#define LDERR_ILDA_LOADED -13
+#define LDERR_DEC3_LOADED -14
+#define LDERR_LDB_LOADED -15
+#define LDERR_LDSECURE_LOADED -16
+
+
+//********* Returned by ConvertToPointFrame **************
+#define LDERR_ALREADY_POINT_ORIENTED -31 //Incase somebody tries to
+ //create a point oriented frame
+ //from a point oriented frame
+
+//******** Currently only returned by CheckSession **************
+#define LDERR_NO_SESSION_IN_PROG -101 //CheckSession return value
+
+//******** Returned by LFileRequest and LPaletteRequest *********
+#define LDERR_FILE_REQUEST_CANCEL -201 //File Requestor Cancelled
+
+//********* Returned by file functions **************************
+#define LDERR_FILE_NOT_FOUND -401 //Loader errors
+#define LDERR_WRONG_FILE_TYPE -402
+#define LDERR_DISK_FULL -403
+#define LDERR_DISK_WRITE_PROTECTED -404
+#define LDERR_FILE_WRITE_PROTECTED -405
+#define LDERR_MISC_FILE_ERROR -406
+#define LDERR_STRING_TOO_LONG -407 //Supplied filename is over 128 chars in length
+
+//*********** Returned by frame commands such as DisplayFrame ***
+#define LDERR_FRAME_OUT_OF_RANGE -501 //Misc programming or config errors
+
+//*********** Returned by point commands such as writepoint *****
+#define LDERR_POINT_OUT_OF_RANGE -502
+
+//*********** Returned by show control commands *****************
+#define LDERR_TDC_NOT_FOUND -511
+#define LDERR_TRANSITION_NOT_FOUND -512
+#define LDERR_EFFECT_NOT_FOUND -513
+#define LDERR_SCENE_NOT_FOUND -514
+#define LDERR_MODULE_NOT_FOUND -515
+#define LDERR_SHOW_NOT_FOUND -516
+#define LDERR_STRUCTURE_NOT_FOUND -519
+
+//Once the element has been deleted, this will be returned
+#define LDERR_EFFECT_DELETED -530
+#define LDERR_SCENE_DELETED -531
+#define LDERR_MODULE_DELETED -532
+#define LDERR_SHOW_DELETED -533
+#define LDERR_STRUCTURE_DELETED -539
+
+//If you try to delete something which is inuse one of these will be returned
+#define LDERR_EFFECT_INUSE -540
+#define LDERR_SCENE_INUSE -541
+#define LDERR_MODULE_INUSE -542
+#define LDERR_SHOW_INUSE -543
+#define LDERR_STRUCTURE_INUSE -549
+
+//*********** These should be rare indeed ***********************
+#define LDERR_NO_IBM_MEMORY -601 //No free IBM Memory
+#define LDERR_CANT_OPEN_WINDOW -602 //Can't open Window (Debug, FileRequest)
+
+//*********** Alot of commands can return this one **************
+#define LDERR_NO_QM32_MEMORY -702 //No free QM32 Memory
+
+//*********** Ran out of memory while trying to load a file *****
+#define LDERR_FILE_TOO_LARGE -703 //No free QM32 Memory to load frames
+
+//********** Several unimplemented DLL commands return this *****
+#define LDERR_NOT_IMPLEMENTED -801 //DLL Command not implemented
+
+//*** This indicates a timeout during a long communication with the QM32
+//*** This only occurs during file loading and saving and ActiveArray functions
+#define LDERR_QM32_ERROR -901 //QM32 Communication error
+
+//***** These should only be returned by InitialQMCheck *********
+#define LDERR_QM32_NOT_PRESENT -1001 //QM32 is not present (like it sounds)
+#define LDERR_QM32_ADDRESS_CONFLICT -1002 //QM32 is not responding properly
+#define LDERR_QM32_INITIALIZATION_ERROR -1003 //Same as above, but even weirder
+
+/*************************************************************************
+* QM32 Error Codes *
+**************************************************************************/
+
+//*** This is a sure sign of QM32 hardware trouble
+#define QM32ERROR_NullCommand 1
+
+//*** Usually because of no laser code running in the QM32 but could
+//*** be caused by a DLL / Q32 mismatch.
+#define QM32ERROR_UndefinedCommand 2
+
+//*** Should only occur during BeginSession. This indicates that a
+//*** communications error has occured while loading the file LD.Q32
+#define QM32ERROR_DownloadBad 3
+#define QM32ERROR_ChecksumBad 4
+
+//*** This is usually caused by a DLL / Q32 mismatch. If it happens
+//*** inconsistantly then this could be a sign of QM32 hardware trouble
+#define QM32ERROR_Insufficient 5
+
+//*** When the QM32 is reset it does 3 ram tests. If one of them fails, this
+//*** would be returned. This is a sign of QM32 hardware trouble.
+#define QM32ERROR_DramTestBad 6
+
+//*** If somebody tampers with the rom chip, this would be returned. Actually
+//*** nothing may be returned because the QM32 would probably lock up.
+#define QM32ERROR_RomTestBad 7
+
+//*** This is equivalent to the Amiga's GURU meditation. It occurs when some
+//*** kind of QM32 software violates the system. (divide by zero, access to memory that isn't there, etc.)
+//*** In certain circomstances, it may also be caused by a hardware problem.
+#define QM32ERROR_AccessError 8
+
+//***************************************************************************
+// Flags used by RedrawFrameFast and other things *
+//***************************************************************************
+
+#define RFF_NOBLIT 64 //RedrawFrameFast should not copy the bitmap to the screen
+#define RFF_NOINITMINMAX 128 //RedrawFrameFast should not init Min and Max variables to 0
+#define RFF_DOUBLEBUFFER 2048 //RedrawFrameFast should use double buffering
+#define RFF_WHITEDOT 8192 //RedrawFrame should place a white dot at the first point
+#define RFF_MONITORPZ 32768 //RedrawFrame should use the laser coordinates from the monitor buffer and not the laser coordinates
+#define RFF_GRAYBLANKING 65536 //Show blanking lines as gray lines
+#define RFF_SELECTEDZONES 131072 //Show only the selected zones, supplied in the Frame parameter of RedrawFrameFast
+
+//***************************************************************************
+// Flags used by DisplayUpdateEx and sometimes by PlayShowEx *
+//***************************************************************************
+
+#define DU_LASEROUTPUT 1 //DisplayUpdate should show laser output
+#define DU_BEGINSLEW 16 //DisplayUpdate should slew beginning blanked points leading up to the first track
+#define DU_CUTSCAN 256 //DisplayUpdate should immediately stop scanning buffer and start a new buffer
+
+
+/**************************************************************************
+* Structures *
+***************************************************************************/
+
+typedef struct tagDMXCHANNELMAP{
+ LONG Function;
+ SHORT SlewRate;
+ SHORT Mode;
+ LONG Reserved1;
+ LONG Reserved2;
+ LONG Reserved3;
+ LONG StartupSource;
+ LONG StartupValue;
+ LONG ShutdownSource;
+ LONG ShutdownValue;
+ LONG ESTOPSource;
+ LONG ESTOPValue;
+ LONG DeselectedSource;
+ LONG DeselectedValue;
+ LONG Source;
+ LONG Value;
+ LONG STMin;
+ LONG DMXMin;
+ LONG STMax;
+ LONG DMXMax;
+ LONG STOrigin;
+ LONG STExtent;
+ LONG DMXOrigin;
+ LONG DMXExtent;
+ LONG DMXExtentOV2;
+} DMXCHANNELMAP;
+
+typedef struct tagDMXMAP{
+ SHORT Reserved1;
+ SHORT NumChannels;
+ SHORT Reserved2;
+ SHORT StartingChannel;
+ SHORT Reserved3;
+ SHORT DeviceType;
+ SHORT Reserved4;
+ SHORT Nondisplayed;
+} DMXMAP;
+
+typedef struct tagPROJECTIONZONE{
+ LONG Scanner; //Scanner for output
+
+ LONG XSize; //Geometric Correction variable -- X Size
+ LONG YSize; //Geometric Correction variable -- Y Size
+ LONG XPosition; //Geometric Correction variable -- X Position
+ LONG YPosition; //Geometric Correction variable -- Y Position
+ LONG ZRotation; //Geometric Correction variable -- Z Rotation angle
+ LONG XLinearity; //Geometric Correction variable -- X Linearity
+ LONG YLinearity; //Geometric Correction variable -- Y Linearity
+ LONG XKeystone; //Geometric Correction variable -- X Keystone
+ LONG YKeystone; //Geometric Correction variable -- Y Keystone
+//10
+ LONG XPincussion; //Geometric Correction variable -- X Pin
+ LONG YPincussion; //Geometric Correction variable -- Y Pin
+ LONG XPincussionOffset; //Geometric Correction variable -- X Pin Offset
+ LONG YPincussionOffset; //Geometric Correction variable -- Y Pin Offset
+ LONG XBow; //Geometric Correction variable -- X Bow
+ LONG YBow; //Geometric Correction variable -- Y Bow
+ LONG XBowOffset; //Geometric Correction variable -- X Bow Offset
+ LONG YBowOffset; //Geometric Correction variable -- Y Bow Offset
+ LONG XShear; //Geometric Correction variable -- X Shear
+ LONG YShear; //Geometric Correction variable -- Y Shear
+//20
+ LONG XSymmetry; //Geometric Correction variable -- X Symmetry
+ LONG YSymmetry; //Geometric Correction variable -- Y Symmetry
+ LONG Reserved1; //Geometric Correction variable -- Reserved for future use
+ LONG Reserved2; //Geometric Correction variable -- Reserved for future use
+
+ LONG NoMinimumPointsFlag; //BOOL: Don't require minimum points during DisplayUpdate
+ LONG AllowManipulationsFlag; //BOOL: Allow Scale, Rotate, Position, Perspective and other effects.
+ LONG AllowMasterResizeFlag; //BOOL: Allow the master size and position controls to affect this projection zone
+ LONG UseGeometricCorrectionData; //BOOL: Observe geometric correction data when calculating beam position
+
+ LONG PreviewWindowXSize; //X Size of the image drawn on the preview window
+ LONG PreviewWindowYSize; //Y Size of the image drawn on the preview window
+//30
+ LONG PreviewWindowXPosition; //X Position of the image drawn on the preview window
+ LONG PreviewWindowYPosition; //Y Position of the image drawn on the preview window
+ LONG PreviewWindowXProjectorPosition; //X Position of the center of all of the beam lines
+ LONG PreviewWindowYProjectorPosition; //Y Position of the center of all of the beam lines
+
+ LONG PreviewWindowMirrorXOutput; //BOOL: Produce a duplicate output with mirrored X output
+ LONG PreviewWindowMirrorXProjector; //BOOL: Produce a duplicate output with mirrored X position
+ LONG PreviewWindowShowAsBeamsFlag; //BOOL: When drawing on the preview window, show this as beams
+
+ LONG ScannerOptimizer; //BOOL: Optimize blanking path within this projection zone
+
+ LONG UseProtectionData; //BOOL: Observe protection data when calculating brightness
+
+ LONG Reserved7; //Reserved for future use
+//40 long words = 160 bytes
+ LONG Reserved8; //Reserved for future use
+ LONG Reserved9;
+ LONG Reserved10;
+ LONG Reserved11;
+ LONG Reserved12;
+
+ char Name[24]; //40 byte name field
+
+ char Reserved200[200]; //200 reserved bytes
+
+ short GeometricCorrectionData[8450]; //65*65*2 integers for geometric correction
+
+ char ProtectionZoneData[4096]; //64*64=4096 bytes for protection zone bitmap
+} PROJECTIONZONE;
+
+
+
+typedef struct tagCOLORREGSTRUCT{
+ LONG ColorIndex;
+ LONG RedScreenVal;
+ LONG GreenScreenVal;
+ LONG BlueScreenVal;
+ LONG RedLaserVal;
+ LONG GreenLaserVal;
+ LONG BlueLaserVal;
+ LONG DeepBlueLaserVal;
+ LONG YellowLaserVal;
+ LONG FocusLaserVal;
+ LONG IntensityLaserVal;
+ LONG ShutterLaserVal;
+} COLORREGSTRUCT;
+
+typedef struct tagPTSTRUCT{
+ LONG XCoord;
+ LONG YCoord;
+ LONG ZCoord;
+ LONG FCoord;
+ LONG RGBValue;
+ LONG X3DCoord;
+ LONG Y3DCoord;
+ LONG Group;
+ LONG Status;
+} PTSTRUCT;
+
+typedef struct tagFRAMESTRUCT{
+ LONG VOFlag;
+ LONG ScanRateMultiplier;
+ LONG AbstractFlag;
+ LONG NumPoints;
+ char FrameNote[24];
+} FRAMESTRUCT;
+
+typedef struct tagFRAMESTRUCTEX{
+ LONG ChangedFlag; //Indicates that this frame has changed since the last time it was saved. This is read-only.
+ LONG ThreeDFlag; //Indicates that this frame is stored internally as 3D data. This is read-only.
+ LONG BeamBrushFlag; //Indicates that this frame stores beam brush points internally. This is read-only.
+ LONG VectorFlag; //Indicates that this frame is to be rendered using the vector renderer. This is read/write.
+ LONG AbstractFlag; //Indicates that this frame has additional abstract information and that this should be rendered as an abstract.
+ LONG DMXFlag; //Indicates that this frame has DMX data in addition to point and perhaps abstract data.
+ LONG RasterFlag; //Indicates that this frame is a raster frame. No special internal handling is done at this time.
+ LONG MaxRenderedFlag; //Indicates that this frame was rendered by 3D Studio MAX.
+ LONG SecureFrameFlag; //Indicates that this frame is secured.
+ LONG Reserved3; //Reserved for future use
+ LONG PreferredPalette; //Palette that this frame will use unless overridden by Track.
+ LONG PreferredProjectionZone; //Projection zone that this frame will be projected onto unless overridden by track.
+ LONG AnimationCount; //Number of frames to the end of the animation. Range is 0 to 65535.
+ LONG ClipartClass; //Number, usually bit-encoded, that describes the frame. This is only 16-bits internally.
+ LONG ScanRate; //Scan rate for this frame. If positive, handled as a multiplier. If negative, treated as exact sample rate in 1K increments.
+ LONG NumPoints; //Number of data points in this frame.
+ char FrameNote[24]; //23 character, plus null, frame note.
+} FRAMESTRUCTEX;
+
+
+//*************************************************************************
+//* Constants
+//*************************************************************************
+
+#define frontview 1
+#define topview 2
+#define sideview 3
+#define threeDview 4
+#define BLACK RGB(0,0,0)
+#define DARKGRAY RGB(128,128,128)
+#define LIGHTGRAY RGB(192,192,192)
+#define WHITE RGB(255, 255, 255)
+
+
+//**********************************************************************************
+// LD2000.DLL API Functions
+//**********************************************************************************
+
+
+//-------------------------------------------------------------------------------------------
+// LD Comm Window Functions
+//-------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI OpenLDCommWindow(void);
+LDDLL_PREFIX LONG WINAPI CloseLDCommWindow(void);
+LDDLL_PREFIX LONG WINAPI WriteToLDCommWindow(LPSTR SUPPLY_OutputString);
+LDDLL_PREFIX LONG WINAPI QM32BeepOnError(LONG OnOff); //Controls whether or not the Comm window automatically opens
+
+
+//--------------------------------------------------------------------------------------------
+// Port functions. Only used in the Interactive Character project.
+//--------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX unsigned short WINAPI ldInp(unsigned short PortID);
+
+LDDLL_PREFIX unsigned short WINAPI ldInpw(unsigned short PortID);
+
+LDDLL_PREFIX unsigned short WINAPI ldOutp(unsigned short PortID, short DataByte);
+
+LDDLL_PREFIX unsigned short WINAPI ldOutpw(unsigned short PortID, unsigned short DataWord);
+
+//--------------------------------------------------------------------------------------------
+// Status and setting and retrieval
+//--------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI GetLDStatus(LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI GetDates(LPLONG RETURN_DLLDate, LPLONG RETURN_LibDate, LPLONG RETURN_RomDate);
+
+LDDLL_PREFIX LONG WINAPI GetSerialNumber(LPLONG RETURN_SerialNumber);
+
+
+//------------------------------------------------------------------------------------------
+// QuadMod and session functions
+//------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI GetLDDLLModuleUsage(LPLONG ModuleUsage);
+
+LDDLL_PREFIX LONG WINAPI QM32AvailMemEx(LPLONG RETURN_TotalMemory, LPLONG RETURN_TotalFreeMemory, LPLONG RETURN_LargestBlock, LPLONG RETURN_NumFreeBlocks);
+LDDLL_PREFIX LONG WINAPI QM32DefragmentMem(LPLONG RETURN_NumBlocksCombined);
+LDDLL_PREFIX LONG WINAPI RebootQM32(void);
+LDDLL_PREFIX LONG WINAPI InitialQMCheck(LPLONG RETURN_LDStatus);
+LDDLL_PREFIX LONG WINAPI BeginSession(LONG MaxFrames, LONG MaxPoints, LONG MaxBuffer, LONG UndoFrames, LPLONG RETURN_LDStatus);
+LDDLL_PREFIX LONG WINAPI CheckSession(LPLONG RETURN_LDStatus);
+LDDLL_PREFIX LONG WINAPI CheckSessionSettings(LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus);
+LDDLL_PREFIX LONG WINAPI EndSession(void);
+
+LDDLL_PREFIX LONG WINAPI BeginSessionEx(LPLONG RETURN_Version, LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus);
+//Does everything necessary to start a session including checking settings and loading parameters from INI file including palette and geometric correction data
+
+
+//------------------------------------------------------------------------------------------
+// Working Scanners, Tracks, Frames
+//------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI SetWorkingScanners(LONG Scanner);
+LDDLL_PREFIX LONG WINAPI GetWorkingScanners(LONG *RETURN_ScannerSelection);
+
+LDDLL_PREFIX LONG WINAPI SetWorkingTracks(LONG Track);
+
+LDDLL_PREFIX LONG WINAPI SetWorkingFrame(LONG FrameNumber);
+LDDLL_PREFIX LONG WINAPI GetWorkingFrame(LPLONG RETURN_Frame);
+
+
+//-------------------------------------------------------------------------------------------
+// Projection Zone Functions
+//-------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI ReadProjectionZone(LONG ZoneNumber, PROJECTIONZONE *RETURN_PZ);
+
+LDDLL_PREFIX LONG WriteProjectionZone(LONG ZoneNumber, PROJECTIONZONE *SUPPLY_PZ);
+
+LDDLL_PREFIX LONG WINAPI LoadProjectionZones(LPSTR ZoneFilename, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI SaveProjectionZones(LPSTR ZoneFilename, LPLONG RETURN_LDStatus);
+
+
+//-----------------------------------------------------------------------------------------
+// Showtime Synchronization Functions
+//-----------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI QM32MultiCommand(LONG Allow);
+LDDLL_PREFIX LONG WINAPI SetSyncParameters(LONG Proportional, LONG Integral, LONG Derivative);
+LDDLL_PREFIX LONG WINAPI SendSync(LONG CurrentTime);
+LDDLL_PREFIX LONG WINAPI SendMultiSync(LONG CurrentTime);
+LDDLL_PREFIX LONG WINAPI GetShowTimeMilliseconds(LPLONG RETURN_CurrentTime);
+LDDLL_PREFIX LONG WINAPI GetQMEvents(LPLONG RETURN_nEvents, LPSTR RETURN_MIDIEventStruct);
+LDDLL_PREFIX LONG WINAPI SendSyncGetQMEvents(LONG CurrentTime, LPLONG RETURN_nEvents, LPSTR RETURN_MIDIEventStruct);
+
+
+//--------------------------------------------------------------------------------------------
+// Showtime operation functions
+//--------------------------------------------------------------------------------------------
+
+
+LDDLL_PREFIX LONG WINAPI SetResetTTL(LONG IOMask, LONG OutputData); //This may go away
+
+LDDLL_PREFIX LONG WINAPI PlayShowEx(LONG StartTime, LONG EndTime, LONG PlaySpeed, LONG Mode);
+
+LDDLL_PREFIX LONG WINAPI StopShow(void); //Correct way to stop a show in progress.
+
+
+LDDLL_PREFIX LONG WINAPI StopShowEx(LONG Mode); //Mode parameter allows you to skip the final refresh after PlayShow has ended.
+
+//--------------------------------------------------------------------------------------------
+// Showtime file functions
+//--------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI LoadShowStructures(LPSTR Filename, LONG StructureTypes, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI SaveShowStructures(LPSTR Filename, LONG StructureTypes, LPINT RETURN_LDStatus);
+
+
+//--------------------------------------------------------------------------------------------
+// Laser Display Functions
+//--------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI ResetLD(void); //Updates all track variables
+
+LONG WINAPI DisplayGeometricCorrection( long Enable, long YLine, short *GeometryData); //GeometryData must be in device coordinates
+
+LDDLL_PREFIX LONG WINAPI DisplaySize( float XSize, float YSize, float ZSize, float CSize, float FSize); // Normalized Variables
+
+LDDLL_PREFIX LONG WINAPI DisplayPosition( float XPosition, float YPosition ); // Normalized Variables
+
+LDDLL_PREFIX LONG WINAPI DisplayAuxOutput(float OutputVoltage);
+
+LDDLL_PREFIX LONG WINAPI lsDisplayAuxOutput(float OutputVoltage, float ZSize, float ZOffset);
+
+LDDLL_PREFIX LONG WINAPI DisplayMasterAngle(float XAngle, float YAngle, float ZAngle); //Normalized
+
+
+LDDLL_PREFIX LONG WINAPI DisplayFreq3(long PointFreq, long VectorFreq, long AbstractFreq, LPLONG RETURN_ActualPointFreq, LPLONG RETURN_ActualVectorFreq, LPLONG RETURN_ActualAbstractFreq);
+
+LDDLL_PREFIX LONG WINAPI DisplayScanLimits(LONG FromPt, LONG ToPt);
+
+LDDLL_PREFIX LONG WINAPI DisplayObjectSettings(LONG VisibleBeginEmph, LONG VisibleMiddleEmph,
+ LONG VisibleEndEmph, LONG VisibleDensity,
+ LONG BlankedBeginEmph, LONG BlankedEndEmph,
+ LONG BlankedDensity);
+
+LDDLL_PREFIX LONG WINAPI DisplayAbstractSettings(LONG NumVisible, LONG NumOverscan, LONG NumOverlap);
+
+LDDLL_PREFIX LONG WINAPI DisplayFlags(LONG Flags);
+
+LDDLL_PREFIX LONG WINAPI SetGetDisplayFlags(LONG Mode, LONG TrackNumber, LPLONG RETURN_Flags);
+
+LDDLL_PREFIX LONG WINAPI DisplayMaskFlags(LONG MaskFlags);
+
+LDDLL_PREFIX LONG WINAPI DisplayScale(float XScale, float YScale, float ZScale); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayRotCenter(float XRotCent, float YRotCent, float ZRotCent); // Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayAngle(float XAngle, float YAngle, float ZAngle); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayAngleDegrees(float XAngle, float YAngle, float ZAngle); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayRotOrder(LONG RotationOrder);
+
+LDDLL_PREFIX LONG WINAPI DisplayWAngle(float XAngle, float YAngle, float ZAngle); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayWAngleDegrees(float XAngle, float YAngle, float ZAngle); //Normalized
+
+LDDLL_PREFIX LONG WINAPI AutoRotateInit(float InitialXAngle, float InitialYAngle,
+ float InitialZAngle, LONG AnimateFromFrame,
+ LONG AnimateToFrame, long AutoRotateTrack);
+
+LDDLL_PREFIX LONG WINAPI AutoRotateIncrement(float XIncrement, float YIncrement, float ZIncrement, LONG TenthFlag);
+
+LDDLL_PREFIX LONG WINAPI AutoRotatePlus(LONG Rotate, LONG GenerateAbstract, LONG Animate, LONG Extra); //Pretty much unneccessary now
+
+LDDLL_PREFIX LONG WINAPI DisplayPostTrans(float XOffs, float YOffs, float ZOffs); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayStereoSettings(float EyeSeparation, long EndOfScanDelay,
+ float StereoIDLEVoltage, float StereoLEFTVoltage, float StereoRIGHTVoltage); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayPerspective(float Dist, float Xobs, float Yobs, float Zobs);//Norm
+
+LDDLL_PREFIX LONG WINAPI DisplayWindow( float WinLeft,
+ float WinRight, float WinBottom, float WinTop,
+ float WinRear, float WinFront); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayWindowX(float WinLeft, float WinRight); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayWindowY(float WinBot, float WinTop); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayWindowZ(float WinRear, float WinFront); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayCSize(float ColorSize); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayPaletteSelect(LONG Palette1, LONG Palette2);
+
+LDDLL_PREFIX LONG WINAPI DisplayPaletteMix(float MixValue); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayHueOffset(LONG HueStart, LONG HueEnd, LONG HueNew);
+
+LDDLL_PREFIX LONG WINAPI DisplaySaturation(float SaturationLevel); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayPath(LONG Frame, LONG Point);
+
+LDDLL_PREFIX LONG WINAPI DisplayIris(float IrisLevel); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayColorWheel(float ColorWheelLevel); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayGoboWheel(float Gobo1, float Gobo2, float Gobo3); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayGoboRotate(float Gobo1, float Gobo2, float Gobo3); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayFrost(float Frost1, float Frost2, float Frost3); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayFocus(float FocusLevel); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayMiscControl(float M1, float M2, float M3); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayDepthCue(float DepthEffect, float MinimumZ, float MaximumZ); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayTrackAllow(long Permission);
+
+LDDLL_PREFIX LONG WINAPI DisplayProjectionZones(long ProjectionZoneCode);
+
+LDDLL_PREFIX LONG WINAPI SetGetDisplayProjectionZones(LONG Mode, LONG TrackNumber, LPLONG RETURN_ProjectionZoneCode);
+
+LDDLL_PREFIX LONG WINAPI DisplayFrame(LONG Frame);
+
+LDDLL_PREFIX LONG WINAPI SetGetDisplayFrame(LONG Mode, LONG TrackNumber, LPLONG RETURN_FrameNumber);
+
+LDDLL_PREFIX LONG WINAPI DisplayFrameMix(LONG ToFrame, float MixValue); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplayPreTrans( float XOffs, float YOffs, float ZOffs); //Normalized
+
+LDDLL_PREFIX LONG WINAPI DisplaySkew(LONG TrackDelay, LONG ColorShift, LONG FocusShift);
+LDDLL_PREFIX LONG WINAPI DisplayMinimumPoints(LONG MinimumPoints);
+
+LDDLL_PREFIX LONG WINAPI DisplayUpdateTest(void);
+
+LONG WINAPI DisplayBufferStatus(LONG *RETURN_BufferIsFree, LONG *RETURN_CurrentOutputPoints);
+
+LDDLL_PREFIX LONG WINAPI DisplayUpdate(void);
+
+LDDLL_PREFIX LONG WINAPI DisplayUpdateToFrame(LONG Frame);
+
+LDDLL_PREFIX LONG WINAPI DisplayUpdateEx(LONG Mode);
+
+LDDLL_PREFIX LONG WINAPI DisplayUpdateMode(LONG SyncMode, LONG LeftRightUpdate);
+
+//--------------------------------------------------------------------------------------------
+// QuadMod DMX-512 functions
+//--------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI QMDMXMode(LONG DMXMode, LONG TransmitBreakLength, LONG TransmitMABLength, LONG TransmitStartCode, LONG TransmitNumChannels, LONG TransmitRestLength);
+
+LDDLL_PREFIX LONG WINAPI QMDMXInput(LONG ChannelNumber, LPLONG RETURN_Data);
+
+LDDLL_PREFIX LONG WINAPI QMDMXOutput(LONG ChannelNumber, LONG Data);
+
+LDDLL_PREFIX LONG WINAPI QMDMXVirtualChannels(LONG PortAStartChannel, LONG PortBStartChannel, LONG AUXOutChannel, LONG GraphicsShutterChannel);
+
+LDDLL_PREFIX LONG WINAPI QMDMXStartupFrame(LONG Frame);
+
+LDDLL_PREFIX LONG WINAPI QMDMXShutdownFrame(LONG Frame);
+
+LDDLL_PREFIX LONG WINAPI QMDMXESTOP(void);
+
+LDDLL_PREFIX LONG WINAPI DMXToFrame(void);
+
+LDDLL_PREFIX LONG WINAPI FrameToDMX(void);
+
+LDDLL_PREFIX LONG WINAPI GetDMXMap(DMXMAP *RETURN_DMXMap);
+
+LDDLL_PREFIX LONG WINAPI SetDMXMap(DMXMAP *SUPPLY_DMXMap);
+
+LDDLL_PREFIX LONG WINAPI GetDMXChannelMap(LONG ChannelNumber, DMXCHANNELMAP *RETURN_DMXChannel);
+
+LDDLL_PREFIX LONG WINAPI SetDMXChannelMap(LONG ChannelNumber, DMXCHANNELMAP *SUPPLY_DMXChannel);
+
+
+//-------------------------------------------------------------------------------------------
+// Frame Loading and Saving
+//-------------------------------------------------------------------------------------------
+
+
+LDDLL_PREFIX LONG WINAPI LoadLDA(LPSTR Filename, LPLONG SUPPLY_FileFromFr, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr,LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI LoadLDB(LPSTR Filename, LPLONG SUPPLY_FileFromFr, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI LoadLDSecure(LPSTR Filename, LPLONG SUPPLY_FileFromFr, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI LoadLFile(LPSTR Filename, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI ReadFileInfo(LPSTR Filename, LPSTR RETURN_Description, LPLONG RETURN_NumFrames, LPLONG RETURN_Format, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI SaveLFile(LPSTR Filename, LPSTR Description, LPLONG SUPPLY_FromFr, LPLONG SUPPLY_ToFr, LPLONG Format, LPSTR SUPPLY_Password, LPLONG RETURN_LDStatus);
+
+
+//-------------------------------------------------------------------------------------------
+// Frame Functions
+//-------------------------------------------------------------------------------------------
+
+
+LDDLL_PREFIX LONG WINAPI FindFrame(LPSTR Frame, LPLONG RETURN_FrameNumber);
+
+LDDLL_PREFIX LONG WINAPI ReadMaskData(LONG TrackNumber, LONG FAR* RETURN_MaskData);
+
+LDDLL_PREFIX LONG WINAPI SetChangedFlag(LONG FrameNumber, LONG State);
+
+LDDLL_PREFIX LONG WINAPI ReadFrameStruct(LONG FrameNumber, FRAMESTRUCT *RETURN_FrameStruct);
+
+LDDLL_PREFIX LONG WINAPI ReadFrameStructEx(LONG FrameNumber, FRAMESTRUCTEX *RETURN_FrameStructEx);
+
+LDDLL_PREFIX LONG WINAPI WriteFrameStructEx(LONG FrameNumber,FRAMESTRUCTEX *SUPPLY_FrameStructEx);
+
+LDDLL_PREFIX LONG WINAPI ReadFrame(FRAMESTRUCT *RETURN_FrameStruct, PTSTRUCT *RETURN_PointArray);
+
+LDDLL_PREFIX LONG WINAPI WriteFrame(FRAMESTRUCT *SUPPLY_FrameStruct, PTSTRUCT *SUPPLY_PointArray);
+
+LDDLL_PREFIX LONG WINAPI WriteFrameEx(FRAMESTRUCTEX *SUPPLY_FrameStructEx, PTSTRUCT *SUPPLY_PointArray);
+
+LDDLL_PREFIX LONG WINAPI CopyFrameActive(LONG SourceFrame, LONG DestFrame, LPLONG SUPPLY_ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI CopyBlock(LONG FromFrame, LONG ToFrame, LONG DestFrame);
+
+LDDLL_PREFIX LONG WINAPI ReverseBlock(LONG FromFrame, LONG ToFrame);
+
+LDDLL_PREFIX LONG WINAPI DeleteFrames(LONG FromFr, LONG ToFr);
+
+LDDLL_PREFIX LONG WINAPI MergeFrames(LONG source1fr, LONG source2fr, LONG destfr);
+
+LDDLL_PREFIX LONG WINAPI FrameToUndoActive(LPLONG SUPPLY_ActiveArray); //If no active array is used, supply a NULL pointer.
+
+LDDLL_PREFIX LONG WINAPI UndoToFrameActive(LPLONG RETURN_ActiveArray); //If no active array is used, supply a NULL pointer.
+
+
+//--------------------------------------------------------------------------------------------
+// Vector Frame functions
+//--------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI ConvertToVectorFrame(LONG OptimizePath, LONG PreserveBlanking,
+ LONG StartingX, LONG StartingY, LONG StartingZ);
+
+LDDLL_PREFIX LONG WINAPI ConvertToPointFrame(LONG VisibleBeginEmph, LONG VisibleMiddleEmph,
+ LONG VisibleEndEmph, LONG VisibleDensity,
+ LONG BlankedBeginEmph, LONG BlankedEndEmph,
+ LONG BlankedDensity);
+
+//-------------------------------------------------------------------------------------------
+// Point Functions
+//-------------------------------------------------------------------------------------------
+
+
+LDDLL_PREFIX LONG WINAPI ReadNumPoints(LPLONG RETURN_NumPoints);
+
+LDDLL_PREFIX LONG WINAPI ReadPoint(LONG PointNumber, PTSTRUCT *RETURN_PtStruct);
+
+LDDLL_PREFIX LONG WINAPI WritePoint(LONG PointNumber, PTSTRUCT *SUPPLY_PtStruct);
+
+LDDLL_PREFIX LONG WINAPI SetInsertOnWrite(LONG TrueOrFalse); //For WritePoint function
+
+
+LDDLL_PREFIX LONG WINAPI DeletePoints(LONG FromPt, LONG ToPt);
+
+LDDLL_PREFIX LONG WINAPI InsertPoints(LONG FromPt, LONG ToPt);
+
+LDDLL_PREFIX LONG WINAPI InvertPointsActive(LONG FromPt, LONG ToPt, LONG XOffs, LONG YOffs,
+ LONG ZOffs, LONG Mask, LPLONG SUPPLY_ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI MovePointsActive(LONG FromPt, LONG ToPt, LONG XOffs, LONG YOffs,
+ LONG ZOffs, LONG Mask, LPLONG SUPPLY_ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI ResizePointsActive(LONG FromPt, LONG ToPt,
+ float XResizepct, float YResizepct, float ZResizepct,
+ LONG XResizectr, LONG YResizectr, LONG ZResizectr,
+ LONG Mask, LPLONG SUPPLY_ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI RotatePointsActive(LONG FromPt, LONG ToPt,
+ float XRotatepct, float YRotatepct, float ZRotatepct,
+ LONG XRotatectr, LONG YRotatectr, LONG ZRotatectr,
+ LONG Mask, LPLONG SUPPLY_ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI Set_XYZ_TO_3D_Track(LONG Track);
+
+LDDLL_PREFIX LONG WINAPI XYZ_TO_3D(LONG XCoord, LONG YCoord, LONG ZCoord, LPLONG RETURN_X3D, LPLONG RETURN_Y3D, LPLONG RETURN_VisibleFlag);
+
+//-------------------------------------------------------------------------------------------
+// Palette and color Functions
+//-------------------------------------------------------------------------------------------
+
+
+LDDLL_PREFIX LONG WINAPI LoadPalette(LPSTR ColorFilename, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI LoadPaletteDots(LPSTR ColorFilename, LONG *RETURN_PaletteDotColor1, LONG *RETURN_PaletteDotColor2, LONG *RETURN_PaletteDotColor3, LONG *RETURN_PaletteDotColor4, LONG *RETURN_PaletteDotColor5, LONG *RETURN_PaletteDotColor6, LONG *RETURN_PaletteDotColor7, LONG *RETURN_PaletteDotColor8, char *RETURN_PaletteDotName1, char *RETURN_PaletteDotName2, char *RETURN_PaletteDotName3, char *RETURN_PaletteDotName4, char *RETURN_PaletteDotName5, char *RETURN_PaletteDotName6, char *RETURN_PaletteDotName7, char *RETURN_PaletteDotName8, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI SavePalette(LPSTR ColorFilename, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI SavePaletteDots(LPSTR ColorFilename, LONG *SUPPLY_PaletteDotColor1, LONG *SUPPLY_PaletteDotColor2, LONG *SUPPLY_PaletteDotColor3, LONG *SUPPLY_PaletteDotColor4, LONG *SUPPLY_PaletteDotColor5, LONG *SUPPLY_PaletteDotColor6, LONG *SUPPLY_PaletteDotColor7, LONG *SUPPLY_PaletteDotColor8, char *SUPPLY_PaletteDotName1, char *SUPPLY_PaletteDotName2, char *SUPPLY_PaletteDotName3, char *SUPPLY_PaletteDotName4, char *SUPPLY_PaletteDotName5, char *SUPPLY_PaletteDotName6, char *SUPPLY_PaletteDotName7, char *SUPPLY_PaletteDotName8, LPLONG RETURN_LDStatus);
+
+LDDLL_PREFIX LONG WINAPI TrainColorSystem(void);
+
+LDDLL_PREFIX LONG WINAPI UseDefaultColors(void);
+
+LDDLL_PREFIX LONG WINAPI EliminateUnusedColors(LONG LastColorNumber);
+
+LDDLL_PREFIX LONG WINAPI UpdateAlternatePalettes(void);
+
+
+LDDLL_PREFIX LONG WINAPI ReadColorReg(COLORREGSTRUCT *RETURN_ColorStruct);
+
+LDDLL_PREFIX LONG WINAPI ReadColorRegEx(LONG PaletteSelect, COLORREGSTRUCT *RETURN_ColorStruct);
+
+LDDLL_PREFIX LONG WINAPI ReadNumColors(LPLONG RETURN_NumColors);
+
+LDDLL_PREFIX LONG WINAPI WriteColorReg(COLORREGSTRUCT *SUPPLY_ColorStruct);
+
+LDDLL_PREFIX LONG WINAPI WriteColorRegEx(LONG PaletteSelect, COLORREGSTRUCT *SUPPLY_ColorStruct);
+
+LDDLL_PREFIX LONG WINAPI ReadActuatorColorMode(LPLONG RETURN_Mode);
+
+LDDLL_PREFIX LONG WINAPI WriteActuatorColorMode(LONG Mode);
+
+LDDLL_PREFIX LONG WINAPI RGB4toRGB1(LPLONG SUPPLY_Red, LPLONG SUPPLY_Green, LPLONG SUPPLY_Blue,
+ LPLONG SUPPLY_MSB, LPLONG RETURN_RGBMValue);
+
+LDDLL_PREFIX LONG WINAPI RGB1toRGB4(LPLONG SUPPLY_RGBMValue, LPLONG RETURN_Red, LPLONG RETURN_Green,
+ LPLONG RETURN_Blue, LPLONG RETURN_MSB);
+
+LDDLL_PREFIX LONG WINAPI RGBtoHSV(LPLONG SUPPLY_RGB, LPLONG RETURN_HSV);
+
+LDDLL_PREFIX LONG WINAPI HSVtoRGB(LPLONG SUPPLY_HSV, LPLONG RETURN_RGB);
+
+
+//-------------------------------------------------------------------------------------------
+// Scale setting and getting functions. Sets coordinate scale for Frame/Point reading/writing
+//-------------------------------------------------------------------------------------------
+
+
+
+LDDLL_PREFIX LONG WINAPI SetWorkingScale(LONG LogicalLeft, LONG LogicalRight,
+ LONG LogicalBottom, LONG LogicalTop,
+ LONG LogicalRear, LONG LogicalFront);
+
+
+LDDLL_PREFIX LONG WINAPI SetWorkingScaleX(LONG LogicalLeft, LONG LogicalRight,
+ LONG LogicalOriginX, LONG DeviceLeft,
+ LONG DeviceRight, LONG DeviceOriginX);
+
+LDDLL_PREFIX LONG WINAPI SetWorkingScaleY(LONG LogicalBottom, LONG LogicalTop,
+ LONG LogicalOriginY, LONG DeviceBottom,
+ LONG DeviceTop, LONG DeviceOriginY);
+
+LDDLL_PREFIX LONG WINAPI SetWorkingScaleZ(LONG LogicalRear, LONG LogicalFront,
+ LONG LogicalOriginZ, LONG DeviceRear,
+ LONG DeviceFront, LONG DeviceOriginZ);
+
+LDDLL_PREFIX LONG WINAPI SetWorkingScaleF(LONG LogicalMaxFocus, LONG LogicalOriginF,
+ LONG DeviceMaxFocus, LONG DeviceOriginF);
+
+LDDLL_PREFIX LONG WINAPI GetWorkingScaleX(LPLONG LogicalLeft, LPLONG LogicalRight,
+ LPLONG LogicalOriginX, LPLONG DeviceLeft,
+ LPLONG DeviceRight, LPLONG DeviceOriginX);
+
+LDDLL_PREFIX LONG WINAPI GetWorkingScaleY(LPLONG LogicalBottom, LPLONG LogicalTop,
+ LPLONG LogicalOriginY, LPLONG DeviceBottom,
+ LPLONG DeviceTop, LPLONG DeviceOriginY);
+
+LDDLL_PREFIX LONG WINAPI GetWorkingScaleZ(LPLONG LogicalRear, LPLONG LogicalFront,
+ LPLONG LogicalOriginZ, LPLONG DeviceRear,
+ LPLONG DeviceFront, LPLONG DeviceOriginZ);
+
+LDDLL_PREFIX LONG WINAPI GetWorkingScaleF(LPLONG LogicalMaxFocus, LPLONG LogicalOriginF,
+ LPLONG DeviceMaxFocus, LPLONG DeviceOriginF);
+
+//-------------------------------------------------------------------------------------------
+// Screen Drawing Functions
+//-------------------------------------------------------------------------------------------
+
+
+
+LDDLL_PREFIX LONG WINAPI SetLaserWindow(LONG LeftEdge, LONG RightEdge, LONG BottomEdge, LONG TopEdge, LONG MagLevel);
+
+LDDLL_PREFIX LONG WINAPI DrawGrid(HWND hWnd, LONG gridHvalue, LONG gridVvalue, LONG MClearScreen, LONG MShowZero, LONG MShowGrid);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrame(HWND hWnd, LONG frompt, LONG topt, LONG ViewMode,
+ LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
+ LONG MShowFocus);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameActive(HWND hWnd, LONG frompt, LONG topt, LONG ViewMode,
+ LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
+ LONG MShowFocus, LPLONG ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameActiveEx(HWND hWnd, LONG frompt, LONG topt, LONG ViewMode,
+ LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
+ LONG MShowFocus, LONG MShowBlankedLines, LONG MShowBlankedPoints, LPLONG ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameActiveDC(HWND hWnd, HDC hDC, LONG frompt, LONG topt, LONG ViewMode,
+ LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
+ LONG MShowFocus, LPLONG ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameActiveDCEx(HWND hWnd, HDC hDC, LONG frompt, LONG topt, LONG ViewMode,
+ LONG ClearScreenFlag, long HiliteColor, LONG MShowColorAtPts,
+ LONG MShowFocus, LONG MShowBlankedLines, LONG MShowBlankedPoints, LPLONG ActiveArray);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameFast(HWND hWnd, LONG FrameNumber, LONG ViewMode, LONG ClearScreenFlag, LONG MShowFocus);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameFastDC(HWND hWnd, HDC hDC, LONG FrameNumber, LONG ViewMode, LONG ClearScreenFlag, LONG MShowFocus);
+
+LDDLL_PREFIX LONG WINAPI RedrawFrameFastDCRECT(HWND hWnd, HDC hDC, RECT *rect, LONG FrameNumber, LONG ViewMode, LONG ClearScreenFlag, LONG MShowFocus);
+
+//-------------------------------------------------------------------------------------------
+// Text functions
+//-------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI SetLineLimits(LONG NumBlanked, LONG NumEmphasis, LONG NumPoints, LONG Density);
+
+LDDLL_PREFIX LONG WINAPI LoadFont(LPSTR FontFilename, LPLONG RETURN_LDStatus);
+LDDLL_PREFIX LONG WINAPI SetLaserChar(LONG ViewMode, LONG TextBlanked, LONG TextEmphasis, LONG Density, LONG Width, LONG Height, LONG MaxAngle, LONG AngleDetect, long RGBColor);
+LDDLL_PREFIX LONG WINAPI LaserChar(LONG Ascii, LONG XStart, LONG YStart, LONG BeginPoint, LPLONG RETURN_charXEnd, LPLONG RETURN_charYEnd, LPLONG RETURN_charEndPt);
+LDDLL_PREFIX LONG WINAPI GetLaserCharExtent(LONG Ascii, LPLONG RETURN_charXExtent, LPLONG RETURN_charYExtent);
+
+//-------------------------------------------------------------------------------------------
+// QuadMod32 Parallel Port Functions
+//-------------------------------------------------------------------------------------------
+
+LDDLL_PREFIX LONG WINAPI ParOn(LONG BankNum, LONG LineNum);
+
+LDDLL_PREFIX LONG WINAPI ParOff(LONG BankNum, LONG LineNum);
+
+LDDLL_PREFIX LONG WINAPI ParIn(LONG BankNum, LONG LineNum, LPLONG RETURN_Value);
+
+LDDLL_PREFIX LONG WINAPI DisplayPortLong(long I_OMask, long OutputValue, LPLONG RETURN_Value);
+
+//-------------------------------------------------------------------------------------------
+// Abstract Generator functions
+//-------------------------------------------------------------------------------------------
+
+
+
+LDDLL_PREFIX LONG WINAPI InitAbstractOsc1(float XPhase, float YPhase, float ZPhase);
+
+LDDLL_PREFIX LONG WINAPI InitAbstractOsc2(float XPhase, float YPhase, float ZPhase);
+
+LDDLL_PREFIX LONG WINAPI InitAbstractOsc3(float XPhase, float YPhase, float ZPhase);
+
+LDDLL_PREFIX LONG WINAPI InitAbstractMod1(float ModPhase);
+
+LDDLL_PREFIX LONG WINAPI InitAbstractMod2(float ModPhase);
+
+LDDLL_PREFIX LONG WINAPI InitAbstractColor(LONG SequenceStart);
+
+LDDLL_PREFIX LONG WINAPI InitAbstractColorNew(float ColorPhase);
+
+LDDLL_PREFIX LONG WINAPI SetAbstractOsc1(float XFreq, float YFreq, float ZFreq, float XSize,
+ float YSize, float ZSize, LONG Wave);
+ //Normalized Size Variables
+
+LDDLL_PREFIX LONG WINAPI SetAbstractOsc2(float XFreq, float YFreq, float ZFreq, float XSize,
+ float YSize, float ZSize, LONG Wave);
+ //Normalized Size Variables
+
+LDDLL_PREFIX LONG WINAPI SetAbstractOsc3(float XFreq, float YFreq, float ZFreq, float XSize,
+ float YSize, float ZSize, LONG Wave);
+ //Normalized Size Variables
+
+LDDLL_PREFIX LONG WINAPI SetAbstractMod1(float ModFreq, float ModAmplitude, LONG ModWave);
+ //Normalized Amplitude Variable
+
+LDDLL_PREFIX LONG WINAPI SetAbstractMod2(float ModFreq, float ModAmplitude, LONG ModWave);
+ //Normalized Amplitude Variable
+
+LDDLL_PREFIX LONG WINAPI SetAbstractColor(LONG ColorFreq, LONG ColorWave);
+
+LDDLL_PREFIX LONG WINAPI SetAbstractColorNew(float ColorFreq, LONG ColorWave);
+
+LDDLL_PREFIX LONG WINAPI SwapWaves(void);
+
+LDDLL_PREFIX LONG WINAPI GenerateAbstract(LONG NumVisible, LONG NumOverscan, LONG NumOverlap);
+
+LDDLL_PREFIX LONG WINAPI GenerateAbstractNew(LONG NumVisible, LONG NumOverscan, LONG NumOverlap);
+
+LDDLL_PREFIX LONG WINAPI GetAbstractPhase(LONG SUPPLY_OscID, float *RETURN_XPhase, float *RETURN_YPhase, float *RETURN_ZPhase);
+
+LDDLL_PREFIX LONG WINAPI GetAbstractFreqSizeWave(LONG SUPPLY_OscID, float *RETURN_XFreq,
+ float *RETURN_YFreq, float *RETURN_ZFreq,
+ float *RETURN_XSize, float *RETURN_YSize, float *RETURN_ZSize, int *RETURN_Wave);
+
+LDDLL_PREFIX LONG WINAPI AbstractToFrame(void);
+
+LDDLL_PREFIX LONG WINAPI FrameToAbstract(void);
+
diff --git a/Src/Plugins/Visualization/vis_avs/laser/laser.cpp b/Src/Plugins/Visualization/vis_avs/laser/laser.cpp
new file mode 100644
index 00000000..c229499b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/laser.cpp
@@ -0,0 +1,149 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+extern "C" {
+#include "ld32.h"
+};
+
+int active_state;
+
+int g_laser_nomessage,g_laser_zones;
+int init=0;
+int ld32_framebase=1;
+
+static void onActivate()
+{
+ if (active_state) return;
+ active_state=1;
+
+ ResetLD();
+ SetWorkingTracks(-1);
+ SetWorkingScanners(-1);
+ DisplayFlags(0);
+}
+static void onDeactivate()
+{
+ if (!active_state) return;
+ active_state=0;
+
+ ResetLD();
+ SetWorkingTracks(-1);
+ SetWorkingScanners(-1);
+ DisplayFlags(0);
+ DisplayFrame(0);
+ DisplayUpdate();
+}
+
+
+void laser_connect(void)
+{
+ LONG v;
+ InitialQMCheck(&v);
+ if (v != LDERR_OK)
+ {
+ if (!g_laser_nomessage) MessageBox(NULL,"No QM2000 found.","AVS/Laser Error",MB_OK);
+ return;
+ }
+ {
+ LONG mf,mp,mb,uf,ver;
+ BeginSessionEx(&ver,&mf, &mp, &mb, &uf, &v);
+ if (v != LDERR_OK)
+ {
+ return;
+ }
+ GetLDDLLModuleUsage(&v);
+ if (v != 1)
+ {
+ if (!g_laser_nomessage) MessageBox(NULL,"QM2000 is being shared with other software.","AVS/Laser Warning",MB_OK);
+ }
+ else
+ {
+ onActivate();
+ }
+ ld32_framebase=mf;
+ }
+
+ init=1;
+}
+extern "C" void LaserQuit();
+
+
+void laser_disconnect(void)
+{
+ if (!init) return;
+ init=0;
+ onDeactivate();
+ LaserQuit();
+}
+
+void laser_sendframe(void *data, int datalen)
+{
+ struct t
+ {
+ FRAMESTRUCTEX frame;
+ PTSTRUCT points[4096];
+ } *framedata=(struct t *)data;
+
+ if (!init) return;
+
+ extern int g_laser_nomessage;
+ if (g_laser_nomessage&4)
+ {
+ onDeactivate();
+ return;
+ }
+ if (g_laser_nomessage&2)
+ {
+ DWORD dw;
+ GetWindowThreadProcessId(GetForegroundWindow(),&dw);
+ if (dw != GetCurrentProcessId())
+ {
+ onDeactivate();
+ return;
+ }
+ }
+ onActivate();
+
+
+ SetWorkingFrame(ld32_framebase);
+ WriteFrameEx(&framedata->frame,framedata->points);
+
+ SetWorkingTracks(1);
+ DisplayFlags(0);
+ DisplayFrame(ld32_framebase);
+ DisplayProjectionZones(g_laser_zones);
+
+ LONG bif=0, cop;
+ if (!(g_laser_nomessage&8)) DisplayBufferStatus(&bif,&cop);
+ if (!bif)
+ DisplayUpdate();
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/laserline.cpp b/Src/Plugins/Visualization/vis_avs/laser/laserline.cpp
new file mode 100644
index 00000000..e9c44c2c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/laserline.cpp
@@ -0,0 +1,218 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include <math.h>
+#include "../r_defs.h"
+extern "C" {
+#include "ld32.h"
+};
+
+
+static int fix(int a)
+{
+ return ((a&0xff0000)>>16)|(a&0xff00)|((a&0xff)<<16);
+}
+
+static int dist(int x1, int y1, int x2, int y2)
+{
+ x1-=x2;
+ y1-=y2;
+ return x1*x1+y1*y1;
+}
+
+static double actdist(double x1, double y1, double x2, double y2)
+{
+ x1-=x2;
+ y1-=y2;
+ return sqrt(x1*x1+y1*y1);
+}
+
+static __inline int getval(int x1, int y1, int x2, int y2, int xv)
+{
+ if (x1==x2) return y1;
+ return y1+MulDiv(xv-x1,y2-y1,x2-x1);
+}
+
+static void doclip(int &x1, int &y1, int x2, int y2)
+{
+ if (x1 > 8000 && x2 <= 8000)
+ {
+ y1=getval(x1,y1,x2,y2,8000);
+ x1=8000;
+ }
+ if (x1 < -8000 && x2 >= -8000)
+ {
+ y1=getval(x1,y1,x2,y2,-8000);
+ x1=-8000;
+ }
+}
+
+void LineDrawList(C_LineListBase *list, int *fb, int w, int h)
+{
+ LineType *ll;
+
+ static struct
+ {
+ FRAMESTRUCTEX frame;
+ PTSTRUCT points[32768];
+ } d;
+ memset(&d.frame,0,sizeof(d.frame));
+ int cp=0;
+ int lastendx=-10000,lastendy=-10000;
+
+ int w2=w/2;
+ int h2=h/2;
+ int numl=list->GetUsedLines();
+ ll=list->GetLineList();
+ while (numl-->0 && cp < sizeof(d.points)/sizeof(PTSTRUCT)-2)
+ {
+ int x1,y1,x2,y2;
+ // draw to screen
+ {
+ x1=(int) (ll->x1 * w2) + w2;
+ x2=(int) (ll->x2 * w2) + w2;
+ y1=(int) (ll->y1 * h2) + h2;
+ y2=(int) (ll->y2 * h2) + h2;
+ if (ll->mode==0)
+ {
+ line(fb,x1,y1,x2,y2,w,h,ll->color);
+ }
+ else
+ {
+ if (x1 >= 0 && x1 < w && y1 >= 0 && y1 < h)
+ {
+ int o=x1+y1*w;
+ fb[o]=BLEND(fb[o],ll->color);
+ }
+ }
+ }
+
+ x1=(int) (ll->x1*8000.0);
+ x2=(int) (ll->x2*8000.0);
+
+ y1=(int) (ll->y1*-8000.0);
+ y2=(int) (ll->y2*-8000.0);
+
+
+ if (ll->mode==0)
+ {
+ doclip(x1,y1,x2,y2);
+ doclip(x2,y2,x1,y1);
+ doclip(y1,x1,y2,x2);
+ doclip(y2,x2,y1,x1);
+
+ if (x1 >= -8000 && x1 <= 8000 && y1 >= -8000 && y1 <= 8000 &&
+ x2 >= -8000 && x2 <= 8000 && y2 >= -8000 && y2 <= 8000)
+ {
+ // x1, y1 is the new, far point
+ if (cp && dist(x1,y1,lastendx,lastendy) < dist(x2,y2,lastendx,lastendy))
+ {
+ int t;
+ t=x1; x1=x2; x2=t;
+ t=y1; y1=y2; y2=t;
+ }
+
+ // if new start point is too far away, blank to that point
+ if (dist(x2,y2,lastendx,lastendy) > 400*400 || !cp)
+ {
+ memset(&d.points[cp],0,sizeof(d.points[0]));
+ if (cp)
+ {
+ d.points[cp-1].Status=4096;
+ }
+ d.points[cp].Status=0;
+ d.points[cp].XCoord=x2;
+ d.points[cp].YCoord=y2;
+ cp++;
+ }
+ else if (cp>1 && d.points[cp-1].RGBValue)
+ {
+ double a1=atan2(d.points[cp-2].XCoord-x2,d.points[cp-2].YCoord-y2);
+ double a2=atan2(x2-x1,y2-y1);
+ if (fabs(a1-a2) >= 1.0*3.14159/180.0)
+ {
+ d.points[cp-1].Status=4096;
+ }
+
+ }
+ lastendx=x1;
+ lastendy=y1;
+ memset(&d.points[cp],0,sizeof(d.points[0]));
+ d.points[cp].RGBValue=fix(ll->color);
+ d.points[cp].Status=0;
+ d.points[cp].XCoord=x1;
+ d.points[cp].YCoord=y1;
+ cp++;
+ }
+ }
+ else
+ {
+ if (x1 > -8000 && x1 < 8000 && y1 > -8000 && y1 < 8000)
+ {
+ if (dist(x1,y1,lastendx,lastendy) > 30*30)
+ {
+ memset(&d.points[cp],0,sizeof(d.points[0]));
+ d.points[cp].Status=0;
+ d.points[cp].XCoord=x1;
+ d.points[cp].YCoord=y1;
+ cp++;
+ }
+ memset(&d.points[cp],0,2*sizeof(d.points[0]));
+ d.points[cp].RGBValue=fix(ll->color);
+ d.points[cp].Status=4096;
+ d.points[cp].XCoord=x1;
+ d.points[cp].YCoord=y1;
+ cp++;
+ d.points[cp].Status=4096;
+ d.points[cp].XCoord=x1;
+ d.points[cp].YCoord=y1;
+ cp++;
+ lastendx=x1;
+ lastendy=y1;
+ }
+ }
+
+ ll++;
+ }
+ if (cp)
+ {
+ d.points[cp-1].Status=4096;
+ }
+
+ memset(&d.frame,0,sizeof(d.frame));
+ d.frame.VectorFlag=1;
+ d.frame.NumPoints=max(cp,1);
+ d.frame.ScanRate=100;
+ memcpy(d.frame.FrameNote,"AVS/Laser Frame ",24);
+
+ laser_sendframe(&d,sizeof(d.frame)+sizeof(PTSTRUCT)*max(cp,16));
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/laserline.h b/Src/Plugins/Visualization/vis_avs/laser/laserline.h
new file mode 100644
index 00000000..4ed4d2bf
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/laserline.h
@@ -0,0 +1,55 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include "linelist.h"
+
+void LineDrawList(C_LineListBase *list, int *fb, int w, int h);
+
+void laser_connect(void);
+void laser_disconnect(void);
+void laser_sendframe(void *data, int datalen);
+
+static void __inline laser_drawpoint(float x, float y, int current_color)
+{
+ LineType line;
+ line.color=current_color;
+ line.mode=1;
+ line.x2=0;
+ line.x1=x;
+ line.y2=0;
+ line.y1=y;
+ g_laser_linelist->AddLine(&line);
+}
+
+#else
+#ifndef laser_drawpoint
+#define laser_drawpoint(x,y,c)
+#endif
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/ld32.c b/Src/Plugins/Visualization/vis_avs/laser/ld32.c
new file mode 100644
index 00000000..90a1f385
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/ld32.c
@@ -0,0 +1,187 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+
+#include "ld32.h"
+
+static HINSTANCE hDll;
+
+LONG (WINAPI *_LoadPalette)(LPSTR ColorFilename, LPLONG RETURN_LDStatus);
+LONG (WINAPI *_WritePoint)(LONG PointNumber, PTSTRUCT *SUPPLY_PtStruct);
+LONG (WINAPI *_InitialQMCheck)(LPLONG RETURN_LDStatus);
+LONG (WINAPI *_DisplayUpdate)(void);
+LONG (WINAPI *_DisplayBufferStatus)(LONG *RETURN_BufferIsFree, LONG *RETURN_CurrentOutputPoints);
+LONG (WINAPI *_DisplayFrame)(LONG Frame);
+LONG (WINAPI *_WriteFrameEx)(FRAMESTRUCTEX *SUPPLY_FrameStruct, PTSTRUCT *SUPPLY_PointArray);
+LONG (WINAPI *_SetWorkingScanners)(LONG Scanner);
+LONG (WINAPI *_SetWorkingTracks)(LONG Track);
+LONG (WINAPI *_SetWorkingFrame)(LONG FrameNumber);
+LONG (WINAPI *_BeginSessionEx)(LPLONG RETURN_Version, LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus);
+LONG (WINAPI *_DisplayFlags)(LONG Flags);
+LONG (WINAPI *_EndSession)(void);
+LONG (WINAPI *_GetLDDLLModuleUsage)(LPLONG ModuleUsage);
+LONG (WINAPI *_ResetLD)(void); //Updates all track variables
+LONG (WINAPI *_ReadProjectionZone)(LONG ZoneNumber, PROJECTIONZONE *RETURN_PZ);
+LONG (WINAPI *_OpenLDCommWindow)(void);
+LONG (WINAPI *_DisplayProjectionZones)(long ProjectionZoneCode);
+
+LONG WINAPI InitialQMCheck(LPLONG RETURN_LDStatus)
+{
+ hDll=LoadLibrary("ld2000.dll");
+ if (!hDll)
+ {
+// printf("LD2000: error loading DLL\n");
+ *RETURN_LDStatus=1;
+ return 1;
+ }
+#define RETR(x) *((void**)&_##x)=(void*)GetProcAddress(hDll,#x); if (!_##x) { FreeLibrary(hDll); hDll=0; *RETURN_LDStatus=1; return 1; }
+
+ // \
+ // if (!_##x) printf("LD2000: error loading DLL: " #x "\n");
+
+ RETR(ReadProjectionZone);
+ RETR(InitialQMCheck);
+ RETR(DisplayUpdate);
+ RETR(DisplayBufferStatus);
+ RETR(DisplayFrame);
+ RETR(WriteFrameEx);
+ RETR(WritePoint);
+ RETR(SetWorkingScanners);
+ RETR(LoadPalette);
+ RETR(SetWorkingTracks);
+ RETR(SetWorkingFrame);
+ RETR(EndSession);
+ RETR(BeginSessionEx);
+ RETR(DisplayFlags);
+ RETR(ResetLD);
+ RETR(OpenLDCommWindow);
+ RETR(GetLDDLLModuleUsage);
+ RETR(DisplayProjectionZones);
+ return _InitialQMCheck(RETURN_LDStatus);
+}
+
+LONG WINAPI DisplayProjectionZones(long ProjectionZoneCode)
+{
+ return _DisplayProjectionZones(ProjectionZoneCode);
+}
+
+
+
+LONG WINAPI ReadProjectionZone(LONG ZoneNumber, PROJECTIONZONE *RETURN_PZ)
+{
+ if (!hDll||!_ReadProjectionZone) return 1;
+ return _ReadProjectionZone(ZoneNumber,RETURN_PZ);
+}
+
+LONG WINAPI DisplayBufferStatus(LONG *RETURN_BufferIsFree, LONG *RETURN_CurrentOutputPoints)
+{
+ return _DisplayBufferStatus(RETURN_BufferIsFree,RETURN_CurrentOutputPoints);
+}
+
+LONG WINAPI DisplayUpdate(void)
+{
+ return _DisplayUpdate();
+}
+LONG WINAPI DisplayFrame(LONG Frame)
+{
+ return _DisplayFrame(Frame);
+}
+
+LONG WINAPI WriteFrameEx(FRAMESTRUCTEX *SUPPLY_FrameStruct, PTSTRUCT *SUPPLY_PointArray)
+{
+ return _WriteFrameEx(SUPPLY_FrameStruct,SUPPLY_PointArray);
+}
+
+LONG WINAPI SetWorkingScanners(LONG Scanner)
+{
+ return _SetWorkingScanners(Scanner);
+}
+
+LONG WINAPI SetWorkingTracks(LONG Track)
+{
+ return _SetWorkingTracks(Track);
+}
+
+LONG WINAPI SetWorkingFrame(LONG FrameNumber)
+{
+ return _SetWorkingFrame(FrameNumber);
+}
+
+LONG WINAPI OpenLDCommWindow(void)
+{
+ return _OpenLDCommWindow();
+}
+
+LONG WINAPI EndSession(void)
+{
+ return _EndSession();
+}
+
+LONG WINAPI LoadPalette(LPSTR ColorFilename, LPLONG RETURN_LDStatus)
+{
+ return _LoadPalette(ColorFilename,RETURN_LDStatus);
+}
+
+LONG WINAPI WritePoint(LONG PointNumber, PTSTRUCT *SUPPLY_PtStruct)
+{
+ return _WritePoint(PointNumber,SUPPLY_PtStruct);
+}
+
+LONG WINAPI GetLDDLLModuleUsage(LPLONG ModuleUsage)
+{
+ return _GetLDDLLModuleUsage(ModuleUsage);
+}
+
+LONG WINAPI ResetLD()
+{
+ return _ResetLD();
+}
+
+LONG WINAPI BeginSessionEx(LPLONG RETURN_Version, LPLONG RETURN_MaxFrames, LPLONG RETURN_MaxPoints, LPLONG RETURN_MaxBuffer, LPLONG RETURN_UndoFrames, LPLONG RETURN_LDStatus)
+{
+ return _BeginSessionEx(
+ RETURN_Version, RETURN_MaxFrames,
+ RETURN_MaxPoints, RETURN_MaxBuffer,
+ RETURN_UndoFrames,RETURN_LDStatus);
+}
+LONG WINAPI DisplayFlags(LONG Flags)
+{
+ return _DisplayFlags(Flags);
+}
+
+void LaserQuit()
+{
+ if (hDll) FreeLibrary(hDll);
+ hDll=0;
+ _InitialQMCheck=0;
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/linelist.cpp b/Src/Plugins/Visualization/vis_avs/laser/linelist.cpp
new file mode 100644
index 00000000..bfc36e2e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/linelist.cpp
@@ -0,0 +1,107 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include "linelist.h"
+
+class C_LineList : public C_LineListBase
+{
+private:
+ int max;
+ int used;
+ LineType *linelist;
+public:
+ C_LineList() { max=16384; linelist=(LineType *)malloc(16384*sizeof(LineType)); used=0; };
+ virtual ~C_LineList() { free(linelist); }
+ virtual int GetMaxLines(void) { return max; };
+ virtual int GetUsedLines(void) { return used; };
+ virtual void SetUsedLines(int usedlines) { used=usedlines; }
+ virtual void SetLines(LineType *list, int start, int length) { memcpy(linelist+start,list,length*sizeof(LineType)); }
+ virtual void SetMaxLines(int m);
+ virtual void ClearLineList(void);
+ virtual LineType *GetLineList(void);
+ virtual void AddLine(LineType *line);
+
+ void swapcontents(C_LineList *other)
+ {
+ {
+ int tmp;
+ tmp=max;
+ max=other->max;
+ other->max=tmp;
+
+ tmp=used;
+ used=other->used;
+ other->used=tmp;
+ }
+ LineType *tmp;
+ tmp=linelist;
+ linelist=other->linelist;
+ other->linelist=tmp;
+ }
+
+};
+
+C_LineListBase *createLineList(void)
+{
+ return (C_LineListBase *)new C_LineList();
+}
+
+void LineListSwap(C_LineListBase *item1, C_LineListBase *item2)
+{
+ C_LineList *i1=(C_LineList*)item1;
+ C_LineList *i2=(C_LineList*)item2;
+ i1->swapcontents(i2);
+}
+
+void C_LineList::SetMaxLines(int m)
+{
+ if (m > 16384) m = 16384;
+ max=m;
+ if (used > max) ClearLineList();
+}
+
+void C_LineList::ClearLineList(void)
+{
+ used=0;
+}
+
+LineType *C_LineList::GetLineList(void)
+{
+ return linelist;
+}
+
+void C_LineList::AddLine(LineType *line)
+{
+ if (used >= max) return;
+ memcpy(linelist+used,line,sizeof(LineType));
+ used++;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/linelist.h b/Src/Plugins/Visualization/vis_avs/laser/linelist.h
new file mode 100644
index 00000000..2d1b9ec8
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/linelist.h
@@ -0,0 +1,57 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+typedef struct
+{
+ float x1, y1;
+ float x2, y2;
+ int color;
+ int mode;
+} LineType;
+
+class C_LineListBase
+{
+ public:
+ C_LineListBase(){ };
+ virtual ~C_LineListBase() { };
+
+ virtual int GetMaxLines(void)=0;
+ virtual int GetUsedLines(void)=0;
+ virtual void SetMaxLines(int m)=0;
+ virtual void SetUsedLines(int usedlines)=0;
+ virtual void SetLines(LineType *list, int start, int length)=0;
+ virtual void ClearLineList(void)=0;
+ virtual LineType *GetLineList(void)=0;
+ virtual void AddLine(LineType *line)=0;
+};
+
+C_LineListBase *createLineList(void);
+extern C_LineListBase *g_laser_linelist;
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/rl_beathold.cpp b/Src/Plugins/Visualization/vis_avs/laser/rl_beathold.cpp
new file mode 100644
index 00000000..abbb556c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/rl_beathold.cpp
@@ -0,0 +1,165 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include <commctrl.h>
+#include "../r_defs.h"
+#include "../resource.h"
+#include <math.h>
+
+#define C_THISCLASS CLASER_BeatHoldClass
+#define MOD_NAME "Misc / Beat Hold"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // returns 1 if fbout has dest
+ virtual char *get_desc() { return MOD_NAME; }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int decayMS, beatSkip;
+
+ DWORD isBeatDecay;
+ int beatCount;
+
+ LineType m_linelist[1024];
+ int linelist_used;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255; pos+=4
+#define GET_INT(a) if (len-pos>=4) { (a)=(data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24)); pos += 4; }
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ GET_INT(decayMS);
+ GET_INT(beatSkip);
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(decayMS);
+ PUT_INT(beatSkip);
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ isBeatDecay=0;
+ decayMS=500;
+ beatCount=0;
+ beatSkip=4;
+ linelist_used=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
+{
+ if (isBeat&0x80000000) return 0;
+ if (isBeatDecay)
+ {
+ if (GetTickCount() > isBeatDecay)
+ {
+ isBeatDecay=0;
+ }
+ else
+ {
+ g_laser_linelist->SetLines(m_linelist,0,linelist_used);
+ g_laser_linelist->SetUsedLines(linelist_used);
+ }
+ }
+ else if (isBeat && ++beatCount > beatSkip)
+ {
+ beatCount=0;
+ isBeatDecay=GetTickCount()+decayMS;
+ linelist_used=g_laser_linelist->GetUsedLines();
+ memcpy(m_linelist,g_laser_linelist->GetLineList(),linelist_used*sizeof(LineType));
+ }
+ return 0;
+}
+
+C_RBASE *RLASER_BeatHold(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,20);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->decayMS/100);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,16);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->beatSkip);
+
+ return 1;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->decayMS=t*100;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
+ {
+ g_this->beatSkip=t;
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_BEATHOLD,hwndParent,g_DlgProc);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/rl_bren.cpp b/Src/Plugins/Visualization/vis_avs/laser/rl_bren.cpp
new file mode 100644
index 00000000..d91a310b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/rl_bren.cpp
@@ -0,0 +1,183 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include <commctrl.h>
+#include "../r_defs.h"
+#include "../resource.h"
+
+#include <math.h>
+
+#define C_THISCLASS CLASER_BrenClass
+#define MOD_NAME "Render / Brennan\'s Effect"
+
+typedef struct {
+ float x, y;
+} PT;
+
+typedef struct {
+ PT pt[4];
+} segment;
+
+#define BOUND (0.6f)
+#define NSEG 48
+#define VISSEG 6
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // returns 1 if fbout has dest
+ virtual char *get_desc() { return MOD_NAME; }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ segment seg[NSEG];
+ PT d[4];
+ float phase;
+ int step;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ return pos;
+}
+
+float frandom() {
+ return (float)rand() / (float)RAND_MAX;
+}
+
+C_THISCLASS::C_THISCLASS()
+{
+ int i, j;
+
+ for (j = 0; j < NSEG; j++) {
+ for (i = 0; i < 4; i++) {
+// seg[j].pt[i].x = frandom() * 2.0 - 1.0;
+ // seg[j].pt[i].y = frandom() * 2.0 - 1.0;
+ seg[j].pt[i].x = 0.f;
+ seg[j].pt[i].y = 0.f;
+ }
+ }
+ for (i = 0; i < 4; i++) {
+ d[i].x = frandom() * 0.015 + 0.005;
+ d[i].y = frandom() * 0.015 + 0.005;
+ }
+
+
+ phase = 0.0;
+ step = 0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+
+#define PI 3.14159
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
+{
+ if (isBeat&0x80000000) return 0;
+ LineType l;
+ int i, j;
+ float s;
+
+ s = sin(phase * 2 * PI)*0.10+0.9;
+ //s = 1.0;
+ //s = 0.8 + isBeat * 0.2;
+
+ for (i = 0; i < 4; i++) {
+ seg[0].pt[i].x += d[i].x * s;
+ seg[0].pt[i].y += d[i].y * s;
+ if (seg[0].pt[i].x < -BOUND || seg[0].pt[i].x > BOUND) d[i].x = -d[i].x;
+ if (seg[0].pt[i].y < -BOUND || seg[0].pt[i].y > BOUND) d[i].y = -d[i].y;
+ }
+
+ for (j = 0; j < NSEG; j++) {
+ static PT p;
+ if ((step++ % (NSEG/VISSEG)) != 0) continue;
+ for (i = 0; i < 4; i++) {
+ l.mode=0;
+ l.color=RGB(0, 0, 255);
+ l.x1= seg[j].pt[i].x * s;
+ l.y1= seg[j].pt[i].y * s;
+ l.x2= (p.x)*s;
+ l.y2= (p.y)*s;
+ p = seg[j].pt[i];
+
+ g_laser_linelist->AddLine(&l);
+ l.x1 = l.x2;
+ l.y1 = l.y2;
+ l.mode=1;
+ l.color=RGB(0, 255, 0);
+ g_laser_linelist->AddLine(&l);
+ }
+ }
+
+ for (i = NSEG-1; i > 0; i--) {
+ seg[i] = seg[i-1];
+ }
+
+ phase += 0.005f;
+ return 0;
+}
+
+C_RBASE *RLASER_Bren(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return 0;//WASABI_API_CREATEDIALOG(IDD_CFG_LINE,hwndParent,g_DlgProc);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/rl_cones.cpp b/Src/Plugins/Visualization/vis_avs/laser/rl_cones.cpp
new file mode 100644
index 00000000..027b2607
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/rl_cones.cpp
@@ -0,0 +1,363 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include <commctrl.h>
+#include "../r_defs.h"
+#include "../resource.h"
+
+#include <math.h>
+
+#define C_THISCLASS CLASER_MovingConeClass
+#define MOD_NAME "Render / Moving Cone"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // returns 1 if fbout has dest
+ virtual char *get_desc() { return MOD_NAME; }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+
+ int maxdist[2],size,size2,num_seg;
+
+ int s_pos;
+ int beatcnt;
+
+ double c[2];
+ double v[2];
+ double p[2];
+
+ int mode;
+
+ int colors[16],num_colors;
+
+ int color_pos;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=0;
+ if (len-pos >= 4) { maxdist[0]=maxdist[1]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { size=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { size2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { num_seg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { mode=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { maxdist[1]=GET_INT(); pos+=4; }
+ s_pos=size;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ PUT_INT(maxdist[0]); pos+=4;
+ PUT_INT(size); pos+=4;
+ PUT_INT(size2); pos+=4;
+ PUT_INT(num_seg); pos+=4;
+ PUT_INT(mode); pos+=4;
+ PUT_INT(maxdist[1]); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ num_seg=8;
+ size=size2=s_pos=8;
+ maxdist[0]=maxdist[1]=16;
+ c[0]=c[1]=0.0f;
+ v[0]=-0.01551;
+ v[1]=0.0;
+
+ p[0]=-0.6;
+ p[1]=0.3;
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+ beatcnt=0;
+ mode=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
+{
+ if (isBeat&0x80000000) return 0;
+ LineType l;
+ int x;
+ int current_color;
+
+ if (!num_colors) return 0;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ float xp,yp;
+
+ if (isBeat)
+ {
+ c[0]=((rand()%33)-16)/48.0f;
+ c[1]=((rand()%33)-16)/48.0f;
+ }
+
+
+ {
+ if (p[0] >= 0.0000001 || p[0] <= -0.0000001) v[0] -= 0.004*(p[0]-c[0]);
+ if (p[1] >= 0.0000001 || p[1] <= -0.0000001) v[1] -= 0.004*(p[1]-c[1]);
+ }
+
+ p[0]+=v[0];
+ p[1]+=v[1];
+
+ v[0]*=0.991;
+ v[1]*=0.991;
+
+ xp=(float) (p[0]*(maxdist[0]/32.0));
+ yp=(float) (p[1]*(maxdist[1]/32.0));
+ if (isBeat)
+ s_pos=size2;
+ int sz=s_pos;
+ s_pos=(s_pos+size)/2;
+ {
+ float dx,dy;
+ float lx,ly;
+ lx=(float) (cos(0.0)*s_pos/75.0);
+ ly=(float) (sin(0.0)*s_pos/75.0);
+ for (x = 0; x < num_seg; x ++)
+ {
+ l.mode=mode;
+ l.color=current_color;
+ dx=(float) (cos(0.0+(x+1)*3.14159*2.0/num_seg)*s_pos/75.0);
+ dy=(float) (sin(0.0+(x+1)*3.14159*2.0/num_seg)*s_pos/75.0);
+ if (!mode)
+ {
+ l.x2=xp+lx;
+ l.y2=yp+ly;
+ }
+ else l.x2=l.y2=0;
+ l.x1=xp+dx;
+ l.y1=yp+dy;
+ lx=dx;
+ ly=dy;
+ int x=(int) (l.x1*(w/2)+(w/2));
+ int y=(int) (l.y1*(h/2)+(h/2));
+
+ g_laser_linelist->AddLine(&l);
+ }
+ }
+ return 0;
+}
+
+C_RBASE *RLASER_Cone(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={BS_SOLID,color,0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,g_this->num_seg,FALSE);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->maxdist[0]);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER7,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER7,TBM_SETRANGEMAX,0,32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER7,TBM_SETPOS,1,g_this->maxdist[1]);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,128);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->size);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,128);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->size2);
+ if (g_this->mode) CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
+
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_RADIO1:
+ case IDC_RADIO2:
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1))
+ g_this->mode=1;
+ else g_this->mode=0;
+ break;
+ case IDC_EDIT1:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_EDIT1,&tr,FALSE);
+ if (tr)
+ {
+ g_this->num_seg=p;
+ }
+ }
+ break;
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ } }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->maxdist[0]=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER7))
+ {
+ g_this->maxdist[1]=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
+ {
+ g_this->s_pos=g_this->size=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
+ {
+ g_this->s_pos=g_this->size2=t;
+ }
+ }
+ return 0;
+
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_CONE,hwndParent,g_DlgProc);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/rl_line.cpp b/Src/Plugins/Visualization/vis_avs/laser/rl_line.cpp
new file mode 100644
index 00000000..a049532a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/rl_line.cpp
@@ -0,0 +1,338 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include <commctrl.h>
+#include "../r_defs.h"
+#include "../resource.h"
+
+#include <math.h>
+
+#define C_THISCLASS C_MovingLineClass
+#define MOD_NAME "Render / Moving Line"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // returns 1 if fbout has dest
+ virtual char *get_desc() { return MOD_NAME; }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+
+ int maxdist,size,size2,maxbeatcnt;
+
+ int s_pos;
+ int beatcnt;
+
+ double angle,dangle;
+
+ double c[2];
+ double v[2];
+ double p[2];
+
+
+ int colors[16],num_colors;
+
+ int color_pos;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=0;
+ if (len-pos >= 4) { maxdist=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { size=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { size2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { maxbeatcnt=GET_INT(); pos+=4; }
+ s_pos=size;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ PUT_INT(maxdist); pos+=4;
+ PUT_INT(size); pos+=4;
+ PUT_INT(size2); pos+=4;
+ PUT_INT(maxbeatcnt); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ size=size2=s_pos=8;
+ maxdist=16;
+ c[0]=c[1]=0.0f;
+ v[0]=-0.01551;
+ v[1]=0.0;
+
+ angle=0.0;
+ dangle=3.14159/180.0*8.0;
+ p[0]=-0.6;
+ p[1]=0.3;
+ num_colors=1;
+ maxbeatcnt=16;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+ beatcnt=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
+{
+ if (isBeat&0x80000000) return 0;
+ LineType l;
+ int current_color;
+
+ if (!num_colors) return 0;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ l.mode=0;
+ l.color=current_color;
+
+ double xp,yp;
+
+ if (isBeat)
+ {
+ if (maxbeatcnt && ++beatcnt >= maxbeatcnt)
+ {
+ beatcnt=0;
+ dangle=-dangle;
+ }
+ c[0]=((rand()%33)-16)/48.0f;
+ c[1]=((rand()%33)-16)/48.0f;
+ }
+
+
+ {
+ if (p[0] >= 0.0000001 || p[0] <= -0.0000001) v[0] -= 0.004*(p[0]-c[0]);
+ if (p[1] >= 0.0000001 || p[1] <= -0.0000001) v[1] -= 0.004*(p[1]-c[1]);
+ }
+
+ p[0]+=v[0];
+ p[1]+=v[1];
+
+ v[0]*=0.991;
+ v[1]*=0.991;
+
+ xp=(p[0]*(maxdist/32.0));
+ yp=(p[1]*(maxdist/32.0));
+ if (isBeat)
+ s_pos=size2;
+ int sz=s_pos;
+ s_pos=(s_pos+size)/2;
+ {
+ double dx,dy;
+ dx=cos(angle)*s_pos/75.0;
+ dy=sin(angle)*s_pos/75.0;
+ l.x1=(float) (xp-dx);
+ l.y1=(float) (yp-dy);
+ l.x2=(float) (xp+dx);
+ l.y2=(float) (yp+dy);
+ g_laser_linelist->AddLine(&l);
+ angle += dangle;
+ }
+ return 0;
+}
+
+C_RBASE *RLASER_Line(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={BS_SOLID,color,0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->maxdist);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,128);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->size);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,128);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->size2);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,g_this->maxbeatcnt,FALSE);
+
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_EDIT1:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_EDIT1,&tr,FALSE);
+ if (tr)
+ {
+ g_this->maxbeatcnt=p;
+ }
+ }
+ break;
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ } }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->maxdist=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
+ {
+ g_this->s_pos=g_this->size=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
+ {
+ g_this->s_pos=g_this->size2=t;
+ }
+ }
+ return 0;
+
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_LINE,hwndParent,g_DlgProc);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/laser/rl_trans.cpp b/Src/Plugins/Visualization/vis_avs/laser/rl_trans.cpp
new file mode 100644
index 00000000..af4d3f70
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/laser/rl_trans.cpp
@@ -0,0 +1,338 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifdef LASER
+#include <windows.h>
+#include <commctrl.h>
+#include "../r_defs.h"
+#include "../resource.h"
+#include "../evallib/eval.h"
+#include "../evallib/compiler.h"
+#include <math.h>
+
+#define C_THISCLASS CLASER_Transform
+#define MOD_NAME "Misc / Transform"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // returns 1 if fbout has dest
+ virtual char *get_desc() { return MOD_NAME; }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ void load_string(RString &s,unsigned char *data, int &pos, int len);
+ void save_string(unsigned char *data, int &pos, RString &text);
+
+ void dopoint(float &x, float &y, char visdata[2][2][576], int &color);
+
+ varType vars[EVAL_MAX_VARS];
+ NSEEL_CODEHANDLE codehandle,codehandle_b,codehandle_i,codehandle_f;
+ double *v_d;
+ double *v_r;
+ double *v_x;
+ double *v_y;
+ double *v_b;
+ double *v_red;
+ double *v_green;
+ double *v_blue;
+
+ int rectangular;
+ RString effect_exp[4];
+ int effect_exp_ch;
+ CRITICAL_SECTION rcs;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ rectangular=GET_INT(); pos+=4;
+ if (data[pos] == 1)
+ {
+ pos++;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ load_string(effect_exp[2],data,pos,len);
+ load_string(effect_exp[3],data,pos,len);
+ }
+ else
+ {
+ char buf[1025];
+ if (len-pos >= 1024)
+ {
+ memcpy(buf,data+pos,1024);
+ pos+=1024;
+ buf[1024]=0;
+ effect_exp[3].assign(buf+768);
+ buf[768]=0;
+ effect_exp[2].assign(buf+512);
+ buf[512]=0;
+ effect_exp[1].assign(buf+256);
+ buf[256]=0;
+ effect_exp[0].assign(buf);
+ }
+ }
+ effect_exp_ch=1;
+}
+
+void C_THISCLASS::load_string(RString &s,unsigned char *data, int &pos, int len) // read configuration of max length "len" from data.
+{
+ int size=GET_INT(); pos += 4;
+ if (size > 0 && len-pos >= size)
+ {
+ s.resize(size);
+ memcpy(s.get(), data+pos, size);
+ pos+=size;
+ }
+ else
+ {
+ s.resize(1);
+ s.get()[0]=0;
+ }
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(rectangular); pos+=4;
+ data[pos++]=1;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ save_string(data,pos,effect_exp[2]);
+ save_string(data,pos,effect_exp[3]);
+ return pos;
+}
+
+// special version that encodes with a 1 at the start.
+void C_THISCLASS::save_string(unsigned char *data, int &pos, RString &text)
+{
+ if (text.get() && text.get()[0])
+ {
+ int l=(strlen(text.get())+1);
+ PUT_INT(l); pos+=4;
+ memcpy(data+pos, text.get(), strlen(text.get())+1);
+ pos+=strlen(text.get())+1;
+ }
+ else
+ {
+ PUT_INT(0);
+ pos+=4;
+ }
+}
+
+C_THISCLASS::C_THISCLASS()
+{
+ rectangular=0;
+ codehandle=0;
+ codehandle_b=0;
+ codehandle_i=0;
+ codehandle_f=0;
+ memset(vars,0,sizeof(vars));
+ resetVars(vars);
+ v_d = registerVar("d");
+ v_r = registerVar("r");
+ v_x = registerVar("x");
+ v_y = registerVar("y");
+ v_b = registerVar("b");
+ v_red = registerVar("red");
+ v_green = registerVar("green");
+ v_blue = registerVar("blue");
+ resetVars(NULL);
+ effect_exp[0].assign("d=0.5;");
+ effect_exp[1].assign("");
+ effect_exp[2].assign("");
+ effect_exp[3].assign("");
+ effect_exp_ch=1;
+ InitializeCriticalSection(&rcs);
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ freeCode(codehandle);
+ freeCode(codehandle_b);
+ freeCode(codehandle_i);
+ freeCode(codehandle_f);
+ codehandle=0;
+ codehandle_b=0;
+ codehandle_i=0;
+ codehandle_f=0;
+ DeleteCriticalSection(&rcs);
+}
+
+void C_THISCLASS::dopoint(float &x, float &y, char visdata[2][2][576], int &color)
+{
+ *v_d=sqrt(x*x+y*y);
+ *v_r=atan2(y,x) + 3.14159*0.5;
+ *v_x=x;
+ *v_y=y;
+ *v_blue=(color&0xff)/255.0;
+ *v_green=((color>>8)&0xff)/255.0;
+ *v_red=((color>>16)&0xff)/255.0;
+
+ executeCode(codehandle,visdata);
+ if (rectangular)
+ {
+ x=*v_x;
+ y=*v_y;
+ }
+ else
+ {
+ *v_r -= 3.14159*0.5;
+ if (*v_r < 0.0) *v_r += 3.14159*2.0;
+ if (*v_r >= 3.14159*2.0) *v_r -= 3.14159*2.0;
+ x=cos(*v_r)* *v_d;
+ y=sin(*v_r)* *v_d;
+ }
+
+ int a=(int)(*v_blue * 255.0);
+ if (a>255) a=255;
+ if (a<0)a=0;
+ color=a;
+ a=(int)(*v_green * 255.0);
+ if (a>255) a=255;
+ if (a<0)a=0;
+ color|=a<<8;
+ a=(int)(*v_red * 255.0);
+ if (a>255) a=255;
+ if (a<0)a=0;
+ color|=a<<16;
+
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // returns 1 if fbout has dest
+{
+ if (isBeat&0x80000000) return 0;
+
+ if (effect_exp_ch || !codehandle)
+ {
+ EnterCriticalSection(&rcs);
+ memset(vars,0,sizeof(vars));
+ resetVars(vars);
+ if (codehandle) freeCode(codehandle);
+ if (codehandle_b) freeCode(codehandle_b);
+ if (codehandle_i) freeCode(codehandle_i);
+ if (codehandle_f) freeCode(codehandle_f);
+ codehandle=compileCode(effect_exp[0].get());
+ codehandle_i=compileCode(effect_exp[1].get());
+ codehandle_f=compileCode(effect_exp[2].get());
+ codehandle_b=compileCode(effect_exp[3].get());
+ effect_exp_ch=0;
+ resetVars(NULL);
+ LeaveCriticalSection(&rcs);
+ executeCode(codehandle_i,visdata);
+ }
+ executeCode(codehandle_f,visdata);
+ if (isBeat)
+ executeCode(codehandle_b,visdata);
+ if (codehandle)
+ {
+ *v_b=isBeat?1.0:0.0;
+ int x,num=g_laser_linelist->GetUsedLines();
+ LineType *l=g_laser_linelist->GetLineList();
+ for (x = 0; x < num; x ++)
+ {
+ dopoint(l->x1,l->y1,visdata,l->color);
+ if (l->mode == 0) dopoint(l->x2,l->y2,visdata,l->color);
+ l++;
+ }
+ }
+ return 0;
+}
+
+C_RBASE *RLASER_Transform(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+ isstart=0;
+ if (g_this->rectangular)
+ CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if ((
+ LOWORD(wParam) == IDC_EDIT1 ||
+ LOWORD(wParam) == IDC_EDIT2 ||
+ LOWORD(wParam) == IDC_EDIT3 ||
+ LOWORD(wParam) == IDC_EDIT4
+
+ )
+ && HIWORD(wParam) == EN_CHANGE)
+ {
+ if (!isstart)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
+ g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
+ g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
+ g_this->effect_exp_ch=1;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ }
+ if (LOWORD(wParam) == IDC_CHECK3)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->rectangular=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
+ g_this->effect_exp_ch=1;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_LASER_TRANSFORM,hwndParent,g_DlgProc);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/linedraw.cpp b/Src/Plugins/Visualization/vis_avs/linedraw.cpp
new file mode 100644
index 00000000..f6ec9de3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/linedraw.cpp
@@ -0,0 +1,261 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include "r_defs.h"
+#include <math.h>
+
+#define SWAP(x,y,temp) ( temp ) = ( x ); ( x ) = ( y ); ( y ) = ( temp )
+#define ABS(x) (( x ) < 0 ? - ( x ) : ( x ))
+
+void line(int *fb, int x1,int y1,int x2,int y2, int width, int height, int color, int lw)
+{
+ int dy = ABS(y2-y1);
+ int dx = ABS(x2-x1);
+
+#ifdef LASER
+ lw=1;
+ #define BLEND_LINE(fb,color) (*(fb)=BLEND(*(fb),(color)))
+#else
+ if (lw<1) lw=1;
+ else if (lw>255)lw=255;
+#endif
+
+ int lw2=lw/2;
+ if (!dx) // optimize vertical draw
+ {
+ x1-=lw2;
+ if (x1+lw >= 0 && x1 < width)
+ {
+ int d=max(min(y1,y2),0);
+ int ye=min(max(y1,y2),height-1);
+ if (x1<0)
+ {
+ lw+=x1;
+ x1=0;
+ }
+ if (x1+lw >= width) lw=width-x1;
+ fb += d*width+x1;
+ width-=lw;
+ if (lw>0) while (d++ < ye)
+ {
+ int x=lw;
+ while (x--) { BLEND_LINE(fb, color); fb++; }
+ fb+=width;
+ }
+ }
+ return;
+ }
+ if (y1==y2) // optimize horizontal draw.
+ {
+ y1-=lw2;
+ if (y1+lw >= 0 && y1 < height)
+ {
+ int d=max(min(x1,x2),0);
+ int xe=min(max(x1,x2),width-1);
+ if (y1<0)
+ {
+ lw+=y1;
+
+
+ y1=0;
+ }
+ if (y1+lw >= height) lw=height-y1;
+ fb+=y1*width+d;
+ width-=xe-d;
+ int y=lw;
+ while (y--)
+ {
+ int lt=d;
+ while (lt++<xe) { BLEND_LINE(fb,color); fb++; }
+ fb+=width;
+ }
+ }
+ return;
+ }
+
+ if (dy <= dx) // x major, low slope
+ {
+ // first things first for better line drawing, let's see if we can't get the
+ // width calculated right.
+ // lw is the width in pixels. if dy = 0, then lw=lw. if dy=dx, then:
+ /*
+
+
+ __________ C=30d
+ |\
+ | \ lw
+ | \_____ A=90d
+ ? | /
+ | / pc2
+ |/ ____ B = 60d
+
+ tan(C) = sin(C)/cos(C) = (dy / dx)
+ cos(C) = lw / ?
+
+ sin(C)/(lw / ? ) = (dy / dx)
+ sin(C) * ? / lw = (dy/dx)
+ sin(C) * ? = lw * dy/dx;
+ ? = lw * dy/dx / sin(C)
+
+
+ cos(C) = lw / ? === ? = lw / cos(C)
+ tan(C) = dy / dx;
+
+ C = atan2(dy,dx);
+ ? = lw / cos(C)
+
+ */
+
+#if 0// lame
+ if (lw>1 && (GetAsyncKeyState(VK_SHIFT)&0x8000)){
+ double d=atan2((double)dy,(double)dx);
+ lw = (int) (lw / cos(d));
+ if (lw<1)lw=1;
+ }
+#endif
+
+
+ if (x2 < x1)
+ {
+ int temp;
+ SWAP(x1,x2,temp);
+ SWAP(y1,y2,temp);
+ }
+
+ int yincr = y2>y1?1:-1;
+ int offsincr= y2>y1?width:-width;
+ y1-=lw2;
+ int offs = y1 * width + x1;
+ int d = dy + dy - dx;
+ int Eincr = dy + dy;
+ int NEincr = d - dx;
+ if (x2 >= 0 && x1 < width)
+ {
+ if (x1<0)
+ {
+ int v;
+ v=yincr * -x1;
+ if (dx) v= (v * dy)/dx;
+
+ y1 += v;
+ offs += v*width - x1;
+ x1=0;
+ }
+
+ if (x2 > width) x2=width;
+ while (x1<x2)
+ {
+ int yp=y1;
+ int ype=y1+lw;
+ int *newfb=fb+offs;
+ if (yp < 0)
+ {
+ newfb-=yp*width;
+ yp=0;
+ }
+ if (ype>height) ype=height;
+ while (yp++ < ype)
+ {
+ BLEND_LINE(newfb,color);
+ newfb+=width;
+ }
+ if (d < 0) d += Eincr;
+ else
+ {
+ d += NEincr;
+ y1 += yincr;
+ offs += offsincr;
+ }
+ offs++;
+ x1++;
+ }
+ }
+ }
+ else
+ {
+#if 0//lame
+ if (lw>1 && (GetAsyncKeyState(VK_SHIFT)&0x8000)){
+ double d=atan2((double)dx,(double)dy);
+ lw = (int) (lw / cos(d));
+ if (lw<1)lw=1;
+ }
+#endif
+ if (y2 < y1)
+ {
+ int temp;
+ SWAP(x1,x2,temp);
+ SWAP(y1,y2,temp);
+ }
+
+ int yincr=(x2>x1)?1:-1;
+ int d = dx + dx - dy;
+ int Eincr = dx + dx;
+ int NEincr = d - dy;
+ x1-=lw2;
+ int offs = y1 * width + x1;
+ if (y2 >= 0 && y1 < height)
+ {
+ if (y1<0)
+ {
+ int v;
+ v=yincr * -y1;
+ if (dy) v= (v * dx)/dy;
+
+ x1 += v;
+ offs += v - y1*width;
+ y1=0;
+ }
+ if (y2 > height) y2 = height;
+ while (y1 < y2)
+ {
+ int xp=x1;
+ int xpe=x1+lw;
+ int *newfb=fb+offs;
+ if (xp<0)
+ {
+ newfb-=xp;
+ xp=0;
+ }
+ if (xpe > width) xpe=width;
+ while (xp++ < xpe) { BLEND_LINE(newfb, color); newfb++; }
+
+ if (d < 0) d += Eincr;
+ else
+ {
+ d += NEincr;
+ x1 += yincr;
+ offs += yincr;
+ }
+ offs += width;
+ y1++;
+ }
+ }
+ }
+}
diff --git a/Src/Plugins/Visualization/vis_avs/main.cpp b/Src/Plugins/Visualization/vis_avs/main.cpp
new file mode 100644
index 00000000..05b16d5c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/main.cpp
@@ -0,0 +1,604 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <math.h>
+#include <process.h>
+#include "draw.h"
+#include "wnd.h"
+#include "r_defs.h"
+#include "render.h"
+#include "vis.h"
+#include "cfgwnd.h"
+#include "resource.h"
+#include "bpm.h"
+#include "api.h"
+#include "../winamp/wa_ipc.h"
+#include "../Agave/Language/api_language.h"
+#include <api/service/waServiceFactory.h>
+
+#include <stdio.h>
+
+#ifdef REAPLAY_PLUGIN
+#include "../../jmde/reaper_plugin.h"
+const char *(*get_ini_file)();
+int (*vuGetVisData)(char *vdata, int size);
+#endif
+
+#define PLUGIN_VERSION "v2.93"
+
+#include "avs_eelif.h"
+
+extern void GetClientRect_adj(HWND hwnd, RECT *r);
+
+static unsigned char g_logtab[256];
+HINSTANCE g_hInstance;
+
+/* char *verstr=
+#ifndef LASER
+"Advanced Visualization Studio"
+#else
+"AVS/Laser"
+#endif
+" v2.92"
+;
+*/
+
+static unsigned int WINAPI RenderThread(LPVOID a);
+
+static void config(struct winampVisModule *this_mod);
+static int init(struct winampVisModule *this_mod);
+static int render(struct winampVisModule *this_mod);
+static void quit(struct winampVisModule *this_mod);
+
+HANDLE g_hThread;
+volatile int g_ThreadQuit;
+
+static CRITICAL_SECTION g_cs;
+
+static unsigned char g_visdata[2][2][576];
+static int g_visdata_pstat;
+
+/* wasabi based services for localisation support */
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+static char module1[128];
+
+static winampVisModule *getModule(int which);
+static winampVisHeader hdr = { VIS_HDRVER, 0, getModule };
+
+// use this to get our own HINSTACE since overriding DllMain(..) causes instant crashes (should see why)
+
+static HINSTANCE GetMyInstance()
+{
+ MEMORY_BASIC_INFORMATION mbi = {0};
+ if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
+ return (HINSTANCE)mbi.AllocationBase;
+ return NULL;
+}
+
+extern "C" {
+ __declspec( dllexport ) winampVisHeader* winampVisGetHeader(HWND hwndParent)
+ {
+ if(!WASABI_API_LNG_HINST)
+ {
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessage(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(GetMyInstance(),VisAVSLangGUID);
+ }
+
+ #ifndef LASER
+ static char szDescription[256];
+ wsprintfA(szDescription,"%s " PLUGIN_VERSION,WASABI_API_LNGSTRING_BUF(IDS_AVS,module1,128));
+ hdr.description = szDescription;
+ #else
+ hdr.description = "AVS/Laser "PLUGIN_VERSION;
+ #endif
+
+ return &hdr;
+ }
+}
+
+static winampVisModule *getModule(int which)
+{
+ static winampVisModule mod =
+ {
+#ifdef LASER
+ "Advanced Visualization Studio/Laser",
+#else
+ module1,
+#endif
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ 0, // sRate
+ 0, // nCh
+ 1000/70, // latencyMS
+ 1000/70,// delayMS
+ 2, // spectrumNch
+ 2, // waveformNch
+ { 0, }, // spectrumData
+ { 0, }, // waveformData
+ config,
+ init,
+ render,
+ quit
+ };
+ if (which==0) return &mod;
+ return 0;
+}
+
+void about(HWND hwndParent)
+
+ {
+ static int about_here = 0;
+ char aboutbuf[1024] = {0}, aboutTitle[48] = {0};
+ if (about_here)
+ {
+ SetActiveWindow(FindWindow("#32770",WASABI_API_LNGSTRING_BUF(IDS_ABOUT_AVS,aboutTitle,48)));
+ return;
+ }
+ about_here = 1;
+ wsprintf(aboutbuf,WASABI_API_LNGSTRING(IDS_ABOUT_STRING),hdr.description);
+ MessageBox(hwndParent,aboutbuf,WASABI_API_LNGSTRING_BUF(IDS_ABOUT_AVS,aboutTitle,48),0);
+ about_here = 0;
+}
+
+HWND GetDialogBoxParent(HWND winamp)
+{
+ HWND parent = (HWND)SendMessage(winamp, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
+ if (!parent || parent == (HWND)1)
+ return winamp;
+ return parent;
+
+/*
+BOOL CALLBACK aboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hwndDlg,IDC_VERSTR,verstr);
+
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDOK: case IDCANCEL:
+ EndDialog(hwndDlg,0);
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+*/
+
+}
+
+static void config(struct winampVisModule *this_mod)
+{
+ if (!g_hwnd || !IsWindow(g_hwnd))
+ {
+ about(GetDialogBoxParent(this_mod->hwndParent));
+// DialogBox(this_mod->hDllInstance,MAKEINTRESOURCE(IDD_DIALOG2),this_mod->hwndParent,aboutProc);
+ }
+ else
+ {
+ SendMessage(g_hwnd,WM_USER+33,0,0);
+ }
+}
+
+CRITICAL_SECTION g_render_cs;
+static int g_is_beat;
+char g_path[1024];
+
+int beat_peak1,beat_peak2, beat_cnt,beat_peak1_peak;
+
+void main_setRenderThreadPriority()
+{
+ int prios[]={
+ GetThreadPriority(GetCurrentThread()),
+ THREAD_PRIORITY_IDLE,
+ THREAD_PRIORITY_LOWEST,
+ THREAD_PRIORITY_NORMAL,
+ THREAD_PRIORITY_HIGHEST,
+ };
+ SetThreadPriority(g_hThread,prios[cfg_render_prio]);
+}
+
+extern void previous_preset(HWND hwnd);
+extern void next_preset(HWND hwnd);
+extern void random_preset(HWND hwnd);
+
+#if 0//syntax highlighting
+HINSTANCE hRich;
+#endif
+
+static int init(struct winampVisModule *this_mod)
+{
+ DWORD id;
+ FILETIME ft;
+#if 0//syntax highlighting
+ if (!hRich) hRich=LoadLibrary("RICHED32.dll");
+#endif
+ GetSystemTimeAsFileTime(&ft);
+ srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
+ g_hInstance=this_mod->hDllInstance;
+ GetModuleFileName(g_hInstance,g_path,MAX_PATH);
+ char *p=g_path+strlen(g_path);
+ while (p > g_path && *p != '\\') p--;
+ *p = 0;
+
+#ifdef WA2_EMBED
+ if (SendMessage(this_mod->hwndParent,WM_USER,0,0) < 0x2900)
+ {
+ char title[16];
+ MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_REQUIRES_2_9_PLUS),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,16),MB_OK|MB_ICONSTOP);
+ return 1;
+ }
+#endif
+
+#ifndef NO_MMX
+ extern int is_mmx(void);
+ if (!is_mmx())
+ {
+ char title[16];
+ MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_NO_MMX_SUPPORT),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,16),MB_OK|MB_ICONSTOP);
+ return 1;
+ }
+#endif
+
+#ifdef LASER
+ strcat(g_path,"\\avs_laser");
+#else
+ strcat(g_path,"\\avs");
+#endif
+ CreateDirectory(g_path,NULL);
+
+ InitializeCriticalSection(&g_cs);
+ InitializeCriticalSection(&g_render_cs);
+ g_ThreadQuit=0;
+ g_visdata_pstat=1;
+
+ AVS_EEL_IF_init();
+
+ if (Wnd_Init(this_mod)) return 1;
+
+ {
+ int x;
+ for (x = 0; x < 256; x ++)
+ {
+ double a=log((double)x*60.0/255.0 + 1.0)/log(60.0);
+ int t=(int)(a*255.0);
+ if (t<0)t=0;
+ if (t>255)t=255;
+ g_logtab[x]=(unsigned char )t;
+ }
+ }
+
+ initBpm();
+
+ Render_Init(g_hInstance);
+
+ CfgWnd_Create(this_mod);
+
+ g_hThread=(HANDLE)_beginthreadex(NULL,0,RenderThread,0,0,(unsigned int *)&id);
+ main_setRenderThreadPriority();
+ SetForegroundWindow(g_hwnd);
+ SetFocus(g_hwnd);
+
+ return 0;
+}
+
+static int render(struct winampVisModule *this_mod)
+{
+ int x,avs_beat=0,b;
+ if (g_ThreadQuit) return 1;
+ EnterCriticalSection(&g_cs);
+ if (g_ThreadQuit)
+ {
+ LeaveCriticalSection(&g_cs);
+ return 1;
+ }
+ if (g_visdata_pstat)
+ for (x = 0; x< 576*2; x ++)
+ g_visdata[0][0][x]=g_logtab[(unsigned char)this_mod->spectrumData[0][x]];
+ else
+ {
+ for (x = 0; x < 576*2; x ++)
+ {
+ int t=g_logtab[(unsigned char)this_mod->spectrumData[0][x]];
+ if (g_visdata[0][0][x] < t)
+ g_visdata[0][0][x] = t;
+ }
+ }
+ memcpy(&g_visdata[1][0][0],this_mod->waveformData,576*2);
+ {
+ int lt[2]={0,0};
+ int x;
+ int ch;
+ for (ch = 0; ch < 2; ch ++)
+ {
+ unsigned char *f=(unsigned char*)&this_mod->waveformData[ch][0];
+ for (x = 0; x < 576; x ++)
+ {
+ int r= *f++^128;
+ r-=128;
+ if (r<0)r=-r;
+ lt[ch]+=r;
+ }
+ }
+ lt[0]=max(lt[0],lt[1]);
+
+ beat_peak1=(beat_peak1*125+beat_peak2*3)/128;
+
+ beat_cnt++;
+
+ if (lt[0] >= (beat_peak1*34)/32 && lt[0] > (576*16))
+ {
+ if (beat_cnt>0)
+ {
+ beat_cnt=0;
+ avs_beat=1;
+ }
+ beat_peak1=(lt[0]+beat_peak1_peak)/2;
+ beat_peak1_peak=lt[0];
+ }
+ else if (lt[0] > beat_peak2)
+ {
+ beat_peak2=lt[0];
+ }
+ else beat_peak2=(beat_peak2*14)/16;
+
+ }
+ b=refineBeat(avs_beat);
+ if (b) g_is_beat=1;
+ g_visdata_pstat=0;
+ LeaveCriticalSection(&g_cs);
+ return 0;
+}
+
+static void quit(struct winampVisModule *this_mod)
+{
+#define DS(x)
+ //MessageBox(this_mod->hwndParent,x,"AVS Debug",MB_OK)
+ if (g_hThread)
+ {
+ DS("Waitin for thread to quit\n");
+ g_ThreadQuit=1;
+ if (WaitForSingleObject(g_hThread,10000) != WAIT_OBJECT_0)
+ {
+ DS("Terminated thread (BAD!)\n");
+ //MessageBox(NULL,"error waiting for thread to quit","a",MB_TASKMODAL);
+ TerminateThread(g_hThread,0);
+ }
+ DS("Thread done... calling ddraw_quit\n");
+ DDraw_Quit();
+
+ DS("Calling cfgwnd_destroy\n");
+ CfgWnd_Destroy();
+ DS("Calling render_quit\n");
+ Render_Quit(this_mod->hDllInstance);
+
+ DS("Calling wnd_quit\n");
+ Wnd_Quit();
+
+ DS("closing thread handle\n");
+ CloseHandle(g_hThread);
+ g_hThread=NULL;
+
+ DS("calling eel quit\n");
+ AVS_EEL_IF_quit();
+
+ DS("cleaning up critsections\n");
+ DeleteCriticalSection(&g_cs);
+ DeleteCriticalSection(&g_render_cs);
+
+ DS("smp_cleanupthreads\n");
+ C_RenderListClass::smp_cleanupthreads();
+ }
+#undef DS
+#if 0//syntax highlighting
+ if (hRich) FreeLibrary(hRich);
+ hRich=0;
+#endif
+}
+
+#define FPS_NF 64
+
+static unsigned int WINAPI RenderThread(LPVOID a)
+{
+ int framedata[FPS_NF]={0,};
+ int framedata_pos=0;
+ int s=0;
+ char vis_data[2][2][576];
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
+ while (!g_ThreadQuit)
+ {
+ int w,h,*fb=NULL, *fb2=NULL,beat=0;
+
+#ifdef REAPLAY_PLUGIN
+ if(!IsWindowVisible(g_hwnd))
+ {
+ Sleep(1);
+ continue;
+ }
+
+ char visdata[576*2*2];
+ int ret = vuGetVisData(visdata, sizeof(visdata));
+ if (!ret)
+ {
+ memset(&vis_data[0][0][0],0,576*2*2);
+ beat=0;
+ }
+ else
+ {
+ int x;
+ unsigned char *v=(unsigned char *)visdata;
+ for (x = 0; x < 576*2; x ++)
+ vis_data[0][0][x]=g_logtab[*v++];
+ for (x = 0; x < 576*2; x ++)
+ ((unsigned char *)vis_data[1][0])[x]=*v++;
+
+ v=(unsigned char *)visdata+1152;
+ {
+ int lt[2]={0,0};
+ int ch;
+ for (ch = 0; ch < 2; ch ++)
+ {
+ for (x = 0; x < 576; x ++)
+ {
+ int r=*v++^128;
+ r-=128;
+ if (r<0)r=-r;
+ lt[ch]+=r;
+ }
+ }
+ lt[0]=max(lt[0],lt[1]);
+
+ beat_peak1=(beat_peak1*125+beat_peak2*3)/128;
+ beat_cnt++;
+
+ if (lt[0] >= (beat_peak1*34)/32 && lt[0] > (576*16))
+ {
+ if (beat_cnt>0)
+ {
+ beat_cnt=0;
+ beat=1;
+ }
+ beat_peak1=(lt[0]+beat_peak1_peak)/2;
+ beat_peak1_peak=lt[0];
+ }
+ else if (lt[0] > beat_peak2)
+ {
+ beat_peak2=lt[0];
+ }
+ else beat_peak2=(beat_peak2*14)/16;
+
+ }
+// EnterCriticalSection(&g_title_cs);
+ beat=refineBeat(beat);
+// LeaveCriticalSection(&g_title_cs);
+ }
+#else
+ EnterCriticalSection(&g_cs);
+ memcpy(&vis_data[0][0][0],&g_visdata[0][0][0],576*2*2);
+ g_visdata_pstat=1;
+ beat=g_is_beat;
+ g_is_beat=0;
+ LeaveCriticalSection(&g_cs);
+#endif
+
+ if (!g_ThreadQuit)
+ {
+ if (IsWindow(g_hwnd)&&!g_in_destroy) DDraw_Enter(&w,&h,&fb,&fb2);
+ else break;
+ if (fb&&fb2)
+ {
+ extern int g_dlg_w, g_dlg_h, g_dlg_fps;
+#ifdef LASER
+ g_laser_linelist->ClearLineList();
+#endif
+
+ EnterCriticalSection(&g_render_cs);
+ int t=g_render_transition->render(vis_data,beat,s?fb2:fb,s?fb:fb2,w,h);
+ LeaveCriticalSection(&g_render_cs);
+ if (t&1) s^=1;
+
+#ifdef LASER
+ s=0;
+ memset(fb,0,w*h*sizeof(int));
+ LineDrawList(g_laser_linelist,fb,w,h);
+#endif
+ if (IsWindow(g_hwnd)) DDraw_Exit(s);
+
+ int lastt=framedata[framedata_pos];
+ int thist=GetTickCount();
+ framedata[framedata_pos]=thist;
+ g_dlg_w=w;
+ g_dlg_h=h;
+ if (lastt)
+ {
+ g_dlg_fps=MulDiv(sizeof(framedata)/sizeof(framedata[0]),10000,thist-lastt);
+ }
+ framedata_pos++;
+ if (framedata_pos >= sizeof(framedata)/sizeof(framedata[0])) framedata_pos=0;
+
+ }
+ int fs=DDraw_IsFullScreen();
+ int sv=(fs?(cfg_speed>>8):cfg_speed)&0xff;
+ Sleep(min(max(sv,1),100));
+ }
+ }
+ _endthreadex(0);
+ return 0;
+}
+
+#ifdef REAPLAY_PLUGIN
+static winampVisModule dummyMod;
+extern "C"
+{
+
+ REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(REAPER_PLUGIN_HINSTANCE hInstance, reaper_plugin_info_t *rec)
+ {
+ g_hInstance=hInstance;
+ if (rec)
+ {
+ if (rec->caller_version != REAPER_PLUGIN_VERSION || !rec->GetFunc)
+ return 0;
+
+ *((void **)&get_ini_file) = rec->GetFunc("get_ini_file");
+ *((void **)&vuGetVisData) = rec->GetFunc("vuGetVisData");
+ if (!get_ini_file || !vuGetVisData)
+ return 0;
+
+ dummyMod.hwndParent=rec->hwnd_main;
+ dummyMod.hDllInstance=g_hInstance;
+ init(&dummyMod);
+
+ return 1;
+ }
+ else
+ {
+ quit(&dummyMod);
+ return 0;
+ }
+ }
+
+};
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/matrix.cpp b/Src/Plugins/Visualization/vis_avs/matrix.cpp
new file mode 100644
index 00000000..8b567f2a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/matrix.cpp
@@ -0,0 +1,74 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <math.h>
+#include "r_defs.h"
+
+void matrixRotate(float matrix[], char m, float Deg) {
+ char m1, m2;
+ float c,s;
+ Deg *= 3.141592653589f / 180.0f;
+ memset(matrix,0,sizeof(float)*16);
+ matrix[((m-1)<<2)+m-1] = matrix[15] = 1.0f;
+ m1 = (m % 3);
+ m2 = ((m1+1) % 3);
+ c = (float)cos(Deg); s = (float)sin(Deg);
+ matrix[(m1<<2)+m1]=c; matrix[(m1<<2)+m2]=s;
+ matrix[(m2<<2)+m2]=c; matrix[(m2<<2)+m1]=-s;
+}
+
+void matrixTranslate(float m[], float x, float y, float z) {
+ memset(m,0,sizeof(float)*16);
+ m[0] = m[4+1] = m[8+2] = m[12+3] = 1.0f;
+ m[0+3] = x; m[4+3] = y; m[8+3] = z;
+}
+
+void matrixMultiply(float *dest, float src[]) {
+ float temp[16];
+ int i;
+ memcpy(temp,dest,sizeof(float)*16);
+ for (i = 0; i < 16; i += 4) {
+ *dest++ = src[i+0]*temp[(0<<2)+0]+src[i+1]*temp[(1<<2)+0]+
+ src[i+2]*temp[(2<<2)+0]+src[i+3]*temp[(3<<2)+0];
+ *dest++ = src[i+0]*temp[(0<<2)+1]+src[i+1]*temp[(1<<2)+1]+
+ src[i+2]*temp[(2<<2)+1]+src[i+3]*temp[(3<<2)+1];
+ *dest++ = src[i+0]*temp[(0<<2)+2]+src[i+1]*temp[(1<<2)+2]+
+ src[i+2]*temp[(2<<2)+2]+src[i+3]*temp[(3<<2)+2];
+ *dest++ = src[i+0]*temp[(0<<2)+3]+src[i+1]*temp[(1<<2)+3]+
+ src[i+2]*temp[(2<<2)+3]+src[i+3]*temp[(3<<2)+3];
+ }
+}
+
+void matrixApply(float *m, float x, float y, float z,
+ float *outx, float *outy, float *outz) {
+ *outx = x*m[0] + y*m[1] + z*m[2] + m[3];
+ *outy = x*m[4] + y*m[5] + z*m[6] + m[7];
+ *outz = x*m[8] + y*m[9] + z*m[10] + m[11];
+}
diff --git a/Src/Plugins/Visualization/vis_avs/movement.bin b/Src/Plugins/Visualization/vis_avs/movement.bin
new file mode 100644
index 00000000..d68ca743
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/movement.bin
@@ -0,0 +1,5 @@
+Movement help goes here (send me some :) )
+
+To use the custom table, modify r,d,x or y.
+Rect coords: x,y are in (-1..1) . Otherwise: d is (0..1) and r is (0..2PI).
+You can also access 'sw' and 'sh' for screen dimensions in pixels (might be useful) \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/peices.bmp b/Src/Plugins/Visualization/vis_avs/peices.bmp
new file mode 100644
index 00000000..ddb7609f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/peices.bmp
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_avs/r_avi.cpp b/Src/Plugins/Visualization/vis_avs/r_avi.cpp
new file mode 100644
index 00000000..fd52ff32
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_avi.cpp
@@ -0,0 +1,383 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+
+#define MOD_NAME "Render / AVI"
+#define C_THISCLASS C_AVIClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ void reinit(int, int);
+ void loadAvi(char *name);
+ void closeAvi(void);
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_AVI,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int enabled;
+ char ascName[MAX_PATH];
+ int lastWidth, lastHeight;
+ HDRAWDIB hDrawDib;
+ PAVISTREAM PAVIVideo;
+ PGETFRAME PgetFrame;
+ HBITMAP hRetBitmap;
+ HBITMAP hOldBitmap;
+ HDC hDesktopDC;
+ HDC hBitmapDC;
+ LPBITMAPINFOHEADER lpFrame;
+ BITMAPINFO bi;
+ int blend, blendavg, adapt, persist;
+ int loaded, rendering;
+ int lFrameIndex;
+ int length;
+ unsigned int speed;
+ unsigned int lastspeed;
+ int *old_image,old_image_w,old_image_h;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ AVIFileInit ( ) ;
+ hDrawDib = DrawDibOpen ( ) ;
+ lastWidth=0;
+ lastHeight=0;
+ lFrameIndex=0;
+ loaded=0;
+ rendering=0;
+ length=0;
+ blend=0;
+ adapt=0;
+ blendavg=1;
+ persist=6;
+ enabled=1;
+ speed=0;
+ lastspeed=0;
+ old_image=NULL; old_image_h=0; old_image_w=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ closeAvi();
+ SelectObject (hBitmapDC, hOldBitmap);
+ DeleteDC (hBitmapDC);
+ ReleaseDC (NULL, hDesktopDC);
+ AVIFileExit ( );
+ DrawDibClose (hDrawDib);
+ if(old_image) {
+ GlobalFree(old_image);
+ old_image=NULL;
+ old_image_h=old_image_w=0;
+ }
+}
+
+void C_THISCLASS::loadAvi(char *name)
+{
+ char pathfile[MAX_PATH];
+
+ if (loaded) closeAvi();
+
+ wsprintf(pathfile,"%s\\%s",g_path, name);
+
+ if (AVIStreamOpenFromFile ((PAVISTREAM FAR *) &PAVIVideo, pathfile, streamtypeVIDEO, 0, OF_READ | OF_SHARE_EXCLUSIVE, NULL) != 0)
+ {
+ // MessageBox(NULL, "An error occured while trying to open a file. Effect is disabled", "Warning", 0);
+ return;
+ }
+ PgetFrame = AVIStreamGetFrameOpen (PAVIVideo, NULL);
+ length = AVIStreamLength(PAVIVideo);
+ lFrameIndex = 0;
+
+ lpFrame = (LPBITMAPINFOHEADER) AVIStreamGetFrame (PgetFrame, 0);
+
+ reinit(lastWidth, lastHeight);
+
+ loaded=1;
+}
+
+void C_THISCLASS::closeAvi(void)
+{
+if (loaded)
+ {
+ while (rendering);
+ loaded=0;
+ AVIStreamGetFrameClose (PgetFrame);
+ AVIStreamRelease (PAVIVideo);
+ }
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ char *p=ascName;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ while (data[pos] && len-pos > 0 && p-ascName < sizeof(ascName)-1) *p++=data[pos++];
+ *p=0; pos++;
+ if (len-pos >= 4) { adapt=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { persist=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { speed=GET_INT(); pos+=4; }
+
+ if (*ascName)
+ loadAvi(ascName);
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ strcpy((char *)data+pos, ascName);
+ pos+=strlen(ascName)+1;
+ PUT_INT(adapt); pos+=4;
+ PUT_INT(persist); pos+=4;
+ PUT_INT(speed); pos+=4;
+ return pos;
+}
+
+
+void C_THISCLASS::reinit(int w, int h)
+{
+if (lastWidth || lastHeight)
+ {
+ SelectObject (hBitmapDC, hOldBitmap);
+ DeleteDC (hBitmapDC);
+ ReleaseDC (NULL, hDesktopDC);
+ }
+
+ hDesktopDC = GetDC (NULL);
+ hRetBitmap = CreateCompatibleBitmap (hDesktopDC, w, h);
+ hBitmapDC = CreateCompatibleDC (hDesktopDC);
+ hOldBitmap = (HBITMAP) SelectObject (hBitmapDC, hRetBitmap);
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = w;
+ bi.bmiHeader.biHeight = h;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 0;
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+ bi.bmiHeader.biClrImportant = 0;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int *p,*d;
+ int i,j;
+ static int persistCount=0;
+
+ if (!enabled || !loaded) return 0;
+
+ if(h!=old_image_h||w!=old_image_w) {
+ if(old_image)
+ GlobalFree(old_image);
+ old_image=(int *)GlobalAlloc(GMEM_FIXED,sizeof(int)*w*h);
+ old_image_h=h; old_image_w=w;
+ }
+
+ if((lastspeed+speed)>GetTickCount()) {
+ memcpy(fbout,old_image,sizeof(int)*w*h);
+ } else {
+ lastspeed=GetTickCount();
+
+ rendering=1;
+
+ if (lastWidth != w || lastHeight != h)
+ {
+ lastWidth = w;
+ lastHeight = h;
+ reinit(w, h);
+ }
+ if (isBeat&0x80000000) return 0;
+
+ if (!length) return 0;
+
+ lFrameIndex %= length;
+ lpFrame = (LPBITMAPINFOHEADER) AVIStreamGetFrame (PgetFrame, lFrameIndex++);
+ DrawDibDraw (hDrawDib, hBitmapDC, 0, 0, lastWidth, lastHeight, lpFrame,
+ NULL, 0, 0, (int) lpFrame ->biWidth, (int) lpFrame ->biHeight, 0);
+ GetDIBits(hBitmapDC, hRetBitmap, 0, h, (void *)fbout, &bi, DIB_RGB_COLORS);
+ rendering=0;
+ memcpy(old_image,fbout,sizeof(int)*w*h);
+ }
+
+ if (isBeat)
+ persistCount=persist;
+ else
+ if (persistCount>0) persistCount--;
+
+ p = fbout;
+ d = framebuffer+w*(h-1);
+ if (blend || (adapt && (isBeat || persistCount)))
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ *d=BLEND(*p, *d);
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+ else
+ if (blendavg || adapt)
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ *d=BLEND_AVG(*p, *d);
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+ else
+ for (i=0;i<h;i++)
+ {
+ memcpy(d, p, w*4);
+ p+=w;
+ d-=w;
+ }
+
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+static void EnableWindows(HWND hwndDlg)
+{
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST),g_ConfigThis->adapt);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST_TITLE),g_ConfigThis->adapt);
+}
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_SETRANGE, TRUE, MAKELONG(0, 32));
+ SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_SETPOS, TRUE, g_ConfigThis->persist);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETTICFREQ, 50, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, TRUE, MAKELONG(0, 1000));
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, g_ConfigThis->speed);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (g_ConfigThis->adapt) CheckDlgButton(hwndDlg,IDC_ADAPT,BST_CHECKED);
+ if (!g_ConfigThis->adapt && !g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ EnableWindows(hwndDlg);
+ loadComboBox(GetDlgItem(hwndDlg,OBJ_COMBO),"*.AVI",g_ConfigThis->ascName);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_PERSIST)
+ g_ConfigThis->persist = SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_SPEED)
+ g_ConfigThis->speed = SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0);
+ }
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_ADAPT) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->adapt=IsDlgButtonChecked(hwndDlg,IDC_ADAPT)?1:0;
+ EnableWindows(hwndDlg);
+ }
+ if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == OBJ_COMBO) // handle clicks to combo box
+ {
+ int sel = SendDlgItemMessage(hwndDlg, OBJ_COMBO, CB_GETCURSEL, 0, 0);
+ if (sel != -1)
+ {
+ SendDlgItemMessage(hwndDlg, OBJ_COMBO, CB_GETLBTEXT, sel, (LPARAM)g_ConfigThis->ascName);
+ if (*(g_ConfigThis->ascName))
+ g_ConfigThis->loadAvi(g_ConfigThis->ascName);
+ }
+ }
+ return 0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_AVI,hwndParent,g_DlgProc);
+}
+// export stuff
+
+C_RBASE *R_AVI(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else//!LASER
+C_RBASE *R_AVI(char *desc) { return NULL; }
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/r_blit.cpp b/Src/Plugins/Visualization/vis_avs/r_blit.cpp
new file mode 100644
index 00000000..901df213
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_blit.cpp
@@ -0,0 +1,557 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+// highly optimized on 10/10/00 JF. MMX.
+
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+#define C_THISCLASS C_BlitClass
+#define MOD_NAME "Trans / Blitter Feedback"
+
+static const unsigned int revn[2]={0xff00ff,0xff00ff};//{0x1000100,0x1000100}; <<- this is actually more correct, but we're going for consistency vs. the non-mmx ver-jf
+static const int zero=0;
+
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BLITTER_FEEDBACK,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int scale, scale2, blend,beatch;
+ int fpos;
+ int subpixel;
+
+
+ int blitter_normal(int *framebuffer, int *fbout, int w, int h, int f_val);
+ int blitter_out(int *framebuffer, int *fbout, int w, int h, int f_val);
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { scale=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { scale2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatch=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
+ else subpixel=0;
+
+ fpos=scale;
+
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(scale); pos+=4;
+ PUT_INT(scale2); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(beatch); pos+=4;
+ PUT_INT(subpixel); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ scale=30;
+ scale2=30;
+ blend=0;
+ fpos=scale;
+ beatch=0;
+ subpixel=1;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::blitter_out(int *framebuffer, int *fbout, int w, int h, int f_val)
+{
+ const int adj=7;
+ int ds_x = ((f_val+(1<<adj)-32)<<(16-adj));
+ int x_len=((w<<16)/ds_x)&~3;
+ int y_len=(h<<16)/ds_x;
+
+ if (x_len >= w || y_len >= h) return 0;
+
+
+ int start_x=(w-x_len)/2;
+ int start_y=(h-y_len)/2;
+ int s_y=32768;
+
+ int *dest=(int *)framebuffer+start_y*w + start_x;
+ int *src=(int *)fbout+start_y*w + start_x;
+ int y;
+
+ fbout += start_y*w;
+ for (y = 0; y < y_len; y ++)
+ {
+ int s_x=32768;
+ unsigned int *src = ((unsigned int *) framebuffer)+(s_y>>16)*w;
+ unsigned int *old_dest=((unsigned int *)fbout) + start_x;
+ s_y+=ds_x;
+ if (!blend)
+ {
+ int x=x_len/4;
+ while (x--)
+ {
+ old_dest[0]=src[s_x>>16];
+ s_x += ds_x;
+ old_dest[1]=src[s_x>>16];
+ s_x += ds_x;
+ old_dest[2]=src[s_x>>16];
+ s_x += ds_x;
+ old_dest[3]=src[s_x>>16];
+ s_x += ds_x;
+ old_dest+=4;
+ }
+ }
+ else
+ {
+ unsigned int *s2=(unsigned int *)framebuffer+((y+start_y)*w)+start_x;
+ int x=x_len/4;
+ while (x--)
+ {
+ old_dest[0]=BLEND_AVG(s2[0],src[s_x>>16]);
+ s_x += ds_x;
+ old_dest[1]=BLEND_AVG(s2[1],src[s_x>>16]);
+ s_x += ds_x;
+ old_dest[2]=BLEND_AVG(s2[2],src[s_x>>16]);
+ s_x += ds_x;
+ old_dest[3]=BLEND_AVG(s2[3],src[s_x>>16]);
+ s2+=4;
+ old_dest+=4;
+ s_x += ds_x;
+ }
+ }
+ fbout += w;
+ }
+ for (y = 0; y < y_len; y ++)
+ {
+ memcpy(dest,src,x_len*sizeof(int));
+ dest+=w;
+ src+=w;
+ }
+
+ return 0;
+}
+
+
+
+int C_THISCLASS::blitter_normal(int *framebuffer, int *fbout, int w, int h, int f_val)
+{
+ int ds_x = ((f_val+32)<<16)/64;
+ int isx=(((w<<16)-((ds_x*w)))/2);
+ int s_y=(((h<<16)-((ds_x*h)))/2);
+
+ if (subpixel)
+ {
+ int y;
+ for (y = 0; y < h; y ++)
+ {
+ int s_x=isx;
+ unsigned int *src = ((unsigned int *) framebuffer)+(s_y>>16)*w;
+ int ypart=(s_y>>8)&0xff;
+ s_y+=ds_x;
+#ifdef NO_MMX
+ {
+ ypart=(ypart*255)>>8;
+ int x=w/4;
+ while (x--)
+ {
+ fbout[0]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
+ s_x += ds_x;
+ fbout[1]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
+ s_x += ds_x;
+ fbout[2]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
+ s_x += ds_x;
+ fbout[3]=BLEND4(src+(s_x>>16),w,(s_x>>8)&0xff,ypart);
+ s_x += ds_x;
+ fbout+=4;
+ }
+ }
+#else
+ {
+ __int64 mem5,mem7;
+ __asm
+ {
+ mov edi, fbout
+ mov esi, w
+
+ movd mm7, ypart
+ punpcklwd mm7,mm7
+
+ movq mm5, revn
+ punpckldq mm7,mm7
+
+ psubw mm5, mm7
+ mov ecx, esi
+
+ movq mem5,mm5
+ movq mem7,mm7
+
+ shr ecx, 1
+ mov edx, s_x
+
+ align 16
+ mmx_scale_loop1:
+
+ mov ebx, edx
+ mov eax, edx
+
+ shr eax, 14
+ add edx, ds_x
+
+ shr ebx, 8
+ and eax, ~3
+
+ add eax, src
+ and ebx, 0xff
+
+ movd mm6, ebx
+ //
+
+ movq mm4, revn
+ punpcklwd mm6,mm6
+
+ movd mm0, [eax]
+ punpckldq mm6,mm6
+
+ movd mm1, [eax+4]
+ psubw mm4, mm6
+
+ movd mm2, [eax+esi*4]
+ punpcklbw mm0, [zero]
+
+ movd mm3, [eax+esi*4+4]
+ pmullw mm0, mm4 // mm0 used in divide for 3 cycles
+
+ punpcklbw mm1, [zero]
+ mov eax, edx
+
+ pmullw mm1, mm6 // mm1 used in divide for 3 cycles
+ punpcklbw mm2, [zero]
+
+ pmullw mm2, mm4 // mm2 used in divide for 3 cycles
+ punpcklbw mm3, [zero]
+
+ pmullw mm3, mm6 // mm3 used in divide for 3 cycles
+ shr eax, 14
+
+ mov ebx, edx
+ and eax, ~3
+
+ paddw mm0, mm1
+ shr ebx, 8
+
+ psrlw mm0, 8
+ add eax, src
+
+ paddw mm2, mm3
+ and ebx, 0xff
+
+ pmullw mm0, mem5
+ psrlw mm2, 8
+
+ pmullw mm2, mem7
+ add edx, ds_x
+
+
+ movd mm6, ebx
+ //
+
+ movq mm4, revn
+ punpcklwd mm6,mm6
+
+
+ movd mm1, [eax+4]
+ //
+
+ movd mm7, [eax+esi*4]
+ paddw mm0, mm2
+
+ movd mm5, [eax]
+ psrlw mm0, 8
+
+ movd mm3, [eax+esi*4+4]
+ packuswb mm0, mm0
+
+ movd [edi], mm0
+ punpckldq mm6,mm6
+
+ //poop
+
+ punpcklbw mm5, [zero]
+ psubw mm4, mm6
+
+ punpcklbw mm1, [zero]
+ pmullw mm5, mm4
+
+ punpcklbw mm7, [zero]
+ pmullw mm1, mm6
+
+ punpcklbw mm3, [zero]
+ pmullw mm7, mm4
+
+ //cycle
+ //cycle
+
+ paddw mm5, mm1
+ //
+
+ pmullw mm3, mm6
+ psrlw mm5, 8
+
+ pmullw mm5, mem5
+ add edi, 8
+
+ // cycle
+ // cycle
+
+ paddw mm7, mm3
+ //
+
+ psrlw mm7, 8
+ //
+
+ pmullw mm7, mem7
+ dec ecx
+
+ // cycle
+ // cycle
+ // cycle
+
+ paddw mm5, mm7
+
+ psrlw mm5, 8
+
+ packuswb mm5, mm5
+
+ movd [edi-4], mm5
+
+
+ jnz mmx_scale_loop1
+ mov fbout, edi
+ }
+ } // end mmx
+ __asm emms;
+#endif
+ if (blend) // reblend this scanline with the original
+ {
+ fbout-=w;
+ int x=w/4;
+ unsigned int *s2=(unsigned int *)framebuffer+y*w;
+ while (x--)
+ {
+ fbout[0]=BLEND_AVG(fbout[0],s2[0]);
+ fbout[1]=BLEND_AVG(fbout[1],s2[1]);
+ fbout[2]=BLEND_AVG(fbout[2],s2[2]);
+ fbout[3]=BLEND_AVG(fbout[3],s2[3]);
+ fbout+=4;
+ s2+=4;
+ }
+ }
+ } // end subpixel y loop
+ }
+ else // !subpixel
+ {
+ int y;
+ for (y = 0; y < h; y ++)
+ {
+ int s_x=isx;
+ unsigned int *src = ((unsigned int *) framebuffer)+(s_y>>16)*w;
+ int ypart=(s_y>>8)&0xff;
+ s_y+=ds_x;
+ if (!blend)
+ {
+ int x=w/4;
+ while (x--)
+ {
+ fbout[0]=src[s_x>>16];
+ s_x += ds_x;
+ fbout[1]=src[s_x>>16];
+ s_x += ds_x;
+ fbout[2]=src[s_x>>16];
+ s_x += ds_x;
+ fbout[3]=src[s_x>>16];
+ s_x += ds_x;
+ fbout+=4;
+ }
+ }
+ else
+ {
+ unsigned int *s2=(unsigned int *)framebuffer+(y*w);
+ int x=w/4;
+ while (x--)
+ {
+ fbout[0]=BLEND_AVG(s2[0],src[s_x>>16]);
+ s_x += ds_x;
+ fbout[1]=BLEND_AVG(s2[1],src[s_x>>16]);
+ s_x += ds_x;
+ fbout[2]=BLEND_AVG(s2[2],src[s_x>>16]);
+ s_x += ds_x;
+ fbout[3]=BLEND_AVG(s2[3],src[s_x>>16]);
+ s2+=4;
+ fbout+=4;
+ s_x += ds_x;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+ int f_val;
+ unsigned int *dest=(unsigned int *) fbout;
+
+ if (isBeat && beatch)
+ {
+ fpos=scale2;
+ }
+
+ if (scale < scale2)
+ {
+ f_val=(fpos > scale? fpos:scale);
+ fpos -= 3;
+ }
+ else
+ {
+ f_val=(fpos < scale? fpos :scale);
+ fpos+=3;
+ }
+
+ if (f_val<0) f_val=0;
+
+ if (f_val < 32) return blitter_normal(framebuffer,fbout,w,h,f_val);
+ if (f_val > 32) return blitter_out(framebuffer,fbout,w,h,f_val);
+ return 0;
+}
+
+C_RBASE *R_BlitterFB(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,256);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->scale);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,256);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->scale2);
+ if (g_this->blend==1) CheckDlgButton(hwndDlg,IDC_BLEND,BST_CHECKED);
+ if (g_this->subpixel) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ if (g_this->beatch==1) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_BLEND:
+ if (IsDlgButtonChecked(hwndDlg,IDC_BLEND))
+ {
+ g_this->blend=1;
+ }
+ else g_this->blend=0;
+ break;
+ case IDC_CHECK1:
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1))
+ g_this->beatch=1;
+ else g_this->beatch=0;
+ break;
+ case IDC_CHECK2:
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK2))
+ {
+ g_this->subpixel=1;
+ }
+ else g_this->subpixel=0;
+ break;
+ }
+ return 0;
+
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->scale=t;
+ g_this->fpos=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
+ {
+ g_this->scale2=t;
+ g_this->fpos=t;
+ }
+ }
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_BLT,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_BlitterFB(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_blur.cpp b/Src/Plugins/Visualization/vis_avs/r_blur.cpp
new file mode 100644
index 00000000..77645dc9
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_blur.cpp
@@ -0,0 +1,883 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+
+#ifndef LASER
+
+#define C_THISCLASS C_BlurClass
+#define MOD_NAME "Trans / Blur"
+
+static const int zero=0;
+
+class C_THISCLASS : public C_RBASE2 {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BLUR,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ virtual int smp_getflags() { return 1; }
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // return value is that of render() for fbstuff etc
+
+ int enabled;
+
+ int roundmode;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { roundmode=GET_INT(); pos+=4; }
+ else roundmode=0;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(roundmode); pos+=4;
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ roundmode=0;
+ enabled=1;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+#define MASK_SH1 (~(((1<<7)|(1<<15)|(1<<23))<<1))
+#define MASK_SH2 (~(((3<<6)|(3<<14)|(3<<22))<<2))
+#define MASK_SH3 (~(((7<<5)|(7<<13)|(7<<21))<<3))
+#define MASK_SH4 (~(((15<<4)|(15<<12)|(15<<20))<<4))
+static unsigned int mmx_mask1[2]={MASK_SH1,MASK_SH1};
+static unsigned int mmx_mask2[2]={MASK_SH2,MASK_SH2};
+static unsigned int mmx_mask3[2]={MASK_SH3,MASK_SH3};
+static unsigned int mmx_mask4[2]={MASK_SH4,MASK_SH4};
+
+#define DIV_2(x) ((( x ) & MASK_SH1)>>1)
+#define DIV_4(x) ((( x ) & MASK_SH2)>>2)
+#define DIV_8(x) ((( x ) & MASK_SH3)>>3)
+#define DIV_16(x) ((( x ) & MASK_SH4)>>4)
+
+
+void C_THISCLASS::smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return;
+
+ timingEnter(0);
+
+ unsigned int *f = (unsigned int *) framebuffer;
+ unsigned int *of = (unsigned int *) fbout;
+
+ if (max_threads < 1) max_threads=1;
+
+ int start_l = ( this_thread * h ) / max_threads;
+ int end_l;
+
+ if (this_thread >= max_threads - 1) end_l = h;
+ else end_l = ( (this_thread+1) * h ) / max_threads;
+
+ int outh=end_l-start_l;
+ if (outh<1) return;
+
+ int skip_pix=start_l*w;
+
+ f += skip_pix;
+ of+= skip_pix;
+
+ int at_top=0, at_bottom=0;
+
+ if (!this_thread) at_top=1;
+ if (this_thread >= max_threads - 1) at_bottom=1;
+
+ if (enabled == 2)
+ {
+ // top line
+ if (at_top)
+ {
+ unsigned int *f2=f+w;
+ int x;
+ int adj_tl=0, adj_tl2=0;
+ if (roundmode) { adj_tl = 0x03030303; adj_tl2 = 0x04040404; }
+ // top left
+ *of++=DIV_2(f[0])+DIV_4(f[0])+DIV_8(f[1])+DIV_8(f2[0]) + adj_tl; f++; f2++;
+ // top center
+ x=(w-2)/4;
+ while (x--)
+ {
+ of[0]=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + adj_tl2;
+ of[1]=DIV_2(f[1]) + DIV_8(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + adj_tl2;
+ of[2]=DIV_2(f[2]) + DIV_8(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2]) + adj_tl2;
+ of[3]=DIV_2(f[3]) + DIV_8(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3]) + adj_tl2;
+ f+=4;
+ f2+=4;
+ of+=4;
+ }
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + adj_tl2;
+ f++;
+ f2++;
+ }
+ // top right
+ *of++=DIV_2(f[0])+DIV_4(f[0]) + DIV_8(f[-1])+DIV_8(f2[0]) + adj_tl; f++; f2++;
+ }
+
+
+ // middle block
+ {
+ int y=outh-at_top-at_bottom;
+ unsigned int adj_tl1=0,adj_tl2=0;
+ unsigned __int64 adj2=0;
+ if (roundmode) { adj_tl1=0x04040404; adj_tl2=0x05050505; adj2=0x0505050505050505i64; }
+ while (y--)
+ {
+ int x;
+ unsigned int *f2=f+w;
+ unsigned int *f3=f-w;
+
+ // left edge
+ *of++=DIV_2(f[0])+DIV_8(f[0])+DIV_8(f[1])+DIV_8(f2[0])+DIV_8(f3[0])+adj_tl1; f++; f2++; f3++;
+
+ // middle of line
+#ifdef NO_MMX
+ x=(w-2)/4;
+ if (roundmode)
+ {
+ while (x--)
+ {
+ of[0]=DIV_2(f[0]) + DIV_4(f[0]) + DIV_16(f[1]) + DIV_16(f[-1]) + DIV_16(f2[0]) + DIV_16(f3[0]) + 0x05050505;
+ of[1]=DIV_2(f[1]) + DIV_4(f[1]) + DIV_16(f[2]) + DIV_16(f[0]) + DIV_16(f2[1]) + DIV_16(f3[1]) + 0x05050505;
+ of[2]=DIV_2(f[2]) + DIV_4(f[2]) + DIV_16(f[3]) + DIV_16(f[1]) + DIV_16(f2[2]) + DIV_16(f3[2]) + 0x05050505;
+ of[3]=DIV_2(f[3]) + DIV_4(f[3]) + DIV_16(f[4]) + DIV_16(f[2]) + DIV_16(f2[3]) + DIV_16(f3[3]) + 0x05050505;
+ f+=4;
+ f2+=4;
+ f3+=4;
+ of+=4;
+ }
+ }
+ else
+ {
+ while (x--)
+ {
+ of[0]=DIV_2(f[0]) + DIV_4(f[0]) + DIV_16(f[1]) + DIV_16(f[-1]) + DIV_16(f2[0]) + DIV_16(f3[0]);
+ of[1]=DIV_2(f[1]) + DIV_4(f[1]) + DIV_16(f[2]) + DIV_16(f[0]) + DIV_16(f2[1]) + DIV_16(f3[1]);
+ of[2]=DIV_2(f[2]) + DIV_4(f[2]) + DIV_16(f[3]) + DIV_16(f[1]) + DIV_16(f2[2]) + DIV_16(f3[2]);
+ of[3]=DIV_2(f[3]) + DIV_4(f[3]) + DIV_16(f[4]) + DIV_16(f[2]) + DIV_16(f2[3]) + DIV_16(f3[3]);
+ f+=4;
+ f2+=4;
+ f3+=4;
+ of+=4;
+ }
+ }
+#else
+ {
+ __asm
+ {
+ mov ecx, w
+ mov edx, ecx
+ mov ebx, edx
+ neg ebx
+ mov esi, f
+ mov edi, of
+ sub ecx, 2
+ shr ecx, 2
+ movq mm1, [esi-4]
+ align 16
+mmx_light_blur_loop:
+ movq mm0, [esi]
+
+ movq mm2, [esi+4]
+ pand mm0, mmx_mask1
+
+ movq mm5, mm2
+ psrl mm0, 1
+
+ movq mm7, [esi+8]
+ movq mm4, mm0
+
+ pand mm1, mmx_mask4
+ pand mm4, mmx_mask1
+
+ movq mm3, [esi+edx*4]
+ psrl mm4, 1
+
+ paddb mm0, mm4
+ pand mm2, mmx_mask4
+
+ movq mm4, [esi+ebx*4]
+ pand mm3, mmx_mask4
+
+ pand mm4, mmx_mask4
+
+ psrl mm1, 4
+ pand mm7, mmx_mask1
+
+ movq mm6, [esi+12]
+
+ psrl mm2, 4
+ add esi, 16
+
+ psrl mm3, 4
+
+ paddb mm0, mm1
+ psrl mm4, 4
+
+ movq mm1, mm6
+ psrl mm7, 1
+
+ paddb mm2, mm3
+ paddb mm0, mm4
+
+ movq mm3, [esi+edx*4-8]
+ paddb mm0, mm2
+
+ movq mm4, [esi+ebx*4-8]
+ paddb mm0, [adj2]
+
+ pand mm6, mmx_mask4
+
+ movq [edi],mm0
+ pand mm5, mmx_mask4
+
+ movq mm0, mm7
+ pand mm3, mmx_mask4
+
+ psrl mm6, 4
+ pand mm0, mmx_mask1
+
+ pand mm4, mmx_mask4
+ psrl mm5, 4
+
+ psrl mm0, 1
+ paddb mm7, mm6
+
+ paddb mm7, mm0
+ add edi, 16
+
+ psrl mm3, 4
+
+ psrl mm4, 4
+ paddb mm5, mm3
+
+ paddb mm7, mm4
+ dec ecx
+
+ paddb mm7, mm5
+ paddb mm7, [adj2]
+
+ movq [edi-8],mm7
+
+ jnz mmx_light_blur_loop
+ mov of, edi
+ mov f, esi
+ };
+ f2=f+w; // update these bitches
+ f3=f-w;
+ }
+#endif
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_2(f[0]) + DIV_4(f[0]) + DIV_16(f[1]) + DIV_16(f[-1]) + DIV_16(f2[0]) + DIV_16(f3[0]) + adj_tl2;
+ f++;
+ f2++;
+ f3++;
+ }
+
+ // right block
+ *of++=DIV_2(f[0])+DIV_8(f[0])+DIV_8(f[-1])+DIV_8(f2[0])+DIV_8(f3[0])+adj_tl1; f++;
+ }
+ }
+ // bottom block
+ if (at_bottom)
+ {
+ unsigned int *f2=f-w;
+ int x;
+ int adj_tl=0, adj_tl2=0;
+ if (roundmode) { adj_tl = 0x03030303; adj_tl2 = 0x04040404; }
+ // bottom left
+ *of++=DIV_2(f[0])+DIV_4(f[0])+DIV_8(f[1])+DIV_8(f2[0]) + adj_tl; f++; f2++;
+ // bottom center
+ x=(w-2)/4;
+ while (x--)
+ {
+ of[0]=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + adj_tl2;
+ of[1]=DIV_2(f[1]) + DIV_8(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + adj_tl2;
+ of[2]=DIV_2(f[2]) + DIV_8(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2])+adj_tl2;
+ of[3]=DIV_2(f[3]) + DIV_8(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3])+adj_tl2;
+ f+=4;
+ f2+=4;
+ of+=4;
+ }
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_2(f[0]) + DIV_8(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0])+adj_tl2;
+ f++;
+ f2++;
+ }
+ // bottom right
+ *of++=DIV_2(f[0])+DIV_4(f[0]) + DIV_8(f[-1])+DIV_8(f2[0])+adj_tl; f++; f2++;
+ }
+ }
+ else if (enabled == 3) // more blur
+ {
+ // top line
+ if (at_top) {
+ unsigned int *f2=f+w;
+ int x;
+ int adj_tl=0, adj_tl2=0;
+ if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x01010101; }
+ // top left
+ *of++=DIV_2(f[1])+DIV_2(f2[0]) + adj_tl2; f++; f2++;
+ // top center
+ x=(w-2)/4;
+ while (x--)
+ {
+ of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0]) + adj_tl;
+ of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_2(f2[1]) +adj_tl;
+ of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_2(f2[2]) + adj_tl;
+ of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_2(f2[3]) + adj_tl;
+ f+=4;
+ f2+=4;
+ of+=4;
+ }
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0])+adj_tl;
+ f++;
+ f2++;
+ }
+ // top right
+ *of++=DIV_2(f[-1])+DIV_2(f2[0])+adj_tl2; f++; f2++;
+ }
+
+
+ // middle block
+ {
+ int y=outh-at_top-at_bottom;
+ int adj_tl1=0,adj_tl2=0;
+ unsigned __int64 adj2=0;
+ if (roundmode) { adj_tl1=0x02020202; adj_tl2=0x03030303; adj2=0x0303030303030303i64; }
+
+ while (y--)
+ {
+ int x;
+ unsigned int *f2=f+w;
+ unsigned int *f3=f-w;
+
+ // left edge
+ *of++=DIV_2(f[1])+DIV_4(f2[0])+DIV_4(f3[0]) + adj_tl1; f++; f2++; f3++;
+
+ // middle of line
+#ifdef NO_MMX
+ x=(w-2)/4;
+ if (roundmode)
+ {
+ while (x--)
+ {
+ of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + DIV_4(f3[0]) + 0x03030303;
+ of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + DIV_4(f3[1]) + 0x03030303;
+ of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + DIV_4(f3[2]) + 0x03030303;
+ of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + DIV_4(f3[3]) + 0x03030303;
+ f+=4; f2+=4; f3+=4; of+=4;
+ }
+ }
+ else
+ {
+ while (x--)
+ {
+ of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + DIV_4(f3[0]);
+ of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + DIV_4(f3[1]);
+ of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + DIV_4(f3[2]);
+ of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + DIV_4(f3[3]);
+ f+=4; f2+=4; f3+=4; of+=4;
+ }
+ }
+#else
+ {
+ __asm
+ {
+ mov ecx, w
+ mov edx, ecx
+ mov ebx, edx
+ neg ebx
+ mov esi, f
+ mov edi, of
+ sub ecx, 2
+ shr ecx, 2
+ movq mm1, [esi-4]
+ align 16
+mmx_heavy_blur_loop:
+ movq mm2, [esi+4]
+ pxor mm0, mm0
+
+ movq mm5, mm2
+ pxor mm7, mm7
+
+ movq mm3, [esi+edx*4]
+ pand mm1, mmx_mask2
+
+ movq mm4, [esi+ebx*4]
+ pand mm2, mmx_mask2
+
+ pand mm3, mmx_mask2
+ pand mm4, mmx_mask2
+
+ psrl mm1, 2
+
+ movq mm6, [esi+12]
+ psrl mm2, 2
+
+ psrl mm3, 2
+
+ paddb mm0, mm1
+ psrl mm4, 2
+
+ movq mm1, mm6
+
+ paddb mm2, mm3
+ paddb mm0, mm4
+
+ movq mm3, [esi+edx*4+8]
+ paddb mm0, mm2
+
+ movq mm4, [esi+ebx*4+8]
+ paddb mm0, [adj2]
+
+ pand mm6, mmx_mask2
+
+ movq [edi],mm0
+ pand mm5, mmx_mask2
+
+ pand mm3, mmx_mask2
+ add esi, 16
+
+ psrl mm6, 2
+ pand mm4, mmx_mask2
+
+ psrl mm5, 2
+ paddb mm7, mm6
+
+ psrl mm3, 2
+ add edi, 16
+
+ psrl mm4, 2
+ paddb mm5, mm3
+
+ paddb mm7, mm4
+
+ paddb mm7, mm5
+ paddb mm7, [adj2]
+
+ movq [edi-8],mm7
+
+ dec ecx
+ jnz mmx_heavy_blur_loop
+ mov of, edi
+ mov f, esi
+ };
+ f2=f+w; // update these bitches
+ f3=f-w;
+ }
+#endif
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + DIV_4(f3[0]) + adj_tl2;
+ f++;
+ f2++;
+ f3++;
+ }
+
+ // right block
+ *of++=DIV_2(f[-1])+DIV_4(f2[0])+DIV_4(f3[0]) + adj_tl1; f++;
+ }
+ }
+
+ // bottom block
+ if (at_bottom)
+ {
+ unsigned int *f2=f-w;
+ int x;
+ int adj_tl=0, adj_tl2=0;
+ if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x01010101; }
+ // bottom left
+ *of++=DIV_2(f[1])+DIV_2(f2[0]) + adj_tl2; f++; f2++;
+ // bottom center
+ x=(w-2)/4;
+ while (x--)
+ {
+ of[0]=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0])+adj_tl;
+ of[1]=DIV_4(f[2]) + DIV_4(f[0]) + DIV_2(f2[1])+adj_tl;
+ of[2]=DIV_4(f[3]) + DIV_4(f[1]) + DIV_2(f2[2])+adj_tl;
+ of[3]=DIV_4(f[4]) + DIV_4(f[2]) + DIV_2(f2[3])+adj_tl;
+ f+=4;
+ f2+=4;
+ of+=4;
+ }
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_4(f[1]) + DIV_4(f[-1]) + DIV_2(f2[0])+adj_tl;
+ f++;
+ f2++;
+ }
+ // bottom right
+ *of++=DIV_2(f[-1])+DIV_2(f2[0])+adj_tl2; f++; f2++;
+ }
+ }
+ else
+ {
+ // top line
+ if (at_top)
+ {
+ unsigned int *f2=f+w;
+ int x;
+ int adj_tl=0, adj_tl2=0;
+ if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x03030303; }
+ // top left
+ *of++=DIV_2(f[0])+DIV_4(f[1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
+ // top center
+ x=(w-2)/4;
+ while (x--)
+ {
+ of[0]=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
+ of[1]=DIV_4(f[1]) + DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + adj_tl2;
+ of[2]=DIV_4(f[2]) + DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + adj_tl2;
+ of[3]=DIV_4(f[3]) + DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + adj_tl2;
+ f+=4;
+ f2+=4;
+ of+=4;
+ }
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
+ f++;
+ f2++;
+ }
+ // top right
+ *of++=DIV_2(f[0])+DIV_4(f[-1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
+ }
+
+
+ // middle block
+ {
+ int y=outh-at_top-at_bottom;
+ int adj_tl1=0,adj_tl2=0;
+ unsigned __int64 adj2=0;
+ if (roundmode) { adj_tl1=0x03030303; adj_tl2=0x04040404; adj2=0x0404040404040404i64; }
+ while (y--)
+ {
+ int x;
+ unsigned int *f2=f+w;
+ unsigned int *f3=f-w;
+
+ // left edge
+ *of++=DIV_4(f[0])+DIV_4(f[1])+DIV_4(f2[0])+DIV_4(f3[0])+adj_tl1; f++; f2++; f3++;
+
+ // middle of line
+#ifdef NO_MMX
+ x=(w-2)/4;
+ if (roundmode)
+ {
+ while (x--)
+ {
+ of[0]=DIV_2(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + DIV_8(f3[0]) + 0x04040404;
+ of[1]=DIV_2(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + DIV_8(f3[1]) + 0x04040404;
+ of[2]=DIV_2(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2]) + DIV_8(f3[2]) + 0x04040404;
+ of[3]=DIV_2(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3]) + DIV_8(f3[3]) + 0x04040404;
+ f+=4; f2+=4; f3+=4; of+=4;
+ }
+ }
+ else
+ {
+ while (x--)
+ {
+ of[0]=DIV_2(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + DIV_8(f3[0]);
+ of[1]=DIV_2(f[1]) + DIV_8(f[2]) + DIV_8(f[0]) + DIV_8(f2[1]) + DIV_8(f3[1]);
+ of[2]=DIV_2(f[2]) + DIV_8(f[3]) + DIV_8(f[1]) + DIV_8(f2[2]) + DIV_8(f3[2]);
+ of[3]=DIV_2(f[3]) + DIV_8(f[4]) + DIV_8(f[2]) + DIV_8(f2[3]) + DIV_8(f3[3]);
+ f+=4; f2+=4; f3+=4; of+=4;
+ }
+ }
+#else
+ {
+ __asm
+ {
+ mov ecx, w
+ mov edx, ecx
+ mov ebx, edx
+ neg ebx
+ mov esi, f
+ mov edi, of
+ sub ecx, 2
+ shr ecx, 2
+ movq mm1, [esi-4]
+ align 16
+mmx_normal_blur_loop:
+ movq mm0, [esi]
+
+ movq mm2, [esi+4]
+ pand mm0, mmx_mask1
+
+ movq mm5, mm2
+
+ movq mm7, [esi+8]
+ pand mm1, mmx_mask3
+
+ movq mm3, [esi+edx*4]
+ pand mm2, mmx_mask3
+
+ movq mm4, [esi+ebx*4]
+ pand mm3, mmx_mask3
+
+ psrl mm0, 1
+ pand mm4, mmx_mask3
+
+ psrl mm1, 3
+ pand mm7, mmx_mask1
+
+ movq mm6, [esi+12]
+ psrl mm2, 3
+
+ add esi, 16
+ psrl mm3, 3
+
+ paddb mm0, mm1
+ psrl mm4, 3
+
+ movq mm1, mm6
+
+ paddb mm2, mm3
+ paddb mm0, mm4
+
+ movq mm3, [esi+edx*4-8]
+ paddb mm0, mm2
+
+ movq mm4, [esi+ebx*4-8]
+ paddb mm0, [adj2]
+
+ pand mm6, mmx_mask3
+
+ movq [edi],mm0
+ pand mm5, mmx_mask3
+
+ psrl mm7, 1
+ pand mm3, mmx_mask3
+
+ psrl mm6, 3
+ pand mm4, mmx_mask3
+
+ psrl mm5, 3
+ paddb mm7, mm6
+
+ add edi, 16
+ psrl mm3, 3
+
+ psrl mm4, 3
+ paddb mm5, mm3
+
+ paddb mm7, mm4
+ dec ecx
+
+ paddb mm7, mm5
+ paddb mm7, [adj2]
+
+ movq [edi-8],mm7
+
+ jnz mmx_normal_blur_loop
+ mov of, edi
+ mov f, esi
+ };
+ f2=f+w; // update these bitches
+ f3=f-w;
+ }
+#endif
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_2(f[0]) + DIV_8(f[1]) + DIV_8(f[-1]) + DIV_8(f2[0]) + DIV_8(f3[0]) + adj_tl2;
+ f++;
+ f2++;
+ f3++;
+ }
+
+ // right block
+ *of++=DIV_4(f[0])+DIV_4(f[-1])+DIV_4(f2[0])+DIV_4(f3[0]) + adj_tl1; f++;
+ }
+ }
+
+ // bottom block
+ if (at_bottom)
+ {
+ unsigned int *f2=f-w;
+ int adj_tl=0, adj_tl2=0;
+ if (roundmode) { adj_tl = 0x02020202; adj_tl2 = 0x03030303; }
+ int x;
+ // bottom left
+ *of++=DIV_2(f[0])+DIV_4(f[1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
+ // bottom center
+ x=(w-2)/4;
+ while (x--)
+ {
+ of[0]=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
+ of[1]=DIV_4(f[1]) + DIV_4(f[2]) + DIV_4(f[0]) + DIV_4(f2[1]) + adj_tl2;
+ of[2]=DIV_4(f[2]) + DIV_4(f[3]) + DIV_4(f[1]) + DIV_4(f2[2]) + adj_tl2;
+ of[3]=DIV_4(f[3]) + DIV_4(f[4]) + DIV_4(f[2]) + DIV_4(f2[3]) + adj_tl2;
+ f+=4;
+ f2+=4;
+ of+=4;
+ }
+ x=(w-2)&3;
+ while (x--)
+ {
+ *of++=DIV_4(f[0]) + DIV_4(f[1]) + DIV_4(f[-1]) + DIV_4(f2[0]) + adj_tl2;
+ f++;
+ f2++;
+ }
+ // bottom right
+ *of++=DIV_2(f[0])+DIV_4(f[-1])+DIV_4(f2[0]) + adj_tl; f++; f2++;
+ }
+ }
+
+#ifndef NO_MMX
+ __asm emms;
+#endif
+
+ timingLeave(0);
+}
+
+int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return 0;
+ return max_threads;
+}
+
+
+int C_THISCLASS::smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // return value is that of render() for fbstuff etc
+{
+ return !!enabled;
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
+ if (isBeat & 0x80000000) return 0;
+
+ smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
+ return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
+}
+
+
+C_RBASE *R_Blur(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_this->enabled==2) CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
+ else if (g_this->enabled==3) CheckDlgButton(hwndDlg,IDC_RADIO4,BST_CHECKED);
+ else if (g_this->enabled) CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
+ if (g_this->roundmode==0) CheckDlgButton(hwndDlg,IDC_ROUNDDOWN,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_ROUNDUP,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_RADIO1)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1))
+ g_this->enabled=0;
+ if (LOWORD(wParam) == IDC_RADIO2)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2))
+ g_this->enabled=1;
+ if (LOWORD(wParam) == IDC_RADIO3)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3))
+ g_this->enabled=2;
+ if (LOWORD(wParam) == IDC_RADIO4)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO4))
+ g_this->enabled=3;
+ if (LOWORD(wParam) == IDC_ROUNDUP)
+ if (IsDlgButtonChecked(hwndDlg,IDC_ROUNDUP))
+ g_this->roundmode=1;
+ if (LOWORD(wParam) == IDC_ROUNDDOWN)
+ if (IsDlgButtonChecked(hwndDlg,IDC_ROUNDDOWN))
+ g_this->roundmode=0;
+ return 0;
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_BLUR,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_Blur(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_bpm.cpp b/Src/Plugins/Visualization/vis_avs/r_bpm.cpp
new file mode 100644
index 00000000..9ed19d16
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_bpm.cpp
@@ -0,0 +1,285 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <math.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#define MOD_NAME "Misc / Custom BPM"
+#define C_THISCLASS C_BpmClass
+
+#define SET_BEAT 0x10000000
+#define CLR_BEAT 0x20000000
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_MISC_CUSTOM_BPM,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ void SliderStep(int Ctl, int *slide);
+ int enabled;
+ int arbitrary, skip, invert; // Type of action, adapt = detect beat
+ int arbVal, skipVal; // Values of arbitrary beat and beat skip
+ DWORD arbLastTC; // Last tick count used for arbitrary beat
+ int skipCount; // Beat counter used by beat skipper
+ int inInc, outInc; // +1/-1, Used by the nifty beatsynced sliders
+ int inSlide, outSlide; // Positions of sliders
+ int oldInSlide, oldOutSlide; // Used by timer to detect changes in sliders
+ int skipfirst;
+ int count;
+ };
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ skipfirst=0;
+ inSlide=0;
+ outSlide=0;
+ oldInSlide=0;
+ oldOutSlide=0;
+ enabled = 1;
+ arbLastTC = GetTickCount();
+ arbitrary=1;
+ arbVal = 500;
+ skipVal = 1;
+ skipCount = 0;
+ skip=0;
+ invert=0;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { arbitrary=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { skip=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { invert=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { arbVal=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { skipVal=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { skipfirst=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(arbitrary); pos+=4;
+ PUT_INT(skip); pos+=4;
+ PUT_INT(invert); pos+=4;
+ PUT_INT(arbVal); pos+=4;
+ PUT_INT(skipVal); pos+=4;
+ PUT_INT(skipfirst); pos+=4;
+ return pos;
+}
+
+
+
+void C_THISCLASS::SliderStep(int Ctl, int *slide)
+{
+*slide += Ctl == IDC_IN ? inInc : outInc;
+if (!*slide || *slide == 8) (Ctl == IDC_IN ? inInc : outInc) *= -1;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return 0;
+ if (isBeat&0x80000000) return 0;
+
+ if (isBeat) // Show the beat received from AVS
+ {
+ SliderStep(IDC_IN, &inSlide);
+ count++;
+ }
+
+ if (skipfirst != 0 && count <= skipfirst)
+ return isBeat ? CLR_BEAT : 0;
+
+ if (arbitrary)
+ {
+ DWORD TCNow = GetTickCount();
+ if (TCNow > arbLastTC + arbVal)
+ {
+ arbLastTC = TCNow;
+ SliderStep(IDC_OUT, &outSlide);
+ return SET_BEAT;
+ }
+ return CLR_BEAT;
+ }
+
+ if (skip)
+ {
+ if (isBeat && ++skipCount >= skipVal+1)
+ {
+ skipCount = 0;
+ SliderStep(IDC_OUT, &outSlide);
+ return SET_BEAT;
+ }
+ return CLR_BEAT;
+ }
+
+ if (invert)
+ {
+ if (isBeat)
+ return CLR_BEAT;
+ else
+ {
+ SliderStep(IDC_OUT, &outSlide);
+ return SET_BEAT;
+ }
+ }
+return 0;
+}
+
+// configuration dialog stuff
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ char txt[40], beat[16], beats[16];
+ g_ConfigThis->inInc = 1;
+ g_ConfigThis->outInc = 1;
+ g_ConfigThis->inSlide = 0;
+ g_ConfigThis->outSlide = 0;
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->arbitrary) CheckDlgButton(hwndDlg,IDC_ARBITRARY,BST_CHECKED);
+ if (g_ConfigThis->skip) CheckDlgButton(hwndDlg,IDC_SKIP,BST_CHECKED);
+ if (g_ConfigThis->invert) CheckDlgButton(hwndDlg,IDC_INVERT,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_SETTICFREQ, 100, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_SETRANGE, TRUE, MAKELONG(200, 10000));
+ SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_SETRANGE, TRUE, MAKELONG(1, 16));
+ SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_SETPOS, TRUE, g_ConfigThis->arbVal);
+ SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_SETPOS, TRUE, g_ConfigThis->skipVal);
+ SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
+ SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
+ SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_SETPOS, TRUE, g_ConfigThis->skipfirst);
+ wsprintf(txt, "%d bpm", 60000 / g_ConfigThis->arbVal);
+ SetDlgItemText(hwndDlg, IDC_ARBTXT, txt);
+ WASABI_API_LNGSTRING_BUF(IDS_BEAT,beat,16);
+ WASABI_API_LNGSTRING_BUF(IDS_BEATS,beats,16);
+ wsprintf(txt, "%d %s", g_ConfigThis->skipVal, g_ConfigThis->skipVal > 1 ? beats : beat);
+ SetDlgItemText(hwndDlg, IDC_SKIPTXT, txt);
+ wsprintf(txt, "%d %s", g_ConfigThis->skipfirst, g_ConfigThis->skipfirst > 1 ? beats : beat);
+ SetDlgItemText(hwndDlg, IDC_SKIPFIRSTTXT, txt);
+ SetTimer(hwndDlg, 0, 50, NULL);
+ }
+ return 1;
+ case WM_TIMER:
+ {
+ if (g_ConfigThis->oldInSlide != g_ConfigThis->inSlide) {
+ SendDlgItemMessage(hwndDlg, IDC_IN, TBM_SETPOS, TRUE, g_ConfigThis->inSlide); g_ConfigThis->oldInSlide=g_ConfigThis->inSlide; }
+ if (g_ConfigThis->oldOutSlide != g_ConfigThis->outSlide) {
+ SendDlgItemMessage(hwndDlg, IDC_OUT, TBM_SETPOS, TRUE, g_ConfigThis->outSlide); g_ConfigThis->oldOutSlide=g_ConfigThis->outSlide; }
+ }
+ return 0;
+ case WM_NOTIFY:
+ {
+ char txt[40], beat[16], beats[16];
+ if (LOWORD(wParam) == IDC_ARBVAL)
+ g_ConfigThis->arbVal = SendDlgItemMessage(hwndDlg, IDC_ARBVAL, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_SKIPVAL)
+ g_ConfigThis->skipVal = SendDlgItemMessage(hwndDlg, IDC_SKIPVAL, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_SKIPFIRST)
+ g_ConfigThis->skipfirst = SendDlgItemMessage(hwndDlg, IDC_SKIPFIRST, TBM_GETPOS, 0, 0);
+ wsprintf(txt, "%d bpm", 60000 / g_ConfigThis->arbVal);
+ SetDlgItemText(hwndDlg, IDC_ARBTXT, txt);
+ WASABI_API_LNGSTRING_BUF(IDS_BEAT,beat,16);
+ WASABI_API_LNGSTRING_BUF(IDS_BEATS,beats,16);
+ wsprintf(txt, "%d %s", g_ConfigThis->skipVal, g_ConfigThis->skipVal > 1 ? beats : beat);
+ SetDlgItemText(hwndDlg, IDC_SKIPTXT, txt);
+ wsprintf(txt, "%d %s", g_ConfigThis->skipfirst, g_ConfigThis->skipfirst > 1 ? beats : beat);
+ SetDlgItemText(hwndDlg, IDC_SKIPFIRSTTXT, txt);
+ return 0;
+ }
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ARBITRARY) ||
+ (LOWORD(wParam) == IDC_SKIP) ||
+ (LOWORD(wParam) == IDC_INVERT))
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->arbitrary=IsDlgButtonChecked(hwndDlg,IDC_ARBITRARY)?1:0;
+ g_ConfigThis->skip=IsDlgButtonChecked(hwndDlg,IDC_SKIP)?1:0;
+ g_ConfigThis->invert=IsDlgButtonChecked(hwndDlg,IDC_INVERT)?1:0;
+ }
+ return 0;
+ case WM_DESTROY:
+ KillTimer(hwndDlg, 0);
+ return 0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_BPM,hwndParent,g_DlgProc);
+}
+
+C_RBASE *R_Bpm(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
diff --git a/Src/Plugins/Visualization/vis_avs/r_bright.cpp b/Src/Plugins/Visualization/vis_avs/r_bright.cpp
new file mode 100644
index 00000000..bb224add
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_bright.cpp
@@ -0,0 +1,506 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include <math.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+#define MOD_NAME "Trans / Brightness"
+#define C_THISCLASS C_BrightnessClass
+
+class C_THISCLASS : public C_RBASE2 {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BRIGHTNESS,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ virtual int smp_getflags() { return 1; }
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // return value is that of render() for fbstuff etc
+
+ int enabled;
+ int redp, greenp, bluep;
+ int blend, blendavg;
+ int dissoc;
+ int color;
+ int exclude;
+ int distance;
+ int tabs_needinit;
+ int green_tab[256];
+ int red_tab[256];
+ int blue_tab[256];
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ tabs_needinit=1;
+ redp=0;
+ bluep=0;
+ greenp=0;
+ blend=0;
+ blendavg=1;
+ enabled=1;
+ color=0;
+ exclude=0;
+ distance = 16;
+ dissoc=0;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { redp=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { greenp=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { bluep=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { dissoc=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { exclude=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { distance=GET_INT(); pos+=4; }
+ tabs_needinit=1;
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(redp); pos+=4;
+ PUT_INT(greenp); pos+=4;
+ PUT_INT(bluep); pos+=4;
+ PUT_INT(dissoc); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(exclude); pos+=4;
+ PUT_INT(distance); pos+=4;
+ return pos;
+}
+
+static __inline int iabs(int v)
+{
+return (v<0) ? -v : v;
+}
+
+static __inline int inRange(int color, int ref, int distance)
+{
+if (iabs((color & 0xFF) - (ref & 0xFF)) > distance) return 0;
+if (iabs(((color) & 0xFF00) - ((ref) & 0xFF00)) > (distance<<8)) return 0;
+if (iabs(((color) & 0xFF0000) - ((ref) & 0xFF0000)) > (distance<<16)) return 0;
+return 1;
+}
+
+static void mmx_brighten_block(int *p, int rm, int gm, int bm, int l)
+{
+ int poo[2]=
+ {
+ (bm>>8)|((gm>>8)<<16),
+ rm>>8
+ };
+ __asm
+ {
+ mov eax, p
+ mov ecx, l
+ movq mm1, [poo]
+ align 16
+mmx_brightblock_loop:
+ pxor mm0, mm0
+ punpcklbw mm0, [eax]
+
+ pmulhw mm0, mm1
+ packuswb mm0, mm0
+
+ movd [eax], mm0
+
+ add eax, 4
+
+ dec ecx
+ jnz mmx_brightblock_loop
+ emms
+ };
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
+ if (isBeat & 0x80000000) return 0;
+
+ smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
+ return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
+}
+
+int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int rm=(int)((1+(redp < 0 ? 1 : 16)*((float)redp/4096))*65536.0);
+ int gm=(int)((1+(greenp < 0 ? 1 : 16)*((float)greenp/4096))*65536.0);
+ int bm=(int)((1+(bluep < 0 ? 1 : 16)*((float)bluep/4096))*65536.0);
+
+ if (!enabled) return 0;
+ if (tabs_needinit)
+ {
+ int n;
+ for (n = 0; n < 256; n ++)
+ {
+ red_tab[n] = (n*rm)&0xffff0000;
+ if (red_tab[n]>0xff0000) red_tab[n]=0xff0000;
+ if (red_tab[n]<0) red_tab[n]=0;
+ green_tab[n] = ((n*gm)>>8)&0xffff00;
+ if (green_tab[n]>0xff00) green_tab[n]=0xff00;
+ if (green_tab[n]<0) green_tab[n]=0;
+ blue_tab[n] = ((n*bm)>>16)&0xffff;
+ if (blue_tab[n]>0xff) blue_tab[n]=0xff;
+ if (blue_tab[n]<0) blue_tab[n]=0;
+ }
+ tabs_needinit=0;
+ }
+ if (isBeat&0x80000000) return 0;
+
+ return max_threads;
+}
+
+int C_THISCLASS::smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // return value is that of render() for fbstuff etc
+{
+ return 0;
+}
+
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+void C_THISCLASS::smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled || (isBeat&0x80000000)) return;
+
+ if (max_threads < 1) max_threads=1;
+
+ int start_l = ( this_thread * h ) / max_threads;
+ int end_l;
+
+ if (this_thread >= max_threads - 1) end_l = h;
+ else end_l = ( (this_thread+1) * h ) / max_threads;
+
+ int outh=end_l-start_l;
+ if (outh<1) return;
+
+ int l=w*outh;
+
+ int *p = framebuffer + start_l * w;
+ if (blend)
+ {
+ if (!exclude)
+ {
+ while (l--)
+ {
+ int pix=*p;
+ *p++ = BLEND(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
+ }
+ }
+ else
+ {
+ while (l--)
+ {
+ int pix=*p;
+ if (!inRange(pix,color,distance))
+ {
+ *p = BLEND(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
+ }
+ p++;
+ }
+ }
+ }
+ else if (blendavg)
+ {
+ if (!exclude)
+ {
+ while (l--)
+ {
+ int pix=*p;
+ *p++ = BLEND_AVG(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
+ }
+ }
+ else
+ {
+ while (l--)
+ {
+ int pix=*p;
+ if (!inRange(pix,color,distance))
+ {
+ *p = BLEND_AVG(pix, red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff]);
+ }
+ p++;
+ }
+ }
+ }
+ else
+ {
+ if (!exclude)
+ {
+#if 1 // def NO_MMX
+ while (l--)
+ {
+ int pix=*p;
+ *p++ = red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff];
+ }
+#else
+ mmx_brighten_block(p,rm,gm,bm,l);
+#endif
+ }
+ else
+ {
+ while (l--)
+ {
+ int pix=*p;
+ if (!inRange(pix,color,distance))
+ {
+ *p = red_tab[(pix>>16)&0xff] | green_tab[(pix>>8)&0xff] | blue_tab[pix&0xff];
+ }
+ p++;
+ }
+ }
+ }
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETRANGEMIN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETRANGEMIN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETRANGEMIN, TRUE, 0);
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETRANGEMAX, TRUE, 8192);
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETRANGEMAX, TRUE, 8192);
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETRANGEMAX, TRUE, 8192);
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETTICFREQ, 256, 0);
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETTICFREQ, 256, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETTICFREQ, 256, 0);
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETPOS, TRUE, g_ConfigThis->distance);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETTICFREQ, 16, 0);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->exclude) CheckDlgButton(hwndDlg,IDC_EXCLUDE,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (g_ConfigThis->dissoc) CheckDlgButton(hwndDlg,IDC_DISSOC,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_DISTANCE)
+ {
+ g_ConfigThis->distance = SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_GETPOS, 0, 0);
+ }
+ if (LOWORD(wParam) == IDC_RED)
+ {
+ g_ConfigThis->redp = SendDlgItemMessage(hwndDlg, IDC_RED, TBM_GETPOS, 0, 0)-4096;
+ rred:
+ g_ConfigThis->tabs_needinit=1;
+ if (!g_ConfigThis->dissoc)
+ {
+ g_ConfigThis->greenp = g_ConfigThis->redp;
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
+ g_ConfigThis->bluep = g_ConfigThis->redp;
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
+ }
+ }
+ if (LOWORD(wParam) == IDC_GREEN)
+ {
+ g_ConfigThis->greenp = SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_GETPOS, 0, 0)-4096;
+ rgreen:
+ g_ConfigThis->tabs_needinit=1;
+ if (!g_ConfigThis->dissoc)
+ {
+ g_ConfigThis->redp = g_ConfigThis->greenp;
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
+ g_ConfigThis->bluep = g_ConfigThis->greenp;
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
+ }
+ }
+ if (LOWORD(wParam) == IDC_BLUE)
+ {
+ g_ConfigThis->bluep = SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_GETPOS, 0, 0)-4096;
+ rblue:
+ g_ConfigThis->tabs_needinit=1;
+ if (!g_ConfigThis->dissoc)
+ {
+ g_ConfigThis->redp = g_ConfigThis->bluep;
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
+ g_ConfigThis->greenp = g_ConfigThis->bluep;
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
+ }
+ }
+ return 0;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
+ {
+ int *a=&(g_ConfigThis->color);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ g_ConfigThis->color = *a;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ if (LOWORD(wParam) == IDC_BRED)
+ {
+ g_ConfigThis->redp = 0;
+ SendDlgItemMessage(hwndDlg, IDC_RED, TBM_SETPOS, TRUE, g_ConfigThis->redp+4096);
+ goto rred; // gotos are so sweet ;)
+ }
+ if (LOWORD(wParam) == IDC_BGREEN)
+ {
+ g_ConfigThis->greenp = 0;
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
+ goto rgreen;
+ }
+ if (LOWORD(wParam) == IDC_BBLUE)
+ {
+ g_ConfigThis->bluep = 0;
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
+ goto rblue;
+ }
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_EXCLUDE) ||
+ (LOWORD(wParam) == IDC_DISSOC) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->exclude=IsDlgButtonChecked(hwndDlg,IDC_EXCLUDE)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->dissoc=IsDlgButtonChecked(hwndDlg,IDC_DISSOC)?1:0;
+ if (!g_ConfigThis->dissoc)
+ {
+ g_ConfigThis->greenp = g_ConfigThis->redp;
+ SendDlgItemMessage(hwndDlg, IDC_GREEN, TBM_SETPOS, TRUE, g_ConfigThis->greenp+4096);
+ g_ConfigThis->bluep = g_ConfigThis->redp;
+ SendDlgItemMessage(hwndDlg, IDC_BLUE, TBM_SETPOS, TRUE, g_ConfigThis->bluep+4096);
+ }
+ }
+ return 0;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL) // paint nifty color button
+ {
+ int w=di->rcItem.right-di->rcItem.left;
+ int _color=g_ConfigThis->color;
+ _color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ }
+ }
+ return 0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_BRIGHTNESS,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Brightness(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+#else
+C_RBASE *R_Brightness(char *desc) { return NULL; }
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/r_bspin.cpp b/Src/Plugins/Visualization/vis_avs/r_bspin.cpp
new file mode 100644
index 00000000..dac61a1b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_bspin.cpp
@@ -0,0 +1,315 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe (sets alpha to 0 on rendered portions) 11/21/99
+
+#include <windows.h>
+#include <math.h>
+#include "r_defs.h"
+
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_BSpinClass
+#define MOD_NAME "Render / Bass Spin"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_BASS_SPIN,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ void my_triangle(int *fb, int points[6], int width, int height, int color);
+ int enabled;
+ int colors[2];
+ int mode;
+
+
+ int last_a;
+ int lx[2][2],ly[2][2];
+ double r_v[2];
+ double v[2];
+ double dir[2];
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { colors[0]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { colors[1]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { mode=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(colors[0]); pos+=4;
+ PUT_INT(colors[1]); pos+=4;
+ PUT_INT(mode); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ last_a=0;
+ enabled=3;
+ colors[0]=RGB(255,255,255);
+ colors[1]=RGB(255,255,255);
+ memset(lx,0,sizeof(lx));
+ memset(ly,0,sizeof(ly));
+ memset(v,0,sizeof(v));
+ r_v[0]=3.14159;
+ r_v[1]=0.0;
+ dir[0]=-1.0;
+ dir[1]=1.0;
+ mode=1;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int y,x;
+ if (isBeat&0x80000000) return 0;
+ for (y = 0; y < 2; y ++)
+ {
+ if (!(enabled&(1<<y))) continue;
+ unsigned char *fa_data=(unsigned char *)visdata[0][y];
+ int xp,yp;
+ int ss=min(h/2,(w*3)/8);
+ double s=(double)ss;
+ int c_x = (!y?w/2-ss/2:w/2+ss/2);
+ int a=0,d=0;
+ int nc=1;
+ int oc6 = colors[y];
+ for (x = 0; x < 44; x ++)
+ {
+ d+=fa_data[x];
+ }
+
+ a=(d*512)/(last_a+30*256);
+
+ last_a=d;
+
+ if (a > 255) a =255;
+ v[y] = 0.7*(max(a-104,12)/96.0) + 0.3*v[y];
+ r_v[y] += 3.14159/6.0 * v[y] * dir[y];
+
+ s *= a*1.0/256.0f;
+ yp=(int)(sin(r_v[y])*s);
+ xp=(int)(cos(r_v[y])*s);
+ if (mode==0)
+ {
+ if (lx[0][y] || ly[0][y]) line(framebuffer,lx[0][y],ly[0][y],xp+c_x,yp+h/2,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
+ lx[0][y]=xp+c_x;
+ ly[0][y]=yp+h/2;
+ line(framebuffer,c_x,h/2,c_x+xp,h/2+yp,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
+ if (lx[1][y] || ly[1][y]) line(framebuffer,lx[1][y],ly[1][y],c_x-xp,h/2-yp,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
+ lx[1][y]=c_x-xp;
+ ly[1][y]=h/2-yp;
+ line(framebuffer,c_x,h/2,c_x-xp,h/2-yp,w,h,oc6,(g_line_blend_mode&0xff0000)>>16);
+ }
+ else if (mode==1)
+ {
+ if (lx[0][y] || ly[0][y])
+ {
+ int points[6] = { c_x,h/2, lx[0][y], ly[0][y], xp+c_x,yp+h/2 };
+ my_triangle(framebuffer,points,w,h,oc6);
+ }
+ lx[0][y]=xp+c_x;
+ ly[0][y]=yp+h/2;
+ if (lx[1][y] || ly[1][y])
+ {
+ int points[6] = { c_x,h/2, lx[1][y], ly[1][y], c_x-xp,h/2-yp };
+ my_triangle(framebuffer,points,w,h,oc6);
+ }
+ lx[1][y]=c_x-xp;
+ ly[1][y]=h/2-yp;
+ }
+ }
+ return 0;
+}
+
+C_RBASE *R_BSpin(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_LC:
+ GR_DrawColoredButton(di,g_this->colors[0]);
+ break;
+ case IDC_RC:
+ GR_DrawColoredButton(di,g_this->colors[1]);
+ break;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ if (g_this->enabled&1) CheckDlgButton(hwndDlg,IDC_LEFT,BST_CHECKED);
+ if (g_this->enabled&2) CheckDlgButton(hwndDlg,IDC_RIGHT,BST_CHECKED);
+ if (g_this->mode==0) CheckDlgButton(hwndDlg,IDC_LINES,BST_CHECKED);
+ if (g_this->mode==1) CheckDlgButton(hwndDlg,IDC_TRI,BST_CHECKED);
+
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_LINES:
+ g_this->mode=IsDlgButtonChecked(hwndDlg,IDC_LINES)?0:1;
+ return 0;
+ case IDC_TRI:
+ g_this->mode=IsDlgButtonChecked(hwndDlg,IDC_TRI)?1:0;
+ return 0;
+ case IDC_LEFT:
+ g_this->enabled&=~1;
+ g_this->enabled|=IsDlgButtonChecked(hwndDlg,IDC_LEFT)?1:0;
+ return 0;
+ case IDC_RIGHT:
+ g_this->enabled&=~2;
+ g_this->enabled|=IsDlgButtonChecked(hwndDlg,IDC_RIGHT)?2:0;
+ return 0;
+ case IDC_LC:
+ if (!a) a=&g_this->colors[0];
+ case IDC_RC:
+ if (!a) a=&g_this->colors[1];
+ GR_SelectColor(hwndDlg,a);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ return 0;
+
+
+ }
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_BSPIN,hwndParent,g_DlgProc);
+}
+
+
+
+#define F16(x) ((x)<<16)
+
+void C_THISCLASS::my_triangle(int *fb, int points[6], int width, int height, int color)
+{
+ int ymax;
+ int p;
+ int y;
+ int dx1,dx2;
+ int x1,x2;
+ for (y = 0; y < 2; y ++)
+ {
+ if (points[1] > points[3])
+ {
+ p=points[2]; points[2]=points[0]; points[0]=p;
+ p=points[3]; points[3]=points[1]; points[1]=p;
+ }
+ if (points[3] > points[5])
+ {
+ p=points[4]; points[4]=points[2]; points[2]=p;
+ p=points[5]; points[5]=points[3]; points[3]=p;
+ }
+ }
+
+ x1=x2=F16(points[0]);
+ if (points[1] < points[3])
+ {
+ dx1 = F16(points[2]-points[0])/(points[3]-points[1]);
+ } else dx1=0;
+
+ if (points[1] < points[5])
+ dx2 = F16(points[4]-points[0])/(points[5]-points[1]);
+ else dx2=0;
+
+ fb += points[1]*width;
+ ymax = min(points[5],height);
+ for (y = points[1]; y < ymax; y ++)
+ {
+ if (y == points[3])
+ {
+ if (y == points[5]) return;
+ x1=F16(points[2]);
+ dx1=F16(points[4]-points[2])/(points[5]-points[3]);
+ }
+ if (y >= 0) {
+ int x,xl;
+ x=(min(x1,x2)-32768)>>16;
+ xl=((max(x1,x2)+32768)>>16)-x;
+ if (xl < 0) xl=-xl;
+ if (!xl) xl++;
+ {
+ int *t=fb+x;
+ if (x < 0) { t-=x; xl-=x; }
+ if (x+xl >= width) xl=width-x;
+ if (xl>0) while (xl--) BLEND_LINE(t++,color);
+ }
+ }
+ fb += width;
+ x1+=dx1;
+ x2+=dx2;
+ }
+
+}
+
+#else
+C_RBASE *R_BSpin(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_bump.cpp b/Src/Plugins/Visualization/vis_avs/r_bump.cpp
new file mode 100644
index 00000000..5d0e5fdd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_bump.cpp
@@ -0,0 +1,562 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "r_stack.h"
+#include "avs_eelif.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Bump"
+#define C_THISCLASS C_BumpClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ float GET_FLOAT(unsigned char *data, int pos);
+ void PUT_FLOAT(float f, unsigned char *data, int pos);
+ void InitializeStars(int Start);
+ void CreateStar(int A);
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_BUMP,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int __inline depthof(int c, int i);
+ int enabled;
+ int depth;
+ int depth2;
+ int onbeat;
+ int durFrames;
+ int thisDepth;
+ int blend;
+ int blendavg;
+ int nF;
+ NSEEL_CODEHANDLE codeHandle;
+ NSEEL_CODEHANDLE codeHandleBeat;
+ NSEEL_CODEHANDLE codeHandleInit;
+ double *var_x;
+ double *var_y;
+ double *var_isBeat;
+ double *var_isLongBeat;
+ double *var_bi;
+ RString code1,code2,code3;
+ int need_recompile;
+ int showlight;
+ int initted;
+ int invert;
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ int oldstyle;
+ int buffern;
+ CRITICAL_SECTION rcs;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+ freeCode(codeHandle);
+ freeCode(codeHandleBeat);
+ freeCode(codeHandleInit);
+ DeleteCriticalSection(&rcs);
+ AVS_EEL_QUITINST();
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ AVS_EEL_INITINST();
+ InitializeCriticalSection(&rcs);
+ buffern=0;
+ oldstyle=0;
+ invert=0;
+ enabled=1;
+ onbeat = 0;
+ durFrames = 15;
+ depth=30;
+ depth2=100;
+ nF=0;
+ showlight=0;
+ thisDepth=depth;
+ blend = 0;
+ blendavg = 0;
+ code1.assign("x=0.5+cos(t)*0.3;\r\ny=0.5+sin(t)*0.3;\r\nt=t+0.1;");
+ code2.assign("");
+ code3.assign("t=0;");
+ codeHandle=0;
+ codeHandleBeat=0;
+ codeHandleInit=0;
+ var_bi=0;
+ initted=0;
+
+ need_recompile=1;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { durFrames=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { depth=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { depth2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ load_string(code1,data,pos,len);
+ load_string(code2,data,pos,len);
+ load_string(code3,data,pos,len);
+ if (len-pos >= 4) { showlight=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { invert=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { oldstyle=GET_INT(); pos+=4; } else oldstyle=1;
+ if (len-pos >= 4) { buffern=GET_INT(); pos+=4; }
+ thisDepth=depth;
+ nF=0;
+
+ need_recompile=1;
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+
+
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_INT(durFrames); pos+=4;
+ PUT_INT(depth); pos+=4;
+ PUT_INT(depth2); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ save_string(data, pos, code1);
+ save_string(data, pos, code2);
+ save_string(data, pos, code3);
+ PUT_INT(showlight); pos+=4;
+ PUT_INT(invert); pos+=4;
+ PUT_INT(oldstyle); pos+=4;
+ PUT_INT(buffern); pos+=4;
+ return pos;
+}
+
+int __inline C_THISCLASS::depthof(int c, int i)
+{
+int r= max(max((c & 0xFF), ((c & 0xFF00)>>8)), (c & 0xFF0000)>>16);
+return i ? 255 - r : r;
+}
+
+static int __inline setdepth(int l, int c)
+{
+int r;
+r=min((c&0xFF)+l, 254);
+r|=min(((c&0xFF00))+(l<<8),254<<8);
+r|=min(((c&0xFF0000))+(l<<16),254<<16);
+return r;
+}
+
+static int __inline setdepth0(int c)
+{
+int r;
+r=min((c&0xFF), 254);
+r|=min(((c&0xFF00)),254<<8);
+r|=min(((c&0xFF0000)),254<<16);
+return r;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+#define abs(x) (( x ) >= 0 ? ( x ) : - ( x ))
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int cx,cy;
+ int curbuf;
+
+ if (!enabled) return 0;
+
+ if (need_recompile)
+ {
+ EnterCriticalSection(&rcs);
+ if (!var_bi || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_x = registerVar("x");
+ var_y = registerVar("y");
+ var_isBeat = registerVar("isbeat");
+ var_isLongBeat = registerVar("islbeat");
+ var_bi = registerVar("bi");
+ *var_bi = 1.0;
+ initted=0;
+ }
+
+ need_recompile=0;
+
+ freeCode(codeHandle);
+ freeCode(codeHandleBeat);
+ freeCode(codeHandleInit);
+ codeHandle = compileCode(code1.get());
+ codeHandleBeat = compileCode(code2.get());
+ codeHandleInit = compileCode(code3.get());
+
+ LeaveCriticalSection(&rcs);
+ }
+ if (isBeat&0x80000000) return 0;
+
+ int *depthbuffer = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
+ if (!depthbuffer) return 0;
+
+ curbuf = (depthbuffer==framebuffer);
+
+ if (!initted)
+ {
+ executeCode(codeHandleInit,visdata);
+ initted=1;
+ }
+
+ executeCode(codeHandle,visdata);
+ if (isBeat) executeCode(codeHandleBeat,visdata);
+
+ if (isBeat)
+ *var_isBeat=-1;
+ else
+ *var_isBeat=1;
+ if (nF)
+ *var_isLongBeat=-1;
+ else
+ *var_isLongBeat=1;
+
+ if (onbeat && isBeat)
+ {
+ thisDepth=depth2;
+ nF = durFrames;
+ }
+ else if (!nF) thisDepth = depth;
+
+ memset(fbout, 0, w*h*4); // previous effects may have left fbout in a mess
+
+ if (oldstyle)
+ {
+ cx = (int)(*var_x/100.0*w);
+ cy = (int)(*var_y/100.0*h);
+ }
+ else
+ {
+ cx = (int)(*var_x*w);
+ cy = (int)(*var_y*h);
+ }
+ cx = max(0, min(w, cx));
+ cy = max(0, min(h, cy));
+ if (showlight) fbout[cx+cy*w]=0xFFFFFF;
+
+ if (var_bi)
+ {
+ *var_bi = min(max(*var_bi, 0), 1);
+ thisDepth = (int)(thisDepth * *var_bi);
+ }
+
+ int thisDepth_scaled=(thisDepth<<8)/100;
+ depthbuffer += w+1;
+ framebuffer += w+1;
+ fbout += w+1;
+
+ int ly=1-cy;
+ int i=h-2;
+ while (i--)
+ {
+ int j=w-2;
+ int lx=1-cx;
+ if (blend)
+ {
+ while (j--)
+ {
+ int m1,p1,mw,pw;
+ m1=depthbuffer[-1];
+ p1=depthbuffer[1];
+ mw=depthbuffer[-w];
+ pw=depthbuffer[w];
+ if (!curbuf || (curbuf && (m1||p1||mw||pw)))
+ {
+ int coul1,coul2;
+ coul1=depthof(p1, invert)-depthof(m1, invert)-lx;
+ coul2=depthof(pw, invert)-depthof(mw, invert)-ly;
+ coul1=127-abs(coul1);
+ coul2=127-abs(coul2);
+ if (coul1<=0||coul2<=0)
+ coul1=setdepth0(framebuffer[0]);
+ else
+ coul1=setdepth((coul1*coul2*thisDepth_scaled)>>(8+6), framebuffer[0]);
+ fbout[0]=BLEND(framebuffer[0], coul1);
+ }
+ depthbuffer++;
+ framebuffer++;
+ fbout++;
+ lx++;
+ }
+ }
+ else if (blendavg)
+ {
+ while (j--)
+ {
+ int m1,p1,mw,pw;
+ m1=depthbuffer[-1];
+ p1=depthbuffer[1];
+ mw=depthbuffer[-w];
+ pw=depthbuffer[w];
+ if (!curbuf || (curbuf && (m1||p1||mw||pw)))
+ {
+ int coul1,coul2;
+ coul1=depthof(p1, invert)-depthof(m1, invert)-lx;
+ coul2=depthof(pw, invert)-depthof(mw, invert)-ly;
+ coul1=127-abs(coul1);
+ coul2=127-abs(coul2);
+ if (coul1<=0||coul2<=0)
+ coul1=setdepth0(framebuffer[0]);
+ else
+ coul1=setdepth((coul1*coul2*thisDepth_scaled)>>(8+6), framebuffer[0]);
+ fbout[0]=BLEND_AVG(framebuffer[0], coul1);
+ }
+ depthbuffer++;
+ framebuffer++;
+ fbout++;
+ lx++;
+ }
+ }
+ else
+ {
+ while (j--)
+ {
+ int m1,p1,mw,pw;
+ m1=depthbuffer[-1];
+ p1=depthbuffer[1];
+ mw=depthbuffer[-w];
+ pw=depthbuffer[w];
+ if (!curbuf || (curbuf && (m1||p1||mw||pw)))
+ {
+ int coul1,coul2;
+ coul1=depthof(p1, invert)-depthof(m1, invert)-lx;
+ coul2=depthof(pw, invert)-depthof(mw, invert)-ly;
+ coul1=127-abs(coul1);
+ coul2=127-abs(coul2);
+ if (coul1<=0||coul2<=0)
+ coul1=setdepth0(framebuffer[0]);
+ else
+ coul1=setdepth((coul1*coul2*thisDepth_scaled)>>(8+6), framebuffer[0]);
+ fbout[0]=coul1;
+ }
+ depthbuffer++;
+ framebuffer++;
+ fbout++;
+ lx++;
+ }
+ }
+ depthbuffer+=2;
+ framebuffer+=2;
+ fbout+=2;
+ ly++;
+ }
+
+ if (nF)
+ {
+ nF--;
+ if (nF)
+ {
+ int a = abs(depth - depth2) / durFrames;
+ thisDepth += a * (depth2 > depth ? -1 : 1);
+ }
+ }
+
+ return 1;
+}
+
+// configuration dialog stuff
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hwndDlg, IDC_CODE1, g_ConfigThis->code1.get());
+ SetDlgItemText(hwndDlg, IDC_CODE2, g_ConfigThis->code2.get());
+ SetDlgItemText(hwndDlg, IDC_CODE3, g_ConfigThis->code3.get());
+ SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_SETPOS, TRUE, g_ConfigThis->depth);
+ SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_SETPOS, TRUE, g_ConfigThis->depth2);
+ SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETPOS, TRUE, g_ConfigThis->durFrames);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->invert) CheckDlgButton(hwndDlg,IDC_INVERTDEPTH,BST_CHECKED);
+ if (g_ConfigThis->onbeat) CheckDlgButton(hwndDlg,IDC_ONBEAT,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (g_ConfigThis->showlight) CheckDlgButton(hwndDlg,IDC_DOT,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_CURRENT));
+ {
+ int i=0;
+ char txt[64];
+ for (i=0;i<NBUF;i++)
+ {
+ wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
+ SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)txt);
+ }
+ }
+ SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_SETCURSEL, (WPARAM) g_ConfigThis->buffern, 0);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_DEPTH)
+ g_ConfigThis->depth = SendDlgItemMessage(hwndDlg, IDC_DEPTH, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_DEPTH2)
+ g_ConfigThis->depth2 = SendDlgItemMessage(hwndDlg, IDC_DEPTH2, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_BEATDUR)
+ g_ConfigThis->durFrames = SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_GETPOS, 0, 0);
+ }
+ return 0;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_HELPBTN)
+ {
+/* char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_BUMP_LIGHT_POSITION,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_BUMP_LIGHT_POSITION),4095-titlelen);
+*/
+ char *text="Bump Light Position\0"
+ "How to use the custom light position evaluator:\r\n"
+ " * Init code will be executed each time the window size is changed\r\n"
+ " or when the effect loads\r\n"
+ " * Frame code is executed before rendering a new frame\r\n"
+ " * Beat code is executed when a beat is detected\r\n"
+ "\r\n"
+ "Predefined variables:\r\n"
+ " x : Light x position, ranges from 0 (left) to 1 (right) (0.5 = center)\r\n"
+ " y : Light y position, ranges from 0 (top) to 1 (bottom) (0.5 = center)\r\n"
+ " isBeat : 1 if no beat, -1 if beat (weird, but old)\r\n"
+ " isLBeat: same as isBeat but persists according to 'shorter/longer' settings\r\n"
+ " (usable only with OnBeat checked)\r\n"
+ " bi: Bump intensity, ranges from 0 (flat) to 1 (max specified bump, default)\r\n"
+ " You may also use temporary variables accross code segments\r\n"
+ "\r\n"
+ "Some examples:\r\n"
+ " Circular move\r\n"
+ " Init : t=0\r\n"
+ " Frame: x=0.5+cos(t)*0.3; y=0.5+sin(t)*0.3; t=t+0.1;\r\n"
+ " Nice motion:\r\n"
+ " Init : t=0;u=0\r\n"
+ " Frame: x=0.5+cos(t)*0.3; y=0.5+cos(u)*0.3; t=t+0.1; u=u+0.012;\r\n"
+ ;
+ compilerfunctionlist(hwndDlg,text);
+ return 0;
+ }
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ONBEAT) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_DOT) ||
+ (LOWORD(wParam) == IDC_INVERTDEPTH) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->showlight=IsDlgButtonChecked(hwndDlg,IDC_DOT)?1:0;
+ g_ConfigThis->invert=IsDlgButtonChecked(hwndDlg,IDC_INVERTDEPTH)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_CODE1 && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_ConfigThis->rcs);
+ g_ConfigThis->code1.get_from_dlgitem(hwndDlg,IDC_CODE1);
+ g_ConfigThis->need_recompile=1;
+ LeaveCriticalSection(&g_ConfigThis->rcs);
+ }
+ if (LOWORD(wParam) == IDC_CODE2 && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_ConfigThis->rcs);
+ g_ConfigThis->code2.get_from_dlgitem(hwndDlg,IDC_CODE2);
+ g_ConfigThis->need_recompile=1;
+ LeaveCriticalSection(&g_ConfigThis->rcs);
+ }
+ if (LOWORD(wParam) == IDC_CODE3 && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_ConfigThis->rcs);
+ g_ConfigThis->code3.get_from_dlgitem(hwndDlg,IDC_CODE3);
+ g_ConfigThis->need_recompile=1;
+ g_ConfigThis->initted=0;
+ LeaveCriticalSection(&g_ConfigThis->rcs);
+ }
+ if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMBO1) // handle clicks to combo box
+ g_ConfigThis->buffern = SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0);
+ return 0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_BUMP,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Bump(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Bump(char *desc) { return NULL; }
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/r_chanshift.cpp b/Src/Plugins/Visualization/vis_avs/r_chanshift.cpp
new file mode 100644
index 00000000..7bf60ea4
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_chanshift.cpp
@@ -0,0 +1,362 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include <time.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+// this will be the directory and APE name displayed in the AVS Editor
+#define MOD_NAME "Trans / Channel Shift"
+
+#define C_THISCLASS C_ChannelShiftClass
+
+
+typedef struct {
+ int mode;
+ int onbeat;
+} apeconfig;
+
+class C_THISCLASS : public C_RBASE
+{
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual char *get_desc();
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ apeconfig config;
+
+ HWND hwndDlg;
+};
+
+// global configuration dialog pointer
+static C_THISCLASS *g_ConfigThis;
+static HINSTANCE g_hDllInstance;
+
+
+// this is where we deal with the configuration screen
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ int ids[] = { IDC_RBG, IDC_BRG, IDC_BGR, IDC_GBR, IDC_GRB, IDC_RGB };
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ if (HIWORD(wParam) == BN_CLICKED) {
+ for (int i=0;i<sizeof(ids)/sizeof(ids[0]);i++)
+ if (IsDlgButtonChecked(hwndDlg, ids[i]))
+ g_ConfigThis->config.mode = ids[i];
+ g_ConfigThis->config.onbeat = IsDlgButtonChecked(hwndDlg, IDC_ONBEAT) ? 1 : 0;
+ }
+ return 1;
+
+
+ case WM_INITDIALOG:
+ g_ConfigThis->hwndDlg = hwndDlg;
+
+ CheckDlgButton(hwndDlg, g_ConfigThis->config.mode, 1);
+ if (g_ConfigThis->config.onbeat)
+ CheckDlgButton(hwndDlg, IDC_ONBEAT, 1);
+
+ return 1;
+
+ case WM_DESTROY:
+ KillTimer(hwndDlg, 1);
+ return 1;
+ }
+ return 0;
+}
+
+// set up default configuration
+C_THISCLASS::C_THISCLASS()
+{
+ memset(&config, 0, sizeof(apeconfig));
+ config.mode = IDC_RBG;
+ config.onbeat = 1;
+}
+
+// virtual destructor
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+
+ int c;
+ int modes[] = { IDC_RGB, IDC_RBG, IDC_GBR, IDC_GRB, IDC_BRG, IDC_BGR };
+
+ if (isBeat && config.onbeat) {
+ config.mode = modes[rand() % 6];
+ }
+
+ c = w*h;
+
+ switch (config.mode) {
+ default:
+ case IDC_RGB:
+ return 0;
+ case IDC_RBG:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp1:
+ sub ecx, 4;
+
+ mov eax, dword ptr [ebx+ecx*4];
+ xchg ah, al;
+ mov [ebx+ecx*4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+4];
+ xchg ah, al;
+ mov [ebx+ecx*4+4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+8];
+ xchg ah, al;
+ mov [ebx+ecx*4+8], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+12];
+ xchg ah, al;
+ mov [ebx+ecx*4+12], eax;
+
+ test ecx, ecx;
+ jnz lp1;
+ }
+ break;
+
+ case IDC_BRG:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp2:
+ sub ecx, 4;
+
+ mov eax, dword ptr [ebx+ecx*4];
+ mov dl, al;
+ shr eax, 8;
+ bswap eax;
+ mov ah, dl;
+ bswap eax;
+ mov [ebx+ecx*4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+4];
+ mov dl, al;
+ shr eax, 8;
+ bswap eax;
+ mov ah, dl;
+ bswap eax;
+ mov [ebx+ecx*4+4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+8];
+ mov dl, al;
+ shr eax, 8;
+ bswap eax;
+ mov ah, dl;
+ bswap eax;
+ mov [ebx+ecx*4+8], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+12];
+ mov dl, al;
+ shr eax, 8;
+ bswap eax;
+ mov ah, dl;
+ bswap eax;
+ mov [ebx+ecx*4+12], eax;
+
+ test ecx, ecx;
+ jnz lp2;
+ }
+ break;
+
+ case IDC_BGR:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp3:
+ sub ecx, 4;
+
+ mov eax, dword ptr [ebx+ecx*4];
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+4];
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4+4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+8];
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4+8], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+12];
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4+12], eax;
+
+ test ecx, ecx;
+ jnz lp3;
+ }
+ break;
+
+ case IDC_GBR:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp4:
+ sub ecx, 4;
+
+ mov eax, dword ptr [ebx+ecx*4];
+ mov edx, eax;
+ bswap edx;
+ shl eax, 8;
+ mov al, dh;
+ mov [ebx+ecx*4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+4];
+ mov edx, eax;
+ bswap edx;
+ shl eax, 8;
+ mov al, dh;
+ mov [ebx+ecx*4+4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+8];
+ mov edx, eax;
+ bswap edx;
+ shl eax, 8;
+ mov al, dh;
+ mov [ebx+ecx*4+8], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+12];
+ mov edx, eax;
+ bswap edx;
+ shl eax, 8;
+ mov al, dh;
+ mov [ebx+ecx*4+12], eax;
+
+ test ecx, ecx;
+ jnz lp4;
+ }
+ break;
+
+ case IDC_GRB:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp5:
+ sub ecx, 4;
+
+ mov eax, dword ptr [ebx+ecx*4];
+ shl eax, 8;
+ bswap eax;
+ xchg ah, al;
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+4];
+ shl eax, 8;
+ bswap eax;
+ xchg ah, al;
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4+4], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+8];
+ shl eax, 8;
+ bswap eax;
+ xchg ah, al;
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4+8], eax;
+
+ mov eax, dword ptr [ebx+ecx*4+12];
+ shl eax, 8;
+ bswap eax;
+ xchg ah, al;
+ bswap eax;
+ shr eax, 8;
+ mov [ebx+ecx*4+12], eax;
+
+ test ecx, ecx;
+ jnz lp5;
+ }
+ break;
+ }
+ return 0;
+}
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_CHANSHIFT, hwndParent, (DLGPROC)g_DlgProc);
+}
+
+
+char *C_THISCLASS::get_desc(void)
+{
+ static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_CHANNEL_SHIFT,desc,128):desc);
+}
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ srand((unsigned int)time(0));
+ if (len <= sizeof(apeconfig))
+ memcpy(&this->config, data, len);
+}
+
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ memcpy(data, &this->config, sizeof(apeconfig));
+ return sizeof(apeconfig);
+}
+
+C_RBASE *R_ChannelShift(char *desc)
+{
+ if (desc) {
+ strcpy(desc,MOD_NAME);
+ return NULL;
+ }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_clear.cpp b/Src/Plugins/Visualization/vis_avs/r_clear.cpp
new file mode 100644
index 00000000..21021b6b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_clear.cpp
@@ -0,0 +1,231 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Render / Clear screen"
+#define C_THISCLASS C_ClearClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_CLEAR_SCREEN,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int enabled;
+ int onlyfirst;
+ int color;
+ int fcounter;
+ int blend, blendavg;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ color = 0;
+ onlyfirst = 0;
+ fcounter=0;
+ blend = 0;
+ blendavg = 0;
+ enabled=1;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onlyfirst=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(onlyfirst); pos+=4;
+ return pos;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int i=w*h;
+ int *p=framebuffer;
+
+ if (!enabled) return 0;
+ if (onlyfirst && fcounter) return 0;
+ if (isBeat&0x80000000) return 0;
+
+ fcounter++;
+
+ if (blend==2) while (i--) BLEND_LINE(p++,color);
+ else if (blend) while (i--) *p++=BLEND(*p,color);
+ else if (blendavg) while (i--) *p++=BLEND_AVG(*p,color);
+ else while (i--) *p++=color;
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->onlyfirst) CheckDlgButton(hwndDlg,IDC_CLEARFIRSTFRAME,BST_CHECKED);
+ if (g_ConfigThis->blend==1) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ else if (g_ConfigThis->blend==2) CheckDlgButton(hwndDlg,IDC_DEFRENDBLEND,BST_CHECKED);
+ else if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL) // paint nifty color button
+ {
+ int w=di->rcItem.right-di->rcItem.left;
+ int _color=g_ConfigThis->color;
+ _color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={(COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) ||
+ (LOWORD(wParam) == IDC_DEFRENDBLEND))
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ if (!g_ConfigThis->blend)
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_DEFRENDBLEND)?2:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_CLEARFIRSTFRAME)
+ {
+ g_ConfigThis->onlyfirst=IsDlgButtonChecked(hwndDlg,IDC_CLEARFIRSTFRAME)?1:0;
+ if (g_ConfigThis->onlyfirst) g_ConfigThis->fcounter=0;
+ }
+
+ if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
+ {
+ int *a=&(g_ConfigThis->color);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ g_ConfigThis->color = *a;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_CLEAR,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Clear(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Clear(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_colorfade.cpp b/Src/Plugins/Visualization/vis_avs/r_colorfade.cpp
new file mode 100644
index 00000000..021a6cd1
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_colorfade.cpp
@@ -0,0 +1,357 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_ColorFadeClass
+#define MOD_NAME "Trans / Colorfade"
+
+class C_THISCLASS : public C_RBASE2 {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLORFADE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+
+ virtual int smp_getflags() { return 1; }
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // return value is that of render() for fbstuff etc
+ static int ft[4][3];
+
+
+ int enabled;
+ int faders[3];
+ int beatfaders[3];
+ int faderpos[3];
+ unsigned char c_tab[512][512];
+ unsigned char clip[256+40+40];
+};
+int C_THISCLASS::ft[4][3];
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { faders[0]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { faders[1]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { faders[2]=GET_INT(); pos+=4; }
+ memcpy(beatfaders,faders,3*sizeof(int));
+ if (len-pos >= 4) { beatfaders[0]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatfaders[1]=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatfaders[2]=GET_INT(); pos+=4; }
+ memcpy(faderpos,faders,3*sizeof(int));
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(faders[0]); pos+=4;
+ PUT_INT(faders[1]); pos+=4;
+ PUT_INT(faders[2]); pos+=4;
+ PUT_INT(beatfaders[0]); pos+=4;
+ PUT_INT(beatfaders[1]); pos+=4;
+ PUT_INT(beatfaders[2]); pos+=4;
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ int x,y;
+ enabled=1;
+ faders[0]=8;
+ faders[1]=faders[2]=-8;
+ memcpy(beatfaders,faders,3*sizeof(int));
+ memcpy(faderpos,faders,3*sizeof(int));
+ for (x = 0; x < 512; x ++)
+ {
+ for (y = 0; y < 512; y ++)
+ {
+ int xp=x-255;
+ int yp=y-255;
+ if (xp > 0 /* g-b > 0, or g > b */ && xp > -yp /* g-b > r-b, or g > r */ ) c_tab[x][y]=0;
+ else if (yp < 0 /* b-r < 0 or r > b */ && xp < -yp /* g-b < r-b, or g < r */ ) c_tab[x][y]=1;
+ else if (xp < 0 && yp > 0) c_tab[x][y]=2;
+ else c_tab[x][y]=3;
+ }
+ }
+ for (x = 0; x < 256+40+40; x ++)
+ clip[x]=min(max(x-40,0),255);
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
+ if (isBeat & 0x80000000) return 0;
+
+ smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
+ return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
+}
+
+int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled || (isBeat&0x80000000)) return 0;
+
+ if (faderpos[0] < faders[0]) faderpos[0]++;
+ if (faderpos[1] < faders[2]) faderpos[1]++;
+ if (faderpos[2] < faders[1]) faderpos[2]++;
+ if (faderpos[0] > faders[0]) faderpos[0]--;
+ if (faderpos[1] > faders[2]) faderpos[1]--;
+ if (faderpos[2] > faders[1]) faderpos[2]--;
+
+ if (!(enabled&4))
+ {
+ faderpos[0]=faders[0];
+ faderpos[1]=faders[1];
+ faderpos[2]=faders[2];
+ }
+ else if (isBeat && (enabled&2))
+ {
+ faderpos[0]=(rand()%32)-6;
+ faderpos[1]=(rand()%64)-32;
+ if (faderpos[1] < 0 && faderpos[1] > -16) faderpos[1]=-32;
+ if (faderpos[1] >= 0 && faderpos[1] < 16) faderpos[1]=32;
+ faderpos[2]=(rand()%32)-6;
+ }
+ else if (isBeat)
+ {
+ faderpos[0]=beatfaders[0];
+ faderpos[1]=beatfaders[1];
+ faderpos[2]=beatfaders[2];
+ }
+
+ {
+ int fs1,fs2,fs3;
+ fs1=faderpos[0];
+ fs2=faderpos[1];
+ fs3=faderpos[2];
+
+ ft[0][0]=fs3;
+ ft[0][1]=fs2;
+ ft[0][2]=fs1;
+
+ ft[1][0]=fs2;
+ ft[1][1]=fs1;
+ ft[1][2]=fs3;
+
+ ft[2][0]=fs1;
+ ft[2][1]=fs3;
+ ft[2][2]=fs2;
+
+ ft[3][0]=fs3;
+ ft[3][1]=fs3;
+ ft[3][2]=fs3;
+ }
+
+ return max_threads;
+}
+
+int C_THISCLASS::smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // return value is that of render() for fbstuff etc
+{
+ return 0;
+}
+
+
+void C_THISCLASS::smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return;
+
+ if (max_threads < 1) max_threads=1;
+
+ int start_l = ( this_thread * h ) / max_threads;
+ int end_l;
+
+ if (this_thread >= max_threads - 1) end_l = h;
+ else end_l = ( (this_thread+1) * h ) / max_threads;
+
+ int outh=end_l-start_l;
+ if (outh<1) return;
+
+ unsigned char *q=(unsigned char *)(framebuffer + start_l*w);
+
+ unsigned char *ctab_ptr=(unsigned char *)c_tab[0]+255+(255<<9);
+ unsigned char *clip_ptr=(unsigned char *)clip+40;
+
+ int x=w*outh;
+
+ if (enabled)
+ {
+ int lx=x&1;
+ x>>=1;
+ while (x--)
+ {
+ int r=q[0];
+ int g=q[1];
+ int b=q[2];
+ int r2=q[4];
+ int g2=q[5];
+ int b2=q[6];
+ int i=((g-b)<<9) + b - r;
+ int i2=((g2-b2)<<9) + b2 - r2;
+ int p=ctab_ptr[i];
+ int p2=ctab_ptr[i2];
+
+ q[0]=clip_ptr[r+ft[p][0]];
+ q[1]=clip_ptr[g+ft[p][1]];
+ q[2]=clip_ptr[b+ft[p][2]];
+ q[4]=clip_ptr[r2+ft[p2][0]];
+ q[5]=clip_ptr[g2+ft[p2][1]];
+ q[6]=clip_ptr[b2+ft[p2][2]];
+ q+=8;
+ }
+ if (lx)
+ {
+ int r=q[0];
+ int g=q[1];
+ int b=q[2];
+ int i=((g-b)<<9) + b - r;
+ int p=ctab_ptr[i];
+ q[0]=clip_ptr[r+ft[p][0]];
+ q[1]=clip_ptr[g+ft[p][1]];
+ q[2]=clip_ptr[b+ft[p][2]];
+ }
+ }
+}
+
+C_RBASE *R_ColorFade(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->faders[0]+32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->faders[1]+32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->faders[2]+32);
+
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->beatfaders[0]+32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETPOS,1,g_this->beatfaders[1]+32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETPOS,1,g_this->beatfaders[2]+32);
+
+ if (g_this->enabled&1) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_this->enabled&2) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ if (g_this->enabled&4) CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHECK1:
+ case IDC_CHECK2:
+ case IDC_CHECK3:
+ g_this->enabled=(IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0)|
+ (IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?2:0)|
+ (IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?4:0);
+ return 0;
+
+ }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->faders[0]=t-32;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
+ {
+ g_this->faders[1]=t-32;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
+ {
+ g_this->faders[2]=t-32;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
+ {
+ g_this->beatfaders[0]=t-32;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER5))
+ {
+ g_this->beatfaders[1]=t-32;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER6))
+ {
+ g_this->beatfaders[2]=t-32;
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_COLORFADE,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_ColorFade(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_colorreduction.cpp b/Src/Plugins/Visualization/vis_avs/r_colorreduction.cpp
new file mode 100644
index 00000000..2d4fa7a4
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_colorreduction.cpp
@@ -0,0 +1,193 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+// this will be the directory and APE name displayed in the AVS Editor
+#define MOD_NAME "Trans / Color Reduction"
+#define C_THISCLASS C_ColorReduction
+
+typedef struct {
+ char fname[MAX_PATH];
+ int levels;
+} apeconfig;
+
+class C_THISCLASS : public C_RBASE
+{
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual char *get_desc();
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ apeconfig config;
+
+ HWND hwndDlg;
+};
+
+// global configuration dialog pointer
+static C_THISCLASS *g_ConfigThis;
+static HINSTANCE g_hDllInstance;
+
+
+// this is where we deal with the configuration screen
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_HSCROLL:
+ {
+ if (LOWORD(wParam) == TB_ENDTRACK)
+ g_ConfigThis->config.levels = SendMessage(GetDlgItem(hwndDlg, IDC_LEVELS), TBM_GETPOS, 0, 0);
+ {
+ char buf[4];
+ int a,b;
+ a = 8-g_ConfigThis->config.levels;
+ b = 0x100;
+ while (a--) b>>=1;
+ wsprintf(buf, "%d", b);
+ SetDlgItemText(hwndDlg, IDC_LEVELTEXT, buf);
+ }
+ }
+ return 1;
+
+ case WM_INITDIALOG:
+ g_ConfigThis->hwndDlg = hwndDlg;
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_LEVELS), TBM_SETRANGE, TRUE, MAKELONG(1, 8));
+ SendMessage(GetDlgItem(hwndDlg, IDC_LEVELS), TBM_SETPOS, TRUE, g_ConfigThis->config.levels);
+ SetFocus(GetDlgItem(hwndDlg, IDC_LEVELS));
+ {
+ char buf[4];
+ int a,b;
+ a = 8-g_ConfigThis->config.levels;
+ b = 0x100;
+ while (a--) b>>=1;
+ wsprintf(buf, "%d", b);
+ SetDlgItemText(hwndDlg, IDC_LEVELTEXT, buf);
+ }
+ return 1;
+
+ case WM_DESTROY:
+ KillTimer(hwndDlg, 1);
+ return 1;
+ }
+ return 0;
+}
+
+// set up default configuration
+C_THISCLASS::C_THISCLASS()
+{
+ memset(&config, 0, sizeof(apeconfig));
+ config.levels = 7;
+}
+
+// virtual destructor
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+
+ int a,b,c;
+ a = 8-config.levels;
+ b = 0xFF;
+ while (a--) b=(b<<1)&0xFF;
+ b |= (b<<16) | (b<<8);
+ c = w*h;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ mov edx, b;
+ lp:
+ sub ecx, 4;
+ test ecx, ecx;
+ jz end;
+ and dword ptr [ebx+ecx*4], edx;
+ and dword ptr [ebx+ecx*4+4], edx;
+ and dword ptr [ebx+ecx*4+8], edx;
+ and dword ptr [ebx+ecx*4+12], edx;
+ jmp lp;
+ end:
+ }
+ return 0;
+}
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_COLORREDUCTION, hwndParent, (DLGPROC)g_DlgProc);
+}
+
+
+char *C_THISCLASS::get_desc(void)
+{
+ static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_REDUCTION,desc,128):desc);
+}
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ if (len == sizeof(apeconfig))
+ memcpy(&this->config, data, len);
+ else
+ memset(&this->config, 0, sizeof(apeconfig));
+}
+
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ memcpy(data, &this->config, sizeof(apeconfig));
+ return sizeof(apeconfig);
+}
+
+C_RBASE *R_ColorReduction(char *desc)
+{
+ if (desc) {
+ strcpy(desc,MOD_NAME);
+ return NULL;
+ }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_colorreplace.cpp b/Src/Plugins/Visualization/vis_avs/r_colorreplace.cpp
new file mode 100644
index 00000000..adf4d775
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_colorreplace.cpp
@@ -0,0 +1,159 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#define C_THISCLASS C_ContrastEnhanceClass
+#define MOD_NAME "Trans / Color Clip"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_CLIP,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int enabled;
+ int color_clip;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color_clip=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color_clip); pos+=4;
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ enabled=1;
+ color_clip=RGB(32,32,32);
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ unsigned int *f = (unsigned int *) framebuffer;
+ int fs_r,fs_g,fs_b;
+ int x=w*h;
+ if (!enabled) return 0;
+
+ fs_b=(color_clip>>16)&255;
+ fs_g=(color_clip>>8)&255;
+ fs_r=(color_clip)&255;
+
+ while (x--)
+ {
+ int r=f[0]&255;
+ int g=(f[0]>>8)&255;
+ int b=(f[0]>>16)&255;
+ int a=(f[0]&0xff000000);
+ if (r <= fs_r && g <= fs_g && b <= fs_b)
+ f[0]=a|fs_r|(fs_g<<8)|(fs_b<<16);
+ f++;
+ }
+ return 0;
+}
+
+C_RBASE *R_ContrastEnhance(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_LC:
+ GR_DrawColoredButton(di,g_this->color_clip);
+ break;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ if (g_this->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHECK1:
+ g_this->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ return 0;
+ case IDC_LC:
+ GR_SelectColor(hwndDlg,&g_this->color_clip);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ return 0;
+
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_CONTRASTENHANCE,hwndParent,g_DlgProc);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_comment.cpp b/Src/Plugins/Visualization/vis_avs/r_comment.cpp
new file mode 100644
index 00000000..be4c8fba
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_comment.cpp
@@ -0,0 +1,116 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#define C_THISCLASS C_CommentClass
+#define MOD_NAME "Misc / Comment"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_MISC_COMMENT,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ RString msgdata;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ load_string(msgdata,data,pos,len);
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ save_string(data,pos,msgdata);
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ msgdata.assign("");
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ return 0;
+}
+
+C_RBASE *R_Comment(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->msgdata.get());
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_EDIT1 && HIWORD(wParam) == EN_CHANGE)
+ {
+ g_this->msgdata.get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_COMMENT,hwndParent,g_DlgProc);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_contrast.cpp b/Src/Plugins/Visualization/vis_avs/r_contrast.cpp
new file mode 100644
index 00000000..bf7395f4
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_contrast.cpp
@@ -0,0 +1,226 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_ContrastEnhanceClass
+#define MOD_NAME "Trans / Color Clip"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_CLIP,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int enabled;
+ int color_clip,color_clip_out,color_dist;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color_clip=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color_clip_out=GET_INT(); pos+=4; }
+ else color_clip_out=color_clip;
+ if (len-pos >= 4) { color_dist=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color_clip); pos+=4;
+ PUT_INT(color_clip_out); pos+=4;
+ PUT_INT(color_dist); pos+=4;
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ enabled=1;
+ color_clip=RGB(32,32,32);
+ color_clip_out=RGB(32,32,32);
+ color_dist=10;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return 0;
+ if (isBeat&0x80000000) return 0;
+
+ int *f = framebuffer;
+ int fs_r,fs_g,fs_b;
+ int x=w*h;
+ int l=color_dist*2;
+
+
+ l=l*l;
+
+ fs_b=(color_clip&0xff0000);
+ fs_g=(color_clip&0xff00);
+ fs_r=(color_clip&0xff);
+
+ if (enabled==1) while (x--)
+ {
+ int a=f[0];
+ if ((a&0xff) <= fs_r && (a&0xff00) <= fs_g && (a&0xff0000) <= fs_b)
+ f[0]=(a&0xff000000)|color_clip_out;
+ f++;
+ }
+ else if (enabled==2) while (x--)
+ {
+ int a=f[0];
+ if ((a&0xff) >= fs_r && (a&0xff00) >= fs_g && (a&0xff0000) >= fs_b)
+ f[0]=(a&0xff000000)|color_clip_out;
+ f++;
+ }
+ else
+ {
+ fs_b>>=16;
+ fs_g>>=8;
+ while (x--)
+ {
+ int a=f[0];
+ int r=a&255;
+ int g=(a>>8)&255;
+ int b=(a>>16)&255;
+ r-=fs_r; g-=fs_g; b-=fs_b;
+ if (r*r+g*g+b*b <= l) f[0]=(a&0xff000000)|color_clip_out;
+ f++;
+ }
+ }
+ return 0;
+}
+
+C_RBASE *R_ContrastEnhance(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_LC:
+ GR_DrawColoredButton(di,g_this->color_clip);
+ break;
+ case IDC_LC2:
+ GR_DrawColoredButton(di,g_this->color_clip_out);
+ break;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ if (g_this->enabled==0) CheckDlgButton(hwndDlg,IDC_OFF,BST_CHECKED);
+ else if (g_this->enabled==1) CheckDlgButton(hwndDlg,IDC_BELOW,BST_CHECKED);
+ else if (g_this->enabled==2) CheckDlgButton(hwndDlg,IDC_ABOVE,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_NEAR,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETPOS, TRUE, g_this->color_dist);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETTICFREQ, 4, 0);
+ return 1;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_DISTANCE)
+ g_this->color_dist = SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_GETPOS, 0, 0);
+ return 0;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_OFF:
+ case IDC_BELOW:
+ case IDC_ABOVE:
+ case IDC_NEAR:
+ if (IsDlgButtonChecked(hwndDlg,IDC_OFF))
+ g_this->enabled=0;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_BELOW))
+ g_this->enabled=1;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_ABOVE))
+ g_this->enabled=2;
+ else
+ g_this->enabled=3;
+ return 0;
+ case IDC_LC:
+ GR_SelectColor(hwndDlg,&g_this->color_clip);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ return 0;
+ case IDC_LC2:
+ GR_SelectColor(hwndDlg,&g_this->color_clip_out);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ return 0;
+ case IDC_BUTTON1:
+ g_this->color_clip_out=g_this->color_clip;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_LC2),NULL,FALSE);
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_CONTRASTENHANCE,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_ContrastEnhance(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_dcolormod.cpp b/Src/Plugins/Visualization/vis_avs/r_dcolormod.cpp
new file mode 100644
index 00000000..640f7e8c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_dcolormod.cpp
@@ -0,0 +1,359 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "avs_eelif.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_DColorModClass
+#define MOD_NAME "Trans / Color Modifier"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_COLOR_MODIFIER,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ RString effect_exp[4];
+
+ int m_recompute;
+
+ int m_tab_valid;
+ unsigned char m_tab[768];
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ double *var_r, *var_g, *var_b, *var_beat;
+ int inited;
+ NSEEL_CODEHANDLE codehandle[4];
+ int need_recompile;
+ CRITICAL_SECTION rcs;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (data[pos] == 1)
+ {
+ pos++;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ load_string(effect_exp[2],data,pos,len);
+ load_string(effect_exp[3],data,pos,len);
+ }
+ else
+ {
+ char buf[1025];
+ if (len-pos >= 1024)
+ {
+ memcpy(buf,data+pos,1024);
+ pos+=1024;
+ buf[1024]=0;
+ effect_exp[3].assign(buf+768);
+ buf[768]=0;
+ effect_exp[2].assign(buf+512);
+ buf[512]=0;
+ effect_exp[1].assign(buf+256);
+ buf[256]=0;
+ effect_exp[0].assign(buf);
+ }
+ }
+ if (len-pos >= 4) { m_recompute=GET_INT(); pos+=4; }
+
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ data[pos++]=1;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ save_string(data,pos,effect_exp[2]);
+ save_string(data,pos,effect_exp[3]);
+ PUT_INT(m_recompute); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ AVS_EEL_INITINST();
+ InitializeCriticalSection(&rcs);
+ need_recompile=1;
+ m_recompute=1;
+ memset(codehandle,0,sizeof(codehandle));
+ effect_exp[0].assign("");
+ effect_exp[1].assign("");
+ effect_exp[2].assign("");
+ effect_exp[3].assign("");
+
+ var_beat=0;
+ m_tab_valid=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=0;
+ }
+ AVS_EEL_QUITINST();
+
+ DeleteCriticalSection(&rcs);
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (need_recompile)
+ {
+ EnterCriticalSection(&rcs);
+ if (!var_beat || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_r = registerVar("red");
+ var_g = registerVar("green");
+ var_b = registerVar("blue");
+ var_beat = registerVar("beat");
+ inited=0;
+ }
+ need_recompile=0;
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=compileCode(effect_exp[x].get());
+ }
+ LeaveCriticalSection(&rcs);
+ }
+ if (isBeat&0x80000000) return 0;
+
+ *var_beat=isBeat?1.0:0.0;
+
+ if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
+ executeCode(codehandle[1],visdata);
+
+ if (isBeat) executeCode(codehandle[2],visdata);
+
+ if (m_recompute || !m_tab_valid)
+ {
+ int x;
+ unsigned char *t=m_tab;
+ for (x = 0; x < 256; x ++)
+ {
+ *var_r=*var_b=*var_g=x/255.0;
+ executeCode(codehandle[0],visdata);
+ int r=(int) (*var_r*255.0 + 0.5);
+ int g=(int) (*var_g*255.0 + 0.5);
+ int b=(int) (*var_b*255.0 + 0.5);
+ if (r < 0) r=0;
+ else if (r > 255)r=255;
+ if (g < 0) g=0;
+ else if (g > 255)g=255;
+ if (b < 0) b=0;
+ else if (b > 255)b=255;
+ t[512]=r;
+ t[256]=g;
+ t[0]=b;
+ t++;
+ }
+ m_tab_valid=1;
+ }
+
+ unsigned char *fb=(unsigned char *)framebuffer;
+ int l=w*h;
+ while (l--)
+ {
+ fb[0]=m_tab[fb[0]];
+ fb[1]=m_tab[(int)fb[1]+256];
+ fb[2]=m_tab[(int)fb[2]+512];
+ fb+=4;
+ }
+
+
+ return 0;
+}
+
+C_RBASE *R_DColorMod(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+typedef struct
+{
+ char *name;
+ char *init;
+ char *point;
+ char *frame;
+ char *beat;
+ int recompute;
+} presetType;
+
+static presetType presets[]=
+{
+ // Name, Init, Level, Frame, Beat, Recalc
+ {"4x Red Brightness, 2x Green, 1x Blue","","red=4*red; green=2*green;","","",0},
+ {"Solarization","","red=(min(1,red*2)-red)*2;\r\ngreen=red; blue=red;","","",0},
+ {"Double Solarization","","red=(min(1,red*2)-red)*2;\r\nred=(min(1,red*2)-red)*2;\r\ngreen=red; blue=red;","","",0},
+ {"Inverse Solarization (Soft)","","red=abs(red - .5) * 1.5;\r\ngreen=red; blue=red;","","",0},
+ {"Big Brightness on Beat","scale=1.0","red=red*scale;\r\ngreen=red; blue=red;","scale=0.07 + (scale*0.93)","scale=16",1},
+ {"Big Brightness on Beat (Interpolative)","c = 200; f = 0;","red = red * t;\r\ngreen=red;blue=red;","f = f + 1;\r\nt = (1.025 - (f / c)) * 5;","c = f;f = 0;",1},
+ {"Pulsing Brightness (Beat Interpolative)","c = 200; f = 0;","red = red * st;\r\ngreen=red;blue=red;","f = f + 1;\r\nt = (f * 2 * $PI) / c;\r\nst = sin(t) + 1;","c = f;f = 0;",1},
+ {"Rolling Solarization (Beat Interpolative)","c = 200; f = 0;","red=(min(1,red*st)-red)*st;\r\nred=(min(1,red*2)-red)*2;\r\ngreen=red; blue=red;","f = f + 1;\r\nt = (f * 2 * $PI) / c;\r\nst = ( sin(t) * .75 ) + 2;","c = f;f = 0;",1},
+ {"Rolling Tone (Beat Interpolative)","c = 200; f = 0;","red = red * st;\r\ngreen = green * ct;\r\nblue = (blue * 4 * ti) - red - green;","f = f + 1;\r\nt = (f * 2 * $PI) / c;\r\nti = (f / c);\r\nst = sin(t) + 1.5;\r\nct = cos(t) + 1.5;","c = f;f = 0;",1},
+ {"Random Inverse Tone (Switch on Beat)","","dd = red * 1.5;\r\nred = pow(dd, dr);\r\ngreen = pow(dd, dg);\r\nblue = pow(dd, db);","","token = rand(99) % 3;\r\ndr = if (equal(token, 0), -1, 1);\r\ndg = if (equal(token, 1), -1, 1);\r\ndb = if (equal(token, 2), -1, 1);",1},
+ };
+
+
+static C_THISCLASS *g_this;
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+ if (g_this->m_recompute)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+
+ isstart=0;
+
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+/* char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_COLOR_MODIFIER,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_COLOR_MODIFIER),4095-titlelen);
+*/
+ char *text="Color Modifier\0"
+ "The color modifier allows you to modify the intensity of each color\r\n"
+ "channel with respect to itself. For example, you could reverse the red\r\n"
+ "channel, double the green channel, or half the blue channel.\r\n"
+ "\r\n"
+ "The code in the 'level' section should adjust the variables\r\n"
+ "'red', 'green', and 'blue', whose value represent the channel\r\n"
+ "intensity (0..1).\r\n"
+ "Code in the 'frame' or 'level' sections can also use the variable\r\n"
+ "'beat' to detect if it is currently a beat.\r\n"
+ "\r\n"
+ "Try loading an example via the 'Load Example' button for examples."
+
+ ;
+ compilerfunctionlist(hwndDlg,text);
+ }
+
+ if (LOWORD(wParam)==IDC_CHECK1)
+ {
+ g_this->m_recompute=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+
+ if (LOWORD(wParam) == IDC_BUTTON4)
+ {
+ RECT r;
+ HMENU hMenu;
+ MENUITEMINFO i={sizeof(i),};
+ hMenu=CreatePopupMenu();
+ int x;
+ for (x = 0; x < sizeof(presets)/sizeof(presets[0]); x ++)
+ {
+ i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.wID = x+16;
+ i.dwTypeData=presets[x].name;
+ i.cch=strlen(presets[x].name);
+ InsertMenuItem(hMenu,x,TRUE,&i);
+ }
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON4),&r);
+ x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.right,r.top,0,hwndDlg,NULL);
+ if (x >= 16 && x < 16+sizeof(presets)/sizeof(presets[0]))
+ {
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,presets[x-16].point);
+ SetDlgItemText(hwndDlg,IDC_EDIT2,presets[x-16].frame);
+ SetDlgItemText(hwndDlg,IDC_EDIT3,presets[x-16].beat);
+ SetDlgItemText(hwndDlg,IDC_EDIT4,presets[x-16].init);
+ g_this->m_recompute=presets[x-16].recompute;
+ CheckDlgButton(hwndDlg,IDC_CHECK1,g_this->m_recompute?BST_CHECKED:0);
+ isstart=0;
+
+ SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_EDIT4,EN_CHANGE),0);
+ }
+ DestroyMenu(hMenu);
+ }
+ if (!isstart && HIWORD(wParam) == EN_CHANGE)
+ {
+ if (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
+ g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
+ g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
+ g_this->need_recompile=1;
+ if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
+ g_this->m_tab_valid=0;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_COLORMOD,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_DColorMod(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_ddm.cpp b/Src/Plugins/Visualization/vis_avs/r_ddm.cpp
new file mode 100644
index 00000000..21db977c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_ddm.cpp
@@ -0,0 +1,492 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#define M_PI 3.14159265358979323846
+
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "avs_eelif.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_PulseClass
+#define MOD_NAME "Trans / Dynamic Distance Modifier"
+
+
+// Integer Square Root function
+
+// Uses factoring to find square root
+// A 256 entry table used to work out the square root of the 7 or 8 most
+// significant bits. A power of 2 used to approximate the rest.
+// Based on an 80386 Assembly implementation by Arne Steinarson
+
+static unsigned const char sq_table[]=
+{0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61, 64, 65,
+67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84, 86, 87, 89, 90, 91, 93, 94,
+96, 97, 98, 99, 101, 102, 103, 104, 106, 107, 108, 109, 110, 112, 113,
+114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128,
+128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
+142, 143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153,
+154, 155, 155, 156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164,
+165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175,
+176, 176, 177, 178, 178, 179, 180, 181, 181, 182, 183, 183, 184, 185,
+185, 186, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 193, 194,
+195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, 202, 203, 203,
+204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211, 212,
+212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220,
+221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228,
+229, 229, 230, 230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236,
+236, 237, 237, 238, 238, 239, 240, 240, 241, 241, 242, 242, 243, 243,
+244, 244, 245, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250,
+251, 251, 252, 252, 253, 253, 254, 254, 255};
+
+static __inline unsigned long isqrt(unsigned long n)
+{
+ if (n >= 0x10000)
+ if (n >= 0x1000000)
+ if (n >= 0x10000000)
+ if (n >= 0x40000000) return(sq_table[n >> 24] << 8);
+ else return(sq_table[n >> 22] << 7);
+ else
+ if (n >= 0x4000000) return(sq_table[n >> 20] << 6);
+ else return(sq_table[n >> 18] << 5);
+ else
+ if (n >= 0x100000)
+ if (n >= 0x400000) return(sq_table[n >> 16] << 4);
+ else return(sq_table[n >> 14] << 3);
+ else
+ if (n >= 0x40000) return(sq_table[n >> 12] << 2);
+ else return(sq_table[n >> 10] << 1);
+
+ else
+ if (n >= 0x100)
+ if (n >= 0x1000)
+ if (n >= 0x4000) return(sq_table[n >> 8]);
+ else return(sq_table[n >> 6] >> 1);
+ else
+ if (n >= 0x400) return(sq_table[n >> 4] >> 2);
+ else return(sq_table[n >> 2] >> 3);
+ else
+ if (n >= 0x10)
+ if (n >= 0x40) return(sq_table[n] >> 4);
+ else return(sq_table[n << 2] << 5);
+ else
+ if (n >= 0x4) return(sq_table[n >> 4] << 6);
+ else return(sq_table[n >> 6] << 7);
+
+}
+
+
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_DYNAMIC_DISTANCE_MODIFIER,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ RString effect_exp[4];
+ int blend;
+
+ int m_wt;
+ int m_lastw,m_lasth;
+ int *m_wmul;
+ int *m_tab;
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ double *var_d, *var_b;
+ double max_d;
+ int inited;
+ NSEEL_CODEHANDLE codehandle[4];
+ int need_recompile;
+ int subpixel;
+ CRITICAL_SECTION rcs;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (data[pos] == 1)
+ {
+ pos++;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ load_string(effect_exp[2],data,pos,len);
+ load_string(effect_exp[3],data,pos,len);
+ }
+ else
+ {
+ char buf[513];
+ if (len-pos >= 256*2)
+ {
+ memcpy(buf,data+pos,256*2);
+ pos+=256*2;
+ buf[512]=0;
+ effect_exp[1].assign(buf+256);
+ buf[256]=0;
+ effect_exp[0].assign(buf);
+ }
+ if (len-pos >= 256*2)
+ {
+ memcpy(buf,data+pos,256*2);
+ pos+=256*2;
+ buf[512]=0;
+ effect_exp[3].assign(buf+256);
+ buf[256]=0;
+ effect_exp[2].assign(buf);
+ }
+ }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
+
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ data[pos++]=1;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ save_string(data,pos,effect_exp[2]);
+ save_string(data,pos,effect_exp[3]);
+ PUT_INT(blend); pos+=4;
+ PUT_INT(subpixel); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ AVS_EEL_INITINST();
+ InitializeCriticalSection(&rcs);
+ need_recompile=1;
+ memset(codehandle,0,sizeof(codehandle));
+ m_lasth=m_lastw=0;
+ m_wmul=0;
+ m_tab=0;
+ m_wt=0;
+ effect_exp[0].assign("d=d-sigmoid((t-50)/100,2)");
+ effect_exp[3].assign("u=1;t=0");
+ effect_exp[1].assign("t=t+u;t=min(100,t);t=max(0,t);u=if(equal(t,100),-1,u);u=if(equal(t,0),1,u)");
+ effect_exp[2].assign("");
+
+ blend=0;
+ subpixel=0;
+
+ var_b=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=0;
+ }
+ if (m_wmul) GlobalFree(m_wmul);
+ if (m_tab) GlobalFree(m_tab);
+ AVS_EEL_QUITINST();
+
+ m_tab=0;
+ m_wmul=0;
+ DeleteCriticalSection(&rcs);
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int *fbin=framebuffer;
+ if (m_lasth != h || m_lastw != w || !m_tab || !m_wmul)
+ {
+ int y;
+ m_lastw=w; // jf 121100 - added (oops)
+ m_lasth=h;
+ max_d=sqrt((w*w+h*h)/4.0);
+ if (m_wmul) GlobalFree(m_wmul);
+ m_wmul=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*h);
+ for (y = 0; y < h; y ++) m_wmul[y]=y*w;
+ if (m_tab) GlobalFree(m_tab);
+ m_tab=0;
+ }
+ int imax_d=(int)(max_d + 32.9);
+
+ if (imax_d < 33) imax_d=33;
+
+ if (!m_tab)
+ m_tab=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*imax_d);
+
+ int x;
+
+ //pow(sin(d),dpos)*1.7
+ if (need_recompile)
+ {
+ EnterCriticalSection(&rcs);
+ if (!var_b || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_d = registerVar("d");
+ var_b = registerVar("b");
+ inited=0;
+ }
+ need_recompile=0;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=compileCode(effect_exp[x].get());
+ }
+ LeaveCriticalSection(&rcs);
+ }
+ if (isBeat&0x80000000) return 0;
+
+ *var_b=isBeat?1.0:0.0;
+
+ if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
+ executeCode(codehandle[1],visdata);
+ if (isBeat) executeCode(codehandle[2],visdata);
+ if (codehandle[0])
+ {
+ for (x = 0; x < imax_d-32; x ++)
+ {
+ *var_d=x/(max_d-1);
+ executeCode(codehandle[0],visdata);
+ m_tab[x]=(int) (*var_d*256.0*max_d/(x+1));
+ }
+ for (; x < imax_d; x ++)
+ {
+ m_tab[x]=m_tab[x-1];
+ }
+ }
+ else for (x = 0; x < imax_d; x ++) m_tab[x]=0;
+
+ m_wt++;
+ m_wt&=63;
+
+ {
+ int w2=w/2;
+ int h2=h/2;
+ int y;
+ for (y = 0; y < h; y ++)
+ {
+ int ty=y-h2;
+ int x2=w2*w2+w2+ty*ty+256;
+ int dx2=-2*w2;
+ int yysc=ty;
+ int xxsc=-w2;
+ int x=w;
+ if (subpixel)
+ {
+ if (blend)
+ while (x--)
+ {
+ int qd=m_tab[isqrt(x2)];
+ int ow,oh;
+ int xpart,ypart;
+ x2+=dx2;
+ dx2+=2;
+ xpart=(qd*xxsc+128);
+ ypart=(qd*yysc+128);
+ ow = w2 + (xpart>>8);
+ oh = h2 + (ypart>>8);
+ xpart&=0xff;
+ ypart&=0xff;
+ xxsc++;
+
+ if (ow < 0) ow=0;
+ else if (ow >= w-1) ow=w-2;
+ if (oh < 0) oh=0;
+ else if (oh >= h-1) oh=h-2;
+
+ *fbout++=BLEND_AVG(BLEND4((unsigned int *)framebuffer+ow+m_wmul[oh],w,xpart,ypart),*fbin++);
+ }
+ else
+ while (x--)
+ {
+ int qd=m_tab[isqrt(x2)];
+ int ow,oh;
+ int xpart,ypart;
+ x2+=dx2;
+ dx2+=2;
+ xpart=(qd*xxsc+128);
+ ypart=(qd*yysc+128);
+ ow = w2 + (xpart>>8);
+ oh = h2 + (ypart>>8);
+ xpart&=0xff;
+ ypart&=0xff;
+ xxsc++;
+
+ if (ow < 0) ow=0;
+ else if (ow >= w-1) ow=w-2;
+ if (oh < 0) oh=0;
+ else if (oh >= h-1) oh=h-2;
+
+ *fbout++=BLEND4((unsigned int *)framebuffer+ow+m_wmul[oh],w,xpart,ypart);
+ }
+ }
+ else
+ {
+ if (blend)
+ while (x--)
+ {
+ int qd=m_tab[isqrt(x2)];
+ int ow,oh;
+ x2+=dx2;
+ dx2+=2;
+ ow = w2 + ((qd*xxsc+128)>>8);
+ xxsc++;
+ oh = h2 + ((qd*yysc+128)>>8);
+
+ if (ow < 0) ow=0;
+ else if (ow >= w) ow=w-1;
+ if (oh < 0) oh=0;
+ else if (oh >= h) oh=h-1;
+
+ *fbout++=BLEND_AVG(framebuffer[ow+m_wmul[oh]],*fbin++);
+ }
+ else
+ while (x--)
+ {
+ int qd=m_tab[isqrt(x2)];
+ int ow,oh;
+ x2+=dx2;
+ dx2+=2;
+ ow = w2 + ((qd*xxsc+128)>>8);
+ xxsc++;
+ oh = h2 + ((qd*yysc+128)>>8);
+
+ if (ow < 0) ow=0;
+ else if (ow >= w) ow=w-1;
+ if (oh < 0) oh=0;
+ else if (oh >= h) oh=h-1;
+
+ *fbout++=framebuffer[ow+m_wmul[oh]];
+ }
+ }
+ }
+ }
+#ifndef NO_MMX
+ if (subpixel) __asm emms;
+#endif
+ return 1;
+}
+
+C_RBASE *R_DDM(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+ isstart=0;
+ if (g_this->blend)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_this->subpixel)
+ CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+/* char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_DYNAMIC_DISTANCE_MODIFIER,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_DYNAMIC_DISTANCE_MODIFIER),4095-titlelen);
+*/
+ char *text="Dynamic Distance Modifier\0"
+ "The dynamic distance modifier allows you to dynamically (once per frame)\r\n"
+ "change the source pixels for each ring of pixels out from the center.\r\n"
+ "In the 'pixel' code section, 'd' represents the distance in pixels\r\n"
+ "the current ring is from the center, and code can modify it to\r\n"
+ "change the distance from the center where the source pixels for\r\n"
+ "that ring would be read. This is a terrible explanation, and if\r\n"
+ "you want to make a better one send it to me. \r\n"
+ "\r\n"
+ "Examples:\r\n"
+ "Zoom in: 'd=d*0.9'\r\n"
+ "Zoom out: 'd=d*1.1'\r\n"
+ "Back and forth: pixel='d=d*(1.0+0.1*cos(t));', frame='t=t+0.1'\r\n"
+ ;
+ compilerfunctionlist(hwndDlg,text);
+ }
+
+ if (LOWORD(wParam)==IDC_CHECK1)
+ {
+ g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_CHECK2)
+ {
+ g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
+ }
+ if (!isstart && (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4) && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
+ g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
+ g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
+ g_this->need_recompile=1;
+ if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_DDM,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_DDM(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_defs.h b/Src/Plugins/Visualization/vis_avs/r_defs.h
new file mode 100644
index 00000000..19f0fc30
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_defs.h
@@ -0,0 +1,739 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _R_DEFS_H_
+#define _R_DEFS_H_
+
+// base class declaration, compatibility class
+class RString;
+
+class C_RBASE {
+ public:
+ C_RBASE() { }
+ virtual ~C_RBASE() { };
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)=0; // returns 1 if fbout has dest
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent){return 0;};
+ virtual char *get_desc()=0;
+ virtual void load_config(unsigned char *data, int len) { }
+ virtual int save_config(unsigned char *data) { return 0; }
+
+ void load_string(RString &s,unsigned char *data, int &pos, int len);
+ void save_string(unsigned char *data, int &pos, RString &text);
+
+};
+
+class C_RBASE2 : public C_RBASE {
+ public:
+ C_RBASE2() { }
+ virtual ~C_RBASE2() { };
+
+ int getRenderVer2() { return 2; }
+
+
+ virtual int smp_getflags() { return 0; } // return 1 to enable smp support
+
+ // returns # of threads you desire, <= max_threads, or 0 to not do anything
+ // default should return max_threads if you are flexible
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { return 0; }
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { };
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) { return 0; }; // return value is that of render() for fbstuff etc
+
+};
+
+
+// defined in main.cpp, render.cpp
+extern char g_path[];
+extern unsigned char g_blendtable[256][256];
+
+extern int g_reset_vars_on_recompile;
+
+// use this function to get a global buffer, and the last flag says whether or not to
+// allocate it if it's not valid...
+#define NBUF 8
+void *getGlobalBuffer(int w, int h, int n, int do_alloc);
+
+
+// implemented in util.cpp
+char* GetTextResource(UINT id);
+void GR_SelectColor(HWND hwnd, int *a);
+void GR_DrawColoredButton(DRAWITEMSTRUCT *di, COLORREF color);
+void loadComboBox(HWND dlg, char *ext, char *selectedName);
+void compilerfunctionlist(HWND hwndDlg, char *localinfo=NULL);
+
+// matrix.cpp
+void matrixRotate(float matrix[], char m, float Deg);
+void matrixTranslate(float m[], float x, float y, float z);
+void matrixMultiply(float *dest, float src[]);
+void matrixApply(float *m, float x, float y, float z, float *outx, float *outy, float *outz);
+
+// linedraw.cpp
+extern int g_line_blend_mode;
+void line(int *fb, int x1,int y1,int x2,int y2, int width, int height, int color, int lw);
+
+
+// inlines
+static unsigned int __inline BLEND(unsigned int a, unsigned int b)
+{
+ register unsigned int r,t;
+ r=(a&0xff)+(b&0xff);
+ t=min(r,0xff);
+ r=(a&0xff00)+(b&0xff00);
+ t|=min(r,0xff00);
+ r=(a&0xff0000)+(b&0xff0000);
+ t|=min(r,0xff0000);
+ r=(a&0xff000000)+(b&0xff000000);
+ return t|min(r,0xff000000);
+}
+
+#if 1
+#define FASTMAX(x,y) max(x,y)
+// (x-(((x-y)>>(32-1))&(x-y))) // hmm not faster :(
+#define FASTMIN(x,y) min(x,y)
+//(x+(((y-x)>>(32-1))&(y-x)))
+#else
+#pragma warning( push, 1 )
+
+static __inline int FASTMAX(int x, int y)
+{
+ __asm
+ {
+ mov ecx, [x]
+ mov eax, [y]
+ sub ecx, eax
+ cmc
+ and ecx, edx
+ add eax, ecx
+ }
+}
+static __inline int FASTMIN(int x, int y)
+{
+ __asm
+ {
+ mov ecx, [x]
+ mov eax, [y]
+ sub ecx, eax
+ sbb edx, edx
+ and ecx, edx
+ add eax, ecx
+ }
+}
+#pragma warning( pop )
+
+#endif
+
+static unsigned int __inline BLEND_MAX(unsigned int a, unsigned int b)
+{
+ register unsigned int t;
+ int _a=a&0xff;
+ int _b=b&0xff;
+ t=FASTMAX(_a,_b);
+ _a=a&0xff00; _b=b&0xff00;
+ t|=FASTMAX(_a,_b);
+ _a=a&0xff0000; _b=b&0xff0000;
+ t|=FASTMAX(_a,_b);
+ return t;
+}
+
+static unsigned int __inline BLEND_MIN(unsigned int a, unsigned int b)
+{
+#if 1
+ register unsigned int t;
+ int _a=a&0xff;
+ int _b=b&0xff;
+ t=FASTMIN(_a,_b);
+ _a=a&0xff00; _b=b&0xff00;
+ t|=FASTMIN(_a,_b);
+ _a=a&0xff0000; _b=b&0xff0000;
+ t|=FASTMIN(_a,_b);
+ return t;
+#else
+ __asm
+ {
+ mov ecx, [a]
+ mov eax, [b]
+
+ and ecx, 0xff
+ and eax, 0xff
+
+ mov esi, [a]
+ mov ebx, [b]
+
+ sub ecx, eax
+ sbb edx, edx
+
+ and esi, 0xff00
+ and ebx, 0xff00
+
+ and ecx, edx
+ sub esi, ebx
+
+ sbb edx, edx
+ add eax, ecx
+
+ and esi, edx
+ mov ecx, [a]
+
+ add ebx, esi
+ and ecx, 0xff0000
+
+ mov esi, [b]
+ or eax, ebx
+
+ and esi, 0xff0000
+
+ sub ecx, esi
+ sbb edx, edx
+
+ and ecx, edx
+ add esi, ecx
+
+ or eax, esi
+ }
+#endif
+}
+
+#ifdef FASTMAX
+#undef FASTMAX
+#undef FASTMIN
+#endif
+
+
+static unsigned int __inline BLEND_AVG(unsigned int a, unsigned int b)
+{
+ return ((a>>1)&~((1<<7)|(1<<15)|(1<<23)))+((b>>1)&~((1<<7)|(1<<15)|(1<<23)));
+}
+
+
+static unsigned int __inline BLEND_SUB(unsigned int a, unsigned int b)
+{
+ register int r,t;
+ r=(a&0xff)-(b&0xff);
+ t=max(r,0);
+ r=(a&0xff00)-(b&0xff00);
+ t|=max(r,0);
+ r=(a&0xff0000)-(b&0xff0000);
+ t|=max(r,0);
+ r=(a&0xff000000)-(b&0xff000000);
+ return t|max(r,0);
+}
+
+#ifdef NO_MMX
+#define BLEND_ADJ BLEND_ADJ_NOMMX
+#endif
+
+static unsigned int __inline BLEND_ADJ_NOMMX(unsigned int a, unsigned int b, int v)
+{
+ register int t;
+ t=g_blendtable[a&0xFF][v]+g_blendtable[b&0xFF][0xFF-v];
+ t|=(g_blendtable[(a&0xFF00)>>8][v]+g_blendtable[(b&0xFF00)>>8][0xFF-v])<<8;
+ t|=(g_blendtable[(a&0xFF0000)>>16][v]+g_blendtable[(b&0xFF0000)>>16][0xFF-v])<<16;
+ return t;
+}
+
+static unsigned int __inline BLEND_MUL(unsigned int a, unsigned int b)
+{
+ register int t;
+ t=g_blendtable[a&0xFF][b&0xFF];
+ t|=g_blendtable[(a&0xFF00)>>8][(b&0xFF00)>>8]<<8;
+ t|=g_blendtable[(a&0xFF0000)>>16][(b&0xFF0000)>>16]<<16;
+ return t;
+}
+
+static __inline void BLEND_LINE(int *fb, int color)
+{
+ register int bm=g_line_blend_mode&0xff;
+ switch (g_line_blend_mode&0xff)
+ {
+ case 1: *fb=BLEND(*fb,color); break;
+ case 2: *fb=BLEND_MAX(*fb,color); break;
+ case 3: *fb=BLEND_AVG(*fb,color); break;
+ case 4: *fb=BLEND_SUB(*fb,color); break;
+ case 5: *fb=BLEND_SUB(color,*fb); break;
+ case 6: *fb=BLEND_MUL(*fb,color); break;
+ case 7: *fb=BLEND_ADJ_NOMMX(*fb,color,(g_line_blend_mode>>8)&0xff); break;
+ case 8: *fb=*fb^color; break;
+ case 9: *fb=BLEND_MIN(*fb,color); break;
+ default: *fb=color; break;
+ }
+}
+extern unsigned int const mmx_blend4_revn[2];
+extern int const mmx_blend4_zero;
+extern int const mmx_blendadj_mask[2];
+// NOTE. WHEN USING THIS FUNCTION, BE SURE TO DO 'if (g_mmx_available) __asm emms;' before calling
+// any fpu code, or before returning.
+#pragma warning( push, 1 )
+
+#ifndef NO_MMX
+static unsigned int __inline BLEND_ADJ(unsigned int a, unsigned int b, int v)
+{
+ __asm
+ {
+ movd mm3, [v] // VVVVVVVV
+
+ movd mm0, [a]
+ packuswb mm3, mm3 // 0000HHVV
+
+ movd mm1, [b]
+ punpcklwd mm3, mm3 // HHVVHHVV
+
+ movq mm4, [mmx_blend4_revn]
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+
+ punpcklbw mm0, [mmx_blend4_zero]
+ pand mm3, [mmx_blendadj_mask]
+
+ punpcklbw mm1, [mmx_blend4_zero]
+ psubw mm4, mm3
+
+ pmullw mm0, mm3
+ pmullw mm1, mm4
+
+ paddw mm0, mm1
+
+ psrlw mm0, 8
+
+ packuswb mm0, mm0
+
+ movd eax, mm0
+ }
+}
+#endif
+
+
+static __inline unsigned int BLEND4(unsigned int *p1, unsigned int w, int xp, int yp)
+{
+#ifdef NO_MMX
+ register int t;
+ unsigned char a1,a2,a3,a4;
+ a1=g_blendtable[255-xp][255-yp];
+ a2=g_blendtable[xp][255-yp];
+ a3=g_blendtable[255-xp][yp];
+ a4=g_blendtable[xp][yp];
+ t=g_blendtable[p1[0]&0xff][a1]+g_blendtable[p1[1]&0xff][a2]+g_blendtable[p1[w]&0xff][a3]+g_blendtable[p1[w+1]&0xff][a4];
+ t|=(g_blendtable[(p1[0]>>8)&0xff][a1]+g_blendtable[(p1[1]>>8)&0xff][a2]+g_blendtable[(p1[w]>>8)&0xff][a3]+g_blendtable[(p1[w+1]>>8)&0xff][a4])<<8;
+ t|=(g_blendtable[(p1[0]>>16)&0xff][a1]+g_blendtable[(p1[1]>>16)&0xff][a2]+g_blendtable[(p1[w]>>16)&0xff][a3]+g_blendtable[(p1[w+1]>>16)&0xff][a4])<<16;
+ return t;
+#else
+ __asm
+ {
+ movd mm6, xp
+ mov eax, p1
+
+ movd mm7, yp
+ mov esi, w
+
+ movq mm4, mmx_blend4_revn
+ punpcklwd mm6,mm6
+
+ movq mm5, mmx_blend4_revn
+ punpcklwd mm7,mm7
+
+ movd mm0, [eax]
+ punpckldq mm6,mm6
+
+ movd mm1, [eax+4]
+ punpckldq mm7,mm7
+
+ movd mm2, [eax+esi*4]
+ punpcklbw mm0, [mmx_blend4_zero]
+
+ movd mm3, [eax+esi*4+4]
+ psubw mm4, mm6
+
+ punpcklbw mm1, [mmx_blend4_zero]
+ pmullw mm0, mm4
+
+ punpcklbw mm2, [mmx_blend4_zero]
+ pmullw mm1, mm6
+
+ punpcklbw mm3, [mmx_blend4_zero]
+ psubw mm5, mm7
+
+ pmullw mm2, mm4
+ pmullw mm3, mm6
+
+ paddw mm0, mm1
+ // stall (mm0)
+
+ psrlw mm0, 8
+ // stall (waiting for mm3/mm2)
+
+ paddw mm2, mm3
+ pmullw mm0, mm5
+
+ psrlw mm2, 8
+ // stall (mm2)
+
+ pmullw mm2, mm7
+ // stall
+
+ // stall (mm2)
+
+ paddw mm0, mm2
+ // stall
+
+ psrlw mm0, 8
+ // stall
+
+ packuswb mm0, mm0
+ // stall
+
+ movd eax, mm0
+ }
+#endif
+}
+
+
+static __inline unsigned int BLEND4_16(unsigned int *p1, unsigned int w, int xp, int yp)
+{
+#ifdef NO_MMX
+ register int t;
+ unsigned char a1,a2,a3,a4;
+ xp=(xp>>8)&0xff;
+ yp=(yp>>8)&0xff;
+ a1=g_blendtable[255-xp][255-yp];
+ a2=g_blendtable[xp][255-yp];
+ a3=g_blendtable[255-xp][yp];
+ a4=g_blendtable[xp][yp];
+ t=g_blendtable[p1[0]&0xff][a1]+g_blendtable[p1[1]&0xff][a2]+g_blendtable[p1[w]&0xff][a3]+g_blendtable[p1[w+1]&0xff][a4];
+ t|=(g_blendtable[(p1[0]>>8)&0xff][a1]+g_blendtable[(p1[1]>>8)&0xff][a2]+g_blendtable[(p1[w]>>8)&0xff][a3]+g_blendtable[(p1[w+1]>>8)&0xff][a4])<<8;
+ t|=(g_blendtable[(p1[0]>>16)&0xff][a1]+g_blendtable[(p1[1]>>16)&0xff][a2]+g_blendtable[(p1[w]>>16)&0xff][a3]+g_blendtable[(p1[w+1]>>16)&0xff][a4])<<16;
+ return t;
+#else
+ __asm
+ {
+ movd mm6, xp
+ mov eax, p1
+
+ movd mm7, yp
+ mov esi, w
+
+ movq mm4, mmx_blend4_revn
+ psrlw mm6, 8
+
+ movq mm5, mmx_blend4_revn
+ psrlw mm7, 8
+
+ movd mm0, [eax]
+ punpcklwd mm6,mm6
+
+ movd mm1, [eax+4]
+ punpcklwd mm7,mm7
+
+ movd mm2, [eax+esi*4]
+ punpckldq mm6,mm6
+
+ movd mm3, [eax+esi*4+4]
+ punpckldq mm7,mm7
+
+ punpcklbw mm0, [mmx_blend4_zero]
+ psubw mm4, mm6
+
+ punpcklbw mm1, [mmx_blend4_zero]
+ pmullw mm0, mm4
+
+ punpcklbw mm2, [mmx_blend4_zero]
+ pmullw mm1, mm6
+
+ punpcklbw mm3, [mmx_blend4_zero]
+ psubw mm5, mm7
+
+ pmullw mm2, mm4
+ pmullw mm3, mm6
+
+ paddw mm0, mm1
+ // stall (mm0)
+
+ psrlw mm0, 8
+ // stall (waiting for mm3/mm2)
+
+ paddw mm2, mm3
+ pmullw mm0, mm5
+
+ psrlw mm2, 8
+ // stall (mm2)
+
+ pmullw mm2, mm7
+ // stall
+
+ // stall (mm2)
+
+ paddw mm0, mm2
+ // stall
+
+ psrlw mm0, 8
+ // stall
+
+ packuswb mm0, mm0
+ // stall
+
+ movd eax, mm0
+ }
+#endif
+}
+
+
+#pragma warning( pop )
+
+
+static __inline void mmx_avgblend_block(int *output, int *input, int l)
+{
+#ifdef NO_MMX
+ while (l--)
+ {
+ *output=BLEND_AVG(*input++,*output);
+ output++;
+ }
+#else
+ static int mask[2]=
+ {
+ ~((1<<7)|(1<<15)|(1<<23)),
+ ~((1<<7)|(1<<15)|(1<<23))
+ };
+ __asm
+ {
+ mov eax, input
+ mov edi, output
+ mov ecx, l
+ shr ecx, 2
+ align 16
+mmx_avgblend_loop:
+ movq mm0, [eax]
+ movq mm1, [edi]
+ psrlq mm0, 1
+ movq mm2, [eax+8]
+ psrlq mm1, 1
+ movq mm3, [edi+8]
+ psrlq mm2, 1
+ pand mm0, [mask]
+ psrlq mm3, 1
+ pand mm1, [mask]
+ pand mm2, [mask]
+ paddusb mm0, mm1
+ pand mm3, [mask]
+ add eax, 16
+ paddusb mm2, mm3
+
+ movq [edi], mm0
+ movq [edi+8], mm2
+
+ add edi, 16
+
+ dec ecx
+ jnz mmx_avgblend_loop
+ emms
+ };
+#endif
+}
+
+
+static __inline void mmx_addblend_block(int *output, int *input, int l)
+{
+#ifdef NO_MMX
+ while (l--)
+ {
+ *output=BLEND(*input++,*output);
+ output++;
+ }
+#else
+ __asm
+ {
+ mov eax, input
+ mov edi, output
+ mov ecx, l
+ shr ecx, 2
+ align 16
+mmx_addblend_loop:
+ movq mm0, [eax]
+ movq mm1, [edi]
+ movq mm2, [eax+8]
+ movq mm3, [edi+8]
+ paddusb mm0, mm1
+ paddusb mm2, mm3
+ add eax, 16
+
+ movq [edi], mm0
+ movq [edi+8], mm2
+
+ add edi, 16
+
+ dec ecx
+ jnz mmx_addblend_loop
+ emms
+ };
+#endif
+}
+
+static __inline void mmx_mulblend_block(int *output, int *input, int l)
+{
+#ifdef NO_MMX
+ while (l--)
+ {
+ *output=BLEND_MUL(*input++,*output);
+ output++;
+ }
+#else
+ __asm
+ {
+ mov eax, input
+ mov edi, output
+ mov ecx, l
+ shr ecx, 1
+ align 16
+mmx_mulblend_loop:
+ movd mm0, [eax]
+ movd mm1, [edi]
+ movd mm2, [eax+4]
+ punpcklbw mm0, [mmx_blend4_zero]
+ movd mm3, [edi+4]
+ punpcklbw mm1, [mmx_blend4_zero]
+ punpcklbw mm2, [mmx_blend4_zero]
+ pmullw mm0, mm1
+ punpcklbw mm3, [mmx_blend4_zero]
+ psrlw mm0, 8
+ pmullw mm2, mm3
+ packuswb mm0, mm0
+ psrlw mm2, 8
+ packuswb mm2, mm2
+ add eax, 8
+
+ movd [edi], mm0
+ movd [edi+4], mm2
+
+ add edi, 8
+
+ dec ecx
+ jnz mmx_mulblend_loop
+ emms
+ };
+#endif
+}
+
+static void __inline mmx_adjblend_block(int *o, int *in1, int *in2, int len, int v)
+{
+#ifdef NO_MMX
+ while (len--)
+ {
+ *o++=BLEND_ADJ(*in1++,*in2++,inblendval);
+ }
+#else
+ __asm
+ {
+ movd mm3, [v] // VVVVVVVV
+ mov ecx, len
+
+ packuswb mm3, mm3 // 0000HHVV
+ mov edx, o
+
+ punpcklwd mm3, mm3 // HHVVHHVV
+ mov esi, in1
+
+ movq mm4, [mmx_blend4_revn]
+ punpckldq mm3, mm3 // HHVVHHVV HHVVHHVV
+
+ pand mm3, [mmx_blendadj_mask]
+ mov edi, in2
+
+ shr ecx, 1
+ psubw mm4, mm3
+
+ align 16
+_mmx_adjblend_loop:
+
+ movd mm0, [esi]
+
+ movd mm1, [edi]
+ punpcklbw mm0, [mmx_blend4_zero]
+
+ movd mm6, [esi+4]
+ punpcklbw mm1, [mmx_blend4_zero]
+
+ movd mm7, [edi+4]
+ punpcklbw mm6, [mmx_blend4_zero]
+
+ pmullw mm0, mm3
+ punpcklbw mm7, [mmx_blend4_zero]
+
+ pmullw mm1, mm4
+ pmullw mm6, mm3
+
+ pmullw mm7, mm4
+ paddw mm0, mm1
+
+ paddw mm6, mm7
+ add edi, 8
+
+ psrlw mm0, 8
+ add esi, 8
+
+ psrlw mm6, 8
+ packuswb mm0, mm0
+
+ packuswb mm6, mm6
+ movd [edx], mm0
+
+ movd [edx+4], mm6
+ add edx, 8
+ dec ecx
+ jnz _mmx_adjblend_loop
+
+ emms
+ };
+#endif
+}
+
+
+
+class RString
+{
+ public:
+ RString() { m_str=0; m_size=0; }
+ ~RString() { if (m_str) GlobalFree(m_str); };
+ void resize(int size) { m_size=size; if (m_str) GlobalFree(m_str); m_str=0; if (size) m_str=(char*)GlobalAlloc(GPTR,size); }
+ char *get() { return m_str; }
+ int getsize() { if (!m_str) return 0; return m_size; }
+ void assign(char *s) { resize(strlen(s)+1); strcpy(m_str,s); }
+ void get_from_dlgitem(HWND hwnd, int dlgItem)
+ {
+ int l=SendDlgItemMessage(hwnd,dlgItem,WM_GETTEXTLENGTH,0,0);
+ if ( l < 256) l=256;
+ resize(l+1+256);
+ GetDlgItemText(hwnd,dlgItem, m_str, l+1);
+ m_str[l]=0;
+ }
+ private:
+ char *m_str;
+ int m_size;
+};
+
+void doAVSEvalHighLight(HWND hwndDlg, UINT sub, char *data);
+
+#include "laser/laserline.h"
+
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/r_dmove.cpp b/Src/Plugins/Visualization/vis_avs/r_dmove.cpp
new file mode 100644
index 00000000..34ce6481
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_dmove.cpp
@@ -0,0 +1,780 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#define M_PI 3.14159265358979323846
+
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "avs_eelif.h"
+#include "r_list.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+
+#if 0
+static void __docheck(int xp, int yp, int m_lastw, int m_lasth, int d_x, int d_y)
+{
+ xp >>= 16;
+ yp >>= 16;
+ if (xp < 0 || xp >= m_lastw || yp < 0 || yp >= m_lasth)
+ {
+ char buf[512];
+ wsprintf(buf,"@ %d,%d on %d,%d (dx,dy=%d,%d)\n",xp,yp,m_lastw,m_lasth,d_x,d_y);
+ OutputDebugString(buf);
+ }
+}
+#endif
+
+
+#ifndef LASER
+
+#define C_THISCLASS C_DMoveClass
+#define MOD_NAME "Trans / Dynamic Movement"
+
+class C_THISCLASS : public C_RBASE2 {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+
+ virtual int smp_getflags() { return 1; }
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // return value is that of render() for fbstuff etc
+
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_DYNAMIC_MOVEMENT,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ RString effect_exp[4];
+
+ int m_lastw,m_lasth;
+ int m_lastxres, m_lastyres, m_xres, m_yres;
+ int *m_wmul;
+ int *m_tab;
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ double *var_d, *var_b, *var_r, *var_x, *var_y, *var_w, *var_h, *var_alpha;
+ int inited;
+ NSEEL_CODEHANDLE codehandle[4];
+ int need_recompile;
+ int buffern;
+ int subpixel,rectcoords,blend,wrap, nomove;
+ CRITICAL_SECTION rcs;
+
+
+ // smp stuff
+ int __subpixel,__rectcoords,__blend,__wrap, __nomove;
+ int w_adj;
+ int h_adj;
+ int XRES;
+ int YRES;
+
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (data[pos] == 1)
+ {
+ pos++;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ load_string(effect_exp[2],data,pos,len);
+ load_string(effect_exp[3],data,pos,len);
+ }
+ else
+ {
+ char buf[1025];
+ if (len-pos >= 1024)
+ {
+ memcpy(buf,data+pos,1024);
+ pos+=1024;
+ buf[1024]=0;
+ effect_exp[3].assign(buf+768);
+ buf[768]=0;
+ effect_exp[2].assign(buf+512);
+ buf[512]=0;
+ effect_exp[1].assign(buf+256);
+ buf[256]=0;
+ effect_exp[0].assign(buf);
+ }
+ }
+ if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rectcoords=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { m_xres=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { m_yres=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { wrap=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { buffern=GET_INT(); pos+=4; }
+ else buffern=0;
+ if (len-pos >= 4) { nomove=GET_INT(); pos+=4; }
+ else nomove=0;
+
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ data[pos++]=1;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ save_string(data,pos,effect_exp[2]);
+ save_string(data,pos,effect_exp[3]);
+ PUT_INT(subpixel); pos+=4;
+ PUT_INT(rectcoords); pos+=4;
+ PUT_INT(m_xres); pos+=4;
+ PUT_INT(m_yres); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(wrap); pos+=4;
+ PUT_INT(buffern); pos+=4;
+ PUT_INT(nomove); pos+=4;
+ return pos;
+}
+
+C_THISCLASS::C_THISCLASS()
+{
+ AVS_EEL_INITINST();
+ InitializeCriticalSection(&rcs);
+ need_recompile=1;
+ memset(codehandle,0,sizeof(codehandle));
+ m_lasth=m_lastw=0;
+ m_wmul=0;
+ m_tab=0;
+ effect_exp[0].assign("");
+ effect_exp[1].assign("");
+ effect_exp[2].assign("");
+ effect_exp[3].assign("");
+
+ m_lastxres=m_lastyres=0;
+ m_xres=16;
+ m_yres=16;
+ var_b=0;
+ subpixel=1;
+ rectcoords=0;
+ blend=0;
+ wrap=0;
+ buffern=0;
+ nomove=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=0;
+ }
+ AVS_EEL_QUITINST();
+ if (m_wmul) GlobalFree(m_wmul);
+ if (m_tab) GlobalFree(m_tab);
+
+ m_tab=0;
+ m_wmul=0;
+ DeleteCriticalSection(&rcs);
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
+ if (isBeat & 0x80000000) return 0;
+
+ smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
+ return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
+}
+
+int C_THISCLASS::smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // return value is that of render() for fbstuff etc
+{
+ return !__nomove;
+}
+
+int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ __subpixel=subpixel;
+ __rectcoords=rectcoords;
+ __blend=blend;
+ __wrap=wrap;
+ __nomove=nomove;
+
+ w_adj=(w-2)<<16;
+ h_adj=(h-2)<<16;
+ XRES=m_xres+1;
+ YRES=m_yres+1;
+
+ if (XRES < 2) XRES=2;
+ if (XRES > 256) XRES=256;
+ if (YRES < 2) YRES=2;
+ if (YRES > 256) YRES=256;
+
+ if (m_lasth != h || m_lastw != w || !m_tab || !m_wmul ||
+ m_lastxres != XRES || m_lastyres != YRES)
+ {
+ int y;
+ m_lastxres = XRES;
+ m_lastyres = YRES;
+ m_lastw=w;
+ m_lasth=h;
+ if (m_wmul) GlobalFree(m_wmul);
+ m_wmul=(int*)GlobalAlloc(GMEM_FIXED,sizeof(int)*h);
+ for (y = 0; y < h; y ++) m_wmul[y]=y*w;
+ if (m_tab) GlobalFree(m_tab);
+
+ m_tab=(int*)GlobalAlloc(GMEM_FIXED,(XRES*YRES*3 + (XRES*6 + 6)*MAX_SMP_THREADS)*sizeof(int));
+ }
+
+ if (!__subpixel)
+ {
+ w_adj=(w-1)<<16;
+ h_adj=(h-1)<<16;
+ }
+
+ if (need_recompile)
+ {
+ int x;
+ int err=0;
+ EnterCriticalSection(&rcs);
+ if (!var_b || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_d = registerVar("d");
+ var_b = registerVar("b");
+ var_r = registerVar("r");
+ var_x = registerVar("x");
+ var_y = registerVar("y");
+ var_w = registerVar("w");
+ var_h = registerVar("h");
+ var_alpha = registerVar("alpha");
+ inited=0;
+ }
+ need_recompile=0;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=compileCode(effect_exp[x].get());
+ }
+ LeaveCriticalSection(&rcs);
+ }
+ if (isBeat&0x80000000) return 0;
+ int *fbin = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
+ if (!fbin) return 0;
+
+ *var_w=(double)w;
+ *var_h=(double)h;
+ *var_b=isBeat?1.0:0.0;
+ *var_alpha=0.5;
+ if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
+ executeCode(codehandle[1],visdata);
+ if (isBeat) executeCode(codehandle[2],visdata);
+ {
+ int x;
+ int y;
+ int *tabptr=m_tab;
+
+ double xsc=2.0/w,ysc=2.0/h;
+ double dw2=((double)w*32768.0);
+ double dh2=((double)h*32768.0);
+ double max_screen_d=sqrt((double)(w*w+h*h))*0.5;
+
+ double divmax_d=1.0/max_screen_d;
+
+ max_screen_d *= 65536.0;
+
+ int yc_pos, yc_dpos, xc_pos, xc_dpos;
+ yc_pos=0;
+ xc_dpos = (w<<16)/(XRES-1);
+ yc_dpos = (h<<16)/(YRES-1);
+ for (y = 0; y < YRES; y ++)
+ {
+ xc_pos=0;
+ for (x = 0; x < XRES; x ++)
+ {
+ double xd,yd;
+
+ xd=((double)xc_pos-dw2)*(1.0/65536.0);
+ yd=((double)yc_pos-dh2)*(1.0/65536.0);
+
+ xc_pos+=xc_dpos;
+
+ *var_x=xd*xsc;
+ *var_y=yd*ysc;
+ *var_d=sqrt(xd*xd+yd*yd)*divmax_d;
+ *var_r=atan2(yd,xd) + M_PI*0.5;
+
+ executeCode(codehandle[0],visdata);
+
+ int tmp1,tmp2;
+ if (!__rectcoords)
+ {
+ *var_d *= max_screen_d;
+ *var_r -= M_PI*0.5;
+ tmp1=(int) (dw2 + cos(*var_r) * *var_d);
+ tmp2=(int) (dh2 + sin(*var_r) * *var_d);
+ }
+ else
+ {
+ tmp1=(int) ((*var_x+1.0)*dw2);
+ tmp2=(int) ((*var_y+1.0)*dh2);
+ }
+ if (!__wrap)
+ {
+ if (tmp1 < 0) tmp1=0;
+ if (tmp1 > w_adj) tmp1=w_adj;
+ if (tmp2 < 0) tmp2=0;
+ if (tmp2 > h_adj) tmp2=h_adj;
+ }
+ *tabptr++ = tmp1;
+ *tabptr++ = tmp2;
+ double va=*var_alpha;
+ if (va < 0.0) va=0.0;
+ else if (va > 1.0) va=1.0;
+ int a=(int)(va*255.0*65536.0);
+ *tabptr++ = a;
+ }
+ yc_pos+=yc_dpos;
+ }
+ }
+
+ return max_threads;
+}
+
+
+void C_THISCLASS::smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (max_threads < 1) max_threads=1;
+
+ int start_l = ( this_thread * h ) / max_threads;
+ int end_l;
+ int ypos=0;
+
+ if (this_thread >= max_threads - 1) end_l = h;
+ else end_l = ( (this_thread+1) * h ) / max_threads;
+
+ int outh=end_l-start_l;
+ if (outh<1) return;
+
+ int *fbin = !buffern ? framebuffer : (int *)getGlobalBuffer(w,h,buffern-1,0);
+ if (!fbin) return;
+ // yay, the table is generated. now we do a fixed point
+ // interpolation of the whole thing and pray.
+
+ {
+ int *interptab=m_tab+XRES*YRES*3 + this_thread * (XRES*6+6);
+ int *rdtab=m_tab;
+ unsigned int *in=(unsigned int *)fbin;
+ unsigned int *blendin=(unsigned int *)framebuffer;
+ unsigned int *out=(unsigned int *)fbout;
+ int yseek=1;
+ int xc_dpos, yc_pos=0, yc_dpos;
+ xc_dpos=(w<<16)/(XRES-1);
+ yc_dpos=(h<<16)/(YRES-1);
+ int lypos=0;
+ int yl=end_l;
+ while (yl>0)
+ {
+ yc_pos+=yc_dpos;
+ yseek=(yc_pos>>16)-lypos;
+ if (!yseek)
+ {
+ #ifndef NO_MMX
+ __asm emms;
+ #endif
+ return;
+ }
+ lypos=yc_pos>>16;
+ int l=XRES;
+ int *stab=interptab;
+ int xr3=XRES*3;
+ while (l--)
+ {
+ int tmp1, tmp2,tmp3;
+ tmp1=rdtab[0];
+ tmp2=rdtab[1];
+ tmp3=rdtab[2];
+ stab[0]=tmp1;
+ stab[1]=tmp2;
+ stab[2]=(rdtab[xr3]-tmp1)/yseek;
+ stab[3]=(rdtab[xr3+1]-tmp2)/yseek;
+ stab[4]=tmp3;
+ stab[5]=(rdtab[xr3+2]-tmp3)/yseek;
+ rdtab+=3;
+ stab+=6;
+ }
+
+ if (yseek > yl) yseek=yl;
+ yl-=yseek;
+
+ if (yseek > 0) while (yseek--)
+ {
+ int d_x;
+ int d_y;
+ int d_a;
+ int ap;
+ int seek;
+ int *seektab=interptab;
+ int xp,yp;
+ int l=w;
+ int lpos=0;
+ int xc_pos=0;
+ ypos++;
+ {
+ while (l>0)
+ {
+ xc_pos+=xc_dpos;
+ seek=(xc_pos>>16)-lpos;
+ if (!seek)
+ {
+ #ifndef NO_MMX
+ __asm emms;
+ #endif
+ return;
+ }
+ lpos=xc_pos>>16;
+ xp=seektab[0];
+ yp=seektab[1];
+ ap=seektab[4];
+ d_a=(seektab[10]-ap)/(seek);
+ d_x=(seektab[6]-xp)/(seek);
+ d_y=(seektab[7]-yp)/(seek);
+ seektab[0] += seektab[2];
+ seektab[1] += seektab[3];
+ seektab[4] += seektab[5];
+ seektab+=6;
+
+ if (seek>l) seek=l;
+ l-=seek;
+ if (seek > 0 && ypos <= start_l)
+ {
+ blendin+=seek;
+ if (__nomove) in+=seek;
+ else out+=seek;
+
+ seek=0;
+ }
+ if (seek>0)
+ {
+
+ #define CHECK
+ //__docheck(xp,yp,m_lastw,m_lasth,d_x,d_y);
+ // normal loop
+ #define NORMAL_LOOP(Z) while ((seek--)) { Z; xp+=d_x; yp+=d_y; }
+
+ #if 0
+ // this would be faster, but seems like it might be less reliable:
+ #define WRAPPING_LOOPS(Z) \
+ if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp < 0) yp += h_adj; Z) \
+ else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp += w_adj; if (yp >= h_adj) yp-=h_adj; Z) \
+ else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp < 0) yp += h_adj; Z) \
+ else NORMAL_LOOP(if (xp >= w_adj) xp-=w_adj; if (yp >= h_adj) yp-=h_adj; Z)
+
+ #define CLAMPED_LOOPS(Z) \
+ if (d_x <= 0 && d_y <= 0) NORMAL_LOOP(if (xp < 0) xp=0; if (yp < 0) yp=0; Z) \
+ else if (d_x <= 0) NORMAL_LOOP(if (xp < 0) xp=0; if (yp >= h_adj) yp=h_adj-1; Z) \
+ else if (d_y <= 0) NORMAL_LOOP(if (xp >= w_adj) xp=w_adj-1; if (yp < 0) yp=0; Z) \
+ else NORMAL_LOOP(if (xp >= w_adj) xp=w_adj-1; if (yp >= h_adj) yp=h_adj-1; Z)
+
+ #else // slower, more reliable loops
+
+ // wrapping loop
+ #define WRAPPING_LOOPS(Z) \
+ NORMAL_LOOP(if (xp < 0) xp += w_adj; \
+ else if (xp >= w_adj) xp-=w_adj; \
+ if (yp < 0) yp += h_adj; \
+ else if (yp >= h_adj) yp-=h_adj; \
+ Z)
+
+ #define CLAMPED_LOOPS(Z) \
+ NORMAL_LOOP(if (xp < 0) xp=0; \
+ else if (xp >= w_adj) xp=w_adj-1; \
+ if (yp < 0) yp=0; \
+ else if (yp >= h_adj) yp=h_adj-1; \
+ Z)
+
+ #endif
+
+ #define LOOPS(DO) \
+ if (__blend && __subpixel) DO(CHECK *out++=BLEND_ADJ(BLEND4_16(in+(xp>>16)+(m_wmul[yp>>16]),w,xp,yp),*blendin++,ap>>16); ap+=d_a) \
+ else if (__blend) DO(CHECK *out++=BLEND_ADJ(in[(xp>>16)+(m_wmul[yp>>16])],*blendin++,ap>>16); ap+=d_a) \
+ else if (__subpixel) DO(CHECK *out++=BLEND4_16(in+(xp>>16)+(m_wmul[yp>>16]),w,xp,yp)) \
+ else DO(CHECK *out++=in[(xp>>16)+(m_wmul[yp>>16])])
+
+ if (__nomove)
+ {
+ if (fbin != framebuffer) while (seek--)
+ {
+ *blendin=BLEND_ADJ(*in++,*blendin,ap>>16); ap+=d_a;
+ blendin++;
+ }
+ else while (seek--)
+ {
+ *blendin=BLEND_ADJ(0,*blendin,ap>>16); ap+=d_a;
+ blendin++;
+ }
+ }
+ else if (!__wrap)
+ {
+ // this might not really be necessary b/c of the clamping in the loop, but I'm sick of crashes
+ if (xp < 0) xp=0;
+ else if (xp >= w_adj) xp=w_adj-1;
+ if (yp < 0) yp=0;
+ else if (yp >= h_adj) yp=h_adj-1;
+
+ LOOPS(CLAMPED_LOOPS)
+ }
+ else // __wrap
+ {
+ xp %= w_adj;
+ yp %= h_adj;
+ if (xp < 0) xp+=w_adj;
+ if (yp < 0) yp+=h_adj;
+
+ if (d_x <= -w_adj) d_x=-w_adj+1;
+ else if (d_x >= w_adj) d_x=w_adj-1;
+
+ if (d_y <= -h_adj) d_y=-h_adj+1;
+ else if (d_y >= h_adj) d_y=h_adj-1;
+
+ LOOPS(WRAPPING_LOOPS)
+ }
+ } // if seek>0
+ }
+ // adjust final (rightmost elem) part of seektab
+ seektab[0] += seektab[2];
+ seektab[1] += seektab[3];
+ seektab[4] += seektab[5];
+ }
+ }
+ }
+ }
+
+
+#ifndef NO_MMX
+ __asm emms;
+#endif
+
+}
+
+C_RBASE *R_DMove(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+typedef struct
+{
+ char *name;
+ int rect;
+ int wrap;
+ int grid1;
+ int grid2;
+ char *init;
+ char *point;
+ char *frame;
+ char *beat;
+} presetType;
+
+static presetType presets[]=
+{
+ {"Random Rotate", 0, 1, 2, 2, "","r = r + dr;","","dr = (rand(100) / 100) * $PI;\r\nd = d * .95;"},
+ {"Random Direction", 1, 1, 2, 2, "speed=.05;dr = (rand(200) / 100) * $PI;","x = x + dx;\r\ny = y + dy;","dx = cos(dr) * speed;\r\ndy = sin(dr) * speed;","dr = (rand(200) / 100) * $PI;"},
+ {"In and Out", 0, 1, 2, 2, "speed=.2;c=0;","d = d * dd;","","c = c + ($PI/2);\r\ndd = 1 - (sin(c) * speed);"},
+ {"Unspun Kaleida", 0, 1, 33, 33, "c=200;f=0;dt=0;dl=0;beatdiv=8","r=cos(r*dr);","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndr = 4+(cos(dt)*2);","c=f;f=0;dl=dt"},
+ {"Roiling Gridley", 1, 1, 32, 32, "c=200;f=0;dt=0;dl=0;beatdiv=8","x=x+(sin(y*dx) * .03);\r\ny=y-(cos(x*dy) * .03);","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndx = 14+(cos(dt)*8);\r\ndy = 10+(sin(dt*2)*4);","c=f;f=0;dl=dt"},
+ {"6-Way Outswirl", 0, 0, 32, 32, "c=200;f=0;dt=0;dl=0;beatdiv=8","d=d*(1+(cos(r*6) * .05));\r\nr=r-(sin(d*dr) * .05);\r\nd = d * .98;","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndr = 18+(cos(dt)*12);","c=f;f=0;dl=dt"},
+ {"Wavy", 1, 1, 6, 6, "c=200;f=0;dx=0;dl=0;beatdiv=16;speed=.05","y = y + ((sin((x+dx) * $PI))*speed);\r\nx = x + .025","f = f + 1;\r\nt = ( (f * 2 * 3.1415) / c ) / beatdiv;\r\ndx = dl + t;","c = f;\r\nf = 0;\r\ndl = dx;"},
+ {"Smooth Rotoblitter", 0, 1, 2, 2, "c=200;f=0;dt=0;dl=0;beatdiv=4;speed=.15","r = r + dr;\r\nd = d * dd;","f = f + 1;\r\nt = ((f * $pi * 2)/c)/beatdiv;\r\ndt = dl + t;\r\ndr = cos(dt)*speed*2;\r\ndd = 1 - (sin(dt)*speed);","c=f;f=0;dl=dt"},
+};
+
+
+static C_THISCLASS *g_this;
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+ if (g_this->blend)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_this->subpixel)
+ CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ if (g_this->rectcoords)
+ CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ if (g_this->wrap)
+ CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
+ if (g_this->nomove)
+ CheckDlgButton(hwndDlg,IDC_NOMOVEMENT,BST_CHECKED);
+
+ SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRING(IDS_CURRENT));
+ {
+ int i=0;
+ char txt[64];
+ for (i=0;i<NBUF;i++)
+ {
+ wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
+ SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (int)txt);
+ }
+ }
+ SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_SETCURSEL, (WPARAM) g_this->buffern, 0);
+
+ SetDlgItemInt(hwndDlg,IDC_EDIT5,g_this->m_xres,FALSE);
+ SetDlgItemInt(hwndDlg,IDC_EDIT6,g_this->m_yres,FALSE);
+ isstart=0;
+
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+ char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_DYNAMIC_MOVEMENT,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_DYNAMIC_MOVEMENT),4095-titlelen);
+ compilerfunctionlist(hwndDlg,text);
+ }
+
+ if (LOWORD(wParam)==IDC_CHECK1)
+ {
+ g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_CHECK2)
+ {
+ g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_CHECK3)
+ {
+ g_this->rectcoords=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_WRAP)
+ {
+ g_this->wrap=IsDlgButtonChecked(hwndDlg,IDC_WRAP)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_NOMOVEMENT)
+ {
+ g_this->nomove=IsDlgButtonChecked(hwndDlg,IDC_NOMOVEMENT)?1:0;
+ }
+ // Load preset examples from the examples table.
+ if (LOWORD(wParam) == IDC_BUTTON4)
+ {
+ RECT r;
+ HMENU hMenu;
+ MENUITEMINFO i={sizeof(i),};
+ hMenu=CreatePopupMenu();
+ int x;
+ for (x = 0; x < sizeof(presets)/sizeof(presets[0]); x ++)
+ {
+ i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.wID = x+16;
+ i.dwTypeData=presets[x].name;
+ i.cch=strlen(presets[x].name);
+ InsertMenuItem(hMenu,x,TRUE,&i);
+ }
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON1),&r);
+ x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.right,r.top,0,hwndDlg,NULL);
+ if (x >= 16 && x < 16+sizeof(presets)/sizeof(presets[0]))
+ {
+ SetDlgItemText(hwndDlg,IDC_EDIT1,presets[x-16].point);
+ SetDlgItemText(hwndDlg,IDC_EDIT2,presets[x-16].frame);
+ SetDlgItemText(hwndDlg,IDC_EDIT3,presets[x-16].beat);
+ SetDlgItemText(hwndDlg,IDC_EDIT4,presets[x-16].init);
+ SetDlgItemInt(hwndDlg,IDC_EDIT5,presets[x-16].grid1,FALSE);
+ SetDlgItemInt(hwndDlg,IDC_EDIT6,presets[x-16].grid2,FALSE);
+ if (presets[x-16].rect)
+ {
+ g_this->rectcoords = 1;
+ CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ }
+ else
+ {
+ g_this->rectcoords = 0;
+ CheckDlgButton(hwndDlg,IDC_CHECK3,0);
+ }
+ if (presets[x-16].wrap)
+ {
+ g_this->wrap = 1;
+ CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
+ }
+ else
+ {
+ g_this->wrap = 0;
+ CheckDlgButton(hwndDlg,IDC_WRAP,0);
+ }
+ SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_EDIT4,EN_CHANGE),0);
+ }
+ DestroyMenu(hMenu);
+ }
+
+ if (!isstart && HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMBO1) // handle clicks to combo box
+ g_this->buffern = SendDlgItemMessage(hwndDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0);
+
+ if (!isstart && HIWORD(wParam) == EN_CHANGE)
+ {
+ if (LOWORD(wParam) == IDC_EDIT5 || LOWORD(wParam) == IDC_EDIT6)
+ {
+ BOOL t;
+ g_this->m_xres=GetDlgItemInt(hwndDlg,IDC_EDIT5,&t,0);
+ g_this->m_yres=GetDlgItemInt(hwndDlg,IDC_EDIT6,&t,0);
+ }
+
+ if (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
+ g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
+ g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
+ g_this->need_recompile=1;
+ if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_DMOVE,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_DMove(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_dotfnt.cpp b/Src/Plugins/Visualization/vis_avs/r_dotfnt.cpp
new file mode 100644
index 00000000..2ec518a9
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_dotfnt.cpp
@@ -0,0 +1,324 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <stdio.h>
+#include <math.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+
+#ifndef LASER
+
+#define C_THISCLASS C_DotFountainClass
+#define MOD_NAME "Render / Dot Fountain"
+
+#define NUM_ROT_DIV 30
+#define NUM_ROT_HEIGHT 256
+typedef struct {
+ float r, dr;
+ float h, dh;
+ float ax,ay;
+ int c;
+} FountainPoint;
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ float r;
+ FountainPoint points[NUM_ROT_HEIGHT][NUM_ROT_DIV];
+ int color_tab[64];
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int, int);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_DOT_FOUNTAIN,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int rotvel,angle;
+ int colors[5];
+
+ void initcolortab();
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { rotvel=GET_INT(); pos+=4; }
+ int x;
+ for (x = 0; x < 5; x ++)
+ {
+ if (len-pos >= 4) { colors[x]=GET_INT(); pos+=4; }
+ }
+ if (len-pos >= 4) { angle=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { int rr=GET_INT(); pos+=4; r=rr/32.0f;}
+
+
+ initcolortab();
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int rr;
+ int pos=0;
+ int x;
+ PUT_INT(rotvel); pos+=4;
+ for (x = 0; x < 5; x ++)
+ {
+ PUT_INT(colors[x]); pos+=4;
+ }
+ PUT_INT(angle); pos+=4;
+ rr=(int)(r*32.0f);
+ PUT_INT(rr); pos+=4;
+ return pos;
+}
+
+
+void C_THISCLASS::initcolortab()
+{
+ int x,r,g,b,dr,dg,db,t;
+ for (t=0; t < 4; t ++)
+ {
+ r=(colors[t]&255)<<16;
+ g=((colors[t]>>8)&255)<<16;
+ b=((colors[t]>>16)&255)<<16;
+ dr=(((colors[t+1]&255)-(colors[t]&255))<<16)/16;
+ dg=((((colors[t+1]>>8)&255)-((colors[t]>>8)&255))<<16)/16;
+ db=((((colors[t+1]>>16)&255)-((colors[t]>>16)&255))<<16)/16;
+ for (x = 0; x < 16; x ++)
+ {
+ color_tab[t*16+x]=(r>>16)|((g>>16)<<8)|((b>>16)<<16);
+ r+=dr;g+=dg;b+=db;
+ }
+ }
+}
+
+C_THISCLASS::C_THISCLASS()
+{
+ colors[0]=RGB(24,107,28); // reverse BGR :)
+ colors[1]=RGB(35,10,255);
+ colors[2]=RGB(116,29,42);
+ colors[3]=RGB(217,54,144);
+ colors[4]=RGB(255,136,107);
+ initcolortab();
+
+ memset(points,0,sizeof(points));
+
+ angle=-20;
+ rotvel=16;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int width, int height)
+{
+ if (isBeat&0x80000000) return 0;
+ int fo, p;
+ float matrix[16],matrix2[16];
+ matrixRotate(matrix,2,r);
+ matrixRotate(matrix2,1,(float)angle);
+ matrixMultiply(matrix,matrix2);
+ matrixTranslate(matrix2,0.0f,-20.0f,400.0f);
+ matrixMultiply(matrix,matrix2);
+
+
+ FountainPoint pb[NUM_ROT_DIV];
+ FountainPoint *in, *out;
+ memcpy(pb,&points[0],sizeof(pb));
+ fo = NUM_ROT_HEIGHT-2;
+ do // transform points and remove old ones
+ {
+ float booga = 1.3f / (fo+100);
+ in = &points[fo][0];
+ out = &points[fo+1][0];
+ for (p = 0; p < NUM_ROT_DIV; p ++)
+ {
+ *out = *in;
+ out->r += out->dr;
+ out->dh += 0.05f;
+ out->dr += booga;
+ out->h += out->dh;
+ out++;
+ in++;
+ }
+ } while (fo--);
+
+ out = &points[0][0];
+ in = pb;
+ { // create new points
+ float a;
+ unsigned char *sd = (unsigned char *) visdata[1][0];
+ for (p = 0; p < NUM_ROT_DIV; p ++)
+ {
+ int t;
+ if (p >= NUM_ROT_DIV) t= (sd[576] ^ 128);
+ else t= (*sd ^ 128);
+ sd++;
+ t*=5;
+ t/=4;
+ t-=64;
+ if (isBeat) t+=128;
+ if (t > 255) t=255;
+// t+=sd[576]^128;
+ // t/=2;
+ out->r = 1.0f;
+ float dr = t/200.0f;
+ if (dr < 0) dr = -dr;
+ out->h = 250;
+ dr += 1.0;
+ out->dh = -dr * (100.0f + (out->dh - in->dh)) / 100.0f * 2.8f;
+ t = t/4;
+ if (t > 63) t = 63;
+ out->c = color_tab[t];
+ a = p* 3.14159f * 2.0f / NUM_ROT_DIV;
+ out->ax=(float)sin(a);
+ out->ay=(float)cos(a);
+ out->dr =0.0;
+ out++;
+ in++;
+ }
+ }
+
+ float adj=width*440.0f/640.0f;
+ float adj2=height*440.0f/480.0f;
+ if (adj2 < adj) adj=adj2;
+ in = &points[0][0];
+ for (fo = 0; fo < NUM_ROT_HEIGHT; fo ++)
+ {
+ for (p = 0; p < NUM_ROT_DIV; p ++)
+ {
+ register float x, y, z;
+ matrixApply(matrix,in->ax*in->r,in->h,in->ay*in->r,&x,&y,&z);
+ z = adj / z;
+ if (z > 0.0000001)
+ {
+ register int ix = (int) (x * z) + width/2;
+ register int iy = (int) (y * z) + height/2;
+ if (iy >= 0 && iy < height && ix >= 0 && ix < width)
+ {
+ BLEND_LINE(framebuffer + iy*width + ix,in->c);
+ }
+ }
+ in++;
+ }
+ }
+ r += rotvel/5.0f;
+ if (r >= 360.0f) r -= 360.0f;
+ if (r < 0.0f) r += 360.0f;
+ return 0;
+}
+
+C_RBASE *R_DotFountain(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+ g_this->rotvel=0;
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,50);
+ }
+ if (LOWORD(wParam) >= IDC_C1 && LOWORD(wParam) <= IDC_C5) {
+ GR_SelectColor(hwndDlg,&g_this->colors[IDC_C5-LOWORD(wParam)]);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ g_this->initcolortab();
+ }
+ return 0;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID >= IDC_C1 && di->CtlID <= IDC_C5)
+ {
+ GR_DrawColoredButton(di,g_this->colors[IDC_C5-di->CtlID]);
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,101);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->rotvel+50);
+ SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMAX,0,181);
+ SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETPOS,1,g_this->angle+90);
+
+ return 1;
+
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->rotvel=t-50;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_ANGLE))
+ {
+ g_this->angle=t-90;
+ }
+ }
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_DOTPLANE,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_DotFountain(char *desc) {return NULL; }
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_dotgrid.cpp b/Src/Plugins/Visualization/vis_avs/r_dotgrid.cpp
new file mode 100644
index 00000000..129c6410
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_dotgrid.cpp
@@ -0,0 +1,331 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+
+#include <math.h>
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_DotGridClass
+#define MOD_NAME "Render / Dot Grid"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_DOT_GRID,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int num_colors;
+ int colors[16];
+
+ int color_pos;
+
+ int xp;
+ int yp;
+ int x_move;
+ int y_move;
+ int spacing;
+ int blend;
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=0;
+ if (len-pos >= 4) { spacing=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { x_move=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { y_move=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ PUT_INT(spacing); pos+=4;
+ PUT_INT(x_move); pos+=4;
+ PUT_INT(y_move); pos+=4;
+ PUT_INT(blend); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+ xp=0;
+ yp=0;
+ x_move=128;
+ y_move=128;
+ spacing=8;
+ blend=3;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int x,y;
+ int current_color;
+
+ if (isBeat&0x80000000) return 0;
+ if (!num_colors) return 0;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+ if (spacing<2)spacing=2;
+ while (yp < 0) yp+=spacing*256;
+ while (xp < 0) xp+=spacing*256;
+
+ int sy=(yp>>8)%spacing;
+ int sx=(xp>>8)%spacing;
+ framebuffer += sy*w;
+ for (y = sy; y < h; y += spacing)
+ {
+ if (blend==1)
+ for (x = sx; x < w; x += spacing)
+ framebuffer[x]=BLEND(framebuffer[x],current_color);
+ else if (blend == 2)
+ for (x = sx; x < w; x += spacing)
+ framebuffer[x]=BLEND_AVG(framebuffer[x],current_color);
+ else if (blend == 3)
+ for (x = sx; x < w; x += spacing)
+ BLEND_LINE(framebuffer+x,current_color);
+ else
+ for (x = sx; x < w; x += spacing)
+ framebuffer[x]=current_color;
+ framebuffer += w*spacing;
+ }
+ xp+=x_move;
+ yp+=y_move;
+
+ return 0;
+}
+
+C_RBASE *R_DotGrid(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,33);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->x_move/32+16);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,33);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->y_move/32+16);
+
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,g_this->spacing,FALSE);
+ if (g_this->blend==1)
+ CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
+ else if (g_this->blend==2)
+ CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
+ else if (g_this->blend==3)
+ CheckDlgButton(hwndDlg,IDC_RADIO4,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
+ return 1;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->x_move=(t-16)*32;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
+ {
+ g_this->y_move=(t-16)*32;
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_BUTTON1:
+ g_this->x_move=0;
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,16);
+ return 0;
+ case IDC_BUTTON3:
+ g_this->y_move=0;
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,16);
+ return 0;
+ case IDC_RADIO1:
+ case IDC_RADIO2:
+ case IDC_RADIO3:
+ case IDC_RADIO4:
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1)) g_this->blend=0;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2)) g_this->blend=1;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3)) g_this->blend=2;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO4)) g_this->blend=3;
+ break;
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_EDIT1:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_EDIT1,&tr,FALSE);
+ if (tr)
+ {
+ if (p < 2) p = 2;
+ g_this->spacing=p;
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_DOTGRID,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_DotGrid(char *desc) { return NULL; }
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/r_dotpln.cpp b/Src/Plugins/Visualization/vis_avs/r_dotpln.cpp
new file mode 100644
index 00000000..0f94b133
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_dotpln.cpp
@@ -0,0 +1,313 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <math.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_DotPlaneClass
+#define MOD_NAME "Render / Dot Plane"
+
+#define NUM_WIDTH 64
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ float r;
+ float atable[NUM_WIDTH*NUM_WIDTH];
+ float vtable[NUM_WIDTH*NUM_WIDTH];
+ int ctable[NUM_WIDTH*NUM_WIDTH];
+ int color_tab[64];
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int, int);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_DOT_PLANE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int rotvel,angle;
+ int colors[5];
+
+ void initcolortab();
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { rotvel=GET_INT(); pos+=4; }
+ int x;
+ for (x = 0; x < 5; x ++)
+ {
+ if (len-pos >= 4) { colors[x]=GET_INT(); pos+=4; }
+ }
+ if (len-pos >= 4) { angle=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { int rr=GET_INT(); pos+=4; r=rr/32.0f;}
+
+
+ initcolortab();
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int rr;
+ int pos=0;
+ int x;
+ PUT_INT(rotvel); pos+=4;
+ for (x = 0; x < 5; x ++)
+ {
+ PUT_INT(colors[x]); pos+=4;
+ }
+ PUT_INT(angle); pos+=4;
+ rr=(int)(r*32.0f);
+ PUT_INT(rr); pos+=4;
+ return pos;
+}
+
+
+void C_THISCLASS::initcolortab()
+{
+ int x,r,g,b,dr,dg,db,t;
+ for (t=0; t < 4; t ++)
+ {
+ r=(colors[t]&255)<<16;
+ g=((colors[t]>>8)&255)<<16;
+ b=((colors[t]>>16)&255)<<16;
+ dr=(((colors[t+1]&255)-(colors[t]&255))<<16)/16;
+ dg=((((colors[t+1]>>8)&255)-((colors[t]>>8)&255))<<16)/16;
+ db=((((colors[t+1]>>16)&255)-((colors[t]>>16)&255))<<16)/16;
+ for (x = 0; x < 16; x ++)
+ {
+ color_tab[t*16+x]=(r>>16)|((g>>16)<<8)|((b>>16)<<16);
+ r+=dr;g+=dg;b+=db;
+ }
+ }
+}
+
+C_THISCLASS::C_THISCLASS()
+{
+ colors[0]=RGB(24,107,28); // reverse BGR :)
+ colors[1]=RGB(35,10,255);
+ colors[2]=RGB(116,29,42);
+ colors[3]=RGB(217,54,144);
+ colors[4]=RGB(255,136,107);
+ initcolortab();
+
+ memset(atable,0,sizeof(atable));
+ memset(vtable,0,sizeof(vtable));
+ memset(ctable,0,sizeof(ctable));
+
+ angle=-20;
+ rotvel=16;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int width, int height)
+{
+ if (isBeat&0x80000000) return 0;
+ float btable[NUM_WIDTH];
+ int fo, p;
+ float matrix[16],matrix2[16];
+ matrixRotate(matrix,2,r);
+ matrixRotate(matrix2,1,(float)angle);
+ matrixMultiply(matrix,matrix2);
+ matrixTranslate(matrix2,0.0f,-20.0f,400.0f);
+ matrixMultiply(matrix,matrix2);
+
+ memcpy(btable,&atable[0],sizeof(float)*NUM_WIDTH);
+ for (fo = 0; fo < NUM_WIDTH; fo ++)
+ {
+ float *i, *o, *v, *ov;
+ int *c,*oc;
+ int t=(NUM_WIDTH-(fo+2))*NUM_WIDTH;
+ i = &atable[t];
+ o = &atable[t+NUM_WIDTH];
+ v = &vtable[t];
+ ov = &vtable[t+NUM_WIDTH];
+ c = &ctable[t];
+ oc = &ctable[t+NUM_WIDTH];
+ if (fo == NUM_WIDTH-1)
+ {
+ unsigned char *sd = (unsigned char *)&visdata[0][0][0];
+ i = btable;
+ for (p = 0; p < NUM_WIDTH; p ++)
+ {
+ register int t;
+ t=max(sd[0],sd[1]);
+ t=max(t,sd[2]);
+ *o = (float)t;
+ t>>=2;
+ if (t > 63) t=63;
+ *oc++=color_tab[t];
+
+ *ov++ = (*o++ - *i++) / 90.0f;
+ sd+=3;
+ }
+ }
+ else for (p = 0; p < NUM_WIDTH; p ++)
+ {
+ *o = *i++ + *v;
+ if (*o < 0.0f) *o=0.0f;
+ *ov++ = *v++ - 0.15f*(*o++/255.0f);
+ *oc++ = *c++;
+
+ }
+ }
+
+ float adj=width*440.0f/640.0f;
+ float adj2=height*440.0f/480.0f;
+ if (adj2 < adj) adj=adj2;
+ for (fo = 0; fo < NUM_WIDTH; fo ++)
+ {
+ int f = (r < 90.0 || r > 270.0) ? NUM_WIDTH-fo-1 : fo;
+ float dw=350.0f/(float)NUM_WIDTH, w = -(NUM_WIDTH*0.5f)*dw;
+ float q = (f - NUM_WIDTH*0.5f)*dw;
+ int *ct = &ctable[f*NUM_WIDTH];
+ float *at = &atable[f*NUM_WIDTH];
+ int da=1;
+ if (r < 180.0)
+ {
+ da=-1;
+ dw=-dw;
+ w=-w+dw;
+ ct += NUM_WIDTH-1;
+ at += NUM_WIDTH-1;
+ }
+ for (p = 0; p < NUM_WIDTH; p ++)
+ {
+ float x, y, z;
+ matrixApply(matrix,w,64.0f-*at,q,&x,&y,&z);
+ z = adj / z;
+ register int ix = (int) (x * z) + (width/2);
+ register int iy = (int) (y * z) + (height/2);
+ if (iy >= 0 && iy < height && ix >= 0 && ix < width)
+ {
+ BLEND_LINE(framebuffer + iy*width + ix,*ct);
+ }
+ w+=dw;
+ ct+=da;
+ at+=da;
+ }
+ }
+ r += rotvel/5.0f;
+ if (r >= 360.0f) r -= 360.0f;
+ if (r < 0.0f) r += 360.0f;
+ return 0;
+}
+
+C_RBASE *R_DotPlane(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+ g_this->rotvel=0;
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,50);
+ }
+ if (LOWORD(wParam) >= IDC_C1 && LOWORD(wParam) <= IDC_C5) {
+ GR_SelectColor(hwndDlg,&g_this->colors[IDC_C5-LOWORD(wParam)]);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ g_this->initcolortab();
+ }
+ return 0;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID >= IDC_C1 && di->CtlID <= IDC_C5)
+ {
+ GR_DrawColoredButton(di,g_this->colors[IDC_C5-di->CtlID]);
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,101);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->rotvel+50);
+ SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETRANGEMAX,0,181);
+ SendDlgItemMessage(hwndDlg,IDC_ANGLE,TBM_SETPOS,1,g_this->angle+90);
+
+ return 1;
+
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->rotvel=t-50;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_ANGLE))
+ {
+ g_this->angle=t-90;
+ }
+ }
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_DOTPLANE,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_DotPlane(char *desc) { return NULL; }
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_fadeout.cpp b/Src/Plugins/Visualization/vis_avs/r_fadeout.cpp
new file mode 100644
index 00000000..335b64cf
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_fadeout.cpp
@@ -0,0 +1,280 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_FadeOutClass
+#define MOD_NAME "Trans / Fadeout"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_FADEOUT,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ void maketab(void);
+
+ unsigned char fadtab[3][256];
+ int fadelen, color;
+};
+
+void C_THISCLASS::maketab(void)
+{
+ int rseek=color&0xff;
+ int gseek=(color>>8)&0xff;
+ int bseek=(color>>16)&0xff;
+ int x;
+ for (x = 0; x < 256; x ++)
+ {
+ int r=x;
+ int g=x;
+ int b=x;
+ if (r <= rseek-fadelen) r+=fadelen;
+ else if (r >= rseek+fadelen) r-=fadelen;
+ else r=rseek;
+
+ if (g <= gseek-fadelen) g+=fadelen;
+ else if (g >= gseek+fadelen) g-=fadelen;
+ else g=gseek;
+ if (b <= bseek-fadelen) b+=fadelen;
+ else if (b >= bseek+fadelen) b-=fadelen;
+ else b=bseek;
+
+ fadtab[0][x]=r;
+ fadtab[1][x]=g;
+ fadtab[2][x]=b;
+ }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { fadelen=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ maketab();
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(fadelen); pos+=4;
+ PUT_INT(color); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ color=0;
+ fadelen=16;
+ maketab();
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+ if (!fadelen) return 0;
+ timingEnter(1);
+ if (
+#ifdef NO_MMX
+ 1
+#else
+ color
+#endif
+ )
+ {
+ unsigned char *t=(unsigned char *)framebuffer;
+ int x=w*h;
+ while (x--)
+ {
+ t[0]=fadtab[0][t[0]];
+ t[1]=fadtab[1][t[1]];
+ t[2]=fadtab[2][t[2]];
+ t+=4;
+ }
+ }
+#ifndef NO_MMX
+ else
+ {
+ int l=(w*h);
+ char fadj[8];
+ int x;
+ unsigned char *t=fadtab[0];
+ for (x = 0; x < 8; x ++) fadj[x]=this->fadelen;
+ __asm
+ {
+ mov edx, l
+ mov edi, framebuffer
+ movq mm7, [fadj]
+ shr edx, 3
+ align 16
+ _l1:
+ movq mm0, [edi]
+
+ movq mm1, [edi+8]
+
+ movq mm2, [edi+16]
+ psubusb mm0, mm7
+
+ movq mm3, [edi+24]
+ psubusb mm1, mm7
+
+ movq [edi], mm0
+ psubusb mm2, mm7
+
+ movq [edi+8], mm1
+ psubusb mm3, mm7
+
+ movq [edi+16], mm2
+
+ movq [edi+24], mm3
+
+ add edi, 8*4
+
+ dec edx
+ jnz _l1
+
+ mov edx, l
+ sub eax, eax
+
+ and edx, 7
+ jz _l3
+
+ sub ebx, ebx
+ sub ecx, ecx
+
+ mov esi, t
+ _l2:
+ mov al, [edi]
+ mov bl, [edi+1]
+ mov cl, [edi+2]
+ sub al, [esi+eax]
+ sub bl, [esi+ebx]
+ sub cl, [esi+ecx]
+ mov [edi], al
+ mov [edi+1], bl
+ mov [edi+2], cl
+ add edi, 4
+ dec edx
+ jnz _l2
+ _l3:
+ emms
+ }
+ }
+#endif
+ timingLeave(1);
+ return 0;
+}
+
+C_RBASE *R_FadeOut(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_LC:
+ GR_DrawColoredButton(di,g_this->color);
+ break;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,92);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->fadelen);
+
+ return 1;
+
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->fadelen=t;
+ g_this->maketab();
+ }
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_LC:
+ GR_SelectColor(hwndDlg,&g_this->color);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ g_this->maketab();
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_FADE,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_FadeOut(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_fastbright.cpp b/Src/Plugins/Visualization/vis_avs/r_fastbright.cpp
new file mode 100644
index 00000000..f30a6710
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_fastbright.cpp
@@ -0,0 +1,279 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_FastBright
+#define MOD_NAME "Trans / Fast Brightness"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_FAST_BRIGHTNESS,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+#ifdef NO_MMX
+ int tab[3][256];
+#endif
+
+ int dir;
+};
+
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ dir=0;
+ if (len-pos >= 4) { dir=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(dir); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+#ifdef NO_MMX
+ int x;
+ for (x = 0; x < 128; x ++)
+ {
+ tab[0][x]=x+x;
+ tab[1][x]=x<<9;
+ tab[2][x]=x<<17;
+ }
+ for (; x < 256; x ++)
+ {
+ tab[0][x]=255;
+ tab[1][x]=255<<8;
+ tab[2][x]=255<<16;
+ }
+#endif
+ dir=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+#ifdef NO_MMX // the non mmx x2 version really isn't any , in terms faster than normal brightness with no exclusions turned on
+ {
+ unsigned int *t=(unsigned int *)framebuffer;
+ int x;
+ unsigned int mask = 0x7F7F7F7F;
+
+ x=w*h/2;
+ if (dir == 0)
+ while (x--)
+ {
+ unsigned int v1=t[0];
+ unsigned int v2=t[1];
+ v1=tab[0][v1&0xff]|tab[1][(v1>>8)&0xff]|tab[2][(v1>>16)&0xff]|(v1&0xff000000);
+ v2=tab[0][v2&0xff]|tab[1][(v2>>8)&0xff]|tab[2][(v2>>16)&0xff]|(v2&0xff000000);
+ t[0]=v1;
+ t[1]=v2;
+ t+=2;
+ }
+ else if (dir == 1)
+ while (x--)
+ {
+ unsigned int v1=t[0]>>1;
+ unsigned int v2=t[1]>>1;
+ t[0]=v1&mask;
+ t[1]=v2&mask;
+ t+=2;
+ }
+ }
+#else
+ int mask[2] =
+ {
+ 0x7F7F7F7F,
+ 0x7F7F7F7F,
+ };
+ int l=(w*h);
+ if (dir == 0) __asm
+ {
+ mov edx, l
+ mov edi, framebuffer
+ shr edx, 3 // 8 pixels at a time
+ align 16
+ _l1:
+ movq mm0, [edi]
+ movq mm1, [edi+8]
+ movq mm2, [edi+16]
+ paddusb mm0, mm0
+ movq mm3, [edi+24]
+ paddusb mm1, mm1
+ paddusb mm2, mm2
+ movq [edi], mm0
+ paddusb mm3, mm3
+ movq [edi+8], mm1
+ movq [edi+16], mm2
+ movq [edi+24], mm3
+
+ add edi, 32
+
+ dec edx
+ jnz _l1
+
+ mov edx, l
+ and edx, 7
+ shr edx, 1 // up the last 7 pixels (two at a time)
+ jz _l3
+
+ _l2:
+ movq mm3, [edi]
+ paddusb mm3, mm3
+ movq [edi], mm3
+ add edi, 8
+ dec edx
+ jnz _l2
+ _l3:
+ emms
+ }
+ else if (dir == 1) __asm
+ {
+ mov edx, l
+ movq mm7, [mask]
+ mov edi, framebuffer
+ shr edx, 3 // 8 pixels at a time
+ align 16
+ _lr1:
+ movq mm0, [edi]
+ movq mm1, [edi+8]
+
+ movq mm2, [edi+16]
+ psrl mm0, 1
+
+ movq mm3, [edi+24]
+ pand mm0, mm7
+
+ psrl mm1, 1
+ movq [edi], mm0
+
+ psrl mm2, 1
+ pand mm1, mm7
+
+ movq [edi+8], mm1
+ pand mm2, mm7
+
+ psrl mm3, 1
+ movq [edi+16], mm2
+
+ pand mm3, mm7
+ movq [edi+24], mm3
+
+ add edi, 32
+
+ dec edx
+ jnz _lr1
+
+ mov edx, l
+ and edx, 7
+ shr edx, 1 // up the last 7 pixels (two at a time)
+ jz _lr3
+
+ _lr2:
+ movq mm3, [edi]
+ psrl mm3, 1
+ pand mm3, mm7
+ movq [edi], mm3
+ add edi, 8
+ dec edx
+ jnz _lr2
+ _lr3:
+ emms
+ }
+#endif
+ return 0;
+}
+
+C_RBASE *R_FastBright(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_this->dir==0) CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
+ else if (g_this->dir == 1) CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_RADIO1)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1))
+ g_this->dir=0;
+ if (LOWORD(wParam) == IDC_RADIO2)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2))
+ g_this->dir=1;
+ if (LOWORD(wParam) == IDC_RADIO3)
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3))
+ g_this->dir=2;
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_FASTBRIGHT,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_FastBright(char *desc) { return NULL; }
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_grain.cpp b/Src/Plugins/Visualization/vis_avs/r_grain.cpp
new file mode 100644
index 00000000..ed8f368b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_grain.cpp
@@ -0,0 +1,406 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Grain"
+#define C_THISCLASS C_GrainClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_GRAIN,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ unsigned char __inline fastrandbyte(void);
+ void reinit(int w, int h);
+ int enabled;
+ int blend, blendavg, smax;
+ unsigned char *depthBuffer;
+ int oldx, oldy;
+ int staticgrain;
+ unsigned char randtab[491];
+ int randtab_pos;
+};
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS() // set up default configuration
+{
+if (depthBuffer)
+ GlobalFree(depthBuffer);
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ blend=0;
+ blendavg=0;
+ smax=100;
+ enabled=1;
+ oldx=0;
+ oldy=0;
+ staticgrain=0;
+ depthBuffer=NULL;
+ int x;
+ for (x = 0 ;x < sizeof(randtab); x ++)
+ randtab[x]=rand()&255;
+ randtab_pos=rand()%sizeof(randtab);
+}
+
+unsigned char __inline C_THISCLASS::fastrandbyte(void)
+{
+ unsigned char r=randtab[randtab_pos];
+ randtab_pos++;
+ if (!(randtab_pos&15))
+ {
+ randtab_pos+=rand()%73;
+ }
+ if (randtab_pos >= 491) randtab_pos-=491;
+ return r;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { smax=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { staticgrain=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(smax); pos+=4;
+ PUT_INT(staticgrain); pos+=4;
+ return pos;
+}
+
+void C_THISCLASS::reinit(int w, int h)
+{
+int x,y;
+unsigned char *p;
+if (depthBuffer)
+ GlobalFree(depthBuffer);
+depthBuffer = (unsigned char *)GlobalAlloc(GMEM_FIXED,w*h*2);
+p = depthBuffer;
+if (p)
+ for (y=0;y<h;y++)
+ for (x=0;x<w;x++)
+ {
+ *p++ = (rand()%255);
+ *p++ = (rand()%100);
+ }
+
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+ if (!enabled) return 0;
+
+ int smax_sc = (smax*255)/100;
+ int *p;
+ unsigned char *q;
+ int l=w*h;
+
+ if (w != oldx || h != oldy)
+ {
+ reinit(w, h);
+ oldx = w;
+ oldy = h;
+ }
+ randtab_pos+=rand()%300;
+ if (randtab_pos >= 491) randtab_pos-=491;
+
+ p = framebuffer;
+ q = depthBuffer;
+ if (staticgrain)
+ {
+ if (blend)
+ {
+ while (l--)
+ {
+ if (*p)
+ {
+ int c=0;
+ if (q[1] < smax_sc)
+ {
+ int s = q[0];
+ int r=(((p[0]&0xff0000)*s)>>8);
+ if (r > 0xff0000) r=0xff0000;
+ c|=r&0xff0000;
+ r=(((p[0]&0xff00)*s)>>8);
+ if (r > 0xff00) r=0xff00;
+ c|=r&0xff00;
+ r=(((p[0]&0xff)*s)>>8);
+ if (r > 0xff) r=0xff;
+ c|=r;
+ }
+ *p = BLEND(*p, c);
+ }
+ p++;
+ q+=2;
+ }
+ }
+ else if (blendavg)
+ {
+ while (l--)
+ {
+ if (*p)
+ {
+ int c=0;
+ if (q[1] < smax_sc)
+ {
+ int s = q[0];
+ int r=(((p[0]&0xff0000)*s)>>8);
+ if (r > 0xff0000) r=0xff0000;
+ c|=r&0xff0000;
+ r=(((p[0]&0xff00)*s)>>8);
+ if (r > 0xff00) r=0xff00;
+ c|=r&0xff00;
+ r=(((p[0]&0xff)*s)>>8);
+ if (r > 0xff) r=0xff;
+ c|=r;
+ }
+ *p = BLEND_AVG(*p, c);
+ }
+ p++;
+ q+=2;
+ }
+ }
+ else
+ {
+ while (l--)
+ {
+ if (*p)
+ {
+ int c=0;
+ if (q[1] < smax_sc)
+ {
+ int s = q[0];
+ int r=(((p[0]&0xff0000)*s)>>8);
+ if (r > 0xff0000) r=0xff0000;
+ c|=r&0xff0000;
+ r=(((p[0]&0xff00)*s)>>8);
+ if (r > 0xff00) r=0xff00;
+ c|=r&0xff00;
+ r=(((p[0]&0xff)*s)>>8);
+ if (r > 0xff) r=0xff;
+ c|=r;
+ }
+ *p = c;
+ }
+ p++;
+ q+=2;
+ }
+ }
+ }
+ else
+ {
+ if (blend)
+ {
+ while (l--)
+ {
+ if (*p)
+ {
+ int c=0;
+ if (fastrandbyte() < smax_sc)
+ {
+ int s = fastrandbyte();
+ int r=(((p[0]&0xff0000)*s)>>8);
+ if (r > 0xff0000) r=0xff0000;
+ c|=r&0xff0000;
+ r=(((p[0]&0xff00)*s)>>8);
+ if (r > 0xff00) r=0xff00;
+ c|=r&0xff00;
+ r=(((p[0]&0xff)*s)>>8);
+ if (r > 0xff) r=0xff;
+ c|=r;
+ }
+ *p = BLEND(*p, c);
+ }
+ p++;
+ q+=2;
+ }
+ }
+ else if (blendavg)
+ {
+ while (l--)
+ {
+ if (*p)
+ {
+ int c=0;
+ if (fastrandbyte() < smax_sc)
+ {
+ int s = fastrandbyte();
+ int r=(((p[0]&0xff0000)*s)>>8);
+ if (r > 0xff0000) r=0xff0000;
+ c|=r&0xff0000;
+ r=(((p[0]&0xff00)*s)>>8);
+ if (r > 0xff00) r=0xff00;
+ c|=r&0xff00;
+ r=(((p[0]&0xff)*s)>>8);
+ if (r > 0xff) r=0xff;
+ c|=r;
+ }
+ *p = BLEND_AVG(*p, c);
+ }
+ p++;
+ q+=2;
+ }
+ }
+ else
+ {
+ while (l--)
+ {
+ if (*p)
+ {
+ int c=0;
+ if (fastrandbyte() < smax_sc)
+ {
+ int s = fastrandbyte();
+ int r=(((p[0]&0xff0000)*s)>>8);
+ if (r > 0xff0000) r=0xff0000;
+ c|=r&0xff0000;
+ r=(((p[0]&0xff00)*s)>>8);
+ if (r > 0xff00) r=0xff00;
+ c|=r&0xff00;
+ r=(((p[0]&0xff)*s)>>8);
+ if (r > 0xff) r=0xff;
+ c|=r;
+ }
+ *p = c;
+ }
+ p++;
+ q+=2;
+ }
+ }
+ }
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_MAX, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_MAX, TBM_SETRANGE, TRUE, MAKELONG(0, 100));
+ SendDlgItemMessage(hwndDlg, IDC_MAX, TBM_SETPOS, TRUE, g_ConfigThis->smax);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->staticgrain) CheckDlgButton(hwndDlg,IDC_STATGRAIN,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_MAX)
+ g_ConfigThis->smax = SendDlgItemMessage(hwndDlg, IDC_MAX, TBM_GETPOS, 0, 0);
+ return 0;
+ }
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_STATGRAIN) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->staticgrain=IsDlgButtonChecked(hwndDlg,IDC_STATGRAIN)?1:0;
+ }
+ return 0;
+ }
+return 0;
+}
+
+
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_GRAIN,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Grain(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+#else
+C_RBASE *R_Grain(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_interf.cpp b/Src/Plugins/Visualization/vis_avs/r_interf.cpp
new file mode 100644
index 00000000..40b4e4bd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_interf.cpp
@@ -0,0 +1,525 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <commctrl.h>
+#include <math.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Interferences"
+#define C_THISCLASS C_InterferencesClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ float GET_FLOAT(unsigned char *data, int pos);
+ void PUT_FLOAT(float f, unsigned char *data, int pos);
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_INTERFERENCES,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int enabled;
+ int nPoints;
+ int distance;
+ int alpha;
+ int rotation;
+ int rotationinc;
+ int distance2;
+ int alpha2;
+ int rotationinc2;
+ int rgb;
+ int blend;
+ int blendavg;
+ float speed;
+ int onbeat;
+ float a;
+ int _distance;
+ int _alpha;
+ int _rotationinc;
+ int _rgb;
+ float status;
+ };
+
+#define PI 3.14159
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+enabled=1;
+nPoints = 2;
+distance=10;
+alpha=128;
+rotation=0;
+rotationinc=0;
+rgb=1;
+blendavg=0;
+blend=0;
+onbeat=1;
+distance2=32;
+rotationinc2=25;
+alpha2=192;
+status=2;
+speed = (float)0.2;
+a=(float)rotation/255*(float)PI*2;
+}
+
+void C_THISCLASS::PUT_FLOAT(float f, unsigned char *data, int pos)
+{
+int y = *(int *)&f;
+data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255;
+}
+
+float C_THISCLASS::GET_FLOAT(unsigned char *data, int pos)
+{
+int a = data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24);
+float f = *(float *)&a;
+return f;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { nPoints=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rotation=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { distance=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { alpha=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rotationinc=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { distance2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { alpha2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rotationinc2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rgb=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { speed=GET_FLOAT(data, pos); pos+=4; }
+ a=(float)rotation/255*(float)PI*2;
+ status=(float)PI;
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(nPoints); pos+=4;
+ PUT_INT(rotation); pos+=4;
+ PUT_INT(distance); pos+=4;
+ PUT_INT(alpha); pos+=4;
+ PUT_INT(rotationinc); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(distance2); pos+=4;
+ PUT_INT(alpha2); pos+=4;
+ PUT_INT(rotationinc2); pos+=4;
+ PUT_INT(rgb); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_FLOAT(speed, data, pos); pos+=4;
+
+ return pos;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+#define MAX_POINTS 8
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int pnts=nPoints;
+ int x,y;
+ int i;
+ int mask=0;
+ float s;
+
+ if (isBeat&0x80000000) return 0;
+ if (!enabled) return 0;
+ if (pnts == 0) return 0;
+
+ float angle=(float)(2*PI)/pnts;
+
+ if (onbeat && isBeat)
+ if (status >= PI)
+ status=0;
+
+ s = (float)sin(status);
+ _rotationinc = rotationinc + (int)((float)(rotationinc2-rotationinc) * s);
+ _alpha = alpha + (int)((float)(alpha2-alpha) * s);
+ _distance = distance + (int)((float)(distance2-distance) * s);
+
+ a=(float)rotation/255*(float)PI*2;
+
+ int xpoints[MAX_POINTS],ypoints[MAX_POINTS];
+
+ int minx=0, maxx=0;
+ int miny=0, maxy=0;
+
+ for (i=0;i<pnts;i++)
+ {
+ xpoints[i] = (int)(cos(a)*_distance);
+ ypoints[i] = (int)(sin(a)*_distance);
+ if (ypoints[i] > miny) miny=ypoints[i];
+ if (-ypoints[i] > maxy) maxy=-ypoints[i];
+ if (xpoints[i] > minx) minx=xpoints[i];
+ if (-xpoints[i] > maxx) maxx=-xpoints[i];
+ a += angle;
+ }
+
+ unsigned char *bt=g_blendtable[_alpha];
+
+ int *outp=fbout;
+ for (y = 0; y < h; y ++)
+ {
+ int yp=ypoints[i];
+ int yoffs[MAX_POINTS];
+ for (i = 0; i < pnts; i ++)
+ {
+ if (y >= ypoints[i] && y-ypoints[i] < h)
+ yoffs[i]=(y-ypoints[i])*w;
+ else yoffs[i]=-1;
+ }
+ if (rgb && (pnts==3 || pnts==6))
+ {
+ if (pnts == 3) for (x = 0; x < w; x ++)
+ {
+ int r=0,g=0,b=0;
+ int xp;
+ xp=x-xpoints[0];
+ if (xp >= 0 && xp < w && yoffs[0]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[0]];
+ r=bt[pix&0xff];
+ }
+ xp=x-xpoints[1];
+ if (xp >= 0 && xp < w && yoffs[1]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[1]];
+ g=bt[(pix>>8)&0xff];
+ }
+ xp=x-xpoints[2];
+ if (xp >= 0 && xp < w && yoffs[2]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[2]];
+ b=bt[(pix>>16)&0xff];
+ }
+ *outp++ = r|(g<<8)|(b<<16);
+ }
+ else for (x = 0; x < w; x ++)
+ {
+ int r=0,g=0,b=0;
+ int xp;
+ xp=x-xpoints[0];
+ if (xp >= 0 && xp < w && yoffs[0]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[0]];
+ r=bt[pix&0xff];
+ }
+ xp=x-xpoints[1];
+ if (xp >= 0 && xp < w && yoffs[1]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[1]];
+ g=bt[(pix>>8)&0xff];
+ }
+ xp=x-xpoints[2];
+ if (xp >= 0 && xp < w && yoffs[2]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[2]];
+ b=bt[(pix>>16)&0xff];
+ }
+ xp=x-xpoints[3];
+ if (xp >= 0 && xp < w && yoffs[3]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[3]];
+ r+=bt[pix&0xff];
+ }
+ xp=x-xpoints[4];
+ if (xp >= 0 && xp < w && yoffs[4]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[4]];
+ g+=bt[(pix>>8)&0xff];
+ }
+ xp=x-xpoints[5];
+ if (xp >= 0 && xp < w && yoffs[5]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[5]];
+ b+=bt[(pix>>16)&0xff];
+ }
+ if (r > 255) r=255;
+ if (g > 255) g=255;
+ if (b > 255) b=255;
+ *outp++ = r|(g<<8)|(b<<16);
+ }
+ }
+ else if (y > miny && y < h-maxy && minx+maxx < w) // no y clipping required
+ {
+ for (x = 0; x < minx; x ++)
+ {
+ int r=0,g=0,b=0;
+ for (i = 0; i < pnts; i++)
+ {
+ int xp=x-xpoints[i];
+ if (xp >= 0 && xp < w)
+ {
+ int pix=framebuffer[xp+yoffs[i]];
+ r+=bt[pix&0xff];
+ g+=bt[(pix>>8)&0xff];
+ b+=bt[(pix>>16)&0xff];
+ }
+ }
+ if (r > 255) r=255;
+ if (g > 255) g=255;
+ if (b > 255) b=255;
+ *outp++ = r|(g<<8)|(b<<16);
+ }
+ int *lfb=framebuffer+x;
+ for (; x < w-maxx; x ++)
+ {
+ int r=0,g=0,b=0;
+ for (i = 0; i < pnts; i++)
+ {
+ int pix=lfb[yoffs[i]-xpoints[i]];
+ r+=bt[pix&0xff];
+ g+=bt[(pix>>8)&0xff];
+ b+=bt[(pix>>16)&0xff];
+ }
+ if (r > 255) r=255;
+ if (g > 255) g=255;
+ if (b > 255) b=255;
+ lfb++;
+ *outp++ = r|(g<<8)|(b<<16);
+ }
+ for (; x < w; x ++)
+ {
+ int r=0,g=0,b=0;
+ for (i = 0; i < pnts; i++)
+ {
+ int xp=x-xpoints[i];
+ if (xp >= 0 && xp < w)
+ {
+ int pix=framebuffer[xp+yoffs[i]];
+ r+=bt[pix&0xff];
+ g+=bt[(pix>>8)&0xff];
+ b+=bt[(pix>>16)&0xff];
+ }
+ }
+ if (r > 255) r=255;
+ if (g > 255) g=255;
+ if (b > 255) b=255;
+ *outp++ = r|(g<<8)|(b<<16);
+ }
+ }
+ else for (x = 0; x < w; x ++)
+ {
+ int r=0,g=0,b=0;
+ for (i = 0; i < pnts; i++)
+ {
+ int xp=x-xpoints[i];
+ if (xp >= 0 && xp < w && yoffs[i]!=-1)
+ {
+ int pix=framebuffer[xp+yoffs[i]];
+ r+=bt[pix&0xff];
+ g+=bt[(pix>>8)&0xff];
+ b+=bt[(pix>>16)&0xff];
+ }
+ }
+ if (r > 255) r=255;
+ if (g > 255) g=255;
+ if (b > 255) b=255;
+ *outp++ = r|(g<<8)|(b<<16);
+ }
+ }
+
+
+
+
+
+ rotation+=_rotationinc;
+ rotation=rotation>255 ? rotation-255 : rotation;
+ rotation=rotation<-255 ? rotation+255 : rotation;
+
+ status += speed;
+ status=min(status, (float)PI);
+ if (status<-PI) status = (float) PI;
+
+ int *p = framebuffer;
+ int *d = fbout;
+
+ if (!blend && !blendavg) return 1;
+ if (blendavg)
+ {
+ int i=w*h/4;
+ while (i--)
+ {
+ p[0] = BLEND_AVG(p[0], d[0]);
+ p[1] = BLEND_AVG(p[1], d[1]);
+ p[2] = BLEND_AVG(p[2], d[2]);
+ p[3] = BLEND_AVG(p[3], d[3]);
+ p+=4;
+ d+=4;
+ }
+ }
+ else
+ mmx_addblend_block(p,d,w*h);
+
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_NPOINTS, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_NPOINTS, TBM_SETRANGE, TRUE, MAKELONG(0, 8));
+ SendDlgItemMessage(hwndDlg, IDC_NPOINTS, TBM_SETPOS, TRUE, g_ConfigThis->nPoints);
+ SendDlgItemMessage(hwndDlg, IDC_ALPHA, TBM_SETTICFREQ, 16, 0);
+ SendDlgItemMessage(hwndDlg, IDC_ALPHA, TBM_SETRANGE, TRUE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_ALPHA, TBM_SETPOS, TRUE, g_ConfigThis->alpha);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETTICFREQ, 8, 0);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETRANGE, TRUE, MAKELONG(1, 64));
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_SETPOS, TRUE, g_ConfigThis->distance);
+ SendDlgItemMessage(hwndDlg, IDC_ROTATE, TBM_SETTICFREQ, 2, 0);
+ SendDlgItemMessage(hwndDlg, IDC_ROTATE, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_ROTATE, TBM_SETPOS, TRUE, g_ConfigThis->rotationinc*-1+32);
+ SendDlgItemMessage(hwndDlg, IDC_ALPHA2, TBM_SETTICFREQ, 16, 0);
+ SendDlgItemMessage(hwndDlg, IDC_ALPHA2, TBM_SETRANGE, TRUE, MAKELONG(1, 255));
+ SendDlgItemMessage(hwndDlg, IDC_ALPHA2, TBM_SETPOS, TRUE, g_ConfigThis->alpha2);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE2, TBM_SETTICFREQ, 8, 0);
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE2, TBM_SETRANGE, TRUE, MAKELONG(1, 64));
+ SendDlgItemMessage(hwndDlg, IDC_DISTANCE2, TBM_SETPOS, TRUE, g_ConfigThis->distance2);
+ SendDlgItemMessage(hwndDlg, IDC_ROTATE2, TBM_SETTICFREQ, 2, 0);
+ SendDlgItemMessage(hwndDlg, IDC_ROTATE2, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_ROTATE2, TBM_SETPOS, TRUE, g_ConfigThis->rotationinc2*-1+32);
+ SendDlgItemMessage(hwndDlg, IDC_INITROT, TBM_SETTICFREQ, 16, 0);
+ SendDlgItemMessage(hwndDlg, IDC_INITROT, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
+ SendDlgItemMessage(hwndDlg, IDC_INITROT, TBM_SETPOS, TRUE, 255-g_ConfigThis->rotation);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETTICFREQ, 1000, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1, 128));
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(g_ConfigThis->speed*100));
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RGB), (g_ConfigThis->nPoints == 3 || g_ConfigThis->nPoints==6));
+ CheckDlgButton(hwndDlg,IDC_RGB,g_ConfigThis->rgb ? BST_CHECKED: BST_UNCHECKED);
+ CheckDlgButton(hwndDlg,IDC_ONBEAT,g_ConfigThis->onbeat ? BST_CHECKED: BST_UNCHECKED);
+ return 1;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_RGB) ||
+ (LOWORD(wParam) == IDC_ONBEAT) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->rgb=IsDlgButtonChecked(hwndDlg,IDC_RGB)?1:0;
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT)?1:0;
+ }
+ return 0;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_NPOINTS)
+ {
+ g_ConfigThis->nPoints = SendDlgItemMessage(hwndDlg, IDC_NPOINTS, TBM_GETPOS, 0, 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_RGB), (g_ConfigThis->nPoints == 3 || g_ConfigThis->nPoints==6));
+ }
+ if (LOWORD(wParam) == IDC_ALPHA)
+ g_ConfigThis->alpha = SendDlgItemMessage(hwndDlg, IDC_ALPHA, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_DISTANCE)
+ g_ConfigThis->distance = SendDlgItemMessage(hwndDlg, IDC_DISTANCE, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_ROTATE)
+ g_ConfigThis->rotationinc= -1*(SendDlgItemMessage(hwndDlg, IDC_ROTATE, TBM_GETPOS, 0, 0)-32);
+ if (LOWORD(wParam) == IDC_INITROT)
+ g_ConfigThis->rotation = 255-SendDlgItemMessage(hwndDlg, IDC_INITROT, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_SPEED)
+ g_ConfigThis->speed = (float)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)/100;
+ if (LOWORD(wParam) == IDC_ALPHA2)
+ g_ConfigThis->alpha2 = SendDlgItemMessage(hwndDlg, IDC_ALPHA2, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_DISTANCE2)
+ g_ConfigThis->distance2 = SendDlgItemMessage(hwndDlg, IDC_DISTANCE2, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_ROTATE2)
+ g_ConfigThis->rotationinc2= -1*(SendDlgItemMessage(hwndDlg, IDC_ROTATE2, TBM_GETPOS, 0, 0)-32);
+ return 0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_INTERF,hwndParent,g_DlgProc);
+}
+
+// export stuff
+
+C_RBASE *R_Interferences(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+
+#else
+C_RBASE *R_Interferences(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_interleave.cpp b/Src/Plugins/Visualization/vis_avs/r_interleave.cpp
new file mode 100644
index 00000000..62b1ae19
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_interleave.cpp
@@ -0,0 +1,381 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Interleave"
+#define C_THISCLASS C_InterleaveClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_INTERLEAVE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int x, y;
+ int enabled;
+ int color;
+ int blend;
+ int blendavg;
+ int onbeat, x2,y2,beatdur;
+ double cur_x,cur_y;
+};
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS() // set up default configuration
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ onbeat=0;
+ beatdur=4;
+
+ color = 0;
+ x2=x=1;
+ y2=y=1;
+ cur_x=cur_y=1.0;
+ enabled=1;
+ blend=0;
+ blendavg=0;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { x=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { y=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { x2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { y2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatdur=GET_INT(); pos+=4; }
+ cur_x=x;
+ cur_y=y;
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(x); pos+=4;
+ PUT_INT(y); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_INT(x2); pos+=4;
+ PUT_INT(y2); pos+=4;
+ PUT_INT(beatdur); pos+=4;
+ return pos;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+ if (!enabled) return 0;
+ int ystat=0;
+ int yp=0;
+
+ double sc1=(beatdur+512.0-64.0)/512.0;
+ cur_x=(cur_x*sc1+x*(1.0-sc1));
+ cur_y=(cur_y*sc1+y*(1.0-sc1));
+
+ if (isBeat && onbeat)
+ {
+ cur_x=x2;
+ cur_y=y2;
+ }
+ int tx=(int)cur_x;
+ int ty=(int)cur_y;
+ int xos=0;
+
+ int *p=framebuffer;
+ int j;
+ if (!ty)
+ {
+ ystat=1;
+ }
+ if (tx > 0)
+ {
+ xos=(w%tx)/2;
+ }
+ if (ty > 0) yp=(h%ty)/2;
+ if (tx>=0 && ty >=0) for (j=0;j<h;j++)
+ {
+ int xstat=0;
+ if (ty && ++yp>=ty)
+ {
+ ystat=!ystat;
+ yp=0;
+ }
+ int l=w;
+
+ if (!ystat) // this line is pure color
+ {
+ if (blend)
+ {
+ while (l--)
+ {
+ *p=BLEND(*p, color);
+ p++;
+ }
+ }
+ else if (blendavg)
+ {
+ while (l--)
+ {
+ *p=BLEND_AVG(*p, color);
+ p++;
+ }
+ }
+ else
+ {
+ while (l--)
+ {
+ *p++=color;
+ }
+ }
+ }
+ else if (tx)
+ {
+ if (blend)
+ {
+ int xo=xos;
+ while (l>0)
+ {
+ int l2=min(l,tx-xo);
+ xo=0;
+ l-=l2;
+ if (xstat) p+=l2;
+ else while (l2--) { *p=BLEND(*p,color); p++; }
+ xstat=!xstat;
+ }
+ }
+ else if (blendavg)
+ {
+ int xo=xos;
+ while (l>0)
+ {
+ int l2=min(l,tx-xo);
+ xo=0;
+ l-=l2;
+ if (xstat) p+=l2;
+ else while (l2--) { *p=BLEND_AVG(*p,color); p++; }
+ xstat=!xstat;
+ }
+ }
+ else
+ {
+ int xo=xos;
+ while (l>0)
+ {
+ int l2=min(l,tx-xo);
+ xo=0;
+ l-=l2;
+ if (xstat) p+=l2;
+ else while (l2--) { *p++=color; }
+ xstat=!xstat;
+ }
+ }
+ }
+ else p+=w;
+ }
+
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_X, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_X, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_X, TBM_SETPOS, TRUE, g_ConfigThis->x);
+ SendDlgItemMessage(hwndDlg, IDC_Y, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_Y, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_Y, TBM_SETPOS, TRUE, g_ConfigThis->y);
+ SendDlgItemMessage(hwndDlg, IDC_X2, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_X2, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_X2, TBM_SETPOS, TRUE, g_ConfigThis->x2);
+ SendDlgItemMessage(hwndDlg, IDC_Y2, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_Y2, TBM_SETRANGE, TRUE, MAKELONG(0, 64));
+ SendDlgItemMessage(hwndDlg, IDC_Y2, TBM_SETPOS, TRUE, g_ConfigThis->y2);
+ SendDlgItemMessage(hwndDlg, IDC_X3, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_X3, TBM_SETRANGE, TRUE, MAKELONG(1, 64));
+ SendDlgItemMessage(hwndDlg, IDC_X3, TBM_SETPOS, TRUE, g_ConfigThis->beatdur);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->onbeat) CheckDlgButton(hwndDlg,IDC_CHECK8,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_X))
+ {
+ g_ConfigThis->cur_x=(double)(g_ConfigThis->x = t);
+ }
+ else if (swnd == GetDlgItem(hwndDlg,IDC_Y))
+ {
+ g_ConfigThis->cur_y=(double)(g_ConfigThis->y = t);
+ }
+ else if (swnd == GetDlgItem(hwndDlg,IDC_X2))
+ {
+ g_ConfigThis->cur_x=(double)(g_ConfigThis->x2 = t);
+ }
+ else if (swnd == GetDlgItem(hwndDlg,IDC_Y2))
+ {
+ g_ConfigThis->cur_y=(double)(g_ConfigThis->y2 = t);
+ }
+ else if (swnd == GetDlgItem(hwndDlg,IDC_X3))
+ {
+ g_ConfigThis->beatdur=t;
+ }
+ }
+ return 0;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL) // paint nifty color button
+ {
+ int w=di->rcItem.right-di->rcItem.left;
+ int _color=g_ConfigThis->color;
+ _color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_CHECK8) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_CHECK8)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
+ {
+ int *a=&(g_ConfigThis->color);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ g_ConfigThis->color = *a;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_INTERLEAVE,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Interleave(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Interleave(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_invert.cpp b/Src/Plugins/Visualization/vis_avs/r_invert.cpp
new file mode 100644
index 00000000..50520b4b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_invert.cpp
@@ -0,0 +1,186 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Invert"
+#define C_THISCLASS C_InvertClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_INVERT,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int enabled;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ enabled=1;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ return pos;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int i=w*h;
+ int *p=framebuffer;
+
+ if (isBeat&0x80000000) return 0;
+ if (!enabled) return 0;
+
+#ifndef NO_MMX
+ int a[2]={0xffffff,0xffffff};
+ __asm
+ {
+ mov ecx, i
+ shr ecx, 3
+ movq mm0, [a]
+ mov edi, p
+ align 16
+_mmx_invert_loop:
+ movq mm1, [edi]
+ movq mm2, [edi+8]
+ pxor mm1, mm0
+ movq mm3, [edi+16]
+ pxor mm2, mm0
+ movq mm4, [edi+24]
+ pxor mm3, mm0
+ movq [edi], mm1
+ pxor mm4, mm0
+ movq [edi+8], mm2
+ movq [edi+16], mm3
+ movq [edi+24], mm4
+ add edi, 32
+ dec ecx
+ jnz _mmx_invert_loop
+ mov ecx, i
+ shr ecx, 1
+ and ecx, 3
+ jz _mmx_invert_noendloop
+_mmx_invert_endloop:
+ movq mm1, [edi]
+ pxor mm1, mm0
+ movq [edi], mm1
+ add edi, 8
+ dec ecx
+ jnz _mmx_invert_endloop
+
+_mmx_invert_noendloop:
+ emms
+ }
+#else
+ while (i--) *p++ = 0xFFFFFF^*p;
+#endif
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_CHECK1)
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_INVERT,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Invert(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Invert(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_linemode.cpp b/Src/Plugins/Visualization/vis_avs/r_linemode.cpp
new file mode 100644
index 00000000..370c1922
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_linemode.cpp
@@ -0,0 +1,190 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+int g_line_blend_mode;
+
+static int line_blendmodes[]=
+{
+ IDS_REPLACE,
+ IDS_ADDITIVE,
+ IDS_MAXIMUM_BLEND,
+ IDS_50_50_BLEND,
+ IDS_SUBTRACTIVE_BLEND_1,
+ IDS_SUBTRACTIVE_BLEND_2,
+ IDS_MULTIPLY_BLEND,
+ IDS_ADJUSTABLE_BLEND,
+ IDS_XOR,
+ IDS_MINIMUM_BLEND,
+};
+
+#define C_THISCLASS C_LineModeClass
+#define MOD_NAME "Misc / Set render mode"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_MISC_SET_RENDER_MODE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int newmode;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { newmode=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(newmode); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ newmode=0x80010000;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+ if (newmode&0x80000000)
+ {
+ g_line_blend_mode=newmode&0x7fffffff;
+ }
+ return 0;
+}
+
+C_RBASE *R_LineMode(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int x;
+ for (x = 0; x<sizeof(line_blendmodes)/sizeof(line_blendmodes[0]); x ++)
+ {
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRING(line_blendmodes[x]));
+ }
+ }
+ if (g_this->newmode&0x80000000)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_ALPHASLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
+ SendDlgItemMessage(hwndDlg, IDC_ALPHASLIDE, TBM_SETPOS, TRUE, (int)(g_this->newmode>>8)&0xff);
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,(WPARAM)g_this->newmode&0xff,0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), (g_this->newmode&0xff) == 7);
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,(g_this->newmode>>16)&0xff,FALSE);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_EDIT1:
+ {
+ int r,t;
+ r=GetDlgItemInt(hwndDlg,IDC_EDIT1,&t,FALSE);
+ if (t)
+ {
+ g_this->newmode&=~0xff0000;
+ g_this->newmode|=(r&0xff)<<16;
+ }
+ }
+ break;
+ case IDC_CHECK1:
+ g_this->newmode&=0x7fffffff;
+ g_this->newmode|=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?0x80000000:0;
+ break;
+ case IDC_COMBO1:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int r=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (r!=CB_ERR)
+ {
+ g_this->newmode&=~0xff;
+ g_this->newmode|=r;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), r == 7);
+ }
+ }
+ break;
+ }
+ return 0;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_ALPHASLIDE)
+ {
+ g_this->newmode &= ~0xff00;
+ g_this->newmode |= (SendDlgItemMessage(hwndDlg, IDC_ALPHASLIDE, TBM_GETPOS, 0, 0)&0xff)<<8;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_LINEMODE,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_LineMode(char *desc)
+{
+ return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_list.cpp b/Src/Plugins/Visualization/vis_avs/r_list.cpp
new file mode 100644
index 00000000..d0ee55a6
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_list.cpp
@@ -0,0 +1,1401 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdio.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "r_unkn.h"
+#include "r_list.h"
+#include "render.h"
+#include "undo.h"
+
+#include "avs_eelif.h"
+#include "../Agave/Language/api_language.h"
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+char *C_RenderListClass::get_desc() { static char desc[128]; return WASABI_API_LNGSTRING_BUF(isroot?IDS_MAIN:IDS_EFFECT_LIST,desc,128); }
+
+int g_config_seh=1;
+extern int g_config_smp_mt,g_config_smp;
+
+static char extsigstr[]="AVS 2.8+ Effect List Config";
+
+void C_RenderListClass::load_config_code(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4)
+ {
+ use_code=GET_INT(); pos+=4;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ }
+
+}
+
+void C_RenderListClass::load_config(unsigned char *data, int len)
+{
+ int pos=0,ext;
+ if (pos<len) { mode=data[pos++]; }
+ if (mode&0x80)
+ {
+ mode&=~0x80;
+ mode=mode|GET_INT(); pos+=4;
+ }
+ ext = get_extended_datasize()+5;
+ if (ext > 5)
+ {
+ if (pos<ext) { inblendval=GET_INT(); pos+=4; }
+ if (pos<ext) { outblendval=GET_INT(); pos+=4; }
+ if (pos<ext) { bufferin=GET_INT(); pos+=4; }
+ if (pos<ext) { bufferout=GET_INT(); pos+=4; }
+ if (pos<ext) { ininvert=GET_INT(); pos+=4; }
+ if (pos<ext) { outinvert=GET_INT(); pos+=4; }
+ if (pos<ext-4) { beat_render=GET_INT(); pos+=4; } //BU
+ if (pos<ext-4) { beat_render_frames=GET_INT(); pos+=4; }
+ }
+ use_code=0;
+ effect_exp[0].assign("");
+ effect_exp[1].assign("");
+ while (pos < len)
+ {
+ char s[33];
+ T_RenderListType t;
+ int l_len;
+ t.effect_index=GET_INT(); pos+=4;
+ if (t.effect_index >= DLLRENDERBASE)
+ {
+ if (pos+32 > len) break;
+ memcpy(s,data+pos,32);
+ s[32]=0;
+ t.effect_index=(int)s;
+ pos+=32;
+ }
+ if (pos+4 > len) break;
+ l_len=GET_INT(); pos+=4;
+ if (pos+l_len > len || l_len < 0) break;
+
+ if (ext>5 && t.effect_index >= DLLRENDERBASE && !memcmp(s,extsigstr,strlen(extsigstr)+1))
+ {
+ load_config_code(data+pos,l_len);
+ }
+ else
+ {
+ t.render=g_render_library->CreateRenderer(&t.effect_index,&t.has_rbase2);
+ if (t.render)
+ {
+ t.render->load_config(data+pos,l_len);
+ insertRender(&t,-1);
+ }
+ }
+ pos+=l_len;
+ }
+}
+
+int C_RenderListClass::save_config_code(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(use_code); pos+=4;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ return pos;
+}
+
+int C_RenderListClass::save_config(unsigned char *data)
+{
+ return save_config_ex(data,0);
+}
+int C_RenderListClass::save_config_ex(unsigned char *data, int rootsave)
+{
+ int pos=0;
+ int x;
+ if (!rootsave)
+ {
+ set_extended_datasize(36); // size of extended data + 4 cause we fucked up
+ data[pos++]=(mode&0xff)|0x80;
+ PUT_INT(mode); pos+=4;
+ // extended_data
+ PUT_INT(inblendval); pos+=4;
+ PUT_INT(outblendval); pos+=4;
+ PUT_INT(bufferin); pos+=4;
+ PUT_INT(bufferout); pos+=4;
+ PUT_INT(ininvert); pos+=4;
+ PUT_INT(outinvert); pos+=4;
+ PUT_INT(beat_render); pos+=4;
+ PUT_INT(beat_render_frames); pos+=4;
+ // end extended data
+ }
+ else data[pos++] = mode;
+
+ if (!rootsave)
+ {
+ // write in our ext field
+ PUT_INT(DLLRENDERBASE); pos+=4;
+ char s[33];
+ strncpy(s,extsigstr,32);
+ memcpy(data+pos,s,32);
+ pos+=32;
+ int t=save_config_code(data+pos+4);
+ PUT_INT(t);
+ pos+=4+t;
+ }
+
+
+ for (x = 0; x < num_renders; x ++)
+ {
+ int t;
+ int idx=renders[x].effect_index;
+ if (idx==UNKN_ID)
+ {
+ C_UnknClass *r=(C_UnknClass *)renders[x].render;
+ if (!r->idString[0]) { PUT_INT(r->id); pos+=4; }
+ else
+ {
+ PUT_INT(r->id); pos+=4;
+ memcpy(data+pos,r->idString,32);
+ pos+=32;
+ }
+ }
+ else
+ {
+ PUT_INT(idx); pos+=4;
+ if (idx >= DLLRENDERBASE)
+ {
+ char s[33];
+ strncpy(s,(char*)idx,32);
+ memcpy(data+pos,s,32);
+ pos+=32;
+ }
+ }
+
+ t=renders[x].render->save_config(data+pos+4);
+ PUT_INT(t);
+ pos+=4+t;
+ }
+
+
+
+ return pos;
+}
+
+
+C_RenderListClass::C_RenderListClass(int iroot)
+{
+ AVS_EEL_INITINST();
+ isstart=0;
+#ifndef LASER
+ nsaved=0;
+ memset(nbw_save,0,sizeof(nbw_save));
+ memset(nbw_save2,0,sizeof(nbw_save2));
+ memset(nbh_save,0,sizeof(nbh_save));
+ memset(nbh_save2,0,sizeof(nbh_save2));
+ memset(nb_save,0,sizeof(nb_save));
+ memset(nb_save2,0,sizeof(nb_save2));
+#endif
+ inblendval=128;
+ outblendval=128;
+ ininvert=0;
+
+ InitializeCriticalSection(&rcs);
+ use_code=0;
+ inited=0;
+ need_recompile=1;
+ memset(codehandle,0,sizeof(codehandle));
+ var_beat=0;
+
+
+ effect_exp[0].assign("");
+ effect_exp[1].assign("");
+ outinvert=0;
+ bufferin=0;
+ bufferout=0;
+ isroot=iroot;
+ num_renders=0;
+ num_renders_alloc=0;
+ renders=NULL;
+ thisfb=NULL;
+ l_w=l_h=0;
+ mode=0;
+ beat_render = 0;
+ beat_render_frames = 1;
+ fake_enabled = 0;
+#ifdef LASER
+ if (!iroot) line_save=createLineList();
+ else line_save=NULL;
+#endif
+}
+
+extern int g_n_buffers_w[NBUF],g_n_buffers_h[NBUF];
+extern void *g_n_buffers[NBUF];
+
+#ifndef LASER
+void C_RenderListClass::set_n_Context()
+{
+ if (!isroot) return;
+ if (nsaved) return;
+ nsaved=1;
+ memcpy(nbw_save2,g_n_buffers_w,sizeof(nbw_save2));
+ memcpy(nbh_save2,g_n_buffers_h,sizeof(nbh_save2));
+ memcpy(nb_save2,g_n_buffers,sizeof(nb_save2));
+
+ memcpy(g_n_buffers_w,nbw_save,sizeof(nbw_save));
+ memcpy(g_n_buffers_h,nbh_save,sizeof(nbh_save));
+ memcpy(g_n_buffers,nb_save,sizeof(nb_save));
+}
+
+void C_RenderListClass::unset_n_Context()
+{
+ if (!isroot) return;
+ if (!nsaved) return;
+ nsaved=0;
+
+ memcpy(nbw_save,g_n_buffers_w,sizeof(nbw_save));
+ memcpy(nbh_save,g_n_buffers_h,sizeof(nbh_save));
+ memcpy(nb_save,g_n_buffers,sizeof(nb_save));
+
+ memcpy(g_n_buffers_w,nbw_save2,sizeof(nbw_save2));
+ memcpy(g_n_buffers_h,nbh_save2,sizeof(nbh_save2));
+ memcpy(g_n_buffers,nb_save2,sizeof(nb_save2));
+
+}
+#endif
+
+void C_RenderListClass::smp_cleanupthreads()
+{
+
+ if (smp_parms.threadTop>0)
+ {
+ if (smp_parms.hQuitHandle) SetEvent(smp_parms.hQuitHandle);
+
+ WaitForMultipleObjects(smp_parms.threadTop,smp_parms.hThreads,TRUE,INFINITE);
+ int x;
+ for (x = 0; x < smp_parms.threadTop; x ++)
+ {
+ CloseHandle(smp_parms.hThreads[x]);
+ CloseHandle(smp_parms.hThreadSignalsDone[x]);
+ CloseHandle(smp_parms.hThreadSignalsStart[x]);
+ }
+ }
+
+ if (smp_parms.hQuitHandle) CloseHandle(smp_parms.hQuitHandle);
+
+ memset(&smp_parms,0,sizeof(smp_parms));
+}
+
+void C_RenderListClass::freeBuffers()
+{
+#ifndef LASER
+ if (isroot)
+ {
+ int x;
+ for (x = 0; x < NBUF; x ++)
+ {
+ if (nb_save[x]) GlobalFree(nb_save[x]);
+ nb_save[x]=NULL;
+ nbw_save[x]=nbh_save[x]=0;
+ }
+ }
+#endif
+}
+
+C_RenderListClass::~C_RenderListClass()
+{
+#ifdef LASER
+ if (line_save) delete line_save;
+#endif
+ clearRenders();
+
+ // free nb_save
+ freeBuffers();
+
+ int x;
+ for (x = 0; x < 2; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=0;
+ }
+ AVS_EEL_QUITINST();
+ DeleteCriticalSection(&rcs);
+}
+
+static int __inline depthof(int c, int i)
+{
+ int r= max(max((c & 0xFF), ((c & 0xFF00)>>8)), (c & 0xFF0000)>>16);
+ return i ? 255 - r : r;
+}
+
+
+
+int C_RenderListClass::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int is_preinit = (isBeat&0x80000000);
+
+ if (isBeat && beat_render)
+ fake_enabled = beat_render_frames;
+
+ int use_enabled=enabled();
+ int use_inblendval = inblendval;
+ int use_outblendval = outblendval;
+ int use_clear=clearfb();
+
+ if (!isroot && use_code)
+ {
+ if (need_recompile)
+ {
+ EnterCriticalSection(&rcs);
+
+ if (!var_beat || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_beat = registerVar("beat");
+ var_alphain = registerVar("alphain");
+ var_alphaout = registerVar("alphaout");
+ var_enabled = registerVar("enabled");
+ var_clear = registerVar("clear");
+ var_w = registerVar("w");
+ var_h = registerVar("h");
+ inited=0;
+ }
+
+ need_recompile=0;
+ int x;
+ for (x = 0; x < 2; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=compileCode(effect_exp[x].get());
+ }
+
+ LeaveCriticalSection(&rcs);
+ }
+
+ *var_beat = ((isBeat&1) && !is_preinit) ?1.0:0.0;
+ *var_enabled=use_enabled ? 1.0:0.0;
+ *var_w=(double)w;
+ *var_h=(double)h;
+ *var_clear=use_clear ? 1.0:0.0;
+ *var_alphain=use_inblendval/255.0;
+ *var_alphaout=use_outblendval/255.0;
+ if (codehandle[0] && !inited) { executeCode(codehandle[0],visdata); inited=1; }
+ executeCode(codehandle[1],visdata);
+
+ if (!is_preinit)
+ {
+ isBeat = *var_beat > 0.1 || *var_beat < -0.1;
+ }
+ use_inblendval = (int) (*var_alphain * 255.0);
+ if (use_inblendval < 0) use_inblendval=0;
+ else if (use_inblendval>255) use_inblendval=255;
+ use_outblendval = (int) (*var_alphaout * 255.0);
+ if (use_outblendval < 0) use_outblendval=0;
+ else if (use_outblendval>255) use_outblendval=255;
+
+ use_enabled = *var_enabled > 0.1 || *var_enabled < -0.1;
+ use_clear = *var_clear > 0.1 || *var_clear < -0.1;
+
+ // code execute
+ }
+
+#ifndef LASER
+ // root/replaceinout special cases
+ if (isroot || (use_enabled && blendin()==1 && blendout()==1))
+#endif
+ {
+ int s=0,x;
+#ifndef LASER
+ int line_blend_mode_save=g_line_blend_mode;
+ if (thisfb) GlobalFree((HGLOBAL)thisfb);
+ thisfb=NULL;
+ if (use_clear&&(isroot||blendin()!=1))
+ memset(framebuffer,0,w*h*sizeof(int));
+ if (!is_preinit)
+ {
+ g_line_blend_mode=0;
+ set_n_Context();
+ }
+#else
+ if (isroot || use_enabled)
+ {
+ void LineListSwap(C_LineListBase *item1, C_LineListBase *item2);
+ if (!isroot)
+ {
+ line_save->ClearLineList();
+ LineListSwap(line_save,g_laser_linelist);
+ }
+#endif
+ for (x = 0; x < num_renders; x ++)
+ {
+ int t=0;
+ int smp_max_threads = g_config_smp ? g_config_smp_mt : 0;
+ C_RBASE2 *rb2 = (C_RBASE2*)renders[x].render;
+
+ if (renders[x].has_rbase2 && smp_max_threads > 1 && (rb2->smp_getflags()&1))
+ {
+ if (smp_max_threads>MAX_SMP_THREADS) smp_max_threads=MAX_SMP_THREADS;
+
+ int nt=smp_max_threads;
+ nt=rb2->smp_begin(nt,visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+ if (!is_preinit && nt>0)
+ {
+ if (nt>smp_max_threads)nt=smp_max_threads;
+
+ // launch threads
+ smp_Render(nt,rb2,visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+
+
+ t=rb2->smp_finish(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+ }
+
+ }
+ else
+ {
+ if (g_config_seh && renders[x].effect_index != LIST_ID)
+ {
+ __try
+ {
+ t=renders[x].render->render(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ t=0;
+ }
+ }
+ else
+ {
+ t=renders[x].render->render(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+ }
+ }
+
+
+ if (t&1) s^=1;
+ if (!is_preinit)
+ {
+ if (t&0x10000000) isBeat=1;
+ if (t&0x20000000) isBeat=0;
+ }
+ }
+#ifdef LASER
+ if (!isroot)
+ {
+ LineListSwap(line_save,g_laser_linelist);
+ int us=g_laser_linelist->GetUsedLines();
+ int n=g_laser_linelist->GetMaxLines()-us;
+ if (line_save->GetUsedLines() < n) n=line_save->GetUsedLines();
+ g_laser_linelist->SetLines(line_save->GetLineList(),us,n);
+ g_laser_linelist->SetUsedLines(us+n);
+ }
+ }
+#else
+ if (!is_preinit)
+ {
+ g_line_blend_mode=line_blend_mode_save;
+ unset_n_Context();
+ }
+#endif
+ fake_enabled--;
+ return s;
+ }
+
+#ifndef LASER
+ // check to see if we're enabled
+ if (!use_enabled)
+ {
+ if (thisfb) GlobalFree((HGLOBAL)thisfb);
+ thisfb=NULL;
+ return 0;
+ }
+
+ fake_enabled--;
+
+
+ // handle resize
+ if (l_w != w || l_h != h || !thisfb)
+ {
+ extern int config_reuseonresize;
+ int do_resize=config_reuseonresize && !!thisfb && l_w && l_h && !use_clear;
+
+ int *newfb=(int*)GlobalAlloc(do_resize?GMEM_FIXED:GPTR,w*h*sizeof(int));
+ if (newfb && do_resize)
+ {
+ int x,y;
+ int dxpos=(l_w<<16)/w;
+ int ypos=0;
+ int dypos=(l_h<<16)/h;
+ int *out=newfb;
+ for (y = 0; y < h; y++)
+ {
+ int *p=thisfb + l_w * (ypos>>16);
+ int xpos=0;
+ for (x = 0; x < w; x ++)
+ {
+ *out++=p[xpos>>16];
+ xpos+=dxpos;
+ }
+ ypos+=dypos;
+ }
+ }
+ l_w=w;
+ l_h=h;
+ if (thisfb) GlobalFree((HGLOBAL)thisfb);
+ thisfb=newfb;
+ }
+ // handle clear mode
+ if (use_clear) memset(thisfb,0,w*h*sizeof(int));
+
+
+ // blend parent framebuffer into current, if necessary
+
+ if (!is_preinit)
+ {
+ int x=w*h;
+ int *tfb=framebuffer;
+ int *o=thisfb;
+ set_n_Context();
+ int use_blendin=blendin();
+ if (use_blendin == 10 && use_inblendval >= 255)
+ use_blendin=1;
+
+ switch (use_blendin)
+ {
+ case 1:
+ memcpy(o,tfb,w*h*sizeof(int));
+ break;
+ case 2:
+ mmx_avgblend_block(o,tfb,x);
+ break;
+ case 3:
+ while (x--)
+ {
+ *o=BLEND_MAX(*o,*tfb++);
+ o++;
+ }
+ break;
+ case 4:
+ mmx_addblend_block(o,tfb,x);
+ break;
+ case 5:
+ while (x--)
+ {
+ *o=BLEND_SUB(*o,*tfb++);
+ o++;
+ }
+ break;
+ case 6:
+ while (x--)
+ {
+ *o=BLEND_SUB(*tfb++,*o);
+ o++;
+ }
+ break;
+ case 7:
+ {
+ int y=h/2;
+ while (y-- > 0)
+ {
+ memcpy(o,tfb,w*sizeof(int));
+ tfb+=w*2;
+ o+=w*2;
+ }
+ }
+ break;
+ case 8:
+ {
+ int r=0;
+ int y=h;
+ while (y-- > 0)
+ {
+ int *out, *in;
+ int x=w/2;
+ out=o+r;
+ in=tfb+r;
+ r^=1;
+ while (x-- > 0)
+ {
+ *out=*in;
+ out+=2;
+ in+=2;
+ }
+ o+=w;
+ tfb+=w;
+ }
+ }
+ break;
+ case 9:
+ while (x--)
+ {
+ *o=*o^*tfb++;
+ o++;
+ }
+ break;
+ case 10:
+ mmx_adjblend_block(o,tfb,o,x,use_inblendval);
+ break;
+ case 11:
+ mmx_mulblend_block(o,tfb,x);
+ break;
+ case 13:
+ while (x--)
+ {
+ *o=BLEND_MIN(*o,*tfb++);
+ o++;
+ }
+ break;
+ case 12:
+ {
+ int *buf=(int*)getGlobalBuffer(w,h,bufferin,0);
+ if (!buf) break;
+ while (x--)
+ {
+ *o=BLEND_ADJ(*tfb++,*o, depthof(*buf, ininvert));
+ o++;
+ buf++;
+ }
+ }
+#ifndef NO_MMX
+ __asm emms;
+#endif
+ break;
+ default:
+ break;
+ }
+ unset_n_Context();
+ }
+
+ int s=0;
+ int x;
+ int line_blend_mode_save=g_line_blend_mode;
+ if (!is_preinit) g_line_blend_mode=0;
+
+ for (x = 0; x < num_renders; x ++)
+ {
+ int t=0;
+
+ int smp_max_threads;
+ C_RBASE2 *rb2;
+
+ if (renders[x].has_rbase2 && (smp_max_threads=g_config_smp ? g_config_smp_mt : 0) > 1 && ((rb2 = (C_RBASE2*)renders[x].render)->smp_getflags()&1))
+ {
+ if (smp_max_threads>MAX_SMP_THREADS) smp_max_threads=MAX_SMP_THREADS;
+
+ int nt=smp_max_threads;
+ nt=rb2->smp_begin(nt,visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+ if (!is_preinit && nt>0)
+ {
+ if (nt>smp_max_threads)nt=smp_max_threads;
+
+ // launch threads
+ smp_Render(nt,rb2,visdata,isBeat,s?fbout:thisfb,s?thisfb:fbout,w,h);
+
+ t=rb2->smp_finish(visdata,isBeat,s?fbout:framebuffer,s?framebuffer:fbout,w,h);
+ }
+
+ }
+ else if (g_config_seh && renders[x].effect_index != LIST_ID)
+ {
+ __try
+ {
+ t=renders[x].render->render(visdata,isBeat,s?fbout:thisfb,s?thisfb:fbout,w,h);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ t=0;
+ }
+ }
+ else
+ {
+ t=renders[x].render->render(visdata,isBeat,s?fbout:thisfb,s?thisfb:fbout,w,h);
+ }
+
+
+ if (t&1) s^=1;
+ if (!is_preinit)
+ {
+ if (t&0x10000000)
+ isBeat=1;
+ if (t&0x20000000)
+ isBeat=0;
+ }
+ }
+ if (!is_preinit) g_line_blend_mode=line_blend_mode_save;
+
+ // if s==1 at this point, data we want is in fbout.
+
+ if (!is_preinit)
+ {
+ if (s) memcpy(thisfb,fbout,w*h*sizeof(int));
+
+ int *tfb=s?fbout:thisfb;
+ int *o=framebuffer;
+ x=w*h;
+ set_n_Context();
+
+ int use_blendout=blendout();
+ if (use_blendout == 10 && use_outblendval >= 255)
+ use_blendout=1;
+ switch (use_blendout)
+ {
+ case 1:
+ if (s)
+ {
+ unset_n_Context();
+ return 1;
+ }
+ memcpy(o,tfb,x*sizeof(int));
+ break;
+ case 2:
+ mmx_avgblend_block(o,tfb,x);
+ break;
+ case 3:
+ while (x--)
+ {
+ *o=BLEND_MAX(*o,*tfb++);
+ o++;
+ }
+ break;
+ case 4:
+ mmx_addblend_block(o,tfb,x);
+ break;
+ case 5:
+ while (x--)
+ {
+ *o=BLEND_SUB(*o,*tfb++);
+ o++;
+ }
+ break;
+ case 6:
+ while (x--)
+ {
+ *o=BLEND_SUB(*tfb++,*o);
+ o++;
+ }
+ break;
+ case 7:
+ {
+ int y=h/2;
+ while (y-- > 0)
+ {
+ memcpy(o,tfb,w*sizeof(int));
+ tfb+=w*2;
+ o+=w*2;
+ }
+ }
+ break;
+ case 8:
+ {
+ int r=0;
+ int y=h;
+ while (y-- > 0)
+ {
+ int *out, *in;
+ int x=w/2;
+ out=o+r;
+ in=tfb+r;
+ r^=1;
+ while (x-- > 0)
+ {
+ *out=*in;
+ out+=2;
+ in+=2;
+ }
+ o+=w;
+ tfb+=w;
+ }
+ }
+ break;
+ case 9:
+ while (x--)
+ {
+ *o=*o^*tfb++;
+ o++;
+ }
+ break;
+ case 10:
+ mmx_adjblend_block(o,tfb,o,x,use_outblendval);
+ break;
+ case 11:
+ mmx_mulblend_block(o,tfb,x);
+ break;
+ case 13:
+ while (x--)
+ {
+ *o=BLEND_MIN(*o,*tfb++);
+ o++;
+ }
+ break;
+ case 12:
+ {
+ int *buf=(int*)getGlobalBuffer(w,h,bufferout,0);
+ if (!buf) break;
+ while (x--)
+ {
+ *o=BLEND_ADJ(*tfb++,*o, depthof(*buf, outinvert));
+ o++;
+ buf++;
+ }
+ #ifndef NO_MMX
+ __asm emms;
+ #endif
+ }
+ break;
+ default:
+ break;
+ }
+ unset_n_Context();
+ }
+ return 0;
+#endif // !LASER
+}
+
+int C_RenderListClass::getNumRenders(void)
+{
+ return num_renders;
+}
+
+C_RenderListClass::T_RenderListType *C_RenderListClass::getRender(int index)
+{
+ if (index >= 0 && index < num_renders) return &renders[index];
+ return NULL;
+}
+
+int C_RenderListClass::findRender(T_RenderListType *r)
+{
+ int idx;
+ if (!r) return -1;
+ for (idx=0;idx<num_renders&&renders[idx].render!=r->render; idx++);
+ if (idx<num_renders) return idx;
+ return -1;
+}
+
+int C_RenderListClass::removeRenderFrom(T_RenderListType *r, int del)
+{
+ int idx;
+ if (!r) return 1;
+ for (idx=0;idx<num_renders&&renders[idx].render!=r->render; idx++);
+ return removeRender(idx,del);
+}
+
+int C_RenderListClass::removeRender(int index, int del)
+{
+ if (index >= 0 && index < num_renders)
+ {
+ if (del&&renders[index].render) delete renders[index].render;
+ num_renders--;
+ while (index<num_renders)
+ {
+ renders[index]=renders[index+1];
+ index++;
+ }
+ if (!num_renders)
+ {
+ num_renders_alloc=0;
+ if (renders) GlobalFree((HGLOBAL)renders);
+ renders=NULL;
+ }
+ return 0;
+ }
+ return 1;
+}
+void C_RenderListClass::clearRenders(void)
+{
+ int x;
+ if (renders)
+ {
+ for (x = 0; x < num_renders; x ++)
+ {
+ delete renders[x].render;
+ }
+ GlobalFree((HGLOBAL)renders);
+ }
+ num_renders=0;
+ num_renders_alloc=0;
+ renders=NULL;
+ if (thisfb) GlobalFree((HGLOBAL)thisfb);
+ thisfb=0;
+}
+
+int C_RenderListClass::insertRenderBefore(T_RenderListType *r, T_RenderListType *before)
+{
+ int idx;
+ if (!before) idx=num_renders;
+ else for (idx=0;idx<num_renders&&renders[idx].render!=before->render; idx++);
+ return insertRender(r,idx);
+}
+
+int C_RenderListClass::insertRender(T_RenderListType *r, int index) // index=-1 for add
+{
+ if (num_renders+1 >= num_renders_alloc || !renders)
+ {
+ num_renders_alloc=num_renders+16;
+ T_RenderListType *newr=(T_RenderListType *) GlobalAlloc(GPTR,num_renders_alloc*sizeof(T_RenderListType));
+ if (!newr) return -1;
+ if (num_renders&&renders)
+ {
+ memcpy(newr,renders,num_renders*sizeof(T_RenderListType));
+ }
+ if (renders)
+ {
+ GlobalFree((HGLOBAL)renders);
+ }
+ renders=newr;
+ }
+
+ if (index<0 || index>=num_renders)
+ {
+ renders[num_renders]=*r;
+ return num_renders++;
+ }
+ int x;
+ for (x=num_renders++; x > index; x--)
+ {
+ renders[x]=renders[x-1];
+ }
+ renders[x]=*r;
+
+ return x;
+}
+
+void C_RenderListClass::FillBufferCombo(HWND dlg, int ctl)
+{
+int i=0;
+char txt[64];
+for (i=0;i<NBUF;i++)
+ {
+ wsprintf(txt, WASABI_API_LNGSTRING(IDS_BUFFER_X), i+1);
+ SendDlgItemMessage(dlg, ctl, CB_ADDSTRING, 0, (LPARAM)txt);
+ }
+}
+
+
+static C_RenderListClass *g_this;
+int blendmodes[] =
+{
+ IDS_IGNORE,
+ IDS_REPLACE,
+ IDS_50_50,
+ IDS_MAXIMUM,
+ IDS_ADDITIVE,
+ IDS_SUBTRACTIVE_1,
+ IDS_SUBTRACTIVE_2,
+ IDS_EVERY_OTHER_LINE,
+ IDS_EVERY_OTHER_PIXEL,
+ IDS_XOR,
+ IDS_ADJUSTABLE,
+ IDS_MULTIPLY,
+ IDS_BUFFER,
+ IDS_MINIMUM,
+};
+
+
+
+BOOL CALLBACK C_RenderListClass::g_DlgProcRoot(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+#ifdef LASER
+ ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK1),SW_HIDE);
+#endif
+ {
+#ifndef LASER
+ if (g_this->clearfb()) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+#endif
+ }
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_CHECK1:
+ g_this->set_clearfb(IsDlgButtonChecked(hwndDlg,IDC_CHECK1));
+ break;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+BOOL CALLBACK C_RenderListClass::g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+#ifdef LASER
+ ShowWindow(GetDlgItem(hwndDlg,IDC_CHECK1),SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INSLIDE), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF1), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF2), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT1), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT2), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_COMBO1), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_COMBO2), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_FR1), SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_FR2), SW_HIDE);
+#endif
+ {
+#ifndef LASER
+ {
+ int x;
+ for (x = 0; x < sizeof(blendmodes)/sizeof(blendmodes[0]); x ++)
+ {
+ char blendStr[64];
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRING_BUF(blendmodes[x],blendStr,64));
+ SendDlgItemMessage(hwndDlg,IDC_COMBO2,CB_ADDSTRING,0,(LPARAM)blendStr);
+ }
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,(WPARAM)g_this->blendout(),0);
+ SendDlgItemMessage(hwndDlg,IDC_COMBO2,CB_SETCURSEL,(WPARAM)g_this->blendin(),0);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INSLIDE), (g_this->blendin() == 10) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), (g_this->blendout() == 10) ? SW_NORMAL : SW_HIDE);
+ SendDlgItemMessage(hwndDlg, IDC_INSLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
+ SendDlgItemMessage(hwndDlg, IDC_INSLIDE, TBM_SETPOS, TRUE, (int)(g_this->inblendval));
+ SendDlgItemMessage(hwndDlg, IDC_OUTSLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
+ SendDlgItemMessage(hwndDlg, IDC_OUTSLIDE, TBM_SETPOS, TRUE, (int)(g_this->outblendval));
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
+ g_this->FillBufferCombo(hwndDlg, IDC_CBBUF1);
+ g_this->FillBufferCombo(hwndDlg, IDC_CBBUF2);
+ SendDlgItemMessage(hwndDlg, IDC_CBBUF1, CB_SETCURSEL, (WPARAM) g_this->bufferin, 0);
+ SendDlgItemMessage(hwndDlg, IDC_CBBUF2, CB_SETCURSEL, (WPARAM) g_this->bufferout, 0);
+ if (g_this->ininvert) CheckDlgButton(hwndDlg,IDC_INVERT1,BST_CHECKED);
+ if (g_this->outinvert) CheckDlgButton(hwndDlg,IDC_INVERT2,BST_CHECKED);
+ }
+ if (g_this->clearfb()) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+#endif
+ g_this->isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT5,g_this->effect_exp[1].get());
+ g_this->isstart=0;
+
+
+ if (((g_this->mode&2)^2))
+ CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ if (g_this->beat_render) CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ else EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), FALSE);
+ if (g_this->use_code) CheckDlgButton(hwndDlg,IDC_CHECK4,BST_CHECKED);
+ char buf[999];
+ wsprintf(buf, "%d", g_this->beat_render_frames);
+ SetDlgItemText(hwndDlg,IDC_EDIT1,buf);
+ }
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_EDIT4:
+ case IDC_EDIT5:
+ if (!g_this->isstart && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT4);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT5);
+ g_this->need_recompile=1;
+ if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ break;
+ case IDC_COMBO1:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int r=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (r!=CB_ERR)
+ {
+ g_this->set_blendout(r);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_OUTSLIDE), (r == 10) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT2), (g_this->blendout() == 12) ? SW_NORMAL : SW_HIDE);
+ }
+ }
+ break;
+ case IDC_COMBO2:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int r=SendDlgItemMessage(hwndDlg,IDC_COMBO2,CB_GETCURSEL,0,0);
+ if (r!=CB_ERR)
+ {
+ g_this->set_blendin(r);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INSLIDE), (r == 10) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_CBBUF1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_INVERT1), (g_this->blendin() == 12) ? SW_NORMAL : SW_HIDE);
+ }
+ }
+ break;
+ case IDC_CBBUF1:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ g_this->bufferin = SendDlgItemMessage(hwndDlg, IDC_CBBUF1, CB_GETCURSEL, 0, 0);
+ break;
+ case IDC_CBBUF2:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ g_this->bufferout = SendDlgItemMessage(hwndDlg, IDC_CBBUF2, CB_GETCURSEL, 0, 0);
+ break;
+ case IDC_CHECK1:
+ g_this->set_clearfb(IsDlgButtonChecked(hwndDlg,IDC_CHECK1));
+ break;
+ case IDC_CHECK2:
+ g_this->set_enabled(IsDlgButtonChecked(hwndDlg,IDC_CHECK2));
+ break;
+ case IDC_INVERT1:
+ g_this->ininvert = IsDlgButtonChecked(hwndDlg,IDC_INVERT1);
+ break;
+ case IDC_INVERT2:
+ g_this->outinvert = IsDlgButtonChecked(hwndDlg,IDC_INVERT2);
+ break;
+ case IDC_CHECK3:
+ g_this->beat_render = IsDlgButtonChecked(hwndDlg,IDC_CHECK3);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), g_this->beat_render);
+ break;
+ case IDC_CHECK4:
+ g_this->use_code = !!IsDlgButtonChecked(hwndDlg,IDC_CHECK4);
+ break;
+ case IDC_EDIT1:
+ if (HIWORD(wParam) == EN_CHANGE) {
+ char buf[999]="1";
+ GetDlgItemText(hwndDlg, IDC_EDIT1, buf, 999);
+ buf[998] = 0;
+ g_this->beat_render_frames = atoi(buf);
+ }
+ break;
+ case IDC_BUTTON2:
+ {
+/* char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_EFFECT_LIST,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_EFFECT_LIST),4095-titlelen);
+*/
+ char *text="Effect List\0"
+ "Read/write 'enabled' to get/set whether the effect list is enabled for this frame\r\n"
+ "Read/write 'beat' to get/set whether there is currently a beat\r\n"
+ "Read/write 'clear' to get/set whether to clear the framebuffer\r\n"
+ "If the input blend is set to adjustable, 'alphain' can be set from 0.0-1.0\r\n"
+ "If the output blend is set to adjustable, 'alphaout' can be set from 0.0-1.0\r\n"
+ "'w' and 'h' are set with the current width and height of the frame\r\n"
+ ;
+
+ compilerfunctionlist(hwndDlg,text);
+ }
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_INSLIDE)
+ g_this->inblendval = SendDlgItemMessage(hwndDlg, IDC_INSLIDE, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_OUTSLIDE)
+ g_this->outblendval = SendDlgItemMessage(hwndDlg, IDC_OUTSLIDE, TBM_GETPOS, 0, 0);
+ break;
+ }
+ return 0;
+}
+
+
+HWND C_RenderListClass::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(isroot?IDD_CFG_LISTROOT:IDD_CFG_LIST,hwndParent,(WNDPROC)(isroot?g_DlgProcRoot:g_DlgProc));
+// return NULL;
+}
+
+char C_RenderListClass::sig_str[] = "Nullsoft AVS Preset 0.2\x1a";
+
+int C_RenderListClass::__SavePreset(char *filename)
+{
+ EnterCriticalSection(&g_render_cs);
+ unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1124*1024);
+ int success=-1;
+ if (data)
+ {
+ int pos=0;
+ memcpy(data+pos,sig_str,strlen(sig_str)); pos += strlen(sig_str);
+ pos+=save_config_ex(data+pos,1);
+ if (pos < 1024*1024)
+ {
+ HANDLE fp=CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
+ if (fp!=INVALID_HANDLE_VALUE)
+ {
+ DWORD dw;
+ success=0;
+ WriteFile(fp,data,pos,&dw,NULL);
+ CloseHandle(fp);
+ }
+ else success=2;
+ }
+ else success=1;
+ GlobalFree((HGLOBAL)data);
+ }
+ LeaveCriticalSection(&g_render_cs);
+ return success;
+}
+
+int C_RenderListClass::__LoadPreset(char *filename, int clear)
+{
+ EnterCriticalSection(&g_render_cs);
+ unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1024*1024);
+ int success=1;
+ if (clear) clearRenders();
+ if (data)
+ {
+ // OutputDebugString(filename);
+ HANDLE fp=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+ if (fp!=INVALID_HANDLE_VALUE)
+ {
+ DWORD len=GetFileSize(fp,NULL);
+ if (len == 0xffffffff) len=0;
+ if (!ReadFile(fp,data,min(len,1024*1024),&len,NULL)) len=0;
+ CloseHandle(fp);
+ if (len>strlen(sig_str)+2 && !memcmp(data,sig_str,strlen(sig_str)-2) &&
+ data[strlen(sig_str)-2] >= '1' &&
+ data[strlen(sig_str)-2] <= '2' &&
+ data[strlen(sig_str)-1] == '\x1a')
+ {
+ load_config(data+strlen(sig_str),len-strlen(sig_str));
+ success=0;
+ }
+ else
+ {
+ // if (len<=strlen(sig_str)+2) MessageBox(NULL,"Error loading preset: len",filename,MB_OK);
+ // else MessageBox(NULL,"Error loading preset: signature",filename,MB_OK);
+ }
+ }
+ // else MessageBox(NULL,"Error loading preset: fopen",filename,MB_OK);
+ GlobalFree((HGLOBAL)data);
+ }
+// else MessageBox(NULL,"Error loading preset: MALLOC",filename,MB_OK);
+ LeaveCriticalSection(&g_render_cs);
+ return success;
+}
+
+int C_RenderListClass::__SavePresetToUndo(C_UndoItem &item)
+{
+ EnterCriticalSection(&g_render_cs);
+ unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1124*1024);
+ int success=-1;
+ if (data)
+ {
+ // Do whatever the file saving stuff did
+ int pos=0;
+ memcpy(data+pos,sig_str,strlen(sig_str)); pos += strlen(sig_str);
+ pos+=save_config_ex(data+pos,1);
+
+ // And then set the data into the undo object.
+ if (pos < 1024*1024)
+ {
+ item.set(data, pos, true); // all undo items start dirty.
+ }
+
+ else success=1;
+ GlobalFree((HGLOBAL)data);
+ }
+ LeaveCriticalSection(&g_render_cs);
+ return success;
+}
+
+int C_RenderListClass::__LoadPresetFromUndo(C_UndoItem &item, int clear)
+{
+ EnterCriticalSection(&g_render_cs);
+ unsigned char *data = (unsigned char *) GlobalAlloc(GPTR,1024*1024);
+ int success=1;
+ if (clear) clearRenders();
+ if (data)
+ {
+ if (item.size() < 1024*1024)
+ {
+ // Get the data from the undo object.
+ DWORD len = item.size();
+ if (len == 0xffffffff) len=0;
+ memcpy(data, item.get(), item.size());
+
+ // And then do whatever the file loading stuff did.
+ if (!memcmp(data,sig_str,strlen(sig_str)-2) &&
+ data[strlen(sig_str)-2] >= '1' &&
+ data[strlen(sig_str)-2] <= '2' &&
+ data[strlen(sig_str)-1] == '\x1a')
+ {
+ load_config(data+strlen(sig_str),len-strlen(sig_str));
+ success=0;
+ }
+ }
+ GlobalFree((HGLOBAL)data);
+ }
+ LeaveCriticalSection(&g_render_cs);
+ return success;
+}
+
+
+
+
+/// smp fun
+
+void C_RenderListClass::smp_Render(int minthreads, C_RBASE2 *render, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int x;
+ smp_parms.nthreads=minthreads;
+ if (!smp_parms.hQuitHandle) smp_parms.hQuitHandle=CreateEvent(NULL,TRUE,FALSE,NULL);
+
+ smp_parms.vis_data_ptr=visdata;
+ smp_parms.isBeat=isBeat;
+ smp_parms.framebuffer=framebuffer;
+ smp_parms.fbout=fbout;
+ smp_parms.w=w;
+ smp_parms.h=h;
+ smp_parms.render=render;
+ for (x = 0; x < minthreads; x ++)
+ {
+ if (x >= smp_parms.threadTop)
+ {
+ DWORD id;
+ smp_parms.hThreadSignalsStart[x]=CreateEvent(NULL,FALSE,TRUE,NULL);
+ smp_parms.hThreadSignalsDone[x]=CreateEvent(NULL,FALSE,FALSE,NULL);
+
+ smp_parms.hThreads[x]=CreateThread(NULL,0,smp_threadProc,(LPVOID)(x),0,&id);
+ smp_parms.threadTop=x+1;
+ }
+ else
+ SetEvent(smp_parms.hThreadSignalsStart[x]);
+ }
+ WaitForMultipleObjects(smp_parms.nthreads,smp_parms.hThreadSignalsDone,TRUE,INFINITE);
+}
+
+DWORD WINAPI C_RenderListClass::smp_threadProc(LPVOID parm)
+{
+ int which=(int)parm;
+ HANDLE hdls[2]={smp_parms.hThreadSignalsStart[which],smp_parms.hQuitHandle};
+ for (;;)
+ {
+ if (WaitForMultipleObjects(2,hdls,FALSE,INFINITE) == WAIT_OBJECT_0 + 1) return 0;
+
+ smp_parms.render->smp_render(which,smp_parms.nthreads,
+ *(char (*)[2][2][576])smp_parms.vis_data_ptr,
+
+ smp_parms.isBeat,smp_parms.framebuffer,smp_parms.fbout,smp_parms.w,smp_parms.h);
+ SetEvent(smp_parms.hThreadSignalsDone[which]);
+ }
+}
+
+C_RenderListClass::_s_smp_parms C_RenderListClass::smp_parms; \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_list.h b/Src/Plugins/Visualization/vis_avs/r_list.h
new file mode 100644
index 00000000..e1036ca4
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_list.h
@@ -0,0 +1,173 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _R_LIST_H_
+#define _R_LIST_H_
+
+#include "avs_eelif.h"
+#define LIST_ID 0xfffffffe
+
+extern unsigned char blendtable[256][256];
+extern BOOL blendtableInited;
+
+class C_RenderTransitionClass;
+class C_UndoItem;
+
+class C_RenderListClass : public C_RBASE {
+ friend C_RenderTransitionClass;
+ public:
+ typedef struct
+ {
+ C_RBASE *render;
+ int effect_index;
+ int has_rbase2;
+ } T_RenderListType;
+
+ protected:
+ static char sig_str[];
+ int *thisfb;
+ int l_w, l_h;
+ int isroot;
+
+ int num_renders,num_renders_alloc;
+ T_RenderListType *renders;
+ int inblendval, outblendval;
+ int bufferin, bufferout;
+ int ininvert, outinvert;
+
+ int use_code;
+ RString effect_exp[2];
+
+ int inited;
+ NSEEL_CODEHANDLE codehandle[4];
+ int need_recompile;
+ CRITICAL_SECTION rcs;
+
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ double *var_beat, *var_alphain, *var_alphaout, *var_enabled, *var_clear, *var_w, *var_h;
+ int isstart;
+
+ int mode;
+
+ int beat_render, beat_render_frames;
+ int fake_enabled;
+
+#ifdef LASER
+ C_LineListBase *line_save;
+#else
+ void set_n_Context();
+ void unset_n_Context();
+
+ int nbw_save[NBUF],nbh_save[NBUF]; // these are our framebuffers
+ void *nb_save[NBUF];
+
+ int nbw_save2[NBUF],nbh_save2[NBUF]; // this are temp space for saving the global ones
+ void *nb_save2[NBUF];
+ int nsaved;
+#endif
+
+#define MAX_SMP_THREADS 8
+ // smp stuff
+ void smp_Render(int minthreads, C_RBASE2 *render, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ typedef struct
+ {
+ void *vis_data_ptr;
+ int nthreads;
+ int isBeat;
+ int *framebuffer;
+ int *fbout;
+ int w;
+ int h;
+ C_RBASE2 *render;
+
+
+
+ HANDLE hQuitHandle;
+ HANDLE hThreads[MAX_SMP_THREADS];
+ HANDLE hThreadSignalsStart[MAX_SMP_THREADS];
+ HANDLE hThreadSignalsDone[MAX_SMP_THREADS];
+
+ int threadTop;
+
+ } _s_smp_parms;
+
+
+ static _s_smp_parms smp_parms;
+ static DWORD WINAPI smp_threadProc(LPVOID parm);
+
+ public:
+
+ static void smp_cleanupthreads();
+
+ C_RenderListClass(int iroot=0);
+ virtual ~C_RenderListClass();
+
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ virtual char *get_desc();
+
+ int getNumRenders(void);
+ T_RenderListType *getRender(int index);
+ int findRender(T_RenderListType *r);
+ int removeRender(int index, int del); // return 0 on success
+ int removeRenderFrom(T_RenderListType *r, int del); // return 0 on success
+ int insertRender(T_RenderListType *r, int index); // return -1 on failure, actual position on success
+ int insertRenderBefore(T_RenderListType *r, T_RenderListType *before); // return -1 on failure, actual position on success
+ void clearRenders(void);
+ void freeBuffers();
+
+ int __SavePreset(char *filename);
+ int __LoadPreset(char *filename, int clear);
+
+ int __SavePresetToUndo(C_UndoItem &item);
+ int __LoadPresetFromUndo(C_UndoItem &item, int clear);
+
+ int clearfb() { return mode&1; }
+ void set_clearfb(int v) { if (v) mode|=1; else mode&=~1; }
+
+ int blendin() { return ((mode>>8)&31); }
+ void set_blendin(int v) { mode&=~(31<<8); mode|=(v&31)<<8; }
+ int blendout() { return ((mode>>16)&31)^1; }
+ void set_blendout(int v) { mode&=~(31<<16); mode|=((v^1)&31)<<16; }
+ unsigned char get_extended_datasize(void) { return ((mode & 0xFF000000) >> 24); }
+ void set_extended_datasize(unsigned char s) { mode &= 0xFFFFFF; mode |= s << 24; }
+
+ int enabled() { return ((mode&2)^2) || fake_enabled>0; }
+ void set_enabled(int v) { if (!v) mode|=2; else mode&=~2; }
+ static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+ static BOOL CALLBACK g_DlgProcRoot(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+ int save_config_ex(unsigned char *data, int rootsave);
+ void load_config_code(unsigned char *data, int len);
+ int save_config_code(unsigned char *data);
+ void FillBufferCombo(HWND dlg, int ctl);
+};
+
+#endif // _R_LIST_H_
diff --git a/Src/Plugins/Visualization/vis_avs/r_mirror.cpp b/Src/Plugins/Visualization/vis_avs/r_mirror.cpp
new file mode 100644
index 00000000..2573cb3e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_mirror.cpp
@@ -0,0 +1,385 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Mirror"
+#define C_THISCLASS C_MirrorClass
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS() { }
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_MIRROR,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int framecount;
+ int enabled;
+ int mode;
+ int onbeat;
+ int rbeat;
+ int smooth;
+ int slower;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+#define HORIZONTAL1 1
+#define HORIZONTAL2 2
+#define VERTICAL1 4
+#define VERTICAL2 8
+
+#define D_HORIZONTAL1 0
+#define D_HORIZONTAL2 8
+#define D_VERTICAL1 16
+#define D_VERTICAL2 24
+#define M_HORIZONTAL1 0xFF
+#define M_HORIZONTAL2 0xFF00
+#define M_VERTICAL1 0xFF0000
+#define M_VERTICAL2 0xFF000000
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ framecount=0;
+ enabled=1;
+ onbeat=0;
+ smooth=0;
+ slower=4;
+ mode=HORIZONTAL1;
+}
+
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { mode=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { smooth=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { slower=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(mode); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_INT(smooth); pos+=4;
+ PUT_INT(slower); pos+=4;
+ return pos;
+}
+
+static unsigned int __inline BLEND_ADAPT(unsigned int a, unsigned int b, /*float*/int divisor)
+{
+return ((((a >> 4) & 0x0F0F0F) * (16-divisor) + (((b >> 4) & 0x0F0F0F) * divisor)));
+}
+
+
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int hi,t,j,halfw,halfh,m,d;
+ int *thismode=&mode;
+ static int lastMode;
+ static int divisors=0;
+ static int inc=0;
+ int divis;
+ int *fbp;
+
+ if (isBeat&0x80000000) return 0;
+ if (!enabled) return 0;
+
+ t=w*h;
+ halfw = w / 2 ;
+ halfh = h / 2 ;
+
+ if (onbeat)
+ {
+ if (isBeat) rbeat = (rand()%16) & mode;
+ thismode=&rbeat;
+ }
+
+ if (*thismode != lastMode)
+ {
+ int dif = *thismode ^ lastMode;
+ int i;
+ for (i=1,m=0xFF,d=0;i<16;i<<=1,m<<=8,d+=8)
+ if (dif & i)
+ {
+ inc = (inc & ~m) | ((lastMode & i) ? 0xFF : 1) << d;
+ if (!(divisors & m)) divisors = (divisors & ~m) | ((lastMode & i) ? 16 : 1) << d;
+ }
+ lastMode = *thismode;
+ }
+
+ fbp=framebuffer;
+ if (*thismode & VERTICAL1 || (smooth && (divisors & 0x00FF0000)))
+ {
+ divis = (divisors & M_VERTICAL1) >> D_VERTICAL1;
+ for ( hi=0 ; hi < h ; hi++)
+ {
+ if (smooth && divis)
+ {
+ int *tmp=fbp+w-1;
+ int n=halfw;
+ while (n--) *tmp-- = BLEND_ADAPT(*tmp, *fbp++, divis);
+ }
+ else
+ {
+ int *tmp=fbp+w-1;
+ int n=halfw;
+ while (n--) *tmp-- = *fbp++;
+ }
+ fbp+=halfw;
+ }
+ }
+ fbp=framebuffer;
+ if (*thismode & VERTICAL2 || (smooth && (divisors & 0xFF000000)))
+ {
+ divis = (divisors & M_VERTICAL2) >> D_VERTICAL2;
+ for ( hi=0 ; hi < h ; hi++)
+ {
+ if (smooth && divis)
+ {
+ int *tmp=fbp+w-1;
+ int n=halfw;
+ while (n--) *fbp++ = BLEND_ADAPT(*fbp,*tmp--,divis);
+ }
+ else
+ {
+ int *tmp=fbp+w-1;
+ int n=halfw;
+ while (n--) *fbp++ = *tmp--;
+ }
+ fbp+=halfw;
+ }
+ }
+ fbp=framebuffer;
+ j=t-w;
+ if (*thismode & HORIZONTAL1 || (smooth && (divisors & 0x000000FF)))
+ {
+ divis = (divisors & M_HORIZONTAL1) >> D_HORIZONTAL1;
+ for ( hi=0 ; hi < halfh ; hi++)
+ {
+ if (smooth && divis)
+ {
+ int n=w;
+ while (n--) fbp++[j]=BLEND_ADAPT(fbp[j], *fbp, divis);
+ }
+ else
+ {
+ memcpy(fbp+j,fbp,w*sizeof(int));
+ fbp+=w;
+ }
+ j-=2*w;
+ }
+ }
+ fbp=framebuffer;
+ j=t-w;
+ if (*thismode & HORIZONTAL2 || (smooth && (divisors & 0x0000FF00)))
+ {
+ divis = (divisors & M_HORIZONTAL2) >> D_HORIZONTAL2;
+ for ( hi=0 ; hi < halfh ; hi++)
+ {
+ if (smooth && divis)
+ {
+ int n=w;
+ while (n--)
+ *fbp++ = BLEND_ADAPT(*fbp, fbp[j], divis);
+ }
+ else
+ {
+ memcpy(fbp,fbp+j,w*sizeof(int));
+ fbp+=w;
+ }
+ j-=2*w;
+ }
+ }
+
+ if (smooth && !(++framecount % slower))
+ {
+ int i;
+ for (i=1,m=0xFF,d=0;i<16;i<<=1,m<<=8,d+=8)
+ {
+ if (divisors & m)
+ divisors = (divisors & ~m) | ((((divisors & m) >> d) + (unsigned char)((inc & m) >> d)) % 16) << d;
+ }
+ }
+ return 0;
+}
+
+int getMode(HWND hwndDlg)
+{
+int a;
+a=IsDlgButtonChecked(hwndDlg,IDC_HORIZONTAL1)?HORIZONTAL1:0;
+a|=IsDlgButtonChecked(hwndDlg,IDC_HORIZONTAL2)?HORIZONTAL2:0;
+a|=IsDlgButtonChecked(hwndDlg,IDC_VERTICAL1)?VERTICAL1:0;
+a|=IsDlgButtonChecked(hwndDlg,IDC_VERTICAL2)?VERTICAL2:0;
+return a;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_SLOWER, TBM_SETTICFREQ, 1, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SLOWER, TBM_SETRANGE, TRUE, MAKELONG(1, 16));
+ SendDlgItemMessage(hwndDlg, IDC_SLOWER, TBM_SETPOS, TRUE, g_ConfigThis->slower);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->smooth) CheckDlgButton(hwndDlg,IDC_SMOOTH,BST_CHECKED);
+ if (g_ConfigThis->mode & VERTICAL1)
+ CheckDlgButton(hwndDlg,IDC_VERTICAL1,BST_CHECKED);
+ if (g_ConfigThis->mode & VERTICAL2)
+ CheckDlgButton(hwndDlg,IDC_VERTICAL2,BST_CHECKED);
+ if (g_ConfigThis->mode & HORIZONTAL1)
+ CheckDlgButton(hwndDlg,IDC_HORIZONTAL1,BST_CHECKED);
+ if (g_ConfigThis->mode & HORIZONTAL2)
+ CheckDlgButton(hwndDlg,IDC_HORIZONTAL2,BST_CHECKED);
+ if (g_ConfigThis->onbeat)
+ CheckDlgButton(hwndDlg,IDC_ONBEAT,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_STAT,BST_CHECKED);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_SLOWER)
+ g_ConfigThis->slower = SendDlgItemMessage(hwndDlg, IDC_SLOWER, TBM_GETPOS, 0, 0);
+ return 0;
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_CHECK1)
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_HORIZONTAL1)
+ {
+ g_ConfigThis->mode = getMode(hwndDlg);
+ if ((g_ConfigThis->mode & HORIZONTAL1) && (g_ConfigThis->mode & HORIZONTAL2) && !(g_ConfigThis->onbeat))
+ {
+ CheckDlgButton(hwndDlg,IDC_HORIZONTAL2,BST_UNCHECKED);
+ g_ConfigThis->mode = getMode(hwndDlg);
+ }
+ }
+ if (LOWORD(wParam) == IDC_HORIZONTAL2)
+ {
+ g_ConfigThis->mode = getMode(hwndDlg);
+ if ((g_ConfigThis->mode & HORIZONTAL1) && (g_ConfigThis->mode & HORIZONTAL2) && !(g_ConfigThis->onbeat))
+ {
+ CheckDlgButton(hwndDlg,IDC_HORIZONTAL1,BST_UNCHECKED);
+ g_ConfigThis->mode = getMode(hwndDlg);
+ }
+ }
+ if (LOWORD(wParam) == IDC_VERTICAL1)
+ {
+ g_ConfigThis->mode = getMode(hwndDlg);
+ if ((g_ConfigThis->mode & VERTICAL1) && (g_ConfigThis->mode & VERTICAL2) && !(g_ConfigThis->onbeat))
+ {
+ CheckDlgButton(hwndDlg,IDC_VERTICAL2,BST_UNCHECKED);
+ g_ConfigThis->mode = getMode(hwndDlg);
+ }
+ }
+ if (LOWORD(wParam) == IDC_VERTICAL2)
+ {
+ g_ConfigThis->mode = getMode(hwndDlg);
+ if ((g_ConfigThis->mode & VERTICAL1) && (g_ConfigThis->mode & VERTICAL2) && !(g_ConfigThis->onbeat))
+ {
+ CheckDlgButton(hwndDlg,IDC_VERTICAL1,BST_UNCHECKED);
+ g_ConfigThis->mode = getMode(hwndDlg);
+ }
+ }
+ if (LOWORD(wParam) == IDC_STAT || LOWORD(wParam) == IDC_ONBEAT)
+ {
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT)?1:0;
+ if (!(g_ConfigThis->onbeat))
+ {
+ if ((g_ConfigThis->mode & HORIZONTAL1) && (g_ConfigThis->mode & HORIZONTAL2))
+ CheckDlgButton(hwndDlg,IDC_HORIZONTAL2,BST_UNCHECKED);
+ if ((g_ConfigThis->mode & VERTICAL1) && (g_ConfigThis->mode & VERTICAL2))
+ CheckDlgButton(hwndDlg,IDC_VERTICAL2,BST_UNCHECKED);
+ g_ConfigThis->mode = getMode(hwndDlg);
+ }
+ }
+ if (LOWORD(wParam) == IDC_SMOOTH)
+ g_ConfigThis->smooth=IsDlgButtonChecked(hwndDlg,IDC_SMOOTH)?1:0;
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_MIRROR,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Mirror(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Mirror(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_mosaic.cpp b/Src/Plugins/Visualization/vis_avs/r_mosaic.cpp
new file mode 100644
index 00000000..b298c3d0
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_mosaic.cpp
@@ -0,0 +1,299 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+#define MOD_NAME "Trans / Mosaic"
+#define C_THISCLASS C_MosaicClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ float GET_FLOAT(unsigned char *data, int pos);
+ void PUT_FLOAT(float f, unsigned char *data, int pos);
+ void InitializeStars(int Start);
+ void CreateStar(int A);
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_MOSAIC,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int enabled;
+ int quality;
+ int quality2;
+ int blend;
+ int blendavg;
+ int onbeat;
+ int durFrames;
+ int nF;
+ int thisQuality;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ enabled=1;
+ quality = 50;
+ blend = 0;
+ blendavg = 0;
+ onbeat = 0;
+ durFrames = 15;
+ nF=0;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { quality=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { quality2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { durFrames=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(quality); pos+=4;
+ PUT_INT(quality2); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_INT(durFrames); pos+=4;
+ return pos;
+}
+
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int rval=0;
+
+ if (isBeat&0x80000000) return 0;
+
+ if (!enabled) return 0;
+
+ if (onbeat && isBeat)
+ {
+ thisQuality=quality2;
+ nF = durFrames;
+ }
+ else if (!nF) thisQuality = quality;
+
+ if (thisQuality<100)
+ {
+ int y;
+ int *p = fbout;
+ int *p2 = framebuffer;
+ int sXInc = (w*65536) / thisQuality;
+ int sYInc = (h*65536) / thisQuality;
+ int ypos=(sYInc>>17);
+ int dypos=0;
+
+ for (y = 0; y < h; y ++)
+ {
+ int x=w;
+ int *fbread=framebuffer+ypos*w;
+ int dpos=0;
+ int xpos=(sXInc>>17);
+ int src=fbread[xpos];
+
+ if (blend)
+ {
+ while (x--)
+ {
+ *p++ = BLEND(*p2++, src);
+ dpos+=1<<16;
+ if (dpos>=sXInc)
+ {
+ xpos+=dpos>>16;
+ if (xpos >= w) break;
+ src=fbread[xpos];
+ dpos-=sXInc;
+ }
+ }
+ }
+ else if (blendavg)
+ {
+ while (x--)
+ {
+ *p++ = BLEND_AVG(*p2++, src);
+ dpos+=1<<16;
+ if (dpos>=sXInc)
+ {
+ xpos+=dpos>>16;
+ if (xpos >= w) break;
+ src=fbread[xpos];
+ dpos-=sXInc;
+ }
+ }
+ }
+ else
+ {
+ while (x--)
+ {
+ *p++ = src;
+ dpos+=1<<16;
+ if (dpos>=sXInc)
+ {
+ xpos+=dpos>>16;
+ if (xpos >= w) break;
+ src=fbread[xpos];
+ dpos-=sXInc;
+ }
+ }
+ }
+ dypos+=1<<16;
+ if (dypos>=sYInc)
+ {
+ ypos+=(dypos>>16);
+ dypos-=sYInc;
+ if (ypos >= h) break;
+ }
+ }
+ rval=1;
+ }
+
+ if (nF)
+ {
+ nF--;
+ if (nF)
+ {
+ int a = abs(quality - quality2) / durFrames;
+ thisQuality += a * (quality2 > quality ? -1 : 1);
+ }
+ }
+
+ return rval;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_QUALITY, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_QUALITY, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_QUALITY, TBM_SETPOS, TRUE, g_ConfigThis->quality);
+ SendDlgItemMessage(hwndDlg, IDC_QUALITY2, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_QUALITY2, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_QUALITY2, TBM_SETPOS, TRUE, g_ConfigThis->quality2);
+ SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_SETPOS, TRUE, g_ConfigThis->durFrames);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->onbeat) CheckDlgButton(hwndDlg,IDC_ONBEAT,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_QUALITY2)
+ g_ConfigThis->quality2 = SendDlgItemMessage(hwndDlg, IDC_QUALITY2, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_BEATDUR)
+ g_ConfigThis->durFrames = SendDlgItemMessage(hwndDlg, IDC_BEATDUR, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_QUALITY)
+ g_ConfigThis->quality = SendDlgItemMessage(hwndDlg, IDC_QUALITY, TBM_GETPOS, 0, 0);
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ONBEAT) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ }
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_MOSAIC,hwndParent,g_DlgProc);
+}
+
+// export stuff
+
+C_RBASE *R_Mosaic(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Mosaic(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_multidelay.cpp b/Src/Plugins/Visualization/vis_avs/r_multidelay.cpp
new file mode 100644
index 00000000..7f742e63
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_multidelay.cpp
@@ -0,0 +1,440 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// video delay
+// copyright tom holden, 2002
+// mail: cfp@myrealbox.com
+
+#include <windows.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#define MOD_NAME "Trans / Multi Delay"
+#define C_DELAY C_MultiDelayClass
+
+// R_MultiDelay / #define UNIQUEIDSTRING "Holden05: Multi Delay"
+
+// saved
+bool usebeats[6];
+int delay[6];
+
+// unsaved
+LPVOID buffer[6];
+LPVOID inpos[6];
+LPVOID outpos[6];
+unsigned long buffersize[6];
+unsigned long virtualbuffersize[6];
+unsigned long oldvirtualbuffersize[6];
+unsigned long framedelay[6];
+unsigned int numinstances = 0;
+unsigned long framessincebeat;
+unsigned long framesperbeat;
+unsigned long framemem;
+unsigned long oldframemem;
+unsigned int renderid;
+
+class C_DELAY : public C_RBASE
+{
+ protected:
+ public:
+ // standard ape members
+ C_DELAY();
+ virtual ~C_DELAY();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual char *get_desc();
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ // saved members
+ int mode;
+ int activebuffer;
+
+ // unsaved members
+ unsigned int creationid;
+};
+
+// global configuration dialog pointer
+static C_DELAY *g_Delay;
+// global DLL instance pointer
+static HINSTANCE g_hDllInstance;
+
+// configuration screen
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ char value[16];
+ unsigned int objectcode, objectmessage;
+ HWND hwndEdit;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG: //init
+ {
+ int i;
+ for (i=0;i<3;i++) CheckDlgButton(hwndDlg,1100+i,g_Delay->mode==i);
+ for (i=0;i<6;i++)
+ {
+ CheckDlgButton(hwndDlg,1000+i,g_Delay->activebuffer==i);
+ CheckDlgButton(hwndDlg,1020+i,usebeats[i]);
+ CheckDlgButton(hwndDlg,1030+i,!usebeats[i]);
+ hwndEdit = GetDlgItem(hwndDlg,1010+i);
+ _itoa(delay[i],value,10);
+ SetWindowText(hwndEdit,value);
+ }
+ }
+ return 1;
+ case WM_COMMAND:
+ objectcode = LOWORD(wParam);
+ objectmessage = HIWORD(wParam);
+ // mode stuff
+ if (objectcode >= 1100)
+ {
+ if(IsDlgButtonChecked(hwndDlg,objectcode)==1)
+ {
+ g_Delay->mode = objectcode - 1100;
+ for (int i=1100;i<1103;i++) if (objectcode != i) CheckDlgButton(hwndDlg,i,BST_UNCHECKED);
+ }
+ return 0;
+ }
+ // frames stuff
+ if (objectcode >= 1030)
+ {
+ if(IsDlgButtonChecked(hwndDlg,objectcode)==1)
+ {
+ usebeats[objectcode-1030] = false;
+ CheckDlgButton(hwndDlg,objectcode-10,BST_UNCHECKED);
+ framedelay[objectcode-1030] = delay[objectcode-1030]+1;
+ }
+ else usebeats[objectcode-1030] = true;
+ return 0;
+ }
+ // beats stuff
+ if (objectcode >= 1020)
+ {
+ if(IsDlgButtonChecked(hwndDlg,objectcode)==1)
+ {
+ usebeats[objectcode-1020] = true;
+ CheckDlgButton(hwndDlg,objectcode+10,BST_UNCHECKED);
+ framedelay[objectcode-1020] = framesperbeat+1;
+ }
+ else usebeats[objectcode-1020] = false;
+ return 0;
+ }
+ // edit box stuff
+ if (objectcode >= 1010)
+ {
+ hwndEdit = GetDlgItem(hwndDlg,objectcode);
+ if (objectmessage == EN_CHANGE)
+ {
+ GetWindowText(hwndEdit,value,16);
+ delay[objectcode-1010] = max(atoi(value),0);
+ framedelay[objectcode-1010] = (usebeats[objectcode-1010]?framesperbeat:delay[objectcode-1010])+1;
+ }
+ else if (objectmessage == EN_KILLFOCUS)
+ {
+ _itoa(delay[objectcode-1010],value,10);
+ SetWindowText(hwndEdit,value);
+ }
+ return 0;
+ }
+ // active buffer stuff
+ if (objectcode >= 1000)
+ {
+ if(IsDlgButtonChecked(hwndDlg,objectcode)==1)
+ {
+ g_Delay->activebuffer = objectcode - 1000;
+ for (int i=1000;i<1006;i++) if (objectcode != i) CheckDlgButton(hwndDlg,i,BST_UNCHECKED);
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+// set up default configuration
+C_DELAY::C_DELAY()
+{
+ // enable
+ mode = 0;
+ activebuffer = 0;
+ numinstances++;
+ creationid = numinstances;
+ if (creationid == 1)
+ {
+ for (int i=0; i<6; i++)
+ {
+ renderid = 0;
+ framessincebeat = 0;
+ framesperbeat = 0;
+ framemem = 1;
+ oldframemem = 1;
+ usebeats[i] = false;
+ delay[i] = 0;
+ framedelay[i] = 0;
+ buffersize[i] = 1;
+ virtualbuffersize[i] = 1;
+ oldvirtualbuffersize[i] = 1;
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ inpos[i] = buffer[i];
+ outpos[i] = buffer[i];
+ }
+ }
+}
+
+// virtual destructor
+C_DELAY::~C_DELAY()
+{
+ numinstances--;
+ if (numinstances == 0) for (int i=0; i<6; i++) VirtualFree(buffer[i],buffersize[i],MEM_DECOMMIT);
+}
+
+// RENDER FUNCTION:
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout
+// w and h are the-width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_DELAY::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+
+ if (renderid == numinstances) renderid = 0;
+ renderid++;
+ if (renderid == 1)
+ {
+ framemem = w*h*4;
+ if (isBeat)
+ {
+ framesperbeat = framessincebeat;
+ for (int i=0;i<6;i++) if (usebeats[i]) framedelay[i] = framesperbeat+1;
+ framessincebeat = 0;
+ }
+ framessincebeat++;
+ for (int i=0;i<6;i++)
+ {
+ if (framedelay[i]>1)
+ {
+ virtualbuffersize[i] = framedelay[i]*framemem;
+ if (framemem == oldframemem)
+ {
+ if (virtualbuffersize[i] != oldvirtualbuffersize[i])
+ {
+ if (virtualbuffersize[i] > oldvirtualbuffersize[i])
+ {
+ if (virtualbuffersize[i] > buffersize[i])
+ {
+ // allocate new memory
+ if (!VirtualFree(buffer[i],buffersize[i],MEM_DECOMMIT)) return 0;
+ if (usebeats[i])
+ {
+ buffersize[i] = 2*virtualbuffersize[i];
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ if (buffer[i] == NULL)
+ {
+ buffersize[i] = virtualbuffersize[i];
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ }
+ }
+ else
+ {
+ buffersize[i] = virtualbuffersize[i];
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ }
+ outpos[i] = buffer[i];
+ inpos[i] = (LPVOID)(((unsigned long)buffer[i])+virtualbuffersize[i]-framemem);
+ if (buffer[i] == NULL)
+ {
+ framedelay[i] = 0;
+ if (usebeats[i])
+ {
+ framesperbeat = 0;
+ framessincebeat = 0;
+ framedelay[i] = 0;
+ delay[i] = 0;
+ }
+ }
+ }
+ else
+ {
+ unsigned long size = (((unsigned long)buffer[i])+oldvirtualbuffersize[i]) - ((unsigned long)outpos[i]);
+ unsigned long l = ((unsigned long)buffer[i])+virtualbuffersize[i];
+ unsigned long d = l - size;
+ MoveMemory((LPVOID)d, outpos[i], size);
+ for (l = (unsigned long)outpos[i]; l < d; l += framemem) CopyMemory((LPVOID)l,(LPVOID)d,framemem);
+ }
+ }
+ else
+ { // virtualbuffersize < oldvirtualbuffersize
+ unsigned long presegsize = ((unsigned long)outpos[i])-((unsigned long)buffer[i]);
+ if (presegsize > virtualbuffersize[i])
+ {
+ MoveMemory(buffer[i],(LPVOID)(((unsigned long)buffer[i])+presegsize-virtualbuffersize[i]),virtualbuffersize[i]);
+ inpos[i] = (LPVOID)(((unsigned long)buffer[i])+virtualbuffersize[i]-framemem);
+ outpos[i] = buffer[i];
+ }
+ else if (presegsize < virtualbuffersize[i]) MoveMemory(outpos[i],(LPVOID)(((unsigned long)buffer[i])+oldvirtualbuffersize[i]+presegsize-virtualbuffersize[i]),virtualbuffersize[i]-presegsize);
+ }
+ oldvirtualbuffersize[i] = virtualbuffersize[i];
+ }
+ }
+ else
+ {
+ // allocate new memory
+ if (!VirtualFree(buffer[i],buffersize[i],MEM_DECOMMIT)) return 0;
+ if (usebeats[i])
+ {
+ buffersize[i] = 2*virtualbuffersize[i];
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ if (buffer[i] == NULL)
+ {
+ buffersize[i] = virtualbuffersize[i];
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ }
+ }
+ else
+ {
+ buffersize[i] = virtualbuffersize[i];
+ buffer[i] = VirtualAlloc(NULL,buffersize[i],MEM_COMMIT,PAGE_READWRITE);
+ }
+ outpos[i] = buffer[i];
+ inpos[i] = (LPVOID)(((unsigned long)buffer[i])+virtualbuffersize[i]-framemem);
+ if (buffer[i] == NULL)
+ {
+ framedelay[i] = 0;
+ if (usebeats[i])
+ {
+ framesperbeat = 0;
+ framessincebeat = 0;
+ framedelay[i] = 0;
+ delay[i] = 0;
+ }
+ }
+ oldvirtualbuffersize[i] = virtualbuffersize[i];
+ }
+ oldframemem = framemem;
+ }
+ }
+ }
+ if (mode != 0 && framedelay[activebuffer]>1)
+ {
+ if (mode == 2) CopyMemory(framebuffer,outpos[activebuffer],framemem);
+ else CopyMemory(inpos[activebuffer],framebuffer,framemem);
+ }
+ if (renderid == numinstances) for (int i=0;i<6;i++)
+ {
+ inpos[i] = (LPVOID)(((unsigned long)inpos[i])+framemem);
+ outpos[i] = (LPVOID)(((unsigned long)outpos[i])+framemem);
+ if ((unsigned long)inpos[i]>=((unsigned long)buffer[i])+virtualbuffersize[i]) inpos[i] = buffer[i];
+ if ((unsigned long)outpos[i]>=((unsigned long)buffer[i])+virtualbuffersize[i]) outpos[i] = buffer[i];
+ }
+ return 0;
+}
+
+HWND C_DELAY::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_Delay = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_MULTIDELAY,hwndParent,g_DlgProc);
+}
+
+char *C_DELAY::get_desc(void)
+{
+ static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_MULTI_DELAY,desc,128):desc);
+}
+
+// load_/save_config are called when saving and loading presets (.avs files)
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_DELAY::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ // always ensure there is data to be loaded
+ if (len-pos >= 4)
+ {
+ // load mode
+ mode=GET_INT();
+ pos+=4;
+ }
+ if (len-pos >= 4)
+ {
+ // load active buffer
+ activebuffer=GET_INT();
+ pos+=4;
+ }
+ if (len-pos >= 4)
+ {
+ for (int i=0;i<6;i++)
+ {
+ if (len-pos >= 4)
+ {
+ // load usebeats
+ usebeats[i]=(GET_INT()==1);
+ pos+=4;
+ }
+ if (len-pos >= 4)
+ {
+ // load delay
+ delay[i]=GET_INT();
+ framedelay[i] = (usebeats[i]?framesperbeat:delay[i])+1;
+ pos+=4;
+ }
+ }
+ }
+}
+
+// write configuration to data, return length. config data should not exceed 64k.
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_DELAY::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(mode);
+ pos+=4;
+ PUT_INT(activebuffer);
+ pos+=4;
+ if (creationid == 1)
+ {
+ for (int i=0;i<6;i++)
+ {
+ PUT_INT((int)usebeats[i]);
+ pos+=4;
+ PUT_INT(delay[i]);
+ pos+=4;
+ }
+ }
+ return pos;
+}
+
+// export stuff
+C_RBASE *R_MultiDelay(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc)
+ {
+ strcpy(desc,MOD_NAME);
+ return NULL;
+ }
+ return (C_RBASE *) new C_DELAY();
+}
diff --git a/Src/Plugins/Visualization/vis_avs/r_multiplier.cpp b/Src/Plugins/Visualization/vis_avs/r_multiplier.cpp
new file mode 100644
index 00000000..c59acb5e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_multiplier.cpp
@@ -0,0 +1,365 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+#define MD_XI 0
+#define MD_X8 1
+#define MD_X4 2
+#define MD_X2 3
+#define MD_X05 4
+#define MD_X025 5
+#define MD_X0125 6
+#define MD_XS 7
+
+// this will be the directory and APE name displayed in the AVS Editor
+#define MOD_NAME "Trans / Multiplier"
+#define C_THISCLASS C_MultiplierClass
+
+typedef struct {
+ int ml;
+} apeconfig;
+
+class C_THISCLASS : public C_RBASE
+{
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual char *get_desc();
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ apeconfig config;
+
+ HWND hwndDlg;
+};
+
+// global configuration dialog pointer
+static C_THISCLASS *g_ConfigThis;
+static HINSTANCE g_hDllInstance;
+
+
+// this is where we deal with the configuration screen
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ int id;
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ if (HIWORD(wParam) == BN_CLICKED) {
+ id = LOWORD(wParam);
+ switch (id) {
+ case IDC_XI:
+ g_ConfigThis->config.ml = MD_XI;
+ break;
+ case IDC_X8:
+ g_ConfigThis->config.ml = MD_X8;
+ break;
+ case IDC_X4:
+ g_ConfigThis->config.ml = MD_X4;
+ break;
+ case IDC_X2:
+ g_ConfigThis->config.ml = MD_X2;
+ break;
+ case IDC_X05:
+ g_ConfigThis->config.ml = MD_X05;
+ break;
+ case IDC_X025:
+ g_ConfigThis->config.ml = MD_X025;
+ break;
+ case IDC_X0125:
+ g_ConfigThis->config.ml = MD_X0125;
+ break;
+ case IDC_XS:
+ g_ConfigThis->config.ml = MD_XS;
+ break;
+ }
+ }
+ return 0;
+
+ case WM_INITDIALOG:
+ g_ConfigThis->hwndDlg = hwndDlg;
+
+ switch (g_ConfigThis->config.ml) {
+ case MD_XI:
+ id = IDC_XI;
+ break;
+ case MD_X8:
+ id = IDC_X8;
+ break;
+ case MD_X4:
+ id = IDC_X4;
+ break;
+ case MD_X2:
+ id = IDC_X2;
+ break;
+ case MD_X05:
+ id = IDC_X05;
+ break;
+ case MD_X025:
+ id = IDC_X025;
+ break;
+ case MD_X0125:
+ id = IDC_X0125;
+ break;
+ case MD_XS:
+ id = IDC_XS;
+ break;
+ }
+ SendMessage(GetDlgItem(hwndDlg, id), BM_SETCHECK, BST_CHECKED, 0);
+
+ return 1;
+
+ case WM_DESTROY:
+ return 1;
+ }
+ return 0;
+}
+
+// set up default configuration
+C_THISCLASS::C_THISCLASS()
+{
+ memset(&config, 0, sizeof(apeconfig));
+ config.ml = MD_X2;
+}
+
+// virtual destructor
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+
+ int b,c;
+ __int64 mask;
+
+ c = w*h;
+ switch (config.ml) {
+ case MD_XI:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ mov edx, b;
+ lp0:
+ xor eax, eax;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ mov eax, dword ptr [ebx+ecx*4];
+ test eax, eax;
+ jz sk0;
+ mov eax, 0xFFFFFF;
+ sk0:
+ mov [ebx+ecx*4], eax;
+ jmp lp0;
+ }
+ break;
+ case MD_XS:
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ mov edx, b;
+ lp9:
+ xor eax, eax;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ mov eax, dword ptr [ebx+ecx*4];
+ cmp eax, 0xFFFFFF;
+ je sk9;
+ mov eax, 0x000000;
+ sk9:
+ mov [ebx+ecx*4], eax;
+ jmp lp9;
+ }
+ break;
+ case MD_X8:
+ c = w*h/2;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp1:
+ movq mm0, [ebx];
+ paddusb mm0, mm0;
+ paddusb mm0, mm0;
+ paddusb mm0, mm0;
+ movq [ebx], mm0;
+ add ebx, 8;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ jmp lp1;
+ }
+ break;
+ case MD_X4:
+ c = w*h/2;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp2:
+ movq mm0, [ebx];
+ paddusb mm0, mm0;
+ paddusb mm0, mm0;
+ movq [ebx], mm0;
+ add ebx, 8;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ jmp lp2;
+ }
+ break;
+ case MD_X2:
+ c = w*h/2;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ lp3:
+ movq mm0, [ebx];
+ paddusb mm0, mm0;
+ movq [ebx], mm0;
+ add ebx, 8;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ jmp lp3;
+ }
+ break;
+ case MD_X05:
+ c = w*h/2;
+ mask = 0x7F7F7F7F7F7F7F7F;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ movq mm1, mask;
+ lp4:
+ movq mm0, [ebx];
+ psrlq mm0, 1;
+ pand mm0, mm1;
+ movq [ebx], mm0;
+ add ebx, 8;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ jmp lp4;
+ }
+ break;
+ case MD_X025:
+ c = w*h/2;
+ mask = 0x3F3F3F3F3F3F3F3F;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ movq mm1, mask;
+ lp5:
+ movq mm0, [ebx];
+ psrlq mm0, 2;
+ pand mm0, mm1;
+ movq [ebx], mm0;
+ add ebx, 8;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ jmp lp5;
+ }
+ break;
+ case MD_X0125:
+ c = w*h/2;
+ mask = 0x1F1F1F1F1F1F1F1F;
+ __asm {
+ mov ebx, framebuffer;
+ mov ecx, c;
+ movq mm1, mask;
+ lp6:
+ movq mm0, [ebx];
+ psrlq mm0, 3;
+ pand mm0, mm1;
+ movq [ebx], mm0;
+ add ebx, 8;
+ dec ecx;
+ test ecx, ecx;
+ jz end;
+ jmp lp6;
+ }
+ break;
+ }
+ end:
+ __asm emms;
+ return 0;
+}
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_MULT, hwndParent, (DLGPROC)g_DlgProc);
+}
+
+
+char *C_THISCLASS::get_desc(void)
+{
+ static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_MULTIPLIER,desc,128):desc);
+}
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ if (len == sizeof(apeconfig))
+ memcpy(&this->config, data, len);
+ else
+ memset(&this->config, 0, sizeof(apeconfig));
+}
+
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ memcpy(data, &this->config, sizeof(apeconfig));
+ return sizeof(apeconfig);
+}
+
+C_RBASE *R_Multiplier(char *desc)
+{
+ if (desc) {
+ strcpy(desc,MOD_NAME);
+ return NULL;
+ }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_nfclr.cpp b/Src/Plugins/Visualization/vis_avs/r_nfclr.cpp
new file mode 100644
index 00000000..3c5a393c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_nfclr.cpp
@@ -0,0 +1,233 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_NFClearClass
+#define MOD_NAME "Render / OnBeat Clear"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_ONBEAT_CLEAR,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int nf,cf,df;
+
+ int color, blend;
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { nf=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(nf); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ cf=0;
+ nf=1;
+ df=0;
+ color=RGB(255,255,255);
+ blend=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int p=0;
+ char *t=(char *)&visdata[1][0][0];
+ int np=0;
+ if (isBeat&0x80000000) return 0;
+
+ if (isBeat)
+ {
+ if (nf && ++cf >= nf)
+ {
+ cf=df=0;
+ int i=w*h;
+ int c=color;
+ if (!blend) __asm
+ {
+ mov ecx, i
+ mov edi, framebuffer
+ mov eax, c
+ rep stosd
+ }
+ else
+ {
+#ifdef NO_MMX
+ while (i--)
+ {
+ *framebuffer=BLEND_AVG(*framebuffer,color);
+ framebuffer++;
+ }
+#else
+ {
+ int icolor[2]={this->color,this->color};
+ int vc[2] = { ~((1<<7)|(1<<15)|(1<<23)),~((1<<7)|(1<<15)|(1<<23))};
+ i/=4;
+ __asm
+ {
+ movq mm6, vc
+ movq mm7, icolor
+ psrlq mm7, 1
+ pand mm7, mm6
+ mov edx, i
+ mov edi, framebuffer
+ _l1:
+ movq mm0, [edi]
+
+ movq mm1, [edi+8]
+ psrlq mm0, 1
+
+ pand mm0, mm6
+ psrlq mm1, 1
+
+ paddb mm0, mm7
+ pand mm1, mm6
+
+ movq [edi], mm0
+ paddb mm1, mm7
+
+ movq [edi+8], mm1
+ add edi, 16
+ dec edx
+ jnz _l1
+ emms
+ }
+ }
+#endif
+ }
+ }
+ }
+ else if (++df >= nf)
+ {
+ df=0;
+ // memset(framebuffer,0,w*h*4);
+ }
+ return 0;
+}
+
+C_RBASE *R_NFClear(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_BUTTON1:
+ GR_DrawColoredButton(di,g_this->color);
+ break;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,100);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->nf);
+
+ if (g_this->blend) CheckDlgButton(hwndDlg,IDC_BLEND,BST_CHECKED);
+ return 1;
+
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->nf=t;
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+ GR_SelectColor(hwndDlg,&g_this->color);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ }
+ if (LOWORD(wParam) == IDC_BLEND)
+ {
+ if (IsDlgButtonChecked(hwndDlg,IDC_BLEND))
+ g_this->blend=1;
+ else g_this->blend=0;
+ }
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_NFC,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_NFClear(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_onetone.cpp b/Src/Plugins/Visualization/vis_avs/r_onetone.cpp
new file mode 100644
index 00000000..c709dac9
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_onetone.cpp
@@ -0,0 +1,269 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Unique tone"
+#define C_THISCLASS C_OnetoneClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_UNIQUE_TONE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ void RebuildTable(void);
+ int __inline depthof(int c);
+ int enabled;
+ int invert;
+ int color;
+ unsigned char tabler[256];
+ unsigned char tableg[256];
+ unsigned char tableb[256];
+ int blend, blendavg;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ color = 0xFFFFFF;
+ invert=0;
+ blend = 0;
+ blendavg = 0;
+ enabled=1;
+ RebuildTable();
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { invert=GET_INT(); pos+=4; }
+ RebuildTable();
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(invert); pos+=4;
+ return pos;
+}
+
+int __inline C_THISCLASS::depthof(int c)
+{
+int r= max(max((c & 0xFF), ((c & 0xFF00)>>8)), (c & 0xFF0000)>>16);
+return invert ? 255 - r : r;
+}
+
+void C_THISCLASS::RebuildTable(void)
+{
+int i;
+for (i=0;i<256;i++)
+ tableb[i] = (unsigned char)((i / 255.0) * (float)(color & 0xFF));
+for (i=0;i<256;i++)
+ tableg[i] = (unsigned char)((i / 255.0) * (float)((color & 0xFF00) >> 8));
+for (i=0;i<256;i++)
+ tabler[i] = (unsigned char)((i / 255.0) * (float)((color & 0xFF0000) >> 16));
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int i=w*h;
+ int *p=framebuffer;
+ int c,d;
+
+ if (!enabled) return 0;
+ if (isBeat&0x80000000) return 0;
+
+ if (blend)
+ {
+ while (i--)
+ {
+ d = depthof(*p);
+ c = tableb[d] | (tableg[d]<<8) | (tabler[d]<<16);
+ *p++ = BLEND(*p, c);
+ }
+ }
+ else if (blendavg)
+ {
+ while (i--)
+ {
+ d = depthof(*p);
+ c = tableb[d] | (tableg[d]<<8) | (tabler[d]<<16);
+ *p++ = BLEND_AVG(*p, c);
+ }
+ }
+ else
+ {
+ while (i--)
+ {
+ d = depthof(*p);
+ *p++ = tableb[d] | (tableg[d]<<8) | (tabler[d]<<16);
+ }
+ }
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->invert) CheckDlgButton(hwndDlg,IDC_INVERT,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL) // paint nifty color button
+ {
+ int w=di->rcItem.right-di->rcItem.left;
+ int _color=g_ConfigThis->color;
+ _color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) ||
+ (LOWORD(wParam) == IDC_INVERT))
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->invert=IsDlgButtonChecked(hwndDlg,IDC_INVERT)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
+ {
+ int *a=&(g_ConfigThis->color);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ g_ConfigThis->color = *a;
+ g_ConfigThis->RebuildTable();
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_ONETONE,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Onetone(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Onetone(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_oscring.cpp b/Src/Plugins/Visualization/vis_avs/r_oscring.cpp
new file mode 100644
index 00000000..497662bb
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_oscring.cpp
@@ -0,0 +1,356 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+
+#define C_THISCLASS C_OscRingClass
+#define MOD_NAME "Render / Ring"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_RING,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int effect;
+ int num_colors;
+ int colors[16];
+ int size;
+
+ int color_pos;
+ int source;
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { effect=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=1;
+ if (len-pos >= 4) { size=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { source=GET_INT(); pos+=4; }
+
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(effect); pos+=4;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ PUT_INT(size); pos+=4;
+ PUT_INT(source); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ effect=0|(2<<2)|(2<<4);
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+ size=8; // of 16
+ source=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int x;
+ int current_color;
+ unsigned char *fa_data;
+ char center_channel[576];
+ int which_ch=(effect>>2)&3;
+ int y_pos=(effect>>4);
+
+ if (isBeat&0x80000000) return 0;
+ if (!num_colors) return 0;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ if (which_ch>=2)
+ {
+ for (x = 0; x < 576; x ++) center_channel[x]=visdata[source?0:1][0][x]/2+visdata[source?0:1][1][x]/2;
+ }
+ if (which_ch < 2) fa_data=(unsigned char *)&visdata[source?0:1][which_ch][0];
+ else fa_data=(unsigned char *)center_channel;
+
+ {
+ double s=size/32.0;
+#ifdef LASER
+ double lx,ly;
+ double is=s;
+ double c_x;
+ double c_y=0;
+ if (y_pos == 2) c_x = 0;
+ else if (y_pos == 0) c_x=-0.5;
+ else c_x=0.5;
+#else
+ int lx,ly;
+ double is=min((h*s),(w*s));
+ int c_x;
+ int c_y=h/2;
+ if (y_pos == 2) c_x = w/2;
+ else if (y_pos == 0) c_x=(w/4);
+ else c_x=w/2+w/4;
+#endif
+ {
+ int q=0;
+ double a=0.0;
+ double sca;
+ if (!source) sca=0.1 + ((fa_data[q]^128)/255.0)*0.9;
+ else sca=0.1 + ((fa_data[q*2]/2+fa_data[q*2+1]/2)/255.0)*0.9;
+#ifdef LASER
+ int n_seg=4;
+#else
+ int n_seg=1;
+#endif
+ lx=c_x+(int)(cos(a)*is*sca);
+ ly=c_y+(int)(sin(a)*is*sca);
+
+ for (q = 1; q <= 80; q += n_seg)
+ {
+#ifdef LASER
+ double tx,ty;
+#else
+ int tx,ty;
+#endif
+ a -= 3.14159*2.0 / 80.0 * n_seg;
+ if (!source) sca=0.1 + ((fa_data[q>40?80-q:q]^128)/255.0)*0.90;
+ else sca=0.1 + ((fa_data[q>40?(80-q)*2:q*2]/2+fa_data[q>40?(80-q)*2+1:q*2+1]/2)/255.0)*0.9;
+ tx=c_x+(int)(cos(a)*is*sca);
+ ty=c_y+(int)(sin(a)*is*sca);
+#ifdef LASER
+ if ((tx > -1.0 && tx < 1.0 && ty > -1.0 && ty < 1.0) ||
+ (lx > -1.0 && lx < 1.0 && ly > -1.0 && ly < 1.0))
+ {
+ LineType l;
+ l.color=current_color;
+ l.mode=0;
+ l.x1=(float)tx;
+ l.x2=(float)lx;
+ l.y1=(float)ty;
+ l.y2=(float)ly;
+ g_laser_linelist->AddLine(&l);
+ }
+#else
+
+ if ((tx >= 0 && tx < w && ty >= 0 && ty < h) ||
+ (lx >= 0 && lx < w && ly >= 0 && ly < h))
+ {
+ line(framebuffer,tx,ty,lx,ly,w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ }
+#endif
+// line(framebuffer,tx,ty,c_x,c_y,w,h,current_color);
+// if (tx >= 0 && tx < w && ty >= 0 && ty < h) framebuffer[tx+ty*w]=current_color;
+ lx=tx;
+ ly=ty;
+ }
+ }
+ }
+ return 0;
+}
+
+C_RBASE *R_OscRings(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->size=t;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ switch ((g_this->effect>>2)&3)
+ {
+ case 0: CheckDlgButton(hwndDlg,IDC_LEFTCH,BST_CHECKED); break;
+ case 1: CheckDlgButton(hwndDlg,IDC_RIGHTCH,BST_CHECKED); break;
+ case 2: CheckDlgButton(hwndDlg,IDC_MIDCH,BST_CHECKED); break;
+ }
+ switch ((g_this->effect>>4)&3)
+ {
+ case 0: CheckDlgButton(hwndDlg,IDC_TOP,BST_CHECKED); break;
+ case 1: CheckDlgButton(hwndDlg,IDC_BOTTOM,BST_CHECKED); break;
+ case 2: CheckDlgButton(hwndDlg,IDC_CENTER,BST_CHECKED); break;
+ }
+ if (g_this->source)
+ CheckDlgButton(hwndDlg,IDC_SPEC,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_OSC,BST_CHECKED);
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->size);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_OSC: g_this->source=0; break;
+ case IDC_SPEC: g_this->source=1; break;
+ case IDC_LEFTCH: g_this->effect&=~12; break;
+ case IDC_RIGHTCH: g_this->effect&=~12; g_this->effect|=4; break;
+ case IDC_MIDCH: g_this->effect&=~12; g_this->effect|=8; break;
+ case IDC_TOP: g_this->effect&=~48; break;
+ case IDC_BOTTOM: g_this->effect&=~48; g_this->effect|=16; break;
+ case IDC_CENTER: g_this->effect&=~48; g_this->effect|=32; break;
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_OSCRING,hwndParent,g_DlgProc);
+}
diff --git a/Src/Plugins/Visualization/vis_avs/r_oscstar.cpp b/Src/Plugins/Visualization/vis_avs/r_oscstar.cpp
new file mode 100644
index 00000000..1bb37a1b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_oscstar.cpp
@@ -0,0 +1,365 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+
+#define C_THISCLASS C_OscStarClass
+#define MOD_NAME "Render / Oscilliscope Star"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_OSCILLOSCOPE_STAR,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int effect;
+ int num_colors;
+ int colors[16];
+ int size, rot;
+
+ int color_pos;
+ double m_r;
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { effect=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=1;
+ if (len-pos >= 4) { size=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rot=GET_INT(); pos+=4; }
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(effect); pos+=4;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ PUT_INT(size); pos+=4;
+ PUT_INT(rot); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ effect=0|(2<<2)|(2<<4);
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+ m_r=0.0;
+ size=8; // of 16
+ rot=3; // of 16
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int x;
+ int current_color;
+ unsigned char *fa_data;
+ char center_channel[576];
+ int which_ch=(effect>>2)&3;
+ int y_pos=(effect>>4);
+
+ if (isBeat&0x80000000) return 0;
+
+ if (!num_colors) return 0;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ if (which_ch>=2)
+ {
+ for (x = 0; x < 576; x ++) center_channel[x]=visdata[1][0][x]/2+visdata[1][1][x]/2;
+ }
+ if (which_ch < 2) fa_data=(unsigned char *)&visdata[1][which_ch][0];
+ else fa_data=(unsigned char *)center_channel;
+
+ {
+ double s=size/32.0;
+#ifdef LASER
+ double c_x;
+ double is=s;
+ if (y_pos == 2) c_x = 0;
+ else if (y_pos == 0) c_x=-0.5;
+ else c_x=0.5;
+#else
+ int c_x;
+ int is=min((int)(h*s),(int)(w*s));
+ if (y_pos == 2) c_x = w/2;
+ else if (y_pos == 0) c_x=(w/4);
+ else c_x=w/2+w/4;
+#endif
+ {
+ int q,ii=0;
+ for (q = 0; q < 5; q ++)
+ {
+ double s,c;
+ s=sin(m_r+q*(3.14159*2.0/5.0));
+ c=cos(m_r+q*(3.14159*2.0/5.0));
+ double p=0.0;
+#ifdef LASER
+ double lx=c_x;
+ double ly=0.0;
+ int t=6;
+#else
+ if (y_pos == 2) c_x = w/2;
+ else if (y_pos == 0) c_x=(w/4);
+ int lx=c_x;
+ int ly=h/2;
+ int t=64;
+#endif
+ double dp=is/(double)t;
+ double dfactor=1.0/1024.0f;
+ double hw=is;
+ while (t--)
+ {
+ double ale=(((fa_data[ii]^128)-128)*dfactor*hw);
+#ifdef LASER
+ double x,y;
+ ii+=8;
+ x=c_x+(c*p)-(s*ale);
+ y=(s*p)+(c*ale);
+ if ((x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) ||
+ (lx > -1.0 && lx < 1.0 && ly > -.10 && ly < 1.0))
+ {
+ LineType l;
+ l.color=current_color;
+ l.mode=0;
+ l.x1=(float)x;
+ l.x2=(float)lx;
+ l.y1=(float)y;
+ l.y2=(float)ly;
+ g_laser_linelist->AddLine(&l);
+ }
+#else
+ int x,y;
+ ii++;
+ x=c_x+(int)(c*p)-(int)(s*ale);
+ y=h/2+(int)(s*p)+(int)(c*ale);
+ if ((x >= 0 && x < w && y >= 0 && y < h) ||
+ (lx >= 0 && lx < w && ly >= 0 && ly < h))
+ {
+ line(framebuffer,x,y,lx,ly,w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ }
+#endif
+ lx=x;
+ ly=y;
+ p+=dp;
+ dfactor -= ((1.0/1024.0f)-(1.0/128.0f))/64.0f;
+ }
+ }
+
+ m_r+=0.01 * (double)rot;
+ if (m_r >= 3.14159*2)
+ m_r -= 3.14159*2;
+ }
+ }
+ return 0;
+}
+
+C_RBASE *R_OscStars(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={(COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->size=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
+ {
+ g_this->rot=t-16;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ switch ((g_this->effect>>2)&3)
+ {
+ case 0: CheckDlgButton(hwndDlg,IDC_LEFTCH,BST_CHECKED); break;
+ case 1: CheckDlgButton(hwndDlg,IDC_RIGHTCH,BST_CHECKED); break;
+ case 2: CheckDlgButton(hwndDlg,IDC_MIDCH,BST_CHECKED); break;
+ }
+ switch ((g_this->effect>>4)&3)
+ {
+ case 0: CheckDlgButton(hwndDlg,IDC_TOP,BST_CHECKED); break;
+ case 1: CheckDlgButton(hwndDlg,IDC_BOTTOM,BST_CHECKED); break;
+ case 2: CheckDlgButton(hwndDlg,IDC_CENTER,BST_CHECKED); break;
+ }
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->size);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->rot+16);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_LEFTCH: g_this->effect&=~12; break;
+ case IDC_RIGHTCH: g_this->effect&=~12; g_this->effect|=4; break;
+ case IDC_MIDCH: g_this->effect&=~12; g_this->effect|=8; break;
+ case IDC_TOP: g_this->effect&=~48; break;
+ case IDC_BOTTOM: g_this->effect&=~48; g_this->effect|=16; break;
+ case IDC_CENTER: g_this->effect&=~48; g_this->effect|=32; break;
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_OSCSTAR,hwndParent,g_DlgProc);
+}
diff --git a/Src/Plugins/Visualization/vis_avs/r_parts.cpp b/Src/Plugins/Visualization/vis_avs/r_parts.cpp
new file mode 100644
index 00000000..085830dd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_parts.cpp
@@ -0,0 +1,311 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_BPartsClass
+#define MOD_NAME "Render / Moving Particle"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_MOVING_PARTICLE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+
+ int enabled;
+ int colors;
+ int maxdist,size,size2;
+ int blend;
+
+ int s_pos;
+
+
+ double c[2];
+ double v[2];
+ double p[2];
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { colors=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { maxdist=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { size=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { size2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ s_pos=size;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(colors); pos+=4;
+ PUT_INT(maxdist); pos+=4;
+ PUT_INT(size); pos+=4;
+ PUT_INT(size2); pos+=4;
+ PUT_INT(blend); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ blend=1;
+ size=size2=s_pos=8;
+ maxdist=16;
+ enabled=1;
+ colors=RGB(255,255,255);
+ c[0]=c[1]=0.0f;
+ v[0]=-0.01551;
+ v[1]=0.0;
+
+ p[0]=-0.6;
+ p[1]=0.3;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!(enabled&1)) return 0;
+ if (isBeat&0x80000000) return 0;
+ int xp,yp;
+ int ss=min(h/2,(w*3)/8);
+ int oc6 = colors;
+
+ if (isBeat)
+ {
+ c[0]=((rand()%33)-16)/48.0f;
+ c[1]=((rand()%33)-16)/48.0f;
+ }
+
+
+ v[0] -= 0.004*(p[0]-c[0]);
+ v[1] -= 0.004*(p[1]-c[1]);
+
+ p[0]+=v[0];
+ p[1]+=v[1];
+
+ v[0]*=0.991;
+ v[1]*=0.991;
+
+ xp=(int)(p[0]*(ss)*(maxdist/32.0))+w/2;
+ yp=(int)(p[1]*(ss)*(maxdist/32.0))+h/2;
+ if (isBeat && enabled&2)
+ s_pos=size2;
+ int sz=s_pos;
+ s_pos=(s_pos+size)/2;
+ if (sz <= 1)
+ {
+ framebuffer += xp+(yp)*w;
+ if (xp >= 0 && yp >= 0 && xp < w && yp < h)
+ {
+ if (blend==0)
+ framebuffer[0]=colors;
+ else if (blend==2)
+ framebuffer[0]=BLEND_AVG(framebuffer[0],colors);
+ else if (blend==3)
+ BLEND_LINE(framebuffer,colors);
+ else
+ framebuffer[0]=BLEND(framebuffer[0],colors);
+ }
+ return 0;
+ }
+ if (sz > 128) sz=128;
+ {
+ int y;
+ double md=sz*sz*0.25;
+ yp-=sz/2;
+ for (y = 0; y < sz; y ++)
+ {
+ if (yp+y >= 0 && yp+y < h)
+ {
+ double yd=(y-sz*0.5);
+ double l=sqrt(md-yd*yd);
+ int xs=(int)(l+0.99);
+ int x;
+ if (xs < 1) xs=1;
+ int xe=xp + xs;
+ if (xe > w) xe=w;
+ int xst=xp-xs;
+ if (xst < 0) xst=0;
+ int *f=&framebuffer[xst+(yp+y)*w];
+ if (blend == 0) for ( x = xst; x < xe; x ++) *f++=colors;
+ else if (blend == 2)
+ for ( x = xst; x < xe; x ++)
+ {
+ *f=BLEND_AVG(*f,colors);
+ f++;
+ }
+ else if (blend == 3)
+ for ( x = xst; x < xe; x ++)
+ {
+ BLEND_LINE(f++,colors);
+ }
+ else
+ for ( x = xst; x < xe; x ++)
+ {
+ *f=BLEND(*f,colors);
+ f++;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+C_RBASE *R_Parts(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ switch (di->CtlID)
+ {
+ case IDC_LC:
+ GR_DrawColoredButton(di,g_this->colors);
+ break;
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,32);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->maxdist);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETRANGEMAX,0,128);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER3,TBM_SETPOS,1,g_this->size);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMIN,0,1);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETRANGEMAX,0,128);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER4,TBM_SETPOS,1,g_this->size2);
+ if (g_this->enabled&1) CheckDlgButton(hwndDlg,IDC_LEFT,BST_CHECKED);
+ if (g_this->enabled&2) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+
+ if (g_this->blend == 1) CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
+ else if (g_this->blend == 2) CheckDlgButton(hwndDlg,IDC_RADIO3,BST_CHECKED);
+ else if (g_this->blend == 3) CheckDlgButton(hwndDlg,IDC_RADIO4,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
+
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_RADIO1:
+ case IDC_RADIO2:
+ case IDC_RADIO3:
+ case IDC_RADIO4:
+ if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1)) g_this->blend=0;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2)) g_this->blend=1;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO3)) g_this->blend=2;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO4)) g_this->blend=3;
+ break;
+ case IDC_LEFT:
+ g_this->enabled&=~1;
+ g_this->enabled|=IsDlgButtonChecked(hwndDlg,IDC_LEFT)?1:0;
+ return 0;
+ case IDC_CHECK1:
+ g_this->enabled&=~2;
+ g_this->enabled|=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?2:0;
+ return 0;
+ case IDC_LC:
+ if (!a) a=&g_this->colors;
+ GR_SelectColor(hwndDlg,a);
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,FALSE);
+ return 0;
+
+
+ }
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->maxdist=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER3))
+ {
+ g_this->s_pos=g_this->size=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER4))
+ {
+ g_this->s_pos=g_this->size2=t;
+ }
+ }
+ return 0;
+
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_PARTS,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_Parts(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_picture.cpp b/Src/Plugins/Visualization/vis_avs/r_picture.cpp
new file mode 100644
index 00000000..9ff29ec5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_picture.cpp
@@ -0,0 +1,372 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+
+#ifndef LASER
+
+
+#define MOD_NAME "Render / Picture"
+#define C_THISCLASS C_PictureClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_PICTURE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ void loadPicture(char *name);
+ void freePicture();
+
+ int enabled;
+ int width,height;
+ HBITMAP hOldBitmap;
+ HBITMAP hb;
+ HBITMAP hb2;
+ HDC hBitmapDC;
+ HDC hBitmapDC2;
+ int lastWidth,lastHeight;
+ int blend, blendavg, adapt, persist;
+ int ratio,axis_ratio;
+ char ascName[MAX_PATH];
+ int persistCount;
+};
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ persistCount=0;
+ enabled=1;
+ blend=0;
+ adapt=0;
+ blendavg=1;
+ persist=6;
+ strcpy(ascName,"");
+ hb=0; ratio=0; axis_ratio=0;
+ hBitmapDC=0; hBitmapDC2=0;
+}
+C_THISCLASS::~C_THISCLASS()
+{
+ freePicture();
+}
+
+void C_THISCLASS::loadPicture(char *name)
+{
+ freePicture();
+
+ char longName[MAX_PATH];
+ wsprintf(longName,"%s\\%s",g_path,name);
+ hb=(HBITMAP)LoadImage(0,longName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
+
+ BITMAP bm;
+ GetObject(hb, sizeof(bm), (LPSTR)&bm);
+ width=bm.bmWidth;
+ height=bm.bmHeight;
+
+ lastWidth=lastHeight=0;
+}
+void C_THISCLASS::freePicture()
+{
+ if(hb)
+ {
+ DeleteObject(hb);
+ hb=0;
+ }
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { adapt=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { persist=GET_INT(); pos+=4; }
+
+ char *p=ascName;
+ while (data[pos] && len-pos > 0) *p++=data[pos++];
+ *p=0; pos++;
+
+ if (len-pos >= 4) { ratio=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { axis_ratio=GET_INT(); pos+=4; }
+
+ if (*ascName)
+ loadPicture(ascName);
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(adapt); pos+=4;
+ PUT_INT(persist); pos+=4;
+ strcpy((char *)data+pos, ascName);
+ pos+=strlen(ascName)+1;
+ PUT_INT(ratio); pos+=4;
+ PUT_INT(axis_ratio); pos+=4;
+ return pos;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+
+ if (!enabled) return 0;
+
+ if (!width || !height) return 0;
+
+
+ if (lastWidth != w || lastHeight != h)
+ {
+ lastWidth = w;
+ lastHeight = h;
+
+ if(hBitmapDC2) {
+ DeleteDC(hBitmapDC2);
+ DeleteObject(hb2);
+ hBitmapDC2=0;
+ }
+
+ // Copy the bitmap from hBitmapDC to hBitmapDC2 and stretch it
+ hBitmapDC = CreateCompatibleDC (NULL);
+ hOldBitmap = (HBITMAP) SelectObject (hBitmapDC, hb);
+ hBitmapDC2 = CreateCompatibleDC (NULL);
+ hb2=CreateCompatibleBitmap (hBitmapDC, w, h);
+ SelectObject(hBitmapDC2,hb2);
+ {
+ HBRUSH b=CreateSolidBrush(0);
+ HPEN p=CreatePen(PS_SOLID,0,0);
+ HBRUSH bold;
+ HPEN pold;
+ bold=(HBRUSH)SelectObject(hBitmapDC2,b);
+ pold=(HPEN)SelectObject(hBitmapDC2,p);
+ Rectangle(hBitmapDC2,0,0,w,h);
+ SelectObject(hBitmapDC2,bold);
+ SelectObject(hBitmapDC2,pold);
+ DeleteObject(b);
+ DeleteObject(p);
+ }
+ SetStretchBltMode(hBitmapDC2,COLORONCOLOR);
+ int final_height=h,start_height=0;
+ int final_width=w,start_width=0;
+ if (ratio)
+ {
+ if(axis_ratio==0) {
+ // ratio on X axis
+ final_height=height*w/width;
+ start_height=(h/2)-(final_height/2);
+ } else {
+ // ratio on Y axis
+ final_width=width*h/height;
+ start_width=(w/2)-(final_width/2);
+ }
+ }
+ StretchBlt(hBitmapDC2,start_width,start_height,final_width,final_height,hBitmapDC,0,0,width,height,SRCCOPY);
+ DeleteDC(hBitmapDC);
+ hBitmapDC=0;
+ }
+ if (isBeat&0x80000000) return 0;
+
+ // Copy the stretched bitmap to fbout
+ BITMAPINFO bi;
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = w;
+ bi.bmiHeader.biHeight = h;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 0;
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+ bi.bmiHeader.biClrImportant = 0;
+ GetDIBits(hBitmapDC2, hb2, 0, h, (void *)fbout, &bi, DIB_RGB_COLORS);
+
+ // Copy the bitmap from fbout to framebuffer applying replace/blend/etc...
+ if (isBeat)
+ persistCount=persist;
+ else
+ if (persistCount>0) persistCount--;
+
+ int *p,*d;
+ int i,j;
+
+ p = fbout;
+ d = framebuffer+w*(h-1);
+ if (blend || (adapt && (isBeat || persistCount)))
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ *d=BLEND(*p, *d);
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+ else
+ if (blendavg || adapt)
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ *d=BLEND_AVG(*p, *d);
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+ else
+ for (i=0;i<h;i++)
+ {
+ memcpy(d, p, w*4);
+ p+=w;
+ d-=w;
+ }
+
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+static void EnableWindows(HWND hwndDlg)
+{
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST),g_ConfigThis->adapt);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST_TITLE),g_ConfigThis->adapt);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST_TEXT1),g_ConfigThis->adapt);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_PERSIST_TEXT2),g_ConfigThis->adapt);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_X_RATIO),g_ConfigThis->ratio);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_Y_RATIO),g_ConfigThis->ratio);
+}
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_SETRANGE, TRUE, MAKELONG(0, 32));
+ SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_SETPOS, TRUE, g_ConfigThis->persist);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_ENABLED,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (g_ConfigThis->adapt) CheckDlgButton(hwndDlg,IDC_ADAPT,BST_CHECKED);
+ if (!g_ConfigThis->adapt && !g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ if (g_ConfigThis->ratio) CheckDlgButton(hwndDlg,IDC_RATIO,BST_CHECKED);
+ if (!g_ConfigThis->axis_ratio) CheckDlgButton(hwndDlg,IDC_X_RATIO,BST_CHECKED);
+ if (g_ConfigThis->axis_ratio) CheckDlgButton(hwndDlg,IDC_Y_RATIO,BST_CHECKED);
+ EnableWindows(hwndDlg);
+ loadComboBox(GetDlgItem(hwndDlg,OBJ_COMBO),"*.BMP",g_ConfigThis->ascName);
+ return 1;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_PERSIST)
+ g_ConfigThis->persist = SendDlgItemMessage(hwndDlg, IDC_PERSIST, TBM_GETPOS, 0, 0);
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_ENABLED) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_ADAPT) ||
+ (LOWORD(wParam) == IDC_5050) ) {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_ENABLED)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ g_ConfigThis->adapt=IsDlgButtonChecked(hwndDlg,IDC_ADAPT)?1:0;
+ EnableWindows(hwndDlg);
+ }
+ if(LOWORD(wParam) == IDC_RATIO || LOWORD(wParam) == IDC_X_RATIO || LOWORD(wParam) == IDC_Y_RATIO) {
+ g_ConfigThis->ratio=IsDlgButtonChecked(hwndDlg,IDC_RATIO)?1:0;
+ g_ConfigThis->axis_ratio=IsDlgButtonChecked(hwndDlg,IDC_Y_RATIO)?1:0;
+ g_ConfigThis->lastWidth=-1; g_ConfigThis->lastHeight=-1;
+ EnableWindows(hwndDlg);
+ }
+ if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == OBJ_COMBO) // handle clicks to combo box
+ {
+ int sel = SendDlgItemMessage(hwndDlg, OBJ_COMBO, CB_GETCURSEL, 0, 0);
+ if (sel != -1)
+ {
+ SendDlgItemMessage(hwndDlg, OBJ_COMBO, CB_GETLBTEXT, sel, (LPARAM)g_ConfigThis->ascName);
+ if (*(g_ConfigThis->ascName))
+ g_ConfigThis->loadPicture(g_ConfigThis->ascName);
+ }
+ }
+ return 0;
+ case WM_HSCROLL:
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_PICTURE,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Picture(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Picture(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_rotblit.cpp b/Src/Plugins/Visualization/vis_avs/r_rotblit.cpp
new file mode 100644
index 00000000..97ee2a05
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_rotblit.cpp
@@ -0,0 +1,327 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+
+#ifndef LASER
+
+#include <math.h>
+#define M_PI 3.1415926536
+
+#define C_THISCLASS C_RotBlitClass
+#define MOD_NAME "Trans / Roto Blitter"
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_ROTO_BLITTER,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int zoom_scale, rot_dir, blend, beatch, beatch_speed, zoom_scale2, beatch_scale,scale_fpos;
+ int rot_rev;
+ int subpixel;
+ double rot_rev_pos;
+
+ int l_w, l_h;
+ int *w_mul;
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { zoom_scale=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rot_dir=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatch=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatch_speed=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { zoom_scale2=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { beatch_scale=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
+ else subpixel=0;
+
+ scale_fpos=zoom_scale;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(zoom_scale); pos+=4;
+ PUT_INT(rot_dir); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(beatch); pos+=4;
+ PUT_INT(beatch_speed); pos+=4;
+ PUT_INT(zoom_scale2); pos+=4;
+ PUT_INT(beatch_scale); pos+=4;
+ PUT_INT(subpixel); pos+=4;
+ return pos;
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ zoom_scale=31;
+ rot_dir=31;
+ blend=0;
+ rot_rev=1;
+ rot_rev_pos=1.0;
+ beatch=0;
+ l_w=l_h=0;
+ w_mul=NULL;
+ beatch_speed=0;
+ beatch_scale=0;
+ zoom_scale2=31;
+ scale_fpos=zoom_scale;
+ subpixel=1;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ if (w_mul) GlobalFree(w_mul);
+ w_mul=NULL;
+ l_w=l_h=0;
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int y;
+
+ if (l_w != w || l_h != h || !w_mul) // generate width table
+ {
+ int x;
+ if (w_mul) GlobalFree(w_mul);
+ l_w=w;
+ l_h=h;
+ w_mul=(int *)GlobalAlloc(GMEM_FIXED,sizeof(int)*h);
+ for (x = 0; x < h; x ++)
+ w_mul[x]=x*w;
+ }
+ if (isBeat&0x80000000) return 0;
+
+ unsigned int *dest=(unsigned int *) fbout;
+ unsigned int *src=(unsigned int *) framebuffer;
+ unsigned int *bdest=(unsigned int *) framebuffer;
+
+ if (isBeat && beatch)
+ {
+ rot_rev=-rot_rev;
+ }
+
+ if (!beatch) rot_rev=1;
+
+ rot_rev_pos+=(1.0/(1+beatch_speed*4))*(rot_rev-rot_rev_pos);
+
+ if (rot_rev_pos > rot_rev && rot_rev>0) rot_rev_pos=rot_rev;
+ if (rot_rev_pos < rot_rev && rot_rev<0) rot_rev_pos=rot_rev;
+
+
+ if (isBeat && beatch_scale)
+ {
+ scale_fpos=zoom_scale2;
+ }
+
+ int f_val;
+ if (zoom_scale < zoom_scale2)
+ {
+ f_val=max(scale_fpos,zoom_scale);
+ if (scale_fpos > zoom_scale) scale_fpos -= 3;
+ }
+ else
+ {
+ f_val=min(scale_fpos,zoom_scale);
+ if (scale_fpos < zoom_scale) scale_fpos+=3;
+ }
+
+ double zoom = 1.0 + (f_val-31)/31.0;
+
+ double theta=((rot_dir-32))*rot_rev_pos;
+ double temp;
+ int ds_dx, dt_dx, ds_dy, dt_dy, s, t, sstart, tstart;
+ int x, offset=0;
+
+ temp = cos((theta)*M_PI/180.0)*zoom;
+ ds_dx = (int) (temp*65536.0);
+ dt_dy = (int) (temp*65536.0);
+ temp = sin((theta)*M_PI/180.0)*zoom;
+ ds_dy = - (int) (temp*65536.0);
+ dt_dx = (int) (temp*65536.0);
+
+ s = sstart = -(((w-1)/2)*ds_dx + ((h-1)/2)*ds_dy) + (w-1)*(32768 + (1<<20));
+ t = tstart = -(((w-1)/2)*dt_dx + ((h-1)/2)*dt_dy) + (h-1)*(32768 + (1<<20));
+ int ds, dt;
+ ds = (w-1)<<16;
+ dt = (h-1)<<16;
+ y = h;
+
+ if (ds_dx <= -ds || ds_dx >= ds || dt_dx <= -dt || dt_dx >= dt);
+ else while (y--)
+ {
+ if (ds) s %= ds;
+ if (dt) t %= dt;
+ if (s < 0) s+=ds; if (t < 0) t+=dt;
+ x = w;
+ offset = y*w;
+
+
+#define DO_LOOP(Z) while (x--) { Z; s += ds_dx; t += dt_dx; }
+#define DO_LOOPS(Z) \
+ if (ds_dx <= 0 && dt_dx <= 0) DO_LOOP(if (t < 0) t += dt; if (s < 0) s += ds; Z) \
+ else if (ds_dx <= 0) DO_LOOP(if (t >= dt) t -= dt; if (s < 0) s += ds; Z) \
+ else if (dt_dx <= 0) DO_LOOP(if (t < 0) t += dt; if (s >= ds) s -= ds; Z) \
+ else DO_LOOP(if (t >= dt) t -= dt; if (s >= ds) s -= ds; Z)
+
+
+ if (subpixel && blend) DO_LOOPS(*dest++ = BLEND_AVG(*bdest++,BLEND4_16(src+(s>>16)+w_mul[t>>16],w,s,t)))
+ else if (subpixel) DO_LOOPS(*dest++ = BLEND4_16(src+(s>>16)+w_mul[t>>16],w,s,t))
+ else if (!blend) DO_LOOPS(*dest++ = src[(s>>16)+w_mul[t>>16]])
+ else DO_LOOPS(*dest++ = BLEND_AVG(*bdest++,src[(s>>16)+w_mul[t>>16]]))
+
+ s = (sstart += ds_dy);
+ t = (tstart += dt_dy);
+ }
+#ifndef NO_MMX
+ __asm emms;
+#endif
+
+ return 1;
+}
+
+C_RBASE *R_RotBlit(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGEMAX,0,256);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_this->zoom_scale);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETRANGEMAX,0,256);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER6,TBM_SETPOS,1,g_this->zoom_scale2);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETRANGEMAX,0,8);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER5,TBM_SETPOS,1,g_this->beatch_speed);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMIN,0,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETRANGEMAX,0,64);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER2,TBM_SETPOS,1,g_this->rot_dir);
+ if (g_this->subpixel) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ else if (g_this->blend==1) CheckDlgButton(hwndDlg,IDC_BLEND,BST_CHECKED);
+ if (g_this->beatch==1) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_this->beatch_scale==1) CheckDlgButton(hwndDlg,IDC_CHECK6,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_BLEND:
+ if (IsDlgButtonChecked(hwndDlg,IDC_BLEND))
+ {
+ g_this->blend=1;
+ }
+ else g_this->blend=0;
+ break;
+ case IDC_CHECK1:
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1))
+ g_this->beatch=1;
+ else g_this->beatch=0;
+ break;
+ case IDC_CHECK2:
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK2))
+ {
+ g_this->subpixel=1;
+ }
+ else g_this->subpixel=0;
+ break;
+ case IDC_CHECK6:
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK6))
+ g_this->beatch_scale=1;
+ else g_this->beatch_scale=0;
+ break;
+ }
+ return 0;
+
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER1))
+ {
+ g_this->zoom_scale=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER6))
+ {
+ g_this->zoom_scale2=t;
+ g_this->scale_fpos=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER2))
+ {
+ g_this->rot_dir=t;
+ }
+ if (swnd == GetDlgItem(hwndDlg,IDC_SLIDER5))
+ {
+ g_this->beatch_speed=t;
+ }
+ }
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_ROTBLT,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_RotBlit(char *desc)
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_rotstar.cpp b/Src/Plugins/Visualization/vis_avs/r_rotstar.cpp
new file mode 100644
index 00000000..dd3c038e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_rotstar.cpp
@@ -0,0 +1,271 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include "r_defs.h"
+
+#include <math.h>
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_RotStarClass
+#define MOD_NAME "Render / Rotating Stars"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_ROTATING_STARS,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int num_colors;
+ int colors[16];
+
+ int color_pos;
+ double r1;
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=0;
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ r1=0.0;
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int x,y,c;
+ int current_color;
+
+ if (isBeat&0x80000000) return 0;
+ if (!num_colors) return 0;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ x=(int) (cos(r1)*w/4.0);
+ y=(int) (sin(r1)*h/4.0);
+ for (c = 0; c < 2; c ++)
+ {
+ double r2=-r1;
+ int s=0;
+ int t;
+ int a,b;
+ int nx, ny;
+ int lx,ly,l;
+ a=x;
+ b=y;
+
+ for (l = 3; l < 14; l ++)
+ if (visdata[0][c][l] > s &&
+ visdata[0][c][l] > visdata[0][c][l+1]+4 &&
+ visdata[0][c][l] > visdata[0][c][l-1]+4)
+ s=visdata[0][c][l];
+
+ if (c==1) { a=-a; b=-b; }
+
+ double vw,vh;
+ vw=w/8.0*(s+9)/88.0;
+ vh=h/8.0*(s+9)/88.0;
+
+ nx=(int) (cos(r2)*vw);
+ ny=(int) (sin(r2)*vh);
+ lx = w/2+a+nx;
+ ly = h/2+b+ny;
+
+ r2+=3.14159*4.0/5.0;
+
+ for (t = 0; t < 5; t ++)
+ {
+ int nx, ny;
+ nx=(int) (cos(r2)*vw+w/2+a);
+ ny=(int) (sin(r2)*vh+h/2+b);
+ r2+=3.14159*4.0/5.0;
+ line(framebuffer,lx,ly,nx,ny,w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ lx=nx;
+ ly=ny;
+ }
+ }
+ r1+=0.1;
+ return 0;
+}
+
+C_RBASE *R_RotStar(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={(COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_ROTSTAR,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_RotStar(char *desc)
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_scat.cpp b/Src/Plugins/Visualization/vis_avs/r_scat.cpp
new file mode 100644
index 00000000..99c9f0f6
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_scat.cpp
@@ -0,0 +1,161 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_ScatClass
+#define MOD_NAME "Trans / Scatter"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_SCATTER,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int enabled;
+ int fudgetable[512],ftw;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ enabled=1;
+ ftw=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int l;
+ if (!enabled) return 0;
+ if (ftw != w)
+ {
+ int x;
+ for (x = 0; x < 512; x ++)
+ {
+ int yp;
+ int xp;
+ xp=(x%8)-4;
+ yp=(x/8)%8-4;
+ if (xp<0) xp++;
+ if (yp<0) yp++;
+ fudgetable[x]=w*yp+xp;
+ }
+ ftw=w;
+
+ }
+ if (isBeat&0x80000000) return 0;
+
+ l=w*4;
+ while (l-- > 0) *fbout++=*framebuffer++;
+ l=w*(h-8);
+ while (l-- > 0)
+ {
+ *fbout++ = framebuffer[fudgetable[rand()&511]];
+ framebuffer++;
+ }
+ l=w*4;
+ while (l-- > 0) *fbout++=*framebuffer++;
+
+
+ return 1;
+}
+
+C_RBASE *R_Scat(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_this->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_CHECK1)
+ {
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1))
+ g_this->enabled=1;
+ else
+ g_this->enabled=0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_SCAT,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_Scat(char *desc)
+{return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_shift.cpp b/Src/Plugins/Visualization/vis_avs/r_shift.cpp
new file mode 100644
index 00000000..3fcced02
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_shift.cpp
@@ -0,0 +1,391 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "avs_eelif.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+
+#ifndef LASER
+
+#define C_THISCLASS C_ShiftClass
+#define MOD_NAME "Trans / Dynamic Shift"
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_DYNAMIC_SHIFT,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ RString effect_exp[3];
+ int blend,subpixel;
+
+ int m_lastw,m_lasth;
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ double *var_x, *var_y, *var_w, *var_h, *var_b, *var_alpha;
+ double max_d;
+ int inited;
+ NSEEL_CODEHANDLE codehandle[3];
+ int need_recompile;
+ CRITICAL_SECTION rcs;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (data[pos] == 1)
+ {
+ pos++;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ load_string(effect_exp[2],data,pos,len);
+ }
+ else
+ {
+ char buf[769];
+ if (len-pos >= 768)
+ {
+ memcpy(buf,data+pos,768);
+ pos+=768;
+ buf[768]=0;
+ effect_exp[2].assign(buf+512);
+ buf[512]=0;
+ effect_exp[1].assign(buf+256);
+ buf[256]=0;
+ effect_exp[0].assign(buf);
+ }
+ }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
+
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ data[pos++]=1;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ save_string(data,pos,effect_exp[2]);
+ PUT_INT(blend); pos+=4;
+ PUT_INT(subpixel); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ InitializeCriticalSection(&rcs);
+ AVS_EEL_INITINST();
+
+ memset(codehandle,0,sizeof(codehandle));
+ m_lasth=m_lastw=0;
+
+ effect_exp[0].assign("d=0;"); // init
+ effect_exp[1].assign("x=sin(d)*1.4; y=1.4*cos(d); d=d+0.01;"); // frame
+ effect_exp[2].assign("d=d+2.0");
+ blend=0;
+ subpixel=1;
+
+ need_recompile=1;
+ var_b=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ int x;
+ for (x = 0; x < 3; x ++)
+ {
+ freeCode(codehandle[x]);
+ }
+ AVS_EEL_QUITINST();
+
+ DeleteCriticalSection(&rcs);
+}
+
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ //pow(sin(d),dpos)*1.7
+ if (need_recompile)
+ {
+ int err=0;
+ int x;
+ EnterCriticalSection(&rcs);
+ if (!var_b || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_x = registerVar("x");
+ var_y = registerVar("y");
+ var_w = registerVar("w");
+ var_h = registerVar("h");
+ var_b = registerVar("b");
+ var_alpha = registerVar("alpha");
+ inited=0;
+ }
+ need_recompile=0;
+ for (x = 0; x < 3; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=compileCode(effect_exp[x].get());
+ }
+ LeaveCriticalSection(&rcs);
+ }
+ *var_w=w;
+ *var_h=h;
+ *var_b=isBeat?1.0:0.0;
+
+ if (isBeat&0x80000000) return 0;
+
+ if (codehandle[0] && (!inited || m_lasth != h || m_lastw != w))
+ {
+ m_lastw=w;
+ m_lasth=h;
+ *var_x=0; *var_y=0; *var_alpha=0.5;
+ executeCode(codehandle[0],visdata);
+ inited=1;
+ }
+
+ executeCode(codehandle[1],visdata);
+ if (isBeat) executeCode(codehandle[2],visdata);
+
+ int doblend=blend;
+ int ialpha=127;
+ if (doblend)
+ {
+ ialpha=(int)(*var_alpha*255.0);
+ if (ialpha <= 0) return 0;
+ if (ialpha >= 255) doblend=0;
+ }
+ int *inptr=framebuffer;
+ int *blendptr=framebuffer;
+ int *outptr=fbout;
+ int xa=(int)*var_x;
+ int ya=(int)*var_y;
+
+ // var_x, var_y at this point tell us how to shift, and blend also tell us what to do.
+ if (!subpixel)
+ {
+ int endy=h+ya;
+ int endx=w+xa;
+ int x,y;
+ if (endx > w) endx=w;
+ if (endy > h) endy=h;
+ if (ya < 0) inptr += -ya*w;
+ if (ya > h) ya=h;
+ if (xa > w) xa=w;
+ for (y = 0; y < ya; y ++)
+ {
+ x=w;
+ if (!doblend) while (x--) *outptr++ = 0;
+ else while (x--) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ }
+ for (; y < endy; y ++)
+ {
+ int *ip=inptr;
+ if (xa < 0) inptr += -xa;
+ if (!doblend)
+ {
+ for (x = 0; x < xa; x ++) *outptr++=0;
+ for (; x < endx; x ++) *outptr++=*inptr++;
+ for (; x < w; x ++) *outptr++=0;
+ }
+ else
+ {
+ for (x = 0; x < xa; x ++) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ for (; x < endx; x ++) *outptr++ = BLEND_ADJ(*inptr++,*blendptr++,ialpha);
+ for (; x < w; x ++) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ }
+ inptr=ip+w;
+ }
+ for (; y < h; y ++)
+ {
+ x=w;
+ if (!doblend) while (x--) *outptr++ = 0;
+ else while (x--) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ }
+ }
+ else // bilinear filtering version
+ {
+
+ int xpart,ypart;
+
+ {
+ double vx=*var_x;
+ double vy=*var_y;
+ xpart=(int) ((vx - (int)vx)*255.0);
+ if (xpart < 0) xpart=-xpart;
+ else { xa++; xpart=255-xpart; }
+ if (xpart < 0) xpart=0;
+ if (xpart > 255) xpart=255;
+
+ ypart=(int) ((vy - (int)vy)*255.0);
+ if (ypart < 0) ypart=-ypart;
+ else { ya++; ypart=255-ypart; }
+ if (ypart < 0) ypart=0;
+ if (ypart > 255) ypart=255;
+ }
+
+ int x,y;
+ if (ya < 1-h) ya=1-h;
+ if (xa < 1-w) xa=1-w;
+ if (ya > h-1) ya=h-1;
+ if (xa > w-1) xa=w-1;
+ if (ya < 0) inptr += -ya*w;
+ int endy=h-1+ya;
+ int endx=w-1+xa;
+ if (endx > w-1) endx=w-1;
+ if (endy > h-1) endy=h-1;
+ if (endx < 0) endx=0;
+ if (endy < 0) endy=0;
+ for (y = 0; y < ya; y ++)
+ {
+ x=w;
+ if (!doblend) while (x--) *outptr++ = 0;
+ else while (x--) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ }
+ for (; y < endy; y ++)
+ {
+ int *ip=inptr;
+ if (xa < 0) inptr += -xa;
+ if (!doblend)
+ {
+ for (x = 0; x < xa; x ++) *outptr++=0;
+ for (; x < endx; x ++) *outptr++=BLEND4((unsigned int *)inptr++,w,xpart,ypart);
+ for (; x < w; x ++) *outptr++=0;
+ }
+ else
+ {
+ for (x = 0; x < xa; x ++) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ for (; x < endx; x ++) *outptr++ = BLEND_ADJ(BLEND4((unsigned int *)inptr++,w,xpart,ypart),*blendptr++,ialpha);
+ for (; x < w; x ++) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ }
+ inptr=ip+w;
+ }
+ for (; y < h; y ++)
+ {
+ x=w;
+ if (!doblend) while (x--) *outptr++ = 0;
+ else while (x--) *outptr++ = BLEND_ADJ(0,*blendptr++,ialpha);
+ }
+ }
+ #ifndef NO_MMX
+ __asm emms;
+ #endif
+
+ return 1;
+}
+
+C_RBASE *R_Shift(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ isstart=0;
+ if (g_this->blend)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_this->subpixel)
+ CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_HELPBTN)
+ {
+ char *text="Dynamic Shift\0"
+ "better Dynamic shift help goes here (send me some :)\r\n";
+ "Variables:\r\n"
+ "x,y = amount to shift (in pixels - set these)\r\n"
+ "w,h = width, height (in pixels)\r\n"
+ "b = isBeat\r\n"
+ "alpha = alpha value (0.0-1.0) for blend\r\n"
+ ;
+ compilerfunctionlist(hwndDlg,text);
+ }
+ if (LOWORD(wParam)==IDC_CHECK1)
+ {
+ g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_CHECK2)
+ {
+ g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
+ }
+ if (!isstart && (LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3) && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
+ g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
+ g_this->need_recompile=1;
+ if (LOWORD(wParam) == IDC_EDIT1) g_this->inited = 0;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_SHIFT,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_Shift(char *desc)
+{
+ return NULL;
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_simple.cpp b/Src/Plugins/Visualization/vis_avs/r_simple.cpp
new file mode 100644
index 00000000..4d910a6f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_simple.cpp
@@ -0,0 +1,427 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include "r_defs.h"
+
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_SimpleClass
+#define MOD_NAME "Render / Simple"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_SIMPLE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int effect;
+ int num_colors;
+ int colors[16];
+
+ int color_pos;
+
+};
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (len-pos >= 4) { effect=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=0;
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0,x=0;
+ PUT_INT(effect); pos+=4;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ effect=0|(2<<2)|(2<<4);
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!num_colors) return 0;
+ if (isBeat&0x80000000) return 0;
+ int x;
+ float yscale = (float) h / 2.0f / 256.0f;
+ float xscale = 288.0f/w;
+ int current_color;
+ unsigned char *fa_data;
+ char center_channel[576];
+ int which_ch=(effect>>2)&3;
+ int y_pos=(effect>>4)&3;
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ if (which_ch>=2)
+ {
+ int w=0;
+ if ((effect&3)>1)
+ w=1;
+
+ for (x = 0; x < 576; x ++) center_channel[x]=visdata[w][0][x]/2+visdata[w][1][x]/2;
+ }
+ if (which_ch < 2) fa_data=(unsigned char *)&visdata[(effect&3)>1?1:0][which_ch][0];
+ else fa_data=(unsigned char *)center_channel;
+
+ if (effect&(1<<6))
+ {
+ switch (effect&2)
+ {
+ case 2: // dot scope
+ {
+ int yh = y_pos*h / 2;
+ if (y_pos==2) yh=h/4;
+ int ys = yh+(int)(yscale*128.0f);
+ for (x = 0; x < w; x ++)
+ {
+ float r=x*xscale;
+ float s1=r-(int)r;
+ float yr=(fa_data[(int)r]^128)*(1.0f-s1)+(fa_data[(int)r+1]^128)*(s1);
+ int y=yh + (int) (yr*yscale);
+ if (y >= 0 && y < h) framebuffer[x+y*w]=current_color;
+ }
+ }
+ break;
+ case 0: // dot analyzer
+ {
+ int h2=h/2;
+ float ys=yscale;
+ float xs=200.0f/w;
+ int adj=1;
+ if (y_pos!=1) { ys=-ys; adj=0; }
+ if (y_pos==2)
+ {
+ h2 -= (int) (ys*256/2);
+ }
+ for (x = 0; x < w; x ++)
+ {
+ float r=x*xs;
+ float s1=r-(int)r;
+ float yr=fa_data[(int)r]*(1.0f-s1)+fa_data[(int)r+1]*(s1);
+ int y=h2+adj+(int)(yr*ys-1.0f);
+ if (y >= 0 && y < h) framebuffer[x+w*y]=current_color;
+ }
+ }
+ break;
+ }
+ }
+ else
+ switch (effect&3)
+ {
+ case 0: //solid analyzer
+ {
+ int h2=h/2;
+ float ys=yscale;
+ float xs=200.0f/w;
+ int adj=1;
+ if (y_pos!=1) { ys=-ys; adj=0; }
+ if (y_pos==2)
+ {
+ h2 -= (int) (ys*256/2);
+ }
+ for (x = 0; x < w; x ++)
+ {
+ float r=x*xs;
+ float s1=r-(int)r;
+ float yr=fa_data[(int)r]*(1.0f-s1)+fa_data[(int)r+1]*(s1);
+ line(framebuffer,x,h2-adj,x,h2 + adj + (int) (yr*ys - 1.0f),w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ }
+ }
+ break;
+ case 1: // line analyzer
+ {
+ int yh = 0;
+ int h2=h/2;
+ int lx,ly,ox,oy;
+ float xs= 1.0f/xscale*(288.0f/200.f);
+ float ys=yscale;
+ if (y_pos!=1) { ys=-ys; }
+ if (y_pos == 2)
+ h2 -= (int) (ys*256/2);
+
+ ly=h2 + (int) ((fa_data[0])*ys);
+ lx=0;
+ for (x = 1; x < 200; x ++)
+ {
+ oy=h2 + (int) ((fa_data[x])*ys);
+ ox=(int) (x*xs);
+ line(framebuffer,lx,ly,ox,oy,w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ ly=oy;
+ lx=ox;
+ }
+ }
+ break;
+ case 2: // line scope
+ {
+ float xs = 1.0f/xscale;
+ int lx, ly,ox,oy;
+ int yh;
+ if (y_pos == 2)
+ yh = h/4;
+ else yh = y_pos*h/ 2;
+ lx=0;
+ ly=yh + (int) ((int)(fa_data[0]^128)*yscale);;
+ for (x = 1; x < 288; x ++)
+ {
+ ox=(int)(x*xs);
+ oy = yh + (int) ((int)(fa_data[x]^128)*yscale);
+ line(framebuffer, lx,ly,ox,oy,w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ lx=ox;
+ ly=oy;
+ }
+ }
+ break;
+ case 3: // solid scope
+ {
+ int yh = y_pos*h / 2;
+ if (y_pos==2) yh=h/4;
+ int ys = yh+(int)(yscale*128.0f);
+ for (x = 0; x < w; x ++)
+ {
+ float r=x*xscale;
+ float s1=r-(int)r;
+ float yr=(fa_data[(int)r]^128)*(1.0f-s1)+(fa_data[(int)r+1]^128)*(s1);
+ line(framebuffer,x,ys-1,x,yh + (int) (yr*yscale),w,h,current_color,(g_line_blend_mode&0xff0000)>>16);
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+C_RBASE *R_SimpleSpectrum(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ const static int chex[8]=
+ {
+ IDC_SA,IDC_SOLID,
+ IDC_SA,IDC_LINES,
+ IDC_OSC,IDC_LINES,
+ IDC_OSC,IDC_SOLID,
+ };
+ int *a=NULL;
+ switch (uMsg)
+ {
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={(COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_INITDIALOG:
+ if ((g_this->effect>>6)&1)
+ {
+ CheckDlgButton(hwndDlg,IDC_DOT,BST_CHECKED);
+ if (g_this->effect&2)
+ CheckDlgButton(hwndDlg,IDC_OSC,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_SA,BST_CHECKED);
+ }
+ else
+ {
+ CheckDlgButton(hwndDlg,chex[(g_this->effect&3)*2],BST_CHECKED);
+ CheckDlgButton(hwndDlg,chex[(g_this->effect&3)*2+1],BST_CHECKED);
+ }
+
+ switch ((g_this->effect>>2)&3)
+ {
+ case 0: CheckDlgButton(hwndDlg,IDC_LEFTCH,BST_CHECKED); break;
+ case 1: CheckDlgButton(hwndDlg,IDC_RIGHTCH,BST_CHECKED); break;
+ case 2: CheckDlgButton(hwndDlg,IDC_MIDCH,BST_CHECKED); break;
+ }
+ switch ((g_this->effect>>4)&3)
+ {
+ case 0: CheckDlgButton(hwndDlg,IDC_TOP,BST_CHECKED); break;
+ case 1: CheckDlgButton(hwndDlg,IDC_BOTTOM,BST_CHECKED); break;
+ case 2: CheckDlgButton(hwndDlg,IDC_CENTER,BST_CHECKED); break;
+ }
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_DOT: case IDC_SA: case IDC_SOLID: case IDC_OSC: case IDC_LINES:
+ if (!IsDlgButtonChecked(hwndDlg,IDC_DOT))
+ {
+ int c;
+
+ g_this->effect &= ~(1<<6);
+ for (c = 0; c < 4; c ++)
+ {
+ if (IsDlgButtonChecked(hwndDlg,chex[c*2]) && IsDlgButtonChecked(hwndDlg,chex[c*2+1])) break;
+ }
+ if (c!=4) { g_this->effect&=~3; g_this->effect|=c;}
+ }
+ else
+ {
+ g_this->effect&=~3;
+ if (!IsDlgButtonChecked(hwndDlg,IDC_SA)) g_this->effect|=2;
+ g_this->effect |= 1<<6;
+ }
+ break;
+ case IDC_LEFTCH: g_this->effect&=~12; break;
+ case IDC_RIGHTCH: g_this->effect&=~12; g_this->effect|=4; break;
+ case IDC_MIDCH: g_this->effect&=~12; g_this->effect|=8; break;
+ case IDC_TOP: g_this->effect&=~48; break;
+ case IDC_BOTTOM: g_this->effect&=~48; g_this->effect|=16; break;
+ case IDC_CENTER: g_this->effect&=~48; g_this->effect|=32; break;
+ case IDC_NUMCOL:
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ break;
+ case IDC_DEFCOL:
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_SIMPLE,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_SimpleSpectrum(char *desc)
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_sscope.cpp b/Src/Plugins/Visualization/vis_avs/r_sscope.cpp
new file mode 100644
index 00000000..c466db2e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_sscope.cpp
@@ -0,0 +1,595 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#define M_PI 3.14159265358979323846
+
+#include <windows.h>
+#include <commctrl.h>
+#include <math.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "avs_eelif.h"
+#if 0//syntax highlighting
+#include "richedit.h"
+#endif
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#define C_THISCLASS C_SScopeClass
+#define MOD_NAME "Render / SuperScope"
+
+
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_SUPERSCOPE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ RString effect_exp[4];
+ int which_ch;
+ int num_colors;
+ int colors[16];
+ int mode;
+
+ int color_pos;
+
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ double *var_b, *var_x, *var_y, *var_i, *var_n, *var_v, *var_w, *var_h, *var_red, *var_green, *var_blue;
+ double *var_skip, *var_linesize, *var_drawmode;
+ int inited;
+ NSEEL_CODEHANDLE codehandle[4];
+ int need_recompile;
+ CRITICAL_SECTION rcs;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ int x=0;
+ if (data[pos] == 1)
+ {
+ pos++;
+ load_string(effect_exp[0],data,pos,len);
+ load_string(effect_exp[1],data,pos,len);
+ load_string(effect_exp[2],data,pos,len);
+ load_string(effect_exp[3],data,pos,len);
+ }
+ else
+ {
+ char buf[1025];
+ if (len-pos >= 1024)
+ {
+ memcpy(buf,data+pos,1024);
+ pos+=1024;
+ buf[1024]=0;
+ effect_exp[3].assign(buf+768);
+ buf[768]=0;
+ effect_exp[2].assign(buf+512);
+ buf[512]=0;
+ effect_exp[1].assign(buf+256);
+ buf[256]=0;
+ effect_exp[0].assign(buf);
+ }
+ }
+ if (len-pos >= 4) { which_ch=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { num_colors=GET_INT(); pos+=4; }
+ if (num_colors <= 16) while (len-pos >= 4 && x < num_colors) { colors[x++]=GET_INT(); pos+=4; }
+ else num_colors=0;
+ if (len-pos >= 4) { mode=GET_INT(); pos+=4; }
+ need_recompile=1;
+}
+
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int x=0;
+ int pos=0;
+ data[pos++]=1;
+ save_string(data,pos,effect_exp[0]);
+ save_string(data,pos,effect_exp[1]);
+ save_string(data,pos,effect_exp[2]);
+ save_string(data,pos,effect_exp[3]);
+ PUT_INT(which_ch); pos+=4;
+ PUT_INT(num_colors); pos+=4;
+ while (x < num_colors) { PUT_INT(colors[x]); x++; pos+=4; }
+ PUT_INT(mode); pos+=4;
+ return pos;
+}
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ InitializeCriticalSection(&rcs);
+ AVS_EEL_INITINST();
+#ifdef LASER
+ mode=1;
+#else
+ mode=0;
+#endif
+
+
+ need_recompile=1;
+ which_ch=2;
+ num_colors=1;
+ memset(colors,0,sizeof(colors));
+ colors[0]=RGB(255,255,255);
+ color_pos=0;
+ memset(codehandle,0,sizeof(codehandle));
+
+#ifdef LASER
+ effect_exp[0].assign("d=i+v*0.2; r=t+i*$PI*4; x=cos(r)*d; y=sin(r)*d");
+ effect_exp[1].assign("t=t-0.05");
+ effect_exp[2].assign("");
+ effect_exp[3].assign("n=100");
+#else
+ effect_exp[0].assign("d=i+v*0.2; r=t+i*$PI*4; x=cos(r)*d; y=sin(r)*d");
+ effect_exp[1].assign("t=t-0.05");
+ effect_exp[2].assign("");
+ effect_exp[3].assign("n=800");
+#endif
+
+ var_n=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=0;
+ }
+ AVS_EEL_QUITINST();
+ DeleteCriticalSection(&rcs);
+}
+
+static __inline int makeint(double t)
+{
+ if (t <= 0.0) return 0;
+ if (t >= 1.0) return 255;
+ return (int)(t*255.0);
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (need_recompile)
+ {
+ EnterCriticalSection(&rcs);
+
+ if (!var_n || g_reset_vars_on_recompile)
+ {
+ clearVars();
+ var_n = registerVar("n");
+ var_b = registerVar("b");
+ var_x = registerVar("x");
+ var_y = registerVar("y");
+ var_i = registerVar("i");
+ var_v = registerVar("v");
+ var_w = registerVar("w");
+ var_h = registerVar("h");
+ var_red = registerVar("red");
+ var_green = registerVar("green");
+ var_blue = registerVar("blue");
+ var_linesize = registerVar("linesize");
+ var_skip = registerVar("skip");
+ var_drawmode = registerVar("drawmode");
+ *var_n=100.0;
+ inited=0;
+ }
+
+ need_recompile=0;
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ freeCode(codehandle[x]);
+ codehandle[x]=compileCode(effect_exp[x].get());
+ }
+
+ LeaveCriticalSection(&rcs);
+ }
+ if (isBeat&0x80000000) return 0;
+
+ if (!num_colors) return 0;
+
+ int x;
+ int current_color;
+ unsigned char *fa_data;
+ char center_channel[576];
+ int ws=(which_ch&4)?1:0;
+ int xorv=(ws*128)^128;
+
+ if ((which_ch&3) >=2)
+ {
+ for (x = 0; x < 576; x ++) center_channel[x]=visdata[ws^1][0][x]/2+visdata[ws^1][1][x]/2;
+ fa_data=(unsigned char *)center_channel;
+ }
+ else fa_data=(unsigned char *)&visdata[ws^1][which_ch&3][0];
+
+ color_pos++;
+ if (color_pos >= num_colors * 64) color_pos=0;
+
+ {
+ int p=color_pos/64;
+ int r=color_pos&63;
+ int c1,c2;
+ int r1,r2,r3;
+ c1=colors[p];
+ if (p+1 < num_colors)
+ c2=colors[p+1];
+ else c2=colors[0];
+
+ r1=(((c1&255)*(63-r))+((c2&255)*r))/64;
+ r2=((((c1>>8)&255)*(63-r))+(((c2>>8)&255)*r))/64;
+ r3=((((c1>>16)&255)*(63-r))+(((c2>>16)&255)*r))/64;
+
+ current_color=r1|(r2<<8)|(r3<<16);
+ }
+
+ *var_h=h;
+ *var_w=w;
+ *var_b=isBeat?1.0:0.0;
+ *var_blue=(current_color&0xff)/255.0;
+ *var_green=((current_color>>8)&0xff)/255.0;
+ *var_red=((current_color>>16)&0xff)/255.0;
+ *var_skip=0.0;
+ *var_linesize = (double) ((g_line_blend_mode&0xff0000)>>16);
+ *var_drawmode = mode ? 1.0 : 0.0;
+ if (codehandle[3] && !inited) { executeCode(codehandle[3],visdata); inited=1; }
+ executeCode(codehandle[1],visdata);
+ if (isBeat) executeCode(codehandle[2],visdata);
+ if (codehandle[0])
+ {
+ int candraw=0,lx=0,ly=0;
+#ifdef LASER
+ double dlx=0.0,dly=0.0;
+#endif
+ int a;
+ int l=(int)*var_n;
+ if (l > 128*1024) l = 128*1024;
+ for (a = 0; a < l; a ++)
+ {
+ int x,y;
+ double r=(a*576.0)/l;
+ double s1=r-(int)r;
+ double yr=(fa_data[(int)r]^xorv)*(1.0f-s1)+(fa_data[(int)r+1]^xorv)*(s1);
+ *var_v = yr/128.0 - 1.0;
+ *var_i = (double)a/(double)(l-1);
+ *var_skip=0.0;
+ executeCode(codehandle[0],visdata);
+ x=(int)((*var_x+1.0)*w*0.5);
+ y=(int)((*var_y+1.0)*h*0.5);
+ if (*var_skip < 0.00001)
+ {
+ int thiscolor=makeint(*var_blue)|(makeint(*var_green)<<8)|(makeint(*var_red)<<16);
+ if (*var_drawmode < 0.00001)
+ {
+ if (y >= 0 && y < h && x >= 0 && x < w)
+ {
+ #ifdef LASER
+ laser_drawpoint((float)*var_x,(float)*var_y,thiscolor);
+ #else
+ BLEND_LINE(framebuffer+x+y*w,thiscolor);
+ #endif
+ }
+ }
+ else
+ {
+ if (candraw)
+ {
+ #ifdef LASER
+ LineType l;
+ l.color=thiscolor;
+ l.mode=0;
+ l.x1=(float)*var_x;
+ l.y1=(float)*var_y;
+ l.x2=(float)dlx;
+ l.y2=(float)dly;
+ g_laser_linelist->AddLine(&l);
+ #else
+ if ((thiscolor&0xffffff) || (g_line_blend_mode&0xff)!=1)
+ {
+ line(framebuffer,lx,ly,x,y,w,h,thiscolor,(int) (*var_linesize+0.5));
+ }
+ #endif
+ } // candraw
+ } // line
+ } // skip
+ candraw=1;
+ lx=x;
+ ly=y;
+ #ifdef LASER
+ dlx=*var_x;
+ dly=*var_y;
+ #endif
+ }
+ }
+
+ return 0;
+}
+
+C_RBASE *R_SScope(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+typedef struct
+{
+ int name;
+ char *init;
+ char *point;
+ char *frame;
+ char *beat;
+} presetType;
+
+static presetType presets[]=
+{
+#ifdef LASER
+ {"Laser - Bouncing Line","n=8;xp=0;yp=0;d=0.5;r=0;xps=0; yps=0; dtr=0.1; bv=1; gv=1; rv=1;","x=xp+d*cos(r)*sign(i-0.5); y=yp+d*sin(r)*sign(i-0.5);","r=r+dtr; xp=xp*0.99+xps*0.01; yp=yp*0.99+yps*0.01; red=rv; green=gv; blue=bv;","xps=(rand(100)-50)/50; yps=(rand(100)-50)/50; dtr=-dtr; rv=rand(100)/100; gv=rand(100)/100; bv=rand(100)/100;"},
+ {"Laser - BeatFlex Scope","n=5; tv=0; dtv=0; tvs=1.0;","x=(i-0.5)*2; y=-sin(i*$PI)*tv+v*0.2;","tv=tv*0.97+tvs*0.03;","tvs=-sign(tvs);"},
+ {"Laser - Pulsing Box","n=5;r=$PI/4;","x=cos(i*$PI*2+r); y=sin(i*$PI*2+r); red=rv; green=gv; blue=bv;","rv=rv*0.93; gv=gv*0.93; bv=bv*0.93;","bv=blue; gv=green;rv=red;"},
+#else
+ {IDS_SPIRAL,"n=800","d=i+v*0.2; r=t+i*$PI*4; x=cos(r)*d; y=sin(r)*d","t=t-0.05",""},
+ {IDS_3D_SCOPE_DISH, "n=200","iz=1.3+sin(r+i*$PI*2)*(v+0.5)*0.88; ix=cos(r+i*$PI*2)*(v+0.5)*.88; iy=-0.3+abs(cos(v*$PI)); x=ix/iz;y=iy/iz;","",""},
+ {IDS_ROTATING_BOW_THING,"n=80;t=0.0;","r=i*$PI*2; d=sin(r*3)+v*0.5; x=cos(t+r)*d; y=sin(t-r)*d","t=t+0.01",""},
+ {IDS_VERTICAL_BOUNCING_SCOPE,"n=100; t=0; tv=0.1;dt=1;","x=t+v*pow(sin(i*$PI),2); y=i*2-1.0;","t=t*0.9+tv*0.1","tv=((rand(50.0)/50.0))*dt; dt=-dt;"},
+ {IDS_SPIRAL_GRAPH_FUN,"n=100;t=0;","r=i*$PI*128+t; x=cos(r/64)*0.7+sin(r)*0.3; y=sin(r/64)*0.7+cos(r)*0.3","t=t+0.01;","n=80+rand(120.0)"},
+ {IDS_ALTERNATING_DIAGONAL_SCOPE,"n=64; t=1;","sc=0.4*sin(i*$PI); x=2*(i-0.5-v*sc)*t; y=2*(i-0.5+v*sc);","","t=-t;"},
+ {IDS_VIBRATING_WORM,"n=w; dt=0.01; t=0; sc=1;","x=cos(2*i+t)*0.9*(v*0.5+0.5); y=sin(i*2+t)*0.9*(v*0.5+0.5);","t=t+dt;dt=0.9*dt+0.001; t=if(above(t,$PI*2),t-$PI*2,t);","dt=sc;sc=-sc;"},
+ {IDS_WANDERING_SIMPLE,"n=800;xa=-0.5;ya=0.0;xb=-0.0;yb=0.75;c=200;f=0;\r\nnxa=(rand(100)-50)*.02;nya=(rand(100)-50)*.02;\r\nnxb=(rand(100)-50)*.02;nyb=(rand(100)-50)*.02;","//primary render\r\nx=(ex*i)+xa;\r\ny=(ey*i)+ya;\r\n\r\n//volume offset\r\nx=x+ ( cos(r) * v * dv);\r\ny=y+ ( sin(r) * v * dv);\r\n\r\n//color values\r\nred=i;\r\ngreen=(1-i);\r\nblue=abs(v*6);","f=f+1;\r\nt=1-((cos((f*3.1415)/c)+1)*.5);\r\nxa=((nxa-lxa)*t)+lxa;\r\nya=((nya-lya)*t)+lya;\r\nxb=((nxb-lxb)*t)+lxb;\r\nyb=((nyb-lyb)*t)+lyb;\r\nex=(xb-xa);\r\ney=(yb-ya);\r\nd=sqrt(sqr(ex)+sqr(ey));\r\nr=atan(ey/ex)+(3.1415/2);\r\ndv=d*2","c=f;\r\nf=0;\r\nlxa=nxa;\r\nlya=nya;\r\nlxb=nxb;\r\nlyb=nyb;\r\nnxa=(rand(100)-50)*.02;\r\nnya=(rand(100)-50)*.02;\r\nnxb=(rand(100)-50)*.02;\r\nnyb=(rand(100)-50)*.02"},
+ {IDS_FLITTERBUG,"n=180;t=0.0;lx=0;ly=0;vx=rand(200)-100;vy=rand(200)-100;cf=.97;c=200;f=0","x=nx;y=ny;\r\nr=i*3.14159*2; d=(sin(r*5*(1-s))+i*0.5)*(.3-s);\r\ntx=(t*(1-(s*(i-.5))));\r\nx=x+cos(tx+r)*d; y=y+sin(t-y)*d;\r\nred=abs(x-nx)*5;\r\ngreen=abs(y-ny)*5;\r\nblue=1-s-red-green;","f=f+1;t=(f*2*3.1415)/c;\r\nvx=(vx-(lx*.1))*cf;\r\nvy=(vy-(ly*.1))*cf;\r\nlx=lx+vx;ly=ly+vy;\r\nnx=lx*.001;ny=ly*.001;\r\ns=abs(nx*ny)","c=f;f=0;\r\nvx=vx+rand(600)-300;vy=vy+rand(600)-300"},
+ {IDS_SPIROSTAR,"n=20;t=0;f=0;c=200;mn=10;dv=2;dn=0","r=if(b,0,((i*dv)*3.14159*128)+(t/2));\r\nx=cos(r)*sz;\r\ny=sin(r)*sz;","f=f+1;t=(f*3.1415*2)/c;\r\nsz=abs(sin(t-3.1415));\r\ndv=if(below(n,12),(n/2)-1,\r\n if(equal(12,n),3,\r\n if(equal(14,n),6,\r\n if(below(n,20),2,4))))","bb = bb + 1;\r\nbeatdiv = 8;\r\nc=if(equal(bb%beatdiv,0),f,c);\r\nf=if(equal(bb%beatdiv,0),0,f);\r\ng=if(equal(bb%beatdiv,0),g+1,g);\r\nn=if(equal(bb%beatdiv,0),(abs((g%17)-8) *2)+4,n);"},
+ {IDS_EXPLODING_DAISY,"n = 380 + rand(200) ; k = 0.0; l = 0.0; m = ( rand( 10 ) + 2 ) * .5; c = 0; f = 0","r=(i*3.14159*2)+(a * 3.1415);\r\nd=sin(r*m)*.3;\r\nx=cos(k+r)*d*2;y=( (sin(k-r)*d) + ( sin(l*(i-.5) ) ) ) * .7;\r\nred=abs(x);\r\ngreen=abs(y);\r\nblue=d","a = a + 0.002 ; k = k + 0.04 ; l = l + 0.03","bb = bb + 1;\r\nbeatdiv = 16;\r\nn=if(equal(bb%beatdiv,0),380 + rand(200),n);\r\nt=if(equal(bb%beatdiv,0),0.0,t);\r\na=if(equal(bb%beatdiv,0),0.0,a);\r\nk=if(equal(bb%beatdiv,0),0.0,k);\r\nl=if(equal(bb%beatdiv,0),0.0,l);\r\nm=if(equal(bb%beatdiv,0),(( rand( 100 ) + 2 ) * .1) + 2,m);"},
+ {IDS_SWIRLIE_DOTS,"n=45;t=rand(100);u=rand(100)","di = ( i - .5) * 2;\r\nx = di;sin(u*di) * .4;\r\ny = cos(u*di) * .6;\r\nx = x + ( cos(t) * .05 );\r\ny = y + ( sin(t) * .05 );","t = t + .15; u = u + .05","bb = bb + 1;\r\nbeatdiv = 16;\r\nn = if(equal(bb%beatdiv,0),30 + rand( 30 ),n);"},
+ {IDS_SWEEP,"n=180;lsv=100;sv=200;ssv=200;c=200;f=0","sv=(sv*abs(cos(lsv)))+(lsv*abs(cos(sv)));\r\nfv=fv+(sin(sv)*dv);\r\nd=i; r=t+(fv * sin(t) * .3)*3.14159*4;\r\nx=cos(r)*d;\r\ny=sin(r)*d;\r\nred=i;\r\ngreen=abs(sin(r))-(red*.15);\r\nblue=fv","f=f+1;t=(f*2*3.1415)/c;\r\nlsv=slsv;sv=ssv;fv=0","bb = bb + 1;\r\nbeatdiv = 8;\r\nc=if(equal(bb%beatdiv,0),f,c);\r\nf=if(equal(bb%beatdiv,0),0,f);\r\ndv=if(equal(bb%beatdiv,0),((rand(100)*.01) * .1) + .02,dv);\r\nn=if(equal(bb%beatdiv,0),80+rand(100),n);\r\nssv=if(equal(bb%beatdiv,0),rand(200)+100,ssv);\r\nslsv=if(equal(bb%beatdiv,0),rand(200)+100,slsv);"},
+ {IDS_WHIPLASH_SPIRAL,"n=80;c=200;f=0","d=i;\r\nr=t+i*3.14159*4;\r\nsdt=sin(dt+(i*3.1415*2));\r\ncdt=cos(dt+(i*3.1415*2));\r\nx=(cos(r)*d) + (sdt * .6 * sin(t) );\r\ny=(sin(r)*d) + ( cdt *.6 * sin(t) );\r\nblue=abs(x);\r\ngreen=abs(y);\r\nred=cos(dt*4)","t=t-0.05;f=f+1;dt=(f*2*3.1415)/c","bb = bb + 1;\r\nbeatdiv = 8;\r\nc=if(equal(bb%beatdiv,0),f,c);\r\nf=if(equal(bb%beatdiv,0),0,f);"},
+#endif
+};
+
+static C_THISCLASS *g_this;
+BOOL CALLBACK C_THISCLASS::g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ isstart=1;
+#if 0//syntax highlighting
+ SendDlgItemMessage(hwndDlg,IDC_EDIT1,EM_SETEVENTMASK,0,ENM_CHANGE);
+ SendDlgItemMessage(hwndDlg,IDC_EDIT2,EM_SETEVENTMASK,0,ENM_CHANGE);
+ SendDlgItemMessage(hwndDlg,IDC_EDIT3,EM_SETEVENTMASK,0,ENM_CHANGE);
+ SendDlgItemMessage(hwndDlg,IDC_EDIT4,EM_SETEVENTMASK,0,ENM_CHANGE);
+#endif
+ SetDlgItemInt(hwndDlg,IDC_NUMCOL,g_this->num_colors,FALSE);
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ SetDlgItemText(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+
+#if 0//syntax highlighting
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+#endif
+
+ CheckDlgButton(hwndDlg,g_this->mode?IDC_LINES:IDC_DOT,BST_CHECKED);
+ if ((g_this->which_ch&3)==0)
+ CheckDlgButton(hwndDlg,IDC_LEFTCH,BST_CHECKED);
+ else if ((g_this->which_ch&3)==1)
+ CheckDlgButton(hwndDlg,IDC_RIGHTCH,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_MIDCH,BST_CHECKED);
+ if (g_this->which_ch&4)
+ CheckDlgButton(hwndDlg,IDC_SPEC,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_WAVE,BST_CHECKED);
+
+ isstart=0;
+ return 1;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL && g_this->num_colors>0)
+ {
+ int x;
+ int w=di->rcItem.right-di->rcItem.left;
+ int l=0,nl;
+ for (x = 0; x < g_this->num_colors; x ++)
+ {
+ int color=g_this->colors[x];
+ nl = (w*(x+1))/g_this->num_colors;
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={(COLORREF)BS_SOLID,(COLORREF)color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left+l,di->rcItem.top,di->rcItem.left+nl,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ l=nl;
+ }
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if (!isstart)
+ {
+ if ((LOWORD(wParam) == IDC_EDIT1||LOWORD(wParam) == IDC_EDIT2||LOWORD(wParam) == IDC_EDIT3||LOWORD(wParam) == IDC_EDIT4) && HIWORD(wParam) == EN_CHANGE)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp[0].get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp[1].get_from_dlgitem(hwndDlg,IDC_EDIT2);
+ g_this->effect_exp[2].get_from_dlgitem(hwndDlg,IDC_EDIT3);
+ g_this->effect_exp[3].get_from_dlgitem(hwndDlg,IDC_EDIT4);
+ g_this->need_recompile=1;
+ if (LOWORD(wParam) == IDC_EDIT4) g_this->inited = 0;
+ LeaveCriticalSection(&g_this->rcs);
+#if 0//syntax highlighting
+ if (LOWORD(wParam) == IDC_EDIT1)
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT1,g_this->effect_exp[0].get());
+ if (LOWORD(wParam) == IDC_EDIT2)
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT2,g_this->effect_exp[1].get());
+ if (LOWORD(wParam) == IDC_EDIT3)
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT3,g_this->effect_exp[2].get());
+ if (LOWORD(wParam) == IDC_EDIT4)
+ doAVSEvalHighLight(hwndDlg,IDC_EDIT4,g_this->effect_exp[3].get());
+#endif
+ }
+ if (LOWORD(wParam) == IDC_DOT || LOWORD(wParam) == IDC_LINES)
+ {
+ g_this->mode=IsDlgButtonChecked(hwndDlg,IDC_LINES)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_WAVE || LOWORD(wParam) == IDC_SPEC)
+ {
+ if (IsDlgButtonChecked(hwndDlg,IDC_WAVE)) g_this->which_ch&=~4;
+ else g_this->which_ch|=4;
+ }
+ if (LOWORD(wParam) == IDC_LEFTCH || LOWORD(wParam) == IDC_RIGHTCH || LOWORD(wParam)==IDC_MIDCH)
+ {
+ g_this->which_ch&=~3;
+ if (IsDlgButtonChecked(hwndDlg,IDC_LEFTCH));
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RIGHTCH)) g_this->which_ch|=1;
+ else g_this->which_ch|=2;
+ }
+ }
+ if (LOWORD(wParam) == IDC_BUTTON2)
+ {
+/*
+ char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_SUPERSCOPE,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_SUPERSCOPE),4095-titlelen);
+*/
+ char *text="Superscope\0"
+ "Superscope tutorial:\r\n\n"
+// "But for now, here is the old text:\r\n"
+ "You can specify expressions that run on Init, Frame, and on Beat.\r\n"
+ " 'n' specifies the number of points to render (set this in Init, Beat, or Frame).\r\n"
+ "For the 'Per Point' expression (which happens 'n' times per frame), use:\r\n"
+ " 'x' and 'y' are the coordinates to draw to (-1..1)\r\n"
+ " 'i' is the position of the scope (0..1)\r\n"
+ " 'v' is the value at that point (-1..1).\r\n"
+ " 'b' is 1 if beat, 0 if not.\r\n"
+ " 'red', 'green' and 'blue' are all (0..1) and can be modified\r\n"
+ " 'linesize' can be set from 1.0 to 255.0\r\n"
+ " 'skip' can be set to >0 to skip drawing the current item\r\n"
+ " 'drawmode' can be set to > 0 for lines, <= 0 for points\r\n"
+ " 'w' and 'h' are the width and height of the screen, in pixels.\r\n"
+// " Anybody want to send me better text to put here? Please :)\r\n"
+ ;
+
+ compilerfunctionlist(hwndDlg,text);
+ }
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+ RECT r;
+ HMENU hMenu;
+ MENUITEMINFO i={sizeof(i),};
+ hMenu=CreatePopupMenu();
+ int x;
+ for (x = 0; x < sizeof(presets)/sizeof(presets[0]); x ++)
+ {
+ i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.wID = x+16;
+ i.dwTypeData=WASABI_API_LNGSTRING(presets[x].name);
+ i.cch=strlen(i.dwTypeData);
+ InsertMenuItem(hMenu,x,TRUE,&i);
+ }
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_BUTTON1),&r);
+ x=TrackPopupMenu(hMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON|TPM_NONOTIFY,r.right,r.top,0,hwndDlg,NULL);
+ if (x >= 16 && x < 16+sizeof(presets)/sizeof(presets[0]))
+ {
+ SetDlgItemText(hwndDlg,IDC_EDIT1,presets[x-16].point);
+ SetDlgItemText(hwndDlg,IDC_EDIT2,presets[x-16].frame);
+ SetDlgItemText(hwndDlg,IDC_EDIT3,presets[x-16].beat);
+ SetDlgItemText(hwndDlg,IDC_EDIT4,presets[x-16].init);
+ SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_EDIT4,EN_CHANGE),0);
+ }
+ DestroyMenu(hMenu);
+ }
+ if (LOWORD(wParam) == IDC_NUMCOL)
+ {
+ int p;
+ BOOL tr=FALSE;
+ p=GetDlgItemInt(hwndDlg,IDC_NUMCOL,&tr,FALSE);
+ if (tr)
+ {
+ if (p > 16) p = 16;
+ g_this->num_colors=p;
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ if (LOWORD(wParam) == IDC_DEFCOL)
+ {
+ int wc=-1,w,h;
+ POINT p;
+ RECT r;
+ GetCursorPos(&p);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_DEFCOL),&r);
+ p.x -= r.left;
+ p.y -= r.top;
+ w=r.right-r.left;
+ h=r.bottom-r.top;
+ if (p.x >= 0 && p.x < w && p.y >= 0 && p.y < h)
+ {
+ wc = (p.x*g_this->num_colors)/w;
+ }
+ if (wc>=0)
+ {
+ GR_SelectColor(hwndDlg,g_this->colors+wc);
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_SSCOPE,hwndParent,g_DlgProc);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_stack.cpp b/Src/Plugins/Visualization/vis_avs/r_stack.cpp
new file mode 100644
index 00000000..3fca86e0
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_stack.cpp
@@ -0,0 +1,338 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "r_stack.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Misc / Buffer Save"
+
+#define C_THISCLASS C_StackClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_StackClass();
+ virtual ~C_StackClass();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc();
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int clear;
+ volatile int dir_ch;
+
+ int blend;
+ int dir;
+ int which;
+ int adjblend_val;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { dir=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { which=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { adjblend_val=GET_INT(); pos+=4; }
+
+ if (which < 0) which=0;
+ if (which >= NBUF) which=NBUF-1;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(dir); pos+=4;
+ PUT_INT(which); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(adjblend_val); pos+=4;
+ return pos;
+}
+
+char *C_THISCLASS::get_desc()
+{
+static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_MISC_BUFFER_SAVE,desc,128):desc);
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ adjblend_val=128;
+ dir_ch=0;
+ which=0;
+ dir=0;
+ blend=0;
+ clear=0;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ void *thisbufptr;
+ if (isBeat&0x80000000) return 0;
+ if (!(thisbufptr=getGlobalBuffer(w,h,which,dir!=1)))
+ {
+ return 0;
+ }
+
+ if (clear)
+ {
+ clear=0;
+ memset(thisbufptr,0,sizeof(int)*w*h);
+ }
+
+ {
+ int t_dir;
+ t_dir=(dir<2)?dir:((dir&1)^dir_ch);
+ dir_ch^=1;
+ int *fbin=(int*)(t_dir==0?framebuffer:thisbufptr);
+ int *fbout=(int*)(t_dir!=0?framebuffer:thisbufptr);
+ if (blend == 1)
+ {
+ mmx_avgblend_block(fbout,fbin,w*h);
+ }
+ else if (blend == 2)
+ {
+ mmx_addblend_block(fbout,fbin,w*h);
+ }
+ else if (blend == 3)
+ {
+ int r=0;
+ int y=h;
+ int *bf=fbin;
+ while (y-- > 0)
+ {
+ int *out, *in;
+ int x=w/2;
+ out=fbout+r;
+ in=bf+r;
+ r^=1;
+ while (x-- > 0)
+ {
+ *out=*in;
+ out+=2;
+ in+=2;
+ }
+ fbout+=w;
+ bf+=w;
+ }
+ }
+ else if (blend == 4)
+ {
+ int x=w*h;
+ int *bf=fbin;
+ while (x-- > 0)
+ {
+ *fbout=BLEND_SUB(*fbout,*bf);
+ fbout++;
+ bf++;
+ }
+ }
+ else if (blend == 5)
+ {
+ int y=h/2;
+ while (y-- > 0)
+ {
+ memcpy(fbout,fbin,w*sizeof(int));
+ fbout+=w*2;
+ fbin+=w*2;
+ }
+ }
+ else if (blend == 6)
+ {
+ int x=w*h;
+ while (x-- > 0)
+ {
+ *fbout=*fbout ^ *fbin;
+ fbout++;
+ fbin++;
+ }
+ }
+ else if (blend == 7)
+ {
+ int x=w*h;
+ int *bf=fbin;
+ while (x-- > 0)
+ {
+ *fbout=BLEND_MAX(*fbout,*bf);
+ fbout++;
+ bf++;
+ }
+ }
+ else if (blend == 8)
+ {
+ int x=w*h;
+ int *bf=fbin;
+ while (x-- > 0)
+ {
+ *fbout=BLEND_MIN(*fbout,*bf);
+ fbout++;
+ bf++;
+ }
+ }
+ else if (blend == 9)
+ {
+ int x=w*h;
+ int *bf=fbin;
+ while (x-- > 0)
+ {
+ *fbout=BLEND_SUB(*bf,*fbout);
+ fbout++;
+ bf++;
+ }
+ }
+ else if (blend == 10)
+ {
+ mmx_mulblend_block(fbout,fbin,w*h);
+ }
+ else if (blend == 11)
+ {
+ mmx_adjblend_block(fbout,fbin,fbout,w*h,adjblend_val);
+ }
+ else memcpy(fbout,fbin,w*h*sizeof(int));
+ return 0;
+ }
+
+ return 0;
+}
+
+C_RBASE *R_Stack(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int x;
+ for (x = 1; x <= NBUF; x ++)
+ {
+ char s[32];
+ wsprintf(s,WASABI_API_LNGSTRING(IDS_BUFFER_X),x);
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_ADDSTRING,0,(LPARAM)s);
+ }
+ }
+ SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_SETCURSEL,g_this->which,0);
+ if (g_this->dir==1) CheckDlgButton(hwndDlg,IDC_RESTFB,BST_CHECKED);
+ else if (g_this->dir == 2) CheckDlgButton(hwndDlg,IDC_RADIO1,BST_CHECKED);
+ else if (g_this->dir == 3) CheckDlgButton(hwndDlg,IDC_RADIO2,BST_CHECKED);
+ else CheckDlgButton(hwndDlg,IDC_SAVEFB,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_BLENDSLIDE, TBM_SETRANGE, TRUE, MAKELONG(0, 255));
+ SendDlgItemMessage(hwndDlg, IDC_BLENDSLIDE, TBM_SETPOS, TRUE, (int)(g_this->adjblend_val));
+ if (g_this->blend==0) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND1,BST_CHECKED);
+ if (g_this->blend==1) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND2,BST_CHECKED);
+ if (g_this->blend==2) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND3,BST_CHECKED);
+ if (g_this->blend==3) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND4,BST_CHECKED);
+ if (g_this->blend==4) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND5,BST_CHECKED);
+ if (g_this->blend==5) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND6,BST_CHECKED);
+ if (g_this->blend==6) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND7,BST_CHECKED);
+ if (g_this->blend==7) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND8,BST_CHECKED);
+ if (g_this->blend==8) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND9,BST_CHECKED);
+ if (g_this->blend==9) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND10,BST_CHECKED);
+ if (g_this->blend==10) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND11,BST_CHECKED);
+ if (g_this->blend==11) CheckDlgButton(hwndDlg,IDC_RSTACK_BLEND12,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_BUTTON2)
+ {
+ g_this->dir_ch^=1;
+ }
+ if (LOWORD(wParam) == IDC_BUTTON1)
+ {
+ g_this->clear=1;
+ }
+ if (LOWORD(wParam) == IDC_SAVEFB || LOWORD(wParam) == IDC_RESTFB || LOWORD(wParam) == IDC_RADIO1 || LOWORD(wParam) == IDC_RADIO2)
+ {
+ if (IsDlgButtonChecked(hwndDlg,IDC_SAVEFB)) g_this->dir=0;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO2)) g_this->dir=3;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RADIO1)) g_this->dir=2;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RESTFB)) g_this->dir=1;
+ }
+ if (IsDlgButtonChecked(hwndDlg,LOWORD(wParam)))
+ {
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND1) g_this->blend=0;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND2) g_this->blend=1;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND3) g_this->blend=2;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND4) g_this->blend=3;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND5) g_this->blend=4;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND6) g_this->blend=5;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND7) g_this->blend=6;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND8) g_this->blend=7;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND9) g_this->blend=8;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND10) g_this->blend=9;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND11) g_this->blend=10;
+ if (LOWORD(wParam) == IDC_RSTACK_BLEND12) g_this->blend=11;
+ }
+ if (LOWORD(wParam) == IDC_COMBO1 && HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int i=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (i != CB_ERR)
+ g_this->which=i;
+ }
+ return 0;
+ return 0;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_BLENDSLIDE)
+ g_this->adjblend_val = SendDlgItemMessage(hwndDlg, IDC_BLENDSLIDE, TBM_GETPOS, 0, 0);
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_STACK,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_Stack(char *desc)
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_stack.h b/Src/Plugins/Visualization/vis_avs/r_stack.h
new file mode 100644
index 00000000..a62ae57f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_stack.h
@@ -0,0 +1,29 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
diff --git a/Src/Plugins/Visualization/vis_avs/r_stars.cpp b/Src/Plugins/Visualization/vis_avs/r_stars.cpp
new file mode 100644
index 00000000..21a1a5fc
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_stars.cpp
@@ -0,0 +1,402 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <math.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#define MOD_NAME "Render / Starfield"
+
+#define C_THISCLASS C_StarField
+
+typedef struct
+ {
+ int X, Y;
+ float Z;
+ float Speed;
+ int OX, OY;
+ } StarFormat;
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ float GET_FLOAT(unsigned char *data, int pos);
+ void PUT_FLOAT(float f, unsigned char *data, int pos);
+ void InitializeStars(void);
+ void CreateStar(int A);
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_STARFIELD,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int enabled;
+ int color;
+ int MaxStars,MaxStars_set;
+ int Xoff;
+ int Yoff;
+ int Zoff;
+ float WarpSpeed;
+ int blend;
+ int blendavg;
+ StarFormat Stars[4096];
+ int Width, Height;
+ int onbeat;
+ float spdBeat;
+ float incBeat;
+ int durFrames;
+ float CurrentSpeed;
+ int nc;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ nc=0;
+ color = 0xFFFFFF;
+ enabled=1;
+ MaxStars = 350;
+ MaxStars_set=350;
+ Xoff = 0;
+ Yoff = 0;
+ Zoff = 255;
+ WarpSpeed = 6;
+ CurrentSpeed = 6;
+ blend = 0;
+ blendavg = 0;
+ Width = 0;
+ Height = 0;
+ onbeat = 0;
+ spdBeat = 4;
+ durFrames = 15;
+ incBeat = 0;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+float C_THISCLASS::GET_FLOAT(unsigned char *data, int pos)
+{
+int a = data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24);
+float f = *(float *)&a;
+return f;
+}
+
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { WarpSpeed=GET_FLOAT(data, pos); pos+=4; }
+ CurrentSpeed = WarpSpeed;
+ if (len-pos >= 4) { MaxStars_set=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { spdBeat=GET_FLOAT(data, pos); pos+=4; }
+ if (len-pos >= 4) { durFrames=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+void C_THISCLASS::PUT_FLOAT(float f, unsigned char *data, int pos)
+{
+int y = *(int *)&f;
+data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255;
+}
+
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_FLOAT(WarpSpeed, data, pos); pos+=4;
+ PUT_INT(MaxStars_set); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_FLOAT(spdBeat, data, pos); pos+=4;
+ PUT_INT(durFrames); pos+=4;
+ return pos;
+}
+
+void C_THISCLASS::InitializeStars(void)
+{
+ int i;
+#ifdef LASER
+ MaxStars = MaxStars_set/12;
+ if (MaxStars < 10) MaxStars=10;
+#else
+ MaxStars = MulDiv(MaxStars_set,Width*Height,512*384);
+#endif
+ if (MaxStars > 4095) MaxStars=4095;
+ for (i=0;i<MaxStars;i++)
+ {
+ Stars[i].X=(rand()%Width)-Xoff;
+ Stars[i].Y=(rand()%Height)-Yoff;
+ Stars[i].Z=(float)(rand()%255);
+ Stars[i].Speed = (float)(rand()%9+1)/10;
+ }
+}
+
+void C_THISCLASS::CreateStar(int A)
+{
+ Stars[A].X = (rand()%Width)-Xoff;
+ Stars[A].Y = (rand()%Height)-Yoff;
+ Stars[A].Z = (float)Zoff;
+}
+
+static unsigned int __inline BLEND_ADAPT(unsigned int a, unsigned int b, /*float*/int divisor)
+{
+return ((((a >> 4) & 0x0F0F0F) * (16-divisor) + (((b >> 4) & 0x0F0F0F) * divisor)));
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+#ifdef LASER
+ w=h=1024;
+#endif
+ int i=w*h;
+ int NX,NY;
+ int c;
+
+ if (!enabled) return 0;
+
+ if (onbeat && isBeat)
+ {
+ CurrentSpeed = spdBeat;
+ incBeat = (WarpSpeed - CurrentSpeed) / (float)durFrames;
+ nc = durFrames;
+ }
+
+ if (Width != w || Height != h)
+ {
+ Width = w;
+ Height = h;
+ Xoff = Width/2;
+ Yoff = Height/2;
+ InitializeStars();
+ }
+ if (isBeat&0x80000000) return 0;
+
+ for (i=0;i<MaxStars;i++)
+ {
+ if ((int)Stars[i].Z > 0)
+ {
+ NX = ((Stars[i].X << 7) / (int)Stars[i].Z) + Xoff;
+ NY = ((Stars[i].Y << 7) / (int)Stars[i].Z) + Yoff;
+ if ((NX > 0) && (NX < w) && (NY > 0) && (NY < h))
+ {
+ c = (int)((255-(int)Stars[i].Z)*Stars[i].Speed);
+ if (color != 0xFFFFFF) c = BLEND_ADAPT((c|(c<<8)|(c<<16)), color, c>>4); else c = (c|(c<<8)|(c<<16));
+#ifdef LASER
+ LineType l;
+ l.color=c;
+ l.mode=1;
+ l.x1=(float)NX/512.0f - 1.0f;
+ l.y1=(float)NY/512.0f - 1.0f;
+ g_laser_linelist->AddLine(&l);
+#else
+ framebuffer[NY*w+NX] = blend ? BLEND(framebuffer[NY*w+NX], c) : blendavg ? BLEND_AVG(framebuffer[NY*w+NX], c) : c;
+#endif
+ Stars[i].OX = NX;
+ Stars[i].OY = NY;
+ Stars[i].Z-=Stars[i].Speed*CurrentSpeed;
+ }
+ else
+ CreateStar(i);
+ }
+ else
+ CreateStar(i);
+ }
+
+ if (!nc)
+ CurrentSpeed = WarpSpeed;
+ else
+ {
+ CurrentSpeed = max(0, CurrentSpeed + incBeat);
+ nc--;
+ }
+
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+#ifdef LASER
+ ShowWindow(GetDlgItem(hwndDlg,IDC_ADDITIVE),SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_5050),SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg,IDC_REPLACE),SW_HIDE);
+#endif
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1, 5000));
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(g_ConfigThis->WarpSpeed*100));
+ SendDlgItemMessage(hwndDlg, IDC_NUMSTARS, TBM_SETTICFREQ, 100, 0);
+ SendDlgItemMessage(hwndDlg, IDC_NUMSTARS, TBM_SETRANGE, TRUE, MAKELONG(100, 4095));
+ SendDlgItemMessage(hwndDlg, IDC_NUMSTARS, TBM_SETPOS, TRUE, g_ConfigThis->MaxStars_set);
+ SendDlgItemMessage(hwndDlg, IDC_SPDCHG, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SPDCHG, TBM_SETRANGE, TRUE, MAKELONG(1, 5000));
+ SendDlgItemMessage(hwndDlg, IDC_SPDCHG, TBM_SETPOS, TRUE, (int)(g_ConfigThis->spdBeat*100));
+ SendDlgItemMessage(hwndDlg, IDC_SPDDUR, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SPDDUR, TBM_SETRANGE, TRUE, MAKELONG(1, 100));
+ SendDlgItemMessage(hwndDlg, IDC_SPDDUR, TBM_SETPOS, TRUE, (int)(g_ConfigThis->durFrames));
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->onbeat) CheckDlgButton(hwndDlg,IDC_ONBEAT2,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ return 1;
+ case WM_NOTIFY:
+ {
+ if (LOWORD(wParam) == IDC_SPDCHG)
+ g_ConfigThis->spdBeat = (float)SendDlgItemMessage(hwndDlg, IDC_SPDCHG, TBM_GETPOS, 0, 0)/100;
+ if (LOWORD(wParam) == IDC_SPDDUR)
+ g_ConfigThis->durFrames = SendDlgItemMessage(hwndDlg, IDC_SPDDUR, TBM_GETPOS, 0, 0);
+ if (LOWORD(wParam) == IDC_SPEED)
+ {
+ g_ConfigThis->WarpSpeed = (float)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)/100;
+ g_ConfigThis->CurrentSpeed = (float)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)/100;
+ }
+
+ if (LOWORD(wParam) == IDC_NUMSTARS)
+ {
+#ifndef LASER
+ int a = g_ConfigThis->MaxStars_set;
+#endif
+ g_ConfigThis->MaxStars_set = SendDlgItemMessage(hwndDlg, IDC_NUMSTARS, TBM_GETPOS, 0, 0);
+#ifndef LASER
+ if (g_ConfigThis->MaxStars_set > a)
+#endif
+ if (g_ConfigThis->Width && g_ConfigThis->Height) g_ConfigThis->InitializeStars();
+ }
+ return 0;
+ }
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL) // paint nifty color button
+ {
+ int w=di->rcItem.right-di->rcItem.left;
+ int _color=g_ConfigThis->color;
+ _color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ONBEAT2) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT2)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
+ {
+ int *a=&(g_ConfigThis->color);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ g_ConfigThis->color = *a;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_STARFIELD,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_StarField(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
diff --git a/Src/Plugins/Visualization/vis_avs/r_svp.cpp b/Src/Plugins/Visualization/vis_avs/r_svp.cpp
new file mode 100644
index 00000000..97781f0a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_svp.cpp
@@ -0,0 +1,227 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+extern HINSTANCE g_hInstance;
+
+#include "svp_vis.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_SVPClass
+#define MOD_NAME "Render / SVP Loader"
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_SVP_LOADER,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+
+ char m_library[MAX_PATH];
+ void SetLibrary();
+ HMODULE hLibrary;
+ CRITICAL_SECTION cs;
+ VisInfo *vi;
+ VisData vd;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (pos+MAX_PATH <= len)
+ {
+ memcpy(m_library,data+pos,MAX_PATH);
+ pos+=MAX_PATH;
+ SetLibrary();
+ }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ memcpy(data+pos,m_library,MAX_PATH);
+ pos+=MAX_PATH;
+ return pos;
+}
+
+
+
+void C_THISCLASS::SetLibrary()
+{
+ EnterCriticalSection(&cs);
+ if (hLibrary)
+ {
+ if (vi) vi->SaveSettings("avs.ini");
+ vi=NULL;
+ FreeLibrary(hLibrary);
+ hLibrary=NULL;
+ }
+
+ if (!m_library[0]) { LeaveCriticalSection(&cs); return; }
+
+ char buf1[MAX_PATH];
+ strcpy(buf1,g_path);
+ strcat(buf1,"\\");
+ strcat(buf1,m_library);
+
+ vi=NULL;
+ hLibrary = LoadLibrary(buf1);
+ if (hLibrary)
+ {
+ VisInfo* (*qm)(void);
+ qm=(struct _VisInfo *(__cdecl *)(void))GetProcAddress(hLibrary,"QueryModule");
+ if (!qm)
+ qm=(struct _VisInfo *(__cdecl *)(void))GetProcAddress(hLibrary,"?QueryModule@@YAPAUUltraVisInfo@@XZ");
+
+ if (!qm || !(vi=qm()))
+ {
+ vi=NULL;
+ FreeLibrary(hLibrary);
+ hLibrary=NULL;
+ }
+ }
+ if (vi) {
+ vi->OpenSettings("avs.ini"); vi->Initialize();
+ }
+ LeaveCriticalSection(&cs);
+}
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ InitializeCriticalSection(&cs);
+ m_library[0]=0;
+ hLibrary=0;
+ vi=NULL;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ if (vi) vi->SaveSettings("avs.ini");
+ if (hLibrary) FreeLibrary(hLibrary);
+ DeleteCriticalSection(&cs);
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+ EnterCriticalSection(&cs);
+ if (vi)
+ {
+ // if (vi->lRequired & VI_WAVEFORM)
+ {
+ int ch,p;
+ for (ch = 0; ch < 2; ch ++)
+ {
+ unsigned char *v=(unsigned char *)visdata[1][ch];
+ for (p = 0; p < 512; p ++)
+ vd.Waveform[ch][p]=v[p];
+ }
+ }
+ // if (vi->lRequired & VI_SPECTRUM)
+ {
+ int ch,p;
+ for (ch = 0; ch < 2; ch ++)
+ {
+ unsigned char *v=(unsigned char *) visdata[0][ch];
+ for (p = 0; p < 256; p ++)
+ vd.Spectrum[ch][p]=v[p*2]/2+v[p*2+1]/2;
+ }
+ }
+
+ vd.MillSec=GetTickCount();
+ vi->Render((unsigned long *)framebuffer,w,h,w,&vd);
+ }
+ LeaveCriticalSection(&cs);
+ return 0;
+}
+
+C_RBASE *R_SVP(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ loadComboBox(GetDlgItem(hwndDlg,IDC_COMBO1), "*.SVP", g_this->m_library);
+ loadComboBox(GetDlgItem(hwndDlg,IDC_COMBO1), "*.UVS", g_this->m_library);
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_COMBO1:
+ {
+ int a=SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
+ if (a != CB_ERR)
+ {
+ if (SendDlgItemMessage(hwndDlg,IDC_COMBO1,CB_GETLBTEXT,a,(LPARAM)g_this->m_library) == CB_ERR)
+ {
+ g_this->m_library[0]=0;
+ }
+ }
+ else
+ g_this->m_library[0]=0;
+ g_this->SetLibrary();
+ }
+ return 0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDC_CFG_SVP,hwndParent,g_DlgProc);
+}
+#else
+C_RBASE *R_SVP(char *desc)
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_text.cpp b/Src/Plugins/Visualization/vis_avs/r_text.cpp
new file mode 100644
index 00000000..e0d0edfc
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_text.cpp
@@ -0,0 +1,1012 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdio.h>
+#include <memory.h>
+#include <stdlib.h>
+#include <math.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+
+#include "avs_eelif.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+
+#define MOD_NAME "Render / Text"
+#define C_THISCLASS C_TextClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ void getWord(int n, char *buf, int max);
+ void reinit(int w, int h);
+ float GET_FLOAT(unsigned char *data, int pos);
+ void PUT_FLOAT(float f, unsigned char *data, int pos);
+ void InitializeStars(int Start);
+ void CreateStar(int A);
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_TEXT,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ CHOOSEFONT cf;
+ LOGFONT lf;
+ HBITMAP hRetBitmap;
+ HBITMAP hOldBitmap;
+ HFONT hOldFont;
+ HFONT myFont;
+ HDC hDesktopDC;
+ HDC hBitmapDC;
+ BITMAPINFO bi;
+ int enabled;
+ int color;
+ int blend;
+ int blendavg;
+ int onbeat;
+ int insertBlank;
+ int randomPos;
+ int valign;
+ int halign;
+ int onbeatSpeed;
+ int normSpeed;
+ char *text;
+ int lw,lh;
+ bool updating;
+ int outline;
+ int shadow;
+ int outlinecolor;
+ int outlinesize;
+ int curword;
+ int nb;
+ int forceBeat;
+ int xshift, yshift;
+ int _xshift, _yshift;
+ int forceshift;
+ int forcealign;
+ int _valign, _halign;
+ int oddeven;
+ int nf;
+ RECT r;
+ int *myBuffer;
+ int forceredraw;
+ int old_valign, old_halign, old_outline, oldshadow;
+ int old_curword, old_clipcolor;
+ char oldtxt[256];
+ int old_blend1, old_blend2, old_blend3;
+ int oldxshift, oldyshift;
+ int randomword;
+ int shiftinit;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+// Reinit bitmap buffer since size changed
+void C_THISCLASS::reinit(int w, int h)
+{
+// Free anything if needed
+if (lw || lh)
+ {
+ SelectObject (hBitmapDC, hOldBitmap);
+ if (hOldFont) SelectObject(hBitmapDC, hOldFont);
+ DeleteDC (hBitmapDC);
+ ReleaseDC (NULL, hDesktopDC);
+ if (myBuffer) GlobalFree(myBuffer);
+ }
+
+// Alloc buffers, select objects, init structures
+ myBuffer = (int *)GlobalAlloc(GMEM_FIXED,w*h*4);
+ hDesktopDC = GetDC (NULL);
+ hRetBitmap = CreateCompatibleBitmap (hDesktopDC, w, h);
+ hBitmapDC = CreateCompatibleDC (hDesktopDC);
+ hOldBitmap = (HBITMAP) SelectObject (hBitmapDC, hRetBitmap);
+ SetTextColor(hBitmapDC, ((color & 0xFF0000) >> 16) | (color & 0xFF00) | (color&0xFF)<<16);
+ SetBkMode(hBitmapDC, TRANSPARENT);
+ SetBkColor(hBitmapDC, 0);
+ if (myFont)
+ hOldFont = (HFONT) SelectObject(hBitmapDC, myFont);
+ else
+ hOldFont = NULL;
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = w;
+ bi.bmiHeader.biHeight = h;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 0;
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+ bi.bmiHeader.biClrImportant = 0;
+}
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+// Free up everything
+if (lw || lh)
+ {
+ SelectObject (hBitmapDC, hOldBitmap);
+ if (hOldFont) SelectObject(hBitmapDC, hOldFont);
+ DeleteDC (hBitmapDC);
+ ReleaseDC (NULL, hDesktopDC);
+ if (myBuffer) GlobalFree(myBuffer);
+ }
+if (text) GlobalFree(text);
+if (myFont)
+ DeleteObject(myFont);
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+// Init all
+ randomword=0;
+ shadow=0;
+ old_valign=0;
+ old_halign=0;
+ old_outline=-1;
+ old_curword=-1;
+ old_clipcolor=-1;
+ oldshadow=-1;
+ *oldtxt=0;
+ old_blend1=0;
+ old_blend2=0;
+ old_blend3=0;
+ _xshift=0;
+ _yshift=0;
+ forceredraw=0;
+ myBuffer = NULL;
+ curword=0;
+ forceshift=0;
+ forceBeat=0;
+ forcealign=1;
+ xshift=0;
+ yshift=0;
+ outlinecolor = 0;
+ outline=0;
+ outline=0;
+ color = 0xFFFFFF;
+ enabled = 1;
+ blend = 0;
+ blendavg = 0;
+ onbeat = 0;
+ insertBlank = 0;
+ randomPos = 0;
+ halign = DT_CENTER;
+ valign = DT_VCENTER;
+ onbeatSpeed=15;
+ normSpeed=15;
+ myFont = NULL;
+ memset(&cf, 0, sizeof(CHOOSEFONT));
+ cf.lStructSize = sizeof(CHOOSEFONT);
+ cf.lpLogFont = &lf;
+ cf.Flags = CF_EFFECTS|CF_SCREENFONTS |CF_FORCEFONTEXIST|CF_INITTOLOGFONTSTRUCT;
+ cf.rgbColors = color;
+ memset(&lf, 0, sizeof(LOGFONT));
+ text = NULL;
+ lw=lh=0;
+ updating=false;
+ nb=0;
+ outlinesize=1;
+ oddeven=0;
+ nf=0;
+ shiftinit=1;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+float C_THISCLASS::GET_FLOAT(unsigned char *data, int pos)
+{
+int a = data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24);
+float f = *(float *)&a;
+return f;
+}
+
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ int size;
+ updating=true;
+ forceredraw=1;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeat=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { insertBlank=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { randomPos=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { valign=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { halign=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { onbeatSpeed=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { normSpeed=GET_INT(); pos+=4; }
+ if (len-pos >= sizeof(cf)) { memcpy(&cf, data+pos, sizeof(cf)); pos+=sizeof(cf);}
+ cf.lpLogFont = &lf;
+ if (len-pos >= sizeof(lf)) { memcpy(&lf, data+pos, sizeof(lf)); pos+=sizeof(lf);}
+ if (len-pos >= 4) { size=GET_INT(); pos+=4; }
+ if (size > 0 && len-pos >= size)
+ {
+ if (text) GlobalFree(text);
+ text = (char *)GlobalAlloc(GMEM_FIXED,size+1);
+ memcpy(text, data+pos, size);
+ pos+=size;
+ }
+ else
+ {
+ if (text) GlobalFree(text);
+ text = NULL;
+ }
+ myFont = CreateFontIndirect(&lf);
+ if (len-pos >= 4) { outline=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { outlinecolor=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { xshift=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { yshift=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { outlinesize=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { randomword=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { shadow=GET_INT(); pos+=4; }
+ forcealign=1;
+ forceredraw=1;
+ forceshift=1;
+ shiftinit=1;
+ updating=false;
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+void C_THISCLASS::PUT_FLOAT(float f, unsigned char *data, int pos)
+{
+int y = *(int *)&f;
+data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255;
+}
+extern HWND hwnd_WinampParent;
+
+
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(onbeat); pos+=4;
+ PUT_INT(insertBlank); pos+=4;
+ PUT_INT(randomPos); pos+=4;
+ PUT_INT(valign); pos+=4;
+ PUT_INT(halign); pos+=4;
+ PUT_INT(onbeatSpeed); pos+=4;
+ PUT_INT(normSpeed); pos+=4;
+ memcpy(data+pos, &cf, sizeof(cf));
+ pos+=sizeof(cf);
+ memcpy(data+pos, &lf, sizeof(lf));
+ pos+=sizeof(lf);
+ if (text)
+ {
+ int l=strlen(text)+1;
+ PUT_INT(l); pos+=4;
+ memcpy(data+pos, text, strlen(text)+1);
+ pos+=strlen(text)+1;
+ }
+ else
+ { PUT_INT(0); pos+=4;}
+ PUT_INT(outline); pos+=4;
+ PUT_INT(outlinecolor); pos+=4;
+ PUT_INT(xshift); pos+=4;
+ PUT_INT(yshift); pos+=4;
+ PUT_INT(outlinesize); pos+=4;
+ PUT_INT(randomword); pos+=4;
+ PUT_INT(shadow); pos+=4;
+
+ return pos;
+}
+// Parse text buffer for a specified word
+void C_THISCLASS::getWord(int n, char *buf, int maxlen)
+{
+ int w=0;
+ char *p=text;
+ char *d=buf;
+ *d=0;
+ if (!p) return;
+ while (w<n && *p)
+ {
+ if (*p==';')
+ w++;
+ p++;
+ }
+
+ maxlen--; // null terminator
+ while (*p && *p != ';' && maxlen>0)
+ {
+ char *endp;
+ if ((!strnicmp(p,"$(playpos",9) || !strnicmp(p,"$(playlen",9)) && (endp = strstr(p+9,")")))
+ {
+ char buf[128];
+ int islen=strnicmp(p,"$(playpos",9);
+ int add_dig=0;
+ if (p[9]=='.')
+ add_dig=atoi(p+10);
+
+ if (add_dig > 3) add_dig=3;
+
+ int pos=0;
+
+ extern HWND hwnd_WinampParent;
+ if (IsWindow(hwnd_WinampParent))
+ {
+ if (!SendMessageTimeout( hwnd_WinampParent, WM_USER,(WPARAM)!!islen,(LPARAM)105,SMTO_BLOCK,50,(LPDWORD)&pos))
+ pos=0;
+ }
+ if (islen) pos*=1000;
+ wsprintf(buf,"%d:%02d",pos/60000,(pos/1000)%60);
+ if (add_dig>0)
+ {
+ char fmt[16];
+ wsprintf(fmt,".%%%02dd",add_dig);
+ int div=1;
+ int x;
+ for (x = 0; x < 3-add_dig; x ++)
+ {
+ div*=10;
+ }
+ wsprintf(buf+strlen(buf),fmt,(pos%1000) / div);
+ }
+
+ int l=strlen(buf);
+ if (l > maxlen) l=maxlen;
+ memcpy(d,buf,l);
+ maxlen-=l;
+ d += l;
+
+ p=endp+1;
+ }
+ else if (!strnicmp(p,"$(title",7) && (endp = strstr(p+7,")")))
+ {
+ static char this_title[256];
+ static unsigned int ltg;
+
+ unsigned int now=GetTickCount();
+
+ if (!this_title[0] || now-ltg > 1000 || now < ltg)
+ {
+ ltg=now;
+
+ char *tpp;
+ if (IsWindow(hwnd_WinampParent))
+ {
+ DWORD id;
+ if (!SendMessageTimeout( hwnd_WinampParent,WM_GETTEXT,(WPARAM)sizeof(this_title),(LPARAM)this_title,SMTO_BLOCK,50,&id) || !id)
+ {
+ this_title[0]=0;
+ }
+ }
+ tpp = this_title+strlen(this_title);
+ while (tpp >= this_title)
+ {
+ char buf[9];
+ memcpy(buf,tpp,8);
+ buf[8]=0;
+ if (!lstrcmpi(buf,"- Winamp")) break;
+ tpp--;
+ }
+ if (tpp >= this_title) tpp--;
+ while (tpp >= this_title && *tpp == ' ') tpp--;
+ *++tpp=0;
+ }
+
+ int skipnum=1,max_fmtlen=0;
+ char *titleptr=this_title;
+
+ if (p[7] == ':')
+ {
+ char *ptr=p+8;
+ if (*ptr == 'n') { ptr++; skipnum=0; }
+
+ max_fmtlen=atoi(ptr);
+ }
+
+ // use: $(reg00), $(reg00:4.5), $(title), $(title:32), $(title:n32)
+
+ if (skipnum && *titleptr >= '0' && *titleptr <= '9')
+ {
+ while (*titleptr >= '0' && *titleptr <= '9') titleptr++;
+ if (*titleptr == '.')
+ {
+ titleptr++;
+ if (*titleptr == ' ')
+ {
+ titleptr++;
+ }
+ else titleptr=this_title;
+ }
+ else titleptr=this_title;
+ }
+ int n=strlen(titleptr);
+ if (n > maxlen)n=maxlen;
+ if (max_fmtlen >0 && max_fmtlen < n) n=max_fmtlen;
+
+ memcpy(d,titleptr,n);
+ maxlen-=n;
+ d+=n;
+ p=endp+1;
+ }
+ else if (!strnicmp(p,"$(reg",5) && p[5] >= '0' && p[5] <= '9' &&
+ p[6] >= '0' && p[6] <= '9' && (endp = strstr(p+7,")")))
+ {
+ char buf[128];
+ char fmt[32];
+ int wr=atoi(p+5);
+ if (wr <0)wr=0;
+ if (wr>99)wr=99;
+ p+=7;
+ char *fmtptr=fmt;
+ *fmtptr++='%';
+ if (*p == ':')
+ {
+ p++;
+ while (fmtptr-fmt < 16 && ((*p >= '0' && *p <= '9') || *p == '.'))
+ *fmtptr++=*p++;
+ }
+ *fmtptr++='f';
+ *fmtptr++=0;
+
+ int l=sprintf(buf,fmt,NSEEL_getglobalregs()[wr]);
+ if (l > maxlen) l=maxlen;
+ memcpy(d,buf,l);
+ maxlen-=l;
+ d += l;
+ p = endp+1;
+ }
+ else
+ {
+ *d++=*p++;
+ maxlen--;
+ }
+ }
+ *d=0;
+}
+
+// Returns number of words in buffer
+static int getNWords(char *buf)
+{
+char *p=buf;
+int n=0;
+while (p && *p)
+ {
+ if (*p==';')
+ n++;
+ p++;
+ }
+return n;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int i,j;
+ int *p,*d;
+ int clipcolor;
+ char thisText[256];
+
+ if (updating) return 0;
+ if (!enabled) return 0;
+ if (isBeat&0x80000000) return 0;
+
+ if (forcealign)
+ {
+ forcealign=false;
+ _halign = halign;
+ _valign = valign;
+ }
+ if (shiftinit)
+ {
+ shiftinit=0;
+ _xshift = xshift;
+ _yshift = yshift;
+ }
+
+ // If not beat sensitive and time is up for this word
+ // OR if beat sensitive and this frame is a beat and time is up for last beat
+ if ((!onbeat && nf >= normSpeed) || (onbeat && isBeat && !nb))
+ { // Then choose which word to show
+ if (!(insertBlank && !(oddeven % 2)))
+ {
+ if (randomword)
+ curword=rand()%(getNWords(text)+1);
+ else
+ {
+ curword++;
+ curword%=(getNWords(text)+1);
+ }
+ }
+ oddeven++;
+ oddeven%=2;
+ }
+
+ if (forceBeat)
+ {
+ isBeat = 1;
+ forceBeat=0;
+ }
+
+ // If beat sensitive and frame is a beat and last beat expired, start frame timer for this beat
+ if (onbeat && isBeat && !nb)
+ nb = onbeatSpeed;
+
+ // Get the word(s) to show
+ getWord(curword, thisText, 256);
+ if (insertBlank && !oddeven)
+ *thisText=0;
+
+ // Same test as above but takes care of nb init
+ if ((!onbeat && nf >= normSpeed) || (onbeat && isBeat && nb == onbeatSpeed))
+ {
+ nf=0;
+ if (randomPos && w && h) // Handle random position
+ {
+ SIZE size={0,0};
+ GetTextExtentPoint32(hBitmapDC, thisText, strlen(thisText), &size); // Don't write outside the screen
+ _halign = DT_LEFT;
+ if (size.cx < w)
+ _xshift = rand() % (int)(((float)(w-size.cx) / (float)w) * 100.0F);
+ _valign = DT_TOP;
+ if (size.cy < h)
+ _yshift = rand() % (int)(((float)(h-size.cy) / (float)h) * 100.0F);
+ forceshift=1;
+ }
+ else
+ { // Reset position to what is specified
+ _halign = halign;
+ _valign = valign;
+ _xshift = xshift;
+ _yshift = yshift;
+ }
+ }
+
+ // Choose cliping color
+ if (color != 0 && outlinecolor != 0)
+ clipcolor = 0;
+ else
+ if (color != 0x000008 && outlinecolor != 0x000008)
+ clipcolor = 8;
+ else
+ if (color != 0x0000010 && outlinecolor != 0x0000010)
+ clipcolor = 10;
+
+ // If size changed or if we're forced to shift the buffer
+ if ((lw != w || lh != h) || forceshift)
+ {
+ if (lw != w || lh != h) // only if size changed then reinit buffer, not if its only a forcedshifting
+ reinit(w, h);
+ forceshift=0;
+ forceredraw=1; // do redraw!
+ // remember last state
+ lw = w;
+ lh = h;
+ // Compute buffer position
+ r.left = 0;
+ r.right = w;
+ r.top = 0;
+ r.bottom = h;
+ r.left += (int)((float)_xshift * (float)w / 100.0F);
+ r.right += (int)((float)_xshift * (float)w / 100.0F);
+ r.top += (int)((float)_yshift * (float)h / 100.0F);
+ r.bottom += (int)((float)_yshift * (float)h / 100.0F);
+ forceredraw=1;
+ }
+
+ // Check if we need to redraw the buffer
+ if (forceredraw ||
+ old_halign != _halign ||
+ old_valign != _valign ||
+ curword != old_curword ||
+ (*thisText && strcmp(thisText, oldtxt)) ||
+ old_clipcolor != clipcolor ||
+ (old_blend1 != (blend && !(onbeat && !nb))) ||
+ (old_blend2 != (blendavg && !(onbeat && !nb))) ||
+ (old_blend3 != (!(onbeat && !nb))) ||
+ old_outline != outline ||
+ oldshadow != shadow ||
+ _xshift != oldxshift ||
+ _yshift != oldyshift)
+ {
+ forceredraw=0;
+ old_halign = _halign;
+ old_valign = _valign;
+ old_curword = curword;
+ if (thisText) strcpy(oldtxt, thisText);
+ old_clipcolor = clipcolor;
+ old_blend1 = (blend && !(onbeat && !nb));
+ old_blend2 = (blendavg && !(onbeat && !nb));
+ old_blend3 = !(onbeat && !nb);
+ old_outline = outline;
+ oldshadow = shadow;
+ oldxshift = _xshift;
+ oldyshift = _yshift;
+
+ // Draw everything
+ p = myBuffer;
+ while (p < myBuffer+h*w) { *p = clipcolor; p++; }
+ SetDIBits(hBitmapDC, hRetBitmap, 0, h, (void *)myBuffer, &bi, DIB_RGB_COLORS);
+ if (*thisText)
+ {
+ if (outline)
+ {
+ SetTextColor(hBitmapDC, ((outlinecolor&0xFF0000) >> 16) | (outlinecolor& 0xFF00) | (outlinecolor&0xFF)<<16);
+ r.left-=outlinesize; r.right-=outlinesize; r.top-=outlinesize; r.bottom-=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.left+=outlinesize; r.right+=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.left+=outlinesize; r.right+=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.top+=outlinesize; r.bottom+=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.top+=outlinesize; r.bottom+=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.left-=outlinesize; r.right-=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.left-=outlinesize; r.right-=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.top-=outlinesize; r.bottom-=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.left+=outlinesize; r.right+=outlinesize;
+ SetTextColor(hBitmapDC, ((color&0xFF0000) >> 16) | (color& 0xFF00) | (color&0xFF)<<16);
+ }
+ else if (shadow)
+ {
+ SetTextColor(hBitmapDC, ((outlinecolor&0xFF0000) >> 16) | (outlinecolor& 0xFF00) | (outlinecolor&0xFF)<<16);
+ r.left+=outlinesize; r.right+=outlinesize; r.top+=outlinesize; r.bottom+=outlinesize;
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ r.left-=outlinesize; r.right-=outlinesize; r.top-=outlinesize; r.bottom-=outlinesize;
+ SetTextColor(hBitmapDC, ((color&0xFF0000) >> 16) | (color& 0xFF00) | (color&0xFF)<<16);
+ }
+ DrawText(hBitmapDC, thisText, strlen(thisText), &r, _valign | _halign | DT_NOCLIP | DT_SINGLELINE);
+ }
+ GetDIBits(hBitmapDC, hRetBitmap, 0, h, (void *)myBuffer, &bi, DIB_RGB_COLORS);
+ }
+
+ // Now render the bitmap text buffer over framebuffer, handle blending options.
+ // Separate blocks here so we don4t have to make w*h tests
+ p = myBuffer;
+ d = framebuffer+w*(h-1);
+
+ if (blend && !(onbeat && !nb))
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ if (*p != clipcolor) *d=BLEND(*p, *d);
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+ else
+ if (blendavg && !(onbeat && !nb))
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ if (*p != clipcolor) *d=BLEND_AVG(*p, *d);
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+ else
+ if (!(onbeat && !nb))
+ for (i=0;i<h;i++)
+ {
+ for (j=0;j<w;j++)
+ {
+ if (*p != clipcolor)
+ *d=*p;
+ d++;
+ p++;
+ }
+ d -= w*2;
+ }
+
+ // Advance frame counter
+ if (!onbeat) nf++;
+ // Decrease frametimer
+ if (onbeat && nb) nb--;
+
+
+ return 0;
+}
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hwndDlg, IDC_EDIT, g_ConfigThis->text);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETTICFREQ, 10, 0);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1, 400));
+ SendDlgItemMessage(hwndDlg, IDC_OUTLINESIZE, TBM_SETTICFREQ, 15, 0);
+ SendDlgItemMessage(hwndDlg, IDC_OUTLINESIZE, TBM_SETRANGE, TRUE, MAKELONG(1, 16));
+ SendDlgItemMessage(hwndDlg, IDC_OUTLINESIZE, TBM_SETPOS, TRUE, g_ConfigThis->outlinesize);
+ SendDlgItemMessage(hwndDlg, IDC_VSHIFT, TBM_SETTICFREQ, 50, 0);
+ SendDlgItemMessage(hwndDlg, IDC_VSHIFT, TBM_SETRANGE, TRUE, MAKELONG(0, 200));
+ SendDlgItemMessage(hwndDlg, IDC_VSHIFT, TBM_SETPOS, TRUE, g_ConfigThis->yshift+100);
+ SendDlgItemMessage(hwndDlg, IDC_HSHIFT, TBM_SETTICFREQ, 50, 0);
+ SendDlgItemMessage(hwndDlg, IDC_HSHIFT, TBM_SETRANGE, TRUE, MAKELONG(0, 200));
+ SendDlgItemMessage(hwndDlg, IDC_HSHIFT, TBM_SETPOS, TRUE, g_ConfigThis->xshift+100);
+ if (g_ConfigThis->onbeat)
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(g_ConfigThis->onbeatSpeed));
+ else
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(g_ConfigThis->normSpeed));
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->onbeat) CheckDlgButton(hwndDlg,IDC_ONBEAT,BST_CHECKED);
+ if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->outline) CheckDlgButton(hwndDlg,IDC_OUTLINE,BST_CHECKED);
+ if (g_ConfigThis->shadow) CheckDlgButton(hwndDlg,IDC_SHADOW,BST_CHECKED);
+ if (!g_ConfigThis->outline && !g_ConfigThis->shadow) CheckDlgButton(hwndDlg,IDC_PLAIN,BST_CHECKED);
+ if (g_ConfigThis->randomword) CheckDlgButton(hwndDlg,IDC_RANDWORD, BST_CHECKED);
+ switch (g_ConfigThis->valign)
+ {
+ case DT_TOP:
+ CheckDlgButton(hwndDlg,IDC_VTOP,BST_CHECKED);
+ break;
+ case DT_BOTTOM:
+ CheckDlgButton(hwndDlg,IDC_VBOTTOM,BST_CHECKED);
+ break;
+ case DT_VCENTER:
+ CheckDlgButton(hwndDlg,IDC_VCENTER,BST_CHECKED);
+ break;
+ }
+ switch (g_ConfigThis->halign)
+ {
+ case DT_LEFT:
+ CheckDlgButton(hwndDlg,IDC_HLEFT,BST_CHECKED);
+ break;
+ case DT_RIGHT:
+ CheckDlgButton(hwndDlg,IDC_HRIGHT,BST_CHECKED);
+ break;
+ case DT_CENTER:
+ CheckDlgButton(hwndDlg,IDC_HCENTER,BST_CHECKED);
+ break;
+ }
+ if (g_ConfigThis->insertBlank) CheckDlgButton(hwndDlg,IDC_BLANKS,BST_CHECKED);
+ if (g_ConfigThis->randomPos) {
+ CheckDlgButton(hwndDlg,IDC_RANDOMPOS,BST_CHECKED);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VTOP), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VBOTTOM), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VCENTER), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HLEFT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HRIGHT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HCENTER), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HSHIFT), FALSE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VSHIFT), FALSE);
+ }
+ return 1;
+ case WM_NOTIFY:
+ {
+ if ((LOWORD(wParam) == IDC_VSHIFT) || (LOWORD(wParam) == IDC_HSHIFT))
+ {
+ g_ConfigThis->yshift = SendDlgItemMessage(hwndDlg, IDC_VSHIFT, TBM_GETPOS, 0, 0)-100;
+ g_ConfigThis->xshift = SendDlgItemMessage(hwndDlg, IDC_HSHIFT, TBM_GETPOS, 0, 0)-100;
+ g_ConfigThis->forceshift=1;
+ g_ConfigThis->forceredraw=1;
+ g_ConfigThis->shiftinit=1;
+ }
+ if (LOWORD(wParam) == IDC_OUTLINESIZE)
+ {
+ g_ConfigThis->outlinesize = SendDlgItemMessage(hwndDlg, IDC_OUTLINESIZE, TBM_GETPOS, 0, 0);
+ g_ConfigThis->forceredraw=1;
+ }
+ if (LOWORD(wParam) == IDC_SPEED)
+ {
+ if (g_ConfigThis->onbeat)
+ {
+ g_ConfigThis->onbeatSpeed = SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0);
+ if (g_ConfigThis->nb > g_ConfigThis->onbeatSpeed)
+ g_ConfigThis->nb = g_ConfigThis->onbeatSpeed;
+ }
+ else
+ g_ConfigThis->normSpeed = SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0);
+ }
+ return 0;
+ }
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL || di->CtlID == IDC_DEFOUTCOL) // paint nifty color button
+ {
+ GR_DrawColoredButton(di,di->CtlID == IDC_DEFCOL ? g_ConfigThis->color : g_ConfigThis->outlinecolor);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_HRESET)
+ {
+ g_ConfigThis->xshift = 0;
+ SendDlgItemMessage(hwndDlg, IDC_HSHIFT, TBM_SETPOS, TRUE, 100);
+ g_ConfigThis->forceshift=1;
+ g_ConfigThis->forceredraw=1;
+ g_ConfigThis->shiftinit=1;
+ }
+ if (LOWORD(wParam) == IDC_VRESET)
+ {
+ g_ConfigThis->yshift = 0;
+ SendDlgItemMessage(hwndDlg, IDC_VSHIFT, TBM_SETPOS, TRUE, 100);
+ g_ConfigThis->forceshift=1;
+ g_ConfigThis->forceredraw=1;
+ g_ConfigThis->shiftinit=1;
+ }
+ if (LOWORD(wParam) == IDC_EDIT)
+ if (HIWORD(wParam) == EN_CHANGE)
+ {
+ int l;
+ if (g_ConfigThis->text)
+ GlobalFree(g_ConfigThis->text);
+ l = SendDlgItemMessage(hwndDlg, IDC_EDIT, WM_GETTEXTLENGTH, 0, 0);
+ if (!l)
+ g_ConfigThis->text = NULL;
+ else
+ {
+ g_ConfigThis->text = (char *)GlobalAlloc(GMEM_FIXED,l+2);
+ GetDlgItemText(hwndDlg, IDC_EDIT, g_ConfigThis->text, l+1);
+ }
+ g_ConfigThis->forceredraw=1;
+ }
+ if (LOWORD(wParam) == IDC_CHOOSEFONT)
+ {
+ g_ConfigThis->cf.hwndOwner = hwndDlg;
+ ChooseFont(&(g_ConfigThis->cf));
+ g_ConfigThis->updating=true;
+ g_ConfigThis->myFont = CreateFontIndirect(&(g_ConfigThis->lf));
+ g_ConfigThis->forceredraw=1;
+ if (g_ConfigThis->hOldFont)
+ SelectObject(g_ConfigThis->hBitmapDC, g_ConfigThis->hOldFont);
+ if (g_ConfigThis->myFont)
+ g_ConfigThis->hOldFont = (HFONT)SelectObject(g_ConfigThis->hBitmapDC, g_ConfigThis->myFont);
+ else
+ g_ConfigThis->hOldFont = NULL;
+ g_ConfigThis->updating=false;
+ }
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ONBEAT) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_BLANKS) ||
+ (LOWORD(wParam) == IDC_RANDOMPOS) ||
+ (LOWORD(wParam) == IDC_OUTLINE) ||
+ (LOWORD(wParam) == IDC_SHADOW) ||
+ (LOWORD(wParam) == IDC_PLAIN) ||
+ (LOWORD(wParam) == IDC_HLEFT) ||
+ (LOWORD(wParam) == IDC_HRIGHT) ||
+ (LOWORD(wParam) == IDC_HCENTER) ||
+ (LOWORD(wParam) == IDC_VTOP) ||
+ (LOWORD(wParam) == IDC_VBOTTOM) ||
+ (LOWORD(wParam) == IDC_VCENTER) ||
+ (LOWORD(wParam) == IDC_RANDWORD) ||
+ (LOWORD(wParam) == IDC_5050) )
+ {
+ g_ConfigThis->forceredraw=1;
+ g_ConfigThis->randomword=IsDlgButtonChecked(hwndDlg,IDC_RANDWORD)?1:0;
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->outline=IsDlgButtonChecked(hwndDlg,IDC_OUTLINE)?1:0;
+ g_ConfigThis->shadow=IsDlgButtonChecked(hwndDlg,IDC_SHADOW)?1:0;
+ g_ConfigThis->onbeat=IsDlgButtonChecked(hwndDlg,IDC_ONBEAT)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ if (g_ConfigThis->onbeat)
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(g_ConfigThis->onbeatSpeed));
+ else
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, (int)(g_ConfigThis->normSpeed));
+ g_ConfigThis->insertBlank=IsDlgButtonChecked(hwndDlg,IDC_BLANKS)?1:0;
+ g_ConfigThis->randomPos=IsDlgButtonChecked(hwndDlg,IDC_RANDOMPOS)?1:0;
+ g_ConfigThis->valign=IsDlgButtonChecked(hwndDlg,IDC_VTOP)?DT_TOP:g_ConfigThis->valign;
+ g_ConfigThis->valign=IsDlgButtonChecked(hwndDlg,IDC_VCENTER)?DT_VCENTER:g_ConfigThis->valign;
+ g_ConfigThis->valign=IsDlgButtonChecked(hwndDlg,IDC_VBOTTOM)?DT_BOTTOM:g_ConfigThis->valign;
+ g_ConfigThis->halign=IsDlgButtonChecked(hwndDlg,IDC_HLEFT)?DT_LEFT:g_ConfigThis->halign;
+ g_ConfigThis->halign=IsDlgButtonChecked(hwndDlg,IDC_HRIGHT)?DT_RIGHT:g_ConfigThis->halign;
+ g_ConfigThis->halign=IsDlgButtonChecked(hwndDlg,IDC_HCENTER)?DT_CENTER:g_ConfigThis->halign;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VTOP), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VBOTTOM), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VCENTER), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HLEFT), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HRIGHT), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HCENTER), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_HSHIFT), g_ConfigThis->randomPos ? FALSE : TRUE);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_VSHIFT), g_ConfigThis->randomPos ? FALSE : TRUE);
+ if ((LOWORD(wParam) == IDC_ONBEAT) && g_ConfigThis->onbeat)
+ g_ConfigThis->nb=g_ConfigThis->onbeatSpeed;
+ if ((LOWORD(wParam) == IDC_RANDOMPOS) && g_ConfigThis->randomPos)
+ g_ConfigThis->forcealign=1;
+ }
+ if (LOWORD(wParam) == IDC_DEFCOL ||LOWORD(wParam) == IDC_DEFOUTCOL) // handle clicks to nifty color button
+ {
+ int *a=&(LOWORD(wParam) == IDC_DEFCOL ? g_ConfigThis->color : g_ConfigThis->outlinecolor);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ if (LOWORD(wParam) == IDC_DEFCOL)
+ g_ConfigThis->color = *a;
+ else
+ g_ConfigThis->outlinecolor = *a;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,LOWORD(wParam)),NULL,TRUE);
+ g_ConfigThis->updating=true;
+ SetTextColor(g_ConfigThis->hBitmapDC, ((g_ConfigThis->color&0xFF0000) >> 16) | (g_ConfigThis->color& 0xFF00) | (g_ConfigThis->color&0xFF)<<16);
+ g_ConfigThis->forceredraw=1;
+ g_ConfigThis->updating=false;
+ }
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_TEXT,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Text(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+
+#else
+C_RBASE *R_Text(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{ return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_timescope.cpp b/Src/Plugins/Visualization/vis_avs/r_timescope.cpp
new file mode 100644
index 00000000..2cd67dc5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_timescope.cpp
@@ -0,0 +1,289 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+#include <stdio.h>
+
+
+#ifndef LASER
+
+#define MOD_NAME "Render / Timescope"
+#define C_THISCLASS C_TimescopeClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_RENDER_TIMESCOPE,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ int which_ch;
+ int enabled;
+ int color;
+ int blend, blendavg;
+ int nbands;
+ int x;
+ int oldh;
+ };
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+C_THISCLASS::~C_THISCLASS()
+{
+}
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ x = 0;
+ color = 0xFFFFFF;
+ blend = 2;
+ blendavg = 0;
+ enabled=1;
+ nbands = 576;
+ oldh=-1;
+ which_ch=2;
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { color=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { blendavg=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { which_ch=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { nbands=GET_INT(); pos+=4; }
+ oldh=-1;
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(color); pos+=4;
+ PUT_INT(blend); pos+=4;
+ PUT_INT(blendavg); pos+=4;
+ PUT_INT(which_ch); pos+=4;
+ PUT_INT(nbands); pos+=4;
+ return pos;
+}
+
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ int i,j;
+ int c;
+ char center_channel[576];
+ unsigned char *fa_data;
+
+ if (!enabled) return 0;
+ if (isBeat&0x80000000) return 0;
+
+ if (which_ch >=2)
+ {
+ for (j = 0; j < 576; j ++) center_channel[j]=visdata[1][0][j]/2+visdata[1][1][j]/2;
+ fa_data=(unsigned char *)center_channel;
+ }
+ else fa_data=(unsigned char *)&visdata[1][which_ch][0];
+
+ x++;
+ x %= w;
+ framebuffer+=x;
+ int r,g,b;
+ r=color&0xff;
+ g=(color>>8)&0xff;
+ b=(color>>16)&0xff;
+ for (i=0;i<h;i++)
+ {
+ c = visdata[0][0][(i*nbands)/h] & 0xFF;
+ c = (r*c)/256 + (((g*c)/256)<<8) + (((b*c)/256)<<16);
+ if (blend == 2)
+ BLEND_LINE(framebuffer,c);
+ else if (blend == 1)
+ framebuffer[0]=BLEND(framebuffer[0],c);
+ else if (blendavg)
+ framebuffer[0]=BLEND_AVG(framebuffer[0],c);
+ else
+ framebuffer[0]=c;
+ framebuffer+=w;
+ }
+
+ return 0;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_ConfigThis->blend==2) CheckDlgButton(hwndDlg,IDC_DEFAULTBLEND,BST_CHECKED);
+ else if (g_ConfigThis->blend) CheckDlgButton(hwndDlg,IDC_ADDITIVE,BST_CHECKED);
+ if (g_ConfigThis->blendavg) CheckDlgButton(hwndDlg,IDC_5050,BST_CHECKED);
+ if (!g_ConfigThis->blend && !g_ConfigThis->blendavg)
+ CheckDlgButton(hwndDlg,IDC_REPLACE,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg, IDC_BANDS, TBM_SETTICFREQ, 32, 0);
+ SendDlgItemMessage(hwndDlg, IDC_BANDS, TBM_SETRANGE, TRUE, MAKELONG(16, 576));
+ SendDlgItemMessage(hwndDlg, IDC_BANDS, TBM_SETPOS, TRUE, g_ConfigThis->nbands);
+ {
+ char txt[64];
+ wsprintf(txt, WASABI_API_LNGSTRING(IDS_DRAW_X_BANDS), g_ConfigThis->nbands);
+ SetDlgItemText(hwndDlg, IDC_BANDTXT, txt);
+ }
+ if (g_ConfigThis->which_ch==0)
+ CheckDlgButton(hwndDlg,IDC_LEFT,BST_CHECKED);
+ else if (g_ConfigThis->which_ch==1)
+ CheckDlgButton(hwndDlg,IDC_RIGHT,BST_CHECKED);
+ else
+ CheckDlgButton(hwndDlg,IDC_CENTER,BST_CHECKED);
+ return 1;
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di=(DRAWITEMSTRUCT *)lParam;
+ if (di->CtlID == IDC_DEFCOL) // paint nifty color button
+ {
+ int w=di->rcItem.right-di->rcItem.left;
+ int _color=g_ConfigThis->color;
+ _color = ((_color>>16)&0xff)|(_color&0xff00)|((_color<<16)&0xff0000);
+
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ LOGBRUSH lb={ (COLORREF)BS_SOLID,(COLORREF)_color,(COLORREF)0};
+ hPen = (HPEN)CreatePen(PS_SOLID,0,_color);
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+ DeleteObject(hBrush);
+ DeleteObject(hPen);
+ }
+ }
+ return 0;
+ case WM_COMMAND:
+ if ((LOWORD(wParam) == IDC_CHECK1) ||
+ (LOWORD(wParam) == IDC_ADDITIVE) ||
+ (LOWORD(wParam) == IDC_REPLACE) ||
+ (LOWORD(wParam) == IDC_5050) ||
+ (LOWORD(wParam) == IDC_DEFAULTBLEND))
+ {
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_ADDITIVE)?1:0;
+ if (!g_ConfigThis->blend)
+ g_ConfigThis->blend=IsDlgButtonChecked(hwndDlg,IDC_DEFAULTBLEND)?2:0;
+ g_ConfigThis->blendavg=IsDlgButtonChecked(hwndDlg,IDC_5050)?1:0;
+ }
+ if (LOWORD(wParam) == IDC_DEFCOL) // handle clicks to nifty color button
+ {
+ int *a=&(g_ConfigThis->color);
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwndDlg;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ g_ConfigThis->color = *a;
+ }
+ InvalidateRect(GetDlgItem(hwndDlg,IDC_DEFCOL),NULL,TRUE);
+ }
+ if (LOWORD(wParam) == IDC_LEFT || LOWORD(wParam) == IDC_RIGHT || LOWORD(wParam)==IDC_CENTER)
+ {
+ if (IsDlgButtonChecked(hwndDlg,IDC_LEFT)) g_ConfigThis->which_ch=0;
+ else if (IsDlgButtonChecked(hwndDlg,IDC_RIGHT)) g_ConfigThis->which_ch=1;
+ else g_ConfigThis->which_ch=2;
+ }
+ break;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_BANDS)
+ {
+ g_ConfigThis->nbands = SendDlgItemMessage(hwndDlg, IDC_BANDS, TBM_GETPOS, 0, 0);
+ {
+ char txt[64];
+ wsprintf(txt, WASABI_API_LNGSTRING(IDS_DRAW_X_BANDS), g_ConfigThis->nbands);
+ SetDlgItemText(hwndDlg, IDC_BANDTXT, txt);
+ }
+ }
+ return 0;
+ }
+return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_TIMESCOPE,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_Timescope(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_Timescope(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_trans.cpp b/Src/Plugins/Visualization/vis_avs/r_trans.cpp
new file mode 100644
index 00000000..9181c354
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_trans.cpp
@@ -0,0 +1,982 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+#define M_PI 3.14159265358979323846
+
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "avs_eelif.h"
+#include "../Agave/Language/api_language.h"
+#include "../nu/AutoWide.h"
+#include <math.h>
+
+
+#ifndef LASER
+
+#define C_THISCLASS C_TransTabClass
+#define MOD_NAME "Trans / Movement"
+
+#define REFFECT_MIN 3
+#define REFFECT_MAX 23
+
+typedef struct {
+// int index; // Just here for descriptive purposes, makes it easy to match stuff up.
+ int list_desc; // The string to show in the listbox.
+ char *eval_desc; // The optional string to display in the evaluation editor.
+ char uses_eval; // If this is true, the preset engages the eval library and there is NULL in the radial_effects array for its entry
+ char uses_rect; // This value sets the checkbox for rectangular calculation
+} Description;
+
+static Description descriptions[]=
+{
+ {/* 0,*/ IDS_NONE, "", 0, 0},
+ {/* 1,*/ IDS_SLIGHT_FUZZIFY, "", 0, 0},
+ {/* 2,*/ IDS_SHIFT_ROTATE_LEFT, "x=x+1/32; // use wrap for this one", 0, 1},
+ {/* 3,*/ IDS_BIG_SWIRL_OUT, "r = r + (0.1 - (0.2 * d));\r\nd = d * 0.96;", 0, 0},
+ {/* 4,*/ IDS_MEDIUM_SWIRL, "d = d * (0.99 * (1.0 - sin(r-$PI*0.5) / 32.0));\r\nr = r + (0.03 * sin(d * $PI * 4));", 0, 0},
+ {/* 5,*/ IDS_SUNBURSTER, "d = d * (0.94 + (cos((r-$PI*0.5) * 32.0) * 0.06));", 0, 0},
+ {/* 6,*/ IDS_SWIRL_TO_CENTER, "d = d * (1.01 + (cos((r-$PI*0.5) * 4) * 0.04));\r\nr = r + (0.03 * sin(d * $PI * 4));", 0, 0},
+ {/* 7,*/ IDS_BLOCKY_PARTIAL_OUT, "", 0, 0},
+ {/* 8,*/ IDS_SWIRLING_AROUND_BOTH_WAYS, "r = r + (0.1 * sin(d * $PI * 5));", 0, 0},
+ {/* 9,*/ IDS_BUBBLING_OUTWARD, "t = sin(d * $PI);\r\nd = d - (8*t*t*t*t*t)/sqrt((sw*sw+sh*sh)/4);", 0, 0},
+ {/*10,*/ IDS_BUBBLING_OUTWARD_WITH_SWIRL, "t = sin(d * $PI);\r\nd = d - (8*t*t*t*t*t)/sqrt((sw*sw+sh*sh)/4);\r\nt=cos(d*$PI/2.0);\r\nr= r + 0.1*t*t*t;", 0, 0},
+ {/*11,*/ IDS_5_POINTED_DISTRO, "d = d * (0.95 + (cos(((r-$PI*0.5) * 5.0) - ($PI / 2.50)) * 0.03));", 0, 0},
+ {/*12,*/ IDS_TUNNELING, "r = r + 0.04;\r\nd = d * (0.96 + cos(d * $PI) * 0.05);", 0, 0},
+ {/*13,*/ IDS_BLEEDIN, "t = cos(d * $PI);\r\nr = r + (0.07 * t);\r\nd = d * (0.98 + t * 0.10);", 0, 0},
+ {/*14,*/ IDS_SHIFTED_BIG_SWIRL_OUT, "// this is a very bad approximation in script. fixme.\r\nd=sqrt(x*x+y*y); r=atan2(y,x);\r\nr=r+0.1-0.2*d; d=d*0.96;\r\nx=cos(r)*d + 8/128; y=sin(r)*d;", 0, 1},
+ {/*15,*/ IDS_PSYCHOTIC_BEAMING_OUTWARD, "d = 0.15", 0, 0},
+ {/*16,*/ IDS_COSINE_RADIAL_3_WAY, "r = cos(r * 3)", 0, 0},
+ {/*17,*/ IDS_SPINNY_TUBE, "d = d * (1 - ((d - .35) * .5));\r\nr = r + .1;", 0, 0},
+ {/*18,*/ IDS_RADIAL_SWIRLIES, "d = d * (1 - (sin((r-$PI*0.5) * 7) * .03));\r\nr = r + (cos(d * 12) * .03);", 1, 0},
+ {/*19,*/ IDS_SWILL, "d = d * (1 - (sin((r - $PI*0.5) * 12) * .05));\r\nr = r + (cos(d * 18) * .05);\r\nd = d * (1-((d - .4) * .03));\r\nr = r + ((d - .4) * .13)", 1, 0},
+ {/*20,*/ IDS_GRIDLEY, "x = x + (cos(y * 18) * .02);\r\ny = y + (sin(x * 14) * .03);", 1, 1},
+ {/*21,*/ IDS_GRAPEVINE, "x = x + (cos(abs(y-.5) * 8) * .02);\r\ny = y + (sin(abs(x-.5) * 8) * .05);\r\nx = x * .95;\r\ny = y * .95;", 1, 1},
+ {/*22,*/ IDS_QUADRANT, "y = y * ( 1 + (sin(r + $PI/2) * .3) );\r\nx = x * ( 1 + (cos(r + $PI/2) * .3) );\r\nx = x * .995;\r\ny = y * .995;", 1, 1},
+ {/*23,*/ IDS_6_WAY_KALAEIDA, "y = (r*6)/($PI); x = d;", 1, 1},
+};
+
+#define MAKE_REFFECT(n,x) void _ref##n(double &r, double &d, double max_d, int &xo, int &yo) { x }
+
+typedef void t_reffect(double &r, double &d, double max_d, int &xo, int &yo);
+
+MAKE_REFFECT(3, r+=0.1-0.2*(d/max_d); d*=0.96;)
+MAKE_REFFECT(4, d*=0.99*(1.0-sin(r)/32.0); r+=0.03*sin(d/max_d * M_PI * 4);)
+MAKE_REFFECT(5, d*=0.94+(cos(r*32.0)*0.06);)
+MAKE_REFFECT(6, d*=1.01+(cos(r*4.0)*0.04); r+=0.03*sin(d/max_d * M_PI * 4);)
+MAKE_REFFECT(8, r+=0.1*sin(d/max_d*M_PI*5);)
+MAKE_REFFECT(9, double t; t=sin(d/max_d*M_PI); d-=8*t*t*t*t*t; )
+MAKE_REFFECT(10,double t; t=sin(d/max_d*M_PI); d-=8*t*t*t*t*t; t=cos((d/max_d)*M_PI/2.0); r+=0.1*t*t*t; )
+MAKE_REFFECT(11, d*=0.95+(cos(r*5.0 - M_PI/2.50)*0.03); )
+MAKE_REFFECT(12, r+=0.04; d*=0.96+cos(d/max_d*M_PI)*0.05; )
+MAKE_REFFECT(13, double t; t=cos(d/max_d*M_PI); r+=0.07*t; d*=0.98+t*0.10; )
+MAKE_REFFECT(14, r+=0.1-0.2*(d/max_d); d*=0.96; xo=8; )
+MAKE_REFFECT(15, d=max_d*0.15;)
+MAKE_REFFECT(16, r=cos(r*3);)
+MAKE_REFFECT(17, d*=(1-(((d/max_d)-.35)*.5)); r+=.1;)
+
+static t_reffect *radial_effects[REFFECT_MAX-REFFECT_MIN+1]=
+{
+ _ref3, _ref4, _ref5, _ref6, NULL, _ref8, _ref9, _ref10, _ref11, _ref12, _ref13,
+ _ref14, _ref15, _ref16, _ref17, NULL/*18*/, NULL/*19*/, NULL/*20*/, NULL/*21*/,
+ NULL/*22*/, NULL/*23*/,
+};
+
+static inline bool effect_uses_eval(int t)
+{
+ bool retval = false;
+ if ((t >= REFFECT_MIN) && (t <= REFFECT_MAX))
+ {
+ if (descriptions[t].uses_eval)
+ {
+ retval = true;
+ }
+ }
+ return retval;
+}
+
+
+class C_THISCLASS : public C_RBASE2 {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+
+ virtual int smp_getflags() { return 1; }
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // return value is that of render() for fbstuff etc
+
+ virtual char *get_desc() { return MOD_NAME; }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ int *trans_tab, trans_tab_w, trans_tab_h, trans_tab_subpixel;
+ int trans_effect;
+ RString effect_exp;
+ int effect_exp_ch;
+ int effect,blend;
+ int sourcemapped;
+ int rectangular;
+ int subpixel;
+ int wrap;
+ CRITICAL_SECTION rcs;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { effect=GET_INT(); pos+=4; }
+ if (effect == 32767)
+ {
+ if (!memcmp(data+pos,"!rect ",6))
+ {
+ pos+=6;
+ rectangular=1;
+ }
+ if (data[pos]==1)
+ {
+ pos++;
+ int l=GET_INT(); pos+=4;
+ if (l > 0 && len-pos >= l)
+ {
+ effect_exp.resize(l);
+ memcpy(effect_exp.get(), data+pos, l);
+ pos+=l;
+ }
+ else
+ {
+ effect_exp.resize(1);
+ effect_exp.get()[0]=0;
+ }
+ }
+ else if (len-pos >= 256)
+ {
+ char buf[257];
+ int l=256-(rectangular?6:0);
+ memcpy(buf,data+pos,l);
+ buf[l]=0;
+ effect_exp.assign(buf);
+ pos+=l;
+ }
+ }
+ if (len-pos >= 4) { blend=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { sourcemapped=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { rectangular=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { subpixel=GET_INT(); pos+=4; }
+ else subpixel=0;
+ if (len-pos >= 4) { wrap=GET_INT(); pos+=4; }
+ else wrap=0;
+ if (!effect && len-pos >= 4)
+ {
+ effect=GET_INT(); pos+=4;
+ }
+
+ if (effect != 32767 && effect > REFFECT_MAX || effect < 0)
+ effect=0;
+
+ // Once we know what our _real_ effect value is, if it uses the evaluator, allocate and stuff the string, here.
+ /*
+ if (effect_uses_eval(effect))
+ {
+ const char *eval_string = descriptions[effect].eval_desc;
+ int length = strlen(eval_string);
+ effect_exp.resize(length+1);
+ strcpy(effect_exp.get(), eval_string);
+ }
+ */
+
+ effect_exp_ch=1;
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+
+ // the reason this is 15, and not REFFECT_MAX, is because old versions of AVS barf
+ // if effect is > 15, so we put 0, and at the end put the new value
+ if (effect > 15 && effect != 32767)
+ {
+ PUT_INT(0);
+ pos += 4;
+ }
+ else
+ {
+ PUT_INT(effect);
+ pos+=4;
+ }
+ if (effect == 32767)
+ {
+ int l=strlen(effect_exp.get())+1;
+ data[pos++]=1;
+ PUT_INT(l);
+ pos+=4;
+ memcpy(data+pos,effect_exp.get(),strlen(effect_exp.get())+1);
+ pos+=strlen(effect_exp.get())+1;
+ }
+ PUT_INT(blend); pos+=4;
+ PUT_INT(sourcemapped); pos+=4;
+ PUT_INT(rectangular); pos+=4;
+ PUT_INT(subpixel); pos+=4;
+ PUT_INT(wrap); pos+=4;
+
+ // see note on '15' above =)
+ if (effect > 15 && effect != 32767)
+ {
+ PUT_INT(effect);
+ pos+=4;
+ }
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ InitializeCriticalSection(&rcs);
+ sourcemapped=0;
+ trans_tab=NULL;
+ trans_tab_w=trans_tab_h=0;
+ effect=1;
+ trans_effect=0;
+ blend=0;
+ effect_exp.assign("");
+ rectangular=0;
+ subpixel=1;
+ wrap=0;
+ trans_tab_subpixel=0;
+ effect_exp_ch=1;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ if (trans_tab) GlobalFree(trans_tab);
+ trans_tab=NULL;
+ trans_tab_w=trans_tab_h=0;
+ trans_effect=0;
+ DeleteCriticalSection(&rcs);
+}
+
+int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!effect) return 0;
+
+ if (!trans_tab || trans_tab_w != w || trans_tab_h != h || effect != trans_effect ||
+ effect_exp_ch)
+ {
+ int p;
+ int *transp,x;
+ if (trans_tab) GlobalFree(trans_tab);
+ trans_tab_w=w;
+ trans_tab_h=h;
+ trans_tab=(int*)GlobalAlloc(GMEM_FIXED,trans_tab_w*trans_tab_h*sizeof(int));
+ trans_effect=effect;
+ trans_tab_subpixel=(subpixel && trans_tab_w*trans_tab_h < (1<<22) &&
+ ((trans_effect >= REFFECT_MIN && trans_effect <= REFFECT_MAX
+ && trans_effect != 1 && trans_effect != 2 && trans_effect != 7
+ )||trans_effect ==32767));
+
+ /* generate trans_tab */
+ transp=trans_tab;
+ x=w*h;
+ p=0;
+
+ if (trans_effect == 1)
+ {
+ while (x--)
+ {
+ int r=(p++)+(rand()%3)-1 + ((rand()%3)-1)*w;
+ *transp++ = min(w*h-1,max(r,0));
+ }
+ }
+ else if (trans_effect == 2)
+ {
+ int y=h;
+ while (y--)
+ {
+ int x=w;
+ int lp=w/64;
+ while (x--)
+ {
+ *transp++ = p+lp++;
+ if (lp >= w) lp-=w;
+ }
+ p+=w;
+ }
+ }
+ else if (trans_effect == 7)
+ {
+ int y;
+ for (y = 0; y < h; y ++)
+ {
+ for (x = 0; x < w; x ++)
+ {
+ if (x&2 || y&2)
+ {
+ *transp++ = x+y*w;
+ }
+ else
+ {
+ int xp=w/2+(((x&~1)-w/2)*7)/8;
+ int yp=h/2+(((y&~1)-h/2)*7)/8;
+ *transp++=xp+yp*w;
+ }
+ }
+ }
+ }
+ else if (trans_effect >= REFFECT_MIN && trans_effect <= REFFECT_MAX && !effect_uses_eval(trans_effect))
+ {
+ double max_d=sqrt((w*w+h*h)/4.0);
+ int y;
+ t_reffect *ref=radial_effects[trans_effect-REFFECT_MIN];
+ if (ref) for (y = 0; y < h; y ++)
+ {
+ for (x = 0; x < w; x ++)
+ {
+ double r,d;
+ double xd,yd;
+ int ow,oh,xo=0,yo=0;
+ xd=x-(w/2);
+ yd=y-(h/2);
+ d=sqrt(xd*xd+yd*yd);
+ r=atan2(yd,xd);
+
+ ref(r,d,max_d,xo,yo);
+
+ double tmp1,tmp2;
+ tmp1= ((h/2) + sin(r)*d + 0.5) + (yo*h)*(1.0/256.0);
+ tmp2= ((w/2) + cos(r)*d + 0.5) + (xo*w)*(1.0/256.0);
+ oh=(int)tmp1;
+ ow=(int)tmp2;
+ if (trans_tab_subpixel)
+ {
+ int xpartial=(int)(32.0*(tmp2-ow));
+ int ypartial=(int)(32.0*(tmp1-oh));
+ if (wrap)
+ {
+ ow%=(w-1);
+ oh%=(h-1);
+ if (ow<0)ow+=w-1;
+ if (oh<0)oh+=h-1;
+ }
+ else
+ {
+ if (ow < 0) { xpartial=0; ow=0; }
+ if (ow >= w-1) { xpartial=31; ow=w-2; }
+ if (oh < 0) { ypartial=0; oh=0; }
+ if (oh >= h-1) {ypartial=31; oh=h-2; }
+ }
+ *transp++ = ow+oh*w | (ypartial<<22) | (xpartial<<27);
+ }
+ else
+ {
+ if (wrap)
+ {
+ ow%=(w);
+ oh%=(h);
+ if (ow<0)ow+=w;
+ if (oh<0)oh+=h;
+ }
+ else
+ {
+ if (ow < 0) ow=0;
+ if (ow >= w) ow=w-1;
+ if (oh < 0) oh=0;
+ if (oh >= h) oh=h-1;
+ }
+ *transp++ = ow+oh*w;
+ }
+ }
+ }
+ }
+ else if (trans_effect == 32767 || effect_uses_eval(trans_effect))
+ {
+ NSEEL_VMCTX AVS_EEL_CONTEXTNAME;
+ AVS_EEL_INITINST();
+ double max_d=sqrt((double)(w*w+h*h))/2.0;
+ double divmax_d=1.0/max_d;
+ int y;
+ double *d = registerVar("d");
+ double *r = registerVar("r");
+ double *px = registerVar("x");
+ double *py = registerVar("y");
+ double *pw = registerVar("sw");
+ double *ph = registerVar("sh");
+ NSEEL_CODEHANDLE codehandle=0;
+ int offs=0;
+ int is_rect = trans_effect == 32767 ? rectangular : descriptions[trans_effect].uses_rect;
+ *pw=w;
+ *ph=h;
+ EnterCriticalSection(&rcs);
+ codehandle=compileCode(
+ trans_effect == 32767 ? effect_exp.get() : descriptions[trans_effect].eval_desc
+ );
+ LeaveCriticalSection(&rcs);
+ if (codehandle)
+ {
+ double w2=w/2;
+ double h2=h/2;
+ double xsc=1.0/w2,ysc=1.0/h2;
+
+ for (y = 0; y < h; y ++)
+ {
+ for (x = 0; x < w; x ++)
+ {
+ double xd,yd;
+ int ow,oh;
+ xd=x-w2;
+ yd=y-h2;
+ *px=xd*xsc;
+ *py=yd*ysc;
+ *d=sqrt(xd*xd+yd*yd)*divmax_d;
+ *r=atan2(yd,xd) + M_PI*0.5;
+
+ executeCode(codehandle,visdata);
+
+ double tmp1,tmp2;
+ if (!is_rect)
+ {
+ *d *= max_d;
+ *r -= M_PI/2.0;
+ tmp1=((h/2) + sin(*r)* *d);
+ tmp2=((w/2) + cos(*r)* *d);
+ }
+ else
+ {
+ tmp1=((*py+1.0)*h2);
+ tmp2=((*px+1.0)*w2);
+ }
+ if (trans_tab_subpixel)
+ {
+ oh=(int) tmp1;
+ ow=(int) tmp2;
+ int xpartial=(int)(32.0*(tmp2-ow));
+ int ypartial=(int)(32.0*(tmp1-oh));
+ if (wrap)
+ {
+ ow%=(w-1);
+ oh%=(h-1);
+ if (ow<0)ow+=w-1;
+ if (oh<0)oh+=h-1;
+ }
+ else
+ {
+ if (ow < 0) { xpartial=0; ow=0; }
+ if (ow >= w-1) { xpartial=31; ow=w-2; }
+ if (oh < 0) { ypartial=0; oh=0; }
+ if (oh >= h-1) {ypartial=31; oh=h-2; }
+ }
+ *transp++ = ow+oh*w | (ypartial<<22) | (xpartial<<27);
+ }
+ else
+ {
+ tmp1+=0.5;
+ tmp2+=0.5;
+ oh=(int) tmp1;
+ ow=(int) tmp2;
+ if (wrap)
+ {
+ ow%=(w);
+ oh%=(h);
+ if (ow<0)ow+=w;
+ if (oh<0)oh+=h;
+ }
+ else
+ {
+ if (ow < 0) ow=0;
+ if (ow >= w) ow=w-1;
+ if (oh < 0) oh=0;
+ if (oh >= h) oh=h-1;
+ }
+ *transp++ = ow+oh*w;
+ }
+ }
+ }
+ }
+ else
+ {
+ transp=trans_tab;
+ trans_tab_subpixel=0;
+ for (x = 0; x < w*h; x ++)
+ *transp++=x;
+ }
+ freeCode(codehandle);
+ AVS_EEL_QUITINST();
+ }
+ effect_exp_ch=0;
+ }
+
+ if (!(isBeat & 0x80000000))
+ {
+ if ((sourcemapped&2)&&isBeat) sourcemapped^=1;
+ if (sourcemapped&1)
+ {
+ if (!blend) memset(fbout,0,w*h*sizeof(int));
+ else memcpy(fbout,framebuffer,w*h*sizeof(int));
+ }
+ }
+ return max_threads;
+}
+
+void C_THISCLASS::smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!effect) return;
+
+#define OFFSET_MASK ((1<<22)-1)
+
+ unsigned int *inp = (unsigned int *) framebuffer;
+ unsigned int *outp;
+ int *transp, x;
+
+ if (max_threads < 1) max_threads=1;
+
+ int start_l = ( this_thread * h ) / max_threads;
+ int end_l;
+
+ if (this_thread >= max_threads - 1) end_l = h;
+ else end_l = ( (this_thread+1) * h ) / max_threads;
+
+ int outh=end_l-start_l;
+ if (outh<1) return;
+
+ int skip_pix=start_l*w;
+ transp=trans_tab;
+
+ outp = (unsigned int *) fbout;
+ x=(w*outh)/4;
+ if (sourcemapped&1)
+ {
+ inp += skip_pix;
+ transp += skip_pix;
+ if (trans_tab_subpixel)
+ {
+ timingEnter(3);
+ while (x--)
+ {
+ fbout[transp[0]&OFFSET_MASK]=BLEND_MAX(inp[0],fbout[transp[0]&OFFSET_MASK]);
+ fbout[transp[1]&OFFSET_MASK]=BLEND_MAX(inp[1],fbout[transp[1]&OFFSET_MASK]);
+ fbout[transp[2]&OFFSET_MASK]=BLEND_MAX(inp[2],fbout[transp[2]&OFFSET_MASK]);
+ fbout[transp[3]&OFFSET_MASK]=BLEND_MAX(inp[3],fbout[transp[3]&OFFSET_MASK]);
+ inp+=4;
+ transp+=4;
+ }
+ timingLeave(3);
+ x = (w*outh)&3;
+ if (x>0) while (x--)
+ {
+ fbout[transp[0]&OFFSET_MASK]=BLEND_MAX(inp++[0],fbout[transp[0]&OFFSET_MASK]);
+ transp++;
+ }
+ }
+ else
+ {
+ {
+ timingEnter(3);
+ while (x--)
+ {
+ fbout[transp[0]]=BLEND_MAX(inp[0],fbout[transp[0]]);
+ fbout[transp[1]]=BLEND_MAX(inp[1],fbout[transp[1]]);
+ fbout[transp[2]]=BLEND_MAX(inp[2],fbout[transp[2]]);
+ fbout[transp[3]]=BLEND_MAX(inp[3],fbout[transp[3]]);
+ inp+=4;
+ transp+=4;
+ }
+ timingLeave(3);
+ x = (w*outh)&3;
+ if (x>0) while (x--)
+ {
+ fbout[transp[0]]=BLEND_MAX(inp++[0],fbout[transp[0]]);
+ transp++;
+ }
+ }
+ }
+ if (blend)
+ {
+ framebuffer += skip_pix;
+ fbout += skip_pix;
+ x=(w*outh)/4;
+ while (x--)
+ {
+ fbout[0]=BLEND_AVG(fbout[0],framebuffer[0]);
+ fbout[1]=BLEND_AVG(fbout[1],framebuffer[1]);
+ fbout[2]=BLEND_AVG(fbout[2],framebuffer[2]);
+ fbout[3]=BLEND_AVG(fbout[3],framebuffer[3]);
+ fbout+=4;
+ framebuffer+=4;
+ }
+ x=(w*outh)&3;
+ while (x--)
+ {
+ fbout[0]=BLEND_AVG(fbout[0],framebuffer[0]);
+ fbout++;
+ framebuffer++;
+ }
+ }
+ }
+ else
+ {
+ inp += skip_pix;
+ outp += skip_pix;
+ transp += skip_pix;
+ if (trans_tab_subpixel&&blend)
+ {
+ while (x--)
+ {
+ int offs=transp[0]&OFFSET_MASK;
+ outp[0]=BLEND_AVG(inp[0],BLEND4((unsigned int *)framebuffer+offs,w,((transp[0]>>24)&(31<<3)),((transp[0]>>19)&(31<<3))));
+ offs=transp[1]&OFFSET_MASK;
+ outp[1]=BLEND_AVG(inp[1],BLEND4((unsigned int *)framebuffer+offs,w,((transp[1]>>24)&(31<<3)),((transp[1]>>19)&(31<<3))));
+ offs=transp[2]&OFFSET_MASK;
+ outp[2]=BLEND_AVG(inp[2],BLEND4((unsigned int *)framebuffer+offs,w,((transp[2]>>24)&(31<<3)),((transp[2]>>19)&(31<<3))));
+ offs=transp[3]&OFFSET_MASK;
+ outp[3]=BLEND_AVG(inp[3],BLEND4((unsigned int *)framebuffer+offs,w,((transp[3]>>24)&(31<<3)),((transp[3]>>19)&(31<<3))));
+ transp+=4;
+ outp+=4;
+ inp+=4;
+ }
+ x=(w*outh)&3;
+ while (x--)
+ {
+ int offs=transp[0]&OFFSET_MASK;
+ outp++[0]=BLEND_AVG(inp[0],BLEND4((unsigned int *)framebuffer+offs,w,((transp[0]>>24)&(31<<3)),((transp[0]>>19)&(31<<3))));
+ transp++;
+ inp++;
+ }
+ #ifndef NO_MMX
+ __asm emms;
+ #endif
+ }
+ else if (trans_tab_subpixel)
+ {
+ while (x--)
+ {
+ int offs=transp[0]&OFFSET_MASK;
+ outp[0]=BLEND4((unsigned int *)framebuffer+offs,w,((transp[0]>>24)&(31<<3)),((transp[0]>>19)&(31<<3)));
+ offs=transp[1]&OFFSET_MASK;
+ outp[1]=BLEND4((unsigned int *)framebuffer+offs,w,((transp[1]>>24)&(31<<3)),((transp[1]>>19)&(31<<3)));
+ offs=transp[2]&OFFSET_MASK;
+ outp[2]=BLEND4((unsigned int *)framebuffer+offs,w,((transp[2]>>24)&(31<<3)),((transp[2]>>19)&(31<<3)));
+ offs=transp[3]&OFFSET_MASK;
+ outp[3]=BLEND4((unsigned int *)framebuffer+offs,w,((transp[3]>>24)&(31<<3)),((transp[3]>>19)&(31<<3)));
+ transp+=4;
+ outp+=4;
+ }
+ x=(w*outh)&3;
+ while (x--)
+ {
+ int offs=transp[0]&OFFSET_MASK;
+ outp++[0]=BLEND4((unsigned int *)framebuffer+offs,w,((transp[0]>>24)&(31<<3)),((transp[0]>>19)&(31<<3)));
+ transp++;
+ }
+ #ifndef NO_MMX
+ __asm emms;
+ #endif
+ }
+ else if (blend)
+ {
+ timingEnter(3);
+ while (x--)
+ {
+ outp[0]=BLEND_AVG(inp[0],framebuffer[transp[0]]);
+ outp[1]=BLEND_AVG(inp[1],framebuffer[transp[1]]);
+ outp[2]=BLEND_AVG(inp[2],framebuffer[transp[2]]);
+ outp[3]=BLEND_AVG(inp[3],framebuffer[transp[3]]);
+ outp+=4;
+ inp+=4;
+ transp+=4;
+ }
+ timingLeave(3);
+ x = (w*outh)&3;
+ if (x>0) while (x--)
+ {
+ outp++[0]=BLEND_AVG(inp++[0],framebuffer[transp++[0]]);
+ }
+ }
+ else
+ {
+ timingEnter(4);
+ while (x--)
+ {
+ outp[0]=framebuffer[transp[0]];
+ outp[1]=framebuffer[transp[1]];
+ outp[2]=framebuffer[transp[2]];
+ outp[3]=framebuffer[transp[3]];
+ outp+=4;
+ transp+=4;
+ }
+ timingLeave(4);
+ x = (w*outh)&3;
+ if (x>0) while (x--)
+ {
+ outp++[0]=framebuffer[transp++[0]];
+ }
+ }
+ }
+}
+
+int C_THISCLASS::smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // return value is that of render() for fbstuff etc
+{
+ return !!effect;
+}
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
+ if (isBeat & 0x80000000) return 0;
+
+ smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
+ return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
+}
+
+C_RBASE *R_Trans(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ static int isstart;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int x;
+ for (x = 0; x < sizeof(descriptions)/sizeof(descriptions[0]); x ++)
+ {
+ SendDlgItemMessage( hwndDlg, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)(const wchar_t *)AutoWide( WASABI_API_LNGSTRING( descriptions[ x ].list_desc ), CP_UTF8 ) );
+ }
+
+ isstart=1;
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp.get());
+ // After we set whatever value into the edit box, that's the new saved value (ie: don't change the save format)
+ isstart=0;
+
+ if (g_this->blend)
+ CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (g_this->subpixel)
+ CheckDlgButton(hwndDlg,IDC_CHECK4,BST_CHECKED);
+ if (g_this->wrap)
+ CheckDlgButton(hwndDlg,IDC_WRAP,BST_CHECKED);
+ if (g_this->rectangular)
+ CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ if (g_this->sourcemapped&2)
+ CheckDlgButton(hwndDlg,IDC_CHECK2,BST_INDETERMINATE);
+ else if (g_this->sourcemapped&1)
+ CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+
+ SendDlgItemMessage( hwndDlg, IDC_LIST1, LB_ADDSTRING, 0, (LPARAM)(const wchar_t *)AutoWide( WASABI_API_LNGSTRING( IDS_USER_DEFINED ), CP_UTF8 ) );
+ SendDlgItemMessage(hwndDlg,IDC_LIST1,LB_SETCURSEL,(g_this->effect==32767)?sizeof(descriptions)/sizeof(descriptions[0]):g_this->effect,0);
+ if (g_this->effect == 32767)
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),1);
+ }
+ else if (g_this->effect >= 0 && g_this->effect <= REFFECT_MAX)
+ {
+ if (strlen(descriptions[g_this->effect].eval_desc) > 0)
+ {
+ SetDlgItemTextA(hwndDlg,IDC_EDIT1,descriptions[g_this->effect].eval_desc);
+ CheckDlgButton(hwndDlg,IDC_CHECK3,descriptions[g_this->effect].uses_rect?BST_CHECKED:0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),1);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),0);
+ }
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),0);
+ }
+ }
+ return 1;
+ case WM_TIMER:
+ if (wParam == 1)
+ {
+ KillTimer(hwndDlg,1);
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect=32767;
+ g_this->effect_exp.get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp_ch=1;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ return 0;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_EDIT1 && HIWORD(wParam) == EN_CHANGE)
+ {
+ KillTimer(hwndDlg,1);
+ if (!isstart) SetTimer(hwndDlg,1,1000,NULL);
+
+ // If someone edits the editwnd, force the "(user defined)" to be the new selection.
+ if (SendDlgItemMessageA(hwndDlg,IDC_LIST1,LB_GETCURSEL,0,0) != sizeof(descriptions)/sizeof(descriptions[0]))
+ {
+ g_this->rectangular=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
+ SendDlgItemMessageA(hwndDlg,IDC_LIST1,LB_SETCURSEL,sizeof(descriptions)/sizeof(descriptions[0]),0);
+ }
+ }
+ if (LOWORD(wParam)==IDC_LIST1 && HIWORD(wParam)==LBN_SELCHANGE)
+ {
+ int t;
+ t=SendDlgItemMessageA(hwndDlg,IDC_LIST1,LB_GETCURSEL,0,0);
+ if (t == sizeof(descriptions)/sizeof(descriptions[0]))
+ {
+ g_this->effect=32767;
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),1);
+
+ SetDlgItemText(hwndDlg,IDC_EDIT1,g_this->effect_exp.get());
+ CheckDlgButton(hwndDlg,IDC_CHECK3,g_this->rectangular);
+
+ // always reinit =)
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect_exp.get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp_ch=1;
+ LeaveCriticalSection(&g_this->rcs);
+ }
+ }
+ else
+ {
+ g_this->effect=t;
+
+ // If there is a string to stuff in the eval box,
+ if (strlen(descriptions[t].eval_desc) > 0)
+ {
+ // save the value to be able to restore it later
+ // stuff it and make sure the boxes are editable
+ SetDlgItemText(hwndDlg,IDC_EDIT1,descriptions[t].eval_desc);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),1);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),1);
+ CheckDlgButton(hwndDlg,IDC_CHECK3,descriptions[t].uses_rect?BST_CHECKED:0);
+ }
+ else
+ {
+ // otherwise, they're not editable.
+ CheckDlgButton(hwndDlg,IDC_CHECK3,g_this->rectangular?BST_CHECKED:0);
+ SetDlgItemText(hwndDlg,IDC_EDIT1,"");
+ EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT1),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK3),0);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_LABEL1),0);
+ }
+ }
+
+ }
+ if (LOWORD(wParam)==IDC_CHECK1)
+ {
+ g_this->blend=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ }
+ if (LOWORD(wParam)==IDC_CHECK4)
+ {
+ g_this->subpixel=IsDlgButtonChecked(hwndDlg,IDC_CHECK4)?1:0;
+ g_this->effect_exp_ch=1;
+ }
+ if (LOWORD(wParam)==IDC_WRAP)
+ {
+ g_this->wrap=IsDlgButtonChecked(hwndDlg,IDC_WRAP)?1:0;
+ g_this->effect_exp_ch=1;
+ }
+ if (LOWORD(wParam)==IDC_CHECK2)
+ {
+ int a=IsDlgButtonChecked(hwndDlg,IDC_CHECK2);
+ if (a == BST_INDETERMINATE)
+ g_this->sourcemapped=2;
+ else if (a == BST_CHECKED)
+ g_this->sourcemapped=1;
+ else
+ g_this->sourcemapped=0;
+ }
+ if (LOWORD(wParam) == IDC_CHECK3)
+ {
+ g_this->rectangular=IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?1:0;
+ if (SendDlgItemMessageA(hwndDlg,IDC_LIST1,LB_GETCURSEL,0,0) != sizeof(descriptions)/sizeof(descriptions[0]))
+ {
+ EnterCriticalSection(&g_this->rcs);
+ g_this->effect=32767;
+ g_this->effect_exp.get_from_dlgitem(hwndDlg,IDC_EDIT1);
+ g_this->effect_exp_ch=1;
+ LeaveCriticalSection(&g_this->rcs);
+ SendDlgItemMessageA(hwndDlg,IDC_LIST1,LB_SETCURSEL,sizeof(descriptions)/sizeof(descriptions[0]),0);
+ }
+ else
+ g_this->effect_exp_ch=1;
+ }
+ if (LOWORD(wParam) == IDC_BUTTON2)
+ {
+/*
+ char text[4096];
+ WASABI_API_LNGSTRING_BUF(IDS_MOVEMENT,text,4096);
+ int titlelen = lstrlen(text)+1;
+ lstrcpyn(text+titlelen,GetTextResource(IDR_MOVEMENT),4095-titlelen);
+*/
+
+ char *text="Movement\0"
+ "Movement help:\r\n"
+"To use the custom table, modify r,d,x or y.\r\n"
+"Rect coords: x,y are in (-1..1) . Otherwise: d is (0..1) and r is (0..2PI).\r\n"
+"You can also access 'sw' and 'sh' for screen dimensions in pixels (might be useful)\r\n"
+ ;
+ compilerfunctionlist(hwndDlg,text);
+ }
+ return 0;
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_TRANS,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_Trans(char *desc){return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_transition.cpp b/Src/Plugins/Visualization/vis_avs/r_transition.cpp
new file mode 100644
index 00000000..0d94f64d
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_transition.cpp
@@ -0,0 +1,632 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdio.h>
+#include <commctrl.h>
+#include <process.h>
+#include "draw.h"
+#include "resource.h"
+#include "cfgwnd.h"
+#include "r_defs.h"
+#include "r_unkn.h"
+#include "r_transition.h"
+#include "render.h"
+#include <math.h>
+#include "../Agave/Language/api_language.h"
+
+extern char *scanstr_back(char *str, char *toscan, char *defval);
+
+int transitionmodes[] =
+{
+ IDS_RANDOM,
+ IDS_CROSS_DISSOLVE,
+ IDS_L_R_PUSH,
+ IDS_R_L_PUSH,
+ IDS_T_B_PUSH,
+ IDS_B_T_PUSH,
+ IDS_9_RANDOM_BLOCKS,
+ IDS_SPLIT_L_R_PUSH,
+ IDS_L_R_CENTER_PUSH,
+ IDS_L_R_CENTER_SQUEEZE,
+ IDS_L_R_WIPE,
+ IDS_R_L_WIPE,
+ IDS_T_B_WIPE,
+ IDS_B_T_WIPE,
+ IDS_DOT_DISSOLVE,
+};
+
+static C_RenderTransitionClass *g_this;
+C_RenderTransitionClass::C_RenderTransitionClass()
+{
+ last_file[0]=0;
+ l_w=l_h=0;
+ memset(fbs,0,sizeof(fbs));
+ enabled=0;
+ start_time=0;
+ _dotransitionflag=0;
+ initThread=0;
+}
+
+C_RenderTransitionClass::~C_RenderTransitionClass()
+{
+ int x;
+ if (initThread)
+ {
+ WaitForSingleObject(initThread,INFINITE);
+ CloseHandle(initThread);
+ initThread=0;
+ } for (x = 0; x < 4; x ++)
+ {
+ if (fbs[x]) GlobalFree(fbs[x]);
+ fbs[x]=NULL;
+ }
+}
+
+unsigned int WINAPI C_RenderTransitionClass::m_initThread(LPVOID p)
+{
+ C_RenderTransitionClass *_this=(C_RenderTransitionClass*)p;
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
+ if (cfg_transitions2&32)
+ {
+ extern HANDLE g_hThread;
+ int d=GetThreadPriority(g_hThread);
+ if (d == THREAD_PRIORITY_TIME_CRITICAL) d=THREAD_PRIORITY_HIGHEST;
+ else if (d == THREAD_PRIORITY_HIGHEST) d=THREAD_PRIORITY_ABOVE_NORMAL;
+ else if (d == THREAD_PRIORITY_ABOVE_NORMAL) d=THREAD_PRIORITY_NORMAL;
+ else if (d == THREAD_PRIORITY_NORMAL) d=THREAD_PRIORITY_BELOW_NORMAL;
+ else if (d == THREAD_PRIORITY_BELOW_NORMAL) d=THREAD_PRIORITY_LOWEST;
+ else if (d == THREAD_PRIORITY_LOWEST) d=THREAD_PRIORITY_IDLE;
+ SetThreadPriority(GetCurrentThread(),d);
+ }
+ int *fb=(int *)GlobalAlloc(GPTR,_this->l_w*_this->l_h*sizeof(int));
+ char last_visdata[2][2][576]={0,};
+ g_render_effects2->render(last_visdata,0x80000000,fb,fb,_this->l_w,_this->l_h);
+ GlobalFree((HGLOBAL)fb);
+
+ _this->_dotransitionflag=2;
+
+ _endthreadex(0);
+ return 0;
+}
+
+
+int C_RenderTransitionClass::LoadPreset(char *file, int which, C_UndoItem *item)
+{
+ if (initThread)
+ {
+ if (WaitForSingleObject(initThread,0)==WAIT_TIMEOUT)
+ {
+ DDraw_SetStatusText("loading [wait]...",1000*100);
+ return 2;
+ }
+ CloseHandle(initThread);
+ initThread=0;
+ }
+
+
+ EnterCriticalSection(&g_render_cs);
+ if (enabled)
+ {
+ enabled=0;
+ }
+
+ int r = 0;
+
+ if (item)
+ {
+ g_render_effects2->__LoadPresetFromUndo(*item,1);
+ last_which=which;
+ _dotransitionflag=2;
+ }
+ else
+ {
+ lstrcpyn(last_file,file,sizeof(last_file));
+ if (file[0]) r=g_render_effects2->__LoadPreset(file,1);
+ else
+ {
+ g_render_effects2->clearRenders();
+ }
+ if (!r && l_w && l_h && (cfg_transitions2&which) && ((cfg_transitions2&128)||DDraw_IsFullScreen()))
+ {
+ DWORD id;
+ last_which=which;
+ _dotransitionflag=1;
+ initThread=(HANDLE)_beginthreadex(NULL,0,m_initThread,(LPVOID)this,0,(unsigned int*)&id);
+ DDraw_SetStatusText("loading...",1000*100);
+ }
+ else
+ {
+ last_which=which;
+ _dotransitionflag=2;
+ }
+
+ if (r)
+ {
+ char s[MAX_PATH*2];
+ wsprintf(s,WASABI_API_LNGSTRING(IDS_ERROR_LOADING_X),scanstr_back(last_file,"\\",last_file-1)+1);
+ DDraw_SetStatusText(s);
+ _dotransitionflag=3;
+ }
+ C_UndoStack::clear();
+ C_UndoStack::saveundo(1);
+ C_UndoStack::cleardirty();
+ }
+ LeaveCriticalSection(&g_render_cs);
+
+ return !!r;
+}
+
+#define PI 3.14159265358979323846
+//264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848...
+
+extern int g_rnd_cnt;
+
+int C_RenderTransitionClass::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (_dotransitionflag||enabled) g_rnd_cnt=0;
+ if (_dotransitionflag==2 || _dotransitionflag == 3)
+ {
+ int notext=_dotransitionflag==3;
+ _dotransitionflag=0;
+ if (cfg_transitions&last_which)
+ {
+ curtrans = (cfg_transition_mode&0x7fff) ? (cfg_transition_mode&0x7fff) : (rand() % ((sizeof(transitionmodes)/sizeof(transitionmodes[0]))-1))+1;
+ if (cfg_transition_mode&0x8000) curtrans|=0x8000;
+ ep[0]=0;
+ ep[1]=2;
+ mask=0;
+ start_time=0;
+ enabled=1;
+ }
+ C_RenderListClass *temp=g_render_effects;
+ g_render_effects=g_render_effects2;
+ g_render_effects2=temp;
+ extern int need_repop;
+ extern char *extension(char *fn);
+ need_repop=1;
+ PostMessage(g_hwndDlg,WM_USER+20,0,0);
+ if (!notext && stricmp("aph",extension(last_file)))
+ {
+ char buf[512];
+ strncpy(buf,scanstr_back(last_file,"\\",last_file-1)+1,510);
+ buf[510]=0;
+ scanstr_back(buf,".",buf+strlen(buf))[0]=0;
+ strcat(buf," ");
+ DDraw_SetStatusText(buf);
+ }
+ }
+
+ if (!enabled)
+ {
+ int x;
+ l_w=w;
+ l_h=h;
+ if (fbs[0]) for (x = 0; x < 4; x ++)
+ {
+ if (fbs[x])
+ {
+ GlobalFree(fbs[x]);
+ fbs[x]=NULL;
+ }
+ }
+ if (!initThread && g_render_effects2->getNumRenders())
+ {
+ g_render_effects2->clearRenders();
+ g_render_effects2->freeBuffers();
+ }
+ return g_render_effects->render(visdata,isBeat,framebuffer,fbout,w,h);
+ }
+
+ // handle resize
+ if (l_w != w || l_h != h || !fbs[0])
+ {
+ l_w=w;
+ l_h=h;
+ int x;
+ for (x = 0; x < 4; x ++)
+ {
+ if (fbs[x]) GlobalFree(fbs[x]);
+ fbs[x]=(int*)GlobalAlloc(GPTR,l_w*l_h*sizeof(int));
+ }
+ }
+
+ if (start_time == 0)
+ {
+ memcpy(fbs[ep[0]],framebuffer,sizeof(int)*l_w*l_h);
+ memcpy(fbs[ep[1]],framebuffer,sizeof(int)*l_w*l_h);
+ }
+
+
+ // maybe there's a faster way than using 3 more buffers without screwing
+ // any effect... justin ?
+ if (curtrans&0x8000)
+ ep[1]^=g_render_effects2->render(visdata,isBeat,fbs[ep[1]],fbs[ep[1]^1],w,h)&1;
+ ep[0]^=g_render_effects->render(visdata,isBeat,fbs[ep[0]],fbs[ep[0]^1],w,h)&1;
+
+ int *p = fbs[ep[1]];
+ int *d = fbs[ep[0]];
+ int *o = framebuffer;
+ int x=w*h;
+
+ int ttime=250*cfg_transitions_speed;
+ if (ttime<100) ttime=100;
+
+ int n;
+ if (!start_time) { n=0; start_time=GetTickCount(); }
+ else n=MulDiv(GetTickCount()-start_time,256,ttime);
+
+ if (n >= 255) n=255;
+
+ float sintrans = (float)(sin(((float)n/255)*PI-PI/2)/2+0.5); // used for smoothing transitions
+ // now sintrans does a smooth curve
+ // from 0 to 1
+ switch (curtrans&0x7fff)
+ {
+ case 1: // Crossfade
+ mmx_adjblend_block(o,d,p,x,n);
+ break;
+ case 2: // Left to right push
+ {
+ int i = (int)(sintrans*w);
+ int j;
+ for (j=0;j<h;j++)
+ {
+ memcpy(framebuffer+(j*w), d+(j*w)+(w-i), i*4);
+ memcpy(framebuffer+(j*w)+i, p+(j*w), (w-i)*4);
+ }
+ }
+ break;
+ case 3: // Right to left push
+ {
+ int i = (int)(sintrans*w);
+ int j;
+ for (j=0;j<h;j++)
+ {
+ memcpy(framebuffer+(j*w), p+(i+j*w), (w-i)*4);
+ memcpy(framebuffer+(j*w)+(w-i), d+(j*w), i*4);
+ }
+ }
+ break;
+ case 4: // Top to bottom push
+ {
+ int i = (int)(sintrans*h);
+ memcpy(framebuffer, d+(h-i)*w, w*i*4);
+ memcpy(framebuffer+w*i, p, w*(h-i)*4);
+ }
+ break;
+ case 5: // Bottom to Top push
+ {
+ int i = (int)(sintrans*h);
+ memcpy(framebuffer,p+i*w, w*(h-i)*4);
+ memcpy(framebuffer+w*(h-i), d, w*i*4);
+ }
+ break;
+ case 6: // 9 random blocks
+ {
+ if (!(mask&(1<<(10+n/28))))
+ {
+ int r=0;
+ if ((mask & 0x1ff) != 0x1ff)
+ {
+ do
+ {
+ r = rand()%9;
+ }
+ while ((1 << r) & mask);
+ }
+ mask |= (1<<r)|(1<<(10+n/28));
+ }
+ int j;
+ int tw=w/3, th=h/3;
+ int twr=w-2*tw;
+ memcpy(framebuffer, p, w*h*4);
+ int i;
+ for (i=0;i<9;i++)
+ {
+ if (mask & (1<<i))
+ {
+ int end=i/3*th+th;
+ if (i > 5) end=h;
+ for (j=i/3*th;j<end;j++)
+ memcpy(framebuffer+(j*w)+(i%3)*tw, d+(j*w)+(i%3)*tw, (i%3==2) ? twr*4 : tw*4);
+ }
+ }
+ }
+ break;
+ case 7: // Left/Right to Right/Left
+ {
+ int i = (int)(sintrans*w);
+ int j;
+ for (j=0;j<h/2;j++)
+ {
+ memcpy(framebuffer+(i+j*w), p+(j*w), (w-i)*4);
+ memcpy(framebuffer+(j*w), d+((j+1)*w)-i, i*4);
+ }
+ for (j=h/2;j<h;j++)
+ {
+ memcpy(framebuffer+(j*w), p+(i+j*w), (w-i)*4);
+ memcpy(framebuffer+(j*w)+(w-i), d+(j*w), i*4);
+ }
+ }
+ break;
+ case 8: // Left/Right to Center
+ {
+ int i = (int)(sintrans*w/2);
+ int j;
+ for (j=0;j<h;j++)
+ {
+ memcpy(framebuffer+(j*w), d+((j+1)*w-i-w/2), i*4);
+ memcpy(framebuffer+((j+1)*w-i), d+(j*w+w/2), i*4);
+ memcpy(framebuffer+(j*w)+i, p+(j*w)+i, (w-i*2)*4);
+ }
+ }
+ break;
+ case 9: // Left/Right to Center, squeeze
+ {
+ int i = (int)(sintrans*w/2);
+ int j;
+ for (j=0;j<h;j++)
+ {
+ if (i)
+ {
+ int xl=i;
+ int xp=0;
+ int dxp=((w/2)<<16)/xl;
+ int *ot=framebuffer+(j*w);
+ int *it=d+(j*w);
+ while (xl--)
+ {
+ *ot++=it[xp>>16];
+ xp+=dxp;
+ }
+ }
+
+ if (i*2 != w)
+ {
+ int xl=w-i*2;
+ int xp=0;
+ int dxp=(w<<16)/xl;
+ int *ot=framebuffer+(j*w)+i;
+ int *it=p+(j*w);
+ while (xl--)
+ {
+ *ot++=it[xp>>16];
+ xp+=dxp;
+ }
+ }
+ if (i)
+ {
+ int xl=i;
+ int xp=0;
+ int dxp=((w/2)<<16)/xl;
+ int *ot=framebuffer+(j*w)+w-i;
+ int *it=d+(j*w)+w/2;
+ while (xl--)
+ {
+ *ot++=it[xp>>16];
+ xp+=dxp;
+ }
+ }
+
+
+ }
+ }
+ break;
+ case 10: // Left to right wipe
+ {
+ int i = (int)(sintrans*w);
+ int j;
+ for (j=0;j<h;j++)
+ {
+ memcpy(framebuffer+(i+j*w), p+(j*w)+i, (w-i)*4);
+ memcpy(framebuffer+(j*w), d+(j*w), i*4);
+ }
+ }
+ break;
+ case 11: // Right to left wipe
+ {
+ int i = (int)(sintrans*w);
+ int j;
+ for (j=0;j<h;j++)
+ {
+ memcpy(framebuffer+(j*w), p+(j*w), (w-i)*4);
+ memcpy(framebuffer+(j*w)+(w-i), d+(j*w)+(w-i), i*4);
+ }
+ }
+ break;
+ case 12: // Top to bottom wipe
+ {
+ int i = (int)(sintrans*h);
+ memcpy(framebuffer, d, w*i*4);
+ memcpy(framebuffer+w*i, p+w*i, w*(h-i)*4);
+ }
+ break;
+ case 13: // Bottom to top wipe
+ {
+ int i = (int)(sintrans*h);
+ memcpy(framebuffer, p, w*(h-i)*4);
+ memcpy(framebuffer+w*(h-i), d+w*(h-i), w*i*4);
+ }
+ break;
+ case 14: // dot dissolve
+ {
+ int i=((int)(sintrans*5))-5;
+ int j;
+ int t=0;
+ int dir=1;
+
+ if (i < 0)
+ {
+ dir=!dir;
+ i++;
+ i=-i;
+ }
+ i=1<<i;
+ for (j = 0; j < h; j ++)
+ {
+ if (t++==i)
+ {
+ int x=w;
+ t=0;
+ int t2=0;
+ int *of=framebuffer+j*w;
+ int *p2=(dir?p:d)+j*w;
+ int *d2=(dir?d:p)+j*w;
+ while (x--)
+ {
+ if (t2++==i)
+ {
+ of[0]=p2[0];
+ t2=0;
+ }
+ else of[0]=d2[0];
+ p2++;
+ d2++;
+ of++;
+ }
+ }
+ else
+ memcpy(framebuffer+j*w,(dir?d:p)+j*w,w*sizeof(int));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (n == 255)
+ {
+ int x;
+ enabled=0;
+ start_time=0;
+ for (x = 0; x < 4; x ++)
+ {
+ if (fbs[x]) GlobalFree(fbs[x]);
+ fbs[x]=NULL;
+ }
+ g_render_effects2->clearRenders();
+ g_render_effects2->freeBuffers();
+ }
+ return 0;
+}
+
+BOOL CALLBACK C_RenderTransitionClass::g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ int x;
+ for (x = 0; x < sizeof(transitionmodes)/sizeof(transitionmodes[0]); x ++)
+ SendDlgItemMessage(hwndDlg,IDC_TRANSITION,CB_ADDSTRING,0,(LPARAM)WASABI_API_LNGSTRING(transitionmodes[x]));
+ SendDlgItemMessage(hwndDlg,IDC_TRANSITION,CB_SETCURSEL,(WPARAM)cfg_transition_mode&0x7fff,0);
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1, 32));
+ SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, cfg_transitions_speed);
+ if (cfg_transition_mode&0x8000) CheckDlgButton(hwndDlg,IDC_CHECK9,BST_CHECKED);
+ if (cfg_transitions&1) CheckDlgButton(hwndDlg,IDC_CHECK2,BST_CHECKED);
+ if (cfg_transitions&2) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ if (cfg_transitions&4) CheckDlgButton(hwndDlg,IDC_CHECK8,BST_CHECKED);
+ if (cfg_transitions2&1) CheckDlgButton(hwndDlg,IDC_CHECK10,BST_CHECKED);
+ if (cfg_transitions2&2) CheckDlgButton(hwndDlg,IDC_CHECK11,BST_CHECKED);
+ if (cfg_transitions2&4) CheckDlgButton(hwndDlg,IDC_CHECK3,BST_CHECKED);
+ if (cfg_transitions2&32) CheckDlgButton(hwndDlg,IDC_CHECK4,BST_CHECKED);
+ if (!(cfg_transitions2&128)) CheckDlgButton(hwndDlg,IDC_CHECK5,BST_CHECKED);
+
+ }
+ return 1;
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_TRANSITION:
+ if (HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int r=SendDlgItemMessage(hwndDlg,IDC_TRANSITION,CB_GETCURSEL,0,0);
+ if (r!=CB_ERR)
+ {
+ cfg_transition_mode&=~0x7fff;
+ cfg_transition_mode |= r;
+ }
+ }
+ break;
+ case IDC_CHECK9:
+ cfg_transition_mode&=0x7fff;
+ cfg_transition_mode |= IsDlgButtonChecked(hwndDlg,IDC_CHECK9)?0x8000:0;
+ break;
+ case IDC_CHECK2:
+ cfg_transitions &= ~1;
+ cfg_transitions |= IsDlgButtonChecked(hwndDlg,IDC_CHECK2)?1:0;
+ break;
+ case IDC_CHECK1:
+ cfg_transitions &= ~2;
+ cfg_transitions |= IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?2:0;
+ break;
+ case IDC_CHECK8:
+ cfg_transitions &= ~4;
+ cfg_transitions |= IsDlgButtonChecked(hwndDlg,IDC_CHECK8)?4:0;
+ break;
+ case IDC_CHECK10:
+ cfg_transitions2 &= ~1;
+ cfg_transitions2 |= IsDlgButtonChecked(hwndDlg,IDC_CHECK10)?1:0;
+ break;
+ case IDC_CHECK11:
+ cfg_transitions2 &= ~2;
+ cfg_transitions2 |= IsDlgButtonChecked(hwndDlg,IDC_CHECK11)?2:0;
+ break;
+ case IDC_CHECK3:
+ cfg_transitions2 &= ~4;
+ cfg_transitions2 |= IsDlgButtonChecked(hwndDlg,IDC_CHECK3)?4:0;
+ break;
+ case IDC_CHECK4:
+ cfg_transitions2 &= ~32;
+ cfg_transitions2 |= IsDlgButtonChecked(hwndDlg,IDC_CHECK4)?32:0;
+ break;
+ case IDC_CHECK5:
+ cfg_transitions2 &= ~128;
+ cfg_transitions2 |= IsDlgButtonChecked(hwndDlg,IDC_CHECK5)?0:128;
+ break;
+ }
+ break;
+ case WM_NOTIFY:
+ if (LOWORD(wParam) == IDC_SPEED)
+ cfg_transitions_speed = SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0);
+ break;
+ }
+ return 0;
+}
+
+
+HWND C_RenderTransitionClass::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_GCFG_TRANSITIONS,hwndParent,g_DlgProc);
+}
+
diff --git a/Src/Plugins/Visualization/vis_avs/r_transition.h b/Src/Plugins/Visualization/vis_avs/r_transition.h
new file mode 100644
index 00000000..cf808739
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_transition.h
@@ -0,0 +1,63 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _R_TRANSITION_H_
+#define _R_TRANSITION_H_
+
+#include "undo.h"
+
+class C_RenderTransitionClass {
+ protected:
+
+ int *fbs[4];
+ int ep[2];
+ int l_w, l_h;
+ int enabled;
+ int start_time;
+ int curtrans;
+ int mask;
+ HANDLE initThread;
+ char last_file[MAX_PATH];
+ int last_which;
+ int _dotransitionflag;
+
+ public:
+
+ static unsigned int WINAPI m_initThread(LPVOID p);
+
+ int LoadPreset(char *file, int which, C_UndoItem *item=0); // 0 on success
+ C_RenderTransitionClass();
+ virtual ~C_RenderTransitionClass();
+
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+};
+
+#endif // _R_TRANSITION_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_unkn.cpp b/Src/Plugins/Visualization/vis_avs/r_unkn.cpp
new file mode 100644
index 00000000..7d58ef3e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_unkn.cpp
@@ -0,0 +1,114 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#define MOD_NAME "Unknown Render Object"
+
+#include "r_unkn.h"
+
+char *C_UnknClass::get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_UNKNOWN_RENDER_OBJECT,desc,128):desc); }
+void C_UnknClass::SetID(int d, char *dString) { id=d; memset(idString,0,sizeof(idString)); strcpy(idString,dString); }
+
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_UnknClass::load_config(unsigned char *data, int len)
+{
+ if (configdata) GlobalFree(configdata);
+ configdata=(char *)GlobalAlloc(GMEM_FIXED,len);
+ memcpy(configdata,data,len);
+ configdata_len=len;
+// char s[1024]="";
+// for (int x = 0 ;x < configdata_len; x ++)
+// wsprintf(s+strlen(s),"%X,",configdata[x]);
+// MessageBox(NULL,s,"loaded config",0);
+
+}
+int C_UnknClass::save_config(unsigned char *data)
+{
+ int pos=0;
+// char s[1024]="";
+// for (int x = 0 ;x < configdata_len; x ++)
+// wsprintf(s+strlen(s),"%X,",configdata[x]);
+// MessageBox(NULL,s,"saving config",0);
+ memcpy(data+pos,configdata,configdata_len);
+ pos+=configdata_len;
+ return pos;
+}
+
+
+C_UnknClass::C_UnknClass()
+{
+ configdata=0;
+ configdata_len=0;
+ id=0;
+ idString[0]=0;
+}
+
+C_UnknClass::~C_UnknClass()
+{
+ if (configdata) GlobalFree(configdata);
+ configdata=0;
+}
+
+int C_UnknClass::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ return 0;
+}
+
+static C_UnknClass *g_this;
+
+BOOL CALLBACK C_UnknClass::g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ char s[512]="";
+ if (g_this->idString[0]) wsprintf(s,"APE: %s\r\n",g_this->idString);
+ else wsprintf(s,WASABI_API_LNGSTRING(IDS_BUILTIN_ID),g_this->id);
+ wsprintf(s+strlen(s),WASABI_API_LNGSTRING(IDS_CONFIG_SIZE),g_this->configdata_len);
+ SetDlgItemText(hwndDlg,IDC_EDIT1,s);
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+HWND C_UnknClass::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_UNKN,hwndParent,g_DlgProc);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_unkn.h b/Src/Plugins/Visualization/vis_avs/r_unkn.h
new file mode 100644
index 00000000..5c2be157
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_unkn.h
@@ -0,0 +1,55 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _R_UNKN_H_
+#define _R_UNKN_H_
+
+#define UNKN_ID 0xffffffff
+
+class C_UnknClass : public C_RBASE {
+ protected:
+ char *configdata;
+ int configdata_len;
+ public:
+ C_UnknClass();
+ virtual ~C_UnknClass();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ virtual char *get_desc();
+
+ virtual void SetID(int d, char *dString);
+ int id;
+ char idString[33];
+
+ static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+};
+
+#endif // _R_UNKN_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_videodelay.cpp b/Src/Plugins/Visualization/vis_avs/r_videodelay.cpp
new file mode 100644
index 00000000..e8a3e1fc
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_videodelay.cpp
@@ -0,0 +1,365 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// video delay
+// copyright tom holden, 2002
+// mail: cfp@myrealbox.com
+
+#include <windows.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Video Delay"
+#define C_DELAY C_VideoDelayClass
+
+class C_DELAY : public C_RBASE
+{
+ protected:
+ public:
+ // standard ape members
+ C_DELAY();
+ virtual ~C_DELAY();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual char *get_desc();
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ // saved members
+ bool enabled;
+ bool usebeats;
+ unsigned int delay;
+
+ // unsaved members
+ LPVOID buffer;
+ LPVOID inoutpos;
+ unsigned long buffersize;
+ unsigned long virtualbuffersize;
+ unsigned long oldvirtualbuffersize;
+ unsigned long framessincebeat;
+ unsigned long framedelay;
+ unsigned long framemem;
+ unsigned long oldframemem;
+};
+
+// global configuration dialog pointer
+static C_DELAY *g_Delay;
+// global DLL instance pointer
+static HINSTANCE g_hDllInstance;
+
+// configuration screen
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ char value[16];
+ int val;
+ unsigned int objectcode, objectmessage;
+ HWND hwndEdit;
+ switch (uMsg)
+ {
+ case WM_INITDIALOG: //init
+ CheckDlgButton(hwndDlg,IDC_CHECK1,g_Delay->enabled);
+ CheckDlgButton(hwndDlg,IDC_RADIO1,g_Delay->usebeats);
+ CheckDlgButton(hwndDlg,IDC_RADIO2,!g_Delay->usebeats);
+ hwndEdit = GetDlgItem(hwndDlg,IDC_EDIT1);
+ _itoa(g_Delay->delay,value,10);
+ SetWindowText(hwndEdit,value);
+ return 1;
+ case WM_COMMAND:
+ objectcode = LOWORD(wParam);
+ objectmessage = HIWORD(wParam);
+ // see if enable checkbox is checked
+ if (objectcode == IDC_CHECK1)
+ {
+ g_Delay->enabled = IsDlgButtonChecked(hwndDlg,IDC_CHECK1)==1;
+ return 0;
+ }
+ // see if beats radiobox is checked
+ if (objectcode == IDC_RADIO1)
+ {
+ if(IsDlgButtonChecked(hwndDlg,IDC_RADIO1)==1)
+ {
+ g_Delay->usebeats = true;
+ CheckDlgButton(hwndDlg,IDC_RADIO2,BST_UNCHECKED);
+ g_Delay->framedelay = 0;
+ g_Delay->framessincebeat = 0;
+ hwndEdit = GetDlgItem(hwndDlg,IDC_EDIT1); //new
+ if (g_Delay->delay>16) { //new
+ g_Delay->delay = 16; //new
+ SetWindowText(hwndEdit,"16"); //new
+ } //new
+ }
+ else g_Delay->usebeats = false;
+ return 0;
+ }
+ // see if frames radiobox is checked
+ if (objectcode == IDC_RADIO2)
+ {
+ if(IsDlgButtonChecked(hwndDlg,IDC_RADIO2)==1)
+ {
+ g_Delay->usebeats = false;
+ CheckDlgButton(hwndDlg,IDC_RADIO1,BST_UNCHECKED);
+ g_Delay->framedelay = g_Delay->delay;
+ }
+ else g_Delay->usebeats = true;
+ return 0;
+ }
+ //get and put data from the delay box
+ if (objectcode == IDC_EDIT1)
+ {
+ hwndEdit = GetDlgItem(hwndDlg,IDC_EDIT1);
+ if (objectmessage == EN_CHANGE)
+ {
+ GetWindowText(hwndEdit,value,16);
+ val = atoi(value);
+ if (g_Delay->usebeats) {if (val > 16) val = 16;} //new
+ else {if (val > 200) val = 200;} //new
+ g_Delay->delay = val;
+ g_Delay->framedelay = g_Delay->usebeats?0:g_Delay->delay;
+ }
+ else if (objectmessage == EN_KILLFOCUS)
+ {
+ _itoa(g_Delay->delay,value,10);
+ SetWindowText(hwndEdit,value);
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+
+// set up default configuration
+C_DELAY::C_DELAY()
+{
+ // enable
+ enabled = true;
+ usebeats = false;
+ delay = 10;
+ framedelay = 10;
+ framessincebeat = 0;
+ buffersize = 1;
+ virtualbuffersize = 1;
+ oldvirtualbuffersize = 1;
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ inoutpos = buffer;
+}
+
+// virtual destructor
+C_DELAY::~C_DELAY()
+{
+ VirtualFree(buffer,buffersize,MEM_DECOMMIT);
+}
+
+// RENDER FUNCTION:
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout
+// w and h are the-width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+
+int C_DELAY::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (isBeat&0x80000000) return 0;
+
+ framemem = w*h*4;
+ if (usebeats)
+ {
+ if (isBeat)
+ {
+ framedelay = framessincebeat*delay; //changed
+ if (framedelay > 400) framedelay = 400; //new
+ framessincebeat = 0;
+ }
+ framessincebeat++;
+ }
+ if (enabled && framedelay!=0)
+ {
+ virtualbuffersize = framedelay*framemem;
+ if (framemem == oldframemem)
+ {
+ if (virtualbuffersize != oldvirtualbuffersize)
+ {
+ if (virtualbuffersize > oldvirtualbuffersize)
+ {
+ if (virtualbuffersize > buffersize)
+ {
+ // allocate new memory
+ if (!VirtualFree(buffer,buffersize,MEM_DECOMMIT)) return 0;
+ if (usebeats)
+ {
+ buffersize = 2*virtualbuffersize;
+ if (buffersize > framemem*400) buffersize = framemem*400; //new
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ if (buffer == NULL)
+ {
+ buffersize = virtualbuffersize;
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ }
+ }
+ else
+ {
+ buffersize = virtualbuffersize;
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ }
+ inoutpos = buffer;
+ if (buffer == NULL)
+ {
+ framedelay = 0;
+ framessincebeat = 0;
+ return 0;
+ }
+ }
+ else
+ {
+ unsigned long size = (((unsigned long)buffer)+oldvirtualbuffersize) - ((unsigned long)inoutpos);
+ unsigned long l = ((unsigned long)buffer)+virtualbuffersize;
+ unsigned long d = l - size;
+ MoveMemory((LPVOID)d, inoutpos, size);
+ for (l = (unsigned long)inoutpos; l < d; l += framemem) CopyMemory((LPVOID)l,(LPVOID)d,framemem);
+ }
+ }
+ else
+ { // virtualbuffersize < oldvirtualbuffersize
+ unsigned long presegsize = ((unsigned long)inoutpos)-((unsigned long)buffer)+framemem;
+ if (presegsize > virtualbuffersize)
+ {
+ MoveMemory(buffer,(LPVOID)(((unsigned long)buffer)+presegsize-virtualbuffersize),virtualbuffersize);
+ inoutpos = (LPVOID)(((unsigned long)buffer)+virtualbuffersize-framemem);
+ }
+ else if (presegsize < virtualbuffersize) MoveMemory((LPVOID)(((unsigned long)inoutpos)+framemem),(LPVOID)(((unsigned long)buffer)+oldvirtualbuffersize+presegsize-virtualbuffersize),virtualbuffersize-presegsize);
+ }
+ oldvirtualbuffersize = virtualbuffersize;
+ }
+ }
+ else
+ {
+ // allocate new memory
+ if (!VirtualFree(buffer,buffersize,MEM_DECOMMIT)) return 0;
+ if (usebeats)
+ {
+ buffersize = 2*virtualbuffersize;
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ if (buffer == NULL)
+ {
+ buffersize = virtualbuffersize;
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ }
+ }
+ else
+ {
+ buffersize = virtualbuffersize;
+ buffer = VirtualAlloc(NULL,buffersize,MEM_COMMIT,PAGE_READWRITE);
+ }
+ inoutpos = buffer;
+ if (buffer == NULL)
+ {
+ framedelay = 0;
+ framessincebeat = 0;
+ return 0;
+ }
+ oldvirtualbuffersize = virtualbuffersize;
+ }
+ oldframemem = framemem;
+ CopyMemory(fbout,inoutpos,framemem);
+ CopyMemory(inoutpos,framebuffer,framemem);
+ inoutpos = (LPVOID)(((unsigned long)inoutpos)+framemem);
+ if ((unsigned long)inoutpos>=((unsigned long)buffer)+virtualbuffersize) inoutpos = buffer;
+ return 1;
+ }
+ else return 0;
+}
+
+HWND C_DELAY::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_Delay = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_VIDEODELAY,hwndParent,g_DlgProc);
+}
+
+char *C_DELAY::get_desc(void)
+{
+ static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_VIDEO_DELAY,desc,128):desc);
+}
+
+// load_/save_config are called when saving and loading presets (.avs files)
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_DELAY::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ // always ensure there is data to be loaded
+ if (len-pos >= 4)
+ {
+ // load activation toggle
+ enabled=(GET_INT()==1);
+ pos+=4;
+ }
+ if (len-pos >= 4)
+ {
+ // load beats toggle
+ usebeats=(GET_INT()==1);
+ pos+=4;
+ }
+ if (len-pos >= 4)
+ {
+ // load delay
+ delay=GET_INT();
+
+ if (usebeats) {if (delay > 16) delay = 16;} //new
+ else {if (delay > 200) delay = 200;} //new
+
+ pos+=4;
+ }
+}
+
+// write configuration to data, return length. config data should not exceed 64k.
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_DELAY::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT((int)enabled);
+ pos+=4;
+ PUT_INT((int)usebeats);
+ pos+=4;
+ PUT_INT((unsigned int)delay);
+ pos+=4;
+ return pos;
+}
+
+// export stuff
+C_RBASE *R_VideoDelay(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc)
+ {
+ strcpy(desc,MOD_NAME);
+ return NULL;
+ }
+ return (C_RBASE *) new C_DELAY();
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_water.cpp b/Src/Plugins/Visualization/vis_avs/r_water.cpp
new file mode 100644
index 00000000..424ec4dd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_water.cpp
@@ -0,0 +1,502 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+// alphachannel safe 11/21/99
+
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+
+#include "timing.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define C_THISCLASS C_WaterClass
+#define MOD_NAME "Trans / Water"
+
+class C_THISCLASS : public C_RBASE2 {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_WATER,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+
+ virtual int smp_getflags() { return 1; }
+ virtual int smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual void smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual int smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h); // return value is that of render() for fbstuff etc
+
+ unsigned int *lastframe;
+ int lastframe_len;
+
+ int enabled;
+};
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len)
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+}
+int C_THISCLASS::save_config(unsigned char *data)
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ return pos;
+}
+
+
+
+
+C_THISCLASS::C_THISCLASS()
+{
+ enabled=1;
+ lastframe_len=0;
+ lastframe=NULL;
+}
+
+C_THISCLASS::~C_THISCLASS()
+{
+ if (lastframe) GlobalFree(lastframe);
+}
+
+
+
+#define _R(x) (( x ) & 0xff)
+#define _G(x) ((( x )) & 0xff00)
+#define _B(x) ((( x )) & 0xff0000)
+#define _RGB(r,g,b) (( r ) | (( g ) & 0xff00) | (( b ) & 0xff0000))
+
+static const int zero=0;
+
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ smp_begin(1,visdata,isBeat,framebuffer,fbout,w,h);
+ if (isBeat & 0x80000000) return 0;
+
+ smp_render(0,1,visdata,isBeat,framebuffer,fbout,w,h);
+ return smp_finish(visdata,isBeat,framebuffer,fbout,w,h);
+}
+
+
+int C_THISCLASS::smp_begin(int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return 0;
+
+ if (!lastframe || w*h != lastframe_len)
+ {
+ if (lastframe) GlobalFree(lastframe);
+ lastframe_len=w*h;
+ lastframe=(unsigned int *)GlobalAlloc(GPTR,w*h*sizeof(int));
+ }
+
+ return max_threads;
+}
+
+
+int C_THISCLASS::smp_finish(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h) // return value is that of render() for fbstuff etc
+{
+ return !!enabled;
+}
+
+
+void C_THISCLASS::smp_render(int this_thread, int max_threads, char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return;
+
+ unsigned int *f = (unsigned int *) framebuffer;
+ unsigned int *of = (unsigned int *) fbout;
+ unsigned int *lfo = (unsigned int *) lastframe;
+
+
+ int start_l = ( this_thread * h ) / max_threads;
+ int end_l;
+
+ if (this_thread >= max_threads - 1) end_l = h;
+ else end_l = ( (this_thread+1) * h ) / max_threads;
+
+ int outh=end_l-start_l;
+ if (outh<1) return;
+
+ int skip_pix=start_l*w;
+
+ f += skip_pix;
+ of+= skip_pix;
+ lfo += skip_pix;
+
+ int at_top=0, at_bottom=0;
+
+ if (!this_thread) at_top=1;
+ if (this_thread >= max_threads - 1) at_bottom=1;
+
+
+ timingEnter(0);
+
+ {
+
+ if (at_top)
+ // top line
+ {
+ int x;
+
+ // left edge
+ {
+ int r=_R(f[1]); int g=_G(f[1]); int b=_B(f[1]);
+ r += _R(f[w]); g += _G(f[w]); b += _B(f[w]);
+ f++;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+
+ // middle of line
+ x=(w-2);
+ while (x--)
+ {
+ int r=_R(f[1]); int g=_G(f[1]); int b=_B(f[1]);
+ r += _R(f[-1]); g += _G(f[-1]); b += _B(f[-1]);
+ r += _R(f[w]); g += _G(f[w]); b += _B(f[w]);
+ f++;
+
+ r/=2; g/=2; b/=2;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+
+ // right block
+ {
+ int r=_R(f[-1]); int g=_G(f[-1]); int b=_B(f[-1]);
+ r += _R(f[w]); g += _G(f[w]); b += _B(f[w]);
+ f++;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+ }
+
+
+ // middle block
+ {
+ int y=outh-at_top-at_bottom;
+ while (y--)
+ {
+ int x;
+
+ // left edge
+ {
+ int r=_R(f[1]); int g=_G(f[1]); int b=_B(f[1]);
+ r += _R(f[w]); g += _G(f[w]); b += _B(f[w]);
+ r += _R(f[-w]); g += _G(f[-w]); b += _B(f[-w]);
+ f++;
+
+ r/=2; g/=2; b/=2;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+
+ // middle of line
+ x=(w-2);
+#ifdef NO_MMX
+ while (x--)
+ {
+ int r=_R(f[1]); int g=_G(f[1]); int b=_B(f[1]);
+ r += _R(f[-1]); g += _G(f[-1]); b += _B(f[-1]);
+ r += _R(f[w]); g += _G(f[w]); b += _B(f[w]);
+ r += _R(f[-w]); g += _G(f[-w]); b += _B(f[-w]);
+ f++;
+
+ r/=2; g/=2; b/=2;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+#else
+ __asm
+ {
+ mov esi, f
+ mov edi, of
+ mov edx, lfo
+ mov ecx, x
+ mov ebx, w
+ shl ebx, 2
+ shr ecx, 1
+ sub esi, ebx
+ align 16
+mmx_water_loop1:
+ movd mm0, [esi+ebx+4]
+
+ movd mm1, [esi+ebx-4]
+ punpcklbw mm0, [zero]
+
+ movd mm2, [esi+ebx*2]
+ punpcklbw mm1, [zero]
+
+ movd mm3, [esi]
+ punpcklbw mm2, [zero]
+
+ movd mm4, [edx]
+ paddw mm0, mm1
+
+ punpcklbw mm3, [zero]
+ movd mm7, [esi+ebx+8]
+
+ punpcklbw mm4, [zero]
+ paddw mm2, mm3
+
+ movd mm6, [esi+ebx]
+ paddw mm0, mm2
+
+ psrlw mm0, 1
+ punpcklbw mm7, [zero]
+
+ movd mm2, [esi+ebx*2+4]
+ psubw mm0, mm4
+
+ movd mm3, [esi+4]
+ packuswb mm0, mm0
+
+ movd [edi], mm0
+ punpcklbw mm6, [zero]
+
+ movd mm4, [edx+4]
+ punpcklbw mm2, [zero]
+
+ paddw mm7, mm6
+ punpcklbw mm3, [zero]
+
+ punpcklbw mm4, [zero]
+ paddw mm2, mm3
+
+ paddw mm7, mm2
+ add edx, 8
+
+ psrlw mm7, 1
+ add esi, 8
+
+ psubw mm7, mm4
+
+ packuswb mm7, mm7
+
+ movd [edi+4], mm7
+
+ add edi, 8
+
+ dec ecx
+ jnz mmx_water_loop1
+
+ add esi, ebx
+ mov f, esi
+ mov of, edi
+ mov lfo, edx
+ };
+#endif
+ // right block
+ {
+ int r=_R(f[-1]); int g=_G(f[-1]); int b=_B(f[-1]);
+ r += _R(f[w]); g += _G(f[w]); b += _B(f[w]);
+ r += _R(f[-w]); g += _G(f[-w]); b += _B(f[-w]);
+ f++;
+
+ r/=2; g/=2; b/=2;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+ }
+ }
+ // bottom line
+ if (at_bottom)
+ {
+ int x;
+
+ // left edge
+ {
+ int r=_R(f[1]); int g=_G(f[1]); int b=_B(f[1]);
+ r += _R(f[-w]); g += _G(f[-w]); b += _B(f[-w]);
+ f++;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+
+ // middle of line
+ x=(w-2);
+ while (x--)
+ {
+ int r=_R(f[1]); int g=_G(f[1]); int b=_B(f[1]);
+ r += _R(f[-1]); g += _G(f[-1]); b += _B(f[-1]);
+ r += _R(f[-w]); g += _G(f[-w]); b += _B(f[-w]);
+ f++;
+
+ r/=2; g/=2; b/=2;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+
+ // right block
+ {
+ int r=_R(f[-1]); int g=_G(f[-1]); int b=_B(f[-1]);
+ r += _R(f[-w]); g += _G(f[-w]); b += _B(f[-w]);
+ f++;
+
+ r-=_R(lfo[0]); g-=_G(lfo[0]); b-=_B(lfo[0]);
+ lfo++;
+
+ if (r < 0) r=0;
+ else if (r > 255) r=255;
+ if (g < 0) g=0;
+ else if (g > 255*256) g=255*256;
+ if (b < 0) b=0;
+ else if (b > 255*65536) b=255*65536;
+ *of++=_RGB(r,g,b);
+ }
+ }
+ }
+
+ memcpy(lastframe+skip_pix,framebuffer+skip_pix,w*outh*sizeof(int));
+
+#ifndef NO_MMX
+ __asm emms;
+#endif
+ timingLeave(0);
+}
+
+C_RBASE *R_Water(char *desc)
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+
+static C_THISCLASS *g_this;
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_this->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ return 1;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_CHECK1)
+ {
+ if (IsDlgButtonChecked(hwndDlg,IDC_CHECK1))
+ g_this->enabled=1;
+ else
+ g_this->enabled=0;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent)
+{
+ g_this = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_WATER,hwndParent,g_DlgProc);
+}
+
+#else
+C_RBASE *R_Water(char *desc) { return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/r_waterbump.cpp b/Src/Plugins/Visualization/vis_avs/r_waterbump.cpp
new file mode 100644
index 00000000..92a6c85f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/r_waterbump.cpp
@@ -0,0 +1,439 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <stdlib.h>
+#include <vfw.h>
+#include <commctrl.h>
+#include <math.h>
+#include "resource.h"
+#include "r_defs.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef LASER
+
+#define MOD_NAME "Trans / Water Bump"
+#define C_THISCLASS C_WaterBumpClass
+
+class C_THISCLASS : public C_RBASE {
+ protected:
+ public:
+ C_THISCLASS();
+ virtual ~C_THISCLASS();
+ virtual int render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h);
+ virtual char *get_desc() { static char desc[128]; return (!desc[0]?WASABI_API_LNGSTRING_BUF(IDS_TRANS_WATER_BUMP,desc,128):desc); }
+ virtual HWND conf(HINSTANCE hInstance, HWND hwndParent);
+ virtual void load_config(unsigned char *data, int len);
+ virtual int save_config(unsigned char *data);
+ void SineBlob(int x, int y, int radius, int height, int page);
+ void CalcWater(int npage, int density);
+ void CalcWaterSludge(int npage, int density);
+ void HeightBlob(int x, int y, int radius, int height, int page);
+
+ int enabled;
+ int *buffers[2];
+ int buffer_w,buffer_h;
+ int page;
+ int density;
+ int depth;
+ int random_drop;
+ int drop_position_x;
+ int drop_position_y;
+ int drop_radius;
+ int method;
+};
+
+
+static C_THISCLASS *g_ConfigThis; // global configuration dialog pointer
+static HINSTANCE g_hDllInstance; // global DLL instance pointer (not needed in this example, but could be useful)
+
+
+
+// configuration read/write
+
+C_THISCLASS::C_THISCLASS() // set up default configuration
+{
+ int i;
+ enabled=1; density=6; depth=600; random_drop=0; drop_position_x=1; drop_position_y=1; drop_radius=40; method=0;
+ buffer_w=0; buffer_h=0;
+ for(i=0;i<2;i++)
+ buffers[i]=NULL;
+ page=0;
+}
+C_THISCLASS::~C_THISCLASS()
+{
+ int i;
+ for(i=0;i<2;i++) {
+ if(buffers[i]) GlobalFree(buffers[i]);
+ buffers[i]=NULL;
+ }
+}
+
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+void C_THISCLASS::load_config(unsigned char *data, int len) // read configuration of max length "len" from data.
+{
+ int pos=0;
+ if (len-pos >= 4) { enabled=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { density=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { depth=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { random_drop=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { drop_position_x=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { drop_position_y=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { drop_radius=GET_INT(); pos+=4; }
+ if (len-pos >= 4) { method=GET_INT(); pos+=4; }
+}
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+int C_THISCLASS::save_config(unsigned char *data) // write configuration to data, return length. config data should not exceed 64k.
+{
+ int pos=0;
+ PUT_INT(enabled); pos+=4;
+ PUT_INT(density); pos+=4;
+ PUT_INT(depth); pos+=4;
+ PUT_INT(random_drop); pos+=4;
+ PUT_INT(drop_position_x); pos+=4;
+ PUT_INT(drop_position_y); pos+=4;
+ PUT_INT(drop_radius); pos+=4;
+ PUT_INT(method); pos+=4;
+ return pos;
+}
+
+
+void C_THISCLASS::SineBlob(int x, int y, int radius, int height, int page)
+{
+ int cx, cy;
+ int left,top,right,bottom;
+ int square;
+ double dist;
+ int radsquare = radius * radius;
+ double length = (1024.0/(float)radius)*(1024.0/(float)radius);
+
+ if(x<0) x = 1+radius+ rand()%(buffer_w-2*radius-1);
+ if(y<0) y = 1+radius+ rand()%(buffer_h-2*radius-1);
+
+
+ radsquare = (radius*radius);
+
+ left=-radius; right = radius;
+ top=-radius; bottom = radius;
+
+ // Perform edge clipping...
+ if(x - radius < 1) left -= (x-radius-1);
+ if(y - radius < 1) top -= (y-radius-1);
+ if(x + radius > buffer_w-1) right -= (x+radius-buffer_w+1);
+ if(y + radius > buffer_h-1) bottom-= (y+radius-buffer_h+1);
+
+ for(cy = top; cy < bottom; cy++)
+ {
+ for(cx = left; cx < right; cx++)
+ {
+ square = cy*cy + cx*cx;
+ if(square < radsquare)
+ {
+ dist = sqrt(square*length);
+ buffers[page][buffer_w*(cy+y) + cx+x]
+ += (int)((cos(dist)+0xffff)*(height)) >> 19;
+ }
+ }
+ }
+}
+
+void C_THISCLASS::HeightBlob(int x, int y, int radius, int height, int page)
+{
+ int rquad;
+ int cx, cy, cyq;
+ int left, top, right, bottom;
+
+ rquad = radius * radius;
+
+ // Make a randomly-placed blob...
+ if(x<0) x = 1+radius+ rand()%(buffer_w-2*radius-1);
+ if(y<0) y = 1+radius+ rand()%(buffer_h-2*radius-1);
+
+ left=-radius; right = radius;
+ top=-radius; bottom = radius;
+
+ // Perform edge clipping...
+ if(x - radius < 1) left -= (x-radius-1);
+ if(y - radius < 1) top -= (y-radius-1);
+ if(x + radius > buffer_w-1) right -= (x+radius-buffer_w+1);
+ if(y + radius > buffer_h-1) bottom-= (y+radius-buffer_h+1);
+
+
+ for(cy = top; cy < bottom; cy++)
+ {
+ cyq = cy*cy;
+ for(cx = left; cx < right; cx++)
+ {
+ if(cx*cx + cyq < rquad)
+ buffers[page][buffer_w*(cy+y) + (cx+x)] += height;
+ }
+ }
+
+}
+
+
+void C_THISCLASS::CalcWater(int npage, int density)
+{
+ int newh;
+ int count = buffer_w + 1;
+
+ int *newptr = buffers[npage];
+ int *oldptr = buffers[!npage];
+
+ int x, y;
+
+ for (y = (buffer_h-1)*buffer_w; count < y; count += 2)
+ {
+ for (x = count+buffer_w-2; count < x; count++)
+ {
+// This does the eight-pixel method. It looks much better.
+
+ newh = ((oldptr[count + buffer_w]
+ + oldptr[count - buffer_w]
+ + oldptr[count + 1]
+ + oldptr[count - 1]
+ + oldptr[count - buffer_w - 1]
+ + oldptr[count - buffer_w + 1]
+ + oldptr[count + buffer_w - 1]
+ + oldptr[count + buffer_w + 1]
+ ) >> 2 )
+ - newptr[count];
+
+
+ newptr[count] = newh - (newh >> density);
+ }
+ }
+}
+
+/*
+void C_THISCLASS::CalcWaterSludge(int npage, int density)
+{
+ int newh;
+ int count = buffer_w + 1;
+
+ int *newptr = buffers[npage];
+ int *oldptr = buffers[!npage];
+
+ int x, y;
+
+ for (y = (buffer_h-1)*buffer_w; count < y; count += 2)
+ {
+ for (x = count+buffer_w-2; count < x; count++)
+ {
+// This is the "sludge" method...
+ newh = (oldptr[count]<<2)
+ + oldptr[count-1-buffer_w]
+ + oldptr[count+1-buffer_w]
+ + oldptr[count-1+buffer_w]
+ + oldptr[count+1+buffer_w]
+ + ((oldptr[count-1]
+ + oldptr[count+1]
+ + oldptr[count-buffer_w]
+ + oldptr[count+buffer_w])<<1);
+
+ newptr[count] = (newh-(newh>>6)) >> density;
+ }
+ }
+}
+*/
+// render function
+// render should return 0 if it only used framebuffer, or 1 if the new output data is in fbout. this is
+// used when you want to do something that you'd otherwise need to make a copy of the framebuffer.
+// w and h are the width and height of the screen, in pixels.
+// isBeat is 1 if a beat has been detected.
+// visdata is in the format of [spectrum:0,wave:1][channel][band].
+int C_THISCLASS::render(char visdata[2][2][576], int isBeat, int *framebuffer, int *fbout, int w, int h)
+{
+ if (!enabled) return 0;
+ int l,i;
+ l=w*h;
+
+ if(buffer_w!=w||buffer_h!=h) {
+ for(i=0;i<2;i++) {
+ if(buffers[i])GlobalFree(buffers[i]);
+ buffers[i]=NULL;
+ }
+ }
+ if(buffers[0]==NULL) {
+ for(i=0;i<2;i++) {
+ buffers[i]=(int *)GlobalAlloc(GPTR,w*h*sizeof(int));
+ }
+ buffer_w=w;
+ buffer_h=h;
+ }
+ if (isBeat&0x80000000) return 0;
+
+ if(isBeat) {
+ if(random_drop) {
+ int max=w;
+ if(h>w) max=h;
+ SineBlob(-1,-1,drop_radius*max/100,-depth,page);
+ } else {
+ int x,y;
+ switch(drop_position_x) {
+ case 0: x=w/4; break;
+ case 1: x=w/2; break;
+ case 2: x=w*3/4; break;
+ }
+ switch(drop_position_y) {
+ case 0: y=h/4; break;
+ case 1: y=h/2; break;
+ case 2: y=h*3/4; break;
+ }
+ SineBlob(x,y,drop_radius,-depth,page);
+ }
+// HeightBlob(-1,-1,80/2,1400,page);
+ }
+
+{
+ int dx, dy;
+ int x, y;
+ int ofs,len=buffer_h*buffer_w;
+
+ int offset=buffer_w + 1;
+
+ int *ptr = buffers[page];
+
+ for (y = (buffer_h-1)*buffer_w; offset < y; offset += 2)
+ {
+ for (x = offset+buffer_w-2; offset < x; offset++)
+ {
+ dx = ptr[offset] - ptr[offset+1];
+ dy = ptr[offset] - ptr[offset+buffer_w];
+ ofs=offset + buffer_w*(dy>>3) + (dx>>3);
+ if((ofs<len)&&(ofs>-1))
+ fbout[offset] = framebuffer[ofs];
+ else
+ fbout[offset] = framebuffer[offset];
+
+ offset++;
+ dx = ptr[offset] - ptr[offset+1];
+ dy = ptr[offset] - ptr[offset+buffer_w];
+ ofs=offset + buffer_w*(dy>>3) + (dx>>3);
+ if((ofs<len)&&(ofs>-1))
+ fbout[offset] = framebuffer[ofs];
+ else
+ fbout[offset] = framebuffer[offset];
+
+ }
+ }
+}
+
+ CalcWater(!page,density);
+
+ page=!page;
+
+ return 1;
+}
+
+
+// configuration dialog stuff
+
+
+static BOOL CALLBACK g_DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ if (g_ConfigThis->enabled) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg,IDC_DAMP,TBM_SETRANGEMIN,0,2);
+ SendDlgItemMessage(hwndDlg,IDC_DAMP,TBM_SETRANGEMAX,0,10);
+ SendDlgItemMessage(hwndDlg,IDC_DAMP,TBM_SETPOS,1,g_ConfigThis->density);
+ SendDlgItemMessage(hwndDlg,IDC_DEPTH,TBM_SETRANGEMIN,0,100);
+ SendDlgItemMessage(hwndDlg,IDC_DEPTH,TBM_SETRANGEMAX,0,2000);
+ SendDlgItemMessage(hwndDlg,IDC_DEPTH,TBM_SETPOS,1,g_ConfigThis->depth);
+ SendDlgItemMessage(hwndDlg,IDC_RADIUS,TBM_SETRANGEMIN,0,10);
+ SendDlgItemMessage(hwndDlg,IDC_RADIUS,TBM_SETRANGEMAX,0,100);
+ SendDlgItemMessage(hwndDlg,IDC_RADIUS,TBM_SETPOS,1,g_ConfigThis->drop_radius);
+ CheckDlgButton(hwndDlg,IDC_RANDOM_DROP,g_ConfigThis->random_drop);
+ CheckDlgButton(hwndDlg,IDC_DROP_LEFT,g_ConfigThis->drop_position_x==0);
+ CheckDlgButton(hwndDlg,IDC_DROP_CENTER,g_ConfigThis->drop_position_x==1);
+ CheckDlgButton(hwndDlg,IDC_DROP_RIGHT,g_ConfigThis->drop_position_x==2);
+ CheckDlgButton(hwndDlg,IDC_DROP_TOP,g_ConfigThis->drop_position_y==0);
+ CheckDlgButton(hwndDlg,IDC_DROP_MIDDLE,g_ConfigThis->drop_position_y==1);
+ CheckDlgButton(hwndDlg,IDC_DROP_BOTTOM,g_ConfigThis->drop_position_y==2);
+ return 1;
+ case WM_DRAWITEM:
+ return 0;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_CHECK1)
+ g_ConfigThis->enabled=IsDlgButtonChecked(hwndDlg,IDC_CHECK1)?1:0;
+ if (LOWORD(wParam) == IDC_RANDOM_DROP)
+ g_ConfigThis->random_drop=IsDlgButtonChecked(hwndDlg,IDC_RANDOM_DROP);
+ if (LOWORD(wParam) == IDC_DROP_LEFT)
+ g_ConfigThis->drop_position_x=0;
+ if (LOWORD(wParam) == IDC_DROP_CENTER)
+ g_ConfigThis->drop_position_x=1;
+ if (LOWORD(wParam) == IDC_DROP_RIGHT)
+ g_ConfigThis->drop_position_x=2;
+ if (LOWORD(wParam) == IDC_DROP_TOP)
+ g_ConfigThis->drop_position_y=0;
+ if (LOWORD(wParam) == IDC_DROP_MIDDLE)
+ g_ConfigThis->drop_position_y=1;
+ if (LOWORD(wParam) == IDC_DROP_BOTTOM)
+ g_ConfigThis->drop_position_y=2;
+ return 0;
+ case WM_HSCROLL:
+ {
+ HWND swnd = (HWND) lParam;
+ int t = (int) SendMessage(swnd,TBM_GETPOS,0,0);
+ if (swnd == GetDlgItem(hwndDlg,IDC_DAMP))
+ g_ConfigThis->density=t;
+ if (swnd == GetDlgItem(hwndDlg,IDC_DEPTH))
+ g_ConfigThis->depth=t;
+ if (swnd == GetDlgItem(hwndDlg,IDC_RADIUS))
+ g_ConfigThis->drop_radius=t;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+
+HWND C_THISCLASS::conf(HINSTANCE hInstance, HWND hwndParent) // return NULL if no config dialog possible
+{
+ g_ConfigThis = this;
+ return WASABI_API_CREATEDIALOG(IDD_CFG_WATERBUMP,hwndParent,g_DlgProc);
+}
+
+
+
+// export stuff
+
+C_RBASE *R_WaterBump(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{
+ if (desc) { strcpy(desc,MOD_NAME); return NULL; }
+ return (C_RBASE *) new C_THISCLASS();
+}
+
+#else
+C_RBASE *R_WaterBump(char *desc) // creates a new effect object if desc is NULL, otherwise fills in desc with description
+{return NULL; }
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/reaplay_avs.dsp b/Src/Plugins/Visualization/vis_avs/reaplay_avs.dsp
new file mode 100644
index 00000000..b0c144d9
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/reaplay_avs.dsp
@@ -0,0 +1,641 @@
+# Microsoft Developer Studio Project File - Name="reaplay_avs" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=reaplay_avs - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "reaplay_avs.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "reaplay_avs.mak" CFG="reaplay_avs - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "reaplay_avs - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "reaplay_avs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "reaplay_avs - Win32 Laser Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "reaplay_avs - Win32 NoMMX Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""$/reaplay_avs", RDAAAAAA"
+# PROP Scc_LocalPath "."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "reaplay_avs - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G6 /MD /W3 /O2 /Ob2 /I "evallib/" /D "NDEBUG" /D "WA2_EMBED" /D "REAPLAY_PLUGIN" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /D "NSEEL_EEL1_COMPAT_MODE" /D "EEL_NO_CHANGE_FPFLAGS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /map /machine:I386 /out:"..\jmde\Release\plugins\reaplay_avs.dll"
+# SUBTRACT LINK32 /debug
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "evallib/" /D "_DEBUG" /D "WA2_EMBED" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /D "NSEEL_EEL1_COMPAT_MODE" /D "EEL_NO_CHANGE_FPFLAGS" /D "REAPLAY_PLUGIN" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /debug /machine:I386 /out:"..\jmde\Debug\plugins\reaplay_avs.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 Laser Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "reaplay_avs___Win32_Laser_Release"
+# PROP BASE Intermediate_Dir "reaplay_avs___Win32_Laser_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "reaplay_avs___Win32_Laser_Release"
+# PROP Intermediate_Dir "reaplay_avs___Win32_Laser_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "evallib/" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "evallib/" /D "NDEBUG" /D "LASER" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /D "NSEEL_EEL1_COMPAT_MODE" /D "EEL_NO_CHANGE_FPFLAGS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "LASER"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /machine:I386 /out:"c:\program files\winamp\plugins\reaplay_avs.dll"
+# SUBTRACT BASE LINK32 /debug
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /machine:I386 /out:"c:\program files\winamp\plugins\reaplay_avs_laser.dll"
+# SUBTRACT LINK32 /debug
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 NoMMX Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "reaplay_avs___Win32_NoMMX_Release"
+# PROP BASE Intermediate_Dir "reaplay_avs___Win32_NoMMX_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "reaplay_avs___Win32_NoMMX_Release"
+# PROP Intermediate_Dir "reaplay_avs___Win32_NoMMX_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "evallib/" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MD /W3 /GX /O2 /Ob2 /I "evallib/" /D "NDEBUG" /D "NO_MMX" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /D "NSEEL_EEL1_COMPAT_MODE" /D "EEL_NO_CHANGE_FPFLAGS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /map /machine:I386 /out:"c:\progra~1\winamp\plugins\reaplay_avs.dll"
+# SUBTRACT BASE LINK32 /debug
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /map /machine:I386 /out:"c:\progra~1\winamp\plugins\reaplay_avs.dll"
+# SUBTRACT LINK32 /debug
+
+!ENDIF
+
+# Begin Target
+
+# Name "reaplay_avs - Win32 Release"
+# Name "reaplay_avs - Win32 Debug"
+# Name "reaplay_avs - Win32 Laser Release"
+# Name "reaplay_avs - Win32 NoMMX Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Group "Renders"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\r_avi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_blit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_blur.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bpm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bright.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bspin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bump.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_chanshift.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_clear.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_colorfade.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_colorreduction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_comment.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_contrast.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dcolormod.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_ddm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dmove.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dotfnt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dotgrid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dotpln.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_fadeout.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_fastbright.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_grain.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_interf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_interleave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_invert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_linemode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_mirror.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_mosaic.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_multidelay.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_multiplier.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_nfclr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_onetone.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_oscring.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_oscstar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_parts.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_picture.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_rotblit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_rotstar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_scat.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_shift.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_simple.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_sscope.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_stack.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_stars.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_svp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_timescope.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_trans.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_videodelay.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_water.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_waterbump.cpp
+# End Source File
+# End Group
+# Begin Group "EvalLib"
+
+# PROP Default_Filter ""
+# Begin Group "eel2"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE="..\WDL\eel2\ns-eel-addfuncs.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\ns-eel-int.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\ns-eel.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-caltab.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-cfunc.c"
+
+!IF "$(CFG)" == "reaplay_avs - Win32 Release"
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 Laser Release"
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 NoMMX Release"
+
+# ADD CPP /O1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-compiler.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-eval.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-lextab.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-ram.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\WDL\eel2\nseel-yylex.c"
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\avs_eelif.cpp
+
+!IF "$(CFG)" == "reaplay_avs - Win32 Release"
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 Laser Release"
+
+!ELSEIF "$(CFG)" == "reaplay_avs - Win32 NoMMX Release"
+
+# ADD CPP /O1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\avs_eelif.h
+# End Source File
+# End Group
+# Begin Group "Render utils"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\linedraw.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\matrix.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_list.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_transition.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_transition.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_unkn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_unkn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.cpp
+# End Source File
+# End Group
+# Begin Group "laser"
+
+# PROP Default_Filter ""
+# Begin Group "laser renders"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\laser\rl_beathold.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_bren.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_cones.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_line.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_trans.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\laser\laser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\laserline.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\laserline.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\ld32.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\Ld32.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\linelist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\linelist.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\bpm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cfgwin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\draw.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\render.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rlib.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TIMING.C
+# End Source File
+# Begin Source File
+
+SOURCE=.\TIMING.H
+# End Source File
+# Begin Source File
+
+SOURCE=.\undo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\wnd.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\ape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\bpm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cfgwnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\draw.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\render.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\undo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wnd.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/Src/Plugins/Visualization/vis_avs/render.cpp b/Src/Plugins/Visualization/vis_avs/render.cpp
new file mode 100644
index 00000000..72fd3fb9
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/render.cpp
@@ -0,0 +1,141 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include "render.h"
+#include "timing.h"
+#include "undo.h"
+
+#ifdef LASER
+C_LineListBase *g_laser_linelist;
+#endif
+
+C_RenderListClass *g_render_effects;
+C_RenderListClass *g_render_effects2;
+C_RenderTransitionClass *g_render_transition;
+C_RLibrary *g_render_library;
+
+int is_mmx(void) {
+ DWORD retval1,retval2;
+ __try {
+ _asm {
+ mov eax, 1 // set up CPUID to return processor version and features
+ // 0 = vendor string, 1 = version info, 2 = cache info
+ _emit 0x0f // code bytes = 0fh, 0a2h
+ _emit 0xa2
+ mov retval1, eax
+ mov retval2, edx
+ }
+ } __except(EXCEPTION_EXECUTE_HANDLER) { retval1 = retval2= 0;}
+ if (!retval1) return 0;
+ return (retval2&0x800000)?1:0;
+}
+
+
+unsigned char g_blendtable[256][256];
+unsigned int const mmx_blend4_revn[2]={0xff00ff,0xff00ff};//{0x1000100,0x1000100}; <<- this is actually more correct, but we're going for consistency vs. the non-mmx ver-jf
+int const mmx_blendadj_mask[2] = { 0xff00ff,0xff00ff};
+int const mmx_blend4_zero=0;
+
+void Render_Init(HINSTANCE hDllInstance)
+{
+#ifdef LASER
+ laser_connect();
+ g_laser_linelist=createLineList();
+#endif
+ timingInit();
+ {
+ int i,j;
+ for (j=0;j<256;j++)
+ for (i=0;i<256;i++)
+ g_blendtable[i][j] = (unsigned char)((i / 255.0) * (float)j);
+ }
+
+ g_render_library=new C_RLibrary();
+ g_render_effects=new C_RenderListClass(1);
+ g_render_effects2=new C_RenderListClass(1);
+ g_render_transition=new C_RenderTransitionClass();
+
+ char INI_FILE[MAX_PATH];
+ char *p=INI_FILE;
+ GetModuleFileName(hDllInstance,INI_FILE,sizeof(INI_FILE));
+ if (p[0]) while (p[1]) p++;
+ while (p >= INI_FILE && *p != '\\') p--;
+#ifdef LASER
+ strcpy(p,"\\vis_avs_laser.dat");
+#else
+ strcpy(p,"\\vis_avs.dat");
+#endif
+ extern int g_saved_preset_dirty;
+ // clear the undo stack before loading a file.
+ C_UndoStack::clear();
+ g_render_effects->__LoadPreset(INI_FILE,1);
+ // then add the new load to the undo stack but mark it clean if it is supposed to be
+ C_UndoStack::saveundo();
+ if (!g_saved_preset_dirty)
+ {
+ C_UndoStack::cleardirty();
+ }
+}
+
+void Render_Quit(HINSTANCE hDllInstance)
+{
+ if (g_render_transition) delete g_render_transition;
+ g_render_transition=NULL;
+ if (g_render_effects)
+ {
+ char INI_FILE[MAX_PATH];
+ char *p=INI_FILE;
+ GetModuleFileName(hDllInstance,INI_FILE,sizeof(INI_FILE));
+ if (p[0]) while (p[1]) p++;
+ while (p >= INI_FILE && *p != '\\') p--;
+ #ifdef LASER
+ strcpy(p,"\\vis_avs_laser.dat");
+ #else
+ strcpy(p,"\\vis_avs.dat");
+ #endif
+
+ g_render_effects->__SavePreset(INI_FILE);
+ }
+
+ if (g_render_effects) delete g_render_effects;
+ g_render_effects=NULL;
+ if (g_render_effects2) delete g_render_effects2;
+ g_render_effects2=NULL;
+
+ if (g_render_library) delete g_render_library;
+ g_render_library=NULL;
+
+ timingPrint();
+#ifdef LASER
+ if (g_laser_linelist) delete g_laser_linelist;
+ g_laser_linelist=0;
+ laser_disconnect();
+#endif
+}
diff --git a/Src/Plugins/Visualization/vis_avs/render.h b/Src/Plugins/Visualization/vis_avs/render.h
new file mode 100644
index 00000000..fe216269
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/render.h
@@ -0,0 +1,43 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include "r_defs.h"
+#include "r_list.h"
+#include "r_transition.h"
+#include "rlib.h"
+
+void Render_Init(HINSTANCE hDllInstance);
+void Render_Quit(HINSTANCE hDllInstance);
+
+extern C_RenderListClass *g_render_effects;
+extern C_RenderListClass *g_render_effects2;
+extern C_RenderTransitionClass *g_render_transition;
+extern C_RLibrary *g_render_library;
+
+extern CRITICAL_SECTION g_render_cs;
diff --git a/Src/Plugins/Visualization/vis_avs/res.rc b/Src/Plugins/Visualization/vis_avs/res.rc
new file mode 100644
index 00000000..ffe2e4ae
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/res.rc
@@ -0,0 +1,2329 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Data
+//
+
+#if defined(APSTUDIO_INVOKED) || defined(WA3_COMPONENT)
+#if defined(APSTUDIO_INVOKED)
+IDB_TAB_NORMAL$(WA3_COMPONENT) RCDATA DISCARDABLE "avs-normal.png"
+#else
+IDB_TAB_NORMAL RCDATA DISCARDABLE "avs-normal.png"
+#endif
+#endif
+#if defined(APSTUDIO_INVOKED) || defined(WA3_COMPONENT)
+#if defined(APSTUDIO_INVOKED)
+IDB_TAB_HILITED$(WA3_COMPONENT) RCDATA DISCARDABLE "avs-hilited.png"
+#else
+IDB_TAB_HILITED RCDATA DISCARDABLE "avs-hilited.png"
+#endif
+#endif
+#if defined(APSTUDIO_INVOKED) || defined(WA3_COMPONENT)
+#if defined(APSTUDIO_INVOKED)
+IDB_TAB_SELECTED$(WA3_COMPONENT) RCDATA DISCARDABLE "avs-selected.png"
+#else
+IDB_TAB_SELECTED RCDATA DISCARDABLE "avs-selected.png"
+#endif
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 400, 241
+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+CAPTION "Winamp AVS Editor"
+MENU IDR_MENU1
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "-",IDC_REMSEL,121,2,14,12
+ PUSHBUTTON "+",IDC_ADD,4,2,14,12
+ PUSHBUTTON "x2",IDC_CLONESEL,22,2,14,12,BS_CENTER
+ CONTROL "",IDC_EFFECTRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE,
+ 145,9,245,214
+ GROUPBOX "No effect/setting selected",IDC_EFNAME,139,0,257,229
+ LTEXT "",IDC_FPS,2,230,374,8
+ CONTROL "Tree1",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_SHOWSELALWAYS | TVS_NOTOOLTIPS | WS_BORDER |
+ WS_TABSTOP,4,18,131,137
+ CONTROL "",IDC_RRECT,"Static",SS_BLACKRECT | SS_NOTIFY,4,159,131,69
+END
+
+IDD_CFG_SIMPLE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Spectrum",IDC_SA,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,6,13,60,8
+ CONTROL "Oscilliscope",IDC_OSC,"Button",BS_AUTORADIOBUTTON,70,13,65,8
+ CONTROL "Lines",IDC_LINES,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,6,26,41,8
+ CONTROL "Solid",IDC_SOLID,"Button",BS_AUTORADIOBUTTON,51,26,40,8
+ CONTROL "Dots",IDC_DOT,"Button",BS_AUTORADIOBUTTON,95,26,40,8
+ CONTROL "Left Channel",IDC_LEFTCH,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,6,57,75,8
+ CONTROL "Right Channel",IDC_RIGHTCH,"Button",BS_AUTORADIOBUTTON,
+ 6,69,75,8
+ CONTROL "Center Channel",IDC_MIDCH,"Button",BS_AUTORADIOBUTTON,6,80,75,8
+ CONTROL "Top",IDC_TOP,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,110,57,45,10
+ CONTROL "Bottom",IDC_BOTTOM,"Button",BS_AUTORADIOBUTTON,110,69,45,10
+ CONTROL "Center",IDC_CENTER,"Button",BS_AUTORADIOBUTTON,110,80,45,10
+ GROUPBOX "Effect options",IDC_STATIC,0,45,245,51
+ EDITTEXT IDC_NUMCOL,53,110,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW,6,122,127,11
+ GROUPBOX "Render Effect",IDC_STATIC,0,2,245,39
+ GROUPBOX "Colors",IDC_STATIC,0,101,137,36
+ LTEXT "Cycle through ",IDC_STATIC,7,112,46,8
+ LTEXT "colors (max 16)",IDC_STATIC,77,112,48,8
+END
+
+IDD_CFG_FADE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,3,9,129,13
+ CONTROL "fade to color",IDC_LC,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,0,51,78,20
+ GROUPBOX "Fade velocity",IDC_STATIC,0,0,137,47
+ LTEXT "None .. slow",IDC_STATIC,7,25,40,8
+ LTEXT "..fast",IDC_STATIC,110,25,16,8
+END
+
+IDD_CFG_BLT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP,4,10,128,13
+ CONTROL "Enable on-beat changes",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX,5,51,93,10
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP,4,63,128,13
+ GROUPBOX "Blitter direction (onbeat)",IDC_STATIC,0,41,137,50
+ CONTROL "Blend blitter",IDC_BLEND,"Button",BS_AUTOCHECKBOX,0,95,
+ 53,10
+ GROUPBOX "Blitter direction",IDC_STATIC,0,0,137,38
+ LTEXT "Zooming in",IDC_STATIC,8,26,36,8
+ LTEXT "Zooming out",IDC_STATIC,88,26,40,8
+ LTEXT "Zooming in",IDC_STATIC,8,78,36,8
+ LTEXT "Zooming out",IDC_STATIC,88,78,40,8
+ CONTROL "Bilinear filtering",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,104,63,10
+END
+
+IDD_CFG_DOTPLANE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,6,17,95,15
+ PUSHBUTTON "zero",IDC_BUTTON1,103,15,28,10
+ CONTROL "Slider1",IDC_ANGLE,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,6,45,126,15
+ CONTROL "Top",IDC_C1,"Button",BS_OWNERDRAW | WS_TABSTOP,7,79,41,
+ 10
+ CONTROL "High",IDC_C2,"Button",BS_OWNERDRAW | WS_TABSTOP,7,90,41,
+ 10
+ CONTROL "Mid",IDC_C3,"Button",BS_OWNERDRAW | WS_TABSTOP,7,101,41,
+ 10
+ CONTROL "Low",IDC_C4,"Button",BS_OWNERDRAW | WS_TABSTOP,7,112,41,
+ 10
+ CONTROL "Bottom",IDC_C5,"Button",BS_OWNERDRAW | WS_TABSTOP,7,123,
+ 41,10
+ GROUPBOX "Rotation",IDC_STATIC,0,0,137,36
+ LTEXT "Left",IDC_STATIC,12,9,13,8
+ LTEXT "Right",IDC_STATIC,80,9,18,8
+ GROUPBOX "Dot colors",IDC_STATIC,0,69,53,68
+ GROUPBOX "Angle",IDC_STATIC,0,36,137,29
+END
+
+IDD_CFG_OSCSTAR DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,10,128,13
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,3,43,128,13
+ CONTROL "Left Channel",IDC_LEFTCH,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,8,68,56,10
+ CONTROL "Right Channel",IDC_RIGHTCH,"Button",BS_AUTORADIOBUTTON,
+ 8,78,61,10
+ CONTROL "Center Channel",IDC_MIDCH,"Button",BS_AUTORADIOBUTTON,8,
+ 88,65,10
+ CONTROL "Left",IDC_TOP,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,86,68,28,10
+ CONTROL "Right",IDC_BOTTOM,"Button",BS_AUTORADIOBUTTON,86,78,33,
+ 10
+ CONTROL "Center",IDC_CENTER,"Button",BS_AUTORADIOBUTTON,86,88,37,
+ 10
+ EDITTEXT IDC_NUMCOL,53,107,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,6,122,
+ 127,11
+ GROUPBOX "Star size",IDC_STATIC,0,0,137,39
+ GROUPBOX "Rotation",IDC_STATIC,0,34,137,30
+ GROUPBOX "Star source and position",IDC_STATIC,0,59,137,42
+ GROUPBOX "Colors",IDC_STATIC,0,101,137,36
+ LTEXT "Cycle through ",IDC_STATIC,7,109,46,8
+ LTEXT "colors (max 16)",IDC_STATIC,77,109,48,8
+ LTEXT "Small",IDC_STATIC,8,24,18,8
+ LTEXT "Large",IDC_STATIC,106,25,19,8
+END
+
+IDD_CFG_NFC DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,9,128,13
+ CONTROL "Color...",IDC_BUTTON1,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,0,40,46,10
+ CONTROL "Blend to color",IDC_BLEND,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,49,40,59,10
+ GROUPBOX "Clear every N beats",IDC_STATIC,0,0,137,36
+ LTEXT "0",IDC_STATIC,7,24,8,8
+ LTEXT "100",IDC_STATIC,115,24,13,8
+END
+
+IDD_CFG_BLUR DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "No blur",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,2,1,39,10
+ CONTROL "Light blur",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,2,12,
+ 45,10
+ CONTROL "Medium blur",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,2,
+ 23,54,10
+ CONTROL "Heavy blur",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,2,34,
+ 50,10
+ CONTROL "Round down",IDC_ROUNDDOWN,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,3,58,57,10
+ CONTROL "Round up",IDC_ROUNDUP,"Button",BS_AUTORADIOBUTTON,3,69,
+ 47,10
+END
+
+IDD_CFG_BSPIN DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Left enabled",IDC_LEFT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,55,10
+ CONTROL "Right enabled",IDC_RIGHT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,11,60,10
+ CONTROL "left color",IDC_LC,"Button",BS_OWNERDRAW | WS_TABSTOP,
+ 61,0,40,10
+ CONTROL "right color",IDC_RC,"Button",BS_OWNERDRAW | WS_TABSTOP,
+ 61,11,40,10
+ CONTROL "Filled Triangles",IDC_TRI,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,23,63,10
+ CONTROL "Lines",IDC_LINES,"Button",BS_AUTORADIOBUTTON,0,32,33,10
+END
+
+IDD_GCFG_DISP DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Wait for retrace",IDC_CHECK6,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,5,10,65,10
+ CONTROL "Pixel doubling (half resolution)",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,20,115,10
+ LTEXT "Windowed performance:",IDC_STATIC,5,33,78,8
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,40,127,14
+ LTEXT "Higher framerate",IDC_STATIC,8,56,54,9
+ CONTROL "Suppress status text in windowed",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,67,121,10
+ CONTROL "Suppress title text in windowed",IDC_CHECK5,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,77,113,10
+ CONTROL "Reuse image on window resize",IDC_CHECK2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,88,113,10
+ CONTROL "Enable (Win2k/XP only)",IDC_TRANS_CHECK,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,122,99,10
+ CONTROL "Slider1",IDC_TRANS_SLIDER,"msctls_trackbar32",
+ TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,6,140,119,10
+ CONTROL "color",IDC_OVERLAYCOLOR,"Button",BS_OWNERDRAW |
+ WS_TABSTOP,146,23,40,10
+ PUSHBUTTON "default",IDC_DEFOVERLAYCOLOR,190,23,40,10
+ CONTROL "Set desktop to color",IDC_SETDESKTOPCOLOR,"Button",
+ BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,146,76,82,11
+ COMBOBOX IDC_THREAD_PRIORITY,144,138,86,65,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Projection zones...",IDC_L_PROJZONES,5,169,78,14,NOT
+ WS_VISIBLE
+ GROUPBOX "Windowed settings",IDC_STATIC,0,0,137,104
+ LTEXT "Lower framerate",IDC_STATIC,77,56,53,8
+ GROUPBOX "Alpha blending",IDC_STATIC_ALPHA,0,107,137,49
+ LTEXT "Total",IDC_STATIC_TRANS_TOTAL,5,133,17,8
+ LTEXT "None",IDC_STATIC_TRANS_NONE,108,133,18,8
+ GROUPBOX "Laser",IDC_L_FRAME,0,158,232,56,NOT WS_VISIBLE
+ GROUPBOX "Overlay mode",IDC_STATIC,140,0,93,91
+ CONTROL "Overlay mode",IDC_BKGND_RENDER,"Button",BS_AUTOCHECKBOX |
+ BS_MULTILINE | WS_TABSTOP,145,9,82,11
+ LTEXT "Note that the overlay color must be carefully selected at non-32bpp color depths.",
+ IDC_STATIC,148,41,75,33
+ GROUPBOX "Priority",IDC_STATIC,140,107,93,49
+ LTEXT "Render thread priority:",IDC_STATIC,145,122,70,8
+ CONTROL "Suppress laser-related messages",IDC_L_SUPPRESS_DIALOGS,
+ "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,
+ 99,188,119,10
+ CONTROL "Suppress laser output when Winamp or AVS/Laser is not active",
+ IDC_L_ACTIVEOUTPUT,"Button",BS_AUTOCHECKBOX | NOT
+ WS_VISIBLE | WS_TABSTOP,5,198,216,10
+ CONTROL "Suppress laser output",IDC_L_SUPPRESS_OUTPUT,"Button",
+ BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,5,187,84,
+ 10
+ CONTROL "Sync with laser (no call to DBStatus)",IDC_L_SYNC,
+ "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,
+ 90,171,130,10
+ GROUPBOX "SMP support",IDC_THREADSBORDER,1,160,232,29
+ CONTROL "Experimental multiprocessor support:",IDC_CHECK4,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,8,171,130,10
+ EDITTEXT IDC_EDIT1,139,170,28,12,ES_AUTOHSCROLL
+ LTEXT "threads",IDC_THREADS,170,172,24,8
+END
+
+IDD_CFG_PARTS DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "enabled",IDC_LEFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 0,0,41,10
+ CONTROL "color",IDC_LC,"Button",BS_OWNERDRAW | WS_TABSTOP,43,0,
+ 40,10
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,21,130,16
+ CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,47,130,16
+ CONTROL "Onbeat sizechange enabled.",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,9,75,107,10
+ CONTROL "Slider1",IDC_SLIDER4,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,84,130,16
+ CONTROL "Replace",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,5,114,43,10
+ CONTROL "Additive",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,51,114,
+ 41,10
+ CONTROL "50/50",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,93,114,35,
+ 10
+ CONTROL "Default render blend mode",IDC_RADIO4,"Button",
+ BS_AUTORADIOBUTTON,5,124,99,9
+ GROUPBOX "Distance from center",IDC_STATIC,0,13,137,32
+ GROUPBOX "Particle size",IDC_STATIC,0,40,137,30
+ GROUPBOX "Particle size (onbeat)",IDC_STATIC,0,65,137,45
+ GROUPBOX "Blending",IDC_STATIC,0,105,137,32
+END
+
+IDD_CFG_ROTBLT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,10,128,15
+ CONTROL "Enable on-beat change",IDC_CHECK6,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,28,90,10
+ CONTROL "Slider1",IDC_SLIDER6,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,37,128,13
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,78,128,15
+ CONTROL "Enable on-beat reversal",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,107,91,10
+ CONTROL "Slider1",IDC_SLIDER5,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,115,128,15
+ CONTROL "Blend blitter",IDC_BLEND,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,147,53,10
+ GROUPBOX "Zoom",IDC_STATIC,0,0,137,146
+ LTEXT "Zooming in",IDC_STATIC,8,52,36,8
+ LTEXT "Zooming out",IDC_STATIC,88,52,40,8
+ GROUPBOX "Rotation",IDC_STATIC,0,69,137,77
+ LTEXT "Rotating Left",IDC_STATIC,7,96,42,8
+ LTEXT "Rotating Right",IDC_STATIC,83,96,46,8
+ LTEXT "Fast reversal",IDC_STATIC,8,132,41,8
+ LTEXT "Slow reversal",IDC_STATIC,83,132,43,8
+ CONTROL "Bilinear filtering",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,55,147,63,10
+END
+
+IDC_CFG_SVP DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ GROUPBOX "SVP/UVS library",IDC_STATIC,0,0,233,34
+ COMBOBOX IDC_COMBO1,4,12,225,222,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_CFG_COLORFADE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable colorfade",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,69,10
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,0,11,100,14
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,0,28,100,14
+ CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,0,46,100,14
+ CONTROL "Onbeat Randomize",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,9,79,73,10
+ CONTROL "OnBeat Change",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,67,67,10
+ CONTROL "Slider1",IDC_SLIDER4,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,7,90,100,14
+ CONTROL "Slider1",IDC_SLIDER5,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,7,107,100,14
+ CONTROL "Slider1",IDC_SLIDER6,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,7,125,100,14
+END
+
+IDD_CFG_CONTRASTENHANCE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Off",IDC_OFF,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,0,0,25,10
+ CONTROL "Below",IDC_BELOW,"Button",BS_AUTORADIOBUTTON,0,10,35,10
+ CONTROL "Above",IDC_ABOVE,"Button",BS_AUTORADIOBUTTON,0,20,37,10
+ CONTROL "Near",IDC_NEAR,"Button",BS_AUTORADIOBUTTON,0,30,31,10
+ CONTROL "Slider1",IDC_DISTANCE,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,36,29,101,13
+ CONTROL "color",IDC_LC,"Button",BS_OWNERDRAW | WS_TABSTOP,0,46,
+ 26,10
+ PUSHBUTTON "->",IDC_BUTTON1,28,46,17,10
+ CONTROL "outcolor",IDC_LC2,"Button",BS_OWNERDRAW | WS_TABSTOP,47,
+ 46,37,10
+END
+
+IDD_CFG_ROTSTAR DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_NUMCOL,53,6,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW,6,21,127,11
+ GROUPBOX "Colors",-1,0,0,137,36
+ LTEXT "Cycle through ",-1,7,8,46,8
+ LTEXT "colors (max 16)",-1,77,8,48,8
+END
+
+IDD_CFG_OSCRING DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,4,10,128,15
+ CONTROL "Oscilliscope",IDC_OSC,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,8,56,53,10
+ CONTROL "Spectrum",IDC_SPEC,"Button",BS_AUTORADIOBUTTON,65,56,46,
+ 10
+ CONTROL "Left Channel",IDC_LEFTCH,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,8,68,56,10
+ CONTROL "Right Channel",IDC_RIGHTCH,"Button",BS_AUTORADIOBUTTON,
+ 8,78,61,10
+ CONTROL "Center Channel",IDC_MIDCH,"Button",BS_AUTORADIOBUTTON,8,
+ 88,65,10
+ CONTROL "Left",IDC_TOP,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,86,68,28,10
+ CONTROL "Right",IDC_BOTTOM,"Button",BS_AUTORADIOBUTTON,86,78,33,
+ 10
+ CONTROL "Center",IDC_CENTER,"Button",BS_AUTORADIOBUTTON,86,88,37,
+ 10
+ EDITTEXT IDC_NUMCOL,53,107,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,6,122,
+ 127,11
+ GROUPBOX "Ring size",-1,0,0,137,42
+ GROUPBOX "Ring source and position",-1,0,44,137,57
+ GROUPBOX "Colors",-1,0,101,137,36
+ LTEXT "Cycle through ",-1,7,109,46,8
+ LTEXT "colors (max 16)",-1,77,109,48,8
+ LTEXT "Small",-1,8,29,18,8
+ LTEXT "Large",-1,106,30,19,8
+END
+
+IDD_GCFG_PRESET DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ COMBOBOX IDC_COMBO1,5,11,64,203,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ PUSHBUTTON "save to hotkey",IDC_BUTTON1,5,26,56,14
+ PUSHBUTTON "load from hotkey",IDC_BUTTON2,66,26,56,14
+ CONTROL "Randomly switch presets",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,180,93,10
+ EDITTEXT IDC_EDIT1,38,191,21,12,ES_AUTOHSCROLL | ES_NUMBER
+ PUSHBUTTON "All",IDC_BUTTON3,0,161,233,15,BS_LEFT
+ GROUPBOX "Hotkeys",IDC_STATIC,0,0,135,112
+ LTEXT "Note: you can load hotkey settings in the render window by hitting the hotkey. \n\nYou can save hotkey settings in the render window by holding control and hitting the hotkey.",
+ IDC_STATIC,5,49,114,57
+ LTEXT "seconds",IDC_STATIC,61,193,28,8
+ LTEXT "Every",IDC_STATIC,15,193,19,8
+ LTEXT "Preset (sub) directory to use for random/cycle:",
+ IDC_STATIC,0,150,146,8
+ CONTROL "Prompt to save unsaved presets when loading other presets",
+ IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,124,
+ 204,10
+END
+
+IDD_CFG_SCAT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable scatter effect",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,81,10
+END
+
+IDD_CFG_DOTGRID DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_NUMCOL,53,6,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,6,21,
+ 127,11
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,16,47,85,13
+ PUSHBUTTON "zero",IDC_BUTTON1,103,50,28,10
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,16,65,85,13
+ PUSHBUTTON "zero",IDC_BUTTON3,103,68,28,10
+ CONTROL "Replace",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,5,99,43,10
+ CONTROL "Additive",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,51,99,
+ 41,10
+ CONTROL "50/50",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,93,99,35,
+ 10
+ CONTROL "Default render blend mode",IDC_RADIO4,"Button",
+ BS_AUTORADIOBUTTON,5,109,99,10
+ EDITTEXT IDC_EDIT1,44,125,20,12,ES_AUTOHSCROLL | ES_NUMBER
+ GROUPBOX "Colors",IDC_STATIC,0,0,137,36
+ LTEXT "Cycle through ",IDC_STATIC,7,8,46,8
+ LTEXT "colors (max 16)",IDC_STATIC,77,8,48,8
+ LTEXT "Dot spacing: ",IDC_STATIC,0,127,43,8
+ LTEXT "pixels",IDC_STATIC,67,127,18,8
+ GROUPBOX "Grid movement",IDC_STATIC,0,37,137,52
+ LTEXT "X",IDC_STATIC,8,50,8,8
+ LTEXT "Y",IDC_STATIC,8,69,8,8
+ GROUPBOX "Blending",IDC_STATIC,0,90,137,34
+END
+
+IDD_CFG_STACK DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Save framebuffer",IDC_SAVEFB,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,5,7,70,10
+ CONTROL "Restore framebuffer",IDC_RESTFB,"Button",
+ BS_AUTORADIOBUTTON,5,17,78,10
+ CONTROL "Alternate Save/Restore",IDC_RADIO1,"Button",
+ BS_AUTORADIOBUTTON,5,28,91,10
+ CONTROL "Alternate Restore/Save",IDC_RADIO7,"Button",
+ BS_AUTORADIOBUTTON,5,38,91,10
+ PUSHBUTTON "Nudge parity",IDC_BUTTON2,100,31,50,14
+ COMBOBOX IDC_COMBO1,32,53,74,90,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Replace",IDC_RSTACK_BLEND1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,12,79,43,10
+ CONTROL "50/50",IDC_RSTACK_BLEND2,"Button",BS_AUTORADIOBUTTON,12,
+ 89,35,10
+ CONTROL "Additive",IDC_RSTACK_BLEND3,"Button",BS_AUTORADIOBUTTON,
+ 12,99,41,10
+ CONTROL "Every other pixel",IDC_RSTACK_BLEND4,"Button",
+ BS_AUTORADIOBUTTON,12,109,68,10
+ CONTROL "Every other line",IDC_RSTACK_BLEND6,"Button",
+ BS_AUTORADIOBUTTON,12,118,65,10
+ CONTROL "Subtractive 1",IDC_RSTACK_BLEND5,"Button",
+ BS_AUTORADIOBUTTON,12,128,58,10
+ CONTROL "Subtractive 2",IDC_RSTACK_BLEND10,"Button",
+ BS_AUTORADIOBUTTON,12,138,58,10
+ CONTROL "Xor",IDC_RSTACK_BLEND7,"Button",BS_AUTORADIOBUTTON,12,
+ 148,27,10
+ CONTROL "Maximum",IDC_RSTACK_BLEND8,"Button",BS_AUTORADIOBUTTON,
+ 12,158,45,10
+ CONTROL "Minimum",IDC_RSTACK_BLEND9,"Button",BS_AUTORADIOBUTTON,
+ 12,168,43,10
+ CONTROL "Multiply",IDC_RSTACK_BLEND11,"Button",
+ BS_AUTORADIOBUTTON,12,178,39,10
+ CONTROL "Adjustable:",IDC_RSTACK_BLEND12,"Button",
+ BS_AUTORADIOBUTTON,12,188,51,10
+ CONTROL "Slider2",IDC_BLENDSLIDE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,62,188,111,11
+ PUSHBUTTON "Clear buffer",IDC_BUTTON1,99,11,50,14
+ GROUPBOX "Blending",IDC_STATIC,8,68,172,138
+ LTEXT "Buffer:",IDC_STATIC,8,55,22,8
+END
+
+IDD_DIALOG2 DIALOGEX 0, 0, 205, 150
+STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About AVS"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,77,129,50,14
+ LTEXT "version string",IDC_VERSTR,7,7,191,8
+ LTEXT "Copyright (C) 1998-2023 Winamp SA",IDC_STATIC,7,16,191,8
+ CTEXT "Justin Frankel, Francis Gastellu, Christophe Thibault\r\nBrennan Underwood && mig",
+ IDC_STATIC,22,85,168,19
+ LTEXT "Portions Copyright (C) 2010 Cockos Incorporated\r\r\nThis software is BSD-licensed open source.",
+ IDC_STATIC,7,26,191,26
+ CTEXT "You are welcome to use AVS at parties, clubs, concerts, and whatnot. Just give credit where credit is due.",
+ IDC_STATIC,7,54,191,17
+ LTEXT "Love,",IDC_STATIC,7,74,19,8
+ CTEXT "Special thanks to Steven Wittens and Tom Holden for their contributions.",
+ IDC_STATIC,7,107,191,19
+END
+
+IDD_CFG_WATER DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Water effect",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,79,10
+END
+
+IDD_CFG_COMMENT DIALOGEX 0, 0, 233, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT1,0,0,233,214,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_WANTRETURN | WS_VSCROLL
+END
+
+IDD_CFG_BRIGHTNESS DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Brightness filter",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,87,10
+ CONTROL "Slider1",IDC_RED,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,25,13,97,13
+ PUSHBUTTON "><",IDC_BRED,125,12,12,14
+ CONTROL "Slider1",IDC_GREEN,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,25,28,97,13
+ PUSHBUTTON "><",IDC_BGREEN,125,28,12,14
+ CONTROL "Slider1",IDC_BLUE,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,25,44,97,13
+ PUSHBUTTON "><",IDC_BBLUE,125,44,12,14
+ CONTROL "Dissociate RGB values",IDC_DISSOC,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,60,89,10
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,71,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,81,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,92,
+ 55,10
+ CONTROL "Exclude color range",IDC_EXCLUDE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,103,79,10
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,0,114,
+ 29,13
+ CONTROL "Slider1",IDC_DISTANCE,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,31,114,106,13
+ LTEXT "Red",IDC_STATIC,0,15,14,8
+ LTEXT "Blue",IDC_STATIC,0,47,15,8
+ LTEXT "Green",IDC_STATIC,0,31,20,8
+END
+
+IDD_CFG_INTERLEAVE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Interleave effect",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,91,10
+ CONTROL "Slider1",IDC_X,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,0,12,137,13
+ CONTROL "Slider1",IDC_Y,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,0,27,137,13
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,0,43,
+ 137,13
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,58,43,10
+ CONTROL "50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,42,58,35,10
+ CONTROL "Add",IDC_ADDITIVE,"Button",BS_AUTORADIOBUTTON,77,58,29,
+ 10
+ CONTROL "OnBeat",IDC_CHECK8,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,70,40,10
+ CONTROL "Slider1",IDC_X2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,0,83,137,13
+ CONTROL "Slider1",IDC_Y2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,0,98,137,13
+ CONTROL "Slider1",IDC_X3,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,41,112,95,13
+ LTEXT "Duration",IDC_STATIC,3,115,32,8
+END
+
+IDD_CFG_GRAIN DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Grain filter",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,71,10
+ CONTROL "Slider1",IDC_MAX,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_BORDER | WS_TABSTOP,0,12,137,13
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,28,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,38,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,49,
+ 55,10
+ CONTROL "Static grain",IDC_STATGRAIN,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,60,51,10
+END
+
+IDD_CFG_CLEAR DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Clear screen",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,79,10
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,0,15,
+ 137,13
+ CONTROL "First frame only",IDC_CLEARFIRSTFRAME,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,30,63,10
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,41,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,51,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,61,
+ 55,10
+ CONTROL "Default render blend mode",IDC_DEFRENDBLEND,"Button",
+ BS_AUTORADIOBUTTON,0,71,99,10
+END
+
+IDD_CFG_MIRROR DIALOGEX 0, 0, 245, 213
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Mirror effect",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,77,10
+ CONTROL "Static",IDC_STAT,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,0,20,34,10
+ CONTROL "OnBeat random",IDC_ONBEAT,"Button",BS_AUTORADIOBUTTON,0,
+ 29,65,10
+ CONTROL "Copy Top to Bottom",IDC_HORIZONTAL1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,3,44,79,10
+ CONTROL "Copy Bottom to Top",IDC_HORIZONTAL2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,3,54,88,9
+ CONTROL "Copy Left to Right",IDC_VERTICAL1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,3,63,88,10
+ CONTROL "Copy Right to Left",IDC_VERTICAL2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,3,73,98,10
+ CONTROL "Smooth transitions",IDC_SMOOTH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,90,73,10
+ CONTROL "Slider1",IDC_SLOWER,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_BORDER | WS_TABSTOP,0,103,137,11
+ GROUPBOX "",IDC_STATIC,0,36,137,51
+ LTEXT "Faster",IDC_STATIC,0,114,20,8
+ LTEXT "Slower",IDC_STATIC,115,114,22,8
+END
+
+IDD_CFG_STARFIELD DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Starfield",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,65,10
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,13,137,11
+ CONTROL "Slider2",IDC_NUMSTARS,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,32,137,11
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,52,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,62,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,72,
+ 55,10
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,100,57,
+ 37,15
+ CONTROL "OnBeat Speed changes",IDC_ONBEAT2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,82,92,10
+ CONTROL "Slider1",IDC_SPDCHG,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,93,137,11
+ CONTROL "Slider2",IDC_SPDDUR,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,112,137,11
+ LTEXT "Fast",IDC_STATIC,123,23,14,8
+ LTEXT "Slow",IDC_STATIC,0,23,16,8
+ LTEXT "More stars",IDC_STATIC,103,42,34,8
+ LTEXT "Fewer stars",IDC_STATIC,0,42,37,8
+ LTEXT "Faster",IDC_STATIC,117,103,20,8
+ LTEXT "Slower",IDC_STATIC,0,103,22,8
+ LTEXT "Longer",IDC_STATIC,114,122,23,8
+ LTEXT "Shorter",IDC_STATIC,0,122,24,8
+END
+
+IDD_CFG_TEXT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Text",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,1,51,10
+ CONTROL "OnBeat",IDC_ONBEAT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,11,40,10
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,57,1,102,11
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,21,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,42,21,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,103,
+ 21,55,10
+ CONTROL "Color",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,
+ 45,32,11
+ CONTROL "Outline/Shadow color",IDC_DEFOUTCOL,"Button",
+ BS_OWNERDRAW | WS_TABSTOP,5,76,109,11
+ PUSHBUTTON "Choose font",IDC_CHOOSEFONT,43,45,57,11
+ CONTROL "Random",IDC_RANDOMPOS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,6,113,43,10
+ CONTROL "Left",IDC_HLEFT,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,14,133,28,10
+ CONTROL "Center",IDC_HCENTER,"Button",BS_AUTORADIOBUTTON,14,143,
+ 33,10
+ CONTROL "Right",IDC_HRIGHT,"Button",BS_AUTORADIOBUTTON,14,154,29,
+ 10
+ CONTROL "Slider1",IDC_HSHIFT,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,8,165,37,10
+ PUSHBUTTON "><",IDC_HRESET,48,166,9,9
+ CONTROL "Top",IDC_VTOP,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,71,135,29,10
+ CONTROL "Center",IDC_VCENTER,"Button",BS_AUTORADIOBUTTON,71,146,
+ 33,10
+ CONTROL "Bottom",IDC_VBOTTOM,"Button",BS_AUTORADIOBUTTON,71,157,
+ 34,10
+ CONTROL "Slider1",IDC_VSHIFT,"msctls_trackbar32",TBS_VERT |
+ TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,112,130,9,35
+ PUSHBUTTON "><",IDC_VRESET,112,166,9,9
+ CONTROL "insert blanks",IDC_BLANKS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,165,191,55,10
+ CONTROL "Slider1",IDC_OUTLINESIZE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,85,89,42,9
+ CONTROL "Plain",IDC_PLAIN,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,5,62,29,10
+ CONTROL "Outlined",IDC_OUTLINE,"Button",BS_AUTORADIOBUTTON,37,62,
+ 39,10
+ CONTROL "Shadowed",IDC_SHADOW,"Button",BS_AUTORADIOBUTTON,81,62,
+ 46,10
+ CONTROL "random ordering",IDC_RANDWORD,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,98,191,67,10
+ EDITTEXT IDC_EDIT,0,202,233,12,ES_AUTOHSCROLL
+ GROUPBOX "Horizontal",IDC_STATIC,6,124,56,55,WS_GROUP
+ LTEXT "Fast",IDC_STATIC,61,11,14,8
+ LTEXT "Slow",IDC_STATIC,140,11,16,8
+ GROUPBOX "Vertical",IDC_STATIC,65,124,61,55,WS_GROUP
+ LTEXT "Text to display (';' separated) :",IDC_STATIC,0,191,94,
+ 8
+ GROUPBOX "Text positioning",IDC_STATIC,0,103,138,83
+ GROUPBOX "Text style",IDC_STATIC,0,34,138,68
+ LTEXT "Outline/Shadow amount:",IDC_STATIC,5,89,80,8
+ LTEXT "In the text, one can use $(title) to get the current track title, $(title:n) to get the title with playlist entry number, $(title:32) to get the first 32 characters of the title, $(title:n32) to get the first 32 characters of the title+track number. ",
+ IDC_STATIC,142,38,86,72
+ LTEXT "Also of use, $(reg00) or $(reg00:1.3) (formats like 2.000), and $(playpos) and $(playlen) and $(playpos.1) and $(playpos.3). Ok so this needs better explanation, but that'll come later.",
+ IDC_STATIC,142,115,86,64
+END
+
+IDD_CFG_BUMP DIALOG 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "Enable Bump",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,56,10
+ CONTROL "Invert depth",IDC_INVERTDEPTH,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,10,54,10
+ CONTROL "Slider1",IDC_DEPTH,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,58,11,79,11
+ CONTROL "Show Dot",IDC_DOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 0,20,47,10
+ LTEXT "Flat",IDC_STATIC,61,22,12,8
+ LTEXT "Bumpy",IDC_STATIC,115,22,22,8
+ LTEXT "Light position:",IDC_STATIC,0,38,44,8
+ LTEXT "init",IDC_STATIC,0,63,10,8
+ EDITTEXT IDC_CODE3,24,52,209,33,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ PUSHBUTTON "expression help",IDC_HELPBTN,52,36,71,12
+ EDITTEXT IDC_CODE1,24,87,209,48,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_CODE2,24,136,209,40,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ COMBOBOX IDC_COMBO1,52,179,85,56,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,148,0,43,10
+ CONTROL "OnBeat",IDC_ONBEAT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,198,40,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,148,9,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,148,
+ 19,55,10
+ CONTROL "Slider2",IDC_BEATDUR,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,44,196,67,11
+ CONTROL "Slider1",IDC_DEPTH2,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,114,196,67,11
+ LTEXT "Bumpy",IDC_STATIC,159,207,22,8
+ LTEXT "Flat",IDC_STATIC,117,207,12,8
+ LTEXT "Longer",IDC_STATIC,84,207,23,8
+ LTEXT "Shorter",IDC_STATIC,44,207,24,8
+ LTEXT "frame",IDC_STATIC,0,108,18,8
+ LTEXT "beat",IDC_STATIC,1,151,15,8
+ LTEXT "Depth buffer :",IDC_STATIC,0,181,44,8
+END
+
+IDD_CFG_MOSAIC DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Mosaic",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,65,10
+ CONTROL "Slider1",IDC_QUALITY,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,13,137,11
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,33,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,43,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,53,
+ 55,10
+ CONTROL "OnBeat",IDC_ONBEAT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,63,40,10
+ CONTROL "Slider1",IDC_QUALITY2,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,74,137,11
+ CONTROL "Slider2",IDC_BEATDUR,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,93,137,11
+ LTEXT "Smaller squares",IDC_STATIC,87,23,50,8
+ LTEXT "Bigger squares",IDC_STATIC,0,23,48,8
+ LTEXT "Smaller",IDC_STATIC,113,84,24,8
+ LTEXT "Bigger",IDC_STATIC,0,84,21,8
+ LTEXT "Longer",IDC_STATIC,114,103,23,8
+ LTEXT "Shorter",IDC_STATIC,0,103,24,8
+END
+
+IDD_CFG_WATERBUMP DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Water bump effect",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,99,10
+ CONTROL "Slider1",IDC_DAMP,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,5,21,130,12
+ CONTROL "Random drop position",IDC_RANDOM_DROP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,2,51,85,10
+ CONTROL "Left",IDC_DROP_LEFT,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,6,72,28,10
+ CONTROL "Center",IDC_DROP_CENTER,"Button",BS_AUTORADIOBUTTON,46,
+ 72,37,10
+ CONTROL "Right",IDC_DROP_RIGHT,"Button",BS_AUTORADIOBUTTON,95,72,
+ 33,10
+ CONTROL "Top",IDC_DROP_TOP,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,6,84,29,10
+ GROUPBOX "Drop position",-1,0,61,137,36
+ CONTROL "Middle",IDC_DROP_MIDDLE,"Button",BS_AUTORADIOBUTTON,46,
+ 84,37,10
+ CONTROL "Bottom",IDC_DROP_BOTTOM,"Button",BS_AUTORADIOBUTTON,95,
+ 84,38,10
+ CONTROL "Slider1",IDC_DEPTH,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,5,108,56,12
+ CONTROL "Slider1",IDC_RADIUS,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,74,108,58,12
+ LTEXT "Thicker",-1,3,34,25,8
+ LTEXT "Fluid",-1,118,34,16,8
+ GROUPBOX "Water density",-1,0,11,137,36
+ LTEXT "Less",-1,3,120,16,8
+ LTEXT "More",-1,44,120,17,8
+ GROUPBOX "Drop depth",-1,0,98,67,36
+ LTEXT "Small",-1,75,120,18,8
+ LTEXT "Big",-1,120,120,11,8
+ GROUPBOX "Drop radius",-1,70,98,67,36
+END
+
+IDD_CFG_AVI DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ COMBOBOX OBJ_COMBO,0,12,233,92,CBS_DROPDOWNLIST | CBS_SORT |
+ CBS_UPPERCASE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,29,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,39,61,10
+ CONTROL "Blend 50/50 + OnBeat Additive",IDC_ADAPT,"Button",
+ BS_AUTORADIOBUTTON,0,59,115,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,49,
+ 55,10
+ CONTROL "Slider1",IDC_PERSIST,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,6,79,222,19
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,6,121,222,19
+ CONTROL "Enable AVI stream",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,74,10
+ GROUPBOX "Beat persistance",IDC_PERSIST_TITLE,0,70,233,31
+ GROUPBOX "Speed",IDC_STATIC,0,102,233,43
+ LTEXT "Faster",IDC_STATIC,6,112,20,8
+ LTEXT "Slower",IDC_STATIC,206,112,22,8
+END
+
+IDD_CFG_UNKN DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT1,0,0,233,31,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_READONLY | NOT WS_TABSTOP
+END
+
+IDD_CFG_BPM DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable BPM Customizer",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,137,10
+ CONTROL "Arbitrary",IDC_ARBITRARY,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,14,41,10
+ CONTROL "Slider1",IDC_ARBVAL,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,38,14,65,11
+ CONTROL "Skip",IDC_SKIP,"Button",BS_AUTORADIOBUTTON,0,24,30,10
+ CONTROL "Slider1",IDC_SKIPVAL,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,38,24,65,11
+ CONTROL "Reverse",IDC_INVERT,"Button",BS_AUTORADIOBUTTON,0,34,43,
+ 10
+ LTEXT "First skip",IDC_STATIC,0,45,28,8
+ CONTROL "Slider1",IDC_SKIPFIRST,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,38,45,65,11
+ CONTROL "Slider1",IDC_IN,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_DISABLED | WS_TABSTOP,13,56,124,11
+ CONTROL "Slider1",IDC_OUT,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_DISABLED | WS_TABSTOP,13,66,124,11
+ LTEXT "1s",IDC_ARBTXT,103,15,34,8
+ LTEXT "1 beat",IDC_SKIPTXT,103,24,34,8
+ LTEXT "In",IDC_STATIC,0,57,8,8
+ LTEXT "Out",IDC_STATIC,0,67,12,8
+ LTEXT "1 beat",IDC_SKIPFIRSTTXT,103,45,34,8
+END
+
+IDD_GCFG_BPM DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Standard",IDC_BPMSTD,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,4,11,45,10
+ CONTROL "Advanced",IDC_BPMADV,"Button",BS_AUTORADIOBUTTON,4,21,
+ 49,10
+ CONTROL "Slider1",IDC_IN,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_DISABLED | WS_TABSTOP,55,11,79,11
+ CONTROL "Slider1",IDC_OUT,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_DISABLED | WS_TABSTOP,55,21,79,11
+ LTEXT "Current BPM :",IDC_CURBPM,8,43,45,8
+ CONTROL "Auto-keep",IDC_STICKY,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,8,61,49,10
+ PUSHBUTTON "Reset",IDC_RESET,7,80,23,10
+ PUSHBUTTON "Keep",IDC_STICK,34,80,29,10
+ PUSHBUTTON "Readapt",IDC_UNSTICK,66,80,29,10
+ GROUPBOX "New Song",IDC_STATIC,8,90,121,32
+ CONTROL "Adapt from known BPM",IDC_NEWADAPT,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,99,91,10
+ CONTROL "Restart learning from scratch",IDC_NEWRESET,"Button",
+ BS_AUTORADIOBUTTON,13,109,106,10
+ GROUPBOX "Advanced status",IDC_STATIC,4,33,128,92
+ LTEXT "",IDC_BPM,55,43,70,8
+ LTEXT "Confidence :",IDC_CURCONF,8,52,41,8
+ LTEXT "",IDC_CONFIDENCE,55,52,71,8
+ GROUPBOX "Beat detection settings",IDC_STATIC,0,0,137,130
+ CONTROL "Predict only if bpm has been found",IDC_ONLYSTICKY,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,70,121,10
+END
+
+IDD_CFG_PICTURE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Picture rendering",IDC_ENABLED,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,93,10
+ COMBOBOX OBJ_COMBO,1,14,232,223,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,30,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,41,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,52,
+ 55,10
+ CONTROL "Blend 50/50 + OnBeat Additive",IDC_ADAPT,"Button",
+ BS_AUTORADIOBUTTON,0,63,115,10
+ CONTROL "Slider1",IDC_PERSIST,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,6,92,125,19
+ CONTROL "Keep aspect ratio",IDC_RATIO,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,2,121,71,10
+ CONTROL "On X-Axis",IDC_X_RATIO,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,20,136,47,10
+ CONTROL "On Y-Axis",IDC_Y_RATIO,"Button",BS_AUTORADIOBUTTON,20,
+ 147,47,10
+ GROUPBOX "Beat persistance",IDC_PERSIST_TITLE,0,73,137,42
+ LTEXT "Fast",IDC_PERSIST_TEXT1,4,83,14,8
+ LTEXT "Long",IDC_PERSIST_TEXT2,115,83,17,8
+END
+
+IDD_CFG_TRANS DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ LISTBOX IDC_LIST1,101,0,132,142,LBS_NOINTEGRALHEIGHT |
+ WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_EDIT1,0,144,233,70,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN
+ CONTROL "Rectangular coordinates for user defined code",
+ IDC_CHECK3,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ WS_TABSTOP,0,114,100,15
+ CONTROL "Blend",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 0,18,34,10
+ CONTROL "Source map",IDC_CHECK2,"Button",BS_AUTO3STATE |
+ WS_TABSTOP,0,0,54,10
+ CONTROL "Bilinear filtering",IDC_CHECK4,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,27,61,10
+ CONTROL "Wrap",IDC_WRAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,
+ 9,33,10
+ PUSHBUTTON "expression help",IDC_BUTTON2,0,97,55,15,BS_MULTILINE
+ LTEXT "User defined code:",IDC_LABEL1,0,134,61,8
+END
+
+IDD_CFG_DDM DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT4,25,0,208,39,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT2,25,38,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT3,25,91,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT1,25,144,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ CONTROL "Blend",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 0,204,34,10
+ CONTROL "Bilinear filtering",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,38,204,63,10
+ PUSHBUTTON "expression help",IDC_BUTTON1,171,200,62,14,BS_MULTILINE
+ LTEXT "pixel",IDC_STATIC,0,166,15,8
+ LTEXT "frame",IDC_STATIC,0,60,18,8
+ LTEXT "beat",IDC_STATIC,0,113,15,8
+ LTEXT "init",IDC_STATIC,0,14,10,8
+END
+
+IDD_CFG_SSCOPE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT4,25,0,208,26,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT2,25,26,208,46,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT3,25,72,208,38,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT1,25,110,208,56,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ CONTROL "Waveform",IDC_WAVE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,5,178,49,10
+ CONTROL "Spectrum",IDC_SPEC,"Button",BS_AUTORADIOBUTTON,55,178,
+ 46,10
+ CONTROL "Left",IDC_LEFTCH,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,5,189,28,10
+ CONTROL "Center",IDC_MIDCH,"Button",BS_AUTORADIOBUTTON,36,189,37,
+ 10
+ CONTROL "Right",IDC_RIGHTCH,"Button",BS_AUTORADIOBUTTON,76,189,
+ 33,10
+ EDITTEXT IDC_NUMCOL,47,202,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,125,202,
+ 108,11
+ PUSHBUTTON "Load example...",IDC_BUTTON1,176,170,57,14
+ LTEXT "Cycle through ",IDC_STATIC,0,204,46,8
+ LTEXT "point",IDC_STATIC,0,131,16,8
+ LTEXT "frame",IDC_STATIC,1,41,18,8
+ LTEXT "colors (max 16)",IDC_STATIC,71,204,48,8
+ LTEXT "Source data: ",IDC_STATIC,0,168,44,8
+ LTEXT "init",IDC_STATIC,0,9,10,8
+ CONTROL "Dots",IDC_DOT,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,166,188,31,10
+ CONTROL "Lines",IDC_LINES,"Button",BS_AUTORADIOBUTTON,200,188,33,
+ 10
+ LTEXT "Draw as:",IDC_STATIC,132,188,29,8
+ PUSHBUTTON "expression help",IDC_BUTTON2,107,170,67,14,BS_MULTILINE
+ LTEXT "beat",IDC_STATIC,0,87,15,8
+END
+
+IDD_CFG_INVERT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Invert colors",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,79,10
+END
+
+IDD_CFG_ONETONE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Unique tone",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,79,10
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,0,15,
+ 137,13
+ CONTROL "Invert",IDC_INVERT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,30,34,10
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,41,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,51,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,61,
+ 55,10
+END
+
+IDD_CFG_TIMESCOPE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Timescope",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,75,10
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,0,15,
+ 137,13
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,30,43,10
+ CONTROL "Additive blend",IDC_ADDITIVE,"Button",
+ BS_AUTORADIOBUTTON,0,40,61,10
+ CONTROL "Blend 50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,0,50,
+ 55,10
+ CONTROL "Default render blend",IDC_DEFAULTBLEND,"Button",
+ BS_AUTORADIOBUTTON,0,59,80,10
+ CONTROL "Slider1",IDC_BANDS,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,95,137,11
+ LTEXT "Draw 16 bands",IDC_BANDTXT,0,84,137,8
+ CONTROL "Left channel",IDC_LEFT,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,0,108,55,10
+ CONTROL "Right channel",IDC_RIGHT,"Button",BS_AUTORADIOBUTTON,0,
+ 118,60,10
+ CONTROL "Center channel",IDC_CENTER,"Button",BS_AUTORADIOBUTTON,
+ 0,128,64,10
+END
+
+IDD_CFG_INTERF DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable Interferences",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,81,10
+ CONTROL "Slider1",IDC_NPOINTS,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,13,67,11
+ CONTROL "Slider1",IDC_ALPHA,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,70,12,67,11
+ CONTROL "Slider1",IDC_ROTATE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,33,67,11
+ CONTROL "Slider1",IDC_DISTANCE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,70,33,67,11
+ CONTROL "Separate RGB",IDC_RGB,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,2,51,62,10
+ LTEXT "Init Rotation",IDC_STATIC,85,62,40,8
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,4,78,63,11
+ CONTROL "Slider1",IDC_ALPHA2,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,70,78,63,11
+ CONTROL "Slider1",IDC_ROTATE2,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,4,99,63,11
+ CONTROL "Slider1",IDC_DISTANCE2,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,70,99,63,11
+ CONTROL "Replace",IDC_REPLACE,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,2,123,43,10
+ CONTROL "Additive",IDC_ADDITIVE,"Button",BS_AUTORADIOBUTTON,51,
+ 123,41,10
+ CONTROL "50/50",IDC_5050,"Button",BS_AUTORADIOBUTTON,100,123,35,
+ 10
+ LTEXT "0",IDC_STATIC,4,23,8,8
+ LTEXT "8",IDC_STATIC,55,23,8,8
+ CONTROL "OnBeat",IDC_ONBEAT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,2,60,40,10
+ LTEXT "N",IDC_STATIC,29,23,8,8
+ LTEXT "Alpha",IDC_STATIC,96,22,18,8
+ LTEXT "-",IDC_STATIC,76,23,8,8
+ LTEXT "+",IDC_STATIC,129,23,8,8
+ LTEXT "Rotation",IDC_STATIC,19,43,27,8
+ LTEXT "-",IDC_STATIC,5,43,8,8
+ LTEXT "+",IDC_STATIC,58,43,8,8
+ LTEXT "Distance",IDC_STATIC,91,43,28,8
+ LTEXT "-",IDC_STATIC,76,43,8,8
+ LTEXT "+",IDC_STATIC,129,43,8,8
+ LTEXT "-",IDC_STATIC,8,88,8,8
+ LTEXT "+",IDC_STATIC,59,88,8,8
+ LTEXT "Speed",IDC_STATIC,24,88,21,8
+ LTEXT "Alpha",IDC_STATIC,94,88,18,8
+ LTEXT "-",IDC_STATIC,76,88,8,8
+ LTEXT "+",IDC_STATIC,125,88,8,8
+ LTEXT "Rotation",IDC_STATIC,21,109,27,8
+ LTEXT "-",IDC_STATIC,5,109,8,8
+ LTEXT "+",IDC_STATIC,58,109,8,8
+ LTEXT "Distance",IDC_STATIC,89,109,28,8
+ LTEXT "-",IDC_STATIC,76,109,8,8
+ LTEXT "+",IDC_STATIC,125,109,8,8
+ GROUPBOX "OnBeat",IDC_STATIC,0,70,137,51
+ CONTROL "Slider1",IDC_INITROT,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,70,52,67,11
+ LTEXT "-",IDC_STATIC,76,62,8,8
+ LTEXT "+",IDC_STATIC,129,62,8,8
+END
+
+IDD_CFG_LIST DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enabled",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,2,56,10
+ CONTROL "Clear every frame",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,13,71,10
+ COMBOBOX IDC_COMBO2,5,37,101,184,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Slider2",IDC_INSLIDE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | NOT WS_VISIBLE | WS_TABSTOP,1,51,106,11
+ COMBOBOX IDC_COMBO1,121,37,101,168,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Slider2",IDC_OUTSLIDE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,117,51,106,11
+ GROUPBOX "Output blending",IDC_FR2,115,27,111,39
+ GROUPBOX "Input blending",IDC_FR1,0,27,111,39
+ COMBOBOX IDC_CBBUF2,121,50,62,64,CBS_DROPDOWNLIST | CBS_SORT |
+ NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Invert",IDC_INVERT2,"Button",BS_AUTOCHECKBOX | NOT
+ WS_VISIBLE | WS_TABSTOP,187,52,34,10
+ COMBOBOX IDC_CBBUF1,5,50,62,67,CBS_DROPDOWNLIST | CBS_SORT | NOT
+ WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Invert",IDC_INVERT1,"Button",BS_AUTOCHECKBOX | NOT
+ WS_VISIBLE | WS_TABSTOP,72,51,34,10
+ CONTROL "Enabled OnBeat for",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,89,3,78,9
+ EDITTEXT IDC_EDIT1,167,1,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "frames",IDC_STATIC,190,3,22,8
+ CONTROL "Use evaluation override (can change enabled, clear, etc):",
+ IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,78,
+ 197,10
+ EDITTEXT IDC_EDIT4,25,93,208,26,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT5,25,119,208,71,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ LTEXT "frame",IDC_STATIC,0,148,18,8
+ LTEXT "init",IDC_STATIC,0,102,10,8
+ PUSHBUTTON "expression help",IDC_BUTTON2,25,193,67,14,BS_MULTILINE
+END
+
+IDD_CFG_LISTROOT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Clear every frame",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,0,71,10
+END
+
+IDD_CFG_LINEMODE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable mode change",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,2,83,10
+ COMBOBOX IDC_COMBO1,5,25,128,184,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Slider2",IDC_ALPHASLIDE,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,1,39,132,11
+ EDITTEXT IDC_EDIT1,58,53,20,12,ES_AUTOHSCROLL | ES_NUMBER
+ GROUPBOX "Set blend mode to",IDC_STATIC,0,15,136,37
+ LTEXT "Line width (pixels)",IDC_STATIC,0,55,56,8
+END
+
+IDD_GCFG_TRANSITIONS DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Enable pre-init on random",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,0,96,10
+ CONTROL "Enable pre-init on next/prev",IDC_CHECK11,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,10,103,10
+ CONTROL "Enable pre-init on load preset",IDC_CHECK10,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,20,107,10
+ CONTROL "Low priority pre-init",IDC_CHECK4,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,31,74,10
+ CONTROL "Enable transition on random",IDC_CHECK8,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,79,137,10
+ CONTROL "Enable transition on next/prev",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,89,137,10
+ CONTROL "Enable transition on load preset",IDC_CHECK2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,99,126,10
+ CONTROL "Keep rendering old effect",IDC_CHECK9,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,111,126,10
+ COMBOBOX IDC_TRANSITION,0,133,137,392,CBS_DROPDOWNLIST |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_BOTH |
+ TBS_NOTICKS | WS_TABSTOP,0,149,137,11
+ LTEXT "Transition :",IDC_STATIC,0,123,36,8
+ LTEXT "Speed",IDC_STATIC,57,160,22,8
+ LTEXT "250ms",IDC_STATIC,4,160,30,8
+ LTEXT "8s",IDC_STATIC,125,160,9,8
+ CONTROL "Only pre-init when in fullscreen",IDC_CHECK5,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,41,111,10
+END
+
+#if defined(APSTUDIO_INVOKED) || defined(LASER)
+#if defined(APSTUDIO_INVOKED)
+IDD_CFG_LASER_CONE$(LASER) DIALOGEX 0, 0, 137, 155
+#else
+IDD_CFG_LASER_CONE DIALOGEX 0, 0, 137, 155
+#endif
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,11,8,125,11
+ CONTROL "Slider1",IDC_SLIDER7,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,11,19,125,11
+ CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,44,130,16
+ CONTROL "Slider1",IDC_SLIDER4,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,73,130,16
+ EDITTEXT IDC_EDIT1,78,98,24,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "Dots",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
+ WS_TABSTOP,9,110,31,10
+ CONTROL "Lines",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,41,110,33,
+ 10
+ EDITTEXT IDC_NUMCOL,53,125,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,6,140,
+ 127,11
+ GROUPBOX "Distance from center",IDC_STATIC,0,0,137,36
+ GROUPBOX "Cone size",IDC_STATIC,0,37,137,30
+ GROUPBOX "Cone size on beat",IDC_STATIC,0,62,137,35
+ LTEXT "Number of segments:",IDC_STATIC,7,100,68,8
+ GROUPBOX "Colors",IDC_STATIC,0,119,137,36
+ LTEXT "Cycle through ",IDC_STATIC,7,127,46,8
+ LTEXT "colors (max 16)",IDC_STATIC,77,127,48,8
+ RTEXT "x",IDC_STATIC,3,12,8,8
+ RTEXT "y",IDC_STATIC,3,22,8,8
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(LASER)
+#if defined(APSTUDIO_INVOKED)
+IDD_CFG_LASER_BEATHOLD$(LASER) DIALOGEX 0, 0, 245, 214
+#else
+IDD_CFG_LASER_BEATHOLD DIALOGEX 0, 0, 245, 214
+#endif
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Hold for (ms)",-1,0,0,137,32
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,8,130,16
+ GROUPBOX "Hold on the nth beat",-1,0,39,137,30
+ CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,46,130,16
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(LASER)
+#if defined(APSTUDIO_INVOKED)
+IDD_CFG_LASER_LINE$(LASER) DIALOGEX 0, 0, 137, 137
+#else
+IDD_CFG_LASER_LINE DIALOGEX 0, 0, 137, 137
+#endif
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,8,130,16
+ CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,34,130,16
+ CONTROL "Slider1",IDC_SLIDER4,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,5,63,130,16
+ EDITTEXT IDC_EDIT1,103,87,26,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_NUMCOL,53,107,19,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEFCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,6,122,
+ 127,11
+ GROUPBOX "Colors",IDC_STATIC,0,101,137,36
+ LTEXT "Cycle through ",IDC_STATIC,7,109,46,8
+ LTEXT "colors (max 16)",IDC_STATIC,77,109,48,8
+ GROUPBOX "Distance from center",IDC_STATIC,0,0,137,32
+ GROUPBOX "Line size",IDC_STATIC,0,27,137,30
+ GROUPBOX "Line size on beat",IDC_STATIC,0,52,137,35
+ LTEXT "Beat count for rotation switch: ",IDC_STATIC,3,89,97,8
+END
+#endif
+
+IDD_GCFG_FS DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Use fullscreen overlay mode (current bpp is used)",
+ IDC_USE_OVERLAY,"Button",BS_AUTOCHECKBOX | BS_MULTILINE |
+ WS_TABSTOP,0,0,214,10
+ COMBOBOX IDC_COMBO1,2,42,199,180,CBS_DROPDOWNLIST | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "go",IDC_BUTTON1,2,57,23,13
+ EDITTEXT IDC_EDIT1,134,72,20,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "Keep fullscreen when deactivated (overlay mode only)",
+ IDC_CHECK8,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,155,
+ 186,10
+ CONTROL "Pixel doubling",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,84,59,10
+ CONTROL "Wait for retrace",IDC_CHECK7,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,94,65,10
+ CONTROL "Page flipping (slower, smoother)",IDC_CHECK4,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,104,115,10
+ CONTROL "Fast software bpp conversion",IDC_BPP_CONV,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,114,105,10
+ CONTROL "Display framerate counter",IDC_CHECK2,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,125,96,10
+ CONTROL "Suppress status text in fullscreen",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,135,119,10
+ CONTROL "Suppress title text in fullscreen",IDC_CHECK5,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,145,111,10
+ LTEXT "Rendering performance:",IDC_STATIC,0,168,77,8
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_TOP | WS_TABSTOP,0,177,137,14
+ CONTROL "Doubleclick in main window goes fullscreen (instead of config )",
+ IDC_CHECK6,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0,204,
+ 213,10
+ LTEXT "Vertical screen height to render (percent): ",
+ IDC_STATIC,0,73,133,8
+ LTEXT "Higher framerate",IDC_STATIC,0,193,54,9
+ LTEXT "Lower framerate",IDC_STATIC,84,194,53,8
+ LTEXT "Fullscreen video mode:",IDC_STATIC,0,33,74,8
+ LTEXT "Note: fullscreen overlay mode is experimental, and most fullscreen options don't work with it. Expect more soon.",
+ IDC_STATIC,0,10,234,18
+END
+
+IDD_CFG_SHIFT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT1,29,0,204,52,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT2,29,52,204,70,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT3,29,123,204,63,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ LTEXT "frame",IDC_STATIC,0,83,18,8
+ LTEXT "beat",IDC_STATIC,0,150,15,8
+ LTEXT "init",IDC_STATIC,0,20,10,8
+ CONTROL "Blend",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 0,194,34,10
+ CONTROL "Bilinear filtering",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,35,194,63,10
+ PUSHBUTTON "expression help",IDC_HELPBTN,162,196,71,12
+END
+
+#if defined(APSTUDIO_INVOKED) || defined(LASER)
+#if defined(APSTUDIO_INVOKED)
+IDD_CFG_LASER_TRANSFORM$(LASER) DIALOGEX 0, 0, 245, 214
+#else
+IDD_CFG_LASER_TRANSFORM DIALOGEX 0, 0, 245, 214
+#endif
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT1,0,161,233,41,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN
+ CONTROL "Rectangular coordinates",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,204,93,10
+ LTEXT "Point:",IDC_STATIC,0,151,19,8
+ EDITTEXT IDC_EDIT2,0,10,233,41,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN
+ LTEXT "Init:",IDC_STATIC,0,0,12,8
+ EDITTEXT IDC_EDIT3,0,65,233,41,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN
+ LTEXT "Frame:",IDC_STATIC,0,52,22,8
+ EDITTEXT IDC_EDIT4,0,119,233,28,ES_MULTILINE | ES_AUTOHSCROLL |
+ ES_WANTRETURN
+ LTEXT "Beat:",IDC_STATIC,0,108,18,8
+END
+#endif
+
+IDD_CFG_DMOVE DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT4,25,0,208,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT2,25,14,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT3,25,67,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT1,25,120,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT5,108,190,18,12,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_EDIT6,136,190,18,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "Rectangular coordinates",IDC_CHECK3,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,0,204,90,10
+ CONTROL "Bilinear filtering",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,94,204,63,10
+ PUSHBUTTON "expression help",IDC_BUTTON1,158,200,73,13,BS_MULTILINE
+ LTEXT "pixel",IDC_STATIC,0,142,15,8
+ LTEXT "frame",IDC_STATIC,0,36,18,8
+ LTEXT "beat",IDC_STATIC,0,89,15,8
+ LTEXT "init",IDC_STATIC,0,3,10,8
+ LTEXT "Grid size:",IDC_STATIC,78,192,30,8
+ LTEXT "x",IDC_STATIC,128,191,8,8
+ CONTROL "Blend",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 0,190,34,10
+ CONTROL "Wrap",IDC_WRAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,
+ 190,33,10
+ COMBOBOX IDC_COMBO1,25,175,85,56,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ LTEXT "source",IDC_STATIC,0,177,22,8
+ CONTROL "No movement (just blend)",IDC_NOMOVEMENT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,113,176,100,10
+ PUSHBUTTON "Load example...",IDC_BUTTON4,158,186,73,13,BS_MULTILINE
+END
+
+IDD_CFG_FASTBRIGHT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Brighten by 2x",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP | WS_TABSTOP,2,1,61,10
+ CONTROL "Darken by 0.5x",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,
+ 2,12,64,10
+ CONTROL "Do nothing",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,2,23,
+ 51,10
+END
+
+IDD_CFG_COLORMOD DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_EDIT4,25,0,208,29,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT2,25,29,208,44,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT3,25,73,208,53,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ EDITTEXT IDC_EDIT1,25,126,208,69,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
+ PUSHBUTTON "expression help",IDC_BUTTON1,164,200,69,14,BS_MULTILINE
+ LTEXT "level",IDC_STATIC,0,156,16,8
+ LTEXT "frame",IDC_STATIC,0,45,18,8
+ LTEXT "beat",IDC_STATIC,0,93,15,8
+ LTEXT "init",IDC_STATIC,0,9,10,8
+ PUSHBUTTON "Load example...",IDC_BUTTON4,97,200,63,14
+ CONTROL "Recompute every frame",IDC_CHECK1,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,2,199,91,10
+END
+
+IDD_EVAL_HELP DIALOGEX 0, 0, 311, 228
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "AVS Expression Help"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,7,210,50,14
+ EDITTEXT IDC_EDIT1,12,25,286,177,ES_MULTILINE | ES_READONLY |
+ WS_VSCROLL
+ CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,7,7,297,200
+END
+
+IDD_DEBUG DIALOGEX 0, 0, 360, 185
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "AVS Debug Information"
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDOK,7,162,50,14
+ GROUPBOX "Global register (reg00-99) watch",IDC_STATIC,7,7,111,
+ 130
+ LTEXT "Register",IDC_STATIC,13,19,27,8
+ LTEXT "Value",IDC_STATIC,47,19,19,8
+ EDITTEXT IDC_DEBUGREG_1,13,29,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_2,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN |
+ WS_GROUP,45,29,68,12
+ EDITTEXT IDC_DEBUGREG_3,13,42,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_4,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN |
+ WS_GROUP,45,42,68,12
+ EDITTEXT IDC_DEBUGREG_5,13,55,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_6,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN |
+ WS_GROUP,45,55,68,12
+ EDITTEXT IDC_DEBUGREG_7,13,68,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_8,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN |
+ WS_GROUP,45,68,68,12
+ EDITTEXT IDC_DEBUGREG_9,13,81,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_10,"Static",SS_LEFTNOWORDWRAP |
+ SS_SUNKEN | WS_GROUP,45,81,68,12
+ EDITTEXT IDC_DEBUGREG_11,13,94,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_12,"Static",SS_LEFTNOWORDWRAP |
+ SS_SUNKEN | WS_GROUP,45,94,68,12
+ EDITTEXT IDC_DEBUGREG_13,13,108,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_14,"Static",SS_LEFTNOWORDWRAP |
+ SS_SUNKEN | WS_GROUP,45,108,68,12
+ EDITTEXT IDC_DEBUGREG_15,13,121,27,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_DEBUGREG_16,"Static",SS_LEFTNOWORDWRAP |
+ SS_SUNKEN | WS_GROUP,45,121,68,12
+ GROUPBOX "Recent eval code errors:",IDC_STATIC,123,7,230,129
+ EDITTEXT IDC_EDIT1,133,19,211,98,ES_MULTILINE | ES_AUTOVSCROLL |
+ ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL
+ PUSHBUTTON "clear",IDC_BUTTON1,133,119,31,14
+ CONTROL "Log compile errors (use only when developing)",
+ IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,120,
+ 161,10
+ CONTROL "Clear all local variables on all code recompiles (disabling can be useful for development)",
+ IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,151,
+ 291,9
+ CONTROL "Disable SEH for effects (for APE developers who want to debug their APEs)",
+ IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,166,
+ 253,10
+ EDITTEXT IDC_EDIT2,7,137,346,12,ES_AUTOHSCROLL | ES_READONLY
+END
+
+IDD_CFG_CHANSHIFT DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Order",-1,5,5,85,135
+ CONTROL "GBR",IDC_GBR,"Button",BS_AUTORADIOBUTTON,15,81,35,10
+ CONTROL "BRG",IDC_BRG,"Button",BS_AUTORADIOBUTTON,15,50,35,10
+ CONTROL "RBG",IDC_RBG,"Button",BS_AUTORADIOBUTTON,15,36,35,10
+ CONTROL "BGR",IDC_BGR,"Button",BS_AUTORADIOBUTTON,15,65,35,10
+ CONTROL "GRB",IDC_GRB,"Button",BS_AUTORADIOBUTTON,15,95,35,10
+ CONTROL "RGB",1023,"Button",BS_AUTORADIOBUTTON,15,20,31,10
+ CONTROL "OnBeat Random",IDC_ONBEAT,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,15,120,65,10
+END
+
+IDD_CFG_COLORREDUCTION DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Color levels",-1,5,5,220,35
+ CONTROL "Slider1",IDC_LEVELS,"msctls_trackbar32",TBS_AUTOTICKS |
+ WS_TABSTOP,10,15,185,20
+ LTEXT "Static",IDC_LEVELTEXT,200,17,20,10
+END
+
+IDD_CFG_MULT DIALOGEX 0, 0, 231, 216
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Multiplier",-1,5,5,70,117
+ CONTROL "Color x 8",IDC_X8,"Button",BS_AUTORADIOBUTTON,10,29,60,
+ 10
+ CONTROL "Color x 4",IDC_X4,"Button",BS_AUTORADIOBUTTON,10,42,60,
+ 10
+ CONTROL "Color x 2",IDC_X2,"Button",BS_AUTORADIOBUTTON,10,55,60,
+ 10
+ CONTROL "Color x 0.5",IDC_X05,"Button",BS_AUTORADIOBUTTON,10,68,
+ 60,10
+ CONTROL "Color x 0.25",IDC_X025,"Button",BS_AUTORADIOBUTTON,10,
+ 81,60,10
+ CONTROL "Color x 0.125",IDC_X0125,"Button",BS_AUTORADIOBUTTON,10,
+ 94,60,10
+ CONTROL "Infinite root",IDC_XI,"Button",BS_AUTORADIOBUTTON,10,16,
+ 60,10
+ CONTROL "Infinite square",IDC_XS,"Button",BS_AUTORADIOBUTTON,10,
+ 107,60,10
+END
+
+IDD_CFG_MULTIDELAY DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Beats",1020,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,
+ 102,42,12
+ CONTROL "Frames",1030,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,
+ 114,42,12
+ EDITTEXT 1010,12,90,42,12,ES_AUTOHSCROLL
+ GROUPBOX "Buffer A",IDC_STATIC,6,78,54,54
+ CONTROL "Beats",1021,"Button",BS_AUTORADIOBUTTON | WS_GROUP,72,
+ 102,42,12
+ CONTROL "Frames",1031,"Button",BS_AUTORADIOBUTTON | WS_GROUP,72,
+ 114,42,12
+ EDITTEXT 1011,72,90,42,12,ES_AUTOHSCROLL
+ GROUPBOX "Buffer B",IDC_STATIC,66,78,54,54
+ CONTROL "Beats",1022,"Button",BS_AUTORADIOBUTTON | WS_GROUP,132,
+ 102,42,12
+ CONTROL "Frames",1032,"Button",BS_AUTORADIOBUTTON | WS_GROUP,132,
+ 114,42,12
+ EDITTEXT 1012,132,90,42,12,ES_AUTOHSCROLL
+ GROUPBOX "Buffer C",IDC_STATIC,126,78,54,54
+ CONTROL "Beats",1023,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,
+ 156,42,12
+ CONTROL "Frames",1033,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,
+ 168,42,12
+ EDITTEXT 1013,12,144,42,12,ES_AUTOHSCROLL
+ GROUPBOX "Buffer D",IDC_STATIC,6,132,54,54
+ CONTROL "Beats",1024,"Button",BS_AUTORADIOBUTTON | WS_GROUP,72,
+ 156,42,12
+ CONTROL "Frames",1034,"Button",BS_AUTORADIOBUTTON | WS_GROUP,72,
+ 168,42,12
+ EDITTEXT 1014,72,144,42,12,ES_AUTOHSCROLL
+ GROUPBOX "Buffer E",IDC_STATIC,66,132,54,54
+ CONTROL "Beats",1025,"Button",BS_AUTORADIOBUTTON | WS_GROUP,132,
+ 156,42,12
+ CONTROL "Frames",1035,"Button",BS_AUTORADIOBUTTON | WS_GROUP,132,
+ 168,42,12
+ EDITTEXT 1015,132,144,42,12,ES_AUTOHSCROLL
+ GROUPBOX "Buffer F",IDC_STATIC,126,132,54,54
+ CONTROL "Input",1101,"Button",BS_AUTORADIOBUTTON | WS_GROUP,72,
+ 18,30,12
+ CONTROL "Output",1102,"Button",BS_AUTORADIOBUTTON | WS_GROUP,132,
+ 18,36,12
+ CONTROL "Buffer A",1000,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 12,48,48,12
+ CONTROL "Buffer B",1001,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 72,48,48,12
+ CONTROL "Buffer C",1002,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 132,48,42,12
+ CONTROL "Buffer D",1003,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 12,60,48,12
+ CONTROL "Buffer E",1004,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 72,60,48,12
+ CONTROL "Buffer F",1005,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 132,60,42,12
+ GROUPBOX "Active Buffer",IDC_STATIC,6,36,174,42
+ GROUPBOX "Mode",IDC_STATIC,6,6,174,30
+ CONTROL "Disabled",1100,"Button",BS_AUTORADIOBUTTON | WS_GROUP,
+ 12,18,48,12
+ CTEXT "(c) Tom Holden, 2002",IDC_STATIC,6,192,174,12
+END
+
+IDD_CFG_VIDEODELAY DIALOGEX 0, 0, 245, 214
+STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+ CONTROL "Beats",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,54,18,36,
+ 12
+ CONTROL "Frames",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,90,18,36,
+ 12
+ CONTROL "Enabled",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,6,7,42,8
+ EDITTEXT IDC_EDIT1,6,18,43,12,ES_AUTOHSCROLL
+ CTEXT "(c) Tom Holden, 2002",IDC_STATIC,6,36,120,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ LEFTMARGIN, 2
+ RIGHTMARGIN, 376
+ BOTTOMMARGIN, 177
+ END
+
+ IDD_CFG_BLUR, DIALOG
+ BEGIN
+ TOPMARGIN, 1
+ END
+
+ IDD_CFG_COLORFADE, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 137
+ END
+
+ IDD_GCFG_PRESET, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 214
+ END
+
+ IDD_DIALOG2, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 198
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 143
+ END
+
+ IDD_CFG_AVI, DIALOG
+ BEGIN
+ RIGHTMARGIN, 137
+ BOTTOMMARGIN, 157
+ END
+
+ IDD_GCFG_BPM, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_GCFG_TRANSITIONS, DIALOG
+ BEGIN
+ RIGHTMARGIN, 137
+ BOTTOMMARGIN, 176
+ END
+
+ "IDD_CFG_LASER_CONE$(LASER)", DIALOG
+ BEGIN
+ BOTTOMMARGIN, 137
+ END
+
+ IDD_GCFG_FS, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 214
+ END
+
+ IDD_EVAL_HELP, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 304
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 224
+ END
+
+ IDD_DEBUG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 353
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 176
+ END
+
+ IDD_CFG_CHANSHIFT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 224
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 209
+ END
+
+ IDD_CFG_COLORREDUCTION, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 224
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 209
+ END
+
+ IDD_CFG_MULT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 224
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 209
+ END
+
+ IDD_CFG_MULTIDELAY, DIALOG
+ BEGIN
+ RIGHTMARGIN, 180
+ BOTTOMMARGIN, 203
+ END
+
+ IDD_CFG_VIDEODELAY, DIALOG
+ BEGIN
+ RIGHTMARGIN, 216
+ BOTTOMMARGIN, 191
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENUEX
+BEGIN
+ POPUP "&Preset", 65535,MFT_STRING,MFS_ENABLED
+ BEGIN
+ MENUITEM "Load...", 1028,MFT_STRING,MFS_ENABLED
+ MENUITEM "&Save...", 1035,MFT_STRING,MFS_ENABLED
+ MENUITEM MFT_SEPARATOR
+ MENUITEM "&New", 1041,MFT_STRING,MFS_ENABLED
+ END
+ POPUP "&Edit", 65535,MFT_STRING,MFS_ENABLED
+ BEGIN
+ MENUITEM "&Undo", 40009,MFT_STRING,MFS_ENABLED
+ MENUITEM "&Redo", 40010,MFT_STRING,MFS_ENABLED
+ END
+ POPUP "&Settings", 65535,MFT_STRING,MFS_ENABLED
+ BEGIN
+ MENUITEM "&Display", 40001,MFT_STRING,MFS_ENABLED
+ MENUITEM "&Fullscreen", 40007,MFT_STRING,MFS_ENABLED
+ MENUITEM "&Presets/Hotkeys", 40002,MFT_STRING,MFS_ENABLED
+ MENUITEM "&Beat Detection", 40005,MFT_STRING,MFS_ENABLED
+ MENUITEM "Transitio&ns", 40006,MFT_STRING,MFS_ENABLED
+ MENUITEM MFT_SEPARATOR
+ MENUITEM "Debug Window...", 40008,MFT_STRING,MFS_ENABLED
+ END
+ POPUP "&Help", 65535,MFT_STRING | MFT_RIGHTJUSTIFY,MFS_ENABLED
+ BEGIN
+ MENUITEM "&About...", 40004,MFT_STRING,MFS_ENABLED
+ END
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXT
+//
+
+IDR_BUMP_LIGHT_POSITION TEXT "bump_lig.bin"
+IDR_COLOR_MODIFIER TEXT "color_mo.bin"
+IDR_DYNAMIC_DISTANCE_MODIFIER TEXT "dyn_dist.bin"
+IDR_DYNAMIC_MOVEMENT TEXT "dyn_move.bin"
+IDR_DYNAMIC_SHIFT TEXT "dyn_shift.bin"
+IDR_SUPERSCOPE TEXT "supersco.bin"
+IDR_MOVEMENT TEXT "movement.bin"
+IDR_EFFECT_LIST TEXT "effect_l.bin"
+IDR_HELP_1 TEXT "help_1.bin"
+IDR_HELP_2 TEXT "help_2.bin"
+IDR_HELP_3 TEXT "help_3.bin"
+IDR_HELP_4 TEXT "help_4.bin"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+
+ IDS_AVS "Advanced Visualization Studio"
+ IDS_AVS_EDITOR "AVS Editor"
+ IDS_DOCK_IN_AVS_EDITOR "Dock in AVS Editor"
+ IDS_LEARNING "Learning..."
+ IDS_GOT_IT " Got it!"
+ IDS_NO_EFFECT_SETTING_SELECTED "No Effect/Setting Selected"
+ IDS_SHIFT_X "Shift+%d"
+ IDS_ALL "All"
+ IDS_SAME_AS_WINAMP "Same as Winamp"
+ IDS_IDLE "Idle"
+ IDS_LOWEST "Lowest"
+ IDS_NORMAL "Normal"
+ IDS_HIGHEST "Highest"
+ IDS_NO_SUITABLE_MODES_FOUND "No suitable modes found"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CHOOSE_A_VIDEO_MODE "Choose a video mode"
+ IDS_FULLSCREEN "Fullscreen"
+ IDS_AVS_FILTER_STRING "AVS presets|*.avs|All files|*.*|"
+ IDS_SAVE_PRESET "Save Preset"
+ IDS_ERROR_SAVING_PRESET "Error saving preset"
+ IDS_PRESET_TOO_LARGE "Preset too large"
+ IDS_OUT_OF_MEMORY "Out of memory"
+ IDS_EVAL_CODE_STATS_ETC "Eval code stats: %d segments, %d bytes source, %d+%d bytes code, %d bytes data"
+ IDS_MOVE_HERE "<move here>"
+ IDS_ERROR_TREE_INCONSISTANCY
+ "Error: Inconsistency in tree. this should never happen. ACK!"
+ IDS_CRITICAL_ERROR_OCCURRED "Critical Error Occurred"
+ IDS_DISPLAY "Display"
+ IDS_FULLSCREEN_SETTINGS "Fullscreen Settings"
+ IDS_PRESET_HOTKEYS "Presets / Hotkeys"
+ IDS_BEAT_DETECTION "Beat Detection"
+ IDS_TRANSITIONS "Transitions"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_EFFECT_LIST "Effect List"
+ IDS_PRESETS "Presets"
+ IDS_LOAD_PRESET "Load Preset"
+ IDS_STILL_INITIALIZING_PREVIOUS_PRESET
+ "Still initializing previous preset"
+ IDS_MAIN "Main"
+ IDS_ERROR_CREATING_DDRAW_OBJECT "Error creating ddraw object"
+ IDS_ABOUT_STRING "\t%s\n\tCopyright (C) 1998-2023 Winamp SA\nPortions Copyright (C) 2010 Cockos Incorporated\r\r\nThis software is BSD-licensed open source.\n\nYou are welcome to use\nAVS at parties, clubs, concerts and whatnot.\nJust give credit where credit is due.\n\nLove,\n Justin Frankel, Francis Gastellu, Christophe Thibault,\n Brennan Underwood & mig\n\nSpecial thanks to Steven Wittens and Tom Holden."
+ IDS_ABOUT_AVS "About AVS"
+ IDS_REQUIRES_2_9_PLUS "This version of AVS requires Winamp 2.9+"
+ IDS_AVS_ERROR "AVS Error"
+ IDS_NO_MMX_SUPPORT "No MMX support found - cannot run AVS!\nGet the non-MMX version."
+ IDS_SHIFT_ "shift-"
+ IDS_AVS_CRITICAL_ERROR "AVS Critical Error"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_LOAD
+ "Current preset may have been edited. Save preset before loading?"
+ IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_NEW
+ "Current preset may have been edited. Save preset before creating new?"
+ IDS_AVS_PRESET_MODIFIED "AVS Preset Modified"
+ IDS_ERROR_CREATING_WINDOW "Error creating window"
+ IDS_CANNOT_GO_FULLSCREEN_WHEN_VIDEO_PLAYING
+ "Cannot go fullscreen when video is playing"
+ IDS_AVS_FULLSCREEN "AVS Fullscreen"
+ IDS_FULLSCREEN_FPS_ON "fullscreen fps on"
+ IDS_FULLSCREEN_FPS_OFF "fullscreen fps off"
+ IDS_RANDOM_PRESETS_ON "random presets on"
+ IDS_RANDOM_PRESETS_OFF "random presets off"
+ IDS_SAVED_TO "saved to"
+ IDS_LOADED_FROM "loaded from"
+ IDS_ERROR_LOADING_FROM "error loading from"
+ IDS_BEAT "beat"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CURRENT "Current"
+ IDS_BUFFER_X "Buffer %d"
+ IDS_BUMP_LIGHT_POSITION "Bump Light Position"
+ IDS_4X_RED_BRIGHTNESS_2X_GREEN_1X_BLUE
+ "4x Red Brightness, 2x Green, 1x Blue"
+ IDS_SOLARIZATION "Solarization"
+ IDS_DOUBLE_SOLARIZATION "Double Solarization"
+ IDS_INVERSE_SOLARIZATION_SOFT "Inverse Solarization (Soft)"
+ IDS_BIG_BRIGHTNESS_ON_BEAT "Big Brightness on Beat"
+ IDS_BIG_BRIGHTNESS_ON_BEAT_INTERPOLATIVE
+ "Big Brightness on Beat (Interpolative)"
+ IDS_PULSING_BRIGHTNESS_BEAT_INTERPOLATIVE
+ "Pulsing Brightness (Beat Interpolative)"
+ IDS_ROLLING_SOLARIZATION_BEAT_INTERPOLATIVE
+ "Rolling Solarization (Beat Interpolative)"
+ IDS_ROLLING_TONE_BEAT_INTERPOLATIVE "Rolling Tone (Beat Interpolative)"
+ IDS_RANDOM_INVERSE_TONE_SWITCH_ON_BEAT
+ "Random Inverse Tone (Switch on Beat)"
+ IDS_COLOR_MODIFIER "Color Modifier"
+ IDS_DYNAMIC_DISTANCE_MODIFIER "Dynamic Distance Modifier"
+ IDS_RANDOM_ROTATE "Random Rotate"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_RANDOM_DIRECTION "Random Direction"
+ IDS_IN_AND_OUT "In and Out"
+ IDS_UNSPUN_KALEIDA "Unspun Kaleida"
+ IDS_ROLLING_GRIDLEY "Roiling Gridley"
+ IDS_6_WAY_OUTSWIRL "6-Way Outswirl"
+ IDS_WAVY "Wavy"
+ IDS_SMOOTH_ROTOBLITTER "Smooth Rotoblitter"
+ IDS_DYNAMIC_MOVEMENT "Dynamic Movement"
+ IDS_REPLACE "Replace"
+ IDS_ADDITIVE "Additive"
+ IDS_MAXIMUM_BLEND "Maximum Blend"
+ IDS_50_50_BLEND "50/50 Blend"
+ IDS_SUBTRACTIVE_BLEND_1 "Subtractive Blend 1"
+ IDS_SUBTRACTIVE_BLEND_2 "Subtractive Blend 2"
+ IDS_MULTIPLY_BLEND "Multiply Blend"
+ IDS_ADJUSTABLE_BLEND "Adjustable Blend"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_XOR "XOR"
+ IDS_MINIMUM_BLEND "Minimum Blend"
+ IDS_DYNAMIC_SHIFT "Dynamic Shift"
+ IDS_SPIRAL "Spiral"
+ IDS_3D_SCOPE_DISH "3D Scope Dish"
+ IDS_ROTATING_BOW_THING "Rotating Bow Thing"
+ IDS_VERTICAL_BOUNCING_SCOPE "Vertical Bouncing Scope"
+ IDS_SPIRAL_GRAPH_FUN "Spiral Graph Fun"
+ IDS_ALTERNATING_DIAGONAL_SCOPE "Alternating Diagonal Scope"
+ IDS_VIBRATING_WORM "Vibrating Worm"
+ IDS_WANDERING_SIMPLE "Wandering Simple"
+ IDS_FLITTERBUG "Flitterbug"
+ IDS_SPIROSTAR "Spirostar"
+ IDS_EXPLODING_DAISY "Exploding Daisy"
+ IDS_SWIRLIE_DOTS "Swirlie Dots"
+ IDS_SWEEP "Sweep"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_WHIPLASH_SPIRAL "Whiplash Spiral"
+ IDS_SUPERSCOPE "Superscope"
+ IDS_DRAW_X_BANDS "Draw %d bands"
+ IDS_NONE "none"
+ IDS_SLIGHT_FUZZIFY "slight fuzzify"
+ IDS_SHIFT_ROTATE_LEFT "shift rotate left"
+ IDS_BIG_SWIRL_OUT "big swirl out"
+ IDS_MEDIUM_SWIRL "medium swirl"
+ IDS_SUNBURSTER "sunburster"
+ IDS_SWIRL_TO_CENTER "swirl to center"
+ IDS_BLOCKY_PARTIAL_OUT "blocky partial out"
+ IDS_SWIRLING_AROUND_BOTH_WAYS "swirling around both ways at once"
+ IDS_BUBBLING_OUTWARD "bubbling outward"
+ IDS_BUBBLING_OUTWARD_WITH_SWIRL "bubbling outward with swirl"
+ IDS_5_POINTED_DISTRO "5 pointed distro"
+ IDS_TUNNELING "tunneling"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_BLEEDIN "bleedin'"
+ IDS_SHIFTED_BIG_SWIRL_OUT "shifted big swirl out"
+ IDS_PSYCHOTIC_BEAMING_OUTWARD "psychotic beaming outward"
+ IDS_COSINE_RADIAL_3_WAY "cosine radial 3-way"
+ IDS_SPINNY_TUBE "spinny tube"
+ IDS_RADIAL_SWIRLIES "radial swirlies"
+ IDS_SWILL "swill"
+ IDS_GRIDLEY "gridley"
+ IDS_GRAPEVINE "grapevine"
+ IDS_QUADRANT "quadrant"
+ IDS_6_WAY_KALAEIDA "6-way kaleida (use wrap!)"
+ IDS_USER_DEFINED "(user defined)"
+ IDS_MOVEMENT "Movement"
+ IDS_IGNORE "Ignore"
+ IDS_MAXIMUM "Maximum"
+ IDS_50_50 "50/50"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_EVERY_OTHER_LINE "Every other line"
+ IDS_EVERY_OTHER_PIXEL "Every other pixel"
+ IDS_ADJUSTABLE "Adjustable"
+ IDS_MULTIPLY "Multiply"
+ IDS_BUFFER "Buffer"
+ IDS_MINIMUM "Minimum"
+ IDS_CROSS_DISSOLVE "Cross dissolve"
+ IDS_RANDOM "Random"
+ IDS_L_R_PUSH "L/R Push"
+ IDS_R_L_PUSH "R/L Push"
+ IDS_T_B_PUSH "T/B Push"
+ IDS_B_T_PUSH "B/T Push"
+ IDS_9_RANDOM_BLOCKS "9 Random Blocks"
+ IDS_SPLIT_L_R_PUSH "Split L/R Push"
+ IDS_L_R_CENTER_PUSH "L/R to Center Push"
+ IDS_L_R_CENTER_SQUEEZE "L/R to Center Squeeze"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_L_R_WIPE "L/R Wipe"
+ IDS_R_L_WIPE "R/L Wipe"
+ IDS_T_B_WIPE "T/B Wipe"
+ IDS_B_T_WIPE "B/T Wipe"
+ IDS_DOT_DISSOLVE "Dot Dissolve"
+ IDS_LOADING_WAIT "loading [wait]..."
+ IDS_LOADING "loading..."
+ IDS_ERROR_LOADING_X "error loading: %s"
+ IDS_BUILTIN_ID "Built-in ID: %d\r\n"
+ IDS_CONFIG_SIZE "Config size: %d\r\n"
+ IDS_GENERAL "General"
+ IDS_OPERATORS "Operators"
+ IDS_FUNCTIONS "Functions"
+ IDS_CONSTANTS "Constants"
+ IDS_BEATS "beats"
+ IDS_SUBTRACTIVE_1 "Subtractive 1"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SUBTRACTIVE_2 "Subtractive 2"
+ IDS_RENDER_AVI "Render / AVI"
+ IDS_TRANS_BLITTER_FEEDBACK "Trans / Blitter Feedback"
+ IDS_TRANS_BLUR "Trans / Blur"
+ IDS_MISC_CUSTOM_BPM "Misc / Custom BPM"
+ IDS_TRANS_BRIGHTNESS "Trans / Brightness"
+ IDS_RENDER_BASS_SPIN "Render / Bass Spin"
+ IDS_TRANS_BUMP "Trans / Bump"
+ IDS_TRANS_CHANNEL_SHIFT "Trans / Channel Shift"
+ IDS_RENDER_CLEAR_SCREEN "Render / Clear Screen"
+ IDS_TRANS_COLORFADE "Trans / Colorfade"
+ IDS_TRANS_COLOR_REDUCTION "Trans / Color Reduction"
+ IDS_TRANS_COLOR_CLIP "Trans / Color Clip"
+ IDS_MISC_COMMENT "Misc / Comment"
+ IDS_TRANS_COLOR_MODIFIER "Trans / Color Modifier"
+ IDS_TRANS_DYNAMIC_DISTANCE_MODIFIER "Trans / Dynamic Distance Modifier"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_TRANS_DYNAMIC_MOVEMENT "Trans / Dynamic Movement"
+ IDS_RENDER_DOT_FOUNTAIN "Render / Dot Fountain"
+ IDS_RENDER_DOT_GRID "Render / Dot Grid"
+ IDS_RENDER_DOT_PLANE "Render / Dot Plane"
+ IDS_TRANS_FADEOUT "Trans / Fadeout"
+ IDS_TRANS_FAST_BRIGHTNESS "Trans / Fast Brightness"
+ IDS_TRANS_GRAIN "Trans / Grain"
+ IDS_TRANS_INTERFERENCES "Trans / Interferences"
+ IDS_TRANS_INTERLEAVE "Trans / Interleave"
+ IDS_TRANS_INVERT "Trans / Invert"
+ IDS_MISC_SET_RENDER_MODE "Misc / Set render mode"
+ IDS_TRANS_MIRROR "Trans / Mirror"
+ IDS_TRANS_MOSAIC "Trans / Mosaic"
+ IDS_TRANS_MULTI_DELAY "Trans / Multi Delay"
+ IDS_TRANS_MULTIPLIER "Trans / Multiplier"
+ IDS_RENDER_ONBEAT_CLEAR "Render / OnBeat Clear"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_TRANS_UNIQUE_TONE "Trans / Unique Tone"
+ IDS_RENDER_RING "Render / Ring"
+ IDS_RENDER_OSCILLOSCOPE_STAR "Render / Oscilliscope Star"
+ IDS_RENDER_MOVING_PARTICLE "Render / Moving Particle"
+ IDS_RENDER_PICTURE "Render / Picture"
+ IDS_TRANS_ROTO_BLITTER "Trans / Roto Blitter"
+ IDS_RENDER_ROTATING_STARS "Render / Rotating Stars"
+ IDS_TRANS_SCATTER "Trans / Scatter"
+ IDS_TRANS_DYNAMIC_SHIFT "Trans / Dynamic Shift"
+ IDS_RENDER_SIMPLE "Render / Simple"
+ IDS_RENDER_SUPERSCOPE "Render / SuperScope"
+ IDS_MISC_BUFFER_SAVE "Misc / Buffer Save"
+ IDS_RENDER_STARFIELD "Render / Starfield"
+ IDS_RENDER_SVP_LOADER "Render / SVP Loader"
+ IDS_RENDER_TEXT "Render / Text"
+ IDS_RENDER_TIMESCOPE "Render / Timescope"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_TRANS_MOVEMENT "Trans / Movement"
+ IDS_UNKNOWN_RENDER_OBJECT "Unknown Render Object"
+ IDS_TRANS_VIDEO_DELAY "Trans / Video Delay"
+ IDS_TRANS_WATER "Trans / Water"
+ IDS_TRANS_WATER_BUMP "Trans / Water Bump"
+ IDS_OVERLAY_MODE "Overlay Mode"
+END
+
+STRINGTABLE
+BEGIN
+ 65535 "{BE608673-B723-4a59-9EBA-52DC77109E10}"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Visualization/vis_avs/resource.h b/Src/Plugins/Visualization/vis_avs/resource.h
new file mode 100644
index 00000000..41944089
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/resource.h
@@ -0,0 +1,665 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by res.rc
+//
+#define IDS_AVS 0
+#define IDS_WINAMP_AVS_DISPLAY 1
+#define IDS_AVS_EDITOR 2
+#define IDS_DOCK_IN_AVS_EDITOR 3
+#define IDS_LEARNING 5
+#define IDS_GOT_IT 6
+#define IDS_NO_EFFECT_SETTING_SELECTED 7
+#define IDS_SHIFT_X 8
+#define IDS_ALL 9
+#define IDS_SAME_AS_WINAMP 10
+#define IDS_IDLE 11
+#define IDS_LOWEST 12
+#define IDS_NORMAL 13
+#define IDS_HIGHEST 14
+#define IDS_NO_SUITABLE_MODES_FOUND 15
+#define IDS_CHOOSE_A_VIDEO_MODE 16
+#define IDS_FULLSCREEN 17
+#define IDS_AVS_FILTER_STRING 18
+#define IDS_SAVE_PRESET 19
+#define IDS_ERROR_SAVING_PRESET 20
+#define IDS_PRESET_TOO_LARGE 21
+#define IDS_OUT_OF_MEMORY 22
+#define IDS_EVAL_CODE_STATS_ETC 23
+#define IDS_MOVE_HERE 24
+#define IDS_ERROR_TREE_INCONSISTANCY 25
+#define IDS_CRITICAL_ERROR_OCCURRED 26
+#define IDS_DISPLAY 27
+#define IDS_FULLSCREEN_SETTINGS 28
+#define IDS_PRESET_HOTKEYS 29
+#define IDS_BEAT_DETECTION 30
+#define IDS_TRANSITIONS 31
+#define IDS_EFFECT_LIST 32
+#define IDS_PRESETS 33
+#define IDS_LOAD_PRESET 34
+#define IDS_STILL_INITIALIZING_PREVIOUS_PRESET 35
+#define IDS_MAIN 36
+#define IDS_ERROR_CREATING_DDRAW_OBJECT 37
+#define IDS_ABOUT_STRING 38
+#define IDS_ABOUT_AVS 39
+#define IDS_REQUIRES_2_9_PLUS 40
+#define IDS_AVS_ERROR 41
+#define IDS_NO_MMX_SUPPORT 42
+#define IDS_STRING43 43
+#define IDS_SHIFT_ 43
+#define IDS_AVS_CRITICAL_ERROR 44
+#define IDS_CHANNEL_SHIFT 45
+#define IDS_COLOR_REDUCTION 46
+#define IDS_MULTIPLIER 47
+#define IDS_HOLDEN04_VIDEO_DELAY 48
+#define IDS_HOLDEN05_MULTI_DELAY 49
+#define IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_LOAD 50
+#define IDS_STRING51IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_NEW 51
+#define IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_NEW 51
+#define IDS_AVS_PRESET_MODIFIED 52
+#define IDS_ERROR_CREATING_WINDOW 53
+#define IDS_CANNOT_GO_FULLSCREEN_WHEN_VIDEO_PLAYING 54
+#define IDS_AVS_FULLSCREEN 55
+#define IDS_FULLSCREEN_FPS_ON 56
+#define IDS_FULLSCREEN_FPS_OFF 57
+#define IDS_RANDOM_PRESETS_ON 58
+#define IDS_RANDOM_PRESETS_OFF 59
+#define IDS_SAVED_TO 60
+#define IDS_LOADED_FROM 61
+#define IDS_ERROR_LOADING_FROM 62
+#define IDS_X_BEATX 63
+#define IDS_BEAT 63
+#define IDS_CURRENT 64
+#define IDS_BUFFER_X 65
+#define IDS_BUMP_LIGHT_POSITION 66
+#define IDS_4X_RED_BRIGHTNESS_2X_GREEN_1X_BLUE 67
+#define IDS_SOLARIZATION 68
+#define IDS_DOUBLE_SOLARIZATION 69
+#define IDS_INVERSE_SOLARIZATION_SOFT 70
+#define IDS_BIG_BRIGHTNESS_ON_BEAT 71
+#define IDS_BIG_BRIGHTNESS_ON_BEAT_INTERPOLATIVE 72
+#define IDS_PULSING_BRIGHTNESS_BEAT_INTERPOLATIVE 73
+#define IDS_ROLLING_SOLARIZATION_BEAT_INTERPOLATIVE 74
+#define IDS_ROLLING_TONE_BEAT_INTERPOLATIVE 75
+#define IDS_RANDOM_INVERSE_TONE_SWITCH_ON_BEAT 76
+#define IDS_COLOR_MODIFIER 77
+#define IDS_DYNAMIC_DISTANCE_MODIFIER 78
+#define IDS_RANDOM_ROTATE 79
+#define IDS_RANDOM_DIRECTION 80
+#define IDS_IN_AND_OUT 81
+#define IDS_UNSPUN_KALEIDA 82
+#define IDS_ROLLING_GRIDLEY 83
+#define IDS_6_WAY_OUTSWIRL 84
+#define IDS_WAVY 85
+#define IDS_SMOOTH_ROTOBLITTER 86
+#define IDS_DYNAMIC_MOVEMENT 87
+#define IDS_REPLACE 88
+#define IDS_ADDITIVE 89
+#define IDS_MAXIMUM_BLEND 90
+#define IDS_50_50_BLEND 91
+#define IDS_SUBTRACTIVE_BLEND_1 92
+#define IDS_SUBTRACTIVE_BLEND_2 93
+#define IDS_MULTIPLY_BLEND 94
+#define IDS_ADJUSTABLE_BLEND 95
+#define IDS_XOR 96
+#define IDS_MINIMUM_BLEND 97
+#define IDS_DYNAMIC_SHIFT 98
+#define IDS_SPIRAL 99
+#define IDS_3D_SCOPE_DISH 100
+#define IDD_DIALOG1 101
+#define IDS_ROTATING_BOW_THING 101
+#define IDB_TAB_NORMAL 102
+#define IDS_VERTICAL_BOUNCING_SCOPE 102
+#define IDB_TAB_SELECTED 103
+#define IDD_CFG_SIMPLE 103
+#define IDS_SPIRAL_GRAPH_FUN 103
+#define IDB_TAB_HILITED 104
+#define IDD_CFG_FADE 104
+#define IDS_ALTERNATING_DIAGONAL_SCOPE 104
+#define IDD_CFG_BLT 105
+#define IDS_VIBRATING_WORM 105
+#define IDD_CFG_DOTPLANE 106
+#define IDS_WANDERING_SIMPLE 106
+#define IDD_CFG_OSCSTAR 107
+#define IDS_FLITTERBUG 107
+#define IDD_CFG_NFC 108
+#define IDS_SPIROSTAR 108
+#define IDD_CFG_BLUR 109
+#define IDS_EXPLODING_DAISY 109
+#define IDD_CFG_BSPIN 110
+#define IDS_SWIRLIE_DOTS 110
+#define IDD_GCFG_BEAT 111
+#define IDS_SWEEP 111
+#define IDD_GCFG_DISP 112
+#define IDS_WHIPLASH_SPIRAL 112
+#define IDD_CFG_PARTS 113
+#define IDS_SUPERSCOPE 113
+#define IDD_GCFG_ABOUT 114
+#define IDS_DRAW_X_BANDS 114
+#define IDD_CFG_FILTER 115
+#define IDS_NONE 115
+#define IDD_CFG_ROTBLT 116
+#define IDS_SLIGHT_FUZZIFY 116
+#define IDC_CFG_SVP 117
+#define IDS_SHIFT_ROTATE_LEFT 117
+#define IDD_CFG_COLORFADE 118
+#define IDS_BIG_SWIRL_OUT 118
+#define IDD_CFG_CONTRASTENHANCE 119
+#define IDS_MEDIUM_SWIRL 119
+#define IDD_CFG_ROTSTAR 120
+#define IDS_SUNBURSTER 120
+#define IDD_CFG_OSCRING 121
+#define IDS_SWIRL_TO_CENTER 121
+#define IDD_CFG_TRANS 122
+#define IDB_BITMAP1 122
+#define IDS_BLOCKY_PARTIAL_OUT 122
+#define IDD_GCFG_PRESET 123
+#define IDS_SWIRLING_AROUND_BOTH_WAYS 123
+#define IDD_CFG_SCAT 124
+#define IDS_BUBBLING_OUTWARD 124
+#define IDD_CFG_DOTGRID 125
+#define IDS_BUBBLING_OUTWARD_WITH_SWIRL 125
+#define IDD_CFG_STACK 126
+#define IDS_5_POINTED_DISTRO 126
+#define IDS_TUNNELING 127
+#define IDD_DIALOG2 127
+#define IDD_CFG_WATER 128
+#define IDS_BLEEDIN 128
+#define IDD_CFG_COMMENT 129
+#define IDS_SHIFTED_BIG_SWIRL_OUT 129
+#define IDD_CFG_BRIGHTNESS 130
+#define IDS_PSYCHOTIC_BEAMING_OUTWARD 130
+#define IDD_CFG_INTERLEAVE 131
+#define IDS_COSINE_RADIAL_3_WAY 131
+#define IDD_CFG_GRAIN 132
+#define IDS_SPINNY_TUBE 132
+#define IDD_CFG_CLEAR 133
+#define IDS_RADIAL_SWIRLIES 133
+#define IDD_CFG_BUMP 134
+#define IDS_SWILL 134
+#define IDD_CFG_MIRROR 135
+#define IDS_GRIDLEY 135
+#define IDD_CFG_STARFIELD 136
+#define IDS_GRAPEVINE 136
+#define IDD_CFG_TEXT 137
+#define IDS_QUADRANT 137
+#define IDD_BUMP_HELP 138
+#define IDS_6_WAY_KALAEIDA 138
+#define IDD_CFG_MOSAIC 139
+#define IDS_USER_DEFINED 139
+#define IDD_CFG_WATERBUMP 140
+#define IDR_MENU1 140
+#define IDS_MOVEMENT 140
+#define IDD_CFG_AVI 141
+#define IDS_IGNORE 141
+#define IDD_CFG_UNKN 142
+#define IDS_MAXIMUM 142
+#define IDD_GCFG_TRANS 143
+#define IDS_50_50 143
+#define IDD_CFG_BPM 144
+#define IDS_EVERY_OTHER_LINE 144
+#define IDD_GCFG_BPM 145
+#define IDS_EVERY_OTHER_PIXEL 145
+#define IDD_CFG_PICTURE 146
+#define IDS_ADJUSTABLE 146
+#define IDD_CFG_DDM 147
+#define IDS_MULTIPLY 147
+#define IDD_CFG_SSCOPE 148
+#define IDS_BUFFER 148
+#define IDD_CFG_INVERT 149
+#define IDS_MINIMUM 149
+#define IDD_CFG_ONETONE 150
+#define IDS_CROSS_DISSOLVE 150
+#define IDD_CFG_TIMESCOPE 151
+#define IDS_RANDOM 151
+#define IDD_CFG_LIST 152
+#define IDS_L_R_PUSH 152
+#define IDD_CFG_LISTROOT 153
+#define IDS_R_L_PUSH 153
+#define IDD_CFG_LINEMODE 154
+#define IDS_T_B_PUSH 154
+#define IDD_GCFG_TRANSITIONS 155
+#define IDS_B_T_PUSH 155
+#define IDD_CFG_LASER_CONE 156
+#define IDS_9_RANDOM_BLOCKS 156
+#define IDD_CFG_LASER_BEATHOLD 157
+#define IDS_SPLIT_L_R_PUSH 157
+#define IDD_CFG_LASER_LINE 158
+#define IDS_L_R_CENTER_PUSH 158
+#define IDD_GCFG_FS 159
+#define IDS_L_R_CENTER_SQUEEZE 159
+#define IDD_CFG_INTERF 160
+#define IDS_L_R_WIPE 160
+#define IDD_CFG_SHIFT 161
+#define IDS_R_L_WIPE 161
+#define IDD_CFG_LASER_TRANSFORM 162
+#define IDS_T_B_WIPE 162
+#define IDD_CFG_DMOVE 163
+#define IDS_B_T_WIPE 163
+#define IDD_CFG_FASTBRIGHT 164
+#define IDS_DOT_DISSOLVE 164
+#define IDD_CFG_COLORMOD 165
+#define IDS_LOADING_WAIT 165
+#define IDD_EVAL_HELP 166
+#define IDS_LOADING 166
+#define IDD_DEBUG 167
+#define IDS_ERROR_LOADING_X 167
+#define IDD_CFG_CHANSHIFT 168
+#define IDS_BUILTIN_ID 168
+#define IDD_CFG_COLORREDUCTION 169
+#define IDS_CONFIG_SIZE 169
+#define IDD_CFG_MULT 170
+#define IDS_GENERAL 170
+#define IDD_CFG_MULTIDELAY 171
+#define IDS_OPERATORS 171
+#define IDD_CFG_VIDEODELAY 172
+#define IDS_FUNCTIONS 172
+#define IDS_STRING173 173
+#define IDS_CONSTANTS 173
+#define IDR_BUMP_LIGHT_POSITION 174
+#define IDS_BEAT2 174
+#define IDS_BEATS 174
+#define IDR_COLOR_MODIFIER 175
+#define IDS_SUBTRACTIVE_1 175
+#define IDR_DYNAMIC_DISTANCE_MODIFIER 176
+#define IDS_SUBTRACTIVE_2 176
+#define IDR_DYNAMIC_MOVEMENT 177
+#define IDS_STRING177 177
+#define IDS_RENDER_AVI 177
+#define IDR_DYNAMIC_SHIFT 178
+#define IDS_TRANS_BLITTER_FEEDBACK 178
+#define IDR_SUPERSCOPE 179
+#define IDS_TRANS_BLUR 179
+#define IDR_MOVEMENT 180
+#define IDS_MISC_CUSTOM_BPM 180
+#define IDR_EFFECT_LIST 181
+#define IDS_TRANS_BRIGHTNESS 181
+#define IDR_HELP_1 182
+#define IDS_RENDER_BASS_SPIN 182
+#define IDR_HELP_2 183
+#define IDS_TRANS_BUMP 183
+#define IDR_HELP_3 184
+#define IDS_TRANS_CHANNEL_SHIFT 184
+#define IDR_HELP_4 185
+#define IDS_RENDER_CLEAR_SCREEN 185
+#define IDS_TRANS_COLORFADE 186
+#define IDS_TRANS_COLOR_REDUCTION 187
+#define IDS_TRANS_COLOR_CLIP 188
+#define IDS_MISC_COMMENT 189
+#define IDS_TRANS_COLOR_MODIFIER 190
+#define IDS_TRANS_DYNAMIC_DISTANCE_MODIFIER 191
+#define IDS_TRANS_DYNAMIC_MOVEMENT 192
+#define IDS_RENDER_DOT_FOUNTAIN 193
+#define IDS_RENDER_DOT_GRID 194
+#define IDS_RENDER_DOT_PLANE 195
+#define IDS_TRANS_FADEOUT 196
+#define IDS_TRANS_FAST_BRIGHTNESS 197
+#define IDS_TRANS_GRAIN 198
+#define IDS_TRANS_INTERFERENCES 199
+#define IDS_TRANS_INTERLEAVE 200
+#define IDS_TRANS_INVERT 201
+#define IDS_MISC_SET_RENDER_MODE 202
+#define IDS_TRANS_MIRROR 203
+#define IDS_TRANS_MOSAIC 204
+#define IDS_TRANS_MULTI_DELAY 205
+#define IDS_TRANS_MULTIPLIER 206
+#define IDS_RENDER_ONBEAT_CLEAR 207
+#define IDS_TRANS_UNIQUE_TONE 208
+#define IDS_RENDER_RING 209
+#define IDS_RENDER_OSCILLOSCOPE_STAR 210
+#define IDS_RENDER_MOVING_PARTICLE 211
+#define IDS_RENDER_PICTURE 212
+#define IDS_TRANS_ROTO_BLITTER 213
+#define IDS_RENDER_ROTATING_STARS 214
+#define IDS_TRANS_SCATTER 215
+#define IDS_TRANS_DYNAMIC_SHIFT 216
+#define IDS_RENDER_SIMPLE 217
+#define IDS_RENDER_SUPERSCOPE 218
+#define IDS_MISC_BUFFER_SAVE 219
+#define IDS_RENDER_STARFIELD 220
+#define IDS_RENDER_SVP_LOADER 221
+#define IDS_RENDER_TEXT 222
+#define IDS_RENDER_TIMESCOPE 223
+#define IDS_TRANS_MOVEMENT 224
+#define IDS_UNKNOWN_RENDER_OBJECT 225
+#define IDS_TRANS_VIDEO_DELAY 226
+#define IDS_TRANS_WATER 227
+#define IDS_TRANS_WATER_BUMP 228
+#define IDS_OVERLAY_MODE 229
+#define IDC_EFFECTS 1000
+#define IDC_ENABLED 1001
+#define IDC_FBCLEAR 1002
+#define IDC_DISSOC 1003
+#define IDC_DAMP 1004
+#define OBJ_COMBO 1005
+#define IDC_EFFECTRECT 1006
+#define IDC_BIN 1007
+#define IDC_RRECT 1007
+#define IDC_ADDITIVE 1008
+#define IDC_RADIUS 1009
+#define IDC_REMSEL 1010
+#define IDC_5050 1011
+#define IDC_LIB 1012
+#define IDC_DEFRENDBLEND 1012
+#define IDC_REPLACE 1013
+#define IDC_RANDOM_DROP 1014
+#define IDC_ADD 1015
+#define IDC_LEVELS 1015
+#define IDC_DROP_LEFT 1016
+#define IDC_LEVELTEXT 1016
+#define IDC_ADAPT 1017
+#define IDC_MOVEUP 1018
+#define IDC_GBR 1018
+#define IDC_X8 1018
+#define IDC_RED 1019
+#define IDC_BRG 1019
+#define IDC_X4 1019
+#define IDC_HORIZONTAL1 1020
+#define IDC_RBG 1020
+#define IDC_DROP_CENTER 1021
+#define IDC_BGR 1021
+#define IDC_X05 1021
+#define IDC_PERSIST 1022
+#define IDC_GRB 1022
+#define IDC_X025 1022
+#define IDC_MOVEDOWN 1023
+#define IDC_X0125 1023
+#define IDC_GREEN 1024
+#define IDC_XI 1024
+#define IDC_HORIZONTAL2 1025
+#define IDC_XS 1025
+#define IDC_DROP_RIGHT 1026
+#define IDC_PERSIST_TITLE 1027
+#define IDC_LOAD 1028
+#define IDC_LEFT 1029
+#define IDC_BLUE 1030
+#define IDC_X 1031
+#define IDC_MAX 1032
+#define IDC_X2 1032
+#define IDC_VERTICAL1 1033
+#define IDC_X3 1033
+#define IDC_DROP_TOP 1034
+#define IDC_SAVE 1035
+#define IDC_RIGHT 1036
+#define IDC_BRED 1037
+#define IDC_Y 1038
+#define IDC_VERTICAL2 1039
+#define IDC_Y2 1039
+#define IDC_DROP_MIDDLE 1040
+#define IDC_CLEAR 1041
+#define IDC_LC 1042
+#define IDC_BGREEN 1043
+#define IDC_LC2 1043
+#define IDC_DROP_BOTTOM 1044
+#define IDC_RC 1045
+#define IDC_CLONESEL 1046
+#define IDC_BBLUE 1047
+#define IDC_SPEED 1048
+#define IDC_DOTS 1049
+#define IDC_SA 1050
+#define IDC_DISTANCE 1051
+#define IDC_METHOD_SLUDGE 1052
+#define IDC_PERSIST_TEXT1 1053
+#define IDC_LINES 1054
+#define IDC_SLIDER1 1055
+#define IDC_EXCLUDE 1056
+#define IDC_SLIDER7 1056
+#define IDC_STAT 1057
+#define IDC_PERSIST_TEXT2 1058
+#define IDC_LINES2 1059
+#define IDC_BLEND 1060
+#define IDC_SLIDER3 1061
+#define IDC_SMOOTH 1062
+#define IDC_BUTTON1 1063
+#define IDC_LINES3 1064
+#define IDC_BUTTON4 1064
+#define IDC_SLIDER4 1065
+#define IDC_SOLID 1066
+#define IDC_SLOWER 1067
+#define IDC_ONBEAT2 1068
+#define IDC_RATIO 1069
+#define IDC_SLIDER2 1070
+#define IDC_RSTACK_BLEND1 1070
+#define IDC_X_RATIO 1071
+#define IDC_RSTACK_BLEND2 1071
+#define IDC_CHECK1 1072
+#define IDC_RSTACK_BLEND3 1072
+#define IDC_RSTACK_BLEND4 1073
+#define IDC_BUTTON3 1073
+#define IDC_CHECK8 1073
+#define IDC_Y_RATIO 1074
+#define IDC_NEWADAPT 1074
+#define IDC_RSTACK_BLEND5 1074
+#define IDC_C1 1075
+#define IDC_RSTACK_BLEND6 1075
+#define IDC_INVERTDEPTH 1075
+#define IDC_SLIDER5 1076
+#define IDC_C2 1076
+#define IDC_RSTACK_BLEND7 1076
+#define IDC_OFF 1076
+#define IDC_C3 1077
+#define IDC_RSTACK_BLEND8 1077
+#define IDC_BANDS 1077
+#define IDC_C4 1078
+#define IDC_FPS 1078
+#define IDC_BANDTXT 1078
+#define IDC_RSTACK_BLEND9 1078
+#define IDC_C5 1079
+#define IDC_SLIDER6 1079
+#define IDC_TREE1 1079
+#define IDC_RSTACK_BLEND10 1079
+#define IDC_INSLIDE 1080
+#define IDC_RSTACK_BLEND11 1080
+#define IDC_TRI 1081
+#define IDC_OUTSLIDE 1081
+#define IDC_ALPHASLIDE 1081
+#define IDC_RSTACK_BLEND12 1081
+#define IDC_HLEFT 1082
+#define IDC_CBBUF2 1082
+#define IDC_BLENDSLIDE 1082
+#define IDC_CHECK6 1083
+#define IDC_CBBUF1 1083
+#define IDC_CHECK7 1084
+#define IDC_INVERT2 1084
+#define IDC_EFNAME 1085
+#define IDC_DEFAULTBLEND 1085
+#define IDC_HCENTER 1086
+#define IDC_BPP_CONV 1086
+#define IDC_TRANSITION 1087
+#define IDC_WRAP 1087
+#define IDC_HRIGHT 1088
+#define IDC_L_FRAME 1088
+#define IDC_EDIT1 1089
+#define IDC_L_TEXT1 1089
+#define IDC_VTOP 1090
+#define IDC_EDIT2 1090
+#define IDC_VCENTER 1091
+#define IDC_EDIT3 1091
+#define IDC_L_MASK 1091
+#define IDC_VBOTTOM 1092
+#define IDC_EDIT4 1092
+#define IDC_BKGND_RENDER 1092
+#define IDC_COMBO1 1093
+#define IDC_SETDESKTOPCOLOR 1093
+#define IDC_EDIT9 1093
+#define IDC_CHOOSEFONT 1094
+#define IDC_OVERLAYCOLOR 1094
+#define IDC_EDIT66 1094
+#define IDC_T 1095
+#define IDC_COMBO2 1095
+#define IDC_DEFOVERLAYCOLOR 1095
+#define IDC_EDIT7 1095
+#define IDC_EDIT 1096
+#define IDC_EDIT5 1096
+#define IDC_LEFTCH 1097
+#define IDC_EDIT6 1097
+#define IDC_BLANKS 1098
+#define IDC_NOMOVEMENT 1098
+#define IDC_EDIT10 1098
+#define IDC_RIGHTCH 1099
+#define IDC_USE_OVERLAY 1099
+#define IDC_EDIT11 1099
+#define IDC_RANDOMPOS 1100
+#define IDC_THREAD_PRIORITY 1100
+#define IDC_EDIT12 1100
+#define IDC_MIDCH 1101
+#define IDC_L_PROJZONES 1101
+#define IDC_EDIT13 1101
+#define IDC_OUTLINE 1102
+#define IDC_L_SUPPRESS_DIALOGS 1102
+#define IDC_EDIT14 1102
+#define IDC_TOP 1103
+#define IDC_L_ACTIVEOUTPUT 1103
+#define IDC_EDIT15 1103
+#define IDC_HSHIFT 1104
+#define IDC_FR1 1104
+#define IDC_EDIT16 1104
+#define IDC_CENTER 1105
+#define IDC_FR2 1105
+#define IDC_VSHIFT 1106
+#define IDC_L_SUPPRESS_OUTPUT 1106
+#define IDC_BOTTOM 1107
+#define IDC_L_SYNC 1107
+#define IDC_OUTLINESIZE 1108
+#define IDC_EDIT8 1108
+#define IDC_NUMCOL 1109
+#define IDC_RANDWORD 1110
+#define IDC_RADIO1 1111
+#define IDC_DEFOUTCOL 1112
+#define IDC_NEWRESET 1112
+#define IDC_BELOW 1112
+#define IDC_RADIO7 1112
+#define IDC_RADIO2 1113
+#define IDC_ABOVE 1113
+#define IDC_ANGLE 1114
+#define IDC_NEAR 1114
+#define IDC_HRESET 1115
+#define IDC_RADIO3 1116
+#define IDC_CHECK2 1117
+#define IDC_VRESET 1118
+#define IDC_CHECK9 1118
+#define IDC_RADIO4 1119
+#define IDC_PLAIN 1120
+#define IDC_RADIO5 1121
+#define IDC_SAVEFB 1121
+#define IDC_ROUNDDOWN 1121
+#define IDC_CHECK3 1122
+#define IDC_RESTFB 1122
+#define IDC_ROUNDUP 1122
+#define IDC_RADIO6 1123
+#define IDC_INVERT1 1123
+#define IDC_CHECK10 1123
+#define IDC_LIST1 1124
+#define IDC_CHECK11 1124
+#define IDC_CHECK5 1125
+#define IDC_CHECK4 1126
+#define IDC_SHADOW 1127
+#define IDC_CLEAR2 1128
+#define IDC_BUTTON2 1129
+#define IDC_VERSTR 1130
+#define IDC_OSC 1131
+#define IDC_SPEC 1132
+#define IDC_STATGRAIN 1133
+#define IDC_CLEARFIRSTFRAME 1134
+#define IDC_DEPTH 1135
+#define IDC_SETTINGS 1136
+#define IDC_NUMSTARS 1137
+#define IDC_ONBEAT 1138
+#define IDC_SCROLLBAR1 1139
+#define IDC_SPDCHG 1140
+#define IDC_QUALITY2 1141
+#define IDC_TRANS_SLIDER 1142
+#define IDC_DEPTH2 1143
+#define IDC_TRANS_CHECK 1144
+#define IDC_SPDDUR 1145
+#define IDC_AVS_VER 1146
+#define IDC_BEATDUR 1147
+#define IDC_DONT_MIN_AVS 1148
+#define IDC_CODE1 1149
+#define IDC_BPMSTD 1150
+#define IDC_HELPBTN 1151
+#define IDC_BPMADV 1152
+#define IDC_CODE2 1153
+#define IDC_STICKY 1154
+#define IDC_CODE3 1155
+#define IDC_ONLYSTICKY 1155
+#define IDC_MOREADAPT 1156
+#define IDC_DOT 1157
+#define IDC_TEXT 1158
+#define IDC_WAVE 1158
+#define IDC_DEFCOL 1159
+#define IDC_QUALITY 1160
+#define IDC_BPM 1161
+#define IDC_CONFIDENCE 1162
+#define IDC_2X 1163
+#define IDC_DIV2 1164
+#define IDC_ARBVAL 1165
+#define IDC_RESET 1166
+#define IDC_SKIPVAL 1167
+#define IDC_STICK 1167
+#define IDC_INVERT 1168
+#define IDC_UNSTICK 1168
+#define IDC_ARBITRARY 1169
+#define IDC_ARBTXT 1170
+#define IDC_SKIPTXT 1171
+#define IDC_CURBPM 1172
+#define IDC_SKIPFIRST 1172
+#define IDC_CURCONF 1173
+#define IDC_SKIPFIRSTTXT 1173
+#define IDC_SKIP 1174
+#define IDC_IN 1175
+#define IDC_OUT 1176
+#define IDC_NPOINTS 1177
+#define IDC_ROTATE 1178
+#define IDC_ALPHA 1179
+#define IDC_ROTATE2 1180
+#define IDC_DISTANCE2 1181
+#define IDC_ALPHA2 1182
+#define IDC_RGB 1183
+#define IDC_RGB2 1184
+#define IDC_INITROT 1185
+#define IDC_DEBUGREG_1 1186
+#define IDC_DEBUGREG_2 1187
+#define IDC_DEBUGREG_3 1188
+#define IDC_DEBUGREG_4 1189
+#define IDC_DEBUGREG_5 1190
+#define IDC_DEBUGREG_6 1191
+#define IDC_DEBUGREG_7 1192
+#define IDC_DEBUGREG_8 1193
+#define IDC_DEBUGREG_9 1194
+#define IDC_DEBUGREG_10 1195
+#define IDC_DEBUGREG_11 1196
+#define IDC_DEBUGREG_12 1197
+#define IDC_DEBUGREG_13 1198
+#define IDC_DEBUGREG_14 1199
+#define IDC_DEBUGREG_15 1200
+#define IDC_DEBUGREG_16 1201
+#define IDC_TAB1 1203
+#define IDC_LABEL1 1204
+#define IDC_STATIC_ALPHA 1205
+#define IDC_STATIC_TRANS_TOTAL 1206
+#define IDC_STATIC_TRANS_NONE 1207
+#define IDC_THREADS 1208
+#define IDC_THREADSBORDER 1209
+#define IDC_STATIC1 1210
+#define IDC_STATIC2 1211
+#define IDM_DISPLAY 40001
+#define IDM_PRESETS 40002
+#define IDM_TRANS 40003
+#define IDM_ABOUT 40004
+#define IDM_BPM 40005
+#define IDM_TRANSITIONS 40006
+#define IDM_FULLSCREEN 40007
+#define IDM_HELP_DEBUGWND 40008
+#define IDM_UNDO 40009
+#define IDM_REDO 40010
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 230
+#define _APS_NEXT_COMMAND_VALUE 40011
+#define _APS_NEXT_CONTROL_VALUE 1212
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/Visualization/vis_avs/rlib.cpp b/Src/Plugins/Visualization/vis_avs/rlib.cpp
new file mode 100644
index 00000000..07c92611
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/rlib.cpp
@@ -0,0 +1,458 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include "r_defs.h"
+#include "r_unkn.h"
+#include "r_list.h"
+#include "rlib.h"
+
+#include "ape.h"
+
+#include "avs_eelif.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+
+#define PUT_INT(y) data[pos]=(y)&255; data[pos+1]=(y>>8)&255; data[pos+2]=(y>>16)&255; data[pos+3]=(y>>24)&255
+#define GET_INT() (data[pos]|(data[pos+1]<<8)|(data[pos+2]<<16)|(data[pos+3]<<24))
+
+void C_RBASE::load_string(RString &s,unsigned char *data, int &pos, int len) // read configuration of max length "len" from data.
+{
+ int size=GET_INT(); pos += 4;
+ if (size > 0 && len-pos >= size)
+ {
+ s.resize(size);
+ memcpy(s.get(), data+pos, size);
+ pos+=size;
+ }
+ else
+ {
+ s.resize(1);
+ s.get()[0]=0;
+ }
+}
+void C_RBASE::save_string(unsigned char *data, int &pos, RString &text)
+{
+ if (text.get() && text.get()[0])
+ {
+ char *p=text.get();
+ int x=32768;
+ while (x-- && *p) p++;
+ if (*p)
+ {
+ MessageBox(NULL,"Yo, this is some long ass shit","FUCK!",MB_OK);
+ //FUCKO
+ }
+ int l=(strlen(text.get())+1);
+ PUT_INT(l); pos+=4;
+ memcpy(data+pos, text.get(), strlen(text.get())+1);
+ pos+=strlen(text.get())+1;
+ }
+ else
+ {
+ PUT_INT(0);
+ pos+=4;
+ }
+}
+
+void C_RLibrary::add_dofx(void *rf, int has_r2)
+{
+ if ((NumRetrFuncs&7)==0||!RetrFuncs)
+ {
+ void *newdl=(void *)GlobalAlloc(GMEM_FIXED,sizeof(rfStruct)*(NumRetrFuncs+8));
+ if (!newdl)
+ {
+ char title[64];
+ MessageBox(NULL,WASABI_API_LNGSTRING(IDS_OUT_OF_MEMORY),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_CRITICAL_ERROR,title,64),MB_OK);
+ ExitProcess(0);
+ }
+ memset(newdl,0,sizeof(rfStruct)*(NumRetrFuncs+8));
+ if (RetrFuncs)
+ {
+ memcpy(newdl,RetrFuncs,NumRetrFuncs*sizeof(rfStruct));
+ GlobalFree(RetrFuncs);
+ }
+ RetrFuncs=(rfStruct*)newdl;
+ }
+ RetrFuncs[NumRetrFuncs].is_r2=has_r2;
+ *((void**)&RetrFuncs[NumRetrFuncs].rf) = rf;
+ NumRetrFuncs++;
+}
+
+// declarations for built-in effects
+#define DECLARE_EFFECT(name) extern C_RBASE *(name)(char *desc); add_dofx((void*)name,0);
+#define DECLARE_EFFECT2(name) extern C_RBASE *(name)(char *desc); add_dofx((void*)name,1);
+
+void C_RLibrary::initfx(void)
+{
+ DECLARE_EFFECT(R_SimpleSpectrum);
+ DECLARE_EFFECT(R_DotPlane);
+ DECLARE_EFFECT(R_OscStars);
+ DECLARE_EFFECT(R_FadeOut);
+ DECLARE_EFFECT(R_BlitterFB);
+ DECLARE_EFFECT(R_NFClear);
+ DECLARE_EFFECT2(R_Blur);
+ DECLARE_EFFECT(R_BSpin);
+ DECLARE_EFFECT(R_Parts);
+ DECLARE_EFFECT(R_RotBlit);
+ DECLARE_EFFECT(R_SVP);
+ DECLARE_EFFECT2(R_ColorFade);
+ DECLARE_EFFECT(R_ContrastEnhance);
+ DECLARE_EFFECT(R_RotStar);
+ DECLARE_EFFECT(R_OscRings);
+ DECLARE_EFFECT2(R_Trans);
+ DECLARE_EFFECT(R_Scat);
+ DECLARE_EFFECT(R_DotGrid);
+ DECLARE_EFFECT(R_Stack);
+ DECLARE_EFFECT(R_DotFountain);
+ DECLARE_EFFECT2(R_Water);
+ DECLARE_EFFECT(R_Comment);
+ DECLARE_EFFECT2(R_Brightness);
+ DECLARE_EFFECT(R_Interleave);
+ DECLARE_EFFECT(R_Grain);
+ DECLARE_EFFECT(R_Clear);
+ DECLARE_EFFECT(R_Mirror);
+ DECLARE_EFFECT(R_StarField);
+ DECLARE_EFFECT(R_Text);
+ DECLARE_EFFECT(R_Bump);
+ DECLARE_EFFECT(R_Mosaic);
+ DECLARE_EFFECT(R_WaterBump);
+ DECLARE_EFFECT(R_AVI);
+ DECLARE_EFFECT(R_Bpm);
+ DECLARE_EFFECT(R_Picture);
+ DECLARE_EFFECT(R_DDM);
+ DECLARE_EFFECT(R_SScope);
+ DECLARE_EFFECT(R_Invert);
+ DECLARE_EFFECT(R_Onetone);
+ DECLARE_EFFECT(R_Timescope);
+ DECLARE_EFFECT(R_LineMode);
+ DECLARE_EFFECT(R_Interferences);
+ DECLARE_EFFECT(R_Shift);
+ DECLARE_EFFECT2(R_DMove);
+ DECLARE_EFFECT(R_FastBright);
+ DECLARE_EFFECT(R_DColorMod);
+}
+
+static const struct
+{
+ char id[33];
+ int newidx;
+} NamedApeToBuiltinTrans[] =
+{
+ {"Winamp Brightness APE v1", 22},
+ {"Winamp Interleave APE v1", 23},
+ {"Winamp Grain APE v1", 24 },
+ {"Winamp ClearScreen APE v1", 25},
+ {"Nullsoft MIRROR v1", 26},
+ {"Winamp Starfield v1", 27},
+ {"Winamp Text v1", 28 },
+ {"Winamp Bump v1", 29 },
+ {"Winamp Mosaic v1", 30 },
+ {"Winamp AVIAPE v1", 32},
+ {"Nullsoft Picture Rendering v1", 34},
+ {"Winamp Interf APE v1", 41}
+};
+
+void C_RLibrary::initbuiltinape(void)
+{
+#define ADD(sym) extern C_RBASE * sym(char *desc); _add_dll(0,sym,"Builtin_" #sym, 0)
+#define ADD2(sym,name) extern C_RBASE * sym(char *desc); _add_dll(0,sym,name, 0)
+#ifdef LASER
+ ADD(RLASER_Cone);
+ ADD(RLASER_BeatHold);
+ ADD(RLASER_Line);
+ ADD(RLASER_Bren); // not including it for now
+ ADD(RLASER_Transform);
+#else
+ ADD2(R_ChannelShift,"Channel Shift");
+ ADD2(R_ColorReduction,"Color Reduction");
+ ADD2(R_Multiplier,"Multiplier");
+ ADD2(R_VideoDelay,"Holden04: Video Delay");
+ ADD2(R_MultiDelay,"Holden05: Multi Delay");
+#endif
+#undef ADD
+#undef ADD2
+}
+
+
+void C_RLibrary::_add_dll(HINSTANCE hlib,class C_RBASE *(__cdecl *cre)(char *),char *inf, int is_r2)
+{
+ if ((NumDLLFuncs&7)==0||!DLLFuncs)
+ {
+ DLLInfo *newdl=(DLLInfo *)GlobalAlloc(GMEM_FIXED,sizeof(DLLInfo)*(NumDLLFuncs+8));
+ if (!newdl)
+ {
+ char title[64];
+ MessageBox(NULL,WASABI_API_LNGSTRING(IDS_OUT_OF_MEMORY),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_CRITICAL_ERROR,title,64),MB_OK);
+ ExitProcess(0);
+ }
+ memset(newdl,0,sizeof(DLLInfo)*(NumDLLFuncs+8));
+ if (DLLFuncs)
+ {
+ memcpy(newdl,DLLFuncs,NumDLLFuncs*sizeof(DLLInfo));
+ GlobalFree(DLLFuncs);
+ }
+ DLLFuncs=newdl;
+
+ }
+ DLLFuncs[NumDLLFuncs].hDllInstance=hlib;
+ DLLFuncs[NumDLLFuncs].createfunc=cre;
+ DLLFuncs[NumDLLFuncs].idstring=inf;
+ DLLFuncs[NumDLLFuncs].is_r2=is_r2;
+ NumDLLFuncs++;
+}
+
+
+static APEinfo ext_info=
+{
+ 3,
+ 0,
+ &g_line_blend_mode,
+ NSEEL_VM_alloc,
+ NSEEL_VM_free,
+ AVS_EEL_IF_resetvars,
+ NSEEL_VM_regvar,
+ AVS_EEL_IF_Compile,
+ AVS_EEL_IF_Execute,
+ NSEEL_code_free,
+ compilerfunctionlist,
+ getGlobalBuffer,
+};
+
+void C_RLibrary::initdll()
+{
+ ext_info.global_registers=NSEEL_getglobalregs();
+
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[MAX_PATH*2];
+#ifdef LASER
+ wsprintf(dirmask,"%s\\*.lpe",g_path);
+#else
+ wsprintf(dirmask,"%s\\*.ape",g_path);
+#endif
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do {
+ char s[MAX_PATH];
+ HINSTANCE hlib;
+ wsprintf(s,"%s\\%s",g_path,d.cFileName);
+ hlib=LoadLibrary(s);
+ if (hlib)
+ {
+ int cre;
+ char *inf;
+
+ void (*sei)(HINSTANCE hDllInstance, APEinfo *ptr);
+ *(void**)&sei = (void *) GetProcAddress(hlib,"_AVS_APE_SetExtInfo");
+ if (sei)
+ sei(hlib,&ext_info);
+
+#ifdef LASER
+ int (*retr)(HINSTANCE hDllInstance, char **info, int *create, C_LineListBase *linelist);
+ retr = (int (*)(HINSTANCE, char ** ,int *, C_LineListBase*)) GetProcAddress(hlib,"_AVS_LPE_RetrFunc");
+ if (retr && retr(hlib,&inf,&cre,g_laser_linelist))
+ {
+ _add_dll(hlib,(class C_RBASE *(__cdecl *)(char *))cre,inf,0);
+ }
+ else FreeLibrary(hlib);
+#else
+ int (*retr)(HINSTANCE hDllInstance, char **info, int *create);
+ retr = (int (*)(HINSTANCE, char ** ,int *)) GetProcAddress(hlib,"_AVS_APE_RetrFuncEXT2");
+ if (retr && retr(hlib,&inf,&cre))
+ {
+ _add_dll(hlib,(class C_RBASE *(__cdecl *)(char *))cre,inf,1);
+ }
+ else
+ {
+ retr = (int (*)(HINSTANCE, char ** ,int *)) GetProcAddress(hlib,"_AVS_APE_RetrFunc");
+ if (retr && retr(hlib,&inf,&cre))
+ {
+ _add_dll(hlib,(class C_RBASE *(__cdecl *)(char *))cre,inf,0);
+ }
+ else FreeLibrary(hlib);
+ }
+#endif
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+}
+
+
+int C_RLibrary::GetRendererDesc(int which, char *str)
+{
+ *str=0;
+ if (which >= 0 && which < NumRetrFuncs)
+ {
+ RetrFuncs[which].rf(str);
+ return 1;
+ }
+ if (which >= DLLRENDERBASE)
+ {
+ which-=DLLRENDERBASE;
+ if (which < NumDLLFuncs)
+ {
+ DLLFuncs[which].createfunc(str);
+ return (int)DLLFuncs[which].idstring;
+ }
+ }
+ return 0;
+}
+
+C_RBASE *C_RLibrary::CreateRenderer(int *which, int *has_r2)
+{
+ if (has_r2) *has_r2=0;
+
+ if (*which >= 0 && *which < NumRetrFuncs)
+ {
+ if (has_r2) *has_r2 = RetrFuncs[*which].is_r2;
+ return RetrFuncs[*which].rf(NULL);
+ }
+
+ if (*which == LIST_ID)
+ return (C_RBASE *) new C_RenderListClass();
+
+ if (*which >= DLLRENDERBASE)
+ {
+ int x;
+ char *p=(char *)*which;
+ for (x = 0; x < NumDLLFuncs; x ++)
+ {
+ if (!DLLFuncs[x].createfunc) break;
+ if (DLLFuncs[x].idstring)
+ {
+ if (!strncmp(p,DLLFuncs[x].idstring,32))
+ {
+ *which=(int)DLLFuncs[x].idstring;
+ return DLLFuncs[x].createfunc(NULL);
+ }
+ }
+ }
+ for (x = 0; x < sizeof(NamedApeToBuiltinTrans)/sizeof(NamedApeToBuiltinTrans[0]); x ++)
+ {
+ if (!strncmp(p,NamedApeToBuiltinTrans[x].id,32))
+ {
+ *which=NamedApeToBuiltinTrans[x].newidx;
+ if (has_r2) *has_r2 = RetrFuncs[*which].is_r2;
+ return RetrFuncs[*which].rf(NULL);
+ }
+ }
+ }
+ int r=*which;
+ *which=UNKN_ID;
+ C_UnknClass *p=new C_UnknClass();
+ p->SetID(r,(r >= DLLRENDERBASE)?(char*)r:"");
+ return (C_RBASE *)p;
+}
+
+C_RLibrary::C_RLibrary()
+{
+ DLLFuncs=NULL;
+ NumDLLFuncs=0;
+ RetrFuncs=0;
+ NumRetrFuncs=0;
+
+ initfx();
+ initdll();
+ initbuiltinape();
+
+}
+
+C_RLibrary::~C_RLibrary()
+{
+ if (RetrFuncs) GlobalFree(RetrFuncs);
+ RetrFuncs=0;
+ NumRetrFuncs=0;
+
+ if (DLLFuncs)
+ {
+ int x;
+ for (x = 0; x < NumDLLFuncs; x ++)
+ {
+ if (DLLFuncs[x].hDllInstance)
+ FreeLibrary(DLLFuncs[x].hDllInstance);
+ }
+ GlobalFree(DLLFuncs);
+ }
+ DLLFuncs=NULL;
+ NumDLLFuncs=0;
+}
+
+HINSTANCE C_RLibrary::GetRendererInstance(int which, HINSTANCE hThisInstance)
+{
+ if (which < DLLRENDERBASE || which == UNKN_ID || which == LIST_ID) return hThisInstance;
+ int x;
+ char *p=(char *)which;
+ for (x = 0; x < NumDLLFuncs; x ++)
+ {
+ if (DLLFuncs[x].idstring)
+ {
+ if (!strncmp(p,DLLFuncs[x].idstring,32))
+ {
+ if (DLLFuncs[x].hDllInstance)
+ return DLLFuncs[x].hDllInstance;
+ break;
+ }
+ }
+ }
+ return hThisInstance;
+}
+
+
+void *g_n_buffers[NBUF];
+int g_n_buffers_w[NBUF],g_n_buffers_h[NBUF];
+
+
+void *getGlobalBuffer(int w, int h, int n, int do_alloc)
+{
+ if (n < 0 || n >= NBUF) return 0;
+
+ if (!g_n_buffers[n] || g_n_buffers_w[n] != w || g_n_buffers_h[n] != h)
+ {
+ if (g_n_buffers[n]) GlobalFree(g_n_buffers[n]);
+ if (do_alloc)
+ {
+ g_n_buffers_w[n]=w;
+ g_n_buffers_h[n]=h;
+ return g_n_buffers[n]=GlobalAlloc(GPTR,sizeof(int)*w*h);
+ }
+
+ g_n_buffers[n]=NULL;
+ g_n_buffers_w[n]=0;
+ g_n_buffers_h[n]=0;
+
+ return 0;
+ }
+ return g_n_buffers[n];
+}
+
diff --git a/Src/Plugins/Visualization/vis_avs/rlib.h b/Src/Plugins/Visualization/vis_avs/rlib.h
new file mode 100644
index 00000000..76365d41
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/rlib.h
@@ -0,0 +1,74 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _RLIB_H_
+#define _RLIB_H_
+
+#define DLLRENDERBASE 16384
+
+class C_RLibrary {
+ protected:
+ typedef struct
+ {
+ C_RBASE *(*rf)(char *desc);
+ int is_r2;
+ } rfStruct;
+ rfStruct *RetrFuncs;
+
+ int NumRetrFuncs;
+
+ typedef struct
+ {
+ HINSTANCE hDllInstance;
+ char *idstring;
+ C_RBASE *(*createfunc)(char *desc);
+ int is_r2;
+
+ } DLLInfo;
+
+ DLLInfo *DLLFuncs;
+ int NumDLLFuncs;
+
+ void add_dofx(void *rf, int has_r2);
+ void initfx(void);
+ void initdll(void);
+ void initbuiltinape(void);
+ void _add_dll(HINSTANCE,class C_RBASE *(__cdecl *)(char *),char *, int);
+ public:
+ C_RLibrary();
+ ~C_RLibrary();
+ C_RBASE *CreateRenderer(int *which, int *has_r2);
+ HINSTANCE GetRendererInstance(int which,HINSTANCE hThisInstance);
+ int GetRendererDesc(int which, char *str);
+ // if which is >= DLLRENDERBASE
+ // returns "id" of DLL. which is used to enumerate. str is desc
+ // otherwise, returns 1 on success, 0 on error
+};
+
+#endif // _RLIB_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/supersco.bin b/Src/Plugins/Visualization/vis_avs/supersco.bin
new file mode 100644
index 00000000..636391b5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/supersco.bin
@@ -0,0 +1,18 @@
+Superscope tutorial goes here
+But for now, here is the old text:
+
+You can specify expressions that run on Init, Frame, and on Beat.
+ 'n' specifies the number of points to render (set this in Init, Beat, or Frame).
+
+For the 'Per Point' expression (which happens 'n' times per frame), use:
+ 'x' and 'y' are the coordinates to draw to (-1..1)
+ 'i' is the position of the scope (0..1)
+ 'v' is the value at that point (-1..1).
+ 'b' is 1 if beat, 0 if not.
+ 'red', 'green' and 'blue' are all (0..1) and can be modified
+ 'linesize' can be set from 1.0 to 255.0
+ 'skip' can be set to >0 to skip drawing the current item
+ 'drawmode' can be set to > 0 for lines, <= 0 for points
+ 'w' and 'h' are the width and height of the screen, in pixels.
+
+Anybody want to send me better text to put here? Please :) \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/svp_vis.h b/Src/Plugins/Visualization/vis_avs/svp_vis.h
new file mode 100644
index 00000000..f4bb785b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/svp_vis.h
@@ -0,0 +1,136 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+// Note!
+// *Video points to memory in 32bit video memory, ie, the following can be used
+// for your utility and to help your understanding of the pixel format used.
+
+// In Visual C, you should start a DLL project, under code generation set it to
+// use the DLL libraries, and most likely for release you will want to turn
+// optimisation for speed on. Include this .h file in your project, then create
+// or add your main C/C++ file and #include "vis.h"
+
+// To start off, fill in the VisInfo structure. Render should draw a whole frame
+// into the 32 bit ABGR buffer (for blur, smoke and zoom to work it should, rather
+// than replacing the video data, add to it using bitwise or, saturated add, or
+// alpha blend). Make sure not to exceed the boundaries given. 'Pitch' specifies
+// the distance, in pixels, between the start of each line. If you have a pointer
+// at the start of a line, Pointer+Pitch is the start of the next line and
+// Pointer-Pitch is the start of the previous.
+// Make sure that QueryModule is defined exactly as at the end of this file,
+// including the extern "C" keyword if you're using C++. It should return a
+// pointer to this structure. All routines that are pointed to by the structure
+// must be filled in even if they don't do anything. Render is the only function
+// that is required to have a body.
+
+
+
+#define ALPHA_MASK 0xFF000000
+#define RED_MASK 0x00FF0000
+#define GREEN_MASK 0x0000FF00
+#define BLUE_MASK 0x000000FF
+
+#define ALPHA_SHIFT 24
+#define RED_SHIFT 16
+#define GREEN_SHIFT 8
+#define BLUE_SHIFT 0
+
+#define AlphaByte(x) (((x))>>ALPHA_SHIFT)
+#define RedByte(x) (((x) & RED_MASK)>>RED_SHIFT)
+#define GreenByte(x) (((x) & GREEN_MASK)>>GREEN_SHIFT)
+#define BlueByte(x) (((x) & BLUE_MASK)>>BLUE_SHIFT)
+
+
+
+// files should be renamed from .DLL to .SVP
+
+#ifndef DLLEXPORT
+#define DLLEXPORT __declspec( dllexport )
+#endif
+
+
+#define VI_WAVEFORM 0x0001 // set if you need the waveform
+#define VI_SPECTRUM 0x0002 // set if you need the FFT values
+#define SONIQUEVISPROC 0x0004 // set if you want to allow Soniques user pref vis to affect your vis
+ // for example - blur, smoke and zoom
+
+#pragma pack (push, 8)
+
+typedef struct
+{
+ unsigned long MillSec; // Sonique sets this to the time stamp of end this block of data
+ unsigned char Waveform[2][512]; // Sonique sets this to the PCM data being outputted at this time
+ unsigned char Spectrum[2][256]; // Sonique sets this to a lowfidely version of the spectrum data
+ // being outputted at this time
+} VisData;
+
+typedef struct _VisInfo
+{
+ unsigned long Reserved; // Reserved
+
+ char *PluginName; // Set to the name of the plugin
+ long lRequired; // Which vis data this plugin requires (set to a combination of
+ // the VI_WAVEFORM, VI_SPECTRUM and SONIQEUVISPROC flags)
+
+ void (*Initialize)(void); // Called some time before your plugin is asked to render for
+ // the first time
+ BOOL (*Render)( unsigned long *Video, int width, int height, int pitch, VisData* pVD);
+ // Called for each frame. Pitch is in pixels and can be negative.
+ // Render like this:
+ // for (y = 0; y < height; y++)
+ // {
+ // for (x = 0; x < width; x++)
+ // Video[x] = <pixel value>;
+ // Video += pitch;
+ // }
+ // OR
+ // void PutPixel(int x, int y, unsigned long Pixel)
+ // {
+ // _ASSERT( x >= 0 && x < width && y >= 0 && y < height );
+ // Video[y*pitch+x] = Pixel;
+ // }
+ BOOL (*SaveSettings)( char* FileName );
+ // Use WritePrivateProfileString to save settings when this is called
+ // Example:
+ // WritePrivateProfileString("my plugin", "brightness", "3", FileName);
+ BOOL (*OpenSettings)( char* FileName );
+ // Use GetPrivateProfileString similarly:
+ // char BrightnessBuffer[256];
+ // GetPrivateProfileString("my plugin", "brightness", "3", BrightnessBuffer, sizeof(BrightnessBuffer), FileName);
+} VisInfo;
+
+#pragma pack (pop, 8)
+
+
+// DLL exports this function - it should return a pointer to a static structure
+// as above.
+extern "C"
+DLLEXPORT VisInfo* QueryModule(void);
+
diff --git a/Src/Plugins/Visualization/vis_avs/undo.cpp b/Src/Plugins/Visualization/vis_avs/undo.cpp
new file mode 100644
index 00000000..0010dcf1
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/undo.cpp
@@ -0,0 +1,177 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include "undo.h"
+#include "render.h"
+
+int C_UndoStack::list_pos;
+C_UndoItem *C_UndoStack::list[256];
+
+C_UndoItem::C_UndoItem() : data(NULL), length(0), isdirty(true)
+{
+}
+
+C_UndoItem::C_UndoItem(const C_UndoItem& T) : data(NULL), length(0), isdirty(true)
+{
+ *this = T;
+}
+
+C_UndoItem::C_UndoItem(void *_data, int _length, bool _isdirty) : data(NULL), length(length), isdirty(_isdirty)
+{
+ data = GlobalAlloc(GPTR, length);
+ memcpy(data, _data, length);
+}
+
+C_UndoItem::~C_UndoItem()
+{
+ if (data)
+ {
+ GlobalFree(data);
+ }
+}
+
+C_UndoItem & C_UndoItem::operator = (const C_UndoItem& T)
+{
+ length = T.length;
+ isdirty = T.isdirty;
+ if (data)
+ {
+ GlobalFree(data);
+ }
+ data = GlobalAlloc(GPTR, length);
+ memcpy(data, T.data, length);
+ return *this;
+}
+
+bool C_UndoItem::operator == (const C_UndoItem& T) const
+{
+ bool retval = false;
+ if (length == T.length)
+ {
+ retval = (memcmp(data, T.data, length) == 0);
+ }
+ return retval;
+}
+
+void C_UndoItem::set(void *_data, int _length, bool _isdirty)
+{
+ length = _length;
+ isdirty = _isdirty;
+ if (data)
+ {
+ GlobalFree(data);
+ }
+ data = GlobalAlloc(GPTR, length);
+ memcpy(data, _data, length);
+}
+
+
+void C_UndoStack::saveundo(int is2)
+{
+ // Save to the undo buffer (sets the dirty bit for this item)
+ C_UndoItem *item = new C_UndoItem;
+ C_UndoItem *old = list[list_pos];
+
+ if (is2)
+ {
+ g_render_effects2->__SavePresetToUndo(*item);
+ }
+ else
+ {
+ g_render_effects->__SavePresetToUndo(*item);
+ }
+
+ // Only add it to the stack if it has changed.
+ if (!old || !(*old == *item))
+ {
+ if (list_pos == sizeof(list)/sizeof(list[0])-1)
+ {
+ delete list[0];
+ memcpy(list,list+1,sizeof(list)/sizeof(list[0])-1);
+ list_pos--;
+ }
+ list[++list_pos]=item;
+ }
+ else delete item;
+}
+
+void C_UndoStack::cleardirty()
+{
+ // If we're clearing the dirty bit, we only clear it on the current item.
+ if (list_pos >= 0 && list_pos < sizeof(list)/sizeof(list[0]) && list[list_pos])
+ {
+ list[list_pos]->isdirty = 0;
+ }
+}
+
+bool C_UndoStack::isdirty()
+{
+ if (list_pos >= 0 && list_pos < sizeof(list)/sizeof(list[0]) && list[list_pos])
+ return list[list_pos]->isdirty;
+ return false;
+}
+
+int C_UndoStack::can_undo()
+{
+ return (list_pos>0 && list[list_pos-1]);
+}
+
+int C_UndoStack::can_redo()
+{
+ return list_pos < sizeof(list)/sizeof(list[0])-1 && list[list_pos+1];
+}
+
+
+void C_UndoStack::undo()
+{
+ if (list_pos>0 && list[list_pos-1])
+ {
+ g_render_transition->LoadPreset(NULL,0,list[--list_pos]);
+ }
+}
+
+void C_UndoStack::redo()
+{
+ if (list_pos < sizeof(list)/sizeof(list[0])-1 && list[list_pos+1])
+ {
+ g_render_transition->LoadPreset(NULL,0,list[++list_pos]);
+ }
+}
+
+void C_UndoStack::clear()
+{
+ list_pos=0;
+ int x;
+ for (x = 0; x < sizeof(list)/sizeof(list[0]); x ++)
+ {
+ delete list[x];
+ list[x]=0;
+ }
+}
diff --git a/Src/Plugins/Visualization/vis_avs/undo.h b/Src/Plugins/Visualization/vis_avs/undo.h
new file mode 100644
index 00000000..92bdb695
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/undo.h
@@ -0,0 +1,81 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _UNDO_H_
+#define _UNDO_H_
+
+class C_UndoStack;
+
+class C_UndoItem
+{
+ friend C_UndoStack;
+ public:
+ C_UndoItem();
+ ~C_UndoItem();
+ C_UndoItem(const C_UndoItem& T);
+ C_UndoItem(void *data, int length, bool isdirty);
+
+ C_UndoItem & operator = (const C_UndoItem& T);
+ bool operator == (const C_UndoItem& T) const;
+
+ void set(void *data, int length, bool isdirty);
+ void *get() const { return data; }
+ int size() const { return length; }
+
+ private:
+ void *data;
+ int length;
+ bool isdirty;
+};
+
+class C_UndoStack
+{
+ public:
+ static void saveundo(int is2=0);
+ static void cleardirty();
+ static bool isdirty();
+
+ static void undo();
+ static void redo();
+
+ static int can_undo();
+ static int can_redo();
+
+ static void clear();
+
+ private:
+
+ // sorry to do this mig, but that doubly linked lists made me scared. I think it
+ // wasn't actually the source of my bug (I later fixed it), but doubly linked lists
+ // are just plain hard to get right. :)
+ static int list_pos;
+ static C_UndoItem *list[256]; // only keep 256 elements in list at a time
+};
+
+#endif//_UNDO_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/util.cpp b/Src/Plugins/Visualization/vis_avs/util.cpp
new file mode 100644
index 00000000..03ffc769
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/util.cpp
@@ -0,0 +1,536 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include <commctrl.h>
+#include "r_defs.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+#if 0//syntax highlighting
+#include "compiler.h"
+#include "richedit.h"
+#endif
+
+char* GetTextResource(UINT id){
+ void* data = 0;
+ HRSRC rsrc = FindResource(WASABI_API_LNG_HINST,MAKEINTRESOURCE(id),"TEXT");
+ if(rsrc){
+ HGLOBAL resourceHandle = LoadResource(WASABI_API_LNG_HINST,rsrc);
+ data = LockResource(resourceHandle);
+ }
+ return (char*)data;
+}
+
+void loadComboBox(HWND dlg, char *ext, char *selectedName)
+{
+ char path[MAX_PATH];
+ int a;
+ HANDLE ff;
+ WIN32_FIND_DATA fd;
+
+ wsprintf(path,"%s\\%s",g_path,ext);
+
+ ff=FindFirstFile(path, &fd);
+ if (ff == INVALID_HANDLE_VALUE) return;
+
+ do
+ {
+ SendMessage(dlg, CB_ADDSTRING, 0, (LPARAM)(fd.cFileName));
+ } while (FindNextFile(ff, &fd));
+ FindClose(ff);
+
+ a = SendMessage(dlg, CB_FINDSTRINGEXACT, 0, (LPARAM)(selectedName));
+ if (a != CB_ERR) SendMessage(dlg, CB_SETCURSEL, (WPARAM) a, 0);
+}
+
+void GR_SelectColor(HWND hwnd, int *a)
+{
+ static COLORREF custcolors[16];
+ CHOOSECOLOR cs;
+ cs.lStructSize = sizeof(cs);
+ cs.hwndOwner = hwnd;
+ cs.hInstance = 0;
+ cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColor(&cs))
+ {
+ *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
+ }
+}
+
+void GR_DrawColoredButton(DRAWITEMSTRUCT *di, COLORREF color)
+{
+ color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
+
+ char wt[123];
+ HPEN hPen,hOldPen;
+ HBRUSH hBrush,hOldBrush;
+ hPen = (HPEN)GetStockObject(BLACK_PEN);
+ LOGBRUSH lb={BS_SOLID,color,0};
+ hBrush = CreateBrushIndirect(&lb);
+ hOldPen=(HPEN)SelectObject(di->hDC,hPen);
+ hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
+
+ Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
+
+ GetWindowText(di->hwndItem,wt,sizeof(wt));
+ SetBkColor(di->hDC,color);
+ SetTextColor(di->hDC,~color & 0xffffff);
+ DrawText(di->hDC,wt,-1,&di->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
+
+ DeleteObject(hBrush);
+ SelectObject(di->hDC,hOldPen);
+ SelectObject(di->hDC,hOldBrush);
+}
+
+static int m_help_lastpage=4;
+static char *m_localtext;
+static void _dosetsel(HWND hwndDlg)
+{
+ HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
+ int sel=TabCtrl_GetCurSel(tabwnd);
+ char *text="";
+
+ m_help_lastpage=sel;
+
+ if (sel == 0)
+
+/*
+ text="Many AVS effects allow you to write simple expressions to control\r\n"
+ "visualization. Here is a brief summary of how to write AVS code.\r\n"
+ "\r\n"
+ "Many aspects of AVS code are similar to C (including comments). "
+ "\r\n"
+ "You can create new variables just by using them, and you can read\r\n"
+ "and write predefined variables (of which each effect has its own)\r\n"
+ "to interact with the effect. Note that variables are all floating\r\n"
+ "point numbers (no strings), and the maximum length of a variable's\r\n"
+ "name is 8 characters (anything longer will be ignored.\r\n"
+ "\r\n"
+ "So, to create a variable, you can simply use it, for example:\r\n"
+ " x = 5;\r\n"
+ "\r\n"
+ "You can also use a variety of operators and math functions to\r\n"
+ "modify variables, see the Operators and Functions tabs above.\r\n"
+ "\r\n"
+ "Code can include C and C++ style comments:\r\n"
+ "\r\n"
+ "You can combine operators and functions into expressions, such\r\n"
+ "as:\r\n"
+ " x = 5 * cos(y) / 32.0; // this does some leetness right here\r\n"
+ "\r\n"
+ "You can use multiple expressions by seperating them with one or\r\n"
+ "more semicolons, for example:\r\n"
+ " x = x * 17.0; x = x / 5; y = pow(x,3.0);\r\n"
+ "\r\n"
+ "It is worth noting that extra whitespace (spaces, newlines) is\r\n"
+ "ignored, so if you need to space things out for clarity, you can.\r\n"
+ ;
+ else if (sel == 1)
+ text="The following operators are available:\r\n"
+ "=\r\n"
+ " assigns a value to a variable. \r\n"
+ " example: var=5;\r\n"
+ "\r\n"
+ "+\r\n"
+ " adds two values, returns the sum. \r\n"
+ " example: var=5+var2;\r\n"
+ "\r\n"
+ "-\r\n"
+ " subtracts two values, returns the difference. \r\n"
+ " example: var=5-var2;\r\n"
+ "\r\n"
+ "*\r\n"
+ " multiplies two values, returns the product. \r\n"
+ " example: var=5*var2;\r\n"
+ "\r\n"
+ "/\r\n"
+ " divides two values, returns the quotient. \r\n"
+ " example: var=5/var2;\r\n"
+ "\r\n"
+ "%\r\n"
+ " converts two values to integer, performs division, returns remainder\r\n"
+ " example: var=var2%5;\r\n"
+ "\r\n"
+ "|\r\n"
+ " converts two values to integer, returns bitwise OR of both values\r\n"
+ " example: var=var2|31;\r\n"
+ "\r\n"
+ "&\r\n"
+ " converts two values to integer, returns bitwise AND of both values\r\n"
+ " example: var=var2&31;\r\n"
+ "\r\n"
+ ;
+ else if (sel == 2)
+ text="Functions available from code:\r\n"
+ "abs(value)\r\n"
+ " = returns the absolute value of 'value'\r\n"
+ "\r\n"
+ "sin(value)\r\n"
+ " = returns the sine of the radian angle 'value'\r\n"
+ "\r\n"
+ "cos(value)\r\n"
+ " = returns the cosine of the radian angle 'value'\r\n"
+ "\r\n"
+ "tan(value)\r\n"
+ " = returns the tangent of the radian angle 'value'\r\n"
+ "\r\n"
+ "asin(value)\r\n"
+ " = returns the arcsine (in radians) of 'value'\r\n"
+ "\r\n"
+ "acos(value)\r\n"
+ " = returns the arccosine (in radians) of 'value'\r\n"
+ "\r\n"
+ "atan(value)\r\n"
+ " = returns the arctangent (in radians) of 'value'\r\n"
+ "\r\n"
+ "atan2(value,value2)\r\n"
+ " = returns the arctangent (in radians) of 'value'/'value2'\r\n"
+ "\r\n"
+ "sqr(value)\r\n"
+ " = returns the square of 'value'\r\n"
+ "\r\n"
+ "sqrt(value)\r\n"
+ " = returns the square root of 'value'\r\n"
+ "\r\n"
+ "invsqrt(value)\r\n"
+ " = returns the reciprocal of the square root of 'value' (1/sqrt(value))\r\n"
+ " (uses a fast approximation, may not always = 1/sqrt(value) :)\r\n"
+ "\r\n"
+ "pow(value,value2)\r\n"
+ " = returns 'value' to the power of 'value2'\r\n"
+ "\r\n"
+ "exp(value)\r\n"
+ " = returns e to the power of 'value'\r\n"
+ "\r\n"
+ "log(value)\r\n"
+ " = returns the log in base e of 'value'\r\n"
+ "\r\n"
+ "log10(value)\r\n"
+ " = returns the log in base 10 of 'value'\r\n"
+ "\r\n"
+ "floor(value)\r\n"
+ " = returns the largest integer less than or equal to 'value'\r\n"
+ "\r\n"
+ "ceil(value)\r\n"
+ " = returns the smallest integer greater than or equal to 'value'\r\n"
+ "\r\n"
+ "sign(value)\r\n"
+ " = returns the sign of 'value' (-1.0 or 1.0, or 0.0 or -0.0 for 0.0 or -0.0)\r\n"
+ "\r\n"
+ "min(value,value2)\r\n"
+ " = returns the smallest of 'value' and 'value2'\r\n"
+ "\r\n"
+ "max(var,var2)\r\n"
+ " = returns the greatest of 'value' and 'value2'\r\n"
+ "\r\n"
+ "sigmoid(value,value2)\r\n"
+ " = returns sigmoid function value of x='value' ('value2'=constraint)\r\n"
+ "\r\n"
+ "rand(value)\r\n"
+ " = returns a random integer between 0 and 'value'\r\n"
+ "\r\n"
+ "band(value,value2)\r\n"
+ " = returns a boolean AND of 'value' and 'value2'\r\n"
+ "\r\n"
+ "bor(value,value2)\r\n"
+ " = returns a boolean OR of 'value' and 'value2'\r\n"
+ "\r\n"
+ "bnot(value)\r\n"
+ " = returns a boolean NOT of 'value'\r\n"
+ "\r\n"
+ "if(condition,valtrue,valfalse)\r\n"
+ " = returns 'valtrue' if 'condition' is nonzero, returns 'valfalse' otherwise.\r\n"
+ " new in AVS 2.8+: only one of valtrue/valfalse is evaluated, depending on condition\r\n"
+ "\r\n"
+ "assign(dest, source)\r\n"
+ " = if 'dest' is a variable, assigns the value of 'source' to it. returns the value of 'source'.\r\n"
+ " a little trick: assign(if(v,a,b),1.0); is like if V is true, a=1.0, otherwise b=1.0. :)\r\n"
+ "\r\n"
+ "exec2(parm1, parm2)\r\n"
+ " = evaluates parm1, then parm2, and returns the value of parm2.\r\n"
+ "\r\n"
+ "equal(value,value2)\r\n"
+ " = returns 1.0 if 'value' is equal to 'value2', otherwise returns 0.0\r\n"
+ "\r\n"
+ "above(value,value2)\r\n"
+ " = returns 1.0 if 'value' is greater than 'value2', otherwise returns 0.0\r\n"
+ "\r\n"
+ "below(value,value2)\r\n"
+ " = returns 1.0 if 'value' is less than 'value2', otherwise returns 0.0\r\n"
+ "\r\n"
+ "getosc(band,width,channel)\r\n"
+ " = returns waveform data centered at 'band', (0..1), sampled 'width' (0..1) wide.\r\n"
+ " 'channel' can be: 0=center, 1=left, 2=right. return value is (-1..1)\r\n"
+ "\r\n"
+ "getspec(band,width,channel)\r\n"
+ " = returns spectrum data centered at 'band', (0..1), sampled 'width' (0..1) wide.\r\n"
+ " 'channel' can be: 0=center, 1=left, 2=right. return value is (0..1)\r\n"
+ "\r\n"
+ "gettime(start_time)\r\n"
+ " = returns time in seconds since start_time (start_time can be 0 for time since boot)\r\n"
+ " (start_time can be -1.0 for current play time in seconds\r\n"
+ " (start_time can be -2.0 for current play length in seconds\r\n"
+ "\r\n"
+ "getkbmouse(which_parm)\r\n"
+ " = returns information about the location and state of the keyboard or mouse\r\n"
+ " which_parm = 1: mouse X position (-1..1 is onscreen)\r\n"
+ " which_parm = 2: mouse Y position (-1..1 is onscreen)\r\n"
+ " which_parm = 3: mouse left button state (0 up, 1 down)\r\n"
+ " which_parm = 4: mouse right button state (0 up, 1 down)\r\n"
+ " which_parm = 5: mouse middle button state (0 up, 1 down)\r\n"
+ " which_parm > 5: (GetAsyncKeyState(which_parm)&0x8000)?1:0\r\n"
+ "\r\n"
+ "megabuf(index)\r\n"
+ " = can be used to get or set an item from the 1 million item temp buffer\r\n"
+ " to get, use: val=megabuf(index);\r\n"
+ " to set, use: assign(megabuf(index),val);\r\n"
+ "gmegabuf(index)\r\n"
+ " = can be used to get or set an item from the global 1 million item buffer\r\n"
+ " to get, use: val=gmegabuf(index);\r\n"
+ " to set, use: assign(gmegabuf(index),val);\r\n"
+ "\r\n"
+ "loop(count, statement)\r\n"
+ " = executes <statement> <count> times. count is evaluated once and clamped\r\n"
+ " to 0..4096. best used with exec2() and exec3() and assign(). Note that\r\n"
+ " the return value of loop() is undefined and should not be used.\r\n"
+ "\r\n"
+ ;
+ else if (sel == 3)
+ text="Constants\r\n"
+ " '$PI' can be used in place of '3.14159'\r\n"
+ " '$E' can be used in place of '2.71828'\r\n"
+ " '$PHI' can be used in place of '1.618033'\r\n"
+ " Numbers can be specified as integers or as floating point\r\n"
+ " (i.e. '5' or '5.0' or '5.00001')\r\n"
+
+ ;
+*/
+
+ text=GetTextResource(IDR_HELP_1);
+ else if (sel == 1)
+ text=GetTextResource(IDR_HELP_2);
+ else if (sel == 2)
+ text=GetTextResource(IDR_HELP_3);
+ else if (sel == 3)
+ text=GetTextResource(IDR_HELP_4);
+ else if (sel == 4 && m_localtext)
+ text=m_localtext;
+
+ SetDlgItemText(hwndDlg,IDC_EDIT1,text);
+}
+
+static BOOL CALLBACK evalHelpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEM item;
+ HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
+ item.mask=TCIF_TEXT;
+ item.pszText=WASABI_API_LNGSTRING(IDS_GENERAL);
+ TabCtrl_InsertItem(tabwnd,0,&item);
+ item.pszText=WASABI_API_LNGSTRING(IDS_OPERATORS);
+ TabCtrl_InsertItem(tabwnd,1,&item);
+ item.pszText=WASABI_API_LNGSTRING(IDS_FUNCTIONS);
+ TabCtrl_InsertItem(tabwnd,2,&item);
+ item.pszText=WASABI_API_LNGSTRING(IDS_CONSTANTS);
+ TabCtrl_InsertItem(tabwnd,3,&item);
+ // fucko: context specific stuff
+ m_localtext=0;
+ if (lParam)
+ {
+ item.pszText=(char *)lParam;
+ m_localtext=item.pszText + strlen(item.pszText)+1;
+ TabCtrl_InsertItem(tabwnd,4,&item);
+ }
+ else if (m_help_lastpage > 3) m_help_lastpage=0;
+
+ TabCtrl_SetCurSel(tabwnd,m_help_lastpage);
+ _dosetsel(hwndDlg);
+ }
+ return 0;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
+ EndDialog(hwndDlg,1);
+ return 0;
+ case WM_NOTIFY:
+ {
+ LPNMHDR p=(LPNMHDR) lParam;
+ if (p->idFrom == IDC_TAB1 && p->code == TCN_SELCHANGE) _dosetsel(hwndDlg);
+ }
+ return 0;
+ }
+ return 0;
+}
+
+void compilerfunctionlist(HWND hwndDlg, char *localinfo)
+{
+ WASABI_API_DIALOGBOXPARAM(IDD_EVAL_HELP,hwndDlg,evalHelpDlgProc, (LONG)localinfo);
+}
+
+
+
+#if 0//syntax highlighting
+// If you include richedit boxes, you need to load the richlib at the beginning:
+// HANDLE hRichLib = LoadLibrary("RICHED32.DLL");
+// When quitting:
+// FreeLibrary(hRichLib);
+
+
+#define M_WORD 1
+#define M_NUM 2
+#define M_COMM 3
+
+#define is_alpha(a) ((((a) >= 'A') && ((a) <= 'Z')) || (((a) >= 'a') && ((a) <= 'z')))
+#define is_num(a) (((a) >= '0') && ((a) <= '9'))
+
+#define is_op(a) (((a) == '=') || ((a) == '+') || ((a) == '-') || ((a) == '*') || ((a) == '/') || ((a) == '%'))
+
+
+// Colors for bracket pairs (loops around, ugly colors for now), can be any number of colors
+static int bcol[] = { RGB(192, 0, 0), RGB(64, 128, 128), RGB(128, 0, 255), RGB(128, 128, 255) };
+
+#define COLOR_COMMENT RGB(0, 128, 0)
+#define COLOR_FUNC RGB(0, 0, 192)
+#define COLOR_VAR RGB(96, 96, 96)
+#define COLOR_OP RGB(0, 0, 0)
+#define COLOR_NUMBER RGB(0, 0, 128)
+
+// Actual syntax highlighting
+// 'hwnd' is a richedit box, 'data' is the code of 'size' characters
+void doAVSEvalHighLight(HWND hwndDlg, UINT sub, char *data) {
+ int size=strlen(data);
+ HWND hwnd=GetDlgItem(hwndDlg,sub);
+ CHARRANGE cr, cro;
+
+ CHARFORMAT cf;
+ cf.cbSize = sizeof(CHARFORMAT);
+ cf.dwMask = CFM_COLOR;
+ cf.dwEffects = 0;
+
+ SendMessage(hwnd, WM_SETREDRAW, false, 0);
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&cro);
+ int mode = 0;
+ int pos = 0;
+ int brackets = 0;
+ for (int i = 0; i < size; ++i) {
+ if (mode == M_COMM) {
+ // We're inside a comment, check for its end
+ if ((data[i] == ';') || ((data[i] == '*') && ((i+1) < size) && (data[++i] == '/'))) {
+ mode = 0;
+ cf.crTextColor = COLOR_COMMENT;
+ cr.cpMin = pos;
+ cr.cpMax = i+1;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
+ SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ } else if (is_alpha(data[i]) || ((mode == M_WORD) && is_num(data[i]))) {
+ // Letter tokens (func calls, vars)
+ if (mode != M_WORD) {
+ // Enter word-mode if we haven't yet
+ mode = M_WORD;
+ pos = i;
+ }
+ // Stop condition
+ bool valid = (i != (size-1)); // Check if this isn't the last character
+ if (valid) {
+ valid = is_num(data[i+1]) || is_alpha(data[i+1]);
+ }
+ if (!valid) {
+ // We have reached the end of this word
+ cr.cpMin = pos;
+ cr.cpMax = i+1;
+ // Check if its a function
+ bool func = false;
+ for (int j = 0; j < (sizeof(fnTable) / sizeof(fnTable[0])); ++j) {
+ if ((i - pos + 1) == (signed)strlen(fnTable[j].name)) {
+ if (strnicmp(fnTable[j].name, &data[pos], strlen(fnTable[j].name)) == 0) {
+ func = true;
+ break;
+ }
+ }
+ }
+ cf.crTextColor = func ? COLOR_FUNC : COLOR_VAR;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
+ SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ } else if (is_op(data[i])) {
+ // This is an operator
+ mode = 0;
+ cf.crTextColor = COLOR_OP;
+ cr.cpMin = i;
+ cr.cpMax = i+1;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
+ SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ } else if ((data[i] & 0x80) || ((data[i] == '/') && ((i+1) < size) && (data[++i] == '*'))) {
+ // This is a comment marker, enter comment mode
+ mode = M_COMM;
+ pos = i;
+ } else if ((data[i] == '(') || (data[i] == ')') || (data[i] == ',')) {
+ // Reached brackets: we count them and color them in pairs
+ mode = 0;
+ if (data[i] == '(') ++brackets;
+ cf.crTextColor = bcol[brackets % (sizeof(bcol) / sizeof(bcol[0]))];
+ if (data[i] == ')') --brackets;
+ cr.cpMin = i;
+ cr.cpMax = i+1;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
+ SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ } else if (is_num(data[i]) || (data[i] == '.')) {
+ // constants
+ if (mode != M_NUM) {
+ pos = i;
+ mode = M_NUM;
+ }
+ // Stop condition
+ bool valid = (i != (size-1));
+ if (valid) {
+ valid = is_num(data[i+1]) || (data[i+1] == '.');
+ }
+ if (!valid) {
+ cf.crTextColor = COLOR_NUMBER;
+ cr.cpMin = pos;
+ cr.cpMax = i+1;
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
+ SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+ }
+ } else if (data[i] == ';') {
+ // Reset bracket count and mode for every statement.
+ mode = 0;
+ brackets = 0;
+ }
+ }
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cro);
+ SendMessage(hwnd, WM_SETREDRAW, true, 0);
+ InvalidateRect(hwnd, 0, true);
+}
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/version.rc2 b/Src/Plugins/Visualization/vis_avs/version.rc2
new file mode 100644
index 00000000..bedc24d5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/version.rc2
@@ -0,0 +1,40 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,9,3,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Advanced Visualization Studio"
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Visualization Plug-in"
+ VALUE "FileVersion", "2,9,3,0"
+ VALUE "InternalName", "Advanced Visualization Studio"
+ VALUE "LegalCopyright", "Copyright © 2001-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "vis_avs.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/Visualization/vis_avs/vis_Avs.dsw b/Src/Plugins/Visualization/vis_avs/vis_Avs.dsw
new file mode 100644
index 00000000..b469ac5f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/vis_Avs.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "vis_avs"=.\vis_avs.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Src/Plugins/Visualization/vis_avs/vis_avs.dsp b/Src/Plugins/Visualization/vis_avs/vis_avs.dsp
new file mode 100644
index 00000000..a4f0d111
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/vis_avs.dsp
@@ -0,0 +1,722 @@
+# Microsoft Developer Studio Project File - Name="vis_avs" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=vis_avs - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "vis_avs.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "vis_avs.mak" CFG="vis_avs - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "vis_avs - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "vis_avs - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "vis_avs - Win32 Laser Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "vis_avs - Win32 NoMMX Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""$/vis_avs", RDAAAAAA"
+# PROP Scc_LocalPath "."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "vis_avs - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G6 /MD /W3 /O2 /Ob2 /I "evallib/" /I "../Wasabi" /D "NDEBUG" /D "WA2_EMBED" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /FD /c
+# SUBTRACT CPP /Z<none> /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /map /machine:I386 /out:"c:\progra~1\winamp\plugins\vis_avs.dll"
+# SUBTRACT LINK32 /debug
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "evallib/" /D "_DEBUG" /D "WA2_EMBED" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /debug /machine:I386 /out:"c:\progra~1\winamp\plugins\vis_avs.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Laser Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "vis_avs___Win32_Laser_Release"
+# PROP BASE Intermediate_Dir "vis_avs___Win32_Laser_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "vis_avs___Win32_Laser_Release"
+# PROP Intermediate_Dir "vis_avs___Win32_Laser_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "evallib/" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "evallib/" /D "NDEBUG" /D "LASER" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "LASER"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /machine:I386 /out:"c:\program files\winamp\plugins\vis_avs.dll"
+# SUBTRACT BASE LINK32 /debug
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /machine:I386 /out:"c:\program files\winamp\plugins\vis_avs_laser.dll"
+# SUBTRACT LINK32 /debug
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 NoMMX Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "vis_avs___Win32_NoMMX_Release"
+# PROP BASE Intermediate_Dir "vis_avs___Win32_NoMMX_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "vis_avs___Win32_NoMMX_Release"
+# PROP Intermediate_Dir "vis_avs___Win32_NoMMX_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G6 /MT /W3 /GX /O2 /Ob2 /I "evallib/" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /G6 /MD /W3 /GX /O2 /Ob2 /I "evallib/" /D "NDEBUG" /D "NO_MMX" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VIS_PL_EXPORTS" /D "NSEEL_LOOPFUNC_SUPPORT" /D "AVS_MEGABUF_SUPPORT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /map /machine:I386 /out:"c:\progra~1\winamp\plugins\vis_avs.dll"
+# SUBTRACT BASE LINK32 /debug
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ddraw.lib vfw32.lib /nologo /dll /map /machine:I386 /out:"c:\progra~1\winamp\plugins\vis_avs.dll"
+# SUBTRACT LINK32 /debug
+
+!ENDIF
+
+# Begin Target
+
+# Name "vis_avs - Win32 Release"
+# Name "vis_avs - Win32 Debug"
+# Name "vis_avs - Win32 Laser Release"
+# Name "vis_avs - Win32 NoMMX Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Group "Renders"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\r_avi.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_blit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_blur.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bpm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bright.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bspin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_bump.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_chanshift.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_clear.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_colorfade.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_colorreduction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_comment.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_contrast.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dcolormod.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_ddm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dmove.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dotfnt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dotgrid.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_dotpln.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_fadeout.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_fastbright.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_grain.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_interf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_interleave.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_invert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_linemode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_mirror.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_mosaic.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_multidelay.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_multiplier.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_nfclr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_onetone.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_oscring.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_oscstar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_parts.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_picture.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_rotblit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_rotstar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_scat.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_shift.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_simple.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_sscope.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_stack.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_stars.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_svp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_timescope.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_trans.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_videodelay.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_water.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_waterbump.cpp
+# End Source File
+# End Group
+# Begin Group "EvalLib"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\avs_eelif.cpp
+
+!IF "$(CFG)" == "vis_avs - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Laser Release"
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 NoMMX Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\avs_eelif.h
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\megabuf.c"
+
+!IF "$(CFG)" == "vis_avs - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Laser Release"
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 NoMMX Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\ns-eel-addfuncs.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\ns-eel-int.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\ns-eel.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\nseel-caltab.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\nseel-cfunc.c"
+
+!IF "$(CFG)" == "vis_avs - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 Laser Release"
+
+!ELSEIF "$(CFG)" == "vis_avs - Win32 NoMMX Release"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\nseel-compiler.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\nseel-eval.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\nseel-lextab.c"
+# End Source File
+# Begin Source File
+
+SOURCE="..\ns-eel\nseel-yylex.c"
+# End Source File
+# End Group
+# Begin Group "Render utils"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\linedraw.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\matrix.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_list.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_list.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_transition.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_transition.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_unkn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\r_unkn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.cpp
+# End Source File
+# End Group
+# Begin Group "laser"
+
+# PROP Default_Filter ""
+# Begin Group "laser renders"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\laser\rl_beathold.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_bren.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_cones.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_line.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\rl_trans.cpp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\laser\laser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\laserline.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\laserline.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\ld32.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\Ld32.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\linelist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\laser\linelist.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\bpm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cfgwin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\draw.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\render.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rlib.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TIMING.C
+# End Source File
+# Begin Source File
+
+SOURCE=.\TIMING.H
+# End Source File
+# Begin Source File
+
+SOURCE=.\undo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\wnd.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\ape.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\bpm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\cfgwnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\draw.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\render.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\undo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\wnd.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=".\avs-hilited.png"
+# End Source File
+# Begin Source File
+
+SOURCE=".\avs-normal.png"
+# End Source File
+# Begin Source File
+
+SOURCE=".\avs-selected.png"
+# End Source File
+# Begin Source File
+
+SOURCE=.\bump_lig.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\color_mo.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\dyn_dist.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\dyn_move.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\dyn_shift.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\effect_l.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\help_1.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\help_2.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\help_3.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\help_4.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\movement.bin
+# End Source File
+# Begin Source File
+
+SOURCE=.\supersco.bin
+# End Source File
+# End Group
+# Begin Group "Text files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\vis_avs.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\whatsnew.txt
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/Src/Plugins/Visualization/vis_avs/vis_avs.sln b/Src/Plugins/Visualization/vis_avs/vis_avs.sln
new file mode 100644
index 00000000..d174dab0
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/vis_avs.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29509.3
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vis_avs", "vis_avs.vcxproj", "{8105B192-3D54-4D0F-A5CD-4EEFC869C4EF}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8105B192-3D54-4D0F-A5CD-4EEFC869C4EF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8105B192-3D54-4D0F-A5CD-4EEFC869C4EF}.Debug|Win32.Build.0 = Debug|Win32
+ {8105B192-3D54-4D0F-A5CD-4EEFC869C4EF}.Release|Win32.ActiveCfg = Release|Win32
+ {8105B192-3D54-4D0F-A5CD-4EEFC869C4EF}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {3490B70A-188B-4E5D-8B96-500B330A05DF}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/Visualization/vis_avs/vis_avs.txt b/Src/Plugins/Visualization/vis_avs/vis_avs.txt
new file mode 100644
index 00000000..2aed6cc4
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/vis_avs.txt
@@ -0,0 +1,228 @@
+
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+Nullsoft Advanced Visualization Studio (AVS) v2.0a4 README
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+TODO: write readme here :)
+
+Thanks to Paul Holden for the FunkyFX Firewurx APE
+
+Once you install this baby, fire up Winamp, open up the preferences
+(CTRL+P), go to the Plugins/Visualization section, and select
+Nullsoft AVS as the visualization plug-in. Hit start.
+
+Once the AVS opens, it will probably be showing a nice black output.
+To get AVS to display something more interesting, hit space, or right
+click in the black area and select a preset to load.
+
+If you want to create your own presets, click the left mouse button in
+the black area of the window to bring up the AVS Editor window.
+
+The editor lets you create new visuals by adding effects from your Effect
+Library (in the upper right) to the Active Effect list (on the left side).
+Once you've added effects, you can configure each effect by selecting them
+from the Active Effect list. You can also clear the list, or load or save
+the list to be loaded later as a preset.
+
+You can also configure some of AVS's settings by selecting items from the
+Settings section of the Editor.
+
+Hotkeys for main window:
+ * Any winamp key
+ * R toggles randomswitching
+ * F toggles fullscreen framerate counter
+ * Y and U cycle through presets in order
+ * Space goes to random preset
+ * Enter toggles fullscreen
+ * 0,1-9, F1-F10 load presets
+ * Ctrl+above save presets
+
+That's it for now, and enjoy!
+
+
+Version history:
+2.0a4:
+- auto fullscreen window resizing
+2.0a3:
+- updated fullscreen vis code to handle leaving fullscreen
+ unexpectedly better
+- made configwnd repopulation more robust
+- made transitions work when preinit is disabled and you just
+ started up
+2.0a2:
+- updated options of display/fullscreen/trans
+- added doublesize for windowed
+- added seperate opts for windowed/fullscreen for text
+- fixed bug in mosaic.
+2.0a1:
+- preinit of presets for better transitions
+- integrated laser support (built-time option)
+- changed name to 'Winamp AVS'
+- Improved SVP/UVS loading
+- Made superscope support 'red' 'green' and 'blue'
+
+1.5a6:
+- preset transitions, woohoo
+- yay
+
+1.5a4:
+- presets for superscope
+- more superscope options
+- made random preset loading on beat
+- bugfixes
+
+1.5a3:
+- line width option
+- ability to use buffer as alpha channel for blending sub-effects back in
+- tons more
+
+1.5a2:
+- deadbeef: cleanups
+- lone: adjustable blend for sub-effects
+
+1.5a1:
+- deadbeef: made new effect system completely hiererchical and scaleable.
+ reorganized code a lot. cleaned things up. made it nice.
+
+1.0a53:
+- deadbeef: superscope effect
+ made it save to plugins\vis_avs.dat, instead.
+
+a52:
+- deadbeef: optimized/simplified evallib. made it limited to 8 char variable names,
+ 32 variables max.
+ improved ddm effect.
+ improved color clip effect
+
+a51:
+- deadbeef: optimized mosaic, grain, brightness, and bump effects
+ optimized and added more functionality to interleave effect
+- lone : clear - fixed 'first frame only'
+ eval - added sigmoid, sign, max, min, rand, band, bor, bnot, if, equal, above, below
+ ddm - added code for init and beat
+ bump - added 'bi' var to control bump intensity thru exps.
+ - added depth source
+ clear - fixed 'first frame only' (again)
+ onbeat clear - fixed 'skip n beats' which was not saved
+- ron : picture - fixed picture border bugs when aspect ratio was on
+
+a50:
+- deadbeef: added subtractive blend, every other line blend to stack
+ fixed window-no-erase bug.
+ added new dynamic distance modifier effect
+ added 'go' button to fullscreen options
+ added wait for retrace options
+ revised logarithmic spectrum scaling table
+- ron: better no-minimize-on-winamp (now displays a separate window in taskman)
+- lone : bpm - better out of range detection in average calculation
+ - better confidence calculation
+ - added option to predict beats only if bpm has been found
+ - fixed relearn/adapt on new song option
+ - fixed unwanted resets when using 'don't minimize avs when minimizing winamp' option
+ brightness - now works actually like a brightness filter (bit slower tho)
+ text - fixed crash when window is smaller than width/height of text and random mode was checked
+ bump - added invert depth
+ - fixed exclusive use of eval lib, was choking with misc trans/custom
+ or additional bump effects, now saves/restores vars in a clean way.
+ - changed 0-100 range to 0-1 which is much easier to use with math exps
+ (for backward compatibility, old settings are still using the old range)
+
+a49:
+
+- ron: added transparency settings (win2k only).
+ added AVI and Water Bump effects.
+ settings are now drageable (fixed).
+ deleting a setting now doesn't loose selection.
+ evallib now works when AVS is compiled in debug mode.
+ added "don't minimize avs with winamp" setting in Display tab.
+ added BMP Picture rendering.
+- lone: disabled resize in fullscreen mode, fixes directx lockups
+ added Custom BPM filter
+ fixed stuck moving particles when no beat occurs for a long time
+ fixed random word option in text renderer
+ added beat learning - fixed broken version, now better than ever :>
+ added option to dock AVS into litestep's wharfamp window :)
+- deadbeef: restyled editor.
+ made rotation switching variable in rotoblitter, and onbeat zoom changes
+ made loading/saving of unsupported effects/ape's better
+ fixed text drawing bugs.
+ fixed fullscreen-when-no-mode-selected, and made it verify video modes
+ made skin change detection
+ added vertical blank wait options
+ fixed rotoblitter crashing effect
+ tons of other stuff.
+
+
+
+a46: more effects, etc from lone/ron. Improved main interface.
+ a few small bugfixes.
+a44: crashing bugfixes. border drawing bugfixes.
+a43: skinnability. Put the avs.bmp in the skin directory.
+ avs.bmp.
+a42: improved mirror effect. Misc trans now has mixed mapping mode
+ (onbeat changes). should either have fixed or broken coming out
+ of fullscreen modes. Fixed a few cosmetic bugs.
+a41: added lone's mirror effect.
+a40: comment bugfix, lone's effects, MUCH better beat detection
+a39: source mapping translation mode. Fadeto has color to fade to.
+a38: clone button. One level of presets directories allowed. Lets
+ you select a preset directory to pull random/cycles from.
+ Neato.
+a37: comment thingy. Status line. More improvements. No more keyboard
+ controls for config, though :(
+a36: optimized colorfade, moving particle is nicer circle, water effect,
+ little cleanups, AVS editor now in own thread, keyboard controls
+ work better, etc etc .
+a35: more blur options, more presets, new APE module (FyreWurx)
+a33: ultra-fast expression eval. test those custom trantabs to make sure they didn't break.
+a32: unfucks blur for older presets
+a31: dot fountain, baby.
+a30: made effects alpha-channel-safe, made random switching adjustable,
+ a lot of little tastey cleanups, etc.
+a29: nifty-ass framebuffer saving/restoring effect
+a28: adjustable CPU usage. better beat detection stuff. etc.
+a26: new effect (dot grid), widescreen fullscreen modes, etc.
+a25: bugfixes, you can now drop .avs's into the window, etc.
+a24: much better custom transtab stuff (thanks, LONE, not lore. no
+ offense, lore, though :)
+a23: custom transtabs much faster. buggier, though. will be fixed soon.
+ lone owns. :)
+a22: higher framerate, custom transtabs, more effects, etc.
+a21 adds new "Scatter" effect
+a20 adds DLL effect loading (APE)
+a18 fixes close-winamp die bug.
+a18 speeds up colorfade (all table driven)
+a17 fixes win2k fullscreen issues (afaik)
+a16 adds some fixes, and new winamp styled window
+
+and before:
+
+Started out as wVis 5.0. Started out pretty lame. \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj b/Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj
new file mode 100644
index 00000000..356ca61e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj
@@ -0,0 +1,814 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8105B192-3D54-4D0F-A5CD-4EEFC869C4EF}</ProjectGuid>
+ <RootNamespace>vis_avs</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;evallib;..\..\..\Wasabi;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;UNICODE;WA2_EMBED;WIN32;_WINDOWS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;_CRT_SECURE_NO_WARNINGS;NO_X86ASM;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4302;4799;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;ddraw.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+ <GenerateMapFile>true</GenerateMapFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>.;evallib;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;UNICODE;WA2_EMBED;WIN32;_WINDOWS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;_CRT_SECURE_NO_WARNINGS;NO_X86ASM;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4302;4799;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;ddraw.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(OutDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+ <GenerateMapFile>true</GenerateMapFile>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>.;evallib;..\..\..\Wasabi;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;UNICODE;WA2_EMBED;WIN32;_WINDOWS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;_CRT_SECURE_NO_WARNINGS;NO_X86ASM;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4302;4799;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;ddraw.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>.;evallib;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;UNICODE;WA2_EMBED;WIN32;_WINDOWS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;_CRT_SECURE_NO_WARNINGS;NO_X86ASM;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4302;4799;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>odbc32.lib;odbccp32.lib;ddraw.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\ns-eel2\y.tab.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-caltab.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-cfunc.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-compiler.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-eval.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-lextab.c" />
+ <ClCompile Include="..\..\..\ns-eel2\nseel-ram.c" />
+ <ClCompile Include="avs_eelif.cpp" />
+ <ClCompile Include="bpm.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="cfgwin.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="draw.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;NO_X86ASM;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;NO_X86ASM;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;NO_X86ASM;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT;NO_X86ASM;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\laser.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\laserline.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\ld32.c">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\linelist.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\rl_beathold.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\rl_bren.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\rl_cones.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\rl_line.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="laser\rl_trans.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="linedraw.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="matrix.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="render.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="rlib.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_avi.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_blit.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_blur.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_bpm.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_bright.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_bspin.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_bump.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_chanshift.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_clear.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_colorfade.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_colorreduction.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_comment.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_contrast.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_dcolormod.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_ddm.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_dmove.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_dotfnt.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_dotgrid.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_dotpln.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_fadeout.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_fastbright.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_grain.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_interf.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_interleave.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_invert.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_linemode.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_list.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_mirror.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_mosaic.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_multidelay.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_multiplier.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_nfclr.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_onetone.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_oscring.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_oscstar.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_parts.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_picture.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_rotblit.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_rotstar.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_scat.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_shift.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_simple.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_sscope.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_stack.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_stars.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_svp.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_text.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_timescope.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_trans.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_transition.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_unkn.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_videodelay.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_water.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="r_waterbump.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="TIMING.C">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="undo.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="util.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="wnd.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WA2_EMBED;WIN32;_WINDOWS;_MBCS;_USRDLL;VIS_PL_EXPORTS;NSEEL_LOOPFUNC_SUPPORT;AVS_MEGABUF_SUPPORT</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-addfuncs.h" />
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-int.h" />
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel.h" />
+ <ClInclude Include="..\..\..\ns-eel2\glue_x86.h" />
+ <ClInclude Include="ape.h" />
+ <ClInclude Include="avs_eelif.h" />
+ <ClInclude Include="bpm.h" />
+ <ClInclude Include="cfgwnd.h" />
+ <ClInclude Include="draw.h" />
+ <ClInclude Include="laser\laserline.h" />
+ <ClInclude Include="laser\Ld32.h" />
+ <ClInclude Include="laser\linelist.h" />
+ <ClInclude Include="render.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="rlib.h" />
+ <ClInclude Include="r_defs.h" />
+ <ClInclude Include="r_list.h" />
+ <ClInclude Include="r_transition.h" />
+ <ClInclude Include="r_unkn.h" />
+ <ClInclude Include="TIMING.H" />
+ <ClInclude Include="undo.h" />
+ <ClInclude Include="wnd.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="vis_avs.txt" />
+ <Text Include="whatsnew.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="bump_lig.bin" />
+ <None Include="color_mo.bin" />
+ <None Include="dyn_dist.bin" />
+ <None Include="dyn_move.bin" />
+ <None Include="dyn_shift.bin" />
+ <None Include="effect_l.bin" />
+ <None Include="help_1.bin" />
+ <None Include="help_2.bin" />
+ <None Include="help_3.bin" />
+ <None Include="help_4.bin" />
+ <None Include="movement.bin" />
+ <None Include="supersco.bin" />
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="avs-hilited.png" />
+ <Image Include="avs-normal.png" />
+ <Image Include="avs-selected.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\tataki\tataki.vcxproj">
+ <Project>{255b68b5-7ef8-45ef-a675-2d6b88147909}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\WAT\WAT.vcxproj">
+ <Project>{c5714908-a71f-4644-bd95-aad8ee7914da}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj.filters b/Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj.filters
new file mode 100644
index 00000000..1d5d93a5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/vis_avs.vcxproj.filters
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="avs_eelif.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="bpm.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="cfgwin.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="draw.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\laser.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\laserline.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\ld32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="linedraw.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\linelist.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="matrix.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_avi.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_blit.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_blur.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_bpm.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_bright.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_bspin.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_bump.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_chanshift.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_clear.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_colorfade.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_colorreduction.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_comment.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_contrast.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_dcolormod.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_ddm.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_dmove.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_dotfnt.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_dotgrid.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_dotpln.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_fadeout.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_fastbright.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_grain.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_interf.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_interleave.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_invert.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_linemode.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_list.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_mirror.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_mosaic.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_multidelay.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_multiplier.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_nfclr.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_onetone.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_oscring.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_oscstar.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_parts.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_picture.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_rotblit.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_rotstar.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_scat.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_shift.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_simple.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_sscope.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_stack.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_stars.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_svp.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_text.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_timescope.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_trans.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_transition.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_videodelay.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_unkn.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_water.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="r_waterbump.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="render.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\rl_beathold.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\rl_bren.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\rl_cones.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\rl_line.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="laser\rl_trans.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="rlib.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="TIMING.C">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="undo.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="util.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wnd.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-caltab.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-cfunc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-compiler.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-eval.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-lextab.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\nseel-ram.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\ns-eel2\y.tab.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ape.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="avs_eelif.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="bpm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="cfgwnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="draw.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="laser\laserline.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="laser\Ld32.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="laser\linelist.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="r_defs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="r_list.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="r_transition.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="r_unkn.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="render.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="rlib.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="TIMING.H">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="undo.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="wnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\glue_x86.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-addfuncs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\ns-eel2\ns-eel-int.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="avs-hilited.png">
+ <Filter>Image Files</Filter>
+ </Image>
+ <Image Include="avs-normal.png">
+ <Filter>Image Files</Filter>
+ </Image>
+ <Image Include="avs-selected.png">
+ <Filter>Image Files</Filter>
+ </Image>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="bump_lig.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="color_mo.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="dyn_dist.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="dyn_move.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="dyn_shift.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="effect_l.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="help_1.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="help_2.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="help_3.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="help_4.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="movement.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ <None Include="supersco.bin">
+ <Filter>Bin Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="vis_avs.txt" />
+ <Text Include="whatsnew.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{0c48c00b-88c3-4d28-8885-18c16c3cd71f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{0602e4a3-e8f4-495f-baaa-fa3612b2a340}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{ac7b0822-e89e-4c0c-b819-1bac21bf5c49}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Image Files">
+ <UniqueIdentifier>{e7728cec-04d3-427a-bad9-aa1be3e625c9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Bin Files">
+ <UniqueIdentifier>{1a8c5984-38ed-45af-9ff5-e097cc54fd83}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/wa_ipc.h b/Src/Plugins/Visualization/vis_avs/wa_ipc.h
new file mode 100644
index 00000000..1efc7950
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/wa_ipc.h
@@ -0,0 +1,1127 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _WA_IPC_H_
+#define _WA_IPC_H_
+
+/*
+** This is the modern replacement for the classic 'frontend.h'. Most of these
+** updates are designed for in-process use, i.e. from a plugin.
+**
+*/
+
+/* message used to sent many messages to winamp's main window.
+** most all of the IPC_* messages involve sending the message in the form of:
+** result = SendMessage(hwnd_winamp,WM_WA_IPC,(parameter),IPC_*);
+*/
+#define WM_WA_IPC WM_USER
+/* but some of them use WM_COPYDATA. be afraid.
+*/
+
+#define IPC_GETVERSION 0
+/* int version = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVERSION);
+**
+** Version will be 0x20yx for winamp 2.yx. versions previous to Winamp 2.0
+** typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know.
+*/
+
+#define IPC_GETREGISTEREDVERSION 770
+
+
+typedef struct {
+ char *filename;
+ char *title;
+ int length;
+} enqueueFileWithMetaStruct; // send this to a IPC_PLAYFILE in a non WM_COPYDATA,
+// and you get the nice desired result. if title is NULL, it is treated as a "thing",
+// otherwise it's assumed to be a file (for speed)
+
+#define IPC_PLAYFILE 100 // dont be fooled, this is really the same as enqueufile
+#define IPC_ENQUEUEFILE 100
+/* sent as a WM_COPYDATA, with IPC_PLAYFILE as the dwData, and the string to play
+** as the lpData. Just enqueues, does not clear the playlist or change the playback
+** state.
+*/
+
+
+#define IPC_DELETE 101
+#define IPC_DELETE_INT 1101 // don't use this, it's used internally by winamp when
+ // dealing with some lame explorer issues.
+/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
+** Use IPC_DELETE to clear Winamp's internal playlist.
+*/
+
+
+#define IPC_STARTPLAY 102 // starts playback. almost like hitting play in Winamp.
+#define IPC_STARTPLAY_INT 1102 // used internally, don't bother using it (won't be any fun)
+
+
+#define IPC_CHDIR 103
+/* sent as a WM_COPYDATA, with IPC_CHDIR as the dwData, and the directory to change to
+** as the lpData.
+*/
+
+
+#define IPC_ISPLAYING 104
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISPLAYING);
+** If it returns 1, it is playing. if it returns 3, it is paused,
+** if it returns 0, it is not playing.
+*/
+
+
+#define IPC_GETOUTPUTTIME 105
+/* int res = SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETOUTPUTTIME);
+** returns the position in milliseconds of the current track (mode = 0),
+** or the track length, in seconds (mode = 1). Returns -1 if not playing or error.
+*/
+
+
+#define IPC_JUMPTOTIME 106
+/* (requires Winamp 1.60+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,ms,IPC_JUMPTOTIME);
+** IPC_JUMPTOTIME sets the position in milliseconds of the
+** current song (approximately).
+** Returns -1 if not playing, 1 on eof, or 0 if successful
+*/
+
+#define IPC_GETMODULENAME 109
+#define IPC_EX_ISRIGHTEXE 666
+/* usually shouldnt bother using these, but here goes:
+** send a WM_COPYDATA with IPC_GETMODULENAME, and an internal
+** flag gets set, which if you send a normal WM_WA_IPC message with
+** IPC_EX_ISRIGHTEXE, it returns whether or not that filename
+** matches. lame, I know.
+*/
+
+#define IPC_WRITEPLAYLIST 120
+/* (requires Winamp 1.666+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
+**
+** IPC_WRITEPLAYLIST writes the current playlist to <winampdir>\\Winamp.m3u,
+** and returns the current playlist position.
+** Kinda obsoleted by some of the 2.x new stuff, but still good for when
+** using a front-end (instead of a plug-in)
+*/
+
+
+#define IPC_SETPLAYLISTPOS 121
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
+** IPC_SETPLAYLISTPOS sets the playlist position to 'position'. It
+** does not change playback or anything, it just sets position, and
+** updates the view if necessary
+*/
+
+
+#define IPC_SETVOLUME 122
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
+** IPC_SETVOLUME sets the volume of Winamp (from 0-255).
+*/
+
+
+#define IPC_SETPANNING 123
+/* (requires Winamp 2.0+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,panning,IPC_SETPANNING);
+** IPC_SETPANNING sets the panning of Winamp (from 0 (left) to 255 (right)).
+*/
+
+
+#define IPC_GETLISTLENGTH 124
+/* (requires Winamp 2.0+)
+** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
+** IPC_GETLISTLENGTH returns the length of the current playlist, in
+** tracks.
+*/
+
+
+#define IPC_GETLISTPOS 125
+/* (requires Winamp 2.05+)
+** int pos=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTPOS);
+** IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST
+** only faster since it doesn't have to write out the list. Heh, silly me.
+*/
+
+
+#define IPC_GETINFO 126
+/* (requires Winamp 2.05+)
+** int inf=SendMessage(hwnd_winamp,WM_WA_IPC,mode,IPC_GETINFO);
+** IPC_GETINFO returns info about the current playing song. The value
+** it returns depends on the value of 'mode'.
+** Mode Meaning
+** ------------------
+** 0 Samplerate (i.e. 44100)
+** 1 Bitrate (i.e. 128)
+** 2 Channels (i.e. 2)
+** 3 (5+) Video LOWORD=w HIWORD=h
+** 4 (5+) > 65536, string (video description)
+*/
+
+
+#define IPC_GETEQDATA 127
+/* (requires Winamp 2.05+)
+** int data=SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** IPC_GETEQDATA queries the status of the EQ.
+** The value returned depends on what 'pos' is set to:
+** Value Meaning
+** ------------------
+** 0-9 The 10 bands of EQ data. 0-63 (+20db - -20db)
+** 10 The preamp value. 0-63 (+20db - -20db)
+** 11 Enabled. zero if disabled, nonzero if enabled.
+** 12 Autoload. zero if disabled, nonzero if enabled.
+*/
+
+
+#define IPC_SETEQDATA 128
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,pos,IPC_GETEQDATA);
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SETEQDATA);
+** IPC_SETEQDATA sets the value of the last position retrieved
+** by IPC_GETEQDATA. This is pretty lame, and we should provide
+** an extended version that lets you do a MAKELPARAM(pos,value).
+** someday...
+
+ new (2.92+):
+ if the high byte is set to 0xDB, then the third byte specifies
+ which band, and the bottom word specifies the value.
+*/
+
+#define IPC_ADDBOOKMARK 129
+/* (requires Winamp 2.4+)
+** Sent as a WM_COPYDATA, using IPC_ADDBOOKMARK, adds the specified
+** file/url to the Winamp bookmark list.
+*/
+/*
+In winamp 5+, we use this as a normal WM_WA_IPC and the string:
+
+ "filename\0title\0"
+
+ to notify the library/bookmark editor that a bookmark
+was added. Note that using this message in this context does not
+actually add the bookmark.
+do not use :)
+*/
+
+
+#define IPC_INSTALLPLUGIN 130
+/* not implemented, but if it was you could do a WM_COPYDATA with
+** a path to a .wpz, and it would install it.
+*/
+
+
+#define IPC_RESTARTWINAMP 135
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_RESTARTWINAMP);
+** IPC_RESTARTWINAMP will restart Winamp (isn't that obvious ? :)
+*/
+
+
+#define IPC_ISFULLSTOP 400
+/* (requires winamp 2.7+ I think)
+** ret=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISFULLSTOP);
+** useful for when you're an output plugin, and you want to see
+** if the stop/close is a full stop, or just between tracks.
+** returns nonzero if it's full, zero if it's just a new track.
+*/
+
+
+#define IPC_INETAVAILABLE 242
+/* (requires Winamp 2.05+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INETAVAILABLE);
+** IPC_INETAVAILABLE will return 1 if the Internet connection is available for Winamp.
+*/
+
+
+#define IPC_UPDTITLE 243
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_UPDTITLE);
+** IPC_UPDTITLE will ask Winamp to update the informations about the current title.
+*/
+
+
+#define IPC_REFRESHPLCACHE 247
+/* (requires Winamp 2.2+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REFRESHPLCACHE);
+** IPC_REFRESHPLCACHE will flush the playlist cache buffer.
+** (send this if you want it to go refetch titles for tracks)
+*/
+
+
+#define IPC_GET_SHUFFLE 250
+/* (requires Winamp 2.4+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE);
+**
+** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set)
+*/
+
+
+#define IPC_GET_REPEAT 251
+/* (requires Winamp 2.4+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT);
+**
+** IPC_GET_REPEAT returns the status of the Repeat option (1 if set)
+*/
+
+
+#define IPC_SET_SHUFFLE 252
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE);
+**
+** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on)
+*/
+
+
+#define IPC_SET_REPEAT 253
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT);
+**
+** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on)
+*/
+
+
+#define IPC_ENABLEDISABLE_ALL_WINDOWS 259 // 0xdeadbeef to disable
+/* (requires Winamp 2.9+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,enable?0:0xdeadbeef,IPC_MBOPENREAL);
+** sending with 0xdeadbeef as the param disables all winamp windows,
+** any other values will enable all winamp windows.
+*/
+
+
+#define IPC_GETWND 260
+/* (requires Winamp 2.9+)
+** HWND h=SendMessage(hwnd_winamp,WM_WA_IPC,IPC_GETWND_xxx,IPC_GETWND);
+** returns the HWND of the window specified.
+*/
+ #define IPC_GETWND_EQ 0 // use one of these for the param
+ #define IPC_GETWND_PE 1
+ #define IPC_GETWND_MB 2
+ #define IPC_GETWND_VIDEO 3
+#define IPC_ISWNDVISIBLE 261 // same param as IPC_GETWND
+
+
+
+
+/************************************************************************
+***************** in-process only (WE LOVE PLUGINS)
+************************************************************************/
+
+
+#define IPC_SETSKIN 200
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
+** IPC_SETSKIN sets the current skin to "skinname". Note that skinname
+** can be the name of a skin, a skin .zip file, with or without path.
+** If path isn't specified, the default search path is the winamp skins
+** directory.
+*/
+
+
+#define IPC_GETSKIN 201
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)skinname_buffer,IPC_GETSKIN);
+** IPC_GETSKIN puts the directory where skin bitmaps can be found
+** into skinname_buffer.
+** skinname_buffer must be MAX_PATH characters in length.
+** When using a .zip'd skin file, it'll return a temporary directory
+** where the ZIP was decompressed.
+*/
+
+
+#define IPC_EXECPLUG 202
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"vis_file.dll",IPC_EXECPLUG);
+** IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
+** the format of this string can be:
+** "vis_whatever.dll"
+** "vis_whatever.dll,0" // (first mod, file in winamp plug-in dir)
+** "C:\\dir\\vis_whatever.dll,1"
+*/
+
+
+#define IPC_GETPLAYLISTFILE 211
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
+** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETPLAYLISTTITLE 212
+/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
+** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
+**
+** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
+** returns a pointer to it. returns NULL on error.
+*/
+
+
+#define IPC_GETHTTPGETTER 240
+/* retrieves a function pointer to a HTTP retrieval function.
+** if this is unsupported, returns 1 or 0.
+** the function should be:
+** int (*httpRetrieveFile)(HWND hwnd, char *url, char *file, char *dlgtitle);
+** if you call this function, with a parent window, a URL, an output file, and a dialog title,
+** it will return 0 on successful download, 1 on error.
+*/
+
+
+#define IPC_MBOPEN 241
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_MBOPEN);
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPEN);
+** IPC_MBOPEN will open a new URL in the minibrowser. if url is NULL, it will open the Minibrowser window.
+*/
+
+
+
+#define IPC_CHANGECURRENTFILE 245
+/* (requires Winamp 2.05+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILE);
+** IPC_CHANGECURRENTFILE will set the current playlist item.
+*/
+
+
+#define IPC_GETMBURL 246
+/* (requires Winamp 2.2+)
+** char buffer[4096]; // Urls can be VERY long
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)buffer,IPC_GETMBURL);
+** IPC_GETMBURL will retrieve the current Minibrowser URL into buffer.
+** buffer must be at least 4096 bytes long.
+*/
+
+
+#define IPC_MBBLOCK 248
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_MBBLOCK);
+**
+** IPC_MBBLOCK will block the Minibrowser from updates if value is set to 1
+*/
+
+#define IPC_MBOPENREAL 249
+/* (requires Winamp 2.4+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPENREAL);
+**
+** IPC_MBOPENREAL works the same as IPC_MBOPEN except that it will works even if
+** IPC_MBBLOCK has been set to 1
+*/
+
+#define IPC_ADJUST_OPTIONSMENUPOS 280
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_OPTIONSMENUPOS);
+** moves where winamp expects the Options menu in the main menu. Useful if you wish to insert a
+** menu item above the options/skins/vis menus.
+*/
+
+#define IPC_GET_HMENU 281
+/* (requires Winamp 2.9+)
+** HMENU hMenu=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
+** values for data:
+** 0 : main popup menu
+** 1 : main menubar file menu
+** 2 : main menubar options menu
+** 3 : main menubar windows menu
+** 4 : main menubar help menu
+** other values will return NULL.
+*/
+
+#define IPC_GET_EXTENDED_FILE_INFO 290 //pass a pointer to the following struct in wParam
+#define IPC_GET_EXTENDED_FILE_INFO_HOOKABLE 296
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to query, and ret to a buffer, with retlen to the
+** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_GET_EXTENDED_FILE_INFO);
+** the results should be in the buffer pointed to by ret.
+** returns 1 if the decoder supports a getExtendedFileInfo method
+*/
+typedef struct {
+ char *filename;
+ char *metadata;
+ char *ret;
+ int retlen;
+} extendedFileInfoStruct;
+
+#define IPC_GET_BASIC_FILE_INFO 291 //pass a pointer to the following struct in wParam
+typedef struct {
+ char *filename;
+
+ int quickCheck; // set to 0 to always get, 1 for quick, 2 for default (if 2, quickCheck will be set to 0 if quick wasnot used)
+
+ // filled in by winamp
+ int length;
+ char *title;
+ int titlelen;
+} basicFileInfoStruct;
+
+#define IPC_GET_EXTLIST 292 //returns doublenull delimited. GlobalFree() it when done. if data is 0, returns raw extlist, if 1, returns something suitable for getopenfilename
+
+#define IPC_INFOBOX 293
+typedef struct {
+ HWND parent;
+ char *filename;
+} infoBoxParam;
+
+#define IPC_SET_EXTENDED_FILE_INFO 294 //pass a pointer to the a extendedFileInfoStruct in wParam
+/* (requires Winamp 2.9+)
+** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
+** filename and metadata field you wish to write in ret. (retlen is not used). and then
+** SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_SET_EXTENDED_FILE_INFO);
+** returns 1 if the metadata is supported
+** Call IPC_WRITE_EXTENDED_FILE_INFO once you're done setting all the metadata you want to update
+*/
+
+#define IPC_WRITE_EXTENDED_FILE_INFO 295
+/* (requires Winamp 2.9+)
+** writes all the metadata set thru IPC_SET_EXTENDED_FILE_INFO to the file
+** returns 1 if the file has been successfully updated, 0 if error
+*/
+
+#define IPC_FORMAT_TITLE 297
+typedef struct
+{
+ char *spec; // NULL=default winamp spec
+ void *p;
+
+ char *out;
+ int out_len;
+
+ char * (*TAGFUNC)(char * tag, void * p); //return 0 if not found
+ void (*TAGFREEFUNC)(char * tag,void * p);
+} waFormatTitle;
+
+#define IPC_GETUNCOMPRESSINTERFACE 331
+/* returns a function pointer to uncompress().
+** int (*uncompress)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen);
+** right out of zlib, useful for decompressing zlibbed data.
+** if you pass the parm of 0x10100000, it will return a wa_inflate_struct * to an inflate API.
+*/
+
+typedef struct {
+ int (*inflateReset)(void *strm);
+ int (*inflateInit_)(void *strm,const char *version, int stream_size);
+ int (*inflate)(void *strm, int flush);
+ int (*inflateEnd)(void *strm);
+ unsigned long (*crc32)(unsigned long crc, const unsigned char *buf, unsigned int len);
+} wa_inflate_struct;
+
+
+#define IPC_ADD_PREFS_DLG 332
+#define IPC_REMOVE_PREFS_DLG 333
+/* (requires Winamp 2.9+)
+** to use, allocate a prefsDlgRec structure (either on the heap or some global
+** data, but NOT on the stack), initialze the members:
+** hInst to the DLL instance where the resource is located
+** dlgID to the ID of the dialog,
+** proc to the window procedure for the dialog
+** name to the name of the prefs page in the prefs.
+** where to 0 (eventually we may add more options)
+** then, SendMessage(hwnd_winamp,WM_WA_IPC,&prefsRec,IPC_ADD_PREFS_DLG);
+**
+** you can also IPC_REMOVE_PREFS_DLG with the address of the same prefsRec,
+** but you shouldn't really ever have to.
+**
+*/
+#define IPC_OPENPREFSTOPAGE 380 // pass an id of a builtin page, or a &prefsDlgRec of prefs page to open
+
+typedef struct _prefsDlgRec {
+ HINSTANCE hInst;
+ int dlgID;
+ void *proc;
+
+ char *name;
+ int where; // 0 for options, 1 for plugins, 2 for skins, 3 for bookmarks, 4 for prefs
+
+
+ int _id;
+ struct _prefsDlgRec *next;
+} prefsDlgRec;
+
+
+#define IPC_GETINIFILE 334 // returns a pointer to winamp.ini
+#define IPC_GETINIDIRECTORY 335 // returns a pointer to the directory to put config files in (if you dont want to use winamp.ini)
+
+#define IPC_SPAWNBUTTONPOPUP 361 // param =
+// 0 = eject
+// 1 = previous
+// 2 = next
+// 3 = pause
+// 4 = play
+// 5 = stop
+
+#define IPC_OPENURLBOX 360 // pass a HWND to a parent, returns a HGLOBAL that needs to be freed with GlobalFree(), if successful
+#define IPC_OPENFILEBOX 362 // pass a HWND to a parent
+#define IPC_OPENDIRBOX 363 // pass a HWND to a parent
+
+// pass an HWND to a parent. call this if you take over the whole UI so that the dialogs are not appearing on the
+// bottom right of the screen since the main winamp window is at 3000x3000, call again with NULL to reset
+#define IPC_SETDIALOGBOXPARENT 364
+
+
+
+// pass 0 for a copy of the skin HBITMAP
+// pass 1 for name of font to use for playlist editor likeness
+// pass 2 for font charset
+// pass 3 for font size
+#define IPC_GET_GENSKINBITMAP 503
+
+
+#define IPC_GET_EMBEDIF 505 // pass an embedWindowState
+// returns an HWND embedWindow(embedWindowState *); if the data is NULL, otherwise returns the HWND directly
+typedef struct
+{
+ HWND me; //hwnd of the window
+
+ int flags;
+
+ RECT r;
+
+ void *user_ptr; // for application use
+
+ int extra_data[64]; // for internal winamp use
+} embedWindowState;
+
+#define EMBED_FLAGS_NORESIZE 1 // set this bit in embedWindowState.flags to keep window from being resizable
+#define EMBED_FLAGS_NOTRANSPARENCY 2 // set this bit in embedWindowState.flags to make gen_ff turn transparency off for this wnd
+
+
+#define IPC_EMBED_ENUM 532
+typedef struct embedEnumStruct
+{
+ int (*enumProc)(embedWindowState *ws, struct embedEnumStruct *param); // return 1 to abort
+ int user_data; // or more :)
+} embedEnumStruct;
+ // pass
+
+#define IPC_EMBED_ISVALID 533
+
+#define IPC_CONVERTFILE 506
+/* (requires Winamp 2.92+)
+** Converts a given file to a different format (PCM, MP3, etc...)
+** To use, pass a pointer to a waFileConvertStruct struct
+** This struct can be either on the heap or some global
+** data, but NOT on the stack. At least, until the conversion is done.
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE);
+**
+** Return value:
+** 0: Can't start the conversion. Look at myConvertStruct->error for details.
+** 1: Conversion started. Status messages will be sent to the specified callbackhwnd.
+** Be sure to call IPC_CONVERTFILE_END when your callback window receives the
+** IPC_CB_CONVERT_DONE message.
+*/
+typedef struct
+{
+ char *sourcefile; // "c:\\source.mp3"
+ char *destfile; // "c:\\dest.pcm"
+ int destformat[8]; // like 'PCM ',srate,nch,bps
+ HWND callbackhwnd; // window that will receive the IPC_CB_CONVERT notification messages
+
+ //filled in by winamp.exe
+ char *error; //if IPC_CONVERTFILE returns 0, the reason will be here
+
+ int bytes_done; //you can look at both of these values for speed statistics
+ int bytes_total;
+ int bytes_out;
+
+ int killswitch; // don't set it manually, use IPC_CONVERTFILE_END
+ int extra_data[64]; // for internal winamp use
+} convertFileStruct;
+
+#define IPC_CONVERTFILE_END 507
+/* (requires Winamp 2.92+)
+** Stop/ends a convert process started from IPC_CONVERTFILE
+** You need to call this when you receive the IPC_CB_CONVERTDONE message or when you
+** want to abort a conversion process
+**
+** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE_END);
+**
+** No return value
+*/
+
+typedef struct {
+ HWND hwndParent;
+ int format;
+
+ //filled in by winamp.exe
+ HWND hwndConfig;
+ int extra_data[8];
+} convertConfigStruct;
+#define IPC_CONVERT_CONFIG 508
+#define IPC_CONVERT_CONFIG_END 509
+
+typedef struct
+{
+ void (*enumProc)(int user_data, const char *desc, int fourcc);
+ int user_data;
+} converterEnumFmtStruct;
+#define IPC_CONVERT_CONFIG_ENUMFMTS 510
+/* (requires Winamp 2.92+)
+*/
+
+
+typedef struct
+{
+ char cdletter;
+ char *playlist_file;
+ HWND callback_hwnd;
+
+ //filled in by winamp.exe
+ char *error;
+} burnCDStruct;
+#define IPC_BURN_CD 511
+/* (requires Winamp 5.0+)
+*/
+
+typedef struct
+{
+ convertFileStruct *cfs;
+ int priority;
+} convertSetPriority;
+#define IPC_CONVERT_SET_PRIORITY 512
+
+typedef struct
+{
+ char *filename;
+ char *title; // 2048 bytes
+ int length;
+ int force_useformatting; // can set this to 1 if you want to force a url to use title formatting shit
+} waHookTitleStruct;
+// return TRUE if you hook this
+#define IPC_HOOK_TITLES 850
+
+#define IPC_GETSADATAFUNC 800
+// 0: returns a char *export_sa_get() that returns 150 bytes of data
+// 1: returns a export_sa_setreq(int want);
+
+#define IPC_ISMAINWNDVISIBLE 900
+
+
+#define IPC_SETPLEDITCOLORS 920
+typedef struct
+{
+ int numElems;
+ int *elems;
+ HBITMAP bm; // set if you want to override
+} waSetPlColorsStruct;
+
+
+// the following IPC use waSpawnMenuParms as parameter
+#define IPC_SPAWNEQPRESETMENU 933
+#define IPC_SPAWNFILEMENU 934 //menubar
+#define IPC_SPAWNOPTIONSMENU 935 //menubar
+#define IPC_SPAWNWINDOWSMENU 936 //menubar
+#define IPC_SPAWNHELPMENU 937 //menubar
+#define IPC_SPAWNPLAYMENU 938 //menubar
+#define IPC_SPAWNPEFILEMENU 939 //menubar
+#define IPC_SPAWNPEPLAYLISTMENU 940 //menubar
+#define IPC_SPAWNPESORTMENU 941 //menubar
+#define IPC_SPAWNPEHELPMENU 942 //menubar
+#define IPC_SPAWNMLFILEMENU 943 //menubar
+#define IPC_SPAWNMLVIEWMENU 944 //menubar
+#define IPC_SPAWNMLHELPMENU 945 //menubar
+#define IPC_SPAWNPELISTOFPLAYLISTS 946
+
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+} waSpawnMenuParms;
+
+// waSpawnMenuParms2 is used by the menubar submenus
+typedef struct
+{
+ HWND wnd;
+ int xpos; // in screen coordinates
+ int ypos;
+ int width;
+ int height;
+} waSpawnMenuParms2;
+
+
+// system tray sends this (you might want to simulate it)
+#define WM_WA_SYSTRAY WM_USER+1
+
+// input plugins send this when they are done playing back
+#define WM_WA_MPEG_EOF WM_USER+2
+
+
+
+//// video stuff
+
+#define IPC_IS_PLAYING_VIDEO 501 // returns >1 if playing, 0 if not, 1 if old version (so who knows):)
+#define IPC_GET_IVIDEOOUTPUT 500 // see below for IVideoOutput interface
+#define VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24))
+#define VIDUSER_SET_INFOSTRING 0x1000
+#define VIDUSER_GET_VIDEOHWND 0x1001
+#define VIDUSER_SET_VFLIP 0x1002
+#define VIDUSER_SET_TRACKSELINTERFACE 0x1003 // give your ITrackSelector interface as param2
+
+#ifndef NO_IVIDEO_DECLARE
+#ifdef __cplusplus
+
+class VideoOutput;
+class SubsItem;
+
+typedef struct {
+ unsigned char* baseAddr;
+ long rowBytes;
+} YV12_PLANE;
+
+typedef struct {
+ YV12_PLANE y;
+ YV12_PLANE u;
+ YV12_PLANE v;
+} YV12_PLANES;
+
+class IVideoOutput
+{
+ public:
+ virtual ~IVideoOutput() { }
+ virtual int open(int w, int h, int vflip, double aspectratio, unsigned int fmt)=0;
+ virtual void setcallback(LRESULT (*msgcallback)(void *token, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam), void *token) { }
+ virtual void close()=0;
+ virtual void draw(void *frame)=0;
+ virtual void drawSubtitle(SubsItem *item) { }
+ virtual void showStatusMsg(const char *text) { }
+ virtual int get_latency() { return 0; }
+ virtual void notifyBufferState(int bufferstate) { } /* 0-255*/
+
+ virtual int extended(int param1, int param2, int param3) { return 0; } // Dispatchable, eat this!
+};
+
+class ITrackSelector
+{
+ public:
+ virtual int getNumAudioTracks()=0;
+ virtual void enumAudioTrackName(int n, const char *buf, int size)=0;
+ virtual int getCurAudioTrack()=0;
+ virtual int getNumVideoTracks()=0;
+ virtual void enumVideoTrackName(int n, const char *buf, int size)=0;
+ virtual int getCurVideoTrack()=0;
+
+ virtual void setAudioTrack(int n)=0;
+ virtual void setVideoTrack(int n)=0;
+};
+
+#endif //cplusplus
+#endif//NO_IVIDEO_DECLARE
+
+// these messages are callbacks that you can grab by subclassing the winamp window
+
+// wParam =
+#define IPC_CB_WND_EQ 0 // use one of these for the param
+#define IPC_CB_WND_PE 1
+#define IPC_CB_WND_MB 2
+#define IPC_CB_WND_VIDEO 3
+#define IPC_CB_WND_MAIN 4
+
+#define IPC_CB_ONSHOWWND 600
+#define IPC_CB_ONHIDEWND 601
+
+#define IPC_CB_GETTOOLTIP 602
+
+#define IPC_CB_MISC 603
+ #define IPC_CB_MISC_TITLE 0
+ #define IPC_CB_MISC_VOLUME 1 // volume/pan
+ #define IPC_CB_MISC_STATUS 2
+ #define IPC_CB_MISC_EQ 3
+ #define IPC_CB_MISC_INFO 4
+ #define IPC_CB_MISC_VIDEOINFO 5
+
+#define IPC_CB_CONVERT_STATUS 604 // param value goes from 0 to 100 (percent)
+#define IPC_CB_CONVERT_DONE 605
+
+#define IPC_ADJUST_FFWINDOWSMENUPOS 606
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFWINDOWSMENUPOS);
+** moves where winamp expects the freeform windows in the menubar windows main menu. Useful if you wish to insert a
+** menu item above extra freeform windows.
+*/
+
+#define IPC_ISDOUBLESIZE 608
+
+#define IPC_ADJUST_FFOPTIONSMENUPOS 609
+/* (requires Winamp 2.9+)
+** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFOPTIONSMENUPOS);
+** moves where winamp expects the freeform preferences item in the menubar windows main menu. Useful if you wish to insert a
+** menu item above preferences item.
+*/
+
+#define IPC_GETTIMEDISPLAYMODE 610 // returns 0 if displaying elapsed time or 1 if displaying remaining time
+
+#define IPC_SETVISWND 611 // param is hwnd, setting this allows you to receive ID_VIS_NEXT/PREVOUS/RANDOM/FS wm_commands
+#define ID_VIS_NEXT 40382
+#define ID_VIS_PREV 40383
+#define ID_VIS_RANDOM 40384
+#define ID_VIS_FS 40389
+#define ID_VIS_CFG 40390
+#define ID_VIS_MENU 40391
+
+#define IPC_GETVISWND 612 // returns the vis cmd handler hwnd
+#define IPC_ISVISRUNNING 613
+#define IPC_CB_VISRANDOM 628 // param is status of random
+
+#define IPC_SETIDEALVIDEOSIZE 614 // sent by winamp to winamp, trap it if you need it. width=HIWORD(param), height=LOWORD(param)
+
+#define IPC_GETSTOPONVIDEOCLOSE 615
+#define IPC_SETSTOPONVIDEOCLOSE 616
+
+typedef struct {
+ HWND hwnd;
+ int uMsg;
+ int wParam;
+ int lParam;
+} transAccelStruct;
+
+#define IPC_TRANSLATEACCELERATOR 617
+
+typedef struct {
+ int cmd;
+ int x;
+ int y;
+ int align;
+} windowCommand; // send this as param to an IPC_PLCMD, IPC_MBCMD, IPC_VIDCMD
+
+#define IPC_CB_ONTOGGLEAOT 618
+
+#define IPC_GETPREFSWND 619
+
+#define IPC_SET_PE_WIDTHHEIGHT 620 // data is a pointer to a POINT structure that holds width & height
+
+#define IPC_GETLANGUAGEPACKINSTANCE 621
+
+#define IPC_CB_PEINFOTEXT 622 // data is a string, ie: "04:21/45:02"
+
+#define IPC_CB_OUTPUTCHANGED 623 // output plugin was changed in config
+
+#define IPC_GETOUTPUTPLUGIN 625
+
+#define IPC_SETDRAWBORDERS 626
+#define IPC_DISABLESKINCURSORS 627
+#define IPC_CB_RESETFONT 629
+
+#define IPC_IS_FULLSCREEN 630 // returns 1 if video or vis is in fullscreen mode
+#define IPC_SET_VIS_FS_FLAG 631 // a vis should send this message with 1/as param to notify winamp that it has gone to or has come back from fullscreen mode
+
+#define IPC_SHOW_NOTIFICATION 632
+
+#define IPC_GETSKININFO 633
+
+#define IPC_GET_MANUALPLADVANCE 634
+/* (requires Winamp 5.03+)
+** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_MANUALPLADVANCE);
+**
+** IPC_GET_MANUALPLADVANCE returns the status of the Manual Playlist Advance (1 if set)
+*/
+
+#define IPC_SET_MANUALPLADVANCE 635
+/* (requires Winamp 5.03+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_MANUALPLADVANCE);
+**
+** IPC_SET_MANUALPLADVANCE sets the status of the Manual Playlist Advance option (1 to turn it on)
+*/
+
+#define IPC_GET_NEXT_PLITEM 636
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_EOF_GET_NEXT_PLITEM);
+**
+** Sent to Winamp's main window when an item has just finished playback or the next button has been pressed and
+** requesting the new playlist item number to go to.
+** Mainly used by gen_jumpex. Subclass this message in your application to return the new item number.
+** -1 for normal winamp operation (default) or the new item number in the playlist to play.
+*/
+
+#define IPC_GET_PREVIOUS_PLITEM 637
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_EOF_GET_PREVIOUS_PLITEM);
+**
+** Sent to Winamp's main window when the previous button has been pressed and Winamp is requesting the new playlist item number to go to.
+** Mainly used by gen_jumpex. Subclass this message in your application to return the new item number.
+** -1 for normal winamp operation (default) or the new item number in the playlist to play.
+*/
+
+#define IPC_IS_WNDSHADE 638
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,wnd,IPC_IS_WNDSHADE);
+**
+** 'wnd' is window id as defined for IPC_GETWND, or -1 for main window
+** Returns 1 if wnd is set to winshade mode, or 0 if it is not
+*/
+
+#define IPC_SETRATING 639
+/* (requires Winamp 5.04+ with ML)
+** SendMessage(hwnd_winamp,WM_WA_IPC,rating,IPC_SETRATING);
+** 'rating' is an int value from 0 (no rating) to 5
+*/
+
+#define IPC_GETRATING 640
+/* (requires Winamp 5.04+ with ML)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETRATING);
+** returns the current item's rating
+*/
+
+#define IPC_GETNUMAUDIOTRACKS 641
+/* (requires Winamp 5.04+)
+** int n = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETNUMAUDIOTRACKS);
+** returns the number of audio tracks for the currently playing item
+*/
+
+#define IPC_GETNUMVIDEOTRACKS 642
+/* (requires Winamp 5.04+)
+** int n = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETNUMVIDEOTRACKS);
+** returns the number of video tracks for the currently playing item
+*/
+
+#define IPC_GETAUDIOTRACK 643
+/* (requires Winamp 5.04+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETAUDIOTRACK);
+** returns the id of the current audio track for the currently playing item
+*/
+
+#define IPC_GETVIDEOTRACK 644
+/* (requires Winamp 5.04+)
+** int cur = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETVIDEOTRACK);
+** returns the id of the current video track for the currently playing item
+*/
+
+#define IPC_SETAUDIOTRACK 645
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,track,IPC_SETAUDIOTRACK);
+** switch the currently playing item to a new audio track
+*/
+
+#define IPC_SETVIDEOTRACK 646
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,track,IPC_SETVIDEOTRACK);
+** switch the currently playing item to a new video track
+*/
+
+#define IPC_PUSH_DISABLE_EXIT 647
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_PUSH_DISABLE_EXIT );
+** lets you disable or re-enable the UI exit functions (close button,
+** context menu, alt-f4).
+** call IPC_POP_DISABLE_EXIT when you are done doing whatever required
+** preventing exit
+*/
+
+#define IPC_POP_DISABLE_EXIT 648
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_POP_DISABLE_EXIT );
+** see IPC_PUSH_DISABLE_EXIT
+*/
+
+#define IPC_IS_EXIT_ENABLED 649
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_EXIT_ENABLED);
+** returns 0 if exit is disabled, 1 otherwise
+*/
+
+#define IPC_IS_AOT 650
+/* (requires Winamp 5.04+)
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_IS_AOT);
+** returns status of always on top flag. note: this may not match the actual
+** TOPMOST window flag while another fullscreen application is focused
+*/
+
+#define IPC_USES_RECYCLEBIN 651
+/*
+** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_USES_RECYCLEBIN);
+** returns 1 if deleted files should be sent to the recycle bin.
+** returns 0 if deleted files should be deleted permanently.
+**
+** You should check for this option if your plugin deletes files
+** so that your setting matches the winamp setting
+*/
+// >>>>>>>>>>> Next is 652
+
+#define IPC_PLCMD 1000
+
+#define PLCMD_ADD 0
+#define PLCMD_REM 1
+#define PLCMD_SEL 2
+#define PLCMD_MISC 3
+#define PLCMD_LIST 4
+
+#define IPC_MBCMD 1001
+
+#define MBCMD_BACK 0
+#define MBCMD_FORWARD 1
+#define MBCMD_STOP 2
+#define MBCMD_RELOAD 3
+#define MBCMD_MISC 4
+
+#define IPC_VIDCMD 1002
+
+#define VIDCMD_FULLSCREEN 0
+#define VIDCMD_1X 1
+#define VIDCMD_2X 2
+#define VIDCMD_LIB 3
+#define VIDPOPUP_MISC 4
+
+#define IPC_MBURL 1003 //sets the URL
+#define IPC_MBGETCURURL 1004 //copies the current URL into wParam (have a 4096 buffer ready)
+#define IPC_MBGETDESC 1005 //copies the current URL description into wParam (have a 4096 buffer ready)
+#define IPC_MBCHECKLOCFILE 1006 //checks that the link file is up to date (otherwise updates it). wParam=parent HWND
+#define IPC_MBREFRESH 1007 //refreshes the "now playing" view in the library
+#define IPC_MBGETDEFURL 1008 //copies the default URL into wParam (have a 4096 buffer ready)
+
+#define IPC_STATS_LIBRARY_ITEMCNT 1300 // updates library count status
+
+// IPC 2000-3000 reserved for freeform messages, see gen_ff/ff_ipc.h
+#define IPC_FF_FIRST 2000
+#define IPC_FF_LAST 3000
+
+#define IPC_GETDROPTARGET 3001
+
+#define IPC_PLAYLIST_MODIFIED 3002 // sent to main wnd whenever the playlist is modified
+
+#define IPC_PLAYING_FILE 3003 // sent to main wnd with the file as parm whenever a file is played
+#define IPC_FILE_TAG_MAY_HAVE_UPDATED 3004 // sent to main wnd with the file as parm whenever a file tag might be updated
+
+
+#define IPC_ALLOW_PLAYTRACKING 3007
+// send nonzero to allow, zero to disallow
+
+#define IPC_HOOK_OKTOQUIT 3010 // return 0 to abort a quit, nonzero if quit is OK
+
+#define IPC_WRITECONFIG 3011 // pass 2 to write all, 1 to write playlist + common, 0 to write common+less common
+
+#define IPC_TOGGLE_RESIZE 3012 // USE THIS TO TOGGLE RESIZING OFF/ON BP.
+// USE THIS TO PASS A URL TO AD WINDOW bp
+#define IPC_SHOW_AD_URL 3013 // pass the URL (char *) in lparam
+#define IPC_SHOW_HWND 3014 // HWND of AdBox is in lparam
+// pass a string to be the name to register, and returns a value > 65536, which is a unique value you can use
+// for custom WM_WA_IPC messages.
+#define IPC_REGISTER_WINAMP_IPCMESSAGE 65536
+
+
+
+#endif//_WA_IPC_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_avs/whatsnew.txt b/Src/Plugins/Visualization/vis_avs/whatsnew.txt
new file mode 100644
index 00000000..12601f16
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/whatsnew.txt
@@ -0,0 +1,233 @@
+-francis:
+added floor(), ceil() and $Phi
+added "cancel fullscreen on deactivation" toggle option
+
+-mig:
+added example infrastructure to dmove. :)
+now there are 8 examples in dmove. also tuned up my beat-interpolation algos! woo!
+
+-justin
+added blend modes to misc / buffer save
+made config expand trees by default
+
+-mig:
+started work on undo/redo system.
+infrastructure seems to work, but I can't figure out the magical
+ incantation to make the UI reflect the newly altered render list
+ although it seems to actually go back to the last values in the renderer.
+"Do you want to save?" dirty flag now contained (mostly) in the undo object.
+(In fact, it saves a dirty bit for every undo state, so you can undo twice,
+ save, then redo and you should have your dirty bit still set. If you then
+ undo yet again, you're back to what you saved and you have no dirty bit)
+added more examples to SuperScope
+
+-justin:
+fixed memory leak in evallib stuff I made a bit back
+added debug window, moved register watch to it, added error listing
+added option for clear variables on recompile in debug window
+fixed bugs, too.
+
+-justin:
+started adding setting for reinit on edit for evallib stuff
+made config change detection a little more accurate
+made superscope/dmove/shift/etc reinit on edit work right
+made trans / movement only replace usereval with preseteval if editted
+fyi: trans / movement also provides 'sw' and 'sh' for screen width and height,
+ so things like 'd=d*0.93 + (((x*sw/2)&(y*sh/2)&1)*-0.3);' are fun :)
+fixed trans / movement backwards compatible stuff (no crashy at least)
+updated eval documentation stuff, need people to write docs for it, too.. heheh
+lots of ui cleanups (more edit room!)
+fixed some fullscreen new fbresize bugs
+updated fullscreen overlay mode some
+updated maximum local variables to 256 from 64
+added global registers [reg00,reg01,... reg99] for debug
+ and effect synchronization (or inter-preset communication)
+added global register watch in root list window (for debugging)
+added comments for eval code. // and /* bla */
+updated eval documentation
+added gettime() function to eval
+made annoying grey rectangle below tree go away when you aren't docked
+added new color modifier effect, which can be used to replace
+ (with script) a lot of different effects (and be faster and more flexible).
+added 'minimum blend' mode for effect lists/line drawing
+added 'round up' option for Blur.
+made a generic avs directory scanner routine for subdirs (yay!)
+ made it only generate menus when opened, for speed
+made effects that use evallib reset variables to empty on recompile
+made avs track dirtiness of presets, and (optionally) prompt to save etc
+made avs resize images when resizing (optionally)
+added extended APE interface, that lets you access evallib, global registers,
+ line blend/width modes. (see apesdk.zip)
+
+
+
+
+- mig: made most of the presets in Trans/Movement show their algos in the edit field (so you can tune them yourself)
+ added multiple new algos to the preset list
+
+- mig: removed ability to RMB in fullscreen mode. Bug 331 from the database. want make new gui. want make now.
+- basu: added 'onbeat enabled' option to lists
+- christophe: added thread priority settings (so you can set avs in idle prority while keeping winamp in
+ high prio.)
+2.0a7:
+- made better multimonitor support -- still needs more work (making it able to go fullscreen and you do other things
+2.0a6:
+- added 'skip first' in misc/custom bpm
+- added interferences effect
+2.0a4:
+- auto fullscreen window resizing
+2.0a3:
+- updated fullscreen vis code to handle leaving fullscreen
+ unexpectedly better
+- made configwnd repopulation more robust
+- made transitions work when preinit is disabled and you just
+ started up
+2.0a2:
+- updated options of display/fullscreen/trans
+- added doublesize for windowed
+- added seperate opts for windowed/fullscreen for text
+- fixed bug in mosaic.
+
+2.0a1:
+- preinit of presets for better transitions
+- integrated laser support (built-time option)
+- changed name to 'Winamp AVS'
+- Improved SVP/UVS loading
+- Made superscope support 'red' 'green' and 'blue'
+
+1.5a6:
+- preset transitions, woohoo
+- yay
+
+1.5a4:
+- presets for superscope
+- more superscope options
+- made random preset loading on beat
+- bugfixes
+
+1.5a3:
+- line width option
+- ability to use buffer as alpha channel for blending sub-effects back in
+- tons more
+
+1.5a2:
+- deadbeef: cleanups
+- lone: adjustable blend for sub-effects
+
+1.5a1:
+- deadbeef: made new effect system completely hiererchical and scaleable.
+ reorganized code a lot. cleaned things up. made it nice.
+
+1.0a53:
+- deadbeef: superscope effect
+ made it save to plugins\vis_avs.dat, instead.
+-lone : added Trans / Invert
+ added Trans / Unique tone
+ added Render / Timescope
+
+a52:
+- deadbeef: optimized/simplified evallib. made it limited to 8 char variable names,
+ 32 variables max.
+ improved ddm effect.
+ improved color clip effect
+
+a51:
+- deadbeef: optimized mosaic, grain, brightness, and bump effects
+ optimized and added more functionality to interleave effect
+- lone : clear - fixed 'first frame only'
+ eval - added sigmoid, sign, max, min, rand, band, bor, bnot, if, equal, above, below
+ ddm - added code for init and beat
+ bump - added 'bi' var to control bump intensity thru exps.
+ - added depth source
+ clear - fixed 'first frame only' (again)
+ onbeat clear - fixed 'skip n beats' which was not saved
+- ron : picture - fixed picture border bugs when aspect ratio was on
+
+a50:
+- deadbeef: added subtractive blend, every other line blend to stack
+ fixed window-no-erase bug.
+ added new dynamic distance modifier effect
+ added 'go' button to fullscreen options
+ added wait for retrace options
+ revised logarithmic spectrum scaling table
+- ron: better no-minimize-on-winamp (now displays a separate window in taskman)
+- lone : bpm - better out of range detection in average calculation
+ - better confidence calculation
+ - added option to predict beats only if bpm has been found
+ - fixed relearn/adapt on new song option
+ - fixed unwanted resets when using 'don't minimize avs when minimizing winamp' option
+ brightness - now works actually like a brightness filter (bit slower tho)
+ text - fixed crash when window is smaller than width/height of text and random mode was checked
+ bump - added invert depth
+ - fixed exclusive use of eval lib, was choking with misc trans/custom
+ or additional bump effects, now saves/restores vars in a clean way.
+ - changed 0-100 range to 0-1 which is much easier to use with math exps
+ (for backward compatibility, old settings are still using the old range)
+
+a49:
+
+- ron: added transparency settings (win2k only).
+ added AVI and Water Bump effects.
+ settings are now drageable (fixed).
+ deleting a setting now doesn't loose selection.
+ evallib now works when AVS is compiled in debug mode.
+ added "don't minimize avs with winamp" setting in Display tab.
+ added BMP Picture rendering.
+- lone: disabled resize in fullscreen mode, fixes directx lockups
+ added Custom BPM filter
+ fixed stuck moving particles when no beat occurs for a long time
+ fixed random word option in text renderer
+ added beat learning - fixed broken version, now better than ever :>
+ added option to dock AVS into litestep's wharfamp window :)
+- deadbeef: restyled editor.
+ made rotation switching variable in rotoblitter, and onbeat zoom changes
+ made loading/saving of unsupported effects/ape's better
+ fixed text drawing bugs.
+ fixed fullscreen-when-no-mode-selected, and made it verify video modes
+ made skin change detection
+ added vertical blank wait options
+ fixed rotoblitter crashing effect
+ tons of other stuff.
+
+
+
+a46: more effects, etc from lone/ron. Improved main interface.
+ a few small bugfixes.
+a44: crashing bugfixes. border drawing bugfixes.
+a43: skinnability. Put the avs.bmp in the skin directory.
+ avs.bmp.
+a42: improved mirror effect. Misc trans now has mixed mapping mode
+ (onbeat changes). should either have fixed or broken coming out
+ of fullscreen modes. Fixed a few cosmetic bugs.
+a41: added lone's mirror effect.
+a40: comment bugfix, lone's effects, MUCH better beat detection
+a39: source mapping translation mode. Fadeto has color to fade to.
+a38: clone button. One level of presets directories allowed. Lets
+ you select a preset directory to pull random/cycles from.
+ Neato.
+a37: comment thingy. Status line. More improvements. No more keyboard
+ controls for config, though :(
+a36: optimized colorfade, moving particle is nicer circle, water effect,
+ little cleanups, AVS editor now in own thread, keyboard controls
+ work better, etc etc .
+a35: more blur options, more presets, new APE module (FyreWurx)
+a33: ultra-fast expression eval. test those custom trantabs to make sure they didn't break.
+a32: unfucks blur for older presets
+a31: dot fountain, baby.
+a30: made effects alpha-channel-safe, made random switching adjustable,
+ a lot of little tastey cleanups, etc.
+a29: nifty-ass framebuffer saving/restoring effect
+a28: adjustable CPU usage. better beat detection stuff. etc.
+a26: new effect (dot grid), widescreen fullscreen modes, etc.
+a25: bugfixes, you can now drop .avs's into the window, etc.
+a24: much better custom transtab stuff (thanks, LONE, not lore. no
+ offense, lore, though :)
+a23: custom transtabs much faster. buggier, though. will be fixed soon.
+ lone owns. :)
+a22: higher framerate, custom transtabs, more effects, etc.
+a21 adds new "Scatter" effect
+a20 adds DLL effect loading (APE)
+a18 fixes close-winamp die bug.
+a18 speeds up colorfade (all table driven)
+a17 fixes win2k fullscreen issues (afaik)
+a16 adds some fixes, and new winamp styled window
diff --git a/Src/Plugins/Visualization/vis_avs/wnd.cpp b/Src/Plugins/Visualization/vis_avs/wnd.cpp
new file mode 100644
index 00000000..7b920059
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/wnd.cpp
@@ -0,0 +1,1749 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <stdio.h>
+#include <windows.h>
+#include <windowsx.h>
+#include "vis.h"
+#include "draw.h"
+#include "wnd.h"
+#include "cfgwnd.h"
+#include "r_defs.h"
+#include "resource.h"
+#include "render.h"
+#include "undo.h"
+#include <multimon.h>
+
+#include "avs_eelif.h"
+
+#define WINAMP_NEXT_WINDOW 40063
+#include "wa_ipc.h"
+#include "ff_ipc.h"
+#include "../Agave/Language/api_language.h"
+
+#ifndef WS_EX_LAYERED
+#define WS_EX_LAYERED 0x80000
+#endif
+
+#ifndef LWA_ALPHA
+#define LWA_ALPHA 2
+#endif
+
+#define ID_VIS_NEXT 40382
+#define ID_VIS_PREV 40383
+#define ID_VIS_RANDOM 40384
+
+struct winampVisModule *g_mod;
+extern volatile int g_ThreadQuit;
+extern int /*g_preset_dirty,*/ config_prompt_save_preset, config_reuseonresize;
+int g_saved_preset_dirty;
+extern int cfg_cancelfs_on_deactivate;
+
+extern char g_noeffectstr[];
+#ifndef WA2_EMBED
+static int cfg_x=100, cfg_y=100, cfg_w=400, cfg_h=300;
+#endif
+
+#ifndef WA2_EMBED
+static HDC hFrameDC;
+static HBITMAP hFrameBitmap, hFrameBitmap_old;
+#else
+embedWindowState myWindowState;
+HWND g_hWA2ParentWindow;
+#endif
+
+int g_reset_vars_on_recompile=1; // fucko: add config for this
+
+
+// Wharf integration
+int inWharf=0;
+int need_redock=0;
+
+extern int cfg_fs_use_overlay;
+extern int g_config_seh;
+
+
+void toggleWharfAmpDock(HWND hwnd);
+
+//-
+
+int g_in_destroy=0,g_minimized=0,g_fakeinit=0;
+
+int g_rnd_cnt;
+char g_skin_name[MAX_PATH];
+
+int debug_reg[8];
+
+void GetClientRect_adj(HWND hwnd, RECT *r)
+{
+ GetClientRect(hwnd,r);
+#ifndef WA2_EMBED
+ if (!inWharf)
+ {
+ r->right-=7+6;
+ r->bottom-=15+5;
+ }
+#endif
+}
+
+HWND g_hwnd;
+
+HWND hwnd_WinampParent;
+extern HWND g_hwndDlg;
+extern char last_preset[2048];
+char *scanstr_back(char *str, char *toscan, char *defval)
+{
+ char *s=str+strlen(str)-1;
+ if (strlen(str) < 1) return defval;
+ if (strlen(toscan) < 1) return defval;
+ while (1)
+ {
+ char *t=toscan;
+ while (*t)
+ if (*t++ == *s) return s;
+ t=CharPrev(str,s);
+ if (t==s) return defval;
+ s=t;
+ }
+}
+
+int LoadPreset(int preset)
+{
+ char temp[MAX_PATH];
+ wsprintf(temp,"%s\\PRESET%02d.APH",g_path,preset);
+ if (g_render_transition->LoadPreset(temp,1))
+ return 0;
+ if (preset < 12) wsprintf(last_preset,"\\F%d.aph",preset+1);
+ else if (preset < 22) wsprintf(last_preset,"\\%d.aph",preset-12);
+ else if (preset < 32) wsprintf(last_preset,"\\Shift-%d.aph",preset-22);
+ return 1;
+}
+
+void WritePreset(int preset)
+{
+ char temp[MAX_PATH];
+ wsprintf(temp,"%s\\PRESET%02d.APH",g_path,preset);
+ g_render_effects->__SavePreset(temp);
+}
+
+void my_getViewport( RECT *r, RECT *sr )
+{
+ if ( sr )
+ {
+ HINSTANCE h = LoadLibraryW( L"user32.dll" );
+ if ( h )
+ {
+ HMONITOR( WINAPI * Mfr )( LPCRECT lpcr, DWORD dwFlags ) = ( HMONITOR( WINAPI * )( LPCRECT, DWORD ) ) GetProcAddress( h, "MonitorFromRect" );
+ BOOL( WINAPI * Gmi )( HMONITOR mon, LPMONITORINFO lpmi ) = ( BOOL( WINAPI * )( HMONITOR, LPMONITORINFO ) ) GetProcAddress( h, "GetMonitorInfoW" );
+ if ( Mfr && Gmi )
+ {
+ HMONITOR hm;
+ hm = Mfr( sr, MONITOR_DEFAULTTONULL );
+ if ( hm )
+ {
+ MONITORINFOEXW mi;
+ memset( &mi, 0, sizeof( mi ) );
+ mi.cbSize = sizeof( mi );
+
+ if ( Gmi( hm, &mi ) )
+ {
+ *r = mi.rcWork;
+ return;
+ }
+ }
+ }
+ FreeLibrary( h );
+ }
+ }
+ SystemParametersInfoW( SPI_GETWORKAREA, 0, r, 0 );
+}
+
+
+void SetTransparency(HWND hWnd, int enable, int amount)
+{
+#ifdef WA2_EMBED
+ // disable transparency if hosted in gen_ff
+ HWND w = myWindowState.me;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD) w = GetParent(w);
+ char classname[256];
+ GetClassName(w, classname, 255); classname[255] = 0;
+ if (!stricmp(classname, "BaseWindow_RootWnd")) return;
+ // --
+#endif
+
+ DWORD dwLong;
+ HINSTANCE h;
+ void (__stdcall *a)(HWND h, int a, int b, int c);
+
+ hWnd=GetParent(hWnd);
+
+ dwLong = GetWindowLong(hWnd, GWL_EXSTYLE);
+ if(amount==255||!enable) {
+ if(dwLong&WS_EX_LAYERED)
+ SetWindowLong(hWnd, GWL_EXSTYLE, dwLong & ~WS_EX_LAYERED);
+ } else {
+ if(!(dwLong&WS_EX_LAYERED))
+ SetWindowLong(hWnd, GWL_EXSTYLE, dwLong | WS_EX_LAYERED);
+ h=LoadLibrary("USER32.DLL");
+ if(h!=NULL) {
+ a=(void (__stdcall *)(HWND,int,int,int))GetProcAddress(h,"SetLayeredWindowAttributes");
+ if(a!=NULL)
+ a(hWnd, RGB(0,0,0), amount, LWA_ALPHA);
+ FreeLibrary(h);
+ }
+ }
+}
+
+int readyToLoadPreset(HWND parent, int isnew)
+{
+ if (config_prompt_save_preset && C_UndoStack::isdirty())
+ {
+ static int here;
+ if (here) return 0;
+ here=1;
+
+ // strange bugfix, ick
+ void Wnd_GoWindowed(HWND hwnd);
+ if (DDraw_IsFullScreen()) Wnd_GoWindowed(g_hwnd);
+
+ char title[48];
+ int ret=MessageBox(parent,
+ WASABI_API_LNGSTRING(!isnew?IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_LOAD:
+ IDS_CURRENT_PRESET_EDITED_SAVE_BEFORE_NEW),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_PRESET_MODIFIED,title,48),MB_YESNOCANCEL);
+ here=0;
+
+ if (ret == IDCANCEL)
+ {
+ return 0;
+ }
+ if (ret == IDYES)
+ {
+ int dosavePreset(HWND hwndDlg);
+ int r=1;
+// if (last_preset[0])
+ // r=g_render_effects->SavePreset(last_preset);
+
+ if (r)
+ {
+ if (dosavePreset(parent)) return 0;
+ }
+ }
+ }
+ //C_UndoStack::clear();
+ // g_preset_dirty=0;
+ return 1;
+}
+
+char *extension(char *fn)
+{
+ char *s = fn + strlen(fn);
+ while (s >= fn && *s != '.' && *s != '\\') s--;
+ if (s < fn) return fn;
+ if (*s == '\\') return fn;
+ return (s+1);
+}
+
+static int last_windowed_w, last_windowed_h;
+void Wnd_GoWindowed(HWND hwnd)
+{
+ if (DDraw_IsFullScreen())
+ {
+#ifdef WA2_EMBED
+ SendMessage(g_mod->hwndParent,WM_WA_IPC,0,IPC_SET_VIS_FS_FLAG);
+#endif
+#if !defined(WA2_EMBED)
+ DDraw_SetFullScreen(0,cfg_w-7-6,cfg_h-15-5,cfg_fs_d&2,0);
+#else
+ SetParent(hwnd,myWindowState.me);
+ SetWindowLong(hwnd,GWL_STYLE,WS_VISIBLE|WS_CHILDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_OVERLAPPED);
+ DDraw_SetFullScreen(0,last_windowed_w,last_windowed_h,cfg_fs_d&2,0);
+ HWND w = myWindowState.me;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD) w = GetParent(w);
+ ShowWindow(w,SW_SHOWNA);
+#endif
+
+ if (cfg_cancelfs_on_deactivate) ShowCursor(TRUE);
+ int tm=(GetWindowLong(g_mod->hwndParent,GWL_EXSTYLE)&WS_EX_TOPMOST)==WS_EX_TOPMOST;
+
+#if !defined(WA2_EMBED)
+ SetWindowPos(hwnd,tm?HWND_TOPMOST:HWND_NOTOPMOST,cfg_x,cfg_y,cfg_w,cfg_h,SWP_NOACTIVATE);
+#else
+ PostMessage(GetParent(hwnd),WM_SIZE,0,0);
+#endif
+
+ SetTransparency(hwnd,cfg_trans,cfg_trans_amount);
+
+ SetTimer(hwnd,88,100,NULL);
+ }
+}
+
+void Wnd_GoFullScreen(HWND hwnd)
+{
+ if (!DDraw_IsFullScreen())
+ {
+
+#if 1
+#ifdef WA2_EMBED
+ if (SendMessage(g_mod->hwndParent,WM_WA_IPC,0,IPC_IS_PLAYING_VIDEO)>1)
+ {
+ PostMessage(hwnd,WM_USER+1667,1,2);
+ return;
+ }
+#endif
+#endif
+
+ extern int cfg_fs_use_overlay;
+#ifdef WA2_EMBED
+ RECT r;
+ GetClientRect(hwnd,&r);
+ last_windowed_w=r.right;
+ last_windowed_h=r.bottom;
+#endif
+
+ if (!DDraw_IsMode(cfg_fs_w,cfg_fs_h,cfg_fs_bpp))
+ {
+ int DDraw_PickMode(int *w, int *h, int *bpp);
+ if (!DDraw_PickMode(&cfg_fs_w,&cfg_fs_h,&cfg_fs_bpp))
+ return;
+ }
+
+ {
+#ifdef WA2_EMBED
+ SendMessage(g_mod->hwndParent,WM_WA_IPC,1,IPC_SET_VIS_FS_FLAG);
+#endif
+ RECT tr;
+ if (inWharf)
+ {
+ need_redock=1;
+ toggleWharfAmpDock(hwnd);
+ }
+ SetTransparency(hwnd,0,0);
+ if (cfg_cancelfs_on_deactivate) ShowCursor(FALSE);
+ GetWindowRect(hwnd,&tr);
+ if (cfg_cfgwnd_open) ShowWindow(g_hwndDlg,SW_HIDE);
+ if (!cfg_fs_use_overlay)
+ {
+#if defined(WA2_EMBED)
+ SetWindowLong(hwnd,GWL_STYLE,WS_VISIBLE);
+ SetParent(hwnd,NULL);
+ HWND w = myWindowState.me;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD) w = GetParent(w);
+ ShowWindow(w,SW_HIDE);
+#endif
+ DDraw_SetFullScreen(1,cfg_fs_w,cfg_fs_h,cfg_fs_d&1,cfg_fs_bpp);
+ RECT r;
+ my_getViewport(&r,&tr);
+ SetWindowPos(hwnd,HWND_TOPMOST,r.left,r.top,cfg_fs_w,cfg_fs_h,0);
+ SetForegroundWindow(hwnd);
+ }
+ else
+ {
+#if defined(WA2_EMBED)
+ SetWindowLong(hwnd,GWL_STYLE,WS_VISIBLE);
+ SetParent(hwnd,NULL);
+ HWND w = myWindowState.me;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD) w = GetParent(w);
+ ShowWindow(w,SW_HIDE);
+#endif
+ DDraw_SetFullScreen(1,cfg_fs_w,cfg_fs_h,cfg_fs_d&1,0);
+ }
+ }
+#if 0
+ else
+ {
+ if (!cfg_cfgwnd_open)
+ {
+ ShowWindow(g_hwndDlg,SW_SHOWNA);
+ CfgWnd_RePopIfNeeded();
+ cfg_cfgwnd_open=1;
+ }
+ SendMessage(g_hwndDlg,WM_COMMAND,IDM_FULLSCREEN,0);
+ }
+#endif
+ }
+}
+
+int g_config_smp_mt=2,g_config_smp=0;
+static char *INI_FILE;
+
+static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+int cfg_fs_dblclk=1;
+
+int Wnd_Init(struct winampVisModule *this_mod)
+{
+ WNDCLASS wc={0,};
+ g_mod=this_mod;
+ wc.style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW;
+ wc.lpfnWndProc = WndProc;
+ wc.hInstance = this_mod->hDllInstance;
+ wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
+ wc.lpszClassName = "avswnd";
+ wc.hCursor=LoadCursor(NULL,IDC_ARROW);
+
+ hwnd_WinampParent=this_mod->hwndParent;
+
+
+ if (!RegisterClass(&wc))
+ {
+// MessageBox(this_mod->hwndParent,"Error registering window class","Error",MB_OK);
+ // return 1;
+ }
+ {
+#ifndef REAPLAY_PLUGIN
+ INI_FILE = (char*)SendMessage(this_mod->hwndParent,WM_WA_IPC,0,IPC_GETINIFILE);
+#else
+ extern const char *(*get_ini_file)();
+ INI_FILE = (char *)get_ini_file();
+#endif
+#define AVS_SECTION "AVS"
+#ifdef LASER
+#undef AVS_SECTION
+#define AVS_SECTION "AVS_L"
+ extern int g_laser_nomessage,g_laser_zones;
+ g_laser_nomessage=GetPrivateProfileInt(AVS_SECTION,"laser_nomessage",0,INI_FILE);
+ g_laser_zones=GetPrivateProfileInt(AVS_SECTION,"laser_zones",1,INI_FILE);
+#else
+ g_config_smp=GetPrivateProfileInt(AVS_SECTION,"smp",0,INI_FILE);
+ g_config_smp_mt=GetPrivateProfileInt(AVS_SECTION,"smp_mt",2,INI_FILE);
+#endif
+ need_redock=GetPrivateProfileInt(AVS_SECTION,"cfg_docked",0,INI_FILE);
+ cfg_cfgwnd_x=GetPrivateProfileInt(AVS_SECTION,"cfg_cfgwnd_x",cfg_cfgwnd_x,INI_FILE);
+ cfg_cfgwnd_y=GetPrivateProfileInt(AVS_SECTION,"cfg_cfgwnd_y",cfg_cfgwnd_y,INI_FILE);
+ cfg_cfgwnd_open=GetPrivateProfileInt(AVS_SECTION,"cfg_cfgwnd_open",cfg_cfgwnd_open,INI_FILE);
+ cfg_fs_w=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_w",cfg_fs_w,INI_FILE);
+ cfg_fs_h=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_h",cfg_fs_h,INI_FILE);
+ cfg_fs_bpp=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_bpp",cfg_fs_bpp,INI_FILE);
+ cfg_fs_d=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_d",cfg_fs_d,INI_FILE);
+ cfg_fs_fps=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_fps",6,INI_FILE);
+ cfg_fs_rnd=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_rnd",cfg_fs_rnd,INI_FILE);
+ cfg_fs_rnd_time=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_rnd_time",cfg_fs_rnd_time,INI_FILE);
+ cfg_fs_dblclk=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_dblclk",cfg_fs_dblclk,INI_FILE);
+ cfg_fs_flip=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_flip",cfg_fs_flip,INI_FILE);
+ cfg_fs_height=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_height",cfg_fs_height,INI_FILE);
+ cfg_fs_use_overlay=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_use_overlay",cfg_fs_use_overlay,INI_FILE);
+ cfg_cancelfs_on_deactivate=GetPrivateProfileInt(AVS_SECTION,"cfg_fs_cancelondeactivate",cfg_cancelfs_on_deactivate,INI_FILE);
+ cfg_speed=GetPrivateProfileInt(AVS_SECTION,"cfg_speed",cfg_speed,INI_FILE);
+ cfg_trans=GetPrivateProfileInt(AVS_SECTION,"cfg_trans",cfg_trans,INI_FILE);
+ cfg_dont_min_avs=GetPrivateProfileInt(AVS_SECTION,"cfg_dont_min_avs",cfg_dont_min_avs,INI_FILE);
+ cfg_smartbeat=GetPrivateProfileInt(AVS_SECTION,"cfg_smartbeat",cfg_smartbeat,INI_FILE);
+ cfg_smartbeatsticky=GetPrivateProfileInt(AVS_SECTION,"cfg_smartbeatsticky",cfg_smartbeatsticky,INI_FILE);
+ cfg_smartbeatresetnewsong=GetPrivateProfileInt(AVS_SECTION,"cfg_smartbeatresetnewsong",cfg_smartbeatresetnewsong,INI_FILE);
+ cfg_smartbeatonlysticky=GetPrivateProfileInt(AVS_SECTION,"cfg_smartbeatonlysticky",cfg_smartbeatonlysticky,INI_FILE);
+ GetPrivateProfileString( AVS_SECTION,"config_pres_subdir","",config_pres_subdir,sizeof(config_pres_subdir),INI_FILE);
+ GetPrivateProfileString( AVS_SECTION,"last_preset_name","",last_preset,sizeof(last_preset),INI_FILE);
+ cfg_transitions=GetPrivateProfileInt(AVS_SECTION,"cfg_transitions_en",cfg_transitions,INI_FILE);
+ cfg_transitions2=GetPrivateProfileInt(AVS_SECTION,"cfg_transitions_preinit",cfg_transitions2,INI_FILE);
+ cfg_transitions_speed=GetPrivateProfileInt(AVS_SECTION,"cfg_transitions_speed",cfg_transitions_speed,INI_FILE);
+ cfg_transition_mode=GetPrivateProfileInt(AVS_SECTION,"cfg_transitions_mode",cfg_transition_mode,INI_FILE);
+ cfg_bkgnd_render=GetPrivateProfileInt(AVS_SECTION,"cfg_bkgnd_render",cfg_bkgnd_render,INI_FILE);
+ cfg_bkgnd_render_color=GetPrivateProfileInt(AVS_SECTION,"cfg_bkgnd_render_color",cfg_bkgnd_render_color,INI_FILE);
+ cfg_render_prio=GetPrivateProfileInt(AVS_SECTION,"cfg_render_prio",cfg_render_prio,INI_FILE);
+ g_saved_preset_dirty=GetPrivateProfileInt(AVS_SECTION,"g_preset_dirty",C_UndoStack::isdirty(),INI_FILE);
+ config_prompt_save_preset=GetPrivateProfileInt(AVS_SECTION,"cfg_prompt_save_preset",config_prompt_save_preset,INI_FILE);
+ config_reuseonresize=GetPrivateProfileInt(AVS_SECTION,"cfg_reuseonresize",config_reuseonresize,INI_FILE);
+ g_log_errors=GetPrivateProfileInt(AVS_SECTION,"cfg_log_errors",g_log_errors,INI_FILE);
+ g_reset_vars_on_recompile=GetPrivateProfileInt(AVS_SECTION,"cfg_reset_vars",g_reset_vars_on_recompile,INI_FILE);
+ g_config_seh=GetPrivateProfileInt(AVS_SECTION,"cfg_seh",g_config_seh,INI_FILE);
+
+
+#ifdef WA2_EMBED
+ memset(&myWindowState,0,sizeof(myWindowState));
+ myWindowState.r.left=GetPrivateProfileInt(AVS_SECTION,"wx",32,INI_FILE);
+ myWindowState.r.top=GetPrivateProfileInt(AVS_SECTION,"wy",32,INI_FILE);
+ myWindowState.r.right = GetPrivateProfileInt(AVS_SECTION,"ww",320,INI_FILE)+myWindowState.r.left;
+ myWindowState.r.bottom = GetPrivateProfileInt(AVS_SECTION,"wh",240,INI_FILE)+myWindowState.r.top;
+#else
+ cfg_x=GetPrivateProfileInt(AVS_SECTION,"cfg_x",cfg_x,INI_FILE);
+ cfg_y=GetPrivateProfileInt(AVS_SECTION,"cfg_y",cfg_y,INI_FILE);
+ cfg_w=GetPrivateProfileInt(AVS_SECTION,"cfg_w",cfg_w,INI_FILE);
+ cfg_h=GetPrivateProfileInt(AVS_SECTION,"cfg_h",cfg_h,INI_FILE);
+#endif
+
+ int x;
+ for (x = 0; x < 8; x ++)
+ {
+ char debugreg[32];
+ wsprintf(debugreg,"debugreg_%d",x);
+ debug_reg[x]=GetPrivateProfileInt(AVS_SECTION,debugreg,x,INI_FILE);
+ }
+
+ }
+#ifdef LASER
+ cfg_transitions=0;
+ cfg_transition_mode=0;
+ cfg_transitions2=0;
+#endif
+
+ g_in_destroy=0;
+#ifndef WA2_EMBED
+ {
+ RECT ir={cfg_x,cfg_y,cfg_w+cfg_x,cfg_y+cfg_h};
+ RECT or;
+ my_getViewport(&or,&ir);
+ if (cfg_x < or.left) cfg_x=or.left;
+ if (cfg_y < or.top) cfg_y=or.top;
+ if (cfg_x > or.right-16) cfg_x=or.right-16;
+ if (cfg_y > or.bottom-16) cfg_y=or.bottom-16;
+ // determine bounding rectangle for window
+ }
+#endif
+#ifndef WA2_EMBED
+ int styles=WS_VISIBLE;
+ HWND par = g_minimized?NULL:this_mod->hwndParent;
+#else
+ int styles=WS_CHILDWINDOW|WS_OVERLAPPED|WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
+ HWND (*e)(embedWindowState *v) = NULL;
+#ifndef REAPLAY_PLUGIN
+ *(void**)&e = (void *)SendMessage(this_mod->hwndParent,WM_WA_IPC,(LPARAM)0,IPC_GET_EMBEDIF);
+ HWND par=0;
+ if (e) par=e(&myWindowState);
+ if (par) SetWindowText(par,"AVS");
+#else
+ HWND par = this_mod->hwndParent;
+#endif
+ g_hWA2ParentWindow=par;
+#endif
+
+#ifndef WA2_EMBED
+
+ CreateWindowEx(WS_EX_ACCEPTFILES,"avswnd","Winamp AVS Display",
+ styles,cfg_x,cfg_y,cfg_w,cfg_h,par,NULL,
+ this_mod->hDllInstance,0);
+#else
+ CreateWindowEx(WS_EX_ACCEPTFILES,"avswnd","avs",
+ styles,0,0,100,100,par,NULL, this_mod->hDllInstance,0);
+ SendMessage(this_mod->hwndParent, WM_WA_IPC, (int)g_hwnd, IPC_SETVISWND);
+#endif
+ if (!g_hwnd)
+ {
+ char title[32];
+ MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_ERROR_CREATING_WINDOW),
+ WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,32),MB_OK);
+ return 1;
+ }
+#ifndef REAPLAY_PLUGIN
+#ifdef WA2_EMBED
+ ShowWindow(g_hwnd,SW_SHOWNA);
+ ShowWindow(par,SW_SHOWNA);
+#endif
+#endif
+ SetTransparency(g_hwnd,cfg_trans,cfg_trans_amount);
+ return 0;
+}
+
+static void WriteInt(char *name, int value)
+{
+ char str[128];
+ wsprintf(str,"%d",value);
+ WritePrivateProfileString(AVS_SECTION,name,str,INI_FILE);
+}
+
+void Wnd_Quit(void)
+{
+ extern HWND g_hwndDlg;
+ g_in_destroy=1;
+#ifdef WA2_EMBED
+ SendMessage(g_mod->hwndParent, WM_WA_IPC, 0, IPC_SETVISWND);
+ if (myWindowState.me)
+ {
+ SetForegroundWindow(g_mod->hwndParent);
+ DestroyWindow(myWindowState.me);
+ }
+ else
+#endif
+ if (g_hwnd && IsWindow(g_hwnd)) DestroyWindow(g_hwnd);
+ g_hwnd=NULL;
+ UnregisterClass("avswnd",g_mod->hDllInstance);
+ {
+#ifdef LASER
+ extern int g_laser_zones,g_laser_nomessage;
+ wsprintf(str,"%d",g_laser_zones);
+ WriteInt("laser_zones",g_laser_zones);
+ WriteInt("laser_nomessage",g_laser_nomessage);
+#else
+ WriteInt("smp",g_config_smp);
+ WriteInt("smp_mt",g_config_smp_mt);
+#endif
+#ifdef WA2_EMBED
+ WriteInt("wx",myWindowState.r.left);
+ WriteInt("wy",myWindowState.r.top);
+ WriteInt("ww",myWindowState.r.right-myWindowState.r.left);
+ WriteInt("wh",myWindowState.r.bottom-myWindowState.r.top);
+#else
+ WriteInt("cfg_x",cfg_x);
+ WriteInt("cfg_y",cfg_y);
+ WriteInt("cfg_w",cfg_w);
+ WriteInt("cfg_h",cfg_h);
+#endif
+ WritePrivateProfileString(AVS_SECTION,"config_pres_subdir",config_pres_subdir,INI_FILE);
+
+ WriteInt("cfg_docked",inWharf?1:0);
+ WriteInt("cfg_cfgwnd_open",cfg_cfgwnd_open);
+ WriteInt("cfg_cfgwnd_x",cfg_cfgwnd_x);
+ WriteInt("cfg_cfgwnd_y",cfg_cfgwnd_y);
+ WriteInt("cfg_fs_w",cfg_fs_w);
+ WriteInt("cfg_fs_h",cfg_fs_h);
+ WriteInt("cfg_fs_d",cfg_fs_d);
+ WriteInt("cfg_fs_bpp",cfg_fs_bpp);
+ WriteInt("cfg_fs_fps",cfg_fs_fps);
+ WriteInt("cfg_fs_rnd",cfg_fs_rnd);
+ WriteInt("cfg_fs_rnd_time",cfg_fs_rnd_time);
+ WriteInt("cfg_fs_dblclk",cfg_fs_dblclk);
+ WriteInt("cfg_fs_flip",cfg_fs_flip);
+ WriteInt("cfg_fs_height",cfg_fs_height);
+ WriteInt("cfg_fs_use_overlay",cfg_fs_use_overlay);
+ WriteInt("cfg_fs_cancelondeactivate",cfg_cancelfs_on_deactivate);
+ WriteInt("cfg_speed",cfg_speed);
+ WriteInt("cfg_trans",cfg_trans);
+ WriteInt("cfg_dont_min_avs",cfg_dont_min_avs);
+ WriteInt("cfg_smartbeat",cfg_smartbeat);
+ WriteInt("cfg_smartbeatsticky",cfg_smartbeatsticky);
+ WriteInt("cfg_smartbeatresetnewsong",cfg_smartbeatresetnewsong);
+ WriteInt("cfg_smartbeatonlysticky",cfg_smartbeatonlysticky);
+ WriteInt("cfg_transitions_en",cfg_transitions);
+ WriteInt("cfg_transitions_preinit",cfg_transitions2);
+ WriteInt("cfg_transitions_speed",cfg_transitions_speed);
+ WriteInt("cfg_transitions_mode",cfg_transition_mode);
+ WriteInt("cfg_bkgnd_render",cfg_bkgnd_render);
+ WriteInt("cfg_bkgnd_render_color",cfg_bkgnd_render_color);
+ WriteInt("cfg_render_prio",cfg_render_prio);
+ WriteInt("g_preset_dirty",C_UndoStack::isdirty());
+ WriteInt("cfg_prompt_save_preset",config_prompt_save_preset);
+ WritePrivateProfileString(AVS_SECTION,"last_preset_name",last_preset,INI_FILE);
+ WriteInt("cfg_reuseonresize",config_reuseonresize);
+ WriteInt("cfg_log_errors",g_log_errors);
+ WriteInt("cfg_reset_vars",g_reset_vars_on_recompile);
+ WriteInt("cfg_seh",g_config_seh);
+
+ int x;
+ for (x = 0; x < 8; x ++)
+ {
+ char debugreg[32];
+ wsprintf(debugreg,"debugreg_%d",x);
+ WriteInt(debugreg,debug_reg[x]);
+ }
+ }
+}
+
+
+void toggleWharfAmpDock(HWND hwnd)
+{
+ if (DDraw_IsFullScreen()) return;
+ HWND Wharf=g_hwndDlg?GetDlgItem(g_hwndDlg,IDC_RRECT):NULL;
+ if (!Wharf) return;
+
+ if (!inWharf)
+ {
+ RECT r,r2;
+
+ // show IDC_RRECT, resize IDC_TREE1 down
+ GetWindowRect(GetDlgItem(g_hwndDlg,IDC_RRECT),&r);
+ GetWindowRect(GetDlgItem(g_hwndDlg,IDC_TREE1),&r2);
+ SetWindowPos(GetDlgItem(g_hwndDlg,IDC_TREE1),NULL,0,0,r2.right-r2.left,r.top - 4 - r2.top,SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
+ ShowWindow(GetDlgItem(g_hwndDlg,IDC_RRECT),SW_SHOWNA);
+
+#ifdef WA2_EMBED
+ GetClientRect(hwnd,&r);
+ last_windowed_w=r.right;
+ last_windowed_h=r.bottom;
+#endif
+ inWharf=1;
+ GetWindowRect(Wharf, &r);
+ SetParent(hwnd, Wharf);
+#ifndef WA2_EMBED
+ SetWindowLong(hwnd, GWL_STYLE, (GetWindowLong(hwnd,GWL_STYLE)&(~WS_POPUP))|WS_CHILD);
+#else
+ HWND w = g_hWA2ParentWindow;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD)
+ {
+ w = GetParent(w);
+ }
+ if (!SendMessage(g_mod->hwndParent, WM_WA_IPC, (int)w, IPC_FF_ISMAINWND)) ShowWindow(w,SW_HIDE);
+ else ShowWindow(g_hWA2ParentWindow,SW_HIDE);
+#endif
+ SetWindowPos(hwnd, NULL, 0, 0, r.right-r.left, r.bottom-r.top, SWP_NOZORDER|SWP_NOACTIVATE);
+ DDraw_Resize(r.right-r.left, r.bottom-r.top,cfg_fs_d&2);
+ }
+ else
+ {
+
+ RECT r,r2;
+ // hide IDC_RRECT, resize IDC_TREE1 up
+ GetWindowRect(GetDlgItem(g_hwndDlg,IDC_RRECT),&r);
+ GetWindowRect(GetDlgItem(g_hwndDlg,IDC_TREE1),&r2);
+ ShowWindow(GetDlgItem(g_hwndDlg,IDC_RRECT),SW_HIDE);
+ SetWindowPos(GetDlgItem(g_hwndDlg,IDC_TREE1),NULL,0,0,r2.right-r2.left,r.bottom - r2.top - 2,SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
+
+#ifndef WA2_EMBED
+ SetWindowLong(hwnd, GWL_STYLE, (GetWindowLong(hwnd,GWL_STYLE)&(~(WS_CHILD|WS_VISIBLE)))|WS_POPUP);
+ SetParent(hwnd, NULL);
+ SetWindowPos(hwnd, NULL, cfg_x, cfg_y, cfg_w,cfg_h, SWP_NOZORDER|SWP_NOACTIVATE);
+ DDraw_Resize(cfg_w-7-6,cfg_h-15-5,cfg_fs_d&2);
+ ShowWindow(hwnd,SW_SHOWNA);
+#else
+ SetParent(hwnd, g_hWA2ParentWindow);
+ DDraw_Resize(last_windowed_w,last_windowed_h,cfg_fs_d&2);
+
+ HWND w = g_hWA2ParentWindow;
+ while (GetWindowLong(w, GWL_STYLE) & WS_CHILD)
+ {
+ w = GetParent(w);
+ }
+ if (SendMessage(g_mod->hwndParent, WM_WA_IPC, (int)w, IPC_FF_ISMAINWND))
+ w=g_hWA2ParentWindow;
+
+ PostMessage(GetParent(hwnd),WM_SIZE,0,0);
+
+ ShowWindow(w,SW_SHOWNA);
+
+ //SetWindowPos(hwnd,0,0,0,cfg_w,cfg_h,SWP_NOACTIVATE|SWP_NOZORDER);
+ //SetTimer(hwnd,66,500,NULL);
+#endif
+ InvalidateRect(Wharf,NULL,TRUE);
+ inWharf=0;
+ }
+}
+
+int findInMenu(HMENU parent, HMENU sub, UINT id, char *buf, int buf_len)
+{
+ int x,l=GetMenuItemCount(parent);
+ char *bufadd=buf+strlen(buf);
+ bufadd[0]='\\';
+ for (x = 0; x < l; x ++)
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_TYPE|MIIM_ID,};
+ mi.dwTypeData=bufadd+1;
+ mi.cch=buf_len - (bufadd-buf+2);
+ GetMenuItemInfo(parent,x,TRUE,&mi);
+ if (mi.hSubMenu)
+ {
+ if (sub && mi.hSubMenu == sub)
+ return 1;
+ if (findInMenu(mi.hSubMenu,sub,id,buf,buf_len))
+ return 1;
+ }
+ else
+ {
+ if (!sub && id && mi.wID == id)
+ return 1;
+ }
+ }
+ bufadd[0]=0;
+ return 0;
+}
+
+static int find_preset(char *parent_path, int dir, char *lastpreset, char *newpreset, int *state)
+{
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[4096];
+ wsprintf(dirmask,"%s\\*.avs",parent_path);
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (!(d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ wsprintf(dirmask,"%s\\%s",parent_path,d.cFileName);
+
+ if (lastpreset)
+ {
+ if (*state)
+ {
+ strcpy(newpreset,dirmask);
+ FindClose(h);
+ return 1;
+ }
+ if (dir > 0)
+ {
+ if (!newpreset[0]) // save the first one we find, in case we fail (wrap)
+ strcpy(newpreset,dirmask);
+
+ if (!stricmp(dirmask,lastpreset)) *state=1;
+ }
+ if (dir < 0)
+ {
+ if (!stricmp(dirmask,lastpreset))
+ {
+ if (newpreset[0]) { // if we find it first, skip it so we can go to the end :)
+ FindClose(h);
+ return 1;
+ }
+ }
+ strcpy(newpreset,dirmask);
+ }
+
+ }
+ else
+ {
+ int cnt=++(*state);
+ if (cnt < 1) cnt=1;
+ int r=((rand()&1023)<<10)|(rand()&1023);
+ if (r < (1024*1024)/cnt)
+ {
+ strcpy(newpreset,dirmask);
+ }
+ }
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+ wsprintf(dirmask,"%s\\*.*",parent_path);
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && d.cFileName[0] != '.')
+ {
+ wsprintf(dirmask,"%s\\%s",parent_path,d.cFileName);
+ if (find_preset(dirmask,dir,lastpreset,newpreset,state)) {
+ FindClose(h);
+ return 1;
+ }
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+ return 0;
+}
+
+void next_preset(HWND hwnd) {
+ g_rnd_cnt=0;
+
+ if (readyToLoadPreset(hwnd,0))
+ {
+ char dirmask[2048];
+ char i_path[1024];
+ if (config_pres_subdir[0]) wsprintf(i_path,"%s\\%s",g_path,config_pres_subdir);
+ else strcpy(i_path,g_path);
+
+ dirmask[0]=0;
+
+ int state=0;
+ find_preset(i_path,1,last_preset,dirmask,&state);
+
+ if (dirmask[0] && stricmp(last_preset,dirmask))
+ {
+ if (g_render_transition->LoadPreset(dirmask,2) != 2)
+ lstrcpyn(last_preset,dirmask,sizeof(last_preset));
+ }
+ }
+}
+
+void random_preset(HWND hwnd) {
+ g_rnd_cnt=0;
+ if (readyToLoadPreset(hwnd,0))
+ {
+ char dirmask[2048];
+ char i_path[1024];
+ if (config_pres_subdir[0]) wsprintf(i_path,"%s\\%s",g_path,config_pres_subdir);
+ else strcpy(i_path,g_path);
+
+ dirmask[0]=0;
+
+ int state=0;
+ find_preset(i_path,0,NULL,dirmask,&state);
+
+ if (dirmask[0])
+ {
+ if (g_render_transition->LoadPreset(dirmask,4) != 2)
+ lstrcpyn(last_preset,dirmask,sizeof(last_preset));
+ }
+ }
+}
+
+void previous_preset(HWND hwnd) {
+ g_rnd_cnt=0;
+ if (readyToLoadPreset(hwnd,0))
+ {
+ char dirmask[2048];
+ char i_path[1024];
+ if (config_pres_subdir[0]) wsprintf(i_path,"%s\\%s",g_path,config_pres_subdir);
+ else strcpy(i_path,g_path);
+
+ dirmask[0]=0;
+
+ int state=0;
+ find_preset(i_path,-1,last_preset,dirmask,&state);
+
+ if (dirmask[0] && stricmp(last_preset,dirmask))
+ {
+ if (g_render_transition->LoadPreset(dirmask,2) != 2)
+ lstrcpyn(last_preset,dirmask,sizeof(last_preset));
+ }
+ }
+}
+
+static HMENU presetTreeMenu;
+static int presetTreeCount;
+
+void DoPopupMenu() {
+ // Winamp3 Bug#331: Don't let the popupmenu pop when in fullscreen.
+ if (!DDraw_IsFullScreen())
+ {
+ void DDraw_NoUpdateScreen(int r);
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[1024];
+
+ if (presetTreeMenu) DestroyMenu(presetTreeMenu);
+
+ POINT p;
+ int x;
+ int insert_pos=0, directory_pos=0;
+ presetTreeMenu=CreatePopupMenu();
+
+ {
+ MENUITEMINFO i={sizeof(i),};
+ i.fMask=MIIM_TYPE|MIIM_DATA|MIIM_ID;
+ i.fType=MFT_STRING;
+ i.dwItemData=0;
+
+ i.wID = 1024;
+ i.dwTypeData=WASABI_API_LNGSTRING(IDS_FULLSCREEN);
+ i.cch=strlen(i.dwTypeData);
+ InsertMenuItem(presetTreeMenu,insert_pos++,TRUE,&i);
+
+ if (!inWharf)
+ {
+ i.wID = 256;
+ i.dwTypeData=WASABI_API_LNGSTRING(IDS_AVS_EDITOR);
+ i.cch=strlen(i.dwTypeData);
+ InsertMenuItem(presetTreeMenu,insert_pos++,TRUE,&i);
+ }
+
+ if (!DDraw_IsFullScreen())
+ {
+ i.wID = 512;
+ i.dwTypeData=WASABI_API_LNGSTRING(IDS_DOCK_IN_AVS_EDITOR);
+ i.cch=strlen(i.dwTypeData);
+ InsertMenuItem(presetTreeMenu,insert_pos++,TRUE,&i);
+ }
+
+ i.wID=0;
+ i.fType=MFT_SEPARATOR;
+ InsertMenuItem(presetTreeMenu,insert_pos++,TRUE,&i);
+ }
+
+ GetCursorPos(&p);
+ if (DDraw_IsFullScreen())
+ {
+ CheckMenuItem(presetTreeMenu,1024,MF_CHECKED);
+ }
+ if (IsWindowVisible(g_hwndDlg)) CheckMenuItem(presetTreeMenu,256,MF_CHECKED);
+ if (inWharf) CheckMenuItem(presetTreeMenu,512,MF_CHECKED);
+
+ wsprintf(dirmask,"%s\\*.*",g_path);
+
+ directory_pos=insert_pos;
+
+ presetTreeCount=1025;
+ h = FindFirstFile(dirmask,&d);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && d.cFileName[0] != '.')
+ {
+ MENUITEMINFO mi={sizeof(mi),MIIM_SUBMENU|MIIM_TYPE,MFT_STRING,MFS_DEFAULT
+ };
+ mi.hSubMenu=CreatePopupMenu();
+ mi.dwTypeData=d.cFileName;
+ mi.cch = strlen(d.cFileName);
+ InsertMenuItem(presetTreeMenu,directory_pos++,TRUE,&mi);
+ insert_pos++;
+ }
+ else if (!stricmp(extension(d.cFileName),"avs"))
+ {
+ extension(d.cFileName)[-1]=0;
+ MENUITEMINFO i={sizeof(i),MIIM_TYPE|MIIM_ID,MFT_STRING,MFS_DEFAULT };
+ i.dwTypeData = d.cFileName;
+ i.cch = strlen(d.cFileName);
+ i.wID=presetTreeCount++;
+ InsertMenuItem(presetTreeMenu,insert_pos++,TRUE,&i);
+ }
+ } while (FindNextFile(h,&d));
+ FindClose(h);
+ }
+
+ x=TrackPopupMenu(presetTreeMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON|TPM_LEFTBUTTON,p.x,p.y,0,g_hwnd,NULL);
+ if (x == 1024)
+ {
+ if (DDraw_IsFullScreen())
+ {
+ if (!cfg_fs_use_overlay) Wnd_GoWindowed(g_hwnd);
+ }
+ else
+ Wnd_GoFullScreen(g_hwnd);
+ }
+ else if (x == 512)
+ {
+ if (!inWharf && !cfg_cfgwnd_open)
+ {
+ cfg_cfgwnd_open=1;
+ ShowWindow(g_hwndDlg,SW_SHOWNA);
+ CfgWnd_RePopIfNeeded();
+ }
+ toggleWharfAmpDock(g_hwnd);
+ }
+ else if (x == 256)
+ {
+ SendMessage(g_hwnd,WM_USER+33,0,0);
+ }
+ else if (x >= 1025)
+ {
+ char buf[2048];
+ buf[0]=0;
+ if (readyToLoadPreset(g_hwnd,0))
+ {
+ if (findInMenu(presetTreeMenu,0,x,buf,2048))
+ {
+ char temp[4096];
+ wsprintf(temp,"%s%s.avs",g_path,buf);
+ if (g_render_transition->LoadPreset(temp,1) != 2)
+ lstrcpyn(last_preset,temp,sizeof(last_preset));
+ }
+ else
+ {
+// g_render_transition->LoadPreset
+// wsprintf(temp,"%s\\%s",g_path,curfilename);
+ }
+ }
+ }
+
+ DestroyMenu(presetTreeMenu);
+ presetTreeMenu=0;
+
+ }
+}
+
+static LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ if ( DDraw_IsFullScreen() &&
+ !cfg_fs_use_overlay &&
+ ( ( message == WM_KEYDOWN && wParam == VK_ESCAPE ) ||
+ message == WM_LBUTTONUP ||
+ ( message == WM_NCACTIVATE && !wParam ) ||
+ message == WM_KILLFOCUS
+ )
+ )
+ {
+ Wnd_GoWindowed( hwnd );
+ return 0;
+ }
+ else if ( message == WM_LBUTTONUP )
+ {
+ if ( !DDraw_IsFullScreen() )
+ {
+#ifndef WA2_EMBED
+ int x = GET_X_LPARAM( lParam );
+ int y = GET_Y_LPARAM( lParam );
+ RECT r;
+ GetClientRect( hwnd, &r );
+ if ( x > r.right - 12 && x < r.right - 3 && y > r.top + 3 && y < r.top + 13 )
+ {
+ g_in_destroy = 1;
+ DestroyWindow( hwnd );
+ }
+#endif
+ /*
+ else
+ {
+ static int lastdblclk;
+ if (lastdblclk && GetTickCount()-lastdblclk > 1000 && !inWharf)
+ DDraw_SetStatusText("double-click for configuration",600);
+ lastdblclk=GetTickCount();
+ }
+ */
+ }
+ }
+ if ( message == WM_LBUTTONDOWN )
+ {
+ SetFocus( g_hwnd );
+ if ( inWharf ) SetFocus( hwnd );
+ SetCapture( hwnd );
+ return 0;
+ }
+ if ( message == WM_LBUTTONUP )
+ {
+ POINT p;
+ RECT r;
+ p.x = GET_X_LPARAM( lParam );
+ p.y = GET_Y_LPARAM( lParam );
+ ClientToScreen( hwnd, &p );
+ if ( inWharf )
+ {
+ GetWindowRect( g_hwndDlg, &r );
+ if ( !PtInRect( &r, p ) )
+ {
+ toggleWharfAmpDock( hwnd );
+ }
+ }
+ else
+ {
+ RECT r2;
+ GetWindowRect( GetDlgItem( g_hwndDlg, IDC_TREE1 ), &r );
+ GetWindowRect( hwnd, &r2 );
+ if ( PtInRect( &r, p ) && cfg_cfgwnd_open && !PtInRect( &r2, p ) )
+ {
+ toggleWharfAmpDock( hwnd );
+ }
+ }
+ ReleaseCapture();
+ return 0;
+ }
+ if ( message == WM_LBUTTONDBLCLK && !DDraw_IsFullScreen() )
+ {
+ if ( cfg_fs_dblclk )
+ {
+ if ( DDraw_IsFullScreen() )
+ {
+ if ( !cfg_fs_use_overlay ) Wnd_GoWindowed( hwnd );
+ }
+ else
+ Wnd_GoFullScreen( hwnd );
+ }
+ else
+ {
+ if ( inWharf )
+ {
+ toggleWharfAmpDock( hwnd );
+ }
+ else if ( IsWindowVisible( g_hwndDlg ) )
+ {
+ cfg_cfgwnd_open = 0;
+ ShowWindow( g_hwndDlg, SW_HIDE );
+ }
+ else
+ {
+ cfg_cfgwnd_open = 1;
+ ShowWindow( g_hwndDlg, SW_SHOWNA );
+ CfgWnd_RePopIfNeeded();
+ }
+ }
+ return 0;
+ }
+
+ switch ( message )
+ {
+ case WM_USER + 1667:
+ if ( wParam == 1 && lParam == 2 )
+ {
+ char title[ 32 ];
+ MessageBox( hwnd, WASABI_API_LNGSTRING( IDS_CANNOT_GO_FULLSCREEN_WHEN_VIDEO_PLAYING ),
+ WASABI_API_LNGSTRING_BUF( IDS_AVS_FULLSCREEN, title, 32 ),
+ MB_OK | MB_ICONINFORMATION );
+ }
+ return 0;
+ case WM_USER + 1666:
+ if ( wParam == 1 && lParam == 15 )
+ {
+ if ( DDraw_IsFullScreen() )
+ {
+ if ( cfg_fs_use_overlay ) SetFocus( hwnd ); // kill overlay window
+ else Wnd_GoWindowed( hwnd );
+ }
+ }
+ return 0;
+ case WM_INITMENUPOPUP:
+ if ( HIWORD( lParam ) == 0 && presetTreeMenu && !GetMenuItemCount( (HMENU) wParam ) )
+ {
+ char buf[ 2048 ];
+ buf[ 0 ] = 0;
+ if ( findInMenu( presetTreeMenu, (HMENU) wParam, 0, buf, 2048 ) )
+ {
+ HANDLE h;
+ WIN32_FIND_DATA d;
+ char dirmask[ 4096 ];
+ wsprintf( dirmask, "%s%s\\*.*", g_path, buf );
+ int directory_pos = 0, insert_pos = 0;
+ // build menu
+ h = FindFirstFile( dirmask, &d );
+ if ( h != INVALID_HANDLE_VALUE )
+ {
+ do
+ {
+ if ( d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && d.cFileName[ 0 ] != '.' )
+ {
+ MENUITEMINFO mi = { sizeof( mi ),MIIM_SUBMENU | MIIM_TYPE,MFT_STRING,MFS_DEFAULT };
+ mi.hSubMenu = CreatePopupMenu();
+ mi.dwTypeData = d.cFileName;
+ mi.cch = strlen( d.cFileName );
+ InsertMenuItem( (HMENU) wParam, directory_pos++, TRUE, &mi );
+ insert_pos++;
+ }
+ else if ( !stricmp( extension( d.cFileName ), "avs" ) )
+ {
+ extension( d.cFileName )[ -1 ] = 0;
+ MENUITEMINFO i = { sizeof( i ),MIIM_TYPE | MIIM_ID,MFT_STRING,MFS_DEFAULT };
+ i.dwTypeData = d.cFileName;
+ i.cch = strlen( d.cFileName );
+ i.wID = presetTreeCount++;
+ InsertMenuItem( (HMENU) wParam, insert_pos++, TRUE, &i );
+ }
+ } while ( FindNextFile( h, &d ) );
+ FindClose( h );
+ }
+ }
+ }
+ return 0;
+ case WM_RBUTTONUP:
+ DoPopupMenu();
+ return 0;
+ case WM_USER + 33:
+ DDraw_SetStatusText( "", 100 );
+ if ( inWharf )
+ {
+ toggleWharfAmpDock( hwnd );
+ }
+ else if ( IsWindowVisible( g_hwndDlg ) )
+ {
+ cfg_cfgwnd_open = 0;
+ ShowWindow( g_hwndDlg, SW_HIDE );
+ }
+ else
+ {
+ cfg_cfgwnd_open = 1;
+ ShowWindow( g_hwndDlg, SW_SHOWNA );
+ CfgWnd_RePopIfNeeded();
+ }
+ return 0;
+ case WM_USER + 32:
+ Wnd_GoFullScreen( hwnd );
+ return 0;
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ if ( ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) && wParam == VK_F4 )
+ {
+ SendMessage( hwnd, WM_CLOSE, 0, 0 );
+ return 0;
+ }
+ if ( ( GetAsyncKeyState( VK_MENU ) & 0x8000 ) && wParam == VK_F4 )
+ {
+ PostMessage( hwnd_WinampParent, message, wParam, lParam );
+ break;
+ }
+
+ if ( wParam == VK_SPACE )
+ {
+ do_random:
+ random_preset( hwnd );
+ }
+ else if ( wParam == 0x55 )
+ {
+ next_preset( hwnd );
+ }
+ else if ( wParam == 0x59 )
+ {
+ previous_preset( hwnd );
+ }
+ else if ( wParam == VK_RETURN )
+ {
+ if ( GetAsyncKeyState( VK_MENU ) & 0x8000 )
+ {
+ if ( DDraw_IsFullScreen() )
+ {
+ if ( !cfg_fs_use_overlay ) Wnd_GoWindowed( hwnd );
+ }
+ else
+ Wnd_GoFullScreen( hwnd );
+ }
+ }
+ else if ( wParam == /* VK_T */ 0x54 )
+ {
+ extern int draw_title_p;
+ draw_title_p = 2;
+ }
+ else if ( wParam == /* VK_F */ 0x52 + 'F' - 'R' )
+ {
+ cfg_fs_fps ^= 1;
+ DDraw_SetStatusText( WASABI_API_LNGSTRING( cfg_fs_fps & 1 ? IDS_FULLSCREEN_FPS_ON : IDS_FULLSCREEN_FPS_OFF ) );
+ }
+ else if ( wParam == /* VK_R */ 0x52 )
+ {
+ cfg_fs_rnd = !cfg_fs_rnd;
+ g_rnd_cnt = 0;
+ DDraw_SetStatusText( WASABI_API_LNGSTRING( cfg_fs_rnd ? IDS_RANDOM_PRESETS_ON : IDS_RANDOM_PRESETS_OFF ) );
+ }
+ else if ( wParam >= VK_F1 && wParam <= VK_F12 )
+ {
+ char s[ 128 ], *st, stBuf[ 48 ];
+ if ( GetAsyncKeyState( VK_CONTROL ) & ( 1 << 15 ) )
+ {
+ st = WASABI_API_LNGSTRING_BUF( IDS_SAVED_TO, stBuf, 48 );
+ WritePreset( wParam - VK_F1 );
+ }
+ else
+ {
+ if ( !readyToLoadPreset( hwnd, 0 ) ) return 0;
+
+ if ( LoadPreset( wParam - VK_F1 ) ) st = WASABI_API_LNGSTRING_BUF( IDS_LOADED_FROM, stBuf, 48 );
+ else st = WASABI_API_LNGSTRING_BUF( IDS_ERROR_LOADING_FROM, stBuf, 48 );
+ }
+ wsprintf( s, "%s F%d", st, wParam - VK_F1 + 1 );
+ DDraw_SetStatusText( s );
+ }
+ else if ( wParam >= '0' && wParam <= '9' )
+ {
+ int n = 0;
+ char s[ 128 ], *st, stBuf[ 48 ];
+ if ( GetAsyncKeyState( VK_SHIFT ) & ( 1 << 15 ) )
+ n = 10;
+ if ( GetAsyncKeyState( VK_CONTROL ) & ( 1 << 15 ) )
+ {
+ st = WASABI_API_LNGSTRING_BUF( IDS_SAVED_TO, stBuf, 48 );
+ WritePreset( wParam - '0' + 12 + n );
+ }
+ else
+ {
+ if ( !readyToLoadPreset( hwnd, 0 ) ) return 0;
+ if ( LoadPreset( wParam - '0' + 12 + n ) ) st = WASABI_API_LNGSTRING_BUF( IDS_LOADED_FROM, stBuf, 48 );
+ else st = WASABI_API_LNGSTRING_BUF( IDS_ERROR_LOADING_FROM, stBuf, 48 );
+ }
+ wsprintf( s, "%s %s%d", st, n ? WASABI_API_LNGSTRING( IDS_SHIFT_ ) : "", wParam - '0' );
+ DDraw_SetStatusText( s );
+ }
+ else
+ {
+ if ( wParam == 0x4B && DDraw_IsFullScreen() )
+ {
+ if ( !cfg_fs_use_overlay ) Wnd_GoWindowed( hwnd );
+ }
+ else PostMessage( hwnd_WinampParent, message, wParam, lParam );
+ }
+ return 0;
+ case WM_TIMER:
+#ifndef WA2_EMBED
+ if ( wParam == 66 )
+ {
+ KillTimer( hwnd, 66 );
+ SetWindowPos( hwnd, 0, 0, 0, cfg_w, cfg_h, SWP_NOACTIVATE | SWP_NOZORDER );
+ }
+#endif
+ if ( wParam == 88 )
+ {
+ KillTimer( hwnd, 88 );
+ if ( cfg_cfgwnd_open )
+ {
+ ShowWindow( g_hwndDlg, SW_SHOWNA );
+ UpdateWindow( g_hwndDlg );
+ CfgWnd_RePopIfNeeded();
+ }
+
+ if ( need_redock && g_hwndDlg )
+ {
+ need_redock = 0;
+ toggleWharfAmpDock( hwnd );
+ }
+ }
+ if ( wParam == 32 )
+ {
+ DWORD a;
+
+#ifndef REAPLAY_PLUGIN
+ if ( SendMessageTimeout( hwnd_WinampParent, WM_USER, (WPARAM) 0, 201, SMTO_BLOCK, 1000, &a ) && a )
+ {
+ if ( strcmp( g_skin_name, (char *) a ) )
+ {
+ lstrcpyn( g_skin_name, (char *) a, sizeof( g_skin_name ) );
+ PostMessage( hwnd, WM_DISPLAYCHANGE, 0, 0 );
+ }
+ }
+#endif
+
+ if ( g_rnd_cnt >= 0 && g_rnd_cnt++ >= max( cfg_fs_rnd_time, 1 ) )
+ {
+ g_rnd_cnt = 0;
+ if ( ( !IsWindowVisible( g_hwndDlg ) || DDraw_IsFullScreen() ) && cfg_fs_rnd )
+ goto do_random;
+ }
+ }
+ if ( wParam == 30 )
+ {
+ KillTimer( hwnd, 30 );
+ if ( !DDraw_IsFullScreen() && !inWharf )
+ {
+ InvalidateRect( hwnd, NULL, FALSE );
+ int tm = ( GetWindowLong( g_mod->hwndParent, GWL_EXSTYLE ) & WS_EX_TOPMOST ) == WS_EX_TOPMOST;
+ SetWindowPos( hwnd, tm ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+ RECT r;
+ GetClientRect_adj( hwnd, &r );
+ DDraw_Resize( r.right - r.left, r.bottom - r.top, cfg_fs_d & 2 );
+ }
+ }
+#ifndef WA2_EMBED
+ if ( wParam == 29 )
+ {
+ if ( !IsIconic( hwnd_WinampParent ) )
+ {
+ KillTimer( hwnd, 29 );
+ g_mod->Quit( g_mod );
+ g_minimized = 0;
+ g_fakeinit = 1;
+ g_mod->Init( g_mod );
+ g_fakeinit = 0;
+ SetActiveWindow( g_mod->hwndParent );
+ }
+ }
+#endif
+ return 0;
+ case WM_DROPFILES:
+ {
+ char temp[ MAX_PATH ];
+ HDROP hdrop = (HDROP) wParam;
+ DragQueryFile( hdrop, 0, temp, sizeof( temp ) );
+ if ( readyToLoadPreset( hwnd, 0 ) )
+ {
+ if ( !stricmp( extension( temp ), "avs" ) )
+ {
+ if ( g_render_transition->LoadPreset( temp, 1 ) != 2 )
+ lstrcpyn( last_preset, temp, sizeof( last_preset ) );
+ }
+ }
+ DragFinish( hdrop );
+ }
+ return 0;
+ case WM_DISPLAYCHANGE:
+#ifndef WA2_EMBED
+ SelectObject( hFrameDC, hFrameBitmap_old );
+ DeleteObject( hFrameBitmap );
+ hFrameBitmap = NULL;
+ {
+ char buf[ MAX_PATH ];
+ if ( SendMessage( hwnd_WinampParent, WM_USER, (WPARAM) buf, 201 ) )
+ {
+ strcat( buf, "\\avs.bmp" );
+ hFrameBitmap = (HBITMAP) LoadImage( g_hInstance, buf, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE );
+ }
+ if ( !hFrameBitmap )
+ hFrameBitmap = (HBITMAP) LoadImage( g_hInstance, MAKEINTRESOURCE( IDB_BITMAP1 ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
+ }
+ hFrameBitmap_old = (HBITMAP) SelectObject( hFrameDC, hFrameBitmap );
+#endif
+ InvalidateRect( hwnd, NULL, FALSE );
+ return 0;
+ case WM_CREATE:
+ g_hwnd = hwnd;
+
+ if ( DDraw_Init() )
+ {
+ return 1;
+ }
+
+#ifndef WA2_EMBED
+
+ {
+ char buf[ MAX_PATH ];
+ int a;
+ if ( ( a = SendMessage( hwnd_WinampParent, WM_USER, (WPARAM) buf, 201 ) ) )
+ {
+ lstrcpyn( g_skin_name, (char *) a, sizeof( g_skin_name ) );
+ strcat( buf, "\\avs.bmp" );
+ hFrameBitmap = (HBITMAP) LoadImage( g_hInstance, buf, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE );
+ }
+ if ( !hFrameBitmap )
+ hFrameBitmap = (HBITMAP) LoadImage( g_hInstance, MAKEINTRESOURCE( IDB_BITMAP1 ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
+ }
+ hFrameDC = (HDC) CreateCompatibleDC( NULL );
+ hFrameBitmap_old = (HBITMAP) SelectObject( hFrameDC, hFrameBitmap );
+#endif
+ //FG> This totally fucks up a child layered window painting in wa3, i'm not even sure that's a good thing for wa2... basically the child window gets excluded from the layered update and ends up updating behind the layer, on top of the desktop
+#ifndef WA2_EMBED
+ SetWindowLong( hwnd, GWL_STYLE, 0 );
+ SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME | SWP_NOACTIVATE );
+#endif
+ SetTimer( hwnd, 32, 1000, NULL );
+ return 0;
+#ifndef WA2_EMBED
+ case WM_NCHITTEST:
+ {
+ int x = GET_X_LPARAM( lParam );
+ int y = GET_Y_LPARAM( lParam );
+ RECT r;
+ GetWindowRect( hwnd, &r );
+ if ( inWharf )
+ return HTCLIENT;
+ if ( DDraw_IsFullScreen() || ( x > r.right - 12 && x < r.right - 3 && y > r.top + 3 && y < r.top + 13 ) )
+ return HTCLIENT;
+ if ( x < r.left + 6 && y > r.bottom - 6 ) return HTBOTTOMLEFT;
+ if ( x > r.right - 6 && y > r.bottom - 6 ) return HTBOTTOMRIGHT;
+ if ( x < r.left + 6 && y < r.top + 6 ) return HTTOPLEFT;
+ if ( x > r.right - 6 && y < r.top + 6 ) return HTTOPRIGHT;
+ if ( y < r.top + 6 ) return HTTOP;
+ if ( y > r.bottom - 6 ) return HTBOTTOM;
+ if ( x < r.left + 6 ) return HTLEFT;
+ if ( x > r.right - 6 ) return HTRIGHT;
+ if ( y < r.top + 15 ) return HTCAPTION;
+ }
+ return HTCLIENT;
+#endif
+ case WM_CLOSE:
+#ifndef WA2_EMBED
+ g_in_destroy = 1;
+ DestroyWindow( hwnd );
+#else
+ g_in_destroy = 1;
+ SetForegroundWindow( g_mod->hwndParent );
+ DestroyWindow( myWindowState.me );
+#endif
+ return 0;
+ case WM_DESTROY:
+#ifndef WA2_EMBED
+ SelectObject( hFrameDC, hFrameBitmap_old );
+ DeleteObject( hFrameDC );
+ DeleteObject( hFrameBitmap );
+#endif
+ g_ThreadQuit = 1;
+ if ( !g_minimized )
+ {
+ PostQuitMessage( 0 );
+ }
+ return 0;
+ case WM_MOVE:
+ if ( !DDraw_IsFullScreen() && !inWharf )
+ {
+#ifndef WA2_EMBED
+ int w;
+ RECT r;
+ RECT r2;
+ int xPos, yPos, f = 0;
+ xPos = (int) (short) LOWORD( lParam ); // horizontal position
+ yPos = (int) (short) HIWORD( lParam ); // vertical position
+ GetClientRect( hwnd, &r2 );
+
+ for ( w = 0; w < 5; w++ )
+ {
+ HWND hw;
+ if ( w == 0 )
+ {
+ RECT r2;
+ GetWindowRect( hwnd, &r2 );
+ my_getViewport( &r, &r2 );
+ }
+ else if ( w == 1 && IsWindowVisible( hwnd_WinampParent ) )
+ GetWindowRect( hwnd_WinampParent, &r );
+ else if ( w == 2 && ( hw = FindWindowEx( NULL, NULL, "Winamp EQ", NULL ) )
+ && IsWindowVisible( hw ) )
+ GetWindowRect( hw, &r );
+ else if ( w == 3 && ( hw = FindWindowEx( NULL, NULL, "Winamp PE", NULL ) )
+ && IsWindowVisible( hw ) )
+ GetWindowRect( hw, &r );
+ else if ( w == 4 && ( hw = FindWindowEx( NULL, NULL, "Winamp MB", NULL ) )
+ && IsWindowVisible( hw ) )
+ GetWindowRect( hw, &r );
+ else continue;
+
+#define intersect(x1,x2,y1,y2) \
+ (((x1)>(y1)&&(x1)<(y2))||((x2)>(y1)&&(x2)<(y2))||((y1)>(x1)&&(y1)<(x2))||((y2)>(x1)&&(y2)<(x2)))
+
+ if ( xPos > r.left - 10 && xPos < r.left + 10 && intersect( yPos, yPos + r2.bottom, r.top, r.bottom ) )
+ {
+ xPos = r.left;
+ f++;
+ }
+ if ( yPos > r.top - 10 && yPos < r.top + 10 && intersect( xPos, xPos + r2.right, r.left, r.right ) )
+ {
+ yPos = r.top;
+ f++;
+ }
+ if ( xPos + r2.right > r.right - 10 && xPos + r2.right < r.right + 10 && intersect( yPos, yPos + r2.bottom, r.top, r.bottom ) )
+ {
+ xPos = r.right - r2.right;
+ f++;
+ }
+ if ( yPos + r2.bottom > r.bottom - 10 && yPos + r2.bottom < r.bottom + 10 && intersect( xPos, xPos + r2.right, r.left, r.right ) )
+ {
+ yPos = r.bottom - r2.bottom;
+ f++;
+ }
+
+
+
+ if ( xPos + r2.right > r.left - 10 && xPos + r2.right < r.left + 10 && intersect( yPos, yPos + r2.bottom, r.top, r.bottom ) )
+ {
+ xPos = r.left - r2.right;
+ f++;
+ }
+ if ( yPos + r2.bottom > r.top - 10 && yPos + r2.bottom < r.top + 10 && intersect( xPos, xPos + r2.right, r.left, r.right ) )
+ {
+ yPos = r.top - r2.bottom;
+ f++;
+ }
+ if ( xPos > r.right - 10 && xPos < r.right + 10 && intersect( yPos, yPos + r2.bottom, r.top, r.bottom ) )
+ {
+ xPos = r.right;
+ f++;
+ }
+ if ( yPos > r.bottom - 10 && yPos < r.bottom + 10 && intersect( xPos, xPos + r2.right, r.left, r.right ) )
+ {
+ yPos = r.bottom;
+ f++;
+ }
+ }
+
+ if ( f )
+ {
+ SetWindowPos( hwnd, NULL, xPos, yPos, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ }
+ {
+ RECT r;
+ GetWindowRect( hwnd, &r );
+ cfg_x = r.left;
+ cfg_y = r.top;
+ cfg_w = r.right - r.left;
+ cfg_h = r.bottom - r.top;
+ }
+#endif
+ }
+ return 0;
+ case WM_GETMINMAXINFO:
+ {
+ LPMINMAXINFO mmi = (LPMINMAXINFO) lParam;
+ mmi->ptMinTrackSize.x = 80;
+ mmi->ptMinTrackSize.y = 40;
+ }
+ return 0;
+ case WM_SETCURSOR:
+ if ( DDraw_IsFullScreen() )
+ {
+ SetCursor( NULL );
+ return TRUE;
+ }
+ break;
+ case WM_SIZE:
+ if ( wParam != SIZE_MINIMIZED )
+ {
+ if ( !DDraw_IsFullScreen() )
+ {
+ if ( !inWharf )
+ {
+#ifndef WA2_EMBED
+ RECT r;
+ GetWindowRect( hwnd, &r );
+ cfg_x = r.left;
+ cfg_y = r.top;
+ cfg_w = r.right - r.left;
+ cfg_h = r.bottom - r.top;
+#endif
+ DDraw_BeginResize();
+ KillTimer( hwnd, 30 );
+ SetTimer( hwnd, 30, 33, NULL );
+ }
+ }
+ }
+ break;
+ case WM_WINDOWPOSCHANGING:
+ {
+ LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;
+ if ( cfg_dont_min_avs && !g_in_destroy && lpwp->flags & SWP_HIDEWINDOW && !g_minimized && !inWharf )
+ {
+#ifndef WA2_EMBED
+ g_minimized = 1;
+ g_mod->Quit( g_mod );
+ g_fakeinit = 1;
+ g_mod->Init( g_mod );
+ g_fakeinit = 0;
+ if ( ( GetWindowLong( g_mod->hwndParent, GWL_EXSTYLE ) & WS_EX_TOPMOST ) == WS_EX_TOPMOST )
+ SetWindowPos( g_hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
+ SetTimer( g_hwnd, 29, 500, NULL );
+#endif
+ }
+ }
+ return 0;
+ case WM_PAINT:
+ if ( !DDraw_IsFullScreen() )
+ {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint( hwnd, &ps );
+#ifndef WA2_EMBED
+ RECT r;
+ HDC tempdc = CreateCompatibleDC( hdc );
+ GetClientRect( hwnd, &r );
+ HBITMAP oldbm, tempbm = CreateCompatibleBitmap( hdc, 7, r.bottom - 20 );
+ oldbm = (HBITMAP) SelectObject( tempdc, tempbm );
+ if ( !inWharf )
+ { // draw window frame
+ SetStretchBltMode( hdc, COLORONCOLOR );
+ SetStretchBltMode( tempdc, COLORONCOLOR );
+ BitBlt( hdc, 0, 0, 50, 15, hFrameDC, 15, 0, SRCCOPY ); // top left
+ StretchBlt( hdc, 50, 0, r.right - 50 - 16, 15, hFrameDC, 66, 0, 14, 15, SRCCOPY ); // top middle
+ BitBlt( hdc, r.right - 16, 0, 16, 15, hFrameDC, 81, 0, SRCCOPY ); // top right
+
+ StretchBlt( tempdc, 0, 0, 7, r.bottom - 15 - 5, hFrameDC, 0, 16, 7, 172, SRCCOPY ); // left middle
+ BitBlt( hdc, 0, 15, 7, r.bottom - 15 - 5, tempdc, 0, 0, SRCCOPY );
+ StretchBlt( tempdc, 0, 0, 6, r.bottom - 15 - 5, hFrameDC, 8, 16, 6, 172, SRCCOPY ); // right middle
+ BitBlt( hdc, r.right - 6, 15, 6, r.bottom - 15 - 5, tempdc, 0, 0, SRCCOPY );
+
+ BitBlt( hdc, 0, r.bottom - 5, 50, 15, hFrameDC, 15, 16, SRCCOPY ); // bottom left
+ StretchBlt( hdc, 50, r.bottom - 5, r.right - 50 - 16, 5, hFrameDC, 66, 16, 14, 5, SRCCOPY ); // bottom middle
+ BitBlt( hdc, r.right - 16, r.bottom - 5, 16, 5, hFrameDC, 81, 16, SRCCOPY ); // bottom right
+ }
+ SelectObject( tempdc, oldbm );
+ DeleteObject( tempbm );
+ DeleteObject( tempdc );
+#endif
+ EndPaint( hwnd, &ps );
+ return 0;
+ }
+ break;
+#ifdef WA2_EMBED
+ case WM_COMMAND:
+ {
+ int id = LOWORD( wParam );
+ switch ( id )
+ {
+ case ID_VIS_NEXT: next_preset( hwnd ); break;
+ case ID_VIS_PREV: previous_preset( hwnd ); break;
+ case ID_VIS_RANDOM:
+ {
+ int v = HIWORD( wParam ) ? 1 : 0;
+ if ( wParam >> 16 == 0xFFFF )
+ {
+ SendMessage( g_mod->hwndParent, WM_WA_IPC, cfg_fs_rnd, IPC_CB_VISRANDOM );
+ break;
+ }
+ cfg_fs_rnd = v;
+ if ( cfg_fs_rnd ) random_preset( hwnd );
+ DDraw_SetStatusText( WASABI_API_LNGSTRING( cfg_fs_rnd ? IDS_RANDOM_PRESETS_ON : IDS_RANDOM_PRESETS_OFF ) );
+ break;
+ }
+ case ID_VIS_FS: Wnd_GoFullScreen( hwnd ); break;
+ case ID_VIS_CFG: SendMessage( hwnd, WM_USER + 33, 0, 0 ); break;
+ case ID_VIS_MENU: DoPopupMenu(); break;
+ }
+ break;
+ }
+#endif
+ }
+ return DefWindowProc( hwnd, message, wParam, lParam );
+}
diff --git a/Src/Plugins/Visualization/vis_avs/wnd.h b/Src/Plugins/Visualization/vis_avs/wnd.h
new file mode 100644
index 00000000..9cf4605e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/wnd.h
@@ -0,0 +1,39 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+int Wnd_Init(struct winampVisModule *this_mod);
+void Wnd_Quit(void);
+void SetTransparency(HWND hWnd, int enable, int amount);
+HWND GetWinampHwnd(void);
+void about(HWND hwndParent);
+
+extern HWND g_hwnd;
+extern HINSTANCE g_hInstance;
+extern int g_in_destroy;
+extern int g_rnd_cnt;
diff --git a/Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT b/Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT
new file mode 100644
index 00000000..3e98969e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT
@@ -0,0 +1,1022 @@
+
+-----------------------------------------------------------------------
+ WINAMP 2.X VISUALIZATION PLUG-IN "MEGA SDK"
+ ('Vis Mega SDK' for short)
+ ('VMS' for shorter)
+-----------------------------------------------------------------------
+ Description: A codebase for rapidly creating robust and feature-rich
+ DX8-based visualization plug-ins of your own.
+ Version: custom version based on 1.05 beta 1; upgraded to use DX9.
+ Released: n/a
+ Author: Ryan Geiss
+ Copyright: (c) 2002-2007 Nullsoft, Inc.
+ VMS HOMEPAGE: http://www.nullsoft.com/free/vms/
+ VMS AT WINAMP: http://www.winamp.com/nsdn/winamp2x/dev/plugins/vis.jhtml
+ SUPPORT FORUM: http://forums.winamp.com/forumdisplay.php?forumid=147
+-----------------------------------------------------------------------
+
+
+TABLE OF CONTENTS
+-----------------
+ 1. Purpose of this package
+ 2. Features
+ 3. Required software
+ 4. Setting up the build environment
+ 5. Starting Your Own Plugin Based on the Framework
+ 6. Writing your own Plugin: A Brief Tour
+ 7. Order of Function Calls
+ 8. Using Data From the Base Class (CPluginShell)
+ 9. Adding Controls to the Config Panel
+ 10. Enabling Additional Tabs (pages) on the Config Panel
+ 11. Using Visual C++ to Debug your Plugin
+ 12. Releasing a Plugin
+ 13. Tips to pass on the the user, in your documentation
+ 14. Performance Tips for DirectX 8
+ 15. Other Resources
+ 16. Known Bugs
+ 17. Version History
+ 18. License
+
+
+Purpose of this package
+-----------------------
+ This package is for DEVELOPERS who want to write their own
+ visualization plugins.
+
+ It aims to provide a codebase that enables all developers
+ (beginning to advanced) to easily build robust Winamp 2.x
+ visualization plugins whose graphics are to be generated
+ though the DirectX 8 API. This codebase will 1) drastically
+ reduce the time it takes to write your plugin, 2) ensure
+ that it is robust (if you follow directions), and 3) give
+ you built-in support for many cool features, such as
+ multiple monitors. (See below for more details.)
+
+ Feel free to base any plugins on this "framework".
+
+
+Features
+--------
+ -DESKTOP MODE. Lets your plugin run as animated wallpaper,
+ with very little CPU overhead. (Your plugin can also
+ run in windowed or fullscreen modes, and the user can
+ switch between all 3 on the fly.)
+ -SUPERIOR MULTIMON SUPPORT. Your plugin will work on systems
+ with multiple display adapters, as well as systems with
+ a multi-head card. For multi-head cards that treat all
+ screens as one giant display (ie. resolutions like 2048x768
+ or 1024x1536), your users can even use 'fake' fullscreen mode
+ to run your plugin fullscreen on just one monitor!
+ -SOUND ANALYSIS: the framework provides your plugin with a
+ super-high-quality FFT (fast fourier transform) for doing your
+ own frequency analysis, or for drawing spectra. Framework also
+ provides super-simple loudness levels for 3 bands (bass,
+ mids, and treble) and at varying attenuation (damping) rates.
+ -A very nice CONFIGURATION PANEL is provided for the plugin.
+ On the first page (tab) of the config panel are all the
+ settings that all plugins share in common [handled by VMS];
+ on subsequent tabs, you add your own controls, for settings
+ that are specific to your plugin. The example plugin also
+ shows you how to easily handle the reading/writing of settings
+ that you add to/from the .INI file that will store your
+ plugin's settings.
+ -OTHER PERKS like a runtime help screen and playlist; high-precision
+ timing (accurate to 10 microseconds, or 0.00001 seconds);
+ pause-filtering (so your timing code won't got haywire
+ when Winamp is unpaused); and many others.
+ -CPU-FRIENDLY: when the window is minimized, or when you're
+ in fullscreen mode and ALT-TAB out, the plugin sleeps to
+ preserve CPU. FPS limiting also does its best to preserve
+ CPU, while at the same time, accurately limiting the FPS.
+ -ERROR FEEDBACK: provides detailed error messages to the user
+ on failure, as well as suggestions on how to fix problems.
+
+
+Required software
+-----------------
+ 1. Nullsoft Winamp 2.X (~1 MB)
+ http://www.winamp.com/
+ 2. Microsoft DirectX 8.0+ - (~11 MB)
+ http://www.microsoft.com/windows/directx/
+ 3. Microsoft Developer Studio (Visual C++) 6.0
+ (a retail product)
+ 4. Microsoft DirectX 8.0 SDK (Software Development Kit) - (~173 MB)
+ http://www.microsoft.com/windows/directx/
+ (then click the 'msdn' icon in the lower right, under
+ "info for developers")
+ *** NOTE that you can use a later SDK, such as 8.1b; but if you
+ do, then your plugin will only run on systems with that version
+ (or later) of the DirectX runtime installed! ***
+ *** You can also install several versions of the SDK into
+ different directories, and as long as the 8.0 sdk paths are
+ selected in Dev Studio (see below), your plugin will only
+ require the 8.0 runtime. ***
+ 5. MSDN (Microsoft Developer Network) help library (OPTIONAL) (~1GB)
+ (also a retail product; optional, but highly recommended
+ to have around. If you can't get the CD's, though, you
+ can always access the help database online at
+ http://msdn.microsoft.com/library/ )
+
+
+Setting up the build environment
+--------------------------------
+ [Note: for Visual C++ .Net users, see below]
+
+ 1. Make sure DirectX 8.0 or later is installed.
+ 2. Make sure the DirectX 8.0 SDK (source development kit) is installed.
+ ** (see notes above & below) **
+ 3. Configure Visual C++ to use the [appropriate] DX8 SDK:
+
+ In Visual C++, go to Tools, then Options. Click on the
+ 'Directories' tab. Under 'Show directories for:', select
+ 'Include Files.' Then, below, add the INCLUDE folder
+ underneath the folder into which you installed the DX8 SDK.
+ Now highlight your addition and use the fancy-looking 'up'
+ arrow icon to move it to the top of the list of directories.
+
+ Now do the same thing for the LIB folder. Under 'Show
+ directories for:', select 'Library Files.' Now add the LIB
+ folder underneath the folder into which you installed the
+ DX8 SDK. Again, use the fancy-looking 'up' arrow icon
+ to move it to the top of the list of directories.
+
+ *** NOTE that if you have multiple DirectX 8 SDK's (such as 8.0
+ and 8.1b) installed to different directories, you'll want the
+ earliest one (hopefully 8.0) to be first in the list; that's
+ the one that will get used when you compile & link. Otherwise,
+ your plugin will only run on systems with the other version
+ (or later) of the DirectX runtime installed! ***
+
+ 4. (optional) you might want to set Visual C++ up to use
+ 4 spaces instead of symbolic tabs, to keep the formatting
+ of new code that you write consistent with this code.
+ If you want to do this, go to menu:Tools->Options, click
+ the 'Tabs' tab, set the 'Tab Size' to 4 and click on
+ 'Insert Spaces'.
+
+ [FOR VISUAL C++ .NET USERS:]
+ You'll want to start a fresh DLL-based project and manually
+ add all the source/header files to it. Then go into project
+ settings and make it **Use MFC in a SHARED DLL**.
+
+
+Starting Your Own Plugin Based on the Framework
+-----------------------------------------------
+ 1. Copy the files in the 'ExPlugin' folder to a new folder,
+ such as 'MyPlugin' - it can be anything.
+ 2. In the new folder, rename the workspace file ExPlugin.dsw
+ to MyPlugin.dsw (or equivalent).
+ 3. Open the new workspace file (that you just renamed) in Visual C++.
+ 4. Go to menu:Build->Configurations and select 'plugin - Win32 Debug'.
+ 5. Go to menu:Project->Settings
+ a. In the upper-left corner, where it says 'Settings For:',
+ select 'All Configurations' from the dropdown box.
+ b. Click the 'debug' tab, and under 'Executable for debug
+ session', point it to winamp.exe (most likely
+ c:\program files\winamp\winamp.exe). (This will enable
+ you to debug your plugin using Visual C++.)
+ c. Click the 'link' tab, and under 'Output file name',
+ enter the name of the .DLL to write (such as
+ c:\program files\winamp\plugins\vis_myplugin.dll).
+ This should start with 'vis_' and end in the
+ '.dll' extension. This DLL will be your plugin.
+ d. click OK.
+ 6. On the left you should see the workspace view (if not, hit ALT+ZERO)
+ to bring it up) with 3 tabs at the bottom (ClassView, ResourceView,
+ FileView). Click 'FileView'. Expand everything in this view so you
+ can see all the files.
+ 7. Open 'defines.h' by double-clicking it. Now edit this file according
+ to the comments, to give your plugin a name, a version number, enter
+ the author's name, copyright string, the name of the .INI file you
+ want to save the user's settings in, the name of the documentation
+ file, and so on. (You can always come back and change these values
+ later, of course).
+
+ Now you're ready to build & run the plugin:
+
+ 8. Press F7 to build the plugin.
+ a. If you get any of these error messages:
+ fatal error C1083: Cannot open include file: 'd3d8.h'...
+ fatal error C1083: Cannot open include file: 'd3dx8.h'...
+ Then you haven't added the DX8 SDK *include* path to your
+ build environment. See 'To set up the build environment'
+ above.
+ b. If you any linker error messages, such as this one:
+ LINK : fatal error LNK1104: cannot open file "d3d8.lib"
+ Then you haven't added the DX8 SDK *library* file path to your
+ build environment. See 'To set up the build environment'
+ above.
+
+ 9. Copy the files 'ex_tex.jpg' and 'vms_desktop.dll' from the MyPlugin
+ directory to your Winamp PLUGINS folder (usually c:\program files\
+ winamp\plugins).
+
+ 10. Run Winamp, press CTRL+P to select your plugin, and make sure that
+ it appears in the list. Notice that the name matches what you
+ entered into the 'defines.h' file as APPNAME; if you didn't change
+ it, it will appear as 'Example Plugin v1.04 / VisMegaSDK' (or
+ something similar). Next, configure the plugin, hit OK, & run it
+ by clicking 'Start'.
+
+
+Writing your own Plugin: A Brief Tour
+-------------------------------------
+ This starts out by pointing you at the important source code,
+ then by showing you around the resource editor and, finally,
+ the DirectX 8 and MSDN help libraries.
+
+ 1. Take a look at each of the 6 files in the 'My Plugin Source Files'
+ and 'My Plugin Header Files' groups. These will give you an idea
+ of the code that makes up the example plugin. All of the
+ behind-the-scenes code is wrapped up in the 'Framework Files'
+ group, which you shouldn't have to bother with (unless you
+ want to).
+
+ 2. Take a close look at plugin.h. This is the C++ class that makes
+ up your plugin. Note that the class is derived from the
+ CPluginShell class (which is in pluginshell.h/cpp), so it inherits
+ all its functions & variables. What you see here (in plugin.h)
+ are the data members and functions ADDED for this specific
+ (example) plugin, as well as the 12 pure virtual functions we've
+ implemented from the base class.
+
+ 3. Take a close look at plugin.cpp. READ THE BRIEF COMMENTS AT THE
+ TOP OF THOSE 12 VIRTUAL FUNCTIONS TO GET AN IDEA OF WHEN THEY'RE
+ CALLED AND WHAT THEY DO.
+
+ 4. Next we'll go into the Resource Editor.
+ Click the 'ResourceView' tab at the bottom of the Workspace view.
+ Then expand 'plugin resources' by double-clicking it, expand
+ 'Dialog' in the same way, and double-click 'IDD_CONFIG' to open
+ the template for the config panel. You can now double-click
+ individual controls to edit their properties; move/resize them;
+ press CTRL+T to test the dialog; press CTRL+D to define the tab
+ order; and even add new controls (using the floating toolbar)
+ (note that added controls require a lot of support code in
+ plugin.cpp; see 'Adding Controls to the Config Panel' below).
+
+ Also expand the 'Icon' folder on the left (just after 'Dialog')
+ and double-click IDI_PLUGIN_ICON. This is the icon used in the
+ taskbar, window title, and ALT+TAB screen when your plugin is
+ running. Note that there are 5 different icons within this one,
+ all at different resolutions and color depths, accessible by
+ changing the 'device' (just above the enlarged icon in the
+ resource editor). So, when you go to update the icon, don't forget
+ to update it for all devices!
+
+ 5. In Windows, go to Start Menu -> Program Files -> Microsoft
+ DirectX 8 SDK -> DirectX Documentation (Visual C++). This
+ is the help library for DirectX 8; you will need to refer to
+ it religiously in order to get anything done in DirectX 8.
+ The good news is, it's *extremely* well-written.
+
+ 6. In Windows, go to Start Menu -> Program Files -> Microsoft
+ Developer Network -> MSDN Library. This is the help library
+ for the general Win32 platform, but might not have info on
+ DirectX 8 (depending on when your version was published).
+ If you couldn't get the MSDN CD's, you can access the MSDN
+ library online at:
+ http://msdn.microsoft.com/library/
+ You'll have to do this from time to time to write a plugin,
+ but not nearly as often as you'll be accessing the DirectX 8
+ help library.
+
+ You might also want to take a look at the useful goodies inside
+ utility.cpp; they could come in handy.
+
+ That's it; you've now seen all the 'screens' you'll spend 99% of
+ your time on, in order to write your own plugin.
+
+
+Order of Function Calls
+-----------------------
+ The only code that will be called by the plugin framework are the
+ 12 virtual functions in plugin.h. But in what order are they called?
+ A breakdown follows. A function name in { } means that it is only
+ called under certain conditions.
+
+ Order of function calls...
+
+ When the PLUGIN launches
+ ------------------------
+ INITIALIZATION
+ OverrideDefaults
+ MyPreInitialize
+ MyReadConfig
+ << DirectX gets initialized at this point >>
+ AllocateMyNonDx8Stuff
+ AllocateMyDX8Stuff
+ RUNNING
+ +--> { CleanUpMyDX8Stuff + AllocateMyDX8Stuff } // called together when user resizes window or toggles fullscreen<->windowed.
+ | MyRenderFn
+ | MyRenderUI
+ | { MyWindowProc } // called, between frames, on mouse/keyboard/system events. 100% threadsafe.
+ +----<< repeat >>
+ CLEANUP
+ CleanUpMyDX8Stuff
+ CleanUpMyNonDx8Stuff
+ << DirectX gets uninitialized at this point >>
+
+ When the CONFIG PANEL launches
+ ------------------------------
+ INITIALIZATION
+ OverrideDefaults
+ MyPreInitialize
+ MyReadConfig
+ << DirectX gets initialized at this point >>
+ RUNNING
+ { MyConfigTabProc } // called on startup & on keyboard events
+ CLEANUP
+ [ MyWriteConfig ] // only called if user clicked 'OK' to exit
+ << DirectX gets uninitialized at this point >>
+
+
+Using Data From the Base Class (CPluginShell)
+---------------------------------------------
+ The base class from which your CPlugin class (in plugin.cpp) is
+ derived is called CPluginShell and is defined in pluginshell.cpp.
+ Many of its data members are 'protected', which means that only that
+ class itself, *plus derived classes*, can access them. ('Public'
+ members can be accessed by anyone; 'private' are unaccessible even
+ to derived classes.)
+
+ The protected data members and methods (functions) are as follows.
+ Generally, you should treat the data members as READ-ONLY; the only
+ exception is in OverrideDefaults(), where you can modify some of
+ their values to alter the "default defaults". See the comments at
+ the top of OverrideDefaults() in plugin.cpp for more information.
+
+ Here are all of the members & methods maintained by the plugin shell,
+ and available to CPlugin:
+
+
+ // GET METHODS
+ // ------------------------------------------------------------
+ int GetFrame(); // returns current frame # (starts at zero)
+ float GetTime(); // returns current animation time (in seconds) (starts at zero) (updated once per frame)
+ float GetFps(); // returns current estimate of framerate (frames per second)
+ eScrMode GetScreenMode(); // returns WINDOWED, FULLSCREEN, FAKE_FULLSCREEN, DESKTOP, or NOT_YET_KNOWN (if called before or during OverrideDefaults()).
+ HWND GetWinampWindow(); // returns handle to Winamp main window
+ HINSTANCE GetInstance(); // returns handle to the plugin DLL module; used for things like loading resources (dialogs, bitmaps, icons...) that are built into the plugin.
+ char* GetPluginsDirPath(); // usually returns 'c:\\program files\\winamp\\plugins\\'
+ char* GetConfigIniFile(); // usually returns 'c:\\program files\\winamp\\plugins\\something.ini' - filename is determined from identifiers in 'defines.h'
+
+ // GET METHODS THAT ONLY WORK ONCE DIRECTX IS READY
+ // ------------------------------------------------------------
+ // The following 'Get' methods are only available after DirectX has been initialized.
+ // If you call these from OverrideDefaults, MyPreInitialize, or MyReadConfig,
+ // they will return NULL (zero).
+ // ------------------------------------------------------------
+ HWND GetPluginWindow(); // returns handle to the plugin window. NOT persistent; can change!
+ int GetWidth(); // returns width of plugin window interior, in pixels.
+ int GetHeight(); // returns height of plugin window interior, in pixels.
+ int GetBitDepth(); // returns 8, 16, 24 (rare), or 32
+ LPDIRECT3DDEVICE8 GetDevice(); // returns a pointer to the DirectX 8 Device. NOT persistent; can change!
+ D3DCAPS8* GetCaps(); // returns a pointer to the D3DCAPS8 structer for the device. NOT persistent; can change.
+ D3DFORMAT GetBackBufFormat(); // returns the pixelformat of the back buffer (probably D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_A4R4G4B4, D3DFMT_R3G3B2, D3DFMT_A8R3G3B2, D3DFMT_X4R4G4B4, or D3DFMT_UNKNOWN)
+ D3DFORMAT GetBackBufZFormat(); // returns the pixelformat of the back buffer's Z buffer (probably D3DFMT_D16_LOCKABLE, D3DFMT_D32, D3DFMT_D15S1, D3DFMT_D24S8, D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D24X4S4, or D3DFMT_UNKNOWN)
+ char* GetDriverFilename(); // returns a text string with the filename of the current display adapter driver, such as "nv4_disp.dll"
+ char* GetDriverDescription(); // returns a text string describing the current display adapter, such as "NVIDIA GeForce4 Ti 4200"
+
+ // FONTS & TEXT
+ // ------------------------------------------------------------
+ LPD3DXFONT GetFont(eFontIndex idx); // returns a D3DX font handle for drawing text; see shell_defines.h for the definition of the 'eFontIndex' enum.
+ int GetFontHeight(eFontIndex idx); // returns the height of the font, in pixels; see shell_defines.h for the definition of the 'eFontIndex' enum.
+
+ // MISC
+ // ------------------------------------------------------------
+ td_soundinfo m_sound; // a structure always containing the most recent sound analysis information; defined in pluginshell.h.
+ void SuggestHowToFreeSomeMem(); // gives the user a 'smart' messagebox that suggests how they can free up some video memory.
+
+ // CONFIG PANEL SETTINGS
+ // ------------------------------------------------------------
+ // *** only read/write these values during CPlugin::OverrideDefaults! ***
+ int m_start_fullscreen; // 0 or 1
+ int m_start_desktop; // 0 or 1
+ int m_fake_fullscreen_mode; // 0 or 1
+ int m_max_fps_fs; // 1-120, or 0 for 'unlimited'
+ int m_max_fps_dm; // 1-120, or 0 for 'unlimited'
+ int m_max_fps_w; // 1-120, or 0 for 'unlimited'
+ int m_show_press_f1_msg; // 0 or 1
+ int m_allow_page_tearing_w; // 0 or 1
+ int m_allow_page_tearing_fs; // 0 or 1
+ int m_allow_page_tearing_dm; // 0 or 1
+ int m_minimize_winamp; // 0 or 1
+ int m_desktop_show_icons; // 0 or 1
+ int m_desktop_textlabel_boxes; // 0 or 1
+ int m_desktop_manual_icon_scoot; // 0 or 1
+ int m_desktop_555_fix; // 0 = 555, 1 = 565, 2 = 888
+ int m_dualhead_horz; // 0 = both, 1 = left, 2 = right
+ int m_dualhead_vert; // 0 = both, 1 = top, 2 = bottom
+ int m_save_cpu; // 0 or 1
+ int m_skin; // 0 or 1
+ td_fontinfo m_fontinfo[NUM_BASIC_FONTS + NUM_EXTRA_FONTS];
+ D3DDISPLAYMODE m_disp_mode_fs; // a D3DDISPLAYMODE struct that specifies the width, height, refresh rate, and color format to use when the plugin goes fullscreen.
+
+
+Adding Controls to the Config Panel
+-----------------------------------
+ There are four basic aspects of adding a new control to the config panel,
+ outlined below.
+
+ 1. Add the control to one of the property pages in the config panel (2..8),
+ via the Resource Editor. Note that you should not modify the config
+ panel itself (IDD_CONFIG) or the first property page (IDD_PROPSHEET_1).
+ Also, do not resize the page dialogs or the config panel; they are designed
+ to fit on a 640x480 screen, and should not be expanded.
+
+ 2. Add a variable (data member) to represent the control to your CPlugin class,
+ in plugin.h.
+
+ 3. In plugin.cpp:
+ a. initialize the variable to its default value in MyPreInitialize(),
+ b. read its value from the INI file in MyReadConfig(), and
+ c. write its value to the INI file in MyWriteConfig().
+
+ 4. In plugin.cpp, in the MyConfigTabProc function, **when 'nPage' is
+ the index (2..8) of the tab on which the control was placed:**
+ a. add code under WM_INITDIALOG to set the state of the control
+ (from the variable) when the config panel is started
+ b. add code under WM_COMMAND, case IDOK, to read the state
+ of the control and save the result in the variable
+ c. add a handler for your new control underneath WM_HELP, so that
+ when the user clicks the '?' in the config panel titlebar,
+ then clicks on your control, they get a helpful messagebox
+ explaining what the control does.
+
+
+Enabling Additional Tabs (pages) on the Config Panel
+----------------------------------------------------
+ By default, only two 'tabs' (pages) are enabled on the config panel.
+ The first is handled by the framework, and should not be modified;
+ the second, and any you add, are handled in plugin.cpp, in MyConfigTabProc().
+ The maximum number of tabs/pages is 8 (unless you want to modify the
+ framework files).
+
+ To add a third page (for example), simply open defines.h, and give a name
+ to the tab by setting the value of CONFIG_PANEL_BUTTON_3. This is all you
+ have to do to make the tab appear! To add controls to the new page, see
+ the above section entitled 'Adding Controls to the Config Panel.'
+
+ If you want to extend the framework to add a 9th page (?!), you need to:
+ 1. create a dialog called IDD_PROPPAGE_9 (style=child, border=none, visible, ctrl parent, control).
+ 2. in config.cpp, increment MAX_PROPERTY_PAGES
+ 3. in config.cpp, add IDD_PROPPAGE_9 to g_proppage_id[]
+ 4. in config.cpp, call AddButton for it
+
+
+Using Visual C++ to Debug your Plugin
+-------------------------------------
+ 1. Build the plugin in the 'Debug' configuration
+ (menu:Build->Configurations, then select 'debug').
+ 2. Go to menu:Project->Settings (ALT+F7) and click the
+ 'Debug' tab. Under 'Executable for debug session',
+ point it to winamp.exe.
+ 3. Press F5 to start debug session; it will launch winamp.
+ 4. You can now configure your plugin or run it; just set a
+ breakpoint anywhere in your code (F9) and when the code
+ gets to that point, it will break, and you can look at
+ variable values and browse structures (SHIFT+F9), jump
+ around on the call stack (ALT+7), and so on.
+
+
+Releasing a Plugin
+------------------
+ 1. Build in Release Mode
+
+ Once you're done debugging and ready to share your plugin
+ with others, go to menu:Build->Configurations and select
+ 'plugin - Win32 Release', then go to menu:Build->Clean and
+ menu:Build->Rebuild All. Building in release mode makes
+ your code smaller and faster (but doesn't allow debugging).
+
+ 2. Package it up an a self-installing .EXE
+
+ Here you'll want to download the Nullsoft Superpimp Install
+ System (NSIS) from http://www.nullsoft.com/free/nsis/ to
+ make your users' lives easier.
+
+ Then read the instructions at the top of the install script
+ file 'installer.nsi' (next to DOCUMENTATION.TXT) and edit the
+ install script to reflect the name and version of your plugin,
+ the paths & filenames & destination paths of everything you
+ want packaged up, and the output installer filename.
+
+ After installing NSIS, editing installer.nsi, and doing
+ a final release build, run a command something like this
+ from the command prompt (you'll have to adjust the paths):
+
+ "c:\program files\Nsis\makensis" C:\MyProjects\MyPlugin\installer.nsi
+
+ If all goes well, you'll have a file named something like
+ 'myplugin_100.exe' in your MyPlugin directory. Test it
+ out on a fresh machine to make sure the install screens
+ say the right thing and install the right files, and
+ you're set to go!
+
+ 3. Checklist: (prior to actually running makensis.exe)
+
+ * Did you update the version number and APPNAME in defines.h?
+ * Did you do a final pass on the tab ordering (CTRL+D from the
+ Resource Editor) of the config panel?
+ * Did you add WM_HELP handlers to new controls on the config panel?
+ * If you added any MessageBox() commands, did you supply the right
+ HWND parameter? (The messagebox will pop up on the same monitor
+ that that HWND is on.)
+ * Did you test your plugin in Desktop Mode, while Winamp is
+ *paused*, and then try moving icons around, to make sure that
+ you're properly handling the 'redraw' flag in MyRenderFn()?
+ * Did you update the version numbers throughout installer.nsi?
+ * Did you update the help screen text? (see top of plugin.cpp)
+ * Did you do your final build in Release mode?
+ * Did you write/update documentation?
+ Does the config panel link to it work?
+ * Did you make/update a webpage?
+ Does the config panel link to it work?
+
+
+Tips to pass on the the user, in your documentation
+---------------------------------------------------
+ 1. In general, it's a very good idea to use only Microsoft-certified
+ WHQL (Windows Hardware Quality Labs) drivers for your video card.
+ Often people want to get the newest, fastest beta drivers, but
+ these drivers are almost ALWAYS riddled with new bugs.
+
+ 2. If you want Winamp to listen to your sound card's Line-In or Mic-In
+ (or other audio input channel on your system) for driving the
+ visuals, just do the following:
+
+ 1. CONNECT WIRES
+ Connect your audio source (a stereo, a live feed, whatever) into
+ the line-in (or microphone) 1/8" jack on your sound card.
+
+ 2. SELECT SOUND INPUT CHANNEL & ADJUST VOLUME
+ In Windows, double-click the speaker icon in your systray (where
+ the clock is). Then, on the menu, go to Options -> Properties
+ and select the "Recording" option. Then make sure the Line In
+ (or Microphone) input channel (whichever is appropriate for
+ your case) is SELECTED (with a check mark) and that the volume
+ is close to, or at, the maximum. Hit OK.
+
+ 3. TELL WINAMP TO USE LINE-IN
+ Open Winamp, and hit CTRL+L (the "Open Location" hotkey). Now
+ type in "linein://" as the location you want to open. (Leave out
+ the quotes and make sure you use FORWARD slashes.) Hit PLAY
+ in Winamp, and the little built-in oscilloscope (or spectrum
+ analyzer) in Winamp should start showing your signal.
+
+ 4. RUN YOUR VISUALIZATION PLUGIN OF CHOICE
+ If the plugin seems to be responding too much or too little,
+ try adjusting the volume from Windows' Volume Control, or adjust
+ the sound level at the source.
+
+ 3. For the best graphics performance, try to close as many other
+ applications as you can, before running the plugin, especially
+ those that tend to work in the background, such as anti-virus
+ or file-swapping software. Also, if you must leave other
+ applications open, try to minimize them (i.e. shrink the window
+ down to the taskbar) so that they stay out of the painting loop.
+
+ 4. LCD screens: Note that most LCD screens (flatpanels) run at 60 Hz only,
+ meaning that they update the screen 60 times per second. However,
+ sometimes the video driver reports that it supports other refresh
+ rates, such as 72, 75, 85, etc. It is strongly recommended that
+ [for fullscreen mode, and for Windows in general] you choose a
+ display mode with a 60 Hz refresh rate, for the smoothest possible
+ animation. For this plugin, you will also want to choose
+ Maximum Framerates that divide evenly into 60 - such as 60, 30, 20,
+ 15, 12, 10, 6, 5, and so on - so that the # of times the LCD shows
+ each frame of animation remains constant, resulting in the smoothest
+ possible animation.
+
+ 5. Multiple Monitors: It is recommended that whenever you modify your Windows
+ multimon setup (i.e. turn an adapter on/off, change its color depth, etc.)
+ that you reboot Windows before running this plugin.
+
+ 6. Video Capture: If you'd like to save sequences of video from this plugin,
+ there are several programs out there that will let you do this. Warning:
+ you will need a ton of free hard drive space, and a fast CPU helps. A
+ few of these programs are:
+ "FRAPS" http://www.fraps.com/
+ "Hypercam" http://www.hyperionics.com
+
+ (That's it, for now. PLEASE include the tip about live audio input!)
+
+
+Performance Tips for DirectX 8
+------------------------------
+ 1. Minimize state changes (SetTexture, SetTextureStageState,
+ and SetRenderState) at all cost; group polygons together
+ that share the same rendering settings and send them all
+ together. You will be amazed at the performance gain.
+
+ 2. Use Vertex Buffers and Index Buffers for all your static
+ geometry (i.e. vertices/indices that don't change every
+ frame - like a static model that doesn't change, even
+ though it might move around, rotate, resize, etc. due
+ to the world/view/projection matrices). These buffers
+ will keep the geometry in video memory (if possible) so
+ that the data doesn't have to cross the bus every frame;
+ if not, they'll try to at least place the geometry/indices
+ in AGP memory. If you don't use these driver-managed
+ buffers (and instead use DrawPrimitiveUP and
+ DrawIndexedPrimitiveUP), you're keeping all of your data
+ in non-AGP system memory, and unless the data is very
+ small, you can expect a major bottleneck. Note that for
+ dynamically-generated vertex data (i.e. vertices are
+ generated each frame - like when you draw a waveform),
+ you don't have a choice.
+
+ If you follow these two tips and use common sense (and know
+ the basic theory behind how 3D accelerators work), you should
+ be getting 30 fps on a Voodoo 3 (assuming your overdraw is low,
+ i.e. you don't draw each pixel on the screen more than once or
+ twice per frame).
+
+ For more tips, look in the DX8 SDK Documentation, or look on
+ the web.
+
+
+Other Resources
+---------------
+ 1. DX8 SDK: The DX8 documentation that came with your DX8 SDK is,
+ by far, the most critical resource you have. It fully documents
+ the entire API, and much more. The SDK also comes with tons of
+ samples and their source code.
+ 2. NSDN: the Nullsoft Developer Network, where the Winamp API
+ is published: http://www.winamp.com/nsdn/winamp2x/
+ If you want to do anything in MyWindowProc() that involves
+ communicating with the Winamp window directly (such as
+ querying for the song title/time/length, querying the playlist,
+ adjusting the panning, toggling shuffle, etc.), you'll need
+ to delve into NSDN. It's all extremely straightforward and
+ simple. For a few examples of how to talk to the main Winamp
+ window, check out PluginShellWindowProc() in pluginshell.cpp.
+ 3. Here are links to a few sites with good DirectX tutorials/faqs/code:
+ The X-Zone: http://www.mvps.org/directx/
+ Gamedev.net: http://www.gamedev.net/reference/
+
+
+Known Bugs
+----------
+ 1. When running [true] fullscreen in a multimon setup,
+ sometimes when the user presses ALT-TAB to switch away from the plugin
+ and to another window, the plugin will minimize. The 'sometimes' is
+ determined as follows:
+ -if the user releases TAB before depressing ALT, the window
+ minimizes (undesired behavior).
+ -if the user depresses ALT before releasing TAB, the window does
+ not minimize (desired behavior).
+ 2. Desktop Mode: some features are not implemented yet. They are:
+ -right-click -> cut/copy/paste/rename
+ -right-click -> "send to" doesn't work on all machines
+ -no keyboard commands (delete, enter, arrows, CTRL+X/C/V/Z)
+ -no drag-and-drop for files
+ -desktop shortcuts mostly work when you double-click them,
+ but on some machines bring up an "open/save" dialog
+ instead of actually launching the file.
+
+ That's it for now.
+
+ If anyone finds a solution for any of these bugs, please post the solution
+ in the VMS forum, and it will be included in the next VMS release.
+
+
+Version History
+-----------------------------------------------------------------------
+[v1.05 beta 1 - June 26, 2003]
+
+ -revamped the way keyboard commands are routed between your plugin
+ and the plugin shell. Before, the shell captured certain keys
+ ('p' for playlist, 'zxcvb' for playback, 's' for shuffle, 'F1'
+ for help, ESC to exit, arrows for volume/seeking, etc.)
+ and the plugin was unable to override these. Now, the shell
+ will pass the WM_KEYDOWN/WM_CHAR message to the plugin
+ (MyWindowProc) first, to see if it wants to process it. If the
+ plugin steals the key, it returns 0, and the shell ignores it.
+ If the plugin does not process the key, it returns 1, and then
+ the shell is free to process it.
+
+*** NOTE that if you are upgrading to VMS 1.05, this means you'll have to
+*** update the way your WM_CHAR and WM_KEYDOWN handlers work in plugin.cpp!
+*** [primarily, you'll have to return 0 when you handle a key, and 1
+*** otherwise.]
+
+ -added key: 'r' for repeat
+ -added SKINNING; if you have Winamp 2.90+, you can now check the
+ 'integrate with winamp' checkbox and the plugin [when running in
+ windowed mode] will be skinned just like Winamp. The integrated
+ window works just like any other Winamp window; it docks with
+ other windows, CTRL+TAB cycles between them all, and lots of new
+ keys work (J, L, CTRL+P, ALT+E, etc.).
+ -fixed bug (or error in judgment?) where fake fullscreen mode window
+ would actually run at the *bottom* of the Z order when running
+ on a multiple monitor setup. The problem was that if you clicked
+ on any other window, the taskbar would pop up, potentially overtop
+ of the plugin. Since there's really no way around this, I decided
+ (before) to just stick the plugin at the bottom of the Z order in
+ this case. Well, this is now fixed; the plugin tries its best
+ to stay on top, but watch out - if you try and click on any other
+ windows, the taskbar WILL pop up. If you want to avoid that,
+ you'll have to run in true fullscreen mode.
+ -improved audio and video synchronization
+ -the current framerate is now used to tell Winamp, each frame,
+ exactly how far in advance it should give us the audio data.
+ For example, if we're getting 20 fps, we should get the
+ audio 50 ms in advance for the proper video frame to appear
+ when the user will actually hear those audio samples.
+ -timing: added calls to beginTimePeriod and endTimePeriod, so the assumed
+ granularity for Sleep() is now 2 ms (down from 10 ms).
+ This means that CPU usage will dramatically drop, and
+ fortunately, there should be no effect on framerate accuracy.
+ -desktop mode: added 'show icons' option to the desktop mode options
+ dialog, so users can uncheck it (and hide/disable the icons) if they
+ like.
+ -user can no longer shrink the window to less than 64x48 in size.
+ (often the minimum size will be higher than this though; see
+ WM_GETMINMAXINFO in pluginshell.cpp).
+ -user can now switch modes (windowed <-> fullscreen <-> desktop mode)
+ immediately. (before, it was blocked until frame 5.)
+ -(fixed a small bug in the example plugin, where handler for WM_KEYUP
+ returned DefWindowProc instead of 1).
+ -any time the DirectX setup fails when starting up (or switching to)
+ windowed mode, the window coords are now saved to disk as a 256x256
+ window placed at (64,64). That way, if the problem was due to running
+ out of video memory, it will be less likely to recur.
+ -config panel:
+ -added two more fonts: one for the playlist, and another for the
+ help screen.
+ -it's now easy to add your own fonts to the font dialog in the
+ config panel; just add the appropriate #defines in the file
+ defines.h. Then you can access them easily from plugin.cpp by
+ calling GetFont(EXTRA_1), GetFont(EXTRA_2), and so on, up to
+ GetFont(EXTRA_5). You can also get their height by calling
+ GetFontHeight(EXTRA_1) through GetFontHeight(EXTRA_5).
+ -greatly improved the installer script.
+ -now selects winamp2 dir by default, if both winamp 2 & 3 are installed.
+ -fixed a bug where the plugin wasn't being correctly set as the default plugin
+ in winamp. Also, this is no longer an option - it just automatically does it.
+ -now, when you go to install to winamp 3, it checks to see if ClassicVis
+ is installed. If it is, you're set; if not, it prompts you to go download
+ it. If you choose not to, it alerts you that the installation failed.
+ -the FFT class (fft.cpp, fft.h) now has 2 extra optional init parameters.
+ -'bEqualize' is 1 by default; set it to 0 to have a non-equlized FFT;
+ bass frequencies will be much higher in magnitude than treble frequencies.
+ -'envelope_power' is 1.0 by default; adjust it to change the characteristics
+ of the resulting frequency spectrum (see comments in fft.cpp, in
+ InitEnvelopeTable). Set this to a negative value to not use an envelope.
+ -the help screen is no longer pre-rendered to a texture; it is now just drawn every
+ frame that it's needed. (Decided that that precious memory on some 8MB graphics
+ cards was more important than having a good framerate, on some cards, while viewing
+ the help screen.)
+ -added some nice macros to MyRenderUI() in plugin.cpp; makes the code for drawing
+ text much simpler.
+ -added 2 functions, GetDriver and GetDesc, which will return text strings with the
+ name & description of the currently active display adapter. (search these
+ strings for vendor substrings like "nvidia", using strstr or something similar,
+ to do vendor-specific bug workarounds. blech.)
+ -fixed a bug in SSE detection
+ -added handy memset_MMX() function to utility.cpp (alongside memcpy_MMX)
+ -fixed tabbing order for controls config panel tab #1 (doh)
+ -in 'defines.h', you now specify a long name + a short name for your plugin.
+ The long name is used for the description string in winamp's list of plugins;
+ the short name is used for the window caption.
+ -in the example plugin, in plugin.cpp, the F3 key (show song length)
+ is now a three-state toggle: off, current time, and current time / total
+ length.
+
+[v1.04 - October 29, 2002]
+
+ -DESKTOP MODE: the icing on the cake.
+ -Allows users to run your plugin as animated wallpaper, with very
+ little cpu overhead. Uses no overlays or other unusual hardware
+ features.
+ -Just make sure you include the file 'vms_desktop.dll' with your
+ plugin; it is required for Desktop Mode to work properly.
+ It's small, though - only 48 kb. This file is now included
+ in the sample install script (installer.nsi).
+ -You can toggle Desktop Mode on/off at runtime by hitting ALT+D.
+ And as before, you can toggle Fullscreen via ALT+ENTER.
+ -Not all features of the desktop are fully implemented, but most
+ of the most-frequently-used features should be working.
+ For a list of the features not yet implemented, see the
+ 'Known Bugs' section above.
+ -CHANGES MADE TO PLUGIN.H,CPP: (isolated for ease-of-merging purposes)
+ 1. added a few config settings; see OverrideDefaults()
+ in PLUGIN.CPP.
+ 2. added 'redraw' flag to MyRenderFn - see the comments
+ at the top of MyRenderFn. Make sure you respect this
+ flag, or else, when the user moves icons around in
+ Desktop Mode while Winamp is paused, your plugin
+ will mysteriously start animating.
+ 3. added the 'MyRenderUI' function - please break your
+ text-rendering code in MyRenderFn off into this function.
+ 4. removed the ClipPlaylist() functions and, instead, provided
+ pointers to some values as params to MyRenderUI() that tell
+ you where to place text in each of the corners. As you
+ draw text, be sure to update these values, so that any
+ text drawn by the plugin shell (parent class) won't try to
+ draw text overtop of your text.
+ -Plugins based on VMS now remember the window position when they last
+ (successfully) exited windowed mode, and use that as the
+ default when they re-enter windowed mode (during the same
+ session or in a later session). If there is an error creating
+ that window (too big/not enough video memory, off-screen
+ because display mode resolution decreased, etc.) it will
+ revert to the default window size & position.
+ -Config Panel:
+ -For users with DualHead cards that run two monitors as one
+ virtual display (e.g. 2048x768 or 1024x1536), you can now
+ specify which half of the screen you want Fake Fullscreen Mode
+ and Desktop Mode to occupy, or both. See the 'DualHead'
+ button on the config panel.
+ -Added an option to save cpu usage by using a more-tolerant
+ framerate limitation algorithm - saves 0-20%. Default: ON.
+ -Fixed appearance of the help screen by adding +0.5-texel offset;
+ on some cards, help screen text was kind of jaggy and munged.
+ -Release builds no longer log window messages to the debug
+ output stream.
+ -The D3DX font for the help screen text is now created at
+ initialization time, instead of on demand.
+ -Framework Files:
+ -renamed 'fontdialog.cpp' to 'config2.cpp', since it now contains
+ more than just the font dialog code.
+ -added 'desktop_mode.cpp' and 'icon_t.h' to support Desktop Mode.
+ -Changes made to the sample installer script: [installer.nsi]
+ -added UnInstall options for winamp 2 and 3
+ -simplified things by using some !define's at the top
+ -updated it to look for Winamp 3's new executable
+ name: winamp3.exe (in addition to the old, which was
+ studio.exe)
+
+-----------------------------------------------------------------------
+[v1.03 - August 27, 2002]
+
+ [MAJOR CHANGES]
+ -audio:
+ -vastly improved frequency analysis by multiplying the waveform by a
+ bell-shaped envelope before sending it to the FFT, lessening the
+ frequency response of the old square filter and producing a more
+ precise frequency analysis. Also improved it by doing a 1024-sample
+ FFT (instead of a 512). Special thanks goes out to Alan Seefeldt
+ and Alan Peevers for sharing their extensive knowledge in this area!
+ -config panel:
+ -split it into separate property sheets, so that
+ future updates to VMS (this sdk) will be easier to integrate
+ with code based on previous versions. Also, this gives developers
+ a lot more space to add things to the config panel.
+ -split the settings for 'fake fullscreen' mode and regular
+ fullscreen mode into two separate sets of controls, instead
+ of sharing controls; it was too confusing that way.
+ -added option to minimize winamp when going fullscreen.
+ Only actually minimizes winampwhen going fullscreen
+ (or fake fullscreen) AND winamp and the plugin window
+ are situated on the same monitor.
+ -added user-configurable fonts to the config panel.
+ -text:
+ -added a built-in playlist!
+ -added some sample code (in plugin.cpp / RenderText()) for showing
+ the current song title, position, and length.
+ -timing:
+ -oops... hi-precision timer was disabled in last version!
+ -also discovered an even more high-precision timer, which provides
+ a time sampling precision of from 1 to 5 *MICRO*seconds!
+ -ditched the 'frame delay' system and replaced it with a 'max fps'
+ system that should work more intuitively, and be extremely
+ accurate (thanks to the new timer).
+ -classes:
+ -got rid of InitMyGDIStuff() and CleanUpMyGDIStuff() - not really needed
+ -got rid of MyPreRenderFn() - also not really needed
+ -in windowed mode, if there is not enough video memory to create
+ the window at the default size, the window will now try to shrink
+ further and further, until it is small enough to work.
+ -fixed problem where the plugin wouldn't show up in the plug-ins list
+ in Winamp, if the user didn't have DX8 or later installed. Now
+ it does show up in the list, and if they try to run/configure it
+ and DX8 is missing, it will indicate this, and even offer to
+ take them to the MS DirectX website to download it.
+ -also started calling LoadLibrary("d3d8.dll") before calling
+ Direct3DCreate8(), so the latter wouldn't crash on systems
+ without DX8.
+ -yanked the fractal stuff out of the example plugin; too complicated.
+
+ [MINOR CHANGES]
+ -now more resilient when user turns off some display (in a multimon
+ setup), then goes to run the plugin on that display (because they
+ didn't return to the config panel and update the display adapter
+ selection).
+ -improved suggested actions for when the plugin fails to start
+ because there is not enough video memory; suggestions now
+ include turning off other programs that might be using up
+ video memory (Windows Media Player, NetMeeting, and so on).
+ -config panel: disabled caps checking; sometimes requesting
+ the caps fails when you dynamically enable/disable monitors in
+ a multimon setup, so adapters that really exist (and are on)
+ would be missing in the list.
+ -config panel: added a sample combobox & slider to the 2nd property page,
+ which now features a checkbox, slider, and combobox, all
+ as simple examples for the plugin developer to build off of.
+ -noticed that multipsampling only works with D3DSWAPEFFECT_DISCARD,
+ so the code is now protected against using D3DSWAPEFFECT_COPY_VSYNC
+ with multisampling. The config panel has also been updated to
+ indicate to the user that if page tearing is disallowed,
+ multisampling will not function. This is a limitation of
+ the DirectX 8 API.
+ -added OverrideDefaults() function; see comments in plugin.cpp
+ -revamped the sample beat detection code
+ -tightened up the interface to CPluginShell
+ -made DirectX get initialized earlier (and cleaned up later)
+ so that GetWidth() and GetHeight() would be valid longer
+ -moved srand(time(NULL)) up to top of MyPreInitialize, in case
+ the developer wants to randomly initialize any of their
+ variables there.
+ -modified PrepareFor2DDrawing() so that it always makes the range
+ of X,Y coords -1..1 (before it was -width/2..width/2, and similarly
+ for height). Also inverted Y, so that y==-1 is actually at the
+ top of the screen, and Y==1 is at the bottom.
+ -added PrepareFor3DDrawing()
+ -improved auto-selection of best-match video mode; now, if it can't
+ find the exact pixel format that was in the INI file,
+ if will try other video modes that have the same bit depth,
+ but a different arrangement of the bits. [This applies to both
+ the config panel, AND when you go to run the plugin fullscreen.]
+ -respected key repeat count for playlist navigation (up/down), volume
+ adjust (up/down), and seeking (left/right).
+ -fixed a bug where the plugin would close on WM_KEYUP/VK_ESCAPE. Now,
+ instead, it closes on WM_KEYDOWN/VK_ESCAPE. This was a problem when
+ you hit ESCAPE to close some other app (on WM_KEYDOWN), then the focus
+ went to the plugin, and WM_KEYUP/VK_ESCAPE got sent to the plugin.
+ Not sure why it was even like this in the first place...
+ -fixed a timing but where, when the frame delay was zero (or fps
+ was unlimited), and the plugin was using the low-precision timer,
+ the fps reading would blow up and m_time would stop.
+ -fixed a bug w/a parameter to CreateFont: max font weight was
+ 900; 'twas calling it with 1000
+ -fixed bug with context menu cleanup
+ -fixed a bug where winamp playback nav. keys (zxcvbs) were
+ handled under WM_KEYDOWN; should have been under WM_CHAR.
+ -fixed a bug where DXContext was calling DestroyWindow (on the final
+ exit of the plugin), when in fact, the window had already been
+ destroyed (by Windows, it seems).
+ -fixed a bug in config panel, where list of video modes wasn't updating
+ when you changed the fullscreen adapter.
+ -fixed a bug where DXContext was remembering the native windows display
+ mode for the first monitor that the window was created on, only.
+ This was a problem because if two monitors had different bit depths,
+ and you ran it and switched to another monitor by toggling fullscreen,
+ it would try to create a device with a back buffer whose bit depth
+ was that of the original monitor. To fix this, it now does the
+ following: the first time it creates a window, before changing the
+ display mode, it remembers the native display mode for all the
+ adapters present, then uses the appropriate one whenever it needs
+ it.
+ -deleted the 'DX8 Includes' project folder from the workspace;
+ use 'External Dependencies' folder instead, it automatically
+ points you to the right directories.
+
+
+-----------------------------------------------------------------------
+[1.02, August 5, 2002]
+ -Fixed bug where the plugin would minimize if you were running
+ [true] fullscreen with multiple monitors, and went to click
+ in another window. Previously the workaround was to use fake
+ fullscreen mode, but now this is not necessary. Fake fullscreen
+ mode still remains, though; for the rationale, see the help text
+ for the 'fake fullscreen mode' checkbox in the config panel.
+ -Decided that InitMyNonDx8Stuff() should be called first, instead
+ of last, and that CleanUpMyNonDx8Stuff() should be called last,
+ not first.
+ -Might have fixed a bug with high-precision timer.
+ -Added a custom icon (...which the developer can modify, of course).
+
+
+-----------------------------------------------------------------------
+[1.01, July 19, 2002]
+ -Initial release
+
+
+-----------------------------------------------------------------------
+
+License
+-------
+Copyright (C) 1999-2002 Nullsoft, Inc.
+
+ This source code is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this source code or the software it produces.
+
+ Permission is granted to anyone to use this source code for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented; you must not
+ claim that you wrote the original source code. If you use this source code
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original source code.
+ 3. This notice may not be removed or altered from any source distribution.
+
+
+
+
diff --git a/Src/Plugins/Visualization/vis_milk2/api__vis_milk2.h b/Src/Plugins/Visualization/vis_milk2/api__vis_milk2.h
new file mode 100644
index 00000000..8b25cfd5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/api__vis_milk2.h
@@ -0,0 +1,16 @@
+#ifndef NULLSOFT_APIH
+#define NULLSOFT_APIH
+
+#include <api/service/api_service.h>
+#include "../Agave/Language/api_language.h"
+#include <api/service/waServiceFactory.h>
+#include <api/syscb/callbacks/browsercb.h>
+#include <api/syscb/callbacks/syscb.h>
+#include <api/syscb/api_syscb.h>
+extern api_syscb *WASABI_API_SYSCB;
+#define WASABI_API_SYSCB sysCallbackApi
+#include <api/application/api_application.h>
+extern api_application *applicationApi;
+#define WASABI_API_APP applicationApi
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/config.cpp b/Src/Plugins/Visualization/vis_milk2/config.cpp
new file mode 100644
index 00000000..db418171
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/config.cpp
@@ -0,0 +1,1589 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "pluginshell.h"
+#include "resource.h"
+#include "utility.h"
+#include "defines.h"
+#include "shell_defines.h"
+#include "vis.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <multimon.h>
+#include <commctrl.h>
+#include <shellapi.h>
+#include <strsafe.h>
+#include <assert.h>
+
+#define PREFERRED_FORMAT D3DFMT_X8R8G8B8
+#define MAX_PROPERTY_PAGES 8
+#define MAX_DISPLAY_ADAPTERS 16
+#define MAX_MAX_FPS 120
+#define MAX_DISPLAY_MODES 1024
+
+extern winampVisModule mod1;
+
+IDirect3D9* g_lpDX;
+HMODULE g_hmod_d3d9;
+HMODULE g_hmod_d3dx9;
+D3DADAPTER_IDENTIFIER9 g_disp_adapter_w[MAX_DISPLAY_ADAPTERS]; // NOTE: indices into this list might not equal the ordinal adapter indices!
+D3DADAPTER_IDENTIFIER9 g_disp_adapter_fs[MAX_DISPLAY_ADAPTERS]; // NOTE: indices into this list might not equal the ordinal adapter indices!
+D3DADAPTER_IDENTIFIER9 g_disp_adapter_dm[MAX_DISPLAY_ADAPTERS]; // NOTE: indices into this list might not equal the ordinal adapter indices!
+D3DDISPLAYMODE g_disp_mode[MAX_DISPLAY_MODES];
+HWND g_config_hwnd;
+HWND g_subwnd;
+int g_num_disp_modes;
+int g_nTab;
+int g_ignore_clicks;
+int g_zero_display_modes_warning_given;
+int g_proppage_id[MAX_PROPERTY_PAGES];
+
+void GetCurrentDisplayMode(D3DDISPLAYMODE *pMode)
+{
+ if (!pMode)
+ return;
+
+ DEVMODE dm;
+ dm.dmSize = sizeof(dm);
+ dm.dmDriverExtra = 0;
+ if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
+ return;
+
+ pMode->Width = dm.dmPelsWidth;
+ pMode->Height = dm.dmPelsHeight;
+ pMode->Format = (dm.dmBitsPerPel==16) ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
+ pMode->RefreshRate = dm.dmDisplayFrequency;
+}
+
+bool CPluginShell::InitConfig(HWND hDialogWnd)
+{
+ // ******* do initialization of global variables HERE *******
+ // ******* do initialization of global variables HERE *******
+ // ******* do initialization of global variables HERE *******
+
+ g_lpDX = NULL;
+ g_hmod_d3d9 = NULL;
+ g_hmod_d3dx9 = NULL;
+ g_num_disp_modes = 0;
+ g_config_hwnd = hDialogWnd;
+ g_ignore_clicks = 1;
+ g_subwnd = NULL;
+ g_nTab = 0;
+ g_zero_display_modes_warning_given = 0;
+
+ g_proppage_id[0] = IDD_PROPPAGE_1;
+ g_proppage_id[1] = IDD_PROPPAGE_2;
+ g_proppage_id[2] = IDD_PROPPAGE_3;
+ g_proppage_id[3] = IDD_PROPPAGE_4;
+ g_proppage_id[4] = IDD_PROPPAGE_5;
+ g_proppage_id[5] = IDD_PROPPAGE_6;
+ g_proppage_id[6] = IDD_PROPPAGE_7;
+ g_proppage_id[7] = IDD_PROPPAGE_8;
+
+ // ******* do initialization of global variables HERE *******
+ // ******* do initialization of global variables HERE *******
+ // ******* do initialization of global variables HERE *******
+
+ return true;
+}
+
+void CPluginShell::EndConfig()
+{
+ SafeRelease(g_lpDX);
+
+ if (g_subwnd)
+ {
+ DestroyWindow(g_subwnd);
+ g_subwnd = NULL;
+ }
+
+ if (g_hmod_d3d9)
+ {
+ FreeLibrary(g_hmod_d3d9);
+ g_hmod_d3d9 = NULL;
+ }
+ if (g_hmod_d3dx9)
+ {
+ g_hmod_d3dx9 = NULL;
+ }
+}
+
+static bool AddButton(int pos, HWND tabctrl, LPWSTR szButtonText)
+{
+ if (szButtonText && szButtonText[0] && szButtonText[0] != L' ')
+ {
+ TCITEMW tie = {0};
+ tie.mask = TCIF_TEXT | TCIF_IMAGE;
+ tie.iImage = -1;
+ tie.pszText = szButtonText;
+
+ if (SendMessageW(tabctrl, TCM_INSERTITEMW, pos, (LPARAM)&tie) == -1)
+ return false;
+ }
+ return true;
+}
+
+void CPluginShell::UpdateAdapters(int screenmode)
+{
+ int i;
+
+ if (!g_lpDX) return;
+
+ int nDispAdapters = 0;
+
+ HWND ctrl;
+ GUID* pGUID = NULL;
+ char deviceName[256];
+ switch(screenmode)
+ {
+ case FULLSCREEN:
+ ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FS);
+ pGUID = &m_adapter_guid_fullscreen;
+ StringCbCopy(deviceName, sizeof(deviceName), m_adapter_devicename_fullscreen);
+ break;
+ case WINDOWED:
+ ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_W);
+ pGUID = &m_adapter_guid_windowed;
+ StringCbCopy(deviceName, sizeof(deviceName), m_adapter_devicename_windowed);
+ break;
+ /*case FAKE_FULLSCREEN:
+ ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FFS);
+ pGUID = &m_adapter_guid_fake_fullscreen;
+ strcpy(deviceName, m_adapter_devicename_fake_fullscreen);
+ break;*/
+ case DESKTOP:
+ ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_DMS);
+ pGUID = &m_adapter_guid_desktop;
+ StringCbCopy(deviceName, sizeof(deviceName), m_adapter_devicename_desktop);
+ break;
+ }
+
+ // clear the combo box
+ SendMessage( ctrl, CB_RESETCONTENT, 0, 0);
+
+ // repopulate the combo box with a list of adapters
+ {
+ char szDesc[1024];
+
+ D3DADAPTER_IDENTIFIER9* global_adapter_list;
+ switch(screenmode)
+ {
+ case FULLSCREEN:
+ global_adapter_list = g_disp_adapter_fs;
+ break;
+ case WINDOWED:
+ global_adapter_list = g_disp_adapter_w;
+ break;
+ /*case FAKE_FULLSCREEN:
+ global_adapter_list = g_disp_adapter_w; // [sic]
+ break;*/
+ case DESKTOP:
+ global_adapter_list = g_disp_adapter_dm;
+ break;
+ }
+
+ int nAdapters = g_lpDX->GetAdapterCount();
+
+ // re-populate it:
+
+ wchar_t szDebugFile[MAX_PATH];
+ StringCbCopyW(szDebugFile, sizeof(szDebugFile), m_szConfigIniFile);
+ wchar_t* p = wcsrchr(szDebugFile, L'\\');
+ if (p)
+ {
+ lstrcpyW(p+1, ADAPTERSFILE);
+ FILE* f = _wfopen(szDebugFile, L"w");
+ if (f)
+ {
+ DWORD winamp_version = SendMessage(GetWinampWindow(),WM_WA_IPC,0,0);
+ fprintf(f, "Winamp version = 0x%04X\n", winamp_version);
+ fprintf(f, "Plugin long name = \"%s\", version=%d, subversion=%d\n", LONGNAME, INT_VERSION, INT_SUBVERSION);
+ fprintf(f, "Enumeration of Display Adapters:\n");
+ //fprintf(f, "...this is a temporary debug file created by MilkDrop 2.\n");
+ //fprintf(f, "...don't worry - the final release of the plug-in will NOT generate this file.\n");
+ for (i=0; i<nAdapters && nDispAdapters<MAX_DISPLAY_ADAPTERS; i++)
+ {
+ if (g_lpDX->GetAdapterIdentifier(i, /*D3DENUM_NO_WHQL_LEVEL*/ 0, &global_adapter_list[nDispAdapters]) == D3D_OK)
+ {
+ // Now get the caps, and filter out any graphics cards that can't
+ // do, say, gouraud shading:
+
+ int adapter_ok = 1;
+
+ /*
+ D3DCAPS9 caps;
+ if (g_lpDX->GetDeviceCaps(i, D3DDEVTYPE_HAL, &caps)==D3D_OK)
+ {
+ // check the caps here, make sure the device is up to par. example:
+ if (caps.ShadeCaps & D3DPSHADECAPS_COLORGOURAUDRGB)
+ adapter_ok = 0;
+ }
+ */
+
+ if (f) {
+ fprintf(f, "%d. Driver=%s\n", nDispAdapters+1, global_adapter_list[nDispAdapters].Driver);
+ fprintf(f, " Description=%s\n", global_adapter_list[nDispAdapters].Description);
+ fprintf(f, " DeviceName=%s\n", global_adapter_list[nDispAdapters].DeviceName);
+ fprintf(f, " DriverVersion=0x%08X (%d)\n",global_adapter_list[nDispAdapters].DriverVersion);
+ fprintf(f, " VendorId=%d\n", global_adapter_list[nDispAdapters].VendorId);
+ fprintf(f, " DeviceId=%d\n", global_adapter_list[nDispAdapters].DeviceId);
+ fprintf(f, " SubSysId=0x%08X\n", global_adapter_list[nDispAdapters].SubSysId);
+ fprintf(f, " Revision=%d\n", global_adapter_list[nDispAdapters].Revision);
+ //fprintf(f, " DeviceIdentifier=0x%08X\n", global_adapter_list[nDispAdapters].DeviceIdentifier);
+ char szGuidText[512];
+ GuidToText(&global_adapter_list[nDispAdapters].DeviceIdentifier, szGuidText, sizeof(szGuidText));
+ fprintf(f, " WHQLLevel=%d\n", global_adapter_list[nDispAdapters].WHQLLevel);
+ fprintf(f, " GUID=%s\n", szGuidText);
+ }
+
+ if (adapter_ok)
+ {
+ sprintf(szDesc, "%d. %s [%s]", nDispAdapters+1, global_adapter_list[nDispAdapters].Description, global_adapter_list[nDispAdapters].Driver);
+ SendMessage( ctrl, CB_ADDSTRING, nDispAdapters, (LPARAM)szDesc);
+ nDispAdapters++;
+ }
+ }
+ }
+ fclose(f);
+ }
+ }
+
+ // set selection(s):
+ // find i where global_adapter_list[i].DeviceIdentifier is the same as last time,
+ // and select it.
+ int found = 0;
+ for (i=0; i<nDispAdapters; i++)
+ {
+ if (!found &&
+ memcmp(&global_adapter_list[i].DeviceIdentifier, pGUID, sizeof(GUID))==0 &&
+ !strcmp(global_adapter_list[i].DeviceName, deviceName)
+ )
+ {
+ SendMessage( ctrl, CB_SETCURSEL, i, 0);
+ found = 1;
+ }
+ }
+ if (!found)
+ SendMessage( ctrl, CB_SETCURSEL, 0, 0);
+ }
+
+ if (screenmode == FULLSCREEN)
+ UpdateFSAdapterDispModes();
+ else
+ UpdateDispModeMultiSampling(screenmode);
+}
+
+void CPluginShell::UpdateFSAdapterDispModes() // (fullscreen only)
+{
+ wchar_t szfmt[256], str[256];
+ int i;
+ HWND hwnd_listbox = GetDlgItem( g_subwnd, IDC_DISP_MODE );
+
+ int nVideoModesTotal = 0;
+ if (!g_lpDX) return;
+ int nAdapterOrdinal = GetCurrentlySelectedAdapter(FULLSCREEN);
+ nVideoModesTotal = g_lpDX->GetAdapterModeCount(nAdapterOrdinal, PREFERRED_FORMAT);
+
+ if (nVideoModesTotal <= 0 && !g_zero_display_modes_warning_given)
+ {
+ g_zero_display_modes_warning_given = 1;
+ wchar_t title[64];
+ MessageBoxW(g_config_hwnd, WASABI_API_LNGSTRINGW(IDS_GRAPHICS_SUBSYSTEM_IS_TEMPORARILY_UNSTABLE),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_WARNING, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+
+ // clear the combo box
+ SendMessage( hwnd_listbox, CB_RESETCONTENT, 0, 0);
+
+ int nAdded = 0;
+
+ // re-populate it:
+ for (i=0; i<nVideoModesTotal; i++)
+ {
+ if (nAdded >= MAX_DISPLAY_MODES)
+ break;
+
+ // get info for display mode into g_disp_mode[nAdded]
+ if (g_lpDX->EnumAdapterModes(nAdapterOrdinal, PREFERRED_FORMAT, i, &g_disp_mode[nAdded]) != D3D_OK)
+ continue;
+
+ // add to combo box
+ int bpp = 0;
+ switch(g_disp_mode[nAdded].Format)
+ {
+ default:
+ case D3DFMT_UNKNOWN : WASABI_API_LNGSTRINGW_BUF(IDS_UNKNOWN, szfmt, 256); bpp=0; break;
+ case D3DFMT_R8G8B8 : lstrcpynW(szfmt, L"RGB-888", 256); bpp=32; break;
+ case D3DFMT_A8R8G8B8 : lstrcpynW(szfmt, L"ARGB-8888", 256); bpp=32; break;
+ case D3DFMT_X8R8G8B8 : lstrcpynW(szfmt, L"XRGB-8888", 256); bpp=32; break;
+ case D3DFMT_R5G6B5 : lstrcpynW(szfmt, L"RGB-565", 256); bpp=16; break;
+ case D3DFMT_X1R5G5B5 : lstrcpynW(szfmt, L"XRGB-1555", 256); bpp=16; break;
+ case D3DFMT_A1R5G5B5 : lstrcpynW(szfmt, L"ARGB-1555", 256); bpp=16; break;
+ case D3DFMT_A4R4G4B4 : lstrcpynW(szfmt, L"ARGB-4444", 256); bpp=16; break;
+ case D3DFMT_X4R4G4B4 : lstrcpynW(szfmt, L"XRGB-4444", 256); bpp=16; break;
+ }
+ swprintf(str, L" %s, %4d x %4d, %3d %s ",
+ szfmt, g_disp_mode[nAdded].Width,
+ g_disp_mode[nAdded].Height,
+ g_disp_mode[nAdded].RefreshRate,
+ WASABI_API_LNGSTRINGW(IDS_HZ));
+
+ /*
+ #ifdef DONT_ALLOW_8BIT_FULLSCREEN
+ if (bpp==8) continue;
+ #endif
+ #ifdef DONT_ALLOW_16_24_32_BIT_FULLSCREEN
+ if (bpp==16 || bpp==24 || bpp==32) continue;
+ #endif
+ */
+
+ int nPos = SendMessageW( hwnd_listbox, CB_ADDSTRING, 0, (LPARAM)str);
+
+ // keep a record of the original index, because the combo box SORTS the data:
+ SendMessage( hwnd_listbox, CB_SETITEMDATA, nPos, i);
+
+ nAdded++;
+ }
+
+ g_num_disp_modes = nAdded;
+
+ // now set selection, based on best match to prev. video mode.
+ int found = 0;
+
+ // Fallback order:
+ // 0. exact match (4 params) w,h,r,f
+ // 1. ignore refresh rate, but still heed color format
+ // 2. heed only w,h, and if desired_mode.Format is UNKNOWN,
+ // try for a 16-bpp color format and 60 Hz
+ // 3. heed only w,h, and if desired_mode.Format is UNKNOWN,
+ // try for a 16-bpp color format at any Hz
+ // 4. heed only w,h.
+
+ D3DDISPLAYMODE desired_mode = m_disp_mode_fs;
+
+ assert(desired_mode.Format != D3DFMT_UNKNOWN);
+ // this should never happen anymore, now that we set smarter default FS display mode
+ // (to match the current display mode) in PluginShell.cpp's PluginPreInitialize().
+ /*if (desired_mode.Format==D3DFMT_UNKNOWN)
+ {
+ GetCurrentDisplayMode(&desired_mode);
+
+ // first-time config: try to find a video mode that matches our ideal.
+ // do many passes until we find one, each time relaxing more constraints.
+ // outline of the passes:
+
+ // PASS MATCH:
+ // 0. w,h,r,16bpp
+ // 1. w,h,-,16bpp
+ // 2. w,h,r,-
+ // 3. w,h,-,-
+ // 4. -,-,-,-
+ for (int rep=0; rep<5; rep++)
+ {
+ for (i=0; i<g_num_disp_modes && !found; i++)
+ {
+ // we have to remap here, because the combo box SORTED the data:
+ int id = SendMessage( hwnd_listbox, CB_GETITEMDATA, i, 0);
+
+ bool bDesiredBitDepth = (
+ (g_disp_mode[id].Format == D3DFMT_R8G8B8 ) ||
+ (g_disp_mode[id].Format == D3DFMT_A8R8G8B8) ||
+ (g_disp_mode[id].Format == D3DFMT_X8R8G8B8)
+ );
+
+ bool bMatch = true;
+
+ if (rep<=3 && desired_mode.Width!=g_disp_mode[id].Width)
+ bMatch = false;
+ if (rep<=3 && desired_mode.Height!=g_disp_mode[id].Height)
+ bMatch = false;
+ if ((rep==0 || rep==2) && desired_mode.RefreshRate!=g_disp_mode[id].RefreshRate)
+ bMatch = false;
+ if (rep<=1 && !bDesiredBitDepth)
+ bMatch = false;
+
+ if (bMatch)
+ {
+ SendMessage( hwnd_listbox, CB_SETCURSEL, i, 0);
+ found = 1;
+ }
+ }
+ }
+
+ // if no match could be found, select #0.
+ if (!found)
+ SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
+ }
+ else
+ */
+ {
+ // find best match to prev. selection.
+ // do many passes until we find one, each time relaxing more constraints.
+ // outline of the passes:
+
+ int bpp_desired = 0;
+ switch(desired_mode.Format)
+ {
+ case D3DFMT_R8G8B8 : bpp_desired = 32; break;
+ case D3DFMT_A8R8G8B8: bpp_desired = 32; break;
+ case D3DFMT_X8R8G8B8: bpp_desired = 32; break;
+ case D3DFMT_R5G6B5 : bpp_desired = 16; break;
+ case D3DFMT_X1R5G5B5: bpp_desired = 16; break;
+ case D3DFMT_A1R5G5B5: bpp_desired = 16; break;
+ case D3DFMT_A4R4G4B4: bpp_desired = 16; break;
+ case D3DFMT_R3G3B2 : bpp_desired = 8; break;
+ case D3DFMT_A8R3G3B2: bpp_desired = 16; break;
+ case D3DFMT_X4R4G4B4: bpp_desired = 16; break;
+ }
+
+ // rep MATCH:
+ // 0. w,h,r,f
+ // 1. w,h,-,f
+ // 2. w,h,r,- pass:
+ // 3. w,h,-,- -on pass 0, for 'f', match exact format
+ // 4. 8,6,r,f -on pass 1, for 'f', just match # of bits per pixel
+ // 5. 8,6,-,f (more relaxed match)
+ // 6. 8,6,r,-
+ // 7. 8,6,-,-
+ // 8. -,-,r,f
+ // 9. -,-,-,f
+ // 10. -,-,r,-
+ // 11. -,-,-,-
+ for (int rep=0; rep<12 && !found; rep++)
+ {
+ for (int pass=0; pass<2 && !found; pass++)
+ {
+ for (i=0; i<g_num_disp_modes && !found; i++)
+ {
+ // we have to remap here, because the combo box SORTED the data:
+ int id = SendMessage( hwnd_listbox, CB_GETITEMDATA, i, 0);
+
+ int bpp_this_mode = 0;
+ switch(g_disp_mode[id].Format)
+ {
+ case D3DFMT_R8G8B8 : bpp_this_mode = 32; break;
+ case D3DFMT_A8R8G8B8: bpp_this_mode = 32; break;
+ case D3DFMT_X8R8G8B8: bpp_this_mode = 32; break;
+ case D3DFMT_R5G6B5 : bpp_this_mode = 16; break;
+ case D3DFMT_X1R5G5B5: bpp_this_mode = 16; break;
+ case D3DFMT_A1R5G5B5: bpp_this_mode = 16; break;
+ case D3DFMT_A4R4G4B4: bpp_this_mode = 16; break;
+ case D3DFMT_R3G3B2 : bpp_this_mode = 8; break;
+ case D3DFMT_A8R3G3B2: bpp_this_mode = 16; break;
+ case D3DFMT_X4R4G4B4: bpp_this_mode = 16; break;
+ }
+
+ bool bMatch = true;
+
+ if (rep < 4)
+ {
+ if (desired_mode.Width != g_disp_mode[id].Width)
+ bMatch = false;
+ if (desired_mode.Height != g_disp_mode[id].Height)
+ bMatch = false;
+ }
+ else if (rep < 8)
+ {
+ if (DEFAULT_FULLSCREEN_WIDTH != g_disp_mode[id].Width)
+ bMatch = false;
+ if (DEFAULT_FULLSCREEN_HEIGHT != g_disp_mode[id].Height)
+ bMatch = false;
+ }
+
+ if (((rep/2)%2)==0)
+ {
+ if (pass==0 && desired_mode.Format != g_disp_mode[id].Format)
+ bMatch = false;
+ else if (pass==1 && bpp_desired != bpp_this_mode)
+ bMatch = false;
+ }
+
+ if (((rep%2)==0) && desired_mode.RefreshRate!=g_disp_mode[id].RefreshRate)
+ {
+ bMatch = false;
+ }
+
+ if (bMatch)
+ {
+ SendMessage( hwnd_listbox, CB_SETCURSEL, i, 0);
+ found = 1;
+ }
+ }
+ }
+ }
+
+ // if no match could be found, select #0.
+ if (!found)
+ SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
+ }
+
+ UpdateDispModeMultiSampling(0);
+}
+
+void CPluginShell::UpdateDispModeMultiSampling(int screenmode)
+{
+ int nSampleTypes = 0;
+
+ HWND hwnd_listbox;
+ switch(screenmode)
+ {
+ case FULLSCREEN: hwnd_listbox = GetDlgItem(g_subwnd, IDC_FSMS); break;
+ case WINDOWED: hwnd_listbox = GetDlgItem(g_subwnd, IDC_WMS); break;
+ case DESKTOP: hwnd_listbox = GetDlgItem(g_subwnd, IDC_DMSMS); break;
+ }
+
+ wchar_t str[256];
+ int i;
+
+ if (!g_lpDX)
+ return;
+
+ if ((screenmode == WINDOWED && !m_allow_page_tearing_w) ||
+ (screenmode == FULLSCREEN && m_fake_fullscreen_mode && !m_allow_page_tearing_fs) ||
+ (screenmode == DESKTOP && !m_allow_page_tearing_dm))
+ {
+ // page tearing not allowed -> disable multisampling!
+ SendMessage( hwnd_listbox, CB_RESETCONTENT, 0, 0);
+ SendMessageW( hwnd_listbox, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_DISABLED_PAGE_TEARING));
+ SendMessage( hwnd_listbox, CB_SETITEMDATA, 0, 0 );
+ SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
+ EnableWindow( hwnd_listbox, 0 );
+ }
+ else
+ {
+ EnableWindow( hwnd_listbox, 1 );
+
+ // figure out which [fullscreen/windowed] adapter is currently selected:
+ int nAdapterOrdinal = GetCurrentlySelectedAdapter(screenmode);
+
+ // figure out current format:
+ D3DFORMAT format = D3DFMT_UNKNOWN;
+ if ((screenmode == WINDOWED) ||
+ (screenmode == FULLSCREEN && m_fake_fullscreen_mode) ||
+ (screenmode == DESKTOP))
+ {
+ // ** get it from the current display mode
+ // of the currently-selected [windowed/fake fullscreen] mode adapter **
+ D3DDISPLAYMODE dispmode;
+ if (g_lpDX->GetAdapterDisplayMode(nAdapterOrdinal, &dispmode) == D3D_OK)
+ format = dispmode.Format;
+ }
+ else
+ {
+ // **get it from the currently-selected fullscreen display mode**
+ int n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETCURSEL, 0, 0);
+ if (n != CB_ERR)
+ {
+ // since the combobox contents were sorted, we need to look up the original
+ // index into g_disp_mode[]:
+ n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETITEMDATA, n, 0);
+ if (n != CB_ERR)
+ format = g_disp_mode[n].Format;
+ }
+ }
+
+ D3DMULTISAMPLE_TYPE check[16] = {
+ D3DMULTISAMPLE_NONE,
+ D3DMULTISAMPLE_2_SAMPLES ,
+ D3DMULTISAMPLE_3_SAMPLES ,
+ D3DMULTISAMPLE_4_SAMPLES ,
+ D3DMULTISAMPLE_5_SAMPLES ,
+ D3DMULTISAMPLE_6_SAMPLES ,
+ D3DMULTISAMPLE_7_SAMPLES ,
+ D3DMULTISAMPLE_8_SAMPLES ,
+ D3DMULTISAMPLE_9_SAMPLES ,
+ D3DMULTISAMPLE_10_SAMPLES,
+ D3DMULTISAMPLE_11_SAMPLES,
+ D3DMULTISAMPLE_12_SAMPLES,
+ D3DMULTISAMPLE_13_SAMPLES,
+ D3DMULTISAMPLE_14_SAMPLES,
+ D3DMULTISAMPLE_15_SAMPLES,
+ D3DMULTISAMPLE_16_SAMPLES,
+ };
+
+ // clear the combo box
+ SendMessage( hwnd_listbox, CB_RESETCONTENT, 0, 0);
+
+ // re-populate it:
+ for (i=0; i<16; i++)
+ {
+ if (i==0 || SUCCEEDED(g_lpDX->CheckDeviceMultiSampleType(nAdapterOrdinal, D3DDEVTYPE_HAL,
+ format,
+ (screenmode==FULLSCREEN) ? 0 : 1,//bWindowed,
+ check[i], NULL)))
+ {
+ // add to listbox
+ if (i==0)
+ WASABI_API_LNGSTRINGW_BUF(IDS_NONE, str, 256);
+ else
+ StringCbPrintfW(str, sizeof(str), L"%2dX", i+1);
+
+ SendMessage( hwnd_listbox, CB_ADDSTRING, nSampleTypes, (LPARAM)str);
+
+ // set the item data to the D3DMULTISAMPLE_TYPE value:
+ SendMessage( hwnd_listbox, CB_SETITEMDATA, nSampleTypes, check[i] );
+
+ nSampleTypes++;
+ }
+ }
+
+ // set prev. selection
+ D3DMULTISAMPLE_TYPE prev_seln;
+ switch(screenmode)
+ {
+ case FULLSCREEN: prev_seln = m_multisample_fullscreen; break;
+ case WINDOWED: prev_seln = m_multisample_windowed; break;
+ //case FAKE_FULLSCREEN: prev_seln = m_multisample_fake_fullscreen; break;
+ case DESKTOP: prev_seln = m_multisample_desktop; break;
+ }
+
+ for (i=0; i<nSampleTypes; i++)
+ {
+ int id = SendMessage( hwnd_listbox, CB_GETITEMDATA, i, 0);
+ if (id==prev_seln)
+ {
+ SendMessage( hwnd_listbox, CB_SETCURSEL, i, 0);
+ return;
+ }
+ }
+
+ SendMessage( hwnd_listbox, CB_SETCURSEL, 0, 0);
+ }
+}
+
+void CPluginShell::UpdateMaxFps(int screenmode)
+{
+ // initialize sleep combo boxes
+ HWND ctrl;
+ switch(screenmode)
+ {
+ case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FS_MAXFPS ); break;
+ case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_W_MAXFPS ); break;
+ //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FFS_MAXFPS); break;
+ case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_DMS_MAXFPS); break;
+ }
+
+ SendMessage( ctrl, CB_RESETCONTENT, 0, 0);
+ for (int j=0; j<=MAX_MAX_FPS; j++)
+ {
+ wchar_t buf[256];
+ if (j==0)
+ WASABI_API_LNGSTRINGW_BUF(IDS_UNLIMITED, buf, 256);
+ else
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_X_FRAME_SEC), (j<MAX_MAX_FPS)?(MAX_MAX_FPS+1-j):(MAX_MAX_FPS+1-j));
+
+ SendMessageW( ctrl, CB_ADDSTRING, j, (LPARAM)buf);
+ }
+
+ // set prev. selection
+ int max_fps;
+ switch(screenmode)
+ {
+ case FULLSCREEN: max_fps = m_max_fps_fs; break;
+ case WINDOWED: max_fps = m_max_fps_w; break;
+ //case FAKE_FULLSCREEN: max_fps = m_max_fps_fake_fs; break;
+ case DESKTOP: max_fps = m_max_fps_dm; break;
+ }
+ if (max_fps == 0)
+ SendMessage(ctrl, CB_SETCURSEL, 0, 0);
+ else
+ SendMessage(ctrl, CB_SETCURSEL, MAX_MAX_FPS-max_fps+1, 0);
+}
+
+int CPluginShell::GetCurrentlySelectedAdapter(int screenmode)
+{
+ // returns the ordinal adapter #.
+ HWND ctrl;
+ switch(screenmode)
+ {
+ case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FS ); break;
+ case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_W ); break;
+ //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FFS); break;
+ case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_DMS); break;
+ }
+
+ int n = SendMessage(ctrl, CB_GETCURSEL, 0, 0);
+ //if (n != CB_ERR)
+ // n = SendMessage(ctrl, CB_GETITEMDATA, n, 0);
+ if (n != CB_ERR)
+ return n;
+ else
+ return D3DADAPTER_DEFAULT;
+}
+
+void CPluginShell::SaveDisplayMode()
+{
+ //if (m_fake_fullscreen_mode)
+ // return;
+
+ // read fullscreen display mode
+ int n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETCURSEL, 0, 0);
+ if (n != CB_ERR)
+ {
+ // since the combobox contents were sorted, we need to look up the original
+ // index into g_disp_mode[]:
+ n = SendMessage( GetDlgItem( g_subwnd, IDC_DISP_MODE ), CB_GETITEMDATA, n, 0);
+ if (n != CB_ERR)
+ m_disp_mode_fs = g_disp_mode[n];
+ }
+}
+
+void CPluginShell::SaveMultiSamp(int screenmode)
+{
+ HWND ctrl;
+ switch(screenmode)
+ {
+ case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FSMS); break;
+ case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_WMS); break;
+ //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FFSMS); break;
+ case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_DMSMS); break;
+ }
+
+ // if page tearing is disabled, then multisampling must be disabled,
+ // so ignore multisample selection
+ if (g_subwnd && g_nTab==0)
+ {
+ if (screenmode == WINDOWED && !m_allow_page_tearing_w)
+ return;
+ if (screenmode == DESKTOP && !m_allow_page_tearing_dm)
+ return;
+ if (screenmode == FULLSCREEN && m_fake_fullscreen_mode && !m_allow_page_tearing_fs)
+ return;
+ }
+
+ // read windowed & fullscreen multisampling settings:
+ int n = SendMessage(ctrl , CB_GETCURSEL, 0, 0);
+ if (n != CB_ERR)
+ {
+ n = SendMessage( ctrl, CB_GETITEMDATA, n, 0);
+ if (n != CB_ERR)
+ {
+ switch(screenmode)
+ {
+ case FULLSCREEN: m_multisample_fullscreen = (D3DMULTISAMPLE_TYPE)n; break;
+ case WINDOWED: m_multisample_windowed = (D3DMULTISAMPLE_TYPE)n; break;
+ //case FAKE_FULLSCREEN: m_multisample_fake_fullscreen = (D3DMULTISAMPLE_TYPE)n; break;
+ case DESKTOP: m_multisample_desktop = (D3DMULTISAMPLE_TYPE)n; break;
+ }
+ }
+ }
+}
+
+void CPluginShell::SaveMaxFps(int screenmode)
+{
+ HWND ctrl;
+ switch(screenmode)
+ {
+ case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FS_MAXFPS); break;
+ case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_W_MAXFPS); break;
+ //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_FFS_MAXFPS); break;
+ case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_DMS_MAXFPS); break;
+ }
+
+ // read max fps settings
+ int n = SendMessage(ctrl, CB_GETCURSEL, 0, 0);
+ if (n != CB_ERR)
+ {
+ if (n > 0)
+ n = MAX_MAX_FPS+1 - n;
+
+ switch(screenmode)
+ {
+ case FULLSCREEN: m_max_fps_fs = n; break;
+ case WINDOWED: m_max_fps_w = n; break;
+ //case FAKE_FULLSCREEN: m_max_fps_fake_fs = n; break;
+ case DESKTOP: m_max_fps_dm = n; break;
+ }
+ }
+}
+
+void CPluginShell::SaveAdapter(int screenmode)
+{
+ HWND ctrl;
+ switch(screenmode)
+ {
+ case FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FS); break;
+ case WINDOWED: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_W); break;
+ //case FAKE_FULLSCREEN: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_FFS); break;
+ case DESKTOP: ctrl = GetDlgItem(g_subwnd, IDC_ADAPTER_DMS); break;
+ }
+
+ // save windowed/fullscreen adapter
+ int n = SendMessage( ctrl, CB_GETCURSEL, 0, 0);
+ if (n != CB_ERR)
+ {
+ switch(screenmode)
+ {
+ case FULLSCREEN:
+ m_adapter_guid_fullscreen = g_disp_adapter_fs[n].DeviceIdentifier;
+ StringCbCopy(m_adapter_devicename_fullscreen, sizeof(m_adapter_devicename_fullscreen), g_disp_adapter_fs[n].DeviceName);
+ //strcpy(m_adapter_desc_fullscreen, g_disp_adapter_fs[n].Description);
+ break;
+ case WINDOWED:
+ m_adapter_guid_windowed = g_disp_adapter_w[n].DeviceIdentifier;
+ StringCbCopy(m_adapter_devicename_windowed, sizeof(m_adapter_devicename_windowed), g_disp_adapter_fs[n].DeviceName);
+ //strcpy(m_adapter_desc_windowed, g_disp_adapter_fs[n].Description);
+ break;
+ //case FAKE_FULLSCREEN:
+ //m_adapter_guid_fake_fullscreen = g_disp_adapter_w[n].DeviceIdentifier;
+ //strcpy(m_adapter_desc_fake_fullscreen, g_disp_adapter_fs[n].Description);
+ //break; // [sic]
+ case DESKTOP:
+ m_adapter_guid_desktop = g_disp_adapter_dm[n].DeviceIdentifier;
+ StringCbCopy(m_adapter_devicename_desktop, sizeof(m_adapter_devicename_desktop), g_disp_adapter_fs[n].DeviceName);
+ //strcpy(m_adapter_desc_desktop, g_disp_adapter_fs[n].Description);
+ break;
+ }
+ }
+}
+
+/*
+BOOL CALLBACK GenericTabCtrlProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ return 0;
+}
+*/
+
+// OnTabChanged - processes the TCN_SELCHANGE notification.
+void CPluginShell::OnTabChanged(int nNewTab)
+{
+ if (g_subwnd)
+ {
+ DestroyWindow(g_subwnd);
+ g_subwnd = NULL;
+ }
+
+ g_nTab = nNewTab;
+
+ if (g_nTab >= 0 && g_nTab < MAX_PROPERTY_PAGES)
+ {
+ HWND h = WASABI_API_CREATEDIALOGPARAMW(g_proppage_id[g_nTab], g_config_hwnd, this->TabCtrlProc, (LPARAM)this);
+ // NOTE: CreateDialogParam will call TabCtrlProc with WM_INITDIALOG,
+ // which is where 'g_subwnd' will get set.
+
+ // do this here to ensure that the current prefs page is correctly themed
+ if(!SendMessage(this->m_hWndWinamp,WM_WA_IPC,IPC_ISWINTHEMEPRESENT,IPC_USE_UXTHEME_FUNC))
+ {
+ SendMessage(this->m_hWndWinamp,WM_WA_IPC,(WPARAM)h,IPC_USE_UXTHEME_FUNC);
+ }
+ }
+}
+
+INT_PTR CALLBACK CPluginShell::TabCtrlProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
+
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+
+ if (p && g_nTab >= 0 && g_nTab < MAX_PROPERTY_PAGES)
+ {
+ if (msg==WM_INITDIALOG)
+ g_subwnd = hwnd;
+
+ if (g_nTab==0)
+ p->PluginShellConfigTab1Proc(hwnd, msg, wParam, lParam);
+ p->MyConfigTabProc(g_nTab+1, hwnd, msg, wParam, lParam);
+
+ if (msg==WM_INITDIALOG)
+ {
+ // once it has been initialized, reposition the subdialog:
+ RECT r;
+ GetWindowRect(GetDlgItem(g_config_hwnd,IDC_RECT),&r);
+ ScreenToClient(g_config_hwnd,(LPPOINT)&r);
+ SetWindowPos(g_subwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
+ ShowWindow(g_subwnd,SW_SHOWNA);
+ }
+ }
+
+ const int controls[] =
+ {
+ IDC_BRIGHT_SLIDER,
+ IDC_HARDCUT_LOUDNESS,
+ };
+ if (FALSE != WASABI_API_APP->DirectMouseWheel_ProcessDialogMessage(hwnd, msg, wParam, lParam, controls, ARRAYSIZE(controls)))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL CPluginShell::PluginShellConfigTab1Proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ #ifdef _DEBUG
+ OutputDebugMessage(" Tab1Proc: ", hwnd, msg, wParam, lParam);
+ #endif
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ // pre-checks
+ if (m_start_fullscreen && m_start_desktop)
+ m_start_desktop = 0;
+ if (!mod1.hwndParent || SendMessage(mod1.hwndParent,WM_WA_IPC,0,0) < 0x2900)
+ {
+ m_skin = 0;
+ EnableWindow(GetDlgItem(hwnd,IDC_CB_SKIN), 0);
+ char buf[256];
+ buf[0] = 0;
+ GetWindowText(GetDlgItem(hwnd,IDC_CB_SKIN), buf, 255);
+ StringCbCat(buf, sizeof(buf), " 2.90+");
+ SetWindowText(GetDlgItem(hwnd,IDC_CB_SKIN), buf);
+ }
+
+ // set checkboxes
+ CheckDlgButton(hwnd, IDC_CB_FS, m_start_fullscreen);
+ CheckDlgButton(hwnd, IDC_CB_DMS, m_start_desktop);
+ CheckDlgButton(hwnd, IDC_CB_FAKE, m_fake_fullscreen_mode);
+ CheckDlgButton(hwnd, IDC_CB_PRESS_F1_MSG, m_show_press_f1_msg);
+ CheckDlgButton(hwnd, IDC_CB_WPT, m_allow_page_tearing_w);
+ CheckDlgButton(hwnd, IDC_CB_FSPT, m_allow_page_tearing_fs);
+ CheckDlgButton(hwnd, IDC_CB_DMSPT, m_allow_page_tearing_dm);
+ CheckDlgButton(hwnd, IDC_CB_MIN, m_minimize_winamp);
+ CheckDlgButton(hwnd, IDC_CB_SAVE_CPU, m_save_cpu);
+ CheckDlgButton(hwnd, IDC_CB_SKIN, m_skin);
+ CheckDlgButton(hwnd, IDC_CB_FIXSLOWTEXT, m_fix_slow_text);
+ CheckDlgButton(hwnd, IDC_CB_VJMODE, m_vj_mode);
+
+ // Enumerate available adapters.
+ UpdateAdapters(0); // fullscreen
+ //-calls UpdateFSAdapterDispModes()
+ //-which then calls UpdateDispModeMultiSampling(0).
+ UpdateAdapters(1); // windowed
+ //-skips UpdateFSAdapterDispModes() (not necessary for windowed mode)
+ //-then calls UpdateDispModeMultiSampling(1).
+ UpdateAdapters(3); // desktop
+ //-skips UpdateFSAdapterDispModes() (not necessary for fake fullscreen mode)
+ //-then calls UpdateDispModeMultiSampling(2).
+ UpdateMaxFps(0);
+ UpdateMaxFps(1);
+ UpdateMaxFps(3); // desktop
+
+ // disable a few things if fake fullscreen mode enabled:
+ EnableWindow(GetDlgItem(hwnd, IDC_DISP_MODE), !m_fake_fullscreen_mode);
+ //EnableWindow(GetDlgItem(hwnd, IDC_FSMS), !m_fake_fullscreen_mode);
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ // read checkboxes
+ m_start_fullscreen = DlgItemIsChecked(hwnd, IDC_CB_FS );
+ m_start_desktop = DlgItemIsChecked(hwnd, IDC_CB_DMS );
+ m_fake_fullscreen_mode = DlgItemIsChecked(hwnd, IDC_CB_FAKE );
+ m_show_press_f1_msg = DlgItemIsChecked(hwnd, IDC_CB_PRESS_F1_MSG);
+ m_allow_page_tearing_w = DlgItemIsChecked(hwnd, IDC_CB_WPT );
+ m_allow_page_tearing_fs= DlgItemIsChecked(hwnd, IDC_CB_FSPT );
+ m_allow_page_tearing_dm= DlgItemIsChecked(hwnd, IDC_CB_DMSPT);
+ m_minimize_winamp = DlgItemIsChecked(hwnd, IDC_CB_MIN );
+ m_save_cpu = DlgItemIsChecked(hwnd, IDC_CB_SAVE_CPU );
+ m_fix_slow_text = DlgItemIsChecked(hwnd, IDC_CB_FIXSLOWTEXT);
+ m_vj_mode = DlgItemIsChecked(hwnd, IDC_CB_VJMODE);
+
+ if (mod1.hwndParent && SendMessage(mod1.hwndParent,WM_WA_IPC,0,0) >= 0x2900)
+ m_skin = DlgItemIsChecked(hwnd, IDC_CB_SKIN );
+
+ // read all 3 adapters
+ SaveAdapter(0);
+ SaveAdapter(1);
+ SaveAdapter(3);
+
+ // read fullscreen display mode
+ SaveDisplayMode();
+
+ // read all 3 multisampling settings:
+ SaveMultiSamp(0);
+ SaveMultiSamp(1);
+ SaveMultiSamp(3);
+
+ // read all 3 max fps settings
+ SaveMaxFps(0);
+ SaveMaxFps(1);
+ SaveMaxFps(3);
+ }
+ break;
+
+ case WM_COMMAND:
+ if (!g_ignore_clicks)
+ {
+ int id = LOWORD(wParam);
+ g_ignore_clicks = 1;
+ switch(id)
+ {
+ case ID_FONTS:
+ WASABI_API_DIALOGBOXPARAMW(IDD_FONTDIALOG, hwnd, FontDialogProc, (LPARAM)this);
+ break;
+
+ case ID_DM_MORE:
+ WASABI_API_DIALOGBOXPARAMW(IDD_DESKTOPMODE, hwnd, DesktopOptionsDialogProc, (LPARAM)this);
+ break;
+
+ case ID_DUALHEAD:
+ WASABI_API_DIALOGBOXPARAMW(IDD_DUALHEAD, hwnd, DualheadDialogProc, (LPARAM)this);
+ break;
+
+ case IDC_ADAPTER_FS:
+ SaveDisplayMode();
+ SaveMultiSamp(FULLSCREEN);
+ SaveAdapter(0);
+ UpdateFSAdapterDispModes();
+ break;
+
+ case IDC_ADAPTER_W:
+ SaveMultiSamp(WINDOWED);
+ UpdateDispModeMultiSampling(WINDOWED);
+ break;
+
+ /*
+ case IDC_ADAPTER_FFS:
+ SaveMultiSamp(FAKE_FULLSCREEN);
+ UpdateDispModeMultiSampling(FAKE_FULLSCREEN);
+ break;
+ */
+
+ case IDC_ADAPTER_DMS:
+ SaveMultiSamp(DESKTOP);
+ UpdateDispModeMultiSampling(DESKTOP);
+ break;
+
+ case IDC_DISP_MODE:
+ SaveMultiSamp(FULLSCREEN);
+ UpdateDispModeMultiSampling(FULLSCREEN);
+ break;
+
+ case IDC_CB_WPT:
+ SaveMultiSamp(WINDOWED);
+ m_allow_page_tearing_w = DlgItemIsChecked(hwnd, IDC_CB_WPT);
+ UpdateDispModeMultiSampling(WINDOWED);
+ break;
+
+ case IDC_CB_FSPT:
+ SaveMultiSamp(FULLSCREEN);
+ m_allow_page_tearing_fs = DlgItemIsChecked(hwnd, IDC_CB_FSPT);
+ UpdateDispModeMultiSampling(FULLSCREEN);
+ break;
+
+ case IDC_CB_DMSPT:
+ SaveMultiSamp(DESKTOP);
+ m_allow_page_tearing_dm = DlgItemIsChecked(hwnd, IDC_CB_DMSPT);
+ UpdateDispModeMultiSampling(DESKTOP);
+ break;
+
+ case IDC_CB_FS:
+ m_start_fullscreen = DlgItemIsChecked(hwnd, IDC_CB_FS );
+ if (m_start_fullscreen && m_start_desktop)
+ {
+ m_start_desktop = 0;
+ CheckDlgButton(hwnd, IDC_CB_DMS, m_start_desktop);
+ }
+ break;
+
+ case IDC_CB_DMS:
+ m_start_desktop = DlgItemIsChecked(hwnd, IDC_CB_DMS );
+ if (m_start_fullscreen && m_start_desktop)
+ {
+ m_start_fullscreen = 0;
+ CheckDlgButton(hwnd, IDC_CB_FS, m_start_fullscreen);
+ }
+ break;
+
+ case IDC_CB_FAKE:
+ SaveMultiSamp(FULLSCREEN);
+ m_fake_fullscreen_mode = DlgItemIsChecked(hwnd, IDC_CB_FAKE );
+ EnableWindow(GetDlgItem(hwnd, IDC_DISP_MODE), !m_fake_fullscreen_mode);
+ CheckDlgButton(hwnd, IDC_CB_FSPT, m_fake_fullscreen_mode ? m_allow_page_tearing_fs : 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_CB_FSPT), m_fake_fullscreen_mode ? 1 : 0);
+ UpdateDispModeMultiSampling(FULLSCREEN);
+ break;
+
+ /*
+ case IDC_CB_FFSPT:
+ SaveMultiSamp(FAKE_FULLSCREEN);
+ m_allow_page_tearing_fake_fs = DlgItemIsChecked(hwnd, IDC_CB_FFSPT);
+ UpdateDispModeMultiSampling(FAKE_FULLSCREEN);
+ break;
+ */
+ }
+ g_ignore_clicks = 0;
+ }
+ break; // case WM_COMMAND
+
+ case WM_HELP:
+ if (lParam)
+ {
+ HELPINFO *ph = (HELPINFO*)lParam;
+ wchar_t title[1024];
+ wchar_t buf[2048];
+ wchar_t ctrl_name[1024];
+ GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
+ RemoveSingleAmpersands(ctrl_name);
+ buf[0] = 0;
+
+ switch(ph->iCtrlId)
+ {
+ case ID_FONTS:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FONTS_HELP, buf, 2048);
+ break;
+
+ case ID_DUALHEAD:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_DUAL_HEAD_HELP, buf, 2048);
+ break;
+
+ case IDC_W_MULTISAMPLING_CAPTION:
+ case IDC_FS_MULTISAMPLING_CAPTION:
+ case IDC_DMS_MULTISAMPLING_CAPTION:
+ //case IDC_FFS_MULTISAMPLING_CAPTION:
+ case IDC_WMS:
+ case IDC_FSMS:
+ case IDC_DMSMS:
+ //case IDC_FFSMS:
+ WASABI_API_LNGSTRINGW_BUF(IDS_MULTI_SAMPLING, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_MULTI_SAMPLING_HELP, buf, 2048);
+ break;
+
+ case IDC_W_MAXFPS:
+ case IDC_FS_MAXFPS:
+ case IDC_DMS_MAXFPS:
+ //case IDC_FFS_MAXFPS:
+ case IDC_W_MAXFPS_CAPTION:
+ case IDC_FS_MAXFPS_CAPTION:
+ case IDC_DMS_MAXFPS_CAPTION:
+ //case IDC_FFS_MAXFPS_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_MAX_FRAMERATE, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_MAX_FRAMERATE_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_FAKE:
+ WASABI_API_LNGSTRINGW_BUF(IDS_FAKE_FULLSCREEN, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FAKE_FULLSCREEN_HELP, buf, 2048);
+ break;
+
+ case IDC_ADAPTER_FS:
+ case IDC_FS_ADAPTER_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_FULLSCREEN_ADAPTER, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FULLSCREEN_ADAPTER_HELP, buf, 2048);
+ break;
+
+ case IDC_ADAPTER_W:
+ case IDC_W_ADAPTER_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_WINDOWED_ADPATER, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_WINDOWED_ADPATER_HELP, buf, 2048);
+ break;
+
+ case IDC_ADAPTER_DMS:
+ case IDC_DMS_ADAPTER_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_DESKTOP_ADAPTER, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_DESKTOP_ADAPTER_HELP, buf, 2048);
+ break;
+
+ case IDC_DISP_MODE:
+ case IDC_DISP_MODE_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_FS_DISPLAY_MODE, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FS_DISPLAY_MODE_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_WPT:
+ case IDC_CB_FSPT:
+ case IDC_CB_DMSPT:
+ //case IDC_CB_FFSPT:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_HELP_ON_X_CHECKBOX_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_FS:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FORCE_INTO_FS_MODE_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_DMS:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FORCE_INTO_DESKTOP_MODE_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_PRESS_F1_MSG:
+ WASABI_API_LNGSTRINGW_BUF(IDS_HELP_ON_F1, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_HELP_ON_F1_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_SKIN:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_SKIN_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_SAVE_CPU:
+ WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_CPU_CHECKBOX, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_CPU_CHECKBOX_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_MIN:
+ WASABI_API_LNGSTRINGW_BUF(IDS_HELP_MINIMIZE_WINAMP, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_HELP_MINIMIZE_WINAMP_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_FIXSLOWTEXT:
+ WASABI_API_LNGSTRINGW_BUF(IDS_TRY_TO_FIX_SLOW_TEXT, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_TRY_TO_FIX_SLOW_TEXT_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_VJMODE:
+ WASABI_API_LNGSTRINGW_BUF(IDS_VJ_MODE, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_VJ_MODE_HELP, buf, 2048);
+ break;
+
+ case IDC_DMS_LABEL:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_DMS_LABEL_HELP, buf, 2048);
+ break;
+
+ case IDC_FS_LABEL:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_FS_LABEL_HELP, buf, 2048);
+ break;
+
+ case IDC_W_LABEL:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_W_LABEL_HELP, buf, 2048);
+ break;
+
+ case ID_DM_MORE:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_DM_MORE_HELP, buf, 2048);
+ break;
+ }
+
+ if (buf[0])
+ MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+
+ }
+ break; // case WM_HELP
+ }
+
+ return 0;
+}
+
+BOOL CALLBACK CPluginShell::ConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
+
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+
+ if (p)
+ return p->PluginShellConfigDialogProc(hwnd, msg, wParam, lParam);
+ else
+ return FALSE;
+}
+
+BOOL CPluginShell::PluginShellConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ #ifdef _DEBUG
+ OutputDebugMessage("CfgDlgProc: ", hwnd, msg, wParam, lParam);
+ #endif
+
+ switch (msg)
+ {
+ case WM_DESTROY:
+ EndConfig();
+ return 0;
+
+ case WM_INITDIALOG:
+ {
+ // Initialize all config panel global variables:
+ if (!InitConfig(hwnd))
+ {
+ wchar_t title[64];
+ MessageBoxW(hwnd, WASABI_API_LNGSTRINGW(IDS_INITCONFIG_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ EndConfig();
+ int id=LOWORD(wParam);
+ EndDialog(hwnd,id);
+ return false;
+ }
+
+ // set window caption
+ SetWindowText( hwnd, WINDOWCAPTION );
+
+ // Test for DirectX 9 + start it
+ // note: if you don't call LoadLibrary here, and you're on a system
+ // where DX9 is missing, Direct3DCreate9() might crash; so call it.
+ int d3d9_already_loaded = (GetModuleHandle("d3d9.dll") != NULL) ? 1 : 0;
+ if (!d3d9_already_loaded)
+ g_hmod_d3d9 = LoadLibrary("d3d9.dll");
+
+ if ( (!d3d9_already_loaded && !g_hmod_d3d9) ||
+ !(g_lpDX = Direct3DCreate9(D3D_SDK_VERSION))
+ )
+ {
+ MissingDirectX(hwnd);
+
+ EndConfig();
+ int id=LOWORD(wParam);
+ EndDialog(hwnd,id);
+ return false;
+ }
+
+ if (!g_hmod_d3dx9)
+ g_hmod_d3dx9 = FindD3DX9(GetWinampWindow());
+
+ if ((!g_hmod_d3dx9))
+ {
+ MissingDirectX(hwnd);
+ EndConfig();
+ int id=LOWORD(wParam);
+ EndDialog(hwnd,id);
+ return false;
+ }
+
+ // enable the 'view website' button only if plugin author has #defined a URL (in defines.h):
+ #ifndef PLUGIN_WEB_URL
+ ShowWindow(GetDlgItem(hwnd, ID_WEB), SW_HIDE);
+ #else
+ if (wcslen(PLUGIN_WEB_URL)==0)
+ ShowWindow(GetDlgItem(hwnd, ID_WEB), SW_HIDE);
+ #endif
+
+ // enable the 'view docs' button only if plugin author has #defined a filename (in defines.h):
+ #ifndef DOCFILE
+ ShowWindow(GetDlgItem(hwnd, ID_DOCS), SW_HIDE);
+ #else
+ if (wcslen(DOCFILE)==0)
+ ShowWindow(GetDlgItem(hwnd, ID_DOCS), SW_HIDE);
+ #endif
+
+ // set contents of IDC_SZ_ABOUT
+ wchar_t about[256];
+ StringCchPrintfW(about, 256, WASABI_API_LNGSTRINGW(IDS_ABOUT_STRING), LONGNAMEW, AUTHOR_NAME, COPYRIGHT);
+ SetDlgItemTextW(hwnd, IDC_SZ_ABOUT, about);
+
+ // initialize tab control:
+ {
+ HWND tabWnd = GetDlgItem(hwnd,IDC_TABS);
+ // Add Tabs:
+ if (!AddButton(0, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_1)) ||
+ !AddButton(1, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_2)) ||
+ !AddButton(2, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_3)) ||
+ !AddButton(3, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_4)) ||
+ !AddButton(4, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_5)) ||
+ !AddButton(5, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_6)) ||
+ !AddButton(6, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_7)) ||
+ !AddButton(7, tabWnd, WASABI_API_LNGSTRINGW(IDS_CONFIG_PANEL_BUTTON_8)))
+ {
+ wchar_t title[64];
+ MessageBoxW(hwnd, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_LOAD_TABS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ EndConfig();
+ int id=LOWORD(wParam);
+ EndDialog(hwnd,id);
+ return false;
+ }
+
+ // Simulate selection of the first tab.
+ int last_tab = GetPrivateProfileIntW(L"settings",L"last_tab",0,m_szConfigIniFile);
+ TabCtrl_SetCurSel(tabWnd, last_tab);
+ OnTabChanged(last_tab);
+ }
+
+ g_ignore_clicks = 0;
+
+ SetFocus(hwnd);
+ }
+ return 0;
+
+ case WM_NOTIFY:
+ if (!g_ignore_clicks)
+ {
+ LPNMHDR pnmh = (LPNMHDR)lParam;
+ switch(pnmh->code)
+ {
+ case TCN_SELCHANGE:
+ OnTabChanged(TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_TABS)));
+ break;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ if (!g_ignore_clicks)
+ {
+ int id = LOWORD(wParam);
+ switch(id)
+ {
+ case IDOK:
+ // kill current tab window, so that its settings get read
+ WritePrivateProfileIntW(TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_TABS)),L"last_tab",m_szConfigIniFile,L"settings");
+ OnTabChanged(-1);
+
+ // then save new config
+ WriteConfig();
+
+ EndDialog(hwnd,id);
+ return 0;
+
+ case IDCANCEL:
+ WritePrivateProfileIntW(TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_TABS)),L"last_tab",m_szConfigIniFile,L"settings");
+ EndDialog(hwnd,id);
+ return 0;
+
+ case ID_DOCS:
+ {
+ wchar_t szPath[512], szFile[512];
+ lstrcpyW(szPath, m_szPluginsDirPath);
+ lstrcpyW(szFile, szPath);
+ lstrcatW(szFile, DOCFILE);
+
+ intptr_t ret = myOpenURL(0,szFile);
+ if (ret <= 32)
+ {
+ wchar_t buf[1024];
+ switch(ret)
+ {
+ case SE_ERR_FNF:
+ case SE_ERR_PNF:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_DOCUMENTATION_FILE_NOT_FOUND), szFile);
+ break;
+ case SE_ERR_ACCESSDENIED:
+ case SE_ERR_SHARE:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_DOCUMENTATION_FILE_DENIED), szFile);
+ break;
+ case SE_ERR_NOASSOC:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_DUE_TO_NO_ASSOC), szFile);
+ break;
+ default:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_CODE_X), szFile, ret);
+ break;
+ }
+ MessageBoxW(hwnd, buf, WASABI_API_LNGSTRINGW(IDS_ERROR_OPENING_DOCUMENTATION), MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ }
+ break;
+
+ case ID_WEB:
+ {
+ intptr_t ret = myOpenURL(NULL, PLUGIN_WEB_URL);
+ if (ret <= 32)
+ {
+ wchar_t buf[1024];
+ switch(ret)
+ {
+ case SE_ERR_FNF:
+ case SE_ERR_PNF:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_URL_COULD_NOT_OPEN), PLUGIN_WEB_URL);
+ break;
+ case SE_ERR_ACCESSDENIED:
+ case SE_ERR_SHARE:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_WAS_DENIED), PLUGIN_WEB_URL);
+ break;
+ case SE_ERR_NOASSOC:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_FAILED_DUE_TO_NO_ASSOC), PLUGIN_WEB_URL);
+ break;
+ default:
+ StringCbPrintfW(buf, sizeof(buf), WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_FAILED_CODE_X), PLUGIN_WEB_URL, ret);
+ break;
+ }
+ MessageBoxW(hwnd, buf, WASABI_API_LNGSTRINGW(IDS_ERROR_OPENING_URL), MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ }
+ break;
+
+ case ID_DEFAULTS:
+ wchar_t title[64];
+ if (IDYES == MessageBoxW(hwnd, WASABI_API_LNGSTRINGW(IDS_RESTORE_ALL_DEFAULTS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_RESTORE_ALL_DEFAULTS_TITLE, title, 64),
+ MB_YESNO|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL))
+ {
+ DeleteFileW(m_szConfigIniFile);
+ Sleep(100);
+ EndDialog(hwnd,id);
+ }
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ break; // case WM_COMMAND
+
+ case WM_HELP:
+ if (lParam)
+ {
+ HELPINFO *ph = (HELPINFO*)lParam;
+ wchar_t title[1024];
+ wchar_t buf[2048];
+ wchar_t ctrl_name[1024];
+ GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
+ RemoveSingleAmpersands(ctrl_name);
+ buf[0] = 0;
+ switch(ph->iCtrlId)
+ {
+ case IDOK:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_OK_HELP, buf, 2048);
+ break;
+
+ case IDCANCEL:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_CANCEL_HELP, buf, 2048);
+ break;
+
+ case ID_DEFAULTS:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_RESTORE_DEFAULTS_HELP, buf, 2048);
+ break;
+
+ case ID_DOCS:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_DOCUMENTATION_BUTTON_HELP, buf, 2048);
+ break;
+
+ case ID_WEB:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_BUTTON), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_VIEW_ONLINE_DOCS_HELP, buf, 2048);
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (buf[0])
+ MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ break; // case WM_HELP
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/config2.cpp b/Src/Plugins/Visualization/vis_milk2/config2.cpp
new file mode 100644
index 00000000..ce4abb10
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/config2.cpp
@@ -0,0 +1,425 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "pluginshell.h"
+#include "resource.h"
+#include "utility.h"
+#include <strsafe.h>
+
+int g_nFontSize[] = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32,
+ 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 88, 96, 104, 112, 120, 128 };
+
+int CALLBACK EnumFontsProc(
+ CONST LOGFONT *lplf, // logical-font data
+ CONST TEXTMETRIC *lptm, // physical-font data
+ DWORD dwType, // font type
+ LPARAM lpData // application-defined data
+)
+{
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT1), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT2), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT3), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT4), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT5), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT6), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT7), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT8), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT9), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ return 1;
+}
+
+void SaveFont2(td_fontinfo *fi, DWORD ctrl1, DWORD ctrl2, DWORD bold_id, DWORD ital_id, DWORD aa_id, HWND hwnd)
+{
+ HWND fontbox = GetDlgItem( hwnd, ctrl1 );
+ HWND sizebox = GetDlgItem( hwnd, ctrl2 );
+
+ // font face
+ int t = SendMessage( fontbox, CB_GETCURSEL, 0, 0);
+ SendMessageW( fontbox, CB_GETLBTEXT, t, (LPARAM)fi->szFace);
+
+ // font size
+ t = SendMessage( sizebox, CB_GETCURSEL, 0, 0);
+ if (t != CB_ERR)
+ {
+ int nMax = sizeof(g_nFontSize)/sizeof(int);
+ fi->nSize =g_nFontSize[nMax-1 - t];
+ }
+
+ // font options
+ fi->bBold = DlgItemIsChecked(hwnd, bold_id);
+ fi->bItalic = DlgItemIsChecked(hwnd, ital_id);
+ fi->bAntiAliased = DlgItemIsChecked(hwnd, aa_id);
+}
+
+void InitFont2(td_fontinfo *fi, DWORD ctrl1, DWORD ctrl2, DWORD bold_id, DWORD ital_id, DWORD aa_id, HWND hwnd, DWORD ctrl4, wchar_t* szFontName)
+{
+ HWND namebox = ctrl4 ? GetDlgItem( hwnd, ctrl4 ) : 0;
+ HWND fontbox = GetDlgItem( hwnd, ctrl1 );
+ HWND sizebox = GetDlgItem( hwnd, ctrl2 );
+ ShowWindow(fontbox, SW_NORMAL);
+ ShowWindow(sizebox, SW_NORMAL);
+ ShowWindow(GetDlgItem(hwnd,bold_id), SW_NORMAL);
+ ShowWindow(GetDlgItem(hwnd,ital_id), SW_NORMAL);
+ ShowWindow(GetDlgItem(hwnd,aa_id), SW_NORMAL);
+ if (namebox && szFontName && szFontName[0])
+ {
+ ShowWindow(namebox, SW_NORMAL);
+ wchar_t buf[256];
+ StringCbPrintfW(buf, sizeof(buf), L"%s:", szFontName);
+ SetWindowTextW(GetDlgItem(hwnd,ctrl4), buf);
+ }
+
+ // set selection
+ int nPos = SendMessageW( fontbox, CB_FINDSTRINGEXACT, -1, (LPARAM)fi->szFace);
+ if (nPos == CB_ERR)
+ nPos = 0;
+ SendMessage( fontbox, CB_SETCURSEL, nPos, 0);
+
+ //---------font size box-------------------
+ int nSel = 0;
+ int nMax = sizeof(g_nFontSize)/sizeof(int);
+ for (int i=0; i<nMax; i++)
+ {
+ wchar_t buf[256];
+ int s = g_nFontSize[nMax-1 - i];
+ StringCbPrintfW(buf, sizeof(buf), L" %2d ", s);
+ SendMessageW(sizebox, CB_ADDSTRING, i, (LPARAM)buf);
+ if (s == fi->nSize)
+ nSel = i;
+ }
+ SendMessage(sizebox, CB_SETCURSEL, nSel, 0);
+
+ //---------font options box-------------------
+ CheckDlgButton(hwnd, bold_id, fi->bBold);
+ CheckDlgButton(hwnd, ital_id, fi->bItalic);
+ CheckDlgButton(hwnd, aa_id, fi->bAntiAliased);
+}
+
+void SCOOT_CONTROL(HWND hwnd, int ctrl_id, int dx, int dy)
+{
+ RECT r;
+ GetWindowRect(GetDlgItem(hwnd,ctrl_id), &r);
+ ScreenToClient(hwnd, (LPPOINT)&r);
+ SetWindowPos (GetDlgItem(hwnd,ctrl_id), NULL, r.left + dx, r.top + dy, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
+}
+
+BOOL CALLBACK CPluginShell::FontDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
+
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+
+ if (p)
+ return p->PluginShellFontDialogProc(hwnd, msg, wParam, lParam);
+ else
+ return FALSE;
+}
+
+BOOL CPluginShell::PluginShellFontDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ #ifdef _DEBUG
+ OutputDebugMessage("FontDlgProc: ", hwnd, msg, wParam, lParam);
+ #endif
+
+ switch (msg)
+ {
+ case WM_DESTROY:
+ return 0;
+
+ case WM_INITDIALOG:
+ {
+ // Initialize all font dialog global variables here:
+ // ...
+
+ HDC hdc = GetDC(hwnd);
+ if (hdc)
+ {
+ EnumFonts(hdc, NULL, &EnumFontsProc, (LPARAM)hwnd);
+ ReleaseDC(hwnd, hdc);
+ }
+
+ #define InitFont(n, m) InitFont2(&m_fontinfo[n-1], IDC_FONT##n, IDC_FONTSIZE##n, IDC_FONTBOLD##n, IDC_FONTITAL##n, IDC_FONTAA##n, hwnd, IDC_FONT_NAME_##n, m)
+ InitFont(1, 0);
+ InitFont(2, 0);
+ InitFont(3, 0);
+ InitFont(4, 0);
+ #if (NUM_EXTRA_FONTS >= 1)
+ InitFont(5, WASABI_API_LNGSTRINGW(IDS_EXTRA_FONT_1_NAME));
+ #endif
+ #if (NUM_EXTRA_FONTS >= 2)
+ InitFont(6, WASABI_API_LNGSTRINGW(IDS_EXTRA_FONT_2_NAME));
+ #endif
+ #if (NUM_EXTRA_FONTS >= 3)
+ InitFont(7, EXTRA_FONT_3_NAME);
+ #endif
+ #if (NUM_EXTRA_FONTS >= 4)
+ InitFont(5, EXTRA_FONT_4_NAME);
+ #endif
+ #if (NUM_EXTRA_FONTS >= 5)
+ InitFont(9, EXTRA_FONT_5_NAME);
+ #endif
+
+ // Finally, if not all extra fonts are in use, shrink the window size, and
+ // move up any controls that were at the bottom:
+ RECT r;
+ GetWindowRect(hwnd, &r);
+ int scoot_factor = 128*(MAX_EXTRA_FONTS-NUM_EXTRA_FONTS)/MAX_EXTRA_FONTS;
+ if (scoot_factor>0)
+ {
+ SetWindowPos(hwnd, NULL, 0, 0, r.right-r.left, r.bottom-r.top - scoot_factor, SWP_NOMOVE|SWP_NOZORDER);
+ SCOOT_CONTROL(hwnd, IDC_FONT_TEXT, 0, -scoot_factor);
+ SCOOT_CONTROL(hwnd, IDOK, 0, -scoot_factor);
+ SCOOT_CONTROL(hwnd, IDCANCEL, 0, -scoot_factor);
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ int id = LOWORD(wParam);
+ switch(id)
+ {
+ case IDOK:
+
+ #define SaveFont(n) SaveFont2(&m_fontinfo[n-1], IDC_FONT##n, IDC_FONTSIZE##n, IDC_FONTBOLD##n, IDC_FONTITAL##n, IDC_FONTAA##n, hwnd)
+ SaveFont(1);
+ SaveFont(2);
+ SaveFont(3);
+ SaveFont(4);
+ #if (NUM_EXTRA_FONTS >= 1)
+ SaveFont(5);
+ #endif
+ #if (NUM_EXTRA_FONTS >= 2)
+ SaveFont(6);
+ #endif
+ #if (NUM_EXTRA_FONTS >= 3)
+ SaveFont(7);
+ #endif
+ #if (NUM_EXTRA_FONTS >= 4)
+ SaveFont(5);
+ #endif
+ #if (NUM_EXTRA_FONTS >= 5)
+ SaveFont(9);
+ #endif
+
+ EndDialog(hwnd,id);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwnd,id);
+ break;
+ }
+ }
+ break;
+
+ }
+
+ return 0;
+}
+
+void EnableStuff(HWND hwnd, int bEnable)
+{
+ EnableWindow(GetDlgItem(hwnd, IDC_CB_BOX), bEnable);
+ EnableWindow(GetDlgItem(hwnd, IDC_CB_MANUAL_SCOOT), bEnable);
+ EnableWindow(GetDlgItem(hwnd, IDC_DM_ALPHA_FIX_CAPTION), bEnable);
+ EnableWindow(GetDlgItem(hwnd, IDC_DM_ALPHA_FIX), bEnable);
+}
+
+BOOL CALLBACK CPluginShell::DesktopOptionsDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
+
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+
+ if (p)
+ return p->PluginShellDesktopOptionsDialogProc(hwnd, msg, wParam, lParam);
+ else
+ return FALSE;
+}
+
+BOOL CPluginShell::PluginShellDesktopOptionsDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ #ifdef _DEBUG
+ OutputDebugMessage("DmDlgProc: ", hwnd, msg, wParam, lParam);
+ #endif
+
+ switch (msg)
+ {
+ case WM_DESTROY:
+ return 0;
+
+ case WM_INITDIALOG:
+ {
+ CheckDlgButton(hwnd, IDC_CB_SHOW_ICONS, m_desktop_show_icons );
+ CheckDlgButton(hwnd, IDC_CB_BOX, m_desktop_textlabel_boxes );
+ CheckDlgButton(hwnd, IDC_CB_MANUAL_SCOOT, m_desktop_manual_icon_scoot);
+
+ HWND ctrl = GetDlgItem(hwnd, IDC_DM_ALPHA_FIX);
+ SendMessageW( ctrl, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_5_6_5_TEXTURE));
+ SendMessageW( ctrl, CB_ADDSTRING, 1, (LPARAM)WASABI_API_LNGSTRINGW(IDS_5_5_5_TEXTURE));
+ SendMessageW( ctrl, CB_ADDSTRING, 2, (LPARAM)WASABI_API_LNGSTRINGW(IDS_8_8_8_TEXTURE));
+ SendMessageW( ctrl, CB_SETCURSEL, m_desktop_555_fix, 0 );
+
+ EnableStuff(hwnd, m_desktop_show_icons);
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ int id = LOWORD(wParam);
+ switch(id)
+ {
+ case IDC_CB_SHOW_ICONS:
+ m_desktop_show_icons = DlgItemIsChecked(hwnd, IDC_CB_SHOW_ICONS);
+ EnableStuff(hwnd, m_desktop_show_icons);
+ break;
+
+ case IDOK:
+ m_desktop_show_icons = DlgItemIsChecked(hwnd, IDC_CB_SHOW_ICONS);
+ m_desktop_textlabel_boxes = DlgItemIsChecked(hwnd, IDC_CB_BOX);
+ m_desktop_manual_icon_scoot = DlgItemIsChecked(hwnd, IDC_CB_MANUAL_SCOOT);
+ m_desktop_555_fix = SendMessage( GetDlgItem(hwnd, IDC_DM_ALPHA_FIX), CB_GETCURSEL, 0, 0 );
+
+ EndDialog(hwnd,id);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwnd,id);
+ break;
+ }
+ }
+ break;
+
+ case WM_HELP:
+ if (lParam)
+ {
+ HELPINFO *ph = (HELPINFO*)lParam;
+ wchar_t title[1024];
+ wchar_t buf[2048];
+ wchar_t ctrl_name[1024];
+ GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
+ RemoveSingleAmpersands(ctrl_name);
+ buf[0] = 0;
+
+ switch(ph->iCtrlId)
+ {
+ case IDC_DM_ALPHA_FIX:
+ case IDC_DM_ALPHA_FIX_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_NO_ALPHA_FALLBACK, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_NO_ALPHA_FALLBACK_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_SHOW_ICONS:
+ StringCbPrintfW(title, sizeof(title), WASABI_API_LNGSTRINGW(IDS_HELP_ON_X_CHECKBOX), ctrl_name);
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_SHOW_ICONS_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_BOX:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_BOX, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_BOX_HELP, buf, 2048);
+ break;
+
+ case IDC_CB_MANUAL_SCOOT:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_MANUAL_SCOOT, title, 1024);
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_MANUAL_SCOOT_HELP, buf, 2048);
+ break;
+ }
+
+ if (buf[0])
+ MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ break;
+ }
+ return 0;
+}
+
+BOOL CALLBACK CPluginShell::DualheadDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ if (msg==WM_INITDIALOG && lParam > 0 && GetWindowLongPtr(hwnd,GWLP_USERDATA)==0)
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
+
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+
+ if (p)
+ return p->PluginShellDualheadDialogProc(hwnd, msg, wParam, lParam);
+ else
+ return FALSE;
+}
+
+BOOL CPluginShell::PluginShellDualheadDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ #ifdef _DEBUG
+ OutputDebugMessage("DHDlgProc: ", hwnd, msg, wParam, lParam);
+ #endif
+
+ switch (msg)
+ {
+ case WM_DESTROY:
+ return 0;
+
+ case WM_INITDIALOG:
+ {
+ HWND ctrl = GetDlgItem(hwnd, IDC_H_PICK);
+ SendMessageW( ctrl, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_SPAN_BOTH_SCREENS));
+ SendMessageW( ctrl, CB_ADDSTRING, 1, (LPARAM)WASABI_API_LNGSTRINGW(IDS_USE_LEFT_SCREEN_ONLY));
+ SendMessageW( ctrl, CB_ADDSTRING, 2, (LPARAM)WASABI_API_LNGSTRINGW(IDS_USE_RIGHT_SCREEN_ONLY));
+ SendMessage( ctrl, CB_SETCURSEL, m_dualhead_horz, 0 );
+
+ ctrl = GetDlgItem(hwnd, IDC_V_PICK);
+ SendMessageW( ctrl, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_SPAN_BOTH_SCREENS));
+ SendMessageW( ctrl, CB_ADDSTRING, 1, (LPARAM)WASABI_API_LNGSTRINGW(IDS_USE_TOP_SCREEN_ONLY));
+ SendMessageW( ctrl, CB_ADDSTRING, 2, (LPARAM)WASABI_API_LNGSTRINGW(IDS_USE_BOTTOM_SCREEN_ONLY));
+ SendMessage( ctrl, CB_SETCURSEL, m_dualhead_vert, 0 );
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ int id = LOWORD(wParam);
+ switch(id)
+ {
+ case IDOK:
+ m_dualhead_horz = SendMessage( GetDlgItem(hwnd, IDC_H_PICK), CB_GETCURSEL, 0, 0 );
+ m_dualhead_vert = SendMessage( GetDlgItem(hwnd, IDC_V_PICK), CB_GETCURSEL, 0, 0 );
+
+ EndDialog(hwnd,id);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hwnd,id);
+ break;
+ }
+ }
+ break;
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/defines.h b/Src/Plugins/Visualization/vis_milk2/defines.h
new file mode 100644
index 00000000..b7283f41
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/defines.h
@@ -0,0 +1,223 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2012 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX8_PLUGIN_SHELL_DEFINES_H__
+#define __NULLSOFT_DX8_PLUGIN_SHELL_DEFINES_H__ 1
+
+// APPNAME should be something like "MyPlugin 1.0".
+// This is the name that will appear in Winamp's list of installed plugins.
+// Try to include the version number with the name.
+// Note: to change the name of the *file* (DLL) that the plugin is
+// compiled to, go to Project Settings -> Link tab -> and change the
+// 'output file name'. Don't forget to do it for both Debug AND
+// Release builds!
+#define SHORTNAME "MilkDrop 2" // used as window caption for both MilkDrop and the config panel. avoid numbers or punctuation; when 'integrate with winamp' option is enabled, these characters don't always work with all skins.
+#define LONGNAME "MilkDrop v2.25d" // appears at bottom of config panel
+#define LONGNAMEW L"MilkDrop v2.25d" // appears at bottom of config panel
+
+// INT_VERSION is the major version #, multipled by 100 (ie. version 1.02
+// would be 102). If the app goes to read in the INI file and sees that
+// the INI file is from an older version of your plugin, it will ignore
+// their old settings and reset them to the defaults for the new version;
+// but that only works if you keep this value up-to-date. ***To disable this
+// behavior, just always leave this at 100. ***
+#define INT_VERSION 200
+// INT_SUBVERSION is the minor version #, counting up from 0 as you do
+// mini-releases. If the plugin goes to read the old INI file and sees that
+// the major version # is the same but the minor version # is not, it will,
+// again, ignore their old settings and reset them to the defaults for the
+// new version. ***To disable this behavior, just always leave this at 0. ***
+#define INT_SUBVERSION 5 //straight=0, a=1, b=2, ...
+
+// SUBDIR puts milkdrop's documentation, INI file, presets folder, etc.
+// in a subdir underneath Winamp\Plugins.
+#define SUBDIR L"Milkdrop2\\" //""
+
+// INIFILE is the name of the .INI file that will save the user's
+// config panel settings. Do not include a path; just give the filename.
+// The actual file will be stored in the WINAMP\PLUGINS directory,
+// OR POSSIBLY c:\application data\...(user)...\winamp\plugins!!! - if
+// they have sep. settings for each user!
+#define INIFILE L"milk2.ini" //*** DO NOT PUT IN A SUBDIR because on save, if dir doesn't already exist,
+ // it won't be able to save the INI file.
+#define MSG_INIFILE L"milk2_msg.ini" //*** could be in c:\program files\winamp\plugins, or in
+#define IMG_INIFILE L"milk2_img.ini" // c:\application data\...user...\winamp\plugins !!
+#define ADAPTERSFILE L"milk2_adapters.txt"
+
+// DOCFILE is the name of the documentation file that you'll write
+// for your users. Do not include a path; just give the filename.
+// When a user clicks the 'View Docs' button on the config panel,
+// the plugin will try to display this file, located in the
+// WINAMP\PLUGINS directory.
+//
+// ***Note that the button will be invisible (on the config panel)
+// at runtime if this string is empty.***
+#define DOCFILE SUBDIR L"docs\\milkdrop.html" // set this to something like "myplugin.html"
+
+// PLUGIN_WEB_URL is the web address of the homepage for your plugin.
+// It should be a well-formed URL (http://...). When a user clicks
+// the 'View Webpage' button on the config panel, the plugin will
+// launch their default browser to display this page.
+//
+// ***Note that the button will be invisible (on the config panel)
+// at runtime if this string is empty.***
+#define PLUGIN_WEB_URL L"http://www.geisswerks.com/milkdrop/" // set this to something like "http://www.myplugin.com/"
+
+// The following two strings - AUTHOR_NAME and COPYRIGHT - will be used
+// in a little box in the config panel, to identify the author & copyright
+// holder of the plugin. Keep them short so they fit in the box.
+#define AUTHOR_NAME L"Ryan Geiss"
+#define COPYRIGHT L"(c) 2001-2023 Winamp SA"
+
+// CLASSNAME is the name of the window class that the plugin will
+// use. You don't want this to overlap with any other plugins
+// or applications that are running, so change this to something
+// that will probably be unique. For example, if your plugin was
+// called Libido, then "LibidoClass" would probably be a safe bet.
+#define CLASSNAME L"MilkDrop2"
+
+// Here you can give names to the buttons (~tabs) along the top
+// of the config panel. Each button, when clicked, will bring
+// up the corresponding 'property page' (embedded dialog),
+// IDD_PROPPAGE_1 through IDD_PROPPAGE_8. If you want less than
+// 8 buttons to show up, just leave their names as blank. For
+// full instructions on how to add a new tab/page, see
+// DOCUMENTATION.TXT.
+//#define CONFIG_PANEL_BUTTON_1 " Common Settings " // nPage==1
+//#define CONFIG_PANEL_BUTTON_2 " MORE SETTINGS " // nPage==2
+//#define CONFIG_PANEL_BUTTON_3 " Artist Tools " // nPage==3
+//#define CONFIG_PANEL_BUTTON_4 " Transitions " // nPage==4
+//#define CONFIG_PANEL_BUTTON_5 "" // nPage==5
+//#define CONFIG_PANEL_BUTTON_6 "" // nPage==6
+//#define CONFIG_PANEL_BUTTON_7 "" // nPage==7
+//#define CONFIG_PANEL_BUTTON_8 "" // nPage==8
+// As if 2.0e, these strings are defined in the stringtable of the dll
+// and otherwise work the same as these header defines.
+// (The equivelent of "" in these is a single space now)
+
+// adjust the defaults for the 4 built-in fonts here.
+// (note: if you want the font to be available on 98 + ME + 2k + XP, use one of the following...)
+// arial
+// courier 10-12-15
+// courier new
+// comic san[s] ms
+// lucida console
+// ms sans serif
+// ms serif
+// small fonts
+// symbol 8-10-12-14-18-24
+// tahoma
+// times new roman
+// verdana
+// webdings
+#define SIMPLE_FONT_DEFAULT_FACE L"Courier" //"MS Sans Serif" - changed to Courier because menus + code FAR more legible!
+#define SIMPLE_FONT_DEFAULT_SIZE 12 //16
+#define SIMPLE_FONT_DEFAULT_BOLD 0
+#define SIMPLE_FONT_DEFAULT_ITAL 0
+#define SIMPLE_FONT_DEFAULT_AA 0
+#define DECORATIVE_FONT_DEFAULT_FACE L"Times New Roman"
+#define DECORATIVE_FONT_DEFAULT_SIZE 24
+#define DECORATIVE_FONT_DEFAULT_BOLD 0
+#define DECORATIVE_FONT_DEFAULT_ITAL 1
+#define DECORATIVE_FONT_DEFAULT_AA 1
+#define HELPSCREEN_FONT_DEFAULT_FACE L"MS Sans Serif"
+#define HELPSCREEN_FONT_DEFAULT_SIZE 14 // NOTE: should fit on 640x480 screen!
+#define HELPSCREEN_FONT_DEFAULT_BOLD 1
+#define HELPSCREEN_FONT_DEFAULT_ITAL 0
+#define HELPSCREEN_FONT_DEFAULT_AA 0
+#define PLAYLIST_FONT_DEFAULT_FACE L"Arial"
+#define PLAYLIST_FONT_DEFAULT_SIZE 16
+#define PLAYLIST_FONT_DEFAULT_BOLD 0
+#define PLAYLIST_FONT_DEFAULT_ITAL 0
+#define PLAYLIST_FONT_DEFAULT_AA 0
+
+// automatically add extra fonts to the config panel
+// by simply #defining them here, UP TO A MAX OF 5 EXTRA FONTS.
+// access the font by calling GetFont(EXTRA_1) for extra font #1,
+// GetExtraFont(EXTRA_2) for extra font #2, and so on.
+#define NUM_EXTRA_FONTS 2 // <- don't exceed 5 here!
+#define TOOLTIP_FONT EXTRA_1
+//#define EXTRA_FONT_1_NAME "Tooltips"
+// defined in the stringtable resources now since 2.0e
+#define EXTRA_FONT_1_DEFAULT_FACE L"Arial"
+#define EXTRA_FONT_1_DEFAULT_SIZE 14
+#define EXTRA_FONT_1_DEFAULT_BOLD 0
+#define EXTRA_FONT_1_DEFAULT_ITAL 0
+#define EXTRA_FONT_1_DEFAULT_AA 0
+#define SONGTITLE_FONT EXTRA_2
+//#define EXTRA_FONT_2_NAME "Animated Songtitles"
+// defined in the stringtable resources now since 2.0e
+#define EXTRA_FONT_2_DEFAULT_FACE L"Times New Roman"
+#define EXTRA_FONT_2_DEFAULT_SIZE 18
+#define EXTRA_FONT_2_DEFAULT_BOLD 0
+#define EXTRA_FONT_2_DEFAULT_ITAL 1
+#define EXTRA_FONT_2_DEFAULT_AA 1
+
+#define WINDOWCAPTION SHORTNAME // the caption that will appear on the plugin window
+#define DLLDESC LONGNAME // the desc. of this DLL, as it appears in Winamp's list of viz plugins
+#define MODULEDESC LONGNAME // the desc. of this viz module within the DLL (..this framework is set up for just 1 module per DLL)
+
+// Finally, a few parameters that will control how things are done
+// inside the plugin shell:
+#define NUM_WAVEFORM_SAMPLES 480 // RANGE: 32-576. This is the # of samples of waveform data that you want.
+ // Note that if it is less than 576, then VMS will do its best
+ // to line up the waveforms from frame to frame for you, using
+ // the extra samples as 'squish' space.
+ // Note: the more 'slush' samples you leave, the better the alignment
+ // will be. 512 samples gives you decent alignment; 400 samples
+ // leaves room for fantastic alignment.
+ // Observe that if you specify a value here (say 400) and then only
+ // render a sub-portion of that in some cases (say, 200 samples),
+ // make sure you render the *middle* 200 samples (#100-300), because
+ // the alignment happens *mostly at the center*.
+#define NUM_FREQUENCIES 512 // # of freq. samples you want *out* of the FFT, for 0-11kHz range.
+ // ** this must be a power of 2!
+ // ** the actual FFT will use twice this many frequencies **
+
+#define TEXT_MARGIN 10 // the # of pixels of margin to leave between text and the edge of the screen
+#define PLAYLIST_INNER_MARGIN 4 // the extra margin between the playlist box and the text inside
+
+#define PLAYLIST_COLOR_PLAYING_TRACK 0xFFCCFF00 // alpha|red|green|blue
+#define PLAYLIST_COLOR_HILITE_TRACK 0xFFFF5050
+#define PLAYLIST_COLOR_BOTH 0xFFFFCC22
+#define PLAYLIST_COLOR_NORMAL 0xFFCCCCCC
+
+#define MENU_COLOR 0xFFCCCCCC
+#define MENU_HILITE_COLOR 0xFFFF4400
+#define DIR_COLOR 0xFF88CCFF
+#define TOOLTIP_COLOR 0xFFBBBBCC
+
+#define MAX_PRESETS_PER_PAGE 32
+
+//#define PRESS_F1_MSG "Press F1 for Help " // leave extra space @ end, so italicized fonts don't get clipped
+// defined in the stringtable resources now since 2.0e
+#define PRESS_F1_DUR 3.0f // in seconds
+#define PRESS_F1_EXP 10.0f // exponent for how quickly it accelerates to leave the screen. 1 = linear; >1 = stays & then dashes off @ end
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/desktop_mode.cpp b/Src/Plugins/Visualization/vis_milk2/desktop_mode.cpp
new file mode 100644
index 00000000..6b66f3c5
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/desktop_mode.cpp
@@ -0,0 +1,1097 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "pluginshell.h"
+#include "resource.h"
+#include "utility.h"
+#include "defines.h"
+#include <shellapi.h>
+
+//----------------------------------------------------------------------
+
+#define VMS_DESKTOP_DLLNAME (SUBDIR L"data\\vms_desktop.dll")
+
+//----------------------------------------------------------------------
+
+typedef struct _SIMPLEVERTEX
+{
+ float x, y; // screen position
+ float z; // Z-buffer depth
+ DWORD Diffuse; // diffuse color. also acts as filler; aligns struct to 16 bytes (good for random access/indexed prims)
+} SIMPLEVERTEX, *LPSIMPLEVERTEX;
+
+typedef struct _HELPVERTEX
+{
+ float x, y; // screen position
+ float z; // Z-buffer depth
+ DWORD Diffuse; // diffuse color. also acts as filler; aligns struct to 16 bytes (good for random access/indexed prims)
+ float tu, tv; // texture coordinates for texture #0
+} HELPVERTEX, *LPHELPVERTEX;
+
+#define SIMPLE_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE)
+#define HELP_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
+
+//----------------------------------------------------------------------
+
+// resides in vms_desktop.dll/lib:
+int setHook(HWND hlv,HWND w,int version);
+void removeHook();
+
+//----------------------------------------------------------------------
+
+typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+bool IsVistaOrLater()
+{
+ // adapted from "Getting the System Version" on MSDN - http://msdn2.microsoft.com/en-us/library/ms724429.aspx
+ OSVERSIONINFOEX osvi;
+ SYSTEM_INFO si;
+ PGNSI pGNSI;
+ BOOL bOsVersionInfoEx;
+
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ if (bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi))
+ {
+ // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+ pGNSI = (PGNSI) GetProcAddress( GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo" );
+ if(NULL != pGNSI)
+ pGNSI(&si);
+ else
+ GetSystemInfo(&si);
+
+ if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4 )
+ {
+ if ( osvi.dwMajorVersion >= 6 )
+ return true;
+ }
+ }
+ return false;
+}
+
+int CPluginShell::InitDesktopMode()
+{
+ if (m_screenmode != DESKTOP)
+ return false;
+
+ // check for Vista - if Vista, don't try to draw desktop icons.
+ // [ vms_desktop.dll's message posts to the desktop listview window cause explorer to crash...
+ // whether it sends WM_NULL or WM_USER+516/517. ]
+ if (m_desktop_show_icons && IsVistaOrLater())
+ m_desktop_show_icons = false;
+
+ if (!m_desktop_show_icons)
+ return true;
+
+ // note: we have to explicitly make sure the DLL is present,
+ // since we're delay-loading it; otherwise, calling setHook, etc. will crash it.
+ wchar_t szVmsDesktopDll[MAX_PATH];
+ swprintf(szVmsDesktopDll, L"%s%s", GetPluginsDirPath(), VMS_DESKTOP_DLLNAME);
+ if (!GetModuleHandleW(szVmsDesktopDll))
+ {
+ if (!LoadLibraryW(szVmsDesktopDll))
+ {
+ wchar_t buf[2048];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_COULD_NOT_FIND_FILE_FOR_DESKTOP_MODE_X), szVmsDesktopDll);
+ MessageBoxW(GetPluginWindow(),buf,WASABI_API_LNGSTRINGW(IDS_MILKDROP_ERROR_FILE_MISSING), MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ //return false;
+ m_desktop_icons_disabled = 1;
+ }
+ else
+ {
+ m_vms_desktop_loaded = 1;
+ }
+ }
+
+ InitializeCriticalSection(&m_desktop_cs);
+
+ m_desktop_icon_state = 0;
+ m_desktop_icon_count = 0;
+ m_desktop_icon_update_frame = 0;
+ m_desktop_icon_size = GetDesktopIconSize();
+
+ // GDI font for desktop mode:
+ LOGFONT lf = {0};
+ wchar_t title[64];
+ if (SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
+ {
+ if (!(m_font_desktop = CreateFontIndirect(&lf)))
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_GDI_DESKTOP_FONT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+ }
+ else
+ {
+ if (!(m_font_desktop = CreateFont(14, 0, 0, 0, 0, 0, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, "Monotype Sans Serif")))
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_GDI_DESKTOP_FONT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+ }
+
+ // Create D3DX font for drawing icon labels on desktop:
+ if (pCreateFontW(m_lpDX->m_lpDevice, 14, 0, 0, 0, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH, L"Monotype Sans Serif", &m_d3dx_desktop_font) != D3D_OK)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_DESKTOP_FONT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ // create first texture for holding icon bitmaps:
+ // (do it now, to ensure that at least 1 gets created, before
+ // the plugin does all of its DX9 allocations.)
+ if (!CreateDesktopIconTexture(&m_desktop_icons_texture[0]))
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_TEXTURE_FOR_ICON_BITMAPS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ }
+
+ if (!m_desktop_icons_disabled)
+ {
+ int ret = setHook(m_hWndDesktopListView, GetPluginWindow(), 1);
+ if (ret == 1)
+ m_desktop_hook_set = 1;
+ else if (ret == -1)
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_OUTDATED_VMS_DESKTOP_DLL_NEED_TO_REINSTALL),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ else
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_HOOK_PROC_DESKTOP_ICONS_NOT_AVAILABLE),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+
+void CPluginShell::CleanUpDesktopMode()
+{
+ if (m_screenmode != DESKTOP)
+ return;
+ if (!m_desktop_show_icons)
+ return;
+
+ if (m_desktop_hook_set)
+ {
+ m_desktop_hook_set = 0;
+ removeHook();
+ }
+
+ for (int i=0; i<MAX_ICON_TEXTURES; i++)
+ SafeRelease(m_desktop_icons_texture[i]);
+ SafeRelease(m_d3dx_desktop_font);
+
+ if (m_desktop_wc_registered)
+ {
+ UnregisterClass(DESKTOP_MODE_KEYBOARD_INPUT_WINDOW_CLASSNAME, m_hInstance);
+ m_desktop_wc_registered = 0;
+ }
+
+ if (m_font_desktop)
+ {
+ DeleteObject(m_font_desktop);
+ m_font_desktop = 0;
+ }
+
+ m_icon_list.clear();
+
+ DeleteCriticalSection(&m_desktop_cs);
+
+ if (m_vms_desktop_loaded)
+ {
+ char szVmsDesktopDll[MAX_PATH];
+ sprintf(szVmsDesktopDll, "%s%s", GetPluginsDirPath(), VMS_DESKTOP_DLLNAME);
+ FreeLibrary(GetModuleHandle(szVmsDesktopDll));
+ m_vms_desktop_loaded = 0;
+ }
+}
+
+//----------------------------------------------------------------------
+
+int CPluginShell::CreateDesktopIconTexture(IDirect3DTexture9** ppTex)
+{
+ // release old texture (shouldn't really be necessary)
+ if (*ppTex)
+ {
+ (*ppTex)->Release();
+ *ppTex = NULL;
+ }
+
+ // create new
+ int ntries = (m_lpDX->m_d3dpp.BackBufferFormat == D3DFMT_R5G6B5) ? 3 : 1;
+ for (int ntry=0; ntry<ntries; ntry++)
+ {
+ D3DFORMAT fmt = m_lpDX->m_d3dpp.BackBufferFormat;
+ switch(m_lpDX->m_d3dpp.BackBufferFormat)
+ {
+ case D3DFMT_R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ fmt = D3DFMT_A8R8G8B8;
+ break;
+ case D3DFMT_R5G6B5: // <- PROBLEM: NO ALPHA CHANNEL FOR ICONS
+ if (ntry==0)
+ switch(m_desktop_555_fix)
+ {
+ case 0: fmt = D3DFMT_R5G6B5; break;
+ case 1: fmt = D3DFMT_A1R5G5B5; break;
+ case 2: fmt = D3DFMT_A8R8G8B8; break;
+ }
+ else if (ntry==1)
+ switch(m_desktop_555_fix)
+ {
+ case 0: fmt = D3DFMT_A1R5G5B5; break;
+ case 1: fmt = D3DFMT_A8R8G8B8; break;
+ case 2: fmt = D3DFMT_A1R5G5B5; break;
+ }
+ else
+ switch(m_desktop_555_fix)
+ {
+ case 0: fmt = D3DFMT_A8R8G8B8; break;
+ case 1: fmt = D3DFMT_R5G6B5; break;
+ case 2: fmt = D3DFMT_R5G6B5; break;
+ }
+ break;
+ case D3DFMT_X1R5G5B5:
+ fmt = D3DFMT_A1R5G5B5;
+ break;
+ }
+
+ if (m_lpDX->m_lpDevice->CreateTexture(ICON_TEXTURE_SIZE, ICON_TEXTURE_SIZE, 1, 0, fmt, D3DPOOL_MANAGED, ppTex, NULL) != D3D_OK)
+ *ppTex = NULL;
+ else
+ break;
+ }
+
+ return (*ppTex) ? 1 : 0;
+}
+
+//----------------------------------------------------------------------
+
+void CPluginShell::DeselectDesktop()
+{
+ IconList::iterator p;
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ p->selected = 0;
+}
+
+//----------------------------------------------------------------------
+
+void CPluginShell::UpdateDesktopBitmaps()
+{
+ // update the D3DX textures that hold all the icons:
+
+ int idx = 0;
+ int texnum = 0;
+ int show_msgs = 1;
+
+ // if no icon texture could be created at startup,
+ // don't bother trying anything here, and don't give them
+ // any extra error messages.
+ if (!m_desktop_icons_texture[0])
+ return;
+
+ IconList::iterator p;
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ p->icon_bitmap_idx = -1;
+
+ do
+ {
+ idx = StuffIconBitmaps(idx, texnum++, &show_msgs);
+ }
+ while (idx > 0 && texnum < MAX_ICON_TEXTURES);
+
+ if (idx > 0)
+ {
+ wchar_t title[64];
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_WARNING, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ }
+}
+
+//----------------------------------------------------------------------
+
+int CPluginShell::StuffIconBitmaps(int iStartIconIdx, int iTexNum, int *show_msgs)
+{
+ // returns:
+ // 0 if done (or error), or
+ // N if the texture is full & we need to start another one,
+ // where N is the new iStartIconIdx to use.
+
+ if (m_screenmode != DESKTOP)
+ return 0;
+
+ wchar_t title[64];
+ if (!m_desktop_icons_texture[iTexNum])
+ {
+ int ret = CreateDesktopIconTexture(&m_desktop_icons_texture[iTexNum]);
+ if (!ret)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_TOO_MANY_UNIQUE_ICON_BITMAPS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_WARNING, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return 0;
+ }
+ }
+
+ D3DSURFACE_DESC sd;
+ if (m_desktop_icons_texture[iTexNum]->GetLevelDesc(0, &sd) != D3D_OK)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_COULD_NOT_GET_LEVEL_DESCRIPTION),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return 0;
+ }
+
+ D3DLOCKED_RECT lr;
+ if (m_desktop_icons_texture[iTexNum]->LockRect(0, &lr, NULL, 0) != D3D_OK)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_LOCKRECT_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return 0;
+ }
+ if (lr.pBits == NULL)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_LR_PBITS_IS_NULL),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ m_desktop_icons_texture[iTexNum]->UnlockRect(0);
+ return 0;
+ }
+
+ unsigned __int16* p16 = (unsigned __int16*)lr.pBits;
+ unsigned __int32* p32 = (unsigned __int32*)lr.pBits;
+ int WIDTH = sd.Width;
+
+ int i;
+
+ int start;
+ int bpp;
+ int rshift[3]; // 1. bits to first shift right r,g,b
+ int mask[3]; // 2. mask for r, g, b
+ int lshift[3]; // 3. bits to then shift left r,g,b
+
+ switch(sd.Format)
+ {
+ case D3DFMT_R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ start = 0xFF000000;
+ bpp = 32;
+ rshift[0] = 0;
+ rshift[1] = 0;
+ rshift[2] = 0;
+ mask[0] = 0xFF;
+ mask[1] = 0xFF;
+ mask[2] = 0xFF;
+ lshift[0] = 16;
+ lshift[1] = 8;
+ lshift[2] = 0;
+ break;
+
+ case D3DFMT_R5G6B5:
+ start = 0x0000;
+ bpp = 16;
+ rshift[0] = 3;
+ rshift[1] = 2;
+ rshift[2] = 3;
+ mask[0] = 0x1F;
+ mask[1] = 0x3F;
+ mask[2] = 0x1F;
+ lshift[0] = 11;
+ lshift[1] = 5;
+ lshift[2] = 0;
+ break;
+
+ case D3DFMT_X1R5G5B5:
+ case D3DFMT_A1R5G5B5:
+ start = 0x8000;
+ bpp = 16;
+ rshift[0] = 3;
+ rshift[1] = 3;
+ rshift[2] = 3;
+ mask[0] = 0x1F;
+ mask[1] = 0x1F;
+ mask[2] = 0x1F;
+ lshift[0] = 10;
+ lshift[1] = 5;
+ lshift[2] = 0;
+ break;
+
+ case D3DFMT_A4R4G4B4:
+ start = 0xF000;
+ bpp = 16;
+ rshift[0] = 4;
+ rshift[1] = 4;
+ rshift[2] = 4;
+ mask[0] = 0x0F;
+ mask[1] = 0x0F;
+ mask[2] = 0x0F;
+ lshift[0] = 8;
+ lshift[1] = 4;
+ lshift[2] = 0;
+ break;
+
+ default:
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_UNKNOWN_PIXEL_FORMAT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ m_desktop_icons_texture[iTexNum]->UnlockRect(0);
+ return 0;
+ }
+
+ HDC hdc = GetDC(NULL);
+ if (!hdc)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_COULDNT_GET_HDC),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ m_desktop_icons_texture[iTexNum]->UnlockRect(0);
+ return 0;
+ }
+
+ #define MAX_ICON_SIZE 128
+ unsigned char data[MAX_ICON_SIZE*MAX_ICON_SIZE*4];
+
+ int nAcross = ICON_TEXTURE_SIZE/m_desktop_icon_size;
+ int nDown = ICON_TEXTURE_SIZE/m_desktop_icon_size;
+
+ // for each icon, add its bitmap to the texture (if not already there),
+ // and set 'icon_bitmap_idx'.
+ IconList::iterator p = m_icon_list.begin();
+ for (i=0; i < iStartIconIdx; i++)
+ p++;
+
+ int bitmap_idx = 0;
+ int list_idx = iStartIconIdx;
+
+ for ( ; p != m_icon_list.end() && bitmap_idx < nAcross*nDown; p++)
+ {
+ // note: 'p' points to the correct icon to start with,
+ // but 'idx' starts at zero!
+
+ // get the icon:
+ SHFILEINFO sfi;
+ int flags = SHGFI_ICON|SHGFI_PIDL|SHGFI_SHELLICONSIZE | ((m_desktop_icon_size > 32) ? SHGFI_LARGEICON : 0);
+ if (SHGetFileInfo((LPCTSTR)p->pidl, 0, &sfi, sizeof(sfi), flags))
+ {
+ ICONINFO ii;
+ if (GetIconInfo(sfi.hIcon, &ii))
+ {
+ int x0 = (bitmap_idx%nAcross)*m_desktop_icon_size;
+ int y0 = (bitmap_idx/nAcross)*m_desktop_icon_size;
+ int checksum[3] = { 0, 0, 0 };
+
+ BITMAPINFO bmi;
+
+ // pass 1: get the colors
+
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = m_desktop_icon_size;
+ bmi.bmiHeader.biHeight = m_desktop_icon_size;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ if (GetDIBits(
+ hdc, // handle to DC
+ ii.hbmColor, // handle to bitmap
+ 0, // first scan line to set
+ m_desktop_icon_size,// number of scan lines to copy
+ data, // array for bitmap bits
+ &bmi, // bitmap data buffer
+ DIB_RGB_COLORS // RGB or palette index
+ ))
+ {
+ int w = min(bmi.bmiHeader.biWidth , m_desktop_icon_size);
+ int h = min(bmi.bmiHeader.biHeight, m_desktop_icon_size);
+
+ for (int y=0; y<h; y++)
+ for (int x=0; x<w; x++)
+ {
+ int in_offset = ((h-1-y)*w + x)*4;
+ int r = data[in_offset+2];
+ int g = data[in_offset+1];
+ int b = data[in_offset+0];
+
+ checksum[0] += r;
+ checksum[1] += g;
+ checksum[2] += b;
+
+ int out_offset = (y0+y)*WIDTH + (x0+x);
+ if (bpp==16)
+ p16[out_offset] = start |
+ (((r >> rshift[0]) & mask[0]) << lshift[0]) |
+ (((g >> rshift[1]) & mask[1]) << lshift[1]) |
+ (((b >> rshift[2]) & mask[2]) << lshift[2]);
+ else
+ p32[out_offset] = start |
+ (((r >> rshift[0]) & mask[0]) << lshift[0]) |
+ (((g >> rshift[1]) & mask[1]) << lshift[1]) |
+ (((b >> rshift[2]) & mask[2]) << lshift[2]);
+ }
+ }
+ else
+ {
+ if (*show_msgs)
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_CALL_TO_GETDIBITS_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ *show_msgs = 0;
+ }
+
+ // pass 2: get the alpha mask
+
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = m_desktop_icon_size;
+ bmi.bmiHeader.biHeight = m_desktop_icon_size;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ if (GetDIBits(
+ hdc, // handle to DC
+ ii.hbmMask, // handle to bitmap
+ 0, // first scan line to set
+ m_desktop_icon_size,// number of scan lines to copy
+ data, // array for bitmap bits
+ &bmi, // bitmap data buffer
+ DIB_RGB_COLORS // RGB or palette index
+ ))
+ {
+ int w = min(bmi.bmiHeader.biWidth , m_desktop_icon_size);
+ int h = min(bmi.bmiHeader.biHeight, m_desktop_icon_size);
+
+ for (int y=0; y<h; y++)
+ for (int x=0; x<w; x++)
+ {
+ int in_offset = ((h-1-y)*w + x)*4;
+ int r = data[in_offset+2];
+ int g = data[in_offset+1];
+ int b = data[in_offset+0];
+
+ checksum[0] += r;
+ checksum[1] += g;
+ checksum[2] += b;
+
+ if (r || g || b)
+ {
+ int out_offset = (y0+y)*WIDTH + (x0+x);
+ if (bpp==16)
+ p16[out_offset] &= ~start;
+ else
+ p32[out_offset] &= ~start;
+ }
+ }
+ }
+ else
+ {
+ if (*show_msgs)
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_CALL_2_TO_GETDIBITS_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ *show_msgs = 0;
+ }
+
+ // check for duplicate icon, and if found, reuse it
+ int done = 0;
+ IconList::iterator q;
+ for (q = m_icon_list.begin(); q != m_icon_list.end() && q != p; q++)
+ {
+ if (checksum[0] == q->checksum[0] &&
+ checksum[1] == q->checksum[1] &&
+ checksum[2] == q->checksum[2])
+ {
+ p->icon_bitmap_idx = q->icon_bitmap_idx;
+ done = 1;
+ break;
+ }
+ }
+
+ // otherwise, keep new icon
+ if (!done)
+ {
+ p->icon_bitmap_idx = nAcross*nDown*iTexNum + bitmap_idx;
+ p->checksum[0] = checksum[0];
+ p->checksum[1] = checksum[1];
+ p->checksum[2] = checksum[2];
+
+ bitmap_idx++;
+ }
+
+ DeleteObject(ii.hbmMask);
+ DeleteObject(ii.hbmColor);
+ }
+ else
+ {
+ if (*show_msgs)
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_GETICONINFO_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ *show_msgs = 0;
+ }
+
+ DestroyIcon(sfi.hIcon);
+ }
+ else
+ {
+ if (*show_msgs)
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_UPDATING_ICON_BITMAPS_SHGETFILEINFO_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ *show_msgs = 0;
+ }
+
+ list_idx++;
+ }
+
+ ReleaseDC(NULL, hdc);
+ m_desktop_icons_texture[iTexNum]->UnlockRect(0);
+
+ if (bitmap_idx >= nAcross*nDown)
+ return list_idx;
+ else
+ return 0; // all done
+}
+
+//----------------------------------------------------------------------
+
+void CPluginShell::RenderDesktop()
+{
+ if (m_screenmode != DESKTOP)
+ return;
+ if (!m_desktop_show_icons)
+ return;
+ if (m_desktop_icons_disabled)
+ return;
+
+ IconList::iterator p;
+
+ EnterCriticalSection(&m_desktop_cs);
+
+ int iconcount = static_cast<unsigned long>(SendMessage(m_hWndDesktopListView, LVM_GETITEMCOUNT, 0, 0));
+ if (iconcount == 0)
+ {
+ LeaveCriticalSection(&m_desktop_cs);
+ return;
+ }
+
+ // if the icons list is empty,
+ // or if we check it for consistency and an update is recommended (GetDesktopIcons(1)==2),
+ // update the icons list & the bitmaps:
+ /*if (m_icon_list.size()==0 || GetDesktopIcons(1)==2)
+ {
+ m_icon_list.clear();
+ GetDesktopIcons(0);
+
+ UpdateDesktopBitmaps();
+ }*/
+
+ // check for invalid entries. (if there is an error in getItemData(),
+ // it will return the icon_t structure anyway, but with empty strings.)
+ int invalid_entries = 0;
+ if (m_desktop_icon_state >= 2)
+ {
+ for (p = m_icon_list.begin(); p != m_icon_list.end() && !invalid_entries; p++)
+ {
+ if (p->name[0]==0)
+ invalid_entries = 1;
+ //if (p->pidl[0].mkid.cb==0 && p->pidl[0].mkid.abID[0]==0)
+ if (p->pidl[0]==0 && p->pidl[1]==0)
+ invalid_entries = 1;
+ }
+ }
+
+ if (
+ (m_desktop_icon_state == 0) ||
+ (m_desktop_icon_state >= 2 && m_desktop_icon_count != iconcount) ||
+ (m_desktop_icon_state >= 2 && invalid_entries)
+ )
+ {
+ // begin total refresh
+ m_desktop_icon_state = 1;
+ m_desktop_icon_count = iconcount;
+ m_desktop_icon_update_frame = GetFrame();
+ m_icon_list.clear();
+
+ SendMessage(GetPluginWindow(), WM_USER, 0x80000000 | iconcount, 0);//getItemData(i);
+
+ // try to get the desktop window's listview to respond to
+ // the queries as quickly as possible:
+ {
+ LeaveCriticalSection(&m_desktop_cs);
+
+ DWORD procid = NULL;
+ DWORD threadid = GetWindowThreadProcessId(m_hWndDesktopListView, &procid);
+
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION, FALSE, procid);
+ DWORD x = GetPriorityClass(hProcess);
+ if (x) SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS);
+
+ for (int i=0; i<5; i++)
+ {
+ Sleep(10);
+
+ MSG msg;
+ while(PeekMessage(&msg,GetPluginWindow(),0,0,PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ if (x) SetPriorityClass(hProcess, x);
+ CloseHandle(hProcess);
+
+ EnterCriticalSection(&m_desktop_cs);
+ }
+ }
+ else if (m_desktop_icon_state == 1 &&
+ m_icon_list.size() < (size_t)m_desktop_icon_count)
+ {
+ // waiting for the 'total refresh' to complete
+ // ...
+ if (GetFrame() > m_desktop_icon_update_frame+64)
+ {
+ m_desktop_icon_state = 0;
+ }
+ }
+ else
+ if (m_desktop_icon_state == 1 &&
+ m_icon_list.size() == m_desktop_icon_count)
+ {
+ // done with total refresh
+ m_desktop_icon_state = 2;
+ m_desktop_icon_update_frame = GetFrame();
+ UpdateDesktopBitmaps();
+ }
+ else if (m_desktop_icon_state == 2)
+ {
+ if (GetFrame() > m_desktop_icon_update_frame+4)
+ {
+ m_desktop_icon_state = 3; // will mean we're waiting on data to return.
+ m_desktop_icon_update_frame = GetFrame();
+ int start = 0;
+ int len = iconcount;
+ SendMessage(GetPluginWindow(), WM_USER, start | (len << 16), 0);//getItemData(i);
+ }
+ }
+ else if (m_desktop_icon_state == 3)
+ {
+ if (GetFrame() > m_desktop_icon_update_frame+64)
+ {
+ // timeout; give up waiting for update message to come back,
+ // and just request another.
+ m_desktop_icon_state = 2;
+ m_desktop_icon_update_frame = GetFrame();
+ }
+ }
+
+ // get horz. spacing between icons (...determines width of labels)
+ ICONMETRICS icm;
+ icm.cbSize = sizeof(icm);
+ if (!SystemParametersInfo(SPI_GETICONMETRICS, sizeof(icm), &icm, 0))
+ icm.iHorzSpacing = 68;
+
+ /*int font_height = 0;
+ {
+ RECT r;
+ m_d3dx_desktop_font->DrawText(NULL, "M", -1, &r, DT_CALCRECT, 0xFFFFFFFF);
+ font_height = r.bottom - r.top;
+ }*/
+
+ // display the desktop.
+
+ m_lpDX->m_lpDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
+ m_lpDX->m_lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);//D3DTOP_SELECTARG1 );
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
+ m_lpDX->m_lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ int nAcross = ICON_TEXTURE_SIZE/m_desktop_icon_size;
+ int nDown = ICON_TEXTURE_SIZE/m_desktop_icon_size;
+
+ // The icon's x and y coordinates (as returned by the
+ // getIconData/WM_COPYDATA system) are (0,0) at the
+ // upper-left corner of the rectangle that encompasses
+ // all the monitors together (m_lpDX->m_all_monitors_rect).
+
+ // Note that in 'm_all_monitors_rect', (0,0) represents
+ // the upper-left corner of the PRIMARY DISPLAY - not necessarily
+ // the one we're showing the fake desktop on.
+
+ // What we have to do here is determine icon_dx and icon_dy,
+ // which are the transformation from the coordinate space used
+ // by the desktop itself (as returned in WM_COPYDATA)
+ // and the coordinates used by Windows itself (where 0,0 is
+ // the upper-left corner of the PRIMARY DISPLAY, and coordinates
+ // in other displays can be negative if they are above/left of it).
+
+ int upperleft_x = min(m_lpDX->m_all_monitors_rect.left, m_lpDX->m_monitor_rect.left);
+ int upperleft_y = min(m_lpDX->m_all_monitors_rect.top , m_lpDX->m_monitor_rect.top );
+ int icon_dx = m_lpDX->m_monitor_rect.left - upperleft_x; // subtract this amount
+ int icon_dy = m_lpDX->m_monitor_rect.top - upperleft_y; // subtract this amount
+
+ if (!m_desktop_manual_icon_scoot)
+ {
+ icon_dx -= m_lpDX->m_monitor_rect.left - m_lpDX->m_monitor_work_rect.left;
+ icon_dy -= m_lpDX->m_monitor_rect.top - m_lpDX->m_monitor_work_rect.top ;
+ }
+
+ // pass 0: draw normal text & icons
+ // pass 1: redraw icon currently being dragged, transparently
+ int nPasses = m_desktop_dragging ? 2 : 1;
+ for (int pass=0; pass<nPasses; pass++)
+ {
+ // first, draw [blue backgrounds &] text labels
+ {
+ m_lpDX->m_lpDevice->SetVertexShader( NULL );
+ m_lpDX->m_lpDevice->SetFVF( SIMPLE_VERTEX_FORMAT );
+ m_lpDX->m_lpDevice->SetTexture(0, NULL);
+ SIMPLEVERTEX verts[4];
+
+ // pass2==0: draw text labels
+ // pass2==1: draw text overtop
+ // (separated for speed, so ID3DXFont can get the HDC just once for all the DrawText calls)
+ for (int pass2=0; pass2<2; pass2++)
+ {
+ //if (pass2==1)
+ //m_d3dx_desktop_font->Begin();
+
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ {
+ if (pass==0 || (p->selected && m_desktop_dragging))
+ {
+ int max_width = icm.iHorzSpacing-5+m_desktop_icon_size-32;//icm.iHorzSpacing-5;
+
+ int dx = 0;
+ int dy = 4;
+
+ if (pass>0)
+ {
+ dx += m_desktop_drag_curpos.x - m_desktop_drag_startpos.x;
+ dy += m_desktop_drag_curpos.y - m_desktop_drag_startpos.y;
+ }
+
+ SetRect(&p->label_rect,
+ p->x + m_desktop_icon_size/2 - icon_dx - max_width/2 + dx,
+ p->y + m_desktop_icon_size - icon_dy + dy,
+ p->x + m_desktop_icon_size/2 - icon_dx + max_width/2 + dx,
+ p->y + m_desktop_icon_size - icon_dy + 0 + dy // will be extended by DT_CALCRECT step!
+ );
+
+ // calculate rect for the text label
+ DWORD style = DT_CENTER|DT_WORDBREAK|DT_END_ELLIPSIS|DT_WORD_ELLIPSIS;
+ // these aren't supported by D3DX9:
+ style &= ~(DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX);
+ m_d3dx_desktop_font->DrawText(NULL, p->name, -1, &p->label_rect, style|DT_CALCRECT, 0xFFFFFFFF);
+
+ // D3DX doesn't handle text so well if it goes off
+ // the left edge of the screen, so don't show text labels
+ // that are mostly off (on the left side):
+ if ((p->label_rect.left + p->label_rect.right)/2 > 0)
+ {
+ // also, if label would go off left edge of screen,
+ // push it to the right:
+ if (p->label_rect.left < 0 && p->label_rect.right > 0)
+ {
+ p->label_rect.right -= p->label_rect.left;
+ p->label_rect.left = 0;
+ }
+
+ //if (p->selected) // ...draw blue background around text label
+ if (pass2==0)
+ {
+ if (m_desktop_textlabel_boxes || p->selected)
+ {
+ #define EXTEND_LEFT 3
+ #define EXTEND_RIGHT 2
+ #define EXTEND_TOP 0
+ #define EXTEND_BOTTOM 2
+ for (int i=0; i<4; i++)
+ {
+ verts[i].x = (i%2==0) ? (float)(-m_lpDX->m_client_width/2 + p->label_rect.left - EXTEND_LEFT) : (float)(-m_lpDX->m_client_width/2 + p->label_rect.right + EXTEND_RIGHT); // was -2/+3
+ verts[i].y = (i/2==0) ? (float)(m_lpDX->m_client_height/2 - p->label_rect.top + EXTEND_TOP ) : (float)(m_lpDX->m_client_height/2 - p->label_rect.bottom - EXTEND_BOTTOM); // was +1/-1
+ verts[i].z = 0;
+ verts[i].Diffuse = (p->selected) ? m_desktop_sel_color : m_desktop_bk_color;//0xFF000000;
+ if (pass>0)
+ verts[i].Diffuse &= 0x7FFFFFFF;
+ }
+ m_lpDX->m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(SIMPLEVERTEX));
+ }
+ }
+ else
+ {
+ DWORD text_color = (p->selected) ? m_desktop_sel_text_color : m_desktop_text_color;
+ if (pass==1)
+ text_color &= 0x7FFFFFFF;
+ // these aren't supported by D3DX9:
+ style &= ~(DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX);
+ m_d3dx_desktop_font->DrawText(NULL, p->name, -1, &p->label_rect, style, text_color);
+ }
+ }
+ }
+ }
+
+ //if (pass2==1)
+ // m_d3dx_desktop_font->End();
+ }
+ }
+
+ m_lpDX->m_lpDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
+ m_lpDX->m_lpDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
+ m_lpDX->m_lpDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
+
+ // second, draw icon bitmaps (overtop)
+ if (m_desktop_icon_state >= 2)
+ {
+ int dx = 0;
+ int dy = 0;
+ int iTexNum = 0;
+
+ while (m_desktop_icons_texture[iTexNum] && iTexNum < MAX_ICON_TEXTURES)
+ {
+ HELPVERTEX verts[4];
+ m_lpDX->m_lpDevice->SetVertexShader( NULL );
+ m_lpDX->m_lpDevice->SetFVF( HELP_VERTEX_FORMAT );
+ m_lpDX->m_lpDevice->SetTexture(0, m_desktop_icons_texture[iTexNum]);
+
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ {
+ int icon_tex_idx = (p->icon_bitmap_idx==-1) ? 0 : (p->icon_bitmap_idx / (nAcross*nDown));
+ int icon_bitmap_idx = (p->icon_bitmap_idx==-1) ? 0 : (p->icon_bitmap_idx % (nAcross*nDown));
+ if (
+ (icon_tex_idx == iTexNum) &&
+ (pass==0 || (p->selected && m_desktop_dragging))
+ )
+ {
+ SetRect(&p->icon_rect,
+ p->x - icon_dx + dx,
+ p->y - icon_dy + dy,
+ p->x - icon_dx + dx + m_desktop_icon_size,
+ p->y - icon_dy + dy + m_desktop_icon_size);
+
+ int lookup_x = 0;
+ int lookup_y = 0;
+
+ if (icon_bitmap_idx >= 0) // if -1, means icon didn't fit in the texture
+ {
+ lookup_x = icon_bitmap_idx % nAcross;
+ lookup_y = icon_bitmap_idx / nAcross;
+ }
+
+ for (int i=0; i<4; i++)
+ {
+ verts[i].x = (i%2==0) ? (float)(-m_lpDX->m_client_width/2 + p->icon_rect.left) : (float)(-m_lpDX->m_client_width/2 + p->icon_rect.right );
+ verts[i].y = (i/2==0) ? (float)(m_lpDX->m_client_height/2 - p->icon_rect.top ) : (float)(m_lpDX->m_client_height/2 - p->icon_rect.bottom);
+ verts[i].z = 0;
+ verts[i].tu = ((lookup_x + i%2)*m_desktop_icon_size + 0.5f)/(float)ICON_TEXTURE_SIZE;
+ verts[i].tv = ((lookup_y + i/2)*m_desktop_icon_size + 0.5f)/(float)ICON_TEXTURE_SIZE;
+ verts[i].Diffuse = (p->selected) ? m_desktop_sel_color : 0xFFFFFFFF;
+ if (pass>0)
+ {
+ verts[i].x += m_desktop_drag_curpos.x - m_desktop_drag_startpos.x;
+ verts[i].y -= m_desktop_drag_curpos.y - m_desktop_drag_startpos.y;
+ verts[i].Diffuse &= 0x7FFFFFFF;
+ }
+ }
+
+ m_lpDX->m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(HELPVERTEX));
+ }
+ }
+
+ iTexNum++;
+ }
+ }
+ }
+
+ // finally, draw selection box (if user is dragging one)
+ if (m_desktop_box)
+ {
+ m_lpDX->m_lpDevice->SetVertexShader( NULL );
+ m_lpDX->m_lpDevice->SetFVF( SIMPLE_VERTEX_FORMAT );
+ m_lpDX->m_lpDevice->SetTexture(0, NULL);
+ SIMPLEVERTEX verts[5];
+ for (int i=0; i<4; i++)
+ {
+ verts[i].x = (i==1||i==2) ? (float)(-m_lpDX->m_client_width/2 + m_desktop_drag_startpos.x) : (float)(-m_lpDX->m_client_width/2 + m_desktop_drag_curpos.x);
+ verts[i].y = (i==0||i==1) ? (float)(m_lpDX->m_client_height/2 - m_desktop_drag_startpos.y) : (float)(m_lpDX->m_client_height/2 - m_desktop_drag_curpos.y);
+ verts[i].z = 0;
+ verts[i].Diffuse = 0x80FFFFFF;
+ }
+ verts[4] = verts[0];
+ m_lpDX->m_lpDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, 4, verts, sizeof(SIMPLEVERTEX));
+ }
+
+ m_lpDX->m_lpDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ m_lpDX->m_lpDevice->SetTexture(0, NULL);
+
+ LeaveCriticalSection(&m_desktop_cs);
+}
+
+//----------------------------------------------------------------------
+
+/*
+NOTES LOG
+
+-problem: you can't click on the 1st monitor's desktop & do stuff
+ -> fixed if you get rid of m_desktop_focuswnd and
+ don't block WM_MOUSEACTIVATE.
+ -> but doing this causes a flash when you click on
+ the real desktop (in multimon setup) of any windows
+ that are overtop of the fake desktop, since the
+ fake desktop rises up in the Z order (activates)
+ and then, next frame, gets pushed back again.
+ -> so how do we avoid the flash?
+ by [conditionally] stopping any z-order changes;
+ intercept & change WM_WINDOWPOSCHANGING messages
+ so there's no z-change, unless *we* specifically
+ requested it (in PushWindowToBack()).
+ -> new problem: right-click context menu won't go away
+ until you click something.
+ -> was fixed by making the plugin window a child
+ of m_hWndDesktopListView.
+*/ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/dxcontext.cpp b/Src/Plugins/Visualization/vis_milk2/dxcontext.cpp
new file mode 100644
index 00000000..6744a645
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/dxcontext.cpp
@@ -0,0 +1,1419 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "DXContext.h"
+#include "utility.h"
+#include "shell_defines.h"
+#include "resource.h"
+#define COMPILE_MULTIMON_STUBS 1
+#include <multimon.h>
+#include <strsafe.h>
+
+// note: added WS_EX_CONTROLPARENT and WS_TABSTOP for embedwnd so window frame will pass on KB commands to us, if it has focus & receives them.
+// however, it is still not working. Maksim says he needs to use GetNextDlgTabItem() and then it will work.
+// aha- had to remove WS_EX_CONTROLPARENT and WS_OVERLAPPED. Should now work with winamp 5.5 build 1620.
+#define MY_EXT_WINDOW_STYLE (m_current_mode.m_skin ? 0/*WS_EX_CONTROLPARENT*/ : ((m_current_mode.screenmode==DESKTOP) ? (WS_EX_TOOLWINDOW) : 0)) // note: changed from TOOLWINDOW to APPWINDOW b/c we wanted the plugin to appear in the taskbar.
+#define SKINNED_WS (WS_VISIBLE|WS_CHILDWINDOW/*|WS_OVERLAPPED*/|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_TABSTOP)
+#define MY_WINDOW_STYLE (m_current_mode.m_skin ? SKINNED_WS : ((m_current_mode.screenmode==FAKE_FULLSCREEN || m_current_mode.screenmode==DESKTOP) ? WS_POPUP : WS_OVERLAPPEDWINDOW)) // note: WS_POPUP (by itself) removes all borders, captions, etc.
+
+#include "vis.h"
+extern winampVisModule mod1;
+
+DXContext::DXContext(HWND hWndWinamp,HINSTANCE hInstance,LPCWSTR szClassName,LPCSTR szWindowCaption,WNDPROC pProc,LONG_PTR uWindowLong, int minimize_winamp, wchar_t* szIniFile)
+{
+ m_classAtom = 0;
+ m_szWindowCaption[0] = 0;
+ m_hwnd = NULL;
+ m_lpD3D = NULL;
+ m_lpDevice = NULL;
+ m_hmod_d3d9 = NULL;
+ m_hmod_d3dx9 = NULL;
+ m_zFormat = D3DFMT_UNKNOWN;
+ for (int i=0; i<MAX_DXC_ADAPTERS; i++)
+ m_orig_windowed_mode_format[i] = D3DFMT_UNKNOWN;
+ m_ordinal_adapter = D3DADAPTER_DEFAULT;
+ m_ignore_wm_destroy = 0;
+ m_hwnd_winamp = hWndWinamp;
+ m_minimize_winamp = minimize_winamp;
+ m_winamp_minimized = 0;
+ m_truly_exiting = 0;
+ m_bpp = 0;
+ m_frame_delay = 0;
+ StringCbCopyW(m_szIniFile, sizeof(m_szIniFile), szIniFile);
+ memset(&myWindowState,0,sizeof(myWindowState));
+ m_szDriver[0] = 0;
+ m_szDesc[0] = 0;
+
+ WNDCLASSW wc = {0};
+
+ // clear the error register
+
+ m_lastErr = S_OK;
+
+ // clear the active flag
+
+ m_ready=FALSE;
+
+ // Set up and register window class
+
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // CS_DBLCLKS lets the window receive WM_LBUTTONDBLCLK, for toggling fullscreen mode...
+ wc.lpfnWndProc = (WNDPROC) pProc;
+ wc.cbWndExtra = sizeof(DWORD);
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PLUGIN_ICON));//NULL;
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = szClassName;
+ m_classAtom = RegisterClassW(&wc);
+ if (!m_classAtom)
+ {
+ wchar_t title[64];
+ int y = GetLastError();
+ m_lastErr = DXC_ERR_REGWIN;
+ MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_REGISTER_WINDOW_CLASS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ Internal_CleanUp();
+ return;
+ }
+
+ StringCbCopy(m_szWindowCaption, sizeof(m_szWindowCaption), szWindowCaption);
+ m_hInstance = hInstance;
+ m_uWindowLong = uWindowLong;
+}
+
+DXContext::~DXContext()
+{
+ Internal_CleanUp();
+}
+
+void DXContext::Internal_CleanUp()
+{
+ // clear active flag
+ m_ready=FALSE;
+
+ // release 3D interfaces
+ SafeRelease(m_lpDevice);
+ SafeRelease(m_lpD3D);
+
+ // destroy the window
+ if (m_truly_exiting)
+ {
+ // somebody else will destroy the window for us!
+ m_hwnd = NULL;
+ if (m_hmod_d3d9)
+ {
+ FreeLibrary(m_hmod_d3d9);
+ m_hmod_d3d9 = NULL;
+ }
+
+ if (m_hmod_d3dx9)
+ {
+ m_hmod_d3dx9 = NULL;
+ }
+ }
+
+ if (myWindowState.me)
+ {
+ DestroyWindow(myWindowState.me);
+ myWindowState.me = NULL;
+ m_hwnd = NULL;
+ }
+ else if (m_hwnd)
+ {
+ DestroyWindow(m_hwnd);
+ m_hwnd = NULL;
+ }
+
+ // unregister window class. note: only works if window is already destroyed!
+ if (m_classAtom)
+ {
+ UnregisterClass(MAKEINTATOM(m_classAtom), m_hInstance);
+ m_classAtom = 0;
+ }
+
+ RestoreWinamp();
+}
+
+void DXContext::GetSnappedClientSize()
+{
+ // Call this whenever you set m_REAL_client_width/height while in windowed mode,
+ // to compute an appropriate (oversized) internal canvas size. At the end of each
+ // frame, for display, the canvas will be centered & cropped.
+ m_client_width = m_REAL_client_width;
+ m_client_height = m_REAL_client_height;
+#if (SNAP_WINDOWED_MODE_BLOCKSIZE >= 1)
+ if (m_current_mode.screenmode == WINDOWED)
+ {
+ // oversize it - then we'll just crop - so onscreen text has no stretching :)
+ m_client_width = max(1, (m_REAL_client_width + 31)/32)*32;
+ m_client_height = max(1, (m_REAL_client_height + 31)/32)*32;
+ }
+#endif
+}
+
+BOOL DXContext::TestFormat(int ordinal_adapter, D3DFORMAT fmt)
+{
+ if (D3D_OK==m_lpD3D->CheckDeviceType(ordinal_adapter,D3DDEVTYPE_HAL,fmt,fmt,FALSE))
+ return TRUE;
+ return FALSE;
+}
+
+BOOL DXContext::TestDepth(int ordinal_adapter, D3DFORMAT fmt)
+{
+ if (D3D_OK!=m_lpD3D->CheckDeviceFormat(ordinal_adapter,D3DDEVTYPE_HAL,m_current_mode.display_mode.Format,
+ D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,fmt))
+ return FALSE;
+ if (D3D_OK!=m_lpD3D->CheckDepthStencilMatch(ordinal_adapter,D3DDEVTYPE_HAL,
+ m_current_mode.display_mode.Format,m_current_mode.display_mode.Format,fmt))
+ return FALSE;
+ return TRUE;
+}
+
+int DXContext::CheckAndCorrectFullscreenDispMode(int ordinal_adapter, D3DDISPLAYMODE *pdm)
+{
+ // given the user's choice of fullscreen display mode,
+ // go through all the display modes available to the currently-selected adapter
+ // and find the best match.
+
+ // returns 1 if it altered pdm to the best match,
+ // or 0 if it was able to find a perfect match.
+
+ // if it returns 1, you might want to notify the user.
+
+
+#define MAX_DISPLAY_MODES 4096
+ D3DDISPLAYMODE list[MAX_DISPLAY_MODES];
+ int nCount = min(m_lpD3D->GetAdapterModeCount(ordinal_adapter, D3DFMT_A8R8G8B8), MAX_DISPLAY_MODES);
+ int nValid = 0;
+ for (int i=0; i<nCount; i++)
+ if (m_lpD3D->EnumAdapterModes(ordinal_adapter, D3DFMT_A8R8G8B8, i, &list[nValid]) == D3D_OK)
+ nValid++;
+
+ // do many passes through the set until we find a match,
+ // each time relaxing more constraints.
+ // outline of the passes:
+
+ int bpp_desired = 0;
+ switch (pdm->Format)
+ {
+ case D3DFMT_R8G8B8 : bpp_desired = 32; break;
+ case D3DFMT_A8R8G8B8: bpp_desired = 32; break;
+ case D3DFMT_X8R8G8B8: bpp_desired = 32; break;
+ case D3DFMT_R5G6B5 : bpp_desired = 16; break;
+ case D3DFMT_X1R5G5B5: bpp_desired = 16; break;
+ case D3DFMT_A1R5G5B5: bpp_desired = 16; break;
+ case D3DFMT_A4R4G4B4: bpp_desired = 16; break;
+ case D3DFMT_R3G3B2 : bpp_desired = 8; break;
+ case D3DFMT_A8R3G3B2: bpp_desired = 16; break;
+ case D3DFMT_X4R4G4B4: bpp_desired = 16; break;
+ }
+
+ // rep MATCH:
+ // 0. w,h,r,f
+ // 1. w,h,-,f
+ // 2. w,h,r,- pass:
+ // 3. w,h,-,- -on pass 0, for 'f', match exact format
+ // 4. 8,6,r,f -on pass 1, for 'f', just match # of bits per pixel
+ // 5. 8,6,-,f (more relaxed match)
+ // 6. 8,6,r,-
+ // 7. 8,6,-,-
+ // 8. -,-,r,f
+ // 9. -,-,-,f
+ // 10. -,-,r,-
+ // 11. -,-,-,-
+ int found = 0;
+ for (int rep=0; rep<12 && !found; rep++)
+ {
+ for (int pass=0; pass<2 && !found; pass++)
+ {
+ for (int i=0; i<nValid && !found; i++)
+ {
+ bool bMatch = true;
+
+ int bpp_this_mode = 0;
+ switch (list[i].Format)
+ {
+ case D3DFMT_R8G8B8 : bpp_this_mode = 32; break;
+ case D3DFMT_A8R8G8B8: bpp_this_mode = 32; break;
+ case D3DFMT_X8R8G8B8: bpp_this_mode = 32; break;
+ case D3DFMT_R5G6B5 : bpp_this_mode = 16; break;
+ case D3DFMT_X1R5G5B5: bpp_this_mode = 16; break;
+ case D3DFMT_A1R5G5B5: bpp_this_mode = 16; break;
+ case D3DFMT_A4R4G4B4: bpp_this_mode = 16; break;
+ case D3DFMT_R3G3B2 : bpp_this_mode = 8; break;
+ case D3DFMT_A8R3G3B2: bpp_this_mode = 16; break;
+ case D3DFMT_X4R4G4B4: bpp_this_mode = 16; break;
+ }
+
+ if (rep < 4)
+ {
+ if (pdm->Width != list[i].Width)
+ bMatch = false;
+ if (pdm->Height != list[i].Height)
+ bMatch = false;
+ }
+ else if (rep < 8)
+ {
+ if (DEFAULT_FULLSCREEN_WIDTH != list[i].Width)
+ bMatch = false;
+ if (DEFAULT_FULLSCREEN_HEIGHT != list[i].Height)
+ bMatch = false;
+ }
+
+ if (((rep/2)%2)==0)
+ {
+ if (pass==0 && pdm->Format != list[i].Format)
+ bMatch = false;
+ else if (pass==1 && bpp_desired != bpp_this_mode)
+ bMatch = false;
+ }
+
+ if (((rep%2)==0) && pdm->RefreshRate != list[i].RefreshRate)
+ {
+ bMatch = false;
+ }
+
+ if (bMatch)
+ {
+ memcpy(pdm, &list[i], sizeof(D3DDISPLAYMODE));
+ found = 1;
+ if (rep != 0 || pass != 0)
+ {
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+BOOL CALLBACK MyMonitorEnumProc(
+ HMONITOR hMonitor, // handle to display monitor
+ HDC hdcMonitor, // handle to monitor DC
+ LPRECT lprcMonitor, // monitor intersection rectangle
+ LPARAM dwData // data
+)
+{
+ RECT* p = (RECT*)dwData;
+ if (hMonitor)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfo(hMonitor, &mi))
+ {
+ p->top = min(p->top , mi.rcMonitor.top);
+ p->left = min(p->left , mi.rcMonitor.left);
+ p->right = max(p->right , mi.rcMonitor.right);
+ p->bottom = max(p->bottom, mi.rcMonitor.bottom);
+ }
+ }
+
+ return TRUE;
+}
+
+int DXContext::GetWindowedModeAutoSize(int iteration)
+{
+ // note: requires 'm_monitor_rect' has been set!
+
+ // generically determine size of window, for windowed mode:
+ int x = m_monitor_rect.right-m_monitor_rect.left;
+ int y = m_monitor_rect.bottom-m_monitor_rect.top;
+
+ // if running in horz/vert-span multi-display mode, base the window size on
+ // an actual display size, not the giant double-sized monitor. Also, position
+ // the window on the same monitor that Winamp is on.
+ if (x >= y*2)
+ {
+ x /= 2;
+
+ // move window to same display that Winamp is on:
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ if (GetWindowPlacement(m_hwnd_winamp, &wp))
+ {
+ int winamp_center_x = (wp.rcNormalPosition.right + wp.rcNormalPosition.left)/2;
+ if (winamp_center_x > x)
+ {
+ m_monitor_rect.left += x;
+ m_monitor_rect.right += x;
+ }
+ }
+ }
+ else if (y > x*4/3)
+ {
+ y /= 2;
+
+ // move window to same display that Winamp is on:
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ if (GetWindowPlacement(m_hwnd_winamp, &wp))
+ {
+ int winamp_center_y = (wp.rcNormalPosition.top + wp.rcNormalPosition.bottom)/2;
+ if (winamp_center_y > y)
+ {
+ m_monitor_rect.top += y;
+ m_monitor_rect.bottom += y;
+ }
+ }
+ }
+
+ int size = min(x, y);
+ size = (int)(size*DEFAULT_WINDOW_SIZE);
+ size = (size/64 - iteration)*64;
+ if (size < 64)
+ size = 64;
+
+ return size;
+}
+
+void DXContext::WriteSafeWindowPos()
+{
+ if (m_current_mode.screenmode == WINDOWED)
+ {
+ WritePrivateProfileIntW(64, L"nMainWndTop", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(64, L"nMainWndLeft", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(64+256, L"nMainWndRight", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(64+256, L"nMainWndBottom", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(64, L"avs_wx",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(64, L"avs_wy",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(256, L"avs_ww",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(256, L"avs_wh",m_szIniFile,L"settings");
+ }
+}
+
+// {0000000A-000C-0010-FF7B-01014263450C}
+const GUID avs_guid =
+ { 10, 12, 16, { 255, 123, 1, 1, 66, 99, 69, 12 } };
+
+BOOL DXContext::Internal_Init(DXCONTEXT_PARAMS *pParams, BOOL bFirstInit)
+{
+ memcpy(&m_current_mode, pParams, sizeof(DXCONTEXT_PARAMS));
+ memset(&myWindowState,0,sizeof(myWindowState));
+
+ // various checks
+ if (m_current_mode.screenmode != WINDOWED)
+ m_current_mode.m_skin = 0;
+
+ // 1. destroy old window
+ if (m_hwnd)
+ {
+ m_ignore_wm_destroy = 1;
+ DestroyWindow(m_hwnd);
+ m_ignore_wm_destroy = 0;
+ m_hwnd = NULL;
+ }
+
+ // 2. CHECK TO MAKE SURE DIRECTX/DDRAW IS INSTALLED
+ if (bFirstInit)
+ {
+ // Test for DirectX 9 + start it
+ // note: if you don't call LoadLibrary here, and you're on a system
+ // where DX9 is missing, Direct3DCreate8() might crash; so call it.
+ int d3d9_already_loaded = (GetModuleHandle("d3d9.dll") != NULL) ? 1 : 0;
+ if (!d3d9_already_loaded)
+ m_hmod_d3d9 = LoadLibrary("d3d9.dll");
+
+ if ((!d3d9_already_loaded && !m_hmod_d3d9) ||
+ !(m_lpD3D = Direct3DCreate9(D3D_SDK_VERSION))
+ )
+ {
+ MissingDirectX(NULL);
+ m_lastErr = DXC_ERR_CREATE3D;
+ return FALSE;
+ }
+
+ if (!m_hmod_d3dx9)
+ m_hmod_d3dx9 = FindD3DX9(m_hwnd_winamp);
+
+ if ((!m_hmod_d3dx9))
+ {
+ MissingDirectX(NULL);
+ m_lastErr = DXC_ERR_CREATE3D;
+ return FALSE;
+ }
+ }
+
+ // 3. get the smallest single rectangle that encloses ALL the monitors on the desktop:
+ SetRect(&m_all_monitors_rect, 0, 0, 0, 0);
+ EnumDisplayMonitors(NULL, NULL, MyMonitorEnumProc, (LPARAM)&m_all_monitors_rect);
+
+ // 4. some DirectX- / DDraw-specific stuff. Also determine hPluginMonitor.
+ HMONITOR hPluginMonitor = NULL;
+ {
+ D3DADAPTER_IDENTIFIER9 temp;
+
+ // find the ordinal # of the adapter whose GUID matches what the user picked from the config panel,
+ // and whose DeviceName matches as well.
+ // if no match found, use D3DADAPTER_DEFAULT.
+ m_ordinal_adapter = D3DADAPTER_DEFAULT;
+ int nAdapters = m_lpD3D->GetAdapterCount();
+ {
+ for (int i=0; i<nAdapters; i++)
+ {
+ if ((m_lpD3D->GetAdapterIdentifier(i, /*D3DENUM_NO_WHQL_LEVEL*/ 0, &temp) == D3D_OK) &&
+ (memcmp(&temp.DeviceIdentifier, &m_current_mode.adapter_guid, sizeof(GUID))==0) &&
+ !strcmp(temp.DeviceName, m_current_mode.adapter_devicename)
+ )
+ {
+ m_ordinal_adapter = i;
+ break;
+ }
+ }
+ }
+
+ if (m_lpD3D->GetAdapterIdentifier(m_ordinal_adapter, /*D3DENUM_NO_WHQL_LEVEL*/ 0, &temp) == D3D_OK)
+ {
+ StringCbCopy(m_szDriver, sizeof(m_szDriver), temp.Driver);
+ StringCbCopy(m_szDesc, sizeof(m_szDesc), temp.Description);
+ }
+
+ int caps_ok = 0;
+ int caps_tries = 0;
+ int changed_fs_disp_mode;
+
+ // try to get the device caps for the adapter selected from the config panel.
+ // if GetDeviceCaps() fails, it's probably because the adapter has been
+ // removed from the system (or disabled), so we try again with other adapter(s).
+ do
+ {
+ changed_fs_disp_mode = 0;
+
+ SetRect(&m_monitor_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
+
+ // get bounding rect of the monitor attached to the adapter (to assist w/window positioning)
+ // note: in vert/horz span setups (psuedo-multimon),
+ // this will be 2048x768 or 1024x1536 or something like that.
+ hPluginMonitor = m_lpD3D->GetAdapterMonitor(m_ordinal_adapter);
+ /*if (hPluginMonitor)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfo(hPluginMonitor, &mi))
+ {
+ memcpy(&m_monitor_rect, &mi.rcMonitor, sizeof(RECT));
+ memcpy(&m_monitor_work_rect, &mi.rcWork, sizeof(RECT));
+ }
+ }*/
+
+ if (bFirstInit)
+ {
+ for (int i=0; i<min(nAdapters, MAX_DXC_ADAPTERS); i++)
+ {
+ // if this is the first call to Init, get the display mode's original color format,
+ // before we go changing it:
+ D3DDISPLAYMODE d3ddm;
+ if (FAILED(m_lpD3D->GetAdapterDisplayMode(i, &d3ddm)))
+ {
+ d3ddm.Format = D3DFMT_UNKNOWN;
+ }
+ m_orig_windowed_mode_format[i] = d3ddm.Format;
+ }
+ }
+
+ // figure out pixel (color) format for back buffer: (m_current_mode.display_mode.Format)
+ if (m_current_mode.screenmode!=FULLSCREEN && m_ordinal_adapter < MAX_DXC_ADAPTERS)
+ m_current_mode.display_mode.Format = m_orig_windowed_mode_format[m_ordinal_adapter];
+ // else
+ // for fullscreen, use what they gave us
+
+ if (m_current_mode.display_mode.Format == D3DFMT_UNKNOWN ||
+ !TestFormat(m_ordinal_adapter, m_current_mode.display_mode.Format))
+ {
+ // if they try to run the plugin without ever running the config panel
+ // first (& pressing OK), then the fullscreen pixelformat hasn't been
+ // chosen... so we try all the possilibities until one works:
+ if (TestFormat(m_ordinal_adapter,D3DFMT_A8R8G8B8)) m_current_mode.display_mode.Format = D3DFMT_A8R8G8B8;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_X8R8G8B8)) m_current_mode.display_mode.Format = D3DFMT_X8R8G8B8;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_R8G8B8)) m_current_mode.display_mode.Format = D3DFMT_R8G8B8 ;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_R5G6B5)) m_current_mode.display_mode.Format = D3DFMT_R5G6B5 ;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_X1R5G5B5)) m_current_mode.display_mode.Format = D3DFMT_X1R5G5B5;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_A1R5G5B5)) m_current_mode.display_mode.Format = D3DFMT_A1R5G5B5;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_A4R4G4B4)) m_current_mode.display_mode.Format = D3DFMT_A4R4G4B4;
+ else if (TestFormat(m_ordinal_adapter,D3DFMT_X4R4G4B4)) m_current_mode.display_mode.Format = D3DFMT_X4R4G4B4;
+ }
+
+ if (m_current_mode.display_mode.Format==D3DFMT_UNKNOWN)
+ {
+ wchar_t title[64];
+ m_lastErr = DXC_ERR_FORMAT;
+ MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_DIRECTX_INIT_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return FALSE;
+ }
+
+ if (m_current_mode.screenmode == FULLSCREEN)
+ changed_fs_disp_mode = CheckAndCorrectFullscreenDispMode(m_ordinal_adapter, &m_current_mode.display_mode);
+
+ // figure out pixel format of the z-buffer: (m_zFormat)
+ m_zFormat = D3DFMT_UNKNOWN;
+ /*
+ if (TestDepth(m_ordinal_adapter,D3DFMT_D32 )) m_zFormat=D3DFMT_D32;
+ else if (TestDepth(m_ordinal_adapter,D3DFMT_D24S8 )) m_zFormat=D3DFMT_D24S8;
+ else if (TestDepth(m_ordinal_adapter,D3DFMT_D24X4S4 )) m_zFormat=D3DFMT_D24X4S4;
+ else if (TestDepth(m_ordinal_adapter,D3DFMT_D24X8 )) m_zFormat=D3DFMT_D24X8;
+ else if (TestDepth(m_ordinal_adapter,D3DFMT_D16 )) m_zFormat=D3DFMT_D16;
+ else if (TestDepth(m_ordinal_adapter,D3DFMT_D15S1 )) m_zFormat=D3DFMT_D15S1;
+ else if (TestDepth(m_ordinal_adapter,D3DFMT_D16_LOCKABLE)) m_zFormat=D3DFMT_D16_LOCKABLE;
+ */
+
+ // get device caps:
+ memset(&m_caps, 0, sizeof(m_caps));
+ if (FAILED(m_lpD3D->GetDeviceCaps(m_ordinal_adapter, D3DDEVTYPE_HAL, &m_caps)))
+ {
+ // that adapter was found in the system, but it might be disabled
+ // (i.e. 'extend my Windows desktop onto this monitor') is unchecked)
+ // so, try other adapters (try all sequentially).
+
+ if (caps_tries < nAdapters)
+ {
+ // try again, this time using the default adapter:
+ m_ordinal_adapter = caps_tries;
+ caps_tries++;
+ }
+ else
+ {
+ wchar_t title[64];
+ m_lastErr = DXC_ERR_CAPSFAIL;
+ MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_DXC_ERR_CAPSFAIL),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return FALSE;
+ }
+ }
+ else
+ {
+ caps_ok = 1;
+ }
+ }
+ while (!caps_ok);
+
+ if (changed_fs_disp_mode)
+ {
+ wchar_t title[64];
+ MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_FS_DISPLAY_MODE_SELECTED_IS_INVALID),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_WARNING, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ }
+
+ switch (m_current_mode.display_mode.Format)
+ {
+ case D3DFMT_R8G8B8 : m_bpp = 32; break;
+ case D3DFMT_A8R8G8B8: m_bpp = 32; break;
+ case D3DFMT_X8R8G8B8: m_bpp = 32; break;
+ case D3DFMT_R5G6B5 : m_bpp = 16; break;
+ case D3DFMT_X1R5G5B5: m_bpp = 16; break;
+ case D3DFMT_A1R5G5B5: m_bpp = 16; break;
+ case D3DFMT_A8R3G3B2: m_bpp = 16; break;
+ case D3DFMT_A4R4G4B4: m_bpp = 16; break;
+ case D3DFMT_X4R4G4B4: m_bpp = 16; break;
+ case D3DFMT_R3G3B2 : m_bpp = 8; break; // misleading? implies a palette...
+ }
+ }
+
+ // 5. set m_monitor_rect and m_monitor_work_rect.
+ if (hPluginMonitor)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfo(hPluginMonitor, &mi))
+ {
+ m_monitor_rect = mi.rcMonitor;
+ m_monitor_rect_orig = mi.rcMonitor;
+ m_monitor_work_rect = mi.rcWork;
+ m_monitor_work_rect_orig = mi.rcWork;
+ }
+ }
+
+ // 6. embedded window stuff [where the plugin window is integrated w/winamp]
+ if (m_current_mode.m_skin)
+ {
+ // set up the window's position on screen
+ // note that we'd prefer to set the CLIENT size we want, but we can't, so we'll just do
+ // this here, and later, adjust the client rect size to what's left...
+ int size = GetWindowedModeAutoSize(0); // note: requires 'm_monitor_rect' has been set!
+ myWindowState.r.left = GetPrivateProfileIntW(L"settings",L"avs_wx",64,m_szIniFile);
+ myWindowState.r.top = GetPrivateProfileIntW(L"settings",L"avs_wy",64,m_szIniFile);
+ myWindowState.r.right = myWindowState.r.left + GetPrivateProfileIntW(L"settings",L"avs_ww",size+24,m_szIniFile);
+ myWindowState.r.bottom = myWindowState.r.top + GetPrivateProfileIntW(L"settings",L"avs_wh",size+40,m_szIniFile);
+
+ // only works on winamp 2.90+!
+ int success = 0;
+ if (GetWinampVersion(mod1.hwndParent) >= 0x2900)
+ {
+ SET_EMBED_GUID((&myWindowState), avs_guid);
+ myWindowState.flags |= EMBED_FLAGS_NOTRANSPARENCY;
+ HWND (*e)(embedWindowState *v);
+ *(void**)&e = (void *)SendMessage(mod1.hwndParent,WM_WA_IPC,(LPARAM)0,IPC_GET_EMBEDIF);
+ if (e)
+ {
+ m_current_mode.parent_window = e(&myWindowState);
+ if (m_current_mode.parent_window)
+ {
+ SetWindowText(m_current_mode.parent_window, m_szWindowCaption);
+ success = 1;
+ }
+ }
+ }
+
+ if (!success)
+ m_current_mode.m_skin = 0;
+ }
+
+ // remember the client rect that was originally desired...
+ RECT windowed_mode_desired_client_rect;
+ windowed_mode_desired_client_rect.top = GetPrivateProfileIntW(L"settings",L"nMainWndTop",-1,m_szIniFile);
+ windowed_mode_desired_client_rect.left = GetPrivateProfileIntW(L"settings",L"nMainWndLeft",-1,m_szIniFile);
+ windowed_mode_desired_client_rect.right = GetPrivateProfileIntW(L"settings",L"nMainWndRight",-1,m_szIniFile);
+ windowed_mode_desired_client_rect.bottom = GetPrivateProfileIntW(L"settings",L"nMainWndBottom",-1,m_szIniFile);
+
+ // ...and in case windowed mode init fails severely,
+ // set it up to try next time for a simple 256x256 window.
+ WriteSafeWindowPos();
+
+ // 7. create the window, if not already created
+ if (!m_hwnd)
+ {
+ m_hwnd = CreateWindowEx(
+ MY_EXT_WINDOW_STYLE, // extended style
+ MAKEINTATOM(m_classAtom), // class
+ m_szWindowCaption, // caption
+ MY_WINDOW_STYLE, // style
+ windowed_mode_desired_client_rect.left, // left
+ windowed_mode_desired_client_rect.top, // top
+ windowed_mode_desired_client_rect.right - windowed_mode_desired_client_rect.left, // temporary width
+ windowed_mode_desired_client_rect.bottom - windowed_mode_desired_client_rect.top, // temporary height
+ m_current_mode.parent_window, // parent window
+ NULL, // menu
+ m_hInstance, // instance
+ (LPVOID)m_uWindowLong
+ ); // parms
+
+ if (!m_hwnd)
+ {
+ wchar_t title[64];
+ m_lastErr = DXC_ERR_CREATEWIN;
+ MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_CREATEWINDOW_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return FALSE;
+ }
+
+ SendMessage(m_hwnd_winamp, WM_WA_IPC, (WPARAM)m_hwnd, IPC_SETVISWND);
+
+ if (m_current_mode.m_skin)
+ {
+ if (GetWinampVersion(mod1.hwndParent) < 0x5051)
+ ShowWindow(m_current_mode.parent_window,SW_SHOWNA); // showing the parent wnd will make it size the child, too
+ else
+ SendMessage(m_current_mode.parent_window, WM_USER+102, 0, 0); // benski> major hack alert. winamp's embedwnd will call ShowWindow in response. SendMessage moves us over to the main thread (we're currently sitting on the viz thread)
+ }
+ }
+
+ // 8. minimize winamp before creating devices & such, so there aren't
+ // any confusing window-focus issues
+ MinimizeWinamp(hPluginMonitor);
+
+ // 9. loop to try and create the window.
+ // if in windowed mode and not enough vidmem, it will try again w/smaller window
+ // (repeatedly, until window client size would be < 64)
+ int iteration = 0;
+ int device_ok = 0;
+ do
+ {
+ // set the window position
+ if (m_current_mode.screenmode==DESKTOP ||
+ m_current_mode.screenmode==FAKE_FULLSCREEN)
+ {
+ int x = m_monitor_rect.right - m_monitor_rect.left;
+ int y = m_monitor_rect.bottom - m_monitor_rect.top;
+
+ if (x >= y*2)
+ {
+ // (pseudo-multimon modes like 2048x768)
+ int mid = (m_monitor_rect.left + m_monitor_rect.right)/2;
+ if (m_current_mode.m_dualhead_horz==1) // show on left side
+ m_monitor_rect.right = mid;
+ else if (m_current_mode.m_dualhead_horz==2) // show on right side
+ m_monitor_rect.left = mid;
+ }
+ else if (y > x*4/3)
+ {
+ // (pseudo-multimon modes like 1024x1536)
+ int mid = (m_monitor_rect.top + m_monitor_rect.bottom)/2;
+ if (m_current_mode.m_dualhead_vert==1) // show on top half
+ m_monitor_rect.bottom = mid;
+ else if (m_current_mode.m_dualhead_vert==2) // show on bottom half
+ m_monitor_rect.top = mid;
+ }
+
+ // recompute width & height (into x,y):
+ x = m_monitor_rect.right - m_monitor_rect.left;
+ y = m_monitor_rect.bottom - m_monitor_rect.top;
+
+ m_client_width = x;
+ m_client_height = y;
+ m_window_width = x;
+ m_window_height = y;
+
+ if (m_current_mode.screenmode == DESKTOP)
+ {
+ // note: we initially hide the window, and then
+ // only display it once the desktop is all nice & ready.
+ // see CPluginShell::DrawAndDisplay().
+
+ RECT r = m_monitor_rect;
+
+ // if possible, shrink the desktop window so it doesn't cover the taskbar.
+ HWND hTaskbar = FindWindow("Shell_TrayWnd", "");
+ if (hTaskbar)
+ {
+ RECT taskbar;
+ GetWindowRect(hTaskbar, &taskbar);
+ int tbw = taskbar.right - taskbar.left;
+ int tbh = taskbar.bottom-taskbar.top;
+
+ if (taskbar.bottom == m_monitor_rect.bottom &&
+ taskbar.left == m_monitor_rect.left &&
+ taskbar.right == m_monitor_rect.right)
+ {
+ r.bottom -= tbh;
+ }
+ else if (taskbar.top == m_monitor_rect.top &&
+ taskbar.left == m_monitor_rect.left &&
+ taskbar.right == m_monitor_rect.right)
+ {
+ r.top += tbh;
+ }
+ else if (taskbar.left == m_monitor_rect.left &&
+ taskbar.top == m_monitor_rect.top &&
+ taskbar.bottom == m_monitor_rect.bottom)
+ {
+ r.left += tbw;
+ }
+ else if (taskbar.right == m_monitor_rect.right &&
+ taskbar.top == m_monitor_rect.top &&
+ taskbar.bottom == m_monitor_rect.bottom)
+ {
+ r.right -= tbw;
+ }
+
+ m_client_width = r.right - r.left;
+ m_client_height = r.bottom - r.top;
+ m_REAL_client_width = m_client_width;
+ m_REAL_client_height = m_client_height;
+ m_window_width = m_client_width;
+ m_window_height = m_client_height;
+
+ //...ok, but text is squished - some w/h is not right...
+
+ }
+
+ SetWindowPos(m_hwnd,HWND_BOTTOM,r.left,r.top,r.right-r.left,r.bottom-r.top,SWP_HIDEWINDOW);
+ }
+ else // FAKE_FULLSCREEN
+ {
+ if (memcmp(&m_all_monitors_rect, &m_monitor_rect, sizeof(RECT))==0)
+ {
+ // there's only one display, and it's entirely covered
+ // by the plugin -> PUT THE PLUGIN ABOVE THE TASKBAR
+ // -> normally, if the user clicked another window,
+ // it would pop the taskbar to the top; but we don't
+ // have to worry about that here, since we're taking
+ // up the whole screen.
+ // -> don't worry about making the text, etc. avoid
+ // the taskbar in this case (see DrawAndDisplay())
+ // -> DO worry about hiding the mouse cursor in this case
+ // (see WM_SETCURSOR handler)
+
+ m_fake_fs_covers_all = 1;
+ //SetWindowPos(m_hwnd,HWND_TOPMOST,m_monitor_rect.left,m_monitor_rect.top,m_window_width,m_window_height,SWP_SHOWWINDOW);
+ }
+ else
+ {
+ // there is space to work outside of the plugin window.
+ // -> here we pretty much have to let the taskbar stay on
+ // top, because it really likes to be there; i.e.,
+ // if you click any other window, it automatically
+ // pops up again.
+ // -> therefore, TRY TO KEEP THE WINDOW ON BOTTOM
+ // (below the taskbar). (see PushWindowToBack)
+ // -> don't worry about hiding the mouse cursor in this case
+ // (see WM_SETCURSOR handler)
+ // -> DO worry about making the text, etc. avoid
+ // the taskbar in this case (see DrawAndDisplay())
+
+ // (note that if taskbar is in the way, they can move it,
+ // since there are other monitors available)
+
+ m_fake_fs_covers_all = 0;
+ //SetWindowPos(m_hwnd,HWND_TOP,m_monitor_rect.left,m_monitor_rect.top,m_window_width,m_window_height,SWP_SHOWWINDOW);
+ }
+
+ SetWindowPos(m_hwnd,HWND_TOPMOST,m_monitor_rect.left,m_monitor_rect.top,m_window_width,m_window_height,SWP_SHOWWINDOW);
+ }
+ }
+ else if (m_current_mode.screenmode == FULLSCREEN)
+ {
+ int x = m_current_mode.display_mode.Width ;
+ int y = m_current_mode.display_mode.Height;
+ int cx = m_monitor_rect.right - m_monitor_rect.left;
+ int cy = m_monitor_rect.bottom - m_monitor_rect.top;
+
+ // test #1
+ if (x >= y*2 || y > x*4/3) // tackle problem of vert/horz spans
+ {
+ wchar_t title[64];
+ int ret = MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_TRYING_TO_ENTER_FS_MODE_WITH_MULTIPLE_DISPLAYS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_TIP, title, 64),
+ MB_OKCANCEL|MB_SETFOREGROUND|MB_TOPMOST);
+ if (ret==IDCANCEL)
+ {
+ m_lastErr = DXC_ERR_USER_CANCELED;
+ return FALSE;
+ }
+ }
+
+ // test #2
+ if ((cx >= cy*2 && x < y*2) || (cy > cx*4/3 && y <= x*4/3))
+ {
+ wchar_t title[64];
+ int ret = MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_TRYING_TO_ENTER_FS_MODE_WITH_MULTIPLE_DISPLAYS_2),
+ WASABI_API_LNGSTRINGW_BUF(IDS_TIP, title, 64),
+ MB_OKCANCEL|MB_SETFOREGROUND|MB_TOPMOST);
+ if (ret==IDCANCEL)
+ {
+ m_lastErr = DXC_ERR_USER_CANCELED;
+ return FALSE;
+ }
+ }
+
+ m_client_width = x;
+ m_client_height = y;
+ m_window_width = x;
+ m_window_height = y;
+ SetWindowPos(m_hwnd,HWND_TOPMOST,m_monitor_rect.left,m_monitor_rect.top,m_window_width,m_window_height,SWP_SHOWWINDOW);
+ }
+ else // WINDOWED
+ {
+ RECT margin;
+ if (m_current_mode.m_skin)
+ {
+ RECT r1, r2;
+ GetWindowRect(m_current_mode.parent_window, &r1);
+ GetWindowRect(m_hwnd , &r2);
+ margin.left = r2.left - r1.left;
+ margin.right = r1.right - r2.right;
+ margin.top = r2.top - r1.top;
+ margin.bottom= r1.bottom - r2.bottom;
+ }
+ else
+ {
+ RECT r1;
+ SetRect(&r1, 0, 0, 256, 256);
+ AdjustWindowRect(&r1, MY_WINDOW_STYLE, 0);
+ margin.left = 0 - r1.left;
+ margin.right = r1.right - 256;
+ margin.top = 0 - r1.top;
+ margin.bottom= r1.bottom - 256;
+ }
+
+ int autosize = 1;
+
+ RECT r = windowed_mode_desired_client_rect;
+ if (iteration==0 && r.top != -1 && r.left != -1 && r.bottom != -1 && r.right != -1)
+ {
+ // use prev. window coordinates:
+ m_REAL_client_width = r.right - r.left;
+ m_REAL_client_height = r.bottom - r.top;
+ GetSnappedClientSize();
+ if (m_current_mode.m_skin) // check this here in case they got a non-aligned size by resizing when "integrated with winamp" was unchecked, then checked it & ran the plugin...
+ {
+ // STRANGE ALIGNMENTS FOR THE WINDOW FRAME: (required by winamp 2):
+ // the window frame's width must be divisible by 25, and height by 29.
+ if (GetWinampVersion(mod1.hwndParent) < 0x4000) // ... winamp 5 doesn't have this prob. (test vs. 0x4000 because winamp5 betas have version tags like 0x4987)
+ {
+ m_REAL_client_width = ((m_client_width + margin.left + margin.right)/25)*25 - margin.left - margin.right;
+ m_REAL_client_height = ((m_client_height + margin.top + margin.bottom)/29)*29 - margin.top - margin.bottom;
+ GetSnappedClientSize();
+ }
+ }
+
+ // transform screen-space CLIENT rect into screen-space WINDOW rect
+ r.top = windowed_mode_desired_client_rect.top - margin.top;
+ r.left = windowed_mode_desired_client_rect.left - margin.left;
+ r.right = r.left + margin.left + m_REAL_client_width + margin.right;
+ r.bottom = r.top + margin.top + m_REAL_client_height + margin.bottom;
+
+ // make sure the window is entirely visible on the selected monitor;
+ // otherwise, autosize/place it.
+ // (note that this test is only appled 1) at startup, and 2) after a resize/max/restore.
+ // this test is not applied when merely moving the window.)
+ if (r.top >= m_monitor_work_rect.top &&
+ r.left >= m_monitor_work_rect.left &&
+ r.right <= m_monitor_work_rect.right &&
+ r.bottom <= m_monitor_work_rect.bottom)
+ {
+ if (m_current_mode.m_skin)
+ {
+ m_window_width = m_REAL_client_width ; // m_window_width/height are for OUR borderless window, not the embedwnd parent frame.
+ m_window_height = m_REAL_client_height;
+ SetWindowPos(m_current_mode.parent_window,HWND_NOTOPMOST, r.left, r.top, r.right-r.left, r.bottom-r.top, /*SWP_SHOWWINDOW|*//*SWP_ASYNCWINDOWPOS*/0);
+ SetWindowPos(m_hwnd ,HWND_NOTOPMOST, windowed_mode_desired_client_rect.left,
+ windowed_mode_desired_client_rect.top,
+ m_REAL_client_width,
+ m_REAL_client_height,
+ SWP_SHOWWINDOW);
+ }
+ else
+ {
+ m_window_width = r.right - r.left;
+ m_window_height = r.bottom - r.top;
+ SetWindowPos(m_hwnd,HWND_NOTOPMOST,r.left,r.top,m_window_width,m_window_height,SWP_SHOWWINDOW);
+ }
+
+ autosize = 0;
+ }
+ }
+
+ if (autosize)
+ {
+ int size = GetWindowedModeAutoSize(iteration); // note: requires 'm_monitor_rect' has been set!
+
+ m_REAL_client_width = size;
+ m_REAL_client_height = size;
+ GetSnappedClientSize();
+
+ if (m_current_mode.m_skin)
+ {
+ // STRANGE ALIGNMENTS FOR THE WINDOW FRAME: (required by winamp 2):
+ // the window frame's width must be divisible by 25, and height by 29.
+ if (GetWinampVersion(mod1.hwndParent) < 0x4000) // ... winamp 5 doesn't have this prob. (test vs. 0x4000 because winamp5 betas have version tags like 0x4987)
+ {
+ m_REAL_client_width = ((m_client_width + margin.left + margin.right)/25)*25 - margin.left - margin.right;
+ m_REAL_client_height = ((m_client_height + margin.top + margin.bottom)/29)*29 - margin.top - margin.bottom;
+ GetSnappedClientSize();
+ }
+
+ m_window_width = m_client_width ; // m_window_width/height are for OUR [borderless] window, not the parent window (which is the embedwnd frame).
+ m_window_height = m_client_height;
+ SetWindowPos(m_current_mode.parent_window,HWND_NOTOPMOST, m_monitor_work_rect.left+32, m_monitor_work_rect.top+32, m_client_width + margin.left + margin.right, m_client_height + margin.top + margin.bottom, /*SWP_SHOWWINDOW|*//*SWP_ASYNCWINDOWPOS*/0);
+ SetWindowPos(m_hwnd ,HWND_NOTOPMOST, m_monitor_work_rect.left+32 + margin.left, m_monitor_work_rect.top+32 + margin.top, m_client_width, m_client_height, SWP_SHOWWINDOW);
+ }
+ else
+ {
+ SetRect(&r, 0, 0, size, size);
+ AdjustWindowRect(&r, MY_WINDOW_STYLE, 0);
+
+ m_window_width = r.right - r.left;
+ m_window_height = r.bottom - r.top;
+
+ SetWindowPos(m_hwnd,HWND_NOTOPMOST, m_monitor_work_rect.left+32, m_monitor_work_rect.top+32, m_window_width, m_window_height, SWP_SHOWWINDOW);
+ }
+ }
+ }
+
+ m_frame_delay = 1; // set this to 2 if you use triple buffering!
+
+ {
+ m_current_mode.display_mode.Width = m_client_width;
+ m_current_mode.display_mode.Height = m_client_height;
+
+ // set up m_d3dpp (presentation parameters):
+ ZeroMemory(&m_d3dpp,sizeof(m_d3dpp));
+ m_d3dpp.Windowed = (m_current_mode.screenmode==FULLSCREEN) ? 0 : 1;
+ m_d3dpp.BackBufferFormat = m_current_mode.display_mode.Format;
+ m_d3dpp.BackBufferWidth = m_client_width;
+ m_d3dpp.BackBufferHeight = m_client_height;
+ m_d3dpp.BackBufferCount = m_current_mode.nbackbuf;
+ if (m_current_mode.screenmode==FULLSCREEN)
+ m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;//D3DSWAPEFFECT_FLIP;
+ else // windowed or fake FS
+ m_d3dpp.SwapEffect = (m_current_mode.allow_page_tearing) ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_COPY;//D3DSWAPEFFECT_DISCARD;//D3DSWAPEFFECT_FLIP;
+ // note: multisampling is only allowed if swapeffect is DISCARD!
+ m_d3dpp.MultiSampleType = (m_d3dpp.SwapEffect==D3DSWAPEFFECT_DISCARD) ? m_current_mode.multisamp : D3DMULTISAMPLE_NONE;
+ //m_d3dpp.hDeviceWindow = m_hwnd;
+ if (m_current_mode.screenmode==FULLSCREEN)
+ {
+ m_d3dpp.FullScreen_RefreshRateInHz = m_current_mode.display_mode.RefreshRate;//D3DPRESENT_RATE_DEFAULT;
+ m_d3dpp.PresentationInterval = m_current_mode.allow_page_tearing ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;//D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT_INTERVAL_ONE;
+ }
+ if (m_zFormat != D3DFMT_UNKNOWN)
+ {
+ m_d3dpp.EnableAutoDepthStencil=TRUE;
+ m_d3dpp.AutoDepthStencilFormat=m_zFormat;
+ }
+
+ // finally, create the device:
+ HRESULT hRes;
+ if (FAILED(hRes = m_lpD3D->CreateDevice(
+ m_ordinal_adapter,
+ D3DDEVTYPE_HAL,
+ m_hwnd,
+ (m_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_MIXED_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+ &m_d3dpp,
+ &m_lpDevice)))
+ {
+ int code = LOWORD(hRes);
+
+ wchar_t str[1024];
+ if (code==2156) //D3DERR_NOTAVAILABLE
+ {
+ m_lastErr = DXC_ERR_CREATEDEV_NOT_AVAIL;
+
+ wchar_t str[2048];
+ WASABI_API_LNGSTRINGW_BUF(IDS_UNABLE_TO_CREATE_DIRECTX_DEVICE, str, 2048);
+
+ if (m_current_mode.screenmode == FULLSCREEN)
+ StringCbCatW(str, sizeof(str), WASABI_API_LNGSTRINGW(IDS_OLDER_DISPLAY_ADAPTER_CATENATION));
+ else
+ StringCbCatW(str, sizeof(str), WASABI_API_LNGSTRINGW(IDS_OLDER_DISPLAY_ADAPTER_CATENATION_2));
+
+ MessageBoxW(m_hwnd,str,
+ WASABI_API_LNGSTRINGW(IDS_MILKDROP_ERROR),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return FALSE;
+ }
+ else if (m_current_mode.screenmode==WINDOWED && m_client_width>64)
+ {
+ // DO NOTHING; try again w/smaller window
+ }
+ else if (m_current_mode.screenmode != WINDOWED || m_client_width <= 64)
+ {
+ // usually, code==2154 here, which is D3DERR_OUTOFVIDEOMEMORY
+ m_lastErr = DXC_ERR_CREATEDEV_PROBABLY_OUTOFVIDEOMEMORY;
+ StringCbPrintfW(str, sizeof(str), WASABI_API_LNGSTRINGW(IDS_DIRECTX_INIT_FAILED_X), LOWORD(hRes));
+
+ // NOTE: *A 'SUGGESTION' SCREEN SHOULD APPEAR NEXT, PROVIDED BY THE CALLER*
+ MessageBoxW(m_hwnd, str,
+ WASABI_API_LNGSTRINGW(IDS_MILKDROP_ERROR),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return FALSE;
+ }
+ }
+ else
+ {
+ device_ok = 1;
+ }
+ }
+
+ iteration++;
+ }
+ while (!device_ok);
+
+ // set initial viewport
+ SetViewport();
+
+ // for desktop mode, push window to back again:
+ if (m_current_mode.screenmode==DESKTOP)
+ SetWindowPos(m_hwnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
+
+ if (m_current_mode.m_skin)
+ {
+ if (GetWinampVersion(mod1.hwndParent) < 0x5051)
+ SetFocus(m_current_mode.parent_window);
+ else
+ PostMessage(m_current_mode.parent_window, WM_USER+103, 0, 0);
+
+ //SetActiveWindow(m_current_mode.parent_window);
+ //SetForegroundWindow(m_current_mode.parent_window);
+ }
+
+ /*if (m_current_mode.screenmode == WINDOWED)
+ SaveWindow();*/
+
+ // return success
+ m_ready = TRUE;
+ // benski> a little hack to get the window size correct. it seems to work
+ if (m_current_mode.screenmode==WINDOWED)
+ PostMessage(m_hwnd, WM_USER+555, 0, 0);
+ return TRUE;
+}
+
+BOOL DXContext::StartOrRestartDevice(DXCONTEXT_PARAMS *pParams)
+{
+ // call this to [re]initialize the DirectX environment with new parameters.
+ // examples: startup; toggle windowed/fullscreen mode; change fullscreen resolution;
+ // and so on.
+ // be sure to clean up all your DirectX stuff first (textures, vertex buffers,
+ // D3DX allocations, etc.) and reallocate it afterwards!
+
+ // note: for windowed mode, 'pParams->disp_mode' (w/h/r/f) is ignored.
+
+ // destroy old window
+ if (myWindowState.me)
+ {
+ m_ignore_wm_destroy = 1;
+ if (m_current_mode.screenmode == WINDOWED)
+ SaveWindow();
+ DestroyWindow(myWindowState.me);
+ myWindowState.me = NULL;
+ m_ignore_wm_destroy = 0;
+ m_hwnd=0;
+ }
+ else if (m_hwnd)
+ {
+ SendMessage(m_hwnd_winamp, WM_WA_IPC, NULL, IPC_SETVISWND);
+ m_ignore_wm_destroy = 1;
+ DestroyWindow(m_hwnd);
+ m_ignore_wm_destroy = 0;
+ m_hwnd = NULL;
+ }
+
+ if (!m_ready)
+ {
+ // first-time init: create a fresh new device
+ return Internal_Init(pParams, TRUE);
+ }
+ else
+ {
+ // re-init: preserve the DX9 object (m_lpD3D),
+ // but destroy and re-create the DX9 device (m_lpDevice).
+ m_ready = FALSE;
+
+ SafeRelease(m_lpDevice);
+ // but leave the D3D object!
+
+ RestoreWinamp();
+ return Internal_Init(pParams, FALSE);
+ }
+}
+
+BOOL DXContext::OnUserResizeWindow(RECT *new_window_rect, RECT *new_client_rect)
+{
+ // call this function on WM_EXITSIZEMOVE when running windowed.
+ // don't bother calling this when fullscreen.
+ // be sure to clean up all your DirectX stuff first (textures, vertex buffers,
+ // D3DX allocations, etc.) and reallocate it afterwards!
+
+ if (!m_ready || (m_current_mode.screenmode != WINDOWED))
+ return FALSE;
+
+ if ((m_client_width == new_client_rect->right - new_client_rect->left) &&
+ (m_client_height == new_client_rect->bottom - new_client_rect->top) &&
+ (m_window_width == new_window_rect->right - new_window_rect->left) &&
+ (m_window_height == new_window_rect->bottom - new_window_rect->top))
+ {
+ return TRUE;
+ }
+
+ m_ready = FALSE;
+
+ m_window_width = new_window_rect->right - new_window_rect->left;
+ m_window_height = new_window_rect->bottom - new_window_rect->top;
+ m_REAL_client_width = new_client_rect->right - new_client_rect->left;
+ m_REAL_client_height = new_client_rect->bottom - new_client_rect->top;
+ GetSnappedClientSize(); //sets m_client_width/height, but with snapping, if in windowed mode.
+
+ m_d3dpp.BackBufferWidth = m_client_width;
+ m_d3dpp.BackBufferHeight = m_client_height;
+ if (m_lpDevice->Reset(&m_d3dpp) != D3D_OK)
+ {
+ WriteSafeWindowPos();
+
+ wchar_t title[64];
+ MessageBoxW(m_hwnd, WASABI_API_LNGSTRINGW(IDS_WINDOW_RESIZE_FAILED),
+ WASABI_API_LNGSTRINGW_BUF(IDS_OUT_OF_VIDEO_MEMORY, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+
+ m_lastErr = DXC_ERR_RESIZEFAILED;
+ return FALSE;
+ }
+
+ SetViewport();
+ m_ready = TRUE;
+ return TRUE;
+}
+
+void DXContext::SetViewport()
+{
+ D3DVIEWPORT9 v;
+ v.X = 0;
+ v.Y = 0;
+ v.Width = m_client_width;
+ v.Height = m_client_height;
+ v.MinZ = 0.0f;
+ v.MaxZ = 1.0f;
+ m_lpDevice->SetViewport(&v);
+}
+
+void DXContext::MinimizeWinamp(HMONITOR hPluginMonitor)
+{
+ // minimize Winamp window
+
+ HMONITOR hWinampMon = MonitorFromWindow(m_hwnd_winamp, MONITOR_DEFAULTTONEAREST);
+ HMONITOR hPluginMon = hPluginMonitor;//MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);//m_lpD3D->GetAdapterMonitor(ordinal_adapter);
+
+ if ((m_current_mode.screenmode == FULLSCREEN || m_current_mode.screenmode == FAKE_FULLSCREEN) &&
+ (m_minimize_winamp) &&
+ (hWinampMon && hPluginMon && hPluginMon==hWinampMon) &&
+ (!m_winamp_minimized)
+ )
+ {
+ // nitpicky check: if we're in fake fullscreen mode
+ // and are only going to display on half the screen,
+ // don't minimize Winamp.
+ if (m_current_mode.screenmode == FAKE_FULLSCREEN)
+ {
+ int x = m_monitor_rect.right - m_monitor_rect.left;
+ int y = m_monitor_rect.bottom - m_monitor_rect.top;
+ if ((x >= y*2 && m_current_mode.m_dualhead_horz != 0) ||
+ (y > x*4/3 && m_current_mode.m_dualhead_vert != 0))
+ {
+ return;
+ }
+ }
+
+ ShowWindow(m_hwnd_winamp, SW_MINIMIZE);
+ // also restore the focus to the plugin window, since this will steal it:
+ SetFocus(m_hwnd);
+ SetActiveWindow(m_hwnd);
+ SetForegroundWindow(m_hwnd);
+ m_winamp_minimized = 1;
+ }
+}
+
+void DXContext::RestoreWinamp()
+{
+ if (m_winamp_minimized)
+ {
+ ShowWindow(m_hwnd_winamp, SW_RESTORE);
+ m_winamp_minimized = 0;
+ }
+}
+
+void DXContext::UpdateMonitorWorkRect()
+{
+ // get active monitor's bounding rectangle (to assist w/window positioning)
+ // note: in vert/horz span setups (psuedo-multimon),
+ // this will be 2048x768 or 1024x1536 or something like that.
+
+ // calling this each frame allows you to detect when the taskbar
+ // moves around on the screen (from edge to edge), and rearrange
+ // the visual elements accordingly, so nothing is obscured.
+
+ HMONITOR hMon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);//m_lpD3D->GetAdapterMonitor(m_ordinal_adapter);
+ if (hMon)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfo(hMon, &mi))
+ {
+ m_monitor_work_rect = mi.rcWork;
+ m_monitor_work_rect_orig = mi.rcWork;
+
+ // if the monitor rect we're using is the same as the
+ // whole area of the monitor, there's no need to update it...
+ //if (memcmp(&mi.rcMonitor, &m_monitor_rect, sizeof(RECT))==0)
+ // return;
+
+ // otherwise, we're doing a half-screen special case
+ // and are running in some pseudo-multimon res like
+ // 2048x768 or 1024x1536, but only using half of it
+ // (i.e. fake fullscreen or desktop mode)
+
+ // therefore... we need to update the work-area rectangle
+ // to reflect which half of the screen it's on.
+
+ if (m_monitor_rect.left == mi.rcMonitor.left)
+ m_monitor_work_rect.left = mi.rcWork.left;
+ else
+ m_monitor_work_rect.left = m_monitor_rect.left + (mi.rcWork.left - mi.rcMonitor.left);
+
+ if (m_monitor_rect.top == mi.rcMonitor.top)
+ m_monitor_work_rect.top = mi.rcWork.top;
+ else
+ m_monitor_work_rect.top = m_monitor_rect.top + (mi.rcWork.top - mi.rcMonitor.top);
+
+ if (m_monitor_rect.right == mi.rcMonitor.right)
+ m_monitor_work_rect.right = mi.rcWork.right;
+ else
+ m_monitor_work_rect.right = m_monitor_rect.right;
+
+ if (m_monitor_rect.bottom == mi.rcMonitor.bottom)
+ m_monitor_work_rect.bottom = mi.rcWork.bottom;
+ else
+ m_monitor_work_rect.bottom = m_monitor_rect.bottom;
+ }
+ }
+}
+
+void DXContext::SaveWindow()
+{
+ if ( m_hwnd == NULL )
+ return;
+
+
+ if (m_current_mode.screenmode == WINDOWED)
+ {
+ RECT c;
+ GetClientRect(m_hwnd, &c);
+
+ // convert client rect from client coords to screen coords:
+ // (window rect is already in screen coords...)
+ POINT p;
+ p.x = c.left;
+ p.y = c.top;
+ if (ClientToScreen(m_hwnd, &p))
+ {
+ c.left += p.x;
+ c.right += p.x;
+ c.top += p.y;
+ c.bottom += p.y;
+ }
+
+ // save bounds for window CLIENT area, but in screen coords
+ WritePrivateProfileIntW(c.top, L"nMainWndTop", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(c.left, L"nMainWndLeft", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(c.right, L"nMainWndRight", m_szIniFile, L"settings");
+ WritePrivateProfileIntW(c.bottom,L"nMainWndBottom", m_szIniFile, L"settings");
+
+ // also save bounds for embedwnd
+ if (m_current_mode.m_skin && myWindowState.me)
+ {
+ WritePrivateProfileIntW(myWindowState.r.left,L"avs_wx",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(myWindowState.r.top ,L"avs_wy",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(myWindowState.r.right-myWindowState.r.left,L"avs_ww",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(myWindowState.r.bottom-myWindowState.r.top,L"avs_wh",m_szIniFile,L"settings");
+ }
+ else if (!m_current_mode.m_skin && m_hwnd)
+ {
+ RECT r;
+ GetWindowRect(m_hwnd, &r);
+ WritePrivateProfileIntW(r.left,L"avs_wx",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(r.top ,L"avs_wy",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(r.right-r.left,L"avs_ww",m_szIniFile,L"settings");
+ WritePrivateProfileIntW(r.bottom-r.top,L"avs_wh",m_szIniFile,L"settings");
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/dxcontext.h b/Src/Plugins/Visualization/vis_milk2/dxcontext.h
new file mode 100644
index 00000000..15076f9c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/dxcontext.h
@@ -0,0 +1,151 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_PLUGIN_SHELL_DXCONTEXT_H__
+#define __NULLSOFT_DX9_PLUGIN_SHELL_DXCONTEXT_H__ 1
+
+#include <windows.h>
+#include "shell_defines.h"
+
+#ifdef _DEBUG
+ #define D3D_DEBUG_INFO // declare this before including d3d9.h
+#endif
+#include <d3d9.h>
+#include <d3dx9.h>
+
+#define SNAP_WINDOWED_MODE_BLOCKSIZE 32 // or use 0 if you don't want snapping
+
+typedef struct
+{
+ eScrMode screenmode; // WINDOWED, FULLSCREEN, or FAKE FULLSCREEN
+ int nbackbuf;
+ int allow_page_tearing;
+ GUID adapter_guid;
+ char adapter_devicename[256];
+ D3DDISPLAYMODE display_mode; // ONLY VALID FOR FULLSCREEN MODE.
+ D3DMULTISAMPLE_TYPE multisamp;
+ HWND parent_window;
+ int m_dualhead_horz; // 0 = span both, 1 = left only, 2 = right only
+ int m_dualhead_vert; // 0 = span both, 1 = top only, 2 = bottom only
+ int m_skin;
+}
+DXCONTEXT_PARAMS;
+
+#define MAX_DXC_ADAPTERS 32
+
+class DXContext
+{
+ public:
+ // PUBLIC FUNCTIONS
+ DXContext(HWND hWndWinamp,HINSTANCE hInstance,LPCWSTR szClassName,LPCSTR szWindowCaption,WNDPROC pProc,LONG_PTR uWindowLong, int minimize_winamp, wchar_t* szIniFile);
+ ~DXContext();
+ BOOL StartOrRestartDevice(DXCONTEXT_PARAMS *pParams); // also serves as Init() function
+ BOOL OnUserResizeWindow(RECT *new_window_rect, RECT *new_client_rect);
+ inline HWND GetHwnd() { return m_hwnd; };
+ inline int TempIgnoreDestroyMessages() { return m_ignore_wm_destroy; };
+ void OnTrulyExiting() { m_truly_exiting = 1; }
+ void UpdateMonitorWorkRect();
+ int GetBitDepth() { return m_bpp; };
+ inline D3DFORMAT GetZFormat() { return m_zFormat; };
+ char* GetDriver() { return m_szDriver; };
+ char* GetDesc() { return m_szDesc; };
+ void SaveWindow();
+
+ // PUBLIC DATA - DO NOT WRITE TO THESE FROM OUTSIDE THE CLASS
+ int m_ready;
+ HRESULT m_lastErr;
+ int m_window_width;
+ int m_window_height;
+ int m_client_width; //in windowed mode, these are the SNAPPED (locked to nearest 32x32)
+ int m_client_height; // width and height
+ int m_REAL_client_width; //these are the ACTUAL (raw) width and height -
+ int m_REAL_client_height; // only valid in windowed mode!
+ int m_fake_fs_covers_all;
+ int m_frame_delay;
+ RECT m_all_monitors_rect; // rect that encompasses all monitors that make up the desktop. The primary monitor's upper-left corner is (0,0).
+ RECT m_monitor_rect; // rect for monitor the plugin is running on; for pseudo-multimon modes like 2048x768, if user decides to only run on half the monitor, this rect reflects that as well.
+ RECT m_monitor_rect_orig; // same, but it's the original rect; does not account for pseudo-multimon modes like 2048x768
+ RECT m_monitor_work_rect; // same, but excludes the taskbar area.
+ RECT m_monitor_work_rect_orig; // original work rect; does not account for pseudo-multimon modes like 2048x768
+ DXCONTEXT_PARAMS m_current_mode;
+ LPDIRECT3DDEVICE9 m_lpDevice;
+ D3DPRESENT_PARAMETERS m_d3dpp;
+ LPDIRECT3D9 m_lpD3D;
+ D3DCAPS9 m_caps;
+
+ protected:
+ D3DMULTISAMPLE_TYPE m_multisamp;
+ D3DFORMAT m_zFormat;
+ D3DFORMAT m_orig_windowed_mode_format[MAX_DXC_ADAPTERS];
+ HMODULE m_hmod_d3d9, m_hmod_d3dx9;
+ int m_ordinal_adapter;
+ HWND m_hwnd;
+ HWND m_hwnd_winamp;
+ LONG_PTR m_uWindowLong;
+ ATOM m_classAtom;
+ char m_szWindowCaption[512];
+ wchar_t m_szIniFile[MAX_PATH];
+ char m_szDriver[MAX_DEVICE_IDENTIFIER_STRING];
+ char m_szDesc[MAX_DEVICE_IDENTIFIER_STRING];
+ HINSTANCE m_hInstance;
+ int m_ignore_wm_destroy;
+ int m_minimize_winamp;
+ int m_winamp_minimized;
+ int m_truly_exiting;
+ int m_bpp;
+
+ embedWindowState myWindowState;
+
+ void WriteSafeWindowPos();
+ int GetWindowedModeAutoSize(int iteration);
+ BOOL TestDepth(int ordinal_adapter, D3DFORMAT fmt);
+ BOOL TestFormat(int ordinal_adapter, D3DFORMAT fmt);
+ int CheckAndCorrectFullscreenDispMode(int ordinal_adapter, D3DDISPLAYMODE *pdm);
+ void SetViewport();
+ void MinimizeWinamp(HMONITOR hPluginMonitor);
+ BOOL Internal_Init(DXCONTEXT_PARAMS *pParams, BOOL bFirstInit);
+ void Internal_CleanUp();
+ void RestoreWinamp();
+ void GetSnappedClientSize(); //windowed mode only
+};
+
+#define DXC_ERR_REGWIN -2
+#define DXC_ERR_CREATEWIN -3
+#define DXC_ERR_CREATE3D -4
+#define DXC_ERR_GETFORMAT -5
+#define DXC_ERR_FORMAT -6
+#define DXC_ERR_CREATEDEV_PROBABLY_OUTOFVIDEOMEMORY -7
+#define DXC_ERR_RESIZEFAILED -8
+#define DXC_ERR_CAPSFAIL -9
+#define DXC_ERR_BAD_FS_DISPLAYMODE -10
+#define DXC_ERR_USER_CANCELED -11
+#define DXC_ERR_CREATEDEV_NOT_AVAIL -12
+#define DXC_ERR_CREATEDDRAW -13
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/fft.cpp b/Src/Plugins/Visualization/vis_milk2/fft.cpp
new file mode 100644
index 00000000..7c0a5129
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/fft.cpp
@@ -0,0 +1,320 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <math.h>
+#include <memory.h>
+#include "fft.h"
+
+#define PI 3.141592653589793238462643383279502884197169399f
+
+#define SafeDeleteArray(x) { if (x) { delete [] x; x = 0; } }
+
+/*****************************************************************************/
+
+FFT::FFT()
+{
+ NFREQ = 0;
+
+ envelope = 0;
+ equalize = 0;
+ bitrevtable = 0;
+ cossintable = 0;
+ temp1 = 0;
+ temp2 = 0;
+}
+
+/*****************************************************************************/
+
+FFT::~FFT()
+{
+ CleanUp();
+}
+
+/*****************************************************************************/
+
+void FFT::Init(int samples_in, int samples_out, int bEqualize, float envelope_power)
+{
+ // samples_in: # of waveform samples you'll feed into the FFT
+ // samples_out: # of frequency samples you want out; MUST BE A POWER OF 2.
+ // bEqualize: set to 1 if you want the magnitude of the basses and trebles
+ // to be roughly equalized; 0 to leave them untouched.
+ // envelope_power: set to -1 to disable the envelope; otherwise, specify
+ // the envelope power you want here. See InitEnvelopeTable for more info.
+
+ CleanUp();
+
+ m_samples_in = samples_in;
+ NFREQ = samples_out*2;
+
+ InitBitRevTable();
+ InitCosSinTable();
+ if (envelope_power > 0)
+ InitEnvelopeTable(envelope_power);
+ if (bEqualize)
+ InitEqualizeTable();
+ temp1 = new float[NFREQ];
+ temp2 = new float[NFREQ];
+}
+
+/*****************************************************************************/
+
+void FFT::CleanUp()
+{
+ SafeDeleteArray(envelope);
+ SafeDeleteArray(equalize);
+ SafeDeleteArray(bitrevtable);
+ SafeDeleteArray(cossintable);
+ SafeDeleteArray(temp1);
+ SafeDeleteArray(temp2);
+}
+
+/*****************************************************************************/
+
+void FFT::InitEqualizeTable()
+{
+ int i;
+ float scaling = -0.02f;
+ float inv_half_nfreq = 1.0f/(float)(NFREQ/2);
+
+ equalize = new float[NFREQ/2];
+
+ for (i=0; i<NFREQ/2; i++)
+ equalize[i] = scaling * logf( (float)(NFREQ/2-i)*inv_half_nfreq );
+}
+
+/*****************************************************************************/
+
+void FFT::InitEnvelopeTable(float power)
+{
+ // this precomputation is for multiplying the waveform sample
+ // by a bell-curve-shaped envelope, so we don't see the ugly
+ // frequency response (oscillations) of a square filter.
+
+ // a power of 1.0 will compute the FFT with exactly one convolution.
+ // a power of 2.0 is like doing it twice; the resulting frequency
+ // output will be smoothed out and the peaks will be "fatter".
+ // a power of 0.5 is closer to not using an envelope, and you start
+ // to get the frequency response of the square filter as 'power'
+ // approaches zero; the peaks get tighter and more precise, but
+ // you also see small oscillations around their bases.
+
+ int i;
+ float mult = 1.0f/(float)m_samples_in * 6.2831853f;
+
+ envelope = new float[m_samples_in];
+
+ if (power==1.0f)
+ for (i=0; i<m_samples_in; i++)
+ envelope[i] = 0.5f + 0.5f*sinf(i*mult - 1.5707963268f);
+ else
+ for (i=0; i<m_samples_in; i++)
+ envelope[i] = powf(0.5f + 0.5f*sinf(i*mult - 1.5707963268f), power);
+}
+
+/*****************************************************************************/
+
+void FFT::InitBitRevTable()
+{
+ int i,j,m,temp;
+ bitrevtable = new int[NFREQ];
+
+ for (i=0; i<NFREQ; i++)
+ bitrevtable[i] = i;
+
+ for (i=0,j=0; i < NFREQ; i++)
+ {
+ if (j > i)
+ {
+ temp = bitrevtable[i];
+ bitrevtable[i] = bitrevtable[j];
+ bitrevtable[j] = temp;
+ }
+
+ m = NFREQ >> 1;
+
+ while (m >= 1 && j >= m)
+ {
+ j -= m;
+ m >>= 1;
+ }
+
+ j += m;
+ }
+}
+
+/*****************************************************************************/
+
+void FFT::InitCosSinTable()
+{
+
+ int i,dftsize,tabsize;
+ float theta;
+
+ dftsize = 2;
+ tabsize = 0;
+ while (dftsize <= NFREQ)
+ {
+ tabsize++;
+ dftsize <<= 1;
+ }
+
+ cossintable = new float[tabsize][2];
+
+ dftsize = 2;
+ i = 0;
+ while (dftsize <= NFREQ)
+ {
+ theta = (float)(-2.0f*PI/(float)dftsize);
+ cossintable[i][0] = (float)cosf(theta);
+ cossintable[i][1] = (float)sinf(theta);
+ i++;
+ dftsize <<= 1;
+ }
+}
+
+/*****************************************************************************/
+
+void FFT::time_to_frequency_domain(float *in_wavedata, float *out_spectraldata)
+{
+ // Converts time-domain samples from in_wavedata[]
+ // into frequency-domain samples in out_spectraldata[].
+ // The array lengths are the two parameters to Init().
+
+ // The last sample of the output data will represent the frequency
+ // that is 1/4th of the input sampling rate. For example,
+ // if the input wave data is sampled at 44,100 Hz, then the last
+ // sample of the spectral data output will represent the frequency
+ // 11,025 Hz. The first sample will be 0 Hz; the frequencies of
+ // the rest of the samples vary linearly in between.
+ // Note that since human hearing is limited to the range 200 - 20,000
+ // Hz. 200 is a low bass hum; 20,000 is an ear-piercing high shriek.
+ // Each time the frequency doubles, that sounds like going up an octave.
+ // That means that the difference between 200 and 300 Hz is FAR more
+ // than the difference between 5000 and 5100, for example!
+ // So, when trying to analyze bass, you'll want to look at (probably)
+ // the 200-800 Hz range; whereas for treble, you'll want the 1,400 -
+ // 11,025 Hz range.
+ // If you want to get 3 bands, try it this way:
+ // a) 11,025 / 200 = 55.125
+ // b) to get the number of octaves between 200 and 11,025 Hz, solve for n:
+ // 2^n = 55.125
+ // n = log 55.125 / log 2
+ // n = 5.785
+ // c) so each band should represent 5.785/3 = 1.928 octaves; the ranges are:
+ // 1) 200 - 200*2^1.928 or 200 - 761 Hz
+ // 2) 200*2^1.928 - 200*2^(1.928*2) or 761 - 2897 Hz
+ // 3) 200*2^(1.928*2) - 200*2^(1.928*3) or 2897 - 11025 Hz
+
+ // A simple sine-wave-based envelope is convolved with the waveform
+ // data before doing the FFT, to emeliorate the bad frequency response
+ // of a square (i.e. nonexistent) filter.
+
+ // You might want to slightly damp (blur) the input if your signal isn't
+ // of a very high quality, to reduce high-frequency noise that would
+ // otherwise show up in the output.
+
+ int j, m, i, dftsize, hdftsize, t;
+ float wr, wi, wpi, wpr, wtemp, tempr, tempi;
+
+ if (!bitrevtable) return;
+ //if (!envelope) return;
+ //if (!equalize) return;
+ if (!temp1) return;
+ if (!temp2) return;
+ if (!cossintable) return;
+
+ // 1. set up input to the fft
+ if (envelope)
+ {
+ for (i=0; i<NFREQ; i++)
+ {
+ int idx = bitrevtable[i];
+ if (idx < m_samples_in)
+ temp1[i] = in_wavedata[idx] * envelope[idx];
+ else
+ temp1[i] = 0;
+ }
+ }
+ else
+ {
+ for (i=0; i<NFREQ; i++)
+ {
+ int idx = bitrevtable[i];
+ if (idx < m_samples_in)
+ temp1[i] = in_wavedata[idx];// * envelope[idx];
+ else
+ temp1[i] = 0;
+ }
+ }
+ memset(temp2, 0, sizeof(float)*NFREQ);
+
+ // 2. perform FFT
+ float *real = temp1;
+ float *imag = temp2;
+ dftsize = 2;
+ t = 0;
+ while (dftsize <= NFREQ)
+ {
+ wpr = cossintable[t][0];
+ wpi = cossintable[t][1];
+ wr = 1.0f;
+ wi = 0.0f;
+ hdftsize = dftsize >> 1;
+
+ for (m = 0; m < hdftsize; m+=1)
+ {
+ for (i = m; i < NFREQ; i+=dftsize)
+ {
+ j = i + hdftsize;
+ tempr = wr*real[j] - wi*imag[j];
+ tempi = wr*imag[j] + wi*real[j];
+ real[j] = real[i] - tempr;
+ imag[j] = imag[i] - tempi;
+ real[i] += tempr;
+ imag[i] += tempi;
+ }
+
+ wr = (wtemp=wr)*wpr - wi*wpi;
+ wi = wi*wpr + wtemp*wpi;
+ }
+
+ dftsize <<= 1;
+ t++;
+ }
+
+ // 3. take the magnitude & equalize it (on a log10 scale) for output
+ if (equalize)
+ for (i=0; i<NFREQ/2; i++)
+ out_spectraldata[i] = equalize[i] * sqrtf(temp1[i]*temp1[i] + temp2[i]*temp2[i]);
+ else
+ for (i=0; i<NFREQ/2; i++)
+ out_spectraldata[i] = sqrtf(temp1[i]*temp1[i] + temp2[i]*temp2[i]);
+}
+
+/*****************************************************************************/ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/fft.h b/Src/Plugins/Visualization/vis_milk2/fft.h
new file mode 100644
index 00000000..5484b336
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/fft.h
@@ -0,0 +1,60 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_PLUGIN_SHELL_FFT_H__
+#define __NULLSOFT_DX9_PLUGIN_SHELL_FFT_H__ 1
+
+class FFT
+{
+public:
+ FFT();
+ ~FFT();
+ void Init(int samples_in, int samples_out, int bEqualize=1, float envelope_power=1.0f);
+ void time_to_frequency_domain(float *in_wavedata, float *out_spectraldata);
+ int GetNumFreq() { return NFREQ; };
+ void CleanUp();
+private:
+ int m_ready;
+ int m_samples_in;
+ int NFREQ;
+
+ void InitEnvelopeTable(float power);
+ void InitEqualizeTable();
+ void InitBitRevTable();
+ void InitCosSinTable();
+
+ int *bitrevtable;
+ float *envelope;
+ float *equalize;
+ float *temp1;
+ float *temp2;
+ float (*cossintable)[2];
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/gstring.h b/Src/Plugins/Visualization/vis_milk2/gstring.h
new file mode 100644
index 00000000..c7134645
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/gstring.h
@@ -0,0 +1,229 @@
+#ifndef __GSTRING_SMART_STRING_CLASS__
+#define __GSTRING_SMART_STRING_CLASS__ 1
+
+// This is just a streamlined version of std::string.
+// It cleans itself up automatically, it can copy itself,
+// test for equality, etc.
+// and you can use .c_str() to get the string const, so it's
+// sytactically the same (usage-wise) as std::string.
+// Written by Ryan Geiss.
+
+#include <windows.h>
+
+class GString
+{
+public:
+ GString()
+ {
+ m_data = new wchar_t[1];
+ m_data[0] = 0;
+ m_size = 1;
+ }
+
+ GString(const wchar_t* src)
+ {
+ m_data = NULL;
+ m_size = 0;
+ operator=(src);
+ }
+
+ GString(const GString &src_string)
+ {
+ m_data = NULL;
+ m_size = 0;
+ operator=(src_string);
+ }
+
+ ~GString()
+ {
+ delete m_data; // note: delete is safe on NULL ptrs
+ m_data = NULL;
+ m_size = 0;
+ }
+
+ inline GString& operator=(const wchar_t* src)
+ {
+ if (src != m_data) // don't do anything on "x = x.c_str();"
+ {
+ delete m_data; // note: delete is safe on NULL ptrs
+ if (src)
+ {
+ m_size = wcslen(src)+1;
+ m_data = new wchar_t[m_size];
+ memcpy(m_data, src, m_size*2);
+ }
+ else
+ {
+ m_size = 1;
+ m_data = new wchar_t[1];
+ m_data[0] = 0;
+ }
+ }
+ return *this;
+ }
+
+ inline GString& operator=(const GString &src_string)
+ {
+ if (&src_string != this) // don't do anything on "x = x;"
+ {
+ if (src_string.GetSize() != m_size) //optimization
+ {
+ delete m_data;
+ m_size = src_string.GetSize();
+ m_data = new wchar_t[m_size];
+ }
+ memcpy(m_data, src_string.c_str(), m_size*2);
+ }
+ return *this;
+ }
+
+ inline wchar_t operator[](int index) const
+ {
+ return m_data[index];
+ }
+
+ inline bool operator==(const wchar_t* comp)
+ {
+ return (wcscmp(m_data,comp) == 0);
+ }
+
+ inline bool operator==(const GString &comp)
+ {
+ if (m_size != comp.m_size) // shortcut
+ return false;
+ return (wcscmp(m_data,comp.c_str()) == 0); //return operator==(comp.m_data);
+ }
+
+ inline const wchar_t* c_str() const
+ {
+ return m_data;
+ }
+
+ // This is actually unsafe, but we need it for convenience, unless we really
+ // feel like copying all data twice. BE WARNED! When this class reallocates
+ // memory, all old references to _data are invalid!
+ //operator const char*() const { return _data; }
+ inline int GetSize() const //in bytes - including terminating NULL char.
+ {
+ return m_size;
+ }
+
+ inline int GetLength() const
+ {
+ return (m_size >= 1) ? m_size-1 : 0;
+ }
+
+private:
+ wchar_t* m_data;
+ int m_size;
+};
+
+class GStringA
+{
+public:
+ GStringA()
+ {
+ m_data = new char[1];
+ m_data[0] = 0;
+ m_size = 1;
+ }
+
+ GStringA(const char* src)
+ {
+ m_data = NULL;
+ m_size = 0;
+ operator=(src);
+ }
+
+ GStringA(const GStringA &src_string)
+ {
+ m_data = NULL;
+ m_size = 0;
+ operator=(src_string);
+ }
+
+ ~GStringA()
+ {
+ delete m_data; // note: delete is safe on NULL ptrs
+ m_data = NULL;
+ m_size = 0;
+ }
+
+ inline GStringA& operator=(const char* src)
+ {
+ if (src != m_data) // don't do anything on "x = x.c_str();"
+ {
+ delete m_data; // note: delete is safe on NULL ptrs
+ if (src)
+ {
+ m_size = strlen(src)+1;
+ m_data = new char[m_size];
+ memcpy(m_data, src, m_size);
+ }
+ else
+ {
+ m_size = 1;
+ m_data = new char[1];
+ m_data[0] = 0;
+ }
+ }
+ return *this;
+ }
+
+ inline GStringA& operator=(const GStringA &src_string)
+ {
+ if (&src_string != this) // don't do anything on "x = x;"
+ {
+ if (src_string.GetSize() != m_size) //optimization
+ {
+ delete m_data;
+ m_size = src_string.GetSize();
+ m_data = new char[m_size];
+ }
+ memcpy(m_data, src_string.c_str(), m_size);
+ }
+ return *this;
+ }
+
+ inline char operator[](int index) const
+ {
+ return m_data[index];
+ }
+
+ inline bool operator==(const char* comp)
+ {
+ return (strcmp(m_data,comp) == 0);
+ }
+
+ inline bool operator==(const GStringA &comp)
+ {
+ if (m_size != comp.m_size) // shortcut
+ return false;
+ return (strcmp(m_data,comp.c_str()) == 0); //return operator==(comp.m_data);
+ }
+
+ inline const char* c_str() const
+ {
+ return m_data;
+ }
+
+ // This is actually unsafe, but we need it for convenience, unless we really
+ // feel like copying all data twice. BE WARNED! When this class reallocates
+ // memory, all old references to _data are invalid!
+ //operator const char*() const { return _data; }
+ inline int GetSize() const //in bytes - including terminating NULL char.
+ {
+ return m_size;
+ }
+
+ inline int GetLength() const
+ {
+ return (m_size >= 1) ? m_size-1 : 0;
+ }
+
+private:
+ char* m_data;
+ int m_size;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/icon_t.h b/Src/Plugins/Visualization/vis_milk2/icon_t.h
new file mode 100644
index 00000000..c1f6e90f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/icon_t.h
@@ -0,0 +1,49 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __ICON_T_H__
+#define __ICON_T_H__ 1
+
+#include <windows.h>
+#include <shlobj.h> // for ITEMIDLIST
+
+typedef struct
+{
+ int x, y, selected, icon_bitmap_idx, checksum[3], bUpdate;
+ DWORD dwReserved1;
+ DWORD dwReserved2;
+ DWORD dwReserved3;
+ DWORD dwReserved4;
+ RECT icon_rect;
+ RECT label_rect;
+ BYTE pidl[1024]; // when using this, cast it to an ITEMIDLIST
+ TCHAR name[MAX_PATH];
+} icon_t;
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/manifest.xml b/Src/Plugins/Visualization/vis_milk2/manifest.xml
new file mode 100644
index 00000000..5f91bfcc
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/manifest.xml
@@ -0,0 +1 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><description>Nullsoft Winamp Milkdrop 2 (So You Don't Have To Keep Hacking The Plug-in Dll</description><dependency><dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity></dependentAssembly></dependency></assembly> \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/md_defines.h b/Src/Plugins/Visualization/vis_milk2/md_defines.h
new file mode 100644
index 00000000..36003231
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/md_defines.h
@@ -0,0 +1,83 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __MILKDROP_DEFINES_H__
+#define __MILKDROP_DEFINES_H__ 1
+
+// IDENTIFIERS
+/*
+#define CURRENT_VERSION 220
+#define CURRENT_SUBVERSION 0 // 0=first release, 1=a, 2=b, 3=c...
+#define MODULEDESC "MilkDrop 2.2" // used for module desc (from Winamp/Prefs) + window title for fullscreen mode
+#define DLLDESC "MilkDrop 2.2"
+#define NAME "MilkDrop"
+#define TITLE "MilkDrop"
+#define CLASSNAME "MilkDrop" // window class name
+*/
+#define TEXT_WINDOW_CLASSNAME "MilkDrop Console [VJ Mode]"
+#define DEBUGFILE "c:\\m_debug.txt"
+//#define CONFIG_INIFILE "milkdrop_config.ini"
+//#define PRESET_INIFILE "milkdrop_presets.ini"
+#define DEBUGFILEHEADER "[milkdrop debug file]\n"
+
+// define this to disable expression evaluation:
+// (...for some reason, evallib kills the debugger)
+#ifdef _DEBUG
+ #define _NO_EXPR_ //FIXME
+#endif
+
+#define MAX_GRID_X 192//128
+#define MAX_GRID_Y 144//96
+#define NUM_WAVES 8
+#define NUM_MODES 7
+#define LINEFEED_CONTROL_CHAR 1 // note: this char should be outside the ascii range from SPACE (32) to lowercase 'z' (122)
+#define MAX_CUSTOM_MESSAGE_FONTS 16 // 0-15
+#define MAX_CUSTOM_MESSAGES 100 // 00-99
+#define MAX_CUSTOM_WAVES 4
+#define MAX_CUSTOM_SHAPES 4
+
+// aspect ratio makes the motion in the UV field [0..1] cover the screen appropriately,
+//#define ASPECT_X 1.00
+//#define ASPECT_Y 0.75 // ~h/w
+//#define ASPECT_X ( (m_nTexSizeY > m_nTexSizeX) ? m_nTexSizeX/(float)m_nTexSizeY : 1.0f ) //0.75f
+//#define ASPECT_Y ( (m_nTexSizeX > m_nTexSizeY) ? m_nTexSizeY/(float)m_nTexSizeX : 1.0f ) //0.75f
+// --> now stored in m_fAspectX, m_fInvAspectY, etc. <--
+
+#define WM_MILKDROP_SYSTRAY_MSG WM_USER + 407
+#define IDC_MILKDROP_SYSTRAY_ICON 555
+#define ID_MILKDROP_SYSTRAY_CLOSE 556
+//#define ID_MILKDROP_SYSTRAY_RESUME 559
+//#define ID_MILKDROP_SYSTRAY_SUSPEND 560
+//#define ID_MILKDROP_SYSTRAY_HOTKEYS 561
+
+#define NUMERIC_INPUT_MODE_CUST_MSG 0
+#define NUMERIC_INPUT_MODE_SPRITE 1
+#define NUMERIC_INPUT_MODE_SPRITE_KILL 2
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/menu.cpp b/Src/Plugins/Visualization/vis_milk2/menu.cpp
new file mode 100644
index 00000000..be632314
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/menu.cpp
@@ -0,0 +1,751 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "state.h" // for CBlendableFloat - fix this
+#include "menu.h"
+#include "plugin.h"
+#include <stdio.h>
+#include <math.h>
+#include <assert.h>
+#include "resource.h"
+
+extern CPlugin g_plugin; // declared in main.cpp
+
+//----------------------------------------
+
+CMilkMenuItem::CMilkMenuItem()
+{
+ WASABI_API_LNGSTRINGW_BUF(IDS_UNTITLED_MENU_ITEM,m_szName,64);
+ m_szToolTip[0] = 0;
+ m_type = MENUITEMTYPE_BUNK;
+ m_fMin = 0.0f;
+ m_fMax = 0.0f;
+ m_var_offset = NULL;
+ m_pCallbackFn = NULL;
+ m_pNext = NULL;
+ m_original_value = NULL;
+ m_nLastCursorPos = 0;
+ m_bEnabled = true;
+}
+
+CMilkMenuItem::~CMilkMenuItem()
+{
+ if (m_pNext)
+ {
+ delete m_pNext;
+ m_pNext = NULL;
+ }
+}
+
+//----------------------------------------
+
+CMilkMenu::CMilkMenu()
+{
+ //Reset();
+}
+
+CMilkMenu::~CMilkMenu()
+{
+ /*
+ if (m_pFirstChildItem)
+ {
+ delete m_pFirstChildItem;
+ m_pFirstChildItem = NULL;
+ }
+ */
+}
+
+//----------------------------------------
+
+bool CMilkMenu::ItemIsEnabled(int j)
+{
+ if (j < m_nChildMenus)
+ return m_ppChildMenu[j]->IsEnabled();
+
+ int i = m_nChildMenus;
+ CMilkMenuItem *pChild = m_pFirstChildItem;
+ while (pChild && i<j)
+ {
+ pChild = pChild->m_pNext;
+ i++;
+ }
+ if (pChild)
+ return pChild->m_bEnabled;
+
+ return false;
+}
+
+//----------------------------------------
+
+void CMilkMenu::EnableItem(wchar_t* szName, bool bEnable)
+{
+ //search submenus
+ int i = 0;
+ for (i=0; i<m_nChildMenus; i++) {
+ if (!wcscmp(m_ppChildMenu[i]->GetName(), szName))
+ {
+ m_ppChildMenu[i]->Enable(bEnable);
+ if (!bEnable)
+ {
+ while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel))
+ m_nCurSel--;
+ if (m_nCurSel==0 && !ItemIsEnabled(m_nCurSel))
+ while (m_nCurSel < m_nChildMenus+m_nChildItems-1 && !ItemIsEnabled(m_nCurSel))
+ m_nCurSel++;
+ }
+ return;
+ }
+ }
+
+ //search child items
+ CMilkMenuItem *pChild = m_pFirstChildItem;
+ while (pChild)
+ {
+ if (!wcscmp(pChild->m_szName, szName))
+ {
+ pChild->m_bEnabled = bEnable;
+ if (!bEnable)
+ {
+ while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel))
+ m_nCurSel--;
+ if (m_nCurSel==0 && !ItemIsEnabled(m_nCurSel))
+ while (m_nCurSel < m_nChildMenus+m_nChildItems-1 && !ItemIsEnabled(m_nCurSel))
+ m_nCurSel++;
+ }
+ return;
+ }
+ pChild = pChild->m_pNext;
+ i++;
+ }
+}
+
+//----------------------------------------
+
+void CMilkMenu::Reset()
+{
+ m_pParentMenu = NULL;
+ for (int i=0; i<MAX_CHILD_MENUS; i++)
+ m_ppChildMenu[i] = NULL;
+ m_pFirstChildItem = NULL;
+ WASABI_API_LNGSTRINGW_BUF(IDS_UNTITLED_MENU,m_szMenuName,64);
+ m_nChildMenus = 0;
+ m_nChildItems = 0;
+ m_nCurSel = 0;
+ m_bEditingCurSel = false;
+ m_bEnabled = true;
+}
+
+//----------------------------------------
+
+void CMilkMenu::Init(wchar_t *szName)
+{
+ Reset();
+ if (szName && szName[0])
+ wcsncpy(m_szMenuName, szName, 64);
+}
+
+void CMilkMenu::Finish()
+{
+ if (m_pFirstChildItem)
+ {
+ delete m_pFirstChildItem;
+ m_pFirstChildItem = NULL;
+ }
+}
+
+//----------------------------------------
+
+void CMilkMenu::AddChildMenu(CMilkMenu *pMenu)
+{
+ if (m_nChildMenus < MAX_CHILD_MENUS)
+ {
+ m_ppChildMenu[m_nChildMenus++] = pMenu;
+ pMenu->SetParentPointer(this);
+ }
+}
+
+//----------------------------------------
+
+void CMilkMenu::AddItem(wchar_t *szName, void *var, MENUITEMTYPE type, wchar_t *szToolTip,
+ float min, float max, MilkMenuCallbackFnPtr pCallback,
+ unsigned int wParam, unsigned int lParam)
+{
+ CMilkMenuItem *pLastItem = NULL;
+
+ // find last item in linked list
+ if (!m_pFirstChildItem)
+ {
+ // first item
+ m_pFirstChildItem = new CMilkMenuItem;
+ pLastItem = m_pFirstChildItem;
+ }
+ else
+ {
+ pLastItem = m_pFirstChildItem;
+ while (pLastItem->m_pNext)
+ pLastItem = pLastItem->m_pNext;
+
+ // allocate a new CMilkMenuItem
+ pLastItem->m_pNext = new CMilkMenuItem;
+ pLastItem = pLastItem->m_pNext;
+ }
+
+ // set its attributes
+ wcsncpy(pLastItem->m_szName, szName, 64);
+ wcsncpy(pLastItem->m_szToolTip, szToolTip, 1024);
+ pLastItem->m_var_offset = (size_t)var - (size_t)(g_plugin.m_pState);
+ pLastItem->m_type = type;
+ pLastItem->m_fMin = min;
+ pLastItem->m_fMax = max;
+ pLastItem->m_wParam = wParam;
+ pLastItem->m_lParam = lParam;
+ if ((type==MENUITEMTYPE_LOGBLENDABLE || type==MENUITEMTYPE_LOGFLOAT) && min==max)
+ {
+ // special defaults
+ pLastItem->m_fMin = 0.01f;
+ pLastItem->m_fMax = 100.0f;
+ }
+ pLastItem->m_pCallbackFn = pCallback;
+
+ m_nChildItems++;
+}
+
+//----------------------------------------
+
+void MyMenuTextOut(eFontIndex font_index, wchar_t* str, DWORD color, RECT* pRect, int bCalcRect, RECT* pCalcRect)
+{
+ if (bCalcRect)
+ {
+ RECT t = *pRect;
+ pRect->top += g_plugin.m_text.DrawTextW(g_plugin.GetFont(font_index), str, -1, &t, DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT, 0xFFFFFFFF, false);
+ pCalcRect->bottom += t.bottom - t.top;
+ //if (pCalcRect->bottom > pRect->bottom)
+ // pCalcRect->bottom = pRect->bottom;
+ pCalcRect->right = max(pCalcRect->right, pCalcRect->left + t.right - t.left);
+ }
+ else
+ {
+ pRect->top += g_plugin.m_text.DrawTextW(g_plugin.GetFont(font_index), str, -1, pRect, DT_SINGLELINE | DT_END_ELLIPSIS, color, false);
+ }
+}
+
+void CMilkMenu::DrawMenu(RECT rect, int xR, int yB, int bCalcRect, RECT* pCalcRect)
+{
+ // 'rect' is the bounding rectangle in which we're allowed to draw the menu;
+ // it's .top member is incremented as we draw downward.
+ // if bCalcRect==1, then we return pCalcRect as the area that the menu actually
+ // occupies, excluding any tooltips.
+
+ if (bCalcRect!=0 && pCalcRect==NULL)
+ return;
+
+ if (bCalcRect)
+ {
+ pCalcRect->left = rect.left;
+ pCalcRect->right = rect.left;
+ pCalcRect->top = rect.top;
+ pCalcRect->bottom = rect.top;
+ }
+
+ if (!m_bEditingCurSel)
+ {
+ int nLines = (rect.bottom - rect.top - PLAYLIST_INNER_MARGIN*2) / g_plugin.GetFontHeight(SIMPLE_FONT) - 1; // save 1 line for the tooltip
+ if (nLines<1) return;
+ int nStart = (m_nCurSel/nLines)*nLines;
+
+ int nLinesDrawn = 0;
+ int i = 0;
+ for (i=0; i < m_nChildMenus; i++)
+ {
+ if (i >= nStart && i < nStart+nLines)
+ {
+ //rect.top += g_plugin.GetFont(SIMPLE_FONT)->DrawText(m_ppChildMenu[i]->m_szMenuName, -1, pRect, DT_SINGLELINE | DT_END_ELLIPSIS, (i == m_nCurSel) ? MENU_HILITE_COLOR : MENU_COLOR);
+ if (m_ppChildMenu[i]->IsEnabled()) {
+ MyMenuTextOut(SIMPLE_FONT, m_ppChildMenu[i]->m_szMenuName, (i == m_nCurSel) ? MENU_HILITE_COLOR : MENU_COLOR, &rect, bCalcRect, pCalcRect);
+ nLinesDrawn++;
+ }
+
+ if (g_plugin.m_bShowMenuToolTips && i == m_nCurSel && !bCalcRect)
+ {
+ // tooltip:
+ g_plugin.DrawTooltip(WASABI_API_LNGSTRINGW(IDS_SZ_MENU_NAV_TOOLTIP), xR, yB);
+ }
+ }
+ }
+
+ CMilkMenuItem *pItem = m_pFirstChildItem;
+
+ while (pItem && nLinesDrawn < nStart+nLines)
+ {
+ if (!pItem->m_bEnabled)
+ {
+ pItem = pItem->m_pNext;
+ i++;
+ continue;
+ }
+
+ size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState;
+ if (i >= nStart)
+ {
+ wchar_t szItemText[256];
+ switch(pItem->m_type)
+ {
+ case MENUITEMTYPE_STRING:
+ lstrcpyW(szItemText, pItem->m_szName);
+ break;
+ case MENUITEMTYPE_BOOL:
+ swprintf(szItemText, L"%s [%s]", pItem->m_szName,
+ WASABI_API_LNGSTRINGW(*((bool *)(addr)) ? IDS_ON : IDS_OFF));
+ break;
+ default:
+ lstrcpyW(szItemText, pItem->m_szName);
+ break;
+ }
+
+ if (i == m_nCurSel)
+ {
+ MyMenuTextOut(SIMPLE_FONT, szItemText, MENU_HILITE_COLOR, &rect, bCalcRect, pCalcRect);
+
+ if (g_plugin.m_bShowMenuToolTips && !bCalcRect)
+ {
+ // tooltip:
+ g_plugin.DrawTooltip(pItem->m_szToolTip, xR, yB);
+ }
+ }
+ else
+ {
+ MyMenuTextOut(SIMPLE_FONT, szItemText, MENU_COLOR, &rect, bCalcRect, pCalcRect);
+ }
+ nLinesDrawn++;
+ }
+
+ pItem = pItem->m_pNext;
+ i++;
+ }
+ }
+ else
+ {
+ // editing current selection
+
+ // find the item
+ CMilkMenuItem *pItem = m_pFirstChildItem;
+ for (int i=m_nChildMenus; i < m_nCurSel; i++)
+ pItem = pItem->m_pNext;
+ size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState;
+
+ wchar_t buf[256];
+
+ MyMenuTextOut(SIMPLE_FONT, WASABI_API_LNGSTRINGW(IDS_USE_UP_DOWN_ARROW_KEYS), MENU_COLOR, &rect, bCalcRect, pCalcRect);
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_CURRENT_VALUE_OF_X), pItem->m_szName);
+ MyMenuTextOut(SIMPLE_FONT, buf, MENU_COLOR, &rect, bCalcRect, pCalcRect);
+
+ switch(pItem->m_type)
+ {
+ case MENUITEMTYPE_INT:
+ swprintf(buf, L" %d ", *((int*)(addr)) );
+ break;
+ case MENUITEMTYPE_FLOAT:
+ case MENUITEMTYPE_LOGFLOAT:
+ swprintf(buf, L" %5.3f ", *((float*)(addr)) );
+ break;
+ case MENUITEMTYPE_BLENDABLE:
+ case MENUITEMTYPE_LOGBLENDABLE:
+ swprintf(buf, L" %5.3f ", ((CBlendableFloat*)addr)->eval(-1) );
+ break;
+ default:
+ lstrcpyW(buf, L" ? ");
+ break;
+ }
+
+ MyMenuTextOut(SIMPLE_FONT, buf, MENU_HILITE_COLOR, &rect, bCalcRect, pCalcRect);
+
+ // tooltip:
+ if (g_plugin.m_bShowMenuToolTips && !bCalcRect)
+ {
+ g_plugin.DrawTooltip(pItem->m_szToolTip, xR, yB);
+ }
+ }
+}
+
+void CMilkMenu::OnWaitStringAccept(wchar_t *szNewString)
+{
+ m_bEditingCurSel = false;
+
+ // find the item
+ CMilkMenuItem *pItem = m_pFirstChildItem;
+ for (int i=m_nChildMenus; i < m_nCurSel; i++)
+ pItem = pItem->m_pNext;
+ size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState;
+
+ assert(pItem->m_type == MENUITEMTYPE_STRING);
+
+ // apply the edited string
+ lstrcpyW((wchar_t *)(addr), szNewString);
+
+ // if user gave us a callback function pointer, call it now
+ if (pItem->m_pCallbackFn)
+ {
+ pItem->m_pCallbackFn(0, 0);
+ }
+
+ // remember the last cursor position
+ pItem->m_nLastCursorPos = g_plugin.m_waitstring.nCursorPos;
+}
+
+//----------------------------------------
+
+LRESULT CMilkMenu::HandleKeydown(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // all WM_KEYDOWNS that your app gets when a menu is up should be handled here,
+ // by the menu that is currently active.
+
+ // return value: FALSE if it handled the key; TRUE if it didn't
+
+ int nRepeat = LOWORD(lParam);
+ int rep;
+
+ if (!m_bEditingCurSel)
+ {
+ switch(wParam)
+ {
+ case VK_UP:
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ if (m_nCurSel==0)
+ break;
+ do {
+ m_nCurSel--;
+ } while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel));
+ }
+ if (m_nCurSel < 0) m_nCurSel = 0;//m_nChildMenus + m_nChildItems - 1;
+ while (m_nCurSel < m_nChildMenus + m_nChildItems - 1 && !ItemIsEnabled(m_nCurSel))
+ m_nCurSel++;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_DOWN:
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ if (m_nCurSel == m_nChildMenus + m_nChildItems - 1)
+ break;
+ do {
+ m_nCurSel++;
+ } while (m_nCurSel < m_nChildMenus + m_nChildItems - 1 && !ItemIsEnabled(m_nCurSel));
+ }
+ if (m_nCurSel >= m_nChildMenus + m_nChildItems) m_nCurSel = m_nChildMenus + m_nChildItems - 1;//0;
+ while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel))
+ m_nCurSel--;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_HOME:
+ m_nCurSel = 0;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_END:
+ m_nCurSel = m_nChildMenus + m_nChildItems - 1;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_ESCAPE:
+ g_plugin.m_UI_mode = UI_REGULAR;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_BACK:
+ case VK_LEFT:
+ if (m_pParentMenu)
+ g_plugin.m_pCurMenu = m_pParentMenu;
+ else
+ g_plugin.m_UI_mode = UI_REGULAR; // exit the menu
+ return 0; // we processed (or absorbed) the key
+
+ case VK_RETURN:
+ case VK_RIGHT:
+ case VK_SPACE:
+ if (m_nCurSel < m_nChildMenus)
+ {
+ // go to sub-menu
+ g_plugin.m_pCurMenu = m_ppChildMenu[m_nCurSel];
+ }
+ else
+ {
+ // find the item
+ CMilkMenuItem *pItem = GetCurItem();
+ size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState;
+
+ float fTemp;
+
+ // begin editing the item
+
+ switch(pItem->m_type)
+ {
+ case MENUITEMTYPE_UIMODE:
+ g_plugin.m_UI_mode = (ui_mode)pItem->m_wParam;
+
+ if (g_plugin.m_UI_mode==UI_IMPORT_WAVE ||
+ g_plugin.m_UI_mode==UI_EXPORT_WAVE ||
+ g_plugin.m_UI_mode==UI_IMPORT_SHAPE ||
+ g_plugin.m_UI_mode==UI_EXPORT_SHAPE)
+ {
+ g_plugin.m_bPresetLockedByCode = true;
+
+ // enter WaitString mode
+ g_plugin.m_waitstring.bActive = true;
+ g_plugin.m_waitstring.bFilterBadChars = false;
+ g_plugin.m_waitstring.bDisplayAsCode = false;
+ g_plugin.m_waitstring.nSelAnchorPos = -1;
+ g_plugin.m_waitstring.nMaxLen = min(sizeof(g_plugin.m_waitstring.szText)-1, MAX_PATH - wcslen(g_plugin.GetPresetDir()) - 6); // 6 for the extension + null char. We set this because win32 LoadFile, MoveFile, etc. barf if the path+filename+ext are > MAX_PATH chars.
+ swprintf(g_plugin.m_waitstring.szText, L"%sfile.dat", g_plugin.m_szPresetDir);
+ if (g_plugin.m_UI_mode==UI_IMPORT_WAVE || g_plugin.m_UI_mode==UI_IMPORT_SHAPE)
+ WASABI_API_LNGSTRINGW_BUF(IDS_LOAD_FROM_FILE,g_plugin.m_waitstring.szPrompt,512);
+ else
+ WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_TO_FILE,g_plugin.m_waitstring.szPrompt,512);
+ g_plugin.m_waitstring.szToolTip[0] = 0;
+ g_plugin.m_waitstring.nCursorPos = wcslen(g_plugin.m_waitstring.szText); // set the starting edit position
+ }
+ break;
+ case MENUITEMTYPE_BOOL:
+ *((bool *)addr) = !(*((bool *)addr));
+ break;
+ case MENUITEMTYPE_INT:
+ m_bEditingCurSel = true;
+ pItem->m_original_value = (LPARAM)(*((int*)(addr)));
+ break;
+ case MENUITEMTYPE_FLOAT:
+ case MENUITEMTYPE_LOGFLOAT:
+ m_bEditingCurSel = true;
+ pItem->m_original_value = (LPARAM)(*((float*)(addr))*10000L);
+ break;
+ case MENUITEMTYPE_BLENDABLE:
+ case MENUITEMTYPE_LOGBLENDABLE:
+ m_bEditingCurSel = true;
+ {
+ //CBlendableFloat *p = (CBlendableFloat*)(pItem->m_pVariable);
+ //*p = 0.99f;
+ fTemp = ((CBlendableFloat*)addr)->eval(-1);//p->eval(-1);
+ }
+ pItem->m_original_value = (LPARAM)(fTemp*10000L);
+ break;
+ case MENUITEMTYPE_STRING:
+ // enter waitstring mode. ***This function will cease to receive keyboard input
+ // while the string is being edited***
+ g_plugin.m_UI_mode = UI_EDIT_MENU_STRING;
+ g_plugin.m_waitstring.bActive = true;
+ g_plugin.m_waitstring.bFilterBadChars = false;
+ g_plugin.m_waitstring.bDisplayAsCode = true;
+ g_plugin.m_waitstring.nSelAnchorPos = -1;
+ g_plugin.m_waitstring.nMaxLen = pItem->m_wParam ? pItem->m_wParam : 8190;
+ g_plugin.m_waitstring.nMaxLen = min(g_plugin.m_waitstring.nMaxLen, sizeof(g_plugin.m_waitstring.szText)-16);
+ //lstrcpyW(g_plugin.m_waitstring.szText, (wchar_t *)addr);
+ lstrcpyA((char*)g_plugin.m_waitstring.szText, (char*)addr);
+ swprintf(g_plugin.m_waitstring.szPrompt, WASABI_API_LNGSTRINGW(IDS_ENTER_THE_NEW_STRING), pItem->m_szName);
+ lstrcpyW(g_plugin.m_waitstring.szToolTip, pItem->m_szToolTip);
+ g_plugin.m_waitstring.nCursorPos = strlen/*wcslen*/((char*)g_plugin.m_waitstring.szText);
+ if (pItem->m_nLastCursorPos < g_plugin.m_waitstring.nCursorPos)
+ g_plugin.m_waitstring.nCursorPos = pItem->m_nLastCursorPos;
+ break;
+ /*
+ case MENUITEMTYPE_OSC:
+ m_bEditingCurSel = true;
+ pItem->m_bEditingSubSel = false;
+ break;
+ */
+ }
+ }
+ return 0; // we processed (or absorbed) the key
+
+ default:
+ // key wasn't handled
+ return TRUE;
+ break;
+ }
+ }
+ else // m_bEditingCurSel
+ {
+ float fMult = 1.0f;
+ bool bDec;
+
+ // find the item
+ CMilkMenuItem *pItem = m_pFirstChildItem;
+ for (int i=m_nChildMenus; i < m_nCurSel; i++)
+ pItem = pItem->m_pNext;
+ size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState;
+
+ switch(wParam)
+ {
+ case VK_ESCAPE: // exit Edit mode & restore original value
+
+ switch(pItem->m_type)
+ {
+ case MENUITEMTYPE_INT:
+ m_bEditingCurSel = false;
+ *((int *)addr) = (int)pItem->m_original_value;
+ break;
+ case MENUITEMTYPE_FLOAT:
+ m_bEditingCurSel = false;
+ *((float *)addr) = ((float)pItem->m_original_value)*0.0001f;
+ break;
+ case MENUITEMTYPE_LOGFLOAT:
+ m_bEditingCurSel = false;
+ *((float *)addr) = ((float)pItem->m_original_value)*0.0001f;
+ break;
+ case MENUITEMTYPE_BLENDABLE:
+ m_bEditingCurSel = false;
+ *((CBlendableFloat *)(addr)) = ((float)(pItem->m_original_value))*0.0001f;
+ break;
+ case MENUITEMTYPE_LOGBLENDABLE:
+ m_bEditingCurSel = false;
+ *((CBlendableFloat *)(addr)) = ((float)(pItem->m_original_value))*0.0001f;
+ break;
+ //case MENUITEMTYPE_STRING:
+ // won't ever happen - see OnWaitStringCancel()
+ }
+ return 0;
+
+ case VK_RETURN:
+
+ //if (pItem->m_type == MENUITEMTYPE_STRING)
+ // ... won't ever happen - see OnWaitStringAccept()
+
+ m_bEditingCurSel = false;
+ return 0;
+
+
+ case VK_NEXT:
+ case VK_PRIOR:
+ fMult *= 10.0f;
+ // break intentionally left out here...
+ case VK_UP:
+ case VK_DOWN:
+
+ {
+ USHORT mask = 1 << (sizeof(USHORT)*8 - 1); // we want the highest-order bit
+ bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+ //bool bCtrlHeldDown = (GetKeyState(VK_CONTROL) & mask) != 0;
+ if (bShiftHeldDown && (wParam==VK_UP || wParam==VK_DOWN))
+ fMult *= 0.1f;
+ }
+
+ bDec = (wParam == VK_DOWN || wParam == VK_NEXT);
+
+ switch(pItem->m_type)
+ {
+ case MENUITEMTYPE_INT:
+ {
+ int *pInt = ((int *)addr);
+ if (fMult<1) fMult=1;
+ (*pInt) += (int)((bDec) ? -fMult : fMult);
+ if (*pInt < pItem->m_fMin) *pInt = (int)pItem->m_fMin;
+ if (*pInt > pItem->m_fMax) *pInt = (int)pItem->m_fMax;
+ }
+ break;
+ case MENUITEMTYPE_FLOAT:
+ {
+ float *pFloat = ((float *)addr);
+ float fInc = (pItem->m_fMax - pItem->m_fMin)*0.01f*fMult;
+ (*pFloat) += (bDec) ? -fInc : fInc;
+ if (*pFloat < pItem->m_fMin) *pFloat = pItem->m_fMin;
+ if (*pFloat > pItem->m_fMax) *pFloat = pItem->m_fMax;
+ }
+ break;
+ case MENUITEMTYPE_LOGFLOAT:
+ {
+ float *pFloat = ((float *)addr);
+ (*pFloat) *= (bDec) ? powf(1.0f/1.01f, fMult) : powf(1.01f, fMult);
+ if (*pFloat < pItem->m_fMin) *pFloat = pItem->m_fMin;
+ if (*pFloat > pItem->m_fMax) *pFloat = pItem->m_fMax;
+ }
+ break;
+ case MENUITEMTYPE_BLENDABLE:
+ {
+ CBlendableFloat *pBlend = ((CBlendableFloat *)addr);
+ float fInc = (pItem->m_fMax - pItem->m_fMin)*0.01f*fMult;
+ (*pBlend) += (bDec) ? -fInc : fInc;
+ if (pBlend->eval(-1) < pItem->m_fMin) *pBlend = pItem->m_fMin;
+ if (pBlend->eval(-1) > pItem->m_fMax) *pBlend = pItem->m_fMax;
+ }
+ break;
+ case MENUITEMTYPE_LOGBLENDABLE:
+ {
+ CBlendableFloat *pBlend = ((CBlendableFloat *)addr);
+ (*pBlend) *= (bDec) ? powf(1.0f/1.01f, fMult) : powf(1.01f, fMult);
+ if (pBlend->eval(-1) < pItem->m_fMin) *pBlend = pItem->m_fMin;
+ if (pBlend->eval(-1) > pItem->m_fMax) *pBlend = pItem->m_fMax;
+ }
+ break;
+ /*
+ case MENUITEMTYPE_OSC:
+ if (pItem->m_bEditingSubSel)
+ {
+ if (wParam == VK_UP)
+ {
+ pItem->m_nSubSel--;
+ if (pItem->m_nSubSel < 0) pItem->m_nSubSel = 4;
+ }
+ else if (wParam == VK_DOWN)
+ {
+ pItem->m_nSubSel++;
+ if (pItem->m_nSubSel > 4) pItem->m_nSubSel = 0;
+ }
+ }
+ else
+ {
+ switch(pItem->m_nSubSel)
+ {
+ also to do: make 'drawtext' draw it properly
+
+ case 0:
+ fixme - what are the bounds for each type? and are incs constant or log?
+ break;
+ case 1:
+ fixme
+ break;
+ case 2:
+ fixme
+ break;
+ case 3:
+ fixme
+ break;
+ case 4:
+ fixme
+ break;
+ }
+ }
+ break;
+ */
+ }
+ return 0;
+
+ default:
+ // key wasn't handled
+ return TRUE;
+ break;
+ }
+ }
+
+ return TRUE;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/menu.h b/Src/Plugins/Visualization/vis_milk2/menu.h
new file mode 100644
index 00000000..2668032e
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/menu.h
@@ -0,0 +1,126 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _MILKDROP_MENU_H_
+#define _MILKDROP_MENU_H_ 1
+
+//----------------------------------------
+
+#include <windows.h>
+
+//----------------------------------------
+
+typedef enum {
+ MENUITEMTYPE_BUNK,
+ MENUITEMTYPE_BOOL,
+ MENUITEMTYPE_INT,
+ MENUITEMTYPE_FLOAT,
+ MENUITEMTYPE_LOGFLOAT,
+ MENUITEMTYPE_BLENDABLE,
+ MENUITEMTYPE_LOGBLENDABLE,
+ MENUITEMTYPE_STRING,
+ MENUITEMTYPE_UIMODE,
+ //MENUITEMTYPE_OSC,
+} MENUITEMTYPE;
+#define MAX_CHILD_MENUS 16
+typedef void (*MilkMenuCallbackFnPtr)(LPARAM param1, LPARAM param2); // MilkMenuCallbackFnPtr is synonym for "pointer to function returning void, and taking 2 lparams"
+
+//----------------------------------------
+class CMilkMenuItem
+{
+public:
+ CMilkMenuItem();
+ ~CMilkMenuItem();
+
+ wchar_t m_szName[64];
+ wchar_t m_szToolTip[1024];
+ MENUITEMTYPE m_type;
+ float m_fMin; // note: has different meanings based on the MENUITEMTYPE
+ float m_fMax; // note: has different meanings based on the MENUITEMTYPE
+ unsigned int m_wParam;
+ unsigned int m_lParam;
+ MilkMenuCallbackFnPtr m_pCallbackFn; // Callback Function pointer; if non-NULL, this functino will be called whenever the menu item is modified by the user.
+ ptrdiff_t m_var_offset; // dist of variable's mem loc., in bytes, from pg->m_pState.
+ LPARAM m_original_value; // can hold a float or int
+ int m_nLastCursorPos; // for strings; remembers most recent pos. of the cursor
+ bool m_bEnabled;
+
+ // special data used for MENUITEMTYPE_OSCILLATOR:
+ //int m_nSubSel;
+ //bool m_bEditingSubSel;
+
+ CMilkMenuItem *m_pNext;
+};
+//----------------------------------------
+
+//----------------------------------------
+class CMilkMenu
+{
+public:
+ CMilkMenu();
+ ~CMilkMenu();
+
+ void Init(wchar_t *szName);
+ void Finish();
+ void AddChildMenu(CMilkMenu *pChildMenu);
+ void AddItem(wchar_t *szName, void *var, MENUITEMTYPE type, wchar_t *szToolTip,
+ float min=0, float max=0, MilkMenuCallbackFnPtr pCallback=NULL,
+ unsigned int wParam=0, unsigned int lParam=0);
+ void SetParentPointer(CMilkMenu *pParentMenu) { m_pParentMenu = pParentMenu; }
+ LRESULT HandleKeydown(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+ void DrawMenu(RECT rect, int xR, int yB, int bCalcRect=0, RECT* pCalcRect=NULL);
+ void OnWaitStringAccept(wchar_t *szNewString);
+ void EnableItem(wchar_t* szName, bool bEnable);
+ CMilkMenuItem* GetCurItem() // NOTE: ONLY WORKS IF AN *ITEM* IS HIGHLIGHTED; NOT A CHILD MENU
+ {
+ CMilkMenuItem *pItem = m_pFirstChildItem;
+ for (int i=m_nChildMenus; i < m_nCurSel; i++)
+ pItem = pItem->m_pNext;
+ return pItem;
+ }
+ const wchar_t* GetName() { return m_szMenuName; }
+ void Enable(bool bEnabled) { m_bEnabled = bEnabled; }
+ bool IsEnabled() { return m_bEnabled; }
+ bool ItemIsEnabled(int i);
+
+protected:
+ void Reset();
+ CMilkMenu *m_pParentMenu;
+ CMilkMenu *m_ppChildMenu[MAX_CHILD_MENUS]; // pointers are kept here, but these should be cleaned up by the app.
+ CMilkMenuItem *m_pFirstChildItem; // linked list; these are dynamically allocated, and automatically cleaned up in destructor
+ wchar_t m_szMenuName[64];
+ int m_nChildMenus;
+ int m_nChildItems;
+ int m_nCurSel;
+ bool m_bEditingCurSel;
+ bool m_bEnabled;
+};
+//----------------------------------------
+
+#endif //_MILKDROP_MENU_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/milkdrop.nsi b/Src/Plugins/Visualization/vis_milk2/milkdrop.nsi
new file mode 100644
index 00000000..c10333e6
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/milkdrop.nsi
@@ -0,0 +1,439 @@
+; LICENSE
+; -------
+; Copyright 2005-2013 Nullsoft, Inc.
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+; are permitted provided that the following conditions are met:
+;
+; * Redistributions of source code must retain the above copyright notice,
+; this list of conditions and the following disclaimer.
+;
+; * Redistributions in binary form must reproduce the above copyright notice,
+; this list of conditions and the following disclaimer in the documentation
+; and/or other materials provided with the distribution.
+;
+; * Neither the name of Nullsoft nor the names of its contributors may be used to
+; endorse or promote products derived from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+; FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+; IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+; OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+; ----------------------------------------------------------------
+; NOTE: this .nsi script was last built with 'makensis.exe'
+; version 1.98. If you go to install it (unchanged) and get errors,
+; try tracking down that older version, or try to figure out what
+; has changed since then. You can get NSIS at:
+;
+; http://www.nullsoft.com/free/nsis/
+;
+; This installer will produce a single EXE file that, when run,
+; will decompress and install your plugin and all of its data files
+; to Winamp 2 or Winamp 3.
+; ----------------------------------------------------------------
+; MODIFYING THIS SCRIPT TO CREATE AN INSTALLER FOR YOUR OWN PLUGIN:
+; ----------------------------------------------------------------
+; 1) there are three sections below, each marked 'EDIT THIS SECTION
+; [x/3]' where 'x' is the section number. These are the 3
+; places where you need to make changes to customize this
+; installer script for your particular plugin. Go to each
+; and make the changes, reading the comments there for
+; more information.
+; 2) download NSIS from http://www.nullsoft.com/free/nsis/, if you
+; haven't already.
+; 3) run the command 'makensis.exe installer.nsi' to build
+; the executable. (note: ignore the warning message about
+; 'InstallRegKey' being used multiple times; this is necessary
+; to determine whether Winamp 2 or 3 is a better candidate
+; for the install.)
+; ----------------------------------------------------------------
+; WHAT THIS INSTALLER SCRIPT DOES:
+; ----------------------------------------------------------------
+; If Winamp 2 is installed, it will install your plugin to Winamp 2,
+; in the directory Winamp\Plugins (or whatever is specified as the
+; vis plugins path, in Winamp\winamp.ini). It will also select
+; the plugin as the current plugin. (Note that Winamp must be
+; closed to do this, so if it's open, the installer will ask the
+; user to close it before proceeding.) At the end of a successful
+; install, it asks if they'd like to run Winamp.
+;
+; If Winamp 2 is not present but Winamp 3 is, or if the user manually
+; selects the Winamp 3 directory to install to, the plugin will be
+; installed to Winamp 3 as a classic visualization plugin, to the
+; directory Winamp3\Plugins. At install time, if ClassicVis is not
+; installed, it will prompt the user to go download it. If they
+; don't download it, it will tell them the installation failed.
+; If they already had it, or after they presumably download it,
+; the installer will briefly tell them how to select their new
+; plugin and run it in Winamp 3, using ClassicVis. Finally, at
+; the end of a successful install, it asks if they'd like to run
+; Winamp 3.
+; ----------------------------------------------------------------
+
+
+
+; -------------------- EDIT THIS SECTION [1/3] --------------------
+; -------------------- EDIT THIS SECTION [1/3] --------------------
+; -------------------- EDIT THIS SECTION [1/3] --------------------
+
+ !define PLUGIN_NAME "MilkDrop 2" ; Brief name of the component. Can have spaces in it.
+ !define INSTALL_CAPTION "MilkDrop 2.2 Setup" ; Caption for the installer dialog
+ !define PLUGIN_DLL "vis_milk2.dll" ; The filename of the actual plugin
+ !define PLUGIN_OUTFILE "milkdrop_2.exe" ; Name of the installer to create
+
+; ----------------------- END SECTION [1/3] -----------------------
+; ----------------------- END SECTION [1/3] -----------------------
+; ----------------------- END SECTION [1/3] -----------------------
+
+; ----------------------------------------------------------------
+Name ${PLUGIN_NAME}
+Caption "${INSTALL_CAPTION}"
+OutFile ${PLUGIN_OUTFILE}
+; ----------------------------------------------------------------
+
+; to determine the install directory, we start with Program Files\Winamp.
+; then, if winamp 3 is found, override this and use that directory.
+; finally, if winamp 2 is found, override again and use that directory.
+InstallDir $PROGRAMFILES\Winamp
+InstallDirRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\Winamp3" "UninstallString"
+InstallDirRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\Winamp" "UninstallString"
+DirText \
+ "The installer has determined that this is the path to Winamp.$\rIf it is not correct, please change it. You will not be able to proceed$\runtil a valid path is found." \
+ "Select the directory in which Winamp 2 or 3 is installed:"
+
+Function .onInit
+ IfFileExists $INSTDIR\winamp.exe End ; else if winamp.exe found (winamp2), we're good
+ IfFileExists $INSTDIR\winamp3.exe End ; if winamp3.exe found (winamp3), we're good
+ IfFileExists $INSTDIR\studio.exe End ; or if studio.exe found (older version of winamp3), we're good
+ ; the above will work fine if winamp 2 or 3 is installed,
+ ; but will break if winamp 2 or 3 was uninstalled *but the directory remains.*
+ IfFileExists $PROGRAMFILES\Winamp\winamp.exe SelectNaturalWinamp2 ; last but not least, try the default winamp 2 directory
+ IfFileExists $PROGRAMFILES\Winamp3\winamp3.exe SelectNaturalWinamp3 ; otherwise, try the default winamp 3 directory
+ IfFileExists $PROGRAMFILES\Winamp3\studio.exe SelectNaturalWinamp3 ; otherwise, try the default winamp 3 directory
+ ; if all of these failed, no good path to Winamp (2 or 3) could be found,
+ ; and the 'Next' button will be disabled until the user can specify
+ ; the correct folder.
+ Goto End
+
+ SelectNaturalWinamp3:
+ strcpy $INSTDIR $PROGRAMFILES\Winamp3
+ goto End
+
+ SelectNaturalWinamp2:
+ strcpy $INSTDIR $PROGRAMFILES\Winamp
+ goto End
+
+ End:
+FunctionEnd
+
+
+Function .onVerifyInstDir
+ IfFileExists $INSTDIR\Winamp.exe DirOk
+ IfFileExists $INSTDIR\Winamp3.exe DirOk
+ IfFileExists $INSTDIR\Studio.exe DirOk
+ Abort ; leaves the directory as the selected one, but disables the 'Next' button...
+
+ DirOk:
+FunctionEnd
+
+
+
+
+
+Function QueryWinampVisPath
+ ; input: $INSTDIR, the currently-selected install dir (path to winamp)
+ ; output: $1, the path to the winamp vis plugins subdirectory
+ ; -for winamp 3x, this is just $INSTDIR\plugins
+ ; -for winamp 2x, it comes from the winamp.ini file
+ ; (or just $INSTDIR\plugins if there is an error reading it.)
+ IfFileExists $INSTDIR\Winamp.exe CaseWinamp2
+ IfFileExists $INSTDIR\Winamp3.exe CaseWinamp3
+ IfFileExists $INSTDIR\Studio.exe CaseWinamp3 ; legacy check
+ goto CaseImpossible
+
+ CaseWinamp2:
+ StrCpy $1 $INSTDIR\Plugins\MilkDrop2
+ ReadINIStr $8 $INSTDIR\winamp.ini Winamp VisDir
+ StrCmp $8 "" End
+ IfFileExists $8 0 End
+ StrCpy $1 $8 ; update dir
+ goto end
+
+ CaseWinamp3:
+ CaseImpossible:
+ StrCpy $1 $INSTDIR\Plugins\MilkDrop2
+ goto end
+
+ End:
+FunctionEnd
+
+
+; The stuff to install
+Section ""
+
+ CloseWinamp2:
+ ; make sure winamp is closed before we 1) try to install files
+ ; and 2) (later) edit winamp.ini. for 1), if they're running
+ ; (or were running) some other vms-based plugin using
+ ; vms_desktop.dll, then if winamp is still open, the installer
+ ; could have trouble overwriting vms_desktop.dll, or other files;
+ ; the user would get an abort/retry/ignore box, but it's easier
+ ; to just play it safe.
+ FindWindow $R0 "winamp v1.x"
+ StrCmp $R0 0 "" RequestCloseWinamp2
+ goto Winamp2Closed
+ RequestCloseWinamp2:
+ MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "Winamp is currently running; please close it,$\rand then hit OK to continue..." \
+ IDCANCEL WarnWinampStillOpen
+ goto CloseWinamp2
+ WarnWinampStillOpen:
+ FindWindow $R0 "winamp v1.x"
+ StrCmp $R0 0 "" WarnWinampStillOpen2
+ goto Winamp2Closed
+ WarnWinampStillOpen2:
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Warning: Winamp is still open; as a result, the installer$\rwill not be able to set ${PLUGIN_NAME} as the default plugin; you will$\rhave to do this yourself.$\r$\rTo do so, wait until the installation is finished. Then bring up $\rWinamp and hit CTRL+K. From there, you will be able to select$\r${PLUGIN_NAME} from the list of visualization plug-ins, and it will$\rbecome the new default."
+ goto Winamp2Closed
+ Winamp2Closed:
+
+ ; this function sets $1 to point to the 'winamp\plugins\milkdrop2' folder:
+ ; (see function definition above)
+ Call QueryWinampVisPath
+
+ ; -------------------- EDIT THIS SECTION [2/3] --------------------
+ ; -------------------- EDIT THIS SECTION [2/3] --------------------
+ ; -------------------- EDIT THIS SECTION [2/3] --------------------
+
+ ; LIST FILES TO INCLUDE WITH THE INSTALLER
+
+ ; For each file we want to install onto the destination system,
+ ; we first set the output directory (relative to $1, which is
+ ; the PLUGINS directory) and then list files. The paths for
+ ; the files will be local paths on your hard disk, but fear not -
+ ; the files will be placed in the current output directory
+ ; (as last set by SetOutPath) on the destination system.
+
+ ; So, first, we set the current output path (the folder to which
+ ; files will be decompressed on the user's system) to '$1',
+ ; which is the path to their winamp plugins folder.
+
+ SetOutPath $1
+ File "C:\program files\winamp\plugins\${PLUGIN_DLL}"
+
+ SetOutPath $1\Milkdrop2\config
+ File "C:\program files\winamp\plugins\milkdrop2\config\milk_msg.ini"
+ File "C:\program files\winamp\plugins\milkdrop2\config\milk_img.ini"
+ ;File "C:\program files\winamp\plugins\milkdrop2\config\milkdrop.ini" ;this one will be generated - do not install
+
+ SetOutPath $1\Milkdrop2\data
+ File "C:\program files\winamp\plugins\milkdrop2\data\vms_desktop.dll"
+ File "C:\program files\winamp\plugins\milkdrop2\data\comp_ps.fx"
+ File "C:\program files\winamp\plugins\milkdrop2\data\comp_vs.fx"
+ File "C:\program files\winamp\plugins\milkdrop2\data\warp_ps.fx"
+ File "C:\program files\winamp\plugins\milkdrop2\data\warp_vs.fx"
+ File "C:\program files\winamp\plugins\milkdrop2\data\include.fx"
+
+ SetOutPath $1\Milkdrop2\docs
+ File "C:\program files\winamp\plugins\milkdrop2\docs\milkdrop.html"
+ File "C:\program files\winamp\plugins\milkdrop2\docs\milkdrop_preset_authoring.html"
+ File "C:\program files\winamp\plugins\milkdrop2\docs\q_and_t_vars.gif"
+
+ SetOutPath $1\Milkdrop2\textures
+ File "C:\program files\winamp\plugins\milkdrop2\textures\*.*"
+
+ SetOutPath $1\Milkdrop2\presets
+ File "C:\program files\winamp\plugins\milkdrop2\presets\*.milk"
+
+ hmmm
+ SetOutPath $1\MilkDrop2\presets\3d
+ File "C:\program files\winamp\plugins\milkdrop2\presets\3d\*.milk"
+
+ hmmm
+ SetOutPath $1\MilkDrop2\presets\inverted
+ File "C:\program files\winamp\plugins\milkdrop2\presets\inverted\*.milk"
+
+ ; ----------------------- END SECTION [2/3] -----------------------
+ ; ----------------------- END SECTION [2/3] -----------------------
+ ; ----------------------- END SECTION [2/3] -----------------------
+
+
+ ; now time to create the Uninstaller:
+
+ IfFileExists $INSTDIR\Winamp.exe UninstWinamp2
+ IfFileExists $INSTDIR\Winamp3.exe UninstWinamp3
+ IfFileExists $INSTDIR\Studio.exe UninstWinamp3 ; legacy check
+ goto UninstDone
+
+ UninstWinamp3:
+ WriteRegStr HKLM SOFTWARE\${PLUGIN_DLL}Winamp3 "Install_Dir" "$INSTDIR"
+ WriteRegStr HKLM SOFTWARE\${PLUGIN_DLL}Winamp3 "Install_Plugins_Dir" $1
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_DLL}Winamp3" "DisplayName" "${PLUGIN_NAME} for Winamp 3 (remove only)"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_DLL}Winamp3" "UninstallString" '"$INSTDIR\uninst-${PLUGIN_DLL}.exe"'
+ WriteUninstaller "$INSTDIR\uninst-${PLUGIN_DLL}.exe"
+ CreateDirectory "$SMPROGRAMS\Winamp3\Vis Plugin Uninstallers"
+ CreateShortCut "$SMPROGRAMS\Winamp3\Vis Plugin Uninstallers\Uninstall ${PLUGIN_NAME}.lnk" "$INSTDIR\uninst-${PLUGIN_DLL}.exe" "" "$INSTDIR\uninst-${PLUGIN_DLL}.exe" 0
+ goto UninstDone
+
+ UninstWinamp2:
+ WriteRegStr HKLM SOFTWARE\${PLUGIN_DLL}Winamp "Install_Dir" "$INSTDIR"
+ WriteRegStr HKLM SOFTWARE\${PLUGIN_DLL}Winamp "Install_Plugins_Dir" $1
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_DLL}Winamp" "DisplayName" "${PLUGIN_NAME} for Winamp 2x (remove only)"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_DLL}Winamp" "UninstallString" '"$INSTDIR\uninst-${PLUGIN_DLL}.exe"'
+ WriteUninstaller "$INSTDIR\uninst-${PLUGIN_DLL}.exe"
+ CreateDirectory "$SMPROGRAMS\Winamp\Vis Plugin Uninstallers"
+ CreateShortCut "$SMPROGRAMS\Winamp\Vis Plugin Uninstallers\Uninstall ${PLUGIN_NAME}.lnk" "$INSTDIR\uninst-${PLUGIN_DLL}.exe" "" "$INSTDIR\uninst-${PLUGIN_DLL}.exe" 0
+ goto UninstDone
+
+ UninstDone:
+
+SectionEnd
+
+;----------------------------------------------------------------------
+
+UninstallText "This will uninstall the ${PLUGIN_NAME} plugin. Hit next to continue."
+ShowUninstDetails Show
+
+Section "Uninstall"
+
+ ; This section is the code that will be run when the user goes
+ ; to Uninstall the plugin.
+
+ IfFileExists $INSTDIR\Winamp.exe UninstStep1Winamp2
+ IfFileExists $INSTDIR\Winamp3.exe UninstStep1Winamp3
+ IfFileExists $INSTDIR\Studio.exe UninstStep1Winamp3 ; legacy check
+ goto UninstScriptDone
+
+ UninstStep1Winamp3:
+ ReadRegStr $1 HKLM SOFTWARE\${PLUGIN_DLL}Winamp3 "Install_Plugins_Dir"
+ goto UninstStep2
+ UninstStep1Winamp2:
+ ReadRegStr $1 HKLM SOFTWARE\${PLUGIN_DLL}Winamp "Install_Plugins_Dir"
+ goto UninstStep2
+
+ UninstStep2:
+
+ ; -------------------- EDIT THIS SECTION [3/3] --------------------
+ ; -------------------- EDIT THIS SECTION [3/3] --------------------
+ ; -------------------- EDIT THIS SECTION [3/3] --------------------
+
+ ; LIST OF FILES TO DELETE WHEN USER RUNS THE UNINSTALL
+
+ Delete "$1\${PLUGIN_DLL}"
+ ;Delete "$1\vms_desktop.dll" ** DO NOT DELETE! **
+ Delete "$1\milkdrop.html"
+ Delete "$1\milkdrop_preset_authoring.html"
+ Delete "$1\q_and_t_vars.gif"
+
+ MessageBox MB_YESNO|MB_ICONQUESTION \
+ "Clear your saved settings?:$\r $1\milkdrop_config.ini$\r $1\milk_msg.ini$\r $1\milk_img.ini" \
+ IDNO SaveSettings
+
+ Delete "$1\milkdrop_config.ini"
+ Delete "$1\milk_msg.ini"
+ Delete "$1\milk_img.ini"
+
+ SaveSettings:
+
+ MessageBox MB_YESNO|MB_ICONQUESTION \
+ "Delete all presets in these 3 directories?:$\r $1\milkdrop$\r $1\milkdrop\3d$\r $1\milkdrop\inverted" \
+ IDNO SavePresets
+
+ Delete "$1\milkdrop2\inverted\*.milk"
+ Delete "$1\milkdrop2\3d\*.milk"
+ Delete "$1\milkdrop2\*.milk"
+ RMDir "$1\milkdrop2\inverted"
+ RMDir "$1\milkdrop2\3d"
+ RMDir "$1\milkdrop2"
+
+ SavePresets:
+
+ ; ----------------------- END SECTION [3/3] -----------------------
+ ; ----------------------- END SECTION [3/3] -----------------------
+ ; ----------------------- END SECTION [3/3] -----------------------
+
+ IfFileExists $INSTDIR\Winamp.exe UninstStep3Winamp2
+ IfFileExists $INSTDIR\Winamp3.exe UninstStep3Winamp3
+ IfFileExists $INSTDIR\Studio.exe UninstStep3Winamp3 ; legacy check
+ goto UninstScriptDone
+
+ UninstStep3Winamp3:
+ DeleteRegKey HKLM SOFTWARE\${PLUGIN_DLL}Winamp3
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_DLL}Winamp3"
+ Delete $INSTDIR\uninst-${PLUGIN_DLL}.exe
+ Delete "$SMPROGRAMS\Winamp3\Vis Plugin Uninstallers\Uninstall ${PLUGIN_NAME}.lnk"
+ RMDir "$SMPROGRAMS\Winamp3\Vis Plugin Uninstallers"
+ goto UninstScriptDone
+ UninstStep3Winamp2:
+ DeleteRegKey HKLM SOFTWARE\${PLUGIN_DLL}Winamp
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_DLL}Winamp"
+ Delete $INSTDIR\uninst-${PLUGIN_DLL}.exe
+ Delete "$SMPROGRAMS\Winamp\Vis Plugin Uninstallers\Uninstall ${PLUGIN_NAME}.lnk"
+ RMDir "$SMPROGRAMS\Winamp\Vis Plugin Uninstallers"
+ goto UninstScriptDone
+
+ UninstScriptDone:
+SectionEnd
+
+;----------------------------------------------------------------------
+
+Function .onInstSuccess
+ IfFileExists $INSTDIR\Winamp.exe CaseWinamp2
+ IfFileExists $INSTDIR\Winamp3.exe CaseWinamp3
+ IfFileExists $INSTDIR\Studio.exe CaseWinamp3 ; legacy check
+ goto CaseImpossible
+
+ CaseWinamp3:
+ IfFileExists $INSTDIR\wacs\classicvis.wac ClassicVisOk
+ ; no classicvis -> give them instructions
+ MessageBox MB_YESNO|MB_ICONEXCLAMATION \
+ "IMPORTANT: You must download and install the Classic Visualization$\rComponent before ${PLUGIN_NAME} will work with Winamp 3.$\r$\rWould you like to download it now?" \
+ IDNO FailNoClassicVis
+ ExecShell "open" "http://www.winamp.com/components3/detail.jhtml?componentId=122130"
+ MessageBox MB_OK|MB_ICONINFORMATION \
+ "Your web browser will now open and allow you to download$\rthe Classic Visualization Component. Please download$\rand install it.$\r$\rOnce it is installed, open Winamp 3 and hit CTRL+P$\rto open the Preferences screen. Then, on the left,$\rscroll to 'Classic Visualizations' and select it. From there,$\ryou can easily select, configure and run any plugins$\rinstalled to Winamp 2 or 3."
+ goto end
+ FailNoClassicVis:
+ MessageBox MB_OK|MB_ICONSTOP "Installation failed."
+ goto end
+ ClassicVisOk:
+ FindWindow $R0 "STUDIO"
+ StrCmp $R0 0 "" DoneWinamp3
+ MessageBox MB_YESNO|MB_ICONQUESTION \
+ "${PLUGIN_NAME} was installed successfully.$\rWould you like to run Winamp 3 now?" \
+ IDNO DoneWinamp3
+ ; to do here: update 'oldvisname' string in the *xml* file winamp3\studio.xnf,
+ ; and set 'oldvisidx' to "0"
+ IfFileExists $INSTDIR\Winamp3.exe CaseWinamp3b
+ Exec '"$INSTDIR\studio.exe"'
+ goto DoneWinamp3
+ CaseWinamp3b:
+ Exec '"$INSTDIR\winamp3.exe"'
+ goto DoneWinamp3
+ DoneWinamp3:
+ MessageBox MB_OK "While in Winamp 3, press CTRL+P to bring up the$\rPreferences screen, then scroll down and select$\rthe 'Classic Visualizations' option. From there,$\ryou can select, configure, and run the ${PLUGIN_NAME} plugin."
+ goto end
+
+ CaseWinamp2:
+ ; note: winamp 2 should already be closed at this point.
+ WriteINIStr "$INSTDIR\Winamp.ini" "Winamp" "visplugin_name" ${PLUGIN_DLL}
+ WriteINIStr "$INSTDIR\Winamp.ini" "Winamp" "visplugin_num" "0"
+ MessageBox MB_YESNO|MB_ICONQUESTION \
+ "${PLUGIN_NAME} was installed successfully.$\r$\rWhile in Winamp, press ALT+K to configure it (optional);$\rpress CTRL+SHIFT+K to execute it.$\r$\rWould you like to run Winamp now?" \
+ IDNO end
+ Exec '"$INSTDIR\Winamp.exe"'
+ Goto end
+
+ CaseImpossible:
+ MessageBox MB_OK|MB_ICONEXCLAMATION "ERROR: unable to find winamp.exe (winamp2) or studio.exe/winamp3.exe (winamp3) in the install directory..."
+ Goto end
+
+ End:
+FunctionEnd
+
+; eof
+
diff --git a/Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.dsw b/Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.dsw
new file mode 100644
index 00000000..b5ebf318
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "plugin"=.\plugin.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.sln b/Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.sln
new file mode 100644
index 00000000..e123bc29
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/milkdrop_DX9.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29709.97
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vis_milk2", "plugin.vcxproj", "{881FB534-7396-485A-ADC2-6FBEBED7A0F4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {881FB534-7396-485A-ADC2-6FBEBED7A0F4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {881FB534-7396-485A-ADC2-6FBEBED7A0F4}.Debug|Win32.Build.0 = Debug|Win32
+ {881FB534-7396-485A-ADC2-6FBEBED7A0F4}.Release|Win32.ActiveCfg = Release|Win32
+ {881FB534-7396-485A-ADC2-6FBEBED7A0F4}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0BFB0275-73AE-400C-9070-5C0471284DD5}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/Visualization/vis_milk2/milkdropfs.cpp b/Src/Plugins/Visualization/vis_milk2/milkdropfs.cpp
new file mode 100644
index 00000000..600f7202
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/milkdropfs.cpp
@@ -0,0 +1,4801 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "plugin.h"
+#include "resource.h"
+#include "support.h"
+//#include "evallib\eval.h" // for math. expr. eval - thanks Francis! (in SourceOffSite, it's the 'vis_avs\evallib' project.)
+//#include "evallib\compiler.h"
+#include "ns-eel2/ns-eel.h"
+#include "utility.h"
+#include <assert.h>
+#include <math.h>
+
+#define D3DCOLOR_RGBA_01(r,g,b,a) D3DCOLOR_RGBA(((int)(r*255)),((int)(g*255)),((int)(b*255)),((int)(a*255)))
+#define FRAND ((warand() % 7381)/7380.0f)
+
+#define VERT_CLIP 0.75f // warning: top/bottom can get clipped if you go < 0.65!
+
+int g_title_font_sizes[] =
+{
+ // NOTE: DO NOT EXCEED 64 FONTS HERE.
+ 6, 8, 10, 12, 14, 16,
+ 20, 26, 32, 38, 44, 50, 56,
+ 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144,
+ 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,
+ 480, 512 /**/
+};
+
+//#define COMPILE_MULTIMON_STUBS 1
+//#include <multimon.h>
+
+// This function evaluates whether the floating-point
+// control Word is set to single precision/round to nearest/
+// exceptions disabled. If not, the
+// function changes the control Word to set them and returns
+// TRUE, putting the old control Word value in the passback
+// location pointed to by pwOldCW.
+static void MungeFPCW( WORD *pwOldCW )
+{
+#if 0
+ BOOL ret = FALSE;
+ WORD wTemp, wSave;
+
+ __asm fstcw wSave
+ if (wSave & 0x300 || // Not single mode
+ 0x3f != (wSave & 0x3f) || // Exceptions enabled
+ wSave & 0xC00) // Not round to nearest mode
+ {
+ __asm
+ {
+ mov ax, wSave
+ and ax, not 300h ;; single mode
+ or ax, 3fh ;; disable all exceptions
+ and ax, not 0xC00 ;; round to nearest mode
+ mov wTemp, ax
+ fldcw wTemp
+ }
+ ret = TRUE;
+ }
+ if (pwOldCW) *pwOldCW = wSave;
+ // return ret;
+#else
+ _controlfp(_PC_24, _MCW_PC); // single precision
+ _controlfp(_RC_NEAR, _MCW_RC); // round to nearest mode
+ _controlfp(_EM_ZERODIVIDE, _EM_ZERODIVIDE); // disable divide-by-zero
+#endif
+}
+
+void RestoreFPCW(WORD wSave)
+{
+ __asm fldcw wSave
+}
+
+int GetNumToSpawn(float fTime, float fDeltaT, float fRate, float fRegularity, int iNumSpawnedSoFar)
+{
+ // PARAMETERS
+ // ------------
+ // fTime: sum of all fDeltaT's so far (excluding this one)
+ // fDeltaT: time window for this frame
+ // fRate: avg. rate (spawns per second) of generation
+ // fRegularity: regularity of generation
+ // 0.0: totally chaotic
+ // 0.2: getting chaotic / very jittered
+ // 0.4: nicely jittered
+ // 0.6: slightly jittered
+ // 0.8: almost perfectly regular
+ // 1.0: perfectly regular
+ // iNumSpawnedSoFar: the total number of spawnings so far
+ //
+ // RETURN VALUE
+ // ------------
+ // The number to spawn for this frame (add this to your net count!).
+ //
+ // COMMENTS
+ // ------------
+ // The spawn values returned will, over time, match
+ // (within 1%) the theoretical totals expected based on the
+ // amount of time passed and the average generation rate.
+ //
+ // UNRESOLVED ISSUES
+ // -----------------
+ // actual results of mixed gen. (0 < reg < 1) are about 1% too low
+ // in the long run (vs. analytical expectations). Decided not
+ // to bother fixing it since it's only 1% (and VERY consistent).
+
+ float fNumToSpawnReg;
+ float fNumToSpawnIrreg;
+ float fNumToSpawn;
+
+ // compute # spawned based on regular generation
+ fNumToSpawnReg = ((fTime + fDeltaT) * fRate) - iNumSpawnedSoFar;
+
+ // compute # spawned based on irregular (random) generation
+ if (fDeltaT <= 1.0f / fRate)
+ {
+ // case 1: avg. less than 1 spawn per frame
+ if ((warand() % 16384)/16384.0f < fDeltaT * fRate)
+ fNumToSpawnIrreg = 1.0f;
+ else
+ fNumToSpawnIrreg = 0.0f;
+ }
+ else
+ {
+ // case 2: avg. more than 1 spawn per frame
+ fNumToSpawnIrreg = fDeltaT * fRate;
+ fNumToSpawnIrreg *= 2.0f*(warand() % 16384)/16384.0f;
+ }
+
+ // get linear combo. of regular & irregular
+ fNumToSpawn = fNumToSpawnReg*fRegularity + fNumToSpawnIrreg*(1.0f - fRegularity);
+
+ // round to nearest integer for result
+ return (int)(fNumToSpawn + 0.49f);
+}
+
+bool CPlugin::OnResizeTextWindow()
+{
+ /*
+ if (!m_hTextWnd)
+ return false;
+
+ RECT rect;
+ GetClientRect(m_hTextWnd, &rect);
+
+ if (rect.right - rect.left != m_nTextWndWidth ||
+ rect.bottom - rect.top != m_nTextWndHeight)
+ {
+ m_nTextWndWidth = rect.right - rect.left;
+ m_nTextWndHeight = rect.bottom - rect.top;
+
+ // first, resize fonts if necessary
+ //if (!InitFont())
+ //return false;
+
+ // then resize the memory bitmap used for double buffering
+ if (m_memDC)
+ {
+ SelectObject(m_memDC, m_oldBM); // delete our doublebuffer
+ DeleteObject(m_memDC);
+ DeleteObject(m_memBM);
+ m_memDC = NULL;
+ m_memBM = NULL;
+ m_oldBM = NULL;
+ }
+
+ HDC hdc = GetDC(m_hTextWnd);
+ if (!hdc) return false;
+
+ m_memDC = CreateCompatibleDC(hdc);
+ m_memBM = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
+ m_oldBM = (HBITMAP)SelectObject(m_memDC,m_memBM);
+
+ ReleaseDC(m_hTextWnd, hdc);
+
+ // save new window pos
+ WriteRealtimeConfig();
+ }*/
+
+ return true;
+}
+
+
+void CPlugin::ClearGraphicsWindow()
+{
+ // clear the window contents, to avoid a 1-pixel-thick border of noise that sometimes sticks around
+ /*
+ RECT rect;
+ GetClientRect(GetPluginWindow(), &rect);
+
+ HDC hdc = GetDC(GetPluginWindow());
+ FillRect(hdc, &rect, m_hBlackBrush);
+ ReleaseDC(GetPluginWindow(), hdc);
+ */
+}
+
+/*
+bool CPlugin::OnResizeGraphicsWindow()
+{
+ // NO LONGER NEEDED, SINCE PLUGIN SHELL CREATES A NEW DIRECTX
+ // OBJECT WHENEVER WINDOW IS RESIZED.
+}
+*/
+
+bool CPlugin::RenderStringToTitleTexture() // m_szSongMessage
+{
+ if (!m_lpDDSTitle) // this *can* be NULL, if not much video mem!
+ return false;
+
+ if (m_supertext.szTextW[0]==0)
+ return false;
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return false;
+
+ wchar_t szTextToDraw[512];
+ swprintf(szTextToDraw, L" %s ", m_supertext.szTextW); //add a space @ end for italicized fonts; and at start, too, because it's centered!
+
+ // Remember the original backbuffer and zbuffer
+ LPDIRECT3DSURFACE9 pBackBuffer=NULL;//, pZBuffer=NULL;
+ lpDevice->GetRenderTarget( 0, &pBackBuffer );
+ //lpDevice->GetDepthStencilSurface( &pZBuffer );
+
+ // set render target to m_lpDDSTitle
+ {
+ lpDevice->SetTexture(0, NULL);
+
+ IDirect3DSurface9* pNewTarget = NULL;
+ if (m_lpDDSTitle->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ {
+ SafeRelease(pBackBuffer);
+ //SafeRelease(pZBuffer);
+ return false;
+ }
+ lpDevice->SetRenderTarget(0, pNewTarget);
+ //lpDevice->SetDepthStencilSurface( NULL );
+ pNewTarget->Release();
+
+ lpDevice->SetTexture(0, NULL);
+ }
+
+ // clear the texture to black
+ {
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( WFVERTEX_FORMAT );
+ lpDevice->SetTexture(0, NULL);
+
+ lpDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+
+ // set up a quad
+ WFVERTEX verts[4];
+ for (int i=0; i<4; i++)
+ {
+ verts[i].x = (i%2==0) ? -1.f : 1.f;
+ verts[i].y = (i/2==0) ? -1.f : 1.f;
+ verts[i].z = 0;
+ verts[i].Diffuse = 0xFF000000;
+ }
+
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(WFVERTEX));
+ }
+
+ /*// 1. clip title if too many chars
+ if (m_supertext.bIsSongTitle)
+ {
+ // truncate song title if too long; don't clip custom messages, though!
+ int clip_chars = 32;
+ int user_title_size = GetFontHeight(SONGTITLE_FONT);
+
+ #define MIN_CHARS 8 // max clip_chars *for BIG FONTS*
+ #define MAX_CHARS 64 // max clip chars *for tiny fonts*
+ float t = (user_title_size-10)/(float)(128-10);
+ t = min(1,max(0,t));
+ clip_chars = (int)(MAX_CHARS - (MAX_CHARS-MIN_CHARS)*t);
+
+ if ((int)strlen(szTextToDraw) > clip_chars+3)
+ lstrcpy(&szTextToDraw[clip_chars], "...");
+ }*/
+
+ bool ret = true;
+
+ // use 2 lines; must leave room for bottom of 'g' characters and such!
+ RECT rect;
+ rect.left = 0;
+ rect.right = m_nTitleTexSizeX;
+ rect.top = m_nTitleTexSizeY* 1/21; // otherwise, top of '%' could be cut off (1/21 seems safe)
+ rect.bottom = m_nTitleTexSizeY*17/21; // otherwise, bottom of 'g' could be cut off (18/21 seems safe, but we want some leeway)
+
+ if (!m_supertext.bIsSongTitle)
+ {
+ // custom msg -> pick font to use that will best fill the texture
+
+ HFONT gdi_font = NULL;
+ LPD3DXFONT d3dx_font = NULL;
+
+ int lo = 0;
+ int hi = sizeof(g_title_font_sizes)/sizeof(int) - 1;
+
+ // limit the size of the font used:
+
+ //int user_title_size = GetFontHeight(SONGTITLE_FONT);
+ //while (g_title_font_sizes[hi] > user_title_size*2 && hi>4)
+ // hi--;
+
+ RECT temp;
+ while (1)//(lo < hi-1)
+ {
+ int mid = (lo+hi)/2;
+
+ // create new gdi font at 'mid' size:
+ gdi_font = CreateFontW( g_title_font_sizes[mid], 0, 0, 0, m_supertext.bBold ? 900 : 400, m_supertext.bItal, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
+ m_fontinfo[SONGTITLE_FONT].bAntiAliased ? ANTIALIASED_QUALITY : DEFAULT_QUALITY,
+ DEFAULT_PITCH, m_supertext.nFontFace );
+ if (gdi_font)
+ {
+ // create new d3dx font at 'mid' size:
+ if (pCreateFontW(
+ lpDevice,
+ g_title_font_sizes[mid],
+ 0,
+ m_supertext.bBold ? 900 : 400,
+ 1,
+ m_supertext.bItal,
+ DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ ANTIALIASED_QUALITY,//m_fontinfo[SONGTITLE_FONT].bAntiAliased ? ANTIALIASED_QUALITY : DEFAULT_QUALITY,
+ DEFAULT_PITCH,
+ m_supertext.nFontFace,
+ &d3dx_font
+ ) == D3D_OK)
+ {
+ if (lo == hi-1)
+ break; // DONE; but the 'lo'-size font is ready for use!
+
+ // compute size of text if drawn w/font of THIS size:
+ temp = rect;
+ int h = d3dx_font->DrawTextW(NULL, szTextToDraw, -1, &temp, DT_SINGLELINE | DT_CALCRECT /*| DT_NOPREFIX*/, 0xFFFFFFFF);
+
+ // adjust & prepare to reiterate:
+ if (temp.right >= rect.right || h > rect.bottom-rect.top)
+ hi = mid;
+ else
+ lo = mid;
+
+ SafeRelease(d3dx_font);
+ }
+
+ DeleteObject(gdi_font); gdi_font=NULL;
+ }
+ }
+
+ if (gdi_font && d3dx_font)
+ {
+ // do actual drawing + set m_supertext.nFontSizeUsed; use 'lo' size
+ int h = d3dx_font->DrawTextW(NULL, szTextToDraw, -1, &temp, DT_SINGLELINE | DT_CALCRECT /*| DT_NOPREFIX*/ | DT_CENTER, 0xFFFFFFFF);
+ temp.left = 0;
+ temp.right = m_nTitleTexSizeX; // now allow text to go all the way over, since we're actually drawing!
+ temp.top = m_nTitleTexSizeY/2 - h/2;
+ temp.bottom = m_nTitleTexSizeY/2 + h/2;
+ m_supertext.nFontSizeUsed = d3dx_font->DrawTextW(NULL, szTextToDraw, -1, &temp, DT_SINGLELINE /*| DT_NOPREFIX*/ | DT_CENTER, 0xFFFFFFFF);
+
+ ret = true;
+ }
+ else
+ {
+ ret = false;
+ }
+
+ // clean up font:
+ SafeRelease(d3dx_font);
+ if (gdi_font) DeleteObject(gdi_font); gdi_font=NULL;
+ }
+ else // song title
+ {
+ wchar_t* str = m_supertext.szTextW;
+
+ // clip the text manually...
+ // NOTE: DT_END_ELLIPSIS CAUSES NOTHING TO DRAW, IF YOU USE W/D3DX9!
+ int h;
+ int max_its = 6;
+ int it = 0;
+ while (it < max_its)
+ {
+ it++;
+
+ if (!str[0])
+ break;
+
+ RECT temp = rect;
+ h = m_d3dx_title_font_doublesize->DrawTextW(NULL, str, -1, &temp, DT_SINGLELINE | DT_CALCRECT /*| DT_NOPREFIX | DT_END_ELLIPSIS*/, 0xFFFFFFFF);
+ if (temp.right-temp.left <= m_nTitleTexSizeX)
+ break;
+
+ // 11/01/2009 DO - disabled as it was causing to users 'random' titles against
+ // what is expected so we now just work on the ellipse at the end approach which
+
+ // manually clip the text... chop segments off the front
+ /*wchar_t* p = wcsstr(str, L" - ");
+ if (p)
+ {
+ str = p+3;
+ continue;
+ }*/
+
+ // no more stuff to chop off the front; chop off the end w/ ...
+ int len = wcslen(str);
+ float fPercentToKeep = 0.91f * m_nTitleTexSizeX / (float)(temp.right-temp.left);
+ if (len > 8)
+ lstrcpyW( &str[ (int)(len*fPercentToKeep) ], L"...");
+ break;
+ }
+
+ // now actually draw it
+ RECT temp;
+ temp.left = 0;
+ temp.right = m_nTitleTexSizeX; // now allow text to go all the way over, since we're actually drawing!
+ temp.top = m_nTitleTexSizeY/2 - h/2;
+ temp.bottom = m_nTitleTexSizeY/2 + h/2;
+
+ // NOTE: DT_END_ELLIPSIS CAUSES NOTHING TO DRAW, IF YOU USE W/D3DX9!
+ m_supertext.nFontSizeUsed = m_d3dx_title_font_doublesize->DrawTextW(NULL, str, -1, &temp, DT_SINGLELINE /*| DT_NOPREFIX | DT_END_ELLIPSIS*/ | DT_CENTER , 0xFFFFFFFF);
+ }
+
+ // Change the rendertarget back to the original setup
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderTarget( 0, pBackBuffer );
+ //lpDevice->SetDepthStencilSurface( pZBuffer );
+ SafeRelease(pBackBuffer);
+ //SafeRelease(pZBuffer);
+
+ return ret;
+}
+
+void CPlugin::LoadPerFrameEvallibVars(CState* pState)
+{
+ // load the 'var_pf_*' variables in this CState object with the correct values.
+ // for vars that affect pixel motion, that means evaluating them at time==-1,
+ // (i.e. no blending w/blendto value); the blending of the file dx/dy
+ // will be done *after* execution of the per-vertex code.
+ // for vars that do NOT affect pixel motion, evaluate them at the current time,
+ // so that if they're blending, both states see the blended value.
+
+ // 1. vars that affect pixel motion: (eval at time==-1)
+ *pState->var_pf_zoom = (double)pState->m_fZoom.eval(-1);//GetTime());
+ *pState->var_pf_zoomexp = (double)pState->m_fZoomExponent.eval(-1);//GetTime());
+ *pState->var_pf_rot = (double)pState->m_fRot.eval(-1);//GetTime());
+ *pState->var_pf_warp = (double)pState->m_fWarpAmount.eval(-1);//GetTime());
+ *pState->var_pf_cx = (double)pState->m_fRotCX.eval(-1);//GetTime());
+ *pState->var_pf_cy = (double)pState->m_fRotCY.eval(-1);//GetTime());
+ *pState->var_pf_dx = (double)pState->m_fXPush.eval(-1);//GetTime());
+ *pState->var_pf_dy = (double)pState->m_fYPush.eval(-1);//GetTime());
+ *pState->var_pf_sx = (double)pState->m_fStretchX.eval(-1);//GetTime());
+ *pState->var_pf_sy = (double)pState->m_fStretchY.eval(-1);//GetTime());
+ // read-only:
+ *pState->var_pf_time = (double)(GetTime() - m_fStartTime);
+ *pState->var_pf_fps = (double)GetFps();
+ *pState->var_pf_bass = (double)mysound.imm_rel[0];
+ *pState->var_pf_mid = (double)mysound.imm_rel[1];
+ *pState->var_pf_treb = (double)mysound.imm_rel[2];
+ *pState->var_pf_bass_att = (double)mysound.avg_rel[0];
+ *pState->var_pf_mid_att = (double)mysound.avg_rel[1];
+ *pState->var_pf_treb_att = (double)mysound.avg_rel[2];
+ *pState->var_pf_frame = (double)GetFrame();
+ //*pState->var_pf_monitor = 0; -leave this as it was set in the per-frame INIT code!
+ for (int vi=0; vi<NUM_Q_VAR; vi++)
+ *pState->var_pf_q[vi] = pState->q_values_after_init_code[vi];//0.0f;
+ *pState->var_pf_monitor = pState->monitor_after_init_code;
+ *pState->var_pf_progress = (GetTime() - m_fPresetStartTime) / (m_fNextPresetTime - m_fPresetStartTime);
+
+ // 2. vars that do NOT affect pixel motion: (eval at time==now)
+ *pState->var_pf_decay = (double)pState->m_fDecay.eval(GetTime());
+ *pState->var_pf_wave_a = (double)pState->m_fWaveAlpha.eval(GetTime());
+ *pState->var_pf_wave_r = (double)pState->m_fWaveR.eval(GetTime());
+ *pState->var_pf_wave_g = (double)pState->m_fWaveG.eval(GetTime());
+ *pState->var_pf_wave_b = (double)pState->m_fWaveB.eval(GetTime());
+ *pState->var_pf_wave_x = (double)pState->m_fWaveX.eval(GetTime());
+ *pState->var_pf_wave_y = (double)pState->m_fWaveY.eval(GetTime());
+ *pState->var_pf_wave_mystery= (double)pState->m_fWaveParam.eval(GetTime());
+ *pState->var_pf_wave_mode = (double)pState->m_nWaveMode; //?!?! -why won't it work if set to pState->m_nWaveMode???
+ *pState->var_pf_ob_size = (double)pState->m_fOuterBorderSize.eval(GetTime());
+ *pState->var_pf_ob_r = (double)pState->m_fOuterBorderR.eval(GetTime());
+ *pState->var_pf_ob_g = (double)pState->m_fOuterBorderG.eval(GetTime());
+ *pState->var_pf_ob_b = (double)pState->m_fOuterBorderB.eval(GetTime());
+ *pState->var_pf_ob_a = (double)pState->m_fOuterBorderA.eval(GetTime());
+ *pState->var_pf_ib_size = (double)pState->m_fInnerBorderSize.eval(GetTime());
+ *pState->var_pf_ib_r = (double)pState->m_fInnerBorderR.eval(GetTime());
+ *pState->var_pf_ib_g = (double)pState->m_fInnerBorderG.eval(GetTime());
+ *pState->var_pf_ib_b = (double)pState->m_fInnerBorderB.eval(GetTime());
+ *pState->var_pf_ib_a = (double)pState->m_fInnerBorderA.eval(GetTime());
+ *pState->var_pf_mv_x = (double)pState->m_fMvX.eval(GetTime());
+ *pState->var_pf_mv_y = (double)pState->m_fMvY.eval(GetTime());
+ *pState->var_pf_mv_dx = (double)pState->m_fMvDX.eval(GetTime());
+ *pState->var_pf_mv_dy = (double)pState->m_fMvDY.eval(GetTime());
+ *pState->var_pf_mv_l = (double)pState->m_fMvL.eval(GetTime());
+ *pState->var_pf_mv_r = (double)pState->m_fMvR.eval(GetTime());
+ *pState->var_pf_mv_g = (double)pState->m_fMvG.eval(GetTime());
+ *pState->var_pf_mv_b = (double)pState->m_fMvB.eval(GetTime());
+ *pState->var_pf_mv_a = (double)pState->m_fMvA.eval(GetTime());
+ *pState->var_pf_echo_zoom = (double)pState->m_fVideoEchoZoom.eval(GetTime());
+ *pState->var_pf_echo_alpha = (double)pState->m_fVideoEchoAlpha.eval(GetTime());
+ *pState->var_pf_echo_orient = (double)pState->m_nVideoEchoOrientation;
+ // new in v1.04:
+ *pState->var_pf_wave_usedots = (double)pState->m_bWaveDots;
+ *pState->var_pf_wave_thick = (double)pState->m_bWaveThick;
+ *pState->var_pf_wave_additive = (double)pState->m_bAdditiveWaves;
+ *pState->var_pf_wave_brighten = (double)pState->m_bMaximizeWaveColor;
+ *pState->var_pf_darken_center = (double)pState->m_bDarkenCenter;
+ *pState->var_pf_gamma = (double)pState->m_fGammaAdj.eval(GetTime());
+ *pState->var_pf_wrap = (double)pState->m_bTexWrap;
+ *pState->var_pf_invert = (double)pState->m_bInvert;
+ *pState->var_pf_brighten = (double)pState->m_bBrighten;
+ *pState->var_pf_darken = (double)pState->m_bDarken;
+ *pState->var_pf_solarize = (double)pState->m_bSolarize;
+ *pState->var_pf_meshx = (double)m_nGridX;
+ *pState->var_pf_meshy = (double)m_nGridY;
+ *pState->var_pf_pixelsx = (double)GetWidth();
+ *pState->var_pf_pixelsy = (double)GetHeight();
+ *pState->var_pf_aspectx = (double)m_fInvAspectX;
+ *pState->var_pf_aspecty = (double)m_fInvAspectY;
+ // new in v2.0:
+ *pState->var_pf_blur1min = (double)pState->m_fBlur1Min.eval(GetTime());
+ *pState->var_pf_blur2min = (double)pState->m_fBlur2Min.eval(GetTime());
+ *pState->var_pf_blur3min = (double)pState->m_fBlur3Min.eval(GetTime());
+ *pState->var_pf_blur1max = (double)pState->m_fBlur1Max.eval(GetTime());
+ *pState->var_pf_blur2max = (double)pState->m_fBlur2Max.eval(GetTime());
+ *pState->var_pf_blur3max = (double)pState->m_fBlur3Max.eval(GetTime());
+ *pState->var_pf_blur1_edge_darken = (double)pState->m_fBlur1EdgeDarken.eval(GetTime());
+}
+
+void CPlugin::RunPerFrameEquations(int code)
+{
+ // run per-frame calculations
+
+ /*
+ code is only valid when blending.
+ OLDcomp ~ blend-from preset has a composite shader;
+ NEWwarp ~ blend-to preset has a warp shader; etc.
+
+ code OLDcomp NEWcomp OLDwarp NEWwarp
+ 0
+ 1 1
+ 2 1
+ 3 1 1
+ 4 1
+ 5 1 1
+ 6 1 1
+ 7 1 1 1
+ 8 1
+ 9 1 1
+ 10 1 1
+ 11 1 1 1
+ 12 1 1
+ 13 1 1 1
+ 14 1 1 1
+ 15 1 1 1 1
+ */
+
+ // when blending booleans (like darken, invert, etc) for pre-shader presets,
+ // if blending to/from a pixel-shader preset, we can tune the snap point
+ // (when it changes during the blend) for a less jumpy transition:
+ m_fSnapPoint = 0.5f;
+ if (m_pState->m_bBlending)
+ {
+ switch(code)
+ {
+ case 4:
+ case 6:
+ case 12:
+ case 14:
+ // old preset (only) had a comp shader
+ m_fSnapPoint = -0.01f;
+ break;
+ case 1:
+ case 3:
+ case 9:
+ case 11:
+ // new preset (only) has a comp shader
+ m_fSnapPoint = 1.01f;
+ break;
+ case 0:
+ case 2:
+ case 8:
+ case 10:
+ // neither old or new preset had a comp shader
+ m_fSnapPoint = 0.5f;
+ break;
+ case 5:
+ case 7:
+ case 13:
+ case 15:
+ // both old and new presets use a comp shader - so it won't matter
+ m_fSnapPoint = 0.5f;
+ break;
+ }
+ }
+
+ int num_reps = (m_pState->m_bBlending) ? 2 : 1;
+ for (int rep=0; rep<num_reps; rep++)
+ {
+ CState *pState;
+
+ if (rep==0)
+ pState = m_pState;
+ else
+ pState = m_pOldState;
+
+ // values that will affect the pixel motion (and will be automatically blended
+ // LATER, when the results of 2 sets of these params creates 2 different U/V
+ // meshes that get blended together.)
+ LoadPerFrameEvallibVars(pState);
+
+ // also do just a once-per-frame init for the *per-**VERTEX*** *READ-ONLY* variables
+ // (the non-read-only ones will be reset/restored at the start of each vertex)
+ *pState->var_pv_time = *pState->var_pf_time;
+ *pState->var_pv_fps = *pState->var_pf_fps;
+ *pState->var_pv_frame = *pState->var_pf_frame;
+ *pState->var_pv_progress = *pState->var_pf_progress;
+ *pState->var_pv_bass = *pState->var_pf_bass;
+ *pState->var_pv_mid = *pState->var_pf_mid;
+ *pState->var_pv_treb = *pState->var_pf_treb;
+ *pState->var_pv_bass_att = *pState->var_pf_bass_att;
+ *pState->var_pv_mid_att = *pState->var_pf_mid_att;
+ *pState->var_pv_treb_att = *pState->var_pf_treb_att;
+ *pState->var_pv_meshx = (double)m_nGridX;
+ *pState->var_pv_meshy = (double)m_nGridY;
+ *pState->var_pv_pixelsx = (double)GetWidth();
+ *pState->var_pv_pixelsy = (double)GetHeight();
+ *pState->var_pv_aspectx = (double)m_fInvAspectX;
+ *pState->var_pv_aspecty = (double)m_fInvAspectY;
+ //*pState->var_pv_monitor = *pState->var_pf_monitor;
+
+ // execute once-per-frame expressions:
+#ifndef _NO_EXPR_
+ if (pState->m_pf_codehandle)
+ {
+ if (pState->m_pf_codehandle)
+ {
+ NSEEL_code_execute(pState->m_pf_codehandle);
+ }
+ }
+#endif
+
+ // save some things for next frame:
+ pState->monitor_after_init_code = *pState->var_pf_monitor;
+
+ // save some things for per-vertex code:
+ for (int vi=0; vi<NUM_Q_VAR; vi++)
+ *pState->var_pv_q[vi] = *pState->var_pf_q[vi];
+
+ // (a few range checks:)
+ *pState->var_pf_gamma = max(0 , min( 8, *pState->var_pf_gamma ));
+ *pState->var_pf_echo_zoom = max(0.001, min( 1000, *pState->var_pf_echo_zoom));
+
+ /*
+ if (m_pState->m_bRedBlueStereo || m_bAlways3D)
+ {
+ // override wave colors
+ *pState->var_pf_wave_r = 0.35f*(*pState->var_pf_wave_r) + 0.65f;
+ *pState->var_pf_wave_g = 0.35f*(*pState->var_pf_wave_g) + 0.65f;
+ *pState->var_pf_wave_b = 0.35f*(*pState->var_pf_wave_b) + 0.65f;
+ }
+ */
+ }
+
+ if (m_pState->m_bBlending)
+ {
+ // For all variables that do NOT affect pixel motion, blend them NOW,
+ // so later the user can just access m_pState->m_pf_whatever.
+ double mix = (double)CosineInterp(m_pState->m_fBlendProgress);
+ double mix2 = 1.0 - mix;
+ *m_pState->var_pf_decay = mix*(*m_pState->var_pf_decay ) + mix2*(*m_pOldState->var_pf_decay );
+ *m_pState->var_pf_wave_a = mix*(*m_pState->var_pf_wave_a ) + mix2*(*m_pOldState->var_pf_wave_a );
+ *m_pState->var_pf_wave_r = mix*(*m_pState->var_pf_wave_r ) + mix2*(*m_pOldState->var_pf_wave_r );
+ *m_pState->var_pf_wave_g = mix*(*m_pState->var_pf_wave_g ) + mix2*(*m_pOldState->var_pf_wave_g );
+ *m_pState->var_pf_wave_b = mix*(*m_pState->var_pf_wave_b ) + mix2*(*m_pOldState->var_pf_wave_b );
+ *m_pState->var_pf_wave_x = mix*(*m_pState->var_pf_wave_x ) + mix2*(*m_pOldState->var_pf_wave_x );
+ *m_pState->var_pf_wave_y = mix*(*m_pState->var_pf_wave_y ) + mix2*(*m_pOldState->var_pf_wave_y );
+ *m_pState->var_pf_wave_mystery = mix*(*m_pState->var_pf_wave_mystery) + mix2*(*m_pOldState->var_pf_wave_mystery);
+ // wave_mode: exempt (integer)
+ *m_pState->var_pf_ob_size = mix*(*m_pState->var_pf_ob_size ) + mix2*(*m_pOldState->var_pf_ob_size );
+ *m_pState->var_pf_ob_r = mix*(*m_pState->var_pf_ob_r ) + mix2*(*m_pOldState->var_pf_ob_r );
+ *m_pState->var_pf_ob_g = mix*(*m_pState->var_pf_ob_g ) + mix2*(*m_pOldState->var_pf_ob_g );
+ *m_pState->var_pf_ob_b = mix*(*m_pState->var_pf_ob_b ) + mix2*(*m_pOldState->var_pf_ob_b );
+ *m_pState->var_pf_ob_a = mix*(*m_pState->var_pf_ob_a ) + mix2*(*m_pOldState->var_pf_ob_a );
+ *m_pState->var_pf_ib_size = mix*(*m_pState->var_pf_ib_size ) + mix2*(*m_pOldState->var_pf_ib_size );
+ *m_pState->var_pf_ib_r = mix*(*m_pState->var_pf_ib_r ) + mix2*(*m_pOldState->var_pf_ib_r );
+ *m_pState->var_pf_ib_g = mix*(*m_pState->var_pf_ib_g ) + mix2*(*m_pOldState->var_pf_ib_g );
+ *m_pState->var_pf_ib_b = mix*(*m_pState->var_pf_ib_b ) + mix2*(*m_pOldState->var_pf_ib_b );
+ *m_pState->var_pf_ib_a = mix*(*m_pState->var_pf_ib_a ) + mix2*(*m_pOldState->var_pf_ib_a );
+ *m_pState->var_pf_mv_x = mix*(*m_pState->var_pf_mv_x ) + mix2*(*m_pOldState->var_pf_mv_x );
+ *m_pState->var_pf_mv_y = mix*(*m_pState->var_pf_mv_y ) + mix2*(*m_pOldState->var_pf_mv_y );
+ *m_pState->var_pf_mv_dx = mix*(*m_pState->var_pf_mv_dx ) + mix2*(*m_pOldState->var_pf_mv_dx );
+ *m_pState->var_pf_mv_dy = mix*(*m_pState->var_pf_mv_dy ) + mix2*(*m_pOldState->var_pf_mv_dy );
+ *m_pState->var_pf_mv_l = mix*(*m_pState->var_pf_mv_l ) + mix2*(*m_pOldState->var_pf_mv_l );
+ *m_pState->var_pf_mv_r = mix*(*m_pState->var_pf_mv_r ) + mix2*(*m_pOldState->var_pf_mv_r );
+ *m_pState->var_pf_mv_g = mix*(*m_pState->var_pf_mv_g ) + mix2*(*m_pOldState->var_pf_mv_g );
+ *m_pState->var_pf_mv_b = mix*(*m_pState->var_pf_mv_b ) + mix2*(*m_pOldState->var_pf_mv_b );
+ *m_pState->var_pf_mv_a = mix*(*m_pState->var_pf_mv_a ) + mix2*(*m_pOldState->var_pf_mv_a );
+ *m_pState->var_pf_echo_zoom = mix*(*m_pState->var_pf_echo_zoom ) + mix2*(*m_pOldState->var_pf_echo_zoom );
+ *m_pState->var_pf_echo_alpha = mix*(*m_pState->var_pf_echo_alpha ) + mix2*(*m_pOldState->var_pf_echo_alpha );
+ *m_pState->var_pf_echo_orient = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_echo_orient : *m_pState->var_pf_echo_orient;
+ // added in v1.04:
+ *m_pState->var_pf_wave_usedots = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_wave_usedots : *m_pState->var_pf_wave_usedots ;
+ *m_pState->var_pf_wave_thick = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_wave_thick : *m_pState->var_pf_wave_thick ;
+ *m_pState->var_pf_wave_additive= (mix < m_fSnapPoint) ? *m_pOldState->var_pf_wave_additive : *m_pState->var_pf_wave_additive;
+ *m_pState->var_pf_wave_brighten= (mix < m_fSnapPoint) ? *m_pOldState->var_pf_wave_brighten : *m_pState->var_pf_wave_brighten;
+ *m_pState->var_pf_darken_center= (mix < m_fSnapPoint) ? *m_pOldState->var_pf_darken_center : *m_pState->var_pf_darken_center;
+ *m_pState->var_pf_gamma = mix*(*m_pState->var_pf_gamma ) + mix2*(*m_pOldState->var_pf_gamma );
+ *m_pState->var_pf_wrap = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_wrap : *m_pState->var_pf_wrap ;
+ *m_pState->var_pf_invert = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_invert : *m_pState->var_pf_invert ;
+ *m_pState->var_pf_brighten = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_brighten : *m_pState->var_pf_brighten ;
+ *m_pState->var_pf_darken = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_darken : *m_pState->var_pf_darken ;
+ *m_pState->var_pf_solarize = (mix < m_fSnapPoint) ? *m_pOldState->var_pf_solarize : *m_pState->var_pf_solarize ;
+ // added in v2.0:
+ *m_pState->var_pf_blur1min = mix*(*m_pState->var_pf_blur1min ) + mix2*(*m_pOldState->var_pf_blur1min );
+ *m_pState->var_pf_blur2min = mix*(*m_pState->var_pf_blur2min ) + mix2*(*m_pOldState->var_pf_blur2min );
+ *m_pState->var_pf_blur3min = mix*(*m_pState->var_pf_blur3min ) + mix2*(*m_pOldState->var_pf_blur3min );
+ *m_pState->var_pf_blur1max = mix*(*m_pState->var_pf_blur1max ) + mix2*(*m_pOldState->var_pf_blur1max );
+ *m_pState->var_pf_blur2max = mix*(*m_pState->var_pf_blur2max ) + mix2*(*m_pOldState->var_pf_blur2max );
+ *m_pState->var_pf_blur3max = mix*(*m_pState->var_pf_blur3max ) + mix2*(*m_pOldState->var_pf_blur3max );
+ *m_pState->var_pf_blur1_edge_darken = mix*(*m_pState->var_pf_blur1_edge_darken) + mix2*(*m_pOldState->var_pf_blur1_edge_darken);
+ }
+}
+
+void CPlugin::RenderFrame(int bRedraw)
+{
+ int i;
+
+ float fDeltaT = 1.0f/GetFps();
+
+ if (bRedraw)
+ {
+ // pre-un-flip buffers, so we are redoing the same work as we did last frame...
+ IDirect3DTexture9* pTemp = m_lpVS[0];
+ m_lpVS[0] = m_lpVS[1];
+ m_lpVS[1] = pTemp;
+ }
+
+ // update time
+ /*
+ float fDeltaT = (GetFrame()==0) ? 1.0f/30.0f : GetTime() - m_prev_time;
+ DWORD dwTime = GetTickCount();
+ float fDeltaT = (dwTime - m_dwPrevTickCount)*0.001f;
+ if (GetFrame() > 64)
+ {
+ fDeltaT = (fDeltaT)*0.2f + 0.8f*(1.0f/m_fps);
+ if (fDeltaT > 2.0f/m_fps)
+ {
+ char buf[64];
+ sprintf(buf, "fixing time gap of %5.3f seconds", fDeltaT);
+ dumpmsg(buf);
+
+ fDeltaT = 1.0f/m_fps;
+ }
+ }
+ m_dwPrevTickCount = dwTime;
+ GetTime() += fDeltaT;
+ */
+
+ if (GetFrame()==0)
+ {
+ m_fStartTime = GetTime();
+ m_fPresetStartTime = GetTime();
+ }
+
+ if (m_fNextPresetTime < 0)
+ {
+ float dt = m_fTimeBetweenPresetsRand * (warand()%1000)*0.001f;
+ m_fNextPresetTime = GetTime() + m_fBlendTimeAuto + m_fTimeBetweenPresets + dt;
+ }
+
+ /*
+ if (m_bPresetLockedByUser || m_bPresetLockedByCode)
+ {
+ // if the user has the preset LOCKED, or if they're in the middle of
+ // saving it, then keep extending the time at which the auto-switch will occur
+ // (by the length of this frame).
+
+ m_fPresetStartTime += fDeltaT;
+ m_fNextPresetTime += fDeltaT;
+ }*/
+
+ // update fps
+ /*
+ if (GetFrame() < 4)
+ {
+ m_fps = 0.0f;
+ }
+ else if (GetFrame() <= 64)
+ {
+ m_fps = GetFrame() / (float)(GetTime() - m_fTimeHistory[0]);
+ }
+ else
+ {
+ m_fps = 64.0f / (float)(GetTime() - m_fTimeHistory[m_nTimeHistoryPos]);
+ }
+ m_fTimeHistory[m_nTimeHistoryPos] = GetTime();
+ m_nTimeHistoryPos = (m_nTimeHistoryPos + 1) % 64;
+ */
+
+ // limit fps, if necessary
+ /*
+ if (m_nFpsLimit > 0 && (GetFrame() % 64) == 0 && GetFrame() > 64)
+ {
+ float spf_now = 1.0f / m_fps;
+ float spf_desired = 1.0f / (float)m_nFpsLimit;
+
+ float new_sleep = m_fFPSLimitSleep + (spf_desired - spf_now)*1000.0f;
+
+ if (GetFrame() <= 128)
+ m_fFPSLimitSleep = new_sleep;
+ else
+ m_fFPSLimitSleep = m_fFPSLimitSleep*0.8f + 0.2f*new_sleep;
+
+ if (m_fFPSLimitSleep < 0) m_fFPSLimitSleep = 0;
+ if (m_fFPSLimitSleep > 100) m_fFPSLimitSleep = 100;
+
+ //sprintf(m_szUserMessage, "sleep=%f", m_fFPSLimitSleep);
+ //m_fShowUserMessageUntilThisTime = GetTime() + 3.0f;
+ }
+
+ static float deficit;
+ if (GetFrame()==0) deficit = 0;
+ float ideal_sleep = (m_fFPSLimitSleep + deficit);
+ int actual_sleep = (int)ideal_sleep;
+ if (actual_sleep > 0)
+ Sleep(actual_sleep);
+ deficit = ideal_sleep - actual_sleep;
+ if (deficit < 0) deficit = 0; // just in case
+ if (deficit > 1) deficit = 1; // just in case
+ */
+
+ if (!bRedraw)
+ {
+ m_rand_frame = D3DXVECTOR4(FRAND, FRAND, FRAND, FRAND);
+
+ // randomly change the preset, if it's time
+ if (m_fNextPresetTime < GetTime())
+ {
+ if (m_nLoadingPreset==0) // don't start a load if one is already underway!
+ LoadRandomPreset(m_fBlendTimeAuto);
+ }
+
+ // randomly spawn Song Title, if time
+ if (m_fTimeBetweenRandomSongTitles > 0 &&
+ !m_supertext.bRedrawSuperText &&
+ GetTime() >= m_supertext.fStartTime + m_supertext.fDuration + 1.0f/GetFps())
+ {
+ int n = GetNumToSpawn(GetTime(), fDeltaT, 1.0f/m_fTimeBetweenRandomSongTitles, 0.5f, m_nSongTitlesSpawned);
+ if (n > 0)
+ {
+ LaunchSongTitleAnim();
+ m_nSongTitlesSpawned += n;
+ }
+ }
+
+ // randomly spawn Custom Message, if time
+ if (m_fTimeBetweenRandomCustomMsgs > 0 &&
+ !m_supertext.bRedrawSuperText &&
+ GetTime() >= m_supertext.fStartTime + m_supertext.fDuration + 1.0f/GetFps())
+ {
+ int n = GetNumToSpawn(GetTime(), fDeltaT, 1.0f/m_fTimeBetweenRandomCustomMsgs, 0.5f, m_nCustMsgsSpawned);
+ if (n > 0)
+ {
+ LaunchCustomMessage(-1);
+ m_nCustMsgsSpawned += n;
+ }
+ }
+
+ // update m_fBlendProgress;
+ if (m_pState->m_bBlending)
+ {
+ m_pState->m_fBlendProgress = (GetTime() - m_pState->m_fBlendStartTime) / m_pState->m_fBlendDuration;
+ if (m_pState->m_fBlendProgress > 1.0f)
+ {
+ m_pState->m_bBlending = false;
+ }
+ }
+
+ // handle hard cuts here (just after new sound analysis)
+ static float m_fHardCutThresh;
+ if (GetFrame() == 0)
+ m_fHardCutThresh = m_fHardCutLoudnessThresh*2.0f;
+ if (GetFps() > 1.0f && !m_bHardCutsDisabled && !m_bPresetLockedByUser && !m_bPresetLockedByCode)
+ {
+ if (mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2] > m_fHardCutThresh*3.0f)
+ {
+ if (m_nLoadingPreset==0) // don't start a load if one is already underway!
+ LoadRandomPreset(0.0f);
+ m_fHardCutThresh *= 2.0f;
+ }
+ else
+ {
+ /*
+ float halflife_modified = m_fHardCutHalflife*0.5f;
+ //thresh = (thresh - 1.5f)*0.99f + 1.5f;
+ float k = -0.69315f / halflife_modified;*/
+ float k = -1.3863f / (m_fHardCutHalflife*GetFps());
+ //float single_frame_multiplier = powf(2.7183f, k / GetFps());
+ float single_frame_multiplier = expf(k);
+ m_fHardCutThresh = (m_fHardCutThresh - m_fHardCutLoudnessThresh)*single_frame_multiplier + m_fHardCutLoudnessThresh;
+ }
+ }
+
+ // smooth & scale the audio data, according to m_state, for display purposes
+ float scale = m_pState->m_fWaveScale.eval(GetTime()) / 128.0f;
+ mysound.fWave[0][0] *= scale;
+ mysound.fWave[1][0] *= scale;
+ float mix2 = m_pState->m_fWaveSmoothing.eval(GetTime());
+ float mix1 = scale*(1.0f - mix2);
+ for (i=1; i<576; i++)
+ {
+ mysound.fWave[0][i] = mysound.fWave[0][i]*mix1 + mysound.fWave[0][i-1]*mix2;
+ mysound.fWave[1][i] = mysound.fWave[1][i]*mix1 + mysound.fWave[1][i-1]*mix2;
+ }
+ }
+
+ bool bOldPresetUsesWarpShader = (m_pOldState->m_nWarpPSVersion > 0);
+ bool bNewPresetUsesWarpShader = (m_pState->m_nWarpPSVersion > 0);
+ bool bOldPresetUsesCompShader = (m_pOldState->m_nCompPSVersion > 0);
+ bool bNewPresetUsesCompShader = (m_pState->m_nCompPSVersion > 0);
+
+ // note: 'code' is only meaningful if we are BLENDING.
+ int code = (bOldPresetUsesWarpShader ? 8 : 0) |
+ (bOldPresetUsesCompShader ? 4 : 0) |
+ (bNewPresetUsesWarpShader ? 2 : 0) |
+ (bNewPresetUsesCompShader ? 1 : 0);
+
+ RunPerFrameEquations(code);
+
+ // restore any lost surfaces
+ //m_lpDD->RestoreAllSurfaces();
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ // Remember the original backbuffer and zbuffer
+ LPDIRECT3DSURFACE9 pBackBuffer=NULL;//, pZBuffer=NULL;
+ lpDevice->GetRenderTarget( 0, &pBackBuffer );
+ //lpDevice->GetDepthStencilSurface( &pZBuffer );
+
+ // set up render state
+ {
+ DWORD texaddr = (*m_pState->var_pf_wrap > m_fSnapPoint) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
+ lpDevice->SetRenderState(D3DRS_WRAP0, 0);//D3DWRAPCOORD_0|D3DWRAPCOORD_1|D3DWRAPCOORD_2|D3DWRAPCOORD_3);
+ //lpDevice->SetRenderState(D3DRS_WRAP0, (*m_pState->var_pf_wrap) ? D3DWRAP_U|D3DWRAP_V|D3DWRAP_W : 0);
+ //lpDevice->SetRenderState(D3DRS_WRAP1, (*m_pState->var_pf_wrap) ? D3DWRAP_U|D3DWRAP_V|D3DWRAP_W : 0);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);//texaddr);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);//texaddr);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);//texaddr);
+ lpDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
+ lpDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
+ lpDevice->SetSamplerState(1, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
+
+ lpDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
+ lpDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
+ lpDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
+ lpDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
+ lpDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
+ lpDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
+ lpDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE );
+ lpDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
+ lpDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+ lpDevice->SetRenderState( D3DRS_AMBIENT, 0xFFFFFFFF ); //?
+ lpDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
+
+ // stages 0 and 1 always just use bilinear filtering.
+ lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ // note: this texture stage state setup works for 0 or 1 texture.
+ // if you set a texture, it will be modulated with the current diffuse color.
+ // if you don't set a texture, it will just use the current diffuse color.
+ lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ // NOTE: don't forget to call SetTexture and SetVertexShader before drawing!
+ // Examples:
+ // SPRITEVERTEX verts[4]; // has texcoords
+ // lpDevice->SetTexture(0, m_sprite_tex);
+ // lpDevice->SetVertexShader( SPRITEVERTEX_FORMAT );
+ //
+ // WFVERTEX verts[4]; // no texcoords
+ // lpDevice->SetTexture(0, NULL);
+ // lpDevice->SetVertexShader( WFVERTEX_FORMAT );
+ }
+
+ // render string to m_lpDDSTitle, if necessary
+ if (m_supertext.bRedrawSuperText)
+ {
+ if (!RenderStringToTitleTexture())
+ m_supertext.fStartTime = -1.0f;
+ m_supertext.bRedrawSuperText = false;
+ }
+
+ // set up to render [from NULL] to VS0 (for motion vectors).
+ {
+ lpDevice->SetTexture(0, NULL);
+
+ IDirect3DSurface9* pNewTarget = NULL;
+ if (m_lpVS[0]->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ return;
+ lpDevice->SetRenderTarget(0, pNewTarget );
+ //lpDevice->SetDepthStencilSurface( NULL );
+ pNewTarget->Release();
+
+ lpDevice->SetTexture(0, NULL);
+ }
+
+ // draw motion vectors to VS0
+ DrawMotionVectors();
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetTexture(1, NULL);
+
+ // on first frame, clear OLD VS.
+ if (m_nFramesSinceResize == 0)
+ {
+ IDirect3DSurface9* pNewTarget = NULL;
+ if (m_lpVS[0]->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ return;
+ lpDevice->SetRenderTarget(0, pNewTarget );
+ //lpDevice->SetDepthStencilSurface( NULL );
+ pNewTarget->Release();
+
+ lpDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
+ }
+
+ // set up to render [from VS0] to VS1.
+ {
+ IDirect3DSurface9* pNewTarget = NULL;
+ if (m_lpVS[1]->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ return;
+ lpDevice->SetRenderTarget(0, pNewTarget );
+ //lpDevice->SetDepthStencilSurface( NULL );
+ pNewTarget->Release();
+ }
+
+ if (m_bAutoGamma && GetFrame()==0)
+ {
+ if (strstr(GetDriverDescription(), "nvidia") ||
+ strstr(GetDriverDescription(), "nVidia") ||
+ strstr(GetDriverDescription(), "NVidia") ||
+ strstr(GetDriverDescription(), "NVIDIA"))
+ m_n16BitGamma = 2;
+ else if (strstr(GetDriverDescription(), "ATI RAGE MOBILITY M"))
+ m_n16BitGamma = 2;
+ else
+ m_n16BitGamma = 0;
+ }
+
+ ComputeGridAlphaValues();
+
+ // do the warping for this frame [warp shader]
+ if (!m_pState->m_bBlending)
+ {
+ // no blend
+ if (bNewPresetUsesWarpShader)
+ WarpedBlit_Shaders(1, false, false, false, false);
+ else
+ WarpedBlit_NoShaders(1, false, false, false, false);
+ }
+ else
+ {
+ // blending
+ // WarpedBlit( nPass, bAlphaBlend, bFlipAlpha, bCullTiles, bFlipCulling )
+ // note: alpha values go from 0..1 during a blend.
+ // note: bFlipCulling==false means tiles with alpha>0 will draw.
+ // bFlipCulling==true means tiles with alpha<255 will draw.
+
+ if (bOldPresetUsesWarpShader && bNewPresetUsesWarpShader)
+ {
+ WarpedBlit_Shaders (0, false, false, true, true);
+ WarpedBlit_Shaders (1, true, false, true, false);
+ }
+ else if (!bOldPresetUsesWarpShader && bNewPresetUsesWarpShader)
+ {
+ WarpedBlit_NoShaders(0, false, false, true, true);
+ WarpedBlit_Shaders (1, true, false, true, false);
+ }
+ else if (bOldPresetUsesWarpShader && !bNewPresetUsesWarpShader)
+ {
+ WarpedBlit_Shaders (0, false, false, true, true);
+ WarpedBlit_NoShaders(1, true, false, true, false);
+ }
+ else if (!bOldPresetUsesWarpShader && !bNewPresetUsesWarpShader)
+ {
+ //WarpedBlit_NoShaders(0, false, false, true, true);
+ //WarpedBlit_NoShaders(1, true, false, true, false);
+
+ // special case - all the blending just happens in the vertex UV's, so just pretend there's no blend.
+ WarpedBlit_NoShaders(1, false, false, false, false);
+ }
+ }
+
+ if (m_nMaxPSVersion > 0)
+ BlurPasses();
+
+ // draw audio data
+ DrawCustomShapes(); // draw these first; better for feedback if the waves draw *over* them.
+ DrawCustomWaves();
+ DrawWave(mysound.fWave[0], mysound.fWave[1]);
+ DrawSprites();
+
+ float fProgress = (GetTime() - m_supertext.fStartTime) / m_supertext.fDuration;
+
+ // if song title animation just ended, burn it into the VS:
+ if (m_supertext.fStartTime >= 0 &&
+ fProgress >= 1.0f &&
+ !m_supertext.bRedrawSuperText)
+ {
+ ShowSongTitleAnim(m_nTexSizeX, m_nTexSizeY, 1.0f);
+ }
+
+ // Change the rendertarget back to the original setup
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderTarget(0, pBackBuffer );
+ //lpDevice->SetDepthStencilSurface( pZBuffer );
+ SafeRelease(pBackBuffer);
+ //SafeRelease(pZBuffer);
+
+ // show it to the user [composite shader]
+ if (!m_pState->m_bBlending)
+ {
+ // no blend
+ if (bNewPresetUsesCompShader)
+ ShowToUser_Shaders(1, false, false, false, false);
+ else
+ ShowToUser_NoShaders();//1, false, false, false, false);
+ }
+ else
+ {
+ // blending
+ // ShowToUser( nPass, bAlphaBlend, bFlipAlpha, bCullTiles, bFlipCulling )
+ // note: alpha values go from 0..1 during a blend.
+ // note: bFlipCulling==false means tiles with alpha>0 will draw.
+ // bFlipCulling==true means tiles with alpha<255 will draw.
+
+ // NOTE: ShowToUser_NoShaders() must always come before ShowToUser_Shaders(),
+ // because it always draws the full quad (it can't do tile culling or alpha blending).
+ // [third case here]
+
+ if (bOldPresetUsesCompShader && bNewPresetUsesCompShader)
+ {
+ ShowToUser_Shaders (0, false, false, true, true);
+ ShowToUser_Shaders (1, true, false, true, false);
+ }
+ else if (!bOldPresetUsesCompShader && bNewPresetUsesCompShader)
+ {
+ ShowToUser_NoShaders();
+ ShowToUser_Shaders (1, true, false, true, false);
+ }
+ else if (bOldPresetUsesCompShader && !bNewPresetUsesCompShader)
+ {
+ // THA FUNKY REVERSAL
+ //ShowToUser_Shaders (0);
+ //ShowToUser_NoShaders(1);
+ ShowToUser_NoShaders();
+ ShowToUser_Shaders (0, true, true, true, true);
+ }
+ else if (!bOldPresetUsesCompShader && !bNewPresetUsesCompShader)
+ {
+ // special case - all the blending just happens in the blended state vars, so just pretend there's no blend.
+ ShowToUser_NoShaders();//1, false, false, false, false);
+ }
+ }
+
+ // finally, render song title animation to back buffer
+ if (m_supertext.fStartTime >= 0 &&
+ !m_supertext.bRedrawSuperText)
+ {
+ ShowSongTitleAnim(GetWidth(), GetHeight(), min(fProgress, 0.9999f));
+ if (fProgress >= 1.0f)
+ m_supertext.fStartTime = -1.0f; // 'off' state
+ }
+
+ DrawUserSprites();
+
+ // flip buffers
+ IDirect3DTexture9* pTemp = m_lpVS[0];
+ m_lpVS[0] = m_lpVS[1];
+ m_lpVS[1] = pTemp;
+
+ /*
+ // FIXME - remove EnforceMaxFPS() if never used
+ //EnforceMaxFPS(!(m_nLoadingPreset==1 || m_nLoadingPreset==2 || m_nLoadingPreset==4 || m_nLoadingPreset==5)); // this call just turns it on or off; doesn't do it now...
+ //EnforceMaxFPS(!(m_nLoadingPreset==2 || m_nLoadingPreset==5)); // this call just turns it on or off; doesn't do it now...
+
+ // FIXME - remove this stuff, and change 'm_last_raw_time' in pluginshell (and others) back to private.
+ static float fOldTime = 0;
+ float fNewTime = (float)((double)m_last_raw_time/(double)m_high_perf_timer_freq.QuadPart);
+ float dt = fNewTime-fOldTime;
+ if (m_nLoadingPreset != 0) {
+ char buf[256];
+ sprintf(buf, "m_nLoadingPreset==%d: dt=%d ms\n", m_nLoadingPreset, (int)(dt*1000) );
+ OutputDebugString(buf);
+ }
+ fOldTime = fNewTime;
+ */
+}
+
+void CPlugin::DrawMotionVectors()
+{
+ // FLEXIBLE MOTION VECTOR FIELD
+ if ((float)*m_pState->var_pf_mv_a >= 0.001f)
+ {
+ //-------------------------------------------------------
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader(NULL);
+ lpDevice->SetFVF(WFVERTEX_FORMAT);
+ //-------------------------------------------------------
+
+ int x,y;
+
+ int nX = (int)(*m_pState->var_pf_mv_x);// + 0.999f);
+ int nY = (int)(*m_pState->var_pf_mv_y);// + 0.999f);
+ float dx = (float)*m_pState->var_pf_mv_x - nX;
+ float dy = (float)*m_pState->var_pf_mv_y - nY;
+ if (nX > 64) { nX = 64; dx = 0; }
+ if (nY > 48) { nY = 48; dy = 0; }
+
+ if (nX > 0 && nY > 0)
+ {
+ /*
+ float dx2 = m_fMotionVectorsTempDx;//(*m_pState->var_pf_mv_dx) * 0.05f*GetTime(); // 0..1 range
+ float dy2 = m_fMotionVectorsTempDy;//(*m_pState->var_pf_mv_dy) * 0.05f*GetTime(); // 0..1 range
+ if (GetFps() > 2.0f && GetFps() < 300.0f)
+ {
+ dx2 += (float)(*m_pState->var_pf_mv_dx) * 0.05f / GetFps();
+ dy2 += (float)(*m_pState->var_pf_mv_dy) * 0.05f / GetFps();
+ }
+ if (dx2 > 1.0f) dx2 -= (int)dx2;
+ if (dy2 > 1.0f) dy2 -= (int)dy2;
+ if (dx2 < 0.0f) dx2 = 1.0f - (-dx2 - (int)(-dx2));
+ if (dy2 < 0.0f) dy2 = 1.0f - (-dy2 - (int)(-dy2));
+ // hack: when there is only 1 motion vector on the screem, to keep it in
+ // the center, we gradually migrate it toward 0.5.
+ dx2 = dx2*0.995f + 0.5f*0.005f;
+ dy2 = dy2*0.995f + 0.5f*0.005f;
+ // safety catch
+ if (dx2 < 0 || dx2 > 1 || dy2 < 0 || dy2 > 1)
+ {
+ dx2 = 0.5f;
+ dy2 = 0.5f;
+ }
+ m_fMotionVectorsTempDx = dx2;
+ m_fMotionVectorsTempDy = dy2;*/
+ float dx2 = (float)(*m_pState->var_pf_mv_dx);
+ float dy2 = (float)(*m_pState->var_pf_mv_dy);
+
+ float len_mult = (float)*m_pState->var_pf_mv_l;
+ if (dx < 0) dx = 0;
+ if (dy < 0) dy = 0;
+ if (dx > 1) dx = 1;
+ if (dy > 1) dy = 1;
+ //dx = dx * 1.0f/(float)nX;
+ //dy = dy * 1.0f/(float)nY;
+ float inv_texsize = 1.0f/(float)m_nTexSizeX;
+ float min_len = 1.0f*inv_texsize;
+
+ WFVERTEX v[(64+1)*2];
+ ZeroMemory(v, sizeof(WFVERTEX)*(64+1)*2);
+ v[0].Diffuse = D3DCOLOR_RGBA_01((float)*m_pState->var_pf_mv_r,(float)*m_pState->var_pf_mv_g,(float)*m_pState->var_pf_mv_b,(float)*m_pState->var_pf_mv_a);
+ for (x=1; x<(nX+1)*2; x++)
+ v[x].Diffuse = v[0].Diffuse;
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+ for (y=0; y<nY; y++)
+ {
+ float fy = (y + 0.25f)/(float)(nY + dy + 0.25f - 1.0f);
+
+ // now move by offset
+ fy -= dy2;
+
+ if (fy > 0.0001f && fy < 0.9999f)
+ {
+ int n = 0;
+ for (x=0; x<nX; x++)
+ {
+ //float fx = (x + 0.25f)/(float)(nX + dx + 0.25f - 1.0f);
+ float fx = (x + 0.25f)/(float)(nX + dx + 0.25f - 1.0f);
+
+ // now move by offset
+ fx += dx2;
+
+ if (fx > 0.0001f && fx < 0.9999f)
+ {
+ float fx2, fy2;
+ ReversePropagatePoint(fx, fy, &fx2, &fy2); // NOTE: THIS IS REALLY A REVERSE-PROPAGATION
+ //fx2 = fx*2 - fx2;
+ //fy2 = fy*2 - fy2;
+ //fx2 = fx + 1.0f/(float)m_nTexSize;
+ //fy2 = 1-(fy + 1.0f/(float)m_nTexSize);
+
+ // enforce minimum trail lengths:
+ {
+ float dx = (fx2 - fx);
+ float dy = (fy2 - fy);
+ dx *= len_mult;
+ dy *= len_mult;
+ float len = sqrtf(dx*dx + dy*dy);
+
+ if (len > min_len)
+ {
+
+ }
+ else if (len > 0.00000001f)
+ {
+ len = min_len/len;
+ dx *= len;
+ dy *= len;
+ }
+ else
+ {
+ dx = min_len;
+ dy = min_len;
+ }
+
+ fx2 = fx + dx;
+ fy2 = fy + dy;
+ }
+ /**/
+
+ v[n].x = fx * 2.0f - 1.0f;
+ v[n].y = fy * 2.0f - 1.0f;
+ v[n+1].x = fx2 * 2.0f - 1.0f;
+ v[n+1].y = fy2 * 2.0f - 1.0f;
+
+ // actually, project it in the reverse direction
+ //v[n+1].x = v[n].x*2.0f - v[n+1].x;// + dx*2;
+ //v[n+1].y = v[n].y*2.0f - v[n+1].y;// + dy*2;
+ //v[n].x += dx*2;
+ //v[n].y += dy*2;
+
+ n += 2;
+ }
+ }
+
+ // draw it
+ lpDevice->DrawPrimitiveUP(D3DPT_LINELIST, n/2, v, sizeof(WFVERTEX));
+ }
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+ }
+}
+
+/*
+void CPlugin::UpdateSongInfo()
+{
+ if (m_bShowSongTitle || m_bSongTitleAnims)
+ {
+ char szOldSongMessage[512];
+ lstrcpy(szOldSongMessage, m_szSongMessage);
+
+ if (::GetWindowText(m_hWndParent, m_szSongMessage, sizeof(m_szSongMessage)))
+ {
+ // remove ' - Winamp' at end
+ if (strlen(m_szSongMessage) > 9)
+ {
+ int check_pos = strlen(m_szSongMessage) - 9;
+ if (lstrcmp(" - Winamp", (char *)(m_szSongMessage + check_pos)) == 0)
+ m_szSongMessage[check_pos] = 0;
+ }
+
+ // remove ' - Winamp [Paused]' at end
+ if (strlen(m_szSongMessage) > 18)
+ {
+ int check_pos = strlen(m_szSongMessage) - 18;
+ if (lstrcmp(" - Winamp [Paused]", (char *)(m_szSongMessage + check_pos)) == 0)
+ m_szSongMessage[check_pos] = 0;
+ }
+
+ // remove song # and period from beginning
+ char *p = m_szSongMessage;
+ while (*p >= '0' && *p <= '9') p++;
+ if (*p == '.' && *(p+1) == ' ')
+ {
+ p += 2;
+ int pos = 0;
+ while (*p != 0)
+ {
+ m_szSongMessage[pos++] = *p;
+ p++;
+ }
+ m_szSongMessage[pos++] = 0;
+ }
+
+ // fix &'s for display
+ /*
+ {
+ int pos = 0;
+ int len = strlen(m_szSongMessage);
+ while (m_szSongMessage[pos])
+ {
+ if (m_szSongMessage[pos] == '&')
+ {
+ for (int x=len; x>=pos; x--)
+ m_szSongMessage[x+1] = m_szSongMessage[x];
+ len++;
+ pos++;
+ }
+ pos++;
+ }
+ }*/
+ /*
+ if (m_bSongTitleAnims &&
+ ((lstrcmp(szOldSongMessage, m_szSongMessage) != 0) || (GetFrame()==0)))
+ {
+ // launch song title animation
+ LaunchSongTitleAnim();
+
+ /*
+ m_supertext.bRedrawSuperText = true;
+ m_supertext.bIsSongTitle = true;
+ lstrcpy(m_supertext.szText, m_szSongMessage);
+ lstrcpy(m_supertext.nFontFace, m_szTitleFontFace);
+ m_supertext.fFontSize = (float)m_nTitleFontSize;
+ m_supertext.bBold = m_bTitleFontBold;
+ m_supertext.bItal = m_bTitleFontItalic;
+ m_supertext.fX = 0.5f;
+ m_supertext.fY = 0.5f;
+ m_supertext.fGrowth = 1.0f;
+ m_supertext.fDuration = m_fSongTitleAnimDuration;
+ m_supertext.nColorR = 255;
+ m_supertext.nColorG = 255;
+ m_supertext.nColorB = 255;
+
+ m_supertext.fStartTime = GetTime();
+ */
+/* }
+ }
+ else
+ {
+ sprintf(m_szSongMessage, "<couldn't get song title>");
+ }
+ }
+
+ m_nTrackPlaying = SendMessage(m_hWndParent,WM_USER, 0, 125);
+
+ // append song time
+ if (m_bShowSongTime && m_nSongPosMS >= 0)
+ {
+ float time_s = m_nSongPosMS*0.001f;
+
+ int minutes = (int)(time_s/60);
+ time_s -= minutes*60;
+ int seconds = (int)time_s;
+ time_s -= seconds;
+ int dsec = (int)(time_s*100);
+
+ sprintf(m_szSongTime, "%d:%02d.%02d", minutes, seconds, dsec);
+ }
+
+ // append song length
+ if (m_bShowSongLen && m_nSongLenMS > 0)
+ {
+ int len_s = m_nSongLenMS/1000;
+ int minutes = len_s/60;
+ int seconds = len_s - minutes*60;
+
+ char buf[512];
+ sprintf(buf, " / %d:%02d", minutes, seconds);
+ lstrcat(m_szSongTime, buf);
+ }
+}
+*/
+
+bool CPlugin::ReversePropagatePoint(float fx, float fy, float *fx2, float *fy2)
+{
+ //float fy = y/(float)nMotionVectorsY;
+ int y0 = (int)(fy*m_nGridY);
+ float dy = fy*m_nGridY - y0;
+
+ //float fx = x/(float)nMotionVectorsX;
+ int x0 = (int)(fx*m_nGridX);
+ float dx = fx*m_nGridX - x0;
+
+ int x1 = x0 + 1;
+ int y1 = y0 + 1;
+
+ if (x0 < 0) return false;
+ if (y0 < 0) return false;
+ //if (x1 < 0) return false;
+ //if (y1 < 0) return false;
+ //if (x0 > m_nGridX) return false;
+ //if (y0 > m_nGridY) return false;
+ if (x1 > m_nGridX) return false;
+ if (y1 > m_nGridY) return false;
+
+ float tu, tv;
+ tu = m_verts[y0*(m_nGridX+1)+x0].tu * (1-dx)*(1-dy);
+ tv = m_verts[y0*(m_nGridX+1)+x0].tv * (1-dx)*(1-dy);
+ tu += m_verts[y0*(m_nGridX+1)+x1].tu * (dx)*(1-dy);
+ tv += m_verts[y0*(m_nGridX+1)+x1].tv * (dx)*(1-dy);
+ tu += m_verts[y1*(m_nGridX+1)+x0].tu * (1-dx)*(dy);
+ tv += m_verts[y1*(m_nGridX+1)+x0].tv * (1-dx)*(dy);
+ tu += m_verts[y1*(m_nGridX+1)+x1].tu * (dx)*(dy);
+ tv += m_verts[y1*(m_nGridX+1)+x1].tv * (dx)*(dy);
+
+ *fx2 = tu;
+ *fy2 = 1.0f - tv;
+ return true;
+}
+
+void CPlugin::GetSafeBlurMinMax(CState* pState, float* blur_min, float* blur_max)
+{
+ blur_min[0] = (float)*pState->var_pf_blur1min;
+ blur_min[1] = (float)*pState->var_pf_blur2min;
+ blur_min[2] = (float)*pState->var_pf_blur3min;
+ blur_max[0] = (float)*pState->var_pf_blur1max;
+ blur_max[1] = (float)*pState->var_pf_blur2max;
+ blur_max[2] = (float)*pState->var_pf_blur3max;
+
+ // check that precision isn't wasted in later blur passes [...min-max gap can't grow!]
+ // also, if min-max are close to each other, push them apart:
+ const float fMinDist = 0.1f;
+ if (blur_max[0] - blur_min[0] < fMinDist) {
+ float avg = (blur_min[0] + blur_max[0])*0.5f;
+ blur_min[0] = avg - fMinDist*0.5f;
+ blur_max[0] = avg - fMinDist*0.5f;
+ }
+ blur_max[1] = min(blur_max[0], blur_max[1]);
+ blur_min[1] = max(blur_min[0], blur_min[1]);
+ if (blur_max[1] - blur_min[1] < fMinDist) {
+ float avg = (blur_min[1] + blur_max[1])*0.5f;
+ blur_min[1] = avg - fMinDist*0.5f;
+ blur_max[1] = avg - fMinDist*0.5f;
+ }
+ blur_max[2] = min(blur_max[1], blur_max[2]);
+ blur_min[2] = max(blur_min[1], blur_min[2]);
+ if (blur_max[2] - blur_min[2] < fMinDist) {
+ float avg = (blur_min[2] + blur_max[2])*0.5f;
+ blur_min[2] = avg - fMinDist*0.5f;
+ blur_max[2] = avg - fMinDist*0.5f;
+ }
+}
+
+void CPlugin::BlurPasses()
+{
+ #if (NUM_BLUR_TEX>0)
+
+ // Note: Blur is currently a little funky. It blurs the *current* frame after warp;
+ // this way, it lines up well with the composite pass. However, if you switch
+ // presets instantly, to one whose *warp* shader uses the blur texture,
+ // it will be outdated (just for one frame). Oh well.
+ // This also means that when sampling the blurred textures in the warp shader,
+ // they are one frame old. This isn't too big a deal. Getting them to match
+ // up for the composite pass is probably more important.
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ int passes = min(NUM_BLUR_TEX, m_nHighestBlurTexUsedThisFrame*2);
+ if (passes==0)
+ return;
+
+ LPDIRECT3DSURFACE9 pBackBuffer=NULL;//, pZBuffer=NULL;
+ lpDevice->GetRenderTarget( 0, &pBackBuffer );
+
+ //lpDevice->SetFVF( MYVERTEX_FORMAT );
+ lpDevice->SetVertexShader( m_BlurShaders[0].vs.ptr );
+ lpDevice->SetVertexDeclaration(m_pMyVertDecl);
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ DWORD wrap = D3DTADDRESS_CLAMP;//D3DTADDRESS_WRAP;// : D3DTADDRESS_CLAMP;
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSW, wrap);
+ lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 1);
+
+ IDirect3DSurface9* pNewTarget = NULL;
+
+ // clear texture bindings
+ for (int i=0; i<16; i++)
+ lpDevice->SetTexture(i, NULL);
+
+ // set up fullscreen quad
+ MYVERTEX v[4];
+
+ v[0].x = -1;
+ v[0].y = -1;
+ v[1].x = 1;
+ v[1].y = -1;
+ v[2].x = -1;
+ v[2].y = 1;
+ v[3].x = 1;
+ v[3].y = 1;
+
+ v[0].tu = 0; //kiv: upside-down?
+ v[0].tv = 0;
+ v[1].tu = 1;
+ v[1].tv = 0;
+ v[2].tu = 0;
+ v[2].tv = 1;
+ v[3].tu = 1;
+ v[3].tv = 1;
+
+ const float w[8] = { 4.0f, 3.8f, 3.5f, 2.9f, 1.9f, 1.2f, 0.7f, 0.3f }; //<- user can specify these
+ float edge_darken = (float)*m_pState->var_pf_blur1_edge_darken;
+ float blur_min[3], blur_max[3];
+ GetSafeBlurMinMax(m_pState, blur_min, blur_max);
+
+ float fscale[3];
+ float fbias[3];
+
+ // figure out the progressive scale & bias needed, at each step,
+ // to go from one [min..max] range to the next.
+ float temp_min, temp_max;
+ fscale[0] = 1.0f / (blur_max[0] - blur_min[0]);
+ fbias [0] = -blur_min[0] * fscale[0];
+ temp_min = (blur_min[1] - blur_min[0]) / (blur_max[0] - blur_min[0]);
+ temp_max = (blur_max[1] - blur_min[0]) / (blur_max[0] - blur_min[0]);
+ fscale[1] = 1.0f / (temp_max - temp_min);
+ fbias [1] = -temp_min * fscale[1];
+ temp_min = (blur_min[2] - blur_min[1]) / (blur_max[1] - blur_min[1]);
+ temp_max = (blur_max[2] - blur_min[1]) / (blur_max[1] - blur_min[1]);
+ fscale[2] = 1.0f / (temp_max - temp_min);
+ fbias [2] = -temp_min * fscale[2];
+
+ // note: warped blit just rendered from VS0 to VS1.
+ for (int i=0; i<passes; i++)
+ {
+ // hook up correct render target
+ if (m_lpBlur[i]->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ return;
+ lpDevice->SetRenderTarget(0, pNewTarget);
+ pNewTarget->Release();
+
+ // hook up correct source texture - assume there is only one, at stage 0
+ lpDevice->SetTexture(0, (i==0) ? m_lpVS[0] : m_lpBlur[i-1]);
+
+ // set pixel shader
+ lpDevice->SetPixelShader (m_BlurShaders[i%2].ps.ptr);
+
+ // set constants
+ LPD3DXCONSTANTTABLE pCT = m_BlurShaders[i%2].ps.CT;
+ D3DXHANDLE* h = m_BlurShaders[i%2].ps.params.const_handles;
+
+ int srcw = (i==0) ? GetWidth() : m_nBlurTexW[i-1];
+ int srch = (i==0) ? GetHeight() : m_nBlurTexH[i-1];
+ D3DXVECTOR4 srctexsize = D3DXVECTOR4( (float)srcw, (float)srch, 1.0f/(float)srcw, 1.0f/(float)srch );
+
+ float fscale_now = fscale[i/2];
+ float fbias_now = fbias[i/2];
+
+ if (i%2==0)
+ {
+ // pass 1 (long horizontal pass)
+ //-------------------------------------
+ const float w1 = w[0] + w[1];
+ const float w2 = w[2] + w[3];
+ const float w3 = w[4] + w[5];
+ const float w4 = w[6] + w[7];
+ const float d1 = 0 + 2*w[1]/w1;
+ const float d2 = 2 + 2*w[3]/w2;
+ const float d3 = 4 + 2*w[5]/w3;
+ const float d4 = 6 + 2*w[7]/w4;
+ const float w_div = 0.5f/(w1+w2+w3+w4);
+ //-------------------------------------
+ //float4 _c0; // source texsize (.xy), and inverse (.zw)
+ //float4 _c1; // w1..w4
+ //float4 _c2; // d1..d4
+ //float4 _c3; // scale, bias, w_div, 0
+ //-------------------------------------
+ if (h[0]) pCT->SetVector( lpDevice, h[0], &srctexsize );
+ if (h[1]) pCT->SetVector( lpDevice, h[1], &D3DXVECTOR4( w1,w2,w3,w4 ));
+ if (h[2]) pCT->SetVector( lpDevice, h[2], &D3DXVECTOR4( d1,d2,d3,d4 ));
+ if (h[3]) pCT->SetVector( lpDevice, h[3], &D3DXVECTOR4( fscale_now,fbias_now,w_div,0));
+ }
+ else
+ {
+ // pass 2 (short vertical pass)
+ //-------------------------------------
+ const float w1 = w[0]+w[1] + w[2]+w[3];
+ const float w2 = w[4]+w[5] + w[6]+w[7];
+ const float d1 = 0 + 2*((w[2]+w[3])/w1);
+ const float d2 = 2 + 2*((w[6]+w[7])/w2);
+ const float w_div = 1.0f/((w1+w2)*2);
+ //-------------------------------------
+ //float4 _c0; // source texsize (.xy), and inverse (.zw)
+ //float4 _c5; // w1,w2,d1,d2
+ //float4 _c6; // w_div, edge_darken_c1, edge_darken_c2, edge_darken_c3
+ //-------------------------------------
+ if (h[0]) pCT->SetVector( lpDevice, h[0], &srctexsize );
+ if (h[5]) pCT->SetVector( lpDevice, h[5], &D3DXVECTOR4( w1,w2,d1,d2 ));
+ if (h[6])
+ {
+ // note: only do this first time; if you do it many times,
+ // then the super-blurred levels will have big black lines along the top & left sides.
+ if (i==1)
+ pCT->SetVector( lpDevice, h[6], &D3DXVECTOR4( w_div,(1-edge_darken),edge_darken,5.0f )); //darken edges
+ else
+ pCT->SetVector( lpDevice, h[6], &D3DXVECTOR4( w_div,1.0f,0.0f,5.0f )); // don't darken
+ }
+ }
+
+ // draw fullscreen quad
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(MYVERTEX));
+
+ // clear texture bindings
+ lpDevice->SetTexture(0, NULL);
+ }
+
+ lpDevice->SetRenderTarget(0, pBackBuffer);
+ pBackBuffer->Release();
+ lpDevice->SetPixelShader( NULL );
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetFVF( MYVERTEX_FORMAT );
+ #endif
+
+ m_nHighestBlurTexUsedThisFrame = 0;
+}
+
+void CPlugin::ComputeGridAlphaValues()
+{
+ float fBlend = m_pState->m_fBlendProgress;//max(0,min(1,(m_pState->m_fBlendProgress*1.6f - 0.3f)));
+ /*switch(code) //if (nPassOverride==0)
+ {
+ //case 8:
+ //case 9:
+ //case 12:
+ //case 13:
+ // note - these are the 4 cases where the old preset uses a warp shader, but new preset doesn't.
+ fBlend = 1-fBlend; // <-- THIS IS THE KEY - FLIPS THE ALPHAS AND EVERYTHING ELSE JUST WORKS.
+ break;
+ }*/
+ //fBlend = 1-fBlend; // <-- THIS IS THE KEY - FLIPS THE ALPHAS AND EVERYTHING ELSE JUST WORKS.
+ bool bBlending = m_pState->m_bBlending;//(fBlend >= 0.0001f && fBlend <= 0.9999f);
+
+
+ // warp stuff
+ float fWarpTime = GetTime() * m_pState->m_fWarpAnimSpeed;
+ float fWarpScaleInv = 1.0f / m_pState->m_fWarpScale.eval(GetTime());
+ float f[4];
+ f[0] = 11.68f + 4.0f*cosf(fWarpTime*1.413f + 10);
+ f[1] = 8.77f + 3.0f*cosf(fWarpTime*1.113f + 7);
+ f[2] = 10.54f + 3.0f*cosf(fWarpTime*1.233f + 3);
+ f[3] = 11.49f + 4.0f*cosf(fWarpTime*0.933f + 5);
+
+ // texel alignment
+ float texel_offset_x = 0.5f / (float)m_nTexSizeX;
+ float texel_offset_y = 0.5f / (float)m_nTexSizeY;
+
+ int num_reps = (m_pState->m_bBlending) ? 2 : 1;
+ int start_rep = 0;
+
+ // FIRST WE HAVE 1-2 PASSES FOR CRUNCHING THE PER-VERTEX EQUATIONS
+ for (int rep=start_rep; rep<num_reps; rep++)
+ {
+ // to blend the two PV equations together, we simulate both to get the final UV coords,
+ // then we blend those final UV coords. We also write out an alpha value so that
+ // the second DRAW pass below (which might use a different shader) can do blending.
+ CState *pState;
+
+ if (rep==0)
+ pState = m_pState;
+ else
+ pState = m_pOldState;
+
+ // cache the doubles as floats so that computations are a bit faster
+ float fZoom = (float)(*pState->var_pf_zoom);
+ float fZoomExp = (float)(*pState->var_pf_zoomexp);
+ float fRot = (float)(*pState->var_pf_rot);
+ float fWarp = (float)(*pState->var_pf_warp);
+ float fCX = (float)(*pState->var_pf_cx);
+ float fCY = (float)(*pState->var_pf_cy);
+ float fDX = (float)(*pState->var_pf_dx);
+ float fDY = (float)(*pState->var_pf_dy);
+ float fSX = (float)(*pState->var_pf_sx);
+ float fSY = (float)(*pState->var_pf_sy);
+
+ int n = 0;
+
+ for (int y=0; y<=m_nGridY; y++)
+ {
+ for (int x=0; x<=m_nGridX; x++)
+ {
+ // Note: x, y, z are now set at init. time - no need to mess with them!
+ //m_verts[n].x = i/(float)m_nGridX*2.0f - 1.0f;
+ //m_verts[n].y = j/(float)m_nGridY*2.0f - 1.0f;
+ //m_verts[n].z = 0.0f;
+
+ if (pState->m_pp_codehandle)
+ {
+ // restore all the variables to their original states,
+ // run the user-defined equations,
+ // then move the results into local vars for computation as floats
+
+ *pState->var_pv_x = (double)(m_verts[n].x* 0.5f*m_fAspectX + 0.5f);
+ *pState->var_pv_y = (double)(m_verts[n].y*-0.5f*m_fAspectY + 0.5f);
+ *pState->var_pv_rad = (double)m_vertinfo[n].rad;
+ *pState->var_pv_ang = (double)m_vertinfo[n].ang;
+ *pState->var_pv_zoom = *pState->var_pf_zoom;
+ *pState->var_pv_zoomexp = *pState->var_pf_zoomexp;
+ *pState->var_pv_rot = *pState->var_pf_rot;
+ *pState->var_pv_warp = *pState->var_pf_warp;
+ *pState->var_pv_cx = *pState->var_pf_cx;
+ *pState->var_pv_cy = *pState->var_pf_cy;
+ *pState->var_pv_dx = *pState->var_pf_dx;
+ *pState->var_pv_dy = *pState->var_pf_dy;
+ *pState->var_pv_sx = *pState->var_pf_sx;
+ *pState->var_pv_sy = *pState->var_pf_sy;
+ //*pState->var_pv_time = *pState->var_pv_time; // (these are all now initialized
+ //*pState->var_pv_bass = *pState->var_pv_bass; // just once per frame)
+ //*pState->var_pv_mid = *pState->var_pv_mid;
+ //*pState->var_pv_treb = *pState->var_pv_treb;
+ //*pState->var_pv_bass_att = *pState->var_pv_bass_att;
+ //*pState->var_pv_mid_att = *pState->var_pv_mid_att;
+ //*pState->var_pv_treb_att = *pState->var_pv_treb_att;
+
+#ifndef _NO_EXPR_
+ NSEEL_code_execute(pState->m_pp_codehandle);
+#endif
+
+ fZoom = (float)(*pState->var_pv_zoom);
+ fZoomExp = (float)(*pState->var_pv_zoomexp);
+ fRot = (float)(*pState->var_pv_rot);
+ fWarp = (float)(*pState->var_pv_warp);
+ fCX = (float)(*pState->var_pv_cx);
+ fCY = (float)(*pState->var_pv_cy);
+ fDX = (float)(*pState->var_pv_dx);
+ fDY = (float)(*pState->var_pv_dy);
+ fSX = (float)(*pState->var_pv_sx);
+ fSY = (float)(*pState->var_pv_sy);
+ }
+
+ float fZoom2 = powf(fZoom, powf(fZoomExp, m_vertinfo[n].rad*2.0f - 1.0f));
+
+ // initial texcoords, w/built-in zoom factor
+ float fZoom2Inv = 1.0f/fZoom2;
+ float u = m_verts[n].x*m_fAspectX*0.5f*fZoom2Inv + 0.5f;
+ float v = -m_verts[n].y*m_fAspectY*0.5f*fZoom2Inv + 0.5f;
+ //float u_orig = u;
+ //float v_orig = v;
+ //m_verts[n].tr = u_orig + texel_offset_x;
+ //m_verts[n].ts = v_orig + texel_offset_y;
+
+ // stretch on X, Y:
+ u = (u - fCX)/fSX + fCX;
+ v = (v - fCY)/fSY + fCY;
+
+ // warping:
+ //if (fWarp > 0.001f || fWarp < -0.001f)
+ //{
+ u += fWarp*0.0035f*sinf(fWarpTime*0.333f + fWarpScaleInv*(m_verts[n].x*f[0] - m_verts[n].y*f[3]));
+ v += fWarp*0.0035f*cosf(fWarpTime*0.375f - fWarpScaleInv*(m_verts[n].x*f[2] + m_verts[n].y*f[1]));
+ u += fWarp*0.0035f*cosf(fWarpTime*0.753f - fWarpScaleInv*(m_verts[n].x*f[1] - m_verts[n].y*f[2]));
+ v += fWarp*0.0035f*sinf(fWarpTime*0.825f + fWarpScaleInv*(m_verts[n].x*f[0] + m_verts[n].y*f[3]));
+ //}
+
+ // rotation:
+ float u2 = u - fCX;
+ float v2 = v - fCY;
+
+ float cos_rot = cosf(fRot);
+ float sin_rot = sinf(fRot);
+ u = u2*cos_rot - v2*sin_rot + fCX;
+ v = u2*sin_rot + v2*cos_rot + fCY;
+
+ // translation:
+ u -= fDX;
+ v -= fDY;
+
+ // undo aspect ratio fix:
+ u = (u-0.5f)*m_fInvAspectX + 0.5f;
+ v = (v-0.5f)*m_fInvAspectY + 0.5f;
+
+ // final half-texel-offset translation:
+ u += texel_offset_x;
+ v += texel_offset_y;
+
+ if (rep==0)
+ {
+ // UV's for m_pState
+ m_verts[n].tu = u;
+ m_verts[n].tv = v;
+ m_verts[n].Diffuse = 0xFFFFFFFF;
+ }
+ else
+ {
+ // blend to UV's for m_pOldState
+ float mix2 = m_vertinfo[n].a*fBlend + m_vertinfo[n].c;//fCosineBlend2;
+ mix2 = max(0,min(1,mix2));
+ // if fBlend un-flipped, then mix2 is 0 at the beginning of a blend, 1 at the end...
+ // and alphas are 0 at the beginning, 1 at the end.
+ m_verts[n].tu = m_verts[n].tu*(mix2) + u*(1-mix2);
+ m_verts[n].tv = m_verts[n].tv*(mix2) + v*(1-mix2);
+ // this sets the alpha values for blending between two presets:
+ m_verts[n].Diffuse = 0x00FFFFFF | (((DWORD)(mix2*255))<<24);
+ }
+
+ n++;
+ }
+ }
+
+ }
+}
+
+void CPlugin::WarpedBlit_NoShaders(int nPass, bool bAlphaBlend, bool bFlipAlpha, bool bCullTiles, bool bFlipCulling)
+{
+ MungeFPCW(NULL); // puts us in single-precision mode & disables exceptions
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ if (!wcscmp(m_pState->m_szDesc, INVALID_PRESET_DESC))
+ {
+ // if no valid preset loaded, clear the target to black, and return
+ lpDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
+ return;
+ }
+
+ lpDevice->SetTexture(0, m_lpVS[0]);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetPixelShader( NULL );
+ lpDevice->SetFVF( MYVERTEX_FORMAT );
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ // stages 0 and 1 always just use bilinear filtering.
+ lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ // note: this texture stage state setup works for 0 or 1 texture.
+ // if you set a texture, it will be modulated with the current diffuse color.
+ // if you don't set a texture, it will just use the current diffuse color.
+ lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ DWORD texaddr = (*m_pState->var_pf_wrap > m_fSnapPoint) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, texaddr);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, texaddr);
+ lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSW, texaddr);
+
+ // decay
+ float fDecay = (float)(*m_pState->var_pf_decay);
+
+ //if (m_pState->m_bBlending)
+ // fDecay = fDecay*(fCosineBlend) + (1.0f-fCosineBlend)*((float)(*m_pOldState->var_pf_decay));
+
+ if (m_n16BitGamma > 0 &&
+ (GetBackBufFormat()==D3DFMT_R5G6B5 || GetBackBufFormat()==D3DFMT_X1R5G5B5 || GetBackBufFormat()==D3DFMT_A1R5G5B5 || GetBackBufFormat()==D3DFMT_A4R4G4B4) &&
+ fDecay < 0.9999f)
+ {
+ fDecay = min(fDecay, (32.0f - m_n16BitGamma)/32.0f);
+ }
+
+ D3DCOLOR cDecay = D3DCOLOR_RGBA_01(fDecay,fDecay,fDecay,1);
+
+ // hurl the triangle strips at the video card
+ int poly;
+ for (poly=0; poly<(m_nGridX+1)*2; poly++)
+ m_verts_temp[poly].Diffuse = cDecay;
+
+ if (bAlphaBlend)
+ {
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ if (bFlipAlpha)
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
+ }
+ else
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ }
+ }
+ else
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ int nAlphaTestValue = 0;
+ if (bFlipCulling)
+ nAlphaTestValue = 1-nAlphaTestValue;
+
+ // Hurl the triangles at the video card.
+ // We're going to un-index it, so that we don't stress any crappy (AHEM intel g33)
+ // drivers out there.
+ // If we're blending, we'll skip any polygon that is all alpha-blended out.
+ // This also respects the MaxPrimCount limit of the video card.
+ MYVERTEX tempv[1024 * 3];
+ int max_prims_per_batch = min( GetCaps()->MaxPrimitiveCount, (sizeof(tempv)/sizeof(tempv[0]))/3) - 4;
+ int primCount = m_nGridX*m_nGridY*2;
+ int src_idx = 0;
+ int prims_sent = 0;
+ while (src_idx < primCount*3)
+ {
+ int prims_queued = 0;
+ int i=0;
+ while (prims_queued < max_prims_per_batch && src_idx < primCount*3)
+ {
+ // copy 3 verts
+ for (int j=0; j<3; j++)
+ {
+ tempv[i++] = m_verts[ m_indices_list[src_idx++] ];
+ // don't forget to flip sign on Y and factor in the decay color!:
+ tempv[i-1].y *= -1;
+ tempv[i-1].Diffuse = (cDecay & 0x00FFFFFF) | (tempv[i-1].Diffuse & 0xFF000000);
+ }
+ if (bCullTiles)
+ {
+ DWORD d1 = (tempv[i-3].Diffuse >> 24);
+ DWORD d2 = (tempv[i-2].Diffuse >> 24);
+ DWORD d3 = (tempv[i-1].Diffuse >> 24);
+ bool bIsNeeded;
+ if (nAlphaTestValue)
+ bIsNeeded = ((d1 & d2 & d3) < 255);//(d1 < 255) || (d2 < 255) || (d3 < 255);
+ else
+ bIsNeeded = ((d1|d2|d3) > 0);//(d1 > 0) || (d2 > 0) || (d3 > 0);
+ if (!bIsNeeded)
+ i -= 3;
+ else
+ prims_queued++;
+ }
+ else
+ prims_queued++;
+ }
+ if (prims_queued > 0)
+ lpDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, prims_queued, tempv, sizeof(MYVERTEX) );
+ }
+
+ /*
+ if (!bCullTiles)
+ {
+ assert(!bAlphaBlend); //not handled yet
+
+ // draw normally - just a full triangle strip for each half-row of cells
+ // (even if we are blending, it is between two pre-pixel-shader presets,
+ // so the blend all happens exclusively in the per-vertex equations.)
+ for (int strip=0; strip<m_nGridY*2; strip++)
+ {
+ int index = strip * (m_nGridX+2);
+
+ for (poly=0; poly<m_nGridX+2; poly++)
+ {
+ int ref_vert = m_indices_strip[index];
+ m_verts_temp[poly].x = m_verts[ref_vert].x;
+ m_verts_temp[poly].y = -m_verts[ref_vert].y;
+ m_verts_temp[poly].z = m_verts[ref_vert].z;
+ m_verts_temp[poly].tu = m_verts[ref_vert].tu;
+ m_verts_temp[poly].tv = m_verts[ref_vert].tv;
+ //m_verts_temp[poly].Diffuse = cDecay; this is done just once - see jsut above
+ index++;
+ }
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, m_nGridX, (void*)m_verts_temp, sizeof(MYVERTEX));
+ }
+ }
+ else
+ {
+ // we're blending to/from a new pixel-shader enabled preset;
+ // only draw the cells needed! (an optimization)
+ int nAlphaTestValue = 0;
+ if (bFlipCulling)
+ nAlphaTestValue = 1-nAlphaTestValue;
+
+ int idx[2048];
+ for (int y=0; y<m_nGridY; y++)
+ {
+ // copy verts & flip sign on Y
+ int ref_vert = y*(m_nGridX+1);
+ for (int i=0; i<(m_nGridX+1)*2; i++)
+ {
+ m_verts_temp[i].x = m_verts[ref_vert].x;
+ m_verts_temp[i].y = -m_verts[ref_vert].y;
+ m_verts_temp[i].z = m_verts[ref_vert].z;
+ m_verts_temp[i].tu = m_verts[ref_vert].tu;
+ m_verts_temp[i].tv = m_verts[ref_vert].tv;
+ m_verts_temp[i].Diffuse = (cDecay & 0x00FFFFFF) | (m_verts[ref_vert].Diffuse & 0xFF000000);
+ ref_vert++;
+ }
+
+ // create (smart) indices
+ int count = 0;
+ int nVert = 0;
+ bool bWasNeeded;
+ ref_vert = (y)*(m_nGridX+1);
+ DWORD d1 = (m_verts[ref_vert ].Diffuse >> 24);
+ DWORD d2 = (m_verts[ref_vert+m_nGridX+1].Diffuse >> 24);
+ if (nAlphaTestValue)
+ bWasNeeded = (d1 < 255) || (d2 < 255);
+ else
+ bWasNeeded = (d1 > 0) || (d2 > 0);
+ for (i=0; i<m_nGridX; i++)
+ {
+ bool bIsNeeded;
+ DWORD d1 = (m_verts[ref_vert+1 ].Diffuse >> 24);
+ DWORD d2 = (m_verts[ref_vert+1+m_nGridX+1].Diffuse >> 24);
+ if (nAlphaTestValue)
+ bIsNeeded = (d1 < 255) || (d2 < 255);
+ else
+ bIsNeeded = (d1 > 0) || (d2 > 0);
+
+ if (bIsNeeded || bWasNeeded)
+ {
+ idx[count++] = nVert;
+ idx[count++] = nVert+1;
+ idx[count++] = nVert+m_nGridX+1;
+ idx[count++] = nVert+m_nGridX+1;
+ idx[count++] = nVert+1;
+ idx[count++] = nVert+m_nGridX+2;
+ }
+ bWasNeeded = bIsNeeded;
+
+ nVert++;
+ ref_vert++;
+ }
+ lpDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, (m_nGridX+1)*2, count/3, (void*)idx, D3DFMT_INDEX32, (void*)m_verts_temp, sizeof(MYVERTEX));
+ }
+ }/**/
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+}
+
+void CPlugin::WarpedBlit_Shaders(int nPass, bool bAlphaBlend, bool bFlipAlpha, bool bCullTiles, bool bFlipCulling)
+{
+ // if nPass==0, it draws old preset (blending 1 of 2).
+ // if nPass==1, it draws new preset (blending 2 of 2, OR done blending)
+
+ MungeFPCW(NULL); // puts us in single-precision mode & disables exceptions
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ if (!wcscmp(m_pState->m_szDesc, INVALID_PRESET_DESC))
+ {
+ // if no valid preset loaded, clear the target to black, and return
+ lpDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
+ return;
+ }
+
+ //float fBlend = m_pState->m_fBlendProgress;//max(0,min(1,(m_pState->m_fBlendProgress*1.6f - 0.3f)));
+ //if (nPassOverride==0)
+ // fBlend = 1-fBlend; // <-- THIS IS THE KEY - FLIPS THE ALPHAS AND EVERYTHING ELSE JUST WORKS.
+ //bool bBlending = m_pState->m_bBlending;//(fBlend >= 0.0001f && fBlend <= 0.9999f);
+
+ //lpDevice->SetTexture(0, m_lpVS[0]);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( MYVERTEX_FORMAT );
+
+ // texel alignment
+ float texel_offset_x = 0.5f / (float)m_nTexSizeX;
+ float texel_offset_y = 0.5f / (float)m_nTexSizeY;
+
+ int nAlphaTestValue = 0;
+ if (bFlipCulling)
+ nAlphaTestValue = 1-nAlphaTestValue;
+
+ if (bAlphaBlend)
+ {
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ if (bFlipAlpha)
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
+ }
+ else
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ }
+ }
+ else
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ int pass = nPass;
+ {
+ // PASS 0: draw using *blended per-vertex motion vectors*, but with the OLD warp shader.
+ // PASS 1: draw using *blended per-vertex motion vectors*, but with the NEW warp shader.
+ PShaderInfo* si = (pass==0) ? &m_OldShaders.warp : &m_shaders.warp;
+ CState* state = (pass==0) ? m_pOldState : m_pState;
+
+ lpDevice->SetVertexDeclaration(m_pMyVertDecl);
+ lpDevice->SetVertexShader(m_fallbackShaders_vs.warp.ptr);
+ lpDevice->SetPixelShader (si->ptr);
+
+ ApplyShaderParams( &(si->params), si->CT, state );
+
+ // Hurl the triangles at the video card.
+ // We're going to un-index it, so that we don't stress any crappy (AHEM intel g33)
+ // drivers out there.
+ // We divide it into the two halves of the screen (top/bottom) so we can hack
+ // the 'ang' values along the angle-wrap seam, halfway through the draw.
+ // If we're blending, we'll skip any polygon that is all alpha-blended out.
+ // This also respects the MaxPrimCount limit of the video card.
+ MYVERTEX tempv[1024 * 3];
+ int max_prims_per_batch = min( GetCaps()->MaxPrimitiveCount, (sizeof(tempv)/sizeof(tempv[0]))/3) - 4;
+ for (int half=0; half<2; half++)
+ {
+ // hack / restore the ang values along the angle-wrap [0 <-> 2pi] seam...
+ float new_ang = half ? 3.1415926535897932384626433832795f : -3.1415926535897932384626433832795f;
+ int y_offset = (m_nGridY/2) * (m_nGridX+1);
+ for (int x=0; x<m_nGridX/2; x++)
+ m_verts[y_offset + x].ang = new_ang;
+
+ // send half of the polys
+ int primCount = m_nGridX*m_nGridY*2 / 2; // in this case, to draw HALF the polys
+ int src_idx = 0;
+ int src_idx_offset = half * primCount*3;
+ int prims_sent = 0;
+ while (src_idx < primCount*3)
+ {
+ int prims_queued = 0;
+ int i=0;
+ while (prims_queued < max_prims_per_batch && src_idx < primCount*3)
+ {
+ // copy 3 verts
+ for (int j=0; j<3; j++)
+ tempv[i++] = m_verts[ m_indices_list[src_idx_offset + src_idx++] ];
+ if (bCullTiles)
+ {
+ DWORD d1 = (tempv[i-3].Diffuse >> 24);
+ DWORD d2 = (tempv[i-2].Diffuse >> 24);
+ DWORD d3 = (tempv[i-1].Diffuse >> 24);
+ bool bIsNeeded;
+ if (nAlphaTestValue)
+ bIsNeeded = ((d1 & d2 & d3) < 255);//(d1 < 255) || (d2 < 255) || (d3 < 255);
+ else
+ bIsNeeded = ((d1|d2|d3) > 0);//(d1 > 0) || (d2 > 0) || (d3 > 0);
+ if (!bIsNeeded)
+ i -= 3;
+ else
+ prims_queued++;
+ }
+ else
+ prims_queued++;
+ }
+ if (prims_queued > 0)
+ lpDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, prims_queued, tempv, sizeof(MYVERTEX) );
+ }
+ }
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ RestoreShaderParams();
+}
+
+void CPlugin::DrawCustomShapes()
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ //lpDevice->SetTexture(0, m_lpVS[0]);//NULL);
+ //lpDevice->SetVertexShader( SPRITEVERTEX_FORMAT );
+
+ int num_reps = (m_pState->m_bBlending) ? 2 : 1;
+ for (int rep=0; rep<num_reps; rep++)
+ {
+ CState *pState = (rep==0) ? m_pState : m_pOldState;
+ float alpha_mult = 1;
+ if (num_reps==2)
+ alpha_mult = (rep==0) ? m_pState->m_fBlendProgress : (1-m_pState->m_fBlendProgress);
+
+ for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ if (pState->m_shape[i].enabled)
+ {
+ /*
+ int bAdditive = 0;
+ int nSides = 3;//3 + ((int)GetTime() % 8);
+ int bThickOutline = 0;
+ float x = 0.5f + 0.1f*cosf(GetTime()*0.8f+1);
+ float y = 0.5f + 0.1f*sinf(GetTime()*0.8f+1);
+ float rad = 0.15f + 0.07f*sinf(GetTime()*1.1f+3);
+ float ang = GetTime()*1.5f;
+
+ // inside colors
+ float r = 1;
+ float g = 0;
+ float b = 0;
+ float a = 0.4f;//0.1f + 0.1f*sinf(GetTime()*0.31f);
+
+ // outside colors
+ float r2 = 0;
+ float g2 = 1;
+ float b2 = 0;
+ float a2 = 0;
+
+ // border colors
+ float border_r = 1;
+ float border_g = 1;
+ float border_b = 1;
+ float border_a = 0.5f;
+ */
+
+ for (int instance=0; instance<pState->m_shape[i].instances; instance++)
+ {
+ // 1. execute per-frame code
+ LoadCustomShapePerFrameEvallibVars(pState, i, instance);
+
+ #ifndef _NO_EXPR_
+ if (pState->m_shape[i].m_pf_codehandle)
+ {
+ NSEEL_code_execute(pState->m_shape[i].m_pf_codehandle);
+ }
+ #endif
+
+ // save changes to t1-t8 this frame
+ /*
+ pState->m_shape[i].t_values_after_init_code[0] = *pState->m_shape[i].var_pf_t1;
+ pState->m_shape[i].t_values_after_init_code[1] = *pState->m_shape[i].var_pf_t2;
+ pState->m_shape[i].t_values_after_init_code[2] = *pState->m_shape[i].var_pf_t3;
+ pState->m_shape[i].t_values_after_init_code[3] = *pState->m_shape[i].var_pf_t4;
+ pState->m_shape[i].t_values_after_init_code[4] = *pState->m_shape[i].var_pf_t5;
+ pState->m_shape[i].t_values_after_init_code[5] = *pState->m_shape[i].var_pf_t6;
+ pState->m_shape[i].t_values_after_init_code[6] = *pState->m_shape[i].var_pf_t7;
+ pState->m_shape[i].t_values_after_init_code[7] = *pState->m_shape[i].var_pf_t8;
+ */
+
+ int sides = (int)(*pState->m_shape[i].var_pf_sides);
+ if (sides<3) sides=3;
+ if (sides>100) sides=100;
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, ((int)(*pState->m_shape[i].var_pf_additive) != 0) ? D3DBLEND_ONE : D3DBLEND_INVSRCALPHA);
+
+ SPRITEVERTEX v[512]; // for textured shapes (has texcoords)
+ WFVERTEX v2[512]; // for untextured shapes + borders
+
+ v[0].x = (float)(*pState->m_shape[i].var_pf_x* 2-1);// * ASPECT;
+ v[0].y = (float)(*pState->m_shape[i].var_pf_y*-2+1);
+ v[0].z = 0;
+ v[0].tu = 0.5f;
+ v[0].tv = 0.5f;
+ v[0].Diffuse =
+ ((((int)(*pState->m_shape[i].var_pf_a * 255 * alpha_mult)) & 0xFF) << 24) |
+ ((((int)(*pState->m_shape[i].var_pf_r * 255)) & 0xFF) << 16) |
+ ((((int)(*pState->m_shape[i].var_pf_g * 255)) & 0xFF) << 8) |
+ ((((int)(*pState->m_shape[i].var_pf_b * 255)) & 0xFF) );
+ v[1].Diffuse =
+ ((((int)(*pState->m_shape[i].var_pf_a2 * 255 * alpha_mult)) & 0xFF) << 24) |
+ ((((int)(*pState->m_shape[i].var_pf_r2 * 255)) & 0xFF) << 16) |
+ ((((int)(*pState->m_shape[i].var_pf_g2 * 255)) & 0xFF) << 8) |
+ ((((int)(*pState->m_shape[i].var_pf_b2 * 255)) & 0xFF) );
+
+ int j = 1;
+ for (j=1; j<sides+1; j++)
+ {
+ float t = (j-1)/(float)sides;
+ v[j].x = v[0].x + (float)*pState->m_shape[i].var_pf_rad*cosf(t*3.1415927f*2 + (float)*pState->m_shape[i].var_pf_ang + 3.1415927f*0.25f)*m_fAspectY; // DON'T TOUCH!
+ v[j].y = v[0].y + (float)*pState->m_shape[i].var_pf_rad*sinf(t*3.1415927f*2 + (float)*pState->m_shape[i].var_pf_ang + 3.1415927f*0.25f); // DON'T TOUCH!
+ v[j].z = 0;
+ v[j].tu = 0.5f + 0.5f*cosf(t*3.1415927f*2 + (float)*pState->m_shape[i].var_pf_tex_ang + 3.1415927f*0.25f)/((float)*pState->m_shape[i].var_pf_tex_zoom) * m_fAspectY; // DON'T TOUCH!
+ v[j].tv = 0.5f + 0.5f*sinf(t*3.1415927f*2 + (float)*pState->m_shape[i].var_pf_tex_ang + 3.1415927f*0.25f)/((float)*pState->m_shape[i].var_pf_tex_zoom); // DON'T TOUCH!
+ v[j].Diffuse = v[1].Diffuse;
+ }
+ v[sides+1] = v[1];
+
+ if ((int)(*pState->m_shape[i].var_pf_textured) != 0)
+ {
+ // draw textured version
+ lpDevice->SetTexture(0, m_lpVS[0]);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, sides, (void*)v, sizeof(SPRITEVERTEX));
+ }
+ else
+ {
+ // no texture
+ for (j=0; j < sides+2; j++)
+ {
+ v2[j].x = v[j].x;
+ v2[j].y = v[j].y;
+ v2[j].z = v[j].z;
+ v2[j].Diffuse = v[j].Diffuse;
+ }
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( WFVERTEX_FORMAT );
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, sides, (void*)v2, sizeof(WFVERTEX));
+ }
+
+ // DRAW BORDER
+ if (*pState->m_shape[i].var_pf_border_a > 0)
+ {
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( WFVERTEX_FORMAT );
+
+ v2[0].Diffuse =
+ ((((int)(*pState->m_shape[i].var_pf_border_a * 255 * alpha_mult)) & 0xFF) << 24) |
+ ((((int)(*pState->m_shape[i].var_pf_border_r * 255)) & 0xFF) << 16) |
+ ((((int)(*pState->m_shape[i].var_pf_border_g * 255)) & 0xFF) << 8) |
+ ((((int)(*pState->m_shape[i].var_pf_border_b * 255)) & 0xFF) );
+ for (j=0; j<sides+2; j++)
+ {
+ v2[j].x = v[j].x;
+ v2[j].y = v[j].y;
+ v2[j].z = v[j].z;
+ v2[j].Diffuse = v2[0].Diffuse;
+ }
+
+ int its = ((int)(*pState->m_shape[i].var_pf_thick) != 0) ? 4 : 1;
+ float x_inc = 2.0f / (float)m_nTexSizeX;
+ float y_inc = 2.0f / (float)m_nTexSizeY;
+ for (int it=0; it<its; it++)
+ {
+ switch(it)
+ {
+ case 0: break;
+ case 1: for (j=0; j<sides+2; j++) v2[j].x += x_inc; break; // draw fat dots
+ case 2: for (j=0; j<sides+2; j++) v2[j].y += y_inc; break; // draw fat dots
+ case 3: for (j=0; j<sides+2; j++) v2[j].x -= x_inc; break; // draw fat dots
+ }
+ lpDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, sides, (void*)&v2[1], sizeof(WFVERTEX));
+ }
+ }
+
+ lpDevice->SetTexture(0, m_lpVS[0]);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+ }
+ }
+ }
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+}
+
+void CPlugin::LoadCustomShapePerFrameEvallibVars(CState* pState, int i, int instance)
+{
+ *pState->m_shape[i].var_pf_time = (double)(GetTime() - m_fStartTime);
+ *pState->m_shape[i].var_pf_frame = (double)GetFrame();
+ *pState->m_shape[i].var_pf_fps = (double)GetFps();
+ *pState->m_shape[i].var_pf_progress = (GetTime() - m_fPresetStartTime) / (m_fNextPresetTime - m_fPresetStartTime);
+ *pState->m_shape[i].var_pf_bass = (double)mysound.imm_rel[0];
+ *pState->m_shape[i].var_pf_mid = (double)mysound.imm_rel[1];
+ *pState->m_shape[i].var_pf_treb = (double)mysound.imm_rel[2];
+ *pState->m_shape[i].var_pf_bass_att = (double)mysound.avg_rel[0];
+ *pState->m_shape[i].var_pf_mid_att = (double)mysound.avg_rel[1];
+ *pState->m_shape[i].var_pf_treb_att = (double)mysound.avg_rel[2];
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ *pState->m_shape[i].var_pf_q[vi] = *pState->var_pf_q[vi];
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ *pState->m_shape[i].var_pf_t[vi] = pState->m_shape[i].t_values_after_init_code[vi];
+ *pState->m_shape[i].var_pf_x = pState->m_shape[i].x;
+ *pState->m_shape[i].var_pf_y = pState->m_shape[i].y;
+ *pState->m_shape[i].var_pf_rad = pState->m_shape[i].rad;
+ *pState->m_shape[i].var_pf_ang = pState->m_shape[i].ang;
+ *pState->m_shape[i].var_pf_tex_zoom = pState->m_shape[i].tex_zoom;
+ *pState->m_shape[i].var_pf_tex_ang = pState->m_shape[i].tex_ang;
+ *pState->m_shape[i].var_pf_sides = pState->m_shape[i].sides;
+ *pState->m_shape[i].var_pf_additive = pState->m_shape[i].additive;
+ *pState->m_shape[i].var_pf_textured = pState->m_shape[i].textured;
+ *pState->m_shape[i].var_pf_instances = pState->m_shape[i].instances;
+ *pState->m_shape[i].var_pf_instance = instance;
+ *pState->m_shape[i].var_pf_thick = pState->m_shape[i].thickOutline;
+ *pState->m_shape[i].var_pf_r = pState->m_shape[i].r;
+ *pState->m_shape[i].var_pf_g = pState->m_shape[i].g;
+ *pState->m_shape[i].var_pf_b = pState->m_shape[i].b;
+ *pState->m_shape[i].var_pf_a = pState->m_shape[i].a;
+ *pState->m_shape[i].var_pf_r2 = pState->m_shape[i].r2;
+ *pState->m_shape[i].var_pf_g2 = pState->m_shape[i].g2;
+ *pState->m_shape[i].var_pf_b2 = pState->m_shape[i].b2;
+ *pState->m_shape[i].var_pf_a2 = pState->m_shape[i].a2;
+ *pState->m_shape[i].var_pf_border_r = pState->m_shape[i].border_r;
+ *pState->m_shape[i].var_pf_border_g = pState->m_shape[i].border_g;
+ *pState->m_shape[i].var_pf_border_b = pState->m_shape[i].border_b;
+ *pState->m_shape[i].var_pf_border_a = pState->m_shape[i].border_a;
+}
+
+void CPlugin::LoadCustomWavePerFrameEvallibVars(CState* pState, int i)
+{
+ *pState->m_wave[i].var_pf_time = (double)(GetTime() - m_fStartTime);
+ *pState->m_wave[i].var_pf_frame = (double)GetFrame();
+ *pState->m_wave[i].var_pf_fps = (double)GetFps();
+ *pState->m_wave[i].var_pf_progress = (GetTime() - m_fPresetStartTime) / (m_fNextPresetTime - m_fPresetStartTime);
+ *pState->m_wave[i].var_pf_bass = (double)mysound.imm_rel[0];
+ *pState->m_wave[i].var_pf_mid = (double)mysound.imm_rel[1];
+ *pState->m_wave[i].var_pf_treb = (double)mysound.imm_rel[2];
+ *pState->m_wave[i].var_pf_bass_att = (double)mysound.avg_rel[0];
+ *pState->m_wave[i].var_pf_mid_att = (double)mysound.avg_rel[1];
+ *pState->m_wave[i].var_pf_treb_att = (double)mysound.avg_rel[2];
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ *pState->m_wave[i].var_pf_q[vi] = *pState->var_pf_q[vi];
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ *pState->m_wave[i].var_pf_t[vi] = pState->m_wave[i].t_values_after_init_code[vi];
+ *pState->m_wave[i].var_pf_r = pState->m_wave[i].r;
+ *pState->m_wave[i].var_pf_g = pState->m_wave[i].g;
+ *pState->m_wave[i].var_pf_b = pState->m_wave[i].b;
+ *pState->m_wave[i].var_pf_a = pState->m_wave[i].a;
+ *pState->m_wave[i].var_pf_samples = pState->m_wave[i].samples;
+}
+
+// does a better-than-linear smooth on a wave. Roughly doubles the # of points.
+int SmoothWave(WFVERTEX* vi, int nVertsIn, WFVERTEX* vo)
+{
+ const float c1 = -0.15f;
+ const float c2 = 1.15f;
+ const float c3 = 1.15f;
+ const float c4 = -0.15f;
+ const float inv_sum = 1.0f/(c1+c2+c3+c4);
+
+ int j = 0;
+
+ int i_below = 0;
+ int i_above;
+ int i_above2 = 1;
+ for (int i=0; i<nVertsIn-1; i++)
+ {
+ i_above = i_above2;
+ i_above2 = min(nVertsIn-1,i+2);
+ vo[j] = vi[i];
+ vo[j+1].x = (c1*vi[i_below].x + c2*vi[i].x + c3*vi[i_above].x + c4*vi[i_above2].x)*inv_sum;
+ vo[j+1].y = (c1*vi[i_below].y + c2*vi[i].y + c3*vi[i_above].y + c4*vi[i_above2].y)*inv_sum;
+ vo[j+1].z = 0;
+ vo[j+1].Diffuse = vi[i].Diffuse;//0xFFFF0080;
+ i_below = i;
+ j += 2;
+ }
+ vo[j++] = vi[nVertsIn-1];
+
+ return j;
+}
+
+void CPlugin::DrawCustomWaves()
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( WFVERTEX_FORMAT );
+
+ // note: read in all sound data from CPluginShell's m_sound
+ int num_reps = (m_pState->m_bBlending) ? 2 : 1;
+ for (int rep=0; rep<num_reps; rep++)
+ {
+ CState *pState = (rep==0) ? m_pState : m_pOldState;
+ float alpha_mult = 1;
+ if (num_reps==2)
+ alpha_mult = (rep==0) ? m_pState->m_fBlendProgress : (1-m_pState->m_fBlendProgress);
+
+ for (int i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ if (pState->m_wave[i].enabled)
+ {
+ int nSamples = pState->m_wave[i].samples;
+ int max_samples = pState->m_wave[i].bSpectrum ? 512 : NUM_WAVEFORM_SAMPLES;
+ if (nSamples > max_samples)
+ nSamples = max_samples;
+ nSamples -= pState->m_wave[i].sep;
+
+ // 1. execute per-frame code
+ LoadCustomWavePerFrameEvallibVars(pState, i);
+
+ // 2.a. do just a once-per-frame init for the *per-point* *READ-ONLY* variables
+ // (the non-read-only ones will be reset/restored at the start of each vertex)
+ *pState->m_wave[i].var_pp_time = *pState->m_wave[i].var_pf_time;
+ *pState->m_wave[i].var_pp_fps = *pState->m_wave[i].var_pf_fps;
+ *pState->m_wave[i].var_pp_frame = *pState->m_wave[i].var_pf_frame;
+ *pState->m_wave[i].var_pp_progress = *pState->m_wave[i].var_pf_progress;
+ *pState->m_wave[i].var_pp_bass = *pState->m_wave[i].var_pf_bass;
+ *pState->m_wave[i].var_pp_mid = *pState->m_wave[i].var_pf_mid;
+ *pState->m_wave[i].var_pp_treb = *pState->m_wave[i].var_pf_treb;
+ *pState->m_wave[i].var_pp_bass_att = *pState->m_wave[i].var_pf_bass_att;
+ *pState->m_wave[i].var_pp_mid_att = *pState->m_wave[i].var_pf_mid_att;
+ *pState->m_wave[i].var_pp_treb_att = *pState->m_wave[i].var_pf_treb_att;
+
+ NSEEL_code_execute(pState->m_wave[i].m_pf_codehandle);
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ *pState->m_wave[i].var_pp_q[vi] = *pState->m_wave[i].var_pf_q[vi];
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ *pState->m_wave[i].var_pp_t[vi] = *pState->m_wave[i].var_pf_t[vi];
+
+ nSamples = (int)*pState->m_wave[i].var_pf_samples;
+ nSamples = min(512, nSamples);
+
+ if ((nSamples >= 2) || (pState->m_wave[i].bUseDots && nSamples >= 1))
+ {
+ int j;
+ float tempdata[2][512];
+ float mult = ((pState->m_wave[i].bSpectrum) ? 0.15f : 0.004f) * pState->m_wave[i].scaling * pState->m_fWaveScale.eval(-1);
+ float *pdata1 = (pState->m_wave[i].bSpectrum) ? m_sound.fSpectrum[0] : m_sound.fWaveform[0];
+ float *pdata2 = (pState->m_wave[i].bSpectrum) ? m_sound.fSpectrum[1] : m_sound.fWaveform[1];
+
+ // initialize tempdata[2][512]
+ int j0 = (pState->m_wave[i].bSpectrum) ? 0 : (max_samples - nSamples)/2/**(1-pState->m_wave[i].bSpectrum)*/ - pState->m_wave[i].sep/2;
+ int j1 = (pState->m_wave[i].bSpectrum) ? 0 : (max_samples - nSamples)/2/**(1-pState->m_wave[i].bSpectrum)*/ + pState->m_wave[i].sep/2;
+ float t = (pState->m_wave[i].bSpectrum) ? (max_samples - pState->m_wave[i].sep)/(float)nSamples : 1;
+ float mix1 = powf(pState->m_wave[i].smoothing*0.98f, 0.5f); // lower exponent -> more default smoothing
+ float mix2 = 1-mix1;
+ // SMOOTHING:
+ tempdata[0][0] = pdata1[j0];
+ tempdata[1][0] = pdata2[j1];
+ for (j=1; j<nSamples; j++)
+ {
+ tempdata[0][j] = pdata1[(int)(j*t)+j0]*mix2 + tempdata[0][j-1]*mix1;
+ tempdata[1][j] = pdata2[(int)(j*t)+j1]*mix2 + tempdata[1][j-1]*mix1;
+ }
+ // smooth again, backwards: [this fixes the asymmetry of the beginning & end..]
+ for (j=nSamples-2; j>=0; j--)
+ {
+ tempdata[0][j] = tempdata[0][j]*mix2 + tempdata[0][j+1]*mix1;
+ tempdata[1][j] = tempdata[1][j]*mix2 + tempdata[1][j+1]*mix1;
+ }
+ // finally, scale to final size:
+ for (j=0; j<nSamples; j++)
+ {
+ tempdata[0][j] *= mult;
+ tempdata[1][j] *= mult;
+ }
+
+ // 2. for each point, execute per-point code
+
+
+ // to do:
+ // -add any of the m_wave[i].xxx menu-accessible vars to the code?
+ WFVERTEX v[1024];
+ float j_mult = 1.0f/(float)(nSamples-1);
+ for (j=0; j<nSamples; j++)
+ {
+ float t = j*j_mult;
+ float value1 = tempdata[0][j];
+ float value2 = tempdata[1][j];
+ *pState->m_wave[i].var_pp_sample = t;
+ *pState->m_wave[i].var_pp_value1 = value1;
+ *pState->m_wave[i].var_pp_value2 = value2;
+ *pState->m_wave[i].var_pp_x = 0.5f + value1;
+ *pState->m_wave[i].var_pp_y = 0.5f + value2;
+ *pState->m_wave[i].var_pp_r = *pState->m_wave[i].var_pf_r;
+ *pState->m_wave[i].var_pp_g = *pState->m_wave[i].var_pf_g;
+ *pState->m_wave[i].var_pp_b = *pState->m_wave[i].var_pf_b;
+ *pState->m_wave[i].var_pp_a = *pState->m_wave[i].var_pf_a;
+
+ #ifndef _NO_EXPR_
+ NSEEL_code_execute(pState->m_wave[i].m_pp_codehandle);
+ #endif
+
+ v[j].x = (float)(*pState->m_wave[i].var_pp_x* 2-1)*m_fInvAspectX;
+ v[j].y = (float)(*pState->m_wave[i].var_pp_y*-2+1)*m_fInvAspectY;
+ v[j].z = 0;
+ v[j].Diffuse =
+ ((((int)(*pState->m_wave[i].var_pp_a * 255 * alpha_mult)) & 0xFF) << 24) |
+ ((((int)(*pState->m_wave[i].var_pp_r * 255)) & 0xFF) << 16) |
+ ((((int)(*pState->m_wave[i].var_pp_g * 255)) & 0xFF) << 8) |
+ ((((int)(*pState->m_wave[i].var_pp_b * 255)) & 0xFF) );
+ }
+
+
+
+ // save changes to t1-t8 this frame
+ /*
+ pState->m_wave[i].t_values_after_init_code[0] = *pState->m_wave[i].var_pp_t1;
+ pState->m_wave[i].t_values_after_init_code[1] = *pState->m_wave[i].var_pp_t2;
+ pState->m_wave[i].t_values_after_init_code[2] = *pState->m_wave[i].var_pp_t3;
+ pState->m_wave[i].t_values_after_init_code[3] = *pState->m_wave[i].var_pp_t4;
+ pState->m_wave[i].t_values_after_init_code[4] = *pState->m_wave[i].var_pp_t5;
+ pState->m_wave[i].t_values_after_init_code[5] = *pState->m_wave[i].var_pp_t6;
+ pState->m_wave[i].t_values_after_init_code[6] = *pState->m_wave[i].var_pp_t7;
+ pState->m_wave[i].t_values_after_init_code[7] = *pState->m_wave[i].var_pp_t8;
+ */
+
+ // 3. smooth it
+ WFVERTEX v2[2048];
+ WFVERTEX *pVerts = v;
+ if (!pState->m_wave[i].bUseDots)
+ {
+ nSamples = SmoothWave(v, nSamples, v2);
+ pVerts = v2;
+ }
+
+ // 4. draw it
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, pState->m_wave[i].bAdditive ? D3DBLEND_ONE : D3DBLEND_INVSRCALPHA);
+
+ float ptsize = (float)((m_nTexSizeX >= 1024) ? 2 : 1) + (pState->m_wave[i].bDrawThick ? 1 : 0);
+ if (pState->m_wave[i].bUseDots)
+ lpDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&ptsize) );
+
+ int its = (pState->m_wave[i].bDrawThick && !pState->m_wave[i].bUseDots) ? 4 : 1;
+ float x_inc = 2.0f / (float)m_nTexSizeX;
+ float y_inc = 2.0f / (float)m_nTexSizeY;
+ for (int it=0; it<its; it++)
+ {
+ switch(it)
+ {
+ case 0: break;
+ case 1: for (j=0; j<nSamples; j++) pVerts[j].x += x_inc; break; // draw fat dots
+ case 2: for (j=0; j<nSamples; j++) pVerts[j].y += y_inc; break; // draw fat dots
+ case 3: for (j=0; j<nSamples; j++) pVerts[j].x -= x_inc; break; // draw fat dots
+ }
+ lpDevice->DrawPrimitiveUP(pState->m_wave[i].bUseDots ? D3DPT_POINTLIST : D3DPT_LINESTRIP, nSamples - (pState->m_wave[i].bUseDots ? 0 : 1), (void*)pVerts, sizeof(WFVERTEX));
+ }
+
+ ptsize = 1.0f;
+ if (pState->m_wave[i].bUseDots)
+ lpDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&ptsize) );
+ }
+ }
+ }
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+}
+
+void CPlugin::DrawWave(float *fL, float *fR)
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( WFVERTEX_FORMAT );
+
+ int i;
+ WFVERTEX v1[576+1], v2[576+1];
+
+ /*
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD); //D3DSHADE_FLAT
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE);
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
+ if (m_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER)
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE);
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_COLORVERTEX, TRUE);
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_FILLMODE, D3DFILL_WIREFRAME); // vs. SOLID
+ m_lpD3DDev->SetRenderState(D3DRENDERSTATE_AMBIENT, D3DCOLOR_RGBA_01(1,1,1,1));
+
+ hr = m_lpD3DDev->SetTexture(0, NULL);
+ if (hr != D3D_OK)
+ {
+ //dumpmsg("Draw(): ERROR: SetTexture");
+ //IdentifyD3DError(hr);
+ }
+ */
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, (*m_pState->var_pf_wave_additive) ? D3DBLEND_ONE : D3DBLEND_INVSRCALPHA);
+
+ //float cr = m_pState->m_waveR.eval(GetTime());
+ //float cg = m_pState->m_waveG.eval(GetTime());
+ //float cb = m_pState->m_waveB.eval(GetTime());
+ float cr = (float)(*m_pState->var_pf_wave_r);
+ float cg = (float)(*m_pState->var_pf_wave_g);
+ float cb = (float)(*m_pState->var_pf_wave_b);
+ float cx = (float)(*m_pState->var_pf_wave_x);
+ float cy = (float)(*m_pState->var_pf_wave_y); // note: it was backwards (top==1) in the original milkdrop, so we keep it that way!
+ float fWaveParam = (float)(*m_pState->var_pf_wave_mystery);
+
+ /*if (m_pState->m_bBlending)
+ {
+ cr = cr*(m_pState->m_fBlendProgress) + (1.0f-m_pState->m_fBlendProgress)*((float)(*m_pOldState->var_pf_wave_r));
+ cg = cg*(m_pState->m_fBlendProgress) + (1.0f-m_pState->m_fBlendProgress)*((float)(*m_pOldState->var_pf_wave_g));
+ cb = cb*(m_pState->m_fBlendProgress) + (1.0f-m_pState->m_fBlendProgress)*((float)(*m_pOldState->var_pf_wave_b));
+ cx = cx*(m_pState->m_fBlendProgress) + (1.0f-m_pState->m_fBlendProgress)*((float)(*m_pOldState->var_pf_wave_x));
+ cy = cy*(m_pState->m_fBlendProgress) + (1.0f-m_pState->m_fBlendProgress)*((float)(*m_pOldState->var_pf_wave_y));
+ fWaveParam = fWaveParam*(m_pState->m_fBlendProgress) + (1.0f-m_pState->m_fBlendProgress)*((float)(*m_pOldState->var_pf_wave_mystery));
+ }*/
+
+ if (cr < 0) cr = 0;
+ if (cg < 0) cg = 0;
+ if (cb < 0) cb = 0;
+ if (cr > 1) cr = 1;
+ if (cg > 1) cg = 1;
+ if (cb > 1) cb = 1;
+
+ // maximize color:
+ if (*m_pState->var_pf_wave_brighten)
+ {
+ float fMaximizeWaveColorAmount = 1.0f;
+ float max = cr;
+ if (max < cg) max = cg;
+ if (max < cb) max = cb;
+ if (max > 0.01f)
+ {
+ cr = cr/max*fMaximizeWaveColorAmount + cr*(1.0f - fMaximizeWaveColorAmount);
+ cg = cg/max*fMaximizeWaveColorAmount + cg*(1.0f - fMaximizeWaveColorAmount);
+ cb = cb/max*fMaximizeWaveColorAmount + cb*(1.0f - fMaximizeWaveColorAmount);
+ }
+ }
+
+ float fWavePosX = cx*2.0f - 1.0f; // go from 0..1 user-range to -1..1 D3D range
+ float fWavePosY = cy*2.0f - 1.0f;
+
+ float bass_rel = mysound.imm[0];
+ float mid_rel = mysound.imm[1];
+ float treble_rel = mysound.imm[2];
+
+ int sample_offset = 0;
+ int new_wavemode = (int)(*m_pState->var_pf_wave_mode) % NUM_WAVES; // since it can be changed from per-frame code!
+
+ int its = (m_pState->m_bBlending && (new_wavemode != m_pState->m_nOldWaveMode)) ? 2 : 1;
+ int nVerts1 = 0;
+ int nVerts2 = 0;
+ int nBreak1 = -1;
+ int nBreak2 = -1;
+ float alpha1, alpha2;
+
+ for (int it=0; it<its; it++)
+ {
+ int wave = (it==0) ? new_wavemode : m_pState->m_nOldWaveMode;
+ int nVerts = NUM_WAVEFORM_SAMPLES; // allowed to peek ahead 64 (i.e. left is [i], right is [i+64])
+ int nBreak = -1;
+
+ float fWaveParam2 = fWaveParam;
+ //std::string fWaveParam; // kill its scope
+ if ((wave==0 || wave==1 || wave==4) && (fWaveParam2 < -1 || fWaveParam2 > 1))
+ {
+ //fWaveParam2 = max(fWaveParam2, -1.0f);
+ //fWaveParam2 = min(fWaveParam2, 1.0f);
+ fWaveParam2 = fWaveParam2*0.5f + 0.5f;
+ fWaveParam2 -= floorf(fWaveParam2);
+ fWaveParam2 = fabsf(fWaveParam2);
+ fWaveParam2 = fWaveParam2*2-1;
+ }
+
+ WFVERTEX *v = (it==0) ? v1 : v2;
+ ZeroMemory(v, sizeof(WFVERTEX)*nVerts);
+
+ float alpha = (float)(*m_pState->var_pf_wave_a);//m_pState->m_fWaveAlpha.eval(GetTime());
+
+ switch(wave)
+ {
+ case 0:
+ // circular wave
+
+ nVerts /= 2;
+ sample_offset = (NUM_WAVEFORM_SAMPLES-nVerts)/2;//mysound.GoGoAlignatron(nVerts * 12/10); // only call this once nVerts is final!
+
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ {
+ float inv_nverts_minus_one = 1.0f/(float)(nVerts-1);
+
+ for (i=0; i<nVerts; i++)
+ {
+ float rad = 0.5f + 0.4f*fR[i+sample_offset] + fWaveParam2;
+ float ang = (i)*inv_nverts_minus_one*6.28f + GetTime()*0.2f;
+ if (i < nVerts/10)
+ {
+ float mix = i/(nVerts*0.1f);
+ mix = 0.5f - 0.5f*cosf(mix * 3.1416f);
+ float rad_2 = 0.5f + 0.4f*fR[i + nVerts + sample_offset] + fWaveParam2;
+ rad = rad_2*(1.0f-mix) + rad*(mix);
+ }
+ v[i].x = rad*cosf(ang) *m_fAspectY + fWavePosX; // 0.75 = adj. for aspect ratio
+ v[i].y = rad*sinf(ang) *m_fAspectX + fWavePosY;
+ //v[i].Diffuse = color;
+ }
+ }
+
+ // dupe last vertex to connect the lines; skip if blending
+ if (!m_pState->m_bBlending)
+ {
+ nVerts++;
+ memcpy(&v[nVerts-1], &v[0], sizeof(WFVERTEX));
+ }
+
+ break;
+
+ case 1:
+ // x-y osc. that goes around in a spiral, in time
+
+ alpha *= 1.25f;
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ nVerts /= 2;
+
+ for (i=0; i<nVerts; i++)
+ {
+ float rad = 0.53f + 0.43f*fR[i] + fWaveParam2;
+ float ang = fL[i+32] * 1.57f + GetTime()*2.3f;
+ v[i].x = rad*cosf(ang) *m_fAspectY + fWavePosX; // 0.75 = adj. for aspect ratio
+ v[i].y = rad*sinf(ang) *m_fAspectX + fWavePosY;
+ //v[i].Diffuse = color;//(D3DCOLOR_RGBA_01(cr, cg, cb, alpha*min(1, max(0, fL[i])));
+ }
+
+ break;
+
+ case 2:
+ // centered spiro (alpha constant)
+ // aimed at not being so sound-responsive, but being very "nebula-like"
+ // difference is that alpha is constant (and faint), and waves a scaled way up
+
+ switch(m_nTexSizeX)
+ {
+ case 256: alpha *= 0.07f; break;
+ case 512: alpha *= 0.09f; break;
+ case 1024: alpha *= 0.11f; break;
+ case 2048: alpha *= 0.13f; break;
+ }
+
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ for (i=0; i<nVerts; i++)
+ {
+ v[i].x = fR[i ] *m_fAspectY + fWavePosX;//((pR[i] ^ 128) - 128)/90.0f * ASPECT; // 0.75 = adj. for aspect ratio
+ v[i].y = fL[i+32] *m_fAspectX + fWavePosY;//((pL[i+32] ^ 128) - 128)/90.0f;
+ //v[i].Diffuse = color;
+ }
+
+ break;
+ case 3:
+ // centered spiro (alpha tied to volume)
+ // aimed at having a strong audio-visual tie-in
+ // colors are always bright (no darks)
+
+ switch(m_nTexSizeX)
+ {
+ case 256: alpha = 0.075f; break;
+ case 512: alpha = 0.150f; break;
+ case 1024: alpha = 0.220f; break;
+ case 2048: alpha = 0.330f; break;
+ }
+
+ alpha *= 1.3f;
+ alpha *= powf(treble_rel, 2.0f);
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ for (i=0; i<nVerts; i++)
+ {
+ v[i].x = fR[i ] *m_fAspectY + fWavePosX;//((pR[i] ^ 128) - 128)/90.0f * ASPECT; // 0.75 = adj. for aspect ratio
+ v[i].y = fL[i+32] *m_fAspectX + fWavePosY;//((pL[i+32] ^ 128) - 128)/90.0f;
+ //v[i].Diffuse = color;
+ }
+ break;
+ case 4:
+ // horizontal "script", left channel
+
+ if (nVerts > m_nTexSizeX/3)
+ nVerts = m_nTexSizeX/3;
+
+ sample_offset = (NUM_WAVEFORM_SAMPLES-nVerts)/2;//mysound.GoGoAlignatron(nVerts + 25); // only call this once nVerts is final!
+
+ /*
+ if (treble_rel > treb_thresh_for_wave6)
+ {
+ //alpha = 1.0f;
+ treb_thresh_for_wave6 = treble_rel * 1.025f;
+ }
+ else
+ {
+ alpha *= 0.2f;
+ treb_thresh_for_wave6 *= 0.996f; // fixme: make this fps-independent
+ }
+ */
+
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ {
+ float w1 = 0.45f + 0.5f*(fWaveParam2*0.5f + 0.5f); // 0.1 - 0.9
+ float w2 = 1.0f - w1;
+
+ float inv_nverts = 1.0f/(float)(nVerts);
+
+ for (i=0; i<nVerts; i++)
+ {
+ v[i].x = -1.0f + 2.0f*(i*inv_nverts) + fWavePosX;
+ v[i].y = fL[i+sample_offset]*0.47f + fWavePosY;//((pL[i] ^ 128) - 128)/270.0f;
+ v[i].x += fR[i+25+sample_offset]*0.44f;//((pR[i+25] ^ 128) - 128)/290.0f;
+ //v[i].Diffuse = color;
+
+ // momentum
+ if (i>1)
+ {
+ v[i].x = v[i].x*w2 + w1*(v[i-1].x*2.0f - v[i-2].x);
+ v[i].y = v[i].y*w2 + w1*(v[i-1].y*2.0f - v[i-2].y);
+ }
+ }
+
+ /*
+ // center on Y
+ float avg_y = 0;
+ for (i=0; i<nVerts; i++)
+ avg_y += v[i].y;
+ avg_y /= (float)nVerts;
+ avg_y *= 0.5f; // damp the movement
+ for (i=0; i<nVerts; i++)
+ v[i].y -= avg_y;
+ */
+ }
+
+ break;
+
+ case 5:
+ // weird explosive complex # thingy
+
+ switch(m_nTexSizeX)
+ {
+ case 256: alpha *= 0.07f; break;
+ case 512: alpha *= 0.09f; break;
+ case 1024: alpha *= 0.11f; break;
+ case 2048: alpha *= 0.13f; break;
+ }
+
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ {
+ float cos_rot = cosf(GetTime()*0.3f);
+ float sin_rot = sinf(GetTime()*0.3f);
+
+ for (i=0; i<nVerts; i++)
+ {
+ float x0 = (fR[i]*fL[i+32] + fL[i]*fR[i+32]);
+ float y0 = (fR[i]*fR[i] - fL[i+32]*fL[i+32]);
+ v[i].x = (x0*cos_rot - y0*sin_rot)*m_fAspectY + fWavePosX;
+ v[i].y = (x0*sin_rot + y0*cos_rot)*m_fAspectX + fWavePosY;
+ //v[i].Diffuse = color;
+ }
+ }
+
+ break;
+
+ case 6:
+ case 7:
+ case 8:
+ // 6: angle-adjustable left channel, with temporal wave alignment;
+ // fWaveParam2 controls the angle at which it's drawn
+ // fWavePosX slides the wave away from the center, transversely.
+ // fWavePosY does nothing
+ //
+ // 7: same, except there are two channels shown, and
+ // fWavePosY determines the separation distance.
+ //
+ // 8: same as 6, except using the spectrum analyzer (UNFINISHED)
+ //
+ nVerts /= 2;
+
+ if (nVerts > m_nTexSizeX/3)
+ nVerts = m_nTexSizeX/3;
+
+ if (wave==8)
+ nVerts = 256;
+ else
+ sample_offset = (NUM_WAVEFORM_SAMPLES-nVerts)/2;//mysound.GoGoAlignatron(nVerts); // only call this once nVerts is final!
+
+ if (m_pState->m_bModWaveAlphaByVolume)
+ alpha *= ((mysound.imm_rel[0] + mysound.imm_rel[1] + mysound.imm_rel[2])*0.333f - m_pState->m_fModWaveAlphaStart.eval(GetTime()))/(m_pState->m_fModWaveAlphaEnd.eval(GetTime()) - m_pState->m_fModWaveAlphaStart.eval(GetTime()));
+ if (alpha < 0) alpha = 0;
+ if (alpha > 1) alpha = 1;
+ //color = D3DCOLOR_RGBA_01(cr, cg, cb, alpha);
+
+ {
+ float ang = 1.57f*fWaveParam2; // from -PI/2 to PI/2
+ float dx = cosf(ang);
+ float dy = sinf(ang);
+
+ float edge_x[2], edge_y[2];
+
+ //edge_x[0] = fWavePosX - dx*3.0f;
+ //edge_y[0] = fWavePosY - dy*3.0f;
+ //edge_x[1] = fWavePosX + dx*3.0f;
+ //edge_y[1] = fWavePosY + dy*3.0f;
+ edge_x[0] = fWavePosX*cosf(ang + 1.57f) - dx*3.0f;
+ edge_y[0] = fWavePosX*sinf(ang + 1.57f) - dy*3.0f;
+ edge_x[1] = fWavePosX*cosf(ang + 1.57f) + dx*3.0f;
+ edge_y[1] = fWavePosX*sinf(ang + 1.57f) + dy*3.0f;
+
+ for (i=0; i<2; i++) // for each point defining the line
+ {
+ // clip the point against 4 edges of screen
+ // be a bit lenient (use +/-1.1 instead of +/-1.0)
+ // so the dual-wave doesn't end too soon, after the channels are moved apart
+ for (int j=0; j<4; j++)
+ {
+ float t;
+ bool bClip = false;
+
+ switch(j)
+ {
+ case 0:
+ if (edge_x[i] > 1.1f)
+ {
+ t = (1.1f - edge_x[1-i]) / (edge_x[i] - edge_x[1-i]);
+ bClip = true;
+ }
+ break;
+ case 1:
+ if (edge_x[i] < -1.1f)
+ {
+ t = (-1.1f - edge_x[1-i]) / (edge_x[i] - edge_x[1-i]);
+ bClip = true;
+ }
+ break;
+ case 2:
+ if (edge_y[i] > 1.1f)
+ {
+ t = (1.1f - edge_y[1-i]) / (edge_y[i] - edge_y[1-i]);
+ bClip = true;
+ }
+ break;
+ case 3:
+ if (edge_y[i] < -1.1f)
+ {
+ t = (-1.1f - edge_y[1-i]) / (edge_y[i] - edge_y[1-i]);
+ bClip = true;
+ }
+ break;
+ }
+
+ if (bClip)
+ {
+ float dx = edge_x[i] - edge_x[1-i];
+ float dy = edge_y[i] - edge_y[1-i];
+ edge_x[i] = edge_x[1-i] + dx*t;
+ edge_y[i] = edge_y[1-i] + dy*t;
+ }
+ }
+ }
+
+ dx = (edge_x[1] - edge_x[0]) / (float)nVerts;
+ dy = (edge_y[1] - edge_y[0]) / (float)nVerts;
+ float ang2 = atan2f(dy,dx);
+ float perp_dx = cosf(ang2 + 1.57f);
+ float perp_dy = sinf(ang2 + 1.57f);
+
+ if (wave == 6)
+ for (i=0; i<nVerts; i++)
+ {
+ v[i].x = edge_x[0] + dx*i + perp_dx*0.25f*fL[i + sample_offset];
+ v[i].y = edge_y[0] + dy*i + perp_dy*0.25f*fL[i + sample_offset];
+ //v[i].Diffuse = color;
+ }
+ else if (wave == 8)
+ //256 verts
+ for (i=0; i<nVerts; i++)
+ {
+ float f = 0.1f*logf(mysound.fSpecLeft[i*2] + mysound.fSpecLeft[i*2+1]);
+ v[i].x = edge_x[0] + dx*i + perp_dx*f;
+ v[i].y = edge_y[0] + dy*i + perp_dy*f;
+ //v[i].Diffuse = color;
+ }
+ else
+ {
+ float sep = powf(fWavePosY*0.5f + 0.5f, 2.0f);
+ for (i=0; i<nVerts; i++)
+ {
+ v[i].x = edge_x[0] + dx*i + perp_dx*(0.25f*fL[i + sample_offset] + sep);
+ v[i].y = edge_y[0] + dy*i + perp_dy*(0.25f*fL[i + sample_offset] + sep);
+ //v[i].Diffuse = color;
+ }
+
+ //D3DPRIMITIVETYPE primtype = (*m_pState->var_pf_wave_usedots) ? D3DPT_POINTLIST : D3DPT_LINESTRIP;
+ //m_lpD3DDev->DrawPrimitive(primtype, D3DFVF_LVERTEX, (LPVOID)v, nVerts, NULL);
+
+ for (i=0; i<nVerts; i++)
+ {
+ v[i+nVerts].x = edge_x[0] + dx*i + perp_dx*(0.25f*fR[i + sample_offset] - sep);
+ v[i+nVerts].y = edge_y[0] + dy*i + perp_dy*(0.25f*fR[i + sample_offset] - sep);
+ //v[i+nVerts].Diffuse = color;
+ }
+
+ nBreak = nVerts;
+ nVerts *= 2;
+ }
+ }
+
+ break;
+ }
+
+ if (it==0)
+ {
+ nVerts1 = nVerts;
+ nBreak1 = nBreak;
+ alpha1 = alpha;
+ }
+ else
+ {
+ nVerts2 = nVerts;
+ nBreak2 = nBreak;
+ alpha2 = alpha;
+ }
+ }
+
+ // v1[] is for the current waveform
+ // v2[] is for the old waveform (from prev. preset - only used if blending)
+ // nVerts1 is the # of vertices in v1
+ // nVerts2 is the # of vertices in v2
+ // nBreak1 is the index of the point at which to break the solid line in v1[] (-1 if no break)
+ // nBreak2 is the index of the point at which to break the solid line in v2[] (-1 if no break)
+
+ float mix = CosineInterp(m_pState->m_fBlendProgress);
+ float mix2 = 1.0f - mix;
+
+ // blend 2 waveforms
+ if (nVerts2 > 0)
+ {
+ // note: this won't yet handle the case where (nBreak1 > 0 && nBreak2 > 0)
+ // in this case, code must break wave into THREE segments
+ float m = (nVerts2-1)/(float)nVerts1;
+ float x,y;
+ for (int i=0; i<nVerts1; i++)
+ {
+ float fIdx = i*m;
+ int nIdx = (int)fIdx;
+ float t = fIdx - nIdx;
+ if (nIdx == nBreak2-1)
+ {
+ x = v2[nIdx].x;
+ y = v2[nIdx].y;
+ nBreak1 = i+1;
+ }
+ else
+ {
+ x = v2[nIdx].x*(1-t) + v2[nIdx+1].x*(t);
+ y = v2[nIdx].y*(1-t) + v2[nIdx+1].y*(t);
+ }
+ v1[i].x = v1[i].x*(mix) + x*(mix2);
+ v1[i].y = v1[i].y*(mix) + y*(mix2);
+ }
+ }
+
+ // determine alpha
+ if (nVerts2 > 0)
+ {
+ alpha1 = alpha1*(mix) + alpha2*(1.0f-mix);
+ }
+
+ // apply color & alpha
+ // ALSO reverse all y values, to stay consistent with the pre-VMS milkdrop,
+ // which DIDN'T:
+ v1[0].Diffuse = D3DCOLOR_RGBA_01(cr, cg, cb, alpha1);
+ for (i=0; i<nVerts1; i++)
+ {
+ v1[i].Diffuse = v1[0].Diffuse;
+ v1[i].y = -v1[i].y;
+ }
+
+ // don't draw wave if (possibly blended) alpha is less than zero.
+ if (alpha1 < 0.004f)
+ goto SKIP_DRAW_WAVE;
+
+ // TESSELLATE - smooth the wave, one time.
+ WFVERTEX* pVerts = v1;
+ WFVERTEX vTess[(576+3)*2];
+ if (1)
+ {
+ if (nBreak1==-1)
+ {
+ nVerts1 = SmoothWave(v1, nVerts1, vTess);
+ }
+ else
+ {
+ int oldBreak = nBreak1;
+ nBreak1 = SmoothWave(v1, nBreak1, vTess);
+ nVerts1 = SmoothWave(&v1[oldBreak], nVerts1-oldBreak, &vTess[nBreak1]) + nBreak1;
+ }
+ pVerts = vTess;
+ }
+
+ // draw primitives
+ {
+ //D3DPRIMITIVETYPE primtype = (*m_pState->var_pf_wave_usedots) ? D3DPT_POINTLIST : D3DPT_LINESTRIP;
+ float x_inc = 2.0f / (float)m_nTexSizeX;
+ float y_inc = 2.0f / (float)m_nTexSizeY;
+ int drawing_its = ((*m_pState->var_pf_wave_thick || *m_pState->var_pf_wave_usedots) && (m_nTexSizeX >= 512)) ? 4 : 1;
+
+ for (int it=0; it<drawing_its; it++)
+ {
+ int j;
+
+ switch(it)
+ {
+ case 0: break;
+ case 1: for (j=0; j<nVerts1; j++) pVerts[j].x += x_inc; break; // draw fat dots
+ case 2: for (j=0; j<nVerts1; j++) pVerts[j].y += y_inc; break; // draw fat dots
+ case 3: for (j=0; j<nVerts1; j++) pVerts[j].x -= x_inc; break; // draw fat dots
+ }
+
+ if (nBreak1 == -1)
+ {
+ if (*m_pState->var_pf_wave_usedots)
+ lpDevice->DrawPrimitiveUP(D3DPT_POINTLIST, nVerts1, (void*)pVerts, sizeof(WFVERTEX));
+ else
+ lpDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, nVerts1-1, (void*)pVerts, sizeof(WFVERTEX));
+ }
+ else
+ {
+ if (*m_pState->var_pf_wave_usedots)
+ {
+ lpDevice->DrawPrimitiveUP(D3DPT_POINTLIST, nBreak1, (void*)pVerts, sizeof(WFVERTEX));
+ lpDevice->DrawPrimitiveUP(D3DPT_POINTLIST, nVerts1-nBreak1, (void*)&pVerts[nBreak1], sizeof(WFVERTEX));
+ }
+ else
+ {
+ lpDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, nBreak1-1, (void*)pVerts, sizeof(WFVERTEX));
+ lpDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, nVerts1-nBreak1-1, (void*)&pVerts[nBreak1], sizeof(WFVERTEX));
+ }
+ }
+ }
+ }
+
+SKIP_DRAW_WAVE:
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+}
+
+void CPlugin::DrawSprites()
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( WFVERTEX_FORMAT );
+
+ if (*m_pState->var_pf_darken_center)
+ {
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);//SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+ WFVERTEX v3[6];
+ ZeroMemory(v3, sizeof(WFVERTEX)*6);
+
+ // colors:
+ v3[0].Diffuse = D3DCOLOR_RGBA_01(0, 0, 0, 3.0f/32.0f);
+ v3[1].Diffuse = D3DCOLOR_RGBA_01(0, 0, 0, 0.0f/32.0f);
+ v3[2].Diffuse = v3[1].Diffuse;
+ v3[3].Diffuse = v3[1].Diffuse;
+ v3[4].Diffuse = v3[1].Diffuse;
+ v3[5].Diffuse = v3[1].Diffuse;
+
+ // positioning:
+ float fHalfSize = 0.05f;
+ v3[0].x = 0.0f;
+ v3[1].x = 0.0f - fHalfSize*m_fAspectY;
+ v3[2].x = 0.0f;
+ v3[3].x = 0.0f + fHalfSize*m_fAspectY;
+ v3[4].x = 0.0f;
+ v3[5].x = v3[1].x;
+ v3[0].y = 0.0f;
+ v3[1].y = 0.0f;
+ v3[2].y = 0.0f - fHalfSize;
+ v3[3].y = 0.0f;
+ v3[4].y = 0.0f + fHalfSize;
+ v3[5].y = v3[1].y;
+ //v3[0].tu = 0; v3[1].tu = 1; v3[2].tu = 0; v3[3].tu = 1;
+ //v3[0].tv = 1; v3[1].tv = 1; v3[2].tv = 0; v3[3].tv = 0;
+
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 4, (LPVOID)v3, sizeof(WFVERTEX));
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+
+ // do borders
+ {
+ float fOuterBorderSize = (float)*m_pState->var_pf_ob_size;
+ float fInnerBorderSize = (float)*m_pState->var_pf_ib_size;
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+ for (int it=0; it<2; it++)
+ {
+ WFVERTEX v3[4];
+ ZeroMemory(v3, sizeof(WFVERTEX)*4);
+
+ // colors:
+ float r = (it==0) ? (float)*m_pState->var_pf_ob_r : (float)*m_pState->var_pf_ib_r;
+ float g = (it==0) ? (float)*m_pState->var_pf_ob_g : (float)*m_pState->var_pf_ib_g;
+ float b = (it==0) ? (float)*m_pState->var_pf_ob_b : (float)*m_pState->var_pf_ib_b;
+ float a = (it==0) ? (float)*m_pState->var_pf_ob_a : (float)*m_pState->var_pf_ib_a;
+ if (a > 0.001f)
+ {
+ v3[0].Diffuse = D3DCOLOR_RGBA_01(r,g,b,a);
+ v3[1].Diffuse = v3[0].Diffuse;
+ v3[2].Diffuse = v3[0].Diffuse;
+ v3[3].Diffuse = v3[0].Diffuse;
+
+ // positioning:
+ float fInnerRad = (it==0) ? 1.0f - fOuterBorderSize : 1.0f - fOuterBorderSize - fInnerBorderSize;
+ float fOuterRad = (it==0) ? 1.0f : 1.0f - fOuterBorderSize;
+ v3[0].x = fInnerRad;
+ v3[1].x = fOuterRad;
+ v3[2].x = fOuterRad;
+ v3[3].x = fInnerRad;
+ v3[0].y = fInnerRad;
+ v3[1].y = fOuterRad;
+ v3[2].y = -fOuterRad;
+ v3[3].y = -fInnerRad;
+
+ for (int rot=0; rot<4; rot++)
+ {
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, (LPVOID)v3, sizeof(WFVERTEX));
+
+ // rotate by 90 degrees
+ for (int v=0; v<4; v++)
+ {
+ float t = 1.570796327f;
+ float x = v3[v].x;
+ float y = v3[v].y;
+ v3[v].x = x*cosf(t) - y*sinf(t);
+ v3[v].y = x*sinf(t) + y*cosf(t);
+ }
+ }
+ }
+ }
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+}
+
+/*
+bool CPlugin::SetMilkdropRenderTarget(LPDIRECTDRAWSURFACE7 lpSurf, int w, int h, char *szErrorMsg)
+{
+ HRESULT hr = m_lpD3DDev->SetRenderTarget(0, lpSurf, 0);
+ if (hr != D3D_OK)
+ {
+ //if (szErrorMsg && szErrorMsg[0]) dumpmsg(szErrorMsg);
+ //IdentifyD3DError(hr);
+ return false;
+ }
+
+ //DDSURFACEDESC2 ddsd;
+ //ddsd.dwSize = sizeof(ddsd);
+ //lpSurf->GetSurfaceDesc(&ddsd);
+
+ D3DVIEWPORT7 viewData;
+ ZeroMemory(&viewData, sizeof(D3DVIEWPORT7));
+ viewData.dwWidth = w; // not: in windowed mode, when lpSurf is the back buffer, chances are good that w,h are smaller than the full surface size (since real size is fullscreen, but we're only using a portion of it as big as the window).
+ viewData.dwHeight = h;
+ hr = m_lpD3DDev->SetViewport(&viewData);
+
+ return true;
+}
+*/
+
+void CPlugin::DrawUserSprites() // from system memory, to back buffer.
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+
+ //lpDevice->SetRenderState(D3DRS_WRAP0, 0);
+ //lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
+ //lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
+ //lpDevice->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
+
+ // reset these to the standard safe mode:
+ lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ /*
+ lpDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); //D3DSHADE_GOURAUD
+ lpDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
+ lpDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ if (m_D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER)
+ lpDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ lpDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
+ lpDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE);
+ lpDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); // vs. wireframe
+ lpDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA_01(1,1,1,1));
+ lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTFG_LINEAR );
+ lpDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTFN_LINEAR );
+ lpDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTFP_LINEAR );
+ */
+
+ for (int iSlot=0; iSlot < NUM_TEX; iSlot++)
+ {
+ if (m_texmgr.m_tex[iSlot].pSurface)
+ {
+ int k;
+
+ // set values of input variables:
+ *(m_texmgr.m_tex[iSlot].var_time) = (double)(GetTime() - m_texmgr.m_tex[iSlot].fStartTime);
+ *(m_texmgr.m_tex[iSlot].var_frame) = (double)(GetFrame() - m_texmgr.m_tex[iSlot].nStartFrame);
+ *(m_texmgr.m_tex[iSlot].var_fps) = (double)GetFps();
+ *(m_texmgr.m_tex[iSlot].var_progress) = (double)m_pState->m_fBlendProgress;
+ *(m_texmgr.m_tex[iSlot].var_bass) = (double)mysound.imm_rel[0];
+ *(m_texmgr.m_tex[iSlot].var_mid) = (double)mysound.imm_rel[1];
+ *(m_texmgr.m_tex[iSlot].var_treb) = (double)mysound.imm_rel[2];
+ *(m_texmgr.m_tex[iSlot].var_bass_att) = (double)mysound.avg_rel[0];
+ *(m_texmgr.m_tex[iSlot].var_mid_att) = (double)mysound.avg_rel[1];
+ *(m_texmgr.m_tex[iSlot].var_treb_att) = (double)mysound.avg_rel[2];
+
+ // evaluate expressions
+ #ifndef _NO_EXPR_
+ if (m_texmgr.m_tex[iSlot].m_codehandle)
+ {
+ NSEEL_code_execute(m_texmgr.m_tex[iSlot].m_codehandle);
+ }
+ #endif
+
+ bool bKillSprite = (*m_texmgr.m_tex[iSlot].var_done != 0.0);
+ bool bBurnIn = (*m_texmgr.m_tex[iSlot].var_burn != 0.0);
+
+ // Remember the original backbuffer and zbuffer
+ LPDIRECT3DSURFACE9 pBackBuffer=NULL;//, pZBuffer=NULL;
+ lpDevice->GetRenderTarget( 0, &pBackBuffer );
+ //lpDevice->GetDepthStencilSurface( &pZBuffer );
+
+ if (/*bKillSprite &&*/ bBurnIn)
+ {
+ // set up to render [from NULL] to VS1 (for burn-in).
+
+ lpDevice->SetTexture(0, NULL);
+
+ IDirect3DSurface9* pNewTarget = NULL;
+ if (m_lpVS[1]->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ return;
+ lpDevice->SetRenderTarget(0, pNewTarget );
+ //lpDevice->SetDepthStencilSurface( NULL );
+ pNewTarget->Release();
+
+ lpDevice->SetTexture(0, NULL);
+ }
+
+ // finally, use the results to draw the sprite.
+ if (lpDevice->SetTexture(0, m_texmgr.m_tex[iSlot].pSurface) != D3D_OK)
+ return;
+
+ SPRITEVERTEX v3[4];
+ ZeroMemory(v3, sizeof(SPRITEVERTEX)*4);
+
+ /*
+ int dest_w, dest_h;
+ {
+ LPDIRECT3DSURFACE9 pRT;
+ lpDevice->GetRenderTarget( 0, &pRT );
+
+ D3DSURFACE_DESC desc;
+ pRT->GetDesc(&desc);
+ dest_w = desc.Width;
+ dest_h = desc.Height;
+ pRT->Release();
+ }*/
+
+ float x = min(1000.0f, max(-1000.0f, (float)(*m_texmgr.m_tex[iSlot].var_x) * 2.0f - 1.0f ));
+ float y = min(1000.0f, max(-1000.0f, (float)(*m_texmgr.m_tex[iSlot].var_y) * 2.0f - 1.0f ));
+ float sx = min(1000.0f, max(-1000.0f, (float)(*m_texmgr.m_tex[iSlot].var_sx) ));
+ float sy = min(1000.0f, max(-1000.0f, (float)(*m_texmgr.m_tex[iSlot].var_sy) ));
+ float rot = (float)(*m_texmgr.m_tex[iSlot].var_rot);
+ int flipx = (*m_texmgr.m_tex[iSlot].var_flipx == 0.0) ? 0 : 1;
+ int flipy = (*m_texmgr.m_tex[iSlot].var_flipy == 0.0) ? 0 : 1;
+ float repeatx = min(100.0f, max(0.01f, (float)(*m_texmgr.m_tex[iSlot].var_repeatx) ));
+ float repeaty = min(100.0f, max(0.01f, (float)(*m_texmgr.m_tex[iSlot].var_repeaty) ));
+
+ int blendmode = min(4, max(0, ((int)(*m_texmgr.m_tex[iSlot].var_blendmode))));
+ float r = min(1.0f, max(0.0f, ((float)(*m_texmgr.m_tex[iSlot].var_r))));
+ float g = min(1.0f, max(0.0f, ((float)(*m_texmgr.m_tex[iSlot].var_g))));
+ float b = min(1.0f, max(0.0f, ((float)(*m_texmgr.m_tex[iSlot].var_b))));
+ float a = min(1.0f, max(0.0f, ((float)(*m_texmgr.m_tex[iSlot].var_a))));
+
+ // set x,y coords
+ v3[0+flipx].x = -sx;
+ v3[1-flipx].x = sx;
+ v3[2+flipx].x = -sx;
+ v3[3-flipx].x = sx;
+ v3[0+flipy*2].y = -sy;
+ v3[1+flipy*2].y = -sy;
+ v3[2-flipy*2].y = sy;
+ v3[3-flipy*2].y = sy;
+
+ // first aspect ratio: adjust for non-1:1 images
+ {
+ float aspect = m_texmgr.m_tex[iSlot].img_h / (float)m_texmgr.m_tex[iSlot].img_w;
+
+ if (aspect < 1)
+ for (k=0; k<4; k++) v3[k].y *= aspect; // wide image
+ else
+ for (k=0; k<4; k++) v3[k].x /= aspect; // tall image
+ }
+
+ // 2D rotation
+ {
+ float cos_rot = cosf(rot);
+ float sin_rot = sinf(rot);
+ for (k=0; k<4; k++)
+ {
+ float x2 = v3[k].x*cos_rot - v3[k].y*sin_rot;
+ float y2 = v3[k].x*sin_rot + v3[k].y*cos_rot;
+ v3[k].x = x2;
+ v3[k].y = y2;
+ }
+ }
+
+ // translation
+ for (k=0; k<4; k++)
+ {
+ v3[k].x += x;
+ v3[k].y += y;
+ }
+
+ // second aspect ratio: normalize to width of screen
+ {
+ float aspect = GetWidth() / (float)(GetHeight());
+
+ if (aspect > 1)
+ for (k=0; k<4; k++) v3[k].y *= aspect;
+ else
+ for (k=0; k<4; k++) v3[k].x /= aspect;
+ }
+
+ // third aspect ratio: adjust for burn-in
+ if (bKillSprite && bBurnIn) // final render-to-VS1
+ {
+ float aspect = GetWidth()/(float)(GetHeight()*4.0f/3.0f);
+ if (aspect < 1.0f)
+ for (k=0; k<4; k++) v3[k].x *= aspect;
+ else
+ for (k=0; k<4; k++) v3[k].y /= aspect;
+ }
+
+ // finally, flip 'y' for annoying DirectX
+ //for (k=0; k<4; k++) v3[k].y *= -1.0f;
+
+ // set u,v coords
+ {
+ float dtu = 0.5f;// / (float)m_texmgr.m_tex[iSlot].tex_w;
+ float dtv = 0.5f;// / (float)m_texmgr.m_tex[iSlot].tex_h;
+ v3[0].tu = -dtu;
+ v3[1].tu = dtu;///*m_texmgr.m_tex[iSlot].img_w / (float)m_texmgr.m_tex[iSlot].tex_w*/ - dtu;
+ v3[2].tu = -dtu;
+ v3[3].tu = dtu;///*m_texmgr.m_tex[iSlot].img_w / (float)m_texmgr.m_tex[iSlot].tex_w*/ - dtu;
+ v3[0].tv = -dtv;
+ v3[1].tv = -dtv;
+ v3[2].tv = dtv;///*m_texmgr.m_tex[iSlot].img_h / (float)m_texmgr.m_tex[iSlot].tex_h*/ - dtv;
+ v3[3].tv = dtv;///*m_texmgr.m_tex[iSlot].img_h / (float)m_texmgr.m_tex[iSlot].tex_h*/ - dtv;
+
+ // repeat on x,y
+ for (k=0; k<4; k++)
+ {
+ v3[k].tu = (v3[k].tu - 0.0f)*repeatx + 0.5f;
+ v3[k].tv = (v3[k].tv - 0.0f)*repeaty + 0.5f;
+ }
+ }
+
+ // blendmodes src alpha: dest alpha:
+ // 0 blend r,g,b=modulate a=opacity SRCALPHA INVSRCALPHA
+ // 1 decal r,g,b=modulate a=modulate D3DBLEND_ONE D3DBLEND_ZERO
+ // 2 additive r,g,b=modulate a=modulate D3DBLEND_ONE D3DBLEND_ONE
+ // 3 srccolor r,g,b=no effect a=no effect SRCCOLOR INVSRCCOLOR
+ // 4 colorkey r,g,b=modulate a=no effect
+ switch(blendmode)
+ {
+ case 0:
+ default:
+ // alpha blend
+
+ /*
+ Q. I am rendering with alpha blending and setting the alpha
+ of the diffuse vertex component to determine the opacity.
+ It works when there is no texture set, but as soon as I set
+ a texture the alpha that I set is no longer applied. Why?
+
+ The problem originates in the texture blending stages, rather
+ than in the subsequent alpha blending. Alpha can come from
+ several possible sources. If this has not been specified,
+ then the alpha will be taken from the texture, if one is selected.
+ If no texture is selected, then the default will use the alpha
+ channel of the diffuse vertex component.
+
+ Explicitly specifying the diffuse vertex component as the source
+ for alpha will insure that the alpha is drawn from the alpha value
+ you set, whether a texture is selected or not:
+
+ pDevice->SetSamplerState(D3DSAMP_ALPHAOP,D3DTOP_SELECTARG1);
+ pDevice->SetSamplerState(D3DSAMP_ALPHAARG1,D3DTA_DIFFUSE);
+
+ If you later need to use the texture alpha as the source, set
+ D3DSAMP_ALPHAARG1 to D3DTA_TEXTURE.
+ */
+
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ for (k=0; k<4; k++) v3[k].Diffuse = D3DCOLOR_RGBA_01(r,g,b,a);
+ break;
+ case 1:
+ // decal
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ //lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ //lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+ for (k=0; k<4; k++) v3[k].Diffuse = D3DCOLOR_RGBA_01(r*a,g*a,b*a,1);
+ break;
+ case 2:
+ // additive
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ for (k=0; k<4; k++) v3[k].Diffuse = D3DCOLOR_RGBA_01(r*a,g*a,b*a,1);
+ break;
+ case 3:
+ // srccolor
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
+ for (k=0; k<4; k++) v3[k].Diffuse = D3DCOLOR_RGBA_01(1,1,1,1);
+ break;
+ case 4:
+ // color keyed texture: use the alpha value in the texture to
+ // determine which texels get drawn.
+ /*lpDevice->SetRenderState(D3DRS_ALPHAREF, 0);
+ lpDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL);
+ lpDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
+ */
+
+ lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ // also, smoothly blend this in-between texels:
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ for (k=0; k<4; k++) v3[k].Diffuse = D3DCOLOR_RGBA_01(r,g,b,a);
+ break;
+ }
+
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID)v3, sizeof(SPRITEVERTEX));
+
+ if (/*bKillSprite &&*/ bBurnIn) // final render-to-VS1
+ {
+ // Change the rendertarget back to the original setup
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderTarget( 0, pBackBuffer );
+ //lpDevice->SetDepthStencilSurface( pZBuffer );
+ lpDevice->SetTexture(0, m_texmgr.m_tex[iSlot].pSurface);
+
+ // undo aspect ratio changes (that were used to fit it to VS1):
+ {
+ float aspect = GetWidth()/(float)(GetHeight()*4.0f/3.0f);
+ if (aspect < 1.0f)
+ for (k=0; k<4; k++) v3[k].x /= aspect;
+ else
+ for (k=0; k<4; k++) v3[k].y *= aspect;
+ }
+
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID)v3, sizeof(SPRITEVERTEX));
+ }
+
+ SafeRelease(pBackBuffer);
+ //SafeRelease(pZBuffer);
+
+ if (bKillSprite)
+ {
+ KillSprite(iSlot);
+ }
+
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+ }
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ // reset these to the standard safe mode:
+ lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+}
+
+void CPlugin::UvToMathSpace(float u, float v, float* rad, float* ang)
+{
+ // (screen space = -1..1 on both axes; corresponds to UV space)
+ // uv space = [0..1] on both axes
+ // "math" space = what the preset authors are used to:
+ // upper left = [0,0]
+ // bottom right = [1,1]
+ // rad == 1 at corners of screen
+ // ang == 0 at three o'clock, and increases counter-clockwise (to 6.28).
+ float px = (u*2-1) * m_fAspectX; // probably 1.0
+ float py = (v*2-1) * m_fAspectY; // probably <1
+
+ *rad = sqrtf(px*px + py*py) / sqrtf(m_fAspectX*m_fAspectX + m_fAspectY*m_fAspectY);
+ *ang = atan2f(py, px);
+ if (*ang < 0)
+ *ang += 6.2831853071796f;
+}
+
+void CPlugin::RestoreShaderParams()
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ int i = 0;
+ for (i=0; i<2; i++)
+ {
+ lpDevice->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);//texaddr);
+ lpDevice->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);//texaddr);
+ lpDevice->SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);//texaddr);
+ lpDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ }
+
+ for (i=0; i<4; i++)
+ lpDevice->SetTexture( i, NULL );
+
+ lpDevice->SetVertexShader(NULL);
+ //lpDevice->SetVertexDeclaration(NULL); -directx debug runtime complains heavily about this
+ lpDevice->SetPixelShader(NULL);
+
+}
+
+void CPlugin::ApplyShaderParams(CShaderParams* p, LPD3DXCONSTANTTABLE pCT, CState* pState)
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+
+ //if (p->texbind_vs >= 0) lpDevice->SetTexture( p->texbind_vs , m_lpVS[0] );
+ //if (p->texbind_noise >= 0) lpDevice->SetTexture( p->texbind_noise, m_pTexNoise );
+
+ // bind textures
+ int i = 0;
+ for (i=0; i<sizeof(p->m_texture_bindings)/sizeof(p->m_texture_bindings[0]); i++)
+ {
+ if (p->m_texcode[i] == TEX_VS)
+ lpDevice->SetTexture(i, m_lpVS[0]);
+ else
+ lpDevice->SetTexture(i, p->m_texture_bindings[i].texptr);
+
+ // also set up sampler stage, if anything is bound here...
+ if (p->m_texcode[i]==TEX_VS || p->m_texture_bindings[i].texptr)
+ {
+ bool bAniso = false;
+ DWORD HQFilter = bAniso ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
+ DWORD wrap = p->m_texture_bindings[i].bWrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
+ DWORD filter = p->m_texture_bindings[i].bBilinear ? HQFilter : D3DTEXF_POINT;
+ lpDevice->SetSamplerState(i, D3DSAMP_ADDRESSU, wrap);
+ lpDevice->SetSamplerState(i, D3DSAMP_ADDRESSV, wrap);
+ lpDevice->SetSamplerState(i, D3DSAMP_ADDRESSW, wrap);
+ lpDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, filter);
+ lpDevice->SetSamplerState(i, D3DSAMP_MINFILTER, filter);
+ lpDevice->SetSamplerState(i, D3DSAMP_MIPFILTER, filter);
+ //lpDevice->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, bAniso ? 4 : 1); //FIXME:ANISO
+ }
+
+ // finally, if it was a blur texture, note that
+ if (p->m_texcode[i] >= TEX_BLUR1 && p->m_texcode[i] <= TEX_BLUR_LAST)
+ m_nHighestBlurTexUsedThisFrame = max(m_nHighestBlurTexUsedThisFrame, ((int)p->m_texcode[i] - (int)TEX_BLUR1) + 1);
+ }
+
+ // bind "texsize_XYZ" params
+ int N = p->texsize_params.size();
+ for (i=0; i<N; i++)
+ {
+ TexSizeParamInfo* q = &(p->texsize_params[i]);
+ pCT->SetVector( lpDevice, q->texsize_param, &D3DXVECTOR4((float)q->w,(float)q->h,1.0f/q->w,1.0f/q->h));
+ }
+
+ float time_since_preset_start = GetTime() - pState->GetPresetStartTime();
+ float time_since_preset_start_wrapped = time_since_preset_start - (int)(time_since_preset_start/10000)*10000;
+ float time = GetTime() - m_fStartTime;
+ float progress = (GetTime() - m_fPresetStartTime) / (m_fNextPresetTime - m_fPresetStartTime);
+ float mip_x = logf((float)GetWidth())/logf(2.0f);
+ float mip_y = logf((float)GetWidth())/logf(2.0f);
+ float mip_avg = 0.5f*(mip_x + mip_y);
+ float aspect_x = 1;
+ float aspect_y = 1;
+ if (GetWidth() > GetHeight())
+ aspect_y = GetHeight()/(float)GetWidth();
+ else
+ aspect_x = GetWidth()/(float)GetHeight();
+
+ float blur_min[3], blur_max[3];
+ GetSafeBlurMinMax(pState, blur_min, blur_max);
+
+ // bind float4's
+ if (p->rand_frame ) pCT->SetVector( lpDevice, p->rand_frame , &m_rand_frame );
+ if (p->rand_preset) pCT->SetVector( lpDevice, p->rand_preset, &pState->m_rand_preset );
+ D3DXHANDLE* h = p->const_handles;
+ if (h[0]) pCT->SetVector( lpDevice, h[0], &D3DXVECTOR4( aspect_x, aspect_y, 1.0f/aspect_x, 1.0f/aspect_y ));
+ if (h[1]) pCT->SetVector( lpDevice, h[1], &D3DXVECTOR4(0, 0, 0, 0 ));
+ if (h[2]) pCT->SetVector( lpDevice, h[2], &D3DXVECTOR4(time_since_preset_start_wrapped, GetFps(), (float)GetFrame(), progress));
+ if (h[3]) pCT->SetVector( lpDevice, h[3], &D3DXVECTOR4(mysound.imm_rel[0], mysound.imm_rel[1], mysound.imm_rel[2], 0.3333f*(mysound.imm_rel[0], mysound.imm_rel[1], mysound.imm_rel[2]) ));
+ if (h[4]) pCT->SetVector( lpDevice, h[4], &D3DXVECTOR4(mysound.avg_rel[0], mysound.avg_rel[1], mysound.avg_rel[2], 0.3333f*(mysound.avg_rel[0], mysound.avg_rel[1], mysound.avg_rel[2]) ));
+ if (h[5]) pCT->SetVector( lpDevice, h[5], &D3DXVECTOR4( blur_max[0]-blur_min[0], blur_min[0], blur_max[1]-blur_min[1], blur_min[1] ));
+ if (h[6]) pCT->SetVector( lpDevice, h[6], &D3DXVECTOR4( blur_max[2]-blur_min[2], blur_min[2], blur_min[0], blur_max[0] ));
+ if (h[7]) pCT->SetVector( lpDevice, h[7], &D3DXVECTOR4((float)m_nTexSizeX, (float)m_nTexSizeY, 1.0f/(float)m_nTexSizeX, 1.0f/(float)m_nTexSizeY ));
+ if (h[8]) pCT->SetVector( lpDevice, h[8], &D3DXVECTOR4( 0.5f+0.5f*cosf(time* 0.329f+1.2f),
+ 0.5f+0.5f*cosf(time* 1.293f+3.9f),
+ 0.5f+0.5f*cosf(time* 5.070f+2.5f),
+ 0.5f+0.5f*cosf(time*20.051f+5.4f)
+ ));
+ if (h[9]) pCT->SetVector( lpDevice, h[9], &D3DXVECTOR4( 0.5f+0.5f*sinf(time* 0.329f+1.2f),
+ 0.5f+0.5f*sinf(time* 1.293f+3.9f),
+ 0.5f+0.5f*sinf(time* 5.070f+2.5f),
+ 0.5f+0.5f*sinf(time*20.051f+5.4f)
+ ));
+ if (h[10]) pCT->SetVector( lpDevice, h[10], &D3DXVECTOR4( 0.5f+0.5f*cosf(time*0.0050f+2.7f),
+ 0.5f+0.5f*cosf(time*0.0085f+5.3f),
+ 0.5f+0.5f*cosf(time*0.0133f+4.5f),
+ 0.5f+0.5f*cosf(time*0.0217f+3.8f)
+ ));
+ if (h[11]) pCT->SetVector( lpDevice, h[11], &D3DXVECTOR4( 0.5f+0.5f*sinf(time*0.0050f+2.7f),
+ 0.5f+0.5f*sinf(time*0.0085f+5.3f),
+ 0.5f+0.5f*sinf(time*0.0133f+4.5f),
+ 0.5f+0.5f*sinf(time*0.0217f+3.8f)
+ ));
+ if (h[12]) pCT->SetVector( lpDevice, h[12], &D3DXVECTOR4( mip_x, mip_y, mip_avg, 0 ));
+ if (h[13]) pCT->SetVector( lpDevice, h[13], &D3DXVECTOR4( blur_min[1], blur_max[1], blur_min[2], blur_max[2] ));
+
+ // write q vars
+ int num_q_float4s = sizeof(p->q_const_handles)/sizeof(p->q_const_handles[0]);
+ for (i=0; i<num_q_float4s; i++)
+ {
+ if (p->q_const_handles[i])
+ pCT->SetVector( lpDevice, p->q_const_handles[i], &D3DXVECTOR4(
+ (float)*pState->var_pf_q[i*4+0],
+ (float)*pState->var_pf_q[i*4+1],
+ (float)*pState->var_pf_q[i*4+2],
+ (float)*pState->var_pf_q[i*4+3] ));
+ }
+
+ // write matrices
+ for (i=0; i<20; i++)
+ {
+ if (p->rot_mat[i])
+ {
+ D3DXMATRIX mx,my,mz,mxlate,temp;
+
+ pMatrixRotationX(&mx, pState->m_rot_base[i].x + pState->m_rot_speed[i].x*time);
+ pMatrixRotationY(&my, pState->m_rot_base[i].y + pState->m_rot_speed[i].y*time);
+ pMatrixRotationZ(&mz, pState->m_rot_base[i].z + pState->m_rot_speed[i].z*time);
+ pMatrixTranslation(&mxlate, pState->m_xlate[i].x, pState->m_xlate[i].y, pState->m_xlate[i].z);
+
+ pMatrixMultiply(&temp, &mx, &mxlate);
+ pMatrixMultiply(&temp, &temp, &mz);
+ pMatrixMultiply(&temp, &temp, &my);
+
+ pCT->SetMatrix(lpDevice, p->rot_mat[i], &temp);
+ }
+ }
+ // the last 4 are totally random, each frame
+ for (i=20; i<24; i++)
+ {
+ if (p->rot_mat[i])
+ {
+ D3DXMATRIX mx,my,mz,mxlate,temp;
+
+ pMatrixRotationX(&mx, FRAND * 6.28f);
+ pMatrixRotationY(&my, FRAND * 6.28f);
+ pMatrixRotationZ(&mz, FRAND * 6.28f);
+ pMatrixTranslation(&mxlate, FRAND, FRAND, FRAND);
+
+ pMatrixMultiply(&temp, &mx, &mxlate);
+ pMatrixMultiply(&temp, &temp, &mz);
+ pMatrixMultiply(&temp, &temp, &my);
+
+ pCT->SetMatrix(lpDevice, p->rot_mat[i], &temp);
+ }
+ }
+}
+
+void CPlugin::ShowToUser_NoShaders()//int bRedraw, int nPassOverride)
+{
+ // note: this one has to draw the whole screen! (one big quad)
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, m_lpVS[1]);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetPixelShader( NULL );
+ lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+
+ // stages 0 and 1 always just use bilinear filtering.
+ lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ lpDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+
+ // note: this texture stage state setup works for 0 or 1 texture.
+ // if you set a texture, it will be modulated with the current diffuse color.
+ // if you don't set a texture, it will just use the current diffuse color.
+ lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
+ lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ float fZoom = 1.0f;
+ SPRITEVERTEX v3[4];
+ ZeroMemory(v3, sizeof(SPRITEVERTEX)*4);
+
+ // extend the poly we draw by 1 pixel around the viewable image area,
+ // in case the video card wraps u/v coords with a +0.5-texel offset
+ // (otherwise, a 1-pixel-wide line of the image would wrap at the top and left edges).
+ float fOnePlusInvWidth = 1.0f + 1.0f/(float)GetWidth();
+ float fOnePlusInvHeight = 1.0f + 1.0f/(float)GetHeight();
+ v3[0].x = -fOnePlusInvWidth;
+ v3[1].x = fOnePlusInvWidth;
+ v3[2].x = -fOnePlusInvWidth;
+ v3[3].x = fOnePlusInvWidth;
+ v3[0].y = fOnePlusInvHeight;
+ v3[1].y = fOnePlusInvHeight;
+ v3[2].y = -fOnePlusInvHeight;
+ v3[3].y = -fOnePlusInvHeight;
+
+ //float aspect = GetWidth() / (float)(GetHeight()/(ASPECT)/**4.0f/3.0f*/);
+ float aspect = GetWidth() / (float)(GetHeight()*m_fInvAspectY/**4.0f/3.0f*/);
+ float x_aspect_mult = 1.0f;
+ float y_aspect_mult = 1.0f;
+
+ if (aspect>1)
+ y_aspect_mult = aspect;
+ else
+ x_aspect_mult = 1.0f/aspect;
+
+ for (int n=0; n<4; n++)
+ {
+ v3[n].x *= x_aspect_mult;
+ v3[n].y *= y_aspect_mult;
+ }
+
+ {
+ float shade[4][3] = {
+ { 1.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f } }; // for each vertex, then each comp.
+
+ float fShaderAmount = m_pState->m_fShader.eval(GetTime());
+
+ if (fShaderAmount > 0.001f)
+ {
+ for (int i=0; i<4; i++)
+ {
+ shade[i][0] = 0.6f + 0.3f*sinf(GetTime()*30.0f*0.0143f + 3 + i*21 + m_fRandStart[3]);
+ shade[i][1] = 0.6f + 0.3f*sinf(GetTime()*30.0f*0.0107f + 1 + i*13 + m_fRandStart[1]);
+ shade[i][2] = 0.6f + 0.3f*sinf(GetTime()*30.0f*0.0129f + 6 + i*9 + m_fRandStart[2]);
+ float max = ((shade[i][0] > shade[i][1]) ? shade[i][0] : shade[i][1]);
+ if (shade[i][2] > max) max = shade[i][2];
+ for (int k=0; k<3; k++)
+ {
+ shade[i][k] /= max;
+ shade[i][k] = 0.5f + 0.5f*shade[i][k];
+ }
+ for (int k=0; k<3; k++)
+ {
+ shade[i][k] = shade[i][k]*(fShaderAmount) + 1.0f*(1.0f - fShaderAmount);
+ }
+ v3[i].Diffuse = D3DCOLOR_RGBA_01(shade[i][0],shade[i][1],shade[i][2],1);
+ }
+ }
+
+ float fVideoEchoZoom = (float)(*m_pState->var_pf_echo_zoom);//m_pState->m_fVideoEchoZoom.eval(GetTime());
+ float fVideoEchoAlpha = (float)(*m_pState->var_pf_echo_alpha);//m_pState->m_fVideoEchoAlpha.eval(GetTime());
+ int nVideoEchoOrientation = (int) (*m_pState->var_pf_echo_orient) % 4;//m_pState->m_nVideoEchoOrientation;
+ float fGammaAdj = (float)(*m_pState->var_pf_gamma);//m_pState->m_fGammaAdj.eval(GetTime());
+
+ if (m_pState->m_bBlending &&
+ m_pState->m_fVideoEchoAlpha.eval(GetTime()) > 0.01f &&
+ m_pState->m_fVideoEchoAlphaOld > 0.01f &&
+ m_pState->m_nVideoEchoOrientation != m_pState->m_nVideoEchoOrientationOld)
+ {
+ if (m_pState->m_fBlendProgress < m_fSnapPoint)
+ {
+ nVideoEchoOrientation = m_pState->m_nVideoEchoOrientationOld;
+ fVideoEchoAlpha *= 1.0f - 2.0f*CosineInterp(m_pState->m_fBlendProgress);
+ }
+ else
+ {
+ fVideoEchoAlpha *= 2.0f*CosineInterp(m_pState->m_fBlendProgress) - 1.0f;
+ }
+ }
+
+ if (fVideoEchoAlpha > 0.001f)
+ {
+ // video echo
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+
+ for (int i=0; i<2; i++)
+ {
+ fZoom = (i==0) ? 1.0f : fVideoEchoZoom;
+
+ float temp_lo = 0.5f - 0.5f/fZoom;
+ float temp_hi = 0.5f + 0.5f/fZoom;
+ v3[0].tu = temp_lo;
+ v3[0].tv = temp_hi;
+ v3[1].tu = temp_hi;
+ v3[1].tv = temp_hi;
+ v3[2].tu = temp_lo;
+ v3[2].tv = temp_lo;
+ v3[3].tu = temp_hi;
+ v3[3].tv = temp_lo;
+
+ // flipping
+ if (i==1)
+ {
+ for (int j=0; j<4; j++)
+ {
+ if (nVideoEchoOrientation % 2)
+ v3[j].tu = 1.0f - v3[j].tu;
+ if (nVideoEchoOrientation >= 2)
+ v3[j].tv = 1.0f - v3[j].tv;
+ }
+ }
+
+ float mix = (i==1) ? fVideoEchoAlpha : 1.0f - fVideoEchoAlpha;
+ for (int k=0; k<4; k++)
+ v3[k].Diffuse = D3DCOLOR_RGBA_01(mix*shade[k][0],mix*shade[k][1],mix*shade[k][2],1);
+
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ if (i==0)
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ }
+
+ if (fGammaAdj > 0.001f)
+ {
+ // draw layer 'i' a 2nd (or 3rd, or 4th...) time, additively
+ int nRedraws = (int)(fGammaAdj - 0.0001f);
+ float gamma;
+
+ for (int nRedraw=0; nRedraw < nRedraws; nRedraw++)
+ {
+ if (nRedraw == nRedraws-1)
+ gamma = fGammaAdj - (int)(fGammaAdj - 0.0001f);
+ else
+ gamma = 1.0f;
+
+ for (int k=0; k<4; k++)
+ v3[k].Diffuse = D3DCOLOR_RGBA_01(gamma*mix*shade[k][0],gamma*mix*shade[k][1],gamma*mix*shade[k][2],1);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+ }
+ }
+ }
+ }
+ else
+ {
+ // no video echo
+ v3[0].tu = 0; v3[1].tu = 1; v3[2].tu = 0; v3[3].tu = 1;
+ v3[0].tv = 1; v3[1].tv = 1; v3[2].tv = 0; v3[3].tv = 0;
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+
+ // draw it iteratively, solid the first time, and additively after that
+ int nPasses = (int)(fGammaAdj - 0.001f) + 1;
+ float gamma;
+
+ for (int nPass=0; nPass < nPasses; nPass++)
+ {
+ if (nPass == nPasses - 1)
+ gamma = fGammaAdj - (float)nPass;
+ else
+ gamma = 1.0f;
+
+ for (int k=0; k<4; k++)
+ v3[k].Diffuse = D3DCOLOR_RGBA_01(gamma*shade[k][0],gamma*shade[k][1],gamma*shade[k][2],1);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ if (nPass==0)
+ {
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ }
+ }
+ }
+
+ SPRITEVERTEX v3[4];
+ ZeroMemory(v3, sizeof(SPRITEVERTEX)*4);
+ float fOnePlusInvWidth = 1.0f + 1.0f/(float)GetWidth();
+ float fOnePlusInvHeight = 1.0f + 1.0f/(float)GetHeight();
+ v3[0].x = -fOnePlusInvWidth;
+ v3[1].x = fOnePlusInvWidth;
+ v3[2].x = -fOnePlusInvWidth;
+ v3[3].x = fOnePlusInvWidth;
+ v3[0].y = fOnePlusInvHeight;
+ v3[1].y = fOnePlusInvHeight;
+ v3[2].y = -fOnePlusInvHeight;
+ v3[3].y = -fOnePlusInvHeight;
+ for (int i=0; i<4; i++) v3[i].Diffuse = D3DCOLOR_RGBA_01(1,1,1,1);
+
+ if (*m_pState->var_pf_brighten &&
+ (GetCaps()->SrcBlendCaps & D3DPBLENDCAPS_INVDESTCOLOR ) &&
+ (GetCaps()->DestBlendCaps & D3DPBLENDCAPS_DESTCOLOR)
+ )
+ {
+ // square root filter
+
+ //lpDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); //?
+ //lpDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); //?
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ // first, a perfect invert
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ // then modulate by self (square it)
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ // then another perfect invert
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+ }
+
+ if (*m_pState->var_pf_darken &&
+ (GetCaps()->DestBlendCaps & D3DPBLENDCAPS_DESTCOLOR)
+ )
+ {
+ // squaring filter
+
+ //lpDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); //?
+ //lpDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); //?
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ //lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
+ //lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ //lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ }
+
+ if (*m_pState->var_pf_solarize &&
+ (GetCaps()->SrcBlendCaps & D3DPBLENDCAPS_DESTCOLOR ) &&
+ (GetCaps()->DestBlendCaps & D3DPBLENDCAPS_INVDESTCOLOR)
+ )
+ {
+ //lpDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); //?
+ //lpDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); //?
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+ }
+
+ if (*m_pState->var_pf_invert &&
+ (GetCaps()->SrcBlendCaps & D3DPBLENDCAPS_INVDESTCOLOR )
+ )
+ {
+ //lpDevice->SetRenderState(D3DRS_COLORVERTEX, FALSE); //?
+ //lpDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); //?
+
+ lpDevice->SetTexture(0, NULL);
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
+
+ lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (void*)v3, sizeof(SPRITEVERTEX));
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+}
+
+void CPlugin::ShowToUser_Shaders(int nPass, bool bAlphaBlend, bool bFlipAlpha, bool bCullTiles, bool bFlipCulling)//int bRedraw, int nPassOverride, bool bFlipAlpha)
+{
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ //lpDevice->SetTexture(0, m_lpVS[1]);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( MYVERTEX_FORMAT );
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ float fZoom = 1.0f;
+
+ float aspect = GetWidth() / (float)(GetHeight()*m_fInvAspectY/**4.0f/3.0f*/);
+ float x_aspect_mult = 1.0f;
+ float y_aspect_mult = 1.0f;
+
+ if (aspect>1)
+ y_aspect_mult = aspect;
+ else
+ x_aspect_mult = 1.0f/aspect;
+
+ // hue shader
+ float shade[4][3] = {
+ { 1.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f },
+ { 1.0f, 1.0f, 1.0f } }; // for each vertex, then each comp.
+
+ float fShaderAmount = 1;//since we don't know if shader uses it or not! m_pState->m_fShader.eval(GetTime());
+
+ if (fShaderAmount > 0.001f || m_pState->m_bBlending)
+ {
+ // pick 4 colors for the 4 corners
+ for (int i=0; i<4; i++)
+ {
+ shade[i][0] = 0.6f + 0.3f*sinf(GetTime()*30.0f*0.0143f + 3 + i*21 + m_fRandStart[3]);
+ shade[i][1] = 0.6f + 0.3f*sinf(GetTime()*30.0f*0.0107f + 1 + i*13 + m_fRandStart[1]);
+ shade[i][2] = 0.6f + 0.3f*sinf(GetTime()*30.0f*0.0129f + 6 + i*9 + m_fRandStart[2]);
+ float max = ((shade[i][0] > shade[i][1]) ? shade[i][0] : shade[i][1]);
+ if (shade[i][2] > max) max = shade[i][2];
+ for (int k=0; k<3; k++)
+ {
+ shade[i][k] /= max;
+ shade[i][k] = 0.5f + 0.5f*shade[i][k];
+ }
+ // note: we now pass the raw hue shader colors down; the shader can only use a certain % if it wants.
+ //for (k=0; k<3; k++)
+ // shade[i][k] = shade[i][k]*(fShaderAmount) + 1.0f*(1.0f - fShaderAmount);
+ //m_comp_verts[i].Diffuse = D3DCOLOR_RGBA_01(shade[i][0],shade[i][1],shade[i][2],1);
+ }
+
+ // interpolate the 4 colors & apply to all the verts
+ for (int j=0; j<FCGSY; j++)
+ {
+ for (int i=0; i<FCGSX; i++)
+ {
+ MYVERTEX* p = &m_comp_verts[i + j*FCGSX];
+ float x = p->x*0.5f + 0.5f;
+ float y = p->y*0.5f + 0.5f;
+
+ float col[3] = { 1, 1, 1 };
+ if (fShaderAmount > 0.001f)
+ {
+ for (int c=0; c<3; c++)
+ col[c] = shade[0][c]*( x)*( y) +
+ shade[1][c]*(1-x)*( y) +
+ shade[2][c]*( x)*(1-y) +
+ shade[3][c]*(1-x)*(1-y);
+ }
+
+ // TO DO: improve interp here?
+ // TO DO: during blend, only send the triangles needed
+
+ // if blending, also set up the alpha values - pull them from the alphas used for the Warped Blit
+ double alpha = 1;
+ if (m_pState->m_bBlending)
+ {
+ x *= (m_nGridX + 1);
+ y *= (m_nGridY + 1);
+ x = max(min(x,m_nGridX-1),0);
+ y = max(min(y,m_nGridY-1),0);
+ int nx = (int)x;
+ int ny = (int)y;
+ double dx = x - nx;
+ double dy = y - ny;
+ double alpha00 = (m_verts[(ny )*(m_nGridX+1) + (nx )].Diffuse >> 24);
+ double alpha01 = (m_verts[(ny )*(m_nGridX+1) + (nx+1)].Diffuse >> 24);
+ double alpha10 = (m_verts[(ny+1)*(m_nGridX+1) + (nx )].Diffuse >> 24);
+ double alpha11 = (m_verts[(ny+1)*(m_nGridX+1) + (nx+1)].Diffuse >> 24);
+ alpha = alpha00*(1-dx)*(1-dy) +
+ alpha01*( dx)*(1-dy) +
+ alpha10*(1-dx)*( dy) +
+ alpha11*( dx)*( dy);
+ alpha /= 255.0f;
+ //if (bFlipAlpha)
+ // alpha = 1-alpha;
+
+ //alpha = (m_verts[y*(m_nGridX+1) + x].Diffuse >> 24) / 255.0f;
+ }
+ p->Diffuse = D3DCOLOR_RGBA_01(col[0],col[1],col[2],alpha);
+ }
+ }
+ }
+
+ int nAlphaTestValue = 0;
+ if (bFlipCulling)
+ nAlphaTestValue = 1-nAlphaTestValue;
+
+ if (bAlphaBlend)
+ {
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ if (bFlipAlpha)
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
+ }
+ else
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ }
+ }
+ else
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ // Now do the final composite blit, fullscreen;
+ // or do it twice, alpha-blending, if we're blending between two sets of shaders.
+
+ int pass = nPass;
+ {
+ // PASS 0: draw using *blended per-vertex motion vectors*, but with the OLD comp shader.
+ // PASS 1: draw using *blended per-vertex motion vectors*, but with the NEW comp shader.
+ PShaderInfo* si = (pass==0) ? &m_OldShaders.comp : &m_shaders.comp;
+ CState* state = (pass==0) ? m_pOldState : m_pState;
+
+ lpDevice->SetVertexDeclaration(m_pMyVertDecl);
+ lpDevice->SetVertexShader(m_fallbackShaders_vs.comp.ptr);
+ lpDevice->SetPixelShader (si->ptr);
+
+ ApplyShaderParams( &(si->params), si->CT, state );
+
+ // Hurl the triangles at the video card.
+ // We're going to un-index it, so that we don't stress any crappy (AHEM intel g33)
+ // drivers out there. Not a big deal - only ~800 polys / 24kb of data.
+ // If we're blending, we'll skip any polygon that is all alpha-blended out.
+ // This also respects the MaxPrimCount limit of the video card.
+ MYVERTEX tempv[1024 * 3];
+ int primCount = (FCGSX-2)*(FCGSY-2)*2; // although, some might not be drawn!
+ int max_prims_per_batch = min( GetCaps()->MaxPrimitiveCount, (sizeof(tempv)/sizeof(tempv[0]))/3) - 4;
+ int src_idx = 0;
+ while (src_idx < primCount*3)
+ {
+ int prims_queued = 0;
+ int i=0;
+ while (prims_queued < max_prims_per_batch && src_idx < primCount*3)
+ {
+ // copy 3 verts
+ for (int j=0; j<3; j++)
+ tempv[i++] = m_comp_verts[ m_comp_indices[src_idx++] ];
+ if (bCullTiles)
+ {
+ DWORD d1 = (tempv[i-3].Diffuse >> 24);
+ DWORD d2 = (tempv[i-2].Diffuse >> 24);
+ DWORD d3 = (tempv[i-1].Diffuse >> 24);
+ bool bIsNeeded;
+ if (nAlphaTestValue)
+ bIsNeeded = ((d1 & d2 & d3) < 255);//(d1 < 255) || (d2 < 255) || (d3 < 255);
+ else
+ bIsNeeded = ((d1|d2|d3) > 0);//(d1 > 0) || (d2 > 0) || (d3 > 0);
+ if (!bIsNeeded)
+ i -= 3;
+ else
+ prims_queued++;
+ }
+ else
+ prims_queued++;
+ }
+ if (prims_queued > 0)
+ lpDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, prims_queued, tempv, sizeof(MYVERTEX) );
+ }
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ RestoreShaderParams();
+}
+
+void CPlugin::ShowSongTitleAnim(int w, int h, float fProgress)
+{
+ int i,x,y;
+
+ if (!m_lpDDSTitle) // this *can* be NULL, if not much video mem!
+ return;
+
+ LPDIRECT3DDEVICE9 lpDevice = GetDevice();
+ if (!lpDevice)
+ return;
+
+ lpDevice->SetTexture(0, m_lpDDSTitle);
+ lpDevice->SetVertexShader( NULL );
+ lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+
+ SPRITEVERTEX v3[128];
+ ZeroMemory(v3, sizeof(SPRITEVERTEX)*128);
+
+ if (m_supertext.bIsSongTitle)
+ {
+ // positioning:
+ float fSizeX = 50.0f / (float)m_supertext.nFontSizeUsed * powf(1.5f, m_supertext.fFontSize - 2.0f);
+ float fSizeY = fSizeX * m_nTitleTexSizeY/(float)m_nTitleTexSizeX;// * m_nWidth/(float)m_nHeight;
+
+ if (fSizeX > 0.88f)
+ {
+ fSizeY *= 0.88f/fSizeX;
+ fSizeX = 0.88f;
+ }
+
+ //fixme
+ if (fProgress < 1.0f)//(w!=h) // regular render-to-backbuffer
+ {
+ //float aspect = w/(float)(h*4.0f/3.0f);
+ //fSizeY *= aspect;
+ }
+ else // final render-to-VS0
+ {
+ //float aspect = GetWidth()/(float)(GetHeight()*4.0f/3.0f);
+ //if (aspect < 1.0f)
+ //{
+ // fSizeX *= aspect;
+ // fSizeY *= aspect;
+ //}
+
+ //fSizeY *= -1;
+ }
+
+ //if (fSizeX > 0.92f) fSizeX = 0.92f;
+ //if (fSizeY > 0.92f) fSizeY = 0.92f;
+ i = 0;
+ float vert_clip = VERT_CLIP;//1.0f;//0.45f; // warning: visible clipping has been observed at 0.4!
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ v3[i].tu = x/15.0f;
+ v3[i].tv = (y/7.0f - 0.5f)*vert_clip + 0.5f;
+ v3[i].x = (v3[i].tu*2.0f - 1.0f)*fSizeX;
+ v3[i].y = (v3[i].tv*2.0f - 1.0f)*fSizeY;
+ if (fProgress >= 1.0f)
+ v3[i].y += 1.0f/(float)m_nTexSizeY; //this is a pretty hacky guess @ getting it to align...
+ i++;
+ }
+ }
+
+ // warping
+ float ramped_progress = max(0.0f, 1-fProgress*1.5f);
+ float t2 = powf(ramped_progress, 1.8f)*1.3f;
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ i = y*16+x;
+ v3[i].x += t2*0.070f*sinf(GetTime()*0.31f + v3[i].x*0.39f - v3[i].y*1.94f);
+ v3[i].x += t2*0.044f*sinf(GetTime()*0.81f - v3[i].x*1.91f + v3[i].y*0.27f);
+ v3[i].x += t2*0.061f*sinf(GetTime()*1.31f + v3[i].x*0.61f + v3[i].y*0.74f);
+ v3[i].y += t2*0.061f*sinf(GetTime()*0.37f + v3[i].x*1.83f + v3[i].y*0.69f);
+ v3[i].y += t2*0.070f*sinf(GetTime()*0.67f + v3[i].x*0.42f - v3[i].y*1.39f);
+ v3[i].y += t2*0.087f*sinf(GetTime()*1.07f + v3[i].x*3.55f + v3[i].y*0.89f);
+ }
+ }
+
+ // scale down over time
+ float scale = 1.01f/(powf(fProgress, 0.21f) + 0.01f);
+ for (i=0; i<128; i++)
+ {
+ v3[i].x *= scale;
+ v3[i].y *= scale;
+ }
+ }
+ else
+ {
+ // positioning:
+ float fSizeX = (float)m_nTexSizeX/1024.0f * 100.0f / (float)m_supertext.nFontSizeUsed * powf(1.033f, m_supertext.fFontSize - 50.0f);
+ float fSizeY = fSizeX * m_nTitleTexSizeY/(float)m_nTitleTexSizeX;
+
+ //fixme
+ if (fProgress < 1.0f)//w!=h) // regular render-to-backbuffer
+ {
+ //float aspect = w/(float)(h*4.0f/3.0f);
+ //fSizeY *= aspect;
+ }
+ else // final render-to-VS0
+ {
+ //float aspect = GetWidth()/(float)(GetHeight()*4.0f/3.0f);
+ //if (aspect < 1.0f)
+ //{
+ // fSizeX *= aspect;
+ // fSizeY *= aspect;
+ //}
+ //fSizeY *= -1;
+ }
+
+ //if (fSize > 0.92f) fSize = 0.92f;
+ i = 0;
+ float vert_clip = VERT_CLIP;//0.67f; // warning: visible clipping has been observed at 0.5 (for very short strings) and even 0.6 (for wingdings)!
+ for (y=0; y<8; y++)
+ {
+ for (x=0; x<16; x++)
+ {
+ v3[i].tu = x/15.0f;
+ v3[i].tv = (y/7.0f - 0.5f)*vert_clip + 0.5f;
+ v3[i].x = (v3[i].tu*2.0f - 1.0f)*fSizeX;
+ v3[i].y = (v3[i].tv*2.0f - 1.0f)*fSizeY;
+ if (fProgress >= 1.0f)
+ v3[i].y += 1.0f/(float)m_nTexSizeY; //this is a pretty hacky guess @ getting it to align...
+ i++;
+ }
+ }
+
+ // apply 'growth' factor and move to user-specified (x,y)
+ //if (fabsf(m_supertext.fGrowth-1.0f) > 0.001f)
+ {
+ float t = (1.0f)*(1-fProgress) + (fProgress)*(m_supertext.fGrowth);
+ float dx = (m_supertext.fX*2-1);
+ float dy = (m_supertext.fY*2-1);
+ if (w!=h) // regular render-to-backbuffer
+ {
+ float aspect = w/(float)(h*4.0f/3.0f);
+ if (aspect < 1)
+ dx /= aspect;
+ else
+ dy *= aspect;
+ }
+
+ for (i=0; i<128; i++)
+ {
+ // note: (x,y) are in (-1,1) range, but m_supertext.f{X|Y} are in (0..1) range
+ v3[i].x = (v3[i].x)*t + dx;
+ v3[i].y = (v3[i].y)*t + dy;
+ }
+ }
+ }
+
+ WORD indices[7*15*6];
+ i = 0;
+ for (y=0; y<7; y++)
+ {
+ for (x=0; x<15; x++)
+ {
+ indices[i++] = y*16 + x;
+ indices[i++] = y*16 + x + 1;
+ indices[i++] = y*16 + x + 16;
+ indices[i++] = y*16 + x + 1;
+ indices[i++] = y*16 + x + 16;
+ indices[i++] = y*16 + x + 17;
+ }
+ }
+
+ // final flip on y
+ //for (i=0; i<128; i++)
+ // v3[i].y *= -1.0f;
+ for (i=0; i<128; i++)
+ //v3[i].y /= ASPECT_Y;
+ v3[i].y *= m_fInvAspectY;
+
+ for (int it=0; it<2; it++)
+ {
+ // colors
+ {
+ float t;
+
+ if (m_supertext.bIsSongTitle)
+ t = powf(fProgress, 0.3f)*1.0f;
+ else
+ t = CosineInterp(min(1.0f, (fProgress/m_supertext.fFadeTime)));
+
+ if (it==0)
+ v3[0].Diffuse = D3DCOLOR_RGBA_01(t,t,t,t);
+ else
+ v3[0].Diffuse = D3DCOLOR_RGBA_01(t*m_supertext.nColorR/255.0f,t*m_supertext.nColorG/255.0f,t*m_supertext.nColorB/255.0f,t);
+
+ for (i=1; i<128; i++)
+ v3[i].Diffuse = v3[0].Diffuse;
+ }
+
+ // nudge down & right for shadow, up & left for solid text
+ float offset_x = 0, offset_y = 0;
+ switch(it)
+ {
+ case 0:
+ offset_x = 2.0f/(float)m_nTitleTexSizeX;
+ offset_y = 2.0f/(float)m_nTitleTexSizeY;
+ break;
+ case 1:
+ offset_x = -4.0f/(float)m_nTitleTexSizeX;
+ offset_y = -4.0f/(float)m_nTitleTexSizeY;
+ break;
+ }
+
+ for (i=0; i<128; i++)
+ {
+ v3[i].x += offset_x;
+ v3[i].y += offset_y;
+ }
+
+ if (it == 0)
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);//SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
+ }
+ else
+ {
+ lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);//SRCALPHA);
+ lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ }
+
+ lpDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 128, 15*7*6/3, indices, D3DFMT_INDEX16, v3, sizeof(SPRITEVERTEX));
+ }
+
+ lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-ppc-gcc.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-ppc-gcc.c
new file mode 100644
index 00000000..19a09ba8
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-ppc-gcc.c
@@ -0,0 +1,1041 @@
+#if EEL_F_SIZE == 8
+
+void nseel_asm_1pdd(void)
+{
+
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r3)\n"
+ "mtctr r5\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ :: );
+}
+void nseel_asm_1pdd_end(void){}
+
+void nseel_asm_2pdd(void)
+{
+
+ __asm__(
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "lfd f2, 0(r3)\n"
+ "lfd f1, 0(r14)\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ :: );
+};
+void nseel_asm_2pdd_end(void){}
+
+void nseel_asm_2pdds(void)
+{
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f2, 0(r3)\n"
+ "lfd f1, 0(r14)\n"
+ "mtctr r5\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ :: );
+}
+void nseel_asm_2pdds_end(void){}
+
+#else // 32 bit floating point calls
+
+#error mac only can do 64 bit floats for now
+
+#endif
+
+
+void nseel_asm_2pp(void)
+{
+// r3=firstparm, r4=second parm, returns in f1
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "mtctr r5\n"
+ "mr r4, r3\n"
+ "mr r3, r14\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ :: );
+};
+void nseel_asm_2pp_end(void){}
+
+void nseel_asm_1pp(void)
+{
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "mtctr r5\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ :: );
+};
+void nseel_asm_1pp_end(void){}
+
+
+//---------------------------------------------------------------------------------------------------------------
+
+
+
+// do nothing, eh
+void nseel_asm_exec2(void)
+{
+}
+void nseel_asm_exec2_end(void) { }
+
+
+
+void nseel_asm_invsqrt(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "frsqrte f1, f1\n" // less accurate than our x86 equivilent, but invsqrt() is inherently inaccurate anyway
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_invsqrt_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sqr(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "fmul f1, f1, f1\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_sqr_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_abs(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "fabs f1, f1\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_abs_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_assign(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "stfd f1, 0(r14)\n"
+ );
+}
+void nseel_asm_assign_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_add(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fadd f1, f1, f2\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_add_end(void) {}
+
+void nseel_asm_add_op(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fadd f1, f1, f2\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+}
+void nseel_asm_add_op_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sub(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fsub f1, f2, f1\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_sub_end(void) {}
+
+void nseel_asm_sub_op(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fsub f1, f2, f1\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+}
+void nseel_asm_sub_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_mul(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fmul f1, f2, f1\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_mul_end(void) {}
+
+void nseel_asm_mul_op(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fmul f1, f2, f1\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+}
+void nseel_asm_mul_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_div(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fdiv f1, f2, f1\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_div_end(void) {}
+
+void nseel_asm_div_op(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fdiv f1, f2, f1\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+}
+void nseel_asm_div_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_mod(void)
+{
+ __asm__(
+
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fabs f1, f1\n"
+ "fabs f2, f2\n"
+ "fctiwz f1, f1\n"
+ "fctiwz f2, f2\n"
+ "stfd f1, 8(r16)\n"
+ "stfd f2, 16(r16)\n"
+ "lwz r10, 12(r16)\n"
+ "lwz r11, 20(r16)\n" //r11 and r12 have the integers
+
+ "divw r12, r11, r10\n"
+ "mullw r12, r12, r10\n"
+ "subf r10, r12, r11\n"
+
+ "addis r11, 0, 0x4330\n"
+ "addis r12, 0, 0x8000\n"
+ "xoris r10, r10, 0x8000\n"
+ "stw r11, 8(r16)\n" // 0x43300000
+ "stw r10, 12(r16)\n" // our integer sign flipped
+ "stw r11, 16(r16)\n" // 0x43300000
+ "stw r12, 20(r16)\n" // 0x80000000
+ "lfd f1, 8(r16)\n"
+ "lfd f2, 16(r16)\n"
+ "fsub f1, f1, f2\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+
+
+ );
+}
+void nseel_asm_mod_end(void) {}
+
+void nseel_asm_mod_op(void)
+{
+
+ __asm__(
+
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fabs f1, f1\n"
+ "fabs f2, f2\n"
+ "fctiwz f1, f1\n"
+ "fctiwz f2, f2\n"
+ "stfd f1, 8(r16)\n"
+ "stfd f2, 16(r16)\n"
+ "lwz r10, 12(r16)\n"
+ "lwz r11, 20(r16)\n" //r11 and r12 have the integers
+
+ "divw r12, r11, r10\n"
+ "mullw r12, r12, r10\n"
+ "subf r10, r12, r11\n"
+
+ "addis r11, 0, 0x4330\n"
+ "addis r12, 0, 0x8000\n"
+ "xoris r10, r10, 0x8000\n"
+ "stw r11, 8(r16)\n" // 0x43300000
+ "stw r10, 12(r16)\n" // our integer sign flipped
+ "stw r11, 16(r16)\n" // 0x43300000
+ "stw r12, 20(r16)\n" // 0x80000000
+ "lfd f1, 8(r16)\n"
+ "lfd f2, 16(r16)\n"
+ "fsub f1, f1, f2\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+
+}
+void nseel_asm_mod_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_or(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fctiwz f1, f1\n"
+ "fctiwz f2, f2\n"
+ "stfd f1, 8(r16)\n"
+ "stfd f2, 16(r16)\n"
+ "lwz r10, 12(r16)\n"
+ "lwz r11, 20(r16)\n" //r11 and r12 have the integers
+ "or r10, r10, r11\n" // r10 has the result
+ "addis r11, 0, 0x4330\n"
+ "addis r12, 0, 0x8000\n"
+ "xoris r10, r10, 0x8000\n"
+ "stw r11, 8(r16)\n" // 0x43300000
+ "stw r10, 12(r16)\n" // our integer sign flipped
+ "stw r11, 16(r16)\n" // 0x43300000
+ "stw r12, 20(r16)\n" // 0x80000000
+ "lfd f1, 8(r16)\n"
+ "lfd f2, 16(r16)\n"
+ "fsub f1, f1, f2\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_or_end(void) {}
+
+void nseel_asm_or_op(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fctiwz f1, f1\n"
+ "fctiwz f2, f2\n"
+ "stfd f1, 8(r16)\n"
+ "stfd f2, 16(r16)\n"
+ "lwz r10, 12(r16)\n"
+ "lwz r11, 20(r16)\n" //r11 and r12 have the integers
+ "or r10, r10, r11\n" // r10 has the result
+ "addis r11, 0, 0x4330\n"
+ "addis r12, 0, 0x8000\n"
+ "xoris r10, r10, 0x8000\n"
+ "stw r11, 8(r16)\n" // 0x43300000
+ "stw r10, 12(r16)\n" // our integer sign flipped
+ "stw r11, 16(r16)\n" // 0x43300000
+ "stw r12, 20(r16)\n" // 0x80000000
+ "lfd f1, 8(r16)\n"
+ "lfd f2, 16(r16)\n"
+ "fsub f1, f1, f2\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+}
+void nseel_asm_or_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_and(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fctiwz f1, f1\n"
+ "fctiwz f2, f2\n"
+ "stfd f1, 8(r16)\n"
+ "stfd f2, 16(r16)\n"
+ "lwz r10, 12(r16)\n"
+ "lwz r11, 20(r16)\n" //r11 and r12 have the integers
+ "and r10, r10, r11\n" // r10 has the result
+ "addis r11, 0, 0x4330\n"
+ "addis r12, 0, 0x8000\n"
+ "xoris r10, r10, 0x8000\n"
+ "stw r11, 8(r16)\n" // 0x43300000
+ "stw r10, 12(r16)\n" // our integer sign flipped
+ "stw r11, 16(r16)\n" // 0x43300000
+ "stw r12, 20(r16)\n" // 0x80000000
+ "lfd f1, 8(r16)\n"
+ "lfd f2, 16(r16)\n"
+ "fsub f1, f1, f2\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );}
+void nseel_asm_and_end(void) {}
+
+void nseel_asm_and_op(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fctiwz f1, f1\n"
+ "fctiwz f2, f2\n"
+ "stfd f1, 8(r16)\n"
+ "stfd f2, 16(r16)\n"
+ "lwz r10, 12(r16)\n"
+ "lwz r11, 20(r16)\n" //r11 and r12 have the integers
+ "and r10, r10, r11\n" // r10 has the result
+ "addis r11, 0, 0x4330\n"
+ "addis r12, 0, 0x8000\n"
+ "xoris r10, r10, 0x8000\n"
+ "stw r11, 8(r16)\n" // 0x43300000
+ "stw r10, 12(r16)\n" // our integer sign flipped
+ "stw r11, 16(r16)\n" // 0x43300000
+ "stw r12, 20(r16)\n" // 0x80000000
+ "lfd f1, 8(r16)\n"
+ "lfd f2, 16(r16)\n"
+ "fsub f1, f1, f2\n"
+ "stfd f1, 0(r14)\n"
+ "mr r3, r14\n"
+ );
+}
+void nseel_asm_and_op_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
+{
+}
+void nseel_asm_uplus_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_uminus(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "fneg f1, f1\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ );
+}
+void nseel_asm_uminus_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sign(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f2, 0(r5)\n"
+ "lis r9, 0xbff0\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt- cr7, 0f\n"
+ "ble- cr7, 1f\n"
+ " lis r9, 0x3ff0\n"
+ "0:\n"
+ " li r10, 0\n"
+ " stwu r9, 8(r16)\n"
+ " stw r10, 4(r16)\n"
+ " b 2f\n"
+ "1:\n"
+ " stfdu f1, 8(r16)\n"
+ "2:\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_sign_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_bnot(void)
+{
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f2, 0(r5)\n"
+ "lfd f1, 0(r3)\n"
+ "fabs f1, f1\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "1:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_bnot_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_if(void)
+{
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f2, 0(r5)\n"
+ "lfd f1, 0(r3)\n"
+ "addis r6, 0, 0xdead\n"
+ "ori r6, r6, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "fabs f1, f1\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt cr7, 0f\n"
+ " mtctr r6\n"
+ "b 1f\n"
+ "0:\n"
+ " mtctr r7\n"
+ "1:\n"
+ "bctrl\n"
+ :: );
+}
+void nseel_asm_if_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_repeat(void)
+{
+ __asm__(
+ "addis r6, 0, 0xdead\n"
+ "ori r6, r6, 0xbeef\n"
+ "addis r7, 0, ha16(%0)\n"
+ "addi r7, r7, lo16(%0)\n"
+ "lfd f1, 0(r3)\n"
+ "fctiwz f1, f1\n"
+ "stfd f1, 8(r16)\n"
+ "lwz r5, 12(r16)\n" // r5 has count now
+ "cmpwi cr0, r5, 0\n"
+ "ble cr0, 1f\n"
+ "cmpw cr0, r7, r5\n"
+ "bge cr0, 0f\n"
+ "mr r5, r7\n" // set r5 to max if we have to
+"0:\n"
+ "stw r5, -4(r1)\n"
+ "stw r6, -8(r1)\n"
+ "stwu r16, -12(r1)\n"
+
+ "mtctr r6\n"
+ "bctrl\n"
+
+ "lwz r16, 0(r1)\n"
+ "lwz r6, 4(r1)\n"
+ "lwz r5, 8(r1)\n"
+ "addi r1, r1, 12\n"
+ "addi r5, r5, -1\n"
+
+ "cmpwi cr0, r5, 0\n"
+ "bgt cr0, 0b\n"
+ "1:\n"
+ ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN)
+ );
+}
+void nseel_asm_repeat_end(void) {}
+
+void nseel_asm_repeatwhile(void)
+{
+ __asm__(
+ "addis r6, 0, 0xdead\n"
+ "ori r6, r6, 0xbeef\n"
+ "addis r5, 0, ha16(%0)\n"
+ "addi r5, r5, lo16(%0)\n"
+"0:\n"
+ "stw r5, -4(r1)\n"
+ "stw r6, -8(r1)\n"
+ "stwu r16, -12(r1)\n"
+
+ "mtctr r6\n"
+ "bctrl\n"
+
+ "lwz r16, 0(r1)\n"
+ "lwz r6, 4(r1)\n"
+ "lwz r5, 8(r1)\n"
+ "addi r1, r1, 12\n"
+ "addi r5, r5, -1\n"
+
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "lfd f2, 0(r7)\n"
+
+ "lfd f1, 0(r3)\n"
+ "fabs f1, f1\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt cr7, 1f\n"
+
+ "cmpwi cr0, r5, 0\n"
+ "bgt cr0, 0b\n"
+ "1:\n"
+ ::"g" (NSEEL_LOOPFUNC_SUPPORT_MAXLEN)
+ );
+}
+void nseel_asm_repeatwhile_end(void) {}
+
+
+void nseel_asm_band(void)
+{
+ __asm__(
+
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f2, 0(r5)\n"
+ "lfd f1, 0(r3)\n"
+ "fabs f1, f1\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt cr7, 0f\n"
+ "addis r6, 0, 0xdead\n"
+ "ori r6, r6, 0xbeef\n"
+ " mtctr r6\n"
+ " bctrl\n"
+ " addis r5, 0, 0xdead\n"
+ " ori r5, r5, 0xbeef\n"
+ " lfd f2, 0(r5)\n"
+ " lfd f1, 0(r3)\n"
+ " fabs f1, f1\n"
+ " fcmpu cr7, f1, f2\n"
+ " bge cr7, 1f\n"
+ "0:\n"
+ " fsub f1, f1, f1\n" // set f1 to 0!
+ " b 2f\n"
+ "1:\n"
+ " addis r5, 0, 0xdead\n" // set f1 to 1
+ " ori r5, r5, 0xbeef\n"
+ " lfd f1, 0(r5)\n"
+ "2:\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ :: );
+}
+void nseel_asm_band_end(void) {}
+
+void nseel_asm_bor(void)
+{
+ __asm__(
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f2, 0(r5)\n"
+ "lfd f1, 0(r3)\n"
+ "fabs f1, f1\n"
+ "fcmpu cr7, f1, f2\n"
+ "bge cr7, 0f\n"
+ "addis r6, 0, 0xdead\n"
+ "ori r6, r6, 0xbeef\n"
+ " mtctr r6\n"
+ " bctrl\n"
+ " addis r5, 0, 0xdead\n"
+ " ori r5, r5, 0xbeef\n"
+ " lfd f2, 0(r5)\n"
+ " lfd f1, 0(r3)\n"
+ " fabs f1, f1\n"
+ " fcmpu cr7, f1, f2\n"
+ " blt cr7, 1f\n"
+ "0:\n"
+ " addis r5, 0, 0xdead\n" // set f1 to 1
+ " ori r5, r5, 0xbeef\n"
+ " lfd f1, 0(r5)\n"
+ " b 2f\n"
+ "1:\n"
+ " fsub f1, f1, f1\n" // set f1 to 0!
+ "2:\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ :: );
+}
+void nseel_asm_bor_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_equal(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "fsub f1, f1, f2\n"
+ "fabs f1, f1\n"
+ "lfd f2, 0(r5)\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "1:\n"
+ "lfd f1, 0(r5)\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_equal_end(void) {}
+//
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_notequal(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "fsub f1, f1, f2\n"
+ "fabs f1, f1\n"
+ "lfd f2, 0(r5)\n"
+ "fcmpu cr7, f1, f2\n"
+ "blt cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "1:\n"
+ "lfd f1, 0(r5)\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_notequal_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_below(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fcmpu cr7, f2, f1\n"
+ "blt cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "1:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_below_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_beloweq(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fcmpu cr7, f2, f1\n"
+ "ble cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "1:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_beloweq_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_above(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fcmpu cr7, f2, f1\n"
+ "bgt cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "1:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_above_end(void) {}
+
+void nseel_asm_aboveeq(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fcmpu cr7, f2, f1\n"
+ "bge cr7, 0f\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "b 1f\n"
+ "0:\n"
+ "addis r5, 0, 0xdead\n"
+ "ori r5, r5, 0xbeef\n"
+ "lfd f1, 0(r5)\n"
+ "1:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ ::
+ );
+}
+void nseel_asm_aboveeq_end(void) {}
+
+
+
+void nseel_asm_min(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fcmpu cr7, f2, f1\n"
+ "bgt cr7, 0f\n"
+ "fmr f1, f2\n"
+ "0:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ );
+}
+void nseel_asm_min_end(void) {}
+
+void nseel_asm_max(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "lfd f2, 0(r14)\n"
+ "fcmpu cr7, f2, f1\n"
+ "blt cr7, 0f\n"
+ "fmr f1, f2\n"
+ "0:\n"
+ " stfdu f1, 8(r16)\n"
+ " mr r3, r16\n"
+ );
+}
+
+void nseel_asm_max_end(void) {}
+
+
+
+
+
+
+
+
+
+void _asm_generic3parm(void)
+{
+ __asm__(
+ "mr r6, r3\n"
+ "addis r3, 0, 0xdead\n"
+ "ori r3, r3, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mr r4, r15\n"
+ "mr r5, r14\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ ::
+ );
+}
+void _asm_generic3parm_end(void) {}
+
+void _asm_generic3parm_retd(void)
+{
+ __asm__(
+ "mr r6, r3\n"
+ "addis r3, 0, 0xdead\n"
+ "ori r3, r3, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mr r4, r15\n"
+ "mr r5, r14\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ ::
+ );
+}
+void _asm_generic3parm_retd_end(void) {}
+
+
+void _asm_generic2parm(void) // this prob neds to be fixed for ppc
+{
+ __asm__(
+ "mr r5, r3\n"
+ "addis r3, 0, 0xdead\n"
+ "ori r3, r3, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mr r4, r14\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ ::
+ );
+}
+void _asm_generic2parm_end(void) {}
+
+
+void _asm_generic2parm_retd(void)
+{
+ __asm__(
+ "mr r5, r3\n"
+ "addis r3, 0, 0xdead\n"
+ "ori r3, r3, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mr r4, r14\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ ::
+ );
+}
+void _asm_generic2parm_retd_end(void) {}
+
+void _asm_generic1parm(void) // this prob neds to be fixed for ppc
+{
+ __asm__(
+ "mr r4, r3\n"
+ "addis r3, 0, 0xdead\n"
+ "ori r3, r3, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ ::
+ );
+}
+void _asm_generic1parm_end(void) {}
+
+
+
+void _asm_generic1parm_retd(void)
+{
+ __asm__(
+ "mr r4, r3\n"
+ "addis r3, 0, 0xdead\n"
+ "ori r3, r3, 0xbeef\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mtctr r7\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "stfdu f1, 8(r16)\n"
+ "mr r3, r16\n"
+ ::
+ );
+}
+void _asm_generic1parm_retd_end(void) {}
+
+
+
+
+void _asm_megabuf(void)
+{
+ __asm__(
+ "lfd f1, 0(r3)\n"
+ "addis r3, 0, 0xdead\n" // set up context pointer
+ "ori r3, r3, 0xbeef\n"
+ "addis r4, 0, 0xdead\n"
+ "ori r4, r4, 0xbeef\n"
+ "lfd f2, 0(r4)\n"
+ "fadd f1, f2, f1\n"
+ "addis r7, 0, 0xdead\n"
+ "ori r7, r7, 0xbeef\n"
+ "mtctr r7\n"
+ "fctiwz f1, f1\n"
+ "stfd f1, 8(r16)\n"
+ "lwz r4, 12(r16)\n"
+ "subi r1, r1, 64\n"
+ "bctrl\n"
+ "addi r1, r1, 64\n"
+ "cmpi cr0, r3, 0\n"
+ "bne cr0, 0f\n"
+ "sub r5, r5, r5\n"
+ "stwu r5, 8(r16)\n"
+ "stw r5, 4(r16)\n"
+ "mr r3, r16\n"
+ "0:\n"
+ ::
+ );
+}
+
+void _asm_megabuf_end(void) {}
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x64-macho.o b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x64-macho.o
new file mode 100644
index 00000000..76e918ed
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x64-macho.o
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-gcc.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-gcc.c
new file mode 100644
index 00000000..e7cd7e94
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-gcc.c
@@ -0,0 +1,1566 @@
+#if defined(__APPLE__)
+#define SAVE_STACK "pushl %ebp\nmovl %esp, %ebp\nandl $-16, %esp\n"
+#define RESTORE_STACK "leave\n"
+#else
+#define SAVE_STACK
+#define RESTORE_STACK
+#endif
+
+/* note: only EEL_F_SIZE=8 is now supported (no float EEL_F's) */
+
+void nseel_asm_1pdd(void)
+{
+ __asm__(
+ SAVE_STACK
+#ifdef TARGET_X64
+ "movq (%eax), %xmm0\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %edi\n"
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "call *%edi\n"
+ "movl %r15, %rsi\n"
+ "movq xmm0, (%r15)\n"
+#else
+ "call *%edi\n"
+ "movq xmm0, (%esi)\n"
+#endif
+ "addl $128, %rsp\n"
+#else
+ "subl $8, %esp\n" /* keep stack aligned */
+ "pushl 4(%eax)\n" /* push parameter */
+ "pushl (%eax)\n" /* push the rest of the parameter */
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "fstpl (%esi)\n" /* store result */
+ "addl $16, %esp\n"
+#endif
+ "movl %esi, %eax\n" /* set return value */
+ "addl $8, %esi\n" /* advance worktab ptr */
+ RESTORE_STACK
+ );
+}
+void nseel_asm_1pdd_end(void){}
+
+void nseel_asm_2pdd(void)
+{
+ __asm__(
+ SAVE_STACK
+#ifdef TARGET_X64
+ "movq (%eax), xmm1\n"
+ "movq (%edi), xmm0\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %edi\n"
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "call *%edi\n"
+ "movl %r15, %rsi\n"
+ "movq xmm0, (%r15)\n"
+#else
+ "call *%edi\n"
+ "movq xmm0, (%esi)\n"
+#endif
+ "addl $128, %rsp\n"
+#else
+ "pushl 4(%eax)\n" /* push parameter */
+ "pushl (%eax)\n" /* push the rest of the parameter */
+ "pushl 4(%edi)\n" /* push parameter */
+ "pushl (%edi)\n" /* push the rest of the parameter */
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "fstpl (%esi)\n" /* store result */
+ "addl $16, %esp\n"
+#endif
+ "movl %esi, %eax\n" /* set return value */
+ "addl $8, %esi\n" /* advance worktab ptr */
+ RESTORE_STACK
+ );
+}
+void nseel_asm_2pdd_end(void){}
+
+void nseel_asm_2pdds(void)
+{
+ __asm__(
+ SAVE_STACK
+#ifdef TARGET_X64
+ "movq (%eax), xmm1\n"
+ "movq (%edi), xmm0\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %eax\n"
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "movl %rdi, %r14\n"
+ "call *%eax\n"
+ "movl %r15, %rsi\n"
+ "movq xmm0, (%r14)\n"
+ "movl %r14, %rax\n" /* set return value */
+#else
+ "call *%eax\n"
+ "movq xmm0, (%edi)\n"
+ "movl %edi, %eax\n" /* set return value */
+#endif
+ "subl $128, %rsp\n"
+#else
+ "pushl 4(%eax)\n" /* push parameter */
+ "pushl (%eax)\n" /* push the rest of the parameter */
+ "pushl 4(%edi)\n" /* push parameter */
+ "pushl (%edi)\n" /* push the rest of the parameter */
+ "movl $0xffffffff, %eax\n"
+ "call *%eax\n"
+ "fstpl (%edi)\n" /* store result */
+ "addl $16, %esp\n"
+ "movl %edi, %eax\n" /* set return value */
+#endif
+RESTORE_STACK
+ );
+}
+void nseel_asm_2pdds_end(void){}
+
+void nseel_asm_2pp(void)
+{
+ __asm__(
+SAVE_STACK
+#ifdef TARGET_X64
+
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ /* rdi is first parameter */
+ "movl %rax, %rsi\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %eax\n"
+ "call *%eax\n"
+ "movl %r15, %rsi\n"
+ "movq xmm0, (%r15)\n"
+#else
+ "movl %edi, %ecx\n"
+ "movl %eax, %edx\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "movq xmm0, (%esi)\n"
+#endif
+ "addl $128, %rsp\n"
+#else
+ "subl $8, %esp\n" /* keep stack aligned */
+ "pushl %eax\n" /* push parameter */
+ "pushl %edi\n" /* push second parameter */
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n" /* store result */
+ "addl $16, %esp\n"
+#endif
+ "movl %esi, %eax\n" /* set return value */
+ "addl $" EEL_F_SSTR ", %esi\n" /* advance worktab ptr */
+RESTORE_STACK
+ );
+}
+void nseel_asm_2pp_end(void) {}
+
+
+void nseel_asm_1pp(void)
+{
+__asm__(
+SAVE_STACK
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "movl %eax, %edi\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %rax\n"
+ "call *%rax\n"
+ "movl %r15, %rsi\n"
+ "movq xmm0, (%r15)\n"
+#else
+ "movl %eax, %ecx\n"
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "movq xmm0, (%esi)\n"
+#endif
+ "addl $128, %rsp\n"
+#else
+ "subl $12, %esp\n" /* keep stack aligned */
+ "pushl %eax\n" /* push parameter */
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n" /* store result */
+ "addl $16, %esp\n"
+#endif
+ "movl %esi, %eax\n" /* set return value */
+ "addl $" EEL_F_SSTR ", %esi\n" /* advance worktab ptr */
+RESTORE_STACK
+ );
+}
+void nseel_asm_1pp_end(void){}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+
+
+// do nothing, eh
+void nseel_asm_exec2(void)
+{
+ __asm__(
+ ""
+ );
+}
+void nseel_asm_exec2_end(void) { }
+
+
+
+void nseel_asm_invsqrt(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl $0x5f3759df, %edx\n"
+ "fsts (%esi)\n"
+#ifdef TARGET_X64
+ "movl 0xffffffff, %rax\n"
+ "subl %ecx, %ecx\n"
+ "fmul" EEL_F_SUFFIX " (%rax)\n"
+#else
+ "fmul" EEL_F_SUFFIX " (0xffffffff)\n"
+#endif
+ "movl (%esi), %ecx\n"
+ "sarl $1, %ecx\n"
+ "subl %ecx, %edx\n"
+ "movl %edx, (%esi)\n"
+ "fmuls (%esi)\n"
+ "fmuls (%esi)\n"
+#ifdef TARGET_X64
+ "movl 0xffffffff, %rax\n"
+ "fadd" EEL_F_SUFFIX " (%rax)\n"
+#else
+ "fadd" EEL_F_SUFFIX " (0xffffffff)\n"
+#endif
+ "fmuls (%esi)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_invsqrt_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sin(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fsin\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_sin_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_cos(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fcos\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_cos_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_tan(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fptan\n"
+ "movl %esi, %eax\n"
+ "fstp %st(0)\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_tan_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sqr(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fmul %st(0), %st(0)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_sqr_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sqrt(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+ "fsqrt\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_sqrt_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_log(void)
+{
+ __asm__(
+ "fldln2\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fyl2x\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_log_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_log10(void)
+{
+ __asm__(
+ "fldlg2\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fyl2x\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+
+ );
+}
+void nseel_asm_log10_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_abs(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_abs_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_assign(void)
+{
+#ifdef TARGET_X64
+
+ __asm__(
+ "movll (%rax), %rdx\n"
+ "movll %rdx, %rcx\n"
+ "shrl $32, %rdx\n"
+ "andl $0x7FF00000, %edx\n"
+ "jz 1f\n"
+ "cmpl $0x7FF00000, %edx\n"
+ "je 1f\n"
+ "jmp 0f\n"
+ "1:\n"
+ "subl %rcx, %rcx\n"
+ "0:\n"
+ "movll %rcx, (%edi)\n"
+ );
+
+#else
+
+
+#if EEL_F_SIZE == 8
+ __asm__(
+ "movl 4(%eax), %edx\n"
+ "movl (%eax), %ecx\n"
+ "andl $0x7ff00000, %edx\n"
+ "jz 1f\n" // if exponent=zero, zero
+ "cmpl $0x7ff00000, %edx\n"
+ "je 1f\n" // if exponent=all 1s, zero
+ "movl 4(%eax), %edx\n" // reread
+ "jmp 0f\n"
+ "1:\n"
+ "subl %ecx, %ecx\n"
+ "subl %edx, %edx\n"
+ "0:\n"
+ "movl %ecx, (%edi)\n"
+ "movl %edx, 4(%edi)\n"
+ );
+#else
+ __asm__(
+ "movl (%eax), %ecx\n"
+ "movl %ecx, (%edi)\n"
+ );
+#endif
+
+#endif
+
+}
+void nseel_asm_assign_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_add(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fadd" EEL_F_SUFFIX " (%edi)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_add_end(void) {}
+
+void nseel_asm_add_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fadd" EEL_F_SUFFIX " (%edi)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_add_op_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sub(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fsub" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_sub_end(void) {}
+
+void nseel_asm_sub_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fsub" EEL_F_SUFFIX " (%eax)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_sub_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_mul(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fmul" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_mul_end(void) {}
+
+void nseel_asm_mul_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fmul" EEL_F_SUFFIX " (%edi)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_mul_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_div(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fdiv" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_div_end(void) {}
+
+void nseel_asm_div_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fdiv" EEL_F_SUFFIX " (%eax)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_div_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_mod(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+ "fistpl (%esi)\n"
+ "fabs\n"
+ "fistpl 4(%esi)\n"
+ "xorl %edx, %edx\n"
+#ifdef TARGET_X64
+ "subl %eax, %eax\n"
+#endif
+ "cmpl $0, (%esi)\n"
+ "je 0f\n" // skip devide, set return to 0
+ "movl 4(%esi), %eax\n"
+ "divl (%esi)\n"
+ "0:\n"
+ "movl %edx, (%esi)\n"
+ "fildl (%esi)\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_mod_end(void) {}
+
+void nseel_asm_mod_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+ "fistpl (%edi)\n"
+ "fabs\n"
+ "fistpl (%esi)\n"
+#ifdef TARGET_X64
+ "subl %eax, %eax\n"
+#endif
+ "xorl %edx, %edx\n"
+ "cmpl $0, (%edi)\n"
+ "je 0f\n" // skip devide, set return to 0
+ "movl (%esi), %eax\n"
+ "divl (%edi)\n"
+ "0:\n"
+ "movl %edx, (%edi)\n"
+ "fildl (%edi)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_mod_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_or(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fistpll (%esi)\n"
+ "fistpll 8(%esi)\n"
+#ifdef TARGET_X64
+ "movll 8(%rsi), %rdi\n"
+ "orll %rdi, (%rsi)\n"
+#else
+ "movl 8(%esi), %edi\n"
+ "movl 12(%esi), %ecx\n"
+ "orl %edi, (%esi)\n"
+ "orl %ecx, 4(%esi)\n"
+#endif
+ "fildll (%esi)\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_or_end(void) {}
+
+void nseel_asm_or_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fistpll (%edi)\n"
+ "fistpll (%esi)\n"
+#ifdef TARGET_X64
+ "movll (%rsi), %rax\n"
+ "orll %rax, (%rdi)\n"
+#else
+ "movl (%esi), %eax\n"
+ "movl 4(%esi), %ecx\n"
+ "orl %eax, (%edi)\n"
+ "orl %ecx, 4(%edi)\n"
+#endif
+ "fildll (%edi)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_or_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_and(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl %esi, %eax\n"
+ "fistpll (%esi)\n"
+ "fistpll 8(%esi)\n"
+#ifdef TARGET_X64
+ "movll 8(%rsi), %rdi\n"
+ "andll %rdi, (%rsi)\n"
+#else
+ "movl 8(%esi), %edi\n"
+ "movl 12(%esi), %ecx\n"
+ "andl %edi, (%esi)\n"
+ "andl %ecx, 4(%esi)\n"
+#endif
+ "fildll (%esi)\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_and_end(void) {}
+
+void nseel_asm_and_op(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fistpll (%edi)\n"
+ "fistpll (%esi)\n"
+#ifdef TARGET_X64
+ "movll (%rsi), %rax\n"
+ "andll %rax, (%rdi)\n"
+#else
+ "movl (%esi), %eax\n"
+ "movl 4(%esi), %ecx\n"
+ "andl %eax, (%edi)\n"
+ "andl %ecx, 4(%edi)\n"
+#endif
+ "fildll (%edi)\n"
+ "movl %edi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%edi)\n"
+ );
+}
+void nseel_asm_and_op_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
+{
+ __asm__(
+ ""
+ );
+}
+void nseel_asm_uplus_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_uminus(void)
+{
+ __asm__(
+#if EEL_F_SIZE == 8
+ "movl (%eax), %ecx\n"
+ "movl 4(%eax), %edi\n"
+ "movl %ecx, (%esi)\n"
+ "xorl $0x80000000, %edi\n"
+ "movl %esi, %eax\n"
+ "movl %edi, 4(%esi)\n"
+ "addl $8, %esi\n"
+#else
+ "movl (%eax), %ecx\n"
+ "xorl $0x80000000, %ecx\n"
+ "movl %esi, %eax\n"
+ "movl %ecx, (%esi)\n"
+ "addl $4, %esi\n"
+#endif
+ );
+}
+void nseel_asm_uminus_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_sign(void)
+{
+ __asm__(
+
+#ifdef TARGET_X64
+
+
+ "movl $0xFFFFFFFF, %rdi\n"
+ "movll (%rax), %rcx\n"
+ "movll $0x7FFFFFFFFFFFFFFF, %rdx\n"
+ "testl %rdx, %rcx\n"
+ "jz 1f\n"
+ "shr $60, %rcx\n"
+ "andl $8, %rcx\n"
+ "addll %rdi, %rcx\n"
+ "movl %rsi, %rax\n"
+ "addl $8, %rsi\n"
+ "movll (%rcx), %rdi\n"
+ "movll %rdi, (%rax)\n"
+ "1:\n"
+
+
+#else
+
+ "movl $0xFFFFFFFF, %edi\n"
+#if EEL_F_SIZE == 8
+ "movl 4(%eax), %ecx\n"
+ "movl (%eax), %edx\n"
+ "testl $0xFFFFFFFF, %edx\n"
+ "jnz 0f\n"
+#else
+ "movl (%eax), %ecx\n"
+#endif
+ // high dword (minus sign bit) is zero
+ "test $0x7FFFFFFF, %ecx\n"
+ "jz 1f\n" // zero zero, return the value passed directly
+ "0:\n"
+#if EEL_F_SIZE == 8
+ "shrl $28, %ecx\n"
+#else
+ "shrl $29, %ecx\n"
+#endif
+
+ "andl $" EEL_F_SSTR ", %ecx\n"
+ "addl %edi, %ecx\n"
+
+ "movl %esi, %eax\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+
+ "movl (%ecx), %edi\n"
+#if EEL_F_SIZE == 8
+ "movl 4(%ecx), %edx\n"
+#endif
+ "movl %edi, (%eax)\n"
+#if EEL_F_SIZE == 8
+ "movl %edx, 4(%eax)\n"
+#endif
+ "1:\n"
+
+#endif
+);
+}
+void nseel_asm_sign_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_bnot(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "test $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_bnot_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_if(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+ "movll $0xFFFFFFFF, %rax\n"
+ "movll %rax, (%esi)\n" // conversion script will extend these out to full len
+ "movll $0xFFFFFFFF, %rax\n"
+ "movll %rax, 8(%esi)\n"
+ "fstsw %ax\n"
+ "shrl $5, %rax\n"
+ "andl $8, %rax\n"
+ "movll (%rax, %rsi), %rax\n"
+ "subl $8, %rsp\n"
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+ "movl $0xFFFFFFFF, (%esi)\n"
+ "movl $0xFFFFFFFF, 4(%esi)\n"
+ "fstsw %ax\n"
+ "shrl $6, %eax\n"
+ "andl $4, %eax\n"
+ "movl (%eax, %esi), %eax\n"
+#endif
+ "call *%eax\n"
+#ifdef TARGET_X64
+ "addl $8, %rsp\n"
+#endif
+
+ );
+}
+void nseel_asm_if_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_repeat(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fistpl (%esi)\n"
+#ifdef TARGET_X64 // safe not sure if movl ecx will zero the high word
+ "xorl %ecx, %ecx\n"
+#endif
+ "movl (%esi), %ecx\n"
+ "cmpl $1, %ecx\n"
+ "jl 1f\n"
+ "cmpl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
+ "jl 0f\n"
+ "movl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
+"0:\n"
+ "movl $0xFFFFFFFF, %edx\n"
+ "subl $8, %esp\n" /* keep stack aligned -- note this is required on x64 too!*/
+ "pushl %esi\n" // revert back to last temp workspace
+ "pushl %ecx\n"
+ "call *%edx\n"
+ "popl %ecx\n"
+ "popl %esi\n"
+ "addl $8, %esp\n" /* keep stack aligned -- also required on x64*/
+ "decl %ecx\n"
+ "jnz 0b\n"
+"1:\n"
+ );
+}
+void nseel_asm_repeat_end(void) {}
+
+void nseel_asm_repeatwhile(void)
+{
+ __asm__(
+ "movl $" NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR ", %ecx\n"
+"0:\n"
+ "movl $0xFFFFFFFF, %edx\n"
+ "subl $8, %esp\n" /* keep stack aligned -- required on x86 and x64*/
+ "pushl %esi\n" // revert back to last temp workspace
+ "pushl %ecx\n"
+ "call *%edx\n"
+ "popl %ecx\n"
+ "popl %esi\n"
+ "addl $8, %esp\n" /* keep stack aligned -- required on x86 and x64 */
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "jnz 0f\n"
+ "decl %ecx\n"
+ "jnz 0b\n"
+ "0:\n"
+ "movl %esi, %eax\n"
+ );
+}
+void nseel_asm_repeatwhile_end(void) {}
+
+
+void nseel_asm_band(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "jnz 0f\n" // if Z, then we are nonzero
+
+ "movl $0xFFFFFFFF, %ecx\n"
+#ifdef TARGET_X64
+ "subl $8, %rsp\n"
+#endif
+ "call *%ecx\n"
+#ifdef TARGET_X64
+ "addl $8, %rsp\n"
+#endif
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "jnz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+
+"0:\n"
+ "fldz\n"
+"1:\n"
+
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_band_end(void) {}
+
+void nseel_asm_bor(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "jz 0f\n" // if Z, then we are nonzero
+
+ "movl $0xFFFFFFFF, %ecx\n"
+#ifdef TARGET_X64
+ "subl $8, %rsp\n"
+#endif
+ "call *%ecx\n"
+#ifdef TARGET_X64
+ "addl $8, %rsp\n"
+#endif
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "jz 0f\n"
+ "fldz\n"
+ "jmp 1f\n"
+
+"0:\n"
+ "fld1\n"
+"1:\n"
+
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_bor_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_equal(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fsub" EEL_F_SUFFIX " (%edi)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_equal_end(void) {}
+//
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_notequal(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fsub" EEL_F_SUFFIX " (%edi)\n"
+ "fabs\n"
+#ifdef TARGET_X64
+ "movl $0xFFFFFFFF, %rax\n"
+ "fcomp" EEL_F_SUFFIX " (%rax)\n" //[g_closefact]
+#else
+ "fcomp" EEL_F_SUFFIX " (0xFFFFFFFF)\n" //[g_closefact]
+#endif
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jnz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_notequal_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_below(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fcomp" EEL_F_SUFFIX " (%eax)\n"
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_below_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_beloweq(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fcomp" EEL_F_SUFFIX " (%edi)\n"
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jnz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_beloweq_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+void nseel_asm_above(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fcomp" EEL_F_SUFFIX " (%edi)\n"
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_above_end(void) {}
+
+void nseel_asm_aboveeq(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fcomp" EEL_F_SUFFIX " (%eax)\n"
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "movl %esi, %eax\n"
+ "jnz 0f\n"
+ "fld1\n"
+ "jmp 1f\n"
+ "0:\n"
+ "fldz\n"
+ "1:\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ );
+}
+void nseel_asm_aboveeq_end(void) {}
+
+
+
+void nseel_asm_min(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fcomp" EEL_F_SUFFIX " (%eax)\n"
+ "pushl %eax\n"
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "popl %eax\n"
+ "jz 0f\n"
+ "movl %edi, %eax\n"
+ "0:\n"
+ );
+
+}
+void nseel_asm_min_end(void) {}
+
+void nseel_asm_max(void)
+{
+ __asm__(
+ "fld" EEL_F_SUFFIX " (%edi)\n"
+ "fcomp" EEL_F_SUFFIX " (%eax)\n"
+ "pushl %eax\n"
+ "fstsw %ax\n"
+ "testl $256, %eax\n"
+ "popl %eax\n"
+ "jnz 0f\n"
+ "movl %edi, %eax\n"
+ "0:\n"
+ );
+}
+void nseel_asm_max_end(void) {}
+
+
+
+
+
+// just generic functions left, yay
+
+
+
+
+void _asm_generic3parm(void)
+{
+ __asm__(
+#ifdef TARGET_X64
+
+#ifdef AMD64ABI
+
+ "movl %rsi, %r15\n"
+ "movl %rdi, %rdx\n" // third parameter = parm
+ "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
+
+ "movl %ecx, %rsi\n" // second parameter = parm
+ "movl %rax, %rcx\n" // fourth parameter = parm
+ "movl $0xffffffff, %rax\n" // call function
+ "subl $128, %rsp\n"
+ "call *%rax\n"
+
+ "movl %r15, %rsi\n"
+ "addl $128, %rsp\n"
+
+#else
+ "movl %ecx, %edx\n" // second parameter = parm
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
+ "movl %rdi, %r8\n" // third parameter = parm
+ "movl %rax, %r9\n" // fourth parameter = parm
+ "movl $0xffffffff, %edi\n" // call function
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+#endif
+
+#else
+SAVE_STACK
+ "movl $0xFFFFFFFF, %edx\n"
+ "pushl %eax\n" // push parameter
+ "pushl %edi\n" // push parameter
+ "pushl %ecx\n" // push parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "addl $16, %esp\n"
+RESTORE_STACK
+#endif
+ );
+}
+void _asm_generic3parm_end(void) {}
+
+
+void _asm_generic3parm_retd(void)
+{
+ __asm__(
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "movl %rdi, %rdx\n" // third parameter = parm
+ "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
+ "movl %ecx, %rsi\n" // second parameter = parm
+ "movl %rax, %rcx\n" // fourth parameter = parm
+ "movl $0xffffffff, %rax\n" // call function
+ "subl $128, %rsp\n"
+ "call *%rax\n"
+ "addl $128, %rsp\n"
+ "movl %r15, %rsi\n"
+ "movl %r15, %rax\n"
+ "movq xmm0, (%r15)\n"
+ "addl $8, %rsi\n"
+#else
+ "movl %ecx, %edx\n" // second parameter = parm
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
+ "movl %rdi, %r8\n" // third parameter = parm
+ "movl %rax, %r9\n" // fourth parameter = parm
+ "movl $0xffffffff, %edi\n" // call function
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+ "movq xmm0, (%rsi)\n"
+ "movl %rsi, %rax\n"
+ "addl $8, %rsi\n"
+#endif
+#else
+SAVE_STACK
+ "movl $0xFFFFFFFF, %edx\n"
+ "pushl %eax\n" // push parameter
+ "pushl %edi\n" // push parameter
+ "pushl %ecx\n" // push parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ "addl $16, %esp\n"
+RESTORE_STACK
+#endif
+ );
+}
+void _asm_generic3parm_retd_end(void) {}
+
+
+void _asm_generic2parm(void) // this prob neds to be fixed for ppc
+{
+ __asm__(
+#ifdef TARGET_X64
+
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "movl %edi, %esi\n" // second parameter = parm
+ "movl $0xFFFFFFFF, %edi\n" // first parameter= context
+ "movl %rax, %rdx\n" // third parameter = parm
+ "movl $0xffffffff, %rcx\n" // call function
+ "subl $128, %rsp\n"
+ "call *%rcx\n"
+ "movl %r15, %rsi\n"
+ "addl $128, %rsp\n"
+#else
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
+ "movl %edi, %edx\n" // second parameter = parm
+ "movl %rax, %r8\n" // third parameter = parm
+ "movl $0xffffffff, %edi\n" // call function
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+#endif
+#else
+SAVE_STACK
+ "movl $0xFFFFFFFF, %edx\n"
+ "subl $4, %esp\n" // keep stack aligned
+ "pushl %eax\n" // push parameter
+ "pushl %edi\n" // push parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "addl $16, %esp\n"
+RESTORE_STACK
+#endif
+ );
+}
+void _asm_generic2parm_end(void) {}
+
+
+void _asm_generic2parm_retd(void)
+{
+ __asm__(
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "movl %rdi, %rsi\n" // second parameter = parm
+ "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
+ "movl %rax, %rdx\n" // third parameter = parm
+ "movl $0xffffffff, %rcx\n" // call function
+ "subl $128, %rsp\n"
+ "call *%rcx\n"
+ "movl %r15, %rsi\n"
+ "addl $128, %rsp\n"
+ "movq xmm0, (%r15)\n"
+ "movl %r15, %rax\n"
+ "addl $8, %rsi\n"
+#else
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
+ "movl %edi, %edx\n" // second parameter = parm
+ "movl %rax, %r8\n" // third parameter = parm
+ "movl $0xffffffff, %edi\n" // call function
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+ "movq xmm0, (%rsi)\n"
+ "movl %rsi, %rax\n"
+ "addl $8, %rsi\n"
+#endif
+#else
+SAVE_STACK
+ "movl $0xFFFFFFFF, %edx\n"
+ "pushl %eax\n" // push parameter
+ "pushl %edi\n" // push parameter
+ "pushl %ecx\n" // push parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ "addl $16, %esp\n"
+RESTORE_STACK
+#endif
+ );
+}
+void _asm_generic2parm_retd_end(void) {}
+
+
+
+
+
+void _asm_generic1parm(void) // this prob neds to be fixed for ppc
+{
+ __asm__(
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
+ "movl %rsi, %r15\n"
+ "movl %eax, %rsi\n" // second parameter = parm
+ "subl $128, %rsp\n"
+ "movl $0xffffffff, %rcx\n" // call function
+ "call *%rcx\n"
+ "movl %r15, %rsi\n"
+ "addl $128, %rsp\n"
+#else
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
+ "movl %eax, %edx\n" // second parameter = parm
+ "movl $0xffffffff, %edi\n" // call function
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+#endif
+#else
+SAVE_STACK
+ "movl $0xFFFFFFFF, %edx\n"
+ "subl $8, %esp\n" // keep stack aligned
+ "pushl %eax\n" // push parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "addl $16, %esp\n"
+RESTORE_STACK
+#endif
+
+ );
+}
+void _asm_generic1parm_end(void) {}
+
+
+void _asm_generic1parm_retd(void) // 1 parameter returning double
+{
+ __asm__(
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ "movl %rsi, %r15\n"
+ "movl $0xFFFFFFFF, %rdi\n" // first parameter= context
+ "movl %rax, %rsi\n" // second parameter = parm
+ "movl $0xffffffff, %rcx\n" // call function
+ "subl $128, %rsp\n"
+ "call *%rcx\n"
+ "movl %r15, %rsi\n"
+ "addl $128, %rsp\n"
+ "movq xmm0, (%r15)\n"
+ "movl %r15, %rax\n"
+ "addl $8, %rsi\n"
+#else
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter= context
+ "movl %eax, %edx\n" // second parameter = parm
+ "movl $0xffffffff, %edi\n" // call function
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+ "movq xmm0, (%rsi)\n"
+ "movl %rsi, %rax\n"
+ "addl $8, %rsi\n"
+#endif
+#else
+SAVE_STACK
+ "movl $0xFFFFFFFF, %edx\n"
+ "subl $8, %esp\n" // keep stack aligned
+ "pushl %eax\n" // push parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "movl %esi, %eax\n"
+ "fstp" EEL_F_SUFFIX " (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ "addl $16, %esp\n"
+RESTORE_STACK
+#endif
+ );
+}
+void _asm_generic1parm_retd_end(void) {}
+
+
+
+
+
+// this gets its own stub because it's pretty crucial for performance :/
+
+void _asm_megabuf(void)
+{
+ __asm__(
+SAVE_STACK
+
+#ifdef TARGET_X64
+
+
+#ifdef AMD64ABI
+
+ "movl %rsi, %r15\n"
+ "movl $0xFFFFFFFF, %rdi\n" // first parameter = context pointer
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl $0xFFFFFFFF, %rdx\n"
+ "fadd" EEL_F_SUFFIX " (%rdx)\n"
+ "fistpl (%r15)\n"
+ "xorl %rsi, %rsi\n"
+ "movl (%r15), %esi\n" // r15 = esi (from above)
+ "movl $0xffffffff, %edx\n"
+ "subl $128, %rsp\n"
+ "call *%edx\n"
+ "movl %r15, %rsi\n"
+ "addl $128, %rsp\n"
+ "and %rax, %rax\n"
+ "jnz 0f\n"
+ "movl %r15, %rax\n"
+ "movll $0, (%esi)\n"
+ "addl $" EEL_F_SSTR ", %rsi\n"
+ "0:"
+
+#else
+ "movl $0xFFFFFFFF, %ecx\n" // first parameter = context pointer
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "movl $0xFFFFFFFF, %edx\n"
+ "fadd" EEL_F_SUFFIX " (%rdx)\n"
+ "fistpl (%esi)\n"
+ "xorl %rdx, %rdx\n"
+ "movl (%esi), %edx\n"
+ "movl $0xffffffff, %edi\n"
+ "subl $128, %rsp\n"
+ "call *%edi\n"
+ "addl $128, %rsp\n"
+ "and %rax, %rax\n"
+ "jnz 0f\n"
+ "movl %rsi, %rax\n"
+ "movll $0, (%esi)\n"
+ "addl $" EEL_F_SSTR ", %esi\n"
+ "0:"
+#endif
+
+
+#else
+ "movl $0xFFFFFFFF, %edx\n"
+ "fld" EEL_F_SUFFIX " (%eax)\n"
+ "fadd" EEL_F_SUFFIX " (0xFFFFFFFF)\n"
+ "fistpl (%esi)\n"
+ "subl $8, %esp\n" // keep stack aligned
+ "pushl (%esi)\n" // parameter
+ "pushl %edx\n" // push context pointer
+ "movl $0xffffffff, %edi\n"
+ "call *%edi\n"
+ "addl $16, %esp\n"
+ "and %eax, %eax\n"
+ "jnz 0f\n"
+ "movl %esi, %eax\n"
+ "movl $0, (%esi)\n"
+#if EEL_F_SIZE == 8
+ "movl $0, 4(%esi)\n"
+#endif
+ "addl $" EEL_F_SSTR ", %esi\n"
+ "0:"
+
+
+#endif
+
+RESTORE_STACK
+
+ );
+}
+
+void _asm_megabuf_end(void) {}
+
+
+#ifdef TARGET_X64
+void win64_callcode()
+{
+ __asm__(
+#ifdef AMD64ABI
+ "movll %edi, %eax\n"
+#else
+ "movll %ecx, %eax\n"
+#endif
+
+ "push %rbx\n"
+ "push %rbp\n"
+#ifndef AMD64ABI
+ "push %rdi\n"
+ "push %rsi\n"
+ "push %r12\n"
+ "push %r13\n"
+#endif
+ "push %r14\n" // on AMD64ABI, we'll use r14/r15 to save edi/esi
+ "push %r15\n"
+ "call %eax\n"
+ "pop %r15\n"
+ "pop %r14\n"
+#ifndef AMD64ABI
+ "pop %r13\n"
+ "pop %r12\n"
+ "pop %rsi\n"
+ "pop %rdi\n"
+ "fclex\n"
+#endif
+ "pop %rbp\n"
+ "pop %rbx\n"
+ "ret\n"
+ );
+}
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-msvc.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-msvc.c
new file mode 100644
index 00000000..30c88c5c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/asm-nseel-x86-msvc.c
@@ -0,0 +1,2463 @@
+// THIS FILE AUTOGENERATED FROM asm-nseel-x86-gcc.c by a2i.php
+
+#if EEL_F_SIZE == 8
+ #define EEL_ASM_TYPE qword ptr
+#else
+ #define EEL_ASM_TYPE dword ptr
+#endif
+
+#if defined(__APPLE__)
+#define SAVE_STACK "pushl %ebp\nmovl %esp, %ebp\nandl $-16, %esp\n"
+#define RESTORE_STACK "leave\n"
+#else
+#define SAVE_STACK
+#define RESTORE_STACK
+#endif
+
+/* note: only EEL_F_SIZE=8 is now supported (no float EEL_F's) */
+
+__declspec(naked) void nseel_asm_1pdd(void)
+{
+ __asm {
+ SAVE_STACK
+#ifdef TARGET_X64
+ movq xmm0, [eax];
+ sub rsp, 128;
+ mov edi, 0xffffffff;
+#ifdef AMD64ABI
+ mov r15, rsi;
+ call edi;
+ mov rsi, r15;
+ movq [r15], xmm0;
+#else
+ call edi;
+ movq [esi], xmm0;
+#endif
+ add rsp, 128;
+#else
+ sub esp, 8; /* keep stack aligned */
+ push dword ptr [eax+4]; /* push parameter */
+ push dword ptr [eax]; /* push the rest of the parameter */
+ mov edi, 0xffffffff;
+ call edi;
+ fstp qword ptr [esi]; /* store result */
+ add esp, 16;
+#endif
+ mov eax, esi; /* set return value */
+ add esi, 8; /* advance worktab ptr */
+ RESTORE_STACK
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_1pdd_end(void){}
+
+__declspec(naked) void nseel_asm_2pdd(void)
+{
+ __asm {
+ SAVE_STACK
+#ifdef TARGET_X64
+ movq xmm1, [eax];
+ movq xmm0, [edi];
+ sub rsp, 128;
+ mov edi, 0xffffffff;
+#ifdef AMD64ABI
+ mov r15, rsi;
+ call edi;
+ mov rsi, r15;
+ movq [r15], xmm0;
+#else
+ call edi;
+ movq [esi], xmm0;
+#endif
+ add rsp, 128;
+#else
+ push dword ptr [eax+4]; /* push parameter */
+ push dword ptr [eax]; /* push the rest of the parameter */
+ push dword ptr [edi+4]; /* push parameter */
+ push dword ptr [edi]; /* push the rest of the parameter */
+ mov edi, 0xffffffff;
+ call edi;
+ fstp qword ptr [esi]; /* store result */
+ add esp, 16;
+#endif
+ mov eax, esi; /* set return value */
+ add esi, 8; /* advance worktab ptr */
+ RESTORE_STACK
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_2pdd_end(void){}
+
+__declspec(naked) void nseel_asm_2pdds(void)
+{
+ __asm {
+ SAVE_STACK
+#ifdef TARGET_X64
+ movq xmm1, [eax];
+ movq xmm0, [edi];
+ sub rsp, 128;
+ mov eax, 0xffffffff;
+#ifdef AMD64ABI
+ mov r15, rsi;
+ mov r14, rdi;
+ call eax;
+ mov rsi, r15;
+ movq [r14], xmm0;
+ mov rax, r14; /* set return value */
+#else
+ call eax;
+ movq [edi], xmm0;
+ mov eax, edi; /* set return value */
+#endif
+ sub rsp, 128;
+#else
+ push dword ptr [eax+4]; /* push parameter */
+ push dword ptr [eax]; /* push the rest of the parameter */
+ push dword ptr [edi+4]; /* push parameter */
+ push dword ptr [edi]; /* push the rest of the parameter */
+ mov eax, 0xffffffff;
+ call eax;
+ fstp qword ptr [edi]; /* store result */
+ add esp, 16;
+ mov eax, edi; /* set return value */
+#endif
+RESTORE_STACK
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_2pdds_end(void){}
+
+__declspec(naked) void nseel_asm_2pp(void)
+{
+ __asm {
+SAVE_STACK
+#ifdef TARGET_X64
+
+#ifdef AMD64ABI
+ mov r15, rsi;
+ /* rdi is first parameter */
+ mov rsi, rax;
+ sub rsp, 128;
+ mov eax, 0xffffffff;
+ call eax;
+ mov rsi, r15;
+ movq [r15], xmm0;
+#else
+ mov ecx, edi;
+ mov edx, eax;
+ sub rsp, 128;
+ mov edi, 0xffffffff;
+ call edi;
+ movq [esi], xmm0;
+#endif
+ add rsp, 128;
+#else
+ sub esp, 8; /* keep stack aligned */
+ push eax; /* push parameter */
+ push edi; /* push second parameter */
+ mov edi, 0xffffffff;
+ call edi;
+ fstp EEL_ASM_TYPE [esi]; /* store result */
+ add esp, 16;
+#endif
+ mov eax, esi; /* set return value */
+ add esi, EEL_F_SIZE; /* advance worktab ptr */
+RESTORE_STACK
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_2pp_end(void) {}
+
+
+__declspec(naked) void nseel_asm_1pp(void)
+{
+__asm {
+SAVE_STACK
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ mov r15, rsi;
+ mov edi, eax;
+ sub rsp, 128;
+ mov rax, 0xffffffff;
+ call rax;
+ mov rsi, r15;
+ movq [r15], xmm0;
+#else
+ mov ecx, eax;
+ sub rsp, 128;
+ mov edi, 0xffffffff;
+ call edi;
+ movq [esi], xmm0;
+#endif
+ add rsp, 128;
+#else
+ sub esp, 12; /* keep stack aligned */
+ push eax; /* push parameter */
+ mov edi, 0xffffffff;
+ call edi;
+ fstp EEL_ASM_TYPE [esi]; /* store result */
+ add esp, 16;
+#endif
+ mov eax, esi; /* set return value */
+ add esi, EEL_F_SIZE; /* advance worktab ptr */
+RESTORE_STACK
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_1pp_end(void){}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+
+
+// do nothing, eh
+__declspec(naked) void nseel_asm_exec2(void)
+{
+ __asm {
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_exec2_end(void) { }
+
+
+
+__declspec(naked) void nseel_asm_invsqrt(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ mov edx, 0x5f3759df;
+ fst dword ptr [esi];
+#ifdef TARGET_X64
+ mov rax, 0xffffffff;
+ sub ecx, ecx;
+ fmul EEL_ASM_TYPE [rax];
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fmul qword ptr [0xffffffff]
+_emit 0x0D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fmul dword ptr [0xffffffff]
+_emit 0x0D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ mov ecx, dword ptr [esi];
+ sar ecx, 1;
+ sub edx, ecx;
+ mov dword ptr [esi], edx;
+ fmul dword ptr [esi];
+ fmul dword ptr [esi];
+#ifdef TARGET_X64
+ mov rax, 0xffffffff;
+ fadd EEL_ASM_TYPE [rax];
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fadd qword ptr [0xffffffff]
+_emit 0x05;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fadd dword ptr [0xffffffff]
+_emit 0x05;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fmul dword ptr [esi];
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_invsqrt_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_sin(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fsin;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_sin_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_cos(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fcos;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_cos_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_tan(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fptan;
+ mov eax, esi;
+ fstp st(0);
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_tan_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_sqr(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fmul st(0), st(0);
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_sqr_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_sqrt(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+ fsqrt;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_sqrt_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_log(void)
+{
+ __asm {
+ fldln2;
+ fld EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fyl2x;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_log_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_log10(void)
+{
+ __asm {
+ fldlg2;
+ fld EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fyl2x;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_log10_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_abs(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_abs_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_assign(void)
+{
+#ifdef TARGET_X64
+
+ __asm {
+ mov rdx, qword ptr [rax];
+ mov rcx, rdx;
+ shr rdx, 32;
+ and edx, 0x7FF00000;
+ jz label_0;
+ cmp edx, 0x7FF00000;
+ je label_0;
+ jmp label_1;
+label_0:
+
+ sub rcx, rcx;
+label_1:
+
+ mov qword ptr [edi], rcx;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+
+#else
+
+
+#if EEL_F_SIZE == 8
+ __asm {
+ mov edx, dword ptr [eax+4];
+ mov ecx, dword ptr [eax];
+ and edx, 0x7ff00000;
+ jz label_2; // if exponent=zero, zero
+ cmp edx, 0x7ff00000;
+ je label_2; // if exponent=all 1s, zero
+ mov edx, dword ptr [eax+4]; // reread
+ jmp label_3;
+label_2:
+
+ sub ecx, ecx;
+ sub edx, edx;
+label_3:
+
+ mov dword ptr [edi], ecx;
+ mov dword ptr [edi+4], edx;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+#else
+ __asm {
+ mov ecx, dword ptr [eax];
+ mov dword ptr [edi], ecx;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+#endif
+
+#endif
+
+}
+__declspec(naked) void nseel_asm_assign_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_add(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fadd EEL_ASM_TYPE [edi];
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_add_end(void) {}
+
+__declspec(naked) void nseel_asm_add_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fadd EEL_ASM_TYPE [edi];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_add_op_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_sub(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fsub EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_sub_end(void) {}
+
+__declspec(naked) void nseel_asm_sub_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fsub EEL_ASM_TYPE [eax];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_sub_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_mul(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fmul EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_mul_end(void) {}
+
+__declspec(naked) void nseel_asm_mul_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fmul EEL_ASM_TYPE [edi];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_mul_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_div(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fdiv EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_div_end(void) {}
+
+__declspec(naked) void nseel_asm_div_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fdiv EEL_ASM_TYPE [eax];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_div_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_mod(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+ fistp dword ptr [esi];
+ fabs;
+ fistp dword ptr [esi+4];
+ xor edx, edx;
+#ifdef TARGET_X64
+ sub eax, eax;
+#endif
+ cmp dword ptr [esi], 0;
+ je label_4; // skip devide, set return to 0
+ mov eax, dword ptr [esi+4];
+ div dword ptr [esi];
+label_4:
+
+ mov dword ptr [esi], edx;
+ fild dword ptr [esi];
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_mod_end(void) {}
+
+__declspec(naked) void nseel_asm_mod_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+ fistp dword ptr [edi];
+ fabs;
+ fistp dword ptr [esi];
+#ifdef TARGET_X64
+ sub eax, eax;
+#endif
+ xor edx, edx;
+ cmp dword ptr [edi], 0;
+ je label_5; // skip devide, set return to 0
+ mov eax, dword ptr [esi];
+ div dword ptr [edi];
+label_5:
+
+ mov dword ptr [edi], edx;
+ fild dword ptr [edi];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_mod_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_or(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fld EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fistp qword ptr [esi];
+ fistp qword ptr [esi+8];
+#ifdef TARGET_X64
+ mov rdi, qword ptr [rsi+8];
+ or qword ptr [rsi], rdi;
+#else
+ mov edi, dword ptr [esi+8];
+ mov ecx, dword ptr [esi+12];
+ or dword ptr [esi], edi;
+ or dword ptr [esi+4], ecx;
+#endif
+ fild qword ptr [esi];
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_or_end(void) {}
+
+__declspec(naked) void nseel_asm_or_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fld EEL_ASM_TYPE [eax];
+ fistp qword ptr [edi];
+ fistp qword ptr [esi];
+#ifdef TARGET_X64
+ mov rax, qword ptr [rsi];
+ or qword ptr [rdi], rax;
+#else
+ mov eax, dword ptr [esi];
+ mov ecx, dword ptr [esi+4];
+ or dword ptr [edi], eax;
+ or dword ptr [edi+4], ecx;
+#endif
+ fild qword ptr [edi];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_or_op_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_and(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fld EEL_ASM_TYPE [eax];
+ mov eax, esi;
+ fistp qword ptr [esi];
+ fistp qword ptr [esi+8];
+#ifdef TARGET_X64
+ mov rdi, qword ptr [rsi+8];
+ and qword ptr [rsi], rdi;
+#else
+ mov edi, dword ptr [esi+8];
+ mov ecx, dword ptr [esi+12];
+ and dword ptr [esi], edi;
+ and dword ptr [esi+4], ecx;
+#endif
+ fild qword ptr [esi];
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_and_end(void) {}
+
+__declspec(naked) void nseel_asm_and_op(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fld EEL_ASM_TYPE [eax];
+ fistp qword ptr [edi];
+ fistp qword ptr [esi];
+#ifdef TARGET_X64
+ mov rax, qword ptr [rsi];
+ and qword ptr [rdi], rax;
+#else
+ mov eax, dword ptr [esi];
+ mov ecx, dword ptr [esi+4];
+ and dword ptr [edi], eax;
+ and dword ptr [edi+4], ecx;
+#endif
+ fild qword ptr [edi];
+ mov eax, edi;
+ fstp EEL_ASM_TYPE [edi];
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_and_op_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
+{
+ __asm {
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_uplus_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_uminus(void)
+{
+ __asm {
+#if EEL_F_SIZE == 8
+ mov ecx, dword ptr [eax];
+ mov edi, dword ptr [eax+4];
+ mov dword ptr [esi], ecx;
+ xor edi, 0x80000000;
+ mov eax, esi;
+ mov dword ptr [esi+4], edi;
+ add esi, 8;
+#else
+ mov ecx, dword ptr [eax];
+ xor ecx, 0x80000000;
+ mov eax, esi;
+ mov dword ptr [esi], ecx;
+ add esi, 4;
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_uminus_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_sign(void)
+{
+ __asm {
+
+#ifdef TARGET_X64
+
+
+ mov rdi, 0xFFFFFFFF;
+ mov rcx, qword ptr [rax];
+ mov rdx, 0x7FFFFFFFFFFFFFFF;
+ test rcx, rdx;
+ jz label_6;
+ shr rcx, 60;
+ and rcx, 8;
+ add rcx, rdi;
+ mov rax, rsi;
+ add rsi, 8;
+ mov rdi, qword ptr [rcx];
+ mov qword ptr [rax], rdi;
+label_6:
+
+
+
+#else
+
+ mov edi, 0xFFFFFFFF;
+#if EEL_F_SIZE == 8
+ mov ecx, dword ptr [eax+4];
+ mov edx, dword ptr [eax];
+ test edx, 0xFFFFFFFF;
+ jnz label_7;
+#else
+ mov ecx, dword ptr [eax];
+#endif
+ // high dword (minus sign bit) is zero
+ test ecx, 0x7FFFFFFF;
+ jz label_8; // zero zero, return the value passed directly
+label_7:
+
+#if EEL_F_SIZE == 8
+ shr ecx, 28;
+#else
+ shr ecx, 29;
+#endif
+
+ and ecx, EEL_F_SIZE;
+ add ecx, edi;
+
+ mov eax, esi;
+ add esi, EEL_F_SIZE;
+
+ mov edi, dword ptr [ecx];
+#if EEL_F_SIZE == 8
+ mov edx, dword ptr [ecx+4];
+#endif
+ mov dword ptr [eax], edi;
+#if EEL_F_SIZE == 8
+ mov dword ptr [eax+4], edx;
+#endif
+label_8:
+
+
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+}
+}
+__declspec(naked) void nseel_asm_sign_end(void) {}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_bnot(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jz label_9;
+ fld1;
+ jmp label_10;
+label_9:
+
+ fldz;
+label_10:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_bnot_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_if(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+ mov rax, 0xFFFFFFFF;
+ mov qword ptr [esi], rax; // conversion script will extend these out to full len
+ mov rax, 0xFFFFFFFF;
+ mov qword ptr [esi+8], rax;
+ fstsw ax;
+ shr rax, 5;
+ and rax, 8;
+ mov rax, qword ptr [rax+rsi];
+ sub rsp, 8;
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+ mov dword ptr [esi], 0xFFFFFFFF;
+ mov dword ptr [esi+4], 0xFFFFFFFF;
+ fstsw ax;
+ shr eax, 6;
+ and eax, 4;
+ mov eax, dword ptr [eax+esi];
+#endif
+ call eax;
+#ifdef TARGET_X64
+ add rsp, 8;
+#endif
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_if_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_repeat(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fistp dword ptr [esi];
+#ifdef TARGET_X64 // safe not sure if movl ecx will zero the high word
+ xor ecx, ecx;
+#endif
+ mov ecx, dword ptr [esi];
+ cmp ecx, 1;
+ jl label_11;
+ cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN;
+ jl label_12;
+ mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN;
+label_12:
+
+ mov edx, 0xFFFFFFFF;
+ sub esp, 8; /* keep stack aligned -- note this is required on x64 too!*/
+ push esi; // revert back to last temp workspace
+ push ecx;
+ call edx;
+ pop ecx;
+ pop esi;
+ add esp, 8; /* keep stack aligned -- also required on x64*/
+ dec ecx;
+ jnz label_12;
+label_11:
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_repeat_end(void) {}
+
+__declspec(naked) void nseel_asm_repeatwhile(void)
+{
+ __asm {
+ mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN;
+label_13:
+
+ mov edx, 0xFFFFFFFF;
+ sub esp, 8; /* keep stack aligned -- required on x86 and x64*/
+ push esi; // revert back to last temp workspace
+ push ecx;
+ call edx;
+ pop ecx;
+ pop esi;
+ add esp, 8; /* keep stack aligned -- required on x86 and x64 */
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ jnz label_14;
+ dec ecx;
+ jnz label_13;
+label_14:
+
+ mov eax, esi;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_repeatwhile_end(void) {}
+
+
+__declspec(naked) void nseel_asm_band(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ jnz label_15; // if Z, then we are nonzero
+
+ mov ecx, 0xFFFFFFFF;
+#ifdef TARGET_X64
+ sub rsp, 8;
+#endif
+ call ecx;
+#ifdef TARGET_X64
+ add rsp, 8;
+#endif
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ jnz label_15;
+ fld1;
+ jmp label_16;
+
+label_15:
+
+ fldz;
+label_16:
+
+
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_band_end(void) {}
+
+__declspec(naked) void nseel_asm_bor(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ jz label_17; // if Z, then we are nonzero
+
+ mov ecx, 0xFFFFFFFF;
+#ifdef TARGET_X64
+ sub rsp, 8;
+#endif
+ call ecx;
+#ifdef TARGET_X64
+ add rsp, 8;
+#endif
+ fld EEL_ASM_TYPE [eax];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ jz label_17;
+ fldz;
+ jmp label_18;
+
+label_17:
+
+ fld1;
+label_18:
+
+
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_bor_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_equal(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fsub EEL_ASM_TYPE [edi];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jz label_19;
+ fld1;
+ jmp label_20;
+label_19:
+
+ fldz;
+label_20:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_equal_end(void) {}
+//
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_notequal(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fsub EEL_ASM_TYPE [edi];
+ fabs;
+#ifdef TARGET_X64
+ mov rax, 0xFFFFFFFF;
+ fcomp EEL_ASM_TYPE [rax]; //[g_closefact]
+#else
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fcomp qword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fcomp dword ptr [0xffffffff]
+_emit 0x1D;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+#endif
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jnz label_21;
+ fld1;
+ jmp label_22;
+label_21:
+
+ fldz;
+label_22:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_notequal_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_below(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fcomp EEL_ASM_TYPE [eax];
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jz label_23;
+ fld1;
+ jmp label_24;
+label_23:
+
+ fldz;
+label_24:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_below_end(void) {}
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_beloweq(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fcomp EEL_ASM_TYPE [edi];
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jnz label_25;
+ fld1;
+ jmp label_26;
+label_25:
+
+ fldz;
+label_26:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_beloweq_end(void) {}
+
+
+//---------------------------------------------------------------------------------------------------------------
+__declspec(naked) void nseel_asm_above(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [eax];
+ fcomp EEL_ASM_TYPE [edi];
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jz label_27;
+ fld1;
+ jmp label_28;
+label_27:
+
+ fldz;
+label_28:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_above_end(void) {}
+
+__declspec(naked) void nseel_asm_aboveeq(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fcomp EEL_ASM_TYPE [eax];
+ fstsw ax;
+ test eax, 256;
+ mov eax, esi;
+ jnz label_29;
+ fld1;
+ jmp label_30;
+label_29:
+
+ fldz;
+label_30:
+
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_aboveeq_end(void) {}
+
+
+
+__declspec(naked) void nseel_asm_min(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fcomp EEL_ASM_TYPE [eax];
+ push eax;
+ fstsw ax;
+ test eax, 256;
+ pop eax;
+ jz label_31;
+ mov eax, edi;
+label_31:
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+
+}
+__declspec(naked) void nseel_asm_min_end(void) {}
+
+__declspec(naked) void nseel_asm_max(void)
+{
+ __asm {
+ fld EEL_ASM_TYPE [edi];
+ fcomp EEL_ASM_TYPE [eax];
+ push eax;
+ fstsw ax;
+ test eax, 256;
+ pop eax;
+ jnz label_32;
+ mov eax, edi;
+label_32:
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void nseel_asm_max_end(void) {}
+
+
+
+
+
+// just generic functions left, yay
+
+
+
+
+__declspec(naked) void _asm_generic3parm(void)
+{
+ __asm {
+#ifdef TARGET_X64
+
+#ifdef AMD64ABI
+
+ mov r15, rsi;
+ mov rdx, rdi; // third parameter = parm
+ mov rdi, 0xFFFFFFFF; // first parameter= context
+
+ mov rsi, ecx; // second parameter = parm
+ mov rcx, rax; // fourth parameter = parm
+ mov rax, 0xffffffff; // call function
+ sub rsp, 128;
+ call rax;
+
+ mov rsi, r15;
+ add rsp, 128;
+
+#else
+ mov edx, ecx; // second parameter = parm
+ mov ecx, 0xFFFFFFFF; // first parameter= context
+ mov r8, rdi; // third parameter = parm
+ mov r9, rax; // fourth parameter = parm
+ mov edi, 0xffffffff; // call function
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+#endif
+
+#else
+SAVE_STACK
+ mov edx, 0xFFFFFFFF;
+ push eax; // push parameter
+ push edi; // push parameter
+ push ecx; // push parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ add esp, 16;
+RESTORE_STACK
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void _asm_generic3parm_end(void) {}
+
+
+__declspec(naked) void _asm_generic3parm_retd(void)
+{
+ __asm {
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ mov r15, rsi;
+ mov rdx, rdi; // third parameter = parm
+ mov rdi, 0xFFFFFFFF; // first parameter= context
+ mov rsi, ecx; // second parameter = parm
+ mov rcx, rax; // fourth parameter = parm
+ mov rax, 0xffffffff; // call function
+ sub rsp, 128;
+ call rax;
+ add rsp, 128;
+ mov rsi, r15;
+ mov rax, r15;
+ movq [r15], xmm0;
+ add rsi, 8;
+#else
+ mov edx, ecx; // second parameter = parm
+ mov ecx, 0xFFFFFFFF; // first parameter= context
+ mov r8, rdi; // third parameter = parm
+ mov r9, rax; // fourth parameter = parm
+ mov edi, 0xffffffff; // call function
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+ movq [rsi], xmm0;
+ mov rax, rsi;
+ add rsi, 8;
+#endif
+#else
+SAVE_STACK
+ mov edx, 0xFFFFFFFF;
+ push eax; // push parameter
+ push edi; // push parameter
+ push ecx; // push parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+ add esp, 16;
+RESTORE_STACK
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void _asm_generic3parm_retd_end(void) {}
+
+
+__declspec(naked) void _asm_generic2parm(void) // this prob neds to be fixed for ppc
+{
+ __asm {
+#ifdef TARGET_X64
+
+#ifdef AMD64ABI
+ mov r15, rsi;
+ mov esi, edi; // second parameter = parm
+ mov edi, 0xFFFFFFFF; // first parameter= context
+ mov rdx, rax; // third parameter = parm
+ mov rcx, 0xffffffff; // call function
+ sub rsp, 128;
+ call rcx;
+ mov rsi, r15;
+ add rsp, 128;
+#else
+ mov ecx, 0xFFFFFFFF; // first parameter= context
+ mov edx, edi; // second parameter = parm
+ mov r8, rax; // third parameter = parm
+ mov edi, 0xffffffff; // call function
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+#endif
+#else
+SAVE_STACK
+ mov edx, 0xFFFFFFFF;
+ sub esp, 4; // keep stack aligned
+ push eax; // push parameter
+ push edi; // push parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ add esp, 16;
+RESTORE_STACK
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void _asm_generic2parm_end(void) {}
+
+
+__declspec(naked) void _asm_generic2parm_retd(void)
+{
+ __asm {
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ mov r15, rsi;
+ mov rsi, rdi; // second parameter = parm
+ mov rdi, 0xFFFFFFFF; // first parameter= context
+ mov rdx, rax; // third parameter = parm
+ mov rcx, 0xffffffff; // call function
+ sub rsp, 128;
+ call rcx;
+ mov rsi, r15;
+ add rsp, 128;
+ movq [r15], xmm0;
+ mov rax, r15;
+ add rsi, 8;
+#else
+ mov ecx, 0xFFFFFFFF; // first parameter= context
+ mov edx, edi; // second parameter = parm
+ mov r8, rax; // third parameter = parm
+ mov edi, 0xffffffff; // call function
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+ movq [rsi], xmm0;
+ mov rax, rsi;
+ add rsi, 8;
+#endif
+#else
+SAVE_STACK
+ mov edx, 0xFFFFFFFF;
+ push eax; // push parameter
+ push edi; // push parameter
+ push ecx; // push parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+ add esp, 16;
+RESTORE_STACK
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void _asm_generic2parm_retd_end(void) {}
+
+
+
+
+
+__declspec(naked) void _asm_generic1parm(void) // this prob neds to be fixed for ppc
+{
+ __asm {
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ mov rdi, 0xFFFFFFFF; // first parameter= context
+ mov r15, rsi;
+ mov rsi, eax; // second parameter = parm
+ sub rsp, 128;
+ mov rcx, 0xffffffff; // call function
+ call rcx;
+ mov rsi, r15;
+ add rsp, 128;
+#else
+ mov ecx, 0xFFFFFFFF; // first parameter= context
+ mov edx, eax; // second parameter = parm
+ mov edi, 0xffffffff; // call function
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+#endif
+#else
+SAVE_STACK
+ mov edx, 0xFFFFFFFF;
+ sub esp, 8; // keep stack aligned
+ push eax; // push parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ add esp, 16;
+RESTORE_STACK
+#endif
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void _asm_generic1parm_end(void) {}
+
+
+__declspec(naked) void _asm_generic1parm_retd(void) // 1 parameter returning double
+{
+ __asm {
+#ifdef TARGET_X64
+#ifdef AMD64ABI
+ mov r15, rsi;
+ mov rdi, 0xFFFFFFFF; // first parameter= context
+ mov rsi, rax; // second parameter = parm
+ mov rcx, 0xffffffff; // call function
+ sub rsp, 128;
+ call rcx;
+ mov rsi, r15;
+ add rsp, 128;
+ movq [r15], xmm0;
+ mov rax, r15;
+ add rsi, 8;
+#else
+ mov ecx, 0xFFFFFFFF; // first parameter= context
+ mov edx, eax; // second parameter = parm
+ mov edi, 0xffffffff; // call function
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+ movq [rsi], xmm0;
+ mov rax, rsi;
+ add rsi, 8;
+#endif
+#else
+SAVE_STACK
+ mov edx, 0xFFFFFFFF;
+ sub esp, 8; // keep stack aligned
+ push eax; // push parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ mov eax, esi;
+ fstp EEL_ASM_TYPE [esi];
+ add esi, EEL_F_SIZE;
+ add esp, 16;
+RESTORE_STACK
+#endif
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+__declspec(naked) void _asm_generic1parm_retd_end(void) {}
+
+
+
+
+
+// this gets its own stub because it's pretty crucial for performance :/
+
+__declspec(naked) void _asm_megabuf(void)
+{
+ __asm {
+SAVE_STACK
+
+#ifdef TARGET_X64
+
+
+#ifdef AMD64ABI
+
+ mov r15, rsi;
+ mov rdi, 0xFFFFFFFF; // first parameter = context pointer
+ fld EEL_ASM_TYPE [eax];
+ mov rdx, 0xFFFFFFFF;
+ fadd EEL_ASM_TYPE [rdx];
+ fistp dword ptr [r15];
+ xor rsi, rsi;
+ mov esi, dword ptr [r15]; // r15 = esi (from above)
+ mov edx, 0xffffffff;
+ sub rsp, 128;
+ call edx;
+ mov rsi, r15;
+ add rsp, 128;
+ and rax, rax;
+ jnz label_33;
+ mov rax, r15;
+ mov qword ptr [esi], 0;
+ add rsi, EEL_F_SIZE;
+label_33:
+
+
+#else
+ mov ecx, 0xFFFFFFFF; // first parameter = context pointer
+ fld EEL_ASM_TYPE [eax];
+ mov edx, 0xFFFFFFFF;
+ fadd EEL_ASM_TYPE [rdx];
+ fistp dword ptr [esi];
+ xor rdx, rdx;
+ mov edx, dword ptr [esi];
+ mov edi, 0xffffffff;
+ sub rsp, 128;
+ call edi;
+ add rsp, 128;
+ and rax, rax;
+ jnz label_34;
+ mov rax, rsi;
+ mov qword ptr [esi], 0;
+ add esi, EEL_F_SIZE;
+label_34:
+
+#endif
+
+
+#else
+ mov edx, 0xFFFFFFFF;
+ fld EEL_ASM_TYPE [eax];
+#if EEL_F_SIZE == 8
+_emit 0xDC; // fadd qword ptr [0xffffffff]
+_emit 0x05;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#else
+_emit 0xD8; // fadd dword ptr [0xffffffff]
+_emit 0x05;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+_emit 0xFF;
+#endif
+ fistp dword ptr [esi];
+ sub esp, 8; // keep stack aligned
+ push dword ptr [esi]; // parameter
+ push edx; // push context pointer
+ mov edi, 0xffffffff;
+ call edi;
+ add esp, 16;
+ and eax, eax;
+ jnz label_35;
+ mov eax, esi;
+ mov dword ptr [esi], 0;
+#if EEL_F_SIZE == 8
+ mov dword ptr [esi+4], 0;
+#endif
+ add esi, EEL_F_SIZE;
+label_35:
+
+
+
+#endif
+
+RESTORE_STACK
+
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+
+__declspec(naked) void _asm_megabuf_end(void) {}
+
+
+#ifdef TARGET_X64
+__declspec(naked) void win64_callcode()
+{
+ __asm {
+#ifdef AMD64ABI
+ mov eax, edi;
+#else
+ mov eax, ecx;
+#endif
+
+ push rbx;
+ push rbp;
+#ifndef AMD64ABI
+ push rdi;
+ push rsi;
+ push r12;
+ push r13;
+#endif
+ push r14; // on AMD64ABI, we'll use r14/r15 to save edi/esi
+ push r15;
+ call eax;
+ pop r15;
+ pop r14;
+#ifndef AMD64ABI
+ pop r13;
+ pop r12;
+ pop rsi;
+ pop rdi;
+ fclex;
+#endif
+ pop rbp;
+ pop rbx;
+ ret;
+_emit 0x89;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+_emit 0x90;
+ }
+}
+
+#endif
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-addfuncs.h b/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-addfuncs.h
new file mode 100644
index 00000000..e653e0a1
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-addfuncs.h
@@ -0,0 +1,74 @@
+/*
+ Nullsoft Expression Evaluator Library (NS-EEL)
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ ns-eel-addfuncs.h: defines macros useful for adding functions to the compiler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __NS_EEL_ADDFUNCS_H__
+#define __NS_EEL_ADDFUNCS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _compileContext;
+typedef void (*NSEEL_PPPROC)(void *data, int data_size, struct _compileContext *userfunc_data);
+
+void NSEEL_PProc_RAM(void *data, int data_size, struct _compileContext *ctx);
+void NSEEL_PProc_THIS(void *data, int data_size, struct _compileContext *ctx);
+
+
+void _asm_generic3parm(void); // 3 double * parms, returning double *
+void _asm_generic3parm_end(void);
+void _asm_generic3parm_retd(void); // 3 double * parms, returning double
+void _asm_generic3parm_retd_end(void);
+void _asm_generic2parm(void); // 2 double * parms, returning double *
+void _asm_generic2parm_end(void);
+void _asm_generic2parm_retd(void); // 2 double * parms, returning double
+void _asm_generic2parm_retd_end(void);
+void _asm_generic1parm(void); // 1 double * parms, returning double *
+void _asm_generic1parm_end(void);
+void _asm_generic1parm_retd(void); // 1 double * parms, returning double
+void _asm_generic1parm_retd_end(void);
+
+void _asm_megabuf(void);
+void _asm_megabuf_end(void);
+
+
+
+#if EEL_F_SIZE == 4
+#define EEL_F_SSTR "4"
+#define EEL_F_SUFFIX "s"
+#else
+#define EEL_F_SSTR "8"
+#define EEL_F_SUFFIX "l"
+#endif
+
+#ifdef _MSC_VER
+#define NSEEL_CGEN_CALL __cdecl
+#else
+#define NSEEL_CGEN_CALL
+#endif
+
+#ifdef __cplusplus
+};
+
+#endif
+#endif//__NS_EEL_ADDFUNCS_H__
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-int.h b/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-int.h
new file mode 100644
index 00000000..3718604a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel-int.h
@@ -0,0 +1,227 @@
+/*
+ Nullsoft Expression Evaluator Library (NS-EEL)
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ ns-eel-int.h: internal code definition header.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __NS_EELINT_H__
+#define __NS_EELINT_H__
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include "../wdltypes.h"
+#endif
+
+#include "ns-eel.h"
+#include "ns-eel-addfuncs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FN_ASSIGN 0
+#define FN_MULTIPLY 1
+#define FN_DIVIDE 2
+#define FN_MODULO 3
+#define FN_ADD 4
+#define FN_SUB 5
+#define FN_AND 6
+#define FN_OR 7
+#define FN_UMINUS 8
+#define FN_UPLUS 9
+
+#define MATH_SIMPLE 0
+#define MATH_FN 1
+
+#define YYSTYPE INT_PTR
+
+#define NSEEL_CLOSEFACTOR 0.00001
+
+typedef struct
+{
+ int srcByteCount;
+ int destByteCount;
+} lineRecItem;
+
+typedef struct _compileContext
+{
+ EEL_F **varTable_Values;
+ char **varTable_Names;
+ int varTable_numBlocks;
+
+ int errVar;
+ int colCount;
+ INT_PTR result;
+ char last_error_string[256];
+ YYSTYPE yylval;
+ int yychar; /* the lookahead symbol */
+ int yynerrs; /* number of parse errors so far */
+ char yytext[256];
+ char lastVar[256];
+
+ char *llsave[16]; /* Look ahead buffer */
+ char llbuf[100]; /* work buffer */
+ char *llp1;// = &llbuf[0]; /* pointer to next avail. in token */
+ char *llp2;// = &llbuf[0]; /* pointer to end of lookahead */
+ char *llend;// = &llbuf[0]; /* pointer to end of token */
+ char *llebuf;// = &llbuf[sizeof llbuf];
+ int lleof;
+ int yyline;// = 0;
+
+ void *tmpblocks_head,*blocks_head;
+ int computTableTop; // make it abort on potential overflow =)
+ int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
+
+ lineRecItem *compileLineRecs;
+ int compileLineRecs_size;
+ int compileLineRecs_alloc;
+
+ void *ram_blocks; // this needs to be immediately followed by
+ int ram_needfree;
+
+ void *gram_blocks;
+
+ void *caller_this;
+}
+compileContext;
+
+#define NSEEL_VARS_PER_BLOCK 64
+
+typedef struct {
+ const char *name;
+ void *afunc;
+ void *func_e;
+ int nParams;
+ void *replptrs[4];
+ NSEEL_PPPROC pProc;
+} functionType;
+
+
+extern functionType *nseel_getFunctionFromTable(int idx);
+
+INT_PTR nseel_createCompiledValue(compileContext *ctx, EEL_F value, EEL_F *addrValue);
+INT_PTR nseel_createCompiledFunction1(compileContext *ctx, int fntype, INT_PTR fn, INT_PTR code);
+INT_PTR nseel_createCompiledFunction2(compileContext *ctx, int fntype, INT_PTR fn, INT_PTR code1, INT_PTR code2);
+INT_PTR nseel_createCompiledFunction3(compileContext *ctx, int fntype, INT_PTR fn, INT_PTR code1, INT_PTR code2, INT_PTR code3);
+
+extern EEL_F nseel_globalregs[100];
+
+void nseel_resetVars(compileContext *ctx);
+EEL_F *nseel_getVarPtr(compileContext *ctx, char *varName);
+EEL_F *nseel_registerVar(compileContext *ctx, char *varName);
+
+INT_PTR *EEL_GLUE_set_immediate(void *_p, void *newv);
+
+// other shat
+
+
+
+INT_PTR nseel_setVar(compileContext *ctx, INT_PTR varNum);
+INT_PTR nseel_getVar(compileContext *ctx, INT_PTR varNum);
+void *nseel_compileExpression(compileContext *ctx, char *txt);
+
+#define VALUE 258
+#define IDENTIFIER 259
+#define FUNCTION1 260
+#define FUNCTION2 261
+#define FUNCTION3 262
+#define UMINUS 263
+#define UPLUS 264
+
+INT_PTR nseel_translate(compileContext *ctx, int type);
+void nseel_count(compileContext *ctx);
+void nseel_setLastVar(compileContext *ctx);
+INT_PTR nseel_lookup(compileContext *ctx, int *typeOfObject);
+int nseel_yyerror(compileContext *ctx);
+int nseel_yylex(compileContext *ctx, char **exp);
+int nseel_yyparse(compileContext *ctx, char *exp);
+void nseel_llinit(compileContext *ctx);
+int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz);
+
+struct lextab {
+ int llendst; /* Last state number */
+ char *lldefault; /* Default state table */
+ char *llnext; /* Next state table */
+ char *llcheck; /* Check table */
+ int *llbase; /* Base table */
+ int llnxtmax; /* Last in next table */
+ int (*llmove)(); /* Move between states */
+ char *llfinal; /* Final state descriptions */
+ int (*llactr)(); /* Action routine */
+ int *lllook; /* Look ahead vector if != NULL */
+ char *llign; /* Ignore char vec if != NULL */
+ char *llbrk; /* Break char vec if != NULL */
+ char *llill; /* Illegal char vec if != NULL */
+};
+extern struct lextab nseel_lextab;
+
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F ***blocks, int w);
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, int w);
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F ***blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr);
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(EEL_F ***blocks, EEL_F *which);
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F ***blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr);
+
+
+
+#ifndef max
+#define max(x,y) ((x)<(y)?(y):(x))
+#define min(x,y) ((x)<(y)?(x):(y))
+#endif
+
+
+
+#ifdef __ppc__
+
+ #define EEL_F2int(x) ((int)(x))
+
+#elif defined (_WIN64)
+
+ // todo: AMD64 version?
+ #define EEL_F2int(x) ((int)(x))
+
+#elif defined(_MSC_VER)
+
+static __inline int EEL_F2int(EEL_F d)
+{
+ int tmp;
+ __asm {
+ fld d
+ fistp tmp
+ }
+ return tmp;
+}
+
+#else
+
+static inline int EEL_F2int(EEL_F d)
+{
+ int tmp;
+ __asm__ __volatile__ ("fistpl %0" : "=m" (tmp) : "t" (d) : "st") ;
+ return tmp;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif//__NS_EELINT_H__
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel.h b/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel.h
new file mode 100644
index 00000000..cb561377
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/ns-eel.h
@@ -0,0 +1,155 @@
+/*
+ Nullsoft Expression Evaluator Library (NS-EEL)
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ ns-eel.h: main application interface header
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef __NS_EEL_H__
+#define __NS_EEL_H__
+
+// put standard includes here
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef _MSC_VER
+#define strcasecmp stricmp
+#define strncasecmp _strnicmp
+#endif
+
+#ifndef EEL_F_SIZE
+#define EEL_F_SIZE 8
+#endif
+
+#if EEL_F_SIZE == 4
+typedef float EEL_F;
+#else
+typedef double EEL_F;
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// host should implement these (can be empty stub functions if no VM will execute code in multiple threads at once)
+
+ // implement if you will be running the code in same VM from multiple threads,
+ // or VMs that have the same GRAM pointer from different threads, or multiple
+ // VMs that have a NULL GRAM pointer from multiple threads.
+ // if you give each VM it's own unique GRAM and only run each VM in one thread, then you can leave it blank.
+
+ // or if you're daring....
+
+void NSEEL_HOSTSTUB_EnterMutex();
+void NSEEL_HOSTSTUB_LeaveMutex();
+
+
+int NSEEL_init(); // returns 0 on success. clears any added functions as well
+
+#define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0,0)
+#define NSEEL_addfunctionex(name,nparms,code,len,pproc,fptr) NSEEL_addfunctionex2((name),(nparms),(code),(len),(pproc),(fptr),0)
+void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, void *pproc, void *fptr, void *fptr2);
+
+void NSEEL_quit();
+
+int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles
+EEL_F *NSEEL_getglobalregs();
+
+typedef void *NSEEL_VMCTX;
+typedef void *NSEEL_CODEHANDLE;
+
+NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle
+void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well
+
+void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx); // return false from func to stop
+void NSEEL_VM_resetvars(NSEEL_VMCTX ctx); // clears all vars to 0.0.
+
+EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation)
+
+void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used
+void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory
+int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx); // want NSEEL_VM_freeRAMIfCodeRequested?
+
+// if you set this, it uses a local GMEM context.
+// Must be set before compilation.
+// void *p=NULL;
+// NSEEL_VM_SetGRAM(ctx,&p);
+// .. do stuff
+// NSEEL_VM_FreeGRAM(&p);
+void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram);
+void NSEEL_VM_FreeGRAM(void **ufd); // frees a gmem context.
+void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr);
+
+
+ // note that you shouldnt pass a C string directly, since it may need to
+ // fudge with the string during the compilation (it will always restore it to the
+ // original value though).
+#ifdef __cplusplus
+NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, char *code, int lineoffs=0);
+#else
+NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, char *code, int lineoffs);
+#endif
+
+char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx);
+void NSEEL_code_execute(NSEEL_CODEHANDLE code);
+void NSEEL_code_free(NSEEL_CODEHANDLE code);
+int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes
+
+
+// global memory control/view
+extern unsigned int NSEEL_RAM_limitmem; // if nonzero, memory limit for user data, in bytes
+extern unsigned int NSEEL_RAM_memused;
+extern int NSEEL_RAM_memused_errors;
+
+
+
+// configuration:
+
+#define NSEEL_MAX_VARIABLE_NAMELEN 16
+// define this to override the max variable length (default is 16 bytes)
+
+//#define NSEEL_MAX_TEMPSPACE_ENTRIES 2048
+// define this to override the maximum working space in 8 byte units.
+// 2048 is the default, and is way more than enough for most applications
+// but in theory you might be able to come up with an expression big enough? maybe?
+
+
+// maximum loop length
+#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN 1048576 // scary, we can do a million entries. probably will never want to, though.
+#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN_STR "1048576"
+
+
+
+// when a VM ctx doesn't have a GRAM context set, make the global one this big
+#define NSEEL_SHARED_GRAM_SIZE (1<<20)
+
+// 128*65536 = ~8million entries. (64MB RAM used)
+#define NSEEL_RAM_BLOCKS 128
+#define NSEEL_RAM_ITEMSPERBLOCK 65536
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif//__NS_EEL_H__
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-caltab.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-caltab.c
new file mode 100644
index 00000000..1d8a6d32
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-caltab.c
@@ -0,0 +1,553 @@
+/*
+ Expression Evaluator Library (NS-EEL) v2
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-caltab.c
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "ns-eel-int.h"
+
+#define VALUE 258
+#define IDENTIFIER 259
+#define FUNCTION1 260
+#define FUNCTION2 261
+#define FUNCTION3 262
+#define UMINUS 263
+#define UPLUS 264
+
+#define YYERROR(x) nseel_yyerror(ctx)
+
+#define YYFINAL 51
+#define YYFLAG -32768
+#define YYNTBASE 21
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 264 ? yytranslate[x] : 26)
+
+static const char yytranslate[] = { 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 14, 9, 2, 18,
+ 19, 12, 10, 20, 11, 2, 13, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 17, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 8, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 15, 16
+};
+
+
+static const short yyr1[] = { 0,
+ 21, 21, 22, 23, 23, 23, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 25, 25, 25
+};
+
+static const short yyr2[] = { 0,
+ 1, 3, 1, 1, 1, 3, 1, 3, 3, 3,
+ 3, 3, 3, 3, 2, 2, 1, 4, 6, 8
+};
+
+static const short yydefact[] = { 0,
+ 3, 4, 0, 0, 0, 0, 0, 0, 5, 7,
+ 1, 17, 0, 0, 0, 0, 4, 16, 15, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 6, 14, 13, 11, 12, 8, 9, 10, 18,
+ 0, 0, 0, 0, 19, 0, 0, 20, 0, 0,
+ 0
+};
+
+static const short yydefgoto[] = { 49,
+ 9, 10, 11, 12
+};
+
+static const short yypact[] = { 19,
+-32768, -11, -7, -5, -4, 38, 38, 38,-32768,-32768,
+ 136,-32768, 38, 38, 38, 38,-32768,-32768,-32768, 88,
+ 38, 38, 38, 38, 38, 38, 38, 136, 100, 49,
+ 62,-32768, 41, 54, -9, -9,-32768,-32768,-32768,-32768,
+ 38, 38, 112, 75,-32768, 38, 124,-32768, 12, 27,
+-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768,-32768, -6,-32768
+};
+
+
+#define YYLAST 150
+
+
+static const short yytable[] = { 18,
+ 19, 20, 25, 26, 27, 13, 28, 29, 30, 31,
+ 14, 50, 15, 16, 33, 34, 35, 36, 37, 38,
+ 39, 1, 2, 3, 4, 5, 51, 0, 6, 7,
+ 0, 0, 0, 0, 43, 44, 8, 0, 0, 47,
+ 1, 17, 3, 4, 5, 0, 0, 6, 7, 22,
+ 23, 24, 25, 26, 27, 8, 21, 22, 23, 24,
+ 25, 26, 27, 23, 24, 25, 26, 27, 41, 21,
+ 22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
+ 0, 42, 21, 22, 23, 24, 25, 26, 27, 0,
+ 0, 0, 0, 0, 46, 21, 22, 23, 24, 25,
+ 26, 27, 0, 0, 0, 0, 32, 21, 22, 23,
+ 24, 25, 26, 27, 0, 0, 0, 0, 40, 21,
+ 22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
+ 45, 21, 22, 23, 24, 25, 26, 27, 0, 0,
+ 0, 0, 48, 21, 22, 23, 24, 25, 26, 27
+};
+
+static const short yycheck[] = { 6,
+ 7, 8, 12, 13, 14, 17, 13, 14, 15, 16,
+ 18, 0, 18, 18, 21, 22, 23, 24, 25, 26,
+ 27, 3, 4, 5, 6, 7, 0, -1, 10, 11,
+ -1, -1, -1, -1, 41, 42, 18, -1, -1, 46,
+ 3, 4, 5, 6, 7, -1, -1, 10, 11, 9,
+ 10, 11, 12, 13, 14, 18, 8, 9, 10, 11,
+ 12, 13, 14, 10, 11, 12, 13, 14, 20, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
+ -1, 20, 8, 9, 10, 11, 12, 13, 14, -1,
+ -1, -1, -1, -1, 20, 8, 9, 10, 11, 12,
+ 13, 14, -1, -1, -1, -1, 19, 8, 9, 10,
+ 11, 12, 13, 14, -1, -1, -1, -1, 19, 8,
+ 9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
+ 19, 8, 9, 10, 11, 12, 13, 14, -1, -1,
+ -1, -1, 19, 8, 9, 10, 11, 12, 13, 14
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (ctx->yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#define YYLEX nseel_yylex(ctx,&exp)
+
+/* If nonreentrant, generate the variables here */
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#define YYINITDEPTH 5000
+#define YYMAXDEPTH 5000
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+#define __yy_bcopy(from,to,count) memcpy(to,from,(count)>0?(count):0)
+
+//#ln 131 "bison.simple"
+int nseel_yyparse(compileContext *ctx, char *exp)
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+ int yystacksize = YYINITDEPTH;
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+ ctx->yylval = 0;
+ yystate = 0;
+ yyerrstatus = 0;
+ ctx->yynerrs = 0;
+ ctx->yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack. */
+
+ yyssp = yyss - 1;
+ yyvsp = yyvs;
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Give user a chance to reallocate the stack */
+ /* Use copies of these so that the &'s don't force the real ones into memory. */
+// YYSTYPE *yyvs1 = yyvs;
+ // short *yyss1 = yyss;
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ YYERROR("internal error: parser stack overflow");
+ return 2;
+ }
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+
+
+ if (yyssp >= yyss + yystacksize - 1) YYABORT;
+ }
+
+
+// yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (ctx->yychar == YYEMPTY)
+ {
+// yyStackSize = yyssp - (yyss - 1);
+ ctx->yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (ctx->yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ ctx->yychar = YYEOF; /* Don't call YYLEX any more */
+
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(ctx->yychar);
+
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+
+ /* Discard the token being shifted unless it is eof. */
+ if (ctx->yychar != YYEOF)
+ ctx->yychar = YYEMPTY;
+
+ *++yyvsp = ctx->yylval;
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+
+ switch (yyn) {
+
+case 1:
+//#ln 32 "cal.y"
+{ yyval = yyvsp[0]; ctx->result = yyvsp[0]; ;
+ break;}
+case 2:
+//#ln 34 "cal.y"
+{ {
+ YYSTYPE i = nseel_setVar(ctx,yyvsp[-2]);
+ YYSTYPE v=nseel_getVar(ctx,i);
+
+ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_ASSIGN, v, yyvsp[0]);
+ ctx->result = yyval;
+ }
+ ;
+ break;}
+case 3:
+//#ln 50 "cal.y"
+{ yyval = yyvsp[0] ;
+ break;}
+case 4:
+//#ln 55 "cal.y"
+{ yyval = nseel_getVar(ctx,yyvsp[0]);;
+ break;}
+case 5:
+//#ln 57 "cal.y"
+{ yyval = yyvsp[0];;
+ break;}
+case 6:
+//#ln 59 "cal.y"
+{ yyval = yyvsp[-1];;
+ break;}
+case 7:
+//#ln 64 "cal.y"
+{ yyval = yyvsp[0]; ;
+ break;}
+case 8:
+//#ln 66 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_MULTIPLY, yyvsp[-2], yyvsp[0]);
+ break;}
+case 9:
+//#ln 72 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_DIVIDE, yyvsp[-2], yyvsp[0]);
+ break;}
+case 10:
+//#ln 78 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_MODULO, yyvsp[-2], yyvsp[0]);
+ break;}
+case 11:
+//#ln 84 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_ADD, yyvsp[-2], yyvsp[0]);
+ break;}
+case 12:
+//#ln 90 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_SUB, yyvsp[-2], yyvsp[0]);
+ break;}
+case 13:
+//#ln 96 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_AND, yyvsp[-2], yyvsp[0]);
+ break;}
+case 14:
+//#ln 102 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_OR, yyvsp[-2], yyvsp[0]);
+ break;}
+case 15:
+//#ln 108 "cal.y"
+{ yyval = nseel_createCompiledFunction1(ctx,MATH_SIMPLE, FN_UMINUS, yyvsp[0]);
+ break;}
+case 16:
+//#ln 114 "cal.y"
+{ yyval = nseel_createCompiledFunction1(ctx,MATH_SIMPLE, FN_UPLUS, yyvsp[0]);
+ break;}
+case 17:
+//#ln 120 "cal.y"
+{ yyval = yyvsp[0];
+ break;}
+case 18:
+//#ln 125 "cal.y"
+{ yyval = nseel_createCompiledFunction1(ctx,MATH_FN, yyvsp[-3], yyvsp[-1]);
+ break;}
+case 19:
+//#ln 131 "cal.y"
+{ yyval = nseel_createCompiledFunction2(ctx,MATH_FN, yyvsp[-5], yyvsp[-3], yyvsp[-1]);
+ break;}
+case 20:
+//#ln 137 "cal.y"
+{ yyval = nseel_createCompiledFunction3(ctx,MATH_FN, yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]);
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+//#ln 362 "bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+ *++yyvsp = yyval;
+
+
+ /* Now "shift" the result of the reduction.
+ Determine what state that goes to,
+ based on the state we popped back to
+ and the rule number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++ctx->yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+#error this should not compile
+ msg = (char *) xmalloc(size + 15);
+ strcpy(msg, "syntax error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ YYERROR(msg);
+ free(msg);
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ YYERROR("syntax error");
+ }
+
+//yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (ctx->yychar == YYEOF) YYABORT;
+
+ ctx->yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = ctx->yylval;
+
+ yystate = yyn;
+ goto yynewstate;
+}
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-cfunc.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-cfunc.c
new file mode 100644
index 00000000..57cb7c05
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-cfunc.c
@@ -0,0 +1,131 @@
+/*
+ Expression Evaluator Library (NS-EEL) v2
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-cfunc.c: assembly/C implementation of operator/function templates
+ This file should be ideally compiled with optimizations towards "minimize size"
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "ns-eel-int.h"
+#include <math.h>
+#include <stdio.h>
+
+
+
+// these are used by our assembly code
+
+
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0dfUL /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+static unsigned int genrand_int32(void)
+{
+
+ unsigned int y;
+ static unsigned int mag01[2]={0x0UL, MATRIX_A};
+ /* mag01[x] = x * MATRIX_A for x=0,1 */
+
+ static unsigned int mt[N]; /* the array for the state vector */
+ static int mti; /* mti==N+1 means mt[N] is not initialized */
+
+
+ if (!mti)
+ {
+ unsigned int s=0x4141f00d;
+ mt[0]= s & 0xffffffffUL;
+ for (mti=1; mti<N; mti++)
+ {
+ mt[mti] =
+ (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+ /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+ /* In the previous versions, MSBs of the seed affect */
+ /* only MSBs of the array mt[]. */
+ /* 2002/01/09 modified by Makoto Matsumoto */
+ mt[mti] &= 0xffffffffUL;
+ /* for >32 bit machines */
+ }
+ }
+
+ if (mti >= N) { /* generate N words at one time */
+ int kk;
+
+ for (kk=0;kk<N-M;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ for (;kk<N-1;kk++) {
+ y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+ mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+ }
+ y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+ mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+ mti = 0;
+ }
+
+ y = mt[mti++];
+
+ /* Tempering */
+ y ^= (y >> 11);
+ y ^= (y << 7) & 0x9d2c5680UL;
+ y ^= (y << 15) & 0xefc60000UL;
+ y ^= (y >> 18);
+
+ return y;
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------
+EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F *f)
+{
+ EEL_F x=floor(*f);
+ if (x < 1.0) x=1.0;
+
+#ifdef NSEEL_EEL1_COMPAT_MODE
+ return (EEL_F)(genrand_int32()%(int)x);
+#else
+ return (EEL_F) (genrand_int32()*(1.0/(double)0xFFFFFFFF)*x);
+#endif
+// return (EEL_F)(rand()%EEL_F2int(x));
+}
+
+//---------------------------------------------------------------------------------------------------------------
+
+
+
+#ifdef __ppc__
+#include "asm-nseel-ppc-gcc.c"
+#else
+ #ifdef _MSC_VER
+ #ifdef _WIN64
+ //nasm
+ #else
+ #include "asm-nseel-x86-msvc.c"
+ #endif
+ #elif !defined(__LP64__)
+ #include "asm-nseel-x86-gcc.c"
+ #endif
+#endif
+
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-compiler.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-compiler.c
new file mode 100644
index 00000000..da222179
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-compiler.c
@@ -0,0 +1,1791 @@
+/*
+ Expression Evaluator Library (NS-EEL) v2
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-compiler.c
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+// for VirtualProtect
+
+#include "ns-eel-int.h"
+
+
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#ifndef _WIN64
+ #ifndef __ppc__
+ #include <float.h>
+ #endif
+#endif
+
+#ifdef __APPLE__
+ #ifdef __LP64__
+ #define EEL_USE_MPROTECT
+ #endif
+#endif
+
+#ifdef EEL_USE_MPROTECT
+#include <sys/mman.h>
+#include <stdint.h>
+#include <unistd.h>
+#endif
+
+#ifdef NSEEL_EEL1_COMPAT_MODE
+
+#ifndef EEL_NO_CHANGE_FPFLAGS
+#define EEL_NO_CHANGE_FPFLAGS
+#endif
+
+#endif
+
+#ifndef _WIN64
+#if !defined(_RC_CHOP) && !defined(EEL_NO_CHANGE_FPFLAGS)
+
+#include <fpu_control.h>
+#define _RC_CHOP _FPU_RC_ZERO
+#define _MCW_RC _FPU_RC_ZERO
+static unsigned int _controlfp(unsigned int val, unsigned int mask)
+{
+ unsigned int ret;
+ _FPU_GETCW(ret);
+ if (mask)
+ {
+ ret&=~mask;
+ ret|=val;
+ _FPU_SETCW(ret);
+ }
+ return ret;
+}
+
+#endif
+#endif
+
+
+#ifdef __ppc__
+
+#define GLUE_MOV_EAX_DIRECTVALUE_SIZE 8
+static void GLUE_MOV_EAX_DIRECTVALUE_GEN(void *b, INT_PTR v)
+{
+ unsigned int uv=(unsigned int)v;
+ unsigned short *p=(unsigned short *)b;
+
+ *p++ = 0x3C60; // addis r3, r0, hw
+ *p++ = (uv>>16)&0xffff;
+ *p++ = 0x6063; // ori r3, r3, lw
+ *p++ = uv&0xffff;
+}
+
+
+// mflr r5
+// stwu r5, -4(r1)
+const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFFC };
+
+// lwz r5, 0(r1)
+// addi r1, r1, 4
+// mtlr r5
+const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210004, 0x7CA803A6 };
+#define GLUE_FUNC_ENTER_SIZE sizeof(GLUE_FUNC_ENTER)
+#define GLUE_FUNC_LEAVE_SIZE sizeof(GLUE_FUNC_LEAVE)
+
+const static unsigned int GLUE_RET[]={0x4E800020}; // blr
+
+const static unsigned int GLUE_MOV_ESI_EDI=0x7E308B78; // mr r16, r17
+
+static int GLUE_RESET_ESI(char *out, void *ptr)
+{
+ if (out) memcpy(out,&GLUE_MOV_ESI_EDI,sizeof(GLUE_MOV_ESI_EDI));
+ return sizeof(GLUE_MOV_ESI_EDI);
+
+}
+
+
+
+// stwu r3, -4(r1)
+const static unsigned int GLUE_PUSH_EAX[1]={ 0x9461FFFC};
+
+// lwz r14, 0(r1)
+// addi r1, r1, 4
+const static unsigned int GLUE_POP_EBX[2]={ 0x81C10000, 0x38210004, };
+
+// lwz r15, 0(r1)
+// addi r1, r1, 4
+const static unsigned int GLUE_POP_ECX[2]={ 0x81E10000, 0x38210004 };
+
+
+static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp)
+{
+ __asm__(
+ "stmw r14, -80(r1)\n"
+ "mtctr %0\n"
+ "mr r17, %1\n"
+ "subi r17, r17, 8\n"
+ "mflr r5\n"
+ "stw r5, -84(r1)\n"
+ "subi r1, r1, 88\n"
+ "bctrl\n"
+ "addi r1, r1, 88\n"
+ "lwz r5, -84(r1)\n"
+ "lmw r14, -80(r1)\n"
+ "mtlr r5\n"
+ ::"r" (cp), "r" (bp));
+};
+
+INT_PTR *EEL_GLUE_set_immediate(void *_p, void *newv)
+{
+// todo 64 bit ppc will take some work
+ unsigned int *p=(unsigned int *)_p;
+ while ((p[0]&0x0000FFFF) != 0x0000dead &&
+ (p[1]&0x0000FFFF) != 0x0000beef) p++;
+ p[0] = (p[0]&0xFFFF0000) | (((unsigned int)newv)>>16);
+ p[1] = (p[1]&0xFFFF0000) | (((unsigned int)newv)&0xFFFF);
+
+ return (INT_PTR*)++p;
+}
+
+
+#else
+
+//x86 specific code
+
+#define GLUE_FUNC_ENTER_SIZE 0
+#define GLUE_FUNC_LEAVE_SIZE 0
+const static unsigned int GLUE_FUNC_ENTER[1];
+const static unsigned int GLUE_FUNC_LEAVE[1];
+
+#if defined(_WIN64) || defined(__LP64__)
+#define GLUE_MOV_EAX_DIRECTVALUE_SIZE 10
+static void GLUE_MOV_EAX_DIRECTVALUE_GEN(void *b, INT_PTR v) {
+ unsigned short *bb = (unsigned short *)b;
+ *bb++ =0xB848;
+ *(INT_PTR *)bb = v;
+}
+const static unsigned char GLUE_PUSH_EAX[2]={ 0x50,0x50}; // push rax ; push rax (push twice to preserve alignment)
+const static unsigned char GLUE_POP_EBX[2]={0x5F, 0x5f}; //pop rdi ; twice
+const static unsigned char GLUE_POP_ECX[2]={0x59, 0x59 }; // pop rcx ; twice
+#else
+#define GLUE_MOV_EAX_DIRECTVALUE_SIZE 5
+static void GLUE_MOV_EAX_DIRECTVALUE_GEN(void *b, int v)
+{
+ *((unsigned char *)b) =0xB8;
+ b= ((unsigned char *)b)+1;
+ *(int *)b = v;
+}
+const static unsigned char GLUE_PUSH_EAX[4]={0x83, 0xEC, 12, 0x50}; // sub esp, 12, push eax
+const static unsigned char GLUE_POP_EBX[4]={0x5F, 0x83, 0xC4, 12}; //pop ebx, add esp, 12 // DI=5F, BX=0x5B;
+const static unsigned char GLUE_POP_ECX[4]={0x59, 0x83, 0xC4, 12}; // pop ecx, add esp, 12
+
+#endif
+
+//const static unsigned short GLUE_MOV_ESI_EDI=0xF78B;
+const static unsigned char GLUE_RET=0xC3;
+
+static int GLUE_RESET_ESI(unsigned char *out, void *ptr)
+{
+#if defined(_WIN64) || defined(__LP64__)
+ if (out)
+ {
+ *out++ = 0x48;
+ *out++ = 0xBE; // mov rsi, constant64
+ *(void **)out = ptr;
+ out+=sizeof(void *);
+ }
+ return 2+sizeof(void *);
+#else
+ if (out)
+ {
+ *out++ = 0xBE; // mov esi, constant
+ memcpy(out,&ptr,sizeof(void *));
+ out+=sizeof(void *);
+ }
+ return 1+sizeof(void *);
+#endif
+}
+
+static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp)
+{
+ #if defined(_WIN64) || defined(__LP64__)
+ extern void win64_callcode(INT_PTR code);
+ win64_callcode(cp);
+ #else // non-64 bit
+ #ifdef _MSC_VER
+ #ifndef EEL_NO_CHANGE_FPFLAGS
+ unsigned int old_v=_controlfp(0,0);
+ _controlfp(_RC_CHOP,_MCW_RC);
+ #endif
+
+ __asm
+ {
+ mov eax, cp
+ pushad
+ call eax
+ popad
+ };
+
+ #ifndef EEL_NO_CHANGE_FPFLAGS
+ _controlfp(old_v,_MCW_RC);
+ #endif
+
+#else // gcc x86
+ #ifndef EEL_NO_CHANGE_FPFLAGS
+ unsigned int old_v=_controlfp(0,0);
+ _controlfp(_RC_CHOP,_MCW_RC);
+ #endif
+ __asm__("call *%%eax"::"a" (cp): "%ecx","%edx","%esi","%edi");
+ #ifndef EEL_NO_CHANGE_FPFLAGS
+ _controlfp(old_v,_MCW_RC);
+ #endif
+ #endif //gcc x86
+ #endif // 32bit
+}
+
+INT_PTR *EEL_GLUE_set_immediate(void *_p, void *newv)
+{
+ char *p=(char*)_p;
+ while (*(INT_PTR *)p != ~(INT_PTR)0) p++;
+ *(INT_PTR *)p = (INT_PTR)newv;
+ return ((INT_PTR*)p)+1;
+}
+
+#endif
+
+
+static void *GLUE_realAddress(void *fn, void *fn_e, int *size)
+{
+#if defined(_MSC_VER) || defined(__LP64__)
+
+ unsigned char *p;
+
+#if defined(_DEBUG) && !defined(__LP64__)
+ if (*(unsigned char *)fn == 0xE9) // this means jump to the following address
+ {
+ fn = ((unsigned char *)fn) + *(int *)((char *)fn+1) + 5;
+ }
+#endif
+
+ // this may not work in debug mode
+ p=(unsigned char *)fn;
+ for (;;)
+ {
+ int a;
+ for (a=0;a<12;a++)
+ {
+ if (p[a] != (a?0x90:0x89)) break;
+ }
+ if (a>=12)
+ {
+ *size = (char *)p - (char *)fn;
+ // if (*size<0) MessageBox(NULL,"expect poof","a",0);
+ return fn;
+ }
+ p++;
+ }
+#else
+ char *p=(char *)fn_e - sizeof(GLUE_RET);
+ if (p <= (char *)fn) *size=0;
+ else
+ {
+ while (p > (char *)fn && memcmp(p,&GLUE_RET,sizeof(GLUE_RET))) p-=sizeof(GLUE_RET);
+ *size = p - (char *)fn;
+ }
+ return fn;
+#endif
+}
+
+
+
+static int nseel_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
+int *NSEEL_getstats()
+{
+ return nseel_evallib_stats;
+}
+EEL_F *NSEEL_getglobalregs()
+{
+ return nseel_globalregs;
+}
+
+// this stuff almost works
+static int findByteOffsetInSource(compileContext *ctx, int byteoffs,int *destoffs)
+{
+ int x;
+ if (!ctx->compileLineRecs || !ctx->compileLineRecs_size) return *destoffs=0;
+ if (byteoffs < ctx->compileLineRecs[0].destByteCount)
+ {
+ *destoffs=0;
+ return 1;
+ }
+ for (x = 0; x < ctx->compileLineRecs_size-1; x ++)
+ {
+ if (byteoffs >= ctx->compileLineRecs[x].destByteCount &&
+ byteoffs < ctx->compileLineRecs[x+1].destByteCount) break;
+ }
+ *destoffs=ctx->compileLineRecs[(x&&x==ctx->compileLineRecs_size-1)?x-1:x].srcByteCount;
+
+ return x+2;
+}
+
+
+static void onCompileNewLine(compileContext *ctx, int srcBytes, int destBytes)
+{
+ if (!ctx->compileLineRecs || ctx->compileLineRecs_size >= ctx->compileLineRecs_alloc)
+ {
+ ctx->compileLineRecs_alloc = ctx->compileLineRecs_size+1024;
+ ctx->compileLineRecs = (lineRecItem *)realloc(ctx->compileLineRecs,sizeof(lineRecItem)*ctx->compileLineRecs_alloc);
+ }
+ if (ctx->compileLineRecs)
+ {
+ ctx->compileLineRecs[ctx->compileLineRecs_size].srcByteCount=srcBytes;
+ ctx->compileLineRecs[ctx->compileLineRecs_size++].destByteCount=destBytes;
+ }
+}
+
+
+
+#define LLB_DSIZE (65536-64)
+typedef struct _llBlock {
+ struct _llBlock *next;
+ int sizeused;
+ char block[LLB_DSIZE];
+} llBlock;
+
+typedef struct _startPtr {
+ struct _startPtr *next;
+ void *startptr;
+} startPtr;
+
+typedef struct {
+ void *workTable;
+
+ llBlock *blocks;
+ void *code;
+ int code_stats[4];
+} codeHandleType;
+
+#ifndef NSEEL_MAX_TEMPSPACE_ENTRIES
+#define NSEEL_MAX_TEMPSPACE_ENTRIES 2048
+#endif
+
+static void *__newBlock(llBlock **start,int size);
+
+#define newTmpBlock(x) __newTmpBlock((llBlock **)&ctx->tmpblocks_head,x)
+#define newBlock(x,a) __newBlock_align(ctx,x,a)
+
+static void *__newTmpBlock(llBlock **start, int size)
+{
+ void *p=__newBlock(start,size+4);
+ if (p && size>=0) *((int *)p) = size;
+ return p;
+}
+
+static void *__newBlock_align(compileContext *ctx, int size, int align) // makes sure block is aligned to 32 byte boundary, for code
+{
+ int a1=align-1;
+ char *p=(char*)__newBlock((llBlock **)&ctx->blocks_head,size+a1);
+ return p+((align-(((INT_PTR)p)&a1))&a1);
+}
+
+static void freeBlocks(llBlock **start);
+
+#define DECL_ASMFUNC(x) \
+ void nseel_asm_##x(void); \
+ void nseel_asm_##x##_end(void); \
+
+ DECL_ASMFUNC(sin)
+ DECL_ASMFUNC(cos)
+ DECL_ASMFUNC(tan)
+ DECL_ASMFUNC(1pdd)
+ DECL_ASMFUNC(2pdd)
+ DECL_ASMFUNC(2pdds)
+ DECL_ASMFUNC(1pp)
+ DECL_ASMFUNC(2pp)
+ DECL_ASMFUNC(sqr)
+ DECL_ASMFUNC(sqrt)
+ DECL_ASMFUNC(log)
+ DECL_ASMFUNC(log10)
+ DECL_ASMFUNC(abs)
+ DECL_ASMFUNC(min)
+ DECL_ASMFUNC(max)
+ DECL_ASMFUNC(sig)
+ DECL_ASMFUNC(sign)
+ DECL_ASMFUNC(band)
+ DECL_ASMFUNC(bor)
+ DECL_ASMFUNC(bnot)
+ DECL_ASMFUNC(if)
+ DECL_ASMFUNC(repeat)
+ DECL_ASMFUNC(repeatwhile)
+ DECL_ASMFUNC(equal)
+ DECL_ASMFUNC(notequal)
+ DECL_ASMFUNC(below)
+ DECL_ASMFUNC(above)
+ DECL_ASMFUNC(beloweq)
+ DECL_ASMFUNC(aboveeq)
+ DECL_ASMFUNC(assign)
+ DECL_ASMFUNC(add)
+ DECL_ASMFUNC(sub)
+ DECL_ASMFUNC(add_op)
+ DECL_ASMFUNC(sub_op)
+ DECL_ASMFUNC(mul)
+ DECL_ASMFUNC(div)
+ DECL_ASMFUNC(mul_op)
+ DECL_ASMFUNC(div_op)
+ DECL_ASMFUNC(mod)
+ DECL_ASMFUNC(mod_op)
+ DECL_ASMFUNC(or)
+ DECL_ASMFUNC(and)
+ DECL_ASMFUNC(or_op)
+ DECL_ASMFUNC(and_op)
+ DECL_ASMFUNC(uplus)
+ DECL_ASMFUNC(uminus)
+ DECL_ASMFUNC(invsqrt)
+ DECL_ASMFUNC(exec2)
+
+static void NSEEL_PProc_GRAM(void *data, int data_size, compileContext *ctx)
+{
+ if (data_size>0) EEL_GLUE_set_immediate(data, ctx->gram_blocks);
+}
+
+
+static EEL_F g_signs[2]={1.0,-1.0};
+static EEL_F negativezeropointfive=-0.5f;
+static EEL_F onepointfive=1.5f;
+static EEL_F g_closefact = NSEEL_CLOSEFACTOR;
+static const EEL_F eel_zero=0.0, eel_one=1.0;
+
+//#if defined(_MSC_VER) && _MSC_VER >= 1400
+//static double __floor(double a) { return floor(a); }
+//#endif
+
+static double eel1band(double a, double b)
+{
+ return (fabs(a)>g_closefact && fabs(b) > g_closefact) ? 1.0 : 0.0;
+}
+static double eel1bor(double a, double b)
+{
+ return (fabs(a)>g_closefact || fabs(b) > g_closefact) ? 1.0 : 0.0;
+}
+
+static double eel1sigmoid(double x, double constraint)
+{
+ double t = (1+exp(-x * (constraint)));
+ return fabs(t)>g_closefact ? 1.0/t : 0;
+}
+
+
+EEL_F NSEEL_CGEN_CALL nseel_int_rand(EEL_F *f);
+
+static functionType fnTable1[] = {
+ { "_if", nseel_asm_if,nseel_asm_if_end, 3, {&g_closefact} },
+ { "_and", nseel_asm_band,nseel_asm_band_end, 2 } ,
+ { "_or", nseel_asm_bor,nseel_asm_bor_end, 2 } ,
+ { "loop", nseel_asm_repeat,nseel_asm_repeat_end, 2 },
+ { "while", nseel_asm_repeatwhile,nseel_asm_repeatwhile_end, 1 },
+
+#ifdef __ppc__
+ { "_not", nseel_asm_bnot,nseel_asm_bnot_end, 1, {&g_closefact,&eel_zero,&eel_one} } ,
+ { "_equal", nseel_asm_equal,nseel_asm_equal_end, 2, {&g_closefact,&eel_zero, &eel_one} },
+ { "_noteq", nseel_asm_notequal,nseel_asm_notequal_end, 2, {&g_closefact,&eel_one,&eel_zero} },
+ { "_below", nseel_asm_below,nseel_asm_below_end, 2, {&eel_zero, &eel_one} },
+ { "_above", nseel_asm_above,nseel_asm_above_end, 2, {&eel_zero, &eel_one} },
+ { "_beleq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2, {&eel_zero, &eel_one} },
+ { "_aboeq", nseel_asm_aboveeq,nseel_asm_aboveeq_end, 2, {&eel_zero, &eel_one} },
+#else
+ { "_not", nseel_asm_bnot,nseel_asm_bnot_end, 1, {&g_closefact} } ,
+ { "_equal", nseel_asm_equal,nseel_asm_equal_end, 2, {&g_closefact} },
+ { "_noteq", nseel_asm_notequal,nseel_asm_notequal_end, 2, {&g_closefact} },
+ { "_below", nseel_asm_below,nseel_asm_below_end, 2 },
+ { "_above", nseel_asm_above,nseel_asm_above_end, 2 },
+ { "_beleq", nseel_asm_beloweq,nseel_asm_beloweq_end, 2 },
+ { "_aboeq", nseel_asm_aboveeq,nseel_asm_aboveeq_end, 2 },
+#endif
+
+ { "_set",nseel_asm_assign,nseel_asm_assign_end,2},
+ { "_mod",nseel_asm_mod,nseel_asm_mod_end,2},
+ { "_mulop",nseel_asm_mul_op,nseel_asm_mul_op_end,2},
+ { "_divop",nseel_asm_div_op,nseel_asm_div_op_end,2},
+ { "_orop",nseel_asm_or_op,nseel_asm_or_op_end,2},
+ { "_andop",nseel_asm_and_op,nseel_asm_and_op_end,2},
+ { "_addop",nseel_asm_add_op,nseel_asm_add_op_end,2},
+ { "_subop",nseel_asm_sub_op,nseel_asm_sub_op_end,2},
+ { "_modop",nseel_asm_mod_op,nseel_asm_mod_op_end,2},
+
+
+#ifdef __ppc__
+ { "sin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&sin} },
+ { "cos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&cos} },
+ { "tan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&tan} },
+#else
+ { "sin", nseel_asm_sin,nseel_asm_sin_end, 1 },
+ { "cos", nseel_asm_cos,nseel_asm_cos_end, 1 },
+ { "tan", nseel_asm_tan,nseel_asm_tan_end, 1 },
+#endif
+ { "asin", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&asin}, },
+ { "acos", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&acos}, },
+ { "atan", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&atan}, },
+ { "atan2", nseel_asm_2pdd,nseel_asm_2pdd_end, 2, {&atan2}, },
+ { "sqr", nseel_asm_sqr,nseel_asm_sqr_end, 1 },
+#ifdef __ppc__
+ { "sqrt", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&sqrt}, },
+#else
+ { "sqrt", nseel_asm_sqrt,nseel_asm_sqrt_end, 1 },
+#endif
+ { "pow", nseel_asm_2pdd,nseel_asm_2pdd_end, 2, {&pow}, },
+ { "_powop", nseel_asm_2pdds,nseel_asm_2pdds_end, 2, {&pow}, },
+ { "exp", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&exp}, },
+#ifdef __ppc__
+ { "log", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&log} },
+ { "log10", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&log10} },
+#else
+ { "log", nseel_asm_log,nseel_asm_log_end, 1, },
+ { "log10", nseel_asm_log10,nseel_asm_log10_end, 1, },
+#endif
+ { "abs", nseel_asm_abs,nseel_asm_abs_end, 1 },
+ { "min", nseel_asm_min,nseel_asm_min_end, 2 },
+ { "max", nseel_asm_max,nseel_asm_max_end, 2 },
+#ifdef __ppc__
+ { "sign", nseel_asm_sign,nseel_asm_sign_end, 1, {&eel_zero}} ,
+#else
+ { "sign", nseel_asm_sign,nseel_asm_sign_end, 1, {&g_signs}} ,
+#endif
+ { "rand", nseel_asm_1pp,nseel_asm_1pp_end, 1, {&nseel_int_rand}, } ,
+
+//#if defined(_MSC_VER) && _MSC_VER >= 1400
+// { "floor", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&__floor} },
+//#else
+// { "floor", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&floor} },
+//#endif
+ { "ceil", nseel_asm_1pdd,nseel_asm_1pdd_end, 1, {&ceil} },
+#ifdef __ppc__
+ { "invsqrt", nseel_asm_invsqrt,nseel_asm_invsqrt_end, 1, },
+#else
+ { "invsqrt", nseel_asm_invsqrt,nseel_asm_invsqrt_end, 1, {&negativezeropointfive, &onepointfive} },
+#endif
+
+ { "sigmoid", nseel_asm_2pdd,nseel_asm_2pdd_end, 2, {&eel1sigmoid}, },
+
+ // these differ from _and/_or, they always evaluate both...
+ { "band", nseel_asm_2pdd,nseel_asm_2pdd_end, 2, {&eel1band}, },
+ { "bor", nseel_asm_2pdd,nseel_asm_2pdd_end, 2, {&eel1bor}, },
+
+ {"exec2",nseel_asm_exec2,nseel_asm_exec2_end,2},
+ {"exec3",nseel_asm_exec2,nseel_asm_exec2_end,3},
+ {"_mem",_asm_megabuf,_asm_megabuf_end,1,{&g_closefact,&__NSEEL_RAMAlloc},NSEEL_PProc_RAM},
+ {"_gmem",_asm_megabuf,_asm_megabuf_end,1,{&g_closefact,&__NSEEL_RAMAllocGMEM},NSEEL_PProc_GRAM},
+ {"freembuf",_asm_generic1parm,_asm_generic1parm_end,1,{&__NSEEL_RAM_MemFree},NSEEL_PProc_RAM},
+ {"memcpy",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemCpy},NSEEL_PProc_RAM},
+ {"memset",_asm_generic3parm,_asm_generic3parm_end,3,{&__NSEEL_RAM_MemSet},NSEEL_PProc_RAM},
+};
+
+static functionType *fnTableUser;
+static int fnTableUser_size;
+
+functionType *nseel_getFunctionFromTable(int idx)
+{
+ if (idx<0) return 0;
+ if (idx>=sizeof(fnTable1)/sizeof(fnTable1[0]))
+ {
+ idx -= sizeof(fnTable1)/sizeof(fnTable1[0]);
+ if (!fnTableUser || idx >= fnTableUser_size) return 0;
+ return fnTableUser+idx;
+ }
+ return fnTable1+idx;
+}
+
+int NSEEL_init() // returns 0 on success
+{
+ NSEEL_quit();
+ return 0;
+}
+
+void NSEEL_addfunctionex2(const char *name, int nparms, char *code_startaddr, int code_len, void *pproc, void *fptr, void *fptr2)
+{
+ if (!fnTableUser || !(fnTableUser_size&7))
+ {
+ fnTableUser=(functionType *)realloc(fnTableUser,(fnTableUser_size+8)*sizeof(functionType));
+ }
+ if (fnTableUser)
+ {
+ memset(&fnTableUser[fnTableUser_size],0,sizeof(functionType));
+ fnTableUser[fnTableUser_size].nParams = nparms;
+ fnTableUser[fnTableUser_size].name = name;
+ fnTableUser[fnTableUser_size].afunc = code_startaddr;
+ fnTableUser[fnTableUser_size].func_e = code_startaddr + code_len;
+ fnTableUser[fnTableUser_size].pProc = (NSEEL_PPPROC) pproc;
+ fnTableUser[fnTableUser_size].replptrs[0]=fptr;
+ fnTableUser[fnTableUser_size].replptrs[1]=fptr2;
+ fnTableUser_size++;
+ }
+}
+
+void NSEEL_quit()
+{
+ free(fnTableUser);
+ fnTableUser_size=0;
+ fnTableUser=0;
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static void freeBlocks(llBlock **start)
+{
+ llBlock *s=*start;
+ *start=0;
+ while (s)
+ {
+ llBlock *llB = s->next;
+#ifdef _WIN32
+ VirtualFree(s, 0 /*LLB_DSIZE*/, MEM_RELEASE);
+#else
+ free(s);
+#endif
+ s=llB;
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static void *__newBlock(llBlock **start, int size)
+{
+ llBlock *llb;
+ int alloc_size;
+ if (*start && (LLB_DSIZE - (*start)->sizeused) >= size)
+ {
+ void *t=(*start)->block+(*start)->sizeused;
+ (*start)->sizeused+=(size+7)&~7;
+ return t;
+ }
+
+ alloc_size=sizeof(llBlock);
+ if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
+
+#ifdef _WIN32
+ llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+#else
+ llb = (llBlock *)malloc(alloc_size); // grab bigger block if absolutely necessary (heh)
+#endif
+#if defined(EEL_USE_MPROTECT)
+ {
+ static int pagesize = 0;
+ if (!pagesize)
+ {
+ pagesize=sysconf(_SC_PAGESIZE);
+ if (!pagesize) pagesize=4096;
+ }
+ uintptr_t offs,eoffs;
+ offs=((uintptr_t)llb)&~(pagesize-1);
+ eoffs=((uintptr_t)llb + alloc_size + pagesize-1)&~(pagesize-1);
+ mprotect((void*)offs,eoffs-offs,PROT_WRITE|PROT_READ|PROT_EXEC);
+ }
+#endif
+ llb->sizeused=(size+7)&~7;
+ llb->next = *start;
+ *start = llb;
+ return llb->block;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------
+INT_PTR nseel_createCompiledValue(compileContext *ctx, EEL_F value, EEL_F *addrValue)
+{
+ unsigned char *block;
+
+ block=(unsigned char *)newTmpBlock(GLUE_MOV_EAX_DIRECTVALUE_SIZE);
+
+ if (addrValue == NULL)
+ {
+ *(addrValue = (EEL_F *)newBlock(sizeof(EEL_F),sizeof(EEL_F))) = value;
+ ctx->l_stats[3]+=sizeof(EEL_F);
+ }
+
+ GLUE_MOV_EAX_DIRECTVALUE_GEN(block+4,(INT_PTR)addrValue);
+
+ return ((INT_PTR)(block));
+
+}
+
+//---------------------------------------------------------------------------------------------------------------
+static void *nseel_getFunctionAddress(int fntype, int fn, int *size, NSEEL_PPPROC *pProc, void ***replList)
+{
+ *replList=0;
+ switch (fntype)
+ {
+ case MATH_SIMPLE:
+ switch (fn)
+ {
+ case FN_ASSIGN:
+ return GLUE_realAddress(nseel_asm_assign,nseel_asm_assign_end,size);
+ case FN_ADD:
+ return GLUE_realAddress(nseel_asm_add,nseel_asm_add_end,size);
+ case FN_SUB:
+ return GLUE_realAddress(nseel_asm_sub,nseel_asm_sub_end,size);
+ case FN_MULTIPLY:
+ return GLUE_realAddress(nseel_asm_mul,nseel_asm_mul_end,size);
+ case FN_DIVIDE:
+ return GLUE_realAddress(nseel_asm_div,nseel_asm_div_end,size);
+ case FN_MODULO:
+ return GLUE_realAddress(nseel_asm_exec2,nseel_asm_exec2_end,size);
+ case FN_AND:
+ return GLUE_realAddress(nseel_asm_and,nseel_asm_and_end,size);
+ case FN_OR:
+ return GLUE_realAddress(nseel_asm_or,nseel_asm_or_end,size);
+ case FN_UPLUS:
+ return GLUE_realAddress(nseel_asm_uplus,nseel_asm_uplus_end,size);
+ case FN_UMINUS:
+ return GLUE_realAddress(nseel_asm_uminus,nseel_asm_uminus_end,size);
+ }
+ case MATH_FN:
+ {
+ functionType *p=nseel_getFunctionFromTable(fn);
+ if (p)
+ {
+ *replList=p->replptrs;
+ *pProc=p->pProc;
+ return GLUE_realAddress(p->afunc,p->func_e,size);
+ }
+ }
+ }
+
+ *size=0;
+ return 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------
+INT_PTR nseel_createCompiledFunction3(compileContext *ctx, int fntype, INT_PTR fn, INT_PTR code1, INT_PTR code2, INT_PTR code3)
+{
+ int sizes1=((int *)code1)[0];
+ int sizes2=((int *)code2)[0];
+ int sizes3=((int *)code3)[0];
+
+ if (fntype == MATH_FN && fn == 0) // special case: IF
+ {
+ void *func3;
+ int size;
+ INT_PTR *ptr;
+ char *block;
+
+ unsigned char *newblock2,*newblock3;
+ unsigned char *p;
+
+ p=newblock2=newBlock(sizes2+sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32);
+ memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); p+=GLUE_FUNC_ENTER_SIZE;
+ memcpy(p,(char*)code2+4,sizes2); p+=sizes2;
+ memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); p+=GLUE_FUNC_LEAVE_SIZE;
+ memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET);
+
+ p=newblock3=newBlock(sizes3+sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32);
+ memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); p+=GLUE_FUNC_ENTER_SIZE;
+ memcpy(p,(char*)code3+4,sizes3); p+=sizes3;
+ memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); p+=GLUE_FUNC_LEAVE_SIZE;
+ memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET);
+
+ ctx->l_stats[2]+=sizes2+sizes3+sizeof(GLUE_RET)*2;
+
+ func3 = GLUE_realAddress(nseel_asm_if,nseel_asm_if_end,&size);
+
+ block=(char *)newTmpBlock(sizes1+size);
+
+ memcpy(block+4,(char*)code1+4,sizes1);
+ ptr=(INT_PTR *)(block+4+sizes1);
+ memcpy(ptr,func3,size);
+
+ ptr=EEL_GLUE_set_immediate(ptr,&g_closefact);
+ ptr=EEL_GLUE_set_immediate(ptr,newblock2);
+ EEL_GLUE_set_immediate(ptr,newblock3);
+
+ ctx->computTableTop++;
+
+ return (INT_PTR)block;
+
+ }
+ else
+ {
+ int size2;
+ unsigned char *block;
+ unsigned char *outp;
+
+ void *myfunc;
+ NSEEL_PPPROC preProc=0;
+ void **repl;
+
+ myfunc = nseel_getFunctionAddress(fntype, fn, &size2, &preProc,&repl);
+
+ block=(unsigned char *)newTmpBlock(size2+sizes1+sizes2+sizes3+
+ sizeof(GLUE_PUSH_EAX) +
+ sizeof(GLUE_PUSH_EAX) +
+ sizeof(GLUE_POP_EBX) +
+ sizeof(GLUE_POP_ECX));
+
+ outp=block+4;
+ memcpy(outp,(char*)code1+4,sizes1);
+ outp+=sizes1;
+ memcpy(outp,&GLUE_PUSH_EAX,sizeof(GLUE_PUSH_EAX)); outp+=sizeof(GLUE_PUSH_EAX);
+ memcpy(outp,(char*)code2+4,sizes2);
+ outp+=sizes2;
+ memcpy(outp,&GLUE_PUSH_EAX,sizeof(GLUE_PUSH_EAX)); outp+=sizeof(GLUE_PUSH_EAX);
+ memcpy(outp,(char*)code3+4,sizes3);
+ outp+=sizes3;
+ memcpy(outp,&GLUE_POP_EBX,sizeof(GLUE_POP_EBX)); outp+=sizeof(GLUE_POP_EBX);
+ memcpy(outp,&GLUE_POP_ECX,sizeof(GLUE_POP_ECX)); outp+=sizeof(GLUE_POP_ECX);
+
+ memcpy(outp,myfunc,size2);
+ if (preProc) preProc(outp,size2,ctx);
+ if (repl)
+ {
+ if (repl[0]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[0]);
+ if (repl[1]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[1]);
+ if (repl[2]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[2]);
+ if (repl[3]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[3]);
+ }
+
+ ctx->computTableTop++;
+
+ return ((INT_PTR)(block));
+ }
+}
+
+//---------------------------------------------------------------------------------------------------------------
+INT_PTR nseel_createCompiledFunction2(compileContext *ctx, int fntype, INT_PTR fn, INT_PTR code1, INT_PTR code2)
+{
+ int size2;
+ unsigned char *outp;
+ void *myfunc;
+ int sizes1=((int *)code1)[0];
+ int sizes2=((int *)code2)[0];
+ if (fntype == MATH_FN && (fn == 1 || fn == 2 || fn == 3)) // special case: LOOP/BOR/BAND
+ {
+ void *func3;
+ int size;
+ INT_PTR *ptr;
+ char *block;
+
+ unsigned char *newblock2, *p;
+
+ p=newblock2=newBlock(sizes2+sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32);
+ memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); p+=GLUE_FUNC_ENTER_SIZE;
+ memcpy(p,(char*)code2+4,sizes2); p+=sizes2;
+ memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); p+=GLUE_FUNC_LEAVE_SIZE;
+ memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET);
+
+ ctx->l_stats[2]+=sizes2+2;
+
+ if (fn == 1) func3 = GLUE_realAddress(nseel_asm_band,nseel_asm_band_end,&size);
+ else if (fn == 3) func3 = GLUE_realAddress(nseel_asm_repeat,nseel_asm_repeat_end,&size);
+ else func3 = GLUE_realAddress(nseel_asm_bor,nseel_asm_bor_end,&size);
+
+ block=(char *)newTmpBlock(sizes1+size);
+ memcpy(block+4,(char*)code1+4,sizes1);
+ ptr=(INT_PTR *)(block+4+sizes1);
+ memcpy(ptr,func3,size);
+
+ if (fn!=3) ptr=EEL_GLUE_set_immediate(ptr,&g_closefact); // for or/and
+ ptr=EEL_GLUE_set_immediate(ptr,newblock2);
+ if (fn!=3) ptr=EEL_GLUE_set_immediate(ptr,&g_closefact); // for or/and
+#ifdef __ppc__
+ if (fn!=3) // for or/and on ppc we need a one
+ {
+ ptr=EEL_GLUE_set_immediate(ptr,&eel_one);
+ }
+#endif
+
+ ctx->computTableTop++;
+ return (INT_PTR)block;
+ }
+
+ {
+ NSEEL_PPPROC preProc=0;
+ unsigned char *block;
+ void **repl;
+ myfunc = nseel_getFunctionAddress(fntype, fn, &size2,&preProc,&repl);
+
+ block=(unsigned char *)newTmpBlock(size2+sizes1+sizes2+sizeof(GLUE_PUSH_EAX)+sizeof(GLUE_POP_EBX));
+
+ outp=block+4;
+ memcpy(outp,(char*)code1+4,sizes1);
+ outp+=sizes1;
+ memcpy(outp,&GLUE_PUSH_EAX,sizeof(GLUE_PUSH_EAX)); outp+=sizeof(GLUE_PUSH_EAX);
+ memcpy(outp,(char*)code2+4,sizes2);
+ outp+=sizes2;
+ memcpy(outp,&GLUE_POP_EBX,sizeof(GLUE_POP_EBX)); outp+=sizeof(GLUE_POP_EBX);
+
+ memcpy(outp,myfunc,size2);
+ if (preProc) preProc(outp,size2,ctx);
+ if (repl)
+ {
+ if (repl[0]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[0]);
+ if (repl[1]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[1]);
+ if (repl[2]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[2]);
+ if (repl[3]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[3]);
+ }
+
+ ctx->computTableTop++;
+
+ return ((INT_PTR)(block));
+ }
+}
+
+
+//---------------------------------------------------------------------------------------------------------------
+INT_PTR nseel_createCompiledFunction1(compileContext *ctx, int fntype, INT_PTR fn, INT_PTR code)
+{
+ NSEEL_PPPROC preProc=0;
+ int size,size2;
+ char *block;
+ void *myfunc;
+ void *func1;
+
+ size =((int *)code)[0];
+ func1 = (void *)(code+4);
+
+
+ if (fntype == MATH_FN && fn == 4) // special case: while
+ {
+ void *func3;
+ INT_PTR *ptr;
+
+ unsigned char *newblock2, *p;
+
+ p=newblock2=newBlock(size+sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE,32);
+ memcpy(p,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); p+=GLUE_FUNC_ENTER_SIZE;
+ memcpy(p,func1,size); p+=size;
+ memcpy(p,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); p+=GLUE_FUNC_LEAVE_SIZE;
+ memcpy(p,&GLUE_RET,sizeof(GLUE_RET)); p+=sizeof(GLUE_RET);
+
+ ctx->l_stats[2]+=size+2;
+
+ func3 = GLUE_realAddress(nseel_asm_repeatwhile,nseel_asm_repeatwhile_end,&size);
+
+ block=(char *)newTmpBlock(size);
+ ptr = (INT_PTR *)(block+4);
+ memcpy(ptr,func3,size);
+ ptr=EEL_GLUE_set_immediate(ptr,newblock2);
+ EEL_GLUE_set_immediate(ptr,&g_closefact);
+
+ ctx->computTableTop++;
+ return (INT_PTR)block;
+ }
+
+ {
+ void **repl;
+ myfunc = nseel_getFunctionAddress(fntype, fn, &size2,&preProc,&repl);
+
+ block=(char *)newTmpBlock(size+size2);
+
+ memcpy(block+4, func1, size);
+ memcpy(block+size+4,myfunc,size2);
+ if (preProc) preProc(block+size+4,size2,ctx);
+ if (repl)
+ {
+ unsigned char *outp=(unsigned char *)block+size+4;
+ if (repl[0]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[0]);
+ if (repl[1]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[1]);
+ if (repl[2]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[2]);
+ if (repl[3]) outp=(unsigned char *)EEL_GLUE_set_immediate(outp,repl[3]);
+ }
+
+ ctx->computTableTop++;
+
+ return ((INT_PTR)(block));
+ }
+}
+
+
+static char *preprocessCode(compileContext *ctx, char *expression)
+{
+ char *expression_start=expression;
+ int len=0;
+ int alloc_len=strlen(expression)+1+64;
+ char *buf=(char *)malloc(alloc_len);
+ int semicnt=0;
+ // we need to call onCompileNewLine for each new line we get
+
+ //onCompileNewLine(ctx,
+
+ while (*expression)
+ {
+ if (len > alloc_len-64)
+ {
+ alloc_len = len+128;
+ buf=(char*)realloc(buf,alloc_len);
+ }
+
+ if (expression[0] == '/')
+ {
+ if (expression[1] == '/')
+ {
+ expression+=2;
+ while (expression[0] && expression[0] != '\n') expression++;
+ continue;
+ }
+ else if (expression[1] == '*')
+ {
+ expression+=2;
+ while (expression[0] && (expression[0] != '*' || expression[1] != '/'))
+ {
+ if (expression[0] == '\n') onCompileNewLine(ctx,expression+1-expression_start,len);
+ expression++;
+ }
+ if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/
+ continue;
+ }
+ }
+
+ if (expression[0] == '$')
+ {
+ if (toupper(expression[1]) == 'X')
+ {
+ char *p=expression+2;
+ unsigned int v=strtoul(expression+2,&p,16);
+ char tmp[64];
+ expression=p;
+
+ sprintf(tmp,"%u",v);
+ memcpy(buf+len,tmp,strlen(tmp));
+ len+=strlen(tmp);
+ ctx->l_stats[0]+=strlen(tmp);
+ continue;
+
+ }
+ if (expression[1]=='\'' && expression[2] && expression[3]=='\'')
+ {
+ char tmp[64];
+ sprintf(tmp,"%u",((unsigned char *)expression)[2]);
+ expression+=4;
+
+ memcpy(buf+len,tmp,strlen(tmp));
+ len+=strlen(tmp);
+ ctx->l_stats[0]+=strlen(tmp);
+ continue;
+ }
+ if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I')
+ {
+ static char *str="3.141592653589793";
+ expression+=3;
+ memcpy(buf+len,str,17);
+ len+=17; //strlen(str);
+ ctx->l_stats[0]+=17;
+ continue;
+ }
+ if (toupper(expression[1]) == 'E')
+ {
+ static char *str="2.71828183";
+ expression+=2;
+ memcpy(buf+len,str,10);
+ len+=10; //strlen(str);
+ ctx->l_stats[0]+=10;
+ continue;
+ }
+ if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I')
+ {
+ static char *str="1.61803399";
+ expression+=4;
+ memcpy(buf+len,str,10);
+ len+=10; //strlen(str);
+ ctx->l_stats[0]+=10;
+ continue;
+ }
+
+ }
+
+ {
+ char c=*expression++;
+
+ if (c == '\n') onCompileNewLine(ctx,expression-expression_start,len);
+ if (isspace(c)) c=' ';
+
+ if (c == '(') semicnt++;
+ else if (c == ')') { semicnt--; if (semicnt < 0) semicnt=0; }
+ else if (c == ';' && semicnt > 0)
+ {
+ // convert ; to % if next nonwhitespace char is alnum, otherwise convert to space
+ int p=0;
+ int nc;
+ int commentstate=0;
+ while ((nc=expression[p]))
+ {
+ if (!commentstate && nc == '/')
+ {
+ if (expression[p+1] == '/') commentstate=1;
+ else if (expression[p+1] == '*') commentstate=2;
+ }
+
+ if (commentstate == 1 && nc == '\n') commentstate=0;
+ else if (commentstate == 2 && nc == '*' && expression[p+1]=='/')
+ {
+ p++; // skip *
+ commentstate=0;
+ }
+ else if (!commentstate && !isspace(nc)) break;
+
+ p++;
+ }
+ // fucko, we should look for even more chars, me thinks
+ if (nc && (isalnum(nc)
+#if 1
+ || nc == '(' || nc == '_' || nc == '!' || nc == '$'
+#endif
+ )) c='%';
+ else c = ' '; // stray ;
+ }
+#if 0
+ else if (semicnt > 0 && c == ',')
+ {
+ int p=0;
+ int nc;
+ while ((nc=expression[p]) && isspace(nc)) p++;
+ if (nc == ',' || nc == ')')
+ {
+ expression += p+1;
+ buf[len++]=',';
+ buf[len++]='0';
+ c=nc; // append this char
+ }
+ }
+#endif
+ // list of operators
+
+ else if (!isspace(c) && !isalnum(c)) // check to see if this operator is ours
+ {
+
+ static char *symbollists[]=
+ {
+ "", // or any control char that is not parenthed
+ ":(,;?%",
+ ",):?;", // or || or &&
+ ",);", // jf> removed :? from this, for =
+ ",);",
+ "", // only scans for a negative ] level
+
+ };
+
+
+ static struct
+ {
+ char op[2];
+ char lscan,rscan;
+ char *func;
+ } preprocSymbols[] =
+ {
+ {{'+','='}, 0, 3, "_addop" },
+ {{'-','='}, 0, 3, "_subop" },
+ {{'%','='}, 0, 3, "_modop" },
+ {{'|','='}, 0, 3, "_orop" },
+ {{'&','='}, 0, 3, "_andop"},
+
+ {{'/','='}, 0, 3, "_divop"},
+ {{'*','='}, 0, 3, "_mulop"},
+ {{'^','='}, 0, 3, "_powop"},
+
+ {{'=','='}, 1, 2, "_equal" },
+ {{'<','='}, 1, 2, "_beleq" },
+ {{'>','='}, 1, 2, "_aboeq" },
+ {{'<',0 }, 1, 2, "_below" },
+ {{'>',0 }, 1, 2, "_above" },
+ {{'!','='}, 1, 2, "_noteq" },
+ {{'|','|'}, 1, 2, "_or" },
+ {{'&','&'}, 1, 2, "_and" },
+ {{'=',0 }, 0, 3, "_set" },
+ {{'%',0}, 0, 0, "_mod" },
+ {{'^',0}, 0, 0, "pow" },
+
+
+ {{'[',0 }, 0, 5, },
+ {{'!',0 },-1, 0, }, // this should also ignore any leading +-
+ {{'?',0 }, 1, 4, },
+
+ };
+
+
+ int n;
+ int ns=sizeof(preprocSymbols)/sizeof(preprocSymbols[0]);
+ for (n = 0; n < ns; n++)
+ {
+ if (c == preprocSymbols[n].op[0] && (!preprocSymbols[n].op[1] || expression[0] == preprocSymbols[n].op[1]))
+ {
+ break;
+ }
+ }
+ if (n < ns)
+ {
+
+ int lscan=preprocSymbols[n].lscan;
+ int rscan=preprocSymbols[n].rscan;
+
+ // parse left side of =, scanning back for an unparenthed nonwhitespace nonalphanumeric nonparenth?
+ // so megabuf(x+y)= would be fine, x=, but +x= would do +set(x,)
+ char *l_ptr=0;
+ char *r_ptr=0;
+ if (lscan >= 0)
+ {
+ char *scan=symbollists[lscan];
+ int l_semicnt=0;
+ l_ptr=buf + len - 1;
+ while (l_ptr >= buf)
+ {
+ if (*l_ptr == ')') l_semicnt++;
+ else if (*l_ptr == '(')
+ {
+ l_semicnt--;
+ if (l_semicnt < 0) break;
+ }
+ else if (!l_semicnt)
+ {
+ if (!*scan)
+ {
+ if (!isspace(*l_ptr) && !isalnum(*l_ptr) && *l_ptr != '_' && *l_ptr != '.') break;
+ }
+ else
+ {
+ char *sc=scan;
+ if (lscan == 2 && ( // not currently used, even
+ (l_ptr[0]=='|' && l_ptr[1] == '|')||
+ (l_ptr[0]=='&' && l_ptr[1] == '&')
+ )
+ ) break;
+ while (*sc && *l_ptr != *sc) sc++;
+ if (*sc) break;
+ }
+ }
+ l_ptr--;
+ }
+ buf[len]=0;
+
+ l_ptr++;
+
+ len = l_ptr - buf;
+
+ l_ptr = strdup(l_ptr); // doesn't need to be preprocessed since it just was
+ }
+ if (preprocSymbols[n].op[1]) expression++;
+
+ r_ptr=expression;
+ {
+ // scan forward to an uncommented, unparenthed semicolon, comma, or )
+ int r_semicnt=0;
+ int r_qcnt=0;
+ char *scan=symbollists[rscan];
+ int commentstate=0;
+ int hashadch=0;
+ int bracketcnt=0;
+ while (*r_ptr)
+ {
+ if (!commentstate && *r_ptr == '/')
+ {
+ if (r_ptr[1] == '/') commentstate=1;
+ else if (r_ptr[1] == '*') commentstate=2;
+ }
+ if (commentstate == 1 && *r_ptr == '\n') commentstate=0;
+ else if (commentstate == 2 && *r_ptr == '*' && r_ptr[1]=='/')
+ {
+ r_ptr++; // skip *
+ commentstate=0;
+ }
+ else if (!commentstate)
+ {
+ if (*r_ptr == '(') {hashadch=1; r_semicnt++; }
+ else if (*r_ptr == ')')
+ {
+ r_semicnt--;
+ if (r_semicnt < 0) break;
+ }
+ else if (!r_semicnt)
+ {
+ char *sc=scan;
+ if (*r_ptr == ';' || *r_ptr == ',') break;
+
+ if (!rscan)
+ {
+ if (*r_ptr == ':') break;
+ if (!isspace(*r_ptr) && !isalnum(*r_ptr) && *r_ptr != '_' && *r_ptr != '.' && hashadch) break;
+ if (isalnum(*r_ptr) || *r_ptr == '_')hashadch=1;
+ }
+ else if (rscan == 2 &&
+ ((r_ptr[0]=='|' && r_ptr[1] == '|')||
+ (r_ptr[0]=='&' && r_ptr[1] == '&')
+ )
+ ) break;
+
+ else if (rscan == 3 || rscan == 4)
+ {
+ if (*r_ptr == ':') r_qcnt--;
+ else if (*r_ptr == '?') r_qcnt++;
+
+ if (r_qcnt < 3-rscan) break;
+ }
+ else if (rscan == 5)
+ {
+ if (*r_ptr == '[') bracketcnt++;
+ else if (*r_ptr == ']') bracketcnt--;
+ if (bracketcnt < 0) break;
+ }
+
+ while (*sc && *r_ptr != *sc) sc++;
+ if (*sc) break;
+ }
+ }
+ r_ptr++;
+ }
+ // expression -> r_ptr is our string (not including r_ptr)
+
+ {
+ char *orp=r_ptr;
+
+ char rps=*orp;
+ *orp=0; // temporarily terminate
+
+ r_ptr=preprocessCode(ctx,expression);
+ expression=orp;
+
+ *orp = rps; // fix termination(restore string)
+ }
+
+ }
+
+ if (r_ptr)
+ {
+ int thisl = strlen(l_ptr?l_ptr:"") + strlen(r_ptr) + 32;
+
+ if (len+thisl > alloc_len-64)
+ {
+ alloc_len = len+thisl+128;
+ buf=(char*)realloc(buf,alloc_len);
+ }
+
+
+ if (n == ns-3)
+ {
+ char *lp = l_ptr;
+ char *rp = r_ptr;
+ while (lp && *lp && isspace(*lp)) lp++;
+ while (rp && *rp && isspace(*rp)) rp++;
+ if (lp && !strncasecmp(lp,"gmem",4) && (!lp[4] || isspace(lp[4])))
+ {
+ len+=sprintf(buf+len,"_gmem(%s",r_ptr && *r_ptr ? r_ptr : "0");
+ ctx->l_stats[0]+=strlen(l_ptr)+4;
+ }
+ else if (rp && *rp && strcmp(rp,"0"))
+ {
+ len+=sprintf(buf+len,"_mem((%s)+(%s)",lp,rp);
+ ctx->l_stats[0]+=strlen(lp)+strlen(rp)+8;
+ }
+ else
+ {
+ len+=sprintf(buf+len,"_mem(%s",lp);
+ ctx->l_stats[0]+=strlen(lp)+4;
+ }
+
+ // skip the ]
+ if (*expression == ']') expression++;
+
+ }
+ else if (n == ns-2)
+ {
+ len+=sprintf(buf+len,"_not(%s",
+ r_ptr);
+
+ ctx->l_stats[0]+=4;
+ }
+ else if (n == ns-1)// if (l_ptr,r_ptr1,r_ptr2)
+ {
+ char *rptr2=r_ptr;
+ char *tmp=r_ptr;
+ int parcnt=0;
+ int qcnt=1;
+ while (*rptr2)
+ {
+ if (*rptr2 == '?') qcnt++;
+ else if (*rptr2 == ':') qcnt--;
+ else if (*rptr2 == '(') parcnt++;
+ else if (*rptr2 == ')') parcnt--;
+ if (parcnt < 0) break;
+ if (!parcnt && !qcnt && *rptr2 == ':') break;
+ rptr2++;
+ }
+ if (*rptr2) *rptr2++=0;
+ while (isspace(*rptr2)) rptr2++;
+
+ while (isspace(*tmp)) tmp++;
+
+ len+=sprintf(buf+len,"_if(%s,%s,%s",l_ptr,*tmp?tmp:"0",*rptr2?rptr2:"0");
+ ctx->l_stats[0]+=6;
+ }
+ else
+ {
+ len+=sprintf(buf+len,"%s(%s,%s",preprocSymbols[n].func,l_ptr?l_ptr:"",r_ptr);
+ ctx->l_stats[0]+=strlen(preprocSymbols[n].func)+2;
+ }
+
+ }
+
+ free(r_ptr);
+ free(l_ptr);
+
+
+ c = ')'; // close parenth below
+ }
+ }
+
+// if (c != ' ' || (len && buf[len-1] != ' ')) // don't bother adding multiple spaces
+ {
+ buf[len++]=c;
+ if (c != ' ') ctx->l_stats[0]++;
+ }
+ }
+ }
+ buf[len]=0;
+
+ return buf;
+}
+
+#ifdef PPROC_TEST
+
+int main(int argc, char* argv[])
+{
+ compileContext ctx={0};
+ char *p=preprocessCode(&ctx,argv[1]);
+ if (p)printf("%s\n",p);
+ free(p);
+ return 0;
+}
+
+#endif
+
+#if 0
+static void movestringover(char *str, int amount)
+{
+ char tmp[1024+8];
+
+ int l=(int)strlen(str);
+ l=min(1024-amount-1,l);
+
+ memcpy(tmp,str,l+1);
+
+ while (l >= 0 && tmp[l]!='\n') l--;
+ l++;
+
+ tmp[l]=0;//ensure we null terminate
+
+ memcpy(str+amount,tmp,l+1);
+}
+#endif
+
+//------------------------------------------------------------------------------
+NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX _ctx, char *_expression, int lineoffs)
+{
+ compileContext *ctx = (compileContext *)_ctx;
+ char *expression,*expression_start;
+ int computable_size=0;
+ codeHandleType *handle;
+ startPtr *scode=NULL;
+ startPtr *startpts=NULL;
+
+ if (!ctx) return 0;
+
+ ctx->last_error_string[0]=0;
+
+ if (!_expression || !*_expression) return 0;
+
+ freeBlocks((llBlock **)&ctx->tmpblocks_head); // free blocks
+ freeBlocks((llBlock **)&ctx->blocks_head); // free blocks
+ memset(ctx->l_stats,0,sizeof(ctx->l_stats));
+ free(ctx->compileLineRecs); ctx->compileLineRecs=0; ctx->compileLineRecs_size=0; ctx->compileLineRecs_alloc=0;
+
+ handle = (codeHandleType*)newBlock(sizeof(codeHandleType),8);
+
+ if (!handle)
+ {
+ return 0;
+ }
+
+ memset(handle,0,sizeof(codeHandleType));
+
+ expression_start=expression=preprocessCode(ctx,_expression);
+
+
+ while (*expression)
+ {
+ void *startptr;
+ char *expr;
+ ctx->colCount=0;
+ ctx->computTableTop=0;
+
+ // single out segment
+ while (*expression == ';' || isspace(*expression)) expression++;
+ if (!*expression) break;
+ expr=expression;
+
+ while (*expression && *expression != ';') expression++;
+ if (*expression) *expression++ = 0;
+
+ // parse
+
+ startptr=nseel_compileExpression(ctx,expr);
+
+ if (ctx->computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES- /* safety */ 16 - /* alignment */4 ||
+ !startptr)
+ {
+ int byteoffs = expr - expression_start;
+ int destoffs,linenumber;
+ char buf[21], *p;
+ int x,le;
+
+#ifdef NSEEL_EEL1_COMPAT_MODE
+ if (!startptr) continue;
+#endif
+ if (ctx->errVar > 0) byteoffs += ctx->errVar;
+ linenumber=findByteOffsetInSource(ctx,byteoffs,&destoffs);
+ if (destoffs < 0) destoffs=0;
+
+ le=strlen(_expression);
+ if (destoffs >= le) destoffs=le;
+ p= _expression + destoffs;
+ for (x = 0;x < 20; x ++)
+ {
+ if (!*p || *p == '\r' || *p == '\n') break;
+ buf[x]=*p++;
+ }
+ buf[x]=0;
+
+ sprintf(ctx->last_error_string,"Around line %d '%s'",linenumber+lineoffs,buf);
+
+ ctx->last_error_string[sizeof(ctx->last_error_string)-1]=0;
+ scode=NULL;
+ break;
+ }
+ if (computable_size < ctx->computTableTop)
+ {
+ computable_size=ctx->computTableTop;
+ }
+
+ {
+ startPtr *tmp=(startPtr*) __newBlock((llBlock **)&ctx->tmpblocks_head,sizeof(startPtr));
+ if (!tmp) break;
+
+ tmp->startptr = startptr;
+ tmp->next=NULL;
+ if (!scode) scode=startpts=tmp;
+ else
+ {
+ scode->next=tmp;
+ scode=tmp;
+ }
+ }
+}
+ free(ctx->compileLineRecs); ctx->compileLineRecs=0; ctx->compileLineRecs_size=0; ctx->compileLineRecs_alloc=0;
+
+ // check to see if failed on the first startingCode
+ if (!scode)
+ {
+ handle=NULL; // return NULL (after resetting blocks_head)
+ }
+ else
+ {
+ char *tabptr = (char *)(handle->workTable=calloc(computable_size+64, sizeof(EEL_F)));
+ unsigned char *writeptr;
+ startPtr *p=startpts;
+ int size=sizeof(GLUE_RET)+GLUE_FUNC_ENTER_SIZE+GLUE_FUNC_LEAVE_SIZE; // for ret at end :)
+
+ if (((INT_PTR)tabptr)&31)
+ tabptr += 32-(((INT_PTR)tabptr)&31);
+
+ // now we build one big code segment out of our list of them, inserting a mov esi, computable before each item
+ while (p)
+ {
+ size += GLUE_RESET_ESI(NULL,0);
+ size+=*(int *)p->startptr;
+ p=p->next;
+ }
+ handle->code = newBlock(size,32);
+ if (handle->code)
+ {
+ writeptr=(unsigned char *)handle->code;
+ memcpy(writeptr,&GLUE_FUNC_ENTER,GLUE_FUNC_ENTER_SIZE); writeptr += GLUE_FUNC_ENTER_SIZE;
+ p=startpts;
+ while (p)
+ {
+ int thissize=*(int *)p->startptr;
+ writeptr+=GLUE_RESET_ESI(writeptr,tabptr);
+ //memcpy(writeptr,&GLUE_MOV_ESI_EDI,sizeof(GLUE_MOV_ESI_EDI));
+ //writeptr+=sizeof(GLUE_MOV_ESI_EDI);
+ memcpy(writeptr,(char*)p->startptr + 4,thissize);
+ writeptr += thissize;
+
+ p=p->next;
+ }
+ memcpy(writeptr,&GLUE_FUNC_LEAVE,GLUE_FUNC_LEAVE_SIZE); writeptr += GLUE_FUNC_LEAVE_SIZE;
+ memcpy(writeptr,&GLUE_RET,sizeof(GLUE_RET)); writeptr += sizeof(GLUE_RET);
+ ctx->l_stats[1]=size;
+ }
+ handle->blocks = ctx->blocks_head;
+ ctx->blocks_head=0;
+
+ }
+ freeBlocks((llBlock **)&ctx->tmpblocks_head); // free blocks
+ freeBlocks((llBlock **)&ctx->blocks_head); // free blocks
+
+ if (handle)
+ {
+ memcpy(handle->code_stats,ctx->l_stats,sizeof(ctx->l_stats));
+ nseel_evallib_stats[0]+=ctx->l_stats[0];
+ nseel_evallib_stats[1]+=ctx->l_stats[1];
+ nseel_evallib_stats[2]+=ctx->l_stats[2];
+ nseel_evallib_stats[3]+=ctx->l_stats[3];
+ nseel_evallib_stats[4]++;
+ }
+ memset(ctx->l_stats,0,sizeof(ctx->l_stats));
+
+ free(expression_start);
+
+ return (NSEEL_CODEHANDLE)handle;
+}
+
+//------------------------------------------------------------------------------
+void NSEEL_code_execute(NSEEL_CODEHANDLE code)
+{
+ INT_PTR tabptr;
+ INT_PTR codeptr;
+ codeHandleType *h = (codeHandleType *)code;
+ if (!h || !h->code) return;
+
+ codeptr = (INT_PTR) h->code;
+#if 0
+ {
+ unsigned int *p=(unsigned int *)codeptr;
+ while (*p != GLUE_RET[0])
+ {
+ printf("instr:%04X:%04X\n",*p>>16,*p&0xffff);
+ p++;
+ }
+ }
+#endif
+
+ tabptr=(INT_PTR)h->workTable;
+ if (tabptr&31)
+ tabptr += 32-((tabptr)&31);
+ //printf("calling code!\n");
+ GLUE_CALL_CODE(tabptr,codeptr);
+
+}
+
+
+char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx)
+{
+ compileContext *c=(compileContext *)ctx;
+ if (ctx && c->last_error_string[0]) return c->last_error_string;
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void NSEEL_code_free(NSEEL_CODEHANDLE code)
+{
+ codeHandleType *h = (codeHandleType *)code;
+ if (h != NULL)
+ {
+ free(h->workTable);
+ nseel_evallib_stats[0]-=h->code_stats[0];
+ nseel_evallib_stats[1]-=h->code_stats[1];
+ nseel_evallib_stats[2]-=h->code_stats[2];
+ nseel_evallib_stats[3]-=h->code_stats[3];
+ nseel_evallib_stats[4]--;
+ freeBlocks(&h->blocks);
+
+
+ }
+
+}
+
+
+//------------------------------------------------------------------------------
+void NSEEL_VM_resetvars(NSEEL_VMCTX _ctx)
+{
+ if (_ctx)
+ {
+ compileContext *ctx=(compileContext *)_ctx;
+ int x;
+ if (ctx->varTable_Names || ctx->varTable_Values) for (x = 0; x < ctx->varTable_numBlocks; x ++)
+ {
+ if (ctx->varTable_Names) free(ctx->varTable_Names[x]);
+ if (ctx->varTable_Values) free(ctx->varTable_Values[x]);
+ }
+
+ free(ctx->varTable_Values);
+ free(ctx->varTable_Names);
+ ctx->varTable_Values=0;
+ ctx->varTable_Names=0;
+
+ ctx->varTable_numBlocks=0;
+ }
+}
+
+
+NSEEL_VMCTX NSEEL_VM_alloc() // return a handle
+{
+ compileContext *ctx=calloc(1,sizeof(compileContext));
+ return ctx;
+}
+
+void NSEEL_VM_free(NSEEL_VMCTX _ctx) // free when done with a VM and ALL of its code have been freed, as well
+{
+
+ if (_ctx)
+ {
+ compileContext *ctx=(compileContext *)_ctx;
+ NSEEL_VM_resetvars(_ctx);
+ NSEEL_VM_freeRAM(_ctx);
+
+ freeBlocks((llBlock **)&ctx->tmpblocks_head); // free blocks
+ freeBlocks((llBlock **)&ctx->blocks_head); // free blocks
+ free(ctx->compileLineRecs);
+ free(ctx);
+ }
+
+}
+
+int *NSEEL_code_getstats(NSEEL_CODEHANDLE code)
+{
+ codeHandleType *h = (codeHandleType *)code;
+ if (h)
+ {
+ return h->code_stats;
+ }
+ return 0;
+}
+
+void NSEEL_VM_SetCustomFuncThis(NSEEL_VMCTX ctx, void *thisptr)
+{
+ if (ctx)
+ {
+ compileContext *c=(compileContext*)ctx;
+ c->caller_this=thisptr;
+ }
+}
+
+
+
+
+
+void NSEEL_PProc_RAM(void *data, int data_size, compileContext *ctx)
+{
+ if (data_size>0) EEL_GLUE_set_immediate(data, &ctx->ram_blocks);
+}
+void NSEEL_PProc_THIS(void *data, int data_size, compileContext *ctx)
+{
+ if (data_size>0) EEL_GLUE_set_immediate(data, ctx->caller_this);
+}
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-eval.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-eval.c
new file mode 100644
index 00000000..2dc1d063
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-eval.c
@@ -0,0 +1,321 @@
+/*
+ Expression Evaluator Library (NS-EEL) v2
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-eval.c
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <string.h>
+#include <ctype.h>
+#include "ns-eel-int.h"
+
+#define NSEEL_VARS_MALLOC_CHUNKSIZE 8
+#define NSEEL_GLOBALVAR_BASE (1<<24)
+
+#ifndef NSEEL_MAX_VARIABLE_NAMELEN
+#define NSEEL_MAX_VARIABLE_NAMELEN 8
+#endif
+
+#define strnicmp(x,y,z) strncasecmp(x,y,z)
+
+
+#define INTCONST 1
+#define DBLCONST 2
+#define HEXCONST 3
+#define VARIABLE 4
+#define OTHER 5
+
+EEL_F nseel_globalregs[100];
+
+
+//------------------------------------------------------------------------------
+void *nseel_compileExpression(compileContext *ctx, char *exp)
+{
+ ctx->errVar=0;
+ nseel_llinit(ctx);
+ if (!nseel_yyparse(ctx,exp) && !ctx->errVar)
+ {
+ return (void*)ctx->result;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void nseel_setLastVar(compileContext *ctx)
+{
+ nseel_gettoken(ctx,ctx->lastVar, sizeof(ctx->lastVar));
+}
+
+void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx)
+{
+ compileContext *tctx = (compileContext *) ctx;
+ int wb;
+ if (!tctx) return;
+
+ for (wb = 0; wb < tctx->varTable_numBlocks; wb ++)
+ {
+ int ti;
+ int namepos=0;
+ for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++)
+ {
+ char *p=tctx->varTable_Names[wb]+namepos;
+ if (!*p) break;
+
+
+ if (!func(p,&tctx->varTable_Values[wb][ti],userctx))
+ break;
+
+ namepos += NSEEL_MAX_VARIABLE_NAMELEN;
+ }
+ if (ti < NSEEL_VARS_PER_BLOCK)
+ break;
+ }
+}
+
+
+
+static INT_PTR register_var(compileContext *ctx, const char *name, EEL_F **ptr)
+{
+ int wb;
+ int ti=0;
+ int i=0;
+ char *nameptr;
+ for (wb = 0; wb < ctx->varTable_numBlocks; wb ++)
+ {
+ int namepos=0;
+ for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++)
+ {
+ if (!ctx->varTable_Names[wb][namepos] || !strnicmp(ctx->varTable_Names[wb]+namepos,name,NSEEL_MAX_VARIABLE_NAMELEN))
+ {
+ break;
+ }
+ namepos += NSEEL_MAX_VARIABLE_NAMELEN;
+ i++;
+ }
+ if (ti < NSEEL_VARS_PER_BLOCK)
+ break;
+ }
+ if (wb == ctx->varTable_numBlocks)
+ {
+ ti=0;
+ // add new block
+ if (!(ctx->varTable_numBlocks&(NSEEL_VARS_MALLOC_CHUNKSIZE-1)) || !ctx->varTable_Values || !ctx->varTable_Names )
+ {
+ ctx->varTable_Values = (EEL_F **)realloc(ctx->varTable_Values,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(EEL_F *));
+ ctx->varTable_Names = (char **)realloc(ctx->varTable_Names,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(char *));
+ }
+ ctx->varTable_numBlocks++;
+
+ ctx->varTable_Values[wb] = (EEL_F *)calloc(sizeof(EEL_F),NSEEL_VARS_PER_BLOCK);
+ ctx->varTable_Names[wb] = (char *)calloc(NSEEL_MAX_VARIABLE_NAMELEN,NSEEL_VARS_PER_BLOCK);
+ }
+
+ nameptr=ctx->varTable_Names[wb]+ti*NSEEL_MAX_VARIABLE_NAMELEN;
+ if (!nameptr[0])
+ {
+ strncpy(nameptr,name,NSEEL_MAX_VARIABLE_NAMELEN);
+ }
+ if (ptr) *ptr = ctx->varTable_Values[wb] + ti;
+ return i;
+}
+
+//------------------------------------------------------------------------------
+INT_PTR nseel_setVar(compileContext *ctx, INT_PTR varNum)
+{
+ if (varNum < 0) // adding new var
+ {
+ char *var=ctx->lastVar;
+ if (!strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
+ {
+ int i,x=atoi(var+3);
+ if (x < 0 || x > 99) x=0;
+ i=NSEEL_GLOBALVAR_BASE+x;
+ return i;
+ }
+
+ return register_var(ctx,ctx->lastVar,NULL);
+
+ }
+
+ // setting/getting oldvar
+
+ if (varNum >= NSEEL_GLOBALVAR_BASE && varNum < NSEEL_GLOBALVAR_BASE+100)
+ {
+ return varNum;
+ }
+
+ {
+ int wb,ti;
+ char *nameptr;
+ if (varNum < 0 || varNum >= ctx->varTable_numBlocks*NSEEL_VARS_PER_BLOCK) return -1;
+
+ wb=varNum/NSEEL_VARS_PER_BLOCK;
+ ti=(varNum%NSEEL_VARS_PER_BLOCK);
+ nameptr=ctx->varTable_Names[wb]+ti*NSEEL_MAX_VARIABLE_NAMELEN;
+ if (!nameptr[0])
+ {
+ strncpy(nameptr,ctx->lastVar,NSEEL_MAX_VARIABLE_NAMELEN);
+ }
+ return varNum;
+ }
+
+}
+
+//------------------------------------------------------------------------------
+INT_PTR nseel_getVar(compileContext *ctx, INT_PTR i)
+{
+ if (i >= 0 && i < (NSEEL_VARS_PER_BLOCK*ctx->varTable_numBlocks))
+ return nseel_createCompiledValue(ctx,0, ctx->varTable_Values[i/NSEEL_VARS_PER_BLOCK] + i%NSEEL_VARS_PER_BLOCK);
+ if (i >= NSEEL_GLOBALVAR_BASE && i < NSEEL_GLOBALVAR_BASE+100)
+ return nseel_createCompiledValue(ctx,0, nseel_globalregs+i-NSEEL_GLOBALVAR_BASE);
+
+ return nseel_createCompiledValue(ctx,0, NULL);
+}
+
+
+
+//------------------------------------------------------------------------------
+EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX _ctx, const char *var)
+{
+ compileContext *ctx = (compileContext *)_ctx;
+ EEL_F *r;
+ if (!ctx) return 0;
+
+ if (!strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
+ {
+ int x=atoi(var+3);
+ if (x < 0 || x > 99) x=0;
+ return nseel_globalregs + x;
+ }
+
+ register_var(ctx,var,&r);
+
+ return r;
+}
+
+//------------------------------------------------------------------------------
+INT_PTR nseel_translate(compileContext *ctx, int type)
+{
+ int v;
+ int n;
+ *ctx->yytext = 0;
+ nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
+
+ switch (type)
+ {
+ case INTCONST: return nseel_createCompiledValue(ctx,(EEL_F)atoi(ctx->yytext), NULL);
+ case DBLCONST: return nseel_createCompiledValue(ctx,(EEL_F)atof(ctx->yytext), NULL);
+ case HEXCONST:
+ v=0;
+ n=0;
+ while (1)
+ {
+ int a=ctx->yytext[n++];
+ if (a >= '0' && a <= '9') v=(v<<4)+a-'0';
+ else if (a >= 'A' && a <= 'F') v=(v<<4)+10+a-'A';
+ else if (a >= 'a' && a <= 'f') v=(v<<4)+10+a-'a';
+ else break;
+ }
+ return nseel_createCompiledValue(ctx,(EEL_F)v, NULL);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+INT_PTR nseel_lookup(compileContext *ctx, int *typeOfObject)
+{
+ int i, ti, wb;
+ const char *nptr;
+ nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
+
+ if (!strnicmp(ctx->yytext,"reg",3) && strlen(ctx->yytext) == 5 && isdigit(ctx->yytext[3]) && isdigit(ctx->yytext[4]) && (i=atoi(ctx->yytext+3))>=0 && i<100)
+ {
+ *typeOfObject=IDENTIFIER;
+ return i+NSEEL_GLOBALVAR_BASE;
+ }
+
+ i=0;
+ for (wb = 0; wb < ctx->varTable_numBlocks; wb ++)
+ {
+ int namepos=0;
+ for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++)
+ {
+ if (!ctx->varTable_Names[wb][namepos]) break;
+
+ if (!strnicmp(ctx->varTable_Names[wb]+namepos,ctx->yytext,NSEEL_MAX_VARIABLE_NAMELEN))
+ {
+ *typeOfObject = IDENTIFIER;
+ return i;
+ }
+
+ namepos += NSEEL_MAX_VARIABLE_NAMELEN;
+ i++;
+ }
+ if (ti < NSEEL_VARS_PER_BLOCK) break;
+ }
+
+
+ nptr = ctx->yytext;
+ if (!strcasecmp(nptr,"if")) nptr="_if";
+ else if (!strcasecmp(nptr,"bnot")) nptr="_not";
+ else if (!strcasecmp(nptr,"assign")) nptr="_set";
+ else if (!strcasecmp(nptr,"equal")) nptr="_equal";
+ else if (!strcasecmp(nptr,"below")) nptr="_below";
+ else if (!strcasecmp(nptr,"above")) nptr="_above";
+ else if (!strcasecmp(nptr,"megabuf")) nptr="_mem";
+ else if (!strcasecmp(nptr,"gmegabuf")) nptr="_gmem";
+ else if (!strcasecmp(nptr,"int")) nptr="floor";
+
+ for (i=0;nseel_getFunctionFromTable(i);i++)
+ {
+ functionType *f=nseel_getFunctionFromTable(i);
+ if (!strcasecmp(f->name, nptr))
+ {
+ switch (f->nParams)
+ {
+ case 1: *typeOfObject = FUNCTION1; break;
+ case 2: *typeOfObject = FUNCTION2; break;
+ case 3: *typeOfObject = FUNCTION3; break;
+ default: *typeOfObject = IDENTIFIER; break;
+ }
+ return i;
+ }
+ }
+
+ *typeOfObject = IDENTIFIER;
+ nseel_setLastVar(ctx);
+ return nseel_setVar(ctx,-1);
+}
+
+
+
+//---------------------------------------------------------------------------
+void nseel_count(compileContext *ctx)
+{
+ nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
+ ctx->colCount+=strlen(ctx->yytext);
+}
+
+//---------------------------------------------------------------------------
+int nseel_yyerror(compileContext *ctx)
+{
+ ctx->errVar = ctx->colCount;
+ return 0;
+}
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-lextab.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-lextab.c
new file mode 100644
index 00000000..9d90b769
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-lextab.c
@@ -0,0 +1,277 @@
+/*
+ Expression Evaluator Library (NS-EEL) v2
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-lextab.c
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "ns-eel-int.h"
+
+
+#define LEXSKIP (-1)
+
+static int _lmovb(struct lextab *lp, int c, int st)
+{
+ int base;
+
+ while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
+ (lp->llcheck[base] & 0377) != st) {
+
+ if (st != lp->llendst) {
+ base = lp->lldefault[st] & 0377;
+ st = base;
+ }
+ else
+ return(-1);
+ }
+ return(lp->llnext[base]&0377);
+}
+
+#define INTCONST 1
+#define DBLCONST 2
+#define HEXCONST 3
+#define VARIABLE 4
+#define OTHER 5
+
+static int _Alextab(compileContext *ctx, int __na__)
+{
+ // fucko: JF> 17 -> 19?
+
+ if (__na__ >= 0 && __na__ <= 17)
+ nseel_count(ctx);
+ switch (__na__)
+ {
+ case 0:
+ *ctx->yytext = 0;
+ nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
+ if (ctx->yytext[0] < '0' || ctx->yytext[0] > '9') // not really a hex value, lame
+ {
+ nseel_setLastVar(ctx); ctx->yylval = nseel_lookup(ctx,&__na__); return __na__;
+ }
+ ctx->yylval = nseel_translate(ctx,HEXCONST);
+ return VALUE;
+ case 1: ctx->yylval = nseel_translate(ctx,INTCONST); return VALUE;
+ case 2: ctx->yylval = nseel_translate(ctx,INTCONST); return VALUE;
+ case 3: ctx->yylval = nseel_translate(ctx,DBLCONST); return VALUE;
+ case 4:
+ case 5: nseel_setLastVar(ctx); ctx->yylval = nseel_lookup(ctx,&__na__); return __na__;
+ case 6: return '+';
+ case 7: return '-';
+ case 8: return '*';
+ case 9: return '/';
+ case 10: return '%';
+ case 11: return '&';
+ case 12: return '|';
+ case 13: return '(';
+ case 14: return ')';
+ case 15: return '=';
+ case 16: return ',';
+ case 17: return ';';
+ }
+ return (LEXSKIP);
+}
+
+
+static char _Flextab[] =
+ {
+ 1, 18, 17, 16, 15, 14, 13, 12,
+ 11, 10, 9, 8, 7, 6, 4, 5,
+ 5, 4, 4, 3, 3, 3, 3, 4,
+ 0, 4, 5, 0, 5, 4, 1, 3,
+ 0, 2, -1, 1, -1,
+ };
+
+
+static char _Nlextab[] =
+ {
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 1, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 1, 36, 36, 36, 36, 9, 8, 36,
+ 6, 5, 11, 13, 3, 12, 19, 10,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 36, 2, 36, 4, 36, 36,
+ 36, 29, 29, 29, 29, 29, 29, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 36, 36, 36, 36, 18,
+ 36, 29, 29, 29, 29, 29, 23, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 14, 18,
+ 18, 18, 18, 36, 7, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 36,
+ 36, 36, 36, 36, 36, 36, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 36, 36, 36, 36, 17, 36, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 36, 36, 36, 36, 36, 36,
+ 36, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 36, 36, 36, 36, 16,
+ 36, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 36,
+ 20, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 36, 36, 36, 36, 36,
+ 36, 36, 25, 25, 25, 25, 25, 25,
+ 36, 24, 36, 36, 36, 36, 36, 36,
+ 20, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 25, 25, 25, 25, 25, 25,
+ 36, 24, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 36, 36, 36, 36,
+ 36, 36, 36, 28, 28, 28, 28, 28,
+ 28, 36, 27, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 28, 28, 28, 28, 28,
+ 28, 31, 27, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 36, 36, 36,
+ 36, 36, 36, 36, 34, 34, 34, 33,
+ 34, 34, 36, 32, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 34, 34, 34, 33,
+ 34, 34, 36, 32, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 36, 36,
+ 36, 36, 36, 36, 36, 34, 34, 34,
+ 34, 34, 34, 36, 32, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 34, 34, 34,
+ 34, 34, 34, 36, 32,
+ };
+
+static char _Clextab[] =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 0, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, -1, -1, -1, -1, 0, 0, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -1, 0, -1, 0, -1, -1,
+ -1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -1, -1, -1, -1, 0,
+ -1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -1, 0, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, -1,
+ -1, -1, -1, -1, -1, -1, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ -1, -1, -1, -1, 14, -1, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, -1, -1, -1, -1, -1, -1,
+ -1, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, -1, -1, -1, -1, 15,
+ -1, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, -1,
+ 19, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, -1, -1, -1, -1, -1,
+ -1, -1, 23, 23, 23, 23, 23, 23,
+ -1, 23, -1, -1, -1, -1, -1, -1,
+ 19, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 23, 23, 23, 23, 23, 23,
+ -1, 23, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, -1, -1, -1, -1,
+ -1, -1, -1, 26, 26, 26, 26, 26,
+ 26, -1, 26, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 26, 26, 26, 26, 26,
+ 26, 30, 26, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, -1, -1, -1,
+ -1, -1, -1, -1, 30, 30, 30, 30,
+ 30, 30, -1, 30, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 30, 30, 30, 30,
+ 30, 30, -1, 30, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, -1, -1,
+ -1, -1, -1, -1, -1, 33, 33, 33,
+ 33, 33, 33, -1, 33, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 33, 33, 33,
+ 33, 33, 33, -1, 33,
+ };
+
+static char _Dlextab[] =
+ {
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,
+ 15, 14, 14, 36, 36, 20, 19, 14,
+ 14, 23, 15, 15, 26, 23, 36, 19,
+ 36, 36, 33, 30,
+ };
+
+static int _Blextab[] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 77, 152,
+ 0, 0, 0, 227, 237, 0, 0, 249,
+ 0, 0, 306, 0, 0, 0, 363, 0,
+ 0, 420, 0, 0, 0,
+ };
+
+struct lextab nseel_lextab = {
+ 36,
+ _Dlextab,
+ _Nlextab,
+ _Clextab,
+ _Blextab,
+ 524,
+ _lmovb,
+ _Flextab,
+ _Alextab,
+
+ 0,
+ 0,
+ 0,
+ 0,
+ };
+
+
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-ram.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-ram.c
new file mode 100644
index 00000000..d20dd449
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-ram.c
@@ -0,0 +1,320 @@
+/*
+ Expression Evaluator Library (NS-EEL) v2
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "ns-eel.h"
+#include "ns-eel-int.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#ifdef _WIN32
+#include <malloc.h>
+#endif
+
+unsigned int NSEEL_RAM_limitmem=0;
+unsigned int NSEEL_RAM_memused=0;
+int NSEEL_RAM_memused_errors=0;
+
+
+
+int NSEEL_VM_wantfreeRAM(NSEEL_VMCTX ctx)
+{
+ if (ctx)
+ {
+ compileContext *c=(compileContext*)ctx;
+ if (c->ram_needfree)
+ return 1;
+ }
+ return 0;
+}
+
+void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX ctx) // check to see if our free flag was set
+{
+ if (ctx)
+ {
+ compileContext *c=(compileContext*)ctx;
+ if (c->ram_needfree)
+ {
+ NSEEL_HOSTSTUB_EnterMutex();
+ if (c->ram_blocks)
+ {
+ INT_PTR startpos=((INT_PTR)c->ram_needfree)-1;
+ EEL_F **blocks = (EEL_F **)c->ram_blocks;
+ INT_PTR pos=0;
+ int x;
+ for (x = 0; x < NSEEL_RAM_BLOCKS; x ++)
+ {
+ if (pos >= startpos)
+ {
+ if (blocks[x])
+ {
+ if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK)
+ NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
+ else NSEEL_RAM_memused_errors++;
+ }
+ free(blocks[x]);
+ blocks[x]=0;
+ }
+ pos+=NSEEL_RAM_ITEMSPERBLOCK;
+ }
+ if (!startpos)
+ {
+ free(blocks);
+ c->ram_blocks=0;
+ }
+ }
+ c->ram_needfree=0;
+ NSEEL_HOSTSTUB_LeaveMutex();
+ }
+
+ }
+}
+
+
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAllocGMEM(EEL_F ***blocks, int w)
+{
+ static EEL_F * volatile gmembuf;
+ if (blocks) return __NSEEL_RAMAlloc(blocks,w);
+
+ if (!gmembuf)
+ {
+ NSEEL_HOSTSTUB_EnterMutex();
+ if (!gmembuf) gmembuf=(EEL_F*)calloc(sizeof(EEL_F),NSEEL_SHARED_GRAM_SIZE);
+ NSEEL_HOSTSTUB_LeaveMutex();
+
+ if (!gmembuf) return 0;
+ }
+
+ return gmembuf+(((unsigned int)w)&((NSEEL_SHARED_GRAM_SIZE)-1));
+}
+
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAMAlloc(EEL_F ***blocks, int w)
+{
+ int whichblock;
+ EEL_F **pblocks=*blocks;
+
+ int is_locked=0;
+
+ if (!pblocks)
+ {
+ if (!is_locked) { is_locked=1; NSEEL_HOSTSTUB_EnterMutex(); }
+
+ if (!(pblocks=*blocks))
+ {
+ pblocks = *blocks = (EEL_F **)calloc(sizeof(EEL_F *),NSEEL_RAM_BLOCKS);
+ if (!pblocks) {
+ if (is_locked) NSEEL_HOSTSTUB_LeaveMutex();
+ return 0;
+ }
+ }
+ }
+
+// fprintf(stderr,"got request at %d, %d\n",w/NSEEL_RAM_ITEMSPERBLOCK, w&(NSEEL_RAM_ITEMSPERBLOCK-1));
+ if (w >= 0 && (whichblock = w/NSEEL_RAM_ITEMSPERBLOCK) < NSEEL_RAM_BLOCKS)
+ {
+ EEL_F *p=pblocks[whichblock];
+ if (!p)
+ {
+ if (!is_locked) { is_locked=1; NSEEL_HOSTSTUB_EnterMutex(); }
+
+ if (!(p=pblocks[whichblock]))
+ {
+
+ const int msize=sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
+ if (!NSEEL_RAM_limitmem || NSEEL_RAM_memused+msize < NSEEL_RAM_limitmem)
+ {
+ p=pblocks[whichblock]=(EEL_F *)calloc(sizeof(EEL_F),NSEEL_RAM_ITEMSPERBLOCK);
+ if (p) NSEEL_RAM_memused+=msize;
+ }
+ if (!p) w=0;
+ }
+ }
+ if (is_locked) NSEEL_HOSTSTUB_LeaveMutex();
+ return p + (w&(NSEEL_RAM_ITEMSPERBLOCK-1));
+ }
+ if (is_locked) NSEEL_HOSTSTUB_LeaveMutex();
+// fprintf(stderr,"ret 0\n");
+ return 0;
+}
+
+
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemFree(EEL_F ***blocks, EEL_F *which)
+{
+ int d=EEL_F2int(*which);
+ if (d < 0) d=0;
+ if (d < NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) ((INT_PTR *)blocks)[1]=1+d;
+ return which;
+}
+
+
+
+
+
+
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemCpy(EEL_F ***blocks,EEL_F *dest, EEL_F *src, EEL_F *lenptr)
+{
+ int dest_offs = EEL_F2int(*dest + 0.0001);
+ int src_offs = EEL_F2int(*src + 0.0001);
+ int len = EEL_F2int(*lenptr + 0.0001);
+
+ // trim to front
+ if (src_offs<0)
+ {
+ len += src_offs;
+ dest_offs -= src_offs;
+ src_offs=0;
+ }
+ if (dest_offs<0)
+ {
+ len += dest_offs;
+ src_offs -= dest_offs;
+ dest_offs=0;
+ }
+
+ while (len > 0)
+ {
+ EEL_F *srcptr,*destptr;
+ int copy_len = len;
+ int maxdlen=NSEEL_RAM_ITEMSPERBLOCK - (dest_offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
+ int maxslen=NSEEL_RAM_ITEMSPERBLOCK - (src_offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
+
+ if (dest_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK ||
+ src_offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) break;
+
+ if (copy_len > maxdlen) copy_len=maxdlen;
+ if (copy_len > maxslen) copy_len=maxslen;
+
+ if (copy_len<1) break;
+
+ srcptr = __NSEEL_RAMAlloc(blocks,src_offs);
+ destptr = __NSEEL_RAMAlloc(blocks,dest_offs);
+ if (!srcptr || !destptr) break;
+
+ memmove(destptr,srcptr,sizeof(EEL_F)*copy_len);
+ src_offs+=copy_len;
+ dest_offs+=copy_len;
+ len-=copy_len;
+ }
+ return dest;
+}
+
+EEL_F * NSEEL_CGEN_CALL __NSEEL_RAM_MemSet(EEL_F ***blocks,EEL_F *dest, EEL_F *v, EEL_F *lenptr)
+{
+ int offs = EEL_F2int(*dest + 0.0001);
+ int len = EEL_F2int(*lenptr + 0.0001);
+ EEL_F t;
+ if (offs<0)
+ {
+ len += offs;
+ offs=0;
+ }
+ if (offs >= NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) return dest;
+
+ if (offs+len > NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK) len = NSEEL_RAM_BLOCKS*NSEEL_RAM_ITEMSPERBLOCK - offs;
+
+ if (len < 1) return dest;
+
+
+ t=*v; // set value
+
+// int lastBlock=-1;
+ while (len > 0)
+ {
+ int lcnt;
+ EEL_F *ptr=__NSEEL_RAMAlloc(blocks,offs);
+ if (!ptr) break;
+
+ lcnt=NSEEL_RAM_ITEMSPERBLOCK-(offs&(NSEEL_RAM_ITEMSPERBLOCK-1));
+ if (lcnt > len) lcnt=len;
+
+ len -= lcnt;
+ offs += lcnt;
+
+ while (lcnt--)
+ {
+ *ptr++=t;
+ }
+ }
+ return dest;
+}
+
+
+void NSEEL_VM_SetGRAM(NSEEL_VMCTX ctx, void **gram)
+{
+ if (ctx)
+ {
+ compileContext *c=(compileContext*)ctx;
+ c->gram_blocks = gram;
+ }
+}
+
+
+void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx)
+{
+ if (ctx)
+ {
+ int x;
+ compileContext *c=(compileContext*)ctx;
+ if (c->ram_blocks)
+ {
+ EEL_F **blocks = (EEL_F **)c->ram_blocks;
+ for (x = 0; x < NSEEL_RAM_BLOCKS; x ++)
+ {
+ if (blocks[x])
+ {
+ if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK)
+ NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
+ else NSEEL_RAM_memused_errors++;
+ }
+ free(blocks[x]);
+ blocks[x]=0;
+ }
+ free(blocks);
+ c->ram_blocks=0;
+ }
+ c->ram_needfree=0; // no need to free anymore
+ }
+}
+
+void NSEEL_VM_FreeGRAM(void **ufd)
+{
+ if (ufd[0])
+ {
+ EEL_F **blocks = (EEL_F **)ufd[0];
+ int x;
+ for (x = 0; x < NSEEL_RAM_BLOCKS; x ++)
+ {
+ if (blocks[x])
+ {
+ if (NSEEL_RAM_memused >= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK)
+ NSEEL_RAM_memused -= sizeof(EEL_F) * NSEEL_RAM_ITEMSPERBLOCK;
+ else NSEEL_RAM_memused_errors++;
+ }
+ free(blocks[x]);
+ blocks[x]=0;
+ }
+ free(blocks);
+ ufd[0]=0;
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-yylex.c b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-yylex.c
new file mode 100644
index 00000000..605b4776
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/ns-eel2/nseel-yylex.c
@@ -0,0 +1,163 @@
+/*
+ Expression Evaluator Library (NS-EEL)
+ Copyright (C) 2004-2008 Cockos Incorporated
+ Copyright (C) 1999-2003 Nullsoft, Inc.
+
+ nseel-yylex.c
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "ns-eel-int.h"
+
+
+#define NBPW 16
+#define EOF (-1)
+
+
+#define YYERRORVAL 256 /* yacc's value */
+
+static int llset(compileContext *ctx);
+static int llinp(compileContext *ctx, char **exp);
+static int lexgetc(char **exp)
+{
+ char c= **exp;
+ if (c) (*exp)++;
+ return( c != 0 ? c : -1);
+}
+static int tst__b(register int c, char tab[])
+{
+ return (tab[(c >> 3) & 037] & (1 << (c & 07)) );
+}
+
+int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz)
+{
+ register char *lp, *tp, *ep;
+
+ tp = lltb;
+ ep = tp+lltbsiz-1;
+ for (lp = ctx->llbuf; lp < ctx->llend && tp < ep;)
+ *tp++ = *lp++;
+ *tp = 0;
+ return(tp-lltb);
+}
+
+
+int nseel_yylex(compileContext *ctx, char **exp)
+{
+ register int c, st;
+ int final, l, llk, i;
+ register struct lextab *lp;
+ char *cp;
+
+ while (1)
+ {
+ llk = 0;
+ if (llset(ctx)) return(0);
+ st = 0;
+ final = -1;
+ lp = &nseel_lextab;
+
+ do {
+ if (lp->lllook && (l = lp->lllook[st])) {
+ for (c=0; c<NBPW; c++)
+ if (l&(1<<c))
+ ctx->llsave[c] = ctx->llp1;
+ llk++;
+ }
+ if ((i = lp->llfinal[st]) != -1) {
+ final = i;
+ ctx->llend = ctx->llp1;
+ }
+ if ((c = llinp(ctx,exp)) < 0)
+ break;
+ if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
+ ctx->llp1--;
+ break;
+ }
+ } while ((st = (*lp->llmove)(lp, c, st)) != -1);
+
+
+ if (ctx->llp2 < ctx->llp1)
+ ctx->llp2 = ctx->llp1;
+ if (final == -1) {
+ ctx->llend = ctx->llp1;
+ if (st == 0 && c < 0)
+ return(0);
+ if ((cp = lp->llill) && tst__b(c, cp)) {
+ continue;
+ }
+ return(YYERRORVAL);
+ }
+ if ((c = (final >> 11) & 037))
+ ctx->llend = ctx->llsave[c-1];
+ if ((c = (*lp->llactr)(ctx,final&03777)) >= 0)
+ return(c);
+ }
+}
+
+void nseel_llinit(compileContext *ctx)
+{
+ ctx->llp1 = ctx->llp2 = ctx->llend = ctx->llbuf;
+ ctx->llebuf = ctx->llbuf + sizeof(ctx->llbuf);
+ ctx->lleof = ctx->yyline = 0;
+}
+
+
+static int llinp(compileContext *ctx, char **exp)
+{
+ register int c;
+ register struct lextab *lp;
+ register char *cp;
+
+ lp = &nseel_lextab;
+ cp = lp->llign; /* Ignore class */
+ for (;;) {
+ /*
+ * Get the next character from the save buffer (if possible)
+ * If the save buffer's empty, then return EOF or the next
+ * input character. Ignore the character if it's in the
+ * ignore class.
+ */
+ c = (ctx->llp1 < ctx->llp2) ? *ctx->llp1 & 0377 : (ctx->lleof) ? EOF : lexgetc(exp);
+ if (c >= 0) { /* Got a character? */
+ if (cp && tst__b(c, cp))
+ continue; /* Ignore it */
+ if (ctx->llp1 >= ctx->llebuf) { /* No, is there room? */
+ return -1;
+ }
+ *ctx->llp1++ = c; /* Store in token buff */
+ } else
+ ctx->lleof = 1; /* Set EOF signal */
+ return(c);
+ }
+}
+
+static int llset(compileContext *ctx)
+/*
+ * Return TRUE if EOF and nothing was moved in the look-ahead buffer
+ */
+{
+ register char *lp1, *lp2;
+
+ for (lp1 = ctx->llbuf, lp2 = ctx->llend; lp2 < ctx->llp2;)
+ *lp1++ = *lp2++;
+ ctx->llend = ctx->llp1 = ctx->llbuf;
+ ctx->llp2 = lp1;
+ return(ctx->lleof && lp1 == ctx->llbuf);
+}
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin.cpp b/Src/Plugins/Visualization/vis_milk2/plugin.cpp
new file mode 100644
index 00000000..e3d66a39
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin.cpp
@@ -0,0 +1,9653 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*
+ ##########################################################################################
+
+ NOTE:
+
+ The DX9 SDK include & lib files for building MilkDrop 2 are right here, in the subdirectory:
+ .\dx9sdk_summer04\
+
+ The summer 2004 SDK statically links you to d3dx9.lib (5,820 kb). It bloats vis_milk2.dll
+ a bit, but we (Ben Allison / Ryan Geiss) decided it's worth the stability. We tinkered
+ with using the February 2005 sdk, which lets you dynamically link to d3dx9_31.dll (?),
+ but decided to skip it because it would cause too much hassle/confusion among users.
+
+ Summer 2004 sdk: http://www.microsoft.com/downloads/details.aspx?FamilyID=fd044a42-9912-42a3-9a9e-d857199f888e&DisplayLang=en
+ Feb 2005 sdk: http://www.microsoft.com/downloads/details.aspx?FamilyId=77960733-06E9-47BA-914A-844575031B81&displaylang=en
+
+ ##########################################################################################
+*/
+
+/*
+Order of Function Calls
+-----------------------
+ The only code that will be called by the plugin framework are the
+ 12 virtual functions in plugin.h. But in what order are they called?
+ A breakdown follows. A function name in { } means that it is only
+ called under certain conditions.
+
+ Order of function calls...
+
+ When the PLUGIN launches
+ ------------------------
+ INITIALIZATION
+ OverrideDefaults
+ MyPreInitialize
+ MyReadConfig
+ << DirectX gets initialized at this point >>
+ AllocateMyNonDx9Stuff
+ AllocateMyDX9Stuff
+ RUNNING
+ +--> { CleanUpMyDX9Stuff + AllocateMyDX9Stuff } // called together when user resizes window or toggles fullscreen<->windowed.
+ | MyRenderFn
+ | MyRenderUI
+ | { MyWindowProc } // called, between frames, on mouse/keyboard/system events. 100% threadsafe.
+ +----<< repeat >>
+ CLEANUP
+ CleanUpMyDX9Stuff
+ CleanUpMyNonDx9Stuff
+ << DirectX gets uninitialized at this point >>
+
+ When the CONFIG PANEL launches
+ ------------------------------
+ INITIALIZATION
+ OverrideDefaults
+ MyPreInitialize
+ MyReadConfig
+ << DirectX gets initialized at this point >>
+ RUNNING
+ { MyConfigTabProc } // called on startup & on keyboard events
+ CLEANUP
+ [ MyWriteConfig ] // only called if user clicked 'OK' to exit
+ << DirectX gets uninitialized at this point >>
+*/
+
+/*
+ NOTES
+ -----
+
+
+
+ To do
+ -----
+ -VMS VERSION:
+ -based on vms 1.05, but the 'fix slow text' option has been added.
+ that includes m_lpDDSText, CTextManager (m_text), changes to
+ DrawDarkTranslucentBox, the replacement of all DrawText calls
+ (now routed through m_text), and adding the 'fix slow text' cb
+ to the config panel.
+
+ -KILLED FEATURES:
+ -vj mode
+
+ -NEW FEATURES FOR 1.04:
+ -added the following variables for per-frame scripting: (all booleans, except 'gamma')
+ wave_usedots, wave_thick, wave_additive, wave_brighten
+ gamma, darken_center, wrap, invert, brighten, darken, solarize
+ (also, note that echo_zoom, echo_alpha, and echo_orient were already in there,
+ but weren't covered in the documentation!)
+ d -fixed: spectrum w/512 samples + 256 separation -> infinite spike
+ d -reverted dumb changes to aspect ratio stuff
+ d -reverted wave_y fix; now it's backwards, just like it's always been
+ (i.e. for wave's y position, 0=bottom and 1=top, which is opposite
+ to the convention in the rest of milkdrop. decided to keep the
+ 'bug' so presets don't need modified.)
+ d -fixed: Krash: Inconsistency bug - pressing Escape while in the code windows
+ for custom waves completely takes you out of the editing menus,
+ rather than back to the custom wave menu
+ d -when editing code: fix display of '&' character
+ d -internal texture size now has a little more bias toward a finer texture,
+ based on the window size, when set to 'Auto'. (Before, for example,
+ to reach 1024x1024, the window had to be 768x768 or greater; now, it
+ only has to be 640x640 (25% of the way there). I adjusted it because
+ before, at in-between resolutions like 767x767, it looked very grainy;
+ now it will always look nice and crisp, at any window size, but still
+ won't cause too much aliasing (due to downsampling for display).
+ d -fixed: rova:
+ When creating presets have commented code // in the per_pixel section when cause error in preset.
+ Example nothing in per_frame and just comments in the per_pixel. EXamples on repuest I have a few.
+ d -added kill keys:
+ -CTRL+K kills all running sprites
+ -CTRL+T kills current song title anim
+ -CTRL+Y kills current custom message
+ d -notice to sprite users:
+ -in milk_img.ini, color key can't be a range anymore; it's
+ now limited to just a single color. 'colorkey_lo' and
+ 'colorkey_hi' have been replaced with just one setting,
+ 'colorkey'.
+ d -song titles + custom messages are working again
+ ? -fixed?: crashes on window resize [out of mem]
+ -Rova: BTW the same bug as krash with the window resizing.
+ -NOT due to the 'integrate w/winamp' option.
+ -> might be fixed now (had forgotten to release m_lpDDSText)
+ <AFTER BETA 3..>
+ d -added checkbox to config screen to automatically turn SCROLL LOCK on @ startup
+ d -added alphanumeric seeking to the playlist; while playlist is up,
+ you can now press A-Z and 0-9 to seek to the next song in the playlist
+ that starts with that character.
+ d -<fixed major bug w/illegal mem access on song title launches;
+ could have been causing crashing madness @ startup on many systems>
+ d -<fixed bug w/saving 64x48 mesh size>
+ d -<fixed squashed shapes>
+ d -<fixed 'invert' variable>
+ d -<fixed squashed song titles + custom msgs>
+ ? -<might have fixed scroll lock stuff>
+ ? -<might have fixed crashing; could have been due to null ptr for failed creation of song title texture.>
+ ? -<also might have solved any remaining resize or exit bugs by callign SetTexture(NULL)
+ in DX8 cleanup.>
+ d -<fixed sizing issues with songtitle font.>
+ d -<fixed a potentially bogus call to deallocate memory on exit, when it was cleaning up the menus.>
+ d -<fixed more scroll lock issues>
+ d -<fixed broken Noughts & Crosses presets; max # of per-frame vars was one too few, after the additions of the new built-in variables.>
+ d -<hopefully fixed waveforms>
+ <AFTER BETA 4>
+ -now when playlist is up, SHIFT+A-Z seeks upward (while lowercase/regular a-z seeks downward).
+ -custom shapes:
+ -OH MY GOD
+ -increased max. # of custom shapes (and waves) from 3 to 4
+ -added 'texture' option, which allows you to use the last frame as a texture on the shape
+ -added "tex_ang" and "tex_zoom" params to control the texture coords
+ -each frame, custom shapes now draw BEFORE regular waveform + custom waves
+ -added init + per-frame vars: "texture", "additive", "thick", "tex_ang", "tex_zoom"
+ -fixed valid characters for filenames when importing/exporting custom shapes/waves;
+ also, it now gives error messages on error in import/export.
+ -cranked max. meshsize up to 96x72
+ -Krash, Rova: now the 'q' variables, as modified by the preset per-frame equations, are again
+ readable by the custom waves + custom shapes. Sorry about that. Should be the end of the
+ 'q' confusion.
+ -added 'meshx' and 'meshy' [read-only] variables to the preset init, per-frame, and per-pixel
+ equations (...and inc'd the size of the global variable pool by 2).
+ -removed t1-t8 vars for Custom Shapes; they were unnecessary (since there's no per-point code there).
+ -protected custom waves from trying to draw when # of sample minus the separation is < 2
+ (or 1 if drawing with dots)
+ -fixed some [minor] preset-blending bugs in the custom wave code
+ -created a visual map for the flow of values for the q1-q8 and t1-t8 variables:
+ q_and_t_vars.gif (or something).
+ -fixed clipping of onscreen text in low-video-memory situations. Now, if there isn't enough
+ video memory to create an offscreen texture that is at least 75% of the size of the
+ screen (or to create at least a 256x256 one), it won't bother using one, and will instead draw text directly to the screen.
+ Otherwise, if the texture is from 75%-99% of the screen size, text will now at least
+ appear in the correct position on the screen so that it will be visible; this will mean
+ that the right- and bottom-aligned text will no longer be fully right/bottom-aligned
+ to the edge of the screen.
+ -fixed blurry text
+ -VJ mode is partially restored; the rest will come with beta 7 or the final release. At the time of beta 6, VJ mode still has some glitches in it, but I'm working on them. Most notably, it doesn't resize the text image when you resize the window; that's next on my list.
+ <AFTER BETA 6:>
+ -now sprites can burn-in on any frame, not just on the last frame.
+ set 'burn' to one (in the sprite code) on any frame to make it burn in.
+ this will break some older sprites, but it's super easy to fix, and
+ I think it's worth it. =) thanks to papaw00dy for the suggestion!
+ -fixed the asymptotic-value bug with custom waves using spectral data & having < 512 samples (thanks to telek's example!)
+ -fixed motion vectors' reversed Y positioning.
+ -fixed truncation ("...") of long custom messages
+ -fixed that pesky bug w/the last line of code on a page
+ -fixed the x-positioning of custom waves & shapes. Before, if you were
+ saving some coordinates from the preset's per-frame equations (say in q1 and q2)
+ and then you set "x = q1; y = q2;" in a custom shape's per-frame code
+ (or in a custom wave's per-point code), the x position wouldn't really be
+ in the right place, because of aspect ratio multiplications. Before, you had
+ to actually write "x = (q1-0.5)*0.75 + 0.5; y = q2;" to get it to line up;
+ now it's fixed, though, and you can just write "x = q1; y = q2;".
+ -fixed some bugs where the plugin start up, in windowed mode, on the wrong window
+ (and hence run super slow).
+ -fixed some bugs w/a munged window frame when the "integrate with winamp" option
+ was checked.
+ <AFTER BETA 7:>
+ -preset ratings are no longer read in all at once; instead, they are scanned in
+ 1 per frame until they're all in. This fixes the long pauses when you switch
+ to a directory that has many hundreds of presets. If you want to switch
+ back to the old way (read them all in at once), there is an option for it
+ in the config panel.
+ -cranked max. mesh size up to 128x96
+ -fixed bug in custom shape per-frame code, where t1-t8 vars were not
+ resetting, at the beginning of each frame, to the values that they had
+ @ the end of the custom shape init code's execution.
+ -
+ -
+ -
+
+
+ beta 2 thread: http://forums.winamp.com/showthread.php?threadid=142635
+ beta 3 thread: http://forums.winamp.com/showthread.php?threadid=142760
+ beta 4 thread: http://forums.winamp.com/showthread.php?threadid=143500
+ beta 6 thread: http://forums.winamp.com/showthread.php?threadid=143974
+ (+read about beat det: http://forums.winamp.com/showthread.php?threadid=102205)
+
+@ -code editing: when cursor is on 1st posn. in line, wrong line is highlighted!?
+ -requests:
+ -random sprites (...they can just write a prog for this, tho)
+ -Text-entry mode.
+ -Like your favorite online game, hit T or something to enter 'text entry' mode. Type a message, then either hit ESC to clear and cancel text-entry mode, or ENTER to display the text on top of the vis. Easier for custom messages than editing the INI file (and probably stopping or minimizing milkdrop to do it) and reloading.
+ -OR SKIP IT; EASY TO JUST EDIT, RELOAD, AND HIT 00.
+ -add 'AA' parameter to custom message text file?
+ -when mem is low, fonts get kicked out -> white boxes
+ -probably happening b/c ID3DXFont can't create a
+ temp surface to use to draw text, since all the
+ video memory is gobbled up.
+* -add to installer: q_and_t_vars.gif
+* -presets:
+ 1. pick final set
+ a. OK-do a pass weeding out slow presets (crank mesh size up)
+ b. OK-do 2nd pass; rate them & delete crappies
+ c. OK-merge w/set from 1.03; check for dupes; delete more suckies
+ 2. OK-check for cpu-guzzlers
+ 3. OK-check for big ones (>= 8kb)
+ 4. check for ultra-spastic-when-audio-quiet ones
+ 5. update all ratings
+ 6. zip 'em up for safekeeping
+* -docs:
+ -link to milkdrop.co.uk
+ -preset authoring:
+ -there are 11 variable pools:
+ preset:
+ a) preset init & per-frame code
+ b) preset per-pixel code
+ custom wave 1:
+ c) init & per-frame code
+ d) per-point code
+ custom wave 2:
+ e) init & per-frame code
+ f) per-point code
+ custom wave 3:
+ g) init & per-frame code
+ h) per-point code
+ i) custom shape 1: init & per-frame code
+ j) custom shape 2: init & per-frame code
+ k) custom shape 3: init & per-frame code
+
+ -all of these have predefined variables, the values of many of which
+ trickle down from init code, to per-frame code, to per-pixel code,
+ when the same variable is defined for each of these.
+ -however, variables that you define ("my_var = 5;") do NOT trickle down.
+ To allow you to pass custom values from, say, your per-frame code
+ to your per-pixel code, the variables q1 through q8 were created.
+ For custom waves and custom shapes, t1 through t8 work similarly.
+ -q1-q8:
+ -purpose: to allow [custom] values to carry from {the preset init
+ and/or per-frame equations}, TO: {the per-pixel equations},
+ {custom waves}, and {custom shapes}.
+ -are first set in preset init code.
+ -are reset, at the beginning of each frame, to the values that
+ they had at the end of the preset init code.
+ -can be modified in per-frame code...
+ -changes WILL be passed on to the per-pixel code
+ -changes WILL pass on to the q1-q8 vars in the custom waves
+ & custom shapes code
+ -changes will NOT pass on to the next frame, though;
+ use your own (custom) variables for that.
+ -can be modified in per-pixel code...
+ -changes will pass on to the next *pixel*, but no further
+ -changes will NOT pass on to the q1-q8 vars in the custom
+ waves or custom shapes code.
+ -changes will NOT pass on to the next frame, after the
+ last pixel, though.
+ -CUSTOM SHAPES: q1-q8...
+ -are readable in both the custom shape init & per-frame code
+ -start with the same values as q1-q8 had at the end of the *preset*
+ per-frame code, this frame
+ -can be modified in the init code, but only for a one-time
+ pass-on to the per-frame code. For all subsequent frames
+ (after the first), the per-frame code will get the q1-q8
+ values as described above.
+ -can be modified in the custom shape per-frame code, but only
+ as temporary variables; the changes will not pass on anywhere.
+ -CUSTOM WAVES: q1-q8...
+ -are readable in the custom wave init, per-frame, and per-point code
+ -start with the same values as q1-q8 had at the end of the *preset*
+ per-frame code, this frame
+ -can be modified in the init code, but only for a one-time
+ pass-on to the per-frame code. For all subsequent frames
+ (after the first), the per-frame code will get the q1-q8
+ values as described above.
+ -can be modified in the custom wave per-frame code; changes will
+ pass on to the per-point code, but that's it.
+ -can be modified in the per-point code, and the modified values
+ will pass on from point to point, but won't carry beyond that.
+ -CUSTOM WAVES: t1-t8...
+ -allow you to generate & save values in the custom wave init code,
+ that can pass on to the per-frame and, more sigificantly,
+ per-point code (since it's in a different variable pool).
+ -...
+
+
+
+ !-whatever the values of q1-q8 were at the end of the per-frame and per-pixel
+ code, these are copied to the q1-q8 variables in the custom wave & custom
+ shape code, for that frame. However, those values are separate.
+ For example, if you modify q1-q8 in the custom wave #1 code, those changes
+ will not be visible anywhere else; if you modify q1-q8 in the custom shape
+ #2 code, same thing. However, if you modify q1-q8 in the per-frame custom
+ wave code, those modified values WILL be visible to the per-point custom
+ wave code, and can be modified within it; but after the last point,
+ the values q1-q8 will be discarded; on the next frame, in custom wave #1
+ per-frame code, the values will be freshly copied from the values of the
+ main q1-q8 after the preset's per-frame and per-point code have both been
+ executed.
+ -monitor:
+ -can be read/written in preset init code & preset per-frame code.
+ -not accessible from per-pixel code.
+ -if you write it on one frame, then that value persists to the next frame.
+ -t1-t8:
+ -
+ -
+ -
+ -regular docs:
+ -put in the stuff recommended by VMS (vidcap, etc.)
+ -add to troubleshooting:
+ 1) desktop mode icons not appearing? or
+ onscreen text looking like colored boxes?
+ -> try freeing up some video memory. lower your res; drop to 16 bit;
+ etc. TURN OFF AUTO SONGTITLES.
+ 1) slow desktop/fullscr mode? -> try disabling auto songtitles + desktop icons.
+ also try reducing texsize to 256x256, since that eats memory that the text surface could claim.
+ 2)
+ 3)
+ * -presets:
+ -add new
+ -fix 3d presets (bring gammas back down to ~1.0)
+ -check old ones, make sure they're ok
+ -"Rovastar - Bytes"
+ -check wave_y
+ * -document custom waves & shapes
+ * -slow text is mostly fixed... =(
+ -desktop icons + playlist both have begin/end around them now, but in desktop mode,
+ if you bring up playlist or Load menu, fps drops in half; press Esc, and fps doesn't go back up.
+ -
+ -
+ -
+ -DONE / v1.04:
+ -updated to VMS 1.05
+ -[list benefits...]
+ -
+ -
+ -3d mode:
+ a) SWAPPED DEFAULT L/R LENS COLORS! All images on the web are left=red, right=blue!
+ b) fixed image display when viewing a 3D preset in a non-4:3 aspect ratio window
+ c) gamma now works for 3d presets! (note: you might have to update your old presets.
+ if they were 3D presets, the gamma was ignored and 1.0 was used; now,
+ if gamma was >1.0 in the old preset, it will probably appear extremely bright.)
+ d) added SHIFT+F9 and CTRL+C9 to inc/dec stereo separation
+ e) added default stereo separation to config panel
+ -cranked up the max. mesh size (was 48x36, now 64x48) and the default mesh size
+ (was 24x18, now 32x24)
+ -fixed aspect ratio for final display
+ -auto-texsize is now computed slightly differently; for vertically or horizontally-stretched
+ windows, the texsize is now biased more toward the larger dimension (vs. just the
+ average).
+ -added anisotropic filtering (for machines that support it)
+ -fixed bug where the values of many variables in the preset init code were not set prior
+ to execution of the init code (e.g. time, bass, etc. were all broken!)
+ -added various preset blend effects. In addition to the old uniform fade, there is
+ now a directional wipe, radial wipe, and plasma fade.
+ -FIXED SLOW TEXT for DX8 (at least, on the geforce 4).
+ Not using DT_RIGHT or DT_BOTTOM was the key.
+
+
+ -why does text kill it in desktop mode?
+ -text is SLOOW
+ -to do: add (and use) song title font + tooltip font
+ -re-test: menus, text, boxes, etc.
+ -re-test: TIME
+ -testing:
+ -make sure sound works perfectly. (had to repro old pre-vms sound analysis!)
+ -autogamma: currently assumes/requires that GetFrame() resets to 0 on a mode change
+ (i.e. windowed -> fullscreen)... is that the case?
+ -restore motion vectors
+ -
+ -
+ -restore lost surfaces
+ -test bRedraw flag (desktop mode/paused)
+ -search for //? in milkdropfs.cpp and fix things
+
+ problem: no good soln for VJ mode
+ problem: D3DX won't give you solid background for your text.
+ soln: (for later-) create wrapper fn that draws w/solid bkg.
+
+ SOLN?: use D3DX to draw all text (plugin.cpp stuff AND playlist);
+ then, for VJ mode, create a 2nd DxContext
+ w/its own window + windowproc + fonts. (YUCK)
+ 1) config panel: test, and add WM_HELP's (copy from tooltips)
+ 2) keyboard input: test; and...
+ -need to reset UI_MODE when playlist is turned on, and
+ -need to reset m_show_playlist when UI_MODE is changed. (?)
+ -(otherwise they can both show @ same time and will fight
+ for keys and draw over each other)
+ 3) comment out most of D3D stuff in milkdropfs.cpp, and then
+ get it running w/o any milkdrop, but with text, etc.
+ 4) sound
+
+ Issues / To Do Later
+ --------------------
+ 1) sprites: color keying stuff probably won't work any more...
+ 2) scroll lock: pull code from Monkey
+ 3) m_nGridY should not always be m_nGridX*3/4!
+ 4) get solid backgrounds for menus, waitstring code, etc.
+ (make a wrapper function!)
+
+ 99) at end: update help screen
+
+ Things that will be different
+ -----------------------------
+ 1) font sizes are no longer relative to size of window; they are absolute.
+ 2) 'don't clear screen at startup' option is gone
+ 3) 'always on top' option is gone
+ 4) text will not be black-on-white when an inverted-color preset is showing
+
+ -VJ mode:
+ -notes
+ 1. (remember window size/pos, and save it from session to session? nah.)
+ 2. (kiv: scroll lock)
+ 3. (VJ window + desktop mode:)
+ -ok w/o VJ mode
+ -w/VJ mode, regardless of 'fix slow text' option, probs w/focus;
+ click on vj window, and plugin window flashes to top of Z order!
+ -goes away if you comment out 1st call to PushWindowToJustBeforeDesktop()...
+ -when you disable PushWindowToJustBeforeDesktop:
+ -..and click on EITHER window, milkdrop jumps in front of the taskbar.
+ -..and click on a non-MD window, nothing happens.
+ d-FIXED somehow, magically, while fixing bugs w/true fullscreen mode!
+ 4. (VJ window + true fullscreen mode:)
+ d-make sure VJ window gets placed on the right monitor, at startup,
+ and respects taskbar posn.
+ d-bug - start in windowed mode, then dbl-clk to go [true] fullscreen
+ on 2nd monitor, all with VJ mode on, and it excepts somewhere
+ in m_text.DrawNow() in a call to DrawPrimitive()!
+ FIXED - had to check m_vjd3d8_device->TestCooperativeLevel
+ each frame, and destroy/reinit if device needed reset.
+ d-can't resize VJ window when grfx window is running true fullscreen!
+ -FIXED, by dropping the Sleep(30)/return when m_lost_focus
+ was true, and by not consuming WM_NCACTIVATE in true fullscreen
+ mode when m_hTextWnd was present, since DX8 doesn't do its
+ auto-minimize thing in that case.
+
+
+
+*/
+
+#include "api__vis_milk2.h"
+#include "plugin.h"
+#include "utility.h"
+#include "support.h"
+#include "resource.h"
+#include "defines.h"
+#include "shell_defines.h"
+#include <assert.h>
+#include <locale.h>
+#include <process.h> // for beginthread, etc.
+#include <shellapi.h>
+#include <strsafe.h>
+#include "../nu/AutoCharFn.h"
+
+#define FRAND ((warand() % 7381)/7380.0f)
+
+void NSEEL_HOSTSTUB_EnterMutex(){}
+void NSEEL_HOSTSTUB_LeaveMutex(){}
+
+// note: these must match layouts in support.h!!
+D3DVERTEXELEMENT9 g_MyVertDecl[] =
+{
+ { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
+ { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
+ { 0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
+ { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
+ D3DDECL_END()
+};
+D3DVERTEXELEMENT9 g_WfVertDecl[] =
+{
+ { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
+ { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
+ D3DDECL_END()
+};
+D3DVERTEXELEMENT9 g_SpriteVertDecl[] =
+{
+ // matches D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1
+ { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
+ { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
+ { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
+ D3DDECL_END()
+};
+
+//extern CSoundData* pg_sound; // declared in main.cpp
+extern CPlugin g_plugin; // declared in main.cpp (note: was 'pg')
+
+// from support.cpp:
+extern bool g_bDebugOutput;
+extern bool g_bDumpFileCleared;
+
+// for __UpdatePresetList:
+volatile HANDLE g_hThread; // only r/w from our MAIN thread
+volatile bool g_bThreadAlive; // set true by MAIN thread, and set false upon exit from 2nd thread.
+volatile int g_bThreadShouldQuit; // set by MAIN thread to flag 2nd thread that it wants it to exit.
+static CRITICAL_SECTION g_cs;
+
+#define IsAlphabetChar(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z'))
+#define IsAlphanumericChar(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || (x >= '0' && x <= '9') || x == '.')
+#define IsNumericChar(x) (x >= '0' && x <= '9')
+
+const unsigned char LC2UC[256] = {
+ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
+ 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,255,
+ 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
+ 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
+ 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
+ 113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,96,
+ 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
+ 113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
+ 129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,
+ 145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,
+ 161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
+ 177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
+ 193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,
+ 209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
+ 225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,
+ 241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
+};
+
+/*
+ * Copies the given string TO the clipboard.
+ */
+void copyStringToClipboardA(const char * source)
+{
+ int ok = OpenClipboard(NULL);
+ if (!ok)
+ return;
+
+ HGLOBAL clipbuffer;
+ EmptyClipboard();
+ clipbuffer = GlobalAlloc(GMEM_DDESHARE, (lstrlenA(source)+1)*sizeof(char));
+ char* buffer = (char*)GlobalLock(clipbuffer);
+ lstrcpyA(buffer, source);
+ GlobalUnlock(clipbuffer);
+ SetClipboardData(CF_TEXT, clipbuffer);
+ CloseClipboard();
+}
+
+void copyStringToClipboardW(const wchar_t * source)
+{
+ int ok = OpenClipboard(NULL);
+ if (!ok)
+ return;
+
+ HGLOBAL clipbuffer;
+ EmptyClipboard();
+ clipbuffer = GlobalAlloc(GMEM_DDESHARE, (lstrlenW(source)+1)*sizeof(wchar_t));
+ wchar_t* buffer = (wchar_t*)GlobalLock(clipbuffer);
+ lstrcpyW(buffer, source);
+ GlobalUnlock(clipbuffer);
+ SetClipboardData(CF_UNICODETEXT, clipbuffer);
+ CloseClipboard();
+}
+
+/*
+ * Suppose there is a string on the clipboard.
+ * This function copies it FROM there.
+ */
+char * getStringFromClipboardA()
+{
+ int ok = OpenClipboard(NULL);
+ if (!ok)
+ return NULL;
+
+ HANDLE hData = GetClipboardData(CF_TEXT);
+ char* buffer = (char*)GlobalLock(hData);
+ GlobalUnlock(hData);
+ CloseClipboard();
+ return buffer;
+}
+
+wchar_t * getStringFromClipboardW()
+{
+ int ok = OpenClipboard(NULL);
+ if (!ok)
+ return NULL;
+
+ HANDLE hData = GetClipboardData(CF_UNICODETEXT);
+ wchar_t* buffer = (wchar_t*)GlobalLock(hData);
+ GlobalUnlock(hData);
+ CloseClipboard();
+ return buffer;
+}
+
+void ConvertCRsToLFCA(const char* src, char* dst)
+{
+ while (*src)
+ {
+ char ch = *src;
+ if (*src==13 && *(src+1)==10)
+ {
+ *dst++ = LINEFEED_CONTROL_CHAR;
+ src += 2;
+ }
+ else
+ {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
+void ConvertCRsToLFCW(const wchar_t* src, wchar_t* dst)
+{
+ while (*src)
+ {
+ wchar_t ch = *src;
+ if (*src==13 && *(src+1)==10)
+ {
+ *dst++ = LINEFEED_CONTROL_CHAR;
+ src += 2;
+ }
+ else
+ {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
+void ConvertLFCToCRsA(const char* src, char* dst)
+{
+ while (*src)
+ {
+ char ch = *src;
+ if (*src==LINEFEED_CONTROL_CHAR)
+ {
+ *dst++ = 13;
+ *dst++ = 10;
+ src++;
+ }
+ else
+ {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
+void ConvertLFCToCRsW(const wchar_t* src, wchar_t* dst)
+{
+ while (*src)
+ {
+ wchar_t ch = *src;
+ if (*src==LINEFEED_CONTROL_CHAR)
+ {
+ *dst++ = 13;
+ *dst++ = 10;
+ src++;
+ }
+ else
+ {
+ *dst++ = *src++;
+ }
+ }
+ *dst = 0;
+}
+
+int mystrcmpiW(const wchar_t *s1, const wchar_t *s2)
+{
+ // returns 1 if s1 comes before s2
+ // returns 0 if equal
+ // returns -1 if s1 comes after s2
+ // treats all characters/symbols by their ASCII values,
+ // except that it DOES ignore case.
+
+ int i=0;
+
+ while (LC2UC[s1[i]] == LC2UC[s2[i]] && s1[i] != 0)
+ i++;
+
+ //FIX THIS!
+
+ if (s1[i]==0 && s2[i]==0)
+ return 0;
+ else if (s1[i]==0)
+ return -1;
+ else if (s2[i]==0)
+ return 1;
+ else
+ return (LC2UC[s1[i]] < LC2UC[s2[i]]) ? -1 : 1;
+}
+
+bool ReadFileToString(const wchar_t* szBaseFilename, char* szDestText, int nMaxBytes, bool bConvertLFsToSpecialChar)
+{
+ wchar_t szFile[MAX_PATH];
+ swprintf(szFile, L"%s%s", g_plugin.m_szMilkdrop2Path, szBaseFilename);
+
+ // read in all chars. Replace char combos: { 13; 13+10; 10 } with LINEFEED_CONTROL_CHAR, if bConvertLFsToSpecialChar is true.
+ FILE* f = _wfopen(szFile, L"rb");
+ if (!f)
+ {
+ wchar_t buf[1024], title[64];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_READ_DATA_FILE_X), szFile);
+ g_plugin.dumpmsg(buf);
+ MessageBoxW(NULL, buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ int len = 0;
+ int x;
+ char prev_ch = 0;
+ while ( (x = fgetc(f)) >= 0 && len < nMaxBytes-4 )
+ {
+ char orig_ch = (char)x;
+ char ch = orig_ch;
+ bool bSkipChar = false;
+ if (bConvertLFsToSpecialChar)
+ {
+ if (ch==10)
+ {
+ if (prev_ch==13)
+ bSkipChar = true;
+ else
+ ch = LINEFEED_CONTROL_CHAR;
+ }
+ else if (ch==13)
+ ch = LINEFEED_CONTROL_CHAR;
+ }
+
+ if (!bSkipChar)
+ szDestText[len++] = ch;
+ prev_ch = orig_ch;
+ }
+ szDestText[len] = 0;
+ szDestText[len++] = ' '; // make sure there is some whitespace after
+ fclose(f);
+ return true;
+}
+
+// these callback functions are called by menu.cpp whenever the user finishes editing an eval_ expression.
+void OnUserEditedPerFrame(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_PRESET_CODE, 0);
+}
+
+void OnUserEditedPerPixel(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_PRESET_CODE, 0);
+}
+
+void OnUserEditedPresetInit(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_PRESET_CODE, 1);
+}
+
+void OnUserEditedWavecode(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_WAVE_CODE, 0);
+}
+
+void OnUserEditedWavecodeInit(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_WAVE_CODE, 1);
+}
+
+void OnUserEditedShapecode(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_SHAPE_CODE, 0);
+}
+
+void OnUserEditedShapecodeInit(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_pState->RecompileExpressions(RECOMPILE_SHAPE_CODE, 1);
+}
+
+void OnUserEditedWarpShaders(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_bNeedRescanTexturesDir = true;
+ g_plugin.ClearErrors(ERR_PRESET);
+ if (g_plugin.m_nMaxPSVersion == 0)
+ return;
+ if (!g_plugin.RecompilePShader(g_plugin.m_pState->m_szWarpShadersText, &g_plugin.m_shaders.warp, SHADER_WARP, false, g_plugin.m_pState->m_nWarpPSVersion))
+ {
+ // switch to fallback
+ g_plugin.m_fallbackShaders_ps.warp.ptr->AddRef();
+ g_plugin.m_fallbackShaders_ps.warp.CT->AddRef();
+ g_plugin.m_shaders.warp = g_plugin.m_fallbackShaders_ps.warp;
+ }
+}
+
+void OnUserEditedCompShaders(LPARAM param1, LPARAM param2)
+{
+ g_plugin.m_bNeedRescanTexturesDir = true;
+ g_plugin.ClearErrors(ERR_PRESET);
+ if (g_plugin.m_nMaxPSVersion == 0)
+ return;
+ if (!g_plugin.RecompilePShader(g_plugin.m_pState->m_szCompShadersText, &g_plugin.m_shaders.comp, SHADER_COMP, false, g_plugin.m_pState->m_nCompPSVersion))
+ {
+ // switch to fallback
+ g_plugin.m_fallbackShaders_ps.comp.ptr->AddRef();
+ g_plugin.m_fallbackShaders_ps.comp.CT->AddRef();
+ g_plugin.m_shaders.comp = g_plugin.m_fallbackShaders_ps.comp;
+ }
+}
+
+// Modify the help screen text here.
+// Watch the # of lines, though; if there are too many, they will get cut off;
+// and watch the length of the lines, since there is no wordwrap.
+// A good guideline: your entire help screen should be visible when fullscreen
+// @ 640x480 and using the default help screen font.
+wchar_t* g_szHelp = 0;
+int g_szHelp_W = 0;
+
+// this is for integrating modern skins (with their Random button)
+// and having it match our Scroll Lock (preset lock) state...
+#define IPC_CB_VISRANDOM 628
+
+//----------------------------------------------------------------------
+
+void CPlugin::OverrideDefaults()
+{
+ // Here, you have the option of overriding the "default defaults"
+ // for the stuff on tab 1 of the config panel, replacing them
+ // with custom defaults for your plugin.
+ // To override any of the defaults, just uncomment the line
+ // and change the value.
+ // DO NOT modify these values from any function but this one!
+
+ // This example plugin only changes the default width/height
+ // for fullscreen mode; the "default defaults" are just
+ // 640 x 480.
+ // If your plugin is very dependent on smooth animation and you
+ // wanted it plugin to have the 'save cpu' option OFF by default,
+ // for example, you could set 'm_save_cpu' to 0 here.
+
+ // m_start_fullscreen = 0; // 0 or 1
+ // m_start_desktop = 0; // 0 or 1
+ // m_fake_fullscreen_mode = 0; // 0 or 1
+ // m_max_fps_fs = 30; // 1-120, or 0 for 'unlimited'
+ // m_max_fps_dm = 30; // 1-120, or 0 for 'unlimited'
+ // m_max_fps_w = 30; // 1-120, or 0 for 'unlimited'
+ // m_show_press_f1_msg = 1; // 0 or 1
+ m_allow_page_tearing_w = 0; // 0 or 1
+ // m_allow_page_tearing_fs = 0; // 0 or 1
+ // m_allow_page_tearing_dm = 1; // 0 or 1
+ // m_minimize_winamp = 1; // 0 or 1
+ // m_desktop_textlabel_boxes = 1; // 0 or 1
+ // m_save_cpu = 0; // 0 or 1
+
+ // lstrcpy(m_fontinfo[0].szFace, "Trebuchet MS"); // system font
+ // m_fontinfo[0].nSize = 18;
+ // m_fontinfo[0].bBold = 0;
+ // m_fontinfo[0].bItalic = 0;
+ // lstrcpy(m_fontinfo[1].szFace, "Times New Roman"); // decorative font
+ // m_fontinfo[1].nSize = 24;
+ // m_fontinfo[1].bBold = 0;
+ // m_fontinfo[1].bItalic = 1;
+
+ // Don't override default FS mode here; shell is now smart and sets it to match
+ // the current desktop display mode, by default.
+
+ //m_disp_mode_fs.Width = 1024; // normally 640
+ //m_disp_mode_fs.Height = 768; // normally 480
+ // use either D3DFMT_X8R8G8B8 or D3DFMT_R5G6B5.
+ // The former will match to any 32-bit color format available,
+ // and the latter will match to any 16-bit color available,
+ // if that exact format can't be found.
+ //m_disp_mode_fs.Format = D3DFMT_UNKNOWN; //<- this tells config panel & visualizer to use current display mode as a default!! //D3DFMT_X8R8G8B8;
+ // m_disp_mode_fs.RefreshRate = 60;
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::MyPreInitialize()
+{
+ // Initialize EVERY data member you've added to CPlugin here;
+ // these will be the default values.
+ // If you want to initialize any of your variables with random values
+ // (using rand()), be sure to seed the random number generator first!
+ // (If you want to change the default values for settings that are part of
+ // the plugin shell (framework), do so from OverrideDefaults() above.)
+
+ // seed the system's random number generator w/the current system time:
+ //srand((unsigned)time(NULL)); -don't - let winamp do it
+
+ // attempt to load a unicode F1 help message otherwise revert to the ansi version
+ g_szHelp = (wchar_t*)GetTextResource(IDR_TEXT2,1);
+ if(!g_szHelp) g_szHelp = (wchar_t*)GetTextResource(IDR_TEXT1,0);
+ else g_szHelp_W = 1;
+
+ // CONFIG PANEL SETTINGS THAT WE'VE ADDED (TAB #2)
+ m_bFirstRun = true;
+ m_bInitialPresetSelected = false;
+ m_fBlendTimeUser = 1.7f;
+ m_fBlendTimeAuto = 2.7f;
+ m_fTimeBetweenPresets = 16.0f;
+ m_fTimeBetweenPresetsRand = 10.0f;
+ m_bSequentialPresetOrder = false;
+ m_bHardCutsDisabled = true;
+ m_fHardCutLoudnessThresh = 2.5f;
+ m_fHardCutHalflife = 60.0f;
+ //m_nWidth = 1024;
+ //m_nHeight = 768;
+ //m_nDispBits = 16;
+ m_nCanvasStretch = 0;
+ m_nTexSizeX = -1; // -1 means "auto"
+ m_nTexSizeY = -1; // -1 means "auto"
+ m_nTexBitsPerCh = 8;
+ m_nGridX = 48;//32;
+ m_nGridY = 36;//24;
+
+ m_bShowPressF1ForHelp = true;
+ //lstrcpy(m_szMonitorName, "[don't use multimon]");
+ m_bShowMenuToolTips = true; // NOTE: THIS IS CURRENTLY HARDWIRED TO TRUE - NO OPTION TO CHANGE
+ m_n16BitGamma = 2;
+ m_bAutoGamma = true;
+ //m_nFpsLimit = -1;
+ m_bEnableRating = true;
+ //m_bInstaScan = false;
+ m_bSongTitleAnims = true;
+ m_fSongTitleAnimDuration = 1.7f;
+ m_fTimeBetweenRandomSongTitles = -1.0f;
+ m_fTimeBetweenRandomCustomMsgs = -1.0f;
+ m_nSongTitlesSpawned = 0;
+ m_nCustMsgsSpawned = 0;
+ m_nFramesSinceResize = 0;
+
+ //m_bAlways3D = false;
+ //m_fStereoSep = 1.0f;
+ //m_bAlwaysOnTop = false;
+ //m_bFixSlowText = true;
+ //m_bWarningsDisabled = false;
+ m_bWarningsDisabled2 = true;
+ //m_bAnisotropicFiltering = true;
+ m_bPresetLockOnAtStartup = false;
+ m_bPreventScollLockHandling = false;
+ m_nMaxPSVersion_ConfigPanel = -1; // -1 = auto, 0 = disable shaders, 2 = ps_2_0, 3 = ps_3_0
+ m_nMaxPSVersion_DX9 = -1; // 0 = no shader support, 2 = ps_2_0, 3 = ps_3_0
+ m_nMaxPSVersion = -1; // this one will be the ~min of the other two. 0/2/3.
+ m_nMaxImages = 32;
+ m_nMaxBytes = 16000000;
+
+ #ifdef _DEBUG
+ m_dwShaderFlags = D3DXSHADER_DEBUG|(1<<16);
+ #else
+ m_dwShaderFlags = (1<<16);//D3DXSHADER_SKIPOPTIMIZATION|D3DXSHADER_NO_PRESHADER;
+ #endif
+ //m_pFragmentLinker = NULL;
+ //m_pCompiledFragments = NULL;
+ m_pShaderCompileErrors = NULL;
+ //m_vs_warp = NULL;
+ //m_ps_warp = NULL;
+ //m_vs_comp = NULL;
+ //m_ps_comp = NULL;
+ ZeroMemory(&m_shaders, sizeof(PShaderSet));
+ ZeroMemory(&m_OldShaders, sizeof(PShaderSet));
+ ZeroMemory(&m_NewShaders, sizeof(PShaderSet));
+ ZeroMemory(&m_fallbackShaders_vs, sizeof(VShaderSet));
+ ZeroMemory(&m_fallbackShaders_ps, sizeof(PShaderSet));
+ ZeroMemory(m_BlurShaders, sizeof(m_BlurShaders));
+ m_bWarpShaderLock = false;
+ m_bCompShaderLock = false;
+ m_bNeedRescanTexturesDir = true;
+
+ // vertex declarations:
+ m_pSpriteVertDecl = NULL;
+ m_pWfVertDecl = NULL;
+ m_pMyVertDecl = NULL;
+
+ m_gdi_title_font_doublesize = NULL;
+ m_d3dx_title_font_doublesize = NULL;
+
+ // RUNTIME SETTINGS THAT WE'VE ADDED
+ m_prev_time = GetTime() - 0.0333f; // note: this will be updated each frame, at bottom of MyRenderFn.
+ m_bTexSizeWasAutoPow2 = false;
+ m_bTexSizeWasAutoExact = false;
+ //m_bPresetLockedByUser = false; NOW SET IN DERIVED SETTINGS
+ m_bPresetLockedByCode = false;
+ m_fStartTime = 0.0f;
+ m_fPresetStartTime = 0.0f;
+ m_fNextPresetTime = -1.0f; // negative value means no time set (...it will be auto-set on first call to UpdateTime)
+ m_nLoadingPreset = 0;
+ m_nPresetsLoadedTotal = 0;
+ m_fSnapPoint = 0.5f;
+ m_pState = &m_state_DO_NOT_USE[0];
+ m_pOldState = &m_state_DO_NOT_USE[1];
+ m_pNewState = &m_state_DO_NOT_USE[2];
+ m_UI_mode = UI_REGULAR;
+ m_bShowShaderHelp = false;
+
+ m_nMashSlot = 0; //0..MASH_SLOTS-1
+ for (int mash=0; mash<MASH_SLOTS; mash++)
+ m_nLastMashChangeFrame[mash] = 0;
+
+ //m_nTrackPlaying = 0;
+ //m_nSongPosMS = 0;
+ //m_nSongLenMS = 0;
+ m_bUserPagedUp = false;
+ m_bUserPagedDown = false;
+ m_fMotionVectorsTempDx = 0.0f;
+ m_fMotionVectorsTempDy = 0.0f;
+
+ m_waitstring.bActive = false;
+ m_waitstring.bOvertypeMode = false;
+ m_waitstring.szClipboard[0] = 0;
+
+ m_nPresets = 0;
+ m_nDirs = 0;
+ m_nPresetListCurPos = 0;
+ m_nCurrentPreset = -1;
+ m_szCurrentPresetFile[0] = 0;
+ m_szLoadingPreset[0] = 0;
+ //m_szPresetDir[0] = 0; // will be set @ end of this function
+ m_bPresetListReady = false;
+ m_szUpdatePresetMask[0] = 0;
+ //m_nRatingReadProgress = -1;
+
+ myfft.Init(576, MY_FFT_SAMPLES, -1);
+ memset(&mysound, 0, sizeof(mysound));
+ int i = 0;
+ for (i=0; i<PRESET_HIST_LEN; i++)
+ m_presetHistory[i] = L"";
+ m_presetHistoryPos = 0;
+ m_presetHistoryBackFence = 0;
+ m_presetHistoryFwdFence = 0;
+
+ //m_nTextHeightPixels = -1;
+ //m_nTextHeightPixels_Fancy = -1;
+ m_bShowFPS = false;
+ m_bShowRating = false;
+ m_bShowPresetInfo = false;
+ m_bShowDebugInfo = false;
+ m_bShowSongTitle = false;
+ m_bShowSongTime = false;
+ m_bShowSongLen = false;
+ m_fShowRatingUntilThisTime = -1.0f;
+ ClearErrors();
+ m_szDebugMessage[0] = 0;
+ m_szSongTitle[0] = 0;
+ m_szSongTitlePrev[0] = 0;
+
+ m_lpVS[0] = NULL;
+ m_lpVS[1] = NULL;
+ #if (NUM_BLUR_TEX>0)
+ for (i=0; i<NUM_BLUR_TEX; i++)
+ m_lpBlur[i] = NULL;
+ #endif
+ m_lpDDSTitle = NULL;
+ m_nTitleTexSizeX = 0;
+ m_nTitleTexSizeY = 0;
+ m_verts = NULL;
+ m_verts_temp = NULL;
+ m_vertinfo = NULL;
+ m_indices_list = NULL;
+ m_indices_strip = NULL;
+
+ m_bMMX = false;
+ m_bHasFocus = true;
+ m_bHadFocus = false;
+ m_bOrigScrollLockState = GetKeyState(VK_SCROLL) & 1;
+ // m_bMilkdropScrollLockState is derived at end of MyReadConfig()
+
+ m_nNumericInputMode = NUMERIC_INPUT_MODE_CUST_MSG;
+ m_nNumericInputNum = 0;
+ m_nNumericInputDigits = 0;
+ //td_custom_msg_font m_CustomMessageFont[MAX_CUSTOM_MESSAGE_FONTS];
+ //td_custom_msg m_CustomMessage[MAX_CUSTOM_MESSAGES];
+
+ //texmgr m_texmgr; // for user sprites
+
+ m_supertext.bRedrawSuperText = false;
+ m_supertext.fStartTime = -1.0f;
+
+ // --------------------other init--------------------
+
+ g_bDebugOutput = false;
+ g_bDumpFileCleared = false;
+
+ swprintf(m_szMilkdrop2Path, L"%s%s", GetPluginsDirPath(), SUBDIR);
+ swprintf(m_szPresetDir, L"%spresets\\", m_szMilkdrop2Path );
+
+ // note that the config dir can be under Program Files or Application Data!!
+ wchar_t szConfigDir[MAX_PATH] = {0};
+ lstrcpyW(szConfigDir, GetConfigIniFile());
+ wchar_t* p = wcsrchr(szConfigDir, L'\\');
+ if (p) *(p+1) = 0;
+ swprintf(m_szMsgIniFile, L"%s%s", szConfigDir, MSG_INIFILE );
+ swprintf(m_szImgIniFile, L"%s%s", szConfigDir, IMG_INIFILE );
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::MyReadConfig()
+{
+ // Read the user's settings from the .INI file.
+ // If you've added any controls to the config panel, read their value in
+ // from the .INI file here.
+
+ // use this function declared in to read a value of this type:
+ // ----------------- ----------- ----------------------------
+ // GetPrivateProfileInt Win32 API int
+ // GetPrivateProfileBool utility.h bool
+ // GetPrivateProfileBOOL utility.h BOOL
+ // GetPrivateProfileFloat utility.h float
+ // GetPrivateProfileString Win32 API string
+
+ //ex: m_fog_enabled = GetPrivateProfileInt("settings","fog_enabled" ,m_fog_enabled ,GetConfigIniFile());
+
+ int n=0;
+ wchar_t *pIni = GetConfigIniFile();
+
+ m_bFirstRun = !GetPrivateProfileBoolW(L"settings",L"bConfigured" ,false,pIni);
+ m_bEnableRating = GetPrivateProfileBoolW(L"settings",L"bEnableRating",m_bEnableRating,pIni);
+ //m_bInstaScan = GetPrivateProfileBool("settings","bInstaScan",m_bInstaScan,pIni);
+ m_bHardCutsDisabled = GetPrivateProfileBoolW(L"settings",L"bHardCutsDisabled",m_bHardCutsDisabled,pIni);
+ g_bDebugOutput = GetPrivateProfileBoolW(L"settings",L"bDebugOutput",g_bDebugOutput,pIni);
+ //m_bShowSongInfo = GetPrivateProfileBool("settings","bShowSongInfo",m_bShowSongInfo,pIni);
+ //m_bShowPresetInfo=GetPrivateProfileBool("settings","bShowPresetInfo",m_bShowPresetInfo,pIni);
+ m_bShowPressF1ForHelp = GetPrivateProfileBoolW(L"settings",L"bShowPressF1ForHelp",m_bShowPressF1ForHelp,pIni);
+ //m_bShowMenuToolTips = GetPrivateProfileBool("settings","bShowMenuToolTips",m_bShowMenuToolTips,pIni);
+ m_bSongTitleAnims = GetPrivateProfileBoolW(L"settings",L"bSongTitleAnims",m_bSongTitleAnims,pIni);
+
+ m_bShowFPS = GetPrivateProfileBoolW(L"settings",L"bShowFPS", m_bShowFPS ,pIni);
+ m_bShowRating = GetPrivateProfileBoolW(L"settings",L"bShowRating", m_bShowRating ,pIni);
+ m_bShowPresetInfo = GetPrivateProfileBoolW(L"settings",L"bShowPresetInfo",m_bShowPresetInfo ,pIni);
+ //m_bShowDebugInfo = GetPrivateProfileBool("settings","bShowDebugInfo", m_bShowDebugInfo ,pIni);
+ m_bShowSongTitle = GetPrivateProfileBoolW(L"settings",L"bShowSongTitle", m_bShowSongTitle ,pIni);
+ m_bShowSongTime = GetPrivateProfileBoolW(L"settings",L"bShowSongTime", m_bShowSongTime ,pIni);
+ m_bShowSongLen = GetPrivateProfileBoolW(L"settings",L"bShowSongLen", m_bShowSongLen ,pIni);
+
+ //m_bFixPinkBug = GetPrivateProfileBool("settings","bFixPinkBug",m_bFixPinkBug,pIni);
+ int nTemp = GetPrivateProfileBoolW(L"settings",L"bFixPinkBug",-1,pIni);
+ if (nTemp == 0)
+ m_n16BitGamma = 0;
+ else if (nTemp == 1)
+ m_n16BitGamma = 2;
+ m_n16BitGamma = GetPrivateProfileIntW(L"settings",L"n16BitGamma",m_n16BitGamma,pIni);
+ m_bAutoGamma = GetPrivateProfileBoolW(L"settings",L"bAutoGamma",m_bAutoGamma,pIni);
+ //m_bAlways3D = GetPrivateProfileBool("settings","bAlways3D",m_bAlways3D,pIni);
+ //m_fStereoSep = GetPrivateProfileFloat("settings","fStereoSep",m_fStereoSep,pIni);
+ //m_bFixSlowText = GetPrivateProfileBool("settings","bFixSlowText",m_bFixSlowText,pIni);
+ //m_bAlwaysOnTop = GetPrivateProfileBool("settings","bAlwaysOnTop",m_bAlwaysOnTop,pIni);
+ //m_bWarningsDisabled = GetPrivateProfileBool("settings","bWarningsDisabled",m_bWarningsDisabled,pIni);
+ m_bWarningsDisabled2 = GetPrivateProfileBoolW(L"settings",L"bWarningsDisabled2",m_bWarningsDisabled2,pIni);
+ //m_bAnisotropicFiltering = GetPrivateProfileBool("settings","bAnisotropicFiltering",m_bAnisotropicFiltering,pIni);
+ m_bPresetLockOnAtStartup = GetPrivateProfileBoolW(L"settings",L"bPresetLockOnAtStartup",m_bPresetLockOnAtStartup,pIni);
+ m_bPreventScollLockHandling = GetPrivateProfileBoolW(L"settings",L"m_bPreventScollLockHandling",m_bPreventScollLockHandling,pIni);
+
+ m_nCanvasStretch = GetPrivateProfileIntW(L"settings",L"nCanvasStretch" ,m_nCanvasStretch,pIni);
+ m_nTexSizeX = GetPrivateProfileIntW(L"settings",L"nTexSize" ,m_nTexSizeX ,pIni);
+ m_nTexSizeY = m_nTexSizeX;
+ m_bTexSizeWasAutoPow2 = (m_nTexSizeX == -2);
+ m_bTexSizeWasAutoExact = (m_nTexSizeX == -1);
+ m_nTexBitsPerCh = GetPrivateProfileIntW(L"settings", L"nTexBitsPerCh", m_nTexBitsPerCh, pIni);
+ m_nGridX = GetPrivateProfileIntW(L"settings",L"nMeshSize" ,m_nGridX ,pIni);
+ m_nGridY = m_nGridX*3/4;
+ m_nMaxPSVersion_ConfigPanel = GetPrivateProfileIntW(L"settings",L"MaxPSVersion",m_nMaxPSVersion_ConfigPanel,pIni);
+ m_nMaxImages = GetPrivateProfileIntW(L"settings",L"MaxImages",m_nMaxImages,pIni);
+ m_nMaxBytes = GetPrivateProfileIntW(L"settings",L"MaxBytes" ,m_nMaxBytes ,pIni);
+
+ m_fBlendTimeUser = GetPrivateProfileFloatW(L"settings",L"fBlendTimeUser" ,m_fBlendTimeUser ,pIni);
+ m_fBlendTimeAuto = GetPrivateProfileFloatW(L"settings",L"fBlendTimeAuto" ,m_fBlendTimeAuto ,pIni);
+ m_fTimeBetweenPresets = GetPrivateProfileFloatW(L"settings",L"fTimeBetweenPresets" ,m_fTimeBetweenPresets ,pIni);
+ m_fTimeBetweenPresetsRand = GetPrivateProfileFloatW(L"settings",L"fTimeBetweenPresetsRand",m_fTimeBetweenPresetsRand,pIni);
+ m_fHardCutLoudnessThresh = GetPrivateProfileFloatW(L"settings",L"fHardCutLoudnessThresh" ,m_fHardCutLoudnessThresh ,pIni);
+ m_fHardCutHalflife = GetPrivateProfileFloatW(L"settings",L"fHardCutHalflife" ,m_fHardCutHalflife ,pIni);
+ m_fSongTitleAnimDuration = GetPrivateProfileFloatW(L"settings",L"fSongTitleAnimDuration" ,m_fSongTitleAnimDuration ,pIni);
+ m_fTimeBetweenRandomSongTitles = GetPrivateProfileFloatW(L"settings",L"fTimeBetweenRandomSongTitles" ,m_fTimeBetweenRandomSongTitles,pIni);
+ m_fTimeBetweenRandomCustomMsgs = GetPrivateProfileFloatW(L"settings",L"fTimeBetweenRandomCustomMsgs" ,m_fTimeBetweenRandomCustomMsgs,pIni);
+
+ // --------
+
+ GetPrivateProfileStringW(L"settings",L"szPresetDir",m_szPresetDir,m_szPresetDir,sizeof(m_szPresetDir),pIni);
+
+ ReadCustomMessages();
+
+ // bounds-checking:
+ if (m_nGridX > MAX_GRID_X)
+ m_nGridX = MAX_GRID_X;
+ if (m_nGridY > MAX_GRID_Y)
+ m_nGridY = MAX_GRID_Y;
+ if (m_fTimeBetweenPresetsRand < 0)
+ m_fTimeBetweenPresetsRand = 0;
+ if (m_fTimeBetweenPresets < 0.1f)
+ m_fTimeBetweenPresets = 0.1f;
+
+ // DERIVED SETTINGS
+ m_bPresetLockedByUser = m_bPresetLockOnAtStartup;
+ //m_bMilkdropScrollLockState = m_bPresetLockOnAtStartup;
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::MyWriteConfig()
+{
+ // Write the user's settings to the .INI file.
+ // This gets called only when the user runs the config panel and hits OK.
+ // If you've added any controls to the config panel, write their value out
+ // to the .INI file here.
+
+ // use this function declared in to write a value of this type:
+ // ----------------- ----------- ----------------------------
+ // WritePrivateProfileInt Win32 API int
+ // WritePrivateProfileInt utility.h bool
+ // WritePrivateProfileInt utility.h BOOL
+ // WritePrivateProfileFloat utility.h float
+ // WritePrivateProfileString Win32 API string
+
+ // ex: WritePrivateProfileInt(m_fog_enabled ,"fog_enabled" ,GetConfigIniFile(),"settings");
+
+ wchar_t *pIni = GetConfigIniFile();
+
+ // constants:
+ WritePrivateProfileStringW(L"settings",L"bConfigured",L"1",pIni);
+
+ //note: m_szPresetDir is not written here; it is written manually, whenever it changes.
+
+ wchar_t szSectionName[] = L"settings";
+
+ WritePrivateProfileIntW(m_bSongTitleAnims, L"bSongTitleAnims", pIni, L"settings");
+ WritePrivateProfileIntW(m_bHardCutsDisabled, L"bHardCutsDisabled", pIni, L"settings");
+ WritePrivateProfileIntW(m_bEnableRating, L"bEnableRating", pIni, L"settings");
+ //WritePrivateProfileIntW(m_bInstaScan, "bInstaScan", pIni, "settings");
+ WritePrivateProfileIntW(g_bDebugOutput, L"bDebugOutput", pIni, L"settings");
+
+ //itePrivateProfileInt(m_bShowPresetInfo, "bShowPresetInfo", pIni, "settings");
+ //itePrivateProfileInt(m_bShowSongInfo, "bShowSongInfo", pIni, "settings");
+ //itePrivateProfileInt(m_bFixPinkBug, "bFixPinkBug", pIni, "settings");
+
+ WritePrivateProfileIntW(m_bShowPressF1ForHelp, L"bShowPressF1ForHelp", pIni, L"settings");
+ //itePrivateProfileInt(m_bShowMenuToolTips, "bShowMenuToolTips", pIni, "settings");
+ WritePrivateProfileIntW(m_n16BitGamma, L"n16BitGamma", pIni, L"settings");
+ WritePrivateProfileIntW(m_bAutoGamma, L"bAutoGamma", pIni, L"settings");
+
+ //WritePrivateProfileIntW(m_bAlways3D, "bAlways3D", pIni, "settings");
+ //WritePrivateProfileFloat(m_fStereoSep, "fStereoSep", pIni, "settings");
+ //WritePrivateProfileIntW(m_bFixSlowText, "bFixSlowText", pIni, "settings");
+ //itePrivateProfileInt(m_bAlwaysOnTop, "bAlwaysOnTop", pIni, "settings");
+ //WritePrivateProfileIntW(m_bWarningsDisabled, "bWarningsDisabled", pIni, "settings");
+ WritePrivateProfileIntW(m_bWarningsDisabled2, L"bWarningsDisabled2", pIni, L"settings");
+ //WritePrivateProfileIntW(m_bAnisotropicFiltering, "bAnisotropicFiltering",pIni, "settings");
+ WritePrivateProfileIntW(m_bPresetLockOnAtStartup,L"bPresetLockOnAtStartup",pIni,L"settings");
+ WritePrivateProfileIntW(m_bPreventScollLockHandling,L"m_bPreventScollLockHandling",pIni,L"settings");
+ // note: this is also written @ exit of the visualizer
+
+ WritePrivateProfileIntW(m_nCanvasStretch, L"nCanvasStretch", pIni, L"settings");
+ WritePrivateProfileIntW(m_nTexSizeX, L"nTexSize", pIni, L"settings");
+ WritePrivateProfileIntW(m_nTexBitsPerCh, L"nTexBitsPerCh", pIni, L"settings");
+ WritePrivateProfileIntW(m_nGridX, L"nMeshSize", pIni, L"settings");
+ WritePrivateProfileIntW(m_nMaxPSVersion_ConfigPanel, L"MaxPSVersion", pIni, L"settings");
+ WritePrivateProfileIntW(m_nMaxImages, L"MaxImages", pIni, L"settings");
+ WritePrivateProfileIntW(m_nMaxBytes , L"MaxBytes", pIni, L"settings");
+
+ WritePrivateProfileFloatW(m_fBlendTimeAuto, L"fBlendTimeAuto", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fBlendTimeUser, L"fBlendTimeUser", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fTimeBetweenPresets, L"fTimeBetweenPresets", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fTimeBetweenPresetsRand, L"fTimeBetweenPresetsRand", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fHardCutLoudnessThresh, L"fHardCutLoudnessThresh", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fHardCutHalflife, L"fHardCutHalflife", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fSongTitleAnimDuration, L"fSongTitleAnimDuration", pIni, L"settings");
+ WritePrivateProfileFloatW(m_fTimeBetweenRandomSongTitles,L"fTimeBetweenRandomSongTitles",pIni, L"settings");
+ WritePrivateProfileFloatW(m_fTimeBetweenRandomCustomMsgs,L"fTimeBetweenRandomCustomMsgs",pIni, L"settings");
+}
+
+//----------------------------------------------------------------------
+
+void ConvertLLCto1310(char* d, const char *s)
+{
+ // src and dest can NOT be the same pointer.
+ assert(s != d);
+
+ while (*s)
+ {
+ if (*s == LINEFEED_CONTROL_CHAR)
+ {
+ *d++ = 13;
+ *d++ = 10;
+ }
+ else
+ {
+ *d++ = *s;
+ }
+ s++;
+ };
+ *d = 0;
+}
+
+void StripComments(char* str)
+{
+ if (!str || !str[0] || !str[1])
+ return;
+
+ char c0 = str[0];
+ char c1 = str[1];
+ char* dest = str;
+ char* p = &str[1];
+ bool bIgnoreTilEndOfLine = false;
+ bool bIgnoreTilCloseComment = false; //this one takes precedence
+ int nCharsToSkip = 0;
+ while (1)
+ {
+ // handle '//' comments
+ if (!bIgnoreTilCloseComment && c0=='/' && c1=='/')
+ bIgnoreTilEndOfLine = true;
+ if (bIgnoreTilEndOfLine && (c0==10 || c0==13))
+ {
+ bIgnoreTilEndOfLine = false;
+ nCharsToSkip = 0;
+ }
+
+ // handle /* */ comments
+ if (!bIgnoreTilEndOfLine && c0=='/' && c1=='*')
+ bIgnoreTilCloseComment = true;
+ if (bIgnoreTilCloseComment && c0=='*' && c1=='/')
+ {
+ bIgnoreTilCloseComment = false;
+ nCharsToSkip = 2;
+ }
+
+ if (!bIgnoreTilEndOfLine && !bIgnoreTilCloseComment)
+ {
+ if (nCharsToSkip > 0)
+ nCharsToSkip--;
+ else
+ *dest++ = c0;
+ }
+
+ if (c1==0)
+ break;
+
+ p++;
+ c0 = c1;
+ c1 = *p;
+ }
+
+ *dest++ = 0;
+}
+
+int CPlugin::AllocateMyNonDx9Stuff()
+{
+ // This gets called only once, when your plugin is actually launched.
+ // If only the config panel is launched, this does NOT get called.
+ // (whereas MyPreInitialize() still does).
+ // If anything fails here, return FALSE to safely exit the plugin,
+ // but only after displaying a messagebox giving the user some information
+ // about what went wrong.
+
+ /*
+ if (!m_hBlackBrush)
+ m_hBlackBrush = CreateSolidBrush(RGB(0,0,0));
+ */
+
+ g_hThread = INVALID_HANDLE_VALUE;
+ g_bThreadAlive = false;
+ g_bThreadShouldQuit = false;
+ InitializeCriticalSection(&g_cs);
+
+ // read in 'm_szShaderIncludeText'
+ bool bSuccess = true;
+ bSuccess = ReadFileToString(L"data\\include.fx", m_szShaderIncludeText, sizeof(m_szShaderIncludeText)-4, false);
+ if (!bSuccess) return false;
+ StripComments(m_szShaderIncludeText);
+ m_nShaderIncludeTextLen = lstrlen(m_szShaderIncludeText);
+ bSuccess |= ReadFileToString(L"data\\warp_vs.fx", m_szDefaultWarpVShaderText, sizeof(m_szDefaultWarpVShaderText), true);
+ if (!bSuccess) return false;
+ bSuccess |= ReadFileToString(L"data\\warp_ps.fx", m_szDefaultWarpPShaderText, sizeof(m_szDefaultWarpPShaderText), true);
+ if (!bSuccess) return false;
+ bSuccess |= ReadFileToString(L"data\\comp_vs.fx", m_szDefaultCompVShaderText, sizeof(m_szDefaultCompVShaderText), true);
+ if (!bSuccess) return false;
+ bSuccess |= ReadFileToString(L"data\\comp_ps.fx", m_szDefaultCompPShaderText, sizeof(m_szDefaultCompPShaderText), true);
+ if (!bSuccess) return false;
+ bSuccess |= ReadFileToString(L"data\\blur_vs.fx", m_szBlurVS, sizeof(m_szBlurVS), true);
+ if (!bSuccess) return false;
+ bSuccess |= ReadFileToString(L"data\\blur1_ps.fx", m_szBlurPSX, sizeof(m_szBlurPSX), true);
+ if (!bSuccess) return false;
+ bSuccess |= ReadFileToString(L"data\\blur2_ps.fx", m_szBlurPSY, sizeof(m_szBlurPSY), true);
+ if (!bSuccess) return false;
+
+ BuildMenus();
+
+ m_bMMX = CheckForMMX();
+ //m_bSSE = CheckForSSE();
+
+ m_pState->Default();
+ m_pOldState->Default();
+ m_pNewState->Default();
+
+ //LoadRandomPreset(0.0f); -avoid this here; causes some DX9 stuff to happen.
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+
+void CancelThread(int max_wait_time_ms)
+{
+ g_bThreadShouldQuit = true;
+ int waited = 0;
+ while (g_bThreadAlive && waited < max_wait_time_ms)
+ {
+ Sleep(30);
+ waited += 30;
+ }
+
+ if (g_bThreadAlive)
+ {
+ TerminateThread(g_hThread,0);
+ g_bThreadAlive = false;
+ }
+
+ if (g_hThread != INVALID_HANDLE_VALUE)
+ CloseHandle(g_hThread);
+ g_hThread = INVALID_HANDLE_VALUE;
+}
+
+void CPlugin::CleanUpMyNonDx9Stuff()
+{
+ // This gets called only once, when your plugin exits.
+ // Be sure to clean up any objects here that were
+ // created/initialized in AllocateMyNonDx9Stuff.
+
+ //sound.Finish();
+
+ // NOTE: DO NOT DELETE m_gdi_titlefont_doublesize HERE!!!
+
+ DeleteCriticalSection(&g_cs);
+
+ CancelThread(0);
+
+ m_menuPreset .Finish();
+ m_menuWave .Finish();
+ m_menuAugment .Finish();
+ m_menuCustomWave.Finish();
+ m_menuCustomShape.Finish();
+ m_menuMotion .Finish();
+ m_menuPost .Finish();
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ m_menuWavecode[i].Finish();
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ m_menuShapecode[i].Finish();
+
+ SetScrollLock(m_bOrigScrollLockState, m_bPreventScollLockHandling);
+
+ //dumpmsg("Finish: cleanup complete.");
+}
+
+//----------------------------------------------------------------------
+
+float SquishToCenter(float x, float fExp)
+{
+ if (x > 0.5f)
+ return powf(x*2-1, fExp)*0.5f + 0.5f;
+
+ return (1-powf(1-x*2, fExp))*0.5f;
+}
+
+int GetNearestPow2Size(int w, int h)
+{
+ float fExp = logf( max(w,h)*0.75f + 0.25f*min(w,h) ) / logf(2.0f);
+ float bias = 0.55f;
+ if (fExp + bias >= 11.0f) // ..don't jump to 2048x2048 quite as readily
+ bias = 0.5f;
+ int nExp = (int)(fExp + bias);
+ int log2size = (int)powf(2.0f, (float)nExp);
+ return log2size;
+}
+
+int CPlugin::AllocateMyDX9Stuff()
+{
+ // (...aka OnUserResizeWindow)
+ // (...aka OnToggleFullscreen)
+
+ // Allocate and initialize all your DX9 and D3DX stuff here: textures,
+ // surfaces, vertex/index buffers, D3DX fonts, and so on.
+ // If anything fails here, return FALSE to safely exit the plugin,
+ // but only after displaying a messagebox giving the user some information
+ // about what went wrong. If the error is NON-CRITICAL, you don't *have*
+ // to return; just make sure that the rest of the code will be still safely
+ // run (albeit with degraded features).
+ // If you run out of video memory, you might want to show a short messagebox
+ // saying what failed to allocate and that the reason is a lack of video
+ // memory, and then call SuggestHowToFreeSomeMem(), which will show them
+ // a *second* messagebox that (intelligently) suggests how they can free up
+ // some video memory.
+ // Don't forget to account for each object you create/allocate here by cleaning
+ // it up in CleanUpMyDX9Stuff!
+ // IMPORTANT:
+ // Note that the code here isn't just run at program startup!
+ // When the user toggles between fullscreen and windowed modes
+ // or resizes the window, the base class calls this function before
+ // destroying & recreating the plugin window and DirectX object, and then
+ // calls AllocateMyDX9Stuff afterwards, to get your plugin running again.
+
+ wchar_t buf[32768], title[64];
+
+ m_nFramesSinceResize = 0;
+
+ int nNewCanvasStretch = (m_nCanvasStretch == 0) ? 100 : m_nCanvasStretch;
+
+ DWORD PSVersion = GetCaps()->PixelShaderVersion & 0xFFFF; // 0x0300, etc.
+ if (PSVersion >= 0x0300)
+ m_nMaxPSVersion_DX9 = MD2_PS_3_0;
+ else if (PSVersion > 0x0200)
+ m_nMaxPSVersion_DX9 = MD2_PS_2_X;
+ else if (PSVersion >= 0x0200)
+ m_nMaxPSVersion_DX9 = MD2_PS_2_0;
+ else
+ m_nMaxPSVersion_DX9 = MD2_PS_NONE;
+
+ if (m_nMaxPSVersion_ConfigPanel == -1)
+ m_nMaxPSVersion = m_nMaxPSVersion_DX9;
+ else
+ {
+ // to still limit their choice by what HW reports:
+ //m_nMaxPSVersion = min(m_nMaxPSVersion_DX9, m_nMaxPSVersion_ConfigPanel);
+
+ // to allow them to override:
+ m_nMaxPSVersion = m_nMaxPSVersion_ConfigPanel;
+ }
+
+ /*
+ Auto mode: do a check against a few known, *SLOW* DX9/ps_2_0 cards to see
+ if we should run them without pixel shaders instead.
+ Here is valve's list of the cards they run DX8 on (mostly because they're too slow under DX9 + ps_2_0):
+ NVIDIA GeForce FX 5200� 31.12%
+ ATI Radeon 9200�������� 21.29%
+ NVIDIA GeForce FX 5500� 11.27%
+ NVIDIA GeForce4��������� 7.74%
+ NVIDIA GeForce FX 5700�� 7.12%
+ NVIDIA GeForce FX 5600�� 5.16%
+ SiS 661FX_760_741������� 3.34%
+ NVIDIA GeForce FX 5900�� 3.24%
+ NVIDIA GeForce3��������� 2.09%
+ ATI Radeon 9000��������� 1.98%
+ other������������������� 5.66%
+ [ from http://www.steampowered.com/status/survey.html ]
+ see also:
+ http://en.wikipedia.org/wiki/Radeon
+ http://en.wikipedia.org/wiki/Geforce_fx
+ */
+
+ const char* szGPU = GetDriverDescription();
+ /* known examples of this string:
+ "ATI MOBILITY RADEON X600"
+ "RADEON X800 Series " <- note the spaces at the end
+ "Sapphire RADEON X700"
+ "NVIDIA GeForce Go 6200 " <- note the spaces at the end
+ "NVIDIA GeForce 6800 GT"
+ "Intel(R) 82865G Graphics Controller"
+ "Mobile Intel(R) 915GM/GMS,910GML Express Chipset Family"
+
+ might want to consider adding these to the list: [from http://www.intel.com/support/graphics/sb/cs-014257.htm ]
+ (...they should support PS2.0, but not sure if they're fast...)
+ "Mobile Intel(R) 945GM Express Chipset Family"
+ "Mobile Intel(R) 915GM/GMS,910GML Express Chipset"
+ "Intel(R) 945G Express Chipset"
+ "Intel(R) 82915G/82910GL Express Chipset Family"
+
+ or these, if they seem to be reporting that they do support ps_2_0, which would be very bogus info:
+ "Intel(R) 82865G Graphics Controller"
+ "Intel(R) 82852/82855 Graphics Controller Family"
+ "Intel(R) 82845G Graphics Controller"
+ "Intel(R) 82830M Graphics Controller"
+ "Intel(R) 82815 Graphics Controller"
+ "Intel(R) 82810 Graphics Controller"
+ */
+
+ // GREY LIST - slow ps_2_0 cards
+ // In Canvas Stretch==Auto mode, for these cards, if they (claim to) run ps_2_0,
+ // we run at half-res (cuz they're slow).
+ // THE GENERAL GUIDELINE HERE:
+ // It should be at least as fast as a GeForce FX 5700 or my GeForce 6200 (TC)
+ // if it's to run without stretch.
+ if (m_nCanvasStretch==0)// && m_nMaxPSVersion_DX9 > 0)
+ {
+ // put cards on this list if you see them successfully run ps_2_0 (using override)
+ // and they run well at a low resolution (512x512 or less).
+ if (
+ strstr(szGPU, "GeForce 4" ) || // probably not even ps_2_0
+ strstr(szGPU, "GeForce FX 52" ) || // chip's computer (FX 5200) - does do ps_2_0, but slow
+ strstr(szGPU, "GeForce FX 53" ) ||
+ strstr(szGPU, "GeForce FX 54" ) ||
+ strstr(szGPU, "GeForce FX 55" ) || //GeForce FX 5600 is 13 GB/s - 2.5x as fast as my 6200!
+ strstr(szGPU, "GeForce FX 56" ) ||
+ //...GeForce FX 5700 and up, we let those run at full-res on ps_2_0...
+ strstr(szGPU, "GeForce FX 56" ) ||
+ strstr(szGPU, "GeForce FX 56" ) ||
+ strstr(szGPU, "SiS 300/305/630/540/730") || // mom's computer - just slow.
+ strstr(szGPU, "Radeon 8" ) || // no shader model 2.
+ strstr(szGPU, "Radeon 90" ) || // from Valve. no shader model 2.
+ strstr(szGPU, "Radeon 91" ) || // no shader model 2.
+ strstr(szGPU, "Radeon 92" ) || // from Valve. no shader model 2.
+ strstr(szGPU, "Radeon 93" ) || // no shader model 2.
+ strstr(szGPU, "Radeon 94" ) || // no shader model 2.
+ // guessing that 9500+ are ok - they're all ps_2_0 and the 9600 is like an FX 5900.
+ strstr(szGPU, "Radeon 9550") || // *maybe* - kiv - super budget R200 chip. def. ps_2_0 but possibly very slow.
+ strstr(szGPU, "Radeon X300") || // *maybe* - kiv - super budget R200 chip def. ps_2_0 but possibly very slow.
+ 0)
+ {
+ nNewCanvasStretch = 200;
+ }
+ }
+
+ /* pix pipes
+ core Fill(G) membw(GB/s)
+ Radeon 9600 Pro 400 4 1.6 9.6
+ Radeon 9600 XT 500 4 2.0 9.6
+ GeForce FX 5600 Ultra 400 4 1.6 12.8
+ GeForce FX 5700 Ultra 475 4 1.9 14.4
+ GeForce FX 5900 XT 400 4 1.6 22.4
+ GeForce FX 5900 450 4 1.8 27.2
+ GeForce FX 5950 Ultra 475 4 2.9 30
+ GeForce 6200 TC-32 350 4 1.1 5.6 (TurboDonkey)
+ GeForce 6600 GT 500 8 2.0 16
+ GeForce 6800 Ultra 400 16 6.4 35
+ ATI Radeon X800 XT PE 520 16 8.3 36
+ ATI Radeon X850 XT PE 540 16 8.6 38
+
+ Entry-level GPU 5200, 5300, 5500
+ Mid-Range GPU 5600, 5700
+ High-end GPU 5800, 5900, 5950
+
+ Entry-level GPU 6200, 6500
+ Mid-Range GPU 6600
+ High-end GPU 6800
+
+ Entry-level GPU
+ Mid-Range GPU
+ High-end GPU
+
+ R200: only ps_1_4. Radeon 8500-9250.
+ R300: ps_2_0. Radeon 9500-9800, X300-X600, X1050. 9600 fast enough (~FX5900). 9500/9700 ~ GeForce 4 Ti.
+ R420: ps_2_0 Radeon X700-8750 - ALL FAST ENOUGH. X700 is same speed as a GeForce 6600.
+
+ 6600 ~ X700
+ GeForce 4 < X300 / X600 / 9600
+ GeForce 4 Ti > Radeon 8500
+ FX 5900 = Radeon 9600
+ FX 5900 Ultra << [half] Radeon 9800 Pro
+ GeForce FX < Radeon 9700/9800
+ */
+
+ // BLACK LIST
+ // In Pixel Shaders==Auto mode, for these cards, we avoid ps_2_0 completely.
+ // There shouldn't be much on this list... feel free to put anything you KNOW doesn't do ps_2_0 (why not),
+ // and to put anything that is slow to begin with, and HAS BUGGY DRIVERS (INTEL).
+ if (m_nMaxPSVersion_ConfigPanel==-1)
+ {
+ if (strstr(szGPU, "GeForce2" ) || // from Valve
+ strstr(szGPU, "GeForce3" ) || // from Valve
+ strstr(szGPU, "GeForce4" ) || // from Valve
+ strstr(szGPU, "Radeon 7" ) || // from Valve
+ strstr(szGPU, "Radeon 8" ) ||
+ strstr(szGPU, "SiS 661FX_760_741") || // from Valve
+ //FOR NOW, FOR THESE, ASSUME INTEL EITHER DOESN'T DO PS_2_0,
+ //OR DRIVERS SUCK AND IT WOULDN'T WORK ANYWAY!
+ (strstr(szGPU,"Intel") && strstr(szGPU,"945G")) ||
+ (strstr(szGPU,"Intel") && strstr(szGPU,"915G")) || // ben allison's laptop - snow, freezing when you try ps_2_0
+ (strstr(szGPU,"Intel") && strstr(szGPU,"910G")) ||
+ (strstr(szGPU,"Intel") && strstr(szGPU,"8291")) || // gonna guess that this supports ps_2_0 but is SLOW
+ (strstr(szGPU,"Intel") && strstr(szGPU,"8281")) || // definitely DOESN'T support pixel shaders
+ (strstr(szGPU,"Intel") && strstr(szGPU,"8283")) || // definitely DOESN'T support pixel shaders
+ (strstr(szGPU,"Intel") && strstr(szGPU,"8284")) || // definitely DOESN'T support pixel shaders
+ (strstr(szGPU,"Intel") && strstr(szGPU,"8285")) || // definitely DOESN'T support pixel shaders
+ (strstr(szGPU,"Intel") && strstr(szGPU,"8286")) || // definitely DOESN'T support pixel shaders. Ben Allison's desktop (865) - no image w/ps_2_0. Plus Nes's desktop - no ps_2_0.
+ 0)
+ {
+ m_nMaxPSVersion = MD2_PS_NONE;
+ //if (m_nCanvasStretch==0)
+ // nNewCanvasStretch = 100;
+ }
+ }
+
+ /*char fname[512];
+ sprintf(fname, "%s%s", GetPluginsDirPath(), TEXTURE_NAME);
+ if (D3DXCreateTextureFromFile(GetDevice(), fname, &m_object_tex) != S_OK)
+ {
+ // just give a warning, and move on
+ m_object_tex = NULL; // (make sure pointer wasn't mangled by some bad driver)
+
+ char msg[1024];
+ sprintf(msg, "Unable to load texture:\r%s", fname);
+ MessageBox(GetPluginWindow(), msg, "WARNING", MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ //return false;
+ }*/
+
+ // Note: this code used to be in OnResizeGraphicsWindow().
+
+ // SHADERS
+ //-------------------------------------
+ if (m_nMaxPSVersion > MD2_PS_NONE)
+ {
+ // Create vertex declarations (since we're not using FVF anymore)
+ if (D3D_OK != GetDevice()->CreateVertexDeclaration( g_MyVertDecl, &m_pMyVertDecl ))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_CREATE_MY_VERTEX_DECLARATION,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,sizeof(title)), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (D3D_OK != GetDevice()->CreateVertexDeclaration( g_WfVertDecl, &m_pWfVertDecl ))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_CREATE_WF_VERTEX_DECLARATION,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,sizeof(title)), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (D3D_OK != GetDevice()->CreateVertexDeclaration( g_SpriteVertDecl, &m_pSpriteVertDecl ))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_CREATE_SPRITE_VERTEX_DECLARATION,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,sizeof(title)), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ // Load the FALLBACK shaders...
+ if (!RecompilePShader(m_szDefaultWarpPShaderText, &m_fallbackShaders_ps.warp, SHADER_WARP, true, 2))
+ {
+ wchar_t szSM[64];
+ switch(m_nMaxPSVersion_DX9)
+ {
+ case MD2_PS_2_0:
+ case MD2_PS_2_X:
+ WASABI_API_LNGSTRINGW_BUF(IDS_SHADER_MODEL_2,szSM,64); break;
+ case MD2_PS_3_0: WASABI_API_LNGSTRINGW_BUF(IDS_SHADER_MODEL_3,szSM,64); break;
+ case MD2_PS_4_0: WASABI_API_LNGSTRINGW_BUF(IDS_SHADER_MODEL_4,szSM,64); break;
+ default:
+ swprintf(szSM, WASABI_API_LNGSTRINGW(IDS_UKNOWN_CASE_X), m_nMaxPSVersion_DX9);
+ break;
+ }
+ if (m_nMaxPSVersion_ConfigPanel >= MD2_PS_NONE && m_nMaxPSVersion_DX9 < m_nMaxPSVersion_ConfigPanel)
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_FAILED_TO_COMPILE_PIXEL_SHADERS_USING_X),szSM,PSVersion);
+ else
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_FAILED_TO_COMPILE_PIXEL_SHADERS_HARDWARE_MIS_REPORT),szSM,PSVersion);
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (!RecompileVShader(m_szDefaultWarpVShaderText, &m_fallbackShaders_vs.warp, SHADER_WARP, true))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_FALLBACK_WV_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (!RecompileVShader(m_szDefaultCompVShaderText, &m_fallbackShaders_vs.comp, SHADER_COMP, true))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_FALLBACK_CV_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (!RecompilePShader(m_szDefaultCompPShaderText, &m_fallbackShaders_ps.comp, SHADER_COMP, true, 2))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_FALLBACK_CP_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ // Load the BLUR shaders...
+ if (!RecompileVShader(m_szBlurVS, &m_BlurShaders[0].vs, SHADER_BLUR, true))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_BLUR1_VERTEX_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (!RecompilePShader(m_szBlurPSX, &m_BlurShaders[0].ps, SHADER_BLUR, true, 2))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_BLUR1_PIXEL_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (!RecompileVShader(m_szBlurVS, &m_BlurShaders[1].vs, SHADER_BLUR, true))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_BLUR2_VERTEX_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (!RecompilePShader(m_szBlurPSY, &m_BlurShaders[1].ps, SHADER_BLUR, true, 2))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_COMPILE_BLUR2_PIXEL_SHADER,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ }
+
+ // create m_lpVS[2]
+ {
+ int log2texsize = GetNearestPow2Size(GetWidth(), GetHeight());
+
+ // auto-guess texsize
+ if (m_bTexSizeWasAutoExact)
+ {
+ // note: in windowed mode, the winamp window could be weird sizes,
+ // so the plugin shell now gives us a slightly enlarged size,
+ // which pads it out to the nearest 32x32 block size,
+ // and then on display, it intelligently crops the image.
+ // This is pretty likely to work on non-shitty GPUs.
+ // but some shitty ones will still only do powers of 2!
+ // So if we are running out of video memory here or experience
+ // other problems, though, we can make our VS's smaller;
+ // which will work, although it will lead to stretching.
+ m_nTexSizeX = GetWidth();
+ m_nTexSizeY = GetHeight();
+ }
+ else if (m_bTexSizeWasAutoPow2)
+ {
+ m_nTexSizeX = log2texsize;
+ m_nTexSizeY = log2texsize;
+ }
+
+ // clip texsize by max. from caps
+ if ((DWORD)m_nTexSizeX > GetCaps()->MaxTextureWidth && GetCaps()->MaxTextureWidth>0)
+ m_nTexSizeX = GetCaps()->MaxTextureWidth;
+ if ((DWORD)m_nTexSizeY > GetCaps()->MaxTextureHeight && GetCaps()->MaxTextureHeight>0)
+ m_nTexSizeY = GetCaps()->MaxTextureHeight;
+
+ // apply canvas stretch
+ m_nTexSizeX = (m_nTexSizeX * 100)/nNewCanvasStretch;
+ m_nTexSizeY = (m_nTexSizeY * 100)/nNewCanvasStretch;
+
+ // re-compute closest power-of-2 size, now that we've factored in the stretching...
+ log2texsize = GetNearestPow2Size(m_nTexSizeX, m_nTexSizeY);
+ if (m_bTexSizeWasAutoPow2)
+ {
+ m_nTexSizeX = log2texsize;
+ m_nTexSizeY = log2texsize;
+ }
+
+ // snap to 16x16 blocks
+ m_nTexSizeX = ((m_nTexSizeX+15)/16)*16;
+ m_nTexSizeY = ((m_nTexSizeY+15)/16)*16;
+
+ // determine format for VS1/VS2
+ D3DFORMAT fmt;
+ switch(m_nTexBitsPerCh) {
+ case 5: fmt = D3DFMT_R5G6B5 ; break;
+ case 8: fmt = D3DFMT_X8R8G8B8 ; break;
+ case 10: fmt = D3DFMT_A2R10G10B10; break; // D3DFMT_A2W10V10U10 or D3DFMT_A2R10G10B10 or D3DFMT_A2B10G10R10
+ case 16: fmt = D3DFMT_A16B16G16R16F; break;
+ case 32: fmt = D3DFMT_A32B32G32R32F; break; //FIXME
+ default: fmt = D3DFMT_X8R8G8B8 ; break;
+ }
+
+ // reallocate
+ bool bSuccess = false;
+ DWORD vs_flags = D3DUSAGE_RENDERTARGET;// | D3DUSAGE_AUTOGENMIPMAP;//FIXME! (make automipgen optional)
+ bool bRevertedBitDepth = false;
+ do
+ {
+ SafeRelease(m_lpVS[0]);
+ SafeRelease(m_lpVS[1]);
+
+ // create VS1
+ bSuccess = (GetDevice()->CreateTexture(m_nTexSizeX, m_nTexSizeY, 1, vs_flags, fmt, D3DPOOL_DEFAULT, &m_lpVS[0], NULL) == D3D_OK);
+ if (!bSuccess)
+ {
+ bSuccess = (GetDevice()->CreateTexture(m_nTexSizeX, m_nTexSizeY, 1, vs_flags, GetBackBufFormat(), D3DPOOL_DEFAULT, &m_lpVS[0], NULL) == D3D_OK);
+ if (bSuccess)
+ fmt = GetBackBufFormat();
+ }
+
+ // create VS2
+ if (bSuccess)
+ bSuccess = (GetDevice()->CreateTexture(m_nTexSizeX, m_nTexSizeY, 1, vs_flags, fmt, D3DPOOL_DEFAULT, &m_lpVS[1], NULL) == D3D_OK);
+
+ if (!bSuccess)
+ {
+ if (m_bTexSizeWasAutoExact)
+ {
+ if (m_nTexSizeX > 256 || m_nTexSizeY > 256)
+ {
+ m_nTexSizeX /= 2;
+ m_nTexSizeY /= 2;
+ m_nTexSizeX = ((m_nTexSizeX+15)/16)*16;
+ m_nTexSizeY = ((m_nTexSizeY+15)/16)*16;
+ }
+ else
+ {
+ m_nTexSizeX = log2texsize;
+ m_nTexSizeY = log2texsize;
+ m_bTexSizeWasAutoExact = false;
+ m_bTexSizeWasAutoPow2 = true;
+ }
+ }
+ else if (m_bTexSizeWasAutoPow2)
+ {
+ if (m_nTexSizeX > 256)
+ {
+ m_nTexSizeX /= 2;
+ m_nTexSizeY /= 2;
+ }
+ else
+ break;
+ }
+ }
+ }
+ while (!bSuccess);// && m_nTexSizeX >= 256 && (m_bTexSizeWasAutoExact || m_bTexSizeWasAutoPow2));
+
+ if (!bSuccess)
+ {
+ wchar_t buf[2048];
+ UINT err_id = IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_NOT_ENOUGH_VID_MEM;
+ if (GetScreenMode() == FULLSCREEN)
+ err_id = IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_SMALLER_DISPLAY;
+ else if (!(m_bTexSizeWasAutoExact || m_bTexSizeWasAutoPow2))
+ err_id = IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_NOT_ENOUGH_VID_MEM_RECOMMENDATION;
+
+ WASABI_API_LNGSTRINGW_BUF(err_id,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ else
+ {
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SUCCESSFULLY_CREATED_VS0_VS1), m_nTexSizeX, m_nTexSizeY, GetWidth(), GetHeight());
+ dumpmsg(buf);
+ }
+
+ /*
+ if (m_nTexSizeX != GetWidth() || m_nTexSizeY != GetHeight())
+ {
+ char buf[2048];
+ sprintf(buf, "warning - canvas size adjusted from %dx%d to %dx%d.", GetWidth(), GetHeight(), m_nTexSizeX, m_nTexSizeY);
+ dumpmsg(buf);
+ AddError(buf, 3.2f, ERR_INIT, true);
+ }/**/
+
+ // create blur textures w/same format. A complete mip chain costs 33% more video mem then 1 full-sized VS.
+ #if (NUM_BLUR_TEX>0)
+ int w = m_nTexSizeX;
+ int h = m_nTexSizeY;
+ DWORD blurtex_flags = D3DUSAGE_RENDERTARGET;// | D3DUSAGE_AUTOGENMIPMAP;//FIXME! (make automipgen optional)
+ for (int i=0; i<NUM_BLUR_TEX; i++)
+ {
+ // main VS = 1024
+ // blur0 = 512
+ // blur1 = 256 <- user sees this as "blur1"
+ // blur2 = 128
+ // blur3 = 128 <- user sees this as "blur2"
+ // blur4 = 64
+ // blur5 = 64 <- user sees this as "blur3"
+ if (!(i&1) || (i<2))
+ {
+ w = max(16, w/2);
+ h = max(16, h/2);
+ }
+ int w2 = ((w+3)/16)*16;
+ int h2 = ((h+3)/4)*4;
+ bSuccess = (GetDevice()->CreateTexture(w2, h2, 1, blurtex_flags, fmt, D3DPOOL_DEFAULT, &m_lpBlur[i], NULL) == D3D_OK);
+ m_nBlurTexW[i] = w2;
+ m_nBlurTexH[i] = h2;
+ if (!bSuccess)
+ {
+ m_nBlurTexW[i] = 1;
+ m_nBlurTexH[i] = 1;
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_CREATING_BLUR_TEXTURES,buf,sizeof(buf)),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_WARNING,title,sizeof(title)), MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ break;
+ }
+
+ // add it to m_textures[].
+ TexInfo x;
+ swprintf(x.texname, L"blur%d%s", i/2+1, (i%2) ? L"" : L"doNOTuseME");
+ x.texptr = m_lpBlur[i];
+ //x.texsize_param = NULL;
+ x.w = w2;
+ x.h = h2;
+ x.d = 1;
+ x.bEvictable = false;
+ x.nAge = m_nPresetsLoadedTotal;
+ x.nSizeInBytes = 0;
+ m_textures.push_back(x);
+ }
+ #endif
+ }
+
+
+ m_fAspectX = (m_nTexSizeY > m_nTexSizeX) ? m_nTexSizeX/(float)m_nTexSizeY : 1.0f;
+ m_fAspectY = (m_nTexSizeX > m_nTexSizeY) ? m_nTexSizeY/(float)m_nTexSizeX : 1.0f;
+ m_fInvAspectX = 1.0f/m_fAspectX;
+ m_fInvAspectY = 1.0f/m_fAspectY;
+
+
+ // BUILD VERTEX LIST for final composite blit
+ // note the +0.5-texel offset!
+ // (otherwise, a 1-pixel-wide line of the image would wrap at the top and left edges).
+ ZeroMemory(m_comp_verts, sizeof(MYVERTEX)*FCGSX*FCGSY);
+ //float fOnePlusInvWidth = 1.0f + 1.0f/(float)GetWidth();
+ //float fOnePlusInvHeight = 1.0f + 1.0f/(float)GetHeight();
+ float fHalfTexelW = 0.5f / (float)GetWidth(); // 2.5: 2 pixels bad @ bottom right
+ float fHalfTexelH = 0.5f / (float)GetHeight();
+ float fDivX = 1.0f / (float)(FCGSX-2);
+ float fDivY = 1.0f / (float)(FCGSY-2);
+ for (int j=0; j<FCGSY; j++)
+ {
+ int j2 = j - j/(FCGSY/2);
+ float v = j2*fDivY;
+ v = SquishToCenter(v, 3.0f);
+ float sy = -((v-fHalfTexelH)*2-1);//fOnePlusInvHeight*v*2-1;
+ for (int i=0; i<FCGSX; i++)
+ {
+ int i2 = i - i/(FCGSX/2);
+ float u = i2*fDivX;
+ u = SquishToCenter(u, 3.0f);
+ float sx = (u-fHalfTexelW)*2-1;//fOnePlusInvWidth*u*2-1;
+ MYVERTEX* p = &m_comp_verts[i + j*FCGSX];
+ p->x = sx;
+ p->y = sy;
+ p->z = 0;
+ float rad, ang;
+ UvToMathSpace( u, v, &rad, &ang );
+ // fix-ups:
+ if (i==FCGSX/2-1) {
+ if (j < FCGSY/2-1)
+ ang = 3.1415926535898f*1.5f;
+ else if (j == FCGSY/2-1)
+ ang = 3.1415926535898f*1.25f;
+ else if (j == FCGSY/2)
+ ang = 3.1415926535898f*0.75f;
+ else
+ ang = 3.1415926535898f*0.5f;
+ }
+ else if (i==FCGSX/2) {
+ if (j < FCGSY/2-1)
+ ang = 3.1415926535898f*1.5f;
+ else if (j == FCGSY/2-1)
+ ang = 3.1415926535898f*1.75f;
+ else if (j == FCGSY/2)
+ ang = 3.1415926535898f*0.25f;
+ else
+ ang = 3.1415926535898f*0.5f;
+ }
+ else if (j==FCGSY/2-1) {
+ if (i < FCGSX/2-1)
+ ang = 3.1415926535898f*1.0f;
+ else if (i == FCGSX/2-1)
+ ang = 3.1415926535898f*1.25f;
+ else if (i == FCGSX/2)
+ ang = 3.1415926535898f*1.75f;
+ else
+ ang = 3.1415926535898f*2.0f;
+ }
+ else if (j==FCGSY/2) {
+ if (i < FCGSX/2-1)
+ ang = 3.1415926535898f*1.0f;
+ else if (i == FCGSX/2-1)
+ ang = 3.1415926535898f*0.75f;
+ else if (i == FCGSX/2)
+ ang = 3.1415926535898f*0.25f;
+ else
+ ang = 3.1415926535898f*0.0f;
+ }
+ p->tu = u;
+ p->tv = v;
+ //p->tu_orig = u;
+ //p->tv_orig = v;
+ p->rad = rad;
+ p->ang = ang;
+ p->Diffuse = 0xFFFFFFFF;
+ }
+ }
+
+ // build index list for final composite blit -
+ // order should be friendly for interpolation of 'ang' value!
+ int* cur_index = &m_comp_indices[0];
+ int y = 0;
+ for (y=0; y<FCGSY-1; y++)
+ {
+ if (y==FCGSY/2-1)
+ continue;
+ for (int x=0; x<FCGSX-1; x++)
+ {
+ if (x==FCGSX/2-1)
+ continue;
+ bool left_half = (x < FCGSX/2);
+ bool top_half = (y < FCGSY/2);
+ bool center_4 = ((x==FCGSX/2 || x==FCGSX/2-1) && (y==FCGSY/2 || y==FCGSY/2-1));
+
+ if ( ((int)left_half + (int)top_half + (int)center_4) % 2 )
+ {
+ *(cur_index+0) = (y )*FCGSX + (x );
+ *(cur_index+1) = (y )*FCGSX + (x+1);
+ *(cur_index+2) = (y+1)*FCGSX + (x+1);
+ *(cur_index+3) = (y+1)*FCGSX + (x+1);
+ *(cur_index+4) = (y+1)*FCGSX + (x );
+ *(cur_index+5) = (y )*FCGSX + (x );
+ }
+ else
+ {
+ *(cur_index+0) = (y+1)*FCGSX + (x );
+ *(cur_index+1) = (y )*FCGSX + (x );
+ *(cur_index+2) = (y )*FCGSX + (x+1);
+ *(cur_index+3) = (y )*FCGSX + (x+1);
+ *(cur_index+4) = (y+1)*FCGSX + (x+1);
+ *(cur_index+5) = (y+1)*FCGSX + (x );
+ }
+ cur_index += 6;
+ }
+ }
+
+ // -----------------
+
+ /*if (m_bFixSlowText && !m_bSeparateTextWindow)
+ {
+ if (pCreateTexture(GetDevice(), GetWidth(), GetHeight(), 1, D3DUSAGE_RENDERTARGET, GetBackBufFormat(), D3DPOOL_DEFAULT, &m_lpDDSText) != D3D_OK)
+ {
+ char buf[2048];
+ dumpmsg("Init: -WARNING-:");
+ sprintf(buf, "WARNING: Not enough video memory to make a dedicated text surface; \rtext will still be drawn directly to the back buffer.\r\rTo avoid seeing this error again, uncheck the 'fix slow text' option.");
+ dumpmsg(buf);
+ if (!m_bWarningsDisabled)
+ MessageBox(GetPluginWindow(), buf, "WARNING", MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ m_lpDDSText = NULL;
+ }
+ }*/
+
+ // -----------------
+
+ // reallocate the texture for font titles + custom msgs (m_lpDDSTitle)
+ {
+ m_nTitleTexSizeX = max(m_nTexSizeX, m_nTexSizeY);
+ m_nTitleTexSizeY = m_nTitleTexSizeX/4;
+
+ //dumpmsg("Init: [re]allocating title surface");
+
+ // [DEPRECATED as of transition to dx9:]
+ // We could just create one title surface, but this is a problem because many
+ // systems can only call DrawText on DDSCAPS_OFFSCREENPLAIN surfaces, and can NOT
+ // draw text on a DDSCAPS_TEXTURE surface (it comes out garbled).
+ // So, we create one of each; we draw the text to the DDSCAPS_OFFSCREENPLAIN surface
+ // (m_lpDDSTitle[1]), then we blit that (once) to the DDSCAPS_TEXTURE surface
+ // (m_lpDDSTitle[0]), which can then be drawn onto the screen on polys.
+
+ HRESULT hr;
+
+ do
+ {
+ hr = pCreateTexture(GetDevice(), m_nTitleTexSizeX, m_nTitleTexSizeY, 1, D3DUSAGE_RENDERTARGET, GetBackBufFormat(), D3DPOOL_DEFAULT, &m_lpDDSTitle);
+ if (hr != D3D_OK)
+ {
+ if (m_nTitleTexSizeY < m_nTitleTexSizeX)
+ {
+ m_nTitleTexSizeY *= 2;
+ }
+ else
+ {
+ m_nTitleTexSizeX /= 2;
+ m_nTitleTexSizeY /= 2;
+ }
+ }
+ }
+ while (hr != D3D_OK && m_nTitleTexSizeX > 16);
+
+ if (hr != D3D_OK)
+ {
+ //dumpmsg("Init: -WARNING-: Title texture could not be created!");
+ m_lpDDSTitle = NULL;
+ //SafeRelease(m_lpDDSTitle);
+ //return true;
+ }
+ else
+ {
+ //sprintf(buf, "Init: title texture size is %dx%d (ideal size was %dx%d)", m_nTitleTexSizeX, m_nTitleTexSizeY, m_nTexSize, m_nTexSize/4);
+ //dumpmsg(buf);
+ m_supertext.bRedrawSuperText = true;
+ }
+ }
+
+ // -----------------
+
+ // create 'm_gdi_title_font_doublesize'
+ int songtitle_font_size = m_fontinfo[SONGTITLE_FONT].nSize * m_nTitleTexSizeX/256;
+ if (songtitle_font_size<6) songtitle_font_size=6;
+ if (!(m_gdi_title_font_doublesize = CreateFontW(songtitle_font_size, 0, 0, 0, m_fontinfo[SONGTITLE_FONT].bBold ? 900 : 400,
+ m_fontinfo[SONGTITLE_FONT].bItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, m_fontinfo[SONGTITLE_FONT].bAntiAliased ? ANTIALIASED_QUALITY : DEFAULT_QUALITY, DEFAULT_PITCH, m_fontinfo[SONGTITLE_FONT].szFace)))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_DOUBLE_SIZED_GDI_TITLE_FONT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,sizeof(title)),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ if (pCreateFontW( GetDevice(),
+ songtitle_font_size,
+ 0,
+ m_fontinfo[SONGTITLE_FONT].bBold ? 900 : 400,
+ 1,
+ m_fontinfo[SONGTITLE_FONT].bItalic,
+ DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ ANTIALIASED_QUALITY,//DEFAULT_QUALITY,
+ DEFAULT_PITCH,
+ m_fontinfo[SONGTITLE_FONT].szFace,
+ &m_d3dx_title_font_doublesize
+ ) != D3D_OK)
+ {
+ MessageBoxW(GetPluginWindow(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_DOUBLE_SIZED_D3DX_TITLE_FONT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,sizeof(title)), MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ // -----------------
+
+ m_texmgr.Init(GetDevice());
+
+ //dumpmsg("Init: mesh allocation");
+ m_verts = new MYVERTEX[(m_nGridX+1)*(m_nGridY+1)];
+ m_verts_temp = new MYVERTEX[(m_nGridX+2) * 4];
+ m_vertinfo = new td_vertinfo[(m_nGridX+1)*(m_nGridY+1)];
+ m_indices_strip = new int[(m_nGridX+2)*(m_nGridY*2)];
+ m_indices_list = new int[m_nGridX*m_nGridY*6];
+ if (!m_verts || !m_vertinfo)
+ {
+ swprintf(buf, L"couldn't allocate mesh - out of memory");
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ int nVert = 0;
+ float texel_offset_x = 0.5f / (float)m_nTexSizeX;
+ float texel_offset_y = 0.5f / (float)m_nTexSizeY;
+ for (y=0; y<=m_nGridY; y++)
+ {
+ for (int x=0; x<=m_nGridX; x++)
+ {
+ // precompute x,y,z
+ m_verts[nVert].x = x/(float)m_nGridX*2.0f - 1.0f;
+ m_verts[nVert].y = y/(float)m_nGridY*2.0f - 1.0f;
+ m_verts[nVert].z = 0.0f;
+
+ // precompute rad, ang, being conscious of aspect ratio
+ m_vertinfo[nVert].rad = sqrtf(m_verts[nVert].x*m_verts[nVert].x*m_fAspectX*m_fAspectX + m_verts[nVert].y*m_verts[nVert].y*m_fAspectY*m_fAspectY);
+ if (y==m_nGridY/2 && x==m_nGridX/2)
+ m_vertinfo[nVert].ang = 0.0f;
+ else
+ m_vertinfo[nVert].ang = atan2f(m_verts[nVert].y*m_fAspectY, m_verts[nVert].x*m_fAspectX);
+ m_vertinfo[nVert].a = 1;
+ m_vertinfo[nVert].c = 0;
+
+ m_verts[nVert].rad = m_vertinfo[nVert].rad;
+ m_verts[nVert].ang = m_vertinfo[nVert].ang;
+ m_verts[nVert].tu_orig = m_verts[nVert].x*0.5f + 0.5f + texel_offset_x;
+ m_verts[nVert].tv_orig = -m_verts[nVert].y*0.5f + 0.5f + texel_offset_y;
+
+ nVert++;
+ }
+ }
+
+ // generate triangle strips for the 4 quadrants.
+ // each quadrant has m_nGridY/2 strips.
+ // each strip has m_nGridX+2 *points* in it, or m_nGridX/2 polygons.
+ int xref, yref;
+ int nVert_strip = 0;
+ for (int quadrant=0; quadrant<4; quadrant++)
+ {
+ for (int slice=0; slice < m_nGridY/2; slice++)
+ {
+ for (int i=0; i < m_nGridX + 2; i++)
+ {
+ // quadrants: 2 3
+ // 0 1
+ xref = i/2;
+ yref = (i%2) + slice;
+
+ if (quadrant & 1)
+ xref = m_nGridX - xref;
+ if (quadrant & 2)
+ yref = m_nGridY - yref;
+
+ int v = xref + (yref)*(m_nGridX+1);
+
+ m_indices_strip[nVert_strip++] = v;
+ }
+ }
+ }
+
+ // also generate triangle lists for drawing the main warp mesh.
+ int nVert_list = 0;
+ for (int quadrant=0; quadrant<4; quadrant++)
+ {
+ for (int slice=0; slice < m_nGridY/2; slice++)
+ {
+ for (int i=0; i < m_nGridX/2; i++)
+ {
+ // quadrants: 2 3
+ // 0 1
+ xref = i;
+ yref = slice;
+
+ if (quadrant & 1)
+ xref = m_nGridX-1 - xref;
+ if (quadrant & 2)
+ yref = m_nGridY-1 - yref;
+
+ int v = xref + (yref)*(m_nGridX+1);
+
+ m_indices_list[nVert_list++] = v;
+ m_indices_list[nVert_list++] = v +1;
+ m_indices_list[nVert_list++] = v+m_nGridX+1 ;
+ m_indices_list[nVert_list++] = v +1;
+ m_indices_list[nVert_list++] = v+m_nGridX+1 ;
+ m_indices_list[nVert_list++] = v+m_nGridX+1+1;
+ }
+ }
+ }
+
+ // GENERATED TEXTURES FOR SHADERS
+ //-------------------------------------
+ if (m_nMaxPSVersion > 0)
+ {
+ // Generate noise textures
+ if (!AddNoiseTex(L"noise_lq", 256, 1)) return false;
+ if (!AddNoiseTex(L"noise_lq_lite", 32, 1)) return false;
+ if (!AddNoiseTex(L"noise_mq", 256, 4)) return false;
+ if (!AddNoiseTex(L"noise_hq", 256, 8)) return false;
+
+ if (!AddNoiseVol(L"noisevol_lq", 32, 1)) return false;
+ if (!AddNoiseVol(L"noisevol_hq", 32, 4)) return false;
+ }
+
+ if (!m_bInitialPresetSelected)
+ {
+ UpdatePresetList(true); //...just does its initial burst!
+ LoadRandomPreset(0.0f);
+ m_bInitialPresetSelected = true;
+ }
+ else
+ LoadShaders(&m_shaders, m_pState, false); // Also force-load the shaders - otherwise they'd only get compiled on a preset switch.
+
+ return true;
+}
+
+float fCubicInterpolate(float y0, float y1, float y2, float y3, float t)
+{
+ float a0,a1,a2,a3,t2;
+
+ t2 = t*t;
+ a0 = y3 - y2 - y0 + y1;
+ a1 = y0 - y1 - a0;
+ a2 = y2 - y0;
+ a3 = y1;
+
+ return(a0*t*t2+a1*t2+a2*t+a3);
+}
+
+DWORD dwCubicInterpolate(DWORD y0, DWORD y1, DWORD y2, DWORD y3, float t)
+{
+ // performs cubic interpolation on a D3DCOLOR value.
+ DWORD ret = 0;
+ DWORD shift = 0;
+ for (int i=0; i<4; i++)
+ {
+ float f = fCubicInterpolate(
+ ((y0 >> shift) & 0xFF)/255.0f,
+ ((y1 >> shift) & 0xFF)/255.0f,
+ ((y2 >> shift) & 0xFF)/255.0f,
+ ((y3 >> shift) & 0xFF)/255.0f,
+ t
+ );
+ if (f<0)
+ f = 0;
+ if (f>1)
+ f = 1;
+ ret |= ((DWORD)(f*255)) << shift;
+ shift += 8;
+ }
+ return ret;
+}
+
+bool CPlugin::AddNoiseTex(const wchar_t* szTexName, int size, int zoom_factor)
+{
+ // size = width & height of the texture;
+ // zoom_factor = how zoomed-in the texture features should be.
+ // 1 = random noise
+ // 2 = smoothed (interp)
+ // 4/8/16... = cubic interp.
+
+ wchar_t buf[2048], title[64];
+
+ // Synthesize noise texture(s)
+ LPDIRECT3DTEXTURE9 pNoiseTex = NULL;
+ // try twice - once with mips, once without.
+ for (int i=0; i<2; i++)
+ {
+ if (D3D_OK != GetDevice()->CreateTexture(size, size, i, D3DUSAGE_DYNAMIC | (i ? 0 : D3DUSAGE_AUTOGENMIPMAP), D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pNoiseTex, NULL))
+ {
+ if (i==1)
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_CREATE_NOISE_TEXTURE,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ }
+ else
+ break;
+ }
+
+ D3DLOCKED_RECT r;
+ if (D3D_OK != pNoiseTex->LockRect(0, &r, NULL, D3DLOCK_DISCARD))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_LOCK_NOISE_TEXTURE,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ if (r.Pitch < size*4)
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_NOISE_TEXTURE_BYTE_LAYOUT_NOT_RECOGNISED,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ // write to the bits...
+ DWORD* dst = (DWORD*)r.pBits;
+ int dwords_per_line = r.Pitch / sizeof(DWORD);
+ int RANGE = (zoom_factor > 1) ? 216 : 256;
+ for (int y=0; y<size; y++) {
+ LARGE_INTEGER q;
+ QueryPerformanceCounter(&q);
+ srand(q.LowPart ^ q.HighPart ^ warand());
+ int x = 0;
+ for (x=0; x<size; x++) {
+ dst[x] = (((DWORD)(warand() % RANGE)+RANGE/2) << 24) |
+ (((DWORD)(warand() % RANGE)+RANGE/2) << 16) |
+ (((DWORD)(warand() % RANGE)+RANGE/2) << 8) |
+ (((DWORD)(warand() % RANGE)+RANGE/2) );
+ }
+ // swap some pixels randomly, to improve 'randomness'
+ for (x=0; x<size; x++)
+ {
+ int x1 = (warand() ^ q.LowPart ) % size;
+ int x2 = (warand() ^ q.HighPart) % size;
+ DWORD temp = dst[x2];
+ dst[x2] = dst[x1];
+ dst[x1] = temp;
+ }
+ dst += dwords_per_line;
+ }
+
+ // smoothing
+ if (zoom_factor > 1)
+ {
+ // first go ACROSS, blending cubically on X, but only on the main lines.
+ DWORD* dst = (DWORD*)r.pBits;
+ for (int y=0; y<size; y+=zoom_factor)
+ for (int x=0; x<size; x++)
+ if (x % zoom_factor)
+ {
+ int base_x = (x/zoom_factor)*zoom_factor + size;
+ int base_y = y*dwords_per_line;
+ DWORD y0 = dst[ base_y + ((base_x - zoom_factor ) % size) ];
+ DWORD y1 = dst[ base_y + ((base_x ) % size) ];
+ DWORD y2 = dst[ base_y + ((base_x + zoom_factor ) % size) ];
+ DWORD y3 = dst[ base_y + ((base_x + zoom_factor*2) % size) ];
+
+ float t = (x % zoom_factor)/(float)zoom_factor;
+
+ DWORD result = dwCubicInterpolate(y0, y1, y2, y3, t);
+
+ dst[ y*dwords_per_line + x ] = result;
+ }
+
+ // next go down, doing cubic interp along Y, on every line.
+ for (int x=0; x<size; x++)
+ for (int y=0; y<size; y++)
+ if (y % zoom_factor)
+ {
+ int base_y = (y/zoom_factor)*zoom_factor + size;
+ DWORD y0 = dst[ ((base_y - zoom_factor ) % size)*dwords_per_line + x ];
+ DWORD y1 = dst[ ((base_y ) % size)*dwords_per_line + x ];
+ DWORD y2 = dst[ ((base_y + zoom_factor ) % size)*dwords_per_line + x ];
+ DWORD y3 = dst[ ((base_y + zoom_factor*2) % size)*dwords_per_line + x ];
+
+ float t = (y % zoom_factor)/(float)zoom_factor;
+
+ DWORD result = dwCubicInterpolate(y0, y1, y2, y3, t);
+
+ dst[ y*dwords_per_line + x ] = result;
+ }
+
+ }
+
+ // unlock texture
+ pNoiseTex->UnlockRect(0);
+
+ // add it to m_textures[].
+ TexInfo x;
+ lstrcpyW(x.texname, szTexName);
+ x.texptr = pNoiseTex;
+ //x.texsize_param = NULL;
+ x.w = size;
+ x.h = size;
+ x.d = 1;
+ x.bEvictable = false;
+ x.nAge = m_nPresetsLoadedTotal;
+ x.nSizeInBytes = 0;
+ m_textures.push_back(x);
+
+ return true;
+}
+
+bool CPlugin::AddNoiseVol(const wchar_t* szTexName, int size, int zoom_factor)
+{
+ // size = width & height & depth of the texture;
+ // zoom_factor = how zoomed-in the texture features should be.
+ // 1 = random noise
+ // 2 = smoothed (interp)
+ // 4/8/16... = cubic interp.
+
+ wchar_t buf[2048], title[64];
+
+ // Synthesize noise texture(s)
+ LPDIRECT3DVOLUMETEXTURE9 pNoiseTex = NULL;
+ // try twice - once with mips, once without.
+ // NO, TRY JUST ONCE - DX9 doesn't do auto mipgen w/volume textures. (Debug runtime complains.)
+ for (int i=1; i<2; i++)
+ {
+ if (D3D_OK != GetDevice()->CreateVolumeTexture(size, size, size, i, D3DUSAGE_DYNAMIC | (i ? 0 : D3DUSAGE_AUTOGENMIPMAP), D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pNoiseTex, NULL))
+ {
+ if (i==1)
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_CREATE_3D_NOISE_TEXTURE,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ }
+ else
+ break;
+ }
+ D3DLOCKED_BOX r;
+ if (D3D_OK != pNoiseTex->LockBox(0, &r, NULL, D3DLOCK_DISCARD))
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_COULD_NOT_LOCK_3D_NOISE_TEXTURE,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ if (r.RowPitch < size*4 || r.SlicePitch < size*size*4)
+ {
+ WASABI_API_LNGSTRINGW_BUF(IDS_3D_NOISE_TEXTURE_BYTE_LAYOUT_NOT_RECOGNISED,buf,sizeof(buf));
+ dumpmsg(buf);
+ MessageBoxW(GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+ // write to the bits...
+ int dwords_per_slice = r.SlicePitch / sizeof(DWORD);
+ int dwords_per_line = r.RowPitch / sizeof(DWORD);
+ int RANGE = (zoom_factor > 1) ? 216 : 256;
+ for (int z=0; z<size; z++) {
+ DWORD* dst = (DWORD*)r.pBits + z*dwords_per_slice;
+ for (int y=0; y<size; y++) {
+ LARGE_INTEGER q;
+ QueryPerformanceCounter(&q);
+ srand(q.LowPart ^ q.HighPart ^ warand());
+ int x = 0;
+ for (x=0; x<size; x++) {
+ dst[x] = (((DWORD)(warand() % RANGE)+RANGE/2) << 24) |
+ (((DWORD)(warand() % RANGE)+RANGE/2) << 16) |
+ (((DWORD)(warand() % RANGE)+RANGE/2) << 8) |
+ (((DWORD)(warand() % RANGE)+RANGE/2) );
+ }
+ // swap some pixels randomly, to improve 'randomness'
+ for (x=0; x<size; x++)
+ {
+ int x1 = (warand() ^ q.LowPart ) % size;
+ int x2 = (warand() ^ q.HighPart) % size;
+ DWORD temp = dst[x2];
+ dst[x2] = dst[x1];
+ dst[x1] = temp;
+ }
+ dst += dwords_per_line;
+ }
+ }
+
+ // smoothing
+ if (zoom_factor > 1)
+ {
+ // first go ACROSS, blending cubically on X, but only on the main lines.
+ DWORD* dst = (DWORD*)r.pBits;
+ for (int z=0; z<size; z+=zoom_factor)
+ for (int y=0; y<size; y+=zoom_factor)
+ for (int x=0; x<size; x++)
+ if (x % zoom_factor)
+ {
+ int base_x = (x/zoom_factor)*zoom_factor + size;
+ int base_y = z*dwords_per_slice + y*dwords_per_line;
+ DWORD y0 = dst[ base_y + ((base_x - zoom_factor ) % size) ];
+ DWORD y1 = dst[ base_y + ((base_x ) % size) ];
+ DWORD y2 = dst[ base_y + ((base_x + zoom_factor ) % size) ];
+ DWORD y3 = dst[ base_y + ((base_x + zoom_factor*2) % size) ];
+
+ float t = (x % zoom_factor)/(float)zoom_factor;
+
+ DWORD result = dwCubicInterpolate(y0, y1, y2, y3, t);
+
+ dst[ z*dwords_per_slice + y*dwords_per_line + x ] = result;
+ }
+
+ // next go down, doing cubic interp along Y, on the main slices.
+ for (int z=0; z<size; z+=zoom_factor)
+ for (int x=0; x<size; x++)
+ for (int y=0; y<size; y++)
+ if (y % zoom_factor)
+ {
+ int base_y = (y/zoom_factor)*zoom_factor + size;
+ int base_z = z*dwords_per_slice;
+ DWORD y0 = dst[ ((base_y - zoom_factor ) % size)*dwords_per_line + base_z + x ];
+ DWORD y1 = dst[ ((base_y ) % size)*dwords_per_line + base_z + x ];
+ DWORD y2 = dst[ ((base_y + zoom_factor ) % size)*dwords_per_line + base_z + x ];
+ DWORD y3 = dst[ ((base_y + zoom_factor*2) % size)*dwords_per_line + base_z + x ];
+
+ float t = (y % zoom_factor)/(float)zoom_factor;
+
+ DWORD result = dwCubicInterpolate(y0, y1, y2, y3, t);
+
+ dst[ y*dwords_per_line + base_z + x ] = result;
+ }
+
+ // next go through, doing cubic interp along Z, everywhere.
+ for (int x=0; x<size; x++)
+ for (int y=0; y<size; y++)
+ for (int z=0; z<size; z++)
+ if (z % zoom_factor)
+ {
+ int base_y = y*dwords_per_line;
+ int base_z = (z/zoom_factor)*zoom_factor + size;
+ DWORD y0 = dst[ ((base_z - zoom_factor ) % size)*dwords_per_slice + base_y + x ];
+ DWORD y1 = dst[ ((base_z ) % size)*dwords_per_slice + base_y + x ];
+ DWORD y2 = dst[ ((base_z + zoom_factor ) % size)*dwords_per_slice + base_y + x ];
+ DWORD y3 = dst[ ((base_z + zoom_factor*2) % size)*dwords_per_slice + base_y + x ];
+
+ float t = (z % zoom_factor)/(float)zoom_factor;
+
+ DWORD result = dwCubicInterpolate(y0, y1, y2, y3, t);
+
+ dst[ z*dwords_per_slice + base_y + x ] = result;
+ }
+
+ }
+
+ // unlock texture
+ pNoiseTex->UnlockBox(0);
+
+ // add it to m_textures[].
+ TexInfo x;
+ lstrcpyW(x.texname, szTexName);
+ x.texptr = pNoiseTex;
+ //x.texsize_param = NULL;
+ x.w = size;
+ x.h = size;
+ x.d = size;
+ x.bEvictable = false;
+ x.nAge = m_nPresetsLoadedTotal;
+ x.nSizeInBytes = 0;
+ m_textures.push_back(x);
+
+ return true;
+}
+
+void VShaderInfo::Clear()
+{
+ SafeRelease(ptr);
+ SafeRelease(CT);
+ params.Clear();
+}
+void PShaderInfo::Clear()
+{
+ SafeRelease(ptr);
+ SafeRelease(CT);
+ params.Clear();
+}
+
+// global_CShaderParams_master_list: a master list of all CShaderParams classes in existence.
+// ** when we evict a texture, we need to NULL out any texptrs these guys have! **
+CShaderParamsList global_CShaderParams_master_list;
+CShaderParams::CShaderParams() {
+ global_CShaderParams_master_list.push_back(this);
+}
+
+CShaderParams::~CShaderParams() {
+ int N = global_CShaderParams_master_list.size();
+ for (int i=0; i<N; i++)
+ if (global_CShaderParams_master_list[i] == this)
+ {
+ global_CShaderParams_master_list.erase(global_CShaderParams_master_list.begin() + i);
+ break;
+ }
+
+ texsize_params.clear();
+}
+
+void CShaderParams::OnTextureEvict(LPDIRECT3DBASETEXTURE9 texptr)
+{
+ for (int i=0; i<sizeof(m_texture_bindings)/sizeof(m_texture_bindings[0]); i++)
+ if (m_texture_bindings[i].texptr == texptr)
+ m_texture_bindings[i].texptr = NULL;
+}
+
+void CShaderParams::Clear()
+{
+ // float4 handles:
+ rand_frame = NULL;
+ rand_preset = NULL;
+
+ ZeroMemory(rot_mat, sizeof(rot_mat));
+ ZeroMemory(const_handles, sizeof(const_handles));
+ ZeroMemory(q_const_handles, sizeof(q_const_handles));
+ texsize_params.clear();
+
+ // sampler stages for various PS texture bindings:
+ for (int i=0; i<sizeof(m_texture_bindings)/sizeof(m_texture_bindings[0]); i++)
+ {
+ m_texture_bindings[i].texptr = NULL;
+ m_texcode[i] = TEX_DISK;
+ }
+}
+
+bool CPlugin::EvictSomeTexture()
+{
+ // note: this won't evict a texture whose age is zero,
+ // or whose reported size is zero!
+
+ #if _DEBUG
+ {
+ int nEvictableFiles = 0;
+ int nEvictableBytes = 0;
+ int N = m_textures.size();
+ for (int i=0; i<N; i++)
+ if (m_textures[i].bEvictable && m_textures[i].texptr)
+ {
+ nEvictableFiles++;
+ nEvictableBytes += m_textures[i].nSizeInBytes;
+ }
+ char buf[1024];
+ sprintf(buf, "evicting at %d textures, %.1f MB\n", nEvictableFiles, nEvictableBytes*0.000001f);
+ OutputDebugString(buf);
+ }
+ #endif
+
+ int N = m_textures.size();
+
+ // find age gap
+ int newest = 99999999;
+ int oldest = 0;
+ bool bAtLeastOneFound = false;
+ int i = 0;
+ for (i=0; i<N; i++)
+ if (m_textures[i].bEvictable && m_textures[i].nSizeInBytes>0 && m_textures[i].nAge < m_nPresetsLoadedTotal-1) // note: -1 here keeps images around for the blend-from preset, too...
+ {
+ newest = min(newest, m_textures[i].nAge);
+ oldest = max(oldest, m_textures[i].nAge);
+ bAtLeastOneFound = true;
+ }
+ if (!bAtLeastOneFound)
+ return false;
+
+ // find the "biggest" texture, but dilate things so that the newest textures
+ // are HALF as big as the oldest textures, and thus, less likely to get booted.
+ int biggest_bytes = 0;
+ int biggest_index = -1;
+ for (i=0; i<N; i++)
+ if (m_textures[i].bEvictable && m_textures[i].nSizeInBytes>0 && m_textures[i].nAge < m_nPresetsLoadedTotal-1) // note: -1 here keeps images around for the blend-from preset, too...
+ {
+ float size_mult = 1.0f + (m_textures[i].nAge - newest)/(float)(oldest-newest);
+ int bytes = (int)(m_textures[i].nSizeInBytes * size_mult);
+ if (bytes > biggest_bytes)
+ {
+ biggest_bytes = bytes;
+ biggest_index = i;
+ }
+ }
+ if (biggest_index == -1)
+ return false;
+
+
+ // evict that sucker
+ assert(m_textures[biggest_index].texptr);
+
+ // notify all CShaderParams classes that we're releasing a bindable texture!!
+ N = global_CShaderParams_master_list.size();
+ for (i=0; i<N; i++)
+ global_CShaderParams_master_list[i]->OnTextureEvict( m_textures[biggest_index].texptr );
+
+ // 2. erase the texture itself
+ SafeRelease(m_textures[biggest_index].texptr);
+ m_textures.erase(m_textures.begin() + biggest_index);
+
+ return true;
+}
+
+GString texture_exts[] = { L"jpg", L"dds", L"png", L"tga", L"bmp", L"dib", };
+const wchar_t szExtsWithSlashes[] = L"jpg|png|dds|etc.";
+typedef std::vector<GString> StringVec;
+bool PickRandomTexture(const wchar_t* prefix, wchar_t* szRetTextureFilename) //should be MAX_PATH chars
+{
+ static StringVec texfiles;
+ static DWORD texfiles_timestamp = 0; // update this a max of every ~2 seconds or so
+
+ // if it's been more than a few seconds since the last textures dir scan, redo it.
+ // (..just enough to make sure we don't do it more than once per preset load)
+ //DWORD t = timeGetTime(); // in milliseconds
+ //if (abs(t - texfiles_timestamp) > 2000)
+ if (g_plugin.m_bNeedRescanTexturesDir)
+ {
+ g_plugin.m_bNeedRescanTexturesDir = false;//texfiles_timestamp = t;
+ texfiles.clear();
+
+ wchar_t szMask[MAX_PATH];
+ swprintf(szMask, L"%stextures\\*.*", g_plugin.m_szMilkdrop2Path);
+
+ WIN32_FIND_DATAW ffd = {0};
+
+ HANDLE hFindFile = INVALID_HANDLE_VALUE;
+ if( (hFindFile = FindFirstFileW(szMask, &ffd )) == INVALID_HANDLE_VALUE ) // note: returns filename -without- path
+ return false;
+
+ // first, count valid texture files
+ do
+ {
+ if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ continue;
+
+ wchar_t* ext = wcsrchr(ffd.cFileName, L'.');
+ if (!ext)
+ continue;
+
+ for (int i=0; i<sizeof(texture_exts)/sizeof(texture_exts[0]); i++)
+ if (!wcsicmp(texture_exts[i].c_str(), ext+1))
+ {
+ // valid texture found - add it to the list. ("heart.jpg", for example)
+ texfiles.push_back( ffd.cFileName );
+ continue;
+ }
+ }
+ while (FindNextFileW(hFindFile, &ffd));
+ FindClose(hFindFile);
+ }
+
+ if (texfiles.size() == 0)
+ return false;
+
+ // then randomly pick one
+ if (prefix==NULL || prefix[0]==0)
+ {
+ // pick randomly from entire list
+ int i = warand() % texfiles.size();
+ lstrcpyW(szRetTextureFilename, texfiles[i].c_str());
+ }
+ else
+ {
+ // only pick from files w/the right prefix
+ StringVec temp_list;
+ int N = texfiles.size();
+ int len = lstrlenW(prefix);
+ for (int i=0; i<N; i++)
+ if (!_wcsnicmp(prefix, texfiles[i].c_str(), len))
+ temp_list.push_back(texfiles[i]);
+ N = temp_list.size();
+ if (N==0)
+ return false;
+ // pick randomly from the subset
+ int i = warand() % temp_list.size();
+ lstrcpyW(szRetTextureFilename, temp_list[i].c_str());
+ }
+ return true;
+}
+
+void CShaderParams::CacheParams(LPD3DXCONSTANTTABLE pCT, bool bHardErrors)
+{
+ Clear();
+
+ if (!pCT)
+ return;
+
+ D3DXCONSTANTTABLE_DESC d;
+ pCT->GetDesc(&d);
+
+ D3DXCONSTANT_DESC cd;
+
+ #define MAX_RAND_TEX 16
+ GString RandTexName[MAX_RAND_TEX];
+
+ // pass 1: find all the samplers (and texture bindings).
+ UINT i = 0;
+ for (i=0; i<d.Constants; i++)
+ {
+ D3DXHANDLE h = pCT->GetConstant(NULL, i);
+ unsigned int count = 1;
+ pCT->GetConstantDesc(h, &cd, &count);
+
+ // cd.Name = VS_Sampler
+ // cd.RegisterSet = D3DXRS_SAMPLER
+ // cd.RegisterIndex = 3
+ if (cd.RegisterSet == D3DXRS_SAMPLER && cd.RegisterIndex >= 0 && cd.RegisterIndex < sizeof(m_texture_bindings)/sizeof(m_texture_bindings[0]))
+ {
+ assert(m_texture_bindings[cd.RegisterIndex].texptr == NULL);
+
+ // remove "sampler_" prefix to create root file name. could still have "FW_" prefix or something like that.
+ wchar_t szRootName[MAX_PATH];
+ if (!strncmp(cd.Name, "sampler_", 8))
+ lstrcpyW(szRootName, AutoWide(&cd.Name[8]));
+ else
+ lstrcpyW(szRootName, AutoWide(cd.Name));
+
+ // also peel off "XY_" prefix, if it's there, to specify filtering & wrap mode.
+ bool bBilinear = true;
+ bool bWrap = true;
+ bool bWrapFilterSpecified = false;
+ if (lstrlenW(szRootName) > 3 && szRootName[2]==L'_')
+ {
+ wchar_t temp[3];
+ temp[0] = szRootName[0];
+ temp[1] = szRootName[1];
+ temp[2] = 0;
+ // convert to uppercase
+ if (temp[0] >= L'a' && temp[0] <= L'z')
+ temp[0] -= L'a' - L'A';
+ if (temp[1] >= L'a' && temp[1] <= L'z')
+ temp[1] -= L'a' - L'A';
+
+ if (!wcscmp(temp, L"FW")) { bWrapFilterSpecified = true; bBilinear = true; bWrap = true; }
+ else if (!wcscmp(temp, L"FC")) { bWrapFilterSpecified = true; bBilinear = true; bWrap = false; }
+ else if (!wcscmp(temp, L"PW")) { bWrapFilterSpecified = true; bBilinear = false; bWrap = true; }
+ else if (!wcscmp(temp, L"PC")) { bWrapFilterSpecified = true; bBilinear = false; bWrap = false; }
+ // also allow reverses:
+ else if (!wcscmp(temp, L"WF")) { bWrapFilterSpecified = true; bBilinear = true; bWrap = true; }
+ else if (!wcscmp(temp, L"CF")) { bWrapFilterSpecified = true; bBilinear = true; bWrap = false; }
+ else if (!wcscmp(temp, L"WP")) { bWrapFilterSpecified = true; bBilinear = false; bWrap = true; }
+ else if (!wcscmp(temp, L"CP")) { bWrapFilterSpecified = true; bBilinear = false; bWrap = false; }
+
+ // peel off the prefix
+ int i = 0;
+ while (szRootName[i+3])
+ {
+ szRootName[i] = szRootName[i+3];
+ i++;
+ }
+ szRootName[i] = 0;
+ }
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = bWrap;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = bBilinear;
+
+ // if <szFileName> is "main", map it to the VS...
+ if (!wcscmp(L"main", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = NULL;
+ m_texcode[ cd.RegisterIndex ] = TEX_VS;
+ }
+ #if (NUM_BLUR_TEX >= 2)
+ else if (!wcscmp(L"blur1", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_lpBlur[1];
+ m_texcode [ cd.RegisterIndex ] = TEX_BLUR1;
+ if (!bWrapFilterSpecified) { // when sampling blur textures, default is CLAMP
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = false;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = true;
+ }
+ }
+ #endif
+ #if (NUM_BLUR_TEX >= 4)
+ else if (!wcscmp(L"blur2", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_lpBlur[3];
+ m_texcode [ cd.RegisterIndex ] = TEX_BLUR2;
+ if (!bWrapFilterSpecified) { // when sampling blur textures, default is CLAMP
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = false;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = true;
+ }
+ }
+ #endif
+ #if (NUM_BLUR_TEX >= 6)
+ else if (!wcscmp(L"blur3", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_lpBlur[5];
+ m_texcode [ cd.RegisterIndex ] = TEX_BLUR3;
+ if (!bWrapFilterSpecified) { // when sampling blur textures, default is CLAMP
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = false;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = true;
+ }
+ }
+ #endif
+ #if (NUM_BLUR_TEX >= 8)
+ else if (!wcscmp("blur4", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_lpBlur[7];
+ m_texcode [ cd.RegisterIndex ] = TEX_BLUR4;
+ if (!bWrapFilterSpecified) { // when sampling blur textures, default is CLAMP
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = false;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = true;
+ }
+ }
+ #endif
+ #if (NUM_BLUR_TEX >= 10)
+ else if (!wcscmp("blur5", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_lpBlur[9];
+ m_texcode [ cd.RegisterIndex ] = TEX_BLUR5;
+ if (!bWrapFilterSpecified) { // when sampling blur textures, default is CLAMP
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = false;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = true;
+ }
+ }
+ #endif
+ #if (NUM_BLUR_TEX >= 12)
+ else if (!wcscmp("blur6", szRootName))
+ {
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_lpBlur[11];
+ m_texcode [ cd.RegisterIndex ] = TEX_BLUR6;
+ if (!bWrapFilterSpecified) { // when sampling blur textures, default is CLAMP
+ m_texture_bindings[ cd.RegisterIndex ].bWrap = false;
+ m_texture_bindings[ cd.RegisterIndex ].bBilinear = true;
+ }
+ }
+ #endif
+ else
+ {
+ m_texcode[ cd.RegisterIndex ] = TEX_DISK;
+
+ // check for request for random texture.
+ if (!wcsncmp(L"rand", szRootName, 4) &&
+ IsNumericChar(szRootName[4]) &&
+ IsNumericChar(szRootName[5]) &&
+ (szRootName[6]==0 || szRootName[6]=='_') )
+ {
+ int rand_slot = -1;
+
+ // peel off filename prefix ("rand13_smalltiled", for example)
+ wchar_t prefix[MAX_PATH];
+ if (szRootName[6]==L'_')
+ lstrcpyW(prefix, &szRootName[7]);
+ else
+ prefix[0] = 0;
+ szRootName[6] = 0;
+
+ swscanf(&szRootName[4], L"%d", &rand_slot);
+ if (rand_slot >= 0 && rand_slot <= 15) // otherwise, not a special filename - ignore it
+ {
+ if (!PickRandomTexture(prefix, szRootName))
+ {
+ if (prefix[0])
+ swprintf(szRootName, L"[rand%02d] %s*", rand_slot, prefix);
+ else
+ swprintf(szRootName, L"[rand%02d] *", rand_slot);
+ }
+ else
+ {
+ //chop off extension
+ wchar_t *p = wcsrchr(szRootName, L'.');
+ if (p)
+ *p = 0;
+ }
+
+ assert(RandTexName[rand_slot].GetLength() == 0);
+ RandTexName[rand_slot] = szRootName; // we'll need to remember this for texsize_ params!
+ }
+ }
+
+ // see if <szRootName>.tga or .jpg has already been loaded.
+ // (if so, grab a pointer to it)
+ // (if NOT, create & load it).
+ int N = g_plugin.m_textures.size();
+ for (int n=0; n<N; n++) {
+ if (!wcscmp(g_plugin.m_textures[n].texname, szRootName))
+ {
+ // found a match - texture was already loaded
+ m_texture_bindings[ cd.RegisterIndex ].texptr = g_plugin.m_textures[n].texptr;
+ // also bump its age down to zero! (for cache mgmt)
+ g_plugin.m_textures[n].nAge = g_plugin.m_nPresetsLoadedTotal;
+ break;
+ }
+ }
+ // if still not found, load it up / make a new texture
+ if (!m_texture_bindings[ cd.RegisterIndex ].texptr)
+ {
+ TexInfo x;
+ wcsncpy(x.texname, szRootName, 254);
+ x.texptr = NULL;
+ //x.texsize_param = NULL;
+
+ // check if we need to evict anything from the cache,
+ // due to our own cache constraints...
+ while (1)
+ {
+ int nTexturesCached = 0;
+ int nBytesCached = 0;
+ int N = g_plugin.m_textures.size();
+ for (int i=0; i<N; i++)
+ if (g_plugin.m_textures[i].bEvictable && g_plugin.m_textures[i].texptr)
+ {
+ nBytesCached += g_plugin.m_textures[i].nSizeInBytes;
+ nTexturesCached++;
+ }
+ if ( nTexturesCached < g_plugin.m_nMaxImages &&
+ nBytesCached < g_plugin.m_nMaxBytes )
+ break;
+ // otherwise, evict now - and loop until we are within the constraints
+ if (!g_plugin.EvictSomeTexture())
+ break; // or if there was nothing to evict, just give up
+ }
+
+ //load the texture
+ wchar_t szFilename[MAX_PATH];
+ for (int z=0; z<sizeof(texture_exts)/sizeof(texture_exts[0]); z++)
+ {
+ swprintf(szFilename, L"%stextures\\%s.%s", g_plugin.m_szMilkdrop2Path, szRootName, texture_exts[z].c_str());
+ if (GetFileAttributesW(szFilename) == 0xFFFFFFFF)
+ {
+ // try again, but in presets dir
+ swprintf(szFilename, L"%s%s.%s", g_plugin.m_szPresetDir, szRootName, texture_exts[z].c_str());
+ if (GetFileAttributesW(szFilename) == 0xFFFFFFFF)
+ continue;
+ }
+ D3DXIMAGE_INFO desc;
+
+ // keep trying to load it - if it fails due to memory, evict something and try again.
+ while (1)
+ {
+ HRESULT hr = pCreateTextureFromFileExW(g_plugin.GetDevice(),
+ szFilename,
+ D3DX_DEFAULT_NONPOW2, // w
+ D3DX_DEFAULT_NONPOW2, // h
+ D3DX_DEFAULT, // # mip levels to gen - all
+ 0, // usage flags
+ D3DFMT_UNKNOWN,
+ D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, //filter
+ D3DX_DEFAULT, //mipfilter
+ 0, // color key
+ &desc,
+ NULL, //palette
+ (IDirect3DTexture9**)&x.texptr
+ );
+ if (hr==D3DERR_OUTOFVIDEOMEMORY || hr==E_OUTOFMEMORY)
+ {
+ // out of memory - try evicting something old and/or big
+ if (g_plugin.EvictSomeTexture())
+ continue;
+ }
+
+ if (hr==D3D_OK)
+ {
+ x.w = desc.Width;
+ x.h = desc.Height;
+ x.d = desc.Depth;
+ x.bEvictable = true;
+ x.nAge = g_plugin.m_nPresetsLoadedTotal;
+ int nPixels = desc.Width*desc.Height*max(1,desc.Depth);
+ int BitsPerPixel = GetDX9TexFormatBitsPerPixel(desc.Format);
+ x.nSizeInBytes = nPixels*BitsPerPixel/8 + 16384; //plus some overhead
+ }
+ break;
+ }
+ }
+
+ if (!x.texptr)
+ {
+ wchar_t buf[2048], title[64];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_COULD_NOT_LOAD_TEXTURE_X), szRootName, szExtsWithSlashes);
+ g_plugin.dumpmsg(buf);
+ if (bHardErrors)
+ MessageBoxW(g_plugin.GetPluginWindow(), buf, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ else {
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ return;
+ }
+
+ g_plugin.m_textures.push_back(x);
+ m_texture_bindings[ cd.RegisterIndex ].texptr = x.texptr;
+ }
+ }
+ }
+ }
+
+ // pass 2: bind all the float4's. "texsize_XYZ" params will be filled out via knowledge of loaded texture sizes.
+ for (i=0; i<d.Constants; i++)
+ {
+ D3DXHANDLE h = pCT->GetConstant(NULL, i);
+ unsigned int count = 1;
+ pCT->GetConstantDesc(h, &cd, &count);
+
+ if (cd.RegisterSet == D3DXRS_FLOAT4)
+ {
+ if (cd.Class == D3DXPC_MATRIX_COLUMNS)
+ {
+ if (!strcmp(cd.Name, "rot_s1" )) rot_mat[0] = h;
+ else if (!strcmp(cd.Name, "rot_s2" )) rot_mat[1] = h;
+ else if (!strcmp(cd.Name, "rot_s3" )) rot_mat[2] = h;
+ else if (!strcmp(cd.Name, "rot_s4" )) rot_mat[3] = h;
+ else if (!strcmp(cd.Name, "rot_d1" )) rot_mat[4] = h;
+ else if (!strcmp(cd.Name, "rot_d2" )) rot_mat[5] = h;
+ else if (!strcmp(cd.Name, "rot_d3" )) rot_mat[6] = h;
+ else if (!strcmp(cd.Name, "rot_d4" )) rot_mat[7] = h;
+ else if (!strcmp(cd.Name, "rot_f1" )) rot_mat[8] = h;
+ else if (!strcmp(cd.Name, "rot_f2" )) rot_mat[9] = h;
+ else if (!strcmp(cd.Name, "rot_f3" )) rot_mat[10] = h;
+ else if (!strcmp(cd.Name, "rot_f4" )) rot_mat[11] = h;
+ else if (!strcmp(cd.Name, "rot_vf1")) rot_mat[12] = h;
+ else if (!strcmp(cd.Name, "rot_vf2")) rot_mat[13] = h;
+ else if (!strcmp(cd.Name, "rot_vf3")) rot_mat[14] = h;
+ else if (!strcmp(cd.Name, "rot_vf4")) rot_mat[15] = h;
+ else if (!strcmp(cd.Name, "rot_uf1")) rot_mat[16] = h;
+ else if (!strcmp(cd.Name, "rot_uf2")) rot_mat[17] = h;
+ else if (!strcmp(cd.Name, "rot_uf3")) rot_mat[18] = h;
+ else if (!strcmp(cd.Name, "rot_uf4")) rot_mat[19] = h;
+ else if (!strcmp(cd.Name, "rot_rand1")) rot_mat[20] = h;
+ else if (!strcmp(cd.Name, "rot_rand2")) rot_mat[21] = h;
+ else if (!strcmp(cd.Name, "rot_rand3")) rot_mat[22] = h;
+ else if (!strcmp(cd.Name, "rot_rand4")) rot_mat[23] = h;
+ }
+ else if (cd.Class == D3DXPC_VECTOR)
+ {
+ if (!strcmp(cd.Name, "rand_frame")) rand_frame = h;
+ else if (!strcmp(cd.Name, "rand_preset")) rand_preset = h;
+ else if (!strncmp(cd.Name, "texsize_", 8))
+ {
+ // remove "texsize_" prefix to find root file name.
+ wchar_t szRootName[MAX_PATH];
+ if (!strncmp(cd.Name, "texsize_", 8))
+ lstrcpyW(szRootName, AutoWide(&cd.Name[8]));
+ else
+ lstrcpyW(szRootName, AutoWide(cd.Name));
+
+ // check for request for random texture.
+ // it should be a previously-seen random index - just fetch/reuse the name.
+ if (!wcsncmp(L"rand", szRootName, 4) &&
+ IsNumericChar(szRootName[4]) &&
+ IsNumericChar(szRootName[5]) &&
+ (szRootName[6]==0 || szRootName[6]==L'_') )
+ {
+ int rand_slot = -1;
+
+ // ditch filename prefix ("rand13_smalltiled", for example)
+ // and just go by the slot
+ if (szRootName[6]==L'_')
+ szRootName[6] = 0;
+
+ swscanf(&szRootName[4], L"%d", &rand_slot);
+ if (rand_slot >= 0 && rand_slot <= 15) // otherwise, not a special filename - ignore it
+ if (RandTexName[rand_slot].GetLength() > 0)
+ lstrcpyW(szRootName, RandTexName[rand_slot].c_str());
+ }
+
+ // see if <szRootName>.tga or .jpg has already been loaded.
+ bool bTexFound = false;
+ int N = g_plugin.m_textures.size();
+ for (int n=0; n<N; n++) {
+ if (!wcscmp(g_plugin.m_textures[n].texname, szRootName))
+ {
+ // found a match - texture was loaded
+ TexSizeParamInfo y;
+ y.texname = szRootName; //for debugging
+ y.texsize_param = h;
+ y.w = g_plugin.m_textures[n].w;
+ y.h = g_plugin.m_textures[n].h;
+ texsize_params.push_back(y);
+
+ bTexFound = true;
+ break;
+ }
+ }
+
+ if (!bTexFound)
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_RESOLVE_TEXSIZE_FOR_A_TEXTURE_NOT_IN_USE), cd.Name);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ }
+ else if (cd.Name[0] == '_' && cd.Name[1] == 'c')
+ {
+ int z;
+ if (sscanf(&cd.Name[2], "%d", &z)==1)
+ if (z >= 0 && z < sizeof(const_handles)/sizeof(const_handles[0]))
+ const_handles[z] = h;
+ }
+ else if (cd.Name[0] == '_' && cd.Name[1] == 'q')
+ {
+ int z = cd.Name[2] - 'a';
+ if (z >= 0 && z < sizeof(q_const_handles)/sizeof(q_const_handles[0]))
+ q_const_handles[z] = h;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+bool CPlugin::RecompileVShader(const char* szShadersText, VShaderInfo *si, int shaderType, bool bHardErrors)
+{
+ SafeRelease(si->ptr);
+ ZeroMemory(si, sizeof(VShaderInfo));
+
+ // LOAD SHADER
+ if (!LoadShaderFromMemory( szShadersText, "VS", "vs_1_1", &si->CT, (void**)&si->ptr, shaderType, bHardErrors && (GetScreenMode()==WINDOWED)))
+ return false;
+
+ // Track down texture & float4 param bindings for this shader.
+ // Also loads any textures that need loaded.
+ si->params.CacheParams(si->CT, bHardErrors);
+
+ return true;
+}
+
+bool CPlugin::RecompilePShader(const char* szShadersText, PShaderInfo *si, int shaderType, bool bHardErrors, int PSVersion)
+{
+ assert(m_nMaxPSVersion > 0);
+
+ SafeRelease(si->ptr);
+ ZeroMemory(si, sizeof(PShaderInfo));
+
+ // LOAD SHADER
+ // note: ps_1_4 required for dependent texture lookups.
+ // ps_2_0 required for tex2Dbias.
+ char ver[16];
+ lstrcpy(ver, "ps_0_0");
+ switch(PSVersion) {
+ case MD2_PS_NONE:
+ // Even though the PRESET doesn't use shaders, if MilkDrop is running where it CAN do shaders,
+ // we run all the old presets through (shader) emulation.
+ // This way, during a MilkDrop session, we are always calling either WarpedBlit() or WarpedBlit_NoPixelShaders(),
+ // and blending always works.
+ lstrcpy(ver, "ps_2_0");
+ break;
+ case MD2_PS_2_0: lstrcpy(ver, "ps_2_0"); break;
+ case MD2_PS_2_X: lstrcpy(ver, "ps_2_a"); break; // we'll try ps_2_a first, LoadShaderFromMemory will try ps_2_b if compilation fails
+ case MD2_PS_3_0: lstrcpy(ver, "ps_3_0"); break;
+ case MD2_PS_4_0: lstrcpy(ver, "ps_4_0"); break;
+ default: assert(0); break;
+ }
+
+ if (!LoadShaderFromMemory( szShadersText, "PS", ver, &si->CT, (void**)&si->ptr, shaderType, bHardErrors && (GetScreenMode()==WINDOWED)))
+ return false;
+
+ // Track down texture & float4 param bindings for this shader.
+ // Also loads any textures that need loaded.
+ si->params.CacheParams(si->CT, bHardErrors);
+
+ return true;
+}
+
+bool CPlugin::LoadShaders(PShaderSet* sh, CState* pState, bool bTick)
+{
+ if (m_nMaxPSVersion <= 0)
+ return true;
+
+ // load one of the pixel shaders
+ if (!sh->warp.ptr && pState->m_nWarpPSVersion > 0)
+ {
+ bool bOK = RecompilePShader(pState->m_szWarpShadersText, &sh->warp, SHADER_WARP, false, pState->m_nWarpPSVersion);
+ if (!bOK)
+ {
+ // switch to fallback shader
+ m_fallbackShaders_ps.warp.ptr->AddRef();
+ m_fallbackShaders_ps.warp.CT->AddRef();
+ memcpy(&sh->warp, &m_fallbackShaders_ps.warp, sizeof(PShaderInfo));
+ // cancel any slow-preset-load
+ //m_nLoadingPreset = 1000;
+ }
+
+ if (bTick)
+ return true;
+ }
+
+ if (!sh->comp.ptr && pState->m_nCompPSVersion > 0)
+ {
+ bool bOK = RecompilePShader(pState->m_szCompShadersText, &sh->comp, SHADER_COMP, false, pState->m_nCompPSVersion);
+ if (!bOK)
+ {
+ // switch to fallback shader
+ m_fallbackShaders_ps.comp.ptr->AddRef();
+ m_fallbackShaders_ps.comp.CT->AddRef();
+ memcpy(&sh->comp, &m_fallbackShaders_ps.comp, sizeof(PShaderInfo));
+ // cancel any slow-preset-load
+ //m_nLoadingPreset = 1000;
+ }
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+
+/*
+bool CPlugin::LoadShaderFromFile( char* szFile, char* szFn, char* szProfile,
+ LPD3DXCONSTANTTABLE* ppConstTable, void** ppShader )
+{
+ LPD3DXBUFFER pShaderByteCode;
+ char buf[32768];
+
+ if (D3D_OK != D3DXCompileShaderFromFile(
+ szFile,
+ NULL,//CONST D3DXMACRO* pDefines,
+ NULL,//LPD3DXINCLUDE pInclude,
+ szFn,
+ szProfile,
+ m_dwShaderFlags,
+ &pShaderByteCode,
+ &m_pShaderCompileErrors,
+ ppConstTable
+ ))
+ {
+ sprintf(buf, "error compiling shader:\n");
+ lstrcat(buf, szFile);
+ if (m_pShaderCompileErrors->GetBufferSize() < sizeof(buf) - 256)
+ {
+ lstrcat(buf, "\n\n");
+ lstrcat(buf, (const char *)(m_pShaderCompileErrors->GetBufferPointer()));
+ }
+ dumpmsg(buf);
+ MessageBox(GetPluginWindow(), buf, "MILKDROP ERROR", MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ HRESULT hr = 1;
+ if (szProfile[0] == 'v')
+ hr = GetDevice()->CreateVertexShader((const unsigned long *)(pShaderByteCode->GetBufferPointer()), (IDirect3DVertexShader9**)ppShader);
+ else if (szProfile[0] == 'p')
+ hr = GetDevice()->CreatePixelShader((const unsigned long *)(pShaderByteCode->GetBufferPointer()), (IDirect3DPixelShader9**)ppShader);
+ if (hr != D3D_OK)
+ {
+ sprintf(buf, "error creating shader:\n");
+ lstrcat(buf, szFile);
+ dumpmsg(buf);
+ MessageBox(GetPluginWindow(), buf, "MILKDROP ERROR", MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ return false;
+ }
+
+ pShaderByteCode->Release();
+
+ return true;
+}
+*/
+
+bool CPlugin::LoadShaderFromMemory( const char* szOrigShaderText, char* szFn, char* szProfile,
+ LPD3DXCONSTANTTABLE* ppConstTable, void** ppShader, int shaderType, bool bHardErrors )
+{
+ const char szWarpDefines[] = "#define rad _rad_ang.x\n"
+ "#define ang _rad_ang.y\n"
+ "#define uv _uv.xy\n"
+ "#define uv_orig _uv.zw\n";
+ const char szCompDefines[] = "#define rad _rad_ang.x\n"
+ "#define ang _rad_ang.y\n"
+ "#define uv _uv.xy\n"
+ "#define uv_orig _uv.xy\n" //[sic]
+ "#define hue_shader _vDiffuse.xyz\n";
+ const char szWarpParams[] = "float4 _vDiffuse : COLOR, float4 _uv : TEXCOORD0, float2 _rad_ang : TEXCOORD1, out float4 _return_value : COLOR0";
+ const char szCompParams[] = "float4 _vDiffuse : COLOR, float2 _uv : TEXCOORD0, float2 _rad_ang : TEXCOORD1, out float4 _return_value : COLOR0";
+ const char szFirstLine[] = " float3 ret = 0;";
+ const char szLastLine[] = " _return_value = float4(ret.xyz, _vDiffuse.w);";
+
+ char szWhichShader[64];
+ switch(shaderType)
+ {
+ case SHADER_WARP: lstrcpy(szWhichShader, "warp"); break;
+ case SHADER_COMP: lstrcpy(szWhichShader, "composite"); break;
+ case SHADER_BLUR: lstrcpy(szWhichShader, "blur"); break;
+ case SHADER_OTHER: lstrcpy(szWhichShader, "(other)"); break;
+ default: lstrcpy(szWhichShader, "(unknown)"); break;
+ }
+
+ LPD3DXBUFFER pShaderByteCode;
+ wchar_t title[64];
+
+ *ppShader = NULL;
+ *ppConstTable = NULL;
+
+ char szShaderText[128000];
+ char temp[128000];
+ int writePos = 0;
+
+ // paste the universal #include
+ lstrcpy(&szShaderText[writePos], m_szShaderIncludeText); // first, paste in the contents of 'inputs.fx' before the actual shader text. Has 13's and 10's.
+ writePos += m_nShaderIncludeTextLen;
+
+ // paste in any custom #defines for this shader type
+ if (shaderType == SHADER_WARP && szProfile[0]=='p')
+ {
+ lstrcpy(&szShaderText[writePos], szWarpDefines);
+ writePos += lstrlen(szWarpDefines);
+ }
+ else if (shaderType == SHADER_COMP && szProfile[0]=='p')
+ {
+ lstrcpy(&szShaderText[writePos], szCompDefines);
+ writePos += lstrlen(szCompDefines);
+ }
+
+ // paste in the shader itself - converting LCC's to 13+10's.
+ // avoid lstrcpy b/c it might not handle the linefeed stuff...?
+ int shaderStartPos = writePos;
+ {
+ const char *s = szOrigShaderText;
+ char *d = &szShaderText[writePos];
+ while (*s)
+ {
+ if (*s == LINEFEED_CONTROL_CHAR)
+ {
+ *d++ = 13; writePos++;
+ *d++ = 10; writePos++;
+ }
+ else
+ {
+ *d++ = *s; writePos++;
+ }
+ s++;
+ }
+ *d = 0; writePos++;
+ }
+
+ // strip out all comments - but cheat a little - start at the shader test.
+ // (the include file was already stripped of comments)
+ StripComments(&szShaderText[shaderStartPos]);
+
+ /*{
+ char* p = szShaderText;
+ while (*p)
+ {
+ char buf[32];
+ buf[0] = *p;
+ buf[1] = 0;
+ OutputDebugString(buf);
+ if ((rand() % 9) == 0)
+ Sleep(1);
+ p++;
+ }
+ OutputDebugString("\n");
+ }/**/
+
+ //note: only do this stuff if type is WARP or COMP shader... not for blur, etc!
+ //FIXME - hints on the inputs / output / samplers etc.
+ // can go in the menu header, NOT the preset! =)
+ //then update presets
+ // -> be sure to update the presets on disk AND THE DEFAULT SHADERS (for loading MD1 presets)
+ //FIXME - then update auth. guide w/new examples,
+ // and a list of the invisible inputs (and one output) to each shader!
+ // warp: float2 uv, float2 uv_orig, rad, ang
+ // comp: float2 uv, rad, ang, float3 hue_shader
+ // test all this string code in Debug mode - make sure nothing bad is happening
+
+ /*
+ 1. paste warp or comp #defines
+ 2. search for "void" + whitespace + szFn + [whitespace] + '('
+ 3. insert params
+ 4. search for [whitespace] + ')'.
+ 5. search for final '}' (strrchr)
+ 6. back up one char, insert the Last Line, and add '}' and that's it.
+ */
+ if ((shaderType == SHADER_WARP || shaderType == SHADER_COMP) && szProfile[0]=='p')
+ {
+ char* p = &szShaderText[shaderStartPos];
+
+ // seek to 'shader_body' and replace it with spaces
+ while (*p && strncmp(p, "shader_body", 11))
+ p++;
+ if (p)
+ {
+ for (int i=0; i<11; i++)
+ *p++ = ' ';
+ }
+
+ if (p)
+ {
+ // insert "void PS(...params...)\n"
+ lstrcpy(temp, p);
+ const char *params = (shaderType==SHADER_WARP) ? szWarpParams : szCompParams;
+ sprintf(p, "void %s( %s )\n", szFn, params);
+ p += lstrlen(p);
+ lstrcpy(p, temp);
+
+ // find the starting curly brace
+ p = strchr(p, '{');
+ if (p)
+ {
+ // skip over it
+ p++;
+ // then insert "float3 ret = 0;"
+ lstrcpy(temp, p);
+ sprintf(p, "%s\n", szFirstLine);
+ p += lstrlen(p);
+ lstrcpy(p, temp);
+
+ // find the ending curly brace
+ p = strrchr(p, '}');
+ // add the last line - " _return_value = float4(ret.xyz, _vDiffuse.w);"
+ if (p)
+ sprintf(p, " %s\n}\n", szLastLine);
+ }
+ }
+
+ if (!p)
+ {
+ wchar_t temp[512];
+ swprintf(temp, WASABI_API_LNGSTRINGW(IDS_ERROR_PARSING_X_X_SHADER), szProfile, szWhichShader);
+ dumpmsg(temp);
+ AddError(temp, 8.0f, ERR_PRESET, true);
+ return false;
+ }
+ }
+
+ // now really try to compile it.
+
+ bool failed=false;
+ int len = lstrlen(szShaderText);
+ if (D3D_OK != pCompileShader(
+ szShaderText,
+ len,
+ NULL,//CONST D3DXMACRO* pDefines,
+ NULL,//LPD3DXINCLUDE pInclude,
+ szFn,
+ szProfile,
+ m_dwShaderFlags,
+ &pShaderByteCode,
+ &m_pShaderCompileErrors,
+ ppConstTable
+ ))
+ {
+ failed=true;
+ }
+ // before we totally fail, let's try using ps_2_b instead of ps_2_a
+ if (failed && !strcmp(szProfile, "ps_2_a"))
+ {
+ SafeRelease(m_pShaderCompileErrors);
+ if (D3D_OK == pCompileShader(szShaderText, len, NULL, NULL, szFn,
+ "ps_2_b", m_dwShaderFlags, &pShaderByteCode, &m_pShaderCompileErrors, ppConstTable))
+ {
+ failed=false;
+ }
+ }
+
+ if (failed)
+ {
+ wchar_t temp[1024];
+ swprintf(temp, WASABI_API_LNGSTRINGW(IDS_ERROR_COMPILING_X_X_SHADER), szProfile, szWhichShader);
+ if (m_pShaderCompileErrors && m_pShaderCompileErrors->GetBufferSize() < sizeof(temp) - 256)
+ {
+ lstrcatW(temp, L"\n\n");
+ lstrcatW(temp, AutoWide((char*)m_pShaderCompileErrors->GetBufferPointer()));
+ }
+ SafeRelease(m_pShaderCompileErrors);
+ dumpmsg(temp);
+ if (bHardErrors)
+ MessageBoxW(GetPluginWindow(), temp, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ else {
+ AddError(temp, 8.0f, ERR_PRESET, true);
+ }
+ return false;
+ }
+
+ HRESULT hr = 1;
+ if (szProfile[0] == 'v')
+ {
+ hr = GetDevice()->CreateVertexShader((const unsigned long *)(pShaderByteCode->GetBufferPointer()), (IDirect3DVertexShader9**)ppShader);
+ }
+ else if (szProfile[0] == 'p')
+ {
+ hr = GetDevice()->CreatePixelShader((const unsigned long *)(pShaderByteCode->GetBufferPointer()), (IDirect3DPixelShader9**)ppShader);
+ }
+
+ if (hr != D3D_OK)
+ {
+ wchar_t temp[512];
+ WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_CREATING_SHADER,temp,sizeof(temp));
+ dumpmsg(temp);
+ if (bHardErrors)
+ MessageBoxW(GetPluginWindow(), temp, WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR,title,64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ else {
+ AddError(temp, 6.0f, ERR_PRESET, true);
+ }
+ return false;
+ }
+
+ pShaderByteCode->Release();
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::CleanUpMyDX9Stuff(int final_cleanup)
+{
+ // Clean up all your DX9 and D3DX textures, fonts, buffers, etc. here.
+ // EVERYTHING CREATED IN ALLOCATEMYDX9STUFF() SHOULD BE CLEANED UP HERE.
+ // The input parameter, 'final_cleanup', will be 0 if this is
+ // a routine cleanup (part of a window resize or switch between
+ // fullscr/windowed modes), or 1 if this is the final cleanup
+ // and the plugin is exiting. Note that even if it is a routine
+ // cleanup, *you still have to release ALL your DirectX stuff,
+ // because the DirectX device is being destroyed and recreated!*
+ // Also set all the pointers back to NULL;
+ // this is important because if we go to reallocate the DX9
+ // stuff later, and something fails, then CleanUp will get called,
+ // but it will then be trying to clean up invalid pointers.)
+ // The SafeRelease() and SafeDelete() macros make your code prettier;
+ // they are defined here in utility.h as follows:
+ // #define SafeRelease(x) if (x) {x->Release(); x=NULL;}
+ // #define SafeDelete(x) if (x) {delete x; x=NULL;}
+ // IMPORTANT:
+ // This function ISN'T only called when the plugin exits!
+ // It is also called whenever the user toggles between fullscreen and
+ // windowed modes, or resizes the window. Basically, on these events,
+ // the base class calls CleanUpMyDX9Stuff before Reset()ing the DirectX
+ // device, and then calls AllocateMyDX9Stuff afterwards.
+
+
+
+ // One funky thing here: if we're switching between fullscreen and windowed,
+ // or doing any other thing that causes all this stuff to get reloaded in a second,
+ // then if we were blending 2 presets, jump fully to the new preset.
+ // Otherwise the old preset wouldn't get all reloaded, and it app would crash
+ // when trying to use its stuff.
+ if (m_nLoadingPreset != 0) {
+ // finish up the pre-load & start the official blend
+ m_nLoadingPreset = 8;
+ LoadPresetTick();
+ }
+ // just force this:
+ m_pState->m_bBlending = false;
+
+
+ for ( TexInfo &l_texture : m_textures )
+ {
+ if ( l_texture.texptr )
+ {
+ // notify all CShaderParams classes that we're releasing a bindable texture!!
+ for ( CShaderParams *l_shader_param : global_CShaderParams_master_list )
+ l_shader_param->OnTextureEvict( l_texture.texptr );
+
+ SafeRelease( l_texture.texptr );
+ }
+ }
+
+ m_textures.clear();
+
+ // DON'T RELEASE blur textures - they were already released because they're in m_textures[].
+ #if (NUM_BLUR_TEX>0)
+ for (int i=0; i<NUM_BLUR_TEX; i++)
+ m_lpBlur[i] = NULL;//SafeRelease(m_lpBlur[i]);
+ #endif
+
+ // NOTE: not necessary; shell does this for us.
+ /*if (GetDevice())
+ {
+ GetDevice()->SetTexture(0, NULL);
+ GetDevice()->SetTexture(1, NULL);
+ }*/
+
+ SafeRelease(m_pSpriteVertDecl);
+ SafeRelease(m_pWfVertDecl);
+ SafeRelease(m_pMyVertDecl);
+
+ m_shaders.comp.Clear();
+ m_shaders.warp.Clear();
+ m_OldShaders.comp.Clear();
+ m_OldShaders.warp.Clear();
+ m_NewShaders.comp.Clear();
+ m_NewShaders.warp.Clear();
+ m_fallbackShaders_vs.comp.Clear();
+ m_fallbackShaders_ps.comp.Clear();
+ m_fallbackShaders_vs.warp.Clear();
+ m_fallbackShaders_ps.warp.Clear();
+ m_BlurShaders[0].vs.Clear();
+ m_BlurShaders[0].ps.Clear();
+ m_BlurShaders[1].vs.Clear();
+ m_BlurShaders[1].ps.Clear();
+ /*
+ SafeRelease( m_shaders.comp.ptr );
+ SafeRelease( m_shaders.warp.ptr );
+ SafeRelease( m_OldShaders.comp.ptr );
+ SafeRelease( m_OldShaders.warp.ptr );
+ SafeRelease( m_NewShaders.comp.ptr );
+ SafeRelease( m_NewShaders.warp.ptr );
+ SafeRelease( m_fallbackShaders_vs.comp.ptr );
+ SafeRelease( m_fallbackShaders_ps.comp.ptr );
+ SafeRelease( m_fallbackShaders_vs.warp.ptr );
+ SafeRelease( m_fallbackShaders_ps.warp.ptr );
+ */
+ SafeRelease( m_pShaderCompileErrors );
+ //SafeRelease( m_pCompiledFragments );
+ //SafeRelease( m_pFragmentLinker );
+
+ // 2. release stuff
+ SafeRelease(m_lpVS[0]);
+ SafeRelease(m_lpVS[1]);
+ SafeRelease(m_lpDDSTitle);
+ SafeRelease(m_d3dx_title_font_doublesize);
+
+ // NOTE: THIS CODE IS IN THE RIGHT PLACE.
+ if (m_gdi_title_font_doublesize)
+ {
+ DeleteObject(m_gdi_title_font_doublesize);
+ m_gdi_title_font_doublesize = NULL;
+ }
+
+ m_texmgr.Finish();
+
+ if (m_verts != NULL)
+ {
+ delete m_verts;
+ m_verts = NULL;
+ }
+
+ if (m_verts_temp != NULL)
+ {
+ delete m_verts_temp;
+ m_verts_temp = NULL;
+ }
+
+ if (m_vertinfo != NULL)
+ {
+ delete m_vertinfo;
+ m_vertinfo = NULL;
+ }
+
+ if (m_indices_list != NULL)
+ {
+ delete m_indices_list;
+ m_indices_list = NULL;
+ }
+
+ if (m_indices_strip != NULL)
+ {
+ delete m_indices_strip;
+ m_indices_strip = NULL;
+ }
+
+ ClearErrors();
+
+ // This setting is closely tied to the modern skin "random" button.
+ // The "random" state should be preserved from session to session.
+ // It's pretty safe to do, because the Scroll Lock key is hard to
+ // accidentally click... :)
+ WritePrivateProfileIntW(m_bPresetLockedByUser,L"bPresetLockOnAtStartup", GetConfigIniFile(),L"settings");
+}
+
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+
+void CPlugin::MyRenderFn(int redraw)
+{
+ EnterCriticalSection(&g_cs);
+
+ // Render a frame of animation here.
+ // This function is called each frame just AFTER BeginScene().
+ // For timing information, call 'GetTime()' and 'GetFps()'.
+ // The usual formula is like this (but doesn't have to be):
+ // 1. take care of timing/other paperwork/etc. for new frame
+ // 2. clear the background
+ // 3. get ready for 3D drawing
+ // 4. draw your 3D stuff
+ // 5. call PrepareFor2DDrawing()
+ // 6. draw your 2D stuff (overtop of your 3D scene)
+ // If the 'redraw' flag is 1, you should try to redraw
+ // the last frame; GetTime, GetFps, and GetFrame should
+ // all return the same values as they did on the last
+ // call to MyRenderFn(). Otherwise, the redraw flag will
+ // be zero, and you can draw a new frame. The flag is
+ // used to force the desktop to repaint itself when
+ // running in desktop mode and Winamp is paused or stopped.
+
+ // 1. take care of timing/other paperwork/etc. for new frame
+ if (!redraw)
+ {
+ float dt = GetTime() - m_prev_time;
+ m_prev_time = GetTime(); // note: m_prev_time is not for general use!
+ m_bPresetLockedByCode = (m_UI_mode != UI_REGULAR);
+ if (m_bPresetLockedByUser || m_bPresetLockedByCode)
+ {
+ // to freeze time (at current preset time value) when menus are up or Scroll Lock is on:
+ //m_fPresetStartTime += dt;
+ //m_fNextPresetTime += dt;
+ // OR, to freeze time @ [preset] zero, so that when you exit menus,
+ // you don't run the risk of it changing the preset on you right away:
+ m_fPresetStartTime = GetTime();
+ m_fNextPresetTime = -1.0f; // flags UpdateTime() to recompute this.
+ }
+
+ //if (!m_bPresetListReady)
+ // UpdatePresetList(true);//UpdatePresetRatings(); // read in a few each frame, til they're all in
+ }
+
+ // 2. check for lost or gained kb focus:
+ // (note: can't use wm_setfocus or wm_killfocus because they don't work w/embedwnd)
+ if (GetFrame()==0)
+ {
+ // NOTE: we skip this if we've already gotten a WM_COMMAND/ID_VIS_RANDOM message
+ // from the skin - if that happened, we're running windowed with a fancy
+ // skin with a 'rand' button.
+
+ SetScrollLock(m_bPresetLockOnAtStartup, m_bPreventScollLockHandling);
+
+ // make sure the 'random' button on the skin shows the right thing:
+ // NEVERMIND - if it's a fancy skin, it'll send us WM_COMMAND/ID_VIS_RANDOM
+ // and we'll match the skin's Random button state.
+ //SendMessage(GetWinampWindow(),WM_WA_IPC,m_bMilkdropScrollLockState, IPC_CB_VISRANDOM);
+ }
+ else
+ {
+ m_bHadFocus = m_bHasFocus;
+
+ HWND winamp = GetWinampWindow();
+ HWND plugin = GetPluginWindow();
+ HWND focus = GetFocus();
+ HWND cur = plugin;
+
+ m_bHasFocus = false;
+ do
+ {
+ m_bHasFocus = (focus == cur);
+ if (m_bHasFocus)
+ break;
+ cur = GetParent(cur);
+ }
+ while (cur != NULL && cur != winamp);
+
+ if (m_hTextWnd && focus==m_hTextWnd)
+ m_bHasFocus = 1;
+
+ if (GetFocus()==NULL)
+ m_bHasFocus = 0;
+ ;
+ //HWND t1 = GetFocus();
+ //HWND t2 = GetPluginWindow();
+ //HWND t3 = GetParent(t2);
+
+ if (m_bHadFocus==1 && m_bHasFocus==0)
+ {
+ //m_bMilkdropScrollLockState = GetKeyState(VK_SCROLL) & 1;
+ SetScrollLock(m_bOrigScrollLockState, m_bPreventScollLockHandling);
+ }
+ else if (m_bHadFocus==0 && m_bHasFocus==1)
+ {
+ m_bOrigScrollLockState = GetKeyState(VK_SCROLL) & 1;
+ SetScrollLock(m_bPresetLockedByUser, m_bPreventScollLockHandling);
+ }
+ }
+
+ if (!redraw)
+ {
+ GetWinampSongTitle(GetWinampWindow(), m_szSongTitle, sizeof(m_szSongTitle)-1);
+ if (wcscmp(m_szSongTitle, m_szSongTitlePrev))
+ {
+ lstrcpynW(m_szSongTitlePrev, m_szSongTitle, 512);
+ if (m_bSongTitleAnims)
+ LaunchSongTitleAnim();
+ }
+ }
+
+ // 2. Clear the background:
+ //DWORD clear_color = (m_fog_enabled) ? FOG_COLOR : 0xFF000000;
+ //GetDevice()->Clear(0, 0, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, clear_color, 1.0f, 0);
+
+ // 5. switch to 2D drawing mode. 2D coord system:
+ // +--------+ Y=-1
+ // | |
+ // | screen | Z=0: front of scene
+ // | | Z=1: back of scene
+ // +--------+ Y=1
+ // X=-1 X=1
+ PrepareFor2DDrawing(GetDevice());
+
+ if (!redraw)
+ DoCustomSoundAnalysis(); // emulates old pre-vms milkdrop sound analysis
+
+ RenderFrame(redraw); // see milkdropfs.cpp
+
+ /*
+ for (int i=0; i<10; i++)
+ {
+ RECT r;
+ r.top = GetHeight()*i/10;
+ r.left = 0;
+ r.right = GetWidth();
+ r.bottom = r.top + GetFontHeight(DECORATIVE_FONT);
+ char buf[256];
+ switch(i)
+ {
+ case 0: lstrcpy(buf, "this is a test"); break;
+ case 1: lstrcpy(buf, "argh"); break;
+ case 2: lstrcpy(buf, "!!"); break;
+ case 3: lstrcpy(buf, "TESTING FONTS"); break;
+ case 4: lstrcpy(buf, "rancid bear grease"); break;
+ case 5: lstrcpy(buf, "whoppers and ding dongs"); break;
+ case 6: lstrcpy(buf, "billy & joey"); break;
+ case 7: lstrcpy(buf, "."); break;
+ case 8: lstrcpy(buf, "---"); break;
+ case 9: lstrcpy(buf, "test"); break;
+ }
+ int t = (int)( 54 + 18*sin(i/10.0f*53.7f + 1) - 28*sin(i/10.0f*39.4f + 3) );
+ if (((GetFrame() + i*107) % t) < t*8/9)
+ m_text.QueueText(GetFont(DECORATIVE_FONT), buf, r, 0, 0xFFFF00FF);
+ }
+ /**/
+
+ if (!redraw)
+ {
+ m_nFramesSinceResize++;
+ if (m_nLoadingPreset > 0)
+ {
+ LoadPresetTick();
+ }
+ }
+
+ LeaveCriticalSection(&g_cs);
+}
+
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+
+void CPlugin::DrawTooltip(wchar_t* str, int xR, int yB)
+{
+ // draws a string in the lower-right corner of the screen.
+ // note: ID3DXFont handles DT_RIGHT and DT_BOTTOM *very poorly*.
+ // it is best to calculate the size of the text first,
+ // then place it in the right spot.
+ // note: use DT_WORDBREAK instead of DT_WORD_ELLIPSES, otherwise certain fonts'
+ // calcrect (for the dark box) will be wrong.
+
+ RECT r, r2;
+ SetRect(&r, 0, 0, xR-TEXT_MARGIN*2, 2048);
+ m_text.DrawTextW(GetFont(TOOLTIP_FONT), str, -1, &r, DT_CALCRECT, 0xFFFFFFFF, false);
+ r2.bottom = yB - TEXT_MARGIN;
+ r2.right = xR - TEXT_MARGIN;
+ r2.left = r2.right - (r.right-r.left);
+ r2.top = r2.bottom - (r.bottom-r.top);
+ RECT r3 = r2; r3.left -= 4; r3.top -= 2; r3.right += 2; r3.bottom += 2;
+ DrawDarkTranslucentBox(&r3);
+ m_text.DrawTextW(GetFont(TOOLTIP_FONT), str, -1, &r2, 0, 0xFFFFFFFF, false);
+}
+
+#define MTO_UPPER_RIGHT 0
+#define MTO_UPPER_LEFT 1
+#define MTO_LOWER_RIGHT 2
+#define MTO_LOWER_LEFT 3
+
+#define SelectFont(n) { \
+ pFont = GetFont(n); \
+ h = GetFontHeight(n); \
+}
+
+#define MyTextOut_BGCOLOR(str, corner, bDarkBox, boxColor) { \
+ SetRect(&r, 0, 0, xR-xL, 2048); \
+ m_text.DrawTextW(pFont, str, -1, &r, DT_NOPREFIX | ((corner == MTO_UPPER_RIGHT)?0:DT_SINGLELINE) | DT_WORD_ELLIPSIS | DT_CALCRECT | ((corner == MTO_UPPER_RIGHT) ? DT_RIGHT : 0), 0xFFFFFFFF, false, boxColor); \
+ int w = r.right - r.left; \
+ if (corner == MTO_UPPER_LEFT ) SetRect(&r, xL, *upper_left_corner_y, xL+w, *upper_left_corner_y + h); \
+ else if (corner == MTO_UPPER_RIGHT) SetRect(&r, xR-w, *upper_right_corner_y, xR, *upper_right_corner_y + h); \
+ else if (corner == MTO_LOWER_LEFT ) SetRect(&r, xL, *lower_left_corner_y - h, xL+w, *lower_left_corner_y); \
+ else if (corner == MTO_LOWER_RIGHT) SetRect(&r, xR-w, *lower_right_corner_y - h, xR, *lower_right_corner_y); \
+ m_text.DrawTextW(pFont, str, -1, &r, DT_NOPREFIX | ((corner == MTO_UPPER_RIGHT)?0:DT_SINGLELINE) | DT_WORD_ELLIPSIS | ((corner == MTO_UPPER_RIGHT) ? DT_RIGHT: 0), 0xFFFFFFFF, bDarkBox, boxColor); \
+ if (corner == MTO_UPPER_LEFT ) *upper_left_corner_y += h; \
+ else if (corner == MTO_UPPER_RIGHT) *upper_right_corner_y += h; \
+ else if (corner == MTO_LOWER_LEFT ) *lower_left_corner_y -= h; \
+ else if (corner == MTO_LOWER_RIGHT) *lower_right_corner_y -= h; \
+}
+
+#define MyTextOut(str, corner, bDarkBox) MyTextOut_BGCOLOR(str, corner, bDarkBox, 0xFF000000)
+
+#define MyTextOut_Shadow(str, corner) { \
+ /* calc rect size */ \
+ SetRect(&r, 0, 0, xR-xL, 2048); \
+ m_text.DrawTextW(pFont, (wchar_t*)str, -1, &r, DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_CALCRECT, 0xFFFFFFFF, false, 0xFF000000); \
+ int w = r.right - r.left; \
+ /* first the shadow */ \
+ if (corner == MTO_UPPER_LEFT ) SetRect(&r, xL, *upper_left_corner_y, xL+w, *upper_left_corner_y + h); \
+ else if (corner == MTO_UPPER_RIGHT) SetRect(&r, xR-w, *upper_right_corner_y, xR, *upper_right_corner_y + h); \
+ else if (corner == MTO_LOWER_LEFT ) SetRect(&r, xL, *lower_left_corner_y - h, xL+w, *lower_left_corner_y); \
+ else if (corner == MTO_LOWER_RIGHT) SetRect(&r, xR-w, *lower_right_corner_y - h, xR, *lower_right_corner_y); \
+ r.top += 1; r.left += 1; \
+ m_text.DrawTextW(pFont, (wchar_t*)str, -1, &r, DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS, 0xFF000000, false, 0xFF000000); \
+ /* now draw real text */ \
+ r.top -= 1; r.left -= 1; \
+ m_text.DrawTextW(pFont, (wchar_t*)str, -1, &r, DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS, 0xFFFFFFFF, false, 0xFF000000); \
+ if (corner == MTO_UPPER_LEFT ) *upper_left_corner_y += h; \
+ else if (corner == MTO_UPPER_RIGHT) *upper_right_corner_y += h; \
+ else if (corner == MTO_LOWER_LEFT ) *lower_left_corner_y -= h; \
+ else if (corner == MTO_LOWER_RIGHT) *lower_right_corner_y -= h; \
+}
+
+void CPlugin::OnAltK()
+{
+ AddError(WASABI_API_LNGSTRINGW(IDS_PLEASE_EXIT_VIS_BEFORE_RUNNING_CONFIG_PANEL), 3.0f, ERR_NOTIFY, true);
+}
+
+void CPlugin::AddError(wchar_t* szMsg, float fDuration, int category, bool bBold)
+{
+ if (category == ERR_NOTIFY)
+ ClearErrors(category);
+
+ assert(category != ERR_ALL);
+ ErrorMsg x;
+ x.msg = szMsg;
+ x.birthTime = GetTime();
+ x.expireTime = GetTime() + fDuration;
+ x.category = category;
+ x.bBold = bBold;
+ m_errors.push_back(x);
+}
+
+void CPlugin::ClearErrors(int category) // 0=all categories
+{
+ int N = m_errors.size();
+ for (int i = 0; i < N; i++)
+ {
+ if (category == ERR_ALL || m_errors[i].category == category)
+ {
+ m_errors.erase(m_errors.begin() + i);
+ i--;
+ N--;
+ }
+ }
+}
+
+void CPlugin::MyRenderUI(
+ int *upper_left_corner_y, // increment me!
+ int *upper_right_corner_y, // increment me!
+ int *lower_left_corner_y, // decrement me!
+ int *lower_right_corner_y, // decrement me!
+ int xL,
+ int xR
+ )
+{
+ // draw text messages directly to the back buffer.
+ // when you draw text into one of the four corners,
+ // draw the text at the current 'y' value for that corner
+ // (one of the first 4 params to this function),
+ // and then adjust that y value so that the next time
+ // text is drawn in that corner, it gets drawn above/below
+ // the previous text (instead of overtop of it).
+ // when drawing into the upper or lower LEFT corners,
+ // left-align your text to 'xL'.
+ // when drawing into the upper or lower RIGHT corners,
+ // right-align your text to 'xR'.
+
+ // note: try to keep the bounding rectangles on the text small;
+ // the smaller the area that has to be locked (to draw the text),
+ // the faster it will be. (on some cards, drawing text is
+ // ferociously slow, so even if it works okay on yours, it might
+ // not work on another video card.)
+ // note: if you want some text to be on the screen often, and the text
+ // won't be changing every frame, please consider the poor folks
+ // whose video cards hate that; in that case you should probably
+ // draw the text just once, to a texture, and then display the
+ // texture each frame. This is how the help screen is done; see
+ // pluginshell.cpp for example code.
+
+ RECT r = {0};
+ wchar_t buf[512] = {0};
+ LPD3DXFONT pFont = GetFont(DECORATIVE_FONT);
+ int h = GetFontHeight(DECORATIVE_FONT);
+
+ if (!pFont)
+ return;
+
+ if (!GetFont(DECORATIVE_FONT))
+ return;
+
+ // 1. render text in upper-right corner - EXCEPT USER MESSAGE - it goes last b/c it draws a box under itself
+ // and it should be visible over everything else (usually an error msg)
+ {
+ // a) preset name
+ if (m_bShowPresetInfo)
+ {
+ SelectFont(DECORATIVE_FONT);
+ swprintf(buf, L"%s ", (m_nLoadingPreset != 0) ? m_pNewState->m_szDesc : m_pState->m_szDesc);
+ MyTextOut_Shadow(buf, MTO_UPPER_RIGHT);
+ }
+
+ // b) preset rating
+ if (m_bShowRating || GetTime() < m_fShowRatingUntilThisTime)
+ {
+ // see also: SetCurrentPresetRating() in milkdrop.cpp
+ SelectFont(DECORATIVE_FONT);
+ swprintf(buf, L" %s: %d ", WASABI_API_LNGSTRINGW(IDS_RATING), (int)m_pState->m_fRating);
+ if (!m_bEnableRating) lstrcatW(buf, WASABI_API_LNGSTRINGW(IDS_DISABLED));
+ MyTextOut_Shadow(buf, MTO_UPPER_RIGHT);
+ }
+
+ // c) fps display
+ if (m_bShowFPS)
+ {
+ SelectFont(DECORATIVE_FONT);
+ swprintf(buf, L"%s: %4.2f ", WASABI_API_LNGSTRINGW(IDS_FPS), GetFps()); // leave extra space @ end, so italicized fonts don't get clipped
+ MyTextOut_Shadow(buf, MTO_UPPER_RIGHT);
+ }
+
+ // d) debug information
+ if (m_bShowDebugInfo)
+ {
+ SelectFont(SIMPLE_FONT);
+ swprintf(buf, L" %s: %6.4f ", WASABI_API_LNGSTRINGW(IDS_PF_MONITOR), (float)(*m_pState->var_pf_monitor));
+ MyTextOut_Shadow(buf, MTO_UPPER_RIGHT);
+ }
+
+ // NOTE: custom timed msg comes at the end!!
+ }
+
+ // 2. render text in lower-right corner
+ {
+ // waitstring tooltip:
+ if (m_waitstring.bActive && m_bShowMenuToolTips && m_waitstring.szToolTip[0])
+ {
+ DrawTooltip(m_waitstring.szToolTip, xR, *lower_right_corner_y);
+ }
+ }
+
+ // 3. render text in lower-left corner
+ {
+ wchar_t buf2[512] = {0};
+ wchar_t buf3[512+1] = {0}; // add two extra spaces to end, so italicized fonts don't get clipped
+
+ // render song title in lower-left corner:
+ if (m_bShowSongTitle)
+ {
+ wchar_t buf4[512] = {0};
+ SelectFont(DECORATIVE_FONT);
+ GetWinampSongTitle(GetWinampWindow(), buf4, sizeof(buf4)); // defined in utility.h/cpp
+ MyTextOut_Shadow(buf4, MTO_LOWER_LEFT);
+ }
+
+ // render song time & len above that:
+ if (m_bShowSongTime || m_bShowSongLen)
+ {
+ GetWinampSongPosAsText(GetWinampWindow(), buf); // defined in utility.h/cpp
+ GetWinampSongLenAsText(GetWinampWindow(), buf2); // defined in utility.h/cpp
+ if (m_bShowSongTime && m_bShowSongLen)
+ {
+ // only show playing position and track length if it is playing (buffer is valid)
+ if(buf[0])
+ swprintf(buf3, L"%s / %s ", buf, buf2);
+ else
+ lstrcpynW(buf3, buf2, 512);
+ }
+ else if (m_bShowSongTime)
+ lstrcpynW(buf3, buf, 512);
+ else
+ lstrcpynW(buf3, buf2, 512);
+
+ SelectFont(DECORATIVE_FONT);
+ MyTextOut_Shadow(buf3, MTO_LOWER_LEFT);
+ }
+ }
+
+ // 4. render text in upper-left corner
+ {
+ wchar_t buf[64000] = {0}; // must fit the longest strings (code strings are 32768 chars)
+ // AND leave extra space for &->&&, and [,[,& insertion
+ char bufA[64000] = {0};
+
+ SelectFont(SIMPLE_FONT);
+
+ // stuff for loading presets, menus, etc:
+
+ if (m_waitstring.bActive)
+ {
+ // 1. draw the prompt string
+ MyTextOut(m_waitstring.szPrompt, MTO_UPPER_LEFT, true);
+
+ // extra instructions:
+ bool bIsWarp = m_waitstring.bDisplayAsCode && (m_pCurMenu == &m_menuPreset) && !wcscmp(m_menuPreset.GetCurItem()->m_szName, L"[ edit warp shader ]");
+ bool bIsComp = m_waitstring.bDisplayAsCode && (m_pCurMenu == &m_menuPreset) && !wcscmp(m_menuPreset.GetCurItem()->m_szName, L"[ edit composite shader ]");
+ if (bIsWarp || bIsComp)
+ {
+ if (m_bShowShaderHelp) {
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_PRESS_F9_TO_HIDE_SHADER_QREF), MTO_UPPER_LEFT, true);
+ }
+ else {
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_PRESS_F9_TO_SHOW_SHADER_QREF), MTO_UPPER_LEFT, true);
+ }
+ *upper_left_corner_y += h*2/3;
+
+ if (m_bShowShaderHelp)
+ {
+ // draw dark box - based on longest line & # lines...
+ SetRect(&r, 0, 0, 2048, 2048);
+ m_text.DrawTextW(pFont, WASABI_API_LNGSTRINGW(IDS_STRING615), -1, &r, DT_NOPREFIX | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_CALCRECT, 0xFFFFFFFF, false, 0xFF000000);
+ RECT darkbox;
+ SetRect(&darkbox, xL, *upper_left_corner_y-2, xL+r.right-r.left, *upper_left_corner_y + (r.bottom-r.top)*13 + 2);
+ DrawDarkTranslucentBox(&darkbox);
+
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING616), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING617), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING618), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING619), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING620), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING621), MTO_UPPER_LEFT, false);
+ if (bIsWarp)
+ {
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING622), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING623), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING624), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING625), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING626), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING627), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING628), MTO_UPPER_LEFT, false);
+ }
+ else if (bIsComp)
+ {
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING629), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING630), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING631), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING632), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING633), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING634), MTO_UPPER_LEFT, false);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_STRING635), MTO_UPPER_LEFT, false);
+ }
+ *upper_left_corner_y += h*2/3;
+ }
+ }
+ else if (m_UI_mode == UI_SAVEAS && (m_bWarpShaderLock || m_bCompShaderLock))
+ {
+ wchar_t buf[256] = {0};
+ int shader_msg_id = IDS_COMPOSITE_SHADER_LOCKED;
+ if (m_bWarpShaderLock && m_bCompShaderLock)
+ shader_msg_id = IDS_WARP_AND_COMPOSITE_SHADERS_LOCKED;
+ else if (m_bWarpShaderLock && !m_bCompShaderLock)
+ shader_msg_id = IDS_WARP_SHADER_LOCKED;
+ else
+ shader_msg_id = IDS_COMPOSITE_SHADER_LOCKED;
+
+ WASABI_API_LNGSTRINGW_BUF(shader_msg_id, buf, 256);
+ MyTextOut_BGCOLOR(buf, MTO_UPPER_LEFT, true, 0xFF000000);
+ *upper_left_corner_y += h*2/3;
+ }
+ else
+ *upper_left_corner_y += h*2/3;
+
+
+ // 2. reformat the waitstring text for display
+ int bBrackets = m_waitstring.nSelAnchorPos != -1 && m_waitstring.nSelAnchorPos != m_waitstring.nCursorPos;
+ int bCursorBlink = ( !bBrackets &&
+ ((int)(GetTime()*270.0f) % 100 > 50)
+ //((GetFrame() % 3) >= 2)
+ );
+
+ lstrcpyW(buf, m_waitstring.szText);
+ lstrcpyA(bufA, (char*)m_waitstring.szText);
+
+ int temp_cursor_pos = m_waitstring.nCursorPos;
+ int temp_anchor_pos = m_waitstring.nSelAnchorPos;
+
+ if (bBrackets)
+ {
+ if (m_waitstring.bDisplayAsCode)
+ {
+ // insert [] around the selection
+ int start = (temp_cursor_pos < temp_anchor_pos) ? temp_cursor_pos : temp_anchor_pos;
+ int end = (temp_cursor_pos > temp_anchor_pos) ? temp_cursor_pos - 1 : temp_anchor_pos - 1;
+ int len = lstrlenA(bufA);
+ int i;
+
+ for (i=len; i>end; i--)
+ bufA[i+1] = bufA[i];
+ bufA[end+1] = ']';
+ len++;
+
+ for (i=len; i>=start; i--)
+ bufA[i+1] = bufA[i];
+ bufA[start] = '[';
+ len++;
+ }
+ else
+ {
+ // insert [] around the selection
+ int start = (temp_cursor_pos < temp_anchor_pos) ? temp_cursor_pos : temp_anchor_pos;
+ int end = (temp_cursor_pos > temp_anchor_pos) ? temp_cursor_pos - 1 : temp_anchor_pos - 1;
+ int len = lstrlenW(buf);
+ int i;
+
+ for (i=len; i>end; i--)
+ buf[i+1] = buf[i];
+ buf[end+1] = L']';
+ len++;
+
+ for (i=len; i>=start; i--)
+ buf[i+1] = buf[i];
+ buf[start] = L'[';
+ len++;
+ }
+ }
+ else
+ {
+ // underline the current cursor position by rapidly toggling the character with an underscore
+ if (m_waitstring.bDisplayAsCode)
+ {
+ if (bCursorBlink)
+ {
+ if (bufA[temp_cursor_pos] == 0)
+ {
+ bufA[temp_cursor_pos] = '_';
+ bufA[temp_cursor_pos+1] = 0;
+ }
+ else if (bufA[temp_cursor_pos] == LINEFEED_CONTROL_CHAR)
+ {
+ for (int i=strlen(bufA); i>=temp_cursor_pos; i--)
+ bufA[i+1] = bufA[i];
+ bufA[temp_cursor_pos] = '_';
+ }
+ else if (bufA[temp_cursor_pos] == '_')
+ bufA[temp_cursor_pos] = ' ';
+ else // it's a space or symbol or alphanumeric.
+ bufA[temp_cursor_pos] = '_';
+ }
+ else
+ {
+ if (bufA[temp_cursor_pos] == 0)
+ {
+ bufA[temp_cursor_pos] = ' ';
+ bufA[temp_cursor_pos+1] = 0;
+ }
+ else if (bufA[temp_cursor_pos] == LINEFEED_CONTROL_CHAR)
+ {
+ for (int i=strlen(bufA); i>=temp_cursor_pos; i--)
+ bufA[i+1] = bufA[i];
+ bufA[temp_cursor_pos] = ' ';
+ }
+ //else if (buf[temp_cursor_pos] == '_')
+ // do nothing
+ //else // it's a space or symbol or alphanumeric.
+ // do nothing
+ }
+ }
+ else
+ {
+ if (bCursorBlink)
+ {
+ if (buf[temp_cursor_pos] == 0)
+ {
+ buf[temp_cursor_pos] = L'_';
+ buf[temp_cursor_pos+1] = 0;
+ }
+ else if (buf[temp_cursor_pos] == LINEFEED_CONTROL_CHAR)
+ {
+ for (int i=wcslen(buf); i>=temp_cursor_pos; i--)
+ buf[i+1] = buf[i];
+ buf[temp_cursor_pos] = L'_';
+ }
+ else if (buf[temp_cursor_pos] == L'_')
+ buf[temp_cursor_pos] = L' ';
+ else // it's a space or symbol or alphanumeric.
+ buf[temp_cursor_pos] = L'_';
+ }
+ else
+ {
+ if (buf[temp_cursor_pos] == 0)
+ {
+ buf[temp_cursor_pos] = L' ';
+ buf[temp_cursor_pos+1] = 0;
+ }
+ else if (buf[temp_cursor_pos] == LINEFEED_CONTROL_CHAR)
+ {
+ for (int i=wcslen(buf); i>=temp_cursor_pos; i--)
+ buf[i+1] = buf[i];
+ buf[temp_cursor_pos] = L' ';
+ }
+ //else if (buf[temp_cursor_pos] == '_')
+ // do nothing
+ //else // it's a space or symbol or alphanumeric.
+ // do nothing
+ }
+ }
+ }
+
+ RECT rect = {0};
+ SetRect(&rect, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+ rect.top += PLAYLIST_INNER_MARGIN;
+ rect.left += PLAYLIST_INNER_MARGIN;
+ rect.right -= PLAYLIST_INNER_MARGIN;
+ rect.bottom -= PLAYLIST_INNER_MARGIN;
+
+ // then draw the edit string
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char buf2[8192] = {0};
+ int top_of_page_pos = 0;
+
+ // compute top_of_page_pos so that the line the cursor is on will show.
+ // also compute dims of the black rectangle while we're at it.
+ {
+ int start = 0;
+ int pos = 0;
+ int ypixels = 0;
+ int page = 1;
+ int exit_on_next_page = 0;
+
+ RECT box = rect;
+ box.right = box.left;
+ box.bottom = box.top;
+
+ while (bufA[pos] != 0) // for each line of text... (note that it might wrap)
+ {
+ start = pos;
+ while (bufA[pos] != LINEFEED_CONTROL_CHAR && bufA[pos] != 0)
+ pos++;
+
+ char ch = bufA[pos];
+ bufA[pos] = 0;
+ sprintf(buf2, " %sX", &bufA[start]); // put a final 'X' instead of ' ' b/c CALCRECT returns w==0 if string is entirely whitespace!
+ RECT r2 = rect;
+ r2.bottom = 4096;
+ m_text.DrawTextA(GetFont(SIMPLE_FONT), buf2, -1, &r2, DT_CALCRECT /*| DT_WORDBREAK*/, 0xFFFFFFFF, false);
+ int h = r2.bottom-r2.top;
+ ypixels += h;
+ bufA[pos] = ch;
+
+ if (start > m_waitstring.nCursorPos) // make sure 'box' gets updated for each line on this page
+ exit_on_next_page = 1;
+
+ if (ypixels > rect.bottom-rect.top) // this line belongs on the next page
+ {
+ if (exit_on_next_page)
+ {
+ bufA[start] = 0; // so text stops where the box stops, when we draw the text
+ break;
+ }
+
+ ypixels = h;
+ top_of_page_pos = start;
+ page++;
+
+ box = rect;
+ box.right = box.left;
+ box.bottom = box.top;
+ }
+ box.bottom += h;
+ box.right = max(box.right, box.left + r2.right-r2.left);
+
+ if (bufA[pos]==0)
+ break;
+ pos++;
+ }
+
+ // use r2 to draw a dark box:
+ box.top -= PLAYLIST_INNER_MARGIN;
+ box.left -= PLAYLIST_INNER_MARGIN;
+ box.right += PLAYLIST_INNER_MARGIN;
+ box.bottom += PLAYLIST_INNER_MARGIN;
+ DrawDarkTranslucentBox(&box);
+ *upper_left_corner_y += box.bottom - box.top + PLAYLIST_INNER_MARGIN*3;
+ swprintf(m_waitstring.szToolTip, WASABI_API_LNGSTRINGW(IDS_PAGE_X), page);
+ }
+
+ // display multiline (replace all character 13's with a CR)
+ {
+ int start = top_of_page_pos;
+ int pos = top_of_page_pos;
+
+ while (bufA[pos] != 0)
+ {
+ while (bufA[pos] != LINEFEED_CONTROL_CHAR && bufA[pos] != 0)
+ pos++;
+
+ char ch = bufA[pos];
+ bufA[pos] = 0;
+ sprintf(buf2, " %s ", &bufA[start]);
+ DWORD color = MENU_COLOR;
+ if (m_waitstring.nCursorPos >= start && m_waitstring.nCursorPos <= pos)
+ color = MENU_HILITE_COLOR;
+ rect.top += m_text.DrawTextA(GetFont(SIMPLE_FONT), buf2, -1, &rect, 0/*DT_WORDBREAK*/, color, false);
+ bufA[pos] = ch;
+
+ if (rect.top > rect.bottom)
+ break;
+
+ if (bufA[pos] != 0) pos++;
+ start = pos;
+ }
+ }
+ // note: *upper_left_corner_y is updated above, when the dark box is drawn.
+ }
+ else
+ {
+ wchar_t buf2[8192] = {0};
+
+ // display on one line
+ RECT box = rect;
+ box.bottom = 4096;
+ swprintf(buf2, L" %sX", buf); // put a final 'X' instead of ' ' b/c CALCRECT returns w==0 if string is entirely whitespace!
+ m_text.DrawTextW(GetFont(SIMPLE_FONT), buf2, -1, &box, DT_CALCRECT, MENU_COLOR, false );
+
+ // use r2 to draw a dark box:
+ box.top -= PLAYLIST_INNER_MARGIN;
+ box.left -= PLAYLIST_INNER_MARGIN;
+ box.right += PLAYLIST_INNER_MARGIN;
+ box.bottom += PLAYLIST_INNER_MARGIN;
+ DrawDarkTranslucentBox(&box);
+ *upper_left_corner_y += box.bottom - box.top + PLAYLIST_INNER_MARGIN*3;
+
+ swprintf(buf2, L" %s ", buf);
+ m_text.DrawTextW(GetFont(SIMPLE_FONT), buf2, -1, &rect, 0, MENU_COLOR, false );
+ }
+ }
+ else if (m_UI_mode == UI_MENU)
+ {
+ assert(m_pCurMenu);
+ SetRect(&r, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+
+ RECT darkbox = {0};
+ m_pCurMenu->DrawMenu(r, xR, *lower_right_corner_y, 1, &darkbox);
+ *upper_left_corner_y += darkbox.bottom - darkbox.top + PLAYLIST_INNER_MARGIN*3;
+
+ darkbox.right += PLAYLIST_INNER_MARGIN*2;
+ darkbox.bottom += PLAYLIST_INNER_MARGIN*2;
+ DrawDarkTranslucentBox(&darkbox);
+
+ r.top += PLAYLIST_INNER_MARGIN;
+ r.left += PLAYLIST_INNER_MARGIN;
+ r.right += PLAYLIST_INNER_MARGIN;
+ r.bottom += PLAYLIST_INNER_MARGIN;
+ m_pCurMenu->DrawMenu(r, xR, *lower_right_corner_y);
+ }
+ else if (m_UI_mode == UI_UPGRADE_PIXEL_SHADER)
+ {
+ RECT rect = {0};
+ SetRect(&rect, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+
+ if (m_pState->m_nWarpPSVersion >= m_nMaxPSVersion &&
+ m_pState->m_nCompPSVersion >= m_nMaxPSVersion)
+ {
+ assert(m_pState->m_nMaxPSVersion == m_nMaxPSVersion);
+ wchar_t buf[1024] = {0};
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_PRESET_USES_HIGHEST_PIXEL_SHADER_VERSION), m_nMaxPSVersion);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), buf, -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESS_ESC_TO_RETURN), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ }
+ else
+ {
+ if (m_pState->m_nMinPSVersion != m_pState->m_nMaxPSVersion)
+ {
+ switch(m_pState->m_nMinPSVersion)
+ {
+ case MD2_PS_NONE:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_HAS_MIXED_VERSIONS_OF_SHADERS), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_SHADERS_TO_USE_PS2), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ case MD2_PS_2_0:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_HAS_MIXED_VERSIONS_OF_SHADERS), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_SHADERS_TO_USE_PS2X), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ case MD2_PS_2_X:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_HAS_MIXED_VERSIONS_OF_SHADERS), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_SHADERS_TO_USE_PS3), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ case MD2_PS_3_0:
+ assert(false);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else
+ {
+ switch(m_pState->m_nMinPSVersion)
+ {
+ case MD2_PS_NONE:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_DOES_NOT_USE_PIXEL_SHADERS), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_TO_USE_PS2), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_WARNING_OLD_GPU_MIGHT_NOT_WORK_WITH_PRESET), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ case MD2_PS_2_0:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_CURRENTLY_USES_PS2), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_TO_USE_PS2X), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_WARNING_OLD_GPU_MIGHT_NOT_WORK_WITH_PRESET), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ case MD2_PS_2_X:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_CURRENTLY_USES_PS2X), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_TO_USE_PS3), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_WARNING_OLD_GPU_MIGHT_NOT_WORK_WITH_PRESET), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ case MD2_PS_3_0:
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_PRESET_CURRENTLY_USES_PS3), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_UPGRADE_TO_USE_PS4), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_WARNING_OLD_GPU_MIGHT_NOT_WORK_WITH_PRESET), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ }
+ *upper_left_corner_y = rect.top;
+ }
+ else if (m_UI_mode == UI_LOAD_DEL)
+ {
+ RECT rect;
+ SetRect(&rect, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_ARE_YOU_SURE_YOU_WANT_TO_DELETE_PRESET), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_PRESET_TO_DELETE), m_presets[m_nPresetListCurPos].szFilename.c_str());
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), buf, -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ *upper_left_corner_y = rect.top;
+ }
+ else if (m_UI_mode == UI_SAVE_OVERWRITE)
+ {
+ RECT rect;
+ SetRect(&rect, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_FILE_ALREADY_EXISTS_OVERWRITE_IT), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_FILE_IN_QUESTION_X_MILK), m_waitstring.szText);
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), buf, -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, MENU_COLOR, true);
+ if (m_bWarpShaderLock)
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_WARNING_DO_NOT_FORGET_WARP_SHADER_WAS_LOCKED), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, 0xFFFFFFFF, true, 0xFFCC0000);
+ if (m_bCompShaderLock)
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), WASABI_API_LNGSTRINGW(IDS_WARNING_DO_NOT_FORGET_COMPOSITE_SHADER_WAS_LOCKED), -1, &rect, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, 0xFFFFFFFF, true, 0xFFCC0000);
+ *upper_left_corner_y = rect.top;
+ }
+ else if (m_UI_mode == UI_MASHUP)
+ {
+ if (m_nPresets-m_nDirs == 0)
+ {
+ // note: this error message is repeated in milkdrop.cpp in LoadRandomPreset()
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ERROR_NO_PRESET_FILE_FOUND_IN_X_MILK), m_szPresetDir);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ m_UI_mode = UI_REGULAR;
+ }
+ else
+ {
+ UpdatePresetList(); // make sure list is completely ready
+
+ // quick checks
+ for (int mash=0; mash<MASH_SLOTS; mash++)
+ {
+ // check validity
+ if (m_nMashPreset[mash] < m_nDirs)
+ m_nMashPreset[mash] = m_nDirs;
+ if (m_nMashPreset[mash] >= m_nPresets)
+ m_nMashPreset[mash] = m_nPresets-1;
+
+ // apply changes, if it's time
+ if (m_nLastMashChangeFrame[mash]+MASH_APPLY_DELAY_FRAMES+1 == GetFrame())
+ {
+ // import just a fragment of a preset!!
+ DWORD ApplyFlags = 0;
+ switch(mash)
+ {
+ case 0: ApplyFlags = STATE_GENERAL; break;
+ case 1: ApplyFlags = STATE_MOTION; break;
+ case 2: ApplyFlags = STATE_WAVE; break;
+ case 3: ApplyFlags = STATE_WARP; break;
+ case 4: ApplyFlags = STATE_COMP; break;
+ }
+
+ wchar_t szFile[MAX_PATH];
+ swprintf(szFile, L"%s%s", m_szPresetDir, m_presets[m_nMashPreset[mash]].szFilename.c_str());
+
+ m_pState->Import(szFile, GetTime(), m_pState, ApplyFlags);
+
+ if (ApplyFlags & STATE_WARP)
+ SafeRelease( m_shaders.warp.ptr );
+ if (ApplyFlags & STATE_COMP)
+ SafeRelease( m_shaders.comp.ptr );
+ LoadShaders(&m_shaders, m_pState, false);
+
+ SetMenusForPresetVersion( m_pState->m_nWarpPSVersion, m_pState->m_nCompPSVersion );
+ }
+ }
+
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_PRESET_MASH_UP_TEXT1), MTO_UPPER_LEFT, true);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_PRESET_MASH_UP_TEXT2), MTO_UPPER_LEFT, true);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_PRESET_MASH_UP_TEXT3), MTO_UPPER_LEFT, true);
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_PRESET_MASH_UP_TEXT4), MTO_UPPER_LEFT, true);
+ *upper_left_corner_y += PLAYLIST_INNER_MARGIN;
+
+ RECT rect;
+ SetRect(&rect, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+ rect.top += PLAYLIST_INNER_MARGIN;
+ rect.left += PLAYLIST_INNER_MARGIN;
+ rect.right -= PLAYLIST_INNER_MARGIN;
+ rect.bottom -= PLAYLIST_INNER_MARGIN;
+
+ int lines_available = (rect.bottom - rect.top - PLAYLIST_INNER_MARGIN*2) / GetFontHeight(SIMPLE_FONT);
+ lines_available -= MASH_SLOTS;
+
+ if (lines_available < 10)
+ {
+ // force it
+ rect.bottom = rect.top + GetFontHeight(SIMPLE_FONT)*10 + 1;
+ lines_available = 10;
+ }
+ if (lines_available > 16)
+ lines_available = 16;
+
+ if (m_bUserPagedDown)
+ {
+ m_nMashPreset[m_nMashSlot] += lines_available;
+ if (m_nMashPreset[m_nMashSlot] >= m_nPresets)
+ m_nMashPreset[m_nMashSlot] = m_nPresets - 1;
+ m_bUserPagedDown = false;
+ }
+ if (m_bUserPagedUp)
+ {
+ m_nMashPreset[m_nMashSlot] -= lines_available;
+ if (m_nMashPreset[m_nMashSlot] < m_nDirs)
+ m_nMashPreset[m_nMashSlot] = m_nDirs;
+ m_bUserPagedUp = false;
+ }
+
+ int i;
+ int first_line = m_nMashPreset[m_nMashSlot] - (m_nMashPreset[m_nMashSlot] % lines_available);
+ int last_line = first_line + lines_available;
+ wchar_t str[512], str2[512];
+
+ if (last_line > m_nPresets)
+ last_line = m_nPresets;
+
+ // tooltip:
+ if (m_bShowMenuToolTips)
+ {
+ wchar_t buf[256];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_PAGE_X_OF_X), m_nMashPreset[m_nMashSlot]/lines_available+1, (m_nPresets+lines_available-1)/lines_available);
+ DrawTooltip(buf, xR, *lower_right_corner_y);
+ }
+
+ RECT orig_rect = rect;
+
+ RECT box;
+ box.top = rect.top;
+ box.left = rect.left;
+ box.right = rect.left;
+ box.bottom = rect.top;
+
+ int mashNames[MASH_SLOTS] = { IDS_MASHUP_GENERAL_POSTPROC,
+ IDS_MASHUP_MOTION_EQUATIONS,
+ IDS_MASHUP_WAVEFORMS_SHAPES,
+ IDS_MASHUP_WARP_SHADER,
+ IDS_MASHUP_COMP_SHADER,
+ };
+
+ int pass = 0;
+ for (pass=0; pass<2; pass++)
+ {
+ box = orig_rect;
+ int w = 0;
+ int h = 0;
+
+ int start_y = orig_rect.top;
+ for (int mash=0; mash<MASH_SLOTS; mash++)
+ {
+ int idx = m_nMashPreset[mash];
+
+ wchar_t buf[1024];
+ swprintf(buf, L"%s%s", WASABI_API_LNGSTRINGW(mashNames[mash]), m_presets[idx].szFilename);
+ RECT r2 = orig_rect;
+ r2.top += h;
+ h += m_text.DrawTextW(GetFont(SIMPLE_FONT), buf, -1, &r2, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX | (pass==0 ? DT_CALCRECT : 0), (mash==m_nMashSlot) ? PLAYLIST_COLOR_HILITE_TRACK : PLAYLIST_COLOR_NORMAL, false);
+ w = max(w, r2.right - r2.left);
+ }
+ if (pass==0) {
+ box.right = box.left + w;
+ box.bottom = box.top + h;
+ DrawDarkTranslucentBox(&box);
+ }
+ else
+ orig_rect.top += h;
+ }
+
+ orig_rect.top += GetFontHeight(SIMPLE_FONT) + PLAYLIST_INNER_MARGIN;
+
+ box = orig_rect;
+ box.right = box.left;
+ box.bottom = box.top;
+
+ // draw a directory listing box right after...
+ for (pass=0; pass<2; pass++)
+ {
+ //if (pass==1)
+ // GetFont(SIMPLE_FONT)->Begin();
+
+ rect = orig_rect;
+ for (i=first_line; i<last_line; i++)
+ {
+ // remove the extension before displaying the filename. also pad w/spaces.
+ //lstrcpy(str, m_pPresetAddr[i]);
+ bool bIsDir = (m_presets[i].szFilename.c_str()[0] == '*');
+ bool bIsRunning = false;
+ bool bIsSelected = (i == m_nMashPreset[m_nMashSlot]);
+
+ if (bIsDir)
+ {
+ // directory
+ if (wcscmp(m_presets[i].szFilename.c_str()+1, L"..")==0)
+ swprintf(str2, L" [ %s ] (%s) ", m_presets[i].szFilename.c_str()+1, WASABI_API_LNGSTRINGW(IDS_PARENT_DIRECTORY));
+ else
+ swprintf(str2, L" [ %s ] ", m_presets[i].szFilename.c_str()+1);
+ }
+ else
+ {
+ // preset file
+ lstrcpyW(str, m_presets[i].szFilename.c_str());
+ RemoveExtension(str);
+ swprintf(str2, L" %s ", str);
+
+ if (wcscmp(m_presets[m_nMashPreset[m_nMashSlot]].szFilename.c_str(), str)==0)
+ bIsRunning = true;
+ }
+
+ if (bIsRunning && m_bPresetLockedByUser)
+ lstrcatW(str2, WASABI_API_LNGSTRINGW(IDS_LOCKED));
+
+ DWORD color = bIsDir ? DIR_COLOR : PLAYLIST_COLOR_NORMAL;
+ if (bIsRunning)
+ color = bIsSelected ? PLAYLIST_COLOR_BOTH : PLAYLIST_COLOR_PLAYING_TRACK;
+ else if (bIsSelected)
+ color = PLAYLIST_COLOR_HILITE_TRACK;
+
+ RECT r2 = rect;
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), str2, -1, &r2, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX | (pass==0 ? DT_CALCRECT : 0), color, false);
+
+ if (pass==0) // calculating dark box
+ {
+ box.right = max(box.right, box.left + r2.right-r2.left);
+ box.bottom += r2.bottom-r2.top;
+ }
+ }
+
+ //if (pass==1)
+ // GetFont(SIMPLE_FONT)->End();
+
+ if (pass==0) // calculating dark box
+ {
+ box.top -= PLAYLIST_INNER_MARGIN;
+ box.left -= PLAYLIST_INNER_MARGIN;
+ box.right += PLAYLIST_INNER_MARGIN;
+ box.bottom += PLAYLIST_INNER_MARGIN;
+ DrawDarkTranslucentBox(&box);
+ *upper_left_corner_y = box.bottom + PLAYLIST_INNER_MARGIN;
+ }
+ else
+ orig_rect.top += box.bottom-box.top;
+ }
+
+ orig_rect.top += PLAYLIST_INNER_MARGIN;
+
+ }
+ }
+ else if (m_UI_mode == UI_LOAD)
+ {
+ if (m_nPresets == 0)
+ {
+ // note: this error message is repeated in milkdrop.cpp in LoadRandomPreset()
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ERROR_NO_PRESET_FILE_FOUND_IN_X_MILK), m_szPresetDir);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ m_UI_mode = UI_REGULAR;
+ }
+ else
+ {
+ MyTextOut(WASABI_API_LNGSTRINGW(IDS_LOAD_WHICH_PRESET_PLUS_COMMANDS), MTO_UPPER_LEFT, true);
+
+ wchar_t buf[MAX_PATH+64];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_DIRECTORY_OF_X), m_szPresetDir);
+ MyTextOut(buf, MTO_UPPER_LEFT, true);
+
+ *upper_left_corner_y += h/2;
+
+ RECT rect;
+ SetRect(&rect, xL, *upper_left_corner_y, xR, *lower_left_corner_y);
+ rect.top += PLAYLIST_INNER_MARGIN;
+ rect.left += PLAYLIST_INNER_MARGIN;
+ rect.right -= PLAYLIST_INNER_MARGIN;
+ rect.bottom -= PLAYLIST_INNER_MARGIN;
+
+ int lines_available = (rect.bottom - rect.top - PLAYLIST_INNER_MARGIN*2) / GetFontHeight(SIMPLE_FONT);
+
+ if (lines_available < 1)
+ {
+ // force it
+ rect.bottom = rect.top + GetFontHeight(SIMPLE_FONT) + 1;
+ lines_available = 1;
+ }
+ if (lines_available > MAX_PRESETS_PER_PAGE)
+ lines_available = MAX_PRESETS_PER_PAGE;
+
+ if (m_bUserPagedDown)
+ {
+ m_nPresetListCurPos += lines_available;
+ if (m_nPresetListCurPos >= m_nPresets)
+ m_nPresetListCurPos = m_nPresets - 1;
+
+ // remember this preset's name so the next time they hit 'L' it jumps straight to it
+ //lstrcpy(m_szLastPresetSelected, m_presets[m_nPresetListCurPos].szFilename.c_str());
+
+ m_bUserPagedDown = false;
+ }
+
+ if (m_bUserPagedUp)
+ {
+ m_nPresetListCurPos -= lines_available;
+ if (m_nPresetListCurPos < 0)
+ m_nPresetListCurPos = 0;
+
+ // remember this preset's name so the next time they hit 'L' it jumps straight to it
+ //lstrcpy(m_szLastPresetSelected, m_presets[m_nPresetListCurPos].szFilename.c_str());
+
+ m_bUserPagedUp = false;
+ }
+
+ int i;
+ int first_line = m_nPresetListCurPos - (m_nPresetListCurPos % lines_available);
+ int last_line = first_line + lines_available;
+ wchar_t str[512], str2[512];
+
+ if (last_line > m_nPresets)
+ last_line = m_nPresets;
+
+ // tooltip:
+ if (m_bShowMenuToolTips)
+ {
+ wchar_t buf[256];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_PAGE_X_OF_X), m_nPresetListCurPos/lines_available+1, (m_nPresets+lines_available-1)/lines_available);
+ DrawTooltip(buf, xR, *lower_right_corner_y);
+ }
+
+ RECT orig_rect = rect;
+
+ RECT box;
+ box.top = rect.top;
+ box.left = rect.left;
+ box.right = rect.left;
+ box.bottom = rect.top;
+
+ for (int pass=0; pass<2; pass++)
+ {
+ //if (pass==1)
+ // GetFont(SIMPLE_FONT)->Begin();
+
+ rect = orig_rect;
+ for (i=first_line; i<last_line; i++)
+ {
+ // remove the extension before displaying the filename. also pad w/spaces.
+ //lstrcpy(str, m_pPresetAddr[i]);
+ bool bIsDir = (m_presets[i].szFilename.c_str()[0] == '*');
+ bool bIsRunning = (i == m_nCurrentPreset);//false;
+ bool bIsSelected = (i == m_nPresetListCurPos);
+
+ if (bIsDir)
+ {
+ // directory
+ if (wcscmp(m_presets[i].szFilename.c_str()+1, L"..")==0)
+ swprintf(str2, L" [ %s ] (%s) ", m_presets[i].szFilename.c_str()+1, WASABI_API_LNGSTRINGW(IDS_PARENT_DIRECTORY));
+ else
+ swprintf(str2, L" [ %s ] ", m_presets[i].szFilename.c_str()+1);
+ }
+ else
+ {
+ // preset file
+ lstrcpyW(str, m_presets[i].szFilename.c_str());
+ RemoveExtension(str);
+ swprintf(str2, L" %s ", str);
+
+ //if (lstrcmp(m_pState->m_szDesc, str)==0)
+ // bIsRunning = true;
+ }
+
+ if (bIsRunning && m_bPresetLockedByUser)
+ lstrcatW(str2, WASABI_API_LNGSTRINGW(IDS_LOCKED));
+
+ DWORD color = bIsDir ? DIR_COLOR : PLAYLIST_COLOR_NORMAL;
+ if (bIsRunning)
+ color = bIsSelected ? PLAYLIST_COLOR_BOTH : PLAYLIST_COLOR_PLAYING_TRACK;
+ else if (bIsSelected)
+ color = PLAYLIST_COLOR_HILITE_TRACK;
+
+ RECT r2 = rect;
+ rect.top += m_text.DrawTextW(GetFont(SIMPLE_FONT), str2, -1, &r2, DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX | (pass==0 ? DT_CALCRECT : 0), color, false);
+
+ if (pass==0) // calculating dark box
+ {
+ box.right = max(box.right, box.left + r2.right-r2.left);
+ box.bottom += r2.bottom-r2.top;
+ }
+ }
+
+ //if (pass==1)
+ // GetFont(SIMPLE_FONT)->End();
+
+ if (pass==0) // calculating dark box
+ {
+ box.top -= PLAYLIST_INNER_MARGIN;
+ box.left -= PLAYLIST_INNER_MARGIN;
+ box.right += PLAYLIST_INNER_MARGIN;
+ box.bottom += PLAYLIST_INNER_MARGIN;
+ DrawDarkTranslucentBox(&box);
+ *upper_left_corner_y = box.bottom + PLAYLIST_INNER_MARGIN;
+ }
+ }
+ }
+ }
+ }
+
+ // 5. render *remaining* text to upper-right corner
+ {
+ // e) custom timed message:
+ if (!m_bWarningsDisabled2)
+ {
+ wchar_t buf[512] = {0};
+ SelectFont(SIMPLE_FONT);
+ float t = GetTime();
+ int N = m_errors.size();
+ for (int i=0; i<N; i++)
+ {
+ if (t >= m_errors[i].birthTime && t < m_errors[i].expireTime)
+ {
+ swprintf(buf, L"%s ", m_errors[i].msg.c_str());
+ float age_rel = (t - m_errors[i].birthTime) / (m_errors[i].expireTime - m_errors[i].birthTime);
+ DWORD cr = (DWORD)(200 - 199*powf(age_rel,4));
+ DWORD cg = 0;//(DWORD)(136 - 135*powf(age_rel,1));
+ DWORD cb = 0;
+ DWORD z = 0xFF000000 | (cr<<16) | (cg<<8) | cb;
+ MyTextOut_BGCOLOR(buf, MTO_UPPER_RIGHT, true, m_errors[i].bBold ? z : 0xFF000000);
+ }
+ else
+ {
+ m_errors.erase(m_errors.begin() + i);
+ i--;
+ N--;
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------
+
+LRESULT CPlugin::MyWindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
+{
+ // You can handle Windows messages here while the plugin is running,
+ // such as mouse events (WM_MOUSEMOVE/WM_LBUTTONDOWN), keypresses
+ // (WK_KEYDOWN/WM_CHAR), and so on.
+ // This function is threadsafe (thanks to Winamp's architecture),
+ // so you don't have to worry about using semaphores or critical
+ // sections to read/write your class member variables.
+ // If you don't handle a message, let it continue on the usual path
+ // (to Winamp) by returning DefWindowProc(hWnd,uMsg,wParam,lParam).
+ // If you do handle a message, prevent it from being handled again
+ // (by Winamp) by returning 0.
+
+ // IMPORTANT: For the WM_KEYDOWN, WM_KEYUP, and WM_CHAR messages,
+ // you must return 0 if you process the message (key),
+ // and 1 if you do not. DO NOT call DefWindowProc()
+ // for these particular messages!
+
+ USHORT mask = 1 << (sizeof(SHORT)*8 - 1);
+ bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+ bool bCtrlHeldDown = (GetKeyState(VK_CONTROL) & mask) != 0;
+
+ int nRepeat = 1; //updated as appropriate
+ int rep;
+
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case ID_VIS_NEXT:
+ NextPreset(m_fBlendTimeUser);
+ return 0;
+ case ID_VIS_PREV:
+ PrevPreset(m_fBlendTimeUser);
+ return 0;
+ case ID_VIS_RANDOM:
+ {
+ // note: when the vis is launched, if we're using a fancy modern skin
+ // (with a Random button), it will send us one of these...
+ // if it's NOT a fancy skin, we'll never get this message (confirmed).
+
+ USHORT v = HIWORD(wParam); // here, v is 0 (locked) or 1 (random) or 0xFFFF (don't know / startup!)
+ if (v==0xFFFF)
+ {
+ // plugin just launched or changed modes -
+ // Winamp wants to know what our saved Random state is...
+ SendMessage(GetWinampWindow(), WM_WA_IPC, (m_bPresetLockOnAtStartup ? 0 : 1) << 16, IPC_CB_VISRANDOM);
+
+ return 0;
+ }
+
+ // otherwise it's 0 or 1 - user clicked the button, we should respond.
+
+ v = v ? 1 : 0; // same here
+
+ //see also - IPC_CB_VISRANDOM
+ m_bPresetLockedByUser = (v == 0);
+ SetScrollLock(m_bPresetLockedByUser, m_bPreventScollLockHandling);
+
+ return 0;
+ }
+ case ID_VIS_FS:
+ PostMessage(hWnd, WM_USER + 1667, 0, 0);
+ return 0;
+ case ID_VIS_CFG:
+ ToggleHelp();
+ return 0;
+ case ID_VIS_MENU:
+ POINT pt;
+ GetCursorPos(&pt);
+ SendMessage(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, (pt.y << 16) | pt.x);
+ return 0;
+ }
+ break;
+
+ /*
+ case WM_SETFOCUS:
+ m_bOrigScrollLockState = GetKeyState(VK_SCROLL) & 1;
+ SetScrollLock(m_bMilkdropScrollLockState);
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+
+ case WM_KILLFOCUS:
+ m_bMilkdropScrollLockState = GetKeyState(VK_SCROLL) & 1;
+ SetScrollLock(m_bOrigScrollLockState);
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ */
+ // this is used to work around a focusing issue when toggling fullscreen
+ // via the 'fullscreen' button in the bento (and most other) modern skin
+ case WM_USER+1667:
+ if (GetFrame() > 0) ToggleFullScreen();
+ return 0;
+
+ case WM_CHAR: // plain & simple alphanumeric keys
+ nRepeat = LOWORD(lParam);
+ if (m_waitstring.bActive) // if user is in the middle of editing a string
+ {
+ if ((wParam >= ' ' && wParam <= 'z') || wParam=='{' || wParam=='}')
+ {
+ int len;
+ if(m_waitstring.bDisplayAsCode)
+ len = lstrlenA((char*)m_waitstring.szText);
+ else
+ len = lstrlenW(m_waitstring.szText);
+
+ if (m_waitstring.bFilterBadChars &&
+ (wParam == '\"' ||
+ wParam == '\\' ||
+ wParam == '/' ||
+ wParam == ':' ||
+ wParam == '*' ||
+ wParam == '?' ||
+ wParam == '|' ||
+ wParam == '<' ||
+ wParam == '>' ||
+ wParam == '&')) // NOTE: '&' is legal in filenames, but we try to avoid it since during GDI display it acts as a control code (it will not show up, but instead, underline the character following it).
+ {
+ // illegal char
+ AddError(WASABI_API_LNGSTRINGW(IDS_ILLEGAL_CHARACTER), 2.5f, ERR_MISC, true);
+ }
+ else if (len+nRepeat >= m_waitstring.nMaxLen)
+ {
+ // m_waitstring.szText has reached its limit
+ AddError(WASABI_API_LNGSTRINGW(IDS_STRING_TOO_LONG), 2.5f, ERR_MISC, true);
+ }
+ else
+ {
+ //m_fShowUserMessageUntilThisTime = GetTime(); // if there was an error message already, clear it
+
+ if(m_waitstring.bDisplayAsCode)
+ {
+ char buf[16];
+ sprintf(buf, "%c", wParam);
+
+ if (m_waitstring.nSelAnchorPos != -1)
+ WaitString_NukeSelection();
+
+ if (m_waitstring.bOvertypeMode)
+ {
+ // overtype mode
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ if (m_waitstring.nCursorPos == len)
+ {
+ lstrcatA((char*)m_waitstring.szText, buf);
+ len++;
+ }
+ else
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ *(ptr + m_waitstring.nCursorPos) = buf[0];
+ }
+ m_waitstring.nCursorPos++;
+ }
+ }
+ else
+ {
+ // insert mode:
+ char* ptr = (char*)m_waitstring.szText;
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ for (int i=len; i>=m_waitstring.nCursorPos; i--)
+ *(ptr + i+1) = *(ptr + i);
+ *(ptr + m_waitstring.nCursorPos) = buf[0];
+ m_waitstring.nCursorPos++;
+ len++;
+ }
+ }
+ }
+ else
+ {
+ wchar_t buf[16];
+ swprintf(buf, L"%c", wParam);
+
+ if (m_waitstring.nSelAnchorPos != -1)
+ WaitString_NukeSelection();
+
+ if (m_waitstring.bOvertypeMode)
+ {
+ // overtype mode
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ if (m_waitstring.nCursorPos == len)
+ {
+ lstrcatW(m_waitstring.szText, buf);
+ len++;
+ }
+ else
+ m_waitstring.szText[m_waitstring.nCursorPos] = buf[0];
+ m_waitstring.nCursorPos++;
+ }
+ }
+ else
+ {
+ // insert mode:
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ for (int i=len; i>=m_waitstring.nCursorPos; i--)
+ m_waitstring.szText[i+1] = m_waitstring.szText[i];
+ m_waitstring.szText[m_waitstring.nCursorPos] = buf[0];
+ m_waitstring.nCursorPos++;
+ len++;
+ }
+ }
+ }
+ }
+ }
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_LOAD_DEL) // waiting to confirm file delete
+ {
+ if (wParam == keyMappings[0] || wParam == keyMappings[1]) // 'y' or 'Y'
+ {
+ // first add pathname to filename
+ wchar_t szDelFile[512];
+ swprintf(szDelFile, L"%s%s", GetPresetDir(), m_presets[m_nPresetListCurPos].szFilename.c_str());
+
+ DeletePresetFile(szDelFile);
+ //m_nCurrentPreset = -1;
+ }
+
+ m_UI_mode = UI_LOAD;
+
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_UPGRADE_PIXEL_SHADER)
+ {
+ if (wParam == keyMappings[0] || wParam == keyMappings[1]) // 'y' or 'Y'
+ {
+ if (m_pState->m_nMinPSVersion == m_pState->m_nMaxPSVersion)
+ {
+ switch(m_pState->m_nMinPSVersion)
+ {
+ case MD2_PS_NONE:
+ m_pState->m_nWarpPSVersion = MD2_PS_2_0;
+ m_pState->m_nCompPSVersion = MD2_PS_2_0;
+ m_pState->GenDefaultWarpShader();
+ m_pState->GenDefaultCompShader();
+ break;
+ case MD2_PS_2_0:
+ m_pState->m_nWarpPSVersion = MD2_PS_2_X;
+ m_pState->m_nCompPSVersion = MD2_PS_2_X;
+ break;
+ case MD2_PS_2_X:
+ m_pState->m_nWarpPSVersion = MD2_PS_3_0;
+ m_pState->m_nCompPSVersion = MD2_PS_3_0;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else
+ {
+ switch(m_pState->m_nMinPSVersion)
+ {
+ case MD2_PS_NONE:
+ if (m_pState->m_nWarpPSVersion < MD2_PS_2_0)
+ {
+ m_pState->m_nWarpPSVersion = MD2_PS_2_0;
+ m_pState->GenDefaultWarpShader();
+ }
+ if (m_pState->m_nCompPSVersion < MD2_PS_2_0)
+ {
+ m_pState->m_nCompPSVersion = MD2_PS_2_0;
+ m_pState->GenDefaultCompShader();
+ }
+ break;
+ case MD2_PS_2_0:
+ m_pState->m_nWarpPSVersion = max(m_pState->m_nWarpPSVersion, MD2_PS_2_X);
+ m_pState->m_nCompPSVersion = max(m_pState->m_nCompPSVersion, MD2_PS_2_X);
+ break;
+ case MD2_PS_2_X:
+ m_pState->m_nWarpPSVersion = max(m_pState->m_nWarpPSVersion, MD2_PS_3_0);
+ m_pState->m_nCompPSVersion = max(m_pState->m_nCompPSVersion, MD2_PS_3_0);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ m_pState->m_nMinPSVersion = min(m_pState->m_nWarpPSVersion, m_pState->m_nCompPSVersion);
+ m_pState->m_nMaxPSVersion = max(m_pState->m_nWarpPSVersion, m_pState->m_nCompPSVersion);
+
+ LoadShaders(&m_shaders, m_pState, false);
+ SetMenusForPresetVersion( m_pState->m_nWarpPSVersion, m_pState->m_nCompPSVersion );
+ }
+ if (wParam != 13)
+ m_UI_mode = UI_MENU;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_SAVE_OVERWRITE) // waiting to confirm overwrite file on save
+ {
+ if (wParam == keyMappings[0] || wParam == keyMappings[1]) // 'y' or 'Y'
+ {
+ // first add pathname + extension to filename
+ wchar_t szNewFile[512];
+ swprintf(szNewFile, L"%s%s.milk", GetPresetDir(), m_waitstring.szText);
+
+ SavePresetAs(szNewFile);
+
+ // exit waitstring mode
+ m_UI_mode = UI_REGULAR;
+ m_waitstring.bActive = false;
+ //m_bPresetLockedByCode = false;
+ }
+ else if ((wParam >= ' ' && wParam <= 'z') || wParam == 27) // 27 is the ESCAPE key
+ {
+ // go back to SAVE AS mode
+ m_UI_mode = UI_SAVEAS;
+ m_waitstring.bActive = true;
+ }
+
+ return 0; // we processed (or absorbed) the key
+ }
+ else // normal handling of a simple key (all non-virtual-key hotkeys end up here)
+ {
+ if (HandleRegularKey(wParam)==0)
+ return 0;
+ }
+ return 1; // end case WM_CHAR
+
+ case WM_KEYDOWN: // virtual-key codes
+ // Note that some keys will never reach this point, since they are
+ // intercepted by the plugin shell (see PluginShellWindowProc(),
+ // at the end of pluginshell.cpp for which ones).
+ // For a complete list of virtual-key codes, look up the keyphrase
+ // "virtual-key codes [win32]" in the msdn help.
+ nRepeat = LOWORD(lParam);
+
+ switch(wParam)
+ {
+ case VK_F2: m_bShowSongTitle = !m_bShowSongTitle; return 0; // we processed (or absorbed) the key
+ case VK_F3:
+ if (m_bShowSongTime && m_bShowSongLen)
+ {
+ m_bShowSongTime = false;
+ m_bShowSongLen = false;
+ }
+ else if (m_bShowSongTime && !m_bShowSongLen)
+ {
+ m_bShowSongLen = true;
+ }
+ else
+ {
+ m_bShowSongTime = true;
+ m_bShowSongLen = false;
+ }
+ return 0; // we processed (or absorbed) the key
+ case VK_F4: m_bShowPresetInfo = !m_bShowPresetInfo; return 0; // we processed (or absorbed) the key
+ case VK_F5: m_bShowFPS = !m_bShowFPS; return 0; // we processed (or absorbed) the key
+ case VK_F6: m_bShowRating = !m_bShowRating; return 0; // we processed (or absorbed) the key
+ case VK_F7:
+ if (m_nNumericInputMode == NUMERIC_INPUT_MODE_CUST_MSG)
+ ReadCustomMessages(); // re-read custom messages
+ return 0; // we processed (or absorbed) the key
+ case VK_F8:
+ {
+ m_UI_mode = UI_CHANGEDIR;
+
+ // enter WaitString mode
+ m_waitstring.bActive = true;
+ m_waitstring.bFilterBadChars = false;
+ m_waitstring.bDisplayAsCode = false;
+ m_waitstring.nSelAnchorPos = -1;
+ m_waitstring.nMaxLen = min(sizeof(m_waitstring.szText)-1, MAX_PATH - 1);
+ lstrcpyW(m_waitstring.szText, GetPresetDir());
+ {
+ // for subtle beauty - remove the trailing '\' from the directory name (if it's not just "x:\")
+ int len = lstrlenW(m_waitstring.szText);
+ if (len > 3 && m_waitstring.szText[len-1] == '\\')
+ m_waitstring.szText[len-1] = 0;
+ }
+ WASABI_API_LNGSTRINGW_BUF(IDS_DIRECTORY_TO_JUMP_TO, m_waitstring.szPrompt, 512);
+ m_waitstring.szToolTip[0] = 0;
+ m_waitstring.nCursorPos = lstrlenW(m_waitstring.szText); // set the starting edit position
+ }
+ return 0; // we processed (or absorbed) the key
+
+ case VK_F9:
+ m_bShowShaderHelp = !m_bShowShaderHelp;
+ return FALSE;
+
+ case VK_SCROLL:
+ m_bPresetLockedByUser = GetKeyState(VK_SCROLL) & 1;
+ //SetScrollLock(m_bPresetLockedByUser);
+ SendMessage(GetWinampWindow(), WM_WA_IPC, (m_bPresetLockedByUser ? 0 : 1) << 16, IPC_CB_VISRANDOM);
+ //int set = m_bPresetLockedByUser ?
+ //PostMessage(GetWinampWindow(), WM_COMMAND, ID_VIS_RANDOM | (set << 16), 0);
+
+ return 0; // we processed (or absorbed) the key
+ //case VK_F6: break;
+ //case VK_F7: conflict
+ //case VK_F8: break;
+ //case VK_F9: conflict
+ }
+
+ // next handle the waitstring case (for string-editing),
+ // then the menu navigation case,
+ // then handle normal case (handle the message normally or pass on to winamp)
+
+ // case 1: waitstring mode
+ if (m_waitstring.bActive)
+ {
+ // handle arrow keys, home, end, etc.
+
+ USHORT mask = 1 << (sizeof(SHORT)*8 - 1); // we want the highest-order bit
+ bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+ bool bCtrlHeldDown = (GetKeyState(VK_CONTROL) & mask) != 0;
+
+ if (wParam == VK_LEFT || wParam == VK_RIGHT ||
+ wParam == VK_HOME || wParam == VK_END ||
+ wParam == VK_UP || wParam == VK_DOWN)
+ {
+ if (bShiftHeldDown)
+ {
+ if (m_waitstring.nSelAnchorPos == -1)
+ m_waitstring.nSelAnchorPos = m_waitstring.nCursorPos;
+ }
+ else
+ {
+ m_waitstring.nSelAnchorPos = -1;
+ }
+ }
+
+ if (bCtrlHeldDown) // copy/cut/paste
+ {
+ switch(wParam)
+ {
+ case 'c':
+ case 'C':
+ case VK_INSERT:
+ WaitString_Copy();
+ return 0; // we processed (or absorbed) the key
+ case 'x':
+ case 'X':
+ WaitString_Cut();
+ return 0; // we processed (or absorbed) the key
+ case 'v':
+ case 'V':
+ WaitString_Paste();
+ return 0; // we processed (or absorbed) the key
+ case VK_LEFT: WaitString_SeekLeftWord(); return 0; // we processed (or absorbed) the key
+ case VK_RIGHT: WaitString_SeekRightWord(); return 0; // we processed (or absorbed) the key
+ case VK_HOME: m_waitstring.nCursorPos = 0; return 0; // we processed (or absorbed) the key
+ case VK_END:
+ if (m_waitstring.bDisplayAsCode)
+ {
+ m_waitstring.nCursorPos = lstrlenA((char*)m_waitstring.szText);
+ }
+ else
+ {
+ m_waitstring.nCursorPos = lstrlenW(m_waitstring.szText);
+ }
+ return 0; // we processed (or absorbed) the key
+ case VK_RETURN:
+ if (m_waitstring.bDisplayAsCode)
+ {
+ // CTRL+ENTER accepts the string -> finished editing
+ //assert(m_pCurMenu);
+ m_pCurMenu->OnWaitStringAccept(m_waitstring.szText);
+ // OnWaitStringAccept calls the callback function. See the
+ // calls to CMenu::AddItem from milkdrop.cpp to find the
+ // callback functions for different "waitstrings".
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_MENU;
+ }
+ return 0; // we processed (or absorbed) the key
+ }
+ }
+ else // waitstring mode key pressed, and ctrl NOT held down
+ {
+ switch(wParam)
+ {
+ case VK_INSERT:
+ m_waitstring.bOvertypeMode = !m_waitstring.bOvertypeMode;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_LEFT:
+ for (rep=0; rep<nRepeat; rep++)
+ if (m_waitstring.nCursorPos > 0)
+ m_waitstring.nCursorPos--;
+ return 0; // we processed (or absorbed) the key
+
+ case VK_RIGHT:
+ for (rep=0; rep<nRepeat; rep++)
+ {
+ if (m_waitstring.bDisplayAsCode)
+ {
+ if (m_waitstring.nCursorPos < (int)lstrlenA((char*)m_waitstring.szText))
+ m_waitstring.nCursorPos++;
+ }
+ else
+ {
+ if (m_waitstring.nCursorPos < (int)lstrlenW(m_waitstring.szText))
+ m_waitstring.nCursorPos++;
+ }
+ }
+ return 0; // we processed (or absorbed) the key
+
+ case VK_HOME:
+ m_waitstring.nCursorPos -= WaitString_GetCursorColumn();
+ return 0; // we processed (or absorbed) the key
+
+ case VK_END:
+ m_waitstring.nCursorPos += WaitString_GetLineLength() - WaitString_GetCursorColumn();
+ return 0; // we processed (or absorbed) the key
+
+ case VK_UP:
+ for (rep=0; rep<nRepeat; rep++)
+ WaitString_SeekUpOneLine();
+ return 0; // we processed (or absorbed) the key
+
+ case VK_DOWN:
+ for (rep=0; rep<nRepeat; rep++)
+ WaitString_SeekDownOneLine();
+ return 0; // we processed (or absorbed) the key
+
+ case VK_BACK:
+ if (m_waitstring.nSelAnchorPos != -1)
+ {
+ WaitString_NukeSelection();
+ }
+ else if (m_waitstring.nCursorPos > 0)
+ {
+ int len;
+ if (m_waitstring.bDisplayAsCode)
+ {
+ len = lstrlenA((char*)m_waitstring.szText);
+ }
+ else
+ {
+ len = lstrlenW(m_waitstring.szText);
+ }
+ int src_pos = m_waitstring.nCursorPos;
+ int dst_pos = m_waitstring.nCursorPos - nRepeat;
+ int gap = nRepeat;
+ int copy_chars = len - m_waitstring.nCursorPos + 1; // includes NULL @ end
+ if (dst_pos < 0)
+ {
+ gap += dst_pos;
+ //copy_chars += dst_pos;
+ dst_pos = 0;
+ }
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ for (int i=0; i<copy_chars; i++)
+ *(ptr + dst_pos+i) = *(ptr + src_pos+i);
+ }
+ else
+ {
+ for (int i=0; i<copy_chars; i++)
+ m_waitstring.szText[dst_pos+i] = m_waitstring.szText[src_pos+i];
+ }
+ m_waitstring.nCursorPos -= gap;
+ }
+ return 0; // we processed (or absorbed) the key
+
+ case VK_DELETE:
+ if (m_waitstring.nSelAnchorPos != -1)
+ {
+ WaitString_NukeSelection();
+ }
+ else
+ {
+ if (m_waitstring.bDisplayAsCode)
+ {
+ int len = lstrlenA((char*)m_waitstring.szText);
+ char* ptr = (char*)m_waitstring.szText;
+ for (int i=m_waitstring.nCursorPos; i<=len - nRepeat; i++)
+ *(ptr + i) = *(ptr + i+nRepeat);
+ }
+ else
+ {
+ int len = lstrlenW(m_waitstring.szText);
+ for (int i=m_waitstring.nCursorPos; i<=len - nRepeat; i++)
+ m_waitstring.szText[i] = m_waitstring.szText[i+nRepeat];
+ }
+ }
+ return 0; // we processed (or absorbed) the key
+
+ case VK_RETURN:
+ if (m_UI_mode == UI_LOAD_RENAME) // rename (move) the file
+ {
+ // first add pathnames to filenames
+ wchar_t szOldFile[512];
+ wchar_t szNewFile[512];
+ lstrcpyW(szOldFile, GetPresetDir());
+ lstrcpyW(szNewFile, GetPresetDir());
+ lstrcatW(szOldFile, m_presets[m_nPresetListCurPos].szFilename.c_str());
+ lstrcatW(szNewFile, m_waitstring.szText);
+ lstrcatW(szNewFile, L".milk");
+
+ RenamePresetFile(szOldFile, szNewFile);
+ }
+ else if (m_UI_mode == UI_IMPORT_WAVE ||
+ m_UI_mode == UI_EXPORT_WAVE ||
+ m_UI_mode == UI_IMPORT_SHAPE ||
+ m_UI_mode == UI_EXPORT_SHAPE)
+ {
+ int bWave = (m_UI_mode == UI_IMPORT_WAVE || m_UI_mode == UI_EXPORT_WAVE);
+ int bImport = (m_UI_mode == UI_IMPORT_WAVE || m_UI_mode == UI_IMPORT_SHAPE);
+
+ int i = m_pCurMenu->GetCurItem()->m_lParam;
+ int ret;
+ switch(m_UI_mode)
+ {
+ case UI_IMPORT_WAVE : ret = m_pState->m_wave[i].Import(NULL, m_waitstring.szText, 0); break;
+ case UI_EXPORT_WAVE : ret = m_pState->m_wave[i].Export(NULL, m_waitstring.szText, 0); break;
+ case UI_IMPORT_SHAPE: ret = m_pState->m_shape[i].Import(NULL, m_waitstring.szText, 0); break;
+ case UI_EXPORT_SHAPE: ret = m_pState->m_shape[i].Export(NULL, m_waitstring.szText, 0); break;
+ }
+
+ if (bImport)
+ m_pState->RecompileExpressions(1);
+
+ //m_fShowUserMessageUntilThisTime = GetTime() - 1.0f; // if there was an error message already, clear it
+ if (!ret)
+ {
+ wchar_t buf[1024];
+ if (m_UI_mode==UI_IMPORT_WAVE || m_UI_mode==UI_IMPORT_SHAPE)
+ WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_IMPORTING_BAD_FILENAME, buf, 1024);
+ else
+ WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_IMPORTING_BAD_FILENAME_OR_NOT_OVERWRITEABLE, buf, 1024);
+ AddError(WASABI_API_LNGSTRINGW(IDS_STRING_TOO_LONG), 2.5f, ERR_MISC, true);
+ }
+
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_MENU;
+ //m_bPresetLockedByCode = false;
+ }
+ else if (m_UI_mode == UI_SAVEAS)
+ {
+ // first add pathname + extension to filename
+ wchar_t szNewFile[512];
+ swprintf(szNewFile, L"%s%s.milk", GetPresetDir(), m_waitstring.szText);
+
+ if (GetFileAttributesW(szNewFile) != -1) // check if file already exists
+ {
+ // file already exists -> overwrite it?
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_SAVE_OVERWRITE;
+ }
+ else
+ {
+ SavePresetAs(szNewFile);
+
+ // exit waitstring mode
+ m_UI_mode = UI_REGULAR;
+ m_waitstring.bActive = false;
+ //m_bPresetLockedByCode = false;
+ }
+ }
+ else if (m_UI_mode == UI_EDIT_MENU_STRING)
+ {
+ if (m_waitstring.bDisplayAsCode)
+ {
+ if (m_waitstring.nSelAnchorPos != -1)
+ WaitString_NukeSelection();
+
+ int len = lstrlenA((char*)m_waitstring.szText);
+ char* ptr = (char*)m_waitstring.szText;
+ if (len + 1 < m_waitstring.nMaxLen)
+ {
+ // insert a linefeed. Use CTRL+return to accept changes in this case.
+ for (int pos=len+1; pos > m_waitstring.nCursorPos; pos--)
+ *(ptr + pos) = *(ptr + pos - 1);
+ *(ptr + m_waitstring.nCursorPos++) = LINEFEED_CONTROL_CHAR;
+
+ //m_fShowUserMessageUntilThisTime = GetTime() - 1.0f; // if there was an error message already, clear it
+ }
+ else
+ {
+ // m_waitstring.szText has reached its limit
+ AddError(WASABI_API_LNGSTRINGW(IDS_STRING_TOO_LONG), 2.5f, ERR_MISC, true);
+ }
+ }
+ else
+ {
+ // finished editing
+ //assert(m_pCurMenu);
+ m_pCurMenu->OnWaitStringAccept(m_waitstring.szText);
+ // OnWaitStringAccept calls the callback function. See the
+ // calls to CMenu::AddItem from milkdrop.cpp to find the
+ // callback functions for different "waitstrings".
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_MENU;
+ }
+ }
+ else if (m_UI_mode == UI_CHANGEDIR)
+ {
+ //m_fShowUserMessageUntilThisTime = GetTime(); // if there was an error message already, clear it
+
+ // change dir
+ wchar_t szOldDir[512];
+ wchar_t szNewDir[512];
+ lstrcpyW(szOldDir, g_plugin.m_szPresetDir);
+ lstrcpyW(szNewDir, m_waitstring.szText);
+
+ int len = lstrlenW(szNewDir);
+ if (len > 0 && szNewDir[len-1] != L'\\')
+ lstrcatW(szNewDir, L"\\");
+
+ lstrcpyW(g_plugin.m_szPresetDir, szNewDir);
+
+ bool bSuccess = true;
+ if (GetFileAttributesW(g_plugin.m_szPresetDir) == -1)
+ bSuccess = false;
+ if (bSuccess) {
+ UpdatePresetList(false,true,false);
+ bSuccess = (m_nPresets > 0);
+ }
+
+ if (!bSuccess)
+ {
+ // new dir. was invalid -> allow them to try again
+ lstrcpyW(g_plugin.m_szPresetDir, szOldDir);
+
+ // give them a warning
+ AddError(WASABI_API_LNGSTRINGW(IDS_INVALID_PATH), 3.5f, ERR_MISC, true);
+ }
+ else
+ {
+ // success
+ lstrcpyW(g_plugin.m_szPresetDir, szNewDir);
+
+ // save new path to registry
+ WritePrivateProfileStringW(L"settings",L"szPresetDir",g_plugin.m_szPresetDir,GetConfigIniFile());
+
+ // set current preset index to -1 because current preset is no longer in the list
+ m_nCurrentPreset = -1;
+
+ // go to file load menu
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_LOAD;
+
+ ClearErrors(ERR_MISC);
+ }
+ }
+ return 0; // we processed (or absorbed) the key
+
+ case VK_ESCAPE:
+ if (m_UI_mode == UI_LOAD_RENAME)
+ {
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_LOAD;
+ }
+ else if (
+ m_UI_mode == UI_SAVEAS ||
+ m_UI_mode == UI_SAVE_OVERWRITE ||
+ m_UI_mode == UI_EXPORT_SHAPE ||
+ m_UI_mode == UI_IMPORT_SHAPE ||
+ m_UI_mode == UI_EXPORT_WAVE ||
+ m_UI_mode == UI_IMPORT_WAVE)
+ {
+ //m_bPresetLockedByCode = false;
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_REGULAR;
+ }
+ else if (m_UI_mode == UI_EDIT_MENU_STRING)
+ {
+ m_waitstring.bActive = false;
+ if (m_waitstring.bDisplayAsCode) // if were editing code...
+ m_UI_mode = UI_MENU; // return to menu
+ else
+ m_UI_mode = UI_REGULAR; // otherwise don't (we might have been editing a filename, for example)
+ }
+ else /*if (m_UI_mode == UI_EDIT_MENU_STRING || m_UI_mode == UI_CHANGEDIR || 1)*/
+ {
+ m_waitstring.bActive = false;
+ m_UI_mode = UI_REGULAR;
+ }
+ return 0; // we processed (or absorbed) the key
+ }
+ }
+
+ // don't let keys go anywhere else
+ return 0; // we processed (or absorbed) the key
+ }
+
+ // case 2: menu is up & gets the keyboard input
+ if (m_UI_mode == UI_MENU)
+ {
+ //assert(m_pCurMenu);
+ if (m_pCurMenu->HandleKeydown(hWnd, uMsg, wParam, lParam) == 0)
+ return 0; // we processed (or absorbed) the key
+ }
+
+ // case 3: handle non-character keys (virtual keys) and return 0.
+ // if we don't handle them, return 1, and the shell will
+ // (passing some to the shell's key bindings, some to Winamp,
+ // and some to DefWindowProc)
+ // note: regular hotkeys should be handled in HandleRegularKey.
+ switch(wParam)
+ {
+ case VK_LEFT:
+ case VK_RIGHT:
+ if (m_UI_mode == UI_LOAD)
+ {
+ // it's annoying when the music skips if you hit the left arrow from the Load menu, so instead, we exit the menu
+ if (wParam == VK_LEFT) m_UI_mode = UI_REGULAR;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_UPGRADE_PIXEL_SHADER)
+ {
+ m_UI_mode = UI_MENU;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_MASHUP)
+ {
+ if (wParam==VK_LEFT)
+ m_nMashSlot = max(0, m_nMashSlot-1);
+ else
+ m_nMashSlot = min(MASH_SLOTS-1, m_nMashSlot+1);
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+
+ case VK_ESCAPE:
+ if (m_UI_mode == UI_LOAD || m_UI_mode == UI_MENU || m_UI_mode == UI_MASHUP)
+ {
+ m_UI_mode = UI_REGULAR;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_LOAD_DEL)
+ {
+ m_UI_mode = UI_LOAD;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_UPGRADE_PIXEL_SHADER)
+ {
+ m_UI_mode = UI_MENU;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_SAVE_OVERWRITE)
+ {
+ m_UI_mode = UI_SAVEAS;
+ // return to waitstring mode, leaving all the parameters as they were before:
+ m_waitstring.bActive = true;
+ return 0; // we processed (or absorbed) the key
+ }
+ /*else if (hwnd == GetPluginWindow()) // (don't close on ESC for text window)
+ {
+ dumpmsg("User pressed ESCAPE");
+ //m_bExiting = true;
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ return 0; // we processed (or absorbed) the key
+ }*/
+ break;
+
+ case VK_UP:
+ if (m_UI_mode == UI_MASHUP)
+ {
+ for (rep=0; rep<nRepeat; rep++)
+ m_nMashPreset[m_nMashSlot] = max(m_nMashPreset[m_nMashSlot]-1, m_nDirs);
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame(); // causes delayed apply
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_LOAD)
+ {
+ for (rep=0; rep<nRepeat; rep++)
+ if (m_nPresetListCurPos > 0)
+ m_nPresetListCurPos--;
+ return 0; // we processed (or absorbed) the key
+
+ // remember this preset's name so the next time they hit 'L' it jumps straight to it
+ //lstrcpy(m_szLastPresetSelected, m_presets[m_nPresetListCurPos].szFilename.c_str());
+ }
+ break;
+
+ case VK_DOWN:
+ if (m_UI_mode == UI_MASHUP)
+ {
+ for (rep=0; rep<nRepeat; rep++)
+ m_nMashPreset[m_nMashSlot] = min(m_nMashPreset[m_nMashSlot]+1, m_nPresets-1);
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame(); // causes delayed apply
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_LOAD)
+ {
+ for (rep=0; rep<nRepeat; rep++)
+ if (m_nPresetListCurPos < m_nPresets - 1)
+ m_nPresetListCurPos++;
+ return 0; // we processed (or absorbed) the key
+
+ // remember this preset's name so the next time they hit 'L' it jumps straight to it
+ //lstrcpy(m_szLastPresetSelected, m_presets[m_nPresetListCurPos].szFilename.c_str());
+ }
+ break;
+
+ case VK_SPACE:
+ if (m_UI_mode == UI_LOAD)
+ goto HitEnterFromLoadMenu;
+ if (!m_bPresetLockedByCode)
+ {
+ LoadRandomPreset(m_fBlendTimeUser);
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+
+ case VK_PRIOR:
+ if (m_UI_mode == UI_LOAD || m_UI_mode == UI_MASHUP)
+ {
+ m_bUserPagedUp = true;
+ if (m_UI_mode == UI_MASHUP)
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame(); // causes delayed apply
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+ case VK_NEXT:
+ if (m_UI_mode == UI_LOAD || m_UI_mode == UI_MASHUP)
+ {
+ m_bUserPagedDown = true;
+ if (m_UI_mode == UI_MASHUP)
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame(); // causes delayed apply
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+ case VK_HOME:
+ if (m_UI_mode == UI_LOAD)
+ {
+ m_nPresetListCurPos = 0;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_MASHUP)
+ {
+ m_nMashPreset[m_nMashSlot] = m_nDirs;
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame(); // causes delayed apply
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+ case VK_END:
+ if (m_UI_mode == UI_LOAD)
+ {
+ m_nPresetListCurPos = m_nPresets - 1;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_MASHUP)
+ {
+ m_nMashPreset[m_nMashSlot] = m_nPresets-1;
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame(); // causes delayed apply
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+
+ case VK_DELETE:
+ if (m_UI_mode == UI_LOAD)
+ {
+ if (m_presets[m_nPresetListCurPos].szFilename.c_str()[0] != '*') // can't delete directories
+ m_UI_mode = UI_LOAD_DEL;
+ return 0; // we processed (or absorbed) the key
+ }
+ else //if (m_nNumericInputDigits == 0)
+ {
+ if (m_nNumericInputMode == NUMERIC_INPUT_MODE_CUST_MSG)
+ {
+ m_nNumericInputDigits = 0;
+ m_nNumericInputNum = 0;
+
+ // stop display of text message.
+ m_supertext.fStartTime = -1.0f;
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_nNumericInputMode == NUMERIC_INPUT_MODE_SPRITE)
+ {
+ // kill newest sprite (regular DELETE key)
+ // oldest sprite (SHIFT + DELETE),
+ // or all sprites (CTRL + SHIFT + DELETE).
+
+ m_nNumericInputDigits = 0;
+ m_nNumericInputNum = 0;
+
+ USHORT mask = 1 << (sizeof(SHORT)*8 - 1); // we want the highest-order bit
+ bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+ bool bCtrlHeldDown = (GetKeyState(VK_CONTROL) & mask) != 0;
+
+ if (bShiftHeldDown && bCtrlHeldDown)
+ {
+ for (int x=0; x<NUM_TEX; x++)
+ m_texmgr.KillTex(x);
+ }
+ else
+ {
+ int newest = -1;
+ int frame;
+ for (int x=0; x<NUM_TEX; x++)
+ {
+ if (m_texmgr.m_tex[x].pSurface)
+ {
+ if ((newest == -1) ||
+ (!bShiftHeldDown && m_texmgr.m_tex[x].nStartFrame > frame) ||
+ (bShiftHeldDown && m_texmgr.m_tex[x].nStartFrame < frame))
+ {
+ newest = x;
+ frame = m_texmgr.m_tex[x].nStartFrame;
+ }
+ }
+ }
+
+ if (newest != -1)
+ m_texmgr.KillTex(newest);
+ }
+ return 0; // we processed (or absorbed) the key
+ }
+ }
+ break;
+
+ case VK_INSERT: // RENAME
+ if (m_UI_mode == UI_LOAD)
+ {
+ if (m_presets[m_nPresetListCurPos].szFilename.c_str()[0] != '*') // can't rename directories
+ {
+ // go into RENAME mode
+ m_UI_mode = UI_LOAD_RENAME;
+ m_waitstring.bActive = true;
+ m_waitstring.bFilterBadChars = true;
+ m_waitstring.bDisplayAsCode = false;
+ m_waitstring.nSelAnchorPos = -1;
+ m_waitstring.nMaxLen = min(sizeof(m_waitstring.szText)-1, MAX_PATH - lstrlenW(GetPresetDir()) - 6); // 6 for the extension + null char. We set this because win32 LoadFile, MoveFile, etc. barf if the path+filename+ext are > MAX_PATH chars.
+
+ // initial string is the filename, minus the extension
+ lstrcpyW(m_waitstring.szText, m_presets[m_nPresetListCurPos].szFilename.c_str());
+ RemoveExtension(m_waitstring.szText);
+
+ // set the prompt & 'tooltip'
+ swprintf(m_waitstring.szPrompt, WASABI_API_LNGSTRINGW(IDS_ENTER_THE_NEW_NAME_FOR_X), m_waitstring.szText);
+ m_waitstring.szToolTip[0] = 0;
+
+ // set the starting edit position
+ m_waitstring.nCursorPos = lstrlenW(m_waitstring.szText);
+ }
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+
+ case VK_RETURN:
+
+ if (m_UI_mode == UI_MASHUP)
+ {
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame() + MASH_APPLY_DELAY_FRAMES; // causes instant apply
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_LOAD)
+ {
+ HitEnterFromLoadMenu:
+
+ if (m_presets[m_nPresetListCurPos].szFilename.c_str()[0] == '*')
+ {
+ // CHANGE DIRECTORY
+ wchar_t *p = GetPresetDir();
+
+ if (wcscmp(m_presets[m_nPresetListCurPos].szFilename.c_str(), L"*..") == 0)
+ {
+ // back up one dir
+ wchar_t *p2 = wcsrchr(p, L'\\');
+ if (p2)
+ {
+ *p2 = 0;
+ p2 = wcsrchr(p, L'\\');
+ if (p2) *(p2+1) = 0;
+ }
+ }
+ else
+ {
+ // open subdir
+ lstrcatW(p, &m_presets[m_nPresetListCurPos].szFilename.c_str()[1]);
+ lstrcatW(p, L"\\");
+ }
+
+ WritePrivateProfileStringW(L"settings",L"szPresetDir",GetPresetDir(),GetConfigIniFile());
+
+ UpdatePresetList(false, true, false);
+
+ // set current preset index to -1 because current preset is no longer in the list
+ m_nCurrentPreset = -1;
+ }
+ else
+ {
+ // LOAD NEW PRESET
+ m_nCurrentPreset = m_nPresetListCurPos;
+
+ // first take the filename and prepend the path. (already has extension)
+ wchar_t s[MAX_PATH];
+ lstrcpyW(s, GetPresetDir()); // note: m_szPresetDir always ends with '\'
+ lstrcatW(s, m_presets[m_nCurrentPreset].szFilename.c_str());
+
+ // now load (and blend to) the new preset
+ m_presetHistoryPos = (m_presetHistoryPos+1) % PRESET_HIST_LEN;
+ LoadPreset(s, (wParam==VK_SPACE) ? m_fBlendTimeUser : 0);
+ }
+ return 0; // we processed (or absorbed) the key
+ }
+ break;
+
+ case VK_BACK:
+ // pass on to parent
+ //PostMessage(m_hWndParent,message,wParam,lParam);
+ PrevPreset(0);
+ m_fHardCutThresh *= 2.0f; // make it a little less likely that a random hard cut follows soon.
+ //m_nNumericInputDigits = 0;
+ //m_nNumericInputNum = 0;
+ return 0;
+
+ case 'T':
+ if (bCtrlHeldDown)
+ {
+ // stop display of custom message or song title.
+ m_supertext.fStartTime = -1.0f;
+ return 0;
+ }
+ break;
+ case 'K':
+ if (bCtrlHeldDown) // kill all sprites
+ {
+ for (int x=0; x<NUM_TEX; x++)
+ if (m_texmgr.m_tex[x].pSurface)
+ m_texmgr.KillTex(x);
+ return 0;
+ }
+ break;
+ /*case keyMappings[2]: // 'Y'
+ if (bCtrlHeldDown) // stop display of custom message or song title.
+ {
+ m_supertext.fStartTime = -1.0f;
+ return 0;
+ }
+ break;*/
+ }
+ if (wParam == keyMappings[2]) // 'Y'
+ {
+ if (bCtrlHeldDown) // stop display of custom message or song title.
+ {
+ m_supertext.fStartTime = -1.0f;
+ return 0;
+ }
+ }
+ return 1; // end case WM_KEYDOWN
+
+ case WM_KEYUP:
+ return 1;
+ break;
+
+ default:
+ return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+ break;
+ }
+
+ return 0;
+};
+
+//----------------------------------------------------------------------
+
+int CPlugin::HandleRegularKey(WPARAM wParam)
+{
+ // here we handle all the normal keys for milkdrop-
+ // these are the hotkeys that are used when you're not
+ // in the middle of editing a string, navigating a menu, etc.
+
+ // do not make references to virtual keys here; only
+ // straight WM_CHAR messages should be sent in.
+
+ // return 0 if you process/absorb the key; otherwise return 1.
+
+ if (m_UI_mode == UI_LOAD && ((wParam >= 'A' && wParam <= 'Z') || (wParam >= 'a' && wParam <= 'z')))
+ {
+ SeekToPreset((char)wParam);
+ return 0; // we processed (or absorbed) the key
+ }
+ else if (m_UI_mode == UI_MASHUP && wParam >= '1' && wParam <= ('0' + MASH_SLOTS))
+ {
+ m_nMashSlot = wParam - '1';
+ }
+ else switch(wParam)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ int digit = wParam - '0';
+ m_nNumericInputNum = (m_nNumericInputNum*10) + digit;
+ m_nNumericInputDigits++;
+
+ if (m_nNumericInputDigits >= 2)
+ {
+ if (m_nNumericInputMode == NUMERIC_INPUT_MODE_CUST_MSG)
+ LaunchCustomMessage(m_nNumericInputNum);
+ else if (m_nNumericInputMode == NUMERIC_INPUT_MODE_SPRITE)
+ LaunchSprite(m_nNumericInputNum, -1);
+ else if (m_nNumericInputMode == NUMERIC_INPUT_MODE_SPRITE_KILL)
+ {
+ for (int x=0; x<NUM_TEX; x++)
+ if (m_texmgr.m_tex[x].nUserData == m_nNumericInputNum)
+ m_texmgr.KillTex(x);
+ }
+
+ m_nNumericInputDigits = 0;
+ m_nNumericInputNum = 0;
+ }
+ }
+ return 0; // we processed (or absorbed) the key
+
+ // row 1 keys
+ case 'q':
+ m_pState->m_fVideoEchoZoom /= 1.05f;
+ return 0; // we processed (or absorbed) the key
+ case 'Q':
+ m_pState->m_fVideoEchoZoom *= 1.05f;
+ return 0; // we processed (or absorbed) the key
+ case 'w':
+ m_pState->m_nWaveMode++;
+ if (m_pState->m_nWaveMode >= NUM_WAVES) m_pState->m_nWaveMode = 0;
+ return 0; // we processed (or absorbed) the key
+ case 'W':
+ m_pState->m_nWaveMode--;
+ if (m_pState->m_nWaveMode < 0) m_pState->m_nWaveMode = NUM_WAVES - 1;
+ return 0; // we processed (or absorbed) the key
+ case 'e':
+ m_pState->m_fWaveAlpha -= 0.1f;
+ if (m_pState->m_fWaveAlpha.eval(-1) < 0.0f) m_pState->m_fWaveAlpha = 0.0f;
+ return 0; // we processed (or absorbed) the key
+ case 'E':
+ m_pState->m_fWaveAlpha += 0.1f;
+ //if (m_pState->m_fWaveAlpha.eval(-1) > 1.0f) m_pState->m_fWaveAlpha = 1.0f;
+ return 0; // we processed (or absorbed) the key
+
+ case 'I': m_pState->m_fZoom -= 0.01f; return 0; // we processed (or absorbed) the key
+ case 'i': m_pState->m_fZoom += 0.01f; return 0; // we processed (or absorbed) the key
+
+ case 'n':
+ case 'N':
+ m_bShowDebugInfo = !m_bShowDebugInfo;
+ return 0; // we processed (or absorbed) the key
+
+ case 'r':
+ m_bSequentialPresetOrder = !m_bSequentialPresetOrder;
+ {
+ wchar_t buf[1024], tmp[64];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_PRESET_ORDER_IS_NOW_X),
+ WASABI_API_LNGSTRINGW_BUF((m_bSequentialPresetOrder) ? IDS_SEQUENTIAL : IDS_RANDOM, tmp, 64));
+ AddError(buf, 3.0f, ERR_NOTIFY, false);
+ }
+
+ // erase all history, too:
+ m_presetHistory[0] = m_szCurrentPresetFile;
+ m_presetHistoryPos = 0;
+ m_presetHistoryFwdFence = 1;
+ m_presetHistoryBackFence = 0;
+
+ return 0; // we processed (or absorbed) the key
+
+
+ case 'u':
+ case 'U':
+ if (SendMessage(GetWinampWindow(),WM_USER,0,250))
+ AddError(WASABI_API_LNGSTRINGW(IDS_SHUFFLE_IS_NOW_OFF), 3.0f, ERR_NOTIFY, false);
+ else
+ AddError(WASABI_API_LNGSTRINGW(IDS_SHUFFLE_IS_NOW_ON), 3.0f, ERR_NOTIFY, false);
+
+ //m_fShowUserMessageUntilThisTime = GetTime() + 4.0f;
+
+ // toggle shuffle
+ PostMessage(GetWinampWindow(),WM_COMMAND,40023,0);
+
+ return 0; // we processed (or absorbed) the key
+
+
+ /*
+ case 'u': m_pState->m_fWarpScale /= 1.1f; break;
+ case 'U': m_pState->m_fWarpScale *= 1.1f; break;
+ case 'i': m_pState->m_fWarpAnimSpeed /= 1.1f; break;
+ case 'I': m_pState->m_fWarpAnimSpeed *= 1.1f; break;
+ */
+ case 't':
+ case 'T':
+ LaunchSongTitleAnim();
+ return 0; // we processed (or absorbed) the key
+ case 'o': m_pState->m_fWarpAmount /= 1.1f; return 0; // we processed (or absorbed) the key
+ case 'O': m_pState->m_fWarpAmount *= 1.1f; return 0; // we processed (or absorbed) the key
+
+ case '!':
+ // randomize warp shader
+ {
+ bool bWarpLock = m_bWarpShaderLock;
+ wchar_t szOldPreset[MAX_PATH];
+ lstrcpyW(szOldPreset, m_szCurrentPresetFile);
+ m_bWarpShaderLock = false;
+ LoadRandomPreset(0.0f);
+ m_bWarpShaderLock = true;
+ LoadPreset(szOldPreset, 0.0f);
+ m_bWarpShaderLock = bWarpLock;
+ }
+ break;
+ case '@':
+ // randomize comp shader
+ {
+ bool bCompLock = m_bCompShaderLock;
+ wchar_t szOldPreset[MAX_PATH];
+ lstrcpyW(szOldPreset, m_szCurrentPresetFile);
+ m_bCompShaderLock = false;
+ LoadRandomPreset(0.0f);
+ m_bCompShaderLock = true;
+ LoadPreset(szOldPreset, 0.0f);
+ m_bCompShaderLock = bCompLock;
+ }
+ break;
+
+ case 'a':
+ case 'A':
+ // load a random preset, a random warp shader, and a random comp shader.
+ // not quite as extreme as a mash-up.
+ {
+ bool bCompLock = m_bCompShaderLock;
+ bool bWarpLock = m_bWarpShaderLock;
+ m_bCompShaderLock = false; m_bWarpShaderLock = false;
+ LoadRandomPreset(0.0f);
+ m_bCompShaderLock = true; m_bWarpShaderLock = false;
+ LoadRandomPreset(0.0f);
+ m_bCompShaderLock = false; m_bWarpShaderLock = true;
+ LoadRandomPreset(0.0f);
+ m_bCompShaderLock = bCompLock;
+ m_bWarpShaderLock = bWarpLock;
+ }
+ break;
+ case 'd':
+ case 'D':
+ if (!m_bCompShaderLock && !m_bWarpShaderLock) {
+ m_bCompShaderLock = true; m_bWarpShaderLock = false;
+ AddError(WASABI_API_LNGSTRINGW(IDS_COMPSHADER_LOCKED), 3.0f, ERR_NOTIFY, false);
+ } else if (m_bCompShaderLock && !m_bWarpShaderLock) {
+ m_bCompShaderLock = false; m_bWarpShaderLock = true;
+ AddError(WASABI_API_LNGSTRINGW(IDS_WARPSHADER_LOCKED), 3.0f, ERR_NOTIFY, false);
+ } else if (!m_bCompShaderLock && m_bWarpShaderLock) {
+ m_bCompShaderLock = true; m_bWarpShaderLock = true;
+ AddError(WASABI_API_LNGSTRINGW(IDS_ALLSHADERS_LOCKED), 3.0f, ERR_NOTIFY, false);
+ } else {
+ m_bCompShaderLock = false; m_bWarpShaderLock = false;
+ AddError(WASABI_API_LNGSTRINGW(IDS_ALLSHADERS_UNLOCKED), 3.0f, ERR_NOTIFY, false);
+ }
+ break;
+
+ // row 2 keys
+ // 'A' KEY IS FREE!!
+ // 'D' KEY IS FREE!!
+ /*case 'a':
+ m_pState->m_fVideoEchoAlpha -= 0.1f;
+ if (m_pState->m_fVideoEchoAlpha.eval(-1) < 0) m_pState->m_fVideoEchoAlpha = 0;
+ return 0; // we processed (or absorbed) the key
+ case 'A':
+ m_pState->m_fVideoEchoAlpha += 0.1f;
+ if (m_pState->m_fVideoEchoAlpha.eval(-1) > 1.0f) m_pState->m_fVideoEchoAlpha = 1.0f;
+ return 0; // we processed (or absorbed) the key
+ case 'd':
+ m_pState->m_fDecay += 0.01f;
+ if (m_pState->m_fDecay.eval(-1) > 1.0f) m_pState->m_fDecay = 1.0f;
+ return 0; // we processed (or absorbed) the key
+ case 'D':
+ m_pState->m_fDecay -= 0.01f;
+ if (m_pState->m_fDecay.eval(-1) < 0.9f) m_pState->m_fDecay = 0.9f;
+ return 0; // we processed (or absorbed) the key*/
+ case 'h':
+ case 'H':
+ // instant hard cut
+ if (m_UI_mode == UI_MASHUP)
+ {
+ if (wParam=='h')
+ {
+ m_nMashPreset[m_nMashSlot] = m_nDirs + (warand() % (m_nPresets-m_nDirs));
+ m_nLastMashChangeFrame[m_nMashSlot] = GetFrame() + MASH_APPLY_DELAY_FRAMES; // causes instant apply
+ }
+ else
+ {
+ for (int mash=0; mash<MASH_SLOTS; mash++)
+ {
+ m_nMashPreset[mash] = m_nDirs + (warand() % (m_nPresets-m_nDirs));
+ m_nLastMashChangeFrame[mash] = GetFrame() + MASH_APPLY_DELAY_FRAMES; // causes instant apply
+ }
+ }
+ }
+ else
+ {
+ NextPreset(0);
+ m_fHardCutThresh *= 2.0f; // make it a little less likely that a random hard cut follows soon.
+ }
+ return 0; // we processed (or absorbed) the key
+ case 'f':
+ case 'F':
+ m_pState->m_nVideoEchoOrientation = (m_pState->m_nVideoEchoOrientation + 1) % 4;
+ return 0; // we processed (or absorbed) the key
+ case 'g':
+ m_pState->m_fGammaAdj -= 0.1f;
+ if (m_pState->m_fGammaAdj.eval(-1) < 0.0f) m_pState->m_fGammaAdj = 0.0f;
+ return 0; // we processed (or absorbed) the key
+ case 'G':
+ m_pState->m_fGammaAdj += 0.1f;
+ //if (m_pState->m_fGammaAdj > 1.0f) m_pState->m_fGammaAdj = 1.0f;
+ return 0; // we processed (or absorbed) the key
+ case 'j':
+ m_pState->m_fWaveScale *= 0.9f;
+ return 0; // we processed (or absorbed) the key
+ case 'J':
+ m_pState->m_fWaveScale /= 0.9f;
+ return 0; // we processed (or absorbed) the key
+ case 'k':
+ case 'K':
+ {
+ USHORT mask = 1 << (sizeof(SHORT)*8 - 1); // we want the highest-order bit
+ bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+
+ if (bShiftHeldDown)
+ m_nNumericInputMode = NUMERIC_INPUT_MODE_SPRITE_KILL;
+ else
+ m_nNumericInputMode = NUMERIC_INPUT_MODE_SPRITE;
+ m_nNumericInputNum = 0;
+ m_nNumericInputDigits = 0;
+ }
+ return 0; // we processed (or absorbed) the key
+
+ // row 3/misc. keys
+
+ case '[':
+ m_pState->m_fXPush -= 0.005f;
+ return 0; // we processed (or absorbed) the key
+ case ']':
+ m_pState->m_fXPush += 0.005f;
+ return 0; // we processed (or absorbed) the key
+ case '{':
+ m_pState->m_fYPush -= 0.005f;
+ return 0; // we processed (or absorbed) the key
+ case '}':
+ m_pState->m_fYPush += 0.005f;
+ return 0; // we processed (or absorbed) the key
+ case '<':
+ m_pState->m_fRot += 0.02f;
+ return 0; // we processed (or absorbed) the key
+ case '>':
+ m_pState->m_fRot -= 0.02f;
+ return 0; // we processed (or absorbed) the key
+
+ case 's': // SAVE PRESET
+ case 'S':
+ if (m_UI_mode == UI_REGULAR)
+ {
+ //m_bPresetLockedByCode = true;
+ m_UI_mode = UI_SAVEAS;
+
+ // enter WaitString mode
+ m_waitstring.bActive = true;
+ m_waitstring.bFilterBadChars = true;
+ m_waitstring.bDisplayAsCode = false;
+ m_waitstring.nSelAnchorPos = -1;
+ m_waitstring.nMaxLen = min(sizeof(m_waitstring.szText)-1, MAX_PATH - lstrlenW(GetPresetDir()) - 6); // 6 for the extension + null char. We set this because win32 LoadFile, MoveFile, etc. barf if the path+filename+ext are > MAX_PATH chars.
+ lstrcpyW(m_waitstring.szText, m_pState->m_szDesc); // initial string is the filename, minus the extension
+ WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_AS,m_waitstring.szPrompt,512);
+ m_waitstring.szToolTip[0] = 0;
+ m_waitstring.nCursorPos = lstrlenW(m_waitstring.szText); // set the starting edit position
+ return 0;
+ }
+ break;
+
+ case 'l': // LOAD PRESET
+ case 'L':
+ if (m_UI_mode == UI_LOAD)
+ {
+ m_UI_mode = UI_REGULAR;
+ return 0; // we processed (or absorbed) the key
+
+ }
+ else if (
+ m_UI_mode == UI_REGULAR ||
+ m_UI_mode == UI_MENU)
+ {
+ UpdatePresetList(); // make sure list is completely ready
+ m_UI_mode = UI_LOAD;
+ m_bUserPagedUp = false;
+ m_bUserPagedDown = false;
+ return 0; // we processed (or absorbed) the key
+
+ }
+ break;
+
+ case 'm':
+ case 'M':
+
+ if (m_UI_mode == UI_MENU)
+ m_UI_mode = UI_REGULAR;
+ else if (m_UI_mode == UI_REGULAR || m_UI_mode == UI_LOAD)
+ m_UI_mode = UI_MENU;
+
+ return 0; // we processed (or absorbed) the key
+
+ case '-':
+ SetCurrentPresetRating(m_pState->m_fRating - 1.0f);
+ return 0; // we processed (or absorbed) the key
+ case '+':
+ SetCurrentPresetRating(m_pState->m_fRating + 1.0f);
+ return 0; // we processed (or absorbed) the key
+
+ case '*':
+ m_nNumericInputDigits = 0;
+ m_nNumericInputNum = 0;
+ return 0;
+
+ }
+
+ if (wParam == keyMappings[3] || wParam == keyMappings[4]) // 'y' or 'Y'
+ {
+ m_nNumericInputMode = NUMERIC_INPUT_MODE_CUST_MSG;
+ m_nNumericInputNum = 0;
+ m_nNumericInputDigits = 0;
+ return 0; // we processed (or absorbed) the key
+ }
+
+ return 1;
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::RefreshTab2(HWND hwnd)
+{
+ ShowWindow(GetDlgItem(hwnd, IDC_BRIGHT_SLIDER), !m_bAutoGamma);
+ ShowWindow(GetDlgItem(hwnd, IDC_T1), !m_bAutoGamma);
+ ShowWindow(GetDlgItem(hwnd, IDC_T2), !m_bAutoGamma);
+ ShowWindow(GetDlgItem(hwnd, IDC_T3), !m_bAutoGamma);
+ ShowWindow(GetDlgItem(hwnd, IDC_T4), !m_bAutoGamma);
+ ShowWindow(GetDlgItem(hwnd, IDC_T5), !m_bAutoGamma);
+}
+
+int CALLBACK MyEnumFontsProc(
+ CONST LOGFONT *lplf, // logical-font data
+ CONST TEXTMETRIC *lptm, // physical-font data
+ DWORD dwType, // font type
+ LPARAM lpData // application-defined data
+)
+{
+ SendMessage( GetDlgItem( (HWND)lpData, IDC_FONT3), CB_ADDSTRING, 0, (LPARAM)(lplf->lfFaceName));
+ return 1;
+}
+
+/*
+void DoColors(HWND hwnd, int *r, int *g, int *b)
+{
+ static COLORREF acrCustClr[16];
+
+ CHOOSECOLOR cc;
+ ZeroMemory(&cc, sizeof(CHOOSECOLOR));
+ cc.lStructSize = sizeof(CHOOSECOLOR);
+ cc.hwndOwner = hwnd;//NULL;//hSaverMainWindow;
+ cc.Flags = CC_RGBINIT | CC_FULLOPEN;
+ cc.rgbResult = RGB(*r,*g,*b);
+ cc.lpCustColors = (LPDWORD)acrCustClr;
+ if (ChooseColor(&cc))
+ {
+ *r = GetRValue(cc.rgbResult);
+ *g = GetGValue(cc.rgbResult);
+ *b = GetBValue(cc.rgbResult);
+ }
+}*/
+
+wchar_t* FormImageCacheSizeString(wchar_t* itemStr, UINT sizeID)
+{
+ static wchar_t cacheBuf[128] = {0};
+ StringCchPrintfW(cacheBuf, 128, L"%s %s", itemStr, WASABI_API_LNGSTRINGW(sizeID));
+ return cacheBuf;
+}
+
+//----------------------------------------------------------------------
+
+BOOL CPlugin::MyConfigTabProc(int nPage, HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ // This is the only function you need to worry about for programming
+ // tabs 2 through 8 on the config panel. (Tab 1 contains settings
+ // that are common to all plugins, and the code is located in pluginshell.cpp).
+ // By default, only tab 2 is enabled; to enable tabes 3+, see
+ // 'Enabling Additional Tabs (pages) on the Config Panel' in DOCUMENTATION.TXT.
+ // You should always return 0 for this function.
+ // Note that you don't generally have to use critical sections or semaphores
+ // here; Winamp controls the plugin's message queue, and only gives it message
+ // in between frames.
+ //
+ // Incoming parameters:
+ // 'nPage' indicates which tab (aka 'property page') is currently showing: 2 through 5.
+ // 'hwnd' is the window handle of the property page (which is a dialog of its own,
+ // embedded in the config dialog).
+ // 'msg' is the windows message being sent. The main ones are:
+ //
+ // 1) WM_INITDIALOG: This means the page is being initialized, because the
+ // user clicked on it. When you get this message, you should initialize
+ // all the controls on the page, and set them to reflect the settings
+ // that are stored in member variables.
+ //
+ // 2) WM_DESTROY: This is sent when a tab disappears, either because another
+ // tab is about to be displayed, or because the user clicked OK or Cancel.
+ // In any case, you should read the current settings of all the controls
+ // on the page, and store them in member variables. (If the user clicked
+ // CANCEL, these values will not get saved to disk, but for simplicity,
+ // we always poll the controls here.)
+ //
+ // 3) WM_HELP: This is sent when the user clicks the '?' icon (in the
+ // titlebar of the config panel) and then clicks on a control. When you
+ // get this message, you should display a MessageBox telling the user
+ // a little bit about that control/setting.
+ //
+ // 4) WM_COMMAND: Advanced. This notifies you when the user clicks on a
+ // control. Use this if you need to do certain things when the user
+ // changes a setting. (For example, one control might only be enabled
+ // when a certain checkbox is enabled; you would use EnableWindow() for
+ // this.)
+ //
+ // For complete details on adding your own controls to one of the pages, please see
+ // 'Adding Controls to the Config Panel' in DOCUMENTATION.TXT.
+
+ int t;
+ float val;
+
+ if (nPage == 2)
+ {
+ switch(msg)
+ {
+ case WM_INITDIALOG: // initialize controls here
+ {
+ char buf[2048];
+ int nPos, i;
+ HWND ctrl;
+
+ //-------------- pixel shaders combo box ---------------------
+ ctrl = GetDlgItem( hwnd, IDC_SHADERS );
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_PS_AUTO_RECOMMENDED), -1);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_PS_DISABLED), MD2_PS_NONE);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_PS_SHADER_MODEL_2), MD2_PS_2_0);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_PS_SHADER_MODEL_3), MD2_PS_3_0);
+ SelectItemByPos(ctrl, 0); //as a safe default
+ SelectItemByValue(ctrl, m_nMaxPSVersion_ConfigPanel);
+
+ //-------------- texture format combo box ---------------------
+ ctrl = GetDlgItem( hwnd, IDC_TEXFORMAT );
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_TX_8_BITS_PER_CHANNEL), 8);
+ //AddItem(ctrl, " 10 bits per channel", 10);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_TX_16_BITS_PER_CHANNEL), 16);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_TX_32_BITS_PER_CHANNEL), 32);
+ SelectItemByPos(ctrl, 0); //as a safe default
+ SelectItemByValue(ctrl, m_nTexBitsPerCh);
+
+ //-------------- mesh size combo box ---------------------
+ ctrl = GetDlgItem( hwnd, IDC_MESHSIZECOMBO );
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_8X6_FAST), 8);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_16X12_FAST), 16);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_24X18), 24);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_32X24), 32);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_40X30), 40);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_48X36_DEFAULT), 48);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_64X48_SLOW), 64);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_80X60_SLOW), 80);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_96X72_SLOW), 96);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_128X96_SLOW), 128);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_160X120_SLOW), 160);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_192X144_SLOW), 192);
+ SelectItemByPos(ctrl, 0); //as a safe default
+ SelectItemByValue(ctrl, m_nGridX);
+
+ //-------------- canvas stretch combo box ---------------------
+ ctrl = GetDlgItem( hwnd, IDC_STRETCH );
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_AUTO), 0);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_NONE_BEST_IMAGE_QUALITY), 100);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_1_25_X), 125);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_1_33_X), 133);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_1_5_X), 150);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_1_67_X), 167);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_2_X), 200);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_3_X), 300);
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_4_X), 400);
+ SelectItemByPos(ctrl, 0); //as a safe default
+ SelectItemByValue(ctrl, m_nCanvasStretch);
+
+ //-------------- texture size combo box ---------------------
+ for (i=0; i<5; i++)
+ {
+ int size = (int)pow(2., i+8);
+ sprintf(buf, " %4d x %4d ", size, size);
+ nPos = SendMessage( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_ADDSTRING, 0, (LPARAM)buf);
+ SendMessage( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_SETITEMDATA, nPos, size);
+ }
+
+ // throw the "Auto" option in there
+ nPos = SendMessageW( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_NEAREST_POWER_OF_2));
+ SendMessage( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_SETITEMDATA, nPos, -2);
+ nPos = SendMessageW( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW(IDS_EXACT_RECOMMENDED));
+ SendMessage( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_SETITEMDATA, nPos, -1);
+
+ for (i=0; i<5+2; i++)
+ {
+ int size = SendMessage( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_GETITEMDATA, i, 0);
+ if (size == m_nTexSizeX)
+ {
+ SendMessage( GetDlgItem( hwnd, IDC_TEXSIZECOMBO ), CB_SETCURSEL, i, 0);
+ }
+ }
+
+ //---------16-bit brightness slider--------------
+
+ SendMessage( GetDlgItem( hwnd, IDC_BRIGHT_SLIDER), TBM_SETRANGEMIN,
+ FALSE, (LPARAM)(0) );
+ SendMessage( GetDlgItem( hwnd, IDC_BRIGHT_SLIDER), TBM_SETRANGEMAX,
+ FALSE, (LPARAM)(4) );
+ SendMessage( GetDlgItem( hwnd, IDC_BRIGHT_SLIDER), TBM_SETPOS,
+ TRUE, (LPARAM)(m_n16BitGamma) );
+ for (i=0; i<5; i++)
+ SendMessage( GetDlgItem( hwnd, IDC_BRIGHT_SLIDER), TBM_SETTIC, 0, i);
+
+ // append debug output filename to the checkbox's text
+ GetWindowText( GetDlgItem(hwnd, IDC_CB_DEBUGOUTPUT), buf, 256);
+ lstrcat(buf, DEBUGFILE);
+ SetWindowText( GetDlgItem(hwnd, IDC_CB_DEBUGOUTPUT), buf);
+
+ // set checkboxes
+ CheckDlgButton(hwnd, IDC_CB_DEBUGOUTPUT, g_bDebugOutput);
+ //CheckDlgButton(hwnd, IDC_CB_PRESSF1, (!m_bShowPressF1ForHelp));
+ //CheckDlgButton(hwnd, IDC_CB_TOOLTIPS, m_bShowMenuToolTips);
+ //CheckDlgButton(hwnd, IDC_CB_ALWAYS3D, m_bAlways3D);
+ //CheckDlgButton(hwnd, IDC_CB_FIXSLOWTEXT, m_bFixSlowText);
+ //CheckDlgButton(hwnd, IDC_CB_TOP, m_bAlwaysOnTop);
+ //CheckDlgButton(hwnd, IDC_CB_CLS, !m_bClearScreenAtStartup);
+ //CheckDlgButton(hwnd, IDC_CB_NOWARN, m_bWarningsDisabled);
+ CheckDlgButton(hwnd, IDC_CB_NOWARN2, m_bWarningsDisabled2);
+ //CheckDlgButton(hwnd, IDC_CB_ANISO, m_bAnisotropicFiltering);
+ CheckDlgButton(hwnd, IDC_CB_SCROLLON, m_bPresetLockOnAtStartup);
+ CheckDlgButton(hwnd, IDC_CB_SCROLLON2, m_bPreventScollLockHandling);
+ //CheckDlgButton(hwnd, IDC_CB_PINKFIX, m_bFixPinkBug);
+ CheckDlgButton(hwnd, IDC_CB_NORATING, !m_bEnableRating);
+ CheckDlgButton(hwnd, IDC_CB_AUTOGAMMA, m_bAutoGamma);
+
+ RefreshTab2(hwnd);
+ }
+ break; // case WM_INITDIALOG
+
+ case WM_COMMAND:
+ {
+ int id = LOWORD(wParam);
+ //g_ignore_tab2_clicks = 1;
+ switch (id)
+ {
+ case IDC_CB_NORATING:
+ m_bEnableRating = !DlgItemIsChecked(hwnd, IDC_CB_NORATING);
+ RefreshTab2(hwnd);
+ break;
+
+ case IDC_CB_AUTOGAMMA:
+ m_bAutoGamma = DlgItemIsChecked(hwnd, IDC_CB_AUTOGAMMA);
+ RefreshTab2(hwnd);
+ break;
+
+ }
+ //g_ignore_tab2_clicks = 0;
+ } // end WM_COMMAND case
+ break;
+
+ case WM_DESTROY: // read controls here
+ {
+ ReadCBValue(hwnd, IDC_SHADERS , &m_nMaxPSVersion_ConfigPanel );
+ ReadCBValue(hwnd, IDC_TEXFORMAT , &m_nTexBitsPerCh );
+ ReadCBValue(hwnd, IDC_TEXSIZECOMBO , &m_nTexSizeX );
+ ReadCBValue(hwnd, IDC_MESHSIZECOMBO, &m_nGridX );
+ ReadCBValue(hwnd, IDC_STRETCH , &m_nCanvasStretch);
+
+ // 16-bit-brightness slider - this one doesn't use item values... just item pos.
+ t = SendMessage( GetDlgItem( hwnd, IDC_BRIGHT_SLIDER ), TBM_GETPOS, 0, 0);
+ if (t != CB_ERR) m_n16BitGamma = t;
+
+ // checkboxes
+ g_bDebugOutput = DlgItemIsChecked(hwnd, IDC_CB_DEBUGOUTPUT);
+ //m_bShowPressF1ForHelp = (!DlgItemIsChecked(hwnd, IDC_CB_PRESSF1));
+ //m_bShowMenuToolTips = DlgItemIsChecked(hwnd, IDC_CB_TOOLTIPS);
+ //m_bClearScreenAtStartup = !DlgItemIsChecked(hwnd, IDC_CB_CLS);
+ //m_bAlways3D = DlgItemIsChecked(hwnd, IDC_CB_ALWAYS3D);
+ //m_bFixSlowText = DlgItemIsChecked(hwnd, IDC_CB_FIXSLOWTEXT);
+ //m_bAlwaysOnTop = DlgItemIsChecked(hwnd, IDC_CB_TOP);
+ //m_bWarningsDisabled = DlgItemIsChecked(hwnd, IDC_CB_NOWARN);
+ m_bWarningsDisabled2 = DlgItemIsChecked(hwnd, IDC_CB_NOWARN2);
+ //m_bAnisotropicFiltering = DlgItemIsChecked(hwnd, IDC_CB_ANISO);
+ m_bPresetLockOnAtStartup = DlgItemIsChecked(hwnd, IDC_CB_SCROLLON);
+ m_bPreventScollLockHandling = DlgItemIsChecked(hwnd, IDC_CB_SCROLLON2);
+
+ //m_bFixPinkBug = DlgItemIsChecked(hwnd, IDC_CB_PINKFIX);
+ m_bEnableRating = !DlgItemIsChecked(hwnd, IDC_CB_NORATING);
+ m_bAutoGamma = DlgItemIsChecked(hwnd, IDC_CB_AUTOGAMMA);
+
+ }
+ break; // case WM_DESTROY
+
+ case WM_HELP: // give help box for controls here
+ if (lParam)
+ {
+ HELPINFO *ph = (HELPINFO*)lParam;
+ wchar_t title[1024], buf[2048], ctrl_name[1024];
+ GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
+ RemoveSingleAmpersands(ctrl_name);
+ buf[0] = 0;
+
+ StringCbCopyW(title, sizeof(title), ctrl_name);
+
+ switch(ph->iCtrlId)
+ {
+ case IDC_SHADERS:
+ case IDC_SHADERS_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_PIXEL_SHADERS, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_PIXEL_SHADERS_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_TEXFORMAT:
+ case IDC_TEXFORMAT_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_TEXFORMAT, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_TEXFORMAT_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_TEXSIZECOMBO:
+ case IDC_TEXSIZECOMBO_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CANVAS_SIZE, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_CANVAS_SIZE_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_STRETCH:
+ case IDC_STRETCH_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CANVAS_STRETCH, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_CANVAS_STRETCH_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_MESHSIZECOMBO:
+ case IDC_MESHSIZECOMBO_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_MESH_SIZE, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_MESH_SIZE_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_CB_ALWAYS3D:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_ALWAYS3D, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_CB_NORATING:
+ WASABI_API_LNGSTRINGW_BUF(IDS_DISABLE_PRESET_RATING, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_DISABLE_PRESET_RATING_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_CB_NOWARN2:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_NOWARN2, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_CB_SCROLLON:
+ WASABI_API_LNGSTRINGW_BUF(IDS_START_WITH_PRESET_LOCK_ON, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_START_WITH_PRESET_LOCK_ON_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_BRIGHT_SLIDER:
+ case IDC_BRIGHT_SLIDER_BOX:
+ case IDC_T1:
+ case IDC_T2:
+ case IDC_T3:
+ case IDC_T4:
+ case IDC_T5:
+ case IDC_CB_AUTOGAMMA:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_BRIGHT_SLIDER_BOX), title, sizeof(title)/sizeof(*title));
+ RemoveSingleAmpersands(title);
+ WASABI_API_LNGSTRINGW_BUF((ph->iCtrlId==IDC_CB_AUTOGAMMA?IDS_CB_AUTOGAMMA:IDS_BRIGHT_SLIDER), buf, sizeof(buf)/sizeof(*buf));
+ break;
+ }
+
+ if (buf[0])
+ MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ break; // case WM_HELP
+ }
+ }
+ else if (nPage==3)
+ {
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ char buf[2048];
+ HWND ctrl;
+
+ //-------------- image cache max. bytes combo box ---------------------
+ ctrl = GetDlgItem( hwnd, IDC_MAX_BYTES );
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_AUTO), -1);
+ AddItem(ctrl, FormImageCacheSizeString(L" 0", IDS_MB), 0);
+ AddItem(ctrl, FormImageCacheSizeString(L" 1", IDS_MB), 1000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 2", IDS_MB), 2000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 3", IDS_MB), 3000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 4", IDS_MB), 4000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 6", IDS_MB), 6000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 9", IDS_MB), 8000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 10", IDS_MB), 10000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 12", IDS_MB), 12000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 14", IDS_MB), 14000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 16", IDS_MB), 16000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 20", IDS_MB), 20000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 24", IDS_MB), 24000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 28", IDS_MB), 28000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 32", IDS_MB), 32000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 40", IDS_MB), 40000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 48", IDS_MB), 48000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 56", IDS_MB), 56000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 64", IDS_MB), 64000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 80", IDS_MB), 80000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 96", IDS_MB), 96000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 128", IDS_MB), 128000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 160", IDS_MB), 160000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 192", IDS_MB), 192000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 224", IDS_MB), 224000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 256", IDS_MB), 256000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 384", IDS_MB), 384000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 512", IDS_MB), 512000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 768", IDS_MB), 768000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 1", IDS_GB), 1000000000);
+ AddItem(ctrl, FormImageCacheSizeString(L"1.25", IDS_GB), 1250000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 1.5", IDS_GB), 1500000000);
+ AddItem(ctrl, FormImageCacheSizeString(L"1.75", IDS_GB), 1750000000);
+ AddItem(ctrl, FormImageCacheSizeString(L" 2", IDS_GB), 2000000000);
+ SelectItemByPos (ctrl, 0); //as a safe default
+ SelectItemByValue(ctrl, m_nMaxBytes);
+
+ //-------------- image cache max. # images combo box ---------------------
+ ctrl = GetDlgItem( hwnd, IDC_MAX_IMAGES );
+ AddItem(ctrl, WASABI_API_LNGSTRINGW(IDS_AUTO), -1);
+ AddItem(ctrl, L" 0 ", 0);
+ AddItem(ctrl, L" 1 ", 1);
+ AddItem(ctrl, L" 2 ", 2);
+ AddItem(ctrl, L" 3 ", 3);
+ AddItem(ctrl, L" 4 ", 4);
+ AddItem(ctrl, L" 6 ", 6);
+ AddItem(ctrl, L" 8 ", 8);
+ AddItem(ctrl, L" 10 ", 10);
+ AddItem(ctrl, L" 12 ", 12);
+ AddItem(ctrl, L" 14 ", 14);
+ AddItem(ctrl, L" 16 ", 16);
+ AddItem(ctrl, L" 20 ", 20);
+ AddItem(ctrl, L" 24 ", 24);
+ AddItem(ctrl, L" 28 ", 28);
+ AddItem(ctrl, L" 32 ", 32);
+ AddItem(ctrl, L" 40 ", 40);
+ AddItem(ctrl, L" 48 ", 48);
+ AddItem(ctrl, L" 56 ", 56);
+ AddItem(ctrl, L" 64 ", 64);
+ AddItem(ctrl, L" 80 ", 80);
+ AddItem(ctrl, L" 96 ", 96);
+ AddItem(ctrl, L" 128 ",128);
+ AddItem(ctrl, L" 160 ",160);
+ AddItem(ctrl, L" 192 ",192);
+ AddItem(ctrl, L" 224 ",224);
+ AddItem(ctrl, L" 256 ",256);
+ AddItem(ctrl, L" 384 ",384);
+ AddItem(ctrl, L" 512 ",512);
+ AddItem(ctrl, L" 768 ",768);
+ AddItem(ctrl, L" 1024 ",1024);
+ AddItem(ctrl, L" 1536 ",1536);
+ AddItem(ctrl, L" 2048 ",2048);
+ SelectItemByPos (ctrl, 0); //as a safe default
+ SelectItemByValue(ctrl, m_nMaxImages);
+
+ //sprintf(buf, " %3.2f", m_fStereoSep);
+ //SetWindowText( GetDlgItem( hwnd, IDC_3DSEP ), buf );
+
+ sprintf(buf, " %2.1f", m_fSongTitleAnimDuration);
+ SetWindowText(GetDlgItem( hwnd, IDC_SONGTITLEANIM_DURATION), buf);
+ sprintf(buf, " %2.1f", m_fTimeBetweenRandomSongTitles);
+ SetWindowText(GetDlgItem(hwnd, IDC_RAND_TITLE), buf);
+ sprintf(buf, " %2.1f", m_fTimeBetweenRandomCustomMsgs);
+ SetWindowText(GetDlgItem(hwnd, IDC_RAND_MSG), buf);
+
+ CheckDlgButton(hwnd, IDC_CB_TITLE_ANIMS, m_bSongTitleAnims);
+ }
+ break;
+ case WM_COMMAND:
+ {
+ int id = LOWORD(wParam);
+ //g_ignore_tab2_clicks = 1;
+ switch (id)
+ {
+ case ID_SPRITE:
+ {
+ wchar_t szPath[512], szFile[512];
+ lstrcpyW(szPath, GetConfigIniFile());
+ wchar_t *p = wcsrchr(szPath, L'\\');
+ if (p != NULL)
+ {
+ *(p+1) = 0;
+ lstrcpyW(szFile, szPath);
+ lstrcatW(szFile, IMG_INIFILE);
+ intptr_t ret = (intptr_t)ShellExecuteW(NULL, L"open", szFile, NULL, szPath, SW_SHOWNORMAL);
+ if (ret <= 32)
+ {
+ wchar_t* str = WASABI_API_LNGSTRINGW(IDS_ERROR_IN_SHELLEXECUTE);
+ MessageBoxW(hwnd, str, str, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ }
+ }
+ break;
+
+ case ID_MSG:
+ {
+ wchar_t szPath[512], szFile[512];
+ lstrcpyW(szPath, GetConfigIniFile());
+ wchar_t *p = wcsrchr(szPath, L'\\');
+ if (p != NULL)
+ {
+ *(p+1) = 0;
+ lstrcpyW(szFile, szPath);
+ lstrcatW(szFile, MSG_INIFILE);
+ intptr_t ret = (intptr_t)ShellExecuteW(NULL, L"open", szFile, NULL, szPath, SW_SHOWNORMAL);
+ if (ret <= 32)
+ {
+ wchar_t* str = WASABI_API_LNGSTRINGW(IDS_ERROR_IN_SHELLEXECUTE);
+ MessageBoxW(hwnd, str, str, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ }
+ }
+ break;
+ }
+ }
+ /*if (LOWORD(wParam)==IDLEFT)
+ DoColors(hwnd, &m_cLeftEye3DColor[0], &m_cLeftEye3DColor[1], &m_cLeftEye3DColor[2]);
+ if (LOWORD(wParam)==IDRIGHT)
+ DoColors(hwnd, &m_cRightEye3DColor[0], &m_cRightEye3DColor[1], &m_cRightEye3DColor[2]);
+ */
+ break;
+ case WM_DESTROY:
+ {
+ ReadCBValue(hwnd, IDC_MAX_BYTES , &m_nMaxBytes );
+ ReadCBValue(hwnd, IDC_MAX_IMAGES , &m_nMaxImages );
+
+ char buf[2048];
+
+ GetWindowText( GetDlgItem( hwnd, IDC_SONGTITLEANIM_DURATION ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fSongTitleAnimDuration = val;
+ GetWindowText( GetDlgItem( hwnd, IDC_RAND_TITLE ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fTimeBetweenRandomSongTitles = val;
+ GetWindowText( GetDlgItem( hwnd, IDC_RAND_MSG ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fTimeBetweenRandomCustomMsgs = val;
+
+ m_bSongTitleAnims = DlgItemIsChecked(hwnd, IDC_CB_TITLE_ANIMS);
+ }
+ break;
+ case WM_HELP: // give help box for controls here
+ if (lParam)
+ {
+ HELPINFO *ph = (HELPINFO*)lParam;
+ wchar_t title[1024], buf[2048], ctrl_name[1024];
+ GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
+ RemoveSingleAmpersands(ctrl_name);
+ buf[0] = 0;
+
+ StringCbCopyW(title, sizeof(title), ctrl_name);
+
+ switch(ph->iCtrlId)
+ {
+ case IDC_MAX_IMAGES:
+ case IDC_MAX_IMAGES_CAPTION:
+ case IDC_MAX_BYTES:
+ case IDC_MAX_BYTES_CAPTION:
+ WASABI_API_LNGSTRINGW_BUF(IDS_MAX_IMAGES_BYTES, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_MAX_IMAGES_BYTES_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case ID_SPRITE:
+ WASABI_API_LNGSTRINGW_BUF(IDS_SPRITE, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case ID_MSG:
+ WASABI_API_LNGSTRINGW_BUF(IDS_MSG, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_SONGTITLEANIM_DURATION:
+ case IDC_SONGTITLEANIM_DURATION_LABEL:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_SONGTITLEANIM_DURATION_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_SONGTITLEANIM_DURATION_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_RAND_TITLE:
+ case IDC_RAND_TITLE_LABEL:
+ WASABI_API_LNGSTRINGW_BUF(IDS_RAND_TITLE, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_RAND_TITLE_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_RAND_MSG:
+ case IDC_RAND_MSG_LABEL:
+ WASABI_API_LNGSTRINGW_BUF(IDS_RAND_MSG, title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_RAND_MSG_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_CB_TITLE_ANIMS:
+ WASABI_API_LNGSTRINGW_BUF(IDS_TITLE_ANIMS_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+ }
+
+ if (buf[0])
+ MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ break; // case WM_HELP
+ }
+ }
+ else if (nPage==4)
+ {
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ char buf[2048];
+
+ // soft cuts
+ sprintf(buf, " %2.1f", m_fTimeBetweenPresets);
+ SetWindowText( GetDlgItem( hwnd, IDC_BETWEEN_TIME ), buf );
+ sprintf(buf, " %2.1f", m_fTimeBetweenPresetsRand);
+ SetWindowText( GetDlgItem( hwnd, IDC_BETWEEN_TIME_RANDOM ), buf );
+ sprintf(buf, " %2.1f", m_fBlendTimeUser);
+ SetWindowText( GetDlgItem( hwnd, IDC_BLEND_USER ), buf );
+ sprintf(buf, " %2.1f", m_fBlendTimeAuto);
+ SetWindowText( GetDlgItem( hwnd, IDC_BLEND_AUTO ), buf );
+
+ // hard cuts
+ sprintf(buf, " %2.1f", m_fHardCutHalflife);
+ SetWindowText( GetDlgItem( hwnd, IDC_HARDCUT_BETWEEN_TIME ), buf );
+
+ int n = (int)((m_fHardCutLoudnessThresh - 1.25f) * 10.0f);
+ if (n<0) n = 0;
+ if (n>20) n = 20;
+ SendMessage( GetDlgItem( hwnd, IDC_HARDCUT_LOUDNESS), TBM_SETRANGEMIN, FALSE, (LPARAM)(0) );
+ SendMessage( GetDlgItem( hwnd, IDC_HARDCUT_LOUDNESS), TBM_SETRANGEMAX, FALSE, (LPARAM)(20) );
+ SendMessage( GetDlgItem( hwnd, IDC_HARDCUT_LOUDNESS), TBM_SETPOS, TRUE, (LPARAM)(n) );
+
+ CheckDlgButton(hwnd, IDC_CB_HARDCUTS, m_bHardCutsDisabled);
+ }
+ break;
+ case WM_DESTROY:
+ {
+ char buf[2048];
+
+ // soft cuts
+ GetWindowText( GetDlgItem( hwnd, IDC_BETWEEN_TIME ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fTimeBetweenPresets = val;
+ GetWindowText( GetDlgItem( hwnd, IDC_BETWEEN_TIME_RANDOM ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fTimeBetweenPresetsRand = val;
+ GetWindowText( GetDlgItem( hwnd, IDC_BLEND_AUTO ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fBlendTimeAuto = val;
+ GetWindowText( GetDlgItem( hwnd, IDC_BLEND_USER ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fBlendTimeUser = val;
+
+ // hard cuts
+ GetWindowText( GetDlgItem( hwnd, IDC_HARDCUT_BETWEEN_TIME ), buf, sizeof(buf));
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &val) == 1)
+ m_fHardCutHalflife = val;
+
+ t = SendMessage( GetDlgItem( hwnd, IDC_HARDCUT_LOUDNESS ), TBM_GETPOS, 0, 0);
+ if (t != CB_ERR) m_fHardCutLoudnessThresh = 1.25f + t/10.0f;
+
+ m_bHardCutsDisabled = DlgItemIsChecked(hwnd, IDC_CB_HARDCUTS);
+ }
+ break;
+ case WM_HELP:
+ if (lParam)
+ {
+ HELPINFO *ph = (HELPINFO*)lParam;
+ wchar_t title[1024], buf[2048], ctrl_name[1024];
+ GetWindowTextW(GetDlgItem(hwnd, ph->iCtrlId), ctrl_name, sizeof(ctrl_name)/sizeof(*ctrl_name));
+ RemoveSingleAmpersands(ctrl_name);
+ buf[0] = 0;
+
+ StringCbCopyW(title, sizeof(title), ctrl_name);
+
+ switch(ph->iCtrlId)
+ {
+ case IDC_BETWEEN_TIME:
+ case IDC_BETWEEN_TIME_LABEL:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_BETWEEN_TIME_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_BETWEEN_TIME_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_BETWEEN_TIME_RANDOM:
+ case IDC_BETWEEN_TIME_RANDOM_LABEL:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_BETWEEN_TIME_RANDOM_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_BETWEEN_TIME_RANDOM_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_BLEND_AUTO:
+ case IDC_BLEND_AUTO_LABEL:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_BLEND_AUTO_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_BLEND_AUTO_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_BLEND_USER:
+ case IDC_BLEND_USER_LABEL:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_BLEND_USER_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_BLEND_USER_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_HARDCUT_BETWEEN_TIME:
+ case IDC_HARDCUT_BETWEEN_TIME_LABEL:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_HARDCUT_BETWEEN_TIME_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_HARDCUT_BETWEEN_TIME_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_HARDCUT_LOUDNESS:
+ case IDC_HARDCUT_LOUDNESS_LABEL:
+ case IDC_HARDCUT_LOUDNESS_MIN:
+ case IDC_HARDCUT_LOUDNESS_MAX:
+ GetWindowTextW(GetDlgItem(hwnd, IDC_HARDCUT_LOUDNESS_LABEL), title, sizeof(title)/sizeof(*title));
+ WASABI_API_LNGSTRINGW_BUF(IDS_HARDCUT_LOUDNESS_TEXT, buf, sizeof(buf)/sizeof(*buf));
+ break;
+
+ case IDC_CB_HARDCUTS:
+ WASABI_API_LNGSTRINGW_BUF(IDS_CB_HARDCUTS, buf, sizeof(buf)/sizeof(*buf));
+ break;
+ }
+
+ if (buf[0])
+ MessageBoxW(hwnd, buf, title, MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::Randomize()
+{
+ srand((int)(GetTime()*100));
+ //m_fAnimTime = (warand() % 51234L)*0.01f;
+ m_fRandStart[0] = (warand() % 64841L)*0.01f;
+ m_fRandStart[1] = (warand() % 53751L)*0.01f;
+ m_fRandStart[2] = (warand() % 42661L)*0.01f;
+ m_fRandStart[3] = (warand() % 31571L)*0.01f;
+
+ //CState temp;
+ //temp.Randomize(warand() % NUM_MODES);
+ //m_pState->StartBlend(&temp, m_fAnimTime, m_fBlendTimeUser);
+}
+
+//----------------------------------------------------------------------
+
+void CPlugin::SetMenusForPresetVersion(int WarpPSVersion, int CompPSVersion)
+{
+ int MaxPSVersion = max(WarpPSVersion, CompPSVersion);
+
+ m_menuPreset.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_WARP_SHADER), WarpPSVersion > 0);
+ m_menuPreset.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_COMPOSITE_SHADER), CompPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_SUSTAIN_LEVEL), WarpPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_TEXTURE_WRAP), WarpPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_GAMMA_ADJUSTMENT), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_HUE_SHADER), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_VIDEO_ECHO_ALPHA), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_VIDEO_ECHO_ZOOM), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_VIDEO_ECHO_ORIENTATION), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_FILTER_INVERT), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_FILTER_BRIGHTEN), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_FILTER_DARKEN), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_FILTER_SOLARIZE), CompPSVersion==0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT), MaxPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR1_MIN_COLOR_VALUE), MaxPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR1_MAX_COLOR_VALUE), MaxPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR2_MIN_COLOR_VALUE), MaxPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR2_MAX_COLOR_VALUE), MaxPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR3_MIN_COLOR_VALUE), MaxPSVersion > 0);
+ m_menuPost.EnableItem(WASABI_API_LNGSTRINGW(IDS_MENU_BLUR3_MAX_COLOR_VALUE), MaxPSVersion > 0);
+}
+
+void CPlugin::BuildMenus()
+{
+ wchar_t buf[1024];
+
+ m_pCurMenu = &m_menuPreset;//&m_menuMain;
+
+ m_menuPreset .Init(WASABI_API_LNGSTRINGW(IDS_EDIT_CURRENT_PRESET));
+ m_menuMotion .Init(WASABI_API_LNGSTRINGW(IDS_MOTION));
+ m_menuCustomShape.Init(WASABI_API_LNGSTRINGW(IDS_DRAWING_CUSTOM_SHAPES));
+ m_menuCustomWave .Init(WASABI_API_LNGSTRINGW(IDS_DRAWING_CUSTOM_WAVES));
+ m_menuWave .Init(WASABI_API_LNGSTRINGW(IDS_DRAWING_SIMPLE_WAVEFORM));
+ m_menuAugment .Init(WASABI_API_LNGSTRINGW(IDS_DRAWING_BORDERS_MOTION_VECTORS));
+ m_menuPost .Init(WASABI_API_LNGSTRINGW(IDS_POST_PROCESSING_MISC));
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_CUSTOM_WAVE_X), i+1);
+ m_menuWavecode[i].Init(buf);
+ }
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_CUSTOM_SHAPE_X), i+1);
+ m_menuShapecode[i].Init(buf);
+ }
+
+ //-------------------------------------------
+
+ // MAIN MENU / menu hierarchy
+
+ m_menuPreset.AddChildMenu(&m_menuMotion);
+ m_menuPreset.AddChildMenu(&m_menuCustomShape);
+ m_menuPreset.AddChildMenu(&m_menuCustomWave);
+ m_menuPreset.AddChildMenu(&m_menuWave);
+ m_menuPreset.AddChildMenu(&m_menuAugment);
+ m_menuPreset.AddChildMenu(&m_menuPost);
+
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ m_menuCustomShape.AddChildMenu(&m_menuShapecode[i]);
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ m_menuCustomWave.AddChildMenu(&m_menuWavecode[i]);
+
+ // NOTE: all of the eval menuitems use a CALLBACK function to register the user's changes (see last param)
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_PRESET_INIT_CODE),
+ &m_pState->m_szPerFrameInit, MENUITEMTYPE_STRING,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_PRESET_INIT_CODE_TT, buf, 1024),
+ 256, 0, &OnUserEditedPresetInit, sizeof(m_pState->m_szPerFrameInit), 0);
+
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_PER_FRAME_EQUATIONS),
+ &m_pState->m_szPerFrameExpr, MENUITEMTYPE_STRING,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_PER_FRAME_EQUATIONS_TT, buf, 1024),
+ 256, 0, &OnUserEditedPerFrame, sizeof(m_pState->m_szPerFrameExpr), 0);
+
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_PER_VERTEX_EQUATIONS),
+ &m_pState->m_szPerPixelExpr, MENUITEMTYPE_STRING,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_PER_VERTEX_EQUATIONS_TT, buf, 1024),
+ 256, 0, &OnUserEditedPerPixel, sizeof(m_pState->m_szPerPixelExpr), 0);
+
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_WARP_SHADER),
+ &m_pState->m_szWarpShadersText, MENUITEMTYPE_STRING,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_WARP_SHADER_TT, buf, 1024),
+ 256, 0, &OnUserEditedWarpShaders, sizeof(m_pState->m_szWarpShadersText), 0);
+
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_COMPOSITE_SHADER),
+ &m_pState->m_szCompShadersText, MENUITEMTYPE_STRING,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_COMPOSITE_SHADER_TT, buf, 1024),
+ 256, 0, &OnUserEditedCompShaders, sizeof(m_pState->m_szCompShadersText), 0);
+
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_UPGRADE_PRESET_PS_VERSION),
+ (void*)UI_UPGRADE_PIXEL_SHADER, MENUITEMTYPE_UIMODE,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_UPGRADE_PRESET_PS_VERSION_TT, buf, 1024),
+ 0, 0, NULL, UI_UPGRADE_PIXEL_SHADER, 0);
+
+ m_menuPreset.AddItem(WASABI_API_LNGSTRINGW(IDS_MENU_EDIT_DO_A_PRESET_MASH_UP),
+ (void*)UI_MASHUP, MENUITEMTYPE_UIMODE,
+ WASABI_API_LNGSTRINGW_BUF(IDS_MENU_EDIT_DO_A_PRESET_MASH_UP_TT, buf, 1024),
+ 0, 0, NULL, UI_MASHUP, 0);
+
+ //-------------------------------------------
+
+ // menu items
+ #define MEN_T(id) WASABI_API_LNGSTRINGW(id)
+ #define MEN_TT(id) WASABI_API_LNGSTRINGW_BUF(id, buf, 1024)
+
+ m_menuWave.AddItem(MEN_T(IDS_MENU_WAVE_TYPE), &m_pState->m_nWaveMode, MENUITEMTYPE_INT, MEN_TT(IDS_MENU_WAVE_TYPE_TT), 0, NUM_WAVES-1);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_SIZE), &m_pState->m_fWaveScale, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_SIZE_TT));
+ m_menuWave.AddItem(MEN_T(IDS_MENU_SMOOTH), &m_pState->m_fWaveSmoothing,MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_SMOOTH_TT), 0.0f, 0.9f);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_MYSTERY_PARAMETER), &m_pState->m_fWaveParam, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_MYSTERY_PARAMETER_TT), -1.0f, 1.0f);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_POSITION_X), &m_pState->m_fWaveX, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_POSITION_X_TT), 0, 1);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_POSITION_Y), &m_pState->m_fWaveY, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_POSITION_Y_TT), 0, 1);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_COLOR_RED), &m_pState->m_fWaveR, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_RED_TT), 0, 1);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_COLOR_GREEN), &m_pState->m_fWaveG, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_GREEN_TT), 0, 1);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_COLOR_BLUE), &m_pState->m_fWaveB, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_BLUE_TT), 0, 1);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_OPACITY), &m_pState->m_fWaveAlpha, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_OPACITY_TT), 0.001f, 100.0f);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_USE_DOTS), &m_pState->m_bWaveDots, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_USE_DOTS_TT));
+ m_menuWave.AddItem(MEN_T(IDS_MENU_DRAW_THICK), &m_pState->m_bWaveThick, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_DRAW_THICK_TT));
+ m_menuWave.AddItem(MEN_T(IDS_MENU_MODULATE_OPACITY_BY_VOLUME), &m_pState->m_bModWaveAlphaByVolume, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_MODULATE_OPACITY_BY_VOLUME_TT));
+ m_menuWave.AddItem(MEN_T(IDS_MENU_MODULATION_TRANSPARENT_VOLUME), &m_pState->m_fModWaveAlphaStart, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_MODULATION_TRANSPARENT_VOLUME_TT), 0.0f, 2.0f);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_MODULATION_OPAQUE_VOLUME), &m_pState->m_fModWaveAlphaEnd, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_MODULATION_OPAQUE_VOLUME_TT), 0.0f, 2.0f);
+ m_menuWave.AddItem(MEN_T(IDS_MENU_ADDITIVE_DRAWING), &m_pState->m_bAdditiveWaves, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_ADDITIVE_DRAWING_TT));
+ m_menuWave.AddItem(MEN_T(IDS_MENU_COLOR_BRIGHTENING), &m_pState->m_bMaximizeWaveColor, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_COLOR_BRIGHTENING_TT));
+
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_OUTER_BORDER_THICKNESS), &m_pState->m_fOuterBorderSize, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_OUTER_BORDER_THICKNESS_TT), 0, 0.5f);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_RED_OUTER), &m_pState->m_fOuterBorderR, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_RED_OUTER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_GREEN_OUTER), &m_pState->m_fOuterBorderG, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_GREEN_OUTER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_BLUE_OUTER), &m_pState->m_fOuterBorderB, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_BLUE_OUTER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_OPACITY_OUTER), &m_pState->m_fOuterBorderA, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_OPACITY_OUTER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_INNER_BORDER_THICKNESS), &m_pState->m_fInnerBorderSize, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_INNER_BORDER_THICKNESS_TT), 0, 0.5f);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_RED_OUTER), &m_pState->m_fInnerBorderR, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_RED_INNER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_GREEN_OUTER), &m_pState->m_fInnerBorderG, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_GREEN_INNER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_BLUE_OUTER), &m_pState->m_fInnerBorderB, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_BLUE_INNER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_OPACITY_OUTER), &m_pState->m_fInnerBorderA, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_OPACITY_INNER_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_MOTION_VECTOR_OPACITY), &m_pState->m_fMvA, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_MOTION_VECTOR_OPACITY_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_NUM_MOT_VECTORS_X), &m_pState->m_fMvX, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_NUM_MOT_VECTORS_X_TT), 0, 64);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_NUM_MOT_VECTORS_Y), &m_pState->m_fMvY, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_NUM_MOT_VECTORS_Y_TT), 0, 48);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_OFFSET_X), &m_pState->m_fMvDX, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_OFFSET_X_TT), -1, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_OFFSET_Y), &m_pState->m_fMvDY, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_OFFSET_Y_TT), -1, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_TRAIL_LENGTH), &m_pState->m_fMvL, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_TRAIL_LENGTH_TT), 0, 5);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_RED_OUTER), &m_pState->m_fMvR, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_RED_MOTION_VECTOR_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_GREEN_OUTER), &m_pState->m_fMvG, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_GREEN_MOTION_VECTOR_TT), 0, 1);
+ m_menuAugment.AddItem(MEN_T(IDS_MENU_COLOR_BLUE_OUTER), &m_pState->m_fMvB, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_COLOR_BLUE_MOTION_VECTOR_TT), 0, 1);
+
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_ZOOM_AMOUNT), &m_pState->m_fZoom, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_ZOOM_AMOUNT_TT));
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_ZOOM_EXPONENT), &m_pState->m_fZoomExponent, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_ZOOM_EXPONENT_TT));
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_WARP_AMOUNT), &m_pState->m_fWarpAmount, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_WARP_AMOUNT_TT));
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_WARP_SCALE), &m_pState->m_fWarpScale, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_WARP_SCALE_TT));
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_WARP_SPEED), &m_pState->m_fWarpAnimSpeed, MENUITEMTYPE_LOGFLOAT, MEN_TT(IDS_MENU_WARP_SPEED_TT));
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_ROTATION_AMOUNT), &m_pState->m_fRot, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_ROTATION_AMOUNT_TT), -1.00f, 1.00f);
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_ROTATION_CENTER_OF_X), &m_pState->m_fRotCX, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_ROTATION_CENTER_OF_X_TT), -1.0f, 2.0f);
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_ROTATION_CENTER_OF_Y), &m_pState->m_fRotCY, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_ROTATION_CENTER_OF_Y_TT), -1.0f, 2.0f);
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_TRANSLATION_X), &m_pState->m_fXPush, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_TRANSLATION_X_TT), -1.0f, 1.0f);
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_TRANSLATION_Y), &m_pState->m_fYPush, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_TRANSLATION_Y_TT), -1.0f, 1.0f);
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_SCALING_X), &m_pState->m_fStretchX, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_SCALING_X_TT));
+ m_menuMotion.AddItem(MEN_T(IDS_MENU_SCALING_Y), &m_pState->m_fStretchY, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_SCALING_Y_TT));
+
+ m_menuPost.AddItem(MEN_T(IDS_MENU_SUSTAIN_LEVEL), &m_pState->m_fDecay, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_SUSTAIN_LEVEL_TT), 0.50f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_DARKEN_CENTER), &m_pState->m_bDarkenCenter, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_DARKEN_CENTER_TT));
+ m_menuPost.AddItem(MEN_T(IDS_MENU_GAMMA_ADJUSTMENT), &m_pState->m_fGammaAdj, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_GAMMA_ADJUSTMENT_TT), 1.0f, 8.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_HUE_SHADER), &m_pState->m_fShader, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_HUE_SHADER_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_VIDEO_ECHO_ALPHA), &m_pState->m_fVideoEchoAlpha, MENUITEMTYPE_BLENDABLE, MEN_TT(IDS_MENU_VIDEO_ECHO_ALPHA_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_VIDEO_ECHO_ZOOM), &m_pState->m_fVideoEchoZoom, MENUITEMTYPE_LOGBLENDABLE, MEN_TT(IDS_MENU_VIDEO_ECHO_ZOOM_TT));
+ m_menuPost.AddItem(MEN_T(IDS_MENU_VIDEO_ECHO_ORIENTATION), &m_pState->m_nVideoEchoOrientation, MENUITEMTYPE_INT, MEN_TT(IDS_MENU_VIDEO_ECHO_ORIENTATION_TT), 0.0f, 3.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_TEXTURE_WRAP), &m_pState->m_bTexWrap, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_TEXTURE_WRAP_TT));
+ //m_menuPost.AddItem("stereo 3D", &m_pState->m_bRedBlueStereo, MENUITEMTYPE_BOOL, "displays the image in stereo 3D; you need 3D glasses (with red and blue lenses) for this.");
+ m_menuPost.AddItem(MEN_T(IDS_MENU_FILTER_INVERT), &m_pState->m_bInvert, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_FILTER_INVERT_TT));
+ m_menuPost.AddItem(MEN_T(IDS_MENU_FILTER_BRIGHTEN), &m_pState->m_bBrighten, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_FILTER_BRIGHTEN_TT));
+ m_menuPost.AddItem(MEN_T(IDS_MENU_FILTER_DARKEN), &m_pState->m_bDarken, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_FILTER_DARKEN_TT));
+ m_menuPost.AddItem(MEN_T(IDS_MENU_FILTER_SOLARIZE), &m_pState->m_bSolarize, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_FILTER_SOLARIZE_TT));
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT),&m_pState->m_fBlur1EdgeDarken, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR1_MIN_COLOR_VALUE), &m_pState->m_fBlur1Min, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR1_MIN_COLOR_VALUE_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR1_MAX_COLOR_VALUE), &m_pState->m_fBlur1Max, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR1_MAX_COLOR_VALUE_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR2_MIN_COLOR_VALUE), &m_pState->m_fBlur2Min, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR2_MIN_COLOR_VALUE_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR2_MAX_COLOR_VALUE), &m_pState->m_fBlur2Max, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR2_MAX_COLOR_VALUE_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR3_MIN_COLOR_VALUE), &m_pState->m_fBlur3Min, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR3_MIN_COLOR_VALUE_TT), 0.0f, 1.0f);
+ m_menuPost.AddItem(MEN_T(IDS_MENU_BLUR3_MAX_COLOR_VALUE), &m_pState->m_fBlur3Max, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BLUR3_MAX_COLOR_VALUE_TT), 0.0f, 1.0f);
+
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ // blending: do both; fade opacities in/out (w/exagerrated weighting)
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_ENABLED), &m_pState->m_wave[i].enabled, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_ENABLED_TT)); // bool
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_NUMBER_OF_SAMPLES),&m_pState->m_wave[i].samples, MENUITEMTYPE_INT, MEN_TT(IDS_MENU_NUMBER_OF_SAMPLES_TT), 2, 512); // 0-512
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_L_R_SEPARATION), &m_pState->m_wave[i].sep, MENUITEMTYPE_INT, MEN_TT(IDS_MENU_L_R_SEPARATION_TT), 0, 256); // 0-512
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_SCALING), &m_pState->m_wave[i].scaling, MENUITEMTYPE_LOGFLOAT, MEN_TT(IDS_MENU_SCALING_TT));
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_SMOOTH), &m_pState->m_wave[i].smoothing, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_SMOOTHING_TT), 0, 1);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_COLOR_RED), &m_pState->m_wave[i].r, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_COLOR_RED_TT), 0, 1);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_COLOR_GREEN), &m_pState->m_wave[i].g, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_COLOR_GREEN_TT), 0, 1);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_COLOR_BLUE), &m_pState->m_wave[i].b, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_COLOR_BLUE_TT), 0, 1);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_OPACITY), &m_pState->m_wave[i].a, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_OPACITY_WAVE_TT), 0, 1);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_USE_SPECTRUM), &m_pState->m_wave[i].bSpectrum, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_USE_SPECTRUM_TT)); // 0-5 [0=wave left, 1=wave center, 2=wave right; 3=spectrum left, 4=spec center, 5=spec right]
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_USE_DOTS), &m_pState->m_wave[i].bUseDots, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_USE_DOTS_WAVE_TT)); // bool
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_DRAW_THICK), &m_pState->m_wave[i].bDrawThick,MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_DRAW_THICK_WAVE_TT)); // bool
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_ADDITIVE_DRAWING), &m_pState->m_wave[i].bAdditive, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_ADDITIVE_DRAWING_WAVE_TT)); // bool
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_EXPORT_TO_FILE), (void*)UI_EXPORT_WAVE, MENUITEMTYPE_UIMODE,MEN_TT(IDS_MENU_EXPORT_TO_FILE_TT), 0, 0, NULL, UI_EXPORT_WAVE, i);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_IMPORT_FROM_FILE), (void*)UI_IMPORT_WAVE, MENUITEMTYPE_UIMODE,MEN_TT(IDS_MENU_IMPORT_FROM_FILE_TT), 0, 0, NULL, UI_IMPORT_WAVE, i);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_EDIT_INIT_CODE), &m_pState->m_wave[i].m_szInit, MENUITEMTYPE_STRING,MEN_TT(IDS_MENU_EDIT_INIT_CODE_TT), 256, 0, &OnUserEditedWavecodeInit, sizeof(m_pState->m_wave[i].m_szInit), 0);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_EDIT_PER_FRAME_CODE), &m_pState->m_wave[i].m_szPerFrame, MENUITEMTYPE_STRING, MEN_TT(IDS_MENU_EDIT_PER_FRAME_CODE_TT), 256, 0, &OnUserEditedWavecode, sizeof(m_pState->m_wave[i].m_szPerFrame), 0);
+ m_menuWavecode[i].AddItem(MEN_T(IDS_MENU_EDIT_PER_POINT_CODE), &m_pState->m_wave[i].m_szPerPoint, MENUITEMTYPE_STRING, MEN_TT(IDS_MENU_EDIT_PER_POINT_CODE_TT), 256, 0, &OnUserEditedWavecode, sizeof(m_pState->m_wave[i].m_szPerPoint), 0);
+ }
+
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ // blending: do both; fade opacities in/out (w/exagerrated weighting)
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_ENABLED), &m_pState->m_shape[i].enabled, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_ENABLED_SHAPE_TT)); // bool
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_NUMBER_OF_INSTANCES), &m_pState->m_shape[i].instances,MENUITEMTYPE_INT, MEN_TT(IDS_MENU_NUMBER_OF_INSTANCES_TT), 1, 1024);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_NUMBER_OF_SIDES), &m_pState->m_shape[i].sides, MENUITEMTYPE_INT, MEN_TT(IDS_MENU_NUMBER_OF_SIDES_TT), 3, 100);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_DRAW_THICK), &m_pState->m_shape[i].thickOutline, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_DRAW_THICK_SHAPE_TT)); // bool
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_ADDITIVE_DRAWING), &m_pState->m_shape[i].additive, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_ADDITIVE_DRAWING_SHAPE_TT)); // bool
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_X_POSITION), &m_pState->m_shape[i].x, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_X_POSITION_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_Y_POSITION), &m_pState->m_shape[i].y, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_Y_POSITION_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_RADIUS), &m_pState->m_shape[i].rad, MENUITEMTYPE_LOGFLOAT, MEN_TT(IDS_MENU_RADIUS_TT));
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_ANGLE), &m_pState->m_shape[i].ang, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_ANGLE_TT), 0, 3.1415927f*2.0f);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_TEXTURED), &m_pState->m_shape[i].textured, MENUITEMTYPE_BOOL, MEN_TT(IDS_MENU_TEXTURED_TT)); // bool
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_TEXTURE_ZOOM), &m_pState->m_shape[i].tex_zoom, MENUITEMTYPE_LOGFLOAT, MEN_TT(IDS_MENU_TEXTURE_ZOOM_TT)); // bool
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_TEXTURE_ANGLE), &m_pState->m_shape[i].tex_ang, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_TEXTURE_ANGLE_TT), 0, 3.1415927f*2.0f); // bool
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_INNER_COLOR_RED), &m_pState->m_shape[i].r, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_INNER_COLOR_RED_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_INNER_COLOR_GREEN), &m_pState->m_shape[i].g, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_INNER_COLOR_GREEN_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_INNER_COLOR_BLUE), &m_pState->m_shape[i].b, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_INNER_COLOR_BLUE_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_INNER_OPACITY), &m_pState->m_shape[i].a, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_INNER_OPACITY_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_OUTER_COLOR_RED), &m_pState->m_shape[i].r2, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_OUTER_COLOR_RED_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_OUTER_COLOR_GREEN), &m_pState->m_shape[i].g2, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_OUTER_COLOR_GREEN_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_OUTER_COLOR_BLUE), &m_pState->m_shape[i].b2, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_OUTER_COLOR_BLUE_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_OUTER_OPACITY), &m_pState->m_shape[i].a2, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_OUTER_OPACITY_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_BORDER_COLOR_RED), &m_pState->m_shape[i].border_r, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BORDER_COLOR_RED_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_BORDER_COLOR_GREEN), &m_pState->m_shape[i].border_g, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BORDER_COLOR_GREEN_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_BORDER_COLOR_BLUE), &m_pState->m_shape[i].border_b, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BORDER_COLOR_BLUE_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_BORDER_OPACITY), &m_pState->m_shape[i].border_a, MENUITEMTYPE_FLOAT, MEN_TT(IDS_MENU_BORDER_OPACITY_TT), 0, 1);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_EXPORT_TO_FILE), NULL, MENUITEMTYPE_UIMODE, MEN_TT(IDS_MENU_EXPORT_TO_FILE_SHAPE_TT), 0, 0, NULL, UI_EXPORT_SHAPE, i);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_IMPORT_FROM_FILE), NULL, MENUITEMTYPE_UIMODE, MEN_TT(IDS_MENU_IMPORT_FROM_FILE_SHAPE_TT), 0, 0, NULL, UI_IMPORT_SHAPE, i);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_EDIT_INIT_CODE), &m_pState->m_shape[i].m_szInit, MENUITEMTYPE_STRING, MEN_TT(IDS_MENU_EDIT_INIT_CODE_SHAPE_TT), 256, 0, &OnUserEditedShapecodeInit, sizeof(m_pState->m_shape[i].m_szInit), 0);
+ m_menuShapecode[i].AddItem(MEN_T(IDS_MENU_EDIT_PER_FRAME_INSTANCE_CODE), &m_pState->m_shape[i].m_szPerFrame, MENUITEMTYPE_STRING, MEN_TT(IDS_MENU_EDIT_PER_FRAME_INSTANCE_CODE_TT), 256, 0, &OnUserEditedShapecode, sizeof(m_pState->m_shape[i].m_szPerFrame), 0);
+ //m_menuShapecode[i].AddItem("[ edit per-point code ]",&m_pState->m_shape[i].m_szPerPoint, MENUITEMTYPE_STRING, "IN: sample [0..1]; value1 [left ch], value2 [right ch], plus all vars for per-frame code / OUT: x,y; r,g,b,a; t1-t8", 256, 0, &OnUserEditedWavecode);
+ }
+}
+
+void CPlugin::WriteRealtimeConfig()
+{
+ WritePrivateProfileIntW(m_bShowFPS, L"bShowFPS",GetConfigIniFile(), L"settings");
+ WritePrivateProfileIntW(m_bShowRating, L"bShowRating",GetConfigIniFile(), L"settings");
+ WritePrivateProfileIntW(m_bShowPresetInfo, L"bShowPresetInfo",GetConfigIniFile(), L"settings");
+ WritePrivateProfileIntW(m_bShowSongTitle, L"bShowSongTitle",GetConfigIniFile(), L"settings");
+ WritePrivateProfileIntW(m_bShowSongTime, L"bShowSongTime",GetConfigIniFile(), L"settings");
+ WritePrivateProfileIntW(m_bShowSongLen, L"bShowSongLen",GetConfigIniFile(), L"settings");
+}
+
+void CPlugin::dumpmsg(wchar_t *s)
+{
+ #if _DEBUG
+ OutputDebugStringW(s);
+ if (s[0])
+ {
+ int len = lstrlenW(s);
+ if (s[len-1] != L'\n')
+ OutputDebugStringW(L"\n");
+ }
+ #endif
+}
+
+void CPlugin::PrevPreset(float fBlendTime)
+{
+ if (m_bSequentialPresetOrder)
+ {
+ m_nCurrentPreset--;
+ if (m_nCurrentPreset < m_nDirs)
+ m_nCurrentPreset = m_nPresets-1;
+ if (m_nCurrentPreset >= m_nPresets) // just in case
+ m_nCurrentPreset = m_nDirs;
+
+ wchar_t szFile[MAX_PATH];
+ lstrcpyW(szFile, m_szPresetDir); // note: m_szPresetDir always ends with '\'
+ lstrcatW(szFile, m_presets[m_nCurrentPreset].szFilename.c_str());
+
+ LoadPreset(szFile, fBlendTime);
+ }
+ else
+ {
+ int prev = (m_presetHistoryPos-1 + PRESET_HIST_LEN) % PRESET_HIST_LEN;
+ if (m_presetHistoryPos != m_presetHistoryBackFence)
+ {
+ m_presetHistoryPos = prev;
+ LoadPreset( m_presetHistory[m_presetHistoryPos].c_str(), fBlendTime);
+ }
+ }
+}
+
+void CPlugin::NextPreset(float fBlendTime) // if not retracing our former steps, it will choose a random one.
+{
+ LoadRandomPreset(fBlendTime);
+}
+
+void CPlugin::LoadRandomPreset(float fBlendTime)
+{
+ // make sure file list is ok
+ if (m_nPresets - m_nDirs == 0)
+ {
+ if (m_nPresets - m_nDirs == 0)
+ {
+ // note: this error message is repeated in milkdropfs.cpp in DrawText()
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ERROR_NO_PRESET_FILE_FOUND_IN_X_MILK), m_szPresetDir);
+ AddError(buf, 6.0f, ERR_MISC, true);
+
+ // also bring up the dir. navigation menu...
+ if (m_UI_mode == UI_REGULAR || m_UI_mode == UI_MENU)
+ {
+ m_UI_mode = UI_LOAD;
+ m_bUserPagedUp = false;
+ m_bUserPagedDown = false;
+ }
+ return;
+ }
+ }
+
+ bool bHistoryEmpty = (m_presetHistoryFwdFence==m_presetHistoryBackFence);
+
+ // if we have history to march back forward through, do that first
+ if (!m_bSequentialPresetOrder)
+ {
+ int next = (m_presetHistoryPos+1) % PRESET_HIST_LEN;
+ if (next != m_presetHistoryFwdFence && !bHistoryEmpty)
+ {
+ m_presetHistoryPos = next;
+ LoadPreset( m_presetHistory[m_presetHistoryPos].c_str(), fBlendTime);
+ return;
+ }
+ }
+
+ // --TEMPORARY--
+ // this comes in handy if you want to mass-modify a batch of presets;
+ // just automatically tweak values in Import, then they immediately get exported to a .MILK in a new dir.
+ /*
+ for (int i=0; i<m_nPresets; i++)
+ {
+ char szPresetFile[512];
+ lstrcpy(szPresetFile, m_szPresetDir); // note: m_szPresetDir always ends with '\'
+ lstrcat(szPresetFile, m_pPresetAddr[i]);
+ //CState newstate;
+ m_state2.Import(szPresetFile, GetTime());
+
+ lstrcpy(szPresetFile, "c:\\t7\\");
+ lstrcat(szPresetFile, m_pPresetAddr[i]);
+ m_state2.Export(szPresetFile);
+ }
+ */
+ // --[END]TEMPORARY--
+
+ if (m_bSequentialPresetOrder)
+ {
+ m_nCurrentPreset++;
+ if (m_nCurrentPreset < m_nDirs || m_nCurrentPreset >= m_nPresets)
+ m_nCurrentPreset = m_nDirs;
+ }
+ else
+ {
+ // pick a random file
+ if (!m_bEnableRating || (m_presets[m_nPresets - 1].fRatingCum < 0.1f))// || (m_nRatingReadProgress < m_nPresets))
+ {
+ m_nCurrentPreset = m_nDirs + (warand() % (m_nPresets - m_nDirs));
+ }
+ else
+ {
+ float cdf_pos = (warand() % 14345)/14345.0f*m_presets[m_nPresets - 1].fRatingCum;
+
+ /*
+ char buf[512];
+ sprintf(buf, "max = %f, rand = %f, \tvalues: ", m_presets[m_nPresets - 1].fRatingCum, cdf_pos);
+ for (int i=m_nDirs; i<m_nPresets; i++)
+ {
+ char buf2[32];
+ sprintf(buf2, "%3.1f ", m_presets[i].fRatingCum);
+ lstrcat(buf, buf2);
+ }
+ dumpmsg(buf);
+ */
+
+ if (cdf_pos < m_presets[m_nDirs].fRatingCum)
+ {
+ m_nCurrentPreset = m_nDirs;
+ }
+ else
+ {
+ int lo = m_nDirs;
+ int hi = m_nPresets;
+ while (lo + 1 < hi)
+ {
+ int mid = (lo+hi)/2;
+ if (m_presets[mid].fRatingCum > cdf_pos)
+ hi = mid;
+ else
+ lo = mid;
+ }
+ m_nCurrentPreset = hi;
+ }
+ }
+ }
+
+ // m_pPresetAddr[m_nCurrentPreset] points to the preset file to load (w/o the path);
+ // first prepend the path, then load section [preset00] within that file
+ wchar_t szFile[MAX_PATH] = {0};
+ lstrcpyW(szFile, m_szPresetDir); // note: m_szPresetDir always ends with '\'
+ lstrcatW(szFile, m_presets[m_nCurrentPreset].szFilename.c_str());
+
+ if (!bHistoryEmpty)
+ m_presetHistoryPos = (m_presetHistoryPos+1) % PRESET_HIST_LEN;
+
+ LoadPreset(szFile, fBlendTime);
+}
+
+void CPlugin::RandomizeBlendPattern()
+{
+ if (!m_vertinfo)
+ return;
+
+ // note: we now avoid constant uniform blend b/c it's half-speed for shader blending.
+ // (both old & new shaders would have to run on every pixel...)
+ int mixtype = 1 + (warand()%3);//warand()%4;
+
+ if (mixtype==0)
+ {
+ // constant, uniform blend
+ int nVert = 0;
+ for (int y=0; y<=m_nGridY; y++)
+ {
+ for (int x=0; x<=m_nGridX; x++)
+ {
+ m_vertinfo[nVert].a = 1;
+ m_vertinfo[nVert].c = 0;
+ nVert++;
+ }
+ }
+ }
+ else if (mixtype==1)
+ {
+ // directional wipe
+ float ang = FRAND*6.28f;
+ float vx = cosf(ang);
+ float vy = sinf(ang);
+ float band = 0.1f + 0.2f*FRAND; // 0.2 is good
+ float inv_band = 1.0f/band;
+
+ int nVert = 0;
+ for (int y=0; y<=m_nGridY; y++)
+ {
+ float fy = (y/(float)m_nGridY)*m_fAspectY;
+ for (int x=0; x<=m_nGridX; x++)
+ {
+ float fx = (x/(float)m_nGridX)*m_fAspectX;
+
+ // at t==0, mix rangse from -10..0
+ // at t==1, mix ranges from 1..11
+
+ float t = (fx-0.5f)*vx + (fy-0.5f)*vy + 0.5f;
+ t = (t-0.5f)/sqrtf(2.0f) + 0.5f;
+
+ m_vertinfo[nVert].a = inv_band * (1 + band);
+ m_vertinfo[nVert].c = -inv_band + inv_band*t;//(x/(float)m_nGridX - 0.5f)/band;
+ nVert++;
+ }
+ }
+ }
+ else if (mixtype==2)
+ {
+ // plasma transition
+ float band = 0.12f + 0.13f*FRAND;//0.02f + 0.18f*FRAND;
+ float inv_band = 1.0f/band;
+
+ // first generate plasma array of height values
+ m_vertinfo[ 0].c = FRAND;
+ m_vertinfo[ m_nGridX].c = FRAND;
+ m_vertinfo[m_nGridY*(m_nGridX+1) ].c = FRAND;
+ m_vertinfo[m_nGridY*(m_nGridX+1) + m_nGridX].c = FRAND;
+ GenPlasma(0, m_nGridX, 0, m_nGridY, 0.25f);
+
+ // then find min,max so we can normalize to [0..1] range and then to the proper 'constant offset' range.
+ float minc = m_vertinfo[0].c;
+ float maxc = m_vertinfo[0].c;
+ int x,y,nVert;
+
+ nVert = 0;
+ for (y=0; y<=m_nGridY; y++)
+ {
+ for (x=0; x<=m_nGridX; x++)
+ {
+ if (minc > m_vertinfo[nVert].c)
+ minc = m_vertinfo[nVert].c;
+ if (maxc < m_vertinfo[nVert].c)
+ maxc = m_vertinfo[nVert].c;
+ nVert++;
+ }
+ }
+
+ float mult = 1.0f/(maxc-minc);
+ nVert = 0;
+ for (y=0; y<=m_nGridY; y++)
+ {
+ for (x=0; x<=m_nGridX; x++)
+ {
+ float t = (m_vertinfo[nVert].c - minc)*mult;
+ m_vertinfo[nVert].a = inv_band * (1 + band);
+ m_vertinfo[nVert].c = -inv_band + inv_band*t;
+ nVert++;
+ }
+ }
+ }
+ else if (mixtype==3)
+ {
+ // radial blend
+ float band = 0.02f + 0.14f*FRAND + 0.34f*FRAND;
+ float inv_band = 1.0f/band;
+ float dir = (float)((warand()%2)*2 - 1); // 1=outside-in, -1=inside-out
+
+ int nVert = 0;
+ for (int y=0; y<=m_nGridY; y++)
+ {
+ float dy = (y/(float)m_nGridY - 0.5f)*m_fAspectY;
+ for (int x=0; x<=m_nGridX; x++)
+ {
+ float dx = (x/(float)m_nGridX - 0.5f)*m_fAspectX;
+ float t = sqrtf(dx*dx + dy*dy)*1.41421f;
+ if (dir==-1)
+ t = 1-t;
+
+ m_vertinfo[nVert].a = inv_band * (1 + band);
+ m_vertinfo[nVert].c = -inv_band + inv_band*t;
+ nVert++;
+ }
+ }
+ }
+}
+
+void CPlugin::GenPlasma(int x0, int x1, int y0, int y1, float dt)
+{
+ int midx = (x0+x1)/2;
+ int midy = (y0+y1)/2;
+ float t00 = m_vertinfo[y0*(m_nGridX+1) + x0].c;
+ float t01 = m_vertinfo[y0*(m_nGridX+1) + x1].c;
+ float t10 = m_vertinfo[y1*(m_nGridX+1) + x0].c;
+ float t11 = m_vertinfo[y1*(m_nGridX+1) + x1].c;
+
+ if (y1-y0 >= 2)
+ {
+ if (x0==0)
+ m_vertinfo[midy*(m_nGridX+1) + x0].c = 0.5f*(t00 + t10) + (FRAND*2-1)*dt*m_fAspectY;
+ m_vertinfo[midy*(m_nGridX+1) + x1].c = 0.5f*(t01 + t11) + (FRAND*2-1)*dt*m_fAspectY;
+ }
+ if (x1-x0 >= 2)
+ {
+ if (y0==0)
+ m_vertinfo[y0*(m_nGridX+1) + midx].c = 0.5f*(t00 + t01) + (FRAND*2-1)*dt*m_fAspectX;
+ m_vertinfo[y1*(m_nGridX+1) + midx].c = 0.5f*(t10 + t11) + (FRAND*2-1)*dt*m_fAspectX;
+ }
+
+ if (y1-y0 >= 2 && x1-x0 >= 2)
+ {
+ // do midpoint & recurse:
+ t00 = m_vertinfo[midy*(m_nGridX+1) + x0].c;
+ t01 = m_vertinfo[midy*(m_nGridX+1) + x1].c;
+ t10 = m_vertinfo[y0*(m_nGridX+1) + midx].c;
+ t11 = m_vertinfo[y1*(m_nGridX+1) + midx].c;
+ m_vertinfo[midy*(m_nGridX+1) + midx].c = 0.25f*(t10 + t11 + t00 + t01) + (FRAND*2-1)*dt;
+
+ GenPlasma(x0, midx, y0, midy, dt*0.5f);
+ GenPlasma(midx, x1, y0, midy, dt*0.5f);
+ GenPlasma(x0, midx, midy, y1, dt*0.5f);
+ GenPlasma(midx, x1, midy, y1, dt*0.5f);
+ }
+}
+
+void CPlugin::LoadPreset(const wchar_t *szPresetFilename, float fBlendTime)
+{
+ // clear old error msg...
+ if (m_nFramesSinceResize > 4)
+ ClearErrors(ERR_PRESET);
+
+ // make sure preset still exists. (might not if they are using the "back"/fwd buttons
+ // in RANDOM preset order and a file was renamed or deleted!)
+ if (GetFileAttributesW(szPresetFilename) == 0xFFFFFFFF)
+ {
+ const wchar_t *p = wcsrchr(szPresetFilename, L'\\');
+ p = (p) ? p+1 : szPresetFilename;
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ERROR_PRESET_NOT_FOUND_X), p);
+ AddError(buf, 6.0f, ERR_PRESET, true);
+ return;
+ }
+
+ if ( !m_bSequentialPresetOrder )
+ {
+ // save preset in the history. keep in mind - maybe we are searching back through it already!
+ if ( m_presetHistoryFwdFence == m_presetHistoryPos )
+ {
+ // we're at the forward frontier; add to history
+ m_presetHistory[m_presetHistoryPos] = szPresetFilename;
+ m_presetHistoryFwdFence = (m_presetHistoryFwdFence+1) % PRESET_HIST_LEN;
+
+ // don't let the two fences touch
+ if (m_presetHistoryBackFence == m_presetHistoryFwdFence)
+ m_presetHistoryBackFence = (m_presetHistoryBackFence+1) % PRESET_HIST_LEN;
+ }
+ else
+ {
+ // we're retracing our steps, either forward or backward...
+
+ }
+ }
+
+ // if no preset was valid before, make sure there is no blend, because there is nothing valid to blend from.
+ if (!wcscmp(m_pState->m_szDesc, INVALID_PRESET_DESC))
+ fBlendTime = 0;
+
+ if (fBlendTime == 0)
+ {
+ // do it all NOW!
+ if (szPresetFilename != m_szCurrentPresetFile) //[sic]
+ lstrcpyW(m_szCurrentPresetFile, szPresetFilename);
+
+ CState *temp = m_pState;
+ m_pState = m_pOldState;
+ m_pOldState = temp;
+
+ DWORD ApplyFlags = STATE_ALL;
+ ApplyFlags ^= (m_bWarpShaderLock ? STATE_WARP : 0);
+ ApplyFlags ^= (m_bCompShaderLock ? STATE_COMP : 0);
+
+ m_pState->Import(m_szCurrentPresetFile, GetTime(), m_pOldState, ApplyFlags);
+
+ if (fBlendTime >= 0.001f)
+ {
+ RandomizeBlendPattern();
+ m_pState->StartBlendFrom(m_pOldState, GetTime(), fBlendTime);
+ }
+
+ m_fPresetStartTime = GetTime();
+ m_fNextPresetTime = -1.0f; // flags UpdateTime() to recompute this
+
+ // release stuff from m_OldShaders, then move m_shaders to m_OldShaders, then load the new shaders.
+ SafeRelease( m_OldShaders.comp.ptr );
+ SafeRelease( m_OldShaders.warp.ptr );
+ SafeRelease( m_OldShaders.comp.CT );
+ SafeRelease( m_OldShaders.warp.CT );
+ m_OldShaders = m_shaders;
+ ZeroMemory(&m_shaders, sizeof(PShaderSet));
+
+ LoadShaders(&m_shaders, m_pState, false);
+
+ OnFinishedLoadingPreset();
+ }
+ else
+ {
+ // set ourselves up to load the preset (and esp. compile shaders) a little bit at a time
+ SafeRelease( m_NewShaders.comp.ptr );
+ SafeRelease( m_NewShaders.warp.ptr );
+ ZeroMemory(&m_NewShaders, sizeof(PShaderSet));
+
+ DWORD ApplyFlags = STATE_ALL;
+ ApplyFlags ^= (m_bWarpShaderLock ? STATE_WARP : 0);
+ ApplyFlags ^= (m_bCompShaderLock ? STATE_COMP : 0);
+
+ m_pNewState->Import(szPresetFilename, GetTime(), m_pOldState, ApplyFlags);
+
+ m_nLoadingPreset = 1; // this will cause LoadPresetTick() to get called over the next few frames...
+
+ m_fLoadingPresetBlendTime = fBlendTime;
+ lstrcpyW(m_szLoadingPreset, szPresetFilename);
+ }
+}
+
+void CPlugin::OnFinishedLoadingPreset()
+{
+ // note: only used this if you loaded the preset *intact* (or mostly intact)
+
+ SetMenusForPresetVersion( m_pState->m_nWarpPSVersion, m_pState->m_nCompPSVersion );
+ m_nPresetsLoadedTotal++; //only increment this on COMPLETION of the load.
+
+ for (int mash=0; mash<MASH_SLOTS; mash++)
+ m_nMashPreset[mash] = m_nCurrentPreset;
+}
+
+void CPlugin::LoadPresetTick()
+{
+ if (m_nLoadingPreset == 2 || m_nLoadingPreset == 5)
+ {
+ // just loads one shader (warp or comp) then returns.
+ LoadShaders(&m_NewShaders, m_pNewState, true);
+ }
+ else if (m_nLoadingPreset == 8)
+ {
+ // finished loading the shaders - apply the preset!
+ lstrcpyW(m_szCurrentPresetFile, m_szLoadingPreset);
+ m_szLoadingPreset[0] = 0;
+
+ CState *temp = m_pState;
+ m_pState = m_pOldState;
+ m_pOldState = temp;
+
+ temp = m_pState;
+ m_pState = m_pNewState;
+ m_pNewState = temp;
+
+ RandomizeBlendPattern();
+
+ //if (fBlendTime >= 0.001f)
+ m_pState->StartBlendFrom(m_pOldState, GetTime(), m_fLoadingPresetBlendTime);
+
+ m_fPresetStartTime = GetTime();
+ m_fNextPresetTime = -1.0f; // flags UpdateTime() to recompute this
+
+ // release stuff from m_OldShaders, then move m_shaders to m_OldShaders, then load the new shaders.
+ SafeRelease( m_OldShaders.comp.ptr );
+ SafeRelease( m_OldShaders.warp.ptr );
+ m_OldShaders = m_shaders;
+ m_shaders = m_NewShaders;
+ ZeroMemory(&m_NewShaders, sizeof(PShaderSet));
+
+ // end slow-preset-load mode
+ m_nLoadingPreset = 0;
+
+ OnFinishedLoadingPreset();
+ }
+
+ if (m_nLoadingPreset > 0)
+ m_nLoadingPreset++;
+}
+
+void CPlugin::SeekToPreset(wchar_t cStartChar)
+{
+ if (cStartChar >= L'a' && cStartChar <= L'z')
+ cStartChar -= L'a' - L'A';
+
+ for (int i = m_nDirs; i < m_nPresets; i++)
+ {
+ wchar_t ch = m_presets[i].szFilename.c_str()[0];
+ if (ch >= L'a' && ch <= L'z')
+ ch -= L'a' - L'A';
+ if (ch == cStartChar)
+ {
+ m_nPresetListCurPos = i;
+ return;
+ }
+ }
+}
+
+void CPlugin::FindValidPresetDir()
+{
+ swprintf(m_szPresetDir, L"%spresets\\", m_szMilkdrop2Path );
+ if (GetFileAttributesW(m_szPresetDir) != -1)
+ return;
+ lstrcpyW(m_szPresetDir, m_szMilkdrop2Path);
+ if (GetFileAttributesW(m_szPresetDir) != -1)
+ return;
+ lstrcpyW(m_szPresetDir, GetPluginsDirPath());
+ if (GetFileAttributesW(m_szPresetDir) != -1)
+ return;
+ lstrcpyW(m_szPresetDir, L"c:\\program files\\winamp\\"); //getting desperate here
+ if (GetFileAttributesW(m_szPresetDir) != -1)
+ return;
+ lstrcpyW(m_szPresetDir, L"c:\\program files\\"); //getting desperate here
+ if (GetFileAttributesW(m_szPresetDir) != -1)
+ return;
+ lstrcpyW(m_szPresetDir, L"c:\\");
+}
+
+char* NextLine(char* p)
+{
+ // p points to the beginning of a line
+ // we'll return a pointer to the first char of the next line
+ // if we hit a NULL char before that, we'll return NULL.
+ if (!p)
+ return NULL;
+
+ char* s = p;
+ while (*s != '\r' && *s != '\n' && *s != 0)
+ s++;
+
+ while (*s == '\r' || *s == '\n')
+ s++;
+
+ if (*s==0)
+ return NULL;
+
+ return s;
+}
+
+static unsigned int WINAPI __UpdatePresetList(void* lpVoid)
+{
+ // NOTE - this is run in a separate thread!!!
+
+ DWORD flags = (DWORD)lpVoid;
+ bool bForce = (flags & 1) ? true : false;
+ bool bTryReselectCurrentPreset = (flags & 2) ? true : false;
+
+ WIN32_FIND_DATAW fd;
+ ZeroMemory(&fd, sizeof(fd));
+ HANDLE h = INVALID_HANDLE_VALUE;
+
+ int nTry = 0;
+ bool bRetrying = false;
+
+ EnterCriticalSection(&g_cs);
+retry:
+
+ // make sure the path exists; if not, go to winamp plugins dir
+ if (GetFileAttributesW(g_plugin.m_szPresetDir) == -1)
+ {
+ //FIXME...
+ g_plugin.FindValidPresetDir();
+ }
+
+ // if Mask (dir) changed, do a full re-scan;
+ // if not, just finish our old scan.
+ wchar_t szMask[MAX_PATH];
+ swprintf(szMask, L"%s*.*", g_plugin.m_szPresetDir); // cuz dirnames could have extensions, etc.
+ if (bForce || !g_plugin.m_szUpdatePresetMask[0] || wcscmp(szMask, g_plugin.m_szUpdatePresetMask))
+ {
+ // if old dir was "" or the dir changed, reset our search
+ if (h != INVALID_HANDLE_VALUE)
+ FindClose(h);
+ h = INVALID_HANDLE_VALUE;
+ g_plugin.m_bPresetListReady = false;
+ lstrcpyW(g_plugin.m_szUpdatePresetMask, szMask);
+ ZeroMemory(&fd, sizeof(fd));
+
+ g_plugin.m_nPresets = 0;
+ g_plugin.m_nDirs = 0;
+ g_plugin.m_presets.clear();
+
+ // find first .MILK file
+ //if( (hFile = _findfirst(szMask, &c_file )) != -1L ) // note: returns filename -without- path
+ if( (h = FindFirstFileW(g_plugin.m_szUpdatePresetMask, &fd )) == INVALID_HANDLE_VALUE ) // note: returns filename -without- path
+ {
+ // --> revert back to plugins dir
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ERROR_NO_PRESET_FILES_OR_DIRS_FOUND_IN_X), g_plugin.m_szPresetDir);
+ g_plugin.AddError(buf, 4.0f, ERR_MISC, true);
+
+ if (bRetrying)
+ {
+ LeaveCriticalSection(&g_cs);
+ g_bThreadAlive = false;
+ _endthreadex(0);
+ return 0;
+ }
+
+ g_plugin.FindValidPresetDir();
+
+ bRetrying = true;
+ goto retry;
+ }
+
+ g_plugin.AddError(WASABI_API_LNGSTRINGW(IDS_SCANNING_PRESETS), 8.0f, ERR_SCANNING_PRESETS, false);
+ }
+
+ if (g_plugin.m_bPresetListReady)
+ {
+ LeaveCriticalSection(&g_cs);
+ g_bThreadAlive = false;
+ _endthreadex(0);
+ return 0;
+ }
+
+ int nMaxPSVersion = g_plugin.m_nMaxPSVersion;
+ wchar_t szPresetDir[MAX_PATH];
+ lstrcpyW(szPresetDir, g_plugin.m_szPresetDir);
+
+ LeaveCriticalSection(&g_cs);
+
+ PresetList temp_presets;
+ int temp_nDirs = 0;
+ int temp_nPresets = 0;
+
+ // scan for the desired # of presets, this call...
+ while (!g_bThreadShouldQuit && h != INVALID_HANDLE_VALUE)
+ {
+ bool bSkip = false;
+ bool bIsDir = (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+ float fRating = 0;
+
+ wchar_t szFilename[512];
+ lstrcpyW(szFilename, fd.cFileName);
+
+ if (bIsDir)
+ {
+ // skip "." directory
+ if (wcscmp(fd.cFileName, L".")==0)// || lstrlen(ffd.cFileName) < 1)
+ bSkip = true;
+ else
+ swprintf(szFilename, L"*%s", fd.cFileName);
+ }
+ else
+ {
+ // skip normal files not ending in ".milk"
+ int len = lstrlenW(fd.cFileName);
+ if (len < 5 || wcsicmp(fd.cFileName + len - 5, L".milk") != 0)
+ bSkip = true;
+
+ // if it is .milk, make sure we know how to run its pixel shaders -
+ // otherwise we don't want to show it in the preset list!
+ if (!bSkip)
+ {
+ // If the first line of the file is not "MILKDROP_PRESET_VERSION XXX",
+ // then it's a MilkDrop 1 era preset, so it is definitely runnable. (no shaders)
+ // Otherwise, check for the value "PSVERSION". It will be 0, 2, or 3.
+ // If missing, assume it is 2.
+ wchar_t szFullPath[MAX_PATH];
+ swprintf(szFullPath, L"%s%s", szPresetDir, fd.cFileName);
+ FILE* f = _wfopen(szFullPath, L"r");
+ if (!f)
+ bSkip = true;
+ else {
+ #define PRESET_HEADER_SCAN_BYTES 160
+ char szLine[PRESET_HEADER_SCAN_BYTES];
+ char *p = szLine;
+
+ int bytes_to_read = sizeof(szLine)-1;
+ int count = fread(szLine, bytes_to_read, 1, f);
+ if (count < 1) {
+ fseek(f, SEEK_SET, 0);
+ count = fread(szLine, 1, bytes_to_read, f);
+ szLine[ count ] = 0;
+ }
+ else
+ szLine[bytes_to_read-1] = 0;
+
+ bool bScanForPreset00AndRating = false;
+ bool bRatingKnown = false;
+
+ // try to read the PSVERSION and the fRating= value.
+ // most presets (unless hand-edited) will have these right at the top.
+ // if not, [at least for fRating] use GetPrivateProfileFloat to search whole file.
+ // read line 1
+ //p = NextLine(p);//fgets(p, sizeof(p)-1, f);
+ if (!strncmp(p, "MILKDROP_PRESET_VERSION", 23))
+ {
+ p = NextLine(p);//fgets(p, sizeof(p)-1, f);
+ int ps_version = 2;
+ if (p && !strncmp(p, "PSVERSION", 9))
+ {
+ sscanf(&p[10], "%d", &ps_version);
+ if (ps_version > nMaxPSVersion)
+ bSkip = true;
+ else
+ {
+ p = NextLine(p);//fgets(p, sizeof(p)-1, f);
+ bScanForPreset00AndRating = true;
+ }
+ }
+ }
+ else
+ {
+ // otherwise it's a MilkDrop 1 preset - we can run it.
+ bScanForPreset00AndRating = true;
+ }
+
+ // scan up to 10 more lines in the file, looking for [preset00] and fRating=...
+ // (this is WAY faster than GetPrivateProfileFloat, when it works!)
+ int reps = (bScanForPreset00AndRating) ? 10 : 0;
+ for (int z=0; z<reps; z++)
+ {
+ if (p && !strncmp(p, "[preset00]", 10))
+ {
+ p = NextLine(p);
+ if (p && !strncmp(p, "fRating=", 8))
+ {
+ _sscanf_l(&p[8], "%f", g_use_C_locale, &fRating);
+ bRatingKnown = true;
+ break;
+ }
+ }
+ p = NextLine(p);
+ }
+
+ fclose(f);
+
+ if (!bRatingKnown)
+ fRating = GetPrivateProfileFloatW(L"preset00", L"fRating", 3.0f, szFullPath);
+ fRating = max(0.0f, min(5.0f, fRating));
+ }
+ }
+ }
+
+ if (!bSkip)
+ {
+ float fPrevPresetRatingCum = 0;
+ if (temp_nPresets > 0)
+ fPrevPresetRatingCum += temp_presets[temp_nPresets-1].fRatingCum;
+
+ PresetInfo x;
+ x.szFilename = szFilename;
+ x.fRatingThis = fRating;
+ x.fRatingCum = fPrevPresetRatingCum + fRating;
+ temp_presets.push_back(x);
+
+ temp_nPresets++;
+ if (bIsDir)
+ temp_nDirs++;
+ }
+
+ if (!FindNextFileW(h, &fd))
+ {
+ FindClose(h);
+ h = INVALID_HANDLE_VALUE;
+
+ break;
+ }
+
+ // every so often, add some presets...
+ #define PRESET_UPDATE_INTERVAL 64
+ if (temp_nPresets == 30 || ((temp_nPresets % PRESET_UPDATE_INTERVAL)==0))
+ {
+ EnterCriticalSection(&g_cs);
+
+ //g_plugin.m_presets = temp_presets;
+ for (int i=g_plugin.m_nPresets; i<temp_nPresets; i++)
+ g_plugin.m_presets.push_back(temp_presets[i]);
+ g_plugin.m_nPresets = temp_nPresets;
+ g_plugin.m_nDirs = temp_nDirs;
+
+ LeaveCriticalSection(&g_cs);
+ }
+ }
+
+ if (g_bThreadShouldQuit)
+ {
+ // just abort... we are exiting the program or restarting the scan.
+ g_bThreadAlive = false;
+ _endthreadex(0);
+ return 0;
+ }
+
+ EnterCriticalSection(&g_cs);
+
+ //g_plugin.m_presets = temp_presets;
+ for (int i=g_plugin.m_nPresets; i<temp_nPresets; i++)
+ g_plugin.m_presets.push_back(temp_presets[i]);
+ g_plugin.m_nPresets = temp_nPresets;
+ g_plugin.m_nDirs = temp_nDirs;
+ g_plugin.m_bPresetListReady = true;
+
+ if (g_plugin.m_bPresetListReady && g_plugin.m_nPresets == 0)
+ {
+ // no presets OR directories found - weird - but it happens.
+ // --> revert back to plugins dir
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ERROR_NO_PRESET_FILES_OR_DIRS_FOUND_IN_X), g_plugin.m_szPresetDir);
+ g_plugin.AddError(buf, 4.0f, ERR_MISC, true);
+
+ if (bRetrying)
+ {
+ LeaveCriticalSection(&g_cs);
+ g_bThreadAlive = false;
+ _endthreadex(0);
+ return 0;
+ }
+
+ g_plugin.FindValidPresetDir();
+
+ bRetrying = true;
+ goto retry;
+ }
+
+ if (g_plugin.m_bPresetListReady)
+ {
+ g_plugin.MergeSortPresets(0, g_plugin.m_nPresets-1);
+
+ // update cumulative ratings, since order changed...
+ g_plugin.m_presets[0].fRatingCum = g_plugin.m_presets[0].fRatingThis;
+ for (int i=0; i<g_plugin.m_nPresets; i++)
+ g_plugin.m_presets[i].fRatingCum = g_plugin.m_presets[i-1].fRatingCum + g_plugin.m_presets[i].fRatingThis;
+
+ // clear the "scanning presets" msg
+ g_plugin.ClearErrors(ERR_SCANNING_PRESETS);
+
+ // finally, try to re-select the most recently-used preset in the list
+ g_plugin.m_nPresetListCurPos = 0;
+ if (bTryReselectCurrentPreset)
+ {
+ if (g_plugin.m_szCurrentPresetFile[0])
+ {
+ // try to automatically seek to the last preset loaded
+ wchar_t *p = wcsrchr(g_plugin.m_szCurrentPresetFile, L'\\');
+ p = (p) ? (p+1) : g_plugin.m_szCurrentPresetFile;
+ for (int i=g_plugin.m_nDirs; i<g_plugin.m_nPresets; i++)
+ {
+ if (wcscmp(p, g_plugin.m_presets[i].szFilename.c_str())==0) {
+ g_plugin.m_nPresetListCurPos = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ LeaveCriticalSection(&g_cs);
+
+ g_bThreadAlive = false;
+ _endthreadex(0);
+ return 0;
+}
+
+void CPlugin::UpdatePresetList(bool bBackground, bool bForce, bool bTryReselectCurrentPreset)
+{
+ // note: if dir changed, make sure bForce is true!
+
+ if (bForce)
+ {
+ if (g_bThreadAlive)
+ CancelThread(3000); // flags it to exit; the param is the # of ms to wait before forcefully killing it
+ }
+ else
+ {
+ if (bBackground && (g_bThreadAlive || m_bPresetListReady))
+ return;
+ if (!bBackground && m_bPresetListReady)
+ return;
+ }
+
+ assert(!g_bThreadAlive);
+
+ // spawn new thread:
+ DWORD flags = (bForce ? 1 : 0) | (bTryReselectCurrentPreset ? 2 : 0);
+ g_bThreadShouldQuit = false;
+ g_bThreadAlive = true;
+ g_hThread = (HANDLE)_beginthreadex(NULL,0,__UpdatePresetList,(void*)flags,0,0);
+
+ if (!bBackground)
+ {
+ // crank up priority, wait for it to finish, and then return
+ SetThreadPriority(g_hThread,THREAD_PRIORITY_HIGHEST); //THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_HIGHEST,
+
+ // wait for it to finish
+ while (g_bThreadAlive)
+ Sleep(30);
+
+ assert(g_hThread != INVALID_HANDLE_VALUE);
+ CloseHandle(g_hThread);
+ g_hThread = INVALID_HANDLE_VALUE;
+ }
+ else
+ {
+ // it will just run in the background til it finishes.
+ // however, we want to wait until at least ~32 presets are found (or failure) before returning,
+ // so we know we have *something* in the preset list to start with.
+
+ SetThreadPriority(g_hThread,THREAD_PRIORITY_HIGHEST); //THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_HIGHEST,
+
+ // wait until either the thread exits, or # of presets is >32, before returning.
+ // also make sure you enter the CS whenever you check on it!
+ // (thread will update preset list every so often, with the newest presets scanned in...)
+ while (g_bThreadAlive)
+ {
+ Sleep(30);
+
+ EnterCriticalSection(&g_cs);
+ int nPresets = g_plugin.m_nPresets;
+ LeaveCriticalSection(&g_cs);
+
+ if (nPresets >= 30)
+ break;
+ }
+
+ if (g_bThreadAlive)
+ {
+ // the load still takes a while even at THREAD_PRIORITY_ABOVE_NORMAL,
+ // because it is waiting on the HDD so much...
+ // but the OS is smart, and the CPU stays nice and zippy in other threads =)
+ SetThreadPriority(g_hThread,THREAD_PRIORITY_ABOVE_NORMAL); //THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_HIGHEST,
+ }
+ }
+
+ return;
+}
+
+void CPlugin::MergeSortPresets(int left, int right)
+{
+ // note: left..right range is inclusive
+ int nItems = right-left+1;
+
+ if (nItems > 2)
+ {
+ // recurse to sort 2 halves (but don't actually recurse on a half if it only has 1 element)
+ int mid = (left+right)/2;
+ /*if (mid != left) */ MergeSortPresets(left, mid);
+ /*if (mid+1 != right)*/ MergeSortPresets(mid+1, right);
+
+ // then merge results
+ int a = left;
+ int b = mid + 1;
+ while (a <= mid && b <= right)
+ {
+ bool bSwap;
+
+ // merge the sorted arrays; give preference to strings that start with a '*' character
+ int nSpecial = 0;
+ if (m_presets[a].szFilename.c_str()[0] == '*') nSpecial++;
+ if (m_presets[b].szFilename.c_str()[0] == '*') nSpecial++;
+
+ if (nSpecial == 1)
+ {
+ bSwap = (m_presets[b].szFilename.c_str()[0] == '*');
+ }
+ else
+ {
+ bSwap = (mystrcmpiW(m_presets[a].szFilename.c_str(), m_presets[b].szFilename.c_str()) > 0);
+ }
+
+ if (bSwap)
+ {
+ PresetInfo temp = m_presets[b];
+ for (int k=b; k>a; k--)
+ m_presets[k] = m_presets[k-1];
+ m_presets[a] = temp;
+ mid++;
+ b++;
+ }
+ a++;
+ }
+ }
+ else if (nItems == 2)
+ {
+ // sort 2 items; give preference to 'special' strings that start with a '*' character
+ int nSpecial = 0;
+ if (m_presets[left].szFilename.c_str()[0] == '*') nSpecial++;
+ if (m_presets[right].szFilename.c_str()[0] == '*') nSpecial++;
+
+ if (nSpecial == 1)
+ {
+ if (m_presets[right].szFilename.c_str()[0] == '*')
+ {
+ PresetInfo temp = m_presets[left];
+ m_presets[left] = m_presets[right];
+ m_presets[right] = temp;
+ }
+ }
+ else if (mystrcmpiW(m_presets[left].szFilename.c_str(), m_presets[right].szFilename.c_str()) > 0)
+ {
+ PresetInfo temp = m_presets[left];
+ m_presets[left] = m_presets[right];
+ m_presets[right] = temp;
+ }
+ }
+}
+
+void CPlugin::WaitString_NukeSelection()
+{
+ if (m_waitstring.bActive &&
+ m_waitstring.nSelAnchorPos != -1)
+ {
+ // nuke selection. note: start & end are INCLUSIVE.
+ int start = (m_waitstring.nCursorPos < m_waitstring.nSelAnchorPos) ? m_waitstring.nCursorPos : m_waitstring.nSelAnchorPos;
+ int end = (m_waitstring.nCursorPos > m_waitstring.nSelAnchorPos) ? m_waitstring.nCursorPos - 1 : m_waitstring.nSelAnchorPos - 1;
+ int len = (m_waitstring.bDisplayAsCode ? lstrlenA((char*)m_waitstring.szText) : lstrlenW(m_waitstring.szText));
+ int how_far_to_shift = end - start + 1;
+ int num_chars_to_shift = len - end; // includes NULL char
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ for (int i=0; i<num_chars_to_shift; i++)
+ *(ptr + start + i) = *(ptr + start + i + how_far_to_shift);
+ }
+ else
+ {
+ for (int i=0; i<num_chars_to_shift; i++)
+ m_waitstring.szText[start + i] = m_waitstring.szText[start + i + how_far_to_shift];
+ }
+
+ // clear selection
+ m_waitstring.nCursorPos = start;
+ m_waitstring.nSelAnchorPos = -1;
+ }
+}
+
+void CPlugin::WaitString_Cut()
+{
+ if (m_waitstring.bActive &&
+ m_waitstring.nSelAnchorPos != -1)
+ {
+ WaitString_Copy();
+ WaitString_NukeSelection();
+ }
+}
+
+void CPlugin::WaitString_Copy()
+{
+ if (m_waitstring.bActive &&
+ m_waitstring.nSelAnchorPos != -1)
+ {
+ // note: start & end are INCLUSIVE.
+ int start = (m_waitstring.nCursorPos < m_waitstring.nSelAnchorPos) ? m_waitstring.nCursorPos : m_waitstring.nSelAnchorPos;
+ int end = (m_waitstring.nCursorPos > m_waitstring.nSelAnchorPos) ? m_waitstring.nCursorPos - 1 : m_waitstring.nSelAnchorPos - 1;
+ int chars_to_copy = end - start + 1;
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ for (int i=0; i<chars_to_copy; i++)
+ m_waitstring.szClipboard[i] = *(ptr + start + i);
+ m_waitstring.szClipboard[chars_to_copy] = 0;
+
+ char tmp[64000];
+ ConvertLFCToCRsA(m_waitstring.szClipboard, tmp);
+ copyStringToClipboardA(tmp);
+ }
+ else
+ {
+ for (int i=0; i<chars_to_copy; i++)
+ m_waitstring.szClipboardW[i] = m_waitstring.szText[start + i];
+ m_waitstring.szClipboardW[chars_to_copy] = 0;
+
+ wchar_t tmp[64000];
+ ConvertLFCToCRsW(m_waitstring.szClipboardW, tmp);
+ copyStringToClipboardW(tmp);
+ }
+ }
+}
+
+void CPlugin::WaitString_Paste()
+{
+ // NOTE: if there is a selection, it is wiped out, and replaced with the clipboard contents.
+
+ if (m_waitstring.bActive)
+ {
+ WaitString_NukeSelection();
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char tmp[64000];
+ lstrcpyA(tmp, getStringFromClipboardA());
+ ConvertCRsToLFCA(tmp, m_waitstring.szClipboard);
+ }
+ else
+ {
+ wchar_t tmp[64000];
+ lstrcpyW(tmp, getStringFromClipboardW());
+ ConvertCRsToLFCW(tmp, m_waitstring.szClipboardW);
+ }
+
+ int len;
+ int chars_to_insert;
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ len = lstrlenA((char*)m_waitstring.szText);
+ chars_to_insert = lstrlenA(m_waitstring.szClipboard);
+ }
+ else
+ {
+ len = lstrlenW(m_waitstring.szText);
+ chars_to_insert = lstrlenW(m_waitstring.szClipboardW);
+ }
+
+ if (len + chars_to_insert + 1 >= m_waitstring.nMaxLen)
+ {
+ chars_to_insert = m_waitstring.nMaxLen - len - 1;
+
+ // inform user
+ AddError(WASABI_API_LNGSTRINGW(IDS_STRING_TOO_LONG), 2.5f, ERR_MISC, true);
+ }
+ else
+ {
+ //m_fShowUserMessageUntilThisTime = GetTime(); // if there was an error message already, clear it
+ }
+
+ int i;
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ for (i=len; i >= m_waitstring.nCursorPos; i--)
+ *(ptr + i + chars_to_insert) = *(ptr + i);
+ for (i=0; i < chars_to_insert; i++)
+ *(ptr + i + m_waitstring.nCursorPos) = m_waitstring.szClipboard[i];
+ }
+ else
+ {
+ for (i=len; i >= m_waitstring.nCursorPos; i--)
+ m_waitstring.szText[i + chars_to_insert] = m_waitstring.szText[i];
+ for (i=0; i < chars_to_insert; i++)
+ m_waitstring.szText[i + m_waitstring.nCursorPos] = m_waitstring.szClipboardW[i];
+ }
+ m_waitstring.nCursorPos += chars_to_insert;
+ }
+}
+
+void CPlugin::WaitString_SeekLeftWord()
+{
+ // move to beginning of prior word
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ while (m_waitstring.nCursorPos > 0 &&
+ !IsAlphanumericChar(*(ptr + m_waitstring.nCursorPos-1)))
+ m_waitstring.nCursorPos--;
+
+ while (m_waitstring.nCursorPos > 0 &&
+ IsAlphanumericChar(*(ptr + m_waitstring.nCursorPos-1)))
+ m_waitstring.nCursorPos--;
+ }
+ else
+ {
+ while (m_waitstring.nCursorPos > 0 &&
+ !IsAlphanumericChar(m_waitstring.szText[m_waitstring.nCursorPos-1]))
+ m_waitstring.nCursorPos--;
+
+ while (m_waitstring.nCursorPos > 0 &&
+ IsAlphanumericChar(m_waitstring.szText[m_waitstring.nCursorPos-1]))
+ m_waitstring.nCursorPos--;
+ }
+}
+
+void CPlugin::WaitString_SeekRightWord()
+{
+ // move to beginning of next word
+
+ //testing lotsa stuff
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ int len = lstrlenA((char*)m_waitstring.szText);
+
+ char* ptr = (char*)m_waitstring.szText;
+ while (m_waitstring.nCursorPos < len &&
+ IsAlphanumericChar(*(ptr + m_waitstring.nCursorPos)))
+ m_waitstring.nCursorPos++;
+
+ while (m_waitstring.nCursorPos < len &&
+ !IsAlphanumericChar(*(ptr + m_waitstring.nCursorPos)))
+ m_waitstring.nCursorPos++;
+ }
+ else
+ {
+ int len = lstrlenW(m_waitstring.szText);
+
+ while (m_waitstring.nCursorPos < len &&
+ IsAlphanumericChar(m_waitstring.szText[m_waitstring.nCursorPos]))
+ m_waitstring.nCursorPos++;
+
+ while (m_waitstring.nCursorPos < len &&
+ !IsAlphanumericChar(m_waitstring.szText[m_waitstring.nCursorPos]))
+ m_waitstring.nCursorPos++;
+ }
+}
+
+int CPlugin::WaitString_GetCursorColumn()
+{
+ if (m_waitstring.bDisplayAsCode)
+ {
+ int column = 0;
+ char* ptr = (char*)m_waitstring.szText;
+ while (m_waitstring.nCursorPos - column - 1 >= 0 &&
+ *(ptr + m_waitstring.nCursorPos - column - 1) != LINEFEED_CONTROL_CHAR)
+ column++;
+
+ return column;
+ }
+ else
+ {
+ return m_waitstring.nCursorPos;
+ }
+}
+
+int CPlugin::WaitString_GetLineLength()
+{
+ int line_start = m_waitstring.nCursorPos - WaitString_GetCursorColumn();
+ int line_length = 0;
+
+ if (m_waitstring.bDisplayAsCode)
+ {
+ char* ptr = (char*)m_waitstring.szText;
+ while (*(ptr + line_start + line_length) != 0 &&
+ *(ptr + line_start + line_length) != LINEFEED_CONTROL_CHAR)
+ line_length++;
+ }
+ else
+ {
+ while (m_waitstring.szText[line_start + line_length] != 0 &&
+ m_waitstring.szText[line_start + line_length] != LINEFEED_CONTROL_CHAR)
+ line_length++;
+ }
+
+ return line_length;
+}
+
+void CPlugin::WaitString_SeekUpOneLine()
+{
+ int column = g_plugin.WaitString_GetCursorColumn();
+
+ if (column != m_waitstring.nCursorPos)
+ {
+ // seek to very end of previous line (cursor will be at the semicolon)
+ m_waitstring.nCursorPos -= column + 1;
+
+ int new_column = g_plugin.WaitString_GetCursorColumn();
+
+ if (new_column > column)
+ m_waitstring.nCursorPos -= (new_column - column);
+ }
+}
+
+void CPlugin::WaitString_SeekDownOneLine()
+{
+ int column = g_plugin.WaitString_GetCursorColumn();
+ int newpos = m_waitstring.nCursorPos;
+
+ char* ptr = (char*)m_waitstring.szText;
+ while (*(ptr + newpos) != 0 && *(ptr + newpos) != LINEFEED_CONTROL_CHAR)
+ newpos++;
+
+ if (*(ptr + newpos) != 0)
+ {
+ m_waitstring.nCursorPos = newpos + 1;
+
+ while ( column > 0 &&
+ *(ptr + m_waitstring.nCursorPos) != LINEFEED_CONTROL_CHAR &&
+ *(ptr + m_waitstring.nCursorPos) != 0)
+ {
+ m_waitstring.nCursorPos++;
+ column--;
+ }
+ }
+}
+
+void CPlugin::SavePresetAs(wchar_t *szNewFile)
+{
+ // overwrites the file if it was already there,
+ // so you should check if the file exists first & prompt user to overwrite,
+ // before calling this function
+
+ if (!m_pState->Export(szNewFile))
+ {
+ // error
+ AddError(WASABI_API_LNGSTRINGW(IDS_ERROR_UNABLE_TO_SAVE_THE_FILE), 6.0f, ERR_PRESET, true);
+ }
+ else
+ {
+ // pop up confirmation
+ AddError(WASABI_API_LNGSTRINGW(IDS_SAVE_SUCCESSFUL), 3.0f, ERR_NOTIFY, false);
+
+ // update m_pState->m_szDesc with the new name
+ lstrcpyW(m_pState->m_szDesc, m_waitstring.szText);
+
+ // refresh file listing
+ UpdatePresetList(false,true);
+ }
+}
+
+void CPlugin::DeletePresetFile(wchar_t *szDelFile)
+{
+ // NOTE: this function additionally assumes that m_nPresetListCurPos indicates
+ // the slot that the to-be-deleted preset occupies!
+
+ // delete file
+ if (!DeleteFileW(szDelFile))
+ {
+ // error
+ AddError(WASABI_API_LNGSTRINGW(IDS_ERROR_UNABLE_TO_DELETE_THE_FILE), 6.0f, ERR_MISC, true);
+ }
+ else
+ {
+ // pop up confirmation
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_PRESET_X_DELETED), m_presets[m_nPresetListCurPos].szFilename.c_str());
+ AddError(buf, 3.0f, ERR_NOTIFY, false);
+
+ // refresh file listing & re-select the next file after the one deleted
+ int newPos = m_nPresetListCurPos;
+ UpdatePresetList(false,true);
+ m_nPresetListCurPos = max(0, min(m_nPresets-1, newPos));
+ }
+}
+
+void CPlugin::RenamePresetFile(wchar_t *szOldFile, wchar_t *szNewFile)
+{
+ // NOTE: this function additionally assumes that m_nPresetListCurPos indicates
+ // the slot that the to-be-renamed preset occupies!
+
+ if (GetFileAttributesW(szNewFile) != -1) // check if file already exists
+ {
+ // error
+ AddError(WASABI_API_LNGSTRINGW(IDS_ERROR_A_FILE_ALREADY_EXISTS_WITH_THAT_FILENAME), 6.0f, ERR_PRESET, true);
+
+ // (user remains in UI_LOAD_RENAME mode to try another filename)
+ }
+ else
+ {
+ // rename
+ if (!MoveFileW(szOldFile, szNewFile))
+ {
+ // error
+ AddError(WASABI_API_LNGSTRINGW(IDS_ERROR_UNABLE_TO_RENAME_FILE), 6.0f, ERR_MISC, true);
+ }
+ else
+ {
+ // pop up confirmation
+ AddError(WASABI_API_LNGSTRINGW(IDS_RENAME_SUCCESSFUL), 3.0f, ERR_NOTIFY, false);
+
+ // if this preset was the active one, update m_pState->m_szDesc with the new name
+ wchar_t buf[512];
+ swprintf(buf, L"%s.milk", m_pState->m_szDesc);
+ if (wcscmp(m_presets[m_nPresetListCurPos].szFilename.c_str(), buf) == 0)
+ {
+ lstrcpyW(m_pState->m_szDesc, m_waitstring.szText);
+ }
+
+ // refresh file listing & do a trick to make it re-select the renamed file
+ wchar_t buf2[512];
+ lstrcpyW(buf2, m_waitstring.szText);
+ lstrcatW(buf2, L".milk");
+ m_presets[m_nPresetListCurPos].szFilename = buf2;
+ UpdatePresetList(false,true,false);
+
+ // jump to (highlight) the new file:
+ m_nPresetListCurPos = 0;
+ wchar_t* p = wcsrchr(szNewFile, L'\\');
+ if (p)
+ {
+ p++;
+ for (int i=m_nDirs; i<m_nPresets; i++)
+ {
+ if (wcscmp(p, m_presets[i].szFilename.c_str())==0) {
+ m_nPresetListCurPos = i;
+ break;
+ }
+ }
+ }
+ }
+
+ // exit waitstring mode (return to load menu)
+ m_UI_mode = UI_LOAD;
+ m_waitstring.bActive = false;
+ }
+}
+
+/*
+void CPlugin::UpdatePresetRatings()
+{
+ if (!m_bEnableRating)
+ return;
+
+ if (m_nRatingReadProgress==-1 || m_nRatingReadProgress==m_nPresets)
+ return;
+
+ int k;
+
+ if (m_nRatingReadProgress==0 && m_nDirs>0)
+ {
+ for (k=0; k<m_nDirs; k++)
+ {
+ m_presets[m_nRatingReadProgress].fRatingCum = 0.0f;
+ m_nRatingReadProgress++;
+ }
+
+ if (!m_bInstaScan)
+ return;
+ }
+
+ int presets_per_frame = m_bInstaScan ? 4096 : 1;
+ int k1 = m_nRatingReadProgress;
+ int k2 = min(m_nRatingReadProgress + presets_per_frame, m_nPresets);
+ for (k=k1; k<k2; k++)
+ {
+ char szFullPath[512];
+ sprintf(szFullPath, "%s%s", m_szPresetDir, m_presets[k].szFilename.c_str());
+ float f = GetPrivateProfileFloat("preset00", "fRating", 3.0f, szFullPath);
+ if (f < 0) f = 0;
+ if (f > 5) f = 5;
+
+ if (k==0)
+ m_presets[k].fRatingCum = f;
+ else
+ m_presets[k].fRatingCum = m_presets[k-1].fRatingCum + f;
+
+ m_nRatingReadProgress++;
+ }
+}
+*/
+
+void CPlugin::SetCurrentPresetRating(float fNewRating)
+{
+ if (!m_bEnableRating)
+ return;
+
+ if (fNewRating < 0) fNewRating = 0;
+ if (fNewRating > 5) fNewRating = 5;
+ float change = (fNewRating - m_pState->m_fRating);
+
+ // update the file on disk:
+ //char szPresetFileNoPath[512];
+ //char szPresetFileWithPath[512];
+ //sprintf(szPresetFileNoPath, "%s.milk", m_pState->m_szDesc);
+ //sprintf(szPresetFileWithPath, "%s%s.milk", GetPresetDir(), m_pState->m_szDesc);
+ WritePrivateProfileFloatW(fNewRating, L"fRating", m_szCurrentPresetFile, L"preset00");
+
+ // update the copy of the preset in memory
+ m_pState->m_fRating = fNewRating;
+
+ // update the cumulative internal listing:
+ m_presets[m_nCurrentPreset].fRatingThis += change;
+ if (m_nCurrentPreset != -1)// && m_nRatingReadProgress >= m_nCurrentPreset) // (can be -1 if dir. changed but no new preset was loaded yet)
+ for (int i=m_nCurrentPreset; i<m_nPresets; i++)
+ m_presets[i].fRatingCum += change;
+
+ /* keep in view:
+ -test switching dirs w/o loading a preset, and trying to change the rating
+ ->m_nCurrentPreset is out of range!
+ -soln: when adjusting rating:
+ 1. file to modify is m_szCurrentPresetFile
+ 2. only update CDF if m_nCurrentPreset is not -1
+ -> set m_nCurrentPreset to -1 whenever dir. changes
+ -> set m_szCurrentPresetFile whenever you load a preset
+ */
+
+ // show a message
+ if (!m_bShowRating)
+ {
+ // see also: DrawText() in milkdropfs.cpp
+ m_fShowRatingUntilThisTime = GetTime() + 2.0f;
+ }
+}
+
+void CPlugin::ReadCustomMessages()
+{
+ int n;
+
+ // First, clear all old data
+ for (n=0; n<MAX_CUSTOM_MESSAGE_FONTS; n++)
+ {
+ wcscpy(m_CustomMessageFont[n].szFace, L"arial");
+ m_CustomMessageFont[n].bBold = false;
+ m_CustomMessageFont[n].bItal = false;
+ m_CustomMessageFont[n].nColorR = 255;
+ m_CustomMessageFont[n].nColorG = 255;
+ m_CustomMessageFont[n].nColorB = 255;
+ }
+
+ for (n=0; n<MAX_CUSTOM_MESSAGES; n++)
+ {
+ m_CustomMessage[n].szText[0] = 0;
+ m_CustomMessage[n].nFont = 0;
+ m_CustomMessage[n].fSize = 50.0f; // [0..100] note that size is not absolute, but relative to the size of the window
+ m_CustomMessage[n].x = 0.5f;
+ m_CustomMessage[n].y = 0.5f;
+ m_CustomMessage[n].randx = 0;
+ m_CustomMessage[n].randy = 0;
+ m_CustomMessage[n].growth = 1.0f;
+ m_CustomMessage[n].fTime = 1.5f;
+ m_CustomMessage[n].fFade = 0.2f;
+
+ m_CustomMessage[n].bOverrideBold = false;
+ m_CustomMessage[n].bOverrideItal = false;
+ m_CustomMessage[n].bOverrideFace = false;
+ m_CustomMessage[n].bOverrideColorR = false;
+ m_CustomMessage[n].bOverrideColorG = false;
+ m_CustomMessage[n].bOverrideColorB = false;
+ m_CustomMessage[n].bBold = false;
+ m_CustomMessage[n].bItal = false;
+ wcscpy(m_CustomMessage[n].szFace, L"arial");
+ m_CustomMessage[n].nColorR = 255;
+ m_CustomMessage[n].nColorG = 255;
+ m_CustomMessage[n].nColorB = 255;
+ m_CustomMessage[n].nRandR = 0;
+ m_CustomMessage[n].nRandG = 0;
+ m_CustomMessage[n].nRandB = 0;
+ }
+
+ // Then read in the new file
+ for (n=0; n<MAX_CUSTOM_MESSAGE_FONTS; n++)
+ {
+ wchar_t szSectionName[32];
+ swprintf(szSectionName, L"font%02d", n);
+
+ // get face, bold, italic, x, y for this custom message FONT
+ GetPrivateProfileStringW(szSectionName,L"face",L"arial",m_CustomMessageFont[n].szFace,sizeof(m_CustomMessageFont[n].szFace), m_szMsgIniFile);
+ m_CustomMessageFont[n].bBold = GetPrivateProfileBoolW(szSectionName,L"bold",m_CustomMessageFont[n].bBold, m_szMsgIniFile);
+ m_CustomMessageFont[n].bItal = GetPrivateProfileBoolW(szSectionName,L"ital",m_CustomMessageFont[n].bItal, m_szMsgIniFile);
+ m_CustomMessageFont[n].nColorR = GetPrivateProfileIntW (szSectionName,L"r" ,m_CustomMessageFont[n].nColorR, m_szMsgIniFile);
+ m_CustomMessageFont[n].nColorG = GetPrivateProfileIntW (szSectionName,L"g" ,m_CustomMessageFont[n].nColorG, m_szMsgIniFile);
+ m_CustomMessageFont[n].nColorB = GetPrivateProfileIntW (szSectionName,L"b" ,m_CustomMessageFont[n].nColorB, m_szMsgIniFile);
+ }
+
+ for (n=0; n<MAX_CUSTOM_MESSAGES; n++)
+ {
+ wchar_t szSectionName[64];
+ swprintf(szSectionName, L"message%02d", n);
+
+ // get fontID, size, text, etc. for this custom message:
+ GetPrivateProfileStringW(szSectionName,L"text",L"",m_CustomMessage[n].szText,sizeof(m_CustomMessage[n].szText), m_szMsgIniFile);
+ if (m_CustomMessage[n].szText[0])
+ {
+ m_CustomMessage[n].nFont = GetPrivateProfileIntW (szSectionName,L"font" ,m_CustomMessage[n].nFont, m_szMsgIniFile);
+ m_CustomMessage[n].fSize = GetPrivateProfileFloatW(szSectionName,L"size" ,m_CustomMessage[n].fSize, m_szMsgIniFile);
+ m_CustomMessage[n].x = GetPrivateProfileFloatW(szSectionName,L"x" ,m_CustomMessage[n].x, m_szMsgIniFile);
+ m_CustomMessage[n].y = GetPrivateProfileFloatW(szSectionName,L"y" ,m_CustomMessage[n].y, m_szMsgIniFile);
+ m_CustomMessage[n].randx = GetPrivateProfileFloatW(szSectionName,L"randx" ,m_CustomMessage[n].randx, m_szMsgIniFile);
+ m_CustomMessage[n].randy = GetPrivateProfileFloatW(szSectionName,L"randy" ,m_CustomMessage[n].randy, m_szMsgIniFile);
+
+ m_CustomMessage[n].growth = GetPrivateProfileFloatW(szSectionName,L"growth",m_CustomMessage[n].growth, m_szMsgIniFile);
+ m_CustomMessage[n].fTime = GetPrivateProfileFloatW(szSectionName,L"time" ,m_CustomMessage[n].fTime, m_szMsgIniFile);
+ m_CustomMessage[n].fFade = GetPrivateProfileFloatW(szSectionName,L"fade" ,m_CustomMessage[n].fFade, m_szMsgIniFile);
+ m_CustomMessage[n].nColorR = GetPrivateProfileIntW (szSectionName,L"r" ,m_CustomMessage[n].nColorR, m_szMsgIniFile);
+ m_CustomMessage[n].nColorG = GetPrivateProfileIntW (szSectionName,L"g" ,m_CustomMessage[n].nColorG, m_szMsgIniFile);
+ m_CustomMessage[n].nColorB = GetPrivateProfileIntW (szSectionName,L"b" ,m_CustomMessage[n].nColorB, m_szMsgIniFile);
+ m_CustomMessage[n].nRandR = GetPrivateProfileIntW (szSectionName,L"randr" ,m_CustomMessage[n].nRandR, m_szMsgIniFile);
+ m_CustomMessage[n].nRandG = GetPrivateProfileIntW (szSectionName,L"randg" ,m_CustomMessage[n].nRandG, m_szMsgIniFile);
+ m_CustomMessage[n].nRandB = GetPrivateProfileIntW (szSectionName,L"randb" ,m_CustomMessage[n].nRandB, m_szMsgIniFile);
+
+ // overrides: r,g,b,face,bold,ital
+ GetPrivateProfileStringW(szSectionName,L"face",L"",m_CustomMessage[n].szFace,sizeof(m_CustomMessage[n].szFace), m_szMsgIniFile);
+ m_CustomMessage[n].bBold = GetPrivateProfileIntW (szSectionName, L"bold", -1, m_szMsgIniFile);
+ m_CustomMessage[n].bItal = GetPrivateProfileIntW (szSectionName, L"ital", -1, m_szMsgIniFile);
+ m_CustomMessage[n].nColorR = GetPrivateProfileIntW (szSectionName, L"r" , -1, m_szMsgIniFile);
+ m_CustomMessage[n].nColorG = GetPrivateProfileIntW (szSectionName, L"g" , -1, m_szMsgIniFile);
+ m_CustomMessage[n].nColorB = GetPrivateProfileIntW (szSectionName, L"b" , -1, m_szMsgIniFile);
+
+ m_CustomMessage[n].bOverrideFace = (m_CustomMessage[n].szFace[0] != 0);
+ m_CustomMessage[n].bOverrideBold = (m_CustomMessage[n].bBold != -1);
+ m_CustomMessage[n].bOverrideItal = (m_CustomMessage[n].bItal != -1);
+ m_CustomMessage[n].bOverrideColorR = (m_CustomMessage[n].nColorR != -1);
+ m_CustomMessage[n].bOverrideColorG = (m_CustomMessage[n].nColorG != -1);
+ m_CustomMessage[n].bOverrideColorB = (m_CustomMessage[n].nColorB != -1);
+ }
+ }
+}
+
+void CPlugin::LaunchCustomMessage(int nMsgNum)
+{
+ if (nMsgNum > 99)
+ nMsgNum = 99;
+
+ if (nMsgNum < 0)
+ {
+ int count=0;
+ // choose randomly
+ for (nMsgNum=0; nMsgNum<100; nMsgNum++)
+ if (m_CustomMessage[nMsgNum].szText[0])
+ count++;
+
+ int sel = (warand()%count)+1;
+ count = 0;
+ for (nMsgNum=0; nMsgNum<100; nMsgNum++)
+ {
+ if (m_CustomMessage[nMsgNum].szText[0])
+ count++;
+ if (count==sel)
+ break;
+ }
+ }
+
+ if (nMsgNum < 0 ||
+ nMsgNum >= MAX_CUSTOM_MESSAGES ||
+ m_CustomMessage[nMsgNum].szText[0]==0)
+ {
+ return;
+ }
+
+ int fontID = m_CustomMessage[nMsgNum].nFont;
+
+ m_supertext.bRedrawSuperText = true;
+ m_supertext.bIsSongTitle = false;
+ lstrcpyW(m_supertext.szTextW, m_CustomMessage[nMsgNum].szText);
+
+ // regular properties:
+ m_supertext.fFontSize = m_CustomMessage[nMsgNum].fSize;
+ m_supertext.fX = m_CustomMessage[nMsgNum].x + m_CustomMessage[nMsgNum].randx * ((warand()%1037)/1037.0f*2.0f - 1.0f);
+ m_supertext.fY = m_CustomMessage[nMsgNum].y + m_CustomMessage[nMsgNum].randy * ((warand()%1037)/1037.0f*2.0f - 1.0f);
+ m_supertext.fGrowth = m_CustomMessage[nMsgNum].growth;
+ m_supertext.fDuration = m_CustomMessage[nMsgNum].fTime;
+ m_supertext.fFadeTime = m_CustomMessage[nMsgNum].fFade;
+
+ // overrideables:
+ if (m_CustomMessage[nMsgNum].bOverrideFace)
+ lstrcpyW(m_supertext.nFontFace, m_CustomMessage[nMsgNum].szFace);
+ else
+ lstrcpyW(m_supertext.nFontFace, m_CustomMessageFont[fontID].szFace);
+ m_supertext.bItal = (m_CustomMessage[nMsgNum].bOverrideItal) ? (m_CustomMessage[nMsgNum].bItal != 0) : (m_CustomMessageFont[fontID].bItal != 0);
+ m_supertext.bBold = (m_CustomMessage[nMsgNum].bOverrideBold) ? (m_CustomMessage[nMsgNum].bBold != 0) : (m_CustomMessageFont[fontID].bBold != 0);
+ m_supertext.nColorR = (m_CustomMessage[nMsgNum].bOverrideColorR) ? m_CustomMessage[nMsgNum].nColorR : m_CustomMessageFont[fontID].nColorR;
+ m_supertext.nColorG = (m_CustomMessage[nMsgNum].bOverrideColorG) ? m_CustomMessage[nMsgNum].nColorG : m_CustomMessageFont[fontID].nColorG;
+ m_supertext.nColorB = (m_CustomMessage[nMsgNum].bOverrideColorB) ? m_CustomMessage[nMsgNum].nColorB : m_CustomMessageFont[fontID].nColorB;
+
+ // randomize color
+ m_supertext.nColorR += (int)(m_CustomMessage[nMsgNum].nRandR * ((warand()%1037)/1037.0f*2.0f - 1.0f));
+ m_supertext.nColorG += (int)(m_CustomMessage[nMsgNum].nRandG * ((warand()%1037)/1037.0f*2.0f - 1.0f));
+ m_supertext.nColorB += (int)(m_CustomMessage[nMsgNum].nRandB * ((warand()%1037)/1037.0f*2.0f - 1.0f));
+ if (m_supertext.nColorR < 0) m_supertext.nColorR = 0;
+ if (m_supertext.nColorG < 0) m_supertext.nColorG = 0;
+ if (m_supertext.nColorB < 0) m_supertext.nColorB = 0;
+ if (m_supertext.nColorR > 255) m_supertext.nColorR = 255;
+ if (m_supertext.nColorG > 255) m_supertext.nColorG = 255;
+ if (m_supertext.nColorB > 255) m_supertext.nColorB = 255;
+
+ // fix &'s for display:
+ /*
+ {
+ int pos = 0;
+ int len = lstrlen(m_supertext.szText);
+ while (m_supertext.szText[pos] && pos<255)
+ {
+ if (m_supertext.szText[pos] == '&')
+ {
+ for (int x=len; x>=pos; x--)
+ m_supertext.szText[x+1] = m_supertext.szText[x];
+ len++;
+ pos++;
+ }
+ pos++;
+ }
+ }*/
+
+ m_supertext.fStartTime = GetTime();
+}
+
+void CPlugin::LaunchSongTitleAnim()
+{
+ m_supertext.bRedrawSuperText = true;
+ m_supertext.bIsSongTitle = true;
+ lstrcpyW(m_supertext.szTextW, m_szSongTitle);
+ //lstrcpy(m_supertext.szText, " ");
+ lstrcpyW(m_supertext.nFontFace, m_fontinfo[SONGTITLE_FONT].szFace);
+ m_supertext.fFontSize = (float)m_fontinfo[SONGTITLE_FONT].nSize;
+ m_supertext.bBold = m_fontinfo[SONGTITLE_FONT].bBold;
+ m_supertext.bItal = m_fontinfo[SONGTITLE_FONT].bItalic;
+ m_supertext.fX = 0.5f;
+ m_supertext.fY = 0.5f;
+ m_supertext.fGrowth = 1.0f;
+ m_supertext.fDuration = m_fSongTitleAnimDuration;
+ m_supertext.nColorR = 255;
+ m_supertext.nColorG = 255;
+ m_supertext.nColorB = 255;
+
+ m_supertext.fStartTime = GetTime();
+}
+
+bool CPlugin::LaunchSprite(int nSpriteNum, int nSlot)
+{
+ char initcode[8192], code[8192], sectionA[64];
+ char szTemp[8192];
+ wchar_t img[512], section[64];
+
+ initcode[0] = 0;
+ code[0] = 0;
+ img[0] = 0;
+ swprintf(section, L"img%02d", nSpriteNum);
+ sprintf(sectionA, "img%02d", nSpriteNum);
+
+ // 1. read in image filename
+ GetPrivateProfileStringW(section, L"img", L"", img, sizeof(img)-1, m_szImgIniFile);
+ if (img[0] == 0)
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SPRITE_X_ERROR_COULD_NOT_FIND_IMG_OR_NOT_DEFINED), nSpriteNum);
+ AddError(buf, 7.0f, ERR_MISC, false);
+ return false;
+ }
+
+ if (img[1] != L':')// || img[2] != '\\')
+ {
+ // it's not in the form "x:\blah\billy.jpg" so prepend plugin dir path.
+ wchar_t temp[512];
+ wcscpy(temp, img);
+ swprintf(img, L"%s%s", m_szMilkdrop2Path, temp);
+ }
+
+ // 2. get color key
+ //unsigned int ck_lo = (unsigned int)GetPrivateProfileInt(section, "colorkey_lo", 0x00000000, m_szImgIniFile);
+ //unsigned int ck_hi = (unsigned int)GetPrivateProfileInt(section, "colorkey_hi", 0x00202020, m_szImgIniFile);
+ // FIRST try 'colorkey_lo' (for backwards compatibility) and then try 'colorkey'
+ unsigned int ck = (unsigned int)GetPrivateProfileIntW(section, L"colorkey_lo", 0x00000000, m_szImgIniFile/*GetConfigIniFile()*/);
+ ck = (unsigned int)GetPrivateProfileIntW(section, L"colorkey", ck, m_szImgIniFile/*GetConfigIniFile()*/);
+
+ // 3. read in init code & per-frame code
+ for (int n=0; n<2; n++)
+ {
+ char *pStr = (n==0) ? initcode : code;
+ char szLineName[32];
+ int len;
+
+ int line = 1;
+ int char_pos = 0;
+ bool bDone = false;
+
+ while (!bDone)
+ {
+ if (n==0)
+ sprintf(szLineName, "init_%d", line);
+ else
+ sprintf(szLineName, "code_%d", line);
+
+ GetPrivateProfileString(sectionA, szLineName, "~!@#$", szTemp, 8192, AutoCharFn(m_szImgIniFile)); // fixme
+ len = lstrlen(szTemp);
+
+ if ((strcmp(szTemp, "~!@#$")==0) || // if the key was missing,
+ (len >= 8191-char_pos-1)) // or if we're out of space
+ {
+ bDone = true;
+ }
+ else
+ {
+ sprintf(&pStr[char_pos], "%s%c", szTemp, LINEFEED_CONTROL_CHAR);
+ }
+
+ char_pos += len + 1;
+ line++;
+ }
+ pStr[char_pos++] = 0; // null-terminate
+ }
+
+ if (nSlot == -1)
+ {
+ // find first empty slot; if none, chuck the oldest sprite & take its slot.
+ int oldest_index = 0;
+ int oldest_frame = m_texmgr.m_tex[0].nStartFrame;
+ for (int x=0; x<NUM_TEX; x++)
+ {
+ if (!m_texmgr.m_tex[x].pSurface)
+ {
+ nSlot = x;
+ break;
+ }
+ else if (m_texmgr.m_tex[x].nStartFrame < oldest_frame)
+ {
+ oldest_index = x;
+ oldest_frame = m_texmgr.m_tex[x].nStartFrame;
+ }
+ }
+
+ if (nSlot == -1)
+ {
+ nSlot = oldest_index;
+ m_texmgr.KillTex(nSlot);
+ }
+ }
+
+ int ret = m_texmgr.LoadTex(img, nSlot, initcode, code, GetTime(), GetFrame(), ck);
+ m_texmgr.m_tex[nSlot].nUserData = nSpriteNum;
+
+ wchar_t buf[1024];
+ switch(ret & TEXMGR_ERROR_MASK)
+ {
+ case TEXMGR_ERR_SUCCESS:
+ switch(ret & TEXMGR_WARNING_MASK)
+ {
+ case TEXMGR_WARN_ERROR_IN_INIT_CODE:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SPRITE_X_WARNING_ERROR_IN_INIT_CODE), nSpriteNum);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ break;
+ case TEXMGR_WARN_ERROR_IN_REG_CODE:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SPRITE_X_WARNING_ERROR_IN_PER_FRAME_CODE), nSpriteNum);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ break;
+ default:
+ // success; no errors OR warnings.
+ break;
+ }
+ break;
+ case TEXMGR_ERR_BAD_INDEX:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SPRITE_X_ERROR_BAD_SLOT_INDEX), nSpriteNum);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ break;
+ /*
+ case TEXMGR_ERR_OPENING: sprintf(m_szUserMessage, "sprite #%d error: unable to open imagefile", nSpriteNum); break;
+ case TEXMGR_ERR_FORMAT: sprintf(m_szUserMessage, "sprite #%d error: file is corrupt or non-jpeg image", nSpriteNum); break;
+ case TEXMGR_ERR_IMAGE_NOT_24_BIT: sprintf(m_szUserMessage, "sprite #%d error: image does not have 3 color channels", nSpriteNum); break;
+ case TEXMGR_ERR_IMAGE_TOO_LARGE: sprintf(m_szUserMessage, "sprite #%d error: image is too large", nSpriteNum); break;
+ case TEXMGR_ERR_CREATESURFACE_FAILED: sprintf(m_szUserMessage, "sprite #%d error: createsurface() failed", nSpriteNum); break;
+ case TEXMGR_ERR_LOCKSURFACE_FAILED: sprintf(m_szUserMessage, "sprite #%d error: lock() failed", nSpriteNum); break;
+ case TEXMGR_ERR_CORRUPT_JPEG: sprintf(m_szUserMessage, "sprite #%d error: jpeg is corrupt", nSpriteNum); break;
+ */
+ case TEXMGR_ERR_BADFILE:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SPRITE_X_ERROR_IMAGE_FILE_MISSING_OR_CORRUPT), nSpriteNum);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ break;
+ case TEXMGR_ERR_OUTOFMEM:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_SPRITE_X_ERROR_OUT_OF_MEM), nSpriteNum);
+ AddError(buf, 6.0f, ERR_MISC, true);
+ break;
+ }
+
+ return (ret & TEXMGR_ERROR_MASK) ? false : true;
+}
+
+void CPlugin::KillSprite(int iSlot)
+{
+ m_texmgr.KillTex(iSlot);
+}
+
+void CPlugin::DoCustomSoundAnalysis()
+{
+ memcpy(mysound.fWave[0], m_sound.fWaveform[0], sizeof(float)*576);
+ memcpy(mysound.fWave[1], m_sound.fWaveform[1], sizeof(float)*576);
+
+ // do our own [UN-NORMALIZED] fft
+ float fWaveLeft[576];
+ int i = 0;
+ for (i=0; i<576; i++)
+ fWaveLeft[i] = m_sound.fWaveform[0][i];
+
+ memset(mysound.fSpecLeft, 0, sizeof(float)*MY_FFT_SAMPLES);
+
+ myfft.time_to_frequency_domain(fWaveLeft, mysound.fSpecLeft);
+ //for (i=0; i<MY_FFT_SAMPLES; i++) fSpecLeft[i] = sqrtf(fSpecLeft[i]*fSpecLeft[i] + fSpecTemp[i]*fSpecTemp[i]);
+
+ // sum spectrum up into 3 bands
+
+ for (i=0; i<3; i++)
+ {
+ // note: only look at bottom half of spectrum! (hence divide by 6 instead of 3)
+ int start = MY_FFT_SAMPLES*i/6;
+ int end = MY_FFT_SAMPLES*(i+1)/6;
+ int j;
+
+ mysound.imm[i] = 0;
+
+ for (j=start; j<end; j++)
+ mysound.imm[i] += mysound.fSpecLeft[j];
+ }
+
+ // do temporal blending to create attenuated and super-attenuated versions
+ for (i=0; i<3; i++)
+ {
+ float rate;
+
+ if (mysound.imm[i] > mysound.avg[i])
+ rate = 0.2f;
+ else
+ rate = 0.5f;
+ rate = AdjustRateToFPS(rate, 30.0f, GetFps());
+ mysound.avg[i] = mysound.avg[i]*rate + mysound.imm[i]*(1-rate);
+
+ if (GetFrame() < 50)
+ rate = 0.9f;
+ else
+ rate = 0.992f;
+ rate = AdjustRateToFPS(rate, 30.0f, GetFps());
+ mysound.long_avg[i] = mysound.long_avg[i]*rate + mysound.imm[i]*(1-rate);
+
+
+ // also get bass/mid/treble levels *relative to the past*
+ if (fabsf(mysound.long_avg[i]) < 0.001f)
+ mysound.imm_rel[i] = 1.0f;
+ else
+ mysound.imm_rel[i] = mysound.imm[i] / mysound.long_avg[i];
+
+ if (fabsf(mysound.long_avg[i]) < 0.001f)
+ mysound.avg_rel[i] = 1.0f;
+ else
+ mysound.avg_rel[i] = mysound.avg[i] / mysound.long_avg[i];
+ }
+}
+
+void CPlugin::GenWarpPShaderText(char *szShaderText, float decay, bool bWrap)
+{
+ // find the pixel shader body and replace it with custom code.
+
+ lstrcpy(szShaderText, m_szDefaultWarpPShaderText);
+ char LF = LINEFEED_CONTROL_CHAR;
+ char *p = strrchr( szShaderText, '{' );
+ if (!p)
+ return;
+ p++;
+ p += sprintf(p, "%c", 1);
+
+ p += sprintf(p, " // sample previous frame%c", LF);
+ p += sprintf(p, " ret = tex2D( sampler%s_main, uv ).xyz;%c", bWrap ? L"" : L"_fc", LF);
+ p += sprintf(p, " %c", LF);
+ p += sprintf(p, " // darken (decay) over time%c", LF);
+ p += sprintf(p, " ret *= %.2f; //or try: ret -= 0.004;%c", decay, LF);
+ //p += sprintf(p, " %c", LF);
+ //p += sprintf(p, " ret.w = vDiffuse.w; // pass alpha along - req'd for preset blending%c", LF);
+ p += sprintf(p, "}%c", LF);
+}
+
+void CPlugin::GenCompPShaderText(char *szShaderText, float brightness, float ve_alpha, float ve_zoom, int ve_orient, float hue_shader, bool bBrighten, bool bDarken, bool bSolarize, bool bInvert)
+{
+ // find the pixel shader body and replace it with custom code.
+
+ lstrcpy(szShaderText, m_szDefaultCompPShaderText);
+ char LF = LINEFEED_CONTROL_CHAR;
+ char *p = strrchr( szShaderText, '{' );
+ if (!p)
+ return;
+ p++;
+ p += sprintf(p, "%c", 1);
+
+ if (ve_alpha > 0.001f)
+ {
+ int orient_x = (ve_orient % 2) ? -1 : 1;
+ int orient_y = (ve_orient >= 2) ? -1 : 1;
+ p += sprintf(p, " float2 uv_echo = (uv - 0.5)*%.3f*float2(%d,%d) + 0.5;%c", 1.0f/ve_zoom, orient_x, orient_y, LF);
+ p += sprintf(p, " ret = lerp( tex2D(sampler_main, uv).xyz, %c", LF);
+ p += sprintf(p, " tex2D(sampler_main, uv_echo).xyz, %c", LF);
+ p += sprintf(p, " %.2f %c", ve_alpha, LF);
+ p += sprintf(p, " ); //video echo%c", LF);
+ p += sprintf(p, " ret *= %.2f; //gamma%c", brightness, LF);
+ }
+ else
+ {
+ p += sprintf(p, " ret = tex2D(sampler_main, uv).xyz;%c", LF);
+ p += sprintf(p, " ret *= %.2f; //gamma%c", brightness, LF);
+ }
+ if (hue_shader >= 1.0f)
+ p += sprintf(p, " ret *= hue_shader; //old hue shader effect%c", LF);
+ else if (hue_shader > 0.001f)
+ p += sprintf(p, " ret *= %.2f + %.2f*hue_shader; //old hue shader effect%c", 1-hue_shader, hue_shader, LF);
+
+ if (bBrighten)
+ p += sprintf(p, " ret = sqrt(ret); //brighten%c", LF);
+ if (bDarken)
+ p += sprintf(p, " ret *= ret; //darken%c", LF);
+ if (bSolarize)
+ p += sprintf(p, " ret = ret*(1-ret)*4; //solarize%c", LF);
+ if (bInvert)
+ p += sprintf(p, " ret = 1 - ret; //invert%c", LF);
+ //p += sprintf(p, " ret.w = vDiffuse.w; // pass alpha along - req'd for preset blending%c", LF);
+ p += sprintf(p, "}%c", LF);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin.dsp b/Src/Plugins/Visualization/vis_milk2/plugin.dsp
new file mode 100644
index 00000000..e8ed2a95
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin.dsp
@@ -0,0 +1,304 @@
+# Microsoft Developer Studio Project File - Name="plugin" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=plugin - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "plugin.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "plugin.mak" CFG="plugin - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "plugin - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "plugin - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "plugin - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "plugin_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\SDKs\DirectX_9_Oct_2004\Include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib d3dx9.lib d3d9.lib Delayimp.lib /nologo /dll /machine:I386 /out:"c:\program files\winamp\plugins\vis_milk2.dll" /libpath:"..\SDKs\DirectX_9_Oct_2004\lib"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "plugin - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLUGIN_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\SDKs\DirectX_9_Oct_2004\Include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib d3dx9.lib d3d9.lib delayimp.lib /nologo /dll /debug /machine:I386 /out:"c:\program files\winamp\plugins\vis_milk2.dll" /pdbtype:sept /libpath:"..\SDKs\DirectX_9_Oct_2004\lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "plugin - Win32 Release"
+# Name "plugin - Win32 Debug"
+# Begin Group "My Plugin Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\menu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\milkdropfs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\plugin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\plugin_icon.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\state.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\support.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\texmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\textmgr.cpp
+# End Source File
+# End Group
+# Begin Group "My Plugin Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\defines.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\md_defines.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\menu.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\plugin.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\state.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\support.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\texmgr.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\textmgr.h
+# End Source File
+# End Group
+# Begin Group "Framework Files (do not edit)"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\config.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\config2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\desktop_mode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\dxcontext.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\dxcontext.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\fft.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\fft.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\gstring.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\icon_t.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\plugin.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\pluginshell.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pluginshell.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\shell_defines.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\utility.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\utility.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\vis.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\vis.h
+# End Source File
+# End Group
+# Begin Group "evallib"
+
+# PROP Default_Filter "*.c;*.h"
+# Begin Source File
+
+SOURCE=.\evallib\CAL_TAB.C
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\cal_tab.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\cfunc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\Compiler.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\Compiler.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\eval.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\eval.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\Gettok.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\LEX.H
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\Lextab.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\LLSAVE.C
+# End Source File
+# Begin Source File
+
+SOURCE=.\evallib\Yylex.c
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\DOCUMENTATION.TXT
+# End Source File
+# Begin Source File
+
+SOURCE=.\milkdrop.nsi
+# End Source File
+# Begin Source File
+
+SOURCE=.\temp.ico
+# End Source File
+# End Target
+# End Project
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin.h b/Src/Plugins/Visualization/vis_milk2/plugin.h
new file mode 100644
index 00000000..440205bb
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin.h
@@ -0,0 +1,729 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_EXAMPLE_PLUGIN_H__
+#define __NULLSOFT_DX9_EXAMPLE_PLUGIN_H__ 1
+
+#include "pluginshell.h"
+#include "md_defines.h"
+#include "menu.h"
+#include "support.h"
+#include "texmgr.h"
+#include "state.h"
+#include <vector>
+
+#include "gstring.h"
+#include "ns-eel2/ns-eel.h"
+
+
+
+extern "C" int (*warand)(void);
+
+typedef enum { TEX_DISK, TEX_VS, TEX_BLUR0, TEX_BLUR1, TEX_BLUR2, TEX_BLUR3, TEX_BLUR4, TEX_BLUR5, TEX_BLUR6, TEX_BLUR_LAST } tex_code;
+typedef enum { UI_REGULAR, UI_MENU, UI_LOAD, UI_LOAD_DEL, UI_LOAD_RENAME, UI_SAVEAS, UI_SAVE_OVERWRITE, UI_EDIT_MENU_STRING, UI_CHANGEDIR, UI_IMPORT_WAVE, UI_EXPORT_WAVE, UI_IMPORT_SHAPE, UI_EXPORT_SHAPE, UI_UPGRADE_PIXEL_SHADER, UI_MASHUP } ui_mode;
+typedef struct { float rad; float ang; float a; float c; } td_vertinfo; // blending: mix = max(0,min(1,a*t + c));
+typedef char* CHARPTR;
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+
+#define MY_FFT_SAMPLES 512 // for old [pre-vms] milkdrop sound analysis
+typedef struct
+{
+ float imm[3]; // bass, mids, treble (absolute)
+ float imm_rel[3]; // bass, mids, treble (relative to song; 1=avg, 0.9~below, 1.1~above)
+ float avg[3]; // bass, mids, treble (absolute)
+ float avg_rel[3]; // bass, mids, treble (relative to song; 1=avg, 0.9~below, 1.1~above)
+ float long_avg[3]; // bass, mids, treble (absolute)
+ float fWave[2][576];
+ float fSpecLeft[MY_FFT_SAMPLES];
+} td_mysounddata;
+
+typedef struct
+{
+ int bActive;
+ int bFilterBadChars; // if true, it will filter out any characters that don't belong in a filename, plus the & symbol (because it doesn't display properly with DrawText)
+ int bDisplayAsCode; // if true, semicolons will be followed by a newline, for display
+ int nMaxLen; // can't be more than 511
+ int nCursorPos;
+ int nSelAnchorPos; // -1 if no selection made
+ int bOvertypeMode;
+ wchar_t szText[48000];
+ wchar_t szPrompt[512];
+ wchar_t szToolTip[512];
+ char szClipboard[48000];
+ wchar_t szClipboardW[48000];
+} td_waitstr;
+
+typedef struct
+{
+ int bBold;
+ int bItal;
+ wchar_t szFace[128];
+ int nColorR; // 0..255
+ int nColorG; // 0..255
+ int nColorB; // 0..255
+}
+td_custom_msg_font;
+
+enum
+{
+ MD2_PS_NONE = 0,
+ MD2_PS_2_0 = 2,
+ MD2_PS_2_X = 3,
+ MD2_PS_3_0 = 4,
+ MD2_PS_4_0 = 5, // not supported by milkdrop
+};
+/*
+typedef struct
+{
+ char szFace[256];
+ int nSize;
+ int bBold;
+ int bItalic;
+} td_titlefontinfo;*/
+
+typedef struct
+{
+ int nFont;
+ float fSize; // 0..100
+ float x;
+ float y;
+ float randx;
+ float randy;
+ float growth;
+ float fTime; // total time to display the message, in seconds
+ float fFade; // % (0..1) of the time that is spent fading in
+
+ // overrides
+ int bOverrideBold;
+ int bOverrideItal;
+ int bOverrideFace;
+ int bOverrideColorR;
+ int bOverrideColorG;
+ int bOverrideColorB;
+ int nColorR; // 0..255
+ int nColorG; // 0..255
+ int nColorB; // 0..255
+ int nRandR;
+ int nRandG;
+ int nRandB;
+ int bBold;
+ int bItal;
+ wchar_t szFace[128];
+
+ wchar_t szText[256];
+}
+td_custom_msg;
+
+typedef struct
+{
+ int bRedrawSuperText; // true if it needs redraw
+ int bIsSongTitle; // false for custom message, true for song title
+ //char szText[256];
+ wchar_t szTextW[256];
+ wchar_t nFontFace[128];
+ int bBold;
+ int bItal;
+ float fX;
+ float fY;
+ float fFontSize; // [0..100] for custom messages, [0..4] for song titles
+ float fGrowth; // applies to custom messages only
+ int nFontSizeUsed; // height IN PIXELS
+ float fStartTime;
+ float fDuration;
+ float fFadeTime; // applies to custom messages only; song title fade times are handled specially
+ int nColorR;
+ int nColorG;
+ int nColorB;
+}
+td_supertext;
+
+typedef struct
+{
+ wchar_t texname[256]; // ~filename, but without path or extension!
+ LPDIRECT3DBASETEXTURE9 texptr;
+ int w,h,d;
+ //D3DXHANDLE texsize_param;
+ bool bEvictable;
+ int nAge; // only valid if bEvictable is true
+ int nSizeInBytes; // only valid if bEvictable is true
+} TexInfo;
+
+typedef struct
+{
+ GString texname; // just for ref
+ D3DXHANDLE texsize_param;
+ int w,h;
+} TexSizeParamInfo;
+
+typedef struct
+{
+ LPDIRECT3DBASETEXTURE9 texptr;
+ bool bBilinear;
+ bool bWrap;
+} SamplerInfo;
+
+typedef struct
+{
+ GString msg;
+ bool bBold; // true == red bkg; false == black bkg
+ float birthTime;
+ float expireTime;
+ int category;
+} ErrorMsg;
+typedef std::vector<ErrorMsg> ErrorMsgList;
+
+typedef std::vector<CShaderParams*> CShaderParamsList;
+
+class CShaderParams
+{
+public:
+ // float4 handles:
+ D3DXHANDLE rand_frame ;
+ D3DXHANDLE rand_preset;
+ D3DXHANDLE const_handles[24];
+ D3DXHANDLE q_const_handles[(NUM_Q_VAR+3)/4];
+ D3DXHANDLE rot_mat[24];
+
+ typedef std::vector<TexSizeParamInfo> TexSizeParamInfoList;
+ TexSizeParamInfoList texsize_params;
+
+ // sampler stages for various PS texture bindings:
+ //int texbind_vs;
+ //int texbind_disk[32];
+ //int texbind_voronoi;
+ //...
+ SamplerInfo m_texture_bindings[16]; // an entry for each sampler slot. These are ALIASES - DO NOT DELETE.
+ tex_code m_texcode[16]; // if ==TEX_VS, forget the pointer - texture bound @ that stage is the double-buffered VS.
+
+ void Clear();
+ void CacheParams(LPD3DXCONSTANTTABLE pCT, bool bHardErrors);
+ void OnTextureEvict(LPDIRECT3DBASETEXTURE9 texptr);
+ CShaderParams();
+ ~CShaderParams();
+};
+
+class VShaderInfo
+{
+public:
+ IDirect3DVertexShader9* ptr;
+ LPD3DXCONSTANTTABLE CT;
+ CShaderParams params;
+ VShaderInfo() { ptr=NULL; CT=NULL; params.Clear(); }
+ ~VShaderInfo() { Clear(); }
+ void Clear();
+};
+
+class PShaderInfo
+{
+public:
+ IDirect3DPixelShader9* ptr;
+ LPD3DXCONSTANTTABLE CT;
+ CShaderParams params;
+ PShaderInfo() { ptr=NULL; CT=NULL; params.Clear(); }
+ ~PShaderInfo() { Clear(); }
+ void Clear();
+};
+
+typedef struct
+{
+ VShaderInfo vs;
+ PShaderInfo ps;
+} ShaderPairInfo;
+
+typedef struct
+{
+ PShaderInfo warp;
+ PShaderInfo comp;
+} PShaderSet;
+
+typedef struct
+{
+ VShaderInfo warp;
+ VShaderInfo comp;
+} VShaderSet;
+
+/*
+typedef struct
+{
+ void* ptr; // to IDirect3DPixelShader9 or IDirect3DVertexShader9
+ LPD3DXCONSTANTTABLE CT;
+ CShaderParams params;
+} ShaderInfo;
+
+typedef struct
+{
+ ShaderInfo warp;
+ ShaderInfo comp;
+} ShaderSet;
+*/
+
+typedef struct
+{
+ GString szFilename; // without path
+ float fRatingThis;
+ float fRatingCum;
+} PresetInfo;
+typedef std::vector<PresetInfo> PresetList;
+
+
+class CPlugin : public CPluginShell
+{
+public:
+
+ //====[ 1. members added to create this specific example plugin: ]================================================
+
+ /// CONFIG PANEL SETTINGS THAT WE'VE ADDED (TAB #2)
+ bool m_bFirstRun;
+ float m_fBlendTimeAuto; // blend time when preset auto-switches
+ float m_fBlendTimeUser; // blend time when user loads a new preset
+ float m_fTimeBetweenPresets; // <- this is in addition to m_fBlendTimeAuto
+ float m_fTimeBetweenPresetsRand; // <- this is in addition to m_fTimeBetweenPresets
+ bool m_bSequentialPresetOrder;
+ bool m_bHardCutsDisabled;
+ float m_fHardCutLoudnessThresh;
+ float m_fHardCutHalflife;
+ float m_fHardCutThresh;
+ //int m_nWidth;
+ //int m_nHeight;
+ //int m_nDispBits;
+ int m_nCanvasStretch; // 0=Auto, 100=None, 125 = 1.25X, 133, 150, 167, 200, 300, 400 (4X).
+ int m_nTexSizeX; // -1 = exact match to screen; -2 = nearest power of 2.
+ int m_nTexSizeY;
+ float m_fAspectX;
+ float m_fAspectY;
+ float m_fInvAspectX;
+ float m_fInvAspectY;
+ int m_nTexBitsPerCh;
+ int m_nGridX;
+ int m_nGridY;
+
+ bool m_bShowPressF1ForHelp;
+ //char m_szMonitorName[256];
+ bool m_bShowMenuToolTips;
+ int m_n16BitGamma;
+ bool m_bAutoGamma;
+ //int m_nFpsLimit;
+ //int m_cLeftEye3DColor[3];
+ //int m_cRightEye3DColor[3];
+ bool m_bEnableRating;
+ //bool m_bInstaScan;
+ bool m_bSongTitleAnims;
+ float m_fSongTitleAnimDuration;
+ float m_fTimeBetweenRandomSongTitles;
+ float m_fTimeBetweenRandomCustomMsgs;
+ int m_nSongTitlesSpawned;
+ int m_nCustMsgsSpawned;
+
+ //bool m_bAlways3D;
+ //float m_fStereoSep;
+ //bool m_bAlwaysOnTop;
+ //bool m_bFixSlowText;
+ //bool m_bWarningsDisabled; // messageboxes
+ bool m_bWarningsDisabled2; // warnings/errors in upper-right corner (m_szUserMessage)
+ //bool m_bAnisotropicFiltering;
+ bool m_bPresetLockOnAtStartup;
+ bool m_bPreventScollLockHandling;
+ int m_nMaxPSVersion_ConfigPanel; // -1 = auto, 0 = disable shaders, 2 = ps_2_0, 3 = ps_3_0
+ int m_nMaxPSVersion_DX9; // 0 = no shader support, 2 = ps_2_0, 3 = ps_3_0
+ int m_nMaxPSVersion; // this one will be the ~min of the other two. 0/2/3.
+ int m_nMaxImages;
+ int m_nMaxBytes;
+
+ /*
+ char m_szFontFace[NUM_FONTS][128];
+ int m_nFontSize[NUM_FONTS];
+ bool m_bFontBold[NUM_FONTS];
+ bool m_bFontItalic[NUM_FONTS];
+ char m_szTitleFontFace[128];
+ int m_nTitleFontSize; // percentage of screen width (0..100)
+ bool m_bTitleFontBold;
+ bool m_bTitleFontItalic;
+ */
+ HFONT m_gdi_title_font_doublesize;
+ LPD3DXFONT m_d3dx_title_font_doublesize;
+
+ // PIXEL SHADERS
+ DWORD m_dwShaderFlags; // Shader compilation/linking flags
+ //ID3DXFragmentLinker* m_pFragmentLinker; // Fragment linker interface
+ //LPD3DXBUFFER m_pCompiledFragments; // Buffer containing compiled fragments
+ LPD3DXBUFFER m_pShaderCompileErrors;
+ VShaderSet m_fallbackShaders_vs; // *these are the only vertex shaders used for the whole app.*
+ PShaderSet m_fallbackShaders_ps; // these are just used when the preset's pixel shaders fail to compile.
+ PShaderSet m_shaders; // includes shader pointers and constant tables for warp & comp shaders, for cur. preset
+ PShaderSet m_OldShaders; // includes shader pointers and constant tables for warp & comp shaders, for prev. preset
+ PShaderSet m_NewShaders; // includes shader pointers and constant tables for warp & comp shaders, for coming preset
+ ShaderPairInfo m_BlurShaders[2];
+ bool m_bWarpShaderLock;
+ bool m_bCompShaderLock;
+ //bool LoadShaderFromFile( char* szFile, char* szFn, char* szProfile,
+ // LPD3DXCONSTANTTABLE* ppConstTable, void** ppShader );
+ #define SHADER_WARP 0
+ #define SHADER_COMP 1
+ #define SHADER_BLUR 2
+ #define SHADER_OTHER 3
+ bool LoadShaderFromMemory( const char* szShaderText, char* szFn, char* szProfile,
+ LPD3DXCONSTANTTABLE* ppConstTable, void** ppShader, int shaderType, bool bHardErrors );
+ bool RecompileVShader(const char* szShadersText, VShaderInfo *si, int shaderType, bool bHardErrors);
+ bool RecompilePShader(const char* szShadersText, PShaderInfo *si, int shaderType, bool bHardErrors, int PSVersion);
+ bool EvictSomeTexture();
+ typedef std::vector<TexInfo> TexInfoList;
+ TexInfoList m_textures;
+ bool m_bNeedRescanTexturesDir;
+ // vertex declarations:
+ IDirect3DVertexDeclaration9* m_pSpriteVertDecl;
+ IDirect3DVertexDeclaration9* m_pWfVertDecl;
+ IDirect3DVertexDeclaration9* m_pMyVertDecl;
+
+ D3DXVECTOR4 m_rand_frame; // 4 random floats (0..1); randomized once per frame; fed to pixel shaders.
+
+ // RUNTIME SETTINGS THAT WE'VE ADDED
+ float m_prev_time;
+ bool m_bTexSizeWasAutoPow2;
+ bool m_bTexSizeWasAutoExact;
+ bool m_bPresetLockedByUser;
+ bool m_bPresetLockedByCode;
+ float m_fAnimTime;
+ float m_fStartTime;
+ float m_fPresetStartTime;
+ float m_fNextPresetTime;
+ float m_fSnapPoint;
+ CState *m_pState; // points to current CState
+ CState *m_pOldState; // points to previous CState
+ CState *m_pNewState; // points to the coming CState - we're not yet blending to it b/c we're still compiling the shaders for it!
+ int m_nLoadingPreset;
+ wchar_t m_szLoadingPreset[MAX_PATH];
+ float m_fLoadingPresetBlendTime;
+ int m_nPresetsLoadedTotal; //important for texture eviction age-tracking...
+ CState m_state_DO_NOT_USE[3]; // do not use; use pState and pOldState instead.
+ ui_mode m_UI_mode; // can be UI_REGULAR, UI_LOAD, UI_SAVEHOW, or UI_SAVEAS
+
+ #define MASH_SLOTS 5
+ #define MASH_APPLY_DELAY_FRAMES 1
+ int m_nMashSlot; //0..MASH_SLOTS-1
+ //char m_szMashDir[MASH_SLOTS][MAX_PATH];
+ int m_nMashPreset[MASH_SLOTS];
+ int m_nLastMashChangeFrame[MASH_SLOTS];
+
+ //td_playlist_entry *m_szPlaylist; // array of 128-char strings
+ //int m_nPlaylistCurPos;
+ //int m_nPlaylistLength;
+ //int m_nTrackPlaying;
+ //int m_nSongPosMS;
+ //int m_nSongLenMS;
+ bool m_bUserPagedUp;
+ bool m_bUserPagedDown;
+ float m_fMotionVectorsTempDx;
+ float m_fMotionVectorsTempDy;
+
+ td_waitstr m_waitstring;
+ void WaitString_NukeSelection();
+ void WaitString_Cut();
+ void WaitString_Copy();
+ void WaitString_Paste();
+ void WaitString_SeekLeftWord();
+ void WaitString_SeekRightWord();
+ int WaitString_GetCursorColumn();
+ int WaitString_GetLineLength();
+ void WaitString_SeekUpOneLine();
+ void WaitString_SeekDownOneLine();
+
+ int m_nPresets; // the # of entries in the file listing. Includes directories and then files, sorted alphabetically.
+ int m_nDirs; // the # of presets that are actually directories. Always between 0 and m_nPresets.
+ int m_nPresetListCurPos;// Index of the currently-HIGHLIGHTED preset (the user must press Enter on it to select it).
+ int m_nCurrentPreset; // Index of the currently-RUNNING preset.
+ // Note that this is NOT the same as the currently-highlighted preset! (that's m_nPresetListCurPos)
+ // Be careful - this can be -1 if the user changed dir. & a new preset hasn't been loaded yet.
+ wchar_t m_szCurrentPresetFile[512]; // w/o path. this is always valid (unless no presets were found)
+ PresetList m_presets;
+ void UpdatePresetList(bool bBackground=false, bool bForce=false, bool bTryReselectCurrentPreset=true);
+ wchar_t m_szUpdatePresetMask[MAX_PATH];
+ bool m_bPresetListReady;
+ //void UpdatePresetRatings();
+ //int m_nRatingReadProgress; // equals 'm_nPresets' if all ratings are read in & ready to go; -1 if uninitialized; otherwise, it's still reading them in, and range is: [0 .. m_nPresets-1]
+ bool m_bInitialPresetSelected;
+
+ // PRESET HISTORY
+ #define PRESET_HIST_LEN (64+2) // make this 2 more than the # you REALLY want to be able to go back.
+ GString m_presetHistory[PRESET_HIST_LEN]; //circular
+ int m_presetHistoryPos;
+ int m_presetHistoryBackFence;
+ int m_presetHistoryFwdFence;
+ void PrevPreset(float fBlendTime);
+ void NextPreset(float fBlendTime); // if not retracing our former steps, it will choose a random one.
+ void OnFinishedLoadingPreset();
+
+ FFT myfft;
+ td_mysounddata mysound;
+
+ // stuff for displaying text to user:
+ //int m_nTextHeightPixels; // this is for the menu/detail font; NOT the "fancy font"
+ //int m_nTextHeightPixels_Fancy;
+ bool m_bShowFPS;
+ bool m_bShowRating;
+ bool m_bShowPresetInfo;
+ bool m_bShowDebugInfo;
+ bool m_bShowSongTitle;
+ bool m_bShowSongTime;
+ bool m_bShowSongLen;
+ float m_fShowRatingUntilThisTime;
+ //float m_fShowUserMessageUntilThisTime;
+ //char m_szUserMessage[512];
+ //bool m_bUserMessageIsError;
+
+ #define ERR_ALL 0
+ #define ERR_INIT 1 //specifically, loading a preset
+ #define ERR_PRESET 2 //specifically, loading a preset
+ #define ERR_MISC 3
+ #define ERR_NOTIFY 4 // a simple notification - not an error at all. ("shuffle is now ON." etc.)
+ // NOTE: each NOTIFY msg clears all the old NOTIFY messages!
+ #define ERR_SCANNING_PRESETS 5
+ ErrorMsgList m_errors;
+ void AddError(wchar_t* szMsg, float fDuration, int category=ERR_ALL, bool bBold=true);
+ void ClearErrors(int category=ERR_ALL); // 0=all categories
+
+ char m_szDebugMessage[512];
+ wchar_t m_szSongTitle [512];
+ wchar_t m_szSongTitlePrev[512];
+ //HFONT m_hfont[3]; // 0=fancy font (for song titles, preset name)
+ // 1=legible font (the main font)
+ // 2=tooltip font (for tooltips in the menu system)
+ //HFONT m_htitlefont[NUM_TITLE_FONTS]; // ~25 different sizes
+ // stuff for menu system:
+ CMilkMenu *m_pCurMenu; // should always be valid!
+ CMilkMenu m_menuPreset;
+ CMilkMenu m_menuWave;
+ CMilkMenu m_menuAugment;
+ CMilkMenu m_menuCustomWave;
+ CMilkMenu m_menuCustomShape;
+ CMilkMenu m_menuMotion;
+ CMilkMenu m_menuPost;
+ CMilkMenu m_menuWavecode[MAX_CUSTOM_WAVES];
+ CMilkMenu m_menuShapecode[MAX_CUSTOM_SHAPES];
+ bool m_bShowShaderHelp;
+
+
+
+ wchar_t m_szMilkdrop2Path[MAX_PATH]; // ends in a backslash
+ wchar_t m_szMsgIniFile[MAX_PATH];
+ wchar_t m_szImgIniFile[MAX_PATH];
+ wchar_t m_szPresetDir[MAX_PATH];
+ float m_fRandStart[4];
+
+ // DIRECTX 9:
+ IDirect3DTexture9 *m_lpVS[2];
+ #define NUM_BLUR_TEX 6
+ #if (NUM_BLUR_TEX>0)
+ IDirect3DTexture9 *m_lpBlur[NUM_BLUR_TEX]; // each is successively 1/2 size of prev.
+ int m_nBlurTexW[NUM_BLUR_TEX];
+ int m_nBlurTexH[NUM_BLUR_TEX];
+ #endif
+ int m_nHighestBlurTexUsedThisFrame;
+ IDirect3DTexture9 *m_lpDDSTitle; // CAREFUL: MIGHT BE NULL (if not enough mem)!
+ int m_nTitleTexSizeX, m_nTitleTexSizeY;
+ MYVERTEX *m_verts;
+ MYVERTEX *m_verts_temp;
+ td_vertinfo *m_vertinfo;
+ int *m_indices_strip;
+ int *m_indices_list;
+
+ // for final composite grid:
+ #define FCGSX 32 // final composite gridsize - # verts - should be EVEN.
+ #define FCGSY 24 // final composite gridsize - # verts - should be EVEN.
+ // # of grid *cells* is two less,
+ // since we have redundant verts along the center line in X and Y (...for clean 'ang' interp)
+ MYVERTEX m_comp_verts[FCGSX*FCGSY];
+ int m_comp_indices[(FCGSX-2)*(FCGSY-2)*2*3];
+
+ bool m_bMMX;
+ //bool m_bSSE;
+ bool m_bHasFocus;
+ bool m_bHadFocus;
+ bool m_bOrigScrollLockState;
+ //bool m_bMilkdropScrollLockState; // saved when focus is lost; restored when focus is regained
+
+ int m_nNumericInputMode; // NUMERIC_INPUT_MODE_CUST_MSG, NUMERIC_INPUT_MODE_SPRITE
+ int m_nNumericInputNum;
+ int m_nNumericInputDigits;
+ td_custom_msg_font m_CustomMessageFont[MAX_CUSTOM_MESSAGE_FONTS];
+ td_custom_msg m_CustomMessage[MAX_CUSTOM_MESSAGES];
+
+ texmgr m_texmgr; // for user sprites
+
+ td_supertext m_supertext; // **contains info about current Song Title or Custom Message.**
+
+ IDirect3DTexture9 *m_tracer_tex;
+
+ int m_nFramesSinceResize;
+
+ char m_szShaderIncludeText[32768]; // note: this still has char 13's and 10's in it - it's never edited on screen or loaded/saved with a preset.
+ int m_nShaderIncludeTextLen; // # of chars, not including the final NULL.
+ char m_szDefaultWarpVShaderText[32768]; // THIS HAS CHAR 13/10 CONVERTED TO LINEFEED_CONTROL_CHAR
+ char m_szDefaultWarpPShaderText[32768]; // THIS HAS CHAR 13/10 CONVERTED TO LINEFEED_CONTROL_CHAR
+ char m_szDefaultCompVShaderText[32768]; // THIS HAS CHAR 13/10 CONVERTED TO LINEFEED_CONTROL_CHAR
+ char m_szDefaultCompPShaderText[32768]; // THIS HAS CHAR 13/10 CONVERTED TO LINEFEED_CONTROL_CHAR
+ char m_szBlurVS[32768];
+ char m_szBlurPSX[32768];
+ char m_szBlurPSY[32768];
+ //const char* GetDefaultWarpShadersText() { return m_szDefaultWarpShaderText; }
+ //const char* GetDefaultCompShadersText() { return m_szDefaultCompShaderText; }
+ void GenWarpPShaderText(char *szShaderText, float decay, bool bWrap);
+ void GenCompPShaderText(char *szShaderText, float brightness, float ve_alpha, float ve_zoom, int ve_orient, float hue_shader, bool bBrighten, bool bDarken, bool bSolarize, bool bInvert);
+
+ //====[ 2. methods added: ]=====================================================================================
+
+ void RefreshTab2(HWND hwnd);
+ void RenderFrame(int bRedraw);
+ void AlignWave(int nSamples);
+
+ void DrawTooltip(wchar_t* str, int xR, int yB);
+ void RandomizeBlendPattern();
+ void GenPlasma(int x0, int x1, int y0, int y1, float dt);
+ void LoadPerFrameEvallibVars(CState* pState);
+ void LoadCustomWavePerFrameEvallibVars(CState* pState, int i);
+ void LoadCustomShapePerFrameEvallibVars(CState* pState, int i, int instance);
+ void WriteRealtimeConfig(); // called on Finish()
+ void dumpmsg(wchar_t *s);
+ void Randomize();
+ void LoadRandomPreset(float fBlendTime);
+ void LoadPreset(const wchar_t *szPresetFilename, float fBlendTime);
+ void LoadPresetTick();
+ void FindValidPresetDir();
+ //char* GetConfigIniFile() { return m_szConfigIniFile; };
+ wchar_t* GetMsgIniFile() { return m_szMsgIniFile; };
+ wchar_t* GetPresetDir() { return m_szPresetDir; };
+ void SavePresetAs(wchar_t *szNewFile); // overwrites the file if it was already there.
+ void DeletePresetFile(wchar_t *szDelFile);
+ void RenamePresetFile(wchar_t *szOldFile, wchar_t *szNewFile);
+ void SetCurrentPresetRating(float fNewRating);
+ void SeekToPreset(wchar_t cStartChar);
+ bool ReversePropagatePoint(float fx, float fy, float *fx2, float *fy2);
+ int HandleRegularKey(WPARAM wParam);
+ bool OnResizeGraphicsWindow();
+ bool OnResizeTextWindow();
+ //bool InitFont();
+ //void ToggleControlWindow(); // for Desktop Mode only
+ //void DrawUI();
+ void ClearGraphicsWindow(); // for windowed mode only
+ //bool Update_Overlay();
+ //void UpdatePlaylist();
+ void LaunchCustomMessage(int nMsgNum);
+ void ReadCustomMessages();
+ void LaunchSongTitleAnim();
+
+ bool RenderStringToTitleTexture();
+ void ShowSongTitleAnim(/*IDirect3DTexture9* lpRenderTarget,*/ int w, int h, float fProgress);
+ void DrawWave(float *fL, float *fR);
+ void DrawCustomWaves();
+ void DrawCustomShapes();
+ void DrawSprites();
+ void ComputeGridAlphaValues();
+ //void WarpedBlit();
+ // note: 'bFlipAlpha' just flips the alpha blending in fixed-fn pipeline - not the values for culling tiles.
+ void WarpedBlit_Shaders (int nPass, bool bAlphaBlend, bool bFlipAlpha, bool bCullTiles, bool bFlipCulling);
+ void WarpedBlit_NoShaders(int nPass, bool bAlphaBlend, bool bFlipAlpha, bool bCullTiles, bool bFlipCulling);
+ void ShowToUser_Shaders (int nPass, bool bAlphaBlend, bool bFlipAlpha, bool bCullTiles, bool bFlipCulling);
+ void ShowToUser_NoShaders();
+ void BlurPasses();
+ void GetSafeBlurMinMax(CState* pState, float* blur_min, float* blur_max);
+ void RunPerFrameEquations(int code);
+ void DrawUserSprites();
+ void MergeSortPresets(int left, int right);
+ void BuildMenus();
+ void SetMenusForPresetVersion(int WarpPSVersion, int CompPSVersion);
+ //void ResetWindowSizeOnDisk();
+ bool LaunchSprite(int nSpriteNum, int nSlot);
+ void KillSprite(int iSlot);
+ void DoCustomSoundAnalysis();
+ void DrawMotionVectors();
+
+ bool LoadShaders(PShaderSet* sh, CState* pState, bool bTick);
+ void UvToMathSpace(float u, float v, float* rad, float* ang);
+ void ApplyShaderParams(CShaderParams* p, LPD3DXCONSTANTTABLE pCT, CState* pState);
+ void RestoreShaderParams();
+ bool AddNoiseTex(const wchar_t* szTexName, int size, int zoom_factor);
+ bool AddNoiseVol(const wchar_t* szTexName, int size, int zoom_factor);
+
+
+ //====[ 3. virtual functions: ]===========================================================================
+
+ virtual void OverrideDefaults();
+ virtual void MyPreInitialize();
+ virtual void MyReadConfig();
+ virtual void MyWriteConfig();
+ virtual int AllocateMyNonDx9Stuff();
+ virtual void CleanUpMyNonDx9Stuff();
+ virtual int AllocateMyDX9Stuff();
+ virtual void CleanUpMyDX9Stuff(int final_cleanup);
+ virtual void MyRenderFn(int redraw);
+ virtual void MyRenderUI(int *upper_left_corner_y, int *upper_right_corner_y, int *lower_left_corner_y, int *lower_right_corner_y, int xL, int xR);
+ virtual LRESULT MyWindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
+ virtual BOOL MyConfigTabProc(int nPage, HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ virtual void OnAltK();
+
+ //====[ 4. methods from base class: ]===========================================================================
+ /*
+ // 'GET' METHODS
+ // ------------------------------------------------------------
+ int GetFrame(); // returns current frame # (starts at zero)
+ float GetTime(); // returns current animation time (in seconds) (starts at zero) (updated once per frame)
+ float GetFps(); // returns current estimate of framerate (frames per second)
+ eScrMode GetScreenMode(); // returns WINDOWED, FULLSCREEN, FAKE_FULLSCREEN, or NOT_YET_KNOWN (if called before or during OverrideDefaults()).
+ HWND GetWinampWindow(); // returns handle to Winamp main window
+ HINSTANCE GetInstance(); // returns handle to the plugin DLL module; used for things like loading resources (dialogs, bitmaps, icons...) that are built into the plugin.
+ char* GetPluginsDirPath(); // usually returns 'c:\\program files\\winamp\\plugins\\'
+ char* GetConfigIniFile(); // usually returns 'c:\\program files\\winamp\\plugins\\something.ini' - filename is determined from identifiers in 'defines.h'
+
+ // GET METHODS THAT ONLY WORK ONCE DIRECTX IS READY
+ // ------------------------------------------------------------
+ // The following 'Get' methods are only available after DirectX has been initialized.
+ // If you call these from OverrideDefaults, MyPreInitialize, or MyReadConfig,
+ // they will fail and return NULL (zero).
+ // ------------------------------------------------------------
+ HWND GetPluginWindow(); // returns handle to the plugin window. NOT persistent; can change.
+ int GetWidth(); // returns width of plugin window interior, in pixels.
+ int GetHeight(); // returns height of plugin window interior, in pixels.
+ D3DFORMAT GetBackBufFormat(); // returns the pixelformat of the back buffer (probably D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_A4R4G4B4, D3DFMT_R3G3B2, D3DFMT_A8R3G3B2, D3DFMT_X4R4G4B4, or D3DFMT_UNKNOWN)
+ D3DFORMAT GetBackBufZFormat(); // returns the pixelformat of the back buffer's Z buffer (probably D3DFMT_D16_LOCKABLE, D3DFMT_D32, D3DFMT_D15S1, D3DFMT_D24S8, D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D24X4S4, or D3DFMT_UNKNOWN)
+ D3DCAPS8* GetCaps(); // returns a pointer to the D3DCAPS8 structer for the device. NOT persistent; can change.
+ LPDIRECT3DDEVICE8 GetDevice(); // returns a pointer to the DirectX 8 Device. NOT persistent; can change.
+
+ // FONTS & TEXT
+ // ------------------------------------------------------------
+ LPD3DXFONT GetFont(eFontIndex idx); // returns a handle to a D3DX font you can use to draw text on the screen
+ int GetFontHeight(eFontIndex idx); // returns the height of the font, in pixels
+
+ // MISC
+ // ------------------------------------------------------------
+ td_soundinfo m_sound; // a structure always containing the most recent sound analysis information; defined in pluginshell.h.
+ void SuggestHowToFreeSomeMem(); // gives the user a 'smart' messagebox that suggests how they can free up some video memory.
+ */
+ //=====================================================================================================================
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin.rc b/Src/Plugins/Visualization/vis_milk2/plugin.rc
new file mode 100644
index 00000000..aff9fb84
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin.rc
@@ -0,0 +1,1501 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_CONFIG DIALOGEX 0, 0, 390, 292
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "(window title will be assigned at runtime)"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_HOTTRACK | WS_TABSTOP,6,7,324,255
+ CONTROL "",IDC_RECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE,8,20,320,240
+ DEFPUSHBUTTON "OK",IDOK,335,19,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,335,35,50,13
+ PUSHBUTTON "Defaults",ID_DEFAULTS,335,51,50,13
+ PUSHBUTTON "View Docs",ID_DOCS,335,67,50,13
+ PUSHBUTTON "View Website",ID_WEB,335,83,50,13
+ CTEXT "For help on any setting, click the '?' in the upper-right\rcorner, and then click the item you need help with.",IDC_STATIC,6,268,186,19,SS_SUNKEN
+ CTEXT "(...'about' text will be placed in this box automatically, at runtime)",IDC_SZ_ABOUT,198,268,187,19,SS_SUNKEN
+END
+
+IDD_PROPPAGE_2 DIALOGEX 0, 0, 320, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "[ More Settings: ]",IDC_FS_BOX,0,3,319,236
+ RTEXT "Canvas Stretch:",IDC_STRETCH_CAPTION,5,33,56,10
+ COMBOBOX IDC_STRETCH,67,30,99,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "<-- use if your graphics chip (GPU) is slow !!",IDC_STATIC,169,33,144,8
+ RTEXT "Mesh Size:",IDC_MESHSIZECOMBO_CAPTION,19,49,43,10
+ COMBOBOX IDC_MESHSIZECOMBO,67,47,99,123,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "<-- decrease if your processor (CPU) is slow !!",IDC_STATIC,168,50,150,8
+ RTEXT "Pixel Shaders:",IDC_SHADERS_CAPTION,13,67,49,10
+ COMBOBOX IDC_SHADERS,67,64,99,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "<-- don't touch this.",IDC_STATIC,168,67,144,8
+ RTEXT "Canvas Size:",IDC_TEXSIZECOMBO_CAPTION,19,84,43,10
+ COMBOBOX IDC_TEXSIZECOMBO,67,81,99,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "<-- don't touch this.",IDC_STATIC,168,84,144,8
+ CONTROL "Start milkdrop with preset lock [scroll lock key] ON",IDC_CB_SCROLLON,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,22,116,175,10
+ CONTROL "Disable preset rating (...all presets have equal chance)",IDC_CB_NORATING,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,22,129,192,10
+ CONTROL "Suppress all errors/warnings (for VJ'ing)",IDC_CB_NOWARN2,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,142,143,10
+ CONTROL "Prevent milkdrop from controlling the scroll lock key [default: OFF]",IDC_CB_SCROLLON2,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,22,155,227,10
+ GROUPBOX "Brightness control for 16-bit-color video modes",IDC_BRIGHT_SLIDER_BOX,8,182,180,49
+ CONTROL "Slider1",IDC_BRIGHT_SLIDER,"msctls_trackbar32",WS_TABSTOP,25,193,89,14
+ CTEXT "0\r\n(bright)",IDC_T1,20,207,25,17
+ CTEXT "2\r\n(normal)",IDC_T3,54,207,28,18
+ CTEXT "3",IDC_T4,83,207,8,10
+ CTEXT "4\r\n(dark)",IDC_T5,91,207,30,18
+ CONTROL "guess,\r\nbased on my video card",IDC_CB_AUTOGAMMA,
+ "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,129,194,54,30
+ CONTROL "Scan presets instantly @ startup/dir. change (can cause a pause)",IDC_CB_INSTASCAN,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,207,197,100,17
+ CONTROL "Stereo 3D mode Always ON",IDC_CB_ALWAYS3D,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,203,207,103,10
+ CONTROL "Use anisotropic filtering (if available) instead of bilinear interpolation",IDC_CB_ANISO,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,203,203,99,10
+ CTEXT "1",IDC_T2,46,207,8,10
+ COMBOBOX IDC_TEXFORMAT,205,197,99,87,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Texture Format:",IDC_TEXFORMAT_CAPTION,201,198,55,10,NOT WS_VISIBLE | WS_DISABLED
+END
+
+IDD_PROPPAGE_1 DIALOGEX 0, 0, 320, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "",IDC_STATIC,0,0,319,239
+ RTEXT "Display Adapter:",IDC_DMS_ADAPTER_CAPTION,68,12,53,9
+ COMBOBOX IDC_ADAPTER_DMS,126,9,185,191,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CTEXT "\rDESKTOP MODE\rsettings",IDC_DMS_LABEL,3,17,60,38
+ RTEXT "Max Framerate:",IDC_DMS_MAXFPS_CAPTION,63,28,58,9
+ COMBOBOX IDC_DMS_MAXFPS,126,25,81,106,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "More &Options",ID_DM_MORE,261,25,50,15
+ RTEXT "Multisampling:",IDC_DMS_MULTISAMPLING_CAPTION,5,43,46,9,NOT WS_VISIBLE | WS_DISABLED
+ COMBOBOX IDC_DMSMS,56,41,81,123,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Allow Page Tearing",IDC_CB_DMSPT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,43,77,10
+ CONTROL "",IDC_STATIC,"Static",SS_GRAYRECT,0,58,318,1
+ RTEXT "Display Adapter:",IDC_FS_ADAPTER_CAPTION,68,66,53,9
+ COMBOBOX IDC_ADAPTER_FS,126,63,185,208,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CTEXT "FULLSCREEN settings",IDC_FS_LABEL,7,85,50,18
+ RTEXT "Display Mode:",IDC_DISP_MODE_CAPTION,66,81,55,9
+ COMBOBOX IDC_DISP_MODE,126,78,185,208,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Max Framerate:",IDC_FS_MAXFPS_CAPTION,66,96,55,9
+ COMBOBOX IDC_FS_MAXFPS,126,94,81,107,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Multisampling:",IDC_FS_MULTISAMPLING_CAPTION,4,112,47,9,NOT WS_VISIBLE | WS_DISABLED
+ COMBOBOX IDC_FSMS,56,110,81,123,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Allow Page Tearing",IDC_CB_FSPT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,112,77,10
+ CONTROL "Use Fa&ke fullscreen mode",IDC_CB_FAKE,"Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,214,112,97,10
+ CONTROL "",IDC_STATIC,"Static",SS_GRAYRECT,0,127,318,1
+ RTEXT "Display Adapter:",IDC_W_ADAPTER_CAPTION,68,135,53,9
+ COMBOBOX IDC_ADAPTER_W,126,132,185,208,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CTEXT "WINDOWED settings",IDC_W_LABEL,7,145,46,18
+ RTEXT "Max Framerate:",IDC_W_MAXFPS_CAPTION,56,151,65,9
+ COMBOBOX IDC_W_MAXFPS,126,148,81,107,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ RTEXT "Multisampling:",IDC_W_MULTISAMPLING_CAPTION,5,165,46,9,NOT WS_VISIBLE | WS_DISABLED
+ COMBOBOX IDC_WMS,56,163,81,123,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Allow Page Tearing",IDC_CB_WPT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,126,165,77,10
+ CONTROL "Integrate with winamp skin",IDC_CB_SKIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,214,164,102,10
+ CONTROL "",IDC_STATIC,"Static",SS_GRAYRECT,0,180,318,1
+ LTEXT "Start in...",IDC_STATIC,9,192,61,8
+ CONTROL "&Fullscreen",IDC_CB_FS,"Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,9,203,48,10
+ CONTROL "&Desktop Mode",IDC_CB_DMS,"Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,9,215,61,10
+ CONTROL "Sa&ve CPU by loosely enforcing Max Framerate",IDC_CB_SAVE_CPU,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,78,185,164,10
+ CONTROL "Show '&Press F1 for Help' message at startup",IDC_CB_PRESS_F1_MSG,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,78,195,159,10
+ CONTROL "&Minimize Winamp when going fullscreen",IDC_CB_MIN,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,78,205,141,10
+ CONTROL "Try to fix slow menus/text (uses more video memory)",IDC_CB_FIXSLOWTEXT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,78,215,183,10
+ CONTROL "V&J MODE - show text, menus in a second window",IDC_CB_VJMODE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,78,225,173,10
+ PUSHBUTTON "Dual&Head",ID_DUALHEAD,262,200,50,15
+ PUSHBUTTON "&Select Fonts",ID_FONTS,262,217,50,15
+END
+
+IDD_PROPPAGE_3 DIALOGEX 0, 0, 320, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Image cache:",IDC_BRIGHT_SLIDER_BOX2,5,4,140,83
+ LTEXT "Max # Images:",IDC_MAX_IMAGES_CAPTION,16,17,49,10
+ COMBOBOX IDC_MAX_IMAGES,74,14,60,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Max Video Mem:",IDC_MAX_BYTES_CAPTION,16,34,55,10
+ COMBOBOX IDC_MAX_BYTES,74,31,60,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Note: cache settings are only relevant if you've put gobs of textures into your milkdrop2\\textures\\ folder. Otherwise, everything fits in 1 MB of VRAM.",IDC_STATIC,13,49,126,33
+ PUSHBUTTON "Edit &Sprites",ID_SPRITE,11,93,82,15
+ PUSHBUTTON "&Edit Custom Messages",ID_MSG,11,110,82,15
+ GROUPBOX "Song Title Animations and Custom Messages",IDC_STATIC,5,130,169,104
+ LTEXT "(seconds)",IDC_STATIC,137,140,33,9
+ RTEXT "Duration of song title animations:",IDC_SONGTITLEANIM_DURATION_LABEL,20,153,110,10
+ EDITTEXT IDC_SONGTITLEANIM_DURATION,136,151,32,13,ES_AUTOHSCROLL
+ RTEXT "Time between\r\nRANDOM song title anims",IDC_RAND_TITLE_LABEL,34,166,96,17
+ EDITTEXT IDC_RAND_TITLE,136,169,32,13,ES_AUTOHSCROLL
+ RTEXT "Time between\r\nRANDOM custom messages",IDC_RAND_MSG_LABEL,34,185,96,17
+ EDITTEXT IDC_RAND_MSG,136,188,32,13,ES_AUTOHSCROLL
+ CONTROL "Automatically show song title anims when song changes?",IDC_CB_TITLE_ANIMS,
+ "Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,41,207,114,18
+ GROUPBOX "Colored-lens 3D glasses",IDC_STATIC,212,66,104,58,NOT WS_VISIBLE | WS_DISABLED
+ PUSHBUTTON "Set &right eye lens color",IDRIGHT,226,76,82,14,NOT WS_VISIBLE | WS_DISABLED
+ PUSHBUTTON "Set &left eye lens color",IDLEFT,216,83,82,14,NOT WS_VISIBLE | WS_DISABLED
+ RTEXT "Default stereo separation (normal=1):",IDC_3DSEP_LABEL,196,101,119,10,NOT WS_VISIBLE | WS_DISABLED
+ EDITTEXT IDC_3DSEP,260,97,32,13,ES_AUTOHSCROLL | NOT WS_VISIBLE | WS_DISABLED
+ GROUPBOX "VJ Mode",IDC_STATIC,188,129,127,63,NOT WS_VISIBLE | WS_DISABLED
+ CONTROL "Enable &VJ Mode (creates a second window for text input and output and leaves the graphics display text-free; use this in conjunction w/multimon for live shows)",IDC_CB_SEPTEXT,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,194,143,121,44
+END
+
+IDD_PROPPAGE_4 DIALOGEX 0, 0, 320, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Soft Cuts (regular, periodic preset transitions/fades)",IDC_STATIC,5,7,187,96
+ RTEXT "Time between auto preset changes:",IDC_BETWEEN_TIME_LABEL,20,25,116,10
+ EDITTEXT IDC_BETWEEN_TIME,142,23,32,13,ES_AUTOHSCROLL
+ RTEXT "Additional random time:",IDC_BETWEEN_TIME_RANDOM_LABEL,33,39,103,10
+ EDITTEXT IDC_BETWEEN_TIME_RANDOM,142,38,32,13,ES_AUTOHSCROLL
+ RTEXT "Auto preset blend time:",IDC_BLEND_AUTO_LABEL,34,55,102,10
+ EDITTEXT IDC_BLEND_AUTO,142,53,32,13,ES_AUTOHSCROLL
+ RTEXT "User-solicited preset blend time:",IDC_BLEND_USER_LABEL,26,70,110,10
+ EDITTEXT IDC_BLEND_USER,142,68,32,13,ES_AUTOHSCROLL
+ LTEXT "(seconds)",IDC_STATIC,142,83,33,10
+ GROUPBOX "Hard Cuts (driven by major beats)",IDC_STATIC,5,106,187,91
+ RTEXT "Average time between hard cuts:",IDC_HARDCUT_BETWEEN_TIME_LABEL,20,119,116,10
+ EDITTEXT IDC_HARDCUT_BETWEEN_TIME,142,117,32,13,ES_AUTOHSCROLL
+ LTEXT "(seconds)",IDC_STATIC,142,132,33,10
+ LTEXT "Loudness threshold:",IDC_HARDCUT_LOUDNESS_LABEL,31,139,71,9
+ CTEXT "min",IDC_HARDCUT_LOUDNESS_MIN,37,151,14,9
+ CONTROL "Slider1",IDC_HARDCUT_LOUDNESS,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,51,150,114,16
+ CTEXT "max",IDC_HARDCUT_LOUDNESS_MAX,165,151,16,9
+ CONTROL "&Disable hard cuts",IDC_CB_HARDCUTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,33,171,72,13
+END
+
+IDD_PROPPAGE_5 DIALOGEX 0, 0, 320, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+END
+
+#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
+#if defined(APSTUDIO_INVOKED)
+IDD_PROPPAGE_6$(DISABLED) DIALOGEX 0, 0, 320, 240
+#else
+IDD_PROPPAGE_6 DIALOGEX 0, 0, 320, 240
+#endif
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
+#if defined(APSTUDIO_INVOKED)
+IDD_PROPPAGE_7$(DISABLED) DIALOGEX 0, 0, 320, 240
+#else
+IDD_PROPPAGE_7 DIALOGEX 0, 0, 320, 240
+#endif
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(DISABLED)
+#if defined(APSTUDIO_INVOKED)
+IDD_PROPPAGE_8$(DISABLED) DIALOGEX 0, 0, 320, 240
+#else
+IDD_PROPPAGE_8 DIALOGEX 0, 0, 320, 240
+#endif
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+END
+#endif
+
+IDD_FONTDIALOG DIALOGEX 0, 0, 354, 175
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_NOPARENTNOTIFY
+CAPTION "Select Fonts"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "Typeset:",IDC_FONT_CAPTION,85,4,109,9
+ LTEXT "Size:",IDC_FONTSIZE_CAPTION,217,4,50,10
+ LTEXT "Bold",IDC_FONTOPTIONS_CAPTION,290,4,16,10
+ LTEXT "Italics",IDC_FONTOPTIONS_CAPTION2,311,4,20,10
+ LTEXT "AA",IDC_FONTOPTIONS_CAPTION3,336,4,11,10
+ RTEXT "Simple font:",IDC_FONT_NAME_1,7,16,70,9
+ COMBOBOX IDC_FONT1,85,13,127,291,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE1,217,13,65,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,293,16,9,9
+ CONTROL "",IDC_FONTITAL1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,315,16,9,9
+ CONTROL "",IDC_FONTAA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,337,16,9,9
+ RTEXT "Decorative font:",IDC_FONT_NAME_2,7,32,70,9
+ COMBOBOX IDC_FONT2,85,29,127,291,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE2,217,29,65,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,293,32,9,9
+ CONTROL "",IDC_FONTITAL2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,315,32,9,9
+ CONTROL "",IDC_FONTAA2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,337,32,9,9
+ RTEXT "Help screen:",IDC_FONT_NAME_3,7,48,70,9
+ COMBOBOX IDC_FONT3,85,45,127,291,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE3,217,45,65,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,293,48,9,9
+ CONTROL "",IDC_FONTITAL3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,315,48,9,9
+ CONTROL "",IDC_FONTAA3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,337,48,9,9
+ RTEXT "Playlist:",IDC_FONT_NAME_4,7,65,70,9
+ COMBOBOX IDC_FONT4,85,61,127,291,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE4,217,61,65,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,293,64,9,9
+ CONTROL "",IDC_FONTITAL4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,315,64,9,9
+ CONTROL "",IDC_FONTAA4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,337,64,9,9
+ RTEXT "Font 5:",IDC_FONT_NAME_5,7,80,70,9,NOT WS_VISIBLE
+ COMBOBOX IDC_FONT5,85,77,127,291,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE5,217,77,65,87,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD5,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,293,80,9,9
+ CONTROL "",IDC_FONTITAL5,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,315,80,9,9
+ CONTROL "",IDC_FONTAA5,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,337,80,9,9
+ RTEXT "Font 6:",IDC_FONT_NAME_6,7,96,70,9,NOT WS_VISIBLE
+ COMBOBOX IDC_FONT6,85,93,127,291,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE6,217,93,65,87,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD6,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,293,96,9,9
+ CONTROL "",IDC_FONTITAL6,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,315,96,9,9
+ CONTROL "",IDC_FONTAA6,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,337,96,9,9
+ RTEXT "Font 7:",IDC_FONT_NAME_7,7,112,70,9,NOT WS_VISIBLE
+ COMBOBOX IDC_FONT7,85,109,127,291,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE7,217,109,65,87,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD7,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,293,112,9,9
+ CONTROL "",IDC_FONTITAL7,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,315,112,9,9
+ CONTROL "",IDC_FONTAA7,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,337,112,9,9
+ RTEXT "Font 8:",IDC_FONT_NAME_8,7,128,70,9,NOT WS_VISIBLE
+ COMBOBOX IDC_FONT8,85,125,127,291,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE8,217,125,65,87,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD8,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,293,128,9,9
+ CONTROL "",IDC_FONTITAL8,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,315,128,9,9
+ CONTROL "",IDC_FONTAA8,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,337,128,9,9
+ RTEXT "Font 9:",IDC_FONT_NAME_9,7,144,70,9,NOT WS_VISIBLE
+ COMBOBOX IDC_FONT9,85,141,127,291,CBS_DROPDOWNLIST | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_FONTSIZE9,217,141,65,87,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_FONTBOLD9,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,293,144,9,9
+ CONTROL "",IDC_FONTITAL9,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,315,144,9,9
+ CONTROL "",IDC_FONTAA9,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,337,144,9,9
+ CTEXT "Note: 'AA' stands for anti-aliasing (smoothing); not always available.",IDC_FONT_TEXT,7,160,235,8,SS_CENTERIMAGE
+ DEFPUSHBUTTON "OK",IDOK,246,158,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,300,158,50,13
+END
+
+IDD_DESKTOPMODE DIALOGEX 0, 0, 201, 105
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_NOPARENTNOTIFY | WS_EX_CONTEXTHELP
+CAPTION "More Options for Desktop Mode"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Show icons",IDC_CB_SHOW_ICONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,4,51,10
+ CONTROL "Draw colored boxes around icon text labels",IDC_CB_BOX,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,16,154,10
+ CONTROL "My desktop icons get occluded (covered) by the taskbar when I use Desktop Mode; fix it!",IDC_CB_MANUAL_SCOOT,
+ "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,4,28,184,18
+ LTEXT "When Windows is in [5-6-5] 16-bit color and there is no\ralpha (transparency) channel, try drawing the icons using...",IDC_DM_ALPHA_FIX_CAPTION,4,50,193,17
+ COMBOBOX IDC_DM_ALPHA_FIX,4,71,193,291,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK",IDOK,91,88,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,147,88,50,13
+END
+
+IDD_DUALHEAD DIALOGEX 0, 0, 304, 164
+STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_NOPARENTNOTIFY
+CAPTION "Dualhead Options"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ LTEXT "Typically, multimon (ie. multiple monitor) setups feature two separate video cards and two separate monitors; each resulting display has its own resolution, and the desktop spans across them in some fashion.",IDC_STATIC,4,4,296,26
+ LTEXT "DualHead video cards, though, feature a single card that feeds two monitors. Some of these cards treat the two monitors separately, but some of them treat them as halves of a single double-width (~2048x768) or double-height (~1024x1536) 'virtual screen'.",IDC_STATIC,4,34,296,26
+ GROUPBOX "For Desktop and *Fake* Fullscreen modes:",IDC_STATIC,4,64,150,96
+ LTEXT "When a single virtual display spans two real screens Horizontally:",IDC_STATIC,10,75,137,18
+ COMBOBOX IDC_H_PICK,16,96,104,91,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "When a single virtual display spans two real screens Vertically:",IDC_STATIC,10,113,137,18
+ COMBOBOX IDC_V_PICK,16,134,104,67,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "As a result, graphics applications can't go 'fullscreen' on just one monitor, because it's really only half of the 'screen', from Windows' point of view.",IDC_STATIC,159,64,141,32
+ LTEXT "This plug-in, however, will let you get away with it, when you're in Desktop Mode or *Fake* Fullscreen Mode; it just needs to know which half of the display (left/right or top/bottom) you want to use -- or both.",IDC_STATIC,159,100,141,42
+ DEFPUSHBUTTON "OK",IDOK,196,147,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,250,147,50,13
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_CONFIG, DIALOG
+ BEGIN
+ LEFTMARGIN, 6
+ RIGHTMARGIN, 385
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 287
+ END
+
+ IDD_FONTDIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 350
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 171
+ END
+
+ IDD_DESKTOPMODE, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 197
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 101
+ END
+
+ IDD_DUALHEAD, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 300
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 160
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_WINDOWED_CONTEXT_MENU MENU
+BEGIN
+ POPUP "Options:"
+ BEGIN
+ MENUITEM "&Fullscreen\tAlt+Enter", ID_GO_FS
+ MENUITEM "&Desktop Mode\tAlt+D", ID_DESKTOP_MODE
+ MENUITEM SEPARATOR
+ MENUITEM "Show &Help\tF1", ID_SHOWHELP
+ MENUITEM "Show Playlist\tP", ID_SHOWPLAYLIST
+ MENUITEM SEPARATOR
+ MENUITEM "&Quit", ID_QUIT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_PLUGIN_ICON ICON "plugin_icon.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXT
+//
+
+IDR_TEXT1 TEXT "text1.bin"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,25,4,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Visualization Plug-in"
+ VALUE "FileVersion", "2,25,4,0"
+ VALUE "InternalName", "Nullsoft Milkdrop v2"
+ VALUE "LegalCopyright", "Copyright © 2001-2023 Winamp SA"
+ VALUE "OriginalFilename", "vis_milk2.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ 65535 "{C5D175F1-E4E4-47ee-B85C-4EDC6B026A35}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ABOUT_STRING "%s by %s\n%s"
+ IDS_SZ_MENU_NAV_TOOLTIP "navigation: ESC: exit, Left Arrow: back, Right Arrow: select, UP/DOWN: change sel"
+ IDS_UNTITLED_MENU_ITEM "<untitled menu item>"
+ IDS_UNTITLED_MENU "<untitled menu>"
+ IDS_ON "ON"
+ IDS_OFF "OFF"
+ IDS_USE_UP_DOWN_ARROW_KEYS
+ "(use up/down arrow keys, PGUP, PGDN to change value)"
+ IDS_CURRENT_VALUE_OF_X "Current value of %s:"
+ IDS_LOAD_FROM_FILE "Load from file: [note: preset's wave scaling, as well as q1-q8, will not be imported]"
+ IDS_SAVE_TO_FILE "Save to file: [note: preset's wave scaling, as well as q1-q8, will not be exported]"
+ IDS_ENTER_THE_NEW_STRING
+ "Enter the new string; hit CTRL+ENTER to apply or ESC to cancel."
+ IDS_MILKDROP_ERROR "MILKDROP ERROR"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_THIS_PLUGIN_NEEDS_MUSIC_TO_RUN
+ "This plug-in cannot run without music.\n\nPlease play some music, through Winamp, and then try running the plug-in again."
+ IDS_NO_MUSIC_PLAYING "No Music Playing"
+ IDS_UNABLE_TO_READ_DATA_FILE_X "Unable to read the data file:\n %s"
+ IDS_COULD_NOT_CREATE_MY_VERTEX_DECLARATION
+ "Could not create my vertex declaration"
+ IDS_COULD_NOT_CREATE_WF_VERTEX_DECLARATION
+ "Could not create WF vertex declaration"
+ IDS_COULD_NOT_CREATE_SPRITE_VERTEX_DECLARATION
+ "Could not create sprite vertex declaration"
+ IDS_SHADER_MODEL_2 "shader model 2.0"
+ IDS_SHADER_MODEL_3 "shader model 3.0"
+ IDS_SHADER_MODEL_4 "shader model 4.0"
+ IDS_UKNOWN_CASE_X "(unknown case: %d)"
+ IDS_FAILED_TO_COMPILE_PIXEL_SHADERS_USING_X
+ "Failed to compile pixel shaders using %s [PSVersion=0x%X].\n\nAfter hitting OK here, please return to the config panel (ALT+K),\ngo to the second tab, and for the Pixel Shaders option, select Auto."
+ IDS_FAILED_TO_COMPILE_PIXEL_SHADERS_HARDWARE_MIS_REPORT
+ "Your hardware says that it supports %s [PSVersion=0x%X],\nbut it doesn't seem to do it properly -\nmaybe your display driver is just buggy.\n\nYou might want to try updating your display driver\nto the latest WHQL driver from the chipset manufacturer\n(Nvidia, ATI, etc.)."
+ IDS_COULD_NOT_COMPILE_FALLBACK_WV_SHADER
+ "Could not compile fallback warp vertex shader"
+ IDS_COULD_NOT_COMPILE_FALLBACK_CV_SHADER
+ "Could not compile fallback comp vertex shader"
+ IDS_COULD_NOT_COMPILE_FALLBACK_CP_SHADER
+ "Could not compile fallback comp pixel shader"
+ IDS_COULD_NOT_COMPILE_BLUR1_VERTEX_SHADER
+ "Could not compile blur1 vertex shader"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_DXC_ERR_CAPSFAIL "DirectX initialization failed (GetDeviceCaps).\n\nThis means that no valid 3D-accelerated display adapter could be found\non your computer.\nIf you know this is not the case, it is possible that your graphics\nsubsystem is temporarily unstable; please try rebooting your computer,\nand then try to run the plug-in again. Otherwise, please install a\n3D-accelerated display adapter."
+ IDS_FS_DISPLAY_MODE_SELECTED_IS_INVALID
+ "The fullscreen display mode selected from the config panel\nwas invalid, for some reason. For now, the closest match\n(to the old selection) will be used.\n\nTo fix this, please return to the config panel and select a new\nfullscreen display mode.\n\nThe plug-in will now run using the best match..."
+ IDS_CREATEWINDOW_FAILED "CreateWindow failed"
+ IDS_TRYING_TO_ENTER_FS_MODE_WITH_MULTIPLE_DISPLAYS
+ "You are trying to enter fullscreen mode while running\nmultiple displays in a vertical or horizontal span,\nwithout using 'Fake Fullscreen Mode'. As a result,\n--the image will be stretched over both displays.--\n\nIf you would prefer the plug-in to appear on only one display\n(and still be free to operate on the other display),\nplease return to the config panel, enable 'Fake Fullscreen\nMode', click the 'DualHead' button to configure your DualHead\nsetup, and then try again.\n\nHit OK to proceed, or Cancel to exit now."
+ IDS_TIP "Tip"
+ IDS_TRYING_TO_ENTER_FS_MODE_WITH_MULTIPLE_DISPLAYS_2
+ "You are trying to enter fullscreen mode while running\nmultiple displays in a vertical or horizontal span,\nbut the display mode you are entering does not stretch\nover both displays. As a result, --the image will only\nappear on one display, and the other display will be disabled.--\n\nThere are two alternatives:\n\n1. To make the fullscreen image appear on only ONE display\nAND still be free to operate on the other display,\nplease return to the config panel and enable 'Fake Fullscreen Mode',\nthen click 'DualHead' to select which screen you'd like the\nplug-in to occupy. (--RECOMMENDED--)\n\n2. To make the fullscreen image stretch across BOTH displays,\nreturn to the config panel and select a display mode that\nspans both displays (such as 2048 x 768, or 1024 x 1536).\n\nHit OK to continue, or Cancel to exit now."
+ IDS_UNABLE_TO_CREATE_DIRECTX_DEVICE
+ "Unable to create a DirectX device. (D3DERR_NOTAVAILABLE)\n\nThis could mean that you've chosen a combination of settings that is\nnot available on your video card. Try resetting the plug-in to its\ndefault settings (via the config panel's 'Default' button), and then\ntry running the plug-in again.\n\nYou might also want to close all other applications, to make sure they're\nnot interfering.\n\nIf you have made any changes to your graphics subsystem since your\nlast reboot (such as updating video drivers, installing new software,\netc.), or have witnessed any strange behaviors, TRY REBOOTING first.\n\n"
+ IDS_OLDER_DISPLAY_ADAPTER_CATENATION
+ "NOTE: If you are trying to run the plug-in on an older display adapter\n(such as a Voodoo3 card), try going to the config panel (ALT+K)\nand selecting a fullscreen display mode of a different color depth;\nand selecting a fullscreen display mode of a different color depth;\nsome of these older cards can only do 3D in particular color depths\n(such as 16-bit color, for the Voodoo 3).\n"
+ IDS_OLDER_DISPLAY_ADAPTER_CATENATION_2
+ "NOTE: If you are trying to run the plug-in on an older display adapter\n(such as a Voodoo3 card), try changing the color depth that Windows\nis running in; some of these cards can only do 3D in particular color depths\n(such as 16-bit color, for the Voodoo3).\n"
+ IDS_DIRECTX_INIT_FAILED_X
+ "DirectX initialization failed (CreateDevice; code %d)\n\nOften this means you don't have enough free video memory.\n"
+ IDS_WINDOW_RESIZE_FAILED
+ "Window resize failed.\n\nOften this means the application ran out of video memory;\n perhaps you tried to make the window too large."
+ IDS_OUT_OF_VIDEO_MEMORY "OUT OF VIDEO MEMORY"
+ IDS_ERROR_CREATING_GDI_FONTS "Error creating GDI fonts"
+ IDS_ERROR_LOADING_MAIN_MENU "Error loading main menu"
+ IDS_ERROR_LOADING_CONTEXT_MENU "Error loading context menu"
+ IDS_ERROR_CREATING_DIRECT3D_DEVICE_FOR_VJ_MODE
+ "Error invoking Direct3D 9 for VJ mode;\nDirectX 9 could be missing or corrupt."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_COULD_NOT_COMPILE_BLUR1_PIXEL_SHADER
+ "Could not compile blur1 pixel shader"
+ IDS_COULD_NOT_COMPILE_BLUR2_VERTEX_SHADER
+ "Could not compile blur2 vertex shader"
+ IDS_COULD_NOT_COMPILE_BLUR2_PIXEL_SHADER
+ "Could not compile blur2 pixel shader"
+ IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_SMALLER_DISPLAY
+ "Could not create internal canvas texture! (probably not enough video memory left)\ntry selecting a smaller display mode, or decreasing the color bit depth."
+ IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_NOT_ENOUGH_VID_MEM_RECOMMENDATION
+ "Could not create internal canvas texture! (probably not enough video memory left)\n\n\nRECOMMENDATION: SET THE INTERNAL CANVAS SIZE BACK TO 'AUTO' AND TRY AGAIN"
+ IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_NOT_ENOUGH_VID_MEM
+ "Could not create internal canvas texture! (probably not enough video memory left)\n"
+ IDS_SUCCESSFULLY_CREATED_VS0_VS1
+ "Successfully created VS0/VS1 at %d x %d (ideal: %d x %d)"
+ IDS_ERROR_CREATING_BLUR_TEXTURES
+ "Error creating blur textures - probably not enough video memory."
+ IDS_COULD_NOT_CREATE_NOISE_TEXTURE "Could not create noise texture"
+ IDS_COULD_NOT_LOCK_NOISE_TEXTURE "Could not lock noise texture"
+ IDS_NOISE_TEXTURE_BYTE_LAYOUT_NOT_RECOGNISED
+ "Noise texture byte layout not recognized"
+ IDS_COULD_NOT_CREATE_3D_NOISE_TEXTURE "Could not create 3D noise texture"
+ IDS_COULD_NOT_LOCK_3D_NOISE_TEXTURE "Could not lock 3D noise texture"
+ IDS_3D_NOISE_TEXTURE_BYTE_LAYOUT_NOT_RECOGNISED
+ "3D noise texture byte layout not recognized"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MILKDROP_WARNING "MILKDROP WARNING"
+ IDS_ERROR_CREATING_DOUBLE_SIZED_GDI_TITLE_FONT
+ "Error creating double-sized GDI title font"
+ IDS_ERROR_CREATING_DOUBLE_SIZED_D3DX_TITLE_FONT
+ "Error creating double-sized d3dx title font"
+ IDS_RATING "Rating"
+ IDS_DISABLED "[disabled] "
+ IDS_ARE_YOU_SURE_YOU_WANT_TO_DELETE_PRESET
+ "Are you SURE you want to delete this preset? [y/N]"
+ IDS_PRESET_TO_DELETE "(preset to delete: %s)"
+ IDS_FILE_ALREADY_EXISTS_OVERWRITE_IT
+ "This file already exists. Overwrite it? [y/N]"
+ IDS_FILE_IN_QUESTION_X_MILK "(file in question: %s.milk)"
+ IDS_ERROR_NO_PRESET_FILE_FOUND_IN_X_MILK
+ "ERROR: No preset files found in %s*.milk"
+ IDS_LOAD_WHICH_PRESET_PLUS_COMMANDS
+ "Load which preset? (arrow keys to scroll; Esc/close, Enter/select, INS/rename; DEL/delete)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ERROR_CREATING_SHADER "Error creating shader:\n"
+ IDS_PLEASE_EXIT_VIS_BEFORE_RUNNING_CONFIG_PANEL
+ "Please exit the visualizer before running the config panel."
+ IDS_FPS "fps"
+ IDS_PF_MONITOR "pf monitor"
+ IDS_PRESS_F9_TO_HIDE_SHADER_QREF
+ "-- press F9 to hide shader Quick Reference --\n"
+ IDS_PRESS_F9_TO_SHOW_SHADER_QREF
+ "-- press F9 to show shader Quick Reference --\n"
+ IDS_WARP_AND_COMPOSITE_SHADERS_LOCKED
+ "(keep in mind... warp and composite shaders were locked.)"
+ IDS_WARP_SHADER_LOCKED "(keep in mind... warp shader was locked.)"
+ IDS_COMPOSITE_SHADER_LOCKED
+ "(keep in mind... composite shader was locked.)"
+ IDS_PRESET_USES_HIGHEST_PIXEL_SHADER_VERSION
+ "This preset already uses the highest pixel shader version (%d) supported by your graphics chip."
+ IDS_PRESET_HAS_MIXED_VERSIONS_OF_SHADERS
+ "This preset has mixed versions of shaders in it."
+ IDS_UPGRADE_SHADERS_TO_USE_PS2
+ "Do you want to upgrade all shaders to use (at least) pixel shader 2? [y/N]"
+ IDS_UPGRADE_SHADERS_TO_USE_PS3
+ "Do you want to upgrade all shaders to use (at least) pixel shader 3? [y/N]"
+ IDS_PRESET_DOES_NOT_USE_PIXEL_SHADERS
+ "This preset does not currently use pixel shaders."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_UPGRADE_TO_USE_PS2 "Do you want to upgrade it to use pixel shader 2? [y/N]"
+ IDS_WARNING_OLD_GPU_MIGHT_NOT_WORK_WITH_PRESET
+ " (WARNING: if you save it, other users with older graphics chips might not be able to use the preset."
+ IDS_PRESET_CURRENTLY_USES_PS2 "This preset currently uses pixel shader 2."
+ IDS_UPGRADE_TO_USE_PS3 "Do you want to upgrade it to use pixel shader 3? [y/N]"
+ IDS_PRESET_CURRENTLY_USES_PS3 "This preset currently uses pixel shader 3."
+ IDS_UPGRADE_TO_USE_PS4 "Do you want to upgrade it to use pixel shader 4? [y/N]"
+ IDS_WARNING_DO_NOT_FORGET_WARP_SHADER_WAS_LOCKED
+ " WARNING: do not forget WARP shader was LOCKED! "
+ IDS_WARNING_DO_NOT_FORGET_COMPOSITE_SHADER_WAS_LOCKED
+ " WARNING: do not forget COMPOSITE shader was LOCKED! "
+ IDS_PRESET_MASH_UP_TEXT1
+ "Preset Mash-Up: use keys 1-5 to change bin;"
+ IDS_PRESET_CURRENTLY_USES_PS2X
+ "This preset currently uses pixel shader 2.X."
+ IDS_UPGRADE_TO_USE_PS2X "Do you want to upgrade it to use pixel shader 2.X? [y/N]"
+ IDS_PRESET_MASH_UP_TEXT2
+ " up/down/a-z to browse presets for current bin;"
+ IDS_PRESET_MASH_UP_TEXT3
+ " h to randomize preset (or H = all bins); "
+ IDS_PRESET_MASH_UP_TEXT4 " esc exits."
+ IDS_DIRECTORY_OF_X "Directory of: %s"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_PAGE_X_OF_X " (page %d of %d) "
+ IDS_LOCKED "<locked> "
+ IDS_ILLEGAL_CHARACTER "(illegal character)"
+ IDS_STRING_TOO_LONG "(string too long)"
+ IDS_DIRECTORY_TO_JUMP_TO "Directory to jump to:"
+ IDS_ERROR_IMPORTING_BAD_FILENAME
+ "(error importing - bad filename, or file does not exist)"
+ IDS_ERROR_IMPORTING_BAD_FILENAME_OR_NOT_OVERWRITEABLE
+ "(error exporting - bad filename, or file can not be overwritten)"
+ IDS_INVALID_PATH "(invalid path)"
+ IDS_ENTER_THE_NEW_NAME_FOR_X "Enter the new name for ""%s"":"
+ IDS_PRESET_ORDER_IS_NOW_X "preset order is now %s"
+ IDS_SEQUENTIAL "SEQUENTIAL"
+ IDS_RANDOM "RANDOM"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SHUFFLE_IS_NOW_OFF "shuffle is now OFF"
+ IDS_SHUFFLE_IS_NOW_ON "shuffle is now ON"
+ IDS_COMPSHADER_LOCKED "COMP SHADER LOCKED."
+ IDS_WARPSHADER_LOCKED "WARP SHADER LOCKED."
+ IDS_ALLSHADERS_LOCKED "ALL SHADERS LOCKED."
+ IDS_ALLSHADERS_UNLOCKED "ALL SHADERS UNLOCKED."
+ IDS_PS_AUTO_RECOMMENDED " Auto (Recommended)"
+ IDS_PS_DISABLED " Disabled"
+ IDS_PS_SHADER_MODEL_2 " Shader Model 2"
+ IDS_PS_SHADER_MODEL_3 " Shader Model 3"
+ IDS_TX_8_BITS_PER_CHANNEL " 8 bits per channel"
+ IDS_TX_16_BITS_PER_CHANNEL " 16 bits - CAREFUL"
+ IDS_TX_32_BITS_PER_CHANNEL " 32 bits - CAREFUL"
+ IDS_160X120_SLOW "160 x 120 SLOW "
+ IDS_192X144_SLOW "192 x 144 SLOW "
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SAVE_AS "Save as:"
+ IDS_AUTO " Auto "
+ IDS_8X6_FAST " 8 x 6 FAST "
+ IDS_16X12_FAST " 16 x 12 fast "
+ IDS_24X18 " 24 x 18 "
+ IDS_32X24 " 32 x 24 "
+ IDS_40X30 " 40 x 30 "
+ IDS_48X36_DEFAULT " 48 x 36 (default)"
+ IDS_64X48_SLOW " 64 x 48 "
+ IDS_80X60_SLOW " 80 x 60 slow "
+ IDS_96X72_SLOW " 96 x 72 SLOW "
+ IDS_128X96_SLOW "128 x 96 SLOW "
+ IDS_ERROR_IN_SHELLEXECUTE "error in ShellExecute"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NONE_BEST_IMAGE_QUALITY " None (best image quality) "
+ IDS_1_25_X " 1.25 X "
+ IDS_1_33_X " 1.33 X "
+ IDS_1_5_X " 1.5 X (...2x faster)"
+ IDS_1_67_X " 1.67 X (...3x faster)"
+ IDS_2_X " 2 X (...4x faster)"
+ IDS_3_X " 3 X (...9x faster)"
+ IDS_4_X " 4 X (...16x faster) "
+ IDS_NEAREST_POWER_OF_2 " Nearest power of 2 "
+ IDS_EXACT_RECOMMENDED " Exact (Recommended) "
+ IDS_PIXEL_SHADERS "Pixel Shaders"
+ IDS_PIXEL_SHADERS_TEXT "MilkDrop 1 did not use programmable pixel shaders - instead,\nit used the fixed-function graphics pipeline. If your graphics chip\nis older and doesn't support pixel shaders, or doesn't support the\nideal pixel shader version (2.0) for MilkDrop 2, then this should be\nauto-detected without a problem, and MilkDrop will simply skip over\nany presets that can't run on your graphics chip. (These presets will\nalso be hidden from view, in the preset list.)\n\nIf you'd like to force MilkDrop to try and allow higher (or lower)\nversions of pixel shaders, use this option.\n\nFinally, if you want to prevent MilkDrop from running any pixel shader 3,\npresets (because it's too slow for them), you can just set this option\nto version 2.0, and MilkDrop will avoid those presets."
+ IDS_TEXFORMAT "Texture Format"
+ IDS_TEXFORMAT_TEXT "This determines the precision of the colors that you see.\nHigher bit depths are better. A bit depth of 8, for example,\nmeans that in the graphics hardware, the image can have 2^8, or 256,\npossible shades (each) of red, green, and blue.\n\nA bit depth of 8 looks decent, but 16 is much better.\nHOWEVER, only high-end video cards (as of 2007) usually support\nit properly. Older cards can't do 'bilinear interpolation'\nwith 16-bit render targets, meaning that the image will get\nvery grainy and 'digital' looking, so PLEASE WATCH OUT FOR THIS.\n\n32 bits is excessive and slow, don't ever use it.\n\nNote that your monitor can only show 256 shades of each color;\nhowever, if the internal image (that is repeatedly warped and modified\nfrom frame to frame) has better color precision (~16 bits), then \nthe colors in the image will maintain their fidelity as they slowly\nerode and warp, over time."
+ IDS_CANVAS_SIZE "Canvas Size"
+ IDS_CANVAS_SIZE_TEXT "This sets the size of the image that milkdrop uses, internally,\nto drive the visuals. The bigger the value here, the crisper\nthe image you see. It's highly recommended that you set this\nto 'auto', which will determine the ideal image (texture) size\nautomatically. However, if you experience visual problems (such\nas black streaks or missing chunks in the image) due to low\nvideo memory, you might want to set this to a low value (like\n256x256 or 512x512).\n\n'Auto (exact)' means the internal texture size will exactly match\nthe number of pixels on the screen - this is the ideal case.\nIf that doesn't work, try 'Auto (nearest power of 2)' - some older\nvideo cards will have better luck with this option."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CANVAS_STRETCH "Canvas Stretch"
+ IDS_CANVAS_STRETCH_TEXT "MilkDrop works with an internal texture, or canvas, to do all of\nits graphics rendering. The speed (framerate) that MilkDrop runs\nat is inversely proportional to the number of pixels that are in\nthis canvas. So, to render things internally at a smaller resolution,\nbut stretch them up for display, you can use this option. It will\nmake the image look a bit softer and less crisp or detailed,\nbut - especially for older graphics hardware - things will run\nmuch faster.\n\nKeep in mind, a stretch factor of 2X, for example, means that there\nwill be half as manypixels to simulate on both the X and Y axes, \nso MilkDrop will actually run FOUR TIMES as fast. With a stretch\nfactor of 3X, it will run 9X as fast (hypothetically). And so on."
+ IDS_MAX_IMAGES_BYTES_TEXT
+ "This option is only relevant if you've put tons of new textures in your \nwinamp\\plugins\\milkdrop2\\textures directory. If you have (say you\nset up some kind of art kiosk with thousands of large images), this\noption lets you tweak how much video RAM MilkDrop will try to use to\ncache textures. The only point of cacheing textures is so that \nwhen loading a new preset, if the preset needs to load textures,\nif they were already loaded once and are still cached in memory, \nthe load will be much smoother.\n\nGo ahead and crank this up; MilkDrop's core internal textures will\nalways take precedence over disk textures anyway, so it's pretty safe."
+ IDS_MENU_EDIT_WARP_SHADER "[ edit warp shader ]"
+ IDS_MENU_EDIT_COMPOSITE_SHADER "[ edit composite shader ]"
+ IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT "blur1: edge darken amount"
+ IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT_TT
+ "keep this >0.25 to avoid edge artifacts, and <1.0 to avoid black borders."
+ IDS_MENU_BLUR1_MIN_COLOR_VALUE "blur1: min color value"
+ IDS_MENU_BLUR1_MIN_COLOR_VALUE_TT
+ "narrowing these to just the color range you need will greatly increase color fidelity in the blurred images."
+ IDS_MENU_BLUR1_MAX_COLOR_VALUE "blur1: max color value"
+ IDS_MENU_BLUR1_MAX_COLOR_VALUE_TT
+ "narrowing these to just the color range you need will greatly increase color fidelity in the blurred images."
+ IDS_MENU_BLUR2_MIN_COLOR_VALUE "blur2: min color value"
+ IDS_MENU_BLUR2_MIN_COLOR_VALUE_TT
+ "narrowing these to just the color range you need will greatly increase color fidelity in the blurred images. MUST BE SUBSET OF BLUR1 RANGE."
+ IDS_MENU_BLUR2_MAX_COLOR_VALUE "blur2: max color value"
+ IDS_MENU_BLUR2_MAX_COLOR_VALUE_TT
+ "narrowing these to just the color range you need will greatly increase color fidelity in the blurred images. MUST BE SUBSET OF BLUR1 RANGE."
+ IDS_MENU_BLUR3_MIN_COLOR_VALUE "blur3: min color value"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MESH_SIZE "Mesh Size"
+ IDS_MESH_SIZE_TEXT "MilkDrop uses a mesh of polygons to warp the image each frame.\nThis setting determines how finely subdivided that mesh is.\nA larger mesh size will mean finer resolution 'movement' in the\nimage; basically, it will look better. Watch out, though - \nonly crank this way up if you have a fast CPU."
+ IDS_CB_ALWAYS3D "Enable this to force all presets to be displayed in 3D mode.\n(Note that you need glasses with differently-colored lenses\n to see the effect.)"
+ IDS_DISABLE_PRESET_RATING "Disable preset rating"
+ IDS_DISABLE_PRESET_RATING_TEXT
+ "Check this to turn off the preset rating system. Normally, when MilkDrop\ngoes to randomly select a preset, it weights them based on their ratings.\nHowever, if you want all presets to have an equal chance of being chosen,\ncheck this box."
+ IDS_CB_NOWARN2 "Check this to disable any & all warning messages that appear in the\nupper-right corner of the screen."
+ IDS_START_WITH_PRESET_LOCK_ON "Start with preset lock ON"
+ IDS_START_WITH_PRESET_LOCK_ON_TEXT
+ "Check this to make MilkDrop automatically start in 'preset lock' mode,\nmeaning that the preset will not change until the user changes it\nmanually (either by pressing SPACE, hitting H for a hard cut, or by\nselecting a new preset from the 'L'oad menu).\n\nUse the SCROLL LOCK key while MilkDrop is running to toggle the preset\nlock on or off. When the SCROLL LOCK light is on, that means that the\npreset lock is also on, and vice versa."
+ IDS_BRIGHT_SLIDER "The brightness slider lets you control the overall brightness\nof the image. If the image is continually washed out to bright\npurple or white, you'll want to crank this down to (probably) zero.\nIf the image is chronically dark, crank this up.\n\nNote that the slider is not visible when the nearby 'guess'\ncheckbox is checked. Uncheck it to manually set the brightness.\n\nAlso note that this brightness adjustment is only a concern in\n16-bit color modes. (32-bit doesn't have this problem.) So,\nif you're running Windows in 16-bit color, this slider will affect\nwindowed, desktop, and 'fake' fullscreen modes. And if you've\nselected a 16-bit fullscreen display mode, it will affect that\ntoo."
+ IDS_CB_AUTOGAMMA "Check this option to ask milkdrop to make an educated guess\nfor the 'brightness control for 16-bit color' setting, based\non the vendor of your video card. This usually gets it, but\nnot always.\n\nThe slider is only visible when this option is unchecked.\n\nSee the help for the slider for more information."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SPRITE "Click this button to edit milk_img.ini, the file that defines\nall of the custom sprites you can invoke for display while\nmilkdrop is running. A sprite is an image that you can fade\nin or our, move around, and so on."
+ IDS_MSG "Click this button to edit milk_msg.ini, the file that you can\nconfigure to set up custom overlaid text messages that you can\ndisplay while milkdrop is running."
+ IDS_SONGTITLEANIM_DURATION_TEXT
+ "The duration, in seconds, of song title animations."
+ IDS_RAND_TITLE_TEXT "The mean (average) time, in seconds, between randomly-launched\nsong title animations. Set to a negative value to disable random\nlaunching."
+ IDS_RAND_MSG_TEXT "The mean (average) time, in seconds, between randomly-launched\ncustom messages (from milk_msg.ini). Set to a negative value\nto disable random launching."
+ IDS_TITLE_ANIMS_TEXT "Check this to automatically launch song title animations whenever\nthe track changes."
+ IDS_BETWEEN_TIME_TEXT "The minimum amount of time that elapses between preset changes\n(excluding hard cuts, which take priority). The old preset will\nbegin to blend or fade into a new preset after this amount of time,\nplus some random amount of time as specified below in the\n'additional random time' box. Add these two values together to\nget the maximum amount of time that will elapse between preset\nchanges."
+ IDS_BETWEEN_TIME_RANDOM_TEXT
+ "The additional random maximum # of seconds between preset fades\n(aka preset changes) (aka soft cuts)."
+ IDS_BLEND_AUTO_TEXT "The duration, in seconds, of a soft cut (a normal fade from one preset\nto another) that is initiated because some amount of time has passed.\nA value less than 1 will make for a very quick transition, while a value\naround 3 or 4 will allow you to see some interesting behavior during\nthe blend."
+ IDS_BLEND_USER_TEXT "The duration, in seconds, of a soft cut (a normal fade from one preset\nto another) that is initiated by you, when you press the 'H' key (for\na Hard cut). A value less than 1 will make for a very quick transition,\nwhile a value around 3 or 4 will allow you to see some interesting behavior\nduring the blend."
+ IDS_HARDCUT_BETWEEN_TIME_TEXT
+ "The amount of time, in seconds, between hard cuts. Hard cuts are\nset off by loud beats in the music, with (ideally) about this much\ntime in between them."
+ IDS_HARDCUT_LOUDNESS_TEXT
+ "Use this slider to adjust the sensitivity of the beat detection\nalgorithm used to detect the beats that cause hard cuts. A value\nclose to 'min' will cause the algorithm to be very sensitive (so\neven small beats will trigger it); a value close to 'max' will\ncause only the largest beats to trigger it."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_CB_HARDCUTS "Check this to disable hard cuts; a loud beat\nwill never cause the preset to change."
+ IDS_EDIT_CURRENT_PRESET "--edit current preset"
+ IDS_MOTION "--MOTION"
+ IDS_DRAWING_CUSTOM_SHAPES "--drawing: custom shapes"
+ IDS_DRAWING_CUSTOM_WAVES "--drawing: custom waves"
+ IDS_DRAWING_SIMPLE_WAVEFORM "--drawing: simple waveform"
+ IDS_DRAWING_BORDERS_MOTION_VECTORS "--drawing: borders, motion vectors"
+ IDS_POST_PROCESSING_MISC "--post-processing, misc."
+ IDS_CUSTOM_WAVE_X "--custom wave %d"
+ IDS_CUSTOM_SHAPE_X "--custom shape %d"
+ IDS_MENU_EDIT_PRESET_INIT_CODE "[ edit preset initialization code ]"
+ IDS_MENU_EDIT_PRESET_INIT_CODE_TT
+ "read-only: zoom, rot, warp, cx, cy, dx, dy, sx, sy; decay, gamma;\n echo_zoom, echo_scale, echo_orient;\n ib_{size|r|g|b|a}, ob_{size|r|g|b|a}, mv_{x|y|dx|dy|l|r|g|b|a};\n wave_{r|g|b|a|x|y|mode|mystery|usedots|thick|additive|brighten};\n darken_center, wrap; invert, brighten, darken, solarize\n time, fps, frame, progress; {bass|mid|treb}[_att]\nwrite: q1-q8, monitor"
+ IDS_MENU_EDIT_PER_FRAME_EQUATIONS "[ edit per_frame equations ]"
+ IDS_MENU_EDIT_PER_FRAME_EQUATIONS_TT
+ "read-only: time, fps, frame, progress; {bass|mid|treb}[_att]\nread/write: zoom, rot, warp, cx, cy, dx, dy, sx, sy; q1-q8; monitor\n mv_{x|y|dx|dy|l|r|g|b|a}, ib_{size|r|g|b|a}, ob_{size|r|g|b|a};\n wave_{r|g|b|a|x|y|mode|mystery|usedots|thick|additive|brighten};\n darken_center, wrap; invert, brighten, darken, solarize\n decay, gamma, echo_zoom, echo_alpha, echo_orient"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_ROTATION_AMOUNT_TT
+ "controls the amount of rotation. 0=none, 0.1=slightly right, -0.1=slightly clockwise, 0.1=CCW"
+ IDS_MENU_ROTATION_CENTER_OF_X " rot., center of (X)"
+ IDS_MENU_ROTATION_CENTER_OF_X_TT
+ "controls where the center of rotation is, horizontally. 0=left, 0.5=center, 1=right"
+ IDS_MENU_ROTATION_CENTER_OF_Y " rot., center of (Y)"
+ IDS_MENU_ROTATION_CENTER_OF_Y_TT
+ "controls where the center of rotation is, vertically. 0=top, 0.5=center, 1=bottom"
+ IDS_MENU_TRANSLATION_X "translation (X)"
+ IDS_MENU_TRANSLATION_X_TT
+ "controls amount of constant horizontal motion; -0.01 = slight shift right, 0=none, 0.01 = to left"
+ IDS_MENU_TRANSLATION_Y "translation (Y)"
+ IDS_MENU_TRANSLATION_Y_TT
+ "controls amount of constant vertical motion; -0.01 = slight shift downward, 0=none, 0.01 = upward"
+ IDS_MENU_SCALING_X "scaling (X)"
+ IDS_MENU_SCALING_X_TT "controls amount of constant horizontal stretching; 0.99=shrink, 1=normal, 1.01=stretch"
+ IDS_MENU_SCALING_Y "scaling (Y)"
+ IDS_MENU_SCALING_Y_TT "controls amount of constant vertical stretching; 0.99=shrink, 1=normal, 1.01=stretch"
+ IDS_MENU_SUSTAIN_LEVEL "sustain level"
+ IDS_MENU_SUSTAIN_LEVEL_TT
+ "controls the eventual fade to black; 1=no fade, 0.9=strong fade; 0.98=recommended."
+ IDS_MENU_DARKEN_CENTER "darken center"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_DARKEN_CENTER_TT
+ "when ON, help keeps the image from getting too bright by continually dimming the center point"
+ IDS_MENU_GAMMA_ADJUSTMENT "gamma adjustment"
+ IDS_MENU_GAMMA_ADJUSTMENT_TT
+ "controls brightness; 1=normal, 2=double, 3=triple, etc."
+ IDS_MENU_HUE_SHADER "hue shader"
+ IDS_MENU_HUE_SHADER_TT "adds subtle color variations to the image. 0=off, 1=fully on"
+ IDS_MENU_VIDEO_ECHO_ALPHA "video echo: alpha"
+ IDS_MENU_VIDEO_ECHO_ALPHA_TT
+ "controls the opacity of the second graphics layer; 0=transparent (off), 0.5=half-mix, 1=opaque"
+ IDS_MENU_VIDEO_ECHO_ZOOM " video echo: zoom"
+ IDS_MENU_VIDEO_ECHO_ZOOM_TT
+ "controls the size of the second graphics layer"
+ IDS_MENU_VIDEO_ECHO_ORIENTATION " video echo: orientation"
+ IDS_MENU_VIDEO_ECHO_ORIENTATION_TT
+ "selects an orientation for the second graphics layer. 0=normal, 1=flip on x, 2=flip on y, 3=flip on both"
+ IDS_MENU_TEXTURE_WRAP "texture wrap"
+ IDS_MENU_TEXTURE_WRAP_TT
+ "sets whether or not screen elements can drift off of one side and onto the other"
+ IDS_MENU_FILTER_INVERT "filter: invert"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_FILTER_INVERT_TT "inverts the colors in the image"
+ IDS_MENU_FILTER_BRIGHTEN "filter: brighten"
+ IDS_MENU_FILTER_BRIGHTEN_TT
+ "brightens the darker parts of the image (nonlinear; square root filter)"
+ IDS_MENU_FILTER_DARKEN "filter: darken"
+ IDS_MENU_FILTER_DARKEN_TT
+ "darkens the brighter parts of the image (nonlinear; squaring filter)"
+ IDS_MENU_FILTER_SOLARIZE "filter: solarize"
+ IDS_MENU_FILTER_SOLARIZE_TT "emphasizes mid-range colors"
+ IDS_MENU_ENABLED "enabled"
+ IDS_MENU_ENABLED_TT "enables or disables this custom waveform/spectrum"
+ IDS_MENU_NUMBER_OF_SAMPLES "number of samples"
+ IDS_MENU_NUMBER_OF_SAMPLES_TT
+ "the number of samples (points) that makes up the waveform"
+ IDS_MENU_L_R_SEPARATION "L/R separation"
+ IDS_MENU_L_R_SEPARATION_TT
+ "the offset between the left & right channels; useful for doing phase plots. Keep low (<32) when using w/spectrum."
+ IDS_MENU_SCALING "scaling"
+ IDS_MENU_SCALING_TT "the size of the wave (1=normal)"
+ IDS_MENU_SMOOTHING_TT "0=the raw wave; 1=a highly damped (smoothed) wave"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_WAVE_TYPE "wave type"
+ IDS_MENU_WAVE_TYPE_TT "each value represents a different way of drawing the waveform"
+ IDS_MENU_SIZE "size"
+ IDS_MENU_SIZE_TT "relative size of the waveform"
+ IDS_MENU_SMOOTH "smoothing"
+ IDS_MENU_SMOOTH_TT "controls the smoothness of the waveform; 0=natural sound data (no smoothing), 0.9=max. smoothing"
+ IDS_MENU_MYSTERY_PARAMETER "mystery parameter"
+ IDS_MENU_MYSTERY_PARAMETER_TT
+ "what this one does is a secret (actually, its effect depends on the 'wave type'"
+ IDS_MENU_POSITION_X "position (X)"
+ IDS_MENU_POSITION_X_TT "position of the waveform: 0 = far left edge of screen, 0.5 = center, 1 = far right"
+ IDS_MENU_POSITION_Y "position (Y)"
+ IDS_MENU_POSITION_Y_TT "position of the waveform: 0 = very bottom of screen, 0.5 = center, 1 = top"
+ IDS_MENU_COLOR_RED "color (red)"
+ IDS_MENU_COLOR_RED_TT "amount of red color in the wave (0..1)"
+ IDS_MENU_COLOR_GREEN "color (green)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_COLOR_GREEN_TT "amount of green color in the wave (0..1)"
+ IDS_MENU_COLOR_BLUE "color (blue)"
+ IDS_MENU_COLOR_BLUE_TT "amount of blue color in the wave (0..1)"
+ IDS_MENU_OPACITY "opacity"
+ IDS_MENU_OPACITY_TT "opacity of the waveform; lower numbers = more transparent"
+ IDS_MENU_USE_DOTS "use dots"
+ IDS_MENU_USE_DOTS_TT "if true, the waveform is drawn as dots (instead of lines)"
+ IDS_MENU_DRAW_THICK "draw thick"
+ IDS_MENU_DRAW_THICK_TT "if true, the waveform's lines (or dots) are drawn with double thickness"
+ IDS_MENU_MODULATE_OPACITY_BY_VOLUME "modulate opacity by volume"
+ IDS_MENU_MODULATE_OPACITY_BY_VOLUME_TT
+ "if true, the waveform opacity is affected by the music's volume"
+ IDS_MENU_MODULATION_TRANSPARENT_VOLUME "modulation: transparent volume"
+ IDS_MENU_MODULATION_TRANSPARENT_VOLUME_TT
+ "when the relative volume hits this level, the wave becomes transparent. 1 = normal loudness, 0.5 = extremely quiet, 1.5 = extremely loud"
+ IDS_MENU_MODULATION_OPAQUE_VOLUME "modulation: opaque volume"
+ IDS_MENU_MODULATION_OPAQUE_VOLUME_TT
+ "when the relative volume hits this level, the wave becomes opaque. 1 = normal loudness, 0.5 = extremely quiet, 1.5 = extremely loud"
+ IDS_MENU_ADDITIVE_DRAWING "additive drawing"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_ADDITIVE_DRAWING_TT
+ "if true, the wave is drawn additively, saturating the image at white"
+ IDS_MENU_COLOR_BRIGHTENING "color brightening"
+ IDS_MENU_COLOR_BRIGHTENING_TT
+ "if true, the red, green, and blue color components will be scaled up until at least one of them reaches 1.0"
+ IDS_MENU_OUTER_BORDER_THICKNESS "outer border thickness"
+ IDS_MENU_OUTER_BORDER_THICKNESS_TT
+ "thickness of the outer border drawn at the edges of the screen"
+ IDS_MENU_COLOR_RED_OUTER " color (red)"
+ IDS_MENU_COLOR_RED_OUTER_TT "amount of red color in the outer border"
+ IDS_MENU_COLOR_GREEN_OUTER " color (green)"
+ IDS_MENU_COLOR_GREEN_OUTER_TT "amount of green color in the outer border"
+ IDS_MENU_COLOR_BLUE_OUTER " color (blue)"
+ IDS_MENU_COLOR_BLUE_OUTER_TT "amount of blue color in the outer border"
+ IDS_MENU_OPACITY_OUTER " opacity"
+ IDS_MENU_OPACITY_OUTER_TT
+ "opacity of the outer border (0=transparent, 1=opaque)"
+ IDS_MENU_INNER_BORDER_THICKNESS "inner border thickness"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_INNER_BORDER_THICKNESS_TT
+ "thickness of the inner border drawn at the edges of the screen"
+ IDS_MENU_COLOR_RED_INNER_TT "amount of red color in the inner border"
+ IDS_MENU_COLOR_GREEN_INNER_TT "amount of green color in the inner border"
+ IDS_MENU_COLOR_BLUE_INNER_TT "amount of blue color in the inner border"
+ IDS_MENU_OPACITY_INNER_TT
+ "opacity of the inner border (0=transparent, 1=opaque)"
+ IDS_MENU_MOTION_VECTOR_OPACITY "motion vector opacity"
+ IDS_MENU_MOTION_VECTOR_OPACITY_TT
+ "opacity of the motion vectors (0=transparent, 1=opaque)"
+ IDS_MENU_NUM_MOT_VECTORS_X " num. mot. vectors (X)"
+ IDS_MENU_NUM_MOT_VECTORS_X_TT "the number of motion vectors on the x-axis"
+ IDS_MENU_NUM_MOT_VECTORS_Y " num. mot. vectors (Y)"
+ IDS_MENU_NUM_MOT_VECTORS_Y_TT "the number of motion vectors on the y-axis"
+ IDS_MENU_OFFSET_X " offset (X)"
+ IDS_MENU_OFFSET_X_TT "horizontal placement offset of the motion vectors"
+ IDS_MENU_OFFSET_Y " offset (Y)"
+ IDS_MENU_OFFSET_Y_TT "vertical placement offset of the motion vectors"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_TRAIL_LENGTH " trail length"
+ IDS_MENU_TRAIL_LENGTH_TT "the length of the motion vectors (1=normal)"
+ IDS_MENU_COLOR_RED_MOTION_VECTOR_TT
+ "amount of red color in the motion vectors"
+ IDS_MENU_COLOR_GREEN_MOTION_VECTOR_TT
+ "amount of green color in the motion vectors"
+ IDS_MENU_COLOR_BLUE_MOTION_VECTOR_TT
+ "amount of blue color in the motion vectors"
+ IDS_MENU_ZOOM_AMOUNT "zoom amount"
+ IDS_MENU_ZOOM_AMOUNT_TT "controls inward/outward motion. 0.9=zoom out, 1.0=no zoom, 1.1=zoom in"
+ IDS_MENU_ZOOM_EXPONENT " zoom exponent"
+ IDS_MENU_ZOOM_EXPONENT_TT "controls the curvature of the zoom; 1=normal"
+ IDS_MENU_WARP_AMOUNT "warp amount"
+ IDS_MENU_WARP_AMOUNT_TT "controls the magnitude of the warping; 0=none, 1=normal, 2=major warping..."
+ IDS_MENU_WARP_SCALE " warp scale"
+ IDS_MENU_WARP_SCALE_TT "controls the wavelength of the warp; 1=normal, less=turbulent, more=smoother"
+ IDS_MENU_WARP_SPEED " warp speed"
+ IDS_MENU_WARP_SPEED_TT "controls the speed of the warp; 1=normal, less=slower, more=faster"
+ IDS_MENU_ROTATION_AMOUNT "rotation amount"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_BLUR3_MIN_COLOR_VALUE_TT
+ "narrowing these to just the color range you need will greatly increase color fidelity in the blurred images. MUST BE SUBSET OF BLUR1, BLUR2 RANGES."
+ IDS_MENU_BLUR3_MAX_COLOR_VALUE "blur3: max color value"
+ IDS_MENU_BLUR3_MAX_COLOR_VALUE_TT
+ "narrowing these to just the color range you need will greatly increase color fidelity in the blurred images. MUST BE SUBSET OF BLUR1, BLUR2 RANGES."
+ IDS_MENU_EDIT_PER_VERTEX_EQUATIONS "[ edit per_vertex equations ]"
+ IDS_MENU_EDIT_PER_VERTEX_EQUATIONS_TT
+ "read-only: x, y, rad, ang; time, fps, frame, progress; {bass|mid|treb}[_att]\nread/write: dx, dy, zoom, rot, warp, cx, cy, sx, sy, q1-q8"
+ IDS_MENU_EDIT_WARP_SHADER_TT
+ "This pixel shader drives the warping, color, etc. of the internal image each frame.\n"
+ IDS_MENU_EDIT_COMPOSITE_SHADER_TT
+ "This pixel shader drives the final presentation of the internal image to the screen each frame.\n"
+ IDS_MENU_EDIT_UPGRADE_PRESET_PS_VERSION
+ "upgrade preset's pixel shader version"
+ IDS_MENU_EDIT_UPGRADE_PRESET_PS_VERSION_TT
+ "Upgrades the preset to the next-available pixel shader version."
+ IDS_MENU_EDIT_DO_A_PRESET_MASH_UP "do a preset mash-up"
+ IDS_MENU_EDIT_DO_A_PRESET_MASH_UP_TT
+ "Mix qualities from many different presets to create a new one."
+ IDS_MENU_NUMBER_OF_INSTANCES "number of instances"
+ IDS_MENU_NUMBER_OF_INSTANCES_TT
+ "the number of times (num_inst) to draw this shape. Each instance will have a different value for 'instance' in the per-frame eqs (0,1,2...)"
+ IDS_MENU_EDIT_INIT_CODE_SHAPE_TT
+ "IN: time, frame, fps, progress; q1-q8 (from preset init); x,y,rad,ang; r,g,b,a; r2,g2,b2,a2; border_{r|g|b|a}; sides, thick, additive, textured\nOUT: t1-t8; x,y,rad,ang; r,g,b,a; r2,g2,b2,a2; border_{r|g|b|a}; sides, thick, additive, textured"
+ IDS_MENU_EDIT_PER_FRAME_INSTANCE_CODE
+ "[ edit per-frame(/per-instance) code ]"
+ IDS_MENU_EDIT_PER_FRAME_INSTANCE_CODE_TT
+ "IN: instance, num_inst, time, frame, fps, progress; q1-q8 (from preset init); x,y,rad,ang; r,g,b,a; r2,g2,b2,a2; border_{r|g|b|a}; sides, thick, additive, textured\nOUT: t1-t8; x,y,rad,ang; r,g,b,a; r2,g2,b2,a2; border_{r|g|b|a}; sides, thick, additive, textured"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_OPACITY_WAVE_TT
+ "opacity of the waveform; 0=transparent, 1=opaque"
+ IDS_MENU_USE_SPECTRUM "use spectrum"
+ IDS_MENU_USE_SPECTRUM_TT
+ "if ON, the data in value1 and value2 will constitute a frequency spectrum (instead of waveform values)"
+ IDS_MENU_USE_DOTS_WAVE_TT
+ "if ON, the samples will be overdrawn 4X to make them thicker, bolder, and more visible"
+ IDS_MENU_DRAW_THICK_WAVE_TT
+ "if ON, the samples will be overdrawn 4X to make them thicker, bolder, and more visible"
+ IDS_MENU_ADDITIVE_DRAWING_WAVE_TT
+ "if ON, the samples will add color to sature the image toward white; otherwise, they replace what's there."
+ IDS_MENU_EXPORT_TO_FILE "--export to file"
+ IDS_MENU_EXPORT_TO_FILE_TT
+ "export the settings for this custom waveform to a file on disk"
+ IDS_MENU_IMPORT_FROM_FILE "--import from file"
+ IDS_MENU_IMPORT_FROM_FILE_TT
+ "import settings for a custom waveform from a file on disk"
+ IDS_MENU_EDIT_INIT_CODE "[ edit initialization code ]"
+ IDS_MENU_EDIT_INIT_CODE_TT
+ "IN: time, frame, fps, progress; samples; q1-q8 (from preset init) / OUT: t1-t8"
+ IDS_MENU_EDIT_PER_FRAME_CODE "[ edit per-frame code ]"
+ IDS_MENU_EDIT_PER_FRAME_CODE_TT
+ "IN: time, frame, fps, progress; samples; q1-q8, t1-t8; r,g,b,a; {bass|mid|treb}[_att] / OUT: r,g,b,a; samples; t1-t8"
+ IDS_MENU_EDIT_PER_POINT_CODE "[ edit per-point code ]"
+ IDS_MENU_EDIT_PER_POINT_CODE_TT
+ "IN: sample [0..1]; value1 [left ch], value2 [right ch], plus all vars for per-frame code / OUT: x,y; r,g,b,a; t1-t8"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_ENABLED_SHAPE_TT "enables or disables this shape"
+ IDS_MENU_NUMBER_OF_SIDES "number of sides"
+ IDS_MENU_NUMBER_OF_SIDES_TT
+ "the default number of sides that make up the polygonal shape"
+ IDS_MENU_DRAW_THICK_SHAPE_TT
+ "if ON, the border will be overdrawn 4X to make it thicker, bolder, and more visible"
+ IDS_MENU_ADDITIVE_DRAWING_SHAPE_TT
+ "if ON, the shape will add color to sature the image toward white; otherwise, it will replace what's there."
+ IDS_MENU_X_POSITION "x position"
+ IDS_MENU_X_POSITION_TT "default x position of the shape (0..1; 0=left side, 1=right side)"
+ IDS_MENU_Y_POSITION "y position"
+ IDS_MENU_Y_POSITION_TT "default y position of the shape (0..1; 0=bottom, 1=top of screen)"
+ IDS_MENU_RADIUS "radius"
+ IDS_MENU_RADIUS_TT "default radius of the shape (0+)"
+ IDS_MENU_ANGLE "angle"
+ IDS_MENU_ANGLE_TT "default rotation angle of the shape (0...3.14*2)"
+ IDS_MENU_TEXTURED "textured"
+ IDS_MENU_TEXTURED_TT "if ON, the shape will be textured with the image from the previous frame"
+ IDS_MENU_TEXTURE_ZOOM "texture zoom"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_TEXTURE_ZOOM_TT
+ "the portion of the previous frame's image to use with the shape"
+ IDS_MENU_TEXTURE_ANGLE "texture angle"
+ IDS_MENU_TEXTURE_ANGLE_TT
+ "the angle at which to rotate the previous frame's image before applying it to the shape"
+ IDS_MENU_INNER_COLOR_RED "inner color (red)"
+ IDS_MENU_INNER_COLOR_RED_TT
+ "default amount of red color toward the center of the shape (0..1)"
+ IDS_MENU_INNER_COLOR_GREEN "inner color (green)"
+ IDS_MENU_INNER_COLOR_GREEN_TT
+ "default amount of green color toward the center of the shape (0..1)"
+ IDS_MENU_INNER_COLOR_BLUE "inner color (blue)"
+ IDS_MENU_INNER_COLOR_BLUE_TT
+ "default amount of blue color toward the center of the shape (0..1)"
+ IDS_MENU_INNER_OPACITY "inner opacity"
+ IDS_MENU_INNER_OPACITY_TT
+ "default opacity of the center of the shape; 0=transparent, 1=opaque"
+ IDS_MENU_OUTER_COLOR_RED "outer color (red)"
+ IDS_MENU_OUTER_COLOR_RED_TT
+ "default amount of red color toward the outer edge of the shape (0..1)"
+ IDS_MENU_OUTER_COLOR_GREEN "outer color (green)"
+ IDS_MENU_OUTER_COLOR_GREEN_TT
+ "default amount of green color toward the outer edge of the shape (0..1)"
+ IDS_MENU_OUTER_COLOR_BLUE "outer color (blue)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MENU_OUTER_COLOR_BLUE_TT
+ "default amount of blue color toward the outer edge of the shape (0..1)"
+ IDS_MENU_OUTER_OPACITY "outer opacity"
+ IDS_MENU_OUTER_OPACITY_TT
+ "default opacity of the outer edge of the shape; 0=transparent, 1=opaque"
+ IDS_MENU_BORDER_COLOR_RED "border color (red)"
+ IDS_MENU_BORDER_COLOR_RED_TT
+ "default amount of red color in the shape's border (0..1)"
+ IDS_MENU_BORDER_COLOR_GREEN "border color (green)"
+ IDS_MENU_BORDER_COLOR_GREEN_TT
+ "default amount of green color in the shape's border (0..1)"
+ IDS_MENU_BORDER_COLOR_BLUE "border color (blue)"
+ IDS_MENU_BORDER_COLOR_BLUE_TT
+ "default amount of blue color in the shape's border (0..1)"
+ IDS_MENU_BORDER_OPACITY "border opacity"
+ IDS_MENU_BORDER_OPACITY_TT
+ "default opacity of the shape's border; 0=transparent, 1=opaque"
+ IDS_MENU_EXPORT_TO_FILE_SHAPE_TT
+ "export the settings for this custom shape to a file on disk"
+ IDS_MENU_IMPORT_FROM_FILE_SHAPE_TT
+ "import settings for a custom shape from a file on disk"
+ IDS_ERROR_UNABLE_TO_SAVE_THE_FILE "ERROR: unable to save the file"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ERROR_PRESET_NOT_FOUND_X "ERROR: preset not found: %s"
+ IDS_ERROR_NO_PRESET_FILES_OR_DIRS_FOUND_IN_X
+ "ERROR: No preset files OR directories found in %s*.milk"
+ IDS_SCANNING_PRESETS " scanning presets... "
+ IDS_SPRITE_X_ERROR_COULD_NOT_FIND_IMG_OR_NOT_DEFINED
+ "sprite #%d error: could not find 'img=' setting, or sprite is not defined"
+ IDS_WARNING_PRESET_X_ERROR_IN_PRESET_INIT_CODE
+ "warning: preset ""%s"": error in 'preset_init' code"
+ IDS_WARNING_PRESET_X_ERROR_IN_PER_FRAME_CODE
+ "warning: preset ""%s"": error in 'per-frame' code"
+ IDS_WARNING_PRESET_X_ERROR_IN_PER_VERTEX_CODE
+ "warning: preset ""%s"": error in 'per-vertex' code"
+ IDS_HZ "Hz"
+ IDS_HELP_MINIMIZE_WINAMP "Help on 'Minimize Winamp...' checkbox"
+ IDS_HELP_MINIMIZE_WINAMP_HELP
+ "Enable this if you can sometimes see the Winamp window flickering\nthrough, when you run the plug-in fullscreen. Enabling this option\nwill force the Winamp window to minimize whenever the plug-in goes\nfullscreen on the same monitor that the Winamp window is on.\nThe Winamp window will be restored as soon as the plug-in returns\nfrom fullscreen mode.\n\nNote that this also applies for 'fake' fullscreen mode (as well as 'real'\nfullscreen mode).\n\nKeep in mind that when running graphically demanding applications\n(such as this plug-in), it's always good to minimize (or close) as many\nother applications as possible, even if they appear to be idle."
+ IDS_DIRECTX_MISSING_OR_CORRUPT_TEXT
+ "Failed to initialize DirectX 9.0 or later.\nMilkdrop requires d3dx9_31.dll to be installed.\n\nWould you like to be taken to:\nhttp://www.microsoft.com/download/details.aspx?id=35,\nwhere you can update DirectX 9.0?\n"
+ IDS_PARENT_DIRECTORY "parent directory"
+ IDS_RAND_TITLE "Time between random song title animation"
+ IDS_RAND_MSG "Time between random custom messages"
+ IDS_MAX_IMAGES_BYTES "Image cache settings"
+ IDS_PAGE_X " Page %d "
+END
+
+STRINGTABLE
+BEGIN
+ IDS_SAVE_SUCCESSFUL "[save successful]"
+ IDS_ERROR_UNABLE_TO_DELETE_THE_FILE "ERROR: unable to delete the file"
+ IDS_PRESET_X_DELETED "[preset ""%s"" deleted]"
+ IDS_ERROR_A_FILE_ALREADY_EXISTS_WITH_THAT_FILENAME
+ "ERROR: a file already exists with that filename"
+ IDS_ERROR_UNABLE_TO_RENAME_FILE "ERROR: unable to rename the file"
+ IDS_RENAME_SUCCESSFUL "[rename successful]"
+ IDS_SPRITE_X_WARNING_ERROR_IN_INIT_CODE
+ "sprite #%d warning: error in initialization code "
+ IDS_SPRITE_X_WARNING_ERROR_IN_PER_FRAME_CODE
+ "sprite #%d warning: error in per-frame code"
+ IDS_SPRITE_X_ERROR_BAD_SLOT_INDEX "sprite #%d error: bad slot index"
+ IDS_SPRITE_X_ERROR_IMAGE_FILE_MISSING_OR_CORRUPT
+ "sprite #%d error: image file missing or corrupt"
+ IDS_SPRITE_X_ERROR_OUT_OF_MEM
+ "sprite #%d error: out of memory, unable to load image"
+ IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_INIT_CODE
+ "warning: preset ""%s"": error in wave %d init code"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_PER_FRAME_CODE
+ "warning: preset ""%s"": error in wave %d per-frame code"
+ IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_PER_POINT_CODE
+ "warning: preset ""%s"": error in wave %d per-point code"
+ IDS_WARNING_PRESET_X_ERROR_IN_SHAPE_X_INIT_CODE
+ "warning: preset ""%s"": error in shape %d init code"
+ IDS_WARNING_PRESET_X_ERROR_IN_SHAPE_X_PER_FRAME_CODE
+ "warning: preset ""%s"": error in shape %d per-frame code"
+ IDS_CONFIG_PANEL_BUTTON_1 "Common Settings"
+ IDS_CONFIG_PANEL_BUTTON_2 "MORE SETTINGS"
+ IDS_CONFIG_PANEL_BUTTON_3 "Artist Tools"
+ IDS_CONFIG_PANEL_BUTTON_4 "Transitions"
+ IDS_CONFIG_PANEL_BUTTON_5 " "
+ IDS_CONFIG_PANEL_BUTTON_6 " "
+ IDS_CONFIG_PANEL_BUTTON_7 " "
+ IDS_CONFIG_PANEL_BUTTON_8 " "
+ IDS_EXTRA_FONT_1_NAME "Tooltips"
+ IDS_EXTRA_FONT_2_NAME "Animated Songtitles"
+ IDS_PRESS_F1_MSG "Press F1 for Help "
+ IDS_GRAPHICS_SUBSYSTEM_IS_TEMPORARILY_UNSTABLE
+ "One or more fullscreen display adapters are behaving strangely and will not\nreport a list of display modes. It's quite possible that your graphics subsystem\nis temporarily unstable.\n\nSUGGESTED ACTION: If you have modified your multimon setup or Windows,\ndisplay settings, or have updated any display drivers or installed\nany new programs, you should probably REBOOT YOUR COMPUTER before\ntrying to configure (or run) the plug-in again."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_UNKNOWN "UNKNOWN"
+ IDS_DISABLED_PAGE_TEARING "(disabled/pg. tearing)"
+ IDS_NONE "(none)"
+ IDS_UNLIMITED "(unlimited)"
+ IDS_X_FRAME_SEC "%2d frames/sec"
+ IDS_HELP_ON_X_BUTTON "Help on '%s' button"
+ IDS_FONTS_HELP "Click this button to alter the fonts that are used to display text\nwhile the plug-in is running."
+ IDS_DUAL_HEAD_HELP "Click this button for special options concerning DualHead video cards\nthat are capable of running in double-width or double-height display\nmodes. DualHead cards that support this treat the two monitors as\none giant, double-width or double-height display.\n\nThis would usually mean that when going Fullscreen, the plug-in would be\nstretched over both monitors. However, when you run the plug-in in\nDesktop Mode or in *Fake* Fullscreen Mode, you can get around this,\nand allow the plug-in to run on just one monitor, leaving you free\nto work on the other."
+ IDS_MULTI_SAMPLING "Help on Multisampling"
+ IDS_MULTI_SAMPLING_HELP "This controls the level of full-scene anti-aliasing (blending)\nthat the display adapter uses. Only newer video cards will\ntend to support this feature. Anti-aliasing softens out the\n'jaggies' that you sometimes see at the pixel level, for example,\nat the silhouette of an object, or on a wireframe object.\n\nA level of '2X' would mean that 3D rendering/rasterization is done\ninternally *at double-resolution*, and then downsampled before final\ndisplay to the user. A level of '3X' would mean that the rendering\nis done at triple-resolution, and so on.\n\nNote that, due to limitations of the DirectX 8 API, the use of multisampling\ngenerally requires that page tearing be allowed; the one exception is 'true'\nfullscreen mode, where you can have the best of both worlds: you can disable\npage tearing and enable multisampling at the same time."
+ IDS_MAX_FRAMERATE "Help on Max Framerate"
+ IDS_MAX_FRAMERATE_HELP "This controls the maximum # of times the image will be updated, per second.\nFramerate is also commonly called ""FPS"", or ""frames per second.""\n\nIf the plug-in is running too quickly for your taste, you can lower the\nmaximum framerate to slow it down. You might also want to do this if\nthe plug-in is 'hogging the CPU' and slowing down other applications.\n\nTypically, a framerate of 30 looks good; 60 looks great. The human eye\nhas a hard time processing more than 60 fps, though.\n\nNote that if the animation is rendering below the maximum framerate here,\nyour CPU will likely be in 100%% use, leaving your computer somewhat\nunresponsive. If this is the case, try lowering the max. framerate\nuntil it takes effect, and then your computer should become more responsive.\n\nAlso keep in mind that it's a good idea to try and set the max. framerate\nto the current refresh rate of your monitor (e.g. 60 Hz, 72 Hz, etc.)\nor an integer factor of that number; for example, at a 72 Hz monitor\nrefresh rate, good max. framerates would be 2, 3, 4, 6, 8, 9, 12, 18,\n24, 36, or 72."
+ IDS_FAKE_FULLSCREEN "Help on 'fake' fullscreen mode"
+ IDS_FAKE_FULLSCREEN_HELP
+ "When this option is enabled, the display mode is never changed by\nthe plug-in; instead, the plug-in 'fakes' fullscreen mode by simply\nthe plug-in; instead, the plug-in 'fakes' fullscreen mode by simply\nthe window on top.\n\nDUALHEAD: Fake fullscreen mode can be especially handy when you have a\ndualhead display adapter that drives two monitors, but really just treats\nthem as one giant display (e.g. **the display mode is something like 2048x768\nor 1024x1536**), where regular fullscreen mode will take over both monitors,\ncreating a very large, stretched image. HOWEVER, if you use fake\nfullscreen mode, it can (if you want) take over just one monitor, leaving\nyou free to work on the other monitor. To choose which display to favor\n(or to span both), click the 'DualHead' button and follow the instructions\nthere.\n\nTASKBAR: Note that in fake fullscreen mode, the taskbar will still be visible\n(and usable) if the plug-in does not entirely cover all displays & all monitors.\nIf you don't like it, use 'true' fullscreen mode instead, or move the taskbar\n(...there should be a place to move it to, since the plug-in doesn't cover all\nof your displays). However, if the plug-in does cover all displays and all\nmonitors, the taskbar should be nicely hidden."
+ IDS_FULLSCREEN_ADAPTER "Help on fullscreen display adapter selection"
+ IDS_FULLSCREEN_ADAPTER_HELP
+ "This lets you select which display adapter (video card) you'd like to\nrun the plug-in on, when it goes fullscreen. If you only have one video\ncard and monitor in your system, you will only have one choice here; but\nif you have multiple video cards, or a multi-head video card (one card\nthat drives multiple monitors), there should be two or more choices here.\n\nNote that if you have trouble running in fullscreen mode with multiple\ndisplays, you might want to try the 'fake fullscreen mode' option.\nSee its help screen for more information."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_WINDOWED_ADPATER "Help on windowed-mode display adapter selection"
+ IDS_WINDOWED_ADPATER_HELP
+ "This lets you select which display adapter (video card) you'd like to\nrun the plug-in on, when it runs in a window. If you only have one video\ncard and monitor in your system, you will only have one choice here; but\nif you have multiple video cards, or a multi-head video card (one card\nthat drives multiple monitors), there should be two or more choices here.\n\nThe default window position will be somewhere on the monitor for the\ndisplay adapter you choose here. You can drag the window to a different\nmonitor, but it is likely to be very slow, because the pixels will have\nto be copied, via Windows, from one display to the next, each frame.\n\nSo, for best performance in windowed mode, be sure to select the monitor\nyou want it to run on here, in advance, and avoid dragging the window to\nanother monitor at runtime."
+ IDS_DESKTOP_ADAPTER "Help on desktop-mode display adapter selection"
+ IDS_DESKTOP_ADAPTER_HELP
+ "This lets you select which display adapter (video card & monitor) you'd like to\nrun the plug-in on, when it runs in desktop mode, replacing your windows wallpaper.\nIf you only have one video card and monitor in your system, you will only have\none choice here; but if you have multiple video cards, or a multi-head video card\n(one card that drives multiple monitors), there should be two or more choices here."
+ IDS_HELP_ON_X_CHECKBOX "Help on '%s' checkbox"
+ IDS_HELP_ON_X_CHECKBOX_HELP
+ "When a new frame of animation is ready for display, the plug-in\nhas a choice of whether or not to synchronize the new frame to the\nmonitor's next vertical scan.\n\nIf there is no synchronization and the new frame is shown immediately,\nthen the update might occure in 'mid-scan', so for that 1/60th of a second,\nyou'll see the old frame toward the top of the monitor, and the new frame\ntoward the bottom, with a sharp line ('tear') somewhere in between. This\nis especially visible when solid objects on the screen are changing or\nmoving rapidly, from frame to frame.\n\nHowever, if the plug-in waits until the vertical scan is complete to update\nthe image, then at the start of the next vertical scan, the entire image\nwill be ready and will (hopefully) be presented without any tearing.\n\nAlthough page tearing will often cause visible artifacts, it will allow\nthe plug-in to run at its maximum possible framerate. Generally, though,\npage tearing is considered a bad thing, to be avoided when possible.\n\nNote that this synchronization (done by DirectX and your video driver)\nis usually approximate when running in windowed (or fake fullscreen) modes;\nthus, page tearing is often minimized but can't always be completely eliminated.\n\nNote that multisampling is usually only available when page tearing is\nallowed, due to limitations of the DirectX 8 API. The one exception is\n'true' fullscreen mode; there, you can disable page tearing and still use\nmultisampling. (But not in fake fullscreen, windowed, or desktop modes.)"
+ IDS_FORCE_INTO_FS_MODE_HELP
+ "Enable this to force the plug-in to start in fullscreen\n(or 'fake fullscreen') mode.\n\n(Note that if 'fake' fullscreen mode is enabled,\nthe plug-in will start in fake fullscreen mode.)"
+ IDS_FORCE_INTO_DESKTOP_MODE_HELP
+ "Enable this to force the plug-in to start in desktop mode."
+ IDS_HELP_ON_F1 "Help on 'Press F1...' checkbox"
+ IDS_HELP_ON_F1_HELP "Disable this to prevent the 'Press F1 for Help' message\nfrom appearing when the plug-in starts."
+ IDS_CB_SKIN_HELP "Check this box to 'skin' the plug-in's window frame when it runs\nin a window, so that it looks like the rest of the windows that\nmake up Winamp's interface.\n\nThis feature requires Winamp 2.90 or later; if the box is greyed\nout, it means you need a newer version of Winamp."
+ IDS_SAVE_CPU_CHECKBOX "Help on 'Save CPU' checkbox"
+ IDS_SAVE_CPU_CHECKBOX_HELP
+ "Check this box to lower the amount of CPU (processor) that the plug-in uses\nto monitor and limit the framerate.\n\nWhen this box is unchecked, the plug-in will extremely accurately limit the\nframerate, resulting in ultra-smooth animation. However, there is some cost\nin terms of CPU time - usually in the range of 0-20%%.\n\nWhen this box is checked, though, the plug-in uses a more lenient algorithm to\nlimit the framerate, which uses virtually no CPU time. However, the framerate\nwill not be as accurately limited (it might vary over time), and animation is\nnot guaranteed to be perfectly smooth.\n\nNote that you can further decrease CPU usage by:\n 1) decreasing the maximum framerate (via the 'Max Framerate' options)\n 2) allowing page tearing (via the 'Allow Page Tearing' checkboxes)"
+ IDS_FS_DISPLAY_MODE "Help on fullscreen display mode selection"
+ IDS_FS_DISPLAY_MODE_HELP
+ "This lets you select which display mode you'd like to use when you\nrun the plug-in fullscreen.\n\nThe first parameter is the pixel color format, which decides\nthe total number of possible colors in the rendered image.\nRGB-555 and RGB-565 are 16-bit color formats, which have poor\ncolor resolution but are often fast. RGB-888 is a 32-bit color\nformat; it often has superior image quality, but is often slower\nand takes up twice the video memory.\n\nThe next two parameters are the width and height of the display mode,\nin pixels, also known as the 'resolution'. Higher resolutions are\nusually slower and require more video memory, but look better.\n\nThe last parameter is the refresh rate: the rate at which the\n""monitor refreshes the image you see, in Hertz (cycles per second).\nHigher refresh rates tend to be easier on the eyes."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_TRY_TO_FIX_SLOW_TEXT "Help on 'Try to fix slow text' checkbox"
+ IDS_TRY_TO_FIX_SLOW_TEXT_HELP
+ "Many video cards - even new ones - are very slow at drawing onscreen text.\nMost application render onscreen text overtop of the final image\n*every frame*, but since MilkDrop has so many menus, this can severely\ndrop the framerate.\n\nA workaround is invoked by checking this box. Instead of drawing the\ntext every frame, it is instead drawn to a second image buffer, and then\nonly updated when the text changes. That separate image buffer is then\noverlaid onto the final image for display, each frame. By not redrawing\nthe same text over and over, MilkDrop maintains a normal framerate.\n\nThis option is good for maintaining speed, but it uses a substantial amount\nof video memory. You should probably only use it if you have 32 megabytes\n(or more) of graphics memory. If there is not enough video memory to set\nup the offscreen image buffer for cacheing the text, it will not be created,\nand MilkDrop will behave as if the box was unchecked."
+ IDS_VJ_MODE "Help on VJ Mode"
+ IDS_VJ_MODE_HELP "VJ mode is used by those who want to show MilkDrop on one display\nwhile working with it on the other display. When VJ mode is on,\ntext is drawn into a second window, instead of being overlaid on\ntop of the graphics. This leaves the 'VJ' (the person running the\nvisuals for a concert, for example) able to navigate milkdrop's menus\nand edit presets while MilkDrop runs on a second display (likely\nrunning to a projector), without the ugly menus showing up.\n\nIMPORTANT: whichever windowed mode display adapter you have selected \ndetermines which monitor the separate text window appears on, and runs\nbest on. If you try dragging (moving) it to another monitor, performance\nwill be severely impacted; instead, exit MilkDrop, return to the config\npanel, and set the windowed mode display adapter to reflect the monitor\nyou want the separate text window to appear on."
+ IDS_HELP_ON_X "Help on '%s'"
+ IDS_DMS_LABEL_HELP "These settings control the behavior of the plug-in when it is running\nin 'desktop mode'. In desktop mode, the plug-in is visible in your\nWindows background, replacing your wallpaper with the animated plug-in."
+ IDS_FS_LABEL_HELP "These settings control the behavior of the plug-in when it is running\nin fullscreen mode. In fullscreen mode, the plug-in changes the display\nmode to whatever you indicate here, and then uses the entire display\nto render the image.\n\nFullscreen mode also gives the plug-in certain privileges within the\ngraphics subsystem (it enters 'exclusive mode'), so performance is\nusually quite improved."
+ IDS_W_LABEL_HELP "These settings control the behavior of the plug-in when it is running\nin a window. In windowed mode, the plug-in renders right into a window,\njust like any other application you might have running.\n\nWhen the plug-in starts, the default window position will be somewhere\non the monitor for the display adapter you choose here.\nYou *can* drag the window to a different monitor, but it is likely to be,\nVERY slow because the pixels will have to be copied, via Windows, from\none display to the next, each frame.\n\nSo, for best performance in windowed mode, be sure to select the monitor\nyou want it to run on here, in advance, and avoid dragging the window to\nanother monitor at runtime."
+ IDS_DM_MORE_HELP "Click here to bring up a dialog with\nadvanced settings for Desktop Mode."
+ IDS_INITCONFIG_FAILED "InitConfig() failed!"
+ IDS_UNABLE_TO_LOAD_TABS "Unable to load tabs!"
+ IDS_DOCUMENTATION_FILE_NOT_FOUND
+ "the documentation file:\n\n\t%s\n\ncould not be found."
+ IDS_ACCESS_TO_DOCUMENTATION_FILE_DENIED
+ "access to the documentation file:\n\n\t%s\n\nwas denied."
+ IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_DUE_TO_NO_ASSOC
+ "the documentation file:\n\n\t%s\n\ncould not be accessed because there is no application\nassociated with documents of this type."
+ IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_CODE_X
+ "the documentation file:\n\n\t%s\n\ncould not be accessed (error code: %d)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ERROR_OPENING_DOCUMENTATION "Error Opening Documentation"
+ IDS_URL_COULD_NOT_OPEN "the URL\n\n\t%s\n\ncould not be opened."
+ IDS_ACCESS_TO_URL_WAS_DENIED "access to the URL\n\n\t%s\n\nwas denied."
+ IDS_ACCESS_TO_URL_FAILED_DUE_TO_NO_ASSOC
+ "the URL\n\n\t%s\n\ncould not be accessed because there is no application\nassociated with documents of this type."
+ IDS_ACCESS_TO_URL_FAILED_CODE_X
+ "the URL\n\n\t%s\n\ncould not be accessed (error code: %d)"
+ IDS_ERROR_OPENING_URL "Error Opening URL"
+ IDS_RESTORE_ALL_DEFAULTS
+ "Are you sure you want to restore the default settings?\n\nIf you click YES, the config panel will close and the defaults will be restored."
+ IDS_RESTORE_ALL_DEFAULTS_TITLE "Restore Default Settings?"
+ IDS_OK_HELP "Click this button to save your changes and return to Winamp."
+ IDS_CANCEL_HELP "Click this button to cancel any changes and return to Winamp."
+ IDS_RESTORE_DEFAULTS_HELP
+ "Click this button to restore all config panel settings\nto their 'factory' defaults and then return to Winamp."
+ IDS_DOCUMENTATION_BUTTON_HELP
+ "Click this button to view the documentation for this plug-in."
+ IDS_VIEW_ONLINE_DOCS_HELP
+ "Click this button to view the website (homepage) for this plug-in\nusing your default browser."
+ IDS_5_6_5_TEXTURE "a 5-6-5 texture (no transparency)"
+ IDS_5_5_5_TEXTURE "a 5-5-5 texture (w/1 bit of transparency)"
+ IDS_8_8_8_TEXTURE "an 8-8-8 texture (w/8 bits of transparency)"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NO_ALPHA_FALLBACK "Help on ""no alpha"" fallback options"
+ IDS_NO_ALPHA_FALLBACK_HELP
+ "If you run the plug-in in desktop mode and find that your\ndesktop icons are surrounded by black boxes, then you'll\nwant to experiment with this setting. The black box means\nthat 'alpha' (transparency) is not working, probably because\nyour current video mode (that Windows is running in) does\nnot have an alpha channel. To make a long story short,\njust try different options here if you get the 'black box'\neffect, and cross your fingers that one of these works.\n\nNote that the 5-6-5 option uses half as much video memory\nas the 8-8-8 option, so if they both work, use the 5-6-5."
+ IDS_CB_SHOW_ICONS_HELP "When you're running in desktop mode, this option lets you\nchoose to show or hide the icons that normally sit on your\ndesktop."
+ IDS_CB_BOX "Help on 'Draw colored boxes...' checkbox"
+ IDS_CB_BOX_HELP "This option lets you choose whether or not you want to\nsee a solid-colored box around each of the text labels\nfor the icons on your desktop, while the plug-in is running.\n\nIf you turn it off, the icon text labels might be harder\nto read (depending on the current image that the plug-in is\ngenerating), but the icons will also tend to dominate the\nscreen less."
+ IDS_CB_MANUAL_SCOOT "Help on icon occlusion checkbox"
+ IDS_CB_MANUAL_SCOOT_HELP
+ "Normally, when you put your Windows taskbar on the Top or Left\nedge of the screen, Windows nicely scoots your desktop icons out\nfrom underneath it, so that they remain visible.\n\nThis plug-in tries to do the same thing, but on a few video cards,\nthe desktop icons might still be occluded (covered) by the taskbar\nwhen you run the plug-in in Desktop Mode (and the taskbar sits along\nthe Top or Left edge of the screen.)\n\nIf this happens to you, try checking this box - it will try a\ndifferent algorithm for placing the icons, and should manage to\nscoot them out (down or to the right) from underneath the taskbar."
+ IDS_SPAN_BOTH_SCREENS "span both screens"
+ IDS_USE_LEFT_SCREEN_ONLY "use left screen only"
+ IDS_USE_RIGHT_SCREEN_ONLY "use right screen only"
+ IDS_USE_TOP_SCREEN_ONLY "use top screen only"
+ IDS_USE_BOTTOM_SCREEN_ONLY "use bottom screen only"
+ IDS_COULD_NOT_FIND_FILE_FOR_DESKTOP_MODE_X
+ "Could not find the following file:\n\n %s\n\n...which is required for this plug-in to work properly in Desktop Mode.\nPlease reinstall the plug-in."
+ IDS_MILKDROP_ERROR_FILE_MISSING "MILKDROP ERROR - FILE MISSING"
+ IDS_ERROR_CREATING_GDI_DESKTOP_FONT "Error creating GDI desktop font"
+ IDS_ERROR_CREATING_DESKTOP_FONT "Error creating desktop font"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ERROR_CREATING_TEXTURE_FOR_ICON_BITMAPS
+ "Error creating texture for icon bitmaps"
+ IDS_OUTDATED_VMS_DESKTOP_DLL_NEED_TO_REINSTALL
+ "It appears that you have an outdated copy of the file 'vms_desktop.dll'\nin your Winamp PLUGINS directory. Please reinstall the plug-in\nto bring this file up to date."
+ IDS_ERROR_CREATING_HOOK_PROC_DESKTOP_ICONS_NOT_AVAILABLE
+ "Error creating hook procedure;\ndesktop icons will not be available."
+ IDS_ERROR_UPDATING_ICON_BITMAPS
+ "Error updating icon bitmaps; the number of unique\nicon bitmaps on your desktop exceeded the maximum.\n\nAs a result, not all icons will look correct."
+ IDS_ERROR_UPDATING_ICON_BITMAPS_TOO_MANY_UNIQUE_ICON_BITMAPS
+ "Error updating icon bitmaps: there were a lot of unique icon bitmaps,\nbut the plug-in couldn't allocate enough extra texture(s) to hold them all,\nprobably because video memory is low.\n\nAs a result, not all icons will look correct."
+ IDS_ERROR_UPDATING_ICON_BITMAPS_COULD_NOT_GET_LEVEL_DESCRIPTION
+ "Error updating icon bitmaps:\ncouldn't get level description"
+ IDS_ERROR_UPDATING_ICON_BITMAPS_LOCKRECT_FAILED
+ "Error updating icon bitmaps:\nLockRect failed"
+ IDS_ERROR_UPDATING_ICON_BITMAPS_LR_PBITS_IS_NULL
+ "Error updating icon bitmaps:\nlr.pBits == NULL"
+ IDS_ERROR_UPDATING_ICON_BITMAPS_UNKNOWN_PIXEL_FORMAT
+ "Error updating icon bitmaps:\nunknown pixel format"
+ IDS_ERROR_UPDATING_ICON_BITMAPS_COULDNT_GET_HDC
+ "Error updating icon bitmaps:\ncouldn't get HDC"
+ IDS_ERROR_UPDATING_ICON_BITMAPS_CALL_TO_GETDIBITS_FAILED
+ "Error updating icon bitmaps:\ncall #1 to GetDIBits failed."
+ IDS_ERROR_UPDATING_ICON_BITMAPS_CALL_2_TO_GETDIBITS_FAILED
+ "Error updating icon bitmaps:\ncall #2 to GetDIBits failed."
+ IDS_ERROR_UPDATING_ICON_BITMAPS_GETICONINFO_FAILED
+ "Error updating icon bitmaps:\nGetIconInfo failed."
+ IDS_ERROR_UPDATING_ICON_BITMAPS_SHGETFILEINFO_FAILED
+ "Error updating icon bitmaps:\nSHGetFileInfo failed."
+ IDS_UNABLE_TO_REGISTER_WINDOW_CLASS
+ "Unable to register the window class;\nPLEASE RESTART WINAMP."
+ IDS_DIRECTX_INIT_FAILED "DirectX initialization failed; unknown color format"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_VJ_MODE_INIT_ERROR "VJ mode init error: error determining color format\nfor currently-selected Windowed Mode display adapter."
+ IDS_ERROR_REGISTERING_WINDOW_CLASS_FOR_TEXT_WINDOW
+ "Error registering window class for text window"
+ IDS_ERROR_CREATING_VJ_WINDOW "Error creating VJ window"
+ IDS_ERROR_CREATING_D3D_DEVICE_FOR_VJ_MODE
+ "Error creating D3D device for VJ mode"
+ IDS_ERROR_CREATING_D3DX_FONTS "Error creating D3DX fonts"
+ IDS_UNABLE_TO_INIT_DXCONTEXT
+ "Unable to initialize DXContext;\nprobably out of memory."
+ IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG
+ "To free up some memory, please RESTART WINAMP, then return\n to the plug-in's config panel and try setting your\n WINDOWED MODE MULTISAMPLING back to 'NONE.'\n\nThen try running the plug-in again."
+ IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG_2
+ "To free up some memory, please RESTART WINAMP, then return\n to the plug-in's config panel and try setting your\n FAKE FULLSCREEN MODE MULTISAMPLING back to 'NONE.'\n\nThen try running the plug-in again."
+ IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG_3
+ "To free up some memory, please RESTART WINAMP, then return\n to the plug-in's config panel and try setting your\n FULLSCREEN MODE MULTISAMPLING back to 'NONE.'\n\nThen try running the plug-in again."
+ IDS_TO_FREE_UP_VIDEO_MEMORY
+ "To free up some video memory, try the following:\n\n1. Try closing all other applications that might be using video memory, especially:\n\n * WINDOWS MEDIA PLAYER\n * any video conferencing software, such as NETMEETING\n * any DVD playback, TV tuner, or TV capture software\n * any video editing software\n * any software that uses Overlays, such as Drempels Desktop\n * any audio dictation software, such as Dragon NaturallySpeaking\n * any other 3D programs currently running\n\n2. Also try returning to the config panel (ALT+K) and selecting a display mode\n that uses less video memory. 16-bit display modes use half as much memory\n as 32-bit display modes, and lower-resolution display modes (such as 640 x 480)\n use proportionally less video memory.\n\nAfter making these changes, please RESTART WINAMP before trying to run\nthe plug-in again."
+ IDS_TO_FREE_UP_VIDEO_MEMORY_2
+ "To free up some video memory, try the following:\n\n1. Try closing all other applications that might be using video memory, especially:\n\n * WINDOWS MEDIA PLAYER\n * any video conferencing software, such as NETMEETING\n * any DVD playback, TV tuner, or TV capture software\n * any video editing software\n * any software that uses Overlays, such as Drempels Desktop\n * any audio dictation software, such as Dragon NaturallySpeaking\n * any other 3D programs currently running\n\n2. Also try changing your Windows display mode to a lesser bit depth\n (i.e. 16-bit color), or a smaller resolution.\n\nAfter making these changes, please RESTART WINAMP before trying to run\nthe plug-in again."
+ IDS_MILKDROP_SUGGESTION "MILKDROP SUGGESTION"
+ IDS_DIRECTX_MISSING_OR_CORRUPT "DirectX Missing or Corrupt"
+ IDS_ERROR_THE_PLUGIN_IS_ALREADY_RUNNING
+ "Error: the plug-in is already running."
+END
+
+STRINGTABLE
+BEGIN
+ IDS_MB "MB"
+ IDS_GB "GB"
+ IDS_MASHUP_GENERAL_POSTPROC " 1. general, postproc: "
+ IDS_MASHUP_MOTION_EQUATIONS " 2. motion, equations: "
+ IDS_MASHUP_WAVEFORMS_SHAPES " 3. waveforms, shapes: "
+ IDS_MASHUP_WARP_SHADER " 4. warp shader: "
+ IDS_MASHUP_COMP_SHADER " 5. comp shader: "
+ IDS_STRING615 " tex2D(sampler_billy, uv) sample pixel from billy.jpg (must be loaded)\n"
+ IDS_STRING616 " pre-body: sampler sampler_billy; //loads billy.jpg"
+ IDS_STRING617 " float4 texsize_billy; //.xy = width and height, .zw = 1/w, 1/h"
+ IDS_STRING618 " sampling textures:"
+ IDS_STRING619 " tex2D(sampler_main, uv) //sample pixel from prior frame"
+ IDS_STRING620 " tex2D(sampler_billy, uv) //sample pixel from billy.jpg (must be loaded)"
+ IDS_STRING621 " GetBlur1(uv) //sample blurred prior-frame pixel (also 2,3)"
+ IDS_STRING622 " inputs: float2 uv; //warped UV coordinates [0..1]"
+ IDS_STRING623 " float2 uv_orig; //original UV coordinates [0..1]"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_STRING624 " float rad; //radius [0..1]"
+ IDS_STRING625 " float ang; //angle [0..PI*2]"
+ IDS_STRING626 " // + texsize, aspect, time, fps, rand_frame, rand_preset,"
+ IDS_STRING627 " // q1-q32/_qa-_qh, bass, treb_att, vol... - see docs"
+ IDS_STRING628 " output: float3 ret; //the new pixel color (r,g,b)"
+ IDS_STRING629 " inputs: float2 uv; //UV coordinates [0..1]"
+ IDS_STRING630 " float rad; //radius [0..1]"
+ IDS_STRING631 " float ang; //angle [0..PI*2]"
+ IDS_STRING632 " float3 hue_shader //for MilkDrop 1 compatibility"
+ IDS_STRING633 " // + texsize, aspect, time, fps, rand_frame, rand_preset,"
+ IDS_STRING634 " // q1-q32/_qa-_qh, bass, treb_att, vol... - see docs"
+ IDS_STRING635 " output: float3 ret; //display pixel color (r,g,b)"
+ IDS_UPGRADE_SHADERS_TO_USE_PS2X
+ "Do you want to upgrade all shaders to use (at least) pixel shader 2.X? [y/N]"
+ IDS_PRESS_ESC_TO_RETURN "Press ESC to return."
+ IDS_COULD_NOT_LOAD_TEXTURE_X "Could not load texture: %hs.%hs"
+ IDS_ERROR_COMPILING_X_X_SHADER "Error compiling %hs %hs shader:\n"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_ERROR_PARSING_X_X_SHADER "Error parsing %hs %hs shader.\n"
+ IDS_UNABLE_TO_RESOLVE_TEXSIZE_FOR_A_TEXTURE_NOT_IN_USE
+ "Unable to resolve texsize for a texture that is not in use! (%hs)"
+ IDS_KEY_MAPPINGS "yYYyYzZ"
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin.vcxproj b/Src/Plugins/Visualization/vis_milk2/plugin.vcxproj
new file mode 100644
index 00000000..67ca4c8d
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin.vcxproj
@@ -0,0 +1,419 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>vis_milk2</ProjectName>
+ <ProjectGuid>{881FB534-7396-485A-ADC2-6FBEBED7A0F4}</ProjectGuid>
+ <RootNamespace>vis_milk2</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\;..\..\..\Wasabi;..\..\..\external_dependencies\microsoft_directx_sdk_2010\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_DEBUG;_WINDOWS;USE_VIS_HDR_HWND;STRSAFE_NO_DEPRECATE;NSEEL_REENTRANT_EXECUTION;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4473;4477;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>vms_desktop.lib;d3d9.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\microsoft_directx_sdk_2010\Lib\$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <DelayLoadDLLs>vms_desktop.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(intDir)$(ProjectName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+
+xcopy /Y /D /S ..\..\..\resources\data\Milkdrop2 ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\resources\data\milk2_msg.ini ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\resources\data\milk2_img.ini ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+</Command>
+ <Message>Copy resources: Milkdrop2, milk2_msg.ini, milk2_img.ini to ..\..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Message>
+ </PostBuildEvent>
+ <ProjectReference>
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
+ </ProjectReference>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\;..\..\..\Wasabi;..\..\..\external_dependencies\microsoft_directx_sdk_2010\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;WIN64;_DEBUG;_WINDOWS;USE_VIS_HDR_HWND;STRSAFE_NO_DEPRECATE;NSEEL_REENTRANT_EXECUTION;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4473;4477;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>vms_desktop.lib;d3d9.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\..\..\external_dependencies\microsoft_directx_sdk_2010\Lib\$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <DelayLoadDLLs>vms_desktop.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(intDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+
+xcopy /Y /D /S ..\..\..\..\resources\data\Milkdrop2 ..\..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\..\resources\data\milk2_msg.ini ..\..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\..\resources\data\milk2_img.ini ..\..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+</Command>
+ <Message>Copy resources: Milkdrop2, milk2_msg.ini, milk2_img.ini to ..\..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..\;..\..\..\Wasabi;..\..\..\external_dependencies\microsoft_directx_sdk_2010\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;NDEBUG;_WINDOWS;USE_VIS_HDR_HWND;STRSAFE_NO_DEPRECATE;NSEEL_REENTRANT_EXECUTION;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4473;4477;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>vms_desktop.lib;d3d9.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\microsoft_directx_sdk_2010\Lib\$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <DelayLoadDLLs>vms_desktop.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(intDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D /S ..\..\..\resources\data\Milkdrop2 ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\resources\data\milk2_msg.ini ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\resources\data\milk2_img.ini ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+</Command>
+ <Message>Copy resources: Milkdrop2, milk2_msg.ini, milk2_img.ini to ..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..\;..\..\..\Wasabi;..\..\..\external_dependencies\microsoft_directx_sdk_2010\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;WIN64;NDEBUG;_WINDOWS;USE_VIS_HDR_HWND;STRSAFE_NO_DEPRECATE;NSEEL_REENTRANT_EXECUTION;_CRT_SECURE_NO_WARNINGS;_CRT_NON_CONFORMING_SWPRINTFS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4473;4477;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>vms_desktop.lib;d3d9.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalLibraryDirectories>..\..\..\external_dependencies\microsoft_directx_sdk_2010\Lib\$(PlatformShortName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <DelayLoadDLLs>vms_desktop.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(intDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D /S ..\..\..\resources\data\Milkdrop2 ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\resources\data\milk2_msg.ini ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+xcopy /Y /D /S ..\..\..\resources\data\milk2_img.ini ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\Milkdrop2\
+</Command>
+ <Message>Copy resources: Milkdrop2, milk2_msg.ini, milk2_img.ini to ..\..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="ns-eel2\nseel-caltab.c" />
+ <ClCompile Include="ns-eel2\nseel-cfunc.c" />
+ <ClCompile Include="ns-eel2\nseel-compiler.c" />
+ <ClCompile Include="ns-eel2\nseel-eval.c" />
+ <ClCompile Include="ns-eel2\nseel-lextab.c" />
+ <ClCompile Include="ns-eel2\nseel-ram.c" />
+ <ClCompile Include="ns-eel2\nseel-yylex.c" />
+ <ClCompile Include="config.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="config2.cpp" />
+ <ClCompile Include="desktop_mode.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="dxcontext.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="fft.cpp" />
+ <ClCompile Include="menu.cpp" />
+ <ClCompile Include="milkdropfs.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="plugin.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="pluginshell.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="state.cpp" />
+ <ClCompile Include="support.cpp" />
+ <ClCompile Include="texmgr.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="textmgr.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="utility.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_MBCS;</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_MBCS;</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="vis.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="plugin_icon.ico" />
+ <Image Include="temp.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\nu\AutoCharFn.h" />
+ <ClInclude Include="api__vis_milk2.h" />
+ <ClInclude Include="defines.h" />
+ <ClInclude Include="dxcontext.h" />
+ <ClInclude Include="fft.h" />
+ <ClInclude Include="gstring.h" />
+ <ClInclude Include="icon_t.h" />
+ <ClInclude Include="md_defines.h" />
+ <ClInclude Include="menu.h" />
+ <ClInclude Include="plugin.h" />
+ <ClInclude Include="pluginshell.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="shell_defines.h" />
+ <ClInclude Include="state.h" />
+ <ClInclude Include="support.h" />
+ <ClInclude Include="texmgr.h" />
+ <ClInclude Include="textmgr.h" />
+ <ClInclude Include="utility.h" />
+ <ClInclude Include="vis.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="plugin.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="DOCUMENTATION.TXT" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="milkdrop.nsi" />
+ <None Include="text1.bin" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\tataki\tataki.vcxproj">
+ <Project>{255b68b5-7ef8-45ef-a675-2d6b88147909}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin.vcxproj.filters b/Src/Plugins/Visualization/vis_milk2/plugin.vcxproj.filters
new file mode 100644
index 00000000..d271a059
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin.vcxproj.filters
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="vis.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="utility.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="textmgr.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="texmgr.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="support.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="state.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="pluginshell.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="plugin.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-yylex.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-ram.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-lextab.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-eval.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-compiler.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-cfunc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ns-eel2\nseel-caltab.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="milkdropfs.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="menu.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="fft.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dxcontext.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="desktop_mode.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="config2.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="config.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="api__vis_milk2.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="defines.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="dxcontext.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="fft.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="gstring.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="icon_t.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="md_defines.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="menu.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="plugin.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="pluginshell.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="shell_defines.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="state.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="support.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="vis.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="utility.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="textmgr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="texmgr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\nu\AutoCharFn.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="temp.ico">
+ <Filter>Image Files</Filter>
+ </Image>
+ <Image Include="plugin_icon.ico">
+ <Filter>Image Files</Filter>
+ </Image>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="milkdrop.nsi" />
+ <None Include="text1.bin" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="DOCUMENTATION.TXT" />
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{ce7fdde7-654e-45a5-b681-4fcbef840d29}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{4855ad07-70ea-4062-a58a-c2b86cd50226}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{e2bc9640-36e0-4507-a344-217bd59e980a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Image Files">
+ <UniqueIdentifier>{afa2593b-8914-4582-8765-a249b22e82af}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="plugin.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/plugin_icon.ico b/Src/Plugins/Visualization/vis_milk2/plugin_icon.ico
new file mode 100644
index 00000000..a48a54f3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/plugin_icon.ico
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_milk2/pluginshell.cpp b/Src/Plugins/Visualization/vis_milk2/pluginshell.cpp
new file mode 100644
index 00000000..cd79a410
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/pluginshell.cpp
@@ -0,0 +1,3693 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ TO DO
+ -----
+ -done/v1.06:
+ -(nothing yet)
+ -
+ -
+ -to do/v1.06:
+ -FFT: high freq. data kinda sucks because of the 8-bit samples we get in;
+ look for justin to put 16-bit vis data into wa5.
+ -make an 'advanced view' button on config panel; hide complicated stuff
+ til they click that.
+ -put an asterisk(*) next to the 'max framerate' values that
+ are ideal (given the current windows display mode or selected FS dispmode).
+ -or add checkbox: "smart sync"
+ -> matches FPS limit to nearest integer divisor of refresh rate.
+ -debug.txt/logging support!
+ -audio: make it a DSP plugin? then we could get the complete, continuous waveform
+ and overlap our waveform windows, so we'd never miss a brief high note.
+ -bugs:
+ -vms plugins sometimes freeze after a several-minute pause; I've seen it
+ with most of them. hard to repro, though.
+ -running FS on monitor 2, hit ALT-TAB -> minimizes!!!
+ -but only if you let go of TAB first. Let go of ALT first and it's fine!
+ -> means it's related to the keyup...
+ -fix delayloadhelper leak; one for each launch to config panel/plugin.
+ -also, delayload(d3d9.dll) still leaks, if plugin has error initializing and
+ quits by returning false from PluginInitialize().
+ -add config panel option to ignore fake-fullscreen tips
+ -"tip" boxes in dxcontext.cpp
+ -"notice" box on WM_ACTIVATEAPP?
+ -desktop mode:
+ -icon context menus: 'send to', 'cut', and 'copy' links do nothing.
+ -http://netez.com/2xExplorer/shellFAQ/bas_context.html
+ -create a 2nd texture to render all icon text labels into
+ (they're the sole reason that desktop mode is slow)
+ -in UpdateIconBitmaps, don't read the whole bitmap and THEN
+ realize it's a dupe; try to compare icon filename+index or somethign?
+ -DRAG AND DROP. COMPLICATED; MANY DETAILS.
+ -http://netez.com/2xExplorer/shellFAQ/adv_drag.html
+ -http://www.codeproject.com/shell/explorerdragdrop.asp
+ -hmm... you can't drag icons between the 2 desktops (ugh)
+ -multiple delete/open/props/etc
+ -delete + enter + arrow keys.
+ -try to solve mysteries w/ShellExecuteEx() and desktop *shortcuts* (*.lnk).
+ -(notice that when icons are selected, they get modulated by the
+ highlight color, when they should be blended 50% with that color.)
+
+ ---------------------------
+ final touches:
+ -Tests:
+ -make sure desktop still functions/responds properly when winamp paused
+ -desktop mode + multimon:
+ -try desktop mode on all monitors
+ -try moving taskbar around; make sure icons are in the
+ right place, that context menus (general & for
+ specific icons) pop up in the right place, and that
+ text-off-left-edge is ok.
+ -try setting the 2 monitors to different/same resolutions
+ -check tab order of config panel controls!
+ -Clean All
+ -build in release mode to include in the ZIP
+ -leave only one file open in workspace: README.TXT.
+ -TEMPORARILY "ATTRIB -R" ALL FILES BEFORE ZIPPING THEM!
+
+ ---------------------------
+ KEEP IN VIEW:
+ -EMBEDWND:
+ -kiv: on resize of embedwnd, it's out of our control; winamp
+ resizes the child every time the mouse position changes,
+ and we have to cleanup & reallocate everything, b/c we
+ can't tell when the resize begins & ends.
+ [justin said he'd fix in wa5, though]
+ -kiv: with embedded windows of any type (plugin, playlist, etc.)
+ you can't place the winamp main wnd over them.
+ -kiv: embedded windows are child windows and don't get the
+ WM_SETFOCUS or WM_KILLFOCUS messages when they get or lose
+ the focus. (For a workaround, see milkdrop & scroll lock key.)
+ -kiv: tiny bug (IGNORE): when switching between embedwnd &
+ no-embedding, the window gets scooted a tiny tiny bit.
+ -kiv: fake fullscreen mode w/multiple monitors: there is no way
+ to keep the taskbar from popping up [potentially overtop of
+ the plugin] when you click on something besides the plugin.
+ To get around this, use true fullscreen mode.
+ -kiv: max_fps implementation assumptions:
+ -that most computers support high-precision timer
+ -that no computers [regularly] sleep for more than 1-2 ms
+ when you call Sleep(1) after timeBeginPeriod(1).
+ -reminder: if vms_desktop.dll's interface needs changed,
+ it will have to be renamed! (version # upgrades are ok
+ as long as it won't break on an old version; if the
+ new functionality is essential, rename the DLL.)
+
+ ---------------------------
+ REMEMBER:
+ -GF2MX + GF4 have icon scooting probs in desktop mode
+ (when taskbar is on upper or left edge of screen)
+ -Radeon is the one w/super slow text probs @ 1280x1024.
+ (it goes unstable after you show playlist AND helpscr; -> ~1 fps)
+ -Mark's win98 machine has hidden cursor (in all modes),
+ but no one else seems to have this problem.
+ -links:
+ -win2k-only-style desktop mode: (uses VirtualAllocEx, vs. DLL Injection)
+ http://www.digiwar.com/scripts/renderpage.php?section=2&subsection=2
+ -http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_20096218.html
+*/
+
+#include "api__vis_milk2.h"
+#include "pluginshell.h"
+#include "utility.h"
+#include "defines.h"
+#include "shell_defines.h"
+#include "resource.h"
+#include "vis.h"
+#include <multimon.h>
+#include "../Winamp/wa_ipc.h"
+#include "../nu/AutoCharFn.h"
+#include <mmsystem.h>
+#pragma comment(lib,"winmm.lib") // for timeGetTime
+
+// STATE VALUES & VERTEX FORMATS FOR HELP SCREEN TEXTURE:
+#define TEXT_SURFACE_NOT_READY 0
+#define TEXT_SURFACE_REQUESTED 1
+#define TEXT_SURFACE_READY 2
+#define TEXT_SURFACE_ERROR 3
+typedef struct _HELPVERTEX
+{
+ float x, y; // screen position
+ float z; // Z-buffer depth
+ DWORD Diffuse; // diffuse color. also acts as filler; aligns struct to 16 bytes (good for random access/indexed prims)
+ float tu, tv; // texture coordinates for texture #0
+} HELPVERTEX, *LPHELPVERTEX;
+#define HELP_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
+typedef struct _SIMPLEVERTEX
+{
+ float x, y; // screen position
+ float z; // Z-buffer depth
+ DWORD Diffuse; // diffuse color. also acts as filler; aligns struct to 16 bytes (good for random access/indexed prims)
+} SIMPLEVERTEX, *LPSIMPLEVERTEX;
+#define SIMPLE_VERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE)
+
+extern wchar_t* g_szHelp;
+extern int g_szHelp_W;
+extern winampVisModule mod1;
+
+// resides in vms_desktop.dll/lib:
+void getItemData(int x);
+
+
+CPluginShell::CPluginShell()
+{
+ // this should remain empty!
+}
+
+CPluginShell::~CPluginShell()
+{
+ // this should remain empty!
+}
+
+eScrMode CPluginShell::GetScreenMode()
+{
+ return m_screenmode;
+}
+int CPluginShell::GetFrame()
+{
+ return m_frame;
+}
+float CPluginShell::GetTime()
+{
+ return m_time;
+}
+float CPluginShell::GetFps()
+{
+ return m_fps;
+}
+HWND CPluginShell::GetPluginWindow()
+{
+ if (m_lpDX) return m_lpDX->GetHwnd(); else return NULL;
+}
+int CPluginShell::GetWidth()
+{
+ if (m_lpDX) return m_lpDX->m_client_width; else return 0;
+}
+int CPluginShell::GetHeight()
+{
+ if (m_lpDX) return m_lpDX->m_client_height; else return 0;
+}
+int CPluginShell::GetCanvasMarginX()
+{
+ if (m_lpDX && m_screenmode==WINDOWED) return (m_lpDX->m_client_width - m_lpDX->m_REAL_client_width)/2; else return 0;
+}
+int CPluginShell::GetCanvasMarginY()
+{
+ if (m_lpDX && m_screenmode==WINDOWED) return (m_lpDX->m_client_height - m_lpDX->m_REAL_client_height)/2; else return 0;
+}
+HWND CPluginShell::GetWinampWindow()
+{
+ return m_hWndWinamp;
+}
+HINSTANCE CPluginShell::GetInstance()
+{
+ return m_hInstance;
+}
+wchar_t* CPluginShell::GetPluginsDirPath()
+{
+ return m_szPluginsDirPath;
+}
+wchar_t* CPluginShell::GetConfigIniFile()
+{
+ return m_szConfigIniFile;
+}
+char* CPluginShell::GetConfigIniFileA()
+{
+ return m_szConfigIniFileA;
+}
+int CPluginShell::GetFontHeight(eFontIndex idx)
+{
+ if (idx >= 0 && idx < NUM_BASIC_FONTS + NUM_EXTRA_FONTS) return m_fontinfo[idx].nSize; else return 0;
+}
+int CPluginShell::GetBitDepth()
+{
+ return m_lpDX->GetBitDepth();
+}
+LPDIRECT3DDEVICE9 CPluginShell::GetDevice()
+{
+ if (m_lpDX) return m_lpDX->m_lpDevice; else return NULL;
+}
+D3DCAPS9* CPluginShell::GetCaps()
+{
+ if (m_lpDX) return &(m_lpDX->m_caps); else return NULL;
+}
+D3DFORMAT CPluginShell::GetBackBufFormat()
+{
+ if (m_lpDX) return m_lpDX->m_current_mode.display_mode.Format; else return D3DFMT_UNKNOWN;
+}
+D3DFORMAT CPluginShell::GetBackBufZFormat()
+{
+ if (m_lpDX) return m_lpDX->GetZFormat(); else return D3DFMT_UNKNOWN;
+}
+LPD3DXFONT CPluginShell::GetFont(eFontIndex idx)
+{
+ if (idx >= 0 && idx < NUM_BASIC_FONTS + NUM_EXTRA_FONTS) return m_d3dx_font[idx]; else return NULL;
+}
+char* CPluginShell::GetDriverFilename()
+{
+ if (m_lpDX) return m_lpDX->GetDriver(); else return NULL;
+}
+char* CPluginShell::GetDriverDescription()
+{
+ if (m_lpDX) return m_lpDX->GetDesc(); else return NULL;
+}
+
+int CPluginShell::InitNondx9Stuff()
+{
+ timeBeginPeriod(1);
+ m_fftobj.Init(576, NUM_FREQUENCIES);
+ if (!InitGDIStuff()) return false;
+ return AllocateMyNonDx9Stuff();
+}
+
+void CPluginShell::CleanUpNondx9Stuff()
+{
+ timeEndPeriod(1);
+ CleanUpMyNonDx9Stuff();
+ CleanUpGDIStuff();
+ m_fftobj.CleanUp();
+}
+
+int CPluginShell::InitGDIStuff()
+{
+ wchar_t title[64];
+ // note: messagebox parent window should be NULL here, because lpDX is still NULL!
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ {
+ if (!(m_font[i] = CreateFontW(m_fontinfo[i].nSize, 0, 0, 0, m_fontinfo[i].bBold ? 900 : 400, m_fontinfo[i].bItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, m_fontinfo[i].bAntiAliased ? ANTIALIASED_QUALITY : DEFAULT_QUALITY, DEFAULT_PITCH, m_fontinfo[i].szFace)))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_GDI_FONTS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+ }
+
+ if (!(m_main_menu = WASABI_API_LOADMENU(IDR_WINDOWED_CONTEXT_MENU)))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_LOADING_MAIN_MENU),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ if (!(m_context_menu = GetSubMenu(m_main_menu, 0)))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_LOADING_CONTEXT_MENU),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ return true;
+}
+
+void CPluginShell::CleanUpGDIStuff()
+{
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ {
+ if (m_font[i])
+ {
+ DeleteObject(m_font[i]);
+ m_font[i] = NULL;
+ }
+ }
+
+ /*if (m_context_menu)
+ {
+ DestroyMenu(m_context_menu);
+ m_context_menu = NULL;
+ }*/
+
+ if (m_main_menu)
+ {
+ DestroyMenu(m_main_menu);
+ m_main_menu = NULL;
+ }
+
+ //CleanUpMyGDIStuff();
+}
+
+int CPluginShell::InitVJStuff(RECT* pClientRect)
+{
+ wchar_t title[64];
+ // Init VJ mode (second window for text):
+ if (m_vj_mode)
+ {
+ DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU;
+ POINT upper_left_corner;
+ upper_left_corner.x = 0;
+ upper_left_corner.y = 0;
+
+ // Create direct 3d & get some infos
+ if (!(m_vjd3d9 = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_DIRECT3D_DEVICE_FOR_VJ_MODE),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64), MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ // Get ordinal adapter # for the currently-selected Windowed Mode display adapter
+ int ordinal_adapter = D3DADAPTER_DEFAULT;
+ int nAdapters = m_vjd3d9->GetAdapterCount();
+ for (int i=0; i<nAdapters; i++)
+ {
+ D3DADAPTER_IDENTIFIER9 temp;
+ if ((m_vjd3d9->GetAdapterIdentifier(i, /*D3DENUM_NO_WHQL_LEVEL*/ 0, &temp) == D3D_OK) &&
+ (memcmp(&temp.DeviceIdentifier, &m_adapter_guid_windowed, sizeof(GUID))==0))
+ {
+ ordinal_adapter = i;
+ break;
+ }
+ }
+
+ // Get current display mode for windowed-mode adapter:
+ D3DDISPLAYMODE dm;
+ if (D3D_OK != m_vjd3d9->GetAdapterDisplayMode(ordinal_adapter, &dm))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_VJ_MODE_INIT_ERROR),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ // And get the upper-left corner of the monitor for it:
+ HMONITOR hMon = m_vjd3d9->GetAdapterMonitor(ordinal_adapter);
+ if (hMon)
+ {
+ MONITORINFO mi;
+ mi.cbSize = sizeof(mi);
+ if (GetMonitorInfo(hMon, &mi))
+ {
+ upper_left_corner.x = mi.rcWork.left;
+ upper_left_corner.y = mi.rcWork.top;
+ }
+ }
+
+ // CREATE THE WINDOW
+
+ RECT rect;
+ if (pClientRect)
+ {
+ rect = *pClientRect;
+ AdjustWindowRect(&rect, dwStyle, 0); // convert client->wnd
+ }
+ else
+ {
+ SetRect(&rect, 0, 0, 384, 384);
+ AdjustWindowRect(&rect, dwStyle, 0); // convert client->wnd
+
+ rect.right -= rect.left;
+ rect.left = 0;
+ rect.bottom -= rect.top;
+ rect.top = 0;
+
+ rect.top += upper_left_corner.y+32;
+ rect.left += upper_left_corner.x+32;
+ rect.right += upper_left_corner.x+32;
+ rect.bottom += upper_left_corner.y+32;
+ }
+
+ WNDCLASS wc = {0};
+ wc.lpfnWndProc = VJModeWndProc; // our window procedure
+ wc.hInstance = GetInstance(); // hInstance of DLL
+ wc.hIcon = LoadIcon(GetInstance(), MAKEINTRESOURCE(IDI_PLUGIN_ICON));
+ wc.lpszClassName = TEXT_WINDOW_CLASSNAME; // our window class name
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // CS_DBLCLKS lets the window receive WM_LBUTTONDBLCLK, for toggling fullscreen mode...
+ wc.cbWndExtra = sizeof(DWORD);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
+
+ if (!RegisterClass(&wc))
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_REGISTERING_WINDOW_CLASS_FOR_TEXT_WINDOW),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+ m_bTextWindowClassRegistered = true;
+
+ //DWORD nThreadID;
+ //CreateThread(NULL, 0, TextWindowThread, &rect, 0, &nThreadID);
+
+ // Create the text window
+ m_hTextWnd = CreateWindowEx(
+ 0,
+ TEXT_WINDOW_CLASSNAME, // our window class name
+ TEXT_WINDOW_CLASSNAME, // use description for a window title
+ dwStyle,
+ rect.left, rect.top, // screen position (read from config)
+ rect.right - rect.left, rect.bottom - rect.top, // width & height of window (need to adjust client area later)
+ NULL, // parent window (winamp main window)
+ NULL, // no menu
+ GetInstance(), // hInstance of DLL
+ NULL
+ ); // no window creation data
+
+ if (!m_hTextWnd)
+ {
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_VJ_WINDOW),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ SetWindowLongPtr(m_hTextWnd, GWLP_USERDATA, (LONG_PTR)this);
+
+ GetClientRect(m_hTextWnd, &rect);
+ m_nTextWndWidth = rect.right-rect.left;
+ m_nTextWndHeight = rect.bottom-rect.top;
+
+
+ // Create the device
+ D3DPRESENT_PARAMETERS pres_param;
+ ZeroMemory(&pres_param,sizeof(pres_param));
+ pres_param.BackBufferCount = 0;
+ pres_param.BackBufferFormat = dm.Format;
+ pres_param.BackBufferWidth = rect.right - rect.left;
+ pres_param.BackBufferHeight = rect.bottom - rect.top;
+ pres_param.hDeviceWindow = m_hTextWnd;
+ pres_param.AutoDepthStencilFormat = D3DFMT_D16;
+ pres_param.EnableAutoDepthStencil = FALSE;
+ pres_param.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ pres_param.MultiSampleType = D3DMULTISAMPLE_NONE;
+ pres_param.Flags = 0;
+ pres_param.FullScreen_RefreshRateInHz = 0;
+ pres_param.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT_INTERVAL_ONE;//D3DPRESENT_INTERVAL_IMMEDIATE;//m_current_mode.allow_page_tearing ? D3DPRESENT_INTERVAL_IMMEDIATE : D3DPRESENT_INTERVAL_ONE;//D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT_INTERVAL_ONE;
+ //pres_param.FullScreen_PresentationInterval = 0;
+ pres_param.Windowed = TRUE;
+
+ HRESULT hr;
+ if (D3D_OK != (hr = m_vjd3d9->CreateDevice(ordinal_adapter,//D3DADAPTER_DEFAULT,
+ D3DDEVTYPE_HAL,
+ m_hTextWnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+ &pres_param,
+ &m_vjd3d9_device)))
+ {
+ m_vjd3d9_device = NULL;
+ MessageBoxW(m_lpDX->GetHwnd(), WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_D3D_DEVICE_FOR_VJ_MODE),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ if (!AllocateFonts(m_vjd3d9_device))
+ return false;
+
+ if (m_fix_slow_text) // note that when not doing vj mode, m_lpDDSText is allocated in AllocateDX9Stuff
+ AllocateTextSurface();
+
+ m_text.Finish();
+ m_text.Init(m_vjd3d9_device, m_lpDDSText, 0);
+
+ m_bClearVJWindow = true;
+ }
+
+ return true;
+}
+
+void CPluginShell::CleanUpVJStuff()
+{
+ // ALWAYS set the textures to NULL before releasing textures,
+ // otherwise they might still have a hanging reference!
+ if (m_lpDX && m_lpDX->m_lpDevice)
+ {
+ for (int i=0; i<16; i++)
+ m_lpDX->m_lpDevice->SetTexture(i, NULL);
+ }
+
+ if (m_vjd3d9_device)
+ {
+ for (int i=0; i<16; i++)
+ m_vjd3d9_device->SetTexture(i, NULL);
+ }
+
+ if (!m_vj_mode)
+ return;
+
+ // clean up VJ mode
+ {
+ CleanUpFonts();
+ SafeRelease(m_lpDDSText);
+
+ SafeRelease(m_vjd3d9_device);
+ SafeRelease(m_vjd3d9);
+
+ if (m_hTextWnd)
+ {
+ //dumpmsg("Finish: destroying text window");
+ DestroyWindow(m_hTextWnd);
+ m_hTextWnd = NULL;
+ //dumpmsg("Finish: text window destroyed");
+ }
+
+ if (m_bTextWindowClassRegistered)
+ {
+ //dumpmsg("Finish: unregistering text window class");
+ UnregisterClass(TEXT_WINDOW_CLASSNAME,GetInstance()); // unregister window class
+ m_bTextWindowClassRegistered = false;
+ //dumpmsg("Finish: text window class unregistered");
+ }
+ }
+}
+
+int CPluginShell::AllocateFonts(IDirect3DDevice9* pDevice)
+{
+ // Create D3DX system font:
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ if (pCreateFontW(pDevice, //m_font[i],
+ m_fontinfo[i].nSize,
+ m_fontinfo[i].nSize*4/10,
+ m_fontinfo[i].bBold ? 900 : 400,
+ 1, // mip levels
+ m_fontinfo[i].bItalic,
+ DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ m_fontinfo[i].bAntiAliased ? ANTIALIASED_QUALITY : DEFAULT_QUALITY,
+ DEFAULT_PITCH,
+ m_fontinfo[i].szFace,
+ &m_d3dx_font[i]
+ ) != D3D_OK)
+ {
+ wchar_t title[64];
+ MessageBoxW(m_lpDX ? m_lpDX->GetHwnd() : NULL, WASABI_API_LNGSTRINGW(IDS_ERROR_CREATING_D3DX_FONTS),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ // get actual font heights
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ {
+ RECT r;
+ SetRect(&r, 0, 0, 1024, 1024);
+ int h = m_d3dx_font[i]->DrawText(NULL, "M", -1, &r, DT_CALCRECT, 0xFFFFFFFF);
+ if (h>0) m_fontinfo[i].nSize = h;
+ }
+
+ return true;
+}
+
+void CPluginShell::CleanUpFonts()
+{
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ SafeRelease(m_d3dx_font[i]);
+}
+
+void CPluginShell::AllocateTextSurface()
+{
+ IDirect3DDevice9 *pDevice = m_vjd3d9_device ? m_vjd3d9_device : GetDevice();
+ int w = m_vjd3d9_device ? m_nTextWndWidth : GetWidth() ;
+ int h = m_vjd3d9_device ? m_nTextWndHeight : GetHeight();
+
+ if (D3D_OK != pCreateTexture(pDevice, w, h, 1, D3DUSAGE_RENDERTARGET, GetBackBufFormat(), D3DPOOL_DEFAULT, &m_lpDDSText))
+ m_lpDDSText = NULL; // OK if there's not enough mem for it!
+ else
+ {
+ // if m_lpDDSText doesn't cover enough of screen, cancel it.
+ D3DSURFACE_DESC desc;
+ if (D3D_OK == m_lpDDSText->GetLevelDesc(0, &desc))
+ {
+ if ((desc.Width < 256 && w >= 256) ||
+ (desc.Height < 256 && h >= 256) ||
+ (desc.Width /(float)w < 0.74f) ||
+ (desc.Height/(float)h < 0.74f)
+ )
+ {
+ m_lpDDSText->Release();
+ m_lpDDSText = NULL;
+ }
+ }
+ }
+}
+
+int CPluginShell::AllocateDX9Stuff()
+{
+ if (!m_vj_mode)
+ {
+ AllocateFonts(m_lpDX->m_lpDevice);
+ if (m_fix_slow_text) // note that when not doing vj mode, m_lpDDSText is allocated in AllocateDX9Stuff
+ AllocateTextSurface();
+ }
+
+ /*
+ // Create D3DX system font:
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ if (pCreateFontW(m_lpDX->m_lpDevice,
+ m_fontinfo[i].nSize,
+ m_fontinfo[i].nSize*4/10,
+ m_fontinfo[i].bBold ? 900 : 400,
+ 0, // mip levels
+ m_fontinfo[i].bItalic,
+ DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS,
+ m_fontinfo[i].bAntiAliased ? ANTIALIASED_QUALITY : DEFAULT_QUALITY,
+ DEFAULT_PITCH,
+ m_fontinfo[i].szFace,
+ &m_d3dx_font[i]
+ ) != D3D_OK)
+ {
+ MessageBox(m_lpDX->GetHwnd(), "Error creating D3DX fonts", "ERROR", MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ // get actual font heights
+ for (i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ {
+ RECT r;
+ SetRect(&r, 0, 0, 1024, 1024);
+ int h = m_d3dx_font[i]->DrawText(NULL, "M", -1, &r, DT_CALCRECT, 0xFFFFFFFF);
+ if (h>0) m_fontinfo[i].nSize = h;
+ }
+ */
+
+ if (m_screenmode == DESKTOP)
+ if (!InitDesktopMode())
+ return false;
+
+ int ret = AllocateMyDX9Stuff();
+
+ // invalidate various 'caches' here:
+ m_playlist_top_idx = -1; // invalidating playlist cache forces recompute of playlist width
+ //m_icon_list.clear(); // clear desktop mode icon list, so it has to read the bitmaps back in
+
+ if (!m_vj_mode)
+ {
+ m_text.Finish();
+ m_text.Init(GetDevice(), m_lpDDSText, 1);
+ }
+
+ return ret;
+}
+
+void CPluginShell::CleanUpDX9Stuff(int final_cleanup)
+{
+ // ALWAYS unbind the textures before releasing textures,
+ // otherwise they might still have a hanging reference!
+ if (m_lpDX && m_lpDX->m_lpDevice)
+ {
+ for (int i=0; i<16; i++)
+ m_lpDX->m_lpDevice->SetTexture(i, NULL);
+ }
+
+ if (m_screenmode == DESKTOP)
+ CleanUpDesktopMode();
+
+ if (!m_vj_mode)
+ {
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ SafeRelease(m_d3dx_font[i]);
+ SafeRelease(m_lpDDSText);
+ }
+
+ CleanUpMyDX9Stuff(final_cleanup);
+}
+
+void CPluginShell::OnUserResizeTextWindow()
+{
+ // Update window properties
+ RECT w, c;
+ GetWindowRect(m_hTextWnd, &w);
+ GetClientRect(m_hTextWnd, &c);
+
+ WINDOWPLACEMENT wp;
+ ZeroMemory(&wp, sizeof(wp));
+ wp.length = sizeof(wp);
+ GetWindowPlacement(m_hTextWnd, &wp);
+
+ // convert client rect from client coords to screen coords:
+ // (window rect is already in screen coords...)
+ POINT p;
+ p.x = c.left;
+ p.y = c.top;
+ if (ClientToScreen(m_hTextWnd, &p))
+ {
+ c.left += p.x;
+ c.right += p.x;
+ c.top += p.y;
+ c.bottom += p.y;
+ }
+
+ if (wp.showCmd != SW_SHOWMINIMIZED)
+ {
+ if (m_nTextWndWidth != c.right-c.left ||
+ m_nTextWndHeight != c.bottom-c.top)
+ {
+ CleanUpVJStuff();
+ if (!InitVJStuff(&c))
+ {
+ SuggestHowToFreeSomeMem();
+ m_lpDX->m_ready = false; // flag to exit
+ return;
+ }
+ }
+
+ // save the new window position:
+ //if (wp.showCmd==SW_SHOWNORMAL)
+ // SaveTextWindowPos();
+ }
+}
+
+void CPluginShell::OnUserResizeWindow()
+{
+ // Update window properties
+ RECT w, c;
+ GetWindowRect(m_lpDX->GetHwnd(), &w);
+ GetClientRect(m_lpDX->GetHwnd(), &c);
+
+ WINDOWPLACEMENT wp;
+ ZeroMemory(&wp, sizeof(wp));
+ wp.length = sizeof(wp);
+ GetWindowPlacement(m_lpDX->GetHwnd(), &wp);
+
+ // convert client rect from client coords to screen coords:
+ // (window rect is already in screen coords...)
+ POINT p;
+ p.x = c.left;
+ p.y = c.top;
+ if (ClientToScreen(m_lpDX->GetHwnd(), &p))
+ {
+ c.left += p.x;
+ c.right += p.x;
+ c.top += p.y;
+ c.bottom += p.y;
+ }
+
+ if (wp.showCmd != SW_SHOWMINIMIZED)
+ {
+ int new_REAL_client_w = c.right-c.left;
+ int new_REAL_client_h = c.bottom-c.top;
+
+ // kiv: could we just resize when the *snapped* w/h changes? slightly more ideal...
+ if (m_lpDX->m_REAL_client_width != new_REAL_client_w ||
+ m_lpDX->m_REAL_client_height != new_REAL_client_h)
+ {
+ //CleanUpVJStuff();
+ CleanUpDX9Stuff(0);
+ if (!m_lpDX->OnUserResizeWindow(&w, &c))
+ {
+ // note: a basic warning messagebox will have already been given.
+ // now suggest specific advice on how to regain more video memory:
+ SuggestHowToFreeSomeMem();
+ return;
+ }
+ if (!AllocateDX9Stuff())
+ {
+ m_lpDX->m_ready = false; // flag to exit
+ return;
+ }
+ /*if (!InitVJStuff())
+ {
+ m_lpDX->m_ready = false; // flag to exit
+ return;
+ }*/
+ }
+
+ // save the new window position:
+ if (wp.showCmd==SW_SHOWNORMAL)
+ m_lpDX->SaveWindow();
+ }
+}
+
+void CPluginShell::StuffParams(DXCONTEXT_PARAMS *pParams)
+{
+ pParams->screenmode = m_screenmode;
+ pParams->display_mode = m_disp_mode_fs;
+ pParams->nbackbuf = 1;
+ pParams->m_dualhead_horz = m_dualhead_horz;
+ pParams->m_dualhead_vert = m_dualhead_vert;
+ pParams->m_skin = (m_screenmode==WINDOWED) ? m_skin : 0;
+ switch (m_screenmode)
+ {
+ case WINDOWED:
+ pParams->allow_page_tearing = m_allow_page_tearing_w;
+ pParams->adapter_guid = m_adapter_guid_windowed;
+ pParams->multisamp = m_multisample_windowed;
+ strcpy(pParams->adapter_devicename, m_adapter_devicename_windowed);
+ break;
+ case FULLSCREEN:
+ case FAKE_FULLSCREEN:
+ pParams->allow_page_tearing = m_allow_page_tearing_fs;
+ pParams->adapter_guid = m_adapter_guid_fullscreen;
+ pParams->multisamp = m_multisample_fullscreen;
+ strcpy(pParams->adapter_devicename, m_adapter_devicename_fullscreen);
+ break;
+ case DESKTOP:
+ pParams->allow_page_tearing = m_allow_page_tearing_dm;
+ pParams->adapter_guid = m_adapter_guid_desktop;
+ pParams->multisamp = m_multisample_desktop;
+ strcpy(pParams->adapter_devicename, m_adapter_devicename_desktop);
+ break;
+ }
+ pParams->parent_window = (m_screenmode==DESKTOP) ? m_hWndDesktopListView : NULL;
+}
+
+void CPluginShell::ToggleDesktop()
+{
+ CleanUpDX9Stuff(0);
+
+ switch (m_screenmode)
+ {
+ case WINDOWED:
+ case FULLSCREEN:
+ case FAKE_FULLSCREEN:
+ m_screenmode = DESKTOP;
+ break;
+ case DESKTOP:
+ m_screenmode = WINDOWED;
+ break;
+ }
+
+ DXCONTEXT_PARAMS params;
+ StuffParams(&params);
+
+ if (!m_lpDX->StartOrRestartDevice(&params))
+ {
+ // note: a basic warning messagebox will have already been given.
+ if (m_lpDX->m_lastErr == DXC_ERR_CREATEDEV_PROBABLY_OUTOFVIDEOMEMORY)
+ SuggestHowToFreeSomeMem();
+ return;
+ }
+
+ if (!AllocateDX9Stuff())
+ {
+ m_lpDX->m_ready = false; // flag to exit
+ return;
+ }
+
+ SetForegroundWindow(m_lpDX->GetHwnd());
+ SetActiveWindow(m_lpDX->GetHwnd());
+ SetFocus(m_lpDX->GetHwnd());
+}
+
+#define IPC_IS_PLAYING_VIDEO 501 // from wa_ipc.h
+#define IPC_SET_VIS_FS_FLAG 631 // a vis should send this message with 1/as param to notify winamp that it has gone to or has come back from fullscreen mode
+
+void CPluginShell::ToggleFullScreen()
+{
+ CleanUpDX9Stuff(0);
+
+ switch (m_screenmode)
+ {
+ case DESKTOP:
+ case WINDOWED:
+ m_screenmode = m_fake_fullscreen_mode ? FAKE_FULLSCREEN : FULLSCREEN;
+ if (m_screenmode == FULLSCREEN && SendMessage(GetWinampWindow(), WM_WA_IPC, 0, IPC_IS_PLAYING_VIDEO) > 1)
+ {
+ m_screenmode = FAKE_FULLSCREEN;
+ }
+ SendMessage(GetWinampWindow(), WM_WA_IPC, 1, IPC_SET_VIS_FS_FLAG);
+ break;
+ case FULLSCREEN:
+ case FAKE_FULLSCREEN:
+ m_screenmode = WINDOWED;
+ SendMessage(GetWinampWindow(), WM_WA_IPC, 0, IPC_SET_VIS_FS_FLAG);
+ break;
+ }
+
+ DXCONTEXT_PARAMS params;
+ StuffParams(&params);
+
+ if (!m_lpDX->StartOrRestartDevice(&params))
+ {
+ // note: a basic warning messagebox will have already been given.
+ if (m_lpDX->m_lastErr == DXC_ERR_CREATEDEV_PROBABLY_OUTOFVIDEOMEMORY)
+ SuggestHowToFreeSomeMem();
+ return;
+ }
+
+ if (!AllocateDX9Stuff())
+ {
+ m_lpDX->m_ready = false; // flag to exit
+ return;
+ }
+
+ SetForegroundWindow(m_lpDX->GetHwnd());
+ SetActiveWindow(m_lpDX->GetHwnd());
+ SetFocus(m_lpDX->GetHwnd());
+}
+
+void CPluginShell::ToggleHelp()
+{
+ m_show_help = 1-m_show_help;
+ int ret = CheckMenuItem(m_context_menu, ID_SHOWHELP, MF_BYCOMMAND | (m_show_help ? MF_CHECKED : MF_UNCHECKED));
+}
+
+void CPluginShell::TogglePlaylist()
+{
+ m_show_playlist = 1-m_show_playlist;
+ m_playlist_top_idx = -1; // <- invalidates playlist cache
+ int ret = CheckMenuItem(m_context_menu, ID_SHOWPLAYLIST, MF_BYCOMMAND | (m_show_playlist ? MF_CHECKED : MF_UNCHECKED));
+}
+
+int CPluginShell::InitDirectX()
+{
+ m_lpDX = new DXContext(m_hWndWinamp,m_hInstance,CLASSNAME,WINDOWCAPTION,CPluginShell::WindowProc,(LONG_PTR)this, m_minimize_winamp, m_szConfigIniFile);
+
+ if (!m_lpDX)
+ {
+ wchar_t title[64];
+ MessageBoxW(NULL, WASABI_API_LNGSTRINGW(IDS_UNABLE_TO_INIT_DXCONTEXT),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return FALSE;
+ }
+
+ if (m_lpDX->m_lastErr != S_OK)
+ {
+ // warning messagebox will have already been given
+ delete m_lpDX;
+ return FALSE;
+ }
+
+ // initialize graphics
+ DXCONTEXT_PARAMS params;
+ StuffParams(&params);
+
+ if (!m_lpDX->StartOrRestartDevice(&params))
+ {
+ // note: a basic warning messagebox will have already been given.
+
+ if (m_lpDX->m_lastErr == DXC_ERR_CREATEDEV_PROBABLY_OUTOFVIDEOMEMORY)
+ {
+ // suggest specific advice on how to regain more video memory:
+ SuggestHowToFreeSomeMem();
+ }
+
+ delete m_lpDX;
+ m_lpDX = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void CPluginShell::CleanUpDirectX()
+{
+ SafeDelete(m_lpDX);
+}
+
+int CPluginShell::PluginPreInitialize(HWND hWinampWnd, HINSTANCE hWinampInstance)
+{
+ // PROTECTED CONFIG PANEL SETTINGS (also see 'private' settings, below)
+ m_start_fullscreen = 0;
+ m_start_desktop = 0;
+ m_fake_fullscreen_mode = 0;
+ m_max_fps_fs = 30;
+ m_max_fps_dm = 30;
+ m_max_fps_w = 30;
+ m_show_press_f1_msg = 1;
+ m_allow_page_tearing_w = 1;
+ m_allow_page_tearing_fs = 0;
+ m_allow_page_tearing_dm = 0;
+ m_minimize_winamp = 1;
+ m_desktop_show_icons = 1;
+ m_desktop_textlabel_boxes = 1;
+ m_desktop_manual_icon_scoot = 0;
+ m_desktop_555_fix = 2;
+ m_dualhead_horz = 2;
+ m_dualhead_vert = 1;
+ m_save_cpu = 1;
+ m_skin = 1;
+ m_fix_slow_text = 0;
+
+ // initialize font settings:
+ wcscpy(m_fontinfo[SIMPLE_FONT ].szFace, SIMPLE_FONT_DEFAULT_FACE);
+ m_fontinfo[SIMPLE_FONT ].nSize = SIMPLE_FONT_DEFAULT_SIZE ;
+ m_fontinfo[SIMPLE_FONT ].bBold = SIMPLE_FONT_DEFAULT_BOLD ;
+ m_fontinfo[SIMPLE_FONT ].bItalic = SIMPLE_FONT_DEFAULT_ITAL ;
+ m_fontinfo[SIMPLE_FONT ].bAntiAliased = SIMPLE_FONT_DEFAULT_AA ;
+ wcscpy(m_fontinfo[DECORATIVE_FONT].szFace, DECORATIVE_FONT_DEFAULT_FACE);
+ m_fontinfo[DECORATIVE_FONT].nSize = DECORATIVE_FONT_DEFAULT_SIZE;
+ m_fontinfo[DECORATIVE_FONT].bBold = DECORATIVE_FONT_DEFAULT_BOLD;
+ m_fontinfo[DECORATIVE_FONT].bItalic = DECORATIVE_FONT_DEFAULT_ITAL;
+ m_fontinfo[DECORATIVE_FONT].bAntiAliased = DECORATIVE_FONT_DEFAULT_AA ;
+ wcscpy(m_fontinfo[HELPSCREEN_FONT].szFace, HELPSCREEN_FONT_DEFAULT_FACE);
+ m_fontinfo[HELPSCREEN_FONT].nSize = HELPSCREEN_FONT_DEFAULT_SIZE;
+ m_fontinfo[HELPSCREEN_FONT].bBold = HELPSCREEN_FONT_DEFAULT_BOLD;
+ m_fontinfo[HELPSCREEN_FONT].bItalic = HELPSCREEN_FONT_DEFAULT_ITAL;
+ m_fontinfo[HELPSCREEN_FONT].bAntiAliased = HELPSCREEN_FONT_DEFAULT_AA ;
+ wcscpy(m_fontinfo[PLAYLIST_FONT ].szFace, PLAYLIST_FONT_DEFAULT_FACE);
+ m_fontinfo[PLAYLIST_FONT ].nSize = PLAYLIST_FONT_DEFAULT_SIZE;
+ m_fontinfo[PLAYLIST_FONT ].bBold = PLAYLIST_FONT_DEFAULT_BOLD;
+ m_fontinfo[PLAYLIST_FONT ].bItalic = PLAYLIST_FONT_DEFAULT_ITAL;
+ m_fontinfo[PLAYLIST_FONT ].bAntiAliased = PLAYLIST_FONT_DEFAULT_AA ;
+
+#if (NUM_EXTRA_FONTS >= 1)
+ wcscpy(m_fontinfo[NUM_BASIC_FONTS + 0].szFace, EXTRA_FONT_1_DEFAULT_FACE);
+ m_fontinfo[NUM_BASIC_FONTS + 0].nSize = EXTRA_FONT_1_DEFAULT_SIZE;
+ m_fontinfo[NUM_BASIC_FONTS + 0].bBold = EXTRA_FONT_1_DEFAULT_BOLD;
+ m_fontinfo[NUM_BASIC_FONTS + 0].bItalic = EXTRA_FONT_1_DEFAULT_ITAL;
+ m_fontinfo[NUM_BASIC_FONTS + 0].bAntiAliased = EXTRA_FONT_1_DEFAULT_AA;
+#endif
+#if (NUM_EXTRA_FONTS >= 2)
+ wcscpy(m_fontinfo[NUM_BASIC_FONTS + 1].szFace, EXTRA_FONT_2_DEFAULT_FACE);
+ m_fontinfo[NUM_BASIC_FONTS + 1].nSize = EXTRA_FONT_2_DEFAULT_SIZE;
+ m_fontinfo[NUM_BASIC_FONTS + 1].bBold = EXTRA_FONT_2_DEFAULT_BOLD;
+ m_fontinfo[NUM_BASIC_FONTS + 1].bItalic = EXTRA_FONT_2_DEFAULT_ITAL;
+ m_fontinfo[NUM_BASIC_FONTS + 1].bAntiAliased = EXTRA_FONT_2_DEFAULT_AA;
+#endif
+#if (NUM_EXTRA_FONTS >= 3)
+ strcpy(m_fontinfo[NUM_BASIC_FONTS + 2].szFace, EXTRA_FONT_3_DEFAULT_FACE);
+ m_fontinfo[NUM_BASIC_FONTS + 2].nSize = EXTRA_FONT_3_DEFAULT_SIZE;
+ m_fontinfo[NUM_BASIC_FONTS + 2].bBold = EXTRA_FONT_3_DEFAULT_BOLD;
+ m_fontinfo[NUM_BASIC_FONTS + 2].bItalic = EXTRA_FONT_3_DEFAULT_ITAL;
+ m_fontinfo[NUM_BASIC_FONTS + 2].bAntiAliased = EXTRA_FONT_3_DEFAULT_AA;
+#endif
+#if (NUM_EXTRA_FONTS >= 4)
+ strcpy(m_fontinfo[NUM_BASIC_FONTS + 3].szFace, EXTRA_FONT_4_DEFAULT_FACE);
+ m_fontinfo[NUM_BASIC_FONTS + 3].nSize = EXTRA_FONT_4_DEFAULT_SIZE;
+ m_fontinfo[NUM_BASIC_FONTS + 3].bBold = EXTRA_FONT_4_DEFAULT_BOLD;
+ m_fontinfo[NUM_BASIC_FONTS + 3].bItalic = EXTRA_FONT_4_DEFAULT_ITAL;
+ m_fontinfo[NUM_BASIC_FONTS + 3].bAntiAliased = EXTRA_FONT_4_DEFAULT_AA;
+#endif
+#if (NUM_EXTRA_FONTS >= 5)
+ strcpy(m_fontinfo[NUM_BASIC_FONTS + 4].szFace, EXTRA_FONT_5_DEFAULT_FACE);
+ m_fontinfo[NUM_BASIC_FONTS + 4].nSize = EXTRA_FONT_5_DEFAULT_SIZE;
+ m_fontinfo[NUM_BASIC_FONTS + 4].bBold = EXTRA_FONT_5_DEFAULT_BOLD;
+ m_fontinfo[NUM_BASIC_FONTS + 4].bItalic = EXTRA_FONT_5_DEFAULT_ITAL;
+ m_fontinfo[NUM_BASIC_FONTS + 4].bAntiAliased = EXTRA_FONT_5_DEFAULT_AA;
+#endif
+
+ m_disp_mode_fs.Width = DEFAULT_FULLSCREEN_WIDTH;
+ m_disp_mode_fs.Height = DEFAULT_FULLSCREEN_HEIGHT;
+ m_disp_mode_fs.Format = D3DFMT_UNKNOWN;
+ m_disp_mode_fs.RefreshRate = 60;
+ // better yet - in case there is no config INI file saved yet, use the current display mode (if detectable) as the default fullscreen res:
+ DEVMODE dm;
+ dm.dmSize = sizeof(dm);
+ dm.dmDriverExtra = 0;
+ if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
+ {
+ m_disp_mode_fs.Width = dm.dmPelsWidth;
+ m_disp_mode_fs.Height = dm.dmPelsHeight;
+ m_disp_mode_fs.RefreshRate = dm.dmDisplayFrequency;
+ m_disp_mode_fs.Format = (dm.dmBitsPerPel==16) ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
+ }
+
+ // PROTECTED STRUCTURES/POINTERS
+ int i = 0;
+ for (int i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ m_d3dx_font[i] = NULL;
+ m_d3dx_desktop_font = NULL;
+ m_lpDDSText = NULL;
+ ZeroMemory(&m_sound, sizeof(td_soundinfo));
+ for (int ch=0; ch<2; ch++)
+ for (i=0; i<3; i++)
+ {
+ m_sound.infinite_avg[ch][i] = m_sound.avg[ch][i] = m_sound.med_avg[ch][i] = m_sound.long_avg[ch][i] = 1.0f;
+ }
+
+ // GENERAL PRIVATE STUFF
+ //m_screenmode: set at end (derived setting)
+ m_frame = 0;
+ m_time = 0;
+ m_fps = 30;
+ m_hWndWinamp = hWinampWnd;
+ m_hInstance = hWinampInstance;
+ m_lpDX = NULL;
+ m_szPluginsDirPath[0] = 0; // will be set further down
+ m_szConfigIniFile[0] = 0; // will be set further down
+ // m_szPluginsDirPath:
+
+ wchar_t *p;
+
+ if (hWinampWnd
+ && (p = (wchar_t *)SendMessage(hWinampWnd, WM_WA_IPC, 0, IPC_GETPLUGINDIRECTORYW))
+ && p != (wchar_t *)1)
+ {
+ swprintf(m_szPluginsDirPath, L"%s\\", p);
+ }
+ else
+ {
+ // get path to INI file & read in prefs/settings right away, so DumpMsg works!
+ GetModuleFileNameW(m_hInstance, m_szPluginsDirPath, MAX_PATH);
+ wchar_t *p = m_szPluginsDirPath + wcslen(m_szPluginsDirPath);
+ while (p >= m_szPluginsDirPath && *p != L'\\') p--;
+ if (++p >= m_szPluginsDirPath) *p = 0;
+ }
+
+ if (hWinampWnd
+ && (p = (wchar_t *)SendMessage(hWinampWnd, WM_WA_IPC, 0, IPC_GETINIDIRECTORYW))
+ && p != (wchar_t *)1)
+ {
+ // load settings as well as coping with moving old settings to a contained folder
+ wchar_t m_szOldConfigIniFile[MAX_PATH] = {0}, temp[MAX_PATH] = {0}, temp2[MAX_PATH] = {0};
+ swprintf(m_szOldConfigIniFile, L"%s\\Plugins\\%s", p, INIFILE);
+ swprintf(m_szConfigIniFile, L"%s\\Plugins\\%s%s", p, SUBDIR, INIFILE);
+ swprintf(temp, L"%s\\Plugins\\%s", p, SUBDIR);
+ swprintf(temp2, L"%s\\Plugins\\", p);
+ CreateDirectoryW(temp, NULL);
+
+ if (PathFileExistsW(m_szOldConfigIniFile) && !PathFileExistsW(m_szConfigIniFile))
+ {
+ MoveFileW(m_szOldConfigIniFile, m_szConfigIniFile);
+
+ wchar_t m_szMsgIniFile[MAX_PATH] = {0}, m_szNewMsgIniFile[MAX_PATH] = {0},
+ m_szImgIniFile[MAX_PATH] = {0}, m_szNewImgIniFile[MAX_PATH] = {0},
+ m_szAdaptersFile[MAX_PATH] = {0}, m_szNewAdaptersFile[MAX_PATH] = {0};
+ swprintf(m_szMsgIniFile, L"%s%s", temp2, MSG_INIFILE);
+ swprintf(m_szNewMsgIniFile, L"%s%s", temp, MSG_INIFILE);
+ swprintf(m_szImgIniFile, L"%s%s", temp2, IMG_INIFILE);
+ swprintf(m_szNewImgIniFile, L"%s%s", temp, IMG_INIFILE);
+ swprintf(m_szAdaptersFile, L"%s%s", temp2, ADAPTERSFILE);
+ swprintf(m_szNewAdaptersFile, L"%s%s", temp, ADAPTERSFILE);
+
+ MoveFileW(m_szImgIniFile, m_szNewImgIniFile);
+ MoveFileW(m_szMsgIniFile, m_szNewMsgIniFile);
+ MoveFileW(m_szAdaptersFile, m_szNewAdaptersFile);
+ }
+ }
+ else
+ {
+ swprintf(m_szConfigIniFile, L"%s%s", m_szPluginsDirPath, INIFILE);
+ }
+ lstrcpyn(m_szConfigIniFileA,AutoCharFn(m_szConfigIniFile),MAX_PATH);
+
+ // PRIVATE CONFIG PANEL SETTINGS
+ m_multisample_fullscreen = D3DMULTISAMPLE_NONE;
+ m_multisample_desktop = D3DMULTISAMPLE_NONE;
+ m_multisample_windowed = D3DMULTISAMPLE_NONE;
+ ZeroMemory(&m_adapter_guid_fullscreen, sizeof(GUID));
+ ZeroMemory(&m_adapter_guid_desktop , sizeof(GUID));
+ ZeroMemory(&m_adapter_guid_windowed , sizeof(GUID));
+ m_adapter_devicename_windowed[0] = 0;
+ m_adapter_devicename_fullscreen[0] = 0;
+ m_adapter_devicename_desktop[0] = 0;
+
+
+ // PRIVATE RUNTIME SETTINGS
+ m_lost_focus = 0;
+ m_hidden = 0;
+ m_resizing = 0;
+ m_show_help = 0;
+ m_show_playlist = 0;
+ m_playlist_pos = 0;
+ m_playlist_pageups = 0;
+ m_playlist_top_idx = -1;
+ m_playlist_btm_idx = -1;
+ // m_playlist_width_pixels will be considered invalid whenever 'm_playlist_top_idx' is -1.
+ // m_playlist[256][256] will be considered invalid whenever 'm_playlist_top_idx' is -1.
+ m_exiting = 0;
+ m_upper_left_corner_y = 0;
+ m_lower_left_corner_y = 0;
+ m_upper_right_corner_y = 0;
+ m_lower_right_corner_y = 0;
+ m_left_edge = 0;
+ m_right_edge = 0;
+ m_force_accept_WM_WINDOWPOSCHANGING = 0;
+
+ // PRIVATE - GDI STUFF
+ m_main_menu = NULL;
+ m_context_menu = NULL;
+ for (i=0; i<NUM_BASIC_FONTS + NUM_EXTRA_FONTS; i++)
+ m_font[i] = NULL;
+ m_font_desktop = NULL;
+
+ // PRIVATE - DESKTOP MODE STUFF
+ m_icon_list.clear();
+ for (i=0; i<MAX_ICON_TEXTURES; i++)
+ m_desktop_icons_texture[i] = NULL;
+ FindDesktopWindows(&m_hWndProgMan, &m_hWndDesktop, &m_hWndDesktopListView);
+ GetDesktopFolder(m_szDesktopFolder);
+ m_desktop_icon_size = 32;
+ m_desktop_dragging = 0; // '1' when user is dragging icons around
+ m_desktop_box = 0; // '1' when user is drawing a box
+ m_desktop_wc_registered = 0;
+ m_desktop_bk_color = 0xFF000000 | BGR2RGB(::GetSysColor(COLOR_BACKGROUND));
+ m_desktop_text_color = 0xFF000000 | BGR2RGB(SendMessage(m_hWndDesktopListView, LVM_GETTEXTCOLOR, 0, 0));
+ m_desktop_sel_color = 0xFF000000 | BGR2RGB(::GetSysColor(COLOR_HIGHLIGHT));
+ m_desktop_sel_text_color = 0xFF000000 | BGR2RGB(::GetSysColor(COLOR_HIGHLIGHTTEXT));
+ m_desktop_icon_state = 0;
+ m_desktop_icon_count = 0;
+ m_desktop_icon_update_frame = 0;
+ m_desktop_icons_disabled = 0;
+ m_vms_desktop_loaded = 0;
+ m_desktop_hook_set = 0;
+
+ // PRIVATE - MORE TIMEKEEPING
+ m_last_raw_time = 0;
+ memset(m_time_hist, 0, sizeof(m_time_hist));
+ m_time_hist_pos = 0;
+ if (!QueryPerformanceFrequency(&m_high_perf_timer_freq))
+ m_high_perf_timer_freq.QuadPart = 0;
+ m_prev_end_of_frame.QuadPart = 0;
+
+ // PRIVATE AUDIO PROCESSING DATA
+ //(m_fftobj needs no init)
+ memset(m_oldwave[0], 0, sizeof(float)*576);
+ memset(m_oldwave[1], 0, sizeof(float)*576);
+ m_prev_align_offset[0] = 0;
+ m_prev_align_offset[1] = 0;
+ m_align_weights_ready = 0;
+
+ // SEPARATE TEXT WINDOW (FOR VJ MODE)
+ m_vj_mode = 0;
+ m_hidden_textwnd = 0;
+ m_resizing_textwnd = 0;
+ m_hTextWnd = NULL;
+ m_nTextWndWidth = 0;
+ m_nTextWndHeight = 0;
+ m_bTextWindowClassRegistered = false;
+ m_vjd3d9 = NULL;
+ m_vjd3d9_device = NULL;
+
+ //-----
+
+ m_screenmode = NOT_YET_KNOWN;
+
+ OverrideDefaults();
+ ReadConfig();
+
+ if (m_start_fullscreen)
+ {
+ m_screenmode = m_fake_fullscreen_mode ? FAKE_FULLSCREEN : FULLSCREEN;
+ if (m_screenmode == FULLSCREEN && SendMessage(GetWinampWindow(), WM_WA_IPC, 0, IPC_IS_PLAYING_VIDEO) > 1)
+ {
+ m_screenmode = FAKE_FULLSCREEN;
+ }
+ }
+ else if (m_start_desktop)
+ m_screenmode = DESKTOP;
+ else
+ m_screenmode = WINDOWED;
+
+ MyPreInitialize();
+ MyReadConfig();
+
+ //-----
+
+ return TRUE;
+}
+
+int CPluginShell::PluginInitialize()
+{
+ // note: initialize GDI before DirectX. Also separate them because
+ // when we change windowed<->fullscreen, or lose the device and restore it,
+ // we don't want to mess with any (persistent) GDI stuff.
+
+ if (!InitDirectX()) return FALSE; // gives its own error messages
+ if (!InitNondx9Stuff()) return FALSE; // gives its own error messages
+ if (!AllocateDX9Stuff()) return FALSE; // gives its own error messages
+ if (!InitVJStuff()) return FALSE;
+
+ return TRUE;
+}
+
+void CPluginShell::PluginQuit()
+{
+ CleanUpVJStuff();
+ CleanUpDX9Stuff(1);
+ CleanUpNondx9Stuff();
+ CleanUpDirectX();
+
+ SetFocus(m_hWndWinamp);
+ SetActiveWindow(m_hWndWinamp);
+ SetForegroundWindow(m_hWndWinamp);
+}
+
+wchar_t* BuildSettingName(wchar_t* name, int number){
+static wchar_t temp[64];
+ swprintf(temp, L"%s%d", name, number);
+ return temp;
+}
+
+void CPluginShell::READ_FONT(int n){
+ GetPrivateProfileStringW(L"settings",BuildSettingName(L"szFontFace",n),m_fontinfo[n].szFace,m_fontinfo[n].szFace,sizeof(m_fontinfo[n].szFace), m_szConfigIniFile);
+ m_fontinfo[n].nSize = GetPrivateProfileIntW(L"settings",BuildSettingName(L"nFontSize",n),m_fontinfo[n].nSize ,m_szConfigIniFile);
+ m_fontinfo[n].bBold = GetPrivateProfileIntW(L"settings",BuildSettingName(L"bFontBold",n),m_fontinfo[n].bBold ,m_szConfigIniFile);
+ m_fontinfo[n].bItalic = GetPrivateProfileIntW(L"settings",BuildSettingName(L"bFontItalic",n),m_fontinfo[n].bItalic,m_szConfigIniFile);
+ m_fontinfo[n].bAntiAliased = GetPrivateProfileIntW(L"settings",BuildSettingName(L"bFontAA",n),m_fontinfo[n].bItalic,m_szConfigIniFile);
+}
+
+void CPluginShell::ReadConfig()
+{
+ int old_ver = GetPrivateProfileIntW(L"settings",L"version" ,-1,m_szConfigIniFile);
+ int old_subver = GetPrivateProfileIntW(L"settings",L"subversion",-1,m_szConfigIniFile);
+
+ // nuke old settings from prev. version:
+ if (old_ver < INT_VERSION)
+ return;
+ else if (old_subver < INT_SUBVERSION)
+ return;
+
+ //D3DMULTISAMPLE_TYPE m_multisample_fullscreen;
+ //D3DMULTISAMPLE_TYPE m_multisample_desktop;
+ //D3DMULTISAMPLE_TYPE m_multisample_windowed;
+ m_multisample_fullscreen = (D3DMULTISAMPLE_TYPE)GetPrivateProfileIntW(L"settings",L"multisample_fullscreen",m_multisample_fullscreen,m_szConfigIniFile);
+ m_multisample_desktop = (D3DMULTISAMPLE_TYPE)GetPrivateProfileIntW(L"settings",L"multisample_desktop",m_multisample_desktop,m_szConfigIniFile);
+ m_multisample_windowed = (D3DMULTISAMPLE_TYPE)GetPrivateProfileIntW(L"settings",L"multisample_windowed" ,m_multisample_windowed ,m_szConfigIniFile);
+
+ //GUID m_adapter_guid_fullscreen
+ //GUID m_adapter_guid_desktop
+ //GUID m_adapter_guid_windowed
+ char str[256];
+ GetPrivateProfileString("settings","adapter_guid_fullscreen","",str,sizeof(str)-1,m_szConfigIniFileA);
+ TextToGuid(str, &m_adapter_guid_fullscreen);
+ GetPrivateProfileString("settings","adapter_guid_desktop","",str,sizeof(str)-1,m_szConfigIniFileA);
+ TextToGuid(str, &m_adapter_guid_desktop);
+ GetPrivateProfileString("settings","adapter_guid_windowed","",str,sizeof(str)-1,m_szConfigIniFileA);
+ TextToGuid(str, &m_adapter_guid_windowed);
+ GetPrivateProfileString("settings","adapter_devicename_fullscreen","",m_adapter_devicename_fullscreen,sizeof(m_adapter_devicename_fullscreen)-1,m_szConfigIniFileA);
+ GetPrivateProfileString("settings","adapter_devicename_desktop", "",m_adapter_devicename_desktop ,sizeof(m_adapter_devicename_desktop)-1,m_szConfigIniFileA);
+ GetPrivateProfileString("settings","adapter_devicename_windowed", "",m_adapter_devicename_windowed ,sizeof(m_adapter_devicename_windowed)-1,m_szConfigIniFileA);
+
+ // FONTS
+ READ_FONT(0);
+ READ_FONT(1);
+ READ_FONT(2);
+ READ_FONT(3);
+#if (NUM_EXTRA_FONTS >= 1)
+ READ_FONT(4);
+#endif
+#if (NUM_EXTRA_FONTS >= 2)
+ READ_FONT(5);
+#endif
+#if (NUM_EXTRA_FONTS >= 3)
+ READ_FONT(6);
+#endif
+#if (NUM_EXTRA_FONTS >= 4)
+ READ_FONT(7);
+#endif
+#if (NUM_EXTRA_FONTS >= 5)
+ READ_FONT(8);
+#endif
+
+ m_start_fullscreen = GetPrivateProfileIntW(L"settings",L"start_fullscreen",m_start_fullscreen,m_szConfigIniFile);
+ m_start_desktop = GetPrivateProfileIntW(L"settings",L"start_desktop" ,m_start_desktop ,m_szConfigIniFile);
+ m_fake_fullscreen_mode = GetPrivateProfileIntW(L"settings",L"fake_fullscreen_mode",m_fake_fullscreen_mode,m_szConfigIniFile);
+ m_max_fps_fs = GetPrivateProfileIntW(L"settings",L"max_fps_fs",m_max_fps_fs,m_szConfigIniFile);
+ m_max_fps_dm = GetPrivateProfileIntW(L"settings",L"max_fps_dm",m_max_fps_dm,m_szConfigIniFile);
+ m_max_fps_w = GetPrivateProfileIntW(L"settings",L"max_fps_w" ,m_max_fps_w ,m_szConfigIniFile);
+ m_show_press_f1_msg = GetPrivateProfileIntW(L"settings",L"show_press_f1_msg",m_show_press_f1_msg,m_szConfigIniFile);
+ m_allow_page_tearing_w = GetPrivateProfileIntW(L"settings",L"allow_page_tearing_w",m_allow_page_tearing_w,m_szConfigIniFile);
+ m_allow_page_tearing_fs= GetPrivateProfileIntW(L"settings",L"allow_page_tearing_fs",m_allow_page_tearing_fs,m_szConfigIniFile);
+ m_allow_page_tearing_dm= GetPrivateProfileIntW(L"settings",L"allow_page_tearing_dm",m_allow_page_tearing_dm,m_szConfigIniFile);
+ m_minimize_winamp = GetPrivateProfileIntW(L"settings",L"minimize_winamp",m_minimize_winamp,m_szConfigIniFile);
+ m_desktop_show_icons = GetPrivateProfileIntW(L"settings",L"desktop_show_icons",m_desktop_show_icons,m_szConfigIniFile);
+ m_desktop_textlabel_boxes = GetPrivateProfileIntW(L"settings",L"desktop_textlabel_boxes",m_desktop_textlabel_boxes,m_szConfigIniFile);
+ m_desktop_manual_icon_scoot = GetPrivateProfileIntW(L"settings",L"desktop_manual_icon_scoot",m_desktop_manual_icon_scoot,m_szConfigIniFile);
+ m_desktop_555_fix = GetPrivateProfileIntW(L"settings",L"desktop_555_fix",m_desktop_555_fix,m_szConfigIniFile);
+ m_dualhead_horz = GetPrivateProfileIntW(L"settings",L"dualhead_horz",m_dualhead_horz,m_szConfigIniFile);
+ m_dualhead_vert = GetPrivateProfileIntW(L"settings",L"dualhead_vert",m_dualhead_vert,m_szConfigIniFile);
+ m_save_cpu = GetPrivateProfileIntW(L"settings",L"save_cpu",m_save_cpu,m_szConfigIniFile);
+ m_skin = GetPrivateProfileIntW(L"settings",L"skin",m_skin,m_szConfigIniFile);
+ m_fix_slow_text = GetPrivateProfileIntW(L"settings",L"fix_slow_text",m_fix_slow_text,m_szConfigIniFile);
+ m_vj_mode = GetPrivateProfileBoolW(L"settings",L"vj_mode",m_vj_mode,m_szConfigIniFile);
+
+ //D3DDISPLAYMODE m_fs_disp_mode
+ m_disp_mode_fs.Width = GetPrivateProfileIntW(L"settings",L"disp_mode_fs_w", m_disp_mode_fs.Width ,m_szConfigIniFile);
+ m_disp_mode_fs.Height = GetPrivateProfileIntW(L"settings",L"disp_mode_fs_h",m_disp_mode_fs.Height ,m_szConfigIniFile);
+ m_disp_mode_fs.RefreshRate = GetPrivateProfileIntW(L"settings",L"disp_mode_fs_r",m_disp_mode_fs.RefreshRate,m_szConfigIniFile);
+ m_disp_mode_fs.Format = (D3DFORMAT)GetPrivateProfileIntW(L"settings",L"disp_mode_fs_f",m_disp_mode_fs.Format ,m_szConfigIniFile);
+
+ // note: we don't call MyReadConfig() yet, because we
+ // want to completely finish CPluginShell's preinit (and ReadConfig)
+ // before calling CPlugin's preinit and ReadConfig.
+}
+
+void CPluginShell::WRITE_FONT(int n){
+ WritePrivateProfileStringW(L"settings",BuildSettingName(L"szFontFace",n),m_fontinfo[n].szFace,m_szConfigIniFile);
+ WritePrivateProfileIntW(m_fontinfo[n].bBold, BuildSettingName(L"bFontBold",n), m_szConfigIniFile, L"settings");
+ WritePrivateProfileIntW(m_fontinfo[n].bItalic,BuildSettingName(L"bFontItalic",n), m_szConfigIniFile, L"settings");
+ WritePrivateProfileIntW(m_fontinfo[n].nSize, BuildSettingName(L"nFontSize",n), m_szConfigIniFile, L"settings");
+ WritePrivateProfileIntW(m_fontinfo[n].bAntiAliased, BuildSettingName(L"bFontAA",n),m_szConfigIniFile, L"settings");
+}
+
+void CPluginShell::WriteConfig()
+{
+ //D3DMULTISAMPLE_TYPE m_multisample_fullscreen;
+ //D3DMULTISAMPLE_TYPE m_multisample_desktop;
+ //D3DMULTISAMPLE_TYPE m_multisample_windowed;
+ WritePrivateProfileIntW((int)m_multisample_fullscreen,L"multisample_fullscreen",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW((int)m_multisample_desktop ,L"multisample_desktop" ,m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW((int)m_multisample_windowed ,L"multisample_windowed" ,m_szConfigIniFile,L"settings");
+
+ //GUID m_adapter_guid_fullscreen
+ //GUID m_adapter_guid_desktop
+ //GUID m_adapter_guid_windowed
+ char str[256];
+ GuidToText(&m_adapter_guid_fullscreen, str, sizeof(str));
+ WritePrivateProfileString("settings","adapter_guid_fullscreen",str,m_szConfigIniFileA);
+ GuidToText(&m_adapter_guid_desktop, str, sizeof(str));
+ WritePrivateProfileString("settings","adapter_guid_desktop",str,m_szConfigIniFileA);
+ GuidToText(&m_adapter_guid_windowed, str, sizeof(str));
+ WritePrivateProfileString("settings","adapter_guid_windowed" ,str,m_szConfigIniFileA);
+ WritePrivateProfileString("settings","adapter_devicename_fullscreen",m_adapter_devicename_fullscreen,m_szConfigIniFileA);
+ WritePrivateProfileString("settings","adapter_devicename_desktop" ,m_adapter_devicename_desktop ,m_szConfigIniFileA);
+ WritePrivateProfileString("settings","adapter_devicename_windowed" ,m_adapter_devicename_windowed ,m_szConfigIniFileA);
+
+ // FONTS
+ WRITE_FONT(0);
+ WRITE_FONT(1);
+ WRITE_FONT(2);
+ WRITE_FONT(3);
+#if (NUM_EXTRA_FONTS >= 1)
+ WRITE_FONT(4);
+#endif
+#if (NUM_EXTRA_FONTS >= 2)
+ WRITE_FONT(5);
+#endif
+#if (NUM_EXTRA_FONTS >= 3)
+ WRITE_FONT(6);
+#endif
+#if (NUM_EXTRA_FONTS >= 4)
+ WRITE_FONT(7);
+#endif
+#if (NUM_EXTRA_FONTS >= 5)
+ WRITE_FONT(8);
+#endif
+
+ WritePrivateProfileIntW(m_start_fullscreen,L"start_fullscreen",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_start_desktop ,L"start_desktop" ,m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_fake_fullscreen_mode,L"fake_fullscreen_mode",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_max_fps_fs,L"max_fps_fs",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_max_fps_dm,L"max_fps_dm",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_max_fps_w ,L"max_fps_w" ,m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_show_press_f1_msg,L"show_press_f1_msg",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_allow_page_tearing_w,L"allow_page_tearing_w",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_allow_page_tearing_fs,L"allow_page_tearing_fs",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_allow_page_tearing_dm,L"allow_page_tearing_dm",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_minimize_winamp,L"minimize_winamp",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_desktop_show_icons,L"desktop_show_icons",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_desktop_textlabel_boxes,L"desktop_textlabel_boxes",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_desktop_manual_icon_scoot,L"desktop_manual_icon_scoot",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_desktop_555_fix,L"desktop_555_fix",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_dualhead_horz,L"dualhead_horz",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_dualhead_vert,L"dualhead_vert",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_save_cpu,L"save_cpu",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_skin,L"skin",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_fix_slow_text,L"fix_slow_text",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_vj_mode,L"vj_mode",m_szConfigIniFile,L"settings");
+
+ //D3DDISPLAYMODE m_fs_disp_mode
+ WritePrivateProfileIntW(m_disp_mode_fs.Width ,L"disp_mode_fs_w",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_disp_mode_fs.Height ,L"disp_mode_fs_h",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_disp_mode_fs.RefreshRate,L"disp_mode_fs_r",m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(m_disp_mode_fs.Format ,L"disp_mode_fs_f",m_szConfigIniFile,L"settings");
+
+ WritePrivateProfileIntW(INT_VERSION ,L"version" ,m_szConfigIniFile,L"settings");
+ WritePrivateProfileIntW(INT_SUBVERSION ,L"subversion" ,m_szConfigIniFile,L"settings");
+
+ // finally, save the plugin's unique settings:
+ MyWriteConfig();
+}
+
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+//----------------------------------------------------------------------
+
+int CPluginShell::PluginRender(unsigned char *pWaveL, unsigned char *pWaveR)//, unsigned char *pSpecL, unsigned char *pSpecR)
+{
+ // return FALSE here to tell Winamp to terminate the plugin
+
+ if (!m_lpDX || !m_lpDX->m_ready)
+ {
+ // note: 'm_ready' will go false when a device reset fatally fails
+ // (for example, when user resizes window, or toggles fullscreen.)
+ m_exiting = 1;
+ return false; // EXIT THE PLUGIN
+ }
+
+ if (m_hTextWnd)
+ m_lost_focus = ((GetFocus() != GetPluginWindow()) && (GetFocus() != m_hTextWnd));
+ else
+ m_lost_focus = (GetFocus() != GetPluginWindow());
+
+ if ((m_screenmode==WINDOWED && m_hidden) ||
+ (m_screenmode==FULLSCREEN && m_lost_focus) ||
+ (m_screenmode==WINDOWED && m_resizing)
+ )
+ {
+ Sleep(30);
+ return true;
+ }
+
+ // test for lost device
+ // (this happens when device is fullscreen & user alt-tabs away,
+ // or when monitor power-saving kicks in)
+ HRESULT hr = m_lpDX->m_lpDevice->TestCooperativeLevel();
+ if (hr == D3DERR_DEVICENOTRESET)
+ {
+ // device WAS lost, and is now ready to be reset (and come back online):
+ CleanUpDX9Stuff(0);
+ if (m_lpDX->m_lpDevice->Reset(&m_lpDX->m_d3dpp) != D3D_OK)
+ {
+ // note: a basic warning messagebox will have already been given.
+ // now suggest specific advice on how to regain more video memory:
+ if (m_lpDX->m_lastErr == DXC_ERR_CREATEDEV_PROBABLY_OUTOFVIDEOMEMORY)
+ SuggestHowToFreeSomeMem();
+ return false; // EXIT THE PLUGIN
+ }
+ if (!AllocateDX9Stuff())
+ return false; // EXIT THE PLUGIN
+ }
+ else if (hr != D3D_OK)
+ {
+ // device is lost, and not yet ready to come back; sleep.
+ Sleep(30);
+ return true;
+ }
+
+ if (m_vjd3d9_device)
+ {
+ HRESULT hr = m_vjd3d9_device->TestCooperativeLevel();
+ if (hr == D3DERR_DEVICENOTRESET)
+ {
+ RECT c;
+ GetClientRect(m_hTextWnd, &c);
+
+ POINT p;
+ p.x = c.left;
+ p.y = c.top;
+ if (ClientToScreen(m_hTextWnd, &p))
+ {
+ c.left += p.x;
+ c.right += p.x;
+ c.top += p.y;
+ c.bottom += p.y;
+ }
+
+ CleanUpVJStuff();
+ if (!InitVJStuff(&c))
+ return false; // EXIT THE PLUGIN
+ }
+ }
+
+ if (m_screenmode==DESKTOP)
+ {
+ PushWindowToJustBeforeDesktop(GetPluginWindow());
+ }
+
+ DoTime();
+ AnalyzeNewSound(pWaveL, pWaveR);
+ AlignWaves();
+
+ DrawAndDisplay(0);
+
+ EnforceMaxFPS();
+
+ m_frame++;
+
+ return true;
+}
+
+void CPluginShell::PushWindowToJustBeforeDesktop(HWND h)
+{
+ // if our window isn't already at the bottom of the Z order,
+ // freshly send it to HWND_BOTTOM.
+
+ // this usually gives us the Program Manager window:
+ HWND hWndBottom = GetWindow(h, GW_HWNDLAST);
+
+ // then, bottommost 'normal' window is usually the one just in front of it:
+ if (hWndBottom == m_hWndProgMan)
+ hWndBottom = GetWindow(hWndBottom, GW_HWNDPREV);
+
+ if (hWndBottom != h)
+ {
+ m_force_accept_WM_WINDOWPOSCHANGING = 1;
+ SetWindowPos(h, HWND_BOTTOM, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);
+ m_force_accept_WM_WINDOWPOSCHANGING = 0;
+ }
+
+ /*
+ HWND hDesktopBkgWnd = FindWindow("SHELLDLL_DefView", "");
+ if (hDesktopBkgWnd)
+ {
+ HWND hWndInFrontOfIcons = GetWindow(h, GW_HWNDPREV);
+ if (hWndInFrontOfIcons != h)
+ {
+ m_force_accept_WM_WINDOWPOSCHANGING = 1;
+ SetWindowPos(hDesktopBkgWnd, h, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE);
+ m_force_accept_WM_WINDOWPOSCHANGING = 0;
+ }
+ }
+ */
+
+
+}
+
+void CPluginShell::DrawAndDisplay(int redraw)
+{
+ int cx = m_vjd3d9_device ? m_nTextWndWidth : m_lpDX->m_client_width;
+ int cy = m_vjd3d9_device ? m_nTextWndHeight : m_lpDX->m_client_height;
+ if (m_lpDDSText)
+ {
+ D3DSURFACE_DESC desc;
+ if (D3D_OK == m_lpDDSText->GetLevelDesc(0, &desc))
+ {
+ cx = min(cx, (int)desc.Width);
+ cy = min(cy, (int)desc.Height);
+ }
+ }
+ m_upper_left_corner_y = TEXT_MARGIN + GetCanvasMarginY();
+ m_upper_right_corner_y = TEXT_MARGIN + GetCanvasMarginY();
+ m_lower_left_corner_y = cy - TEXT_MARGIN - GetCanvasMarginY();
+ m_lower_right_corner_y = cy - TEXT_MARGIN - GetCanvasMarginY();
+ m_left_edge = TEXT_MARGIN + GetCanvasMarginX();
+ m_right_edge = cx - TEXT_MARGIN - GetCanvasMarginX();
+
+ /*if (m_screenmode == DESKTOP || m_screenmode == FAKE_FULLSCREEN)
+ {
+ // check if taskbar is above plugin window;
+ // if so, scoot text & icons out of the way.
+ // [...should always be true for Desktop Mode,
+ // but it's like this for code simplicity.]
+ int taskbar_is_above_plugin_window = 1;
+ HWND h = FindWindow("Shell_TrayWnd", NULL);
+ while (h) //(..shouldn't be very many windows to iterate through here)
+ {
+ h = GetWindow(h, GW_HWNDPREV);
+ if (h == GetPluginWindow())
+ {
+ taskbar_is_above_plugin_window = 0;
+ break;
+ }
+ }
+
+ if (taskbar_is_above_plugin_window)
+ {
+ // respect the taskbar area; make sure the text, desktop icons, etc.
+ // don't appear underneath it.
+ //m_upper_left_corner_y += m_lpDX->m_monitor_work_rect.top - m_lpDX->m_monitor_rect.top;
+ //m_upper_right_corner_y += m_lpDX->m_monitor_work_rect.top - m_lpDX->m_monitor_rect.top;
+ //m_lower_left_corner_y -= m_lpDX->m_monitor_rect.bottom - m_lpDX->m_monitor_work_rect.bottom;
+ //m_lower_right_corner_y -= m_lpDX->m_monitor_rect.bottom - m_lpDX->m_monitor_work_rect.bottom;
+ //m_left_edge += m_lpDX->m_monitor_work_rect.left - m_lpDX->m_monitor_rect.left;
+ //m_right_edge -= m_lpDX->m_monitor_rect.right - m_lpDX->m_monitor_work_rect.right;
+ m_lpDX->UpdateMonitorWorkRect();
+ m_upper_left_corner_y = max(m_upper_left_corner_y , m_lpDX->m_monitor_work_rect.top - m_lpDX->m_monitor_rect.top + TEXT_MARGIN + GetCanvasMarginY());
+ m_upper_right_corner_y = max(m_upper_right_corner_y, m_lpDX->m_monitor_work_rect.top - m_lpDX->m_monitor_rect.top + TEXT_MARGIN + GetCanvasMarginY());
+ m_lower_left_corner_y = min(m_lower_left_corner_y , m_lpDX->m_client_height - (m_lpDX->m_monitor_rect.bottom - m_lpDX->m_monitor_work_rect.bottom) - TEXT_MARGIN - GetCanvasMarginY());
+ m_lower_right_corner_y = min(m_lower_right_corner_y, m_lpDX->m_client_height - (m_lpDX->m_monitor_rect.bottom - m_lpDX->m_monitor_work_rect.bottom) - TEXT_MARGIN - GetCanvasMarginY());
+ m_left_edge = max(m_left_edge , m_lpDX->m_monitor_work_rect.left - m_lpDX->m_monitor_rect.left + TEXT_MARGIN + GetCanvasMarginX() );
+ m_right_edge = min(m_right_edge, m_lpDX->m_client_width - (m_lpDX->m_monitor_rect.right - m_lpDX->m_monitor_work_rect.right) - TEXT_MARGIN + GetCanvasMarginX());
+ }
+ }*/
+
+ if (D3D_OK==m_lpDX->m_lpDevice->BeginScene())
+ {
+ MyRenderFn(redraw);
+
+ PrepareFor2DDrawing_B(GetDevice(), GetWidth(), GetHeight());
+
+ RenderDesktop();
+ if (!m_vjd3d9_device) // in VJ mode, this renders to different context, so do it after BeginScene() on 2nd device.
+ RenderBuiltInTextMsgs(); // to m_lpDDSText?
+ MyRenderUI(&m_upper_left_corner_y, &m_upper_right_corner_y, &m_lower_left_corner_y, &m_lower_right_corner_y, m_left_edge, m_right_edge);
+ RenderPlaylist();
+
+ if (!m_vjd3d9_device)
+ m_text.DrawNow();
+
+ m_lpDX->m_lpDevice->EndScene();
+ }
+
+ // VJ Mode:
+ if (m_vj_mode && m_vjd3d9_device && !m_hidden_textwnd && D3D_OK==m_vjd3d9_device->BeginScene())
+ {
+ if (!m_lpDDSText || m_bClearVJWindow)
+ m_vjd3d9_device->Clear(0, 0, D3DCLEAR_TARGET, 0xFF000000, 1.0f, 0);
+ m_bClearVJWindow = false;
+ // note: when using debug DX runtime, textwnd will flash red/green after frame 4, if no text is drawn on a frame!
+
+ RenderBuiltInTextMsgs();
+
+ PrepareFor2DDrawing_B(m_vjd3d9_device, m_nTextWndWidth, m_nTextWndHeight);
+
+ m_text.DrawNow();
+
+ m_vjd3d9_device->EndScene();
+ }
+
+ if (m_screenmode == DESKTOP)
+ {
+ // window is hidden after creation, until 1st frame is ready to go;
+ // now that it's ready, we show it.
+ // see dxcontext::Internal_Init()'s call to SetWindowPos() for the DESKTOP case.
+ if (!IsWindowVisible(GetPluginWindow()))
+ ShowWindow(GetPluginWindow(), SW_SHOWNORMAL);
+ }
+
+ if (m_screenmode == WINDOWED && (m_lpDX->m_client_width != m_lpDX->m_REAL_client_width || m_lpDX->m_client_height != m_lpDX->m_REAL_client_height))
+ {
+ int real_w = m_lpDX->m_REAL_client_width; // real client size, in pixels
+ int real_h = m_lpDX->m_REAL_client_height;
+ int fat_w = m_lpDX->m_client_width; // oversized VS canvas size, in pixels
+ int fat_h = m_lpDX->m_client_height;
+ int extra_w = fat_w - real_w;
+ int extra_h = fat_h - real_h;
+ RECT src, dst;
+ SetRect(&src, extra_w/2, extra_h/2, extra_w/2 + real_w, extra_h/2 + real_h);
+ SetRect(&dst, 0, 0, real_w, real_h);
+ m_lpDX->m_lpDevice->Present(&src, &dst,NULL,NULL);
+ }
+ else
+ m_lpDX->m_lpDevice->Present(NULL,NULL,NULL,NULL);
+
+ if (m_vjd3d9_device && !m_hidden_textwnd)
+ m_vjd3d9_device->Present(NULL,NULL,NULL,NULL);
+}
+
+void CPluginShell::EnforceMaxFPS()
+{
+ int max_fps;
+ switch (m_screenmode)
+ {
+ case WINDOWED: max_fps = m_max_fps_w; break;
+ case FULLSCREEN: max_fps = m_max_fps_fs; break;
+ case FAKE_FULLSCREEN: max_fps = m_max_fps_fs; break;
+ case DESKTOP: max_fps = m_max_fps_dm; break;
+ }
+
+ if (max_fps <= 0)
+ return;
+
+ float fps_lo = (float)max_fps;
+ float fps_hi = (float)max_fps;
+
+ if (m_save_cpu)
+ {
+ // Find the optimal lo/hi bounds for the fps
+ // that will result in a maximum difference,
+ // in the time for a single frame, of 0.003 seconds -
+ // the assumed granularity for Sleep(1) -
+
+ // Using this range of acceptable fps
+ // will allow us to do (sloppy) fps limiting
+ // using only Sleep(1), and never the
+ // second half of it: Sleep(0) in a tight loop,
+ // which sucks up the CPU (whereas Sleep(1)
+ // leaves it idle).
+
+ // The original equation:
+ // 1/(max_fps*t1) = 1/(max*fps/t1) - 0.003
+ // where:
+ // t1 > 0
+ // max_fps*t1 is the upper range for fps
+ // max_fps/t1 is the lower range for fps
+
+ float a = 1;
+ float b = -0.003f * max_fps;
+ float c = -1.0f;
+ float det = b*b - 4*a*c;
+ if (det>0)
+ {
+ float t1 = (-b + sqrtf(det)) / (2*a);
+ //float t2 = (-b - sqrtf(det)) / (2*a);
+
+ if (t1 > 1.0f)
+ {
+ fps_lo = max_fps / t1;
+ fps_hi = max_fps * t1;
+ // verify: now [1.0f/fps_lo - 1.0f/fps_hi] should equal 0.003 seconds.
+ // note: allowing tolerance to go beyond these values for
+ // fps_lo and fps_hi would gain nothing.
+ }
+ }
+ }
+
+ if (m_high_perf_timer_freq.QuadPart > 0)
+ {
+ LARGE_INTEGER t;
+ QueryPerformanceCounter(&t);
+
+ if (m_prev_end_of_frame.QuadPart != 0)
+ {
+ int ticks_to_wait_lo = (int)((float)m_high_perf_timer_freq.QuadPart / (float)fps_hi);
+ int ticks_to_wait_hi = (int)((float)m_high_perf_timer_freq.QuadPart / (float)fps_lo);
+ int done = 0;
+ int loops = 0;
+ do
+ {
+ QueryPerformanceCounter(&t);
+
+ __int64 t2 = t.QuadPart - m_prev_end_of_frame.QuadPart;
+ if (t2 > 2147483000)
+ done = 1;
+ if (t.QuadPart < m_prev_end_of_frame.QuadPart) // time wrap
+ done = 1;
+
+ // this is sloppy - if your freq. is high, this can overflow (to a (-) int) in just a few minutes
+ // but it's ok, we have protection for that above.
+ int ticks_passed = (int)(t.QuadPart - m_prev_end_of_frame.QuadPart);
+ if (ticks_passed >= ticks_to_wait_lo)
+ done = 1;
+
+ if (!done)
+ {
+ // if > 0.01s left, do Sleep(1), which will actually sleep some
+ // steady amount of up to 3 ms (depending on the OS),
+ // and do so in a nice way (cpu meter drops; laptop battery spared).
+ // otherwise, do a few Sleep(0)'s, which just give up the timeslice,
+ // but don't really save cpu or battery, but do pass a tiny
+ // amount of time.
+
+ //if (ticks_left > (int)m_high_perf_timer_freq.QuadPart/500)
+ if (ticks_to_wait_hi - ticks_passed > (int)m_high_perf_timer_freq.QuadPart/100)
+ Sleep(5);
+ else if (ticks_to_wait_hi - ticks_passed > (int)m_high_perf_timer_freq.QuadPart/1000)
+ Sleep(1);
+ else
+ for (int i=0; i<10; i++)
+ Sleep(0); // causes thread to give up its timeslice
+ }
+ }
+ while (!done);
+ }
+
+ m_prev_end_of_frame = t;
+ }
+ else
+ {
+ Sleep(1000/max_fps);
+ }
+}
+
+void CPluginShell::DoTime()
+{
+ if (m_frame==0)
+ {
+ m_fps = 30;
+ m_time = 0;
+ m_time_hist_pos = 0;
+ }
+
+ double new_raw_time;
+ float elapsed;
+
+ if (m_high_perf_timer_freq.QuadPart != 0)
+ {
+ // get high-precision time
+ // precision: usually from 1..6 us (MICROseconds), depending on the cpu speed.
+ // (higher cpu speeds tend to have better precision here)
+ LARGE_INTEGER t;
+ if (!QueryPerformanceCounter(&t))
+ {
+ m_high_perf_timer_freq.QuadPart = 0; // something went wrong (exception thrown) -> revert to crappy timer
+ }
+ else
+ {
+ new_raw_time = (double)t.QuadPart;
+ elapsed = (float)((new_raw_time - m_last_raw_time)/(double)m_high_perf_timer_freq.QuadPart);
+ }
+ }
+
+ if (m_high_perf_timer_freq.QuadPart == 0)
+ {
+ // get low-precision time
+ // precision: usually 1 ms (MILLIsecond) for win98, and 10 ms for win2k.
+ new_raw_time = (double)(timeGetTime()*0.001);
+ elapsed = (float)(new_raw_time - m_last_raw_time);
+ }
+
+ m_last_raw_time = new_raw_time;
+ int slots_to_look_back = (m_high_perf_timer_freq.QuadPart==0) ? TIME_HIST_SLOTS : TIME_HIST_SLOTS/2;
+
+ m_time += 1.0f/m_fps;
+
+ // timekeeping goals:
+ // 1. keep 'm_time' increasing SMOOTHLY: (smooth animation depends on it)
+ // m_time += 1.0f/m_fps; // where m_fps is a bit damped
+ // 2. keep m_time_hist[] 100% accurate (except for filtering out pauses),
+ // so that when we look take the difference between two entries,
+ // we get the real amount of time that passed between those 2 frames.
+ // m_time_hist[i] = m_last_raw_time + elapsed_corrected;
+
+ if (m_frame > TIME_HIST_SLOTS)
+ {
+ if (m_fps < 60.0f)
+ slots_to_look_back = (int)(slots_to_look_back*(0.1f + 0.9f*(m_fps/60.0f)));
+
+ if (elapsed > 5.0f/m_fps || elapsed > 1.0f || elapsed < 0)
+ elapsed = 1.0f / 30.0f;
+
+ float old_hist_time = m_time_hist[(m_time_hist_pos - slots_to_look_back + TIME_HIST_SLOTS) % TIME_HIST_SLOTS];
+ float new_hist_time = m_time_hist[(m_time_hist_pos - 1 + TIME_HIST_SLOTS) % TIME_HIST_SLOTS]
+ + elapsed;
+
+ m_time_hist[m_time_hist_pos] = new_hist_time;
+ m_time_hist_pos = (m_time_hist_pos+1) % TIME_HIST_SLOTS;
+
+ float new_fps = slots_to_look_back / (float)(new_hist_time - old_hist_time);
+ float damping = (m_high_perf_timer_freq.QuadPart==0) ? 0.93f : 0.87f;
+
+ // damp heavily, so that crappy timer precision doesn't make animation jerky
+ if (fabsf(m_fps - new_fps) > 3.0f)
+ m_fps = new_fps;
+ else
+ m_fps = damping*m_fps + (1-damping)*new_fps;
+ }
+ else
+ {
+ float damping = (m_high_perf_timer_freq.QuadPart==0) ? 0.8f : 0.6f;
+
+ if (m_frame < 2)
+ elapsed = 1.0f / 30.0f;
+ else if (elapsed > 1.0f || elapsed < 0)
+ elapsed = 1.0f / m_fps;
+
+ float old_hist_time = m_time_hist[0];
+ float new_hist_time = m_time_hist[(m_time_hist_pos - 1 + TIME_HIST_SLOTS) % TIME_HIST_SLOTS]
+ + elapsed;
+
+ m_time_hist[m_time_hist_pos] = new_hist_time;
+ m_time_hist_pos = (m_time_hist_pos+1) % TIME_HIST_SLOTS;
+
+ if (m_frame > 0)
+ {
+ float new_fps = (m_frame) / (new_hist_time - old_hist_time);
+ m_fps = damping*m_fps + (1-damping)*new_fps;
+ }
+ }
+
+ // Synchronize the audio and video by telling Winamp how many milliseconds we want the audio data,
+ // before it's actually audible. If we set this to the amount of time it takes to display 1 frame
+ // (1/fps), the video and audio should be perfectly synchronized.
+ if (m_fps < 2.0f)
+ mod1.latencyMs = 500;
+ else if (m_fps > 125.0f)
+ mod1.latencyMs = 8;
+ else
+ mod1.latencyMs = (int)(1000.0f/m_fps*m_lpDX->m_frame_delay + 0.5f);
+}
+
+void CPluginShell::AnalyzeNewSound(unsigned char *pWaveL, unsigned char *pWaveR)
+{
+ // we get 576 samples in from winamp.
+ // the output of the fft has 'num_frequencies' samples,
+ // and represents the frequency range 0 hz - 22,050 hz.
+ // usually, plugins only use half of this output (the range 0 hz - 11,025 hz),
+ // since >10 khz doesn't usually contribute much.
+
+ int i;
+
+ float temp_wave[2][576];
+
+ int old_i = 0;
+ for (i=0; i<576; i++)
+ {
+ m_sound.fWaveform[0][i] = (float)((pWaveL[i] ^ 128) - 128);
+ m_sound.fWaveform[1][i] = (float)((pWaveR[i] ^ 128) - 128);
+
+ // simulating single frequencies from 200 to 11,025 Hz:
+ //float freq = 1.0f + 11050*(GetFrame() % 100)*0.01f;
+ //m_sound.fWaveform[0][i] = 10*sinf(i*freq*6.28f/44100.0f);
+
+ // damp the input into the FFT a bit, to reduce high-frequency noise:
+ temp_wave[0][i] = 0.5f*(m_sound.fWaveform[0][i] + m_sound.fWaveform[0][old_i]);
+ temp_wave[1][i] = 0.5f*(m_sound.fWaveform[1][i] + m_sound.fWaveform[1][old_i]);
+ old_i = i;
+ }
+
+ m_fftobj.time_to_frequency_domain(temp_wave[0], m_sound.fSpectrum[0]);
+ m_fftobj.time_to_frequency_domain(temp_wave[1], m_sound.fSpectrum[1]);
+
+ // sum (left channel) spectrum up into 3 bands
+ // [note: the new ranges do it so that the 3 bands are equally spaced, pitch-wise]
+ float min_freq = 200.0f;
+ float max_freq = 11025.0f;
+ float net_octaves = (logf(max_freq/min_freq) / logf(2.0f)); // 5.7846348455575205777914165223593
+ float octaves_per_band = net_octaves / 3.0f; // 1.9282116151858401925971388407864
+ float mult = powf(2.0f, octaves_per_band); // each band's highest freq. divided by its lowest freq.; 3.805831305510122517035102576162
+ // [to verify: min_freq * mult * mult * mult should equal max_freq.]
+ for (int ch=0; ch<2; ch++)
+ {
+ for (i=0; i<3; i++)
+ {
+ // old guesswork code for this:
+ // float exp = 2.1f;
+ // int start = (int)(NUM_FREQUENCIES*0.5f*powf(i/3.0f, exp));
+ // int end = (int)(NUM_FREQUENCIES*0.5f*powf((i+1)/3.0f, exp));
+ // results:
+ // old range: new range (ideal):
+ // bass: 0-1097 200-761
+ // mids: 1097-4705 761-2897
+ // treb: 4705-11025 2897-11025
+ int start = (int)(NUM_FREQUENCIES * min_freq*powf(mult, (float)i)/11025.0f);
+ int end = (int)(NUM_FREQUENCIES * min_freq*powf(mult, (float)(i+1))/11025.0f);
+ if (start < 0) start = 0;
+ if (end > NUM_FREQUENCIES) end = NUM_FREQUENCIES;
+
+ m_sound.imm[ch][i] = 0;
+ for (int j=start; j<end; j++)
+ m_sound.imm[ch][i] += m_sound.fSpectrum[ch][j];
+ m_sound.imm[ch][i] /= (float)(end-start);
+ }
+ }
+
+ // some code to find empirical long-term averages for imm[0..2]:
+ /*{
+ static float sum[3];
+ static int count = 0;
+
+ #define FRAMES_PER_SONG 300 // should be at least 200!
+
+ if (m_frame < FRAMES_PER_SONG)
+ {
+ sum[0] = sum[1] = sum[2] = 0;
+ count = 0;
+ }
+ else
+ {
+ if (m_frame%FRAMES_PER_SONG == 0)
+ {
+ char buf[256];
+ sprintf(buf, "%.4f, %.4f, %.4f (%d samples / ~%d songs)\n",
+ sum[0]/(float)(count),
+ sum[1]/(float)(count),
+ sum[2]/(float)(count),
+ count,
+ count/(FRAMES_PER_SONG-10)
+ );
+ OutputDebugString(buf);
+
+ // skip to next song
+ PostMessage(m_hWndWinamp,WM_COMMAND,40048,0);
+ }
+ else if (m_frame%FRAMES_PER_SONG == 5)
+ {
+ // then advance to 0-2 minutes into the song:
+ PostMessage(m_hWndWinamp,WM_USER,(20 + (warand()%65) + (rand()%65))*1000,106);
+ }
+ else if (m_frame%FRAMES_PER_SONG >= 10)
+ {
+ sum[0] += m_sound.imm[0];
+ sum[1] += m_sound.imm[1];
+ sum[2] += m_sound.imm[2];
+ count++;
+ }
+ }
+ }*/
+
+ // multiply by long-term, empirically-determined inverse averages:
+ // (for a trial of 244 songs, 10 seconds each, somewhere in the 2nd or 3rd minute,
+ // the average levels were: 0.326781557 0.38087377 0.199888934
+ for (int ch=0; ch<2; ch++)
+ {
+ m_sound.imm[ch][0] /= 0.326781557f;//0.270f;
+ m_sound.imm[ch][1] /= 0.380873770f;//0.343f;
+ m_sound.imm[ch][2] /= 0.199888934f;//0.295f;
+ }
+
+ // do temporal blending to create attenuated and super-attenuated versions
+ for (int ch=0; ch<2; ch++)
+ {
+ for (i=0; i<3; i++)
+ {
+ // m_sound.avg[i]
+ {
+ float avg_mix;
+ if (m_sound.imm[ch][i] > m_sound.avg[ch][i])
+ avg_mix = AdjustRateToFPS(0.2f, 14.0f, m_fps);
+ else
+ avg_mix = AdjustRateToFPS(0.5f, 14.0f, m_fps);
+ m_sound.avg[ch][i] = m_sound.avg[ch][i]*avg_mix + m_sound.imm[ch][i]*(1-avg_mix);
+ }
+
+ // m_sound.med_avg[i]
+ // m_sound.long_avg[i]
+ {
+ float med_mix = 0.91f;//0.800f + 0.11f*powf(t, 0.4f); // primarily used for velocity_damping
+ float long_mix = 0.96f;//0.800f + 0.16f*powf(t, 0.2f); // primarily used for smoke plumes
+ med_mix = AdjustRateToFPS(med_mix, 14.0f, m_fps);
+ long_mix = AdjustRateToFPS(long_mix, 14.0f, m_fps);
+ m_sound.med_avg[ch][i] = m_sound.med_avg[ch][i]*(med_mix) + m_sound.imm[ch][i]*(1-med_mix);
+ m_sound.long_avg[ch][i] = m_sound.long_avg[ch][i]*(long_mix) + m_sound.imm[ch][i]*(1-long_mix);
+ }
+ }
+ }
+}
+
+void CPluginShell::PrepareFor2DDrawing_B(IDirect3DDevice9 *pDevice, int w, int h)
+{
+ // New 2D drawing area will have x,y coords in the range <-1,-1> .. <1,1>
+ // +--------+ Y=-1
+ // | |
+ // | screen | Z=0: front of scene
+ // | | Z=1: back of scene
+ // +--------+ Y=1
+ // X=-1 X=1
+ // NOTE: After calling this, be sure to then call (at least):
+ // 1. SetVertexShader()
+ // 2. SetTexture(), if you need it
+ // before rendering primitives!
+ // Also, be sure your sprites have a z coordinate of 0.
+
+ pDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+ pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
+ pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ pDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
+ pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ pDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
+ pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
+ pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ pDevice->SetRenderState(D3DRS_LOCALVIEWER, FALSE);
+ pDevice->SetRenderState(D3DRS_COLORVERTEX, TRUE);
+
+ pDevice->SetTexture(0, NULL);
+ pDevice->SetTexture(1, NULL);
+ pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);//D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);//D3DTEXF_LINEAR);
+ pDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+ pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+ pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
+ pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+
+ pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+ pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
+
+ pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+
+ // set up for 2D drawing:
+ {
+ D3DXMATRIX Ortho2D;
+ D3DXMATRIX Identity;
+
+ pMatrixOrthoLH(&Ortho2D, (float)w, (float)h, 0.0f, 1.0f);
+ D3DXMatrixIdentity(&Identity);
+
+ pDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D);
+ pDevice->SetTransform(D3DTS_WORLD, &Identity);
+ pDevice->SetTransform(D3DTS_VIEW, &Identity);
+ }
+}
+
+void CPluginShell::DrawDarkTranslucentBox(RECT* pr)
+{
+ // 'pr' is the rectangle that some text will occupy;
+ // a black box will be drawn around it, plus a bit of extra margin space.
+
+ if (m_vjd3d9_device)
+ return;
+
+ m_lpDX->m_lpDevice->SetVertexShader(NULL);
+ m_lpDX->m_lpDevice->SetPixelShader(NULL);
+ m_lpDX->m_lpDevice->SetFVF(SIMPLE_VERTEX_FORMAT);
+ m_lpDX->m_lpDevice->SetTexture(0, NULL);
+
+ m_lpDX->m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+ m_lpDX->m_lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ m_lpDX->m_lpDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
+ m_lpDX->m_lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ m_lpDX->m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
+
+ // set up a quad
+ SIMPLEVERTEX verts[4];
+ for (int i=0; i<4; i++)
+ {
+ verts[i].x = (i%2==0) ? (float)(-m_lpDX->m_client_width /2 + pr->left) :
+ (float)(-m_lpDX->m_client_width /2 + pr->right);
+ verts[i].y = (i/2==0) ? (float)-(-m_lpDX->m_client_height/2 + pr->bottom) :
+ (float)-(-m_lpDX->m_client_height/2 + pr->top);
+ verts[i].z = 0;
+ verts[i].Diffuse = (m_screenmode==DESKTOP) ? 0xE0000000 : 0xD0000000;
+ }
+
+ m_lpDX->m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, verts, sizeof(SIMPLEVERTEX));
+
+ // undo unusual state changes:
+ m_lpDX->m_lpDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+ m_lpDX->m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+}
+
+void CPluginShell::RenderBuiltInTextMsgs()
+{
+ int _show_press_f1_NOW = (m_show_press_f1_msg && m_time < PRESS_F1_DUR);
+
+ {
+ RECT r;
+
+ if (m_show_help)
+ {
+ int y = m_upper_left_corner_y;
+
+ SetRect(&r, 0, 0, GetWidth(), GetHeight());
+ if(!g_szHelp_W)
+ m_d3dx_font[HELPSCREEN_FONT]->DrawTextA(NULL, (char*)g_szHelp, -1, &r, DT_CALCRECT, 0xFFFFFFFF);
+ else
+ m_d3dx_font[HELPSCREEN_FONT]->DrawTextW(NULL, g_szHelp, -1, &r, DT_CALCRECT, 0xFFFFFFFF);
+
+ r.top += m_upper_left_corner_y;
+ r.left += m_left_edge;
+ r.right += m_left_edge + PLAYLIST_INNER_MARGIN*2;
+ r.bottom += m_upper_left_corner_y + PLAYLIST_INNER_MARGIN*2;
+ DrawDarkTranslucentBox(&r);
+
+ r.top += PLAYLIST_INNER_MARGIN;
+ r.left += PLAYLIST_INNER_MARGIN;
+ r.right -= PLAYLIST_INNER_MARGIN;
+ r.bottom -= PLAYLIST_INNER_MARGIN;
+ if(!g_szHelp_W)
+ m_d3dx_font[HELPSCREEN_FONT]->DrawTextA(NULL, (char*)g_szHelp, -1, &r, 0, 0xFFFFFFFF);
+ else
+ m_d3dx_font[HELPSCREEN_FONT]->DrawTextW(NULL, g_szHelp, -1, &r, 0, 0xFFFFFFFF);
+
+ m_upper_left_corner_y += r.bottom-r.top + PLAYLIST_INNER_MARGIN*3;
+ }
+
+ // render 'Press F1 for Help' message in lower-right corner:
+ if (_show_press_f1_NOW)
+ {
+ int dx = (int)(160.0f * powf(m_time/(float)(PRESS_F1_DUR), (float)(PRESS_F1_EXP)));
+ SetRect(&r, m_left_edge, m_lower_right_corner_y - GetFontHeight(DECORATIVE_FONT), m_right_edge + dx, m_lower_right_corner_y);
+ m_lower_right_corner_y -= m_d3dx_font[DECORATIVE_FONT]->DrawTextW(NULL, WASABI_API_LNGSTRINGW(IDS_PRESS_F1_MSG), -1, &r, DT_RIGHT, 0xFFFFFFFF);
+ }
+ }
+}
+
+void CPluginShell::RenderPlaylist()
+{
+ // draw playlist:
+ if (m_show_playlist)
+ {
+ RECT r;
+ int nSongs = SendMessage(m_hWndWinamp,WM_USER, 0, 124);
+ int now_playing = SendMessage(m_hWndWinamp,WM_USER, 0, 125);
+
+ if (nSongs <= 0)
+ {
+ m_show_playlist = 0;
+ }
+ else
+ {
+ int playlist_vert_pixels = m_lower_left_corner_y - m_upper_left_corner_y;
+ int disp_lines = min(MAX_SONGS_PER_PAGE, (playlist_vert_pixels - PLAYLIST_INNER_MARGIN*2) / GetFontHeight(PLAYLIST_FONT));
+ int total_pages = (nSongs) / disp_lines;
+
+ if (disp_lines<=0)
+ return;
+
+ // apply PgUp/PgDn keypresses since last time
+ m_playlist_pos -= m_playlist_pageups * disp_lines;
+ m_playlist_pageups = 0;
+
+ if (m_playlist_pos < 0)
+ m_playlist_pos = 0;
+ if (m_playlist_pos >= nSongs)
+ m_playlist_pos = nSongs-1;
+
+ // NOTE: 'dwFlags' is used for both DDRAW and DX9
+ DWORD dwFlags = DT_SINGLELINE;// | DT_NOPREFIX | DT_WORD_ELLIPSIS;
+ DWORD color;
+
+ int cur_page = (m_playlist_pos) / disp_lines;
+ int cur_line = (m_playlist_pos + disp_lines - 1) % disp_lines;
+ int new_top_idx = cur_page * disp_lines;
+ int new_btm_idx = new_top_idx + disp_lines;
+ wchar_t buf[1024] = {0};
+
+ // ask winamp for the song names, but DO IT BEFORE getting the DC,
+ // otherwise vaio will crash (~DDRAW port).
+ if (m_playlist_top_idx != new_top_idx ||
+ m_playlist_btm_idx != new_btm_idx)
+ {
+ for (int i=0; i<disp_lines; i++)
+ {
+ int j = new_top_idx + i;
+ if (j < nSongs)
+ {
+ // clip max len. of song name to 240 chars, to prevent overflows
+ lstrcpynW(buf, (wchar_t*)SendMessage(m_hWndWinamp, WM_USER, j, IPC_GETPLAYLISTTITLEW), 240);
+ wsprintfW(m_playlist[i], L"%d. %s ", j+1, buf); // leave an extra space @ end, so italicized fonts don't get clipped
+ }
+ }
+ }
+
+ // update playlist cache, if necessary:
+ if (m_playlist_top_idx != new_top_idx ||
+ m_playlist_btm_idx != new_btm_idx)
+ {
+ m_playlist_top_idx = new_top_idx;
+ m_playlist_btm_idx = new_btm_idx;
+ m_playlist_width_pixels = 0;
+
+ int max_w = min(m_right_edge - m_left_edge, m_lpDX->m_client_width - TEXT_MARGIN*2 - PLAYLIST_INNER_MARGIN*2);
+
+ for (int i=0; i<disp_lines; i++)
+ {
+ int j = new_top_idx + i;
+ if (j < nSongs)
+ {
+ // clip max len. of song name to 240 chars, to prevent overflows
+ //strcpy(buf, (char*)SendMessage(m_hWndWinamp, WM_USER, j, 212));
+ //buf[240] = 0;
+ //sprintf(m_playlist[i], "%d. %s ", j+1, buf); // leave an extra space @ end, so italicized fonts don't get clipped
+
+ SetRect(&r, 0, 0, max_w, 1024);
+ m_d3dx_font[PLAYLIST_FONT]->DrawTextW(NULL, m_playlist[i], -1, &r, dwFlags | DT_CALCRECT, 0xFFFFFFFF);
+ int w = r.right-r.left;
+ if (w>0)
+ m_playlist_width_pixels = max(m_playlist_width_pixels, w);
+ }
+ else
+ {
+ m_playlist[i][0] = 0;
+ }
+ }
+
+ if (m_playlist_width_pixels == 0 ||
+ m_playlist_width_pixels > max_w)
+ m_playlist_width_pixels = max_w;
+ }
+
+ int start = max(0, (cur_page)*disp_lines);
+ int end = min(nSongs, (cur_page+1)*disp_lines);
+
+ // draw dark box around where the playlist will go:
+
+ RECT r;
+ r.top = m_upper_left_corner_y;
+ r.left = m_left_edge;
+ r.right = m_left_edge + m_playlist_width_pixels + PLAYLIST_INNER_MARGIN*2;
+ r.bottom = m_upper_left_corner_y + (end-start)*GetFontHeight(PLAYLIST_FONT) + PLAYLIST_INNER_MARGIN*2;
+ DrawDarkTranslucentBox(&r);
+
+ //m_d3dx_font[PLAYLIST_FONT]->Begin();
+
+ // draw playlist text
+ int y = m_upper_left_corner_y + PLAYLIST_INNER_MARGIN;
+ for (int i=start; i<end; i++)
+ {
+ SetRect(&r, m_left_edge + PLAYLIST_INNER_MARGIN, y, m_left_edge + PLAYLIST_INNER_MARGIN + m_playlist_width_pixels, y + GetFontHeight(PLAYLIST_FONT));
+
+ if (m_lpDX->GetBitDepth() == 8)
+ color = (i==m_playlist_pos) ?
+ (i==now_playing ? 0xFFFFFFFF : 0xFFFFFFFF) :
+ (i==now_playing ? 0xFFFFFFFF : 0xFF707070);
+ else
+ color = (i==m_playlist_pos) ?
+ (i==now_playing ? PLAYLIST_COLOR_BOTH : PLAYLIST_COLOR_HILITE_TRACK) :
+ (i==now_playing ? PLAYLIST_COLOR_PLAYING_TRACK : PLAYLIST_COLOR_NORMAL);
+
+ y += m_d3dx_font[PLAYLIST_FONT]->DrawTextW(NULL, m_playlist[i-start], -1, &r, dwFlags, color);
+ }
+
+ //m_d3dx_font[PLAYLIST_FONT]->End();
+ }
+ }
+}
+
+void CPluginShell::SuggestHowToFreeSomeMem()
+{
+ // This function is called when the plugin runs out of video memory;
+ // it lets you show a messagebox to the user so you can (intelligently)
+ // suggest how to free up some video memory, based on what settings
+ // they've chosen.
+
+ wchar_t str[1024];
+
+ if (m_lpDX->m_current_mode.multisamp != D3DMULTISAMPLE_NONE)
+ {
+ if (m_lpDX->m_current_mode.screenmode == WINDOWED)
+ WASABI_API_LNGSTRINGW_BUF(IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG, str, 2048);
+ else if (m_lpDX->m_current_mode.screenmode == FAKE_FULLSCREEN)
+ WASABI_API_LNGSTRINGW_BUF(IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG_2, str, 2048);
+ else
+ WASABI_API_LNGSTRINGW_BUF(IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG_3, str, 2048);
+ }
+ else
+ if (m_lpDX->m_current_mode.screenmode == FULLSCREEN) // true fullscreen
+ WASABI_API_LNGSTRINGW_BUF(IDS_TO_FREE_UP_VIDEO_MEMORY, str, 2048);
+ else // windowed, desktop mode, or fake fullscreen
+ WASABI_API_LNGSTRINGW_BUF(IDS_TO_FREE_UP_VIDEO_MEMORY, str, 2048);
+
+ MessageBoxW(m_lpDX->GetHwnd(), str, WASABI_API_LNGSTRINGW(IDS_MILKDROP_SUGGESTION), MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+}
+
+LRESULT CALLBACK CPluginShell::WindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
+{
+ //if (uMsg==WM_GETDLGCODE)
+ // return DLGC_WANTALLKEYS|DLGC_WANTCHARS|DLGC_WANTMESSAGE; // this tells the embedwnd that we want keypresses to flow through to our client wnd.
+
+ if (uMsg == WM_CREATE)
+ {
+ CREATESTRUCT *create = (CREATESTRUCT *)lParam;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)create->lpCreateParams);
+ }
+
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
+ if (p)
+ return p->PluginShellWindowProc(hWnd, uMsg, wParam, lParam);
+ else
+ return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+}
+
+LRESULT CPluginShell::PluginShellWindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
+{
+ USHORT mask = 1 << (sizeof(SHORT)*8 - 1);
+ //bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+ bool bCtrlHeldDown = (GetKeyState(VK_CONTROL) & mask) != 0;
+ //bool bAltHeldDown: most keys come in under WM_SYSKEYDOWN when ALT is depressed.
+
+ int i;
+#ifdef _DEBUG
+ char caption[256] = "WndProc: frame 0, ";
+ if (m_frame > 0)
+ {
+ float time = m_time;
+ int hours = (int)(time/3600);
+ time -= hours*3600;
+ int minutes = (int)(time/60);
+ time -= minutes*60;
+ int seconds = (int)time;
+ time -= seconds;
+ int dsec = (int)(time*100);
+ sprintf(caption, "WndProc: frame %d, t=%dh:%02dm:%02d.%02ds, ", m_frame, hours, minutes, seconds, dsec);
+ }
+
+ if (uMsg != WM_MOUSEMOVE &&
+ uMsg != WM_NCHITTEST &&
+ uMsg != WM_SETCURSOR &&
+ uMsg != WM_COPYDATA &&
+ uMsg != WM_USER)
+ OutputDebugMessage(caption, hWnd, uMsg, wParam, lParam);
+#endif
+
+ switch (uMsg)
+ {
+ case WM_USER:
+ if (m_screenmode == DESKTOP)
+ {
+ // this function resides in vms_desktop.dll;
+ // its response will come later, via the WM_COPYDATA
+ // message (See below).
+ //KIV: **THIS CALL CRASHES EXPLORER IN VISTA**
+ getItemData(wParam);
+ return 0;
+ }
+ break;
+
+ case WM_COPYDATA:
+ if (m_screenmode == DESKTOP)
+ {
+ // this message is vms_desktop.dll's response to
+ // our call to getItemData().
+ PCOPYDATASTRUCT c = (PCOPYDATASTRUCT)lParam;
+ if (c && (c->cbData % sizeof(icon_t) == 0))
+ {
+ icon_t *pNewIcons = (icon_t*)c->lpData;
+
+ EnterCriticalSection(&m_desktop_cs);
+
+ if (m_desktop_icon_state == 1 && (c->dwData & 0x80000000)) // if doing a total refresh...
+ {
+ // ...we build the list from zero
+ int len = c->dwData & 0xFFFF;
+ for (int i=0; i<len; i++)
+ m_icon_list.push_back(pNewIcons[i]);
+ }
+ else if (m_desktop_icon_state == 3 && !(c->dwData & 0x80000000))
+ {
+ // otherwise, we alter existing things in the list:
+ IconList::iterator p;
+ int start = c->dwData & 0xFFFF;
+ int len = c->dwData >> 16;
+
+ int i = 0;
+ for (p = m_icon_list.begin(); p != m_icon_list.end() && i<start; p++)
+ i++;
+ for (; p != m_icon_list.end() && i<start+len; p++)
+ {
+ p->x = pNewIcons[i-start].x;
+ p->y = pNewIcons[i-start].y;
+ memcpy(p->name, pNewIcons[i-start].name, sizeof(p->name));
+ memcpy(p->pidl, pNewIcons[i-start].pidl, sizeof(p->pidl));
+ i++;
+ }
+
+ m_desktop_icon_state = 2;
+ m_desktop_icon_update_frame = GetFrame();
+ }
+
+ LeaveCriticalSection(&m_desktop_cs);
+ }
+
+ return 0;
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ // Repaint window when song is paused and image needs to be repainted:
+ if (SendMessage(m_hWndWinamp,WM_USER,0,104)!=1 && m_lpDX && m_lpDX->m_lpDevice && GetFrame() > 0) // WM_USER/104 return codes: 1=playing, 3=paused, other=stopped
+ {
+ m_lpDX->m_lpDevice->Present(NULL,NULL,NULL,NULL);
+ return 0;
+ }
+ break;
+
+ case WM_WINDOWPOSCHANGING:
+ if (
+ m_screenmode == DESKTOP
+ && (!m_force_accept_WM_WINDOWPOSCHANGING)
+ && m_lpDX && m_lpDX->m_ready
+ )
+ {
+ // unless we requested it ourselves or it's init time,
+ // prevent the fake desktop window from moving around
+ // in the Z order! (i.e., keep it on the bottom)
+
+ // without this code, when you click on the 'real' desktop
+ // in a multimon setup, any windows that are overtop of the
+ // 'fake' desktop will flash, since they'll be covered
+ // up by the fake desktop window (but then shown again on
+ // the next frame, when we detect that the fake desktop
+ // window isn't on bottom & send it back to the bottom).
+
+ LPWINDOWPOS pwp = (LPWINDOWPOS)lParam;
+ if (pwp)
+ pwp->flags |= SWP_NOOWNERZORDER | SWP_NOZORDER;
+ }
+ if (m_screenmode==WINDOWED && m_lpDX && m_lpDX->m_ready && m_lpDX->m_current_mode.m_skin)
+ m_lpDX->SaveWindow();
+ break;
+ case WM_NCACTIVATE:
+ // *Very Important Handler!*
+ // -Without this code, the app would not work properly when running in true
+ // fullscreen mode on multiple monitors; it would auto-minimize whenever the
+ // user clicked on a window in another display.
+ if (wParam == 0 &&
+ m_screenmode == FULLSCREEN &&
+ m_frame > 0 &&
+ !m_exiting &&
+ m_lpDX &&
+ m_lpDX->m_ready
+ && m_lpDX->m_lpD3D &&
+ m_lpDX->m_lpD3D->GetAdapterCount() > 1
+ )
+ {
+ return 0;
+ }
+ break;
+
+ case WM_DESTROY:
+ // note: don't post quit message here if the window is being destroyed
+ // and re-created on a switch between windowed & FAKE fullscreen modes.
+ if (!m_lpDX->TempIgnoreDestroyMessages())
+ {
+ // this is a final exit, and not just destroy-then-recreate-the-window.
+ // so, flag DXContext so it knows that someone else
+ // will take care of destroying the window!
+ m_lpDX->OnTrulyExiting();
+ PostQuitMessage(0);
+ }
+ return FALSE;
+ break;
+ // benski> a little hack to get the window size correct. it seems to work
+ case WM_USER+555:
+ if (m_lpDX && m_lpDX->m_ready && m_screenmode==WINDOWED && !m_resizing)
+ {
+ OnUserResizeWindow();
+ m_lpDX->SaveWindow();
+ }
+ break;
+ case WM_MOVE:
+ m_lpDX->SaveWindow();
+ break;
+ case WM_SIZE:
+ // clear or set activity flag to reflect focus
+ if (m_lpDX && m_lpDX->m_ready && m_screenmode==WINDOWED && !m_resizing)
+ {
+ m_hidden = (SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam) ? TRUE : FALSE;
+
+ if (SIZE_MAXIMIZED==wParam || SIZE_RESTORED==wParam) // the window has been maximized or restored
+ OnUserResizeWindow();
+ }
+ break;
+
+ case WM_ENTERSIZEMOVE:
+ m_resizing = 1;
+ break;
+
+ case WM_EXITSIZEMOVE:
+ if (m_lpDX && m_lpDX->m_ready && m_screenmode==WINDOWED)
+ OnUserResizeWindow();
+ m_lpDX->SaveWindow();
+ m_resizing = 0;
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ // don't let the window get too small
+ MINMAXINFO* p = (MINMAXINFO*)lParam;
+ if (p->ptMinTrackSize.x < 64)
+ p->ptMinTrackSize.x = 64;
+ p->ptMinTrackSize.y = p->ptMinTrackSize.x*3/4;
+ }
+ return 0;
+
+ case WM_MOUSEMOVE:
+ if (m_screenmode==DESKTOP && (m_desktop_dragging==1 || m_desktop_box==1))
+ {
+ m_desktop_drag_curpos.x = LOWORD(lParam);
+ m_desktop_drag_curpos.y = HIWORD(lParam);
+ if (m_desktop_box==1)
+ {
+ // update selection based on box coords
+ RECT box, temp;
+ box.left = min(m_desktop_drag_curpos.x, m_desktop_drag_startpos.x);
+ box.right = max(m_desktop_drag_curpos.x, m_desktop_drag_startpos.x);
+ box.top = min(m_desktop_drag_curpos.y, m_desktop_drag_startpos.y);
+ box.bottom = max(m_desktop_drag_curpos.y, m_desktop_drag_startpos.y);
+
+ IconList::iterator p;
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ {
+ p->selected = 0;
+
+ if (IntersectRect(&temp, &box, &p->label_rect))
+ p->selected = 1;
+ else if (IntersectRect(&temp, &box, &p->icon_rect))
+ p->selected = 1;
+ }
+ }
+
+ // repaint window manually, if winamp is paused
+ if (SendMessage(m_hWndWinamp,WM_USER,0,104) != 1)
+ {
+ PushWindowToJustBeforeDesktop(GetPluginWindow());
+ DrawAndDisplay(1);
+ }
+
+ //return 0;
+ }
+ m_lpDX->SaveWindow();
+ break;
+
+ case WM_LBUTTONUP:
+ if (m_screenmode==DESKTOP)
+ {
+ if (m_desktop_dragging)
+ {
+ m_desktop_dragging = 0;
+
+ // move selected item(s) to new cursor position
+ int dx = LOWORD(lParam) - m_desktop_drag_startpos.x;
+ int dy = HIWORD(lParam) - m_desktop_drag_startpos.y;
+
+ if (dx!=0 || dy!=0)
+ {
+ int idx=0;
+ IconList::iterator p;
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ {
+ if (p->selected)
+ {
+ SendMessage(m_hWndDesktopListView, LVM_SETITEMPOSITION, idx, MAKELPARAM(p->x + dx, p->y + dy));
+ p->x += dx;
+ p->y += dy;
+ }
+ idx++;
+ }
+ }
+
+ // repaint window manually, if winamp is paused
+ if (SendMessage(m_hWndWinamp,WM_USER,0,104) != 1)
+ {
+ PushWindowToJustBeforeDesktop(GetPluginWindow());
+ DrawAndDisplay(1);
+ }
+ }
+
+ if (m_desktop_box)
+ {
+ m_desktop_box = 0;
+
+ // repaint window manually, if winamp is paused
+ if (SendMessage(m_hWndWinamp,WM_USER,0,104) != 1)
+ {
+ PushWindowToJustBeforeDesktop(GetPluginWindow());
+ DrawAndDisplay(1);
+ }
+ }
+
+ //return 0;
+ }
+ break;
+
+ case WM_USER + 1666:
+ if (wParam == 1 && lParam == 15)
+ {
+ if (m_screenmode == FULLSCREEN || m_screenmode == FAKE_FULLSCREEN)
+ ToggleFullScreen();
+ }
+ return 0;
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONUP:
+ // Toggle between Fullscreen and Windowed modes on double-click
+ // note: this requires the 'CS_DBLCLKS' windowclass style!
+ if (m_screenmode != DESKTOP)
+ {
+ SetFocus(hWnd);
+ if (uMsg==WM_LBUTTONDBLCLK && m_frame>0)
+ {
+ ToggleFullScreen();
+ return 0;
+ }
+ }
+ else
+ {
+ POINT pt;
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+
+ int done = 0;
+
+ for (int pass=0; pass<2 && !done; pass++)
+ {
+ IconList::iterator p;
+ for (p = m_icon_list.begin(); p != m_icon_list.end(); p++)
+ {
+ RECT *pr = (pass==0) ? &p->icon_rect : &p->label_rect;
+ int bottom_extend = (pass==0) ? 3 : 0; // accepts clicks in the 3-pixel gap between the icon and the text label.
+ if (pt.x >= pr->left &&
+ pt.x <= pr->right &&
+ pt.y >= pr->top &&
+ pt.y <= pr->bottom + bottom_extend)
+ {
+ switch (uMsg)
+ {
+ case WM_RBUTTONUP:
+ //pt.x += m_lpDX->m_monitor_rect.left;
+ //pt.y += m_lpDX->m_monitor_rect.top;
+ DoExplorerMenu(GetPluginWindow(), (LPITEMIDLIST)p->pidl, pt);
+ break;
+ case WM_LBUTTONDBLCLK:
+ {
+ char buf[MAX_PATH];
+ sprintf(buf, "%s\\%s", m_szDesktopFolder, p->name);
+ ExecutePidl((LPITEMIDLIST)p->pidl, buf, m_szDesktopFolder, GetPluginWindow());
+ }
+ break;
+ case WM_LBUTTONDOWN:
+ m_desktop_dragging = 1;
+ memcpy(m_desktop_drag_pidl, p->pidl, sizeof(m_desktop_drag_pidl));
+ m_desktop_drag_startpos.x = LOWORD(lParam);
+ m_desktop_drag_startpos.y = HIWORD(lParam);
+ m_desktop_drag_curpos.x = LOWORD(lParam);
+ m_desktop_drag_curpos.y = HIWORD(lParam);
+ if (!(wParam & MK_CONTROL)) // if CTRL not held down
+ {
+ if (!p->selected)
+ {
+ DeselectDesktop();
+ p->selected = 1;
+ }
+ }
+ else
+ {
+ p->selected = 1-p->selected;
+ }
+ break;
+ case WM_RBUTTONDOWN:
+ DeselectDesktop();
+ p->selected = 1;
+ break;
+ }
+
+ done = 1;
+ break;
+ }
+ }
+ }
+
+ if (!done)
+ {
+ // deselect all, unless they're CTRL+clicking and missed an icon.
+ if (uMsg!=WM_LBUTTONDOWN || !(wParam & MK_CONTROL))
+ DeselectDesktop();
+
+ if (uMsg==WM_RBUTTONUP)// || uMsg==WM_RBUTTONDOWN)
+ {
+ // note: can't use GetMenu and TrackPopupMenu here because the hwnd param to TrackPopupMenu must belong to current application.
+
+ // (before sending coords to desktop window, xform them into its client coords:)
+ POINT pt;
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+ ScreenToClient(m_hWndDesktopListView, &pt);
+ lParam = MAKELPARAM(pt.x + m_lpDX->m_monitor_rect.left, pt.y + m_lpDX->m_monitor_rect.top);
+
+ PostMessage(m_hWndDesktopListView, uMsg, wParam, lParam);
+ //PostMessage(m_hWndDesktopListView, WM_CONTEXTMENU, (WPARAM)m_hWndDesktopListView, lParam);
+ }
+ else if (uMsg==WM_LBUTTONDOWN)
+ {
+ m_desktop_box = 1;
+ m_desktop_drag_startpos.x = LOWORD(lParam);
+ m_desktop_drag_startpos.y = HIWORD(lParam);
+ m_desktop_drag_curpos.x = LOWORD(lParam);
+ m_desktop_drag_curpos.y = HIWORD(lParam);
+ }
+ }
+
+ // repaint window manually, if winamp is paused
+ if (SendMessage(m_hWndWinamp,WM_USER,0,104) != 1)
+ {
+ PushWindowToJustBeforeDesktop(GetPluginWindow());
+ DrawAndDisplay(1);
+ }
+
+ //return 0;
+ }
+ break;
+
+ case WM_SETFOCUS:
+ // note: this msg never comes in when embedwnd is used, but that's ok, because that's only
+ // in Windowed mode, and m_lost_focus only makes us sleep when fullscreen.
+ m_lost_focus = 0;
+ break;
+
+ case WM_KILLFOCUS:
+ // note: this msg never comes in when embedwnd is used, but that's ok, because that's only
+ // in Windowed mode, and m_lost_focus only makes us sleep when fullscreen.
+ m_lost_focus = 1;
+ break;
+
+ case WM_SETCURSOR:
+ if (
+ (m_screenmode == FULLSCREEN) ||
+ (m_screenmode == FAKE_FULLSCREEN && m_lpDX->m_fake_fs_covers_all)
+ )
+ {
+ // hide the cursor
+ SetCursor(NULL);
+ return TRUE; // prevent Windows from setting cursor to window class cursor
+ }
+ break;
+
+ case WM_NCHITTEST:
+ // Prevent the user from selecting the menu in fullscreen mode
+ if (m_screenmode != WINDOWED)
+ return HTCLIENT;
+ break;
+
+ case WM_SYSCOMMAND:
+ // Prevent *moving/sizing* and *entering standby mode* when in fullscreen mode
+ switch (wParam)
+ {
+ case SC_MOVE:
+ case SC_SIZE:
+ case SC_MAXIMIZE:
+ case SC_KEYMENU:
+ if (m_screenmode != WINDOWED)
+ return 1;
+ break;
+ case SC_MONITORPOWER:
+ if (m_screenmode == FULLSCREEN || m_screenmode == FAKE_FULLSCREEN)
+ return 1;
+ break;
+ }
+ break;
+
+ case WM_CONTEXTMENU:
+ // launch popup context menu. see handler for WM_COMMAND also.
+ if (m_screenmode == DESKTOP)
+ {
+ // note: execution should never reach this point,
+ // because we don't pass WM_RBUTTONUP to DefWindowProc
+ // when in desktop mode!
+ return 0;
+ }
+ else if (m_screenmode == WINDOWED) // context menus only allowed in ~windowed modes
+ {
+ TrackPopupMenuEx(m_context_menu, TPM_VERTICAL, LOWORD(lParam), HIWORD(lParam), hWnd, NULL);
+ return 0;
+ }
+ break;
+
+ case WM_COMMAND:
+ // handle clicks on items on context menu.
+ if (m_screenmode == WINDOWED)
+ {
+ switch (LOWORD(wParam))
+ {
+ case ID_QUIT:
+ m_exiting = 1;
+ PostMessage(hWnd, WM_CLOSE, 0, 0);
+ return 0;
+ case ID_GO_FS:
+ if (m_frame > 0)
+ ToggleFullScreen();
+ return 0;
+ case ID_DESKTOP_MODE:
+ if (m_frame > 0)
+ ToggleDesktop();
+ return 0;
+ case ID_SHOWHELP:
+ ToggleHelp();
+ return 0;
+ case ID_SHOWPLAYLIST:
+ TogglePlaylist();
+ return 0;
+ }
+ // then allow the plugin to override any command:
+ if (MyWindowProc(hWnd, uMsg, wParam, lParam) == 0)
+ return 0;
+ }
+ break;
+
+ /*
+ KEY HANDLING: the basic idea:
+ -in all cases, handle or capture:
+ -ZXCVBRS, zxcvbrs
+ -also make sure it's case-insensitive! (lowercase come through only as WM_CHAR; uppercase come in as both)
+ -(ALT+ENTER)
+ -(F1, ESC, UP, DN, Left, Right, SHIFT+l/r)
+ -(P for playlist)
+ -when playlist showing: steal J, HOME, END, PGUP, PGDN, UP, DOWN, ESC
+ -(BLOCK J, L)
+ -when integrated with winamp (using embedwnd), also handle these keys:
+ -j, l, L, CTRL+L [windowed mode only!]
+ -CTRL+P, CTRL+D
+ -CTRL+TAB
+ -ALT-E
+ -ALT+F (main menu)
+ -ALT+3 (id3)
+ */
+
+ case WM_SYSKEYDOWN:
+ if (wParam==VK_RETURN && m_frame > 0)
+ {
+ ToggleFullScreen();
+ return 0;
+ }
+ // if in embedded mode (using winamp skin), pass ALT+ keys on to winamp
+ // ex: ALT+E, ALT+F, ALT+3...
+ if (m_screenmode==WINDOWED && m_lpDX->m_current_mode.m_skin)
+ return PostMessage(m_hWndWinamp, uMsg, wParam, lParam); // force-pass to winamp; required for embedwnd
+ break;
+
+ case WM_SYSKEYUP:
+ if (m_screenmode==WINDOWED && m_lpDX->m_current_mode.m_skin)
+ return PostMessage(m_hWndWinamp, uMsg, wParam, lParam); // force-pass to winamp; required for embedwnd
+ break;
+
+ case WM_SYSCHAR:
+ if ((wParam=='k' || wParam=='K'))
+ {
+ OnAltK();
+ return 0;
+ }
+ if ((wParam=='d' || wParam=='D') && m_frame > 0)
+ {
+ ToggleDesktop();
+ return 0;
+ }
+ break;
+
+ case WM_CHAR:
+ // if playlist is showing, steal p/j keys from the plugin:
+ if (m_show_playlist)
+ {
+ switch (wParam)
+ {
+ case 'j':
+ case 'J':
+ m_playlist_pos = SendMessage(m_hWndWinamp,WM_USER, 0, 125);
+ return 0;
+ default:
+ {
+ int nSongs = SendMessage(m_hWndWinamp,WM_USER, 0, 124);
+ int found = 0;
+ int orig_pos = m_playlist_pos;
+ int inc = (wParam>='A' && wParam<='Z') ? -1 : 1;
+ while (1)
+ {
+ if (inc==1 && m_playlist_pos >= nSongs-1)
+ break;
+ if (inc==-1 && m_playlist_pos <= 0)
+ break;
+
+ m_playlist_pos += inc;
+
+ char buf[32];
+ strncpy(buf, (char*)SendMessage(m_hWndWinamp, WM_USER, m_playlist_pos, 212), 31);
+ buf[31] = 0;
+
+ // remove song # and period from beginning
+ char *p = buf;
+ while (*p >= '0' && *p <= '9') p++;
+ if (*p == '.' && *(p+1) == ' ')
+ {
+ p += 2;
+ int pos = 0;
+ while (*p != 0)
+ {
+ buf[pos++] = *p;
+ p++;
+ }
+ buf[pos++] = 0;
+ }
+
+ int wParam2 = (wParam>='A' && wParam<='Z') ? (wParam + 'a'-'A') : (wParam + 'A'-'a');
+ if (buf[0]==wParam || buf[0]==wParam2)
+ {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ m_playlist_pos = orig_pos;
+ }
+ return 0;
+ }
+ }
+
+ // then allow the plugin to override any keys:
+ if (MyWindowProc(hWnd, uMsg, wParam, lParam) == 0)
+ return 0;
+
+ // finally, default key actions:
+ if (wParam == keyMappings[5] || wParam == keyMappings[6]) // 'z' or 'Z'
+ {
+ PostMessage(m_hWndWinamp,WM_COMMAND,40044,0);
+ return 0;
+ }
+ else
+ {
+ switch (wParam)
+ {
+ // WINAMP PLAYBACK CONTROL KEYS:
+ case 'x':
+ case 'X':
+ PostMessage(m_hWndWinamp,WM_COMMAND,40045,0);
+ return 0;
+ case 'c':
+ case 'C':
+ PostMessage(m_hWndWinamp,WM_COMMAND,40046,0);
+ return 0;
+ case 'v':
+ case 'V':
+ PostMessage(m_hWndWinamp,WM_COMMAND,40047,0);
+ return 0;
+ case 'b':
+ case 'B':
+ PostMessage(m_hWndWinamp,WM_COMMAND,40048,0);
+ return 0;
+ case 's':
+ case 'S':
+ //if (SendMessage(m_hWndWinamp,WM_USER,0,250))
+ // sprintf(m_szUserMessage, "shuffle is now OFF"); // shuffle was on
+ //else
+ // sprintf(m_szUserMessage, "shuffle is now ON"); // shuffle was off
+
+ // toggle shuffle
+ PostMessage(m_hWndWinamp,WM_COMMAND,40023,0);
+ return 0;
+ case 'r':
+ case 'R':
+ // toggle repeat
+ PostMessage(m_hWndWinamp,WM_COMMAND,40022,0);
+ return 0;
+ case 'p':
+ case 'P':
+ TogglePlaylist();
+ return 0;
+ case 'l':
+ // note that this is actually correct; when you hit 'l' from the
+ // MAIN winamp window, you get an "open files" dialog; when you hit
+ // 'l' from the playlist editor, you get an "add files to playlist" dialog.
+ // (that sends IDC_PLAYLIST_ADDMP3==1032 to the playlist, which we can't
+ // do from here.)
+ PostMessage(m_hWndWinamp,WM_COMMAND,40029,0);
+ return 0;
+ case 'L':
+ PostMessage(m_hWndWinamp,WM_COMMAND,40187,0);
+ return 0;
+ case 'j':
+ PostMessage(m_hWndWinamp,WM_COMMAND,40194,0);
+ return 0;
+ }
+
+ return 0;//DefWindowProc(hWnd,uMsg,wParam,lParam);
+ }
+ break; // end case WM_CHAR
+
+ case WM_KEYUP:
+
+ // allow the plugin to override any keys:
+ if (MyWindowProc(hWnd, uMsg, wParam, lParam) == 0)
+ return 0;
+
+ /*
+ switch(wParam)
+ {
+ case VK_SOMETHING:
+ ...
+ break;
+ }
+ */
+
+ return 0;
+ break;
+
+ case WM_KEYDOWN:
+ if (m_show_playlist)
+ {
+ switch (wParam)
+ {
+ case VK_ESCAPE:
+ if(m_show_playlist)
+ TogglePlaylist();
+ //m_show_playlist = 0;
+ return 0;
+
+ case VK_UP:
+ {
+ int nRepeat = lParam & 0xFFFF;
+ if (GetKeyState(VK_SHIFT) & mask)
+ m_playlist_pos -= 10*nRepeat;
+ else
+ m_playlist_pos -= nRepeat;
+ }
+ return 0;
+
+ case VK_DOWN:
+ {
+ int nRepeat = lParam & 0xFFFF;
+ if (GetKeyState(VK_SHIFT) & mask)
+ m_playlist_pos += 10*nRepeat;
+ else
+ m_playlist_pos += nRepeat;
+ }
+ return 0;
+
+ case VK_HOME:
+ m_playlist_pos = 0;
+ return 0;
+
+ case VK_END:
+ m_playlist_pos = SendMessage(m_hWndWinamp,WM_USER, 0, 124) - 1;
+ return 0;
+
+ case VK_PRIOR:
+ if (GetKeyState(VK_SHIFT) & mask)
+ m_playlist_pageups += 10;
+ else
+ m_playlist_pageups++;
+ return 0;
+
+ case VK_NEXT:
+ if (GetKeyState(VK_SHIFT) & mask)
+ m_playlist_pageups -= 10;
+ else
+ m_playlist_pageups--;
+ return 0;
+
+ case VK_RETURN:
+ SendMessage(m_hWndWinamp,WM_USER, m_playlist_pos, 121); // set sel
+ SendMessage(m_hWndWinamp,WM_COMMAND, 40045, 0); // play it
+ return 0;
+ }
+ }
+
+ // allow the plugin to override any keys:
+ if (MyWindowProc(hWnd, uMsg, wParam, lParam) == 0)
+ return 0;
+
+ switch (wParam)
+ {
+ case VK_F1:
+ m_show_press_f1_msg = 0;
+ ToggleHelp();
+ return 0;
+
+ case VK_ESCAPE:
+ if (m_show_help)
+ ToggleHelp();
+ else
+ {
+ if (m_screenmode == FAKE_FULLSCREEN || m_screenmode == FULLSCREEN)
+ {
+ ToggleFullScreen();
+ }
+ else if (m_screenmode == DESKTOP)
+ {
+ ToggleDesktop();
+ }
+ // exit the program on escape
+ //m_exiting = 1;
+ //PostMessage(hWnd, WM_CLOSE, 0, 0);
+ }
+ return 0;
+
+ case VK_UP:
+ // increase volume
+ {
+ int nRepeat = lParam & 0xFFFF;
+ for (i=0; i<nRepeat*2; i++) PostMessage(m_hWndWinamp,WM_COMMAND,40058,0);
+ }
+ return 0;
+
+ case VK_DOWN:
+ // decrease volume
+ {
+ int nRepeat = lParam & 0xFFFF;
+ for (i=0; i<nRepeat*2; i++) PostMessage(m_hWndWinamp,WM_COMMAND,40059,0);
+ }
+ return 0;
+
+ case VK_LEFT:
+ case VK_RIGHT:
+ {
+ bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0;
+ int cmd = (wParam == VK_LEFT) ? 40144 : 40148;
+ int nRepeat = lParam & 0xFFFF;
+ int reps = (bShiftHeldDown) ? 6*nRepeat : 1*nRepeat;
+
+ for (int i=0; i<reps; i++)
+ PostMessage(m_hWndWinamp,WM_COMMAND,cmd,0);
+ }
+ return 0;
+ default:
+ // pass CTRL+A thru CTRL+Z, and also CTRL+TAB, to winamp, *if we're in windowed mode* and using an embedded window.
+ // be careful though; uppercase chars come both here AND to WM_CHAR handler,
+ // so we have to eat some of them here, to avoid them from acting twice.
+ if (m_screenmode==WINDOWED && m_lpDX && m_lpDX->m_current_mode.m_skin)
+ {
+ if (bCtrlHeldDown && ((wParam >= 'A' && wParam <= 'Z') || wParam==VK_TAB))
+ {
+ PostMessage(m_hWndWinamp, uMsg, wParam, lParam);
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+ return 0;
+ break;
+ }
+
+ return MyWindowProc(hWnd, uMsg, wParam, lParam);//DefWindowProc(hWnd, uMsg, wParam, lParam);
+ //return 0L;
+}
+
+LRESULT CALLBACK CPluginShell::DesktopWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
+ if (p)
+ return p->PluginShellDesktopWndProc(hWnd, uMsg, wParam, lParam);
+ else
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+LRESULT CPluginShell::PluginShellDesktopWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
+{
+ //#ifdef _DEBUG
+ // OutputDebugMessage("kbfocus", hWnd, uMsg, wParam, lParam);
+ //#endif
+
+ switch (uMsg)
+ {
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_CHAR:
+ case WM_SYSCHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ //PostMessage(GetPluginWindow(), uMsg, wParam, lParam);
+ PluginShellWindowProc(GetPluginWindow(), uMsg, wParam, lParam);
+ return 0;
+ break;
+ }
+
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+void CPluginShell::AlignWaves()
+{
+ // align waves, using recursive (mipmap-style) least-error matching
+ // note: NUM_WAVEFORM_SAMPLES must be between 32 and 576.
+
+ int align_offset[2] = { 0, 0 };
+
+#if (NUM_WAVEFORM_SAMPLES < 576) // [don't let this code bloat our DLL size if it's not going to be used]
+
+ int nSamples = NUM_WAVEFORM_SAMPLES;
+
+#define MAX_OCTAVES 10
+
+ int octaves = (int)floorf(logf((float)(576-nSamples))/logf(2.0f));
+ if (octaves < 4)
+ return;
+ if (octaves > MAX_OCTAVES)
+ octaves = MAX_OCTAVES;
+
+ for (int ch=0; ch<2; ch++)
+ {
+ // only worry about matching the lower 'nSamples' samples
+ float temp_new[MAX_OCTAVES][576];
+ float temp_old[MAX_OCTAVES][576];
+ static float temp_weight[MAX_OCTAVES][576];
+ static int first_nonzero_weight[MAX_OCTAVES];
+ static int last_nonzero_weight[MAX_OCTAVES];
+ int spls[MAX_OCTAVES];
+ int space[MAX_OCTAVES];
+
+ memcpy(temp_new[0], m_sound.fWaveform[ch], sizeof(float)*576);
+ memcpy(temp_old[0], &m_oldwave[ch][m_prev_align_offset[ch]], sizeof(float)*nSamples);
+ spls[0] = 576;
+ space[0] = 576 - nSamples;
+
+ // potential optimization: could reuse (instead of recompute) mip levels for m_oldwave[2][]?
+ int octave = 0;
+ for (octave=1; octave<octaves; octave++)
+ {
+ spls[octave] = spls[octave-1]/2;
+ space[octave] = space[octave-1]/2;
+ for (int n=0; n<spls[octave]; n++)
+ {
+ temp_new[octave][n] = 0.5f*(temp_new[octave-1][n*2] + temp_new[octave-1][n*2+1]);
+ temp_old[octave][n] = 0.5f*(temp_old[octave-1][n*2] + temp_old[octave-1][n*2+1]);
+ }
+ }
+
+ if (!m_align_weights_ready)
+ {
+ m_align_weights_ready = 1;
+ for (octave=0; octave<octaves; octave++)
+ {
+ int compare_samples = spls[octave] - space[octave];
+ int n = 0;
+ for (n=0; n<compare_samples; n++)
+ {
+ // start with pyramid-shaped pdf, from 0..1..0
+ if (n < compare_samples/2)
+ temp_weight[octave][n] = n*2/(float)compare_samples;
+ else
+ temp_weight[octave][n] = (compare_samples-1 - n)*2/(float)compare_samples;
+
+ // TWEAK how much the center matters, vs. the edges:
+ temp_weight[octave][n] = (temp_weight[octave][n] - 0.8f)*5.0f + 0.8f;
+
+ // clip:
+ if (temp_weight[octave][n]>1) temp_weight[octave][n] = 1;
+ if (temp_weight[octave][n]<0) temp_weight[octave][n] = 0;
+ }
+
+ n = 0;
+ while (temp_weight[octave][n] == 0 && n < compare_samples)
+ n++;
+ first_nonzero_weight[octave] = n;
+
+ n = compare_samples-1;
+ while (temp_weight[octave][n] == 0 && n >= 0)
+ n--;
+ last_nonzero_weight[octave] = n;
+ }
+ }
+
+ int n1 = 0;
+ int n2 = space[octaves-1];
+ for (octave = octaves-1; octave>=0; octave--)
+ {
+ // for example:
+ // space[octave] == 4
+ // spls[octave] == 36
+ // (so we test 32 samples, w/4 offsets)
+ int compare_samples = spls[octave]-space[octave];
+
+ int lowest_err_offset = -1;
+ float lowest_err_amount = 0;
+ for (int n=n1; n<n2; n++)
+ {
+ float err_sum = 0;
+ //for (int i=0; i<compare_samples; i++)
+ for (int i=first_nonzero_weight[octave]; i<=last_nonzero_weight[octave]; i++)
+ {
+ float x = (temp_new[octave][i+n] - temp_old[octave][i]) * temp_weight[octave][i];
+ if (x>0)
+ err_sum += x;
+ else
+ err_sum -= x;
+ }
+
+ if (lowest_err_offset == -1 || err_sum < lowest_err_amount)
+ {
+ lowest_err_offset = n;
+ lowest_err_amount = err_sum;
+ }
+ }
+
+ // now use 'lowest_err_offset' to guide bounds of search in next octave:
+ // space[octave] == 8
+ // spls[octave] == 72
+ // -say 'lowest_err_offset' was 2
+ // -that corresponds to samples 4 & 5 of the next octave
+ // -also, expand about this by 2 samples? YES.
+ // (so we'd test 64 samples, w/8->4 offsets)
+ if (octave > 0)
+ {
+ n1 = lowest_err_offset*2 -1;
+ n2 = lowest_err_offset*2+2+1;
+ if (n1 < 0) n1=0;
+ if (n2 > space[octave-1]) n2 = space[octave-1];
+ }
+ else
+ align_offset[ch] = lowest_err_offset;
+ }
+ }
+#endif
+ memcpy(m_oldwave[0], m_sound.fWaveform[0], sizeof(float)*576);
+ memcpy(m_oldwave[1], m_sound.fWaveform[1], sizeof(float)*576);
+ m_prev_align_offset[0] = align_offset[0];
+ m_prev_align_offset[1] = align_offset[1];
+
+ // finally, apply the results: modify m_sound.fWaveform[2][0..576]
+ // by scooting the aligned samples so that they start at m_sound.fWaveform[2][0].
+ for (int ch=0; ch<2; ch++)
+ if (align_offset[ch]>0)
+ {
+ for (int i=0; i<nSamples; i++)
+ m_sound.fWaveform[ch][i] = m_sound.fWaveform[ch][i+align_offset[ch]];
+ // zero the rest out, so it's visually evident that these samples are now bogus:
+ memset(&m_sound.fWaveform[ch][nSamples], 0, (576-nSamples)*sizeof(float));
+ }
+}
+
+LRESULT CALLBACK CPluginShell::VJModeWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CPluginShell* p = (CPluginShell*)GetWindowLongPtr(hWnd,GWLP_USERDATA);
+ if (p)
+ return p->PluginShellVJModeWndProc(hWnd, uMsg, wParam, lParam);
+ else
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+LRESULT CPluginShell::PluginShellVJModeWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+#ifdef _DEBUG
+ if (message != WM_MOUSEMOVE &&
+ message != WM_NCHITTEST &&
+ message != WM_SETCURSOR &&
+ message != WM_COPYDATA &&
+ message != WM_USER)
+ {
+ char caption[256] = "VJWndProc: frame 0, ";
+ if (m_frame > 0)
+ {
+ float time = m_time;
+ int hours = (int)(time/3600);
+ time -= hours*3600;
+ int minutes = (int)(time/60);
+ time -= minutes*60;
+ int seconds = (int)time;
+ time -= seconds;
+ int dsec = (int)(time*100);
+ sprintf(caption, "VJWndProc: frame %d, t=%dh:%02dm:%02d.%02ds, ", m_frame, hours, minutes, seconds, dsec);
+ }
+ OutputDebugMessage(caption, hwnd, message, wParam, lParam);
+ }
+#endif
+
+ switch (message)
+ {
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_CHAR:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_SYSCHAR:
+ // pass keystrokes on to plugin!
+ return PluginShellWindowProc(GetPluginWindow(),message,wParam,lParam);
+
+ case WM_ERASEBKGND:
+ // Repaint window when song is paused and image needs to be repainted:
+ if (SendMessage(m_hWndWinamp,WM_USER,0,104)!=1 && m_vjd3d9_device && GetFrame() > 0) // WM_USER/104 return codes: 1=playing, 3=paused, other=stopped
+ {
+ m_vjd3d9_device->Present(NULL,NULL,NULL,NULL);
+ return 0;
+ }
+ break;
+
+ /*
+ case WM_WINDOWPOSCHANGING:
+ if (m_screenmode == DESKTOP)
+ {
+ LPWINDOWPOS pwp = (LPWINDOWPOS)lParam;
+ if (pwp)
+ pwp->flags |= SWP_NOOWNERZORDER | SWP_NOZORDER;
+ }
+ break;
+
+ case WM_ACTIVATEAPP:
+ // *Very Important Handler!*
+ // -Without this code, the app would not work properly when running in true
+ // fullscreen mode on multiple monitors; it would auto-minimize whenever the
+ // user clicked on a window in another display.
+ if (wParam == 1 &&
+ m_screenmode == DESKTOP &&
+ m_frame > 0 &&
+ !m_exiting
+ )
+ {
+ return 0;
+ }
+ break;
+
+ /*
+ case WM_NCACTIVATE:
+ // *Very Important Handler!*
+ // -Without this code, the app would not work properly when running in true
+ // fullscreen mode on multiple monitors; it would auto-minimize whenever the
+ // user clicked on a window in another display.
+ // (NOTE: main window also handles this message this way)
+ if (wParam == 0 &&
+ m_screenmode == FULLSCREEN &&
+ m_frame > 0 &&
+ !m_exiting &&
+ m_lpDX &&
+ m_lpDX->m_ready
+ && m_lpDX->m_lpD3D &&
+ m_lpDX->m_lpD3D->GetAdapterCount() > 1
+ )
+ {
+ return 0;
+ }
+ break;
+ */
+
+ /*
+ case WM_ACTIVATEAPP:
+ if (wParam == 1 &&
+ m_screenmode == DESKTOP &&
+ m_frame > 0 &&
+ !m_exiting &&
+ m_vjd3d9_device
+ )
+ {
+ return 0;
+ }
+ break;
+ */
+
+ /*
+ case WM_WINDOWPOSCHANGING:
+ if (
+ m_screenmode == DESKTOP
+ && (!m_force_accept_WM_WINDOWPOSCHANGING)
+ && m_lpDX && m_lpDX->m_ready
+ )
+ {
+ // unless we requested it ourselves or it's init time,
+ // prevent the fake desktop window from moving around
+ // in the Z order! (i.e., keep it on the bottom)
+
+ // without this code, when you click on the 'real' desktop
+ // in a multimon setup, any windows that are overtop of the
+ // 'fake' desktop will flash, since they'll be covered
+ // up by the fake desktop window (but then shown again on
+ // the next frame, when we detect that the fake desktop
+ // window isn't on bottom & send it back to the bottom).
+
+ LPWINDOWPOS pwp = (LPWINDOWPOS)lParam;
+ if (pwp)
+ pwp->flags |= SWP_NOOWNERZORDER | SWP_NOZORDER;
+ }
+ break;
+ */
+
+ case WM_CLOSE:
+ // if they close the VJ window (by some means other than ESC key),
+ // this will make the graphics window close, too.
+ m_exiting = 1;
+ if (GetPluginWindow())
+ PostMessage(GetPluginWindow(), WM_CLOSE, 0, 0);
+ break;
+
+ case WM_GETMINMAXINFO:
+ {
+ // don't let the window get too small
+ MINMAXINFO* p = (MINMAXINFO*)lParam;
+ if (p->ptMinTrackSize.x < 64)
+ p->ptMinTrackSize.x = 64;
+ p->ptMinTrackSize.y = p->ptMinTrackSize.x*3/4;
+ }
+ return 0;
+
+ case WM_SIZE:
+ // clear or set activity flag to reflect focus
+ if (m_vjd3d9_device && !m_resizing_textwnd)
+ {
+ m_hidden_textwnd = (SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam) ? TRUE : FALSE;
+
+ if (SIZE_MAXIMIZED==wParam || SIZE_RESTORED==wParam) // the window has been maximized or restored
+ OnUserResizeTextWindow();
+ }
+ break;
+
+ case WM_ENTERSIZEMOVE:
+ m_resizing_textwnd = 1;
+ break;
+
+ case WM_EXITSIZEMOVE:
+ if (m_vjd3d9_device)
+ OnUserResizeTextWindow();
+ m_resizing_textwnd = 0;
+ break;
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/pluginshell.h b/Src/Plugins/Visualization/vis_milk2/pluginshell.h
new file mode 100644
index 00000000..a7437374
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/pluginshell.h
@@ -0,0 +1,371 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_PLUGIN_SHELL_H__
+#define __NULLSOFT_DX9_PLUGIN_SHELL_H__ 1
+
+#include "shell_defines.h"
+#include "dxcontext.h"
+#include "fft.h"
+#include "defines.h"
+#include "textmgr.h"
+
+#include "icon_t.h"
+#include <vector>
+
+#define TIME_HIST_SLOTS 128 // # of slots used if fps > 60. half this many if fps==30.
+#define MAX_SONGS_PER_PAGE 40
+
+typedef struct
+{
+ wchar_t szFace[256];
+ int nSize; // size requested @ font creation time
+ int bBold;
+ int bItalic;
+ int bAntiAliased;
+} td_fontinfo;
+
+typedef struct
+{
+ float imm[2][3]; // bass, mids, treble, no damping, for each channel (long-term average is 1)
+ float avg[2][3]; // bass, mids, treble, some damping, for each channel (long-term average is 1)
+ float med_avg[2][3]; // bass, mids, treble, more damping, for each channel (long-term average is 1)
+ float long_avg[2][3]; // bass, mids, treble, heavy damping, for each channel (long-term average is 1)
+ float infinite_avg[2][3]; // bass, mids, treble: winamp's average output levels. (1)
+ float fWaveform[2][576]; // Not all 576 are valid! - only NUM_WAVEFORM_SAMPLES samples are valid for each channel (note: NUM_WAVEFORM_SAMPLES is declared in shell_defines.h)
+ float fSpectrum[2][NUM_FREQUENCIES]; // NUM_FREQUENCIES samples for each channel (note: NUM_FREQUENCIES is declared in shell_defines.h)
+} td_soundinfo; // ...range is 0 Hz to 22050 Hz, evenly spaced.
+
+class CPluginShell
+{
+public:
+ // GET METHODS
+ // ------------------------------------------------------------
+ int GetFrame(); // returns current frame # (starts at zero)
+ float GetTime(); // returns current animation time (in seconds) (starts at zero) (updated once per frame)
+ float GetFps(); // returns current estimate of framerate (frames per second)
+ eScrMode GetScreenMode(); // returns WINDOWED, FULLSCREEN, FAKE_FULLSCREEN, DESKTOP, or NOT_YET_KNOWN (if called before or during OverrideDefaults()).
+ HWND GetWinampWindow(); // returns handle to Winamp main window
+ HINSTANCE GetInstance(); // returns handle to the plugin DLL module; used for things like loading resources (dialogs, bitmaps, icons...) that are built into the plugin.
+ wchar_t* GetPluginsDirPath(); // usually returns 'c:\\program files\\winamp\\plugins\\'
+ wchar_t* GetConfigIniFile(); // usually returns 'c:\\program files\\winamp\\plugins\\something.ini' - filename is determined from identifiers in 'defines.h'
+ char* GetConfigIniFileA();
+protected:
+
+ // GET METHODS THAT ONLY WORK ONCE DIRECTX IS READY
+ // ------------------------------------------------------------
+ // The following 'Get' methods are only available after DirectX has been initialized.
+ // If you call these from OverrideDefaults, MyPreInitialize, or MyReadConfig,
+ // they will return NULL (zero).
+ // ------------------------------------------------------------
+ HWND GetPluginWindow(); // returns handle to the plugin window. NOT persistent; can change!
+ int GetWidth(); // returns width of plugin window interior, in pixels. Note: in windowed mode, this is a fudged, larger, aligned value, and on final display, it gets cropped.
+ int GetHeight(); // returns height of plugin window interior, in pixels. Note: in windowed mode, this is a fudged, larger, aligned value, and on final display, it gets cropped.
+ int GetBitDepth(); // returns 8, 16, 24 (rare), or 32
+ LPDIRECT3DDEVICE9 GetDevice(); // returns a pointer to the DirectX 8 Device. NOT persistent; can change!
+ D3DCAPS9* GetCaps(); // returns a pointer to the D3DCAPS9 structer for the device. NOT persistent; can change.
+ D3DFORMAT GetBackBufFormat(); // returns the pixelformat of the back buffer (probably D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_A4R4G4B4, D3DFMT_R3G3B2, D3DFMT_A8R3G3B2, D3DFMT_X4R4G4B4, or D3DFMT_UNKNOWN)
+ D3DFORMAT GetBackBufZFormat(); // returns the pixelformat of the back buffer's Z buffer (probably D3DFMT_D16_LOCKABLE, D3DFMT_D32, D3DFMT_D15S1, D3DFMT_D24S8, D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D24X4S4, or D3DFMT_UNKNOWN)
+ char* GetDriverFilename(); // returns a text string with the filename of the current display adapter driver, such as "nv4_disp.dll"
+ char* GetDriverDescription(); // returns a text string describing the current display adapter, such as "NVIDIA GeForce4 Ti 4200"
+
+ // FONTS & TEXT
+ // ------------------------------------------------------------
+public:
+ LPD3DXFONT GetFont(eFontIndex idx); // returns a D3DX font handle for drawing text; see shell_defines.h for the definition of the 'eFontIndex' enum.
+ int GetFontHeight(eFontIndex idx); // returns the height of the font, in pixels; see shell_defines.h for the definition of the 'eFontIndex' enum.
+ CTextManager m_text;
+protected:
+
+ // MISC
+ // ------------------------------------------------------------
+ td_soundinfo m_sound; // a structure always containing the most recent sound analysis information; defined in pluginshell.h.
+ void SuggestHowToFreeSomeMem(); // gives the user a 'smart' messagebox that suggests how they can free up some video memory.
+
+ // CONFIG PANEL SETTINGS
+ // ------------------------------------------------------------
+ // *** only read/write these values during CPlugin::OverrideDefaults! ***
+ int m_start_fullscreen; // 0 or 1
+ int m_start_desktop; // 0 or 1
+ int m_fake_fullscreen_mode; // 0 or 1
+ int m_max_fps_fs; // 1-120, or 0 for 'unlimited'
+ int m_max_fps_dm; // 1-120, or 0 for 'unlimited'
+ int m_max_fps_w; // 1-120, or 0 for 'unlimited'
+ int m_show_press_f1_msg; // 0 or 1
+ int m_allow_page_tearing_w; // 0 or 1
+ int m_allow_page_tearing_fs; // 0 or 1
+ int m_allow_page_tearing_dm; // 0 or 1
+ int m_minimize_winamp; // 0 or 1
+ int m_desktop_show_icons; // 0 or 1
+ int m_desktop_textlabel_boxes; // 0 or 1
+ int m_desktop_manual_icon_scoot; // 0 or 1
+ int m_desktop_555_fix; // 0 = 555, 1 = 565, 2 = 888
+ int m_dualhead_horz; // 0 = both, 1 = left, 2 = right
+ int m_dualhead_vert; // 0 = both, 1 = top, 2 = bottom
+ int m_save_cpu; // 0 or 1
+ int m_skin; // 0 or 1
+ int m_fix_slow_text; // 0 or 1
+ td_fontinfo m_fontinfo[NUM_BASIC_FONTS + NUM_EXTRA_FONTS];
+ D3DDISPLAYMODE m_disp_mode_fs; // a D3DDISPLAYMODE struct that specifies the width, height, refresh rate, and color format to use when the plugin goes fullscreen.
+
+ // PURE VIRTUAL FUNCTIONS (...must be implemented by derived classes)
+ // ------------------------------------------------------------
+ virtual void OverrideDefaults() = 0;
+ virtual void MyPreInitialize() = 0;
+ virtual void MyReadConfig() = 0;
+ virtual void MyWriteConfig() = 0;
+ virtual int AllocateMyNonDx9Stuff() = 0;
+ virtual void CleanUpMyNonDx9Stuff() = 0;
+ virtual int AllocateMyDX9Stuff() = 0;
+ virtual void CleanUpMyDX9Stuff(int final_cleanup) = 0;
+ virtual void MyRenderFn(int redraw) = 0;
+ virtual void MyRenderUI(int *upper_left_corner_y, int *upper_right_corner_y, int *lower_left_corner_y, int *lower_right_corner_y, int xL, int xR) = 0;
+ virtual LRESULT MyWindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam) = 0;
+ virtual BOOL MyConfigTabProc(int nPage, HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) = 0;
+ virtual void OnAltK() { }; // doesn't *have* to be implemented
+
+//=====================================================================================================================
+private:
+
+ // GENERAL PRIVATE STUFF
+ eScrMode m_screenmode; // // WINDOWED, FULLSCREEN, or FAKE_FULLSCREEN (i.e. running in a full-screen-sized window)
+ int m_frame; // current frame #, starting at zero
+ float m_time; // current animation time in seconds; starts at zero.
+ float m_fps; // current estimate of frames per second
+ HWND m_hWndWinamp; // handle to Winamp window
+ HINSTANCE m_hInstance; // handle to application instance
+ DXContext* m_lpDX; // pointer to DXContext object
+ wchar_t m_szPluginsDirPath[MAX_PATH]; // usually 'c:\\program files\\winamp\\plugins\\'
+ wchar_t m_szConfigIniFile[MAX_PATH]; // usually 'c:\\program files\\winamp\\plugins\\something.ini' - filename is determined from identifiers in 'defines.h'
+ char m_szConfigIniFileA[MAX_PATH]; // usually 'c:\\program files\\winamp\\plugins\\something.ini' - filename is determined from identifiers in 'defines.h'
+
+ // FONTS
+ IDirect3DTexture9* m_lpDDSText;
+ LPD3DXFONT m_d3dx_font[NUM_BASIC_FONTS + NUM_EXTRA_FONTS];
+ LPD3DXFONT m_d3dx_desktop_font;
+ HFONT m_font[NUM_BASIC_FONTS + NUM_EXTRA_FONTS];
+ HFONT m_font_desktop;
+
+ // PRIVATE CONFIG PANEL SETTINGS
+ D3DMULTISAMPLE_TYPE m_multisample_fullscreen;
+ D3DMULTISAMPLE_TYPE m_multisample_desktop;
+ D3DMULTISAMPLE_TYPE m_multisample_windowed;
+ GUID m_adapter_guid_fullscreen;
+ GUID m_adapter_guid_desktop;
+ GUID m_adapter_guid_windowed;
+ char m_adapter_devicename_fullscreen[256]; // these are also necessary sometimes,
+ char m_adapter_devicename_desktop[256]; // for example, when a laptop (single adapter)
+ char m_adapter_devicename_windowed[256]; // drives two displays! DeviceName will be \\.\Display1 and \\.\Display2 or something.
+
+ // PRIVATE RUNTIME SETTINGS
+ int m_lost_focus; // ~mostly for fullscreen mode
+ int m_hidden; // ~mostly for windowed mode
+ int m_resizing; // ~mostly for windowed mode
+ int m_show_help;
+ int m_show_playlist;
+ int m_playlist_pos; // current selection on (plugin's) playlist menu
+ int m_playlist_pageups; // can be + or -
+ int m_playlist_top_idx; // used to track when our little playlist cache (m_playlist) needs updated.
+ int m_playlist_btm_idx; // used to track when our little playlist cache (m_playlist) needs updated.
+ int m_playlist_width_pixels; // considered invalid whenever 'm_playlist_top_idx' is -1.
+ wchar_t m_playlist[MAX_SONGS_PER_PAGE][256]; // considered invalid whenever 'm_playlist_top_idx' is -1.
+ int m_exiting;
+ int m_upper_left_corner_y;
+ int m_lower_left_corner_y;
+ int m_upper_right_corner_y;
+ int m_lower_right_corner_y;
+ int m_left_edge;
+ int m_right_edge;
+ int m_force_accept_WM_WINDOWPOSCHANGING;
+
+ // PRIVATE - GDI STUFF
+ HMENU m_main_menu;
+ HMENU m_context_menu;
+
+ // PRIVATE - DESKTOP MODE STUFF
+ //typedef std::list<icon_t> IconList;
+ typedef std::vector<icon_t> IconList;
+ IconList m_icon_list;
+ IDirect3DTexture9* m_desktop_icons_texture[MAX_ICON_TEXTURES];
+ HWND m_hWndProgMan;
+ HWND m_hWndDesktop;
+ HWND m_hWndDesktopListView;
+ char m_szDesktopFolder[MAX_PATH]; // *without* the final backslash
+ int m_desktop_icon_size;
+ int m_desktop_dragging; // '1' when user is dragging icons around
+ int m_desktop_box; // '1' when user is drawing a box
+ BYTE m_desktop_drag_pidl[1024]; // cast this to ITEMIDLIST
+ POINT m_desktop_drag_startpos; // applies to dragging or box-drawing
+ POINT m_desktop_drag_curpos; // applies to dragging or box-drawing
+ int m_desktop_wc_registered;
+ DWORD m_desktop_bk_color;
+ DWORD m_desktop_text_color;
+ DWORD m_desktop_sel_color;
+ DWORD m_desktop_sel_text_color;
+ int m_desktop_icon_state; // 0=uninit, 1=total refresh in progress, 2=ready, 3=update in progress
+ int m_desktop_icon_count;
+ int m_desktop_icon_update_frame;
+ CRITICAL_SECTION m_desktop_cs;
+ int m_desktop_icons_disabled;
+ int m_vms_desktop_loaded;
+ int m_desktop_hook_set;
+ bool m_bClearVJWindow;
+
+ // PRIVATE - MORE TIMEKEEPING
+ protected:
+ double m_last_raw_time;
+ LARGE_INTEGER m_high_perf_timer_freq; // 0 if high-precision timer not available
+ private:
+ float m_time_hist[TIME_HIST_SLOTS]; // cumulative
+ int m_time_hist_pos;
+ LARGE_INTEGER m_prev_end_of_frame;
+
+ // PRIVATE AUDIO PROCESSING DATA
+ FFT m_fftobj;
+ float m_oldwave[2][576]; // for wave alignment
+ int m_prev_align_offset[2]; // for wave alignment
+ int m_align_weights_ready;
+
+public:
+ CPluginShell();
+ ~CPluginShell();
+
+ // called by vis.cpp, on behalf of Winamp:
+ int PluginPreInitialize(HWND hWinampWnd, HINSTANCE hWinampInstance);
+ int PluginInitialize();
+ int PluginRender(unsigned char *pWaveL, unsigned char *pWaveR);
+ void PluginQuit();
+
+ void ToggleHelp();
+ void TogglePlaylist();
+
+ void READ_FONT(int n);
+ void WRITE_FONT(int n);
+
+ // config panel / windows messaging processes:
+ static LRESULT CALLBACK WindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
+ static LRESULT CALLBACK DesktopWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
+ static LRESULT CALLBACK VJModeWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
+ static INT_PTR CALLBACK ConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ static INT_PTR CALLBACK TabCtrlProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ static INT_PTR CALLBACK FontDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ static INT_PTR CALLBACK DesktopOptionsDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ static INT_PTR CALLBACK DualheadDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+
+private:
+ void PushWindowToJustBeforeDesktop(HWND h);
+ void DrawAndDisplay(int redraw);
+ void ReadConfig();
+ void WriteConfig();
+ void DoTime();
+ void AnalyzeNewSound(unsigned char *pWaveL, unsigned char *pWaveR);
+ void AlignWaves();
+ int InitDirectX();
+ void CleanUpDirectX();
+ int InitGDIStuff();
+ void CleanUpGDIStuff();
+ int AllocateDX9Stuff();
+ void CleanUpDX9Stuff(int final_cleanup);
+ int InitNondx9Stuff();
+ void CleanUpNondx9Stuff();
+ int InitVJStuff(RECT* pClientRect=NULL);
+ void CleanUpVJStuff();
+ int AllocateFonts(IDirect3DDevice9 *pDevice);
+ void CleanUpFonts();
+ void AllocateTextSurface();
+ void ToggleDesktop();
+ void OnUserResizeWindow();
+ void OnUserResizeTextWindow();
+ void PrepareFor2DDrawing_B(IDirect3DDevice9 *pDevice, int w, int h);
+ void RenderBuiltInTextMsgs();
+ int GetCanvasMarginX(); // returns the # of pixels that exist on the canvas, on each side, that the user will never see. Mainly here for windowed mode, where sometimes, up to 15 pixels get cropped at edges of the screen.
+ int GetCanvasMarginY(); // returns the # of pixels that exist on the canvas, on each side, that the user will never see. Mainly here for windowed mode, where sometimes, up to 15 pixels get cropped at edges of the screen.
+public:
+ void ToggleFullScreen();
+ void DrawDarkTranslucentBox(RECT* pr);
+protected:
+ void RenderPlaylist();
+ void StuffParams(DXCONTEXT_PARAMS *pParams);
+ void EnforceMaxFPS();
+
+ // DESKTOP MODE FUNCTIONS (found in desktop_mode.cpp)
+ int InitDesktopMode();
+ void CleanUpDesktopMode();
+ int CreateDesktopIconTexture(IDirect3DTexture9** ppTex);
+ void DeselectDesktop();
+ void UpdateDesktopBitmaps();
+ int StuffIconBitmaps(int iStartIconIdx, int iTexNum, int *show_msgs);
+ void RenderDesktop();
+
+ // SEPARATE TEXT WINDOW (FOR VJ MODE)
+ int m_vj_mode;
+ int m_hidden_textwnd;
+ int m_resizing_textwnd;
+ protected:
+ HWND m_hTextWnd;
+ private:
+ int m_nTextWndWidth;
+ int m_nTextWndHeight;
+ bool m_bTextWindowClassRegistered;
+ LPDIRECT3D9 m_vjd3d9;
+ LPDIRECT3DDEVICE9 m_vjd3d9_device;
+ //HDC m_memDC; // memory device context
+ //HBITMAP m_memBM, m_oldBM;
+ //HBRUSH m_hBlackBrush;
+
+ // WINDOWPROC FUNCTIONS
+ LRESULT PluginShellWindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam); // in windowproc.cpp
+ LRESULT PluginShellDesktopWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
+ LRESULT PluginShellVJModeWndProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam);
+
+ // CONFIG PANEL FUNCTIONS:
+ BOOL PluginShellConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ BOOL PluginShellConfigTab1Proc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ BOOL PluginShellFontDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ BOOL PluginShellDesktopOptionsDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ BOOL PluginShellDualheadDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+ bool InitConfig(HWND hDialogWnd);
+ void EndConfig();
+ void UpdateAdapters(int screenmode);
+ void UpdateFSAdapterDispModes(); // (fullscreen only)
+ void UpdateDispModeMultiSampling(int screenmode);
+ void UpdateMaxFps(int screenmode);
+ int GetCurrentlySelectedAdapter(int screenmode);
+ void SaveDisplayMode();
+ void SaveMultiSamp(int screenmode);
+ void SaveAdapter(int screenmode);
+ void SaveMaxFps(int screenmode);
+ void OnTabChanged(int nNewTab);
+ LPDIRECT3DDEVICE9 GetTextDevice() { return (m_vjd3d9_device) ? m_vjd3d9_device : m_lpDX->m_lpDevice; }
+
+ // CHANGES:
+ friend class CShaderParams;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/resource.h b/Src/Plugins/Visualization/vis_milk2/resource.h
new file mode 100644
index 00000000..fccefb5c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/resource.h
@@ -0,0 +1,877 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by plugin.rc
+//
+#define IDS_ABOUT_STRING 1
+#define IDS_SZ_MENU_NAV_TOOLTIP 2
+#define ID_DOCS 3
+#define IDS_UNTITLED_MENU_ITEM 3
+#define IDLEFT 4
+#define IDS_UNTITLED_MENU 4
+#define ID_WEB 5
+#define IDS_ON 5
+#define IDRIGHT 6
+#define IDS_OFF 6
+#define ID_DEFAULTS 7
+#define IDS_USE_UP_DOWN_ARROW_KEYS 7
+#define ID_MSG 8
+#define IDS_CURRENT_VALUE_OF_X 8
+#define ID_SPRITE 9
+#define IDS_LOAD_FROM_FILE 9
+#define IDS_SAVE_TO_FILE 10
+#define IDS_ENTER_THE_NEW_STRING 11
+#define IDS_MILKDROP_ERROR 14
+#define IDS_MILKDROP_WARNING 19
+#define IDS_ERROR_CREATING_DOUBLE_SIZED_GDI_TITLE_FONT 20
+#define IDS_ERROR_CREATING_DOUBLE_SIZED_D3DX_TITLE_FONT 21
+#define IDS_RATING 23
+#define IDS_DISABLED 24
+#define IDS_ARE_YOU_SURE_YOU_WANT_TO_DELETE_PRESET 26
+#define IDS_PRESET_TO_DELETE 27
+#define IDS_FILE_ALREADY_EXISTS_OVERWRITE_IT 28
+#define IDS_FILE_IN_QUESTION_X_MILK 29
+#define IDS_ERROR_NO_PRESET_FILE_FOUND_IN_X_MILK 30
+#define IDS_LOAD_WHICH_PRESET_PLUS_COMMANDS 31
+#define IDS_PAGE_X_OF_X 32
+#define IDS_LOCKED 33
+#define IDS_ILLEGAL_CHARACTER 37
+#define IDS_STRING_TOO_LONG 38
+#define IDS_DIRECTORY_TO_JUMP_TO 39
+#define IDS_ERROR_IMPORTING_BAD_FILENAME 40
+#define IDS_ERROR_IMPORTING_BAD_FILENAME_OR_NOT_OVERWRITEABLE 41
+#define IDS_INVALID_PATH 42
+#define IDS_ENTER_THE_NEW_NAME_FOR_X 43
+#define IDS_PRESET_ORDER_IS_NOW_X 44
+#define IDS_SEQUENTIAL 45
+#define IDS_RANDOM 46
+#define IDS_SAVE_AS 50
+#define IDS_AUTO 51
+#define IDS_8X6_FAST 52
+#define IDS_16X12_FAST 53
+#define IDS_24X18 54
+#define IDS_32X24 55
+#define IDS_40X30 56
+#define IDS_48X36_DEFAULT 57
+#define IDS_64X48_SLOW 58
+#define IDS_80X60_SLOW 59
+#define IDS_96X72_SLOW 60
+#define IDS_128X96_SLOW 61
+#define IDS_ERROR_IN_SHELLEXECUTE 62
+#define IDS_MESH_SIZE 65
+#define IDS_MESH_SIZE_TEXT 66
+#define IDS_CB_ALWAYS3D 67
+#define IDS_DISABLE_PRESET_RATING 70
+#define IDS_DISABLE_PRESET_RATING_TEXT 71
+#define IDS_CB_NOWARN2 73
+#define IDS_START_WITH_PRESET_LOCK_ON 76
+#define IDS_START_WITH_PRESET_LOCK_ON_TEXT 77
+#define IDS_BRIGHT_SLIDER 78
+#define IDS_CB_AUTOGAMMA 79
+#define IDS_SPRITE 80
+#define IDS_MSG 81
+#define IDS_SONGTITLEANIM_DURATION_TEXT 86
+#define IDS_RAND_TITLE_TEXT 87
+#define IDS_RAND_MSG_TEXT 88
+#define IDS_TITLE_ANIMS_TEXT 89
+#define IDS_BETWEEN_TIME_TEXT 90
+#define IDS_BETWEEN_TIME_RANDOM_TEXT 91
+#define IDS_BLEND_AUTO_TEXT 92
+#define IDS_BLEND_USER_TEXT 93
+#define IDS_HARDCUT_BETWEEN_TIME_TEXT 94
+#define IDS_HARDCUT_LOUDNESS_TEXT 95
+#define IDS_CB_HARDCUTS 96
+#define IDS_EDIT_CURRENT_PRESET 98
+#define IDS_MOTION 99
+#define IDS_DRAWING_CUSTOM_SHAPES 100
+#define IDD_DIALOG1 101
+#define IDD_CONFIG 101
+#define IDS_DRAWING_CUSTOM_WAVES 101
+#define IDD_PROPPAGE_1 102
+#define IDS_DRAWING_SIMPLE_WAVEFORM 102
+#define IDD_PROPPAGE_2 103
+#define IDS_DRAWING_BORDERS_MOTION_VECTORS 103
+#define IDS_POST_PROCESSING_MISC 104
+#define IDS_CUSTOM_WAVE_X 105
+#define IDS_CUSTOM_SHAPE_X 106
+#define IDS_MENU_EDIT_PRESET_INIT_CODE 107
+#define IDS_MENU_EDIT_PRESET_INIT_CODE_TT 108
+#define IDS_MENU_EDIT_PER_FRAME_EQUATIONS 109
+#define IDR_WINDOWED_CONTEXT_MENU 110
+#define IDS_MENU_EDIT_PER_FRAME_EQUATIONS_TT 110
+#define IDS_MENU_WAVE_TYPE 113
+#define IDD_PROPPAGE_3 114
+#define IDS_MENU_WAVE_TYPE_TT 114
+#define IDD_PROPPAGE_4 115
+#define IDS_MENU_SIZE 115
+#define IDD_PROPPAGE_5 116
+#define IDS_MENU_SIZE_TT 116
+#define IDD_PROPPAGE_6 117
+#define IDS_MENU_SMOOTH 117
+#define IDD_PROPPAGE_7 118
+#define IDS_MENU_SMOOTH_TT 118
+#define IDD_PROPPAGE_8 119
+#define IDS_MENU_MYSTERY_PARAMETER 119
+#define IDI_PLUGIN_ICON 120
+#define IDS_MENU_MYSTERY_PARAMETER_TT 120
+#define IDD_FONTDIALOG 121
+#define IDS_MENU_POSITION_X 121
+#define IDD_DESKTOPMODE 122
+#define IDS_MENU_POSITION_X_TT 122
+#define IDD_DUALHEAD 123
+#define IDS_MENU_POSITION_Y 123
+#define IDS_MENU_POSITION_Y_TT 124
+#define IDS_MENU_COLOR_RED 125
+#define IDS_MENU_COLOR_RED_TT 126
+#define IDS_MENU_COLOR_GREEN 127
+#define IDS_MENU_COLOR_GREEN_TT 128
+#define IDR_TEXT1 129
+#define IDS_MENU_COLOR_BLUE 129
+#define IDR_TEXT2 130
+#define IDS_MENU_COLOR_BLUE_TT 130
+#define IDS_MENU_OPACITY 131
+#define IDS_MENU_OPACITY_TT 132
+#define IDS_MENU_USE_DOTS 133
+#define IDS_MENU_USE_DOTS_TT 134
+#define IDS_MENU_DRAW_THICK 135
+#define IDS_MENU_DRAW_THICK_TT 136
+#define IDS_MENU_MODULATE_OPACITY_BY_VOLUME 137
+#define IDS_MENU_MODULATE_OPACITY_BY_VOLUME_TT 138
+#define IDS_MENU_MODULATION_TRANSPARENT_VOLUME 139
+#define IDS_MENU_MODULATION_TRANSPARENT_VOLUME_TT 140
+#define IDS_MENU_MODULATION_OPAQUE_VOLUME 141
+#define IDS_MENU_MODULATION_OPAQUE_VOLUME_TT 142
+#define IDS_MENU_ADDITIVE_DRAWING 143
+#define IDS_MENU_ADDITIVE_DRAWING_TT 144
+#define IDS_MENU_COLOR_BRIGHTENING 145
+#define IDS_MENU_COLOR_BRIGHTENING_TT 146
+#define IDS_MENU_OUTER_BORDER_THICKNESS 147
+#define IDS_MENU_OUTER_BORDER_THICKNESS_TT 148
+#define IDS_MENU_COLOR_RED_OUTER 149
+#define IDS_MENU_COLOR_RED_OUTER_TT 150
+#define IDS_MENU_COLOR_GREEN_OUTER 151
+#define IDS_MENU_COLOR_GREEN_OUTER_TT 152
+#define IDS_MENU_COLOR_BLUE_OUTER 153
+#define IDS_MENU_COLOR_BLUE_OUTER_TT 154
+#define IDS_MENU_OPACITY_OUTER 155
+#define IDS_MENU_OPACITY_OUTER_TT 156
+#define IDS_MENU_INNER_BORDER_THICKNESS 157
+#define IDS_MENU_INNER_BORDER_THICKNESS_TT 160
+#define IDS_MENU_COLOR_RED_INNER_TT 161
+#define IDS_MENU_COLOR_GREEN_INNER_TT 162
+#define IDS_MENU_COLOR_BLUE_INNER_TT 163
+#define IDS_MENU_OPACITY_INNER_TT 164
+#define IDS_MENU_MOTION_VECTOR_OPACITY 165
+#define IDS_MENU_MOTION_VECTOR_OPACITY_TT 167
+#define IDS_MENU_NUM_MOT_VECTORS_X 168
+#define IDS_MENU_NUM_MOT_VECTORS_X_TT 169
+#define IDS_MENU_NUM_MOT_VECTORS_Y 170
+#define IDS_MENU_NUM_MOT_VECTORS_Y_TT 171
+#define IDS_MENU_OFFSET_X 172
+#define IDS_MENU_OFFSET_X_TT 173
+#define IDS_MENU_OFFSET_Y 174
+#define IDS_MENU_OFFSET_Y_TT 175
+#define IDS_MENU_TRAIL_LENGTH 176
+#define IDS_MENU_TRAIL_LENGTH_TT 177
+#define IDS_MENU_COLOR_RED_MOTION_VECTOR_TT 178
+#define IDS_MENU_COLOR_GREEN_MOTION_VECTOR_TT 179
+#define IDS_MENU_COLOR_BLUE_MOTION_VECTOR_TT 180
+#define IDS_MENU_ZOOM_AMOUNT 181
+#define IDS_MENU_ZOOM_AMOUNT_TT 182
+#define IDS_MENU_ZOOM_EXPONENT 183
+#define IDS_MENU_ZOOM_EXPONENT_TT 184
+#define IDS_MENU_WARP_AMOUNT 185
+#define IDS_MENU_WARP_AMOUNT_TT 186
+#define IDS_MENU_WARP_SCALE 187
+#define IDS_MENU_WARP_SCALE_TT 188
+#define IDS_MENU_WARP_SPEED 189
+#define IDS_MENU_WARP_SPEED_TT 190
+#define IDS_MENU_ROTATION_AMOUNT 191
+#define IDS_MENU_ROTATION_AMOUNT_TT 192
+#define IDS_MENU_ROTATION_CENTER_OF_X 193
+#define IDS_MENU_ROTATION_CENTER_OF_X_TT 194
+#define IDS_MENU_ROTATION_CENTER_OF_Y 195
+#define IDS_MENU_ROTATION_CENTER_OF_Y_TT 196
+#define IDS_MENU_TRANSLATION_X 197
+#define IDS_MENU_TRANSLATION_X_TT 198
+#define IDS_MENU_TRANSLATION_Y 199
+#define IDS_MENU_TRANSLATION_Y_TT 200
+#define IDS_MENU_SCALING_X 201
+#define IDS_MENU_SCALING_X_TT 202
+#define IDS_MENU_SCALING_Y 203
+#define IDS_MENU_SCALING_Y_TT 204
+#define IDS_MENU_SUSTAIN_LEVEL 205
+#define IDS_MENU_SUSTAIN_LEVEL_TT 206
+#define IDS_MENU_DARKEN_CENTER 207
+#define IDS_MENU_DARKEN_CENTER_TT 208
+#define IDS_MENU_GAMMA_ADJUSTMENT 209
+#define IDS_MENU_GAMMA_ADJUSTMENT_TT 210
+#define IDS_MENU_HUE_SHADER 211
+#define IDS_MENU_HUE_SHADER_TT 212
+#define IDS_MENU_VIDEO_ECHO_ALPHA 213
+#define IDS_MENU_VIDEO_ECHO_ALPHA_TT 214
+#define IDS_MENU_VIDEO_ECHO_ZOOM 215
+#define IDS_MENU_VIDEO_ECHO_ZOOM_TT 216
+#define IDS_MENU_VIDEO_ECHO_ORIENTATION 217
+#define IDS_MENU_VIDEO_ECHO_ORIENTATION_TT 218
+#define IDS_MENU_TEXTURE_WRAP 219
+#define IDS_MENU_TEXTURE_WRAP_TT 220
+#define IDS_MENU_FILTER_INVERT 223
+#define IDS_MENU_FILTER_INVERT_TT 224
+#define IDS_MENU_FILTER_BRIGHTEN 225
+#define IDS_MENU_FILTER_BRIGHTEN_TT 226
+#define IDS_MENU_FILTER_DARKEN 227
+#define IDS_MENU_FILTER_DARKEN_TT 228
+#define IDS_MENU_FILTER_SOLARIZE 229
+#define IDS_MENU_FILTER_SOLARIZE_TT 230
+#define IDS_MENU_ENABLED 231
+#define IDS_MENU_ENABLED_TT 232
+#define IDS_MENU_NUMBER_OF_SAMPLES 233
+#define IDS_MENU_NUMBER_OF_SAMPLES_TT 234
+#define IDS_MENU_L_R_SEPARATION 235
+#define IDS_MENU_L_R_SEPARATION_TT 236
+#define IDS_MENU_SCALING 237
+#define IDS_MENU_SCALING_TT 238
+#define IDS_MENU_SMOOTHING_TT 239
+#define IDS_MENU_OPACITY_WAVE_TT 240
+#define IDS_MENU_USE_SPECTRUM 241
+#define IDS_MENU_USE_SPECTRUM_TT 242
+#define IDS_MENU_USE_DOTS_WAVE_TT 243
+#define IDS_MENU_DRAW_THICK_WAVE_TT 244
+#define IDS_MENU_ADDITIVE_DRAWING_WAVE_TT 245
+#define IDS_MENU_EXPORT_TO_FILE 246
+#define IDS_MENU_EXPORT_TO_FILE_TT 247
+#define IDS_MENU_IMPORT_FROM_FILE 248
+#define IDS_MENU_IMPORT_FROM_FILE_TT 249
+#define IDS_MENU_EDIT_INIT_CODE 250
+#define IDS_MENU_EDIT_INIT_CODE_TT 251
+#define IDS_MENU_EDIT_PER_FRAME_CODE 252
+#define IDS_MENU_EDIT_PER_FRAME_CODE_TT 253
+#define IDS_MENU_EDIT_PER_POINT_CODE 254
+#define IDS_MENU_EDIT_PER_POINT_CODE_TT 255
+#define IDS_MENU_ENABLED_SHAPE_TT 256
+#define IDS_MENU_NUMBER_OF_SIDES 257
+#define IDS_MENU_NUMBER_OF_SIDES_TT 258
+#define IDS_MENU_DRAW_THICK_SHAPE_TT 259
+#define IDS_MENU_ADDITIVE_DRAWING_SHAPE_TT 260
+#define IDS_MENU_X_POSITION 261
+#define IDS_MENU_X_POSITION_TT 262
+#define IDS_MENU_Y_POSITION 263
+#define IDS_MENU_Y_POSITION_TT 264
+#define IDS_MENU_RADIUS 265
+#define IDS_MENU_RADIUS_TT 266
+#define IDS_MENU_ANGLE 267
+#define IDS_MENU_ANGLE_TT 268
+#define IDS_MENU_TEXTURED 269
+#define IDS_MENU_TEXTURED_TT 270
+#define IDS_MENU_TEXTURE_ZOOM 271
+#define IDS_MENU_TEXTURE_ZOOM_TT 272
+#define IDS_MENU_TEXTURE_ANGLE 273
+#define IDS_MENU_TEXTURE_ANGLE_TT 274
+#define IDS_MENU_INNER_COLOR_RED 275
+#define IDS_MENU_INNER_COLOR_RED_TT 276
+#define IDS_MENU_INNER_COLOR_GREEN 277
+#define IDS_MENU_INNER_COLOR_GREEN_TT 278
+#define IDS_MENU_INNER_COLOR_BLUE 279
+#define IDS_MENU_INNER_COLOR_BLUE_TT 280
+#define IDS_MENU_INNER_OPACITY 281
+#define IDS_MENU_INNER_OPACITY_TT 282
+#define IDS_MENU_OUTER_COLOR_RED 283
+#define IDS_MENU_OUTER_COLOR_RED_TT 284
+#define IDS_MENU_OUTER_COLOR_GREEN 285
+#define IDS_MENU_OUTER_COLOR_GREEN_TT 286
+#define IDS_MENU_OUTER_COLOR_BLUE 287
+#define IDS_MENU_OUTER_COLOR_BLUE_TT 288
+#define IDS_MENU_OUTER_OPACITY 289
+#define IDS_MENU_OUTER_OPACITY_TT 290
+#define IDS_MENU_BORDER_COLOR_RED 291
+#define IDS_MENU_BORDER_COLOR_RED_TT 292
+#define IDS_MENU_BORDER_COLOR_GREEN 293
+#define IDS_MENU_BORDER_COLOR_GREEN_TT 294
+#define IDS_MENU_BORDER_COLOR_BLUE 295
+#define IDS_MENU_BORDER_COLOR_BLUE_TT 296
+#define IDS_MENU_BORDER_OPACITY 297
+#define IDS_MENU_BORDER_OPACITY_TT 298
+#define IDS_MENU_EXPORT_TO_FILE_SHAPE_TT 299
+#define IDS_MENU_IMPORT_FROM_FILE_SHAPE_TT 300
+#define IDS_ERROR_UNABLE_TO_SAVE_THE_FILE 303
+#define IDS_SAVE_SUCCESSFUL 304
+#define IDS_ERROR_UNABLE_TO_DELETE_THE_FILE 305
+#define IDS_PRESET_X_DELETED 306
+#define IDS_ERROR_A_FILE_ALREADY_EXISTS_WITH_THAT_FILENAME 307
+#define IDS_ERROR_UNABLE_TO_RENAME_FILE 308
+#define IDS_RENAME_SUCCESSFUL 309
+#define IDS_SPRITE_X_WARNING_ERROR_IN_INIT_CODE 310
+#define IDS_SPRITE_X_WARNING_ERROR_IN_PER_FRAME_CODE 311
+#define IDS_SPRITE_X_ERROR_BAD_SLOT_INDEX 312
+#define IDS_SPRITE_X_ERROR_IMAGE_FILE_MISSING_OR_CORRUPT 313
+#define IDS_SPRITE_X_ERROR_OUT_OF_MEM 314
+#define IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_INIT_CODE 319
+#define IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_PER_FRAME_CODE 320
+#define IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_PER_POINT_CODE 321
+#define IDS_WARNING_PRESET_X_ERROR_IN_SHAPE_X_INIT_CODE 322
+#define IDS_WARNING_PRESET_X_ERROR_IN_SHAPE_X_PER_FRAME_CODE 323
+#define IDS_CONFIG_PANEL_BUTTON_1 324
+#define IDS_CONFIG_PANEL_BUTTON_2 325
+#define IDS_CONFIG_PANEL_BUTTON_3 326
+#define IDS_CONFIG_PANEL_BUTTON_4 327
+#define IDS_CONFIG_PANEL_BUTTON_5 328
+#define IDS_CONFIG_PANEL_BUTTON_6 329
+#define IDS_CONFIG_PANEL_BUTTON_7 330
+#define IDS_CONFIG_PANEL_BUTTON_8 331
+#define IDS_EXTRA_FONT_1_NAME 332
+#define IDS_EXTRA_FONT_2_NAME 333
+#define IDS_PRESS_F1_MSG 334
+#define IDS_GRAPHICS_SUBSYSTEM_IS_TEMPORARILY_UNSTABLE 335
+#define IDS_UNKNOWN 336
+#define IDS_DISABLED_PAGE_TEARING 337
+#define IDS_NONE 338
+#define IDS_UNLIMITED 339
+#define IDS_X_FRAME_SEC 340
+#define IDS_HELP_ON_X_BUTTON 341
+#define IDS_FONTS_HELP 342
+#define IDS_DUAL_HEAD_HELP 343
+#define IDS_MULTI_SAMPLING 344
+#define IDS_MULTI_SAMPLING_HELP 345
+#define IDS_MAX_FRAMERATE 346
+#define IDS_MAX_FRAMERATE_HELP 347
+#define IDS_FAKE_FULLSCREEN 348
+#define IDS_FAKE_FULLSCREEN_HELP 349
+#define IDS_FULLSCREEN_ADAPTER 350
+#define IDS_FULLSCREEN_ADAPTER_HELP 351
+#define IDS_WINDOWED_ADPATER 352
+#define IDS_WINDOWED_ADPATER_HELP 353
+#define IDS_DESKTOP_ADAPTER 354
+#define IDS_DESKTOP_ADAPTER_HELP 355
+#define IDS_HELP_ON_X_CHECKBOX 356
+#define IDS_HELP_ON_X_CHECKBOX_HELP 357
+#define IDS_FORCE_INTO_FS_MODE_HELP 358
+#define IDS_FORCE_INTO_DESKTOP_MODE_HELP 359
+#define IDS_HELP_ON_F1 360
+#define IDS_HELP_ON_F1_HELP 361
+#define IDS_CB_SKIN_HELP 362
+#define IDS_SAVE_CPU_CHECKBOX 363
+#define IDS_SAVE_CPU_CHECKBOX_HELP 364
+#define IDS_FS_DISPLAY_MODE 365
+#define IDS_FS_DISPLAY_MODE_HELP 366
+#define IDS_TRY_TO_FIX_SLOW_TEXT 369
+#define IDS_TRY_TO_FIX_SLOW_TEXT_HELP 370
+#define IDS_VJ_MODE 371
+#define IDS_VJ_MODE_HELP 372
+#define IDS_HELP_ON_X 373
+#define IDS_DMS_LABEL_HELP 374
+#define IDS_FS_LABEL_HELP 375
+#define IDS_W_LABEL_HELP 376
+#define IDS_DM_MORE_HELP 377
+#define IDS_INITCONFIG_FAILED 378
+#define IDS_UNABLE_TO_LOAD_TABS 379
+#define IDS_DOCUMENTATION_FILE_NOT_FOUND 380
+#define IDS_ACCESS_TO_DOCUMENTATION_FILE_DENIED 381
+#define IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_DUE_TO_NO_ASSOC 382
+#define IDS_ACCESS_TO_DOCUMENTATION_FILE_FAILED_CODE_X 383
+#define IDS_ERROR_OPENING_DOCUMENTATION 384
+#define IDS_URL_COULD_NOT_OPEN 385
+#define IDS_ACCESS_TO_URL_WAS_DENIED 386
+#define IDS_ACCESS_TO_URL_FAILED_DUE_TO_NO_ASSOC 387
+#define IDS_ACCESS_TO_URL_FAILED_CODE_X 388
+#define IDS_ERROR_OPENING_URL 389
+#define IDS_RESTORE_ALL_DEFAULTS 390
+#define IDS_RESTORE_ALL_DEFAULTS_TITLE 391
+#define IDS_OK_HELP 392
+#define IDS_CANCEL_HELP 393
+#define IDS_RESTORE_DEFAULTS_HELP 394
+#define IDS_DOCUMENTATION_BUTTON_HELP 395
+#define IDS_VIEW_ONLINE_DOCS_HELP 396
+#define IDS_5_6_5_TEXTURE 397
+#define IDS_5_5_5_TEXTURE 398
+#define IDS_8_8_8_TEXTURE 399
+#define IDS_NO_ALPHA_FALLBACK 400
+#define IDS_NO_ALPHA_FALLBACK_HELP 401
+#define IDS_CB_SHOW_ICONS_HELP 402
+#define IDS_CB_BOX 403
+#define IDS_CB_BOX_HELP 404
+#define IDS_CB_MANUAL_SCOOT 405
+#define IDS_CB_MANUAL_SCOOT_HELP 406
+#define IDS_SPAN_BOTH_SCREENS 407
+#define IDS_USE_LEFT_SCREEN_ONLY 408
+#define IDS_USE_RIGHT_SCREEN_ONLY 409
+#define IDS_USE_TOP_SCREEN_ONLY 410
+#define IDS_USE_BOTTOM_SCREEN_ONLY 411
+#define IDS_COULD_NOT_FIND_FILE_FOR_DESKTOP_MODE_X 412
+#define IDS_MILKDROP_ERROR_FILE_MISSING 413
+#define IDS_ERROR_CREATING_GDI_DESKTOP_FONT 414
+#define IDS_ERROR_CREATING_DESKTOP_FONT 415
+#define IDS_ERROR_CREATING_TEXTURE_FOR_ICON_BITMAPS 416
+#define IDS_OUTDATED_VMS_DESKTOP_DLL_NEED_TO_REINSTALL 417
+#define IDS_ERROR_CREATING_HOOK_PROC_DESKTOP_ICONS_NOT_AVAILABLE 418
+#define IDS_ERROR_UPDATING_ICON_BITMAPS 419
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_TOO_MANY_UNIQUE_ICON_BITMAPS 420
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_COULD_NOT_GET_LEVEL_DESCRIPTION 421
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_LOCKRECT_FAILED 422
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_LR_PBITS_IS_NULL 423
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_UNKNOWN_PIXEL_FORMAT 424
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_COULDNT_GET_HDC 425
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_CALL_TO_GETDIBITS_FAILED 426
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_CALL_2_TO_GETDIBITS_FAILED 427
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_GETICONINFO_FAILED 428
+#define IDS_ERROR_UPDATING_ICON_BITMAPS_SHGETFILEINFO_FAILED 429
+#define IDS_UNABLE_TO_REGISTER_WINDOW_CLASS 430
+#define IDS_DIRECTX_INIT_FAILED 431
+#define IDS_DXC_ERR_CAPSFAIL 432
+#define IDS_FS_DISPLAY_MODE_SELECTED_IS_INVALID 433
+#define IDS_CREATEWINDOW_FAILED 434
+#define IDS_TRYING_TO_ENTER_FS_MODE_WITH_MULTIPLE_DISPLAYS 435
+#define IDS_TIP 436
+#define IDS_TRYING_TO_ENTER_FS_MODE_WITH_MULTIPLE_DISPLAYS_2 437
+#define IDS_UNABLE_TO_CREATE_DIRECTX_DEVICE 438
+#define IDS_OLDER_DISPLAY_ADAPTER_CATENATION 439
+#define IDS_OLDER_DISPLAY_ADAPTER_CATENATION_2 440
+#define IDS_DIRECTX_INIT_FAILED_X 441
+#define IDS_WINDOW_RESIZE_FAILED 442
+#define IDS_OUT_OF_VIDEO_MEMORY 443
+#define IDS_ERROR_CREATING_GDI_FONTS 444
+#define IDS_ERROR_LOADING_MAIN_MENU 445
+#define IDS_ERROR_LOADING_CONTEXT_MENU 446
+#define IDS_ERROR_CREATING_DIRECT3D_DEVICE_FOR_VJ_MODE 447
+#define IDS_VJ_MODE_INIT_ERROR 448
+#define IDS_ERROR_REGISTERING_WINDOW_CLASS_FOR_TEXT_WINDOW 449
+#define IDS_ERROR_CREATING_VJ_WINDOW 450
+#define IDS_ERROR_CREATING_D3D_DEVICE_FOR_VJ_MODE 451
+#define IDS_ERROR_CREATING_D3DX_FONTS 452
+#define IDS_UNABLE_TO_INIT_DXCONTEXT 453
+#define IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG 454
+#define IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG_2 455
+#define IDS_TO_FREE_UP_SOME_MEMORY_RESTART_WINAMP_THEN_GO_TO_CONFIG_3 456
+#define IDS_TO_FREE_UP_VIDEO_MEMORY 457
+#define IDS_TO_FREE_UP_VIDEO_MEMORY_2 458
+#define IDS_MILKDROP_SUGGESTION 459
+#define IDS_DIRECTX_MISSING_OR_CORRUPT 460
+#define IDS_ERROR_THE_PLUGIN_IS_ALREADY_RUNNING 463
+#define IDS_THIS_PLUGIN_NEEDS_MUSIC_TO_RUN 464
+#define IDS_NO_MUSIC_PLAYING 465
+#define IDS_UNABLE_TO_READ_DATA_FILE_X 466
+#define IDS_COULD_NOT_CREATE_MY_VERTEX_DECLARATION 467
+#define IDS_COULD_NOT_CREATE_WF_VERTEX_DECLARATION 468
+#define IDS_COULD_NOT_CREATE_SPRITE_VERTEX_DECLARATION 469
+#define IDS_SHADER_MODEL_2 470
+#define IDS_SHADER_MODEL_3 471
+#define IDS_SHADER_MODEL_4 472
+#define IDS_UKNOWN_CASE_X 473
+#define IDS_FAILED_TO_COMPILE_PIXEL_SHADERS_USING_X 474
+#define IDS_FAILED_TO_COMPILE_PIXEL_SHADERS_HARDWARE_MIS_REPORT 475
+#define IDS_COULD_NOT_COMPILE_FALLBACK_WV_SHADER 476
+#define IDS_COULD_NOT_COMPILE_FALLBACK_CV_SHADER 477
+#define IDS_COULD_NOT_COMPILE_FALLBACK_CP_SHADER 478
+#define IDS_COULD_NOT_COMPILE_BLUR1_VERTEX_SHADER 479
+#define IDS_COULD_NOT_COMPILE_BLUR1_PIXEL_SHADER 480
+#define IDS_COULD_NOT_COMPILE_BLUR2_VERTEX_SHADER 481
+#define IDS_COULD_NOT_COMPILE_BLUR2_PIXEL_SHADER 482
+#define IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_SMALLER_DISPLAY 483
+#define IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_NOT_ENOUGH_VID_MEM_RECOMMENDATION 484
+#define IDS_COULD_NOT_CREATE_INTERNAL_CANVAS_TEXTURE_NOT_ENOUGH_VID_MEM 485
+#define IDS_SUCCESSFULLY_CREATED_VS0_VS1 486
+#define IDS_ERROR_CREATING_BLUR_TEXTURES 487
+#define IDS_COULD_NOT_CREATE_NOISE_TEXTURE 488
+#define IDS_COULD_NOT_LOCK_NOISE_TEXTURE 489
+#define IDS_NOISE_TEXTURE_BYTE_LAYOUT_NOT_RECOGNISED 490
+#define IDS_COULD_NOT_CREATE_3D_NOISE_TEXTURE 491
+#define IDS_COULD_NOT_LOCK_3D_NOISE_TEXTURE 492
+#define IDS_3D_NOISE_TEXTURE_BYTE_LAYOUT_NOT_RECOGNISED 493
+#define IDS_ERROR_CREATING_SHADER 498
+#define IDS_PLEASE_EXIT_VIS_BEFORE_RUNNING_CONFIG_PANEL 499
+#define IDS_FPS 500
+#define IDS_PF_MONITOR 501
+#define IDS_PRESS_F9_TO_HIDE_SHADER_QREF 502
+#define IDS_PRESS_F9_TO_SHOW_SHADER_QREF 503
+#define IDS_WARP_AND_COMPOSITE_SHADERS_LOCKED 504
+#define IDS_WARP_SHADER_LOCKED 505
+#define IDS_COMPOSITE_SHADER_LOCKED 506
+#define IDS_PRESET_USES_HIGHEST_PIXEL_SHADER_VERSION 507
+#define IDS_PRESET_HAS_MIXED_VERSIONS_OF_SHADERS 508
+#define IDS_UPGRADE_SHADERS_TO_USE_PS2 509
+#define IDS_UPGRADE_SHADERS_TO_USE_PS3 510
+#define IDS_PRESET_DOES_NOT_USE_PIXEL_SHADERS 511
+#define IDS_UPGRADE_TO_USE_PS2 512
+#define IDS_WARNING_OLD_GPU_MIGHT_NOT_WORK_WITH_PRESET 513
+#define IDS_PRESET_CURRENTLY_USES_PS2 514
+#define IDS_UPGRADE_TO_USE_PS3 515
+#define IDS_PRESET_CURRENTLY_USES_PS3 516
+#define IDS_UPGRADE_TO_USE_PS4 517
+#define IDS_WARNING_DO_NOT_FORGET_WARP_SHADER_WAS_LOCKED 518
+#define IDS_WARNING_DO_NOT_FORGET_COMPOSITE_SHADER_WAS_LOCKED 519
+#define IDS_PRESET_MASH_UP_TEXT1 520
+#define IDS_PRESET_CURRENTLY_USES_PS2X 521
+#define IDS_UPGRADE_TO_USE_PS2X 522
+#define IDS_PRESET_MASH_UP_TEXT2 524
+#define IDS_PRESET_MASH_UP_TEXT3 525
+#define IDS_PRESET_MASH_UP_TEXT4 526
+#define IDS_DIRECTORY_OF_X 527
+#define IDS_SHUFFLE_IS_NOW_OFF 528
+#define IDS_SHUFFLE_IS_NOW_ON 529
+#define IDS_COMPSHADER_LOCKED 530
+#define IDS_WARPSHADER_LOCKED 531
+#define IDS_ALLSHADERS_LOCKED 532
+#define IDS_ALLSHADERS_UNLOCKED 533
+#define IDS_UPGRADE_TO_USE_PS2B 534
+#define IDS_PS_AUTO_RECOMMENDED 535
+#define IDS_PS_DISABLED 536
+#define IDS_PS_SHADER_MODEL_2 537
+#define IDS_PS_SHADER_MODEL_3 538
+#define IDS_TX_8_BITS_PER_CHANNEL 539
+#define IDS_TX_16_BITS_PER_CHANNEL 540
+#define IDS_TX_32_BITS_PER_CHANNEL 541
+#define IDS_160X120_SLOW 542
+#define IDS_192X144_SLOW 543
+#define IDS_NONE_BEST_IMAGE_QUALITY 544
+#define IDS_1_25_X 545
+#define IDS_1_33_X 546
+#define IDS_1_5_X 547
+#define IDS_1_67_X 548
+#define IDS_2_X 549
+#define IDS_3_X 550
+#define IDS_4_X 551
+#define IDS_NEAREST_POWER_OF_2 552
+#define IDS_EXACT_RECOMMENDED 553
+#define IDS_PIXEL_SHADERS 554
+#define IDS_PIXEL_SHADERS_TEXT 555
+#define IDS_TEXFORMAT 556
+#define IDS_TEXFORMAT_TEXT 557
+#define IDS_CANVAS_SIZE 558
+#define IDS_CANVAS_SIZE_TEXT 559
+#define IDS_CANVAS_STRETCH 560
+#define IDS_CANVAS_STRETCH_TEXT 561
+#define IDS_MAX_IMAGES_BYTES_TEXT 562
+#define IDS_MENU_EDIT_WARP_SHADER 563
+#define IDS_MENU_EDIT_COMPOSITE_SHADER 564
+#define IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT 565
+#define IDS_MENU_BLUR1_EDGE_DARKEN_AMOUNT_TT 566
+#define IDS_MENU_BLUR1_MIN_COLOR_VALUE 567
+#define IDS_MENU_BLUR1_MIN_COLOR_VALUE_TT 568
+#define IDS_MENU_BLUR1_MAX_COLOR_VALUE 569
+#define IDS_MENU_BLUR1_MAX_COLOR_VALUE_TT 570
+#define IDS_MENU_BLUR2_MIN_COLOR_VALUE 571
+#define IDS_MENU_BLUR2_MIN_COLOR_VALUE_TT 572
+#define IDS_MENU_BLUR2_MAX_COLOR_VALUE 573
+#define IDS_MENU_BLUR2_MAX_COLOR_VALUE_TT 574
+#define IDS_MENU_BLUR3_MIN_COLOR_VALUE 575
+#define IDS_MENU_BLUR3_MIN_COLOR_VALUE_TT 576
+#define IDS_MENU_BLUR3_MAX_COLOR_VALUE 577
+#define IDS_MENU_BLUR3_MAX_COLOR_VALUE_TT 578
+#define IDS_MENU_EDIT_PER_VERTEX_EQUATIONS 579
+#define IDS_MENU_EDIT_PER_VERTEX_EQUATIONS_TT 580
+#define IDS_MENU_EDIT_WARP_SHADER_TT 581
+#define IDS_MENU_EDIT_COMPOSITE_SHADER_TT 582
+#define IDS_MENU_EDIT_UPGRADE_PRESET_PS_VERSION 583
+#define IDS_MENU_EDIT_UPGRADE_PRESET_PS_VERSION_TT 584
+#define IDS_MENU_EDIT_DO_A_PRESET_MASH_UP 585
+#define IDS_MENU_EDIT_DO_A_PRESET_MASH_UP_TT 586
+#define IDS_MENU_NUMBER_OF_INSTANCES 587
+#define IDS_MENU_NUMBER_OF_INSTANCES_TT 588
+#define IDS_MENU_EDIT_INIT_CODE_SHAPE_TT 589
+#define IDS_MENU_EDIT_PER_FRAME_INSTANCE_CODE 590
+#define IDS_MENU_EDIT_PER_FRAME_INSTANCE_CODE_TT 591
+#define IDS_ERROR_PRESET_NOT_FOUND_X 592
+#define IDS_ERROR_NO_PRESET_FILES_OR_DIRS_FOUND_IN_X 593
+#define IDS_SCANNING_PRESETS 594
+#define IDS_SPRITE_X_ERROR_COULD_NOT_FIND_IMG_OR_NOT_DEFINED 595
+#define IDS_WARNING_PRESET_X_ERROR_IN_PRESET_INIT_CODE 596
+#define IDS_WARNING_PRESET_X_ERROR_IN_PER_FRAME_CODE 597
+#define IDS_WARNING_PRESET_X_ERROR_IN_PER_VERTEX_CODE 598
+#define IDS_HZ 599
+#define IDS_HELP_MINIMIZE_WINAMP 600
+#define IDS_HELP_MINIMIZE_WINAMP_HELP 601
+#define IDS_DIRECTX_MISSING_OR_CORRUPT_TEXT 602
+#define IDS_PARENT_DIRECTORY 603
+#define IDS_RAND_TITLE 604
+#define IDS_RAND_MSG 605
+#define IDS_MAX_IMAGES_BYTES 606
+#define IDS_PAGE_X 607
+#define IDS_MB 608
+#define IDS_GB 609
+#define IDS_MASHUP_GENERAL_POSTPROC 610
+#define IDS_MASHUP_MOTION_EQUATIONS 611
+#define IDS_MASHUP_WAVEFORMS_SHAPES 612
+#define IDS_MASHUP_WARP_SHADER 613
+#define IDS_MASHUP_COMP_SHADER 614
+#define IDS_STRING615 615
+#define IDS_STRING616 616
+#define IDS_STRING617 617
+#define IDS_STRNG618 618
+#define IDS_STRING618 618
+#define IDS_STRING619 619
+#define IDS_STRING620 620
+#define IDS_STRING621 621
+#define IDS_STRING622 622
+#define IDS_STRING623 623
+#define IDS_STRING624 624
+#define IDS_STRING625 625
+#define IDS_STRING626 626
+#define IDS_STRING627 627
+#define IDS_STRING628 628
+#define IDS_STRING629 629
+#define IDS_STRING630 630
+#define IDS_STRING631 631
+#define IDS_STRING632 632
+#define IDS_STRING633 633
+#define IDS_STRING634 634
+#define IDS_STRING635 635
+#define IDS_UPGRADE_SHADERS_TO_USE_PS2X 636
+#define IDS_PRESS_ESC_TO_RETURN 637
+#define IDS_COULD_NOT_LOAD_TEXTURE_X 638
+#define IDS_ERROR_COMPILING_X_X_SHADER 639
+#define IDS_ERROR_PARSING_X_X_SHADER 640
+#define IDS_UNABLE_TO_RESOLVE_TEXSIZE_FOR_A_TEXTURE_NOT_IN_USE 641
+#define IDS_KEY_MAPPINGS 642
+#define IDC_CB_FOG 1000
+#define IDC_CB_SUPERTEX 1001
+#define IDC_CB_HELP_MSG 1001
+#define IDC_CB_PRESS_F1_MSG 1001
+#define IDC_DISP_MODE 1003
+#define IDC_CB_FS 1004
+#define IDC_CB_PT 1005
+#define IDC_CB_WPT 1005
+#define IDC_SZ_ABOUT 1006
+#define IDC_CB_MIN 1006
+#define IDC_ADAPTER_W 1007
+#define IDC_ADAPTER_TEXT 1008
+#define IDC_ADAPTER_W_CAPTION 1008
+#define IDC_ADAPTER_FFS 1008
+#define IDC_ADAPTER_DMS 1008
+#define IDC_DISP_MODE_TEXT 1009
+#define IDC_DISP_MODE_CAPTION 1009
+#define IDC_ADAPTER_FS 1010
+#define IDC_ADAPTER_TEXT2 1011
+#define IDC_ADAPTER_FS_CAPTION 1011
+#define IDC_FS_ADAPTER_CAPTION 1011
+#define IDC_CB_TWOPASS 1012
+#define IDC_CB_FFSPT 1012
+#define IDC_CB_DMSPT 1012
+#define IDC_CB_TRANS_HAIR 1013
+#define IDC_ADAPTER_FS_CAPTION2 1013
+#define IDC_W_ADAPTER_CAPTION 1013
+#define IDC_FONT2b 1013
+#define IDC_FONT2 1013
+#define IDC_CB_3B 1014
+#define IDC_ADD_STUFF_HERE 1014
+#define IDC_FFS_ADAPTER_CAPTION 1014
+#define IDC_DMS_ADAPTER_CAPTION 1014
+#define IDC_CB_DEBUGOUTPUT 1014
+#define IDC_FONT3b 1014
+#define IDC_FONT3 1014
+#define IDC_MQ 1015
+#define IDC_CB_FAKE 1015
+#define IDC_TEXSIZECOMBO 1015
+#define IDC_FONT4b 1015
+#define IDC_FONT4 1015
+#define IDC_DISP_MODE_TEXT2 1016
+#define IDC_CB_NO_FAKE_TIPS 1016
+#define IDC_TAB1 1016
+#define IDC_TABS 1016
+#define IDC_CB_FSPT 1016
+#define IDC_FONTSIZE 1016
+#define IDC_CB_AUTOGAMMA 1016
+#define IDC_FONT5b 1016
+#define IDC_FONT5 1016
+#define IDC_WMS 1017
+#define IDC_MESHSIZECOMBO 1017
+#define IDC_FONTSIZE3 1017
+#define IDC_DISP_MODE_TEXT3 1018
+#define IDC_MULTISAMPLING_CAPTION2 1018
+#define IDC_FS_BOX 1018
+#define IDC_W_MULTISAMPLING_CAPTION 1018
+#define IDC_BETWEEN_TIME 1018
+#define IDC_FONTSIZE4 1018
+#define IDC_FSMS 1019
+#define IDC_CB_ALWAYS3D 1019
+#define IDC_BETWEEN_TIME_RANDOM 1019
+#define IDC_FONT6b 1019
+#define IDC_FONT6 1019
+#define IDC_DISP_MODE_TEXT4 1020
+#define IDC_MULTISAMPLING_CAPTION 1020
+#define IDC_FRACTAL_RES_CAPTION 1020
+#define IDC_INITIAL_WAVEMODE_CAPTION 1020
+#define IDC_CB_DMS 1020
+#define IDC_HARDCUT_BETWEEN_TIME 1020
+#define IDC_FONTSIZE5 1020
+#define IDC_CB_SCROLLON 1020
+#define IDC_FS_LIMIT 1021
+#define IDC_FS_MAXFPS 1021
+#define IDC_FONTOPTIONS 1021
+#define IDC_TEXFORMAT 1021
+#define IDC_DISP_MODE_TEXT5 1022
+#define IDC_FRAME_DELAY_CAPTION 1022
+#define IDC_FS_FRAME_DELAY_CAPTION 1022
+#define IDC_FS_MAXFPS_CAPTION 1022
+#define IDC_FONTOPTIONS3 1022
+#define IDC_SHADERS 1022
+#define IDC_W_LIMIT 1023
+#define IDC_W_MAXFPS 1023
+#define IDC_CB_NOWARN 1023
+#define IDC_BLEND_AUTO 1023
+#define IDC_CB_SCROLLON2 1023
+#define IDC_DISP_MODE_TEXT6 1024
+#define IDC_FRAME_DELAY_CAPTION2 1024
+#define IDC_G_BOX 1024
+#define IDC_W_FRAME_DELAY_CAPTION 1024
+#define IDC_W_MAXFPS_CAPTION 1024
+#define IDC_CB_NOWARN2 1024
+#define IDC_BLEND_USER 1024
+#define IDC_W_BOX 1025
+#define IDC_CB_SAVE_CPU 1025
+#define IDC_FONT7b 1025
+#define IDC_FONT7 1025
+#define IDC_CB_ANISO 1025
+#define IDC_TABS_PLACEHOLDER 1026
+#define IDC_FFSMS 1026
+#define IDC_DMSMS 1026
+#define IDC_CB_NORATING 1026
+#define IDC_MULTISAMPLING_CAPTION3 1027
+#define IDC_FFS_MULTISAMPLING_CAPTION 1027
+#define IDC_FONTSIZE2 1027
+#define IDC_DMS_MULTISAMPLING_CAPTION 1027
+#define IDC_CB_INSTASCAN 1027
+#define IDC_FRAME_DELAY_CAPTION3 1028
+#define IDC_FFS_FRAME_DELAY_CAPTION 1028
+#define IDC_FFS_MAXFPS_CAPTION 1028
+#define IDC_FONTOPTIONS2 1028
+#define IDC_DMS_MAXFPS_CAPTION 1028
+#define IDC_STRETCH 1028
+#define IDC_FFS_LIMIT 1029
+#define IDC_FFS_MAXFPS 1029
+#define IDC_DMS_MAXFPS 1029
+#define IDC_FONTSIZE6 1029
+#define IDC_MAX_IMAGES 1029
+#define IDC_RECT 1030
+#define IDC_CB_SKIN 1030
+#define IDC_MAX_BYTES 1030
+#define IDC_Q 1031
+#define IDC_FRACTAL_RES 1031
+#define IDC_INITIAL_WAVEMODE 1031
+#define IDC_FONT8b 1031
+#define IDC_FONT8 1031
+#define IDC_CB_MIN2 1031
+#define IDC_CB_FIXSLOWTEXT 1031
+#define IDC_HS_ANIM_SPEED 1032
+#define IDC_BETWEEN_TIME_LABEL 1032
+#define IDC_FONTSIZE7 1032
+#define IDC_FS_MULTISAMPLING_CAPTION 1033
+#define IDC_BETWEEN_TIME_RANDOM_LABEL 1033
+#define IDC_HS_ANIM_SPEED_CAPTION 1034
+#define IDC_BLEND_AUTO_LABEL 1034
+#define IDC_FONT9b 1034
+#define IDC_FONT9 1034
+#define IDC_BLEND_USER_LABEL 1035
+#define IDC_FONTSIZE8 1035
+#define IDC_FFS_LABEL 1036
+#define IDC_DMS_LABEL 1036
+#define IDC_BLEND_USER_LABEL2 1036
+#define IDC_BETWEEN_TIME_LABEL2 1036
+#define IDC_RAND_TITLE_LABEL 1036
+#define IDC_HARDCUT_BETWEEN_TIME_LABEL 1036
+#define IDC_FS_LABEL 1037
+#define IDC_BLEND_USER_LABEL3 1037
+#define IDC_RAND_MSG_LABEL 1037
+#define IDC_W_LABEL 1038
+#define IDC_FONTSIZE9 1038
+#define IDC_3DSEP_LABEL 1038
+#define ID_FONTS 1039
+#define IDC_BRIGHT_SLIDER 1039
+#define IDC_FONT_CAPTION 1040
+#define ID_DM_MORE 1040
+#define IDC_FONTSIZE_CAPTION 1041
+#define ID_DUALHEAD 1041
+#define IDC_FONTOPTIONS_CAPTION 1042
+#define IDC_SYSTEM_FONT 1043
+#define IDC_CB_SEPTEXT 1043
+#define IDC_FONT_NAME_2 1043
+#define IDC_DECORATIVE_FONT 1044
+#define IDC_HARDCUT_LOUDNESS 1044
+#define IDC_FONT_NAME_1 1044
+#define IDC_CB_HARDCUTS 1045
+#define IDC_TITLE_FONT 1045
+#define IDC_FONT_NAME_3 1045
+#define IDC_CB_BOX 1046
+#define IDC_SONGTITLEANIM_DURATION 1046
+#define IDC_FONT_NAME_4 1046
+#define IDC_DM_ALPHA_FIX 1047
+#define IDC_CB_TITLE_ANIMS 1047
+#define IDC_FONT_NAME_5 1047
+#define IDC_DM_ALPHA_FIX_CAPTION 1048
+#define IDC_V_PICK 1048
+#define IDC_RAND_TITLE 1048
+#define IDC_FONT_NAME_6 1048
+#define IDC_CB_MANUAL_SCOOT 1049
+#define IDC_T1 1049
+#define IDC_RAND_MSG 1049
+#define IDC_FONT_NAME_7 1049
+#define IDC_T3 1050
+#define IDC_CB_SHOW_ICONS 1050
+#define IDC_FONT_NAME_8 1050
+#define IDC_3DSEP 1050
+#define IDC_H_PICK 1051
+#define IDC_T5 1051
+#define IDC_FONT_NAME_9 1051
+#define IDC_T2 1052
+#define IDC_FONTOPTIONS_CAPTION2 1052
+#define IDC_T4 1053
+#define IDC_FONTOPTIONS_CAPTION3 1053
+#define IDC_FONT_TEXT 1054
+#define IDC_TEXSIZECOMBO_CAPTION 1054
+#define IDC_MESHSIZECOMBO_CAPTION 1055
+#define IDC_BRIGHT_SLIDER_BOX 1056
+#define IDC_SONGTITLEANIM_DURATION_LABEL 1057
+#define IDC_TEXFORMAT_CAPTION 1057
+#define IDC_HARDCUT_LOUDNESS_LABEL 1058
+#define IDC_SHADERS_CAPTION 1058
+#define IDC_FONTSIZE1 1059
+#define IDC_HARDCUT_LOUDNESS_MIN 1059
+#define IDC_BRIGHT_SLIDER_BOX2 1059
+#define IDC_HARDCUT_LOUDNESS_MAX 1060
+#define IDC_STRETCH_CAPTION 1060
+#define IDC_CB_VJMODE 1061
+#define IDC_MAX_IMAGES_CAPTION 1061
+#define IDC_MAX_BYTES_CAPTION 1062
+#define IDC_FONTBOLD1 1063
+#define IDC_FONTITAL1 1064
+#define IDC_FONTAA1 1065
+#define IDC_FONTBOLD2 1066
+#define IDC_FONTITAL2 1067
+#define IDC_FONTAA2 1068
+#define IDC_FONTBOLD3 1069
+#define IDC_FONTITAL3 1070
+#define IDC_FONTAA3 1071
+#define IDC_FONTBOLD4 1072
+#define IDC_FONTITAL4 1073
+#define IDC_FONTAA4 1074
+#define IDC_FONTBOLD5 1075
+#define IDC_FONTITAL5 1076
+#define IDC_FONTAA5 1077
+#define IDC_FONTBOLD6 1078
+#define IDC_FONTITAL6 1079
+#define IDC_FONTAA6 1080
+#define IDC_FONTBOLD7 1084
+#define IDC_FONTITAL7 1085
+#define IDC_FONTAA7 1086
+#define IDC_FONTBOLD8 1087
+#define IDC_FONTITAL8 1088
+#define IDC_FONTAA8 1089
+#define IDC_FONTBOLD9 1090
+#define IDC_FONTITAL9 1091
+#define IDC_FONTAA9 1092
+#define IDC_FONT1b 1093
+#define IDC_FONT1 1093
+#define ID_QUIT 40006
+#define ID_GO_FS 40007
+#define ID_SHOWHELP 40008
+#define ID_SHOWPLAYLIST 40009
+#define ID_DESKTOP_MODE 40010
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 131
+#define _APS_NEXT_COMMAND_VALUE 40011
+#define _APS_NEXT_CONTROL_VALUE 1062
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/Visualization/vis_milk2/shell_defines.h b/Src/Plugins/Visualization/vis_milk2/shell_defines.h
new file mode 100644
index 00000000..c978ce71
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/shell_defines.h
@@ -0,0 +1,76 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_PLUGIN_SHELL_SHELL_DEFINES_H__
+#define __NULLSOFT_DX9_PLUGIN_SHELL_SHELL_DEFINES_H__ 1
+
+#include <windows.h>
+
+#define DEFAULT_FULLSCREEN_WIDTH 640
+#define DEFAULT_FULLSCREEN_HEIGHT 480
+#define MAX_ICON_TEXTURES 8
+#define ICON_TEXTURE_SIZE 256
+#define DEFAULT_WINDOW_SIZE 0.625f // as a portion of the width or height of the screen (whichever is smaller)
+#define DESKTOP_MODE_KEYBOARD_INPUT_WINDOW_CLASSNAME "DESKTOP MODE KEYBOARD INPUT WINDOW"
+#define BGR2RGB(x) (((x>>16)&0xFF) | (x & 0xFF00) | ((x<<16)&0xFF0000))
+
+#define NUM_BASIC_FONTS 4
+#define SYS_FONT 0
+#define DEC_FONT 1
+#define HELP_FONT 2
+#define DESK_FONT 3
+#define MAX_EXTRA_FONTS 5
+typedef enum
+{
+ SIMPLE_FONT = 0, // aka 'system' font; should be legible
+ DECORATIVE_FONT = 1,
+ HELPSCREEN_FONT = 2,
+ PLAYLIST_FONT = 3,
+ EXTRA_1 = 4,
+ EXTRA_2 = 5,
+ EXTRA_3 = 6,
+ EXTRA_4 = 7,
+ EXTRA_5 = 8
+}
+eFontIndex;
+
+// for m_screenmode:
+typedef enum
+{
+ NOT_YET_KNOWN = -1,
+ FULLSCREEN = 0,
+ WINDOWED = 1,
+ FAKE_FULLSCREEN = 2,
+ DESKTOP = 3 // doesn't use overlays! =)
+}
+eScrMode;
+
+#include "../Winamp/wa_ipc.h"
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/state.cpp b/Src/Plugins/Visualization/vis_milk2/state.cpp
new file mode 100644
index 00000000..68b060f3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/state.cpp
@@ -0,0 +1,1961 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "state.h"
+#include "support.h"
+#include "ns-eel2/ns-eel.h"
+#include "plugin.h"
+#include "utility.h"
+#include <windows.h>
+#include <locale.h>
+#include "resource.h"
+#include <vector>
+#include <assert.h>
+
+extern CPlugin g_plugin; // declared in main.cpp
+
+#define FRAND ((rand() % 7381)/7380.0f)
+
+
+
+// These are intended to replace GetPrivateProfileInt/FloatString, which are very slow
+// for large files (they always start from the top). (really slow - some preset loads
+// were taking 90 ms because of these!)
+// The trick here is that we assume the file will be ordered correctly. If not - if
+// the next line doesn't have the expected token - we rescan from the top. If the line
+// is never found, we use the default value, and leave MyGetPos untouched.
+
+#include "gstring.h"
+
+typedef std::vector<GStringA> VarNameList;
+typedef std::vector<int > IntList;
+
+
+FILE* fLastFilePtr = NULL;
+void GetFast_CLEAR() { fLastFilePtr = NULL; }
+bool _GetLineByName(FILE* f, const char* szVarName, char* szRet, int nMaxRetChars)
+{
+ // lines in the file look like this: szVarName=szRet
+ // OR: szVarName szRet
+ // the part of the line after the '=' sign (or space) goes into szRet.
+ // szVarName can't have any spaces in it.
+
+ static int MyLineNum = 0;
+ static VarNameList line_varName;
+ static IntList line_value_bytepos;
+
+ if (f != fLastFilePtr)
+ {
+ fLastFilePtr = f;
+ MyLineNum = 0;
+ line_varName.clear();
+ line_value_bytepos.clear();
+
+ // start from beginning of file
+ fseek(f, 0, SEEK_SET);
+
+ // scan each line in the file for "szVarName=value" pairs, and store info about them.
+ #define MAX_VARNAME_LEN 128
+ char szThisLineVarName[MAX_VARNAME_LEN];
+ while (1)
+ {
+ char ch;
+ int pos = 0;
+ do
+ {
+ ch = fgetc(f);
+ if (pos < MAX_VARNAME_LEN-3)
+ szThisLineVarName[pos++] = ch;
+ }
+ while ( ch != '\r' &&
+ ch != '\n' &&
+ ch != ' ' &&
+ ch != '=' &&
+ ch != EOF );
+ if (ch == EOF)
+ break;
+
+ if (ch == '=' || ch == ' ')
+ {
+ szThisLineVarName[pos-1] = 0; // replace '=' with a null char.
+ int bytepos = ftell(f);
+
+ //add an entry
+ line_varName.push_back(szThisLineVarName);
+ line_value_bytepos.push_back( bytepos );
+
+ // eat chars up to linefeed or EOF
+ /*
+ do
+ {
+ ch = fgetc(f);
+ }
+ while (ch != '\r' && ch != '\n' && ch != EOF);
+ */
+ fgets(szRet, nMaxRetChars-3, f); // reads chars up til the next linefeed.
+ }
+ if (ch == EOF)
+ break;
+
+ // eat any extra linefeed chars.
+ do
+ {
+ ch = fgetc(f);
+ }
+ while ((ch == '\r' || ch == '\n') && ch != EOF);
+ if (ch == EOF)
+ break;
+
+ // back up one char
+ fseek(f, -1, SEEK_CUR);
+
+ // on to next line...
+ }
+ }
+
+ // if current line isn't the one, check all the others...
+ if (MyLineNum < 0 || (size_t)MyLineNum >= line_varName.size() || strcmp(line_varName[MyLineNum].c_str(), szVarName) != 0)
+ {
+ int N = line_varName.size();
+ int i = 0;
+ for (i=0; i<N; i++)
+ if (strcmp(line_varName[i].c_str(), szVarName) == 0)
+ {
+ MyLineNum = i;
+ break;
+ }
+
+ // otherwise, szVarName not found in the file!
+ if (i==N)
+ return false;
+ }
+
+ fseek(f, line_value_bytepos[MyLineNum], SEEK_SET);
+
+ // now we know that we found and ate the '=' sign; return rest of the line.
+ int nChars = 0;
+ int pos = 0;
+ while (pos < nMaxRetChars-3)
+ {
+ char ch = fgetc(f);
+ if (ch == '\r' || ch == '\n' || ch==EOF)
+ break;
+ szRet[pos++] = ch;
+ };
+ szRet[pos] = 0;
+ //fgets(szRet, nMaxRetChars-3, f); // reads chars up til the next linefeed. NAH - it also copies in the linefeed char...
+
+ // move to next line
+ MyLineNum++;
+ //fseek(f, line_value_bytepos[MyLineNum], SEEK_SET);
+
+ return true;
+}
+
+int GetFastInt (const char* szVarName, int def, FILE* f)
+{
+ char buf[256];
+ if (!_GetLineByName(f, szVarName, buf, 255))
+ return def;
+ int ret;
+ if (sscanf(buf, "%d", &ret)==1)
+ return ret;
+ return def;
+}
+
+float GetFastFloat (const char* szVarName, float def, FILE* f)
+{
+ char buf[256];
+ if (!_GetLineByName(f, szVarName, buf, 255))
+ return def;
+ float ret;
+ if (_sscanf_l(buf, "%f", g_use_C_locale, &ret)==1)
+ {
+ return ret;
+ }
+ return def;
+}
+
+void GetFastString(const char* szVarName, const char* szDef, char* szRetLine, int nMaxChars, FILE* f)
+{
+ if (_GetLineByName(f, szVarName, szRetLine, nMaxChars-1))
+ return;
+ // otherwise, copy the default string, being careful not to overflow dest buf.
+ // (avoid strncpy because it pads with zeroes all the way out to the max size.)
+ int x = 0;
+ while (szDef[x] && x < nMaxChars)
+ {
+ szRetLine[x] = szDef[x];
+ x++;
+ }
+ szRetLine[x] = 0;
+}
+
+CState::CState()
+{
+ //Default();
+
+ // this is the list of variables that can be used for a PER-FRAME calculation;
+ // it is a SUBSET of the per-vertex calculation variable list.
+ m_pf_codehandle = NULL;
+ m_pp_codehandle = NULL;
+ m_pf_eel = NSEEL_VM_alloc();
+ m_pv_eel = NSEEL_VM_alloc();
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ m_wave[i].m_pf_codehandle = NULL;
+ m_wave[i].m_pp_codehandle = NULL;
+ m_wave[i].m_pf_eel=NSEEL_VM_alloc();
+ m_wave[i].m_pp_eel=NSEEL_VM_alloc();
+ }
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ m_shape[i].m_pf_codehandle = NULL;
+ m_shape[i].m_pf_eel=NSEEL_VM_alloc();
+ //m_shape[i].m_pp_codehandle = NULL;
+ }
+ //RegisterBuiltInVariables();
+}
+
+CState::~CState()
+{
+ FreeVarsAndCode();
+ NSEEL_VM_free(m_pf_eel);
+ NSEEL_VM_free(m_pv_eel);
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ NSEEL_VM_free(m_wave[i].m_pf_eel);
+ NSEEL_VM_free(m_wave[i].m_pp_eel);
+ }
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ NSEEL_VM_free(m_shape[i].m_pf_eel);
+ }
+}
+
+//--------------------------------------------------------------------------------
+
+void CState::RegisterBuiltInVariables(int flags)
+{
+ if (flags & RECOMPILE_PRESET_CODE)
+ {
+ NSEEL_VM_resetvars(m_pf_eel);
+ var_pf_zoom = NSEEL_VM_regvar(m_pf_eel, "zoom"); // i/o
+ var_pf_zoomexp = NSEEL_VM_regvar(m_pf_eel, "zoomexp"); // i/o
+ var_pf_rot = NSEEL_VM_regvar(m_pf_eel, "rot"); // i/o
+ var_pf_warp = NSEEL_VM_regvar(m_pf_eel, "warp"); // i/o
+ var_pf_cx = NSEEL_VM_regvar(m_pf_eel, "cx"); // i/o
+ var_pf_cy = NSEEL_VM_regvar(m_pf_eel, "cy"); // i/o
+ var_pf_dx = NSEEL_VM_regvar(m_pf_eel, "dx"); // i/o
+ var_pf_dy = NSEEL_VM_regvar(m_pf_eel, "dy"); // i/o
+ var_pf_sx = NSEEL_VM_regvar(m_pf_eel, "sx"); // i/o
+ var_pf_sy = NSEEL_VM_regvar(m_pf_eel, "sy"); // i/o
+ var_pf_time = NSEEL_VM_regvar(m_pf_eel, "time"); // i
+ var_pf_fps = NSEEL_VM_regvar(m_pf_eel, "fps"); // i
+ var_pf_bass = NSEEL_VM_regvar(m_pf_eel, "bass"); // i
+ var_pf_mid = NSEEL_VM_regvar(m_pf_eel, "mid"); // i
+ var_pf_treb = NSEEL_VM_regvar(m_pf_eel, "treb"); // i
+ var_pf_bass_att = NSEEL_VM_regvar(m_pf_eel, "bass_att"); // i
+ var_pf_mid_att = NSEEL_VM_regvar(m_pf_eel, "mid_att"); // i
+ var_pf_treb_att = NSEEL_VM_regvar(m_pf_eel, "treb_att"); // i
+ var_pf_frame = NSEEL_VM_regvar(m_pf_eel, "frame");
+ var_pf_decay = NSEEL_VM_regvar(m_pf_eel, "decay");
+ var_pf_wave_a = NSEEL_VM_regvar(m_pf_eel, "wave_a");
+ var_pf_wave_r = NSEEL_VM_regvar(m_pf_eel, "wave_r");
+ var_pf_wave_g = NSEEL_VM_regvar(m_pf_eel, "wave_g");
+ var_pf_wave_b = NSEEL_VM_regvar(m_pf_eel, "wave_b");
+ var_pf_wave_x = NSEEL_VM_regvar(m_pf_eel, "wave_x");
+ var_pf_wave_y = NSEEL_VM_regvar(m_pf_eel, "wave_y");
+ var_pf_wave_mystery = NSEEL_VM_regvar(m_pf_eel, "wave_mystery");
+ var_pf_wave_mode = NSEEL_VM_regvar(m_pf_eel, "wave_mode");
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "q%d", vi+1);
+ var_pf_q[vi] = NSEEL_VM_regvar(m_pf_eel, buf);
+ }
+ var_pf_progress = NSEEL_VM_regvar(m_pf_eel, "progress");
+ var_pf_ob_size = NSEEL_VM_regvar(m_pf_eel, "ob_size");
+ var_pf_ob_r = NSEEL_VM_regvar(m_pf_eel, "ob_r");
+ var_pf_ob_g = NSEEL_VM_regvar(m_pf_eel, "ob_g");
+ var_pf_ob_b = NSEEL_VM_regvar(m_pf_eel, "ob_b");
+ var_pf_ob_a = NSEEL_VM_regvar(m_pf_eel, "ob_a");
+ var_pf_ib_size = NSEEL_VM_regvar(m_pf_eel, "ib_size");
+ var_pf_ib_r = NSEEL_VM_regvar(m_pf_eel, "ib_r");
+ var_pf_ib_g = NSEEL_VM_regvar(m_pf_eel, "ib_g");
+ var_pf_ib_b = NSEEL_VM_regvar(m_pf_eel, "ib_b");
+ var_pf_ib_a = NSEEL_VM_regvar(m_pf_eel, "ib_a");
+ var_pf_mv_x = NSEEL_VM_regvar(m_pf_eel, "mv_x");
+ var_pf_mv_y = NSEEL_VM_regvar(m_pf_eel, "mv_y");
+ var_pf_mv_dx = NSEEL_VM_regvar(m_pf_eel, "mv_dx");
+ var_pf_mv_dy = NSEEL_VM_regvar(m_pf_eel, "mv_dy");
+ var_pf_mv_l = NSEEL_VM_regvar(m_pf_eel, "mv_l");
+ var_pf_mv_r = NSEEL_VM_regvar(m_pf_eel, "mv_r");
+ var_pf_mv_g = NSEEL_VM_regvar(m_pf_eel, "mv_g");
+ var_pf_mv_b = NSEEL_VM_regvar(m_pf_eel, "mv_b");
+ var_pf_mv_a = NSEEL_VM_regvar(m_pf_eel, "mv_a");
+ var_pf_monitor = NSEEL_VM_regvar(m_pf_eel, "monitor");
+ var_pf_echo_zoom = NSEEL_VM_regvar(m_pf_eel, "echo_zoom");
+ var_pf_echo_alpha = NSEEL_VM_regvar(m_pf_eel, "echo_alpha");
+ var_pf_echo_orient = NSEEL_VM_regvar(m_pf_eel, "echo_orient");
+ var_pf_wave_usedots = NSEEL_VM_regvar(m_pf_eel, "wave_usedots");
+ var_pf_wave_thick = NSEEL_VM_regvar(m_pf_eel, "wave_thick");
+ var_pf_wave_additive = NSEEL_VM_regvar(m_pf_eel, "wave_additive");
+ var_pf_wave_brighten = NSEEL_VM_regvar(m_pf_eel, "wave_brighten");
+ var_pf_darken_center = NSEEL_VM_regvar(m_pf_eel, "darken_center");
+ var_pf_gamma = NSEEL_VM_regvar(m_pf_eel, "gamma");
+ var_pf_wrap = NSEEL_VM_regvar(m_pf_eel, "wrap");
+ var_pf_invert = NSEEL_VM_regvar(m_pf_eel, "invert");
+ var_pf_brighten = NSEEL_VM_regvar(m_pf_eel, "brighten");
+ var_pf_darken = NSEEL_VM_regvar(m_pf_eel, "darken");
+ var_pf_solarize = NSEEL_VM_regvar(m_pf_eel, "solarize");
+ var_pf_meshx = NSEEL_VM_regvar(m_pf_eel, "meshx");
+ var_pf_meshy = NSEEL_VM_regvar(m_pf_eel, "meshy");
+ var_pf_pixelsx = NSEEL_VM_regvar(m_pf_eel, "pixelsx");
+ var_pf_pixelsy = NSEEL_VM_regvar(m_pf_eel, "pixelsy");
+ var_pf_aspectx = NSEEL_VM_regvar(m_pf_eel, "aspectx");
+ var_pf_aspecty = NSEEL_VM_regvar(m_pf_eel, "aspecty");
+ var_pf_blur1min = NSEEL_VM_regvar(m_pf_eel, "blur1_min");
+ var_pf_blur2min = NSEEL_VM_regvar(m_pf_eel, "blur2_min");
+ var_pf_blur3min = NSEEL_VM_regvar(m_pf_eel, "blur3_min");
+ var_pf_blur1max = NSEEL_VM_regvar(m_pf_eel, "blur1_max");
+ var_pf_blur2max = NSEEL_VM_regvar(m_pf_eel, "blur2_max");
+ var_pf_blur3max = NSEEL_VM_regvar(m_pf_eel, "blur3_max");
+ var_pf_blur1_edge_darken = NSEEL_VM_regvar(m_pf_eel, "blur1_edge_darken");
+
+ // this is the list of variables that can be used for a PER-VERTEX calculation:
+ // ('vertex' meaning a vertex on the mesh) (as opposed to a once-per-frame calculation)
+
+ NSEEL_VM_resetvars(m_pv_eel);
+
+ var_pv_zoom = NSEEL_VM_regvar(m_pv_eel, "zoom"); // i/o
+ var_pv_zoomexp = NSEEL_VM_regvar(m_pv_eel, "zoomexp"); // i/o
+ var_pv_rot = NSEEL_VM_regvar(m_pv_eel, "rot"); // i/o
+ var_pv_warp = NSEEL_VM_regvar(m_pv_eel, "warp"); // i/o
+ var_pv_cx = NSEEL_VM_regvar(m_pv_eel, "cx"); // i/o
+ var_pv_cy = NSEEL_VM_regvar(m_pv_eel, "cy"); // i/o
+ var_pv_dx = NSEEL_VM_regvar(m_pv_eel, "dx"); // i/o
+ var_pv_dy = NSEEL_VM_regvar(m_pv_eel, "dy"); // i/o
+ var_pv_sx = NSEEL_VM_regvar(m_pv_eel, "sx"); // i/o
+ var_pv_sy = NSEEL_VM_regvar(m_pv_eel, "sy"); // i/o
+ var_pv_time = NSEEL_VM_regvar(m_pv_eel, "time"); // i
+ var_pv_fps = NSEEL_VM_regvar(m_pv_eel, "fps"); // i
+ var_pv_bass = NSEEL_VM_regvar(m_pv_eel, "bass"); // i
+ var_pv_mid = NSEEL_VM_regvar(m_pv_eel, "mid"); // i
+ var_pv_treb = NSEEL_VM_regvar(m_pv_eel, "treb"); // i
+ var_pv_bass_att = NSEEL_VM_regvar(m_pv_eel, "bass_att"); // i
+ var_pv_mid_att = NSEEL_VM_regvar(m_pv_eel, "mid_att"); // i
+ var_pv_treb_att = NSEEL_VM_regvar(m_pv_eel, "treb_att"); // i
+ var_pv_frame = NSEEL_VM_regvar(m_pv_eel, "frame");
+ var_pv_x = NSEEL_VM_regvar(m_pv_eel, "x"); // i
+ var_pv_y = NSEEL_VM_regvar(m_pv_eel, "y"); // i
+ var_pv_rad = NSEEL_VM_regvar(m_pv_eel, "rad"); // i
+ var_pv_ang = NSEEL_VM_regvar(m_pv_eel, "ang"); // i
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "q%d", vi+1);
+ var_pv_q[vi] = NSEEL_VM_regvar(m_pv_eel, buf);
+ }
+ var_pv_progress = NSEEL_VM_regvar(m_pv_eel, "progress");
+ var_pv_meshx = NSEEL_VM_regvar(m_pv_eel, "meshx");
+ var_pv_meshy = NSEEL_VM_regvar(m_pv_eel, "meshy");
+ var_pv_pixelsx = NSEEL_VM_regvar(m_pv_eel, "pixelsx");
+ var_pv_pixelsy = NSEEL_VM_regvar(m_pv_eel, "pixelsy");
+ var_pv_aspectx = NSEEL_VM_regvar(m_pv_eel, "aspectx");
+ var_pv_aspecty = NSEEL_VM_regvar(m_pv_eel, "aspecty");
+ }
+
+ if (flags & RECOMPILE_WAVE_CODE)
+ {
+ for (int i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ NSEEL_VM_resetvars(m_wave[i].m_pf_eel);
+ m_wave[i].var_pf_time = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "time"); // i
+ m_wave[i].var_pf_fps = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "fps"); // i
+ m_wave[i].var_pf_frame = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "frame"); // i
+ m_wave[i].var_pf_progress = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "progress"); // i
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "q%d", vi+1);
+ m_wave[i].var_pf_q[vi] = NSEEL_VM_regvar(m_wave[i].m_pf_eel, buf);
+ }
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "t%d", vi+1);
+ m_wave[i].var_pf_t[vi] = NSEEL_VM_regvar(m_wave[i].m_pf_eel, buf);
+ }
+ m_wave[i].var_pf_bass = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "bass"); // i
+ m_wave[i].var_pf_mid = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "mid"); // i
+ m_wave[i].var_pf_treb = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "treb"); // i
+ m_wave[i].var_pf_bass_att = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "bass_att"); // i
+ m_wave[i].var_pf_mid_att = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "mid_att"); // i
+ m_wave[i].var_pf_treb_att = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "treb_att"); // i
+ m_wave[i].var_pf_r = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "r"); // i/o
+ m_wave[i].var_pf_g = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "g"); // i/o
+ m_wave[i].var_pf_b = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "b"); // i/o
+ m_wave[i].var_pf_a = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "a"); // i/o
+ m_wave[i].var_pf_samples = NSEEL_VM_regvar(m_wave[i].m_pf_eel, "samples"); // i/o
+
+ NSEEL_VM_resetvars(m_wave[i].m_pp_eel);
+ m_wave[i].var_pp_time = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "time"); // i
+ m_wave[i].var_pp_fps = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "fps"); // i
+ m_wave[i].var_pp_frame = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "frame"); // i
+ m_wave[i].var_pp_progress = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "progress"); // i
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "q%d", vi+1);
+ m_wave[i].var_pp_q[vi] = NSEEL_VM_regvar(m_wave[i].m_pp_eel, buf);
+ }
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "t%d", vi+1);
+ m_wave[i].var_pp_t[vi] = NSEEL_VM_regvar(m_wave[i].m_pp_eel, buf);
+ }
+ m_wave[i].var_pp_bass = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "bass"); // i
+ m_wave[i].var_pp_mid = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "mid"); // i
+ m_wave[i].var_pp_treb = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "treb"); // i
+ m_wave[i].var_pp_bass_att = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "bass_att"); // i
+ m_wave[i].var_pp_mid_att = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "mid_att"); // i
+ m_wave[i].var_pp_treb_att = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "treb_att"); // i
+ m_wave[i].var_pp_sample = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "sample"); // i
+ m_wave[i].var_pp_value1 = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "value1"); // i
+ m_wave[i].var_pp_value2 = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "value2"); // i
+ m_wave[i].var_pp_x = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "x"); // i/o
+ m_wave[i].var_pp_y = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "y"); // i/o
+ m_wave[i].var_pp_r = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "r"); // i/o
+ m_wave[i].var_pp_g = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "g"); // i/o
+ m_wave[i].var_pp_b = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "b"); // i/o
+ m_wave[i].var_pp_a = NSEEL_VM_regvar(m_wave[i].m_pp_eel, "a"); // i/o
+ }
+ }
+
+ if (flags & RECOMPILE_SHAPE_CODE)
+ {
+ for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ NSEEL_VM_resetvars(m_shape[i].m_pf_eel);
+ m_shape[i].var_pf_time = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "time"); // i
+ m_shape[i].var_pf_fps = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "fps"); // i
+ m_shape[i].var_pf_frame = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "frame"); // i
+ m_shape[i].var_pf_progress = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "progress"); // i
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "q%d", vi+1);
+ m_shape[i].var_pf_q[vi] = NSEEL_VM_regvar(m_shape[i].m_pf_eel, buf);
+ }
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ {
+ char buf[16];
+ sprintf(buf, "t%d", vi+1);
+ m_shape[i].var_pf_t[vi] = NSEEL_VM_regvar(m_shape[i].m_pf_eel, buf);
+ }
+ m_shape[i].var_pf_bass = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "bass"); // i
+ m_shape[i].var_pf_mid = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "mid"); // i
+ m_shape[i].var_pf_treb = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "treb"); // i
+ m_shape[i].var_pf_bass_att = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "bass_att"); // i
+ m_shape[i].var_pf_mid_att = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "mid_att"); // i
+ m_shape[i].var_pf_treb_att = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "treb_att"); // i
+ m_shape[i].var_pf_x = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "x"); // i/o
+ m_shape[i].var_pf_y = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "y"); // i/o
+ m_shape[i].var_pf_rad = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "rad"); // i/o
+ m_shape[i].var_pf_ang = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "ang"); // i/o
+ m_shape[i].var_pf_tex_ang = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "tex_ang"); // i/o
+ m_shape[i].var_pf_tex_zoom = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "tex_zoom"); // i/o
+ m_shape[i].var_pf_sides = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "sides"); // i/o
+ m_shape[i].var_pf_textured = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "textured"); // i/o
+ m_shape[i].var_pf_instance = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "instance"); // i/o
+ m_shape[i].var_pf_instances = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "num_inst"); // i/o
+ m_shape[i].var_pf_additive = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "additive"); // i/o
+ m_shape[i].var_pf_thick = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "thick"); // i/o
+ m_shape[i].var_pf_r = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "r"); // i/o
+ m_shape[i].var_pf_g = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "g"); // i/o
+ m_shape[i].var_pf_b = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "b"); // i/o
+ m_shape[i].var_pf_a = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "a"); // i/o
+ m_shape[i].var_pf_r2 = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "r2"); // i/o
+ m_shape[i].var_pf_g2 = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "g2"); // i/o
+ m_shape[i].var_pf_b2 = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "b2"); // i/o
+ m_shape[i].var_pf_a2 = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "a2"); // i/o
+ m_shape[i].var_pf_border_r = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "border_r"); // i/o
+ m_shape[i].var_pf_border_g = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "border_g"); // i/o
+ m_shape[i].var_pf_border_b = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "border_b"); // i/o
+ m_shape[i].var_pf_border_a = NSEEL_VM_regvar(m_shape[i].m_pf_eel, "border_a"); // i/o
+ }
+ }
+}
+void CState::Default(DWORD ApplyFlags)
+{
+ // DON'T FORGET TO ADD NEW VARIABLES TO BLEND FUNCTION, IMPORT, and EXPORT AS WELL!!!!!!!!
+
+ if ( (ApplyFlags & STATE_GENERAL) && // check for these 3 @ same time,
+ (ApplyFlags & STATE_MOTION) && // so a preset switch w/ warp/comp lock
+ (ApplyFlags & STATE_WAVE) // updates the name, but mash-ups don't.
+ )
+ {
+ lstrcpyW(m_szDesc, INVALID_PRESET_DESC);
+ //lstrcpy(m_szSection, "n/a");
+
+ m_fPresetStartTime = -1;
+ }
+
+ m_nMinPSVersion = 0;
+ m_nMaxPSVersion = 0;
+
+ m_bBlending = false;
+
+ // general:
+ if (ApplyFlags & STATE_GENERAL)
+ {
+ m_fRating = 3.0f;
+ m_fDecay = 0.98f; // 1.0 = none, 0.95 = heavy decay
+ m_fGammaAdj = 2.0f; // 1.0 = reg; +2.0 = double, +3.0 = triple...
+ m_fVideoEchoZoom = 2.0f;
+ m_fVideoEchoAlpha = 0.0f;
+ m_nVideoEchoOrientation = 0; // 0-3
+ m_bRedBlueStereo = false;
+ m_bBrighten = false;
+ m_bDarken = false;
+ m_bTexWrap = true;
+ m_bDarkenCenter = false;
+ m_bSolarize = false;
+ m_bInvert = false;
+ m_fShader = 0.0f;
+ m_fBlur1Min = 0.0f;
+ m_fBlur2Min = 0.0f;
+ m_fBlur3Min = 0.0f;
+ m_fBlur1Max = 1.0f;
+ m_fBlur2Max = 1.0f;
+ m_fBlur3Max = 1.0f;
+ m_fBlur1EdgeDarken = 0.25f;
+ }
+
+
+ // wave:
+ if (ApplyFlags & STATE_WAVE)
+ {
+ m_nWaveMode = 0;
+ m_nOldWaveMode = -1;
+ m_bAdditiveWaves = false;
+ m_bWaveDots = false;
+ m_bWaveThick = false;
+ m_fWaveAlpha = 0.8f;
+ m_fWaveScale = 1.0f;
+ m_fWaveSmoothing = 0.75f; // 0 = no smoothing, 0.9 = HEAVY smoothing
+ m_fWaveParam = 0.0f;
+ m_bModWaveAlphaByVolume = false;
+ m_fModWaveAlphaStart = 0.75f; // when relative volume hits this level, alpha -> 0
+ m_fModWaveAlphaEnd = 0.95f; // when relative volume hits this level, alpha -> 1
+ m_fWaveR = 1.0f;
+ m_fWaveG = 1.0f;
+ m_fWaveB = 1.0f;
+ m_fWaveX = 0.5f;
+ m_fWaveY = 0.5f;
+ m_bMaximizeWaveColor = true;
+ m_fMvX = 12.0f;
+ m_fMvY = 9.0f;
+ m_fMvDX = 0.0f;
+ m_fMvDY = 0.0f;
+ m_fMvL = 0.9f;
+ m_fMvR = 1.0f;
+ m_fMvG = 1.0f;
+ m_fMvB = 1.0f;
+ m_fMvA = 1.0f;
+
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ m_wave[i].enabled = 0;
+ m_wave[i].samples = 512;
+ m_wave[i].sep = 0;
+ m_wave[i].scaling = 1.0f;
+ m_wave[i].smoothing = 0.5f;
+ m_wave[i].r = 1.0f;
+ m_wave[i].g = 1.0f;
+ m_wave[i].b = 1.0f;
+ m_wave[i].a = 1.0f;
+ m_wave[i].bSpectrum = 0;
+ m_wave[i].bUseDots = 0;
+ m_wave[i].bDrawThick = 0;
+ m_wave[i].bAdditive = 0;
+ }
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ m_shape[i].enabled = 0;
+ m_shape[i].sides = 4;
+ m_shape[i].additive = 0;
+ m_shape[i].thickOutline = 0;
+ m_shape[i].textured = 0;
+ m_shape[i].instances = 1;
+ m_shape[i].tex_zoom = 1.0f;
+ m_shape[i].tex_ang = 0.0f;
+ m_shape[i].x = 0.5f;
+ m_shape[i].y = 0.5f;
+ m_shape[i].rad = 0.1f;
+ m_shape[i].ang = 0.0f;
+ m_shape[i].r = 1.0f;
+ m_shape[i].g = 0.0f;
+ m_shape[i].b = 0.0f;
+ m_shape[i].a = 1.0f;
+ m_shape[i].r2 = 0.0f;
+ m_shape[i].g2 = 1.0f;
+ m_shape[i].b2 = 0.0f;
+ m_shape[i].a2 = 0.0f;
+ m_shape[i].border_r = 1.0f;
+ m_shape[i].border_g = 1.0f;
+ m_shape[i].border_b = 1.0f;
+ m_shape[i].border_a = 0.1f;
+ }
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ m_wave[i].m_szInit[0] = 0;
+ m_wave[i].m_szPerFrame[0] = 0;
+ m_wave[i].m_szPerPoint[0] = 0;
+ }
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ m_shape[i].m_szInit[0] = 0;
+ m_shape[i].m_szPerFrame[0] = 0;
+ //m_shape[i].m_szPerPoint[0] = 0;
+ }
+ }
+
+ // motion:
+ if (ApplyFlags & STATE_MOTION)
+ {
+ m_fWarpAnimSpeed = 1.0f; // additional timescaling for warp animation
+ m_fWarpScale = 1.0f;
+ m_fZoomExponent = 1.0f;
+ m_fZoom = 1.0f;
+ m_fRot = 0.0f;
+ m_fRotCX = 0.5f;
+ m_fRotCY = 0.5f;
+ m_fXPush = 0.0f;
+ m_fYPush = 0.0f;
+ m_fWarpAmount = 1.0f;
+ m_fStretchX = 1.0f;
+ m_fStretchY = 1.0f;
+ m_fOuterBorderSize = 0.01f;
+ m_fOuterBorderR = 0.0f;
+ m_fOuterBorderG = 0.0f;
+ m_fOuterBorderB = 0.0f;
+ m_fOuterBorderA = 0.0f;
+ m_fInnerBorderSize = 0.01f;
+ m_fInnerBorderR = 0.25f;
+ m_fInnerBorderG = 0.25f;
+ m_fInnerBorderB = 0.25f;
+ m_fInnerBorderA = 0.0f;
+
+ // clear all code strings:
+ m_szPerFrameInit[0] = 0;
+ m_szPerFrameExpr[0] = 0;
+ m_szPerPixelExpr[0] = 0;
+ }
+
+ // DON'T FORGET TO ADD NEW VARIABLES TO BLEND FUNCTION, IMPORT, and EXPORT AS WELL!!!!!!!!
+ // ALSO BE SURE TO REGISTER THEM ON THE MAIN MENU (SEE MILKDROP.CPP)
+
+ // warp shader
+ if (ApplyFlags & STATE_WARP)
+ {
+ m_szWarpShadersText[0] = 0;
+ m_nWarpPSVersion = 0;
+ }
+
+ // comp shader
+ if (ApplyFlags & STATE_COMP)
+ {
+ m_szCompShadersText[0] = 0;
+ m_nCompPSVersion = 0;
+ }
+
+ RandomizePresetVars();
+
+ FreeVarsAndCode();
+}
+
+void CState::StartBlendFrom(CState *s_from, float fAnimTime, float fTimespan)
+{
+ CState *s_to = this;
+
+ // bools, ints, and strings instantly change
+
+ s_to->m_fVideoEchoAlphaOld = s_from->m_fVideoEchoAlpha.eval(-1);
+ s_to->m_nVideoEchoOrientationOld = s_from->m_nVideoEchoOrientation;
+ s_to->m_nOldWaveMode = s_from->m_nWaveMode;
+
+ /*
+ s_to->m_fVideoEchoAlphaOld = s_from->m_fVideoEchoAlpha.eval(-1);
+ s_to->m_nVideoEchoOrientationOld = s_from->m_nVideoEchoOrientation;
+
+ s_to->m_nOldWaveMode = s_from->m_nWaveMode;
+ s_to->m_nWaveMode = s_from->m_nWaveMode;
+ s_to->m_bAdditiveWaves = s_from->m_bAdditiveWaves;
+ s_to->m_nVideoEchoOrientation = s_from->m_nVideoEchoOrientation;
+ s_to->m_fWarpAnimSpeed = s_from->m_fWarpAnimSpeed; // would req. 10 phase-matches to blend this one!!!
+ s_to->m_bWaveDots = s_from->m_bWaveDots;
+ s_to->m_bWaveThick = s_from->m_bWaveThick;
+ s_to->m_bModWaveAlphaByVolume = s_from->m_bModWaveAlphaByVolume;
+ s_to->m_bMaximizeWaveColor = s_from->m_bMaximizeWaveColor;
+ s_to->m_bTexWrap = s_from->m_bTexWrap;
+ s_to->m_bDarkenCenter = s_from->m_bDarkenCenter;
+ s_to->m_bRedBlueStereo = s_from->m_bRedBlueStereo;
+ s_to->m_bBrighten = s_from->m_bBrighten;
+ s_to->m_bDarken = s_from->m_bDarken;
+ s_to->m_bSolarize = s_from->m_bSolarize;
+ s_to->m_bInvert = s_from->m_bInvert;
+ s_to->m_fRating = s_from->m_fRating;
+ */
+
+ // expr. eval. also copies over immediately (replaces prev.)
+ m_bBlending = true;
+ m_fBlendStartTime = fAnimTime;
+ m_fBlendDuration = fTimespan;
+
+ /*
+ //for (int e=0; e<MAX_EVALS; e++)
+ {
+ char szTemp[MAX_BIGSTRING_LEN];
+
+ lstrcpy(szTemp, m_szPerFrameExpr);
+ lstrcpy(m_szPerFrameExpr, s_to->m_szPerFrameExpr);
+ lstrcpy(s_to->m_szPerFrameExpr, szTemp);
+
+ lstrcpy(szTemp, m_szPerPixelExpr);
+ lstrcpy(m_szPerPixelExpr, s_to->m_szPerPixelExpr);
+ lstrcpy(s_to->m_szPerPixelExpr, szTemp);
+
+ lstrcpy(szTemp, m_szPerFrameInit);
+ lstrcpy(m_szPerFrameInit, s_to->m_szPerFrameInit);
+ lstrcpy(s_to->m_szPerFrameInit, szTemp);
+ }
+ RecompileExpressions();
+ s_to->RecompileExpressions();
+
+ lstrcpy(m_szDesc, s_to->m_szDesc);
+ //lstrcpy(m_szSection, s_to->m_szSection);
+ */
+
+ // CBlendableFloats & SuperValues blend over time
+ m_fGammaAdj .StartBlendFrom(&s_from->m_fGammaAdj , fAnimTime, fTimespan);
+ m_fVideoEchoZoom .StartBlendFrom(&s_from->m_fVideoEchoZoom , fAnimTime, fTimespan);
+ m_fVideoEchoAlpha.StartBlendFrom(&s_from->m_fVideoEchoAlpha, fAnimTime, fTimespan);
+ m_fDecay .StartBlendFrom(&s_from->m_fDecay , fAnimTime, fTimespan);
+ m_fWaveAlpha .StartBlendFrom(&s_from->m_fWaveAlpha , fAnimTime, fTimespan);
+ m_fWaveScale .StartBlendFrom(&s_from->m_fWaveScale , fAnimTime, fTimespan);
+ m_fWaveSmoothing .StartBlendFrom(&s_from->m_fWaveSmoothing , fAnimTime, fTimespan);
+ m_fWaveParam .StartBlendFrom(&s_from->m_fWaveParam , fAnimTime, fTimespan);
+ m_fWarpScale .StartBlendFrom(&s_from->m_fWarpScale , fAnimTime, fTimespan);
+ m_fZoomExponent .StartBlendFrom(&s_from->m_fZoomExponent , fAnimTime, fTimespan);
+ m_fShader .StartBlendFrom(&s_from->m_fShader , fAnimTime, fTimespan);
+ m_fModWaveAlphaStart.StartBlendFrom(&s_from->m_fModWaveAlphaStart, fAnimTime, fTimespan);
+ m_fModWaveAlphaEnd .StartBlendFrom(&s_from->m_fModWaveAlphaEnd, fAnimTime, fTimespan);
+
+ m_fZoom .StartBlendFrom(&s_from->m_fZoom , fAnimTime, fTimespan);
+ m_fRot .StartBlendFrom(&s_from->m_fRot , fAnimTime, fTimespan);
+ m_fRotCX .StartBlendFrom(&s_from->m_fRotCX , fAnimTime, fTimespan);
+ m_fRotCY .StartBlendFrom(&s_from->m_fRotCY , fAnimTime, fTimespan);
+ m_fXPush .StartBlendFrom(&s_from->m_fXPush , fAnimTime, fTimespan);
+ m_fYPush .StartBlendFrom(&s_from->m_fYPush , fAnimTime, fTimespan);
+ m_fWarpAmount.StartBlendFrom(&s_from->m_fWarpAmount,fAnimTime, fTimespan);
+ m_fStretchX .StartBlendFrom(&s_from->m_fStretchX , fAnimTime, fTimespan);
+ m_fStretchY .StartBlendFrom(&s_from->m_fStretchY , fAnimTime, fTimespan);
+ m_fWaveR .StartBlendFrom(&s_from->m_fWaveR , fAnimTime, fTimespan);
+ m_fWaveG .StartBlendFrom(&s_from->m_fWaveG , fAnimTime, fTimespan);
+ m_fWaveB .StartBlendFrom(&s_from->m_fWaveB , fAnimTime, fTimespan);
+ m_fWaveX .StartBlendFrom(&s_from->m_fWaveX , fAnimTime, fTimespan);
+ m_fWaveY .StartBlendFrom(&s_from->m_fWaveY , fAnimTime, fTimespan);
+ m_fOuterBorderSize .StartBlendFrom(&s_from->m_fOuterBorderSize , fAnimTime, fTimespan);
+ m_fOuterBorderR .StartBlendFrom(&s_from->m_fOuterBorderR , fAnimTime, fTimespan);
+ m_fOuterBorderG .StartBlendFrom(&s_from->m_fOuterBorderG , fAnimTime, fTimespan);
+ m_fOuterBorderB .StartBlendFrom(&s_from->m_fOuterBorderB , fAnimTime, fTimespan);
+ m_fOuterBorderA .StartBlendFrom(&s_from->m_fOuterBorderA , fAnimTime, fTimespan);
+ m_fInnerBorderSize .StartBlendFrom(&s_from->m_fInnerBorderSize , fAnimTime, fTimespan);
+ m_fInnerBorderR .StartBlendFrom(&s_from->m_fInnerBorderR , fAnimTime, fTimespan);
+ m_fInnerBorderG .StartBlendFrom(&s_from->m_fInnerBorderG , fAnimTime, fTimespan);
+ m_fInnerBorderB .StartBlendFrom(&s_from->m_fInnerBorderB , fAnimTime, fTimespan);
+ m_fInnerBorderA .StartBlendFrom(&s_from->m_fInnerBorderA , fAnimTime, fTimespan);
+ m_fMvX .StartBlendFrom(&s_from->m_fMvX , fAnimTime, fTimespan);
+ m_fMvY .StartBlendFrom(&s_from->m_fMvY , fAnimTime, fTimespan);
+ m_fMvDX .StartBlendFrom(&s_from->m_fMvDX , fAnimTime, fTimespan);
+ m_fMvDY .StartBlendFrom(&s_from->m_fMvDY , fAnimTime, fTimespan);
+ m_fMvL .StartBlendFrom(&s_from->m_fMvL , fAnimTime, fTimespan);
+ m_fMvR .StartBlendFrom(&s_from->m_fMvR , fAnimTime, fTimespan);
+ m_fMvG .StartBlendFrom(&s_from->m_fMvG , fAnimTime, fTimespan);
+ m_fMvB .StartBlendFrom(&s_from->m_fMvB , fAnimTime, fTimespan);
+ m_fMvA .StartBlendFrom(&s_from->m_fMvA , fAnimTime, fTimespan);
+ m_fBlur1Min .StartBlendFrom(&s_from->m_fBlur1Min , fAnimTime, fTimespan);
+ m_fBlur2Min .StartBlendFrom(&s_from->m_fBlur2Min , fAnimTime, fTimespan);
+ m_fBlur3Min .StartBlendFrom(&s_from->m_fBlur3Min , fAnimTime, fTimespan);
+ m_fBlur1Max .StartBlendFrom(&s_from->m_fBlur1Max , fAnimTime, fTimespan);
+ m_fBlur2Max .StartBlendFrom(&s_from->m_fBlur2Max , fAnimTime, fTimespan);
+ m_fBlur3Max .StartBlendFrom(&s_from->m_fBlur3Max , fAnimTime, fTimespan);
+ m_fBlur1EdgeDarken .StartBlendFrom(&s_from->m_fBlur1EdgeDarken , fAnimTime, fTimespan);
+
+ // if motion vectors were transparent before, don't morph the # in X and Y - just
+ // start in the right place, and fade them in.
+ bool bOldStateTransparent = (s_from->m_fMvA.eval(-1) < 0.001f);
+ bool bNewStateTransparent = (s_to->m_fMvA.eval(-1) < 0.001f);
+ if (!bOldStateTransparent && bNewStateTransparent)
+ {
+ s_from->m_fMvX = s_to->m_fMvX.eval(fAnimTime);
+ s_from->m_fMvY = s_to->m_fMvY.eval(fAnimTime);
+ s_from->m_fMvDX = s_to->m_fMvDX.eval(fAnimTime);
+ s_from->m_fMvDY = s_to->m_fMvDY.eval(fAnimTime);
+ s_from->m_fMvL = s_to->m_fMvL.eval(fAnimTime);
+ s_from->m_fMvR = s_to->m_fMvR.eval(fAnimTime);
+ s_from->m_fMvG = s_to->m_fMvG.eval(fAnimTime);
+ s_from->m_fMvB = s_to->m_fMvB.eval(fAnimTime);
+ }
+ if (bNewStateTransparent && !bOldStateTransparent)
+ {
+ s_to->m_fMvX = s_from->m_fMvX.eval(fAnimTime);
+ s_to->m_fMvY = s_from->m_fMvY.eval(fAnimTime);
+ s_to->m_fMvDX = s_from->m_fMvDX.eval(fAnimTime);
+ s_to->m_fMvDY = s_from->m_fMvDY.eval(fAnimTime);
+ s_to->m_fMvL = s_from->m_fMvL.eval(fAnimTime);
+ s_to->m_fMvR = s_from->m_fMvR.eval(fAnimTime);
+ s_to->m_fMvG = s_from->m_fMvG.eval(fAnimTime);
+ s_to->m_fMvB = s_from->m_fMvB.eval(fAnimTime);
+ }
+
+}
+
+void WriteCode(FILE* fOut, int i, char* pStr, char* prefix, bool bPrependApostrophe = false)
+{
+ char szLineName[32];
+ int line = 1;
+ int start_pos = 0;
+ int char_pos = 0;
+
+ while (pStr[start_pos] != 0)
+ {
+ while ( pStr[char_pos] != 0 &&
+ pStr[char_pos] != LINEFEED_CONTROL_CHAR)
+ char_pos++;
+
+ sprintf(szLineName, "%s%d", prefix, line);
+
+ char ch = pStr[char_pos];
+ pStr[char_pos] = 0;
+ //if (!WritePrivateProfileString(szSectionName,szLineName,&pStr[start_pos],szIniFile)) return false;
+ fprintf(fOut, "%s=%s%s\n", szLineName, bPrependApostrophe ? "`" : "", &pStr[start_pos]);
+ pStr[char_pos] = ch;
+
+ if (pStr[char_pos] != 0) char_pos++;
+ start_pos = char_pos;
+ line++;
+ }
+}
+
+bool CState::Export(const wchar_t *szIniFile)
+{
+ FILE *fOut = _wfopen(szIniFile, L"w");
+ if (!fOut) return false;
+
+ // IMPORTANT: THESE MUST BE THE FIRST TWO LINES. Otherwise it is assumed to be a MilkDrop 1-era preset.
+ if (m_nMaxPSVersion > 0)
+ {
+ fprintf(fOut, "MILKDROP_PRESET_VERSION=%d\n", CUR_MILKDROP_PRESET_VERSION);
+ fprintf(fOut, "PSVERSION=%d\n" ,m_nMaxPSVersion); // the max
+ fprintf(fOut, "PSVERSION_WARP=%d\n",m_nWarpPSVersion);
+ fprintf(fOut, "PSVERSION_COMP=%d\n",m_nCompPSVersion);
+ }
+
+ // just for backwards compatibility; MilkDrop 1 can read MilkDrop 2 presets, minus the new features.
+ // (...this section name allows the GetPrivateProfile*() functions to still work on milkdrop 1)
+ fprintf(fOut, "[preset00]\n");
+
+ fprintf(fOut, "%s=%.3f\n", "fRating", m_fRating);
+ fprintf(fOut, "%s=%.3f\n", "fGammaAdj", m_fGammaAdj.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fDecay", m_fDecay.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fVideoEchoZoom", m_fVideoEchoZoom.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fVideoEchoAlpha", m_fVideoEchoAlpha.eval(-1));
+ fprintf(fOut, "%s=%d\n", "nVideoEchoOrientation", m_nVideoEchoOrientation);
+
+ fprintf(fOut, "%s=%d\n", "nWaveMode", m_nWaveMode);
+ fprintf(fOut, "%s=%d\n", "bAdditiveWaves", m_bAdditiveWaves);
+ fprintf(fOut, "%s=%d\n", "bWaveDots", m_bWaveDots);
+ fprintf(fOut, "%s=%d\n", "bWaveThick", m_bWaveThick);
+ fprintf(fOut, "%s=%d\n", "bModWaveAlphaByVolume", m_bModWaveAlphaByVolume);
+ fprintf(fOut, "%s=%d\n", "bMaximizeWaveColor", m_bMaximizeWaveColor);
+ fprintf(fOut, "%s=%d\n", "bTexWrap", m_bTexWrap );
+ fprintf(fOut, "%s=%d\n", "bDarkenCenter", m_bDarkenCenter );
+ fprintf(fOut, "%s=%d\n", "bRedBlueStereo", m_bRedBlueStereo );
+ fprintf(fOut, "%s=%d\n", "bBrighten", m_bBrighten );
+ fprintf(fOut, "%s=%d\n", "bDarken", m_bDarken );
+ fprintf(fOut, "%s=%d\n", "bSolarize", m_bSolarize );
+ fprintf(fOut, "%s=%d\n", "bInvert", m_bInvert );
+
+ fprintf(fOut, "%s=%.3f\n", "fWaveAlpha", m_fWaveAlpha.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fWaveScale", m_fWaveScale.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fWaveSmoothing", m_fWaveSmoothing.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fWaveParam", m_fWaveParam.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fModWaveAlphaStart", m_fModWaveAlphaStart.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fModWaveAlphaEnd", m_fModWaveAlphaEnd.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fWarpAnimSpeed", m_fWarpAnimSpeed);
+ fprintf(fOut, "%s=%.3f\n", "fWarpScale", m_fWarpScale.eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "fZoomExponent", m_fZoomExponent.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "fShader", m_fShader.eval(-1));
+
+ fprintf(fOut, "%s=%.5f\n", "zoom", m_fZoom .eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "rot", m_fRot .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "cx", m_fRotCX .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "cy", m_fRotCY .eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "dx", m_fXPush .eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "dy", m_fYPush .eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "warp", m_fWarpAmount.eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "sx", m_fStretchX .eval(-1));
+ fprintf(fOut, "%s=%.5f\n", "sy", m_fStretchY .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "wave_r", m_fWaveR .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "wave_g", m_fWaveG .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "wave_b", m_fWaveB .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "wave_x", m_fWaveX .eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "wave_y", m_fWaveY .eval(-1));
+
+ fprintf(fOut, "%s=%.3f\n", "ob_size", m_fOuterBorderSize.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ob_r", m_fOuterBorderR.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ob_g", m_fOuterBorderG.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ob_b", m_fOuterBorderB.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ob_a", m_fOuterBorderA.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ib_size", m_fInnerBorderSize.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ib_r", m_fInnerBorderR.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ib_g", m_fInnerBorderG.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ib_b", m_fInnerBorderB.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "ib_a", m_fInnerBorderA.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "nMotionVectorsX", m_fMvX.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "nMotionVectorsY", m_fMvY.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_dx", m_fMvDX.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_dy", m_fMvDY.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_l", m_fMvL.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_r", m_fMvR.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_g", m_fMvG.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_b", m_fMvB.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "mv_a", m_fMvA.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b1n", m_fBlur1Min.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b2n", m_fBlur2Min.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b3n", m_fBlur3Min.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b1x", m_fBlur1Max.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b2x", m_fBlur2Max.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b3x", m_fBlur3Max.eval(-1));
+ fprintf(fOut, "%s=%.3f\n", "b1ed", m_fBlur1EdgeDarken.eval(-1));
+
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ m_wave[i].Export(fOut, L"dummy_filename", i);
+
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ m_shape[i].Export(fOut, L"dummy_filename", i);
+
+ // write out arbitrary expressions, one line at a time
+ WriteCode(fOut, i, m_szPerFrameInit, "per_frame_init_");
+ WriteCode(fOut, i, m_szPerFrameExpr, "per_frame_");
+ WriteCode(fOut, i, m_szPerPixelExpr, "per_pixel_");
+ if (m_nWarpPSVersion >= MD2_PS_2_0)
+ WriteCode(fOut, i, m_szWarpShadersText, "warp_", true);
+ if (m_nCompPSVersion >= MD2_PS_2_0)
+ WriteCode(fOut, i, m_szCompShadersText, "comp_", true);
+
+ fclose(fOut);
+
+ return true;
+}
+
+int CWave::Export(FILE* fOut, const wchar_t *szFile, int i)
+{
+ FILE* f2 = fOut;
+ if (!fOut)
+ {
+ f2 = _wfopen(szFile, L"w");
+ if (!f2) return 0;
+ }
+
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "enabled", enabled);
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "samples", samples);
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "sep", sep );
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "bSpectrum", bSpectrum);
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "bUseDots", bUseDots);
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "bDrawThick", bDrawThick);
+ fprintf(f2, "wavecode_%d_%s=%d\n", i, "bAdditive", bAdditive);
+ fprintf(f2, "wavecode_%d_%s=%.5f\n", i, "scaling", scaling);
+ fprintf(f2, "wavecode_%d_%s=%.5f\n", i, "smoothing", smoothing);
+ fprintf(f2, "wavecode_%d_%s=%.3f\n", i, "r", r);
+ fprintf(f2, "wavecode_%d_%s=%.3f\n", i, "g", g);
+ fprintf(f2, "wavecode_%d_%s=%.3f\n", i, "b", b);
+ fprintf(f2, "wavecode_%d_%s=%.3f\n", i, "a", a);
+
+ // READ THE CODE IN
+ char prefix[64];
+ sprintf(prefix, "wave_%d_init", i); WriteCode(f2, i, m_szInit, prefix);
+ sprintf(prefix, "wave_%d_per_frame", i); WriteCode(f2, i, m_szPerFrame, prefix);
+ sprintf(prefix, "wave_%d_per_point", i); WriteCode(f2, i, m_szPerPoint, prefix);
+
+ if (!fOut)
+ fclose(f2); // [sic]
+
+ return 1;
+}
+
+int CShape::Export(FILE* fOut, const wchar_t *szFile, int i)
+{
+ FILE* f2 = fOut;
+ if (!fOut)
+ {
+ f2 = _wfopen(szFile, L"w");
+ if (!f2) return 0;
+ //fprintf(f2, "[%s]\n", szSection);
+ }
+
+ fprintf(f2, "shapecode_%d_%s=%d\n", i, "enabled", enabled);
+ fprintf(f2, "shapecode_%d_%s=%d\n", i, "sides", sides);
+ fprintf(f2, "shapecode_%d_%s=%d\n", i, "additive", additive);
+ fprintf(f2, "shapecode_%d_%s=%d\n", i, "thickOutline",thickOutline);
+ fprintf(f2, "shapecode_%d_%s=%d\n", i, "textured", textured);
+ fprintf(f2, "shapecode_%d_%s=%d\n", i, "num_inst", instances);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "x", x);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "y", y);
+ fprintf(f2, "shapecode_%d_%s=%.5f\n", i, "rad", rad);
+ fprintf(f2, "shapecode_%d_%s=%.5f\n", i, "ang", ang);
+ fprintf(f2, "shapecode_%d_%s=%.5f\n", i, "tex_ang", tex_ang);
+ fprintf(f2, "shapecode_%d_%s=%.5f\n", i, "tex_zoom", tex_zoom);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "r", r);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "g", g);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "b", b);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "a", a);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "r2", r2);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "g2", g2);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "b2", b2);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "a2", a2);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "border_r", border_r);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "border_g", border_g);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "border_b", border_b);
+ fprintf(f2, "shapecode_%d_%s=%.3f\n", i, "border_a", border_a);
+
+ char prefix[64];
+ sprintf(prefix, "shape_%d_init", i); WriteCode(f2, i, m_szInit, prefix);
+ sprintf(prefix, "shape_%d_per_frame", i); WriteCode(f2, i, m_szPerFrame, prefix);
+ //sprintf(prefix, "shape_%d_per_point", i); WriteCode(f2, i, m_szPerPoint, prefix);
+
+ if (!fOut)
+ fclose(f2); // [sic]
+
+ return 1;
+}
+
+void ReadCode(FILE* f, char* pStr, char* prefix)
+{
+ if (!pStr)
+ return;
+ pStr[0] = 0;
+
+ // read in & compile arbitrary expressions
+ char szLineName[32];
+ char szLine[MAX_BIGSTRING_LEN];
+ int len;
+
+ int line = 1;
+ int char_pos = 0;
+ bool bDone = false;
+
+ while (!bDone)
+ {
+ sprintf(szLineName, "%s%d", prefix, line);
+
+ GetFastString(szLineName, "~!@#$", szLine, MAX_BIGSTRING_LEN, f); // fixme
+ len = strlen(szLine);
+
+ if ((strcmp(szLine, "~!@#$")==0) || // if the key was missing,
+ (len >= MAX_BIGSTRING_LEN-1-char_pos-1)) // or if we're out of space
+ {
+ bDone = true;
+ }
+ else
+ {
+ sprintf(&pStr[char_pos], "%s%c", (szLine[0]=='`') ? &szLine[1] : szLine, LINEFEED_CONTROL_CHAR);
+ if (szLine[0] == '`')
+ len--;
+ }
+
+ char_pos += len + 1;
+ line++;
+ }
+ pStr[char_pos++] = 0; // null-terminate
+
+ // read in & compile arbitrary expressions
+ /*
+ int n2 = 3 + MAX_CUSTOM_WAVES*3 + MAX_CUSTOM_SHAPES*2;
+ for (int n=0; n<n2; n++)
+ {
+ char *pStr;
+ char prefix[64];
+ char szLineName[32];
+ char szLine[MAX_BIGSTRING_LEN];
+ int len;
+
+ int line = 1;
+ int char_pos = 0;
+ bool bDone = false;
+
+ switch(n)
+ {
+ case 0: pStr = m_szPerFrameExpr; strcpy(prefix, "per_frame_"); break;
+ case 1: pStr = m_szPerPixelExpr; strcpy(prefix, "per_pixel_"); break;
+ case 2: pStr = m_szPerFrameInit; strcpy(prefix, "per_frame_init_"); break;
+ default:
+ if (n < 3 + 3*MAX_CUSTOM_WAVES)
+ {
+ int i = (n-3) / 3;
+ int j = (n-3) % 3;
+ switch(j)
+ {
+ case 0: pStr = m_wave[i].m_szInit; sprintf(prefix, "wave_%d_init", i); break;
+ case 1: pStr = m_wave[i].m_szPerFrame; sprintf(prefix, "wave_%d_per_frame", i); break;
+ case 2: pStr = m_wave[i].m_szPerPoint; sprintf(prefix, "wave_%d_per_point", i); break;
+ }
+ }
+ else
+ {
+ int i = (n-3-3*MAX_CUSTOM_WAVES) / 2;
+ int j = (n-3-3*MAX_CUSTOM_WAVES) % 2;
+ switch(j)
+ {
+ case 0: pStr = m_shape[i].m_szInit; sprintf(prefix, "shape_%d_init", i); break;
+ case 1: pStr = m_shape[i].m_szPerFrame; sprintf(prefix, "shape_%d_per_frame", i); break;
+ }
+ }
+ }
+
+ while (!bDone)
+ {
+ sprintf(szLineName, "%s%d", prefix, line);
+
+ GetPrivateProfileString(szSectionName, szLineName, "~!@#$", szLine, MAX_BIGSTRING_LEN, szIniFile); // fixme
+ len = strlen(szLine);
+
+ if ((strcmp(szLine, "~!@#$")==0) || // if the key was missing,
+ (len >= MAX_BIGSTRING_LEN-1-char_pos-1)) // or if we're out of space
+ {
+ bDone = true;
+ }
+ else
+ {
+ sprintf(&pStr[char_pos], "%s%c", szLine, LINEFEED_CONTROL_CHAR);
+ }
+
+ char_pos += len + 1;
+ line++;
+ }
+ pStr[char_pos++] = 0; // null-terminate
+ }
+ */
+}
+
+int CWave::Import(FILE* f, const wchar_t* szFile, int i)
+{
+ FILE* f2 = f;
+ if (!f)
+ {
+ f2 = _wfopen(szFile, L"rb");
+ if (!f2) return 0;
+ GetFast_CLEAR();
+ }
+
+ char buf[64];
+ sprintf(buf, "wavecode_%d_%s", i, "enabled" ); enabled = GetFastInt (buf, enabled , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "samples" ); samples = GetFastInt (buf, samples , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "sep" ); sep = GetFastInt (buf, sep , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "bSpectrum" ); bSpectrum = GetFastInt (buf, bSpectrum , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "bUseDots" ); bUseDots = GetFastInt (buf, bUseDots , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "bDrawThick"); bDrawThick = GetFastInt (buf, bDrawThick, f2);
+ sprintf(buf, "wavecode_%d_%s", i, "bAdditive" ); bAdditive = GetFastInt (buf, bAdditive , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "scaling" ); scaling = GetFastFloat(buf, scaling , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "smoothing" ); smoothing = GetFastFloat(buf, smoothing , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "r" ); r = GetFastFloat(buf, r , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "g" ); g = GetFastFloat(buf, g , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "b" ); b = GetFastFloat(buf, b , f2);
+ sprintf(buf, "wavecode_%d_%s", i, "a" ); a = GetFastFloat(buf, a , f2);
+
+ // READ THE CODE IN
+ char prefix[64];
+ sprintf(prefix, "wave_%d_init", i); ReadCode(f2, m_szInit, prefix);
+ sprintf(prefix, "wave_%d_per_frame", i); ReadCode(f2, m_szPerFrame, prefix);
+ sprintf(prefix, "wave_%d_per_point", i); ReadCode(f2, m_szPerPoint, prefix);
+
+ if (!f)
+ fclose(f2); // [sic]
+
+ return 1;
+}
+
+int CShape::Import(FILE* f, const wchar_t* szFile, int i)
+{
+ FILE* f2 = f;
+ if (!f)
+ {
+ f2 = _wfopen(szFile, L"rb");
+ if (!f2) return 0;
+ GetFast_CLEAR();
+ }
+
+ char buf[64];
+ sprintf(buf, "shapecode_%d_%s", i, "enabled" ); enabled = GetFastInt (buf, enabled , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "sides" ); sides = GetFastInt (buf, sides , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "additive" ); additive = GetFastInt (buf, additive , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "thickOutline"); thickOutline = GetFastInt (buf, thickOutline, f2);
+ sprintf(buf, "shapecode_%d_%s", i, "textured" ); textured = GetFastInt (buf, textured , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "num_inst" ); instances = GetFastInt (buf, instances , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "x" ); x = GetFastFloat(buf, x , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "y" ); y = GetFastFloat(buf, y , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "rad" ); rad = GetFastFloat(buf, rad , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "ang" ); ang = GetFastFloat(buf, ang , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "tex_ang" ); tex_ang = GetFastFloat(buf, tex_ang , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "tex_zoom" ); tex_zoom = GetFastFloat(buf, tex_zoom , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "r" ); r = GetFastFloat(buf, r , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "g" ); g = GetFastFloat(buf, g , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "b" ); b = GetFastFloat(buf, b , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "a" ); a = GetFastFloat(buf, a , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "r2" ); r2 = GetFastFloat(buf, r2 , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "g2" ); g2 = GetFastFloat(buf, g2 , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "b2" ); b2 = GetFastFloat(buf, b2 , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "a2" ); a2 = GetFastFloat(buf, a2 , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "border_r" ); border_r = GetFastFloat(buf, border_r , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "border_g" ); border_g = GetFastFloat(buf, border_g , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "border_b" ); border_b = GetFastFloat(buf, border_b , f2);
+ sprintf(buf, "shapecode_%d_%s", i, "border_a" ); border_a = GetFastFloat(buf, border_a , f2);
+
+ // READ THE CODE IN
+ char prefix[64];
+ sprintf(prefix, "shape_%d_init", i); ReadCode(f2, m_szInit, prefix);
+ sprintf(prefix, "shape_%d_per_frame", i); ReadCode(f2, m_szPerFrame, prefix);
+
+ if (!f)
+ fclose(f2); // [sic]
+
+ return 1;
+}
+
+bool CState::Import(const wchar_t *szIniFile, float fTime, CState* pOldState, DWORD ApplyFlags)
+{
+ // if any ApplyFlags are missing, the settings will be copied from pOldState. =)
+
+ if (!pOldState)
+ ApplyFlags = STATE_ALL;
+
+ if (ApplyFlags!=STATE_ALL && this != pOldState)
+ {
+ assert(pOldState);
+ // in order to copy the old state, we have to byte copy it.
+ memcpy(this, pOldState, sizeof(CState));
+ // clear all the copied code pointers, WITHOUT actually freeing it (since ptrs were copied)
+ // so that the Default() call below won't release pOldState's copied pointers.
+ // [all expressions will be recompiled @ end of this fn, whether we updated them or not]
+ FreeVarsAndCode(false);
+ }
+
+ // apply defaults for the stuff we will overwrite.
+ Default(ApplyFlags);//RandomizePresetVars();
+
+ GetFast_CLEAR();
+
+ if ( (ApplyFlags & STATE_GENERAL) && // check for these 3 @ same time,
+ (ApplyFlags & STATE_MOTION) && // so a preset switch w/ warp/comp lock
+ (ApplyFlags & STATE_WAVE) // updates the name, but mash-ups don't.
+ )
+ {
+ m_fPresetStartTime = fTime;
+
+ // extract a description of the preset from the filename
+ {
+ // copy get the filename (without the path)
+ const wchar_t *p = wcsrchr(szIniFile, '\\');
+ if (p==NULL) p = szIniFile;
+ lstrcpyW(m_szDesc, p+1);
+
+ // next remove the extension
+ RemoveExtension(m_szDesc);
+ }
+ }
+
+ FILE* f = _wfopen(szIniFile, L"rb");
+ if (!f)
+ return false;
+
+ int nMilkdropPresetVersion = GetFastInt("MILKDROP_PRESET_VERSION",100,f);
+ //if (ApplyFlags != STATE_ALL)
+ // nMilkdropPresetVersion = CUR_MILKDROP_PRESET_VERSION; //if we're mashing up, force it up to now
+
+
+ int nWarpPSVersionInFile;
+ int nCompPSVersionInFile;
+ if (nMilkdropPresetVersion < 200) {
+ nWarpPSVersionInFile = 0;
+ nCompPSVersionInFile = 0;
+ }
+ else if (nMilkdropPresetVersion == 200) {
+ nWarpPSVersionInFile = GetFastInt("PSVERSION", 2, f);
+ nCompPSVersionInFile = nWarpPSVersionInFile;
+ }
+ else {
+ nWarpPSVersionInFile = GetFastInt("PSVERSION_WARP", 2, f);
+ nCompPSVersionInFile = GetFastInt("PSVERSION_COMP", 2, f);
+ }
+
+ // general:
+ if (ApplyFlags & STATE_GENERAL)
+ {
+ m_fRating = GetFastFloat("fRating",m_fRating,f);
+ m_fDecay = GetFastFloat("fDecay",m_fDecay.eval(-1),f);
+ m_fGammaAdj = GetFastFloat("fGammaAdj" ,m_fGammaAdj.eval(-1),f);
+ m_fVideoEchoZoom = GetFastFloat("fVideoEchoZoom",m_fVideoEchoZoom.eval(-1),f);
+ m_fVideoEchoAlpha = GetFastFloat("fVideoEchoAlpha",m_fVideoEchoAlpha.eval(-1),f);
+ m_nVideoEchoOrientation = GetFastInt ("nVideoEchoOrientation",m_nVideoEchoOrientation,f);
+ m_bRedBlueStereo = (GetFastInt ("bRedBlueStereo", m_bRedBlueStereo,f) != 0);
+ m_bBrighten = (GetFastInt ("bBrighten",m_bBrighten ,f) != 0);
+ m_bDarken = (GetFastInt ("bDarken" ,m_bDarken ,f) != 0);
+ m_bSolarize = (GetFastInt ("bSolarize",m_bSolarize ,f) != 0);
+ m_bInvert = (GetFastInt ("bInvert" ,m_bInvert ,f) != 0);
+ m_fShader = GetFastFloat("fShader",m_fShader.eval(-1),f);
+ m_fBlur1Min = GetFastFloat("b1n", m_fBlur1Min.eval(-1),f);
+ m_fBlur2Min = GetFastFloat("b2n", m_fBlur2Min.eval(-1),f);
+ m_fBlur3Min = GetFastFloat("b3n", m_fBlur3Min.eval(-1),f);
+ m_fBlur1Max = GetFastFloat("b1x", m_fBlur1Max.eval(-1),f);
+ m_fBlur2Max = GetFastFloat("b2x", m_fBlur2Max.eval(-1),f);
+ m_fBlur3Max = GetFastFloat("b3x", m_fBlur3Max.eval(-1),f);
+ m_fBlur1EdgeDarken = GetFastFloat("b1ed", m_fBlur1EdgeDarken.eval(-1),f);
+ }
+
+ // wave:
+ if (ApplyFlags & STATE_WAVE)
+ {
+ m_nWaveMode = GetFastInt ("nWaveMode",m_nWaveMode,f);
+ m_bAdditiveWaves = (GetFastInt ("bAdditiveWaves",m_bAdditiveWaves,f) != 0);
+ m_bWaveDots = (GetFastInt ("bWaveDots",m_bWaveDots,f) != 0);
+ m_bWaveThick = (GetFastInt ("bWaveThick",m_bWaveThick,f) != 0);
+ m_bModWaveAlphaByVolume = (GetFastInt ("bModWaveAlphaByVolume",m_bModWaveAlphaByVolume,f) != 0);
+ m_bMaximizeWaveColor = (GetFastInt ("bMaximizeWaveColor" ,m_bMaximizeWaveColor,f) != 0);
+ m_fWaveAlpha = GetFastFloat("fWaveAlpha",m_fWaveAlpha.eval(-1),f);
+ m_fWaveScale = GetFastFloat("fWaveScale",m_fWaveScale.eval(-1),f);
+ m_fWaveSmoothing = GetFastFloat("fWaveSmoothing",m_fWaveSmoothing.eval(-1),f);
+ m_fWaveParam = GetFastFloat("fWaveParam",m_fWaveParam.eval(-1),f);
+ m_fModWaveAlphaStart = GetFastFloat("fModWaveAlphaStart",m_fModWaveAlphaStart.eval(-1),f);
+ m_fModWaveAlphaEnd = GetFastFloat("fModWaveAlphaEnd",m_fModWaveAlphaEnd.eval(-1),f);
+ m_fWaveR = GetFastFloat("wave_r",m_fRot.eval(-1),f);
+ m_fWaveG = GetFastFloat("wave_g",m_fRot.eval(-1),f);
+ m_fWaveB = GetFastFloat("wave_b",m_fRot.eval(-1),f);
+ m_fWaveX = GetFastFloat("wave_x",m_fRot.eval(-1),f);
+ m_fWaveY = GetFastFloat("wave_y",m_fRot.eval(-1),f);
+ m_fMvX = GetFastFloat("nMotionVectorsX", m_fMvX.eval(-1),f);
+ m_fMvY = GetFastFloat("nMotionVectorsY", m_fMvY.eval(-1),f);
+ m_fMvDX = GetFastFloat("mv_dx", m_fMvDX.eval(-1),f);
+ m_fMvDY = GetFastFloat("mv_dy", m_fMvDY.eval(-1),f);
+ m_fMvL = GetFastFloat("mv_l", m_fMvL.eval(-1),f);
+ m_fMvR = GetFastFloat("mv_r", m_fMvR.eval(-1),f);
+ m_fMvG = GetFastFloat("mv_g", m_fMvG.eval(-1),f);
+ m_fMvB = GetFastFloat("mv_b", m_fMvB.eval(-1),f);
+ m_fMvA = (GetFastInt ("bMotionVectorsOn",false,f) == 0) ? 0.0f : 1.0f; // for backwards compatibility
+ m_fMvA = GetFastFloat("mv_a", m_fMvA.eval(-1),f);
+
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ m_wave[i].Import(f, L"dummy_filename", i);
+ }
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ m_shape[i].Import(f, L"dummy_filename", i);
+ }
+ }
+
+ // motion:
+ if (ApplyFlags & STATE_MOTION)
+ {
+ m_fZoom = GetFastFloat("zoom",m_fZoom.eval(-1),f);
+ m_fRot = GetFastFloat("rot",m_fRot.eval(-1),f);
+ m_fRotCX = GetFastFloat("cx",m_fRotCX.eval(-1),f);
+ m_fRotCY = GetFastFloat("cy",m_fRotCY.eval(-1),f);
+ m_fXPush = GetFastFloat("dx",m_fXPush.eval(-1),f);
+ m_fYPush = GetFastFloat("dy",m_fYPush.eval(-1),f);
+ m_fWarpAmount = GetFastFloat("warp",m_fWarpAmount.eval(-1),f);
+ m_fStretchX = GetFastFloat("sx",m_fStretchX.eval(-1),f);
+ m_fStretchY = GetFastFloat("sy",m_fStretchY.eval(-1),f);
+ m_bTexWrap = (GetFastInt ("bTexWrap", m_bTexWrap,f) != 0);
+ m_bDarkenCenter = (GetFastInt ("bDarkenCenter", m_bDarkenCenter,f) != 0);
+ m_fWarpAnimSpeed = GetFastFloat("fWarpAnimSpeed",m_fWarpAnimSpeed,f);
+ m_fWarpScale = GetFastFloat("fWarpScale",m_fWarpScale.eval(-1),f);
+ m_fZoomExponent = GetFastFloat("fZoomExponent",m_fZoomExponent.eval(-1),f);
+ m_fOuterBorderSize = GetFastFloat("ob_size",m_fOuterBorderSize.eval(-1),f);
+ m_fOuterBorderR = GetFastFloat("ob_r", m_fOuterBorderR.eval(-1),f);
+ m_fOuterBorderG = GetFastFloat("ob_g", m_fOuterBorderG.eval(-1),f);
+ m_fOuterBorderB = GetFastFloat("ob_b", m_fOuterBorderB.eval(-1),f);
+ m_fOuterBorderA = GetFastFloat("ob_a", m_fOuterBorderA.eval(-1),f);
+ m_fInnerBorderSize = GetFastFloat("ib_size",m_fInnerBorderSize.eval(-1),f);
+ m_fInnerBorderR = GetFastFloat("ib_r", m_fInnerBorderR.eval(-1),f);
+ m_fInnerBorderG = GetFastFloat("ib_g", m_fInnerBorderG.eval(-1),f);
+ m_fInnerBorderB = GetFastFloat("ib_b", m_fInnerBorderB.eval(-1),f);
+ m_fInnerBorderA = GetFastFloat("ib_a", m_fInnerBorderA.eval(-1),f);
+ //m_szPerFrameInit[0] = 0;
+ //m_szPerFrameExpr[0] = 0;
+ //m_szPerPixelExpr[0] = 0;
+ ReadCode(f, m_szPerFrameInit, "per_frame_init_");
+ ReadCode(f, m_szPerFrameExpr, "per_frame_");
+ ReadCode(f, m_szPerPixelExpr, "per_pixel_");
+ }
+
+ // warp shader
+ if (ApplyFlags & STATE_WARP)
+ {
+ //m_szWarpShadersText[0] = 0;
+ ReadCode(f, m_szWarpShadersText, "warp_");
+ if (!m_szWarpShadersText[0])
+ g_plugin.GenWarpPShaderText(m_szWarpShadersText, m_fDecay.eval(-1), m_bTexWrap);
+ m_nWarpPSVersion = nWarpPSVersionInFile;
+ }
+
+ // comp shader
+ if (ApplyFlags & STATE_COMP)
+ {
+ //m_szCompShadersText[0] = 0;
+ ReadCode(f, m_szCompShadersText, "comp_");
+ if (!m_szCompShadersText[0])
+ g_plugin.GenCompPShaderText(m_szCompShadersText, m_fGammaAdj.eval(-1), m_fVideoEchoAlpha.eval(-1), m_fVideoEchoZoom.eval(-1), m_nVideoEchoOrientation, m_fShader.eval(-1), m_bBrighten, m_bDarken, m_bSolarize, m_bInvert);
+ m_nCompPSVersion = nCompPSVersionInFile;
+ }
+
+ m_nMaxPSVersion = max(m_nWarpPSVersion, m_nCompPSVersion);
+ m_nMinPSVersion = min(m_nWarpPSVersion, m_nCompPSVersion);
+
+
+ RecompileExpressions();
+
+ fclose(f);
+
+ return true;
+}
+
+void CState::GenDefaultWarpShader()
+{
+ if (m_nWarpPSVersion>0)
+ g_plugin.GenWarpPShaderText(m_szWarpShadersText, m_fDecay.eval(-1), m_bTexWrap);
+}
+void CState::GenDefaultCompShader()
+{
+ if (m_nCompPSVersion>0)
+ g_plugin.GenCompPShaderText(m_szCompShadersText, m_fGammaAdj.eval(-1), m_fVideoEchoAlpha.eval(-1), m_fVideoEchoZoom.eval(-1), m_nVideoEchoOrientation, m_fShader.eval(-1), m_bBrighten, m_bDarken, m_bSolarize, m_bInvert);
+}
+
+void CState::FreeVarsAndCode(bool bFree)
+{
+ // free the compiled expressions
+ if (m_pf_codehandle)
+ {
+ if (bFree)
+ NSEEL_code_free(m_pf_codehandle);
+ m_pf_codehandle = NULL;
+ }
+ if (m_pp_codehandle)
+ {
+ if (bFree)
+ NSEEL_code_free(m_pp_codehandle);
+ m_pp_codehandle = NULL;
+ }
+
+ int i = 0;
+ for (i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ if (m_wave[i].m_pf_codehandle)
+ {
+ if (bFree)
+ NSEEL_code_free(m_wave[i].m_pf_codehandle);
+ m_wave[i].m_pf_codehandle = NULL;
+ }
+ if (m_wave[i].m_pp_codehandle)
+ {
+ if (bFree)
+ NSEEL_code_free(m_wave[i].m_pp_codehandle);
+ m_wave[i].m_pp_codehandle = NULL;
+ }
+ }
+
+ for (i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ if (m_shape[i].m_pf_codehandle)
+ {
+ if (bFree)
+ NSEEL_code_free(m_shape[i].m_pf_codehandle);
+ m_shape[i].m_pf_codehandle = NULL;
+ }
+ /*if (m_shape[i].m_pp_codehandle)
+ {
+ freeCode(m_shape[i].m_pp_codehandle);
+ m_shape[i].m_pp_codehandle = NULL;
+ }*/
+ }
+
+ // free our text version of the expressions? - no!
+ //m_szPerFrameExpr[0] = 0;
+ //m_szPerPixelExpr[0] = 0;
+
+ // free the old variable names & reregister the built-in variables (since they got nuked too)
+ RegisterBuiltInVariables(0xFFFFFFFF);
+}
+
+void CState::StripLinefeedCharsAndComments(char *src, char *dest)
+{
+ // replaces all LINEFEED_CONTROL_CHAR characters in src with a space in dest;
+ // also strips out all comments (beginning with '//' and going til end of line).
+ // Restriction: sizeof(dest) must be >= sizeof(src).
+
+ int i2 = 0;
+ int len = strlen(src);
+ int bComment = false;
+ for (int i=0; i<len; i++)
+ {
+ if (bComment)
+ {
+ if (src[i] == LINEFEED_CONTROL_CHAR)
+ bComment = false;
+ }
+ else
+ {
+ if ((src[i] =='\\' && src[i+1] =='\\') || (src[i] =='/' && src[i+1] =='/'))
+ bComment = true;
+ else if (src[i] != LINEFEED_CONTROL_CHAR)
+ dest[i2++] = src[i];
+ }
+ }
+ dest[i2] = 0;
+}
+
+void CState::RecompileExpressions(int flags, int bReInit)
+{
+ // before we get started, if we redo the init code for the preset, we have to redo
+ // other things too, because q1-q8 could change.
+ if ((flags & RECOMPILE_PRESET_CODE) && bReInit)
+ {
+ flags |= RECOMPILE_WAVE_CODE;
+ flags |= RECOMPILE_SHAPE_CODE;
+ }
+
+ // free old code handles
+ if (flags & RECOMPILE_PRESET_CODE)
+ {
+ if (m_pf_codehandle)
+ {
+ NSEEL_code_free(m_pf_codehandle);
+ m_pf_codehandle = NULL;
+ }
+ if (m_pp_codehandle)
+ {
+ NSEEL_code_free(m_pp_codehandle);
+ m_pp_codehandle = NULL;
+ }
+ }
+ if (flags & RECOMPILE_WAVE_CODE)
+ {
+ for (int i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ if (m_wave[i].m_pf_codehandle)
+ {
+ NSEEL_code_free(m_wave[i].m_pf_codehandle);
+ m_wave[i].m_pf_codehandle = NULL;
+ }
+ if (m_wave[i].m_pp_codehandle)
+ {
+ NSEEL_code_free(m_wave[i].m_pp_codehandle);
+ m_wave[i].m_pp_codehandle = NULL;
+ }
+ }
+ }
+ if (flags & RECOMPILE_SHAPE_CODE)
+ {
+ for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ if (m_shape[i].m_pf_codehandle)
+ {
+ NSEEL_code_free(m_shape[i].m_pf_codehandle);
+ m_shape[i].m_pf_codehandle = NULL;
+ }
+ /*if (m_shape[i].m_pp_codehandle)
+ {
+ freeCode(m_shape[i].m_pp_codehandle);
+ m_shape[i].m_pp_codehandle = NULL;
+ }*/
+ }
+ }
+
+ // if we're recompiling init code, clear vars to zero, and re-register built-in variables.
+ if (bReInit)
+ {
+ RegisterBuiltInVariables(flags);
+ }
+
+ // QUICK FIX: if the code strings ONLY have spaces and linefeeds, erase them,
+ // because for some strange reason this causes errors in compileCode().
+ int n2 = 3 + MAX_CUSTOM_WAVES*3 + MAX_CUSTOM_SHAPES*2;
+ for (int n=0; n<n2; n++)
+ {
+ char *pOrig;
+ switch(n)
+ {
+ case 0: pOrig = m_szPerFrameExpr; break;
+ case 1: pOrig = m_szPerPixelExpr; break;
+ case 2: pOrig = m_szPerFrameInit; break;
+ default:
+ if (n < 3 + 3*MAX_CUSTOM_WAVES)
+ {
+ int i = (n-3) / 3;
+ int j = (n-3) % 3;
+ switch(j)
+ {
+ case 0: pOrig = m_wave[i].m_szInit; break;
+ case 1: pOrig = m_wave[i].m_szPerFrame; break;
+ case 2: pOrig = m_wave[i].m_szPerPoint; break;
+ }
+ }
+ else
+ {
+ int i = (n-3-3*MAX_CUSTOM_WAVES) / 2;
+ int j = (n-3-3*MAX_CUSTOM_WAVES) % 2;
+ switch(j)
+ {
+ case 0: pOrig = m_shape[i].m_szInit; break;
+ case 1: pOrig = m_shape[i].m_szPerFrame; break;
+ }
+ }
+ }
+ char *p = pOrig;
+ while (*p==' ' || *p==LINEFEED_CONTROL_CHAR) p++;
+ if (*p == 0) pOrig[0] = 0;
+ }
+
+ // COMPILE NEW CODE.
+ #ifndef _NO_EXPR_
+ {
+ // clear any old error msg.:
+ //g_plugin.m_fShowUserMessageUntilThisTime = g_plugin.GetTime();
+
+ char buf[MAX_BIGSTRING_LEN*3];
+
+ if (flags & RECOMPILE_PRESET_CODE)
+ {
+ // 1. compile AND EXECUTE preset init code
+ StripLinefeedCharsAndComments(m_szPerFrameInit, buf);
+ if (buf[0] && bReInit)
+ {
+ NSEEL_CODEHANDLE pf_codehandle_init;
+
+ if ( ! (pf_codehandle_init = NSEEL_code_compile(m_pf_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_PRESET_INIT_CODE), m_szDesc);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+
+ for (int vi=0; vi<NUM_Q_VAR; vi++)
+ q_values_after_init_code[vi] = 0;
+ monitor_after_init_code = 0;
+ }
+ else
+ {
+ // now execute the code, save the values of q1..q32, and clean up the code!
+
+ g_plugin.LoadPerFrameEvallibVars(g_plugin.m_pState);
+
+ NSEEL_code_execute(pf_codehandle_init);
+
+ for (int vi=0; vi<NUM_Q_VAR; vi++)
+ q_values_after_init_code[vi] = *var_pf_q[vi];
+ monitor_after_init_code = *var_pf_monitor;
+
+ NSEEL_code_free(pf_codehandle_init);
+ pf_codehandle_init = NULL;
+ }
+ }
+
+ // 2. compile preset per-frame code
+ StripLinefeedCharsAndComments(m_szPerFrameExpr, buf);
+ if (buf[0])
+ {
+ if ( ! (m_pf_codehandle = NSEEL_code_compile(m_pf_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_PER_FRAME_CODE), m_szDesc);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ }
+
+ // 3. compile preset per-pixel code
+ StripLinefeedCharsAndComments(m_szPerPixelExpr, buf);
+ if (buf[0])
+ {
+ if ( ! (m_pp_codehandle = NSEEL_code_compile(m_pv_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_PER_VERTEX_CODE), m_szDesc);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ }
+
+ //resetVars(NULL);
+ }
+
+ if (flags & RECOMPILE_WAVE_CODE)
+ {
+ for (int i=0; i<MAX_CUSTOM_WAVES; i++)
+ {
+ // 1. compile AND EXECUTE custom waveform init code
+ StripLinefeedCharsAndComments(m_wave[i].m_szInit, buf);
+ if (buf[0] && bReInit)
+ {
+ #ifndef _NO_EXPR_
+ {
+ NSEEL_CODEHANDLE codehandle_temp;
+ if ( ! (codehandle_temp = NSEEL_code_compile(m_wave[i].m_pf_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_INIT_CODE), m_szDesc, i);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ *m_wave[i].var_pf_q[vi] = q_values_after_init_code[vi];
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ m_wave[i].t_values_after_init_code[vi] = 0;
+ }
+ else
+ {
+ // now execute the code, save the values of t1..t8, and clean up the code!
+
+ g_plugin.LoadCustomWavePerFrameEvallibVars(g_plugin.m_pState, i);
+ // note: q values at this point will actually be same as
+ // q_values_after_init_code[], since no per-frame code
+ // has actually been executed yet!
+
+ NSEEL_code_execute(codehandle_temp);
+
+ for (int vi=0; vi<NUM_T_VAR; vi++)
+ m_wave[i].t_values_after_init_code[vi] = *m_wave[i].var_pf_t[vi];
+
+ NSEEL_code_free(codehandle_temp);
+ codehandle_temp = NULL;
+ }
+ }
+ #endif
+ }
+
+ // 2. compile custom waveform per-frame code
+ StripLinefeedCharsAndComments(m_wave[i].m_szPerFrame, buf);
+ if (buf[0])
+ {
+ #ifndef _NO_EXPR_
+ if ( ! (m_wave[i].m_pf_codehandle = NSEEL_code_compile(m_wave[i].m_pf_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_PER_FRAME_CODE), m_szDesc, i);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ #endif
+ }
+
+ // 3. compile custom waveform per-point code
+ StripLinefeedCharsAndComments(m_wave[i].m_szPerPoint, buf);
+ if (buf[0])
+ {
+ if ( ! (m_wave[i].m_pp_codehandle = NSEEL_code_compile(m_wave[i].m_pp_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_WAVE_X_PER_POINT_CODE), m_szDesc, i);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ }
+ }
+ }
+
+ if (flags & RECOMPILE_SHAPE_CODE)
+ {
+ for (int i=0; i<MAX_CUSTOM_SHAPES; i++)
+ {
+ // 1. compile AND EXECUTE custom shape init code
+ StripLinefeedCharsAndComments(m_shape[i].m_szInit, buf);
+ if (buf[0] && bReInit)
+ {
+ #ifndef _NO_EXPR_
+ {
+ NSEEL_CODEHANDLE codehandle_temp;
+ if ( ! (codehandle_temp = NSEEL_code_compile(m_shape[i].m_pf_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_SHAPE_X_INIT_CODE), m_szDesc, i);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+
+ int vi = 0;
+ for (vi=0; vi<NUM_Q_VAR; vi++)
+ *m_shape[i].var_pf_q[vi] = q_values_after_init_code[vi];
+ for (vi=0; vi<NUM_T_VAR; vi++)
+ m_shape[i].t_values_after_init_code[vi] = 0;
+ }
+ else
+ {
+ // now execute the code, save the values of q1..q8, and clean up the code!
+
+ g_plugin.LoadCustomShapePerFrameEvallibVars(g_plugin.m_pState, i, 0);
+ // note: q values at this point will actually be same as
+ // q_values_after_init_code[], since no per-frame code
+ // has actually been executed yet!
+
+ NSEEL_code_execute(codehandle_temp);
+
+ for (int vi=0; vi<NUM_T_VAR; vi++)
+ m_shape[i].t_values_after_init_code[vi] = *m_shape[i].var_pf_t[vi];
+
+ NSEEL_code_free(codehandle_temp);
+ codehandle_temp = NULL;
+ }
+ }
+ #endif
+ }
+
+ // 2. compile custom shape per-frame code
+ StripLinefeedCharsAndComments(m_shape[i].m_szPerFrame, buf);
+ if (buf[0])
+ {
+ #ifndef _NO_EXPR_
+ if ( ! (m_shape[i].m_pf_codehandle = NSEEL_code_compile(m_shape[i].m_pf_eel, buf)))
+ {
+ wchar_t buf[1024];
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_WARNING_PRESET_X_ERROR_IN_SHAPE_X_PER_FRAME_CODE), m_szDesc, i);
+ g_plugin.AddError(buf, 6.0f, ERR_PRESET, true);
+ }
+ #endif
+ }
+
+ /*
+ // 3. compile custom shape per-point code
+ StripLinefeedCharsAndComments(m_shape[i].m_szPerPoint, buf);
+ if (buf[0])
+ {
+ resetVars(m_shape[i].m_pp_vars);
+ #ifndef _NO_EXPR_
+ if ( ! (m_shape[i].m_pp_codehandle = compileCode(buf)))
+ {
+ sprintf(g_plugin.m_szUserMessage, "warning: preset \"%s\": error in shape %d per-point code", m_szDesc, i);
+ g_plugin.m_fShowUserMessageUntilThisTime = g_plugin.GetTime() + 6.0f;
+ g_plugin.m_bUserMessageIsError = true;
+ }
+ #endif
+ resetVars(NULL);
+ }
+ */
+ }
+ }
+ }
+ #endif
+}
+
+void CState::RandomizePresetVars()
+{
+ m_rand_preset = D3DXVECTOR4(FRAND, FRAND, FRAND, FRAND);
+
+ int k = 0;
+ do
+ {
+ for (int i=0; i<4; i++)
+ {
+ float xlate_mult = 1;//(j==0) ? 1 : 0;
+ float rot_mult = 0.9f*powf(k/8.0f, 3.2f);
+ m_xlate[k].x = (FRAND*2-1)*xlate_mult;
+ m_xlate[k].y = (FRAND*2-1)*xlate_mult;
+ m_xlate[k].z = (FRAND*2-1)*xlate_mult;
+ m_rot_base[k].x = FRAND*6.28f;
+ m_rot_base[k].y = FRAND*6.28f;
+ m_rot_base[k].z = FRAND*6.28f;
+ m_rot_speed[k].x = (FRAND*2-1)*rot_mult;
+ m_rot_speed[k].y = (FRAND*2-1)*rot_mult;
+ m_rot_speed[k].z = (FRAND*2-1)*rot_mult;
+ k++;
+ }
+ }
+ while (k < sizeof(m_xlate)/sizeof(m_xlate[0]));
+}
+
+CBlendableFloat::CBlendableFloat()
+{
+ m_bBlending = false;
+}
+
+CBlendableFloat::~CBlendableFloat()
+{
+}
+
+//--------------------------------------------------------------------------------
+
+float CBlendableFloat::eval(float fTime)
+{
+ if (fTime < 0)
+ {
+ return val;
+ }
+
+ if (m_bBlending && (fTime > m_fBlendStartTime + m_fBlendDuration) || (fTime < m_fBlendStartTime))
+ {
+ m_bBlending = false;
+ }
+
+ if (!m_bBlending)
+ {
+ return val;
+ }
+ else
+ {
+ float mix = (fTime - m_fBlendStartTime) / m_fBlendDuration;
+ return (m_fBlendFrom*(1.0f - mix) + val*mix);
+ }
+}
+
+//--------------------------------------------------------------------------------
+
+void CBlendableFloat::StartBlendFrom(CBlendableFloat *f_from, float fAnimTime, float fDuration)
+{
+ if (fDuration < 0.001f)
+ return;
+
+ m_fBlendFrom = f_from->eval(fAnimTime);
+ m_bBlending = true;
+ m_fBlendStartTime = fAnimTime;
+ m_fBlendDuration = fDuration;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/state.h b/Src/Plugins/Visualization/vis_milk2/state.h
new file mode 100644
index 00000000..968dd316
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/state.h
@@ -0,0 +1,448 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _MILKDROP_STATE_
+#define _MILKDROP_STATE_ 1
+
+#include <memory.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "gstring.h"
+#include "texmgr.h"
+
+#include <d3dx9math.h> // for D3DXVECTOR3
+
+//#include "evallib/eval.h"
+#include "ns-eel2/ns-eel.h"
+#include "md_defines.h"
+
+// flags for CState::RecompileExpressions():
+#define RECOMPILE_PRESET_CODE 1
+#define RECOMPILE_WAVE_CODE 2
+#define RECOMPILE_SHAPE_CODE 4
+
+#define NUM_Q_VAR 32
+#define NUM_T_VAR 8
+
+#define MAX_BIGSTRING_LEN 32768
+
+class CBlendableFloat
+{
+public:
+ CBlendableFloat();
+ ~CBlendableFloat();
+
+ float operator = (float f) {
+ val = f;
+ m_bBlending = false;
+ return val;
+ };
+ float operator *= (float f) {
+ val *= f;
+ m_bBlending = false;
+ return val;
+ };
+ float operator /= (float f) {
+ val /= f;
+ m_bBlending = false;
+ return val;
+ };
+ float operator -= (float f) {
+ val -= f;
+ m_bBlending = false;
+ return val;
+ };
+ float operator += (float f) {
+ val += f;
+ m_bBlending = false;
+ return val;
+ };
+
+ float eval(float fTime); // call this from animation code. if fTime < 0, it will return unblended 'val'.
+ void StartBlendFrom(CBlendableFloat *f_from, float fAnimTime, float fDuration);
+
+protected:
+ float val;
+ bool m_bBlending;
+ float m_fBlendStartTime;
+ float m_fBlendDuration;
+ float m_fBlendFrom;
+};
+
+class CShape
+{
+public:
+ int Import(FILE* f, const wchar_t* szFile, int i);
+ int Export(FILE* f, const wchar_t* szFile, int i);
+
+ int enabled;
+ int sides;
+ int additive;
+ int thickOutline;
+ int textured;
+ int instances;
+ float x,y,rad,ang;
+ float r,g,b,a;
+ float r2,g2,b2,a2;
+ float border_r,border_g,border_b,border_a;
+ float tex_ang, tex_zoom;
+
+ char m_szInit[MAX_BIGSTRING_LEN]; // note: only executed once -> don't need to save codehandle
+ char m_szPerFrame[MAX_BIGSTRING_LEN];
+ //char m_szPerPoint[MAX_BIGSTRING_LEN];
+ NSEEL_CODEHANDLE m_pf_codehandle;
+ //int m_pp_codehandle;
+
+
+ // for per-frame expression evaluation:
+ NSEEL_VMCTX m_pf_eel;
+ double *var_pf_time, *var_pf_fps;
+ double *var_pf_frame;
+ double *var_pf_progress;
+ //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;
+ //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;
+ double* var_pf_q[NUM_Q_VAR];
+ double* var_pf_t[NUM_T_VAR];
+ double *var_pf_bass, *var_pf_mid, *var_pf_treb, *var_pf_bass_att, *var_pf_mid_att, *var_pf_treb_att;
+ double *var_pf_r, *var_pf_g, *var_pf_b, *var_pf_a;
+ double *var_pf_r2, *var_pf_g2, *var_pf_b2, *var_pf_a2;
+ double *var_pf_border_r, *var_pf_border_g, *var_pf_border_b, *var_pf_border_a;
+ double *var_pf_x, *var_pf_y, *var_pf_rad, *var_pf_ang;
+ double *var_pf_sides, *var_pf_textured, *var_pf_additive, *var_pf_thick, *var_pf_instances, *var_pf_instance;
+ double *var_pf_tex_zoom, *var_pf_tex_ang;
+
+ // for per-point expression evaluation:
+ /*
+ NSEEL_VMCTX m_pp_eel;
+ double *var_pp_time, *var_pp_fps;
+ double *var_pp_frame;
+ double *var_pp_progress;
+ 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;
+ 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;
+ double *var_pp_bass, *var_pp_mid, *var_pp_treb, *var_pp_bass_att, *var_pp_mid_att, *var_pp_treb_att;
+ double *var_pp_r, *var_pp_g, *var_pp_b, *var_pp_a;
+ double *var_pp_r2, *var_pp_g2, *var_pp_b2, *var_pp_a2;
+ double *var_pp_border_r, *var_pp_border_g, *var_pp_border_b, *var_pp_border_a;
+ double *var_pp_x, *var_pp_y, *var_pp_rad, *var_pp_ang, *var_pp_sides;
+ */
+
+ double t_values_after_init_code[NUM_T_VAR];
+};
+
+class CWave
+{
+public:
+ int Import(FILE* f, const wchar_t *szFile, int i);
+ int Export(FILE* f, const wchar_t* szFile, int i);
+
+ int enabled;
+ int samples;
+ int sep;
+ float scaling;
+ float smoothing;
+ float x,y,r,g,b,a;
+ int bSpectrum;
+ int bUseDots;
+ int bDrawThick;
+ int bAdditive;
+
+ char m_szInit[MAX_BIGSTRING_LEN]; // note: only executed once -> don't need to save codehandle
+ char m_szPerFrame[MAX_BIGSTRING_LEN];
+ char m_szPerPoint[MAX_BIGSTRING_LEN];
+ NSEEL_CODEHANDLE m_pf_codehandle;
+ NSEEL_CODEHANDLE m_pp_codehandle;
+
+ // for per-frame expression evaluation:
+ NSEEL_VMCTX m_pf_eel;
+ double *var_pf_time, *var_pf_fps;
+ double *var_pf_frame;
+ double *var_pf_progress;
+ //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;
+ //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;
+ double* var_pf_q[NUM_Q_VAR];
+ double* var_pf_t[NUM_T_VAR];
+ double *var_pf_bass, *var_pf_mid, *var_pf_treb, *var_pf_bass_att, *var_pf_mid_att, *var_pf_treb_att;
+ double *var_pf_r, *var_pf_g, *var_pf_b, *var_pf_a;
+ double *var_pf_samples;
+
+ // for per-point expression evaluation:
+ NSEEL_VMCTX m_pp_eel;
+ double *var_pp_time, *var_pp_fps;
+ double *var_pp_frame;
+ double *var_pp_progress;
+ //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;
+ //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;
+ double* var_pp_q[NUM_Q_VAR];
+ double* var_pp_t[NUM_T_VAR];
+ double *var_pp_bass, *var_pp_mid, *var_pp_treb, *var_pp_bass_att, *var_pp_mid_att, *var_pp_treb_att;
+ double *var_pp_sample, *var_pp_value1, *var_pp_value2;
+ double *var_pp_x, *var_pp_y, *var_pp_r, *var_pp_g, *var_pp_b, *var_pp_a;
+
+ double t_values_after_init_code[NUM_T_VAR];
+};
+
+typedef struct
+{
+ int type;
+ int in_var;
+ int out_var;
+ float constant;
+ float min;
+ float max;
+ float in_scale;
+ float amp; // for sine functions
+ float freq; // for sine functions
+ float freq2; // for sine functions
+ float phase; // for sine functions
+ float phase2; // for sine functions
+} td_modifier;
+
+//#define MAX_EVALS 8
+
+#define INVALID_PRESET_DESC L"<no description>" // this should contain invalid filename chars, so there is never a conflict...
+
+#define STATE_GENERAL 1 // and postproc (old presets) or blur, etc. (new presets)
+#define STATE_MOTION 2 // and equations
+#define STATE_WAVE 4 // waves, shapes, motion vectors
+#define STATE_WARP 8
+#define STATE_COMP 16
+#define STATE_ALL (32-1)
+
+#define CUR_MILKDROP_PRESET_VERSION 201
+// 200: milkdrop 2
+// 201: instead of just 1 variable for shader version, it tracks 2 (comp and warp) separately.
+
+class CState
+{
+public:
+ CState();
+ ~CState();
+
+ void Default(DWORD ApplyFlags=STATE_ALL);
+ void Randomize(int nMode);
+ void StartBlendFrom(CState *s_from, float fAnimTime, float fTimespan);
+ bool Import(const wchar_t *szIniFile, float fTime, CState* pOldState, DWORD ApplyFlags=STATE_ALL);
+ bool Export(const wchar_t *szIniFile);
+ void RecompileExpressions(int flags=0xFFFFFFFF, int bReInit=1);
+ void GenDefaultWarpShader();
+ void GenDefaultCompShader();
+
+ wchar_t m_szDesc[512]; // this is just the filename, without a path or extension.
+ //char m_szSection[256];
+
+ int m_nMinPSVersion; // the min of the warp & comp values...
+ int m_nMaxPSVersion; // the max of the warp & comp values...
+ int m_nWarpPSVersion; // 0 = milkdrop 1 era (no PS), 2 = ps_2_0, 3 = ps_3_0
+ int m_nCompPSVersion; // 0 = milkdrop 1 era (no PS), 2 = ps_2_0, 3 = ps_3_0
+ float m_fRating; // 0..5
+ // post-processing:
+ CBlendableFloat m_fGammaAdj; // +0 -> +1.0 (double), +2.0 (triple)...
+ CBlendableFloat m_fVideoEchoZoom;
+ CBlendableFloat m_fVideoEchoAlpha;
+ float m_fVideoEchoAlphaOld;
+ int m_nVideoEchoOrientation;
+ int m_nVideoEchoOrientationOld;
+
+ // fps-dependant:
+ CBlendableFloat m_fDecay; // 1.0 = none, 0.95 = heavy decay
+
+ // other:
+ int m_nWaveMode;
+ int m_nOldWaveMode;
+ bool m_bAdditiveWaves;
+ CBlendableFloat m_fWaveAlpha;
+ CBlendableFloat m_fWaveScale;
+ CBlendableFloat m_fWaveSmoothing;
+ bool m_bWaveDots;
+ bool m_bWaveThick;
+ CBlendableFloat m_fWaveParam; // -1..1; 0 is normal
+ bool m_bModWaveAlphaByVolume;
+ CBlendableFloat m_fModWaveAlphaStart; // when relative volume hits this level, alpha -> 0
+ CBlendableFloat m_fModWaveAlphaEnd; // when relative volume hits this level, alpha -> 1
+ float m_fWarpAnimSpeed; // 1.0 = normal, 2.0 = double, 0.5 = half, etc.
+ CBlendableFloat m_fWarpScale;
+ CBlendableFloat m_fZoomExponent;
+ CBlendableFloat m_fShader; // 0 = no color shader, 1 = full color shader
+ bool m_bMaximizeWaveColor;
+ bool m_bTexWrap;
+ bool m_bDarkenCenter;
+ bool m_bRedBlueStereo;
+ bool m_bBrighten;
+ bool m_bDarken;
+ bool m_bSolarize;
+ bool m_bInvert;
+ /*
+ bool m_bPlates;
+ int m_nPlates;
+ CBlendableFloat m_fPlateAlpha; // 0 = off, 0.1 = barely visible, 1.0 = solid
+ CBlendableFloat m_fPlateR;
+ CBlendableFloat m_fPlateG;
+ CBlendableFloat m_fPlateB;
+ CBlendableFloat m_fPlateWidth; // 1.0=normal, 2.0=double, etc.
+ CBlendableFloat m_fPlateLength; // 1.0=normal, 2.0=double, etc.
+ float m_fPlateSpeed; // 1.0=normal, 2.0=double, etc.
+ bool m_bPlatesAdditive;
+ */
+
+ // map controls:
+ CBlendableFloat m_fZoom;
+ CBlendableFloat m_fRot;
+ CBlendableFloat m_fRotCX;
+ CBlendableFloat m_fRotCY;
+ CBlendableFloat m_fXPush;
+ CBlendableFloat m_fYPush;
+ CBlendableFloat m_fWarpAmount;
+ CBlendableFloat m_fStretchX;
+ CBlendableFloat m_fStretchY;
+ CBlendableFloat m_fWaveR;
+ CBlendableFloat m_fWaveG;
+ CBlendableFloat m_fWaveB;
+ CBlendableFloat m_fWaveX;
+ CBlendableFloat m_fWaveY;
+ CBlendableFloat m_fOuterBorderSize;
+ CBlendableFloat m_fOuterBorderR;
+ CBlendableFloat m_fOuterBorderG;
+ CBlendableFloat m_fOuterBorderB;
+ CBlendableFloat m_fOuterBorderA;
+ CBlendableFloat m_fInnerBorderSize;
+ CBlendableFloat m_fInnerBorderR;
+ CBlendableFloat m_fInnerBorderG;
+ CBlendableFloat m_fInnerBorderB;
+ CBlendableFloat m_fInnerBorderA;
+ CBlendableFloat m_fMvX;
+ CBlendableFloat m_fMvY;
+ CBlendableFloat m_fMvDX;
+ CBlendableFloat m_fMvDY;
+ CBlendableFloat m_fMvL;
+ CBlendableFloat m_fMvR;
+ CBlendableFloat m_fMvG;
+ CBlendableFloat m_fMvB;
+ CBlendableFloat m_fMvA;
+ CBlendableFloat m_fBlur1Min;
+ CBlendableFloat m_fBlur2Min;
+ CBlendableFloat m_fBlur3Min;
+ CBlendableFloat m_fBlur1Max;
+ CBlendableFloat m_fBlur2Max;
+ CBlendableFloat m_fBlur3Max;
+ CBlendableFloat m_fBlur1EdgeDarken;
+
+ CShape m_shape[MAX_CUSTOM_SHAPES];
+ CWave m_wave[MAX_CUSTOM_WAVES];
+
+ // some random stuff for driving shaders:
+ void RandomizePresetVars();
+ D3DXVECTOR4 m_rand_preset; // 4 random floats (0..1); randomized @ preset load; fed to pixel shaders. --FIXME (blending)
+ D3DXVECTOR3 m_xlate[20];
+ D3DXVECTOR3 m_rot_base[20];
+ D3DXVECTOR3 m_rot_speed[20];
+
+ //COscillator m_waveR;
+ //COscillator m_waveG;
+ //COscillator m_waveB;
+ //COscillator m_wavePosX; // 0 = centered
+ //COscillator m_wavePosY; // 0 = centered
+
+ // for arbitrary function evaluation:
+ NSEEL_CODEHANDLE m_pf_codehandle;
+ NSEEL_CODEHANDLE m_pp_codehandle;
+ char m_szPerFrameInit[MAX_BIGSTRING_LEN];
+ char m_szPerFrameExpr[MAX_BIGSTRING_LEN];
+ char m_szPerPixelExpr[MAX_BIGSTRING_LEN];
+ char m_szWarpShadersText[MAX_BIGSTRING_LEN]; // pixel shader code
+ char m_szCompShadersText[MAX_BIGSTRING_LEN]; // pixel shader code
+ void FreeVarsAndCode(bool bFree = true);
+ void RegisterBuiltInVariables(int flags);
+ void StripLinefeedCharsAndComments(char *src, char *dest);
+
+ bool m_bBlending;
+ float m_fBlendStartTime;
+ float m_fBlendDuration;
+ float m_fBlendProgress; // 0..1; updated every frame based on StartTime and Duration.
+
+ // for once-per-frame expression evaluation: [although, these vars are also shared w/preset init expr eval]
+ NSEEL_VMCTX m_pf_eel;
+ 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;
+ double *var_pf_time, *var_pf_fps;
+ double *var_pf_bass, *var_pf_mid, *var_pf_treb, *var_pf_bass_att, *var_pf_mid_att, *var_pf_treb_att;
+ 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;
+ double *var_pf_decay;
+ double *var_pf_frame;
+ //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;
+ double* var_pf_q[NUM_Q_VAR];
+ double *var_pf_progress;
+ double *var_pf_ob_size, *var_pf_ob_r, *var_pf_ob_g, *var_pf_ob_b, *var_pf_ob_a;
+ double *var_pf_ib_size, *var_pf_ib_r, *var_pf_ib_g, *var_pf_ib_b, *var_pf_ib_a;
+ double *var_pf_mv_x;
+ double *var_pf_mv_y;
+ double *var_pf_mv_dx;
+ double *var_pf_mv_dy;
+ double *var_pf_mv_l;
+ double *var_pf_mv_r;
+ double *var_pf_mv_g;
+ double *var_pf_mv_b;
+ double *var_pf_mv_a;
+ double *var_pf_monitor;
+ double *var_pf_echo_zoom, *var_pf_echo_alpha, *var_pf_echo_orient;
+ // new in v1.04:
+ double *var_pf_wave_usedots, *var_pf_wave_thick, *var_pf_wave_additive, *var_pf_wave_brighten;
+ double *var_pf_darken_center, *var_pf_gamma, *var_pf_wrap;
+ double *var_pf_invert, *var_pf_brighten, *var_pf_darken, *var_pf_solarize;
+ double *var_pf_meshx, *var_pf_meshy;
+ double *var_pf_pixelsx, *var_pf_pixelsy;
+ double *var_pf_aspectx, *var_pf_aspecty;
+ double *var_pf_blur1min;
+ double *var_pf_blur2min;
+ double *var_pf_blur3min;
+ double *var_pf_blur1max;
+ double *var_pf_blur2max;
+ double *var_pf_blur3max;
+ double *var_pf_blur1_edge_darken;
+
+ // for per-vertex expression evaluation:
+ NSEEL_VMCTX m_pv_eel;
+ 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;
+ double *var_pv_time, *var_pv_fps;
+ double *var_pv_bass, *var_pv_mid, *var_pv_treb, *var_pv_bass_att, *var_pv_mid_att, *var_pv_treb_att;
+ double *var_pv_x, *var_pv_y, *var_pv_rad, *var_pv_ang;
+ double *var_pv_frame;
+ //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;
+ double* var_pv_q[NUM_Q_VAR];
+ double *var_pv_progress;
+ double *var_pv_meshx, *var_pv_meshy;
+ double *var_pv_pixelsx, *var_pv_pixelsy;
+ double *var_pv_aspectx, *var_pv_aspecty;
+
+ double q_values_after_init_code[NUM_Q_VAR];
+ double monitor_after_init_code;
+
+ float GetPresetStartTime() { return m_fPresetStartTime; }
+ float m_fPresetStartTime;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/support.cpp b/Src/Plugins/Visualization/vis_milk2/support.cpp
new file mode 100644
index 00000000..76696dae
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/support.cpp
@@ -0,0 +1,361 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "support.h"
+#include "utility.h"
+#include "../Winamp/wa_ipc.h"
+
+bool g_bDebugOutput = false;
+bool g_bDumpFileCleared = false;
+
+//---------------------------------------------------
+void PrepareFor3DDrawing(
+ IDirect3DDevice9 *pDevice,
+ int viewport_width,
+ int viewport_height,
+ float fov_in_degrees,
+ float near_clip,
+ float far_clip,
+ D3DXVECTOR3* pvEye,
+ D3DXVECTOR3* pvLookat,
+ D3DXVECTOR3* pvUp
+ )
+{
+ // This function sets up DirectX up for 3D rendering.
+ // Only call it once per frame, as it is VERY slow.
+ // INPUTS:
+ // pDevice a pointer to the D3D device
+ // viewport_width the width of the client area of the window
+ // viewport_height the height of the client area of the window
+ // fov_in_degrees the field of view, in degrees
+ // near_clip the distance to the near clip plane; should be > 0!
+ // far_clip the distance to the far clip plane
+ // eye the eyepoint coordinates, in world space
+ // lookat the point toward which the eye is looking, in world space
+ // up a vector indicating which dir. is up; usually <0,1,0>
+ //
+ // What this function does NOT do:
+ // 1. set the current texture (SetTexture)
+ // 2. set up the texture stages for texturing (SetTextureStageState)
+ // 3. set the current vertex format (SetVertexShader)
+ // 4. set up the world matrix (SetTransform(D3DTS_WORLD, &my_world_matrix))
+
+
+ // set up render state to some nice defaults:
+ {
+ // some defaults
+ pDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
+ pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
+ pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
+ pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
+ pDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
+ pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
+ pDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE );
+ pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
+ pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
+ pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+
+ // turn fog off
+ pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
+ pDevice->SetRenderState( D3DRS_RANGEFOGENABLE, FALSE );
+
+ // turn on high-quality bilinear interpolations
+ pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
+ }
+
+ // set up view & projection matrices (but not the world matrix!)
+ {
+ // if the window is not square, instead of distorting the scene,
+ // clip it so that the longer dimension of the window has the
+ // regular FOV, and the shorter dimension has a reduced FOV.
+ float fov_x = fov_in_degrees * 3.1415927f/180.0f;
+ float fov_y = fov_in_degrees * 3.1415927f/180.0f;
+ float aspect = (float)viewport_height / (float)viewport_width;
+ if (aspect < 1)
+ fov_y *= aspect;
+ else
+ fov_x /= aspect;
+
+ if (near_clip < 0.1f)
+ near_clip = 0.1f;
+ if (far_clip < near_clip + 1.0f)
+ far_clip = near_clip + 1.0f;
+
+ D3DXMATRIX proj;
+ MakeProjectionMatrix(&proj, near_clip, far_clip, fov_x, fov_y);
+ pDevice->SetTransform(D3DTS_PROJECTION, &proj);
+
+ D3DXMATRIX view;
+ pMatrixLookAtLH(&view, pvEye, pvLookat, pvUp);
+ pDevice->SetTransform(D3DTS_VIEW, &view);
+
+ // Optimization note: "You can minimize the number of required calculations
+ // by concatenating your world and view matrices into a world-view matrix
+ // that you set as the world matrix, and then setting the view matrix
+ // to the identity."
+ //D3DXMatrixMultiply(&world, &world, &view);
+ //D3DXMatrixIdentity(&view);
+ }
+}
+
+void PrepareFor2DDrawing(IDirect3DDevice9 *pDevice)
+{
+ // New 2D drawing area will have x,y coords in the range <-1,-1> .. <1,1>
+ // +--------+ Y=-1
+ // | |
+ // | screen | Z=0: front of scene
+ // | | Z=1: back of scene
+ // +--------+ Y=1
+ // X=-1 X=1
+ // NOTE: After calling this, be sure to then call (at least):
+ // 1. SetVertexShader()
+ // 2. SetTexture(), if you need it
+ // before rendering primitives!
+ // Also, be sure your sprites have a z coordinate of 0.
+ pDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
+ pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
+ pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
+ pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
+ pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
+ pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
+ pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
+ pDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
+ pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
+ pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+ pDevice->SetRenderState( D3DRS_LOCALVIEWER, FALSE );
+
+ pDevice->SetTexture(0, NULL);
+ pDevice->SetTexture(1, NULL);
+ pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);//D3DTEXF_LINEAR);
+ pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);//D3DTEXF_LINEAR);
+ pDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+ pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
+ pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
+ pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
+ pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );
+ pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
+
+ pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
+
+ pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
+
+ // set up for 2D drawing:
+ {
+ D3DXMATRIX Ortho2D;
+ D3DXMATRIX Identity;
+
+ pMatrixOrthoLH(&Ortho2D, 2.0f, -2.0f, 0.0f, 1.0f);
+ D3DXMatrixIdentity(&Identity);
+
+ pDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D);
+ pDevice->SetTransform(D3DTS_WORLD, &Identity);
+ pDevice->SetTransform(D3DTS_VIEW, &Identity);
+ }
+}
+
+//---------------------------------------------------
+
+void MakeWorldMatrix( D3DXMATRIX* pOut,
+ float xpos, float ypos, float zpos,
+ float sx, float sy, float sz,
+ float pitch, float yaw, float roll)
+{
+ /*
+ * The m_xPos, m_yPos, m_zPos variables contain the model's
+ * location in world coordinates.
+ * The m_fPitch, m_fYaw, and m_fRoll variables are floats that
+ * contain the model's orientation in terms of pitch, yaw, and roll
+ * angles, in radians.
+ */
+
+ D3DXMATRIX MatTemp;
+ D3DXMatrixIdentity(pOut);
+
+ // 1. first, rotation
+ if (pitch || yaw || roll)
+ {
+ D3DXMATRIX MatRot;
+ D3DXMatrixIdentity(&MatRot);
+
+ pMatrixRotationX(&MatTemp, pitch); // Pitch
+ pMatrixMultiply(&MatRot, &MatRot, &MatTemp);
+ pMatrixRotationY(&MatTemp, yaw); // Yaw
+ pMatrixMultiply(&MatRot, &MatRot, &MatTemp);
+ pMatrixRotationZ(&MatTemp, roll); // Roll
+ pMatrixMultiply(&MatRot, &MatRot, &MatTemp);
+
+ pMatrixMultiply(pOut, pOut, &MatRot);
+ }
+
+ // 2. then, scaling
+ pMatrixScaling(&MatTemp, sx, sy, sz);
+ pMatrixMultiply(pOut, pOut, &MatTemp);
+
+ // 3. last, translation to final world pos.
+ pMatrixTranslation(&MatTemp, xpos, ypos, zpos);
+ pMatrixMultiply(pOut, pOut, &MatTemp);
+}
+
+void MakeProjectionMatrix( D3DXMATRIX* pOut,
+ const float near_plane, // Distance to near clipping plane
+ const float far_plane, // Distance to far clipping plane
+ const float fov_horiz, // Horizontal field of view angle, in radians
+ const float fov_vert) // Vertical field of view angle, in radians
+{
+ float w = (float)1/tanf(fov_horiz*0.5f); // 1/tan(x) == cot(x)
+ float h = (float)1/tanf(fov_vert*0.5f); // 1/tan(x) == cot(x)
+ float Q = far_plane/(far_plane - near_plane);
+
+ ZeroMemory(pOut, sizeof(D3DXMATRIX));
+ pOut->_11 = w;
+ pOut->_22 = h;
+ pOut->_33 = Q;
+ pOut->_43 = -Q*near_plane;
+ pOut->_34 = 1;
+}
+
+void GetWinampSongTitle(HWND hWndWinamp, wchar_t *szSongTitle, int nSize)
+{
+ szSongTitle[0] = 0;
+ lstrcpynW(szSongTitle, (wchar_t*)SendMessage(hWndWinamp, WM_WA_IPC,
+ SendMessage(hWndWinamp, WM_WA_IPC, 0 , IPC_GETLISTPOS),
+ IPC_GETPLAYLISTTITLEW), nSize);
+}
+
+void GetWinampSongPosAsText(HWND hWndWinamp, wchar_t *szSongPos)
+{
+ // note: size(szSongPos[]) must be at least 64.
+ szSongPos[0] = 0;
+ int nSongPosMS = SendMessage(hWndWinamp,WM_USER,0,105);
+ if (nSongPosMS > 0)
+ {
+ wchar_t tmp[16];
+ float time_s = nSongPosMS*0.001f;
+ int minutes = (int)(time_s/60);
+ time_s -= minutes*60;
+ int seconds = (int)time_s;
+ time_s -= seconds;
+ int dsec = (int)(time_s*100);
+ swprintf(tmp, L"%.02f", dsec/100.0f);
+ swprintf(szSongPos, L"%d:%02d%s", minutes, seconds, tmp+1);
+ }
+}
+
+void GetWinampSongLenAsText(HWND hWndWinamp, wchar_t *szSongLen)
+{
+ // note: size(szSongLen[]) must be at least 64.
+ szSongLen[0] = 0;
+ int nSongLenMS = SendMessage(hWndWinamp,WM_USER,1,105)*1000;
+ if (nSongLenMS > 0)
+ {
+ int len_s = nSongLenMS/1000;
+ int minutes = len_s/60;
+ int seconds = len_s - minutes*60;
+ swprintf(szSongLen, L"%d:%02d", minutes, seconds);
+ }
+}
+
+float GetWinampSongPos(HWND hWndWinamp)
+{
+ // returns answer in seconds
+ return (float)SendMessage(hWndWinamp,WM_USER,0,105)*0.001f;
+}
+
+float GetWinampSongLen(HWND hWndWinamp)
+{
+ // returns answer in seconds
+ return (float)SendMessage(hWndWinamp,WM_USER,1,105);
+}
+
+int GetDX9TexFormatBitsPerPixel(D3DFORMAT fmt)
+{
+ switch(fmt)
+ {
+ case D3DFMT_DXT1: // 64 bits for each 4x4 pixels = 4 bits per pixel. No Alpha channel.
+ return 4; // bytes per pixel
+
+ case D3DFMT_DXT2: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
+ case D3DFMT_DXT3: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
+ case D3DFMT_DXT4: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
+ case D3DFMT_DXT5: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
+ case D3DFMT_R3G3B2: // 8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue.
+ case D3DFMT_A8: // 8-bit alpha only.
+ case D3DFMT_A8P8: // 8-bit color indexed with 8 bits of alpha.
+ case D3DFMT_P8: // 8-bit color indexed.
+ case D3DFMT_L8: // 8-bit luminance only.
+ case D3DFMT_A4L4: // 8-bit using 4 bits each for alpha and luminance.
+ return 8;
+
+ case D3DFMT_R5G6B5: // 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.
+ case D3DFMT_X1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color.
+ case D3DFMT_A1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha.
+ case D3DFMT_A4R4G4B4: // 16-bit ARGB pixel format with 4 bits for each channel.
+ case D3DFMT_R16F:
+ case D3DFMT_A8R3G3B2: // 16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and green, and 2 bits for blue.
+ case D3DFMT_X4R4G4B4: // 16-bit RGB pixel format using 4 bits for each color.
+ case D3DFMT_L16: // 16-bit luminance only.
+ case D3DFMT_A8L8: // 16-bit using 8 bits each for alpha and luminance.
+ case D3DFMT_CxV8U8:
+ case D3DFMT_V8U8:
+ case D3DFMT_L6V5U5:
+ return 16;
+
+ case D3DFMT_G16R16F:
+ case D3DFMT_R32F: // 32-bit float format using 32 bits for the red channel.
+ case D3DFMT_A8R8G8B8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
+ case D3DFMT_X8R8G8B8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
+ case D3DFMT_A8B8G8R8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
+ case D3DFMT_X8B8G8R8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
+ case D3DFMT_G16R16: // 32-bit pixel format using 16 bits each for green and red.
+ case D3DFMT_A2R10G10B10: // 32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for alpha.
+ case D3DFMT_A2B10G10R10: // 32-bit pixel format using 10 bits for each color and 2 bits for alpha.
+ case D3DFMT_R8G8B8: // 24-bit RGB pixel format with 8 bits per channel.
+ case D3DFMT_X8L8V8U8:
+ case D3DFMT_Q8W8V8U8:
+ case D3DFMT_V16U16:
+ return 32;
+
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A16B16G16R16: // 64-bit pixel format using 16 bits for each component.
+ case D3DFMT_G32R32F: // 64-bit float format using 32 bits for the red channel and 32 bits for the green channel.
+ return 64;
+
+ case D3DFMT_A32B32G32R32F:
+ return 128;
+ }
+
+ return 32;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/support.h b/Src/Plugins/Visualization/vis_milk2/support.h
new file mode 100644
index 00000000..e0516142
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/support.h
@@ -0,0 +1,109 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_EXAMPLE_PLUGIN_SUPPORT_H__
+#define __NULLSOFT_DX9_EXAMPLE_PLUGIN_SUPPORT_H__ 1
+
+#include <d3dx9.h>
+
+void MakeWorldMatrix( D3DXMATRIX* pOut,
+ float xpos, float ypos, float zpos,
+ float sx, float sy, float sz,
+ float pitch, float yaw, float roll);
+void MakeProjectionMatrix( D3DXMATRIX* pOut,
+ const float near_plane, // Distance to near clipping plane
+ const float far_plane, // Distance to far clipping plane
+ const float fov_horiz, // Horizontal field of view angle, in radians
+ const float fov_vert); // Vertical field of view angle, in radians
+void PrepareFor3DDrawing(
+ IDirect3DDevice9 *pDevice,
+ int viewport_width,
+ int viewport_height,
+ float fov_in_degrees,
+ float near_clip,
+ float far_clip,
+ D3DXVECTOR3* pvEye,
+ D3DXVECTOR3* pvLookat,
+ D3DXVECTOR3* pvUp
+ );
+void PrepareFor2DDrawing(IDirect3DDevice9 *pDevice);
+
+// Define vertex formats you'll be using here:
+// note: layout must match the vertex declaration in plugin.cpp!
+typedef struct _MYVERTEX
+{
+ float x, y, z; // screen position + Z-buffer depth
+ DWORD Diffuse; // diffuse color
+ float tu, tv; // DYNAMIC
+ float tu_orig, tv_orig; // STATIC
+ float rad, ang; // STATIC
+} MYVERTEX, *LPMYVERTEX;
+
+// note: layout must match the vertex declaration in plugin.cpp!
+typedef struct _WFVERTEX
+{
+ float x, y, z;
+ DWORD Diffuse; // diffuse color. also acts as filler; aligns struct to 16 bytes (good for random access/indexed prims)
+} WFVERTEX, *LPWFVERTEX;
+
+// note: layout must match the vertex declaration in plugin.cpp!
+typedef struct _SPRITEVERTEX
+{
+ float x, y; // screen position
+ float z; // Z-buffer depth
+ DWORD Diffuse; // diffuse color. also acts as filler; aligns struct to 16 bytes (good for random access/indexed prims)
+ float tu, tv; // texture coordinates for texture #0
+} SPRITEVERTEX, *LPSPRITEVERTEX;
+
+// Also prepare vertex format descriptors for each
+// of the 3 kinds of vertices we'll be using:
+// note: D3DFVF_TEXCOORDSIZEm(n): m = the dimension, n = the index
+// AVOID D3DFVF_TEXCOORDSIZE4 - I've seen probs (blending between shader and non-shader presets) on vaio laptop w/6200!
+#define MYVERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) | D3DFVF_TEXCOORDSIZE2(2))
+#define WFVERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE )
+#define SPRITEVERTEX_FORMAT (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) )
+
+void GetWinampSongTitle(HWND hWndWinamp, wchar_t *szSongTitle, int nSize);
+void GetWinampSongPosAsText(HWND hWndWinamp, wchar_t *szSongPos);
+void GetWinampSongLenAsText(HWND hWndWinamp, wchar_t *szSongLen);
+float GetWinampSongPos(HWND hWndWinamp); // returns answer in seconds
+float GetWinampSongLen(HWND hWndWinamp); // returns answer in seconds
+
+//#define PROFILING
+#ifdef PROFILING
+ #define PROFILE_BEGIN LARGE_INTEGER tx, freq, ty; QueryPerformanceCounter(&tx); QueryPerformanceFrequency(&freq);
+ #define PROFILE_END(s) { QueryPerformanceCounter(&ty); float dt = (float)((double)(ty.QuadPart - tx.QuadPart) / (double)freq.QuadPart); char buf[256]; sprintf(buf, " %s = %.1f ms\n", s, dt*1000 ); OutputDebugString(buf); tx = ty; }
+#else
+ #define PROFILE_BEGIN
+ #define PROFILE_END(s)
+#endif
+
+int GetDX9TexFormatBitsPerPixel(D3DFORMAT fmt);
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/temp.ico b/Src/Plugins/Visualization/vis_milk2/temp.ico
new file mode 100644
index 00000000..a48a54f3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/temp.ico
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_milk2/texmgr.cpp b/Src/Plugins/Visualization/vis_milk2/texmgr.cpp
new file mode 100644
index 00000000..9face119
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/texmgr.cpp
@@ -0,0 +1,752 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "texmgr.h"
+//#include "jpegstuff.h"
+//#include "evallib/compiler.h"
+#include "ns-eel2/ns-eel.h"
+#include "support.h"
+#include "plugin.h"
+#include "utility.h"
+texmgr::texmgr()
+{
+}
+
+texmgr::~texmgr()
+{
+ //Finish();
+ // DO NOT RELEASE OR DELETE m_lpDD; CLIENT SHOULD DO THIS!
+}
+
+void texmgr::Finish()
+{
+ for (int i=0; i<NUM_TEX; i++)
+ {
+ KillTex(i);
+ /*
+ if (m_tex[i].pSurface)
+ {
+ m_tex[i].pSurface->Release();
+ m_tex[i].pSurface = NULL;
+ }
+
+ FreeCode(i);
+ FreeVars(i);
+ */
+ NSEEL_VM_free(m_tex[i].tex_eel_ctx);
+ }
+
+ // DO NOT RELEASE OR DELETE m_lpDD; CLIENT SHOULD DO THIS!
+}
+
+void texmgr::Init(LPDIRECT3DDEVICE9 lpDD)
+{
+ m_lpDD = lpDD;
+
+ for (int i=0; i<NUM_TEX; i++)
+ {
+ m_tex[i].pSurface = NULL;
+ m_tex[i].szFileName[0] = 0;
+ m_tex[i].m_codehandle = NULL;
+ m_tex[i].m_szExpr[0] = 0;
+ m_tex[i].tex_eel_ctx = NSEEL_VM_alloc();
+ }
+}
+
+/*
+bool texmgr::TryCreateDDrawSurface(int iSlot, int w, int h)
+{
+ int loop = 1;
+ int done = 0;
+ int scaling = false;
+
+ do
+ {
+ //TEMP!!!
+ //w = 2048;
+ //h = 2048;
+ switch(loop)
+ {
+ case 0:
+ // first, try requesting surface w/original dimensions of image
+ break;
+ case 1:
+ // then, try next-highest-power-of-two for w,h
+ w = (int)powf(2.0f, ceilf(logf((float)w)/logf(2.0f)));
+ h = (int)powf(2.0f, ceilf(logf((float)h)/logf(2.0f)));
+ break;
+ case 2:
+ // then, try making it square
+ if (w < h) w = h;
+ if (h < w) h = w;
+ break;
+ default:
+ if (!scaling)
+ {
+ if (w<256 || h<256)
+ {
+ w *= 2;
+ h *= 2;
+ }
+ else
+ {
+ scaling = true;
+ }
+ }
+ else
+ {
+ if (w>16 && h>16)
+ {
+ w /= 2;
+ h /= 2;
+ }
+ else
+ {
+ done = 1;
+ }
+ }
+
+ break;
+ }
+
+ if (done)
+ break;
+
+ // TRY TO CREATE THE SURFACE IN SYSTEM MEMORY.
+ ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
+ ddsd.dwSize = sizeof( ddsd );
+ ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;//DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;// | DDSCAPS_3DDEVICE;// | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
+ ddsd.dwWidth = w;
+ ddsd.dwHeight = h;
+
+ m_tex[iSlot].pSurface = NULL;
+ //if (w<256 && h<256)
+ if (m_lpDD->CreateSurface( &ddsd, &m_tex[iSlot].pSurface, NULL ) == DD_OK)
+ break;
+ m_tex[iSlot].pSurface = NULL;
+
+ loop++;
+ }
+ while (!done);
+
+ if (m_tex[iSlot].pSurface == NULL)
+ return false;
+
+ // find out (& remember) actual size created:
+ ZeroMemory(&ddsd, sizeof(ddsd));
+ ddsd.dwSize = sizeof(ddsd);
+ m_tex[iSlot].pSurface->GetSurfaceDesc(&ddsd);
+ m_tex[iSlot].tex_w = ddsd.dwWidth;
+ m_tex[iSlot].tex_h = ddsd.dwHeight;
+ m_tex[iSlot].scale_x = 1.0f;
+ m_tex[iSlot].scale_y = 1.0f;
+
+ memcpy(&m_tex[iSlot].ddpf, &ddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT));
+
+ return true;
+}
+*/
+
+int texmgr::LoadTex(wchar_t *szFilename, int iSlot, char *szInitCode, char *szCode, float time, int frame, unsigned int ck)
+{
+ if (iSlot < 0) return TEXMGR_ERR_BAD_INDEX;
+ if (iSlot >= NUM_TEX) return TEXMGR_ERR_BAD_INDEX;
+
+ // first, if this texture is already loaded, just add another instance.
+ bool bTextureInstanced = false;
+ {
+ for (int x=0; x<NUM_TEX; x++)
+ if (m_tex[x].pSurface && _wcsicmp(m_tex[x].szFileName, szFilename)==0)
+ {
+ memcpy(&m_tex[iSlot], &m_tex[x], sizeof(td_tex));
+ m_tex[iSlot].m_szExpr[0] = 0;
+ m_tex[iSlot].m_codehandle = 0;
+
+ bTextureInstanced = true;
+ break;
+ }
+ }
+
+ if (!bTextureInstanced)
+ {
+ // Free old resources:
+ /*
+ if (m_tex[iSlot].pSurface)
+ {
+ m_tex[iSlot].pSurface->Release();
+ m_tex[iSlot].pSurface = NULL;
+ }*/
+ KillTex(iSlot);
+
+ wcscpy(m_tex[iSlot].szFileName, szFilename);
+
+ D3DXIMAGE_INFO info;
+ HRESULT hr = pCreateTextureFromFileExW(
+ m_lpDD,
+ szFilename,
+ D3DX_DEFAULT,
+ D3DX_DEFAULT,
+ D3DX_DEFAULT, // create a mip chain
+ 0,
+ D3DFMT_UNKNOWN,
+ D3DPOOL_DEFAULT,
+ D3DX_DEFAULT,
+ D3DX_DEFAULT,
+ 0xFF000000 | ck,
+ &info,
+ NULL,
+ &m_tex[iSlot].pSurface
+ );
+
+ if (hr != D3D_OK)
+ {
+ switch(hr)
+ {
+ case E_OUTOFMEMORY:
+ case D3DERR_OUTOFVIDEOMEMORY:
+ return TEXMGR_ERR_OUTOFMEM;
+ default:
+ return TEXMGR_ERR_BADFILE;
+ }
+ }
+
+ m_tex[iSlot].img_w = info.Width;
+ m_tex[iSlot].img_h = info.Height;
+
+ /*
+ unsigned int w_img;
+ unsigned int h_img;
+ unsigned int img_color_channels;
+
+ int ret = Begin_Jpeg_Read(szFilename, &w_img, &h_img, &img_color_channels);
+ switch(ret)
+ {
+ case JPEGSTUFF_ERR_SUCCESS:
+ break;
+ case JPEGSTUFF_ERR_OPENING:
+ return TEXMGR_ERR_OPENING;
+ break;
+ case JPEGSTUFF_ERR_MISC:
+ return TEXMGR_ERR_FORMAT;
+ break;
+ }
+
+ sprintf(buf, "texmgr: w=%d, h=%d, channels=%d", w_img, h_img, img_color_channels);
+ //g_dumpmsg(buf);
+
+ m_tex[iSlot].img_w = w_img;
+ m_tex[iSlot].img_h = h_img;
+
+ if (img_color_channels != 3)
+ {
+ // error: not 24-bit!
+ //g_dumpmsg("texmgr: image not 24-bit");
+ End_Jpeg_Read();
+ return TEXMGR_ERR_IMAGE_NOT_24_BIT;
+ }
+
+ if ((w_img > 2048) ||
+ (h_img > 2048)) // RG
+ {
+ // error: too large!
+ //g_dumpmsg("texmgr: image too large");
+ End_Jpeg_Read();
+ return TEXMGR_ERR_IMAGE_TOO_LARGE;
+ }
+
+ if (!TryCreateDDrawSurface(iSlot, w_img, h_img))
+ {
+ //g_dumpmsg("texmgr: unable to create ddraw surface");
+ End_Jpeg_Read();
+ return TEXMGR_ERR_CREATESURFACE_FAILED;
+ }
+
+ unsigned int w_tex = m_tex[iSlot].tex_w;
+ unsigned int h_tex = m_tex[iSlot].tex_h;
+ unsigned int bpp_tex = m_tex[iSlot].ddpf.dwRGBBitCount;
+
+ sprintf(buf, "texmgr: created ddraw surface; %d x %d x %d", w_tex, h_tex, bpp_tex);
+ //g_dumpmsg(buf);
+
+ DDSURFACEDESC2 ddsd;
+ ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
+ ddsd.dwSize = sizeof( ddsd );
+
+ if (m_tex[iSlot].pSurface->Lock(0, &ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_NOSYSLOCK, 0) != DD_OK)
+ {
+ //g_dumpmsg("texmgr: unable to lock ddraw surface");
+ End_Jpeg_Read();
+ m_tex[iSlot].pSurface->Release();
+ m_tex[iSlot].pSurface = NULL;
+ return TEXMGR_ERR_LOCKSURFACE_FAILED;
+ }
+
+ // analyze surface pixel format
+ unsigned int zeroBits[3] = { 0, 0, 0 };
+ unsigned int chopBits[3] = { 8, 8, 8 };
+ unsigned int mask[3] = { ddsd.ddpfPixelFormat.dwRBitMask, ddsd.ddpfPixelFormat.dwGBitMask, ddsd.ddpfPixelFormat.dwBBitMask };
+
+ {
+ int x,y;
+
+ for (x=0; x<3; x++)
+ {
+ for (y=0; y<32; y++)
+ {
+ if ((mask[x] & (1<<y)) == 0)
+ zeroBits[x]++;
+ else
+ break;
+ }
+ mask[x] >>= zeroBits[x];
+ for (y=0; y<32; y++)
+ {
+ if ((mask[x] & (1<<y)) != 0)
+ chopBits[x]--;
+ }
+ }
+ }
+
+ unsigned int ck_r1 = (ck_lo >> 16) & 0xFF;
+ unsigned int ck_g1 = (ck_lo >> 8 ) & 0xFF;
+ unsigned int ck_b1 = (ck_lo ) & 0xFF;
+ unsigned int ck_r2 = (ck_hi >> 16) & 0xFF;
+ unsigned int ck_g2 = (ck_hi >> 8 ) & 0xFF;
+ unsigned int ck_b2 = (ck_hi ) & 0xFF;
+
+ // read jpeg in & store in directdraw surface
+ // 2. read image into texture
+ if (w_img > w_tex || h_img > h_tex)
+ {
+ // DOWNSAMPLING VERSION
+
+ unsigned int new_w_img = min(w_tex, w_img);
+ unsigned int new_h_img = min(h_tex, h_img);
+
+ {
+ char buf[256];
+ sprintf(buf, "texmgr: downsampling image from %dx%d to %dx%d and storing in %dx%d texture.", w_img,h_img, new_w_img,new_h_img, w_tex,h_tex);
+ //g_dumpmsg(buf);
+ }
+
+ int downsample_buf[2048*3];
+ memset(downsample_buf, 0, sizeof(downsample_buf));
+
+ float input_lines_per_output_line = h_img/(float)new_h_img;
+ float lines = 0.0f;
+ unsigned int out_y = 0;
+
+ for (int y=0; y<(int)h_img; y++)
+ {
+ unsigned int x;
+
+ unsigned char *buf = Jpeg_Read_Next_Line();
+ if (!buf)
+ {
+ End_Jpeg_Read();
+ m_tex[iSlot].pSurface->Release();
+ m_tex[iSlot].pSurface = NULL;
+ return TEXMGR_ERR_CORRUPT_JPEG;
+ }
+
+ lines += 1.0f;
+ int portion = (int)(min(256, max(0, (input_lines_per_output_line - lines)*256)));
+ for (x=0; x<w_img*3; x++)
+ downsample_buf[x] += ((int)buf[x] * portion) >> 4;
+
+ if (portion < 256)
+ {
+ // commit this line (out_y) & start a new one
+ if (out_y < h_tex)
+ {
+ float input_cols_per_output_col = w_img/(float)new_w_img;
+ float cols = 0.0f;
+ int out_x = 0;
+
+ int buf2[2048*3];
+ memset(buf2, 0, new_w_img*3);
+
+ for (x=0; x<w_img; x++)
+ {
+ cols += 1.0f;
+ int portion = (int)(min(256, max(0, (input_cols_per_output_col - cols)*256)));
+ buf2[out_x*3 ] += (downsample_buf[x*3 ] * portion) >> 4;
+ buf2[out_x*3+1] += (downsample_buf[x*3+1] * portion) >> 4;
+ buf2[out_x*3+2] += (downsample_buf[x*3+2] * portion) >> 4;
+
+ if (portion < 256)
+ {
+ cols -= input_cols_per_output_col;
+ portion = 256 - portion;
+ out_x++;
+ buf2[out_x*3 ] = (downsample_buf[x*3 ] * portion) >> 4;
+ buf2[out_x*3+1] = (downsample_buf[x*3+1] * portion) >> 4;
+ buf2[out_x*3+2] = (downsample_buf[x*3+2] * portion) >> 4;
+ }
+ }
+
+ // now buf2[0..w_tex] has r,g,b colors in it (but scaled) -> SAVE TO TEXTURE.
+ float scale_factor = 1.0f / (float)(16 * 16 * input_cols_per_output_col * input_lines_per_output_line);
+
+ if (bpp_tex == 16)
+ {
+ unsigned __int16 *dest16 = (unsigned __int16 *)ddsd.lpSurface;
+ unsigned int tex_offset = (ddsd.lPitch/2) * out_y;
+ for (x=0; x<new_w_img; x++)
+ {
+ unsigned int cr = (unsigned int)(buf2[x*3 ]*scale_factor);
+ unsigned int cg = (unsigned int)(buf2[x*3+1]*scale_factor);
+ unsigned int cb = (unsigned int)(buf2[x*3+2]*scale_factor);
+ unsigned int color = (((cr >> chopBits[0]) & mask[0]) << zeroBits[0]) |
+ (((cg >> chopBits[1]) & mask[1]) << zeroBits[1]) |
+ (((cb >> chopBits[2]) & mask[2]) << zeroBits[2]);
+ if (!(cr >= ck_r1 && cr <= ck_r2 &&
+ cg >= ck_g1 && cg <= ck_g2 &&
+ cb >= ck_b1 && cb <= ck_b2))
+ color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
+ dest16[tex_offset++] = color;
+ }
+ }
+ else if (bpp_tex == 32)
+ {
+ unsigned __int32 *dest32 = (unsigned __int32 *)ddsd.lpSurface;
+ unsigned int tex_offset = (ddsd.lPitch/4) * out_y;
+ for (x=0; x<new_w_img; x++)
+ {
+ unsigned int cr = (unsigned int)(buf2[x*3 ]*scale_factor);
+ unsigned int cg = (unsigned int)(buf2[x*3+1]*scale_factor);
+ unsigned int cb = (unsigned int)(buf2[x*3+2]*scale_factor);
+ unsigned int color = (cr << zeroBits[0]) | (cg << zeroBits[1]) | (cb << zeroBits[2]);
+ if (!(cr >= ck_r1 && cr <= ck_r2 &&
+ cg >= ck_g1 && cg <= ck_g2 &&
+ cb >= ck_b1 && cb <= ck_b2))
+ color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
+ dest32[tex_offset++] = color;
+ }
+ }
+
+ out_y++;
+
+ }
+
+ // start next line:
+ lines -= input_lines_per_output_line;
+ portion = 256 - portion;
+ for (x=0; x<w_img*3; x++)
+ downsample_buf[x] = ((int)buf[x] * portion) >> 4;
+ }
+ }
+
+ m_tex[iSlot].scale_x = new_w_img/(float)w_img;
+ m_tex[iSlot].scale_y = new_h_img/(float)h_img;
+ m_tex[iSlot].img_w = new_w_img;
+ m_tex[iSlot].img_h = new_h_img;
+ w_img = new_w_img;
+ h_img = new_h_img;
+ }
+ else
+ {
+ // 1:1 VERSION
+
+ if (bpp_tex == 16)
+ {
+ unsigned __int16 *dest16 = (unsigned __int16 *)ddsd.lpSurface;
+ for (int y=0; y<(int)h_img; y++)
+ {
+ unsigned char *buf = Jpeg_Read_Next_Line();
+ if (!buf)
+ {
+ End_Jpeg_Read();
+ m_tex[iSlot].pSurface->Release();
+ m_tex[iSlot].pSurface = NULL;
+ return TEXMGR_ERR_CORRUPT_JPEG;
+ }
+
+ unsigned int tex_offset = (ddsd.lPitch/2) * y;
+ for (unsigned int x=0; x<w_img; x++)
+ {
+ unsigned int cr = buf[x*3 ];
+ unsigned int cg = buf[x*3+1];
+ unsigned int cb = buf[x*3+2];
+ unsigned int color = (((cr >> chopBits[0]) & mask[0]) << zeroBits[0]) |
+ (((cg >> chopBits[1]) & mask[1]) << zeroBits[1]) |
+ (((cb >> chopBits[2]) & mask[2]) << zeroBits[2]);
+ if (!(cr >= ck_r1 && cr <= ck_r2 &&
+ cg >= ck_g1 && cg <= ck_g2 &&
+ cb >= ck_b1 && cb <= ck_b2))
+ color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
+ dest16[tex_offset++] = color;
+ }
+ }
+ }
+ else if (bpp_tex == 32)
+ {
+ unsigned __int32 *dest32 = (unsigned __int32 *)ddsd.lpSurface;
+ for (int y=0; y<(int)h_img; y++)
+ {
+ unsigned char *buf = Jpeg_Read_Next_Line();
+ if (!buf)
+ {
+ End_Jpeg_Read();
+ m_tex[iSlot].pSurface->Release();
+ m_tex[iSlot].pSurface = NULL;
+ return TEXMGR_ERR_CORRUPT_JPEG;
+ }
+
+ unsigned int tex_offset = (ddsd.lPitch/4) * y;
+ for (unsigned int x=0; x<w_img; x++)
+ {
+ unsigned int cr = buf[x*3 ];
+ unsigned int cg = buf[x*3+1];
+ unsigned int cb = buf[x*3+2];
+ unsigned int color = (cr << zeroBits[0]) | (cg << zeroBits[1]) | (cb << zeroBits[2]);
+ if (!(cr >= ck_r1 && cr <= ck_r2 &&
+ cg >= ck_g1 && cg <= ck_g2 &&
+ cb >= ck_b1 && cb <= ck_b2))
+ color |= ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
+ dest32[tex_offset++] = color;
+ }
+ }
+ }
+ }
+
+ m_tex[iSlot].pSurface->Unlock(0);
+
+ End_Jpeg_Read();
+ */
+ }
+
+ m_tex[iSlot].fStartTime = time;
+ m_tex[iSlot].nStartFrame = frame;
+
+ int ret = TEXMGR_ERR_SUCCESS;
+
+ // compile & run init. code:
+ if (!RunInitCode(iSlot, szInitCode))
+ ret |= TEXMGR_WARN_ERROR_IN_INIT_CODE;
+
+ // compile & save per-frame code:
+ strcpy(m_tex[iSlot].m_szExpr, szCode);
+ FreeCode(iSlot);
+ if (!RecompileExpressions(iSlot))
+ ret |= TEXMGR_WARN_ERROR_IN_REG_CODE;
+
+ //g_dumpmsg("texmgr: success");
+
+ return ret;
+}
+
+void texmgr::KillTex(int iSlot)
+{
+ if (iSlot < 0) return;
+ if (iSlot >= NUM_TEX) return;
+
+ // Free old resources:
+ if (m_tex[iSlot].pSurface)
+ {
+ // first, make sure no other sprites reference this texture!
+ int refcount = 0;
+ for (int x=0; x<NUM_TEX; x++)
+ if (m_tex[x].pSurface == m_tex[iSlot].pSurface)
+ refcount++;
+
+ if (refcount==1)
+ m_tex[iSlot].pSurface->Release();
+ m_tex[iSlot].pSurface = NULL;
+ }
+ m_tex[iSlot].szFileName[0] = 0;
+
+ FreeCode(iSlot);
+}
+
+void texmgr::StripLinefeedCharsAndComments(char *src, char *dest)
+{
+ // replaces all LINEFEED_CONTROL_CHAR characters in src with a space in dest;
+ // also strips out all comments (beginning with '//' and going til end of line).
+ // Restriction: sizeof(dest) must be >= sizeof(src).
+
+ int i2 = 0;
+ int len = strlen(src);
+ int bComment = false;
+ for (int i=0; i<len; i++)
+ {
+ if (bComment)
+ {
+ if (src[i] == LINEFEED_CONTROL_CHAR)
+ bComment = false;
+ }
+ else
+ {
+ if ((src[i] =='\\' && src[i+1] =='\\') || (src[i] =='/' && src[i+1] =='/'))
+ bComment = true;
+ else if (src[i] != LINEFEED_CONTROL_CHAR)
+ dest[i2++] = src[i];
+ }
+ }
+ dest[i2] = 0;
+}
+
+bool texmgr::RunInitCode(int iSlot, char *szInitCode)
+{
+ // warning: destroys contents of m_tex[iSlot].m_szExpr,
+ // so be sure to call RunInitCode before writing or
+ // compiling that string!
+
+ FreeCode(iSlot);
+ FreeVars(iSlot);
+ RegisterBuiltInVariables(iSlot);
+
+ strcpy(m_tex[iSlot].m_szExpr, szInitCode);
+ bool ret = RecompileExpressions(iSlot);
+
+ // set default values of output variables:
+ // (by not setting these every frame, we allow the values to persist from frame-to-frame.)
+ *(m_tex[iSlot].var_x) = 0.5;
+ *(m_tex[iSlot].var_y) = 0.5;
+ *(m_tex[iSlot].var_sx) = 1.0;
+ *(m_tex[iSlot].var_sy) = 1.0;
+ *(m_tex[iSlot].var_repeatx) = 1.0;
+ *(m_tex[iSlot].var_repeaty) = 1.0;
+ *(m_tex[iSlot].var_rot) = 0.0;
+ *(m_tex[iSlot].var_flipx) = 0.0;
+ *(m_tex[iSlot].var_flipy) = 0.0;
+ *(m_tex[iSlot].var_r) = 1.0;
+ *(m_tex[iSlot].var_g) = 1.0;
+ *(m_tex[iSlot].var_b) = 1.0;
+ *(m_tex[iSlot].var_a) = 1.0;
+ *(m_tex[iSlot].var_blendmode)= 0.0;
+ *(m_tex[iSlot].var_done) = 0.0;
+ *(m_tex[iSlot].var_burn) = 1.0;
+
+ #ifndef _NO_EXPR_
+ if (m_tex[iSlot].m_codehandle)
+ NSEEL_code_execute(m_tex[iSlot].m_codehandle);
+ #endif
+
+ return ret;
+}
+
+bool texmgr::RecompileExpressions(int iSlot)
+{
+ char *expr = m_tex[iSlot].m_szExpr;
+
+ // QUICK FIX: if the string ONLY has spaces and linefeeds, erase it,
+ // because for some strange reason this would cause an error in compileCode().
+ {
+ char *p = expr;
+ while (*p==' ' || *p==LINEFEED_CONTROL_CHAR) p++;
+ if (*p == 0) expr[0] = 0;
+ }
+
+ // replace linefeed control characters with spaces, so they don't mess up the code compiler,
+ // and strip out any comments ('//') before sending to CompileCode().
+ char buf[sizeof(m_tex[iSlot].m_szExpr)];
+ StripLinefeedCharsAndComments(expr, buf);
+
+ if (buf[0])
+ {
+ #ifndef _NO_EXPR_
+ //resetVars(m_tex[iSlot].m_vars);
+ //g_dumpmsg("texmgr: compiling string: ");
+ //g_dumpmsg(buf);
+ if ( ! (m_tex[iSlot].m_codehandle = NSEEL_code_compile(m_tex[iSlot].tex_eel_ctx, buf)))
+ {
+ //g_dumpmsg(" -error!");
+ //MessageBox( NULL, "error in per-frame code", "MILKDROP ERROR", MB_OK|MB_SETFOREGROUND|MB_TOPMOST );
+ //sprintf(pg->m_szUserMessage, "warning: preset \"%s\": error in 'per_frame' code", m_szDesc);
+ //pg->m_fShowUserMessageUntilThisTime = pg->m_fAnimTime + 6.0f;
+ }
+ else
+ {
+ //g_dumpmsg(" -ok!");
+ //pg->m_fShowUserMessageUntilThisTime = pg->m_fAnimTime; // clear any old error msg.
+ }
+ //resetVars(NULL);
+
+ return (m_tex[iSlot].m_codehandle != 0);
+
+ #endif
+ }
+
+ return true;
+}
+
+void texmgr::FreeVars(int iSlot)
+{
+ // free the built-in variables AND any user variables
+}
+
+void texmgr::FreeCode(int iSlot)
+{
+ // free the compiled expressions
+ if (m_tex[iSlot].m_codehandle)
+ {
+ NSEEL_code_free(m_tex[iSlot].m_codehandle);
+ m_tex[iSlot].m_codehandle = NULL;
+ }
+}
+
+void texmgr::RegisterBuiltInVariables(int iSlot)
+{
+ NSEEL_VMCTX eel_ctx = m_tex[iSlot].tex_eel_ctx;
+ NSEEL_VM_resetvars(eel_ctx);
+
+ // input variables
+ m_tex[iSlot].var_time = NSEEL_VM_regvar(eel_ctx, "time");
+ m_tex[iSlot].var_frame = NSEEL_VM_regvar(eel_ctx, "frame");
+ m_tex[iSlot].var_fps = NSEEL_VM_regvar(eel_ctx, "fps");
+ m_tex[iSlot].var_progress = NSEEL_VM_regvar(eel_ctx, "progress");
+ m_tex[iSlot].var_bass = NSEEL_VM_regvar(eel_ctx, "bass");
+ m_tex[iSlot].var_bass_att = NSEEL_VM_regvar(eel_ctx, "bass_att");
+ m_tex[iSlot].var_mid = NSEEL_VM_regvar(eel_ctx, "mid");
+ m_tex[iSlot].var_mid_att = NSEEL_VM_regvar(eel_ctx, "mid_att");
+ m_tex[iSlot].var_treb = NSEEL_VM_regvar(eel_ctx, "treb");
+ m_tex[iSlot].var_treb_att = NSEEL_VM_regvar(eel_ctx, "treb_att");
+
+ // output variables
+ m_tex[iSlot].var_x = NSEEL_VM_regvar(eel_ctx, "x");
+ m_tex[iSlot].var_y = NSEEL_VM_regvar(eel_ctx, "y");
+ m_tex[iSlot].var_sx = NSEEL_VM_regvar(eel_ctx, "sx");
+ m_tex[iSlot].var_sy = NSEEL_VM_regvar(eel_ctx, "sy");
+ m_tex[iSlot].var_repeatx = NSEEL_VM_regvar(eel_ctx, "repeatx");
+ m_tex[iSlot].var_repeaty = NSEEL_VM_regvar(eel_ctx, "repeaty");
+ m_tex[iSlot].var_rot = NSEEL_VM_regvar(eel_ctx, "rot");
+ m_tex[iSlot].var_flipx = NSEEL_VM_regvar(eel_ctx, "flipx");
+ m_tex[iSlot].var_flipy = NSEEL_VM_regvar(eel_ctx, "flipy");
+ m_tex[iSlot].var_r = NSEEL_VM_regvar(eel_ctx, "r");
+ m_tex[iSlot].var_g = NSEEL_VM_regvar(eel_ctx, "g");
+ m_tex[iSlot].var_b = NSEEL_VM_regvar(eel_ctx, "b");
+ m_tex[iSlot].var_a = NSEEL_VM_regvar(eel_ctx, "a");
+ m_tex[iSlot].var_blendmode = NSEEL_VM_regvar(eel_ctx, "blendmode");
+ m_tex[iSlot].var_done = NSEEL_VM_regvar(eel_ctx, "done");
+ m_tex[iSlot].var_burn = NSEEL_VM_regvar(eel_ctx, "burn");
+
+// resetVars(NULL);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/texmgr.h b/Src/Plugins/Visualization/vis_milk2/texmgr.h
new file mode 100644
index 00000000..78db5a74
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/texmgr.h
@@ -0,0 +1,120 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef GEISS_TEXTURE_MANAGER
+#define GEISS_TEXTURE_MANAGER 1
+
+#define NUM_TEX 16
+
+#ifdef _DEBUG
+ #define D3D_DEBUG_INFO // declare this before including d3d9.h
+#endif
+#include <d3d9.h>
+#include "ns-eel2/ns-eel.h"
+#include "md_defines.h"
+
+#define TEXMGR_ERROR_MASK 0x0F
+#define TEXMGR_ERR_SUCCESS 0
+#define TEXMGR_ERR_BAD_INDEX 1
+/*
+#define TEXMGR_ERR_OPENING 2
+#define TEXMGR_ERR_IMAGE_NOT_24_BIT 3
+#define TEXMGR_ERR_IMAGE_TOO_LARGE 4
+#define TEXMGR_ERR_CREATESURFACE_FAILED 5
+#define TEXMGR_ERR_LOCKSURFACE_FAILED 6
+#define TEXMGR_ERR_CORRUPT_JPEG 7
+*/
+#define TEXMGR_ERR_FORMAT 8
+#define TEXMGR_ERR_BADFILE 9
+#define TEXMGR_ERR_OUTOFMEM 10
+#define TEXMGR_WARNING_MASK 0xF0
+#define TEXMGR_WARN_ERROR_IN_INIT_CODE 0x10
+#define TEXMGR_WARN_ERROR_IN_REG_CODE 0x20
+
+typedef struct
+{
+ LPDIRECT3DTEXTURE9 pSurface;
+ int img_w, img_h;
+ /*
+ int tex_w, tex_h;
+ float scale_x, scale_y; // the factors by which the original image was squished to become (img_w x img_h) texels in size.
+ DDPIXELFORMAT ddpf;
+ */
+ wchar_t szFileName[512];
+ float fStartTime;
+ int nStartFrame;
+ int nUserData;
+
+ // stuff for expressions:
+ char m_szExpr[8192]; // for expression eval
+ NSEEL_CODEHANDLE m_codehandle; // for expression eval
+ // input variables for expression eval
+ double *var_time, *var_frame, *var_fps, *var_progress;
+ double *var_bass, *var_bass_att, *var_mid, *var_mid_att, *var_treb, *var_treb_att;
+ // output variables for expression eval
+ double *var_x, *var_y;
+ double *var_sx, *var_sy, *var_rot, *var_flipx, *var_flipy;
+ double *var_r, *var_g, *var_b, *var_a;
+ double *var_blendmode;
+ double *var_repeatx, *var_repeaty;
+ double *var_done, *var_burn;
+ NSEEL_VMCTX tex_eel_ctx;
+}
+td_tex;
+
+class texmgr
+{
+public:
+ texmgr();
+ ~texmgr();
+
+ // members
+ void Init(LPDIRECT3DDEVICE9 lpDD); // DirectDraw object
+ int LoadTex(wchar_t *szFilename, int iSlot, char *szInitCode, char *szCode, float time, int frame, unsigned int ck);
+ void KillTex(int iSlot);
+ void Finish();
+
+ // data
+ td_tex m_tex[NUM_TEX];
+
+protected:
+ // members
+ //bool TryCreateDDrawSurface(int iSlot, int w, int h);
+ void FreeVars(int iSlot);
+ void FreeCode(int iSlot);
+ void RegisterBuiltInVariables(int iSlot);
+ bool RunInitCode(int iSlot, char *szInitCode);
+ bool RecompileExpressions(int iSlot);
+ void StripLinefeedCharsAndComments(char *src, char *dest);
+
+ // data
+ LPDIRECT3DDEVICE9 m_lpDD;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/text1.bin b/Src/Plugins/Visualization/vis_milk2/text1.bin
new file mode 100644
index 00000000..86a25375
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/text1.bin
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_milk2/textmgr.cpp b/Src/Plugins/Visualization/vis_milk2/textmgr.cpp
new file mode 100644
index 00000000..12fe540b
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/textmgr.cpp
@@ -0,0 +1,700 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "textmgr.h"
+#include "support.h"
+#include "utility.h"
+
+#define MAX_MSG_CHARS (65536*2)
+#define SafeRelease(x) { if (x) {x->Release(); x=NULL;} }
+wchar_t g_szMsgPool[2][MAX_MSG_CHARS];
+
+/*
+ NOTES ON CTextManager
+
+ *** -desktop mode was SLOOOW when songtitles are on!, esp. since anim. songtitles...
+ -> decided to cache output of ID3DXFont by rendering to a (vidmem) texture,
+ ** only when things change. ** That became CTextManager.
+ -uses GDI-based ID3DXFont to draw text to a 2nd (VIDEO MEMORY) surface,
+ but each frame, it only draws what is necessary (what's changed
+ since last frame). It then blits that image (additively) to
+ the back buffer each frame. (note that dark boxes wouldn't work
+ w/additive drawing, since they're black, so those have to be
+ manually drawn (as black boxes) by the plugin shell, AS WELL AS
+ entered into the CTextManager queue as dark boxes, to handle
+ erasure, dirty rectangles, etc.)
+
+ PROS/CONS:
+ (+) Supports all GDI features: italics, kerning, international fonts, formatting, &, etc.
+ (-) takes a lot of memory
+ (-) if texture can't be created @ proper size, fonts will appear too big
+ -> so don't use texture at all, in that case.
+ -> at least this way it will work well on all newer cards [w/memory]
+ (-) it's still going to crawl *when the text changes*,
+ because d3dx will upload textures to vidmem & blit them *once for each change*.
+
+ OTHER CONCERNS/KIV:
+ -what if m_lpDDSText can't be created @ actual size of window?
+ If it's bigger, that's ok; but if it's smaller, that should result
+ in a clipped area for the text - hmm....
+*/
+
+CTextManager::CTextManager()
+{
+}
+
+CTextManager::~CTextManager()
+{
+}
+
+void CTextManager::Init(LPDIRECT3DDEVICE9 lpDevice, IDirect3DTexture9* lpTextSurface, int bAdditive)
+{
+ m_lpDevice = lpDevice;
+ m_lpTextSurface = lpTextSurface;
+ m_blit_additively = bAdditive;
+
+ m_b = 0;
+ m_nMsg[0] = 0;
+ m_nMsg[1] = 0;
+ m_next_msg_start_ptr = g_szMsgPool[m_b];
+}
+
+void CTextManager::Finish()
+{
+}
+
+void CTextManager::ClearAll()
+{
+ m_nMsg[m_b] = 0;
+ m_next_msg_start_ptr = g_szMsgPool[m_b];
+}
+
+void CTextManager::DrawBox(LPRECT pRect, DWORD boxColor)
+{
+ if (!pRect)
+ return;
+
+ if ((m_nMsg[m_b] < MAX_MSGS) &&
+ (DWORD)m_next_msg_start_ptr - (DWORD)g_szMsgPool[m_b] + 0 + 1 < MAX_MSG_CHARS)
+ {
+ *m_next_msg_start_ptr = 0;
+
+ m_msg[m_b][m_nMsg[m_b]].msg = m_next_msg_start_ptr;
+ m_msg[m_b][m_nMsg[m_b]].pfont = NULL;
+ m_msg[m_b][m_nMsg[m_b]].rect = *pRect;
+ m_msg[m_b][m_nMsg[m_b]].flags = 0;
+ m_msg[m_b][m_nMsg[m_b]].color = 0xFFFFFFFF;
+ m_msg[m_b][m_nMsg[m_b]].bgColor = boxColor;
+ m_nMsg[m_b]++;
+ m_next_msg_start_ptr += 1;
+ }
+}
+
+int CTextManager::DrawText(LPD3DXFONT pFont, char* szText, RECT* pRect, DWORD flags, DWORD color, bool bBox, DWORD boxColor)
+{
+ // these aren't supported by D3DX9:
+ flags &= ~(DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX);
+
+ if (!(pFont && pRect && szText))
+ return 0;
+
+ if (flags & DT_CALCRECT)
+ return pFont->DrawText(NULL, szText, -1, pRect, flags, color);
+
+ if (!m_lpDevice /*|| !m_lpTextSurface*/)
+ return 0;
+
+ int len = strlen(szText);
+
+ if ((m_nMsg[m_b] < MAX_MSGS) &&
+ (DWORD)m_next_msg_start_ptr - (DWORD)g_szMsgPool[m_b] + len + 1 < MAX_MSG_CHARS)
+ {
+ wcscpy(m_next_msg_start_ptr, AutoWide(szText));
+
+ m_msg[m_b][m_nMsg[m_b]].msg = m_next_msg_start_ptr;
+ m_msg[m_b][m_nMsg[m_b]].pfont = pFont;
+ m_msg[m_b][m_nMsg[m_b]].rect = *pRect;
+ m_msg[m_b][m_nMsg[m_b]].flags = flags;
+ m_msg[m_b][m_nMsg[m_b]].color = color;
+ m_msg[m_b][m_nMsg[m_b]].bgColor = boxColor;
+
+ // shrink rects on new frame's text strings; important for deletions
+ int h = pFont->DrawText(NULL, szText, len, &m_msg[m_b][m_nMsg[m_b]].rect, flags | DT_CALCRECT, color);
+
+ m_nMsg[m_b]++;
+ m_next_msg_start_ptr += len + 1;
+
+ if (bBox)
+ {
+ // adds a message with no text, but the rect is the same as the text, so it creates a black box
+ DrawBox(&m_msg[m_b][m_nMsg[m_b]-1].rect, boxColor);
+ // now swap it with the text that precedes it, so it draws first, and becomes a background
+ td_string x = m_msg[m_b][m_nMsg[m_b]-1];
+ m_msg[m_b][m_nMsg[m_b]-1] = m_msg[m_b][m_nMsg[m_b]-2];
+ m_msg[m_b][m_nMsg[m_b]-2] = x;
+ }
+ return h;
+ }
+
+ // no room for more text? ok, but still return accurate info:
+ RECT r2 = *pRect;
+ int h = pFont->DrawText(NULL, szText, len, &r2, flags | DT_CALCRECT, color);
+ return h;
+}
+
+int CTextManager::DrawTextW(LPD3DXFONT pFont, wchar_t* szText, RECT* pRect, DWORD flags, DWORD color, bool bBox, DWORD boxColor)
+{
+ // these aren't supported by D3DX9:
+ flags &= ~(DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | DT_NOPREFIX);
+
+ if (!(pFont && pRect && szText))
+ return 0;
+
+ if (flags & DT_CALCRECT)
+ return pFont->DrawTextW(NULL, szText, -1, pRect, flags, color);
+
+ if (!m_lpDevice /*|| !m_lpTextSurface*/)
+ return 0;
+
+ int len = wcslen(szText);
+
+ if ((m_nMsg[m_b] < MAX_MSGS) &&
+ (DWORD)m_next_msg_start_ptr - (DWORD)g_szMsgPool[m_b] + len + 1 < MAX_MSG_CHARS)
+ {
+ wcscpy(m_next_msg_start_ptr, szText);
+
+ m_msg[m_b][m_nMsg[m_b]].msg = m_next_msg_start_ptr;
+ m_msg[m_b][m_nMsg[m_b]].pfont = pFont;
+ m_msg[m_b][m_nMsg[m_b]].rect = *pRect;
+ m_msg[m_b][m_nMsg[m_b]].flags = flags;
+ m_msg[m_b][m_nMsg[m_b]].color = color;
+ m_msg[m_b][m_nMsg[m_b]].bgColor = boxColor;
+
+ // shrink rects on new frame's text strings; important for deletions
+ int h = pFont->DrawTextW(NULL, szText, len, &m_msg[m_b][m_nMsg[m_b]].rect, flags | DT_CALCRECT, color);
+
+ m_nMsg[m_b]++;
+ m_next_msg_start_ptr += len + 1;
+
+ if (bBox)
+ {
+ // adds a message with no text, but the rect is the same as the text, so it creates a black box
+ DrawBox(&m_msg[m_b][m_nMsg[m_b]-1].rect, boxColor);
+ // now swap it with the text that precedes it, so it draws first, and becomes a background
+ td_string x = m_msg[m_b][m_nMsg[m_b]-1];
+ m_msg[m_b][m_nMsg[m_b]-1] = m_msg[m_b][m_nMsg[m_b]-2];
+ m_msg[m_b][m_nMsg[m_b]-2] = x;
+ }
+ return h;
+ }
+
+ // no room for more text? ok, but still return accurate info:
+ RECT r2 = *pRect;
+ int h = pFont->DrawTextW(NULL, szText, len, &r2, flags | DT_CALCRECT, color);
+ return h;
+}
+
+#define MATCH(i,j) ( m_msg[m_b][i].pfont == m_msg[1-m_b][j].pfont && \
+ m_msg[m_b][i].flags == m_msg[1-m_b][j].flags && \
+ m_msg[m_b][i].color == m_msg[1-m_b][j].color && \
+ m_msg[m_b][i].bgColor == m_msg[1-m_b][j].bgColor && \
+ memcmp(&m_msg[m_b][i].rect, &m_msg[1-m_b][j].rect, sizeof(RECT))==0 && \
+ wcscmp(m_msg[m_b][i].msg, m_msg[1-m_b][j].msg)==0 )
+
+void CTextManager::DrawNow()
+{
+ if (!m_lpDevice)
+ return;
+
+ if (m_nMsg[m_b] > 0 || m_nMsg[1-m_b] > 0) // second condition req'd for clearing text in VJ mode
+ {
+ D3DXMATRIX Ortho2D;
+ pMatrixOrthoLH(&Ortho2D, 2.0f, -2.0f, 0.0f, 1.0f);
+ m_lpDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D);
+
+ #define NUM_DIRTY_RECTS 3
+ RECT dirty_rect[NUM_DIRTY_RECTS];
+ int dirty_rects_ready = 0;
+
+ int bRTT = (m_lpTextSurface==NULL) ? 0 : 1;
+ LPDIRECT3DSURFACE9 pBackBuffer=NULL;//, pZBuffer=NULL;
+ D3DSURFACE_DESC desc_backbuf, desc_text_surface;
+
+ // clear added/deleted flags
+ void* last_dark_box = NULL;
+ for (int i=0; i<m_nMsg[m_b]; i++)
+ {
+ m_msg[m_b][i].deleted = m_msg[m_b][i].added = 0;
+ m_msg[m_b][i].prev_dark_box_ptr = last_dark_box;
+ last_dark_box = (m_msg[m_b][i].pfont) ? last_dark_box : (void*)&m_msg[m_b][i];
+ }
+ last_dark_box = NULL;
+ int j = 0;
+ for (j = 0; j<m_nMsg[1-m_b]; j++)
+ {
+ m_msg[1-m_b][j].deleted = m_msg[1-m_b][j].added = 0;
+ m_msg[1-m_b][j].prev_dark_box_ptr = last_dark_box;
+ last_dark_box = (m_msg[1-m_b][j].pfont) ? last_dark_box : (void*)&m_msg[1-m_b][j];
+ }
+
+ int bRedrawText = 0;
+ if (!bRTT || (m_nMsg[m_b]>0 && m_nMsg[1-m_b]==0))
+ {
+ bRedrawText = 2; // redraw ALL
+ }
+ else
+ {
+ // try to synchronize the text strings from last frame + this frame,
+ // and label additions & deletions. algorithm will catch:
+ // -insertion of any # of items in one spot
+ // -deletion of any # of items from one spot
+ // -changes to 1 item
+ // -changes to 2 consecutive items
+ // (provided that the 2 text strings immediately bounding the
+ // additions/deletions/change(s) are left unchanged.)
+ // in any other case, all the text is just re-rendered.
+
+ int i = 0;
+ int j = 0;
+ while (i < m_nMsg[m_b] && j < m_nMsg[1-m_b])
+ {
+ // MATCH macro: first idx is record # for current stuff; second idx is record # for prev frame stuff.
+ if (MATCH(i,j))
+ {
+ i++;
+ j++;
+ }
+ else
+ {
+ int continue_now = 0;
+
+ // scan to see if something was added:
+ for (int i2=i+1; i2<m_nMsg[m_b]; i2++)
+ if (MATCH(i2,j))
+ {
+ for (int i3=i; i3<i2; i3++)
+ m_msg[m_b][i3].added = 1;
+ i = i2;
+ bRedrawText = 1;
+ continue_now = 1;
+ break;
+ }
+ if (continue_now)
+ continue;
+
+ // scan to see if something was deleted:
+ for (int j2=j+1; j2<m_nMsg[1-m_b]; j2++)
+ if (MATCH(i,j2))
+ {
+ for (int j3=j; j3<j2; j3++)
+ m_msg[1-m_b][j3].deleted = 1;
+ j = j2;
+ bRedrawText = 1;
+ continue_now = 1;
+ break;
+ }
+ if (continue_now)
+ continue;
+
+ // scan to see if just a small group of 1-4 items were changed
+ // [and are followed by two identical items again]
+ int break_now = 0;
+ for (int chgd=1; chgd<=4; chgd++)
+ {
+ if (i>=m_nMsg[m_b]-chgd || j>=m_nMsg[1-m_b]-chgd)
+ {
+ // only a few items left in one of the lists -> just finish it
+ bRedrawText = 1;
+ break_now = 1;
+ break;
+ }
+ if (i<m_nMsg[m_b]-chgd && j<m_nMsg[1-m_b]-chgd && MATCH(i+chgd, j+chgd))
+ {
+ for (int k=0; k<chgd; k++)
+ {
+ m_msg[ m_b][i+k].added = 1;
+ m_msg[1-m_b][j+k].deleted = 1;
+ }
+ i += chgd;
+ j += chgd;
+
+ bRedrawText = 1;
+ continue_now = 1;
+ break;
+ }
+ }
+ if (break_now)
+ break;
+ if (continue_now)
+ continue;
+
+ // otherwise, nontrivial case -> just re-render whole thing
+ bRedrawText = 2; // redraw ALL
+ break;
+ }
+ }
+
+ if (bRedrawText < 2)
+ {
+ while (i < m_nMsg[m_b])
+ {
+ m_msg[m_b][i].added = 1;
+ bRedrawText = 1;
+ i++;
+ }
+
+ while (j < m_nMsg[1-m_b])
+ {
+ m_msg[1-m_b][j].deleted = 1;
+ bRedrawText = 1;
+ j++;
+ }
+ }
+ }
+
+ // ------------------------------------------------------------
+
+ // 0. remember old render target & get surface descriptions
+ m_lpDevice->GetRenderTarget( 0, &pBackBuffer );
+ pBackBuffer->GetDesc(&desc_backbuf);
+
+ if (bRTT)
+ {
+ //if (m_lpDevice->GetDepthStencilSurface( &pZBuffer ) != D3D_OK)
+ // pZBuffer = NULL; // ok if return val != D3D_OK - just means there is no zbuffer.
+ if (m_lpTextSurface->GetLevelDesc(0, &desc_text_surface) != D3D_OK)
+ bRTT = 0;
+
+ m_lpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
+ m_lpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
+ m_lpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );
+ m_lpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
+
+ m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
+ m_lpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
+ m_lpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
+
+ m_lpDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
+ }
+ else
+ {
+ desc_text_surface = desc_backbuf;
+ }
+
+ if (bRTT && bRedrawText)
+ do
+ {
+ // 1. change render target
+ m_lpDevice->SetTexture(0, NULL);
+
+ IDirect3DSurface9* pNewTarget = NULL;
+ if (m_lpTextSurface->GetSurfaceLevel(0, &pNewTarget) != D3D_OK)
+ {
+ bRTT = 0;
+ break;
+ }
+ if (m_lpDevice->SetRenderTarget(0, pNewTarget) != D3D_OK)
+ {
+ pNewTarget->Release();
+ bRTT = 0;
+ break;
+ }
+ //m_lpDevice->SetDepthStencilSurface( ??? );
+ pNewTarget->Release();
+
+ m_lpDevice->SetTexture(0, NULL);
+
+ // 2. clear to black
+ //m_lpDevice->SetTexture(0, NULL);
+ m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ m_lpDevice->SetVertexShader( NULL );
+ m_lpDevice->SetFVF( WFVERTEX_FORMAT );
+ m_lpDevice->SetPixelShader( NULL );
+ WFVERTEX v3[4];
+ if (bRedrawText==2)
+ {
+ DWORD clearcolor = m_msg[m_b][j].bgColor;//0xFF000000;// | ((rand()%32)<<16) | ((rand()%32)<<8) | ((rand()%32));
+ int i = 0;
+ for (i=0; i<4; i++)
+ {
+ v3[i].x = -1.0f + 2.0f*(i%2);
+ v3[i].y = -1.0f + 2.0f*(i/2);
+ v3[i].z = 0;
+ v3[i].Diffuse = clearcolor;
+ }
+ m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v3, sizeof(WFVERTEX));
+ }
+ else
+ {
+ // 1. erase (draw black box over) any old text items deleted.
+ // also, update the dirty rects; stuff that was ABOVE/BELOW these guys will need redrawn!
+ // (..picture them staggered)
+ int j = 0;
+ for (j=0; j<m_nMsg[1-m_b]; j++)
+ {
+ // erase text from PREV frame if it was deleted.
+ if (m_msg[1-m_b][j].deleted)
+ {
+ float x0 = -1.0f + 2.0f*m_msg[1-m_b][j].rect.left/(float)desc_text_surface.Width;
+ float x1 = -1.0f + 2.0f*m_msg[1-m_b][j].rect.right/(float)desc_text_surface.Width;
+ float y0 = -1.0f + 2.0f*m_msg[1-m_b][j].rect.top/(float)desc_text_surface.Height;
+ float y1 = -1.0f + 2.0f*m_msg[1-m_b][j].rect.bottom/(float)desc_text_surface.Height;
+ int i = 0;
+ for (i=0; i<4; i++)
+ {
+ v3[i].x = (i%2) ? x0 : x1;
+ v3[i].y = (i/2) ? y0 : y1;
+ v3[i].z = 0;
+ v3[i].Diffuse = m_msg[m_b][j].bgColor;//0xFF000000;//0xFF300000;
+ }
+ m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v3, sizeof(WFVERTEX));
+
+ //----------------------------------
+
+ // special case:
+ // if something is erased, but it's totally inside a dark box,
+ // then don't add it to the dirty rectangle.
+ td_string* pDarkBox = (td_string*)m_msg[1-m_b][j].prev_dark_box_ptr;
+ int add_to_dirty_rect = 1;
+ while (pDarkBox && add_to_dirty_rect)
+ {
+ RECT t;
+ UnionRect(&t, &pDarkBox->rect, &m_msg[1-m_b][j].rect);
+ if (EqualRect(&t, &pDarkBox->rect))
+ add_to_dirty_rect = 0;
+ pDarkBox = (td_string*)pDarkBox->prev_dark_box_ptr;
+ }
+
+ // also, update dirty rects
+ // first, check to see if this shares area or a border w/any of the going dirty rects,
+ // and if so, expand that dirty rect.
+ if (add_to_dirty_rect)
+ {
+ int done = 0;
+ RECT t;
+ RECT r1 = m_msg[1-m_b][j].rect;
+ RECT r2 = m_msg[1-m_b][j].rect;
+ r2.top -= 1;
+ r2.left -= 1;
+ r2.right += 1;
+ r2.bottom += 1;
+ for (i=0; i<dirty_rects_ready; i++)
+ {
+ if (IntersectRect(&t, &r2, &dirty_rect[i]))
+ {
+ // expand the dirty rect to include r1
+ UnionRect(&t, &r1, &dirty_rect[i]);
+ dirty_rect[i] = t;
+ done = 1;
+ break;
+ }
+ }
+ if (done==1) continue;
+
+ // if it's in a new spot, and there are still unused dirty rects, use those
+ if (dirty_rects_ready < NUM_DIRTY_RECTS)
+ {
+ dirty_rect[dirty_rects_ready] = r1;
+ dirty_rects_ready++;
+ continue;
+ }
+
+ // otherwise, find the closest dirty rect...
+ float nearest_dist;
+ int nearest_id;
+ for (i=0; i<NUM_DIRTY_RECTS; i++)
+ {
+ int dx=0, dy=0;
+
+ if (r1.left > dirty_rect[i].right)
+ dx = r1.left - dirty_rect[i].right;
+ else if (dirty_rect[i].left > r1.right)
+ dx = dirty_rect[i].left - r1.right;
+
+ if (r1.top > dirty_rect[i].bottom)
+ dy = r1.top - dirty_rect[i].bottom;
+ else if (dirty_rect[i].top > r1.bottom)
+ dy = dirty_rect[i].top - r1.bottom;
+
+ float dist = sqrtf((float)(dx*dx + dy*dy));
+ if (i==0 || dist < nearest_dist)
+ {
+ nearest_dist = dist;
+ nearest_id = i;
+ }
+ }
+ //...and expand it to include this one.
+ UnionRect(&t, &r1, &dirty_rect[nearest_id]);
+ dirty_rect[nearest_id] = t;
+ }
+ }
+ }
+
+ // 2. erase AND REDRAW any of *this* frame's text that falls in dirty rects
+ // from erasures of *prev* frame's deleted text:
+ for (j=0; j<m_nMsg[m_b]; j++)
+ {
+ RECT t;
+ // note: none of these could be 'deleted' status yet.
+ if (!m_msg[m_b][j].added)
+ {
+ // check vs. dirty rects so far; if intersects any, erase + redraw this one.
+ for (int i=0; i<dirty_rects_ready; i++)
+ if (m_msg[m_b][j].pfont && // exclude dark boxes... //fixme?
+ IntersectRect(&t, &dirty_rect[i], &m_msg[m_b][j].rect))
+ {
+ float x0 = -1.0f + 2.0f*m_msg[m_b][j].rect.left/(float)desc_text_surface.Width;
+ float x1 = -1.0f + 2.0f*m_msg[m_b][j].rect.right/(float)desc_text_surface.Width;
+ float y0 = -1.0f + 2.0f*m_msg[m_b][j].rect.top/(float)desc_text_surface.Height;
+ float y1 = -1.0f + 2.0f*m_msg[m_b][j].rect.bottom/(float)desc_text_surface.Height;
+ for (int i=0; i<4; i++)
+ {
+ v3[i].x = (i%2) ? x0 : x1;
+ v3[i].y = (i/2) ? y0 : y1;
+ v3[i].z = 0;
+ v3[i].Diffuse = m_msg[m_b][j].bgColor;//0xFF000000;//0xFF000030;
+ }
+ m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v3, sizeof(WFVERTEX));
+
+ m_msg[m_b][j].deleted = 1;
+ m_msg[m_b][j].added = 1;
+ bRedrawText = 1;
+ }
+ }
+ }
+ }
+ }
+ while (0);
+
+ // 3. render text to TEXT surface
+ if (bRedrawText)
+ {
+ m_lpDevice->SetTexture(0, NULL);
+ m_lpDevice->SetTexture(1, NULL);
+ m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ m_lpDevice->SetVertexShader( NULL );
+ m_lpDevice->SetPixelShader( NULL );
+ m_lpDevice->SetFVF( WFVERTEX_FORMAT );
+
+ for (int i=0; i<m_nMsg[m_b]; i++)
+ if (bRedrawText==2 || m_msg[m_b][i].added==1)
+ if (m_msg[m_b][i].pfont) // dark boxes have pfont==NULL
+ // warning: in DX9, the DT_WORD_ELLIPSIS and DT_NOPREFIX flags cause no text to render!!
+ m_msg[m_b][i].pfont->DrawTextW(NULL, m_msg[m_b][i].msg, -1, &m_msg[m_b][i].rect, m_msg[m_b][i].flags, m_msg[m_b][i].color);
+ else if (m_msg[m_b][i].added || bRedrawText==2 || !bRTT)
+ {
+ WFVERTEX v3[4];
+ float x0 = -1.0f + 2.0f*m_msg[m_b][i].rect.left/(float)desc_text_surface.Width;
+ float x1 = -1.0f + 2.0f*m_msg[m_b][i].rect.right/(float)desc_text_surface.Width;
+ float y0 = -1.0f + 2.0f*m_msg[m_b][i].rect.top/(float)desc_text_surface.Height;
+ float y1 = -1.0f + 2.0f*m_msg[m_b][i].rect.bottom/(float)desc_text_surface.Height;
+ for (int k=0; k<4; k++)
+ {
+ v3[k].x = (k%2) ? x0 : x1;
+ v3[k].y = (k/2) ? y0 : y1;
+ v3[k].z = 0;
+ v3[k].Diffuse = m_msg[m_b][i].bgColor;//0xFF303000;
+ }
+ m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v3, sizeof(WFVERTEX));
+ }
+ }
+
+ if (bRTT)
+ {
+ // 4. restore render target
+ if (bRedrawText)
+ {
+ m_lpDevice->SetTexture(0, NULL);
+ m_lpDevice->SetRenderTarget( 0, pBackBuffer );//, pZBuffer );
+ //m_lpDevice->SetDepthStencilSurface( pZBuffer );
+ }
+
+ // 5. blit text surface to backbuffer
+ m_lpDevice->SetTexture(0, m_lpTextSurface);
+ m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, m_blit_additively ? TRUE : FALSE);
+ m_lpDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
+ m_lpDevice->SetRenderState(D3DRS_DESTBLEND, m_blit_additively ? D3DBLEND_ONE : D3DBLEND_ZERO);
+ m_lpDevice->SetVertexShader( NULL );
+ m_lpDevice->SetPixelShader( NULL );
+ m_lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+
+ SPRITEVERTEX v3[4];
+ ZeroMemory(v3, sizeof(SPRITEVERTEX)*4);
+ float fx = desc_text_surface.Width / (float)desc_backbuf.Width ;
+ float fy = desc_text_surface.Height / (float)desc_backbuf.Height;
+ for (int i=0; i<4; i++)
+ {
+ v3[i].x = (i%2==0) ? -1 : -1 + 2*fx;
+ v3[i].y = (i/2==0) ? -1 : -1 + 2*fy;
+ v3[i].z = 0;
+ v3[i].tu = ((i%2==0) ? 0.0f : 1.0f) + 0.5f/desc_text_surface.Width; // FIXES BLURRY TEXT even when bilinear interp. is on (which can't be turned off on all cards!)
+ v3[i].tv = ((i/2==0) ? 0.0f : 1.0f) + 0.5f/desc_text_surface.Height; // FIXES BLURRY TEXT even when bilinear interp. is on (which can't be turned off on all cards!)
+ v3[i].Diffuse = 0xFFFFFFFF;
+ }
+
+ DWORD oldblend[3];
+ //m_lpDevice->GetTextureStageState(0, D3DTSS_MAGFILTER, &oldblend[0]);
+ //m_lpDevice->GetTextureStageState(1, D3DTSS_MINFILTER, &oldblend[1]);
+ //m_lpDevice->GetTextureStageState(2, D3DTSS_MIPFILTER, &oldblend[2]);
+ m_lpDevice->GetSamplerState(0, D3DSAMP_MAGFILTER, &oldblend[0]);
+ m_lpDevice->GetSamplerState(1, D3DSAMP_MINFILTER, &oldblend[1]);
+ m_lpDevice->GetSamplerState(2, D3DSAMP_MIPFILTER, &oldblend[2]);
+ m_lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ m_lpDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ m_lpDevice->SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
+
+ m_lpDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v3, sizeof(SPRITEVERTEX));
+
+ m_lpDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, oldblend[0]);
+ m_lpDevice->SetSamplerState(1, D3DSAMP_MINFILTER, oldblend[1]);
+ m_lpDevice->SetSamplerState(2, D3DSAMP_MIPFILTER, oldblend[2]);
+
+ m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+
+ SafeRelease(pBackBuffer);
+ //SafeRelease(pZBuffer);
+
+ m_lpDevice->SetTexture(0, NULL);
+ m_lpDevice->SetTexture(1, NULL);
+ m_lpDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ m_lpDevice->SetVertexShader( NULL );
+ m_lpDevice->SetPixelShader( NULL );
+ m_lpDevice->SetFVF( SPRITEVERTEX_FORMAT );
+
+ //D3DXMATRIX ident;
+ //D3DXMatrixIdentity(&ident);
+ //m_lpDevice->SetTransform(D3DTS_PROJECTION, &ident);
+ }
+
+ // flip:
+ m_b = 1 - m_b;
+
+ ClearAll();
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/textmgr.h b/Src/Plugins/Visualization/vis_milk2/textmgr.h
new file mode 100644
index 00000000..9a62461c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/textmgr.h
@@ -0,0 +1,91 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef GEISS_TEXT_DRAWING_MANAGER
+#define GEISS_TEXT_DRAWING_MANAGER 1
+
+#ifdef _DEBUG
+ #define D3D_DEBUG_INFO // declare this before including d3d9.h
+#endif
+#include <d3d9.h>
+#include <d3dx9.h>
+#include "md_defines.h"
+#include "..\nu\AutoWide.h"
+
+#define MAX_MSGS 4096
+
+typedef struct
+{
+ wchar_t* msg; // points to some character in g_szMsgPool[2][].
+ LPD3DXFONT pfont; // note: iff this string is really a dark box, pfont will be NULL!
+ RECT rect;
+ DWORD flags;
+ DWORD color;
+ DWORD bgColor;
+ int added, deleted; // temporary; used during DrawNow()
+ void* prev_dark_box_ptr; // temporary; used during DrawNow()
+}
+td_string;
+
+class CTextManager
+{
+public:
+ CTextManager();
+ ~CTextManager();
+
+ // note: if you can't create lpTextSurface full-size, don't create it at all!
+ void Init(LPDIRECT3DDEVICE9 lpDevice, IDirect3DTexture9* lpTextSurface, int bAdditive); // note: ok if lpTextSurface==NULL; in that case, text will be drawn directly to screen (but not til end anyway).
+ void Finish();
+
+ // note: pFont must persist until DrawNow() is called!
+ int DrawText(LPD3DXFONT pFont, char* szText, RECT* pRect, DWORD flags, DWORD color, bool bBlackBox, DWORD boxColor=0xFF000000); // actually queues the text!
+ int DrawText(LPD3DXFONT pFont, char* szText, int len, RECT* pRect, DWORD flags, DWORD color, bool bBox, DWORD boxColor=0xFF000000) {
+ return DrawTextW(pFont, AutoWide(szText), pRect, flags, color, bBox, boxColor);
+ };
+ int DrawTextW(LPD3DXFONT pFont, wchar_t* szText, RECT* pRect, DWORD flags, DWORD color, bool bBlackBox, DWORD boxColor=0xFF000000); // actually queues the text!
+ int DrawTextW(LPD3DXFONT pFont, wchar_t* szText, int len, RECT* pRect, DWORD flags, DWORD color, bool bBox, DWORD boxColor=0xFF000000) {
+ return DrawTextW(pFont, szText, pRect, flags, color, bBox, boxColor);
+ };
+ void DrawBox(LPRECT pRect, DWORD boxColor);
+ void DrawDarkBox(LPRECT pRect) { DrawBox(pRect, 0xFF000000); }
+ void DrawNow();
+ void ClearAll(); // automatically called @ end of DrawNow()
+
+protected:
+ LPDIRECT3DDEVICE9 m_lpDevice;
+ IDirect3DTexture9* m_lpTextSurface;
+ int m_blit_additively;
+
+ int m_nMsg[2];
+ td_string m_msg[2][MAX_MSGS];
+ wchar_t* m_next_msg_start_ptr;
+ int m_b;
+};
+
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/utility.cpp b/Src/Plugins/Visualization/vis_milk2/utility.cpp
new file mode 100644
index 00000000..a59f2e02
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/utility.cpp
@@ -0,0 +1,1259 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include "utility.h"
+#include <math.h>
+#include <locale.h>
+#include <windows.h>
+#ifdef _DEBUG
+ #define D3D_DEBUG_INFO // declare this before including d3d9.h
+#endif
+#include <d3d9.h>
+#include "../Winamp/wa_ipc.h"
+#include "resource.h"
+#include <shellapi.h>
+
+intptr_t myOpenURL(HWND hwnd, wchar_t *loc)
+{
+ if (loc)
+ {
+ bool override=false;
+ WASABI_API_SYSCB->syscb_issueCallback(SysCallback::BROWSER, BrowserCallback::ONOPENURL, reinterpret_cast<intptr_t>(loc), reinterpret_cast<intptr_t>(&override));
+ if (!override)
+ return (intptr_t)ShellExecuteW(hwnd, L"open", loc, NULL, NULL, SW_SHOWNORMAL);
+ else
+ return 33;
+ }
+ return 33;
+}
+
+float PowCosineInterp(float x, float pow)
+{
+ // input (x) & output should be in range 0..1.
+ // pow > 0: tends to push things toward 0 and 1
+ // pow < 0: tends to push things toward 0.5.
+
+ if (x<0)
+ return 0;
+ if (x>1)
+ return 1;
+
+ int bneg = (pow < 0) ? 1 : 0;
+ if (bneg)
+ pow = -pow;
+
+ if (pow>1000) pow=1000;
+
+ int its = (int)pow;
+ for (int i=0; i<its; i++)
+ {
+ if (bneg)
+ x = InvCosineInterp(x);
+ else
+ x = CosineInterp(x);
+ }
+ float x2 = (bneg) ? InvCosineInterp(x) : CosineInterp(x);
+ float dx = pow - its;
+ return ((1-dx)*x + (dx)*x2);
+}
+
+float AdjustRateToFPS(float per_frame_decay_rate_at_fps1, float fps1, float actual_fps)
+{
+ // returns the equivalent per-frame decay rate at actual_fps
+
+ // basically, do all your testing at fps1 and get a good decay rate;
+ // then, in the real application, adjust that rate by the actual fps each time you use it.
+
+ float per_second_decay_rate_at_fps1 = powf(per_frame_decay_rate_at_fps1, fps1);
+ float per_frame_decay_rate_at_fps2 = powf(per_second_decay_rate_at_fps1, 1.0f/actual_fps);
+
+ return per_frame_decay_rate_at_fps2;
+}
+
+float GetPrivateProfileFloatW(wchar_t *szSectionName, wchar_t *szKeyName, float fDefault, wchar_t *szIniFile)
+{
+ wchar_t string[64];
+ wchar_t szDefault[64];
+ float ret = fDefault;
+
+ _swprintf_l(szDefault, L"%f", g_use_C_locale, fDefault);
+
+ if (GetPrivateProfileStringW(szSectionName, szKeyName, szDefault, string, 64, szIniFile) > 0)
+ {
+ _swscanf_l(string, L"%f", g_use_C_locale, &ret);
+ }
+ return ret;
+}
+
+bool WritePrivateProfileFloatW(float f, wchar_t *szKeyName, wchar_t *szIniFile, wchar_t *szSectionName)
+{
+ wchar_t szValue[32];
+ _swprintf_l(szValue, L"%f", g_use_C_locale, f);
+ return (WritePrivateProfileStringW(szSectionName, szKeyName, szValue, szIniFile) != 0);
+}
+
+bool WritePrivateProfileIntW(int d, wchar_t *szKeyName, wchar_t *szIniFile, wchar_t *szSectionName)
+{
+ wchar_t szValue[32];
+ swprintf(szValue, L"%d", d);
+ return (WritePrivateProfileStringW(szSectionName, szKeyName, szValue, szIniFile) != 0);
+}
+
+void SetScrollLock(int bNewState, bool bPreventHandling)
+{
+ if(bPreventHandling) return;
+
+ if (bNewState != (GetKeyState(VK_SCROLL) & 1))
+ {
+ // Simulate a key press
+ keybd_event( VK_SCROLL,
+ 0x45,
+ KEYEVENTF_EXTENDEDKEY | 0,
+ 0 );
+
+ // Simulate a key release
+ keybd_event( VK_SCROLL,
+ 0x45,
+ KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
+ 0);
+ }
+}
+
+void RemoveExtension(wchar_t *str)
+{
+ wchar_t *p = wcsrchr(str, L'.');
+ if (p) *p = 0;
+}
+
+static void ShiftDown(wchar_t *str)
+{
+ while (*str)
+ {
+ str[0] = str[1];
+ str++;
+ }
+}
+
+void RemoveSingleAmpersands(wchar_t *str)
+{
+ while (*str)
+ {
+ if (str[0] == L'&')
+ {
+ if (str[1] == L'&') // two in a row: replace with single ampersand, move on
+ str++;
+
+ ShiftDown(str);
+ }
+ else
+ str = CharNextW(str);
+ }
+}
+
+void TextToGuid(char *str, GUID *pGUID)
+{
+ if (!str) return;
+ if (!pGUID) return;
+
+ DWORD d[11];
+
+ sscanf(str, "%X %X %X %X %X %X %X %X %X %X %X",
+ &d[0], &d[1], &d[2], &d[3], &d[4], &d[5], &d[6], &d[7], &d[8], &d[9], &d[10]);
+
+ pGUID->Data1 = (DWORD)d[0];
+ pGUID->Data2 = (WORD)d[1];
+ pGUID->Data3 = (WORD)d[2];
+ pGUID->Data4[0] = (BYTE)d[3];
+ pGUID->Data4[1] = (BYTE)d[4];
+ pGUID->Data4[2] = (BYTE)d[5];
+ pGUID->Data4[3] = (BYTE)d[6];
+ pGUID->Data4[4] = (BYTE)d[7];
+ pGUID->Data4[5] = (BYTE)d[8];
+ pGUID->Data4[6] = (BYTE)d[9];
+ pGUID->Data4[7] = (BYTE)d[10];
+}
+
+void GuidToText(GUID *pGUID, char *str, int nStrLen)
+{
+ // note: nStrLen should be set to sizeof(str).
+ if (!str) return;
+ if (!nStrLen) return;
+ str[0] = 0;
+ if (!pGUID) return;
+
+ DWORD d[11];
+ d[0] = (DWORD)pGUID->Data1;
+ d[1] = (DWORD)pGUID->Data2;
+ d[2] = (DWORD)pGUID->Data3;
+ d[3] = (DWORD)pGUID->Data4[0];
+ d[4] = (DWORD)pGUID->Data4[1];
+ d[5] = (DWORD)pGUID->Data4[2];
+ d[6] = (DWORD)pGUID->Data4[3];
+ d[7] = (DWORD)pGUID->Data4[4];
+ d[8] = (DWORD)pGUID->Data4[5];
+ d[9] = (DWORD)pGUID->Data4[6];
+ d[10] = (DWORD)pGUID->Data4[7];
+
+ sprintf(str, "%08X %04X %04X %02X %02X %02X %02X %02X %02X %02X %02X",
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10]);
+}
+
+/*
+int GetPentiumTimeRaw(unsigned __int64 *cpu_timestamp)
+{
+ // returns 0 on failure, 1 on success
+ // warning: watch out for wraparound!
+
+ // note: it's probably better to use QueryPerformanceFrequency
+ // and QueryPerformanceCounter()!
+
+ // get high-precision time:
+ __try
+ {
+ unsigned __int64 *dest = (unsigned __int64 *)cpu_timestamp;
+ __asm
+ {
+ _emit 0xf // these two bytes form the 'rdtsc' asm instruction,
+ _emit 0x31 // available on Pentium I and later.
+ mov esi, dest
+ mov [esi ], eax // lower 32 bits of tsc
+ mov [esi+4], edx // upper 32 bits of tsc
+ }
+ return 1;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ return 0;
+ }
+
+ return 0;
+}
+
+double GetPentiumTimeAsDouble(unsigned __int64 frequency)
+{
+ // returns < 0 on failure; otherwise, returns current cpu time, in seconds.
+ // warning: watch out for wraparound!
+
+ // note: it's probably better to use QueryPerformanceFrequency
+ // and QueryPerformanceCounter()!
+
+ if (frequency==0)
+ return -1.0;
+
+ // get high-precision time:
+ __try
+ {
+ unsigned __int64 high_perf_time;
+ unsigned __int64 *dest = &high_perf_time;
+ __asm
+ {
+ _emit 0xf // these two bytes form the 'rdtsc' asm instruction,
+ _emit 0x31 // available on Pentium I and later.
+ mov esi, dest
+ mov [esi ], eax // lower 32 bits of tsc
+ mov [esi+4], edx // upper 32 bits of tsc
+ }
+ __int64 time_s = (__int64)(high_perf_time / frequency); // unsigned->sign conversion should be safe here
+ __int64 time_fract = (__int64)(high_perf_time % frequency); // unsigned->sign conversion should be safe here
+ // note: here, we wrap the timer more frequently (once per week)
+ // than it otherwise would (VERY RARELY - once every 585 years on
+ // a 1 GHz), to alleviate floating-point precision errors that start
+ // to occur when you get to very high counter values.
+ double ret = (time_s % (60*60*24*7)) + (double)time_fract/(double)((__int64)frequency);
+ return ret;
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ return -1.0;
+ }
+
+ return -1.0;
+}
+*/
+
+#ifdef _DEBUG
+ void OutputDebugMessage(char *szStartText, HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+ {
+ // note: this function does NOT log WM_MOUSEMOVE, WM_NCHITTEST, or WM_SETCURSOR
+ // messages, since they are so frequent.
+ // note: these identifiers were pulled from winuser.h
+
+ //if (msg == WM_MOUSEMOVE || msg == WM_NCHITTEST || msg == WM_SETCURSOR)
+ // return;
+
+ #ifdef _DEBUG
+ char buf[64];
+ int matched = 1;
+
+ sprintf(buf, "WM_");
+
+ switch(msg)
+ {
+ case 0x0001: lstrcat(buf, "CREATE"); break;
+ case 0x0002: lstrcat(buf, "DESTROY"); break;
+ case 0x0003: lstrcat(buf, "MOVE"); break;
+ case 0x0005: lstrcat(buf, "SIZE"); break;
+ case 0x0006: lstrcat(buf, "ACTIVATE"); break;
+ case 0x0007: lstrcat(buf, "SETFOCUS"); break;
+ case 0x0008: lstrcat(buf, "KILLFOCUS"); break;
+ case 0x000A: lstrcat(buf, "ENABLE"); break;
+ case 0x000B: lstrcat(buf, "SETREDRAW"); break;
+ case 0x000C: lstrcat(buf, "SETTEXT"); break;
+ case 0x000D: lstrcat(buf, "GETTEXT"); break;
+ case 0x000E: lstrcat(buf, "GETTEXTLENGTH"); break;
+ case 0x000F: lstrcat(buf, "PAINT"); break;
+ case 0x0010: lstrcat(buf, "CLOSE"); break;
+ case 0x0011: lstrcat(buf, "QUERYENDSESSION"); break;
+ case 0x0012: lstrcat(buf, "QUIT"); break;
+ case 0x0013: lstrcat(buf, "QUERYOPEN"); break;
+ case 0x0014: lstrcat(buf, "ERASEBKGND"); break;
+ case 0x0015: lstrcat(buf, "SYSCOLORCHANGE"); break;
+ case 0x0016: lstrcat(buf, "ENDSESSION"); break;
+ case 0x0018: lstrcat(buf, "SHOWWINDOW"); break;
+ case 0x001A: lstrcat(buf, "WININICHANGE"); break;
+ case 0x001B: lstrcat(buf, "DEVMODECHANGE"); break;
+ case 0x001C: lstrcat(buf, "ACTIVATEAPP"); break;
+ case 0x001D: lstrcat(buf, "FONTCHANGE"); break;
+ case 0x001E: lstrcat(buf, "TIMECHANGE"); break;
+ case 0x001F: lstrcat(buf, "CANCELMODE"); break;
+ case 0x0020: lstrcat(buf, "SETCURSOR"); break;
+ case 0x0021: lstrcat(buf, "MOUSEACTIVATE"); break;
+ case 0x0022: lstrcat(buf, "CHILDACTIVATE"); break;
+ case 0x0023: lstrcat(buf, "QUEUESYNC"); break;
+ case 0x0024: lstrcat(buf, "GETMINMAXINFO"); break;
+ case 0x0026: lstrcat(buf, "PAINTICON"); break;
+ case 0x0027: lstrcat(buf, "ICONERASEBKGND"); break;
+ case 0x0028: lstrcat(buf, "NEXTDLGCTL"); break;
+ case 0x002A: lstrcat(buf, "SPOOLERSTATUS"); break;
+ case 0x002B: lstrcat(buf, "DRAWITEM"); break;
+ case 0x002C: lstrcat(buf, "MEASUREITEM"); break;
+ case 0x002D: lstrcat(buf, "DELETEITEM"); break;
+ case 0x002E: lstrcat(buf, "VKEYTOITEM"); break;
+ case 0x002F: lstrcat(buf, "CHARTOITEM"); break;
+ case 0x0030: lstrcat(buf, "SETFONT"); break;
+ case 0x0031: lstrcat(buf, "GETFONT"); break;
+ case 0x0032: lstrcat(buf, "SETHOTKEY"); break;
+ case 0x0033: lstrcat(buf, "GETHOTKEY"); break;
+ case 0x0037: lstrcat(buf, "QUERYDRAGICON"); break;
+ case 0x0039: lstrcat(buf, "COMPAREITEM"); break;
+ case 0x0041: lstrcat(buf, "COMPACTING"); break;
+ case 0x0044: lstrcat(buf, "COMMNOTIFY"); break;
+ case 0x0046: lstrcat(buf, "WINDOWPOSCHANGING"); break;
+ case 0x0047: lstrcat(buf, "WINDOWPOSCHANGED"); break;
+ case 0x0048: lstrcat(buf, "POWER"); break;
+ case 0x004A: lstrcat(buf, "COPYDATA"); break;
+ case 0x004B: lstrcat(buf, "CANCELJOURNAL"); break;
+
+ #if(WINVER >= 0x0400)
+ case 0x004E: lstrcat(buf, "NOTIFY"); break;
+ case 0x0050: lstrcat(buf, "INPUTLANGCHANGEREQUEST"); break;
+ case 0x0051: lstrcat(buf, "INPUTLANGCHANGE"); break;
+ case 0x0052: lstrcat(buf, "TCARD"); break;
+ case 0x0053: lstrcat(buf, "HELP"); break;
+ case 0x0054: lstrcat(buf, "USERCHANGED"); break;
+ case 0x0055: lstrcat(buf, "NOTIFYFORMAT"); break;
+ case 0x007B: lstrcat(buf, "CONTEXTMENU"); break;
+ case 0x007C: lstrcat(buf, "STYLECHANGING"); break;
+ case 0x007D: lstrcat(buf, "STYLECHANGED"); break;
+ case 0x007E: lstrcat(buf, "DISPLAYCHANGE"); break;
+ case 0x007F: lstrcat(buf, "GETICON"); break;
+ case 0x0080: lstrcat(buf, "SETICON"); break;
+ #endif
+
+ case 0x0081: lstrcat(buf, "NCCREATE"); break;
+ case 0x0082: lstrcat(buf, "NCDESTROY"); break;
+ case 0x0083: lstrcat(buf, "NCCALCSIZE"); break;
+ case 0x0084: lstrcat(buf, "NCHITTEST"); break;
+ case 0x0085: lstrcat(buf, "NCPAINT"); break;
+ case 0x0086: lstrcat(buf, "NCACTIVATE"); break;
+ case 0x0087: lstrcat(buf, "GETDLGCODE"); break;
+ case 0x0088: lstrcat(buf, "SYNCPAINT"); break;
+ case 0x00A0: lstrcat(buf, "NCMOUSEMOVE"); break;
+ case 0x00A1: lstrcat(buf, "NCLBUTTONDOWN"); break;
+ case 0x00A2: lstrcat(buf, "NCLBUTTONUP"); break;
+ case 0x00A3: lstrcat(buf, "NCLBUTTONDBLCLK"); break;
+ case 0x00A4: lstrcat(buf, "NCRBUTTONDOWN"); break;
+ case 0x00A5: lstrcat(buf, "NCRBUTTONUP"); break;
+ case 0x00A6: lstrcat(buf, "NCRBUTTONDBLCLK"); break;
+ case 0x00A7: lstrcat(buf, "NCMBUTTONDOWN"); break;
+ case 0x00A8: lstrcat(buf, "NCMBUTTONUP"); break;
+ case 0x00A9: lstrcat(buf, "NCMBUTTONDBLCLK"); break;
+ case 0x0100: lstrcat(buf, "KEYDOWN"); break;
+ case 0x0101: lstrcat(buf, "KEYUP"); break;
+ case 0x0102: lstrcat(buf, "CHAR"); break;
+ case 0x0103: lstrcat(buf, "DEADCHAR"); break;
+ case 0x0104: lstrcat(buf, "SYSKEYDOWN"); break;
+ case 0x0105: lstrcat(buf, "SYSKEYUP"); break;
+ case 0x0106: lstrcat(buf, "SYSCHAR"); break;
+ case 0x0107: lstrcat(buf, "SYSDEADCHAR"); break;
+ case 0x0108: lstrcat(buf, "KEYLAST"); break;
+
+ #if(WINVER >= 0x0400)
+ case 0x010D: lstrcat(buf, "IME_STARTCOMPOSITION"); break;
+ case 0x010E: lstrcat(buf, "IME_ENDCOMPOSITION"); break;
+ case 0x010F: lstrcat(buf, "IME_COMPOSITION"); break;
+ //case 0x010F: lstrcat(buf, "IME_KEYLAST"); break;
+ #endif
+
+ case 0x0110: lstrcat(buf, "INITDIALOG"); break;
+ case 0x0111: lstrcat(buf, "COMMAND"); break;
+ case 0x0112: lstrcat(buf, "SYSCOMMAND"); break;
+ case 0x0113: lstrcat(buf, "TIMER"); break;
+ case 0x0114: lstrcat(buf, "HSCROLL"); break;
+ case 0x0115: lstrcat(buf, "VSCROLL"); break;
+ case 0x0116: lstrcat(buf, "INITMENU"); break;
+ case 0x0117: lstrcat(buf, "INITMENUPOPUP"); break;
+ case 0x011F: lstrcat(buf, "MENUSELECT"); break;
+ case 0x0120: lstrcat(buf, "MENUCHAR"); break;
+ case 0x0121: lstrcat(buf, "ENTERIDLE"); break;
+ #if(WINVER >= 0x0500)
+ case 0x0122: lstrcat(buf, "MENURBUTTONUP"); break;
+ case 0x0123: lstrcat(buf, "MENUDRAG"); break;
+ case 0x0124: lstrcat(buf, "MENUGETOBJECT"); break;
+ case 0x0125: lstrcat(buf, "UNINITMENUPOPUP"); break;
+ case 0x0126: lstrcat(buf, "MENUCOMMAND"); break;
+ #endif
+
+ case 0x0132: lstrcat(buf, "CTLCOLORMSGBOX"); break;
+ case 0x0133: lstrcat(buf, "CTLCOLOREDIT"); break;
+ case 0x0134: lstrcat(buf, "CTLCOLORLISTBOX"); break;
+ case 0x0135: lstrcat(buf, "CTLCOLORBTN"); break;
+ case 0x0136: lstrcat(buf, "CTLCOLORDLG"); break;
+ case 0x0137: lstrcat(buf, "CTLCOLORSCROLLBAR"); break;
+ case 0x0138: lstrcat(buf, "CTLCOLORSTATIC"); break;
+
+ //case 0x0200: lstrcat(buf, "MOUSEFIRST"); break;
+ case 0x0200: lstrcat(buf, "MOUSEMOVE"); break;
+ case 0x0201: lstrcat(buf, "LBUTTONDOWN"); break;
+ case 0x0202: lstrcat(buf, "LBUTTONUP"); break;
+ case 0x0203: lstrcat(buf, "LBUTTONDBLCLK"); break;
+ case 0x0204: lstrcat(buf, "RBUTTONDOWN"); break;
+ case 0x0205: lstrcat(buf, "RBUTTONUP"); break;
+ case 0x0206: lstrcat(buf, "RBUTTONDBLCLK"); break;
+ case 0x0207: lstrcat(buf, "MBUTTONDOWN"); break;
+ case 0x0208: lstrcat(buf, "MBUTTONUP"); break;
+ case 0x0209: lstrcat(buf, "MBUTTONDBLCLK"); break;
+
+ #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
+ case 0x020A: lstrcat(buf, "MOUSEWHEEL"); break;
+ case 0x020E: lstrcat(buf, "MOUSELAST"); break;
+ #else
+ //case 0x0209: lstrcat(buf, "MOUSELAST"); break;
+ #endif
+
+ case 0x0210: lstrcat(buf, "PARENTNOTIFY"); break;
+ case 0x0211: lstrcat(buf, "ENTERMENULOOP"); break;
+ case 0x0212: lstrcat(buf, "EXITMENULOOP"); break;
+
+ #if(WINVER >= 0x0400)
+ case 0x0213: lstrcat(buf, "NEXTMENU"); break;
+ case 0x0214: lstrcat(buf, "SIZING"); break;
+ case 0x0215: lstrcat(buf, "CAPTURECHANGED"); break;
+ case 0x0216: lstrcat(buf, "MOVING"); break;
+ case 0x0218: lstrcat(buf, "POWERBROADCAST"); break;
+ case 0x0219: lstrcat(buf, "DEVICECHANGE"); break;
+ #endif
+
+ /*
+ case 0x0220: lstrcat(buf, "MDICREATE"); break;
+ case 0x0221: lstrcat(buf, "MDIDESTROY"); break;
+ case 0x0222: lstrcat(buf, "MDIACTIVATE"); break;
+ case 0x0223: lstrcat(buf, "MDIRESTORE"); break;
+ case 0x0224: lstrcat(buf, "MDINEXT"); break;
+ case 0x0225: lstrcat(buf, "MDIMAXIMIZE"); break;
+ case 0x0226: lstrcat(buf, "MDITILE"); break;
+ case 0x0227: lstrcat(buf, "MDICASCADE"); break;
+ case 0x0228: lstrcat(buf, "MDIICONARRANGE"); break;
+ case 0x0229: lstrcat(buf, "MDIGETACTIVE"); break;
+ */
+
+ case 0x0230: lstrcat(buf, "MDISETMENU"); break;
+ case 0x0231: lstrcat(buf, "ENTERSIZEMOVE"); break;
+ case 0x0232: lstrcat(buf, "EXITSIZEMOVE"); break;
+ case 0x0233: lstrcat(buf, "DROPFILES"); break;
+ case 0x0234: lstrcat(buf, "MDIREFRESHMENU"); break;
+
+
+ /*
+ #if(WINVER >= 0x0400)
+ case 0x0281: lstrcat(buf, "IME_SETCONTEXT"); break;
+ case 0x0282: lstrcat(buf, "IME_NOTIFY"); break;
+ case 0x0283: lstrcat(buf, "IME_CONTROL"); break;
+ case 0x0284: lstrcat(buf, "IME_COMPOSITIONFULL"); break;
+ case 0x0285: lstrcat(buf, "IME_SELECT"); break;
+ case 0x0286: lstrcat(buf, "IME_CHAR"); break;
+ #endif
+ #if(WINVER >= 0x0500)
+ case 0x0288: lstrcat(buf, "IME_REQUEST"); break;
+ #endif
+ #if(WINVER >= 0x0400)
+ case 0x0290: lstrcat(buf, "IME_KEYDOWN"); break;
+ case 0x0291: lstrcat(buf, "IME_KEYUP"); break;
+ #endif
+ */
+
+ #if(_WIN32_WINNT >= 0x0400)
+ case 0x02A1: lstrcat(buf, "MOUSEHOVER"); break;
+ case 0x02A3: lstrcat(buf, "MOUSELEAVE"); break;
+ #endif
+
+ case 0x0300: lstrcat(buf, "CUT"); break;
+ case 0x0301: lstrcat(buf, "COPY"); break;
+ case 0x0302: lstrcat(buf, "PASTE"); break;
+ case 0x0303: lstrcat(buf, "CLEAR"); break;
+ case 0x0304: lstrcat(buf, "UNDO"); break;
+ case 0x0305: lstrcat(buf, "RENDERFORMAT"); break;
+ case 0x0306: lstrcat(buf, "RENDERALLFORMATS"); break;
+ case 0x0307: lstrcat(buf, "DESTROYCLIPBOARD"); break;
+ case 0x0308: lstrcat(buf, "DRAWCLIPBOARD"); break;
+ case 0x0309: lstrcat(buf, "PAINTCLIPBOARD"); break;
+ case 0x030A: lstrcat(buf, "VSCROLLCLIPBOARD"); break;
+ case 0x030B: lstrcat(buf, "SIZECLIPBOARD"); break;
+ case 0x030C: lstrcat(buf, "ASKCBFORMATNAME"); break;
+ case 0x030D: lstrcat(buf, "CHANGECBCHAIN"); break;
+ case 0x030E: lstrcat(buf, "HSCROLLCLIPBOARD"); break;
+ case 0x030F: lstrcat(buf, "QUERYNEWPALETTE"); break;
+ case 0x0310: lstrcat(buf, "PALETTEISCHANGING"); break;
+ case 0x0311: lstrcat(buf, "PALETTECHANGED"); break;
+ case 0x0312: lstrcat(buf, "HOTKEY"); break;
+
+ #if(WINVER >= 0x0400)
+ case 0x0317: lstrcat(buf, "PRINT"); break;
+ case 0x0318: lstrcat(buf, "PRINTCLIENT"); break;
+
+ case 0x0358: lstrcat(buf, "HANDHELDFIRST"); break;
+ case 0x035F: lstrcat(buf, "HANDHELDLAST"); break;
+
+ case 0x0360: lstrcat(buf, "AFXFIRST"); break;
+ case 0x037F: lstrcat(buf, "AFXLAST"); break;
+ #endif
+
+ case 0x0380: lstrcat(buf, "PENWINFIRST"); break;
+ case 0x038F: lstrcat(buf, "PENWINLAST"); break;
+
+ default:
+ sprintf(buf, "unknown");
+ matched = 0;
+ break;
+ }
+
+ int n = strlen(buf);
+ int desired_len = 24;
+ int spaces_to_append = desired_len-n;
+ if (spaces_to_append>0)
+ {
+ for (int i=0; i<spaces_to_append; i++)
+ buf[n+i] = ' ';
+ buf[desired_len] = 0;
+ }
+
+ char buf2[256];
+ if (matched)
+ sprintf(buf2, "%shwnd=%08x, msg=%s, w=%08x, l=%08x\n", szStartText, hwnd, buf, wParam, lParam);
+ else
+ sprintf(buf2, "%shwnd=%08x, msg=unknown/0x%08x, w=%08x, l=%08x\n", szStartText, hwnd, msg, wParam, lParam);
+ OutputDebugString(buf2);
+ #endif
+ }
+#endif
+
+void DownloadDirectX(HWND hwnd)
+{
+ wchar_t szUrl[] = L"http://www.microsoft.com/download/details.aspx?id=35";
+ intptr_t ret = myOpenURL(NULL, szUrl);
+ if (ret <= 32)
+ {
+ wchar_t buf[1024];
+ switch(ret)
+ {
+ case SE_ERR_FNF:
+ case SE_ERR_PNF:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_URL_COULD_NOT_OPEN), szUrl);
+ break;
+ case SE_ERR_ACCESSDENIED:
+ case SE_ERR_SHARE:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_WAS_DENIED), szUrl);
+ break;
+ case SE_ERR_NOASSOC:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_FAILED_DUE_TO_NO_ASSOC), szUrl);
+ break;
+ default:
+ swprintf(buf, WASABI_API_LNGSTRINGW(IDS_ACCESS_TO_URL_FAILED_CODE_X), szUrl, ret);
+ break;
+ }
+ MessageBoxW(hwnd, buf, WASABI_API_LNGSTRINGW(IDS_ERROR_OPENING_URL),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+}
+
+void MissingDirectX(HWND hwnd)
+{
+ // DIRECTX MISSING OR CORRUPT -> PROMPT TO GO TO WEB.
+ wchar_t title[128];
+ int ret = MessageBoxW(hwnd,
+ #ifndef D3D_SDK_VERSION
+ --- error; you need to #include <d3d9.h> ---
+ #endif
+ #if (D3D_SDK_VERSION==120)
+ // plugin was *built* using the DirectX 9.0 sdk, therefore,
+ // the dx9.0 runtime is missing or corrupt
+ "Failed to initialize DirectX 9.0 or later.\n"
+ "Milkdrop requires d3dx9_31.dll to be installed.\n"
+ "\n"
+ "Would you like to be taken to:\n"
+ "http://www.microsoft.com/download/details.aspx?id=35,\n"
+ "where you can update DirectX 9.0?\n"
+ XXXXXXX
+ #else
+ // plugin was *built* using some other version of the DirectX9 sdk, such as
+ // 9.1b; therefore, we don't know exactly what version to tell them they need
+ // to install; so we ask them to go get the *latest* version.
+ WASABI_API_LNGSTRINGW(IDS_DIRECTX_MISSING_OR_CORRUPT_TEXT)
+ #endif
+ ,
+ WASABI_API_LNGSTRINGW_BUF(IDS_DIRECTX_MISSING_OR_CORRUPT, title, 128),
+ MB_YESNO|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+
+ if (ret==IDYES)
+ DownloadDirectX(hwnd);
+}
+
+bool CheckForMMX()
+{
+#ifdef _WIN64
+ return true; // All x64 processors support SSE
+#else
+ DWORD bMMX = 0;
+ DWORD *pbMMX = &bMMX;
+ __try {
+ __asm {
+ mov eax, 1
+ cpuid
+ mov edi, pbMMX
+ mov dword ptr [edi], edx
+ }
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ bMMX = 0;
+ }
+
+ if (bMMX & 0x00800000) // check bit 23
+ return true;
+
+ return false;
+#endif
+}
+
+bool CheckForSSE()
+{
+#ifdef _WIN64
+ return true; // All x64 processors support SSE
+#else
+ /*
+ The SSE instruction set was introduced with the Pentium III and features:
+ * Additional MMX instructions such as min/max
+ * Prefetch and write-through instructions for optimizing data movement
+ from and to the L2/L3 caches and main memory
+ * 8 New 128 bit XMM registers (xmm0..xmm7) and corresponding 32 bit floating point
+ (single precision) instructions
+ */
+
+ DWORD bSSE = 0;
+ DWORD *pbSSE = &bSSE;
+ __try {
+ __asm
+ {
+ mov eax, 1
+ cpuid
+ mov edi, pbSSE
+ mov dword ptr [edi], edx
+ }
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ bSSE = 0;
+ }
+
+ if (bSSE & 0x02000000) // check bit 25
+ return true;
+
+ return false;
+#endif
+}
+
+void GetDesktopFolder(char *szDesktopFolder) // should be MAX_PATH len.
+{
+ // returns the path to the desktop folder, WITHOUT a trailing backslash.
+ szDesktopFolder[0] = 0;
+ ITEMIDLIST pidl;
+ ZeroMemory(&pidl, sizeof(pidl));
+ if (!SHGetPathFromIDList(&pidl, szDesktopFolder))
+ szDesktopFolder[0] = 0;
+}
+
+void ExecutePidl(LPITEMIDLIST pidl, char *szPathAndFile, char *szWorkingDirectory, HWND hWnd)
+{
+ // This function was based on code by Jeff Prosise.
+
+ // Note: for some reason, ShellExecuteEx fails when executing
+ // *shortcuts* (.lnk files) from the desktop, using their PIDLs.
+ // So, if that fails, we try again w/the plain old text filename
+ // (szPathAndFile).
+
+ char szVerb[] = "open";
+ char szFilename2[MAX_PATH];
+
+ sprintf(szFilename2, "%s.lnk", szPathAndFile);
+
+ // -without the "no-verb" pass,
+ // certain icons still don't work (like shortcuts
+ // to IE, VTune...)
+ // -without the "context menu" pass,
+ // certain others STILL don't work (Netscape...)
+ // -without the 'ntry' pass, shortcuts (to folders/files)
+ // don't work
+ for (int verb_pass=0; verb_pass<2; verb_pass++)
+ {
+ for (int ntry=0; ntry<3; ntry++)
+ {
+ for (int context_pass=0; context_pass<2; context_pass++)
+ {
+ SHELLEXECUTEINFO sei = { sizeof(sei) };
+ sei.hwnd = hWnd;
+ sei.fMask = SEE_MASK_FLAG_NO_UI;
+ if (context_pass==1)
+ sei.fMask |= SEE_MASK_INVOKEIDLIST;
+ sei.lpVerb = (verb_pass) ? NULL : szVerb;
+ sei.lpDirectory = szWorkingDirectory;
+ sei.nShow = SW_SHOWNORMAL;
+
+ if (ntry==0)
+ {
+ // this case works for most non-shortcuts
+ sei.fMask |= SEE_MASK_IDLIST;
+ sei.lpIDList = pidl;
+ }
+ else if (ntry==1)
+ {
+ // this case is required for *shortcuts to folders* to work
+ sei.lpFile = szPathAndFile;
+ }
+ else if (ntry==2)
+ {
+ // this case is required for *shortcuts to files* to work
+ sei.lpFile = szFilename2;
+ }
+
+ if (ShellExecuteEx(&sei))
+ return;
+ }
+ }
+ }
+}
+
+WNDPROC g_pOldWndProc;
+LPCONTEXTMENU2 g_pIContext2or3;
+
+LRESULT CALLBACK HookWndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ //UINT uItem;
+ //TCHAR szBuf[MAX_PATH];
+
+ switch (msg)
+ {
+ case WM_DRAWITEM:
+ case WM_MEASUREITEM:
+ if(wp) break; // not menu related
+ case WM_INITMENUPOPUP:
+ g_pIContext2or3->HandleMenuMsg(msg, wp, lp);
+ return (msg==WM_INITMENUPOPUP ? 0 : TRUE); // handled
+
+ /*case WM_MENUSELECT:
+ // if this is a shell item, get its descriptive text
+ uItem = (UINT) LOWORD(wp);
+ if(0 == (MF_POPUP & HIWORD(wp)) && uItem >= 1 && uItem <= 0x7fff)
+ {
+ g_pIContext2or3->GetCommandString(uItem-1, GCS_HELPTEXT,
+ NULL, szBuf, sizeof(szBuf)/sizeof(szBuf[0]) );
+
+ // set the status bar text
+ ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->SetMessageText(szBuf);
+ return 0;
+ }
+ break;*/
+
+ default:
+ break;
+ }
+
+ // for all untreated messages, call the original wndproc
+ return ::CallWindowProc(g_pOldWndProc, hWnd, msg, wp, lp);
+}
+
+BOOL DoExplorerMenu (HWND hwnd, LPITEMIDLIST pidlMain, POINT point)
+{
+ LPMALLOC pMalloc;
+ LPSHELLFOLDER psfFolder, psfNextFolder;
+ LPITEMIDLIST pidlItem, pidlNextItem, *ppidl;
+ LPCONTEXTMENU pContextMenu;
+ CMINVOKECOMMANDINFO ici;
+ UINT nCount, nCmd;
+ BOOL bResult;
+ HMENU hMenu;
+
+ //
+ // Get pointers to the shell's IMalloc interface and the desktop's
+ // IShellFolder interface.
+ //
+ bResult = FALSE;
+
+ if (!SUCCEEDED (SHGetMalloc (&pMalloc)))
+ return bResult;
+
+ if (!SUCCEEDED (SHGetDesktopFolder (&psfFolder))) {
+ pMalloc->Release();
+ return bResult;
+ }
+
+ if (nCount = GetItemCount (pidlMain)) // nCount must be > 0
+ {
+ //
+ // Initialize psfFolder with a pointer to the IShellFolder
+ // interface of the folder that contains the item whose context
+ // menu we're after, and initialize pidlItem with a pointer to
+ // the item's item ID. If nCount > 1, this requires us to walk
+ // the list of item IDs stored in pidlMain and bind to each
+ // subfolder referenced in the list.
+ //
+ pidlItem = pidlMain;
+
+ while (--nCount) {
+ //
+ // Create a 1-item item ID list for the next item in pidlMain.
+ //
+ pidlNextItem = DuplicateItem (pMalloc, pidlItem);
+ if (pidlNextItem == NULL) {
+ psfFolder->Release();
+ pMalloc->Release();
+ return bResult;
+ }
+
+ //
+ // Bind to the folder specified in the new item ID list.
+ //
+ if (!SUCCEEDED (psfFolder->BindToObject(pidlNextItem, NULL, IID_IShellFolder, (void**)&psfNextFolder))) // modified by RG
+ {
+ pMalloc->Free(pidlNextItem);
+ psfFolder->Release();
+ pMalloc->Release();
+ return bResult;
+ }
+
+ //
+ // Release the IShellFolder pointer to the parent folder
+ // and set psfFolder equal to the IShellFolder pointer for
+ // the current folder.
+ //
+ psfFolder->Release();
+ psfFolder = psfNextFolder;
+
+ //
+ // Release the storage for the 1-item item ID list we created
+ // just a moment ago and initialize pidlItem so that it points
+ // to the next item in pidlMain.
+ //
+ pMalloc->Free(pidlNextItem);
+ pidlItem = GetNextItem (pidlItem);
+ }
+
+ //
+ // Get a pointer to the item's IContextMenu interface and call
+ // IContextMenu::QueryContextMenu to initialize a context menu.
+ //
+ ppidl = &pidlItem;
+ if (SUCCEEDED (psfFolder->GetUIObjectOf(hwnd, 1, (LPCITEMIDLIST*)ppidl, IID_IContextMenu, NULL, (void**)&pContextMenu))) // modified by RG
+ {
+ // try to see if we can upgrade to an IContextMenu3
+ // or IContextMenu2 interface pointer:
+ int level = 1;
+ void *pCM = NULL;
+ if (pContextMenu->QueryInterface(IID_IContextMenu3, &pCM) == NOERROR)
+ {
+ pContextMenu->Release();
+ pContextMenu = (LPCONTEXTMENU)pCM;
+ level = 3;
+ }
+ else if (pContextMenu->QueryInterface(IID_IContextMenu2, &pCM) == NOERROR)
+ {
+ pContextMenu->Release();
+ pContextMenu = (LPCONTEXTMENU)pCM;
+ level = 2;
+ }
+
+ hMenu = CreatePopupMenu ();
+ if (SUCCEEDED (pContextMenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_EXPLORE)))
+ {
+ ClientToScreen (hwnd, &point);
+
+ // install the subclassing "hook", for versions 2 or 3
+ if (level >= 2)
+ {
+ g_pOldWndProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (DWORD_PTR)HookWndProc);
+ g_pIContext2or3 = (LPCONTEXTMENU2)pContextMenu; // cast ok for ICMv3
+ }
+ else
+ {
+ g_pOldWndProc = NULL;
+ g_pIContext2or3 = NULL;
+ }
+
+ //
+ // Display the context menu.
+ //
+ nCmd = TrackPopupMenu (hMenu, TPM_LEFTALIGN |
+ TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+ point.x, point.y, 0, hwnd, NULL);
+
+ // restore old wndProc
+ if (g_pOldWndProc)
+ {
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)g_pOldWndProc);
+ }
+
+ //
+ // If a command was selected from the menu, execute it.
+ //
+ if (nCmd >= 1 && nCmd <= 0x7fff)
+ {
+ ZeroMemory(&ici, sizeof(ici));
+ ici.cbSize = sizeof (CMINVOKECOMMANDINFO);
+ //ici.fMask = 0;
+ ici.hwnd = hwnd;
+ ici.lpVerb = MAKEINTRESOURCE (nCmd - 1);
+ //ici.lpParameters = NULL;
+ //ici.lpDirectory = NULL;
+ ici.nShow = SW_SHOWNORMAL;
+ //ici.dwHotKey = 0;
+ //ici.hIcon = NULL;
+
+ if (SUCCEEDED ( pContextMenu->InvokeCommand (&ici)))
+ bResult = TRUE;
+ }
+ /*else if (nCmd)
+ {
+ PostMessage(hwnd, WM_COMMAND, nCmd, NULL); // our command
+ }*/
+ }
+ DestroyMenu (hMenu);
+ pContextMenu->Release();
+ }
+ }
+
+ //
+ // Clean up and return.
+ //
+ psfFolder->Release();
+ pMalloc->Release();
+
+ return bResult;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Note: a special thanks goes out to Jeff Prosise for writing & publishing
+// the following code!
+//
+// FUNCTION: GetItemCount
+//
+// DESCRIPTION: Computes the number of item IDs in an item ID list.
+//
+// INPUT: pidl = Pointer to an item ID list.
+//
+// RETURNS: Number of item IDs in the list.
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+UINT GetItemCount (LPITEMIDLIST pidl)
+{
+ USHORT nLen;
+ UINT nCount;
+
+ nCount = 0;
+ while ((nLen = pidl->mkid.cb) != 0) {
+ pidl = GetNextItem (pidl);
+ nCount++;
+ }
+ return nCount;
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Note: a special thanks goes out to Jeff Prosise for writing & publishing
+// the following code!
+//
+// FUNCTION: GetNextItem
+//
+// DESCRIPTION: Finds the next item in an item ID list.
+//
+// INPUT: pidl = Pointer to an item ID list.
+//
+// RETURNS: Pointer to the next item.
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LPITEMIDLIST GetNextItem (LPITEMIDLIST pidl)
+{
+ USHORT nLen;
+
+ if ((nLen = pidl->mkid.cb) == 0)
+ return NULL;
+
+ return (LPITEMIDLIST) (((LPBYTE) pidl) + nLen);
+}
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Note: a special thanks goes out to Jeff Prosise for writing & publishing
+// the following code!
+//
+// FUNCTION: DuplicateItem
+//
+// DESCRIPTION: Makes a copy of the next item in an item ID list.
+//
+// INPUT: pMalloc = Pointer to an IMalloc interface.
+// pidl = Pointer to an item ID list.
+//
+// RETURNS: Pointer to an ITEMIDLIST containing the copied item ID.
+//
+// NOTES: It is the caller's responsibility to free the memory
+// allocated by this function when the item ID is no longer
+// needed. Example:
+//
+// pidlItem = DuplicateItem (pMalloc, pidl);
+// .
+// .
+// .
+// pMalloc->lpVtbl->Free (pMalloc, pidlItem);
+//
+// Failure to free the ITEMIDLIST will result in memory
+// leaks.
+//
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+LPITEMIDLIST DuplicateItem (LPMALLOC pMalloc, LPITEMIDLIST pidl)
+{
+ USHORT nLen;
+ LPITEMIDLIST pidlNew;
+
+ nLen = pidl->mkid.cb;
+ if (nLen == 0)
+ return NULL;
+
+ pidlNew = (LPITEMIDLIST) pMalloc->Alloc (
+ nLen + sizeof (USHORT));
+ if (pidlNew == NULL)
+ return NULL;
+
+ CopyMemory (pidlNew, pidl, nLen);
+ *((USHORT*) (((LPBYTE) pidlNew) + nLen)) = 0;
+
+ return pidlNew;
+}
+
+//----------------------------------------------------------------------
+// A special thanks goes out to Jeroen-bart Engelen (Yeep) for providing
+// his source code for getting the position & label information for all
+// the icons on the desktop, as found below. See his article at
+// http://www.digiwar.com/scripts/renderpage.php?section=2&subsection=2
+//----------------------------------------------------------------------
+
+void FindDesktopWindows(HWND *desktop_progman, HWND *desktopview_wnd, HWND *listview_wnd)
+{
+ *desktop_progman = NULL;
+ *desktopview_wnd = NULL;
+ *listview_wnd = NULL;
+
+ *desktop_progman = FindWindow(NULL, ("Program Manager"));
+ if(*desktop_progman == NULL)
+ {
+ //MessageBox(NULL, "Unable to get the handle to the Program Manager.", "Fatal error", MB_OK|MB_ICONERROR);
+ return;
+ }
+
+ *desktopview_wnd = FindWindowEx(*desktop_progman, NULL, "SHELLDLL_DefView", NULL);
+ if(*desktopview_wnd == NULL)
+ {
+ //MessageBox(NULL, "Unable to get the handle to the desktopview.", "Fatal error", MB_OK|MB_ICONERROR);
+ return;
+ }
+
+ // Thanks ef_ef_ef@yahoo.com for pointing out this works in NT 4 and not the way I did it originally.
+ *listview_wnd = FindWindowEx(*desktopview_wnd, NULL, "SysListView32", NULL);
+ if(*listview_wnd == NULL)
+ {
+ //MessageBox(NULL, "Unable to get the handle to the folderview.", "Fatal error", MB_OK|MB_ICONERROR);
+ return;
+ }
+}
+
+//----------------------------------------------------------------------
+
+int GetDesktopIconSize()
+{
+ int ret = 32;
+
+ // reads the key: HKEY_CURRENT_USER\Control Panel, Desktop\WindowMetrics\Shell Icon Size
+ unsigned char buf[64];
+ unsigned long len = sizeof(buf);
+ DWORD type;
+ HKEY key;
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop\\WindowMetrics", 0, KEY_READ, &key))
+ {
+ if (ERROR_SUCCESS == RegQueryValueEx(key, "Shell Icon Size", NULL, &type, (unsigned char*)buf, &len) &&
+ type == REG_SZ)
+ {
+ int x = _atoi_l((char*)buf, g_use_C_locale);
+ if (x>0 && x<=128)
+ ret = x;
+ }
+
+ RegCloseKey(key);
+ }
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+
+// handy functions for populating Combo Boxes:
+int SelectItemByValue(HWND ctrl, DWORD value)
+{
+ int count = SendMessage(ctrl, CB_GETCOUNT, 0, 0);
+ for (int i=0; i<count; i++)
+ {
+ DWORD value_i = SendMessage( ctrl, CB_GETITEMDATA, i, 0);
+ if (value_i == value)
+ {
+ SendMessage( ctrl, CB_SETCURSEL, i, 0);
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool ReadCBValue(HWND hwnd, DWORD ctrl_id, int* pRetValue)
+{
+ if (!pRetValue)
+ return false;
+ HWND ctrl = GetDlgItem( hwnd, ctrl_id );
+ int t = SendMessage( ctrl, CB_GETCURSEL, 0, 0);
+ if (t == CB_ERR)
+ return false;
+ *pRetValue = (int)SendMessage( ctrl, CB_GETITEMDATA, t, 0);
+ return true;
+}
+
+D3DXCREATEFONTW pCreateFontW=0;
+D3DXMATRIXMULTIPLY pMatrixMultiply=0;
+D3DXMATRIXTRANSLATION pMatrixTranslation=0;
+D3DXMATRIXSCALING pMatrixScaling=0;
+D3DXMATRIXROTATION pMatrixRotationX=0, pMatrixRotationY=0, pMatrixRotationZ=0;
+D3DXCREATETEXTUREFROMFILEEXW pCreateTextureFromFileExW=0;
+D3DXMATRIXORTHOLH pMatrixOrthoLH = 0;
+D3DXCOMPILESHADER pCompileShader=0;
+D3DXMATRIXLOOKATLH pMatrixLookAtLH=0;
+D3DXCREATETEXTURE pCreateTexture=0;
+//----------------------------------------------------------------------
+HMODULE FindD3DX9(HWND winamp)
+{
+ HMODULE d3dx9 = (HMODULE)SendMessage(winamp,WM_WA_IPC, 0, IPC_GET_D3DX9);
+ if (!d3dx9 || d3dx9 == (HMODULE)1)
+ {
+
+ // TODO: benski> this is a quick-fix, we should call FindFirstFile() on the system directory
+ d3dx9=NULL;
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_36.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_35.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_34.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_33.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_32.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_31.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_30.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_29.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_28.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_27.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_26.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_25.dll");
+ if (!d3dx9) d3dx9 = LoadLibrary("d3dx9_24.dll");
+ }
+
+ if (d3dx9)
+ {
+ pCreateFontW = (D3DXCREATEFONTW) GetProcAddress(d3dx9,"D3DXCreateFontW");
+ pMatrixMultiply = (D3DXMATRIXMULTIPLY) GetProcAddress(d3dx9,"D3DXMatrixMultiply");
+ pMatrixTranslation = (D3DXMATRIXTRANSLATION)GetProcAddress(d3dx9,"D3DXMatrixTranslation");
+ pMatrixScaling = (D3DXMATRIXSCALING)GetProcAddress(d3dx9,"D3DXMatrixScaling");
+ pMatrixRotationX = (D3DXMATRIXROTATION)GetProcAddress(d3dx9,"D3DXMatrixRotationX");
+ pMatrixRotationY = (D3DXMATRIXROTATION)GetProcAddress(d3dx9,"D3DXMatrixRotationY");
+ pMatrixRotationZ = (D3DXMATRIXROTATION)GetProcAddress(d3dx9,"D3DXMatrixRotationZ");
+ pCreateTextureFromFileExW = (D3DXCREATETEXTUREFROMFILEEXW)GetProcAddress(d3dx9,"D3DXCreateTextureFromFileExW");
+ pMatrixOrthoLH = (D3DXMATRIXORTHOLH)GetProcAddress(d3dx9,"D3DXMatrixOrthoLH");
+ pCompileShader = (D3DXCOMPILESHADER)GetProcAddress(d3dx9,"D3DXCompileShader");
+ pMatrixLookAtLH = (D3DXMATRIXLOOKATLH)GetProcAddress(d3dx9,"D3DXMatrixLookAtLH");
+ pCreateTexture = (D3DXCREATETEXTURE)GetProcAddress(d3dx9,"D3DXCreateTexture");
+
+
+
+ }
+
+ return d3dx9;
+}
+
+LRESULT GetWinampVersion(HWND winamp)
+{
+ static LRESULT version=0;
+ if (!version)
+ version=SendMessage(winamp,WM_WA_IPC,0,0);
+ return version;
+}
+
+void* GetTextResource(UINT id, int no_fallback){
+ void* data = 0;
+ HINSTANCE hinst = WASABI_API_LNG_HINST;
+ HRSRC rsrc = FindResource(hinst,MAKEINTRESOURCE(id),"TEXT");
+ if(!rsrc && !no_fallback) rsrc = FindResource((hinst = WASABI_API_ORIG_HINST),MAKEINTRESOURCE(id),"TEXT");
+ if(rsrc){
+ HGLOBAL resourceHandle = LoadResource(hinst,rsrc);
+ data = LockResource(resourceHandle);
+ }
+ return data;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/utility.h b/Src/Plugins/Visualization/vis_milk2/utility.h
new file mode 100644
index 00000000..13d31e4f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/utility.h
@@ -0,0 +1,164 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __NULLSOFT_DX9_PLUGIN_SHELL_UTILITY_H__
+#define __NULLSOFT_DX9_PLUGIN_SHELL_UTILITY_H__ 1
+
+#include <windows.h>
+#include <crtdefs.h>
+#include <d3d9.h>
+#include <d3dx9.h>
+
+#define SafeRelease(x) { if (x) {x->Release(); x=NULL;} }
+#define SafeDelete(x) { if (x) {delete x; x=NULL;} }
+#define IsNullGuid(lpGUID) ( ((int*)lpGUID)[0]==0 && ((int*)lpGUID)[1]==0 && ((int*)lpGUID)[2]==0 && ((int*)lpGUID)[3]==0 )
+#define DlgItemIsChecked(hDlg, nIDDlgItem) ((SendDlgItemMessage(hDlg, nIDDlgItem, BM_GETCHECK, (WPARAM) 0, (LPARAM) 0) == BST_CHECKED) ? true : false)
+#define CosineInterp(x) (0.5f - 0.5f*cosf((x) * 3.1415926535898f))
+#define InvCosineInterp(x) (acosf(1.0f - 2.0f*(x))/3.1415926535898f)
+float PowCosineInterp(float x, float pow);
+float AdjustRateToFPS(float per_frame_decay_rate_at_fps1, float fps1, float actual_fps);
+
+//int GetPrivateProfileInt - part of Win32 API
+#define GetPrivateProfileBoolW(w,x,y,z) ((bool)(GetPrivateProfileIntW(w,x,y,z) != 0))
+#define GetPrivateProfileBOOLW(w,x,y,z) ((BOOL)(GetPrivateProfileIntW(w,x,y,z) != 0))
+float GetPrivateProfileFloatW(wchar_t *szSectionName, wchar_t *szKeyName, float fDefault, wchar_t *szIniFile);
+bool WritePrivateProfileIntW(int d, wchar_t *szKeyName, wchar_t *szIniFile, wchar_t *szSectionName);
+bool WritePrivateProfileFloatW(float f, wchar_t *szKeyName, wchar_t *szIniFile, wchar_t *szSectionName);
+
+extern _locale_t g_use_C_locale;
+extern char keyMappings[8];
+
+void SetScrollLock(int bNewState, bool bPreventHandling);
+void RemoveExtension(wchar_t *str);
+void RemoveSingleAmpersands(wchar_t *str);
+void TextToGuid(char *str, GUID *pGUID);
+void GuidToText(GUID *pGUID, char *str, int nStrLen);
+//int GetPentiumTimeRaw(unsigned __int64 *cpu_timestamp);
+//double GetPentiumTimeAsDouble(unsigned __int64 frequency);
+#ifdef _DEBUG
+ void OutputDebugMessage(char *szStartText, HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); // only available in RELEASE builds!
+#endif
+void MissingDirectX(HWND hwnd);
+bool CheckForMMX();
+bool CheckForSSE();
+void GetDesktopFolder(char *szDesktopFolder); // should be MAX_PATH len.
+
+#include "icon_t.h"
+#include <shlobj.h>
+#include <list>
+
+BOOL DoExplorerMenu (HWND hwnd, LPCTSTR pszPath, POINT point);
+BOOL DoExplorerMenu (HWND hwnd, LPITEMIDLIST pidl, POINT point);
+UINT GetItemCount (LPITEMIDLIST pidl);
+LPITEMIDLIST GetNextItem (LPITEMIDLIST pidl);
+LPITEMIDLIST DuplicateItem (LPMALLOC pMalloc, LPITEMIDLIST pidl);
+void FindDesktopWindows(HWND *desktop_progman, HWND *desktopview_wnd, HWND *listview_wnd);
+void ExecutePidl(LPITEMIDLIST pidl, char *szPathAndFile, char *szWorkingDirectory, HWND hWnd);
+int GetDesktopIconSize();
+
+// handy functions for populating Combo Boxes:
+inline void AddItem(HWND ctrl, const wchar_t* text, DWORD itemdata) {
+ LRESULT nPos = SendMessageW( ctrl, CB_ADDSTRING, 0, (LPARAM)text);
+ SendMessage( ctrl, CB_SETITEMDATA, nPos, itemdata);
+}
+inline void SelectItemByPos(HWND ctrl, int pos) {
+ SendMessage(ctrl, CB_SETCURSEL, pos, 0);
+}
+int SelectItemByValue(HWND ctrl, DWORD value);
+bool ReadCBValue(HWND hwnd, DWORD ctrl_id, int* pRetValue);
+
+LRESULT GetWinampVersion(HWND winamp);
+void* GetTextResource(UINT id, int no_fallback);
+
+HMODULE FindD3DX9(HWND winamp);
+
+intptr_t myOpenURL(HWND hwnd, wchar_t *loc);
+
+typedef HRESULT (WINAPI *D3DXCREATEFONTW)(LPDIRECT3DDEVICE9, INT, UINT, UINT, UINT, BOOL, DWORD, DWORD, DWORD, DWORD, LPCWSTR, LPD3DXFONT *);
+extern D3DXCREATEFONTW pCreateFontW;
+
+typedef D3DXMATRIX *(WINAPI *D3DXMATRIXMULTIPLY)(D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2);
+extern D3DXMATRIXMULTIPLY pMatrixMultiply;
+
+typedef D3DXMATRIX* (WINAPI *D3DXMATRIXTRANSLATION)( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z );
+extern D3DXMATRIXTRANSLATION pMatrixTranslation;
+
+typedef D3DXMATRIX* (WINAPI *D3DXMATRIXSCALING)( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz );
+extern D3DXMATRIXSCALING pMatrixScaling;
+
+typedef D3DXMATRIX* (WINAPI *D3DXMATRIXROTATION)( D3DXMATRIX *pOut, FLOAT Angle );
+extern D3DXMATRIXROTATION pMatrixRotationX, pMatrixRotationY, pMatrixRotationZ;
+
+typedef HRESULT (WINAPI *D3DXCREATETEXTUREFROMFILEEXW)(
+ LPDIRECT3DDEVICE9 pDevice,
+ LPCWSTR pSrcFile,
+ UINT Width,
+ UINT Height,
+ UINT MipLevels,
+ DWORD Usage,
+ D3DFORMAT Format,
+ D3DPOOL Pool,
+ DWORD Filter,
+ DWORD MipFilter,
+ D3DCOLOR ColorKey,
+ D3DXIMAGE_INFO* pSrcInfo,
+ PALETTEENTRY* pPalette,
+ LPDIRECT3DTEXTURE9* ppTexture);
+extern D3DXCREATETEXTUREFROMFILEEXW pCreateTextureFromFileExW;
+
+typedef D3DXMATRIX* (WINAPI *D3DXMATRIXORTHOLH)(D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf);
+extern D3DXMATRIXORTHOLH pMatrixOrthoLH;
+
+typedef HRESULT (WINAPI *D3DXCOMPILESHADER)(
+ LPCSTR pSrcData,
+ UINT SrcDataLen,
+ CONST D3DXMACRO* pDefines,
+ LPD3DXINCLUDE pInclude,
+ LPCSTR pFunctionName,
+ LPCSTR pProfile,
+ DWORD Flags,
+ LPD3DXBUFFER* ppShader,
+ LPD3DXBUFFER* ppErrorMsgs,
+ LPD3DXCONSTANTTABLE* ppConstantTable);
+extern D3DXCOMPILESHADER pCompileShader;
+
+typedef D3DXMATRIX* (WINAPI *D3DXMATRIXLOOKATLH)( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp );
+extern D3DXMATRIXLOOKATLH pMatrixLookAtLH;
+
+typedef HRESULT (WINAPI *D3DXCREATETEXTURE)(
+ LPDIRECT3DDEVICE9 pDevice,
+ UINT Width,
+ UINT Height,
+ UINT MipLevels,
+ DWORD Usage,
+ D3DFORMAT Format,
+ D3DPOOL Pool,
+ LPDIRECT3DTEXTURE9* ppTexture);
+extern D3DXCREATETEXTURE pCreateTexture;
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/version.rc2 b/Src/Plugins/Visualization/vis_milk2/version.rc2
new file mode 100644
index 00000000..34b06514
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,25,4,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Visualization Plug-in"
+ VALUE "FileVersion", "2,25,4,0"
+ VALUE "InternalName", "Nullsoft Milkdrop v2"
+ VALUE "LegalCopyright", "Copyright © 2001-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "vis_milk2.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/Visualization/vis_milk2/vis.cpp b/Src/Plugins/Visualization/vis_milk2/vis.cpp
new file mode 100644
index 00000000..afc80edd
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/vis.cpp
@@ -0,0 +1,275 @@
+/*
+ LICENSE
+ -------
+Copyright 2005-2013 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "api__vis_milk2.h"
+#include <windows.h>
+#include "vis.h"
+#include "plugin.h"
+#include "defines.h"
+#include "resource.h"
+#include "utility.h"
+
+CPlugin g_plugin;
+_locale_t g_use_C_locale = 0;
+char keyMappings[8];
+bool g_bFullyExited = true;
+
+// wasabi based services for localisation support
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+api_application *WASABI_API_APP = 0;
+api_syscb *WASABI_API_SYSCB = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+void config(struct winampVisModule *this_mod); // configuration dialog
+int init(struct winampVisModule *this_mod); // initialization for module
+int render1(struct winampVisModule *this_mod); // rendering for module 1
+void quit(struct winampVisModule *this_mod); // deinitialization for module
+
+// our only plugin module in this plugin:
+winampVisModule mod1 =
+{
+ MODULEDESC,
+ NULL, // hwndParent
+ NULL, // hDllInstance
+ 0, // sRate
+ 0, // nCh
+ 0, // latencyMS - tells winamp how much in advance you want the audio data,
+ // in ms.
+ 10, // delayMS - if winamp tells the plugin to render a frame and it takes
+ // less than this # of milliseconds, winamp will sleep (go idle)
+ // for the remainder. In effect, this limits the framerate of
+ // the plugin. A value of 10 would cause a fps limit of ~100.
+ // Derivation: (1000 ms/sec) / (10 ms/frame) = 100 fps.
+ 0, // spectrumNch
+ 2, // waveformNch
+ { 0, }, // spectrumData
+ { 0, }, // waveformData
+ config,
+ init,
+ render1,
+ quit
+};
+
+// getmodule routine from the main header. Returns NULL if an invalid module was requested,
+// otherwise returns either mod1, mod2 or mod3 depending on 'which'.
+winampVisModule *getModule(int which)
+{
+ switch (which)
+ {
+ case 0: return &mod1;
+ //case 1: return &mod2;
+ //case 2: return &mod3;
+ default: return NULL;
+ }
+}
+
+// Module header, includes version, description, and address of the module retriever function
+winampVisHeader hdr = { VIS_HDRVER, DLLDESC, getModule };
+
+// use this to get our own HINSTANCE since overriding DllMain(..) causes instant crashes (should see why)
+static HINSTANCE GetMyInstance()
+{
+ MEMORY_BASIC_INFORMATION mbi = {0};
+ if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
+ return (HINSTANCE)mbi.AllocationBase;
+ return NULL;
+}
+
+// this is the only exported symbol. returns our main header.
+// if you are compiling C++, the extern "C" { is necessary, so we just #ifdef it
+#ifdef __cplusplus
+extern "C" {
+#endif
+ __declspec( dllexport ) winampVisHeader *winampVisGetHeader(HWND hwndParent)
+ {
+ if(!WASABI_API_LNG_HINST)
+ {
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessage(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ sf = WASABI_API_SVC->service_getServiceByGuid(applicationApiServiceGuid);
+ if (sf) WASABI_API_APP = reinterpret_cast<api_application*>(sf->getInterface());
+
+ sf = WASABI_API_SVC->service_getServiceByGuid(syscbApiServiceGuid);
+ if (sf) WASABI_API_SYSCB = reinterpret_cast<api_syscb*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(GetMyInstance(),VisMilkdropLangGUID);
+
+ /* added for v2.25 as a quick work around to allow partial
+ /* keyboard mappings (mainly coming from de-de requirements)
+ ** [yY][Y][yY][zZ]
+ ** 1 2 3 4
+ **
+ ** 1 - does yes for the 3 different prompt types
+ ** 2 - does Ctrl+Y for stopping display of custom message of song title
+ ** 3 - something for preset editing (not 100% sure what)
+ ** 4 - used for the previous track sent to Winamp
+ */
+ WASABI_API_LNGSTRING_BUF(IDS_KEY_MAPPINGS, keyMappings, 8);
+
+ // as we're under a different thread we need to set the locale
+ //WASABI_API_LNG->UseUserNumericLocale();
+ g_use_C_locale = WASABI_API_LNG->Get_C_NumericLocale();
+ }
+
+ return &hdr;
+ }
+#ifdef __cplusplus
+}
+#endif
+
+bool WaitUntilPluginFinished(HWND hWndWinamp)
+{
+ int slept = 0;
+ while (!g_bFullyExited && slept < 1000)
+ {
+ Sleep(50);
+ slept += 50;
+ }
+
+ if (!g_bFullyExited)
+ {
+ wchar_t title[64];
+ MessageBoxW(hWndWinamp, WASABI_API_LNGSTRINGW(IDS_ERROR_THE_PLUGIN_IS_ALREADY_RUNNING),
+ WASABI_API_LNGSTRINGW_BUF(IDS_MILKDROP_ERROR, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
+ return false;
+ }
+
+ return true;
+}
+
+HWND GetDialogBoxParent(HWND winamp)
+{
+ HWND parent = (HWND)SendMessage(winamp, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
+ if (!parent || parent == (HWND)1)
+ return winamp;
+ return parent;
+}
+
+// configuration. Passed this_mod, as a "this" parameter. Allows you to make one configuration
+// function that shares code for all your modules (you don't HAVE to use it though, you can make
+// config1(), config2(), etc...)
+void config(struct winampVisModule *this_mod)
+{
+ if (!g_bFullyExited)
+ {
+ g_plugin.OnAltK();
+ return;
+ }
+
+ g_bFullyExited = false;
+ g_plugin.PluginPreInitialize(this_mod->hwndParent, this_mod->hDllInstance);
+ WASABI_API_DIALOGBOXPARAMW(IDD_CONFIG, GetDialogBoxParent(this_mod->hwndParent), g_plugin.ConfigDialogProc, (LPARAM)&g_plugin);
+ g_bFullyExited = true;
+}
+
+int (*warand)(void) = 0;
+
+int fallback_rand_fn(void) {
+ return rand();
+}
+
+// initialization. Registers our window class, creates our window, etc. Again, this one works for
+// both modules, but you could make init1() and init2()...
+// returns 0 on success, 1 on failure.
+int init(struct winampVisModule *this_mod)
+{
+ DWORD version = GetWinampVersion(mod1.hwndParent);
+
+ if (!warand)
+ {
+ warand = (int (*)(void))SendMessage(this_mod->hwndParent, WM_WA_IPC, 0, IPC_GET_RANDFUNC);
+ if ((size_t)warand <= 1)
+ {
+ warand = fallback_rand_fn;
+ }
+ }
+
+ if (!WaitUntilPluginFinished(this_mod->hwndParent))
+ {
+ return 1;
+ }
+
+ if (GetWinampVersion(mod1.hwndParent) < 0x4000)
+ {
+ // query winamp for its playback state
+ LRESULT ret = SendMessage(this_mod->hwndParent, WM_USER, 0, 104);
+ // ret=1: playing, ret=3: paused, other: stopped
+
+ if (ret != 1)
+ {
+ wchar_t title[64];
+ MessageBoxW(this_mod->hwndParent, WASABI_API_LNGSTRINGW(IDS_THIS_PLUGIN_NEEDS_MUSIC_TO_RUN),
+ WASABI_API_LNGSTRINGW_BUF(IDS_NO_MUSIC_PLAYING, title, 64),
+ MB_OK|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL );
+ return 1; // failure
+ }
+ }
+
+ g_bFullyExited = false;
+
+ if (!g_plugin.PluginPreInitialize(this_mod->hwndParent, this_mod->hDllInstance))
+ {
+ g_plugin.PluginQuit();
+ g_bFullyExited = true;
+ return 1;
+ }
+
+ if (!g_plugin.PluginInitialize())
+ {
+ g_plugin.PluginQuit();
+ g_bFullyExited = true;
+ return 1;
+ }
+
+ return 0; // success
+}
+
+// render function for oscilliscope. Returns 0 if successful, 1 if visualization should end.
+int render1(struct winampVisModule *this_mod)
+{
+ if (g_plugin.PluginRender(this_mod->waveformData[0], this_mod->waveformData[1]))
+ return 0; // ok
+ else
+ return 1; // failed
+}
+
+// cleanup (opposite of init()). Should destroy the window, unregister the window class, etc.
+void quit(struct winampVisModule *this_mod)
+{
+ g_plugin.PluginQuit();
+ g_bFullyExited = true;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/vis.h b/Src/Plugins/Visualization/vis_milk2/vis.h
new file mode 100644
index 00000000..cee91b3c
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/vis.h
@@ -0,0 +1 @@
+#include "../Winamp/vis.h" \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_milk2/vms_desktop.lib b/Src/Plugins/Visualization/vis_milk2/vms_desktop.lib
new file mode 100644
index 00000000..40091729
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_milk2/vms_desktop.lib
Binary files differ
diff --git a/Src/Plugins/Visualization/vis_nsfs/Svis.cpp b/Src/Plugins/Visualization/vis_nsfs/Svis.cpp
new file mode 100644
index 00000000..1d81d1aa
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/Svis.cpp
@@ -0,0 +1,892 @@
+//#define PLUGIN_NAME "Nullsoft Tiny Fullscreen"
+#define PLUGIN_VERSION "v2.16"
+
+#include <windows.h>
+#include <commctrl.h>
+#include <ddraw.h>
+#include "resource.h"
+#include "../winamp/vis.h"
+#include "../winamp/wa_ipc.h"
+#include "../Agave/Language/api_language.h"
+#include <api/service/waServiceFactory.h>
+
+/* global variables */
+wchar_t g_title[1024]={0};
+wchar_t *ini_file = 0;
+HWND hwndParent = 0;
+HFONT hFont = 0;
+unsigned char *g_scrollbuf;
+
+extern void do_min(HWND hwnd);
+extern void do_unmin(HWND hwnd);
+extern BOOL DirectMouseWheel_ProcessDialogMessage(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam);
+
+/* wasabi based services for localisation support */
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+/* window procedures */
+static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK dlgProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
+
+/* winamp vis module functions */
+static winampVisModule *getModule(int which);
+static void config_write(struct winampVisModule *this_mod);
+static void config_read(struct winampVisModule *this_mod);
+static void config(struct winampVisModule *this_mod);
+static int init(struct winampVisModule *this_mod);
+static int render_sa_vp_mono(struct winampVisModule *this_mod);
+static int render_sa(struct winampVisModule *this_mod);
+static int render_osc(struct winampVisModule *this_mod);
+static int render_osc_sa_mono(struct winampVisModule *this_mod);
+static int render_super_vp(struct winampVisModule *this_mod);
+static void quit(struct winampVisModule *this_mod);
+
+/* uninitialized data (zeroed) */
+DDBLTFX ddbfx;
+HWND g_hwnd;
+LPDIRECTDRAW lpDD;
+LPDIRECTDRAWPALETTE ddp;
+LPDIRECTDRAWSURFACE lpDDSPrim;
+LPDIRECTDRAWSURFACE lpDDSBack;
+unsigned char *fb_locked;
+int scrpitch;
+unsigned char last[4][4096];
+int lpos;
+int rpos;
+unsigned char colpoints[2][6][3];
+winampVisModule mod[4];
+int hadjusted;
+COLORREF custcolors[16];
+
+/* initialized data */
+wchar_t szAppName[] = L"NSFSVis";
+winampVisHeader hdr = { VIS_HDRVER, 0, getModule };
+unsigned char orig_colpoints[2][6][3] =
+{
+ {
+ { 200, 0, 0 },
+ { 250, 0, 25 },
+ { 243, 65, 5 },
+ { 237, 163, 7 },
+ { 250, 250, 0 },
+ { 255, 255, 255 }
+ },{
+ { 34, 29, 54 },
+ { 251, 125, 0 },
+ { 255, 160, 66 },
+ { 242, 237, 21 },
+ { 255, 255, 0 },
+ { 255, 255, 255 },
+ }
+};
+
+struct
+{
+ int w,h,nbands, hpercent,scope,scopesc;
+ int falloff;
+ int peak_falloff, peak_hold;
+} configst={640,480,188,80,1,33,8,8,1};
+
+
+/* function implimentations */
+void sd_config(struct winampVisModule *this_mod);
+int sd_init(struct winampVisModule *this_mod);
+int sd_render(struct winampVisModule *this_mod);
+void sd_quit(struct winampVisModule *this_mod);
+
+extern "C" {
+
+// do this so we can have the original hinstance of our vis for localisation
+/*BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ if(fdwReason == DLL_PROCESS_ATTACH)
+ {
+ visDll = hinstDLL;
+ DisableThreadLibraryCalls(hinstDLL);
+ }
+ return TRUE;
+}*/
+ static HINSTANCE GetMyInstance()
+ {
+ MEMORY_BASIC_INFORMATION mbi = {0};
+ if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
+ return (HINSTANCE)mbi.AllocationBase;
+ return NULL;
+ }
+
+ /* this is the only exported symbol. returns our main header. */
+ __declspec( dllexport ) winampVisHeader* winampVisGetHeader(HWND hwndParent)
+ {
+ static char module1[96], module2[96], module3[96], module4[96];
+
+ OSVERSIONINFO version = {0};
+ version.dwOSVersionInfoSize = sizeof(version);
+ if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO));
+ if (version.dwMajorVersion < 6 ||
+ (version.dwMajorVersion <= 6 && version.dwMinorVersion < 2)) // Windows 8.x+
+ {
+ if(!WASABI_API_LNG_HINST)
+ {
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessage(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(GetMyInstance(),VisNFSFLangGUID);
+ }
+
+ static char szDescription[256];
+ char temp[256];
+ wsprintfA(szDescription,"%s %s",WASABI_API_LNGSTRING_BUF(IDS_NULLSOFT_TINY_FULLSCREEN, temp, 256), PLUGIN_VERSION);
+ hdr.description = szDescription;
+
+ mod[1].latencyMs=1000/60;
+ mod[1].delayMs=5;
+ mod[1].spectrumNch=
+ mod[1].waveformNch=1;
+ mod[1].Init=init;
+ mod[1].Config=config;
+ mod[1].Quit=quit;
+ mod[1].description=WASABI_API_LNGSTRING_BUF(IDS_SEXY_SCROLLING_VOICEPRINT,module1,96);
+ mod[1].Render=render_super_vp;
+
+ mod[2]=mod[1];
+ mod[2].description=WASABI_API_LNGSTRING_BUF(IDS_SPECTRUM_ANALYZER_VOICEPRINT,module2,96);
+ mod[2].waveformNch--;
+ mod[2].Render=render_sa_vp_mono;
+
+ mod[3]=mod[1];
+ mod[3].description=WASABI_API_LNGSTRING_BUF(IDS_SPECTRUM_ANALYZER_OSCILLOSCOPE,module3,96);
+ mod[3].Render=render_osc_sa_mono;
+
+ mod[0]=mod[1];
+ mod[0].description=WASABI_API_LNGSTRING_BUF(IDS_RANDOM_INTELLIGENT_VISUALIZATION,module4,96);
+ mod[0].spectrumNch--;
+ mod[0].delayMs=1;
+ mod[0].Init=sd_init;
+ mod[0].Config=sd_config;
+ mod[0].Render=sd_render;
+ mod[0].Quit=sd_quit;
+
+ return &hdr;
+ }
+ return NULL;
+ }
+};
+
+winampVisModule *getModule(int which)
+{
+ OSVERSIONINFO version = {0};
+ version.dwOSVersionInfoSize = sizeof(version);
+ if (!GetVersionEx(&version)) ZeroMemory(&version, sizeof(OSVERSIONINFO));
+ if (version.dwMajorVersion < 6 ||
+ (version.dwMajorVersion <= 6 && version.dwMinorVersion < 2)) // Windows 8.x+
+ {
+ if (which < 4 && which >= 0) return mod+which;
+ }
+ return 0;
+}
+
+/* configuration. Passed this_mod, as a "this" parameter. Allows you to make one configuration
+function that shares code for all your modules (you don't HAVE to use it though, you can make
+config1(), config2(), etc...)
+*/
+void config(struct winampVisModule *this_mod)
+{
+ config_read(this_mod);
+ if (WASABI_API_DIALOGBOXW(IDD_DIALOG1,this_mod->hwndParent,dlgProc1) == IDOK)
+ config_write(this_mod);
+}
+
+int DD_Init(int this_w, int this_h, PALETTEENTRY *palette)
+{
+ DDSURFACEDESC DDsd;
+ DDSCAPS ddscaps;
+ DDsd.dwSize = sizeof(DDsd);
+ DDsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
+ DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
+ DDsd.dwBackBufferCount = 1;
+ ddbfx.dwSize=sizeof(ddbfx);
+
+ if (DirectDrawCreate(NULL,&lpDD,NULL) != DD_OK)
+ {
+ lpDD=0;
+ return 1;
+ }
+ if (IDirectDraw_SetCooperativeLevel(lpDD,g_hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK ||
+ IDirectDraw_SetDisplayMode(lpDD,this_w,this_h,8) != DD_OK ||
+ IDirectDraw_CreateSurface(lpDD,&DDsd, &lpDDSPrim, NULL) != DD_OK)
+ {
+ IDirectDraw_Release(lpDD);
+ lpDD=0;
+ return 1;
+ }
+ IDirectDrawSurface_GetSurfaceDesc(lpDDSPrim,&DDsd);
+ scrpitch = DDsd.lPitch;
+ ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
+ if (IDirectDrawSurface_GetAttachedSurface(lpDDSPrim,&ddscaps, &lpDDSBack) != DD_OK)
+ {
+ IDirectDraw_Release(lpDD);
+ lpDD=0;
+ return 1;
+ }
+
+ if (IDirectDraw_CreatePalette(lpDD,DDPCAPS_8BIT|DDPCAPS_ALLOW256,palette,&ddp,NULL) == DD_OK)
+ IDirectDrawSurface_SetPalette(lpDDSPrim,ddp);
+
+ {
+ RECT r1={0,0,this_w,this_h};
+ RECT r2=r1;
+ IDirectDrawSurface_Blt(lpDDSBack,&r1,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ IDirectDrawSurface_Blt(lpDDSPrim,&r2,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ }
+ fb_locked=0;
+ return 0;
+}
+
+void initwindow(struct winampVisModule *this_mod, int w, int h)
+{
+ if (SendMessage(this_mod->hwndParent,WM_WA_IPC,0,IPC_IS_PLAYING_VIDEO)>1)
+ {
+ g_hwnd=0;
+ MessageBox(this_mod->hwndParent,
+ WASABI_API_LNGSTRING(IDS_CANNOT_GO_FULLSCREEN_WHEN_VIDEO_PLAYING),
+ hdr.description,MB_OK|MB_ICONINFORMATION);
+ return;
+ }
+
+ WNDCLASSW wc={0,WndProc,0,0,this_mod->hDllInstance,0,0,(HBRUSH)GetStockObject(BLACK_BRUSH),0,szAppName};
+ UnregisterClassW(szAppName,this_mod->hDllInstance);
+ RegisterClassW(&wc);
+ hwndParent=this_mod->hwndParent;
+ g_hwnd = CreateWindowEx(WS_EX_APPWINDOW|WS_EX_TOPMOST,"NSFSVis",this_mod->description,
+ WS_VISIBLE|WS_POPUP|WS_SYSMENU,0,0,w,h,hwndParent,NULL,
+ this_mod->hDllInstance,0);
+ SendMessage(this_mod->hwndParent, WM_WA_IPC, (WPARAM)g_hwnd, IPC_SETVISWND);
+}
+
+int init(struct winampVisModule *this_mod)
+{
+ PALETTEENTRY palette[256];
+ int x,e,a;
+
+ config_read(this_mod);
+
+ initwindow(this_mod,configst.w,configst.h);
+ if (!g_hwnd)
+ {
+ return 1;
+ }
+
+ SetTimer(g_hwnd,0,1000,NULL);
+
+ {
+ char *t=(char*)palette;
+ int x=sizeof(palette);
+ while (x--) *t++=0;
+ }
+
+ palette[255].peRed=palette[255].peGreen=palette[255].peBlue=255;
+ palette[254].peRed=colpoints[0][5][0];
+ palette[254].peGreen=colpoints[0][5][1];
+ palette[254].peBlue=colpoints[0][5][2];
+ palette[253].peRed=colpoints[1][5][0];
+ palette[253].peGreen=colpoints[1][5][1];
+ palette[253].peBlue=colpoints[1][5][2];
+
+ if (this_mod == mod+1)
+ {
+ PALETTEENTRY *p=palette+1;
+ unsigned char *t=colpoints[1][0];
+ for (a = 0; a < 4; a ++)
+ {
+ int dr, dg, db;
+ int r=*t++;
+ int g=*t++;
+ int b=*t++;
+ dr=((t[0]-r)<<16)/60;
+ dg=((t[1]-g)<<16)/60;
+ db=((t[2]-b)<<16)/60;
+ r<<=16;
+ g<<=16;
+ b<<=16;
+ for (x = 0; x < 60; x ++)
+ {
+ p->peRed = r>>16;
+ p->peGreen = g>>16;
+ p->peBlue = b>>16;
+ r+=dr;g+=dg;b+=db;
+ p++;
+ }
+ }
+ }
+ else
+ {
+ PALETTEENTRY *p=palette+1;
+ unsigned char *t=colpoints[0][0];
+ for (e = 0; e < 3; e ++)
+ {
+ for (a = 0; a < 4; a ++)
+ {
+ int dr, dg, db;
+ int r=*t++;
+ int g=*t++;
+ int b=*t++;
+ dr=(t[0]-r);
+ dg=(t[1]-g);
+ db=(t[2]-b);
+ r<<=4;
+ g<<=4;
+ b<<=4;
+ for (x = 0; x < 16; x ++)
+ {
+ p->peRed = r>>4;
+ p->peGreen = g>>4;
+ p->peBlue = b>>4;
+ r+=dr;g+=dg;b+=db;
+ p++;
+ }
+ }
+ t+=3*2;
+ }
+ }
+
+ do_min(this_mod->hwndParent);
+
+ if (DD_Init(configst.w,configst.h,palette))
+ {
+ DestroyWindow(g_hwnd);
+ do_unmin(this_mod->hwndParent);
+ return 1;
+ }
+
+ char *t=(char*)last;
+ int y=sizeof(last);
+ while (y--) *t++=0;
+
+ hadjusted=((configst.h)*configst.hpercent)/100;
+ if (hadjusted>configst.h) hadjusted=configst.h;
+ if (hadjusted < 1) hadjusted=1;
+ if (this_mod == mod+1) g_scrollbuf = (unsigned char *)GlobalAlloc(GPTR,configst.w*hadjusted);
+ else g_scrollbuf = (unsigned char *)GlobalAlloc(GPTR,hadjusted);
+
+ if (!g_scrollbuf)
+ {
+ IDirectDraw_Release(lpDD);
+ lpDD=0;
+ DestroyWindow(g_hwnd);
+ do_unmin(this_mod->hwndParent);
+ return 1;
+ }
+
+ return 0;
+}
+
+unsigned char *DD_Enter(int l, int t, int r, int b)
+{
+ int h;
+ DDSURFACEDESC d={sizeof(d),};
+ RECT r2={l,t,r,b};
+
+ if (fb_locked) return fb_locked;
+
+ if (l<r && t<b) IDirectDrawSurface_Blt(lpDDSBack,&r2,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+
+ if ((h = IDirectDrawSurface_Lock(lpDDSBack,NULL,&d,DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WRITEONLY,NULL)) != DD_OK)
+ {
+ if (h == DDERR_SURFACELOST)
+ {
+ IDirectDrawSurface_Restore(lpDDSPrim);
+ }
+ return 0;
+ }
+
+ return (fb_locked = (unsigned char *) d.lpSurface);
+}
+
+void DD_Unlock(int w, int transparent)
+{
+ if (fb_locked)
+ {
+ HDC hdc;
+ RECT r1={0,0,w,32};
+ RECT r3=r1;
+ IDirectDrawSurface_Unlock(lpDDSBack,fb_locked);
+ fb_locked=0;
+ if (!transparent) IDirectDrawSurface_Blt(lpDDSBack,&r1,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddbfx);
+ if (IDirectDrawSurface_GetDC(lpDDSBack,&hdc) == DD_OK)
+ {
+ if (!transparent) SetBkColor(hdc,0);
+ else SetBkMode(hdc,TRANSPARENT);
+ SetTextColor(hdc,RGB(255,255,255));
+ HFONT oldfont = (HFONT)SelectObject(hdc,hFont);
+ DrawTextW(hdc,g_title,-1,&r3,DT_CENTER|DT_TOP|DT_SINGLELINE);
+ SelectObject(hdc,oldfont);
+ IDirectDrawSurface_ReleaseDC(lpDDSBack,hdc);
+ }
+ IDirectDrawSurface_Flip(lpDDSPrim,NULL, DDFLIP_WAIT);
+ }
+}
+
+void _render_analyzer(struct winampVisModule *this_mod, int hdiv)
+{
+ int x;
+ int pos;
+ int dpos;
+ unsigned char *sd=this_mod->spectrumData[0];
+ unsigned char *sb;
+ int len=min(configst.w,4096);
+
+ sb=fb_locked+scrpitch*(configst.h-1);
+
+ pos=0;
+ dpos=(400<<16)/configst.w;
+ for (x = 0; x < len; x ++)
+ {
+ unsigned char *f = sb++;
+ int c = 2;
+ int lo=0;
+ int lv=last[0][x]-configst.falloff*2;
+
+ int ipos=(pos>>16);
+ int l = (((int)sd[ipos+1])*((pos&0xffff)) + ((int)sd[ipos ])*(0x10000-(pos&0xffff)))>>16;
+
+ l = l*(ipos+40)/80;
+ l>>=hdiv;
+ if (l > (128>>hdiv)-1) l = (128>>hdiv)-1;
+ pos+=dpos;
+ if (configst.peak_hold)
+ {
+ if ((int)last[2][x]+configst.peak_falloff < 255) last[2][x]+=configst.peak_falloff;
+ else last[2][x]=255;
+ if (last[3][x] < last[2][x]/32) last[3][x]=0;
+ else last[3][x]-=last[2][x]/32;
+ if (l*2 > last[3][x])
+ {
+ last[2][x]=0;
+ last[3][x]=l*2;
+ }
+ if (last[3][x]/2 >= l) lo=(-(int)last[3][x]/2)*scrpitch;
+ }
+
+ if (l < lv) l = lv;
+ last[0][x]= l;
+
+ while (l--)
+ {
+ f[0] = c/2;
+ c+=1+hdiv;
+ f -= scrpitch;
+ }
+ if (lo) sb[lo-1]=254;
+ }
+}
+
+void _render_scope(struct winampVisModule *this_mod, int hr)
+{
+ int x;
+ unsigned char *wd=this_mod->waveformData[0];
+ int scsc;
+ int pos,dpos,lastv;
+ unsigned char *sb;
+ scsc=(configst.scopesc*hr)/100;
+ if (scsc < 1) scsc=1;
+ if (scsc > hr) scsc=hr;
+ sb=fb_locked+scrpitch*(configst.h/2-scsc/2);
+ lastv=-1;
+ pos=0;
+ dpos=(575<<16)/configst.w;
+ for (x = 0; x < configst.w; x ++)
+ {
+ int tv = (((int)wd[(pos>>16)+1]^128)*((pos&0xffff)) + ((int)wd[(pos>>16)] ^128)*(0x10000-(pos&0xffff)))>>16;
+ tv=(tv*scsc)>>8;
+ pos+=dpos;
+ if (lastv<0) lastv=tv;
+ if (tv==lastv) sb[scrpitch*lastv]=253;
+ else
+ {
+ while (tv < lastv) sb[scrpitch*lastv--]=253;
+ while (tv > lastv) sb[scrpitch*lastv++]=253;
+ }
+ sb++;
+ }
+}
+
+int render_super_vp(struct winampVisModule *this_mod)
+{
+ int tb=min(configst.nbands,511);
+ int sy=((configst.h-hadjusted)/2);
+ unsigned char *src=&this_mod->spectrumData[0][tb];
+ unsigned char *op;
+ unsigned char *p1=g_scrollbuf;
+ unsigned char *p2=g_scrollbuf+configst.w;
+ unsigned int pos=0;
+ unsigned int dpos=(tb<<16)/hadjusted;
+
+ if (!g_scrollbuf || !DD_Enter(0,0,configst.w,min(sy,32))) return 0;
+
+ op=fb_locked+sy*scrpitch;
+
+ int y=hadjusted/2;
+ while (y--)
+ {
+ int x=configst.w-1;
+ while (x--)
+ {
+ *p1++=p1[1];
+ *p2++=p2[1];
+ }
+ x = (((int)src[0 - (pos>>16)])*((pos&0xffff)) + ((int)src[1 - (pos>>16)])*(0x10000-(pos&0xffff)))>>16;
+ pos+=dpos;
+ if (++x > 240) x = 240;
+ *p1++ = x;
+ x = (((int)src[0 - (pos>>16)])*((pos&0xffff)) + ((int)src[1 - (pos>>16)])*(0x10000-(pos&0xffff)))>>16;
+ pos+=dpos;
+ if (++x > 240) x = 240;
+ *p2++ = x;
+
+ memcpy(op,p1-configst.w,configst.w);
+ op+=scrpitch;
+ memcpy(op,p2-configst.w,configst.w);
+ op+=scrpitch;
+ p1+=configst.w;
+ p2+=configst.w;
+ }
+ if (configst.scope) _render_scope(this_mod,hadjusted);
+
+ DD_Unlock(configst.w,1);
+ return 0;
+}
+
+int render_sa_vp_mono(struct winampVisModule *this_mod)
+{
+ int x;
+ unsigned char *sd=this_mod->spectrumData[0];
+ unsigned char *b3,*b1,*b2;
+ int pos=0;
+ int vsize=hadjusted;
+ int dpos=(min(configst.nbands,511)<<16)/vsize;
+
+ if (!DD_Enter(0,configst.h-64,configst.w,configst.h)) return 0;
+
+ if (vsize > configst.h-32-64) vsize=configst.h-32-64;
+ b1 = fb_locked + scrpitch*((configst.h-32-64)/2+32+vsize/2) + lpos;
+ b2 = b1+rpos-lpos;
+
+ _render_analyzer(this_mod,1);
+
+ for (x = 0; x < vsize; x ++)
+ {
+ b1[0] = g_scrollbuf[x];
+ b1-=scrpitch;
+ }
+
+ if (rpos < configst.w-2) b3 = b2+1;
+ else b3 = b2 - (configst.w-2);
+
+ for (x = 0; x < vsize; x++)
+ {
+ int ipos=(pos>>16);
+ int l = (((int)sd[ipos+1])*((pos&0xffff)) + ((int)sd[ipos]) *(0x10000-(pos&0xffff)))>>16;
+ l=(l*240)/1024;
+ pos+=dpos;
+ if (l > 63) l = 63;
+ l+=65;
+ b2[0]=l;
+ g_scrollbuf[x]=l;
+ b2-=scrpitch;
+ b3[0] = 255;
+ b3-=scrpitch;
+ }
+
+ lpos=rpos;
+ if (++rpos >= configst.w) rpos -= configst.w;
+
+ DD_Unlock(configst.w,0);
+ return 0;
+}
+
+int render_osc_sa_mono(struct winampVisModule *this_mod)
+{
+ if (!DD_Enter(0,0,configst.w,configst.h)) return 0;
+
+ _render_analyzer(this_mod,0);
+ _render_scope(this_mod,configst.h);
+
+ DD_Unlock(configst.w,1);
+ return 0;
+}
+
+/*
+cleanup (opposite of init()). Destroys the window, unregisters the window class
+*/
+void quit(struct winampVisModule *this_mod)
+{
+ IDirectDrawSurface_Release(lpDDSPrim);
+ IDirectDraw_Release(lpDD);
+ DestroyWindow(g_hwnd);
+ if (g_scrollbuf) GlobalFree(g_scrollbuf);
+ g_scrollbuf=0;
+ UnregisterClassW(szAppName,this_mod->hDllInstance);
+ do_unmin(this_mod->hwndParent);
+}
+
+/*
+window procedure for our window
+*/
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (message == WM_CREATE){
+ if(hFont) DeleteObject(hFont);
+ HDC hdc = GetDC(hwnd);
+ hFont = CreateFontW(-MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72),
+ 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial");
+ ReleaseDC(hwnd,hdc);
+ }
+ else if (message == WM_PAINT)
+ {
+ PAINTSTRUCT ps = {0};
+ HDC hdc = BeginPaint(hwnd,&ps);
+ EndPaint(hwnd,&ps);
+ }
+ else if (message == WM_KEYUP || message == WM_KEYDOWN)
+ {
+ if (wParam == VK_ESCAPE) DestroyWindow(hwnd);
+ else
+ {
+ PostMessage(hwndParent,message,wParam,lParam);
+ }
+ }
+ else if (message ==WM_USER+1666)
+ {
+ if (wParam == 1 && lParam == 15)
+ {
+ DestroyWindow(hwnd);
+ }
+ return 0;
+ }
+ else if (message == WM_DESTROY)
+ {
+ SendMessage(hwndParent, WM_WA_IPC, 0, IPC_SETVISWND);
+ if(hFont) DeleteObject(hFont);
+ PostQuitMessage(0);
+ }
+ else if (message == WM_TIMER)
+ {
+ g_title[0] = 0;
+ GetWindowTextW(hwndParent,g_title,sizeof(g_title)-1-32);
+ wchar_t *p = g_title;
+ while (p && *p) p = CharNextW(p); p = CharPrevW(g_title,p);
+ while (p >= g_title)
+ {
+ if (p[0] == L'-' && p[1] == L' ' && p[2] == L'W' && p[3] == L'i') break;
+ p = CharPrevW(g_title,p);
+ }
+ if (p >= g_title)
+ {
+ wchar_t *e=p;
+ while (e && *e && *e != L'[') e = CharNextW(e);
+ while (p >= g_title && *p == L' ') p = CharPrevW(g_title,p);
+ if (p < g_title) p = CharNextW(p);
+ *(p = CharNextW(p)) = L' ';
+ *p = 0;
+ if (e && *e)
+ {
+ int n=29;
+ while (e && *e && n--)
+ {
+ *p = *e;
+ p = CharNextW(p);
+ e = CharNextW(e);
+ }
+ *p = 0;
+ }
+ }
+ else g_title[0]=0;
+
+ LRESULT t = (SendMessage(hwndParent,WM_USER,0,105) + 500) / 1000;
+ if (t)
+ {
+ p = g_title;
+ while (p && *p) p = CharNextW(p);
+ LRESULT tt = (SendMessage(hwndParent,WM_USER,1,105)*1000);
+ if(tt > 0){
+ int length = tt/=1000,
+ minutes = length/60,
+ seconds = length - (minutes*60);
+ wsprintfW(p,L" [%d:%02d / %d:%02d]",t/60,t%60,minutes,seconds);
+ }
+ else{
+ wsprintfW(p,L" [%d:%02d / %d:%02d]",t/60,t%60);
+ }
+ }
+ // if we did not get a time then remove the '-' on the end
+ else{
+ *(p = CharPrevW(g_title,p)) = 0;
+ }
+ }
+ else if (message == WM_SETCURSOR) SetCursor(NULL);
+ else return DefWindowProc(hwnd,message,wParam,lParam);
+ return 0;
+}
+
+void init_inifile(struct winampVisModule *this_mod)
+{
+ ini_file = (wchar_t*)SendMessage(this_mod->hwndParent,WM_WA_IPC,0,IPC_GETINIFILEW);
+}
+
+static void config_read(struct winampVisModule *this_mod)
+{
+ init_inifile(this_mod);
+ if (!GetPrivateProfileStructW(szAppName,L"colors",colpoints,sizeof(colpoints),ini_file))
+ {
+ int x=sizeof(colpoints);
+ char *i=(char*)orig_colpoints, *o=(char*)colpoints;
+ while (x--) *o++=*i++;
+ }
+
+ GetPrivateProfileStructW(szAppName,L"config",&configst,sizeof(configst),ini_file);
+}
+
+void config_write(struct winampVisModule *this_mod)
+{
+ init_inifile(this_mod);
+ WritePrivateProfileStructW(szAppName,L"colors",colpoints,sizeof(colpoints),ini_file);
+ WritePrivateProfileStructW(szAppName,L"config",&configst,sizeof(configst),ini_file);
+}
+
+void do_vprintcol(HWND hwndDlg, unsigned char *t)
+{
+ CHOOSECOLORW cs={sizeof(cs),hwndDlg,};
+ cs.hInstance = 0;
+ cs.rgbResult=t[0] | (t[1]<<8) | (t[2]<<16);
+ cs.lpCustColors = custcolors;
+ cs.Flags = CC_RGBINIT|CC_FULLOPEN;
+ if (ChooseColorW(&cs))
+ {
+ t[0] = (unsigned char) cs.rgbResult;
+ t[1] = (unsigned char) (cs.rgbResult>>8);
+ t[2] = (unsigned char) (cs.rgbResult>>16);
+ InvalidateRect(hwndDlg,NULL,0);
+ }
+}
+
+static HRESULT WINAPI _cb(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
+{
+ if (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==8)
+ {
+ wchar_t s[32] = {0};
+ wsprintfW(s, L"%dx%d", lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
+ LRESULT idx = SendMessageW((HWND)lpContext,CB_ADDSTRING,0,(LPARAM)s);
+ SendMessage((HWND)lpContext,CB_SETITEMDATA,idx,MAKELONG(lpDDSurfaceDesc->dwWidth,lpDDSurfaceDesc->dwHeight));
+
+ if ((int)lpDDSurfaceDesc->dwWidth == configst.w && (int)lpDDSurfaceDesc->dwHeight == configst.h)
+ SendMessage((HWND)lpContext,CB_SETCURSEL,idx,0);
+ }
+ return DDENUMRET_OK;
+}
+
+static INT_PTR CALLBACK dlgProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ if (uMsg == WM_DRAWITEM)
+ {
+ DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam;
+ unsigned char *thiscol=NULL;
+ if (di->CtlID >= IDC_AP1 && di->CtlID <= IDC_VP6) thiscol=colpoints[0][di->CtlID-IDC_AP1];
+
+ if (thiscol)
+ {
+ HBRUSH b, ob;
+ RECT r;
+ GetClientRect(di->hwndItem,&r);
+ b = CreateSolidBrush(thiscol[0] | (thiscol[1]<<8) | (thiscol[2]<<16));
+ ob = (HBRUSH) SelectObject(di->hDC,b);
+ Rectangle(di->hDC,r.left,r.top,r.right,r.bottom);
+ SelectObject(di->hDC,ob);
+ DeleteObject(b);
+ }
+ }
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ SetWindowText(hwndDlg,hdr.description);
+ if (configst.peak_hold) CheckDlgButton(hwndDlg,IDC_CHECK1,BST_CHECKED);
+ SendDlgItemMessage(hwndDlg,IDC_FALLOFF,TBM_SETRANGE,0,MAKELONG(1,40));
+ SendDlgItemMessage(hwndDlg,IDC_FALLOFF,TBM_SETPOS,1,configst.falloff);
+ SendDlgItemMessage(hwndDlg,IDC_FALLOFF2,TBM_SETRANGE,0,MAKELONG(1,40));
+ SendDlgItemMessage(hwndDlg,IDC_FALLOFF2,TBM_SETPOS,1,configst.peak_falloff);
+ {
+ LPDIRECTDRAW dd;
+ if (DirectDrawCreate(NULL,&dd,NULL) == DD_OK)
+ {
+ IDirectDraw_EnumDisplayModes(dd,0,NULL,GetDlgItem(hwndDlg,IDC_MODELIST),_cb);
+ IDirectDraw_Release(dd);
+ }
+ SendDlgItemMessage(hwndDlg,IDC_BANDS,TBM_SETRANGE,0,MAKELONG(30,511));
+ SendDlgItemMessage(hwndDlg,IDC_BANDS,TBM_SETPOS,1,configst.nbands);
+ SendDlgItemMessage(hwndDlg,IDC_SCSCALE,TBM_SETRANGE,0,MAKELONG(1,100));
+ SendDlgItemMessage(hwndDlg,IDC_SCSCALE,TBM_SETPOS,1,configst.scopesc);
+ SendDlgItemMessage(hwndDlg,IDC_VUSE,TBM_SETRANGE,0,MAKELONG(1,100));
+ SendDlgItemMessage(hwndDlg,IDC_VUSE,TBM_SETPOS,1,configst.hpercent);
+ if (configst.scope) CheckDlgButton(hwndDlg,IDC_SCOPE,BST_CHECKED);
+ }
+ }
+
+ if (uMsg == WM_CLOSE)
+ {
+ uMsg=WM_COMMAND;
+ wParam=IDCANCEL;
+ }
+
+ if (uMsg == WM_COMMAND)
+ {
+ int w=LOWORD(wParam);
+ if (w == IDOK || w == IDCANCEL)
+ {
+ configst.falloff = SendDlgItemMessage(hwndDlg,IDC_FALLOFF,TBM_GETPOS,0,0);
+ configst.peak_falloff = SendDlgItemMessage(hwndDlg,IDC_FALLOFF2,TBM_GETPOS,0,0);
+ configst.peak_hold=!!IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
+ configst.scope=IsDlgButtonChecked(hwndDlg,IDC_SCOPE)?1:0;
+ configst.scopesc = SendDlgItemMessage(hwndDlg,IDC_SCSCALE,TBM_GETPOS,0,0);
+ configst.nbands = SendDlgItemMessage(hwndDlg,IDC_BANDS,TBM_GETPOS,0,0);
+ configst.hpercent = SendDlgItemMessage(hwndDlg,IDC_VUSE,TBM_GETPOS,0,0);
+ EndDialog(hwndDlg,w);
+ }
+
+ if (w == IDC_MODELIST && HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ DWORD n=SendDlgItemMessage(hwndDlg,IDC_MODELIST,CB_GETCURSEL,0,0);
+ if (n != CB_ERR)
+ {
+ n=SendDlgItemMessage(hwndDlg,IDC_MODELIST,CB_GETITEMDATA,n,0);
+ if (n != CB_ERR)
+ {
+ configst.w=LOWORD(n);
+ configst.h=HIWORD(n);
+ }
+ }
+ }
+ if (w == IDC_DEFVP || w == IDC_DEFAP)
+ {
+ int p=(w != IDC_DEFAP);
+ int x=sizeof(colpoints)/2;
+ char *i=(char*)orig_colpoints[p], *o=(char*)colpoints[p];
+ if (p) x-=3;
+ while (x--) *o++=*i++;
+ InvalidateRect(hwndDlg,NULL,FALSE);
+ }
+ if (w >= IDC_AP1 && w <= IDC_VP6) do_vprintcol(hwndDlg,colpoints[0][w-IDC_AP1]);
+ }
+
+ if (FALSE != DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam))
+ {
+ return TRUE;
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/dd.h b/Src/Plugins/Visualization/vis_nsfs/dd.h
new file mode 100644
index 00000000..0c8b089a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/dd.h
@@ -0,0 +1,28 @@
+#ifndef _DD_H_
+#define _DD_H_
+
+class C_DD
+{
+public:
+ C_DD();
+ char *open(int w, int h, HWND hwnd); // returns error string on error, or NULL on success
+ void close(void);
+ int lock(unsigned char **input, unsigned char **output);
+ void unlock(void);
+ void setpalette(unsigned char palette[768], unsigned int time_ms);
+ int palette_fadeleft(void); // returns how long til palette fade will be done
+private:
+ LPDIRECTDRAWPALETTE g_ddp;
+ LPDIRECTDRAW g_lpDD;
+ LPDIRECTDRAWSURFACE g_lpDDSPrim,g_lpPrimSurfBack;
+ LPDIRECTDRAWSURFACE g_RenderSurface[2];
+ void *g_RenderSurfaceLocked[2];
+ unsigned char g_palette_seek[768];
+ unsigned char g_palette_orig[768];
+ unsigned char g_palette_last[768];
+ int g_pal_lastv;
+ int cursurface;
+ unsigned int g_palette_starttime, g_palette_endtime;
+};
+
+#endif // _DD_H_ \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/ddraw.cpp b/Src/Plugins/Visualization/vis_nsfs/ddraw.cpp
new file mode 100644
index 00000000..d0c9da60
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/ddraw.cpp
@@ -0,0 +1,229 @@
+#include <windows.h>
+#include <ddraw.h>
+#include "dd.h"
+#include "../Agave/Language/api_language.h"
+#include "resource.h"
+
+extern HINSTANCE visDll;
+
+#pragma intrinsic(memset)
+C_DD::C_DD()
+{
+ g_lpDD=NULL;
+ cursurface=0;
+ g_ddp=NULL;
+ g_lpDDSPrim=NULL;
+ g_lpPrimSurfBack=NULL;
+ g_RenderSurface[0]=g_RenderSurface[1]=NULL;
+ g_RenderSurfaceLocked[0]=g_RenderSurfaceLocked[1]=NULL;
+ memset(g_palette_seek,0,sizeof(g_palette_seek));
+ memset(g_palette_orig,0,sizeof(g_palette_orig));
+ memset(g_palette_last,0,sizeof(g_palette_last));
+ g_pal_lastv=0;
+ g_palette_starttime=g_palette_endtime=0;
+}
+
+int C_DD::lock(unsigned char **input, unsigned char **output)
+{
+ DDSURFACEDESC d={sizeof(d),};
+ if (g_RenderSurface[cursurface]->Lock(NULL,&d,DDLOCK_WAIT,NULL) != DD_OK)
+ {
+ g_RenderSurfaceLocked[cursurface]=0;
+ return 0;
+ }
+ *input=(unsigned char*)(g_RenderSurfaceLocked[cursurface]=d.lpSurface);
+
+ DDSURFACEDESC e={sizeof(e),};
+ if (g_RenderSurface[cursurface^1]->Lock(NULL,&e,DDLOCK_WAIT,NULL) != DD_OK)
+ {
+ g_RenderSurface[cursurface]->Unlock(g_RenderSurfaceLocked[cursurface]);
+ g_RenderSurfaceLocked[cursurface^1]=0;
+ g_RenderSurfaceLocked[cursurface]=0;
+ return 0;
+ }
+ *output=(unsigned char*)(g_RenderSurfaceLocked[cursurface^1]=e.lpSurface);
+ return 1;
+}
+
+int C_DD::palette_fadeleft()
+{
+ return g_palette_endtime-GetTickCount();
+}
+
+void C_DD::unlock(void)
+{
+ if (g_RenderSurfaceLocked[0])
+ {
+ g_RenderSurface[0]->Unlock(g_RenderSurfaceLocked[0]);
+ g_RenderSurface[1]->Unlock(g_RenderSurfaceLocked[1]);
+ if (g_palette_starttime)
+ {
+ PALETTEENTRY palette[256] = {0};
+ int x = 0;
+ int len=g_palette_endtime-g_palette_starttime;
+ int pos=GetTickCount()-g_palette_starttime;
+ int do_it=1;
+
+ if (pos >= len || !len)
+ {
+ g_palette_starttime=0;
+ g_pal_lastv=-128;
+ memcpy(g_palette_last,g_palette_seek,768);
+ }
+ else
+ {
+ int adj=(pos<<8)/len;
+ int poop=(255*adj)>>8;
+ if (poop != g_pal_lastv)
+ {
+ g_pal_lastv=poop;
+ for (x = 0; x < 768; x ++)
+ {
+ int c=(((int)g_palette_seek[x])*adj + ((int)g_palette_orig[x])*(255-adj))>>8;
+ if (c > 255) c = 255;
+ g_palette_last[x]=c;
+ }
+ }
+ else do_it=0;
+ }
+
+ if (do_it)
+ {
+ int y=0;
+ for (x = 0; x < 256; x ++)
+ {
+ palette[x].peRed=g_palette_last[y];
+ palette[x].peGreen=g_palette_last[y+1];
+ palette[x].peBlue=g_palette_last[y+2];
+ palette[x].peFlags = PC_NOCOLLAPSE;
+ y+=3;
+ }
+ g_ddp->SetEntries(0,0,256,palette);
+ }
+ }
+ if (g_lpPrimSurfBack)
+ {
+ if (g_lpPrimSurfBack->Blt(NULL,g_RenderSurface[cursurface^1],NULL,DDBLT_WAIT,NULL) == DDERR_SURFACELOST)
+ {
+ g_lpDDSPrim->Restore();
+ g_lpPrimSurfBack->Restore();
+ }
+ else
+ g_lpDDSPrim->Flip(NULL,DDFLIP_WAIT);
+ }
+ else
+ {
+ if (g_lpDDSPrim->Blt(NULL,g_RenderSurface[cursurface^1],NULL,DDBLT_WAIT,NULL) == DDERR_SURFACELOST)
+ {
+ g_lpDDSPrim->Restore();
+ }
+ else g_lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
+ }
+ g_RenderSurfaceLocked[0]=0;
+ g_RenderSurfaceLocked[1]=0;
+ cursurface^=1;
+ }
+}
+
+char *C_DD::open(int w, int h, HWND hwnd)
+{
+ static char errbuf[128];
+ if (DirectDrawCreate(NULL,&g_lpDD,NULL) != DD_OK) return WASABI_API_LNGSTRING_BUF(IDS_DIRECTDRAWCREATE_FAILED,errbuf,128);
+ if (g_lpDD->SetCooperativeLevel(hwnd,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
+ {
+ g_lpDD->Release();
+ return WASABI_API_LNGSTRING_BUF(IDS_COULD_NOT_SET_EXCLUSIVE_FULLSCREEN,errbuf,128);
+ }
+ if (g_lpDD->SetDisplayMode(w,h,8) != DD_OK)
+ {
+ g_lpDD->Release();
+ return WASABI_API_LNGSTRING_BUF(IDS_COULD_NOT_SET_DISPLAY_MODE,errbuf,128);
+ }
+ DDSURFACEDESC DDsd = {0};
+ DDsd.dwSize = sizeof(DDsd);
+ DDsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
+ DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
+ DDsd.dwBackBufferCount = 1;
+ if (g_lpDD->CreateSurface(&DDsd, &g_lpDDSPrim, NULL) != DD_OK)
+ {
+ g_lpPrimSurfBack=NULL;
+ DDsd.dwSize = sizeof(DDsd);
+ DDsd.dwFlags = DDSD_CAPS;
+ DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ if (g_lpDD->CreateSurface(&DDsd, &g_lpDDSPrim, NULL) != DD_OK)
+ {
+ g_lpDD->Release();
+ return WASABI_API_LNGSTRING_BUF(IDS_COULD_NOT_CREATE_PRIMARY_SURFACE,errbuf,128);
+ }
+ }
+ else
+ {
+ DDSCAPS ddscaps;
+ ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
+ if (g_lpDDSPrim->GetAttachedSurface(&ddscaps, &g_lpPrimSurfBack) != DD_OK) // no page flipping
+ g_lpPrimSurfBack=NULL;
+ }
+
+ DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT;
+ DDsd.dwWidth=w;
+ DDsd.dwHeight=h;
+ DDsd.lPitch=w;
+ DDsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
+ DDsd.ddpfPixelFormat.dwSize = sizeof(DDsd.ddpfPixelFormat);
+ DDsd.ddpfPixelFormat.dwFlags=DDPF_PALETTEINDEXED8|DDPF_RGB;
+ DDsd.ddpfPixelFormat.dwRGBBitCount = 8;
+
+ if (g_lpDD->CreateSurface(&DDsd, &g_RenderSurface[0], NULL) != DD_OK ||
+ g_lpDD->CreateSurface(&DDsd, &g_RenderSurface[1], NULL) != DD_OK)
+ {
+ g_lpDD->Release();
+ return WASABI_API_LNGSTRING_BUF(IDS_COULD_NOT_CREATE_RENDER_SURFACE,errbuf,128);
+ }
+
+ PALETTEENTRY palette[256] = {0};
+ for (int x = 0; x < 256; x ++)
+ {
+ palette[x].peRed=palette[x].peGreen=palette[x].peBlue=0;
+ palette[x].peFlags = PC_NOCOLLAPSE;
+ }
+
+ if (g_lpDD->CreatePalette(DDPCAPS_8BIT|DDPCAPS_ALLOW256,palette,&g_ddp,NULL) != DD_OK)
+ {
+ g_lpDD->Release();
+ return WASABI_API_LNGSTRING_BUF(IDS_COULD_NOT_CREATE_PALETTE,errbuf,128);
+ }
+ if (g_lpDDSPrim->SetPalette(g_ddp) != DD_OK)
+ {
+ g_lpDD->Release();
+ return WASABI_API_LNGSTRING_BUF(IDS_COULD_NOT_SET_PALETTE,errbuf,128);
+ }
+
+ g_pal_lastv=-128;
+ g_palette_starttime=0;
+ return 0;
+}
+
+void C_DD::setpalette(unsigned char palette[768], unsigned int time_ms)
+{
+ memcpy(g_palette_seek,palette,768);
+ memcpy(g_palette_orig,g_palette_last,768);
+ g_palette_starttime=GetTickCount();
+ g_palette_endtime=g_palette_starttime+time_ms;
+}
+
+void C_DD::close(void)
+{
+ if (g_lpDD) g_lpDD->Release();
+ g_lpDD=0;
+ cursurface=0;
+ g_ddp=NULL;
+ g_lpDDSPrim=NULL;
+ g_lpPrimSurfBack=NULL;
+ g_RenderSurface[0]=g_RenderSurface[1]=NULL;
+ g_RenderSurfaceLocked[0]=g_RenderSurfaceLocked[1]=NULL;
+ memset(g_palette_seek,0,sizeof(g_palette_seek));
+ memset(g_palette_orig,0,sizeof(g_palette_orig));
+ memset(g_palette_last,0,sizeof(g_palette_last));
+ g_pal_lastv=0;
+ g_palette_starttime=g_palette_endtime=0;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/license.txt b/Src/Plugins/Visualization/vis_nsfs/license.txt
new file mode 100644
index 00000000..2a5fb083
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/license.txt
@@ -0,0 +1,9 @@
+Nullsoft TinyVis 2000 is Copyright (C) 2001, Nullsoft Inc.
+
+Redistribution of this software is permitted as long as it is in the original unmodified installer form that includes this readme and license.
+
+Use of this software for display, private or public is permitted with no restrictions, though proper credit would be appreciated.
+
+You may not reverse engineer or otherwise disassemble this software.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
diff --git a/Src/Plugins/Visualization/vis_nsfs/linedraw.cpp b/Src/Plugins/Visualization/vis_nsfs/linedraw.cpp
new file mode 100644
index 00000000..a240cf65
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/linedraw.cpp
@@ -0,0 +1,86 @@
+#include <windows.h>
+
+static void __inline DrawPixel(int color, unsigned char *fb)
+{
+ int a=*fb;
+ a+=color;
+ if (a>255)a=255;
+ *fb=(unsigned char)a;
+}
+
+// based on abrash's wu antialiasing routine
+void line(unsigned char *fb, int X0, int Y0, int X1, int Y1, int w, int h)
+{
+ unsigned int ErrorAdj=0, ErrorAcc;
+ int DeltaX, DeltaY, XDir=1;
+
+ if (Y0 > Y1)
+ {
+ int t = Y0; Y0 = Y1; Y1 = t;
+ t = X0; X0 = X1; X1 = t;
+ }
+
+ DeltaY = Y1 - Y0;
+ DeltaX = X1 - X0;
+ if (DeltaX < 0)
+ {
+ XDir = -1;
+ DeltaX = -DeltaX;
+ }
+
+ if (DeltaY > DeltaX) {
+
+ ErrorAcc = (X0&0xffff);
+ Y0>>=16;
+ X0>>=16;
+ DeltaY += 65535;
+ DeltaY >>= 16;
+ if (DeltaY) ErrorAdj = DeltaX/DeltaY;
+ fb+=Y0*w+X0;
+ while (DeltaY-- >= 0) {
+ if (X0 > 0 && Y0 >= 0 && X0 < w-1 && Y0 < h)
+ {
+ int Weighting = ErrorAcc >> 10;
+ DrawPixel(Weighting^63,fb);
+ DrawPixel(Weighting,fb+XDir);
+ }
+
+ ErrorAcc += ErrorAdj;
+ if (ErrorAcc >= 65536) {
+ X0 += XDir;
+ fb += XDir;
+ ErrorAcc -= 65536;
+ }
+ fb+=w;
+ Y0++;
+ }
+ }
+ else
+ {
+ ErrorAcc = (Y0&0xffff);
+ X0>>=16;
+ Y0>>=16;
+ DeltaX += 65535;
+ DeltaX >>= 16;
+ if (DeltaX) ErrorAdj = DeltaY/DeltaX;
+
+ fb+=Y0*w+X0;
+ while (DeltaX-- >= 0) {
+ if (Y0 >= 0 && Y0 < h-1 && X0 >= 0 && X0 < w)
+ {
+ int Weighting = ErrorAcc >> 10;
+ DrawPixel(Weighting^63,fb);
+ DrawPixel(Weighting,fb+w);
+ }
+
+ ErrorAcc += ErrorAdj;
+ if (ErrorAcc >= 65536) {
+ Y0++;
+ fb+=w;
+ ErrorAcc-=65536;
+ }
+ fb+=XDir;
+ X0+=XDir;
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/makepal.cpp b/Src/Plugins/Visualization/vis_nsfs/makepal.cpp
new file mode 100644
index 00000000..65c28a07
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/makepal.cpp
@@ -0,0 +1,96 @@
+#include <windows.h>
+#include <math.h>
+
+extern int (*warand)(void);
+static double rsc[3], rv[3];
+
+static double drand(void)
+{
+ return (warand()%4096)/(double)4096;
+}
+
+static void startgen(void)
+{
+ for (int x = 0; x < 3; x ++)
+ {
+ rsc[x]=drand()*256.0+256.0;
+ rv[x]=drand()*0.25+0.25;
+ }
+
+ if ((warand()&0xf)==5) rv[0]+=drand()*4.0;
+ if ((warand()&0xf)==2) rv[1]+=drand()*4.0;
+ if ((warand()&0xf)==3) rv[2]+=drand()*4.0;
+}
+
+static int getv(int i, int w)
+{
+ double d=sin((double)i*3.14159/256.0*rv[w])*rsc[w];
+ int v;
+ __asm
+ {
+ fld d
+ fistp v
+ }
+ if (v<0)v=0;
+ if (v>0xff)v=0xff;
+ return v;
+}
+
+static int lreversed;
+
+unsigned char *getnewpalette()
+{
+ static unsigned char thispal[256][3];
+ int x;
+ startgen();
+
+ for (x = 0; x < 768; x ++)
+ {
+ thispal[x/3][x%3]=getv(x/3,x%3);
+ }
+
+ int lr=warand()%21;
+
+ if (lreversed)
+ {
+ if (warand()&1) lreversed=0;
+ lr=4;
+ }
+ else if (lr == 4)
+ {
+ lreversed=1;
+ }
+
+ switch (lr)
+ {
+ case 3:
+ for (x = 0; x < 128; x ++)
+ {
+ thispal[x][0]=thispal[x*2][0];
+ thispal[x][1]=thispal[x*2][1];
+ thispal[x][2]=thispal[x*2][2];
+ }
+ for (; x < 256; x ++)
+ {
+ thispal[x][0]=thispal[255-x][0];
+ thispal[x][1]=thispal[255-x][1];
+ thispal[x][2]=thispal[255-x][2];
+ }
+ break;
+ case 4:
+ for (x = 0; x < 128; x ++)
+ {
+ int q;
+ for (q = 0; q < 3; q ++)
+ {
+ unsigned char t;
+ t=thispal[x][q];
+ thispal[x][q]=thispal[255-x][q];
+ thispal[255-x][q]=t;
+ }
+ }
+ break;
+ }
+
+ return &thispal[0][0];
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/moveframe.cpp b/Src/Plugins/Visualization/vis_nsfs/moveframe.cpp
new file mode 100644
index 00000000..5cdafec1
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/moveframe.cpp
@@ -0,0 +1,609 @@
+#include <windows.h>
+
+#include <math.h>
+
+#define M_PI 3.14159265358979323846
+extern int (*warand)(void);
+static int XRES=24;
+static int YRES=16;
+static int g_w,g_h;
+static int *m_wmul;
+static int *m_tab;
+
+static int __inline myftol(double d)
+{
+ int a;
+ __asm
+ {
+ fld d
+ fistp a
+ mov eax, a
+ }
+}
+
+static double getvis(unsigned char *visdata, int bc, int bw, int ch, int xorv)
+{
+ int x = 0;
+ int accum = 0;
+ if (ch && ch != 1 && ch != 2) return 0.0;
+
+ if (bw < 1) bw=1;
+ bc-=bw/2;
+ if (bc < 0)
+ {
+ bw+=bc;
+ bc=0;
+ }
+ if (bc > 575) bc=575;
+ if (bc+bw > 576) bw=576-bc;
+
+
+ if (!ch)
+ {
+ for (x = 0; x < bw; x ++)
+ {
+ accum+=(visdata[bc]^xorv)-xorv;
+ accum+=(visdata[bc+576]^xorv)-xorv;
+ bc++;
+ }
+ return (double)accum / ((double)bw*255.0);
+ }
+ else
+ {
+ if (ch == 2) visdata+=576;
+ for (x = 0; x < bw; x ++) accum+=(visdata[bc++]^xorv)-xorv;
+ return (double)accum / ((double)bw*127.5);
+ }
+}
+
+static unsigned char *m_visdata;
+
+static double getosc(double band, double bandw)
+{
+ return getvis((unsigned char *)m_visdata,myftol(band*576.0),
+ myftol(bandw*576.0),0,128);
+}
+
+static double fx_gstarttime,fx_curtime;
+static double ef10_sc;
+
+static __inline double sign(double p)
+{
+ if (p < 0.0) return -1.0;
+ return 1.0;
+}
+
+static __inline double my_asin(double v)
+{
+ double tmp;
+ __asm {
+ fld qword ptr [v]
+ fmul qword ptr [v]
+ fld st(0) //Duplicate X**2 on tos.
+ fld1 //Compute 1-X**2.
+ fsubr
+ fdiv //Compute X**2/(1-X**2).
+ fsqrt //Compute sqrt(x**2/(1-X**2)).
+ fld1 //To compute full arctangent.
+ fpatan //Compute atan of the above.
+ fstp qword ptr [tmp]
+ }
+ return tmp;
+}
+
+//#define TEST_FX 24
+
+#define RME(n,x) case n: x break;
+
+static void __fxsfunc(int which, double &d, double &r)
+{
+ double t = 0.0;
+ switch (which)
+ {
+ RME(0, r+=(0.1-0.2*d)*(cos(fx_curtime)); d*=0.96;)
+ RME(1, d*=0.99*(1.0-sin(r*3+fx_curtime*3)/32.0); r+=0.03*sin(d * M_PI * 4.0 +fx_curtime*0.5);)
+ RME(2, d*=0.94+(cos(r*32.0)*0.06);)
+ RME(3, d*=1.01+(cos(r*4.0)*0.04); r+=0.03*sin(d * M_PI * 4);)
+ RME(4, r+=0.1*sin(d*M_PI*5);)
+ RME(5, t=sin(d*M_PI); d-=8*t*t*t*t*t*0.01; )
+ RME(6, d*=0.95+(cos(r*5.0 - M_PI/2.50)*0.03); )
+ RME(7, r+=0.1*cos(fx_curtime); d*=0.96+cos(d*M_PI)*0.05; )
+ RME(8, t=tan(fx_curtime*0.2);
+ if (t < -20.0) t=-20.0;
+ if (t > 20.0) t=20.0;
+ r+=0.07*cos(d*M_PI)*t;
+ )
+ RME(9, t=d; d=d+0.05*cos(r*ef10_sc)+getosc(r,0.2)*0.5; r=r+cos(t*3.14159*ef10_sc)*0.1; )
+ RME(10, d=atan(d); )
+ RME(11, d=sin(d); )
+ RME(12, r=r+sin(d*3.14159*4)*0.1; d=(0.99+0.04*cos(r*32))*d; )
+
+ RME(13,d=d-0.01*(fabs(sin(d*3.14159*8))+0.1);)
+ RME(14,d=d*(1.0+0.5*getosc(d,0.4)); )
+ RME(15,d=0.3; )
+ RME(16,d=0.1*cos(r*4.0+fx_curtime*1.3)+d; )
+
+ RME(17,r=cos(cos(fx_curtime)*d*M_PI*17)*0.1+r; d=d*cos(r*5.0+fx_curtime)*0.1+d; )
+
+ RME(18,r+=sin(r*2.0+cos(fx_curtime*0.2)*8)*0.15; d=d*0.98; )
+
+ RME(19, t=sin(r-M_PI*0.5 + fx_curtime*0.3); if (t < 0.1) t=0.1; d=d-0.3*d*t; )
+
+ RME(20, d=0.92*d*(1.0+0.09*sin(r)); r=r+0.1*(1.0-d)*(1.0-d)*(1.0-d); )
+
+ RME(21, d=my_asin(d*0.75)*0.95/0.75;)
+
+ RME(22,r=r+(0.2*sin(r*8+fx_curtime)); d=d*0.99;)
+
+ RME(23,
+ r=r+sin(r*4+cos(fx_curtime)*3)*sin(d*3.14159*7+cos(fx_curtime*0.2)*7)*0.3;
+ d=d*(0.97+cos(r*32.7)*0.03);
+ )
+
+ RME(24,
+ r=r+cos(fx_curtime*0.3)*0.1;
+ t=r;
+ if (t < 0.0) t+=3.14159;
+ if (t > 3.14159) t-=3.14159;
+ d=atan2(d,t/2)*0.9;
+ )
+ }
+}
+
+#define NUM_FX 25
+
+#define COMBINE_FX 4
+
+static double fx_weight;
+static int cur_fx[COMBINE_FX], last_fx[COMBINE_FX];
+static double fx_offs[2][2];
+static unsigned int fx_start;
+static unsigned int fx_end,fx_end2;
+
+static void fx_init(void)
+{
+ if (GetTickCount()>=fx_end)
+ {
+ memcpy(last_fx,cur_fx,sizeof(last_fx));
+ fx_start=GetTickCount();
+ fx_end2=fx_start+400+(warand()&16383);
+ fx_end=fx_start + 4*(fx_end2-fx_start);
+ if (fx_end > fx_start+8000) fx_end=fx_start+8000;
+ if (fx_end2 > fx_end) fx_end2=fx_end;
+
+ int x;
+ for (x = 0; x < COMBINE_FX; x ++)
+ {
+ cur_fx[x]=warand()%((NUM_FX-x) + x*x*(NUM_FX/3));
+ if (cur_fx[x] == 15) cur_fx[x]=warand()%((NUM_FX-x) + x*x*(NUM_FX/3));
+ }
+
+ for (x = 1; x < COMBINE_FX; x ++)
+ {
+ if (cur_fx[x] >= NUM_FX) break;
+ }
+
+ for (; x < COMBINE_FX; x ++) cur_fx[x]=NUM_FX;
+
+ #if 0
+ static char buf[1024] = {0};
+ wsprintf(buf,"picked: ");
+ for (x = 0; x < COMBINE_FX; x ++)
+ {
+ if (cur_fx[x]>=NUM_FX) break;
+ wsprintf(buf+strlen(buf),"%d,",cur_fx[x]);
+ }
+ wsprintf(buf+strlen(buf),"\n");
+ OutputDebugString(buf);
+ #endif
+
+ // for testing
+ #ifdef TEST_FX
+ for (x = 1; x < COMBINE_FX; x++)
+ {
+ cur_fx[x]=NUM_FX;
+ }
+ cur_fx[0]=TEST_FX;
+ #endif
+
+ for (x = 0; x < 2; x ++)
+ {
+ fx_offs[1][x]=fx_offs[0][x];
+ if (!(warand()&7))
+ fx_offs[0][x]=((warand()%101) - 50)/750.0;
+ else fx_offs[0][x]=0;
+ }
+
+ static int ff;
+ if (!ff)
+ {
+ last_fx[0]=warand()%NUM_FX;
+ for (x = 1; x < COMBINE_FX; x ++)
+ {
+ last_fx[x]=NUM_FX;
+ }
+ ff++;
+ }
+ }
+
+ fx_curtime=(double)(GetTickCount()-fx_gstarttime)/1000.0;
+ fx_weight=(double)(GetTickCount()-fx_start)/(double)(fx_end2-fx_start);
+
+ if (fx_weight > 1.0) fx_weight=1.0;
+ ef10_sc=cos(fx_curtime)*2 + 3;
+}
+
+static void fx_apply(double &d, double &r) // 1 if rect
+{
+ double d2=d, r2=r;
+ int x;
+ for (x = 0; x < COMBINE_FX; x ++)
+ {
+ if (last_fx[x] < NUM_FX)
+ {
+ __fxsfunc(last_fx[x],d2,r2);
+ }
+ if (cur_fx[x] < NUM_FX)
+ {
+ __fxsfunc(cur_fx[x],d,r);
+ }
+ }
+
+ d=d*fx_weight + d2*(1.0-fx_weight);
+ r=r*fx_weight + r2*(1.0-fx_weight);
+}
+
+static int mmx_fadeval[2]={1,1};
+static unsigned int const mmx_blend4_revn[2]={0xff00ff,0xff00ff};
+static int const mmx_blend4_zero;
+
+////// NEW FASTER (HOPEFULLY) - THANKS FOR THE IDEA RYAN! :)
+static int mask1[2]={0x0000ffff,0};
+static int mask2[2]={0xffff0000,0};
+static int revy[2]={0,0xff00ff};
+static int mask3[2]={0xffffffff,0};
+static int mask4[2]={0,0xffffffff};
+static int subma=0x000000FF;
+
+#ifdef CLOOP
+static __inline unsigned char FASTMMXBLEND(unsigned char *i, unsigned int w, int xp, int yp)
+{
+ __asm
+ {
+ movd mm1, [xp]
+ mov eax, i
+
+ psrlw mm1, 8 // mm1 = -0XP
+ mov esi, w
+
+ movd mm3, [yp]
+ punpcklwd mm1,mm1 // mm1=00XP-00XP
+
+ psrlw mm3, 8 // mm3 = -0YP
+ sub ecx, ecx
+
+ movd mm2, [subma] // mm2=0000-00FF
+ mov cl, [eax]
+
+ psubw mm2, mm1 // mm2=00??-00XI
+ mov ch, [eax+1]
+
+ punpcklwd mm3,mm3 // mm3=00YP-00YP
+ pand mm1, [mask2] // mm1=00XP-0000
+
+ punpckldq mm3, mm3 //mm3=00YP-00YP-00YP-00YP
+ shl ecx, 16
+
+ movq mm4, [revy] // mm4=0000-0000-00FF-00FF
+ pand mm2, [mask1] // mm2=0000-00XI
+
+ psubw mm4, mm3 // mm4=00YI-00YI-00??-00??
+ mov cl, [eax+esi]
+
+ pand mm3, [mask3] // mm3=0000-0000-00YP-00YP
+ por mm1, mm2 // mm1=00XP-00XI
+
+ pand mm4, [mask4] // mm4=00YI-00YI-0000-0000
+ mov ch, [eax+esi+1]
+
+ por mm3, mm4 // mm3=00YP-00YP-00YI-00YI
+ punpckldq mm1, mm1 //mm1=00XP-00XI-00XP-00XI
+
+ pmullw mm1, mm3
+
+ movd mm0, ecx
+
+ punpcklbw mm0, [mmx_blend4_zero]
+ psrlw mm1, 8
+
+ Pmaddwd mm0, mm1
+ // empty
+
+ // stall
+
+ // stall
+
+ psrld mm0, 8
+ // empty
+
+ movq mm1, mm0
+ // empty
+
+ psrl mm1, 32
+ // empty
+
+ paddusb mm0, mm1
+ // empty
+
+ psubusb mm0, [mmx_fadeval]
+ // empty
+
+ movd eax, mm0
+ }
+}
+#endif
+
+void moveframe_init(int w, int h, int divx, int divy, int fadeval)
+{
+ int x = 0;
+ XRES=divx+1;
+ YRES=divy+1;
+ if (XRES&1) XRES&=~1;
+ if (YRES&1) YRES&=~1;
+ if (XRES<2) XRES=2;
+ if (YRES<2) YRES=2;
+ if (XRES>128) XRES=128;
+ if (YRES>128) YRES=128;
+ fx_gstarttime=(double)GetTickCount();
+ m_wmul = (int*)GlobalAlloc(GPTR,h*sizeof(int)+(XRES*YRES*2 + XRES*4 + 4)*sizeof(int));
+ m_tab=m_wmul + h;
+ for(x = 0; x < h; x ++)
+ m_wmul[x]=x*w;
+ g_w=w;
+ g_h=h;
+ mmx_fadeval[0]=fadeval;
+ mmx_fadeval[1]=fadeval;
+}
+
+void moveframe_quit()
+{
+ if (m_wmul) GlobalFree(m_wmul);
+ m_wmul=NULL;
+}
+
+void moveframe(unsigned char *inptr, unsigned char *outptr, unsigned char *visdata)
+{
+ m_visdata=visdata;
+ int w=g_w;
+ int h=g_h;
+ int w_adj=(w-2)<<16;
+ int h_adj=(h-2)<<16;
+
+ fx_init();
+ int x = 0;
+ int y = 0;
+ int *tabptr=m_tab;
+
+ double xsc=2.0/w,ysc=2.0/h;
+ double dw2=((double)w*32768.0);
+ double dh2=((double)h*32768.0);
+ double max_screen_d=sqrt((double)(w*w+h*h))*0.5;
+
+ double divmax_d=1.0/max_screen_d;
+
+ max_screen_d *= 65536.0;
+ double xo=fx_offs[0][0]*fx_weight + fx_offs[1][0]*(1.0-fx_weight);
+ double yo=fx_offs[0][1]*fx_weight + fx_offs[1][1]*(1.0-fx_weight);
+
+ int yc_pos, yc_dpos, xc_pos, xc_dpos;
+ yc_pos=0;
+ xc_dpos = (w<<16)/(XRES-1);
+ yc_dpos = (h<<16)/(YRES-1);
+ for (y = 0; y < YRES; y ++)
+ {
+ xc_pos=0;
+ for (x = 0; x < XRES; x ++)
+ {
+ double xd = 0, yd = 0;
+
+ xd=((double)xc_pos-dw2)*(1.0/65536.0);
+ yd=((double)yc_pos-dh2)*(1.0/65536.0);
+ xc_pos+=xc_dpos;
+
+ double var_d=sqrt(xd*xd+yd*yd)*divmax_d;
+ double var_r=atan2(yd,xd) + M_PI*0.5;
+
+ int tmp1 = 0, tmp2 = 0;
+ fx_apply(var_d,var_r);
+ var_d *= max_screen_d;
+ var_r -= M_PI*0.5;
+
+ tmp1=myftol(dw2*(1.0+xo) + cos(var_r) * var_d);
+ tmp2=myftol(dh2*(1.0+yo) + sin(var_r) * var_d);
+ if (tmp1 < 0) tmp1=0;
+ if (tmp1 > w_adj) tmp1=w_adj;
+ if (tmp2 < 0) tmp2=0;
+ if (tmp2 > h_adj) tmp2=h_adj;
+ *tabptr++ = tmp1;
+ *tabptr++ = tmp2;
+ }
+ yc_pos+=yc_dpos;
+ }
+ // yay, the table is generated. now we do a fixed point
+ // interpolation of the whole thing and pray.
+
+ int *interptab=m_tab+XRES*YRES*2;
+ int *rdtab=m_tab;
+ int yseek=1;
+ yc_pos=0;
+ xc_dpos=(w<<16)/(XRES-1);
+ yc_dpos=(h<<16)/(YRES-1);
+ int lypos=0;
+ int yl=h;
+ while (yl>0)
+ {
+ yc_pos+=yc_dpos;
+ yseek=(yc_pos>>16)-lypos;
+ if (!yseek) goto done;
+ lypos=yc_pos>>16;
+ int l=XRES;
+ int *stab=interptab;
+ int xr3=XRES*2;
+ while (l--)
+ {
+ int tmp1, tmp2;
+ tmp1=rdtab[0];
+ tmp2=rdtab[1];
+ stab[0]=tmp1;
+ stab[1]=tmp2;
+ stab[2]=(rdtab[XRES*2]-tmp1)/yseek;
+ stab[3]=(rdtab[XRES*2+1]-tmp2)/yseek;
+ rdtab+=2;
+ stab+=4;
+ }
+
+ if (yseek > yl) yseek=yl;
+ yl-=yseek;
+
+ if (yseek > 0) while (yseek--)
+ {
+ int d_x;
+ int d_y;
+ int seek;
+ int *seektab=interptab;
+ int xp,yp;
+ int l=w;
+ int lpos=0;
+ int xc_pos=0;
+ while (l>0)
+ {
+ xc_pos+=xc_dpos;
+ seek=(xc_pos>>16)-lpos;
+ if (!seek) goto done;
+ lpos=xc_pos>>16;
+ xp=seektab[0];
+ yp=seektab[1];
+ d_x=(seektab[4]-xp)/(seek);
+ d_y=(seektab[5]-yp)/(seek);
+ seektab[0] += seektab[2];
+ seektab[1] += seektab[3];
+ seektab+=4;
+
+ if (seek>l) seek=l;
+ l-=seek;
+ if (seek>0)
+ {
+ // normal loop
+#ifdef CLOOP
+ while (seek--)
+ {
+ *outptr++=FASTMMXBLEND(inptr+(xp>>16)+m_wmul[yp>>16],w,xp,yp);
+ xp+=d_x; yp+=d_y;
+ }
+#else
+ __asm
+ {
+ mov edx, seek
+ mov edi, outptr
+ mov esi, w
+
+ align 16
+ myLoop1:
+ mov eax, m_wmul
+ mov ebx, [yp]
+
+ movd mm3, ebx
+ mov ecx, [xp]
+
+ shr ebx, 16
+ movd mm1, ecx
+
+ mov eax, [eax+ebx*4];
+ shr ecx, 16
+
+ psrlw mm1, 8 // mm1 = -0XP
+ add eax, ecx
+
+ punpcklwd mm1,mm1 // mm1=00XP-00XP
+ add eax, [inptr]
+
+ psrlw mm3, 8 // mm3 = -0YP
+ movd mm2, [subma] // mm2=0000-00FF
+
+ psubw mm2, mm1 // mm2=00??-00XI
+ mov cx, [eax]
+
+ punpcklwd mm3,mm3 // mm3=00YP-00YP
+ pand mm1, [mask2] // mm1=00XP-0000
+
+ punpckldq mm3, mm3 //mm3=00YP-00YP-00YP-00YP
+ shl ecx, 16
+
+ movq mm4, [revy] // mm4=0000-0000-00FF-00FF
+ pand mm2, [mask1] // mm2=0000-00XI
+
+ mov cx, [eax+esi]
+
+ por mm1, mm2 // mm1=00XP-00XI
+ psubw mm4, mm3 // mm4=00YI-00YI-00??-00??
+
+ pand mm3, [mask3] // mm3=0000-0000-00YP-00YP
+ pand mm4, [mask4] // mm4=00YI-00YI-0000-0000
+
+ por mm3, mm4 // mm3=00YP-00YP-00YI-00YI
+ punpckldq mm1, mm1 //mm1=00XP-00XI-00XP-00XI
+
+ pmullw mm1, mm3
+
+ movd mm0, ecx
+ // empty
+
+ // stall
+
+ punpcklbw mm0, [mmx_blend4_zero]
+ psrlw mm1, 8
+
+ Pmaddwd mm0, mm1
+ mov eax, [xp]
+
+ add eax, [d_x]
+ mov ebx, [yp]
+
+ mov [xp], eax
+ add ebx, [d_y]
+
+ psrld mm0, 8
+ mov [yp], ebx
+
+ movq mm1, mm0
+ // empty
+
+ psrl mm1, 32
+ // empty
+
+ paddusb mm0, mm1
+ // empty
+
+ psubusb mm0, [mmx_fadeval]
+ // empty
+
+ movd ecx, mm0
+
+ mov [edi], cl
+
+ inc edi
+ dec edx
+ jnz myLoop1
+ mov outptr, edi
+ }
+#endif
+ }
+ }
+ // adjust final (rightmost elem) part of seektab
+ seektab[0] += seektab[2];
+ seektab[1] += seektab[3];
+ }
+ }
+done:
+ __asm emms;
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/resource.h b/Src/Plugins/Visualization/vis_nsfs/resource.h
new file mode 100644
index 00000000..f7350249
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/resource.h
@@ -0,0 +1,147 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by SVIS.RC
+//
+#define IDS_NULLSOFT_TINY_FULLSCREEN 0
+#define IDS_DIRECTDRAWCREATE_FAILED 1
+#define IDS_COULD_NOT_SET_EXCLUSIVE_FULLSCREEN 2
+#define IDS_COULD_NOT_SET_DISPLAY_MODE 3
+#define IDS_COULD_NOT_CREATE_PRIMARY_SURFACE 4
+#define IDS_COULD_NOT_CREATE_RENDER_SURFACE 5
+#define IDS_COULD_NOT_CREATE_PALETTE 6
+#define IDS_COULD_NOT_SET_PALETTE 7
+#define IDS_MMX_NOT_FOUND 8
+#define IDS_ERROR 9
+#define IDS_DIRECTDRAW_ERROR 10
+#define IDS_SEXY_SCROLLING_VOICEPRINT 11
+#define IDS_SPECTRUM_ANALYZER_VOICEPRINT 12
+#define IDS_SPECTRUM_ANALYZER_OSCILLOSCOPE 13
+#define IDS_RANDOM_INTELLIGENT_VISUALIZATION 14
+#define IDS_CANNOT_GO_FULLSCREEN_WHEN_VIDEO_PLAYING 15
+#define IDD_DIALOG1 101
+#define IDR_MENU1 101
+#define IDD_DIALOG2 102
+#define IDC_SVM 1000
+#define IDC_BPP 1001
+#define IDC_SPEED 1002
+#define IDC_AP1 1003
+#define IDC_AP2 1004
+#define IDC_AP3 1005
+#define IDC_AP4 1006
+#define IDC_AP5 1007
+#define IDC_AP6 1008
+#define IDC_VP1 1009
+#define IDC_VP2 1010
+#define IDC_VP3 1011
+#define IDC_VP4 1012
+#define IDC_VP5 1013
+#define IDC_VP6 1014
+#define IDC_DEFVP 1015
+#define IDC_FALLOFF 1016
+#define IDC_FALLOFF2 1017
+#define IDC_TCOL 1018
+#define IDC_BANDS 1018
+#define IDC_VUSE 1019
+#define IDC_DEFAP 1020
+#define IDC_SCSCALE 1021
+#define IDC_WIDTH 1084
+#define IDC_HEIGHT 1085
+#define IDC_DIZ 1086
+#define IDC_FN 1087
+#define IDC_BROWSSE 1088
+#define IDC_CRIGHT 1089
+#define IDC_CHECK1 1090
+#define IDC_MODELIST 1091
+#define IDC_SCOPE 1092
+#define IDC_EDIT1 1092
+#define IDC_EDIT2 1093
+#define IDC_SLIDER1 1094
+#define IDC_COPYRIGHT 1095
+#define IDM_WVIS 40002
+#define IDM_NOFADE 40004
+#define IDM_NORMALFADE 40005
+#define IDM_NORMALSCOPE 40008
+#define IDM_SOLIDSCOPE 40009
+#define IDM_QUIT 40010
+#define IDM_NORMALANALYZER 40012
+#define IDM_SOLIDANALYZER 40013
+#define IDM_AF_FAST 40016
+#define IDM_AF_FAST2 40017
+#define IDM_AF_FAST3 40018
+#define IDM_REFFAST 40019
+#define IDM_REFMED 40020
+#define IDM_REFSLOW 40021
+#define IDM_FLOWERS 40022
+#define IDM_CLEARFADE 40030
+#define IDM_NORMALSCOPE_COLOR 40031
+#define IDM_SOLIDSCOPE_COLOR 40032
+#define IDM_NORMALANALYZER_COLOR 40033
+#define IDM_SOLIDANALYZER_COLOR 40034
+#define IDM_FLOWERS_COLOR 40035
+#define IDM_FLOWCOMP_VLOW 40036
+#define IDM_FLOWCOMP_LOW 40037
+#define IDM_FLOWCOMP_LOWER 40038
+#define IDM_FLOWCOMP_MID 40039
+#define IDM_FLOWCOMP_HIGH 40040
+#define IDM_SLOWERFADE 40041
+#define IDM_SLOWFADE 40042
+#define IDM_FASTERFADE 40043
+#define IDM_FASTFADE 40044
+#define IDM_NORMALSCOPE_COLOR_R 40045
+#define IDM_SOLIDSCOPE_COLOR_R 40047
+#define IDM_NORMALANALYZER_COLOR_R 40049
+#define IDM_SOLIDANALYZER_COLOR_R 40050
+#define IDM_FLOWERS_COLOR_R 40051
+#define IDM_DOCK_INWINDOW 40052
+#define IDM_DOCK_BOTTOM 40053
+#define IDM_DOCK_TOP 40054
+#define IDM_DOCK_LEFT 40055
+#define IDM_DOCK_RIGHT 40056
+#define IDM_DOCK_LILVIS 40057
+#define IDM_DOCK_LILVIS_2 40058
+#define IDM_FADE_BLUR 40059
+#define IDM_PRE_LOAD 40061
+#define IDM_PRE_SAVE 40062
+#define IDM_COL_BG 40063
+#define IDM_SPECRADAR 40064
+#define IDM_SPECRADAR_COLOR 40065
+#define IDM_SPECRADAR_COLOR_R 40066
+#define IDM_VUSPIN_COLOR 40067
+#define IDM_VUSPIN_COLOR_R 40068
+#define IDM_VUSPIN 40069
+#define IDM_FADE_NONE 40070
+#define IDM_FADE_BLIT 40071
+#define IDM_SPIN_LINE 40072
+#define IDM_SPIN_TRI 40073
+#define IDM_TIME 40074
+#define IDM_TIME_LEFT 40076
+#define IDM_TIME_CENTER 40077
+#define IDM_TIME_RIGHT 40078
+#define IDM_TIME_TOP 40079
+#define IDM_TIME_MIDDLE 40080
+#define IDM_TIME_BOTTOM 40081
+#define IDM_TIME_COLOR 40082
+#define IDM_FULLSCREEN 40084
+#define IDM_FULLSCREEN_320X200 40085
+#define IDM_FULLSCREEN_320X240 40086
+#define IDM_FULLSCREEN_512X384 40087
+#define IDM_FULLSCREEN_640x400 40088
+#define IDM_FULLSCREEN_640x480 40089
+#define IDM_FULLSCREEN_800X600 40090
+#define IDM_OSCSTAR 40091
+#define IDM_OSCSTAR_COLOR 40092
+#define IDM_OSCSTAR_COLOR_R 40093
+#define ID_BLEND_AVG 40094
+#define ID_BLEND_ADD 40095
+#define ID_BLEND_MAX 40096
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 109
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1091
+#define _APS_NEXT_SYMED_VALUE 105
+#endif
+#endif
diff --git a/Src/Plugins/Visualization/vis_nsfs/scope.cpp b/Src/Plugins/Visualization/vis_nsfs/scope.cpp
new file mode 100644
index 00000000..ec1ede89
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/scope.cpp
@@ -0,0 +1,200 @@
+#include <windows.h>
+#include <math.h>
+
+#define M_PI 3.14159265358979323846
+extern int (*warand)(void);
+extern void line(unsigned char *fb, int X0, int Y0, int X1, int Y1, int w, int h);
+
+static double sc_curtime;
+static unsigned int sc_starttime;
+
+static int __inline myftol(double d)
+{
+ int a;
+ __asm
+ {
+ fld d
+ fistp a
+ mov eax, a
+ }
+}
+
+static void __doscope(int fx, int ipos, double i, double v, double &x, double &y, double &sc_tmp)
+{
+ double r,d;
+ switch (fx)
+ {
+ case 0: x=2.0*(i-0.5); y=v*0.5; return;
+ case 1:
+ x=cos(i*M_PI*3.0+sc_curtime)*(0.5+v*0.2);
+ y=sin(i*M_PI*6.0+sc_curtime)*(0.5+v*0.2);
+ return;
+ case 2:
+ r=i*M_PI*128+sc_curtime;
+ x=cos(r/(64.0+32.0*cos(sc_curtime*M_PI)))*0.4+sin(r)*0.05;
+ y=sin(r/(64.0+32.0*cos(sc_curtime*M_PI)))*0.4+cos(r)*0.05;
+ return;
+ case 3:
+ r=M_PI*cos(sc_curtime*0.5)*2;
+ x=cos(r)*0.3+cos(i*M_PI*2)*v*0.5;
+ y=sin(r)*0.3+sin(i*M_PI*2)*v*0.5;
+ return;
+ case 4:
+ r=M_PI*cos(sc_curtime*0.5)*2;
+ x=cos(r)*0.3+cos(i*M_PI*2)*(1.0+v)*0.23;
+ y=sin(r*1.5)*0.3+sin(i*M_PI*2)*(1.0+v)*0.23;
+ return;
+ case 5:
+ y=2.0*(i-0.5);
+ x=v*0.5 + 0.4*cos(sc_curtime);
+ return;
+ case 6:
+ d=i+v*0.2;
+ r=sc_curtime+i*3.14159*4;
+ x=cos(r)*d*0.6;
+ y=sin(r)*d*0.6;
+ return;
+ case 7:
+ x=(i-0.5)*2.0;
+ y=0.25-0.5*fabs(sin(i*M_PI*4 + sc_curtime)) + v*0.2;
+ return;
+ case 8:
+ r=i*3.14159*2;
+ d=sin(r*3)+v*0.5;
+ x=cos(sc_curtime+r)*d;
+ y=sin(sc_curtime-r)*d;
+ return;
+ case 9:
+ x=2.0*(i-0.5);
+ y=v*v*v*0.7;
+ return;
+ case 10:
+ x=cos(i*8)*0.9*sin(sc_curtime);
+ y=sin(i*8)*0.5*v;
+ return;
+ case 11:
+ d=i-0.9;
+ sc_tmp=sc_tmp+v*0.1;
+ x=cos(sc_tmp)*d+sin(sc_tmp)*v+0.3;
+ y=sin(sc_tmp)*d-cos(sc_tmp)*v;
+ return;
+ case 12:
+ r=i*8;
+ x=cos(r)*0.3+sin(r*(3+cos(sc_curtime*0.5+i*3.0)))*0.2;
+ y=sin(r)*0.3+cos(r*(2+2*cos(sc_curtime*0.5+i*3.0)))*0.2;
+ return;
+ case 13:
+ x=v*0.3+sin(i*4*3.14159)*cos(sc_curtime)*0.4;
+ y=2.0*(i-0.5);
+ return;
+ case 14:
+ if (!(ipos&3)) x=y=0;
+ else
+ {
+ x=v;
+ y=(ipos&8)?1.0:-1.0;
+ if (ipos & 4)
+ {
+ sc_tmp=y;
+ y=x;
+ x=sc_tmp;
+ }
+ }
+ return;
+ case 15:
+ x=(ipos&1)?-1:1;
+ y=(ipos&30)?0:v;
+ return;
+ case 16:
+ r=ipos * 3.14159 * (0.3);
+ x=(0.3+v*0.1)*cos(r);
+ y=(0.3+v*0.1)*sin(r);
+ return;
+ }
+}
+
+//#define TEST_SCOPE 14
+#define NUM_SC 17
+
+static unsigned int start;
+
+#define INTERVAL 5000
+
+static int curfx[2]={0,NUM_SC},lastfx[2]={0,NUM_SC}, interval_l=INTERVAL;
+static double fxblend, lastfxblend;
+void drawscope(unsigned char *out, int w, int h, unsigned char *visdata)
+{
+ double tmp1=0.0;
+ double tmp2=0.0;
+ double tmp3=0.0;
+ double tmp4=0.0;
+ int x;
+ int lx=0;
+ int ly=0;
+ double w2=w*65536.0/2.0;
+ double h2=h*65536.0/2.0;
+ if (!sc_starttime) sc_starttime=GetTickCount();
+ sc_curtime=(GetTickCount()-sc_curtime)/1000.0;
+
+ if (GetTickCount()>=start+INTERVAL)
+ {
+ lastfxblend=fxblend;
+ lastfx[0]=curfx[0];
+ lastfx[1]=curfx[1];
+ start=GetTickCount();
+ curfx[0]=warand()%NUM_SC;
+ curfx[1]=warand()%NUM_SC;
+ interval_l=2500+(warand()&8191);
+ if (interval_l > INTERVAL) interval_l=INTERVAL;
+
+ for (x = 0; x < 2; x ++)
+ if (curfx[x] == 14 || curfx[x] == 15) curfx[x]=warand()%NUM_SC;
+ fxblend=0.25+(warand()&511)/1023.0;
+#ifdef TEST_SCOPE
+ curfx[0]=TEST_SCOPE;
+ lastfx[0]=curfx[0];
+ curfx[1]=NUM_SC;
+ lastfx[1]=NUM_SC;
+ fxblend=lastfxblend=0.0;
+#endif
+ }
+ double weight=(double)(GetTickCount()-start)*(1.0/(double)(interval_l));
+ if (weight > 1.0) weight=1.0;
+ for (x = 0; x < 576; x ++)
+ {
+ int xp;
+ int yp;
+ double xof=0.0, yof=0.0;
+ double ix=x/576.0;
+ double iy=((visdata[x]^128)-128)/127.5;
+
+ __doscope(curfx[0],x,ix,iy,xof,yof,tmp1);
+ {
+ double xof2=0.0,yof2=0.0;
+ __doscope(curfx[1],x,ix,iy,xof2,yof2,tmp3);
+ xof=xof*(1.0-fxblend) + xof2*fxblend;
+ yof=yof*(1.0-fxblend) + yof2*fxblend;
+ }
+
+ {
+ double xof2=0.0, yof2=0.0;
+ __doscope(lastfx[0],x,ix,iy,xof2,yof2,tmp2);
+ {
+ double xof3=0.0,yof3=0.0;
+ __doscope(lastfx[1],x,ix,iy,xof3,yof3,tmp4);
+ xof2=xof2*(1.0-lastfxblend) + xof3*lastfxblend;
+ yof2=yof2*(1.0-lastfxblend) + yof3*lastfxblend;
+ }
+ xof=xof*weight + xof2*(1.0-weight);
+ yof=yof*weight + yof2*(1.0-weight);
+ }
+
+ xp = myftol(xof * w2 + w2);
+ yp = myftol(yof * h2 + h2);
+
+ if (x) line(out,lx,ly,xp,yp,w,h);
+
+ lx=xp;
+ ly=yp;
+ }
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/shitdrop.cpp b/Src/Plugins/Visualization/vis_nsfs/shitdrop.cpp
new file mode 100644
index 00000000..4c1b2286
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/shitdrop.cpp
@@ -0,0 +1,318 @@
+#include <windows.h>
+#include <commctrl.h>
+#include <ddraw.h>
+#include <math.h>
+#include "../Winamp/wa_ipc.h"
+#include "resource.h"
+#include "../Agave/Language/api_language.h"
+#include <api/service/waServiceFactory.h>
+#include "dd.h"
+#include "../winamp/vis.h"
+
+int (*warand)(void)=0;
+extern wchar_t szAppName[];
+
+extern void init_inifile(struct winampVisModule *this_mod);
+extern wchar_t *ini_file;
+
+static int g_width=640, g_height=480;
+static int g_divx=16, g_divy=12, g_fadeout=2;
+static C_DD g_dd;
+extern HWND g_hwnd,hwndParent;
+static int running;
+int g_minflag;
+extern api_service *WASABI_API_SVC;
+
+void do_min(HWND hwnd)
+{
+ g_minflag=!IsIconic(hwnd);
+ if (g_minflag)
+ {
+ ShowWindow(hwnd,SW_MINIMIZE);
+ Sleep(100);
+ }
+}
+
+void do_unmin(HWND hwnd)
+{
+ if (g_minflag)
+ {
+ g_minflag=0;
+ ShowWindow(hwnd,SW_RESTORE);
+ SetForegroundWindow(hwnd);
+ }
+}
+
+static void readconfig(struct winampVisModule *this_mod)
+{
+ init_inifile(this_mod);
+ g_width=GetPrivateProfileIntW(szAppName, L"sdwidth", 640, ini_file);
+ g_height=GetPrivateProfileIntW(szAppName, L"sdheight", 480, ini_file);
+ g_divx=GetPrivateProfileIntW(szAppName, L"sdx", 16, ini_file);
+ g_divy=GetPrivateProfileIntW(szAppName, L"sdy", 12, ini_file);
+ g_fadeout=GetPrivateProfileIntW(szAppName, L"sdfadeout", 2, ini_file);
+}
+
+extern void drawscope(unsigned char *out, int w, int h, unsigned char *visdata);
+extern unsigned char *getnewpalette();
+extern void moveframe_init(int w, int h, int divx, int divy, int fadeval);
+extern void moveframe(unsigned char *in, unsigned char *out, unsigned char *visdata);
+extern void moveframe_quit();
+
+static void writeInt(wchar_t *name, int value)
+{
+ wchar_t buf[32] = {0};
+ wsprintfW(buf, L"%d", value);
+ WritePrivateProfileStringW(szAppName, name, buf, ini_file);
+}
+
+static HRESULT WINAPI _cb(LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext)
+{
+ if (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount==8)
+ {
+ wchar_t s[32] = {0};
+ wsprintfW(s, L"%dx%d", lpDDSurfaceDesc->dwWidth, lpDDSurfaceDesc->dwHeight);
+ LRESULT idx=SendMessageW((HWND)lpContext,CB_ADDSTRING,0,(LPARAM)s);
+ SendMessage((HWND)lpContext,CB_SETITEMDATA,idx,MAKELONG(lpDDSurfaceDesc->dwWidth,lpDDSurfaceDesc->dwHeight));
+
+ if ((int)lpDDSurfaceDesc->dwWidth == g_width && (int)lpDDSurfaceDesc->dwHeight == g_height)
+ SendMessage((HWND)lpContext,CB_SETCURSEL,idx,0);
+ }
+ return DDENUMRET_OK;
+}
+
+
+BOOL IsDirectMouseWheelMessage(const UINT uMsg)
+{
+ static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
+
+ if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
+ {
+ WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
+ if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
+ return FALSE;
+ }
+
+ return (WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg);
+}
+
+HWND ActiveChildWindowFromPoint(HWND hwnd, POINTS cursor_s, const int *controls, size_t controlsCount)
+{
+ POINT pt;
+ POINTSTOPOINT(pt, cursor_s);
+
+ while(controlsCount--)
+ {
+ RECT controlRect;
+ HWND controlWindow = GetDlgItem(hwnd, controls[controlsCount]);
+ if (NULL != controlWindow &&
+ FALSE != GetClientRect(controlWindow, &controlRect))
+ {
+ MapWindowPoints(controlWindow, HWND_DESKTOP, (POINT*)&controlRect, 2);
+ if (FALSE != PtInRect(&controlRect, pt))
+ {
+ unsigned long windowStyle;
+ windowStyle = (unsigned long)GetWindowLongPtrW(controlWindow, GWL_STYLE);
+ if(WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & windowStyle))
+ return controlWindow;
+ break;
+ }
+ }
+
+ }
+ return NULL;
+}
+
+BOOL DirectMouseWheel_ProcessDialogMessage(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (FALSE != IsDirectMouseWheelMessage(uMsg))
+ {
+ const int controls[] =
+ {
+ IDC_BANDS,
+ IDC_VUSE,
+ IDC_FALLOFF,
+ IDC_FALLOFF2,
+ IDC_SCSCALE,
+ IDC_SLIDER1,
+ };
+ HWND targetWindow = ActiveChildWindowFromPoint(hwnd, MAKEPOINTS(lParam), controls, ARRAYSIZE(controls));
+ if (NULL != targetWindow)
+ {
+ SendMessage(targetWindow, WM_MOUSEWHEEL, wParam, lParam);
+ SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, (long)TRUE);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK dlgProc1(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
+{
+ if (uMsg == WM_INITDIALOG)
+ {
+ LPDIRECTDRAW dd;
+ if (DirectDrawCreate(NULL,&dd,NULL) == DD_OK)
+ {
+ IDirectDraw_EnumDisplayModes(dd,0,NULL,GetDlgItem(hwndDlg,IDC_MODELIST),_cb);
+ IDirectDraw_Release(dd);
+ }
+ SetDlgItemInt(hwndDlg,IDC_EDIT1,g_divx,0);
+ SetDlgItemInt(hwndDlg,IDC_EDIT2,g_divy,0);
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETRANGE,0,MAKELONG(0,32));
+ SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_SETPOS,1,g_fadeout);
+ return 1;
+ }
+ if (uMsg == WM_CLOSE || (uMsg == WM_COMMAND && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)))
+ {
+ BOOL t;
+ g_divx=GetDlgItemInt(hwndDlg,IDC_EDIT1,&t,0);
+ g_divy=GetDlgItemInt(hwndDlg,IDC_EDIT2,&t,0);
+ g_fadeout = SendDlgItemMessage(hwndDlg,IDC_SLIDER1,TBM_GETPOS,0,0);
+ EndDialog(hwndDlg,IDOK);
+ }
+ if (uMsg == WM_COMMAND)
+ {
+ if (LOWORD(wParam) == IDC_MODELIST && HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ DWORD n=SendDlgItemMessage(hwndDlg,IDC_MODELIST,CB_GETCURSEL,0,0);
+ if (n != CB_ERR)
+ {
+ n=SendDlgItemMessage(hwndDlg,IDC_MODELIST,CB_GETITEMDATA,n,0);
+ if (n != CB_ERR)
+ {
+ g_width=LOWORD(n);
+ g_height=HIWORD(n);
+ }
+ }
+ }
+ }
+ if (FALSE != DirectMouseWheel_ProcessDialogMessage(hwndDlg, uMsg, wParam, lParam))
+ {
+ return TRUE;
+ }
+ return 0;
+}
+
+void sd_config(struct winampVisModule *this_mod)
+{
+ if (running) return;
+ running=1;
+
+ readconfig(this_mod);
+
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessage(this_mod->hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(this_mod->hDllInstance,VisNFSFLangGUID);
+
+ WASABI_API_DIALOGBOXW(IDD_DIALOG2,this_mod->hwndParent,dlgProc1);
+ writeInt(L"sdwidth", g_width);
+ writeInt(L"sdheight", g_height);
+ writeInt(L"sdx", g_divx);
+ writeInt(L"sdy", g_divy);
+ writeInt(L"sdfadeout", g_fadeout);
+ running=0;
+}
+
+static int __inline is_mmx(void) {
+ _asm {
+ sub eax, eax
+ sub edx, edx
+ inc eax
+ _emit 0x0f
+ _emit 0xa2
+ test eax, eax
+ jz noMMX
+ and edx, 0x800000
+ mov eax, edx
+ noMMX:
+
+ sub ebx, ebx // make sure compiler knows ebx and ecx are blown.
+ sub ecx, ecx
+ }
+}
+
+
+int sd_init(struct winampVisModule *this_mod)
+{
+ if (running) return 1;
+ running=1;
+
+ if (!is_mmx())
+ {
+ char err[16];
+ running=0;
+ MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_MMX_NOT_FOUND),
+ WASABI_API_LNGSTRING_BUF(IDS_ERROR,err,16),MB_OK);
+ return 1;
+ }
+
+ readconfig(this_mod);
+ warand = (int (*)())SendMessage(this_mod->hwndParent, WM_WA_IPC, 0, IPC_GET_RANDFUNC);
+
+ extern void initwindow(struct winampVisModule *this_mod,int,int);
+ initwindow(this_mod,g_width,g_height);
+ if (!g_hwnd)
+ {
+ running=0;
+ return 1;
+ }
+
+ do_min(this_mod->hwndParent);
+
+ SetForegroundWindow(g_hwnd);
+
+ char *t=g_dd.open(g_width,g_height,g_hwnd);
+ if (t)
+ {
+ char error[32];
+ DestroyWindow(g_hwnd);
+ g_hwnd=NULL;
+ do_unmin(this_mod->hwndParent);
+ UnregisterClassW(szAppName,this_mod->hDllInstance);
+ MessageBox(this_mod->hwndParent,t,WASABI_API_LNGSTRING_BUF(IDS_DIRECTDRAW_ERROR,error,32),MB_OK);
+ running=0;
+ return 1;
+ }
+ moveframe_init(g_width,g_height,g_divx,g_divy,g_fadeout);
+ g_dd.setpalette(getnewpalette(),5000);
+ return 0;
+}
+
+// render function. This draws a frame. Returns 0 if successful, 1 if visualization should end.
+int sd_render(struct winampVisModule *this_mod)
+{
+ unsigned char *in, *out;
+
+ if (g_dd.palette_fadeleft() < -500)
+ {
+ g_dd.setpalette(getnewpalette(),3500);
+ }
+
+ if (!g_dd.lock(&in,&out)) return 0;
+
+ moveframe(in,out,this_mod->waveformData[0]);
+ drawscope(out,g_width,g_height,this_mod->waveformData[0]);
+
+ g_dd.unlock();
+ return 0;
+}
+
+// cleanup (opposite of init()). Destroys the window, unregisters the window class
+void sd_quit(struct winampVisModule *this_mod)
+{
+ g_dd.close();
+ moveframe_quit();
+ ShowCursor(TRUE);
+ if (g_hwnd) DestroyWindow(g_hwnd);
+ g_hwnd=0;
+ UnregisterClassW(szAppName,this_mod->hDllInstance);
+ running=0;
+ do_unmin(this_mod->hwndParent);
+} \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/tinyvis.txt b/Src/Plugins/Visualization/vis_nsfs/tinyvis.txt
new file mode 100644
index 00000000..a9ae5e9a
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/tinyvis.txt
@@ -0,0 +1,54 @@
+Nullsoft TinyVis 2001 v2.02 - May 21, 2001
+Copyright (C) 1997-2001, Nullsoft Inc.
+======================================================================
+
+TinyVis is a Winamp visualization plug-in.
+Currently four different modes are available:
+ - Random Intelligent Visualization
+ Creates smooth, morphing randomized graphics.
+ - Sexy Scrolling Voiceprint
+ Scrolls a voiceprint across your screen.
+ - Spectrum Analyzer + Voiceprint
+ Creates a static voiceprint, and displays a spectrum analyzer
+ - Spectrum Analyzer + Oscilliscope
+ Displays a spectrum analyzer and oscilliscope.
+
+TinyVis is very small (the plug-in DLL is merely 27kb).
+
+TinyVis requires:
+ - Windows 95, 98, ME, NT 4.0, 2000, or later.
+ - DirectX 3 or later.
+ - Pentium Processor; Pentium II or Athlon recommended.
+ Note: Random Intelligent Visualization requires a processor
+ with MMX technology.
+
+Random Intelligent Visualization features:
+ - 13 waveform renderers that morph from one to another
+ - 23 dynamic movement effects that are combined and morphed
+ - randomly generated palettes that are continually faded
+ - fast 8 bit per pixel MMX rendering
+
+======================================================================
+License:
+
+Redistribution of this software is permitted as long as it is in
+the original unmodified installer form that includes this readme
+and license.
+
+Use of this software for display, private or public is permitted
+with no restrictions, though proper credit would be appreciated.
+
+You may not reverse engineer or otherwise disassemble this
+software.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
diff --git a/Src/Plugins/Visualization/vis_nsfs/version.rc2 b/Src/Plugins/Visualization/vis_nsfs/version.rc2
new file mode 100644
index 00000000..dd56fb3f
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,16,0,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Visualization Plug-in"
+ VALUE "FileVersion", "2,16,0,0"
+ VALUE "InternalName", "Nullsoft Tiny Fullscreen"
+ VALUE "LegalCopyright", "Copyright © 2001-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "vis_nsfs.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.rc b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.rc
new file mode 100644
index 00000000..b7a061d3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.rc
@@ -0,0 +1,194 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 179, 231
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ GROUPBOX "Voiceprint",IDC_STATIC,7,7,164,69
+ CONTROL "",IDC_VP1,"Button",BS_OWNERDRAW | WS_TABSTOP,13,19,14,13
+ CONTROL "",IDC_VP2,"Button",BS_OWNERDRAW | WS_TABSTOP,29,19,14,13
+ CONTROL "",IDC_VP3,"Button",BS_OWNERDRAW | WS_TABSTOP,45,19,14,13
+ CONTROL "",IDC_VP4,"Button",BS_OWNERDRAW | WS_TABSTOP,61,19,14,13
+ CONTROL "",IDC_VP5,"Button",BS_OWNERDRAW | WS_TABSTOP,77,19,14,13
+ PUSHBUTTON "Defaults",IDC_DEFVP,126,19,39,13
+ LTEXT "Bands",IDC_STATIC,14,39,21,8
+ CONTROL "Slider1",IDC_BANDS,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,11,48,75,11
+ LTEXT "Vertical use",IDC_STATIC,92,39,38,8
+ CONTROL "Slider1",IDC_VUSE,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,89,47,75,11
+ LTEXT "40",IDC_STATIC,13,61,9,8
+ LTEXT "512",IDC_STATIC,72,61,13,8
+ LTEXT "1%",IDC_STATIC,93,61,12,8
+ LTEXT "100%",IDC_STATIC,146,61,20,8
+ GROUPBOX "Analyzer",IDC_STATIC,7,80,164,72
+ CONTROL "",IDC_AP1,"Button",BS_OWNERDRAW | WS_TABSTOP,13,94,14,13
+ CONTROL "",IDC_AP2,"Button",BS_OWNERDRAW | WS_TABSTOP,29,94,14,13
+ CONTROL "",IDC_AP3,"Button",BS_OWNERDRAW | WS_TABSTOP,45,94,14,13
+ CONTROL "",IDC_AP4,"Button",BS_OWNERDRAW | WS_TABSTOP,61,94,14,13
+ CONTROL "",IDC_AP5,"Button",BS_OWNERDRAW | WS_TABSTOP,77,94,14,13
+ CONTROL "",IDC_AP6,"Button",BS_OWNERDRAW | WS_TABSTOP,101,94,14,13
+ PUSHBUTTON "Defaults",IDC_DEFAP,126,94,39,13
+ LTEXT "Falloff",IDC_STATIC,14,114,20,8
+ CONTROL "Slider1",IDC_FALLOFF,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,13,124,75,11
+ LTEXT "Slow",IDC_STATIC,15,137,16,8
+ LTEXT "Fast",IDC_STATIC,71,137,14,8
+ CONTROL "Peak Hold",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,114,49,10
+ CONTROL "Slider1",IDC_FALLOFF2,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,94,124,75,11
+ LTEXT "Slow",IDC_STATIC,95,137,16,8
+ LTEXT "Fast",IDC_STATIC,152,137,14,8
+ GROUPBOX "Scope Color",IDC_STATIC,7,156,57,35
+ CONTROL "",IDC_VP6,"Button",BS_OWNERDRAW | WS_TABSTOP,14,170,44,13
+ GROUPBOX "Scope Scaling",IDC_STATIC,70,156,102,35
+ CONTROL "Slider1",IDC_SCSCALE,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,76,167,88,11
+ LTEXT "1%",IDC_STATIC,76,179,12,8
+ LTEXT "100%",IDC_STATIC,144,179,20,8
+ CONTROL "Scope on scrolling voiceprint",IDC_SCOPE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,196,107,10
+ DEFPUSHBUTTON "OK",IDOK,7,211,50,13
+ COMBOBOX IDC_MODELIST,89,211,83,139,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+END
+
+IDD_DIALOG2 DIALOGEX 0, 0, 155, 119
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Random Intelligent Visualization"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ LTEXT "Video mode:",IDC_STATIC,5,8,40,8
+ COMBOBOX IDC_MODELIST,58,6,90,139,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Interpolation grid size:",IDC_STATIC,5,26,72,8
+ EDITTEXT IDC_EDIT1,86,24,25,12,ES_AUTOHSCROLL
+ LTEXT "x",IDC_STATIC,115,26,8,8
+ EDITTEXT IDC_EDIT2,123,24,25,12,ES_AUTOHSCROLL
+ LTEXT "16x12-32x24 recommended\n16x12 is default",IDC_STATIC,5,41,143,16,WS_DISABLED
+ GROUPBOX "Fade Out",IDC_STATIC,5,60,143,37
+ CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,12,70,129,10
+ LTEXT "slow",IDC_STATIC,12,83,15,8
+ LTEXT "fast",IDC_STATIC,129,83,12,8
+ DEFPUSHBUTTON "Close",IDOK,5,102,50,13
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 172
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 224
+ END
+
+ IDD_DIALOG2, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 148
+ TOPMARGIN, 6
+ BOTTOMMARGIN, 115
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ 65535 "{858FBF71-9878-4d86-BFDD-8FEA8361238C}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_TINY_FULLSCREEN "Nullsoft Tiny Fullscreen"
+ IDS_DIRECTDRAWCREATE_FAILED "DirectDrawCreate() failed"
+ IDS_COULD_NOT_SET_EXCLUSIVE_FULLSCREEN
+ "Could not set exclusive fullscreen"
+ IDS_COULD_NOT_SET_DISPLAY_MODE "Could not set display mode"
+ IDS_COULD_NOT_CREATE_PRIMARY_SURFACE "Could not create primary surface"
+ IDS_COULD_NOT_CREATE_RENDER_SURFACE "Could not create render surfaces"
+ IDS_COULD_NOT_CREATE_PALETTE "Could not create palette"
+ IDS_COULD_NOT_SET_PALETTE "Could not set palette"
+ IDS_MMX_NOT_FOUND "MMX technology not found"
+ IDS_ERROR "Error"
+ IDS_DIRECTDRAW_ERROR "DirectDraw Error"
+ IDS_SEXY_SCROLLING_VOICEPRINT "Sexy Scrolling Voiceprint"
+ IDS_SPECTRUM_ANALYZER_VOICEPRINT "Spectrum Analyzer + Voiceprint"
+ IDS_SPECTRUM_ANALYZER_OSCILLOSCOPE "Spectrum Analyzer + Oscilliscope"
+ IDS_RANDOM_INTELLIGENT_VISUALIZATION "Random Intelligent Visualization"
+ IDS_CANNOT_GO_FULLSCREEN_WHEN_VIDEO_PLAYING
+ "Cannot go fullscreen when video is playing"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.sln b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.sln
new file mode 100644
index 00000000..65b50854
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29806.167
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vis_nsfs", "vis_nsfs.vcxproj", "{B6E33AC6-F7BE-4671-9E73-38E58C653331}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B6E33AC6-F7BE-4671-9E73-38E58C653331}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B6E33AC6-F7BE-4671-9E73-38E58C653331}.Debug|Win32.Build.0 = Debug|Win32
+ {B6E33AC6-F7BE-4671-9E73-38E58C653331}.Release|Win32.ActiveCfg = Release|Win32
+ {B6E33AC6-F7BE-4671-9E73-38E58C653331}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {65AF4E5B-4546-4E91-BC2D-54C5C9EC8346}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj
new file mode 100644
index 00000000..b69ce045
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj
@@ -0,0 +1,372 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B6E33AC6-F7BE-4671-9E73-38E58C653331}</ProjectGuid>
+ <RootNamespace>vis_nsfs</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>true</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>..\..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>..\..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>..\..\..\..\external_dependencies\vcpkg</VcpkgInstalledDir>
+ <VcpkgUseStatic>true</VcpkgUseStatic>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;VIS_NSFS_EXPORTS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AssemblerListingLocation>$(intDir)</AssemblerListingLocation>
+ <ObjectFileName>$(intDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ddraw.lib;odbc32.lib;odbccp32.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;VIS_NSFS_EXPORTS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AssemblerListingLocation>$(intDir)</AssemblerListingLocation>
+ <ObjectFileName>$(intDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ddraw.lib;odbc32.lib;odbccp32.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;VIS_NSFS_EXPORTS;USE_VIS_HDR_HWND;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <AssemblerListingLocation>$(intDir)</AssemblerListingLocation>
+ <ObjectFileName>$(intDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ddraw.lib;odbc32.lib;odbccp32.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;VIS_NSFS_EXPORTS;USE_VIS_HDR_HWND;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <AssemblerListingLocation>$(intDir)</AssemblerListingLocation>
+ <ObjectFileName>$(intDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0409</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>ddraw.lib;odbc32.lib;odbccp32.lib;vfw32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName).dll</OutputFile>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(IntDir)$(TargetName).map</MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)*.dll ..\..\..\..\..\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="ddraw.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="linedraw.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="makepal.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="moveframe.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="scope.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="shitdrop.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="Svis.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;VIS_NSFS_EXPORTS</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Winamp\VIS.H" />
+ <ClInclude Include="dd.h" />
+ <ClInclude Include="RESOURCE.H" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="vis_nsfs.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj.filters b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj.filters
new file mode 100644
index 00000000..2e62013d
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_nsfs/vis_nsfs.vcxproj.filters
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="Svis.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ddraw.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="linedraw.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="makepal.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="moveframe.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="scope.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="shitdrop.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="dd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="RESOURCE.H">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\Winamp\VIS.H">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{6612c4d3-8cd8-41e3-a815-5ea40db20bad}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{401b2fd2-fdeb-45a3-9cc0-6b828bee4324}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{f8cac13f-b9bd-49c4-86fe-b8f26763cf04}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="vis_nsfs.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file