git subrepo pull tools/z64compress --force

subrepo:
  subdir:   "tools/z64compress"
  merged:   "43035d97f"
upstream:
  origin:   "https://github.com/z64me/z64compress.git"
  branch:   "main"
  commit:   "43035d97f"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
angie 2023-03-12 11:23:29 -03:00
parent 768094b1a8
commit 2e487b5008
18 changed files with 254 additions and 51 deletions

3
tools/z64compress/.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "src/enc/libdeflate"]
path = src/enc/libdeflate
url = https://github.com/ebiggers/libdeflate

View File

@ -6,7 +6,7 @@
[subrepo] [subrepo]
remote = https://github.com/z64me/z64compress.git remote = https://github.com/z64me/z64compress.git
branch = main branch = main
commit = 5da3132606e4fd427a8d72b8428e4f921cd6e56f commit = 43035d97f2e750332d9644438bc4f687f073a4dd
parent = 837eb1c80687fe9b57a3c7b841547c33feeed6c7 parent = 768094b1a889b2253b3e905b99792efaecd3e879
method = merge method = merge
cmdver = 0.4.3 cmdver = 0.4.3

View File

@ -24,10 +24,12 @@ endif
OBJ_DIR := o/$(TARGET) OBJ_DIR := o/$(TARGET)
$(OBJ_DIR)/src/enc/%.o: CFLAGS := -DNDEBUG -s -Ofast -flto -Wall $(OBJ_DIR)/src/enc/%.o: CFLAGS := -DNDEBUG -s -Ofast -flto -Wall -Isrc/enc/libdeflate
SRC_DIRS := $(shell find src -type d) SRC_DIRS := $(shell find src -type d)
C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) C_DIRS := $(shell find src -type d -not -path "src/enc/libdeflate/*")
C_FILES := $(foreach dir,$(C_DIRS),$(wildcard $(dir)/*.c))
C_FILES += src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c
O_FILES := $(foreach f,$(C_FILES:.c=.o),$(OBJ_DIR)/$f) O_FILES := $(foreach f,$(C_FILES:.c=.o),$(OBJ_DIR)/$f)
# Make build directories # Make build directories
@ -38,7 +40,7 @@ $(shell mkdir -p $(foreach dir,$(SRC_DIRS),$(OBJ_DIR)/$(dir)))
all: z64compress all: z64compress
z64compress: $(O_FILES) z64compress: $(O_FILES)
$(CC) $(TARGET_CFLAGS) $(CFLAGS) $(O_FILES) -lm -lpthread $(TARGET_LIBS) -o z64compress $(CC) $(TARGET_CFLAGS) $(CFLAGS) $(O_FILES) -lm -lpthread -lz $(TARGET_LIBS) -o z64compress
$(OBJ_DIR)/%.o: %.c $(OBJ_DIR)/%.o: %.c
$(CC) -c $(TARGET_CFLAGS) $(CFLAGS) $< -o $@ $(CC) -c $(TARGET_CFLAGS) $(CFLAGS) $< -o $@

View File

@ -2,7 +2,7 @@
`z64compress` is a program for compressing Zelda 64 roms: be they retail, hacked traditionally, or custom-built from the [`Ocarina of Time`](https://github.com/zeldaret/oot) or [`Majora's Mask`](https://github.com/zeldaret/mm) reverse engineering projects. It is written in highly efficient C and leverages the power of multithreading to make compression as fast as possible. To reduce overhead on subsequent compressions, an optional cache directory can be specified. `z64compress` is a program for compressing Zelda 64 roms: be they retail, hacked traditionally, or custom-built from the [`Ocarina of Time`](https://github.com/zeldaret/oot) or [`Majora's Mask`](https://github.com/zeldaret/mm) reverse engineering projects. It is written in highly efficient C and leverages the power of multithreading to make compression as fast as possible. To reduce overhead on subsequent compressions, an optional cache directory can be specified.
In addition to the default `yaz`, it supports some faster and more compact algorithms such as `lzo`, `ucl`, and `aplib`. In order to use these, grab patches or code from my [`z64enc` repository](https://github.com/z64me/z64enc). In addition to the default `yaz`, it supports some faster and more compact algorithms such as `DEFLATE`, `lzo`, `ucl`, and `aplib`. In order to use these, grab patches or code from my [`z64enc` repository](https://github.com/z64me/z64enc).
If you add an algorithm, please make sure `valgrind` reports no memory leaks or other errors before making a pull request. Thank you! If you add an algorithm, please make sure `valgrind` reports no memory leaks or other errors before making a pull request. Thank you!
@ -59,6 +59,7 @@ This is a command line application. Learn from these common examples and adapt t
yaz yaz
ucl ucl
lzo lzo
zlib
aplib aplib
* to use non-yaz codecs, find patches * to use non-yaz codecs, find patches
and code on my z64enc repo and code on my z64enc repo
@ -89,6 +90,13 @@ This is a command line application. Learn from these common examples and adapt t
``` ```
## Building ## Building
I have included shell scripts for building Linux and Windows binaries. Windows binaries are built using a cross compiler ([I recommend `MXE`](https://mxe.cc/)). First, clone the repository and initialize its submodules:
```
git clone https://github.com/z64me/z64compress.git
cd z64compress
git submodule update --init
```
Alternatively, a Makefile-based build system is provided. Choose the target platform with `make TARGET=linux64|linux32|win32`, default is linux64. If building for windows with a cross compiler, specify the compiler executable with `make TARGET=win32 CC=/path/to/executable`. A Makefile-based build system is provided. Choose the target platform with `make TARGET=linux64|linux32|win32`, default is linux64. If building for windows with a cross compiler, specify the compiler executable with `make TARGET=win32 CC=/path/to/executable`.
Alternatively, I have included shell scripts for building Linux and Windows binaries. Windows binaries are built using a cross compiler ([I recommend `MXE`](https://mxe.cc/)).

View File

@ -4,7 +4,7 @@ mkdir -p o
mv *.o o mv *.o o
# build everything else # build everything else
gcc -o z64compress -DNDEBUG src/*.c o/*.o -Wall -Wextra -s -Os -flto -lpthread -march=native -mtune=native gcc -o z64compress -DNDEBUG src/*.c o/*.o src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c -Isrc/enc/libdeflate -Wall -Wextra -s -Os -flto -lpthread -lz -march=native -mtune=native
# move to bin directory # move to bin directory
mkdir -p bin/linux64 mkdir -p bin/linux64

View File

@ -4,7 +4,7 @@ mkdir -p o
mv *.o o mv *.o o
# build everything else # build everything else
gcc -m32 -o z64compress -DNDEBUG src/*.c o/*.o -Wall -Wextra -s -Os -flto -lpthread -march=native -mtune=native gcc -m32 -o z64compress -DNDEBUG src/*.c o/*.o src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c -Isrc/enc/libdeflate -Wall -Wextra -s -Os -flto -lpthread -lz -march=native -mtune=native
# move to bin directory # move to bin directory
mkdir -p bin/linux32 mkdir -p bin/linux32

View File

@ -1,10 +1,10 @@
# build compression functions (slow) # build compression functions (slow)
~/c/mxe/usr/bin/i686-w64-mingw32.static-gcc -DNDEBUG -s -Ofast -flto -lm -c -Wall src/enc/*.c src/enc/lzo/*.c src/enc/ucl/comp/*.c src/enc/apultra/*.c i686-w64-mingw32.static-gcc -DNDEBUG -s -Ofast -flto -lm -c -Wall src/enc/*.c src/enc/lzo/*.c src/enc/ucl/comp/*.c src/enc/apultra/*.c
mkdir -p o mkdir -p o
mv *.o o mv *.o o
# build everything else # build everything else
~/c/mxe/usr/bin/i686-w64-mingw32.static-gcc -o z64compress.exe -DNDEBUG src/*.c o/*.o -Wall -Wextra -s -Os -flto -lpthread -mconsole -municode i686-w64-mingw32.static-gcc -o z64compress.exe -DNDEBUG src/*.c o/*.o src/enc/libdeflate/lib/deflate_compress.c src/enc/libdeflate/lib/utils.c -Isrc/enc/libdeflate -Wall -Wextra -s -Os -flto -lpthread -lz -mconsole -municode
# move to bin directory # move to bin directory
mkdir -p bin/win32 mkdir -p bin/win32

View File

@ -21,8 +21,8 @@ aplenc(
int nMaxCompressedSize = apultra_get_max_compressed_size(src_sz); int nMaxCompressedSize = apultra_get_max_compressed_size(src_sz);
apultra_stats stats; apultra_stats stats;
int hlen = 8; /* header length; required due to MM's archives */ extern int g_hlen; /* header length */
memset(dst, 0, hlen); memset(dst, 0, g_hlen);
memcpy(dst, "APL0", 4); memcpy(dst, "APL0", 4);
dst[4] = (src_sz >> 24); dst[4] = (src_sz >> 24);
dst[5] = (src_sz >> 16); dst[5] = (src_sz >> 16);
@ -31,7 +31,7 @@ aplenc(
*dst_sz = apultra_compress( *dst_sz = apultra_compress(
src src
, dst + hlen , dst + g_hlen
, src_sz , src_sz
, nMaxCompressedSize , nMaxCompressedSize
, 0 /* flags */ , 0 /* flags */
@ -41,7 +41,7 @@ aplenc(
, &stats , &stats
); );
*dst_sz = *dst_sz + hlen; *dst_sz = *dst_sz + g_hlen;
return 0; return 0;
} }

View File

@ -38,6 +38,15 @@ int zx7enc(
, void *_ctx , void *_ctx
); );
int
zlibenc(
void *_src
, unsigned src_sz
, void *_dst
, unsigned *dst_sz
, void *_ctx
);
int aplenc( int aplenc(
void *_src void *_src
, unsigned src_sz , unsigned src_sz

@ -0,0 +1 @@
Subproject commit 6c095314d0c49061f41e1e40be2625dfc2253afa

View File

@ -33,8 +33,8 @@ lzoenc(
unsigned char *wrkmem = _ctx; unsigned char *wrkmem = _ctx;
lzo_uint result_sz = 0; lzo_uint result_sz = 0;
int hlen = 8; /* header length; required due to MM's archives */ extern int g_hlen; /* header length */
memset(dst, 0, hlen); memset(dst, 0, g_hlen);
memcpy(dst, "LZO0", 4); memcpy(dst, "LZO0", 4);
dst[4] = (src_sz >> 24); dst[4] = (src_sz >> 24);
dst[5] = (src_sz >> 16); dst[5] = (src_sz >> 16);
@ -46,9 +46,9 @@ lzoenc(
memset(wrkmem, 0, LZO1X_999_MEM_COMPRESS); memset(wrkmem, 0, LZO1X_999_MEM_COMPRESS);
lzo1x_999_compress(src, src_sz, dst + hlen, &result_sz, wrkmem); lzo1x_999_compress(src, src_sz, dst + g_hlen, &result_sz, wrkmem);
*dst_sz = result_sz + hlen; *dst_sz = result_sz + g_hlen;
return 0; return 0;
} }

View File

@ -18,8 +18,8 @@ uclenc(
int level = 10; int level = 10;
ucl_uint result_sz; ucl_uint result_sz;
int hlen = 8; /* header length; required due to MM's archives */ extern int g_hlen; /* header length */
memset(dst, 0, hlen); memset(dst, 0, g_hlen);
memcpy(dst, "UCL0", 4); memcpy(dst, "UCL0", 4);
dst[4] = (src_sz >> 24); dst[4] = (src_sz >> 24);
dst[5] = (src_sz >> 16); dst[5] = (src_sz >> 16);
@ -29,7 +29,7 @@ uclenc(
r = ucl_nrv2b_99_compress( r = ucl_nrv2b_99_compress(
src /* in */ src /* in */
, src_sz /* in size */ , src_sz /* in size */
, dst + hlen /* out */ , dst + g_hlen /* out */
, &result_sz /* out size */ , &result_sz /* out size */
, NULL /* callback */ , NULL /* callback */
, level /* level */ , level /* level */
@ -43,7 +43,7 @@ uclenc(
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
*dst_sz = result_sz + hlen; *dst_sz = result_sz + g_hlen;
return 0; return 0;
} }

View File

@ -1,5 +1,12 @@
/* <z64.me> yar.c: decode and encode MM yaz archives */ /* <z64.me> yar.c: decode and encode MM yaz archives */
/*
* this file can also be compiled as a standalone program for
* decompressing the contents of a MM yaz archive like so:
* gcc -o unyar -Wall -Wextra -std=c99 -pedantic -DYAR_MAIN_TEST=1 yar.c
*
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
@ -231,7 +238,7 @@ yar_reencode(
ss += 4; ss += 4;
item += 1; item += 1;
} while (ss - src < end); } while ((unsigned)(ss - src) < end);
/* update progress display */ /* update progress display */
if (name) if (name)
@ -277,7 +284,7 @@ yar_reencode(
/* yaz decoder, courtesy of spinout182 */ /* yaz decoder, courtesy of spinout182 */
static static
int spinout_yaz_dec(void *_src, void *_dst, int dstSz) int spinout_yaz_dec(void *_src, void *_dst, unsigned dstSz, unsigned *srcSz)
{ {
unsigned char *src = _src; unsigned char *src = _src;
unsigned char *dst = _dst; unsigned char *dst = _dst;
@ -328,7 +335,7 @@ int spinout_yaz_dec(void *_src, void *_dst, int dstSz)
} }
/*copy run*/ /*copy run*/
int i; unsigned int i;
for(i = 0; i < numBytes; ++i) for(i = 0; i < numBytes; ++i)
{ {
dst[dstPlace] = dst[copySource]; dst[dstPlace] = dst[copySource];
@ -343,12 +350,14 @@ int spinout_yaz_dec(void *_src, void *_dst, int dstSz)
} }
return 0; return 0;
(void)srcSz;
} }
/* encodes decompressed data, storing result in dst */ /* encodes decompressed data, storing result in dst */
static static
int encode(void *src, int srcSz, void *_dst, int *dstSz, void *ctx) int encode(void *src, unsigned srcSz, void *_dst, unsigned *dstSz, void *ctx)
{ {
unsigned char *dst = _dst; unsigned char *dst = _dst;
@ -368,15 +377,22 @@ int encode(void *src, int srcSz, void *_dst, int *dstSz, void *ctx)
*dstSz = srcSz + 0x10; *dstSz = srcSz + 0x10;
return 0; return 0;
(void)ctx;
} }
/* checks if data has already been encoded */ /* checks if data has already been encoded */
/* if it does, dst is filled with that data and 1 is returned */ /* if it does, dst is filled with that data and 1 is returned */
/* 0 is returned otherwise */ /* 0 is returned otherwise */
static static
int exist(void *src, int srcSz, void *dst, int *dstSz) int exist(void *src, unsigned srcSz, void *dst, unsigned *dstSz)
{ {
return 0; return 0;
(void)src;
(void)srcSz;
(void)dst;
(void)dstSz;
} }
/* unsafe but it's a test program so it's fine */ /* unsafe but it's a test program so it's fine */
@ -412,17 +428,39 @@ file_read(char *fn, unsigned *sz)
return raw; return raw;
} }
/* minimal file writer
* returns 0 on failure
* returns non-zero on success
*/
int savefile(const char *fn, const void *dat, const size_t sz)
{
FILE *fp;
/* rudimentary error checking returns 0 on any error */
if (
!fn
|| !sz
|| !dat
|| !(fp = fopen(fn, "wb"))
|| fwrite(dat, 1, sz, fp) != sz
|| fclose(fp)
)
return 0;
return 1;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned char *raw; void *raw;
unsigned int raw_sz; unsigned int raw_sz;
unsigned char *out; void *out;
unsigned char *imm; void *imm;
unsigned int out_sz = 0; unsigned int out_sz = 0;
if (argc != 2) if (argc != 3)
FERR("args: unyar in.yar > out.yar"); FERR("args: unyar in.yar out.yar");
raw = file_read(argv[1], &raw_sz); raw = file_read(argv[1], &raw_sz);
fprintf(stderr, "input file %s:\n", argv[1]); fprintf(stderr, "input file %s:\n", argv[1]);
@ -432,18 +470,21 @@ int main(int argc, char *argv[])
imm = malloc(1024 * 1024 * 64); imm = malloc(1024 * 1024 * 64);
yar_reencode( yar_reencode(
raw, raw_sz, out, &out_sz, 12, "Yaz0", imm raw, raw_sz, out, &out_sz, 16, argv[1], "Yaz0", imm, 0
, spinout_yaz_dec , spinout_yaz_dec
, encode , encode
, exist , exist
); );
/* write output to stdout */ /* write output file */
fwrite(out, 1, out_sz, stdout); if (!savefile(argv[2], out, out_sz))
FERR("failed to write output file");
free(raw); free(raw);
free(out); free(out);
free(imm); free(imm);
return 0;
} }
#endif /* YAR_MAIN_TEST */ #endif /* YAR_MAIN_TEST */

View File

@ -272,16 +272,24 @@ uint32_t encode(struct yazCtx *ctx, uint8_t *data, uint32_t data_size, uint8_t *
// block and stream differentiation // block and stream differentiation
// Yay is block, Yaz is stream // Yay is block, Yaz is stream
int mode_block=1, mode_stream=1; // temporary, for testing int mode_block=1, mode_stream=1; // temporary, for testing
#ifdef YAZ_MAIN_TEST
int g_hlen = 8;
#else
extern int g_hlen;
#endif
mode_block=!strcmp(mode,"Yay0"); mode_block=!strcmp(mode,"Yay0");
if (mode_block ) { if (g_hlen) {
uint32_t l = (sb_count(ctx->cmds) << 2) + 16;
uint32_t o = (sb_count(ctx->ctrl) << 1) + l;
memcpy(output, mode, 4); memcpy(output, mode, 4);
U32wr(output+4, sz); U32wr(output+4, sz);
} else
output -= 8; /* headerless */
if (mode_block) {
uint32_t l = (sb_count(ctx->cmds) << 2) + 16;
uint32_t o = (sb_count(ctx->ctrl) << 1) + l;
U32wr(output+8, l); U32wr(output+8, l);
U32wr(output+12, o); U32wr(output+12, o);
uint32_t output_position = 16; uint32_t output_position = g_hlen + 8;
uint32_t x; uint32_t x;
for (x=0; x<sb_count(ctx->cmds); x++) { for (x=0; x<sb_count(ctx->cmds); x++) {
U32wr(output+output_position, ctx->cmds[x]); U32wr(output+output_position, ctx->cmds[x]);
@ -296,8 +304,6 @@ uint32_t encode(struct yazCtx *ctx, uint8_t *data, uint32_t data_size, uint8_t *
} }
return output_position; return output_position;
} else if(mode_stream) { } else if(mode_stream) {
memcpy(output, mode, 4);
U32wr(output+4, sz);
U32wr(output+8, 0); U32wr(output+8, 0);
U32wr(output+12, 0); U32wr(output+12, 0);
@ -315,8 +321,8 @@ uint32_t encode(struct yazCtx *ctx, uint8_t *data, uint32_t data_size, uint8_t *
sb_push(ctx->back, (ctx->ctrl[x]>>8)&0xFF); sb_push(ctx->back, (ctx->ctrl[x]>>8)&0xFF);
sb_push(ctx->back, (ctx->ctrl[x])&0xFF); sb_push(ctx->back, (ctx->ctrl[x])&0xFF);
} }
output_position = _enc_z_from_tables(ctx, ctx->ctl, ctx->back, ctx->raws, output+16, data_size, mode); output_position = _enc_z_from_tables(ctx, ctx->ctl, ctx->back, ctx->raws, output+g_hlen+8, data_size, mode);
return 16 + output_position; return output_position + g_hlen + 8;
} }
return 0; return 0;
} }

View File

@ -0,0 +1,103 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <zlib.h>
#include "libdeflate/libdeflate.h"
#define CAPACITY (1024 * 1024 * 4) /* output buffer max (4 mb) */
int
zlibenc(
void *_src
, unsigned src_sz
, void *_dst
, unsigned *dst_sz
, void *_ctx
)
{
unsigned char *src = _src;
unsigned char *dst = _dst;
unsigned result_sz;
extern int g_hlen; /* header length */
memset(dst, 0, g_hlen);
memcpy(dst, "ZLIB", 4);
dst[4] = (src_sz >> 24);
dst[5] = (src_sz >> 16);
dst[6] = (src_sz >> 8);
dst[7] = (src_sz >> 0);
/* zlib and gzip have different header lengths
* https://stackoverflow.com/a/68538037
*/
#if 1
#if 0 /* zlib */
z_stream stream = {0};
int r;
stream.avail_in = src_sz;
stream.next_in = src;
stream.avail_out = CAPACITY;
stream.next_out = dst + g_hlen;
#define HEADER_LEN 2
if ((r = deflateInit(&stream, Z_BEST_COMPRESSION)) != Z_OK)
{
fprintf(stderr, "[!] fatal compression error %d\n", r);
exit(EXIT_FAILURE);
}
if ((r = deflate(&stream, Z_FINISH)) == Z_STREAM_ERROR)
{
fprintf(stderr, "[!] Z_STREAM_ERROR\n");
exit(EXIT_FAILURE);
}
deflateEnd(&stream);
result_sz = CAPACITY - stream.avail_out;
#else /* libdeflate */
#define HEADER_LEN 0
int level = 12;
struct libdeflate_compressor *compressor;
compressor = libdeflate_alloc_compressor(level);
result_sz = libdeflate_deflate_compress(
compressor
, src, src_sz
, dst + g_hlen
, CAPACITY
);
libdeflate_free_compressor(compressor);
#endif
#else
/* this gzip code was left in for testing purposes; it may
* be useful if matching ique recompression is ever revisited;
* ique matches (except for one byte...) when compressed using
* gzip 1.2.4 or 1.2.4a (they produce identical results),
* available here: https://ftp.gnu.org/gnu/gzip/
* this is not a compression error, because decompressing the
* recompressed rom produces a rom identical to the original
* decompressed ique rom;
* TODO: find out why that byte doesn't match on recompression;
* TODO: once that's working, add --codec ique for those wanting
* matching ique recompression; otherwise, modern zlib works great!
*/
#define HEADER_LEN 10
FILE *fp = fopen("tmp.bin", "wb");
fwrite(src, 1, src_sz, fp);
fclose(fp);
system("./gzip -c -9 -n tmp.bin > tmp.bin.gzip");
fp = fopen("tmp.bin.gzip", "rb");
fseek(fp, 0, SEEK_END);
result_sz = ftell(fp);
fseek(fp, 0, SEEK_SET);
fread(dst, 1, result_sz, fp);
fclose(fp);
#endif
*dst_sz = result_sz + g_hlen;
/* trim zlib/gzip header */
memmove(dst + g_hlen, dst + g_hlen + HEADER_LEN, result_sz);
*dst_sz -= HEADER_LEN;
return 0;
(void)_ctx; /* -Wunused-parameter */
}

View File

@ -16,20 +16,20 @@ zx7enc(
unsigned char *src = _src; unsigned char *src = _src;
unsigned char *dst = _dst; unsigned char *dst = _dst;
int hlen = 8; /* header length; required due to MM's archives */ extern int g_hlen; /* header length */
memset(dst, 0, hlen); memset(dst, 0, g_hlen);
memcpy(dst, "ZX70", 4); memcpy(dst, "ZX70", 4);
dst[4] = (src_sz >> 24); dst[4] = (src_sz >> 24);
dst[5] = (src_sz >> 16); dst[5] = (src_sz >> 16);
dst[6] = (src_sz >> 8); dst[6] = (src_sz >> 8);
dst[7] = (src_sz >> 0); dst[7] = (src_sz >> 0);
*dst_sz = ZX7Compress(src, src_sz, dst + hlen); *dst_sz = ZX7Compress(src, src_sz, dst + g_hlen);
if (!*dst_sz) if (!*dst_sz)
return 1; return 1;
*dst_sz += hlen; *dst_sz += g_hlen;
return 0; return 0;
} }

