Skip to content

Commit 1391f68

Browse files
committed
Finished implementing compression algorithm
1 parent e704071 commit 1391f68

5 files changed

Lines changed: 41 additions & 19 deletions

File tree

src/compress.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "compress.h"
44

5+
#include "savestate.h"
56
#include "bool.h"
67
#include "libc/string.h"
78

@@ -62,7 +63,7 @@ typedef struct
6263

6364
static MinMatcHash hashMinMatch(MinMatch match)
6465
{
65-
return (MinMatcHash){((match.match3 * 506832829U) << 8) >> (32 - HASH_CHAINS_BITS), (match.match4 * 2654435761U) >> (32 - HASH_CHAINS_BITS)};
66+
return (MinMatcHash){((match.match3 * 506832829U)) >> (32 - HASH_CHAINS_BITS), (match.match4 * 2654435761U) >> (32 - HASH_CHAINS_BITS)};
6667
}
6768

6869
static void wildCopy4(uint8_t *dst, const uint8_t *src, const uint8_t *dstEnd)
@@ -132,7 +133,7 @@ static MinMatchPtr tryMinMatch(uint32_t potentialMinMatchOffset, MinMatch minMat
132133
}
133134
}
134135

135-
void mlz4_compress(const uint8_t *in, const uint32_t inSize, uint8_t *out, uint32_t *outSize)
136+
uint32_t mlz4_compress(const uint8_t *in, const uint32_t inSize, uint8_t *out)
136137
{
137138
uint8_t *compressedData = out;
138139

@@ -142,23 +143,25 @@ void mlz4_compress(const uint8_t *in, const uint32_t inSize, uint8_t *out, uint3
142143
uint8_t hashChains4[HASH_CHAINS_SIZE] = {};
143144
#else
144145
// placed in gDecompressionHeap
145-
uint8_t *hashChains3 = (uint8_t *)0x801c1000;
146-
uint8_t *hashChains4 = (uint8_t *)0x801c1000 + HASH_CHAINS_SIZE;
146+
uint8_t *hashChains3 = Hacktice_gState->memory + MaxStateSize - HASH_CHAINS_SIZE * 2 - 0xf00;
147+
uint8_t *hashChains4 = hashChains3 + HASH_CHAINS_SIZE;
148+
bzero(hashChains3, 2 * HASH_CHAINS_SIZE);
147149
#endif
148150

149151
// should be safe to do
150-
*(uint32_t *)outCursor = inSize;
152+
PUT_UNALIGNED4(inSize, outCursor);
151153
outCursor += 4;
152154

155+
#if 0
153156
// uncompressible data, just write it out as literals
154157
if (inSize <= 8)
155158
{
156159
outCursor[0] = ((uint8_t)inSize) << 4;
157160
outCursor++;
158161
WILD_COPY_MOVE(outCursor, in, inSize);
159-
*outSize = (size_t)(outCursor - compressedData);
160-
return;
162+
return (uint32_t) (outCursor - compressedData);
161163
}
164+
#endif
162165

163166
const uint8_t *inEnd = in + inSize;
164167
const uint8_t *inCursor = in + 4;
@@ -192,8 +195,7 @@ void mlz4_compress(const uint8_t *in, const uint32_t inSize, uint8_t *out, uint3
192195
}
193196

194197
WILD_COPY_MOVE(outCursor, inLiteralStart, literalsCount);
195-
*outSize = (uint32_t)(outCursor - compressedData);
196-
return;
198+
return (uint32_t)(outCursor - compressedData);
197199
}
198200

199201
MinMatch minMatch = readMinMatch(inCursor);
@@ -247,10 +249,10 @@ void mlz4_compress(const uint8_t *in, const uint32_t inSize, uint8_t *out, uint3
247249
}
248250
}
249251

