From 4321c59d8431eaf72d7b36c047859b72bca02318 Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Thu, 12 May 2022 15:44:15 +0200 Subject: Added implementation of Srarctaft I BETA ADPCM decompression --- src/SCompression.cpp | 56 ++++++++++++--- src/SFileOpenArchive.cpp | 19 ++++- src/SFileReadFile.cpp | 9 ++- src/StormCommon.h | 1 + src/StormLib.h | 16 +++-- src/adpcm/adpcm.cpp | 184 +++++++++++++++++++++++++++++++++++++++++------ src/adpcm/adpcm.h | 5 +- 7 files changed, 246 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/SCompression.cpp b/src/SCompression.cpp index 1d0f679..54c84b4 100644 --- a/src/SCompression.cpp +++ b/src/SCompression.cpp @@ -647,6 +647,24 @@ static int Decompress_ADPCM_stereo(void * pvOutBuffer, int * pcbOutBuffer, void return 1; } +/******************************************************************************/ +/* */ +/* Support for ADPCM mono & stereo (Starcraft I BETA - like) */ +/* */ +/******************************************************************************/ + +static int Decompress_ADPCM1_sc1b(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + *pcbOutBuffer = DecompressADPCM_SC1B(pvOutBuffer, *pcbOutBuffer, pvInBuffer, cbInBuffer, 1); + return 1; +} + +static int Decompress_ADPCM2_sc1b(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + *pcbOutBuffer = DecompressADPCM_SC1B(pvOutBuffer, *pcbOutBuffer, pvInBuffer, cbInBuffer, 2); + return 1; +} + /*****************************************************************************/ /* */ /* SCompImplode */ @@ -784,7 +802,7 @@ int WINAPI SCompCompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuff else { // Fill the compressions array - for(size_t i = 0; i < (sizeof(cmp_table) / sizeof(TCompressTable)); i++) + for(size_t i = 0; i < _countof(cmp_table); i++) { // If the mask agrees, insert the compression function to the array if(uCompressionMask & cmp_table[i].uMask) @@ -891,7 +909,17 @@ static TDecompressTable dcmp_table[] = {MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression }; -int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +// Decompression table specific for Starcraft I BETA +// WAVE files are compressed by different ADPCM compression +static TDecompressTable dcmp_table_sc1b[] = +{ + {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library + {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression + {0x10, Decompress_ADPCM1_sc1b}, // IMA ADPCM mono decompression + {0x20, Decompress_ADPCM2_sc1b}, // IMA ADPCM stereo decompression +}; + +static int SCompDecompressInternal(TDecompressTable * table, size_t table_length, void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) { unsigned char * pbWorkBuffer = NULL; unsigned char * pbOutBuffer = (unsigned char *)pvOutBuffer; @@ -920,7 +948,7 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu } // Get applied compression types and decrement data length - uCompressionMask = uCompressionCopy = (unsigned char)*pbInBuffer++; + uCompressionMask = uCompressionCopy = (unsigned char)(*pbInBuffer++); cbInBuffer--; // Get current compressed data and length of it @@ -931,12 +959,12 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu assert(uCompressionMask != MPQ_COMPRESSION_LZMA); // Parse the compression mask - for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++) + for(size_t i = 0; i < table_length; i++) { // If the mask agrees, insert the compression function to the array - if(uCompressionMask & dcmp_table[i].uMask) + if(uCompressionMask & table[i].uMask) { - uCompressionCopy &= ~dcmp_table[i].uMask; + uCompressionCopy &= ~table[i].uMask; nCompressCount++; } } @@ -963,10 +991,10 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu nCompressIndex = nCompressCount - 1; // Apply all decompressions - for(size_t i = 0; i < (sizeof(dcmp_table) / sizeof(TDecompressTable)); i++) + for(size_t i = 0; i < table_length; i++) { // Perform the (next) decompression - if(uCompressionMask & dcmp_table[i].uMask) + if(uCompressionMask & table[i].uMask) { // Get the correct output buffer pbOutput = (nCompressIndex & 1) ? pbWorkBuffer : pbOutBuffer; @@ -974,7 +1002,7 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu // Perform the decompression cbOutBuffer = *pcbOutBuffer; - nResult = dcmp_table[i].Decompress(pbOutput, &cbOutBuffer, pbInput, cbInLength); + nResult = table[i].Decompress(pbOutput, &cbOutBuffer, pbInput, cbInLength); if(nResult == 0 || cbOutBuffer == 0) { SetLastError(ERROR_FILE_CORRUPT); @@ -997,6 +1025,16 @@ int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBu return nResult; } +int WINAPI SCompDecompress(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + return SCompDecompressInternal(dcmp_table, _countof(dcmp_table), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); +} + +int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) +{ + return SCompDecompressInternal(dcmp_table_sc1b, _countof(dcmp_table_sc1b), pvOutBuffer, pcbOutBuffer, pvInBuffer, cbInBuffer); +} + int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer) { DECOMPRESS pfnDecompress1 = NULL; diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp index 52e1a39..8c3cc13 100644 --- a/src/SFileOpenArchive.cpp +++ b/src/SFileOpenArchive.cpp @@ -22,7 +22,7 @@ //----------------------------------------------------------------------------- // Local functions -static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer) +static MTYPE CheckMapType(ULONGLONG FileSize, LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer) { LPDWORD HeaderInt32 = (LPDWORD)pbHeaderBuffer; LPCTSTR szExtension; @@ -35,6 +35,15 @@ static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHe DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderInt32[2]); DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderInt32[3]); + // Check possible MPQs from Starcraft I BETA. We recognize them by checking the file size. + // 167 859: patch_rt.mpq (doesn't contain any WAVE files) + // 55 674 173: StarDat.mpq + // 183 519 584: Install.exe + if(FileSize == 55674173 && DwordValue1 == MPQ_HEADER_SIZE_V1 && DwordValue3 == 0x00030000) + return MapTypeStarcraftBeta; + if(FileSize == 183519584 && DwordValue0 == 0x00905a4D && DwordValue1 == 3 && DwordValue2 == 4) + return MapTypeStarcraftBeta; + // Check maps by extension (Starcraft, Starcraft II). We must do this before // checking actual data, because the "NP_Protect" protector places // fake Warcraft III header into the Starcraft II maps @@ -321,7 +330,7 @@ bool WINAPI SFileOpenArchive( if(MapType == MapTypeNotChecked) { // Do nothing if the file is an AVI file - if((MapType = CheckMapType(szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile) + if((MapType = CheckMapType(FileSize, szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile) { dwErrCode = ERROR_AVI_FILE; break; @@ -446,6 +455,12 @@ bool WINAPI SFileOpenArchive( if(dwFlags & MPQ_OPEN_FORCE_LISTFILE) ha->dwFlags |= MPQ_FLAG_LISTFILE_FORCE; + // StarDat.mpq from Starcraft I BETA: Enable special compression types + if(MapType == MapTypeStarcraftBeta) + { + ha->dwFlags |= MPQ_FLAG_STARCRAFT_BETA; + } + // Remember whether whis is a map for Warcraft III if(MapType == MapTypeWarcraft3) { diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 6ec04f3..8031ba7 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -173,9 +173,16 @@ static DWORD ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, // Decompress the data if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) + { nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector); + } else - nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); + { + if(ha->dwFlags & MPQ_FLAG_STARCRAFT_BETA) + nResult = SCompDecompress_SC1B(pbOutSector, &cbOutSector, pbInSector, cbInSector); + else + nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); + } } // Is the file compressed by PKWARE Data Compression Library ? diff --git a/src/StormCommon.h b/src/StormCommon.h index 865d975..d1d7abe 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -80,6 +80,7 @@ typedef enum _MTYPE { MapTypeNotChecked, // The map type was not checked yet MapTypeNotRecognized, // The file does not seems to be a map + MapTypeStarcraftBeta, // The file is StarDat.mpq from Starcraft I BETA MapTypeAviFile, // The file is actually an AVI file (Warcraft III cinematics) MapTypeStarcraft, // The file is a Starcraft map MapTypeWarcraft3, // The file is a Warcraft III map diff --git a/src/StormLib.h b/src/StormLib.h index 048281d..1c4e199 100644 --- a/src/StormLib.h +++ b/src/StormLib.h @@ -192,13 +192,14 @@ extern "C" { #define MPQ_FLAG_SAVING_TABLES 0x00000040 // If set, we are saving MPQ internal files and MPQ tables #define MPQ_FLAG_PATCH 0x00000080 // If set, this MPQ is a patch archive #define MPQ_FLAG_WAR3_MAP 0x00000100 // If set, this MPQ is a Warcraft III map -#define MPQ_FLAG_LISTFILE_NONE 0x00000200 // Set when no (listfile) was found in InvalidateInternalFiles -#define MPQ_FLAG_LISTFILE_NEW 0x00000400 // Set when (listfile) invalidated by InvalidateInternalFiles -#define MPQ_FLAG_LISTFILE_FORCE 0x00000800 // Save updated listfile on exit -#define MPQ_FLAG_ATTRIBUTES_NONE 0x00001000 // Set when no (attributes) was found in InvalidateInternalFiles -#define MPQ_FLAG_ATTRIBUTES_NEW 0x00002000 // Set when (attributes) invalidated by InvalidateInternalFiles -#define MPQ_FLAG_SIGNATURE_NONE 0x00004000 // Set when no (signature) was found in InvalidateInternalFiles -#define MPQ_FLAG_SIGNATURE_NEW 0x00008000 // Set when (signature) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_STARCRAFT_BETA 0x00000200 // If set, this MPQ is StarDat.mpq from Starcraft I BETA +#define MPQ_FLAG_LISTFILE_NONE 0x00000400 // Set when no (listfile) was found in InvalidateInternalFiles +#define MPQ_FLAG_LISTFILE_NEW 0x00000800 // Set when (listfile) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_LISTFILE_FORCE 0x00001000 // Save updated listfile on exit +#define MPQ_FLAG_ATTRIBUTES_NONE 0x00002000 // Set when no (attributes) was found in InvalidateInternalFiles +#define MPQ_FLAG_ATTRIBUTES_NEW 0x00004000 // Set when (attributes) invalidated by InvalidateInternalFiles +#define MPQ_FLAG_SIGNATURE_NONE 0x00008000 // Set when no (signature) was found in InvalidateInternalFiles +#define MPQ_FLAG_SIGNATURE_NEW 0x00010000 // Set when (signature) invalidated by InvalidateInternalFiles // Values for TMPQArchive::dwSubType #define MPQ_SUBTYPE_MPQ 0x00000000 // The file is a MPQ file (Blizzard games) @@ -1111,6 +1112,7 @@ int WINAPI SCompExplode (void * pvOutBuffer, int * pcbOutBuffer, void * pv int WINAPI SCompCompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer, unsigned uCompressionMask, int nCmpType, int nCmpLevel); int WINAPI SCompDecompress (void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); int WINAPI SCompDecompress2(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); +int WINAPI SCompDecompress_SC1B(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); //----------------------------------------------------------------------------- // Non-Windows support for SetLastError/GetLastError diff --git a/src/adpcm/adpcm.cpp b/src/adpcm/adpcm.cpp index fb0efbf..60e6738 100644 --- a/src/adpcm/adpcm.cpp +++ b/src/adpcm/adpcm.cpp @@ -13,6 +13,7 @@ /* 10.01.13 3.00 Lad Refactored, beautified, documented :-) */ /*****************************************************************************/ +#include #include #include "adpcm.h" @@ -20,7 +21,7 @@ //----------------------------------------------------------------------------- // Tables necessary dor decompression -static int NextStepTable[] = +static const int NextStepTable[] = { -1, 0, -1, 4, -1, 2, -1, 6, -1, 1, -1, 5, -1, 3, -1, 7, @@ -28,7 +29,7 @@ static int NextStepTable[] = -1, 2, -1, 4, -1, 6, -1, 8 }; -static int StepSizeTable[] = +static const int StepSizeTable[] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, @@ -127,10 +128,10 @@ static inline short GetNextStepIndex(int StepIndex, unsigned int EncodedSample) return (short)StepIndex; } -static inline int UpdatePredictedSample(int PredictedSample, int EncodedSample, int Difference) +static inline int UpdatePredictedSample(int PredictedSample, int EncodedSample, int Difference, int BitMask = 0x40) { // Is the sign bit set? - if(EncodedSample & 0x40) + if(EncodedSample & BitMask) { PredictedSample -= Difference; if(PredictedSample <= -32768) @@ -187,8 +188,6 @@ int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cb int MaxBitMask; int StepSize; -// _tprintf(_T("== CMPR Started ==============\n")); - // First byte in the output stream contains zero. The second one contains the compression level os.WriteByteSample(0); if(!os.WriteByteSample(BitShift)) @@ -290,7 +289,6 @@ int CompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cb } } -// _tprintf(_T("== CMPR Ended ================\n")); return os.LengthProcessed(pvOutBuffer); } @@ -311,12 +309,9 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int PredictedSamples[0] = PredictedSamples[1] = 0; StepIndexes[0] = StepIndexes[1] = INITIAL_ADPCM_STEP_INDEX; -// _tprintf(_T("== DCMP Started ==============\n")); - // The first byte is always zero, the second one contains bit shift (compression level - 1) is.ReadByteSample(BitShift); is.ReadByteSample(BitShift); -// _tprintf(_T("DCMP: BitShift = %u\n"), (unsigned int)(unsigned char)BitShift); // Next, InitialSample value for each channel follows for(int i = 0; i < ChannelCount; i++) @@ -328,8 +323,6 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int if(!is.ReadWordSample(InitialSample)) return os.LengthProcessed(pvOutBuffer); -// _tprintf(_T("DCMP: Loaded InitialSample[%u]: %04X\n"), i, (unsigned int)(unsigned short)InitialSample); - // Store the initial sample to our sample array PredictedSamples[i] = InitialSample; @@ -344,8 +337,6 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int // Keep reading as long as there is something in the input buffer while(is.ReadByteSample(EncodedSample)) { -// _tprintf(_T("DCMP: Loaded Encoded Sample: %02X\n"), (unsigned int)(unsigned char)EncodedSample); - // If we have two channels, we need to flip the channel index ChannelIndex = (ChannelIndex + 1) % ChannelCount; @@ -354,7 +345,6 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int if(StepIndexes[ChannelIndex] != 0) StepIndexes[ChannelIndex]--; -// _tprintf(_T("DCMP: Writing Decoded Sample: %04lX\n"), (unsigned int)(unsigned short)PredictedSamples[ChannelIndex]); if(!os.WriteWordSample(PredictedSamples[ChannelIndex])) return os.LengthProcessed(pvOutBuffer); } @@ -365,8 +355,6 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int if(StepIndexes[ChannelIndex] > 0x58) StepIndexes[ChannelIndex] = 0x58; -// _tprintf(_T("DCMP: New value of StepIndex: %04lX\n"), (unsigned int)(unsigned short)StepIndexes[ChannelIndex]); - // Next pass, keep going on the same channel ChannelIndex = (ChannelIndex + 1) % ChannelCount; } @@ -381,21 +369,171 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int StepSize, StepSize >> BitShift); -// _tprintf(_T("DCMP: Writing decoded sample: %04X\n"), (unsigned int)(unsigned short)PredictedSamples[ChannelIndex]); - // Write the decoded sample to the output stream if(!os.WriteWordSample(PredictedSamples[ChannelIndex])) break; // Calculates the step index to use for the next encode StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndex, EncodedSample); -// _tprintf(_T("DCMP: New step index: %04X\n"), (unsigned int)(unsigned short)StepIndexes[ChannelIndex]); } } -// _tprintf(_T("DCMP: Total length written: %u\n"), (unsigned int)os.LengthProcessed(pvOutBuffer)); -// _tprintf(_T("== DCMP Ended ================\n")); - // Return total bytes written since beginning of the output buffer return os.LengthProcessed(pvOutBuffer); } + +//----------------------------------------------------------------------------- +// ADPCM decompression present in Starcraft I BETA + +typedef struct _ADPCM_DATA +{ + unsigned int * pValues; + int BitCount; + int field_8; + int field_C; + int field_10; + +} ADPCM_DATA, *PADPCM_DATA; + +static const unsigned int adpcm_values_2[] = {0x33, 0x66}; +static const unsigned int adpcm_values_3[] = {0x3A, 0x3A, 0x50, 0x70}; +static const unsigned int adpcm_values_4[] = {0x3A, 0x3A, 0x3A, 0x3A, 0x4D, 0x66, 0x80, 0x9A}; +static const unsigned int adpcm_values_6[] = +{ + 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, + 0x46, 0x53, 0x60, 0x6D, 0x7A, 0x86, 0x93, 0xA0, 0xAD, 0xBA, 0xC6, 0xD3, 0xE0, 0xED, 0xFA, 0x106 +}; + +static unsigned int * InitAdpcmData(PADPCM_DATA pData, unsigned char BitCount) +{ + switch(BitCount) + { + case 2: + pData->pValues = adpcm_values_2; + break; + + case 3: + pData->pValues = adpcm_values_3; + break; + + case 4: + pData->pValues = adpcm_values_4; + break; + + default: + pData->pValues = NULL; + break; + + case 6: + pData->pValues = adpcm_values_6; + break; + } + + pData->BitCount = BitCount; + pData->field_C = 0x20000; + pData->field_8 = 1 << BitCount; + pData->field_10 = (1 << BitCount) / 2; + return pData->pValues; +} + +int DecompressADPCM_SC1B(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cbInBuffer, int ChannelCount) +{ + TADPCMStream os(pvOutBuffer, cbOutBuffer); // Output stream + TADPCMStream is(pvInBuffer, cbInBuffer); // Input stream + ADPCM_DATA AdpcmData; + int LowBitValues[MAX_ADPCM_CHANNEL_COUNT]; + int UpperBits[MAX_ADPCM_CHANNEL_COUNT]; + int BitMasks[MAX_ADPCM_CHANNEL_COUNT]; + int PredictedSamples[MAX_ADPCM_CHANNEL_COUNT]; + int ChannelIndex; + int ChannelIndexMax; + int OutputSample; + unsigned char BitCount; + unsigned char EncodedSample; + short InputValue16; + int reg_eax; + int Difference; + + // The first byte contains number of bits + if(!is.ReadByteSample(BitCount)) + return os.LengthProcessed(pvOutBuffer); + if(!InitAdpcmData(&AdpcmData, BitCount)) + return os.LengthProcessed(pvOutBuffer); + assert(AdpcmData.pValues != NULL); + + // Init bit values + for(int i = 0; i < ChannelCount; i++) + { + unsigned char OneByte; + + if(!is.ReadByteSample(OneByte)) + return os.LengthProcessed(pvOutBuffer); + LowBitValues[i] = OneByte & 0x01; + UpperBits[i] = OneByte >> 1; + } + + // + for(int i = 0; i < ChannelCount; i++) + { + if(!is.ReadWordSample(InputValue16)) + return os.LengthProcessed(pvOutBuffer); + BitMasks[i] = InputValue16 << AdpcmData.BitCount; + } + + // Next, InitialSample value for each channel follows + for(int i = 0; i < ChannelCount; i++) + { + if(!is.ReadWordSample(InputValue16)) + return os.LengthProcessed(pvOutBuffer); + + PredictedSamples[i] = InputValue16; + os.WriteWordSample(InputValue16); + } + + // Get the initial index + ChannelIndexMax = ChannelCount - 1; + ChannelIndex = 0; + + // Keep reading as long as there is something in the input buffer + while(is.ReadByteSample(EncodedSample)) + { + reg_eax = ((PredictedSamples[ChannelIndex] * 3) << 3) - PredictedSamples[ChannelIndex]; + PredictedSamples[ChannelIndex] = ((reg_eax * 10) + 0x80) >> 8; + + Difference = (((EncodedSample >> 1) + 1) * BitMasks[ChannelIndex] + AdpcmData.field_10) >> AdpcmData.BitCount; + + PredictedSamples[ChannelIndex] = UpdatePredictedSample(PredictedSamples[ChannelIndex], EncodedSample, Difference, 0x01); + + BitMasks[ChannelIndex] = (AdpcmData.pValues[EncodedSample >> 1] * BitMasks[ChannelIndex] + 0x80) >> 6; + if(BitMasks[ChannelIndex] < AdpcmData.field_8) + BitMasks[ChannelIndex] = AdpcmData.field_8; + + if(BitMasks[ChannelIndex] > AdpcmData.field_C) + BitMasks[ChannelIndex] = AdpcmData.field_C; + + reg_eax = (cbInBuffer - is.LengthProcessed(pvInBuffer)) >> ChannelIndexMax; + OutputSample = PredictedSamples[ChannelIndex]; + if(reg_eax < UpperBits[ChannelIndex]) + { + if(LowBitValues[ChannelIndex]) + { + OutputSample += (UpperBits[ChannelIndex] - reg_eax); + if(OutputSample > 32767) + OutputSample = 32767; + } + else + { + OutputSample += (reg_eax - UpperBits[ChannelIndex]); + if(OutputSample < -32768) + OutputSample = -32768; + } + } + + // Write the word sample and swap channel + os.WriteWordSample((short)(OutputSample)); + ChannelIndex = (ChannelIndex + 1) % ChannelCount; + } + + return os.LengthProcessed(pvOutBuffer); +} + diff --git a/src/adpcm/adpcm.h b/src/adpcm/adpcm.h index b1bf361..22a8095 100644 --- a/src/adpcm/adpcm.h +++ b/src/adpcm/adpcm.h @@ -20,7 +20,8 @@ //----------------------------------------------------------------------------- // Public functions -int CompressADPCM (void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int nCmpType, int ChannelCount); -int DecompressADPCM(void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int ChannelCount); +int CompressADPCM (void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int nCmpType, int ChannelCount); +int DecompressADPCM (void * pvOutBuffer, int dwOutLength, void * pvInBuffer, int dwInLength, int ChannelCount); +int DecompressADPCM_SC1B(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int cbInBuffer, int ChannelCount); #endif // __ADPCM_H__ -- cgit v1.2.3 From 07f9be39a62b93fa3af07c2fc02dcd25edd2c00b Mon Sep 17 00:00:00 2001 From: Ladislav Zezula Date: Sun, 15 May 2022 20:13:36 +0200 Subject: Code refined --- src/SFileOpenArchive.cpp | 31 +++++---- src/StormCommon.h | 1 - src/adpcm/adpcm.cpp | 4 +- test/StormTest.cpp | 5 +- test/stormlib-test.txt | 175 +++++++++++++++++++++++++---------------------- 5 files changed, 118 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/SFileOpenArchive.cpp b/src/SFileOpenArchive.cpp index 8c3cc13..b85f24c 100644 --- a/src/SFileOpenArchive.cpp +++ b/src/SFileOpenArchive.cpp @@ -22,7 +22,7 @@ //----------------------------------------------------------------------------- // Local functions -static MTYPE CheckMapType(ULONGLONG FileSize, LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer) +static MTYPE CheckMapType(LPCTSTR szFileName, LPBYTE pbHeaderBuffer, size_t cbHeaderBuffer) { LPDWORD HeaderInt32 = (LPDWORD)pbHeaderBuffer; LPCTSTR szExtension; @@ -35,15 +35,6 @@ static MTYPE CheckMapType(ULONGLONG FileSize, LPCTSTR szFileName, LPBYTE pbHeade DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderInt32[2]); DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderInt32[3]); - // Check possible MPQs from Starcraft I BETA. We recognize them by checking the file size. - // 167 859: patch_rt.mpq (doesn't contain any WAVE files) - // 55 674 173: StarDat.mpq - // 183 519 584: Install.exe - if(FileSize == 55674173 && DwordValue1 == MPQ_HEADER_SIZE_V1 && DwordValue3 == 0x00030000) - return MapTypeStarcraftBeta; - if(FileSize == 183519584 && DwordValue0 == 0x00905a4D && DwordValue1 == 3 && DwordValue2 == 4) - return MapTypeStarcraftBeta; - // Check maps by extension (Starcraft, Starcraft II). We must do this before // checking actual data, because the "NP_Protect" protector places // fake Warcraft III header into the Starcraft II maps @@ -84,6 +75,20 @@ static MTYPE CheckMapType(ULONGLONG FileSize, LPCTSTR szFileName, LPBYTE pbHeade return MapTypeNotRecognized; } +static bool IsStarcraftBetaArchive(TMPQHeader * pHeader) +{ + // The archive must be version 1, with a standard header size + if(pHeader->dwID == ID_MPQ && pHeader->dwHeaderSize == MPQ_HEADER_SIZE_V1) + { + // Check for known archive sizes + return (pHeader->dwArchiveSize == 0x00028FB3 || // patch_rt.mpq + pHeader->dwArchiveSize == 0x0351853D || // StarDat.mpq + pHeader->dwArchiveSize == 0x0AEC8960); // INSTALL.exe + + } + return false; +} + static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData) { TMPQUserData * pUserData; @@ -330,7 +335,7 @@ bool WINAPI SFileOpenArchive( if(MapType == MapTypeNotChecked) { // Do nothing if the file is an AVI file - if((MapType = CheckMapType(FileSize, szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile) + if((MapType = CheckMapType(szMpqName, pbHeaderBuffer, dwBytesAvailable)) == MapTypeAviFile) { dwErrCode = ERROR_AVI_FILE; break; @@ -456,10 +461,8 @@ bool WINAPI SFileOpenArchive( ha->dwFlags |= MPQ_FLAG_LISTFILE_FORCE; // StarDat.mpq from Starcraft I BETA: Enable special compression types - if(MapType == MapTypeStarcraftBeta) - { + if(IsStarcraftBetaArchive(ha->pHeader)) ha->dwFlags |= MPQ_FLAG_STARCRAFT_BETA; - } // Remember whether whis is a map for Warcraft III if(MapType == MapTypeWarcraft3) diff --git a/src/StormCommon.h b/src/StormCommon.h index d1d7abe..865d975 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -80,7 +80,6 @@ typedef enum _MTYPE { MapTypeNotChecked, // The map type was not checked yet MapTypeNotRecognized, // The file does not seems to be a map - MapTypeStarcraftBeta, // The file is StarDat.mpq from Starcraft I BETA MapTypeAviFile, // The file is actually an AVI file (Warcraft III cinematics) MapTypeStarcraft, // The file is a Starcraft map MapTypeWarcraft3, // The file is a Warcraft III map diff --git a/src/adpcm/adpcm.cpp b/src/adpcm/adpcm.cpp index 60e6738..1725008 100644 --- a/src/adpcm/adpcm.cpp +++ b/src/adpcm/adpcm.cpp @@ -387,7 +387,7 @@ int DecompressADPCM(void * pvOutBuffer, int cbOutBuffer, void * pvInBuffer, int typedef struct _ADPCM_DATA { - unsigned int * pValues; + const unsigned int * pValues; int BitCount; int field_8; int field_C; @@ -404,7 +404,7 @@ static const unsigned int adpcm_values_6[] = 0x46, 0x53, 0x60, 0x6D, 0x7A, 0x86, 0x93, 0xA0, 0xAD, 0xBA, 0xC6, 0xD3, 0xE0, 0xED, 0xFA, 0x106 }; -static unsigned int * InitAdpcmData(PADPCM_DATA pData, unsigned char BitCount) +static const unsigned int * InitAdpcmData(PADPCM_DATA pData, unsigned char BitCount) { switch(BitCount) { diff --git a/test/StormTest.cpp b/test/StormTest.cpp index 2e7389b..f8b8f7d 100644 --- a/test/StormTest.cpp +++ b/test/StormTest.cpp @@ -4255,6 +4255,9 @@ static const TEST_INFO Test_Mpqs[] = { // Correct or damaged archives {_T("MPQ_1997_v1_Diablo1_DIABDAT.MPQ"), NULL, 0, "music\\dintro.wav", "File00000023.xxx"}, + {_T("MPQ_1997_v1_patch_rt_SC1B.mpq"), NULL, TEST_DATA("43fe7d362955be68a708486e399576a7", 10)}, // From Starcraft 1 BETA + {_T("MPQ_1997_v1_StarDat_SC1B.mpq"), NULL, TEST_DATA("0094b23f28cfff7386071ef3bd19a577", 2468)}, // From Starcraft 1 BETA + {_T("MPQ_1997_v1_INSTALL_SC1B.EXE_"), NULL, TEST_DATA("3248460c89bb6f8e3b8fc3e08de7ffbb", 79)}, // From Starcraft 1 BETA {_T("MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq"), NULL, TEST_DATA("255d87a62f3c9518f72cf723a1818946", 221), "waitingroombkgd.dc6"}, // Update MPQ from Diablo II (patch 2016) {_T("MPQ_2018_v1_icon_error.w3m"), NULL, TEST_DATA("fcefa25fb50c391e8714f2562d1e10ff", 19), "file00000002.blp"}, {_T("MPQ_1997_v1_Diablo1_STANDARD.SNP"), Bliz, TEST_DATA("5ef18ef9a26b5704d8d46a344d976c89", 2)}, // File whose archive's (signature) file has flags = 0x90000000 @@ -4343,7 +4346,7 @@ int _tmain(int argc, TCHAR * argv[]) for(int i = 2; i < argc; i++) { // TestArchive(argv[i], Bliz, 0, "sound\\zerg\\advisor\\zaderr05.wav", NULL); - TestArchive(argv[i], Bliz, 0, "music\\trdyroom.wav", NULL); +// TestArchive(argv[i], Bliz, 0, "music\\trdyroom.wav", NULL); } // diff --git a/test/stormlib-test.txt b/test/stormlib-test.txt index 34917cc..4a1bd2c 100644 --- a/test/stormlib-test.txt +++ b/test/stormlib-test.txt @@ -1,11 +1,92 @@ -Microsoft Windows [Version 10.0.19044.1415] +Microsoft Windows [Version 10.0.19044.1706] (c) Microsoft Corporation. All rights reserved. -E:\Ladik\Appdir\StormLib>StormLib_test.exe +E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release>StormLib_test.exe ==== Test Suite for StormLib version 9.23 ==== InitWorkDir: Work directory \Multimedia\MPQs (default) LocalListFile (FLAT-MAP:ListFile_Blizzard.txt) succeeded. LocalListFile (ListFile_Blizzard.txt) succeeded. +FileStreamTest (MPQ_2013_v4_alternate-original.MPQ) succeeded. +FileStreamTest (MPQ_2013_v4_alternate-original.MPQ) succeeded. +FileStreamTest (MPQ_2013_v4_alternate-complete.MPQ) succeeded. +FileStreamTest (part-file://MPQ_2009_v2_WoW_patch.MPQ.part) succeeded. +FileStreamTest (blk4-file://streaming/model.MPQ.0) succeeded. +FileStreamTest (mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE) succeeded. +OpenMirrorFile (part-file://MPQ_2009_v1_patch-created.MPQ.part) succeeded. +OpenMirrorFile (part-file://MPQ_2009_v1_patch-partial.MPQ.part) succeeded. +OpenMirrorFile (part-file://MPQ_2009_v1_patch-complete.MPQ.part) succeeded. +OpenMirrorFile (MPQ_2013_v4_alternate-created.MPQ) succeeded. +OpenMirrorFile (MPQ_2013_v4_alternate-incomplete.MPQ) succeeded. +OpenMirrorFile (MPQ_2013_v4_alternate-complete.MPQ) succeeded. +TestMpq (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded. +TestMpq (MPQ_1997_v1_patch_rt_SC1B.mpq) succeeded. +TestMpq (MPQ_1997_v1_StarDat_SC1B.mpq) succeeded. +TestMpq (MPQ_1997_v1_INSTALL_SC1B.EXE_) succeeded. +TestMpq (MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq) succeeded. +TestMpq (MPQ_2018_v1_icon_error.w3m) succeeded. +TestMpq (MPQ_1997_v1_Diablo1_STANDARD.SNP) succeeded. +TestMpq (MPQ_2012_v2_EmptyMpq.MPQ) succeeded. +TestMpq (MPQ_2013_v4_EmptyMpq.MPQ) succeeded. +TestMpq (MPQ_2013_v4_patch-base-16357.MPQ) succeeded. +TestMpq (MPQ_2011_v4_InvalidHetEntryCount.MPQ) succeeded. +TestMpq (MPQ_2002_v1_BlockTableCut.MPQ) succeeded. +TestMpq (MPQ_2010_v2_HasUserData.s2ma) succeeded. +TestMpq (MPQ_2014_v1_AttributesOneEntryLess.w3x) succeeded. +TestMpq (MPQ_2020_v1_AHF04patch.mix) succeeded. +TestMpq (MPQ_2010_v3_expansion-locale-frFR.MPQ) succeeded. +TestMpq (mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE) succeeded. +TestMpq (MPx_2013_v1_LongwuOnline.mpk) succeeded. +TestMpq (MPx_2013_v1_WarOfTheImmortals.sqp) succeeded. +TestMpq (part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part) succeeded. +TestMpq (blk4-file://streaming/model.MPQ.0) succeeded. +TestMpq (MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x) succeeded. +TestMpq (MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x) succeeded. +TestMpq (MPQ_2002_v1_ProtectedMap_Spazzler.w3x) succeeded. +TestMpq (MPQ_2014_v1_ProtectedMap_Spazzler2.w3x) succeeded. +TestMpq (MPQ_2014_v1_ProtectedMap_Spazzler3.w3x) succeeded. +TestMpq (MPQ_2002_v1_ProtectedMap_BOBA.w3m) succeeded. +TestMpq (MPQ_2015_v1_ProtectedMap_KangTooJee.w3x) succeeded. +TestMpq (MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x) succeeded. +TestMpq (MPQ_2015_v1_ProtectedMap_Spazy.w3x) succeeded. +TestMpq (MPQ_2015_v1_MessListFile.mpq) succeeded. +TestMpq (MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x) succeeded. +TestMpq (MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x) succeeded. +TestMpq (MPQ_2016_v1_ProtectedMap_Somj2.w3x) succeeded. +TestMpq (MPQ_2016_v1_WME4_4.w3x) succeeded. +TestMpq (MPQ_2016_v1_SP_(4)Adrenaline.w3x) succeeded. +TestMpq (MPQ_2016_v1_ProtectedMap_1.4.w3x) succeeded. +TestMpq (MPQ_2016_v1_KoreanFile.w3m) succeeded. +TestMpq (MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x) succeeded. +TestMpq (MPQ_2017_v1_BigDummyFiles.w3x) succeeded. +TestMpq (MPQ_2017_v1_TildeInFileName.mpq) succeeded. +TestMpq (MPQ_2018_v1_EWIX_v8_7.w3x) succeeded. +TestMpq (MPQ_2020_v4_FakeMpqHeaders.SC2Mod) succeeded. +TestMpq (MPQ_2020_v4_NP_Protect_1.s2ma) succeeded. +TestMpq (MPQ_2020_v4_NP_Protect_2.s2ma) succeeded. +TestMpq (MPQ_2015_v1_flem1.w3x) succeeded. +TestMpq (MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x) succeeded. +TestMpq (MPQ_2021_v1_CantExtractCHK.scx) succeeded. +TestMpq (MPQ_2022_v1_Sniper.scx) succeeded. +TestMpq (MPQ_2022_v1_OcOc_Bound_2.scx) succeeded. +PatchedMPQ (MPQ_1998_v1_StarCraft.mpq) succeeded. +PatchedMPQ (MPQ_2012_v4_OldWorld.MPQ) succeeded. +PatchedMPQ (MPQ_2013_v4_world.MPQ) succeeded. +PatchedMPQ (MPQ_2013_v4_locale-enGB.MPQ) succeeded. +PatchedMPQ (MPQ_2013_v4_Base1.SC2Data) succeeded. +PatchedMPQ (MPQ_2013_v4_Base1.SC2Data) succeeded. +PatchedMPQ (MPQ_2013_v4_Base3.SC2Maps) succeeded. +PatchedMPQ (MPQ_2013_v4_Mods#Core.SC2Mod#enGB.SC2Assets) succeeded. +PatchedMPQ (MPQ_2013_v4_Mods#Liberty.SC2Mod#enGB.SC2Data) succeeded. +PatchedMPQ (MPQ_2014_v4_base-Win.MPQ) succeeded. +PatchedMPQ (MPQ_2014_v4_base-Win.MPQ) succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. +VerifyFileHash succeeded. VerifyFileHash succeeded. VerifyFileHash succeeded. VerifyFileHash succeeded. @@ -90,78 +171,12 @@ VerifyFileHash succeeded. VerifyFileHash succeeded. VerifyFileHash succeeded. VerifyFileHash succeeded. -FileStreamTest (MPQ_2013_v4_alternate-original.MPQ) succeeded. -FileStreamTest (MPQ_2013_v4_alternate-original.MPQ) succeeded. -FileStreamTest (MPQ_2013_v4_alternate-complete.MPQ) succeeded. -FileStreamTest (part-file://MPQ_2009_v2_WoW_patch.MPQ.part) succeeded. -FileStreamTest (blk4-file://streaming/model.MPQ.0) succeeded. -FileStreamTest (mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE) succeeded. -OpenMirrorFile (part-file://MPQ_2009_v1_patch-created.MPQ.part) succeeded. -OpenMirrorFile (part-file://MPQ_2009_v1_patch-partial.MPQ.part) succeeded. -OpenMirrorFile (part-file://MPQ_2009_v1_patch-complete.MPQ.part) succeeded. -OpenMirrorFile (MPQ_2013_v4_alternate-created.MPQ) succeeded. -OpenMirrorFile (MPQ_2013_v4_alternate-incomplete.MPQ) succeeded. -OpenMirrorFile (MPQ_2013_v4_alternate-complete.MPQ) succeeded. -TestMpq (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded. -TestMpq (MPQ_2016_v1_D2XP_IX86_1xx_114a.mpq) succeeded. -TestMpq (MPQ_2018_v1_icon_error.w3m) succeeded. -TestMpq (MPQ_1997_v1_Diablo1_STANDARD.SNP) succeeded. -TestMpq (MPQ_2012_v2_EmptyMpq.MPQ) succeeded. -TestMpq (MPQ_2013_v4_EmptyMpq.MPQ) succeeded. -TestMpq (MPQ_2013_v4_patch-base-16357.MPQ) succeeded. -TestMpq (MPQ_2011_v4_InvalidHetEntryCount.MPQ) succeeded. -TestMpq (MPQ_2002_v1_BlockTableCut.MPQ) succeeded. -TestMpq (MPQ_2010_v2_HasUserData.s2ma) succeeded. -TestMpq (MPQ_2014_v1_AttributesOneEntryLess.w3x) succeeded. -TestMpq (MPQ_2020_v1_AHF04patch.mix) succeeded. -TestMpq (MPQ_2010_v3_expansion-locale-frFR.MPQ) succeeded. -TestMpq (mpqe-file://MPQ_2011_v2_EncryptedMpq.MPQE) succeeded. -TestMpq (MPx_2013_v1_LongwuOnline.mpk) succeeded. -TestMpq (MPx_2013_v1_WarOfTheImmortals.sqp) succeeded. -TestMpq (part-file://MPQ_2010_v2_HashTableCompressed.MPQ.part) succeeded. -TestMpq (blk4-file://streaming/model.MPQ.0) succeeded. -TestMpq (MPQ_2002_v1_ProtectedMap_InvalidUserData.w3x) succeeded. -TestMpq (MPQ_2002_v1_ProtectedMap_InvalidMpqFormat.w3x) succeeded. -TestMpq (MPQ_2002_v1_ProtectedMap_Spazzler.w3x) succeeded. -TestMpq (MPQ_2014_v1_ProtectedMap_Spazzler2.w3x) succeeded. -TestMpq (MPQ_2014_v1_ProtectedMap_Spazzler3.w3x) succeeded. -TestMpq (MPQ_2002_v1_ProtectedMap_BOBA.w3m) succeeded. -TestMpq (MPQ_2015_v1_ProtectedMap_KangTooJee.w3x) succeeded. -TestMpq (MPQ_2015_v1_ProtectedMap_Somj2hM16.w3x) succeeded. -TestMpq (MPQ_2015_v1_ProtectedMap_Spazy.w3x) succeeded. -TestMpq (MPQ_2015_v1_MessListFile.mpq) succeeded. -TestMpq (MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x) succeeded. -TestMpq (MPQ_2016_v1_ProtectedMap_HashOffsIsZero.w3x) succeeded. -TestMpq (MPQ_2016_v1_ProtectedMap_Somj2.w3x) succeeded. -TestMpq (MPQ_2016_v1_WME4_4.w3x) succeeded. -TestMpq (MPQ_2016_v1_SP_(4)Adrenaline.w3x) succeeded. -TestMpq (MPQ_2016_v1_ProtectedMap_1.4.w3x) succeeded. -TestMpq (MPQ_2016_v1_KoreanFile.w3m) succeeded. -TestMpq (MPQ_2017_v1_Eden_RPG_S2_2.5J.w3x) succeeded. -TestMpq (MPQ_2017_v1_BigDummyFiles.w3x) succeeded. -TestMpq (MPQ_2017_v1_TildeInFileName.mpq) succeeded. -TestMpq (MPQ_2018_v1_EWIX_v8_7.w3x) succeeded. -TestMpq (MPQ_2020_v4_FakeMpqHeaders.SC2Mod) succeeded. -TestMpq (MPQ_2020_v4_NP_Protect_1.s2ma) succeeded. -TestMpq (MPQ_2020_v4_NP_Protect_2.s2ma) succeeded. -TestMpq (MPQ_2015_v1_flem1.w3x) succeeded. -TestMpq (MPQ_2002_v1_ProtectedMap_HashTable_FakeValid.w3x) succeeded. -TestMpq (MPQ_2021_v1_CantExtractCHK.scx) succeeded. -PatchedMPQ (MPQ_1998_v1_StarCraft.mpq) succeeded. -PatchedMPQ (MPQ_2012_v4_OldWorld.MPQ) succeeded. -PatchedMPQ (MPQ_2013_v4_world.MPQ) succeeded. -PatchedMPQ (MPQ_2013_v4_locale-enGB.MPQ) succeeded. -PatchedMPQ (MPQ_2013_v4_Base1.SC2Data) succeeded. -PatchedMPQ (MPQ_2013_v4_Base1.SC2Data) succeeded. -PatchedMPQ (MPQ_2013_v4_Base3.SC2Maps) succeeded. -PatchedMPQ (MPQ_2013_v4_Mods#Core.SC2Mod#enGB.SC2Assets) succeeded. -PatchedMPQ (MPQ_2013_v4_Mods#Liberty.SC2Mod#enGB.SC2Data) succeeded. -PatchedMPQ (MPQ_2014_v4_base-Win.MPQ) succeeded. -PatchedMPQ (MPQ_2014_v4_base-Win.MPQ) succeeded. -FailMpqTest (flat-file://streaming/model.MPQ.0) succeeded. OpenEachMpqTest ((10)DustwallowKeys.w3m) succeeded. OpenEachMpqTest (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded. OpenEachMpqTest (MPQ_1997_v1_Diablo1_single_0.sv) succeeded. +OpenEachMpqTest (MPQ_1997_v1_patch_rt_SC1B.mpq) succeeded. +OpenEachMpqTest (MPQ_1997_v1_StarDat.mpq) succeeded. +OpenEachMpqTest (MPQ_1997_v1_StarDat_SC1B.mpq) succeeded. OpenEachMpqTest (MPQ_1998_v1_StarCraft.mpq) succeeded. OpenEachMpqTest (MPQ_1998_v1_StarDat.mpq) succeeded. OpenEachMpqTest (MPQ_2002_v1_BlockTableCut.MPQ) succeeded. @@ -230,6 +245,7 @@ OpenEachMpqTest (MPQ_2020_v4_NP_Protect_4.s2ma) succeeded. OpenEachMpqTest (MPQ_2020_v4_ThreeFakeHeaders.s2ma) succeeded. OpenEachMpqTest (MPQ_2021_v1_CrossLinkedFiles.w3x) succeeded. OpenEachMpqTest (MPQ_2021_v4_BzipError.SC2Replay) succeeded. +OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\1995 - Test MPQs\MPQ_2022_v1_MoeMoeMod.asi (error code: 11) OpenEachMpqTest (hs-0-3604-Win-final.MPQ) succeeded. OpenEachMpqTest (hs-0-5314-Win-final.MPQ) succeeded. OpenEachMpqTest (hs-5314-5435-Win-final.MPQ) succeeded. @@ -297,11 +313,15 @@ OpenEachMpqTest (imp.mpq) succeeded. OpenEachMpqTest (pic.mpq) succeeded. OpenEachMpqTest (sndfx.mpq) succeeded. OpenEachMpqTest (special.mpq) succeeded. +OpenEachMpqTest (patch_rt.mpq) succeeded. +OpenEachMpqTest (StarDat.mpq) succeeded. OpenEachMpqTest (BrooDat.mpq) succeeded. OpenEachMpqTest (BroodWar.mpq) succeeded. OpenEachMpqTest (Patch_rt.mpq) succeeded. OpenEachMpqTest (StarCraft.mpq) succeeded. OpenEachMpqTest (StarDat.mpq) succeeded. +OpenEachMpqTest (StardatSW.mpq) succeeded. +OpenEachMpqTest (StarDat_BETA.mpq) succeeded. OpenEachMpqTest (War2Dat.mpq) succeeded. OpenEachMpqTest (War2Patch.mpq) succeeded. OpenEachMpqTest (d2char.mpq) succeeded. @@ -2246,7 +2266,6 @@ OpenEachMpqTest (hs-6485-6898-Win-final.MPQ) succeeded. OpenEachMpqTest (MPQ_1998_v1_StarDat.mpq) succeeded. OpenEachMpqTest (MPQ_1999_v1_WeakSigned1.mpq) succeeded. OpenEachMpqTest (MPQ_1999_v1_WeakSigned2.mpq) succeeded. -OpenEachMpqTest (MPQ_2002_v1_StrongSignature.w3m) succeeded. OpenEachMpqTest (MPQ_2009_v1_patch-complete.MPQ.part) succeeded. OpenEachMpqTest (MPQ_2009_v1_patch-created.MPQ.part) succeeded. OpenEachMpqTest (MPQ_2009_v1_patch-partial.MPQ.part) succeeded. @@ -2254,7 +2273,6 @@ OpenEachMpqTest (MPQ_2009_v2_WoW_patch.MPQ.part) succeeded. OpenEachMpqTest (MPQ_2011_v2_EncryptedMpq.MPQE) succeeded. OpenEachMpqTest (MPQ_2013_v4_alternate-complete.MPQ) succeeded. OpenEachMpqTest (MPQ_2013_v4_alternate-created.MPQ) succeeded. -OpenEachMpqTest (MPQ_2013_v4_alternate-downloaded.MPQ) succeeded. OpenEachMpqTest (MPQ_2013_v4_alternate-incomplete.MPQ) succeeded. OpenEachMpqTest (MPQ_2013_v4_alternate-original.MPQ) succeeded. OpenEachMpqTest (MPQ_2014_v1_out1.w3x) succeeded. @@ -2279,11 +2297,8 @@ OpenEachMpqTest (StormLibTest_NoListFile.mpq) succeeded. OpenEachMpqTest (StormLibTest_NonStdNames.mpq) succeeded. OpenEachMpqTest (StormLibTest_ReadOnly.mpq) succeeded. OpenEachMpqTest (StormLibTest_ReadWrite.mpq) succeeded. -OpenEachMpqTest (TestArchiveCopy.mpq) succeeded. -OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\Work\(1)TheDeathSheep.w3m (error code: 11) -OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\Work\(10)DustwallowKeys#FFFF.w3m (error code: 11) -OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\Work\(10)RagingStream.w3x (error code: 11) -OpenEachMpqTest: Failed to open archive \Multimedia\MPQs\Work\(2)BootyBay.w3m (error code: 11) +OpenEachMpqTest (File00000003.mpq) succeeded. +FailMpqTest (flat-file://streaming/model.MPQ.0) succeeded. OpenCorruptMpqTest (MPQ_2013_vX_Battle.net.MPQ) succeeded. ReadOnlyTest (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded. ReadOnlyTest (MPQ_1997_v1_Diablo1_DIABDAT.MPQ) succeeded. @@ -2304,7 +2319,7 @@ ListFileTest (MPQ_2013_v4_SC2_EmptyMap.SC2Map) succeeded. CreateEmptyMpq: The file "File00000000.xxx" is present, but it should not be CreateEmptyMpq: The file "File00000000.xxx" is present, but it should not be CreateGapsTest (StormLibTest_GapsTest.mpq) succeeded. -NonStdNamesTest: Adding file " \ \ \ .txt" ... NonStdNamesTest: Adding file "Dir1 \Dir2 \File.txt ." ... NonStdNamesTest: Adding file "Dir1 \Dir2 \ . ." ... NonStdNamesTest (StormLibTest_NonStdNames.mpq) succeeded. +NonStdNamesTest: Adding file " \ \ \ .txt" ... NonStdNamesTest: Adding file "Dir1 \Dir2 \File.txt ." ... NonStdNamesTest: Adding file "Dir1 \Dir2 \ . ." ... NonStdNamesTest (StormLibTest_NonStdNames.mpq) succeeded. SignExistingMpq (MPQ_1998_v1_StarDat.mpq) succeeded. ModifySignedTest (MPQ_1999_v1_WeakSignature.exe) succeeded. CreateSignedMpq (MPQ_1999_v1_WeakSigned1.mpq) succeeded. @@ -2324,4 +2339,4 @@ ListFilePos (StormLibTest_ListFilePos.mpq) succeeded. BigMpqTest (StormLibTest_BigArchive_v4.mpq) succeeded. ModifyTest (MPQ_2014_v4_Base.StormReplay) succeeded. -E:\Ladik\Appdir\StormLib> \ No newline at end of file +E:\Ladik\AppDir\StormLib\bin\StormLib_test\x64\Release> \ No newline at end of file -- cgit v1.2.3