View File

@ -8,6 +8,7 @@
#include "rom.h" #include "rom.h"
FILE* printer; FILE* printer;
int g_hlen = 8;
static void compress(struct rom *rom, int start, int end) static void compress(struct rom *rom, int start, int end)
{ {
@ -167,6 +168,7 @@ static void usage(void)
fprintf(printer, " yaz\n"); fprintf(printer, " yaz\n");
fprintf(printer, " ucl\n"); fprintf(printer, " ucl\n");
fprintf(printer, " lzo\n"); fprintf(printer, " lzo\n");
fprintf(printer, " zlib\n");
fprintf(printer, " aplib\n"); fprintf(printer, " aplib\n");
fprintf(printer, " * to use non-yaz codecs, find patches\n"); fprintf(printer, " * to use non-yaz codecs, find patches\n");
fprintf(printer, " and code on my z64enc repo\n"); fprintf(printer, " and code on my z64enc repo\n");
@ -184,6 +186,8 @@ static void usage(void)
fprintf(printer, "\n"); fprintf(printer, "\n");
fprintf(printer, " --skip disable compression on specified files\n"); fprintf(printer, " --skip disable compression on specified files\n");
fprintf(printer, "\n"); fprintf(printer, "\n");
fprintf(printer, " --headerless don't write file headers (for iQue)\n");
fprintf(printer, "\n");
fprintf(printer, " --repack handles Majora's Mask archives\n"); fprintf(printer, " --repack handles Majora's Mask archives\n");
fprintf(printer, "\n"); fprintf(printer, "\n");
fprintf(printer, " --threads optional multithreading;\n"); fprintf(printer, " --threads optional multithreading;\n");
@ -209,6 +213,7 @@ wow_main
int Athreads = 0; int Athreads = 0;
bool Amatching = false; bool Amatching = false;
bool Aonly_stdout = false; bool Aonly_stdout = false;
bool Aheaderless = false;
wow_main_argv; wow_main_argv;
printer = stderr; printer = stderr;
@ -253,6 +258,15 @@ wow_main
i--; i--;
continue; continue;
} }
else if (!strcmp(arg, "--headerless"))
{
if (Aheaderless)
die("--headerless arg provided more than once");
Aheaderless = true;
g_hlen = 0;
i--;
continue;
}
/* arguments with additional parameters */ /* arguments with additional parameters */

