diff --git a/Makefile b/Makefile index 4477ca3..ad7897a 100644 --- a/Makefile +++ b/Makefile @@ -313,7 +313,7 @@ $(STUDIO_DLL): $(DEMO_ASSETS) $(TIC80_DLL) $(TIC_O) bin/html.o $(CC) $(TIC_O) bin/html.o $(TIC80_A) $(OPT) -shared $(INCLUDES) -L$(PRE_BUILT)/mingw -llua -lz -lgif -Wl,--out-implib,$(STUDIO_A) -o $@ emscripten: - $(EMS_CC) $(SOURCES) $(TIC80_SRC) $(OPT) $(INCLUDES) $(EMS_OPT) $(EMS_LINKER_FLAGS) -o build/html/tic.js + $(EMS_CC) $(SOURCES) src/main.c $(TIC80_SRC) $(OPT) $(INCLUDES) $(EMS_OPT) $(EMS_LINKER_FLAGS) -o build/html/tic.js wasm: $(EMS_CC) $(SOURCES) $(TIC80_SRC) $(OPT) $(INCLUDES) $(EMS_OPT) -s WASM=1 $(EMS_LINKER_FLAGS) -o build/html/tic.js diff --git a/src/code.c b/src/code.c index c62f273..ed07e5d 100644 --- a/src/code.c +++ b/src/code.c @@ -764,7 +764,7 @@ static void initOutlineMode(Code* code) char filter[STUDIO_TEXT_BUFFER_WIDTH] = {0}; strncpy(filter, code->popup.text, sizeof(filter)); - _strlwr(filter); + strlwr(filter); const tic_script_config* config = tic->api.get_script_config(tic); @@ -787,7 +787,7 @@ static void initOutlineMode(Code* code) { strncpy(buffer, out->name, sizeof(buffer)); - _strlwr(buffer); + strlwr(buffer); if(strstr(buffer, filter)) out++; else out->pos = NULL; diff --git a/src/console.c b/src/console.c index 2bb49e2..4f9c66e 100644 --- a/src/console.c +++ b/src/console.c @@ -30,6 +30,7 @@ #include #include #include +#include #define CONSOLE_CURSOR_COLOR ((tic_color_red)) #define CONSOLE_BACK_TEXT_COLOR ((tic_color_dark_gray)) diff --git a/src/fs.c b/src/fs.c index a7ae6b7..ac3e4d9 100644 --- a/src/fs.c +++ b/src/fs.c @@ -553,10 +553,12 @@ void* fsReadFile(const char* path, s32* size) static void makeDir(const char* name) { - tic_mkdir(UTF8ToString(name)); - #if defined(__EMSCRIPTEN__) + mkdir(name, 0700); + EM_ASM(FS.syncfs(function(){})); +#else + tic_mkdir(UTF8ToString(name)); #endif } @@ -779,7 +781,7 @@ void fsOpenWorkingFolder(FileSystem* fs) openSystemPath(path); } -void createFileSystem(const char* path, void(*callback)(FileSystem*)) +FileSystem* createFileSystem(const char* path) { FileSystem* fs = (FileSystem*)malloc(sizeof(FileSystem)); memset(fs, 0, sizeof(FileSystem)); @@ -787,54 +789,6 @@ void createFileSystem(const char* path, void(*callback)(FileSystem*)) fs->net = _createNet(); strcpy(fs->dir, path); - callback(fs); -// else -// { - -// #if defined(__EMSCRIPTEN__) - -// strcpy(fs->dir, "/" TIC_PACKAGE "/" TIC_NAME "/"); - -// #elif defined(__ANDROID__) - -// strcpy(fs->dir, SDL_AndroidGetExternalStoragePath()); -// const char AppFolder[] = "/" TIC_NAME "/"; -// strcat(fs->dir, AppFolder); -// mkdir(fs->dir, 0700); - -// #else - -// char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME); -// strcpy(fs->dir, path); -// free(path); - -// #endif - -// #if defined(__EMSCRIPTEN__) -// EM_ASM_ -// ( -// { -// var dir = ""; -// Module.Pointer_stringify($0).split("/").forEach(function(val) -// { -// if(val.length) -// { -// dir += "/" + val; -// FS.mkdir(dir); -// } -// }); - -// FS.mount(IDBFS, {}, dir); -// FS.syncfs(true, function(error) -// { -// if(error) console.log(error); -// else Runtime.dynCall('vi', $1, [$2]); -// }); -// }, fs->dir, callback, fs -// ); -// #else -// callback(fs); -// #endif - // } + return fs; } \ No newline at end of file diff --git a/src/fs.h b/src/fs.h index e1af243..a6d2a66 100644 --- a/src/fs.h +++ b/src/fs.h @@ -47,7 +47,7 @@ typedef void(*OpenCallback)(const char* name, const void* buffer, size_t size, v typedef struct FileSystem FileSystem; -void createFileSystem(const char* path, void(*callback)(FileSystem*)); +FileSystem* createFileSystem(const char* path); void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data); void fsAddFile(FileSystem* fs, AddCallback callback, void* data); diff --git a/src/main.c b/src/main.c index 26b0608..4ad13f1 100644 --- a/src/main.c +++ b/src/main.c @@ -835,17 +835,13 @@ static void tick() { pollEvent(); - // if(!platform.fs) return; - -// if(platform.quit) -// { -// #if defined __EMSCRIPTEN__ -// platform.studio->tic->api.clear(platform.studio->tic, TIC_COLOR_BG); -// blitTexture(); -// emscripten_cancel_main_loop(); -// #endif -// return; -// } + if(platform.studio->quit) + { +#if defined __EMSCRIPTEN__ + emscripten_cancel_main_loop(); +#endif + return; + } SDL_RenderClear(platform.renderer); @@ -858,7 +854,6 @@ static void tick() blitSound(); } -// should work async with callback static const char* getAppFolder() { static char appFolder[FILENAME_MAX]; @@ -878,32 +873,8 @@ static const char* getAppFolder() char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME); strcpy(appFolder, path); - free(path); + SDL_free(path); -#endif - -#if defined(__EMSCRIPTEN__) - EM_ASM_ - ( - { - var dir = ""; - Module.Pointer_stringify($0).split("/").forEach(function(val) - { - if(val.length) - { - dir += "/" + val; - FS.mkdir(dir); - } - }); - - FS.mount(IDBFS, {}, dir); - FS.syncfs(true, function(error) - { - if(error) console.log(error); - else Runtime.dynCall('vi', $1, [$2]); - }); - }, appFolder, callback, fs - ); #endif return appFolder; @@ -1008,7 +979,82 @@ static System sysHandlers = .openSystemPath = _openSystemPath, }; -s32 main(s32 argc, char **argv) +#if defined(__EMSCRIPTEN__) + +static void emstick() +{ + static double nextTick = -1.0; + + platform.missedFrame = false; + + if(nextTick < 0.0) + nextTick = emscripten_get_now(); + + nextTick += 1000.0/TIC_FRAMERATE; + tick(); + double delay = nextTick - emscripten_get_now(); + + if(delay < 0.0) + { + nextTick -= delay; + platform.missedFrame = true; + } + else + emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, delay); +} + +#endif + +// else +// { + +// #if defined(__EMSCRIPTEN__) + +// strcpy(fs->dir, "/" TIC_PACKAGE "/" TIC_NAME "/"); + +// #elif defined(__ANDROID__) + +// strcpy(fs->dir, SDL_AndroidGetExternalStoragePath()); +// const char AppFolder[] = "/" TIC_NAME "/"; +// strcat(fs->dir, AppFolder); +// mkdir(fs->dir, 0700); + +// #else + +// char* path = SDL_GetPrefPath(TIC_PACKAGE, TIC_NAME); +// strcpy(fs->dir, path); +// free(path); + +// #endif + +// #if defined(__EMSCRIPTEN__) +// EM_ASM_ +// ( +// { +// var dir = ""; +// Module.Pointer_stringify($0).split("/").forEach(function(val) +// { +// if(val.length) +// { +// dir += "/" + val; +// FS.mkdir(dir); +// } +// }); + +// FS.mount(IDBFS, {}, dir); +// FS.syncfs(true, function(error) +// { +// if(error) console.log(error); +// else Runtime.dynCall('vi', $1, [$2]); +// }); +// }, fs->dir, callback, fs +// ); +// #else +// callback(fs); +// #endif + // } + +static s32 start(s32 argc, char **argv, const char* folder) { SDL_SetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, "1"); SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); @@ -1026,7 +1072,7 @@ s32 main(s32 argc, char **argv) #endif ); - platform.studio = studioInit(argc, argv, platform.audio.spec.freq, getAppFolder(), &sysHandlers); + platform.studio = studioInit(argc, argv, platform.audio.spec.freq, folder, &sysHandlers); // set the window icon before renderer is created (issues on Linux) setWindowIcon(); @@ -1034,11 +1080,8 @@ s32 main(s32 argc, char **argv) platform.renderer = SDL_CreateRenderer(platform.window, -1, #if defined(__CHIP__) SDL_RENDERER_SOFTWARE -#elif defined(__EMSCRIPTEN__) - SDL_RENDERER_ACCELERATED #else - // TODO: uncomment this later, also init FS before read config - SDL_RENDERER_ACCELERATED// | (getConfig()->useVsync ? SDL_RENDERER_PRESENTVSYNC : 0) + SDL_RENDERER_ACCELERATED | (getConfig()->useVsync ? SDL_RENDERER_PRESENTVSYNC : 0) #endif ); @@ -1048,8 +1091,8 @@ s32 main(s32 argc, char **argv) #if defined(__EMSCRIPTEN__) - // call this after FS is initialized - emscripten_set_main_loop(getConfig()->useVsync ? tick : emstick, TIC_FRAMERATE, 1); + emscripten_set_main_loop(getConfig()->useVsync ? tick : emstick, 0, 1); + #else { u64 nextTick = SDL_GetPerformanceCounter(); @@ -1096,3 +1139,72 @@ s32 main(s32 argc, char **argv) return 0; } + +#if defined(__EMSCRIPTEN__) + +#define DEFAULT_CART "cart.tic" + +static struct +{ + s32 argc; + char **argv; + const char* folder; +} startVars; + +static void onEmscriptenWget(const char* file) +{ + startVars.argv[1] = DEFAULT_CART; + start(startVars.argc, startVars.argv, startVars.folder); +} + +static void onEmscriptenWgetError(const char* error) {} + +static void emsStart(s32 argc, char **argv, const char* folder) +{ + if(argc == 2) + { + startVars.argc = argc; + startVars.argv = argv; + startVars.folder = folder; + + emscripten_async_wget(argv[1], DEFAULT_CART, onEmscriptenWget, onEmscriptenWgetError); + } + else start(argc, argv, folder); +} + +#endif + +s32 main(s32 argc, char **argv) +{ + const char* folder = getAppFolder(); + +#if defined(__EMSCRIPTEN__) + + EM_ASM_ + ( + { + var dir = ""; + Module.Pointer_stringify($0).split("/").forEach(function(val) + { + if(val.length) + { + dir += "/" + val; + FS.mkdir(dir); + } + }); + + FS.mount(IDBFS, {}, dir); + FS.syncfs(true, function() + { + Runtime.dynCall('viii', $1, [$2, $3, $0]); + }); + + }, folder, emsStart, argc, argv + ); + +#else + + return start(argc, argv, folder); + +#endif +} diff --git a/src/studio.c b/src/studio.c index 1010a71..b84e2dd 100644 --- a/src/studio.c +++ b/src/studio.c @@ -1717,9 +1717,70 @@ static void initKeymap() } } -static void onFSInitialized(FileSystem* fs) +// #if defined(__EMSCRIPTEN__) + +// #define DEFAULT_CART "cart.tic" + +// static void onEmscriptenWget(const char* file) +// { +// studioImpl.argv[1] = DEFAULT_CART; +// createFileSystem(NULL, onFSInitialized); +// } + +// static void onEmscriptenWgetError(const char* error) {} + +// static void emstick() +// { +// static double nextTick = -1.0; + +// studioImpl.missedFrame = false; + +// if(nextTick < 0.0) +// nextTick = emscripten_get_now(); + +// nextTick += 1000.0/TIC_FRAMERATE; +// tick(); +// double delay = nextTick - emscripten_get_now(); + +// if(delay < 0.0) +// { +// nextTick -= delay; +// studioImpl.missedFrame = true; +// } +// else +// emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, delay); +// } + +// #endif + +// #if defined(__EMSCRIPTEN__) + +// if(studioImpl.argc == 2) +// { +// emscripten_async_wget(studioImpl.argv[1], DEFAULT_CART, onEmscriptenWget, onEmscriptenWgetError); +// } +// else createFileSystem(NULL, onFSInitialized); + +// // emscripten_set_main_loop(emstick, TIC_FRAMERATE, 1); + +// #else + +// FileSystem* fs = createFileSystem(argc > 1 && fsExists(argv[1]) ? fsBasename(argv[1]) : folder); +// onFSInitialized(fs); + +// #endif + + +Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* folder, System* system) { - studioImpl.fs = fs; + setbuf(stdout, NULL); + studioImpl.argc = argc; + studioImpl.argv = argv; + studioImpl.samplerate = samplerate; + + studioImpl.system = system; + + studioImpl.fs = createFileSystem(argc > 1 && fsExists(argv[1]) ? fsBasename(argv[1]) : folder); studioImpl.tic80local = (tic80_local*)tic80_create(studioImpl.samplerate); studioImpl.studio.tic = studioImpl.tic80local->memory; @@ -1744,7 +1805,7 @@ static void onFSInitialized(FileSystem* fs) studioImpl.surf = calloc(1, sizeof(Surf)); } - fsMakeDir(fs, TIC_LOCAL); + fsMakeDir(studioImpl.fs, TIC_LOCAL); initConfig(studioImpl.config, studioImpl.studio.tic, studioImpl.fs); initKeymap(); @@ -1766,68 +1827,6 @@ static void onFSInitialized(FileSystem* fs) { goFullscreen(); } -} - -#if defined(__EMSCRIPTEN__) - -#define DEFAULT_CART "cart.tic" - -static void onEmscriptenWget(const char* file) -{ - studioImpl.argv[1] = DEFAULT_CART; - createFileSystem(NULL, onFSInitialized); -} - -static void onEmscriptenWgetError(const char* error) {} - -static void emstick() -{ - static double nextTick = -1.0; - - studioImpl.missedFrame = false; - - if(nextTick < 0.0) - nextTick = emscripten_get_now(); - - nextTick += 1000.0/TIC_FRAMERATE; - tick(); - double delay = nextTick - emscripten_get_now(); - - if(delay < 0.0) - { - nextTick -= delay; - studioImpl.missedFrame = true; - } - else - emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, delay); -} - -#endif - -Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* folder, System* system) -{ - setbuf(stdout, NULL); - studioImpl.argc = argc; - studioImpl.argv = argv; - studioImpl.samplerate = samplerate; - - studioImpl.system = system; - -#if defined(__EMSCRIPTEN__) - - if(studioImpl.argc == 2) - { - emscripten_async_wget(studioImpl.argv[1], DEFAULT_CART, onEmscriptenWget, onEmscriptenWgetError); - } - else createFileSystem(NULL, onFSInitialized); - - // emscripten_set_main_loop(emstick, TIC_FRAMERATE, 1); - -#else - - createFileSystem(argc > 1 && fsExists(argv[1]) ? fsBasename(argv[1]) : folder, onFSInitialized); - -#endif return &studioImpl.studio; }