test_feature
{
- feature SDL
+ feature FEATURE_SDL
yes
{
add sdl_async.c
}
}
-
-hook
-{
- affinity -20000
- event START
- function _async_init
-}
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
{
if( target_command )
{
- if( target_command->type == k_console_item_ccmd )
+ if( target_command->type == k_data_type_function )
target_command->fn( &args );
else
{
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 );
}
}
}
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
{
append ../console/console_system.kv
add vg_console.c
-add vg_framebuffer.c
-add vg_render.c
-add vg_shader.c
input_layer
{
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"
}
}
}
SDL_Mutex *_audio_mutex;
_Thread_local static b8 _audio_have_lock = 0;
-static f32 _master_volume = 1.0f;
enum channel_stage
{
#include <math.h>
#include <time.h>
#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 <emscripten.h>
-#include <emscripten/html5.h>
+#if defined( PLATFORM_WEB )
+# include <emscripten.h>
+# include <emscripten/html5.h>
#endif
struct _engine _engine;
return 0;
}
-#if !defined( __EMSCRIPTEN__ )
+#if defined( FEATURE_OPENGL )
+# if !defined( PLATFORM_WEB )
APIENTRY void _opengl_debug( GLenum source,
GLenum type,
GLuint id,
if( type == GL_DEBUG_TYPE_ERROR )
_fatal_exit();
}
+# endif
#endif
#include <unistd.h>
-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;
_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
_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 )
SDL_SetWindowMaximumSize( _engine.window_handle, 1920*2, 1080*2 );
SDL_StopTextInput( _engine.window_handle );
+#if defined( FEATURE_OPENGL )
/*
* OpenGL loading
*/
_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 );
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 )
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:;
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;
}
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
}
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 ) )
{
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 )
{
}
}
}
+
+ // 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
+ }
}
#include "random.h"
+#if !defined( FEATURE_OPENGL )
+# include "SDL3/SDL_surface.h"
+#endif
+
struct _engine
{
b8 vsync;
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;
}
$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 ) ];
+}
#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
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 );
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++ )
{
#include "vg_material.h"
#include "vg_shader.h"
-// FIXME!!!!!!!!!!!!!!!!!!!! QSORT
-#include <stdlib.h>
-
struct
{
struct vg_asset_list asset_list;
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 );
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 )
{
}
}
-
u32 shader_block = keyvalues_get_child( &material->kvs, 0, 0 );
if( shader_block )
{
struct vg_material
{
- u16 shader_id, flags;
+ i16 shader_id;
+ u16 flags;
struct keyvalues kvs;
struct tex_tilemap tilemap;
union
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 );
{
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 )
{
#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 =
};
struct _engine_ui _engine_ui;
+#if defined( FEATURE_OPENGL )
static GLuint _ui_surface_texture;
+#endif
#include <unistd.h>
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 );
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)
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 );
_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; y<surface->h; y ++ )
+ {
+ for( i32 x=0; x<surface->w; 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();
/* 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
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 );
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 );
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 );
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)
* ------------------------------------------------------------------------------------------------------------------ */
i64 _i64;
f64 _f64;
};
-
u32 type;
u32 base;
union
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
* ------------------------------------------------------------------------------------------------------------------ */
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 );
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;
add keyvalues.c
add buffer_operations.c
add temporary.c
+add sort.c
test_feature
{
- feature linux
+ feature PLATFORM_LINUX
yes
{
add io.c
test_feature
{
- feature SDL
+ feature FEATURE_SDL
yes
{
add threads_sdl.c
--- /dev/null
+#include <stdlib.h>
+#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 );
+}
#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 */
active_control_type;
b8 active_control_touched;
b8 redraw;
+ b8 fiddling;
union
{
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;
}
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;
_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 )
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;
+ }
}
}
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];
return _ui.redraw;
}
-void _ui_draw(void)
+void _ui_draw( i16 window_size[2] )
{
if( _ui.active_control_type == k_ui_control_dropdown )
{
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;
}
}
_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] )
{
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; x<columns; x ++ )
+ column_total_bias += column_bias[x];
+
+ for( i32 y=0; y<rows; y ++ )
+ {
+ struct ui_panel row;
+ _ui_panel_row( panel, row_size, ((y+1)==rows)? UI_PADDING_PX: 0, &row );
+
+ for( i32 x=0; x<columns; x ++ )
+ {
+ struct ui_panel *leaf = &out_panels[ y*columns + x ];
+ leaf->flags = 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; i<DATATYPE_GET_COUNT(data_type); i ++ )
+ {
+ struct ui_panel *buttons = grid + (i*6) + 2;
+ enum button_action down_a = _ui_panel_button( &buttons[0], "-", flag ),
+ edit_a = _ui_panel_button( &buttons[3], "=", flag ),
+ up_a = _ui_panel_button( &buttons[2], "+", flag );
+ enum button_action main_a = _ui_button( buttons[1].content_area );
+
+ b8 modified = 0;
+ enum data_type single_type = DATATYPE_GET_SINGLE( data_type );
+
+ /* inc/dec */
+ if( down_a == k_button_click )
+ {
+ if( single_type == k_data_type_i32 ) values_i32[i] --;
+ else if( single_type == k_data_type_f32 ) values_f32[i] -= 1.0f;
+ modified = 1;
+ }
+ if( up_a == k_button_click )
+ {
+ if( single_type == k_data_type_i32 ) values_i32[i] ++;
+ else if( single_type == k_data_type_f32 ) values_f32[i] += 1.0f;
+ modified = 1;
+ }
+
+ /* slider action */
+ if( main_a == k_button_click )
+ {
+ if( single_type == k_data_type_i32 ) start_i32s[i] = values_i32[i];
+ else if( single_type == k_data_type_f32 ) start_f32s[i] = values_f32[i];
+ }
+ if( main_a == k_button_repeat )
+ {
+ i32 delta = _ui.mouse_co[0] - _ui.mouse_co_clicked[0],
+ div = 1;
+ if( _ui.mouse_mods & UI_KEYBOARD_ALT )
+ div = 8;
+ if( single_type == k_data_type_i32 ) values_i32[i] = start_i32s[i] + (delta/div);
+ else if( single_type == k_data_type_f32 ) values_f32[i] = start_f32s[i] + ((f32)delta/(f32)div)/10.0f;
+ modified = 1;
+ }
+
+ if( modified && (mins && maxs) )
+ {
+ if( single_type == k_data_type_i32 )
+ values_i32[i] = i32_clamp( values_i32[i], mins_i32[i], maxs_i32[i] );
+ else if( single_type == k_data_type_f32 )
+ values_f32[i] = f32_clamp( values_f32[i], mins_f32[i], maxs_f32[i] );
+ }
+
+ c8 buf[32];
+ struct stream number_str;
+ stream_open_buffer_write( &number_str, buf, sizeof(buf), k_stream_null_terminate );
+
+ if( single_type == k_data_type_i32 )
+ {
+ $v_string( &number_str, $signed( values_i32[i] ) );
+ }
+ else if( single_type == k_data_type_f32 )
+ {
+ $v_string( &number_str, $float( values_f32[i] ) );
+ }
+ else
+ {
+ $v_string( &number_str, {"NOT_VIEWABLE"} );
+ }
+
+ _ui_panel_widget( &buttons[1], label_box );
+ _graphics_fill_rect( label_box, (union colour){{20,20,20,255}} );
+ _graphics_line_rect( label_box, (union colour){{60,60,60,255}} );
+ _ui_text( label_box, buf, k_ui_align_center, tc );
+
+ if( edit_a == k_button_click )
+ {
+ buffer_copy( buf, 0, _ui.fiddle.buf, sizeof(_ui.fiddle.buf) );
+ _ui.fiddling = 1;
+ _ui.fiddle.value = values + DATATYPE_GET_WIDTH(data_type) * i;
+ _ui.fiddle.data_type = single_type;
+ _ui.fiddle.co[0] = buttons[2].content_area[0];
+ _ui.fiddle.co[1] = buttons[2].content_area[1];
+ }
+ }
+}
+
+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 )
+{
+ 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 dropdown_action action = _ui_dropdown( rect, options, option_count, value );
+ return action;
+}
+
+void _ui_panel_heading( struct ui_panel *panel, const c8 *label, u32 flag )
+{
+ i16 kerning[3];
+ _font_get_kerning( kerning );
+
+ i16 line[4];
+ rect_split( panel->content_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 );
+}
/* 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] );
#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
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 );
{
struct stream name, tripple, folder;
const c8 *enabled_features[ 64 ];
+ u32 feature_count;
}
static _metacompiler;
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 ) )
ASSERT_CRITICAL( test_feature );
b8 result = 0;
- for( u32 i=0; i<feature_count; i ++ )
+ for( u32 i=0; i<_metacompiler.feature_count; i ++ )
if( compare_buffers( _metacompiler.enabled_features[i], 0, test_feature, 0 ) )
result = 1;
u32 pass_block = keyvalues_get( kvs, it, result? "yes": "no", 0 );
if( pass_block )
- _parse_kv_block( kvs, pass_block, file_context, assembly_block, feature_count );
+ _parse_kv_block( kvs, pass_block, file_context, assembly_block );
}
else
{
/* Add the block title to the assembly if it's not a pre-processor thing */
- _parse_kv_block( kvs, it, file_context, keyvalues_append_frame( &_assembly, assembly_block, it_k ), feature_count );
+ _parse_kv_block( kvs, it, file_context, keyvalues_append_frame( &_assembly, assembly_block, it_k ) );
}
}
else
/* ENABLE FEATURE */
if( compare_buffers( it_k, 0, "enable", 0 ) )
- _metacompiler.enabled_features[ feature_count ++ ] = it_v;
+ {
+ ASSERT_CRITICAL( _metacompiler.feature_count < ARRAY_COUNT( _metacompiler.enabled_features ) );
+ u32 copied_kv = keyvalues_append_string( &_assembly, assembly_block, it_k, it_v );
+ _metacompiler.enabled_features[ _metacompiler.feature_count ++ ] = keyvalues_value( &_assembly, copied_kv, NULL );
+ }
/* APPEND */
else if( compare_buffers( it_k, 0, "append", 0 ) )
struct stream path_string;
stream_open_stack( &path_string, _temporary_stack_allocator(), k_stream_null_terminate );
_cannonicalize( file_context, it_v, &path_string );
- _assemble_unit_file( string_get( &path_string ), assembly_block, feature_count );
+ _assemble_unit_file( string_get( &path_string ), assembly_block );
}
_end_temporary_frame( temp_frame );
}
}
}
-void _assemble_unit_file( const c8 *path, u32 assembly_block, u32 feature_count )
+void _assemble_unit_file( const c8 *path, u32 assembly_block )
{
u32 temp_frame = _start_temporary_frame();
{
struct keyvalues kvs;
ASSERT_CRITICAL( keyvalues_read_file( &kvs, path, _temporary_stack_allocator() ) );
- _parse_kv_block( &kvs, 0, file_context, assembly_block, feature_count );
+ _parse_kv_block( &kvs, 0, file_context, assembly_block );
file_context->assembly_kv_end = keyvalues_current_offset( &_assembly );
}
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;
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"} );
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;
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; i<entity_count; i ++ )
$v_string( &H, {" k_"}, {entities[entity_ids[i].index].name}, {" = "}, $signed(entity_ids[i].value), {",\n"} );
+ $v_string( &H, {" k_ent_total_count = "},$unsigned(entity_count),{"\n"} );
$v_string( &H, {"};\n"} );
- u32 function_count = 0;
+ u32 function_count = 0,
+ parameter_count = 0;
$v_string( &H, {"/* serialized entity structures */\n"} );
for( u32 i=0; i<entity_count; i ++ )
{
struct entity *ent = &entities[ entity_ids[i].index ];
ent->function_start = function_count;
+ ent->parameter_start = parameter_count;
if( !keyvalues_get( &_assembly, ent->block, "parameter", 0 ) )
{
{ "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;
$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"} );
}
}
/* 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; i<entity_count; i ++ )
{
struct entity *ent = &entities[ entity_ids[i].index ];
i32 ent_id = entity_ids[i].value;
- $v_string( &C, {" { .id = "}, $signed(ent_id), {", .name = \""}, {ent->name}, {"\", .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; i<entity_count; i ++ )
+ {
+ struct entity *ent = &entities[ entity_ids[i].index ];
+ u32 parameter_it = 0;
+ while( keyvalues_foreach( &_assembly, ¶meter_it, ent->block, "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"} );
$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; i<entity_count; i ++ )
{
struct entity *ent = &entities[ entity_ids[i].index ];
i32 ent_id = entity_ids[i].value;
- $v_string( &C, {" if( entity_type == "}, $signed(ent_id), {" ) return &_entity_infos["}, $unsigned(i), {"];\n"} );
+ $v_string( &C, {" if( entity_type == "}, $signed(ent_id), {" ) return "}, $unsigned(i), {";\n"} );
}
- $v_string( &C, {" ASSERT_CRITICAL(0); return NULL;\n"} );
+ $v_string( &C, {" ASSERT_CRITICAL(0); return 0;\n"} );
$v_string( &C, {"}\n"} );
/* Entity functions, and dispatch */
keyvalues_append_string( &_assembly, info_block, "tripple", string_get( &_metacompiler.tripple ) );
keyvalues_append_string( &_assembly, info_block, "folder", string_get( &_metacompiler.folder ) );
- i32 start_features = 0;
if( _option_platform == k_platform_linux ||
- _option_platform == k_platform_web ) _metacompiler.enabled_features[start_features ++] = "linux";
- if( _option_platform == k_platform_windows ) _metacompiler.enabled_features[start_features ++] = "windows";
+ _option_platform == k_platform_web ) _metacompiler.enabled_features[_metacompiler.feature_count ++] = "PLATFORM_LINUX";
+ if( _option_platform == k_platform_windows ) _metacompiler.enabled_features[_metacompiler.feature_count ++] = "PLATFORM_WINDOWS";
- if( _option_platform == k_platform_web ) _metacompiler.enabled_features[start_features ++] = "web";
- _assemble_unit_file( _option_file_path, 0, start_features );
+ if( _option_platform == k_platform_web ) _metacompiler.enabled_features[_metacompiler.feature_count ++] = "PLATFORM_WEB";
+ _assemble_unit_file( _option_file_path, 0 );
if( _option_assemble_only )
{
$v_string( &cmd->line, {" -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 ) )
{
$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 "} ); }
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
+};