mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 06:53:43 +00:00
Improve PICT compatibility, add batch mode to gpr2gpa
This commit is contained in:
98
Aerofoil.sln
98
Aerofoil.sln
@@ -47,98 +47,196 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unpacktool", "unpacktool\un
|
||||
EndProject
|
||||
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "ReleasePackageInstaller", "ReleasePackageInstaller\ReleasePackageInstaller.wixproj", "{D26BD501-28A7-4849-8130-FB5EA0A2B82F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsUnicodeToolShim", "WindowsUnicodeToolShim\WindowsUnicodeToolShim.vcxproj", "{15009625-1120-405E-8BBA-69A16CD6713D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x64.Build.0 = Debug|x64
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x86.Build.0 = Debug|Win32
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x64.ActiveCfg = Release|x64
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x64.Build.0 = Release|x64
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x86.ActiveCfg = Release|Win32
|
||||
{45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x86.Build.0 = Release|Win32
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x64.Build.0 = Debug|x64
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x64.ActiveCfg = Release|x64
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x64.Build.0 = Release|x64
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x86.Build.0 = Release|Win32
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x64.Build.0 = Debug|x64
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x64.ActiveCfg = Release|x64
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x64.Build.0 = Release|x64
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x86.Build.0 = Release|Win32
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x64.Build.0 = Debug|x64
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x64.ActiveCfg = Release|x64
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x64.Build.0 = Release|x64
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x86.Build.0 = Release|Win32
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x64.Build.0 = Debug|x64
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x86.Build.0 = Debug|Win32
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x64.ActiveCfg = Release|x64
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x64.Build.0 = Release|x64
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x86.Build.0 = Release|Win32
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Debug|x64.Build.0 = Debug|x64
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Release|x64.ActiveCfg = Release|x64
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Release|x64.Build.0 = Release|x64
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{99549E56-2B3A-4B0C-9A1F-FBA6395BC96C}.Release|x86.Build.0 = Release|Win32
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Debug|x64.Build.0 = Debug|x64
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Release|x64.ActiveCfg = Release|x64
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Release|x64.Build.0 = Release|x64
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E3BDC783-8646-433E-ADF0-8B6390D36669}.Release|x86.Build.0 = Release|Win32
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Debug|x64.Build.0 = Debug|x64
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Release|x64.ActiveCfg = Release|x64
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Release|x64.Build.0 = Release|x64
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A8FCDC5E-729C-4A80-BF9F-B669C52B2AE3}.Release|x86.Build.0 = Release|Win32
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Debug|x64.Build.0 = Debug|x64
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Release|x64.ActiveCfg = Release|x64
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Release|x64.Build.0 = Release|x64
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{487216D8-16BA-4B4C-B5BF-43FEEDFEE03A}.Release|x86.Build.0 = Release|Win32
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Debug|x64.Build.0 = Debug|x64
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Debug|x86.Build.0 = Debug|Win32
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x64.ActiveCfg = Release|x64
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x64.Build.0 = Release|x64
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x86.ActiveCfg = Release|Win32
|
||||
{ED2F91E1-673A-4590-82B2-EB157927D3E3}.Release|x86.Build.0 = Release|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x64.Build.0 = Debug|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x64.ActiveCfg = Release|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x64.Build.0 = Release|x64
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B852D549-4020-4477-8BFB-E199FF78B047}.Release|x86.Build.0 = Release|Win32
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x64.Build.0 = Debug|x64
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Debug|x86.Build.0 = Debug|Win32
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x64.ActiveCfg = Release|x64
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x64.Build.0 = Release|x64
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x86.ActiveCfg = Release|Win32
|
||||
{FFC961AC-55B4-4A38-A83E-06AE98F59ACC}.Release|x86.Build.0 = Release|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x64.Build.0 = Debug|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Debug|x86.Build.0 = Debug|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x64.ActiveCfg = Release|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x64.Build.0 = Release|x64
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x86.ActiveCfg = Release|Win32
|
||||
{17B96F07-EF92-47CD-95A5-8E6EE38AB564}.Release|x86.Build.0 = Release|Win32
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x64.Build.0 = Debug|x64
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x86.Build.0 = Debug|Win32
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x64.ActiveCfg = Release|x64
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x64.Build.0 = Release|x64
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x86.Build.0 = Release|Win32
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Debug|x64.Build.0 = Debug|x64
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Debug|x86.Build.0 = Debug|Win32
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Release|x64.ActiveCfg = Release|x64
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Release|x64.Build.0 = Release|x64
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Release|x86.ActiveCfg = Release|Win32
|
||||
{07351A8E-1F79-42C9-BBAB-31F071EAA99E}.Release|x86.Build.0 = Release|Win32
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Debug|x64.Build.0 = Debug|x64
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Debug|x86.Build.0 = Debug|Win32
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Release|x64.ActiveCfg = Release|x64
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Release|x64.Build.0 = Release|x64
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{27B7CA46-ED23-45C2-BF5F-0C126D81AEBF}.Release|x86.Build.0 = Release|Win32
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Debug|x64.Build.0 = Debug|x64
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Release|x64.ActiveCfg = Release|x64
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Release|x64.Build.0 = Release|x64
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6AE5C85E-6631-4A12-97A0-A05F812FE9CA}.Release|x86.Build.0 = Release|Win32
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Debug|x64.Build.0 = Debug|x64
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x64.ActiveCfg = Release|x64
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x64.Build.0 = Release|x64
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x86.Build.0 = Release|Win32
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x64.Build.0 = Debug|x64
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x64.ActiveCfg = Release|x64
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x64.Build.0 = Release|x64
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x86.Build.0 = Release|Win32
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Debug|x64.Build.0 = Debug|x64
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Debug|x86.Build.0 = Debug|Win32
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Release|x64.ActiveCfg = Release|x64
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Release|x64.Build.0 = Release|x64
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Release|x86.ActiveCfg = Release|Win32
|
||||
{89F8D13E-F216-4B67-8DE9-7F842D349E94}.Release|x86.Build.0 = Release|Win32
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Debug|x64.Build.0 = Debug|x64
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Release|x64.ActiveCfg = Release|x64
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Release|x64.Build.0 = Release|x64
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A778D062-DE76-49F6-8D05-EB26852DD605}.Release|x86.Build.0 = Release|Win32
|
||||
{D26BD501-28A7-4849-8130-FB5EA0A2B82F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D26BD501-28A7-4849-8130-FB5EA0A2B82F}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{D26BD501-28A7-4849-8130-FB5EA0A2B82F}.Release|x64.ActiveCfg = Release|x64
|
||||
{D26BD501-28A7-4849-8130-FB5EA0A2B82F}.Release|x86.ActiveCfg = Release|x64
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Debug|x64.Build.0 = Debug|x64
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Debug|x86.Build.0 = Debug|Win32
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Release|x64.ActiveCfg = Release|x64
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Release|x64.Build.0 = Release|x64
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{15009625-1120-405E-8BBA-69A16CD6713D}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
27
Documentation/picterrors.txt
Normal file
27
Documentation/picterrors.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Many Glider PRO houses, including the bundled ones, contain images in QuickDraw
|
||||
PICT format in the game resource data.
|
||||
|
||||
Additionally, some PICT features are impossible to support because they
|
||||
require copyrighted pattern sets and fonts that are bundled with the
|
||||
operating system.
|
||||
|
||||
My goal is to support as many community houses as possible, but there is a
|
||||
point where supporting the format is more work than just manually converting
|
||||
the resources on a Macintosh machine or emulator.
|
||||
|
||||
All of the remaining known unsupported features necessary to decode the
|
||||
remaining cases are only used by one house that I'm aware of each.
|
||||
|
||||
Known error codes:
|
||||
|
||||
Code 5 subcode 25: Strange image channel layout
|
||||
Code 8 subcode 145: Unsupported BitsRgn opcode.
|
||||
Code 8 subcode 40960: Undocumented opcode, possibly a format parsing error.
|
||||
|
||||
Code 8 subcode 34: Unsupported ShortLine opcode. (PICT contains vector graphics.)
|
||||
Code 8 subcode 35: Unsupported ShortLineFrom opcode. (PICT contains vector graphics.)
|
||||
Code 8 subcode 49: Unsupported PaintRect opcode. (PICT contains vector graphics.)
|
||||
Code 8 subcode 51: Unsupported PaintOval opcode. (PICT contains vector graphics.)
|
||||
Code 8 subcode 129: paintRgn opcode. (PICT contains vector graphics.)
|
||||
Code 8 subcode 33280: Unsupported CompressedQuickTime opcode. (PICT contains a QuickTime frame.)
|
||||
Code 8 subcode 33281: Unsupported UncompressedQuickTime opcode. (PICT contains a QuickTime frame.)
|
@@ -55,4 +55,30 @@ Some old QuickTime movies contain movie tracking information in the movie
|
||||
resource fork, in which case you need to merge them into the data for modern
|
||||
utilities to read them. You can use the "flattenmov" tool to do this: Pass
|
||||
it the data (.gpd) and resource (.gpr) data files for a movie, and it will
|
||||
merge them into a single .mov file.
|
||||
merge them into a single .mov file.
|
||||
|
||||
|
||||
BATCH CONVERSION
|
||||
------------------------------------------------------------------------------
|
||||
To batch-convert house resource files, use gpr2gpa with a path that ends
|
||||
with an asterisk (*) and omit the output filename.
|
||||
|
||||
|
||||
SECURITY CONSIDERATIONS
|
||||
------------------------------------------------------------------------------
|
||||
Glider PRO didn't really do any validation of houses. Currently, Aerofoil
|
||||
doesn't do any additional validation either, and it's possible that invalid
|
||||
house data may lead to crashes or even remote code execution.
|
||||
|
||||
I will be doing a hardening pass on the loader for the 1.1 release. Until
|
||||
then, please only load houses from trusted sources.
|
||||
|
||||
Also, Glider PRO houses were able to take advantage of a resource overlaying
|
||||
feature of the Macintosh operating system, where a resource being present in
|
||||
the house file with the same ID as an application resource would cause the
|
||||
resource to override the application resource.
|
||||
|
||||
Aerofoil's resource loader is much more restrictive: Currently, only
|
||||
backgrounds, audio triggers, and icons may load from the house data. This
|
||||
restriction will be loosened in the 1.1 release to allow resources to be
|
||||
overrided if I can confirm that it's safe to override them.
|
@@ -1017,6 +1017,11 @@ public:
|
||||
|
||||
m_outputIndexStart = firstRow * m_width + firstCol;
|
||||
}
|
||||
|
||||
bool EmitQTContent(IOStream *stream, uint32_t dataSize, bool isCompressed) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void BlitScanlineAndAdvance(const void *data) override
|
||||
{
|
||||
|
@@ -87,6 +87,15 @@ Rect BERect::ToRect() const
|
||||
return rect;
|
||||
}
|
||||
|
||||
Point BEPoint::ToPoint() const
|
||||
{
|
||||
Point point;
|
||||
point.h = this->h;
|
||||
point.v = this->v;
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
void HideCursor()
|
||||
{
|
||||
PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kHidden);
|
||||
|
@@ -12,6 +12,28 @@
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
|
||||
struct QDPictDecodeState
|
||||
{
|
||||
PortabilityLayer::RGBAColor m_foreColor;
|
||||
PortabilityLayer::RGBAColor m_backColor;
|
||||
Point m_penPos;
|
||||
Point m_penSize;
|
||||
Point m_origin;
|
||||
uint16_t m_penMode;
|
||||
uint8_t m_penPattern[8];
|
||||
|
||||
QDPictDecodeState()
|
||||
{
|
||||
m_foreColor = PortabilityLayer::RGBAColor::Create(0, 0, 0, 255);
|
||||
m_backColor = PortabilityLayer::RGBAColor::Create(255, 255, 255, 255);
|
||||
m_penPos = Point::Create(0, 0);
|
||||
m_origin = Point::Create(0, 0);
|
||||
m_penSize = Point::Create(1, 1);
|
||||
for (int i = 0; i < 8; i++)
|
||||
m_penPattern[i] = 0xff;
|
||||
m_penMode = 0;
|
||||
}
|
||||
};
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
@@ -23,9 +45,13 @@ namespace PortabilityLayer
|
||||
bool QDPictDecoder::DecodePict(IOStream *stream, QDPictEmitContext *emitContext)
|
||||
{
|
||||
QDPictHeader header;
|
||||
QDPictDecodeState decodeState;
|
||||
|
||||
if (!header.Load(stream))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMissingHeader, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
emitContext->SpecifyFrame(header.GetFrame());
|
||||
|
||||
@@ -64,7 +90,10 @@ namespace PortabilityLayer
|
||||
break;
|
||||
case QDOpcodes::kClipRegion:
|
||||
if (stream->Read(scratchBytes, 10) != 10 || scratchBytes[0] != 0 || scratchBytes[1] != 10)
|
||||
return false; // Unknown format region
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kUnsupportedClipRegionFormat, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
GP_STATIC_ASSERT(sizeof(scratchBERect) == 8);
|
||||
|
||||
@@ -72,17 +101,26 @@ namespace PortabilityLayer
|
||||
scratchRect = scratchBERect.ToRect();
|
||||
|
||||
if (!scratchRect.IsValid())
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kInvalidRegionRect, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case QDOpcodes::kShortComment:
|
||||
if (!stream->SeekCurrent(2))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kLongComment:
|
||||
{
|
||||
if (stream->Read(scratchBytes, 4) != 4)
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint16_t commentKind = (scratchBytes[0] << 8) | scratchBytes[1];
|
||||
const uint16_t commentSize = (scratchBytes[2] << 8) | scratchBytes[3];
|
||||
@@ -92,41 +130,156 @@ namespace PortabilityLayer
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kBitsRect:
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), false, false, false, activeFrame, emitContext);
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), false, false, false, activeFrame, decodeState.m_origin, emitContext);
|
||||
if (rasterOpErrorCode)
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kRasterOpFailure, rasterOpErrorCode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kPackBitsRect:
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, false, false, activeFrame, emitContext);
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, false, false, activeFrame, decodeState.m_origin, emitContext);
|
||||
if (rasterOpErrorCode)
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kRasterOpFailure, rasterOpErrorCode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kPackBitsRgn:
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, true, false, activeFrame, emitContext);
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, true, false, activeFrame, decodeState.m_origin, emitContext);
|
||||
if (rasterOpErrorCode)
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kRasterOpFailure, rasterOpErrorCode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kDirectBitsRect:
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, false, true, activeFrame, emitContext);
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, false, true, activeFrame, decodeState.m_origin, emitContext);
|
||||
if (rasterOpErrorCode)
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kRasterOpFailure, rasterOpErrorCode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kDirectBitsRgn:
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, true, true, activeFrame, emitContext);
|
||||
rasterOpErrorCode = ProcessRasterOp(stream, header.GetVersion(), true, true, true, activeFrame, decodeState.m_origin, emitContext);
|
||||
if (rasterOpErrorCode)
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kRasterOpFailure, rasterOpErrorCode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kDefaultHilite:
|
||||
break;
|
||||
case QDOpcodes::kOpColor:
|
||||
if (!stream->SeekCurrent(6))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kEndOfPicture:
|
||||
finished = true;
|
||||
break;
|
||||
case QDOpcodes::kPenSize:
|
||||
{
|
||||
BEPoint point;
|
||||
|
||||
if (!stream->Read(&point, 4))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
decodeState.m_penSize = point.ToPoint();
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kPenPattern:
|
||||
{
|
||||
if (!stream->Read(decodeState.m_penPattern, 8))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kPenMode:
|
||||
{
|
||||
BEUInt16_t penMode;
|
||||
|
||||
if (!stream->Read(&penMode, 2))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
decodeState.m_penMode = penMode;
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kOrigin:
|
||||
{
|
||||
// NOTE: This is intentionally not the same order as Point
|
||||
BEInt16_t dxdy[2];
|
||||
|
||||
if (!stream->Read(&dxdy, 4))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
decodeState.m_origin.h += dxdy[0];
|
||||
decodeState.m_origin.v += dxdy[1];
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kOpColor: // ??? Not sure what the difference between these two is
|
||||
case QDOpcodes::kRGBForeColor:
|
||||
{
|
||||
uint8_t rgbBytes[6];
|
||||
|
||||
if (!stream->Read(rgbBytes, 6))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
decodeState.m_foreColor = RGBAColor::Create(rgbBytes[0], rgbBytes[2], rgbBytes[4], 255);
|
||||
}
|
||||
break;
|
||||
case QDOpcodes::kRGBBackColor:
|
||||
{
|
||||
uint8_t rgbBytes[6];
|
||||
|
||||
if (!stream->Read(rgbBytes, 6))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
decodeState.m_backColor = RGBAColor::Create(rgbBytes[0], rgbBytes[2], rgbBytes[4], 255);
|
||||
}
|
||||
break;
|
||||
|
||||
case QDOpcodes::kCompressedQT:
|
||||
case QDOpcodes::kUncompressedQT:
|
||||
{
|
||||
BEUInt32_t dataSize;
|
||||
|
||||
if (!stream->Read(&dataSize, 4))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emitContext->EmitQTContent(stream, dataSize, opcode == QDOpcodes::kCompressedQT))
|
||||
{
|
||||
emitContext->ReportError(QDPictEmitContext::kMalformedArguments, opcode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown opcode
|
||||
emitContext->ReportError(QDPictEmitContext::kUnsupportedOpcode, opcode);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -135,7 +288,7 @@ namespace PortabilityLayer
|
||||
}
|
||||
}
|
||||
|
||||
int QDPictDecoder::ProcessRasterOp(IOStream *stream, int pictVersion, bool isPackedFlag, bool hasRegion, bool isDirect, const Rect &constraintRect, QDPictEmitContext *context)
|
||||
int QDPictDecoder::ProcessRasterOp(IOStream *stream, int pictVersion, bool isPackedFlag, bool hasRegion, bool isDirect, const Rect &constraintRect, const Point &origin, QDPictEmitContext *context)
|
||||
{
|
||||
uint16_t rowSizeBytes = 0;
|
||||
|
||||
@@ -415,6 +568,12 @@ namespace PortabilityLayer
|
||||
if (srcRect.bottom - srcRect.top != destRect.bottom - destRect.top)
|
||||
return 39;
|
||||
|
||||
// Offset by origin
|
||||
destRect.left -= origin.h;
|
||||
destRect.right -= origin.v;
|
||||
destRect.top -= origin.v;
|
||||
destRect.bottom -= origin.v;
|
||||
|
||||
const Rect pixMapBounds = pixMapBE.m_bounds.ToRect();
|
||||
if (!pixMapBounds.IsValid())
|
||||
return 40;
|
||||
@@ -574,6 +733,13 @@ namespace PortabilityLayer
|
||||
}
|
||||
else if (packType == 1)
|
||||
{
|
||||
if (!isLineValid)
|
||||
{
|
||||
if (!stream->SeekCurrent(rowSizeBytes))
|
||||
return 59;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stream->Read(decompressedScanlineBuffer, rowSizeBytes) != rowSizeBytes)
|
||||
return 51;
|
||||
|
||||
|
@@ -2,7 +2,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct Rect;
|
||||
struct Rect;
|
||||
struct Point;
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
@@ -17,7 +18,7 @@ namespace PortabilityLayer
|
||||
bool DecodePict(IOStream *stream, QDPictEmitContext *emitContext);
|
||||
|
||||
private:
|
||||
int ProcessRasterOp(IOStream *stream, int pictVersion, bool isPackedFlag, bool hasRegion, bool isDirect, const Rect &drawArea, QDPictEmitContext *context);
|
||||
int ProcessRasterOp(IOStream *stream, int pictVersion, bool isPackedFlag, bool hasRegion, bool isDirect, const Rect &drawArea, const Point &origin, QDPictEmitContext *context);
|
||||
static bool UnpackBits8(uint8_t *dest, size_t destSize, const uint8_t *src, size_t srcSize);
|
||||
static bool UnpackBits16(uint8_t *dest, size_t destSize, const uint8_t *src, size_t srcSize);
|
||||
|
||||
|
@@ -7,7 +7,8 @@ struct Rect;
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
struct RGBAColor;
|
||||
struct QDPictEmitScanlineParameters;
|
||||
struct QDPictEmitScanlineParameters;
|
||||
class IOStream;
|
||||
|
||||
enum QDPictBlitSourceType
|
||||
{
|
||||
@@ -25,11 +26,27 @@ namespace PortabilityLayer
|
||||
|
||||
class QDPictEmitContext
|
||||
{
|
||||
public:
|
||||
public:
|
||||
enum ErrorCode
|
||||
{
|
||||
kMissingHeader,
|
||||
kInvalidRegionRect,
|
||||
kMalformedArguments,
|
||||
kUnusedError1,
|
||||
kUnusedError2,
|
||||
kRasterOpFailure,
|
||||
kUnsupportedClipRegionFormat,
|
||||
kMalformedOpcode,
|
||||
kUnsupportedOpcode,
|
||||
};
|
||||
|
||||
virtual bool SpecifyFrame(const Rect &rect) = 0;
|
||||
virtual Rect ConstrainRegion(const Rect &rect) const = 0;
|
||||
virtual void Start(QDPictBlitSourceType sourceType, const QDPictEmitScanlineParameters ¶ms) = 0;
|
||||
virtual void BlitScanlineAndAdvance(const void *) = 0;
|
||||
virtual bool AllocTempBuffers(uint8_t *&buffer1, size_t buffer1Size, uint8_t *&buffer2, size_t buffer2Size) = 0;
|
||||
virtual bool EmitQTContent(IOStream *stream, uint32_t dataSize, bool isCompressed) = 0;
|
||||
virtual bool AllocTempBuffers(uint8_t *&buffer1, size_t buffer1Size, uint8_t *&buffer2, size_t buffer2Size) = 0;
|
||||
|
||||
virtual void ReportError(int errorType, int errorSubtype) { }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,13 @@ PL_PICTOP(0x0001, kClipRegion, Rule_SizeTagged16)
|
||||
PL_PICTOP(0x0002, kBackPattern, 8)
|
||||
PL_PICTOP(0x0003, kTextFont, 2)
|
||||
PL_PICTOP(0x0004, kTextFontStyle, 1)
|
||||
PL_PICTOP(0x0005, kTextSourceMode, 2)
|
||||
PL_PICTOP(0x0005, kTextSourceMode, 2)
|
||||
PL_PICTOP(0x0007, kPenSize, 4)
|
||||
PL_PICTOP(0x0008, kPenMode, 2)
|
||||
PL_PICTOP(0x0009, kPenPattern, 8)
|
||||
PL_PICTOP(0x000c, kOrigin, 4) // Relative
|
||||
PL_PICTOP(0x001a, kRGBForeColor, 6)
|
||||
PL_PICTOP(0x001b, kRGBBackColor, 6)
|
||||
PL_PICTOP(0x001e, kDefaultHilite, 0)
|
||||
PL_PICTOP(0x001f, kOpColor, 6)
|
||||
PL_PICTOP(0x0030, kFrameRect, 8)
|
||||
@@ -15,4 +21,6 @@ PL_PICTOP(0x0098, kPackBitsRect, Rule_PackBitsRect)
|
||||
PL_PICTOP(0x0099, kPackBitsRgn, Rule_PackBitsRgn)
|
||||
PL_PICTOP(0x009a, kDirectBitsRect, Rule_DirectBitsRect)
|
||||
PL_PICTOP(0x009b, kDirectBitsRgn, Rule_DirectBitsRgn)
|
||||
PL_PICTOP(0x8200, kCompressedQT, Rule_SizeTagged32)
|
||||
PL_PICTOP(0x8201, kUncompressedQT, Rule_SizeTagged32)
|
||||
PL_PICTOP(0x00ff, kEndOfPicture, 0)
|
||||
|
@@ -66,6 +66,14 @@ struct BERect
|
||||
Rect ToRect() const;
|
||||
};
|
||||
|
||||
struct BEPoint
|
||||
{
|
||||
BEInt16_t v;
|
||||
BEInt16_t h;
|
||||
|
||||
Point ToPoint() const;
|
||||
};
|
||||
|
||||
struct BERegion
|
||||
{
|
||||
BEUInt16_t recordSize;
|
||||
|
10
WindowsUnicodeToolShim.props
Normal file
10
WindowsUnicodeToolShim.props
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<IncludePath>$(SolutionDir)WindowsUnicodeToolShim;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup />
|
||||
<ItemGroup />
|
||||
</Project>
|
154
WindowsUnicodeToolShim/WindowsUnicodeToolShim.cpp
Normal file
154
WindowsUnicodeToolShim/WindowsUnicodeToolShim.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <string>
|
||||
|
||||
#include "UTF8.h"
|
||||
#include "UTF16.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
|
||||
// This library provides front-ends and shims to make tools a bit more portable by handling all path strings as UTF-8,
|
||||
// and providing a "main" entry point that is also UTF-8.
|
||||
|
||||
static std::string ConvertWStringToUTF8(const wchar_t *str)
|
||||
{
|
||||
size_t strLength = wcslen(str);
|
||||
|
||||
std::string result;
|
||||
|
||||
for (size_t i = 0; i < strLength; )
|
||||
{
|
||||
size_t charsDigested = 0;
|
||||
uint32_t codePoint = 0;
|
||||
uint8_t asUTF8[4];
|
||||
if (!PortabilityLayer::UTF16Processor::DecodeCodePoint(reinterpret_cast<const uint16_t*>(str) + i, strLength - i, charsDigested, codePoint))
|
||||
return "";
|
||||
|
||||
i += charsDigested;
|
||||
|
||||
size_t bytesEmitted = 0;
|
||||
PortabilityLayer::UTF8Processor::EncodeCodePoint(asUTF8, bytesEmitted, codePoint);
|
||||
|
||||
result.append(reinterpret_cast<const char*>(asUTF8), bytesEmitted);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::wstring ConvertUTF8ToWString(const char *str)
|
||||
{
|
||||
size_t strLength = strlen(str);
|
||||
|
||||
std::wstring result;
|
||||
|
||||
for (size_t i = 0; i < strLength; )
|
||||
{
|
||||
size_t charsDigested = 0;
|
||||
uint32_t codePoint = 0;
|
||||
uint16_t asUTF16[4];
|
||||
if (!PortabilityLayer::UTF8Processor::DecodeCodePoint(reinterpret_cast<const uint8_t*>(str) + i, strLength - i, charsDigested, codePoint))
|
||||
return L"";
|
||||
|
||||
i += charsDigested;
|
||||
|
||||
size_t codePointsEmitted = 0;
|
||||
PortabilityLayer::UTF16Processor::EncodeCodePoint(asUTF16, codePointsEmitted, codePoint);
|
||||
|
||||
result.append(reinterpret_cast<const wchar_t*>(asUTF16), codePointsEmitted);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *fopen_utf8(const char *path, const char *options)
|
||||
{
|
||||
std::wstring pathUTF16 = ConvertUTF8ToWString(path);
|
||||
std::wstring optionsUTF16 = ConvertUTF8ToWString(options);
|
||||
|
||||
return _wfopen(pathUTF16.c_str(), optionsUTF16.c_str());
|
||||
}
|
||||
|
||||
int fputs_utf8(const char *str, FILE *f)
|
||||
{
|
||||
return fputs(str, f);
|
||||
}
|
||||
|
||||
|
||||
int mkdir_utf8(const char *path)
|
||||
{
|
||||
std::wstring pathUTF16 = ConvertUTF8ToWString(path);
|
||||
return _wmkdir(pathUTF16.c_str());
|
||||
}
|
||||
|
||||
void TerminateDirectoryPath(std::string &path)
|
||||
{
|
||||
const size_t length = path.length();
|
||||
|
||||
if (length == 0)
|
||||
path.append("\\");
|
||||
else
|
||||
{
|
||||
const char lastChar = path[path.length() - 1];
|
||||
if (lastChar != '\\' && lastChar != '/')
|
||||
path.append("\\");
|
||||
}
|
||||
}
|
||||
|
||||
void ScanDirectoryForExtension(std::vector<std::string> &outPaths, const char *path, const char *ending, bool recursive)
|
||||
{
|
||||
std::wstring dirFilter = std::wstring(L"\\\\?\\") + ConvertUTF8ToWString(path) + L"\\*";
|
||||
size_t endingLen = strlen(ending);
|
||||
|
||||
WIN32_FIND_DATAW findDataW;
|
||||
HANDLE h = FindFirstFileW(dirFilter.c_str(), &findDataW);
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::string utf8Name = ConvertWStringToUTF8(findDataW.cFileName);
|
||||
if (utf8Name != "." && utf8Name != "..")
|
||||
{
|
||||
if (recursive && findDataW.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
ScanDirectoryForExtension(outPaths, (std::string(path) + "\\" + utf8Name).c_str(), ending, true);
|
||||
else if (utf8Name.length() >= endingLen && utf8Name.substr(utf8Name.length() - endingLen) == ending)
|
||||
outPaths.push_back(std::string(path) + "\\" + utf8Name);
|
||||
}
|
||||
|
||||
if (!FindNextFileW(h, &findDataW))
|
||||
break;
|
||||
}
|
||||
|
||||
FindClose(h);
|
||||
}
|
||||
|
||||
|
||||
int toolMain(int argc, const char **argv);
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
LPWSTR *szArglist;
|
||||
int nArgs;
|
||||
|
||||
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
|
||||
|
||||
std::vector<std::string> utf8ArgStrings;
|
||||
std::vector<const char *> utf8Args;
|
||||
|
||||
utf8ArgStrings.resize(nArgs);
|
||||
utf8Args.resize(nArgs);
|
||||
|
||||
for (int i = 0; i < nArgs; i++)
|
||||
{
|
||||
utf8ArgStrings[i] = ConvertWStringToUTF8(szArglist[i]);
|
||||
utf8Args[i] = utf8ArgStrings[i].c_str();
|
||||
}
|
||||
|
||||
const char **args = nullptr;
|
||||
if (nArgs)
|
||||
args = &utf8Args[0];
|
||||
|
||||
return toolMain(nArgs, args);
|
||||
}
|
9
WindowsUnicodeToolShim/WindowsUnicodeToolShim.h
Normal file
9
WindowsUnicodeToolShim/WindowsUnicodeToolShim.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
|
||||
FILE *fopen_utf8(const char *path, const char *options);
|
||||
int fputs_utf8(const char *str, FILE *f);
|
||||
int mkdir_utf8(const char *path);
|
||||
void TerminateDirectoryPath(std::string &path);
|
||||
void ScanDirectoryForExtension(std::vector<std::string>& outPaths, const char *path, const char *ending, bool recursive);
|
135
WindowsUnicodeToolShim/WindowsUnicodeToolShim.vcxproj
Normal file
135
WindowsUnicodeToolShim/WindowsUnicodeToolShim.vcxproj
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{15009625-1120-405E-8BBA-69A16CD6713D}</ProjectGuid>
|
||||
<RootNamespace>WindowsUnicodeToolShim</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="WindowsUnicodeToolShim.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="WindowsUnicodeToolShim.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -20,6 +20,8 @@
|
||||
#include "rapidjson/rapidjson.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
#include "WindowsUnicodeToolShim.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@@ -205,8 +207,8 @@ void ConvertToMSDOSTimestamp(const PortabilityLayer::CombinedTimestamp &ts, uint
|
||||
|
||||
void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries, const PortabilityLayer::CombinedTimestamp &ts)
|
||||
{
|
||||
FILE *outF = nullptr;
|
||||
if (fopen_s(&outF, path, "wb"))
|
||||
FILE *outF = fopen_utf8(path, "wb");
|
||||
if (!outF)
|
||||
{
|
||||
fprintf(stderr, "Error opening output path");
|
||||
return;
|
||||
@@ -322,8 +324,14 @@ public:
|
||||
Rect ConstrainRegion(const Rect &rect) const override;
|
||||
void Start(PortabilityLayer::QDPictBlitSourceType sourceType, const PortabilityLayer::QDPictEmitScanlineParameters ¶ms) override;
|
||||
void BlitScanlineAndAdvance(const void *) override;
|
||||
bool EmitQTContent(PortabilityLayer::IOStream *stream, uint32_t dataSize, bool isCompressed) override;
|
||||
bool AllocTempBuffers(uint8_t *&buffer1, size_t buffer1Size, uint8_t *&buffer2, size_t buffer2Size) override;
|
||||
|
||||
void ReportError(int errorCode, int subCode) override
|
||||
{
|
||||
fprintf(stderr, "PICT import failed, error code %i, subcode %i\n", errorCode, subCode);
|
||||
}
|
||||
|
||||
bool Export(std::vector<uint8_t> &outData) const;
|
||||
|
||||
private:
|
||||
@@ -462,6 +470,17 @@ void BMPDumperContext::BlitScanlineAndAdvance(const void *scanlineData)
|
||||
}
|
||||
}
|
||||
|
||||
bool BMPDumperContext::EmitQTContent(PortabilityLayer::IOStream *stream, uint32_t dataSize, bool isCompressed)
|
||||
{
|
||||
// Only one known house ("Magic" seems to use uncompressed, which is partly documented here:
|
||||
// https://github.com/gco/xee/blob/master/XeePhotoshopPICTLoader.m
|
||||
|
||||
// Known compressed cases and codecs:
|
||||
// "Egypt" res 10011: JPEG
|
||||
// "The Meadows" res 3000: Apple Video (a.k.a. Apple RPZA)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BMPDumperContext::AllocTempBuffers(uint8_t *&buffer1, size_t buffer1Size, uint8_t *&buffer2, size_t buffer2Size)
|
||||
{
|
||||
m_tempBuffers.resize(buffer1Size + buffer2Size);
|
||||
@@ -1078,7 +1097,7 @@ bool ApplyPatch(const std::vector<uint8_t> &patchFileContents, std::vector<Plann
|
||||
entry = &archive.back();
|
||||
}
|
||||
|
||||
FILE *f = fopen(itemValue.GetString(), "rb");
|
||||
FILE *f = fopen_utf8(itemValue.GetString(), "rb");
|
||||
if (!f)
|
||||
{
|
||||
fprintf(stderr, "Could not find source file %s for patch", static_cast<const char*>(itemValue.GetString()));
|
||||
@@ -1125,47 +1144,19 @@ bool ApplyPatch(const std::vector<uint8_t> &patchFileContents, std::vector<Plann
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
int ConvertSingleFile(const char *resPath, const PortabilityLayer::CombinedTimestamp &ts, FILE *patchF, const char *outPath)
|
||||
{
|
||||
if (argc != 4 && argc != 5)
|
||||
{
|
||||
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <input.ts> <output.gpa> [patch.json]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string base = argv[1];
|
||||
|
||||
FILE *inF = nullptr;
|
||||
if (fopen_s(&inF, argv[1], "rb"))
|
||||
FILE *inF = fopen_utf8(resPath, "rb");
|
||||
if (!inF)
|
||||
{
|
||||
fprintf(stderr, "Error opening input file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *timestampF = nullptr;
|
||||
if (fopen_s(×tampF, argv[2], "rb"))
|
||||
{
|
||||
fprintf(stderr, "Error opening metadata file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PortabilityLayer::CombinedTimestamp ts;
|
||||
if (fread(&ts, 1, sizeof(ts), timestampF) != sizeof(ts))
|
||||
{
|
||||
fprintf(stderr, "Error reading timestamp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool havePatchFile = false;
|
||||
std::vector<uint8_t> patchFileContents;
|
||||
|
||||
FILE *patchF = nullptr;
|
||||
if (argc == 5 && fopen_s(&patchF, argv[4], "rb"))
|
||||
{
|
||||
fprintf(stderr, "Error reading patch file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (patchF)
|
||||
{
|
||||
havePatchFile = true;
|
||||
@@ -1226,6 +1217,8 @@ int main(int argc, const char **argv)
|
||||
|
||||
if (ImportPICT(entry.m_contents, resData, resSize))
|
||||
contents.push_back(entry);
|
||||
else
|
||||
fprintf(stderr, "Failed to import PICT res %i\n", static_cast<int>(res.m_resID));
|
||||
}
|
||||
else if (typeList.m_resType == sndTypeID)
|
||||
{
|
||||
@@ -1285,9 +1278,123 @@ int main(int argc, const char **argv)
|
||||
|
||||
std::sort(contents.begin(), contents.end(), EntryAlphaSortPredicate);
|
||||
|
||||
ExportZipFile(argv[3], contents, ts);
|
||||
ExportZipFile(outPath, contents, ts);
|
||||
|
||||
resFile->Destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConvertDirectory(const std::string &basePath, const PortabilityLayer::CombinedTimestamp &ts)
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
ScanDirectoryForExtension(paths, basePath.c_str(), ".gpr", true);
|
||||
|
||||
for (std::vector<std::string>::const_iterator it = paths.begin(), itEnd = paths.end(); it != itEnd; ++it)
|
||||
{
|
||||
const std::string &resPath = *it;
|
||||
std::string housePathBase = resPath.substr(0, resPath.length() - 4);
|
||||
|
||||
std::string metaPath = housePathBase + ".gpf";
|
||||
|
||||
FILE *metaF = fopen_utf8(metaPath.c_str(), "rb");
|
||||
if (!metaF)
|
||||
{
|
||||
fprintf(stderr, "Failed to open metadata file ");
|
||||
fputs_utf8(metaPath.c_str(), stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
PortabilityLayer::MacFilePropertiesSerialized mfps;
|
||||
if (fread(mfps.m_data, 1, PortabilityLayer::MacFilePropertiesSerialized::kSize, metaF) != PortabilityLayer::MacFilePropertiesSerialized::kSize)
|
||||
{
|
||||
fclose(metaF);
|
||||
fprintf(stderr, "Failed to load metadata file ");
|
||||
fputs_utf8(metaPath.c_str(), stderr);
|
||||
fprintf(stderr, "\n");
|
||||
return -1;
|
||||
}
|
||||
fclose(metaF);
|
||||
|
||||
PortabilityLayer::MacFileProperties mfp;
|
||||
mfps.Deserialize(mfp);
|
||||
|
||||
if (mfp.m_fileType[0] == 'g' && mfp.m_fileType[1] == 'l' && mfp.m_fileType[2] == 'i' && mfp.m_fileType[3] == 'H')
|
||||
{
|
||||
std::string houseArchivePath = (housePathBase + ".gpa");
|
||||
fprintf(stdout, "Importing ");
|
||||
fputs_utf8(houseArchivePath.c_str(), stdout);
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
int returnCode = ConvertSingleFile(resPath.c_str(), ts, nullptr, houseArchivePath.c_str());
|
||||
if (returnCode)
|
||||
{
|
||||
fprintf(stderr, "An error occurred while converting\n");
|
||||
fputs_utf8(resPath.c_str(), stderr);
|
||||
fprintf(stderr, "\n");
|
||||
return returnCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PrintUsage()
|
||||
{
|
||||
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <input.ts> <output.gpa> [patch.json]");
|
||||
fprintf(stderr, " gpr2gpa <input dir>\* <input.ts>");
|
||||
fprintf(stderr, " gpr2gpa <input dir>/* <input.ts>");
|
||||
fprintf(stderr, " gpr2gpa * <input.ts>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int toolMain(int argc, const char **argv)
|
||||
{
|
||||
if (argc < 3)
|
||||
return PrintUsage();
|
||||
|
||||
FILE *timestampF = fopen_utf8(argv[2], "rb");
|
||||
if (!timestampF)
|
||||
{
|
||||
fprintf(stderr, "Error opening timestamp file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PortabilityLayer::CombinedTimestamp ts;
|
||||
if (fread(&ts, 1, sizeof(ts), timestampF) != sizeof(ts))
|
||||
{
|
||||
fprintf(stderr, "Error reading timestamp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(timestampF);
|
||||
|
||||
std::string base = argv[1];
|
||||
|
||||
if (base == "*")
|
||||
return ConvertDirectory(".", ts);
|
||||
|
||||
if (base.length() >= 2)
|
||||
{
|
||||
std::string baseEnding = base.substr(base.length() - 2, 2);
|
||||
if (baseEnding == "\\*" || baseEnding == "/*")
|
||||
return ConvertDirectory(base.substr(0, base.length() - 2), ts);
|
||||
}
|
||||
|
||||
if (argc != 4 && argc != 5)
|
||||
return PrintUsage();
|
||||
|
||||
FILE *patchF = nullptr;
|
||||
if (argc == 5)
|
||||
{
|
||||
patchF = fopen_utf8(argv[4], "rb");
|
||||
if (!patchF)
|
||||
{
|
||||
fprintf(stderr, "Error reading patch file");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return ConvertSingleFile(argv[1], ts, patchF, argv[3]);
|
||||
}
|
||||
|
@@ -64,6 +64,7 @@
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\RapidJSON.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
@@ -73,6 +74,7 @@
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\RapidJSON.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
@@ -82,6 +84,7 @@
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\RapidJSON.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
@@ -91,6 +94,7 @@
|
||||
<Import Project="..\GpCommon.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\RapidJSON.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
@@ -142,6 +146,9 @@
|
||||
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
|
||||
<Project>{6ec62b0f-9353-40a4-a510-3788f1368b33}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WindowsUnicodeToolShim\WindowsUnicodeToolShim.vcxproj">
|
||||
<Project>{15009625-1120-405e-8bba-69a16cd6713d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\zlib\zlib.vcxproj">
|
||||
<Project>{6ae5c85e-6631-4a12-97a0-a05f812fe9ca}</Project>
|
||||
</ProjectReference>
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "CompactProLZHRLEDecompressor.h"
|
||||
|
||||
#include "CSInputBuffer.h"
|
||||
#include "WindowsUnicodeToolShim.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -92,84 +93,6 @@ StuffItParser g_stuffItParser;
|
||||
StuffIt5Parser g_stuffIt5Parser;
|
||||
CompactProParser g_compactProParser;
|
||||
|
||||
std::string ConvertWStringToUTF8(const wchar_t *str)
|
||||
{
|
||||
size_t strLength = wcslen(str);
|
||||
|
||||
std::string result;
|
||||
|
||||
for (size_t i = 0; i < strLength; )
|
||||
{
|
||||
size_t charsDigested = 0;
|
||||
uint32_t codePoint = 0;
|
||||
uint8_t asUTF8[4];
|
||||
if (!PortabilityLayer::UTF16Processor::DecodeCodePoint(reinterpret_cast<const uint16_t*>(str) + i, strLength - i, charsDigested, codePoint))
|
||||
return "";
|
||||
|
||||
i += charsDigested;
|
||||
|
||||
size_t bytesEmitted = 0;
|
||||
PortabilityLayer::UTF8Processor::EncodeCodePoint(asUTF8, bytesEmitted, codePoint);
|
||||
|
||||
result.append(reinterpret_cast<const char*>(asUTF8), bytesEmitted);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::wstring ConvertUTF8ToWString(const char *str)
|
||||
{
|
||||
size_t strLength = strlen(str);
|
||||
|
||||
std::wstring result;
|
||||
|
||||
for (size_t i = 0; i < strLength; )
|
||||
{
|
||||
size_t charsDigested = 0;
|
||||
uint32_t codePoint = 0;
|
||||
uint16_t asUTF16[4];
|
||||
if (!PortabilityLayer::UTF8Processor::DecodeCodePoint(reinterpret_cast<const uint8_t*>(str) + i, strLength - i, charsDigested, codePoint))
|
||||
return L"";
|
||||
|
||||
i += charsDigested;
|
||||
|
||||
size_t codePointsEmitted = 0;
|
||||
PortabilityLayer::UTF16Processor::EncodeCodePoint(asUTF16, codePointsEmitted, codePoint);
|
||||
|
||||
result.append(reinterpret_cast<const wchar_t*>(asUTF16), codePointsEmitted);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FILE *fopen_utf8(const char *path, const char *options)
|
||||
{
|
||||
std::wstring pathUTF16 = ConvertUTF8ToWString(path);
|
||||
std::wstring optionsUTF16 = ConvertUTF8ToWString(options);
|
||||
|
||||
return _wfopen(pathUTF16.c_str(), optionsUTF16.c_str());
|
||||
}
|
||||
|
||||
int mkdir_utf8(const char *path)
|
||||
{
|
||||
std::wstring pathUTF16 = ConvertUTF8ToWString(path);
|
||||
return _wmkdir(pathUTF16.c_str());
|
||||
}
|
||||
|
||||
void TerminateDirectoryPath(std::string &path)
|
||||
{
|
||||
const size_t length = path.length();
|
||||
|
||||
if (length == 0)
|
||||
path.append("\\");
|
||||
else
|
||||
{
|
||||
const char lastChar = path[path.length() - 1];
|
||||
if (lastChar != '\\' && lastChar != '/')
|
||||
path.append("\\");
|
||||
}
|
||||
}
|
||||
|
||||
std::string LegalizeWindowsFileName(const std::string &path)
|
||||
{
|
||||
const size_t length = path.length();
|
||||
@@ -441,7 +364,7 @@ int ExtractItem(int depth, const ArchiveItem &item, const std::string &dirPath,
|
||||
for (int i = 0; i < depth; i++)
|
||||
printf(" ");
|
||||
|
||||
fputws(ConvertUTF8ToWString(path.data()).c_str(), stdout);
|
||||
fputs_utf8(path.c_str(), stdout);
|
||||
printf("\n");
|
||||
|
||||
path = LegalizeWindowsFileName(path);
|
||||
@@ -479,7 +402,7 @@ int RecursiveExtractFiles(int depth, ArchiveItemList *itemList, const std::strin
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unpackMain(int argc, const char **argv)
|
||||
int toolMain(int argc, const char **argv)
|
||||
{
|
||||
if (argc != 3)
|
||||
{
|
||||
@@ -537,30 +460,3 @@ int unpackMain(int argc, const char **argv)
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
LPWSTR *szArglist;
|
||||
int nArgs;
|
||||
int i;
|
||||
|
||||
szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
|
||||
|
||||
std::vector<std::string> utf8ArgStrings;
|
||||
std::vector<const char *> utf8Args;
|
||||
|
||||
utf8ArgStrings.resize(nArgs);
|
||||
utf8Args.resize(nArgs);
|
||||
|
||||
for (int i = 0; i < nArgs; i++)
|
||||
{
|
||||
utf8ArgStrings[i] = ConvertWStringToUTF8(szArglist[i]);
|
||||
utf8Args[i] = utf8ArgStrings[i].c_str();
|
||||
}
|
||||
|
||||
const char **args = nullptr;
|
||||
if (nArgs)
|
||||
args = &utf8Args[0];
|
||||
|
||||
return unpackMain(nArgs, args);
|
||||
}
|
||||
|
||||
|
@@ -61,24 +61,28 @@
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\PortabilityLayer.props" />
|
||||
<Import Project="..\Common.props" />
|
||||
<Import Project="..\MacRomanConversion.props" />
|
||||
<Import Project="..\WindowsUnicodeToolShim.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
@@ -186,6 +190,9 @@
|
||||
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
|
||||
<Project>{6ec62b0f-9353-40a4-a510-3788f1368b33}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\WindowsUnicodeToolShim\WindowsUnicodeToolShim.vcxproj">
|
||||
<Project>{15009625-1120-405e-8bba-69a16cd6713d}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
Reference in New Issue
Block a user