From 40dd4aca96d288262f07bd8b0d81aa6c98cc11d5 Mon Sep 17 00:00:00 2001 From: hgn Date: Mon, 29 Dec 2025 23:46:56 +0000 Subject: [PATCH] mor eidoloegy --- source/async/async.kv | 9 +- source/console/console_system.c | 22 +- source/engine/engine.kv | 483 ++++++++--------------------- source/engine/vg_audio.c | 1 - source/engine/vg_engine.c | 210 ++++++++----- source/engine/vg_engine.h | 12 +- source/engine/vg_entity.c | 5 + source/engine/vg_entity.h | 112 ++++--- source/engine/vg_framebuffer.c | 1 - source/engine/vg_material.c | 21 +- source/engine/vg_material.h | 3 +- source/engine/vg_model.c | 7 - source/engine/vg_tex.c | 13 +- source/engine/vg_ui.c | 58 +++- source/foundation/foundation.h | 30 +- source/foundation/foundation.kv | 5 +- source/foundation/sort.c | 12 + source/graphics/ui.c | 528 +++++++++++++++++++++++++++++--- source/graphics/vg_graphics.h | 60 +++- source/tools/metacompiler.c | 97 ++++-- source/types.h | 72 +++++ 21 files changed, 1111 insertions(+), 650 deletions(-) create mode 100644 source/foundation/sort.c diff --git a/source/async/async.kv b/source/async/async.kv index bb3a9a8..ddd77f7 100644 --- a/source/async/async.kv +++ b/source/async/async.kv @@ -2,7 +2,7 @@ include "" test_feature { - feature SDL + feature FEATURE_SDL yes { add sdl_async.c @@ -12,10 +12,3 @@ test_feature } } - -hook -{ - affinity -20000 - event START - function _async_init -} diff --git a/source/console/console_system.c b/source/console/console_system.c index 7545f76..39d365d 100644 --- a/source/console/console_system.c +++ b/source/console/console_system.c @@ -4,13 +4,7 @@ struct console_item { const c8 *alias; - enum console_item_type - { - k_console_item_ccmd, - k_console_item_cvar_i32, - k_console_item_cvar_f32 - } - type; + enum data_type type; union { @@ -118,7 +112,7 @@ void _console_execute( const c8 *command, b8 silent, b8 cheat_allowed ) if( target_command ) { - if( target_command->type == k_console_item_ccmd ) + if( target_command->type == k_data_type_function ) target_command->fn( &args ); else { @@ -128,31 +122,35 @@ void _console_execute( const c8 *command, b8 silent, b8 cheat_allowed ) struct stream string; stream_open_buffer_read( &string, set_to, buffer_last_index( set_to, 0, 0 ), 0 ); - if( target_command->type == k_console_item_cvar_f32 ) + if( target_command->type == k_data_type_f32 ) { f64 f; if( string_parse_f64( &string, &f ) == k_string_parse_ok ) *target_command->_f32 = f; } - if( target_command->type == k_console_item_cvar_i32 ) + else if( target_command->type == k_data_type_i32 ) { i64 i; if( string_parse_i64( &string, &i ) == k_string_parse_ok ) *target_command->_i32 = i; } + else + ASSERT_CRITICAL( 0 ); $log( $info, {"Value set"} ); } else { - if( target_command->type == k_console_item_cvar_f32 ) + if( target_command->type == k_data_type_f32 ) { $log( $info, {"The value of "}, {target_command->alias}, {"(f32) is: "}, $float( *target_command->_f32 ) ); } - else if( target_command->type == k_console_item_cvar_i32 ) + else if( target_command->type == k_data_type_i32 ) { $log( $info, {"The value of "}, {target_command->alias}, {"(i32) is: "}, $signed( *target_command->_i32 ) ); } + else + ASSERT_CRITICAL( 0 ); } } } diff --git a/source/engine/engine.kv b/source/engine/engine.kv index 8098572..b4b1417 100644 --- a/source/engine/engine.kv +++ b/source/engine/engine.kv @@ -5,27 +5,34 @@ include ../../submodules/SDL/include test_feature { - feature web + feature FEATURE_OPENGL yes { - include ../../dep/glad-3.1-es/ - add ../../dep/glad-3.1-es/glad.c - } - no - { - include ../../dep/glad.4.3/ - add ../../dep/glad.4.3/glad.c + test_feature + { + feature PLATFORM_WEB + + yes + { + include ../../dep/glad-3.1-es/ + add ../../dep/glad-3.1-es/glad.c + } + no + { + include ../../dep/glad.4.3/ + add ../../dep/glad.4.3/glad.c + } + } } } -enable SDL +enable FEATURE_SDL append ../foundation/foundation.kv add vg_engine.c add vg_ui.c add vg_input.c -add vg_asset.c ccmd { @@ -57,9 +64,6 @@ ccmd append ../console/console_system.kv add vg_console.c -add vg_framebuffer.c -add vg_render.c -add vg_shader.c input_layer { @@ -203,370 +207,151 @@ input layer_mask ui } -shader -{ - name invisible -} - -shader +test_feature { - name blit - - subshader + feature FEATURE_OPENGL + yes { - type vertex - add shaders/blit.vs - - uniform + add vg_asset.c + add vg_framebuffer.c + add vg_render.c + add vg_shader.c + shader { - type vec2 - alias uInverseRatio + name invisible } - uniform + shader { - type int - alias uFlip + name blit + subshader + { + type vertex + add shaders/blit.vs + uniform + { + type vec2 + alias uInverseRatio + } + uniform + { + type int + alias uFlip + } + } + subshader + { + type fragment + add shaders/blit_tex.fs + uniform + { + type sampler2D + alias uTexMain + } + uniform + { + type int + alias uSwapRGBA + } + } } - } - - subshader - { - type fragment - add shaders/blit_tex.fs - - uniform + shader { - type sampler2D - alias uTexMain + name blit_colour + subshader + { + type vertex + add shaders/blit_colour.vs + } + subshader + { + type fragment + add shaders/blit_colour.fs + uniform + { + type vec4 + alias uColour + } + } } - uniform + ccmd { - type int - alias uSwapRGBA + name reload_shaders + function _shader_recompile_ccmd + description "Recompile shaders (DEVELOPER ONLY!)" } - } -} -shader -{ - name blit_colour - subshader - { - type vertex - add shaders/blit_colour.vs - } - - subshader - { - type fragment - add shaders/blit_colour.fs - - uniform + add vg_camera.c + add vg_tex.c + add vg_lines.c + cvar { - type vec4 - alias uColour + name vg_lines_enable + type i32 + default 0 + cheat 1 + description "Show line debuggers" } - } -} - -ccmd -{ - name reload_shaders - function _shader_recompile_ccmd - description "Recompile shaders (DEVELOPER ONLY!)" -} - -add vg_camera.c -add vg_tex.c -add vg_lines.c -cvar -{ - name vg_lines_enable - type i32 - default 0 - cheat 1 - description "Show line debuggers" -} -shader -{ - name debug_lines - subshader - { - type vertex - add shaders/debug_lines.vs - uniform + shader { - type mat4 - alias uPv + name debug_lines + subshader + { + type vertex + add shaders/debug_lines.vs + uniform + { + type mat4 + alias uPv + } + } + subshader + { + type fragment + add shaders/debug_lines.fs + } } - } - subshader - { - type fragment - add shaders/debug_lines.fs - } -} - - -add vg_audio.c -add vg_audio_dsp.c -add vg_audio_vorbis.c -cvar -{ - name vg_audio - type i32 - default 0 - cheat 1 - description "Show audio info" -} - -add vg_model.c -add vg_material.c -add vg_entity.c -add vg_metascene.c -add vg_af.c - -entity -{ - name ent_spawn - id 2 - - parameter - { - name transform - type transform - } - parameter - { - name name - type pstr - } - parameter - { - name flags - type u32 - flag + add vg_model.c + add vg_material.c + add vg_entity.c + add vg_metascene.c + add vg_af.c + entity { - name locked - value 0x1 + name ent_audio + id 7 } - flag + entity { - name group1 - value 0x2 + name ent_cubemap + id 21 } - flag + entity { - name group2 - value 0x4 + name ent_prop + id 23 } - flag + entity { - name group3 - value 0x8 + name mdl_armature + id 28 } } - function - { - name lantern - } - function - { - name boat - } - function - { - name me - } -} -entity -{ - name ent_water - id 5 - function - { - name enable - } - function - { - name disable - } - function - { - name show - } } -entity -{ - name ent_volume - id 6 - function - { - name enable - } - function - { - name disable - } -} -entity -{ - name ent_audio - id 7 -} -entity -{ - name ent_marker - id 8 - function - { - name push - } - function - { - name tooltip - } - function - { - name tooltip_special - } -} -entity -{ - name ent_camera - id 13 - function - { - name focus - } - function - { - name unfocus - } -} -entity -{ - name ent_ccmd - id 17 - function - { - name exec - } -} -entity -{ - name ent_cubemap - id 21 -} -entity -{ - name ent_prop - id 23 -} -entity -{ - name ent_armature - id 28 -} -entity -{ - name ent_atom - id 30 - function - { - name pass_equal - } - function - { - name pass_greater - } - function - { - name set - } - function - { - name set_or - } - function - { - name set_and - } -} -entity -{ - name ent_cutscene - id 31 - function - { - name play - } - function - { - name pause - } - function - { - name resume - } - function - { - name end - } -} -entity -{ - name ent_light - id 32 - parameter - { - name transform - type transform - } - parameter - { - name flags - type u32 - flag - { - name daytime - value 0x1 - } - flag - { - name off - value 0x2 - } - } - parameter - { - name type - type u32 - } - parameter - { - name colour - type vec4 - ui rgbe - } - parameter - { - name angle - type f32 - } - parameter - { - name range - type f32 - } - - function +test_feature +{ + feature FEATURE_AUDIO + yes { - name on - argument + add vg_audio.c + add vg_audio_dsp.c + add vg_audio_vorbis.c + cvar { - name enable + name vg_audio type i32 + default 0 + cheat 1 + description "Show audio info" } } } diff --git a/source/engine/vg_audio.c b/source/engine/vg_audio.c index f9f478c..9cbccee 100644 --- a/source/engine/vg_audio.c +++ b/source/engine/vg_audio.c @@ -16,7 +16,6 @@ SDL_Mutex *_audio_mutex; _Thread_local static b8 _audio_have_lock = 0; -static f32 _master_volume = 1.0f; enum channel_stage { diff --git a/source/engine/vg_engine.c b/source/engine/vg_engine.c index f3ea97f..c1fbba0 100644 --- a/source/engine/vg_engine.c +++ b/source/engine/vg_engine.c @@ -4,27 +4,34 @@ #include #include #include "vg_input.h" -#include "vg_opengl.h" #include "vg_engine.h" #include "vg_ui.h" #include "vg_audio.h" #include "vg_graphics.h" -#include "vg_audio_dsp.h" -#include "vg_audio.h" -#include "vg_shader.h" -#include "vg_render.h" -#include "vg_tex.h" -#include "vg_material.h" -#include "vg_lines.h" -#include "vg_framebuffer.h" +#include "SDL3/SDL.h" + +#if defined( FEATURE_AUDIO ) +# include "vg_audio_dsp.h" +# include "vg_audio.h" +#endif + +#if defined( FEATURE_OPENGL ) +# include "vg_opengl.h" +# include "vg_shader.h" +# include "vg_render.h" +# include "vg_tex.h" +# include "vg_material.h" +# include "vg_lines.h" +# include "vg_framebuffer.h" +#endif #include "vg_console.h" // TODO: temp #include "console_system.h" -#if defined( __EMSCRIPTEN__ ) -#include -#include +#if defined( PLATFORM_WEB ) +# include +# include #endif struct _engine _engine; @@ -70,7 +77,8 @@ i32 _async_thread( void *_ ) return 0; } -#if !defined( __EMSCRIPTEN__ ) +#if defined( FEATURE_OPENGL ) +# if !defined( PLATFORM_WEB ) APIENTRY void _opengl_debug( GLenum source, GLenum type, GLuint id, @@ -85,11 +93,12 @@ APIENTRY void _opengl_debug( GLenum source, if( type == GL_DEBUG_TYPE_ERROR ) _fatal_exit(); } +# endif #endif #include -void _vg_engine_frame(void); +void _vg_engine_frame( b8 engine_update ); void _vg_engine_frame_web(void); f64 _fixed_time = 0.0, _fixed_accumulator = 0.0; @@ -111,35 +120,35 @@ i32 main( i32 argc, const c8 *argv[] ) _fatal_exit(); } +#if defined( FEATURE_AUDIO ) $log( $info, {"SDL_INIT_AUDIO"} ); SDL_InitSubSystem( SDL_INIT_AUDIO ); +#endif -#if 0 +#if defined( FEATURE_OPENGL ) + #if 0 $log( $info, {"SDL_INIT_GAMECONTROLLER"} ); SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER ); -#endif + #endif SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); -#if 0 - SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); - SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 ); -#endif -#if defined( __EMSCRIPTEN__ ) + #if defined( PLATFORM_WEB ) SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES ); -#else + #else SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 4 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_RELEASE_BEHAVIOR, SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH ); -#endif + #endif SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0 ); +#endif /* * Get monitor information @@ -164,13 +173,16 @@ i32 main( i32 argc, const c8 *argv[] ) _engine.h = 768; } -#if !defined( WIN32 ) && !defined( __EMSCRIPTEN__ ) +#if !defined( PLATFORM_WINDOWS ) && !defined( PLATFORM_WEB ) SDL_SetHint( "SDL_VIDEO_X11_XINERAMA", "1" ); SDL_SetHint( "SDL_VIDEO_X11_XRANDR", "0" ); SDL_SetHint( "SDL_VIDEO_X11_XVIDMODE", "0" ); #endif - u32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + u32 flags = SDL_WINDOW_RESIZABLE; +#if defined( FEATURE_OPENGL ) + flags |= SDL_WINDOW_OPENGL; +#endif #if 0 if( _vg_window.display_mode == k_vg_window_fullscreen ) @@ -198,6 +210,7 @@ i32 main( i32 argc, const c8 *argv[] ) SDL_SetWindowMaximumSize( _engine.window_handle, 1920*2, 1080*2 ); SDL_StopTextInput( _engine.window_handle ); +#if defined( FEATURE_OPENGL ) /* * OpenGL loading */ @@ -213,11 +226,11 @@ i32 main( i32 argc, const c8 *argv[] ) _fatal_exit(); } -#if defined( __EMSCRIPTEN__ ) + #if defined( PLATFORM_WEB ) if( !gladLoadGLES2Loader((GLADloadproc)SDL_GL_GetProcAddress) ) -#else + #else if( !gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress) ) -#endif + #endif { $log( $fatal, {"Glad Failed to initialize"} ); SDL_GL_DestroyContext( _engine.opengl_handle ); @@ -228,12 +241,15 @@ i32 main( i32 argc, const c8 *argv[] ) const c8 *glver = (const c8 *)glGetString( GL_VERSION ); $log( $ok, {"Load setup complete, OpenGL version: "}, {glver} ); -#if !defined( __EMSCRIPTEN__ ) + #if !defined( PLATFORM_WEB ) glEnable ( GL_DEBUG_OUTPUT ); glDebugMessageCallback( _opengl_debug, 0 ); -#endif + #endif SDL_GL_SetSwapInterval(0); /* disable vsync while loading */ +#else + $log( $ok, {"Load setup complete, no graphics acceleration enabled"} ); +#endif i32 rate = video_mode->refresh_rate; if( rate < 25 || rate > 300 ) @@ -244,28 +260,32 @@ i32 main( i32 argc, const c8 *argv[] ) f64 next_frame_time = 0.0; - /* ------------- */ mt_random_seed( &_engine.random, 887765 ); - _async_init(); +#if defined( FEATURE_AUDIO ) _dsp_init(); _audio_init(); +#endif _engine_ui_init(); _input_init(); _console_init(); _engine_console_init(); + +#if defined( FEATURE_OPENGL ) _vg_render_init(); _shader_init(); _vg_tex_init(); _vg_material_init(); _vg_lines_init(); +#endif + if( _vg_engine_hooks.start ) _vg_engine_hooks.start(); _async_thread_handle = SDL_CreateThread( _async_thread, "ASync thread", NULL ); -#if defined( __EMSCRIPTEN__ ) +#if defined( PLATFORM_WEB ) emscripten_set_main_loop( _vg_engine_frame_web, 0, 1 ); #else L_new_frame:; @@ -281,10 +301,11 @@ L_new_frame:; else { // FIXME: How do we fucking do a no op on web? -#if !defined( __EMSCRIPTEN__ ) +#if !defined( PLATFORM_WEB ) __asm__ __volatile__("pause\n"); #endif } + _vg_engine_frame( 0 ); goto L_new_frame; } @@ -293,7 +314,7 @@ L_new_frame:; if( _engine.time_delta > 1.0/24.0 ) _engine.time_delta = 1.0/24.0; _engine.time = now; next_frame_time = now + 1.0/_engine.framerate_limit; - _vg_engine_frame(); + _vg_engine_frame( 1 ); goto L_new_frame; #endif } @@ -305,56 +326,11 @@ void _vg_engine_frame_web(void) if( _engine.time_delta < 1.0/300.0 ) _engine.time_delta = 1.0/300.0; if( _engine.time_delta > 1.0/24.0 ) _engine.time_delta = 1.0/24.0; _engine.time = now; - - _vg_engine_frame(); + _vg_engine_frame( 1 ); } -void _vg_engine_frame(void) +void _vg_engine_frame( b8 engine_update ) { - while( _task_queue_process( 0 ) ) {} - - /* normal update */ - _input_update(); - _engine_console_update(); - if( _vg_engine_hooks.frame_start ) _vg_engine_hooks.frame_start(); - - /* fixed update */ - _fixed_accumulator += _engine.time_delta; - f64 actual_delta = _engine.time_delta, - actual_time = _engine.time; - _engine.time_delta = 1.0/60.0; - for( u32 i=0; i<8; i ++ ) - { - if( _fixed_accumulator >= 1.0/60.0 ) - { - _fixed_accumulator -= 1.0/60.0; - _fixed_time += _engine.time_delta; - _engine.time = _fixed_time; - if( _vg_engine_hooks.fixed_frame ) _vg_engine_hooks.fixed_frame(); - } - else break; - } - _engine.time = actual_time; - _engine.time_delta = actual_delta; - _engine.time_fixed_extrapolate = _fixed_accumulator;// / (1.0/60.0); - - i32 pw = _engine.w, ph = _engine.h; - //glfwGetFramebufferSize( _engine.window_handle, &_engine.w, &_engine.h ); - SDL_GetWindowSizeInPixels( _engine.window_handle, &_engine.w, &_engine.h ); - if( (pw != _engine.w) || (ph != _engine.h) ) - _framebuffer_resize(); - - if( _vg_engine_hooks.frame_render ) _vg_engine_hooks.frame_render(); - _engine_ui_pre_render(); - - if( _vg_engine_hooks.frame_ui ) _vg_engine_hooks.frame_ui(); - _engine_console_ui(); - _audio_gui(); - _engine_ui_post_render(); - - //glfwSwapBuffers(_engine.window_handle); - SDL_GL_SwapWindow( _engine.window_handle ); - SDL_Event e; while( SDL_PollEvent( &e ) ) { @@ -391,7 +367,7 @@ void _vg_engine_frame(void) else if( e.type == SDL_EVENT_MOUSE_MOTION ) { SDL_MouseMotionEvent *ev = (SDL_MouseMotionEvent *)&e; - _ui_set_mouse( ev->x / _engine_ui.divisor, ev->y / _engine_ui.divisor ); + _ui_set_mouse( ev->x / _engine_ui.divisor, ev->y / _engine_ui.divisor, 0 ); //FIXME: MODIFIERS } else if( e.type == SDL_EVENT_TEXT_INPUT ) { @@ -404,4 +380,72 @@ void _vg_engine_frame(void) } } } + + // TODO: is there an event for this? + i32 pw = _engine.w, ph = _engine.h; + SDL_GetWindowSizeInPixels( _engine.window_handle, &_engine.w, &_engine.h ); + if( (pw != _engine.w) || (ph != _engine.h) ) + { +#if defined( FEATURE_OPENGL ) + _framebuffer_resize(); +#endif + _engine.redraw = 1; + } + + if( engine_update ) + { + while( _task_queue_process( 0 ) ) {} + + /* normal update */ + _input_update(); + _engine_console_update(); + if( _vg_engine_hooks.frame_start ) _vg_engine_hooks.frame_start(); + + /* fixed update */ + _fixed_accumulator += _engine.time_delta; + f64 actual_delta = _engine.time_delta, + actual_time = _engine.time; + _engine.time_delta = 1.0/60.0; + for( u32 i=0; i<8; i ++ ) + { + if( _fixed_accumulator >= 1.0/60.0 ) + { + _fixed_accumulator -= 1.0/60.0; + _fixed_time += _engine.time_delta; + _engine.time = _fixed_time; + if( _vg_engine_hooks.fixed_frame ) _vg_engine_hooks.fixed_frame(); + } + else break; + } + _engine.time = actual_time; + _engine.time_delta = actual_delta; + _engine.time_fixed_extrapolate = _fixed_accumulator;// / (1.0/60.0); + _engine.redraw = 1; + } + + if( _engine.redraw ) + { + _engine.redraw = 0; + +#if !defined( FEATURE_OPENGL ) + _engine.surface_handle = SDL_GetWindowSurface( _engine.window_handle ); +#endif + + if( _vg_engine_hooks.frame_render ) _vg_engine_hooks.frame_render(); + _engine_ui_pre_render(); + if( _vg_engine_hooks.frame_ui ) _vg_engine_hooks.frame_ui(); + _engine_console_ui(); + +#if defined( FEATURE_AUDIO ) + _audio_gui(); +#endif + _engine_ui_post_render(); + + //glfwSwapBuffers(_engine.window_handle); +#if defined( FEATURE_OPENGL ) + SDL_GL_SwapWindow( _engine.window_handle ); +#else + ASSERT_CRITICAL( SDL_UpdateWindowSurface( _engine.window_handle ) ); +#endif + } } diff --git a/source/engine/vg_engine.h b/source/engine/vg_engine.h index ea1c8f4..f3689aa 100644 --- a/source/engine/vg_engine.h +++ b/source/engine/vg_engine.h @@ -1,5 +1,9 @@ #include "random.h" +#if !defined( FEATURE_OPENGL ) +# include "SDL3/SDL_surface.h" +#endif + struct _engine { b8 vsync; @@ -15,10 +19,14 @@ struct _engine quality; void *window_handle; +#if defined( FEATURE_OPENGL ) void *opengl_handle; - i32 w, h; - i32 native_fbo; +#else + SDL_Surface *surface_handle; +#endif + i32 w, h; + b8 redraw; struct mt_random random; } diff --git a/source/engine/vg_entity.c b/source/engine/vg_entity.c index 99aa597..14439ba 100644 --- a/source/engine/vg_entity.c +++ b/source/engine/vg_entity.c @@ -13,3 +13,8 @@ i32 _vg_entity_link_function( u16 entity_type, const c8 *alias ) $log( $error, {"Failed to link function from alias '"}, {alias}, {"'"} ); return -1; } + +struct entity_info *_vg_entity_info( u16 entity_type ) +{ + return &_entity_infos[ _vg_entity_type_index( entity_type ) ]; +} diff --git a/source/engine/vg_entity.h b/source/engine/vg_entity.h index 40e835b..be3ed18 100644 --- a/source/engine/vg_entity.h +++ b/source/engine/vg_entity.h @@ -1,6 +1,61 @@ #pragma once #include "vg_model.h" +enum entity_event_result +{ + k_entity_event_result_OK, + k_entity_event_result_unhandled, + k_entity_event_result_invalid, + k_entity_event_result_invalid_parameter, +}; + +struct ent_event +{ + u32 pstr_source_event; + u32 pstr_recieve_event; + + union entity_id source; + union entity_id reciever; + u16 data_type, unused2; + + f32 delay; + u8 function_index, activator, unused0, unused1; // FIXME: REPLACES PSTR!!!!!!!!!!! + + union + { + i32 const_i32; + f32 const_f32; + union entity_id const_entity_id; + u32 const_pstr; + } + data; +}; + +struct entity_info +{ + u16 id, size; + u16 function_start, function_count, parameter_start, parameter_count; + const c8 *name; +}; +struct entity_function_info +{ + const c8 *name; +}; +struct entity_parameter_info +{ + const c8 *name; + u16 type, offset; +}; + +// Generated +extern struct entity_info _entity_infos[]; +extern struct entity_parameter_info _entity_parameter_infos[]; + +u32 _vg_entity_type_index( u16 entity_type ); +struct entity_info *_vg_entity_info( u16 entity_type ); +enum entity_event_result _vg_entity_event_dispatch( struct ent_event *event ); +i32 _vg_entity_link_function( u16 entity_type, const c8 *alias ); + #include "generated/entities.h" #if 0 @@ -698,60 +753,3 @@ struct ent_npc struct mdl_transform transform; u32 pstr_id, pstr_context_id, pstr_anim, none1; }; - -enum entity_event_result -{ - k_entity_event_result_OK, - k_entity_event_result_unhandled, - k_entity_event_result_invalid, - k_entity_event_result_invalid_parameter, -}; - -enum ent_event_flags -{ - k_ent_event_data_void = 0x0, - k_ent_event_data_const_i32 = 0x1, - k_ent_event_data_const_f32 = 0x2, - k_ent_event_data_const_entity_id = 0x4, - k_ent_event_data_const_string = 0x8, - k_ent_event_data_data_alias = 0x10, - k_ent_event_data_v3f = 0x20, -}; - -struct ent_event -{ - u32 pstr_source_event; - u32 pstr_recieve_event; - - union entity_id source; - union entity_id reciever; - u32 flags; - - f32 delay; - u8 function_index, activator, unused0, unused1; // FIXME: REPLACES PSTR!!!!!!!!!!! - - union - { - i32 const_i32; - f32 const_f32; - union entity_id const_entity_id; - u32 const_pstr; - u32 pstr_data_alias; - } - data; -}; - -struct entity_info -{ - u16 id, unused0; - u16 function_start, function_count; - const c8 *name; -}; -struct entity_function_info -{ - const c8 *name; -}; - -struct entity_info *_vg_entity_info( u16 entity_type ); -enum entity_event_result _vg_entity_event_dispatch( struct ent_event *event ); -i32 _vg_entity_link_function( u16 entity_type, const c8 *alias ); diff --git a/source/engine/vg_framebuffer.c b/source/engine/vg_framebuffer.c index dbc288f..76d290a 100644 --- a/source/engine/vg_framebuffer.c +++ b/source/engine/vg_framebuffer.c @@ -375,7 +375,6 @@ void framebuffer_free( struct framebuffer *fb ) void _framebuffer_resize(void) { - $log( $info, {"Resizing framebuffers..."} ); ASSERT_CRITICAL( _thread_has_flags( _get_thread_id(), THREAD_FLAG_OPENGL ) ); for( i32 i=0; i<_framebuffer.count; i++ ) { diff --git a/source/engine/vg_material.c b/source/engine/vg_material.c index e56f230..bcac544 100644 --- a/source/engine/vg_material.c +++ b/source/engine/vg_material.c @@ -2,9 +2,6 @@ #include "vg_material.h" #include "vg_shader.h" -// FIXME!!!!!!!!!!!!!!!!!!!! QSORT -#include - struct { struct vg_asset_list asset_list; @@ -18,16 +15,6 @@ void _vg_material_init(void) vg_allocate_asset_list( &_vg_material.asset_list, VG_ASSET_MATERIALS_MAX ); } -i32 compar( const void *a, const void *b ) -{ - return ((struct sort_index *)a)->value - ((struct sort_index *)b)->value; -} - -void index_sort( struct sort_index *indices, u32 indice_count ) -{ - qsort( indices, indice_count, sizeof(struct sort_index), compar ); -} - u16 _vg_material_load( const c8 *path, struct stack_allocator *stack ) { u16 id = vg_asset_get( &_vg_material.asset_list, path ); @@ -45,6 +32,13 @@ u16 _vg_material_load( const c8 *path, struct stack_allocator *stack ) return 0; } + u32 flag_it = 0; + while( keyvalues_foreach( &material->kvs, &flag_it, 0, "renderflag" ) ) + { + const c8 *render_flag = keyvalues_value( &material->kvs, flag_it, NULL ); + if( compare_buffers( render_flag, 0, "additive", 0 ) ) material->flags |= VG_MATERIAL_ADDITIVE; + } + u32 tilemap_block = keyvalues_get( &material->kvs, 0, "tilemap", 0 ); if( tilemap_block ) { @@ -150,7 +144,6 @@ u16 _vg_material_load( const c8 *path, struct stack_allocator *stack ) } } - u32 shader_block = keyvalues_get_child( &material->kvs, 0, 0 ); if( shader_block ) { diff --git a/source/engine/vg_material.h b/source/engine/vg_material.h index cf99cc2..6c4c6f4 100644 --- a/source/engine/vg_material.h +++ b/source/engine/vg_material.h @@ -10,7 +10,8 @@ struct vg_material { - u16 shader_id, flags; + i16 shader_id; + u16 flags; struct keyvalues kvs; struct tex_tilemap tilemap; union diff --git a/source/engine/vg_model.c b/source/engine/vg_model.c index 262f56e..5ea1db9 100644 --- a/source/engine/vg_model.c +++ b/source/engine/vg_model.c @@ -441,13 +441,6 @@ void vg_model_bind_mesh( struct vg_model *model ) glBindVertexArray( model->vao ); } -#if 0 -void vg_model_draw_elements( u32 start, u32 count ) -{ - glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT, (void *)(start*sizeof(u32)) ); -} -#endif - void vg_model_draw_batch( struct mdl_batch *batch ) { glDrawElements( GL_TRIANGLES, batch->count, GL_UNSIGNED_INT, (void *)(u64)batch->offset ); diff --git a/source/engine/vg_tex.c b/source/engine/vg_tex.c index cabc08e..e7b2d77 100644 --- a/source/engine/vg_tex.c +++ b/source/engine/vg_tex.c @@ -494,13 +494,12 @@ u16 _vg_texture_load( const c8 *path, struct tex_tilemap *tilemap ) { for( i32 ox = -VG_TEX_TILEMAP_PADDING; ox < tileset->size[0] +VG_TEX_TILEMAP_PADDING; ox ++ ) { - i32 tile_i = tile_y*tileset->grid[0] + tile_x, - dst_x = tile->pixel_root[0] + ox, - dst_y = tile->pixel_root[1] + oy, - src_x = tileset->co[0] + tile_x*tileset->size[0] + i32_clamp( ox, 0, tileset->size[0]-1 ), - src_y = tileset->co[1] + tile_y*tileset->size[1] + i32_clamp( oy, 0, tileset->size[1]-1 ), - dst_i = (((tilemap->sheet_size[1] - dst_y) -1)*tilemap->sheet_size[0] + dst_x)*4, - src_i = (src_y*tilemap->image_size[0] + src_x)*4; + i32 dst_x = tile->pixel_root[0] + ox, + dst_y = tile->pixel_root[1] + oy, + src_x = tileset->co[0] + tile_x*tileset->size[0] + i32_clamp( ox, 0, tileset->size[0]-1 ), + src_y = tileset->co[1] + tile_y*tileset->size[1] + i32_clamp( oy, 0, tileset->size[1]-1 ), + dst_i = (((tilemap->sheet_size[1] - dst_y) -1)*tilemap->sheet_size[0] + dst_x)*4, + src_i = (src_y*tilemap->image_size[0] + src_x)*4; if( src_buffer[ src_i + 3 ] > 0 ) { diff --git a/source/engine/vg_ui.c b/source/engine/vg_ui.c index 91e755e..8e5ede3 100644 --- a/source/engine/vg_ui.c +++ b/source/engine/vg_ui.c @@ -1,15 +1,20 @@ #include "foundation.h" #include "vg_engine.h" #include "vg_graphics.h" -#include "vg_render.h" -#include "vg_opengl.h" -#include "vg_shader.h" #include "vg_ui.h" +#include "SDL3/SDL.h" -#if defined( __EMSCRIPTEN__ ) -# define PIXEL_FORMAT GL_RGBA +#if defined( FEATURE_OPENGL ) +# include "vg_render.h" +# include "vg_opengl.h" +# include "vg_shader.h" +# if defined( PLATFORM_WEB ) +# define PIXEL_FORMAT GL_RGBA +# else +# define PIXEL_FORMAT GL_BGRA +# endif #else -# define PIXEL_FORMAT GL_BGRA +# include "SDL3/SDL_surface.h" #endif struct graphics_target _ui_surface = @@ -19,13 +24,15 @@ struct graphics_target _ui_surface = }; struct _engine_ui _engine_ui; +#if defined( FEATURE_OPENGL ) static GLuint _ui_surface_texture; +#endif #include void _engine_ui_init(void) { _ui_surface.buffer = _heap_allocate( 1920*1080*4 ); - +#if defined( FEATURE_OPENGL ) glGenTextures( 1, &_ui_surface_texture ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, _ui_surface_texture ); @@ -34,6 +41,7 @@ void _engine_ui_init(void) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); +#endif } void _engine_ui_pre_render(void) @@ -59,6 +67,10 @@ void _engine_ui_pre_render(void) void _engine_ui_post_render(void) { + _ui_draw( (i16[]){ _engine_ui.w, _engine_ui.h } ); + + /* Copy via shader onto screen (with blending) */ +#if defined( FEATURE_OPENGL ) glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBlendEquation( GL_FUNC_ADD ); @@ -72,15 +84,39 @@ void _engine_ui_post_render(void) _shader_blit_uTexMain( 0 ); _shader_blit_uFlip( 1 ); _shader_blit_uInverseRatio( (f32[2]){ (f64)_engine_ui.w/1920.0, (f64)_engine_ui.h/1080.0 } ); -#if defined( __EMSCRIPTEN__ ) +# if defined( PLATFORM_WEB ) _shader_blit_uSwapRGBA( 1 ); -#endif +# endif _render_fullscreen_quad(); -#if defined( __EMSCRIPTEN__ ) +# if defined( PLATFORM_WEB ) _shader_blit_uSwapRGBA( 0 ); -#endif +# endif glDisable( GL_BLEND ); +#else + /* Copy to surface without any blending. We currently don't assume anything is under us. */ + SDL_Surface *surface = _engine.surface_handle; + + if( surface->format != SDL_PIXELFORMAT_XRGB8888 ) + { + $log( $error, {"Wrong pixel format. Got: "}, $unsigned( surface->format, .base=16 ) ); + } + ASSERT_CRITICAL( surface->format == SDL_PIXELFORMAT_XRGB8888 ); + ASSERT_CRITICAL( surface->pixels ); + + u8 *dest = surface->pixels; + for( i32 y=0; yh; y ++ ) + { + for( i32 x=0; xw; x ++ ) + { + dest[ y*surface->pitch + x*4 + 0 ] = _ui_surface.buffer[ (y*1920 + x)*4 + 0 ]; + dest[ y*surface->pitch + x*4 + 1 ] = _ui_surface.buffer[ (y*1920 + x)*4 + 1 ]; + dest[ y*surface->pitch + x*4 + 2 ] = _ui_surface.buffer[ (y*1920 + x)*4 + 2 ]; + dest[ y*surface->pitch + x*4 + 3 ] = _ui_surface.buffer[ (y*1920 + x)*4 + 3 ]; + } + } + +#endif static b8 want_text_prev = 0; b8 want_text = _ui_want_text(); diff --git a/source/foundation/foundation.h b/source/foundation/foundation.h index 89d9347..86194ca 100644 --- a/source/foundation/foundation.h +++ b/source/foundation/foundation.h @@ -1,15 +1,6 @@ /* Voyager common application interface */ #pragma once -#if 0 -#define VG_PRE_MAIN \ - _exit_init(); \ - _log_init(); \ - _options_init( argc, argv ); \ - EVENT_CALL( OPTIONS ); \ - _options_check_end(); -#endif - #define BYTES_KB( X ) X*1024 #define BYTES_MB( X ) X*1024*1024 #define BYTES_GB( X ) X*1024*1024*1024 @@ -121,7 +112,6 @@ struct pool_allocator struct pool_node *nodes; u32 count; }; -//void pool_init( struct pool_allocator *pool, struct pool_node *nodes, u16 node_count, struct pool_chain *full_chain ); u32 pool_index( struct pool_allocator *pool, u16 pool_id ); u16 pool_reference( struct pool_allocator *pool, u16 pool_id, b8 increment ); u16 pool_next( struct pool_allocator *pool, u16 pool_id, b8 right ); @@ -152,8 +142,8 @@ void *queue_tail_data( struct queue_allocator *queue ); u32 queue_offset( struct queue_allocator *queue, void *pointer ); /* warning: this is not the size but the allocation size (may be padded) */ u32 queue_item_size( struct queue_allocator *queue, u32 item_id ); -b8 queue_next( struct queue_allocator *queue, u32 item_id, u32 *out_next ); -b8 queue_previous( struct queue_allocator *queue, u32 item_id, u32 *out_prev ); +b8 queue_next( struct queue_allocator *queue, u32 item_id, u32 *out_next ); +b8 queue_previous( struct queue_allocator *queue, u32 item_id, u32 *out_prev ); void queue_pop( struct queue_allocator *queue ); void queue_copy_buffer( struct queue_allocator *queue, void *dst, u32 start, u32 size ); u32 queue_usage( struct queue_allocator *queue ); @@ -201,7 +191,7 @@ void stream_open_auto( struct stream *stream, u32 flags ); void stream_open_stack( struct stream *stream, struct stack_allocator *stack, u32 flags ); void stream_open_buffer_write( struct stream *stream, void *buffer, u32 buffer_length, u32 flags ); void stream_open_buffer_read( struct stream *stream, const void *buffer, u32 buffer_length, u32 flags ); -b8 stream_open_file( struct stream *stream, const c8 *path, u32 flags ); +b8 stream_open_file( struct stream *stream, const c8 *path, u32 flags ); void stream_close( struct stream *stream ); u32 stream_read( struct stream *stream, void *buffer, u32 length ); @@ -209,7 +199,7 @@ void *stream_read_all( struct stream *stream, struct stack_allocator *stack, u32 u32 stream_write( struct stream *stream, const void *buffer, u32 length ); u32 stream_offset( struct stream *stream ); void stream_seek( struct stream *stream, u32 offset ); -b8 stream_error( struct stream *stream ); +b8 stream_error( struct stream *stream ); /* String (Stream subset) * ------------------------------------------------------------------------------------------------------------------ */ @@ -232,7 +222,6 @@ struct v_string_arg i64 _i64; f64 _f64; }; - u32 type; u32 base; union @@ -270,6 +259,7 @@ enum string_parse_result string_parse_i64( struct stream *string, i64 *value ); enum string_parse_result string_parse_f64( struct stream *string, f64 *value ); enum string_parse_result string_parse_string( struct stream *string, u32 *out_start, u32 *out_length, c8 delimiter ); + /* Logging * ------------------------------------------------------------------------------------------------------------------ */ @@ -349,9 +339,9 @@ u32 keyvalues_get_child( struct keyvalues *kvs, u32 root_offset, u32 index ); b8 keyvalues_foreach( struct keyvalues *kvs, u32 *kv, u32 block, const c8 *alias ); const c8 *keyvalues_read_string( struct keyvalues *kvs, u32 root_offset, const c8 *key, const c8 *default_value ); -b8 keyvalues_read_i32s( struct keyvalues *kvs, u32 root_offset, const c8 *key, i32 *default_values, i32 *out_values, u32 len ); -b8 keyvalues_read_u32s( struct keyvalues *kvs, u32 root_offset, const c8 *key, u32 *default_values, u32 *out_values, u32 len ); -b8 keyvalues_read_f32s( struct keyvalues *kvs, u32 root_offset, const c8 *key, f32 *default_values, f32 *out_values, u32 len ); +b8 keyvalues_read_i32s( struct keyvalues *kvs, u32 root_offset, const c8 *key, i32 *default_values, i32 *out_values, u32 len ); +b8 keyvalues_read_u32s( struct keyvalues *kvs, u32 root_offset, const c8 *key, u32 *default_values, u32 *out_values, u32 len ); +b8 keyvalues_read_f32s( struct keyvalues *kvs, u32 root_offset, const c8 *key, f32 *default_values, f32 *out_values, u32 len ); u32 keyvalues_append_frame( struct keyvalues *kvs, u32 parent_offset, const c8 *key ); u32 keyvalues_append_string( struct keyvalues *kvs, u32 parent_offset, const c8 *key, const c8 *value ); u32 keyvalues_append_i32s( struct keyvalues *kvs, u32 parent_offset, const c8 *key, i32 *values, u32 len ); @@ -384,10 +374,6 @@ b8 directory_next_entry( struct directory *directory ); enum directory_entry_type directory_entry_type( struct directory *directory ); void directory_close( struct directory *directory ); -#define EVENT_CALL( NAME, ... ) \ - for( u32 ev_iter=0; _event_##NAME##_subscribers[ ev_iter ]; ev_iter ++ ) \ - _event_##NAME##_subscribers[ ev_iter ]( __VA_ARGS__ ); - struct sort_index { u32 index; diff --git a/source/foundation/foundation.kv b/source/foundation/foundation.kv index c4c4991..7b104af 100644 --- a/source/foundation/foundation.kv +++ b/source/foundation/foundation.kv @@ -11,10 +11,11 @@ add string.c add keyvalues.c add buffer_operations.c add temporary.c +add sort.c test_feature { - feature linux + feature PLATFORM_LINUX yes { add io.c @@ -29,7 +30,7 @@ test_feature test_feature { - feature SDL + feature FEATURE_SDL yes { add threads_sdl.c diff --git a/source/foundation/sort.c b/source/foundation/sort.c new file mode 100644 index 0000000..fbdc36e --- /dev/null +++ b/source/foundation/sort.c @@ -0,0 +1,12 @@ +#include +#include "foundation.h" + +i32 compar( const void *a, const void *b ) +{ + return ((struct sort_index *)a)->value - ((struct sort_index *)b)->value; +} + +void index_sort( struct sort_index *indices, u32 indice_count ) +{ + qsort( indices, indice_count, sizeof(struct sort_index), compar ); +} diff --git a/source/graphics/ui.c b/source/graphics/ui.c index 6ca6b68..b2a024b 100644 --- a/source/graphics/ui.c +++ b/source/graphics/ui.c @@ -3,16 +3,17 @@ #include "vg_input.h" #include "common_maths.h" -#define KEYBOARD_ALT 0x1 -#define KEYBOARD_SHIFT 0x2 -#define KEYBOARD_CAPSLOCK 0x4 -#define KEYBOARD_CONTROL 0x8 - struct { //i16 clipping_area[4]; - i16 mouse_co[2], mouse_co_clicked[2]; + u32 mouse_mods; + + i16 mouse_co_container_last[4], + mouse_co_container[4], + mouse_co_clicked_container_last[4], + mouse_co_clicked_container[4]; + b8 mouse_went_in_click_hole; /* internal state */ @@ -26,6 +27,7 @@ struct active_control_type; b8 active_control_touched; b8 redraw; + b8 fiddling; union { @@ -49,9 +51,25 @@ struct enum dropdown_action action; } dropdown; + + struct + { + u32 start_values[4]; + } + number; } controls; + struct + { + struct ui_panel panel; + enum data_type data_type; + void *value; + char buf[32]; + i16 co[2]; + } + fiddle; + /* user defined state */ enum ui_text_encoding text_encoding; } @@ -204,43 +222,50 @@ void _ui_widget_row( i16 inout_panel[4], i16 out_rect[4], i16 row_size ) rect_split( inout_panel, 0, _ui_widget_row_height( row_size ), UI_PADDING_PX, out_rect, inout_panel ); } +static b8 rect_eq( i16 a[4], i16 b[4] ) +{ + if( (a[0] == b[0]) && + (a[1] == b[1]) && + (a[2] == b[2]) && + (a[3] == b[3]) ) + return 1; + else return 0; +} + enum button_action _ui_button( i16 rect[4] ) { union colour debug_colour = (union colour){{ 200, 200, 200, 50 }}; enum button_action action = k_button_none; - b8 availible = 0; - if( _ui.active_control_type == k_ui_control_none ) - availible = 1; - else if( _ui.active_control_type == k_ui_control_button ) - availible = ui_inside_rect( rect, _ui.mouse_co_clicked ); + b8 mouse_in_box = 0, + clicked_in_box = 0; + + if( ui_inside_rect( rect, _ui.mouse_co ) ) + { + rect_copy( rect, _ui.mouse_co_container ); + if( rect_eq( rect, _ui.mouse_co_container_last ) ) + mouse_in_box = 1; + } + + if( ui_inside_rect( rect, _ui.mouse_co_clicked ) ) + if( rect_eq( rect, _ui.mouse_co_clicked_container_last ) ) + clicked_in_box = 1; - if( availible ) + if( mouse_in_box ) { - if( ui_inside_rect( rect, _ui.mouse_co ) ) + if( _input_button_down( k_input_action_ui_click, 0 ) ) { - if( _input_button_down( k_input_action_ui_click, 0 ) ) - { - action = k_button_click; - debug_colour = (union colour){{ 255, 255, 255, 255 }}; - _ui.active_control_type = k_ui_control_button; - } - else - { - action = _input_button( k_input_action_ui_click )? k_button_repeat: k_button_hover; - debug_colour = (union colour){{ 0, 0, 255, 170 }}; - } + action = k_button_click; + _ui.active_control_type = k_ui_control_button; + rect_copy( rect, _ui.mouse_co_clicked_container ); } - else - if( _input_button( k_input_action_ui_click ) ) - if( ui_inside_rect( rect, _ui.mouse_co_clicked ) ) - { - action = k_button_repeat; - debug_colour = (union colour){{ 255, 0, 255, 140 }}; - } + + if( !_input_button( k_input_action_ui_click ) ) + action = k_button_hover; } - _graphics_line_rect( rect, debug_colour ); + if( clicked_in_box && _input_button( k_input_action_ui_click ) && !_input_button_down( k_input_action_ui_click, 0 ) ) + action = k_button_repeat; if( action == k_button_click || action == k_button_repeat ) _ui.active_control_touched = 1; @@ -340,10 +365,11 @@ static void _ui_textbox_set_cursor_user( i32 position, b8 super ) _ui.controls.textbox.cursor_pos = position; } -void _ui_set_mouse( i16 x, i16 y ) +void _ui_set_mouse( i16 x, i16 y, u32 mods ) { _ui.mouse_co[0] = x; _ui.mouse_co[1] = y; + _ui.mouse_mods = mods; } void _ui_input_text( const c8 *text ) @@ -365,16 +391,19 @@ enum textbox_action _ui_textbox( i16 rect[4], c8 *text_buffer, u32 text_buffer_l if( flags & UI_AUTOFOCUS ) { - if( _ui.active_control_type != k_ui_control_textbox ) - init = 1; - else if( _ui.controls.textbox.text_buffer != text_buffer ) - init = 1; - - if( init ) + if( !_input_button( k_input_action_ui_click ) ) /* only autofocus if not touching stuff, because thats annoying */ { - i32 p = buffer_last_index( text_buffer, 0, 0 ); - _ui.controls.textbox.cursor_pos = p; - _ui.controls.textbox.cursor_user = p; + if( _ui.active_control_type != k_ui_control_textbox ) + init = 1; + else if( _ui.controls.textbox.text_buffer != text_buffer ) + init = 1; + + if( init ) + { + i32 p = buffer_last_index( text_buffer, 0, 0 ); + _ui.controls.textbox.cursor_pos = p; + _ui.controls.textbox.cursor_user = p; + } } } @@ -507,6 +536,9 @@ enum dropdown_action _ui_dropdown( i16 rect[4], struct ui_dropdown_option *optio b8 _ui_update(void) { + rect_copy( _ui.mouse_co_container, _ui.mouse_co_container_last ); + rect_copy( _ui.mouse_co_clicked_container, _ui.mouse_co_clicked_container_last ); + if( _input_button_down( k_input_action_ui_click, 0 ) ) { _ui.mouse_co_clicked[0] = _ui.mouse_co[0]; @@ -628,7 +660,7 @@ b8 _ui_update(void) return _ui.redraw; } -void _ui_draw(void) +void _ui_draw( i16 window_size[2] ) { if( _ui.active_control_type == k_ui_control_dropdown ) { @@ -642,11 +674,21 @@ void _ui_draw(void) button_rect[1] += button_rect[3]; struct ui_dropdown_option *option = &_ui.controls.dropdown.options[i]; - if( _ui_button( button_rect ) == k_button_click ) + enum button_action action = _ui_button( button_rect ); + if( action == k_button_click ) { _ui.controls.dropdown.action = k_dropdown_changed; *_ui.controls.dropdown.value = option->value; + _ui.active_control_touched = 0; + $log( $info, {"Set dropdown enum value to: "}, $signed( option->value ) ); } + + union colour c = (union colour){{100,100,100,255}}; + if( action == k_button_hover ) + c = (union colour){{160,160,160,255}}; + else if( action != k_button_none ) + c = (union colour){{200,200,200,255}}; + _graphics_fill_rect( button_rect, c ); c8 temp[32]; struct stream string; @@ -663,11 +705,95 @@ void _ui_draw(void) } } _ui.active_control_type = k_ui_control_dropdown; + _ui.active_control_touched = 1; + } + + if( _ui.fiddling ) + { + i16 w = 300, + h = 96, + px = i16_clamp( _ui.fiddle.co[0], 0, window_size[0]-w ), + py = i16_clamp( _ui.fiddle.co[1], 0, window_size[1]-h ); + + _ui_panel( &_ui.fiddle.panel, (i16[]){ px,py,w,h }, "Fiddle", UI_NO_OPTIONS ); + if( _ui_panel_content( &_ui.fiddle.panel ) ) + { + enum textbox_action text_action = + _ui_panel_textbox( &_ui.fiddle.panel, _ui.fiddle.buf, sizeof(_ui.fiddle.buf), 1, UI_AUTOFOCUS, "value" ); + + struct ui_panel cols[2]; + _ui_panel_grid( &_ui.fiddle.panel, cols, 1, 2, 1, UI_PADDING_PX, NULL ); + + enum button_action set_action = _ui_panel_button( &cols[0], "SET", 0 ), + cancel_action = _ui_panel_button( &cols[1], "Cancel", 0 ); + + if( (text_action == k_textbox_enter) || (set_action == k_button_click) ) + { + struct stream parse_string; + stream_open_buffer_read( &parse_string, _ui.fiddle.buf, buffer_last_index(_ui.fiddle.buf,0,0), 0 ); + + enum string_parse_result result = k_string_parse_error; + if( _ui.fiddle.data_type == k_data_type_f32 ) + { + f64 v; + result = string_parse_f64(&parse_string, &v); + if( result == k_string_parse_ok ) + { + $log( $low, {"Parsed fiddle f32 value from: "}, {_ui.fiddle.buf} ); + *((f32 *)_ui.fiddle.value) = (f32)v; + _ui.fiddling = 0; + } + else + { + $log( $error, {"Failed to parse f32 value from: "}, {_ui.fiddle.buf} ); + } + } + + if( _ui.fiddle.data_type == k_data_type_i32 ) + { + i64 v; + result = string_parse_i64(&parse_string, &v); + if( result == k_string_parse_ok ) + { + $log( $low, {"Parsed fiddle i32 value from: "}, {_ui.fiddle.buf} ); + *((i32 *)_ui.fiddle.value) = (i32)v; + _ui.fiddling = 0; + } + else + { + $log( $error, {"Failed to parse i32 value from: "}, {_ui.fiddle.buf} ); + } + } + } + + if( cancel_action == k_button_click ) + { + $log( $low, {"Cancel fiddle"} ); + _ui.fiddling = 0; + } + } } _ui.redraw = 0; _graphics_fill_rect( (i16[]){ _ui.mouse_co[0],_ui.mouse_co[1], 4,4 }, (union colour){{0,0,0,255}} ); _graphics_fill_rect( (i16[]){ _ui.mouse_co[0],_ui.mouse_co[1], 3,3 }, (union colour){{255,255,255,255}} ); + + i16 padded_container[4], + padded_container_click[4]; + + rect_copy( _ui.mouse_co_container_last, padded_container ); + rect_copy( _ui.mouse_co_clicked_container_last, padded_container_click ); + + for( i32 i=0; i<2; i ++ ) + { + padded_container[i] -= 2; + padded_container[i+2] += 4; + padded_container_click[i] -= 2; + padded_container_click[i+2] += 4; + } + + _graphics_line_rect( padded_container, (union colour){{100,100,100,255}} ); + _graphics_line_rect( padded_container_click, (union colour){{190,190,100,255}} ); } b8 _ui_want_mouse( i16 area[4] ) @@ -691,3 +817,317 @@ b8 _ui_want_text(void) { return _ui.active_control_type == k_ui_control_textbox; } + +void _ui_panel( struct ui_panel *panel, i16 base_rect[4], const c8 *title, u32 flags ) +{ + panel->main.title = title; + panel->flags = UI_MAIN | flags; + rect_copy( base_rect, panel->main.rect_base ); + if( panel->main.hidden ) + panel->main.rect_base[3] = 24; + _ui_button( panel->main.rect_base ); // Click hole the mouse +} + +void _ui_panel_row( struct ui_panel *panel, i16 size, i16 padding, struct ui_panel *out_row ) +{ + out_row->flags = UI_FULL_HEIGHT; + i16 kerning[3]; + _font_get_kerning( kerning ); + rect_split( panel->content_area, UI_HORIZONTAL, kerning[1]*size + UI_PADDING_PX, 0, out_row->content_area, panel->content_area ); + + if( padding ) + { + i16 _[4]; + rect_split( panel->content_area, UI_HORIZONTAL, padding, 0, _, panel->content_area ); + } +} + +void _ui_panel_grid( struct ui_panel *panel, struct ui_panel *out_panels, i32 rows, i32 columns, i16 row_size, i16 padding, f32 *column_bias ) +{ + f32 column_total_bias = 0.0f; + if( column_bias ) + for( i32 x=0; xflags = UI_FULL_HEIGHT; + + i16 column_width = (panel->content_area[2]) / columns; + if( column_bias ) + { + f32 ratio = column_bias[x] / column_total_bias; + column_width = (f32)panel->content_area[2] * ratio; + } + rect_split( row.content_area, UI_VERTICAL, column_width, 0, leaf->content_area, row.content_area ); + if( x == columns-1 ) + leaf->content_area[2] = (panel->content_area[0] + panel->content_area[2]) - leaf->content_area[0]; + else + leaf->content_area[2] -= padding; + } + } +} + +void _ui_panel_widget( struct ui_panel *panel, i16 out_rect[4] ) +{ + if( panel->flags & UI_FULL_HEIGHT ) + rect_copy( panel->content_area, out_rect ); + else + { + struct ui_panel row; + _ui_panel_row( panel, 1, UI_PADDING_PX, &row ); + rect_copy( row.content_area, out_rect ); + } +} + +enum button_action _ui_panel_button_internal( i16 rect[4], const c8 *text, u32 flag ) +{ + enum button_action action = k_button_none; + if( !(flag & UI_DISABLED) ) + action = _ui_button( rect ); + + union colour c = (union colour){{200,200,200,255}}; + union colour tc = (flag & UI_DULL)? (union colour){{140,140,140,255}}: (union colour){{20,20,20,255}}; + + if( action == k_button_hover ) + c = (union colour){{230,230,230,255}}; + else if( action != k_button_none ) + c = (union colour){{255,255,255,255}}; + if( flag & UI_DISABLED ) + { + c = (union colour){{140,140,140,255}}; + tc = (union colour){{160,160,160,255}}; + } + + _graphics_fill_rect( rect, c ); + _ui_text( rect, text, k_ui_align_center, tc ); + + if( flag & UI_MARKED ) + { + i16 outline_rect[4] = { rect[0] - 2, rect[1] - 2, rect[2] + 4, rect[3] + 4 }; + _graphics_line_rect( outline_rect, (union colour){{0,255,20,200}} ); + } + return action; +} + +b8 _ui_panel_content( struct ui_panel *panel ) +{ + ASSERT_CRITICAL( panel->flags & UI_MAIN ); + _graphics_fill_rect( panel->main.rect_base, (union colour){{50,50,50,160}} ); + + i16 kerning[3]; + _font_get_kerning( kerning ); + + i16 title_box[4] = { panel->main.rect_base[0], panel->main.rect_base[1], + panel->main.rect_base[2], kerning[1] + UI_PADDING_PX }; + _ui_text( title_box, panel->main.title, k_ui_align_center, (union colour){{255,255,255,255}} ); + + b8 show = !panel->main.hidden; + if( !(panel->flags & UI_NO_OPTIONS) ) + { + i16 toggle_box[4] = { title_box[0] + title_box[2] - 20, title_box[1], 20, title_box[3] }; + if( _ui_panel_button_internal( toggle_box, panel->main.hidden? "+": "-", 0 ) == k_button_click ) + { + panel->main.hidden ^= 0x1; + } + } + + panel->content_area[0] = panel->main.rect_base[0] + UI_PADDING_PX; + panel->content_area[1] = title_box[1] + title_box[3] + UI_PADDING_PX; + panel->content_area[2] = panel->main.rect_base[2] - UI_PADDING_PX*2; + panel->content_area[3] = ((panel->main.rect_base[1] + panel->main.rect_base[3]) - panel->content_area[1]) - UI_PADDING_PX; + return show; +} + +enum button_action _ui_panel_button( struct ui_panel *panel, const c8 *text, u32 flag ) +{ + i16 button_rect[4]; + _ui_panel_widget( panel, button_rect ); + return _ui_panel_button_internal( button_rect, text, flag ); +} + +enum button_action _ui_panel_toggle( struct ui_panel *panel, const c8 *label, u32 *value, u32 toggle_mask, u32 flag, + const c8 *options[2] ) +{ + struct ui_panel cols[3]; + _ui_panel_grid( panel, cols, 1, 3, 1, 0, (f32[]){ 4.0f, 0.5f, 3.0f } ); + + i16 label_box[4]; + _ui_panel_widget( cols+0, label_box ); + + union colour tc = (flag & UI_DULL)? (union colour){{20,20,20,255}}: (union colour){{200,200,200,255}}; + _ui_text( label_box, label, k_ui_align_y_center | k_ui_align_x_right, tc ); + + b8 yes = ((*value) & toggle_mask) == toggle_mask; + enum button_action action = _ui_panel_button( cols+2, yes? (options? options[1]:"Yes"): (options? options[0]:"No"), flag ); + + if( action == k_button_click ) + *value = (*value) ^ toggle_mask; + + return action; +} + +enum textbox_action _ui_panel_textbox( struct ui_panel *panel, c8 *text_buffer, u32 text_buffer_length, u32 lines, u32 flag, const c8 *label ) +{ + struct ui_panel cols[3]; + _ui_panel_grid( panel, cols, 1, 3, 1, 0, (f32[]){ 1.0f, 0.5f, 4.0f } ); + + i16 label_box[4]; + _ui_panel_widget( cols+0, label_box ); + + union colour tc = (flag & UI_DULL)? (union colour){{20,20,20,255}}: (union colour){{200,200,200,255}}; + _ui_text( label_box, label, k_ui_align_y_center | k_ui_align_x_right, tc ); + + i16 rect[4]; + _ui_panel_widget( cols+2, rect ); + enum textbox_action action = _ui_textbox( rect, text_buffer, text_buffer_length, lines, flag ); + return action; +} + +void _ui_panel_number( struct ui_panel *panel, const c8 *label, + void *values, + void *mins, + void *maxs, + enum data_type data_type, u32 flag ) +{ + f32 *values_f32 = values; + f32 *mins_f32 = mins; + f32 *maxs_f32 = maxs; + f32 *start_f32s = (void *)_ui.controls.number.start_values; + + i32 *values_i32 = values; + i32 *mins_i32 = mins; + i32 *maxs_i32 = maxs; + i32 *start_i32s = (void *)_ui.controls.number.start_values; + + struct ui_panel grid[6*16]; + _ui_panel_grid( panel, grid, DATATYPE_GET_COUNT(data_type), 6, 1, 0, (f32[]){ 4.0f,0.5f,0.75f,2.0f,0.75f,0.75f } ); + + i16 label_box[4]; + _ui_panel_widget( &grid[0], label_box ); + union colour tc = (flag & UI_DULL)? (union colour){{20,20,20,255}}: (union colour){{200,200,200,255}}; + _ui_text( label_box, label, k_ui_align_y_center | k_ui_align_x_right, tc ); + + for( u32 i=0; icontent_area, UI_HORIZONTAL, 2+UI_PADDING_PX/2, UI_PADDING_PX, line, panel->content_area ); + _graphics_fill_rect( line, (union colour){{20,20,20,255}} ); + + i16 rect[4]; + rect_split( panel->content_area, UI_HORIZONTAL, kerning[1] + UI_PADDING_PX, UI_PADDING_PX, rect, panel->content_area ); + + union colour tc = (flag & UI_DULL)? (union colour){{20,20,20,255}}: (union colour){{200,200,200,255}}; + _ui_text( rect, label, k_ui_align_center, tc ); +} diff --git a/source/graphics/vg_graphics.h b/source/graphics/vg_graphics.h index a21b8e4..3c53591 100644 --- a/source/graphics/vg_graphics.h +++ b/source/graphics/vg_graphics.h @@ -94,7 +94,7 @@ b8 _font_decode_bitmap( i16 uv[2] ); /* Immediate mode UI * ------------------------------------------------------------------------------------------------------------------ */ -void _ui_set_mouse( i16 x, i16 y ); +void _ui_set_mouse( i16 x, i16 y, u32 mods ); void _ui_get_mouse_co( i16 out_co[2] ); void _ui_input_text( const c8 *text ); b8 _ui_want_mouse( i16 area[4] ); @@ -104,14 +104,24 @@ b8 _ui_want_text(void); #define UI_ROW_PADDING_PX 18 #define UI_HORIZONTAL 0 #define UI_VERTICAL 1 -#define MOUSE_LEFT 0x1 -#define MOUSE_RIGHT 0x2 +#define UI_MOUSE_LEFT 0x1 +#define UI_MOUSE_RIGHT 0x2 +#define UI_KEYBOARD_ALT 0x1 +#define UI_KEYBOARD_SHIFT 0x2 +#define UI_KEYBOARD_CAPSLOCK 0x4 +#define UI_KEYBOARD_CONTROL 0x8 #define UI_AUTOFOCUS 0x1 #define UI_MULTILINE 0x2 +#define UI_FULL_HEIGHT 0x100 +#define UI_DULL 0x200 +#define UI_MARKED 0x400 +#define UI_MAIN 0x800 +#define UI_DISABLED 0x1000 +#define UI_NO_OPTIONS 0x2000 b8 _ui_update(void); -void _ui_draw(void); +void _ui_draw( i16 window_size[2] ); /* Text */ enum ui_text_encoding @@ -197,3 +207,45 @@ enum textbox_action k_textbox_escape }; enum textbox_action _ui_textbox( i16 rect[4], c8 *text_buffer, u32 text_buffer_length, u32 lines, u32 flags ); + +/* Panel based immediate mode UI + * ------------------------------------------------------------------------------------------------------------------ */ +struct ui_panel +{ + union + { + struct + { + const c8 *title; + b8 hidden; + i16 rect_base[4]; + } + main; + }; + + u32 flags; + i16 content_area[4]; +}; + +void _ui_panel( struct ui_panel *panel, i16 base_rect[4], const c8 *title, u32 flags ); +void _ui_panel_row( struct ui_panel *panel, i16 size, i16 padding, struct ui_panel *out_row ); +void _ui_panel_grid( struct ui_panel *panel, struct ui_panel *out_panels, i32 rows, i32 columns, i16 row_size, + i16 padding, f32 *column_bias ); +void _ui_panel_widget( struct ui_panel *panel, i16 out_rect[4] ); +enum button_action _ui_panel_button_internal( i16 rect[4], const c8 *text, u32 flag ); +b8 _ui_panel_content( struct ui_panel *panel ); +enum button_action _ui_panel_button( struct ui_panel *panel, const c8 *text, u32 flag ); +enum button_action _ui_panel_toggle( struct ui_panel *panel, const c8 *label, u32 *value, u32 toggle_mask, + u32 flag, const c8 *options[2] ); +enum textbox_action _ui_panel_textbox( struct ui_panel *panel, c8 *text_buffer, u32 text_buffer_length, u32 lines, + u32 flag, const c8 *label ); +void _ui_panel_heading( struct ui_panel *panel, const c8 *label, u32 flag ); + +void _ui_panel_number( struct ui_panel *panel, const c8 *label, + void *values, + void *mins, + void *maxs, + enum data_type data_type, u32 flag ); + +enum dropdown_action _ui_panel_enum( struct ui_panel *panel, const c8 *label, i32 *value, + struct ui_dropdown_option *options, u32 option_count, u32 flag ); diff --git a/source/tools/metacompiler.c b/source/tools/metacompiler.c index 64c3ead..f7ed14d 100644 --- a/source/tools/metacompiler.c +++ b/source/tools/metacompiler.c @@ -90,6 +90,7 @@ struct { struct stream name, tripple, folder; const c8 *enabled_features[ 64 ]; + u32 feature_count; } static _metacompiler; @@ -157,8 +158,8 @@ void _cannonicalize( struct file_context *file_context, const c8 *path, struct s free( source_file_path ); } -void _assemble_unit_file( const c8 *path, u32 assembly_block, u32 feature_count ); -void _parse_kv_block( struct keyvalues *kvs, u32 block, struct file_context *file_context, u32 assembly_block, u32 feature_count ) +void _assemble_unit_file( const c8 *path, u32 assembly_block ); +void _parse_kv_block( struct keyvalues *kvs, u32 block, struct file_context *file_context, u32 assembly_block ) { u32 it = 0; while( keyvalues_foreach( kvs, &it, block, NULL ) ) @@ -172,18 +173,18 @@ void _parse_kv_block( struct keyvalues *kvs, u32 block, struct file_context *fil ASSERT_CRITICAL( test_feature ); b8 result = 0; - for( u32 i=0; iassembly_kv_end = keyvalues_current_offset( &_assembly ); } @@ -579,7 +584,8 @@ void _codegen_console(void) ASSERT_CRITICAL( name && function ); $v_string( &H, {"i32 "}, {function}, {"( struct console_arguments *args );\n"} ); - $v_string( &C, {" {\n .alias = \""}, {name}, {"\",\n .type = k_console_item_ccmd,\n .fn = "}, {function}, {"\n },\n"} ); + $v_string( &C, {" {\n .alias = \""}, {name}, {"\",\n .type = k_data_type_function,\n .fn = "}, + {function}, {"\n },\n"} ); } u32 cvar_it = 0; @@ -591,7 +597,7 @@ void _codegen_console(void) const c8 *cheat = keyvalues_read_string( &_assembly, cvar_it, "cheat", NULL ); ASSERT_CRITICAL( name && type && value ); $v_string( &H, {"extern "}, {type}, {" _cvar_"}, {name}, {";\n"} ); - $v_string( &C, {" {\n .alias = \""}, {name}, {"\",\n .type = k_console_item_cvar_"},{type}, + $v_string( &C, {" {\n .alias = \""}, {name}, {"\",\n .type = k_data_type_"},{type}, {",\n ._"},{type},{" = &_cvar_"}, {name}, {"\n },\n"} ); } $v_string( &C, {"};\n\n"} ); @@ -674,7 +680,7 @@ void _codegen_entities(void) const c8 *name; u32 id; - u16 function_start, function_count; + u16 function_start, function_count, parameter_start, parameter_count; } entities[256]; u32 entity_count = 0; @@ -707,18 +713,21 @@ void _codegen_entities(void) index_sort( entity_ids, entity_count ); - $v_string( &H, {"enum entity_type\n{\n k_ent_none = 0,\n"} ); + $v_string( &H, {"enum entity_type\n{\n k_ent_none = 0,\n"} ); for( u32 i=0; ifunction_start = function_count; + ent->parameter_start = parameter_count; if( !keyvalues_get( &_assembly, ent->block, "parameter", 0 ) ) { @@ -792,6 +801,10 @@ void _codegen_entities(void) { "f32", "f32", "","c_float" }, { "f64", "f64", "","c_double" }, + + { "entity_id", "union entity_id","","c_uint32" }, + { "2dbox", "f32", "[2][2]","(c_float*2)*2" }, + { "3dbox", "f32", "[2][3]","(c_float*3)*2" } }; i32 type_index = -1; @@ -808,6 +821,9 @@ void _codegen_entities(void) $v_string( &H, {" "}, {types[type_index].c_type}, {" "}, {name}, {types[type_index].c_post}, {";\n"} ); $v_string( &PY, {" (\""}, {name}, {"\","}, {types[type_index].py_type}, {"),\n"} ); + + ent->parameter_count ++; + parameter_count ++; } $v_string( &H, {"};\n"} ); } @@ -825,18 +841,43 @@ void _codegen_entities(void) } /* entity info structures */ + $v_string( &H, {"/* Enitity information */\n"} ); + $v_string( &H, {"extern struct entity_info _entity_infos[];\n"} ); $v_string( &C, {"/* Enitity information */\n"} ); $v_string( &C, {"struct entity_info _entity_infos[] = {\n"} ); for( u32 i=0; iname}, {"\", .function_start="}, - $unsigned( ent->function_start ), {", .function_count = "}, - $unsigned( ent->function_count ), {" },\n"} ); + $v_string( &C, {" { .id = "}, $signed(ent_id), {", .name = \""}, {ent->name}, {"\""}, + {", .size=sizeof(struct "}, {ent->name}, {")\n"}, + {",\n.function_start="}, $unsigned( ent->function_start ), + {", .function_count="}, $unsigned( ent->function_count ), + {",\n.parameter_start="}, $unsigned( ent->parameter_start ), + {", .parameter_count="}, $unsigned( ent->parameter_count ), + {" },\n"} ); } $v_string( &C, {"};\n"} ); + /* function info structures (indexed by entity structures) */ + $v_string( &C, {"/* Parameter information */\n"} ); + $v_string( &C, {"struct entity_parameter_info _entity_parameter_infos[] = {\n"} ); + for( u32 i=0; iblock, "parameter" ) ) + { + const c8 *name = keyvalues_read_string( &_assembly, parameter_it, "name", NULL ); + const c8 *type = keyvalues_read_string( &_assembly, parameter_it, "type", NULL ); + ASSERT_CRITICAL( name && type ); + $v_string( &C, {" { .name = \""}, {name}, {"\""} ); + $v_string( &C, {", .type = k_data_type_"}, {type} ); + $v_string( &C, {", .offset = __builtin_offsetof(struct "}, {ent->name}, {", "}, {name}, {")"} ); + $v_string( &C, {" },\n"} ); + } + } + $v_string( &C, {"};\n"} ); /* function info structures (indexed by entity structures) */ $v_string( &C, {"/* Function information */\n"} ); @@ -855,14 +896,14 @@ void _codegen_entities(void) $v_string( &C, {"};\n"} ); /* Entity info, and function to get it by entity ID */ - $v_string( &C, {"struct entity_info *_vg_entity_info( u16 entity_type )\n{\n"} ); + $v_string( &C, {"u32 _vg_entity_type_index( u16 entity_type )\n{\n"} ); for( u32 i=0; iline, {" -I. \\\n"} ); + for( u32 i=0; i<_metacompiler.feature_count; i ++ ) + { + $v_string( &cmd->line, {" -D"}, {_metacompiler.enabled_features[i]}, {" \\\n"} ); + } + u32 compile_it = 0; while( keyvalues_foreach( &_assembly, &compile_it, 0, NULL ) ) { @@ -1142,7 +1187,9 @@ i32 main( i32 argc, const c8 *argv[] ) $v_string( &cmd->line, {keyvalues_value( &_assembly, compile_it, NULL )}, {" \\\n"} ); } } +#if 0 $v_string( &cmd->line, {" generated/hooks.c \\\n"} ); +#endif $v_string( &cmd->line, {"-o "}, {string_get( &_metacompiler.folder )}, {"/"}, {string_get(&_metacompiler.name)} ); if( _option_platform == k_platform_windows ) { $v_string( &cmd->line, {_option_shared? ".dll ": ".exe "} ); } diff --git a/source/types.h b/source/types.h index 7b8142e..8df1618 100644 --- a/source/types.h +++ b/source/types.h @@ -11,3 +11,75 @@ typedef float f32; typedef double f64; typedef unsigned char b8; #define NULL 0 + +#define DATATYPE_SIZE( COUNT, BYTES ) (0x0100*(COUNT-1) | 0x0020*(BYTES-1)) +#define DATATYPE_GET_WIDTH( DATA_TYPE ) (((DATA_TYPE & k_data_mask_width) >> 5)+1) +#define DATATYPE_GET_COUNT( DATA_TYPE ) (((DATA_TYPE & k_data_mask_count) >> 8)+1) +#define DATATYPE_GET_SINGLE( DATA_TYPE ) (data_type & (k_data_mask_format | k_data_mask_width)) +enum data_type +{ + k_data_mask_semantic = 0x001f, /* intended purpose 0 -> 31 (x1F) */ + k_data_mask_width = 0x00e0, /* single element width 1 -> 8 */ + k_data_mask_count = 0x0f00, /* vector wdith 1 -> 16 */ + k_data_mask_format = 0xf000, /* binary format of data 0 -> 15 */ + + k_data_semantic_scalar = 0x0000, + k_data_semantic_boolean = 0x0002, + k_data_semantic_character= 0x0003, + k_data_semantic_colour = 0x0004, + k_data_semantic_rotation = 0x0005, + k_data_semantic_transform= 0x0006, + k_data_semantic_vector = 0x0007, + k_data_semantic_box = 0x0008, + k_data_semantic_key = 0x0009, + k_data_semantic_offset_string = 0x000A, + + k_data_format_unsigned = 0x1000, + k_data_format_signed = 0x2000, + k_data_format_float = 0x3000, + k_data_format_void = 0x4000, + + k_data_type_none = 0, + + /* unsigned integers */ + k_data_type_u8 = k_data_format_unsigned | DATATYPE_SIZE( 1, 1 ) | k_data_semantic_scalar, + k_data_type_u16 = k_data_format_unsigned | DATATYPE_SIZE( 1, 2 ) | k_data_semantic_scalar, + k_data_type_u32 = k_data_format_unsigned | DATATYPE_SIZE( 1, 4 ) | k_data_semantic_scalar, + k_data_type_u64 = k_data_format_unsigned | DATATYPE_SIZE( 1, 8 ) | k_data_semantic_scalar, + k_data_type_b8 = k_data_format_unsigned | DATATYPE_SIZE( 1, 1 ) | k_data_semantic_boolean, + + k_data_type_pstr = k_data_format_unsigned | DATATYPE_SIZE( 1, 4 ) | k_data_semantic_offset_string, + k_data_type_entity_id = k_data_format_unsigned | DATATYPE_SIZE( 1, 4 ) | k_data_semantic_key, + + /* signed integers */ + k_data_type_i8 = k_data_format_signed | DATATYPE_SIZE( 1, 1 ) | k_data_semantic_scalar, + k_data_type_i16 = k_data_format_signed | DATATYPE_SIZE( 1, 2 ) | k_data_semantic_scalar, + k_data_type_i32 = k_data_format_signed | DATATYPE_SIZE( 1, 4 ) | k_data_semantic_scalar, + k_data_type_ivec2 = k_data_format_signed | DATATYPE_SIZE( 2, 4 ) | k_data_semantic_vector, + k_data_type_ivec3 = k_data_format_signed | DATATYPE_SIZE( 3, 4 ) | k_data_semantic_vector, + k_data_type_ivec4 = k_data_format_signed | DATATYPE_SIZE( 4, 4 ) | k_data_semantic_vector, + k_data_type_i64 = k_data_format_signed | DATATYPE_SIZE( 1, 8 ) | k_data_semantic_scalar, + k_data_type_c8 = k_data_format_signed | DATATYPE_SIZE( 1, 1 ) | k_data_semantic_character, + + /* floating types */ + k_data_type_f32 = k_data_format_float | DATATYPE_SIZE( 1, 4 ) | k_data_semantic_scalar, + k_data_type_f64 = k_data_format_float | DATATYPE_SIZE( 1, 8 ) | k_data_semantic_scalar, + /* vectors */ + k_data_type_vec2 = k_data_format_float | DATATYPE_SIZE( 2, 4 ) | k_data_semantic_vector, + k_data_type_vec3 = k_data_format_float | DATATYPE_SIZE( 3, 4 ) | k_data_semantic_vector, + k_data_type_vec4 = k_data_format_float | DATATYPE_SIZE( 4, 4 ) | k_data_semantic_vector, + k_data_type_quat = k_data_format_float | DATATYPE_SIZE( 4, 4 ) | k_data_semantic_rotation, + + /* CO|SCALE|QUAT */ + k_data_type_transform = k_data_format_float | DATATYPE_SIZE( 10, 4 ) | k_data_semantic_transform, + /* matrices */ + k_data_type_mat2x2 = k_data_format_float | DATATYPE_SIZE( 4, 4 ) | k_data_semantic_transform, + k_data_type_mat3x3 = k_data_format_float | DATATYPE_SIZE( 9, 4 ) | k_data_semantic_transform, + k_data_type_mat4x3 = k_data_format_float | DATATYPE_SIZE( 12, 4 ) | k_data_semantic_transform, + k_data_type_mat4x4 = k_data_format_float | DATATYPE_SIZE( 16, 4 ) | k_data_semantic_transform, + /* box */ + k_data_type_2dbox = k_data_format_float | DATATYPE_SIZE( 4, 4 ) | k_data_semantic_box, + k_data_type_3dbox = k_data_format_float | DATATYPE_SIZE( 6, 4 ) | k_data_semantic_box, + + k_data_type_function = k_data_format_void +}; -- 2.25.1