summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/file_system.c906
1 files changed, 188 insertions, 718 deletions
diff --git a/src/file_system.c b/src/file_system.c
index c709b45..4c295fc 100644
--- a/src/file_system.c
+++ b/src/file_system.c
@@ -20,8 +20,8 @@ void DecompressAT_AppendByte(char value);
void DecompressAT_Finish(void);
char DecompressAT_GetByte(int index);
-u32 DecompressAT(char *result, u32 resultLength, const char *compressedData);
-u32 DecompressATGlobal(u32 *result, u32 resultLength, const char *compressedData);
+u32 DecompressAT(char *result, s32 resultLength, const char *compressedData);
+u32 DecompressATGlobal(u32 *result, s32 resultLength, const char *compressedData);
u8 *GetSiroPtr(struct OpenedFile *);
void NDS_DecompressRLE(void *);
@@ -216,686 +216,169 @@ void nullsub_175(void)
{
}
-u32 DecompressATFile(char *result, u32 resultLength, struct OpenedFile *file)
+u32 DecompressATFile(char *result, s32 resultLength, struct OpenedFile *file)
{
return DecompressAT(result, resultLength, file->data);
}
// 800AAB4
-#ifndef NONMATCHING
-NAKED
-#endif
-u32 DecompressAT(char *result, u32 resultLength, const char *compressedData)
+u32 DecompressAT(char *result, s32 resultLength, const char *compressedData)
{
-#ifdef NONMATCHING
-
- // This function is an absolute mess, the compiler does some extremely weird things
- // which makes matching it difficult.
-
- // As-is, it's likely that this implementation is nonfunctional
- // as I've shuffled things around a lot while trying to make some parts match.
-
- int flags1;
- int flags2;
- int flags3;
- int flags4;
- int flags5;
- int flags6;
- int flags7;
- int flags8;
- int flags9;
- int compressedLength;
- char c10;
- char c11;
- u32 curIndex;
- int v12;
- char c13;
- const char *p;
- int command;
- int bytesWritten;
- int v16;
- int cmdBit;
- int currentByte;
-
- compressedLength = compressedData[5] + (compressedData[6] << 8);
- bytesWritten = 0;
- currentByte = 0;
- cmdBit = 8;
+ s32 compressedLength = compressedData[5] + (compressedData[6] << 8);
+ s32 bytesWritten = 0;
+ s32 currentByte = 0;
+ s32 cmdBit = 8;
+ s32 curIndex;
+ s32 flags[9];
+ s32 idxStart;
if (compressedData[0] == 'A'
&& compressedData[1] == 'T'
&& compressedData[2] == '4'
&& compressedData[3] == 'P') {
- if (resultLength != compressedData[0x10] + (compressedData[0x11] << 8) && resultLength != 0)
+ u32 tmp2 = compressedData[0x10] + (compressedData[0x11] << 8);
+ if (resultLength != 0 && resultLength != tmp2)
return 0;
- curIndex = 0x12;
+ idxStart = 0x12;
} else if (compressedData[0] == 'A'
&& compressedData[1] == 'T'
&& compressedData[2] == '3'
&& compressedData[3] == 'P') {
- // Can't get this to match - compiler chooses beq, b pairs instead of bne
- // I tried multiple if (... != 'x') return 0;
- // I tried != chained with ||
- // I tried == chained with &&
- // I tried nested if (... == 'x')
- // None of that produced matching code.
- curIndex = 0x10;
+ idxStart = 0x10;
} else {
return 0;
}
if (compressedData[4] == 'N') {
// uncompressed mode, unused
- int i;
- for (i = 0; i < compressedLength; i++)
- result[i] = compressedData[i + 7];
- return i;
+ for (curIndex = 0; curIndex < compressedLength; curIndex++) {
+ result[curIndex] = compressedData[curIndex + 7];
+ }
+ return curIndex;
}
- flags1 = compressedData[0x7] + 3;
- flags2 = compressedData[0x8] + 3;
- flags3 = compressedData[0x9] + 3;
- flags4 = compressedData[0xa] + 3;
- flags5 = compressedData[0xb] + 3;
- flags6 = compressedData[0xc] + 3;
- flags7 = compressedData[0xd] + 3;
- flags8 = compressedData[0xe] + 3;
- flags9 = compressedData[0xf] + 3;
-
- // Some mismatches regarding the signedness of these two conditionals, extremely fragile
+ flags[0] = compressedData[0x7] + 3;
+ flags[1] = compressedData[0x8] + 3;
+ flags[2] = compressedData[0x9] + 3;
+ flags[3] = compressedData[0xa] + 3;
+ flags[4] = compressedData[0xb] + 3;
+ flags[5] = compressedData[0xc] + 3;
+ flags[6] = compressedData[0xd] + 3;
+ flags[7] = compressedData[0xe] + 3;
+ flags[8] = compressedData[0xf] + 3;
+
+ curIndex = idxStart;
if (curIndex < compressedLength) {
- while (resultLength == 0 || bytesWritten < resultLength) {
+
+ do {
+ if (resultLength != 0 && bytesWritten >= resultLength)
+ return 0;
+
if (cmdBit == 8) {
currentByte = compressedData[curIndex++];
cmdBit = 0;
}
- if (currentByte & 0x80) { // some weird reordering happens here, couldn't figure it out
- result[bytesWritten++] = compressedData[curIndex++];
- goto end_800AE08;
- }
- p = &compressedData[curIndex];
- command = (*p >> 4) + 3;
- if (command == flags1) command = 0x1f;
- if (command == flags2) command = 0x1e;
- if (command == flags3) command = 0x1d;
- if (command == flags4) command = 0x1c;
- if (command == flags5) command = 0x1b;
- if (command == flags6) command = 0x1a;
- if (command == flags7) command = 0x19;
- if (command == flags8) command = 0x18;
- if (command == flags9) command = 0x17;
-
- switch (command) {
- case 0x1f:
- c10 = *p & 0xf;
- c10 = c10 | (c10 << 4);
- result[bytesWritten++] = c10;
- result[bytesWritten++] = c10;
- curIndex++;
- // if curIndex is incremented inside each case, the compiler leaves them inside, but if curIndex is moved after the switch
- // then it moves the second result assignment (just the 'strb' instruction) after the switch.
- // Can't figure out how to make the compiler move only one without the other.
- break;
- case 0x1e:
- v12 = *p & 0xf;
- v12 = (v12 + 1) & 0xf;
- c10 = v12;
- result[bytesWritten++] = ((*p & 0xf) << 4) | c10;
- result[bytesWritten++] = (v12 << 4) | c10;
- curIndex++;
- break;
- case 0x1d:
- c11 = *p & 0xf;
- c10 = c11 << 4;
- result[bytesWritten++] = ((c11 - 1) & 0xf) | c10;
- result[bytesWritten++] = c10 | c11;
- curIndex++;
- break;
- case 0x1c:
- v12 = *p & 0xf;
- c10 = v12;
- result[bytesWritten++] = (v12 << 4) | c10;
- result[bytesWritten++] = ((v12 & 0xf) << 4) | c10;
- v12--;
- curIndex++;
- break;
- case 0x1b:
- c10 = *p;
- c11 = c10 & 0xf;
- c13 = c11 << 4;
- result[bytesWritten++] = c13 | c11;
- c10 = (c10 & 0xf) - 1;
- result[bytesWritten++] = c13 | (c10 & 0xf);
- curIndex++;
- break;
- case 0x1a:
- v12 = ((*p & 0xf) - 1) & 0xf;
- c10 = v12;
- result[bytesWritten++] = ((*p & 0xf) << 4) | c10;
- result[bytesWritten++] = (v12 << 4) | c10;
- curIndex++;
- break;
- case 0x19:
- c11 = *p & 0xf;
- c10 = c11 << 4;
- result[bytesWritten++] = ((c11 + 1) & 0xf) | c10;
- result[bytesWritten++] = c10 | c11;
- curIndex++;
- break;
- case 0x18:
- v12 = *p & 0xf;
- c10 = v12;
- result[bytesWritten++] = (v12 << 4) | c10;
- v12++;
- curIndex++;
- result[bytesWritten++] = ((v12 & 0xf) << 4) | c10;
- break;
- case 0x17:
- c10 = *p;
- c11 = c10 & 0xf;
- c13 = c11 << 4;
- result[bytesWritten++] = c11 | c13;
- c10 = (c10 & 0xf) + 1;
- result[bytesWritten++] = c13 | (c10 & 0xf);
- curIndex++;
- break;
- default:
- v16 = curIndex + 1;
- curIndex += 2;
- v16 = ((*p & 0xf) << 8) + compressedData[v16] + (-0x1000) + bytesWritten;
- while (command) {
- result[bytesWritten++] = result[v16++];
- command--;
+ if ((currentByte & 0x80) == 0) {
+ // if bit is unset, process command
+ u32 command = (compressedData[curIndex] >> 4) + 3;
+ u32 tmp = (compressedData[curIndex] & 0xf) << 8;
+ u32 c;
+
+ if (command == flags[0]) command = 0x1f;
+ if (command == flags[1]) command = 0x1e;
+ if (command == flags[2]) command = 0x1d;
+ if (command == flags[3]) command = 0x1c;
+ if (command == flags[4]) command = 0x1b;
+ if (command == flags[5]) command = 0x1a;
+ if (command == flags[6]) command = 0x19;
+ if (command == flags[7]) command = 0x18;
+ if (command == flags[8]) command = 0x17;
+
+ switch (command) {
+ case 0x1f: { // aaaa
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ break;
+ }
+ case 0x1e: { // abbb
+ u8 byte = compressedData[curIndex];
+ c = 0xF;
+ c = byte & c;
+ curIndex++;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 1) & 0xf));
+ result[bytesWritten++] = ((((c + 1) & 0xf) << 4) | ((c + 1) & 0xf));
+ break;
+ }
+ case 0x1d: { // babb
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c - 1) & 0xf));
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ break;
+ }
+ case 0x1c: { // bbab
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ result[bytesWritten++] = ((((c - 1) & 0xf) << 4) | ((c + 0) & 0xf));
+ break;
+ }
+ case 0x1b: { // bbba
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c - 1) & 0xf));
+ break;
+ }
+ case 0x1a: { // baaa -- the horrible, hard-to-match case
+ u8 byte = compressedData[curIndex];
+ c = 0xF;
+ c = byte & c;
+ curIndex++;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c - 1) & 0xf));
+ result[bytesWritten++] = ((((c - 1) & 0xf) << 4) | ((c - 1) & 0xf));
+ break;
+ }
+ case 0x19: { // abaa
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 1) & 0xf));
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ break;
+ }
+ case 0x18: { // aaba
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ result[bytesWritten++] = ((((c + 1) & 0xf) << 4) | ((c + 0) & 0xf));
+ break;
+ }
+ case 0x17: { // aaab
+ c = compressedData[curIndex++] & 0xf;
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf));
+ result[bytesWritten++] = ((((c + 0) & 0xf) << 4) | ((c + 1) & 0xf));
+ break;
+ }
+ default: {
+ tmp += (compressedData[curIndex++, curIndex++]);
+ tmp += bytesWritten - 0x1000;
+ for(;command;command--)
+ {
+ result[bytesWritten++] = result[tmp];
+ tmp++;
+ }
+ }
}
- break;
+ } else {
+ // if bit is set, just copy next byte
+ result[bytesWritten++] = (compressedData[curIndex]);
+ curIndex++;
}
-end_800AE08:
cmdBit++;
currentByte <<= 1;
- if (curIndex > compressedLength)
- return bytesWritten;
- }
+ } while (curIndex < compressedLength);
}
- return 0;
-#else
- asm_unified(
- "DecompressAT:\n"
- " push {r4-r7,lr}\n"
- " mov r7, r10\n"
- " mov r6, r9\n"
- " mov r5, r8\n"
- " push {r5-r7}\n"
- " sub sp, 0x2C\n"
- " mov r12, r0\n"
- " str r1, [sp, 0x24]\n"
- " mov r8, r2\n"
- " ldrb r0, [r2, 0x5]\n"
- " ldrb r1, [r2, 0x6]\n"
- " lsls r1, 8\n"
- " adds r0, r1\n"
- " str r0, [sp, 0x28]\n"
- " movs r6, 0\n"
- " mov r10, r6\n"
- " movs r0, 0x8\n"
- " mov r9, r0\n"
- " ldrb r0, [r2]\n"
- " cmp r0, 0x41\n"
- " bne _0800AB04\n"
- " ldrb r0, [r2, 0x1]\n"
- " adds r1, r0, 0\n"
- " cmp r1, 0x54\n"
- " bne _0800AB0C\n"
- " ldrb r0, [r2, 0x2]\n"
- " cmp r0, 0x34\n"
- " bne _0800AB0C\n"
- " ldrb r0, [r2, 0x3]\n"
- " cmp r0, 0x50\n"
- " bne _0800AB0C\n"
- " ldrb r1, [r2, 0x10]\n"
- " ldrb r0, [r2, 0x11]\n"
- " lsls r0, 8\n"
- " adds r1, r0\n"
- " ldr r2, [sp, 0x24]\n"
- " cmp r2, 0\n"
- " beq _0800AB08\n"
- " cmp r2, r1\n"
- " beq _0800AB08\n"
- "_0800AB04:\n"
- " movs r0, 0\n"
- " b _0800AE16\n"
- "_0800AB08:\n"
- " movs r1, 0x12\n"
- " b _0800AB26\n"
- "_0800AB0C:\n"
- " mov r3, r8\n"
- " ldrb r0, [r3]\n"
- " cmp r0, 0x41\n"
- " bne _0800AB04\n"
- " cmp r1, 0x54\n"
- " bne _0800AB04\n"
- " ldrb r0, [r3, 0x2]\n"
- " cmp r0, 0x33\n"
- " bne _0800AB04\n"
- " ldrb r0, [r3, 0x3]\n"
- " cmp r0, 0x50\n"
- " bne _0800AB04\n"
- " movs r1, 0x10\n"
- "_0800AB26:\n"
- " mov r2, r8\n"
- " ldrb r0, [r2, 0x4]\n"
- " cmp r0, 0x4E\n"
- " bne _0800AB4A\n"
- " movs r7, 0\n"
- " b _0800AB40\n"
- "_0800AB32:\n"
- " mov r1, r12\n"
- " adds r0, r1, r7\n"
- " mov r2, r8\n"
- " adds r1, r7, r2\n"
- " ldrb r1, [r1, 0x7]\n"
- " strb r1, [r0]\n"
- " adds r7, 0x1\n"
- "_0800AB40:\n"
- " ldr r3, [sp, 0x28]\n"
- " cmp r7, r3\n"
- " blt _0800AB32\n"
- " adds r0, r7, 0\n"
- " b _0800AE16\n"
- "_0800AB4A:\n"
- " mov r2, r8\n"
- " ldrb r0, [r2, 0x7]\n"
- " adds r0, 0x3\n"
- " str r0, [sp]\n"
- " ldrb r0, [r2, 0x8]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x4]\n"
- " ldrb r0, [r2, 0x9]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x8]\n"
- " ldrb r0, [r2, 0xA]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0xC]\n"
- " ldrb r0, [r2, 0xB]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x10]\n"
- " ldrb r0, [r2, 0xC]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x14]\n"
- " ldrb r0, [r2, 0xD]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x18]\n"
- " ldrb r0, [r2, 0xE]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x1C]\n"
- " ldrb r0, [r2, 0xF]\n"
- " adds r0, 0x3\n"
- " str r0, [sp, 0x20]\n"
- " adds r7, r1, 0\n"
- " ldr r3, [sp, 0x28]\n"
- " cmp r7, r3\n"
- " blt _0800AB8C\n"
- " b _0800AE14\n"
- "_0800AB8C:\n"
- " ldr r0, [sp, 0x24]\n"
- " cmp r0, 0\n"
- " beq _0800AB96\n"
- " cmp r6, r0\n"
- " bge _0800AB04\n"
- "_0800AB96:\n"
- " mov r1, r9\n"
- " cmp r1, 0x8\n"
- " bne _0800ABAA\n"
- " mov r2, r8\n"
- " adds r0, r2, r7\n"
- " ldrb r0, [r0]\n"
- " mov r10, r0\n"
- " adds r7, 0x1\n"
- " movs r3, 0\n"
- " mov r9, r3\n"
- "_0800ABAA:\n"
- " movs r0, 0x80\n"
- " mov r1, r10\n"
- " ands r0, r1\n"
- " cmp r0, 0\n"
- " beq _0800ABB6\n"
- " b _0800ADF0\n"
- "_0800ABB6:\n"
- " mov r3, r8\n"
- " adds r2, r3, r7\n"
- " ldrb r1, [r2]\n"
- " lsrs r0, r1, 4\n"
- " adds r3, r0, 0x3\n"
- " movs r0, 0xF\n"
- " ands r0, r1\n"
- " lsls r5, r0, 8\n"
- " ldr r0, [sp]\n"
- " cmp r3, r0\n"
- " bne _0800ABCE\n"
- " movs r3, 0x1F\n"
- "_0800ABCE:\n"
- " ldr r0, [sp, 0x4]\n"
- " cmp r3, r0\n"
- " bne _0800ABD6\n"
- " movs r3, 0x1E\n"
- "_0800ABD6:\n"
- " ldr r0, [sp, 0x8]\n"
- " cmp r3, r0\n"
- " bne _0800ABDE\n"
- " movs r3, 0x1D\n"
- "_0800ABDE:\n"
- " ldr r0, [sp, 0xC]\n"
- " cmp r3, r0\n"
- " bne _0800ABE6\n"
- " movs r3, 0x1C\n"
- "_0800ABE6:\n"
- " ldr r0, [sp, 0x10]\n"
- " cmp r3, r0\n"
- " bne _0800ABEE\n"
- " movs r3, 0x1B\n"
- "_0800ABEE:\n"
- " ldr r0, [sp, 0x14]\n"
- " cmp r3, r0\n"
- " bne _0800ABF6\n"
- " movs r3, 0x1A\n"
- "_0800ABF6:\n"
- " ldr r0, [sp, 0x18]\n"
- " cmp r3, r0\n"
- " bne _0800ABFE\n"
- " movs r3, 0x19\n"
- "_0800ABFE:\n"
- " ldr r0, [sp, 0x1C]\n"
- " cmp r3, r0\n"
- " bne _0800AC06\n"
- " movs r3, 0x18\n"
- "_0800AC06:\n"
- " ldr r0, [sp, 0x20]\n"
- " cmp r3, r0\n"
- " bne _0800AC0E\n"
- " movs r3, 0x17\n"
- "_0800AC0E:\n"
- " adds r0, r3, 0\n"
- " subs r0, 0x17\n"
- " cmp r0, 0x8\n"
- " bls _0800AC18\n"
- " b _0800ADB0\n"
- "_0800AC18:\n"
- " lsls r0, 2\n"
- " ldr r1, _0800AC24\n"
- " adds r0, r1\n"
- " ldr r0, [r0]\n"
- " mov pc, r0\n"
- " .align 2, 0\n"
- "_0800AC24: .4byte _0800AC28\n"
- " .align 2, 0\n"
- "_0800AC28:\n"
- " .4byte _0800AD7C\n"
- " .4byte _0800AD48\n"
- " .4byte _0800AD20\n"
- " .4byte _0800ACFA\n"
- " .4byte _0800ACD6\n"
- " .4byte _0800ACB4\n"
- " .4byte _0800AC8C\n"
- " .4byte _0800AC66\n"
- " .4byte _0800AC4C\n"
- "_0800AC4C:\n"
- " ldrb r1, [r2]\n"
- " movs r0, 0xF\n"
- " adds r7, 0x1\n"
- " mov r3, r12\n"
- " adds r2, r3, r6\n"
- " ands r0, r1\n"
- " lsls r1, r0, 4\n"
- " orrs r1, r0\n"
- " strb r1, [r2]\n"
- " adds r6, 0x1\n"
- " adds r0, r3, r6\n"
- " strb r1, [r0]\n"
- " b _0800ADA4\n"
- "_0800AC66:\n"
- " ldrb r0, [r2]\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r1, r12\n"
- " adds r3, r1, r6\n"
- " movs r2, 0xF\n"
- " lsls r0, r5, 4\n"
- " adds r1, r5, 0x1\n"
- " ands r1, r2\n"
- " orrs r0, r1\n"
- " strb r0, [r3]\n"
- " adds r6, 0x1\n"
- " mov r3, r12\n"
- " adds r2, r3, r6\n"
- " lsls r0, r1, 4\n"
- " orrs r0, r1\n"
- " strb r0, [r2]\n"
- " b _0800ADA4\n"
- "_0800AC8C:\n"
- " ldrb r0, [r2]\n"
- " movs r3, 0xF\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r1, r12\n"
- " adds r4, r1, r6\n"
- " adds r2, r5, 0\n"
- " ands r2, r3\n"
- " lsls r1, r2, 4\n"
- " subs r0, r5, 0x1\n"
- " ands r0, r3\n"
- " orrs r0, r1\n"
- " strb r0, [r4]\n"
- " adds r6, 0x1\n"
- " mov r3, r12\n"
- " adds r0, r3, r6\n"
- " orrs r1, r2\n"
- " strb r1, [r0]\n"
- " b _0800ADA4\n"
- "_0800ACB4:\n"
- " ldrb r0, [r2]\n"
- " movs r3, 0xF\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r1, r12\n"
- " adds r2, r1, r6\n"
- " adds r1, r5, 0\n"
- " ands r1, r3\n"
- " lsls r0, r1, 4\n"
- " orrs r0, r1\n"
- " strb r0, [r2]\n"
- " adds r6, 0x1\n"
- " mov r0, r12\n"
- " adds r2, r0, r6\n"
- " subs r0, r5, 0x1\n"
- " b _0800AD68\n"
- "_0800ACD6:\n"
- " ldrb r0, [r2]\n"
- " movs r4, 0xF\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r2, r12\n"
- " adds r3, r2, r6\n"
- " adds r1, r5, 0\n"
- " ands r1, r4\n"
- " lsls r2, r1, 4\n"
- " adds r0, r2, 0\n"
- " orrs r0, r1\n"
- " strb r0, [r3]\n"
- " adds r6, 0x1\n"
- " mov r3, r12\n"
- " adds r1, r3, r6\n"
- " subs r0, r5, 0x1\n"
- " b _0800AD9E\n"
- "_0800ACFA:\n"
- " ldrb r0, [r2]\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r1, r12\n"
- " adds r3, r1, r6\n"
- " movs r2, 0xF\n"
- " lsls r0, r5, 4\n"
- " subs r1, r5, 0x1\n"
- " ands r1, r2\n"
- " orrs r0, r1\n"
- " strb r0, [r3]\n"
- " adds r6, 0x1\n"
- " mov r3, r12\n"
- " adds r2, r3, r6\n"
- " lsls r0, r1, 4\n"
- " orrs r0, r1\n"
- " strb r0, [r2]\n"
- " b _0800ADA4\n"
- "_0800AD20:\n"
- " ldrb r0, [r2]\n"
- " movs r3, 0xF\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r1, r12\n"
- " adds r4, r1, r6\n"
- " adds r2, r5, 0\n"
- " ands r2, r3\n"
- " lsls r1, r2, 4\n"
- " adds r0, r5, 0x1\n"
- " ands r0, r3\n"
- " orrs r0, r1\n"
- " strb r0, [r4]\n"
- " adds r6, 0x1\n"
- " mov r3, r12\n"
- " adds r0, r3, r6\n"
- " orrs r1, r2\n"
- " strb r1, [r0]\n"
- " b _0800ADA4\n"
- "_0800AD48:\n"
- " ldrb r0, [r2]\n"
- " movs r3, 0xF\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r1, r12\n"
- " adds r2, r1, r6\n"
- " adds r1, r5, 0\n"
- " ands r1, r3\n"
- " lsls r0, r1, 4\n"
- " orrs r0, r1\n"
- " strb r0, [r2]\n"
- " adds r6, 0x1\n"
- " mov r0, r12\n"
- " adds r2, r0, r6\n"
- " adds r0, r5, 0x1\n"
- "_0800AD68:\n"
- " ands r0, r3\n"
- " lsls r0, 4\n"
- " orrs r0, r1\n"
- " strb r0, [r2]\n"
- " adds r6, 0x1\n"
- " mov r4, r9\n"
- " adds r4, 0x1\n"
- " mov r1, r10\n"
- " lsls r2, r1, 1\n"
- " b _0800AE08\n"
- "_0800AD7C:\n"
- " ldrb r0, [r2]\n"
- " movs r4, 0xF\n"
- " movs r5, 0xF\n"
- " ands r5, r0\n"
- " adds r7, 0x1\n"
- " mov r2, r12\n"
- " adds r3, r2, r6\n"
- " adds r1, r5, 0\n"
- " ands r1, r4\n"
- " lsls r2, r1, 4\n"
- " adds r0, r2, 0\n"
- " orrs r0, r1\n"
- " strb r0, [r3]\n"
- " adds r6, 0x1\n"
- " mov r3, r12\n"
- " adds r1, r3, r6\n"
- " adds r0, r5, 0x1\n"
- "_0800AD9E:\n"
- " ands r0, r4\n"
- " orrs r2, r0\n"
- " strb r2, [r1]\n"
- "_0800ADA4:\n"
- " adds r6, 0x1\n"
- " mov r4, r9\n"
- " adds r4, 0x1\n"
- " mov r0, r10\n"
- " lsls r2, r0, 1\n"
- " b _0800AE08\n"
- "_0800ADB0:\n"
- " adds r7, 0x1\n"
- " mov r1, r8\n"
- " adds r0, r1, r7\n"
- " ldrb r0, [r0]\n"
- " adds r5, r0\n"
- " adds r7, 0x1\n"
- " ldr r2, _0800ADEC\n"
- " adds r0, r5, r2\n"
- " adds r5, r0, r6\n"
- " mov r4, r9\n"
- " adds r4, 0x1\n"
- " mov r0, r10\n"
- " lsls r2, r0, 1\n"
- " cmp r3, 0\n"
- " beq _0800AE08\n"
- "_0800ADCE:\n"
- " mov r1, r12\n"
- " adds r1, r6\n"
- " mov r10, r1\n"
- " mov r0, r12\n"
- " adds r0, r5\n"
- " ldrb r1, [r0]\n"
- " mov r0, r10\n"
- " strb r1, [r0]\n"
- " adds r6, 0x1\n"
- " adds r5, 0x1\n"
- " subs r3, 0x1\n"
- " cmp r3, 0\n"
- " bne _0800ADCE\n"
- " b _0800AE08\n"
- " .align 2, 0\n"
- "_0800ADEC: .4byte 0xfffff000\n"
- "_0800ADF0:\n"
- " mov r1, r12\n"
- " adds r0, r1, r6\n"
- " mov r2, r8\n"
- " adds r1, r2, r7\n"
- " ldrb r1, [r1]\n"
- " strb r1, [r0]\n"
- " adds r6, 0x1\n"
- " adds r7, 0x1\n"
- " mov r4, r9\n"
- " adds r4, 0x1\n"
- " mov r3, r10\n"
- " lsls r2, r3, 1\n"
- "_0800AE08:\n"
- " mov r9, r4\n"
- " mov r10, r2\n"
- " ldr r0, [sp, 0x28]\n"
- " cmp r7, r0\n"
- " bge _0800AE14\n"
- " b _0800AB8C\n"
- "_0800AE14:\n"
- " adds r0, r6, 0\n"
- "_0800AE16:\n"
- " add sp, 0x2C\n"
- " pop {r3-r5}\n"
- " mov r8, r3\n"
- " mov r9, r4\n"
- " mov r10, r5\n"
- " pop {r4-r7}\n"
- " pop {r1}\n"
- " bx r1");
-#endif
+ return bytesWritten;
}
-u32 DecompressATGlobalFile(u32 *result, u32 resultLength, struct OpenedFile *file)
+u32 DecompressATGlobalFile(u32 *result, s32 resultLength, struct OpenedFile *file)
{
return DecompressATGlobal(result, resultLength, file->data);
}
@@ -904,28 +387,27 @@ u32 DecompressATGlobalFile(u32 *result, u32 resultLength, struct OpenedFile *fil
#ifndef NONMATCHING
NAKED
#endif
-u32 DecompressATGlobal(u32 *result, u32 resultLength, const char *compressedData)
+u32 DecompressATGlobal(u32 *result, s32 resultLength, const char *compressedData)
{
#ifdef NONMATCHING
-
- // This function has the same issues as above, except is possibly a bit nicer due to the function calls
- // I'd say this one is more likely to be at least correct
-
- int flags1;
- int flags2;
- int flags3;
- int flags4;
- int flags5;
- int flags6;
- int flags7;
- int flags8;
- int flags9;
- int compressedLength;
- int curIndex;
- int command;
- int bytesWritten;
- int cmdBit;
- int currentByte;
+ s32 compressedLength;
+ s32 curIndex;
+ s32 bytesWritten;
+ s32 cmdBit;
+ s32 currentByte;
+ s32 flags1;
+ s32 flags2;
+ s32 flags3;
+ s32 flags4;
+ s32 flags5;
+ s32 flags6;
+ s32 flags7;
+ s32 flags8;
+ s32 flags9;
+ u32 command;
+ u32 tmp;
+ u32 tmp2;
+ u32 c;
compressedLength = compressedData[5] + (compressedData[6] << 8);
bytesWritten = 0;
@@ -938,9 +420,9 @@ u32 DecompressATGlobal(u32 *result, u32 resultLength, const char *compressedData
&& compressedData[1] == 'T'
&& compressedData[2] == '4'
&& compressedData[3] == 'P') {
- // compiler swaps comparison order somehow
- if (resultLength != compressedData[0x10] + (compressedData[0x11] << 8) && resultLength != 0)
- return 0;
+ tmp2 = compressedData[0x10] + (compressedData[0x11] << 8);
+ if (resultLength != 0 && resultLength != tmp2)
+ return bytesWritten;
curIndex = 0x12;
} else if (compressedData[0] == 'A'
&& compressedData[1] == 'T'
@@ -970,24 +452,21 @@ u32 DecompressATGlobal(u32 *result, u32 resultLength, const char *compressedData
flags8 = compressedData[0xe] + 3;
flags9 = compressedData[0xf] + 3;
- // Some mismatches regarding the signedness of these two conditionals, extremely fragile without explicit casts
- // TODO: clean this up later
- if ((int)curIndex < (int)compressedLength) {
- // '<' comparison compiles to wrong branch, but if I add another 'return bytesWritten;'
- // after the while loop, the compiler merges it with the earlier uncompressed case which breaks stuff.
- if (resultLength == 0 || (int)bytesWritten < (int)resultLength) return 0;
+ if (curIndex < compressedLength) {
+
do {
+ if (resultLength != 0 && bytesWritten >= resultLength)
+ return 0;
+
if (cmdBit == 8) {
currentByte = compressedData[curIndex++];
cmdBit = 0;
}
- if (currentByte & 0x80) { // some weird reordering happens here, couldn't figure it out
- // do NOT try inverting the above condition and moving this to the bottom
- // it really won't end well
- DecompressAT_AppendByte(compressedData[curIndex++]);
- bytesWritten++;
- } else {
+ if ((currentByte & 0x80) == 0) {
+ // if bit is unset, process command
command = (compressedData[curIndex] >> 4) + 3;
+ tmp2 = (compressedData[curIndex] & 0xf) << 8;
+
if (command == flags1) command = 0x1f;
if (command == flags2) command = 0x1e;
if (command == flags3) command = 0x1d;
@@ -999,85 +478,76 @@ u32 DecompressATGlobal(u32 *result, u32 resultLength, const char *compressedData
if (command == flags9) command = 0x17;
switch (command) {
- case 0x1f: {
- char c = compressedData[curIndex++] & 0xf;
+ case 0x1f: { // aaaa
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
break;
}
- case 0x1e: {
- char c = compressedData[curIndex++] & 0xf;
+ case 0x1e: { // abbb
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 1) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 1) & 0xf) << 4) | ((c + 1) & 0xf)); bytesWritten++;
- break; // rather large mismatch
+ break;
}
- case 0x1d: {
- char c = compressedData[curIndex] & 0xf;
- curIndex++;
+ case 0x1d: { // babb
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c - 1) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
break;
}
- case 0x1c: {
- char c = compressedData[curIndex] & 0xf;
- curIndex++;
+ case 0x1c: { // bbab
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c - 1) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
break;
}
- case 0x1b: {
- char c = compressedData[curIndex] & 0xf;
- curIndex++;
+ case 0x1b: { // bbba
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c - 1) & 0xf)); bytesWritten++;
break;
}
- case 0x1a: {
- char c = compressedData[curIndex] & 0xf;
- // weird movs/adds here - possibly regalloc
- curIndex++;
- // missing u8 cast for argument, twice
+ case 0x1a: { // baaa -- the horrible, unmatching case
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c - 1) & 0xf)); bytesWritten++;
- DecompressAT_AppendByte((((c - 1) & 0xf) << 4) | ((c - 1) & 0xf)); bytesWritten++;
- break; // second call is inlined! Should end up after switch code
- // and yes, I tried extracting (c-1)&0xf into its own variable, and in 0x1e as well
- // which had little effect
+ c -= 1;
+ DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
+ break;
}
- case 0x19: {
- char c = compressedData[curIndex] & 0xf;
- curIndex++;
+ case 0x19: { // abaa
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 1) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
break;
}
- case 0x18: {
- char c = compressedData[curIndex] & 0xf;
- curIndex++;
+ case 0x18: { // aaba
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 1) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
break;
}
- case 0x17: {
- char c = compressedData[curIndex] & 0xf;
- curIndex++;
+ case 0x17: { // aaab
+ c = compressedData[curIndex++] & 0xf;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 0) & 0xf)); bytesWritten++;
DecompressAT_AppendByte((((c + 0) & 0xf) << 4) | ((c + 1) & 0xf)); bytesWritten++;
break;
}
default: {
- unsigned tmp = curIndex + 1;
- tmp = bytesWritten - 0x1000 + ((compressedData[curIndex++] & 0xf) << 8) + compressedData[tmp];
- curIndex++;
+ tmp = compressedData[curIndex++, curIndex++] + tmp2 - 0x1000 + bytesWritten;
for (; command != 0; tmp++, command--) {
- char c = DecompressAT_GetByte(tmp);
- DecompressAT_AppendByte(c); bytesWritten++;
+ DecompressAT_AppendByte(DecompressAT_GetByte(tmp)); bytesWritten++;
}
}
}
+ } else {
+ // if bit is set, just copy next byte
+ DecompressAT_AppendByte(compressedData[curIndex]); bytesWritten++;
+ curIndex++;
}
cmdBit++;
currentByte <<= 1;
- } while ((int)curIndex < (int)compressedLength);
+ } while (curIndex < compressedLength);
DecompressAT_Finish();
}