From de7557e4f9dc06914c5defc06021462655ccfcba Mon Sep 17 00:00:00 2001 From: "BADIM-PC\\Vadim" Date: Fri, 22 Dec 2017 16:13:34 +0300 Subject: [PATCH] #341 native export has been restored and now it supports compressing --- src/console.c | 302 ++++++++++++++++++++++++++++++++------------------ src/console.h | 1 - 2 files changed, 192 insertions(+), 111 deletions(-) diff --git a/src/console.c b/src/console.c index a331f0c..edadb52 100644 --- a/src/console.c +++ b/src/console.c @@ -47,6 +47,16 @@ typedef enum JavaScript, } ScriptLang; +static const char TicCartSig[] = "TIC.CART"; +#define SIG_SIZE (sizeof TicCartSig-1) + +typedef struct +{ + u8 sig[SIG_SIZE]; + s32 appSize; + s32 cartSize; +} EmbedHeader; + #if defined(__WINDOWS__) || defined(__LINUX__) || defined(__MACOSX__) #define CAN_EXPORT 1 #endif @@ -1163,7 +1173,7 @@ static void onConsoleDirCommand(Console* console, const char* param) commandDone(console); } -#ifdef CAN_EXPORT +#if defined(CAN_EXPORT) static void onConsoleFolderCommand(Console* console, const char* param) { @@ -1757,146 +1767,172 @@ static void onConsoleExportHtmlCommand(Console* console, const char* name) SDL_free(EmbedTicJs); } -// #ifdef CAN_EXPORT +#if defined(CAN_EXPORT) -// static void* embedCart(Console* console, s32* size) -// { -// tic_mem* tic = console->tic; +static void* embedCart(Console* console, s32* size) +{ + tic_mem* tic = console->tic; -// void* data = fsReadFile(console->appPath, size); + u8* data = NULL; + s32 appSize = 0; + void* app = fsReadFile(console->appPath, &appSize); -// if(data) -// { -// void* start = memmem(data, *size, embed.prefix, sizeof(embed.prefix)); + if(app) + { + void* cart = SDL_malloc(sizeof(tic_cartridge)); -// if(start) -// { -// embed.yes = true; -// SDL_memcpy(&embed.file, &tic->cart, sizeof(tic_cartridge)); -// SDL_memcpy(start, &embed, sizeof(embed)); -// embed.yes = false; -// } + if(cart) + { + s32 cartSize = tic->api.save(&tic->cart, cart); -// return data; -// } + { + unsigned long zipSize = sizeof(tic_cartridge); + u8* zip = (u8*)SDL_malloc(zipSize); + + if(zip) + { + compress2(zip, &zipSize, cart, cartSize, Z_BEST_COMPRESSION); + + { + EmbedHeader header = + { + .appSize = appSize, + .cartSize = zipSize, + }; + + SDL_memcpy(header.sig, TicCartSig, SIG_SIZE); + + s32 finalSize = appSize + sizeof header + header.cartSize; + data = SDL_malloc(finalSize); + + if(data) + { + SDL_memcpy(data, app, appSize); + SDL_memcpy(data + appSize, &header, sizeof header); + SDL_memcpy(data + appSize + sizeof header, zip, header.cartSize); + + *size = finalSize; + } + } + + SDL_free(zip); + } + } + + SDL_free(cart); + } + + SDL_free(app); + } -// return NULL; -// } + return data; +} -// #if defined(__WINDOWS__) +#if defined(__WINDOWS__) -// static const char* getFileFolder(const char* path) -// { -// static char folder[FILENAME_MAX]; +static const char* getFileFolder(const char* path) +{ + static char folder[FILENAME_MAX]; -// const char* pos = strrchr(path, '\\'); + const char* pos = strrchr(path, '\\'); -// if(!pos) -// pos = strrchr(path, '/'); + if(!pos) + pos = strrchr(path, '/'); -// if(pos) -// { -// s32 size = pos - path; -// memcpy(folder, path, size); -// folder[size] = 0; + if(pos) + { + s32 size = pos - path; + memcpy(folder, path, size); + folder[size] = 0; -// return folder; -// } + return folder; + } -// return NULL; -// } + return NULL; +} -// static bool exportToFolder(Console* console, const char* folder, const char* file) -// { -// const char* workFolder = getFileFolder(console->appPath); +static bool exportToFolder(Console* console, const char* folder, const char* file) +{ + const char* workFolder = getFileFolder(console->appPath); -// if(workFolder) -// { -// char src[FILENAME_MAX]; -// strcpy(src, workFolder); -// strcat(src, file); + if(workFolder) + { + char src[FILENAME_MAX]; + strcpy(src, workFolder); + strcat(src, file); -// char dst[FILENAME_MAX]; -// strcpy(dst, folder); -// strcat(dst, file); + char dst[FILENAME_MAX]; + strcpy(dst, folder); + strcat(dst, file); -// return fsCopyFile(src, dst); -// } + return fsCopyFile(src, dst); + } -// return NULL; -// } + return false; +} -// static void onConsoleExportNativeCommand(Console* console, const char* cartName) -// { -// const char* folder = folder_dialog(console); -// bool done = false; +static void onConsoleExportNativeCommand(Console* console, const char* cartName) +{ + const char* folder = folder_dialog(console); + bool done = false; -// if(folder) -// { -// s32 size = 0; + if(folder) + { + s32 size = 0; -// void* data = embedCart(console, &size); + void* data = embedCart(console, &size); -// if(data) -// { -// char path[FILENAME_MAX]; -// strcpy(path, folder); -// strcat(path, "\\game.exe"); + if(data) + { + char path[FILENAME_MAX]; + strcpy(path, folder); + strcat(path, "\\game.exe"); -// done = fsWriteFile(path, data, size); + done = fsWriteFile(path, data, size); -// SDL_free(data); -// } -// else -// { -// printBack(console, "\ngame exporting error :("); -// } -// } + SDL_free(data); + } + else + { + printBack(console, "\ngame exporting error :("); + } + } -// if(done && exportToFolder(console, folder, "\\tic80.dll") && -// exportToFolder(console, folder, "\\SDL2.dll")) -// printBack(console, "\ngame exported :)"); -// else printBack(console, "\ngame not exported :|"); + if(done && exportToFolder(console, folder, "\\tic80.dll") && + exportToFolder(console, folder, "\\SDL2.dll")) + printBack(console, "\ngame exported :)"); + else printBack(console, "\ngame not exported :|"); -// commandDone(console); -// } + commandDone(console); +} -// #else +#else -// static void onConsoleExportNativeCommand(Console* console, const char* cartName) -// { -// s32 size = 0; -// void* data = embedCart(console, &size); +static void onConsoleExportNativeCommand(Console* console, const char* cartName) +{ + s32 size = 0; + void* data = embedCart(console, &size); -// if(data) -// { -// fsGetFileData(onFileDownloaded, cartName, data, size, DEFAULT_CHMOD, console); -// } -// else -// { -// onFileDownloaded(FS_FILE_NOT_DOWNLOADED, console); -// } -// } + if(data) + { + fsGetFileData(onFileDownloaded, cartName, data, size, DEFAULT_CHMOD, console); + } + else + { + onFileDownloaded(FS_FILE_NOT_DOWNLOADED, console); + } +} -// #endif +#endif -// #endif +#endif static const char* getExportName(Console* console, bool html) { static char name[FILENAME_MAX]; - if(strlen(console->romName)) - { - memset(name, 0, sizeof name); - memcpy(name, console->romName, strstr(console->romName, ".tic") - console->romName); - } - else - { - strcpy(name, "game"); - } - + strcpy(name, strlen(console->romName) ? console->romName : "game"); if(html) strcat(name, ".html"); @@ -1919,13 +1955,13 @@ static void onConsoleExportCommand(Console* console, const char* param) { if(strcmp(param, "native") == 0) { -// #ifdef CAN_EXPORT -// onConsoleExportNativeCommand(console, getExportName(console, false)); -// #else +#if defined(CAN_EXPORT) + onConsoleExportNativeCommand(console, getExportName(console, false)); +#else printBack(console, "\nnative export isn't supported on this platform\n"); commandDone(console); -// #endif +#endif } else if(strcmp(param, "sprites") == 0) { @@ -2272,7 +2308,7 @@ static const struct {"dir", "ls", "show list of files", onConsoleDirCommand}, {"cd", NULL, "change directory", onConsoleChangeDirectory}, {"mkdir", NULL, "make directory", onConsoleMakeDirectory}, -#ifdef CAN_EXPORT +#if defined(CAN_EXPORT) {"folder", NULL, "open working folder in OS", onConsoleFolderCommand}, #endif {"add", NULL, "add file", onConsoleAddCommand}, @@ -2937,7 +2973,6 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config, .embed = { .yes = false, - .menu = false, .file = console->embed.file, }, .inputPosition = 0, @@ -3074,6 +3109,53 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config, EM_ASM_({Module._free($0);}, cartPtr); } } +#endif + +#if defined(CAN_EXPORT) + + if(!console->embed.yes) + { + s32 appSize = 0; + u8* app = fsReadFile(console->appPath, &appSize); + + if(app) + { + s32 size = appSize; + const u8* ptr = app; + + while(true) + { + const EmbedHeader* header = (const EmbedHeader*)memmem(ptr, size, TicCartSig, SIG_SIZE); + + if(header) + { + if(appSize == header->appSize + sizeof(EmbedHeader) + header->cartSize) + { + u8* data = NULL; + s32 dataSize = unzip(&data, app + header->appSize + sizeof(EmbedHeader), header->cartSize); + + if(data) + { + loadCart(tic, console->embed.file, data, dataSize, true); + console->embed.yes = true; + + SDL_free(data); + } + + break; + } + else + { + ptr = (const u8*)header + SIG_SIZE; + size = appSize - (ptr - app); + } + } + else break; + } + + SDL_free(app); + } + } #endif diff --git a/src/console.h b/src/console.h index 964d367..ba159e9 100644 --- a/src/console.h +++ b/src/console.h @@ -72,7 +72,6 @@ struct Console struct { bool yes; - bool menu; tic_cartridge* file; } embed;