/* =========================================================================== IceTech GPL Source Code Copyright (C) 2026 Justin Marshall This file is part of the IceTech GPL Source Code (?IceTech Source Code?). IceTech Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. IceTech Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with IceTech Source Code. If not, see . In addition, the IceTech Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the IceTech Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing Justin Marshall, justinmarshall20@gmail.com =========================================================================== */ #include "precompiled.h" #pragma hdrstop #include "qe3.h" #include "Radiant.h" #include "../comafx/DialogColorPicker.h" #include "LightDlg.h" #include #ifdef ID_DEBUG_MEMORY #undef new #undef DEBUG_NEW #define DEBUG_NEW new #endif void CLightInfo::Defaults() { pointLight = true; fallOff = 1; strTexture = ""; equalRadius = true; explicitStartEnd = false; lightRadius.Zero(); lightTarget.Zero(); lightRight.Zero(); lightUp.Zero(); lightStart.Zero(); lightEnd.Zero(); lightCenter.Zero(); hasCenter = false; isParallel = false; castShadows = true; castSpecular = true; castDiffuse = true; rotate = false; strobe = false; rotateSpeed = 0; strobeSpeed = 0; color[0] = color[1] = color[2] = 255; fogDensity[0] = fogDensity[1] = fogDensity[2] = 0; fog = false; lightRadius[0] = lightRadius[1] = lightRadius[2] = 300; } void CLightInfo::DefaultPoint() { idVec3 oldColor = color; Defaults(); color = oldColor; pointLight = true; } void CLightInfo::DefaultProjected() { idVec3 oldColor = color; Defaults(); color = oldColor; pointLight = false; lightTarget[2] = -256; lightUp[1] = -128; lightRight[0] = -128; } void CLightInfo::FromDict( const idDict *e ) { lightRadius.Zero(); lightTarget.Zero(); lightRight.Zero(); lightUp.Zero(); lightStart.Zero(); lightEnd.Zero(); lightCenter.Zero(); castShadows = !e->GetBool("noshadows"); castSpecular = !e->GetBool("nospecular"); castDiffuse = !e->GetBool("nodiffuse"); fallOff = e->GetFloat("falloff"); strTexture = e->GetString("texture"); isParallel = e->GetBool("parallel"); if (!e->GetVector("_color", "", color)) { color[0] = color[1] = color[2] = 1; } // windows needs 0-255 scale color[0] *= 255; color[1] *= 255; color[2] *= 255; if (e->GetVec4("fog", "", fogDensity)) { fog = true; } else { fog = false; } if (e->GetVector("light_right","", lightRight)) { // projected light pointLight = false; e->GetVector("light_target", "", lightTarget); e->GetVector("light_up", "", lightUp); if (e->GetVector("light_start", "", lightStart)) { // explicit start and end points explicitStartEnd = true; if (!e->GetVector("light_end", "", lightEnd)) { // no end, use target VectorCopy(lightTarget, lightEnd); } } else { explicitStartEnd = false; // create a start a quarter of the way to the target lightStart = lightTarget * 0.25; VectorCopy(lightTarget, lightEnd); } } else { pointLight = true; if (e->GetVector("light_radius", "", lightRadius)) { equalRadius = false; } else { float radius = e->GetFloat("light"); if (radius == 0) { radius = 300; } lightRadius[0] = lightRadius[1] = lightRadius[2] = radius; equalRadius = true; } if (e->GetVector("light_center", "", lightCenter)) { hasCenter = true; } } } void CLightInfo::ToDictFromDifferences ( idDict *e, const idDict *differences ) { for ( int i = 0 ; i < differences->GetNumKeyVals () ; i ++ ) { const idKeyValue *kv = differences->GetKeyVal( i ); if ( kv->GetValue().Length() > 0 ) { e->Set ( kv->GetKey() ,kv->GetValue() ); } else { e->Delete ( kv->GetKey() ); } common->Printf( "Applied difference: %s %s\n" , kv->GetKey().c_str() , kv->GetValue().c_str() ); } } //write all info to a dict, regardless of light type void CLightInfo::ToDictWriteAllInfo( idDict *e ) { e->Set("noshadows", (!castShadows) ? "1" : "0"); e->Set("nospecular", (!castSpecular) ? "1" : "0"); e->Set("nodiffuse", (!castDiffuse) ? "1" : "0"); e->SetFloat("falloff",fallOff); if (strTexture.GetLength() > 0 ) { e->Set("texture", strTexture); } idVec3 temp = color; temp /= 255; e->SetVector("_color", temp); if (!equalRadius) { e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[1], lightRadius[2])); } else { e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[0], lightRadius[0])); } e->Set("light_center", va("%g %g %g", lightCenter[0], lightCenter[1], lightCenter[2])); e->Set("parallel", isParallel?"1":"0"); e->Set("light_target", va("%g %g %g", lightTarget[0], lightTarget[1], lightTarget[2])); e->Set("light_up", va("%g %g %g", lightUp[0], lightUp[1], lightUp[2])); e->Set("light_right", va("%g %g %g", lightRight[0], lightRight[1], lightRight[2])); e->Set("light_start", va("%g %g %g", lightStart[0], lightStart[1], lightStart[2])); e->Set("light_end", va("%g %g %g", lightEnd[0], lightEnd[1], lightEnd[2])); } void CLightInfo::ToDict( idDict *e ) { e->Delete("noshadows"); e->Delete("nospecular"); e->Delete("nodiffuse"); e->Delete("falloff"); e->Delete("parallel"); e->Delete("texture"); e->Delete("_color"); e->Delete("fog"); e->Delete("light_target"); e->Delete("light_right"); e->Delete("light_up"); e->Delete("light_start"); e->Delete("light_end"); e->Delete("light_radius"); e->Delete("light_center"); e->Delete("light"); e->Set("noshadows", (!castShadows) ? "1" : "0"); e->Set("nospecular", (!castSpecular) ? "1" : "0"); e->Set("nodiffuse", (!castDiffuse) ? "1" : "0"); e->SetFloat("falloff",fallOff); if (strTexture.GetLength() > 0) { e->Set("texture", strTexture); } idVec3 temp = color; temp /= 255; e->SetVector("_color", temp); if (fog) { e->Set("fog", va("%g %g %g %g", fogDensity[0]/255.0, fogDensity[1]/255.0, fogDensity[2]/255.0, fogDensity[3]/255.0)); } if (pointLight) { if (!equalRadius) { e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[1], lightRadius[2])); } else { e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[0], lightRadius[0])); } if (hasCenter) { e->Set("light_center", va("%g %g %g", lightCenter[0], lightCenter[1], lightCenter[2])); } if (isParallel) { e->Set("parallel", "1"); } } else { e->Set("light_target", va("%g %g %g", lightTarget[0], lightTarget[1], lightTarget[2])); e->Set("light_up", va("%g %g %g", lightUp[0], lightUp[1], lightUp[2])); e->Set("light_right", va("%g %g %g", lightRight[0], lightRight[1], lightRight[2])); if (explicitStartEnd) { e->Set("light_start", va("%g %g %g", lightStart[0], lightStart[1], lightStart[2])); e->Set("light_end", va("%g %g %g", lightEnd[0], lightEnd[1], lightEnd[2])); } } } CLightInfo::CLightInfo() { Defaults(); } // -------------------------------------------------------------------------- // IceTech dark MFC/common-control helper // -------------------------------------------------------------------------- #ifndef BS_TYPEMASK #define BS_TYPEMASK 0x0000000F #endif static const COLORREF ICE_DARK_BG = RGB(17, 19, 23); static const COLORREF ICE_DARK_PANEL = RGB(24, 27, 32); static const COLORREF ICE_DARK_PANEL_ALT = RGB(29, 33, 39); static const COLORREF ICE_DARK_FIELD = RGB(14, 16, 20); static const COLORREF ICE_DARK_BORDER = RGB(55, 62, 72); static const COLORREF ICE_DARK_BORDER_HOT = RGB(87, 166, 255); static const COLORREF ICE_DARK_TEXT = RGB(226, 232, 240); static const COLORREF ICE_DARK_TEXT_MUTED = RGB(151, 163, 184); static const COLORREF ICE_DARK_TEXT_DISABLED = RGB(103, 112, 128); static const COLORREF ICE_DARK_ACCENT = RGB(87, 166, 255); static const char* ICE_DARK_PARENT_OLDPROC = "IceTech.Dark.ParentOldProc"; static const char* ICE_DARK_CONTROL_OLDPROC = "IceTech.Dark.ControlOldProc"; static int IceDark_MaxInt(int a, int b) { return (a > b) ? a : b; } static HBRUSH IceDark_BgBrush() { static HBRUSH hBrush = ::CreateSolidBrush(ICE_DARK_BG); return hBrush; } static HBRUSH IceDark_PanelBrush() { static HBRUSH hBrush = ::CreateSolidBrush(ICE_DARK_PANEL); return hBrush; } static HBRUSH IceDark_FieldBrush() { static HBRUSH hBrush = ::CreateSolidBrush(ICE_DARK_FIELD); return hBrush; } static void IceDark_FillRect(HDC hDC, const RECT& rc, COLORREF color) { HBRUSH brush = ::CreateSolidBrush(color); ::FillRect(hDC, &rc, brush); ::DeleteObject(brush); } static void IceDark_FrameRect(HDC hDC, const RECT& rc, COLORREF color) { HBRUSH brush = ::CreateSolidBrush(color); ::FrameRect(hDC, &rc, brush); ::DeleteObject(brush); } static void IceDark_ApplyNativeTheme(HWND hWnd) { if (!hWnd) { return; } typedef HRESULT (WINAPI *SetWindowThemeProc)(HWND, LPCWSTR, LPCWSTR); typedef BOOL (WINAPI *AllowDarkModeForWindowProc)(HWND, BOOL); static HMODULE hUxTheme = ::LoadLibraryA("uxtheme.dll"); static SetWindowThemeProc pSetWindowTheme = hUxTheme ? (SetWindowThemeProc)::GetProcAddress(hUxTheme, "SetWindowTheme") : NULL; static AllowDarkModeForWindowProc pAllowDarkModeForWindow = hUxTheme ? (AllowDarkModeForWindowProc)::GetProcAddress(hUxTheme, MAKEINTRESOURCEA(133)) : NULL; if (pAllowDarkModeForWindow) { pAllowDarkModeForWindow(hWnd, TRUE); } if (pSetWindowTheme) { pSetWindowTheme(hWnd, L"DarkMode_Explorer", NULL); } ::SendMessage(hWnd, WM_THEMECHANGED, 0, 0); } static void IceDark_RemoveClientEdge(HWND hWnd) { if (!hWnd) { return; } LONG exStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE); if (exStyle & WS_EX_CLIENTEDGE) { ::SetWindowLong(hWnd, GWL_EXSTYLE, exStyle & ~WS_EX_CLIENTEDGE); ::SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED); } } static void IceDark_DrawFrame(HWND hWnd, COLORREF color) { HDC hDC = ::GetWindowDC(hWnd); if (!hDC) { return; } RECT rc; ::GetWindowRect(hWnd, &rc); ::OffsetRect(&rc, -rc.left, -rc.top); IceDark_FrameRect(hDC, rc, color); ::ReleaseDC(hWnd, hDC); } static void IceDark_DrawButton(HWND hWnd, HDC hDC) { RECT rc; ::GetClientRect(hWnd, &rc); const UINT style = (UINT)::GetWindowLong(hWnd, GWL_STYLE); const UINT type = style & BS_TYPEMASK; const bool enabled = ::IsWindowEnabled(hWnd) ? true : false; const bool pushed = (::SendMessage(hWnd, BM_GETSTATE, 0, 0) & BST_PUSHED) != 0; const bool checked = (::SendMessage(hWnd, BM_GETCHECK, 0, 0) == BST_CHECKED); const bool isCheck = (type == BS_CHECKBOX || type == BS_AUTOCHECKBOX || type == BS_3STATE || type == BS_AUTO3STATE); const bool isRadio = (type == BS_RADIOBUTTON || type == BS_AUTORADIOBUTTON); const bool isGroup = (type == BS_GROUPBOX); char text[512]; text[0] = '\0'; ::GetWindowTextA(hWnd, text, sizeof(text)); HFONT font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0); HFONT oldFont = font ? (HFONT)::SelectObject(hDC, font) : NULL; ::SetBkMode(hDC, TRANSPARENT); ::SetTextColor(hDC, enabled ? ICE_DARK_TEXT : ICE_DARK_TEXT_DISABLED); if (isGroup) { IceDark_FillRect(hDC, rc, ICE_DARK_BG); RECT textRect = rc; textRect.left += 10; textRect.right -= 8; textRect.bottom = textRect.top + 18; SIZE textSize; textSize.cx = textSize.cy = 0; ::GetTextExtentPoint32A(hDC, text, (int)strlen(text), &textSize); RECT frame = rc; frame.top += 8; HPEN pen = ::CreatePen(PS_SOLID, 1, ICE_DARK_BORDER); HPEN oldPen = (HPEN)::SelectObject(hDC, pen); HBRUSH oldBrush = (HBRUSH)::SelectObject(hDC, ::GetStockObject(NULL_BRUSH)); ::RoundRect(hDC, frame.left, frame.top, frame.right, frame.bottom, 8, 8); ::SelectObject(hDC, oldBrush); ::SelectObject(hDC, oldPen); ::DeleteObject(pen); RECT fillLabel = textRect; fillLabel.right = fillLabel.left + textSize.cx + 8; IceDark_FillRect(hDC, fillLabel, ICE_DARK_BG); ::SetTextColor(hDC, ICE_DARK_TEXT_MUTED); ::DrawTextA(hDC, text, -1, &textRect, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS); } else if (isCheck || isRadio) { IceDark_FillRect(hDC, rc, ICE_DARK_BG); RECT box = rc; box.left += 3; box.right = box.left + 15; box.top += IceDark_MaxInt(0, (rc.bottom - rc.top - 15) / 2); box.bottom = box.top + 15; if (isRadio) { HPEN pen = ::CreatePen(PS_SOLID, 1, checked ? ICE_DARK_ACCENT : ICE_DARK_BORDER); HPEN oldPen = (HPEN)::SelectObject(hDC, pen); HBRUSH brush = ::CreateSolidBrush(enabled ? ICE_DARK_FIELD : RGB(20, 22, 26)); HBRUSH oldBrush = (HBRUSH)::SelectObject(hDC, brush); ::Ellipse(hDC, box.left, box.top, box.right, box.bottom); ::SelectObject(hDC, oldBrush); ::DeleteObject(brush); ::SelectObject(hDC, oldPen); ::DeleteObject(pen); if (checked) { RECT dot = box; ::InflateRect(&dot, -4, -4); HBRUSH dotBrush = ::CreateSolidBrush(enabled ? ICE_DARK_ACCENT : ICE_DARK_TEXT_DISABLED); HBRUSH oldDotBrush = (HBRUSH)::SelectObject(hDC, dotBrush); HPEN dotPen = ::CreatePen(PS_SOLID, 1, enabled ? ICE_DARK_ACCENT : ICE_DARK_TEXT_DISABLED); HPEN oldDotPen = (HPEN)::SelectObject(hDC, dotPen); ::Ellipse(hDC, dot.left, dot.top, dot.right, dot.bottom); ::SelectObject(hDC, oldDotPen); ::DeleteObject(dotPen); ::SelectObject(hDC, oldDotBrush); ::DeleteObject(dotBrush); } } else { IceDark_FillRect(hDC, box, enabled ? ICE_DARK_FIELD : RGB(20, 22, 26)); IceDark_FrameRect(hDC, box, checked ? ICE_DARK_ACCENT : ICE_DARK_BORDER); if (checked) { HPEN pen = ::CreatePen(PS_SOLID, 2, enabled ? ICE_DARK_ACCENT : ICE_DARK_TEXT_DISABLED); HPEN oldPen = (HPEN)::SelectObject(hDC, pen); ::MoveToEx(hDC, box.left + 3, box.top + 7, NULL); ::LineTo(hDC, box.left + 6, box.top + 10); ::LineTo(hDC, box.right - 3, box.top + 3); ::SelectObject(hDC, oldPen); ::DeleteObject(pen); } } RECT textRect = rc; textRect.left = box.right + 7; textRect.right -= 2; ::DrawTextA(hDC, text, -1, &textRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); } else { COLORREF face = pushed ? RGB(22, 25, 30) : ICE_DARK_PANEL_ALT; IceDark_FillRect(hDC, rc, face); IceDark_FrameRect(hDC, rc, enabled ? ICE_DARK_BORDER : RGB(39, 44, 52)); RECT inner = rc; ::InflateRect(&inner, -1, -1); if (!pushed) { IceDark_FrameRect(hDC, inner, RGB(35, 40, 47)); } RECT textRect = rc; if (pushed) { ::OffsetRect(&textRect, 1, 1); } ::DrawTextA(hDC, text, -1, &textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); } if (oldFont) { ::SelectObject(hDC, oldFont); } } static LRESULT CALLBACK IceDark_ButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, ICE_DARK_CONTROL_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_ERASEBKGND: return 1; case WM_PAINT: { UINT style = (UINT)::GetWindowLong(hWnd, GWL_STYLE); if (style & (BS_BITMAP | BS_ICON)) { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); IceDark_DrawFrame(hWnd, ICE_DARK_BORDER); return result; } PAINTSTRUCT ps; HDC hDC = ::BeginPaint(hWnd, &ps); IceDark_DrawButton(hWnd, hDC); ::EndPaint(hWnd, &ps); return 0; } case WM_PRINTCLIENT: IceDark_DrawButton(hWnd, (HDC)wParam); return 0; case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_ENABLE: case WM_SETTEXT: case BM_SETCHECK: case BM_SETSTATE: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); ::InvalidateRect(hWnd, NULL, FALSE); return result; } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, ICE_DARK_CONTROL_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static void IceDark_DrawCombo(HWND hWnd, HDC hDC) { RECT rc; ::GetClientRect(hWnd, &rc); const bool enabled = ::IsWindowEnabled(hWnd) ? true : false; const bool focused = (::GetFocus() == hWnd || ::IsChild(hWnd, ::GetFocus())) ? true : false; IceDark_FillRect(hDC, rc, enabled ? ICE_DARK_FIELD : RGB(20, 22, 26)); IceDark_FrameRect(hDC, rc, focused ? ICE_DARK_BORDER_HOT : ICE_DARK_BORDER); RECT arrow = rc; arrow.left = arrow.right - 22; IceDark_FillRect(hDC, arrow, ICE_DARK_PANEL_ALT); IceDark_FrameRect(hDC, arrow, ICE_DARK_BORDER); POINT pts[3]; int cx = arrow.left + (arrow.right - arrow.left) / 2; int cy = arrow.top + (arrow.bottom - arrow.top) / 2 + 1; pts[0].x = cx - 4; pts[0].y = cy - 2; pts[1].x = cx + 4; pts[1].y = cy - 2; pts[2].x = cx; pts[2].y = cy + 3; HBRUSH arrowBrush = ::CreateSolidBrush(enabled ? ICE_DARK_TEXT : ICE_DARK_TEXT_DISABLED); HBRUSH oldBrush = (HBRUSH)::SelectObject(hDC, arrowBrush); HPEN arrowPen = ::CreatePen(PS_SOLID, 1, enabled ? ICE_DARK_TEXT : ICE_DARK_TEXT_DISABLED); HPEN oldPen = (HPEN)::SelectObject(hDC, arrowPen); ::Polygon(hDC, pts, 3); ::SelectObject(hDC, oldPen); ::DeleteObject(arrowPen); ::SelectObject(hDC, oldBrush); ::DeleteObject(arrowBrush); char text[512]; text[0] = '\0'; int sel = (int)::SendMessage(hWnd, CB_GETCURSEL, 0, 0); if (sel >= 0) { ::SendMessageA(hWnd, CB_GETLBTEXT, (WPARAM)sel, (LPARAM)text); } else { ::GetWindowTextA(hWnd, text, sizeof(text)); } HFONT font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0); HFONT oldFont = font ? (HFONT)::SelectObject(hDC, font) : NULL; ::SetBkMode(hDC, TRANSPARENT); ::SetTextColor(hDC, enabled ? ICE_DARK_TEXT : ICE_DARK_TEXT_DISABLED); RECT textRect = rc; textRect.left += 7; textRect.right = arrow.left - 3; ::DrawTextA(hDC, text, -1, &textRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS); if (oldFont) { ::SelectObject(hDC, oldFont); } } static LRESULT CALLBACK IceDark_ComboProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, ICE_DARK_CONTROL_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_ERASEBKGND: return 1; case WM_PAINT: { UINT comboType = (UINT)::GetWindowLong(hWnd, GWL_STYLE) & 0x00000003; if (comboType == CBS_DROPDOWNLIST) { PAINTSTRUCT ps; HDC hDC = ::BeginPaint(hWnd, &ps); IceDark_DrawCombo(hWnd, hDC); ::EndPaint(hWnd, &ps); return 0; } LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); IceDark_DrawFrame(hWnd, (::GetFocus() == hWnd || ::IsChild(hWnd, ::GetFocus())) ? ICE_DARK_BORDER_HOT : ICE_DARK_BORDER); return result; } case WM_SETFOCUS: case WM_KILLFOCUS: case WM_ENABLE: case WM_SETTEXT: case CB_SETCURSEL: case CB_ADDSTRING: case CB_DELETESTRING: case CB_RESETCONTENT: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); ::InvalidateRect(hWnd, NULL, FALSE); return result; } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, ICE_DARK_CONTROL_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static LRESULT CALLBACK IceDark_FieldProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, ICE_DARK_CONTROL_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_NCPAINT: case WM_PAINT: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); IceDark_DrawFrame(hWnd, (::GetFocus() == hWnd) ? ICE_DARK_BORDER_HOT : ICE_DARK_BORDER); return result; } case WM_SETFOCUS: case WM_KILLFOCUS: case WM_ENABLE: { LRESULT result = ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); ::RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW); return result; } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, ICE_DARK_CONTROL_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static LRESULT CALLBACK IceDark_ParentProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldProc = (WNDPROC)::GetPropA(hWnd, ICE_DARK_PARENT_OLDPROC); if (!oldProc) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } switch (uMsg) { case WM_ERASEBKGND: { RECT rc; ::GetClientRect(hWnd, &rc); IceDark_FillRect((HDC)wParam, rc, ICE_DARK_BG); return 1; } case WM_CTLCOLORDLG: return (LRESULT)IceDark_BgBrush(); case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; ::SetTextColor(hDC, ICE_DARK_TEXT_MUTED); ::SetBkMode(hDC, TRANSPARENT); return (LRESULT)IceDark_BgBrush(); } case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: { HDC hDC = (HDC)wParam; ::SetTextColor(hDC, ICE_DARK_TEXT); ::SetBkColor(hDC, ICE_DARK_FIELD); return (LRESULT)IceDark_FieldBrush(); } case WM_CTLCOLORBTN: { HDC hDC = (HDC)wParam; ::SetTextColor(hDC, ICE_DARK_TEXT); ::SetBkColor(hDC, ICE_DARK_BG); return (LRESULT)IceDark_BgBrush(); } case WM_NCDESTROY: { ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)oldProc); ::RemovePropA(hWnd, ICE_DARK_PARENT_OLDPROC); return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } } return ::CallWindowProc(oldProc, hWnd, uMsg, wParam, lParam); } static void IceDark_Subclass(HWND hWnd, WNDPROC proc, const char* propName) { if (!hWnd || ::GetPropA(hWnd, propName)) { return; } WNDPROC oldProc = (WNDPROC)::GetWindowLongPtr(hWnd, GWLP_WNDPROC); ::SetPropA(hWnd, propName, (HANDLE)oldProc); ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)proc); } static bool IceDark_IsClass(HWND hWnd, const char* className) { char actual[128]; actual[0] = '\0'; ::GetClassNameA(hWnd, actual, sizeof(actual)); return ::lstrcmpiA(actual, className) == 0; } static bool IceDark_IsKnownControl(HWND hWnd) { return IceDark_IsClass(hWnd, "Button") || IceDark_IsClass(hWnd, "Edit") || IceDark_IsClass(hWnd, "ComboBox") || IceDark_IsClass(hWnd, "ListBox") || IceDark_IsClass(hWnd, "SysTreeView32") || IceDark_IsClass(hWnd, "SysListView32") || IceDark_IsClass(hWnd, "msctls_trackbar32") || IceDark_IsClass(hWnd, "msctls_updown32") || IceDark_IsClass(hWnd, "ScrollBar") || IceDark_IsClass(hWnd, "SysTabControl32"); } static void IceDark_ApplyToWindowAndChildren(HWND hWnd) { if (!hWnd) { return; } IceDark_ApplyNativeTheme(hWnd); IceDark_RemoveClientEdge(hWnd); if (IceDark_IsClass(hWnd, "Button")) { IceDark_Subclass(hWnd, IceDark_ButtonProc, ICE_DARK_CONTROL_OLDPROC); } else if (IceDark_IsClass(hWnd, "ComboBox")) { IceDark_Subclass(hWnd, IceDark_ComboProc, ICE_DARK_CONTROL_OLDPROC); } else if (IceDark_IsClass(hWnd, "Edit") || IceDark_IsClass(hWnd, "ListBox") || IceDark_IsClass(hWnd, "SysTreeView32") || IceDark_IsClass(hWnd, "SysListView32")) { IceDark_Subclass(hWnd, IceDark_FieldProc, ICE_DARK_CONTROL_OLDPROC); } else if (!IceDark_IsKnownControl(hWnd)) { IceDark_Subclass(hWnd, IceDark_ParentProc, ICE_DARK_PARENT_OLDPROC); } if (IceDark_IsClass(hWnd, "SysTreeView32")) { ::SendMessage(hWnd, TVM_SETBKCOLOR, 0, (LPARAM)ICE_DARK_FIELD); ::SendMessage(hWnd, TVM_SETTEXTCOLOR, 0, (LPARAM)ICE_DARK_TEXT); } if (IceDark_IsClass(hWnd, "SysListView32")) { ::SendMessage(hWnd, LVM_SETBKCOLOR, 0, (LPARAM)ICE_DARK_FIELD); ::SendMessage(hWnd, LVM_SETTEXTBKCOLOR, 0, (LPARAM)ICE_DARK_FIELD); ::SendMessage(hWnd, LVM_SETTEXTCOLOR, 0, (LPARAM)ICE_DARK_TEXT); } for (HWND child = ::GetWindow(hWnd, GW_CHILD); child != NULL; child = ::GetWindow(child, GW_HWNDNEXT)) { IceDark_ApplyToWindowAndChildren(child); } ::InvalidateRect(hWnd, NULL, TRUE); } static void IceDark_ApplyToDialog(CWnd* wnd) { if (wnd && wnd->GetSafeHwnd()) { IceDark_ApplyToWindowAndChildren(wnd->GetSafeHwnd()); } } ///////////////////////////////////////////////////////////////////////////// // CLightDlg dialog CLightDlg *g_LightDialog = NULL; CLightDlg::CLightDlg(CWnd* pParent /*=NULL*/) : CDialog(CLightDlg::IDD, pParent) { //{{AFX_DATA_INIT(CLightDlg) m_bEqualRadius = FALSE; m_bExplicitFalloff = FALSE; m_bPointLight = FALSE; m_bCheckProjected = FALSE; m_fFallloff = 0.0f; m_nFalloff = -1; m_bRotate = FALSE; m_bShadows = FALSE; m_bSpecular = FALSE; m_bDiffuse = FALSE; m_fEndX = 0.0f; m_fEndY = 0.0f; m_fEndZ = 0.0f; m_fRadiusX = 0.0f; m_fRadiusY = 0.0f; m_fRadiusZ = 0.0f; m_fRightX = 0.0f; m_fRightY = 0.0f; m_fRightZ = 0.0f; m_fRotate = 0.0f; m_fStartX = 0.0f; m_fStartY = 0.0f; m_fStartZ = 0.0f; m_fTargetX = 0.0f; m_fTargetY = 0.0f; m_fTargetZ = 0.0f; m_fUpX = 0.0f; m_fUpY = 0.0f; m_fUpZ = 0.0f; m_hasCenter = FALSE; m_centerX = 0.0f; m_centerY = 0.0f; m_centerZ = 0.0f; m_bIsParallel = FALSE; //}}AFX_DATA_INIT m_drawMaterial = new idGLDrawableMaterial(); } CLightDlg::~CLightDlg() { delete m_drawMaterial; } void CLightDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CLightDlg) if ( com_editorActive ) { DDX_Control(pDX, IDC_LIGHTPREVIEW, m_wndPreview); } DDX_Control(pDX, IDC_COMBO_TEXTURE, m_wndLights); DDX_Check(pDX, IDC_CHECK_EQUALRADIUS, m_bEqualRadius); DDX_Check(pDX, IDC_CHECK_EXPLICITFALLOFF, m_bExplicitFalloff); DDX_Check(pDX, IDC_CHECK_POINT, m_bPointLight); DDX_Check(pDX, IDC_CHECK_PROJECTED, m_bCheckProjected); DDX_Radio(pDX, IDC_RADIO_FALLOFF, m_nFalloff); DDX_Check(pDX, IDC_CHECK_SHADOWS, m_bShadows); DDX_Check(pDX, IDC_CHECK_SPECULAR, m_bSpecular); DDX_Check(pDX, IDC_CHECK_DIFFUSE, m_bDiffuse); DDX_Check(pDX , IDC_CHECK_PARALLEL , m_bIsParallel ); DDX_Text(pDX, IDC_EDIT_ENDX, m_fEndX); DDX_Text(pDX, IDC_EDIT_ENDY, m_fEndY); DDX_Text(pDX, IDC_EDIT_ENDZ, m_fEndZ); DDX_Text(pDX, IDC_EDIT_RADIUSX, m_fRadiusX); DDX_Text(pDX, IDC_EDIT_RADIUSY, m_fRadiusY); DDX_Text(pDX, IDC_EDIT_RADIUSZ, m_fRadiusZ); DDX_Text(pDX, IDC_EDIT_RIGHTX, m_fRightX); DDX_Text(pDX, IDC_EDIT_RIGHTY, m_fRightY); DDX_Text(pDX, IDC_EDIT_RIGHTZ, m_fRightZ); DDX_Text(pDX, IDC_EDIT_STARTX, m_fStartX); DDX_Text(pDX, IDC_EDIT_STARTY, m_fStartY); DDX_Text(pDX, IDC_EDIT_STARTZ, m_fStartZ); DDX_Text(pDX, IDC_EDIT_TARGETX, m_fTargetX); DDX_Text(pDX, IDC_EDIT_TARGETY, m_fTargetY); DDX_Text(pDX, IDC_EDIT_TARGETZ, m_fTargetZ); DDX_Text(pDX, IDC_EDIT_UPX, m_fUpX); DDX_Text(pDX, IDC_EDIT_UPY, m_fUpY); DDX_Text(pDX, IDC_EDIT_UPZ, m_fUpZ); DDX_Check(pDX, IDC_CHECK_CENTER, m_hasCenter); DDX_Text(pDX, IDC_EDIT_CENTERX, m_centerX); DDX_Text(pDX, IDC_EDIT_CENTERY, m_centerY); DDX_Text(pDX, IDC_EDIT_CENTERZ, m_centerZ); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CLightDlg, CDialog) //{{AFX_MSG_MAP(CLightDlg) ON_BN_CLICKED(IDC_BTN_TEXTURE, OnBtnTexture) ON_BN_CLICKED(IDC_CHECK_EQUALRADIUS, OnCheckEqualradius) ON_BN_CLICKED(IDC_CHECK_EXPLICITFALLOFF, OnCheckExplicitfalloff) ON_BN_CLICKED(IDC_CHECK_POINT, OnCheckPoint) ON_BN_CLICKED(IDC_CHECK_PROJECTED, OnCheckProjected) ON_BN_CLICKED(IDC_RADIO_FALLOFF, OnRadioFalloff) ON_BN_CLICKED(IDC_APPLY, OnApply) ON_BN_CLICKED(IDC_APPLY_DIFFERENT, OnApplyDifferences) ON_BN_CLICKED(IDC_BTN_COLOR, OnBtnColor) ON_WM_CTLCOLOR() ON_CBN_SELCHANGE(IDC_COMBO_TEXTURE, OnSelchangeComboTexture) ON_BN_CLICKED(IDC_CHECK_CENTER, OnCheckCenter) ON_BN_CLICKED(IDC_CHECK_PARALLEL, OnCheckParallel) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLightDlg message handlers void CLightDlg::SetSpecifics() { if (lightInfo.pointLight) { GetDlgItem(IDC_EDIT_RADIUSY)->EnableWindow(!lightInfo.equalRadius); GetDlgItem(IDC_EDIT_RADIUSZ)->EnableWindow(!lightInfo.equalRadius); GetDlgItem(IDC_EDIT_CENTERX)->EnableWindow(lightInfo.hasCenter); GetDlgItem(IDC_EDIT_CENTERY)->EnableWindow(lightInfo.hasCenter); GetDlgItem(IDC_EDIT_CENTERZ)->EnableWindow(lightInfo.hasCenter); } else { GetDlgItem(IDC_EDIT_STARTX)->EnableWindow(lightInfo.explicitStartEnd); GetDlgItem(IDC_EDIT_STARTY)->EnableWindow(lightInfo.explicitStartEnd); GetDlgItem(IDC_EDIT_STARTZ)->EnableWindow(lightInfo.explicitStartEnd); GetDlgItem(IDC_EDIT_ENDX)->EnableWindow(lightInfo.explicitStartEnd); GetDlgItem(IDC_EDIT_ENDY)->EnableWindow(lightInfo.explicitStartEnd); GetDlgItem(IDC_EDIT_ENDZ)->EnableWindow(lightInfo.explicitStartEnd); } } void CLightDlg::EnableControls() { GetDlgItem(IDC_CHECK_EQUALRADIUS)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_RADIUSX)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_RADIUSY)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_RADIUSZ)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_RADIO_FALLOFF)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_RADIO_FALLOFF2)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_RADIO_FALLOFF3)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_TARGETX)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_TARGETY)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_TARGETZ)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_RIGHTX)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_RIGHTY)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_RIGHTZ)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_UPX)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_UPY)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_UPZ)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_STARTX)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_STARTY)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_STARTZ)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_ENDX)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_ENDY)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_EDIT_ENDZ)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_CHECK_EXPLICITFALLOFF)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_CHECK_POINT)->EnableWindow(!lightInfo.pointLight); GetDlgItem(IDC_CHECK_PROJECTED)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_CENTERX)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_CENTERY)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_EDIT_CENTERZ)->EnableWindow(lightInfo.pointLight); GetDlgItem(IDC_CHECK_CENTER)->EnableWindow(lightInfo.pointLight); reinterpret_cast(GetDlgItem(IDC_CHECK_PROJECTED))->SetCheck(!lightInfo.pointLight); reinterpret_cast(GetDlgItem(IDC_CHECK_POINT))->SetCheck(lightInfo.pointLight); SetSpecifics(); } void CLightDlg::UpdateDialogFromLightInfo( void ) { m_hasCenter = lightInfo.hasCenter; m_bEqualRadius = lightInfo.equalRadius; m_bExplicitFalloff = lightInfo.explicitStartEnd; m_bPointLight = lightInfo.pointLight; m_bCheckProjected = !lightInfo.pointLight; m_fFallloff = lightInfo.fallOff; if (lightInfo.fallOff < 0.35) { m_nFalloff = 0; } else if (lightInfo.fallOff < 0.70) { m_nFalloff = 1; } else { m_nFalloff = 2; } //m_bFog = lightInfo.fog; m_bRotate = lightInfo.rotate; m_bShadows = lightInfo.castShadows; m_bSpecular = lightInfo.castSpecular; //m_bStrobe = lightInfo.strobe; //m_fStrobe = lightInfo.strobeSpeed; int sel = m_wndLights.FindStringExact(-1, lightInfo.strTexture); m_wndLights.SetCurSel(sel); if (sel >= 0) { m_drawMaterial->setMedia(lightInfo.strTexture); } else { m_drawMaterial->setMedia(lightInfo.strTexture); } m_bDiffuse = lightInfo.castDiffuse; m_fEndX = lightInfo.lightEnd[0]; m_fEndY = lightInfo.lightEnd[1]; m_fEndZ = lightInfo.lightEnd[2]; m_fRadiusX = lightInfo.lightRadius[0]; m_fRadiusY = lightInfo.lightRadius[1]; m_fRadiusZ = lightInfo.lightRadius[2]; m_fRightX = lightInfo.lightRight[0]; m_fRightY = lightInfo.lightRight[1]; m_fRightZ = lightInfo.lightRight[2]; //m_bRotate = lightInfo.rotate; //m_fRotate = lightInfo.rotateSpeed; m_fStartX = lightInfo.lightStart[0]; m_fStartY = lightInfo.lightStart[1]; m_fStartZ = lightInfo.lightStart[2]; m_fTargetX = lightInfo.lightTarget[0]; m_fTargetY = lightInfo.lightTarget[1]; m_fTargetZ = lightInfo.lightTarget[2]; m_fUpX = lightInfo.lightUp[0]; m_fUpY = lightInfo.lightUp[1]; m_fUpZ = lightInfo.lightUp[2]; VectorCopy(lightInfo.color, color); //m_fFogAlpha = lightInfo.fogDensity[3]; m_centerX = lightInfo.lightCenter[0]; m_centerY = lightInfo.lightCenter[1]; m_centerZ = lightInfo.lightCenter[2]; //jhefty - added parallel light updating m_bIsParallel = lightInfo.isParallel; UpdateData(FALSE); } void CLightDlg::UpdateLightInfoFromDialog( void ) { UpdateData( TRUE ); lightInfo.pointLight = ( m_bPointLight != FALSE ); lightInfo.equalRadius = ( m_bEqualRadius != FALSE ); lightInfo.explicitStartEnd = ( m_bExplicitFalloff != FALSE ); if (lightInfo.pointLight) { if (m_nFalloff == 0) { m_fFallloff = 0.0; } else if (m_nFalloff == 1) { m_fFallloff = 0.5; } else { m_fFallloff = 1.0; } } lightInfo.fallOff = m_fFallloff; //lightInfo.fog = m_bFog; lightInfo.rotate = ( m_bRotate != FALSE ); lightInfo.castShadows = ( m_bShadows != FALSE ); lightInfo.castSpecular = ( m_bSpecular != FALSE ); VectorCopy(color, lightInfo.color); lightInfo.isParallel = (m_bIsParallel == TRUE); //lightInfo.fogDensity[3] = m_fFogAlpha; //lightInfo.strobe = m_bStrobe; //lightInfo.strobeSpeed = m_fStrobe; //lightInfo.rotate = m_bRotate; //lightInfo.rotateSpeed = m_fRotate; int sel = m_wndLights.GetCurSel(); CString str(""); if (sel >= 0) { m_wndLights.GetLBText(sel, str); } lightInfo.strTexture = str; lightInfo.castDiffuse = ( m_bDiffuse != FALSE ); lightInfo.lightEnd[0] = m_fEndX; lightInfo.lightEnd[1] = m_fEndY; lightInfo.lightEnd[2] = m_fEndZ; lightInfo.lightRadius[0] = m_fRadiusX; lightInfo.lightRadius[1] = m_fRadiusY; lightInfo.lightRadius[2] = m_fRadiusZ; lightInfo.lightRight[0] = m_fRightX; lightInfo.lightRight[1] = m_fRightY; lightInfo.lightRight[2] = m_fRightZ; lightInfo.lightStart[0] = m_fStartX; lightInfo.lightStart[1] = m_fStartY; lightInfo.lightStart[2] = m_fStartZ; lightInfo.lightTarget[0] = m_fTargetX; lightInfo.lightTarget[1] = m_fTargetY; lightInfo.lightTarget[2] = m_fTargetZ; lightInfo.lightUp[0] = m_fUpX; lightInfo.lightUp[1] = m_fUpY; lightInfo.lightUp[2] = m_fUpZ; lightInfo.hasCenter = ( m_hasCenter != FALSE ); lightInfo.lightCenter[0] = m_centerX; lightInfo.lightCenter[1] = m_centerY; lightInfo.lightCenter[2] = m_centerZ; } void CLightDlg::SaveLightInfo( const idDict *differences ) { if ( com_editorActive ) { // used from Radiant for ( idEditorBrush *b = selected_brushes.next; b && b != &selected_brushes; b = b->next ) { if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) { if ( differences ) { lightInfo.ToDictFromDifferences( &b->owner->epairs, differences ); } else { lightInfo.ToDict( &b->owner->epairs ); } b->Brush_Build(); } } } else { // used in-game idList list; list.SetNum( 128 ); int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); list.SetNum( count ); for ( int i = 0; i < count; i++ ) { if ( differences ) { gameEdit->EntityChangeSpawnArgs( list[i], differences ); gameEdit->EntityUpdateChangeableSpawnArgs( list[i], NULL ); } else { idDict newArgs; lightInfo.ToDict( &newArgs ); gameEdit->EntityChangeSpawnArgs( list[i], &newArgs ); gameEdit->EntityUpdateChangeableSpawnArgs( list[i], NULL ); } gameEdit->EntityUpdateVisuals( list[i] ); } } } void CLightDlg::ColorButtons() { CRect r; CClientDC dc(this); CButton *pBtn = (CButton *)GetDlgItem(IDC_BTN_COLOR); pBtn->GetClientRect(&r); colorBitmap.DeleteObject(); colorBitmap.CreateCompatibleBitmap(&dc, r.Width(), r.Height()); CDC MemDC; MemDC.CreateCompatibleDC(&dc); CBitmap *pOldBmp = MemDC.SelectObject(&colorBitmap); { CBrush br(RGB(color[0], color[1], color[2])); MemDC.FillRect(r,&br); } dc.SelectObject(pOldBmp); pBtn->SetBitmap(HBITMAP(colorBitmap)); } void CLightDlg::LoadLightTextures() { int count = declManager->GetNumDecls( DECL_MATERIAL ); int i; const idMaterial *mat; for (i = 0; i < count; i++) { mat = declManager->MaterialByIndex(i, false); idStr str = mat->GetName(); str.ToLower(); if (str.Icmpn("lights/", strlen("lights/")) == 0 || str.Icmpn("fogs/", strlen("fogs/")) == 0) { m_wndLights.AddString(mat->GetName()); } } } BOOL CLightDlg::OnInitDialog() { CDialog::OnInitDialog(); IceDark_ApplyToDialog(this); com_editors |= EDITOR_LIGHT; UpdateDialog( true ); LoadLightTextures(); if ( com_editorActive ) { m_wndPreview.setDrawable(m_drawMaterial); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CLightDlg::OnDestroy() { com_editors &= ~EDITOR_LIGHT; return CDialog::OnDestroy(); } void CLightDlg::OnBtnTexture() { // TODO: Add your control notification handler code here } void CLightDlg::OnCheckEqualradius() { lightInfo.equalRadius = ( reinterpret_cast(GetDlgItem(IDC_CHECK_EQUALRADIUS))->GetCheck() != 0 ); SetSpecifics(); } void CLightDlg::OnCheckExplicitfalloff() { lightInfo.explicitStartEnd = ( reinterpret_cast(GetDlgItem(IDC_CHECK_EXPLICITFALLOFF))->GetCheck() != 0 ); SetSpecifics(); } void CLightDlg::OnCheckPoint() { lightInfo.DefaultPoint(); UpdateDialogFromLightInfo(); EnableControls(); } void CLightDlg::OnCheckProjected() { lightInfo.DefaultProjected(); UpdateDialogFromLightInfo(); EnableControls(); } void CLightDlg::OnRadioFalloff() { } void CLightDlg::OnOK() { UpdateLightInfoFromDialog(); SaveLightInfo( NULL ); Sys_UpdateWindows(W_ALL); CDialog::OnOK(); } idEditorEntity *SingleLightSelected() { if ( QE_SingleBrush( true, true ) ) { idEditorBrush *b = selected_brushes.next; if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) { return b->owner; } } return NULL; } void CLightDlg::UpdateDialog( bool updateChecks ) { CString title; lightInfo.Defaults(); lightInfoOriginal.Defaults (); if ( com_editorActive ) { // used from Radiant idEditorEntity *e = SingleLightSelected(); if ( e ) { lightInfo.FromDict(&e->epairs); lightInfoOriginal.FromDict(&e->epairs); //our original copy of the values that we compare against for apply differences title = "Light Editor"; } else { //find the last brush belonging to the last entity selected and use that as the source e = NULL; for ( idEditorBrush *b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) { if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) { e = b->owner; break; } } if ( e ) { lightInfo.FromDict( &e->epairs ); lightInfoOriginal.FromDict(&e->epairs); //our original copy of the values that we compaer against for apply differences title = "Light Editor - (Multiple lights selected)"; } else { title = "Light Editor - (No lights selected)"; } } } else { // used in-game idList list; list.SetNum( 128 ); int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() ); list.SetNum( count ); if ( count > 0 ) { lightInfo.FromDict( gameEdit->EntityGetSpawnArgs( list[count-1] ) ); title = "Light Editor"; } else { title = "Light Editor - (No entities selected)"; } } SetWindowText( title ); UpdateDialogFromLightInfo(); ColorButtons(); if ( updateChecks ) { EnableControls(); } } void LightEditorInit( const idDict *spawnArgs ) { if ( renderSystem->IsFullScreen() ) { common->Printf( "Cannot run the light editor in fullscreen mode.\n" "Set r_fullscreen to 0 and vid_restart.\n" ); return; } if ( g_LightDialog == NULL ) { InitAfx(); g_LightDialog = new CLightDlg(); } if ( g_LightDialog->GetSafeHwnd() == NULL ) { g_LightDialog->Create( IDD_DIALOG_LIGHT ); CRect rct; LONG lSize = sizeof( rct ); if ( LoadRegistryInfo( "Radiant::LightWindow", &rct, &lSize ) ) { g_LightDialog->SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE); } } idKeyInput::ClearStates(); g_LightDialog->ShowWindow( SW_SHOW ); g_LightDialog->SetFocus(); g_LightDialog->UpdateDialog( true ); if ( spawnArgs ) { // FIXME: select light based on spawn args } } void LightEditorRun( void ) { #if _MSC_VER >= 1300 MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!! #else MSG *msg = &m_msgCur; #endif while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) { // pump message if ( !AfxGetApp()->PumpMessage() ) { } } } void LightEditorShutdown( void ) { delete g_LightDialog; g_LightDialog = NULL; } void UpdateLightInspector() { if ( g_LightDialog && g_LightDialog->GetSafeHwnd() != NULL ) { g_LightDialog->UpdateDialog(true); //jhefty - update ALL info about the light, including check boxes } } void CLightDlg::OnApply() { UpdateLightInfoFromDialog(); SaveLightInfo( NULL ); Sys_UpdateWindows( W_ALL ); } void UpdateLightDialog( float r, float g, float b, float a ) { UpdateRadiantColor( 0.0f, 0.0f, 0.0f, 0.0f ); g_LightDialog->UpdateColor( r, g, b, a ); } void CLightDlg::UpdateColor( float r, float g, float b, float a ) { color[0] = a * r; color[1] = a * g; color[2] = a * b; ColorButtons(); UpdateLightInfoFromDialog(); SaveLightInfo( NULL ); Sys_UpdateWindows( W_CAMERA ); } void CLightDlg::OnBtnColor() { int r, g, b; float ob; r = color[0]; g = color[1]; b = color[2]; if ( DoNewColor( &r, &g, &b, &ob, UpdateLightDialog ) ) { color[0] = ob * r; color[1] = ob * g; color[2] = ob * b; ColorButtons(); } } void CLightDlg::OnCancel() { CDialog::OnCancel(); } HBRUSH CLightDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if (!pDC) { return hbr; } switch (nCtlColor) { case CTLCOLOR_DLG: pDC->SetBkColor(ICE_DARK_BG); return IceDark_BgBrush(); case CTLCOLOR_STATIC: pDC->SetTextColor(ICE_DARK_TEXT_MUTED); pDC->SetBkMode(TRANSPARENT); return IceDark_BgBrush(); case CTLCOLOR_EDIT: case CTLCOLOR_LISTBOX: pDC->SetTextColor(ICE_DARK_TEXT); pDC->SetBkColor(ICE_DARK_FIELD); return IceDark_FieldBrush(); case CTLCOLOR_BTN: pDC->SetTextColor(ICE_DARK_TEXT); pDC->SetBkColor(ICE_DARK_BG); return IceDark_BgBrush(); } return hbr; } BOOL CLightDlg::DestroyWindow() { if (GetSafeHwnd()) { CRect rct; GetWindowRect(rct); SaveRegistryInfo("Radiant::LightWindow", &rct, sizeof(rct)); } return CDialog::DestroyWindow(); } void CLightDlg::OnSelchangeComboTexture() { UpdateData(TRUE); int sel = m_wndLights.GetCurSel(); CString str; if (sel >= 0) { m_wndLights.GetLBText(sel, str); m_drawMaterial->setMedia(str); if ( com_editorActive ) { m_wndPreview.RedrawWindow(); } } Sys_UpdateWindows(W_ALL); } void CLightDlg::OnCheckCenter() { if (reinterpret_cast(GetDlgItem(IDC_CHECK_CENTER))->GetCheck()) { lightInfo.hasCenter = true; lightInfo.lightCenter.x = 0; lightInfo.lightCenter.y = 0; lightInfo.lightCenter.z = 32; } else { lightInfo.hasCenter = false; lightInfo.lightCenter.Zero(); } UpdateDialogFromLightInfo(); SetSpecifics(); } void CLightDlg::OnCheckParallel() { if ( reinterpret_cast(GetDlgItem(IDC_CHECK_PARALLEL))->GetCheck() ) { lightInfo.hasCenter = true; lightInfo.isParallel = true; lightInfo.lightCenter.x = 0; lightInfo.lightCenter.y = 0; lightInfo.lightCenter.z = 32; } else { lightInfo.isParallel = false; lightInfo.hasCenter = false; } UpdateDialogFromLightInfo(); SetSpecifics(); } //jhefty - only apply settings that are different void CLightDlg::OnApplyDifferences () { idDict differences, modified, original; UpdateLightInfoFromDialog(); lightInfo.ToDict( &modified ); lightInfoOriginal.ToDictWriteAllInfo( &original ); differences = modified; // jhefty - compile a set of modified values to apply for ( int i = 0; i < modified.GetNumKeyVals (); i ++ ) { const idKeyValue* valModified = modified.GetKeyVal ( i ); const idKeyValue* valOriginal = original.FindKey ( valModified->GetKey() ); //if it hasn't changed, remove it from the list of values to apply if ( !valOriginal || ( valModified->GetValue() == valOriginal->GetValue() ) ) { differences.Delete ( valModified->GetKey() ); } } SaveLightInfo( &differences ); lightInfoOriginal.FromDict( &modified ); Sys_UpdateWindows( W_ALL ); }