From 3cc0fb536e87a2235a2b54bf56fb37c9493dc481 Mon Sep 17 00:00:00 2001 From: Nesbox Date: Tue, 21 Jul 2020 17:51:52 +0300 Subject: [PATCH] #1136: added new cart chunk CHUNK_CODE_ZIP for compressed code --- CMakeLists.txt | 4 ++-- src/cart.c | 42 ++++++++++++++++++++++++++++++------------ src/code.c | 2 +- src/config.c | 2 +- src/console.c | 18 +++++++++++------- src/studio.c | 11 ----------- src/studio.h | 3 --- src/tic.h | 12 ++++++++++-- src/tools.c | 11 +++++++++++ src/tools.h | 3 +++ 10 files changed, 69 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ebf1a1b16..2b4400f73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -344,7 +344,7 @@ target_include_directories(tic80core PUBLIC ${CMAKE_SOURCE_DIR}/include) -target_link_libraries(tic80core lua lpeg wren squirrel giflib blipbuf duktape) +target_link_libraries(tic80core lua lpeg wren squirrel giflib blipbuf duktape zlib) if(LINUX) target_link_libraries(tic80core m) @@ -663,7 +663,7 @@ endif() target_include_directories(${TIC80_OUTPUT}lib PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(${TIC80_OUTPUT}lib tic80core zlib zip wave_writer) +target_link_libraries(${TIC80_OUTPUT}lib tic80core zip wave_writer) if(N3DS) target_include_directories(${TIC80_OUTPUT}lib PRIVATE ${DEVKITPRO}/portlibs/3ds/include) diff --git a/src/cart.c b/src/cart.c index 3230ef8ee..fbe5cfdc6 100644 --- a/src/cart.c +++ b/src/cart.c @@ -21,6 +21,7 @@ // SOFTWARE. #include "cart.h" +#include "tools.h" #include #include @@ -42,6 +43,7 @@ typedef enum CHUNK_PATTERNS_DEP, // 13 - deprecated chunk CHUNK_MUSIC, // 14 CHUNK_PATTERNS, // 15 + CHUNK_CODE_ZIP, // 16 } ChunkType; typedef struct @@ -63,7 +65,7 @@ void tic_cart_load(tic_cartridge* cart, const u8* buffer, s32 size) bool paletteExists = false; - tic_code* code = calloc(TIC_BANKS, TIC_CODE_SIZE); + tic_code* code = calloc(TIC_BANKS, TIC_CODE_BANK_SIZE); if(!code) return; @@ -84,7 +86,10 @@ void tic_cart_load(tic_cartridge* cart, const u8* buffer, s32 size) case CHUNK_PATTERNS: LOAD_CHUNK(cart->banks[chunk.bank].music.patterns); break; case CHUNK_PALETTE: LOAD_CHUNK(cart->banks[chunk.bank].palette); break; case CHUNK_FLAGS: LOAD_CHUNK(cart->banks[chunk.bank].flags); break; - case CHUNK_CODE: LOAD_CHUNK(code[chunk.bank].data); break; + case CHUNK_CODE: LOAD_CHUNK(code->banks[chunk.bank].data); break; + case CHUNK_CODE_ZIP: + tic_tool_unzip(cart->code.data, TIC_CODE_SIZE, buffer, chunk.size); + break; case CHUNK_COVER: LOAD_CHUNK(cart->cover.data); cart->cover.size = chunk.size; @@ -119,19 +124,18 @@ void tic_cart_load(tic_cartridge* cart, const u8* buffer, s32 size) #undef LOAD_CHUNK // workaround to load code from banks - if(!strlen(cart->code.data)) + if(!*cart->code.data) for(s32 i = TIC_BANKS-1; i >= 0; i--) { - // add new line to split code banks + const char* data = code->banks[i].data; + + if(*data) { - s32 len = strlen(code[i].data); - if(len && len < TIC_CODE_SIZE && code[i].data[len - 1] != '\n') - strcat(code[i].data, "\n"); - } + if(*cart->code.data) + strcat(cart->code.data, "\n"); - if(strlen(code[i].data) + strlen(cart->code.data) < TIC_CODE_SIZE) - strcat(cart->code.data, code[i].data); - else break; + strcat(cart->code.data, data); + } } free(code); @@ -202,7 +206,21 @@ s32 tic_cart_save(const tic_cartridge* cart, u8* buffer) buffer = SAVE_CHUNK(CHUNK_FLAGS, cart->banks[i].flags, i); } - buffer = SAVE_CHUNK(CHUNK_CODE, cart->code, 0); + if(strlen(cart->code.data) > TIC_CODE_BANK_SIZE) + { + char* dst = malloc(TIC_CODE_BANK_SIZE); + s32 size = tic_tool_zip(dst, TIC_CODE_BANK_SIZE, cart->code.data, strlen(cart->code.data)); + + if(size) + buffer = saveFixedChunk(buffer, CHUNK_CODE_ZIP, dst, size, 0); + + free(dst); + + if(!size) + return 0; + } + else buffer = SAVE_CHUNK(CHUNK_CODE, cart->code, 0); + buffer = saveFixedChunk(buffer, CHUNK_COVER, cart->cover.data, cart->cover.size, 0); #undef SAVE_CHUNK diff --git a/src/code.c b/src/code.c index d2a69524b..9538c5c2b 100644 --- a/src/code.c +++ b/src/code.c @@ -275,7 +275,7 @@ static void updateEditor(Code* code) { sprintf(code->statusLine, "line %i/%i col %i", line + 1, getLinesCount(code) + 1, column + 1); - sprintf(code->statusSize, "%i/%i", (u32)strlen(code->src), TIC_CODE_SIZE); + sprintf(code->statusSize, "size %i", (u32)strlen(code->src)); } } diff --git a/src/config.c b/src/config.c index 0b5cd2af3..92b36acb8 100644 --- a/src/config.c +++ b/src/config.c @@ -311,7 +311,7 @@ static void setDefault(Config* config) if(embedBios) { - s32 size = unzip(embedBios, sizeof(tic_cartridge), DefaultBiosZip, sizeof DefaultBiosZip); + s32 size = tic_tool_unzip(embedBios, sizeof(tic_cartridge), DefaultBiosZip, sizeof DefaultBiosZip); if(size) update(config, embedBios, size); diff --git a/src/console.c b/src/console.c index 91c8ef996..31ba609c3 100644 --- a/src/console.c +++ b/src/console.c @@ -601,7 +601,7 @@ static void* getDemoCart(Console* console, ScriptLang script, s32* size) if(data) { - *size = unzip(data, sizeof(tic_cartridge), demo, romSize); + *size = tic_tool_unzip(data, sizeof(tic_cartridge), demo, romSize); if(*size) fsSaveRootFile(console->fs, path, data, *size, false); @@ -1106,7 +1106,7 @@ static void installDemoCart(FileSystem* fs, const char* name, const void* cart, if(data) { - s32 dataSize = unzip(data, sizeof(tic_cartridge), cart, size); + s32 dataSize = tic_tool_unzip(data, sizeof(tic_cartridge), cart, size); if(dataSize) fsSaveFile(fs, name, data, dataSize, true); @@ -1661,7 +1661,7 @@ static void* embedCart(Console* console, s32* size) if(zipData) { - if(zipSize = zip(zipData, zipSize, cart, cartSize)) + if(zipSize = tic_tool_zip(zipData, zipSize, cart, cartSize)) { EmbedHeader header = { @@ -1827,9 +1827,13 @@ static void onConsoleExportHtmlCommand(Console* console, const char* providedNam { s32 cartSize = tic_cart_save(&tic->cart, cart); - zip_entry_open(zip, "cart.tic"); - zip_entry_write(zip, cart, cartSize); - zip_entry_close(zip); + if(cartSize) + { + zip_entry_open(zip, "cart.tic"); + zip_entry_write(zip, cart, cartSize); + zip_entry_close(zip); + } + else errorOccured = true; free(cart); } @@ -3228,7 +3232,7 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config, if(data) { - s32 dataSize = unzip(data, sizeof(tic_cartridge), app + header->appSize + sizeof(EmbedHeader), header->cartSize); + s32 dataSize = tic_tool_unzip(data, sizeof(tic_cartridge), app + header->appSize + sizeof(EmbedHeader), header->cartSize); if(dataSize) { diff --git a/src/studio.c b/src/studio.c index 7164c606e..ff45bbcfd 100644 --- a/src/studio.c +++ b/src/studio.c @@ -44,7 +44,6 @@ #include "ext/md5.h" #include "wave_writer.h" -#include #include #include @@ -369,16 +368,6 @@ const char* studioExportMusic(s32 track) return WavPath; } -u32 zip(u8* dest, size_t destSize, const u8* source, size_t size) -{ - return compress2(dest, (unsigned long*)&destSize, source, size, Z_BEST_COMPRESSION) == Z_OK ? destSize : 0; -} - -u32 unzip(u8* dest, size_t destSize, const u8* source, size_t size) -{ - return uncompress(dest, (unsigned long*)&destSize, source, size) == Z_OK ? destSize : 0; -} - void sfx_stop(tic_mem* tic, s32 channel) { tic_api_sfx(tic, -1, 0, 0, -1, channel, MAX_VOLUME, SFX_DEF_SPEED); diff --git a/src/studio.h b/src/studio.h index 481f8ec99..85c7deff5 100644 --- a/src/studio.h +++ b/src/studio.h @@ -113,9 +113,6 @@ void resumeRunMode(); EditorMode getStudioMode(); void exitStudio(); -u32 zip(u8* dest, size_t destSize, const u8* source, size_t size); -u32 unzip(u8* dest, size_t bufSize, const u8* source, size_t size); - void toClipboard(const void* data, s32 size, bool flip); bool fromClipboard(void* data, s32 size, bool flip, bool remove_white_spaces); diff --git a/src/tic.h b/src/tic.h index 599ff669e..3db133a2a 100644 --- a/src/tic.h +++ b/src/tic.h @@ -86,10 +86,13 @@ #define WAVE_MAX_VALUE ((1 << WAVE_VALUE_BITS) - 1) #define WAVE_SIZE (WAVE_VALUES * WAVE_VALUE_BITS / BITS_IN_BYTE) -#define TIC_CODE_SIZE (64 * 1024) // 64K #define TIC_BANK_BITS 3 #define TIC_BANKS (1 << TIC_BANK_BITS) + +#define TIC_CODE_BANK_SIZE (64 * 1024) // 64K +#define TIC_CODE_SIZE (TIC_CODE_BANK_SIZE * TIC_BANKS) + #define TIC_GAMEPADS (sizeof(tic80_gamepads) / sizeof(tic80_gamepad)) #define SFX_NOTES {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"} @@ -357,9 +360,14 @@ typedef struct u8 data[TIC_SPRITESIZE * TIC_SPRITESIZE * TIC_PALETTE_BPP / BITS_IN_BYTE]; } tic_tile; -typedef struct +typedef union { char data[TIC_CODE_SIZE]; + + struct + { + char data[TIC_CODE_BANK_SIZE]; + } banks[TIC_BANKS]; } tic_code; typedef struct diff --git a/src/tools.c b/src/tools.c index 0f52f7d3e..4dc2f7e05 100644 --- a/src/tools.c +++ b/src/tools.c @@ -24,6 +24,7 @@ #include #include +#include extern void tic_tool_poke4(void* addr, u32 index, u8 value); extern u8 tic_tool_peek4(const void* addr, u32 index); @@ -180,3 +181,13 @@ void tic_tool_str2buf(const char* str, s32 size, void* buf, bool flip) ((u8*)buf)[i] = (u8)strtol(val, NULL, 16); } } + +u32 tic_tool_zip(u8* dest, size_t destSize, const u8* source, size_t size) +{ + return compress2(dest, (unsigned long*)&destSize, source, size, Z_BEST_COMPRESSION) == Z_OK ? destSize : 0; +} + +u32 tic_tool_unzip(u8* dest, size_t destSize, const u8* source, size_t size) +{ + return uncompress(dest, (unsigned long*)&destSize, source, size) == Z_OK ? destSize : 0; +} diff --git a/src/tools.h b/src/tools.h index 0b6f6fde7..0c7265f95 100644 --- a/src/tools.h +++ b/src/tools.h @@ -83,3 +83,6 @@ s32 tic_tool_get_track_row_sfx(const tic_track_row* row); void tic_tool_set_track_row_sfx(tic_track_row* row, s32 sfx); bool tic_tool_is_noise(const tic_waveform* wave); void tic_tool_str2buf(const char* str, s32 size, void* buf, bool flip); + +u32 tic_tool_zip(u8* dest, size_t destSize, const u8* source, size_t size); +u32 tic_tool_unzip(u8* dest, size_t bufSize, const u8* source, size_t size);