diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 2fc1ed93..ad0a6e99 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -4831,7 +4831,7 @@ lbl_8011F77C = .data:0x8011F77C; // type:object size:0x13 data:string lbl_8011F78F = .data:0x8011F78F; // type:object size:0x13 data:string lbl_8011F7A2 = .data:0x8011F7A2; // type:object size:0x12 data:string lbl_8011F7B4 = .data:0x8011F7B4; // type:object size:0x10 -DataDirStat = .data:0x8011F7C4; // type:object size:0x468 data:4byte scope:local +DataDirStat = .data:0x8011F7C4; // type:object size:0x468 scope:local data:4byte lbl_8011FC2C = .data:0x8011FC2C; // type:object size:0x1D data:string lbl_8011FC49 = .data:0x8011FC49; // type:object size:0x1F data:string lbl_8011FC68 = .data:0x8011FC68; // type:object size:0x3C diff --git a/configure.py b/configure.py index b0fdec5f..b7bbae46 100755 --- a/configure.py +++ b/configure.py @@ -226,7 +226,7 @@ config.libs = [ Object(NonMatching, "game/pad.c"), Object(NonMatching, "game/dvd.c"), Object(NonMatching, "game/data.c"), - Object(NonMatching, "game/decode.c"), + Object(Matching, "game/decode.c"), Object(Matching, "game/malloc.c"), Object(Matching, "game/memory.c"), Object(NonMatching, "game/sprman.c"), diff --git a/include/functions.h b/include/functions.h index 29afc607..b4c7c03a 100644 --- a/include/functions.h +++ b/include/functions.h @@ -8,6 +8,7 @@ void OSReport(const char * format, ...); void* OSAllocFromHeap(int heap, u32 size); s32 OSCheckHeap(int heap); void DCFlushRangeNoSync(void *addr, u32 size); +void DCFlushRange(void *addr, u32 size); void* HuPrcCreate(void (*), s32, s32, s32); void Hu3DBGColorSet(u8, u8, u8); void Hu3DCameraCreate(s16); diff --git a/src/game/decode.c b/src/game/decode.c new file mode 100644 index 00000000..bd42b4a8 --- /dev/null +++ b/src/game/decode.c @@ -0,0 +1,213 @@ +#include "common.h" + +struct decode_data +{ + u8 *src; + u8 *dst; + u32 size; +}; + +static u8 TextBuffer[1024]; + +static void HuDecodeNone(struct decode_data *decode) +{ + while(decode->size) { + *decode->dst++ = *decode->src++; + decode->size--; + } +} + +static void HuDecodeLz(struct decode_data *decode) +{ + u16 flag; + u16 pos; + int i, j; + flag = 0; + pos = 958; + + for(i=0; i<1024; i++) { + TextBuffer[i] = 0; + } + while(decode->size) { + flag >>= 1; + if(!(flag & 0x100)) { + flag = (*decode->src++)|0xFF00; + } + if(flag & 0x1) { + TextBuffer[pos++] = *decode->dst++ = *decode->src++; + pos = pos & 0x3FF; + decode->size--; + } else { + u16 copy_pos, copy_size; + copy_pos = *decode->src++; + copy_size = *decode->src++; + copy_pos |= ((copy_size & 0xC0) << 2); + copy_size = (copy_size & 0x3F)+3; + for(j=0; jdst++ = TextBuffer[(copy_pos+j) & 0x3FF]; + pos &= 0x3FF; + } + decode->size -= j; + } + } +} + +static inline void SlideReadHeader(struct decode_data *decode) +{ + int size; + size = (*decode->src++) << 24; + size += (*decode->src++) << 16; + size += (*decode->src++) << 8; + size += *decode->src++; +} + +static void HuDecodeSlide(struct decode_data *decode) +{ + u8 *base_dst; + u32 num_bits, flag; + SlideReadHeader(decode); + num_bits = 0; + flag = 0; + base_dst = decode->dst; + while(decode->size) { + if(num_bits == 0) { + flag = (*decode->src++) << 24; + flag += (*decode->src++) << 16; + flag += (*decode->src++) << 8; + flag += *decode->src++; + num_bits = 32; + } + if(flag >> 31) { + *decode->dst++ = (int)*decode->src++; + decode->size--; + } else { + u8 *src; + u32 dist, len; + dist = *decode->src++ << 8; + dist += *decode->src++; + len = (dist >> 12) & 0xF; + dist &= 0xFFF; + src = decode->dst-dist; + if(len == 0) { + len = (*decode->src++)+18; + } else { + len += 2; + } + decode->size -= len; + while(len) { + if(src-1 < base_dst) { + *decode->dst++ = 0; + } else { + *decode->dst++ = src[-1]; + } + len--; + src++; + } + } + + flag <<= 1; + num_bits--; + } +} + +static void HuDecodeFslide(struct decode_data *decode) +{ + u32 num_bits, flag; + SlideReadHeader(decode); + num_bits = 0; + flag = 0; + while(decode->size) { + if(num_bits == 0) { + flag = (*decode->src++) << 24; + flag += (*decode->src++) << 16; + flag += (*decode->src++) << 8; + flag += *decode->src++; + num_bits = 32; + } + if(flag >> 31) { + *decode->dst++ = (int)*decode->src++; + decode->size--; + } else { + u8 *src; + u32 dist, len; + dist = *decode->src++ << 8; + dist += *decode->src++; + len = (dist >> 12) & 0xF; + dist &= 0xFFF; + src = decode->dst-dist; + if(len == 0) { + len = (*decode->src++)+18; + } else { + len += 2; + } + decode->size -= len; + while(len) { + *decode->dst++ = src[-1]; + len--; + src++; + } + } + + flag <<= 1; + num_bits--; + } +} + +static void HuDecodeRle(struct decode_data *decode) +{ + int i; + while(decode->size) { + int size = *decode->src++; + if(size < 128) { + int fill = *decode->src++; + for(i=0; idst++ = fill; + } + } else { + size -= 128; + for(i=0; idst++ = *decode->src++; + } + } + decode->size -= size; + } +} + +void HuDecodeData(void *src, void *dst, int decode_type, u32 size) +{ + struct decode_data decode; + struct decode_data *decode_ptr = &decode; + decode_ptr->src = src; + decode_ptr->dst = dst; + decode_ptr->size = size; + switch(decode_type) { + case 0: + HuDecodeNone(decode_ptr); + break; + + case 1: + HuDecodeLz(decode_ptr); + break; + + case 2: + HuDecodeSlide(decode_ptr); + break; + + case 3: + HuDecodeFslide(decode_ptr); + break; + + case 4: + HuDecodeFslide(decode_ptr); + break; + + case 5: + HuDecodeRle(decode_ptr); + break; + + default: + OSReport("decode tyep unknown.(%x)\n", decode_type); + break; + } + DCFlushRange(dst, size); +} \ No newline at end of file