Browse Source

Make save game code big-endian compatible

pull/557/head
Samuel-DEVULDER 6 years ago committed by Anders Jenbo
parent
commit
9c516819c1
  1. 11
      Source/encrypt.cpp
  2. 28
      Source/loadsave.cpp
  3. 19
      Source/mpqapi.cpp
  4. 66
      Source/pack.cpp
  5. 5
      Source/sha.cpp

11
Source/encrypt.cpp

@ -13,9 +13,11 @@ void Decrypt(void *block, DWORD size, DWORD key)
castBlock = (DWORD *)block;
seed = 0xEEEEEEEE;
for (i = 0; i < (size >> 2); i++) {
DWORD t = SwapLE32(*castBlock);
seed += hashtable[0x400 + (key & 0xFF)];
*castBlock ^= seed + key;
seed += *castBlock + (seed << 5) + 3;
t ^= seed + key;
*castBlock = t;
seed += t + (seed << 5) + 3;
key = ((~key << 0x15) + 0x11111111) | (key >> 0x0B);
castBlock++;
}
@ -29,9 +31,10 @@ void Encrypt(void *block, DWORD size, DWORD key)
castBlock = (DWORD *)block;
seed = 0xEEEEEEEE;
for (i = 0; i < (size >> 2); i++) {
ch = *castBlock;
DWORD t = ch = *castBlock;
seed += hashtable[0x400 + (key & 0xFF)];
*castBlock ^= seed + key;
t ^= seed + key;
*castBlock = SwapLE32(t);
seed += ch + (seed << 5) + 3;
key = ((~key << 0x15) + 0x11111111) | (key >> 0x0B);
castBlock++;

28
Source/loadsave.cpp

@ -215,32 +215,48 @@ void CopyBytes(const void *src, const int n, void *dst)
void CopyChar(const void *src, void *dst)
{
CopyBytes(src, 1, dst);
*(char*)dst = *(char*)src;
tbuff += 1;
}
void CopyShort(const void *src, void *dst)
{
CopyBytes(src, 2, dst);
*(unsigned short*)dst = SwapLE16(*(unsigned short*)src);
tbuff += 2;
}
void CopyShorts(const void *src, const int n, void *dst)
{
CopyBytes(src, 2 * n, dst);
unsigned short *s=src, *d=dst;
int i=n;
tbuff += 2*n;
while(i) {
*d = SwapLE16(*s);
++d; ++s; --i;
}
}
void CopyInt(const void *src, void *dst)
{
CopyBytes(src, 4, dst);
*(unsigned int*)dst = SwapLE32(*(unsigned int*)src);
tbuff += 4;
}
void CopyInts(const void *src, const int n, void *dst)
{
CopyBytes(src, 4 * n, dst);
unsigned int *s=src, *d=dst;
int i=n;
tbuff += 4*n;
while(i) {
*d = SwapLE32(*s);
++d; ++s; --i;
}
}
void CopyInt64(const void *src, void *dst)
{
CopyBytes(src, 8, dst);
*(unsigned long long*)dst = SDL_SwapLE64(*(unsigned long long*)src);
tbuff += 8;
}
void LoadPlayer(int i)

19
Source/mpqapi.cpp

@ -216,7 +216,7 @@ BOOL mpqapi_write_file_contents(const char *pszName, const BYTE *pbData, DWORD d
}
destsize += nNumberOfBytesToWrite;
}
sectoroffsettable[j] = destsize;
sectoroffsettable[j] = SwapLE32(destsize);
if (!WriteFile(sghArchive, mpq_buf, len, &len, NULL)) {
goto on_error;
}
@ -228,7 +228,7 @@ BOOL mpqapi_write_file_contents(const char *pszName, const BYTE *pbData, DWORD d
destsize += len;
}
sectoroffsettable[j] = destsize;
sectoroffsettable[j] = SwapLE32(destsize);
if (SetFilePointer(sghArchive, -destsize, NULL, FILE_CURRENT) == (DWORD)-1) {
goto on_error;
}
@ -358,6 +358,20 @@ on_error:
return FALSE;
}
static BOOL byteSwapHdr(_FILEHEADER *pHdr)
{
pHdr->signature = SDL_SwapLE32(pHdr->signature);
pHdr->headersize = SDL_SwapLE32(pHdr->headersize);
pHdr->filesize = SDL_SwapLE32(pHdr->filesize);
pHdr->version = SDL_SwapLE16(pHdr->version);
pHdr->sectorsizeid = SDL_SwapLE16(pHdr->sectorsizeid);
pHdr->hashoffset = SDL_SwapLE32(pHdr->hashoffset);
pHdr->blockoffset = SDL_SwapLE32(pHdr->blockoffset);
pHdr->hashcount = SDL_SwapLE32(pHdr->hashcount);
pHdr->blockcount = SDL_SwapLE32(pHdr->blockcount);
return false;
}
BOOL ParseMPQHeader(_FILEHEADER *pHdr, DWORD *pdwNextFileStart)
{
DWORD size;
@ -369,6 +383,7 @@ BOOL ParseMPQHeader(_FILEHEADER *pHdr, DWORD *pdwNextFileStart)
if (size == -1
|| size < sizeof(*pHdr)
|| !ReadFile(sghArchive, pHdr, sizeof(*pHdr), &NumberOfBytesRead, NULL)
|| byteSwapHdr(pHdr)
|| NumberOfBytesRead != 104
|| pHdr->signature != '\x1AQPM'
|| pHdr->headersize != 32

66
Source/pack.cpp

@ -7,27 +7,27 @@ static void PackItem(PkItemStruct *id, ItemStruct *is)
if (is->_itype == -1) {
id->idx = 0xFFFF;
} else {
id->idx = is->IDidx;
id->idx = SwapLE16(is->IDidx);
if (is->IDidx == IDI_EAR) {
id->iCreateInfo = is->_iName[8] | (is->_iName[7] << 8);
id->iSeed = is->_iName[12] | ((is->_iName[11] | ((is->_iName[10] | (is->_iName[9] << 8)) << 8)) << 8);
id->iSeed = SwapLE32(is->_iName[12] | ((is->_iName[11] | ((is->_iName[10] | (is->_iName[9] << 8)) << 8)) << 8));
id->bId = is->_iName[13];
id->bDur = is->_iName[14];
id->bMDur = is->_iName[15];
id->bCh = is->_iName[16];
id->bMCh = is->_iName[17];
id->wValue = is->_ivalue | (is->_iName[18] << 8) | ((is->_iCurs - 19) << 6);
id->dwBuff = is->_iName[22] | ((is->_iName[21] | ((is->_iName[20] | (is->_iName[19] << 8)) << 8)) << 8);
id->wValue = SwapLE16(is->_ivalue | (is->_iName[18] << 8) | ((is->_iCurs - 19) << 6));
id->dwBuff = SwapLE32(is->_iName[22] | ((is->_iName[21] | ((is->_iName[20] | (is->_iName[19] << 8)) << 8)) << 8));
} else {
id->iSeed = is->_iSeed;
id->iCreateInfo = is->_iCreateInfo;
id->iSeed = SwapLE32(is->_iSeed);
id->iCreateInfo = SwapLE16(is->_iCreateInfo);
id->bId = is->_iIdentified + 2 * is->_iMagical;
id->bDur = is->_iDurability;
id->bMDur = is->_iMaxDur;
id->bCh = is->_iCharges;
id->bMCh = is->_iMaxCharges;
if (is->IDidx == IDI_GOLD)
id->wValue = is->_ivalue;
id->wValue = SwapLE16(is->_ivalue);
}
}
}
@ -57,13 +57,13 @@ void PackPlayer(PkPlayerStruct *pPack, int pnum, BOOL manashield)
pPack->pBaseVit = pPlayer->_pBaseVit;
pPack->pLevel = pPlayer->_pLevel;
pPack->pStatPts = pPlayer->_pStatPts;
pPack->pExperience = pPlayer->_pExperience;
pPack->pGold = pPlayer->_pGold;
pPack->pHPBase = pPlayer->_pHPBase;
pPack->pMaxHPBase = pPlayer->_pMaxHPBase;
pPack->pManaBase = pPlayer->_pManaBase;
pPack->pMaxManaBase = pPlayer->_pMaxManaBase;
pPack->pMemSpells = pPlayer->_pMemSpells;
pPack->pExperience = SwapLE32(pPlayer->_pExperience);
pPack->pGold = SwapLE32(pPlayer->_pGold);
pPack->pHPBase = SwapLE32(pPlayer->_pHPBase);
pPack->pMaxHPBase = SwapLE32(pPlayer->_pMaxHPBase);
pPack->pManaBase = SwapLE32(pPlayer->_pManaBase);
pPack->pMaxManaBase = SwapLE32(pPlayer->_pMaxManaBase);
pPack->pMemSpells = SDL_SwapLE64(pPlayer->_pMemSpells);
for (i = 0; i < MAX_SPELLS; i++)
pPack->pSplLvl[i] = pPlayer->_pSplLvl[i];
@ -99,10 +99,10 @@ void PackPlayer(PkPlayerStruct *pPack, int pnum, BOOL manashield)
pi++;
}
pPack->pDiabloKillLevel = pPlayer->pDiabloKillLevel;
pPack->pDiabloKillLevel = SwapLE32(pPlayer->pDiabloKillLevel);
if (gbMaxPlayers == 1 || manashield)
pPack->pManaShield = pPlayer->pManaShield;
pPack->pManaShield = SwapLE32(pPlayer->pManaShield);
else
pPack->pManaShield = FALSE;
}
@ -111,23 +111,25 @@ void PackPlayer(PkPlayerStruct *pPack, int pnum, BOOL manashield)
// find real name reference below, possibly [sizeof(item[])/sizeof(ItemStruct)]
static void UnPackItem(PkItemStruct *is, ItemStruct *id)
{
if (is->idx == 0xFFFF) {
WORD idx = SwapLE16(is->idx);
if (idx == 0xFFFF) {
id->_itype = -1;
} else {
if (is->idx == IDI_EAR) {
if (idx == IDI_EAR) {
RecreateEar(
MAXITEMS,
is->iCreateInfo,
is->iSeed,
SwapLE16(is->iCreateInfo),
SwapLE32(is->iSeed),
is->bId,
is->bDur,
is->bMDur,
is->bCh,
is->bMCh,
is->wValue,
is->dwBuff);
SwapLE16(is->wValue),
SwapLE32(is->dwBuff));
} else {
RecreateItem(MAXITEMS, is->idx, is->iCreateInfo, is->iSeed, is->wValue);
RecreateItem(MAXITEMS, idx, SwapLE16(is->iCreateInfo), SwapLE32(is->iSeed), SwapLE16(is->wValue));
item[MAXITEMS]._iMagical = is->bId >> 1;
item[MAXITEMS]._iIdentified = is->bId & 1;
item[MAXITEMS]._iDurability = is->bDur;
@ -188,17 +190,17 @@ void UnPackPlayer(PkPlayerStruct *pPack, int pnum, BOOL killok)
pPlayer->_pVitality = pPack->pBaseVit;
pPlayer->_pLevel = pPack->pLevel;
pPlayer->_pStatPts = pPack->pStatPts;
pPlayer->_pExperience = pPack->pExperience;
pPlayer->_pGold = pPack->pGold;
pPlayer->_pMaxHPBase = pPack->pMaxHPBase;
pPlayer->_pHPBase = pPack->pHPBase;
pPlayer->_pExperience = SwapLE32(pPack->pExperience);
pPlayer->_pGold = SwapLE32(pPack->pGold);
pPlayer->_pMaxHPBase = SwapLE32(pPack->pMaxHPBase);
pPlayer->_pHPBase = SwapLE32(pPack->pHPBase);
if (!killok)
if ((int)(pPlayer->_pHPBase & 0xFFFFFFC0) < 64)
pPlayer->_pHPBase = 64;
pPlayer->_pMaxManaBase = pPack->pMaxManaBase;
pPlayer->_pManaBase = pPack->pManaBase;
pPlayer->_pMemSpells = pPack->pMemSpells;
pPlayer->_pMaxManaBase = SwapLE32(pPack->pMaxManaBase);
pPlayer->_pManaBase = SwapLE32(pPack->pManaBase);
pPlayer->_pMemSpells = SDL_SwapLE64(pPack->pMemSpells);
for (i = 0; i < MAX_SPELLS; i++)
pPlayer->_pSplLvl[i] = pPack->pSplLvl[i];
@ -245,9 +247,9 @@ void UnPackPlayer(PkPlayerStruct *pPack, int pnum, BOOL killok)
pPlayer->pTownWarps = 0;
pPlayer->pDungMsgs = 0;
pPlayer->pLvlLoad = 0;
pPlayer->pDiabloKillLevel = pPack->pDiabloKillLevel;
pPlayer->pDiabloKillLevel = SwapLE32(pPack->pDiabloKillLevel);
pPlayer->pBattleNet = pPack->pBattleNet;
pPlayer->pManaShield = pPack->pManaShield;
pPlayer->pManaShield = SwapLE32(pPack->pManaShield);
}
DEVILUTION_END_NAMESPACE

5
Source/sha.cpp

@ -40,7 +40,7 @@ void SHA1Result(int n, char Message_Digest[SHA1HashSize])
Message_Digest_Block = (DWORD *)Message_Digest;
if (Message_Digest) {
for (i = 0; i < 5; i++) {
*Message_Digest_Block = sgSHA1[n].state[i];
*Message_Digest_Block = SwapLE32(sgSHA1[n].state[i]);
Message_Digest_Block++;
}
}
@ -79,7 +79,8 @@ void SHA1ProcessMessageBlock(SHA1Context *context)
DWORD *buf = (DWORD *)context->buffer;
for (i = 0; i < 16; i++)
W[i] = buf[i];
W[i] = SwapLE32(buf[i]);
for (i = 16; i < 80; i++) {
W[i] = W[i - 16] ^ W[i - 14] ^ W[i - 8] ^ W[i - 3];

Loading…
Cancel
Save