use copy loops instead of memcpy/memmove

because different versions of gcc seem to disagree on how both of these
functions should handle overlapping memory. thanks stallman
This commit is contained in:
devinacker 2013-10-26 14:41:21 -04:00
parent e8fb851b50
commit f8ed01c458

View file

@ -158,6 +158,8 @@ size_t unpack(uint8_t *packed, uint8_t *unpacked) {
switch (command) { switch (command) {
// write uncompressed bytes // write uncompressed bytes
// (note: i had to go back to using loops for all of these because memcpy/memmove
// were both fucking up and handling these inconsistently between versions of gcc)
case 0: case 0:
memcpy(&unpacked[outpos], &packed[inpos], length); memcpy(&unpacked[outpos], &packed[inpos], length);
@ -166,30 +168,30 @@ size_t unpack(uint8_t *packed, uint8_t *unpacked) {
break; break;
// 8-bit RLE // 8-bit RLE
case 1: case 1:
unpacked[outpos] = packed[inpos++]; for (int i = 0; i < length; i++)
memcpy(&unpacked[outpos + 1], &unpacked[outpos], length - 1); unpacked[outpos++] = packed[inpos];
outpos += length; inpos++;
break; break;
// 16-bit RLE // 16-bit RLE
case 2: case 2:
unpacked[outpos] = packed[inpos]; for (int i = 0; i < length; i++) {
unpacked[outpos + 1] = packed[inpos + 1]; unpacked[outpos++] = packed[inpos];
memcpy(&unpacked[outpos + 2], &unpacked[outpos], 2 * (length - 1)); unpacked[outpos++] = packed[inpos+1];
}
outpos += (length * 2);
inpos += 2; inpos += 2;
break; break;
// 8-bit increasing sequence // 8-bit increasing sequence
case 3: case 3:
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
unpacked[outpos++] = packed[inpos] + i; unpacked[outpos++] = packed[inpos] + i;
inpos++; inpos++;
break; break;
// regular backref // regular backref
// (offset is big-endian) // (offset is big-endian)
@ -198,33 +200,33 @@ size_t unpack(uint8_t *packed, uint8_t *unpacked) {
// 7 isn't a real method number, but it behaves the same as 4 due to a quirk in how // 7 isn't a real method number, but it behaves the same as 4 due to a quirk in how
// the original decompression routine is programmed. (one of Parasyte's docs confirms // the original decompression routine is programmed. (one of Parasyte's docs confirms
// this for GB games as well). let's handle it anyway // this for GB games as well). let's handle it anyway
command = 4; command = 4;
offset = (packed[inpos] << 8) | packed[inpos+1]; offset = (packed[inpos] << 8) | packed[inpos+1];
memcpy(&unpacked[outpos], &unpacked[offset], length); for (int i = 0; i < length; i++)
unpacked[outpos++] = unpacked[offset + i];
outpos += length;
inpos += 2; inpos += 2;
break; break;
// backref with bit rotation // backref with bit rotation
// (offset is big-endian) // (offset is big-endian)
case 5: case 5:
offset = (packed[inpos] << 8) | packed[inpos+1]; offset = (packed[inpos] << 8) | packed[inpos+1];
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
unpacked[outpos++] = rotate(unpacked[offset + i]); unpacked[outpos++] = rotate(unpacked[offset + i]);
inpos += 2; inpos += 2;
break; break;
// backwards backref // backwards backref
// (offset is big-endian) // (offset is big-endian)
case 6: case 6:
offset = (packed[inpos] << 8) | packed[inpos+1]; offset = (packed[inpos] << 8) | packed[inpos+1];
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
unpacked[outpos++] = unpacked[offset - i]; unpacked[outpos++] = unpacked[offset - i];
inpos += 2; inpos += 2;
} }
// keep track of how many times each compression method is used // keep track of how many times each compression method is used