PSFLoader: Detect region from exe

This commit is contained in:
Connor McLaughlin 2021-01-24 13:55:19 +10:00
parent 10135e08a2
commit 253b115b11
4 changed files with 30 additions and 0 deletions

View File

@ -252,4 +252,20 @@ bool IsValidPSExeHeader(const PSEXEHeader& header, u32 file_size)
return true;
}
DiscRegion GetPSExeDiscRegion(const PSEXEHeader& header)
{
static constexpr char ntsc_u_id[] = "Sony Computer Entertainment Inc. for North America area";
static constexpr char ntsc_j_id[] = "Sony Computer Entertainment Inc. for Japan area";
static constexpr char pal_id[] = "Sony Computer Entertainment Inc. for Europe area";
if (std::memcmp(header.marker, ntsc_u_id, sizeof(ntsc_u_id) - 1) == 0)
return DiscRegion::NTSC_U;
else if (std::memcmp(header.marker, ntsc_j_id, sizeof(ntsc_j_id) - 1) == 0)
return DiscRegion::NTSC_J;
else if (std::memcmp(header.marker, pal_id, sizeof(pal_id) - 1) == 0)
return DiscRegion::PAL;
else
return DiscRegion::Other;
}
} // namespace BIOS

View File

@ -69,4 +69,5 @@ bool PatchBIOSFastBoot(u8* image, u32 image_size, const Hash& hash);
bool PatchBIOSForEXE(u8* image, u32 image_size, u32 r_pc, u32 r_gp, u32 r_sp, u32 r_fp);
bool IsValidPSExeHeader(const PSEXEHeader& header, u32 file_size);
DiscRegion GetPSExeDiscRegion(const PSEXEHeader& header);
} // namespace BIOS

View File

@ -1,4 +1,5 @@
#include "psf_loader.h"
#include "bios.h"
#include "common/assert.h"
#include "common/file_system.h"
#include "common/log.h"
@ -159,6 +160,16 @@ bool File::Load(const char* path)
}
}
// Region detection.
m_region = BIOS::GetPSExeDiscRegion(*reinterpret_cast<const BIOS::PSEXEHeader*>(m_program_data.data()));
// _refresh tag takes precedence.
const int refresh_tag = GetTagInt("_region", 0);
if (refresh_tag == 60)
m_region = DiscRegion::NTSC_U;
else if (refresh_tag == 50)
m_region = DiscRegion::PAL;
return true;
}

View File

@ -27,6 +27,7 @@ public:
ALWAYS_INLINE const ProgramData& GetProgramData() const { return m_program_data; }
ALWAYS_INLINE const TagMap& GetTagMap() const { return m_tags; }
ALWAYS_INLINE DiscRegion GetRegion() const { return m_region; }
std::optional<std::string> GetTagString(const char* tag_name) const;
std::optional<int> GetTagInt(const char* tag_name) const;
@ -46,6 +47,7 @@ private:
ProgramData m_program_data;
TagMap m_tags;
DiscRegion m_region = DiscRegion::Other;
};
bool Load(const char* path);