From 28b41b4b9b6fe1ea719cee7b5d76aba1ded1abd2 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 27 Aug 2026 09:59:55 -0400 Subject: [PATCH] con color --- docs/CHANGELOG.md | 3 +++ game_patch/hud/hud_colors.cpp | 6 +++--- game_patch/misc/alpine_settings.cpp | 9 +++++++++ game_patch/misc/alpine_settings.h | 2 ++ game_patch/os/commands.cpp | 12 ++++++++++++ game_patch/os/console.cpp | 15 ++++++++++----- game_patch/os/console.h | 3 +++ game_patch/rf/os/console.h | 1 + 8 files changed, 43 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 7f5d1fc43..426824b7e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,6 +9,9 @@ Version 1.5.0 (TBD): Not yet released [@GooberRF](https://github.com/GooberRF) - Restore cut first person weapon aim sway, toggleable with `cl_weaponsway` +[@nickalreadyinuse](https://github.com/nickalreadyinuse) +- Add `ui_con_color` console command to set the console background color + ### Bug fixes Version 1.4.0 (Lupin): Released Aug-25-2026 diff --git a/game_patch/hud/hud_colors.cpp b/game_patch/hud/hud_colors.cpp index b7c059116..23e673ee7 100644 --- a/game_patch/hud/hud_colors.cpp +++ b/game_patch/hud/hud_colors.cpp @@ -250,12 +250,12 @@ static void warn_outlines_if_not_d3d11() } } -// helper for always-set (non-optional) color commands -static void handle_required_color_command( +// helper for always-set (non-optional) color commands (declared in console.h) +void handle_required_color_command( const std::optional& input, const std::string& label, uint32_t& target, - std::optional default_value = std::nullopt) + std::optional default_value) { if (!input) { auto [r, g, b, a] = extract_color_components(target); diff --git a/game_patch/misc/alpine_settings.cpp b/game_patch/misc/alpine_settings.cpp index 87ef43d2a..ecf244751 100644 --- a/game_patch/misc/alpine_settings.cpp +++ b/game_patch/misc/alpine_settings.cpp @@ -406,6 +406,14 @@ bool alpine_player_settings_load(rf::Player* player) apply_console_history_setting(); processed_keys.insert("SaveConsoleHistory"); } + if (settings.count("ConsoleColor")) { + auto c = parse_hex_color_string(settings["ConsoleColor"]); + if (c) { + g_alpine_game_config.console_color = *c; + apply_console_color_setting(); + } + processed_keys.insert("ConsoleColor"); + } if (settings.count("AlpineBranding")) { g_alpine_game_config.af_branding = std::stoi(settings["AlpineBranding"]); processed_keys.insert("AlpineBranding"); @@ -1417,6 +1425,7 @@ void alpine_player_settings_save(rf::Player* player) file << "ShowSpeed=" << g_alpine_game_config.speed_display << "\n"; file << "FPSCounterAverageMs=" << g_alpine_game_config.fps_counter_average_ms << "\n"; file << "SaveConsoleHistory=" << g_alpine_game_config.save_console_history << "\n"; + file << "ConsoleColor=" << format_hex_color_string(g_alpine_game_config.console_color) << "\n"; file << "AlpineBranding=" << g_alpine_game_config.af_branding << "\n"; file << "SeasonalEffect=" << g_alpine_game_config.seasonal_effect << "\n"; file << "RealArmorValues=" << g_alpine_game_config.real_armor_values << "\n"; diff --git a/game_patch/misc/alpine_settings.h b/game_patch/misc/alpine_settings.h index f1ce64878..7337d3545 100644 --- a/game_patch/misc/alpine_settings.h +++ b/game_patch/misc/alpine_settings.h @@ -167,6 +167,7 @@ struct AlpineGameSettings bool spectate_show_camera_meshes = true; // draw camera meshes in free look bool spectate_povcomp = true; // delay other players to match what the spectated player saw bool save_console_history = false; // checked before config loaded, must be false here + uint32_t console_color = 0x274E69C0; // console background color (RRGGBBAA) bool screen_shake_force_off = false; bool display_target_player_names = true; bool verbose_time_left_display = true; @@ -457,6 +458,7 @@ void update_scanner_sensitivity(); void recalc_mesh_static_lighting(); void apply_show_enemy_bullets(); void apply_console_history_setting(); +void apply_console_color_setting(); void build_time_left_string_format(); void gr_update_texture_filtering(); void set_play_sound_events_volume_scale(); diff --git a/game_patch/os/commands.cpp b/game_patch/os/commands.cpp index 540762d75..3df62a654 100644 --- a/game_patch/os/commands.cpp +++ b/game_patch/os/commands.cpp @@ -50,6 +50,17 @@ ConsoleCommand2 console_history_cmd{ "Toggles whether console history persists between game launches", }; +ConsoleCommand2 console_color_cmd{ + "ui_con_color", + [](std::optional color_opt) { + handle_required_color_command(color_opt, "Console background color", g_alpine_game_config.console_color, + 0x274E69C0); + apply_console_color_setting(); + }, + "Set the console background color", + "ui_con_color ", +}; + ConsoleCommand2 vli_cmd{ "vli", []() { @@ -615,6 +626,7 @@ void console_commands_init() pcollide_cmd.register_cmd(); dot_cmd.register_cmd(); console_history_cmd.register_cmd(); + console_color_cmd.register_cmd(); vli_cmd.register_cmd(); monitor_resolution_scale_cmd.register_cmd(); fast_anim_cmd.register_cmd(); diff --git a/game_patch/os/console.cpp b/game_patch/os/console.cpp index 0f3cf4cc8..ad5033fd1 100644 --- a/game_patch/os/console.cpp +++ b/game_patch/os/console.cpp @@ -332,6 +332,15 @@ void apply_console_history_setting() { rf::console::console_keep_history = g_alpine_game_config.save_console_history; } +void apply_console_color_setting() { + auto [r, g, b, a] = extract_color_components(g_alpine_game_config.console_color); + write_mem(0x005098D1, a); + write_mem(0x005098D6, b); + write_mem(0x005098D8, g); + write_mem(0x005098DA, r); + rf::console::background_color.set(r, g, b, a); +} + extern void console_commands_apply_patches(); extern void console_auto_complete_apply_patches(); extern void console_commands_init(); @@ -342,11 +351,7 @@ void console_apply_patches() write_mem_ptr(0x004B2534, "-- " PRODUCT_NAME " Initializing --\n"); // Console background color - constexpr rf::Color console_color{0x27, 0x4E, 0x69, 0xC0}; - write_mem(0x005098D1, console_color.alpha); - write_mem(0x005098D6, console_color.blue); - write_mem(0x005098D8, console_color.green); - write_mem(0x005098DA, console_color.red); + apply_console_color_setting(); // Support unsigned hexadecimal arguments. AsmWriter{0x0050B0B0}.call(std::strtoul); diff --git a/game_patch/os/console.h b/game_patch/os/console.h index 9605a7a10..ed8e86089 100644 --- a/game_patch/os/console.h +++ b/game_patch/os/console.h @@ -17,6 +17,9 @@ void console_register_command(rf::console::Command* cmd); rf::Player* find_best_matching_player(const char* name); void console_start_server_log(); void console_run_script(const char* filename); +// Shared handler for console commands setting an always-set color (defined in hud/hud_colors.cpp) +void handle_required_color_command(const std::optional& input, const std::string& label, + uint32_t& target, std::optional default_value = std::nullopt); class DcInvalidArgTypeError : public std::exception {}; diff --git a/game_patch/rf/os/console.h b/game_patch/rf/os/console.h index 2677862ec..1970509a1 100644 --- a/game_patch/rf/os/console.h +++ b/game_patch/rf/os/console.h @@ -85,4 +85,5 @@ namespace rf::console static auto& history_max_index = addr_as_ref(0x005A4030); static auto& console_is_visible = addr_as_ref(0x0050B520); static auto& console_keep_history = addr_as_ref(0x005A402C); + static auto& background_color = addr_as_ref(0x017751DC); }