diff options
| author | JustSomePwner <crotchyalt@gmail.com> | 2018-08-30 14:01:54 +0200 |
|---|---|---|
| committer | JustSomePwner <crotchyalt@gmail.com> | 2018-08-30 14:01:54 +0200 |
| commit | 7ccb819f867493f8ec202ea3b39c94c198c64584 (patch) | |
| tree | 94622e61af0ff359e3d6689cf274d74f60b2492a /gmod/console.cpp | |
| parent | 564d979b79e8a5aaa5014eba0ecd36c61575934f (diff) | |
first
Diffstat (limited to 'gmod/console.cpp')
| -rw-r--r-- | gmod/console.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/gmod/console.cpp b/gmod/console.cpp new file mode 100644 index 0000000..174fc25 --- /dev/null +++ b/gmod/console.cpp @@ -0,0 +1,324 @@ +#include "console.hpp"
+#include "interface.hpp"
+#include "settings.hpp"
+#include "d3d.hpp"
+#include "ui_draw.h"
+
+std::shared_ptr< console > g_con = std::make_shared< console >( );
+
+
+void console::draw_text( int x, int y, bool greyed, const char* fmt, ... ) {
+ va_list args;
+ char buf[ 512 ];
+
+ __crt_va_start( args, fmt );
+ vsprintf_s< 512 >( buf, fmt, args );
+ __crt_va_end( args );
+
+ g_d3d.draw_text< ALIGN_LEFT >( d3d::fonts.f_con, greyed ? clr_t( 160, 160, 160 ) : clr_t( 255, 255, 255 ), x, y, D3DFONTFLAG_DROPSHADOW, "%s", buf );
+ //g_d3d.draw_text< ALIGN_LEFT >( d3d::fonts.f_con, greyed ? clr_t( 160, 160, 160 ) : clr_t( 255, 255, 255 ), x, y, D3DFONTFLAG_DROPSHADOW, buf );
+}
+
+void console::draw_text( int x, int y, const char* fmt, ... ) {
+ va_list args;
+ char buf[ 512 ];
+
+ __crt_va_start( args, fmt );
+ vsprintf_s< 512 >( buf, fmt, args );
+ __crt_va_end( args );
+
+ g_d3d.draw_text< ALIGN_LEFT >( d3d::fonts.f_con, clr_t( 255, 255, 255 ), x, y, D3DFONTFLAG_DROPSHADOW, buf );
+}
+
+void console::draw_rect( int x, int y, int w, int h, clr_t col ) {
+ g_d3d.draw_filled_rect( col, x, y, w, h );
+}
+
+void console::register_alias( std::shared_ptr< ISetting >& alias ) {
+ m_aliases.push_back( alias );
+}
+
+void console::capture_command( ) {
+ float current_time = GetTickCount( ) * 0.001f;
+ size_t length = strlen( m_cur_cmd );
+
+ for( size_t i{ }; i < 0xfe; ++i ) {
+ if( m_input->is_key_pressed( i ) ) {
+ float delta_time = current_time - m_last_key_input[ i ];
+ if( fabs( delta_time ) > 0.2f ) {
+ if( i == KEYS_BACK ) {
+ m_cur_cmd[ length - 1 ] = 0;
+ m_last_key_input[ i ] = current_time;
+ continue;
+ }
+
+ m_key_states[ i ] = 0xf0;
+ wchar_t pressed_char;
+ const auto scan = MapVirtualKeyA( i, 2 );
+ auto ret = ToAscii( i, scan, ( BYTE* )m_key_states, ( LPWORD )&pressed_char, 1 );
+
+ if( ret == 1 ) {
+ if( length < 200 ) {
+ m_cur_cmd[ length ] = ( char )( pressed_char );
+ m_cur_cmd[ length + 1 ] = 0;
+ }
+ }
+ m_last_key_input[ i ] = current_time;
+ }
+ }
+ else {
+ m_last_key_input[ i ] = 0.f;
+ m_key_states[ i ] = 0;
+ }
+ }
+}
+
+ISetting* console::find_var( hash_t var ) {
+ for( auto& it : data::holder_.get_nodes( ) ) {
+ auto setting = static_cast< ISetting* >( it );
+ if( var == setting->get_hash( ) ) {
+ return setting;
+ }
+ }
+
+ return nullptr;
+}
+
+ISetting* console::find_alias( hash_t alias ) {
+ for( auto& it : m_aliases ) {
+ if( it->get_hash( ) == alias )
+ return it.get( );
+ }
+
+ return nullptr;
+}
+
+con_fn_base* console::find_fn( hash_t name ) {
+ for( auto& it : m_functions ) {
+ if( it->get_hash( ) == name ) {
+ return it;
+ }
+ }
+
+ return nullptr;
+}
+
+std::string console::impl_alias_str( std::string str ) {
+ for( size_t i{ }; i < str.length( ); ++i ) {
+ if( str[ i ] == ' ' && str[ i + 1 ] != ' ' ) {
+ size_t end = 0;
+ for( size_t i2{ i + 1 }; i2 < str.length( ); ++i ) {
+ if( str[ i2 ] == ' ' )
+ end = i2;
+ }
+
+ if( end ) {
+ std::string alias_str( str.c_str( ) + i, end - i );
+ auto alias = find_alias( hash::fnv1a( alias_str ) );
+ if( alias ) {
+ str.replace( alias_str.begin( ), alias_str.end( ), alias->get_string( ) );
+ }
+ else {
+ g_con->log( xors( "couldnt find alias %s" ), alias_str.c_str( ) );
+ }
+ }
+ }
+ }
+
+ return str;
+}
+
+void console::execute_command( const char* cmd ) {
+ if( !cmd[ 0 ] ) return;
+ std::string first_param( cmd, strlen( cmd ) );
+
+ size_t end{ };
+ bool one_arg = true;
+ for( size_t i{ }; i < strlen( cmd ); ++i ) {
+ if( cmd[ i ] == ' ' ) {
+ first_param.resize( i );
+ end = i;
+ one_arg = false;
+ break;
+ }
+ }
+
+ if( one_arg ) {
+ first_param.resize( first_param.length( ) - 1 );
+ }
+
+ //find a command to execute
+ auto fn = find_fn( hash::fnv1a( first_param ) );
+ if( fn ) {
+ //std::string alias_cmd = impl_alias_str( cmd );
+
+ if( !fn->execute( cmd ) ) {
+ log( xors( "invalid syntax" ) );
+ }
+ return;
+ }
+
+ //command not found, we're managing vars
+ if( !one_arg ) {
+ std::string second_param = ( cmd + end + 1 );
+ bool is_floating_point = second_param.find( '.' ) != std::string::npos;
+ auto var = find_var( hash::fnv1a( first_param ) );
+
+ if( var ) {
+ auto setting_cast = static_cast< con_var< void* >* >( var );
+ if( !setting_cast->is_integral( ) && !setting_cast->is_floating_point( ) ) {
+ auto value = std::strtol( second_param.c_str( ), 0, 16 );
+ printf( xors( "value: %08x\n" ), value );
+ var->set( value );
+ }
+
+ if( is_floating_point ) {
+ float value = std::strtof( second_param.c_str( ), 0 );
+ var->set( value );
+ }
+ else {
+ int value = std::strtol( second_param.c_str( ), 0, 10 );
+ var->set( value );
+ }
+ log( xors( "%s %s\n" ), first_param.c_str( ), second_param.c_str( ) );
+ return;
+ }
+ }
+
+
+ log( xors( "unknown command: %s" ), first_param.c_str( ) );
+}
+
+void console::input( ) {
+ static int drag_x, drag_y;
+ int cursor_x, cursor_y;
+ int x = m_x, y = m_y;
+ bool clicked = m_input->is_key_pressed( KEYS_MOUSE1 );
+ static bool is_hovered{ };
+ m_input->get_cursor_pos( cursor_x, cursor_y );
+
+ auto is_top_hovered = [ &x, &y,
+ &cursor_x, &cursor_y ]( ) {
+ return cursor_x > x && cursor_x < x + WIDTH
+ && cursor_y > y && cursor_y < y + TOP_HEIGHT;
+ };
+
+ auto is_window_hovered = [ &x, &y,
+ &cursor_x, &cursor_y ]( ) {
+ return cursor_x > x && cursor_x < x + WIDTH
+ && cursor_y > y && cursor_y < y + HEIGHT;
+ };
+
+ auto is_bottom_hovered = [ &x, &y,
+ &cursor_x, &cursor_y ]( ) {
+ return cursor_x > x && cursor_x < x + WIDTH
+ && cursor_y > y + HEIGHT - TOP_HEIGHT
+ && cursor_y < y + HEIGHT;
+ };
+
+ if( clicked ) {
+ //m_consuming_input = is_window_hovered( );
+ }
+
+ if( !clicked && is_top_hovered( ) ) {
+ drag_x = cursor_x - m_x;
+ drag_y = cursor_y - m_y;
+ }
+
+ if( clicked && is_hovered ) {
+ is_hovered = true;
+ m_x = cursor_x - drag_x;
+ m_y = cursor_y - drag_y;
+ }
+ else {
+ is_hovered = is_top_hovered( );
+ }
+
+ if( clicked ) {
+ m_active = is_bottom_hovered( );
+ }
+
+ if( m_active ) {
+ capture_command( );
+
+ static bool was_held{ };
+ if( m_input->is_key_pressed( KEYS_RETURN ) ) {
+ if( !was_held ) {
+ execute_command( m_cur_cmd );
+ m_cur_cmd[ 0 ] = 0;
+ }
+ was_held = true;
+ }
+ else was_held = false;
+ }
+}
+
+void console::draw( ) {
+ if( !m_open ) {
+ m_consuming_input = false;
+ m_active = false;
+ return;
+ }
+
+ static clr_t col = clr_t( 31, 31, 31, 255 );
+
+ input( );
+
+ RECT prev_rect{ };
+ RECT new_rect{ m_x - 1, m_y - 1,
+ m_x + WIDTH + 1, m_y + HEIGHT + 1 };
+ g_d3d.get_device( )->GetScissorRect( &prev_rect );
+
+ g_d3d.get_device( )->SetScissorRect( &new_rect );
+
+ draw_rect( m_x - 1, m_y - 1, WIDTH + 2, HEIGHT + 2, ui::ui_get_accent_col( ) );
+ draw_rect( m_x, m_y, WIDTH, HEIGHT, col );
+ draw_rect( m_x + 1, m_y, WIDTH - 2, TOP_HEIGHT, clr_t( 41, 41, 41 ) );
+
+ draw_rect( m_x + 1, m_y + HEIGHT - TOP_HEIGHT, WIDTH - 2, TOP_HEIGHT, clr_t( 41, 41, 41 ) );
+ if( m_active ) {
+ draw_rect( m_x + 2, m_y + HEIGHT - TOP_HEIGHT + 1, WIDTH - 4, TOP_HEIGHT - 2, clr_t( 31, 31, 31 ) );
+ auto fn = find_fn( hash::fnv1a( m_cur_cmd ) );
+ if( fn ) {
+ std::string fn_str = m_cur_cmd;
+ fn_str += ' ';
+ fn_str += fn->get_syntax( );
+
+ draw_text( m_x + 2, m_y + HEIGHT - TOP_HEIGHT / 2 - 3, true, "%s", fn_str.c_str( ) );
+ }
+
+ else {
+ auto var = find_var( hash::fnv1a( m_cur_cmd ) );
+ if( var ) {
+ std::string var_str = m_cur_cmd;
+ var_str += ' ';
+
+ var_str += var->get_string( );
+
+ draw_text( m_x + 2, m_y + HEIGHT - TOP_HEIGHT / 2 - 3, true, var_str.c_str( ) );
+ }
+ }
+ }
+
+ std::string cur_cmd_str = m_cur_cmd;
+ if( m_active ) {
+ cur_cmd_str += '_';
+ }
+ draw_text( m_x + 2, m_y + HEIGHT - TOP_HEIGHT / 2 - 3, cur_cmd_str.c_str( ) );
+ draw_text( m_x + 3, m_y + TOP_HEIGHT / 2 - 3, xors( "console" ) );
+
+ int cur_y = m_y + HEIGHT - TOP_HEIGHT;
+ for( int i = m_logs.size( ) - 1; i >= 0; --i ) {
+ constexpr int LINE_HEIGHT = 14;
+ auto& log = m_logs.at( i );
+
+ if( cur_y - LINE_HEIGHT < m_y + TOP_HEIGHT ) {
+ m_logs.erase( m_logs.begin( ) + i );
+ continue;
+ }
+
+ draw_text( m_x + 2, cur_y -= LINE_HEIGHT, log.m_msg );
+ }
+
+ g_d3d.get_device( )->SetScissorRect( &prev_rect );
+}
\ No newline at end of file |
