123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- /*
- LICENSE
- -------
- Copyright 2005 Nullsoft, Inc.
- All rights reserved.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of Nullsoft nor the names of its contributors may be used to
- endorse or promote products derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <windows.h>
- #include <math.h>
- #include <process.h>
- #include "draw.h"
- #include "wnd.h"
- #include "r_defs.h"
- #include "render.h"
- #include "vis.h"
- #include "cfgwnd.h"
- #include "resource.h"
- #include "bpm.h"
- #include "api.h"
- #include "../winamp/wa_ipc.h"
- #include "../Agave/Language/api_language.h"
- #include <api/service/waServiceFactory.h>
- #include <stdio.h>
- #ifdef REAPLAY_PLUGIN
- #include "../../jmde/reaper_plugin.h"
- const char *(*get_ini_file)();
- int (*vuGetVisData)(char *vdata, int size);
- #endif
- #define PLUGIN_VERSION "v2.93"
- #include "avs_eelif.h"
- extern void GetClientRect_adj(HWND hwnd, RECT *r);
- static unsigned char g_logtab[256];
- HINSTANCE g_hInstance;
- /* char *verstr=
- #ifndef LASER
- "Advanced Visualization Studio"
- #else
- "AVS/Laser"
- #endif
- " v2.92"
- ;
- */
- static unsigned int WINAPI RenderThread(LPVOID a);
- static void config(struct winampVisModule *this_mod);
- static int init(struct winampVisModule *this_mod);
- static int render(struct winampVisModule *this_mod);
- static void quit(struct winampVisModule *this_mod);
- HANDLE g_hThread;
- volatile int g_ThreadQuit;
- static CRITICAL_SECTION g_cs;
- static unsigned char g_visdata[2][2][576];
- static int g_visdata_pstat;
- /* wasabi based services for localisation support */
- api_service *WASABI_API_SVC = 0;
- api_language *WASABI_API_LNG = 0;
- HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
- static char module1[128];
- static winampVisModule *getModule(int which);
- static winampVisHeader hdr = { VIS_HDRVER, 0, getModule };
- // use this to get our own HINSTACE since overriding DllMain(..) causes instant crashes (should see why)
- static HINSTANCE GetMyInstance()
- {
- MEMORY_BASIC_INFORMATION mbi = {0};
- if(VirtualQuery(GetMyInstance, &mbi, sizeof(mbi)))
- return (HINSTANCE)mbi.AllocationBase;
- return NULL;
- }
- extern "C" {
- __declspec( dllexport ) winampVisHeader* winampVisGetHeader(HWND hwndParent)
- {
- if(!WASABI_API_LNG_HINST)
- {
- // loader so that we can get the localisation service api for use
- WASABI_API_SVC = (api_service*)SendMessage(hwndParent, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
- if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
- waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
- if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
- // need to have this initialised before we try to do anything with localisation features
- WASABI_API_START_LANG(GetMyInstance(),VisAVSLangGUID);
- }
- #ifndef LASER
- static char szDescription[256];
- wsprintfA(szDescription,"%s " PLUGIN_VERSION,WASABI_API_LNGSTRING_BUF(IDS_AVS,module1,128));
- hdr.description = szDescription;
- #else
- hdr.description = "AVS/Laser "PLUGIN_VERSION;
- #endif
- return &hdr;
- }
- }
- static winampVisModule *getModule(int which)
- {
- static winampVisModule mod =
- {
- #ifdef LASER
- "Advanced Visualization Studio/Laser",
- #else
- module1,
- #endif
- NULL, // hwndParent
- NULL, // hDllInstance
- 0, // sRate
- 0, // nCh
- 1000/70, // latencyMS
- 1000/70,// delayMS
- 2, // spectrumNch
- 2, // waveformNch
- { 0, }, // spectrumData
- { 0, }, // waveformData
- config,
- init,
- render,
- quit
- };
- if (which==0) return &mod;
- return 0;
- }
- void about(HWND hwndParent)
- {
- static int about_here = 0;
- char aboutbuf[1024] = {0}, aboutTitle[48] = {0};
- if (about_here)
- {
- SetActiveWindow(FindWindow("#32770",WASABI_API_LNGSTRING_BUF(IDS_ABOUT_AVS,aboutTitle,48)));
- return;
- }
- about_here = 1;
- wsprintf(aboutbuf,WASABI_API_LNGSTRING(IDS_ABOUT_STRING),hdr.description);
- MessageBox(hwndParent,aboutbuf,WASABI_API_LNGSTRING_BUF(IDS_ABOUT_AVS,aboutTitle,48),0);
- about_here = 0;
- }
- HWND GetDialogBoxParent(HWND winamp)
- {
- HWND parent = (HWND)SendMessage(winamp, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
- if (!parent || parent == (HWND)1)
- return winamp;
- return parent;
- /*
- BOOL CALLBACK aboutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_INITDIALOG:
- SetDlgItemText(hwndDlg,IDC_VERSTR,verstr);
-
- return 1;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK: case IDCANCEL:
- EndDialog(hwndDlg,0);
- return 0;
- }
- return 0;
- }
- return 0;
- */
- }
- static void config(struct winampVisModule *this_mod)
- {
- if (!g_hwnd || !IsWindow(g_hwnd))
- {
- about(GetDialogBoxParent(this_mod->hwndParent));
- // DialogBox(this_mod->hDllInstance,MAKEINTRESOURCE(IDD_DIALOG2),this_mod->hwndParent,aboutProc);
- }
- else
- {
- SendMessage(g_hwnd,WM_USER+33,0,0);
- }
- }
- CRITICAL_SECTION g_render_cs;
- static int g_is_beat;
- char g_path[1024];
- int beat_peak1,beat_peak2, beat_cnt,beat_peak1_peak;
- void main_setRenderThreadPriority()
- {
- int prios[]={
- GetThreadPriority(GetCurrentThread()),
- THREAD_PRIORITY_IDLE,
- THREAD_PRIORITY_LOWEST,
- THREAD_PRIORITY_NORMAL,
- THREAD_PRIORITY_HIGHEST,
- };
- SetThreadPriority(g_hThread,prios[cfg_render_prio]);
- }
- extern void previous_preset(HWND hwnd);
- extern void next_preset(HWND hwnd);
- extern void random_preset(HWND hwnd);
- #if 0//syntax highlighting
- HINSTANCE hRich;
- #endif
- static int init(struct winampVisModule *this_mod)
- {
- DWORD id;
- FILETIME ft;
- #if 0//syntax highlighting
- if (!hRich) hRich=LoadLibrary("RICHED32.dll");
- #endif
- GetSystemTimeAsFileTime(&ft);
- srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
- g_hInstance=this_mod->hDllInstance;
- GetModuleFileName(g_hInstance,g_path,MAX_PATH);
- char *p=g_path+strlen(g_path);
- while (p > g_path && *p != '\\') p--;
- *p = 0;
- #ifdef WA2_EMBED
- if (SendMessage(this_mod->hwndParent,WM_USER,0,0) < 0x2900)
- {
- char title[16];
- MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_REQUIRES_2_9_PLUS),
- WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,16),MB_OK|MB_ICONSTOP);
- return 1;
- }
- #endif
- #ifndef NO_MMX
- extern int is_mmx(void);
- if (!is_mmx())
- {
- char title[16];
- MessageBox(this_mod->hwndParent,WASABI_API_LNGSTRING(IDS_NO_MMX_SUPPORT),
- WASABI_API_LNGSTRING_BUF(IDS_AVS_ERROR,title,16),MB_OK|MB_ICONSTOP);
- return 1;
- }
- #endif
- #ifdef LASER
- strcat(g_path,"\\avs_laser");
- #else
- strcat(g_path,"\\avs");
- #endif
- CreateDirectory(g_path,NULL);
- InitializeCriticalSection(&g_cs);
- InitializeCriticalSection(&g_render_cs);
- g_ThreadQuit=0;
- g_visdata_pstat=1;
- AVS_EEL_IF_init();
- if (Wnd_Init(this_mod)) return 1;
- {
- int x;
- for (x = 0; x < 256; x ++)
- {
- double a=log((double)x*60.0/255.0 + 1.0)/log(60.0);
- int t=(int)(a*255.0);
- if (t<0)t=0;
- if (t>255)t=255;
- g_logtab[x]=(unsigned char )t;
- }
- }
- initBpm();
- Render_Init(g_hInstance);
- CfgWnd_Create(this_mod);
- g_hThread=(HANDLE)_beginthreadex(NULL,0,RenderThread,0,0,(unsigned int *)&id);
- main_setRenderThreadPriority();
- SetForegroundWindow(g_hwnd);
- SetFocus(g_hwnd);
- return 0;
- }
- static int render(struct winampVisModule *this_mod)
- {
- int x,avs_beat=0,b;
- if (g_ThreadQuit) return 1;
- EnterCriticalSection(&g_cs);
- if (g_ThreadQuit)
- {
- LeaveCriticalSection(&g_cs);
- return 1;
- }
- if (g_visdata_pstat)
- for (x = 0; x< 576*2; x ++)
- g_visdata[0][0][x]=g_logtab[(unsigned char)this_mod->spectrumData[0][x]];
- else
- {
- for (x = 0; x < 576*2; x ++)
- {
- int t=g_logtab[(unsigned char)this_mod->spectrumData[0][x]];
- if (g_visdata[0][0][x] < t)
- g_visdata[0][0][x] = t;
- }
- }
- memcpy(&g_visdata[1][0][0],this_mod->waveformData,576*2);
- {
- int lt[2]={0,0};
- int x;
- int ch;
- for (ch = 0; ch < 2; ch ++)
- {
- unsigned char *f=(unsigned char*)&this_mod->waveformData[ch][0];
- for (x = 0; x < 576; x ++)
- {
- int r= *f++^128;
- r-=128;
- if (r<0)r=-r;
- lt[ch]+=r;
- }
- }
- lt[0]=max(lt[0],lt[1]);
- beat_peak1=(beat_peak1*125+beat_peak2*3)/128;
- beat_cnt++;
- if (lt[0] >= (beat_peak1*34)/32 && lt[0] > (576*16))
- {
- if (beat_cnt>0)
- {
- beat_cnt=0;
- avs_beat=1;
- }
- beat_peak1=(lt[0]+beat_peak1_peak)/2;
- beat_peak1_peak=lt[0];
- }
- else if (lt[0] > beat_peak2)
- {
- beat_peak2=lt[0];
- }
- else beat_peak2=(beat_peak2*14)/16;
- }
- b=refineBeat(avs_beat);
- if (b) g_is_beat=1;
- g_visdata_pstat=0;
- LeaveCriticalSection(&g_cs);
- return 0;
- }
- static void quit(struct winampVisModule *this_mod)
- {
- #define DS(x)
- //MessageBox(this_mod->hwndParent,x,"AVS Debug",MB_OK)
- if (g_hThread)
- {
- DS("Waitin for thread to quit\n");
- g_ThreadQuit=1;
- if (WaitForSingleObject(g_hThread,10000) != WAIT_OBJECT_0)
- {
- DS("Terminated thread (BAD!)\n");
- //MessageBox(NULL,"error waiting for thread to quit","a",MB_TASKMODAL);
- TerminateThread(g_hThread,0);
- }
- DS("Thread done... calling ddraw_quit\n");
- DDraw_Quit();
- DS("Calling cfgwnd_destroy\n");
- CfgWnd_Destroy();
- DS("Calling render_quit\n");
- Render_Quit(this_mod->hDllInstance);
- DS("Calling wnd_quit\n");
- Wnd_Quit();
- DS("closing thread handle\n");
- CloseHandle(g_hThread);
- g_hThread=NULL;
- DS("calling eel quit\n");
- AVS_EEL_IF_quit();
- DS("cleaning up critsections\n");
- DeleteCriticalSection(&g_cs);
- DeleteCriticalSection(&g_render_cs);
- DS("smp_cleanupthreads\n");
- C_RenderListClass::smp_cleanupthreads();
- }
- #undef DS
- #if 0//syntax highlighting
- if (hRich) FreeLibrary(hRich);
- hRich=0;
- #endif
- }
- #define FPS_NF 64
- static unsigned int WINAPI RenderThread(LPVOID a)
- {
- int framedata[FPS_NF]={0,};
- int framedata_pos=0;
- int s=0;
- char vis_data[2][2][576];
- FILETIME ft;
- GetSystemTimeAsFileTime(&ft);
- srand(ft.dwLowDateTime|ft.dwHighDateTime^GetCurrentThreadId());
- while (!g_ThreadQuit)
- {
- int w,h,*fb=NULL, *fb2=NULL,beat=0;
- #ifdef REAPLAY_PLUGIN
- if(!IsWindowVisible(g_hwnd))
- {
- Sleep(1);
- continue;
- }
- char visdata[576*2*2];
- int ret = vuGetVisData(visdata, sizeof(visdata));
- if (!ret)
- {
- memset(&vis_data[0][0][0],0,576*2*2);
- beat=0;
- }
- else
- {
- int x;
- unsigned char *v=(unsigned char *)visdata;
- for (x = 0; x < 576*2; x ++)
- vis_data[0][0][x]=g_logtab[*v++];
- for (x = 0; x < 576*2; x ++)
- ((unsigned char *)vis_data[1][0])[x]=*v++;
- v=(unsigned char *)visdata+1152;
- {
- int lt[2]={0,0};
- int ch;
- for (ch = 0; ch < 2; ch ++)
- {
- for (x = 0; x < 576; x ++)
- {
- int r=*v++^128;
- r-=128;
- if (r<0)r=-r;
- lt[ch]+=r;
- }
- }
- lt[0]=max(lt[0],lt[1]);
- beat_peak1=(beat_peak1*125+beat_peak2*3)/128;
- beat_cnt++;
- if (lt[0] >= (beat_peak1*34)/32 && lt[0] > (576*16))
- {
- if (beat_cnt>0)
- {
- beat_cnt=0;
- beat=1;
- }
- beat_peak1=(lt[0]+beat_peak1_peak)/2;
- beat_peak1_peak=lt[0];
- }
- else if (lt[0] > beat_peak2)
- {
- beat_peak2=lt[0];
- }
- else beat_peak2=(beat_peak2*14)/16;
- }
- // EnterCriticalSection(&g_title_cs);
- beat=refineBeat(beat);
- // LeaveCriticalSection(&g_title_cs);
- }
- #else
- EnterCriticalSection(&g_cs);
- memcpy(&vis_data[0][0][0],&g_visdata[0][0][0],576*2*2);
- g_visdata_pstat=1;
- beat=g_is_beat;
- g_is_beat=0;
- LeaveCriticalSection(&g_cs);
- #endif
- if (!g_ThreadQuit)
- {
- if (IsWindow(g_hwnd)&&!g_in_destroy) DDraw_Enter(&w,&h,&fb,&fb2);
- else break;
- if (fb&&fb2)
- {
- extern int g_dlg_w, g_dlg_h, g_dlg_fps;
- #ifdef LASER
- g_laser_linelist->ClearLineList();
- #endif
- EnterCriticalSection(&g_render_cs);
- int t=g_render_transition->render(vis_data,beat,s?fb2:fb,s?fb:fb2,w,h);
- LeaveCriticalSection(&g_render_cs);
- if (t&1) s^=1;
- #ifdef LASER
- s=0;
- memset(fb,0,w*h*sizeof(int));
- LineDrawList(g_laser_linelist,fb,w,h);
- #endif
- if (IsWindow(g_hwnd)) DDraw_Exit(s);
- int lastt=framedata[framedata_pos];
- int thist=GetTickCount();
- framedata[framedata_pos]=thist;
- g_dlg_w=w;
- g_dlg_h=h;
- if (lastt)
- {
- g_dlg_fps=MulDiv(sizeof(framedata)/sizeof(framedata[0]),10000,thist-lastt);
- }
- framedata_pos++;
- if (framedata_pos >= sizeof(framedata)/sizeof(framedata[0])) framedata_pos=0;
- }
- int fs=DDraw_IsFullScreen();
- int sv=(fs?(cfg_speed>>8):cfg_speed)&0xff;
- Sleep(min(max(sv,1),100));
- }
- }
- _endthreadex(0);
- return 0;
- }
- #ifdef REAPLAY_PLUGIN
- static winampVisModule dummyMod;
- extern "C"
- {
-
- REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(REAPER_PLUGIN_HINSTANCE hInstance, reaper_plugin_info_t *rec)
- {
- g_hInstance=hInstance;
- if (rec)
- {
- if (rec->caller_version != REAPER_PLUGIN_VERSION || !rec->GetFunc)
- return 0;
- *((void **)&get_ini_file) = rec->GetFunc("get_ini_file");
- *((void **)&vuGetVisData) = rec->GetFunc("vuGetVisData");
- if (!get_ini_file || !vuGetVisData)
- return 0;
- dummyMod.hwndParent=rec->hwnd_main;
- dummyMod.hDllInstance=g_hInstance;
- init(&dummyMod);
- return 1;
- }
- else
- {
- quit(&dummyMod);
- return 0;
- }
- }
-
- };
- #endif
|