Fix most gzip things *EXCEPT THE ACTUAL DECOMPRESSION*

AYY LMAO
This commit is contained in:
CrashOveride95
2021-01-04 00:44:54 -05:00
parent 9e0fc1b088
commit d15c2d494d
11 changed files with 506 additions and 176 deletions

View File

@@ -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

View File

@@ -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

65
src/gzip/dmacopy.c Executable file
View File

@@ -0,0 +1,65 @@
#include <ultra64.h>
/*-----------------------------------------------------------------------------
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;
}

8
src/gzip/dmacopy.h Executable file
View File

@@ -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_

View File

@@ -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

View File

@@ -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_ */

View File

@@ -1,9 +1,4 @@
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
extern void _bcopy(u8*, u8*, u32);
#include <ultra64.h>
#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();
}

255
src/gzip/unzip.c Executable file
View File

@@ -0,0 +1,255 @@
#include <ultra64.h>
#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 );
}

1
tools/.gitignore vendored
View File

@@ -3,6 +3,7 @@
/armips
/bfsize
/extract_data_for_mio
/filesizer
/mio0
/n64cksum
/n64graphics

View File

@@ -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

62
tools/filesizer.c Normal file
View File

@@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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;
}