DXGL r773 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r772‎ | r773 | r774 >
Date:07:20, 13 December 2017
Author:admin
Status:new
Tags:
Comment:
Add custom resolutions to DXGL Config.
Describe scaling hacks to be added to DXGL 0.5.13.
Make handling of edit boxes a bit more robust.
Modified paths:
  • /dxgl-example.ini (modified) (history)
  • /dxglcfg/dxglcfg.cpp (modified) (history)
  • /dxglcfg/dxglcfg.rc (modified) (history)

Diff [purge]

Index: dxgl-example.ini
@@ -505,3 +505,27 @@
506506 ; GL_KHR_no_error extension is available.
507507 ; Default is false
508508 DebugDisableErrors = true
 509+
 510+[hacks]
 511+; Hacks are intended for specific scenarios, and may cause undesired effects
 512+; if used with games they do not apply to or are combined.
 513+
 514+; HackCrop640480to640400 - Boolean
 515+; Crops 640x480 display mode to 640x400. This should be used if a game
 516+; displays internally at 640x400 but sets the display mode to 640x480 and
 517+; letterboxes the output. This hack is only active in fullscreen mode at
 518+; 640x480 display mode.
 519+; Default is false
 520+HackCrop640480to640400 = false
 521+
 522+; HackAutoScale512448to640480 - Boolean
 523+; Detects when the application is rendering a 512x448 image in 640x480 mode.
 524+; This can take effect in 640x480 DR mode in ZSNES, or 640x480 mode in Zelda
 525+; Classic. If it is detected that the game is drawing outside the 512x448
 526+; boundaries, for example in ZC's menu, the hack will be temporarily disabled
 527+; to prevent cutting off these items, then automatically go back into effect
 528+; when when it is detected the out-of-bounds area is clear, like going back
 529+; in-game. This hack should only be enabled on games that render 512x448 with
 530+; black bars in 640x480 mode.
 531+; Default is false
 532+HackAutoScale512448to640480 = false
Index: dxglcfg/dxglcfg.cpp
@@ -66,6 +66,7 @@
6767 static BOOL ExtraModes_Dropdown = FALSE;
6868 static BOOL ColorDepth_Dropdown = FALSE;
6969 static HWND hDialog = NULL;
 70+static BOOL EditInterlock = FALSE;
7071
7172
7273 typedef struct
@@ -89,6 +90,7 @@
9091 DWORD current_app;
9192 BOOL tristate;
9293 TCHAR strdefault[] = _T("(global default)");
 94+TCHAR strdefaultshort[] = _T("(default)");
9395 HWND hTab;
9496 HWND hTabs[6];
9597 static int tabopen;
@@ -541,10 +543,37 @@
542544 {
543545 TCHAR number[32];
544546 if(mask) _sntprintf(number, 31, _T("%.4g"), value);
545 - else number[0] = 0;
 547+ else _tcscpy(number, strdefaultshort);
 548+ EditInterlock = TRUE;
546549 SendDlgItemMessage(hWnd, DlgItem, WM_SETTEXT, 0, (LPARAM)number);
 550+ EditInterlock = FALSE;
547551 }
548552
 553+void SetResolution(HWND hWnd, int DlgItem, const DXGLCFG *cfg, const DXGLCFG *cfgmask)
 554+{
 555+ TCHAR output[104];
 556+ TCHAR *ptr;
 557+ ptr = output;
 558+ if (!cfgmask->CustomResolutionX) _tcscpy(output, strdefault);
 559+ else
 560+ {
 561+ _itot(cfg->CustomResolutionX, ptr, 10);
 562+ _tcscat(ptr, _T("x"));
 563+ ptr = _tcschr(ptr, 0);
 564+ _itot(cfg->CustomResolutionY, ptr, 10);
 565+ if (cfgmask->CustomRefresh)
 566+ {
 567+ _tcscat(ptr, _T(", "));
 568+ ptr = _tcschr(ptr, 0);
 569+ _itot(cfg->CustomRefresh, ptr, 10);
 570+ _tcscat(ptr, _T("Hz"));
 571+ }
 572+ }
 573+ EditInterlock = TRUE;
 574+ SendDlgItemMessage(hWnd, DlgItem, WM_SETTEXT, 0, (LPARAM)output);
 575+ EditInterlock = FALSE;
 576+}
 577+
