1023 lines
56 KiB
Plaintext
1023 lines
56 KiB
Plaintext
|
|
||
|
-----------------------------------------------------------------------
|
||
|
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.
|
||
|
|
||
|
|
||
|
|
||
|
|