DXGL r824 - Code Review

Jump to navigation Jump to search
Repository:DXGL
Revision:r823‎ | r824 | r825 >
Date:01:23, 1 July 2018
Author:admin
Status:new
Tags:
Comment:
Fully implement saving .ini files.
Move some .ini entries to more appropriate sections.
Remove whitespace from sample .ini file.
Modified paths:
  • /cfgmgr/cfgmgr.c (modified) (history)
  • /cfgmgr/cfgmgr.h (modified) (history)
  • /dxgl-example.ini (modified) (history)
  • /dxglcfg/dxglcfg.cpp (modified) (history)

Diff [purge]

Index: cfgmgr/cfgmgr.c
@@ -42,6 +42,18 @@
4343
4444 DXGLCFG defaultmask;
4545
 46+#define INISECTION_NULL 0
 47+#define INISECTION_SYSTEM 1
 48+#define INISECTION_DISPLAY 2
 49+#define INISECTION_SCALING 3
 50+#define INISECTION_POSTPROCESS 4
 51+#define INISECTION_D3D 5
 52+#define INISECTION_ADVANCED 6
 53+#define INISECTION_DEBUG 7
 54+#define INISECTION_HACKS 8
 55+
 56+static int ini_currentsection = 0;
 57+
4658 /**
4759 * Gets the hexadecimal digit for a number; the number must be less than 16
4860 * or 0x10.
@@ -1046,6 +1058,13 @@
10471059 cfg->AddModes = INIIntValue(value);
10481060 }
10491061 if (!_stricmp(name, "SortModes")) cfg->SortModes = INIIntValue(value);
 1062+ if (!_stricmp(name, "VSync")) cfg->vsync = INIIntValue(value);
 1063+ if (!_stricmp(name, "CustomResolutionX")) cfg->CustomResolutionX = INIIntValue(value);
 1064+ if (!_stricmp(name, "CustomResolutionY")) cfg->CustomResolutionY = INIIntValue(value);
 1065+ if (!_stricmp(name, "CustomRefresh")) cfg->CustomRefresh = INIIntValue(value);
 1066+ if (!_stricmp(name, "DisplayMultiplierX")) cfg->DisplayMultiplierX = INIFloatValue(value);
 1067+ if (!_stricmp(name, "DisplayMultiplierY")) cfg->DisplayMultiplierY = INIFloatValue(value);
 1068+ if (!_stricmp(name, "SingleBufferDevice")) cfg->SingleBufferDevice = INIBoolValue(value);
10501069 }
10511070 if (!_stricmp(section, "scaling"))
10521071 {
@@ -1058,11 +1077,6 @@
10591078 if (!_stricmp(name, "PrimaryScaleY")) cfg->primaryscaley = INIFloatValue(value);
10601079 if (!_stricmp(name, "ScreenAspect")) cfg->aspect = INIAspectValue(value);
10611080 if (!_stricmp(name, "DPIScale")) cfg->DPIScale = INIIntValue(value);
1062 - if (!_stricmp(name, "CustomResolutionX")) cfg->CustomResolutionX = INIIntValue(value);
1063 - if (!_stricmp(name, "CustomResolutionY")) cfg->CustomResolutionY = INIIntValue(value);
1064 - if (!_stricmp(name, "CustomRefresh")) cfg->CustomRefresh = INIIntValue(value);
1065 - if (!_stricmp(name, "DisplayMultiplierX")) cfg->DisplayMultiplierX = INIFloatValue(value);
1066 - if (!_stricmp(name, "DisplayMultiplierY")) cfg->DisplayMultiplierY = INIFloatValue(value);
10671081 }
10681082 if (!_stricmp(section, "postprocess"))
10691083 {
@@ -1091,10 +1105,8 @@
10921106 }
10931107 if (!_stricmp(section, "advanced"))
10941108 {
1095 - if (!_stricmp(name, "VSync")) cfg->vsync = INIIntValue(value);
10961109 if (!_stricmp(name, "TextureFormat")) cfg->TextureFormat = INIIntValue(value);
10971110 if (!_stricmp(name, "TexUpload")) cfg->TexUpload = INIIntValue(value);
1098 - if (!_stricmp(name, "SingleBufferDevice")) cfg->SingleBufferDevice = INIBoolValue(value);
10991111 if (!_stricmp(name, "WindowPosition")) cfg->WindowPosition = INIIntValue(value);
11001112 if (!_stricmp(name, "RememberWindowSize")) cfg->RememberWindowSize = INIBoolValue(value);
11011113 if (!_stricmp(name, "RememberWindowPosition")) cfg->RememberWindowPosition = INIBoolValue(value);
@@ -1147,12 +1159,398 @@
11481160 }
11491161 }
11501162
1151 -DWORD WriteINI(DXGLCFG *cfg, DXGLCFG *mask, LPCTSTR path)
 1163+void SetINISection(HANDLE file, int section)
11521164 {
1153 - //TODO: Write INI file.
1154 - return ERROR_CALL_NOT_IMPLEMENTED;
 1165+ char buffer[32];
 1166+ int buffersize;
 1167+ int outsize;
 1168+ if (section != ini_currentsection)
 1169+ {
 1170+ ini_currentsection = section;
 1171+ switch (section)
 1172+ {
 1173+ case INISECTION_SYSTEM:
 1174+ strcpy(buffer, "\r\n[system]\r\n");
 1175+ break;
 1176+ case INISECTION_DISPLAY:
 1177+ strcpy(buffer, "\r\n[display]\r\n");
 1178+ break;
 1179+ case INISECTION_SCALING:
 1180+ strcpy(buffer, "\r\n[scaling]\r\n");
 1181+ break;
 1182+ case INISECTION_POSTPROCESS:
 1183+ strcpy(buffer, "\r\n[postprocess]\r\n");
 1184+ break;
 1185+ case INISECTION_D3D:
 1186+ strcpy(buffer, "\r\n[d3d]\r\n");
 1187+ break;
 1188+ case INISECTION_ADVANCED:
 1189+ strcpy(buffer, "\r\n[advanced]\r\n");
 1190+ break;
 1191+ case INISECTION_DEBUG:
 1192+ strcpy(buffer, "\r\n[debug]\r\n");
 1193+ break;
 1194+ case INISECTION_HACKS:
 1195+ strcpy(buffer, "\r\n[hacks]\r\n");
 1196+ break;
 1197+ default:
 1198+ return;
 1199+ }
 1200+ buffersize = strlen(buffer);
 1201+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1202+ }
11551203 }
11561204
 1205+void INIWriteBool(HANDLE file, const char *name, BOOL value, BOOL mask, int section)
 1206+{
 1207+ char buffer[256];
 1208+ int buffersize;
 1209+ int outsize;
 1210+ if (mask)
 1211+ {
 1212+ SetINISection(file, section);
 1213+ strcpy(buffer, name);
 1214+ strcat(buffer, "=");
 1215+ if (value) strcat(buffer, "true");
 1216+ else strcat(buffer, "false");
 1217+ strcat(buffer, "\r\n");
 1218+ buffersize = strlen(buffer);
 1219+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1220+ }
 1221+}
 1222+
 1223+void INIWriteInt(HANDLE file, const char *name, DWORD value, DWORD mask, int section)
 1224+{
 1225+ char buffer[256];
 1226+ char number[32];
 1227+ int buffersize;
 1228+ int outsize;
 1229+ if (mask)
 1230+ {
 1231+ SetINISection(file, section);
 1232+ strcpy(buffer, name);
 1233+ strcat(buffer, "=");
 1234+ itoa(value, number, 10);
 1235+ strcat(buffer, number);
 1236+ strcat(buffer, "\r\n");
 1237+ buffersize = strlen(buffer);
 1238+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1239+ }
 1240+}
 1241+
 1242+void INIWriteHex(HANDLE file, const char *name, DWORD value, DWORD mask, int section)
 1243+{
 1244+ char buffer[256];
 1245+ char number[32];
 1246+ int buffersize;
 1247+ int outsize;
 1248+ if (mask)
 1249+ {
 1250+ SetINISection(file, section);
 1251+ strcpy(buffer, name);
 1252+ strcat(buffer, "=0x");
 1253+ itoa(value, number, 16);
 1254+ strcat(buffer, number);
 1255+ strcat(buffer, "\r\n");
 1256+ buffersize = strlen(buffer);
 1257+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1258+ }
 1259+}
 1260+
 1261+void INIWriteFloat(HANDLE file, const char *name, float value, float mask, int digits, int section)
 1262+{
 1263+ char buffer[256];
 1264+ char number[32];
 1265+ char floatformat[16];
 1266+ int buffersize;
 1267+ int outsize;
 1268+ if (mask)
 1269+ {
 1270+ SetINISection(file, section);
 1271+ strcpy(buffer, name);
 1272+ strcat(buffer, "=");
 1273+ itoa(digits, number, 10);
 1274+ strcpy(floatformat, "%.");
 1275+ strcat(floatformat, number);
 1276+ strcat(floatformat, "g");
 1277+ _snprintf(number, 31, floatformat, value);
 1278+ itoa(value, number, 10);
 1279+ strcat(buffer, number);
 1280+ strcat(buffer, "\r\n");
 1281+ buffersize = strlen(buffer);
 1282+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1283+ }
 1284+}
 1285+
 1286+void FloatToAspectString(float f, char *aspect)
 1287+{
 1288+ double integer;
 1289+ double dummy;
 1290+ double fract;
 1291+ char denominator[5];
 1292+ int i;
 1293+ if (_isnan(f)) f = 0.0f; //Handle NAN condition
 1294+ if (f >= 1000.0f) // Clamp ridiculously wide aspects
 1295+ {
 1296+ strcpy(aspect, "1000:1");
 1297+ return;
 1298+ }
 1299+ if (f < 0.001f) // Exclude ridiculously tall aspects, zero, and negative
 1300+ {
 1301+ strcpy(aspect, "Default");
 1302+ return;
 1303+ }
 1304+ // Handle common aspects
 1305+ if (fabs(f - 1.25f) < 0.0001f)
 1306+ {
 1307+ strcpy(aspect, "5:4");
 1308+ return;
 1309+ }
 1310+ if (fabs(f - 1.3333333f) < 0.0001f)
 1311+ {
 1312+ strcpy(aspect, "4:3");
 1313+ return;
 1314+ }
 1315+ if (fabs(f - 1.6f) < 0.0001f)
 1316+ {
 1317+ strcpy(aspect, "16:10");
 1318+ return;
 1319+ }
 1320+ if (fabs(f - 1.7777777) < 0.0001f)
 1321+ {
 1322+ strcpy(aspect, "16:9");
 1323+ return;
 1324+ }
 1325+ if (fabs(f - 1.9333333) < 0.0001f)
 1326+ {
 1327+ strcpy(aspect, "256:135");
 1328+ return;
 1329+ }
 1330+ fract = modf(f, &integer);
 1331+ if (fract < 0.0001f) //Handle integer aspects
 1332+ {
 1333+ _itoa((int)integer, aspect, 10);
 1334+ strcat(aspect, ":1");
 1335+ return;
 1336+ }
 1337+ // Finally try from 2 to 1000
 1338+ for (i = 2; i < 1000; i++)
 1339+ {
 1340+ if (fabs(modf(fract*i, &dummy)) < 0.0001f)
 1341+ {
 1342+ _itoa((f*i) + .5f, aspect, 10);
 1343+ _itoa(i, denominator, 10);
 1344+ strcat(aspect, ":");
 1345+ strcat(aspect, denominator);
 1346+ return;
 1347+ }
 1348+ }
 1349+ // Cannot find a reasonable fractional aspect, so display as decimal.
 1350+ sprintf(aspect, "%.6g", f);
 1351+}
 1352+
 1353+void INIWriteAspect(HANDLE file, const char *name, float value, float mask, int section)
 1354+{
 1355+ char buffer[256];
 1356+ char number[32];
 1357+ char floatformat[16];
 1358+ int buffersize;
 1359+ int outsize;
 1360+ if (mask)
 1361+ {
 1362+ SetINISection(file, section);
 1363+ strcpy(buffer, name);
 1364+ strcat(buffer, "=");
 1365+ FloatToAspectString(value,number);
 1366+ strcat(buffer, number);
 1367+ strcat(buffer, "\r\n");
 1368+ buffersize = strlen(buffer);
 1369+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1370+ }
 1371+}
 1372+
 1373+void INIWriteString(HANDLE file, const char *name, const char *value, DWORD mask, int section)
 1374+{
 1375+ char buffer[512];
 1376+ int buffersize;
 1377+ int outsize;
 1378+ if (mask)
 1379+ {
 1380+ SetINISection(file, section);
 1381+ strcpy(buffer, name);
 1382+ strcat(buffer, "=");
 1383+ strcat(buffer, value);
 1384+ strcat(buffer, "\r\n");
 1385+ buffersize = strlen(buffer);
 1386+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1387+ }
 1388+}
 1389+
 1390+void INIWriteTCHARString(HANDLE file, const char *name, LPCTSTR value, DWORD mask, int section)
 1391+{
 1392+ char buffer[512];
 1393+#ifdef _UNICODE
 1394+ wchar_t unicodebuffer[MAX_PATH + 1];
 1395+#endif
 1396+ int buffersize;
 1397+ int outsize;
 1398+ if (mask)
 1399+ {
 1400+ SetINISection(file, section);
 1401+ strcpy(buffer, name);
 1402+ strcat(buffer, "=");
 1403+#ifdef _UNICODE
 1404+ WideCharToMultiByte(CP_UTF8, 0, value, _tcslen(value), unicodebuffer, MAX_PATH, NULL, NULL);
 1405+ strcat(buffer, unicodebuffer);
 1406+#else
 1407+ strcat(buffer, value);
 1408+#endif
 1409+ strcat(buffer, "\r\n");
 1410+ buffersize = strlen(buffer);
 1411+ WriteFile(file, buffer, buffersize, &outsize, NULL);
 1412+ }
 1413+}
 1414+
 1415+DWORD WriteINI(DXGLCFG *cfg, DXGLCFG *mask, LPCTSTR path, HWND hWnd)
 1416+{
 1417+ Sha256Context sha_context;
 1418+ SHA256_HASH sha256;
 1419+ char sha256string[65];
 1420+ char buffer[512];
 1421+ DWORD bytesread;
 1422+ HANDLE file, file2;
 1423+ TCHAR inipath[MAX_PATH + 10];
 1424+ DWORD error;
 1425+ int i;
 1426+ int answer;
 1427+ _tcscpy(inipath, path);
 1428+ _tcscat(inipath, _T("\\dxgl.ini"));
 1429+ file = CreateFile(inipath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
 1430+ if (file == INVALID_HANDLE_VALUE)
 1431+ {
 1432+ error = GetLastError();
 1433+ if (error == ERROR_FILE_EXISTS)
 1434+ {
 1435+ answer = MessageBox(hWnd, _T("File already exists. Do you want to overwrite it?"),
 1436+ _T("File exists"), MB_YESNO | MB_ICONQUESTION);
 1437+ if (answer == IDNO) return error;
 1438+ }
 1439+ else return error;
 1440+ file = CreateFile(inipath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
 1441+ if (file == INVALID_HANDLE_VALUE) return GetLastError();
 1442+ }
 1443+ ini_currentsection = INISECTION_NULL;
 1444+ strcpy(buffer, "; DXGL Configuration file\r\n; This file was generated by DXGL Config.\r\n");
 1445+ WriteFile(file, buffer, strlen(buffer), &bytesread, NULL);
 1446+ // [system]
 1447+ if (cfg->NoWriteRegistry) INIWriteBool(file, "NoWriteRegistry", TRUE, TRUE, INISECTION_SYSTEM);
 1448+ if (cfg->OverrideDefaults) INIWriteBool(file, "OverrideDefaults", TRUE, TRUE, INISECTION_SYSTEM);
 1449+ if (cfg->NoOverwrite) INIWriteBool(file, "NoOverwrite", TRUE, TRUE, INISECTION_SYSTEM);
 1450+ if (cfg->SaveSHA256)
 1451+ {
 1452+ _tcscpy(inipath, path);
 1453+ _tcscat(inipath, _T("\\ddraw.dll"));
 1454+ Sha256Initialise(&sha_context);
 1455+ file2 = CreateFile(inipath, GENERIC_READ, FILE_SHARE_READ, NULL,
 1456+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 1457+ if (file2 != INVALID_HANDLE_VALUE)
 1458+ {
 1459+ while (1)
 1460+ {
 1461+ ReadFile(file2, buffer, 512, &bytesread, NULL);
 1462+ if (!bytesread) break;
 1463+ Sha256Update(&sha_context, buffer, bytesread);
 1464+ if (bytesread < 512) break;
 1465+ }
 1466+ Sha256Finalise(&sha_context, &sha256);
 1467+ CloseHandle(file2);
 1468+ ZeroMemory(sha256string, 65 * sizeof(char));
 1469+ for (i = 0; i < (256 / 8); i++)
 1470+ {
 1471+ sha256string[i * 2] = hexdigit(sha256.bytes[i] >> 4);
 1472+ sha256string[(i * 2) + 1] = hexdigit(sha256.bytes[i] & 0xF);
 1473+ }
 1474+ strcpy(buffer, "; Do not change the following value!\r\n");
 1475+ WriteFile(file, buffer, strlen(buffer), &bytesread, NULL);
 1476+ INIWriteString(file, "BundledDDrawSHA256", sha256string, 1, INISECTION_SYSTEM);
 1477+ }
 1478+ else MessageBox(hWnd, _T("Cannot read ddraw.dll, skipping SHA-256 checksum"),
 1479+ _T("Warning"), MB_OK | MB_ICONWARNING);
 1480+ }
 1481+ if (cfg->NoUninstall) INIWriteBool(file, "NoUninstall", TRUE, TRUE, INISECTION_SYSTEM);
 1482+ // [display]
 1483+ INIWriteInt(file, "ScalingMode", cfg->scaler, mask->scaler, INISECTION_DISPLAY);
 1484+ INIWriteInt(file, "FullscreenWindowMode", cfg->fullmode, mask->fullmode, INISECTION_DISPLAY);
 1485+ INIWriteBool(file, "ChangeColorDepth", cfg->colormode, mask->colormode, INISECTION_DISPLAY);
 1486+ INIWriteInt(file, "AddColorDepths", cfg->AddColorDepths, mask->AddColorDepths, INISECTION_DISPLAY);
 1487+ INIWriteInt(file, "AddModes", cfg->AddModes, mask->AddModes, INISECTION_DISPLAY);
 1488+ INIWriteInt(file, "SortModes", cfg->SortModes, mask->SortModes, INISECTION_DISPLAY);
 1489+ INIWriteInt(file, "VSync", cfg->vsync, mask->vsync, INISECTION_DISPLAY);
 1490+ INIWriteInt(file, "CustomResolutionX", cfg->CustomResolutionX, mask->CustomResolutionX, INISECTION_DISPLAY);
 1491+ INIWriteInt(file, "CustomResolutionY", cfg->CustomResolutionY, mask->CustomResolutionY, INISECTION_DISPLAY);
 1492+ INIWriteInt(file, "CustomRefresh", cfg->CustomRefresh, mask->CustomRefresh, INISECTION_DISPLAY);
 1493+ INIWriteFloat(file, "DisplayMultiplierX", cfg->DisplayMultiplierX, mask->DisplayMultiplierX, 4, INISECTION_DISPLAY);
 1494+ INIWriteFloat(file, "DisplayMultiplierY", cfg->DisplayMultiplierY, mask->DisplayMultiplierY, 4, INISECTION_DISPLAY);
 1495+ INIWriteInt(file, "SingleBufferDevice", cfg->SingleBufferDevice, mask->SingleBufferDevice, INISECTION_DISPLAY);
 1496+ // [scaling]
 1497+ INIWriteInt(file, "ScalingFilter", cfg->scalingfilter, mask->scalingfilter, INISECTION_SCALING);
 1498+ INIWriteInt(file, "BltScale", cfg->BltScale, mask->BltScale, INISECTION_SCALING);
 1499+ // Option was temporarily removed for DXGL 0.5.13 release
 1500+ //INIWriteInt(file, "BltThreshold", cfg->BltThreshold, mask->BltThreshold, INISECTION_SCALING);
 1501+ INIWriteInt(file, "AdjustPrimaryResolution", cfg->primaryscale, mask->primaryscale, INISECTION_SCALING);
 1502+ INIWriteFloat(file, "PrimaryScaleX", cfg->primaryscalex, mask->primaryscalex, 4, INISECTION_SCALING);
 1503+ INIWriteFloat(file, "PrimaryScaleY", cfg->primaryscaley, mask->primaryscaley, 4, INISECTION_SCALING);
 1504+ INIWriteAspect(file, "ScreenAspect", cfg->aspect, mask->aspect, INISECTION_SCALING);
 1505+ INIWriteInt(file, "DPIScale", cfg->DPIScale, mask->DPIScale, INISECTION_SCALING);
 1506+ // [postprocess]
 1507+ INIWriteInt(file, "PostprocessFilter", cfg->postfilter, mask->postfilter, INISECTION_POSTPROCESS);
 1508+ INIWriteFloat(file, "PostprocessScaleX", cfg->postsizex, mask->postsizex, 4, INISECTION_POSTPROCESS);
 1509+ INIWriteFloat(file, "PostprocessScaleY", cfg->postsizey, mask->postsizey, 4, INISECTION_POSTPROCESS);
 1510+ INIWriteInt(file, "EnableShader", cfg->EnableShader, mask->EnableShader, INISECTION_POSTPROCESS);
 1511+ INIWriteTCHARString(file, "ShaderFile", cfg->shaderfile, mask->shaderfile[0], INISECTION_POSTPROCESS);
 1512+ // [d3d]
 1513+ INIWriteInt(file, "TextureFilter", cfg->texfilter, mask->texfilter, INISECTION_D3D);
 1514+ INIWriteInt(file, "AnisotropicFiltering", cfg->anisotropic, mask->anisotropic, INISECTION_D3D);
 1515+ INIWriteHex(file, "Antialiasing", cfg->msaa, mask->msaa, INISECTION_D3D);
 1516+ INIWriteInt(file, "D3DAspect", cfg->aspect3d, mask->aspect3d, INISECTION_D3D);
 1517+ INIWriteInt(file, "LowColorRendering", cfg->LowColorRendering, mask->LowColorRendering, INISECTION_D3D);
 1518+ INIWriteInt(file, "EnableDithering", cfg->EnableDithering, mask->EnableDithering, INISECTION_D3D);
 1519+ // [advanced]
 1520+ INIWriteInt(file, "TextureFormat", cfg->TextureFormat, mask->TextureFormat, INISECTION_ADVANCED);
 1521+ INIWriteInt(file, "TexUpload", cfg->TexUpload, mask->TexUpload, INISECTION_ADVANCED);
 1522+ INIWriteInt(file, "WindowPosition", cfg->WindowPosition, mask->WindowPosition, INISECTION_ADVANCED);
 1523+ INIWriteBool(file, "RememberWindowSize", cfg->RememberWindowSize, mask->RememberWindowSize, INISECTION_ADVANCED);
 1524+ INIWriteBool(file, "RememberWindowPosition", cfg->RememberWindowPosition, mask->RememberWindowPosition, INISECTION_ADVANCED);
 1525+ INIWriteBool(file, "NoResizeWindow", cfg->NoResizeWindow, mask->NoResizeWindow, INISECTION_ADVANCED);
 1526+ INIWriteInt(file, "WindowX", cfg->WindowX, mask->WindowX, INISECTION_ADVANCED);
 1527+ INIWriteInt(file, "WindowY", cfg->WindowY, mask->WindowY, INISECTION_ADVANCED);
 1528+ INIWriteInt(file, "WindowWidth", cfg->WindowWidth, mask->WindowWidth, INISECTION_ADVANCED);
 1529+ INIWriteInt(file, "WindowHeight", cfg->WindowHeight, mask->WindowHeight, INISECTION_ADVANCED);
 1530+ INIWriteBool(file, "WindowMaximized", cfg->WindowMaximized, mask->WindowMaximized, INISECTION_ADVANCED);
 1531+ INIWriteBool(file, "CaptureMouse", cfg->CaptureMouse, mask->CaptureMouse, INISECTION_ADVANCED);
 1532+ // [debug]
 1533+ INIWriteBool(file, "DebugNoExtFramebuffer", cfg->DebugNoExtFramebuffer, mask->DebugNoExtFramebuffer, INISECTION_DEBUG);
 1534+ INIWriteBool(file, "DebugNoArbFramebuffer", cfg->DebugNoArbFramebuffer, mask->DebugNoArbFramebuffer, INISECTION_DEBUG);
 1535+ INIWriteBool(file, "DebugNoES2Compatibility", cfg->DebugNoES2Compatibility, mask->DebugNoES2Compatibility, INISECTION_DEBUG);
 1536+ INIWriteBool(file, "DebugNoExtDirectStateAccess", cfg->DebugNoExtDirectStateAccess, mask->DebugNoExtDirectStateAccess, INISECTION_DEBUG);
 1537+ INIWriteBool(file, "DebugNoArbDirectStateAccess", cfg->DebugNoArbDirectStateAccess, mask->DebugNoArbDirectStateAccess, INISECTION_DEBUG);
 1538+ INIWriteBool(file, "DebugNoSamplerObjects", cfg->DebugNoSamplerObjects, mask->DebugNoSamplerObjects, INISECTION_DEBUG);
 1539+ INIWriteBool(file, "DebugNoGpuShader4", cfg->DebugNoGpuShader4, mask->DebugNoGpuShader4, INISECTION_DEBUG);
 1540+ INIWriteBool(file, "DebugNoGLSL130", cfg->DebugNoGLSL130, mask->DebugNoGLSL130, INISECTION_DEBUG);
 1541+ INIWriteBool(file, "DebugUnloadAfterUnlock", cfg->DebugUploadAfterUnlock, mask->DebugUploadAfterUnlock, INISECTION_DEBUG);
 1542+ INIWriteBool(file, "DebugBlendDestColorKey", cfg->DebugBlendDestColorKey, mask->DebugBlendDestColorKey, INISECTION_DEBUG);
 1543+ INIWriteBool(file, "DebugNoMouseHooks", cfg->DebugNoMouseHooks, mask->DebugNoMouseHooks, INISECTION_DEBUG);
 1544+ INIWriteBool(file, "DebugMaxGLVersionMajor", cfg->DebugMaxGLVersionMajor, mask->DebugMaxGLVersionMajor, INISECTION_DEBUG);
 1545+ INIWriteBool(file, "DebugMaxGLVersionMinor", cfg->DebugMaxGLVersionMinor, mask->DebugMaxGLVersionMinor, INISECTION_DEBUG);
 1546+ // [hacks]
 1547+ INIWriteBool(file, "HackCrop640480to640400", cfg->HackCrop640480to640400, mask->HackCrop640480to640400, INISECTION_HACKS);
 1548+ INIWriteInt(file, "HackAutoScale512448to640480", cfg->HackAutoScale512448to640480, mask->HackAutoScale512448to640480, INISECTION_HACKS);
 1549+ INIWriteBool(file, "HackNoTVRefresh", cfg->HackNoTVRefresh, mask->HackNoTVRefresh, INISECTION_HACKS);
 1550+ INIWriteBool(file, "HackSetCursor", cfg->HackSetCursor, mask->HackSetCursor, INISECTION_HACKS);
 1551+ CloseHandle(file);
 1552+ return ERROR_SUCCESS;
 1553+}
 1554+
11571555 void GetCurrentConfig(DXGLCFG *cfg, BOOL initial)
11581556 {
11591557 HKEY hKey;
Index: cfgmgr/cfgmgr.h
@@ -29,6 +29,9 @@
3030 // [system]
3131 DWORD NoWriteRegistry;
3232 DWORD OverrideDefaults;
 33+ DWORD NoOverwrite;
 34+ DWORD SaveSHA256;
 35+ DWORD NoUninstall;
3336 // [display]
3437 DWORD scaler;
3538 DWORD fullmode;
@@ -128,7 +131,7 @@
129132
130133 void ReadSettings(HKEY hKey, DXGLCFG *cfg, DXGLCFG *mask, BOOL global, BOOL dll, LPTSTR dir);
131134 void WriteSettings(HKEY hKey, const DXGLCFG *cfg, const DXGLCFG *mask);
132 -DWORD WriteINI(DXGLCFG *cfg, DXGLCFG *mask, LPCTSTR path);
 135+DWORD WriteINI(DXGLCFG *cfg, DXGLCFG *mask, LPCTSTR path, HWND hWnd);
133136 void GetCurrentConfig(DXGLCFG *cfg, BOOL initial);
134137 void GetGlobalConfig(DXGLCFG *cfg, BOOL initial);
135138 void GetGlobalConfigWithMask(DXGLCFG *cfg, DXGLCFG *mask, BOOL initial);
Index: dxgl-example.ini
@@ -9,7 +9,7 @@
1010 ; Set to true if distributing the DXGL ddraw.dll with a game or application.
1111 ; Default is false so ensure the following line is set to avoid writing to
1212 ; the end user's registry.
13 -NoWriteRegistry = true
 13+NoWriteRegistry=true
1414
1515 ; OverrideDefaults - Boolean
1616 ; If true, settings not set in the .ini file will not be read from the
@@ -19,7 +19,7 @@
2020 ; created if it does not exist.
2121 ; If false, the settings in DXGL Config global section will be used as default.
2222 ; Default is false
23 -OverrideDefaults = false
 23+OverrideDefaults=false
2424
2525 ; NoOverwrite - Boolean
2626 ; If true, DXGL Config will not overwrite the copy of ddraw in the application
@@ -29,7 +29,7 @@
3030 ; the DXGL consumer application will not remove that copy of ddraw.dll. This
3131 ; will be enforced, even if the existing copy of ddraw.dll is not DXGL.
3232 ; Default is false
33 -NoOverwrite = false
 33+NoOverwrite=false
3434
3535 ; BundledDDrawSHA256 - String
3636 ; This field may be used to define the SHA256 checksum of the copy of ddraw.dll
@@ -41,7 +41,7 @@
4242 ; file is in the application directory with the SHA256 checksum of the bundled
4343 ; ddraw.dll file. This will be ignored if NoOverwrite is true.
4444 ; Default is a zero length string, disabling the backup feature.
45 -BundledDDrawSHA256 =
 45+;BundledDDrawSHA256=
4646
4747 ; NoUninstall - Boolean
4848 ; If true, DXGL will not delete the copy of ddraw.dll in the application folder
@@ -50,7 +50,7 @@
5151 ; BundledDDrawSHA256 variable, it will not be restored, and the end-user must
5252 ; manually copy back the ddraw.dll.dxgl-backup file.
5353 ; Default is false.
54 -NoUninstall = false
 54+NoUninstall=false
5555
5656 [display]
5757 ; ScalingMode - Integer
@@ -68,7 +68,7 @@
6969 ; 8 - Center output, multiply by custom values
7070 ; 9 - Set display to custom resolution and refresh
7171 ; 10 - Center output, scale to custom size
72 -ScalingMode = 0
 72+ScalingMode=0
7373
7474 ; FullscreenWindowMode - Integer
7575 ; Determines how DXGL will draw the window for fullscreen modes.
@@ -80,7 +80,7 @@
8181 ; 3 - Use a resizable window, uses scaler mode, preferably 1, 2, 3, or 7
8282 ; 4 - Use a borderless, non-resizable window, also known as windowed borderless
8383 ; 5 - Use a borderless window scaled to the screen
84 -FullscreenWindowMode = 0
 84+FullscreenWindowMode=0
8585
8686 ; ChangeColorDepth - Boolean
8787 ; If true, Windows will attempt to change the color depth of the screen.
@@ -91,7 +91,7 @@
9292 ; DXGL always performs color depth conversion for DirectDraw internally
9393 ; via the OpenGL runtime regardless of the operating system's display mode.
9494 ; Default is false and is recommended except in special circumstances.
95 -ChangeColorDepth = false
 95+ChangeColorDepth=false
9696
9797 ; AllColorDepths - Boolean
9898 ; Adds 8, 16, 24, and 32-bit color modes if they are not already
@@ -99,7 +99,7 @@
100100 ; Equivalent to setting AddColorDepths to 21.
101101 ; Overridden by AddColorDepths.
102102 ; Default is true if Windows 8 or higher is detected, false otherwise.
103 -AllColorDepths = true
 103+AllColorDepths=true
104104
105105 ; AddColorDepths - Integer
106106 ; (future) Adds additional color modes if they are not already
@@ -114,7 +114,7 @@
115115 ; Default is 21 if Windows 8 or higher is detected, 0 otherwise.
116116 ; Adding both 15 and 16 bit modes at the same time may cause
117117 ; crashes or undefined behavior in some programs.
118 -AddColorDepths = 21
 118+AddColorDepths=21
119119
120120 ; ExtraModes - Boolean
121121 ; Adds additional video modes to the list of resolutions.
@@ -123,7 +123,7 @@
124124 ; video modes.
125125 ; Default is true.
126126 ; Equivalent to setting AddModes to 7. Overridden by AddModes.
127 -ExtraModes = true
 127+ExtraModes=true
128128
129129 ; AddModes - Integer
130130 ; Adds additional video modes to the list of resolutions.
@@ -138,7 +138,7 @@
139139 ; 32 - Add over-4K UHD modes. Check GPU specifications before enabling.
140140 ; 64 - Add very uncommon resolutions of all dimensions.
141141 ; Default is 1.
142 -AddModes = 1
 142+AddModes=1
143143
144144 ; SortModes - Integer
145145 ; Determines whether or not to sort display modes by either
@@ -152,33 +152,47 @@
153153 ; 1 - Sort video modes, grouping by color depth.
154154 ; 2 - Sort video modes, grouping by resolution.
155155 ; Default is 0.
156 -SortModes = 0
 156+SortModes=0
157157
 158+; VSync - Integer
 159+; Determines vertical retrace behavior.
 160+; The following values are currently available:
 161+; 0 - Wait for V-sync when the application requests it.
 162+; 1 - Disables V-sync entirely
 163+; 2 - Waits for V-sync whenever the screen is redrawn.
 164+VSync=0
 165+
158166 ; CustomResolutionX - Integer
159167 ; Width of the custom resolution for the display output for modes 9 and 10.
160168 ; Default is 640.
161 -CustomResolutionX = 640
 169+CustomResolutionX=640
162170
163171 ; CustomResolutionY - Integer
164172 ; Height of the custom resolution for the display output for modes 9 and 10.
165173 ; Default is 480;
166 -CustomResolutionY = 480
 174+CustomResolutionY=480
167175
168176 ; CustomRefresh - Integer
169177 ; Refresh rate for the display output for modes 9 and 10.
170178 ; Default is 60.
171 -CustomRefresh = 60
 179+CustomRefresh=60
172180
173181 ; DisplayMultiplierX - Floating point
174182 ; Multiplier for the pixel width for display mode 8.
175183 ; Default is 1.0.
176 -DisplayMultiplierX = 1.0
 184+DisplayMultiplierX=1.0
177185
178186 ; DisplayMultiplierY - Floating point
179187 ; Multiplier for the pixel height for display mode 8.
180188 ; Default is 1.0.
181 -DisplayMultiplierY = 1.0
 189+DisplayMultiplierY=1.0
182190
 191+; SingleBufferDevice - Boolean
 192+; If true, creates an OpenGL device without double buffering. This has
 193+; various effects, such as disabling vsync and exclusive fullscreen.
 194+; Default is false
 195+SingleBufferDevice=false
 196+
183197 [scaling]
184198 ; ScalingFilter - Integer
185199 ; Selects the filter to be used to scale the output image
@@ -186,7 +200,7 @@
187201 ; The following values are valid:
188202 ; 0 - Nearest-neighbor stretching
189203 ; 1 - Bilinear interpolation
190 -ScalingFilter = 0
 204+ScalingFilter=0
191205
192206 ; BltScale - Integer
193207 ; Selects the filter to be used to scale Blt operations.
@@ -197,7 +211,7 @@
198212 ; 2 - Bilinear interpolation, nearest-neighbor color key
199213 ; 3 - Bilinear interpolation, sharp color key
200214 ; 4 - Bilinear interpolation, soft color key
201 -BltScale = 0
 215+BltScale=0
202216
203217 ; BltThreshold - Integer
204218 ; Sets the threshold point for sharp color key scaling.
@@ -204,7 +218,7 @@
205219 ; 0 will trim the most, 254 will trim the least, and 255 will completely
206220 ; disable color keying.
207221 ; Default is 127
208 -BltThreshold = 127
 222+BltThreshold=127
209223
210224 ; AdjustPrimaryResolution - Integer
211225 ; Determines whether or not to resize the buffers used to hold the primary
@@ -225,7 +239,7 @@
226240 ; 11 - Use exact 8x scale.
227241 ; 12 - Use custom scale.
228242 ; Default is 0.
229 -AdjustPrimaryResolution = 0
 243+AdjustPrimaryResolution=0
230244
231245 ; PrimaryScaleX - Floating point
232246 ; Sets the scaling amount in the X dimension for custom primary
@@ -232,7 +246,7 @@
233247 ; buffer scaling.
234248 ; If zero, negative, or an invalid value, will be interpreted as 1.0
235249 ; Default is 1.0
236 -PrimaryScaleX = 1.0
 250+PrimaryScaleX=1.0
237251
238252 ; PrimaryScaleY - Floating point
239253 ; Sets the scaling amount in the Y dimension for custom primary
@@ -239,7 +253,7 @@
240254 ; buffer scaling.
241255 ; If zero, negative, or an invalid value, will be interpreted as 1.0
242256 ; Default is 1.0
243 -PrimaryScaleY = 1.0
 257+PrimaryScaleY=1.0
244258
245259 ; ScreenAspect - Floating point or string
246260 ; Sets the aspect ratio of the display output.
@@ -250,7 +264,7 @@
251265 ; to a 1:1 PAR except on specific low-resolution modes which may use 2:1 or
252266 ; 1:2 PAR.
253267 ; Default is "Default"
254 -ScreenAspect = Default
 268+ScreenAspect=Default
255269
256270 ; DPIScale - Integer
257271 ; Overrides Windows DPI scaling on high-DPI modes.
@@ -268,7 +282,7 @@
269283 ; or game to restart as the registry value is set. Use this mode only if
270284 ; setting DPIScale to 1 has no effect.
271285 ; Default is 1.
272 -DPIScale = 1
 286+DPIScale=1
273287
274288 [postprocess]
275289 ; PostprocessFilter - Integer
@@ -279,7 +293,7 @@
280294 ; The following values are valid:
281295 ; 0 - Nearest-neighbor stretching
282296 ; 1 - Bilinear interpolation
283 -PostprocessFilter = 0
 297+PostprocessFilter=0
284298
285299 ; PostprocessScaleX - Floating point
286300 ; Scaling in the X direction for the postprocess pass.
@@ -288,7 +302,7 @@
289303 ; amount that doubles the width if it is 400 or fewer pixels wide, and doubles
290304 ; the lines if the height is 300 or fewer lines.
291305 ; Default is 0.0
292 -PostprocessScaleX = 0.0
 306+PostprocessScaleX=0.0
293307
294308 ; PostprocessScaleY - Floating point
295309 ; Scaling in the Y direction for the postprocess pass.
@@ -297,12 +311,12 @@
298312 ; amount that doubles the width if it is 400 or fewer pixels wide, and doubles
299313 ; the lines if the height is 300 or fewer lines.
300314 ; Default is 0.0
301 -PostprocessScaleY = 0.0
 315+PostprocessScaleY=0.0
302316
303317 ; EnableShader - Boolean
304318 ; (future) If true, uses a custom shader to render the postprocess pass.
305319 ; Default is false
306 -EnableShader = false
 320+EnableShader=false
307321
308322 ; ShaderFile - String
309323 ; (future)Path to a file containing either a GLSL fragment shader or a
@@ -312,7 +326,7 @@
313327 ; install directory and the path where the ddraw.dll implementation has been
314328 ; placed) or absolute.
315329 ; Default is undefined.
316 -; ShaderFile = example.fs
 330+; ShaderFile=example.fs
317331
318332 [d3d]
319333 ; TextureFilter - Integer
@@ -326,7 +340,7 @@
327341 ; 5 - GL_LINEAR_MIPMAP_NEAREST (Bilinear with mipmap)
328342 ; 6 - GL_LINEAR_MIPMAP_LINEAR (Trilinear filtering)
329343 ; Default is 0
330 -TextureFilter = 0
 344+TextureFilter=0
331345
332346 ; AnisotropicFiltering - Integer
333347 ; (future) Enabled anisotropic filtering to improve display quality
@@ -339,7 +353,7 @@
340354 ; 4 - Sets anisotropic filtering to 4x.
341355 ; 8 - Sets anisotropic filtering to 8x.
342356 ; 16 - Sets anisotropic filtering to 16x.
343 -AnisotropicFiltering = 0
 357+AnisotropicFiltering=0
344358
345359 ; Antialiasing - Hexadecimal integer
346360 ; (future) Enables multisample antialiasing. May cause significant
@@ -355,7 +369,7 @@
356370 ; Add 0x10000 to the number to enable the specific antialiasing mode only
357371 ; when the application requests it.
358372 ; Default is 0x0
359 -Antialiasing = 0x0
 373+Antialiasing=0x0
360374
361375 ; D3DAspect - Integer
362376 ; (future)Selects whether or not to adjust the aspect ratio for Direct3D
@@ -368,7 +382,7 @@
369383 ; 2 - Crops the display to the viewable area. May cut off parts of the game
370384 ; graphics.
371385 ; Default is 0
372 -D3DAspect = 0
 386+D3DAspect=0
373387
374388 ; LowColorRendering - Integer
375389 ; Selects whether to increase the color depth when rendering to a
@@ -378,7 +392,7 @@
379393 ; 1 - Uses a 32-bit texture format. Increases the quality of the game but
380394 ; will be downsampled if the surface is accessed directly after rendering.
381395 ; Default is 0
382 -LowColorRendering = 0
 396+LowColorRendering=0
383397
384398 ; EnableDithering - Integer
385399 ; Determines when dithering is enabled for Direct3D rendering.
@@ -393,34 +407,22 @@
394408 ; 3 - Enables dithering per application, for all modes.
395409 ; 4 - Always enables dithering, for all modes.
396410 ; Default is 0
397 -EnableDithering = 0
 411+EnableDithering=0
398412
399413 [advanced]
400 -; VSync - Integer
401 -; Determines vertical retrace behavior.
402 -; This option is reserved for future expansion, and the only valid value is
403 -; currently 0.
404 -VSync = 0
405 -
406414 ; TextureFormat - Integer
407415 ; Determines the internal format to use for textures and DirectDraw
408416 ; surfaces.
409417 ; This option is reserved for future expansion, and the only valid value is
410418 ; currently 0.
411 -TextureFormat = 0
 419+TextureFormat=0
412420
413421 ; TexUpload - Integer
414422 ; Determines the method used to upload texture data to the graphics card.
415423 ; This option is reserved for future expansion, and the only valid value is
416424 ; currently 0.
417 -TexUpload = 0
 425+TexUpload=0
418426
419 -; SingleBufferDevice - Boolean
420 -; If true, creates an OpenGL device without double buffering. This has
421 -; various effects, such as disabling vsync and exclusive fullscreen.
422 -; Default is false
423 -SingleBufferDevice = false
424 -
425427 ; WindowPosition - Integer
426428 ; Selects the position for the window on application startup, when using
427429 ; forced-window mode.
@@ -428,7 +430,7 @@
429431 ; 0 - Center window on screen.
430432 ; 1 - Use last remembered position.
431433 ; Default is 1
432 -WindowPosition = 1
 434+WindowPosition=1
433435
434436 ; RememberWindowSize - Boolean
435437 ; Determines whether to remember the last window size in forced window
@@ -436,7 +438,7 @@
437439 ; size before the first SetDisplayMode command. This value will be
438440 ; saved in the per-app profile as WindowX and WindowY.
439441 ; Default is true
440 -RememberWindowSize = true
 442+RememberWindowSize=true
441443
442444 ; RememberWindowPosition - Boolean
443445 ; Determines whether to remember the last window position in forced
@@ -443,40 +445,40 @@
444446 ; window mode, by saving it in the registry. This value will be saved
445447 ; in the per-app profile as WindowWidth and WindowHeight.
446448 ; Default is true
447 -RememberWindowPosition = true
 449+RememberWindowPosition=true
448450
449451 ; NoResizeWindow - Boolean
450452 ; If true, do not resize the window when using resizable window mode, when
451453 ; SetDisplayMode is called.
452454 ; Default is false
453 -NoResizeWindow = false
 455+NoResizeWindow=false
454456
455457 ; WindowX - Integer
456458 ; Remembered X position of the window when using forced window modes.
457459 ; Default is a position that puts the current window size in the center of the
458460 ; screen.
459 -; WindowX = 0
 461+; WindowX=0
460462
461463 ; WindowY - Integer
462464 ; Remembered Y position of the window when using forced window modes.
463465 ; Default is a position that puts the current window size in the center of the
464466 ; screen.
465 -; WindowY = 0
 467+; WindowY=0
466468
467469 ; WindowWidth = Integer
468470 ; Remembered width of the window when using forced window modes.
469471 ; Default is 640
470 -WindowWidth = 640
 472+WindowWidth=640
471473
472474 ; WindowHeight - Integer
473475 ; Remembered height of the window when using forced window modes.
474476 ; Default is 480
475 -WindowHeight = 480
 477+WindowHeight=480
476478
477479 ; WindowMaximized - Boolean
478480 ; Remembered maximized state of the window when using resized window mode.
479481 ; Default is false
480 -WindowMaximized = false
 482+WindowMaximized=false
481483
482484 [debug]
483485 ; DebugNoExtFramebuffer - Boolean
@@ -485,7 +487,7 @@
486488 ; unavailable or DebugNoArbFramebuffer is enabled, then DXGL will fail
487489 ; to initialize.
488490 ; Default is false
489 -DebugNoExtFramebuffer = false
 491+DebugNoExtFramebuffer=false
490492
491493 ; DebugNoArbFramebuffer - Boolean
492494 ; Disables use of the ARB_framebuffer_object OpenGL extension.
@@ -493,7 +495,7 @@
494496 ; unavailable or DebugNoExtFramebuffer is enabled, then DXGL will fail
495497 ; to initialize.
496498 ; Default is false
497 -DebugNoArbFramebuffer = false
 499+DebugNoArbFramebuffer=false
498500
499501 ; DebugNoES2Compatibility - Boolean
500502 ; Disables use of the ARB_ES2_compatibility OpenGL extension.
@@ -500,7 +502,7 @@
501503 ; Currently this means that GL_RGB565 16-bit internal texture format
502504 ; will not be used.
503505 ; Default is false
504 -DebugNoES2Compatibility = false
 506+DebugNoES2Compatibility=false
505507
506508 ; DebugNoExtDirectStateAccess - Boolean
507509 ; Disables use of the EXT_direct_state_access OpenGL extension.
@@ -508,7 +510,7 @@
509511 ; objects. Disabling direct state access will revert to a more traditional
510512 ; approach to manipulating OpenGL objects.
511513 ; Default is false
512 -DebugNoExtDirectStateAccess = false
 514+DebugNoExtDirectStateAccess=false
513515
514516 ; DebugNoArbDirectStateAccess - Boolean
515517 ; Disables use of the ARB_direct_state_access OpenGL extension.
@@ -516,13 +518,13 @@
517519 ; objects. Disabling direct state access will revert to a more traditional
518520 ; approach to manipulating OpenGL objects.
519521 ; Default is false
520 -DebugNoArbDirectStateAccess = false
 522+DebugNoArbDirectStateAccess=false
521523
522524 ; DebugNoSamplerObjects - Boolean
523525 ; Disables use of sampler objects. Disabling sampler objects may reduce
524526 ; the performance and accuracy of Direct3D commands.
525527 ; Default is false
526 -DebugNoSamplerObjects = false
 528+DebugNoSamplerObjects=false
527529
528530 ; DebugNoGpuShader4 - Boolean
529531 ; Disables use of the EXT_gpu_shader4 OpenGL extension.
@@ -532,7 +534,7 @@
533535 ; In addition disabling GLSL 1.30 and EXT_gpu_shader4 will disable DirectDraw
534536 ; ROP support.
535537 ; Default is false.
536 -DebugNoGpuShader4 = false
 538+DebugNoGpuShader4=false
537539
538540 ; DebugNoGLSL130 - Boolean
539541 ; Disables use of GLSL 1.30 shaders. Enabling this parameter as well as
@@ -539,13 +541,13 @@
540542 ; DebugNoGpuShader4 will disable integer processing of DirectDraw commands
541543 ; as well as disabling DirectDraw ROP support.
542544 ; Default is false
543 -DebugNoGLSL130 = false
 545+DebugNoGLSL130=false
544546
545547 ; DebugUploadAfterUnlock - Boolean
546548 ; Uploads surface contents immediately after unlock. This parameter can help
547549 ; with debugging surface uploads, but can also reduce performance.
548550 ; Default is false
549 -DebugUploadAfterUnlock = false
 551+DebugUploadAfterUnlock=false
550552
551553 ; DebugNoMouseHooks - Boolean
552554 ; Disables API hooks that adjust the mouse pointer position in scaled modes
@@ -553,7 +555,7 @@
554556 ; GetCursorPos() and SetCursorPos() will not be adjusted to the scaled size
555557 ; and position of the screen.
556558 ; Default is false
557 -DebugNoMouseHooks - false
 559+DebugNoMouseHooks=false
558560
559561 ; DebugBlendDestColorKey - Boolean
560562 ; Blends the temporary texture used for destination color keying with the
@@ -561,7 +563,7 @@
562564 ; with the destination coordinates being used for a Blt operation. This
563565 ; should only be enabled for development and regression testing purposes.
564566 ; Default is false
565 -DebugBlendDestColorKey = false
 567+DebugBlendDestColorKey=false
566568
567569 ; DebugMaxGLVersionMajor - Integer
568570 ; Determines the maximum OpenGL major version available to DXGL.
@@ -569,7 +571,7 @@
570572 ; If this value is 0 than DXGL will use the highest OpenGL version
571573 ; available to the system and ignore DebugMaxGLVersionMinor.
572574 ; Default is 0
573 -DebugMaxGLVersionMajor = 0
 575+DebugMaxGLVersionMajor=0
574576
575577 ; DebugMaxGLVersionMinor - Integer
576578 ; Determines the maximum OpenGL minor version available to DXGL.
@@ -576,7 +578,7 @@
577579 ; This will be ignored if the system OpenGL major version is less than
578580 ; DebugMaxGLVersionMajor.
579581 ; Default is 0
580 -DebugMaxGLVersionMinor = 0
 582+DebugMaxGLVersionMinor=0
581583
582584 ; DebugDisableErrors - Boolean
583585 ; (future) If OpenGL 4.6 is installed, creates an OpenGL context that has
@@ -585,7 +587,7 @@
586588 ; This option has no effect on OpenGL 4.5 or earlier drivers unless the
587589 ; GL_KHR_no_error extension is available.
588590 ; Default is false
589 -DebugDisableErrors = true
 591+DebugDisableErrors=true
590592
591593 [hacks]
592594 ; Hacks are intended for specific scenarios, and may cause undesired effects
@@ -597,7 +599,7 @@
598600 ; letterboxes the output. This hack is only active in fullscreen mode at
599601 ; 640x480 display mode.
600602 ; Default is false
601 -HackCrop640480to640400 = false
 603+HackCrop640480to640400=false
602604
603605 ; HackAutoScale512448to640480 - Boolean
604606 ; Detects when the application is rendering a 512x448 image in 640x480 mode.
@@ -611,7 +613,7 @@
612614 ; If set to 1, this will scale in both X and Y directions. If set to 1, this
613615 ; will scale only in the X direction.
614616 ; Default is 0
615 -HackAutoScale512448to640480 = 0
 617+HackAutoScale512448to640480=0
616618
617619 ; HackNoTVRefresh - Boolean
618620 ; Removes TV-compatible refresh rates that may be added by Windows 7 and
@@ -619,7 +621,7 @@
620622 ; This may fix some games that may run at a reduced framerate due to these
621623 ; compatible refresh rates operating above the integer refresh rate.
622624 ; Default is false
623 -HackNoTVRefresh = false
 625+HackNoTVRefresh=false
624626
625627 ; HackSetCursor - Boolean
626628 ; Applies a hack to the SetCursor() API to try to prevent a flickering cursor
@@ -626,4 +628,4 @@
627629 ; in some scenarios. This is a contributed code to mitigate this issue in the
628630 ; game "Atlantis 1" and may or may not work in other scenarios.
629631 ; Default is false
630 -HackSetCursor = false
 632+HackSetCursor=false
Index: dxglcfg/dxglcfg.cpp
@@ -1953,8 +1953,9 @@
19541954
19551955 LRESULT CALLBACK SaveINICallback(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
19561956 {
 1957+ BOOL unused;
19571958 DWORD error;
1958 - TCHAR errormsg[2048];
 1959+ TCHAR errormsg[2048+MAX_PATH];
19591960 switch(Msg)
19601961 {
19611962 case WM_INITDIALOG:
@@ -1968,18 +1969,30 @@
19691970 switch (LOWORD(wParam))
19701971 {
19711972 case IDOK:
1972 - error = WriteINI(cfg, cfgmask, apps[current_app].path);
1973 - if (error == 5)
 1973+ cfg->NoWriteRegistry = GetCheck(hWnd, IDC_NOWRITEREGISTRY, &unused);
 1974+ cfg->OverrideDefaults = GetCheck(hWnd, IDC_OVERRIDEREGISTRY, &unused);
 1975+ cfg->NoOverwrite = GetCheck(hWnd, IDC_NOOVERWRITE, &unused);
 1976+ cfg->SaveSHA256 = GetCheck(hWnd, IDC_SAVESHA256, &unused);
 1977+ cfg->NoUninstall = GetCheck(hWnd, IDC_NOUNINSTALL, &unused);
 1978+ error = WriteINI(cfg, cfgmask, apps[current_app].path, hWnd);
 1979+ if (error == ERROR_ACCESS_DENIED)
19741980 {
19751981 MessageBox(hWnd, _T("Access denied error writing .ini file. Please re-launch DXGL Config as Administrator and try again."),
19761982 _T("Error"), MB_OK | MB_ICONWARNING);
19771983 }
1978 - else if (error != 0)
 1984+ else if (error != ERROR_SUCCESS)
19791985 {
19801986 _tcscpy(errormsg, _T("Error writing .ini file:\r\n"));
19811987 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errormsg + _tcslen(errormsg), 2048 - _tcslen(errormsg), NULL);
19821988 MessageBox(hWnd, errormsg, _T("Error"), MB_OK | MB_ICONERROR);
19831989 }
 1990+ else
 1991+ {
 1992+ _tcscpy(errormsg, _T("Saved dxgl.ini to "));
 1993+ _tcscat(errormsg, apps[current_app].path);
 1994+ _tcscat(errormsg, _T("\dxgl.ini"));
 1995+ MessageBox(hWnd, errormsg, _T("Notice"), MB_OK | MB_ICONINFORMATION);
 1996+ }
19841997 EndDialog(hWnd, IDOK);
19851998 return TRUE;
19861999 case IDCANCEL:
@@ -3214,6 +3227,7 @@
32153228 // Paths
32163229 EnableWindow(GetDlgItem(hTabs[3], IDC_PATHLABEL), FALSE);
32173230 EnableWindow(GetDlgItem(hTabs[3], IDC_PROFILEPATH), FALSE);
 3231+ EnableWindow(GetDlgItem(hTabs[3], IDC_WRITEINI), FALSE);
32183232 // Debug
32193233 _tcscpy(buffer, _T("Disable EXT framebuffers"));
32203234 SendDlgItemMessage(hTabs[4], IDC_DEBUGLIST, LB_ADDSTRING, 0, (LPARAM)buffer);
@@ -3566,6 +3580,7 @@
35673581 {
35683582 EnableWindow(GetDlgItem(hTabs[3], IDC_PATHLABEL), TRUE);
35693583 EnableWindow(GetDlgItem(hTabs[3], IDC_PROFILEPATH), TRUE);
 3584+ EnableWindow(GetDlgItem(hTabs[3], IDC_WRITEINI), TRUE);
35703585 SetDlgItemText(hTabs[3], IDC_PROFILEPATH, apps[current_app].path);
35713586 if (apps[current_app].builtin) EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), FALSE);
35723587 else EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), TRUE);
@@ -3574,6 +3589,7 @@
35753590 {
35763591 EnableWindow(GetDlgItem(hTabs[3], IDC_PATHLABEL), FALSE);
35773592 EnableWindow(GetDlgItem(hTabs[3], IDC_PROFILEPATH), FALSE);
 3593+ EnableWindow(GetDlgItem(hTabs[3], IDC_WRITEINI), FALSE);
35783594 SetDlgItemText(hTabs[3], IDC_PROFILEPATH, _T(""));
35793595 EnableWindow(GetDlgItem(hWnd, IDC_REMOVE), FALSE);
35803596 }