From d15c2d494d2343d8fb2f86342a35fd7992a298cc Mon Sep 17 00:00:00 2001 From: CrashOveride95 Date: Mon, 4 Jan 2021 00:44:54 -0500 Subject: [PATCH] Fix most gzip things *EXCEPT THE ACTUAL DECOMPRESSION* AYY LMAO --- Makefile | 7 +- src/game/memory.c | 36 +++-- src/gzip/dmacopy.c | 65 ++++++++ src/gzip/dmacopy.h | 8 + src/gzip/gzip.h | 33 +++- src/gzip/gzipdma.h | 14 -- src/gzip/{gzipdma.c => inflate.c} | 197 +++++++---------------- src/gzip/unzip.c | 255 ++++++++++++++++++++++++++++++ tools/.gitignore | 1 + tools/Makefile | 4 +- tools/filesizer.c | 62 ++++++++ 11 files changed, 506 insertions(+), 176 deletions(-) create mode 100755 src/gzip/dmacopy.c create mode 100755 src/gzip/dmacopy.h delete mode 100755 src/gzip/gzipdma.h rename src/gzip/{gzipdma.c => inflate.c} (82%) create mode 100755 src/gzip/unzip.c create mode 100644 tools/filesizer.c diff --git a/Makefile b/Makefile index 6c7fad09f..1d2aa2205 100644 --- a/Makefile +++ b/Makefile @@ -406,6 +406,7 @@ export LANG := C YAY0TOOL := $(TOOLS_DIR)/slienc ROMALIGN := $(TOOLS_DIR)/romalign BFSIZE := $(TOOLS_DIR)/bfsize +FILESIZER := $(TOOLS_DIR)/filesizer N64CKSUM := $(TOOLS_DIR)/n64cksum N64GRAPHICS := $(TOOLS_DIR)/n64graphics N64GRAPHICS_CI := $(TOOLS_DIR)/n64graphics_ci @@ -582,13 +583,15 @@ ifeq ($(COMPRESS),gzip) $(BUILD_DIR)/%.gz: $(BUILD_DIR)/%.bin $(call print,Compressing:,$<,$@) $(V)gzip -c -9 -n $< > $@ - $(V)dd if=/dev/zero bs=1 count=4 >> $@ - perl -e 'printf ("%x", -s "$<")' $< >> $@ +# $(V)dd if=/dev/zero bs=1 count=4 >> $@ +# $(ROMALIGN) $@ 16 +# $(V)$(FILESIZER) $< $@ # Strip gzip header $(BUILD_DIR)/%.szp: $(BUILD_DIR)/%.gz $(call print,Converting:,$<,$@) $(V)dd bs=10 skip=1 if=$< of=$@ + $(V)$(FILESIZER) $(<:.gz=.bin) $@ # convert binary szp to object file $(BUILD_DIR)/%.szp.o: $(BUILD_DIR)/%.szp diff --git a/src/game/memory.c b/src/game/memory.c index 3f28acd8e..ac5b56632 100644 --- a/src/game/memory.c +++ b/src/game/memory.c @@ -12,7 +12,7 @@ #include "segment_symbols.h" #include "segments.h" #ifdef GZIP -#include "gzip/gzipdma.h" +#include "gzip/gzip.h" #endif #ifdef UNF #include "usb/debug.h" @@ -321,6 +321,17 @@ void *load_to_fixed_pool_addr(u8 *destAddr, u8 *srcStart, u8 *srcEnd) { return dest; } +#ifdef GZIP +u32 ExpandGZip(void *src, void *dest, u32 size) +{ + u32 len; + + len = expand_gzip((char *)src, (char *)dest, size); + + return ((u32)dest + len + 7) & ~7; +} +#endif + /** * Decompress the block of ROM data from srcStart to srcEnd and return a * pointer to an allocated buffer holding the decompressed data. Set the @@ -330,7 +341,7 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) { void *dest = NULL; #ifdef GZIP - u32 compSize = ALIGN16(srcEnd - 8 - srcStart); + u32 compSize = (srcEnd - 4 - srcStart); #else u32 compSize = ALIGN16(srcEnd - srcStart); #endif @@ -339,23 +350,19 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) { #ifdef GZIP // Decompressed size from end of gzip - u32 *size = (u32 *) (compressed + compSize - 4); + u32 *size = (u32 *) (compressed + compSize); #else // Decompressed size from mio0 header u32 *size = (u32 *) (compressed + 4); #endif + if (compressed != NULL) { + dma_read(compressed, srcStart, srcEnd); + dest = main_pool_alloc(*size, MEMORY_POOL_LEFT); + if (dest != NULL) { #ifdef GZIP - if (compressed != NULL) { - dma_read(compressed, srcStart, srcEnd); - dest = main_pool_alloc(*size, MEMORY_POOL_LEFT); - if (dest != NULL) { - slidma(compressed, dest, compSize); + ExpandGZip(compressed, dest, compSize); #else - if (compressed != NULL) { - dma_read(compressed, srcStart, srcEnd); - dest = main_pool_alloc(*size, MEMORY_POOL_LEFT); - if (dest != NULL) { slidstart(compressed, dest); #endif set_segment_base_addr(segment, dest); @@ -371,17 +378,16 @@ void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd) { UNUSED void *dest = NULL; #ifdef GZIP - u32 compSize = (srcEnd - 8 - srcStart); + u32 compSize = (srcEnd - 4 - srcStart); #else u32 compSize = ALIGN16(srcEnd - srcStart); #endif u8 *compressed = main_pool_alloc(compSize, MEMORY_POOL_RIGHT); - UNUSED u32 *pUncSize = (u32 *) (compressed + 4); if (compressed != NULL) { dma_read(compressed, srcStart, srcEnd); #ifdef GZIP - slidma(gDecompressionHeap, compressed, compSize); + ExpandGZip(gDecompressionHeap, compressed, compSize); #else slidstart(compressed, gDecompressionHeap); #endif diff --git a/src/gzip/dmacopy.c b/src/gzip/dmacopy.c new file mode 100755 index 000000000..5bb2839ee --- /dev/null +++ b/src/gzip/dmacopy.c @@ -0,0 +1,65 @@ + +#include + +/*----------------------------------------------------------------------------- + DMA転送 + u32 src_addr : 読み込み元カートリッジアドレス + void* dest_addr: 出力先メインメモリアドレス + u32 size : 転送サイズ(バイト数) +-----------------------------------------------------------------------------*/ + +#define DMAREADBLOCK 8192 + +OSPiHandle *osCartRomHandle() { + static OSPiHandle *cartHandle = NULL; + + if(cartHandle == NULL) { + cartHandle = osCartRomInit(); + } + + return cartHandle; +} + +u32 auRomDataRead(u32 src_addr, void* dest_addr, u32 size) +{ + static OSMesgQueue RomMessageQ; + static OSMesg RomMessageBuf; + static int initialized = 0; + + OSIoMesg dmaIoMesgBuf; + u32 romaddr, memaddr, sizectr, readlen; + + if(!initialized) { + osCreateMesgQueue(&RomMessageQ, &RomMessageBuf, 1); + initialized = 1; + } + + // CPUキャッシュの無効化 + osInvalDCache((void*)dest_addr, (s32)size); + + sizectr = size; + romaddr = src_addr; + memaddr = (u32)dest_addr; + + while(sizectr) { + readlen = MIN(sizectr, DMAREADBLOCK); + + dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL; + dmaIoMesgBuf.hdr.retQueue = &RomMessageQ; + dmaIoMesgBuf.dramAddr = (void *)memaddr; + dmaIoMesgBuf.devAddr = romaddr; + dmaIoMesgBuf.size = readlen; + + osEPiStartDma(osCartRomHandle(), &dmaIoMesgBuf, OS_READ); + + romaddr += readlen; + memaddr += readlen; + sizectr -= readlen; + + // DMA転送終了まで待つ + osRecvMesg(&RomMessageQ, NULL, OS_MESG_BLOCK); + } + + return (u32)dest_addr + size; +} + diff --git a/src/gzip/dmacopy.h b/src/gzip/dmacopy.h new file mode 100755 index 000000000..2bee460a7 --- /dev/null +++ b/src/gzip/dmacopy.h @@ -0,0 +1,8 @@ + +#if !defined(_DMACOPY_H_) +#define _DMACOPY_H_ + +extern OSPiHandle *osCartRomHandle(); +extern u32 auRomDataRead(u32 src_addr, void* dest_addr, u32 size); + +#endif // _DMACOPY_H_ diff --git a/src/gzip/gzip.h b/src/gzip/gzip.h index 9f9f7d7bf..d49b73e4b 100755 --- a/src/gzip/gzip.h +++ b/src/gzip/gzip.h @@ -1,6 +1,7 @@ #ifndef __GZIP_H__ #define __GZIP_H__ + #ifndef NULL #ifdef __cplusplus #define NULL 0 @@ -9,26 +10,50 @@ #endif #endif -#define INBUFSIZ 4096 // input buffer size +/* +#ifndef u8 +#define u8 unsigned char; +#endif +#ifndef u16 +#define u16 unsigned short; +#endif +#ifndef u32 +#define u32 unsigned long; +#endif +*/ + +#define INBUFSIZ 8192 // input buffer size +#define OUTBUFSIZ 8192 // output buffer size #define WSIZE 0x8000 typedef struct { - u8 * next_addr; + u32 next_addr; u32 rest_size; } FILE_HND; #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(0)) #define try_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf(1)) +/* Macros for getting two-byte and four-byte header values */ +#define SH(p) ((u16)(u8)((p)[0]) | ((u16)(u8)((p)[1]) << 8)) +#define LG(p) ((u32)(SH(p)) | ((u32)(SH((p)+2)) << 16)) + extern unsigned int insize; // valid bytes in inbuf extern unsigned int inptr; // index of next byte to be processed in inbuf extern unsigned int outcnt; // bytes in output buffer extern u8 inbuf[]; // input buffer -extern u8 *op; // Sliding window and suffix table +extern u8 outbuf[]; // output buffer +extern u8 window[]; // Sliding window and suffix table extern int inflate(void); extern int fill_inbuf(int eof_ok); extern void flush_window(void); -extern void dma_read(u8 *dest, u8 *srcStart, u8 *srcEnd); + + +//=========================================================================== +// +// +extern u32 expand_gzip(char *src_addr, char *dst_addr, u32 size); + #endif diff --git a/src/gzip/gzipdma.h b/src/gzip/gzipdma.h deleted file mode 100755 index 2012e5a44..000000000 --- a/src/gzip/gzipdma.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _GZIP_DMA_H_ -#define _GZIP_DMA_H_ - -#ifdef _LANGUAGE_C_PLUS_PLUS -extern "C" { -#endif - -void slidma(u8 *src_addr, u8 *dst_addr, u32 size); - -#ifdef _LANGUAGE_C_PLUS_PLUS -} -#endif - -#endif /* _GZIP_DMA_H_ */ diff --git a/src/gzip/gzipdma.c b/src/gzip/inflate.c similarity index 82% rename from src/gzip/gzipdma.c rename to src/gzip/inflate.c index 2f5afa25c..e26688696 100755 --- a/src/gzip/gzipdma.c +++ b/src/gzip/inflate.c @@ -1,9 +1,4 @@ -typedef unsigned long u32; -typedef unsigned short u16; -typedef unsigned char u8; - -extern void _bcopy(u8*, u8*, u32); - +#include #include "gzip.h" @@ -26,9 +21,11 @@ int inflate_dynamic(void); int inflate_block(int *); int inflate(void); + #define wp outcnt #define flush_output(w) (wp=(w),flush_window()) + // Order of the bit length code lengths static unsigned int border[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; @@ -74,7 +71,7 @@ int dbits = 6; /* bits in base distance lookup table */ unsigned int hufts; /* track memory usage */ // Buffer -#define GZIP_MEM_BUFFSIZ 8192 +#define GZIP_MEM_BUFFSIZ 16384 static char gzip_mem_buff[GZIP_MEM_BUFFSIZ]; static char *gzip_malloc_addr = gzip_mem_buff; static long gzip_malloc_tmp = 0; @@ -108,9 +105,11 @@ char *gzip_malloc(long size) // void gzip_free(char *ptr) { - ptr = NULL; - gzip_malloc_tmp = 0; - gzip_malloc_addr = gzip_mem_buff; + // Debug + //if ( gzip_malloc_tmp != 0 ) printf("%ld byte free\n", gzip_malloc_tmp); + + gzip_malloc_tmp = 0; + gzip_malloc_addr = gzip_mem_buff; } @@ -118,7 +117,14 @@ void gzip_free(char *ptr) //=========================================================================== // // -int huft_build(unsigned int *b, unsigned int n, unsigned int s, u16 *d, u16 *e, struct huft **t, int *m) +int huft_build(b, n, s, d, e, t, m) +unsigned int *b; /* code lengths in bits (all assumed <= BMAX) */ +unsigned int n; /* number of codes (assumed <= N_MAX) */ +unsigned int s; /* number of simple-valued codes (0..s-1) */ +u16 *d; /* list of base values for non-simple codes */ +u16 *e; /* list of extra bits for non-simple codes */ +struct huft **t; /* result: starting table */ +int *m; /* maximum lookup bits, returns actual */ { unsigned int a; /* counter for codes of length k */ unsigned int c[BMAX+1]; /* bit length count table */ @@ -133,7 +139,7 @@ int huft_build(unsigned int *b, unsigned int n, unsigned int s, u16 *d, u16 *e, register struct huft *q; /* points to current table */ struct huft r; /* table entry for structure assignment */ struct huft *u[BMAX]; /* table stack */ - static unsigned int v[N_MAX]; /* values in order of bit length */ + unsigned int v[N_MAX]; /* values in order of bit length */ register int w; /* bits before this table == (l * h) */ unsigned int x[BMAX+1]; /* bit offsets, then code stack */ unsigned int *xp; /* pointer into x */ @@ -276,7 +282,8 @@ int huft_build(unsigned int *b, unsigned int n, unsigned int s, u16 *d, u16 *e, -int huft_free(struct huft *t) +int huft_free(t) +struct huft *t; /* table to free */ { register struct huft *p, *q; @@ -291,7 +298,11 @@ int huft_free(struct huft *t) } -int inflate_codes(struct huft *tl, struct huft *td, int bl, int bd) +int inflate_codes(tl, td, bl, bd) +struct huft *tl, *td; /* literal/length and distance decoder tables */ +int bl, bd; /* number of bits decoded by tl[] and td[] */ +/* inflate (decompress) the codes in a deflated (compressed) block. + Return an error code or zero if it all goes ok. */ { register unsigned int e; /* table entry flag/number of extra bits */ unsigned int n, d; /* length and index for copy */ @@ -300,6 +311,8 @@ int inflate_codes(struct huft *tl, struct huft *td, int bl, int bd) unsigned int ml, md; /* masks for bl and bd bits */ register u32 b; /* bit buffer */ register unsigned int k; /* number of bits in bit buffer */ + unsigned int i; + u8 *src, *dst; /* make local copies of globals */ b = bb; /* initialize bit buffer */ @@ -321,10 +334,10 @@ int inflate_codes(struct huft *tl, struct huft *td, int bl, int bd) } DUMPBITS(t->b) if (e == 16) { /* then it's a literal */ - *op++ = (u8)t->v.n; - if (++w == WSIZE) { - flush_output(w); - w = 0; + window[w++] = (u8)t->v.n; + if (w == WSIZE) { + flush_output(w); + w = 0; } } else { /* it's an EOB or a length */ /* exit if end of block */ @@ -349,37 +362,32 @@ int inflate_codes(struct huft *tl, struct huft *td, int bl, int bd) d = w - t->v.n - ((unsigned int)b & mask_bits[e]); DUMPBITS(e) -#if 1 - { - u8 *ip = op + d - w; - do { - *op++ = *ip++; - ++w; - if (w == WSIZE) { - flush_output(w); - w = 0; - } - ++d; - } while (--n); - } -#else - /* do the copy */ do { - char *p; n -= (e = (e = WSIZE - ((d &= WSIZE-1) > w ? d : w)) > n ? n : e); - p = op - w + d; +/* +//#if !defined(NOMEMCPY) && !defined(DEBUG) + if (w - d >= e) { // (this test assumes unsigned comparison) + dst = (u8 *)( (u32)window + (u32)w ); + src = (u8 *)( (u32)window + (u32)d ); + for ( i = 0; i < e; i++ ) { + *dst = *src; + dst++; + src++; + } + w += e; + d += e; + } else // do it slow to avoid memcpy() overlap +//#endif !NOMEMCPY +*/ do { - w++; - d++; - *op++ = *p++; + window[w++] = window[d++]; } while (--e); if (w == WSIZE) { - flush_output(w); - w = 0; + flush_output(w); + w = 0; } } while (n); -#endif } } @@ -423,10 +431,9 @@ int inflate_stored(void) /* read and output the compressed data */ while (n--) { NEEDBITS(8) - w++; - *op++ = (u8)b; + window[w++] = (u8)b; if (w == WSIZE) { - flush_output(w); + flush_output(w); w = 0; } DUMPBITS(8) @@ -451,7 +458,7 @@ int inflate_fixed(void) struct huft *td; /* distance code table */ int bl; /* lookup bits for tl */ int bd; /* lookup bits for td */ -static unsigned int l[288]; /* length list for huft_build */ + unsigned int l[288]; /* length list for huft_build */ /* set up literal table */ for (i = 0; i < 144; i++) @@ -499,7 +506,7 @@ int inflate_dynamic(void) unsigned int nb; /* number of bit length codes */ unsigned int nl; /* number of literal/length codes */ unsigned int nd; /* number of distance codes */ -static unsigned int ll[288+32]; /* literal/length and distance code lengths */ + unsigned int ll[288+32]; /* literal/length and distance code lengths */ register u32 b; /* bit buffer */ register unsigned int k; /* number of bits in bit buffer */ @@ -601,7 +608,8 @@ static unsigned int ll[288+32]; /* literal/length and distance code lengths */ /* decompress an inflated block */ -int inflate_block(int *e) +int inflate_block(e) +int *e; /* last block flag */ { unsigned int t; /* block type */ register u32 b; /* bit buffer */ @@ -634,6 +642,8 @@ int inflate_block(int *e) return 2; } + + //=========================================================================== // decompress an inflated entry //=========================================================================== @@ -673,96 +683,3 @@ int inflate(void) // return success return 0; } - -// expansion buffer -unsigned char inbuf[INBUFSIZ]; -unsigned char *op; - -FILE_HND ifd; /* input file descriptor */ -unsigned int inptr; /* index of next byte to be processed in inbuf */ -unsigned int insize; /* valid bytes in inbuf */ -unsigned int outcnt; /* bytes in output buffer */ - -void clear_bufs(void); - -u32 data_read(FILE_HND *infile, u8 *dst_addr, u32 size) -{ - u32 i; - - if ( infile->rest_size < size ) size = infile->rest_size; - - i = ( size + 7 ) & 0xfffffff8; - - if ( i != 0 ) { - dma_read(dst_addr, infile->next_addr,infile->next_addr+i); - } - - infile->rest_size -= i; - infile->next_addr += i; - if ( infile->rest_size & 0x80000000 ) infile->rest_size = 0; - - return(size); -} - -//=========================================================================== -// unzip -// -int unzip(void) -{ - int res; - // - // Decompress - res = inflate(); - if ( res == 3 ) { - return(-1); - } else if ( res != 0 ) { - return(-1); - } - - return(0); -} - -//=========================================================================== -// Clear input and output buffers -void clear_bufs(void) -{ - insize = inptr = 0; -} - -//=========================================================================== -// Fill the input buffer. This is called only when the buffer is empty. -int fill_inbuf(int eof_ok) -{ - int len; - - insize = 0; - do { - len = data_read(&ifd, (char*)inbuf+insize, INBUFSIZ-insize); - if ( len == 0 || len == -1 ) break; - insize += len; - } while (insize < INBUFSIZ); - - if ( insize == 0 ) { - if (eof_ok) return -1; - } - - inptr = 1; - - return inbuf[0]; -} - -void flush_window(void) -{ - outcnt = 0; -} - - -void slidma(u8 *src_addr, u8 *dst_addr, u32 size) -{ - ifd.next_addr = src_addr; - ifd.rest_size = size; - op = dst_addr; - - clear_bufs(); - unzip(); -} diff --git a/src/gzip/unzip.c b/src/gzip/unzip.c new file mode 100755 index 000000000..33722d7d3 --- /dev/null +++ b/src/gzip/unzip.c @@ -0,0 +1,255 @@ +#include +#include "gzip.h" +#include "dmacopy.h" + +// 展開バッファ +Gfx gzip_dummy_dl[] = { + gsSPEndDisplayList(), +}; +unsigned char inbuf[INBUFSIZ]; +unsigned char outbuf[OUTBUFSIZ]; +unsigned char window[WSIZE]; + +// ワーク +FILE_HND ifd; /* input file descriptor */ +FILE_HND ofd; /* output file descriptor */ +long bytes_in; /* number of input bytes */ +long bytes_out; /* number of output bytes */ +unsigned int insize; /* valid bytes in inbuf */ +unsigned int inptr; /* index of next byte to be processed in inbuf */ +unsigned int outcnt; /* bytes in output buffer */ + + +void clear_bufs(void); +u32 updcrc(u8 *s, unsigned int n); + + +//======================================================================== +// Table of CRC-32's of all single-byte values +//======================================================================== +static u32 crc_32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + + +//=========================================================================== +// データの読み込み +// +u32 data_read(FILE_HND *infile, u8 *dst_addr, u32 size) +{ + u32 i; + + if ( infile->rest_size < size ) size = infile->rest_size; + + i = ( size + 7 ) & 0xfffffff8; + + if ( i != 0 ) { + auRomDataRead(infile->next_addr, (void *)dst_addr, i); + } + + infile->rest_size -= i; + infile->next_addr += i; + if ( infile->rest_size & 0x80000000 ) infile->rest_size = 0; + + return(size); +} + + + +//=========================================================================== +// メモリ書き出し +// +u32 data_write(FILE_HND *outfile, u8 *src_addr, unsigned int size) +{ + u32 i; + u8 *dst_addr = (u8 *)outfile->next_addr; + + for ( i = 0; i < size; i++ ) { + *dst_addr = src_addr[i]; + dst_addr++; + } + outfile->rest_size += size; + outfile->next_addr = (u32)dst_addr; + + return(size); +} + + + +//=========================================================================== +// 展開 +// +int unzip(void) +{ + int res; + int n; + u32 orig_crc; // original crc + u32 orig_len; // original uncompressed length + u8 buf[32]; // extended local header + + updcrc(NULL, 0); // initialize crc + + // Decompress + res = inflate(); + if ( res == 3 ) { + return(-1); + } else if ( res != 0 ) { + return(-1); + } + + // Get the crc and original length + for ( n = 0; n < 8; n++ ) buf[n] = (u8)get_byte(); + orig_crc = LG(buf); + orig_len = LG(buf+4); + +#if 0 // def DEBUG + if ( orig_len == bytes_out ) { + osSyncPrintf("=== ExpOK ===\n"); + } else { + osSyncPrintf("**** ExpError **** orglen : %d , outlen : %d\n", orig_len, bytes_out); + } +#endif + + return(0); +} + + + +//=========================================================================== +// Run a set of bytes through the crc shift register. If s is a NULL +// pointer, then initialize the crc shift register contents instead. +// Return the current crc in either case. +// +u32 updcrc(s, n) + u8 *s; /* pointer to bytes to pump through */ + unsigned int n; /* number of bytes in s[] */ +{ + register u32 c; /* temporary variable */ + + static u32 crc = 0xffffffff; /* shift register contents */ + + if ( s == NULL ) { + c = 0xffffffff; + } else { + c = crc; + if (n) do { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } while (--n); + } + crc = c; + return c ^ 0xffffffff; /* (instead of ~c for 64-bit machines) */ +} + + + +//=========================================================================== +// Clear input and output buffers +void clear_bufs(void) +{ + outcnt = 0; + insize = inptr = 0; + bytes_in = bytes_out = 0; +} + + + +//=========================================================================== +// Fill the input buffer. This is called only when the buffer is empty. +int fill_inbuf(int eof_ok) +{ + int len; + + insize = 0; + do { + len = data_read(&ifd, (char*)inbuf+insize, INBUFSIZ-insize); + if ( len == 0 || len == -1 ) break; + insize += len; + } while (insize < INBUFSIZ); + + if ( insize == 0 ) { + if (eof_ok) return -1; + } + + bytes_in += (u32)insize; + inptr = 1; + + return inbuf[0]; +} + + + +//=========================================================================== +// Does the same as write(), but also handles partial pipe writes and checks +// for error return. +void write_buf(FILE_HND *fd, char *buf, unsigned int cnt) +{ + u32 n; + + while ( ( n = data_write(fd, buf, cnt) ) != cnt ) { + cnt -= n; + buf += n; + } +} + + + +//=========================================================================== +// Write the output window window[0..outcnt-1] and update crc and bytes_out. +// (Used for the decompressed data only.) +void flush_window(void) +{ + if (outcnt == 0) return; + updcrc(window, outcnt); + + write_buf(&ofd, (char *)window, outcnt); + bytes_out += (u32)outcnt; + outcnt = 0; +} + + +//=========================================================================== +// データの読み込みと展開 +// input: +// char *src_addr ROM Address +// char *dst_addr RAM Adress +// u32 size ROM Size +// return: +// 展開後のサイズ +// +u32 expand_gzip(char *src_addr, char *dst_addr, u32 size) +{ + ifd.next_addr = (u32)src_addr; + ifd.rest_size = size; + ofd.next_addr = (u32)dst_addr; + ofd.rest_size = 0; + + clear_bufs(); + unzip(); + + return( ofd.rest_size ); +} \ No newline at end of file diff --git a/tools/.gitignore b/tools/.gitignore index f51778000..fcfd94662 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -3,6 +3,7 @@ /armips /bfsize /extract_data_for_mio +/filesizer /mio0 /n64cksum /n64graphics diff --git a/tools/Makefile b/tools/Makefile index d148500b9..4a2062c79 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -7,7 +7,7 @@ CC := gcc CXX := g++ CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -O2 -s LDFLAGS := -lm -ALL_PROGRAMS := armips bfsize n64graphics n64graphics_ci mio0 slienc n64cksum textconv patch_libultra_math aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv +ALL_PROGRAMS := armips bfsize filesizer n64graphics n64graphics_ci mio0 slienc n64cksum textconv patch_libultra_math aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv LIBAUDIOFILE := audiofile/libaudiofile.a # Only build armips from tools if it is not found on the system @@ -21,6 +21,8 @@ default: all bfsize_SOURCES := bfsize.c +filesizer_SOURCES := filesizer.c + n64graphics_SOURCES := n64graphics.c utils.c n64graphics_CFLAGS := -DN64GRAPHICS_STANDALONE diff --git a/tools/filesizer.c b/tools/filesizer.c new file mode 100644 index 000000000..6c3e5d411 --- /dev/null +++ b/tools/filesizer.c @@ -0,0 +1,62 @@ +#include +#include +#include + +FILE *fptr; +FILE *fptr2; +int insize; +int cmpsize; +unsigned char *bz; + +void writeint4(int val) +{ + fputc((val & 0x00ff000000) >> 24, fptr2); + fputc((val & 0x0000ff0000) >> 16, fptr2); + fputc((val & 0x000000ff00) >> 8, fptr2); + fputc((val & 0x00000000ff) >> 0, fptr2); +} + +int main(int argc, const char **argv) +{ + char src[999]; + char dest[999]; + + if( argc < 3 ) { + printf("Two arguments expected.\n"); + printf("Filesizer\n"); + printf("Usage: [infile] [outfile]\n"); + return 1; + } + + strcpy(src, argv[1]); + strcpy(dest, argv[2]); + + if ((fptr = fopen(src, "rb")) == NULL) + { + fprintf(stderr, "FILE OPEN ERROR![%s]\n", src); + return 1; + } + + if ((fptr2 = fopen(argv[2], "r+")) == NULL) + { + fprintf(stderr, "FILE APPEND ERROR![%s]\n", dest); + exit(1); + } + + fseek(fptr, 0, SEEK_END); + fseek(fptr2, 0, SEEK_END); + insize = ftell(fptr); + writeint4(0); + cmpsize = ftell(fptr2); + int numZeros = 0x10 - (cmpsize % 0x10); + for(int i = 0; i < numZeros; i++) + { + fputc(0, fptr2); + } + fseek(fptr2, -0x4, SEEK_END); + writeint4(insize); + fclose(fptr); + fclose(fptr2); + + return 0; +} \ No newline at end of file