View File

@ -462,6 +462,14 @@ static const struct encoder *encoder(const char *name)
return &zx7; return &zx7;
}*/ }*/
else if (!strcmp(name, "zlib"))
{
static const struct encoder zlib = {
.encfunc = zlibenc
};
return &zlib;
}
else if (!strcmp(name, "aplib")) else if (!strcmp(name, "aplib"))
{ {
static const struct encoder aplib = { static const struct encoder aplib = {
@ -1112,7 +1120,7 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching)
comp_total += sz16; comp_total += sz16;
if (mb != 0 && dma->Pend > compsz) if (mb != 0 && dma->Pend > compsz)
die("ran out of compressed rom space"); die("ran out of compressed rom space (try increasing --mb)");
} }
/* adaptive final size */ /* adaptive final size */
@ -1660,6 +1668,14 @@ struct rom *rom_new(const char *fn)
/* propagate rom file */ /* propagate rom file */
dst->data = file_load(fn, &dst->data_sz); dst->data = file_load(fn, &dst->data_sz);
/* double its bounds just in case compressed rom is larger
* (this can happen if, say, a 23mb rom is provided,
* gets compressed to 17mb, and is rounded up to 24mb)
* (retail rom sizes always use increments of 8)
*/
dst->data_sz *= 2;
dst->data = realloc(dst->data, dst->data_sz);
/* back up load file name */ /* back up load file name */
dst->fn = strdup_safe(fn); dst->fn = strdup_safe(fn);