Add convenience logic for "offset" to Address definitions in GameConf (#580)
Allows for the last "read" offset for an Address to instead be "offset", which doesn't deref the addr pointer after applying the offset Shortens the necessary coding to get a particular Address inside a function (old: store offset in a separate GameConf Offsets entry, apply the offset to the Address in SP)
This commit is contained in:
parent
4bab834716
commit
c3b25e54f8
@ -323,6 +323,7 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
m_Address[0] = '\0';
|
m_Address[0] = '\0';
|
||||||
m_AddressSignature[0] = '\0';
|
m_AddressSignature[0] = '\0';
|
||||||
m_AddressReadCount = 0;
|
m_AddressReadCount = 0;
|
||||||
|
m_AddressLastIsOffset = false;
|
||||||
|
|
||||||
strncopy(m_Address, name, sizeof(m_Address));
|
strncopy(m_Address, name, sizeof(m_Address));
|
||||||
m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS;
|
m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS;
|
||||||
@ -430,10 +431,18 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m_ParseState == PSTATE_GAMEDEFS_ADDRESSES_ADDRESS || m_ParseState == PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ) {
|
} else if (m_ParseState == PSTATE_GAMEDEFS_ADDRESSES_ADDRESS || m_ParseState == PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ) {
|
||||||
if (strcmp(key, "read") == 0) {
|
if (strcmp(key, "read") == 0 || strcmp(key, "offset") == 0) {
|
||||||
int limit = sizeof(m_AddressRead)/sizeof(m_AddressRead[0]);
|
int limit = sizeof(m_AddressRead)/sizeof(m_AddressRead[0]);
|
||||||
if (m_AddressReadCount < limit)
|
if (m_AddressLastIsOffset)
|
||||||
{
|
{
|
||||||
|
logger->LogError("[SM] Error parsing Address \"%s\", 'offset' entry must be the last entry (gameconf \"%s\")", m_Address, m_CurFile);
|
||||||
|
}
|
||||||
|
else if (m_AddressReadCount < limit)
|
||||||
|
{
|
||||||
|
if (strcmp(key, "offset") == 0)
|
||||||
|
{
|
||||||
|
m_AddressLastIsOffset = true;
|
||||||
|
}
|
||||||
m_AddressRead[m_AddressReadCount] = atoi(value);
|
m_AddressRead[m_AddressReadCount] = atoi(value);
|
||||||
m_AddressReadCount++;
|
m_AddressReadCount++;
|
||||||
}
|
}
|
||||||
@ -637,7 +646,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
|
|
||||||
if (m_Address[0] != '\0' && m_AddressSignature[0] != '\0')
|
if (m_Address[0] != '\0' && m_AddressSignature[0] != '\0')
|
||||||
{
|
{
|
||||||
AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead);
|
AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead, m_AddressLastIsOffset);
|
||||||
m_Addresses.replace(m_Address, addrConf);
|
m_Addresses.replace(m_Address, addrConf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,12 +1006,17 @@ bool CGameConfig::GetAddress(const char *key, void **retaddr)
|
|||||||
int offset = addrConf.read[i];
|
int offset = addrConf.read[i];
|
||||||
|
|
||||||
//NULLs in the middle of an indirection chain are bad, end NULL is ok
|
//NULLs in the middle of an indirection chain are bad, end NULL is ok
|
||||||
if (addr == NULL || reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
|
if (addr == NULL || reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
|
||||||
{
|
{
|
||||||
*retaddr = NULL;
|
*retaddr = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
addr = *(reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(addr) + offset));
|
//If lastIsOffset is set and this is the last iteration of the loop, don't deref
|
||||||
|
if (addrConf.lastIsOffset && i == addrConf.readCount-1) {
|
||||||
|
addr = reinterpret_cast<void*>(reinterpret_cast<uint8_t*>(addr) + offset);
|
||||||
|
} else {
|
||||||
|
addr = *(reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(addr) + offset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*retaddr = addr;
|
*retaddr = addr;
|
||||||
@ -1014,13 +1028,17 @@ static inline unsigned minOf(unsigned a, unsigned b)
|
|||||||
return a <= b ? a : b;
|
return a <= b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read)
|
CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read, bool lastIsOffset)
|
||||||
{
|
{
|
||||||
unsigned readLimit = minOf(readCount, sizeof(this->read) / sizeof(this->read[0]));
|
unsigned readLimit = minOf(readCount, sizeof(this->read) / sizeof(this->read[0]));
|
||||||
|
|
||||||
strncopy(signatureName, sigName, sizeof(signatureName) / sizeof(signatureName[0]));
|
strncopy(signatureName, sigName, sizeof(signatureName) / sizeof(signatureName[0]));
|
||||||
this->readCount = readLimit;
|
this->readCount = readLimit;
|
||||||
memcpy(&this->read[0], read, sizeof(this->read[0])*readLimit);
|
memcpy(&this->read[0], read, sizeof(this->read[0])*readLimit);
|
||||||
|
|
||||||
|
//For safety: if the readLimit isn't the same as the readCount, then the
|
||||||
|
//last read value was definitely discarded, so lastIsOffset should be ignored
|
||||||
|
this->lastIsOffset = readLimit < readCount ? false : lastIsOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendProp *CGameConfig::GetSendProp(const char *key)
|
SendProp *CGameConfig::GetSendProp(const char *key)
|
||||||
|
@ -103,8 +103,9 @@ private:
|
|||||||
char signatureName[64];
|
char signatureName[64];
|
||||||
int readCount;
|
int readCount;
|
||||||
int read[8];
|
int read[8];
|
||||||
|
bool lastIsOffset;
|
||||||
|
|
||||||
AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read);
|
AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read, bool lastIsOffset);
|
||||||
|
|
||||||
AddressConf() {}
|
AddressConf() {}
|
||||||
};
|
};
|
||||||
@ -113,6 +114,7 @@ private:
|
|||||||
char m_AddressSignature[64];
|
char m_AddressSignature[64];
|
||||||
int m_AddressReadCount;
|
int m_AddressReadCount;
|
||||||
int m_AddressRead[8];
|
int m_AddressRead[8];
|
||||||
|
bool m_AddressLastIsOffset;
|
||||||
StringHashMap<AddressConf> m_Addresses;
|
StringHashMap<AddressConf> m_Addresses;
|
||||||
const char *m_pEngine;
|
const char *m_pEngine;
|
||||||
const char *m_pBaseEngine;
|
const char *m_pBaseEngine;
|
||||||
|
Loading…
Reference in New Issue
Block a user