diff --git a/src/core/menu/framework.cpp b/src/core/menu/framework.cpp index 4eccf0e..9c6a959 100644 --- a/src/core/menu/framework.cpp +++ b/src/core/menu/framework.cpp @@ -11,13 +11,11 @@ void gui::framework::set_theme( bool dark ) { colors::bg = color_t( 255, 255, 255, 255 ); colors::fg = color_t( 200, 200, 200, 255 ); colors::text = color_t( 0, 0, 0, 200 ); - colors::accent = color_t( 66, 128, 244, 255 ); colors::disabled = color_t( 0, 0, 0, 64 ); } else { colors::bg = color_t( 21, 21, 21, 255 ); colors::fg = color_t( 59, 59, 59, 255 ); colors::text = color_t( 255, 255, 255, 64 ); - colors::accent = color_t( 66, 128, 244, 255 ); colors::disabled = color_t( 255, 255, 255, 2 ); } } @@ -30,8 +28,8 @@ void gui::framework::begin( vec2_t pos, vec2_t size ) { cur_menu.cursor = vec2_t( 8, 8 ); - // block input to other controls when a dropdown is open - cur_menu.block_input = !cur_dropdown.id.empty( ); + // block input to other controls when a dropdown or colorpicker is open + cur_menu.block_input = !cur_dropdown.id.empty( ) || !cur_colorpicker.id.empty( ); photon->render->draw_rounded_rect( cur_menu.pos.x, cur_menu.pos.y, cur_menu.size.x, cur_menu.size.y, colors::bg, 8 ); @@ -75,6 +73,9 @@ void gui::framework::end( ) { } else scroll_offset = 0; // reset scroll offset if content can fit in page + interfaces::surface->set_clip_rect( 0, 0, photon->render->get_screen_size( ).x, photon->render->get_screen_size( ).y ); + interfaces::surface->enable_clipping = false; + // draw dropdowns if ( !cur_dropdown.id.empty( ) ) { auto cur_pos = cur_dropdown.pos; @@ -110,8 +111,102 @@ void gui::framework::end( ) { } } - interfaces::surface->set_clip_rect( 0, 0, photon->render->get_screen_size( ).x, photon->render->get_screen_size( ).y ); - interfaces::surface->enable_clipping = false; + // draw colorpickers + if ( !cur_colorpicker.id.empty( ) ) { + auto cur_pos = cur_colorpicker.pos; + + auto size = vec2_t( 220, 200 ); + + cur_pos.x += 20; + + photon->render->draw_rounded_rect( cur_pos.x, cur_pos.y, size.x, size.y, colors::fg, 8 ); + photon->render->draw_rounded_rect( cur_pos.x + 1, cur_pos.y + 1, size.x - 2, size.y - 2, colors::bg, 8 ); + + cur_pos += vec2_t( 8, 8 ); + size -= vec2_t( 16, 16 ); + + const auto width = size.x - 24; + const auto height = size.y - 20; + + /* logic */ + bool hover_sv = photon->input->is_cursor_in_area( cur_pos.x, cur_pos.y, cur_pos.x + width - 2, cur_pos.y + height - 2 ); + bool hover_h = photon->input->is_cursor_in_area( cur_pos.x + size.x - 18, cur_pos.y, cur_pos.x + size.x - 18 + 20, cur_pos.y + height - 2 ); + bool hover_a = photon->input->is_cursor_in_area( cur_pos.x, cur_pos.y + size.y - 14, cur_pos.x + width - 2, cur_pos.y + size.y - 14 + 14 ); + bool holding = photon->input->get_key_held( mouse_left ); + bool clicking = photon->input->get_key_press( mouse_left ); + + float& h = cur_colorpicker.h; + float& s = cur_colorpicker.s; + float& v = cur_colorpicker.v; + float& a = cur_colorpicker.a; + + // clicking out + // HACK: check if not first frame by checking if alpha is initialized + if ( a != -1 && clicking && !hover_sv && !hover_h && !hover_a ) { + cur_colorpicker = colorpicker_t( ); + return; + } + + a = cur_colorpicker.value.a / 255.f; + +#define SV_ID "photon colorpicker sv" +#define H_ID "photon colorpicker h" +#define A_ID "photon colorpicker a" + + if ( holding && cur_slider.empty( ) ) { + if ( hover_sv ) + cur_slider = SV_ID; + else if ( hover_h ) + cur_slider = H_ID; + else if ( hover_a ) + cur_slider = A_ID; + } else if ( !holding && !cur_slider.empty( ) ) + cur_slider.clear( ); + + if ( cur_slider == SV_ID ) { + s = std::clamp( ( photon->input->get_cursor_position( ).x - cur_pos.x ) / ( width - 2 ), 0.f, 1.f ); + v = 1.f - std::clamp( ( photon->input->get_cursor_position( ).y - cur_pos.y ) / ( height - 2 ), 0.f, 1.f ); + } else if ( cur_slider == H_ID ) + h = std::clamp( ( photon->input->get_cursor_position( ).y - cur_pos.y ) / ( height - 2 ), 0.f, 1.f ); + else if ( cur_slider == A_ID ) + a = std::clamp( ( photon->input->get_cursor_position( ).x - cur_pos.x ) / ( width - 2 ), 0.f, 1.f ); + +#undef SV_ID +#undef H_ID +#undef A_ID + + color_t col = color_t::from_hsv( h, s, v ); + col.a = a * 255; + + cur_colorpicker.value = col; + + /* drawing */ + // saturation, value + photon->render->draw_outlined_rect( cur_pos.x - 1, cur_pos.y - 1, width + 2, height + 2, colors::fg ); + photon->render->draw_gradient( cur_pos.x, cur_pos.y, width, height, { 255, 255, 255 }, color_t::from_hsv( h, 1.f, 1.f ), true ); + photon->render->draw_gradient( cur_pos.x, cur_pos.y, width, height, { 0, 0, 0, 0 }, { 0, 0, 0 }, false ); + + // hue + photon->render->draw_outlined_rect( cur_pos.x + size.x - 18 - 1, cur_pos.y - 1, 20, height + 2, colors::fg ); + photon->render->draw_texture( cur_pos.x + size.x - 18, cur_pos.y, 18, height, "photon_hue_gradient" ); + + // alpha + photon->render->draw_outlined_rect( cur_pos.x - 1, cur_pos.y + size.y - 14 - 1, width + 2, 16, colors::fg ); + photon->render->draw_filled_rect( cur_pos.x, cur_pos.y + size.y - 14, width, 14, col ); + + /* draw cursors */ + // saturation, value + photon->render->draw_outlined_rect( cur_pos.x + s * ( width - 2 ) - 1, cur_pos.y + ( 1.f - v ) * ( height - 2 ) - 1, 4, 4, colors::gray ); + photon->render->draw_filled_rect( cur_pos.x + s * ( width - 2 ), cur_pos.y + ( 1.f - v ) * ( height - 2 ), 2, 2, { 255, 255, 255, 64 } ); + + // hue + photon->render->draw_outlined_rect( cur_pos.x + size.x - 18 - 1, cur_pos.y + h * ( height - 2 ) - 1, 20, 3, colors::gray ); + photon->render->draw_filled_rect( cur_pos.x + size.x - 18, cur_pos.y + h * ( height - 2 ), 18, 1, { 255, 255, 255, 64 } ); + + // alpha + photon->render->draw_outlined_rect( cur_pos.x + a * ( width - 2 ) - 1, cur_pos.y + size.y - 14 - 1, 3, 16, colors::gray ); + photon->render->draw_filled_rect( cur_pos.x + a * ( width - 2 ), cur_pos.y + size.y - 14, 1, 14, { 255, 255, 255, 64 } ); + } } bool gui::framework::tab( int& selected, vec2_t pos, vec2_t size, const std::string& label, bool texture ) { @@ -302,14 +397,15 @@ void gui::framework::slider( int& val, int min, int max, const std::string& labe photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, size.x, size.y - 13, colors::fg, 4 ); photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, value * size.x, size.y - 13, colors::accent, 4 ); + const auto text_size = photon->render->get_text_size( fonts::smaller, util::ssprintf( "%d", val ).c_str( ) ); + photon->render->draw_text( cur_pos2.x - text_size.x / 2 - 8, cur_pos2.y - 3, fonts::smaller, colors::text, true, util::ssprintf( "%d", val ).c_str( ) ); + cur_pos2 += vec2_t( radius_half, radius_half ); cur_pos2.x += value * ( size.x - radius ); photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius, colors::accent ); photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius - 4, colors::white ); - photon->render->draw_text( cur_pos2.x, cur_pos2.y - 26, fonts::smaller, colors::text, true, util::ssprintf( "%d", val ).c_str( ) ); - cur_menu.cursor.y += size.y + 16; } @@ -346,18 +442,55 @@ void gui::framework::sliderf( float& val, float min, float max, const std::strin photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, size.x, size.y - 13, colors::fg, 4 ); photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, value * size.x, size.y - 13, colors::accent, 4 ); + const auto text_size = photon->render->get_text_size( fonts::smaller, util::ssprintf( "%.1f", val ).c_str( ) ); + photon->render->draw_text( cur_pos2.x - text_size.x / 2 - 8, cur_pos2.y - 3, fonts::smaller, colors::text, true, util::ssprintf( "%.1f", val ).c_str( ) ); + cur_pos2 += vec2_t( radius_half, radius_half ); cur_pos2.x += value * ( size.x - radius ); photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius, colors::accent ); photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius - 4, colors::white ); - photon->render->draw_text( cur_pos2.x, cur_pos2.y - 26, fonts::smaller, colors::text, true, util::ssprintf( "%.1f", val ).c_str( ) ); - cur_menu.cursor.y += size.y + 16; } void gui::framework::colorpicker( color_t& val, const std::string& label ) { + auto cur_pos = cur_menu.pos + cur_menu.cursor; + cur_pos.y -= scroll_offset; + + const auto size = vec2_t( 20, 20 ); + + auto cur_pos2 = align_right( cur_pos, size ); + + bool open = cur_colorpicker.id == label; + + bool hover = ( !cur_menu.block_input || open ) && photon->input->is_cursor_in_area( cur_pos2.x, cur_pos2.y, cur_pos2.x + size.x, cur_pos2.y + size.y ); + bool clicking = hover && photon->input->get_key_press( mouse_left ); + + if ( clicking ) { + if ( open ) + cur_colorpicker = colorpicker_t( ); + else { + cur_colorpicker.id = label; + cur_colorpicker.pos = cur_pos2; + cur_colorpicker.value = val; + val.to_hsv( cur_colorpicker.h, cur_colorpicker.s, cur_colorpicker.v ); + } + + open = !open; + } + + if ( open ) + val = cur_colorpicker.value; + + photon->render->draw_text( cur_pos.x, cur_pos.y, fonts::normal, colors::text, false, util::to_upper( label ).c_str( ) ); + + photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y, size.x, size.y, colors::gray, 8 ); + + photon->render->draw_rounded_rect( cur_pos2.x + 1, cur_pos2.y + 1, size.x - 2, size.y - 2, colors::bg, 8 ); + photon->render->draw_rounded_rect( cur_pos2.x + 1, cur_pos2.y + 1, size.x - 2, size.y - 2, val, 8 ); + + cur_menu.cursor.y += size.y + 16; } void gui::framework::combo( std::size_t& val, const std::vector< std::string >& items, const std::string& label ) { diff --git a/src/core/menu/framework.h b/src/core/menu/framework.h index 784384c..2bd3e16 100644 --- a/src/core/menu/framework.h +++ b/src/core/menu/framework.h @@ -15,10 +15,10 @@ namespace gui { inline color_t red = color_t( 168, 43, 43 ); // theme colors + inline color_t accent = color_t( 66, 128, 244, 255 ); inline color_t bg; inline color_t fg; inline color_t text; - inline color_t accent; inline color_t disabled; } // namespace colors @@ -56,12 +56,16 @@ namespace gui { inline dropdown_t cur_dropdown; struct colorpicker_t { - + std::string id; + vec2_t pos; + color_t value; + float h, s, v; + float a{ -1 }; }; inline colorpicker_t cur_colorpicker; - inline std::string cur_slider; // FIXME: make this somehow be only for current menu but still persist - inline int scroll_offset; // ditto + inline std::string cur_slider; + inline int scroll_offset; // FIXME: make this somehow be only for current menu but still persist void set_theme( bool dark = false ); diff --git a/src/core/menu/gui.cpp b/src/core/menu/gui.cpp index 665459f..6c3d006 100644 --- a/src/core/menu/gui.cpp +++ b/src/core/menu/gui.cpp @@ -82,6 +82,8 @@ SIGNAL_CALLBACK( void, __rescall, update_button_state, const int*, event ) { original( ecx, event ); } +static color_t* hue_tex; + bool gui::initialize( ) { framework::set_theme( false ); @@ -90,11 +92,22 @@ bool gui::initialize( ) { photon->render->create_font( framework::fonts::title, "D-DIN EXP", 24, true, fontflag_antialias ); photon->render->create_font( framework::fonts::bigtitle, "D-DIN EXP", 32, true, fontflag_antialias ); - photon->render->load_texture( "photon_icon", resource::icons::photon, 50, 50, sizeof( resource::icons::photon ) ); - photon->render->load_texture( "photon_list", resource::icons::list, 32, 32, sizeof( resource::icons::list ) ); - photon->render->load_texture( "photon_gear", resource::icons::gear, 32, 32, sizeof( resource::icons::gear ) ); - photon->render->load_texture( "photon_left_arrow", resource::icons::left_arrow, 32, 32, sizeof( resource::icons::left_arrow ) ); - photon->render->load_texture( "photon_arrows", resource::icons::arrows, 32, 32, sizeof( resource::icons::arrows ) ); + photon->render->load_texture_png( "photon_icon", resource::icons::photon, 50, 50, sizeof( resource::icons::photon ) ); + photon->render->load_texture_png( "photon_list", resource::icons::list, 32, 32, sizeof( resource::icons::list ) ); + photon->render->load_texture_png( "photon_gear", resource::icons::gear, 32, 32, sizeof( resource::icons::gear ) ); + photon->render->load_texture_png( "photon_left_arrow", resource::icons::left_arrow, 32, 32, sizeof( resource::icons::left_arrow ) ); + photon->render->load_texture_png( "photon_arrows", resource::icons::arrows, 32, 32, sizeof( resource::icons::arrows ) ); + + // initialize hue gradient texture (this should probably be in framework) + constexpr int tex_height = 180; + + hue_tex = new color_t[ 1 * tex_height ]; + for ( int i = 0; i < tex_height; ++i ) { + float hue = i * ( 1.f / tex_height ); + + hue_tex[ i ] = color_t::from_hsv( hue, 1.f, 1.f ); + } + photon->render->load_texture_raw( "photon_hue_gradient", ( uint8_t* ) hue_tex, 1, tex_height ); photon->signal->get( "lock_cursor" )->add_callback( &lock_cursor_cbk ); photon->signal->get( "paint" )->add_callback( &paint_cbk ); @@ -109,6 +122,8 @@ bool gui::initialize( ) { void gui::uninitialize( ) { dx9::uninitialize( ); + DELETE_PTR( hue_tex ); + photon->render->destruct_font( framework::fonts::bigtitle ); photon->render->destruct_font( framework::fonts::title ); photon->render->destruct_font( framework::fonts::normal ); @@ -161,14 +176,22 @@ void gui::paint( ) { } } if ( framework::tab( tab, { screen_half.x + 100 + 8, screen_half.y - tab_height / 2 }, { tab_height, tab_height }, "photon_gear", true ) ) { + framework::separator( "menu settings" ); + + framework::colorpicker( framework::colors::accent, "accent color" ); + static bool dark_mode = false; if ( framework::toggle( dark_mode, "dark mode" ) ) framework::set_theme( dark_mode ); + framework::separator( "game settings" ); + static bool fast_loads = true; if ( framework::toggle( fast_loads, "fast loads" ) ) convars::set_fast_loads( fast_loads ); + framework::separator( "hud settings" ); + framework::slider( huds::safezone_x, 0, 32, "hud safezone x" ); framework::slider( huds::safezone_y, 0, 32, "hud safezone y" ); } diff --git a/src/core/shared/hud.cpp b/src/core/shared/hud.cpp index 5256404..f9a2388 100644 --- a/src/core/shared/hud.cpp +++ b/src/core/shared/hud.cpp @@ -72,6 +72,31 @@ void c_hud::draw_line( int x, int y, int w, int h, color_t color ) { photon->render->draw_line( x, y, w, h, color ); } +void c_hud::draw_polygon( int n, vertex_t* vertices, color_t color ) { + // FIXME: do some calculation here to figure out bounds + // if ( !cur_hud ) + // return; + + // setup_context( x, y, w, h ); + + // photon->render->draw_polygon( n, vertices, color ); +} +void c_hud::draw_rounded_rect( int x, int y, int w, int h, color_t color, int rounding ) { + if ( !cur_hud ) + return; + + setup_context( x, y, w, h ); + + photon->render->draw_rounded_rect( x, y, w, h, color, rounding ); +} +void c_hud::draw_circle( int x, int y, int radius, color_t color ) { + if ( !cur_hud ) + return; + + setup_context( x, y, radius * 2, radius * 2 ); // XXX: maybe wrong ? too lazy to test rn + + photon->render->draw_circle( x, y, radius, color ); +} void c_hud::draw_text( int x, int y, h_font font, color_t color, bool center, const char* text ) { if ( !cur_hud ) return; @@ -90,3 +115,11 @@ void c_hud::draw_texture( int x, int y, int w, int h, const char* texture, color photon->render->draw_texture( x, y, w, h, texture, color ); } +void c_hud::draw_gradient( int x, int y, int w, int h, color_t color1, color_t color2, bool horizontal ) { + if ( !cur_hud ) + return; + + setup_context( x, y, w, h ); + + photon->render->draw_gradient( x, y, w, h, color1, color2, horizontal ); +} diff --git a/src/core/shared/menu.cpp b/src/core/shared/menu.cpp index a6e35ed..3699264 100644 --- a/src/core/shared/menu.cpp +++ b/src/core/shared/menu.cpp @@ -19,6 +19,7 @@ void c_menu::sliderf( float& val, float min, float max, const char* label ) { return gui::framework::sliderf( val, min, max, label ); } void c_menu::colorpicker( color_t& val, const char* label ) { + return gui::framework::colorpicker( val, label ); } void c_menu::combo( std::size_t& val, const char* items[], std::size_t items_count, const char* label ) { std::vector< std::string > items_vector; diff --git a/src/core/shared/render.cpp b/src/core/shared/render.cpp index 85a0f12..fc1ae3c 100644 --- a/src/core/shared/render.cpp +++ b/src/core/shared/render.cpp @@ -105,7 +105,22 @@ void c_render::draw_texture( int x, int y, int w, int h, const char* texture, co interfaces::surface->draw_textured_rect( x, y, x + w, y + h ); } -void c_render::load_texture( const char* name, const uint8_t* png, int w, int h, size_t size ) { +void c_render::draw_gradient( int x, int y, int w, int h, color_t color1, color_t color2, bool horizontal ) { + interfaces::surface->draw_set_color( color1.r, color1.g, color1.b, color1.a ); + interfaces::surface->draw_filled_rect( x, y, x + w, y + h ); + + interfaces::surface->draw_set_color( color2.r, color2.g, color2.b, color2.a ); + interfaces::surface->draw_filled_rect_fade( x, y, x + w, y + h, 0, 255, horizontal ); +} + +void c_render::load_texture_raw( const char* name, const uint8_t* rgba, int w, int h ) { + int id = interfaces::surface->create_new_texture_id( true ); + interfaces::surface->draw_set_texture_rgba( id, rgba, w, h ); + + texture_ids.insert( std::make_pair( name, id ) ); +} + +void c_render::load_texture_png( const char* name, const uint8_t* png, int w, int h, size_t size ) { std::vector< uint8_t > rgba; auto _w = std::uint32_t( w ); @@ -113,10 +128,7 @@ void c_render::load_texture( const char* name, const uint8_t* png, int w, int h, lodepng::decode( rgba, _w, _h, png, size ); - int id = interfaces::surface->create_new_texture_id( true ); - interfaces::surface->draw_set_texture_rgba( id, rgba.data( ), w, h ); - - texture_ids.insert( std::make_pair( name, id ) ); + load_texture_raw( name, rgba.data( ), w, h ); } bool c_render::create_font( h_font& font, const char* font_name, int size, bool bold, int flags ) { diff --git a/src/sdk/hud.h b/src/sdk/hud.h index 2e728f5..46bcd09 100644 --- a/src/sdk/hud.h +++ b/src/sdk/hud.h @@ -46,6 +46,10 @@ class c_hud { virtual void draw_filled_rect( int x, int y, int w, int h, color_t color ); virtual void draw_outlined_rect( int x, int y, int w, int h, color_t color, int stroke_width = 1 ); virtual void draw_line( int x, int y, int w, int h, color_t color ); + virtual void draw_polygon( int n, vertex_t* vertices, color_t color ); + virtual void draw_rounded_rect( int x, int y, int w, int h, color_t color, int rounding ); + virtual void draw_circle( int x, int y, int radius, color_t color ); virtual void draw_text( int x, int y, h_font font, color_t color, bool center, const char* text ); virtual void draw_texture( int x, int y, int w, int h, const char* texture, color_t color = color_t( 255, 255, 255, 255 ) ); + virtual void draw_gradient( int x, int y, int w, int h, color_t color1, color_t color2, bool horizontal ); }; diff --git a/src/sdk/render.h b/src/sdk/render.h index 57fb8f7..a42a8da 100644 --- a/src/sdk/render.h +++ b/src/sdk/render.h @@ -14,7 +14,9 @@ class c_render { virtual void draw_circle( int x, int y, int radius, color_t color ); virtual void draw_text( int x, int y, h_font font, color_t color, bool center, const char* text ); virtual void draw_texture( int x, int y, int w, int h, const char* texture, color_t color = color_t( 255, 255, 255, 255 ) ); - virtual void load_texture( const char* name, const uint8_t* png, int w, int h, size_t size ); + virtual void draw_gradient( int x, int y, int w, int h, color_t color1, color_t color2, bool horizontal ); + virtual void load_texture_raw( const char* name, const uint8_t* rgba, int w, int h ); + virtual void load_texture_png( const char* name, const uint8_t* png, int w, int h, size_t size ); virtual bool create_font( h_font& font, const char* font_name, int size, bool bold, int flags ); virtual void destruct_font( h_font font ); virtual vec2_t get_text_size( h_font font, const char* text ); diff --git a/src/sdk/source-sdk/color.h b/src/sdk/source-sdk/color.h index 96975bf..1db3b01 100644 --- a/src/sdk/source-sdk/color.h +++ b/src/sdk/source-sdk/color.h @@ -1,5 +1,6 @@ #pragma once +#include #include struct color_t { @@ -30,4 +31,67 @@ struct color_t { color_t( uint32_t rgba ) { this->rgba = rgba; } + + void to_hsv( float& h, float& s, float& v ) { + float r = this->r / 255.f; + float g = this->g / 255.f; + float b = this->b / 255.f; + + float cmax = std::max( r, std::max( g, b ) ); + float cmin = std::min( r, std::min( g, b ) ); + float diff = cmax - cmin; + + if ( cmax == cmin ) + h = 0; + else if ( cmax == r ) + h = fmod( ( 60 * ( ( g - b ) / diff ) + 360 ), 360 ) / 360.f; + else if ( cmax == g ) + h = fmod( ( 60 * ( ( b - r ) / diff ) + 120 ), 360 ) / 360.f; + else if ( cmax == b ) + h = fmod( ( 60 * ( ( r - g ) / diff ) + 240 ), 360 ) / 360.f; + + if ( cmax == 0 ) + s = 0; + else + s = diff / cmax; + + v = cmax; + } + + static color_t from_hsv( float h, float s, float v ) { + float r, g, b; + + int i = floor( h * 6 ); + float f = h * 6 - i; + float p = v * ( 1 - s ); + float q = v * ( 1 - f * s ); + float t = v * ( 1 - ( 1 - f ) * s ); + + switch ( i % 6 ) { + case 0: + r = v, g = t, b = p; + break; + case 1: + r = q, g = v, b = p; + break; + case 2: + r = p, g = v, b = t; + break; + case 3: + r = p, g = q, b = v; + break; + case 4: + r = t, g = p, b = v; + break; + case 5: + r = v, g = p, b = q; + break; + } + + return color_t{ + ( uint8_t ) ( r * 255 ), + ( uint8_t ) ( g * 255 ), + ( uint8_t ) ( b * 255 ) + }; + } }; diff --git a/src/source-sdk/interfaces/surface.h b/src/source-sdk/interfaces/surface.h index 14f9a83..839c15c 100644 --- a/src/source-sdk/interfaces/surface.h +++ b/src/source-sdk/interfaces/surface.h @@ -62,6 +62,9 @@ class i_surface { void draw_textured_polygon( int n, vertex_t* vertices, bool clip_vertices = true ) { return util::call_virtual< 104, void >( this, n, vertices, clip_vertices ); } + void draw_filled_rect_fade( int x0, int y0, int x1, int y1, unsigned int alpha0, unsigned int alpha1, bool horizontal ) { + return util::call_virtual< 121, void >( this, x0, y0, x1, y1, alpha0, alpha1, horizontal ); + } void get_clip_rect( int& x0, int& y0, int& x1, int& y1 ) { return util::call_virtual< 144, void >( this, &x0, &y0, &x1, &y1 ); } @@ -74,11 +77,11 @@ class i_surface { return ( *reinterpret_cast< fn_t** >( this ) )[ 160 ]( this, font, x, y, r, g, b, a, text ); } void start_drawing( ) { - auto paint_traverse_ex = util::get_virtual< 117 >( this ); + static auto paint_traverse_ex = util::get_virtual< 117 >( this ); return util::read< void( __rescall* )( void* ) >( paint_traverse_ex + OS( 0x7f, 0x53d ) )( this ); } void finish_drawing( ) { - auto paint_traverse_ex = util::get_virtual< 117 >( this ); + static auto paint_traverse_ex = util::get_virtual< 117 >( this ); return util::read< void( __rescall* )( ) >( paint_traverse_ex + OS( 0x25b, 0x163 ) )( ); }