update : ips feature extensions (#1010)

[1] cps-1 cpsrom is reserved to 0x300000 (captcomm hack).
[2] Lift the limit in byteswap state that [ipsmaxlen] cannot be greater than [romlen].
This commit is contained in:
taoenwen 2022-04-29 08:23:13 +08:00 committed by GitHub
parent 5ccca6baa2
commit b133b6f21f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 12 deletions

View File

@ -399,6 +399,7 @@ void Reinitialise();
extern bool bDoIpsPatch;
extern INT32 nIpsMaxFileLen;
void IpsApplyPatches(UINT8* base, char* rom_name);
INT32 GetIpsesMaxLen(char* rom_name);
// ---------------------------------------------------------------------------
// Flags used with the Burndriver structure

View File

@ -16100,7 +16100,7 @@ static INT32 Cps1LoadRoms(INT32 bLoad)
} while (ri.nLen);
if (bDoIpsPatch && (0x200000 > nCpsRomLen)) nCpsRomLen = 0x200000; // Some ips come from hack games in which CpsRom is expanded.
if (bDoIpsPatch && (0x300000 > nCpsRomLen)) nCpsRomLen = 0x300000; // Some ips come from hack games in which CpsRom is expanded.
if (Cps1Qs) nCpsZRomLen *= 2;
if (GameHasStars) nCpsGfxLen += 0x2000;
if (PangEEP) nCpsGfxLen *= 2;

View File

@ -25,6 +25,12 @@ INT32 BurnLoadRomExt(UINT8 *Dest, INT32 i, INT32 nGap, INT32 nFlags)
if ((nGap>1) || (nFlags & LD_NIBBLES) || (nFlags & LD_XOR))
{
if (bDoIpsPatch) { // Ipses larger than the length of the rom are allowed.
INT32 nIpsesMaxLen = GetIpsesMaxLen(RomName);
if (nIpsesMaxLen > nLen)
nLen = nIpsesMaxLen;
}
INT32 nLoadLen=0;
UINT8 *Load=(UINT8 *)BurnMalloc(nLen);
if (Load==NULL) return 1;
@ -35,8 +41,8 @@ INT32 BurnLoadRomExt(UINT8 *Dest, INT32 i, INT32 nGap, INT32 nFlags)
if (bDoIpsPatch) IpsApplyPatches(Load, RomName);
if (nRet!=0) { if (Load) { BurnFree(Load); Load = NULL; } return 1; }
if (nLoadLen<0) nLoadLen=0;
if (nLoadLen>nLen) nLoadLen=nLen;
if (nLoadLen < 0) nLoadLen = 0;
if (nLoadLen > nLen || bDoIpsPatch) nLoadLen = nLen;
INT32 nGroup = (LD_GROUP(nFlags) > 0) ? LD_GROUP(nFlags) : 1;
INT32 nInvert = (nFlags & LD_INVERT) ? 0xff : 0;
@ -50,8 +56,8 @@ INT32 BurnLoadRomExt(UINT8 *Dest, INT32 i, INT32 nGap, INT32 nFlags)
for (INT32 n = 0, z = 0; n < nLoadLen; n += nGroup, z += nGap) {
if (nNibbles) {
Dest[z+0] = (Src[n^nByteswap] ^ nInvert) & 0xf;
Dest[z+1] = (Src[n^nByteswap] ^ nInvert) >> 4;
Dest[z + 0] = (Src[n ^ nByteswap] ^ nInvert) & 0xf;
Dest[z + 1] = (Src[n ^ nByteswap] ^ nInvert) >> 4;
} else {
if (nReverse) {
for (INT32 j = 0; j < nGroup; j++) {
@ -73,9 +79,7 @@ INT32 BurnLoadRomExt(UINT8 *Dest, INT32 i, INT32 nGap, INT32 nFlags)
BurnFree(Load);
Load = NULL;
}
}
else
{
} else {
// If no XOR, and gap of 1, just copy straight in
nRet=BurnExtLoadRom(Dest,NULL,i);
if (bDoIpsPatch) IpsApplyPatches(Dest, RomName);

View File

@ -796,7 +796,7 @@ static void PatchFile(const char* ips_path, UINT8* base, bool readonly)
}
while (Size--) {
mem8 = base + Offset;
if (!readonly) mem8 = base + Offset; // When in the read-only state, the only thing is to get nIpsMaxFileLen, thus avoiding memory out-of-bounds.
Offset++;
if (Offset > nIpsMaxFileLen) nIpsMaxFileLen = Offset; // file size is growing
if (readonly) {
@ -844,7 +844,7 @@ static char* stristr_int(const char* str1, const char* str2)
return (*p2) ? NULL : (char*)r;
}
static void DoPatchGame(const char* patch_name, char* game_name, UINT8* base, INT32 readonly)
static void DoPatchGame(const char* patch_name, char* game_name, UINT8* base, bool readonly)
{
char s[MAX_PATH];
char* p = NULL;
@ -938,7 +938,7 @@ void IpsApplyPatches(UINT8* base, char* rom_name)
{
char ips_data[MAX_PATH];
nIpsMaxFileLen = 0;
nIpsMaxFileLen = 0;
int nActivePatches = GetIpsNumActivePatches();
@ -946,7 +946,26 @@ void IpsApplyPatches(UINT8* base, char* rom_name)
memset(ips_data, 0, MAX_PATH);
TCHARToANSI(szIpsActivePatches[i], ips_data, sizeof(ips_data));
DoPatchGame(ips_data, rom_name, base, false);
}
}
}
INT32 GetIpsesMaxLen(char* rom_name)
{
INT32 nRet = -1; // The function returns the last patched address if it succeeds, and -1 if it fails.
if (NULL != rom_name) {
char ips_data[MAX_PATH];
nIpsMaxFileLen = 0;
int nActivePatches = GetIpsNumActivePatches();
for (int i = 0; i < nActivePatches; i++) {
memset(ips_data, 0, MAX_PATH);
TCHARToANSI(szIpsActivePatches[i], ips_data, sizeof(ips_data));
DoPatchGame(ips_data, rom_name, NULL, true);
if (nIpsMaxFileLen > nRet) nRet = nIpsMaxFileLen; // Returns the address with the largest length in ipses.
}
}
return nRet;
}
void IpsPatchExit()