549578 __inline DWORD EncodePrimaryScale(DWORD scale)
550579 {
551580 switch (scale)
@@ -663,6 +692,149 @@
664693 }
665694 }
666695
 696+void ProcessResolutionString(LPTSTR input)
 697+{
 698+ DWORD x, y, refresh;
 699+ TCHAR buffer[32];
 700+ int ptr;
 701+ int number[3];
 702+ int length;
 703+ int i;
 704+ BOOL found = FALSE;
 705+ BOOL skip = FALSE;
 706+ length = _tcslen(input);
 707+ for (i = 0; i < length; i++)
 708+ {
 709+ if (_istdigit(input[i]))
 710+ {
 711+ found = TRUE;
 712+ ptr = i;
 713+ break;
 714+ }
 715+ }
 716+ if (!found) // Totally invalid, no numbers
 717+ {
 718+ if (current_app)
 719+ {
 720+ cfgmask->CustomResolutionX = 0;
 721+ cfgmask->CustomResolutionY = 0;
 722+ cfgmask->CustomRefresh = 0;
 723+ }
 724+ return;
 725+ }
 726+ found = FALSE;
 727+ for (i = ptr; i < length; i++)
 728+ {
 729+ if (!(_istdigit(input[i])))
 730+ {
 731+ found = TRUE;
 732+ memset(buffer, 0, 32 * sizeof(TCHAR));
 733+ _tcsncpy(buffer, &input[ptr], i - ptr);
 734+ number[0] = _ttoi(buffer);
 735+ ptr = i;
 736+ break;
 737+ }
 738+ }
 739+ if (!found) // No separating character found
 740+ {
 741+ if (current_app)
 742+ {
 743+ cfgmask->CustomResolutionX = 0;
 744+ cfgmask->CustomResolutionY = 0;
 745+ cfgmask->CustomRefresh = 0;
 746+ }
 747+ return;
 748+ }
 749+ found = FALSE;
 750+ for (i = ptr; i < length; i++)
 751+ {
 752+ if (_istdigit(input[i]))
 753+ {
 754+ found = TRUE;
 755+ ptr = i;
 756+ break;
 757+ }
 758+ }
 759+ if (!found) // Needs two numbers
 760+ {
 761+ if (current_app)
 762+ {
 763+ cfgmask->CustomResolutionX = 0;
 764+ cfgmask->CustomResolutionY = 0;
 765+ cfgmask->CustomRefresh = 0;
 766+ }
 767+ return;
 768+ }
 769+ found = FALSE;
 770+ for (i = ptr; i < length; i++)
 771+ {
 772+ if (!(_istdigit(input[i])))
 773+ {
 774+ found = TRUE;
 775+ memset(buffer, 0, 32 * sizeof(TCHAR));
 776+ _tcsncpy(buffer, &input[ptr], i - ptr);
 777+ number[1] = _ttoi(buffer);
 778+ ptr = i;
 779+ break;
 780+ }
 781+ }
 782+ if (!found)
 783+ {
 784+ number[1] = _ttoi(&input[ptr]);
 785+ skip = TRUE;
 786+ }
 787+ found = FALSE;
 788+ if (!skip)
 789+ {
 790+ for (i = ptr; i < length; i++)
 791+ {
 792+ if (_istdigit(input[i]))
 793+ {
 794+ found = TRUE;
 795+ ptr = i;
 796+ break;
 797+ }
 798+ }
 799+ }
 800+ if (!found) // Found two numbers
 801+ {
 802+ cfg->CustomResolutionX = number[0];
 803+ cfg->CustomResolutionY = number[1];
 804+ cfgmask->CustomResolutionX = 1;
 805+ cfgmask->CustomResolutionY = 1;
 806+ if (current_app) cfgmask->CustomRefresh = 0;
 807+ return;
 808+ }
 809+ found = FALSE;
 810+ for (i = ptr; i < length; i++)
 811+ {
 812+ if (!(_istdigit(input[i])))
 813+ {
 814+ found = TRUE;
 815+ memset(buffer, 0, 32 * sizeof(TCHAR));
 816+ _tcsncpy(buffer, &input[ptr], i - ptr);
 817+ number[2] = _ttoi(buffer);
 818+ ptr = i;
 819+ break;
 820+ }
 821+ }
 822+ if (!found) number[2] = _ttoi(&input[ptr]);
 823+ // Found the refresh rate too.
 824+ cfg->CustomResolutionX = number[0];
 825+ cfg->CustomResolutionY = number[1];
 826+ cfg->CustomRefresh = number[2];
 827+ cfgmask->CustomResolutionX = 1;
 828+ cfgmask->CustomResolutionY = 1;
 829+ cfgmask->CustomRefresh = 1;
 830+}
 831+
 832+void GetResolution(HWND hWnd, int dlgitem, DXGLCFG *cfg, DXGLCFG *cfgmask)
 833+{
 834+ TCHAR input[104];
 835+ SendDlgItemMessage(hWnd, dlgitem, WM_GETTEXT, 104, (LPARAM)input);
 836+ ProcessResolutionString(input);
 837+}
 838+
