123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- /*
- 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 <commctrl.h>
- #include "r_defs.h"
- #include "resource.h"
- #include "../Agave/Language/api_language.h"
- #if 0//syntax highlighting
- #include "compiler.h"
- #include "richedit.h"
- #endif
- char* GetTextResource(UINT id){
- void* data = 0;
- HRSRC rsrc = FindResource(WASABI_API_LNG_HINST,MAKEINTRESOURCE(id),"TEXT");
- if(rsrc){
- HGLOBAL resourceHandle = LoadResource(WASABI_API_LNG_HINST,rsrc);
- data = LockResource(resourceHandle);
- }
- return (char*)data;
- }
- void loadComboBox(HWND dlg, char *ext, char *selectedName)
- {
- char path[MAX_PATH];
- int a;
- HANDLE ff;
- WIN32_FIND_DATA fd;
- wsprintf(path,"%s\\%s",g_path,ext);
- ff=FindFirstFile(path, &fd);
- if (ff == INVALID_HANDLE_VALUE) return;
- do
- {
- SendMessage(dlg, CB_ADDSTRING, 0, (LPARAM)(fd.cFileName));
- } while (FindNextFile(ff, &fd));
- FindClose(ff);
- a = SendMessage(dlg, CB_FINDSTRINGEXACT, 0, (LPARAM)(selectedName));
- if (a != CB_ERR) SendMessage(dlg, CB_SETCURSEL, (WPARAM) a, 0);
- }
- void GR_SelectColor(HWND hwnd, int *a)
- {
- static COLORREF custcolors[16];
- CHOOSECOLOR cs;
- cs.lStructSize = sizeof(cs);
- cs.hwndOwner = hwnd;
- cs.hInstance = 0;
- cs.rgbResult=((*a>>16)&0xff)|(*a&0xff00)|((*a<<16)&0xff0000);
- cs.lpCustColors = custcolors;
- cs.Flags = CC_RGBINIT|CC_FULLOPEN;
- if (ChooseColor(&cs))
- {
- *a = ((cs.rgbResult>>16)&0xff)|(cs.rgbResult&0xff00)|((cs.rgbResult<<16)&0xff0000);
- }
- }
- void GR_DrawColoredButton(DRAWITEMSTRUCT *di, COLORREF color)
- {
- color = ((color>>16)&0xff)|(color&0xff00)|((color<<16)&0xff0000);
- char wt[123];
- HPEN hPen,hOldPen;
- HBRUSH hBrush,hOldBrush;
- hPen = (HPEN)GetStockObject(BLACK_PEN);
- LOGBRUSH lb={BS_SOLID,color,0};
- hBrush = CreateBrushIndirect(&lb);
- hOldPen=(HPEN)SelectObject(di->hDC,hPen);
- hOldBrush=(HBRUSH)SelectObject(di->hDC,hBrush);
- Rectangle(di->hDC,di->rcItem.left,di->rcItem.top,di->rcItem.right,di->rcItem.bottom);
- GetWindowText(di->hwndItem,wt,sizeof(wt));
- SetBkColor(di->hDC,color);
- SetTextColor(di->hDC,~color & 0xffffff);
- DrawText(di->hDC,wt,-1,&di->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
-
- DeleteObject(hBrush);
- SelectObject(di->hDC,hOldPen);
- SelectObject(di->hDC,hOldBrush);
- }
- static int m_help_lastpage=4;
- static char *m_localtext;
- static void _dosetsel(HWND hwndDlg)
- {
- HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
- int sel=TabCtrl_GetCurSel(tabwnd);
- char *text="";
- m_help_lastpage=sel;
- if (sel == 0)
- /*
- text="Many AVS effects allow you to write simple expressions to control\r\n"
- "visualization. Here is a brief summary of how to write AVS code.\r\n"
- "\r\n"
- "Many aspects of AVS code are similar to C (including comments). "
- "\r\n"
- "You can create new variables just by using them, and you can read\r\n"
- "and write predefined variables (of which each effect has its own)\r\n"
- "to interact with the effect. Note that variables are all floating\r\n"
- "point numbers (no strings), and the maximum length of a variable's\r\n"
- "name is 8 characters (anything longer will be ignored.\r\n"
- "\r\n"
- "So, to create a variable, you can simply use it, for example:\r\n"
- " x = 5;\r\n"
- "\r\n"
- "You can also use a variety of operators and math functions to\r\n"
- "modify variables, see the Operators and Functions tabs above.\r\n"
- "\r\n"
- "Code can include C and C++ style comments:\r\n"
- "\r\n"
- "You can combine operators and functions into expressions, such\r\n"
- "as:\r\n"
- " x = 5 * cos(y) / 32.0; // this does some leetness right here\r\n"
- "\r\n"
- "You can use multiple expressions by seperating them with one or\r\n"
- "more semicolons, for example:\r\n"
- " x = x * 17.0; x = x / 5; y = pow(x,3.0);\r\n"
- "\r\n"
- "It is worth noting that extra whitespace (spaces, newlines) is\r\n"
- "ignored, so if you need to space things out for clarity, you can.\r\n"
- ;
- else if (sel == 1)
- text="The following operators are available:\r\n"
- "=\r\n"
- " assigns a value to a variable. \r\n"
- " example: var=5;\r\n"
- "\r\n"
- "+\r\n"
- " adds two values, returns the sum. \r\n"
- " example: var=5+var2;\r\n"
- "\r\n"
- "-\r\n"
- " subtracts two values, returns the difference. \r\n"
- " example: var=5-var2;\r\n"
- "\r\n"
- "*\r\n"
- " multiplies two values, returns the product. \r\n"
- " example: var=5*var2;\r\n"
- "\r\n"
- "/\r\n"
- " divides two values, returns the quotient. \r\n"
- " example: var=5/var2;\r\n"
- "\r\n"
- "%\r\n"
- " converts two values to integer, performs division, returns remainder\r\n"
- " example: var=var2%5;\r\n"
- "\r\n"
- "|\r\n"
- " converts two values to integer, returns bitwise OR of both values\r\n"
- " example: var=var2|31;\r\n"
- "\r\n"
- "&\r\n"
- " converts two values to integer, returns bitwise AND of both values\r\n"
- " example: var=var2&31;\r\n"
- "\r\n"
- ;
- else if (sel == 2)
- text="Functions available from code:\r\n"
- "abs(value)\r\n"
- " = returns the absolute value of 'value'\r\n"
- "\r\n"
- "sin(value)\r\n"
- " = returns the sine of the radian angle 'value'\r\n"
- "\r\n"
- "cos(value)\r\n"
- " = returns the cosine of the radian angle 'value'\r\n"
- "\r\n"
- "tan(value)\r\n"
- " = returns the tangent of the radian angle 'value'\r\n"
- "\r\n"
- "asin(value)\r\n"
- " = returns the arcsine (in radians) of 'value'\r\n"
- "\r\n"
- "acos(value)\r\n"
- " = returns the arccosine (in radians) of 'value'\r\n"
- "\r\n"
- "atan(value)\r\n"
- " = returns the arctangent (in radians) of 'value'\r\n"
- "\r\n"
- "atan2(value,value2)\r\n"
- " = returns the arctangent (in radians) of 'value'/'value2'\r\n"
- "\r\n"
- "sqr(value)\r\n"
- " = returns the square of 'value'\r\n"
- "\r\n"
- "sqrt(value)\r\n"
- " = returns the square root of 'value'\r\n"
- "\r\n"
- "invsqrt(value)\r\n"
- " = returns the reciprocal of the square root of 'value' (1/sqrt(value))\r\n"
- " (uses a fast approximation, may not always = 1/sqrt(value) :)\r\n"
- "\r\n"
- "pow(value,value2)\r\n"
- " = returns 'value' to the power of 'value2'\r\n"
- "\r\n"
- "exp(value)\r\n"
- " = returns e to the power of 'value'\r\n"
- "\r\n"
- "log(value)\r\n"
- " = returns the log in base e of 'value'\r\n"
- "\r\n"
- "log10(value)\r\n"
- " = returns the log in base 10 of 'value'\r\n"
- "\r\n"
- "floor(value)\r\n"
- " = returns the largest integer less than or equal to 'value'\r\n"
- "\r\n"
- "ceil(value)\r\n"
- " = returns the smallest integer greater than or equal to 'value'\r\n"
- "\r\n"
- "sign(value)\r\n"
- " = returns the sign of 'value' (-1.0 or 1.0, or 0.0 or -0.0 for 0.0 or -0.0)\r\n"
- "\r\n"
- "min(value,value2)\r\n"
- " = returns the smallest of 'value' and 'value2'\r\n"
- "\r\n"
- "max(var,var2)\r\n"
- " = returns the greatest of 'value' and 'value2'\r\n"
- "\r\n"
- "sigmoid(value,value2)\r\n"
- " = returns sigmoid function value of x='value' ('value2'=constraint)\r\n"
- "\r\n"
- "rand(value)\r\n"
- " = returns a random integer between 0 and 'value'\r\n"
- "\r\n"
- "band(value,value2)\r\n"
- " = returns a boolean AND of 'value' and 'value2'\r\n"
- "\r\n"
- "bor(value,value2)\r\n"
- " = returns a boolean OR of 'value' and 'value2'\r\n"
- "\r\n"
- "bnot(value)\r\n"
- " = returns a boolean NOT of 'value'\r\n"
- "\r\n"
- "if(condition,valtrue,valfalse)\r\n"
- " = returns 'valtrue' if 'condition' is nonzero, returns 'valfalse' otherwise.\r\n"
- " new in AVS 2.8+: only one of valtrue/valfalse is evaluated, depending on condition\r\n"
- "\r\n"
- "assign(dest, source)\r\n"
- " = if 'dest' is a variable, assigns the value of 'source' to it. returns the value of 'source'.\r\n"
- " a little trick: assign(if(v,a,b),1.0); is like if V is true, a=1.0, otherwise b=1.0. :)\r\n"
- "\r\n"
- "exec2(parm1, parm2)\r\n"
- " = evaluates parm1, then parm2, and returns the value of parm2.\r\n"
- "\r\n"
- "equal(value,value2)\r\n"
- " = returns 1.0 if 'value' is equal to 'value2', otherwise returns 0.0\r\n"
- "\r\n"
- "above(value,value2)\r\n"
- " = returns 1.0 if 'value' is greater than 'value2', otherwise returns 0.0\r\n"
- "\r\n"
- "below(value,value2)\r\n"
- " = returns 1.0 if 'value' is less than 'value2', otherwise returns 0.0\r\n"
- "\r\n"
- "getosc(band,width,channel)\r\n"
- " = returns waveform data centered at 'band', (0..1), sampled 'width' (0..1) wide.\r\n"
- " 'channel' can be: 0=center, 1=left, 2=right. return value is (-1..1)\r\n"
- "\r\n"
- "getspec(band,width,channel)\r\n"
- " = returns spectrum data centered at 'band', (0..1), sampled 'width' (0..1) wide.\r\n"
- " 'channel' can be: 0=center, 1=left, 2=right. return value is (0..1)\r\n"
- "\r\n"
- "gettime(start_time)\r\n"
- " = returns time in seconds since start_time (start_time can be 0 for time since boot)\r\n"
- " (start_time can be -1.0 for current play time in seconds\r\n"
- " (start_time can be -2.0 for current play length in seconds\r\n"
- "\r\n"
- "getkbmouse(which_parm)\r\n"
- " = returns information about the location and state of the keyboard or mouse\r\n"
- " which_parm = 1: mouse X position (-1..1 is onscreen)\r\n"
- " which_parm = 2: mouse Y position (-1..1 is onscreen)\r\n"
- " which_parm = 3: mouse left button state (0 up, 1 down)\r\n"
- " which_parm = 4: mouse right button state (0 up, 1 down)\r\n"
- " which_parm = 5: mouse middle button state (0 up, 1 down)\r\n"
- " which_parm > 5: (GetAsyncKeyState(which_parm)&0x8000)?1:0\r\n"
- "\r\n"
- "megabuf(index)\r\n"
- " = can be used to get or set an item from the 1 million item temp buffer\r\n"
- " to get, use: val=megabuf(index);\r\n"
- " to set, use: assign(megabuf(index),val);\r\n"
- "gmegabuf(index)\r\n"
- " = can be used to get or set an item from the global 1 million item buffer\r\n"
- " to get, use: val=gmegabuf(index);\r\n"
- " to set, use: assign(gmegabuf(index),val);\r\n"
- "\r\n"
- "loop(count, statement)\r\n"
- " = executes <statement> <count> times. count is evaluated once and clamped\r\n"
- " to 0..4096. best used with exec2() and exec3() and assign(). Note that\r\n"
- " the return value of loop() is undefined and should not be used.\r\n"
- "\r\n"
- ;
- else if (sel == 3)
- text="Constants\r\n"
- " '$PI' can be used in place of '3.14159'\r\n"
- " '$E' can be used in place of '2.71828'\r\n"
- " '$PHI' can be used in place of '1.618033'\r\n"
- " Numbers can be specified as integers or as floating point\r\n"
- " (i.e. '5' or '5.0' or '5.00001')\r\n"
- ;
- */
- text=GetTextResource(IDR_HELP_1);
- else if (sel == 1)
- text=GetTextResource(IDR_HELP_2);
- else if (sel == 2)
- text=GetTextResource(IDR_HELP_3);
- else if (sel == 3)
- text=GetTextResource(IDR_HELP_4);
- else if (sel == 4 && m_localtext)
- text=m_localtext;
- SetDlgItemText(hwndDlg,IDC_EDIT1,text);
- }
- static BOOL CALLBACK evalHelpDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- TCITEM item;
- HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
- item.mask=TCIF_TEXT;
- item.pszText=WASABI_API_LNGSTRING(IDS_GENERAL);
- TabCtrl_InsertItem(tabwnd,0,&item);
- item.pszText=WASABI_API_LNGSTRING(IDS_OPERATORS);
- TabCtrl_InsertItem(tabwnd,1,&item);
- item.pszText=WASABI_API_LNGSTRING(IDS_FUNCTIONS);
- TabCtrl_InsertItem(tabwnd,2,&item);
- item.pszText=WASABI_API_LNGSTRING(IDS_CONSTANTS);
- TabCtrl_InsertItem(tabwnd,3,&item);
- // fucko: context specific stuff
- m_localtext=0;
- if (lParam)
- {
- item.pszText=(char *)lParam;
- m_localtext=item.pszText + strlen(item.pszText)+1;
- TabCtrl_InsertItem(tabwnd,4,&item);
- }
- else if (m_help_lastpage > 3) m_help_lastpage=0;
- TabCtrl_SetCurSel(tabwnd,m_help_lastpage);
- _dosetsel(hwndDlg);
- }
- return 0;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- EndDialog(hwndDlg,1);
- return 0;
- case WM_NOTIFY:
- {
- LPNMHDR p=(LPNMHDR) lParam;
- if (p->idFrom == IDC_TAB1 && p->code == TCN_SELCHANGE) _dosetsel(hwndDlg);
- }
- return 0;
- }
- return 0;
- }
- void compilerfunctionlist(HWND hwndDlg, char *localinfo)
- {
- WASABI_API_DIALOGBOXPARAM(IDD_EVAL_HELP,hwndDlg,evalHelpDlgProc, (LONG)localinfo);
- }
- #if 0//syntax highlighting
- // If you include richedit boxes, you need to load the richlib at the beginning:
- // HANDLE hRichLib = LoadLibrary("RICHED32.DLL");
- // When quitting:
- // FreeLibrary(hRichLib);
- #define M_WORD 1
- #define M_NUM 2
- #define M_COMM 3
- #define is_alpha(a) ((((a) >= 'A') && ((a) <= 'Z')) || (((a) >= 'a') && ((a) <= 'z')))
- #define is_num(a) (((a) >= '0') && ((a) <= '9'))
- #define is_op(a) (((a) == '=') || ((a) == '+') || ((a) == '-') || ((a) == '*') || ((a) == '/') || ((a) == '%'))
- // Colors for bracket pairs (loops around, ugly colors for now), can be any number of colors
- static int bcol[] = { RGB(192, 0, 0), RGB(64, 128, 128), RGB(128, 0, 255), RGB(128, 128, 255) };
- #define COLOR_COMMENT RGB(0, 128, 0)
- #define COLOR_FUNC RGB(0, 0, 192)
- #define COLOR_VAR RGB(96, 96, 96)
- #define COLOR_OP RGB(0, 0, 0)
- #define COLOR_NUMBER RGB(0, 0, 128)
- // Actual syntax highlighting
- // 'hwnd' is a richedit box, 'data' is the code of 'size' characters
- void doAVSEvalHighLight(HWND hwndDlg, UINT sub, char *data) {
- int size=strlen(data);
- HWND hwnd=GetDlgItem(hwndDlg,sub);
- CHARRANGE cr, cro;
-
- CHARFORMAT cf;
- cf.cbSize = sizeof(CHARFORMAT);
- cf.dwMask = CFM_COLOR;
- cf.dwEffects = 0;
- SendMessage(hwnd, WM_SETREDRAW, false, 0);
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&cro);
- int mode = 0;
- int pos = 0;
- int brackets = 0;
- for (int i = 0; i < size; ++i) {
- if (mode == M_COMM) {
- // We're inside a comment, check for its end
- if ((data[i] == ';') || ((data[i] == '*') && ((i+1) < size) && (data[++i] == '/'))) {
- mode = 0;
- cf.crTextColor = COLOR_COMMENT;
- cr.cpMin = pos;
- cr.cpMax = i+1;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
- SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
- }
- } else if (is_alpha(data[i]) || ((mode == M_WORD) && is_num(data[i]))) {
- // Letter tokens (func calls, vars)
- if (mode != M_WORD) {
- // Enter word-mode if we haven't yet
- mode = M_WORD;
- pos = i;
- }
- // Stop condition
- bool valid = (i != (size-1)); // Check if this isn't the last character
- if (valid) {
- valid = is_num(data[i+1]) || is_alpha(data[i+1]);
- }
- if (!valid) {
- // We have reached the end of this word
- cr.cpMin = pos;
- cr.cpMax = i+1;
- // Check if its a function
- bool func = false;
- for (int j = 0; j < (sizeof(fnTable) / sizeof(fnTable[0])); ++j) {
- if ((i - pos + 1) == (signed)strlen(fnTable[j].name)) {
- if (strnicmp(fnTable[j].name, &data[pos], strlen(fnTable[j].name)) == 0) {
- func = true;
- break;
- }
- }
- }
- cf.crTextColor = func ? COLOR_FUNC : COLOR_VAR;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
- SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
- }
- } else if (is_op(data[i])) {
- // This is an operator
- mode = 0;
- cf.crTextColor = COLOR_OP;
- cr.cpMin = i;
- cr.cpMax = i+1;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
- SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
- } else if ((data[i] & 0x80) || ((data[i] == '/') && ((i+1) < size) && (data[++i] == '*'))) {
- // This is a comment marker, enter comment mode
- mode = M_COMM;
- pos = i;
- } else if ((data[i] == '(') || (data[i] == ')') || (data[i] == ',')) {
- // Reached brackets: we count them and color them in pairs
- mode = 0;
- if (data[i] == '(') ++brackets;
- cf.crTextColor = bcol[brackets % (sizeof(bcol) / sizeof(bcol[0]))];
- if (data[i] == ')') --brackets;
- cr.cpMin = i;
- cr.cpMax = i+1;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
- SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
- } else if (is_num(data[i]) || (data[i] == '.')) {
- // constants
- if (mode != M_NUM) {
- pos = i;
- mode = M_NUM;
- }
- // Stop condition
- bool valid = (i != (size-1));
- if (valid) {
- valid = is_num(data[i+1]) || (data[i+1] == '.');
- }
- if (!valid) {
- cf.crTextColor = COLOR_NUMBER;
- cr.cpMin = pos;
- cr.cpMax = i+1;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
- SendMessage(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
- }
- } else if (data[i] == ';') {
- // Reset bracket count and mode for every statement.
- mode = 0;
- brackets = 0;
- }
- }
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cro);
- SendMessage(hwnd, WM_SETREDRAW, true, 0);
- InvalidateRect(hwnd, 0, true);
- }
- #endif
|