decodes.c (25960B)
1 /* decodes.c */ 2 3 #include "doomdef.h" 4 5 #include "graph.h" 6 7 /*=======*/ 8 /* TYPES */ 9 /*=======*/ 10 11 typedef struct { 12 int dec_bit_count; 13 int dec_bit_buffer; 14 int enc_bit_count; 15 int enc_bit_buffer; 16 byte* ostart; 17 byte* output; 18 byte* istart; 19 byte* input; 20 } buffers_t; 21 22 typedef struct { 23 int offset; 24 int incrBit; 25 int unk1; 26 int type; 27 } encodeArgs_t; 28 29 /*=========*/ 30 /* GLOBALS */ 31 /*=========*/ 32 33 static short ShiftTable[6] = { 4, 6, 8, 10, 12, 14 }; // 8005D8A0 34 35 static int offsetTable[12]; // 800B2250 36 static int offsetMaxSize, windowSize; // 800b2280 , 800b2284 37 static encodeArgs_t encArgs; // 800b2288 38 39 #define HASH_SIZE (1 << 14) 40 static short* hashtable; // 800B2298 41 static short* hashtarget; // 800B229C 42 static short* hashNext; // 800B22A0 43 static short* hashPrev; // 800B22A4 44 45 static short DecodeTable[2516]; // 800B22A8 46 static short array01[1258]; // 800B3660 47 48 static buffers_t buffers; // 800B4034 49 static byte* window; // 800B4054 50 51 static int OVERFLOW_READ; // 800B4058 52 static int OVERFLOW_WRITE; // 800B405C 53 54 /* 55 ============================================================================ 56 57 DECODE BASED ROUTINES 58 59 ============================================================================ 60 */ 61 62 /* 63 ======================== 64 = 65 = GetOutputSize 66 = 67 ======================== 68 */ 69 int GetOutputSize(void) // [GEC] New 70 { 71 return (int)((int)buffers.output - (int)buffers.ostart); 72 } 73 74 /* 75 ======================== 76 = 77 = GetReadSize 78 = 79 ======================== 80 */ 81 82 int GetReadSize(void) // [GEC] New 83 { 84 return (int)((int)buffers.input - (int)buffers.istart); 85 } 86 87 /* 88 ======================== 89 = 90 = ReadByte -> Old GetDecodeByte 91 = 92 ======================== 93 */ 94 95 static int ReadByte(void) // 8002D1D0 96 { 97 if ((int)(buffers.input - buffers.istart) >= OVERFLOW_READ) 98 return -1; 99 100 return *buffers.input++; 101 } 102 103 /* 104 ======================== 105 = 106 = WriteByte -> Old WriteOutput 107 = 108 ======================== 109 */ 110 111 static void WriteByte(byte outByte) // 8002D214 112 { 113 if ((int)(buffers.output - buffers.ostart) >= OVERFLOW_WRITE) { 114 I_Error("Overflowed output buffer"); 115 } 116 117 *buffers.output++ = outByte; 118 } 119 120 /* 121 ======================== 122 = 123 = WriteBinary 124 = routine required for encoding 125 = 126 ======================== 127 */ 128 129 static void WriteBinary(int binary) // 8002D288 130 { 131 buffers.enc_bit_buffer = (buffers.enc_bit_buffer << 1); 132 133 if (binary != 0) 134 buffers.enc_bit_buffer = (buffers.enc_bit_buffer | 1); 135 136 buffers.enc_bit_count = (buffers.enc_bit_count + 1); 137 if (buffers.enc_bit_count == 8) 138 { 139 WriteByte((byte)buffers.enc_bit_buffer); 140 buffers.enc_bit_count = 0; 141 } 142 } 143 144 /* 145 ======================== 146 = 147 = ReadBinary -> old DecodeScan 148 = 149 ======================== 150 */ 151 152 static int ReadBinary(void) // 8002D2F4 153 { 154 int resultbyte; 155 156 resultbyte = buffers.dec_bit_count; 157 158 buffers.dec_bit_count = (resultbyte - 1); 159 if ((resultbyte < 1)) 160 { 161 resultbyte = ReadByte(); 162 163 buffers.dec_bit_buffer = resultbyte; 164 buffers.dec_bit_count = 7; 165 } 166 167 resultbyte = (0 < (buffers.dec_bit_buffer & 0x80)); 168 buffers.dec_bit_buffer = (buffers.dec_bit_buffer << 1); 169 170 return resultbyte; 171 } 172 173 /* 174 ======================== 175 = 176 = WriteCodeBinary 177 = routine required for encoding 178 = 179 ======================== 180 */ 181 182 static void WriteCodeBinary(int binary, int shift) // 8002D364 183 { 184 int i; 185 186 i = 0; 187 if (shift > 0) 188 { 189 do 190 { 191 WriteBinary(binary & 1); 192 binary = (binary >> 1); 193 } while (++i != shift); 194 } 195 } 196 197 /* 198 ======================== 199 = 200 = ReadCodeBinary -> old RescanByte 201 = 202 ======================== 203 */ 204 205 static int ReadCodeBinary(int byte) // 8002D3B8 206 { 207 int shift; 208 int i; 209 int resultbyte; 210 211 resultbyte = 0; 212 i = 0; 213 shift = 1; 214 215 if (byte <= 0) 216 return resultbyte; 217 218 do 219 { 220 if (ReadBinary() != 0) 221 resultbyte |= shift; 222 223 i++; 224 shift = (shift << 1); 225 } while (i != byte); 226 227 return resultbyte; 228 } 229 230 /* 231 ======================== 232 = 233 = FlushBitBuffer 234 = routine required for encoding 235 = 236 ======================== 237 */ 238 239 static void FlushBitBuffer(void) // 8002D424 240 { 241 if (buffers.enc_bit_count > 0) { 242 WriteByte((byte)(buffers.enc_bit_buffer << (8 - buffers.enc_bit_count)) & 0xff); 243 } 244 } 245 246 /* 247 ======================== 248 = 249 = InitTables -> old InitDecodeTable 250 = 251 ======================== 252 */ 253 254 static void InitTables(void) // 8002D468 255 { 256 int evenVal, oddVal, incrVal, i; 257 258 short* curArray; 259 short* incrTbl; 260 short* evenTbl; 261 short* oddTbl; 262 263 int* Tbl1, * Tbl2; 264 265 encArgs.incrBit = 3; 266 encArgs.unk1 = 0; 267 encArgs.type = 0; 268 269 buffers.dec_bit_count = 0; 270 buffers.dec_bit_buffer = 0; 271 buffers.enc_bit_count = 0; 272 buffers.enc_bit_buffer = 0; 273 274 curArray = &array01[(0 + 2)]; 275 incrTbl = &DecodeTable[(1258 + 2)]; 276 277 incrVal = 2; 278 279 do { 280 *incrTbl++ = (short)(incrVal / 2); 281 *curArray++ = 1; 282 } while (++incrVal < 1258); 283 284 oddTbl = &DecodeTable[(629 + 1)]; 285 evenTbl = &DecodeTable[(0 + 1)]; 286 287 evenVal = 1; 288 oddVal = 3; 289 290 do 291 { 292 *oddTbl++ = (short)oddVal; 293 oddVal += 2; 294 295 *evenTbl++ = (short)(evenVal * 2); 296 evenVal++; 297 } while (evenVal < 629); 298 299 incrVal = 0; 300 i = 0; 301 Tbl2 = &offsetTable[6]; 302 Tbl1 = &offsetTable[0]; 303 do { 304 *Tbl1++ = incrVal; 305 incrVal += (1 << (ShiftTable[i] & 0x1f)); 306 *Tbl2++ = incrVal - 1; 307 } while (++i <= 5); 308 309 offsetMaxSize = incrVal - 1; 310 windowSize = offsetMaxSize + (64 - 1); 311 } 312 313 /* 314 ======================== 315 = 316 = CheckTable 317 = 318 ======================== 319 */ 320 321 static void CheckTable(int a0, int a1, int a2) // 8002D624 322 { 323 int i; 324 int idByte1; 325 int idByte2; 326 short* curArray; 327 short* evenTbl; 328 short* oddTbl; 329 short* incrTbl; 330 331 i = 0; 332 evenTbl = &DecodeTable[0]; 333 oddTbl = &DecodeTable[629]; 334 incrTbl = &DecodeTable[1258]; 335 336 idByte1 = a0; 337 338 do { 339 idByte2 = incrTbl[idByte1]; 340 341 array01[idByte2] = (array01[a1] + array01[a0]); 342 343 a0 = idByte2; 344 345 if (idByte2 != 1) { 346 idByte1 = incrTbl[idByte2]; 347 idByte2 = evenTbl[idByte1]; 348 349 a1 = idByte2; 350 351 if (a0 == idByte2) { 352 a1 = oddTbl[idByte1]; 353 } 354 } 355 356 idByte1 = a0; 357 } while (a0 != 1); 358 359 if (array01[1] != 0x7D0) { 360 return; 361 } 362 363 array01[1] >>= 1; 364 365 curArray = &array01[2]; 366 do 367 { 368 curArray[3] >>= 1; 369 curArray[2] >>= 1; 370 curArray[1] >>= 1; 371 curArray[0] >>= 1; 372 curArray += 4; 373 i += 4; 374 } while (i != 1256); 375 } 376 377 /* 378 ======================== 379 = 380 = UpdateTables -> old DecodeByte 381 = 382 ======================== 383 */ 384 385 static void UpdateTables(int tblpos) // 8002D72C 386 { 387 int incrIdx; 388 int evenVal; 389 int idByte1; 390 int idByte2; 391 int idByte3; 392 int idByte4; 393 394 short* evenTbl; 395 short* oddTbl; 396 short* incrTbl; 397 short* tmpIncrTbl; 398 399 evenTbl = &DecodeTable[0]; 400 oddTbl = &DecodeTable[629]; 401 incrTbl = &DecodeTable[1258]; 402 403 idByte1 = (tblpos + 0x275); 404 array01[idByte1] += 1; 405 406 if (incrTbl[idByte1] != 1) 407 { 408 tmpIncrTbl = &incrTbl[idByte1]; 409 idByte2 = *tmpIncrTbl; 410 411 if (idByte1 == evenTbl[idByte2]) { 412 CheckTable(idByte1, oddTbl[idByte2], idByte1); 413 } 414 else { 415 CheckTable(idByte1, evenTbl[idByte2], idByte1); 416 } 417 418 do 419 { 420 incrIdx = incrTbl[idByte2]; 421 evenVal = evenTbl[incrIdx]; 422 423 if (idByte2 == evenVal) { 424 idByte3 = oddTbl[incrIdx]; 425 } 426 else { 427 idByte3 = evenVal; 428 } 429 430 if (array01[idByte3] < array01[idByte1]) 431 { 432 if (idByte2 == evenVal) { 433 oddTbl[incrIdx] = (short)idByte1; 434 } 435 else { 436 evenTbl[incrIdx] = (short)idByte1; 437 } 438 439 evenVal = evenTbl[idByte2]; 440 441 if (idByte1 == evenVal) { 442 idByte4 = oddTbl[idByte2]; 443 evenTbl[idByte2] = (short)idByte3; 444 } 445 else { 446 idByte4 = evenVal; 447 oddTbl[idByte2] = (short)idByte3; 448 } 449 450 incrTbl[idByte3] = (short)idByte2; 451 452 *tmpIncrTbl = (short)incrIdx; 453 CheckTable(idByte3, idByte4, idByte4); 454 455 tmpIncrTbl = &incrTbl[idByte3]; 456 } 457 458 idByte1 = *tmpIncrTbl; 459 tmpIncrTbl = &incrTbl[idByte1]; 460 461 idByte2 = *tmpIncrTbl; 462 } while (idByte2 != 1); 463 } 464 } 465 466 /* 467 ======================== 468 = 469 = StartDecodeByte 470 = 471 ======================== 472 */ 473 474 static int StartDecodeByte(void) // 8002D904 475 { 476 int lookup; 477 short* evenTbl; 478 short* oddTbl; 479 480 lookup = 1; 481 482 evenTbl = &DecodeTable[0]; 483 oddTbl = &DecodeTable[629]; 484 485 while (lookup < 0x275) { 486 if (ReadBinary() == 0) { 487 lookup = evenTbl[lookup]; 488 } 489 else { 490 lookup = oddTbl[lookup]; 491 } 492 } 493 494 lookup = (lookup + -0x275); 495 UpdateTables(lookup); 496 497 return lookup; 498 } 499 500 /* 501 ======================== 502 = 503 = InsertNodeDirectory 504 = routine required for encoding 505 = 506 ======================== 507 */ 508 509 void InsertNodeDirectory(int start) // 8002D990 510 { 511 int hashKey = ((window[start % windowSize] ^ (window[(start + 1) % windowSize] << 4)) ^ (window[(start + 2) % windowSize] << 8)) & (HASH_SIZE - 1); 512 513 if (hashtable[hashKey] == -1) { 514 hashtarget[hashKey] = start; 515 hashNext[start] = -1; 516 } 517 else { 518 hashNext[start] = hashtable[hashKey]; 519 hashPrev[hashtable[hashKey]] = start; 520 } 521 522 hashtable[hashKey] = start; 523 hashPrev[start] = -1; 524 } 525 526 /* 527 ======================== 528 = 529 = DeleteNodeDirectory 530 = routine required for encoding 531 = 532 ======================== 533 */ 534 535 void DeleteNodeDirectory(int start) // 8002DAD0 536 { 537 int hashKey = ((window[start % windowSize] ^ (window[(start + 1) % windowSize] << 4)) ^ (window[(start + 2) % windowSize] << 8)) & (HASH_SIZE - 1); 538 539 if (hashtable[hashKey] == hashtarget[hashKey]) { 540 hashtable[hashKey] = -1; 541 } 542 else { 543 hashNext[hashPrev[hashtarget[hashKey]]] = -1; 544 hashtarget[hashKey] = hashPrev[hashtarget[hashKey]]; 545 } 546 } 547 548 /* 549 ======================== 550 = 551 = FindMatch 552 = routine required for encoding 553 = 554 ======================== 555 */ 556 557 558 int FindMatch(int start, int count) // 8002DC0C 559 { 560 int encodedlen; 561 int offset; 562 int i; 563 int samelen; 564 int next; 565 int curr; 566 int encodedpos; 567 int hashKey; 568 569 encodedlen = 0; 570 if (start == windowSize) { 571 start = 0; 572 } 573 574 hashKey = ((window[start % windowSize] ^ (window[(start + 1) % windowSize] << 4)) ^ (window[(start + 2) % windowSize] << 8)) & (HASH_SIZE - 1); 575 576 offset = hashtable[hashKey]; 577 578 i = 0; 579 while (offset != -1) 580 { 581 if (++i > count) { 582 break; 583 } 584 585 if ((window[(start + encodedlen) % windowSize]) == (window[(offset + encodedlen) % windowSize])) 586 { 587 samelen = 0; 588 curr = start; 589 next = offset; 590 591 while (window[curr] == window[next]) { 592 if (samelen >= 64) { 593 break; 594 } 595 if (next == start) { 596 break; 597 } 598 if (curr == encArgs.incrBit) { 599 break; 600 } 601 ++samelen; 602 if (++curr == windowSize) { 603 curr = 0; 604 } 605 if (++next == windowSize) { 606 next = 0; 607 } 608 } 609 610 encodedpos = start - offset; 611 if (encodedpos < 0) { 612 encodedpos += windowSize; 613 } 614 encodedpos -= samelen; 615 if ((encArgs.unk1) && (encodedpos > offsetTable[6])) { 616 break; 617 } 618 619 if (encodedlen < samelen && encodedpos <= offsetMaxSize && (samelen > 3 || offsetTable[6 + (encArgs.type + 3)] >= encodedpos)) { 620 encodedlen = samelen; 621 encArgs.offset = encodedpos; 622 } 623 } 624 625 offset = hashNext[offset]; // try next in list 626 } 627 return encodedlen; 628 } 629 630 631 /* 632 ======================== 633 = 634 = FUN_8002df14 635 = unknown Function 636 = 637 ======================== 638 */ 639 640 void FUN_8002df14(void) // 8002DF14 641 { 642 byte byte_val; 643 644 int i, j, k; 645 byte* curPtr; 646 byte* nextPtr; 647 byte* next2Ptr; 648 649 curPtr = &window[0]; 650 651 k = 0; 652 j = 0; 653 i = 1; 654 do 655 { 656 nextPtr = &window[j]; 657 if (curPtr[0] == 10) 658 { 659 j = i; 660 if (nextPtr[0] == curPtr[1]) 661 { 662 next2Ptr = &window[i + 1]; 663 do 664 { 665 nextPtr++; 666 byte_val = *next2Ptr++; 667 k++; 668 } while (*nextPtr == byte_val); 669 } 670 } 671 curPtr++; 672 i++; 673 } while (i != 67); 674 675 if (k >= 16) { 676 encArgs.unk1 = 1; 677 } 678 } 679 680 681 /* 682 ======================== 683 = 684 = DecodeD64 685 = 686 = Exclusive Doom 64 687 = 688 ======================== 689 */ 690 691 void DecodeD64(unsigned char* input, unsigned char* output) // 8002DFA0 692 { 693 int copyPos, storePos; 694 int dec_byte, resc_byte; 695 int incrBit, copyCnt, shiftPos, j; 696 697 //PRINTF_D2(WHITE, 0, 15, "DecodeD64"); 698 699 InitTables(); 700 701 OVERFLOW_READ = MAXINT; 702 OVERFLOW_WRITE = MAXINT; 703 704 incrBit = 0; 705 706 buffers.input = buffers.istart = input; 707 buffers.output = buffers.ostart = output; 708 709 window = (byte *)Z_Alloc(windowSize, PU_STATIC, NULL); 710 711 dec_byte = StartDecodeByte(); 712 713 while (dec_byte != 256) 714 { 715 if (dec_byte < 256) 716 { 717 /* Decode the data directly using binary data code */ 718 719 WriteByte((byte)(dec_byte & 0xff)); 720 window[incrBit] = (byte)dec_byte; 721 722 /* Resets the count once the memory limit is exceeded in allocPtr, 723 so to speak resets it at startup for reuse */ 724 incrBit += 1; 725 if (incrBit == windowSize) { 726 incrBit = 0; 727 } 728 } 729 else 730 { 731 /* Decode the data using binary data code, 732 a count is obtained for the repeated data, 733 positioning itself in the root that is being stored in allocPtr previously. */ 734 735 /* A number is obtained from a range from 0 to 5, 736 necessary to obtain a shift value in the ShiftTable*/ 737 shiftPos = (dec_byte + -257) / 62; 738 739 /* Get a count number for data to copy */ 740 copyCnt = (dec_byte - (shiftPos * 62)) + -254; 741 742 /* To start copying data, you receive a position number 743 that you must sum with the position of table tableVar01 */ 744 resc_byte = ReadCodeBinary(ShiftTable[shiftPos]); 745 746 /* with this formula the exact position is obtained 747 to start copying previously stored data */ 748 copyPos = incrBit - ((offsetTable[shiftPos] + resc_byte) + copyCnt); 749 750 if (copyPos < 0) { 751 copyPos += windowSize; 752 } 753 754 storePos = incrBit; 755 756 for (j = 0; j < copyCnt; j++) 757 { 758 /* write the copied data */ 759 WriteByte(window[copyPos]); 760 761 /* save copied data at current position in memory allocPtr */ 762 window[storePos] = window[copyPos]; 763 764 storePos++; /* advance to next allocPtr memory block to store */ 765 copyPos++; /* advance to next allocPtr memory block to copy */ 766 767 /* reset the position of storePos once the memory limit is exceeded */ 768 if (storePos == windowSize) { 769 storePos = 0; 770 } 771 772 /* reset the position of copyPos once the memory limit is exceeded */ 773 if (copyPos == windowSize) { 774 copyPos = 0; 775 } 776 } 777 778 /* Resets the count once the memory limit is exceeded in allocPtr, 779 so to speak resets it at startup for reuse */ 780 incrBit += copyCnt; 781 if (incrBit >= windowSize) { 782 incrBit -= windowSize; 783 } 784 } 785 786 dec_byte = StartDecodeByte(); 787 } 788 789 Z_Free(window); 790 791 //PRINTF_D2(WHITE, 0, 21, "DecodeD64:End"); 792 } 793 794 // ENCODE MODE BY GEC Erick Vasquez Garcia (ERICK194) 795 // Updated version, compresses too fast and exact. 796 797 void StartEncodeCode(int lookup) 798 { 799 // Encodes data from a table 800 int lookupCode, lookupCheck; 801 short* oddTbl; 802 short* incrTbl; 803 int binCnt = 0; 804 byte binary[64]; 805 //static std::vector<byte> binary; 806 807 //binary.clear(); 808 oddTbl = &DecodeTable[629]; 809 incrTbl = &DecodeTable[1258]; 810 811 lookupCode = lookup + 0x275; 812 while (1) { 813 814 if (lookupCode <= 1) { break; } 815 816 lookupCheck = oddTbl[incrTbl[lookupCode]]; 817 818 //binary.push_back((lookupCheck == lookupCode) ? 1 : 0); 819 binary[binCnt++] = (lookupCheck == lookupCode) ? 1 : 0; 820 821 lookupCode = incrTbl[lookupCode]; 822 }; 823 824 // Write bits in bytes 825 while (binCnt) { 826 WriteBinary(binary[--binCnt]); 827 } 828 829 /*auto it = binary.rbegin(); 830 for (int k = 0; k < (int)binary.size(); k++) { 831 WriteBinary(*it++); 832 }*/ 833 834 // Update table 835 UpdateTables(lookup); 836 } 837 838 unsigned char* EncodeD64(unsigned char* input, int inputlen, int* size) { 839 int i, readPos, nodePos, looKupCode, byteData; 840 int cpyCountNext, cpyCount, cntMin, cntMax; 841 boolean deleteNode, skipCopy; 842 843 unsigned char* output = (unsigned char*)Z_Alloc(inputlen * 2, PU_STATIC, NULL); 844 845 InitTables(); 846 847 OVERFLOW_READ = inputlen; 848 OVERFLOW_WRITE = inputlen * 2; 849 850 deleteNode = false; 851 skipCopy = false; 852 readPos = encArgs.incrBit; 853 nodePos = 0; 854 855 buffers.input = buffers.istart = input; 856 buffers.output = buffers.ostart = output; 857 858 hashtable = (short*)Z_Alloc(HASH_SIZE * sizeof(short), PU_STATIC, NULL); 859 hashtarget = (short*)Z_Alloc(HASH_SIZE * sizeof(short), PU_STATIC, NULL); 860 hashNext = (short*)Z_Alloc(windowSize * sizeof(short), PU_STATIC, NULL); 861 hashPrev = (short*)Z_Alloc(windowSize * sizeof(short), PU_STATIC, NULL); 862 D_memset(hashNext, 0, windowSize * sizeof(short)); 863 D_memset(hashPrev, 0, windowSize * sizeof(short)); 864 865 window = (byte*)Z_Alloc(windowSize * sizeof(byte), PU_STATIC, NULL); 866 D_memset(window, 0, windowSize * sizeof(byte)); 867 868 // Initializes hash encoding tables 869 for (i = 0; i < HASH_SIZE; i++) { 870 hashtable[i] = -1; 871 hashtarget[i] = -1; 872 } 873 874 // Copy the first 3 bytes in the data window 875 for (i = 0; i < encArgs.incrBit; i++) { 876 byteData = ReadByte(); 877 if (byteData != -1) { 878 // Encode a simple byte data. 879 StartEncodeCode(byteData); 880 window[i] = byteData; 881 } 882 } 883 884 if (GetReadSize() < OVERFLOW_READ) { // Does not copy any data if the input data reached the limit 885 // Copy the first 64 bytes in the data window 886 for (i = 0; i < 64; i++) { 887 byteData = ReadByte(); 888 889 // For some unknown reason if a byte is greater than or equal to 128 the form of the encoding changes 890 // This happens depending on the file an example the BLANK and SPACEO texture results in 0 891 // Textures such as C101, result in 1 892 // MAP01, result in 1 893 if (byteData >= 128) { 894 encArgs.type = 1; 895 } 896 897 if (byteData != -1) { 898 window[encArgs.incrBit++] = byteData; 899 } 900 } 901 } 902 903 // Determines the number of bytes to compare 904 cntMin = (encArgs.type == 1) ? 20 : 50; 905 cntMax = (encArgs.type == 1) ? 200 : 1000; 906 907 if (GetReadSize() < OVERFLOW_READ) { // Does not encode any data if the input data reached the limit 908 909 while (readPos != encArgs.incrBit) { 910 // Add the data in the node directory table 911 // update the hash table 912 InsertNodeDirectory(nodePos); 913 914 if (!skipCopy) { 915 916 cpyCountNext = FindMatch(readPos + 1, cntMin); 917 cpyCount = FindMatch(readPos, cntMax); 918 919 //printf("cpyCount %d\n", cpyCount); 920 //printf("cpyCountNext %d\n", cpyCountNext); 921 922 // Check if there is a possibility to copy the data by routes 923 if (cpyCount >= 3 && cpyCount >= cpyCountNext) { 924 925 int count = cpyCount; 926 int ValExtra = encArgs.offset; 927 int Shift = 0x04; 928 929 if ((ValExtra >= offsetTable[1]) && (ValExtra < offsetTable[2])) 930 { 931 Shift = 0x06; 932 ValExtra -= offsetTable[1]; 933 } 934 if ((ValExtra >= offsetTable[2]) && (ValExtra < offsetTable[3])) 935 { 936 Shift = 0x08; 937 ValExtra -= offsetTable[2]; 938 } 939 if ((ValExtra >= offsetTable[3]) && (ValExtra < offsetTable[4])) 940 { 941 Shift = 0x0A; 942 ValExtra -= offsetTable[3]; 943 } 944 if ((ValExtra >= offsetTable[4]) && (ValExtra < offsetTable[5])) 945 { 946 Shift = 0x0C; 947 ValExtra -= offsetTable[4]; 948 } 949 if ((ValExtra >= offsetTable[5])) 950 { 951 Shift = 0x0E; 952 ValExtra -= offsetTable[5]; 953 } 954 955 if (Shift == 0x04) { looKupCode = (0x0101 + (count - 3)); } 956 else if (Shift == 0x06) { looKupCode = (0x013F + (count - 3)); } 957 else if (Shift == 0x08) { looKupCode = (0x017D + (count - 3)); } 958 else if (Shift == 0x0A) { looKupCode = (0x01BB + (count - 3)); } 959 else if (Shift == 0x0C) { looKupCode = (0x01F9 + (count - 3)); } 960 else if (Shift == 0x0E) { looKupCode = (0x0237 + (count - 3)); } 961 962 //printf("Code 0x%04X ValExtra 0x%04X\n", LooKupCode2, ValExtra); 963 964 // Writes the startup code and address to copy data from the data window. 965 StartEncodeCode(looKupCode); 966 // Writes the amount of data to copy from the data window. 967 WriteCodeBinary(ValExtra, Shift); 968 969 skipCopy = true; 970 } 971 else { // Encode a simple byte data. 972 StartEncodeCode(window[readPos]); 973 } 974 } 975 976 // Skip copy data 977 if (--cpyCount == 0) { 978 skipCopy = false; 979 } 980 981 // Advance to the next position to check in matching 982 if (++readPos == windowSize) { 983 readPos = 0; 984 } 985 986 // Advance to the next position to add to the nodes of the directory 987 if (++nodePos == windowSize) { 988 nodePos = 0; 989 } 990 991 // Copy input data to the data window 992 if (GetReadSize() < OVERFLOW_READ) { // Does not copy any data if the input data reached the limit 993 byteData = ReadByte(); 994 if (byteData != -1) { 995 window[encArgs.incrBit++] = byteData; 996 } 997 998 // Enables the deletion of nodes in the directory once the first block of the data window is reached 999 if (encArgs.incrBit == windowSize) { 1000 encArgs.incrBit = 0; 1001 deleteNode = true; 1002 } 1003 } 1004 1005 // Delete the data in the node directory table 1006 if (deleteNode && GetReadSize() < OVERFLOW_READ) { 1007 DeleteNodeDirectory(encArgs.incrBit); 1008 } 1009 } 1010 } 1011 1012 // Write the code to finish the encoding 1013 StartEncodeCode(0x100); 1014 FlushBitBuffer(); 1015 1016 *size = GetOutputSize(); 1017 1018 Z_Free(hashtable); 1019 Z_Free(hashtarget); 1020 Z_Free(hashNext); 1021 Z_Free(hashPrev); 1022 Z_Free(window); 1023 1024 return output; 1025 } 1026 1027 /* 1028 == == == == == == == == == == 1029 = 1030 = DecodeJaguar (decode original name) 1031 = 1032 = Exclusive Psx Doom / Doom 64 from Jaguar Doom 1033 = 1034 == == == == == == == == == == 1035 */ 1036 1037 #define WINDOW_SIZE 4096 1038 #define LOOKAHEAD_SIZE 16 1039 1040 #define LENSHIFT 4 /* this must be log2(LOOKAHEAD_SIZE) */ 1041 1042 void DecodeJaguar(unsigned char *input, unsigned char *output) // 8002E1f4 1043 { 1044 int getidbyte = 0; 1045 int len; 1046 int pos; 1047 int i; 1048 unsigned char *source; 1049 int idbyte = 0; 1050 1051 while (1) 1052 { 1053 /* get a new idbyte if necessary */ 1054 if (!getidbyte) idbyte = *input++; 1055 getidbyte = (getidbyte + 1) & 7; 1056 1057 if (idbyte & 1) 1058 { 1059 /* decompress */ 1060 pos = *input++ << LENSHIFT; 1061 pos = pos | (*input >> LENSHIFT); 1062 source = output - pos - 1; 1063 len = (*input++ & 0xf) + 1; 1064 if (len == 1) break; 1065 1066 //for (i = 0; i<len; i++) 1067 //*output++ = *source++; 1068 1069 i = 0; 1070 if (len > 0) 1071 { 1072 if ((len & 3)) 1073 { 1074 while(i != (len & 3)) 1075 { 1076 *output++ = *source++; 1077 i++; 1078 } 1079 } 1080 while(i != len) 1081 { 1082 output[0] = source[0]; 1083 output[1] = source[1]; 1084 output[2] = source[2]; 1085 output[3] = source[3]; 1086 output += 4; 1087 source += 4; 1088 i += 4; 1089 } 1090 } 1091 } 1092 else 1093 { 1094 *output++ = *input++; 1095 } 1096 1097 idbyte = idbyte >> 1; 1098 } 1099 }