diff --git a/CMakeLists.txt b/CMakeLists.txt index 660edbd08..5a3a5bfc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ if(NOT ANDROID) option(BUILD_NOGUI_FRONTEND "Build the NoGUI frontend" ON) option(BUILD_QT_FRONTEND "Build the Qt frontend" ON) option(BUILD_LIBRETRO_CORE "Build a libretro core" OFF) + option(BUILD_REGTEST "Build regression test runner" OFF) option(ENABLE_DISCORD_PRESENCE "Build with Discord Rich Presence support" ON) option(ENABLE_CHEEVOS "Build with RetroAchievements support" ON) option(USE_SDL2 "Link with SDL2 for controller support" ON) diff --git a/duckstation.sln b/duckstation.sln index ef3559c43..6af261913 100644 --- a/duckstation.sln +++ b/duckstation.sln @@ -101,6 +101,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duckstation-nogui", "src\du EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rcheevos", "dep\rcheevos\rcheevos.vcxproj", "{4BA0A6D4-3AE1-42B2-9347-096FD023FF64}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "duckstation-regtest", "src\duckstation-regtest\duckstation-regtest.vcxproj", "{3029310E-4211-4C87-801A-72E130A648EF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -109,12 +111,18 @@ Global DebugFast|ARM64 = DebugFast|ARM64 DebugFast|x64 = DebugFast|x64 DebugFast|x86 = DebugFast|x86 + DebugUWP|ARM64 = DebugUWP|ARM64 + DebugUWP|x64 = DebugUWP|x64 + DebugUWP|x86 = DebugUWP|x86 Release|ARM64 = Release|ARM64 Release|x64 = Release|x64 Release|x86 = Release|x86 ReleaseLTCG|ARM64 = ReleaseLTCG|ARM64 ReleaseLTCG|x64 = ReleaseLTCG|x64 ReleaseLTCG|x86 = ReleaseLTCG|x86 + ReleaseUWP|ARM64 = ReleaseUWP|ARM64 + ReleaseUWP|x64 = ReleaseUWP|x64 + ReleaseUWP|x86 = ReleaseUWP|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {43540154-9E1E-409C-834F-B84BE5621388}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -129,6 +137,9 @@ Global {43540154-9E1E-409C-834F-B84BE5621388}.DebugFast|x64.Build.0 = DebugFast|x64 {43540154-9E1E-409C-834F-B84BE5621388}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {43540154-9E1E-409C-834F-B84BE5621388}.DebugFast|x86.Build.0 = DebugFast|Win32 + {43540154-9E1E-409C-834F-B84BE5621388}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {43540154-9E1E-409C-834F-B84BE5621388}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {43540154-9E1E-409C-834F-B84BE5621388}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {43540154-9E1E-409C-834F-B84BE5621388}.Release|ARM64.ActiveCfg = Release|ARM64 {43540154-9E1E-409C-834F-B84BE5621388}.Release|ARM64.Build.0 = Release|ARM64 {43540154-9E1E-409C-834F-B84BE5621388}.Release|x64.ActiveCfg = Release|x64 @@ -141,6 +152,9 @@ Global {43540154-9E1E-409C-834F-B84BE5621388}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {43540154-9E1E-409C-834F-B84BE5621388}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {43540154-9E1E-409C-834F-B84BE5621388}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {43540154-9E1E-409C-834F-B84BE5621388}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {43540154-9E1E-409C-834F-B84BE5621388}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {43540154-9E1E-409C-834F-B84BE5621388}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {BB08260F-6FBC-46AF-8924-090EE71360C6}.Debug|ARM64.ActiveCfg = Debug|ARM64 {BB08260F-6FBC-46AF-8924-090EE71360C6}.Debug|ARM64.Build.0 = Debug|ARM64 {BB08260F-6FBC-46AF-8924-090EE71360C6}.Debug|x64.ActiveCfg = Debug|x64 @@ -153,6 +167,9 @@ Global {BB08260F-6FBC-46AF-8924-090EE71360C6}.DebugFast|x64.Build.0 = DebugFast|x64 {BB08260F-6FBC-46AF-8924-090EE71360C6}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {BB08260F-6FBC-46AF-8924-090EE71360C6}.DebugFast|x86.Build.0 = DebugFast|Win32 + {BB08260F-6FBC-46AF-8924-090EE71360C6}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {BB08260F-6FBC-46AF-8924-090EE71360C6}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {BB08260F-6FBC-46AF-8924-090EE71360C6}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {BB08260F-6FBC-46AF-8924-090EE71360C6}.Release|ARM64.ActiveCfg = Release|ARM64 {BB08260F-6FBC-46AF-8924-090EE71360C6}.Release|ARM64.Build.0 = Release|ARM64 {BB08260F-6FBC-46AF-8924-090EE71360C6}.Release|x64.ActiveCfg = Release|x64 @@ -165,6 +182,9 @@ Global {BB08260F-6FBC-46AF-8924-090EE71360C6}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {BB08260F-6FBC-46AF-8924-090EE71360C6}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {BB08260F-6FBC-46AF-8924-090EE71360C6}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {BB08260F-6FBC-46AF-8924-090EE71360C6}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {BB08260F-6FBC-46AF-8924-090EE71360C6}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {BB08260F-6FBC-46AF-8924-090EE71360C6}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {EE054E08-3799-4A59-A422-18259C105FFD}.Debug|ARM64.ActiveCfg = Debug|ARM64 {EE054E08-3799-4A59-A422-18259C105FFD}.Debug|ARM64.Build.0 = Debug|ARM64 {EE054E08-3799-4A59-A422-18259C105FFD}.Debug|x64.ActiveCfg = Debug|x64 @@ -177,6 +197,9 @@ Global {EE054E08-3799-4A59-A422-18259C105FFD}.DebugFast|x64.Build.0 = DebugFast|x64 {EE054E08-3799-4A59-A422-18259C105FFD}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {EE054E08-3799-4A59-A422-18259C105FFD}.DebugFast|x86.Build.0 = DebugFast|Win32 + {EE054E08-3799-4A59-A422-18259C105FFD}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {EE054E08-3799-4A59-A422-18259C105FFD}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {EE054E08-3799-4A59-A422-18259C105FFD}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {EE054E08-3799-4A59-A422-18259C105FFD}.Release|ARM64.ActiveCfg = Release|ARM64 {EE054E08-3799-4A59-A422-18259C105FFD}.Release|ARM64.Build.0 = Release|ARM64 {EE054E08-3799-4A59-A422-18259C105FFD}.Release|x64.ActiveCfg = Release|x64 @@ -189,6 +212,9 @@ Global {EE054E08-3799-4A59-A422-18259C105FFD}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {EE054E08-3799-4A59-A422-18259C105FFD}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {EE054E08-3799-4A59-A422-18259C105FFD}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {EE054E08-3799-4A59-A422-18259C105FFD}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {EE054E08-3799-4A59-A422-18259C105FFD}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {EE054E08-3799-4A59-A422-18259C105FFD}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {868B98C8-65A1-494B-8346-250A73A48C0A}.Debug|ARM64.ActiveCfg = Debug|ARM64 {868B98C8-65A1-494B-8346-250A73A48C0A}.Debug|ARM64.Build.0 = Debug|ARM64 {868B98C8-65A1-494B-8346-250A73A48C0A}.Debug|x64.ActiveCfg = Debug|x64 @@ -201,6 +227,9 @@ Global {868B98C8-65A1-494B-8346-250A73A48C0A}.DebugFast|x64.Build.0 = DebugFast|x64 {868B98C8-65A1-494B-8346-250A73A48C0A}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {868B98C8-65A1-494B-8346-250A73A48C0A}.DebugFast|x86.Build.0 = DebugFast|Win32 + {868B98C8-65A1-494B-8346-250A73A48C0A}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {868B98C8-65A1-494B-8346-250A73A48C0A}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {868B98C8-65A1-494B-8346-250A73A48C0A}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {868B98C8-65A1-494B-8346-250A73A48C0A}.Release|ARM64.ActiveCfg = Release|ARM64 {868B98C8-65A1-494B-8346-250A73A48C0A}.Release|ARM64.Build.0 = Release|ARM64 {868B98C8-65A1-494B-8346-250A73A48C0A}.Release|x64.ActiveCfg = Release|x64 @@ -213,6 +242,9 @@ Global {868B98C8-65A1-494B-8346-250A73A48C0A}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {868B98C8-65A1-494B-8346-250A73A48C0A}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {868B98C8-65A1-494B-8346-250A73A48C0A}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {868B98C8-65A1-494B-8346-250A73A48C0A}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {868B98C8-65A1-494B-8346-250A73A48C0A}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {868B98C8-65A1-494B-8346-250A73A48C0A}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Debug|ARM64.ActiveCfg = Debug|ARM64 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Debug|ARM64.Build.0 = Debug|ARM64 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Debug|x64.ActiveCfg = Debug|x64 @@ -225,6 +257,9 @@ Global {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.DebugFast|x64.Build.0 = DebugFast|x64 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.DebugFast|x86.Build.0 = DebugFast|Win32 + {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Release|ARM64.ActiveCfg = Release|ARM64 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Release|ARM64.Build.0 = Release|ARM64 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.Release|x64.ActiveCfg = Release|x64 @@ -237,6 +272,9 @@ Global {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {ED601289-AC1A-46B8-A8ED-17DB9EB73423}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {3773F4CC-614E-4028-8595-22E08CA649E3}.Debug|ARM64.ActiveCfg = Debug|ARM64 {3773F4CC-614E-4028-8595-22E08CA649E3}.Debug|ARM64.Build.0 = Debug|ARM64 {3773F4CC-614E-4028-8595-22E08CA649E3}.Debug|x64.ActiveCfg = Debug|x64 @@ -249,6 +287,9 @@ Global {3773F4CC-614E-4028-8595-22E08CA649E3}.DebugFast|x64.Build.0 = DebugFast|x64 {3773F4CC-614E-4028-8595-22E08CA649E3}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {3773F4CC-614E-4028-8595-22E08CA649E3}.DebugFast|x86.Build.0 = DebugFast|Win32 + {3773F4CC-614E-4028-8595-22E08CA649E3}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {3773F4CC-614E-4028-8595-22E08CA649E3}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {3773F4CC-614E-4028-8595-22E08CA649E3}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {3773F4CC-614E-4028-8595-22E08CA649E3}.Release|ARM64.ActiveCfg = Release|ARM64 {3773F4CC-614E-4028-8595-22E08CA649E3}.Release|ARM64.Build.0 = Release|ARM64 {3773F4CC-614E-4028-8595-22E08CA649E3}.Release|x64.ActiveCfg = Release|x64 @@ -261,6 +302,9 @@ Global {3773F4CC-614E-4028-8595-22E08CA649E3}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {3773F4CC-614E-4028-8595-22E08CA649E3}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {3773F4CC-614E-4028-8595-22E08CA649E3}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {3773F4CC-614E-4028-8595-22E08CA649E3}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {3773F4CC-614E-4028-8595-22E08CA649E3}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {3773F4CC-614E-4028-8595-22E08CA649E3}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {933118A9-68C5-47B4-B151-B03C93961623}.Debug|ARM64.ActiveCfg = Debug|ARM64 {933118A9-68C5-47B4-B151-B03C93961623}.Debug|ARM64.Build.0 = Debug|ARM64 {933118A9-68C5-47B4-B151-B03C93961623}.Debug|x64.ActiveCfg = Debug|x64 @@ -273,6 +317,9 @@ Global {933118A9-68C5-47B4-B151-B03C93961623}.DebugFast|x64.Build.0 = DebugFast|x64 {933118A9-68C5-47B4-B151-B03C93961623}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {933118A9-68C5-47B4-B151-B03C93961623}.DebugFast|x86.Build.0 = DebugFast|Win32 + {933118A9-68C5-47B4-B151-B03C93961623}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {933118A9-68C5-47B4-B151-B03C93961623}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {933118A9-68C5-47B4-B151-B03C93961623}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {933118A9-68C5-47B4-B151-B03C93961623}.Release|ARM64.ActiveCfg = Release|ARM64 {933118A9-68C5-47B4-B151-B03C93961623}.Release|ARM64.Build.0 = Release|ARM64 {933118A9-68C5-47B4-B151-B03C93961623}.Release|x64.ActiveCfg = Release|x64 @@ -285,6 +332,9 @@ Global {933118A9-68C5-47B4-B151-B03C93961623}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {933118A9-68C5-47B4-B151-B03C93961623}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {933118A9-68C5-47B4-B151-B03C93961623}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {933118A9-68C5-47B4-B151-B03C93961623}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {933118A9-68C5-47B4-B151-B03C93961623}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {933118A9-68C5-47B4-B151-B03C93961623}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {28F14272-0EC4-41BB-849F-182ADB81AF70}.Debug|ARM64.ActiveCfg = Debug|ARM64 {28F14272-0EC4-41BB-849F-182ADB81AF70}.Debug|ARM64.Build.0 = Debug|ARM64 {28F14272-0EC4-41BB-849F-182ADB81AF70}.Debug|x64.ActiveCfg = Debug|x64 @@ -297,6 +347,9 @@ Global {28F14272-0EC4-41BB-849F-182ADB81AF70}.DebugFast|x64.Build.0 = DebugFast|x64 {28F14272-0EC4-41BB-849F-182ADB81AF70}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {28F14272-0EC4-41BB-849F-182ADB81AF70}.DebugFast|x86.Build.0 = DebugFast|Win32 + {28F14272-0EC4-41BB-849F-182ADB81AF70}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {28F14272-0EC4-41BB-849F-182ADB81AF70}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {28F14272-0EC4-41BB-849F-182ADB81AF70}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {28F14272-0EC4-41BB-849F-182ADB81AF70}.Release|ARM64.ActiveCfg = Release|ARM64 {28F14272-0EC4-41BB-849F-182ADB81AF70}.Release|ARM64.Build.0 = Release|ARM64 {28F14272-0EC4-41BB-849F-182ADB81AF70}.Release|x64.ActiveCfg = Release|x64 @@ -309,6 +362,9 @@ Global {28F14272-0EC4-41BB-849F-182ADB81AF70}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {28F14272-0EC4-41BB-849F-182ADB81AF70}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {28F14272-0EC4-41BB-849F-182ADB81AF70}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {28F14272-0EC4-41BB-849F-182ADB81AF70}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {28F14272-0EC4-41BB-849F-182ADB81AF70}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {28F14272-0EC4-41BB-849F-182ADB81AF70}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.Debug|ARM64.ActiveCfg = Debug|ARM64 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.Debug|ARM64.Build.0 = Debug|ARM64 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.Debug|x64.ActiveCfg = Debug|x64 @@ -321,6 +377,9 @@ Global {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.DebugFast|x64.Build.0 = DebugFast|x64 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.DebugFast|x86.Build.0 = DebugFast|Win32 + {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.Release|ARM64.ActiveCfg = Release|ARM64 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.Release|ARM64.Build.0 = Release|ARM64 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.Release|x64.ActiveCfg = Release|x64 @@ -333,6 +392,9 @@ Global {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {72F9423C-91EE-4487-AAC6-555ED6F61AA1}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {8BDA439C-6358-45FB-9994-2FF083BABE06}.Debug|ARM64.ActiveCfg = Debug|ARM64 {8BDA439C-6358-45FB-9994-2FF083BABE06}.Debug|ARM64.Build.0 = Debug|ARM64 {8BDA439C-6358-45FB-9994-2FF083BABE06}.Debug|x64.ActiveCfg = Debug|x64 @@ -345,6 +407,9 @@ Global {8BDA439C-6358-45FB-9994-2FF083BABE06}.DebugFast|x64.Build.0 = DebugFast|x64 {8BDA439C-6358-45FB-9994-2FF083BABE06}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {8BDA439C-6358-45FB-9994-2FF083BABE06}.DebugFast|x86.Build.0 = DebugFast|Win32 + {8BDA439C-6358-45FB-9994-2FF083BABE06}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {8BDA439C-6358-45FB-9994-2FF083BABE06}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {8BDA439C-6358-45FB-9994-2FF083BABE06}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {8BDA439C-6358-45FB-9994-2FF083BABE06}.Release|ARM64.ActiveCfg = Release|ARM64 {8BDA439C-6358-45FB-9994-2FF083BABE06}.Release|ARM64.Build.0 = Release|ARM64 {8BDA439C-6358-45FB-9994-2FF083BABE06}.Release|x64.ActiveCfg = Release|x64 @@ -357,6 +422,9 @@ Global {8BDA439C-6358-45FB-9994-2FF083BABE06}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {8BDA439C-6358-45FB-9994-2FF083BABE06}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {8BDA439C-6358-45FB-9994-2FF083BABE06}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {8BDA439C-6358-45FB-9994-2FF083BABE06}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {8BDA439C-6358-45FB-9994-2FF083BABE06}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {8BDA439C-6358-45FB-9994-2FF083BABE06}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {7FF9FDB9-D504-47DB-A16A-B08071999620}.Debug|ARM64.ActiveCfg = Debug|ARM64 {7FF9FDB9-D504-47DB-A16A-B08071999620}.Debug|ARM64.Build.0 = Debug|ARM64 {7FF9FDB9-D504-47DB-A16A-B08071999620}.Debug|x64.ActiveCfg = Debug|x64 @@ -369,6 +437,9 @@ Global {7FF9FDB9-D504-47DB-A16A-B08071999620}.DebugFast|x64.Build.0 = DebugFast|x64 {7FF9FDB9-D504-47DB-A16A-B08071999620}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {7FF9FDB9-D504-47DB-A16A-B08071999620}.DebugFast|x86.Build.0 = DebugFast|Win32 + {7FF9FDB9-D504-47DB-A16A-B08071999620}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {7FF9FDB9-D504-47DB-A16A-B08071999620}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {7FF9FDB9-D504-47DB-A16A-B08071999620}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {7FF9FDB9-D504-47DB-A16A-B08071999620}.Release|ARM64.ActiveCfg = Release|ARM64 {7FF9FDB9-D504-47DB-A16A-B08071999620}.Release|ARM64.Build.0 = Release|ARM64 {7FF9FDB9-D504-47DB-A16A-B08071999620}.Release|x64.ActiveCfg = Release|x64 @@ -381,6 +452,9 @@ Global {7FF9FDB9-D504-47DB-A16A-B08071999620}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {7FF9FDB9-D504-47DB-A16A-B08071999620}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {7FF9FDB9-D504-47DB-A16A-B08071999620}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {7FF9FDB9-D504-47DB-A16A-B08071999620}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {7FF9FDB9-D504-47DB-A16A-B08071999620}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {7FF9FDB9-D504-47DB-A16A-B08071999620}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.Debug|ARM64.ActiveCfg = Debug|ARM64 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.Debug|ARM64.Build.0 = Debug|ARM64 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.Debug|x64.ActiveCfg = Debug|x64 @@ -393,6 +467,9 @@ Global {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.DebugFast|x64.Build.0 = DebugFast|x64 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.DebugFast|x86.Build.0 = DebugFast|Win32 + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.Release|ARM64.ActiveCfg = Release|ARM64 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.Release|ARM64.Build.0 = Release|ARM64 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.Release|x64.ActiveCfg = Release|x64 @@ -405,6 +482,9 @@ Global {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.Debug|ARM64.ActiveCfg = Debug|ARM64 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.Debug|ARM64.Build.0 = Debug|ARM64 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.Debug|x64.ActiveCfg = Debug|x64 @@ -417,6 +497,9 @@ Global {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.DebugFast|x64.Build.0 = DebugFast|x64 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.DebugFast|x86.Build.0 = DebugFast|Win32 + {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.Release|ARM64.ActiveCfg = Release|ARM64 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.Release|ARM64.Build.0 = Release|ARM64 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.Release|x64.ActiveCfg = Release|x64 @@ -429,6 +512,9 @@ Global {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {97CBD3CB-CBC7-4D52-ABDE-F0AE7B794A5D}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {DD944834-7899-4C1C-A4C1-064B5009D239}.Debug|ARM64.ActiveCfg = Debug|ARM64 {DD944834-7899-4C1C-A4C1-064B5009D239}.Debug|ARM64.Build.0 = Debug|ARM64 {DD944834-7899-4C1C-A4C1-064B5009D239}.Debug|x64.ActiveCfg = Debug|x64 @@ -441,6 +527,9 @@ Global {DD944834-7899-4C1C-A4C1-064B5009D239}.DebugFast|x64.Build.0 = DebugFast|x64 {DD944834-7899-4C1C-A4C1-064B5009D239}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {DD944834-7899-4C1C-A4C1-064B5009D239}.DebugFast|x86.Build.0 = DebugFast|Win32 + {DD944834-7899-4C1C-A4C1-064B5009D239}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {DD944834-7899-4C1C-A4C1-064B5009D239}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {DD944834-7899-4C1C-A4C1-064B5009D239}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {DD944834-7899-4C1C-A4C1-064B5009D239}.Release|ARM64.ActiveCfg = Release|ARM64 {DD944834-7899-4C1C-A4C1-064B5009D239}.Release|ARM64.Build.0 = Release|ARM64 {DD944834-7899-4C1C-A4C1-064B5009D239}.Release|x64.ActiveCfg = Release|x64 @@ -453,6 +542,9 @@ Global {DD944834-7899-4C1C-A4C1-064B5009D239}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {DD944834-7899-4C1C-A4C1-064B5009D239}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {DD944834-7899-4C1C-A4C1-064B5009D239}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {DD944834-7899-4C1C-A4C1-064B5009D239}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {DD944834-7899-4C1C-A4C1-064B5009D239}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {DD944834-7899-4C1C-A4C1-064B5009D239}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.Debug|ARM64.Build.0 = Debug|ARM64 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.Debug|x64.ActiveCfg = Debug|x64 @@ -465,6 +557,9 @@ Global {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.DebugFast|x64.Build.0 = DebugFast|x64 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.DebugFast|x86.Build.0 = DebugFast|Win32 + {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.Release|ARM64.ActiveCfg = Release|ARM64 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.Release|ARM64.Build.0 = Release|ARM64 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.Release|x64.ActiveCfg = Release|x64 @@ -477,6 +572,9 @@ Global {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {6245DEC8-D2DA-47EE-A373-CBD6FCF3ECE6}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.Debug|ARM64.ActiveCfg = Debug|ARM64 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.Debug|ARM64.Build.0 = Debug|ARM64 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.Debug|x64.ActiveCfg = Debug|x64 @@ -489,6 +587,9 @@ Global {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.DebugFast|x64.Build.0 = DebugFast|x64 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.DebugFast|x86.Build.0 = DebugFast|Win32 + {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.Release|ARM64.ActiveCfg = Release|ARM64 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.Release|ARM64.Build.0 = Release|ARM64 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.Release|x64.ActiveCfg = Release|x64 @@ -501,6 +602,9 @@ Global {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {09553C96-9F39-49BF-8AE6-7ACBD07C410C}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|ARM64.ActiveCfg = Debug|ARM64 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|ARM64.Build.0 = Debug|ARM64 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Debug|x64.ActiveCfg = Debug|x64 @@ -513,6 +617,9 @@ Global {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x64.Build.0 = DebugFast|x64 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugFast|x86.Build.0 = DebugFast|Win32 + {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|ARM64.ActiveCfg = Release|ARM64 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|ARM64.Build.0 = Release|ARM64 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.Release|x64.ActiveCfg = Release|x64 @@ -525,6 +632,9 @@ Global {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {49953E1B-2EF7-46A4-B88B-1BF9E099093B}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.Debug|ARM64.ActiveCfg = Debug|ARM64 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.Debug|ARM64.Build.0 = Debug|ARM64 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.Debug|x64.ActiveCfg = Debug|x64 @@ -537,6 +647,9 @@ Global {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.DebugFast|x64.Build.0 = DebugFast|x64 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.DebugFast|x86.Build.0 = DebugFast|Win32 + {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.Release|ARM64.ActiveCfg = Release|ARM64 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.Release|ARM64.Build.0 = Release|ARM64 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.Release|x64.ActiveCfg = Release|x64 @@ -549,6 +662,9 @@ Global {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {EA2B9C7A-B8CC-42F9-879B-191A98680C10}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.Debug|ARM64.ActiveCfg = Debug|ARM64 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.Debug|ARM64.Build.0 = Debug|ARM64 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.Debug|x64.ActiveCfg = Debug|x64 @@ -561,6 +677,9 @@ Global {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.DebugFast|x64.Build.0 = DebugFast|x64 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.DebugFast|x86.Build.0 = DebugFast|Win32 + {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.Release|ARM64.ActiveCfg = Release|ARM64 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.Release|ARM64.Build.0 = Release|ARM64 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.Release|x64.ActiveCfg = Release|x64 @@ -573,6 +692,9 @@ Global {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {075CED82-6A20-46DF-94C7-9624AC9DDBEB}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.Debug|ARM64.ActiveCfg = Debug|ARM64 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.Debug|ARM64.Build.0 = Debug|ARM64 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.Debug|x64.ActiveCfg = Debug|x64 @@ -585,6 +707,9 @@ Global {4266505B-DBAF-484B-AB31-B53B9C8235B3}.DebugFast|x64.Build.0 = DebugFast|x64 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.DebugFast|x86.Build.0 = DebugFast|Win32 + {4266505B-DBAF-484B-AB31-B53B9C8235B3}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {4266505B-DBAF-484B-AB31-B53B9C8235B3}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {4266505B-DBAF-484B-AB31-B53B9C8235B3}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.Release|ARM64.ActiveCfg = Release|ARM64 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.Release|ARM64.Build.0 = Release|ARM64 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.Release|x64.ActiveCfg = Release|x64 @@ -597,6 +722,9 @@ Global {4266505B-DBAF-484B-AB31-B53B9C8235B3}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {4266505B-DBAF-484B-AB31-B53B9C8235B3}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {4266505B-DBAF-484B-AB31-B53B9C8235B3}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {4266505B-DBAF-484B-AB31-B53B9C8235B3}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {4266505B-DBAF-484B-AB31-B53B9C8235B3}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.Debug|ARM64.ActiveCfg = Debug|ARM64 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.Debug|ARM64.Build.0 = Debug|ARM64 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.Debug|x64.ActiveCfg = Debug|x64 @@ -609,6 +737,9 @@ Global {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.DebugFast|x64.Build.0 = DebugFast|x64 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.DebugFast|x86.Build.0 = DebugFast|Win32 + {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.Release|ARM64.ActiveCfg = Release|ARM64 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.Release|ARM64.Build.0 = Release|ARM64 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.Release|x64.ActiveCfg = Release|x64 @@ -621,6 +752,9 @@ Global {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {7F909E29-4808-4BD9-A60C-56C51A3AAEC2}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.Debug|ARM64.ActiveCfg = Debug|ARM64 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.Debug|ARM64.Build.0 = Debug|ARM64 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.Debug|x64.ActiveCfg = Debug|x64 @@ -633,6 +767,9 @@ Global {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.DebugFast|x64.Build.0 = DebugFast|x64 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.DebugFast|x86.Build.0 = DebugFast|Win32 + {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.Release|ARM64.ActiveCfg = Release|ARM64 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.Release|ARM64.Build.0 = Release|ARM64 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.Release|x64.ActiveCfg = Release|x64 @@ -645,6 +782,9 @@ Global {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {9C8DDEB0-2B8F-4F5F-BA86-127CDF27F035}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.Debug|ARM64.ActiveCfg = Debug|ARM64 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.Debug|ARM64.Build.0 = Debug|ARM64 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.Debug|x64.ActiveCfg = Debug|x64 @@ -657,6 +797,9 @@ Global {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.DebugFast|x64.Build.0 = DebugFast|x64 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.DebugFast|x86.Build.0 = DebugFast|Win32 + {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.Release|ARM64.ActiveCfg = Release|ARM64 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.Release|ARM64.Build.0 = Release|ARM64 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.Release|x64.ActiveCfg = Release|x64 @@ -669,6 +812,9 @@ Global {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {32EEAF44-57F8-4C6C-A6F0-DE5667123DD5}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.Debug|ARM64.ActiveCfg = Debug|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.Debug|ARM64.Build.0 = Debug|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.Debug|x64.ActiveCfg = Debug|ARM64 @@ -677,6 +823,9 @@ Global {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.DebugFast|ARM64.Build.0 = DebugFast|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.DebugFast|x64.ActiveCfg = DebugFast|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.DebugFast|x86.ActiveCfg = DebugFast|ARM64 + {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.Release|ARM64.ActiveCfg = Release|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.Release|ARM64.Build.0 = Release|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.Release|x64.ActiveCfg = Release|ARM64 @@ -685,6 +834,9 @@ Global {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.ReleaseLTCG|ARM64.Build.0 = ReleaseLTCG|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.ReleaseLTCG|x64.ActiveCfg = ReleaseLTCG|ARM64 {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|ARM64 + {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {8906836E-F06E-46E8-B11A-74E5E8C7B8FB}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.Debug|ARM64.ActiveCfg = Debug|ARM64 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.Debug|ARM64.Build.0 = Debug|ARM64 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.Debug|x64.ActiveCfg = Debug|x64 @@ -697,6 +849,9 @@ Global {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.DebugFast|x64.Build.0 = DebugFast|x64 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.DebugFast|x86.Build.0 = DebugFast|Win32 + {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.Release|ARM64.ActiveCfg = Release|ARM64 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.Release|ARM64.Build.0 = Release|ARM64 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.Release|x64.ActiveCfg = Release|x64 @@ -709,6 +864,9 @@ Global {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|ARM64.ActiveCfg = Debug|ARM64 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|ARM64.Build.0 = Debug|ARM64 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|x64.ActiveCfg = Debug|x64 @@ -721,6 +879,9 @@ Global {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x64.Build.0 = DebugFast|x64 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x86.Build.0 = DebugFast|Win32 + {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|ARM64.ActiveCfg = Release|ARM64 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|ARM64.Build.0 = Release|ARM64 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x64.ActiveCfg = Release|x64 @@ -733,6 +894,9 @@ Global {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.Debug|ARM64.ActiveCfg = Debug|ARM64 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.Debug|ARM64.Build.0 = Debug|ARM64 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.Debug|x64.ActiveCfg = Debug|x64 @@ -745,6 +909,9 @@ Global {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.DebugFast|x64.Build.0 = DebugFast|x64 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.DebugFast|x86.ActiveCfg = DebugFast|Win32 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.DebugFast|x86.Build.0 = DebugFast|Win32 + {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.Release|ARM64.ActiveCfg = Release|ARM64 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.Release|ARM64.Build.0 = Release|ARM64 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.Release|x64.ActiveCfg = Release|x64 @@ -757,6 +924,27 @@ Global {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32 + {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {4BA0A6D4-3AE1-42B2-9347-096FD023FF64}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 + {3029310E-4211-4C87-801A-72E130A648EF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {3029310E-4211-4C87-801A-72E130A648EF}.Debug|x64.ActiveCfg = Debug|x64 + {3029310E-4211-4C87-801A-72E130A648EF}.Debug|x86.ActiveCfg = Debug|Win32 + {3029310E-4211-4C87-801A-72E130A648EF}.DebugFast|ARM64.ActiveCfg = DebugFast|ARM64 + {3029310E-4211-4C87-801A-72E130A648EF}.DebugFast|x64.ActiveCfg = DebugFast|x64 + {3029310E-4211-4C87-801A-72E130A648EF}.DebugFast|x86.ActiveCfg = DebugFast|Win32 + {3029310E-4211-4C87-801A-72E130A648EF}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64 + {3029310E-4211-4C87-801A-72E130A648EF}.DebugUWP|x64.ActiveCfg = DebugUWP|x64 + {3029310E-4211-4C87-801A-72E130A648EF}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32 + {3029310E-4211-4C87-801A-72E130A648EF}.Release|ARM64.ActiveCfg = Release|ARM64 + {3029310E-4211-4C87-801A-72E130A648EF}.Release|x64.ActiveCfg = Release|x64 + {3029310E-4211-4C87-801A-72E130A648EF}.Release|x86.ActiveCfg = Release|Win32 + {3029310E-4211-4C87-801A-72E130A648EF}.ReleaseLTCG|ARM64.ActiveCfg = ReleaseLTCG|ARM64 + {3029310E-4211-4C87-801A-72E130A648EF}.ReleaseLTCG|x64.ActiveCfg = ReleaseLTCG|x64 + {3029310E-4211-4C87-801A-72E130A648EF}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32 + {3029310E-4211-4C87-801A-72E130A648EF}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64 + {3029310E-4211-4C87-801A-72E130A648EF}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64 + {3029310E-4211-4C87-801A-72E130A648EF}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4dae348af..cd61d4c82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,3 +29,6 @@ if(BUILD_LIBRETRO_CORE) add_subdirectory(duckstation-libretro) endif() +if(BUILD_REGTEST) + add_subdirectory(duckstation-regtest) +endif() diff --git a/src/duckstation-regtest/CMakeLists.txt b/src/duckstation-regtest/CMakeLists.txt new file mode 100644 index 000000000..89fbc4969 --- /dev/null +++ b/src/duckstation-regtest/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable(duckstation-regtest + regtest_host_display.cpp + regtest_host_display.h + regtest_host_interface.cpp + regtest_host_interface.h + regtest_settings_interface.cpp + regtest_settings_interface.h +) + +target_link_libraries(duckstation-regtest PRIVATE core common frontend-common scmversion) diff --git a/src/duckstation-regtest/duckstation-regtest.vcxproj b/src/duckstation-regtest/duckstation-regtest.vcxproj new file mode 100644 index 000000000..37b1824b0 --- /dev/null +++ b/src/duckstation-regtest/duckstation-regtest.vcxproj @@ -0,0 +1,25 @@ + + + + + {3029310E-4211-4C87-801A-72E130A648EF} + + + + + + + + + + + + + + + + $(RootBuildDir)frontend-common\frontend-common.lib;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/src/duckstation-regtest/duckstation-regtest.vcxproj.filters b/src/duckstation-regtest/duckstation-regtest.vcxproj.filters new file mode 100644 index 000000000..79aad0c97 --- /dev/null +++ b/src/duckstation-regtest/duckstation-regtest.vcxproj.filters @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/duckstation-regtest/regtest_host_display.cpp b/src/duckstation-regtest/regtest_host_display.cpp new file mode 100644 index 000000000..dc896d713 --- /dev/null +++ b/src/duckstation-regtest/regtest_host_display.cpp @@ -0,0 +1,221 @@ +#include "regtest_host_display.h" +#include "common/align.h" +#include "common/assert.h" +#include "common/file_system.h" +#include "common/image.h" +#include "common/log.h" +#include "common/string_util.h" +#include +#include +Log_SetChannel(RegTestHostDisplay); + +RegTestHostDisplay::RegTestHostDisplay() = default; + +RegTestHostDisplay::~RegTestHostDisplay() = default; + +HostDisplay::RenderAPI RegTestHostDisplay::GetRenderAPI() const +{ + return RenderAPI::None; +} + +void* RegTestHostDisplay::GetRenderDevice() const +{ + return nullptr; +} + +void* RegTestHostDisplay::GetRenderContext() const +{ + return nullptr; +} + +bool RegTestHostDisplay::HasRenderDevice() const +{ + return true; +} + +bool RegTestHostDisplay::HasRenderSurface() const +{ + return true; +} + +bool RegTestHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool debug_device, + bool threaded_presentation) +{ + m_window_info = wi; + return true; +} + +bool RegTestHostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device, + bool threaded_presentation) +{ + return true; +} + +bool RegTestHostDisplay::MakeRenderContextCurrent() +{ + return true; +} + +bool RegTestHostDisplay::DoneRenderContextCurrent() +{ + return true; +} + +void RegTestHostDisplay::DestroyRenderDevice() +{ + ClearSoftwareCursor(); +} + +void RegTestHostDisplay::DestroyRenderSurface() {} + +bool RegTestHostDisplay::CreateResources() +{ + return true; +} + +void RegTestHostDisplay::DestroyResources() {} + +HostDisplay::AdapterAndModeList RegTestHostDisplay::GetAdapterAndModeList() +{ + return {}; +} + +bool RegTestHostDisplay::CreateImGuiContext() +{ + return true; +} + +void RegTestHostDisplay::DestroyImGuiContext() +{ + // noop +} + +bool RegTestHostDisplay::UpdateImGuiFontTexture() +{ + // noop + return true; +} + +bool RegTestHostDisplay::ChangeRenderWindow(const WindowInfo& wi) +{ + m_window_info = wi; + return true; +} + +void RegTestHostDisplay::ResizeRenderWindow(s32 new_window_width, s32 new_window_height) +{ + m_window_info.surface_width = new_window_width; + m_window_info.surface_height = new_window_height; +} + +bool RegTestHostDisplay::SupportsFullscreen() const +{ + return false; +} + +bool RegTestHostDisplay::IsFullscreen() +{ + return false; +} + +bool RegTestHostDisplay::SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) +{ + return false; +} + +bool RegTestHostDisplay::SetPostProcessingChain(const std::string_view& config) +{ + return false; +} + +std::unique_ptr RegTestHostDisplay::CreateTexture(u32 width, u32 height, u32 layers, u32 levels, + u32 samples, HostDisplayPixelFormat format, + const void* data, u32 data_stride, + bool dynamic /* = false */) +{ + return nullptr; +} + +void RegTestHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, + const void* data, u32 data_stride) +{ +} + +bool RegTestHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, + u32 y, u32 width, u32 height, void* out_data, u32 out_data_stride) +{ + const u32 pixel_size = GetDisplayPixelFormatSize(texture_format); + const u32 input_stride = Common::AlignUpPow2(width * pixel_size, 4); + const u8* input_start = static_cast(texture_handle) + (x * pixel_size); + StringUtil::StrideMemCpy(out_data, out_data_stride, input_start, input_stride, width * pixel_size, height); + return true; +} + +bool RegTestHostDisplay::SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const +{ + return (format == HostDisplayPixelFormat::RGBA8); +} + +bool RegTestHostDisplay::BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer, + u32* out_pitch) +{ + const u32 pixel_size = GetDisplayPixelFormatSize(format); + const u32 pitch = Common::AlignUpPow2(width * GetDisplayPixelFormatSize(format), 4); + const u32 required_size = height * pitch; + if (m_frame_buffer.size() != (required_size / 4)) + { + m_frame_buffer.clear(); + m_frame_buffer.resize(required_size / 4); + } + + // border is already filled here + m_frame_buffer_pitch = pitch; + SetDisplayTexture(m_frame_buffer.data(), format, width, height, 0, 0, width, height); + *out_buffer = reinterpret_cast(m_frame_buffer.data()); + *out_pitch = pitch; + return true; +} + +void RegTestHostDisplay::EndSetDisplayPixels() +{ + // noop +} + +void RegTestHostDisplay::DumpFrame(const std::string& filename) +{ + if (!HasDisplayTexture()) + { + if (FileSystem::FileExists(filename.c_str())) + FileSystem::DeleteFile(filename.c_str()); + + return; + } + + Common::RGBA8Image image(m_display_texture_width, m_display_texture_height, + static_cast(m_display_texture_handle)); + + // set alpha channel on all pixels + u32* pixels = image.GetPixels(); + u32* pixels_end = pixels + (image.GetWidth() * image.GetHeight()); + while (pixels != pixels_end) + *(pixels++) |= 0xFF000000u; + + if (!Common::WriteImageToFile(image, filename.c_str())) + Log_ErrorPrintf("Failed to dump frame '%s'", filename.c_str()); +} + +void RegTestHostDisplay::SetVSync(bool enabled) +{ + Log_DevPrintf("Ignoring SetVSync(%u)", BoolToUInt32(enabled)); +} + +bool RegTestHostDisplay::Render() +{ + return true; +} + +bool RegTestHostDisplay::RenderScreenshot(u32 width, u32 height, std::vector* out_pixels, u32* out_stride, + HostDisplayPixelFormat* out_format) +{ + return false; +} diff --git a/src/duckstation-regtest/regtest_host_display.h b/src/duckstation-regtest/regtest_host_display.h new file mode 100644 index 000000000..5fccb310b --- /dev/null +++ b/src/duckstation-regtest/regtest_host_display.h @@ -0,0 +1,70 @@ +#pragma once +#include "core/host_display.h" +#include + +class RegTestHostDisplay final : public HostDisplay +{ +public: + RegTestHostDisplay(); + ~RegTestHostDisplay(); + + void DumpFrame(const std::string& filename); + + RenderAPI GetRenderAPI() const override; + void* GetRenderDevice() const override; + void* GetRenderContext() const override; + + bool HasRenderDevice() const override; + bool HasRenderSurface() const override; + + bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool debug_device, + bool threaded_presentation) override; + bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device, + bool threaded_presentation) override; + void DestroyRenderDevice() override; + + bool MakeRenderContextCurrent() override; + bool DoneRenderContextCurrent() override; + + bool ChangeRenderWindow(const WindowInfo& wi) override; + void ResizeRenderWindow(s32 new_window_width, s32 new_window_height) override; + bool SupportsFullscreen() const override; + bool IsFullscreen() override; + bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) override; + void DestroyRenderSurface() override; + + bool SetPostProcessingChain(const std::string_view& config) override; + + bool CreateResources() override; + void DestroyResources() override; + + AdapterAndModeList GetAdapterAndModeList() override; + bool CreateImGuiContext() override; + void DestroyImGuiContext() override; + bool UpdateImGuiFontTexture() override; + + std::unique_ptr CreateTexture(u32 width, u32 height, u32 layers, u32 levels, u32 samples, + HostDisplayPixelFormat format, const void* data, u32 data_stride, + bool dynamic = false) override; + void UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, + u32 data_stride) override; + bool DownloadTexture(const void* texture_handle, HostDisplayPixelFormat texture_format, u32 x, u32 y, u32 width, + u32 height, void* out_data, u32 out_data_stride) override; + + void SetVSync(bool enabled) override; + + bool Render() override; + bool RenderScreenshot(u32 width, u32 height, std::vector* out_pixels, u32* out_stride, + HostDisplayPixelFormat* out_format) override; + + bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const override; + + bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer, + u32* out_pitch) override; + void EndSetDisplayPixels() override; + +private: + std::vector m_frame_buffer; + HostDisplayPixelFormat m_frame_buffer_format = HostDisplayPixelFormat::Unknown; + u32 m_frame_buffer_pitch = 0; +}; diff --git a/src/duckstation-regtest/regtest_host_interface.cpp b/src/duckstation-regtest/regtest_host_interface.cpp new file mode 100644 index 000000000..d38b589f6 --- /dev/null +++ b/src/duckstation-regtest/regtest_host_interface.cpp @@ -0,0 +1,498 @@ +#include "regtest_host_interface.h" +#include "common/assert.h" +#include "common/audio_stream.h" +#include "common/byte_stream.h" +#include "common/file_system.h" +#include "common/log.h" +#include "common/string_util.h" +#include "core/system.h" +#include "frontend-common/game_database.h" +#include "frontend-common/game_settings.h" +#include "regtest_host_display.h" +#include "scmversion/scmversion.h" +#include +Log_SetChannel(RegTestHostInterface); + +#ifdef _WIN32 +#include "frontend-common/d3d11_host_display.h" +#include "frontend-common/d3d12_host_display.h" +#endif + +#include "frontend-common/opengl_host_display.h" +#include "frontend-common/vulkan_host_display.h" + +static int s_frames_to_run = 60 * 60; +static int s_frame_dump_interval = 0; +static std::shared_ptr s_boot_parameters; +static std::string s_dump_base_directory; +static std::string s_dump_game_directory; +static GPURenderer s_renderer_to_use = GPURenderer::Software; +static GameSettings::Database s_game_settings_db; +static GameDatabase s_game_database; + +RegTestHostInterface::RegTestHostInterface() = default; + +RegTestHostInterface::~RegTestHostInterface() = default; + +bool RegTestHostInterface::Initialize() +{ + if (!HostInterface::Initialize()) + return false; + + SetUserDirectoryToProgramDirectory(); + s_game_database.Load(); + LoadGameSettingsDatabase(); + InitializeSettings(); + return true; +} + +void RegTestHostInterface::Shutdown() +{ + HostInterface::Shutdown(); +} + +void RegTestHostInterface::ReportError(const char* message) +{ + Log_ErrorPrintf("Error: %s", message); +} + +void RegTestHostInterface::ReportMessage(const char* message) +{ + Log_InfoPrintf("Info: %s", message); +} + +void RegTestHostInterface::ReportDebuggerMessage(const char* message) +{ + Log_DevPrintf("Debugger: %s", message); +} + +bool RegTestHostInterface::ConfirmMessage(const char* message) +{ + Log_InfoPrintf("Confirm: %s", message); + return false; +} + +void RegTestHostInterface::AddOSDMessage(std::string message, float duration /*= 2.0f*/) +{ + Log_InfoPrintf("OSD: %s", message.c_str()); +} + +void RegTestHostInterface::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/, + int progress_max /*= -1*/, int progress_value /*= -1*/) +{ + Log_InfoPrintf("Loading: %s (%d / %d)", message, progress_value + progress_min, progress_max); +} + +void RegTestHostInterface::GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title) +{ + if (image) + { + GameDatabaseEntry database_entry; + if (s_game_database.GetEntryForDisc(image, &database_entry)) + { + *code = std::move(database_entry.serial); + *title = std::move(database_entry.title); + return; + } + + *code = System::GetGameCodeForImage(image, true); + } + + *title = FileSystem::GetFileTitleFromPath(path); +} + +void RegTestHostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code, + const std::string& game_title) +{ + HostInterface::OnRunningGameChanged(path, image, game_code, game_title); + + Log_InfoPrintf("Game Path: %s", path.c_str()); + Log_InfoPrintf("Game Code: %s", game_code.c_str()); + Log_InfoPrintf("Game Title: %s", game_title.c_str()); + + if (!s_dump_base_directory.empty()) + { + s_dump_game_directory = StringUtil::StdStringFromFormat("%s" FS_OSPATH_SEPARATOR_STR "%s", + s_dump_base_directory.c_str(), game_title.c_str()); + + if (!FileSystem::DirectoryExists(s_dump_game_directory.c_str())) + { + Log_InfoPrintf("Creating directory '%s'...", s_dump_game_directory.c_str()); + if (!FileSystem::CreateDirectory(s_dump_game_directory.c_str(), false)) + Panic("Failed to create dump directory."); + } + + Log_InfoPrintf("Dumping frames to '%s'...", s_dump_game_directory.c_str()); + } + + UpdateSettings(); +} + +std::string RegTestHostInterface::GetStringSettingValue(const char* section, const char* key, + const char* default_value /*= ""*/) +{ + return m_settings_interface.GetStringValue(section, key, default_value); +} + +bool RegTestHostInterface::GetBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/) +{ + return m_settings_interface.GetBoolValue(section, key, default_value); +} + +int RegTestHostInterface::GetIntSettingValue(const char* section, const char* key, int default_value /*= 0*/) +{ + return m_settings_interface.GetIntValue(section, key, default_value); +} + +float RegTestHostInterface::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/) +{ + return m_settings_interface.GetFloatValue(section, key, default_value); +} + +std::vector RegTestHostInterface::GetSettingStringList(const char* section, const char* key) +{ + return m_settings_interface.GetStringList(section, key); +} + +void RegTestHostInterface::UpdateSettings() +{ + SettingsInterface& si = m_settings_interface; + HostInterface::LoadSettings(si); + + const std::string& code = System::GetRunningCode(); + if (!code.empty()) + { + const GameSettings::Entry* entry = s_game_settings_db.GetEntry(code); + if (entry) + { + Log_InfoPrintf("Applying game settings for '%s'", code.c_str()); + entry->ApplySettings(true); + } + } + + HostInterface::FixIncompatibleSettings(true); +} + +void RegTestHostInterface::LoadGameSettingsDatabase() +{ + const char* path = "database" FS_OSPATH_SEPARATOR_STR "gamesettings.ini"; + std::unique_ptr stream = OpenPackageFile(path, BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED); + if (!stream) + { + Log_ErrorPrintf("Failed to open game settings database from '%s'. This could cause compatibility issues.", path); + return; + } + + const std::string data(FileSystem::ReadStreamToString(stream.get())); + if (data.empty() || !s_game_settings_db.Load(data)) + { + Log_ErrorPrintf("Failed to load game settings database from '%s'. This could cause compatibility issues.", path); + return; + } +} + +void RegTestHostInterface::InitializeSettings() +{ + SettingsInterface& si = m_settings_interface; + HostInterface::SetDefaultSettings(si); + + // Set the settings we need for testing. + si.SetStringValue("GPU", "Renderer", Settings::GetRendererName(s_renderer_to_use)); + si.SetStringValue("Controller1", "Type", Settings::GetControllerTypeName(ControllerType::DigitalController)); + si.SetStringValue("Controller2", "Type", Settings::GetControllerTypeName(ControllerType::None)); + si.SetStringValue("MemoryCards", "Card1Type", Settings::GetMemoryCardTypeName(MemoryCardType::NonPersistent)); + si.SetStringValue("MemoryCards", "Card2Type", Settings::GetMemoryCardTypeName(MemoryCardType::None)); + si.SetStringValue("ControllerPorts", "MultitapMode", Settings::GetMultitapModeName(MultitapMode::Disabled)); + si.SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(LOGLEVEL_DEV)); + si.SetBoolValue("Logging", "LogToConsole", true); + + HostInterface::LoadSettings(si); +} + +std::string RegTestHostInterface::GetBIOSDirectory() +{ + return GetUserDirectoryRelativePath("bios"); +} + +std::unique_ptr RegTestHostInterface::OpenPackageFile(const char* path, u32 flags) +{ + std::string full_path(GetProgramDirectoryRelativePath("%s", path)); + return ByteStream_OpenFileStream(full_path.c_str(), flags); +} + +bool RegTestHostInterface::AcquireHostDisplay() +{ + switch (g_settings.gpu_renderer) + { +#ifdef _WIN32 + case GPURenderer::HardwareD3D11: + m_display = std::make_unique(); + break; + + case GPURenderer::HardwareD3D12: + m_display = std::make_unique(); + break; +#endif + + case GPURenderer::HardwareOpenGL: + m_display = std::make_unique(); + break; + + case GPURenderer::HardwareVulkan: + m_display = std::make_unique(); + break; + + case GPURenderer::Software: + default: + m_display = std::make_unique(); + break; + } + + WindowInfo wi; + wi.type = WindowInfo::Type::Surfaceless; + wi.surface_width = 640; + wi.surface_height = 480; + if (!m_display->CreateRenderDevice(wi, std::string_view(), false, false)) + { + Log_ErrorPrintf("Failed to create render device"); + m_display.reset(); + return false; + } + + if (!m_display->InitializeRenderDevice(std::string_view(), false, false)) + { + Log_ErrorPrintf("Failed to initialize render device"); + m_display->DestroyRenderDevice(); + m_display.reset(); + return false; + } + + return true; +} + +void RegTestHostInterface::ReleaseHostDisplay() +{ + if (!m_display) + return; + + m_display->DestroyRenderDevice(); + m_display.reset(); +} + +std::unique_ptr RegTestHostInterface::CreateAudioStream(AudioBackend backend) +{ + return AudioStream::CreateNullAudioStream(); +} + +static void PrintCommandLineVersion() +{ + const bool was_console_enabled = Log::IsConsoleOutputEnabled(); + if (!was_console_enabled) + Log::SetConsoleOutputParams(true); + + std::fprintf(stderr, "DuckStation Regression Test Runner Version %s (%s)\n", g_scm_tag_str, g_scm_branch_str); + std::fprintf(stderr, "https://github.com/stenzek/duckstation\n"); + std::fprintf(stderr, "\n"); + + if (!was_console_enabled) + Log::SetConsoleOutputParams(false); +} + +static void PrintCommandLineHelp(const char* progname) +{ + const bool was_console_enabled = Log::IsConsoleOutputEnabled(); + if (!was_console_enabled) + Log::SetConsoleOutputParams(true); + + PrintCommandLineVersion(); + std::fprintf(stderr, "Usage: %s [parameters] [--] [boot filename]\n", progname); + std::fprintf(stderr, "\n"); + std::fprintf(stderr, " -help: Displays this information and exits.\n"); + std::fprintf(stderr, " -version: Displays version information and exits.\n"); + std::fprintf(stderr, " -dumpdir: Set frame dump base directory (will be dumped to basedir/gametitle).\n"); + std::fprintf(stderr, " -dumpinterval: Dumps every N frames.\n"); + std::fprintf(stderr, " -frames: Sets the number of frames to execute.\n"); + std::fprintf(stderr, " -log : Sets the log level. Defaults to verbose.\n"); + std::fprintf(stderr, " -renderer : Sets the graphics renderer. Default to software.\n"); + std::fprintf(stderr, " --: Signals that no more arguments will follow and the remaining\n" + " parameters make up the filename. Use when the filename contains\n" + " spaces or starts with a dash.\n"); + std::fprintf(stderr, "\n"); + + if (!was_console_enabled) + Log::SetConsoleOutputParams(false); +} + +static bool ParseCommandLineArgs(int argc, char* argv[]) +{ + s_boot_parameters = std::make_shared(); + + bool no_more_args = false; + for (int i = 1; i < argc; i++) + { + if (!no_more_args) + { +#define CHECK_ARG(str) !std::strcmp(argv[i], str) +#define CHECK_ARG_PARAM(str) (!std::strcmp(argv[i], str) && ((i + 1) < argc)) + + if (CHECK_ARG("-help")) + { + PrintCommandLineHelp(argv[0]); + return false; + } + else if (CHECK_ARG("-version")) + { + PrintCommandLineVersion(); + return false; + } + else if (CHECK_ARG_PARAM("-dumpdir")) + { + s_dump_base_directory = argv[++i]; + if (s_dump_base_directory.empty()) + { + Log_ErrorPrintf("Invalid dump directory specified."); + return false; + } + + continue; + } + else if (CHECK_ARG_PARAM("-dumpinterval")) + { + s_frame_dump_interval = StringUtil::FromChars(argv[++i]).value_or(0); + if (s_frames_to_run <= 0) + { + Log_ErrorPrintf("Invalid dump interval specified: -1", s_frame_dump_interval); + return false; + } + + continue; + } + else if (CHECK_ARG_PARAM("-frames")) + { + s_frames_to_run = StringUtil::FromChars(argv[++i]).value_or(-1); + if (s_frames_to_run <= 0) + { + Log_ErrorPrintf("Invalid frame count specified: %d", s_frames_to_run); + return false; + } + + continue; + } + else if (CHECK_ARG_PARAM("-log")) + { + std::optional level = Settings::ParseLogLevelName(argv[++i]); + if (!level.has_value()) + { + Log_ErrorPrintf("Invalid log level specified."); + return false; + } + + Log::SetConsoleOutputParams(true, nullptr, level.value()); + continue; + } + else if (CHECK_ARG_PARAM("-renderer")) + { + std::optional renderer = Settings::ParseRendererName(argv[++i]); + if (!renderer.has_value()) + { + Log_ErrorPrintf("Invalid renderer specified."); + return false; + } + + s_renderer_to_use = renderer.value(); + continue; + } + else if (CHECK_ARG("--")) + { + no_more_args = true; + continue; + } + else if (argv[i][0] == '-') + { + Log_ErrorPrintf("Unknown parameter: '%s'", argv[i]); + return false; + } + +#undef CHECK_ARG +#undef CHECK_ARG_PARAM + } + + if (!s_boot_parameters->filename.empty()) + s_boot_parameters->filename += ' '; + s_boot_parameters->filename += argv[i]; + } + + return true; +} + +static std::string GetFrameDumpFilename(int frame) +{ + return StringUtil::StdStringFromFormat("%s" FS_OSPATH_SEPARATOR_STR "frame_%05d.png", s_dump_game_directory.c_str(), + frame); +} + +int main(int argc, char* argv[]) +{ + Log::SetConsoleOutputParams(true, nullptr, LOGLEVEL_VERBOSE); + + if (!ParseCommandLineArgs(argc, argv)) + return -1; + + int result = -1; + + Log_InfoPrintf("Initializing..."); + g_host_interface = new RegTestHostInterface(); + if (!g_host_interface->Initialize()) + goto cleanup; + + if (s_boot_parameters->filename.empty()) + { + Log_ErrorPrintf("No boot path specified."); + goto cleanup; + } + + Log_InfoPrintf("Trying to boot '%s'...", s_boot_parameters->filename.c_str()); + if (!g_host_interface->BootSystem(std::move(s_boot_parameters))) + { + Log_ErrorPrintf("Failed to boot system."); + goto cleanup; + } + + if (s_frame_dump_interval > 0) + { + if (s_dump_base_directory.empty()) + { + Log_ErrorPrint("Dump directory not specified."); + goto cleanup; + } + + Log_InfoPrintf("Dumping every %dth frame to '%s'.", s_frame_dump_interval, s_dump_base_directory.c_str()); + } + + Log_InfoPrintf("Running for %d frames...", s_frames_to_run); + + for (int frame = 1; frame <= s_frames_to_run; frame++) + { + System::RunFrame(); + + if (s_frame_dump_interval > 0 && (s_frame_dump_interval == 1 || (frame % s_frame_dump_interval) == 0)) + { + std::string dump_filename(GetFrameDumpFilename(frame)); + g_host_interface->GetDisplay()->WriteDisplayTextureToFile(std::move(dump_filename)); + } + + g_host_interface->GetDisplay()->Render(); + + System::UpdatePerformanceCounters(); + } + + Log_InfoPrintf("All done, shutting down system."); + g_host_interface->DestroySystem(); + + Log_InfoPrintf("Exiting with success."); + result = 0; + +cleanup: + delete g_host_interface; + return result; +} diff --git a/src/duckstation-regtest/regtest_host_interface.h b/src/duckstation-regtest/regtest_host_interface.h new file mode 100644 index 000000000..b2e98c6c8 --- /dev/null +++ b/src/duckstation-regtest/regtest_host_interface.h @@ -0,0 +1,49 @@ +#pragma once +#include "core/host_interface.h" +#include "regtest_settings_interface.h" + +class RegTestHostInterface : public HostInterface +{ +public: + RegTestHostInterface(); + ~RegTestHostInterface(); + + bool Initialize() override; + void Shutdown() override; + + void ReportError(const char* message) override; + void ReportMessage(const char* message) override; + void ReportDebuggerMessage(const char* message) override; + bool ConfirmMessage(const char* message) override; + + void AddOSDMessage(std::string message, float duration = 2.0f) override; + void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1, + int progress_value = -1) override; + void GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title) override; + + void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code, + const std::string& game_title); + + std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "") override; + bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false) override; + int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override; + float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f) override; + std::vector GetSettingStringList(const char* section, const char* key) override; + + std::string GetBIOSDirectory() override; + + std::unique_ptr OpenPackageFile(const char* path, u32 flags) override; + +protected: + bool AcquireHostDisplay() override; + void ReleaseHostDisplay() override; + + std::unique_ptr CreateAudioStream(AudioBackend backend) override; + +private: + void LoadGameSettingsDatabase(); + void InitializeSettings(); + void UpdateSettings(); + + RegTestSettingsInterface m_settings_interface; +}; diff --git a/src/duckstation-regtest/regtest_settings_interface.cpp b/src/duckstation-regtest/regtest_settings_interface.cpp new file mode 100644 index 000000000..e41fa45dd --- /dev/null +++ b/src/duckstation-regtest/regtest_settings_interface.cpp @@ -0,0 +1,156 @@ +#include "regtest_settings_interface.h" +#include "common/assert.h" +#include "common/log.h" +#include "common/string_util.h" +Log_SetChannel(RegTestSettingsInterface); + +RegTestSettingsInterface::RegTestSettingsInterface() = default; + +RegTestSettingsInterface::~RegTestSettingsInterface() = default; + +bool RegTestSettingsInterface::Save() +{ + return false; +} + +void RegTestSettingsInterface::Clear() +{ + m_keys.clear(); +} + +static std::string GetFullKey(const char* section, const char* key) +{ + return StringUtil::StdStringFromFormat("%s/%s", section, key); +} + +int RegTestSettingsInterface::GetIntValue(const char* section, const char* key, int default_value /*= 0*/) +{ + int retval = default_value; + + const std::string fullkey(GetFullKey(section, key)); + auto iter = m_keys.find(fullkey); + if (iter != m_keys.end()) + retval = StringUtil::FromChars(iter->second, 10).value_or(default_value); + + Log_DevPrintf("GetIntValue(%s) -> %d", fullkey.c_str(), retval); + return retval; +} + +float RegTestSettingsInterface::GetFloatValue(const char* section, const char* key, float default_value /*= 0.0f*/) +{ + float retval = default_value; + + const std::string fullkey(GetFullKey(section, key)); + auto iter = m_keys.find(fullkey); + if (iter != m_keys.end()) + retval = StringUtil::FromChars(iter->second).value_or(default_value); + + Log_DevPrintf("GetFloatValue(%s) -> %f", fullkey.c_str(), retval); + return retval; +} + +bool RegTestSettingsInterface::GetBoolValue(const char* section, const char* key, bool default_value /*= false*/) +{ + bool retval = default_value; + + const std::string fullkey(GetFullKey(section, key)); + auto iter = m_keys.find(fullkey); + if (iter != m_keys.end()) + retval = StringUtil::FromChars(iter->second).value_or(default_value); + + Log_DevPrintf("GetBoolValue(%s) -> %s", fullkey.c_str(), retval ? "true" : "false"); + return retval; +} + +std::string RegTestSettingsInterface::GetStringValue(const char* section, const char* key, + const char* default_value /*= ""*/) +{ + std::string retval; + + const std::string fullkey(GetFullKey(section, key)); + auto iter = m_keys.find(fullkey); + if (iter != m_keys.end()) + retval = iter->second; + else + retval = default_value; + + Log_DevPrintf("GetStringValue(%s) -> %s", fullkey.c_str(), retval.c_str()); + return retval; +} + +void RegTestSettingsInterface::SetIntValue(const char* section, const char* key, int value) +{ + const std::string fullkey(GetFullKey(section, key)); + Log_DevPrintf("SetIntValue(%s, %d)", fullkey.c_str(), value); + m_keys[std::move(fullkey)] = std::to_string(value); +} + +void RegTestSettingsInterface::SetFloatValue(const char* section, const char* key, float value) +{ + const std::string fullkey(GetFullKey(section, key)); + Log_DevPrintf("SetFloatValue(%s, %f)", fullkey.c_str(), value); + m_keys[std::move(fullkey)] = std::to_string(value); +} + +void RegTestSettingsInterface::SetBoolValue(const char* section, const char* key, bool value) +{ + const std::string fullkey(GetFullKey(section, key)); + Log_DevPrintf("SetBoolValue(%s, %s)", fullkey.c_str(), value ? "true" : "false"); + m_keys[std::move(fullkey)] = std::string(value ? "true" : "false"); +} + +void RegTestSettingsInterface::SetStringValue(const char* section, const char* key, const char* value) +{ + const std::string fullkey(GetFullKey(section, key)); + Log_DevPrintf("SetStringValue(%s, %s)", fullkey.c_str(), value); + m_keys[std::move(fullkey)] = value; +} + +std::vector RegTestSettingsInterface::GetStringList(const char* section, const char* key) +{ + std::vector ret; + Panic("Not implemented"); + return ret; +} + +void RegTestSettingsInterface::SetStringList(const char* section, const char* key, + const std::vector& items) +{ + Panic("Not implemented"); +} + +bool RegTestSettingsInterface::RemoveFromStringList(const char* section, const char* key, const char* item) +{ + Panic("Not implemented"); + return false; +} + +bool RegTestSettingsInterface::AddToStringList(const char* section, const char* key, const char* item) +{ + Panic("Not implemented"); + return false; +} + +void RegTestSettingsInterface::DeleteValue(const char* section, const char* key) +{ + const std::string fullkey(GetFullKey(section, key)); + Log_DevPrintf("DeleteValue(%s)", fullkey.c_str()); + + auto iter = m_keys.find(fullkey); + if (iter != m_keys.end()) + m_keys.erase(iter); +} + +void RegTestSettingsInterface::ClearSection(const char* section) +{ + Log_DevPrintf("ClearSection(%s)", section); + + const std::string start(StringUtil::StdStringFromFormat("%s/", section)); + for (auto iter = m_keys.begin(); iter != m_keys.end();) + { + if (StringUtil::StartsWith(iter->first, start.c_str())) + iter = m_keys.erase(iter); + else + ++iter; + } +} diff --git a/src/duckstation-regtest/regtest_settings_interface.h b/src/duckstation-regtest/regtest_settings_interface.h new file mode 100644 index 000000000..7f5d312f0 --- /dev/null +++ b/src/duckstation-regtest/regtest_settings_interface.h @@ -0,0 +1,36 @@ +#pragma once +#include "core/settings.h" +#include +#include + +class RegTestSettingsInterface final : public SettingsInterface +{ +public: + RegTestSettingsInterface(); + ~RegTestSettingsInterface(); + + bool Save() override; + void Clear() override; + + int GetIntValue(const char* section, const char* key, int default_value = 0) override; + float GetFloatValue(const char* section, const char* key, float default_value = 0.0f) override; + bool GetBoolValue(const char* section, const char* key, bool default_value = false) override; + + std::string GetStringValue(const char* section, const char* key, const char* default_value = "") override; + void SetIntValue(const char* section, const char* key, int value) override; + void SetFloatValue(const char* section, const char* key, float value) override; + void SetBoolValue(const char* section, const char* key, bool value) override; + void SetStringValue(const char* section, const char* key, const char* value) override; + + std::vector GetStringList(const char* section, const char* key) override; + void SetStringList(const char* section, const char* key, const std::vector& items) override; + bool RemoveFromStringList(const char* section, const char* key, const char* item) override; + bool AddToStringList(const char* section, const char* key, const char* item) override; + + void DeleteValue(const char* section, const char* key) override; + void ClearSection(const char* section) override; + +private: + using KeyMap = std::unordered_map; + KeyMap m_keys; +}; \ No newline at end of file