diff --git a/emscripten.cross b/emscripten.cross index cbc766d3..f43586b0 100644 --- a/emscripten.cross +++ b/emscripten.cross @@ -3,9 +3,17 @@ c = 'emcc' cpp = 'em++' ar = 'emar' strip = 'emstrip' +cmake = 'emcmake' +pkg-config = 'empkg-config' [host_machine] system = 'emscripten' cpu_family = 'wasm64' cpu = 'wasm64' -endian = 'little' \ No newline at end of file +endian = 'little' + +[built-in options] +c_args = ['-pthread'] +cpp_args = ['-pthread'] +c_link_args = ['-pthread'] +cpp_link_args = ['-pthread'] \ No newline at end of file diff --git a/meson.build b/meson.build index d6e9b525..496fc178 100644 --- a/meson.build +++ b/meson.build @@ -70,7 +70,8 @@ sdl3_opts.add_cmake_defines({ 'SDL_STATIC': 'ON', 'SDL_SHARED': 'OFF', 'SDL_TEST': 'OFF', - 'CMAKE_BUILD_TYPE': 'Release' + 'CMAKE_BUILD_TYPE': 'Release', + 'SDL_THREADS': 'ON' }) cc = meson.get_compiler('c') @@ -95,16 +96,20 @@ if host_machine.system() == 'windows' deps += cc.find_library('imm32') deps += cc.find_library('version') deps += cc.find_library('cfgmgr32') - sdl3_opts.add_cmake_defines({'HAVE_ISINF': '1'}) # TODO: A hack to get this to compile on MSYS2; otherwise it doesn't link correctly + sdl3_opts.add_cmake_defines({'HAVE_ISINF': '1'}) # Hack for MSYS2 link += '-static' endif if host_machine.system() == 'emscripten' link += '-sUSE_WEBGPU' + # Use the Emscripten toolchain file when building with cmake subprojects: + sdl3_opts.add_cmake_defines({ + 'CMAKE_TOOLCHAIN_FILE': meson.current_source_dir() / 'Emscripten.cmake', + 'CMAKE_BUILD_TYPE': 'Release' + }) endif sdl3_proj = cmake.subproject('sdl3', options: sdl3_opts) - deps += sdl3_proj.dependency('SDL3-static') tracy_opts = ['fibers=true', 'on_demand=true'] @@ -115,44 +120,47 @@ add_project_arguments('-DTRACY_ENABLE', language:['c','cpp']) deps += dependency('tracy', static:true, default_options:tracy_opts) quickjs_opts += 'default_library=static' - deps += dependency('quickjs', static:true, default_options:quickjs_opts) - -#deps += dependency('qjs-steam', static:false) - -deps += dependency('qjs-layout',static:true) -deps += dependency('qjs-miniz',static:true) - +deps += dependency('qjs-layout', static:true) +deps += dependency('qjs-miniz', static:true) deps += dependency('physfs', static:true) - -#deps += dependency('opencv4') -#deps += cc.find_library('opencv') - deps += dependency('threads') deps += dependency('chipmunk', static:true) deps += dependency('enet', static:true) deps += dependency('soloud', static:true) +deps += dependency('libqrencode', static:true) -#deps += dependency('qjs-chipmunk', static:false) - -deps += dependency('libqrencode', static: true) - +link_args = link sources = [] -src += ['anim.c', 'config.c', 'datastream.c','font.c','HandmadeMath.c','jsffi.c','model.c','render.c','simplex.c','spline.c', 'transform.c','prosperon.c', 'wildmatch.c', 'sprite.c', 'rtree.c', 'qjs_dmon.c', 'qjs_nota.c', 'qjs_enet.c', 'qjs_soloud.c', 'qjs_qr.c', 'qjs_wota.c', 'monocypher.c', 'qjs_blob.c', 'qjs_crypto.c', 'qjs_time.c'] - +src += [ + 'anim.c', 'config.c', 'datastream.c','font.c','HandmadeMath.c','jsffi.c','model.c', + 'render.c','simplex.c','spline.c', 'transform.c','prosperon.c', 'wildmatch.c', + 'sprite.c', 'rtree.c', 'qjs_dmon.c', 'qjs_nota.c', 'qjs_enet.c', 'qjs_soloud.c', + 'qjs_qr.c', 'qjs_wota.c', 'monocypher.c', 'qjs_blob.c', 'qjs_crypto.c', 'qjs_time.c' +] # quirc src -src += ['thirdparty/quirc/quirc.c', 'thirdparty/quirc/decode.c','thirdparty/quirc/identify.c', 'thirdparty/quirc/version_db.c'] +src += [ + 'thirdparty/quirc/quirc.c', 'thirdparty/quirc/decode.c', + 'thirdparty/quirc/identify.c', 'thirdparty/quirc/version_db.c' +] -imsrc = ['GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp','imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp','implot_items.cpp','implot.cpp', 'imgui_impl_sdlrenderer3.cpp', 'imgui_impl_sdl3.cpp', 'imgui_impl_sdlgpu3.cpp'] +imsrc = [ + 'GraphEditor.cpp','ImCurveEdit.cpp','ImGradient.cpp','imgui_draw.cpp', + 'imgui_tables.cpp','imgui_widgets.cpp','imgui.cpp','ImGuizmo.cpp','imnodes.cpp', + 'implot_items.cpp','implot.cpp','imgui_impl_sdlrenderer3.cpp','imgui_impl_sdl3.cpp', + 'imgui_impl_sdlgpu3.cpp' +] srceng = 'source' tp = srceng / 'thirdparty' - -includes = [srceng,tp / 'cgltf',tp / 'imgui',tp / 'par',tp / 'stb',tp,tp / 'pl_mpeg/include', tp / 'quirc'] +includes = [ + srceng, tp / 'cgltf', tp / 'imgui', tp / 'par', tp / 'stb', + tp, tp / 'pl_mpeg/include', tp / 'quirc' +] foreach file : src - full_path = join_paths('source', file) - sources += files(full_path) + full_path = join_paths('source', file) + sources += files(full_path) endforeach if get_option('editor') @@ -173,7 +181,7 @@ foreach folder: zip_folders zip_paths += meson.project_source_root() / folder endforeach -# Now use the hash file as a dependency so that any change in the files causes a rebuild. +# Produce core.zip core = custom_target('core.zip', output : 'core.zip', command : ['sh', '-c', @@ -215,7 +223,7 @@ prosperon = custom_target('prosperon', ) prosperon_dep = declare_dependency( - link_with:prosperon + link_with: prosperon ) copy_tests = custom_target( @@ -244,4 +252,3 @@ tests = [ foreach file : tests test(file, prosperon_raw, args:['tests/' + file + '.js'], depends:copy_tests) endforeach - diff --git a/scripts/core/engine.js b/scripts/core/engine.js index 2569c21f..a1b8c868 100644 --- a/scripts/core/engine.js +++ b/scripts/core/engine.js @@ -397,8 +397,6 @@ Register.check_registers = function check_registers(obj) { } } - - Register.add_cb("appupdate") Register.add_cb("update").doc = "Called once per frame." Register.add_cb("physupdate") @@ -872,7 +870,14 @@ if (prosperon.args.root) root = json.decode(prosperon.args.root) else root = $_ if (overling) actor_prep(overling, {type:'greet', id: prosperon.id}) -if (prosperon.args.program) actor.spawn(prosperon.args.program) + +if (!prosperon.args.program) + os.exit(1) + +if (typeof prosperon.args.program !== 'string') + prosperon.args.program = 'main.js'; + +actor.spawn(prosperon.args.program) function destroyself() { console.log(`Got the message to destroy self.`) diff --git a/scripts/modules/cmd.js b/scripts/modules/cmd.js index b5da893b..f506354c 100644 --- a/scripts/modules/cmd.js +++ b/scripts/modules/cmd.js @@ -204,11 +204,19 @@ Cmdline.register_order( ); function cmd_args(cmds) { - cmds.shift() - if (!Cmdline.orders[cmds[0]]) { - // assume it's a script - cmds.unshift("--program") - cmds.unshift("spawn") + // Remove the leading 'prosperon' + cmds.shift(); + + // If there are no arguments left, assume we want to spawn main.js + if (!cmds[0]) { + // => effectively do: prosperon spawn --program main.js + cmds.unshift("main.js"); + cmds.unshift("--program"); + cmds.unshift("spawn"); + } else if (!Cmdline.orders[cmds[0]]) { + // If the first token isn't a recognized command, treat it as a script + cmds.unshift("--program"); + cmds.unshift("spawn"); } Cmdline.orders[cmds[0]](cmds.slice(1)); diff --git a/scripts/modules/loop.js b/scripts/modules/dull.js similarity index 69% rename from scripts/modules/loop.js rename to scripts/modules/dull.js index 64c77454..3e84a840 100644 --- a/scripts/modules/loop.js +++ b/scripts/modules/dull.js @@ -1,4 +1,9 @@ -// loop.js +/* + the "dull" game engine + + This sets up a lot of different modules to be used altogether +*/ + var render = use('render') // The refactored file above var layout = use('clay') var input = use('input') @@ -7,27 +12,15 @@ var os = use('os') var imgui = use('imgui') var tracy = use('tracy') -var waittime = 1/240 var last_frame_time = 0 -var frame_t = 0 -var fpses = [] var timescale = 1 -var dmon = use('dmon') - -function dmon_cb(e) { prosperon.dispatch('dmon', e) } +last_frame_time = os.now() function step() { - if (dmon) - dmon.poll(dmon_cb) - var now = os.now() var dt = now - last_frame_time - if (dt < waittime) os.sleep(waittime - dt) - last_frame_time = os.now() - - dt = last_frame_time - frame_t - frame_t = last_frame_time + last_frame_time = now // event.engine_input(e => prosperon.dispatch(e.type, e)) layout.newframe() @@ -35,7 +28,6 @@ function step() { prosperon.appupdate(dt) input.procdown() emitter.update(dt * timescale) - os.update_timers(dt * timescale) prosperon.update(dt * timescale) render.setup_draw() diff --git a/scripts/modules/imgui.js b/scripts/modules/imgui.js index 3a2318a3..3fd5edc5 100644 --- a/scripts/modules/imgui.js +++ b/scripts/modules/imgui.js @@ -56,7 +56,7 @@ if (render_menu) { imtoggle("Console [f9]", debug, "console"); }); - imgui.sokol_gfx(); +// imgui.sokol_gfx(); imgui.menu("Graphics", _ => { // imtoggle("Draw sprites", render, "draw_sprites"); diff --git a/scripts/modules/resources.js b/scripts/modules/resources.js index d2614e96..be245223 100644 --- a/scripts/modules/resources.js +++ b/scripts/modules/resources.js @@ -42,6 +42,8 @@ function isRecognizedExtension(ext) { } function find_in_path(filename, exts = []) { + if (typeof filename !== 'string') return undefined + if (filename.includes('.')) { for (var dir of prosperon.PATH) { var candidate = dir + filename diff --git a/source/prosperon.c b/source/prosperon.c index 598d76f8..7945a25d 100644 --- a/source/prosperon.c +++ b/source/prosperon.c @@ -1327,6 +1327,15 @@ static WotaBuffer event2wota(const SDL_Event *event) { int main(int argc, char **argv) { + const char *new_cwd = NULL; + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--cwd") == 0) { + i++; + if (i < argc) new_cwd = argv[i]; + break; + } + } + SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO); queue_event = SDL_RegisterEvents(1); @@ -1335,6 +1344,7 @@ int main(int argc, char **argv) printf("Platform has only one core!\n"); return 1; } + main_thread = SDL_GetCurrentThreadID(); if (!main_thread) { printf("Platform does not support threads!\n"); @@ -1345,7 +1355,11 @@ int main(int argc, char **argv) PHYSFS_init(argv[0]); const char *base = PHYSFS_getBaseDir(); PHYSFS_setWriteDir(base); - PHYSFS_mount(base, "/", 0); + if (new_cwd) + PHYSFS_mount(new_cwd, NULL, 0); + else + PHYSFS_mount(base, NULL, 0); + int mounted = prosperon_mount_core(); if (!mounted) mounted = PHYSFS_mount("core.zip", NULL, 0); if (!mounted) { @@ -1358,7 +1372,7 @@ int main(int argc, char **argv) actors_mutex = SDL_CreateMutex(); const char *io_script = "scripts/core/io.js"; - char **io_argv = malloc(sizeof(char*)*2); + char **io_argv = malloc(sizeof(char*) * 2); io_argv[0] = strdup(argv[0]); io_argv[1] = strdup(io_script); io_actor = create_actor(2, io_argv); @@ -1367,15 +1381,15 @@ int main(int argc, char **argv) char **margv = malloc(sizeof(char *) * (argc + 2)); for (int i = 0; i < argc; i++) margv[i] = strdup(argv[i]); margv[argc] = "--main"; - margv[argc+1] = "1"; - create_actor(argc+2, margv); + margv[argc + 1] = "1"; + create_actor(argc + 2, margv); /* Start the thread that pumps ready actors, one per logical core. */ for (int i = 0; i < cores; i++) { char threadname[128]; snprintf(threadname, 128, "actor runner %d", i); SDL_Thread *thread = SDL_CreateThread(crank_actor, threadname, NULL); - arrput(runners,thread); + arrput(runners, thread); } /* Set up signal and exit handlers. */ @@ -1387,11 +1401,10 @@ int main(int argc, char **argv) SDL_Event event; while (SDL_WaitEvent(&event)) { - if (event.type == queue_event) - goto QUEUE; + if (event.type == queue_event) goto QUEUE; - WotaBuffer wb = event2wota(&event); - send_message(io_actor->id, wb.data); + WotaBuffer wb = event2wota(&event); + send_message(io_actor->id, wb.data); continue; QUEUE: diff --git a/subprojects/sdl3.wrap b/subprojects/sdl3.wrap index b8a3116f..0682a417 100644 --- a/subprojects/sdl3.wrap +++ b/subprojects/sdl3.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://github.com/libsdl-org/SDL.git -revision = release-3.2.4 +revision = release-3.2.10 depth = 1 diff --git a/tests/window.js b/tests/window.js index e5a2631d..fc1b9634 100644 --- a/tests/window.js +++ b/tests/window.js @@ -1,4 +1,4 @@ -//var draw = use('draw2d') +var draw = use('draw2d') prosperon.win = prosperon.engine_start({ title:`Prosperon [${prosperon.version}-${prosperon.revision}]`,