add source/engine/main.c
add source/engine/ui.c
add source/engine/shader.c
- add source/engine/input.c
add source/engine/console.c
add source/console_core.c
- append graphics.kv
- append glfw3.kv
-
input_layer
{
name console
}
-
input
{
name console
type action
layer_mask console
- bind GRAVE_ACCENT
}
+ append graphics.kv
+ append glfw3.kv
+
+ add source/engine/input.c
+ ccmd
+ {
+ name bind
+ function _input_bind_ccmd
+ description "Bind device input to a button, action or axis"
+
+ parameter
+ {
+ description "Device input alias"
+ }
+
+ parameter
+ {
+ description "button,action,axis name"
+ }
+ }
+
+ ccmd
+ {
+ name exec
+ function _console_exec_ccmd
+ description "Execute a configuration file"
+
+ parameter
+ {
+ description "The path to the config"
+ }
+ }
+
+ config "bind ALT+GRAVE_ACCENT console"
+ config "bind BACKSPACE ui_backspace"
+ config "bind DELETE ui_delete"
+ config "bind ENTER ui_enter"
+ config "bind TAB ui_indent"
+ config "bind HOME ui_home"
+ config "bind SHIFT+HOME ui_home_select"
+ config "bind END ui_end"
+ config "bind SHIFT+END ui_end_select"
+ config "bind LEFT ui_left"
+ config "bind SHIFT+LEFT ui_left_select"
+ config "bind RIGHT ui_right"
+ config "bind SHIFT+RIGHT ui_right_select"
+ config "bind UP ui_up"
+ config "bind SHIFT+UP ui_up_select"
+ config "bind DOWN ui_down"
+ config "bind SHIFT+DOWN ui_down_select"
+
input
{
- name ui_backspace
- bind BACKSPACE
+ name ui_delete
type action
}
input
{
- name ui_delete
- bind DELETE
+ name ui_backspace
type action
}
input
{
name ui_enter
- bind ENTER
type action
}
input
{
name ui_indent
- bind TAB
type action
}
input
{
name ui_home
- bind HOME
type action
}
input
{
name ui_home_select
- bind "SHIFT HOME"
type action
}
input
{
name ui_end
- bind END
type action
}
input
{
name ui_end_select
- bind "SHIFT END"
type action
}
input
{
name ui_left
- bind LEFT
type action
}
input
{
name ui_left_select
- bind "SHIFT LEFT"
type action
}
input
{
name ui_right
- bind RIGHT
type action
}
input
{
name ui_right_select
- bind "SHIFT RIGHT"
type action
}
input
{
name ui_up
- bind UP
type action
}
input
{
name ui_up_select
- bind "SHIFT UP"
type action
}
input
{
name ui_down
- bind DOWN
type action
}
input
{
name ui_down_select
- bind "SHIFT DOWN"
type action
}
description "This is just a test variable!"
}
- ccmd
- {
- name list
- function _console_list_ccmd
- description "List everything the console knows"
-
- parameter
- {
- enum "a b c d e f g"
- description "Nothing!"
- }
- }
-
event
{
name TEST_HOOK
const c8 *string_get( struct stream *string );
void string_clip( struct stream *string, i32 length );
-void string_append( struct stream *string, const c8 *substring );
+void string_append( struct stream *string, const c8 *substring, u32 length );
void string_append_c8( struct stream *string, c8 c );
void string_append_i64( struct stream *string, i64 value, u64 base );
void string_append_i64r( struct stream *string, i64 value, u64 base, u32 width, c8 blank_c8acter );
u32 type;
u32 base;
+ union
+ {
u32 decimals;
+ u32 length;
+ };
};
void v_string( struct stream *string, struct v_string_arg *argument_list );
#define k_$float 4
#define k_$errno 5
-#define $string( X, ... ) { string_get( X ), __VA_ARGS__ }
+#define $string( X, ... ) { X, __VA_ARGS__ }
#define $unsigned( X, ... ) { .type=k_$unsigned, ._u64=X, __VA_ARGS__ }
#define $signed( X, ... ) { .type=k_$signed, ._i64=X, __VA_ARGS__ }
#define $float( X, ... ) { .type=k_$float, ._f64=X, __VA_ARGS__ }
enum input_device
{
+ k_input_device_none = 0,
k_input_device_keyboard,
k_input_device_controller
};
+#include "console_core.h"
+
+struct console_command
+{
+ const c8 *alias;
+ i32 (*fn)( struct console_arguments *args );
+};
+
#include "generated/console.c"
struct
const c8 *entry;
};
+i32 _console_exec_ccmd( struct console_arguments *args )
+{
+ const c8 *path = console_get_argument( args, 0 );
+ if( !path )
+ {
+ $log( $error, {"Usage: exec <path>"} );
+ return -1;
+ }
+
+ struct stream file;
+ if( !stream_open_file( &file, path, k_stream_read ) )
+ return -1;
+
+ bool more_to_go = 1;
+ while( more_to_go )
+ {
+ u32 temp_frame = _start_temporary_frame();
+
+ struct stream line;
+ stream_open_stack( &line, _temporary_stack_allocator(), k_stream_null_terminate );
+
+ c8 c;
+ more_to_go = 0;
+ while( stream_read( &file, &c, 1 ) )
+ {
+ if( c == '\n' )
+ {
+ more_to_go = 1;
+ break;
+ }
+ string_append_c8( &line, c );
+ }
+
+ if( stream_offset( &line ) )
+ _console_execute( string_get( &line ), 1, 0 );
+
+ _end_temporary_frame( temp_frame );
+ }
+
+ return 0;
+}
+
void _console_execute( const c8 *command, bool silent, bool cheat_allowed )
{
+ if( !silent )
+ $log( $shell, {command} );
+
struct stream string;
- stream_open_buffer_read( &string, command, buffer_last_index( command, 0, 0 ), 0 );
+ stream_open_buffer_read( &string, command, buffer_last_index( command, 0, 0 )+1, 0 );
- c8 *tokens[32];
- u32 token_count = 0;
+ struct console_arguments args;
+ args.count = 0;
u32 temp_frame = _start_temporary_frame();
+ struct console_command *target_command = NULL;
- for( u32 i=0; i<32; i ++ )
+ // TODO: warning if we put to many or to few arguments & required ones.
+ for( u32 i=0; i<ARRAY_COUNT(args.arguments)+1; i ++ )
{
u32 start, length;
enum string_parse_result info = string_parse_string( &string, &start, &length, '"' );
if( info == k_string_parse_ok )
{
- tokens[ token_count ] = _temporary_allocate( length + 1, 4 );
- buffer_copy( command + start, length, tokens[ token_count ], length );
- tokens[ token_count ][ length ] = 0;
- token_count ++;
+ if( i == 0 )
+ {
+ for( u32 j=0; j<ARRAY_COUNT(_console_commands); j ++ )
+ {
+ struct console_command *cmd = &_console_commands[j];
+ if( compare_buffers( cmd->alias, 0, command+start, length ) )
+ {
+ target_command = cmd;
+ break;
+ }
+ }
+
+ if( !target_command )
+ {
+ $log( $error, {"There is no command called '"}, $string( command+start, .length=length ), {"'"} );
+ return;
+ }
+ }
+ else
+ {
+ c8 *buffer = _temporary_allocate( length + 1, 4 );
+ buffer_copy( command + start, length, buffer, length );
+ buffer[ length ] = 0;
- $log( $info, {":: "}, {tokens[ token_count ]} );
+ args.arguments[ args.count ] = buffer;
+ args.count ++;
+ }
}
+ else break;
}
+ if( target_command )
+ target_command->fn( &args );
+
_end_temporary_frame( temp_frame );
}
+
+const c8 *console_get_argument( struct console_arguments *args, u32 index )
+{
+ if( index < args->count )
+ return args->arguments[ index ];
+ else
+ return NULL;
+}
+
+void _console_init(void)
+{
+ _console_execute( "exec cfg/default.cfg", 1, 0 );
+}
#include "generated/console.h"
+
+void _console_init(void);
+void _console_execute( const c8 *command, bool silent, bool cheat_allowed );
+
+struct console_arguments
+{
+ const c8 *arguments[ 32 ];
+ u32 count;
+};
+const c8 *console_get_argument( struct console_arguments *args, u32 index );
#include "glfw.h"
#include "engine_interface.h"
+#include "console_core.h"
#include "generated/input.c"
+struct input_alias
+{
+ const c8 *alias;
+ u8 device_type;
+ u32 key, mod;
+ u32 alias_hash;
+}
+_input_aliases[] =
+{
+ { "SPACE", k_input_device_keyboard, .key = GLFW_KEY_SPACE },
+ { "APOSTROPHE", k_input_device_keyboard, .key = GLFW_KEY_APOSTROPHE },
+ { "COMMA", k_input_device_keyboard, .key = GLFW_KEY_COMMA },
+ { "MINUS", k_input_device_keyboard, .key = GLFW_KEY_MINUS },
+ { "PERIOD", k_input_device_keyboard, .key = GLFW_KEY_PERIOD },
+ { "SLASH", k_input_device_keyboard, .key = GLFW_KEY_SLASH },
+ { "0", k_input_device_keyboard, .key = GLFW_KEY_0 },
+ { "1", k_input_device_keyboard, .key = GLFW_KEY_1 },
+ { "2", k_input_device_keyboard, .key = GLFW_KEY_2 },
+ { "3", k_input_device_keyboard, .key = GLFW_KEY_3 },
+ { "4", k_input_device_keyboard, .key = GLFW_KEY_4 },
+ { "5", k_input_device_keyboard, .key = GLFW_KEY_5 },
+ { "6", k_input_device_keyboard, .key = GLFW_KEY_6 },
+ { "7", k_input_device_keyboard, .key = GLFW_KEY_7 },
+ { "8", k_input_device_keyboard, .key = GLFW_KEY_8 },
+ { "9", k_input_device_keyboard, .key = GLFW_KEY_9 },
+ { "SEMICOLON", k_input_device_keyboard, .key = GLFW_KEY_SEMICOLON },
+ { "EQUAL", k_input_device_keyboard, .key = GLFW_KEY_EQUAL },
+ { "A", k_input_device_keyboard, .key = GLFW_KEY_A },
+ { "B", k_input_device_keyboard, .key = GLFW_KEY_B },
+ { "C", k_input_device_keyboard, .key = GLFW_KEY_C },
+ { "D", k_input_device_keyboard, .key = GLFW_KEY_D },
+ { "E", k_input_device_keyboard, .key = GLFW_KEY_E },
+ { "F", k_input_device_keyboard, .key = GLFW_KEY_F },
+ { "G", k_input_device_keyboard, .key = GLFW_KEY_G },
+ { "H", k_input_device_keyboard, .key = GLFW_KEY_H },
+ { "I", k_input_device_keyboard, .key = GLFW_KEY_I },
+ { "J", k_input_device_keyboard, .key = GLFW_KEY_J },
+ { "K", k_input_device_keyboard, .key = GLFW_KEY_K },
+ { "L", k_input_device_keyboard, .key = GLFW_KEY_L },
+ { "M", k_input_device_keyboard, .key = GLFW_KEY_M },
+ { "N", k_input_device_keyboard, .key = GLFW_KEY_N },
+ { "O", k_input_device_keyboard, .key = GLFW_KEY_O },
+ { "P", k_input_device_keyboard, .key = GLFW_KEY_P },
+ { "Q", k_input_device_keyboard, .key = GLFW_KEY_Q },
+ { "R", k_input_device_keyboard, .key = GLFW_KEY_R },
+ { "S", k_input_device_keyboard, .key = GLFW_KEY_S },
+ { "T", k_input_device_keyboard, .key = GLFW_KEY_T },
+ { "U", k_input_device_keyboard, .key = GLFW_KEY_U },
+ { "V", k_input_device_keyboard, .key = GLFW_KEY_V },
+ { "W", k_input_device_keyboard, .key = GLFW_KEY_W },
+ { "X", k_input_device_keyboard, .key = GLFW_KEY_X },
+ { "Y", k_input_device_keyboard, .key = GLFW_KEY_Y },
+ { "Z", k_input_device_keyboard, .key = GLFW_KEY_Z },
+ { "LEFT_BRACKET", k_input_device_keyboard, .key = GLFW_KEY_LEFT_BRACKET },
+ { "BACKSLASH", k_input_device_keyboard, .key = GLFW_KEY_BACKSLASH },
+ { "RIGHT_BRACKET", k_input_device_keyboard, .key = GLFW_KEY_RIGHT_BRACKET },
+ { "GRAVE_ACCENT", k_input_device_keyboard, .key = GLFW_KEY_GRAVE_ACCENT },
+ { "WORLD_1", k_input_device_keyboard, .key = GLFW_KEY_WORLD_1 },
+ { "WORLD_2", k_input_device_keyboard, .key = GLFW_KEY_WORLD_2 },
+ { "ESCAPE", k_input_device_keyboard, .key = GLFW_KEY_ESCAPE },
+ { "ENTER", k_input_device_keyboard, .key = GLFW_KEY_ENTER },
+ { "TAB", k_input_device_keyboard, .key = GLFW_KEY_TAB },
+ { "BACKSPACE", k_input_device_keyboard, .key = GLFW_KEY_BACKSPACE },
+ { "INSERT", k_input_device_keyboard, .key = GLFW_KEY_INSERT },
+ { "DELETE", k_input_device_keyboard, .key = GLFW_KEY_DELETE },
+ { "RIGHT", k_input_device_keyboard, .key = GLFW_KEY_RIGHT },
+ { "LEFT", k_input_device_keyboard, .key = GLFW_KEY_LEFT },
+ { "DOWN", k_input_device_keyboard, .key = GLFW_KEY_DOWN },
+ { "UP", k_input_device_keyboard, .key = GLFW_KEY_UP },
+ { "PAGE_UP", k_input_device_keyboard, .key = GLFW_KEY_PAGE_UP },
+ { "PAGE_DOWN", k_input_device_keyboard, .key = GLFW_KEY_PAGE_DOWN },
+ { "HOME", k_input_device_keyboard, .key = GLFW_KEY_HOME },
+ { "END", k_input_device_keyboard, .key = GLFW_KEY_END },
+ { "CAPS_LOCK", k_input_device_keyboard, .key = GLFW_KEY_CAPS_LOCK },
+ { "SCROLL_LOCK", k_input_device_keyboard, .key = GLFW_KEY_SCROLL_LOCK },
+ { "NUM_LOCK", k_input_device_keyboard, .key = GLFW_KEY_NUM_LOCK },
+ { "PRINT_SCREEN", k_input_device_keyboard, .key = GLFW_KEY_PRINT_SCREEN },
+ { "PAUSE", k_input_device_keyboard, .key = GLFW_KEY_PAUSE },
+ { "F1", k_input_device_keyboard, .key = GLFW_KEY_F1 },
+ { "F2", k_input_device_keyboard, .key = GLFW_KEY_F2 },
+ { "F3", k_input_device_keyboard, .key = GLFW_KEY_F3 },
+ { "F4", k_input_device_keyboard, .key = GLFW_KEY_F4 },
+ { "F5", k_input_device_keyboard, .key = GLFW_KEY_F5 },
+ { "F6", k_input_device_keyboard, .key = GLFW_KEY_F6 },
+ { "F7", k_input_device_keyboard, .key = GLFW_KEY_F7 },
+ { "F8", k_input_device_keyboard, .key = GLFW_KEY_F8 },
+ { "F9", k_input_device_keyboard, .key = GLFW_KEY_F9 },
+ { "F10", k_input_device_keyboard, .key = GLFW_KEY_F10 },
+ { "F11", k_input_device_keyboard, .key = GLFW_KEY_F11 },
+ { "F12", k_input_device_keyboard, .key = GLFW_KEY_F12 },
+ { "F13", k_input_device_keyboard, .key = GLFW_KEY_F13 },
+ { "F14", k_input_device_keyboard, .key = GLFW_KEY_F14 },
+ { "F15", k_input_device_keyboard, .key = GLFW_KEY_F15 },
+ { "F16", k_input_device_keyboard, .key = GLFW_KEY_F16 },
+ { "F17", k_input_device_keyboard, .key = GLFW_KEY_F17 },
+ { "F18", k_input_device_keyboard, .key = GLFW_KEY_F18 },
+ { "F19", k_input_device_keyboard, .key = GLFW_KEY_F19 },
+ { "F20", k_input_device_keyboard, .key = GLFW_KEY_F20 },
+ { "F21", k_input_device_keyboard, .key = GLFW_KEY_F21 },
+ { "F22", k_input_device_keyboard, .key = GLFW_KEY_F22 },
+ { "F23", k_input_device_keyboard, .key = GLFW_KEY_F23 },
+ { "F24", k_input_device_keyboard, .key = GLFW_KEY_F24 },
+ { "F25", k_input_device_keyboard, .key = GLFW_KEY_F25 },
+ { "KP_0", k_input_device_keyboard, .key = GLFW_KEY_KP_0 },
+ { "KP_1", k_input_device_keyboard, .key = GLFW_KEY_KP_1 },
+ { "KP_2", k_input_device_keyboard, .key = GLFW_KEY_KP_2 },
+ { "KP_3", k_input_device_keyboard, .key = GLFW_KEY_KP_3 },
+ { "KP_4", k_input_device_keyboard, .key = GLFW_KEY_KP_4 },
+ { "KP_5", k_input_device_keyboard, .key = GLFW_KEY_KP_5 },
+ { "KP_6", k_input_device_keyboard, .key = GLFW_KEY_KP_6 },
+ { "KP_7", k_input_device_keyboard, .key = GLFW_KEY_KP_7 },
+ { "KP_8", k_input_device_keyboard, .key = GLFW_KEY_KP_8 },
+ { "KP_9", k_input_device_keyboard, .key = GLFW_KEY_KP_9 },
+ { "KP_DECIMAL", k_input_device_keyboard, .key = GLFW_KEY_KP_DECIMAL },
+ { "KP_DIVIDE", k_input_device_keyboard, .key = GLFW_KEY_KP_DIVIDE },
+ { "KP_MULTIPLY", k_input_device_keyboard, .key = GLFW_KEY_KP_MULTIPLY },
+ { "KP_SUBTRACT", k_input_device_keyboard, .key = GLFW_KEY_KP_SUBTRACT },
+ { "KP_ADD", k_input_device_keyboard, .key = GLFW_KEY_KP_ADD },
+ { "KP_ENTER", k_input_device_keyboard, .key = GLFW_KEY_KP_ENTER },
+ { "KP_EQUAL", k_input_device_keyboard, .key = GLFW_KEY_KP_EQUAL },
+ { "LEFT_SHIFT", k_input_device_keyboard, .key = GLFW_KEY_LEFT_SHIFT },
+ { "LEFT_CONTROL", k_input_device_keyboard, .key = GLFW_KEY_LEFT_CONTROL },
+ { "LEFT_ALT", k_input_device_keyboard, .key = GLFW_KEY_LEFT_ALT },
+ { "LEFT_SUPER", k_input_device_keyboard, .key = GLFW_KEY_LEFT_SUPER },
+ { "RIGHT_SHIFT", k_input_device_keyboard, .key = GLFW_KEY_RIGHT_SHIFT },
+ { "RIGHT_CONTROL", k_input_device_keyboard, .key = GLFW_KEY_RIGHT_CONTROL },
+ { "RIGHT_ALT", k_input_device_keyboard, .key = GLFW_KEY_RIGHT_ALT },
+ { "RIGHT_SUPER", k_input_device_keyboard, .key = GLFW_KEY_RIGHT_SUPER },
+ { "MENU", k_input_device_keyboard, .key = GLFW_KEY_MENU },
+ { "SHIFT", k_input_device_keyboard, .mod = GLFW_MOD_SHIFT },
+ { "CONTROL", k_input_device_keyboard, .mod = GLFW_MOD_CONTROL },
+ { "ALT", k_input_device_keyboard, .mod = GLFW_MOD_ALT },
+ { "SUPER", k_input_device_keyboard, .mod = GLFW_MOD_SUPER },
+};
+
+static struct input_alias *_input_alias_find( const c8 *alias, u32 alias_length )
+{
+ u32 hash = buffer_djb2( alias, alias_length );
+ for( u32 i=0; i<ARRAY_COUNT( _input_aliases ); i ++ )
+ {
+ struct input_alias *alias_i = &_input_aliases[i];
+ if( alias_i->alias_hash == hash )
+ if( compare_buffers( alias_i->alias, 0, alias, alias_length ) )
+ return alias_i;
+ }
+ return NULL;
+}
+
static i32 _input_page = 0;
union input_state
struct bind
{
u16 device, input_index;
- struct
- {
- u32 main, modifiers;
- }
- keyboard;
+ u32 id;
+ u32 modifiers;
};
struct stretchy_allocator _bind_allocator;
+i32 _input_bind_ccmd( struct console_arguments *args )
+{
+ const c8 *buttons = console_get_argument( args, 0 );
+ if( !buttons )
+ {
+ $log( $error, {"Usage: bind <button> <action>"} );
+ return -1;
+ }
+
+ const c8 *input_name = console_get_argument( args, 1 );
+ if( !input_name )
+ {
+ $log( $error, {"Usage: bind <button> <action>"} );
+ return -1;
+ }
+
+ i32 input_id = -1;
+ for( u32 i=0; i<k_input_count; i ++ )
+ {
+ struct input_info *input = &_input_infos[ i ];
+ if( compare_buffers( input->name, 0, input_name, 0 ) )
+ {
+ input_id = i;
+ break;
+ }
+ }
+
+ if( input_id == -1 )
+ {
+ $log( $error, {"Don't know an input called '"}, {input_name}, {"'"} );
+ return -1;
+ }
+
+ struct bind new_bind = { .input_index = input_id };
+ while(1)
+ {
+ i32 plus_index = buffer_first_index( buttons, '+', 0 ),
+ length = plus_index == -1? 0: plus_index;
+
+ struct input_alias *alias = _input_alias_find( buttons, length );
+ if( alias )
+ {
+ if( new_bind.device )
+ {
+ if( alias->device_type != new_bind.device )
+ {
+ $log( $error, {"Device mismatch while parsing buttons"} );
+ return -1;
+ }
+ }
+ else
+ new_bind.device = alias->device_type;
+
+ if( alias->device_type == k_input_device_keyboard )
+ {
+ if( alias->key )
+ {
+ if( new_bind.id )
+ {
+ $log( $error, {"Cannot specify more than one normal buttons in bind"} );
+ return -1;
+ }
+ new_bind.id = alias->key;
+ }
+ else //mod
+ {
+ if( new_bind.id )
+ {
+ $log( $error, {"Modifiers must come first"} );
+ return -1;
+ }
+ new_bind.modifiers |= alias->mod;
+ }
+ }
+ else
+ {
+ // TODO
+ $log( $error, {"Currently dont support device type'"}, $unsigned(alias->device_type), {"'"} );
+ return -1;
+ }
+ }
+ else
+ {
+ $log( $error, {"Don't know what a '"}, $string( buttons, .length = length ), {"' is"} );
+ return -1;
+ }
+
+ if( plus_index == -1 )
+ break;
+ else
+ buttons += plus_index+1;
+ }
+
+ if( (new_bind.device == k_input_device_keyboard) && !new_bind.id )
+ {
+ $log( $error, {"No key specified for bind"} );
+ if( new_bind.modifiers )
+ $log( $info, {"If you're trying to bind SHIFT to a normal button, use LEFT_SHIFT or RIGHT_ALT etc."} );
+ return -1;
+ }
+
+ if( !stretchy_count( &_bind_allocator ) )
+ stretchy_init( &_bind_allocator, sizeof(struct bind ) );
+ struct bind *a = stretchy_append( &_bind_allocator );
+ *a = new_bind;
+ return 0;
+}
+
// bind LEFT ui_left <---- action
// bind RIGHT ui_right <---- action
// bind SHIFT ui_select
struct bind *bind = stretchy_get( &_bind_allocator, i );
if( bind->device == k_input_device_keyboard )
{
- if( bind->keyboard.main == key )
+ if( bind->id == key )
{
struct input_info *input = &_input_infos[ bind->input_index ];
union input_state *state = &_input_states[ _input_page^0x1 ][ bind->input_index ];
{
if( (action == GLFW_PRESS) || (action == GLFW_REPEAT) )
{
- if( bind->keyboard.modifiers == mods )
+ if( bind->modifiers == mods )
{
ASSERT_CRITICAL( state->action.activation_count < 255 );
state->action.activation_count ++;
void _input_init(void)
{
glfwSetKeyCallback( _engine.window_handle, _input_key_callback );
+ for( u32 i=0; i<ARRAY_COUNT( _input_aliases ); i ++ )
+ _input_aliases[i].alias_hash = buffer_djb2( _input_aliases[i].alias, 0 );
}
void _input_update(void)
{
- static bool tester = 0;
- if( !tester )
- {
- stretchy_init( &_bind_allocator, sizeof(struct bind) );
- struct bind *bind = stretchy_append( &_bind_allocator );
- bind->device = k_input_device_keyboard;
- bind->input_index = k_input_action_console;
- bind->keyboard.main = GLFW_KEY_GRAVE_ACCENT;
- bind->keyboard.modifiers = GLFW_MOD_SHIFT;
- tester = 1;
- }
-
/* flip to read page and reset the reciever one */
_input_page ^= 0x1;
for( u32 i=0; i<k_input_count; i ++ )
#include "opengl.h"
#include "glfw.h"
+// TODO: temp
+#include "console_core.h"
+
struct _engine _engine;
struct
/* ------------- */
_engine_ui_init();
_input_init();
+ _console_init();
L_new_frame:;
f64 now = glfwGetTime();
struct stream *_log_event( u32 type, const c8 *code_location )
{
struct stream *output = _get_console_stream();
- string_append( output, KBLK );
+ string_append( output, KBLK, 0 );
u32 line_start = output->offset;
i32 s = buffer_last_index( code_location, '/', 0 );
if( s != -1 )
{
- string_append( output, "..." );
+ string_append( output, "...", 0 );
code_location += s+1;
}
- string_append( output, code_location );
+ string_append( output, code_location, 0 );
while( (output->offset-line_start) < 32 ) string_append_c8( output, ' ' );
- if( type == $error ) string_append( output, KRED "ERR|" );
- else if( type == $warning ) string_append( output, KYEL "WRN|" );
- else if( type == $ok ) string_append( output, KGRN "OK |" );
- else if( type == $info ) string_append( output, KNRM "LOG|" );
- else if( type == $low ) string_append( output, KNRM "LOW|" );
- else if( type == $fatal ) string_append( output, KRED "!!!|" );
- else if( type == $shell ) string_append( output, KBLU "SHL|" );
- string_append( output, KNRM );
+ if( type == $error ) string_append( output, KRED "ERR|", 0 );
+ else if( type == $warning ) string_append( output, KYEL "WRN|", 0 );
+ else if( type == $ok ) string_append( output, KGRN "OK |", 0 );
+ else if( type == $info ) string_append( output, KNRM "LOG|", 0 );
+ else if( type == $low ) string_append( output, KNRM "LOW|", 0 );
+ else if( type == $fatal ) string_append( output, KRED "!!!|", 0 );
+ else if( type == $shell ) string_append( output, KBLU "SHL|", 0 );
+ string_append( output, KNRM, 0 );
return output;
}
u32 base_offset = console->offset;
if( option->type == k_option_type_flag || option->type == k_option_type_option )
{
- string_append( console, "-" );
+ string_append( console, "-", 0 );
string_append_c8( console, option->alias_c );
if( option->type == k_option_type_option )
- string_append( console, " <value>" );
+ string_append( console, " <value>", 0 );
}
if( option->type == k_option_type_long_flag || option->type == k_option_type_long_option )
{
- string_append( console, "--" );
- string_append( console, option->alias );
+ string_append( console, "--", 0 );
+ string_append( console, option->alias, 0 );
if( option->type == k_option_type_long_option )
- string_append( console, "=<value>" );
+ string_append( console, "=<value>", 0 );
}
while( console->offset < base_offset + 60 )
string_append_c8( console, ' ' );
- string_append( console, desc );
+ string_append( console, desc, 0 );
string_append_c8( console, '\n' );
}
_normal_exit();
{
if( !(argument->used & (0x1<<j)) )
{
- string_append( console, "Unknown option '" );
+ string_append( console, "Unknown option '", 0 );
string_append_c8( console, argument->name[j] );
- string_append( console, "'\n" );
+ string_append( console, "'\n", 0 );
}
}
}
else
{
- string_append( console, "Unknown option '" );
- string_append( console, argument->name );
- string_append( console, "'\n" );
+ string_append( console, "Unknown option '", 0 );
+ string_append( console, argument->name, 0 );
+ string_append( console, "'\n", 0 );
}
errors = 1;
}
stream_write( string, NULL, 0 );
}
-void string_append( struct stream *string, const c8 *substring )
+void string_append( struct stream *string, const c8 *substring, u32 length )
{
- stream_write( string, substring, buffer_last_index( substring, 0, 0 ) );
+ stream_write( string, substring, length? length: buffer_last_index( substring, 0, 0 ) );
}
void string_append_c8( struct stream *string, c8 c )
else if( arg->type == k_$float )
string_append_f64( string, arg->_f64, arg->base? arg->base: 10, arg->decimals? arg->decimals: 2 );
else if( arg->type == k_$string )
- string_append( string, arg->_string );
+ string_append( string, arg->_string, arg->length );
else if( arg->type == k_$errno )
{
- string_append( string, "<errno#" );
+ string_append( string, "<errno#", 0 );
string_append_u64( string, errno, 10 );
- string_append( string, " (" );
- string_append( string, strerror(errno) );
- string_append( string, ")>" );
+ string_append( string, " (", 0 );
+ string_append( string, strerror(errno), 0 );
+ string_append( string, ")>", 0 );
}
}
}
struct
{
c8 project_name[ 128 ];
- struct stream source_list, include_path_list, define_list;
+ struct stream source_list, include_path_list, define_list, configuration;
const c8 *enabled_features[ 64 ];
}
static _metacompiler;
{
bool using;
struct stream layer_enums;
- struct stream input_enums, input_structures, cfg;
+ struct stream input_enums, input_structures;
}
static _input;
struct
{
bool using;
- struct stream cvar_header, cvar_definitions;
+ struct stream cvar_header, cvar_definitions, command_prototypes, command_definitions;
+ u32 command_count;
}
static _console;
k_target_input_layer,
k_target_input,
k_target_shader,
- k_target_cvar
+ k_target_cvar,
+ k_target_ccmd
}
target;
u32 feature_count;
$v_string( &_console.cvar_header, {"extern "}, {type}, {" cvar_"}, {name}, {";\n"} );
$v_string( &_console.cvar_definitions, {type}, {" cvar_"}, {name}, {" = "}, {default_value}, {";\n"} );
}
+ else if( compare_buffers( block_key, 0, "ccmd", 0 ))
+ {
+ _console.using = 1;
+ _console.command_count ++;
+ context.target = k_target_ccmd;
+ const c8 *name = keyvalues_read_string( kvs, block, "name", NULL );
+ const c8 *function = keyvalues_read_string( kvs, block, "function", NULL );
+ ASSERT_CRITICAL( name && function );
+ $v_string( &_console.command_definitions, {" {\n .alias = \""}, {name}, {"\",\n .fn = "},
+ {function}, {"\n },\n"} );
+ $v_string( &_console.command_prototypes, {"i32 "}, {function}, {"( struct console_arguments *args );\n"} );
+ // TODO: process parameter descriptions
+ return;
+ }
else if( compare_buffers( block_key, 0, "shader", 0 ))
context.target = k_target_shader;
else
{
struct stream path_string;
stream_open_stack( &path_string, _temporary_stack_allocator(), k_stream_null_terminate );
- $v_string( &path_string, {context.folder}, {"/"}, {keyvalues_value( kvs, kv, NULL )} );
+ $v_string( &path_string, {context.folder}, {"/"}, {value} );
_append_kv_list( string_get( &path_string ), context );
}
_end_temporary_frame( temp_frame );
}
+ if( compare_buffers( key, 0, "config", 0 ) )
+ $v_string( &_metacompiler.configuration, {value}, {"\n"} );
+
if( context.target == k_target_main )
{
if( compare_buffers( key, 0, "name", 0 ) )
stream_open_buffer_write( &_metacompiler.source_list, _heap_allocate(size), size, options );
stream_open_buffer_write( &_metacompiler.include_path_list, _heap_allocate(size), size, options );
stream_open_buffer_write( &_metacompiler.define_list, _heap_allocate(size), size, options );
+ stream_open_buffer_write( &_metacompiler.configuration, _heap_allocate(size), size, options );
stream_open_buffer_write( &_input.layer_enums, _heap_allocate(size), size, options );
stream_open_buffer_write( &_input.input_enums, _heap_allocate(size), size, options );
stream_open_buffer_write( &_input.input_structures, _heap_allocate(size), size, options );
- stream_open_buffer_write( &_input.cfg, _heap_allocate(size), size, options );
stream_open_buffer_write( &_console.cvar_header, _heap_allocate(size), size, options );
stream_open_buffer_write( &_console.cvar_definitions, _heap_allocate(size), size, options );
+ stream_open_buffer_write( &_console.command_definitions, _heap_allocate(size), size, options );
+ stream_open_buffer_write( &_console.command_prototypes, _heap_allocate(size), size, options );
if( platform == k_platform_linux ) _metacompiler.enabled_features[0] = "linux";
if( platform == k_platform_windows ) _metacompiler.enabled_features[0] = "windows";
{
struct stream input_header, input_source;
ASSERT_CRITICAL( stream_open_file( &input_header, "generated/input.h", k_stream_write ) );
- $v_string( &input_header, {"enum input_layer_id\n{\n"}, $string( &_input.layer_enums ), {" k_input_layer_count\n};\n"} );
- $v_string( &input_header, {"enum input_id\n{\n"}, $string( &_input.input_enums ), {" k_input_count\n};\n"} );
+ $v_string( &input_header, {"enum input_layer_id\n{\n"}, {string_get( &_input.layer_enums )}, {" k_input_layer_count\n};\n"} );
+ $v_string( &input_header, {"enum input_id\n{\n"}, {string_get( &_input.input_enums )}, {" k_input_count\n};\n"} );
stream_close( &input_header );
ASSERT_CRITICAL( stream_open_file( &input_source, "generated/input.c", k_stream_write ) );
$v_string( &input_source, {"struct input_info _input_infos[k_input_count] = \n{\n"},
- $string( &_input.input_structures ), {"};\n"} );
+ {string_get( &_input.input_structures )}, {"};\n"} );
stream_close( &input_source );
}
{
struct stream console_header, console_source;
ASSERT_CRITICAL( stream_open_file( &console_header, "generated/console.h", k_stream_write ) );
- $v_string( &console_header, $string( &_console.cvar_header ) );
+ $v_string( &console_header, {string_get( &_console.cvar_header )} );
stream_close( &console_header );
ASSERT_CRITICAL( stream_open_file( &console_source, "generated/console.c", k_stream_write ) );
- $v_string( &console_source, $string( &_console.cvar_definitions ) );
+ $v_string( &console_source, {string_get( &_console.cvar_definitions )} );
+ $v_string( &console_source, {string_get( &_console.command_prototypes )} );
+ $v_string( &console_source, {"static struct console_command _console_commands[] = \n{\n"},
+ {string_get( &_console.command_definitions )}, {"};\n\n"} );
stream_close( &console_source );
}
struct stream folder_string;
stream_open_stack( &folder_string, _temporary_stack_allocator(), k_stream_null_terminate );
- $v_string( &folder_string, {output_folder}, {"/bin/"}, {_metacompiler.project_name}, {"-"}, $string(&tripple_string) );
+ $v_string( &folder_string, {output_folder}, {"/bin/"}, {_metacompiler.project_name}, {"-"}, {string_get(&tripple_string)} );
free(output_folder);
struct stream command_string;
stream_open_stack( &command_string, _temporary_stack_allocator(), k_stream_null_terminate );
- $v_string( &command_string, {"mkdir -p "}, $string( &folder_string ) );
+ $v_string( &command_string, {"mkdir -p "}, {string_get( &folder_string )} );
system_call( string_get( &command_string ) );
if( use_tsan ) $v_string( &command_string, {" -fsanitize=thread -lasan \\\n"} );
if( use_asan ) $v_string( &command_string, {" -fsanitize=address -lasan \\\n"} );
- $v_string( &command_string, {" -target "}, $string(&tripple_string), {" "} );
+ $v_string( &command_string, {" -target "}, {string_get(&tripple_string)}, {" "} );
if( platform == k_platform_windows )
{
if( !shared )
$v_string( &command_string, {" -fkeep-static-consts -fkeep-persistent-storage-variables \\\n"} );
$v_string( &command_string, {" -I. \\\n"} );
- $v_string( &command_string, $string( &_metacompiler.include_path_list ) );
- $v_string( &command_string, $string( &_metacompiler.define_list ) );
- $v_string( &command_string, $string( &_metacompiler.source_list ) );
+ $v_string( &command_string, {string_get( &_metacompiler.include_path_list )} );
+ $v_string( &command_string, {string_get( &_metacompiler.define_list )} );
+ $v_string( &command_string, {string_get( &_metacompiler.source_list )} );
- $v_string( &command_string, {"-o "}, $string( &folder_string ), {"/"}, {_metacompiler.project_name} );
+ $v_string( &command_string, {"-o "}, {string_get( &folder_string )}, {"/"}, {_metacompiler.project_name} );
if( platform == k_platform_windows ) $v_string( &command_string, {shared? ".dll ": ".exe "} );
else $v_string( &command_string, {shared? ".so ": " "} );
system_call( string_get( &command_string ) );
+
+ if( _console.using )
+ {
+ u32 temp_frame2 = _start_temporary_frame();
+ struct stream command_string;
+ stream_open_stack( &command_string, _temporary_stack_allocator(), k_stream_null_terminate );
+ $v_string( &command_string, {"mkdir -p "}, {string_get( &folder_string )}, {"/cfg"} );
+ system_call( string_get( &command_string ) );
+
+ struct stream config_path;
+ stream_open_stack( &config_path, _temporary_stack_allocator(), k_stream_null_terminate );
+ $v_string( &config_path, {string_get( &folder_string )}, {"/cfg/default.cfg"} );
+
+ struct stream config_file;
+ ASSERT_CRITICAL( stream_open_file( &config_file, string_get( &config_path ), k_stream_write ) );
+ $v_string( &config_file, {string_get( &_metacompiler.configuration )} );
+ stream_close( &config_file );
+
+ _end_temporary_frame( temp_frame2 );
+ }
}
_end_temporary_frame( temp_frame );
return 0;