#include "vars.h" #include "../util.h" #include VAR_LIST* varl; void vars_check_global_list() { if( !varl ) varl = vars_init(); } VAR_LIST* vars_init() { VAR_LIST* ret = new VAR_LIST; return ret; } inline F32 var_clamp( CVAR* var, F32 value ) { if( !( var->flags & CVAR_FLAG_MINMAX ) ) return value; return m_clamp( value, var->min_v.fl_v, var->max_v.fl_v ); } inline I32 var_clamp( CVAR* var, I32 value ) { if( !( var->flags & CVAR_FLAG_MINMAX ) ) return value; return m_clamp( value, var->min_v.i_v, var->max_v.i_v ); } CVAR* var_new( const char* name, STR desc, F32 v ) { vars_check_global_list(); CVAR* ret = new CVAR{}; ret->type = CVAR_TYPE_FLOAT; ret->default_v.fl_v = v; ret->desc = desc; ret->name = name; ret->fl_v = v; varl->vars.push( ret ); return ret; } CVAR* var_new( const char* name, STR desc, F32 v, F32 min_v, F32 max_v ) { if( min_v > max_v ) { dlog( "var_new() : invalid bounds for %s\n", name ); return 0; } vars_check_global_list(); CVAR* ret = new CVAR{}; ret->flags = CVAR_FLAG_MINMAX; ret->type = CVAR_TYPE_FLOAT; ret->min_v.fl_v = min_v; ret->max_v.fl_v = max_v; ret->desc = desc; ret->name = name; ret->fl_v = var_clamp( ret, v ); ret->default_v.fl_v = ret->fl_v; varl->vars.push( ret ); return ret; } CVAR* var_new( const char* name, STR desc, I32 v ) { vars_check_global_list(); CVAR* ret = new CVAR{}; ret->type = CVAR_TYPE_INT; ret->default_v.i_v = v; ret->desc = desc; ret->name = name; ret->i_v = v; varl->vars.push( ret ); return ret; } CVAR* var_new( const char* name, STR desc, I32 v, I32 min_v, I32 max_v ) { if( min_v > max_v ) { dlog( "var_new() : invalid bounds for %s\n", name ); return 0; } vars_check_global_list(); CVAR* ret = new CVAR{}; ret->flags = CVAR_FLAG_MINMAX; ret->type = CVAR_TYPE_INT; ret->min_v.i_v = min_v; ret->max_v.i_v = max_v; ret->desc = desc; ret->name = name; ret->i_v = var_clamp( ret, v ); ret->default_v.i_v = ret->i_v; varl->vars.push( ret ); return ret; } CVAR* var_new( const char* name, STR desc, CLR c ) { vars_check_global_list(); CVAR* ret = new CVAR{}; ret->type = CVAR_TYPE_COLOR; ret->default_v.clr_v = c; ret->desc = desc; ret->name = name; ret->clr_v = c; varl->vars.push( ret ); return ret; } CVAR* var_new( const char* name, STR desc, CVAR_FUNC func ) { vars_check_global_list(); CVAR* ret = new CVAR{}; ret->type = CVAR_TYPE_FN; ret->name = name; ret->fn_v = func; ret->desc = desc; varl->vars.push( ret ); return ret; } CVAR* var_new( const char* name, STR desc, const char* v ) { vars_check_global_list(); CVAR* ret = new CVAR{}; if( !v || strlen( v ) >= sizeof( ret->str_v ) ) { dlog( "var_new() : invalid initial string for %s\n", name ); delete ret; return 0; } strcpy( ret->default_v.str_v, v ); ret->type = CVAR_TYPE_STRING; strcpy( ret->str_v, v ); ret->desc = desc; ret->name = name; varl->vars.push( ret ); return ret; } CVAR* var_find( const char* name ) { if( !varl ) { dlog( "var_find() : error: varl null\n" ); return 0; } U32 len = (U32)strlen( name ); for( U32 i = 0; i < varl->vars.size; ++i ) { CVAR* cvar = varl->vars[i]; U32 len2 = (U32)strlen( cvar->name ); if( strncmp( cvar->name, name, min( len, len2 ) ) ) continue; return cvar; } return 0; } I32 var_call( CVAR *cmdvar, LIST cmdline ) { if( cmdvar->type != CVAR_TYPE_FN ) { dlog( "var_call() : error: not a function\n" ); return -1; } return cmdvar->fn_v( cmdvar, cmdline ); } F32 var_getf( CVAR *var ) { switch( var->type ) { case CVAR_TYPE_FLOAT: return var->fl_v; case CVAR_TYPE_INT: return (F32)var->i_v; default: return 0.f; } } I32 var_geti( CVAR *var ) { switch( var->type ) { case CVAR_TYPE_INT: return var->i_v; case CVAR_TYPE_FLOAT: return (I32)var->fl_v; default: return 0; } } CLR var_getclr( CVAR *var ) { switch( var->type ) { case CVAR_TYPE_COLOR: return var->clr_v; case CVAR_TYPE_FLOAT: return (CLR){ var->fl_v, var->fl_v, var->fl_v, 1.f }; default: return {}; } } STR var_gets( const CVAR *var ) { if( !var ) return {}; switch( var->type ) { case CVAR_TYPE_STRING: return STR( "%s", var->str_v ); case CVAR_TYPE_COLOR: return STR( "%#.9g %#.9g %#.9g %#.9g", (F64)var->clr_v.r, (F64)var->clr_v.g, (F64)var->clr_v.b, (F64)var->clr_v.a ); case CVAR_TYPE_FLOAT: return STR( "%#.9g", var->fl_v ); case CVAR_TYPE_INT: return STR( "%d", var->i_v ); case CVAR_TYPE_FN: return STR( "", var->name.data ); default: return {}; } } void var_set( CVAR* var, F32 v ) { switch( var->type ) { case CVAR_TYPE_FLOAT: var->fl_v = var_clamp( var, v ); break; case CVAR_TYPE_INT: var->i_v = var_clamp( var, (I32)v ); break; case CVAR_TYPE_COLOR: var->clr_v = (CLR){ v, v, v, 1.f }; break; case CVAR_TYPE_STRING: strcpy( var->str_v, to_str( v ) ); break; default: break; } } void var_set( CVAR* var, I32 v ) { switch( var->type ) { case CVAR_TYPE_FLOAT: var->fl_v = var_clamp( var, (F32)v ); break; case CVAR_TYPE_INT: var->i_v = var_clamp( var, v ); break; case CVAR_TYPE_COLOR: var->clr_v = (CLR){ ((F32)v / 255), ((F32)v / 255), ((F32)v / 255), 1.f }; break; case CVAR_TYPE_STRING: strcpy( var->str_v, to_str( v ) ); break; default: break; } } void var_set( CVAR* var, CLR v ) { switch( var->type ) { case CVAR_TYPE_COLOR: var->clr_v = v; break; case CVAR_TYPE_STRING: strcpy( var->str_v, to_str( v ) ); break; default: dlog( "attempted to set color to %s, but it's not a color value\n", var->name.data ); break; } } void var_set( CVAR* var, STR v ) { if( var->type != CVAR_TYPE_STRING ) { dlog( "attempted to set string to %s, " "but it is not a string value\n", var->name.data ); return; } if( v.size >= sizeof( var->str_v ) ) { dlog( "attempted to set string to %s, " "but it's too long (%u/64 bytes)\n", var->name.data, v.size ); return; } memcpy( var->str_v, v.data, v.size + 1 ); }