1 Commits
stack ... steam

Author SHA1 Message Date
John Alanbrook
019f88c2bc initial try 2025-06-04 14:41:47 -05:00
2 changed files with 75 additions and 103 deletions

View File

@@ -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'
@@ -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

View File

@@ -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 <steam/steam_api.h>
@@ -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) {