📄 vis_spectrum.cpp
字号:
LPBYTE lpByte = LPBYTE(Plugin.lpDIBits);
// draw the background grid (this also serves to "erase" what was on the
// bitmap before)
// ok there's probably a more efficient and better way of doing this.
for(int i=0;i<Plugin.Bit.bmWidth;i++) {
for(int j=0;j<Plugin.Bit.bmHeight;j++) {
if(((i-1)%Plugin.Settings.uchGridWidth <= (Plugin.Settings.uchGridWidth - (Plugin.Settings.uchGridHorzGap+1)))/*i%Plugin.Settings.uchGridWidth!=0*/ && j%(Plugin.Settings.uchGridVertGap+1)==0 && Plugin.Settings.bWantGrid && i!=0){
lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)] = unsigned char((g_ulGridColour >> 16) & 0xFF) /*0x42*/;
lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+1]= unsigned char((g_ulGridColour >> 8 ) & 0xFF)/*0x41*/;
lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+2]= unsigned char((g_ulGridColour >> 0 ) & 0xFF)/*0x00*/;
}
else {
lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)] = unsigned char((g_ulBackColour >> 16) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+1]= unsigned char((g_ulBackColour >> 8 ) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+i*3)+2]= unsigned char((g_ulBackColour >> 0 ) & 0xFF);
}
}
}
for(i=0;i<256 / Plugin.Settings.uchBarWidth;i++) {
// first test if we want to remap the input levels and
// do it accordingly.
if(Plugin.Settings.bRemap)
g_achDisplayData[i] = g_achLevelMap[mod->spectrumData[0][i]];
else
g_achDisplayData[i] = mod->spectrumData[0][i];
// If the new data is greater than the current data....
if(g_achDisplayData[i] > g_achScreenData[i]) {
if(Plugin.Settings.bFilter) {
// with level filter, this attempts to smooth
// the level of the bars and prevent jumping
int nIncrease = g_achDisplayData[i] - g_achScreenData[i];
if(nIncrease > 0) nIncrease /= 2;
if(nIncrease > Plugin.Settings.uchMaxIncrease) nIncrease = Plugin.Settings.uchMaxIncrease;
// Add the increase to the bar
if(g_achScreenData[i]+nIncrease<=255)
g_achScreenData[i]+=nIncrease;
else
g_achScreenData[i]=255;
}
else {
// no level filter so we just use the max and min rise/fall to
// control the actual speed of the bars.
int nIncrease = g_achDisplayData[i] - g_achScreenData[i];
if(nIncrease < Plugin.Settings.uchMaxIncrease)
g_achScreenData[i] +=nIncrease;//g_achDisplayData[i];
else {
if(g_achScreenData[i] + Plugin.Settings.uchMaxIncrease <= 255)
g_achScreenData[i] += Plugin.Settings.uchMaxIncrease;
else
g_achScreenData[i] = 255;
}
}
// put the peak at the top of the bar if it is higher than
// the peak currently is.
if(g_achPeakData[0][i]<g_achScreenData[i]) {
g_achPeakData[0][i] = g_achScreenData[i];
// 1 in this case is used for the delay which
// is why it is measured in frames.
g_achPeakData[1][i] = Plugin.Settings.uchPeakDelay;
}
}
else {
// the value is less
if(Plugin.Settings.bFilter) {
// with the filter
int nDecrease = g_achScreenData[i] - g_achDisplayData[i];
if(nDecrease>0) nDecrease/=16;
// set to max decrease
if (nDecrease > Plugin.Settings.uchMaxDecrease) nDecrease = Plugin.Settings.uchMaxDecrease;
// because of division above, the level will never go below 16.
// this means if the level is 16 or less, we manually set the
// decrease (tacky i know but it works :)
// and we now have magic numbers
if(g_achScreenData[i]<=16) {
nDecrease = Plugin.Settings.uchDefaultDrop;
}
if(g_achScreenData[i] - nDecrease >= 0) {
g_achScreenData[i] -=nDecrease;
}
else {
g_achScreenData[i] = 0;
}
}
else {
// without filter
int nDecrease = g_achScreenData[i] - g_achDisplayData[i];
if(nDecrease < Plugin.Settings.uchMaxDecrease)
g_achScreenData[i] -= nDecrease;
else {
if(g_achScreenData[i] - Plugin.Settings.uchMaxDecrease >= 0)
g_achScreenData[i] -= Plugin.Settings.uchMaxDecrease;
else
g_achScreenData[i] = 0;
}
}
}
if(g_achPeakData[1][i]==0) {
if(g_achPeakData[0][i]-Plugin.Settings.uchPeakDrop>=0) {
if(g_achPeakData[0][i]-Plugin.Settings.uchPeakDrop>=g_achScreenData[i])
g_achPeakData[0][i]-=Plugin.Settings.uchPeakDrop;
else
g_achPeakData[0][i] = g_achScreenData[i];
}
else {
g_achPeakData[0][i]=0;
}
}
else {
g_achPeakData[1][i]--;
}
}
// draw the bars then the peaks
for(i=0;i<(256 / Plugin.Settings.uchBarWidth );i++) {
if(Plugin.Settings.bWantBars) {
int nTo = g_achScreenData[i]/3;
for(int j=nTo-1;j>=0;j--) {
for(int k=0;k<Plugin.Settings.uchBarWidth - (Plugin.Settings.uchBarHorzGap);k++) {
if(j%(Plugin.Settings.uchBarVertGap+1)==0) {
switch(Plugin.Settings.uchBarStyle) {
default:
case 0:
// Normal Style
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulColourMap[255-(j*3)] >> 16) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1] = unsigned char((g_ulColourMap[255-(j*3)] >> 8) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulColourMap[255-(j*3)] >> 0) & 0xFF);
break;
case 1:
// Fire Style
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulColourMap[(nTo-j)*3]>>16) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1] = unsigned char((g_ulColourMap[(nTo-j)*3]>>8) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulColourMap[(nTo-j)*3]>>0) & 0xFF);
break;
case 2:
// Line Style
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulColourMap[255-(nTo*3)]>>16) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1] = unsigned char((g_ulColourMap[255-(nTo*3)]>>8) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes*j)+(((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulColourMap[255-(nTo*3)]>>0) & 0xFF);
break;
}
}
}
}
}
// draw the peaks
if(Plugin.Settings.bWantPeaks) {
int nPeak = g_achPeakData[0][i]/3;
for(int k=0;k<Plugin.Settings.uchBarWidth - (Plugin.Settings.uchBarHorzGap);k++) {
lpByte[((Plugin.Bit.bmWidthBytes * nPeak ) + (((i*Plugin.Settings.uchBarWidth)+k)+1)*3)] = unsigned char((g_ulPeakColour >> 16) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes * nPeak ) + (((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+1]= unsigned char((g_ulPeakColour >> 8) & 0xFF);
lpByte[((Plugin.Bit.bmWidthBytes * nPeak ) + (((i*Plugin.Settings.uchBarWidth)+k)+1)*3)+2] = unsigned char((g_ulPeakColour >> 0) & 0xFF);
}
}
}
// update the dc, i do it like this to make double size
// easier to cope with.
BitBlt(Plugin.hMemDC,Plugin.rcDrawingRect.left, Plugin.rcDrawingRect.top, Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left, Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top, Plugin.hBltDC,0,0,SRCCOPY);
HDC hDC = GetDC(Plugin.hWndMain);
if(!Plugin.Settings.bDoubleSize) {
BitBlt(hDC,Plugin.rcDrawingRect.left,Plugin.rcDrawingRect.top,Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left,
Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top ,Plugin.hMemDC,Plugin.rcDrawingRect.left,Plugin.rcDrawingRect.top,SRCCOPY);
}
else {
StretchBlt(
hDC,
(Plugin.rcDrawingRect.left*2),(Plugin.rcDrawingRect.top*2),
((Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left)*2),
((Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top)*2),
Plugin.hMemDC,Plugin.rcDrawingRect.left,Plugin.rcDrawingRect.top,
(Plugin.rcDrawingRect.right - Plugin.rcDrawingRect.left),
(Plugin.rcDrawingRect.bottom - Plugin.rcDrawingRect.top),SRCCOPY
);
}
ReleaseDC(Plugin.hWndMain,hDC);
return 0;
}
// the main window procedure.
LRESULT CALLBACK VisWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_CREATE:
Plugin.bMouseDown = false;
Plugin.hWndMain = hWnd;
SetWindowLong(hWnd,GWL_STYLE,GetWindowLong(hWnd,GWL_STYLE)&~(WS_CAPTION));
break;
case WM_ACTIVATE:
if(Plugin.Settings.bDimTitleBar) {
switch(LOWORD(wParam)) {
case WA_ACTIVE:
case WA_CLICKACTIVE:{
// set window active flag and draw active title bar
//BitmapBlt(Plugin.hMemDC,Plugin.hBmpTitleActive,0,0);
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, 0, 0, 275, 14, 0, 116);
Plugin.bWindowActive = true;
UpdateRect(&Plugin.rcTitleBar,hWnd);
break;
}
case WA_INACTIVE:
// set window active flag to false and draw the inactive
// title bar
Plugin.bWindowActive = false;
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, 0, 0, 275, 14, 0, 130);
UpdateRect(&Plugin.rcTitleBar,hWnd);
break;
}
}
break;
case WM_USER:
{
// user functions
switch(lParam) {
case USR_REDRAWWINDOW:
{
RECT rRect;
GetWindowRect(hWnd,&rRect);
HDC hDC = GetDC(hWnd);
BitBlt(hDC,0,0,rRect.right-rRect.left,rRect.bottom-rRect.top,Plugin.hMemDC,0,0,SRCCOPY);
ReleaseDC(hWnd,hDC);
break;
}
case USR_HIDE:
ShowWindow(hWnd,SW_HIDE);
break;
case USR_SHOW:
ShowWindow(hWnd,SW_SHOW);
break;
case USR_DOUBLESIZE:
{
switch(wParam) {
case 0:
// doublesize off
Plugin.Settings.bDoubleSize = false;
Plugin.Window.SetWindowPos(NULL,0,0,STD_WIDTH,STD_HEIGHT,SWP_NOMOVE|SWP_NOZORDER);
break;
default:
// doublesize on
Plugin.Window.SetWindowPos(NULL,0,0,STD_WIDTH*2,STD_HEIGHT*2,SWP_NOMOVE|SWP_NOZORDER);
Plugin.Settings.bDoubleSize = true;
break;
}
break;
}
case USR_CLOSETHREAD:
KillUpdateThread();
break;
default:
break;
}
break;
}
case WM_LBUTTONDOWN:
{
// get and set up the point structure
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
// start testing the coordinates, have to test the close
// button before the title rect as it is inside it.
if(PointInRect(&Plugin.rcQuitButton,pt)) {
// if the mouse is on it make it look active
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 9, 144);
// and update the area to the screen
UpdateRect(&Plugin.rcQuitButton,hWnd);
SetCapture(hWnd);
Plugin.bMouseDown = true;
}
else if(PointInRect(&Plugin.rcTitleBar,pt)) {
// this fools the thing into believing that we
// are actually clicking on the caption, and the
// effect of this is that you get automatic window
// moving which is smooth. It also enables the window
// to have just the frame dragged when show window
// contents is off.
PostMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,(LPARAM)&pt);
}
else {
// set mouse down to true
Plugin.bMouseDown = true;
// and capture the mouse
SetCapture(hWnd);
}
break;
}
case WM_LBUTTONUP:
{
ReleaseCapture();
// set mouse down flag to false
Plugin.bMouseDown = false;
// get x,y coords
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
// if over exit button, close
if(PointInRect(&Plugin.rcQuitButton,pt)) SendMessage(hWnd,WM_CLOSE,0,0);
// draw the quit button up or it may get stuck
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 0, 144);
UpdateRect(&Plugin.rcQuitButton,hWnd);
break;
}
case WM_RBUTTONUP:
{
// if the mouse is in the drawing area, pop up our own menu,
// otherwise, popup the winamp menu
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
// check that the mouse is in the rectangle of the drawing
// area
if(PointInRect(&Plugin.rcDrawingRect,pt)) {
// show the popupmenu
HMENU hMenu = LoadMenu((HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),MAKEINTRESOURCE(IDR_MAINMENU));
HMENU hSub = GetSubMenu(hMenu,0);
if(g_bAboutActive) EnableMenuItem(hSub,0,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);
GetCursorPos(&pt);
TrackPopupMenu(hSub,0,pt.x,pt.y,0,hWnd,NULL);
DestroyMenu(hMenu);
}
else {
// ask winamp to display its own menu
PostMessage(Plugin.hWndParent,uMsg,wParam,lParam);
}
break;
}
case WM_MOUSEMOVE:
{
if(Plugin.bMouseDown) {
if(Plugin.bWindowActive) {
POINT pts;
pts.x = GET_X_LPARAM(lParam);
pts.y = GET_Y_LPARAM(lParam);
// handle the quit button
if(PointInRect(&Plugin.rcQuitButton,pts)) {
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 9, 144);
UpdateRect(&Plugin.rcQuitButton,hWnd);
}
else {
BitmapBltEx(Plugin.hMemDC, Plugin.hBmpSkin, Plugin.rcQuitButton.left, Plugin.rcQuitButton.top, 9, 9, 0, 144);
UpdateRect(&Plugin.rcQuitButton,hWnd);
}
}
}
break;
}
case WM_WINDOWPOSCHANGING:
{
if(Plugin.Settings.bSnapWindow) {
LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam;
// brand new docking code that works properly (yay)
winamp_dock(hWnd,&lpWndPos->x,&lpWndPos->y,Plugin.Settings.ulWindowSnap);
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -