basic emscripten compat and various fixes
This commit is contained in:
parent
8fc5abb78a
commit
c8e057e388
12 changed files with 145 additions and 72 deletions
|
@ -1,5 +1,5 @@
|
|||
|
||||
if get_option('docs')
|
||||
if install_docs
|
||||
rst2html5 = find_program(
|
||||
'rst2html5',
|
||||
'rst2html5.py',
|
||||
|
|
53
meson.build
53
meson.build
|
@ -79,7 +79,6 @@ endforeach
|
|||
|
||||
static = get_option('static')
|
||||
|
||||
dep_crossc = dependency('crossc', version : '>=1.5.0', required : false, static : static, fallback : ['crossc', 'crossc_dep'])
|
||||
dep_freetype = dependency('freetype2', required : true, static : static)
|
||||
dep_png = dependency('libpng', version : '>=1.5', required : true, static : static)
|
||||
dep_sdl2 = dependency('sdl2', version : '>=2.0.5', required : true, static : static)
|
||||
|
@ -90,14 +89,6 @@ dep_zip = dependency('libzip', version : '>=1.0', required : f
|
|||
dep_zlib = dependency('zlib', required : true, static : static)
|
||||
dep_crypto = dependency('libcrypto', required : false, static : static)
|
||||
|
||||
# Thanks, google.
|
||||
# https://github.com/google/shaderc/issues/392
|
||||
if static
|
||||
dep_shaderc = cc.find_library('shaderc_combined', required : false)
|
||||
else
|
||||
dep_shaderc = cc.find_library('shaderc_shared', required : false)
|
||||
endif
|
||||
|
||||
dep_m = cc.find_library('m', required : false)
|
||||
|
||||
dep_cglm = subproject('cglm').get_variable('cglm_dep')
|
||||
|
@ -150,19 +141,23 @@ endif
|
|||
|
||||
config.set('TAISEI_BUILDCONF_USE_ZIP', taisei_deps.contains(dep_zip))
|
||||
|
||||
have_posix = cc.has_header_symbol('unistd.h', '_POSIX_VERSION')
|
||||
have_vla = not cc.has_header_symbol('unistd.h', '__STDC_NO_VLA__')
|
||||
have_complex = not cc.has_header_symbol('unistd.h', '__STDC_NO_COMPLEX__')
|
||||
have_timespec = cc.has_header_symbol('time.h', 'timespec_get')
|
||||
have_posix = cc.has_header_symbol('unistd.h', '_POSIX_VERSION')
|
||||
have_vla = not cc.has_header_symbol('stdlib.h', '__STDC_NO_VLA__')
|
||||
have_complex = not cc.has_header_symbol('stdlib.h', '__STDC_NO_COMPLEX__')
|
||||
have_timespec = cc.has_header_symbol('time.h', 'timespec_get')
|
||||
|
||||
if not (have_vla and have_complex)
|
||||
error('Your C implementation needs to support complex numbers and variable-length arrays.')
|
||||
endif
|
||||
assert(have_vla and have_complex, 'Your C implementation needs to support complex numbers and variable-length arrays.')
|
||||
|
||||
config.set('TAISEI_BUILDCONF_HAVE_TIMESPEC', have_timespec)
|
||||
config.set('TAISEI_BUILDCONF_HAVE_INT128', cc.sizeof('__int128') == 16)
|
||||
config.set('TAISEI_BUILDCONF_HAVE_LONG_DOUBLE', cc.sizeof('long double') > 8)
|
||||
config.set('TAISEI_BUILDCONF_HAVE_POSIX', have_posix)
|
||||
config.set('TAISEI_BUILDCONF_HAVE_MAX_ALIGN_T', cc.compiles('#include <stddef.h>\nmax_align_t i;', name : 'max_align_t test'))
|
||||
|
||||
prefer_relpath_systems = [
|
||||
'windows',
|
||||
'emscripten',
|
||||
]
|
||||
|
||||
if macos_app_bundle
|
||||
bundle_dir = 'Taisei.app'
|
||||
|
@ -182,7 +177,7 @@ else
|
|||
datadir = get_option('datadir')
|
||||
|
||||
if get_option('install_relative') == 'auto'
|
||||
config.set('TAISEI_BUILDCONF_RELATIVE_DATA_PATH', host_machine.system() == 'windows')
|
||||
config.set('TAISEI_BUILDCONF_RELATIVE_DATA_PATH', prefer_relpath_systems.contains(host_machine.system()))
|
||||
else
|
||||
config.set('TAISEI_BUILDCONF_RELATIVE_DATA_PATH', get_option('install_relative') == 'true')
|
||||
endif
|
||||
|
@ -202,7 +197,7 @@ endif
|
|||
|
||||
if config.get('TAISEI_BUILDCONF_RELATIVE_DATA_PATH')
|
||||
data_path = 'data'
|
||||
doc_path = ''
|
||||
doc_path = '.' # Meson bug https://github.com/mesonbuild/meson/issues/4295
|
||||
xdg_path = 'freedesktop.org'
|
||||
|
||||
# This is relative to SDL_GetBasePath()
|
||||
|
@ -233,14 +228,18 @@ config.set('TAISEI_BUILDCONF_LOG_FATAL_MSGBOX', (
|
|||
))
|
||||
config.set('TAISEI_BUILDCONF_DEBUG_OPENGL', get_option('debug_opengl'))
|
||||
|
||||
install_docs = get_option('docs') and host_machine.system() != 'emscripten'
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
custom_target('COPYING.txt',
|
||||
command : [eolconv_command, host_eol_style, '@INPUT@', '@OUTPUT@'],
|
||||
input : 'COPYING',
|
||||
output : 'COPYING.txt',
|
||||
install : true,
|
||||
install_dir : doc_path
|
||||
)
|
||||
if install_docs
|
||||
custom_target('COPYING.txt',
|
||||
command : [eolconv_command, host_eol_style, '@INPUT@', '@OUTPUT@'],
|
||||
input : 'COPYING',
|
||||
output : 'COPYING.txt',
|
||||
install : true,
|
||||
install_dir : doc_path
|
||||
)
|
||||
endif
|
||||
|
||||
if angle_enabled
|
||||
install_data(
|
||||
|
@ -250,7 +249,9 @@ if host_machine.system() == 'windows'
|
|||
)
|
||||
endif
|
||||
else
|
||||
install_data('COPYING', install_dir : doc_path)
|
||||
if install_docs
|
||||
install_data('COPYING', install_dir : doc_path)
|
||||
endif
|
||||
|
||||
if angle_enabled
|
||||
error('install_angle is only available for Windows targets at the moment')
|
||||
|
|
|
@ -27,7 +27,7 @@ void fpscounter_reset(FPSCounter *fps) {
|
|||
|
||||
void fpscounter_update(FPSCounter *fps) {
|
||||
const int log_size = sizeof(fps->frametimes)/sizeof(hrtime_t);
|
||||
double frametime = time_get() - fps->last_update_time;
|
||||
hrtime_t frametime = time_get() - fps->last_update_time;
|
||||
|
||||
memmove(fps->frametimes, fps->frametimes + 1, (log_size - 1) * sizeof(hrtime_t));
|
||||
fps->frametimes[log_size - 1] = frametime;
|
||||
|
@ -55,6 +55,11 @@ uint32_t get_effective_frameskip(void) {
|
|||
return frameskip;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define SDL_Delay emscripten_sleep
|
||||
#endif
|
||||
|
||||
void loop_at_fps(LogicFrameFunc logic_frame, RenderFrameFunc render_frame, void *arg, uint32_t fps) {
|
||||
assert(logic_frame != NULL);
|
||||
assert(render_frame != NULL);
|
||||
|
@ -179,6 +184,10 @@ begin_frame:
|
|||
next_frame_time = frame_start_time + target_frame_time;
|
||||
// next_frame_time = frame_start_time + 2 * target_frame_time - global.fps.logic.frametime;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
SDL_Delay(1);
|
||||
#endif
|
||||
|
||||
if(compensate) {
|
||||
hrtime_t rt = time_get();
|
||||
|
||||
|
|
20
src/log.h
20
src/log.h
|
@ -40,7 +40,11 @@ typedef enum LogLevel {
|
|||
#endif
|
||||
|
||||
#ifndef LOG_DEFAULT_LEVELS_FILE
|
||||
#define LOG_DEFAULT_LEVELS_FILE LOG_ALL
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define LOG_DEFAULT_LEVELS_FILE LOG_ALL
|
||||
#else
|
||||
#define LOG_DEFAULT_LEVELS_FILE LOG_NONE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LOG_DEFAULT_LEVELS_CONSOLE
|
||||
|
@ -52,11 +56,19 @@ typedef enum LogLevel {
|
|||
#endif
|
||||
|
||||
#ifndef LOG_DEFAULT_LEVELS_STDOUT
|
||||
#define LOG_DEFAULT_LEVELS_STDOUT LOG_SPAM
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define LOG_DEFAULT_LEVELS_STDOUT LOG_ALL
|
||||
#else
|
||||
#define LOG_DEFAULT_LEVELS_STDOUT LOG_SPAM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LOG_DEFAULT_LEVELS_STDERR
|
||||
#define LOG_DEFAULT_LEVELS_STDERR LOG_ALERT
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define LOG_DEFAULT_LEVELS_STDERR LOG_NONE
|
||||
#else
|
||||
#define LOG_DEFAULT_LEVELS_STDERR LOG_ALERT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct LogEntry {
|
||||
|
@ -90,7 +102,7 @@ LogLevel log_parse_levels(LogLevel lvls, const char *lvlmod) attr_nodiscard;
|
|||
bool log_initialized(void) attr_nodiscard;
|
||||
void log_set_gui_error_appendix(const char *message);
|
||||
|
||||
#ifdef DEBUG
|
||||
#if defined(DEBUG) && !defined(__EMSCRIPTEN__)
|
||||
#define log_debug(...) log_custom(LOG_DEBUG, __VA_ARGS__)
|
||||
#undef UNREACHABLE
|
||||
#define UNREACHABLE log_fatal("This code should never be reached")
|
||||
|
|
15
src/main.c
15
src/main.c
|
@ -86,7 +86,7 @@ static void init_log_file(void) {
|
|||
}
|
||||
|
||||
/*
|
||||
void sdl_log(void *userdata, int category, SDL_LogPriority priority, const char *message) {
|
||||
static SDLCALL void sdl_log(void *userdata, int category, SDL_LogPriority priority, const char *message) {
|
||||
log_debug("[%i %i] %s", category, priority, message);
|
||||
}
|
||||
*/
|
||||
|
@ -101,11 +101,9 @@ static void init_sdl(void) {
|
|||
// initialize it
|
||||
is_main_thread();
|
||||
|
||||
/*
|
||||
* TODO: refine this and make it optional
|
||||
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
||||
SDL_LogSetOutputFunction(sdl_log, NULL);
|
||||
*/
|
||||
// * TODO: refine this and make it optional
|
||||
// SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
||||
// SDL_LogSetOutputFunction(sdl_log, NULL);
|
||||
|
||||
log_info("SDL initialized");
|
||||
|
||||
|
@ -225,6 +223,11 @@ int main(int argc, char **argv) {
|
|||
init_log_file();
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
env_set("TAISEI_NOASYNC", true, true);
|
||||
env_set("TAISEI_NOPRELOAD", true, true);
|
||||
#endif
|
||||
|
||||
log_info("%s %s", TAISEI_VERSION_FULL, TAISEI_VERSION_BUILD_TYPE);
|
||||
log_system_specs();
|
||||
log_lib_versions();
|
||||
|
|
|
@ -8,9 +8,15 @@ r_shaderlib_src = files(
|
|||
r_shaderlib_libdeps = []
|
||||
|
||||
if get_option('shader_transpiler')
|
||||
assert(dep_shaderc.found() and dep_crossc.found(),
|
||||
'shaderc and crossc are required for shader translation. Install them or disable shader_transpiler.'
|
||||
)
|
||||
dep_crossc = dependency('crossc', version : '>=1.5.0', required : true, static : static, fallback : ['crossc', 'crossc_dep'])
|
||||
|
||||
# Thanks, google.
|
||||
# https://github.com/google/shaderc/issues/392
|
||||
if static
|
||||
dep_shaderc = cc.find_library('shaderc_combined', required : true)
|
||||
else
|
||||
dep_shaderc = cc.find_library('shaderc_shared', required : true)
|
||||
endif
|
||||
|
||||
r_shaderlib_src += files(
|
||||
'lang_spirv.c'
|
||||
|
|
|
@ -603,13 +603,16 @@ void glcommon_setup_attributes(SDL_GLprofile profile, uint major, uint minor, SD
|
|||
ctxflags |= SDL_GL_CONTEXT_DEBUG_FLAG;
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, ctxflags);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -141,6 +141,10 @@ typedef _Complex double complex;
|
|||
// standard says `complex` should be a macro
|
||||
#define complex complex
|
||||
|
||||
#ifndef TAISEI_BUILDCONF_HAVE_MAX_ALIGN_T
|
||||
typedef complex max_align_t;
|
||||
#endif
|
||||
|
||||
// In case the C11 CMPLX macro is not present, try our best to provide a substitute
|
||||
#if !defined CMPLX
|
||||
#undef HAS_BUILTIN_COMPLEX
|
||||
|
|
|
@ -236,32 +236,57 @@ void gaussian_kernel_1d(size_t size, float sigma, float kernel[size]) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t upow10(uint n) {
|
||||
static uint64_t pow10[] = {
|
||||
1ull,
|
||||
10ull,
|
||||
100ull,
|
||||
1000ull,
|
||||
10000ull,
|
||||
100000ull,
|
||||
1000000ull,
|
||||
10000000ull,
|
||||
100000000ull,
|
||||
1000000000ull,
|
||||
10000000000ull,
|
||||
100000000000ull,
|
||||
1000000000000ull,
|
||||
10000000000000ull,
|
||||
100000000000000ull,
|
||||
1000000000000000ull,
|
||||
10000000000000000ull,
|
||||
100000000000000000ull,
|
||||
1000000000000000000ull,
|
||||
10000000000000000000ull,
|
||||
};
|
||||
static const uint64_t upow10_table[] = {
|
||||
1ull,
|
||||
10ull,
|
||||
100ull,
|
||||
1000ull,
|
||||
10000ull,
|
||||
100000ull,
|
||||
1000000ull,
|
||||
10000000ull,
|
||||
100000000ull,
|
||||
1000000000ull,
|
||||
10000000000ull,
|
||||
100000000000ull,
|
||||
1000000000000ull,
|
||||
10000000000000ull,
|
||||
100000000000000ull,
|
||||
1000000000000000ull,
|
||||
10000000000000000ull,
|
||||
100000000000000000ull,
|
||||
1000000000000000000ull,
|
||||
10000000000000000000ull,
|
||||
};
|
||||
|
||||
assert(n < sizeof(pow10)/sizeof(*pow10));
|
||||
return pow10[n];
|
||||
uint64_t upow10(uint n) {
|
||||
assert(n < sizeof(upow10_table)/sizeof(*upow10_table));
|
||||
return upow10_table[n];
|
||||
}
|
||||
|
||||
uint digitcnt(uint64_t x) {
|
||||
if(x == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint low = 0;
|
||||
uint high = sizeof(upow10_table)/sizeof(*upow10_table) - 1;
|
||||
|
||||
for(;;) {
|
||||
uint mid = (low + high) / 2;
|
||||
|
||||
if(x >= upow10_table[mid]) {
|
||||
if(low == mid) {
|
||||
return mid + 1;
|
||||
}
|
||||
|
||||
low = mid;
|
||||
} else {
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
typedef struct int128_bits {
|
||||
|
|
|
@ -45,6 +45,7 @@ float smooth(float x) attr_const;
|
|||
float smoothreclamp(float x, float old_min, float old_max, float new_min, float new_max) attr_const;
|
||||
float sanitize_scale(float scale) attr_const;
|
||||
uint64_t upow10(uint n) attr_const;
|
||||
uint digitcnt(uint64_t x) attr_const;
|
||||
float normpdf(float x, float sigma) attr_const;
|
||||
void gaussian_kernel_1d(size_t size, float sigma, float kernel[size]) attr_nonnull(3);
|
||||
|
||||
|
|
|
@ -433,10 +433,9 @@ uint32_t utf8_getch(const char **src) {
|
|||
|
||||
void format_huge_num(uint digits, uint64_t num, size_t bufsize, char *buf) {
|
||||
if(digits == 0) {
|
||||
digits = 1 + (num ? floor(log10(num)) : 0);
|
||||
digits = digitcnt(num);
|
||||
}
|
||||
|
||||
digits = umin(19, digits);
|
||||
num = umin(upow10(digits) - 1, num);
|
||||
|
||||
div_t separators = div(digits, 3);
|
||||
|
|
|
@ -27,6 +27,11 @@ static char* get_default_res_path(void) {
|
|||
}
|
||||
|
||||
static void get_core_paths(char **res, char **storage, char **cache) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
*res = get_default_res_path();
|
||||
*storage = strdup("/storage");
|
||||
*cache = strdup("/cache");
|
||||
#else
|
||||
if(*(*res = (char*)env_get("TAISEI_RES_PATH", ""))) {
|
||||
*res = strdup(*res);
|
||||
} else {
|
||||
|
@ -43,8 +48,13 @@ static void get_core_paths(char **res, char **storage, char **cache) {
|
|||
*cache = strdup(*cache);
|
||||
} else {
|
||||
// TODO: follow XDG on linux
|
||||
*cache = strfmt("%s%ccache", *storage, vfs_get_syspath_separator());
|
||||
if(*storage != NULL) {
|
||||
*cache = strfmt("%s%ccache", *storage, vfs_get_syspath_separator());
|
||||
} else {
|
||||
*cache = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool vfs_mount_pkgdir(const char *dst, const char *src) {
|
||||
|
|
Loading…
Reference in a new issue