Rename Hyrule Magic compression functions; update deprecation notes
This commit is contained in:
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "absl/strings/str_cat.h"
|
|
||||||
#include "app/core/constants.h"
|
#include "app/core/constants.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
@@ -15,9 +14,287 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
namespace lc_lz2 {
|
// Hyrule Magic
|
||||||
|
uint8_t* HyruleMagicCompress(uint8_t const* const src, int const oldsize,
|
||||||
|
int* const size, int const flag) {
|
||||||
|
unsigned char* b2 =
|
||||||
|
(unsigned char*)malloc(0x1000); // allocate a 2^12 sized buffer
|
||||||
|
|
||||||
// Compression commands
|
int i, j, k, l, m = 0, n, o = 0, bd = 0, p, q = 0, r;
|
||||||
|
|
||||||
|
for (i = 0; i < oldsize;) {
|
||||||
|
l = src[i]; // grab a char from the buffer.
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
|
||||||
|
r = !!q; // r = the same logical value (0 or 1) as q, but not the same
|
||||||
|
// value necesarily.
|
||||||
|
|
||||||
|
for (j = 0; j < i - 1; j++) {
|
||||||
|
if (src[j] == l) {
|
||||||
|
m = oldsize - j;
|
||||||
|
|
||||||
|
for (n = 0; n < m; n++)
|
||||||
|
if (src[n + j] != src[n + i]) break;
|
||||||
|
|
||||||
|
if (n > k) k = n, o = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = i + 1; n < oldsize; n++) {
|
||||||
|
if (src[n] != l) {
|
||||||
|
// look for chars identical to the first one.
|
||||||
|
// stop if we can't find one.
|
||||||
|
// n will reach i+k+1 for some k >= 0.
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n -= i; // offset back by i. i.e. n = k+1 as above.
|
||||||
|
|
||||||
|
if (n > 1 + r)
|
||||||
|
p = 1;
|
||||||
|
else {
|
||||||
|
m = src[i + 1];
|
||||||
|
|
||||||
|
for (n = i + 2; n < oldsize; n++) {
|
||||||
|
if (src[n] != l) break;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (src[n] != m) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
n -= i;
|
||||||
|
|
||||||
|
if (n > 2 + r)
|
||||||
|
p = 2;
|
||||||
|
else {
|
||||||
|
m = oldsize - i;
|
||||||
|
|
||||||
|
for (n = 1; n < m; n++)
|
||||||
|
if (src[i + n] != l + n) break;
|
||||||
|
|
||||||
|
if (n > 1 + r)
|
||||||
|
p = 3;
|
||||||
|
else
|
||||||
|
p = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k > 3 + r && k > n + (p & 1)) p = 4, n = k;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
q++, i++;
|
||||||
|
else {
|
||||||
|
if (q) {
|
||||||
|
q--;
|
||||||
|
|
||||||
|
if (q > 31) {
|
||||||
|
b2[bd++] = (unsigned char)(224 + (q >> 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
b2[bd++] = (unsigned char)q;
|
||||||
|
q++;
|
||||||
|
|
||||||
|
memcpy(b2 + bd, src + i - q, q);
|
||||||
|
|
||||||
|
bd += q;
|
||||||
|
q = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += n;
|
||||||
|
n--;
|
||||||
|
|
||||||
|
if (n > 31) {
|
||||||
|
b2[bd++] = (unsigned char)(224 + (n >> 8) + (p << 2));
|
||||||
|
b2[bd++] = (unsigned char)n;
|
||||||
|
} else
|
||||||
|
b2[bd++] = (unsigned char)((p << 5) + n);
|
||||||
|
|
||||||
|
switch (p) {
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
b2[bd++] = (unsigned char)l;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
b2[bd++] = (unsigned char)l;
|
||||||
|
b2[bd++] = (unsigned char)m;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if (flag) {
|
||||||
|
b2[bd++] = (unsigned char)(o >> 8);
|
||||||
|
b2[bd++] = (unsigned char)o;
|
||||||
|
} else {
|
||||||
|
b2[bd++] = (unsigned char)o;
|
||||||
|
b2[bd++] = (unsigned char)(o >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (q) {
|
||||||
|
q--;
|
||||||
|
|
||||||
|
if (q > 31) {
|
||||||
|
b2[bd++] = (unsigned char)(224 + (q >> 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
b2[bd++] = (unsigned char)q;
|
||||||
|
q++;
|
||||||
|
|
||||||
|
memcpy(b2 + bd, src + i - q, q);
|
||||||
|
|
||||||
|
bd += q;
|
||||||
|
}
|
||||||
|
|
||||||
|
b2[bd++] = 255;
|
||||||
|
b2 = (unsigned char*)realloc(b2, bd);
|
||||||
|
*size = bd;
|
||||||
|
|
||||||
|
return b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* HyruleMagicDecompress(uint8_t const* src, int* const size,
|
||||||
|
int const p_big_endian) {
|
||||||
|
unsigned char* b2 = (unsigned char*)malloc(1024);
|
||||||
|
|
||||||
|
int bd = 0, bs = 1024;
|
||||||
|
|
||||||
|
unsigned char a;
|
||||||
|
unsigned char b;
|
||||||
|
unsigned short c, d;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
// retrieve a uchar from the buffer.
|
||||||
|
a = *(src++);
|
||||||
|
|
||||||
|
// end the decompression routine if we encounter 0xff.
|
||||||
|
if (a == 0xff) break;
|
||||||
|
|
||||||
|
// examine the top 3 bits of a.
|
||||||
|
b = (a >> 5);
|
||||||
|
|
||||||
|
if (b == 7) // i.e. 0b 111
|
||||||
|
{
|
||||||
|
// get bits 0b 0001 1100
|
||||||
|
b = ((a >> 2) & 7);
|
||||||
|
|
||||||
|
// get bits 0b 0000 0011, multiply by 256, OR with the next byte.
|
||||||
|
c = ((a & 0x0003) << 8);
|
||||||
|
c |= *(src++);
|
||||||
|
} else
|
||||||
|
// or get bits 0b 0001 1111
|
||||||
|
c = (uint16_t)(a & 31);
|
||||||
|
|
||||||
|
c++;
|
||||||
|
|
||||||
|
if ((bd + c) > (bs - 512)) {
|
||||||
|
// need to increase the buffer size.
|
||||||
|
bs += 1024;
|
||||||
|
b2 = (uint8_t*)realloc(b2, bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7 was handled, here we handle other decompression codes.
|
||||||
|
|
||||||
|
switch (b) {
|
||||||
|
case 0: // 0b 000
|
||||||
|
|
||||||
|
// raw copy
|
||||||
|
|
||||||
|
// copy info from the src buffer to our new buffer,
|
||||||
|
// at offset bd (which we'll be increasing;
|
||||||
|
memcpy(b2 + bd, src, c);
|
||||||
|
|
||||||
|
// increment the src pointer accordingly.
|
||||||
|
src += c;
|
||||||
|
|
||||||
|
bd += c;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // 0b 001
|
||||||
|
|
||||||
|
// rle copy
|
||||||
|
|
||||||
|
// make c duplicates of one byte, inc the src pointer.
|
||||||
|
memset(b2 + bd, *(src++), c);
|
||||||
|
|
||||||
|
// increase the b2 offset.
|
||||||
|
bd += c;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // 0b 010
|
||||||
|
|
||||||
|
// rle 16-bit alternating copy
|
||||||
|
|
||||||
|
d = core::ldle16b(src);
|
||||||
|
|
||||||
|
src += 2;
|
||||||
|
|
||||||
|
while (c > 1) {
|
||||||
|
// copy that 16-bit number c/2 times into the b2 buffer.
|
||||||
|
core::stle16b(b2 + bd, d);
|
||||||
|
|
||||||
|
bd += 2;
|
||||||
|
c -= 2; // hence c/2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c) // if there's a remainder of c/2, this handles it.
|
||||||
|
b2[bd++] = (char)d;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // 0b 011
|
||||||
|
|
||||||
|
// incrementing copy
|
||||||
|
|
||||||
|
// get the current src byte.
|
||||||
|
a = *(src++);
|
||||||
|
|
||||||
|
while (c--) {
|
||||||
|
// increment that byte and copy to b2 in c iterations.
|
||||||
|
// e.g. a = 4, b2 will have 4,5,6,7,8... written to it.
|
||||||
|
b2[bd++] = a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // 0b 100, 101, 110
|
||||||
|
|
||||||
|
// lz copy
|
||||||
|
|
||||||
|
if (p_big_endian) {
|
||||||
|
d = (*src << 8) + src[1];
|
||||||
|
} else {
|
||||||
|
d = core::ldle16b(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (c--) {
|
||||||
|
// copy from a different location in the buffer.
|
||||||
|
b2[bd++] = b2[d++];
|
||||||
|
}
|
||||||
|
|
||||||
|
src += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b2 = (unsigned char*)realloc(b2, bd);
|
||||||
|
|
||||||
|
if (size) (*size) = bd;
|
||||||
|
|
||||||
|
// return the unsigned char* buffer b2, which contains the uncompressed data.
|
||||||
|
return b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace lc_lz2 {
|
||||||
|
|
||||||
void PrintCompressionPiece(const CompressionPiecePointer& piece) {
|
void PrintCompressionPiece(const CompressionPiecePointer& piece) {
|
||||||
std::cout << "Command: " << std::to_string(piece->command) << "\n";
|
std::cout << "Command: " << std::to_string(piece->command) << "\n";
|
||||||
@@ -590,286 +867,6 @@ absl::StatusOr<std::vector<uint8_t>> CompressV2(const uchar* data,
|
|||||||
return CreateCompressionString(compressed_chain_start->next, mode);
|
return CreateCompressionString(compressed_chain_start->next, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hyrule Magic
|
|
||||||
uint8_t* Compress(uint8_t const* const src, int const oldsize, int* const size,
|
|
||||||
int const flag) {
|
|
||||||
unsigned char* b2 =
|
|
||||||
(unsigned char*)malloc(0x1000); // allocate a 2^12 sized buffer
|
|
||||||
|
|
||||||
int i, j, k, l, m = 0, n, o = 0, bd = 0, p, q = 0, r;
|
|
||||||
|
|
||||||
for (i = 0; i < oldsize;) {
|
|
||||||
l = src[i]; // grab a char from the buffer.
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
|
|
||||||
r = !!q; // r = the same logical value (0 or 1) as q, but not the same
|
|
||||||
// value necesarily.
|
|
||||||
|
|
||||||
for (j = 0; j < i - 1; j++) {
|
|
||||||
if (src[j] == l) {
|
|
||||||
m = oldsize - j;
|
|
||||||
|
|
||||||
for (n = 0; n < m; n++)
|
|
||||||
if (src[n + j] != src[n + i]) break;
|
|
||||||
|
|
||||||
if (n > k) k = n, o = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n = i + 1; n < oldsize; n++) {
|
|
||||||
if (src[n] != l) {
|
|
||||||
// look for chars identical to the first one.
|
|
||||||
// stop if we can't find one.
|
|
||||||
// n will reach i+k+1 for some k >= 0.
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n -= i; // offset back by i. i.e. n = k+1 as above.
|
|
||||||
|
|
||||||
if (n > 1 + r)
|
|
||||||
p = 1;
|
|
||||||
else {
|
|
||||||
m = src[i + 1];
|
|
||||||
|
|
||||||
for (n = i + 2; n < oldsize; n++) {
|
|
||||||
if (src[n] != l) break;
|
|
||||||
|
|
||||||
n++;
|
|
||||||
|
|
||||||
if (src[n] != m) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
n -= i;
|
|
||||||
|
|
||||||
if (n > 2 + r)
|
|
||||||
p = 2;
|
|
||||||
else {
|
|
||||||
m = oldsize - i;
|
|
||||||
|
|
||||||
for (n = 1; n < m; n++)
|
|
||||||
if (src[i + n] != l + n) break;
|
|
||||||
|
|
||||||
if (n > 1 + r)
|
|
||||||
p = 3;
|
|
||||||
else
|
|
||||||
p = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k > 3 + r && k > n + (p & 1)) p = 4, n = k;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
q++, i++;
|
|
||||||
else {
|
|
||||||
if (q) {
|
|
||||||
q--;
|
|
||||||
|
|
||||||
if (q > 31) {
|
|
||||||
b2[bd++] = (unsigned char)(224 + (q >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
b2[bd++] = (unsigned char)q;
|
|
||||||
q++;
|
|
||||||
|
|
||||||
memcpy(b2 + bd, src + i - q, q);
|
|
||||||
|
|
||||||
bd += q;
|
|
||||||
q = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += n;
|
|
||||||
n--;
|
|
||||||
|
|
||||||
if (n > 31) {
|
|
||||||
b2[bd++] = (unsigned char)(224 + (n >> 8) + (p << 2));
|
|
||||||
b2[bd++] = (unsigned char)n;
|
|
||||||
} else
|
|
||||||
b2[bd++] = (unsigned char)((p << 5) + n);
|
|
||||||
|
|
||||||
switch (p) {
|
|
||||||
case 1:
|
|
||||||
case 3:
|
|
||||||
b2[bd++] = (unsigned char)l;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
b2[bd++] = (unsigned char)l;
|
|
||||||
b2[bd++] = (unsigned char)m;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
if (flag) {
|
|
||||||
b2[bd++] = (unsigned char)(o >> 8);
|
|
||||||
b2[bd++] = (unsigned char)o;
|
|
||||||
} else {
|
|
||||||
b2[bd++] = (unsigned char)o;
|
|
||||||
b2[bd++] = (unsigned char)(o >> 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (q) {
|
|
||||||
q--;
|
|
||||||
|
|
||||||
if (q > 31) {
|
|
||||||
b2[bd++] = (unsigned char)(224 + (q >> 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
b2[bd++] = (unsigned char)q;
|
|
||||||
q++;
|
|
||||||
|
|
||||||
memcpy(b2 + bd, src + i - q, q);
|
|
||||||
|
|
||||||
bd += q;
|
|
||||||
}
|
|
||||||
|
|
||||||
b2[bd++] = 255;
|
|
||||||
b2 = (unsigned char*)realloc(b2, bd);
|
|
||||||
*size = bd;
|
|
||||||
|
|
||||||
return b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* Uncompress(uint8_t const* src, int* const size,
|
|
||||||
int const p_big_endian) {
|
|
||||||
unsigned char* b2 = (unsigned char*)malloc(1024);
|
|
||||||
|
|
||||||
int bd = 0, bs = 1024;
|
|
||||||
|
|
||||||
unsigned char a;
|
|
||||||
unsigned char b;
|
|
||||||
unsigned short c, d;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
// retrieve a uchar from the buffer.
|
|
||||||
a = *(src++);
|
|
||||||
|
|
||||||
// end the decompression routine if we encounter 0xff.
|
|
||||||
if (a == 0xff) break;
|
|
||||||
|
|
||||||
// examine the top 3 bits of a.
|
|
||||||
b = (a >> 5);
|
|
||||||
|
|
||||||
if (b == 7) // i.e. 0b 111
|
|
||||||
{
|
|
||||||
// get bits 0b 0001 1100
|
|
||||||
b = ((a >> 2) & 7);
|
|
||||||
|
|
||||||
// get bits 0b 0000 0011, multiply by 256, OR with the next byte.
|
|
||||||
c = ((a & 0x0003) << 8);
|
|
||||||
c |= *(src++);
|
|
||||||
} else
|
|
||||||
// or get bits 0b 0001 1111
|
|
||||||
c = (uint16_t)(a & 31);
|
|
||||||
|
|
||||||
c++;
|
|
||||||
|
|
||||||
if ((bd + c) > (bs - 512)) {
|
|
||||||
// need to increase the buffer size.
|
|
||||||
bs += 1024;
|
|
||||||
b2 = (uint8_t*)realloc(b2, bs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7 was handled, here we handle other decompression codes.
|
|
||||||
|
|
||||||
switch (b) {
|
|
||||||
case 0: // 0b 000
|
|
||||||
|
|
||||||
// raw copy
|
|
||||||
|
|
||||||
// copy info from the src buffer to our new buffer,
|
|
||||||
// at offset bd (which we'll be increasing;
|
|
||||||
memcpy(b2 + bd, src, c);
|
|
||||||
|
|
||||||
// increment the src pointer accordingly.
|
|
||||||
src += c;
|
|
||||||
|
|
||||||
bd += c;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // 0b 001
|
|
||||||
|
|
||||||
// rle copy
|
|
||||||
|
|
||||||
// make c duplicates of one byte, inc the src pointer.
|
|
||||||
memset(b2 + bd, *(src++), c);
|
|
||||||
|
|
||||||
// increase the b2 offset.
|
|
||||||
bd += c;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // 0b 010
|
|
||||||
|
|
||||||
// rle 16-bit alternating copy
|
|
||||||
|
|
||||||
d = core::ldle16b(src);
|
|
||||||
|
|
||||||
src += 2;
|
|
||||||
|
|
||||||
while (c > 1) {
|
|
||||||
// copy that 16-bit number c/2 times into the b2 buffer.
|
|
||||||
core::stle16b(b2 + bd, d);
|
|
||||||
|
|
||||||
bd += 2;
|
|
||||||
c -= 2; // hence c/2
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c) // if there's a remainder of c/2, this handles it.
|
|
||||||
b2[bd++] = (char)d;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: // 0b 011
|
|
||||||
|
|
||||||
// incrementing copy
|
|
||||||
|
|
||||||
// get the current src byte.
|
|
||||||
a = *(src++);
|
|
||||||
|
|
||||||
while (c--) {
|
|
||||||
// increment that byte and copy to b2 in c iterations.
|
|
||||||
// e.g. a = 4, b2 will have 4,5,6,7,8... written to it.
|
|
||||||
b2[bd++] = a++;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // 0b 100, 101, 110
|
|
||||||
|
|
||||||
// lz copy
|
|
||||||
|
|
||||||
if (p_big_endian) {
|
|
||||||
d = (*src << 8) + src[1];
|
|
||||||
} else {
|
|
||||||
d = core::ldle16b(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (c--) {
|
|
||||||
// copy from a different location in the buffer.
|
|
||||||
b2[bd++] = b2[d++];
|
|
||||||
}
|
|
||||||
|
|
||||||
src += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b2 = (unsigned char*)realloc(b2, bd);
|
|
||||||
|
|
||||||
if (size) (*size) = bd;
|
|
||||||
|
|
||||||
// return the unsigned char* buffer b2, which contains the uncompressed data.
|
|
||||||
return b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::StatusOr<std::vector<uint8_t>> CompressGraphics(const uchar* data,
|
absl::StatusOr<std::vector<uint8_t>> CompressGraphics(const uchar* data,
|
||||||
const int pos,
|
const int pos,
|
||||||
const int length) {
|
const int length) {
|
||||||
@@ -887,9 +884,6 @@ absl::StatusOr<std::vector<uint8_t>> CompressOverworld(
|
|||||||
return CompressV3(data, pos, length, kNintendoMode1);
|
return CompressV3(data, pos, length, kNintendoMode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// Compression V3
|
|
||||||
|
|
||||||
void CheckByteRepeatV3(CompressionContext& context) {
|
void CheckByteRepeatV3(CompressionContext& context) {
|
||||||
uint pos = context.src_pos;
|
uint pos = context.src_pos;
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,13 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
|
|
||||||
|
// Hyrule Magic
|
||||||
|
uint8_t* HyruleMagicCompress(uint8_t const* const src, int const oldsize,
|
||||||
|
int* const size, int const flag);
|
||||||
|
|
||||||
|
uint8_t* HyruleMagicDecompress(uint8_t const* src, int* const size,
|
||||||
|
int const p_big_endian);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace yaze::gfx::lc_lz2
|
* @namespace yaze::gfx::lc_lz2
|
||||||
* @brief Contains the LC_LZ2 compression algorithm.
|
* @brief Contains the LC_LZ2 compression algorithm.
|
||||||
@@ -138,31 +145,33 @@ void CompressionCommandAlternativeV2(const uchar* data,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compresses a buffer of data using the LC_LZ2 algorithm.
|
* @brief Compresses a buffer of data using the LC_LZ2 algorithm.
|
||||||
* \deprecated Use Compress and Uncompress instead.
|
* \deprecated Use HyruleMagicDecompress instead.
|
||||||
*/
|
*/
|
||||||
absl::StatusOr<std::vector<uint8_t>> CompressV2(const uchar* data, const int start,
|
absl::StatusOr<std::vector<uint8_t>> CompressV2(const uchar* data,
|
||||||
const int length, int mode = 1,
|
const int start,
|
||||||
bool check = false);
|
const int length, int mode = 1,
|
||||||
|
bool check = false);
|
||||||
|
|
||||||
absl::StatusOr<std::vector<uint8_t>> CompressGraphics(const uchar* data, const int pos,
|
absl::StatusOr<std::vector<uint8_t>> CompressGraphics(const uchar* data,
|
||||||
const int length);
|
const int pos,
|
||||||
absl::StatusOr<std::vector<uint8_t>> CompressOverworld(const uchar* data, const int pos,
|
const int length);
|
||||||
const int length);
|
absl::StatusOr<std::vector<uint8_t>> CompressOverworld(const uchar* data,
|
||||||
absl::StatusOr<std::vector<uint8_t>> CompressOverworld(const std::vector<uint8_t> data,
|
const int pos,
|
||||||
const int pos, const int length);
|
const int length);
|
||||||
|
absl::StatusOr<std::vector<uint8_t>> CompressOverworld(
|
||||||
|
const std::vector<uint8_t> data, const int pos, const int length);
|
||||||
|
|
||||||
absl::StatusOr<CompressionPiecePointer> SplitCompressionPiece(
|
absl::StatusOr<CompressionPiecePointer> SplitCompressionPiece(
|
||||||
CompressionPiecePointer& piece, int mode);
|
CompressionPiecePointer& piece, int mode);
|
||||||
|
|
||||||
std::vector<uint8_t> CreateCompressionString(CompressionPiecePointer& start, int mode);
|
std::vector<uint8_t> CreateCompressionString(CompressionPiecePointer& start,
|
||||||
|
int mode);
|
||||||
|
|
||||||
absl::Status ValidateCompressionResult(CompressionPiecePointer& chain_head,
|
absl::Status ValidateCompressionResult(CompressionPiecePointer& chain_head,
|
||||||
int mode, int start, int src_data_pos);
|
int mode, int start, int src_data_pos);
|
||||||
|
|
||||||
CompressionPiecePointer MergeCopy(CompressionPiecePointer& start);
|
CompressionPiecePointer MergeCopy(CompressionPiecePointer& start);
|
||||||
|
|
||||||
// Compression V3
|
|
||||||
|
|
||||||
struct CompressionContext {
|
struct CompressionContext {
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
std::vector<uint8_t> compressed_data;
|
std::vector<uint8_t> compressed_data;
|
||||||
@@ -209,42 +218,35 @@ void FinalizeCompression(CompressionContext& context);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compresses a buffer of data using the LC_LZ2 algorithm.
|
* @brief Compresses a buffer of data using the LC_LZ2 algorithm.
|
||||||
* \deprecated Use Compress and Uncompress instead.
|
* \deprecated Use HyruleMagicCompress
|
||||||
*/
|
*/
|
||||||
absl::StatusOr<std::vector<uint8_t>> CompressV3(const std::vector<uint8_t>& data,
|
absl::StatusOr<std::vector<uint8_t>> CompressV3(
|
||||||
const int start, const int length,
|
const std::vector<uint8_t>& data, const int start, const int length,
|
||||||
int mode = 1, bool check = false);
|
int mode = 1, bool check = false);
|
||||||
|
|
||||||
// Hyrule Magic
|
|
||||||
uint8_t* Compress(uint8_t const* const src, int const oldsize, int* const size,
|
|
||||||
int const flag);
|
|
||||||
|
|
||||||
uint8_t* Uncompress(uint8_t const* src, int* const size,
|
|
||||||
int const p_big_endian);
|
|
||||||
|
|
||||||
// Decompression
|
|
||||||
|
|
||||||
std::string SetBuffer(const std::vector<uint8_t>& data, int src_pos,
|
std::string SetBuffer(const std::vector<uint8_t>& data, int src_pos,
|
||||||
int comp_accumulator);
|
int comp_accumulator);
|
||||||
std::string SetBuffer(const uchar* data, int src_pos, int comp_accumulator);
|
std::string SetBuffer(const uchar* data, int src_pos, int comp_accumulator);
|
||||||
void memfill(const uchar* data, std::vector<uint8_t>& buffer, int buffer_pos, int offset,
|
void memfill(const uchar* data, std::vector<uint8_t>& buffer, int buffer_pos,
|
||||||
int length);
|
int offset, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Decompresses a buffer of data using the LC_LZ2 algorithm.
|
* @brief Decompresses a buffer of data using the LC_LZ2 algorithm.
|
||||||
* \deprecated Use Compress and Uncompress instead.
|
* @note Works well for graphics but not overworld data. Prefer Hyrule Magic
|
||||||
|
* routines for overworld data.
|
||||||
*/
|
*/
|
||||||
absl::StatusOr<std::vector<uint8_t>> DecompressV2(const uchar* data, int offset,
|
absl::StatusOr<std::vector<uint8_t>> DecompressV2(const uchar* data, int offset,
|
||||||
int size = 0x800, int mode = 1);
|
int size = 0x800,
|
||||||
absl::StatusOr<std::vector<uint8_t>> DecompressGraphics(const uchar* data, int pos, int size);
|
int mode = 1);
|
||||||
absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(const uchar* data, int pos, int size);
|
absl::StatusOr<std::vector<uint8_t>> DecompressGraphics(const uchar* data,
|
||||||
absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(const std::vector<uint8_t> data,
|
int pos, int size);
|
||||||
int pos, int size);
|
absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(const uchar* data,
|
||||||
|
int pos, int size);
|
||||||
|
absl::StatusOr<std::vector<uint8_t>> DecompressOverworld(
|
||||||
|
const std::vector<uint8_t> data, int pos, int size);
|
||||||
|
|
||||||
} // namespace lc_lz2
|
} // namespace lc_lz2
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif // YAZE_APP_GFX_COMPRESSION_H
|
#endif // YAZE_APP_GFX_COMPRESSION_H
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ absl::Status Rom::SaveAllGraphicsData() {
|
|||||||
final_data = gfx::Bpp8SnesToIndexed(sheet_data, 8);
|
final_data = gfx::Bpp8SnesToIndexed(sheet_data, 8);
|
||||||
int size = 0;
|
int size = 0;
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
auto compressed_data = gfx::lc_lz2::Compress(
|
auto compressed_data = gfx::HyruleMagicCompress(
|
||||||
final_data.data(), final_data.size(), &size, 1);
|
final_data.data(), final_data.size(), &size, 1);
|
||||||
for (int j = 0; j < size; j++) {
|
for (int j = 0; j < size; j++) {
|
||||||
sheet_data[j] = compressed_data[j];
|
sheet_data[j] = compressed_data[j];
|
||||||
|
|||||||
@@ -542,8 +542,10 @@ absl::Status Overworld::SaveOverworldMaps() {
|
|||||||
std::vector<uint8_t> a, b;
|
std::vector<uint8_t> a, b;
|
||||||
int size_a, size_b;
|
int size_a, size_b;
|
||||||
// Compress single_map_1 and single_map_2
|
// Compress single_map_1 and single_map_2
|
||||||
auto a_char = gfx::lc_lz2::Compress(single_map_1.data(), 256, &size_a, 1);
|
auto a_char =
|
||||||
auto b_char = gfx::lc_lz2::Compress(single_map_2.data(), 256, &size_b, 1);
|
gfx::HyruleMagicCompress(single_map_1.data(), 256, &size_a, 1);
|
||||||
|
auto b_char =
|
||||||
|
gfx::HyruleMagicCompress(single_map_2.data(), 256, &size_b, 1);
|
||||||
if (a_char == nullptr || b_char == nullptr) {
|
if (a_char == nullptr || b_char == nullptr) {
|
||||||
return absl::AbortedError("Error compressing map gfx.");
|
return absl::AbortedError("Error compressing map gfx.");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user