📄 vis_spectrum.cpp
字号:
#include "stdafx.h"
#include "vis_spectrum.h"
#include "optionsdlg.h"
#include "resource.h"
#include "frontend.h"
void* WndProcOld;
HANDLE hThread;
bool g_bAboutActive=false;
void GetColourMap();
// Window Procedure Prototype
LRESULT CALLBACK VisWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK SubWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
bool SetCurrentSkin(const char* lpszBitmap);
void GetConfigFileName(struct winampVisModule* mod, char* lpBuffer, DWORD dwSize);
void OnConfigRead(struct winampVisModule* mod);
void OnConfigWrite(struct winampVisModule* mod);
void OnPluginConfig(struct winampVisModule* mod);
void OnPluginQuit(struct winampVisModule* mod);
int OnPluginInit(struct winampVisModule* mod);
int OnPluginRender(struct winampVisModule* mod);
void UpdateRect(LPRECT lpRect, HWND hWnd);
void KillUpdateThread();
void InitUpdateThread(int nFunc = 0);
void LoadSkin();
void SaveSkin(char* szName);
DWORD kill_update_thread=0;
DWORD APIENTRY UpdateThread(LPVOID lpParam);
// obtain the address of the module
winampVisModule* OnGetModule(int nModule);
// global variables
VS_PLUGINVARS Plugin;
// a level mapper, (these were generated using another program, i did not
// write them out by hand - I am not that stupid :)
unsigned char g_achLevelMap[256] = {
0,35,85,112,129,141,150,158,164,169,174,178,182,186,189,191,194,197,199,201,203,205,207,
209,210,211,213,214,215,216,218,219,220,221,222,223,223,224,225,226,227,228,228,229,230,
230,231,231,232,232,233,233,234,234,235,235,236,236,237,237,237,238,238,239,239,239,240,
240,240,241,241,241,241,242,242,242,242,243,243,243,243,244,244,244,244,244,245,245,245,
245,245,246,246,246,246,246,246,247,247,247,247,247,247,247,247,248,248,248,248,248,248,
248,248,249,249,249,249,249,249,249,249,249,249,250,250,250,250,250,250,250,250,250,250,
250,250,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,252,252,252,252,252,
252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,
253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255
};
// global variables used for adjusting the data and colour mapping. g_achPeakData
// stores the level of the peaks in element 0 and how much delay
// is left (in frames) in element 1.
unsigned char g_achDisplayData[576];
unsigned char g_achScreenData[576];
unsigned char g_achPeakData[2][576]; // 0 = height, 1 = delay time
// A colour mapper
unsigned long g_ulColourMap[256];
unsigned long g_ulPeakColour = 0xFFFFFF;
unsigned long g_ulGridColour = 0x424100;
unsigned long g_ulBackColour = 0x000000;
// (with initialisation)
winampVisHeader waHeader = {
VIS_HDRVER,
PLUGIN_DESC,
OnGetModule
};
// The global module variable
winampVisModule waModule = {
PLUGIN_DESC,
NULL, // hWndParent
NULL, // hDllInstance
0, // sRate
0, // nCh
DEFAULT_LATENCY, // latencyMS
DEFAULT_DELAY, // delayMS
1, // spectrumNch
0, // waveformNch
{ 0, }, // spectrumData
{ 0, }, // waveformData
OnPluginConfig, // config function
OnPluginInit, // init function
OnPluginRender, // render function
OnPluginQuit // quit function
};
// exported function (also see vis_spectrum.def). Returns
// the vis header to winamp.
__declspec(dllexport) winampVisHeader* winampVisGetHeader()
{
return &waHeader;
}
// return the selected module (this dll only contains one
// module of course)
winampVisModule* OnGetModule(int nModule)
{
switch(nModule) {
case 0:
return &waModule;
default:
return NULL;
}
}
// Gets a file name for the plugin to use.
void GetConfigFileName(struct winampVisModule* mod, char* lpBuffer, DWORD dwSize)
{
char* lpPtr;
GetModuleFileName(mod->hDllInstance,lpBuffer,dwSize);
lpPtr=lpBuffer+strlen(lpBuffer);
while(lpPtr>=lpBuffer && *lpPtr !='\\') lpPtr--;
if(++lpPtr>=lpBuffer) *lpPtr = 0;
strcat(lpBuffer,CONFIG_FILE);
}
// Called when the configuration is to be read
void OnConfigRead(struct winampVisModule* mod)
{
char szFileName[256];
GetConfigFileName(mod,szFileName,256);
VS_SAVEDATA Settings = {
GetPrivateProfileInt(PLUGIN_KEY,"ulLeft",0,szFileName), // left window pos
GetPrivateProfileInt(PLUGIN_KEY,"ulTop",0,szFileName), // top window pos
GetPrivateProfileInt(PLUGIN_KEY,"ulWidth",STD_WIDTH,szFileName), // width of window
GetPrivateProfileInt(PLUGIN_KEY,"ulHeight",STD_HEIGHT,szFileName), // height of window
GetPrivateProfileInt(PLUGIN_KEY,"ulWindowSnap",10,szFileName), // window snap threshold
(GetPrivateProfileInt(PLUGIN_KEY,"bSnapWindow",1,szFileName)!=0), // snap windows
(GetPrivateProfileInt(PLUGIN_KEY,"bDoubleSize",0,szFileName)!=0),// double size
(GetPrivateProfileInt(PLUGIN_KEY,"bDimTitleBar",1,szFileName)!=0), // dim title bar on inactive
(GetPrivateProfileInt(PLUGIN_KEY,"bSaveWndPos",1,szFileName)!=0), // save window pos
(GetPrivateProfileInt(PLUGIN_KEY,"bWinampCursor",1,szFileName)!=0), // use default cursor
(GetPrivateProfileInt(PLUGIN_KEY,"bWantPeaks",1,szFileName)!=0), // show peaks
(GetPrivateProfileInt(PLUGIN_KEY,"bWantBars",1,szFileName)!=0), // show bars
(GetPrivateProfileInt(PLUGIN_KEY,"bWantGrid",1,szFileName)!=0),// show grid
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarWidth",4,szFileName), // bar width
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarHorzGap",1,szFileName), // bar horizontal gap (shrinks width of bar)
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarVertGap",0,szFileName), // vertical bar gaps
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchPeakDelay",20,szFileName), // delay (in frames of 25 ms) of peaks to drop
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchPeakDrop",4,szFileName), // peak drop speed (per frame)
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchDefaultDrop",2,szFileName), // default drop speed (when bars are below 16)
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchMaxIncrease",19,szFileName), // maximum increase at one time
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchMaxDecrease",6,szFileName), // maximum decrease at one time
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchGridWidth",4,szFileName), // horizontal grid width
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchGridVertGap",1,szFileName), // vertical grid gap
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchGridHorzGap",0,szFileName),
(GetPrivateProfileInt(PLUGIN_KEY,"bFilter",0,szFileName)!=0), // filter
(GetPrivateProfileInt(PLUGIN_KEY,"bRemap",1,szFileName)!=0), // level remap
0,
0,
(unsigned char)GetPrivateProfileInt(PLUGIN_KEY,"uchBarStyle",1,szFileName)
};
Plugin.Settings.nDelayMS = (int)GetPrivateProfileInt(PLUGIN_KEY,"nDelayMS",25,szFileName);
Plugin.Settings.nLatency = (int)GetPrivateProfileInt(PLUGIN_KEY,"nLatency",25,szFileName);
if(Plugin.Settings.nLatency < 10) Plugin.Settings.nLatency = 25;
if(Plugin.Settings.nDelayMS < 10) Plugin.Settings.nDelayMS = 25;
mod->delayMs = Plugin.Settings.nDelayMS;
mod->latencyMs = Plugin.Settings.nLatency;
Plugin.Settings = Settings;
}
// called when the configuration is to be written
void OnConfigWrite(struct winampVisModule* mod)
{
char szFileName[256];
GetConfigFileName(mod,szFileName,256);
WritePrivateProfileInt(PLUGIN_KEY,"ulLeft",Plugin.Settings.ulLeft,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"ulTop",Plugin.Settings.ulTop,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"ulWidth",Plugin.Settings.ulWidth,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"ulHeight",Plugin.Settings.ulHeight,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"ulWindowSnap",Plugin.Settings.ulWindowSnap,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bSnapWindow",(int)Plugin.Settings.bSnapWindow,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bDoubleSize",(int)Plugin.Settings.bDoubleSize,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bDimTitleBar",(int)Plugin.Settings.bDimTitleBar,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bSaveWndPos",(int)Plugin.Settings.bSaveWndPos,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bWinampCursor",(int)Plugin.Settings.bWinampCursor,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bWantPeaks",(int)Plugin.Settings.bWantPeaks,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bWantBars",(int)Plugin.Settings.bWantBars,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bWantGrid",(int)Plugin.Settings.bWantGrid,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchBarWidth",(int)Plugin.Settings.uchBarWidth,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchBarHorzGap",(int)Plugin.Settings.uchBarHorzGap,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchBarVertGap",(int)Plugin.Settings.uchBarVertGap,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchPeakDelay",(int)Plugin.Settings.uchPeakDelay,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchPeakDrop",(int)Plugin.Settings.uchPeakDrop,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchDefaultDrop",(int)Plugin.Settings.uchDefaultDrop,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchMaxIncrease",(int)Plugin.Settings.uchMaxIncrease,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchMaxDecrease",(int)Plugin.Settings.uchMaxDecrease,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchGridWidth",(int)Plugin.Settings.uchGridWidth,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchGridVertGap",(int)Plugin.Settings.uchGridVertGap,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchGridHorzGap",(int)Plugin.Settings.uchGridHorzGap,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"bFilter",(int)Plugin.Settings.bFilter,szFileName );
WritePrivateProfileInt(PLUGIN_KEY,"bRemap",(int)Plugin.Settings.bRemap,szFileName );
WritePrivateProfileInt(PLUGIN_KEY,"nLatency",(int)mod->latencyMs,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"nDelayMS",(int)mod->delayMs,szFileName);
WritePrivateProfileInt(PLUGIN_KEY,"uchBarStyle",(int)Plugin.Settings.uchBarStyle,szFileName);
}
// Configure the plugin - See optionsdlg.cpp and optionsdlg.h for
// the actual code to this.
void OnPluginConfig(struct winampVisModule* mod)
{
DoOptionsDialogThingy(mod);
}
int OnPluginInit(struct winampVisModule* mod)
{
// set global struct data
Plugin.hWndParent = mod->hwndParent;
// drawing area
Plugin.rcDrawingRect.left = 7;
Plugin.rcDrawingRect.top = 15;
Plugin.rcDrawingRect.right = 268;
Plugin.rcDrawingRect.bottom = 109;
// title bar
Plugin.rcTitleBar.top = 0;
Plugin.rcTitleBar.left = 0;
Plugin.rcTitleBar.right = STD_WIDTH;
Plugin.rcTitleBar.bottom = 14;
// close button
Plugin.rcQuitButton.left = 264;
Plugin.rcQuitButton.top = 3;
Plugin.rcQuitButton.right = 273;
Plugin.rcQuitButton.bottom = 12;
Plugin.hCurDlg = NULL;
// read in config
OnConfigRead(mod);
// do window thing
Plugin.Window.GetClassInfo()->lpfnWndProc = VisWndProc;
Plugin.Window.GetClassInfo()->style = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW;
Plugin.Window.GetClassInfo()->hInstance = mod->hDllInstance;
Plugin.Window.GetClassInfo()->hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
if(Plugin.Settings.bWinampCursor)
Plugin.Window.GetClassInfo()->hCursor = LoadCursor((HINSTANCE)GetWindowLong(mod->hwndParent,GWL_HINSTANCE),MAKEINTRESOURCE(IDR_MAINCURSOR));
else
Plugin.Window.GetClassInfo()->hCursor = LoadCursor(NULL,IDC_ARROW);
Plugin.Window.GetClassInfo()->lpszClassName = g_lpszClassName;
// register the window class
if(!Plugin.Window.DoRegisterClass()) {
MessageBox(mod->hwndParent,"Couldn't register window class for "PLUGIN_DESC" plugin.","Error - "PLUGIN_DESC,MB_ICONERROR);
return INIT_FAIL;
}
// create the window
if(!Plugin.Window.Create(PLUGIN_DESC,Plugin.Settings.ulLeft,Plugin.Settings.ulTop,Plugin.Settings.ulWidth,Plugin.Settings.ulHeight,WS_POPUP,WS_EX_TOOLWINDOW,mod->hwndParent)) {
MessageBox(mod->hwndParent,"Couldn't create window for "PLUGIN_DESC" plugin.","Error - "PLUGIN_DESC,MB_ICONERROR);
// unregister the class again
Plugin.Window.DoUnregisterClass();
return INIT_FAIL;
}
// chuck the address of the module in the user data
SetWindowLong(Plugin.Window.GetSafeHandle(),GWL_USERDATA,(long)mod);
// create the rest of the stuff
HDC hDC = GetDC(mod->hwndParent);
Plugin.hMemDC = CreateCompatibleDC(hDC);
Plugin.hBltDC = CreateCompatibleDC(hDC);
Plugin.hBmpSkin = LoadBitmap(mod->hDllInstance,MAKEINTRESOURCE(IDB_BMPSKIN));
Plugin.hMemBmp = MakeScreenCompatibleBitmap(Plugin.hBmpSkin, STD_WIDTH, STD_HEIGHT);
ReleaseDC(mod->hwndParent,hDC);
// select the new bitmap into the dc
Plugin.hOldBmp = (HBITMAP)SelectObject(Plugin.hMemDC,Plugin.hMemBmp);
// draw on the main window
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin,0,0,STD_WIDTH,STD_HEIGHT,0,0);
LPBITMAPINFO bmi = new BITMAPINFO;
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biBitCount = 24;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biHeight = Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biWidth = Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left;
Plugin.hBmpDIBSection = CreateDIBSection(Plugin.hMemDC,bmi,DIB_RGB_COLORS,&Plugin.lpDIBits,NULL,0);
delete bmi;
if(!Plugin.hBmpDIBSection) {
MessageBox(mod->hwndParent,"Couldn't create DIB Section for "PLUGIN_DESC" plugin.","Error - "PLUGIN_DESC,MB_ICONERROR);
SelectObject(Plugin.hMemDC,Plugin.hOldBmp);
DeleteObject(Plugin.hMemBmp);
DeleteDC(Plugin.hMemDC);
DeleteDC(Plugin.hBltDC);
Plugin.Window.Destroy();
UnregisterClass(g_lpszClassName,mod->hDllInstance);
return INIT_FAIL;
}
Plugin.hOldBltBmp = (HBITMAP)SelectObject(Plugin.hBltDC,Plugin.hBmpDIBSection);
for(int i=0;i<576;i++) {
g_achPeakData[0][i]=0;
g_achPeakData[1][i]=0;
g_achDisplayData[i]=0;
g_achScreenData[i]=0;
}
GetColourMap();
GetObject(Plugin.hBmpDIBSection,sizeof(BITMAP),&Plugin.Bit);
SetDoubleSize(Plugin.Window.GetSafeHandle(),(int)Plugin.Settings.bDoubleSize);
// subclass
WndProcOld = (void *) GetWindowLong(mod->hwndParent,GWL_WNDPROC);
SetWindowLong(mod->hwndParent,GWL_WNDPROC,(long)SubWndProc);
// load skin
LoadSkin();
// render for the first time
OnPluginRender(mod);
// show the window
Plugin.Window.Show();
Plugin.Window.Refresh();
return INIT_SUCCESS;
}
// Called when the plugin is about to be closed.
void OnPluginQuit(struct winampVisModule* mod)
{
// kill the effect thread if it exists
KillUpdateThread();
MessageBeep(MB_ICONEXCLAMATION);
// Restore all original data and delete objects etc.
SelectObject(Plugin.hMemDC,Plugin.hOldBmp);
SelectObject(Plugin.hBltDC,Plugin.hOldBltBmp);
DeleteObject(Plugin.hBmpSkin);
DeleteObject(Plugin.hMemBmp);
DeleteObject(Plugin.hBmpDIBSection);
DeleteDC(Plugin.hMemDC);
DeleteDC(Plugin.hBltDC);
Plugin.Window.Destroy();
Plugin.Window.DoUnregisterClass();
}
int OnPluginRender(struct winampVisModule* mod)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -