| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -7,14 +7,19 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "cd_image.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "cd_subchannel_replacement.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/align.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/assert.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/error.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/file_system.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/log.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/path.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/platform.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "common/string_util.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "fmt/format.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "libchdr/chd.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <algorithm>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <cerrno>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <cstdio>
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -22,6 +27,7 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <limits>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <map>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <optional>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Log_SetChannel(CDImageCHD);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				static std::optional<CDImage::TrackMode> ParseTrackModeString(const char* str)
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -46,6 +52,7 @@ static std::optional<CDImage::TrackMode> ParseTrackModeString(const char* str)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return std::nullopt;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				namespace {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class CDImageCHD : public CDImage
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				public:
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -66,12 +73,13 @@ private:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  enum : u32
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    CHD_CD_SECTOR_DATA_SIZE = 2352 + 96,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    CHD_CD_TRACK_ALIGNMENT = 4
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    CHD_CD_TRACK_ALIGNMENT = 4,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    MAX_PARENTS = 32 // Surely someone wouldn't be insane enough to go beyond this...
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  };
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_file* OpenCHD(const char* filename, FileSystem::ManagedCFilePtr fp, Common::Error* error, u32 recursion_level);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  bool ReadHunk(u32 hunk_index);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  std::FILE* m_fp = nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_file* m_chd = nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  u32 m_hunk_size = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  u32 m_sectors_per_hunk = 0;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -82,6 +90,7 @@ private:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  CDSubChannelReplacement m_sbi;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				} // namespace
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				CDImageCHD::CDImageCHD() = default;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -89,33 +98,114 @@ CDImageCHD::~CDImageCHD()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (m_chd)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    chd_close(m_chd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (m_fp)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    std::fclose(m_fp);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CDImageCHD::Open(const char* filename, Common::Error* error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				chd_file* CDImageCHD::OpenCHD(const char* filename, FileSystem::ManagedCFilePtr fp, Common::Error* error,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                              u32 recursion_level)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Assert(!m_fp);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  m_fp = FileSystem::OpenCFile(filename, "rb");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!m_fp)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_file* chd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_error err = chd_open_file(fp.get(), CHD_OPEN_READ | CHD_OPEN_TRANSFER_FILE, nullptr, &chd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (err == CHDERR_NONE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to open CHD '%s': errno %d", filename, errno);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // fp is now managed by libchdr
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    fp.release();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return chd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  else if (err != CHDERR_REQUIRES_PARENT)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to open CHD '%s': %s", filename, chd_error_string(err));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetErrno(errno);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetMessage(chd_error_string(err));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (recursion_level >= MAX_PARENTS)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to open CHD '%s': Too many parent files", filename);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetMessage("Too many parent files");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Need to get the sha1 to look for.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_header header;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  err = chd_read_header_file(fp.get(), &header);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (err != CHDERR_NONE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to read CHD header '%s': %s", filename, chd_error_string(err));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetMessage(chd_error_string(err));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Find a chd with a matching sha1 in the same directory.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Have to do *.* and filter on the extension manually because Linux is case sensitive.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // We _could_ memoize the CHD headers here, but is anyone actually going to nest CHDs that deep?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_file* parent_chd = nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const std::string parent_dir(Path::GetDirectory(filename));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  FileSystem::FindResultsArray parent_files;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  FileSystem::FindFiles(parent_dir.c_str(), "*.*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &parent_files);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  for (FILESYSTEM_FIND_DATA& fd : parent_files)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (StringUtil::EndsWithNoCase(Path::GetExtension(fd.FileName), ".chd"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      continue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    auto parent_fp =
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      FileSystem::OpenManagedSharedCFile(fd.FileName.c_str(), "rb", FileSystem::FileShareMode::DenyWrite);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (!parent_fp)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      continue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    chd_header parent_header;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    err = chd_read_header_file(parent_fp.get(), &parent_header);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (err != CHDERR_NONE || !chd_is_matching_parent(&header, &parent_header))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      continue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    // Match! Open this one.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if ((parent_chd = OpenCHD(fd.FileName.c_str(), std::move(parent_fp), error, recursion_level + 1)) != nullptr)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      Log_DevPrintf(fmt::format("Found parent CHD '{}' for '{}'.", Path::GetFileName(fd.FileName), Path::GetFileName(filename)).c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      break;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!parent_chd)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to open CHD '%s': Failed to find parent CHD, it must be in the same directory.", filename);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetMessage("Failed to find parent CHD, it must be in the same directory.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  chd_error err = chd_open_file(m_fp, CHD_OPEN_READ, nullptr, &m_chd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Now try re-opening with the parent.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  err = chd_open_file(fp.get(), CHD_OPEN_READ | CHD_OPEN_TRANSFER_FILE, parent_chd, &chd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (err != CHDERR_NONE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to open CHD '%s': %s", filename, chd_error_string(err));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetMessage(chd_error_string(err));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // fp now owned by libchdr
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  fp.release();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return chd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				bool CDImageCHD::Open(const char* filename, Common::Error* error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  auto fp = FileSystem::OpenManagedSharedCFile(filename, "rb", FileSystem::FileShareMode::DenyWrite);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!fp)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Log_ErrorPrintf("Failed to open CHD '%s': errno %d", filename, errno);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      error->SetErrno(errno);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  m_chd = OpenCHD(filename, std::move(fp), error, 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if (!m_chd)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  const chd_header* header = chd_get_header(m_chd);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  m_hunk_size = header->hunkbytes;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if ((m_hunk_size % CHD_CD_SECTOR_DATA_SIZE) != 0)
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -146,8 +236,8 @@ bool CDImageCHD::Open(const char* filename, Common::Error* error)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    u32 metadata_length;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    int track_num = 0, frames = 0, pregap_frames = 0, postgap_frames = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    err = chd_get_metadata(m_chd, CDROM_TRACK_METADATA2_TAG, num_tracks, metadata_str, sizeof(metadata_str),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                           &metadata_length, nullptr, nullptr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    chd_error err = chd_get_metadata(m_chd, CDROM_TRACK_METADATA2_TAG, num_tracks, metadata_str, sizeof(metadata_str),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                                     &metadata_length, nullptr, nullptr);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if (err == CHDERR_NONE)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      if (std::sscanf(metadata_str, CDROM_TRACK_METADATA2_FORMAT, &track_num, type_str, subtype_str, &frames,
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |