/******************************************************************************** Copyright (C) 2012 Hugh Bailey Copyright (C) 2013 Lucas Murray This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********************************************************************************/ #include "Settings.h" //============================================================================ // Helpers BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, List &monitors); FARPROC editProc = NULL; LRESULT WINAPI ResolutionEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if( ((message == WM_KEYDOWN) && (wParam == VK_RETURN)) || (message == WM_KILLFOCUS) ) { String strText = GetEditText(hwnd); if(ValidIntString(strText)) { int iVal = strText.ToInt(); if(iVal < 128) strText = TEXT("128"); else if(iVal > 4096) strText = TEXT("4096"); else return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam); } else strText = TEXT("128"); SetWindowText(hwnd, strText); } return CallWindowProc((WNDPROC)editProc, hwnd, message, wParam, lParam); } const int multiplierCount = 9; const float downscaleMultipliers[multiplierCount] = {1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.25f, 2.5f, 2.75f, 3.0f}; //============================================================================ // SettingsVideo class SettingsVideo::SettingsVideo() : SettingsPane() { } SettingsVideo::~SettingsVideo() { } CTSTR SettingsVideo::GetCategory() const { static CTSTR name = Str("Settings.Video"); return name; } HWND SettingsVideo::CreatePane(HWND parentHwnd) { hwnd = CreateDialogParam(hinstMain, MAKEINTRESOURCE(IDD_SETTINGS_VIDEO), parentHwnd, (DLGPROC)DialogProc, (LPARAM)this); return hwnd; } void SettingsVideo::DestroyPane() { DestroyWindow(hwnd); hwnd = NULL; } void SettingsVideo::RefreshDownscales(HWND hwnd, int cx, int cy) { int lastID = (int)SendMessage(hwnd, CB_GETCURSEL, 0, 0); SendMessage(hwnd, CB_RESETCONTENT, 0, 0); float downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale")); bool bFoundVal = false; for(int i=0; iSetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); if(lastID == CB_ERR) SendMessage(hwnd, CB_SETCURSEL, 0, 0); SetChangedSettings(true); } if(lastID != CB_ERR) SendMessage(hwnd, CB_SETCURSEL, lastID, 0); } void SettingsVideo::RefreshFilters(HWND hwndParent, bool bGetConfig) { HWND hwndFilter = GetDlgItem(hwndParent, IDC_FILTER); HWND hwndDownscale = GetDlgItem(hwndParent, IDC_DOWNSCALE); int curFilter; if(bGetConfig) curFilter = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0); else curFilter = (int)SendMessage(GetDlgItem(hwnd, IDC_FILTER), CB_GETCURSEL, 0, 0); float downscale = 1.0f; int curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_DOWNSCALE), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) downscale = downscaleMultipliers[curSel]; SendMessage(hwndFilter, CB_RESETCONTENT, 0, 0); if(downscale < 2.01) { SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Bilinear")); SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Bicubic")); SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Lanczos")); SendMessage(hwndFilter, CB_SETCURSEL, curFilter, 0); } else { SendMessage(hwndFilter, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Video.Filter.Bilinear")); SendMessage(hwndFilter, CB_SETCURSEL, 0, 0); } EnableWindow(hwndFilter, (downscale > 1.01)); } void SettingsVideo::ApplySettings() { int curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) AppConfig->SetInt(TEXT("Video"), TEXT("Monitor"), curSel); int iVal = GetEditText(GetDlgItem(hwnd, IDC_SIZEX)).ToInt(); if(iVal >= 128) AppConfig->SetInt(TEXT("Video"), TEXT("BaseWidth"), iVal); iVal = GetEditText(GetDlgItem(hwnd, IDC_SIZEY)).ToInt(); if(iVal >= 128) AppConfig->SetInt(TEXT("Video"), TEXT("BaseHeight"), iVal); BOOL bDisableAero = SendMessage(GetDlgItem(hwnd, IDC_DISABLEAERO), BM_GETCHECK, 0, 0) == BST_CHECKED ? TRUE : FALSE; AppConfig->SetInt(TEXT("Video"), TEXT("DisableAero"), bDisableAero); BOOL bFailed; int fps = (int)SendMessage(GetDlgItem(hwnd, IDC_FPS), UDM_GETPOS32, 0, (LPARAM)&bFailed); AppConfig->SetInt(TEXT("Video"), TEXT("FPS"), (bFailed) ? 30 : fps); curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_DOWNSCALE), CB_GETCURSEL, 0, 0); if(curSel != CB_ERR) AppConfig->SetFloat(TEXT("Video"), TEXT("Downscale"), downscaleMultipliers[curSel]); curSel = (int)SendMessage(GetDlgItem(hwnd, IDC_FILTER), CB_GETCURSEL, 0, 0); if(curSel == CB_ERR) curSel = 0; AppConfig->SetInt(TEXT("Video"), TEXT("Filter"), curSel); int gammaVal = (int)SendMessage(GetDlgItem(hwnd, IDC_GAMMA), TBM_GETPOS, 0, 0); AppConfig->SetInt(TEXT("Video"), TEXT("Gamma"), gammaVal); //------------------------------------ if(!App->bRunning) App->ResizeWindow(false); } void SettingsVideo::CancelSettings() { } INT_PTR SettingsVideo::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndTemp; switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //-------------------------------------------- HWND hwndToolTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, NULL, hinstMain, NULL); TOOLINFO ti; zero(&ti, sizeof(ti)); ti.cbSize = sizeof(ti); ti.uFlags = TTF_SUBCLASS|TTF_IDISHWND; ti.hwnd = hwnd; SendMessage(hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 500); SendMessage(hwndToolTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, 8000); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_MONITOR); App->monitors.Clear(); EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)MonitorInfoEnumProc, (LPARAM)&App->monitors); for(UINT i=0; imonitors.Num(); i++) SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)IntString(i+1).Array()); int monitorID = LoadSettingComboInt(hwndTemp, TEXT("Video"), TEXT("Monitor"), 0, App->monitors.Num()-1); if(monitorID > (int)App->monitors.Num()) monitorID = 0; //-------------------------------------------- SendMessage(GetDlgItem(hwnd, IDC_USECUSTOM), BM_SETCHECK, BST_CHECKED, 0); EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), FALSE); //-------------------------------------------- int cx, cy; if(!AppConfig->HasKey(TEXT("Video"), TEXT("BaseWidth")) || !AppConfig->HasKey(TEXT("Video"), TEXT("BaseHeight"))) { cx = App->monitors[monitorID].rect.right - App->monitors[monitorID].rect.left; cy = App->monitors[monitorID].rect.bottom - App->monitors[monitorID].rect.top; AppConfig->SetInt(TEXT("Video"), TEXT("BaseWidth"), cx); AppConfig->SetInt(TEXT("Video"), TEXT("BaseHeight"), cy); } else { cx = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth")); cy = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight")); if(cx < 128) cx = 128; else if(cx > 4096) cx = 4096; if(cy < 128) cy = 128; else if(cy > 4096) cy = 4096; } hwndTemp = GetDlgItem(hwnd, IDC_SIZEX); editProc = (FARPROC)GetWindowLongPtr(hwndTemp, GWLP_WNDPROC); SetWindowLongPtr(hwndTemp, GWLP_WNDPROC, (LONG_PTR)ResolutionEditSubclassProc); SetWindowText(hwndTemp, IntString(cx).Array()); hwndTemp = GetDlgItem(hwnd, IDC_SIZEY); SetWindowLongPtr(hwndTemp, GWLP_WNDPROC, (LONG_PTR)ResolutionEditSubclassProc); SetWindowText(hwndTemp, IntString(cy).Array()); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_DISABLEAERO); if(OSGetVersion() == 8) EnableWindow(hwndTemp, FALSE); BOOL bDisableAero = AppConfig->GetInt(TEXT("Video"), TEXT("DisableAero"), 0); SendMessage(hwndTemp, BM_SETCHECK, bDisableAero ? BST_CHECKED : 0, 0); ti.lpszText = (LPWSTR)Str("Settings.Video.DisableAeroTooltip"); ti.uId = (UINT_PTR)hwndTemp; SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); //-------------------------------------------- BOOL bUnlockFPS = AppConfig->GetInt(TEXT("Video"), TEXT("UnlockFPS")); int topFPS = bUnlockFPS ? 120 : 60; hwndTemp = GetDlgItem(hwnd, IDC_FPS); SendMessage(hwndTemp, UDM_SETRANGE32, 10, topFPS); int fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 30); if(!AppConfig->HasKey(TEXT("Video"), TEXT("FPS"))) { AppConfig->SetInt(TEXT("Video"), TEXT("FPS"), 30); fps = 30; } else if(fps < 10) { AppConfig->SetInt(TEXT("Video"), TEXT("FPS"), 10); fps = 10; } else if(fps > topFPS) { AppConfig->SetInt(TEXT("Video"), TEXT("FPS"), topFPS); fps = topFPS; } SendMessage(hwndTemp, UDM_SETPOS32, 0, fps); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_DOWNSCALE); RefreshDownscales(hwndTemp, cx, cy); ti.lpszText = (LPWSTR)Str("Settings.Video.DownscaleTooltip"); ti.uId = (UINT_PTR)hwndTemp; SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti); //-------------------------------------------- RefreshFilters(hwnd, true); //-------------------------------------------- ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); SetChangedSettings(false); return TRUE; } case WM_COMMAND: { bool bDataChanged = false; switch(LOWORD(wParam)) { case IDC_MONITOR: { if(HIWORD(wParam) != CBN_SELCHANGE) break; int sel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0); if(sel != CB_ERR) { if(sel >= (int)App->monitors.Num()) sel = 0; MonitorInfo &monitor = App->monitors[sel]; int cx, cy; cx = monitor.rect.right - monitor.rect.left; cy = monitor.rect.bottom - monitor.rect.top; SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(cx).Array()); SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(cy).Array()); } break; } case IDC_USECUSTOM: SendMessage(GetDlgItem(hwnd, IDC_SIZEX), EM_SETREADONLY, FALSE, 0); SendMessage(GetDlgItem(hwnd, IDC_SIZEY), EM_SETREADONLY, FALSE, 0); EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), FALSE); break; case IDC_USEMONITOR: { SendMessage(GetDlgItem(hwnd, IDC_SIZEX), EM_SETREADONLY, TRUE, 0); SendMessage(GetDlgItem(hwnd, IDC_SIZEY), EM_SETREADONLY, TRUE, 0); EnableWindow(GetDlgItem(hwnd, IDC_MONITOR), TRUE); int sel = (int)SendMessage(GetDlgItem(hwnd, IDC_MONITOR), CB_GETCURSEL, 0, 0); if(sel != CB_ERR) { if(sel >= (int)App->monitors.Num()) sel = 0; MonitorInfo &monitor = App->monitors[sel]; int cx, cy; cx = monitor.rect.right - monitor.rect.left; cy = monitor.rect.bottom - monitor.rect.top; SetWindowText(GetDlgItem(hwnd, IDC_SIZEX), IntString(cx).Array()); SetWindowText(GetDlgItem(hwnd, IDC_SIZEY), IntString(cy).Array()); } break; } case IDC_SIZEX: case IDC_SIZEY: { if(HIWORD(wParam) != EN_CHANGE) break; String strInt = GetEditText((HWND)lParam); int iVal = strInt.ToInt(); int cx = GetEditText(GetDlgItem(hwnd, IDC_SIZEX)).ToInt(); int cy = GetEditText(GetDlgItem(hwnd, IDC_SIZEY)).ToInt(); if(cx < 128) cx = 128; else if(cx > 4096) cx = 4096; if(cy < 128) cy = 128; else if(cy > 4096) cy = 4096; RefreshDownscales(GetDlgItem(hwnd, IDC_DOWNSCALE), cx, cy); bDataChanged = true; break; } case IDC_DISABLEAERO: if(HIWORD(wParam) == BN_CLICKED) bDataChanged = true; break; case IDC_FPS_EDIT: if(HIWORD(wParam) == EN_CHANGE) bDataChanged = true; break; case IDC_FILTER: if(HIWORD(wParam) == CBN_SELCHANGE) bDataChanged = true; break; case IDC_DOWNSCALE: if(HIWORD(wParam) == CBN_SELCHANGE) { bDataChanged = true; RefreshFilters(hwnd, false); } break; } if(bDataChanged) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; } } return FALSE; }