diff --git a/CMakeLists.txt b/CMakeLists.txt index 8991b4d..d477708 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") set(USE_FLAGS "-pthread -s USE_SDL=2 -s USE_PTHREADS=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 ${USE_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 ${USE_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${USE_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s PTHREAD_POOL_SIZE=2 --preload-file ${CMAKE_SOURCE_DIR}/sqlux.ini@./sqlux.ini --preload-file ${CMAKE_SOURCE_DIR}/roms/MIN198.rom@./roms/MIN198.rom --preload-file ${CMAKE_SOURCE_DIR}/roms/TK232.rom@./roms/TK232.rom" ) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${USE_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s PTHREAD_POOL_SIZE=2 -lidbfs.js --preload-file ${CMAKE_SOURCE_DIR}/sqlux_wasm.ini@./sqlux.ini --preload-file ${CMAKE_SOURCE_DIR}/roms/MIN198.rom@./roms/MIN198.rom --preload-file ${CMAKE_SOURCE_DIR}/roms/TK232.rom@./roms/TK232.rom --preload-file ${CMAKE_SOURCE_DIR}/default.img@./default_win1.win" ) configure_file(sqlux_wrapper_sample.html index.html COPYONLY) else() find_package(SDL2 REQUIRED) @@ -134,6 +134,9 @@ add_dependencies(sqlux SubmarineGitVersion) if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") target_sources(sqlux PRIVATE sQLuxLogo.rc) endif () +if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") + target_sources(sqlux PRIVATE src/wasm_support.c) +endif() if (SUPPORT_SHADERS) message("Enabling shader support") diff --git a/default.img b/default.img new file mode 100644 index 0000000..96fa27b Binary files /dev/null and b/default.img differ diff --git a/include/wasm_support.h b/include/wasm_support.h new file mode 100644 index 0000000..4412e00 --- /dev/null +++ b/include/wasm_support.h @@ -0,0 +1,7 @@ +#ifndef _WASMSUPPORT_H +#define _WASMSUPPORT_H + +int wasm_does_boot_file_exist(void); +void wasm_init_storage(void); + +#endif \ No newline at end of file diff --git a/sqlux_wasm.ini b/sqlux_wasm.ini new file mode 100644 index 0000000..6aede51 --- /dev/null +++ b/sqlux_wasm.ini @@ -0,0 +1,22 @@ +# Example configuration + +SYSROM = MIN198.rom +ROMPORT = TK232.rom +RAMTOP = 4096 +PRINT = lpr +CPU_HOG = 0 +FAST_STARTUP = 0 +#BOOT_DEVICE = WIN1 +BOOT_DEVICE = FLP1 +DEVICE = WIN1,/local/win1.win,qdos-fs +DEVICE = FLP1,/local/win1.win,qdos-fs +DEVICE = RAM1,/tmp/.ram1-%x,clean,qdos-like +#DEVICE = RAM1,/tmp/.ram1-%x,clean,qdos-like +#DEVICE = RAM2,/tmp/.ram2-%x,clean,qdos-like +#DEVICE = RAM8,/tmp/.ram8-%x,clean,qdos-like +WIN_SIZE = max +FILTER = 1 +FIXASPECT = 1 +KBD = GB +SOUND = 1 +SPEED = 0.0 diff --git a/sqlux_wrapper_sample.html b/sqlux_wrapper_sample.html index 92daec5..22d6381 100644 --- a/sqlux_wrapper_sample.html +++ b/sqlux_wrapper_sample.html @@ -1,28 +1,57 @@ + - - - - - - - - - - + + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/src/SDL2main.cpp b/src/SDL2main.cpp index 938f638..c633331 100644 --- a/src/SDL2main.cpp +++ b/src/SDL2main.cpp @@ -16,6 +16,9 @@ extern "C" { #if __EMSCRIPTEN__ #include +extern "C" { + #include "wasm_support.h" +} #endif static SDL_Thread *emuThread = NULL; @@ -25,19 +28,19 @@ void CleanRAMDev() int i, j; for (i = 0; i < MAXDEV; i++) { - if (qdevs[i].qname && strcmp(qdevs[i].qname, "RAM") == 0) { - for (j = 0; j < 8; j++) { - if ((qdevs[i].mountPoints[j] != NULL) && - qdevs[i].clean[j]) { + if (qdevs[i].qname && strcmp(qdevs[i].qname, "RAM") == 0) { + for (j = 0; j < 8; j++) { + if ((qdevs[i].mountPoints[j] != NULL) && + qdevs[i].clean[j]) { if (V2) { std::cout << "Cleaning: " << qdevs[i].mountPoints[j] << "\n"; } - std::filesystem::remove_all(qdevs[i].mountPoints[j]); - } - } - break; - } - } + std::filesystem::remove_all(qdevs[i].mountPoints[j]); + } + } + break; + } + } } extern "C" void emu_shutdown() @@ -51,8 +54,33 @@ extern "C" void emu_shutdown() CleanRAMDev(); } +extern "C" void emu_loop() { + static int init_done = 0; + int boot_file_ready = 1; + +#if __EMSCRIPTEN__ + if(!init_done) { + boot_file_ready = wasm_does_boot_file_exist(); + } +#endif + if(boot_file_ready && !init_done) { + emulator::deviceParse(); + emulator::init(); + QLSDLScreen(); + initSound(optionInt("SOUND")); + emuThread = SDL_CreateThread(QLRun, "sQLux Emulator", NULL); + init_done = 1; + } + if(init_done) { + QLSDLProcessEvents(); + } +} + extern "C" int main(int argc, char *argv[]) { +#if __EMSCRIPTEN__ + wasm_init_storage(); +#endif // set the homedir for the OS first SetHome(); @@ -78,20 +106,11 @@ extern "C" int main(int argc, char *argv[]) } free(boot_cmd); - emulator::deviceParse(); - - emulator::init(); - - QLSDLScreen(); - - initSound(optionInt("SOUND")); - - emuThread = SDL_CreateThread(QLRun, "sQLux Emulator", NULL); #if __EMSCRIPTEN__ - emscripten_set_main_loop(QLSDLProcessEvents, -1, 1); + emscripten_set_main_loop(emu_loop, -1, 1); #else - QLSDLProcessEvents(); + emu_loop(); #endif emu_shutdown(); diff --git a/src/wasm_support.c b/src/wasm_support.c new file mode 100644 index 0000000..f125613 --- /dev/null +++ b/src/wasm_support.c @@ -0,0 +1,27 @@ +#include "emscripten.h" +#include "wasm_support.h" + +EM_JS(int, wasm_does_boot_file_exist, (), { + if (!FS.analyzePath(localWinFile).exists) { + return 0; + } + return 1; +}); + +EM_JS(void, wasm_init_storage, (), { + var localStoragePath = '/local'; + var defaultWinFile = 'win1.win'; + localWinFile = localStoragePath + '/' + defaultWinFile; + FS.mkdir(localStoragePath); + FS.mount(IDBFS, {}, localStoragePath); + FS.syncfs( + true, function(err) { + if (!FS.analyzePath(localWinFile).exists) { + console.log('Copy default win1 file.'); + var wincontent = + FS.readFile('/default_win1.win'); + FS.writeFile(localWinFile, wincontent); + FS.syncfs(false, function(err){}); + } + }); +});