Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- byte[] decompress(byte[] src, int srcPos, int desPos) {
- byte[] des = new byte[0x10000]; //Largest size ever needed.
- int bits, readcount, i, _byte; //offset;
- uint n; ulong z = 0xFEDCBA9876543210;
- int format = src[srcPos++];
- if (format == 0 || format == 2) {
- bits = 0;
- int bitnum = 0;
- if ((srcPos & 1) == 1) { bits = src[srcPos++]; bitnum = 8; } //Optional
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- while (true) {
- readcount = 0;
- if ((bits & 1) == 1) {
- bits >>= 1; bitnum -= 1;
- if (format == 0) { //Format 0: Constant
- des[desPos++] = (byte)bits; bits >>= 8; bitnum -= 8;
- } else { //Format 2: Recent Priority
- if ((bits & 1) == 1) {
- i = 2; bits >>= 1; bitnum -= 1;
- } else if ((bits & 2) == 2) {
- i = 3; bits >>= 2; bitnum -= 2;
- } else {
- i = 4; bits >>= 2; bitnum -= 2;
- }
- for (int offset = 0; offset < 8; offset += 4) {
- _byte = (bits & ((1 << i) - 1)); bits >>= i; bitnum -= i; //Read from compressed data.
- n = (uint)(0xF & (z >> (int)(_byte << 2))); //Get selected value.
- if (_byte != 0xF) { // Check 0xF because <<0x40 does nothing. (ex: no-op?)
- z = (z & (unchecked((ulong)-1) << ((_byte + 1) << 2))) //Keep tail end.
- | ((z & ((((ulong)1) << (_byte << 2)) - 1)) << 4) //Close gap.
- | n; //Put selected value in front.
- } else { z = (z << 4) | n; }
- des[desPos] |= (byte)(n << offset); //Write decompressed 4-bit.
- }
- desPos++;
- }
- if (bitnum < 0) {
- bitnum += 16;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- }
- } else if ((bits & 3) == 0) { //Format 0 & 2: Distance Length: Length
- readcount = 2; bits >>= 2; bitnum -= 2;
- } else if ((bits & 7) == 2) {
- readcount = 3; bits >>= 3; bitnum -= 3;
- } else if ((bits & 0xF) == 6) {
- readcount = 4; bits >>= 4; bitnum -= 4;
- } else if ((bits & 0x1F) == 0xE) {
- readcount = 5; bits >>= 5; bitnum -= 5;
- } else if ((bits & 0x7F) == 0x1E) {
- readcount = 6; bits >>= 7; bitnum -= 7;
- } else if ((bits & 0x7F) == 0x5E) {
- readcount = 7; bits >>= 7; bitnum -= 7;
- } else if ((bits & 0x3F) == 0x3E) {
- readcount = 7 + ((bits >> 6) & 3); bits >>= 8; bitnum -= 8;
- if (readcount == 7) {
- readcount = 10 + (bits & 127); bits >>= 7; bitnum -= 7;
- if (readcount == 10) { return des; }
- }
- }
- if (bitnum < 0) {
- bitnum += 16;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- }
- if (readcount != 0) { //Format 0 & 2: Distance Length: Distance
- uint offset = 0;
- if ((bits & 1) == 0) { //Long Distance - 0~12-bit distance
- bits >>= 1; bitnum -= 1;
- offset = (uint)desPos - 33;
- _byte = 12;
- while (offset < (1 << (_byte - 1))) {
- _byte -= 1;
- }
- offset = (uint)(32 + (bits & ((1 << _byte) - 1))); bits >>= _byte; bitnum -= _byte;
- } else { //Short Distance - 5-bit distance
- bits >>= 1; bitnum -= 1;
- offset = (uint)(bits & 31); bits >>= 5; bitnum -= 5;
- }
- if (bitnum < 0) {
- bitnum += 16;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- }
- //if (desPos < offset) { return null; }
- while (readcount-- > 0) {
- des[desPos] = des[desPos - offset - 1]; desPos++;
- }
- }
- }
- } else { //Format 1
- while (true) {
- bits = src[srcPos++];
- for (int j = 0x80; j > 0; j >>= 1) {
- if ((bits & j) == 0) {
- des[desPos++] = src[srcPos++];
- } else {
- readcount = src[srcPos++];
- int offset = src[srcPos++] | ((readcount & 0xF0) << 4);
- readcount = readcount & 15;
- if (readcount == 0) {
- if (offset == 0) { return des; }
- readcount = src[srcPos++] + 16;
- }
- //if (desPos < offset) { return null; }
- while (readcount-- >= 0) {
- des[desPos] = des[desPos - offset]; desPos++;
- }
- }
- }
- }
- }
- //return des;
- }
- byte[] decompress16(byte[] src, int srcPos, int desPos) {
- byte[] des = new byte[0x4000];
- int bits = 0, i = 0, bitnum = 0;
- uint n; ulong z = 0xFEDCBA9876543210;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- while (true) {
- if ((bits & 0x1) == 0x0) {
- i = 0; bits >>= 1; bitnum -= 1;
- } else if ((bits & 0x7) == 0x1) {
- i = 1; bits >>= 3; bitnum -= 3;
- } else if ((bits & 0xF) == 0x5) {
- i = 2; bits >>= 4; bitnum -= 4;
- } else if ((bits & 0xF) == 0xD) {
- i = 3; bits >>= 4; bitnum -= 4;
- } else if ((bits & 0xF) == 0x3) {
- i = 4; bits >>= 4; bitnum -= 4;
- } else if ((bits & 0xF) == 0xB) {
- i = 5; bits >>= 4; bitnum -= 4;
- } else if ((bits & 0xF) == 0x7) {
- i = 6; bits >>= 4; bitnum -= 4;
- } else if ((bits & 0x3F) == 0xF) {
- i = 7; bits >>= 6; bitnum -= 6;
- } else if ((bits & 0x3F) == 0x2F) {
- i = 8; bits >>= 6; bitnum -= 6;
- } else if ((bits & 0x3F) == 0x1F) {
- i = 9; bits >>= 6; bitnum -= 6;
- } else if ((bits & 0xFF) == 0x3F) {
- i = 10; bits >>= 8; bitnum -= 8;
- } else if ((bits & 0xFF) == 0xBF) {
- i = 11; bits >>= 8; bitnum -= 8;
- } else if ((bits & 0xFF) == 0x7F) {
- i = 12; bits >>= 8; bitnum -= 8;
- } else if ((bits & 0x3FF) == 0xFF) {
- i = 13; bits >>= 10; bitnum -= 10;
- } else if ((bits & 0x3FF) == 0x2FF) {
- i = 14; bits >>= 10; bitnum -= 10;
- } else if ((bits & 0x3FF) == 0x1FF) {
- i = 15; bits >>= 10; bitnum -= 10;
- } else if ((bits & 0x3FF) == 0x3FF) {
- return des;
- }
- n = (uint)(0xF & (z >> (int)(i << 2))); //Get selected value.
- if (i != 0xF) { // Check 0xF because <<0x40 does nothing. (ex: no-op?)
- z = (z & (unchecked((ulong)-1) << ((i + 1) << 2))) //Keep tail end.
- | ((z & ((((ulong)1) << (i << 2)) - 1)) << 4) //Close gap.
- | n; //Put selected value in front.
- } else { z = (z << 4) | n; }
- des[desPos++] = (byte)n; //Write decompressed 4-bit.
- if (bitnum < 0) {
- bitnum += 16;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- }
- }
- }
- int[] bitTable = {0x1, 0x0, 0x3, 0x1, 0x4, 0x5, 0x4, 0xD,
- 0x4, 0x3, 0x4, 0xB, 0x4, 0x7, 0x6, 0xF,
- 0x6, 0x2F, 0x6, 0x1F, 0x8, 0x3F, 0x8, 0xBF,
- 0x8, 0x7F, 0xA, 0xFF, 0xA, 0x2FF, 0xA, 0x1FF,
- 0xA, 0x3FF};
- void compress16(byte[] src, int srcPos, byte[] des, int desPos) { //Not tested.
- int bitnum = 0, bits = 0, i = 0;
- uint n = 0; ulong z = 0xFEDCBA9876543210;
- while (srcPos < src.Length) { //Length may be changed?
- while ((((z >> i) & 0xF) != src[srcPos])) {
- i += 4;
- }
- bits = bits | (bitTable[(i >> 1) + 1] << bitnum); bitnum += bitTable[i >> 1];
- while (bitnum >= 8) {
- des[desPos] = (byte)bits; bits >>= 8; bitnum -= 8;
- }
- n = (uint)(0xF & (z >> (int)i)); //Get selected value.
- if (i != 0x3C) { // Check 0xF because <<0x40 does nothing. (ex: no-op?)
- z = (z & (unchecked((ulong)-1) << (i + 4))) //Keep tail end.
- | ((z & ((((ulong)1) << i) - 1)) << 4) //Close gap.
- | n; //Put selected value in front.
- } else { z = (z << 4) | n; }
- srcPos++;
- }
- bits = bits | (bitTable[0x21] << bitnum); bitnum += bitTable[0x20];
- while (bitnum > 0) {
- des[desPos] = (byte)bits; bits >>= 8; bitnum -= 8;
- }
- }
- byte[] decompBtlBG(byte[] src, int srcPos) {
- byte[] des = new byte[0x8000]; int desPos = 0;
- int bits = 0, i = 0x60, bitnum = 0;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- for (int j = 0; j < 0x7800; j++) {
- switch (bits & 7) {
- case 0:
- case 4:
- bits >>= 2; bitnum -= 2;
- break;
- case 1:
- bits >>= 3; bitnum -= 3;
- i += 1 + (bits & 1); bits >>= 1; bitnum -= 1;
- break;
- case 2:
- bits >>= 3; bitnum -= 3;
- if ((bits & 1) == 0) {
- bits >>= 1; bitnum -= 1;
- i += 11 + (bits & 0xF); bits >>= 4; bitnum -= 4;
- } else {
- bits >>= 1; bitnum -= 1;
- i -= 11 + (bits & 0xF); bits >>= 4; bitnum -= 4;
- }
- break;
- case 3:
- bits >>= 3; bitnum -= 3;
- i += 3 + (bits & 7); bits >>= 3; bitnum -= 3;
- break;
- case 5:
- bits >>= 3; bitnum -= 3;
- i -= 1 + (bits & 1); bits >>= 1; bitnum -= 1;
- break;
- case 6:
- bits >>= 3; bitnum -= 3;
- i = 0x60 + (bits & 0x7F); bits >>= 7; bitnum -= 7;
- break;
- case 7:
- bits >>= 3; bitnum -= 3;
- i -= 3 + (bits & 7); bits >>= 3; bitnum -= 3;
- break;
- }
- des[desPos++] = (byte)i;
- if (bitnum < 0) {
- bitnum += 16;
- bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum));
- }
- }
- return des;
- }
- byte[] decompText(byte[] src, int srcInd) { // int srcPos) {
- byte[] des = new byte[0x8000]; int desPos = 0;
- int textTree = Bits.getInt32(src, 0xA9F54 + ((srcInd >> 8) << 3)) - 0x08000000;
- int textLenAddr = Bits.getInt32(src, 0xA9F54 + ((srcInd >> 8) << 3) + 4) - 0x08000000;
- srcInd &= 0xFF;
- while (srcInd-- != 0) {
- int cLen;
- do {
- cLen = src[textLenAddr++];
- textTree += cLen;
- } while (cLen == 0xFF);
- }
- int initChar = 0;
- int chardata = Bits.getInt32(rom, 0x60C30) - 0x08000000;
- int charpntrs = Bits.getInt32(rom, 0x60C34) - 0x08000000;
- textTree <<= 3;
- do {
- int charTree = (chardata + Bits.getInt16(rom, charpntrs + (initChar << 1))) << 3;
- int charSlot = charTree - 12;
- while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) {
- if (((src[textTree >> 3] >> (textTree++ & 7)) & 1) == 1) {
- int depth = 0;
- while (depth >= 0) {
- while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) {
- depth++;
- }
- charSlot-=12;
- depth--;
- }
- }
- }
- initChar = (Bits.getInt16(rom, charSlot >> 3) >> (charSlot & 7)) & 0xFFF;
- des[desPos++] = (byte)initChar;
- } while (initChar != 0);
- return des;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement