From 019f88c2bc7c69f38ffb91b0d2632ef67b253191 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 4 Jun 2025 14:41:47 -0500 Subject: [PATCH] initial try --- meson.build | 103 +++++++++++++++---------------------------- source/qjs_steam.cpp | 75 ++++++++++++++++--------------- 2 files changed, 75 insertions(+), 103 deletions(-) diff --git a/meson.build b/meson.build index 0e5270cb..ebf34950 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,8 @@ project('cell', ['c', 'cpp'], version: '0.9.3', meson_version: '>=1.4', - default_options : [ 'cpp_std=c++11']) + default_options : [ 'cpp_std=c++11'] +) libtype = get_option('default_library') @@ -24,7 +25,7 @@ if git_commit_cmd.returncode() == 0 cell_commit = git_commit_cmd.stdout().strip() endif -# Important: pass the definitions without double-escaping quotes +# Pass version/commit defines to C add_project_arguments( '-DCELL_VERSION="' + cell_version + '"', '-DCELL_COMMIT="' + cell_commit + '"', @@ -67,21 +68,20 @@ endif cmake = import('cmake') -# Try to find system-installed mbedtls first +# mbedtls (either system or subproject) mbedtls_dep = dependency('mbedtls', static: true, required: false) mbedx509_dep = dependency('mbedx509', static: true, required: false) mbedcrypto_dep = dependency('mbedcrypto', static: true, required: false) - if not mbedtls_dep.found() or not mbedx509_dep.found() or not mbedcrypto_dep.found() message('⚙ System mbedtls not found, building subproject...') mbedtls_opts = cmake.subproject_options() mbedtls_opts.add_cmake_defines({ - 'ENABLE_PROGRAMS': 'OFF', # Disable Mbed TLS programs - 'ENABLE_TESTING': 'OFF', # Disable Mbed TLS tests - 'CMAKE_BUILD_TYPE': 'Release', # Optimize for release - 'MBEDTLS_FATAL_WARNINGS': 'ON', # Treat warnings as errors - 'USE_STATIC_MBEDTLS_LIBRARY': 'ON',# Build static libraries - 'USE_SHARED_MBEDTLS_LIBRARY': 'OFF'# Disable shared libraries + 'ENABLE_PROGRAMS': 'OFF', + 'ENABLE_TESTING': 'OFF', + 'CMAKE_BUILD_TYPE': 'Release', + 'MBEDTLS_FATAL_WARNINGS': 'ON', + 'USE_STATIC_MBEDTLS_LIBRARY': 'ON', + 'USE_SHARED_MBEDTLS_LIBRARY': 'OFF' }) mbedtls_proj = cmake.subproject('mbedtls', options: mbedtls_opts) deps += [ @@ -93,6 +93,7 @@ else deps += [mbedtls_dep, mbedx509_dep, mbedcrypto_dep] endif +# SDL3 (system or subproject) sdl3_opts = cmake.subproject_options() sdl3_opts.add_cmake_defines({ 'SDL_STATIC': 'ON', @@ -103,46 +104,13 @@ sdl3_opts.add_cmake_defines({ 'SDL_PIPEWIRE': 'ON', 'SDL_PULSEAUDIO': 'ON', }) - cc = meson.get_compiler('c') -if host_machine.system() == 'darwin' - deps += dependency('appleframeworks', modules: 'accelerate') - add_project_arguments('-DACCELERATE_NEW_LAPACK=1', language:'c') - add_project_arguments('-DACCELERATE_LAPACK_ILP64=1', language:'c') -endif - -if host_machine.system() == 'linux' - deps += cc.find_library('asound', required:true) - deps += [dependency('x11'), dependency('xi'), dependency('xcursor'), dependency('egl'), dependency('gl')] -endif - -if host_machine.system() == 'windows' - deps += cc.find_library('d3d11') - deps += cc.find_library('ws2_32', required:true) - deps += cc.find_library('dbghelp') - deps += cc.find_library('winmm') - deps += cc.find_library('setupapi') - deps += cc.find_library('imm32') - deps += cc.find_library('version') - deps += cc.find_library('cfgmgr32') - deps += cc.find_library('bcrypt') - sdl3_opts.add_cmake_defines({'HAVE_ISINF': '1'}) # Hack for MSYS2 - sdl3_opts.add_cmake_defines({'HAVE_ISNAN': '1'}) - link += '-static' -endif - if host_machine.system() == 'emscripten' link += '-sUSE_WEBGPU' - # Use the pre-installed copy - deps += dependency('sdl3', - static : true, - method : 'pkg-config', # or 'cmake' if you prefer - required : true) + deps += dependency('sdl3', static : true, method : 'pkg-config', required : true) else - # Try to find system-installed SDL3 first sdl3_dep = dependency('sdl3', static: true, required: false) - if not sdl3_dep.found() message('⚙ System SDL3 not found, building subproject...') sdl3_proj = cmake.subproject('sdl3', options : sdl3_opts) @@ -154,13 +122,9 @@ endif quickjs_opts = [] quickjs_opts += 'default_library=static' - -# Enable leak detection for non-release builds if get_option('buildtype') != 'release' quickjs_opts += 'leaks=true' endif - -# Try to find system-installed quickjs first quickjs_dep = dependency('quickjs', static: true, required: false) if not quickjs_dep.found() message('⚙ System quickjs not found, building subproject...') @@ -169,7 +133,6 @@ else deps += quickjs_dep endif -# Try to find system-installed qjs-layout first qjs_layout_dep = dependency('qjs-layout', static: true, required: false) if not qjs_layout_dep.found() message('⚙ System qjs-layout not found, building subproject...') @@ -186,7 +149,6 @@ else deps += miniz_dep endif -# Try to find system-installed physfs first physfs_dep = dependency('physfs', static: true, required: false) if not physfs_dep.found() message('⚙ System physfs not found, building subproject...') @@ -197,7 +159,6 @@ endif deps += dependency('threads') -# Try to find system-installed chipmunk first chipmunk_dep = dependency('chipmunk', static: true, required: false) if not chipmunk_dep.found() message('⚙ System chipmunk not found, building subproject...') @@ -207,7 +168,6 @@ else endif if host_machine.system() != 'emscripten' - # Try to find system-installed enet first enet_dep = dependency('enet', static: true, required: false) if not enet_dep.found() message('⚙ System enet not found, building subproject...') @@ -219,8 +179,6 @@ if host_machine.system() != 'emscripten' tracy_opts = ['fibers=true', 'no_exit=true', 'libunwind_backtrace=true'] add_project_arguments('-DTRACY_ENABLE', language:['c','cpp']) - - # Try to find system-installed tracy first tracy_dep = dependency('tracy', static: true, required: false) if not tracy_dep.found() message('⚙ System tracy not found, building subproject...') @@ -232,7 +190,6 @@ if host_machine.system() != 'emscripten' src += 'qjs_dmon.c' endif -# Try to find system-installed soloud first soloud_dep = dependency('soloud', static: true, required: false) if not soloud_dep.found() message('⚙ System soloud not found, building subproject...') @@ -241,7 +198,6 @@ else deps += soloud_dep endif -# Try to find system-installed qrencode first qr_dep = dependency('qrencode', static: true, required: false) if not qr_dep.found() message('⚙ System qrencode not found, building subproject...') @@ -250,11 +206,9 @@ else deps += qr_dep endif -# Storefront SDK support storefront = get_option('storefront') if storefront == 'steam' steam_sdk_path = meson.current_source_dir() / 'sdk' - if host_machine.system() == 'darwin' steam_lib_path = steam_sdk_path / 'redistributable_bin' / 'osx' / 'libsteam_api.dylib' elif host_machine.system() == 'linux' @@ -264,7 +218,7 @@ if storefront == 'steam' else steam_lib_path = '' endif - + if fs.exists(steam_lib_path) steam_dep = declare_dependency( include_directories: include_directories('sdk/public'), @@ -281,7 +235,10 @@ else message('Storefront: ' + storefront) endif +# Any extra linker flags link_args = link + +# === COLLECT ALL SOURCE FILES === sources = [] src += [ 'anim.c', 'config.c', 'datastream.c','font.c','HandmadeMath.c','jsffi.c','model.c', @@ -289,7 +246,6 @@ src += [ 'sprite.c', 'rtree.c', 'qjs_nota.c', 'qjs_soloud.c', 'qjs_sdl.c', 'qjs_sdl_video.c', 'qjs_sdl_surface.c', 'qjs_math.c', 'qjs_geometry.c', 'qjs_transform.c', 'qjs_sprite.c', 'qjs_io.c', 'qjs_fd.c', 'qjs_os.c', 'qjs_actor.c', 'qjs_qr.c', 'qjs_wota.c', 'monocypher.c', 'qjs_blob.c', 'qjs_crypto.c', 'qjs_time.c', 'qjs_http.c', 'qjs_rtree.c', 'qjs_spline.c', 'qjs_js.c', 'qjs_debug.c', 'picohttpparser.c', 'qjs_miniz.c' ] -# quirc src src += [ 'thirdparty/quirc/quirc.c', 'thirdparty/quirc/decode.c', 'thirdparty/quirc/identify.c', 'thirdparty/quirc/version_db.c' @@ -326,23 +282,37 @@ else endif strip_enabled = ['release', 'minsize'].contains(get_option('buildtype')) - if strip_enabled add_project_link_arguments('-s', language: ['c', 'cpp']) endif -cell = executable('cell', sources, +# === NEW: build a STATIC library "cell_core" from exactly the same sources === +cell_core = static_library( + 'cell_core', # → libcell_core.a + sources, dependencies: deps, + include_directories: includers +) + +# === Now build the "cell" executable by linking against that static lib === +cell = executable('cell', + link_with : [ cell_core ], + dependencies : deps, include_directories: includers, - link_args: link, - build_rpath: '$ORIGIN', - install: true + link_args : link_args, + build_rpath : '$ORIGIN', + install : true ) +# === Declare a Meson dependency so that other subprojects can do `dependency('cell')` if needed === cell_dep = declare_dependency( - link_with: cell + link_with: [ cell_core ], + include_directories: includers ) + + +# === TESTS (unchanged) === tests = [ 'spawn_actor', 'empty', @@ -353,7 +323,6 @@ tests = [ 'send', 'delay' ] - foreach file : tests test(file, cell, args:['tests/' + file]) endforeach diff --git a/source/qjs_steam.cpp b/source/qjs_steam.cpp index 3a4412d3..cda98728 100644 --- a/source/qjs_steam.cpp +++ b/source/qjs_steam.cpp @@ -2,7 +2,9 @@ extern "C" { #include "qjs_steam.h" -#include "jsffi.h" +#include "cell.h" +#include "qjs_macros.h" +#include "qjs_blob.h" } #include @@ -60,21 +62,22 @@ JSC_CCALL(steam_run_callbacks, ) // USER STATS & ACHIEVEMENTS -JSC_CCALL(stats_request, +JSC_CCALL(steam_stats_request, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); - bool success = SteamAPI_ISteamUserStats_RequestCurrentStats(steam_stats); + SteamAPICall_t call = SteamAPI_ISteamUserStats_RequestUserStats(steam_stats, SteamAPI_ISteamUser_GetSteamID(steam_user)); + bool success = (call != k_uAPICallInvalid); return JS_NewBool(js, success); ) -JSC_CCALL(stats_store, +JSC_CCALL(steam_stats_store, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); bool success = SteamAPI_ISteamUserStats_StoreStats(steam_stats); return JS_NewBool(js, success); ) -JSC_CCALL(stats_get_int, +JSC_CCALL(steam_stats_get_int, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -88,7 +91,7 @@ JSC_CCALL(stats_get_int, return JS_NewInt32(js, value); ) -JSC_CCALL(stats_get_float, +JSC_CCALL(steam_stats_get_float, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -102,7 +105,7 @@ JSC_CCALL(stats_get_float, return JS_NewFloat64(js, value); ) -JSC_CCALL(stats_set_int, +JSC_CCALL(steam_stats_set_int, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -117,7 +120,7 @@ JSC_CCALL(stats_set_int, return JS_NewBool(js, success); ) -JSC_CCALL(stats_set_float, +JSC_CCALL(steam_stats_set_float, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -133,7 +136,7 @@ JSC_CCALL(stats_set_float, return JS_NewBool(js, success); ) -JSC_CCALL(achievement_get, +JSC_CCALL(steam_achievement_get, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -147,7 +150,7 @@ JSC_CCALL(achievement_get, return JS_NewBool(js, achieved); ) -JSC_CCALL(achievement_set, +JSC_CCALL(steam_achievement_set, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -159,7 +162,7 @@ JSC_CCALL(achievement_set, return JS_NewBool(js, success); ) -JSC_CCALL(achievement_clear, +JSC_CCALL(steam_achievement_clear, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); const char *name = JS_ToCString(js, argv[0]); @@ -171,14 +174,14 @@ JSC_CCALL(achievement_clear, return JS_NewBool(js, success); ) -JSC_CCALL(achievement_count, +JSC_CCALL(steam_achievement_count, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); uint32 count = SteamAPI_ISteamUserStats_GetNumAchievements(steam_stats); return JS_NewUint32(js, count); ) -JSC_CCALL(achievement_name, +JSC_CCALL(steam_achievement_name, if (!steam_stats) return JS_ThrowInternalError(js, "Steam stats not initialized"); uint32 index; @@ -191,21 +194,21 @@ JSC_CCALL(achievement_name, ) // APPS -JSC_CCALL(app_id, +JSC_CCALL(steam_app_id, if (!steam_utils) return JS_ThrowInternalError(js, "Steam utils not initialized"); AppId_t appid = SteamAPI_ISteamUtils_GetAppID(steam_utils); return JS_NewUint32(js, appid); ) -JSC_CCALL(app_owner, +JSC_CCALL(steam_app_owner, if (!steam_apps) return JS_ThrowInternalError(js, "Steam apps not initialized"); uint64_steamid owner = SteamAPI_ISteamApps_GetAppOwner(steam_apps); return JS_NewBigUint64(js, owner); ) -JSC_CCALL(app_installed, +JSC_CCALL(steam_app_installed, if (!steam_apps) return JS_ThrowInternalError(js, "Steam apps not initialized"); uint32 appid; @@ -215,21 +218,21 @@ JSC_CCALL(app_installed, return JS_NewBool(js, installed); ) -JSC_CCALL(app_subscribed, +JSC_CCALL(steam_app_subscribed, if (!steam_apps) return JS_ThrowInternalError(js, "Steam apps not initialized"); bool subscribed = SteamAPI_ISteamApps_BIsSubscribed(steam_apps); return JS_NewBool(js, subscribed); ) -JSC_CCALL(app_language, +JSC_CCALL(steam_app_language, if (!steam_apps) return JS_ThrowInternalError(js, "Steam apps not initialized"); const char *lang = SteamAPI_ISteamApps_GetCurrentGameLanguage(steam_apps); return JS_NewString(js, lang ? lang : "english"); ) -JSC_CCALL(app_dlc_installed, +JSC_CCALL(steam_app_dlc_installed, if (!steam_apps) return JS_ThrowInternalError(js, "Steam apps not initialized"); AppId_t dlcid; @@ -240,21 +243,21 @@ JSC_CCALL(app_dlc_installed, ) // USER -JSC_CCALL(user_logged_on, +JSC_CCALL(steam_user_logged_on, if (!steam_user) return JS_ThrowInternalError(js, "Steam user not initialized"); bool logged = SteamAPI_ISteamUser_BLoggedOn(steam_user); return JS_NewBool(js, logged); ) -JSC_CCALL(user_steam_id, +JSC_CCALL(steam_user_steam_id, if (!steam_user) return JS_ThrowInternalError(js, "Steam user not initialized"); uint64_steamid id = SteamAPI_ISteamUser_GetSteamID(steam_user); return JS_NewBigUint64(js, id); ) -JSC_CCALL(user_level, +JSC_CCALL(steam_user_level, if (!steam_user) return JS_ThrowInternalError(js, "Steam user not initialized"); int level = SteamAPI_ISteamUser_GetPlayerSteamLevel(steam_user); @@ -262,14 +265,14 @@ JSC_CCALL(user_level, ) // FRIENDS -JSC_CCALL(friends_name, +JSC_CCALL(steam_friends_name, if (!steam_friends) return JS_ThrowInternalError(js, "Steam friends not initialized"); const char *name = SteamAPI_ISteamFriends_GetPersonaName(steam_friends); return JS_NewString(js, name ? name : ""); ) -JSC_CCALL(friends_state, +JSC_CCALL(steam_friends_state, if (!steam_friends) return JS_ThrowInternalError(js, "Steam friends not initialized"); EPersonaState state = SteamAPI_ISteamFriends_GetPersonaState(steam_friends); @@ -288,21 +291,21 @@ JSC_CCALL(friends_state, ) // CLOUD STORAGE -JSC_CCALL(cloud_enabled_app, +JSC_CCALL(steam_cloud_enabled_app, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); bool enabled = SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp(steam_remote); return JS_NewBool(js, enabled); ) -JSC_CCALL(cloud_enabled_account, +JSC_CCALL(steam_cloud_enabled_account, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); bool enabled = SteamAPI_ISteamRemoteStorage_IsCloudEnabledForAccount(steam_remote); return JS_NewBool(js, enabled); ) -JSC_CCALL(cloud_enable, +JSC_CCALL(steam_cloud_enable, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); bool enable = JS_ToBool(js, argv[0]); @@ -310,7 +313,7 @@ JSC_CCALL(cloud_enable, return JS_UNDEFINED; ) -JSC_CCALL(cloud_quota, +JSC_CCALL(steam_cloud_quota, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); uint64 total, available; @@ -324,7 +327,7 @@ JSC_CCALL(cloud_quota, return obj; ) -JSC_CCALL(cloud_write, +JSC_CCALL(steam_cloud_write, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); const char *filename = JS_ToCString(js, argv[0]); @@ -341,7 +344,7 @@ JSC_CCALL(cloud_write, } data = (uint8_t*)str; } else { - data = js_get_blob_data(js, &data_len, argv[1]); + data = (uint8_t*)js_get_blob_data(js, &data_len, argv[1]); if (!data) { JS_FreeCString(js, filename); return JS_ThrowTypeError(js, "Second argument must be string or ArrayBuffer"); @@ -358,7 +361,7 @@ JSC_CCALL(cloud_write, return JS_NewBool(js, success); ) -JSC_CCALL(cloud_read, +JSC_CCALL(steam_cloud_read, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); const char *filename = JS_ToCString(js, argv[0]); @@ -389,7 +392,7 @@ JSC_CCALL(cloud_read, return result; ) -JSC_CCALL(cloud_delete, +JSC_CCALL(steam_cloud_delete, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); const char *filename = JS_ToCString(js, argv[0]); @@ -401,7 +404,7 @@ JSC_CCALL(cloud_delete, return JS_NewBool(js, success); ) -JSC_CCALL(cloud_exists, +JSC_CCALL(steam_cloud_exists, if (!steam_remote) return JS_ThrowInternalError(js, "Steam remote storage not initialized"); const char *filename = JS_ToCString(js, argv[0]); @@ -464,9 +467,9 @@ static const JSCFunctionListEntry js_steam_cloud_funcs[] = { // Main Steam API functions static const JSCFunctionListEntry js_steam_funcs[] = { - MIST_FUNC_DEF(steam, steam_init, 0), - MIST_FUNC_DEF(steam, steam_shutdown, 0), - MIST_FUNC_DEF(steam, steam_run_callbacks, 0), + MIST_FUNC_DEF(steam, init, 0), + MIST_FUNC_DEF(steam, shutdown, 0), + MIST_FUNC_DEF(steam, run_callbacks, 0), }; extern "C" JSValue js_steam_use(JSContext *js) {