diff --git a/.gitignore b/.gitignore index 92bcf4f..1b1a4e0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +.idea + # User-specific files *.rsuser *.suo diff --git a/GuildWarsMapBrowser.vcxproj b/GuildWarsMapBrowser.vcxproj index d0b2946..5487b08 100644 --- a/GuildWarsMapBrowser.vcxproj +++ b/GuildWarsMapBrowser.vcxproj @@ -214,6 +214,7 @@ + @@ -395,6 +396,7 @@ + diff --git a/SourceFiles/AtexAsm.cpp b/SourceFiles/AtexAsm.cpp index 8d15c04..7c68a6a 100644 --- a/SourceFiles/AtexAsm.cpp +++ b/SourceFiles/AtexAsm.cpp @@ -1,210 +1,6 @@ -#include "pch.h" +#include "pch.h" #include "AtexAsm.h" - -void AtexSubCode1_(unsigned int a, unsigned int b, unsigned int c); -void AtexSubCode2_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f); -void AtexSubCode3_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f); -void AtexSubCode4_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f); -void AtexSubCode5_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f, unsigned int g); -void AtexSubCode6(); -void AtexSubCode7_(unsigned int a, unsigned int b); - -unsigned int ImageFormats[] = {0x0B2, 0x12, 0x0B2, 0x72, 0x12, 0x12, 0x12, 0x100, - 0x1A4, 0x1A4, 0x1A4, 0x104, 0x0A2, 0x78, 0x400, 0x71, - 0x0B1, 0x0B1, 0x0B1, 0x0B1, 0x0A1, 0x11, 0x201}; - -unsigned char byte_79053C[] = { - 0x6, 0x10, 0x6, 0x0F, 0x6, 0x0E, 0x6, 0x0D, 0x6, 0x0C, 0x6, 0x0B, 0x6, 0x0A, 0x6, 0x9, - 0x6, 0x8, 0x6, 0x7, 0x6, 0x6, 0x6, 0x5, 0x6, 0x4, 0x6, 0x3, 0x6, 0x2, 0x6, 0x1, - 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, - 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, - 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, - 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, - 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, - 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0}; - -unsigned char byte_79053D[] = { - 0x10, 0x6, 0x0F, 0x6, 0x0E, 0x6, 0x0D, 0x6, 0x0C, 0x6, 0x0B, 0x6, 0x0A, 0x6, 0x9, 0x6, - 0x8, 0x6, 0x7, 0x6, 0x6, 0x6, 0x5, 0x6, 0x4, 0x6, 0x3, 0x6, 0x2, 0x6, 0x1, 0x2, - 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, - 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x1, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, - 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0}; - -int ImgFmt(unsigned int Format) -{ - if (Format >= 0x17) - { - printf("ERROR: bad image format (%d)!", Format); - exit(0); - } - return ImageFormats[Format]; -} - -struct SImageData -{ - unsigned int *DataPos, *EndPos, _44, _40, _3C, xres, yres; -}; - -void AtexDecompress(unsigned int* InputBuffer, unsigned int BufferSize, unsigned int ImageFormat, - SImageDescriptor ImageDescriptor, unsigned int* OutBuffer) -{ - unsigned int HeaderSize = 12; - - SImageData ImageData; - - int AlphaDataSize2 = ((ImageFormat && 21) - 1) & 2; - - int ColorDataSize = ImgFmt(ImageFormat); - int AlphaDataSize = ColorDataSize; - - AlphaDataSize &= 640; - if (AlphaDataSize) - { - AlphaDataSize = 2; - } - - ColorDataSize &= 528; - if (ColorDataSize) - { - ColorDataSize = 2; - } - - int BlockSize = ColorDataSize + AlphaDataSize2 + AlphaDataSize; - - int BlockCount = ImageDescriptor.xres * ImageDescriptor.yres / 16; - - if (! BlockCount) - { - printf("BlockCount zero\n"); - return; - } - - unsigned int* DcmpBuffer1 = new unsigned int[BlockCount]; - unsigned int* DcmpBuffer2 = DcmpBuffer1 + BlockCount / 2; - memset(DcmpBuffer1, 0, BlockCount * 4); - - ImageData.xres = ImageDescriptor.xres; - ImageData.yres = ImageDescriptor.yres; - - unsigned int DataSize = InputBuffer[HeaderSize >> 2]; - - if (HeaderSize + 8 >= BufferSize) - { - printf("Error 567h\n"); - } - if (DataSize <= 8) - { - printf("Error 569h\n"); - } - if (DataSize + HeaderSize > BufferSize) - { - printf("Error 56Ah\n"); - } - - int CompressionCode = InputBuffer[(HeaderSize + 4) >> 2]; - - ImageData.DataPos = InputBuffer + ((HeaderSize + 8) >> 2); - - if (CompressionCode) - { - ImageData._40 = ImageData._44 = ImageData._3C = 0; - ImageData.EndPos = ImageData.DataPos + ((DataSize - 8) >> 2); - - if (ImageData.DataPos != ImageData.EndPos) - { - ImageData._40 = ImageData.DataPos[0]; - ImageData.DataPos++; - } - - if (CompressionCode & 0x10 && ImageData.xres == 256 && ImageData.yres == 256 && - (ImageFormat == 0x11 || ImageFormat == 0x10)) - { - AtexSubCode1_((unsigned int)DcmpBuffer1, (unsigned int)DcmpBuffer2, BlockCount); - } - if (CompressionCode & 1 && ColorDataSize && ! AlphaDataSize && ! AlphaDataSize2) - { - AtexSubCode2_((unsigned int)OutBuffer, (unsigned int)DcmpBuffer1, (unsigned int)DcmpBuffer2, - (unsigned int)&ImageData, BlockCount, BlockSize); - } - if (CompressionCode & 2 && ImageFormat >= 0x10 && ImageFormat <= 0x11) - { - AtexSubCode3_((unsigned int)OutBuffer, (unsigned int)DcmpBuffer1, (unsigned int)DcmpBuffer2, - (unsigned int)&ImageData, BlockCount, BlockSize); - } - if (CompressionCode & 4 && ImageFormat >= 0x12 && ImageFormat <= 0x15) - { - AtexSubCode4_((unsigned int)OutBuffer, (unsigned int)DcmpBuffer1, (unsigned int)DcmpBuffer2, - (unsigned int)&ImageData, BlockCount, BlockSize); - } - if (CompressionCode & 8 && ColorDataSize) - { - AtexSubCode5_((unsigned int)OutBuffer + AlphaDataSize2 + AlphaDataSize * 4, - (unsigned int)DcmpBuffer1, (unsigned int)DcmpBuffer2, (unsigned int)&ImageData, - BlockCount, BlockSize, ImageFormat == 0xf); - } - ImageData.DataPos--; - } - - unsigned int* DataEnd = InputBuffer + ((HeaderSize + DataSize) >> 2); - - if ((AlphaDataSize || AlphaDataSize2) && BlockCount) - { - unsigned int* BufferVar = OutBuffer; - - for (int x = 0; x < BlockCount; x++) - { - if (! (DcmpBuffer1[x >> 5] & 1 << x)) - { - BufferVar[0] = ImageData.DataPos[0]; - BufferVar[1] = ImageData.DataPos[1]; - ImageData.DataPos += 2; - } - BufferVar += BlockSize; - } - } - - if (ColorDataSize && BlockCount) - { - unsigned int* BufferVar = OutBuffer + AlphaDataSize2 + AlphaDataSize; - - for (int x = 0; x < BlockCount; x++) - { - if (! (DcmpBuffer2[x >> 5] & 1 << x)) - { - BufferVar[0] = ImageData.DataPos[0]; - ImageData.DataPos++; - } - BufferVar += BlockSize; - } - - BufferVar = OutBuffer + AlphaDataSize2 + AlphaDataSize + 1; - - for (int x = 0; x < BlockCount; x++) - { - if (! (DcmpBuffer2[x >> 5] & 1 << x)) - { - BufferVar[0] = ImageData.DataPos[0]; - ImageData.DataPos++; - } - BufferVar += BlockSize; - } - } - - if (CompressionCode & 0x10 && ImageData.xres == 256 && ImageData.yres == 256 && - (ImageFormat == 0x10 || ImageFormat == 0x11)) - { - AtexSubCode7_((unsigned int)OutBuffer, BlockCount); - } - - delete[] (unsigned char*)DcmpBuffer1; -} +#include "AtexDecompress.h" void __declspec(naked) AtexSubCode1() { @@ -263,12 +59,12 @@ void __declspec(naked) AtexSubCode1() } } -void AtexSubCode1_(unsigned int a, unsigned int b, unsigned int c) +void AtexSubCode1_Asm(uint32_t* array1, uint32_t* array2, unsigned int count) { __asm { - mov ecx, a - mov edx, b - push c + mov ecx, array1 + mov edx, array2 + push count call AtexSubCode1 } } @@ -504,16 +300,15 @@ void __declspec(naked) AtexSubCode2() } } -void AtexSubCode2_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f) +void AtexSubCode2_Asm(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize) { __asm { - mov ecx, a - mov edx, b - push f - push e - push d - push c + mov ecx, outBuffer + mov edx, dcmpBuffer1 + push blockSize + push blockCount + push imageData + push dcmpBuffer2 call AtexSubCode2 } } @@ -873,16 +668,15 @@ void __declspec(naked) AtexSubCode3() } } -void AtexSubCode3_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f) +void AtexSubCode3_Asm(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize) { __asm { - mov ecx, a - mov edx, b - push f - push e - push d - push c + mov ecx, outBuffer + mov edx, dcmpBuffer1 + push blockSize + push blockCount + push imageData + push dcmpBuffer2 call AtexSubCode3 } } @@ -1233,20 +1027,20 @@ void __declspec(naked) AtexSubCode4() } } -void AtexSubCode4_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, - unsigned int f) +void AtexSubCode4_Asm(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize) { __asm { - mov ecx, a - mov edx, b - push f - push e - push d - push c + mov ecx, outBuffer + mov edx, dcmpBuffer1 + push blockSize + push blockCount + push imageData + push dcmpBuffer2 call AtexSubCode4 } } +void AtexSubCode6(); void __declspec(naked) AtexSubCode5() { __asm { @@ -1534,7 +1328,7 @@ void __declspec(naked) AtexSubCode5() } } -void AtexSubCode5_(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, +void AtexSubCode5_Asm(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, unsigned int f, unsigned int g) { __asm { @@ -2032,7 +1826,7 @@ void __declspec(naked) AtexSubCode7() } } -void AtexSubCode7_(unsigned int a, unsigned int b) +void AtexSubCode7_Asm(unsigned int a, unsigned int b) { __asm { mov ecx, a diff --git a/SourceFiles/AtexAsm.h b/SourceFiles/AtexAsm.h index df9d084..bfba49b 100644 --- a/SourceFiles/AtexAsm.h +++ b/SourceFiles/AtexAsm.h @@ -1,16 +1,9 @@ -#pragma once +#pragma once -struct SImageDescriptor -{ - int xres, yres; - unsigned char* Data; - int a; - int b; - unsigned char* image; - int imageformat; - int c; -}; - -int DecompressAtex(int a, int b, int imageformat, int d, int e, int f, int g); -void AtexDecompress(unsigned int* input, unsigned int unknown, unsigned int imageformat, - SImageDescriptor ImageDescriptor, unsigned int* output); +struct SImageData; +void AtexSubCode1_Asm(uint32_t* array1, uint32_t* array2, unsigned int count); +void AtexSubCode2_Asm(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize); +void AtexSubCode3_Asm(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize); +void AtexSubCode4_Asm(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize); +void AtexSubCode5_Asm(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int e, unsigned int f, unsigned int g); +void AtexSubCode7_Asm(unsigned int a, unsigned int b); diff --git a/SourceFiles/AtexDecompress.cpp b/SourceFiles/AtexDecompress.cpp new file mode 100644 index 0000000..4d5f488 --- /dev/null +++ b/SourceFiles/AtexDecompress.cpp @@ -0,0 +1,472 @@ +#include "pch.h" +#include "AtexDecompress.h" +#include "AtexAsm.h" + +struct SImageData; + +void AtexSubCode1_Cpp(uint32_t* array1, uint32_t* array2, unsigned int count); +void AtexSubCode2_Cpp(uint32_t* outBuffer, uint32_t* dcmpBuffer1, uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize); +// currently loses some highlights, but I have no idea why. even a direct translation has this issue +void AtexSubCode3_Cpp(uint32_t* outBuffer, uint32_t* dcmpBuffer1, const uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize); + +int ImgFmt(unsigned int Format) +{ + if (Format >= 0x17) + { + printf("ERROR: bad image format (%d)!", Format); + exit(0); + } + return ImageFormats[Format]; +} + +void AtexDecompress(unsigned int* InputBuffer, unsigned int BufferSize, unsigned int ImageFormat, const SImageDescriptor& ImageDescriptor, unsigned int* OutBuffer) +{ + unsigned int HeaderSize = 12; + + SImageData ImageData; + + int AlphaDataSize2 = ((ImageFormat && 21) - 1) & 2; + + int ColorDataSize = ImgFmt(ImageFormat); + int AlphaDataSize = ColorDataSize; + + AlphaDataSize &= 640; + if (AlphaDataSize) + { + AlphaDataSize = 2; + } + + ColorDataSize &= 528; + if (ColorDataSize) + { + ColorDataSize = 2; + } + + int BlockSize = ColorDataSize + AlphaDataSize2 + AlphaDataSize; + + int BlockCount = ImageDescriptor.xres * ImageDescriptor.yres / 16; + + if (! BlockCount) + { + printf("BlockCount zero\n"); + return; + } + + unsigned int* DcmpBuffer1 = new unsigned int[BlockCount]; + unsigned int* DcmpBuffer2 = DcmpBuffer1 + BlockCount / 2; + memset(DcmpBuffer1, 0, BlockCount * 4); + + ImageData.xres = ImageDescriptor.xres; + ImageData.yres = ImageDescriptor.yres; + + unsigned int DataSize = InputBuffer[HeaderSize >> 2]; + + if (HeaderSize + 8 >= BufferSize) + { + printf("Error 567h\n"); + } + if (DataSize <= 8) + { + printf("Error 569h\n"); + } + if (DataSize + HeaderSize > BufferSize) + { + printf("Error 56Ah\n"); + } + + int CompressionCode = InputBuffer[(HeaderSize + 4) >> 2]; + + ImageData.DataPos = InputBuffer + ((HeaderSize + 8) >> 2); + + if (CompressionCode) + { + ImageData.currentBits = ImageData.remainingBits = ImageData.nextBits = 0; + ImageData.EndPos = ImageData.DataPos + ((DataSize - 8) >> 2); + + if (ImageData.DataPos != ImageData.EndPos) + { + ImageData.currentBits = ImageData.DataPos[0]; + ImageData.DataPos++; + } + + if (CompressionCode & 0x10 && ImageData.xres == 256 && ImageData.yres == 256 && + (ImageFormat == 0x11 || ImageFormat == 0x10)) + { + AtexSubCode1_Cpp(DcmpBuffer1, DcmpBuffer2, BlockCount); + } + if (CompressionCode & 1 && ColorDataSize && ! AlphaDataSize && ! AlphaDataSize2) + { + AtexSubCode2_Cpp(OutBuffer, DcmpBuffer1, DcmpBuffer2, &ImageData, BlockCount, BlockSize); + } + if (CompressionCode & 2 && ImageFormat >= 0x10 && ImageFormat <= 0x11) + { + AtexSubCode3_Asm(OutBuffer, DcmpBuffer1, DcmpBuffer2, &ImageData, BlockCount, BlockSize); + } + if (CompressionCode & 4 && ImageFormat >= 0x12 && ImageFormat <= 0x15) + { + AtexSubCode4_Asm(OutBuffer, DcmpBuffer1, DcmpBuffer2, &ImageData, BlockCount, BlockSize); + } + if (CompressionCode & 8 && ColorDataSize) + { + AtexSubCode5_Asm((unsigned int)OutBuffer + AlphaDataSize2 + AlphaDataSize * 4, + (unsigned int)DcmpBuffer1, (unsigned int)DcmpBuffer2, (unsigned int)&ImageData, + BlockCount, BlockSize, ImageFormat == 0xf); + } + ImageData.DataPos--; + } + + [[maybe_unused]] unsigned int* DataEnd = InputBuffer + ((HeaderSize + DataSize) >> 2); + + if ((AlphaDataSize || AlphaDataSize2) && BlockCount) + { + unsigned int* BufferVar = OutBuffer; + + for (int x = 0; x < BlockCount; x++) + { + if (! (DcmpBuffer1[x >> 5] & 1 << x)) + { + BufferVar[0] = ImageData.DataPos[0]; + BufferVar[1] = ImageData.DataPos[1]; + ImageData.DataPos += 2; + } + BufferVar += BlockSize; + } + } + + if (ColorDataSize && BlockCount) + { + unsigned int* BufferVar = OutBuffer + AlphaDataSize2 + AlphaDataSize; + + for (int x = 0; x < BlockCount; x++) + { + if (! (DcmpBuffer2[x >> 5] & 1 << x)) + { + BufferVar[0] = ImageData.DataPos[0]; + ImageData.DataPos++; + } + BufferVar += BlockSize; + } + + BufferVar = OutBuffer + AlphaDataSize2 + AlphaDataSize + 1; + + for (int x = 0; x < BlockCount; x++) + { + if (! (DcmpBuffer2[x >> 5] & 1 << x)) + { + BufferVar[0] = ImageData.DataPos[0]; + ImageData.DataPos++; + } + BufferVar += BlockSize; + } + } + + if (CompressionCode & 0x10 && ImageData.xres == 256 && ImageData.yres == 256 && + (ImageFormat == 0x10 || ImageFormat == 0x11)) + { + AtexSubCode7_Asm((unsigned int)OutBuffer, BlockCount); + } + + delete[] (unsigned char*)DcmpBuffer1; +} + +void AtexSubCode1_Cpp(uint32_t* array1, uint32_t* array2, unsigned int count) +{ + for (auto i = 0u; i < count; ++i) { + const uint32_t mask = 1 << (i & 0x1F); + if ((mask & 0xC0000003) != 0 || ((1 << ((i >> 6) & 0x1F)) & 0xC0000003) != 0) { + const uint32_t array_index = i >> 5; // 4 * (i >> 5), but uint32_t* points to 4 bytes + array1[array_index] |= mask; + array2[array_index] |= mask; + } + } +} + +void AtexSubCode2_Cpp(uint32_t *outBuffer, uint32_t *dcmpBuffer1, uint32_t *dcmpBuffer2, SImageData *imageData, uint32_t blockCount, uint32_t blockSize) +{ + if (blockCount == 0) { + return; + } + + uint32_t block_index = 0; + int extractedBits; + uint32_t* dataPosition; + uint32_t currentWord; + + while (block_index < blockCount) + { + const auto shiftLeft = imageData->currentBits >> 26; + const auto shiftValue = byte_79053C[2 * shiftLeft]; + int remainingBits = byte_79053D[2 * shiftLeft] + 1; + + if (shiftValue) { + imageData->currentBits = (imageData->currentBits << shiftValue) | (imageData->nextBits >> (32 - shiftValue)); + } + + uint32_t bitCount = imageData->remainingBits; + + if (shiftValue > bitCount) + { + dataPosition = imageData->DataPos; + + if (dataPosition == imageData->EndPos) + { + extractedBits = 0; + imageData->nextBits = 0; + } + else + { + currentWord = *dataPosition; + imageData->DataPos = dataPosition + 1; + imageData->nextBits = currentWord; + imageData->currentBits |= currentWord >> (bitCount - shiftValue + 32); + imageData->nextBits = currentWord << (shiftValue - bitCount); + extractedBits = bitCount - shiftValue + 32; + } + } + else + { + extractedBits = bitCount - shiftValue; + imageData->nextBits <<= shiftValue; + } + + const uint64_t combinedValue = (static_cast(imageData->currentBits) << 32) | imageData->nextBits; + imageData->remainingBits = extractedBits; + imageData->currentBits = static_cast(combinedValue >> 31); + int bitMask = static_cast(combinedValue >> 63); + + if (imageData->remainingBits) + { + imageData->nextBits = static_cast(combinedValue << 1); + imageData->remainingBits -= 1; + } + else + { + dataPosition = imageData->DataPos; + + if (dataPosition == imageData->EndPos) + { + imageData->nextBits = 0; + imageData->remainingBits = 0; + } + else + { + const auto curPos = *dataPosition; + imageData->DataPos = dataPosition + 1; + currentWord = curPos; + imageData->currentBits |= currentWord >> 31; + imageData->remainingBits = 31; + imageData->nextBits = 2 * currentWord; + } + } + + while (remainingBits > 0 && block_index < blockCount) + { + const int bitPosition = 1 << (block_index & 0x1F); + const int bufferIndex = block_index >> 5; + + if ((bitPosition & dcmpBuffer2[bufferIndex]) == 0) + { + if (bitMask) + { + outBuffer[0] = static_cast(-2); + outBuffer[1] = static_cast(-1); + dcmpBuffer2[bufferIndex] |= bitPosition; + dcmpBuffer1[bufferIndex] |= bitPosition; + bitMask = static_cast(combinedValue >> 63); + } + remainingBits -= 1; + } + + block_index++; + outBuffer += blockSize; + } + + while (block_index < blockCount && (1 << (block_index & 0x1F) & dcmpBuffer2[block_index >> 5]) != 0) + { + block_index++; + outBuffer += blockSize; + } + } +} + +void AtexSubCode3_Cpp(uint32_t* outBuffer, uint32_t* dcmpBuffer1, const uint32_t* dcmpBuffer2, SImageData* imageData, unsigned int blockCount, unsigned int blockSize) +{ + const unsigned int current_bits = imageData->currentBits; + const int currentDataPos = (16 * current_bits) | (imageData->nextBits >> 28); + const unsigned int remainingBits = imageData->remainingBits; + unsigned int tempBits = 0; + int bitDifference; + int bufferArray[4]{}; + int bitCounter; + uint32_t* bufferPos = outBuffer; + + imageData->currentBits = currentDataPos; + + if (remainingBits < 4) + { + unsigned int* dataPtr = imageData->DataPos; + if (imageData->DataPos == imageData->EndPos) + { + imageData->nextBits = 0; + imageData->remainingBits = 0; + } + else + { + unsigned int newBits = *dataPtr; + imageData->DataPos = dataPtr + 1; + imageData->nextBits = newBits; + imageData->currentBits = (newBits >> (remainingBits + 28)) | currentDataPos; + imageData->remainingBits = remainingBits + 28; + imageData->nextBits = newBits << (4 - remainingBits); + } + } + else + { + imageData->nextBits *= 16; + imageData->remainingBits = remainingBits - 4; + } + + if (blockCount == 0) + { + return; + } + + while (tempBits != blockCount) + { + int bitShifted = imageData->currentBits >> 26; + int bitShiftedBy = byte_79053D[2 * bitShifted] + 1; + unsigned int bitField = byte_79053C[2 * bitShifted]; + + if (byte_79053C[2 * bitShifted]) + { + imageData->currentBits = (imageData->currentBits << bitField) | (imageData->nextBits >> (32 - bitField)); + } + + unsigned int flagBits = imageData->remainingBits; + unsigned int bitMask = flagBits; + + if (bitField > flagBits) + { + if (imageData->DataPos == imageData->EndPos) + { + bitDifference = 0; + imageData->nextBits = 0; + } + else + { + unsigned int dataOffset = *imageData->DataPos++; + imageData->nextBits = dataOffset; + bitCounter = bitMask - bitField + 32; + imageData->currentBits |= dataOffset >> bitCounter; + imageData->nextBits = dataOffset << (bitField - flagBits); + bitDifference = bitCounter; + } + } + else + { + bitDifference = flagBits - bitField; + imageData->nextBits <<= bitField; + } + + imageData->remainingBits = bitDifference; + unsigned int curBits = imageData->currentBits; + imageData->currentBits = (2 * curBits) | (imageData->nextBits >> 31); + flagBits = curBits >> 31; + + if (imageData->remainingBits) + { + imageData->nextBits *= 2; + imageData->remainingBits -= 1; + } + else + { + unsigned int* bufferPtr = imageData->DataPos; + if (imageData->DataPos == imageData->EndPos) + { + imageData->nextBits = 0; + imageData->remainingBits = 0; + } + else + { + unsigned int finalShift = *bufferPtr; + imageData->DataPos = bufferPtr + 1; + imageData->nextBits = finalShift; + int bufferOffset = (finalShift >> 31) | imageData->currentBits; + imageData->currentBits = bufferOffset; + imageData->nextBits = 2 * finalShift; + imageData->remainingBits = 31; + } + } + + int bitIndex = flagBits; + bitCounter = flagBits; + + if (flagBits) + { + unsigned int combinedBitsShifted = imageData->currentBits; + imageData->currentBits = (2 * combinedBitsShifted) | (imageData->nextBits >> 31); + const int bitRemainingShift = imageData->remainingBits; + int finalBitShift = combinedBitsShifted >> 31; + + if (bitRemainingShift) + { + imageData->nextBits *= 2; + imageData->remainingBits = bitRemainingShift - 1; + } + else + { + if (imageData->DataPos == imageData->EndPos) + { + imageData->nextBits = 0; + imageData->remainingBits = 0; + } + else + { + imageData->nextBits = *imageData->DataPos++; + imageData->currentBits |= imageData->nextBits >> 31; + imageData->nextBits *= 2; + imageData->remainingBits = 31; + } + } + + bitIndex = finalBitShift + flagBits; + bitCounter = finalBitShift + flagBits; + } + + while (bitShiftedBy) + { + while (tempBits != blockCount) + { + const int nextBitOffset = 1 << (tempBits & 0x1F); + const int finalShiftedBits = tempBits >> 5; + + if ((nextBitOffset & dcmpBuffer2[finalShiftedBits]) == 0) + { + if (bitIndex) + { + bufferPos[0] = bufferArray[2 * bitIndex]; + bufferPos[1] = bufferArray[2 * bitCounter + 1]; + dcmpBuffer1[finalShiftedBits] |= nextBitOffset; + bitIndex = bitCounter; + } + bitShiftedBy--; + } + + tempBits++; + bufferPos += blockSize; + + if (!bitShiftedBy) + break; + } + + while (((1 << (tempBits & 0x1F)) & dcmpBuffer2[tempBits >> 5]) != 0) + { + bufferPos += blockSize; + + if (++tempBits == blockCount) + return; + } + } + } +} + diff --git a/SourceFiles/AtexDecompress.h b/SourceFiles/AtexDecompress.h new file mode 100644 index 0000000..aaee90a --- /dev/null +++ b/SourceFiles/AtexDecompress.h @@ -0,0 +1,47 @@ +#pragma once + +struct SImageDescriptor +{ + int xres, yres; + unsigned char* Data; + int a; + int b; + unsigned char* image; + int imageformat; + int c; +}; + +struct SImageData +{ + unsigned int *DataPos, *EndPos, remainingBits, currentBits, nextBits, xres, yres; +}; + + + +constexpr unsigned int ImageFormats[] = {0x0B2, 0x12, 0x0B2, 0x72, 0x12, 0x12, 0x12, 0x100, + 0x1A4, 0x1A4, 0x1A4, 0x104, 0x0A2, 0x78, 0x400, 0x71, + 0x0B1, 0x0B1, 0x0B1, 0x0B1, 0x0A1, 0x11, 0x201}; + +constexpr unsigned char byte_79053C[] = { + 0x6, 0x10, 0x6, 0x0F, 0x6, 0x0E, 0x6, 0x0D, 0x6, 0x0C, 0x6, 0x0B, 0x6, 0x0A, 0x6, 0x9, + 0x6, 0x8, 0x6, 0x7, 0x6, 0x6, 0x6, 0x5, 0x6, 0x4, 0x6, 0x3, 0x6, 0x2, 0x6, 0x1, + 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, + 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, + 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, + 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, + 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, + 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0}; + +constexpr unsigned char byte_79053D[] = { + 0x10, 0x6, 0x0F, 0x6, 0x0E, 0x6, 0x0D, 0x6, 0x0C, 0x6, 0x0B, 0x6, 0x0A, 0x6, 0x9, 0x6, + 0x8, 0x6, 0x7, 0x6, 0x6, 0x6, 0x5, 0x6, 0x4, 0x6, 0x3, 0x6, 0x2, 0x6, 0x1, 0x2, + 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, + 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x2, 0x11, 0x1, + 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, + 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, + 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, + 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0}; + +int DecompressAtex(int a, int b, int imageformat, int d, int e, int f, int g); +void AtexDecompress(unsigned int* input, unsigned int unknown, unsigned int imageformat, + const SImageDescriptor& ImageDescriptor, unsigned int* output); diff --git a/SourceFiles/AtexReader.cpp b/SourceFiles/AtexReader.cpp index 65c5875..0d51f61 100644 --- a/SourceFiles/AtexReader.cpp +++ b/SourceFiles/AtexReader.cpp @@ -1,6 +1,6 @@ #include "pch.h" -#include "AtexAsm.h" +#include "AtexDecompress.h" #pragma pack(1) diff --git a/SourceFiles/pch.h b/SourceFiles/pch.h index b067223..027b17f 100644 --- a/SourceFiles/pch.h +++ b/SourceFiles/pch.h @@ -71,7 +71,7 @@ #include "ImGuiFileDialog.h" #include "GWUnpacker.h" -#include "AtexAsm.h" +#include "AtexDecompress.h" #include "AtexReader.h" #ifdef _DEBUG