2023-07-30 19:18:50 +00:00
// ----------------------------------------------------------------------------
2023-08-10 14:30:56 +00:00
static void v4k_pre_init ( ) {
2023-09-27 06:49:59 +00:00
const char * appname = app_name ( ) ;
window_icon ( va ( " %s.png " , appname ) ) ;
ifdef ( win32 , window_icon ( va ( " %s.ico " , appname ) ) ) ;
2023-07-30 19:18:50 +00:00
glfwPollEvents ( ) ;
int i ;
# pragma omp parallel for
for ( i = 0 ; i < = 3 ; + + 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 ( ) ;
2023-09-27 06:49:59 +00:00
else if ( i = = 2 ) profiler_init ( ) ;
2023-07-30 19:18:50 +00:00
else if ( i = = 3 ) storage_mount ( " save/ " ) , storage_read ( ) , touch_init ( ) ; // for ems
}
// window_swap();
}
2023-08-10 14:30:56 +00:00
static void v4k_post_init ( float refresh_rate ) {
2023-07-30 19:18:50 +00:00
// cook cleanup
cook_stop ( ) ;
vfs_reload ( ) ;
// init more subsystems; beware of VFS mounting, as some of these may need cooked assets at this point
int i ;
# if 1 // #ifdef PARALLEL_INIT
# pragma omp parallel for
# endif
for ( i = 0 ; i < = 3 ; + + i ) {
/**/ if ( i = = 0 ) ui_init ( ) , 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 ( ) ;
}
// @todo
// window_icon(vfs_file(va("%s.png", app)));
// window_icon(vfs_file(va("%s.ico", app)));
// display window
glfwShowWindow ( window ) ;
glfwGetFramebufferSize ( window , & w , & h ) ; //glfwGetWindowSize(window, &w, &h);
randset ( time_ns ( ) ) ;
boot_time = - time_ss ( ) ; // measure boot time, this is continued in window_stats()
// clean any errno setup by cooking stage
errno = 0 ;
hz = refresh_rate ;
// t = glfwGetTime();
}
// ----------------------------------------------------------------------------
static
2023-08-10 14:30:56 +00:00
void v4k_quit ( void ) {
2023-07-30 19:18:50 +00:00
storage_flush ( ) ;
midi_quit ( ) ;
}
2023-08-10 14:30:56 +00:00
void v4k_init ( ) {
2023-07-30 19:18:50 +00:00
do_once {
// install signal handlers
2023-10-07 17:34:09 +00:00
ifdef ( debug , trap_install ( ) ) ;
2023-07-30 19:18:50 +00:00
// init panic handler
panic_oom_reserve = SYS_REALLOC ( panic_oom_reserve , 1 < < 20 ) ; // 1MiB
// init glfw
glfw_init ( ) ;
// enable ansi console
tty_init ( ) ;
// chdir to root (if invoked as tcc -g -run)
chdir ( app_path ( ) ) ;
2023-08-10 14:30:56 +00:00
// skip tcc argvs (if invoked as tcc file.c v4k.c -g -run) (win)
2023-07-30 19:18:50 +00:00
if ( __argc > 1 ) if ( strstr ( __argv [ 0 ] , " /tcc " ) | | strstr ( __argv [ 0 ] , " \\ tcc " ) ) {
__argc = 0 ;
}
// create or update cook.zip file
if ( /* !COOK_ON_DEMAND && */ file_exist ( COOK_INI ) & & cook_jobs ( ) ) {
cook_start ( COOK_INI , " ** " , 0 | COOK_ASYNC | COOK_CANCELABLE ) ;
}
2023-08-10 14:30:56 +00:00
atexit ( v4k_quit ) ;
2023-07-30 19:18:50 +00:00
}
}
// Enable more performant GPUs on laptops. Does this work into a dll?
// int NvOptimusEnablement = 1;
// int AmdPowerXpressRequestHighPerformance = 1;
# if is(linux) && is(tcc) // fixes `tcc: error: undefined symbol '__dso_handle'`
2023-08-10 14:30:56 +00:00
int __dso_handle ; // compiled with: `tcc demo.c v4k.c -D__STDC_NO_VLA__ -lX11`
2023-07-30 19:18:50 +00:00
# endif
# if is(win32) && is(tcc) // fixes `tcc: error: undefined symbol '_InterlockedExchangeAdd'` when compiling with `-m64` flag
__CRT_INLINE LONG _InterlockedExchangeAdd ( LONG volatile * add , LONG val ) {
LONG old ;
do old = * add ; while ( InterlockedCompareExchange ( add , old + val , old ) ! = old ) ;
return old ;
}
__CRT_INLINE LONGLONG _InterlockedExchangeAdd64 ( LONGLONG volatile * add , LONGLONG val ) { // 64bit version, for completeness
LONGLONG old ;
do old = * add ; while ( InterlockedCompareExchange64 ( add , old + val , old ) ! = old ) ;
return old ;
}
# endif
# ifdef ZIG_CC
static int IN6_IS_ADDR_V4MAPPED ( const struct in6_addr * a ) { return ( ( a - > s6_words [ 0 ] = = 0 ) & & ( a - > s6_words [ 1 ] = = 0 ) & & ( a - > s6_words [ 2 ] = = 0 ) & & ( a - > s6_words [ 3 ] = = 0 ) & & ( a - > s6_words [ 4 ] = = 0 ) & & ( a - > s6_words [ 5 ] = = 0xffff ) ) ; }
const struct in6_addr in6addr_any ; // = IN6ADDR_ANY_INIT;
//static const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
# endif