basic emscripten compat and various fixes

This commit is contained in:
Andrei Alexeyev 2019-02-22 01:56:48 +02:00
parent 8fc5abb78a
commit c8e057e388
No known key found for this signature in database
GPG key ID: 363707CD4C7FE8A4
12 changed files with 145 additions and 72 deletions

View file

@ -1,5 +1,5 @@
if get_option('docs')
if install_docs
rst2html5 = find_program(
'rst2html5',
'rst2html5.py',

View file

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

View file

@ -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();

View file

@ -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")

View file

@ -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();

View file

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

View file

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

View file

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

View file

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

View file

@ -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);

View file

@ -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);

View file

@ -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) {