#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);
// return NULL; if(zip)
// } {
compress2(zip, &zipSize, cart, cartSize, Z_BEST_COMPRESSION);
// #if defined(__WINDOWS__) {
EmbedHeader header =
{
.appSize = appSize,
.cartSize = zipSize,
};
// static const char* getFileFolder(const char* path) SDL_memcpy(header.sig, TicCartSig, SIG_SIZE);
// {
// static char folder[FILENAME_MAX];
// const char* pos = strrchr(path, '\\'); s32 finalSize = appSize + sizeof header + header.cartSize;
data = SDL_malloc(finalSize);
// if(!pos) if(data)
// pos = strrchr(path, '/'); {
SDL_memcpy(data, app, appSize);
SDL_memcpy(data + appSize, &header, sizeof header);
SDL_memcpy(data + appSize + sizeof header, zip, header.cartSize);
// if(pos) *size = finalSize;
// { }
// s32 size = pos - path; }
// memcpy(folder, path, size);
// folder[size] = 0;
// return folder; SDL_free(zip);
// } }
}
// return NULL; SDL_free(cart);
// } }
// static bool exportToFolder(Console* console, const char* folder, const char* file) SDL_free(app);
// { }
// const char* workFolder = getFileFolder(console->appPath);
// if(workFolder) return data;
// { }
// char src[FILENAME_MAX];
// strcpy(src, workFolder);
// strcat(src, file);
// char dst[FILENAME_MAX]; #if defined(__WINDOWS__)
// strcpy(dst, folder);
// strcat(dst, file);
// return fsCopyFile(src, dst); static const char* getFileFolder(const char* path)
// } {
static char folder[FILENAME_MAX];
// return NULL; const char* pos = strrchr(path, '\\');
// }
// static void onConsoleExportNativeCommand(Console* console, const char* cartName) if(!pos)
// { pos = strrchr(path, '/');
// const char* folder = folder_dialog(console);
// bool done = false;
// if(folder) if(pos)
// { {
// s32 size = 0; s32 size = pos - path;
memcpy(folder, path, size);
folder[size] = 0;
// void* data = embedCart(console, &size); return folder;
}
// if(data) return NULL;
// { }
// char path[FILENAME_MAX];
// strcpy(path, folder);
// strcat(path, "\\game.exe");
// done = fsWriteFile(path, data, size); static bool exportToFolder(Console* console, const char* folder, const char* file)
{
const char* workFolder = getFileFolder(console->appPath);
// SDL_free(data); if(workFolder)
// } {
// else char src[FILENAME_MAX];
// { strcpy(src, workFolder);
// printBack(console, "\ngame exporting error :("); strcat(src, file);
// }
// }
// if(done && exportToFolder(console, folder, "\\tic80.dll") && char dst[FILENAME_MAX];
// exportToFolder(console, folder, "\\SDL2.dll")) strcpy(dst, folder);
// printBack(console, "\ngame exported :)"); strcat(dst, file);
// else printBack(console, "\ngame not exported :|");
// commandDone(console); return fsCopyFile(src, dst);
// } }
// #else return false;
}
// static void onConsoleExportNativeCommand(Console* console, const char* cartName) static void onConsoleExportNativeCommand(Console* console, const char* cartName)
// { {
// s32 size = 0; const char* folder = folder_dialog(console);
// void* data = embedCart(console, &size); bool done = false;
// if(data) if(folder)
// { {
// fsGetFileData(onFileDownloaded, cartName, data, size, DEFAULT_CHMOD, console); s32 size = 0;
// }
// else
// {
// onFileDownloaded(FS_FILE_NOT_DOWNLOADED, console);
// }
// }
// #endif void* data = embedCart(console, &size);
if(data)
{
char path[FILENAME_MAX];
strcpy(path, folder);
strcat(path, "\\game.exe");
done = fsWriteFile(path, data, size);
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 :|");
commandDone(console);
}
#else
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);
}
}
#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;