//========================================================================== // // RenameNerve // // Renames map headers and map name pictures in nerve.wad so as to load it // alongside Doom II and offer both episodes without causing conflicts. // MD5 checksum for NERVE.WAD: 967d5ae23daf45196212ae1b605da3b0 // //========================================================================== void FWadCollection::RenameNerve () { if (gameinfo.gametype != GAME_Doom) return; bool found = false; BYTE cksum[16]; static const BYTE nerve[16] = { 0x96, 0x7d, 0x5a, 0xe2, 0x3d, 0xaf, 0x45, 0x19, 0x62, 0x12, 0xae, 0x1b, 0x60, 0x5d, 0xa3, 0xb0 }; size_t nervesize = 3819855; // NERVE.WAD's file size int w = IWAD_FILENUM; while (++w < GetNumWads()) { FileReader *fr = GetFileReader(w); if (fr == NULL) { continue; } if (fr->GetLength() != (long)nervesize) { // Skip MD5 computation when there is a // cheaper way to know this is not the file continue; } fr->Seek(0, SEEK_SET); MD5Context md5; md5.Update(fr, fr->GetLength()); md5.Final(cksum); if (memcmp(nerve, cksum, 16) == 0) { found = true; break; } } if (!found) return; for (int i = GetFirstLump(w); i <= GetLastLump(w); i++) { // Only rename the maps from NERVE.WAD assert(LumpInfo[i].wadnum == w); if (LumpInfo[i].lump->dwName == MAKE_ID('C', 'W', 'I', 'L')) { LumpInfo[i].lump->Name[0] = 'N'; } else if (LumpInfo[i].lump->dwName == MAKE_ID('M', 'A', 'P', '0')) { LumpInfo[i].lump->Name[6] = LumpInfo[i].lump->Name[4]; LumpInfo[i].lump->Name[5] = '0'; LumpInfo[i].lump->Name[4] = 'L'; LumpInfo[i].lump->dwName = MAKE_ID('L', 'E', 'V', 'E'); } } }
void FWadCollection::FixMacHexen() { if (GAME_Hexen != gameinfo.gametype) { return; } FileReader* const reader = GetFileReader(IWAD_FILENUM); const long iwadSize = reader->GetLength(); static const long DEMO_SIZE = 13596228; static const long FULL_SIZE = 21078584; if ( DEMO_SIZE != iwadSize && FULL_SIZE != iwadSize) { return; } reader->Seek(0, SEEK_SET); BYTE checksum[16]; MD5Context md5; md5.Update(reader, iwadSize); md5.Final(checksum); static const BYTE HEXEN_DEMO_MD5[16] = { 0x92, 0x5f, 0x9f, 0x50, 0x00, 0xe1, 0x7d, 0xc8, 0x4b, 0x0a, 0x6a, 0x3b, 0xed, 0x3a, 0x6f, 0x31 }; static const BYTE HEXEN_FULL_MD5[16] = { 0xb6, 0x81, 0x40, 0xa7, 0x96, 0xf6, 0xfd, 0x7f, 0x3a, 0x5d, 0x32, 0x26, 0xa3, 0x2b, 0x93, 0xbe }; if ( 0 != memcmp(HEXEN_DEMO_MD5, checksum, sizeof checksum) && 0 != memcmp(HEXEN_FULL_MD5, checksum, sizeof checksum)) { return; } static const int EXTRA_LUMPS = 299; const int lastLump = GetLastLump(IWAD_FILENUM); assert(GetFirstLump(IWAD_FILENUM) + 299 < lastLump); for (int i = lastLump - EXTRA_LUMPS + 1; i <= lastLump; ++i) { LumpInfo[i].lump->Name[0] = '\0'; } }
void FWadCollection::FixMacHexen() { if (GAME_Hexen != gameinfo.gametype) { return; } FileReader* const reader = GetFileReader(GetIwadNum()); const long iwadSize = reader->GetLength(); static const long DEMO_SIZE = 13596228; static const long BETA_SIZE = 13749984; static const long FULL_SIZE = 21078584; if ( DEMO_SIZE != iwadSize && BETA_SIZE != iwadSize && FULL_SIZE != iwadSize) { return; } reader->Seek(0, SEEK_SET); uint8_t checksum[16]; MD5Context md5; md5.Update(reader, iwadSize); md5.Final(checksum); static const uint8_t HEXEN_DEMO_MD5[16] = { 0x92, 0x5f, 0x9f, 0x50, 0x00, 0xe1, 0x7d, 0xc8, 0x4b, 0x0a, 0x6a, 0x3b, 0xed, 0x3a, 0x6f, 0x31 }; static const uint8_t HEXEN_BETA_MD5[16] = { 0x2a, 0xf1, 0xb2, 0x7c, 0xd1, 0x1f, 0xb1, 0x59, 0xe6, 0x08, 0x47, 0x2a, 0x1b, 0x53, 0xe4, 0x0e }; static const uint8_t HEXEN_FULL_MD5[16] = { 0xb6, 0x81, 0x40, 0xa7, 0x96, 0xf6, 0xfd, 0x7f, 0x3a, 0x5d, 0x32, 0x26, 0xa3, 0x2b, 0x93, 0xbe }; const bool isBeta = 0 == memcmp(HEXEN_BETA_MD5, checksum, sizeof checksum); if ( !isBeta && 0 != memcmp(HEXEN_DEMO_MD5, checksum, sizeof checksum) && 0 != memcmp(HEXEN_FULL_MD5, checksum, sizeof checksum)) { return; } static const int EXTRA_LUMPS = 299; // Hexen Beta is very similar to Demo but it has MAP41: Maze at the end of the WAD // So keep this map if it's present but discard all extra lumps const int lastLump = GetLastLump(GetIwadNum()) - (isBeta ? 12 : 0); assert(GetFirstLump(GetIwadNum()) + 299 < lastLump); for (int i = lastLump - EXTRA_LUMPS + 1; i <= lastLump; ++i) { LumpInfo[i].lump->Name[0] = '\0'; } }