DOCUMENTATION.TXT 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  1. -----------------------------------------------------------------------
  2. WINAMP 2.X VISUALIZATION PLUG-IN "MEGA SDK"
  3. ('Vis Mega SDK' for short)
  4. ('VMS' for shorter)
  5. -----------------------------------------------------------------------
  6. Description: A codebase for rapidly creating robust and feature-rich
  7. DX8-based visualization plug-ins of your own.
  8. Version: custom version based on 1.05 beta 1; upgraded to use DX9.
  9. Released: n/a
  10. Author: Ryan Geiss
  11. Copyright: (c) 2002-2007 Nullsoft, Inc.
  12. VMS HOMEPAGE: http://www.nullsoft.com/free/vms/
  13. VMS AT WINAMP: http://www.winamp.com/nsdn/winamp2x/dev/plugins/vis.jhtml
  14. SUPPORT FORUM: http://forums.winamp.com/forumdisplay.php?forumid=147
  15. -----------------------------------------------------------------------
  16. TABLE OF CONTENTS
  17. -----------------
  18. 1. Purpose of this package
  19. 2. Features
  20. 3. Required software
  21. 4. Setting up the build environment
  22. 5. Starting Your Own Plugin Based on the Framework
  23. 6. Writing your own Plugin: A Brief Tour
  24. 7. Order of Function Calls
  25. 8. Using Data From the Base Class (CPluginShell)
  26. 9. Adding Controls to the Config Panel
  27. 10. Enabling Additional Tabs (pages) on the Config Panel
  28. 11. Using Visual C++ to Debug your Plugin
  29. 12. Releasing a Plugin
  30. 13. Tips to pass on the the user, in your documentation
  31. 14. Performance Tips for DirectX 8
  32. 15. Other Resources
  33. 16. Known Bugs
  34. 17. Version History
  35. 18. License
  36. Purpose of this package
  37. -----------------------
  38. This package is for DEVELOPERS who want to write their own
  39. visualization plugins.
  40. It aims to provide a codebase that enables all developers
  41. (beginning to advanced) to easily build robust Winamp 2.x
  42. visualization plugins whose graphics are to be generated
  43. though the DirectX 8 API. This codebase will 1) drastically
  44. reduce the time it takes to write your plugin, 2) ensure
  45. that it is robust (if you follow directions), and 3) give
  46. you built-in support for many cool features, such as
  47. multiple monitors. (See below for more details.)
  48. Feel free to base any plugins on this "framework".
  49. Features
  50. --------
  51. -DESKTOP MODE. Lets your plugin run as animated wallpaper,
  52. with very little CPU overhead. (Your plugin can also
  53. run in windowed or fullscreen modes, and the user can
  54. switch between all 3 on the fly.)
  55. -SUPERIOR MULTIMON SUPPORT. Your plugin will work on systems
  56. with multiple display adapters, as well as systems with
  57. a multi-head card. For multi-head cards that treat all
  58. screens as one giant display (ie. resolutions like 2048x768
  59. or 1024x1536), your users can even use 'fake' fullscreen mode
  60. to run your plugin fullscreen on just one monitor!
  61. -SOUND ANALYSIS: the framework provides your plugin with a
  62. super-high-quality FFT (fast fourier transform) for doing your
  63. own frequency analysis, or for drawing spectra. Framework also
  64. provides super-simple loudness levels for 3 bands (bass,
  65. mids, and treble) and at varying attenuation (damping) rates.
  66. -A very nice CONFIGURATION PANEL is provided for the plugin.
  67. On the first page (tab) of the config panel are all the
  68. settings that all plugins share in common [handled by VMS];
  69. on subsequent tabs, you add your own controls, for settings
  70. that are specific to your plugin. The example plugin also
  71. shows you how to easily handle the reading/writing of settings
  72. that you add to/from the .INI file that will store your
  73. plugin's settings.
  74. -OTHER PERKS like a runtime help screen and playlist; high-precision
  75. timing (accurate to 10 microseconds, or 0.00001 seconds);
  76. pause-filtering (so your timing code won't got haywire
  77. when Winamp is unpaused); and many others.
  78. -CPU-FRIENDLY: when the window is minimized, or when you're
  79. in fullscreen mode and ALT-TAB out, the plugin sleeps to
  80. preserve CPU. FPS limiting also does its best to preserve
  81. CPU, while at the same time, accurately limiting the FPS.
  82. -ERROR FEEDBACK: provides detailed error messages to the user
  83. on failure, as well as suggestions on how to fix problems.
  84. Required software
  85. -----------------
  86. 1. Nullsoft Winamp 2.X (~1 MB)
  87. http://www.winamp.com/
  88. 2. Microsoft DirectX 8.0+ - (~11 MB)
  89. http://www.microsoft.com/windows/directx/
  90. 3. Microsoft Developer Studio (Visual C++) 6.0
  91. (a retail product)
  92. 4. Microsoft DirectX 8.0 SDK (Software Development Kit) - (~173 MB)
  93. http://www.microsoft.com/windows/directx/
  94. (then click the 'msdn' icon in the lower right, under
  95. "info for developers")
  96. *** NOTE that you can use a later SDK, such as 8.1b; but if you
  97. do, then your plugin will only run on systems with that version
  98. (or later) of the DirectX runtime installed! ***
  99. *** You can also install several versions of the SDK into
  100. different directories, and as long as the 8.0 sdk paths are
  101. selected in Dev Studio (see below), your plugin will only
  102. require the 8.0 runtime. ***
  103. 5. MSDN (Microsoft Developer Network) help library (OPTIONAL) (~1GB)
  104. (also a retail product; optional, but highly recommended
  105. to have around. If you can't get the CD's, though, you
  106. can always access the help database online at
  107. http://msdn.microsoft.com/library/ )
  108. Setting up the build environment
  109. --------------------------------
  110. [Note: for Visual C++ .Net users, see below]
  111. 1. Make sure DirectX 8.0 or later is installed.
  112. 2. Make sure the DirectX 8.0 SDK (source development kit) is installed.
  113. ** (see notes above & below) **
  114. 3. Configure Visual C++ to use the [appropriate] DX8 SDK:
  115. In Visual C++, go to Tools, then Options. Click on the
  116. 'Directories' tab. Under 'Show directories for:', select
  117. 'Include Files.' Then, below, add the INCLUDE folder
  118. underneath the folder into which you installed the DX8 SDK.
  119. Now highlight your addition and use the fancy-looking 'up'
  120. arrow icon to move it to the top of the list of directories.
  121. Now do the same thing for the LIB folder. Under 'Show
  122. directories for:', select 'Library Files.' Now add the LIB
  123. folder underneath the folder into which you installed the
  124. DX8 SDK. Again, use the fancy-looking 'up' arrow icon
  125. to move it to the top of the list of directories.
  126. *** NOTE that if you have multiple DirectX 8 SDK's (such as 8.0
  127. and 8.1b) installed to different directories, you'll want the
  128. earliest one (hopefully 8.0) to be first in the list; that's
  129. the one that will get used when you compile & link. Otherwise,
  130. your plugin will only run on systems with the other version
  131. (or later) of the DirectX runtime installed! ***
  132. 4. (optional) you might want to set Visual C++ up to use
  133. 4 spaces instead of symbolic tabs, to keep the formatting
  134. of new code that you write consistent with this code.
  135. If you want to do this, go to menu:Tools->Options, click
  136. the 'Tabs' tab, set the 'Tab Size' to 4 and click on
  137. 'Insert Spaces'.
  138. [FOR VISUAL C++ .NET USERS:]
  139. You'll want to start a fresh DLL-based project and manually
  140. add all the source/header files to it. Then go into project
  141. settings and make it **Use MFC in a SHARED DLL**.
  142. Starting Your Own Plugin Based on the Framework
  143. -----------------------------------------------
  144. 1. Copy the files in the 'ExPlugin' folder to a new folder,
  145. such as 'MyPlugin' - it can be anything.
  146. 2. In the new folder, rename the workspace file ExPlugin.dsw
  147. to MyPlugin.dsw (or equivalent).
  148. 3. Open the new workspace file (that you just renamed) in Visual C++.
  149. 4. Go to menu:Build->Configurations and select 'plugin - Win32 Debug'.
  150. 5. Go to menu:Project->Settings
  151. a. In the upper-left corner, where it says 'Settings For:',
  152. select 'All Configurations' from the dropdown box.
  153. b. Click the 'debug' tab, and under 'Executable for debug
  154. session', point it to winamp.exe (most likely
  155. c:\program files\winamp\winamp.exe). (This will enable
  156. you to debug your plugin using Visual C++.)
  157. c. Click the 'link' tab, and under 'Output file name',
  158. enter the name of the .DLL to write (such as
  159. c:\program files\winamp\plugins\vis_myplugin.dll).
  160. This should start with 'vis_' and end in the
  161. '.dll' extension. This DLL will be your plugin.
  162. d. click OK.
  163. 6. On the left you should see the workspace view (if not, hit ALT+ZERO)
  164. to bring it up) with 3 tabs at the bottom (ClassView, ResourceView,
  165. FileView). Click 'FileView'. Expand everything in this view so you
  166. can see all the files.
  167. 7. Open 'defines.h' by double-clicking it. Now edit this file according
  168. to the comments, to give your plugin a name, a version number, enter
  169. the author's name, copyright string, the name of the .INI file you
  170. want to save the user's settings in, the name of the documentation
  171. file, and so on. (You can always come back and change these values
  172. later, of course).
  173. Now you're ready to build & run the plugin:
  174. 8. Press F7 to build the plugin.
  175. a. If you get any of these error messages:
  176. fatal error C1083: Cannot open include file: 'd3d8.h'...
  177. fatal error C1083: Cannot open include file: 'd3dx8.h'...
  178. Then you haven't added the DX8 SDK *include* path to your
  179. build environment. See 'To set up the build environment'
  180. above.
  181. b. If you any linker error messages, such as this one:
  182. LINK : fatal error LNK1104: cannot open file "d3d8.lib"
  183. Then you haven't added the DX8 SDK *library* file path to your
  184. build environment. See 'To set up the build environment'
  185. above.
  186. 9. Copy the files 'ex_tex.jpg' and 'vms_desktop.dll' from the MyPlugin
  187. directory to your Winamp PLUGINS folder (usually c:\program files\
  188. winamp\plugins).
  189. 10. Run Winamp, press CTRL+P to select your plugin, and make sure that
  190. it appears in the list. Notice that the name matches what you
  191. entered into the 'defines.h' file as APPNAME; if you didn't change
  192. it, it will appear as 'Example Plugin v1.04 / VisMegaSDK' (or
  193. something similar). Next, configure the plugin, hit OK, & run it
  194. by clicking 'Start'.
  195. Writing your own Plugin: A Brief Tour
  196. -------------------------------------
  197. This starts out by pointing you at the important source code,
  198. then by showing you around the resource editor and, finally,
  199. the DirectX 8 and MSDN help libraries.
  200. 1. Take a look at each of the 6 files in the 'My Plugin Source Files'
  201. and 'My Plugin Header Files' groups. These will give you an idea
  202. of the code that makes up the example plugin. All of the
  203. behind-the-scenes code is wrapped up in the 'Framework Files'
  204. group, which you shouldn't have to bother with (unless you
  205. want to).
  206. 2. Take a close look at plugin.h. This is the C++ class that makes
  207. up your plugin. Note that the class is derived from the
  208. CPluginShell class (which is in pluginshell.h/cpp), so it inherits
  209. all its functions & variables. What you see here (in plugin.h)
  210. are the data members and functions ADDED for this specific
  211. (example) plugin, as well as the 12 pure virtual functions we've
  212. implemented from the base class.
  213. 3. Take a close look at plugin.cpp. READ THE BRIEF COMMENTS AT THE
  214. TOP OF THOSE 12 VIRTUAL FUNCTIONS TO GET AN IDEA OF WHEN THEY'RE
  215. CALLED AND WHAT THEY DO.
  216. 4. Next we'll go into the Resource Editor.
  217. Click the 'ResourceView' tab at the bottom of the Workspace view.
  218. Then expand 'plugin resources' by double-clicking it, expand
  219. 'Dialog' in the same way, and double-click 'IDD_CONFIG' to open
  220. the template for the config panel. You can now double-click
  221. individual controls to edit their properties; move/resize them;
  222. press CTRL+T to test the dialog; press CTRL+D to define the tab
  223. order; and even add new controls (using the floating toolbar)
  224. (note that added controls require a lot of support code in
  225. plugin.cpp; see 'Adding Controls to the Config Panel' below).
  226. Also expand the 'Icon' folder on the left (just after 'Dialog')
  227. and double-click IDI_PLUGIN_ICON. This is the icon used in the
  228. taskbar, window title, and ALT+TAB screen when your plugin is
  229. running. Note that there are 5 different icons within this one,
  230. all at different resolutions and color depths, accessible by
  231. changing the 'device' (just above the enlarged icon in the
  232. resource editor). So, when you go to update the icon, don't forget
  233. to update it for all devices!
  234. 5. In Windows, go to Start Menu -> Program Files -> Microsoft
  235. DirectX 8 SDK -> DirectX Documentation (Visual C++). This
  236. is the help library for DirectX 8; you will need to refer to
  237. it religiously in order to get anything done in DirectX 8.
  238. The good news is, it's *extremely* well-written.
  239. 6. In Windows, go to Start Menu -> Program Files -> Microsoft
  240. Developer Network -> MSDN Library. This is the help library
  241. for the general Win32 platform, but might not have info on
  242. DirectX 8 (depending on when your version was published).
  243. If you couldn't get the MSDN CD's, you can access the MSDN
  244. library online at:
  245. http://msdn.microsoft.com/library/
  246. You'll have to do this from time to time to write a plugin,
  247. but not nearly as often as you'll be accessing the DirectX 8
  248. help library.
  249. You might also want to take a look at the useful goodies inside
  250. utility.cpp; they could come in handy.
  251. That's it; you've now seen all the 'screens' you'll spend 99% of
  252. your time on, in order to write your own plugin.
  253. Order of Function Calls
  254. -----------------------
  255. The only code that will be called by the plugin framework are the
  256. 12 virtual functions in plugin.h. But in what order are they called?
  257. A breakdown follows. A function name in { } means that it is only
  258. called under certain conditions.
  259. Order of function calls...
  260. When the PLUGIN launches
  261. ------------------------
  262. INITIALIZATION
  263. OverrideDefaults
  264. MyPreInitialize
  265. MyReadConfig
  266. << DirectX gets initialized at this point >>
  267. AllocateMyNonDx8Stuff
  268. AllocateMyDX8Stuff
  269. RUNNING
  270. +--> { CleanUpMyDX8Stuff + AllocateMyDX8Stuff } // called together when user resizes window or toggles fullscreen<->windowed.
  271. | MyRenderFn
  272. | MyRenderUI
  273. | { MyWindowProc } // called, between frames, on mouse/keyboard/system events. 100% threadsafe.
  274. +----<< repeat >>
  275. CLEANUP
  276. CleanUpMyDX8Stuff
  277. CleanUpMyNonDx8Stuff
  278. << DirectX gets uninitialized at this point >>
  279. When the CONFIG PANEL launches
  280. ------------------------------
  281. INITIALIZATION
  282. OverrideDefaults
  283. MyPreInitialize
  284. MyReadConfig
  285. << DirectX gets initialized at this point >>
  286. RUNNING
  287. { MyConfigTabProc } // called on startup & on keyboard events
  288. CLEANUP
  289. [ MyWriteConfig ] // only called if user clicked 'OK' to exit
  290. << DirectX gets uninitialized at this point >>
  291. Using Data From the Base Class (CPluginShell)
  292. ---------------------------------------------
  293. The base class from which your CPlugin class (in plugin.cpp) is
  294. derived is called CPluginShell and is defined in pluginshell.cpp.
  295. Many of its data members are 'protected', which means that only that
  296. class itself, *plus derived classes*, can access them. ('Public'
  297. members can be accessed by anyone; 'private' are unaccessible even
  298. to derived classes.)
  299. The protected data members and methods (functions) are as follows.
  300. Generally, you should treat the data members as READ-ONLY; the only
  301. exception is in OverrideDefaults(), where you can modify some of
  302. their values to alter the "default defaults". See the comments at
  303. the top of OverrideDefaults() in plugin.cpp for more information.
  304. Here are all of the members & methods maintained by the plugin shell,
  305. and available to CPlugin:
  306. // GET METHODS
  307. // ------------------------------------------------------------
  308. int GetFrame(); // returns current frame # (starts at zero)
  309. float GetTime(); // returns current animation time (in seconds) (starts at zero) (updated once per frame)
  310. float GetFps(); // returns current estimate of framerate (frames per second)
  311. eScrMode GetScreenMode(); // returns WINDOWED, FULLSCREEN, FAKE_FULLSCREEN, DESKTOP, or NOT_YET_KNOWN (if called before or during OverrideDefaults()).
  312. HWND GetWinampWindow(); // returns handle to Winamp main window
  313. HINSTANCE GetInstance(); // returns handle to the plugin DLL module; used for things like loading resources (dialogs, bitmaps, icons...) that are built into the plugin.
  314. char* GetPluginsDirPath(); // usually returns 'c:\\program files\\winamp\\plugins\\'
  315. char* GetConfigIniFile(); // usually returns 'c:\\program files\\winamp\\plugins\\something.ini' - filename is determined from identifiers in 'defines.h'
  316. // GET METHODS THAT ONLY WORK ONCE DIRECTX IS READY
  317. // ------------------------------------------------------------
  318. // The following 'Get' methods are only available after DirectX has been initialized.
  319. // If you call these from OverrideDefaults, MyPreInitialize, or MyReadConfig,
  320. // they will return NULL (zero).
  321. // ------------------------------------------------------------
  322. HWND GetPluginWindow(); // returns handle to the plugin window. NOT persistent; can change!
  323. int GetWidth(); // returns width of plugin window interior, in pixels.
  324. int GetHeight(); // returns height of plugin window interior, in pixels.
  325. int GetBitDepth(); // returns 8, 16, 24 (rare), or 32
  326. LPDIRECT3DDEVICE8 GetDevice(); // returns a pointer to the DirectX 8 Device. NOT persistent; can change!
  327. D3DCAPS8* GetCaps(); // returns a pointer to the D3DCAPS8 structer for the device. NOT persistent; can change.
  328. 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)
  329. 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)
  330. char* GetDriverFilename(); // returns a text string with the filename of the current display adapter driver, such as "nv4_disp.dll"
  331. char* GetDriverDescription(); // returns a text string describing the current display adapter, such as "NVIDIA GeForce4 Ti 4200"
  332. // FONTS & TEXT
  333. // ------------------------------------------------------------
  334. LPD3DXFONT GetFont(eFontIndex idx); // returns a D3DX font handle for drawing text; see shell_defines.h for the definition of the 'eFontIndex' enum.
  335. int GetFontHeight(eFontIndex idx); // returns the height of the font, in pixels; see shell_defines.h for the definition of the 'eFontIndex' enum.
  336. // MISC
  337. // ------------------------------------------------------------
  338. td_soundinfo m_sound; // a structure always containing the most recent sound analysis information; defined in pluginshell.h.
  339. void SuggestHowToFreeSomeMem(); // gives the user a 'smart' messagebox that suggests how they can free up some video memory.
  340. // CONFIG PANEL SETTINGS
  341. // ------------------------------------------------------------
  342. // *** only read/write these values during CPlugin::OverrideDefaults! ***
  343. int m_start_fullscreen; // 0 or 1
  344. int m_start_desktop; // 0 or 1
  345. int m_fake_fullscreen_mode; // 0 or 1
  346. int m_max_fps_fs; // 1-120, or 0 for 'unlimited'
  347. int m_max_fps_dm; // 1-120, or 0 for 'unlimited'
  348. int m_max_fps_w; // 1-120, or 0 for 'unlimited'
  349. int m_show_press_f1_msg; // 0 or 1
  350. int m_allow_page_tearing_w; // 0 or 1
  351. int m_allow_page_tearing_fs; // 0 or 1
  352. int m_allow_page_tearing_dm; // 0 or 1
  353. int m_minimize_winamp; // 0 or 1
  354. int m_desktop_show_icons; // 0 or 1
  355. int m_desktop_textlabel_boxes; // 0 or 1
  356. int m_desktop_manual_icon_scoot; // 0 or 1
  357. int m_desktop_555_fix; // 0 = 555, 1 = 565, 2 = 888
  358. int m_dualhead_horz; // 0 = both, 1 = left, 2 = right
  359. int m_dualhead_vert; // 0 = both, 1 = top, 2 = bottom
  360. int m_save_cpu; // 0 or 1
  361. int m_skin; // 0 or 1
  362. td_fontinfo m_fontinfo[NUM_BASIC_FONTS + NUM_EXTRA_FONTS];
  363. 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.
  364. Adding Controls to the Config Panel
  365. -----------------------------------
  366. There are four basic aspects of adding a new control to the config panel,
  367. outlined below.
  368. 1. Add the control to one of the property pages in the config panel (2..8),
  369. via the Resource Editor. Note that you should not modify the config
  370. panel itself (IDD_CONFIG) or the first property page (IDD_PROPSHEET_1).
  371. Also, do not resize the page dialogs or the config panel; they are designed
  372. to fit on a 640x480 screen, and should not be expanded.
  373. 2. Add a variable (data member) to represent the control to your CPlugin class,
  374. in plugin.h.
  375. 3. In plugin.cpp:
  376. a. initialize the variable to its default value in MyPreInitialize(),
  377. b. read its value from the INI file in MyReadConfig(), and
  378. c. write its value to the INI file in MyWriteConfig().
  379. 4. In plugin.cpp, in the MyConfigTabProc function, **when 'nPage' is
  380. the index (2..8) of the tab on which the control was placed:**
  381. a. add code under WM_INITDIALOG to set the state of the control
  382. (from the variable) when the config panel is started
  383. b. add code under WM_COMMAND, case IDOK, to read the state
  384. of the control and save the result in the variable
  385. c. add a handler for your new control underneath WM_HELP, so that
  386. when the user clicks the '?' in the config panel titlebar,
  387. then clicks on your control, they get a helpful messagebox
  388. explaining what the control does.
  389. Enabling Additional Tabs (pages) on the Config Panel
  390. ----------------------------------------------------
  391. By default, only two 'tabs' (pages) are enabled on the config panel.
  392. The first is handled by the framework, and should not be modified;
  393. the second, and any you add, are handled in plugin.cpp, in MyConfigTabProc().
  394. The maximum number of tabs/pages is 8 (unless you want to modify the
  395. framework files).
  396. To add a third page (for example), simply open defines.h, and give a name
  397. to the tab by setting the value of CONFIG_PANEL_BUTTON_3. This is all you
  398. have to do to make the tab appear! To add controls to the new page, see
  399. the above section entitled 'Adding Controls to the Config Panel.'
  400. If you want to extend the framework to add a 9th page (?!), you need to:
  401. 1. create a dialog called IDD_PROPPAGE_9 (style=child, border=none, visible, ctrl parent, control).
  402. 2. in config.cpp, increment MAX_PROPERTY_PAGES
  403. 3. in config.cpp, add IDD_PROPPAGE_9 to g_proppage_id[]
  404. 4. in config.cpp, call AddButton for it
  405. Using Visual C++ to Debug your Plugin
  406. -------------------------------------
  407. 1. Build the plugin in the 'Debug' configuration
  408. (menu:Build->Configurations, then select 'debug').
  409. 2. Go to menu:Project->Settings (ALT+F7) and click the
  410. 'Debug' tab. Under 'Executable for debug session',
  411. point it to winamp.exe.
  412. 3. Press F5 to start debug session; it will launch winamp.
  413. 4. You can now configure your plugin or run it; just set a
  414. breakpoint anywhere in your code (F9) and when the code
  415. gets to that point, it will break, and you can look at
  416. variable values and browse structures (SHIFT+F9), jump
  417. around on the call stack (ALT+7), and so on.
  418. Releasing a Plugin
  419. ------------------
  420. 1. Build in Release Mode
  421. Once you're done debugging and ready to share your plugin
  422. with others, go to menu:Build->Configurations and select
  423. 'plugin - Win32 Release', then go to menu:Build->Clean and
  424. menu:Build->Rebuild All. Building in release mode makes
  425. your code smaller and faster (but doesn't allow debugging).
  426. 2. Package it up an a self-installing .EXE
  427. Here you'll want to download the Nullsoft Superpimp Install
  428. System (NSIS) from http://www.nullsoft.com/free/nsis/ to
  429. make your users' lives easier.
  430. Then read the instructions at the top of the install script
  431. file 'installer.nsi' (next to DOCUMENTATION.TXT) and edit the
  432. install script to reflect the name and version of your plugin,
  433. the paths & filenames & destination paths of everything you
  434. want packaged up, and the output installer filename.
  435. After installing NSIS, editing installer.nsi, and doing
  436. a final release build, run a command something like this
  437. from the command prompt (you'll have to adjust the paths):
  438. "c:\program files\Nsis\makensis" C:\MyProjects\MyPlugin\installer.nsi
  439. If all goes well, you'll have a file named something like
  440. 'myplugin_100.exe' in your MyPlugin directory. Test it
  441. out on a fresh machine to make sure the install screens
  442. say the right thing and install the right files, and
  443. you're set to go!
  444. 3. Checklist: (prior to actually running makensis.exe)
  445. * Did you update the version number and APPNAME in defines.h?
  446. * Did you do a final pass on the tab ordering (CTRL+D from the
  447. Resource Editor) of the config panel?
  448. * Did you add WM_HELP handlers to new controls on the config panel?
  449. * If you added any MessageBox() commands, did you supply the right
  450. HWND parameter? (The messagebox will pop up on the same monitor
  451. that that HWND is on.)
  452. * Did you test your plugin in Desktop Mode, while Winamp is
  453. *paused*, and then try moving icons around, to make sure that
  454. you're properly handling the 'redraw' flag in MyRenderFn()?
  455. * Did you update the version numbers throughout installer.nsi?
  456. * Did you update the help screen text? (see top of plugin.cpp)
  457. * Did you do your final build in Release mode?
  458. * Did you write/update documentation?
  459. Does the config panel link to it work?
  460. * Did you make/update a webpage?
  461. Does the config panel link to it work?
  462. Tips to pass on the the user, in your documentation
  463. ---------------------------------------------------
  464. 1. In general, it's a very good idea to use only Microsoft-certified
  465. WHQL (Windows Hardware Quality Labs) drivers for your video card.
  466. Often people want to get the newest, fastest beta drivers, but
  467. these drivers are almost ALWAYS riddled with new bugs.
  468. 2. If you want Winamp to listen to your sound card's Line-In or Mic-In
  469. (or other audio input channel on your system) for driving the
  470. visuals, just do the following:
  471. 1. CONNECT WIRES
  472. Connect your audio source (a stereo, a live feed, whatever) into
  473. the line-in (or microphone) 1/8" jack on your sound card.
  474. 2. SELECT SOUND INPUT CHANNEL & ADJUST VOLUME
  475. In Windows, double-click the speaker icon in your systray (where
  476. the clock is). Then, on the menu, go to Options -> Properties
  477. and select the "Recording" option. Then make sure the Line In
  478. (or Microphone) input channel (whichever is appropriate for
  479. your case) is SELECTED (with a check mark) and that the volume
  480. is close to, or at, the maximum. Hit OK.
  481. 3. TELL WINAMP TO USE LINE-IN
  482. Open Winamp, and hit CTRL+L (the "Open Location" hotkey). Now
  483. type in "linein://" as the location you want to open. (Leave out
  484. the quotes and make sure you use FORWARD slashes.) Hit PLAY
  485. in Winamp, and the little built-in oscilloscope (or spectrum
  486. analyzer) in Winamp should start showing your signal.
  487. 4. RUN YOUR VISUALIZATION PLUGIN OF CHOICE
  488. If the plugin seems to be responding too much or too little,
  489. try adjusting the volume from Windows' Volume Control, or adjust
  490. the sound level at the source.
  491. 3. For the best graphics performance, try to close as many other
  492. applications as you can, before running the plugin, especially
  493. those that tend to work in the background, such as anti-virus
  494. or file-swapping software. Also, if you must leave other
  495. applications open, try to minimize them (i.e. shrink the window
  496. down to the taskbar) so that they stay out of the painting loop.
  497. 4. LCD screens: Note that most LCD screens (flatpanels) run at 60 Hz only,
  498. meaning that they update the screen 60 times per second. However,
  499. sometimes the video driver reports that it supports other refresh
  500. rates, such as 72, 75, 85, etc. It is strongly recommended that
  501. [for fullscreen mode, and for Windows in general] you choose a
  502. display mode with a 60 Hz refresh rate, for the smoothest possible
  503. animation. For this plugin, you will also want to choose
  504. Maximum Framerates that divide evenly into 60 - such as 60, 30, 20,
  505. 15, 12, 10, 6, 5, and so on - so that the # of times the LCD shows
  506. each frame of animation remains constant, resulting in the smoothest
  507. possible animation.
  508. 5. Multiple Monitors: It is recommended that whenever you modify your Windows
  509. multimon setup (i.e. turn an adapter on/off, change its color depth, etc.)
  510. that you reboot Windows before running this plugin.
  511. 6. Video Capture: If you'd like to save sequences of video from this plugin,
  512. there are several programs out there that will let you do this. Warning:
  513. you will need a ton of free hard drive space, and a fast CPU helps. A
  514. few of these programs are:
  515. "FRAPS" http://www.fraps.com/
  516. "Hypercam" http://www.hyperionics.com
  517. (That's it, for now. PLEASE include the tip about live audio input!)
  518. Performance Tips for DirectX 8
  519. ------------------------------
  520. 1. Minimize state changes (SetTexture, SetTextureStageState,
  521. and SetRenderState) at all cost; group polygons together
  522. that share the same rendering settings and send them all
  523. together. You will be amazed at the performance gain.
  524. 2. Use Vertex Buffers and Index Buffers for all your static
  525. geometry (i.e. vertices/indices that don't change every
  526. frame - like a static model that doesn't change, even
  527. though it might move around, rotate, resize, etc. due
  528. to the world/view/projection matrices). These buffers
  529. will keep the geometry in video memory (if possible) so
  530. that the data doesn't have to cross the bus every frame;
  531. if not, they'll try to at least place the geometry/indices
  532. in AGP memory. If you don't use these driver-managed
  533. buffers (and instead use DrawPrimitiveUP and
  534. DrawIndexedPrimitiveUP), you're keeping all of your data
  535. in non-AGP system memory, and unless the data is very
  536. small, you can expect a major bottleneck. Note that for
  537. dynamically-generated vertex data (i.e. vertices are
  538. generated each frame - like when you draw a waveform),
  539. you don't have a choice.
  540. If you follow these two tips and use common sense (and know
  541. the basic theory behind how 3D accelerators work), you should
  542. be getting 30 fps on a Voodoo 3 (assuming your overdraw is low,
  543. i.e. you don't draw each pixel on the screen more than once or
  544. twice per frame).
  545. For more tips, look in the DX8 SDK Documentation, or look on
  546. the web.
  547. Other Resources
  548. ---------------
  549. 1. DX8 SDK: The DX8 documentation that came with your DX8 SDK is,
  550. by far, the most critical resource you have. It fully documents
  551. the entire API, and much more. The SDK also comes with tons of
  552. samples and their source code.
  553. 2. NSDN: the Nullsoft Developer Network, where the Winamp API
  554. is published: http://www.winamp.com/nsdn/winamp2x/
  555. If you want to do anything in MyWindowProc() that involves
  556. communicating with the Winamp window directly (such as
  557. querying for the song title/time/length, querying the playlist,
  558. adjusting the panning, toggling shuffle, etc.), you'll need
  559. to delve into NSDN. It's all extremely straightforward and
  560. simple. For a few examples of how to talk to the main Winamp
  561. window, check out PluginShellWindowProc() in pluginshell.cpp.
  562. 3. Here are links to a few sites with good DirectX tutorials/faqs/code:
  563. The X-Zone: http://www.mvps.org/directx/
  564. Gamedev.net: http://www.gamedev.net/reference/
  565. Known Bugs
  566. ----------
  567. 1. When running [true] fullscreen in a multimon setup,
  568. sometimes when the user presses ALT-TAB to switch away from the plugin
  569. and to another window, the plugin will minimize. The 'sometimes' is
  570. determined as follows:
  571. -if the user releases TAB before depressing ALT, the window
  572. minimizes (undesired behavior).
  573. -if the user depresses ALT before releasing TAB, the window does
  574. not minimize (desired behavior).
  575. 2. Desktop Mode: some features are not implemented yet. They are:
  576. -right-click -> cut/copy/paste/rename
  577. -right-click -> "send to" doesn't work on all machines
  578. -no keyboard commands (delete, enter, arrows, CTRL+X/C/V/Z)
  579. -no drag-and-drop for files
  580. -desktop shortcuts mostly work when you double-click them,
  581. but on some machines bring up an "open/save" dialog
  582. instead of actually launching the file.
  583. That's it for now.
  584. If anyone finds a solution for any of these bugs, please post the solution
  585. in the VMS forum, and it will be included in the next VMS release.
  586. Version History
  587. -----------------------------------------------------------------------
  588. [v1.05 beta 1 - June 26, 2003]
  589. -revamped the way keyboard commands are routed between your plugin
  590. and the plugin shell. Before, the shell captured certain keys
  591. ('p' for playlist, 'zxcvb' for playback, 's' for shuffle, 'F1'
  592. for help, ESC to exit, arrows for volume/seeking, etc.)
  593. and the plugin was unable to override these. Now, the shell
  594. will pass the WM_KEYDOWN/WM_CHAR message to the plugin
  595. (MyWindowProc) first, to see if it wants to process it. If the
  596. plugin steals the key, it returns 0, and the shell ignores it.
  597. If the plugin does not process the key, it returns 1, and then
  598. the shell is free to process it.
  599. *** NOTE that if you are upgrading to VMS 1.05, this means you'll have to
  600. *** update the way your WM_CHAR and WM_KEYDOWN handlers work in plugin.cpp!
  601. *** [primarily, you'll have to return 0 when you handle a key, and 1
  602. *** otherwise.]
  603. -added key: 'r' for repeat
  604. -added SKINNING; if you have Winamp 2.90+, you can now check the
  605. 'integrate with winamp' checkbox and the plugin [when running in
  606. windowed mode] will be skinned just like Winamp. The integrated
  607. window works just like any other Winamp window; it docks with
  608. other windows, CTRL+TAB cycles between them all, and lots of new
  609. keys work (J, L, CTRL+P, ALT+E, etc.).
  610. -fixed bug (or error in judgment?) where fake fullscreen mode window
  611. would actually run at the *bottom* of the Z order when running
  612. on a multiple monitor setup. The problem was that if you clicked
  613. on any other window, the taskbar would pop up, potentially overtop
  614. of the plugin. Since there's really no way around this, I decided
  615. (before) to just stick the plugin at the bottom of the Z order in
  616. this case. Well, this is now fixed; the plugin tries its best
  617. to stay on top, but watch out - if you try and click on any other
  618. windows, the taskbar WILL pop up. If you want to avoid that,
  619. you'll have to run in true fullscreen mode.
  620. -improved audio and video synchronization
  621. -the current framerate is now used to tell Winamp, each frame,
  622. exactly how far in advance it should give us the audio data.
  623. For example, if we're getting 20 fps, we should get the
  624. audio 50 ms in advance for the proper video frame to appear
  625. when the user will actually hear those audio samples.
  626. -timing: added calls to beginTimePeriod and endTimePeriod, so the assumed
  627. granularity for Sleep() is now 2 ms (down from 10 ms).
  628. This means that CPU usage will dramatically drop, and
  629. fortunately, there should be no effect on framerate accuracy.
  630. -desktop mode: added 'show icons' option to the desktop mode options
  631. dialog, so users can uncheck it (and hide/disable the icons) if they
  632. like.
  633. -user can no longer shrink the window to less than 64x48 in size.
  634. (often the minimum size will be higher than this though; see
  635. WM_GETMINMAXINFO in pluginshell.cpp).
  636. -user can now switch modes (windowed <-> fullscreen <-> desktop mode)
  637. immediately. (before, it was blocked until frame 5.)
  638. -(fixed a small bug in the example plugin, where handler for WM_KEYUP
  639. returned DefWindowProc instead of 1).
  640. -any time the DirectX setup fails when starting up (or switching to)
  641. windowed mode, the window coords are now saved to disk as a 256x256
  642. window placed at (64,64). That way, if the problem was due to running
  643. out of video memory, it will be less likely to recur.
  644. -config panel:
  645. -added two more fonts: one for the playlist, and another for the
  646. help screen.
  647. -it's now easy to add your own fonts to the font dialog in the
  648. config panel; just add the appropriate #defines in the file
  649. defines.h. Then you can access them easily from plugin.cpp by
  650. calling GetFont(EXTRA_1), GetFont(EXTRA_2), and so on, up to
  651. GetFont(EXTRA_5). You can also get their height by calling
  652. GetFontHeight(EXTRA_1) through GetFontHeight(EXTRA_5).
  653. -greatly improved the installer script.
  654. -now selects winamp2 dir by default, if both winamp 2 & 3 are installed.
  655. -fixed a bug where the plugin wasn't being correctly set as the default plugin
  656. in winamp. Also, this is no longer an option - it just automatically does it.
  657. -now, when you go to install to winamp 3, it checks to see if ClassicVis
  658. is installed. If it is, you're set; if not, it prompts you to go download
  659. it. If you choose not to, it alerts you that the installation failed.
  660. -the FFT class (fft.cpp, fft.h) now has 2 extra optional init parameters.
  661. -'bEqualize' is 1 by default; set it to 0 to have a non-equlized FFT;
  662. bass frequencies will be much higher in magnitude than treble frequencies.
  663. -'envelope_power' is 1.0 by default; adjust it to change the characteristics
  664. of the resulting frequency spectrum (see comments in fft.cpp, in
  665. InitEnvelopeTable). Set this to a negative value to not use an envelope.
  666. -the help screen is no longer pre-rendered to a texture; it is now just drawn every
  667. frame that it's needed. (Decided that that precious memory on some 8MB graphics
  668. cards was more important than having a good framerate, on some cards, while viewing
  669. the help screen.)
  670. -added some nice macros to MyRenderUI() in plugin.cpp; makes the code for drawing
  671. text much simpler.
  672. -added 2 functions, GetDriver and GetDesc, which will return text strings with the
  673. name & description of the currently active display adapter. (search these
  674. strings for vendor substrings like "nvidia", using strstr or something similar,
  675. to do vendor-specific bug workarounds. blech.)
  676. -fixed a bug in SSE detection
  677. -added handy memset_MMX() function to utility.cpp (alongside memcpy_MMX)
  678. -fixed tabbing order for controls config panel tab #1 (doh)
  679. -in 'defines.h', you now specify a long name + a short name for your plugin.
  680. The long name is used for the description string in winamp's list of plugins;
  681. the short name is used for the window caption.
  682. -in the example plugin, in plugin.cpp, the F3 key (show song length)
  683. is now a three-state toggle: off, current time, and current time / total
  684. length.
  685. [v1.04 - October 29, 2002]
  686. -DESKTOP MODE: the icing on the cake.
  687. -Allows users to run your plugin as animated wallpaper, with very
  688. little cpu overhead. Uses no overlays or other unusual hardware
  689. features.
  690. -Just make sure you include the file 'vms_desktop.dll' with your
  691. plugin; it is required for Desktop Mode to work properly.
  692. It's small, though - only 48 kb. This file is now included
  693. in the sample install script (installer.nsi).
  694. -You can toggle Desktop Mode on/off at runtime by hitting ALT+D.
  695. And as before, you can toggle Fullscreen via ALT+ENTER.
  696. -Not all features of the desktop are fully implemented, but most
  697. of the most-frequently-used features should be working.
  698. For a list of the features not yet implemented, see the
  699. 'Known Bugs' section above.
  700. -CHANGES MADE TO PLUGIN.H,CPP: (isolated for ease-of-merging purposes)
  701. 1. added a few config settings; see OverrideDefaults()
  702. in PLUGIN.CPP.
  703. 2. added 'redraw' flag to MyRenderFn - see the comments
  704. at the top of MyRenderFn. Make sure you respect this
  705. flag, or else, when the user moves icons around in
  706. Desktop Mode while Winamp is paused, your plugin
  707. will mysteriously start animating.
  708. 3. added the 'MyRenderUI' function - please break your
  709. text-rendering code in MyRenderFn off into this function.
  710. 4. removed the ClipPlaylist() functions and, instead, provided
  711. pointers to some values as params to MyRenderUI() that tell
  712. you where to place text in each of the corners. As you
  713. draw text, be sure to update these values, so that any
  714. text drawn by the plugin shell (parent class) won't try to
  715. draw text overtop of your text.
  716. -Plugins based on VMS now remember the window position when they last
  717. (successfully) exited windowed mode, and use that as the
  718. default when they re-enter windowed mode (during the same
  719. session or in a later session). If there is an error creating
  720. that window (too big/not enough video memory, off-screen
  721. because display mode resolution decreased, etc.) it will
  722. revert to the default window size & position.
  723. -Config Panel:
  724. -For users with DualHead cards that run two monitors as one
  725. virtual display (e.g. 2048x768 or 1024x1536), you can now
  726. specify which half of the screen you want Fake Fullscreen Mode
  727. and Desktop Mode to occupy, or both. See the 'DualHead'
  728. button on the config panel.
  729. -Added an option to save cpu usage by using a more-tolerant
  730. framerate limitation algorithm - saves 0-20%. Default: ON.
  731. -Fixed appearance of the help screen by adding +0.5-texel offset;
  732. on some cards, help screen text was kind of jaggy and munged.
  733. -Release builds no longer log window messages to the debug
  734. output stream.
  735. -The D3DX font for the help screen text is now created at
  736. initialization time, instead of on demand.
  737. -Framework Files:
  738. -renamed 'fontdialog.cpp' to 'config2.cpp', since it now contains
  739. more than just the font dialog code.
  740. -added 'desktop_mode.cpp' and 'icon_t.h' to support Desktop Mode.
  741. -Changes made to the sample installer script: [installer.nsi]
  742. -added UnInstall options for winamp 2 and 3
  743. -simplified things by using some !define's at the top
  744. -updated it to look for Winamp 3's new executable
  745. name: winamp3.exe (in addition to the old, which was
  746. studio.exe)
  747. -----------------------------------------------------------------------
  748. [v1.03 - August 27, 2002]
  749. [MAJOR CHANGES]
  750. -audio:
  751. -vastly improved frequency analysis by multiplying the waveform by a
  752. bell-shaped envelope before sending it to the FFT, lessening the
  753. frequency response of the old square filter and producing a more
  754. precise frequency analysis. Also improved it by doing a 1024-sample
  755. FFT (instead of a 512). Special thanks goes out to Alan Seefeldt
  756. and Alan Peevers for sharing their extensive knowledge in this area!
  757. -config panel:
  758. -split it into separate property sheets, so that
  759. future updates to VMS (this sdk) will be easier to integrate
  760. with code based on previous versions. Also, this gives developers
  761. a lot more space to add things to the config panel.
  762. -split the settings for 'fake fullscreen' mode and regular
  763. fullscreen mode into two separate sets of controls, instead
  764. of sharing controls; it was too confusing that way.
  765. -added option to minimize winamp when going fullscreen.
  766. Only actually minimizes winampwhen going fullscreen
  767. (or fake fullscreen) AND winamp and the plugin window
  768. are situated on the same monitor.
  769. -added user-configurable fonts to the config panel.
  770. -text:
  771. -added a built-in playlist!
  772. -added some sample code (in plugin.cpp / RenderText()) for showing
  773. the current song title, position, and length.
  774. -timing:
  775. -oops... hi-precision timer was disabled in last version!
  776. -also discovered an even more high-precision timer, which provides
  777. a time sampling precision of from 1 to 5 *MICRO*seconds!
  778. -ditched the 'frame delay' system and replaced it with a 'max fps'
  779. system that should work more intuitively, and be extremely
  780. accurate (thanks to the new timer).
  781. -classes:
  782. -got rid of InitMyGDIStuff() and CleanUpMyGDIStuff() - not really needed
  783. -got rid of MyPreRenderFn() - also not really needed
  784. -in windowed mode, if there is not enough video memory to create
  785. the window at the default size, the window will now try to shrink
  786. further and further, until it is small enough to work.
  787. -fixed problem where the plugin wouldn't show up in the plug-ins list
  788. in Winamp, if the user didn't have DX8 or later installed. Now
  789. it does show up in the list, and if they try to run/configure it
  790. and DX8 is missing, it will indicate this, and even offer to
  791. take them to the MS DirectX website to download it.
  792. -also started calling LoadLibrary("d3d8.dll") before calling
  793. Direct3DCreate8(), so the latter wouldn't crash on systems
  794. without DX8.
  795. -yanked the fractal stuff out of the example plugin; too complicated.
  796. [MINOR CHANGES]
  797. -now more resilient when user turns off some display (in a multimon
  798. setup), then goes to run the plugin on that display (because they
  799. didn't return to the config panel and update the display adapter
  800. selection).
  801. -improved suggested actions for when the plugin fails to start
  802. because there is not enough video memory; suggestions now
  803. include turning off other programs that might be using up
  804. video memory (Windows Media Player, NetMeeting, and so on).
  805. -config panel: disabled caps checking; sometimes requesting
  806. the caps fails when you dynamically enable/disable monitors in
  807. a multimon setup, so adapters that really exist (and are on)
  808. would be missing in the list.
  809. -config panel: added a sample combobox & slider to the 2nd property page,
  810. which now features a checkbox, slider, and combobox, all
  811. as simple examples for the plugin developer to build off of.
  812. -noticed that multipsampling only works with D3DSWAPEFFECT_DISCARD,
  813. so the code is now protected against using D3DSWAPEFFECT_COPY_VSYNC
  814. with multisampling. The config panel has also been updated to
  815. indicate to the user that if page tearing is disallowed,
  816. multisampling will not function. This is a limitation of
  817. the DirectX 8 API.
  818. -added OverrideDefaults() function; see comments in plugin.cpp
  819. -revamped the sample beat detection code
  820. -tightened up the interface to CPluginShell
  821. -made DirectX get initialized earlier (and cleaned up later)
  822. so that GetWidth() and GetHeight() would be valid longer
  823. -moved srand(time(NULL)) up to top of MyPreInitialize, in case
  824. the developer wants to randomly initialize any of their
  825. variables there.
  826. -modified PrepareFor2DDrawing() so that it always makes the range
  827. of X,Y coords -1..1 (before it was -width/2..width/2, and similarly
  828. for height). Also inverted Y, so that y==-1 is actually at the
  829. top of the screen, and Y==1 is at the bottom.
  830. -added PrepareFor3DDrawing()
  831. -improved auto-selection of best-match video mode; now, if it can't
  832. find the exact pixel format that was in the INI file,
  833. if will try other video modes that have the same bit depth,
  834. but a different arrangement of the bits. [This applies to both
  835. the config panel, AND when you go to run the plugin fullscreen.]
  836. -respected key repeat count for playlist navigation (up/down), volume
  837. adjust (up/down), and seeking (left/right).
  838. -fixed a bug where the plugin would close on WM_KEYUP/VK_ESCAPE. Now,
  839. instead, it closes on WM_KEYDOWN/VK_ESCAPE. This was a problem when
  840. you hit ESCAPE to close some other app (on WM_KEYDOWN), then the focus
  841. went to the plugin, and WM_KEYUP/VK_ESCAPE got sent to the plugin.
  842. Not sure why it was even like this in the first place...
  843. -fixed a timing but where, when the frame delay was zero (or fps
  844. was unlimited), and the plugin was using the low-precision timer,
  845. the fps reading would blow up and m_time would stop.
  846. -fixed a bug w/a parameter to CreateFont: max font weight was
  847. 900; 'twas calling it with 1000
  848. -fixed bug with context menu cleanup
  849. -fixed a bug where winamp playback nav. keys (zxcvbs) were
  850. handled under WM_KEYDOWN; should have been under WM_CHAR.
  851. -fixed a bug where DXContext was calling DestroyWindow (on the final
  852. exit of the plugin), when in fact, the window had already been
  853. destroyed (by Windows, it seems).
  854. -fixed a bug in config panel, where list of video modes wasn't updating
  855. when you changed the fullscreen adapter.
  856. -fixed a bug where DXContext was remembering the native windows display
  857. mode for the first monitor that the window was created on, only.
  858. This was a problem because if two monitors had different bit depths,
  859. and you ran it and switched to another monitor by toggling fullscreen,
  860. it would try to create a device with a back buffer whose bit depth
  861. was that of the original monitor. To fix this, it now does the
  862. following: the first time it creates a window, before changing the
  863. display mode, it remembers the native display mode for all the
  864. adapters present, then uses the appropriate one whenever it needs
  865. it.
  866. -deleted the 'DX8 Includes' project folder from the workspace;
  867. use 'External Dependencies' folder instead, it automatically
  868. points you to the right directories.
  869. -----------------------------------------------------------------------
  870. [1.02, August 5, 2002]
  871. -Fixed bug where the plugin would minimize if you were running
  872. [true] fullscreen with multiple monitors, and went to click
  873. in another window. Previously the workaround was to use fake
  874. fullscreen mode, but now this is not necessary. Fake fullscreen
  875. mode still remains, though; for the rationale, see the help text
  876. for the 'fake fullscreen mode' checkbox in the config panel.
  877. -Decided that InitMyNonDx8Stuff() should be called first, instead
  878. of last, and that CleanUpMyNonDx8Stuff() should be called last,
  879. not first.
  880. -Might have fixed a bug with high-precision timer.
  881. -Added a custom icon (...which the developer can modify, of course).
  882. -----------------------------------------------------------------------
  883. [1.01, July 19, 2002]
  884. -Initial release
  885. -----------------------------------------------------------------------
  886. License
  887. -------
  888. Copyright (C) 1999-2002 Nullsoft, Inc.
  889. This source code is provided 'as-is', without any express or implied
  890. warranty. In no event will the authors be held liable for any damages
  891. arising from the use of this source code or the software it produces.
  892. Permission is granted to anyone to use this source code for any purpose,
  893. including commercial applications, and to alter it and redistribute it
  894. freely, subject to the following restrictions:
  895. 1. The origin of this source code must not be misrepresented; you must not
  896. claim that you wrote the original source code. If you use this source code
  897. in a product, an acknowledgment in the product documentation would be
  898. appreciated but is not required.
  899. 2. Altered source versions must be plainly marked as such, and must not be
  900. misrepresented as being the original source code.
  901. 3. This notice may not be removed or altered from any source distribution.