Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
decompressor.c
Go to the documentation of this file.
1#include "engine/game.h"
2
3/* Decompressor method: frees its buffer */
5 if (task->buffer != NULL) {
6 HEAP.free(task->buffer);
7 }
8 task->buffer = NULL;
9 task->bufferSize = 0;
10}
11
12/* Points the decompressor at data, which is RLEN-packed or plain */
14 task->data = data;
15 if (data[0] == RLEN_MAGIC) {
16 task->compressed = 1;
17 task->size = data[1];
18 } else {
19 task->compressed = 0;
20 task->size = 0;
21 }
22 data += 2;
23 task->begin = data;
24 task->src = data;
25}
26
27/* Makes the buffer big enough for the unpacked size */
29 if (task->size > task->bufferSize) {
30 if (task->buffer != NULL) {
31 HEAP.free(task->buffer);
32 }
33 task->buffer = HEAP.alloc(task->size, MEM_MODE);
34 task->bufferSize = task->size;
35 }
36 task->dst = task->buffer;
37}
38
39/* Unpacks at least chunkSize bytes; back to substate 0 at the end */
41 u8 *src = task->src;
42 u8 *dst = task->dst;
43 s32 total = 0;
44 s32 done = 0;
45 s32 n;
46 s32 i;
47
48 while (*src != 0) {
49 if (*src & 0x80) {
50 n = *src++ & 0x7F;
51 for (i = 0; i < n; i++) {
52 *dst++ = *src;
53 }
54 src++;
55 total += n;
56 } else {
57 n = *src++;
58 for (i = 0; i < n; i++) {
59 *dst++ = *src++;
60 }
61 total += n;
62 }
63 if (total >= task->chunkSize) {
64 done = 1;
65 task->src = src;
66 task->dst = dst;
67 break;
68 }
69 }
70 if (!done) {
71 task->setSubstate(task, 0);
72 }
73}
74
75/* Decompressor method: unpacks data at once; returns it unpacked (plain data as it is) */
76void *decompressorRun(Decompressor *task, s32 *data) {
77 task->chunkSize = 0x10000000;
78 decompressorSetData(task, data);
79 if (task->compressed) {
81 decompressorStep(task);
82 return task->buffer;
83 }
84 return data;
85}
86
87/* Decompressor method: starts unpacking data chunkSize bytes a frame */
88void decompressorStart(Decompressor *task, s32 *data, s32 chunkSize) {
89 task->chunkSize = chunkSize;
90 decompressorSetData(task, data);
91 if (task->compressed) {
93 task->setSubstate(task, 1);
94 }
95}
96
97/* Decompressor method: the unpacked data, or NULL while it is unpacking */
99 if (task->substate != 0) {
100 return NULL;
101 }
102 if (task->compressed != 0) {
103 return task->buffer;
104 }
105 return task->data;
106}
107
108/* The decompressor task: unpacks a chunk a frame, frees the buffer at the end */
110 switch (task->state) {
111 case 0:
112 default:
113 task->nextState(task);
114 break;
115 case 1:
116 if (task->substate != 0 && task->substate == task->state) {
117 decompressorStep(task);
118 }
119 break;
120 case 2:
121 break;
122 case 3:
123 if (task->buffer != NULL) {
124 HEAP.free(task->buffer);
125 }
126 break;
127 }
128}
129
130/* A decompressor task */
133
134 task->run = decompressorRun;
135 task->free = decompressorFree;
136 task->start = decompressorStart;
138 return task;
139}
#define NULL
Definition common.h:17
signed int s32
Definition common.h:11
unsigned char u8
Definition common.h:8
void updateDecompressor(Decompressor *task)
The decompressor task: unpacks a chunk a frame, frees the buffer at the end.
void decompressorAllocBuffer(Decompressor *task)
Makes the buffer big enough for the unpacked size.
void decompressorStep(Decompressor *task)
Unpacks at least chunkSize bytes; back to substate 0 at the end.
void * decompressorRun(Decompressor *task, s32 *data)
Decompressor method: unpacks data at once; returns it unpacked (plain data as it is)
void decompressorFree(Decompressor *task)
Decompressor method: frees its buffer.
Definition decompressor.c:4
void * decompressorGetData(Decompressor *task)
Decompressor method: the unpacked data, or NULL while it is unpacking.
Decompressor * createDecompressor(void)
A decompressor task.
void decompressorStart(Decompressor *task, s32 *data, s32 chunkSize)
Decompressor method: starts unpacking data chunkSize bytes a frame.
void decompressorSetData(Decompressor *task, s32 *data)
Points the decompressor at data, which is RLEN-packed or plain.
#define RLEN_MAGIC
The first word of "RLEN" data, which its unpacked size follows.
Definition file.h:103
Heap HEAP
The functions that return what a call left in v0 (allocMemHigh, findTask) and the ones that take othe...
Definition heap.c:184
#define MEM_MODE
the current mode's: freed by main whenever the mode task ends
Definition heap.h:17
Expands "RLEN" data (a run-length encoding: a byte n < 0x80 copies n bytes, n | 0x80 repeats the next...
Definition file.h:110
s32 * begin
Definition file.h:113
s32 substate
Definition file.h:111
void(* setSubstate)(struct Decompressor *task, s32 substate)
Definition file.h:111
void(* free)()
Definition file.h:124
s32 bufferSize
Definition file.h:116
void(* start)()
Definition file.h:123
void * dst
Definition file.h:119
void(* nextState)(struct Decompressor *task)
Definition file.h:111
s32 size
Definition file.h:115
void * src
the next packed byte
Definition file.h:118
s32 state
Definition file.h:111
void * buffer
Definition file.h:117
void *(* getData)()
Definition file.h:122
s32 * data
Definition file.h:112
s32 compressed
Definition file.h:114
s32 chunkSize
Definition file.h:120
void *(* run)()
Definition file.h:121
void *(* alloc)(s32 size, s32 tag)
Definition heap.h:29
void(* free)(void *ptr)
Definition heap.h:27
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
Definition task.c:105