sync fwk
parent
a9c5d6c269
commit
64a7eade9f
|
@ -13,3 +13,4 @@ demos/ports/*/*.exe
|
|||
demos/ports/doom/.doomrc
|
||||
*.sublime-workspace
|
||||
engine/v4k.html
|
||||
*.exe.manifest
|
||||
|
|
1
MAKE.bat
1
MAKE.bat
|
@ -395,6 +395,7 @@ if "%1"=="tidy" (
|
|||
del *.zip > nul 2> nul
|
||||
del *.mem > nul 2> nul
|
||||
del *.exp > nul 2> nul
|
||||
del *.exe.manifest > nul 2> nul
|
||||
del tools\*.exp > nul 2> nul
|
||||
del *.lib > nul 2> nul
|
||||
del *.exe > nul 2> nul
|
||||
|
|
2
_mirror
2
_mirror
|
@ -1 +1 @@
|
|||
Subproject commit 20989f73cd14330b84c627cc1742b63732d67bcb
|
||||
Subproject commit 494a0e216d2b4984065994372960d15f197c1e07
|
10
bind/v4k.lua
10
bind/v4k.lua
|
@ -1496,6 +1496,9 @@ ffi.cdef([[
|
|||
//lcpp INF [0000] vec3: macro name but used as C declaration in: void light_dir(light_t* l, vec3 dir);
|
||||
//lcpp INF [0000] vec2i: macro name but used as C declaration in:vec2i* entries;
|
||||
//lcpp INF [0000] vec3i: macro name but used as C declaration in:typedef vec3i guid;
|
||||
//lcpp INF [0000] test: macro name but used as C declaration in:API int (test)(const char *file, int line, const char *expr, bool result);
|
||||
//lcpp INF [0000] test: macro name but used as C declaration in:STATIC int (test)(const char *file, int line, const char *expr, bool result);
|
||||
//lcpp INF [0000] test: macro name but used as C declaration in: int (test)(const char *file, int line, const char *expr, bool result);
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 ui_get_dims();
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 ui_get_dims();
|
||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 ui_get_dims();
|
||||
|
@ -2120,7 +2123,7 @@ typedef union json_t { char* s; double f; int64_t i; uintptr_t p; union json_t*
|
|||
char* kit_translate( const char *id );
|
||||
char* kit_translate2( const char *id, const char *langcode_iso639_1 );
|
||||
void kit_dump_state( FILE *fp );
|
||||
const char** file_list(const char *path, const char *masks);
|
||||
char** file_list( const char *pathmasks );
|
||||
bool file_write( const char *file, const void *ptr, int len );
|
||||
bool file_append( const char *file, const void *ptr, int len );
|
||||
char * file_read(const char *filename);
|
||||
|
@ -3088,6 +3091,8 @@ typedef vec3i guid;
|
|||
void trap_on_abort(int signal);
|
||||
void trap_on_debug(int signal);
|
||||
int (PANIC)(const char *error, const char *file, int line);
|
||||
int (PRINTF)(const char *text, const char *stack, const char *file, int line, const char *function);
|
||||
int (test)(const char *file, int line, const char *expr, bool result);
|
||||
enum PANEL_FLAGS {
|
||||
PANEL_OPEN = 1,
|
||||
};
|
||||
|
@ -3208,7 +3213,6 @@ WINDOW_VSYNC_DISABLED =8192,
|
|||
void window_loop(void (*function)(void* loopArg), void* loopArg );
|
||||
void window_loop_exit();
|
||||
void window_title(const char *title);
|
||||
void window_icon(const char *file_icon);
|
||||
void window_color(unsigned color);
|
||||
vec2 window_canvas();
|
||||
void* window_handle();
|
||||
|
@ -3232,6 +3236,8 @@ WINDOW_VSYNC_DISABLED =8192,
|
|||
int window_has_maximize();
|
||||
void window_transparent(int enabled);
|
||||
int window_has_transparent();
|
||||
void window_icon(const char *file_icon);
|
||||
int window_has_icon();
|
||||
double window_aspect();
|
||||
void window_aspect_lock(unsigned numer, unsigned denom);
|
||||
void window_aspect_unlock();
|
||||
|
|
|
@ -14056,8 +14056,8 @@ extern "C" {
|
|||
#define ENABLE_LINUX_CALLSTACKS 0 ///+
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_TESTS
|
||||
#define ENABLE_TESTS 0 // ifdef(debug, 1, 0) ///+
|
||||
#ifndef ENABLE_AUTOTESTS
|
||||
#define ENABLE_AUTOTESTS ifdef(debug, 1, 0) ///+
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_RETAIL
|
||||
|
@ -14148,15 +14148,6 @@ extern "C" {
|
|||
#define ifdef_release ifdef_false
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
|
||||
#define ifdef_64 ifdef_true
|
||||
#define ifdef_32 ifdef_false
|
||||
#else
|
||||
#define ifdef_64 ifdef_false
|
||||
#define ifdef_32 ifdef_true
|
||||
#endif
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#define ifdef_retail ifdef_true
|
||||
#else
|
||||
|
@ -14169,6 +14160,37 @@ extern "C" {
|
|||
#define ifdef_nocook ifdef_false
|
||||
#endif
|
||||
|
||||
#if defined NDEBUG && NDEBUG >= 3 // we use NDEBUG=[0,1,2,3] to signal the compiler optimization flags O0,O1,O2,O3
|
||||
#define ifdef_O3 ifdef_true
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_false
|
||||
#elif defined NDEBUG && NDEBUG >= 2
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_true
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_false
|
||||
#elif defined NDEBUG && NDEBUG >= 1
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_true
|
||||
#define ifdef_O0 ifdef_false
|
||||
#else
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_true
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
|
||||
#define ifdef_64 ifdef_true
|
||||
#define ifdef_32 ifdef_false
|
||||
#else
|
||||
#define ifdef_64 ifdef_false
|
||||
#define ifdef_32 ifdef_true
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// new C keywords
|
||||
|
||||
|
@ -14197,8 +14219,13 @@ extern "C" {
|
|||
//-----------------------------------------------------------------------------
|
||||
// new C macros
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#define ASSERT(expr, ...) (void)0
|
||||
#define ASSERT_ONCE(expr, ...) (void)0
|
||||
#else
|
||||
#define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
|
||||
#define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
|
||||
#endif
|
||||
#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_)
|
||||
|
||||
#define FILELINE __FILE__ ":" STRINGIZE(__LINE__)
|
||||
|
@ -14475,14 +14502,16 @@ static __thread unsigned array_n_;
|
|||
} while(0)
|
||||
|
||||
#define array_foreach(t,val_t,v) for each_array(t,val_t,v)
|
||||
#define each_array(t,val_t,v) \
|
||||
( int __it = 0, __end = array_count(t); __it < __end; ++__it ) \
|
||||
for( val_t v = __it[t], *on__ = &v; on__; on__ = 0 )
|
||||
#define each_array(a,val_t,v) \
|
||||
( array(val_t) a_ = (a); a_; a_ = 0 ) \
|
||||
for( int i_ = 0, e_ = array_count(a_); i_ < e_; ++i_ ) \
|
||||
for( val_t v = i_[a_], *v_ = (void*)(uintptr_t)&v; v_; v_ = 0 )
|
||||
|
||||
#define array_foreach_ptr(t,val_t,v) for each_array_ptr(t,val_t,v)
|
||||
#define each_array_ptr(t,val_t,v) \
|
||||
( int __it = 0, __end = array_count(t); __it < __end; ++__it ) \
|
||||
for( val_t *v = (val_t*)&__it[t]; v; v = 0 )
|
||||
#define each_array_ptr(a,val_t,v) \
|
||||
( array(val_t) a_ = (a); a_; a_ = 0 ) \
|
||||
for( int i_ = 0, e_ = array_count(a_); i_ < e_; ++i_ ) \
|
||||
for( val_t *v = (val_t*)&i_[a_]; v; v = 0 )
|
||||
|
||||
#define array_search(t, key, cmpfn) /* requires sorted array beforehand */ \
|
||||
bsearch(&key, t, array_count(t), sizeof(t[0]), cmpfn )
|
||||
|
@ -14498,13 +14527,13 @@ static __thread unsigned array_n_;
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define array_copy(t, src) do { /*todo: review old vrealloc call!*/ \
|
||||
#define array_copy(t, src) do { \
|
||||
array_free(t); \
|
||||
(t) = array_realloc_( (t), array_count(src)); \
|
||||
memcpy( (t), src, array_count(src) * sizeof(0[t])); \
|
||||
} while(0)
|
||||
|
||||
#define array_swapback_and_pop(t, i) do { /*may alter ordering*/ \
|
||||
#define array_erase_fast(t, i) do { /*may alter ordering*/ \
|
||||
memcpy( &(t)[i], &(t)[array_count(t) - 1], sizeof(0[t])); \
|
||||
array_pop(t); \
|
||||
} while(0)
|
||||
|
@ -15750,7 +15779,7 @@ API void kit_dump_state( FILE *fp );
|
|||
|
||||
// physical filesystem. files
|
||||
|
||||
API const char** file_list(const char *path, const char *masks); // **.png;*.c
|
||||
API array(char*) file_list( const char *pathmasks ); // folder/*.ico;**.png;*.c
|
||||
API bool file_write( const char *file, const void *ptr, int len );
|
||||
API bool file_append( const char *file, const void *ptr, int len );
|
||||
API char * file_read(const char *filename);
|
||||
|
@ -17729,18 +17758,13 @@ API void trap_on_debug(int signal); // helper util
|
|||
#define PANIC(...) PANIC(va(__VA_ARGS__), strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__, __LINE__) // die() ?
|
||||
API int (PANIC)(const char *error, const char *file, int line);
|
||||
|
||||
#if !ENABLE_RETAIL
|
||||
#define PRINTF(...) PRINTF(va(__VA_ARGS__), 1[#__VA_ARGS__] == '!' ? callstack(+48) : "", strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__, __LINE__, __FUNCTION__)
|
||||
API int (PRINTF)(const char *text, const char *stack, const char *file, int line, const char *function);
|
||||
|
||||
#define test(expr) test(strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__,__LINE__,#expr,!!(expr))
|
||||
API int (test)(const char *file, int line, const char *expr, bool result);
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define test(expr)
|
||||
#endif
|
||||
|
||||
#if ENABLE_TESTS
|
||||
#if ENABLE_AUTOTESTS
|
||||
#define AUTOTEST AUTORUN
|
||||
#else
|
||||
#define AUTOTEST static void concat(concat(concat(disabled_test_, __LINE__), _), __COUNTER__)()
|
||||
|
@ -17748,6 +17772,12 @@ API int (test)(const char *file, int line, const char *expr, bool result);
|
|||
|
||||
// AUTOTEST { test(1<2); }
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#undef PRINTF
|
||||
#define PRINTF(...) 0
|
||||
#undef test
|
||||
#define test(expr) 0
|
||||
#endif
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_ui.h"
|
||||
|
@ -17922,7 +17952,6 @@ API void window_loop(void (*function)(void* loopArg), void* loopArg ); // ru
|
|||
API void window_loop_exit(); // exit from main loop function (emscripten only)
|
||||
|
||||
API void window_title(const char *title);
|
||||
API void window_icon(const char *file_icon);
|
||||
API void window_color(unsigned color);
|
||||
API vec2 window_canvas();
|
||||
API void* window_handle();
|
||||
|
@ -17951,6 +17980,8 @@ API void window_maximize(int enabled);
|
|||
API int window_has_maximize();
|
||||
API void window_transparent(int enabled);
|
||||
API int window_has_transparent();
|
||||
API void window_icon(const char *file_icon);
|
||||
API int window_has_icon();
|
||||
|
||||
API double window_aspect();
|
||||
API void window_aspect_lock(unsigned numer, unsigned denom);
|
||||
|
@ -240032,8 +240063,8 @@ static void browser_reload_directory_content(struct browser *browser, const char
|
|||
|
||||
BROWSER_PRINTF("searching at %s\n", path);
|
||||
|
||||
const char **list = file_list(path, "*");
|
||||
for( int i = 0; list[i]; ++i ) {
|
||||
array(char*) list = file_list(path);
|
||||
for( int i = 0, end = array_count(list); i < end; ++i ) {
|
||||
|
||||
char *absolute = file_pathabs(ifndef(win32, list[i], va("%s/%s", path, list[i]))); // ../dir/./file.ext -> c:/prj/dir/file.ext
|
||||
BROWSER_PRINTF("%s->%s %d->", list[i], absolute, file_directory(absolute) );
|
||||
|
@ -240577,9 +240608,11 @@ char *json5__parse_value(json5 *obj, char *p, char **err_code) {
|
|||
*buf++ = *p++;
|
||||
}
|
||||
obj->type = is_dbl ? JSON5_REAL : JSON5_INTEGER;
|
||||
long long unsigned int llu;
|
||||
long long int lli;
|
||||
/**/ if( is_dbl ) sscanf( buffer, "%lf", &obj->real );
|
||||
else if( is_hex ) sscanf( buffer, "%llx", &obj->integer ); // SCNx64 -> inttypes.h
|
||||
else sscanf( buffer, "%lld", &obj->integer ); // SCNd64 -> inttypes.h
|
||||
else if( is_hex ) sscanf( buffer, "%llx", &llu ), obj->integer = llu; // SCNx64 -> inttypes.h
|
||||
else sscanf( buffer, "%lld", &lli ), obj->integer = lli; // SCNd64 -> inttypes.h
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
|
@ -240631,7 +240664,7 @@ void json5_write(FILE *fp, const json5 *o) {
|
|||
}
|
||||
/**/ if( o->type == JSON5_NULL ) fprintf(fp, "%s", "null");
|
||||
else if( o->type == JSON5_BOOL ) fprintf(fp, "%s", o->boolean ? "true" : "false");
|
||||
else if( o->type == JSON5_INTEGER ) fprintf(fp, "%lld", o->integer);
|
||||
else if( o->type == JSON5_INTEGER ) fprintf(fp, "%lld", (long long int)o->integer);
|
||||
else if( o->type == JSON5_REAL ) {
|
||||
/**/ if( isnan(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-nan" : "nan" );
|
||||
else if( isinf(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-inf" : "inf" );
|
||||
|
@ -252818,10 +252851,10 @@ bool zip_append_file_timeinfo(zip *z, const char *entryname, const char *comment
|
|||
// Read whole file and and use compress(). Simple but won't handle GB files well.
|
||||
unsigned dataSize = e->header.uncompressedSize, compSize = BOUNDS(e->header.uncompressedSize, compress_level);
|
||||
|
||||
comp = REALLOC(0, compSize);
|
||||
comp = REALLOC(comp, compSize);
|
||||
if(comp == NULL) goto cant_compress;
|
||||
|
||||
data = REALLOC(0, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
data = REALLOC(data, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
if(data == NULL) goto cant_compress; else memset((char*)data + dataSize, 0, 8);
|
||||
|
||||
fseek(in, 0, SEEK_SET); // rewind
|
||||
|
@ -252929,10 +252962,10 @@ bool zip_append_mem_timeinfo(zip *z, const char *entryname, const char *comment,
|
|||
// Read whole file and and use compress(). Simple but won't handle GB files well.
|
||||
unsigned dataSize = e->header.uncompressedSize, compSize = BOUNDS(e->header.uncompressedSize, compress_level);
|
||||
|
||||
comp = REALLOC(0, compSize);
|
||||
comp = REALLOC(comp, compSize);
|
||||
if(comp == NULL) goto cant_compress;
|
||||
|
||||
data = REALLOC(0, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
data = REALLOC(data, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
if(data == NULL) goto cant_compress; else memset((char*)data + dataSize, 0, 8);
|
||||
|
||||
size_t bytes = inlen;
|
||||
|
@ -252980,30 +253013,46 @@ common:;
|
|||
|
||||
// zip common
|
||||
|
||||
#if 1
|
||||
# define zip_lockfile(f) (void)(f)
|
||||
# define zip_unlockfile(f) (void)(f)
|
||||
#else
|
||||
# if (defined(__TINYC__) && defined(_WIN32))
|
||||
# define zip_lockfile(f) (void)(f)
|
||||
# define zip_unlockfile(f) (void)(f)
|
||||
# elif defined _MSC_VER
|
||||
# define zip_lockfile(f) _lock_file(f)
|
||||
# define zip_unlockfile(f) _unlock_file(f)
|
||||
# else
|
||||
# define zip_lockfile(f) flockfile(f)
|
||||
# define zip_unlockfile(f) funlockfile(f)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
zip* zip_open_handle(FILE *fp, const char *mode) {
|
||||
if( !fp ) return ERR(NULL, "cannot open file for %s mode", mode);
|
||||
zip zero = {0}, *z = (zip*)REALLOC(0, sizeof(zip));
|
||||
if( !z ) return fclose(fp), ERR(NULL, "out of mem"); else *z = zero;
|
||||
if( !z ) return ERR(NULL, "out of mem"); else *z = zero;
|
||||
if( mode[0] == 'w' ) {
|
||||
z->out = fp;
|
||||
zip_lockfile(z->out = fp);
|
||||
return z;
|
||||
}
|
||||
if( mode[0] == 'r' || mode[0] == 'a' ) {
|
||||
z->in = fp;
|
||||
zip_lockfile(z->in = fp);
|
||||
|
||||
unsigned long long seekcur = ftell(z->in);
|
||||
|
||||
JZEndRecord jzEndRecord = {0};
|
||||
if(jzReadEndRecord(fp, &jzEndRecord) != JZ_OK) {
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Couldn't read ZIP file end record.");
|
||||
return ERR(NULL, "Couldn't read ZIP file end record.");
|
||||
}
|
||||
|
||||
jzEndRecord.centralDirectoryOffset += seekcur;
|
||||
|
||||
if(jzReadCentralDirectory(fp, &jzEndRecord, zip__callback, z, (void*)(uintptr_t)seekcur ) != JZ_OK) {
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Couldn't read ZIP file central directory.");
|
||||
return ERR(NULL, "Couldn't read ZIP file central directory.");
|
||||
}
|
||||
if( mode[0] == 'a' ) {
|
||||
|
||||
|
@ -253020,13 +253069,13 @@ zip* zip_open_handle(FILE *fp, const char *mode) {
|
|||
fseek( fp, 0L, SEEK_END );
|
||||
}
|
||||
|
||||
z->out = z->in;
|
||||
z->in = NULL;
|
||||
z->out = fp;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Unknown open mode %s", mode);
|
||||
return ERR(NULL, "Unknown open mode %s", mode);
|
||||
}
|
||||
|
||||
zip* zip_open(const char *file, const char *mode /*r,w,a*/) {
|
||||
|
@ -253034,7 +253083,11 @@ zip* zip_open(const char *file, const char *mode /*r,w,a*/) {
|
|||
int exists = (stat(file, &buffer) == 0);
|
||||
if( mode[0] == 'a' && !exists ) mode = "wb";
|
||||
FILE *fp = fopen(file, mode[0] == 'w' ? "wb" : mode[0] == 'a' ? "a+b" : "rb");
|
||||
return zip_open_handle(fp, mode);
|
||||
if (!fp) return NULL;
|
||||
if (mode[0] == 'a') fseek(fp, 0L, SEEK_SET);
|
||||
zip *z = zip_open_handle(fp, mode);
|
||||
if (!z) return fclose(fp), NULL;
|
||||
return z;
|
||||
}
|
||||
|
||||
void zip_close(zip* z) {
|
||||
|
@ -253062,8 +253115,8 @@ void zip_close(zip* z) {
|
|||
// flush end record
|
||||
fwrite(&end, 1, sizeof(end), z->out);
|
||||
}
|
||||
if( z->out ) fclose(z->out);
|
||||
if( z->in ) fclose(z->in);
|
||||
if( z->out ) zip_unlockfile(z->out), fclose(z->out);
|
||||
if( z->in ) zip_unlockfile(z->in), fclose(z->in);
|
||||
// clean up
|
||||
for(unsigned i = 0; i < z->count; ++i ) {
|
||||
REALLOC(z->entries[i].filename, 0);
|
||||
|
@ -330573,7 +330626,7 @@ struct xml *xml_parse(char *s, int preserve_white, char **errorp)
|
|||
|
||||
static inline void array_find_and_remove(array(int) arr, int v) {
|
||||
for( int i = 0, end = array_count(arr); i < end; i++ )
|
||||
if( arr[i] == v ) { array_erase(arr, i); --end; break; }
|
||||
if( arr[i] == v ) { array_erase_fast(arr, i); --end; break; }
|
||||
}
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -330687,7 +330740,7 @@ static void RemoveIfNonNeighbor_(struct mesh *M, struct vertex *v, int id) {
|
|||
return;
|
||||
}
|
||||
// remove from neighbors
|
||||
array_erase(v->neighbor, i);
|
||||
array_erase_fast(v->neighbor, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -331954,6 +332007,8 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
|||
#define chdir ifdef(cl, _chdir, chdir)
|
||||
#if is(cl) || is(tcc)
|
||||
#define ftruncate _chsize_s
|
||||
#define flockfile ifdef(cl,_lock_file,(void))
|
||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
||||
#endif
|
||||
#else // gcc
|
||||
//#include <alloca.h> // mingw64 does not have it
|
||||
|
@ -332316,8 +332371,8 @@ int audio_init( int flags ) {
|
|||
ma_backend_wasapi, // Higest priority.
|
||||
ma_backend_dsound,
|
||||
ma_backend_winmm,
|
||||
ma_backend_pulseaudio,
|
||||
ma_backend_coreaudio,
|
||||
ma_backend_pulseaudio,
|
||||
ma_backend_alsa,
|
||||
ma_backend_oss,
|
||||
ma_backend_jack,
|
||||
|
@ -335215,7 +335270,7 @@ int zipscan_diff( zip* old, array(struct fs) now ) {
|
|||
uint64_t oldstamp = atoi64(zip_modt(old,found)+20); // format is "YYYY/MM/DD hh:mm:ss", then +20 chars later a hidden epoch timestamp in base10 can be found
|
||||
int64_t diffstamp = oldstamp < now[i].stamp ? now[i].stamp - oldstamp : oldstamp - now[i].stamp;
|
||||
if( oldsize != now[i].bytes || diffstamp > 1 ) { // @fixme: should use hash instead. hashof(tool) ^ hashof(args used) ^ hashof(rawsize) ^ hashof(rawdate)
|
||||
printf("%s:\t%u vs %u, %llu vs %llu\n", now[i].fname, (unsigned)oldsize,(unsigned)now[i].bytes, oldstamp,now[i].stamp);
|
||||
printf("%s:\t%u vs %u, %llu vs %llu\n", now[i].fname, (unsigned)oldsize,(unsigned)now[i].bytes, (long long unsigned)oldstamp, (long long unsigned)now[i].stamp);
|
||||
array_push(changed, STRDUP(now[i].fname));
|
||||
array_push(uncooked, STRDUP(now[i].fname));
|
||||
}
|
||||
|
@ -335511,8 +335566,8 @@ bool cook_start( const char *cook_ini, const char *masks, int flags ) {
|
|||
// scan disk: all subfolders in ART (comma-separated)
|
||||
static array(char *) list = 0; // @leak
|
||||
for each_substring(ART, ",", art_folder) {
|
||||
const char **glob = file_list(art_folder, "**");
|
||||
for( unsigned i = 0; glob[i]; ++i ) {
|
||||
array(char *) glob = file_list(va("%s**",art_folder)); // art_folder ends with '/'
|
||||
for( unsigned i = 0, end = array_count(glob); i < end; ++i ) {
|
||||
const char *fname = glob[i];
|
||||
if( !strmatchi(fname, masks)) continue;
|
||||
|
||||
|
@ -335532,8 +335587,13 @@ bool cook_start( const char *cook_ini, const char *masks, int flags ) {
|
|||
if( !memcmp(header, "\x64\x86", 2) ) continue;
|
||||
if( !memcmp(header, "\x00\x00", 2) ) continue;
|
||||
}
|
||||
// exclude vc/gcc files
|
||||
if( strend(fname, ".a") || strend(fname, ".pdb") || strend(fname, ".lib") || strend(fname, ".ilk") || strend(fname, ".exp") ) {
|
||||
|
||||
char *dot = strrchr(fname, '.');
|
||||
if( dot ) {
|
||||
char extdot[32];
|
||||
snprintf(extdot, 32, "%s.", dot); // .png -> .png.
|
||||
// exclude vc/gcc/clang files
|
||||
if( strstr(fname, ".a.o.pdb.lib.ilk.exp.dSYM.") ) // must end with dot
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -335594,8 +335654,7 @@ void cook_stop() {
|
|||
if(jobs[i].self) thread_join(jobs[i].self);
|
||||
}
|
||||
// remove all temporary outfiles
|
||||
const char **temps = file_list("./", "temp_*");
|
||||
for( int i = 0; temps[i]; ++i ) unlink(temps[i]);
|
||||
for each_array(file_list("temp_*"), char*, tempfile) unlink(tempfile);
|
||||
}
|
||||
|
||||
int cook_progress() {
|
||||
|
@ -336044,7 +336103,8 @@ bool file_append(const char *name, const void *ptr, int len) {
|
|||
}
|
||||
return ok;
|
||||
}
|
||||
static bool file_stat(const char *fname, struct stat *st) {
|
||||
static // not exposed
|
||||
bool file_stat(const char *fname, struct stat *st) {
|
||||
// remove ending slashes. win32+tcc does not like them.
|
||||
int l = strlen(fname), m = l;
|
||||
while( l && (fname[l-1] == '/' || fname[l-1] == '\\') ) --l;
|
||||
|
@ -336165,7 +336225,7 @@ char *ext = strrchr(base, '.'); //if (ext) ext[0] = '\0'; // remove all extensio
|
|||
}
|
||||
return va("%s", buffer);
|
||||
}
|
||||
const char** file_list(const char *cwds, const char *masks) {
|
||||
array(char*) file_list(const char *pathmasks) {
|
||||
static __thread array(char*) list = 0; // @fixme: should we add 16 slots in here similar to what we do in va() ?
|
||||
|
||||
for( int i = 0; i < array_count(list); ++i ) {
|
||||
|
@ -336173,7 +336233,16 @@ const char** file_list(const char *cwds, const char *masks) {
|
|||
}
|
||||
array_resize(list, 0);//array_free(list);
|
||||
|
||||
for each_substring(cwds,";",cwd) {
|
||||
for each_substring(pathmasks,";",pathmask) {
|
||||
char *cwd = 0, *masks = 0;
|
||||
char *slash = strrchr(pathmask, '/');
|
||||
if( !slash ) cwd = "./", masks = pathmask;
|
||||
else {
|
||||
masks = va("%s", slash+1);
|
||||
cwd = pathmask, slash[1] = '\0';
|
||||
}
|
||||
if( !masks[0] ) masks = "*";
|
||||
|
||||
ASSERT(strend(cwd, "/"), "Error: dirs like '%s' must end with slash", cwd);
|
||||
|
||||
dir *d = dir_open(cwd, strstr(masks,"**") ? "r" : "");
|
||||
|
@ -336201,8 +336270,7 @@ const char** file_list(const char *cwds, const char *masks) {
|
|||
}
|
||||
}
|
||||
|
||||
array_push(list, 0); // terminator
|
||||
return (const char**)list;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool file_move(const char *src, const char *dst) {
|
||||
|
@ -336549,15 +336617,8 @@ void vfs_reload() {
|
|||
#else
|
||||
// mount fused executables
|
||||
vfs_mount(va("%s%s%s", app_path(), app_name(), ifdef(win32, ".exe", "")));
|
||||
/* // old way
|
||||
for( int i = 0; i < JOBS_MAX; ++i) {
|
||||
if( vfs_mount(va(".art[%02x].zip", i)) ) continue;
|
||||
if( vfs_mount(va("%s[%02x].zip", app, i)) ) continue;
|
||||
if( vfs_mount(va("%s%02x.zip", app, i)) ) continue;
|
||||
// if( vfs_mount(va("%s.%02x", app, i)) ) continue;
|
||||
} */
|
||||
// faster way
|
||||
for( const char **file = file_list("./","*.zip"); *file; ++file) vfs_mount(*file);
|
||||
// mount all zipfiles
|
||||
for each_array( file_list("*.zip"), char*, file ) vfs_mount(file);
|
||||
#endif
|
||||
|
||||
// vfs_resolve() will use these art_folder locations as hints when cook-on-demand is in progress.
|
||||
|
@ -336570,7 +336631,7 @@ void vfs_reload() {
|
|||
|
||||
|
||||
|
||||
#define ARK1 'ArK\x1'
|
||||
#define ARK1 0x41724B31 // 'ArK1' in le, 0x314B7241 41 72 4B 31 otherwise
|
||||
#define ARK1_PADDING (512 - 40) // 472
|
||||
#define ARK_PRINTF(f,...) 0 // printf(f,__VA_ARGS__)
|
||||
#define ARK_SWAP32(x) (x)
|
||||
|
@ -336662,9 +336723,9 @@ const char** vfs_list(const char *masks) {
|
|||
|
||||
for each_substring(masks,";",it) {
|
||||
if( COOK_ON_DEMAND ) // edge case: any game using only vfs api + cook-on-demand flag will never find any file
|
||||
for(const char **items = file_list("./", it); *items; items++) {
|
||||
for each_array(file_list(it), char*, item) {
|
||||
// insert copy
|
||||
char *copy = STRDUP(*items);
|
||||
char *copy = STRDUP(item);
|
||||
array_push(list, copy);
|
||||
}
|
||||
|
||||
|
@ -336770,8 +336831,8 @@ if( found && *found == 0 ) {
|
|||
folder = file_path(pathfile);
|
||||
// ease folders reading by shortening them: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav
|
||||
// or C:/prj/v4k/engine/art/fonts/B612-BoldItalic.ttf -> fonts/B612-BoldItalic.ttf
|
||||
static array(char*) art_paths = 0;
|
||||
do_once for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem));
|
||||
static __thread array(char*) art_paths = 0;
|
||||
if(!art_paths) for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem));
|
||||
char* pretty_folder = "";
|
||||
if( folder ) for( int i = 0; i < array_count(art_paths); ++i ) {
|
||||
if( strbeg(folder, art_paths[i]) ) { pretty_folder = folder + strlen(art_paths[i]); break; }
|
||||
|
@ -336822,7 +336883,7 @@ if( found && *found == 0 ) {
|
|||
// this block saves some boot time (editor --cook-on-demand: boot 1.50s -> 0.90s)
|
||||
#if 1 // EXPERIMENTAL_DONT_COOK_NON_EXISTING_ASSETS
|
||||
static set(char*) disk = 0;
|
||||
if(!disk) { set_init_str(disk); for each_substring(ART,",",art_folder) for( const char **list = file_list(art_folder,"**"); *list; ++list) set_insert(disk, STRDUP(*list)); }
|
||||
if(!disk) { set_init_str(disk); for each_substring(ART,",",art_folder) for each_array(file_list(va("%s**", art_folder)), char*, item) set_insert(disk, STRDUP(item)); } // art_folder ends with '/'
|
||||
int found = !!set_find(disk, (char*)pathfile);
|
||||
if( found )
|
||||
#endif
|
||||
|
@ -336935,23 +336996,28 @@ const char *vfs_extract(const char *pathfile) { // extract a vfs file into the l
|
|||
// -----------------------------------------------------------------------------
|
||||
// cache
|
||||
|
||||
static thread_mutex_t cache_mutex; AUTORUN{ thread_mutex_init(&cache_mutex); }
|
||||
|
||||
void* cache_lookup(const char *pathfile, int *size) { // find key->value
|
||||
if( !MAX_CACHED_FILES ) return 0;
|
||||
void* data = 0;
|
||||
thread_mutex_lock(&cache_mutex);
|
||||
for(archive_dir *dir = dir_cache; dir; dir = dir->next) {
|
||||
if( !strcmp(dir->path, pathfile) ) {
|
||||
if(size) *size = dir->size;
|
||||
return dir->data;
|
||||
data = dir->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
thread_mutex_unlock(&cache_mutex);
|
||||
return data;
|
||||
}
|
||||
void* cache_insert(const char *pathfile, void *ptr, int size) { // append key/value; return LRU or NULL
|
||||
if( !MAX_CACHED_FILES ) return 0;
|
||||
if( !ptr || !size ) return 0;
|
||||
|
||||
// keep cached files within limits
|
||||
static thread_mutex_t mutex, *init = 0; if(!init) thread_mutex_init(init = &mutex);
|
||||
thread_mutex_lock(&mutex);
|
||||
thread_mutex_lock(&cache_mutex);
|
||||
|
||||
// append to cache
|
||||
archive_dir zero = {0}, *old = dir_cache;
|
||||
|
@ -336981,7 +337047,7 @@ void* cache_insert(const char *pathfile, void *ptr, int size) { // append key/va
|
|||
}
|
||||
}
|
||||
|
||||
thread_mutex_unlock(&mutex);
|
||||
thread_mutex_unlock(&cache_mutex);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
@ -341907,7 +341973,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
network_put(NETWORK_RANK, -1); /* unassigned until we connect successfully */
|
||||
int64_t socket = client_join(ip, port);
|
||||
if( socket >= 0 ) {
|
||||
PRINTF("Client connected, id %lld\n", socket);
|
||||
PRINTF("Client connected, id %d\n", (int)socket);
|
||||
network_put(NETWORK_LIVE, 1);
|
||||
network_put(NETWORK_RANK, socket);
|
||||
} else {
|
||||
|
@ -341924,7 +341990,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
network_put(NETWORK_RANK, -1); /* unassigned until we connect successfully */
|
||||
int64_t socket = client_join(ip, port);
|
||||
if( socket > 0 ) {
|
||||
PRINTF("Client connected, id %lld\n", socket);
|
||||
PRINTF("Client connected, id %d\n", (int)socket);
|
||||
network_put(NETWORK_LIVE, 1);
|
||||
network_put(NETWORK_RANK, socket);
|
||||
} else {
|
||||
|
@ -341935,7 +342001,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
}
|
||||
}
|
||||
|
||||
PRINTF("Network rank:%lld ip:%s port:%lld\n", network_get(NETWORK_RANK), ip, network_get(NETWORK_PORT));
|
||||
PRINTF("Network rank:%u ip:%s port:%d\n", (unsigned)network_get(NETWORK_RANK), ip, (int)network_get(NETWORK_PORT));
|
||||
}
|
||||
|
||||
int64_t network_put(uint64_t key, int64_t value) {
|
||||
|
@ -342068,8 +342134,8 @@ char** server_poll(unsigned timeout_ms) {
|
|||
*(uint32_t*)&init_msg[0] = MSG_INIT;
|
||||
*(int64_t*)&init_msg[4] = client_id;
|
||||
server_send_bin(client_id, init_msg, 12);
|
||||
PRINTF("Client rank %lld for peer ::%s:%u\n", client_id, ip, event.peer->address.port);
|
||||
msg = va( "%d new client rank:%lld from ::%s:%u", 0, client_id, ip, event.peer->address.port );
|
||||
PRINTF("Client rank %u for peer ::%s:%u\n", (unsigned)client_id, ip, event.peer->address.port);
|
||||
msg = va( "%d new client rank:%u from ::%s:%u", 0, (unsigned)client_id, ip, event.peer->address.port );
|
||||
event.peer->data = (void*)client_id;
|
||||
break;
|
||||
|
||||
|
@ -342125,7 +342191,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
msg = va("%d %s", 0, va("%s", ptr));
|
||||
} break;
|
||||
default:
|
||||
msg = va("%d unk msg len:%u from rank:%lld ::%s:%u", -1, sz, (uint64_t)event.peer->data, ip, event.peer->address.port); /* @TODO: hexdump? */
|
||||
msg = va("%d unk msg len:%u from rank:%u ::%s:%u", -1, sz, (unsigned)(uintptr_t)event.peer->data, ip, event.peer->address.port); /* @TODO: hexdump? */
|
||||
break;
|
||||
}
|
||||
/* Clean up the packet now that we're done using it. */
|
||||
|
@ -342133,7 +342199,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
} break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
msg = va( "%d disconnect rank:%lld", 0, (uint64_t)event.peer->data);
|
||||
msg = va( "%d disconnect rank:%u", 0, (unsigned)(uintptr_t)event.peer->data);
|
||||
/* Reset the peer's client information. */
|
||||
FREE(event.peer->data);
|
||||
event.peer->data = NULL;
|
||||
|
@ -342142,7 +342208,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||
msg = va( "%d timeout rank:%lld", 0, (uint64_t)event.peer->data);
|
||||
msg = va( "%d timeout rank:%u", 0, (unsigned)(uintptr_t)event.peer->data);
|
||||
FREE(event.peer->data);
|
||||
event.peer->data = NULL;
|
||||
server_drop_client_peer(event.peer);
|
||||
|
@ -343850,10 +343916,10 @@ AUTOTEST {
|
|||
|
||||
// iterate reflected struct
|
||||
for each_member("MyVec4", R) {
|
||||
printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||
}
|
||||
|
||||
reflected_printf_all();
|
||||
// reflected_printf_all();
|
||||
}
|
||||
#line 0
|
||||
|
||||
|
@ -343964,9 +344030,10 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char
|
|||
|
||||
const char *glsl_version = ifdef(ems, "300 es", "150");
|
||||
|
||||
vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : "");
|
||||
fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : "");
|
||||
if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : "");
|
||||
if(gs)
|
||||
gs = gs && gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : "");
|
||||
vs = vs && vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : "");
|
||||
fs = fs && fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : "");
|
||||
|
||||
#if is(ems)
|
||||
{
|
||||
|
@ -350498,9 +350565,10 @@ const char *app_path() { // @fixme: should return absolute path always. see tcc
|
|||
strcat(buffer, "..\\..\\");
|
||||
}
|
||||
#else // #elif is(linux)
|
||||
char path[21] = {0};
|
||||
char path[32] = {0};
|
||||
sprintf(path, "/proc/%d/exe", getpid());
|
||||
readlink(path, buffer, sizeof(buffer));
|
||||
if(strrchr(buffer,'/')) 1[strrchr(buffer,'/')] = '\0';
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
@ -351203,15 +351271,15 @@ int (PRINTF)(const char *text, const char *stack, const char *file, int line, co
|
|||
char *location = va("|%s|%s:%d", /*errno?strerror(errno):*/function, file, line);
|
||||
int cols = tty_cols() + 1 - (int)strlen(location);
|
||||
|
||||
static thread_mutex_t lock, *init = 0; if(!init) thread_mutex_init(init = &lock);
|
||||
thread_mutex_lock( &lock );
|
||||
flockfile(stdout);
|
||||
|
||||
tty_color(color);
|
||||
printf("\r%*.s%s", cols, "", location);
|
||||
printf("\r%07.3fs|%s%s", secs, text, stack);
|
||||
tty_color(0);
|
||||
|
||||
thread_mutex_unlock( &lock );
|
||||
funlockfile(stdout);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -351599,20 +351667,20 @@ static void nk_config_custom_fonts() {
|
|||
nk_glfw3_font_stash_begin(&nk_glfw, &atlas); // nk_sdl_font_stash_begin(&atlas);
|
||||
|
||||
// Default font(#1)...
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_REGULAR); data; data = 0 ) {
|
||||
int datalen = 0;
|
||||
for( char *data = vfs_load(UI_FONT_REGULAR, &datalen); data; data = 0 ) {
|
||||
float font_size = UI_FONT_REGULAR_SIZE;
|
||||
struct nk_font_config cfg = nk_font_config(font_size);
|
||||
cfg.oversample_v = 2;
|
||||
cfg.pixel_snap = 0;
|
||||
// win32: struct nk_font *arial = nk_font_atlas_add_from_file(atlas, va("%s/fonts/arial.ttf",getenv("windir")), font_size, &cfg); font = arial ? arial : font;
|
||||
// struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "nuklear/extra_font/DroidSans.ttf", font_size, &cfg); font = droid ? droid : font;
|
||||
struct nk_font *regular = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_REGULAR), font_size, &cfg); font = regular ? regular : font;
|
||||
struct nk_font *regular = nk_font_atlas_add_from_memory(atlas, data, datalen, font_size, &cfg); font = regular ? regular : font;
|
||||
}
|
||||
|
||||
// ...with icons embedded on it.
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_ICONS); data; data = 0 ) {
|
||||
for( char *data = vfs_load(UI_FONT_ICONS, &datalen); data; data = 0 ) {
|
||||
static const nk_rune icon_range[] = {UI_ICON_MIN, UI_ICON_MED /*MAX*/, 0};
|
||||
|
||||
struct nk_font_config cfg = nk_font_config(UI_ICON_FONTSIZE);
|
||||
|
@ -351628,12 +351696,12 @@ static void nk_config_custom_fonts() {
|
|||
cfg.oversample_v = 1;
|
||||
cfg.pixel_snap = 1;
|
||||
|
||||
struct nk_font *icons = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_ICONS), UI_ICON_FONTSIZE, &cfg);
|
||||
struct nk_font *icons = nk_font_atlas_add_from_memory(atlas, data, datalen, UI_ICON_FONTSIZE, &cfg);
|
||||
}
|
||||
|
||||
// Monospaced font. Used in terminals or consoles.
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_TERMINAL); data; data = 0 ) {
|
||||
for( char *data = vfs_load(UI_FONT_TERMINAL, &datalen); data; data = 0 ) {
|
||||
const float font_size = UI_FONT_REGULAR_SIZE;
|
||||
static const nk_rune icon_range[] = {32, 127, 0};
|
||||
|
||||
|
@ -351645,13 +351713,13 @@ static void nk_config_custom_fonts() {
|
|||
cfg.pixel_snap = 1;
|
||||
|
||||
// struct nk_font *proggy = nk_font_atlas_add_default(atlas, font_size, &cfg);
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_TERMINAL), font_size, &cfg);
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, datalen, font_size, &cfg);
|
||||
}
|
||||
|
||||
// Extra optional fonts from here...
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_HEADING); data; data = 0 ) {
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_HEADING), UI_FONT_HEADING_SIZE, 0); // font = bold ? bold : font;
|
||||
for( char *data = vfs_load(UI_FONT_HEADING, &datalen); data; data = 0 ) {
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, datalen, UI_FONT_HEADING_SIZE, 0); // font = bold ? bold : font;
|
||||
}
|
||||
|
||||
nk_glfw3_font_stash_end(&nk_glfw); // nk_sdl_font_stash_end();
|
||||
|
@ -355278,11 +355346,16 @@ void window_color(unsigned color) {
|
|||
unsigned a = (color >> 24) & 255;
|
||||
winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
||||
}
|
||||
static int has_icon;
|
||||
int window_has_icon() {
|
||||
return has_icon;
|
||||
}
|
||||
void window_icon(const char *file_icon) {
|
||||
unsigned len = file_size(file_icon); len = len ? len : vfs_size(file_icon);
|
||||
if( len ) {
|
||||
void *data = file_read(file_icon); data = data ? data : vfs_read(file_icon);
|
||||
if( data ) {
|
||||
int len = 0;
|
||||
void *data = vfs_load(file_icon, &len);
|
||||
if( !data ) data = file_read(file_icon), len = file_size(file_icon);
|
||||
|
||||
if( data && len ) {
|
||||
image_t img = image_from_mem(data, len, IMAGE_RGBA);
|
||||
if( img.w && img.h && img.pixels ) {
|
||||
GLFWimage images[1];
|
||||
|
@ -355290,11 +355363,11 @@ void window_icon(const char *file_icon) {
|
|||
images[0].height = img.h;
|
||||
images[0].pixels = img.pixels;
|
||||
glfwSetWindowIcon(window, 1, images);
|
||||
has_icon = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if is(win32)
|
||||
#if 0 // is(win32)
|
||||
HANDLE hIcon = LoadImageA(0, file_icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||
if( hIcon ) {
|
||||
HWND hWnd = glfwGetWin32Window(window);
|
||||
|
@ -355302,6 +355375,7 @@ void window_icon(const char *file_icon) {
|
|||
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
has_icon = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -355667,7 +355741,7 @@ vec3 get_voxel_for_boid(float perception_radius, const boid_t *b) { // quantize
|
|||
|
||||
static
|
||||
void check_voxel_for_boids(float perception_radius, float blindspot_angledeg_compare_value, array(boid_t*) voxel_cached, array(nearby_boid_t) *result, const vec3 voxelPos, const boid_t *b) {
|
||||
for each_array_ptr(voxel_cached, const boid_t*, test) {
|
||||
for each_array_ptr(voxel_cached, boid_t*, test) {
|
||||
vec3 p1 = b->position;
|
||||
vec3 p2 = (*test)->position;
|
||||
vec3 vec = sub3(p2, p1);
|
||||
|
@ -355680,7 +355754,7 @@ void check_voxel_for_boids(float perception_radius, float blindspot_angledeg_com
|
|||
compare_value = dot3(neg3(b->velocity), vec) / (l1 * l2);
|
||||
}
|
||||
|
||||
if ((&b) != test && distance <= perception_radius && (blindspot_angledeg_compare_value > compare_value || len3(b->velocity) == 0)) {
|
||||
if (b != (*test) && distance <= perception_radius && (blindspot_angledeg_compare_value > compare_value || len3(b->velocity) == 0)) {
|
||||
nearby_boid_t nb;
|
||||
nb.boid = (boid_t*)*test;
|
||||
nb.distance = distance;
|
||||
|
@ -356243,7 +356317,7 @@ int pathfind_astar(int width, int height, const unsigned* map, vec2i src, vec2i
|
|||
// [ ] CompareKeys(keyVar1, operator < <= > >= == !=, keyVar2)
|
||||
// [ ] SetTags(names=blank,cooldownTime=inf,bIsCooldownAdditive=false)
|
||||
// [ ] HasTags(names=blank,bAllRequired=true)
|
||||
// [ ] PushToStack(keyVar,itemObj): creates a new stack if one doesn’t exist, and stores it in the passed variable name, and then pushes ‘item’ object onto it.
|
||||
// [ ] PushToStack(keyVar,itemObj): creates a new stack if one doesn't exist, and stores it in the passed variable name, and then pushes 'item' object onto it.
|
||||
// [ ] PopFromStack(keyVar,itemVar): pop pops an item off the stack, and stores it in the itemVar variable, failing if the stack is already empty.
|
||||
// [ ] IsEmptyStack(keyVar): checks if the stack passed is empty and returns success if it is, and failure if its not.
|
||||
// [ ] Communication Node: This is a type of action node that allows an AI agent to communicate with other agents or entities in the game world. The node takes an input specifying the message to be communicated and the recipient(s) of the message (wildmask,l/p/f/g prefixes). The node then sends the message to the designated recipient(s) and returns success when the communication is completed. This node can be useful for implementing behaviors that require the AI agent to coordinate with other agents or to convey information to the player. It could use a radius argument to specify the maximum allowed distance for the recipients.
|
||||
|
@ -356911,48 +356985,41 @@ int main() {
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void v4k_pre_init() {
|
||||
const char *appname = app_name();
|
||||
const char *appdir = app_path();
|
||||
window_icon(va("%s/%s.png", appdir, appname));
|
||||
ifdef(win32,window_icon(va("%s/%s.ico", appdir, appname)));
|
||||
window_icon(va("%s%s.png", app_path(), app_name()));
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
int i;
|
||||
#pragma omp parallel for
|
||||
for( i = 0; i <= 3; ++i) {
|
||||
for( i = 0; i <= 6; ++i) {
|
||||
/**/ if( i == 0 ) ddraw_init();// init this on thread#0 since it will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
else if( i == 1 ) sprite_init();
|
||||
else if( i == 2 ) profiler_init();
|
||||
else if( i == 3 ) storage_mount("save/"), storage_read(), touch_init(); // for ems
|
||||
else if( i == 4 ) audio_init(0);
|
||||
else if( i == 5 ) script_init(), kit_init(), midi_init();
|
||||
else if( i == 6 ) network_init();
|
||||
}
|
||||
|
||||
// window_swap();
|
||||
}
|
||||
static void v4k_post_init(float refresh_rate) {
|
||||
int i;
|
||||
|
||||
// cook cleanup
|
||||
cook_stop();
|
||||
|
||||
vfs_reload();
|
||||
|
||||
// init subsystems that depend on cooked assets now. ui_init() is special case and needs to be safely in single thread
|
||||
ui_init();
|
||||
// init subsystems that depend on cooked assets now
|
||||
|
||||
// init more subsystems; beware of VFS mounting, as some of these may need cooked assets at this point
|
||||
int i;
|
||||
#pragma omp parallel for
|
||||
for( i = 0; i <= 3; ++i) {
|
||||
/**/ if( i == 0 ) scene_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
else if( i == 1 ) audio_init(0); // initialize audio after cooking // reasoning for this: do not launch audio threads while cooks are in progress, so there is more cpu for cooking actually
|
||||
else if( i == 2 ) script_init(), kit_init(), midi_init();
|
||||
else if( i == 3 ) input_init(), network_init();
|
||||
for( i = 0; i <= 2; ++i ) {
|
||||
if(i == 0) ui_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
if(i == 0) scene_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
if(i == 1) input_init();
|
||||
if(i == 2) window_icon(va("%s.png", app_name()));
|
||||
}
|
||||
|
||||
const char *appname = app_name();
|
||||
window_icon(va("%s.png", appname));
|
||||
window_icon(va("%s.ico", appname));
|
||||
|
||||
// display window
|
||||
glfwShowWindow(window);
|
||||
glfwGetFramebufferSize(window, &w, &h); //glfwGetWindowSize(window, &w, &h);
|
||||
|
|
|
@ -594,10 +594,10 @@ bool zip_append_file_timeinfo(zip *z, const char *entryname, const char *comment
|
|||
// Read whole file and and use compress(). Simple but won't handle GB files well.
|
||||
unsigned dataSize = e->header.uncompressedSize, compSize = BOUNDS(e->header.uncompressedSize, compress_level);
|
||||
|
||||
comp = REALLOC(0, compSize);
|
||||
comp = REALLOC(comp, compSize);
|
||||
if(comp == NULL) goto cant_compress;
|
||||
|
||||
data = REALLOC(0, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
data = REALLOC(data, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
if(data == NULL) goto cant_compress; else memset((char*)data + dataSize, 0, 8);
|
||||
|
||||
fseek(in, 0, SEEK_SET); // rewind
|
||||
|
@ -705,10 +705,10 @@ bool zip_append_mem_timeinfo(zip *z, const char *entryname, const char *comment,
|
|||
// Read whole file and and use compress(). Simple but won't handle GB files well.
|
||||
unsigned dataSize = e->header.uncompressedSize, compSize = BOUNDS(e->header.uncompressedSize, compress_level);
|
||||
|
||||
comp = REALLOC(0, compSize);
|
||||
comp = REALLOC(comp, compSize);
|
||||
if(comp == NULL) goto cant_compress;
|
||||
|
||||
data = REALLOC(0, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
data = REALLOC(data, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
if(data == NULL) goto cant_compress; else memset((char*)data + dataSize, 0, 8);
|
||||
|
||||
size_t bytes = inlen;
|
||||
|
@ -756,30 +756,46 @@ common:;
|
|||
|
||||
// zip common
|
||||
|
||||
#if 1
|
||||
# define zip_lockfile(f) (void)(f)
|
||||
# define zip_unlockfile(f) (void)(f)
|
||||
#else
|
||||
# if (defined(__TINYC__) && defined(_WIN32))
|
||||
# define zip_lockfile(f) (void)(f)
|
||||
# define zip_unlockfile(f) (void)(f)
|
||||
# elif defined _MSC_VER
|
||||
# define zip_lockfile(f) _lock_file(f)
|
||||
# define zip_unlockfile(f) _unlock_file(f)
|
||||
# else
|
||||
# define zip_lockfile(f) flockfile(f)
|
||||
# define zip_unlockfile(f) funlockfile(f)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
zip* zip_open_handle(FILE *fp, const char *mode) {
|
||||
if( !fp ) return ERR(NULL, "cannot open file for %s mode", mode);
|
||||
zip zero = {0}, *z = (zip*)REALLOC(0, sizeof(zip));
|
||||
if( !z ) return fclose(fp), ERR(NULL, "out of mem"); else *z = zero;
|
||||
if( !z ) return ERR(NULL, "out of mem"); else *z = zero;
|
||||
if( mode[0] == 'w' ) {
|
||||
z->out = fp;
|
||||
zip_lockfile(z->out = fp);
|
||||
return z;
|
||||
}
|
||||
if( mode[0] == 'r' || mode[0] == 'a' ) {
|
||||
z->in = fp;
|
||||
zip_lockfile(z->in = fp);
|
||||
|
||||
unsigned long long seekcur = ftell(z->in);
|
||||
|
||||
JZEndRecord jzEndRecord = {0};
|
||||
if(jzReadEndRecord(fp, &jzEndRecord) != JZ_OK) {
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Couldn't read ZIP file end record.");
|
||||
return ERR(NULL, "Couldn't read ZIP file end record.");
|
||||
}
|
||||
|
||||
jzEndRecord.centralDirectoryOffset += seekcur;
|
||||
|
||||
if(jzReadCentralDirectory(fp, &jzEndRecord, zip__callback, z, (void*)(uintptr_t)seekcur ) != JZ_OK) {
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Couldn't read ZIP file central directory.");
|
||||
return ERR(NULL, "Couldn't read ZIP file central directory.");
|
||||
}
|
||||
if( mode[0] == 'a' ) {
|
||||
|
||||
|
@ -796,13 +812,13 @@ zip* zip_open_handle(FILE *fp, const char *mode) {
|
|||
fseek( fp, 0L, SEEK_END );
|
||||
}
|
||||
|
||||
z->out = z->in;
|
||||
z->in = NULL;
|
||||
z->out = fp;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Unknown open mode %s", mode);
|
||||
return ERR(NULL, "Unknown open mode %s", mode);
|
||||
}
|
||||
|
||||
zip* zip_open(const char *file, const char *mode /*r,w,a*/) {
|
||||
|
@ -810,7 +826,11 @@ zip* zip_open(const char *file, const char *mode /*r,w,a*/) {
|
|||
int exists = (stat(file, &buffer) == 0);
|
||||
if( mode[0] == 'a' && !exists ) mode = "wb";
|
||||
FILE *fp = fopen(file, mode[0] == 'w' ? "wb" : mode[0] == 'a' ? "a+b" : "rb");
|
||||
return zip_open_handle(fp, mode);
|
||||
if (!fp) return NULL;
|
||||
if (mode[0] == 'a') fseek(fp, 0L, SEEK_SET);
|
||||
zip *z = zip_open_handle(fp, mode);
|
||||
if (!z) return fclose(fp), NULL;
|
||||
return z;
|
||||
}
|
||||
|
||||
void zip_close(zip* z) {
|
||||
|
@ -838,8 +858,8 @@ void zip_close(zip* z) {
|
|||
// flush end record
|
||||
fwrite(&end, 1, sizeof(end), z->out);
|
||||
}
|
||||
if( z->out ) fclose(z->out);
|
||||
if( z->in ) fclose(z->in);
|
||||
if( z->out ) zip_unlockfile(z->out), fclose(z->out);
|
||||
if( z->in ) zip_unlockfile(z->in), fclose(z->in);
|
||||
// clean up
|
||||
for(unsigned i = 0; i < z->count; ++i ) {
|
||||
REALLOC(z->entries[i].filename, 0);
|
||||
|
|
|
@ -251,9 +251,11 @@ char *json5__parse_value(json5 *obj, char *p, char **err_code) {
|
|||
*buf++ = *p++;
|
||||
}
|
||||
obj->type = is_dbl ? JSON5_REAL : JSON5_INTEGER;
|
||||
long long unsigned int llu;
|
||||
long long int lli;
|
||||
/**/ if( is_dbl ) sscanf( buffer, "%lf", &obj->real );
|
||||
else if( is_hex ) sscanf( buffer, "%llx", &obj->integer ); // SCNx64 -> inttypes.h
|
||||
else sscanf( buffer, "%lld", &obj->integer ); // SCNd64 -> inttypes.h
|
||||
else if( is_hex ) sscanf( buffer, "%llx", &llu ), obj->integer = llu; // SCNx64 -> inttypes.h
|
||||
else sscanf( buffer, "%lld", &lli ), obj->integer = lli; // SCNd64 -> inttypes.h
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
|
@ -305,7 +307,7 @@ void json5_write(FILE *fp, const json5 *o) {
|
|||
}
|
||||
/**/ if( o->type == JSON5_NULL ) fprintf(fp, "%s", "null");
|
||||
else if( o->type == JSON5_BOOL ) fprintf(fp, "%s", o->boolean ? "true" : "false");
|
||||
else if( o->type == JSON5_INTEGER ) fprintf(fp, "%lld", o->integer);
|
||||
else if( o->type == JSON5_INTEGER ) fprintf(fp, "%lld", (long long int)o->integer);
|
||||
else if( o->type == JSON5_REAL ) {
|
||||
/**/ if( isnan(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-nan" : "nan" );
|
||||
else if( isinf(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-inf" : "inf" );
|
||||
|
|
|
@ -117,8 +117,8 @@ static void browser_reload_directory_content(struct browser *browser, const char
|
|||
|
||||
BROWSER_PRINTF("searching at %s\n", path);
|
||||
|
||||
const char **list = file_list(path, "*");
|
||||
for( int i = 0; list[i]; ++i ) {
|
||||
array(char*) list = file_list(path);
|
||||
for( int i = 0, end = array_count(list); i < end; ++i ) {
|
||||
|
||||
char *absolute = file_pathabs(ifndef(win32, list[i], va("%s/%s", path, list[i]))); // ../dir/./file.ext -> c:/prj/dir/file.ext
|
||||
BROWSER_PRINTF("%s->%s %d->", list[i], absolute, file_directory(absolute) );
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
static inline void array_find_and_remove(array(int) arr, int v) {
|
||||
for( int i = 0, end = array_count(arr); i < end; i++ )
|
||||
if( arr[i] == v ) { array_erase(arr, i); --end; break; }
|
||||
if( arr[i] == v ) { array_erase_fast(arr, i); --end; break; }
|
||||
}
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -126,7 +126,7 @@ static void RemoveIfNonNeighbor_(struct mesh *M, struct vertex *v, int id) {
|
|||
return;
|
||||
}
|
||||
// remove from neighbors
|
||||
array_erase(v->neighbor, i);
|
||||
array_erase_fast(v->neighbor, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ vec3 get_voxel_for_boid(float perception_radius, const boid_t *b) { // quantize
|
|||
|
||||
static
|
||||
void check_voxel_for_boids(float perception_radius, float blindspot_angledeg_compare_value, array(boid_t*) voxel_cached, array(nearby_boid_t) *result, const vec3 voxelPos, const boid_t *b) {
|
||||
for each_array_ptr(voxel_cached, const boid_t*, test) {
|
||||
for each_array_ptr(voxel_cached, boid_t*, test) {
|
||||
vec3 p1 = b->position;
|
||||
vec3 p2 = (*test)->position;
|
||||
vec3 vec = sub3(p2, p1);
|
||||
|
@ -64,7 +64,7 @@ void check_voxel_for_boids(float perception_radius, float blindspot_angledeg_com
|
|||
compare_value = dot3(neg3(b->velocity), vec) / (l1 * l2);
|
||||
}
|
||||
|
||||
if ((&b) != test && distance <= perception_radius && (blindspot_angledeg_compare_value > compare_value || len3(b->velocity) == 0)) {
|
||||
if (b != (*test) && distance <= perception_radius && (blindspot_angledeg_compare_value > compare_value || len3(b->velocity) == 0)) {
|
||||
nearby_boid_t nb;
|
||||
nb.boid = (boid_t*)*test;
|
||||
nb.distance = distance;
|
||||
|
|
|
@ -276,8 +276,8 @@ int audio_init( int flags ) {
|
|||
ma_backend_wasapi, // Higest priority.
|
||||
ma_backend_dsound,
|
||||
ma_backend_winmm,
|
||||
ma_backend_pulseaudio,
|
||||
ma_backend_coreaudio,
|
||||
ma_backend_pulseaudio,
|
||||
ma_backend_alsa,
|
||||
ma_backend_oss,
|
||||
ma_backend_jack,
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
// [ ] CompareKeys(keyVar1, operator < <= > >= == !=, keyVar2)
|
||||
// [ ] SetTags(names=blank,cooldownTime=inf,bIsCooldownAdditive=false)
|
||||
// [ ] HasTags(names=blank,bAllRequired=true)
|
||||
// [ ] PushToStack(keyVar,itemObj): creates a new stack if one doesn’t exist, and stores it in the passed variable name, and then pushes ‘item’ object onto it.
|
||||
// [ ] PushToStack(keyVar,itemObj): creates a new stack if one doesn't exist, and stores it in the passed variable name, and then pushes 'item' object onto it.
|
||||
// [ ] PopFromStack(keyVar,itemVar): pop pops an item off the stack, and stores it in the itemVar variable, failing if the stack is already empty.
|
||||
// [ ] IsEmptyStack(keyVar): checks if the stack passed is empty and returns success if it is, and failure if its not.
|
||||
// [ ] Communication Node: This is a type of action node that allows an AI agent to communicate with other agents or entities in the game world. The node takes an input specifying the message to be communicated and the recipient(s) of the message (wildmask,l/p/f/g prefixes). The node then sends the message to the designated recipient(s) and returns success when the communication is completed. This node can be useful for implementing behaviors that require the AI agent to coordinate with other agents or to convey information to the player. It could use a radius argument to specify the maximum allowed distance for the recipients.
|
||||
|
|
|
@ -31,6 +31,8 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
|||
#define chdir ifdef(cl, _chdir, chdir)
|
||||
#if is(cl) || is(tcc)
|
||||
#define ftruncate _chsize_s
|
||||
#define flockfile ifdef(cl,_lock_file,(void))
|
||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
||||
#endif
|
||||
#else // gcc
|
||||
//#include <alloca.h> // mingw64 does not have it
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#define ENABLE_LINUX_CALLSTACKS 0 ///+
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_TESTS
|
||||
#define ENABLE_TESTS 0 // ifdef(debug, 1, 0) ///+
|
||||
#ifndef ENABLE_AUTOTESTS
|
||||
#define ENABLE_AUTOTESTS ifdef(debug, 1, 0) ///+
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_RETAIL
|
||||
|
@ -117,15 +117,6 @@
|
|||
#define ifdef_release ifdef_false
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
|
||||
#define ifdef_64 ifdef_true
|
||||
#define ifdef_32 ifdef_false
|
||||
#else
|
||||
#define ifdef_64 ifdef_false
|
||||
#define ifdef_32 ifdef_true
|
||||
#endif
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#define ifdef_retail ifdef_true
|
||||
#else
|
||||
|
@ -138,6 +129,37 @@
|
|||
#define ifdef_nocook ifdef_false
|
||||
#endif
|
||||
|
||||
#if defined NDEBUG && NDEBUG >= 3 // we use NDEBUG=[0,1,2,3] to signal the compiler optimization flags O0,O1,O2,O3
|
||||
#define ifdef_O3 ifdef_true
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_false
|
||||
#elif defined NDEBUG && NDEBUG >= 2
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_true
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_false
|
||||
#elif defined NDEBUG && NDEBUG >= 1
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_true
|
||||
#define ifdef_O0 ifdef_false
|
||||
#else
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_true
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
|
||||
#define ifdef_64 ifdef_true
|
||||
#define ifdef_32 ifdef_false
|
||||
#else
|
||||
#define ifdef_64 ifdef_false
|
||||
#define ifdef_32 ifdef_true
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// new C keywords
|
||||
|
||||
|
@ -166,8 +188,13 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// new C macros
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#define ASSERT(expr, ...) (void)0
|
||||
#define ASSERT_ONCE(expr, ...) (void)0
|
||||
#else
|
||||
#define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
|
||||
#define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
|
||||
#endif
|
||||
#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_)
|
||||
|
||||
#define FILELINE __FILE__ ":" STRINGIZE(__LINE__)
|
||||
|
|
|
@ -398,7 +398,7 @@ int zipscan_diff( zip* old, array(struct fs) now ) {
|
|||
uint64_t oldstamp = atoi64(zip_modt(old,found)+20); // format is "YYYY/MM/DD hh:mm:ss", then +20 chars later a hidden epoch timestamp in base10 can be found
|
||||
int64_t diffstamp = oldstamp < now[i].stamp ? now[i].stamp - oldstamp : oldstamp - now[i].stamp;
|
||||
if( oldsize != now[i].bytes || diffstamp > 1 ) { // @fixme: should use hash instead. hashof(tool) ^ hashof(args used) ^ hashof(rawsize) ^ hashof(rawdate)
|
||||
printf("%s:\t%u vs %u, %llu vs %llu\n", now[i].fname, (unsigned)oldsize,(unsigned)now[i].bytes, oldstamp,now[i].stamp);
|
||||
printf("%s:\t%u vs %u, %llu vs %llu\n", now[i].fname, (unsigned)oldsize,(unsigned)now[i].bytes, (long long unsigned)oldstamp, (long long unsigned)now[i].stamp);
|
||||
array_push(changed, STRDUP(now[i].fname));
|
||||
array_push(uncooked, STRDUP(now[i].fname));
|
||||
}
|
||||
|
@ -694,8 +694,8 @@ bool cook_start( const char *cook_ini, const char *masks, int flags ) {
|
|||
// scan disk: all subfolders in ART (comma-separated)
|
||||
static array(char *) list = 0; // @leak
|
||||
for each_substring(ART, ",", art_folder) {
|
||||
const char **glob = file_list(art_folder, "**");
|
||||
for( unsigned i = 0; glob[i]; ++i ) {
|
||||
array(char *) glob = file_list(va("%s**",art_folder)); // art_folder ends with '/'
|
||||
for( unsigned i = 0, end = array_count(glob); i < end; ++i ) {
|
||||
const char *fname = glob[i];
|
||||
if( !strmatchi(fname, masks)) continue;
|
||||
|
||||
|
@ -715,8 +715,13 @@ bool cook_start( const char *cook_ini, const char *masks, int flags ) {
|
|||
if( !memcmp(header, "\x64\x86", 2) ) continue;
|
||||
if( !memcmp(header, "\x00\x00", 2) ) continue;
|
||||
}
|
||||
// exclude vc/gcc files
|
||||
if( strend(fname, ".a") || strend(fname, ".pdb") || strend(fname, ".lib") || strend(fname, ".ilk") || strend(fname, ".exp") ) {
|
||||
|
||||
char *dot = strrchr(fname, '.');
|
||||
if( dot ) {
|
||||
char extdot[32];
|
||||
snprintf(extdot, 32, "%s.", dot); // .png -> .png.
|
||||
// exclude vc/gcc/clang files
|
||||
if( strstr(fname, ".a.o.pdb.lib.ilk.exp.dSYM.") ) // must end with dot
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -777,8 +782,7 @@ void cook_stop() {
|
|||
if(jobs[i].self) thread_join(jobs[i].self);
|
||||
}
|
||||
// remove all temporary outfiles
|
||||
const char **temps = file_list("./", "temp_*");
|
||||
for( int i = 0; temps[i]; ++i ) unlink(temps[i]);
|
||||
for each_array(file_list("temp_*"), char*, tempfile) unlink(tempfile);
|
||||
}
|
||||
|
||||
int cook_progress() {
|
||||
|
|
|
@ -90,14 +90,16 @@ static __thread unsigned array_n_;
|
|||
} while(0)
|
||||
|
||||
#define array_foreach(t,val_t,v) for each_array(t,val_t,v)
|
||||
#define each_array(t,val_t,v) \
|
||||
( int __it = 0, __end = array_count(t); __it < __end; ++__it ) \
|
||||
for( val_t v = __it[t], *on__ = &v; on__; on__ = 0 )
|
||||
#define each_array(a,val_t,v) \
|
||||
( array(val_t) a_ = (a); a_; a_ = 0 ) \
|
||||
for( int i_ = 0, e_ = array_count(a_); i_ < e_; ++i_ ) \
|
||||
for( val_t v = i_[a_], *v_ = (void*)(uintptr_t)&v; v_; v_ = 0 )
|
||||
|
||||
#define array_foreach_ptr(t,val_t,v) for each_array_ptr(t,val_t,v)
|
||||
#define each_array_ptr(t,val_t,v) \
|
||||
( int __it = 0, __end = array_count(t); __it < __end; ++__it ) \
|
||||
for( val_t *v = (val_t*)&__it[t]; v; v = 0 )
|
||||
#define each_array_ptr(a,val_t,v) \
|
||||
( array(val_t) a_ = (a); a_; a_ = 0 ) \
|
||||
for( int i_ = 0, e_ = array_count(a_); i_ < e_; ++i_ ) \
|
||||
for( val_t *v = (val_t*)&i_[a_]; v; v = 0 )
|
||||
|
||||
#define array_search(t, key, cmpfn) /* requires sorted array beforehand */ \
|
||||
bsearch(&key, t, array_count(t), sizeof(t[0]), cmpfn )
|
||||
|
@ -113,13 +115,13 @@ static __thread unsigned array_n_;
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define array_copy(t, src) do { /*todo: review old vrealloc call!*/ \
|
||||
#define array_copy(t, src) do { \
|
||||
array_free(t); \
|
||||
(t) = array_realloc_( (t), array_count(src)); \
|
||||
memcpy( (t), src, array_count(src) * sizeof(0[t])); \
|
||||
} while(0)
|
||||
|
||||
#define array_swapback_and_pop(t, i) do { /*may alter ordering*/ \
|
||||
#define array_erase_fast(t, i) do { /*may alter ordering*/ \
|
||||
memcpy( &(t)[i], &(t)[array_count(t) - 1], sizeof(0[t])); \
|
||||
array_pop(t); \
|
||||
} while(0)
|
||||
|
|
|
@ -79,7 +79,8 @@ bool file_append(const char *name, const void *ptr, int len) {
|
|||
}
|
||||
return ok;
|
||||
}
|
||||
static bool file_stat(const char *fname, struct stat *st) {
|
||||
static // not exposed
|
||||
bool file_stat(const char *fname, struct stat *st) {
|
||||
// remove ending slashes. win32+tcc does not like them.
|
||||
int l = strlen(fname), m = l;
|
||||
while( l && (fname[l-1] == '/' || fname[l-1] == '\\') ) --l;
|
||||
|
@ -200,7 +201,7 @@ char *ext = strrchr(base, '.'); //if (ext) ext[0] = '\0'; // remove all extensio
|
|||
}
|
||||
return va("%s", buffer);
|
||||
}
|
||||
const char** file_list(const char *cwds, const char *masks) {
|
||||
array(char*) file_list(const char *pathmasks) {
|
||||
static __thread array(char*) list = 0; // @fixme: should we add 16 slots in here similar to what we do in va() ?
|
||||
|
||||
for( int i = 0; i < array_count(list); ++i ) {
|
||||
|
@ -208,7 +209,16 @@ const char** file_list(const char *cwds, const char *masks) {
|
|||
}
|
||||
array_resize(list, 0);//array_free(list);
|
||||
|
||||
for each_substring(cwds,";",cwd) {
|
||||
for each_substring(pathmasks,";",pathmask) {
|
||||
char *cwd = 0, *masks = 0;
|
||||
char *slash = strrchr(pathmask, '/');
|
||||
if( !slash ) cwd = "./", masks = pathmask;
|
||||
else {
|
||||
masks = va("%s", slash+1);
|
||||
cwd = pathmask, slash[1] = '\0';
|
||||
}
|
||||
if( !masks[0] ) masks = "*";
|
||||
|
||||
ASSERT(strend(cwd, "/"), "Error: dirs like '%s' must end with slash", cwd);
|
||||
|
||||
dir *d = dir_open(cwd, strstr(masks,"**") ? "r" : "");
|
||||
|
@ -236,8 +246,7 @@ const char** file_list(const char *cwds, const char *masks) {
|
|||
}
|
||||
}
|
||||
|
||||
array_push(list, 0); // terminator
|
||||
return (const char**)list;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool file_move(const char *src, const char *dst) {
|
||||
|
@ -584,15 +593,8 @@ void vfs_reload() {
|
|||
#else
|
||||
// mount fused executables
|
||||
vfs_mount(va("%s%s%s", app_path(), app_name(), ifdef(win32, ".exe", "")));
|
||||
/* // old way
|
||||
for( int i = 0; i < JOBS_MAX; ++i) {
|
||||
if( vfs_mount(va(".art[%02x].zip", i)) ) continue;
|
||||
if( vfs_mount(va("%s[%02x].zip", app, i)) ) continue;
|
||||
if( vfs_mount(va("%s%02x.zip", app, i)) ) continue;
|
||||
// if( vfs_mount(va("%s.%02x", app, i)) ) continue;
|
||||
} */
|
||||
// faster way
|
||||
for( const char **file = file_list("./","*.zip"); *file; ++file) vfs_mount(*file);
|
||||
// mount all zipfiles
|
||||
for each_array( file_list("*.zip"), char*, file ) vfs_mount(file);
|
||||
#endif
|
||||
|
||||
// vfs_resolve() will use these art_folder locations as hints when cook-on-demand is in progress.
|
||||
|
@ -605,7 +607,7 @@ void vfs_reload() {
|
|||
|
||||
|
||||
|
||||
#define ARK1 'ArK\x1'
|
||||
#define ARK1 0x41724B31 // 'ArK1' in le, 0x314B7241 41 72 4B 31 otherwise
|
||||
#define ARK1_PADDING (512 - 40) // 472
|
||||
#define ARK_PRINTF(f,...) 0 // printf(f,__VA_ARGS__)
|
||||
#define ARK_SWAP32(x) (x)
|
||||
|
@ -697,9 +699,9 @@ const char** vfs_list(const char *masks) {
|
|||
|
||||
for each_substring(masks,";",it) {
|
||||
if( COOK_ON_DEMAND ) // edge case: any game using only vfs api + cook-on-demand flag will never find any file
|
||||
for(const char **items = file_list("./", it); *items; items++) {
|
||||
for each_array(file_list(it), char*, item) {
|
||||
// insert copy
|
||||
char *copy = STRDUP(*items);
|
||||
char *copy = STRDUP(item);
|
||||
array_push(list, copy);
|
||||
}
|
||||
|
||||
|
@ -805,8 +807,8 @@ if( found && *found == 0 ) {
|
|||
folder = file_path(pathfile);
|
||||
// ease folders reading by shortening them: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav
|
||||
// or C:/prj/v4k/engine/art/fonts/B612-BoldItalic.ttf -> fonts/B612-BoldItalic.ttf
|
||||
static array(char*) art_paths = 0;
|
||||
do_once for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem));
|
||||
static __thread array(char*) art_paths = 0;
|
||||
if(!art_paths) for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem));
|
||||
char* pretty_folder = "";
|
||||
if( folder ) for( int i = 0; i < array_count(art_paths); ++i ) {
|
||||
if( strbeg(folder, art_paths[i]) ) { pretty_folder = folder + strlen(art_paths[i]); break; }
|
||||
|
@ -857,7 +859,7 @@ if( found && *found == 0 ) {
|
|||
// this block saves some boot time (editor --cook-on-demand: boot 1.50s -> 0.90s)
|
||||
#if 1 // EXPERIMENTAL_DONT_COOK_NON_EXISTING_ASSETS
|
||||
static set(char*) disk = 0;
|
||||
if(!disk) { set_init_str(disk); for each_substring(ART,",",art_folder) for( const char **list = file_list(art_folder,"**"); *list; ++list) set_insert(disk, STRDUP(*list)); }
|
||||
if(!disk) { set_init_str(disk); for each_substring(ART,",",art_folder) for each_array(file_list(va("%s**", art_folder)), char*, item) set_insert(disk, STRDUP(item)); } // art_folder ends with '/'
|
||||
int found = !!set_find(disk, (char*)pathfile);
|
||||
if( found )
|
||||
#endif
|
||||
|
@ -970,23 +972,28 @@ const char *vfs_extract(const char *pathfile) { // extract a vfs file into the l
|
|||
// -----------------------------------------------------------------------------
|
||||
// cache
|
||||
|
||||
static thread_mutex_t cache_mutex; AUTORUN{ thread_mutex_init(&cache_mutex); }
|
||||
|
||||
void* cache_lookup(const char *pathfile, int *size) { // find key->value
|
||||
if( !MAX_CACHED_FILES ) return 0;
|
||||
void* data = 0;
|
||||
thread_mutex_lock(&cache_mutex);
|
||||
for(archive_dir *dir = dir_cache; dir; dir = dir->next) {
|
||||
if( !strcmp(dir->path, pathfile) ) {
|
||||
if(size) *size = dir->size;
|
||||
return dir->data;
|
||||
data = dir->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
thread_mutex_unlock(&cache_mutex);
|
||||
return data;
|
||||
}
|
||||
void* cache_insert(const char *pathfile, void *ptr, int size) { // append key/value; return LRU or NULL
|
||||
if( !MAX_CACHED_FILES ) return 0;
|
||||
if( !ptr || !size ) return 0;
|
||||
|
||||
// keep cached files within limits
|
||||
static thread_mutex_t mutex, *init = 0; if(!init) thread_mutex_init(init = &mutex);
|
||||
thread_mutex_lock(&mutex);
|
||||
thread_mutex_lock(&cache_mutex);
|
||||
|
||||
// append to cache
|
||||
archive_dir zero = {0}, *old = dir_cache;
|
||||
|
@ -1016,7 +1023,7 @@ void* cache_insert(const char *pathfile, void *ptr, int size) { // append key/va
|
|||
}
|
||||
}
|
||||
|
||||
thread_mutex_unlock(&mutex);
|
||||
thread_mutex_unlock(&cache_mutex);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
// physical filesystem. files
|
||||
|
||||
API const char** file_list(const char *path, const char *masks); // **.png;*.c
|
||||
API array(char*) file_list( const char *pathmasks ); // folder/*.ico;**.png;*.c
|
||||
API bool file_write( const char *file, const void *ptr, int len );
|
||||
API bool file_append( const char *file, const void *ptr, int len );
|
||||
API char * file_read(const char *filename);
|
||||
|
|
|
@ -1,48 +1,41 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void v4k_pre_init() {
|
||||
const char *appname = app_name();
|
||||
const char *appdir = app_path();
|
||||
window_icon(va("%s/%s.png", appdir, appname));
|
||||
ifdef(win32,window_icon(va("%s/%s.ico", appdir, appname)));
|
||||
window_icon(va("%s%s.png", app_path(), app_name()));
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
int i;
|
||||
#pragma omp parallel for
|
||||
for( i = 0; i <= 3; ++i) {
|
||||
for( i = 0; i <= 6; ++i) {
|
||||
/**/ if( i == 0 ) ddraw_init();// init this on thread#0 since it will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
else if( i == 1 ) sprite_init();
|
||||
else if( i == 2 ) profiler_init();
|
||||
else if( i == 3 ) storage_mount("save/"), storage_read(), touch_init(); // for ems
|
||||
else if( i == 4 ) audio_init(0);
|
||||
else if( i == 5 ) script_init(), kit_init(), midi_init();
|
||||
else if( i == 6 ) network_init();
|
||||
}
|
||||
|
||||
// window_swap();
|
||||
}
|
||||
static void v4k_post_init(float refresh_rate) {
|
||||
int i;
|
||||
|
||||
// cook cleanup
|
||||
cook_stop();
|
||||
|
||||
vfs_reload();
|
||||
|
||||
// init subsystems that depend on cooked assets now. ui_init() is special case and needs to be safely in single thread
|
||||
ui_init();
|
||||
// init subsystems that depend on cooked assets now
|
||||
|
||||
// init more subsystems; beware of VFS mounting, as some of these may need cooked assets at this point
|
||||
int i;
|
||||
#pragma omp parallel for
|
||||
for( i = 0; i <= 3; ++i) {
|
||||
/**/ if( i == 0 ) scene_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
else if( i == 1 ) audio_init(0); // initialize audio after cooking // reasoning for this: do not launch audio threads while cooks are in progress, so there is more cpu for cooking actually
|
||||
else if( i == 2 ) script_init(), kit_init(), midi_init();
|
||||
else if( i == 3 ) input_init(), network_init();
|
||||
for( i = 0; i <= 2; ++i ) {
|
||||
if(i == 0) ui_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
if(i == 0) scene_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
if(i == 1) input_init();
|
||||
if(i == 2) window_icon(va("%s.png", app_name()));
|
||||
}
|
||||
|
||||
const char *appname = app_name();
|
||||
window_icon(va("%s.png", appname));
|
||||
window_icon(va("%s.ico", appname));
|
||||
|
||||
// display window
|
||||
glfwShowWindow(window);
|
||||
glfwGetFramebufferSize(window, &w, &h); //glfwGetWindowSize(window, &w, &h);
|
||||
|
|
|
@ -305,7 +305,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
network_put(NETWORK_RANK, -1); /* unassigned until we connect successfully */
|
||||
int64_t socket = client_join(ip, port);
|
||||
if( socket >= 0 ) {
|
||||
PRINTF("Client connected, id %lld\n", socket);
|
||||
PRINTF("Client connected, id %d\n", (int)socket);
|
||||
network_put(NETWORK_LIVE, 1);
|
||||
network_put(NETWORK_RANK, socket);
|
||||
} else {
|
||||
|
@ -322,7 +322,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
network_put(NETWORK_RANK, -1); /* unassigned until we connect successfully */
|
||||
int64_t socket = client_join(ip, port);
|
||||
if( socket > 0 ) {
|
||||
PRINTF("Client connected, id %lld\n", socket);
|
||||
PRINTF("Client connected, id %d\n", (int)socket);
|
||||
network_put(NETWORK_LIVE, 1);
|
||||
network_put(NETWORK_RANK, socket);
|
||||
} else {
|
||||
|
@ -333,7 +333,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
}
|
||||
}
|
||||
|
||||
PRINTF("Network rank:%lld ip:%s port:%lld\n", network_get(NETWORK_RANK), ip, network_get(NETWORK_PORT));
|
||||
PRINTF("Network rank:%u ip:%s port:%d\n", (unsigned)network_get(NETWORK_RANK), ip, (int)network_get(NETWORK_PORT));
|
||||
}
|
||||
|
||||
int64_t network_put(uint64_t key, int64_t value) {
|
||||
|
@ -466,8 +466,8 @@ char** server_poll(unsigned timeout_ms) {
|
|||
*(uint32_t*)&init_msg[0] = MSG_INIT;
|
||||
*(int64_t*)&init_msg[4] = client_id;
|
||||
server_send_bin(client_id, init_msg, 12);
|
||||
PRINTF("Client rank %lld for peer ::%s:%u\n", client_id, ip, event.peer->address.port);
|
||||
msg = va( "%d new client rank:%lld from ::%s:%u", 0, client_id, ip, event.peer->address.port );
|
||||
PRINTF("Client rank %u for peer ::%s:%u\n", (unsigned)client_id, ip, event.peer->address.port);
|
||||
msg = va( "%d new client rank:%u from ::%s:%u", 0, (unsigned)client_id, ip, event.peer->address.port );
|
||||
event.peer->data = (void*)client_id;
|
||||
break;
|
||||
|
||||
|
@ -523,7 +523,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
msg = va("%d %s", 0, va("%s", ptr));
|
||||
} break;
|
||||
default:
|
||||
msg = va("%d unk msg len:%u from rank:%lld ::%s:%u", -1, sz, (uint64_t)event.peer->data, ip, event.peer->address.port); /* @TODO: hexdump? */
|
||||
msg = va("%d unk msg len:%u from rank:%u ::%s:%u", -1, sz, (unsigned)(uintptr_t)event.peer->data, ip, event.peer->address.port); /* @TODO: hexdump? */
|
||||
break;
|
||||
}
|
||||
/* Clean up the packet now that we're done using it. */
|
||||
|
@ -531,7 +531,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
} break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
msg = va( "%d disconnect rank:%lld", 0, (uint64_t)event.peer->data);
|
||||
msg = va( "%d disconnect rank:%u", 0, (unsigned)(uintptr_t)event.peer->data);
|
||||
/* Reset the peer's client information. */
|
||||
FREE(event.peer->data);
|
||||
event.peer->data = NULL;
|
||||
|
@ -540,7 +540,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||
msg = va( "%d timeout rank:%lld", 0, (uint64_t)event.peer->data);
|
||||
msg = va( "%d timeout rank:%u", 0, (unsigned)(uintptr_t)event.peer->data);
|
||||
FREE(event.peer->data);
|
||||
event.peer->data = NULL;
|
||||
server_drop_client_peer(event.peer);
|
||||
|
|
|
@ -102,8 +102,8 @@ AUTOTEST {
|
|||
|
||||
// iterate reflected struct
|
||||
for each_member("MyVec4", R) {
|
||||
printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||
}
|
||||
|
||||
reflected_printf_all();
|
||||
// reflected_printf_all();
|
||||
}
|
||||
|
|
|
@ -104,9 +104,10 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char
|
|||
|
||||
const char *glsl_version = ifdef(ems, "300 es", "150");
|
||||
|
||||
vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : "");
|
||||
fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : "");
|
||||
if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : "");
|
||||
if(gs)
|
||||
gs = gs && gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : "");
|
||||
vs = vs && vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : "");
|
||||
fs = fs && fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : "");
|
||||
|
||||
#if is(ems)
|
||||
{
|
||||
|
|
|
@ -18,9 +18,10 @@ const char *app_path() { // @fixme: should return absolute path always. see tcc
|
|||
strcat(buffer, "..\\..\\");
|
||||
}
|
||||
#else // #elif is(linux)
|
||||
char path[21] = {0};
|
||||
char path[32] = {0};
|
||||
sprintf(path, "/proc/%d/exe", getpid());
|
||||
readlink(path, buffer, sizeof(buffer));
|
||||
if(strrchr(buffer,'/')) 1[strrchr(buffer,'/')] = '\0';
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
@ -723,15 +724,15 @@ int (PRINTF)(const char *text, const char *stack, const char *file, int line, co
|
|||
char *location = va("|%s|%s:%d", /*errno?strerror(errno):*/function, file, line);
|
||||
int cols = tty_cols() + 1 - (int)strlen(location);
|
||||
|
||||
static thread_mutex_t lock, *init = 0; if(!init) thread_mutex_init(init = &lock);
|
||||
thread_mutex_lock( &lock );
|
||||
flockfile(stdout);
|
||||
|
||||
tty_color(color);
|
||||
printf("\r%*.s%s", cols, "", location);
|
||||
printf("\r%07.3fs|%s%s", secs, text, stack);
|
||||
tty_color(0);
|
||||
|
||||
thread_mutex_unlock( &lock );
|
||||
funlockfile(stdout);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,18 +62,13 @@ API void trap_on_debug(int signal); // helper util
|
|||
#define PANIC(...) PANIC(va(__VA_ARGS__), strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__, __LINE__) // die() ?
|
||||
API int (PANIC)(const char *error, const char *file, int line);
|
||||
|
||||
#if !ENABLE_RETAIL
|
||||
#define PRINTF(...) PRINTF(va(__VA_ARGS__), 1[#__VA_ARGS__] == '!' ? callstack(+48) : "", strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__, __LINE__, __FUNCTION__)
|
||||
API int (PRINTF)(const char *text, const char *stack, const char *file, int line, const char *function);
|
||||
|
||||
#define test(expr) test(strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__,__LINE__,#expr,!!(expr))
|
||||
API int (test)(const char *file, int line, const char *expr, bool result);
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define test(expr)
|
||||
#endif
|
||||
|
||||
#if ENABLE_TESTS
|
||||
#if ENABLE_AUTOTESTS
|
||||
#define AUTOTEST AUTORUN
|
||||
#else
|
||||
#define AUTOTEST static void concat(concat(concat(disabled_test_, __LINE__), _), __COUNTER__)()
|
||||
|
@ -81,3 +76,9 @@ API int (test)(const char *file, int line, const char *expr, bool result);
|
|||
|
||||
// AUTOTEST { test(1<2); }
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#undef PRINTF
|
||||
#define PRINTF(...) 0
|
||||
#undef test
|
||||
#define test(expr) 0
|
||||
#endif
|
||||
|
|
|
@ -64,20 +64,20 @@ static void nk_config_custom_fonts() {
|
|||
nk_glfw3_font_stash_begin(&nk_glfw, &atlas); // nk_sdl_font_stash_begin(&atlas);
|
||||
|
||||
// Default font(#1)...
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_REGULAR); data; data = 0 ) {
|
||||
int datalen = 0;
|
||||
for( char *data = vfs_load(UI_FONT_REGULAR, &datalen); data; data = 0 ) {
|
||||
float font_size = UI_FONT_REGULAR_SIZE;
|
||||
struct nk_font_config cfg = nk_font_config(font_size);
|
||||
cfg.oversample_v = 2;
|
||||
cfg.pixel_snap = 0;
|
||||
// win32: struct nk_font *arial = nk_font_atlas_add_from_file(atlas, va("%s/fonts/arial.ttf",getenv("windir")), font_size, &cfg); font = arial ? arial : font;
|
||||
// struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "nuklear/extra_font/DroidSans.ttf", font_size, &cfg); font = droid ? droid : font;
|
||||
struct nk_font *regular = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_REGULAR), font_size, &cfg); font = regular ? regular : font;
|
||||
struct nk_font *regular = nk_font_atlas_add_from_memory(atlas, data, datalen, font_size, &cfg); font = regular ? regular : font;
|
||||
}
|
||||
|
||||
// ...with icons embedded on it.
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_ICONS); data; data = 0 ) {
|
||||
for( char *data = vfs_load(UI_FONT_ICONS, &datalen); data; data = 0 ) {
|
||||
static const nk_rune icon_range[] = {UI_ICON_MIN, UI_ICON_MED /*MAX*/, 0};
|
||||
|
||||
struct nk_font_config cfg = nk_font_config(UI_ICON_FONTSIZE);
|
||||
|
@ -93,12 +93,12 @@ static void nk_config_custom_fonts() {
|
|||
cfg.oversample_v = 1;
|
||||
cfg.pixel_snap = 1;
|
||||
|
||||
struct nk_font *icons = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_ICONS), UI_ICON_FONTSIZE, &cfg);
|
||||
struct nk_font *icons = nk_font_atlas_add_from_memory(atlas, data, datalen, UI_ICON_FONTSIZE, &cfg);
|
||||
}
|
||||
|
||||
// Monospaced font. Used in terminals or consoles.
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_TERMINAL); data; data = 0 ) {
|
||||
for( char *data = vfs_load(UI_FONT_TERMINAL, &datalen); data; data = 0 ) {
|
||||
const float font_size = UI_FONT_REGULAR_SIZE;
|
||||
static const nk_rune icon_range[] = {32, 127, 0};
|
||||
|
||||
|
@ -110,13 +110,13 @@ static void nk_config_custom_fonts() {
|
|||
cfg.pixel_snap = 1;
|
||||
|
||||
// struct nk_font *proggy = nk_font_atlas_add_default(atlas, font_size, &cfg);
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_TERMINAL), font_size, &cfg);
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, datalen, font_size, &cfg);
|
||||
}
|
||||
|
||||
// Extra optional fonts from here...
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_HEADING); data; data = 0 ) {
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_HEADING), UI_FONT_HEADING_SIZE, 0); // font = bold ? bold : font;
|
||||
for( char *data = vfs_load(UI_FONT_HEADING, &datalen); data; data = 0 ) {
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, datalen, UI_FONT_HEADING_SIZE, 0); // font = bold ? bold : font;
|
||||
}
|
||||
|
||||
nk_glfw3_font_stash_end(&nk_glfw); // nk_sdl_font_stash_end();
|
||||
|
|
|
@ -990,11 +990,16 @@ void window_color(unsigned color) {
|
|||
unsigned a = (color >> 24) & 255;
|
||||
winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
||||
}
|
||||
static int has_icon;
|
||||
int window_has_icon() {
|
||||
return has_icon;
|
||||
}
|
||||
void window_icon(const char *file_icon) {
|
||||
unsigned len = file_size(file_icon); len = len ? len : vfs_size(file_icon);
|
||||
if( len ) {
|
||||
void *data = file_read(file_icon); data = data ? data : vfs_read(file_icon);
|
||||
if( data ) {
|
||||
int len = 0;
|
||||
void *data = vfs_load(file_icon, &len);
|
||||
if( !data ) data = file_read(file_icon), len = file_size(file_icon);
|
||||
|
||||
if( data && len ) {
|
||||
image_t img = image_from_mem(data, len, IMAGE_RGBA);
|
||||
if( img.w && img.h && img.pixels ) {
|
||||
GLFWimage images[1];
|
||||
|
@ -1002,11 +1007,11 @@ void window_icon(const char *file_icon) {
|
|||
images[0].height = img.h;
|
||||
images[0].pixels = img.pixels;
|
||||
glfwSetWindowIcon(window, 1, images);
|
||||
has_icon = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if is(win32)
|
||||
#if 0 // is(win32)
|
||||
HANDLE hIcon = LoadImageA(0, file_icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||
if( hIcon ) {
|
||||
HWND hWnd = glfwGetWin32Window(window);
|
||||
|
@ -1014,6 +1019,7 @@ void window_icon(const char *file_icon) {
|
|||
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
has_icon = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,6 @@ API void window_loop(void (*function)(void* loopArg), void* loopArg ); // ru
|
|||
API void window_loop_exit(); // exit from main loop function (emscripten only)
|
||||
|
||||
API void window_title(const char *title);
|
||||
API void window_icon(const char *file_icon);
|
||||
API void window_color(unsigned color);
|
||||
API vec2 window_canvas();
|
||||
API void* window_handle();
|
||||
|
@ -65,6 +64,8 @@ API void window_maximize(int enabled);
|
|||
API int window_has_maximize();
|
||||
API void window_transparent(int enabled);
|
||||
API int window_has_transparent();
|
||||
API void window_icon(const char *file_icon);
|
||||
API int window_has_icon();
|
||||
|
||||
API double window_aspect();
|
||||
API void window_aspect_lock(unsigned numer, unsigned denom);
|
||||
|
|
64
engine/v4k
64
engine/v4k
|
@ -222022,8 +222022,8 @@ static void browser_reload_directory_content(struct browser *browser, const char
|
|||
|
||||
BROWSER_PRINTF("searching at %s\n", path);
|
||||
|
||||
const char **list = file_list(path, "*");
|
||||
for( int i = 0; list[i]; ++i ) {
|
||||
array(char*) list = file_list(path);
|
||||
for( int i = 0, end = array_count(list); i < end; ++i ) {
|
||||
|
||||
char *absolute = file_pathabs(ifndef(win32, list[i], va("%s/%s", path, list[i]))); // ../dir/./file.ext -> c:/prj/dir/file.ext
|
||||
BROWSER_PRINTF("%s->%s %d->", list[i], absolute, file_directory(absolute) );
|
||||
|
@ -222567,9 +222567,11 @@ char *json5__parse_value(json5 *obj, char *p, char **err_code) {
|
|||
*buf++ = *p++;
|
||||
}
|
||||
obj->type = is_dbl ? JSON5_REAL : JSON5_INTEGER;
|
||||
long long unsigned int llu;
|
||||
long long int lli;
|
||||
/**/ if( is_dbl ) sscanf( buffer, "%lf", &obj->real );
|
||||
else if( is_hex ) sscanf( buffer, "%llx", &obj->integer ); // SCNx64 -> inttypes.h
|
||||
else sscanf( buffer, "%lld", &obj->integer ); // SCNd64 -> inttypes.h
|
||||
else if( is_hex ) sscanf( buffer, "%llx", &llu ), obj->integer = llu; // SCNx64 -> inttypes.h
|
||||
else sscanf( buffer, "%lld", &lli ), obj->integer = lli; // SCNd64 -> inttypes.h
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
|
@ -222621,7 +222623,7 @@ void json5_write(FILE *fp, const json5 *o) {
|
|||
}
|
||||
/**/ if( o->type == JSON5_NULL ) fprintf(fp, "%s", "null");
|
||||
else if( o->type == JSON5_BOOL ) fprintf(fp, "%s", o->boolean ? "true" : "false");
|
||||
else if( o->type == JSON5_INTEGER ) fprintf(fp, "%lld", o->integer);
|
||||
else if( o->type == JSON5_INTEGER ) fprintf(fp, "%lld", (long long int)o->integer);
|
||||
else if( o->type == JSON5_REAL ) {
|
||||
/**/ if( isnan(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-nan" : "nan" );
|
||||
else if( isinf(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-inf" : "inf" );
|
||||
|
@ -234808,10 +234810,10 @@ bool zip_append_file_timeinfo(zip *z, const char *entryname, const char *comment
|
|||
// Read whole file and and use compress(). Simple but won't handle GB files well.
|
||||
unsigned dataSize = e->header.uncompressedSize, compSize = BOUNDS(e->header.uncompressedSize, compress_level);
|
||||
|
||||
comp = REALLOC(0, compSize);
|
||||
comp = REALLOC(comp, compSize);
|
||||
if(comp == NULL) goto cant_compress;
|
||||
|
||||
data = REALLOC(0, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
data = REALLOC(data, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
if(data == NULL) goto cant_compress; else memset((char*)data + dataSize, 0, 8);
|
||||
|
||||
fseek(in, 0, SEEK_SET); // rewind
|
||||
|
@ -234919,10 +234921,10 @@ bool zip_append_mem_timeinfo(zip *z, const char *entryname, const char *comment,
|
|||
// Read whole file and and use compress(). Simple but won't handle GB files well.
|
||||
unsigned dataSize = e->header.uncompressedSize, compSize = BOUNDS(e->header.uncompressedSize, compress_level);
|
||||
|
||||
comp = REALLOC(0, compSize);
|
||||
comp = REALLOC(comp, compSize);
|
||||
if(comp == NULL) goto cant_compress;
|
||||
|
||||
data = REALLOC(0, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
data = REALLOC(data, dataSize + 8); // small excess as some compressors are really wild when reading from buffers (lz4x)
|
||||
if(data == NULL) goto cant_compress; else memset((char*)data + dataSize, 0, 8);
|
||||
|
||||
size_t bytes = inlen;
|
||||
|
@ -234970,30 +234972,46 @@ common:;
|
|||
|
||||
// zip common
|
||||
|
||||
#if 1
|
||||
# define zip_lockfile(f) (void)(f)
|
||||
# define zip_unlockfile(f) (void)(f)
|
||||
#else
|
||||
# if (defined(__TINYC__) && defined(_WIN32))
|
||||
# define zip_lockfile(f) (void)(f)
|
||||
# define zip_unlockfile(f) (void)(f)
|
||||
# elif defined _MSC_VER
|
||||
# define zip_lockfile(f) _lock_file(f)
|
||||
# define zip_unlockfile(f) _unlock_file(f)
|
||||
# else
|
||||
# define zip_lockfile(f) flockfile(f)
|
||||
# define zip_unlockfile(f) funlockfile(f)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
zip* zip_open_handle(FILE *fp, const char *mode) {
|
||||
if( !fp ) return ERR(NULL, "cannot open file for %s mode", mode);
|
||||
zip zero = {0}, *z = (zip*)REALLOC(0, sizeof(zip));
|
||||
if( !z ) return fclose(fp), ERR(NULL, "out of mem"); else *z = zero;
|
||||
if( !z ) return ERR(NULL, "out of mem"); else *z = zero;
|
||||
if( mode[0] == 'w' ) {
|
||||
z->out = fp;
|
||||
zip_lockfile(z->out = fp);
|
||||
return z;
|
||||
}
|
||||
if( mode[0] == 'r' || mode[0] == 'a' ) {
|
||||
z->in = fp;
|
||||
zip_lockfile(z->in = fp);
|
||||
|
||||
unsigned long long seekcur = ftell(z->in);
|
||||
|
||||
JZEndRecord jzEndRecord = {0};
|
||||
if(jzReadEndRecord(fp, &jzEndRecord) != JZ_OK) {
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Couldn't read ZIP file end record.");
|
||||
return ERR(NULL, "Couldn't read ZIP file end record.");
|
||||
}
|
||||
|
||||
jzEndRecord.centralDirectoryOffset += seekcur;
|
||||
|
||||
if(jzReadCentralDirectory(fp, &jzEndRecord, zip__callback, z, (void*)(uintptr_t)seekcur ) != JZ_OK) {
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Couldn't read ZIP file central directory.");
|
||||
return ERR(NULL, "Couldn't read ZIP file central directory.");
|
||||
}
|
||||
if( mode[0] == 'a' ) {
|
||||
|
||||
|
@ -235010,13 +235028,13 @@ zip* zip_open_handle(FILE *fp, const char *mode) {
|
|||
fseek( fp, 0L, SEEK_END );
|
||||
}
|
||||
|
||||
z->out = z->in;
|
||||
z->in = NULL;
|
||||
z->out = fp;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
REALLOC(z, 0);
|
||||
return fclose(fp), ERR(NULL, "Unknown open mode %s", mode);
|
||||
return ERR(NULL, "Unknown open mode %s", mode);
|
||||
}
|
||||
|
||||
zip* zip_open(const char *file, const char *mode /*r,w,a*/) {
|
||||
|
@ -235024,7 +235042,11 @@ zip* zip_open(const char *file, const char *mode /*r,w,a*/) {
|
|||
int exists = (stat(file, &buffer) == 0);
|
||||
if( mode[0] == 'a' && !exists ) mode = "wb";
|
||||
FILE *fp = fopen(file, mode[0] == 'w' ? "wb" : mode[0] == 'a' ? "a+b" : "rb");
|
||||
return zip_open_handle(fp, mode);
|
||||
if (!fp) return NULL;
|
||||
if (mode[0] == 'a') fseek(fp, 0L, SEEK_SET);
|
||||
zip *z = zip_open_handle(fp, mode);
|
||||
if (!z) return fclose(fp), NULL;
|
||||
return z;
|
||||
}
|
||||
|
||||
void zip_close(zip* z) {
|
||||
|
@ -235052,8 +235074,8 @@ void zip_close(zip* z) {
|
|||
// flush end record
|
||||
fwrite(&end, 1, sizeof(end), z->out);
|
||||
}
|
||||
if( z->out ) fclose(z->out);
|
||||
if( z->in ) fclose(z->in);
|
||||
if( z->out ) zip_unlockfile(z->out), fclose(z->out);
|
||||
if( z->in ) zip_unlockfile(z->in), fclose(z->in);
|
||||
// clean up
|
||||
for(unsigned i = 0; i < z->count; ++i ) {
|
||||
REALLOC(z->entries[i].filename, 0);
|
||||
|
@ -312563,7 +312585,7 @@ struct xml *xml_parse(char *s, int preserve_white, char **errorp)
|
|||
|
||||
static inline void array_find_and_remove(array(int) arr, int v) {
|
||||
for( int i = 0, end = array_count(arr); i < end; i++ )
|
||||
if( arr[i] == v ) { array_erase(arr, i); --end; break; }
|
||||
if( arr[i] == v ) { array_erase_fast(arr, i); --end; break; }
|
||||
}
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -312677,7 +312699,7 @@ static void RemoveIfNonNeighbor_(struct mesh *M, struct vertex *v, int id) {
|
|||
return;
|
||||
}
|
||||
// remove from neighbors
|
||||
array_erase(v->neighbor, i);
|
||||
array_erase_fast(v->neighbor, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
188
engine/v4k.c
188
engine/v4k.c
|
@ -969,6 +969,8 @@ const struct in6_addr in6addr_loopback; /* ::1 */
|
|||
#define chdir ifdef(cl, _chdir, chdir)
|
||||
#if is(cl) || is(tcc)
|
||||
#define ftruncate _chsize_s
|
||||
#define flockfile ifdef(cl,_lock_file,(void))
|
||||
#define funlockfile ifdef(cl,_unlock_file,(void))
|
||||
#endif
|
||||
#else // gcc
|
||||
//#include <alloca.h> // mingw64 does not have it
|
||||
|
@ -1331,8 +1333,8 @@ int audio_init( int flags ) {
|
|||
ma_backend_wasapi, // Higest priority.
|
||||
ma_backend_dsound,
|
||||
ma_backend_winmm,
|
||||
ma_backend_pulseaudio,
|
||||
ma_backend_coreaudio,
|
||||
ma_backend_pulseaudio,
|
||||
ma_backend_alsa,
|
||||
ma_backend_oss,
|
||||
ma_backend_jack,
|
||||
|
@ -4230,7 +4232,7 @@ int zipscan_diff( zip* old, array(struct fs) now ) {
|
|||
uint64_t oldstamp = atoi64(zip_modt(old,found)+20); // format is "YYYY/MM/DD hh:mm:ss", then +20 chars later a hidden epoch timestamp in base10 can be found
|
||||
int64_t diffstamp = oldstamp < now[i].stamp ? now[i].stamp - oldstamp : oldstamp - now[i].stamp;
|
||||
if( oldsize != now[i].bytes || diffstamp > 1 ) { // @fixme: should use hash instead. hashof(tool) ^ hashof(args used) ^ hashof(rawsize) ^ hashof(rawdate)
|
||||
printf("%s:\t%u vs %u, %llu vs %llu\n", now[i].fname, (unsigned)oldsize,(unsigned)now[i].bytes, oldstamp,now[i].stamp);
|
||||
printf("%s:\t%u vs %u, %llu vs %llu\n", now[i].fname, (unsigned)oldsize,(unsigned)now[i].bytes, (long long unsigned)oldstamp, (long long unsigned)now[i].stamp);
|
||||
array_push(changed, STRDUP(now[i].fname));
|
||||
array_push(uncooked, STRDUP(now[i].fname));
|
||||
}
|
||||
|
@ -4526,8 +4528,8 @@ bool cook_start( const char *cook_ini, const char *masks, int flags ) {
|
|||
// scan disk: all subfolders in ART (comma-separated)
|
||||
static array(char *) list = 0; // @leak
|
||||
for each_substring(ART, ",", art_folder) {
|
||||
const char **glob = file_list(art_folder, "**");
|
||||
for( unsigned i = 0; glob[i]; ++i ) {
|
||||
array(char *) glob = file_list(va("%s**",art_folder)); // art_folder ends with '/'
|
||||
for( unsigned i = 0, end = array_count(glob); i < end; ++i ) {
|
||||
const char *fname = glob[i];
|
||||
if( !strmatchi(fname, masks)) continue;
|
||||
|
||||
|
@ -4547,8 +4549,13 @@ bool cook_start( const char *cook_ini, const char *masks, int flags ) {
|
|||
if( !memcmp(header, "\x64\x86", 2) ) continue;
|
||||
if( !memcmp(header, "\x00\x00", 2) ) continue;
|
||||
}
|
||||
// exclude vc/gcc files
|
||||
if( strend(fname, ".a") || strend(fname, ".pdb") || strend(fname, ".lib") || strend(fname, ".ilk") || strend(fname, ".exp") ) {
|
||||
|
||||
char *dot = strrchr(fname, '.');
|
||||
if( dot ) {
|
||||
char extdot[32];
|
||||
snprintf(extdot, 32, "%s.", dot); // .png -> .png.
|
||||
// exclude vc/gcc/clang files
|
||||
if( strstr(fname, ".a.o.pdb.lib.ilk.exp.dSYM.") ) // must end with dot
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4609,8 +4616,7 @@ void cook_stop() {
|
|||
if(jobs[i].self) thread_join(jobs[i].self);
|
||||
}
|
||||
// remove all temporary outfiles
|
||||
const char **temps = file_list("./", "temp_*");
|
||||
for( int i = 0; temps[i]; ++i ) unlink(temps[i]);
|
||||
for each_array(file_list("temp_*"), char*, tempfile) unlink(tempfile);
|
||||
}
|
||||
|
||||
int cook_progress() {
|
||||
|
@ -5059,7 +5065,8 @@ bool file_append(const char *name, const void *ptr, int len) {
|
|||
}
|
||||
return ok;
|
||||
}
|
||||
static bool file_stat(const char *fname, struct stat *st) {
|
||||
static // not exposed
|
||||
bool file_stat(const char *fname, struct stat *st) {
|
||||
// remove ending slashes. win32+tcc does not like them.
|
||||
int l = strlen(fname), m = l;
|
||||
while( l && (fname[l-1] == '/' || fname[l-1] == '\\') ) --l;
|
||||
|
@ -5180,7 +5187,7 @@ char *ext = strrchr(base, '.'); //if (ext) ext[0] = '\0'; // remove all extensio
|
|||
}
|
||||
return va("%s", buffer);
|
||||
}
|
||||
const char** file_list(const char *cwds, const char *masks) {
|
||||
array(char*) file_list(const char *pathmasks) {
|
||||
static __thread array(char*) list = 0; // @fixme: should we add 16 slots in here similar to what we do in va() ?
|
||||
|
||||
for( int i = 0; i < array_count(list); ++i ) {
|
||||
|
@ -5188,7 +5195,16 @@ const char** file_list(const char *cwds, const char *masks) {
|
|||
}
|
||||
array_resize(list, 0);//array_free(list);
|
||||
|
||||
for each_substring(cwds,";",cwd) {
|
||||
for each_substring(pathmasks,";",pathmask) {
|
||||
char *cwd = 0, *masks = 0;
|
||||
char *slash = strrchr(pathmask, '/');
|
||||
if( !slash ) cwd = "./", masks = pathmask;
|
||||
else {
|
||||
masks = va("%s", slash+1);
|
||||
cwd = pathmask, slash[1] = '\0';
|
||||
}
|
||||
if( !masks[0] ) masks = "*";
|
||||
|
||||
ASSERT(strend(cwd, "/"), "Error: dirs like '%s' must end with slash", cwd);
|
||||
|
||||
dir *d = dir_open(cwd, strstr(masks,"**") ? "r" : "");
|
||||
|
@ -5216,8 +5232,7 @@ const char** file_list(const char *cwds, const char *masks) {
|
|||
}
|
||||
}
|
||||
|
||||
array_push(list, 0); // terminator
|
||||
return (const char**)list;
|
||||
return list;
|
||||
}
|
||||
|
||||
bool file_move(const char *src, const char *dst) {
|
||||
|
@ -5564,15 +5579,8 @@ void vfs_reload() {
|
|||
#else
|
||||
// mount fused executables
|
||||
vfs_mount(va("%s%s%s", app_path(), app_name(), ifdef(win32, ".exe", "")));
|
||||
/* // old way
|
||||
for( int i = 0; i < JOBS_MAX; ++i) {
|
||||
if( vfs_mount(va(".art[%02x].zip", i)) ) continue;
|
||||
if( vfs_mount(va("%s[%02x].zip", app, i)) ) continue;
|
||||
if( vfs_mount(va("%s%02x.zip", app, i)) ) continue;
|
||||
// if( vfs_mount(va("%s.%02x", app, i)) ) continue;
|
||||
} */
|
||||
// faster way
|
||||
for( const char **file = file_list("./","*.zip"); *file; ++file) vfs_mount(*file);
|
||||
// mount all zipfiles
|
||||
for each_array( file_list("*.zip"), char*, file ) vfs_mount(file);
|
||||
#endif
|
||||
|
||||
// vfs_resolve() will use these art_folder locations as hints when cook-on-demand is in progress.
|
||||
|
@ -5585,7 +5593,7 @@ void vfs_reload() {
|
|||
|
||||
|
||||
|
||||
#define ARK1 'ArK\x1'
|
||||
#define ARK1 0x41724B31 // 'ArK1' in le, 0x314B7241 41 72 4B 31 otherwise
|
||||
#define ARK1_PADDING (512 - 40) // 472
|
||||
#define ARK_PRINTF(f,...) 0 // printf(f,__VA_ARGS__)
|
||||
#define ARK_SWAP32(x) (x)
|
||||
|
@ -5677,9 +5685,9 @@ const char** vfs_list(const char *masks) {
|
|||
|
||||
for each_substring(masks,";",it) {
|
||||
if( COOK_ON_DEMAND ) // edge case: any game using only vfs api + cook-on-demand flag will never find any file
|
||||
for(const char **items = file_list("./", it); *items; items++) {
|
||||
for each_array(file_list(it), char*, item) {
|
||||
// insert copy
|
||||
char *copy = STRDUP(*items);
|
||||
char *copy = STRDUP(item);
|
||||
array_push(list, copy);
|
||||
}
|
||||
|
||||
|
@ -5785,8 +5793,8 @@ if( found && *found == 0 ) {
|
|||
folder = file_path(pathfile);
|
||||
// ease folders reading by shortening them: /home/rlyeh/prj/v4k/art/demos/audio/coin.wav -> demos/audio/coin.wav
|
||||
// or C:/prj/v4k/engine/art/fonts/B612-BoldItalic.ttf -> fonts/B612-BoldItalic.ttf
|
||||
static array(char*) art_paths = 0;
|
||||
do_once for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem));
|
||||
static __thread array(char*) art_paths = 0;
|
||||
if(!art_paths) for each_substring(ART,",",stem) array_push(art_paths, STRDUP(stem));
|
||||
char* pretty_folder = "";
|
||||
if( folder ) for( int i = 0; i < array_count(art_paths); ++i ) {
|
||||
if( strbeg(folder, art_paths[i]) ) { pretty_folder = folder + strlen(art_paths[i]); break; }
|
||||
|
@ -5837,7 +5845,7 @@ if( found && *found == 0 ) {
|
|||
// this block saves some boot time (editor --cook-on-demand: boot 1.50s -> 0.90s)
|
||||
#if 1 // EXPERIMENTAL_DONT_COOK_NON_EXISTING_ASSETS
|
||||
static set(char*) disk = 0;
|
||||
if(!disk) { set_init_str(disk); for each_substring(ART,",",art_folder) for( const char **list = file_list(art_folder,"**"); *list; ++list) set_insert(disk, STRDUP(*list)); }
|
||||
if(!disk) { set_init_str(disk); for each_substring(ART,",",art_folder) for each_array(file_list(va("%s**", art_folder)), char*, item) set_insert(disk, STRDUP(item)); } // art_folder ends with '/'
|
||||
int found = !!set_find(disk, (char*)pathfile);
|
||||
if( found )
|
||||
#endif
|
||||
|
@ -5950,23 +5958,28 @@ const char *vfs_extract(const char *pathfile) { // extract a vfs file into the l
|
|||
// -----------------------------------------------------------------------------
|
||||
// cache
|
||||
|
||||
static thread_mutex_t cache_mutex; AUTORUN{ thread_mutex_init(&cache_mutex); }
|
||||
|
||||
void* cache_lookup(const char *pathfile, int *size) { // find key->value
|
||||
if( !MAX_CACHED_FILES ) return 0;
|
||||
void* data = 0;
|
||||
thread_mutex_lock(&cache_mutex);
|
||||
for(archive_dir *dir = dir_cache; dir; dir = dir->next) {
|
||||
if( !strcmp(dir->path, pathfile) ) {
|
||||
if(size) *size = dir->size;
|
||||
return dir->data;
|
||||
data = dir->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
thread_mutex_unlock(&cache_mutex);
|
||||
return data;
|
||||
}
|
||||
void* cache_insert(const char *pathfile, void *ptr, int size) { // append key/value; return LRU or NULL
|
||||
if( !MAX_CACHED_FILES ) return 0;
|
||||
if( !ptr || !size ) return 0;
|
||||
|
||||
// keep cached files within limits
|
||||
static thread_mutex_t mutex, *init = 0; if(!init) thread_mutex_init(init = &mutex);
|
||||
thread_mutex_lock(&mutex);
|
||||
thread_mutex_lock(&cache_mutex);
|
||||
|
||||
// append to cache
|
||||
archive_dir zero = {0}, *old = dir_cache;
|
||||
|
@ -5996,7 +6009,7 @@ void* cache_insert(const char *pathfile, void *ptr, int size) { // append key/va
|
|||
}
|
||||
}
|
||||
|
||||
thread_mutex_unlock(&mutex);
|
||||
thread_mutex_unlock(&cache_mutex);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
@ -10922,7 +10935,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
network_put(NETWORK_RANK, -1); /* unassigned until we connect successfully */
|
||||
int64_t socket = client_join(ip, port);
|
||||
if( socket >= 0 ) {
|
||||
PRINTF("Client connected, id %lld\n", socket);
|
||||
PRINTF("Client connected, id %d\n", (int)socket);
|
||||
network_put(NETWORK_LIVE, 1);
|
||||
network_put(NETWORK_RANK, socket);
|
||||
} else {
|
||||
|
@ -10939,7 +10952,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
network_put(NETWORK_RANK, -1); /* unassigned until we connect successfully */
|
||||
int64_t socket = client_join(ip, port);
|
||||
if( socket > 0 ) {
|
||||
PRINTF("Client connected, id %lld\n", socket);
|
||||
PRINTF("Client connected, id %d\n", (int)socket);
|
||||
network_put(NETWORK_LIVE, 1);
|
||||
network_put(NETWORK_RANK, socket);
|
||||
} else {
|
||||
|
@ -10950,7 +10963,7 @@ void network_create(unsigned max_clients, const char *ip, const char *port_, uns
|
|||
}
|
||||
}
|
||||
|
||||
PRINTF("Network rank:%lld ip:%s port:%lld\n", network_get(NETWORK_RANK), ip, network_get(NETWORK_PORT));
|
||||
PRINTF("Network rank:%u ip:%s port:%d\n", (unsigned)network_get(NETWORK_RANK), ip, (int)network_get(NETWORK_PORT));
|
||||
}
|
||||
|
||||
int64_t network_put(uint64_t key, int64_t value) {
|
||||
|
@ -11083,8 +11096,8 @@ char** server_poll(unsigned timeout_ms) {
|
|||
*(uint32_t*)&init_msg[0] = MSG_INIT;
|
||||
*(int64_t*)&init_msg[4] = client_id;
|
||||
server_send_bin(client_id, init_msg, 12);
|
||||
PRINTF("Client rank %lld for peer ::%s:%u\n", client_id, ip, event.peer->address.port);
|
||||
msg = va( "%d new client rank:%lld from ::%s:%u", 0, client_id, ip, event.peer->address.port );
|
||||
PRINTF("Client rank %u for peer ::%s:%u\n", (unsigned)client_id, ip, event.peer->address.port);
|
||||
msg = va( "%d new client rank:%u from ::%s:%u", 0, (unsigned)client_id, ip, event.peer->address.port );
|
||||
event.peer->data = (void*)client_id;
|
||||
break;
|
||||
|
||||
|
@ -11140,7 +11153,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
msg = va("%d %s", 0, va("%s", ptr));
|
||||
} break;
|
||||
default:
|
||||
msg = va("%d unk msg len:%u from rank:%lld ::%s:%u", -1, sz, (uint64_t)event.peer->data, ip, event.peer->address.port); /* @TODO: hexdump? */
|
||||
msg = va("%d unk msg len:%u from rank:%u ::%s:%u", -1, sz, (unsigned)(uintptr_t)event.peer->data, ip, event.peer->address.port); /* @TODO: hexdump? */
|
||||
break;
|
||||
}
|
||||
/* Clean up the packet now that we're done using it. */
|
||||
|
@ -11148,7 +11161,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
} break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
msg = va( "%d disconnect rank:%lld", 0, (uint64_t)event.peer->data);
|
||||
msg = va( "%d disconnect rank:%u", 0, (unsigned)(uintptr_t)event.peer->data);
|
||||
/* Reset the peer's client information. */
|
||||
FREE(event.peer->data);
|
||||
event.peer->data = NULL;
|
||||
|
@ -11157,7 +11170,7 @@ char** server_poll(unsigned timeout_ms) {
|
|||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
||||
msg = va( "%d timeout rank:%lld", 0, (uint64_t)event.peer->data);
|
||||
msg = va( "%d timeout rank:%u", 0, (unsigned)(uintptr_t)event.peer->data);
|
||||
FREE(event.peer->data);
|
||||
event.peer->data = NULL;
|
||||
server_drop_client_peer(event.peer);
|
||||
|
@ -12865,10 +12878,10 @@ AUTOTEST {
|
|||
|
||||
// iterate reflected struct
|
||||
for each_member("MyVec4", R) {
|
||||
printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||
// printf("+%s MyVec4.%s // %s\n", R->type, R->name, R->info);
|
||||
}
|
||||
|
||||
reflected_printf_all();
|
||||
// reflected_printf_all();
|
||||
}
|
||||
#line 0
|
||||
|
||||
|
@ -12979,9 +12992,10 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char
|
|||
|
||||
const char *glsl_version = ifdef(ems, "300 es", "150");
|
||||
|
||||
vs = vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : "");
|
||||
fs = fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : "");
|
||||
if (gs) gs = gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : "");
|
||||
if(gs)
|
||||
gs = gs && gs[0] == '#' && gs[1] == 'v' ? gs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, gs ? gs : "");
|
||||
vs = vs && vs[0] == '#' && vs[1] == 'v' ? vs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, vs ? vs : "");
|
||||
fs = fs && fs[0] == '#' && fs[1] == 'v' ? fs : va("#version %s\n%s\n%s", glsl_version, glsl_defines, fs ? fs : "");
|
||||
|
||||
#if is(ems)
|
||||
{
|
||||
|
@ -19513,9 +19527,10 @@ const char *app_path() { // @fixme: should return absolute path always. see tcc
|
|||
strcat(buffer, "..\\..\\");
|
||||
}
|
||||
#else // #elif is(linux)
|
||||
char path[21] = {0};
|
||||
char path[32] = {0};
|
||||
sprintf(path, "/proc/%d/exe", getpid());
|
||||
readlink(path, buffer, sizeof(buffer));
|
||||
if(strrchr(buffer,'/')) 1[strrchr(buffer,'/')] = '\0';
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
@ -20218,15 +20233,15 @@ int (PRINTF)(const char *text, const char *stack, const char *file, int line, co
|
|||
char *location = va("|%s|%s:%d", /*errno?strerror(errno):*/function, file, line);
|
||||
int cols = tty_cols() + 1 - (int)strlen(location);
|
||||
|
||||
static thread_mutex_t lock, *init = 0; if(!init) thread_mutex_init(init = &lock);
|
||||
thread_mutex_lock( &lock );
|
||||
flockfile(stdout);
|
||||
|
||||
tty_color(color);
|
||||
printf("\r%*.s%s", cols, "", location);
|
||||
printf("\r%07.3fs|%s%s", secs, text, stack);
|
||||
tty_color(0);
|
||||
|
||||
thread_mutex_unlock( &lock );
|
||||
funlockfile(stdout);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -20614,20 +20629,20 @@ static void nk_config_custom_fonts() {
|
|||
nk_glfw3_font_stash_begin(&nk_glfw, &atlas); // nk_sdl_font_stash_begin(&atlas);
|
||||
|
||||
// Default font(#1)...
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_REGULAR); data; data = 0 ) {
|
||||
int datalen = 0;
|
||||
for( char *data = vfs_load(UI_FONT_REGULAR, &datalen); data; data = 0 ) {
|
||||
float font_size = UI_FONT_REGULAR_SIZE;
|
||||
struct nk_font_config cfg = nk_font_config(font_size);
|
||||
cfg.oversample_v = 2;
|
||||
cfg.pixel_snap = 0;
|
||||
// win32: struct nk_font *arial = nk_font_atlas_add_from_file(atlas, va("%s/fonts/arial.ttf",getenv("windir")), font_size, &cfg); font = arial ? arial : font;
|
||||
// struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "nuklear/extra_font/DroidSans.ttf", font_size, &cfg); font = droid ? droid : font;
|
||||
struct nk_font *regular = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_REGULAR), font_size, &cfg); font = regular ? regular : font;
|
||||
struct nk_font *regular = nk_font_atlas_add_from_memory(atlas, data, datalen, font_size, &cfg); font = regular ? regular : font;
|
||||
}
|
||||
|
||||
// ...with icons embedded on it.
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_ICONS); data; data = 0 ) {
|
||||
for( char *data = vfs_load(UI_FONT_ICONS, &datalen); data; data = 0 ) {
|
||||
static const nk_rune icon_range[] = {UI_ICON_MIN, UI_ICON_MED /*MAX*/, 0};
|
||||
|
||||
struct nk_font_config cfg = nk_font_config(UI_ICON_FONTSIZE);
|
||||
|
@ -20643,12 +20658,12 @@ static void nk_config_custom_fonts() {
|
|||
cfg.oversample_v = 1;
|
||||
cfg.pixel_snap = 1;
|
||||
|
||||
struct nk_font *icons = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_ICONS), UI_ICON_FONTSIZE, &cfg);
|
||||
struct nk_font *icons = nk_font_atlas_add_from_memory(atlas, data, datalen, UI_ICON_FONTSIZE, &cfg);
|
||||
}
|
||||
|
||||
// Monospaced font. Used in terminals or consoles.
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_TERMINAL); data; data = 0 ) {
|
||||
for( char *data = vfs_load(UI_FONT_TERMINAL, &datalen); data; data = 0 ) {
|
||||
const float font_size = UI_FONT_REGULAR_SIZE;
|
||||
static const nk_rune icon_range[] = {32, 127, 0};
|
||||
|
||||
|
@ -20660,13 +20675,13 @@ static void nk_config_custom_fonts() {
|
|||
cfg.pixel_snap = 1;
|
||||
|
||||
// struct nk_font *proggy = nk_font_atlas_add_default(atlas, font_size, &cfg);
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_TERMINAL), font_size, &cfg);
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, datalen, font_size, &cfg);
|
||||
}
|
||||
|
||||
// Extra optional fonts from here...
|
||||
|
||||
for( char *data = vfs_read(UI_FONT_HEADING); data; data = 0 ) {
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, vfs_size(UI_FONT_HEADING), UI_FONT_HEADING_SIZE, 0); // font = bold ? bold : font;
|
||||
for( char *data = vfs_load(UI_FONT_HEADING, &datalen); data; data = 0 ) {
|
||||
struct nk_font *bold = nk_font_atlas_add_from_memory(atlas, data, datalen, UI_FONT_HEADING_SIZE, 0); // font = bold ? bold : font;
|
||||
}
|
||||
|
||||
nk_glfw3_font_stash_end(&nk_glfw); // nk_sdl_font_stash_end();
|
||||
|
@ -24293,11 +24308,16 @@ void window_color(unsigned color) {
|
|||
unsigned a = (color >> 24) & 255;
|
||||
winbgcolor = vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
||||
}
|
||||
static int has_icon;
|
||||
int window_has_icon() {
|
||||
return has_icon;
|
||||
}
|
||||
void window_icon(const char *file_icon) {
|
||||
unsigned len = file_size(file_icon); len = len ? len : vfs_size(file_icon);
|
||||
if( len ) {
|
||||
void *data = file_read(file_icon); data = data ? data : vfs_read(file_icon);
|
||||
if( data ) {
|
||||
int len = 0;
|
||||
void *data = vfs_load(file_icon, &len);
|
||||
if( !data ) data = file_read(file_icon), len = file_size(file_icon);
|
||||
|
||||
if( data && len ) {
|
||||
image_t img = image_from_mem(data, len, IMAGE_RGBA);
|
||||
if( img.w && img.h && img.pixels ) {
|
||||
GLFWimage images[1];
|
||||
|
@ -24305,11 +24325,11 @@ void window_icon(const char *file_icon) {
|
|||
images[0].height = img.h;
|
||||
images[0].pixels = img.pixels;
|
||||
glfwSetWindowIcon(window, 1, images);
|
||||
has_icon = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if is(win32)
|
||||
#if 0 // is(win32)
|
||||
HANDLE hIcon = LoadImageA(0, file_icon, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||
if( hIcon ) {
|
||||
HWND hWnd = glfwGetWin32Window(window);
|
||||
|
@ -24317,6 +24337,7 @@ void window_icon(const char *file_icon) {
|
|||
SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
has_icon = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -24682,7 +24703,7 @@ vec3 get_voxel_for_boid(float perception_radius, const boid_t *b) { // quantize
|
|||
|
||||
static
|
||||
void check_voxel_for_boids(float perception_radius, float blindspot_angledeg_compare_value, array(boid_t*) voxel_cached, array(nearby_boid_t) *result, const vec3 voxelPos, const boid_t *b) {
|
||||
for each_array_ptr(voxel_cached, const boid_t*, test) {
|
||||
for each_array_ptr(voxel_cached, boid_t*, test) {
|
||||
vec3 p1 = b->position;
|
||||
vec3 p2 = (*test)->position;
|
||||
vec3 vec = sub3(p2, p1);
|
||||
|
@ -24695,7 +24716,7 @@ void check_voxel_for_boids(float perception_radius, float blindspot_angledeg_com
|
|||
compare_value = dot3(neg3(b->velocity), vec) / (l1 * l2);
|
||||
}
|
||||
|
||||
if ((&b) != test && distance <= perception_radius && (blindspot_angledeg_compare_value > compare_value || len3(b->velocity) == 0)) {
|
||||
if (b != (*test) && distance <= perception_radius && (blindspot_angledeg_compare_value > compare_value || len3(b->velocity) == 0)) {
|
||||
nearby_boid_t nb;
|
||||
nb.boid = (boid_t*)*test;
|
||||
nb.distance = distance;
|
||||
|
@ -25258,7 +25279,7 @@ int pathfind_astar(int width, int height, const unsigned* map, vec2i src, vec2i
|
|||
// [ ] CompareKeys(keyVar1, operator < <= > >= == !=, keyVar2)
|
||||
// [ ] SetTags(names=blank,cooldownTime=inf,bIsCooldownAdditive=false)
|
||||
// [ ] HasTags(names=blank,bAllRequired=true)
|
||||
// [ ] PushToStack(keyVar,itemObj): creates a new stack if one doesn’t exist, and stores it in the passed variable name, and then pushes ‘item’ object onto it.
|
||||
// [ ] PushToStack(keyVar,itemObj): creates a new stack if one doesn't exist, and stores it in the passed variable name, and then pushes 'item' object onto it.
|
||||
// [ ] PopFromStack(keyVar,itemVar): pop pops an item off the stack, and stores it in the itemVar variable, failing if the stack is already empty.
|
||||
// [ ] IsEmptyStack(keyVar): checks if the stack passed is empty and returns success if it is, and failure if its not.
|
||||
// [ ] Communication Node: This is a type of action node that allows an AI agent to communicate with other agents or entities in the game world. The node takes an input specifying the message to be communicated and the recipient(s) of the message (wildmask,l/p/f/g prefixes). The node then sends the message to the designated recipient(s) and returns success when the communication is completed. This node can be useful for implementing behaviors that require the AI agent to coordinate with other agents or to convey information to the player. It could use a radius argument to specify the maximum allowed distance for the recipients.
|
||||
|
@ -25926,48 +25947,41 @@ int main() {
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void v4k_pre_init() {
|
||||
const char *appname = app_name();
|
||||
const char *appdir = app_path();
|
||||
window_icon(va("%s/%s.png", appdir, appname));
|
||||
ifdef(win32,window_icon(va("%s/%s.ico", appdir, appname)));
|
||||
window_icon(va("%s%s.png", app_path(), app_name()));
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
int i;
|
||||
#pragma omp parallel for
|
||||
for( i = 0; i <= 3; ++i) {
|
||||
for( i = 0; i <= 6; ++i) {
|
||||
/**/ if( i == 0 ) ddraw_init();// init this on thread#0 since it will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
else if( i == 1 ) sprite_init();
|
||||
else if( i == 2 ) profiler_init();
|
||||
else if( i == 3 ) storage_mount("save/"), storage_read(), touch_init(); // for ems
|
||||
else if( i == 4 ) audio_init(0);
|
||||
else if( i == 5 ) script_init(), kit_init(), midi_init();
|
||||
else if( i == 6 ) network_init();
|
||||
}
|
||||
|
||||
// window_swap();
|
||||
}
|
||||
static void v4k_post_init(float refresh_rate) {
|
||||
int i;
|
||||
|
||||
// cook cleanup
|
||||
cook_stop();
|
||||
|
||||
vfs_reload();
|
||||
|
||||
// init subsystems that depend on cooked assets now. ui_init() is special case and needs to be safely in single thread
|
||||
ui_init();
|
||||
// init subsystems that depend on cooked assets now
|
||||
|
||||
// init more subsystems; beware of VFS mounting, as some of these may need cooked assets at this point
|
||||
int i;
|
||||
#pragma omp parallel for
|
||||
for( i = 0; i <= 3; ++i) {
|
||||
/**/ if( i == 0 ) scene_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
else if( i == 1 ) audio_init(0); // initialize audio after cooking // reasoning for this: do not launch audio threads while cooks are in progress, so there is more cpu for cooking actually
|
||||
else if( i == 2 ) script_init(), kit_init(), midi_init();
|
||||
else if( i == 3 ) input_init(), network_init();
|
||||
for( i = 0; i <= 2; ++i ) {
|
||||
if(i == 0) ui_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
if(i == 0) scene_init(); // init these on thread #0, since both will be compiling shaders, and shaders need to be compiled from the very same thread than glfwMakeContextCurrent() was set up
|
||||
if(i == 1) input_init();
|
||||
if(i == 2) window_icon(va("%s.png", app_name()));
|
||||
}
|
||||
|
||||
const char *appname = app_name();
|
||||
window_icon(va("%s.png", appname));
|
||||
window_icon(va("%s.ico", appname));
|
||||
|
||||
// display window
|
||||
glfwShowWindow(window);
|
||||
glfwGetFramebufferSize(window, &w, &h); //glfwGetWindowSize(window, &w, &h);
|
||||
|
|
85
engine/v4k.h
85
engine/v4k.h
|
@ -123,8 +123,8 @@ extern "C" {
|
|||
#define ENABLE_LINUX_CALLSTACKS 0 ///+
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_TESTS
|
||||
#define ENABLE_TESTS 0 // ifdef(debug, 1, 0) ///+
|
||||
#ifndef ENABLE_AUTOTESTS
|
||||
#define ENABLE_AUTOTESTS ifdef(debug, 1, 0) ///+
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_RETAIL
|
||||
|
@ -215,15 +215,6 @@ extern "C" {
|
|||
#define ifdef_release ifdef_false
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
|
||||
#define ifdef_64 ifdef_true
|
||||
#define ifdef_32 ifdef_false
|
||||
#else
|
||||
#define ifdef_64 ifdef_false
|
||||
#define ifdef_32 ifdef_true
|
||||
#endif
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#define ifdef_retail ifdef_true
|
||||
#else
|
||||
|
@ -236,6 +227,37 @@ extern "C" {
|
|||
#define ifdef_nocook ifdef_false
|
||||
#endif
|
||||
|
||||
#if defined NDEBUG && NDEBUG >= 3 // we use NDEBUG=[0,1,2,3] to signal the compiler optimization flags O0,O1,O2,O3
|
||||
#define ifdef_O3 ifdef_true
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_false
|
||||
#elif defined NDEBUG && NDEBUG >= 2
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_true
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_false
|
||||
#elif defined NDEBUG && NDEBUG >= 1
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_true
|
||||
#define ifdef_O0 ifdef_false
|
||||
#else
|
||||
#define ifdef_O3 ifdef_false
|
||||
#define ifdef_O2 ifdef_false
|
||||
#define ifdef_O1 ifdef_false
|
||||
#define ifdef_O0 ifdef_true
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#if (defined INTPTR_MAX && INTPTR_MAX == INT64_MAX) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__ppc64__) || __WORDSIZE == 64
|
||||
#define ifdef_64 ifdef_true
|
||||
#define ifdef_32 ifdef_false
|
||||
#else
|
||||
#define ifdef_64 ifdef_false
|
||||
#define ifdef_32 ifdef_true
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// new C keywords
|
||||
|
||||
|
@ -264,8 +286,13 @@ extern "C" {
|
|||
//-----------------------------------------------------------------------------
|
||||
// new C macros
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#define ASSERT(expr, ...) (void)0
|
||||
#define ASSERT_ONCE(expr, ...) (void)0
|
||||
#else
|
||||
#define ASSERT(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
|
||||
#define ASSERT_ONCE(expr, ...) do { int fool_msvc[] = {0,}; if(!(expr)) { fool_msvc[0]++; static int seen = 0; if(!seen) seen = 1, breakpoint(va("!Expression failed: " #expr " " FILELINE "\n" __VA_ARGS__)); } } while(0)
|
||||
#endif
|
||||
#define STATIC_ASSERT(EXPR) typedef struct { unsigned macro(static_assert_on_line_) : !!(EXPR); } macro(static_assert_on_line_)
|
||||
|
||||
#define FILELINE __FILE__ ":" STRINGIZE(__LINE__)
|
||||
|
@ -542,14 +569,16 @@ static __thread unsigned array_n_;
|
|||
} while(0)
|
||||
|
||||
#define array_foreach(t,val_t,v) for each_array(t,val_t,v)
|
||||
#define each_array(t,val_t,v) \
|
||||
( int __it = 0, __end = array_count(t); __it < __end; ++__it ) \
|
||||
for( val_t v = __it[t], *on__ = &v; on__; on__ = 0 )
|
||||
#define each_array(a,val_t,v) \
|
||||
( array(val_t) a_ = (a); a_; a_ = 0 ) \
|
||||
for( int i_ = 0, e_ = array_count(a_); i_ < e_; ++i_ ) \
|
||||
for( val_t v = i_[a_], *v_ = (void*)(uintptr_t)&v; v_; v_ = 0 )
|
||||
|
||||
#define array_foreach_ptr(t,val_t,v) for each_array_ptr(t,val_t,v)
|
||||
#define each_array_ptr(t,val_t,v) \
|
||||
( int __it = 0, __end = array_count(t); __it < __end; ++__it ) \
|
||||
for( val_t *v = (val_t*)&__it[t]; v; v = 0 )
|
||||
#define each_array_ptr(a,val_t,v) \
|
||||
( array(val_t) a_ = (a); a_; a_ = 0 ) \
|
||||
for( int i_ = 0, e_ = array_count(a_); i_ < e_; ++i_ ) \
|
||||
for( val_t *v = (val_t*)&i_[a_]; v; v = 0 )
|
||||
|
||||
#define array_search(t, key, cmpfn) /* requires sorted array beforehand */ \
|
||||
bsearch(&key, t, array_count(t), sizeof(t[0]), cmpfn )
|
||||
|
@ -565,13 +594,13 @@ static __thread unsigned array_n_;
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#define array_copy(t, src) do { /*todo: review old vrealloc call!*/ \
|
||||
#define array_copy(t, src) do { \
|
||||
array_free(t); \
|
||||
(t) = array_realloc_( (t), array_count(src)); \
|
||||
memcpy( (t), src, array_count(src) * sizeof(0[t])); \
|
||||
} while(0)
|
||||
|
||||
#define array_swapback_and_pop(t, i) do { /*may alter ordering*/ \
|
||||
#define array_erase_fast(t, i) do { /*may alter ordering*/ \
|
||||
memcpy( &(t)[i], &(t)[array_count(t) - 1], sizeof(0[t])); \
|
||||
array_pop(t); \
|
||||
} while(0)
|
||||
|
@ -1817,7 +1846,7 @@ API void kit_dump_state( FILE *fp );
|
|||
|
||||
// physical filesystem. files
|
||||
|
||||
API const char** file_list(const char *path, const char *masks); // **.png;*.c
|
||||
API array(char*) file_list( const char *pathmasks ); // folder/*.ico;**.png;*.c
|
||||
API bool file_write( const char *file, const void *ptr, int len );
|
||||
API bool file_append( const char *file, const void *ptr, int len );
|
||||
API char * file_read(const char *filename);
|
||||
|
@ -3796,18 +3825,13 @@ API void trap_on_debug(int signal); // helper util
|
|||
#define PANIC(...) PANIC(va(__VA_ARGS__), strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__, __LINE__) // die() ?
|
||||
API int (PANIC)(const char *error, const char *file, int line);
|
||||
|
||||
#if !ENABLE_RETAIL
|
||||
#define PRINTF(...) PRINTF(va(__VA_ARGS__), 1[#__VA_ARGS__] == '!' ? callstack(+48) : "", strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__, __LINE__, __FUNCTION__)
|
||||
API int (PRINTF)(const char *text, const char *stack, const char *file, int line, const char *function);
|
||||
|
||||
#define test(expr) test(strrchr(__FILE__, '/')?(strrchr(__FILE__, '/')+2):__FILE__,__LINE__,#expr,!!(expr))
|
||||
API int (test)(const char *file, int line, const char *expr, bool result);
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define test(expr)
|
||||
#endif
|
||||
|
||||
#if ENABLE_TESTS
|
||||
#if ENABLE_AUTOTESTS
|
||||
#define AUTOTEST AUTORUN
|
||||
#else
|
||||
#define AUTOTEST static void concat(concat(concat(disabled_test_, __LINE__), _), __COUNTER__)()
|
||||
|
@ -3815,6 +3839,12 @@ API int (test)(const char *file, int line, const char *expr, bool result);
|
|||
|
||||
// AUTOTEST { test(1<2); }
|
||||
|
||||
#if ENABLE_RETAIL
|
||||
#undef PRINTF
|
||||
#define PRINTF(...) 0
|
||||
#undef test
|
||||
#define test(expr) 0
|
||||
#endif
|
||||
#line 0
|
||||
|
||||
#line 1 "engine/split/v4k_ui.h"
|
||||
|
@ -3989,7 +4019,6 @@ API void window_loop(void (*function)(void* loopArg), void* loopArg ); // ru
|
|||
API void window_loop_exit(); // exit from main loop function (emscripten only)
|
||||
|
||||
API void window_title(const char *title);
|
||||
API void window_icon(const char *file_icon);
|
||||
API void window_color(unsigned color);
|
||||
API vec2 window_canvas();
|
||||
API void* window_handle();
|
||||
|
@ -4018,6 +4047,8 @@ API void window_maximize(int enabled);
|
|||
API int window_has_maximize();
|
||||
API void window_transparent(int enabled);
|
||||
API int window_has_transparent();
|
||||
API void window_icon(const char *file_icon);
|
||||
API int window_has_icon();
|
||||
|
||||
API double window_aspect();
|
||||
API void window_aspect_lock(unsigned numer, unsigned denom);
|
||||
|
|
Loading…
Reference in New Issue