/* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #pragma once /* cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly in C code. it is sufficient to initialize a cvar_t with just the first two fields, or you can add a ,true flag for variables that you want saved to the configuration file when the game is quit: cvar_t r_draworder = {"r_draworder","1"}; cvar_t scr_screensize = {"screensize","1",true}; Cvars must be registered before use, or they will have a 0 value instead of the float interpretation of the string. Generally, all cvar_t declarations should be registered in the apropriate init function before any console commands are executed: host_framerate.inscribe(); C code usually just references a cvar in place: if ( r_draworder.value ) It could optionally ask for the value to be looked up for a string name: if (Cvar_VariableValue ("r_draworder")) Interpreted prog code can access cvars with the cvar(name) or cvar_set (name, value) internal functions: teamplay = cvar("teamplay"); cvar_set ("registered", "1"); The user can access cvars from the console in two ways: r_draworder prints the current value r_draworder 0 sets the current value to 0 Cvars are restricted from having the same names as commands to keep this interface from being ambiguous. */ #include #include #include #include "convar.hpp" void Cvar_Init(); struct cvar_flags { bool archive{false}; bool notify{false}; bool server_info{false}; bool user_info{false}; bool changed{false}; bool rom{false}; bool locked{false}; bool registered{false}; bool callback{false}; [[nodiscard]] bool matches_mask(const cvar_flags &rhs) const { return (!rhs.archive || this->archive) && (!rhs.notify || this->notify) && (!rhs.server_info || this->server_info) && (!rhs.user_info || this->user_info) && (!rhs.changed || this->changed) && (!rhs.rom || this->rom) && (!rhs.locked || this->locked) && (!rhs.registered || this->registered) && (!rhs.callback || this->callback); } }; struct convar; typedef void (*cvarcallback_t)(convar *); using convar_view = std::ranges::elements_view >, 1>; struct convar { std::string name{}; const char *string{nullptr}; cvar_flags flags{}; float value{}; const char *default_string{nullptr}; //johnfitz -- remember defaults for reset function cvarcallback_t callback{nullptr}; convar(std::string_view name, const char *str); convar(std::string_view name, const char *str, cvar_flags flags); void inscribe(); void set_callback(cvarcallback_t func); void set(const std::string &new_value); void set_value(float new_value); static std::optional find_var(const std::string_view &desired); static std::optional find_var_after(const std::optional &prev_name, std::optional with_flags); static void reset(const std::string &name); static void set(const std::string &name, const std::string &new_value); static void set_value(const std::string &name, float new_value); static std::optional complete_variable(const std::string_view &partial); static std::optional variable_value(const std::string_view &name); static std::optional variable_string(const std::string_view &name); static void lock_var(const std::string_view &name); static void unlock_var(const std::string_view &name); static void unlock_all(); static void set_rom(const std::string_view &name, std::string value); static void set_value_rom(const std::string_view &name, float value); static convar_view get_variables(); }; bool Cvar_Command(void); void Cvar_WriteVariables(FILE *f);