Skip to content

Commit

Permalink
Proof-of-concept: libchdr works on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Sep 29, 2023
1 parent b8fa3a2 commit ade6417
Show file tree
Hide file tree
Showing 16 changed files with 670 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Expand Up @@ -50,3 +50,6 @@
[submodule "ext/naett"]
path = ext/naett
url = https://github.com/erkkah/naett.git
[submodule "ext/libchdr"]
path = ext/libchdr
url = https://github.com/rtissera/libchdr.git
3 changes: 3 additions & 0 deletions Common/Common.vcxproj.filters
Expand Up @@ -1073,6 +1073,9 @@
<Filter Include="ext\naett">
<UniqueIdentifier>{34f45db9-5c08-49cb-b349-b9e760ce3213}</UniqueIdentifier>
</Filter>
<Filter Include="ext\libchdr">
<UniqueIdentifier>{b681797d-7747-487f-b448-5ef5b2d2805b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="..\ext\libpng17\CMakeLists.txt">
Expand Down
19 changes: 11 additions & 8 deletions Core/Core.vcxproj
Expand Up @@ -138,7 +138,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\x86\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WITH_UPNP;WIN32;_ARCH_32=1;_M_IX86=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;ARMIPS_USE_STD_FILESYSTEM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
Expand All @@ -165,7 +165,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib;../ext/zstd/lib</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WITH_UPNP;WIN32;_ARCH_64=1;_M_X64=1;_DEBUG;_LIB;_UNICODE;UNICODE;MINIUPNP_STATICLIB;ARMIPS_USE_STD_FILESYSTEM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
Expand Down Expand Up @@ -193,7 +193,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WITH_UPNP;WIN32;_ARCH_64=1;_DEBUG;_LIB;_UNICODE;UNICODE;ARMIPS_USE_STD_FILESYSTEM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
Expand Down Expand Up @@ -221,7 +221,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\arm\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;USING_WIN_UI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;USE_FFMPEG;WITH_UPNP;WIN32;_ARCH_32=1;_DEBUG;_LIB;_UNICODE;UNICODE;ARMIPS_USE_STD_FILESYSTEM;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
Expand Down Expand Up @@ -253,7 +253,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\x86\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
Expand Down Expand Up @@ -286,7 +286,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\x86_64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib;../ext/zstd/lib</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
Expand Down Expand Up @@ -321,7 +321,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\aarch64\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
Expand Down Expand Up @@ -356,7 +356,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\arm\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\ffmpeg\WindowsInclude;..\ext\libchdr\include;..\ffmpeg\Windows\arm\include;../common;..;../ext/glew;../ext/snappy;../ext/libpng17;../ext/zlib;../ext;../ext/zstd/lib</AdditionalIncludeDirectories>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<FloatingPointModel>Precise</FloatingPointModel>
<BufferSecurityCheck>false</BufferSecurityCheck>
Expand Down Expand Up @@ -1466,6 +1466,9 @@
<ProjectReference Include="..\ext\libarmips.vcxproj">
<Project>{129e5e2b-39c1-4d84-96fe-dfd22dbb4a25}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\libchdr.vcxproj">
<Project>{956f1f48-b612-46d8-89ee-96996dcd9383}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\miniupnpc.vcxproj">
<Project>{d8a71225-178b-424e-96c1-cc3be2c1b047}</Project>
</ProjectReference>
Expand Down
160 changes: 154 additions & 6 deletions Core/FileSystems/BlockDevices.cpp
Expand Up @@ -24,8 +24,11 @@
#include "Common/System/OSD.h"
#include "Common/Log.h"
#include "Common/Swap.h"
#include "Common/File/FileUtil.h"
#include "Common/File/DirListing.h"
#include "Core/Loaders.h"
#include "Core/FileSystems/BlockDevices.h"
#include "libchdr/chd.h"

extern "C"
{
Expand All @@ -37,20 +40,29 @@ extern "C"
std::mutex NPDRMDemoBlockDevice::mutex_;

BlockDevice *constructBlockDevice(FileLoader *fileLoader) {
// Check for CISO
if (!fileLoader->Exists())
return nullptr;
char buffer[4]{};
size_t size = fileLoader->ReadAt(0, 1, 4, buffer);
if (size == 4 && !memcmp(buffer, "CISO", 4))
char buffer[8]{};
size_t size = fileLoader->ReadAt(0, 1, 8, buffer);
if (size != 8) {
// Bad or empty file
return nullptr;
}

// Check for CISO
if (!memcmp(buffer, "CISO", 4)) {
return new CISOFileBlockDevice(fileLoader);
if (size == 4 && !memcmp(buffer, "\x00PBP", 4)) {
} else if (!memcmp(buffer, "\x00PBP", 4)) {
uint32_t psarOffset = 0;
size = fileLoader->ReadAt(0x24, 1, 4, &psarOffset);
if (size == 4 && psarOffset < fileLoader->FileSize())
return new NPDRMDemoBlockDevice(fileLoader);
} else if (!memcmp(buffer, "MComprHD", 8)) {
return new CHDFileBlockDevice(fileLoader);
} else {
// Should be jsut a regular ISO.
return new FileBlockDevice(fileLoader);
}
return new FileBlockDevice(fileLoader);
}

u32 BlockDevice::CalculateCRC(volatile bool *cancel) {
Expand Down Expand Up @@ -519,3 +531,139 @@ bool NPDRMDemoBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)

return true;
}

/*
* CHD file
*/
static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 };

struct CHDImpl {
chd_file *chd = nullptr;
const chd_header *header = nullptr;
};

CHDFileBlockDevice::CHDFileBlockDevice(FileLoader *fileLoader)
: BlockDevice(fileLoader), impl_(new CHDImpl())
{
// Default, in case of failure
numBlocks = 0;

chd_header childHeader;

int depth = 0;
Path paths[8];
paths[0] = fileLoader->GetPath();

chd_error err = chd_read_header(paths[0].c_str(), &childHeader);
if (err != CHDERR_NONE) {
ERROR_LOG(LOADER, "Error loading CHD header for '%s': %s", paths[0].c_str(), chd_error_string(err));
NotifyReadError();
return;
}

/*
// TODO: Support parent/child CHD files.
if (memcmp(nullsha1, childHeader.parentsha1, sizeof(childHeader.sha1)) != 0) {
chd_header parentHeader;
// Look for parent CHD in current directory
Path chdDir = paths[0].NavigateUp();
std::vector<File::FileInfo> files;
if (File::GetFilesInDir(chdDir, &files)) {
parentHeader.length = 0;
for (const auto &file : files) {
std::string extension = file.fullName.GetFileExtension();
if (extension != ".chd") {
continue;
}
if (chd_read_header(filepath.c_str(), &parentHeader) == CHDERR_NONE &&
memcmp(parentHeader.sha1, childHeader.parentsha1, sizeof(parentHeader.sha1)) == 0) {
// ERROR_LOG(LOADER, "Checking '%s'", filepath.c_str());
paths[++depth] = filepath;
break;
}
}
// Check if parentHeader was opened
if (parentHeader.length == 0) {
ERROR_LOG(LOADER, "Error loading CHD '%s': parents not found", fileLoader->GetPath().c_str());
NotifyReadError();
return;
}
memcpy(childHeader.parentsha1, parentHeader.parentsha1, sizeof(childHeader.parentsha1));
} while (memcmp(nullsha1, childHeader.parentsha1, sizeof(childHeader.sha1)) != 0);
}
*/

chd_file *parent = NULL;
chd_file *child = NULL;
err = chd_open(paths[depth].c_str(), CHD_OPEN_READ, NULL, &child);
if (err != CHDERR_NONE) {
ERROR_LOG(LOADER, "Error loading CHD '%s': %s", paths[depth].c_str(), chd_error_string(err));
NotifyReadError();
return;
}
for (int d = depth - 1; d >= 0; d--) {
parent = child;
child = NULL;
err = chd_open(paths[d].c_str(), CHD_OPEN_READ, parent, &child);
if (err != CHDERR_NONE) {
ERROR_LOG(LOADER, "Error loading CHD '%s': %s", paths[d].c_str(), chd_error_string(err));
NotifyReadError();
return;
}
}
impl_->chd = child;

impl_->header = chd_get_header(impl_->chd);
readBuffer = new u8[impl_->header->hunkbytes];
currentHunk = -1;
blocksPerHunk = impl_->header->hunkbytes / impl_->header->unitbytes;
numBlocks = impl_->header->unitcount;
}

CHDFileBlockDevice::~CHDFileBlockDevice()
{
if (numBlocks > 0) {
chd_close(impl_->chd);
delete[] readBuffer;
}
}

bool CHDFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)
{
if ((u32)blockNumber >= numBlocks) {
memset(outPtr, 0, GetBlockSize());
return false;
}
u32 hunk = blockNumber / blocksPerHunk;
u32 blockInHunk = blockNumber % blocksPerHunk;

if (currentHunk != hunk) {
chd_error err = chd_read(impl_->chd, hunk, readBuffer);
if (err != CHDERR_NONE) {
ERROR_LOG(LOADER, "CHD read failed: %d %d %s", blockNumber, hunk, chd_error_string(err));
NotifyReadError();
}
}
memcpy(outPtr, readBuffer + blockInHunk * impl_->header->unitbytes, GetBlockSize());

return true;
}

bool CHDFileBlockDevice::ReadBlocks(u32 minBlock, int count, u8 *outPtr) {
if (minBlock >= numBlocks) {
memset(outPtr, 0, GetBlockSize() * count);
return false;
}

for (int i = 0; i < count; i++) {
if (!ReadBlock(minBlock + i, outPtr + i * GetBlockSize())) {
return false;
}
}
return true;
}
18 changes: 18 additions & 0 deletions Core/FileSystems/BlockDevices.h
Expand Up @@ -130,5 +130,23 @@ class NPDRMDemoBlockDevice : public BlockDevice {
u8 *tempBuf;
};

struct CHDImpl;

class CHDFileBlockDevice : public BlockDevice {
public:
CHDFileBlockDevice(FileLoader *fileLoader);
~CHDFileBlockDevice();
bool ReadBlock(int blockNumber, u8 *outPtr, bool uncached = false) override;
bool ReadBlocks(u32 minBlock, int count, u8 *outPtr) override;
u32 GetNumBlocks() override { return numBlocks; }
bool IsDisc() override { return true; }

private:
std::unique_ptr<CHDImpl> impl_;
u8 *readBuffer;
u32 currentHunk;
u32 blocksPerHunk;
u32 numBlocks;
};

BlockDevice *constructBlockDevice(FileLoader *fileLoader);
2 changes: 2 additions & 0 deletions Core/Loaders.cpp
Expand Up @@ -94,6 +94,8 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader, std::string *errorStrin
return IdentifiedFileType::PSP_ISO;
} else if (extension == ".cso") {
return IdentifiedFileType::PSP_ISO;
} else if (extension == ".chd") {
return IdentifiedFileType::PSP_ISO;
} else if (extension == ".ppst") {
return IdentifiedFileType::PPSSPP_SAVESTATE;
} else if (extension == ".ppdmp") {
Expand Down
2 changes: 1 addition & 1 deletion Qt/QtMain.cpp
Expand Up @@ -304,7 +304,7 @@ bool MainUI::HandleCustomEvent(QEvent *e) {
const char *filter = "All files (*.*)";
switch (fileType) {
case BrowseFileType::BOOTABLE:
filter = "PSP ROMs (*.iso *.cso *.pbp *.elf *.zip *.ppdmp)";
filter = "PSP ROMs (*.iso *.cso *.chd *.pbp *.elf *.zip *.ppdmp)";
break;
case BrowseFileType::IMAGE:
filter = "Pictures (*.jpg *.png)";
Expand Down
4 changes: 2 additions & 2 deletions Qt/mainwindow.cpp
Expand Up @@ -125,7 +125,7 @@ void MainWindow::bootDone()
/* SIGNALS */
void MainWindow::loadAct()
{
QString filename = QFileDialog::getOpenFileName(NULL, "Load File", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.prx)");
QString filename = QFileDialog::getOpenFileName(NULL, "Load File", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.chd *.prx)");
if (QFile::exists(filename))
{
QFileInfo info(filename);
Expand Down Expand Up @@ -255,7 +255,7 @@ void MainWindow::resetAct()

void MainWindow::switchUMDAct()
{
QString filename = QFileDialog::getOpenFileName(NULL, "Switch UMD", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.prx)");
QString filename = QFileDialog::getOpenFileName(NULL, "Switch UMD", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.chd *.prx)");
if (QFile::exists(filename))
{
QFileInfo info(filename);
Expand Down
19 changes: 19 additions & 0 deletions Windows/PPSSPP.sln
Expand Up @@ -93,6 +93,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpu_features", "..\ext\cpu_
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rcheevos", "..\ext\rcheevos-build\rcheevos.vcxproj", "{31694510-A8C0-40F6-B09B-E8DF825ADEFA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libchdr", "..\ext\libchdr.vcxproj", "{956F1F48-B612-46D8-89EE-96996DCD9383}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Expand Down Expand Up @@ -395,6 +397,22 @@ Global
{31694510-A8C0-40F6-B09B-E8DF825ADEFA}.Release|Win32.Build.0 = Release|Win32
{31694510-A8C0-40F6-B09B-E8DF825ADEFA}.Release|x64.ActiveCfg = Release|x64
{31694510-A8C0-40F6-B09B-E8DF825ADEFA}.Release|x64.Build.0 = Release|x64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|ARM.ActiveCfg = Debug|ARM
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|ARM.Build.0 = Debug|ARM
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|ARM64.ActiveCfg = Debug|ARM64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|ARM64.Build.0 = Debug|ARM64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|Win32.ActiveCfg = Debug|Win32
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|Win32.Build.0 = Debug|Win32
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|x64.ActiveCfg = Debug|x64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Debug|x64.Build.0 = Debug|x64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|ARM.ActiveCfg = Release|ARM
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|ARM.Build.0 = Release|ARM
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|ARM64.ActiveCfg = Release|ARM64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|ARM64.Build.0 = Release|ARM64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|Win32.ActiveCfg = Release|Win32
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|Win32.Build.0 = Release|Win32
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|x64.ActiveCfg = Release|x64
{956F1F48-B612-46D8-89EE-96996DCD9383}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -412,6 +430,7 @@ Global
{8BFD8150-94D5-4BF9-8A50-7BD9929A0850} = {39FCACF8-10D9-4D8D-97AA-7507436AD932}
{C249F016-7F82-45CF-BB6E-0642A988C4D3} = {39FCACF8-10D9-4D8D-97AA-7507436AD932}
{31694510-A8C0-40F6-B09B-E8DF825ADEFA} = {39FCACF8-10D9-4D8D-97AA-7507436AD932}
{956F1F48-B612-46D8-89EE-96996DCD9383} = {39FCACF8-10D9-4D8D-97AA-7507436AD932}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2FD47774-A031-48F4-B645-A49A3140A29B}
Expand Down
3 changes: 3 additions & 0 deletions Windows/PPSSPP.vcxproj
Expand Up @@ -1721,6 +1721,9 @@
<ProjectReference Include="..\ext\glslang.vcxproj">
<Project>{edfa2e87-8ac1-4853-95d4-d7594ff81947}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\libchdr.vcxproj">
<Project>{956f1f48-b612-46d8-89ee-96996dcd9383}</Project>
</ProjectReference>
<ProjectReference Include="..\ext\libkirk\libkirk.vcxproj">
<Project>{3baae095-e0ab-4b0e-b5df-ce39c8ae31de}</Project>
</ProjectReference>
Expand Down

0 comments on commit ade6417

Please sign in to comment.