#341 native export has been restored and now it supports compressing

This commit is contained in:
BADIM-PC\Vadim 2017-12-22 16:13:34 +03:00
parent ef502b2496
commit de7557e4f9
2 changed files with 192 additions and 111 deletions

View File

@ -47,6 +47,16 @@ typedef enum
JavaScript, JavaScript,
} ScriptLang; } 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__) #if defined(__WINDOWS__) || defined(__LINUX__) || defined(__MACOSX__)
#define CAN_EXPORT 1 #define CAN_EXPORT 1
#endif #endif
@ -1163,7 +1173,7 @@ static void onConsoleDirCommand(Console* console, const char* param)
commandDone(console); commandDone(console);
} }
#ifdef CAN_EXPORT #if defined(CAN_EXPORT)
static void onConsoleFolderCommand(Console* console, const char* param) static void onConsoleFolderCommand(Console* console, const char* param)
{ {
@ -1757,146 +1767,172 @@ static void onConsoleExportHtmlCommand(Console* console, const char* name)
SDL_free(EmbedTicJs); SDL_free(EmbedTicJs);
} }
// #ifdef CAN_EXPORT #if defined(CAN_EXPORT)
// static void* embedCart(Console* console, s32* size) static void* embedCart(Console* console, s32* size)
// { {
// tic_mem* tic = console->tic; 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) if(app)
// { {
// void* start = memmem(data, *size, embed.prefix, sizeof(embed.prefix)); void* cart = SDL_malloc(sizeof(tic_cartridge));
// if(start) if(cart)
// { {
// embed.yes = true; s32 cartSize = tic->api.save(&tic->cart, cart);
// SDL_memcpy(&embed.file, &tic->cart, sizeof(tic_cartridge));
// SDL_memcpy(start, &embed, sizeof(embed));
// embed.yes = false;
// }
// 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 const char* getFileFolder(const char* path)
// { {
// static char folder[FILENAME_MAX]; static char folder[FILENAME_MAX];
// const char* pos = strrchr(path, '\\'); const char* pos = strrchr(path, '\\');
// if(!pos) if(!pos)
// pos = strrchr(path, '/'); pos = strrchr(path, '/');
// if(pos) if(pos)
// { {
// s32 size = pos - path; s32 size = pos - path;
// memcpy(folder, path, size); memcpy(folder, path, size);
// folder[size] = 0; folder[size] = 0;
// return folder; return folder;
// } }
// return NULL; return NULL;
// } }
// static bool exportToFolder(Console* console, const char* folder, const char* file) static bool exportToFolder(Console* console, const char* folder, const char* file)
// { {
// const char* workFolder = getFileFolder(console->appPath); const char* workFolder = getFileFolder(console->appPath);
// if(workFolder) if(workFolder)
// { {
// char src[FILENAME_MAX]; char src[FILENAME_MAX];
// strcpy(src, workFolder); strcpy(src, workFolder);
// strcat(src, file); strcat(src, file);
// char dst[FILENAME_MAX]; char dst[FILENAME_MAX];
// strcpy(dst, folder); strcpy(dst, folder);
// strcat(dst, file); strcat(dst, file);
// return fsCopyFile(src, dst); return fsCopyFile(src, dst);
// } }
// return NULL; return false;
// } }
// static void onConsoleExportNativeCommand(Console* console, const char* cartName) static void onConsoleExportNativeCommand(Console* console, const char* cartName)
// { {
// const char* folder = folder_dialog(console); const char* folder = folder_dialog(console);
// bool done = false; bool done = false;
// if(folder) if(folder)
// { {
// s32 size = 0; s32 size = 0;
// void* data = embedCart(console, &size); void* data = embedCart(console, &size);
// if(data) if(data)
// { {
// char path[FILENAME_MAX]; char path[FILENAME_MAX];
// strcpy(path, folder); strcpy(path, folder);
// strcat(path, "\\game.exe"); strcat(path, "\\game.exe");
// done = fsWriteFile(path, data, size); done = fsWriteFile(path, data, size);
// SDL_free(data); SDL_free(data);
// } }
// else else
// { {
// printBack(console, "\ngame exporting error :("); printBack(console, "\ngame exporting error :(");
// } }
// } }
// if(done && exportToFolder(console, folder, "\\tic80.dll") && if(done && exportToFolder(console, folder, "\\tic80.dll") &&
// exportToFolder(console, folder, "\\SDL2.dll")) exportToFolder(console, folder, "\\SDL2.dll"))
// printBack(console, "\ngame exported :)"); printBack(console, "\ngame exported :)");
// else printBack(console, "\ngame not exported :|"); else printBack(console, "\ngame not exported :|");
// commandDone(console); commandDone(console);
// } }
// #else #else
// static void onConsoleExportNativeCommand(Console* console, const char* cartName) static void onConsoleExportNativeCommand(Console* console, const char* cartName)
// { {
// s32 size = 0; s32 size = 0;
// void* data = embedCart(console, &size); void* data = embedCart(console, &size);
// if(data) if(data)
// { {
// fsGetFileData(onFileDownloaded, cartName, data, size, DEFAULT_CHMOD, console); fsGetFileData(onFileDownloaded, cartName, data, size, DEFAULT_CHMOD, console);
// } }
// else else
// { {
// onFileDownloaded(FS_FILE_NOT_DOWNLOADED, console); onFileDownloaded(FS_FILE_NOT_DOWNLOADED, console);
// } }
// } }
// #endif #endif
// #endif #endif
static const char* getExportName(Console* console, bool html) static const char* getExportName(Console* console, bool html)
{ {
static char name[FILENAME_MAX]; static char name[FILENAME_MAX];
if(strlen(console->romName)) strcpy(name, strlen(console->romName) ? console->romName : "game");
{
memset(name, 0, sizeof name);
memcpy(name, console->romName, strstr(console->romName, ".tic") - console->romName);
}
else
{
strcpy(name, "game");
}
if(html) if(html)
strcat(name, ".html"); strcat(name, ".html");
@ -1919,13 +1955,13 @@ static void onConsoleExportCommand(Console* console, const char* param)
{ {
if(strcmp(param, "native") == 0) if(strcmp(param, "native") == 0)
{ {
// #ifdef CAN_EXPORT #if defined(CAN_EXPORT)
// onConsoleExportNativeCommand(console, getExportName(console, false)); onConsoleExportNativeCommand(console, getExportName(console, false));
// #else #else
printBack(console, "\nnative export isn't supported on this platform\n"); printBack(console, "\nnative export isn't supported on this platform\n");
commandDone(console); commandDone(console);
// #endif #endif
} }
else if(strcmp(param, "sprites") == 0) else if(strcmp(param, "sprites") == 0)
{ {
@ -2272,7 +2308,7 @@ static const struct
{"dir", "ls", "show list of files", onConsoleDirCommand}, {"dir", "ls", "show list of files", onConsoleDirCommand},
{"cd", NULL, "change directory", onConsoleChangeDirectory}, {"cd", NULL, "change directory", onConsoleChangeDirectory},
{"mkdir", NULL, "make directory", onConsoleMakeDirectory}, {"mkdir", NULL, "make directory", onConsoleMakeDirectory},
#ifdef CAN_EXPORT #if defined(CAN_EXPORT)
{"folder", NULL, "open working folder in OS", onConsoleFolderCommand}, {"folder", NULL, "open working folder in OS", onConsoleFolderCommand},
#endif #endif
{"add", NULL, "add file", onConsoleAddCommand}, {"add", NULL, "add file", onConsoleAddCommand},
@ -2937,7 +2973,6 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config,
.embed = .embed =
{ {
.yes = false, .yes = false,
.menu = false,
.file = console->embed.file, .file = console->embed.file,
}, },
.inputPosition = 0, .inputPosition = 0,
@ -3074,6 +3109,53 @@ void initConsole(Console* console, tic_mem* tic, FileSystem* fs, Config* config,
EM_ASM_({Module._free($0);}, cartPtr); 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 #endif

View File

@ -72,7 +72,6 @@ struct Console
struct struct
{ {
bool yes; bool yes;
bool menu;
tic_cartridge* file; tic_cartridge* file;
} embed; } embed;