diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT')
-rw-r--r-- | Src/Plugins/Visualization/vis_milk2/DOCUMENTATION.TXT | 1022 |
1 files changed, 1022 insertions, 0 deletions
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.
+
+
+
+
|