250-
void mlz4_decompress(const uint8_t *in, uint8_t *out)
252+
uint32_t mlz4_decompress(const uint8_t *in, uint8_t *out)
251253
{
252254
const uint8_t *inCursor = in;
253-
uint32_t originalSize = *(uint32_t *)inCursor;
255+
uint32_t originalSize = GET_UNALIGNED4(inCursor);
254256
inCursor += 4;
255257

256258
uint8_t *outCursor = out;
@@ -279,6 +281,7 @@ void mlz4_decompress(const uint8_t *in, uint8_t *out)
279281
// last 4 literals must be in safety margin
280282
memcpy(outCursor, inCursor, literalsCount);
281283
outCursor += literalsCount;
284+
inCursor += literalsCount;
282285
break;
283286
}
284287
else
@@ -306,4 +309,7 @@ void mlz4_decompress(const uint8_t *in, uint8_t *out)
306309
const uint8_t *matchStart = outCursor - offset;
307310
WILD_COPY_MOVE(outCursor, matchStart, matchesCount);
308311
}
312+
313+
// TODO: this is incredibly ugly, rework this mess
314+
return inCursor - in;
309315
}

src/compress.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
#define uint8_t u8
44
#define uint32_t u32
55

6-
void mlz4_compress(const uint8_t* in, const uint32_t inSize, uint8_t* out, uint32_t* outSize);
7-
void mlz4_decompress(const uint8_t* in, uint8_t* out);
6+
uint32_t mlz4_compress(const uint8_t* in, const uint32_t inSize, uint8_t* out);
7+
uint32_t mlz4_decompress(const uint8_t* in, uint8_t* out);

src/savestate.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
#include "game/area.h"
99
#include "game/camera.h"
10+
#include "game/display.h"
1011
#include "game/print.h"
1112
#include "game/level_update.h"
1213
#include "libc/string.h"
14+
#include "libc/stdio.h"
1315

1416
void set_play_mode(s16 playMode);
1517

@@ -22,6 +24,9 @@ extern u8 _hackticeStateDataStart[];
2224
extern u8 _hackticeStateDataEnd[];
2325
#endif
2426

27+
#define IS_DECADES_LATER (0x8C63E074U == (*(uint32_t*) 0x802C99C4))
28+
extern struct GfxPool gGfxPools[2];
29+
2530
static bool sMustSaveState = 0;
2631

2732
static void resetCamera()
@@ -48,16 +53,27 @@ void SaveState_onNormal()
4853
Hacktice_gState->area = gCurrAreaIndex;
4954
Hacktice_gState->level = gCurrLevelNum;
5055
Hacktice_gState->size = sizeof(State);
51-
uint32_t stateSize = 0;
52-
mlz4_compress(_hackticeStateDataStart, _hackticeStateDataEnd - _hackticeStateDataStart, Hacktice_gState->memory, &stateSize);
56+
uint32_t stateSize = mlz4_compress(_hackticeStateDataStart, _hackticeStateDataEnd - _hackticeStateDataStart, Hacktice_gState->memory);
57+
// Decades Later extra logic
58+
if (IS_DECADES_LATER)
59+
{
60+
uint32_t exStateSize = mlz4_compress((uint8_t*) gGfxPools, sizeof(gGfxPools), Hacktice_gState->memory + stateSize);
61+
static char buf[16];
62+
sprintf(buf, "%d %d", stateSize, exStateSize);
63+
TextManager_addLine(buf, 30);
64+
}
5365
}
5466
else
5567
{
5668
if (Config_action() == Config_ButtonAction_LOAD_STATE)
5769
{
5870
if (Hacktice_gState->area == gCurrAreaIndex && Hacktice_gState->level == gCurrLevelNum)
5971
{
60-
mlz4_decompress(Hacktice_gState->memory, _hackticeStateDataStart);
72+
uint32_t compressedSize = mlz4_decompress(Hacktice_gState->memory, _hackticeStateDataStart);
73+
if (IS_DECADES_LATER)
74+
{
75+
mlz4_decompress(Hacktice_gState->memory + compressedSize, (uint8_t*) gGfxPools);
76+
}
6177
resetCamera();
6278
}
6379
}

src/savestate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ void SaveState_onPause();
66
void SaveState_onNormal();
77

88
// TODO: This is very much a culprit, useless one too
9-
#define MaxStateSize 0x30000
9+
#define MaxStateSize 0x28000
1010

1111
typedef struct
1212
{
1313
s32 size;
1414
s16 level;
1515
s16 area;
16-
char memory[MaxStateSize];
16+
u8 memory[MaxStateSize];
1717
} State;
1818

1919
#ifdef BINARY

src/xversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
HACKTICE_VERSION(1, 6, 0)
1+
HACKTICE_VERSION(1, 6, 1)

0 commit comments

Comments
 (0)