Fix Title_ID parsing/rendering to use the correct format.
This also updates the rendering of the Version Flag. All retail Xbox Games use a title_id of this format: XX-000 Where XX = Publisher code (MS, EA, etc) and 000 = Game Number by that publisher. This can be used to properly uniquely identify games, and even cross-reference with the Redump database that uses the same Serial No. format. Additionally, this PR also fixes Version field rendering, to be in the correct 1.XX format. This is useful because the combination of Title_ID and Version No uniquely identifies games! Even in regional varients where the title_id doesn't change, the version number does! Some special XBEs (like Dashboard, updaters, XDK samples) use non-printable characters in the title_id/serial number field, so we fallback to Hex in this case
This commit is contained in:
parent
4760872a03
commit
9b6fe04096
|
@ -42,6 +42,8 @@
|
|||
#include <sstream> // For std::stringstream
|
||||
#include <iomanip> // For std::setfill, std::uppercase, std::hex
|
||||
|
||||
extern std::string FormatTitleId(uint32_t title_id); // Exposed in Emu.cpp
|
||||
|
||||
// better time
|
||||
static char *BetterTime(uint32 x_timeDate)
|
||||
{
|
||||
|
@ -315,7 +317,7 @@ std::string XbePrinter::GenCertificateHeader()
|
|||
text << "Dumping XBE Certificate...\n\n";
|
||||
text << "Size of Certificate : 0x" << std::setw(8) << Xbe_certificate->dwSize << "\n";
|
||||
text << "TimeDate Stamp : 0x" << std::setw(8) << Xbe_certificate->dwTimeDate << " (" << BetterTime(Xbe_certificate->dwTimeDate) << ")\n";
|
||||
text << "Title ID : 0x" << std::setw(8) << Xbe_certificate->dwTitleId << "\n";
|
||||
text << "Title ID : " << FormatTitleId(Xbe_certificate->dwTitleId) << "\n";
|
||||
text << "Title : L\"" << Xbe_to_print->m_szAsciiTitle << "\"\n";
|
||||
return text.str();
|
||||
}
|
||||
|
@ -347,7 +349,7 @@ std::string XbePrinter::GenMediaInfo()
|
|||
text << "Game Region : 0x" << std::setw(8) << Xbe_certificate->dwGameRegion << " (" << Xbe_to_print->GameRegionToString() << ")\n";
|
||||
text << "Game Ratings : 0x" << std::setw(8) << Xbe_certificate->dwGameRatings << " (" << GameRatingToString() << ")\n";
|
||||
text << "Disk Number : 0x" << std::setw(8) << Xbe_certificate->dwDiskNumber << "\n";
|
||||
text << "Version : 0x" << std::setw(8) << Xbe_certificate->dwVersion << "\n";
|
||||
text << "Version : 1." << std::dec << std::setw(2) << Xbe_certificate->dwVersion << "\n";
|
||||
return text.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -1318,8 +1318,6 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
std::string xbeDirectory(szBuffer);
|
||||
CxbxBasePathHandle = CreateFile(CxbxBasePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
memset(szBuffer, 0, MAX_PATH);
|
||||
sprintf(szBuffer, "%08X", g_pCertificate->dwTitleId);
|
||||
std::string titleId(szBuffer);
|
||||
// Games may assume they are running from CdRom :
|
||||
CxbxDefaultXbeDriveIndex = CxbxRegisterDeviceHostPath(DeviceCdrom0, xbeDirectory);
|
||||
// Partition 0 contains configuration data, and is accessed as a native file, instead as a folder :
|
||||
|
@ -1375,7 +1373,8 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
|
||||
// Dump Xbe certificate
|
||||
if (g_pCertificate != NULL) {
|
||||
printf("[0x%.4X] INIT: XBE TitleID : %.8X\n", GetCurrentThreadId(), g_pCertificate->dwTitleId);
|
||||
printf("[0x%.4X] INIT: XBE TitleID : %s\n", GetCurrentThreadId(), FormatTitleId(g_pCertificate->dwTitleId).c_str());
|
||||
printf("[0x%.4X] INIT: XBE Version : 1.%02d\n", GetCurrentThreadId(), g_pCertificate->dwVersion);
|
||||
printf("[0x%.4X] INIT: XBE TitleName : %ls\n", GetCurrentThreadId(), g_pCertificate->wszTitleName);
|
||||
printf("[0x%.4X] INIT: XBE Region : %s\n", GetCurrentThreadId(), CxbxKrnl_Xbe->GameRegionToString());
|
||||
}
|
||||
|
|
|
@ -75,7 +75,32 @@ bool g_DirectHostBackBufferAccess = false;
|
|||
LARGE_INTEGER HostSystemTimeDelta = {};
|
||||
|
||||
// Static Function(s)
|
||||
static int ExitException(LPEXCEPTION_POINTERS e);
|
||||
static int ExitException(LPEXCEPTION_POINTERS e);
|
||||
|
||||
std::string FormatTitleId(uint32_t title_id)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
// If the Title ID prefix is a printable character, parse it
|
||||
// This shows the correct game serial number for retail titles!
|
||||
// EG: MS-001 for 1st tile published by MS, EA-002 for 2nd title by EA, etc
|
||||
// Some special Xbes (Dashboard, XDK Samples) use non-alphanumeric serials
|
||||
// We fall back to Hex for those
|
||||
char pTitleId1 = (title_id >> 24) & 0xFF;
|
||||
char pTitleId2 = (title_id >> 16) & 0xFF;
|
||||
|
||||
if (isalnum(pTitleId1) && isalnum(pTitleId2)) {
|
||||
ss << pTitleId1 << pTitleId2;
|
||||
} else {
|
||||
// Prefix was non-printable, so we need to print a hex reprentation
|
||||
ss << "0x" << std::setfill('0') << std::setw(4) << std::hex << std::uppercase << (uint16_t)((title_id & 0xFFFF0000) >> 16);
|
||||
}
|
||||
|
||||
ss << "-";
|
||||
ss << std::setfill('0') << std::setw(3) << std::dec << (title_id & 0x0000FFFF);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// print out a warning message to the kernel debug log file
|
||||
#ifdef _DEBUG_WARNINGS
|
||||
|
|
|
@ -45,7 +45,9 @@
|
|||
void NTAPI EmuWarning(const char *szWarningMessage, ...);
|
||||
#else
|
||||
inline void NTAPI EmuWarning(const char *szWarningMessage, ...) { }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
std::string FormatTitleId(uint32_t title_id);
|
||||
|
||||
// exception handler
|
||||
extern int EmuException(LPEXCEPTION_POINTERS e);
|
||||
|
|
|
@ -574,10 +574,7 @@ void EmuHLEIntercept(Xbe::Header *pXbeHeader)
|
|||
|
||||
// Write the Certificate Details to the cache file
|
||||
WritePrivateProfileString("Certificate", "Name", tAsciiTitle, filename.c_str());
|
||||
|
||||
std::stringstream titleId;
|
||||
titleId << std::hex << g_pCertificate->dwTitleId;
|
||||
WritePrivateProfileString("Certificate", "TitleID", titleId.str().c_str(), filename.c_str());
|
||||
WritePrivateProfileString("Certificate", "TitleID", FormatTitleId(g_pCertificate->dwTitleId).c_str(), filename.c_str());
|
||||
|
||||
std::stringstream region;
|
||||
region << std::hex << g_pCertificate->dwGameRegion;
|
||||
|
|
Loading…
Reference in New Issue