667839 void GetPostScaleCombo(HWND hWnd, int DlgItem, float *x, float *y, float *maskx, float *masky)
668840 {
669841 TCHAR buffer[32];
@@ -853,6 +1025,128 @@
8541026 }
8551027 }
8561028
 1029+static int CompareMode(const void *a, const void *b)
 1030+{
 1031+ DEVMODE *modea, *modeb;
 1032+ modea = (DEVMODE*)a;
 1033+ modeb = (DEVMODE*)b;
 1034+ if (modea->dmPelsWidth < modeb->dmPelsWidth) return -1;
 1035+ else if (modea->dmPelsWidth > modeb->dmPelsWidth) return 1;
 1036+ if (modea->dmPelsHeight < modeb->dmPelsHeight) return -1;
 1037+ else if (modea->dmPelsHeight > modeb->dmPelsHeight) return 1;
 1038+ if (modea->dmDisplayFrequency < modeb->dmDisplayFrequency) return -1;
 1039+ else if (modea->dmDisplayFrequency > modeb->dmDisplayFrequency) return 1;
 1040+ return 0;
 1041+}
 1042+
 1043+void DiscardDuplicateModes(DEVMODE **array, DWORD *count)
 1044+{
 1045+ DEVMODE *newarray = (DEVMODE *)malloc(sizeof(DEVMODE)*(*count));
 1046+ if (!newarray) return;
 1047+ DWORD newcount = 0;
 1048+ bool match;
 1049+ for (DWORD x = 0; x < (*count); x++)
 1050+ {
 1051+ match = false;
 1052+ memcpy(&newarray[newcount], &(*array)[x], sizeof(DEVMODE));
 1053+ for (int y = newcount; y > 0; y--)
 1054+ {
 1055+ if ((*array)[x].dmDisplayFrequency == newarray[y - 1].dmDisplayFrequency &&
 1056+ (*array)[x].dmPelsWidth == newarray[y - 1].dmPelsWidth &&
 1057+ (*array)[x].dmPelsHeight == newarray[y - 1].dmPelsHeight)
 1058+ {
 1059+ match = true;
 1060+ break;
 1061+ }
 1062+ }
 1063+ if (!match) newcount++;
 1064+ }
 1065+ DEVMODE *newarray2 = (DEVMODE*)realloc(newarray, sizeof(DEVMODE)*newcount);
 1066+ if (newarray2) newarray = newarray2;
 1067+ free(*array);
 1068+ *array = newarray;
 1069+ *count = newcount;
 1070+}
 1071+
 1072+LRESULT CALLBACK ModeListCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 1073+{
 1074+ int newmodex, newmodey, newmoderefresh;
 1075+ DEVMODE mode;
 1076+ DEVMODE *modes;
 1077+ DEVMODE *tmpmodes;
 1078+ DWORD modenum;
 1079+ DWORD modemax;
 1080+ TCHAR str[64];
 1081+ TCHAR *ptr;
 1082+ int i, j;
 1083+ switch (Msg)
 1084+ {
 1085+ case WM_INITDIALOG:
 1086+ modenum = 0;
 1087+ modemax = 128;
 1088+ modes = (DEVMODE*)malloc(128 * sizeof(DEVMODE));
 1089+ while (EnumDisplaySettings(NULL, modenum++, &mode))
 1090+ {
 1091+ modes[modenum - 1] = mode;
 1092+ if (modenum >= modemax)
 1093+ {
 1094+ modemax += 128;
 1095+ tmpmodes = (DEVMODE*)realloc(modes, modemax * sizeof(DEVMODE));
 1096+ if (tmpmodes == NULL)
 1097+ {
 1098+ free(modes);
 1099+ MessageBox(hWnd, _T("Out of memory!"), _T("Fatal error"), MB_OK | MB_ICONSTOP);
 1100+ ExitProcess(ERROR_NOT_ENOUGH_MEMORY);
 1101+ }
 1102+ modes = tmpmodes;
 1103+ }
 1104+ }
 1105+ DiscardDuplicateModes(&modes, &modenum);
 1106+ qsort(modes, modenum-1, sizeof(DEVMODE), CompareMode);
 1107+ for (i = 0; i < modenum-1; i++)
 1108+ {
 1109+ ptr = str;
 1110+ _itot(modes[i].dmPelsWidth, ptr, 10);
 1111+ _tcscat(ptr, _T("x"));
 1112+ ptr = _tcschr(ptr, 0);
 1113+ _itot(modes[i].dmPelsHeight, ptr, 10);
 1114+ _tcscat(ptr, _T(", "));
 1115+ ptr = _tcschr(ptr, 0);
 1116+ _itot(modes[i].dmDisplayFrequency, ptr, 10);
 1117+ _tcscat(ptr, _T("Hz"));
 1118+ SendDlgItemMessage(hWnd, IDC_MODELIST, LB_ADDSTRING, 0, (LPARAM)str);
 1119+ }
 1120+ free(modes);
 1121+ return TRUE;
 1122+ case WM_CLOSE:
 1123+ EndDialog(hWnd, 0);
 1124+ return TRUE;
 1125+ case WM_COMMAND:
 1126+ switch (LOWORD(wParam))
 1127+ {
 1128+ case IDC_MODELIST:
 1129+ if ((HIWORD(wParam) == LBN_SELCHANGE))
 1130+ EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
 1131+ break;
 1132+ case IDOK:
 1133+ SendDlgItemMessage(hWnd, IDC_MODELIST, LB_GETTEXT,
 1134+ SendDlgItemMessage(hWnd, IDC_MODELIST, LB_GETCURSEL, 0, 0), (LPARAM)str);
 1135+ ProcessResolutionString(str);
 1136+ EndDialog(hWnd, 1);
 1137+ return TRUE;
 1138+ case IDCANCEL:
 1139+ EndDialog(hWnd, 0);
 1140+ return TRUE;
 1141+ default:
 1142+ break;
 1143+ }
 1144+ return TRUE;
 1145+ default:
 1146+ return DefWindowProc(hWnd, Msg, wParam, lParam);
 1147+ }
 1148+ return 0;
 1149+}
 1150+
8571151 LRESULT CALLBACK DisplayTabCallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
8581152 {
8591153 DRAWITEMSTRUCT* drawitem;
@@ -1133,9 +1427,12 @@
11341428 case IDC_FIXEDSCALEX:
11351429 if (HIWORD(wParam) == EN_CHANGE)
11361430 {
1137 - cfg->DisplayMultiplierX = GetFloat(hWnd, IDC_FIXEDSCALEX, &cfgmask->DisplayMultiplierX);
1138 - EnableWindow(GetDlgItem(hDialog, IDC_APPLY), TRUE);
1139 - *dirty = TRUE;
 1431+ if (!EditInterlock)
 1432+ {
 1433+ cfg->DisplayMultiplierX = GetFloat(hWnd, IDC_FIXEDSCALEX, &cfgmask->DisplayMultiplierX);
 1434+ EnableWindow(GetDlgItem(hDialog, IDC_APPLY), TRUE);
 1435+ *dirty = TRUE;
 1436+ }
11401437 }
11411438 if (HIWORD(wParam) == EN_KILLFOCUS)
11421439 {
@@ -1145,9 +1442,12 @@
11461443 case IDC_FIXEDSCALEY:
11471444 if (HIWORD(wParam) == EN_CHANGE)
11481445 {
1149 - cfg->DisplayMultiplierY = GetFloat(hWnd, IDC_FIXEDSCALEY, &cfgmask->DisplayMultiplierY);
1150 - EnableWindow(GetDlgItem(hDialog, IDC_APPLY), TRUE);
1151 - *dirty = TRUE;
 1446+ if (!EditInterlock)
 1447+ {
 1448+ cfg->DisplayMultiplierY = GetFloat(hWnd, IDC_FIXEDSCALEY, &cfgmask->DisplayMultiplierY);
 1449+ EnableWindow(GetDlgItem(hDialog, IDC_APPLY), TRUE);
 1450+ *dirty = TRUE;
 1451+ }
11521452 }
11531453 if (HIWORD(wParam) == EN_KILLFOCUS)
11541454 {
@@ -1154,6 +1454,26 @@
11551455 SetFloat3place(hWnd, IDC_FIXEDSCALEY, cfg->DisplayMultiplierY, cfgmask->DisplayMultiplierY);
11561456 }
11571457 break;
 1458+ case IDC_CUSTOMMODE:
 1459+ if (HIWORD(wParam) == EN_CHANGE)
 1460+ {
 1461+ if (!EditInterlock)
 1462+ {
 1463+ GetResolution(hWnd, IDC_CUSTOMMODE, cfg, cfgmask);
 1464+ EnableWindow(GetDlgItem(hDialog, IDC_APPLY), TRUE);
 1465+ *dirty = TRUE;
 1466+ }
 1467+ }
 1468+ if (HIWORD(wParam) == EN_KILLFOCUS)
 1469+ {
 1470+ SetResolution(hWnd, IDC_CUSTOMMODE, cfg, cfgmask);
 1471+ }
 1472+ break;
 1473+ case IDC_SETMODE:
 1474+ {
 1475+ if (DialogBox(hinstance, MAKEINTRESOURCE(IDD_MODELIST), hWnd, (DLGPROC)ModeListCallback))
 1476+ SetResolution(hWnd, IDC_CUSTOMMODE, cfg, cfgmask);
 1477+ }
11581478 case IDC_SCALE:
11591479 cfg->scalingfilter = GetCombo(hWnd, IDC_SCALE, &cfgmask->scalingfilter);
11601480 EnableWindow(GetDlgItem(hDialog, IDC_APPLY), TRUE);
@@ -1929,6 +2249,8 @@
19302250 // custom scale
19312251 SetFloat3place(hTabs[0], IDC_FIXEDSCALEX, cfg->DisplayMultiplierX, cfgmask->DisplayMultiplierX);
19322252 SetFloat3place(hTabs[0], IDC_FIXEDSCALEY, cfg->DisplayMultiplierY, cfgmask->DisplayMultiplierY);
 2253+ // custom resolution
 2254+ SetResolution(hTabs[0], IDC_CUSTOMMODE, cfg, cfgmask);
19332255 // fullscreen window mode
19342256 _tcscpy(buffer, _T("Exclusive fullscreen"));
19352257 SendDlgItemMessage(hTabs[0], IDC_FULLMODE, CB_ADDSTRING, 0, (LPARAM)buffer);
@@ -2248,6 +2570,12 @@
22492571 /*_tcscpy(buffer, _T("Disable OpenGL errors (OpenGL 4.6+)"));
22502572 SendDlgItemMessage(hTabs[4], IDC_DEBUGLIST, LB_ADDSTRING, 0, (LPARAM)buffer);*/
22512573
 2574+ // Hacks
 2575+ _tcscpy(buffer, _T("Crop 640x480 to 640x400"));
 2576+ SendDlgItemMessage(hTabs[5], IDC_HACKSLIST, LB_ADDSTRING, 0, (LPARAM)buffer);
 2577+ _tcscpy(buffer, _T("Expand 512x448 to 640x480 when border is blank"));
 2578+ SendDlgItemMessage(hTabs[5], IDC_HACKSLIST, LB_ADDSTRING, 0, (LPARAM)buffer);
 2579+
22522580 EnableWindow(GetDlgItem(hWnd, IDC_APPLY), FALSE);
22532581
22542582 // Check install path
@@ -2651,6 +2979,7 @@
26522980 }
26532981 SetFloat3place(hTabs[0], IDC_FIXEDSCALEX, cfg->DisplayMultiplierX, cfgmask->DisplayMultiplierX);
26542982 SetFloat3place(hTabs[0], IDC_FIXEDSCALEY, cfg->DisplayMultiplierY, cfgmask->DisplayMultiplierY);
 2983+ SetResolution(hTabs[0], IDC_CUSTOMMODE, cfg, cfgmask);
26552984 SetCombo(hTabs[1], IDC_POSTSCALE, cfg->postfilter, cfgmask->postfilter, tristate);
26562985 SetPostScaleCombo(hTabs[1], IDC_POSTSCALESIZE, cfg->postsizex, cfg->postsizey,
26572986 cfgmask->postsizex , cfgmask->postsizey, tristate);
Index: dxglcfg/dxglcfg.rc
@@ -460,9 +460,9 @@
461461 CAPTION "Set display resolution"
462462 FONT 8, "Ms Shell Dlg"
463463 {
464 - LISTBOX IDC_MODELIST, 5, 5, 119, 85, WS_TABSTOP | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_SORT | LBS_NOTIFY, WS_EX_LEFT
465 - PUSHBUTTON "Cancel", IDCANCEL, 129, 24, 50, 14, 0, WS_EX_LEFT
466 - DEFPUSHBUTTON "OK", IDOK, 129, 7, 50, 14, 0, WS_EX_LEFT
 464+ LISTBOX IDC_MODELIST, 5, 5, 119, 85, WS_TABSTOP | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_NOTIFY, WS_EX_LEFT
 465+ PUSHBUTTON "Cancel", IDCANCEL, 129, 24, 50, 14, WS_TABSTOP, WS_EX_LEFT
 466+ DEFPUSHBUTTON "OK", IDOK, 129, 7, 50, 14, WS_TABSTOP | WS_DISABLED, WS_EX_LEFT
467467 }
468468
469469