2020-11-06 14:40:59 +00:00
// Hyperbolic Rogue -- configuration
// Copyright (C) 2017-2018 Zeno Rogue, see 'hyper.cpp' for details
/** \file config.cpp
* \ brief Configuration - - initial settings , saving / loading ini files , menus , etc .
*/
# include "hyper.h"
namespace hr {
# if HDR
enum eCentering { face , edge , vertex } ;
# endif
EX eCentering centering ;
2021-02-01 14:22:47 +00:00
EX function < bool ( ) > auto_restrict ;
2021-02-01 11:50:02 +00:00
2024-05-26 18:22:29 +00:00
EX void add_to_changed ( struct parameter * f ) ;
2021-02-01 14:10:03 +00:00
2021-02-06 12:15:24 +00:00
EX bool return_false ( ) { return false ; }
2024-05-27 13:21:31 +00:00
EX bool use_bool_dialog ;
2024-05-26 18:22:29 +00:00
EX string param_esc ( string s ) ;
2024-05-28 13:07:29 +00:00
EX void non_editable_pre ( ) { if ( game_active ) stop_game ( ) ; } ;
EX void non_editable_post ( ) { if ( ! delayed_start ) start_game ( ) ; } ;
2024-05-26 18:22:29 +00:00
2020-11-06 14:40:59 +00:00
# if HDR
2024-05-26 18:22:29 +00:00
2024-05-27 00:18:22 +00:00
struct param_exception : hr_exception {
struct parameter * which ;
param_exception ( ) : hr_exception ( " param_exception " ) , which ( nullptr ) { }
param_exception ( const std : : string & s , parameter * p ) : hr_exception ( s ) , which ( p ) { }
} ;
2024-05-26 18:22:29 +00:00
struct parameter_names {
2020-11-06 14:40:59 +00:00
string name ;
2024-05-26 18:22:29 +00:00
string legacy_config_name ;
parameter_names ( const string & s ) { name = param_esc ( s ) ; legacy_config_name = s ; }
parameter_names ( const char * s ) { name = param_esc ( s ) ; legacy_config_name = s ; }
parameter_names ( const string & p , const string & s ) { name = p ; legacy_config_name = s ; }
2020-11-06 14:40:59 +00:00
} ;
2024-05-26 18:22:29 +00:00
struct parameter : public std : : enable_shared_from_this < parameter > {
2021-02-01 14:22:47 +00:00
function < bool ( ) > restrict ;
2024-05-26 18:22:29 +00:00
string name ;
string legacy_config_name ;
2021-01-31 18:55:33 +00:00
string menu_item_name ;
2023-12-03 13:10:03 +00:00
bool menu_item_name_modified ;
2021-01-31 18:55:33 +00:00
string help_text ;
2024-05-28 13:07:29 +00:00
reaction_t pre_reaction , reaction ;
2021-01-31 18:55:33 +00:00
char default_key ;
2021-02-06 12:15:24 +00:00
bool is_editable ;
2023-10-29 10:00:19 +00:00
bool needs_confirm ;
2021-02-01 14:22:47 +00:00
virtual bool available ( ) { if ( restrict ) return restrict ( ) ; return true ; }
2021-02-01 00:35:34 +00:00
virtual bool affects ( void * v ) { return false ; }
2021-01-31 18:55:33 +00:00
void show_edit_option ( ) { show_edit_option ( default_key ) ; }
2022-10-21 09:29:55 +00:00
virtual void show_edit_option ( int key ) {
2024-05-27 09:32:12 +00:00
println ( hlog , " warning: no edit option defined for " , name ) ;
}
2021-02-01 00:35:34 +00:00
virtual string search_key ( ) {
2024-05-26 18:22:29 +00:00
return name + " | " + legacy_config_name + " | " + menu_item_name + " | " + help_text ;
}
explicit parameter ( ) { restrict = auto_restrict ; is_editable = false ; needs_confirm = false ; }
void be_non_editable ( ) {
2024-05-28 13:07:29 +00:00
pre_reaction = non_editable_pre ;
reaction = non_editable_post ;
2021-02-01 00:35:34 +00:00
}
2023-08-08 23:01:32 +00:00
virtual void check_change ( ) { }
2021-02-01 16:06:26 +00:00
reaction_t sets ;
2024-05-26 18:22:29 +00:00
parameter * set_sets ( const reaction_t & s ) { sets = s ; return this ; }
parameter * set_extra ( const reaction_t & r ) ;
parameter * set_reaction ( const reaction_t & r ) ;
virtual ~ parameter ( ) = default ;
2023-08-08 23:01:32 +00:00
virtual bool load_from_animation ( const string & s ) {
2024-05-26 18:22:29 +00:00
load ( s ) ; return false ;
2023-08-08 23:01:32 +00:00
}
virtual void load_as_animation ( const string & s ) {
2024-05-26 18:22:29 +00:00
load ( s ) ;
2023-08-08 23:01:32 +00:00
}
virtual bool anim_unchanged ( ) { return true ; }
virtual void anim_restore ( ) { }
2024-05-27 00:18:22 +00:00
virtual cld get_cld ( ) { throw param_exception ( " parameter has no complex value " , this ) ; }
virtual void set_cld_raw ( cld x ) { throw param_exception ( " parameter has no complex value " , this ) ; }
2023-08-15 08:54:17 +00:00
virtual void set_cld ( cld value ) {
auto bak = get_cld ( ) ;
set_cld_raw ( value ) ;
if ( value ! = bak & & reaction ) reaction ( ) ;
}
2024-05-26 18:22:29 +00:00
virtual string save ( ) = 0 ;
virtual void load ( const string & s ) {
2024-05-27 00:18:22 +00:00
throw param_exception ( " parameter cannot be loaded " , this ) ;
2024-05-26 18:22:29 +00:00
}
virtual bool dosave ( ) = 0 ;
virtual void reset ( ) = 0 ;
virtual void swap_with ( parameter * ) = 0 ;
2024-05-27 00:18:22 +00:00
virtual shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) { throw param_exception ( " not cloneable " , this ) ; }
2024-05-26 18:22:29 +00:00
void setup ( const parameter_names & s ) ;
} ;
struct local_parameter_set {
string label ;
local_parameter_set * extends ;
vector < pair < shared_ptr < parameter > , shared_ptr < parameter > > > swaps ;
void pswitch ( ) ;
local_parameter_set ( string l , local_parameter_set * ext = nullptr ) : label ( l ) , extends ( ext ) { }
parameter_names mod ( parameter * t ) ;
2021-02-01 00:35:34 +00:00
} ;
# endif
2024-05-26 18:22:29 +00:00
parameter * parameter : : set_extra ( const reaction_t & r ) {
2023-08-09 12:01:24 +00:00
auto s = sets ; set_sets ( [ s , r ] { if ( s ) s ( ) ; dialog : : get_di ( ) . extra_options = r ; } ) ; return this ;
2021-02-01 16:06:26 +00:00
}
2024-05-26 18:22:29 +00:00
parameter * parameter : : set_reaction ( const reaction_t & r ) {
2021-02-04 13:59:31 +00:00
reaction = r ; return this ;
2021-02-01 16:06:26 +00:00
}
2024-05-26 18:22:29 +00:00
# if HDR
using paramlist = map < string , std : : shared_ptr < parameter > > ;
# endif
EX paramlist params ;
2021-02-01 00:35:34 +00:00
2024-05-26 18:22:29 +00:00
EX void show_edit_option_enum ( char * value , const string & name , const vector < pair < string , string > > & options , char key , parameter * s ) ;
2021-02-01 00:35:34 +00:00
# if HDR
2024-05-26 18:22:29 +00:00
struct list_parameter : parameter {
2021-02-01 00:35:34 +00:00
virtual int get_value ( ) = 0 ;
virtual void set_value ( int i ) = 0 ;
vector < pair < string , string > > options ;
2024-05-26 18:22:29 +00:00
list_parameter * editable ( const vector < pair < string , string > > & o , string menu_item_name , char key ) {
2021-02-06 12:15:24 +00:00
is_editable = true ;
2021-02-01 00:35:34 +00:00
options = o ;
this - > menu_item_name = menu_item_name ;
2023-12-03 13:10:03 +00:00
menu_item_name_modified = true ;
2021-02-01 00:35:34 +00:00
default_key = key ;
return this ;
}
2022-10-21 09:29:55 +00:00
void show_edit_option ( int key ) override ;
2021-02-01 00:35:34 +00:00
} ;
2023-08-13 11:34:14 +00:00
namespace anims {
2024-05-26 18:22:29 +00:00
extern void animate_parameter ( parameter * , string ) ;
2023-08-13 11:34:14 +00:00
}
2024-05-26 18:22:29 +00:00
template < class T > struct enum_parameter : list_parameter {
2023-08-13 11:34:14 +00:00
T * value , last_value , dft , anim_value ;
2021-02-01 00:35:34 +00:00
int get_value ( ) override { return ( int ) * value ; }
2023-10-26 10:26:03 +00:00
hr : : function < void ( T ) > set_value_to ;
void set_value ( int i ) override { set_value_to ( ( T ) i ) ; }
2021-07-11 22:03:08 +00:00
bool affects ( void * v ) override { return v = = value ; }
2023-08-13 11:34:14 +00:00
virtual void load_from_raw ( const string & s ) {
int N = isize ( options ) ;
for ( int i = 0 ; i < N ; i + + ) if ( appears ( options [ i ] . first , s ) ) {
2023-10-26 10:26:03 +00:00
set_value_to ( ( T ) i ) ;
2023-08-13 11:34:14 +00:00
return ;
}
2021-04-30 17:43:14 +00:00
* value = ( T ) parseint ( s ) ;
}
2023-08-21 17:23:48 +00:00
void check_change ( ) override {
2023-08-08 23:01:32 +00:00
if ( * value ! = last_value ) {
last_value = * value ;
add_to_changed ( this ) ;
}
}
2024-05-26 18:22:29 +00:00
void load ( const string & s ) override {
2023-08-13 11:34:14 +00:00
auto bak = * value ;
load_from_raw ( s ) ;
2024-05-28 13:07:29 +00:00
if ( * value ! = bak & & pre_reaction ) { swap ( * value , bak ) ; pre_reaction ( ) ; swap ( * value , bak ) ; }
2023-08-13 11:34:14 +00:00
if ( * value ! = bak & & reaction ) reaction ( ) ;
}
bool load_from_animation ( const string & s ) override {
if ( anim_value ! = * value ) return false ;
2024-05-26 18:22:29 +00:00
load ( s ) ;
2023-08-13 11:34:14 +00:00
anim_value = * value ;
return true ;
}
void load_as_animation ( const string & s ) override {
2024-05-26 18:22:29 +00:00
load ( s ) ;
2023-08-13 11:34:14 +00:00
anim_value = * value ;
2024-05-26 18:22:29 +00:00
anims : : animate_parameter ( this , s ) ;
2023-08-13 11:34:14 +00:00
}
2023-10-26 10:26:03 +00:00
2024-05-26 18:22:29 +00:00
enum_parameter < T > * editable ( const vector < pair < string , string > > & o , string menu_item_name , char key ) {
list_parameter : : editable ( o , menu_item_name , key ) ;
2023-10-26 10:26:03 +00:00
return this ;
}
2024-05-26 18:22:29 +00:00
enum_parameter < T > * set_need_confirm ( ) {
2023-10-29 10:00:19 +00:00
needs_confirm = true ;
return this ;
}
2024-02-22 16:29:58 +00:00
virtual cld get_cld ( ) override { return get_value ( ) ; }
2023-08-08 23:01:32 +00:00
2024-05-26 18:22:29 +00:00
bool dosave ( ) override { return * value ! = dft ; }
void reset ( ) override { * value = dft ; }
string save ( ) override { return its ( int ( * value ) ) ; }
shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) override ;
void swap_with ( parameter * s ) override { swap ( * value , * ( ( ( enum_parameter < T > * ) s ) - > value ) ) ; }
2023-08-10 12:38:59 +00:00
} ;
2024-05-26 18:22:29 +00:00
template < class T > struct val_parameter ;
template < class T > struct val_parameter : public parameter {
2023-08-08 23:01:32 +00:00
T * value , last_value , anim_value , dft ;
2024-05-26 18:22:29 +00:00
bool dosave ( ) override { return * value ! = dft ; }
void reset ( ) override { * value = dft ; }
bool affects ( void * v ) override { return v = = value ; }
2023-08-21 17:23:48 +00:00
void check_change ( ) override {
2023-08-08 23:01:32 +00:00
if ( * value ! = last_value ) {
last_value = * value ;
add_to_changed ( this ) ;
}
}
2023-08-21 17:23:48 +00:00
bool anim_unchanged ( ) override { return * value = = anim_value ; }
void anim_restore ( ) override { * value = anim_value ; if ( reaction ) reaction ( ) ; }
2023-08-08 23:11:44 +00:00
2024-05-27 00:18:22 +00:00
virtual void load_from_raw ( const string & s ) { throw param_exception ( " load_from_raw not defined " , this ) ; }
2023-08-08 23:11:44 +00:00
2024-05-26 18:22:29 +00:00
void load ( const string & s ) override {
2023-08-08 23:11:44 +00:00
auto bak = * value ;
load_from_raw ( s ) ;
2024-05-28 13:07:29 +00:00
if ( * value ! = bak & & pre_reaction ) { swap ( * value , bak ) ; pre_reaction ( ) ; swap ( * value , bak ) ; }
2023-08-08 23:11:44 +00:00
if ( * value ! = bak & & reaction ) reaction ( ) ;
}
2023-08-08 23:01:32 +00:00
bool load_from_animation ( const string & s ) override {
if ( anim_value ! = * value ) return false ;
2024-05-26 18:22:29 +00:00
load ( s ) ;
2023-08-08 23:01:32 +00:00
anim_value = * value ;
return true ;
}
void load_as_animation ( const string & s ) override {
2024-05-26 18:22:29 +00:00
load ( s ) ;
2023-08-08 23:01:32 +00:00
anim_value = * value ;
2024-05-26 18:22:29 +00:00
anims : : animate_parameter ( this , s ) ;
2023-08-08 23:01:32 +00:00
}
2024-05-26 18:22:29 +00:00
void swap_with ( parameter * s ) override { swap ( * value , * ( ( ( val_parameter < T > * ) s ) - > value ) ) ; }
2021-02-01 00:35:34 +00:00
} ;
2024-05-26 18:22:29 +00:00
struct float_parameter : public val_parameter < ld > {
2021-02-01 00:35:34 +00:00
ld min_value , max_value , step ;
2021-02-01 11:50:02 +00:00
string unit ;
2024-05-26 18:22:29 +00:00
float_parameter * editable ( ld min_value , ld max_value , ld step , string menu_item_name , string help_text , char key ) {
2021-02-06 12:15:24 +00:00
is_editable = true ;
2021-01-31 18:55:33 +00:00
this - > min_value = min_value ;
this - > max_value = max_value ;
this - > menu_item_name = menu_item_name ;
2023-12-03 13:10:03 +00:00
menu_item_name_modified = true ;
2021-01-31 18:55:33 +00:00
this - > help_text = help_text ;
this - > step = step ;
default_key = key ;
return this ;
}
2024-05-26 18:22:29 +00:00
function < void ( float_parameter * ) > modify_me ;
float_parameter * modif ( const function < void ( float_parameter * ) > & r ) { modify_me = r ; return this ; }
2022-10-21 09:29:55 +00:00
void show_edit_option ( int key ) override ;
2023-08-08 23:11:44 +00:00
void load_from_raw ( const string & s ) override { * value = parseld ( s ) ; }
2023-08-21 17:23:48 +00:00
cld get_cld ( ) override { return * value ; }
2023-08-15 08:54:17 +00:00
void set_cld_raw ( cld x ) override { * value = real ( x ) ; }
2024-05-26 18:22:29 +00:00
string save ( ) override { return fts ( * value , 10 ) ; }
shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) override ;
2021-01-31 18:55:33 +00:00
} ;
2024-05-26 18:22:29 +00:00
struct float_parameter_dft : public float_parameter {
2023-02-19 00:00:15 +00:00
void show_edit_option ( int key ) override ;
function < ld ( ) > get_hint ;
2024-05-26 18:22:29 +00:00
float_parameter_dft * set_hint ( const function < ld ( ) > & f ) { get_hint = f ; return this ; }
2023-02-19 00:00:15 +00:00
} ;
2024-05-26 18:22:29 +00:00
struct int_parameter : public val_parameter < int > {
2021-02-06 12:15:24 +00:00
int min_value , max_value ;
ld step ;
2024-05-26 18:22:29 +00:00
function < void ( int_parameter * ) > modify_me ;
int_parameter * modif ( const function < void ( int_parameter * ) > & r ) { modify_me = r ; return this ; }
2022-10-21 09:29:55 +00:00
void show_edit_option ( int key ) override ;
2024-05-26 18:22:29 +00:00
int_parameter * editable ( int min_value , int max_value , ld step , string menu_item_name , string help_text , char key ) {
2022-02-26 10:18:57 +00:00
this - > is_editable = true ;
2021-02-01 14:22:47 +00:00
this - > min_value = min_value ;
this - > max_value = max_value ;
this - > menu_item_name = menu_item_name ;
2023-12-03 13:10:03 +00:00
menu_item_name_modified = true ;
2021-02-01 14:22:47 +00:00
this - > help_text = help_text ;
this - > step = step ;
default_key = key ;
return this ;
}
2021-02-04 14:01:27 +00:00
2023-08-21 17:23:48 +00:00
cld get_cld ( ) override { return * value ; }
2023-08-08 23:01:32 +00:00
2023-08-08 23:11:44 +00:00
void load_from_raw ( const string & s ) override { * value = parseint ( s ) ; }
2023-08-15 08:54:17 +00:00
void set_cld_raw ( cld x ) override { * value = ( int ) ( real ( x ) + .5 ) ; }
2023-08-08 23:01:32 +00:00
2023-08-21 17:23:48 +00:00
void check_change ( ) override {
2023-08-08 23:01:32 +00:00
if ( * value ! = last_value ) {
last_value = * value ;
add_to_changed ( this ) ;
}
}
2024-05-26 18:22:29 +00:00
string save ( ) override { return its ( * value ) ; }
shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) override ;
} ;
struct string_parameter : public val_parameter < string > {
2024-05-28 13:08:30 +00:00
reaction_t editor ;
2024-05-26 18:22:29 +00:00
string save ( ) override { return * value ; }
void load_from_raw ( const string & s ) override { * value = s ; }
2024-05-27 09:32:12 +00:00
void show_edit_option ( int key ) override ;
2024-05-28 13:35:42 +00:00
string_parameter * set_standard_editor ( bool direct ) ;
2024-05-28 13:08:30 +00:00
string_parameter * set_file_editor ( string ext ) ;
string_parameter * editable ( string cap , string help , char key ) {
is_editable = true ;
menu_item_name = cap ;
default_key = key ;
menu_item_name_modified = true ;
help_text = help ;
return this ;
}
2024-05-26 18:22:29 +00:00
} ;
struct char_parameter : public val_parameter < char > {
string save ( ) override { return " \\ " + its ( * value ) ; }
void show_edit_option ( int key ) override ;
void load_from_raw ( const string & s ) override {
if ( s [ 0 ] = = ' \\ ' & & s . size ( ) > 1 ) * value = parseint ( s . substr ( 1 ) ) ;
else sscanf ( s . c_str ( ) , " %c " , value ) ;
}
} ;
struct bool_parameter : public val_parameter < bool > {
string save ( ) override { return ( * value ) ? " yes " : " no " ; }
reaction_t switcher ;
bool_parameter * editable ( string cap , char key ) {
is_editable = true ;
menu_item_name = cap ; default_key = key ;
menu_item_name_modified = true ;
return this ;
}
2024-05-27 13:21:31 +00:00
bool_parameter * help ( string help ) {
help_text = help ;
return this ;
}
2024-05-26 18:22:29 +00:00
void show_edit_option ( int key ) override ;
void load_from_raw ( const string & s ) override {
if ( s = = " yes " ) * value = true ;
else if ( s = = " no " ) * value = false ;
else * value = parseint ( s ) ;
}
cld get_cld ( ) override { return * value ; }
shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) override ;
2023-08-06 20:07:08 +00:00
} ;
2024-05-26 18:22:29 +00:00
struct color_parameter : public val_parameter < color_t > {
2023-08-06 20:07:08 +00:00
bool has_alpha ;
void show_edit_option ( int key ) override ;
2024-05-26 18:22:29 +00:00
color_parameter * editable ( string menu_item_name , string help_text , char key ) {
2023-08-06 20:07:08 +00:00
this - > is_editable = true ;
this - > menu_item_name = menu_item_name ;
2023-12-03 13:10:03 +00:00
menu_item_name_modified = true ;
2023-08-06 20:07:08 +00:00
this - > help_text = help_text ;
default_key = key ;
return this ;
}
2024-05-27 10:24:12 +00:00
cld get_cld ( ) override { return has_alpha ? * value : ( * value * 256 + 0xFF ) ; }
2024-05-28 18:20:56 +00:00
void load_from_raw ( const string & s ) override {
try {
* value = parsecolor ( s , has_alpha ) ;
} catch ( hr_parse_exception & e ) {
sscanf ( s . c_str ( ) , " %x " , value ) ;
}
}
2024-05-27 10:29:37 +00:00
string save ( ) override { return has_alpha ? itsh8 ( * value ) : itsh6 ( * value ) ; }
2024-05-26 18:22:29 +00:00
shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) override ;
} ;
/** transmatrix with equality, so we can construct val_parameter<matrix_eq> */
struct matrix_eq : transmatrix {
bool operator = = ( const transmatrix & t ) const {
for ( int i = 0 ; i < MAXMDIM ; i + + ) for ( int j = 0 ; j < MAXMDIM ; j + + ) if ( self [ i ] [ j ] ! = t [ i ] [ j ] ) return false ;
return true ;
}
bool operator ! = ( const transmatrix & t ) const {
return ! ( self = = t ) ;
}
2021-02-01 02:11:15 +00:00
} ;
2024-05-26 18:22:29 +00:00
struct matrix_parameter : public val_parameter < matrix_eq > {
void reset ( ) override { * value = dft ; }
bool dosave ( ) override { return ! eqmatrix ( * value , dft ) ; }
2023-08-10 12:38:59 +00:00
int dim ;
2023-08-08 15:20:39 +00:00
void show_edit_option ( int key ) override ;
2024-05-26 18:22:29 +00:00
matrix_parameter * editable ( string menu_item_name , string help_text , char key ) {
2023-08-08 15:20:39 +00:00
this - > is_editable = true ;
this - > menu_item_name = menu_item_name ;
2023-12-03 13:10:03 +00:00
menu_item_name_modified = true ;
2023-08-08 15:20:39 +00:00
this - > help_text = help_text ;
default_key = key ;
return this ;
}
2024-05-26 18:22:29 +00:00
string save ( ) override {
shstream ss ;
print ( ss , " matrix " ) ;
for ( int a = 0 ; a < 4 ; a + + ) for ( int b = 0 ; b < 4 ; b + + ) print ( ss , ( * value ) [ a ] [ b ] , " " ) ;
return ss . s ;
}
2023-08-08 23:11:44 +00:00
void load_from_raw ( const string & s ) override {
2024-05-26 18:22:29 +00:00
if ( s . substr ( 0 , 7 ) = = " matrix " ) {
shstream ss ;
ss . s = s . substr ( 7 ) ;
for ( int a = 0 ; a < 4 ; a + + ) for ( int b = 0 ; b < 4 ; b + + ) scan ( ss , ( * value ) [ a ] [ b ] ) ;
}
else {
( transmatrix & ) * value = parsematrix ( s ) ;
}
2023-08-07 15:14:39 +00:00
}
} ;
2024-05-26 18:22:29 +00:00
struct custom_parameter : public parameter {
cld last_value , anim_value ;
2021-02-01 02:11:15 +00:00
function < void ( char ) > custom_viewer ;
function < cld ( ) > custom_value ;
function < bool ( void * ) > custom_affect ;
2024-02-22 16:21:57 +00:00
function < void ( const string & ) > custom_load ;
2024-05-26 18:38:31 +00:00
function < string ( ) > custom_save ;
2024-05-26 18:51:33 +00:00
function < bool ( ) > custom_do_save ;
2024-05-26 18:57:32 +00:00
reaction_t custom_reset ;
2024-05-26 18:22:29 +00:00
function < shared_ptr < parameter > ( struct local_parameter_set & lps , void * value ) > custom_clone ;
2024-05-26 21:20:50 +00:00
virtual shared_ptr < parameter > clone ( struct local_parameter_set & lps , void * value ) override {
2024-05-26 18:22:29 +00:00
if ( custom_clone ) return custom_clone ( lps , value ) ;
return parameter : : clone ( lps , value ) ;
}
2024-02-22 16:21:57 +00:00
2022-10-21 09:29:55 +00:00
void show_edit_option ( int key ) override { custom_viewer ( key ) ; }
2021-07-11 22:03:08 +00:00
bool affects ( void * v ) override { return custom_affect ( v ) ; }
2023-08-21 17:23:48 +00:00
void check_change ( ) override {
2023-08-08 23:01:32 +00:00
if ( custom_value ( ) ! = last_value ) {
last_value = custom_value ( ) ;
add_to_changed ( this ) ;
}
}
2024-05-26 18:22:29 +00:00
virtual void load_from_raw ( const string & s ) {
2024-02-22 16:21:57 +00:00
if ( ! custom_load ) {
2024-05-27 00:18:22 +00:00
throw param_exception ( " parameter cannot be loaded " , this ) ;
2024-02-22 16:21:57 +00:00
}
custom_load ( s ) ;
}
2023-08-08 15:20:39 +00:00
void load ( const string & s ) override {
2024-05-26 18:22:29 +00:00
auto bak = get_cld ( ) ;
load_from_raw ( s ) ;
if ( bak ! = get_cld ( ) & & reaction ) reaction ( ) ;
2023-08-08 15:20:39 +00:00
}
2024-05-26 18:22:29 +00:00
bool load_from_animation ( const string & s ) override {
if ( anim_value ! = get_cld ( ) ) return false ;
load ( s ) ;
anim_value = get_cld ( ) ;
return true ;
}
void load_as_animation ( const string & s ) override {
load ( s ) ;
anim_value = get_cld ( ) ;
anims : : animate_parameter ( this , s ) ;
2020-11-06 14:40:59 +00:00
}
2023-08-06 20:07:08 +00:00
2024-05-26 18:22:29 +00:00
virtual cld get_cld ( ) override { return custom_value ( ) ; }
2024-05-26 18:38:31 +00:00
virtual string save ( ) override { if ( custom_save ) return custom_save ( ) ; else return " not saveable " ; }
2024-05-26 18:51:33 +00:00
virtual bool dosave ( ) override { if ( custom_do_save ) return custom_do_save ( ) ; else return false ; }
2024-05-26 18:57:32 +00:00
virtual void reset ( ) override { if ( custom_reset ) custom_reset ( ) ; }
2024-05-26 18:22:29 +00:00
virtual void swap_with ( parameter * ) override { }
} ;
2021-02-01 02:11:15 +00:00
# endif
2021-02-06 12:15:24 +00:00
void non_editable ( ) {
dialog : : addHelp ( " Warning: editing this value through this menu may not work correctly " ) ;
}
2024-05-26 18:22:29 +00:00
void float_parameter : : show_edit_option ( int key ) {
2021-01-31 19:45:00 +00:00
if ( modify_me ) modify_me ( this ) ;
2021-02-01 14:22:47 +00:00
dialog : : addSelItem ( XLAT ( menu_item_name ) , fts ( * value ) + unit , key ) ;
2023-02-18 17:32:01 +00:00
if ( * value = = use_the_default_value ) dialog : : lastItem ( ) . value = XLAT ( " default " ) ;
2021-01-31 18:55:33 +00:00
dialog : : add_action ( [ this ] ( ) {
add_to_changed ( this ) ;
dialog : : editNumber ( * value , min_value , max_value , step , dft , XLAT ( menu_item_name ) , help_text ) ;
2021-02-01 14:10:03 +00:00
if ( sets ) sets ( ) ;
2023-08-09 12:01:24 +00:00
if ( reaction ) dialog : : get_di ( ) . reaction = reaction ;
if ( ! is_editable ) dialog : : get_di ( ) . extra_options = non_editable ;
2021-01-31 18:55:33 +00:00
} ) ;
2021-01-31 17:34:54 +00:00
}
2024-05-26 18:22:29 +00:00
void float_parameter_dft : : show_edit_option ( int key ) {
2023-02-19 00:00:15 +00:00
if ( modify_me ) modify_me ( this ) ;
dialog : : addSelItem ( XLAT ( menu_item_name ) , fts ( * value ) + unit , key ) ;
if ( * value = = use_the_default_value ) dialog : : lastItem ( ) . value = XLAT ( " default: " ) + fts ( get_hint ( ) ) ;
dialog : : add_action ( [ this ] ( ) {
add_to_changed ( this ) ;
if ( * value = = use_the_default_value ) * value = get_hint ( ) ;
dialog : : editNumber ( * value , min_value , max_value , step , dft , XLAT ( menu_item_name ) , help_text ) ;
if ( sets ) sets ( ) ;
2023-08-09 12:01:24 +00:00
if ( reaction ) dialog : : get_di ( ) . reaction = reaction ;
if ( ! is_editable ) dialog : : get_di ( ) . extra_options = non_editable ;
auto eo = dialog : : get_di ( ) . extra_options ;
dialog : : get_di ( ) . extra_options = [ eo , this ] {
2023-02-19 00:00:15 +00:00
dialog : : addSelItem ( XLAT ( " use the default value " ) , " " , ' D ' ) ;
dialog : : add_action ( [ this ] { * value = use_the_default_value ; } ) ;
if ( eo ) eo ( ) ;
} ;
} ) ;
}
2024-05-26 18:22:29 +00:00
void int_parameter : : show_edit_option ( int key ) {
2021-02-01 02:11:15 +00:00
if ( modify_me ) modify_me ( this ) ;
2021-02-01 14:22:47 +00:00
dialog : : addSelItem ( XLAT ( menu_item_name ) , its ( * value ) , key ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ this ] ( ) {
add_to_changed ( this ) ;
2021-02-01 16:00:11 +00:00
dialog : : editNumber ( * value , min_value , max_value , step , dft , XLAT ( menu_item_name ) , help_text ) ;
2021-02-01 14:10:03 +00:00
if ( sets ) sets ( ) ;
2023-08-09 12:01:24 +00:00
if ( reaction ) dialog : : get_di ( ) . reaction = reaction ;
if ( ! is_editable ) dialog : : get_di ( ) . extra_options = non_editable ;
2021-02-01 02:11:15 +00:00
} ) ;
}
2024-05-26 18:22:29 +00:00
void bool_parameter : : show_edit_option ( int key ) {
2021-02-01 14:22:47 +00:00
dialog : : addBoolItem ( XLAT ( menu_item_name ) , * value , key ) ;
2024-05-27 13:53:37 +00:00
if ( is_highlight ( dialog : : items . back ( ) ) & & help_text ! = menu_item_name ) mouseovers = XLAT ( help_text ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ this ] ( ) {
2024-05-27 13:21:31 +00:00
if ( use_bool_dialog | | hiliteclick ) {
auto & bd = dialog : : editBool ( * value , dft , XLAT ( menu_item_name ) , XLAT ( help_text ) , switcher ) ;
if ( sets ) sets ( ) ;
if ( reaction ) bd . reaction = reaction ;
if ( ! is_editable ) bd . extra_options = non_editable ;
}
else {
add_to_changed ( this ) ;
switcher ( ) ; if ( sets ) sets ( ) ;
if ( reaction ) reaction ( ) ;
}
2021-02-01 02:11:15 +00:00
} ) ;
}
2024-05-26 18:22:29 +00:00
void color_parameter : : show_edit_option ( int key ) {
2023-08-06 20:07:08 +00:00
dialog : : addColorItem ( XLAT ( menu_item_name ) , has_alpha ? * value : addalpha ( * value ) , key ) ;
dialog : : add_action ( [ this ] ( ) {
dialog : : openColorDialog ( * value ) ;
dialog : : colorAlpha = has_alpha ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags | = sm : : SIDE ;
2023-08-06 20:07:08 +00:00
} ) ;
}
2024-05-26 18:22:29 +00:00
void matrix_parameter : : show_edit_option ( int key ) {
2023-08-15 15:08:12 +00:00
dialog : : addMatrixItem ( XLAT ( menu_item_name ) , * value , key , dim ) ;
2023-08-08 15:20:39 +00:00
dialog : : add_action ( [ this ] ( ) {
2023-08-10 12:38:59 +00:00
dialog : : editMatrix ( * value , XLAT ( menu_item_name ) , help_text , dim ) ;
2023-08-14 14:59:46 +00:00
if ( sets ) sets ( ) ;
if ( reaction ) dialog : : get_di ( ) . reaction = reaction ;
2023-08-08 15:20:39 +00:00
} ) ;
}
2024-05-26 18:22:29 +00:00
void char_parameter : : show_edit_option ( int key ) {
2024-05-27 09:32:12 +00:00
string s = s0 ; s + = * ( value ) ;
2023-08-07 15:14:39 +00:00
dialog : : addSelItem ( XLAT ( menu_item_name ) , s , key ) ;
}
2024-05-27 09:32:12 +00:00
void string_parameter : : show_edit_option ( int key ) {
dialog : : addSelItem ( XLAT ( menu_item_name ) , * value , key ) ;
2024-05-28 13:08:30 +00:00
if ( ! editor ) {
if ( is_highlight ( dialog : : items . back ( ) ) ) mouseovers = XLAT ( " not editable " ) ;
}
else dialog : : add_action ( editor ) ;
}
2024-05-28 13:35:42 +00:00
string_parameter * string_parameter : : set_standard_editor ( bool direct ) {
2024-05-28 13:26:10 +00:00
shared_ptr < string > bak = make_shared < string > ( ) ;
2024-05-28 13:35:42 +00:00
editor = [ this , bak , direct ] {
2024-05-28 13:26:10 +00:00
* bak = * value ;
2024-05-28 13:35:42 +00:00
dialog : : edit_string ( direct ? * value : * bak , menu_item_name , help_text ) ;
dialog : : get_di ( ) . reaction = [ direct , this , bak ] {
if ( ! direct ) if ( pre_reaction ) pre_reaction ( ) ;
if ( ! direct ) * value = * bak ;
2024-05-28 13:08:30 +00:00
if ( reaction ) reaction ( ) ;
} ;
2024-05-28 13:26:10 +00:00
if ( sets ) sets ( ) ;
2024-05-28 13:08:30 +00:00
} ;
return this ;
}
string_parameter * string_parameter : : set_file_editor ( string ext ) {
2024-05-28 13:26:10 +00:00
shared_ptr < string > bak = make_shared < string > ( ) ;
2024-05-28 13:08:30 +00:00
editor = [ this , bak , ext ] {
2024-05-28 13:26:10 +00:00
* bak = * value ;
2024-05-28 13:08:30 +00:00
dialog : : openFileDialog ( * bak , menu_item_name , ext , [ this , bak ] {
if ( pre_reaction ) pre_reaction ( ) ;
* value = * bak ;
if ( reaction ) reaction ( ) ;
return true ;
} ) ;
} ;
return this ;
2024-05-27 09:32:12 +00:00
}
2024-05-26 18:22:29 +00:00
void parameter : : setup ( const parameter_names & n ) {
name = n . name ;
legacy_config_name = n . legacy_config_name ;
menu_item_name = n . legacy_config_name ;
menu_item_name_modified = false ;
if ( params . count ( name ) ) println ( hlog , " ERROR: repeated parameter name " , name ) ;
params [ name ] = shared_from_this ( ) ;
}
EX shared_ptr < float_parameter > param_f ( ld & val , const parameter_names & n , ld dft ) {
shared_ptr < float_parameter > u ( new float_parameter ) ;
u - > setup ( n ) ;
2021-01-31 18:55:33 +00:00
u - > value = & val ;
2021-02-01 14:10:03 +00:00
u - > last_value = dft ;
2021-02-01 11:50:02 +00:00
if ( dft = = 0 ) {
u - > min_value = - 100 ;
u - > max_value = + 100 ;
}
else {
u - > min_value = 0 ;
u - > max_value = 2 * dft ;
}
2021-01-31 18:55:33 +00:00
u - > step = dft / 10 ;
u - > dft = dft ;
val = dft ;
2024-05-26 18:22:29 +00:00
return u ;
2021-01-31 17:34:54 +00:00
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < float_parameter_dft > param_fd ( ld & val , const parameter_names & n , ld dft IS ( use_the_default_value ) ) {
shared_ptr < float_parameter_dft > u ( new float_parameter_dft ) ;
u - > setup ( n ) ;
2023-02-19 00:00:15 +00:00
u - > value = & val ;
u - > last_value = dft ;
u - > min_value = - 100 ;
u - > max_value = + 100 ;
u - > step = 1 ;
u - > dft = dft ;
val = dft ;
2024-05-26 18:22:29 +00:00
return u ;
2023-02-19 00:00:15 +00:00
}
2021-02-01 02:11:15 +00:00
EX string param_esc ( string s ) {
string out ;
for ( char c : s )
if ( c = = ' ' | | c = = ' - ' | | c = = ' : ' )
out + = ' _ ' ;
else
out + = c ;
return out ;
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < int_parameter > param_i ( int & val , const parameter_names & n , int dft ) {
shared_ptr < int_parameter > u ( new int_parameter ) ;
u - > setup ( n ) ;
2021-02-01 02:11:15 +00:00
u - > value = & val ;
2021-02-01 14:10:03 +00:00
u - > last_value = dft ;
2021-02-01 02:11:15 +00:00
u - > dft = dft ;
val = dft ;
2021-02-01 14:10:03 +00:00
if ( dft = = 0 ) {
u - > min_value = - 100 ;
u - > max_value = + 100 ;
}
else {
u - > min_value = 0 ;
u - > max_value = 2 * dft ;
}
2024-05-26 18:22:29 +00:00
return u ;
2021-02-01 02:11:15 +00:00
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < int_parameter > param_i ( int & val , const parameter_names & n ) { return param_i ( val , n , val ) ; }
2021-02-01 02:11:15 +00:00
2024-05-26 18:22:29 +00:00
EX shared_ptr < bool_parameter > param_b ( bool & val , const parameter_names & n , bool dft ) {
shared_ptr < bool_parameter > u ( new bool_parameter ) ;
u - > setup ( n ) ;
2021-02-01 02:11:15 +00:00
u - > value = & val ;
2021-02-01 14:10:03 +00:00
u - > last_value = dft ;
2021-02-01 02:11:15 +00:00
u - > dft = dft ;
u - > switcher = [ & val ] { val = ! val ; } ;
val = dft ;
2024-05-26 18:22:29 +00:00
return u ;
2021-02-01 02:11:15 +00:00
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < color_parameter > param_color ( color_t & val , const parameter_names & n , bool has_alpha , color_t dft ) {
shared_ptr < color_parameter > u ( new color_parameter ) ;
u - > setup ( n ) ;
2023-08-06 20:07:08 +00:00
u - > value = & val ;
u - > last_value = dft ;
u - > dft = dft ;
u - > has_alpha = has_alpha ;
val = dft ;
2024-05-26 18:22:29 +00:00
return u ;
2023-08-06 20:07:08 +00:00
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < matrix_parameter > param_matrix ( transmatrix & val0 , const parameter_names & n , int dim ) {
2023-08-10 12:38:59 +00:00
matrix_eq & val = ( matrix_eq & ) val0 ;
2024-05-26 18:22:29 +00:00
shared_ptr < matrix_parameter > u ( new matrix_parameter ) ;
u - > setup ( n ) ;
2023-08-08 15:20:39 +00:00
u - > value = & val ;
2023-08-08 23:01:32 +00:00
u - > last_value = val ;
2023-08-08 15:20:39 +00:00
u - > dft = val ;
2023-08-10 12:38:59 +00:00
u - > dim = dim ;
2024-05-26 18:22:29 +00:00
return u ;
2023-08-08 15:20:39 +00:00
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < char_parameter > param_char ( char & val , const parameter_names & n , char dft ) {
shared_ptr < char_parameter > u ( new char_parameter ) ;
u - > setup ( n ) ;
2023-08-07 15:14:39 +00:00
u - > value = & val ;
u - > last_value = dft ;
u - > dft = dft ;
val = dft ;
2024-05-26 18:22:29 +00:00
return u ;
}
EX shared_ptr < string_parameter > param_str ( string & val , const parameter_names & n , const string dft ) {
shared_ptr < string_parameter > u ( new string_parameter ) ;
u - > setup ( n ) ;
u - > value = & val ;
u - > last_value = val ;
u - > dft = dft ;
val = dft ;
return u ;
2023-08-07 15:14:39 +00:00
}
2024-05-26 18:22:29 +00:00
EX shared_ptr < string_parameter > param_str ( string & val , const parameter_names & n ) { return param_str ( val , n , val ) ; }
2023-08-06 20:07:08 +00:00
2024-05-26 18:22:29 +00:00
EX shared_ptr < color_parameter > param_color ( color_t & val , const parameter_names & n , bool has_alpha ) { return param_color ( val , n , has_alpha , val ) ; }
2021-02-01 02:11:15 +00:00
2024-05-26 18:22:29 +00:00
EX shared_ptr < bool_parameter > param_b ( bool & val , const parameter_names & n ) { return param_b ( val , n , val ) ; }
2021-02-01 00:35:34 +00:00
2024-05-26 18:22:29 +00:00
# if HDR
template < class T > shared_ptr < enum_parameter < T > > param_enum ( T & val , const parameter_names & n , T dft ) {
shared_ptr < enum_parameter < T > > u ( new enum_parameter < T > ) ;
u - > setup ( n ) ;
2021-02-01 00:35:34 +00:00
u - > value = & val ;
u - > dft = dft ;
val = dft ;
2023-08-08 23:01:32 +00:00
u - > last_value = dft ;
2021-02-01 00:35:34 +00:00
auto f = & * u ;
2023-10-26 10:26:03 +00:00
u - > set_value_to = [ f ] ( T val ) { * f - > value = val ; } ;
2024-05-26 18:22:29 +00:00
return u ;
2021-02-01 00:35:34 +00:00
}
2024-05-26 18:22:29 +00:00
template < class T > shared_ptr < enum_parameter < T > > param_enum ( T & val , const parameter_names & n ) { return param_enum ( val , n , val ) ; }
template < class T > shared_ptr < parameter > enum_parameter < T > : : clone ( struct local_parameter_set & lps , void * value ) { return param_enum ( * ( T * ) value , lps . mod ( this ) , * ( T * ) value ) ; }
2021-02-01 00:35:34 +00:00
# endif
2024-05-26 18:22:29 +00:00
EX shared_ptr < float_parameter > param_f ( ld & val , const parameter_names & n ) {
return param_f ( val , n , val ) ;
}
parameter_names local_parameter_set : : mod ( parameter * t ) {
return parameter_names ( label + t - > name , label + t - > legacy_config_name ) ;
}
shared_ptr < parameter > int_parameter : : clone ( struct local_parameter_set & lps , void * value ) {
auto val = ( int * ) value ;
return param_i ( * val , lps . mod ( this ) , * val ) ;
}
shared_ptr < parameter > bool_parameter : : clone ( struct local_parameter_set & lps , void * value ) {
auto val = ( bool * ) value ;
return param_b ( * val , lps . mod ( this ) , * val ) ;
2021-01-31 18:55:33 +00:00
}
2024-05-26 18:22:29 +00:00
shared_ptr < parameter > color_parameter : : clone ( struct local_parameter_set & lps , void * value ) {
auto val = ( color_t * ) value ;
return param_color ( * val , lps . mod ( this ) , has_alpha , * val ) ;
2021-01-31 18:55:33 +00:00
}
2024-05-26 18:22:29 +00:00
shared_ptr < parameter > float_parameter : : clone ( struct local_parameter_set & lps , void * value ) {
auto val = ( ld * ) value ;
return param_f ( * val , lps . mod ( this ) , * val ) ;
2020-12-31 01:42:00 +00:00
}
2021-02-01 02:11:15 +00:00
# if HDR
template < class T >
2024-05-26 18:22:29 +00:00
shared_ptr < custom_parameter > param_custom_int ( T & val , const parameter_names & n , function < void ( char ) > menuitem , char key ) {
shared_ptr < custom_parameter > u ( new custom_parameter ) ;
u - > setup ( n ) ;
2024-05-26 18:51:33 +00:00
int dft = ( int ) val ;
u - > last_value = dft ;
2021-02-01 02:11:15 +00:00
u - > custom_viewer = menuitem ;
2021-02-01 14:22:47 +00:00
u - > custom_value = [ & val ] ( ) { return ( int ) val ; } ;
2021-02-01 02:11:15 +00:00
u - > custom_affect = [ & val ] ( void * v ) { return & val = = v ; } ;
2024-02-22 16:21:57 +00:00
u - > custom_load = [ & val ] ( const string & s ) { val = ( T ) parseint ( s ) ; } ;
2024-05-26 18:38:31 +00:00
u - > custom_save = [ & val ] { return its ( int ( val ) ) ; } ;
2024-05-26 18:51:33 +00:00
u - > custom_do_save = [ dft , & val ] { return int ( val ) ! = dft ; } ;
2024-05-26 18:22:29 +00:00
u - > custom_clone = [ u ] ( struct local_parameter_set & lps , void * value ) { auto val = ( int * ) value ; return param_i ( * val , lps . mod ( & * u ) , * val ) ; } ;
2024-05-26 18:57:32 +00:00
u - > custom_reset = [ dft , & val ] { val = ( T ) dft ; } ;
2021-02-01 02:11:15 +00:00
u - > default_key = key ;
2021-02-06 12:15:24 +00:00
u - > is_editable = true ;
2024-05-26 18:22:29 +00:00
return u ;
2021-02-01 02:11:15 +00:00
}
# endif
2024-05-26 18:22:29 +00:00
EX shared_ptr < custom_parameter > param_custom_ld ( ld & val , const parameter_names & n , function < void ( char ) > menuitem , char key ) {
shared_ptr < custom_parameter > u ( new custom_parameter ) ;
u - > setup ( n ) ;
2024-05-26 18:51:33 +00:00
ld dft = val ;
u - > last_value = dft ;
2024-05-26 18:22:29 +00:00
u - > custom_viewer = menuitem ;
u - > custom_value = [ & val ] ( ) { return val ; } ;
u - > custom_affect = [ & val ] ( void * v ) { return & val = = v ; } ;
u - > custom_load = [ & val ] ( const string & s ) { val = parseld ( s ) ; } ;
2024-05-26 18:38:31 +00:00
u - > custom_save = [ & val ] { return fts ( val , 10 ) ; } ;
2024-05-26 18:51:33 +00:00
u - > custom_do_save = [ dft , & val ] { return val ! = dft ; } ;
2024-05-26 18:22:29 +00:00
u - > custom_clone = [ u ] ( struct local_parameter_set & lps , void * value ) { auto val = ( ld * ) value ; return param_f ( * val , lps . mod ( & * u ) , * val ) ; } ;
2024-05-26 18:57:32 +00:00
u - > custom_reset = [ dft , & val ] { val = dft ; } ;
2024-05-26 18:22:29 +00:00
u - > default_key = key ;
u - > is_editable = true ;
return u ;
}
2024-05-26 19:15:26 +00:00
EX shared_ptr < custom_parameter > param_colortable ( colortable & val , const parameter_names & n ) {
shared_ptr < custom_parameter > u ( new custom_parameter ) ;
u - > setup ( n ) ;
colortable dft = val ;
u - > last_value = - 1 ;
u - > custom_viewer = [ ] ( char key ) { } ;
2024-05-26 21:26:49 +00:00
u - > custom_value = [ ] ( ) { return - 1 ; } ;
2024-05-26 19:15:26 +00:00
u - > custom_affect = [ & val ] ( void * v ) { return & val = = v ; } ;
u - > custom_load = [ & val ] ( const string & s ) {
2024-05-27 11:10:18 +00:00
val = parsecolortable ( s ) ;
2024-05-26 19:15:26 +00:00
} ;
u - > custom_save = [ & val ] {
bool first = true ;
string str ;
for ( auto v : val ) { if ( first ) first = false ; else str + = " , " ; str + = itsh ( v ) ; }
return str ;
} ;
u - > custom_do_save = [ dft , & val ] { return val ! = dft ; } ;
u - > custom_clone = [ u ] ( struct local_parameter_set & lps , void * value ) { auto val = ( colortable * ) value ; return param_colortable ( * val , lps . mod ( & * u ) ) ; } ;
u - > custom_reset = [ dft , & val ] { val = dft ; } ;
u - > default_key = 0 ;
u - > is_editable = true ;
return u ;
}
2020-11-06 14:40:59 +00:00
EX ld bounded_mine_percentage = 0.1 ;
EX int bounded_mine_quantity , bounded_mine_max ;
EX const char * conffile = " hyperrogue.ini " ;
/* extra space if more geometries are added */
EX array < ld , gGUARD + 64 > sightranges ;
2022-04-07 18:50:59 +00:00
EX bool logfog ;
2020-11-06 14:40:59 +00:00
EX videopar vid ;
# define DEFAULT_WALLMODE (ISMOBILE ? 3 : 5)
# define DEFAULT_MONMODE (ISMOBILE ? 2 : 4)
2021-02-06 00:39:18 +00:00
EX void android_settings_changed ( ) {
# if ISANDROID
settingsChanged = true ;
# endif
}
2020-11-06 14:40:59 +00:00
extern color_t floorcolors [ landtypes ] ;
EX charstyle & getcs ( int id IS ( multi : : cpid ) ) {
if ( multi : : players > 1 & & id > = 0 & & id < multi : : players )
return multi : : scs [ id ] ;
else
return vid . cs ;
}
struct charstyle_old {
int charid ;
color_t skincolor , haircolor , dresscolor , swordcolor , dresscolor2 , uicolor ;
bool lefthanded ;
} ;
2023-12-12 19:03:42 +00:00
struct charstyle_prebow {
int charid ;
color_t skincolor , haircolor , dresscolor , swordcolor , dresscolor2 , uicolor , eyecolor ;
bool lefthanded ;
} ;
2020-11-06 14:40:59 +00:00
EX void hread ( hstream & hs , charstyle & cs ) {
// before 0xA61A there was no eyecolor
if ( hs . get_vernum ( ) < 0xA61A ) {
charstyle_old cso ;
hread_raw ( hs , cso ) ;
cs . charid = cso . charid ;
cs . skincolor = cso . skincolor ;
cs . haircolor = cso . haircolor ;
cs . dresscolor = cso . dresscolor ;
2023-10-26 10:30:33 +00:00
cs . swordcolor = cs . eyecolor = cs . bowcolor = cs . bowcolor2 = cso . swordcolor ;
2020-11-06 14:40:59 +00:00
if ( cs . charid < 4 ) cs . eyecolor = 0 ;
cs . dresscolor2 = cso . dresscolor2 ;
cs . uicolor = cso . uicolor ;
2023-12-12 19:03:42 +00:00
cs . lefthanded = cso . lefthanded ;
}
else if ( hs . get_vernum ( ) < 0xA938 ) {
charstyle_prebow cso ;
hread_raw ( hs , cso ) ;
cs . charid = cso . charid ;
cs . skincolor = cso . skincolor ;
cs . haircolor = cso . haircolor ;
cs . dresscolor = cso . dresscolor ;
cs . eyecolor = cso . eyecolor ;
cs . swordcolor = cs . bowcolor = cs . bowcolor2 = cso . swordcolor ;
if ( cs . charid < 4 ) cs . eyecolor = 0 ;
cs . dresscolor2 = cso . dresscolor2 ;
cs . uicolor = cso . uicolor ;
cs . lefthanded = cso . lefthanded ;
2020-11-06 14:40:59 +00:00
}
else hread_raw ( hs , cs ) ;
}
EX void hwrite ( hstream & hs , const charstyle & cs ) {
hwrite_raw ( hs , cs ) ;
}
// void hread(hstream& hs, charstyle& cs) { hread_raw(hs, cs); }
// void hwrite(hstream& hs, const charstyle& cs) { hwrite_raw(hs, cs); }
EX string csnameid ( int id ) {
if ( id = = 0 ) return XLAT ( " male " ) ;
if ( id = = 1 ) return XLAT ( " female " ) ;
if ( id = = 2 ) return XLAT ( " Prince " ) ;
if ( id = = 3 ) return XLAT ( " Princess " ) ;
if ( id = = 4 | | id = = 5 ) return XLAT ( " cat " ) ;
if ( id = = 6 | | id = = 7 ) return XLAT ( " dog " ) ;
if ( id = = 8 | | id = = 9 ) return XLATN ( " Familiar " ) ;
return XLAT ( " none " ) ;
}
EX string csname ( charstyle & cs ) {
return csnameid ( cs . charid ) ;
}
EX int playergender ( ) {
return ( getcs ( ) . charid > = 0 & & ( getcs ( ) . charid & 1 ) ) ? GEN_F : GEN_M ;
}
EX int princessgender ( ) {
int g = playergender ( ) ;
if ( vid . samegender ) return g ;
return g = = GEN_M ? GEN_F : GEN_M ;
}
EX int default_language ;
EX int lang ( ) {
if ( vid . language > = 0 )
return vid . language ;
return default_language ;
}
EX bool autojoy = true ;
2024-05-26 18:22:29 +00:00
EX void paramset ( charstyle & cs , string s ) {
param_i ( cs . charid , s + " .charid " ) ;
param_color ( cs . skincolor , s + " .skincolor " , true , cs . skincolor ) ;
param_color ( cs . eyecolor , s + " .eyecolor " , true , cs . eyecolor ) ;
param_color ( cs . bowcolor , s + " .bowcolor " , true , cs . bowcolor ) ;
param_color ( cs . bowcolor2 , s + " .bowcolor2 " , true , cs . bowcolor2 ) ;
param_color ( cs . haircolor , s + " .haircolor " , true , cs . haircolor ) ;
param_color ( cs . dresscolor , s + " .dresscolor " , true , cs . dresscolor ) ;
param_color ( cs . swordcolor , s + " .swordcolor " , true , cs . swordcolor ) ;
param_color ( cs . dresscolor2 , s + " .dresscolor2 " , true , cs . dresscolor2 ) ;
param_color ( cs . uicolor , s + " .uicolor " , true , cs . uicolor ) ;
param_b ( cs . lefthanded , s + " .lefthanded " ) ;
2020-11-06 14:40:59 +00:00
}
// R:239, G:208, B:207
unsigned int skincolors [ ] = { 7 , 0xD0D0D0FF , 0xEFD0C9FF , 0xC77A58FF , 0xA58869FF , 0x602010FF , 0xFFDCB1FF , 0xEDE4C8FF } ;
unsigned int haircolors [ ] = { 8 , 0x686868FF , 0x8C684AFF , 0xF2E1AEFF , 0xB55239FF , 0xFFFFFFFF , 0x804000FF , 0x502810FF , 0x301800FF } ;
unsigned int dresscolors [ ] = { 6 , 0xC00000FF , 0x00C000FF , 0x0000C0FF , 0xC0C000FF , 0xC0C0C0FF , 0x202020FF } ;
unsigned int dresscolors2 [ ] = { 7 , 0x8080FFC0 , 0x80FF80C0 , 0xFF8080C0 , 0xFFFF80C0 , 0xFF80FFC0 , 0x80FFFFC0 , 0xFFFFFF80 } ;
unsigned int swordcolors [ ] = { 6 , 0xC0C0C0FF , 0xFFFFFFFF , 0xFFC0C0FF , 0xC0C0FFFF , 0x808080FF , 0x202020FF } ;
unsigned int eyecolors [ ] = { 4 , 0x00C000FF , 0x0000C0FF , 0xC00000FF , 0xC0C000FF , 0x804010FF , 0x00C000FF } ;
EX void initcs ( charstyle & cs ) {
cs . charid = 0 ;
cs . skincolor = 0xD0D0D0FF ;
cs . haircolor = 0x686868FF ;
cs . dresscolor = 0xC00000FF ;
cs . swordcolor = 0xD0D0D0FF ;
cs . dresscolor2 = 0x8080FFC0 ;
cs . uicolor = 0xFF0000FF ;
cs . eyecolor = 0x603000FF ;
2023-10-26 10:30:33 +00:00
cs . bowcolor = 0x603000FF ;
cs . bowcolor2 = 0xFFD500FF ;
2020-11-06 14:40:59 +00:00
cs . lefthanded = false ;
}
EX purehookset hooks_configfile ;
2024-03-21 17:44:19 +00:00
EX ld mapfontscale = 100 ;
2020-11-06 14:40:59 +00:00
EX void initConfig ( ) {
// basic config
2021-02-01 02:11:15 +00:00
param_i ( vid . flashtime , " flashtime " , 8 ) ;
2021-02-01 00:35:34 +00:00
2021-02-01 02:11:15 +00:00
param_i ( vid . msglimit , " message limit " , 5 ) ;
param_i ( vid . timeformat , " message log time format " , 0 ) ;
2021-03-09 09:48:03 +00:00
param_b ( resizable , " resizable " , true )
2024-05-27 13:21:57 +00:00
- > editable ( " resizable window " , ' r ' )
- > help ( " This lets your operating system resize the window. " ) ;
2021-02-06 00:39:18 +00:00
2024-05-27 13:21:57 +00:00
param_b ( no_find_player , " no_find_player " )
- > help ( " Do not show the 'find player' button even if the player seems to be lost. " ) ;
2022-10-24 07:39:01 +00:00
param_b ( game_keys_scroll , " game_keys_scroll " )
2024-05-27 13:21:57 +00:00
- > editable ( " pure exploration (game keys scroll) " , ' P ' )
- > help ( " Enables easier control of the camera for watching visualizations (when you are not playing the game). " ) ;
2022-08-13 20:42:59 +00:00
param_b ( reg3 : : cubes_reg3 , " cubes_reg3 " ) ;
2022-08-26 10:42:07 +00:00
param_f ( linepatterns : : tree_starter , " tree_starter " )
- > editable ( 0 , 1 , 0.05 , " tree-drawing parameter " , " How much of edges to draw for tree patterns (to show how the tree edges are oriented). " , ' t ' ) ;
2022-08-05 17:20:25 +00:00
2024-05-05 18:15:53 +00:00
// param_char(patterns::whichCanvas, "whichCanvas", 0); %TODO
2024-05-27 11:38:33 +00:00
param_f ( ccolor : : rwalls , " randomwalls " ) ;
2024-05-27 13:21:57 +00:00
param_b ( patterns : : innerwalls , " innerwalls " )
- > help ( " In 3D modes, display all the walls, including the walls between adjacent wall tiles. " ) ;
param_b ( use_bool_dialog , " use_bool_dialog " )
- > editable ( " on/off dialog/help " , ' B ' )
- > help (
" Enable this for a full dialog when editing some on/off settings (otherwise, the dialog is not shown, we just switch). "
" This lets you see an explanation of what the setting does. "
" You can also press ALT while changing such settings. " ) ;
2023-08-08 10:04:19 +00:00
param_b ( vid . grid , " grid " ) ;
param_b ( models : : desitter_projections , " desitter_projections " , false ) ;
param_b ( nonisotropic_weird_transforms , " nonisotropic_weird_transforms " , false ) ;
2023-08-07 15:14:39 +00:00
2022-04-26 14:17:01 +00:00
param_b ( arb : : apeirogon_consistent_coloring , " apeirogon_consistent_coloring " , true )
2024-05-27 13:21:57 +00:00
- > editable ( " apeirogon_consistent_coloring " , ' c ' )
- > help ( " In arbitrary tilings, apeirogons are internally represented as multiple tiles. This option ensures that all subtiles have the same color. " ) ;
2022-04-26 14:17:01 +00:00
param_b ( arb : : apeirogon_hide_grid_edges , " apeirogon_hide_grid_edges " , true )
2024-05-27 13:21:57 +00:00
- > editable ( " apeirogon_hide_grid_edges " , ' h ' )
- > help ( " In arbitrary tilings, apeirogons are internally represented as multiple tiles. This option hides the subtile edges. " ) ;
2022-05-01 09:18:39 +00:00
param_b ( arb : : apeirogon_simplified_display , " apeirogon_simplified_display " , false )
2024-05-27 13:21:57 +00:00
- > editable ( " simplified display of apeirogons " , ' f ' )
- > help ( " Connect the ends of the apeirogon segment with the boundary point using straight lines. This should be faster and, in most cases, actually more correct. " ) ;
2022-06-23 08:29:49 +00:00
param_b ( arb : : convert : : minimize_on_convert , " tes_minimize_on_convert " , false )
2022-06-23 08:35:49 +00:00
- > editable ( " consider all symmetries when converting " , ' m ' ) ;
2022-06-23 08:29:49 +00:00
param_b ( arb : : convert : : reverse_order , " tes_reverse_order " , false )
- > editable ( " tes reverse order on convert " , ' r ' ) ;
2022-04-26 14:17:01 +00:00
2021-05-24 14:14:02 +00:00
param_b ( display_yasc_codes , " yasc " , false )
- > editable ( " YASC codes " , ' Y ' )
2024-06-06 17:12:35 +00:00
- > help ( " YASC codes: Sides-Entity-Restrict-Threat-Wall " ) ;
2021-05-24 14:14:02 +00:00
2021-02-06 00:39:18 +00:00
param_b ( vid . relative_font , " relative_font " , true )
- > editable ( " set relative font size " , ' r ' )
2024-05-27 13:21:57 +00:00
- > help ( " Font size is set as a relation to screen size. " )
2021-02-06 00:39:18 +00:00
- > set_reaction ( compute_fsize ) ;
param_i ( vid . fontscale , " fontscale " , 100 )
- > editable ( 25 , 400 , 10 , " font scale " , " " , ' b ' )
- > set_reaction ( compute_fsize )
- > set_sets ( [ ] { dialog : : bound_low ( 0 ) ; } ) ;
2024-03-21 17:44:19 +00:00
param_f ( mapfontscale , " mapfontscale " , 100 )
- > editable ( - 400 , 400 , 10 , " map font scale " ,
" This affects the size of the characters on the ASCII map. This includes ASCII walls/monster display mode, the minimap, minefield values, and various debug features. " , ' B ' )
- > set_extra ( [ ] {
dialog : : get_di ( ) . extra_options = [ ] ( ) { draw_radar ( true ) ; } ;
} ) ;
2021-02-06 00:39:18 +00:00
param_i ( vid . abs_fsize , " fsize " , 12 )
- > editable ( 1 , 72 , 1 , " font size " , " " , ' b ' )
- > set_reaction ( compute_fsize )
- > set_sets ( [ ] { dialog : : bound_low ( 0 ) ; } ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 02:11:15 +00:00
param_i ( vid . mobilecompasssize , " mobile compass size " , 0 ) ; // ISMOBILE || ISPANDORA ? 30 : 0);
param_i ( vid . radarsize , " radarsize size " , 120 ) ;
2022-12-17 22:59:39 +00:00
param_f ( vid . radarrange , " radarrange " , 2.5 ) ;
2021-02-01 02:11:15 +00:00
param_i ( vid . axes , " movement help " , 1 ) ;
param_b ( vid . axes3 , " movement help3 " , true ) ;
param_i ( vid . shifttarget , " shift-targetting " , 2 ) ;
2024-05-26 18:22:29 +00:00
param_i ( vid . steamscore , " scores to Steam " , 1 ) ;
initcs ( vid . cs ) ; paramset ( vid . cs , " single " ) ;
2021-02-01 02:11:15 +00:00
param_b ( vid . samegender , " princess choice " , false ) ;
2024-05-26 18:22:29 +00:00
param_i ( vid . language , " language " , - 1 ) ;
2021-02-01 02:11:15 +00:00
param_b ( vid . drawmousecircle , " mouse circle " , ISMOBILE | | ISPANDORA ) ;
param_b ( vid . revcontrol , " reverse control " , false ) ;
2021-02-07 17:29:49 +00:00
# if CAP_AUDIO
2021-02-01 14:10:03 +00:00
param_i ( musicvolume , " music volume " )
- > editable ( 0 , 128 , 10 , " background music volume " , " " , ' b ' )
- > set_sets ( sets_music_volume ) ;
2021-02-07 17:29:49 +00:00
# endif
2020-11-06 14:40:59 +00:00
# if CAP_SDLAUDIO
2024-05-26 18:22:29 +00:00
param_b ( music_out_of_focus , " music out of focus " , false ) ;
2020-11-06 14:40:59 +00:00
# endif
2021-02-07 17:29:49 +00:00
# if CAP_AUDIO
2021-02-01 14:10:03 +00:00
param_i ( effvolume , " sound effect volume " )
- > editable ( 0 , 128 , 10 , " sound effects volume " , " " , ' e ' )
- > set_sets ( sets_sfx_volume ) ;
2021-02-07 17:29:49 +00:00
# endif
2021-04-30 17:44:54 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( vid . faraway_highlight , parameter_names ( " faraway_highlight " , " highlight faraway monsters " ) , tlNoThreat )
2021-04-30 17:44:54 +00:00
- > editable ( { { " off " , " " } , { " spam " , " " } , { " normal monsters " , " " } , { " high-threat monsters only " , " " } } , " highlight faraway monsters " , ' h ' ) ;
param_i ( vid . faraway_highlight_color , " faraway_highlight_color " , 50 )
- > editable ( 0 , 100 , 10 , " faraway highlight color " , " 0 = monster color, 100 = red-light oscillation " , ' c ' ) ;
2024-05-26 18:22:29 +00:00
param_enum ( glyphsortorder , parameter_names ( " glyph_sort " , " glyph sort order " ) , glyphsortorder )
2021-02-01 00:35:34 +00:00
- > editable ( {
{ " first on top " , " " } ,
{ " first on bottom " , " " } ,
{ " last on top " , " " } ,
{ " last on bottom " , " " } ,
{ " by land " , " " } ,
{ " by number " , " " }
} , " inventory/kill sorting " , ' k ' ) ;
2022-07-12 12:22:46 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( vid . orbmode , parameter_names ( " orb_mode " , " orb display mode " ) , 2 )
2022-10-06 11:10:57 +00:00
- > editable ( {
{ " plain " , " " } ,
{ " types " , " " } ,
{ " icons " , " " } ,
} , " orb display mode " , ' o ' ) ;
2022-07-12 12:22:46 +00:00
param_b ( less_in_landscape , " less_in_landscape " , false )
- > editable ( " less items/kills in landscape " , ' L ' )
2024-05-27 13:53:59 +00:00
- > help ( " If set, only the important items and kills will be shown " )
2023-08-15 18:28:06 +00:00
- > set_reaction ( [ ] { vid . killreduction = 0 ; } ) ;
2022-07-12 12:22:46 +00:00
param_b ( less_in_portrait , " less_in_portrait " , false )
- > editable ( " less items/kills in portrait " , ' P ' )
2024-05-27 13:53:59 +00:00
- > help ( " If set, only the important items and kills will be shown " )
2023-08-15 18:28:06 +00:00
- > set_reaction ( [ ] { vid . killreduction = 0 ; } ) ;
2020-11-06 14:40:59 +00:00
// basic graphics
2021-02-06 00:39:18 +00:00
param_b ( vid . wantGL , " usingGL " , true )
- > editable ( " openGL mode " , ' o ' ) ;
2024-05-26 18:22:29 +00:00
param_i ( vid . want_antialias , " antialias " , AA_NOGL | AA_FONT | ( ISWEB ? AA_MULTI : AA_LINES ) | AA_VERSION ) ;
2024-05-27 13:53:59 +00:00
param_b ( vid . fineline , " fineline " , true ) - > help ( " Disable this to make all line widths 1. " ) ;
2021-02-01 00:45:10 +00:00
param_f ( vid . linewidth , " linewidth " , 1 ) ;
2024-05-26 18:22:29 +00:00
param_f ( precise_width , " precisewidth " , .5 ) ;
2022-01-08 17:54:24 +00:00
param_i ( perfect_linewidth , " perfect_linewidth " , 1 ) ;
2024-05-26 18:22:29 +00:00
param_f ( linepatterns : : width , parameter_names ( " lpwidth " , " pattern-linewidth " ) , 1 ) ;
2024-05-27 13:53:59 +00:00
param_b ( fat_edges , " fat-edges " ) - > help ( " When this setting is ON, grid lines and various line patterns are drawn as pipes. " ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . sspeed , parameter_names ( " sspeed " , " scrollingspeed " ) , 0 ) ;
param_f ( vid . mspeed , parameter_names ( " mspeed " , " movement speed " ) , 1 ) ;
param_f ( vid . ispeed , parameter_names ( " ispeed " , " idle speed " ) , 1 ) ;
param_i ( vid . aurastr , " aura strength " , ISMOBILE ? 0 : 128 ) ;
param_i ( vid . aurasmoothen , " aura smoothen " , 5 ) ;
param_enum ( vid . graphglyph , parameter_names ( " graphglyph " , " graphical items/kills " ) , 1 )
2021-02-01 00:35:34 +00:00
- > editable ( { { " letters " , " " } , { " auto " , " " } , { " images " , " " } } , " inventory/kill mode " , ' d ' ) ;
2023-01-04 22:26:46 +00:00
param_i ( min_cells_drawn , " min_cells_drawn " ) ;
2024-05-28 13:09:00 +00:00
param_str ( menu_format , " menu_format " , " " )
2024-05-28 13:35:42 +00:00
- > set_standard_editor ( true )
2024-05-28 13:26:45 +00:00
- > editable ( " menu line format " ,
" Displays an arbitrary text instead of menu. "
" You can use e.g. $(turncount) or $(gametime,2) "
" to display the values of parameters and statistics. " ,
' T ' )
- > set_extra ( [ ] {
dialog : : addSelItem ( XLAT ( " default " ) , " " , SDLK_F1 ) ;
dialog : : add_action ( [ ] { menu_format = " " ; popScreen ( ) ; } ) ;
dialog : : addSelItem ( XLAT ( " show turn count " ) , " " , SDLK_F2 ) ;
dialog : : add_action ( [ ] { menu_format = " t:$(turncount) " ; popScreen ( ) ; } ) ;
2024-05-28 13:35:42 +00:00
dialog : : addSelItem ( XLAT ( " testing " ) , eval_programmable_string ( menu_format ) , 0 ) ;
2024-05-28 13:26:45 +00:00
} ) ;
2022-07-05 09:51:06 +00:00
param_i ( menu_darkening , " menu_darkening " , 2 )
- > editable ( 0 , 8 , 1 , " menu map darkening " , " A larger number means darker game map in the background. Set to 8 to disable the background. " , ' d ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 0 ) ; dialog : : bound_up ( 8 ) ; dialog : : get_di ( ) . dialogflags | = sm : : DARKEN ; } ) ;
2022-07-12 12:41:54 +00:00
param_b ( centered_menus , " centered_menus " , false )
- > editable ( " centered menus in widescreen " , ' c ' ) ;
2022-07-05 09:51:06 +00:00
2022-07-05 09:51:49 +00:00
param_b ( startanims : : enabled , " startanim " , true )
- > editable ( " start animations " , ' s ' ) ;
2024-05-27 13:53:59 +00:00
param_b ( vid . flasheffects , " flasheffects " , 1 )
- > editable ( " flashing effects " , ' h ' )
- > help ( " Disable if you are photosensitive. Replaces flashing effects such as Orb of Storms lightning with slow, adjustable animations. " ) ;
2022-03-08 00:37:35 +00:00
2024-05-26 18:22:29 +00:00
param_f ( vid . binary_width , parameter_names ( " bwidth " , " binary-tiling-width " ) , 1 ) ;
param_custom_ld ( vid . binary_width , " binary tiling width " , menuitem_binary_width , ' v ' ) ;
2023-03-24 22:53:13 +00:00
2023-06-10 08:35:27 +00:00
param_b ( fake : : multiple_special_draw , " fake_multiple " , true ) ;
2024-05-26 18:22:29 +00:00
param_f ( hat : : hat_param , " hat_param " , 1 )
2023-05-31 00:09:27 +00:00
- > editable ( 0 , 2 , 0.1 , " hat/spectre/turtle parameter " ,
2023-03-24 22:53:13 +00:00
" Apeirodic hat tiling based on: https://arxiv.org/pdf/2303.10798.pdf \n \n "
2023-05-31 00:10:31 +00:00
" This controls the parameter discussed in Section 6. Parameter p is Tile(p, (2-p)√3), scaled so that the area is the same for every p. \n \n "
2023-05-30 16:35:08 +00:00
" Aperiodic spectre tiling based on: https://arxiv.org/abs/2305.17743 \n \n "
2023-05-31 00:10:31 +00:00
" In the spectre tiling, set the parameter to 'spectre' value to make all tiles have the same shape. "
2023-05-30 16:35:08 +00:00
,
' v '
2023-03-24 22:53:13 +00:00
)
2023-03-28 12:10:36 +00:00
- > set_extra ( [ ] {
dialog : : addSelItem ( XLAT ( " chevron (periodic) " ) , " 0 " , ' C ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] { dialog : : get_ne ( ) . s = " 0 " ; dialog : : get_ne ( ) . apply_edit ( ) ; } ) ;
2023-03-28 12:10:36 +00:00
dialog : : addSelItem ( XLAT ( " hat " ) , " 1 " , ' H ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] { dialog : : get_ne ( ) . s = " 1 " ; dialog : : get_ne ( ) . apply_edit ( ) ; } ) ;
2023-05-30 16:35:08 +00:00
dialog : : addSelItem ( XLAT ( " spectre " ) , " 3-√3 " , ' T ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] { dialog : : get_ne ( ) . s = " 3 - sqrt(3) " ; dialog : : get_ne ( ) . apply_edit ( ) ; } ) ;
2023-03-28 12:10:36 +00:00
dialog : : addSelItem ( XLAT ( " turtle " ) , " 1.5 " , ' T ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] { dialog : : get_ne ( ) . s = " 1.5 " ; dialog : : get_ne ( ) . apply_edit ( ) ; } ) ;
2023-03-28 12:10:36 +00:00
dialog : : addSelItem ( XLAT ( " comma (periodic) " ) , " 2 " , ' , ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] { dialog : : get_ne ( ) . s = " 2 " ; dialog : : get_ne ( ) . apply_edit ( ) ; } ) ;
2023-03-28 12:10:36 +00:00
} )
2023-03-24 22:53:13 +00:00
- > set_reaction ( hat : : reshape ) ;
2024-05-26 18:22:29 +00:00
param_f ( hat : : hat_param_imag , " hat_param_imag " , 0 )
2023-04-11 14:41:05 +00:00
- > editable ( 0 , 2 , 0.1 , " hat parameter (imaginary) " ,
2023-05-30 16:35:08 +00:00
" Imaginary part of the hat parameter. This corresponds to the usual interpretation of complex numbers in Euclidean planar geometry: rather than shortened or lengthened, the edges are moved in the other dimension. " , ' v '
2023-04-11 14:41:05 +00:00
)
- > set_reaction ( hat : : reshape ) ;
2024-05-27 13:53:59 +00:00
param_b ( vid . particles , " extra effects " , 1 )
- > help ( " Disable if you do not want particle effects and similar. " ) ;
2021-02-04 14:01:42 +00:00
param_i ( vid . framelimit , " frame limit " , 999 ) ;
2021-02-06 00:39:18 +00:00
2021-02-07 17:29:49 +00:00
# if !ISMOBWEB
2021-02-06 00:39:18 +00:00
param_b ( vid . want_vsync , " vsync " , true )
2024-05-27 13:53:59 +00:00
- > help ( " Disable if you want to see the actual framerate rendered by the engine. " )
2021-02-06 00:39:18 +00:00
- > editable ( " vsync " , ' v ' ) ;
2021-02-07 17:29:49 +00:00
# endif
2021-02-06 00:39:18 +00:00
param_b ( vid . want_fullscreen , " fullscreen " , false )
- > editable ( " fullscreen mode " , ' f ' ) ;
param_b ( vid . change_fullscr , " fullscreen_change " , false )
- > editable ( " use specific fullscreen resolution " , ' g ' ) ;
param_b ( vid . relative_window_size , " window_relative " , true )
- > editable ( " specify relative window size " , ' g ' ) ;
2024-05-26 18:22:29 +00:00
param_custom_int ( vid . xres , " xres " , [ ] ( char ch ) { } , 0 ) - > restrict = return_false ;
param_custom_int ( vid . yres , " yres " , [ ] ( char ch ) { } , 0 ) - > restrict = return_false ;
2021-02-06 00:39:18 +00:00
param_i ( vid . fullscreen_x , " fullscreen_x " , 1280 )
- > editable ( 640 , 3840 , 640 , " fullscreen resolution to use (X) " , " " , ' x ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 640 ) ; dialog : : get_di ( ) . reaction_final = do_request_resolution_change ; } ) ;
2021-02-06 00:39:18 +00:00
param_i ( vid . fullscreen_y , " fullscreen_y " , 1024 )
2021-02-06 12:15:24 +00:00
- > editable ( 480 , 2160 , 480 , " fullscreen resolution to use (Y) " , " " , ' x ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 480 ) ; dialog : : get_di ( ) . reaction_final = do_request_resolution_change ; } ) ;
2021-02-06 00:39:18 +00:00
param_i ( vid . window_x , " window_x " , 1280 )
- > editable ( 160 , 3840 , 160 , " window resolution to use (X) " , " " , ' x ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 160 ) ; dialog : : get_di ( ) . reaction_final = do_request_resolution_change ; } ) ;
2021-02-06 00:39:18 +00:00
param_i ( vid . window_y , " window_y " , 1024 )
- > editable ( 120 , 2160 , 120 , " window resolution to use (Y) " , " " , ' x ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 120 ) ; dialog : : get_di ( ) . reaction_final = do_request_resolution_change ; } ) ;
2021-02-06 00:39:18 +00:00
param_f ( vid . window_rel_x , " window_rel_x " , .9 )
- > editable ( .1 , 1 , .1 , " screen size percentage to use (X) " , " " , ' x ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( .1 ) ; dialog : : get_di ( ) . reaction_final = do_request_resolution_change ; } ) ;
2021-02-06 00:39:18 +00:00
param_f ( vid . window_rel_y , " window_rel_y " , .9 )
2021-02-06 12:15:24 +00:00
- > editable ( .1 , 1 , .1 , " screen size percentage to use (Y) " , " " , ' x ' )
2023-08-09 12:01:24 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( .1 ) ; dialog : : get_di ( ) . reaction_final = do_request_resolution_change ; } ) ;
2021-02-06 00:39:18 +00:00
2021-02-01 02:11:15 +00:00
param_b ( vid . darkhepta , " mark heptagons " , false ) ;
2020-11-06 14:40:59 +00:00
2022-04-07 18:50:59 +00:00
param_b ( logfog , " logfog " , false ) ;
2020-11-06 14:40:59 +00:00
for ( auto & lp : linepatterns : : patterns ) {
2024-05-26 18:22:29 +00:00
param_color ( lp - > color , " lpcolor- " + lp - > lpname , true , lp - > color ) ;
param_f ( lp - > multiplier , " lpwidth- " + lp - > lpname ) ;
2020-11-06 14:40:59 +00:00
}
// special graphics
2024-05-26 18:22:29 +00:00
param_i ( vid . monmode , " monster display mode " , DEFAULT_MONMODE ) ;
param_i ( vid . wallmode , " wall display mode " , DEFAULT_WALLMODE ) ;
param_i ( vid . highlightmode , " highlightmode " ) ;
2020-11-06 14:40:59 +00:00
2024-05-27 13:21:44 +00:00
param_b ( vid . always3 , " 3D always " , false ) - > switcher = geom3 : : switch_fpp ;
2022-12-08 18:38:06 +00:00
2024-05-26 18:22:29 +00:00
param_f ( geom3 : : euclid_embed_scale , " euclid_embed_scale " )
2023-01-05 13:01:23 +00:00
- > editable ( 0 , 2 , 0.05 , " Euclidean embedding scale " , " How to scale the Euclidean map, relatively to the 3D absolute unit. " , ' X ' )
2022-12-16 00:26:11 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 0.05 ) ; } )
2023-04-27 20:46:07 +00:00
- > set_reaction ( geom3 : : apply_settings_light ) ;
2022-12-13 18:04:43 +00:00
2024-05-26 18:22:29 +00:00
param_f ( geom3 : : euclid_embed_scale_y , " euclid_embed_scale_y " )
2023-01-05 13:01:23 +00:00
- > editable ( 0 , 2 , 0.05 , " Euclidean embedding scale Y/X " , " This scaling factor affects only the Y coordinate. " , ' Y ' )
- > set_sets ( [ ] { dialog : : bound_low ( 0.05 ) ; } )
2023-04-27 20:46:07 +00:00
- > set_reaction ( geom3 : : apply_settings_light ) ;
2023-01-05 13:01:23 +00:00
2024-05-26 18:22:29 +00:00
param_f ( geom3 : : euclid_embed_rotate , " euclid_embed_rotate " )
2023-01-05 13:01:23 +00:00
- > editable ( 0 , 360 , 15 , " Euclidean embedding rotation " , " How to rotate the Euclidean embedding, in degrees. " , ' F ' )
2023-04-27 20:46:07 +00:00
- > set_reaction ( geom3 : : apply_settings_light ) ;
2023-01-05 13:01:23 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( embedded_shift_method_choice , " embedded_shift_method " , smcBoth )
2022-12-16 22:03:00 +00:00
- > editable ( {
{ " geodesic " , " always move on geodesics " } ,
{ " keep levels " , " keep the vertical angle of the camera " } ,
{ " mixed " , " on geodesics when moving camera manually, keep level when auto-centering " }
} , " view shift for embedded planes " , ' H ' ) ;
2024-05-26 18:22:29 +00:00
param_b ( geom3 : : auto_configure , " auto_configure_3d " )
2022-12-15 11:48:25 +00:00
- > editable ( " set 3D settings automatically " , ' A ' ) ;
2022-12-15 17:14:09 +00:00
param_b ( geom3 : : inverted_embedding , " inverted_3d " , false )
2022-12-15 12:11:23 +00:00
- > editable ( " invert convex/concave " , ' I ' )
2023-02-10 18:04:32 +00:00
- > set_reaction ( geom3 : : apply_settings_full ) ;
2022-12-15 12:11:23 +00:00
2022-12-15 17:14:09 +00:00
param_b ( geom3 : : flat_embedding , " flat_3d " , false )
2022-12-15 12:11:23 +00:00
- > editable ( " flat, not equidistant " , ' F ' )
2023-02-10 18:04:32 +00:00
- > set_reaction ( geom3 : : apply_settings_full ) ;
2022-12-15 12:11:23 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( geom3 : : spatial_embedding , " spatial_embedding " , geom3 : : seDefault )
2022-12-09 00:57:41 +00:00
- > editable ( geom3 : : spatial_embedding_options , " 3D embedding method " , ' E ' )
2023-02-10 18:04:32 +00:00
- > set_reaction ( geom3 : : apply_settings_full ) ;
2020-11-06 14:40:59 +00:00
2022-07-17 10:40:07 +00:00
param_b ( memory_saving_mode , " memory_saving_mode " , ( ISMOBILE | | ISPANDORA | | ISWEB ) ? 1 : 0 ) ;
2021-02-01 02:11:15 +00:00
param_i ( reserve_limit , " memory_reserve " , 128 ) ;
2024-05-26 18:22:29 +00:00
param_b ( show_memory_warning , " show_memory_warning " ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_b ( rug : : renderonce , " rug-renderonce " ) ;
param_b ( rug : : rendernogl , " rug-rendernogl " ) ;
param_i ( rug : : texturesize , " rug-texturesize " ) ;
2020-11-06 14:40:59 +00:00
# if CAP_RUG
2024-05-26 18:22:29 +00:00
param_f ( rug : : model_distance , " rug-model-distance " ) ;
2020-11-06 14:40:59 +00:00
# endif
2024-05-27 13:53:59 +00:00
param_b ( vid . backeffects , " background particle effects " , ( ISMOBILE | | ISPANDORA ) ? false : true )
- > help ( " Background particle effects, e.g., in the Blizzard. " ) ;
2020-11-06 14:40:59 +00:00
// control
2024-05-28 09:59:03 +00:00
param_enum ( joy_init , " joyinit " , jiFast )
- > editable ( { { " off " , " do not use joysticks " } , { " fast " , " do not wait until the joysticks are initialized " } , { " wait " , " wait until the joysticks are initialized " } } , " joystick initialization " , ' j ' ) ;
2021-02-01 02:11:15 +00:00
param_i ( vid . joyvalue , " vid.joyvalue " , 4800 ) ;
param_i ( vid . joyvalue2 , " vid.joyvalue2 " , 5600 ) ;
param_i ( vid . joysmooth , " vid.joysmooth " , 200 ) ;
param_i ( vid . joypanthreshold , " vid.joypanthreshold " , 2500 ) ;
param_f ( vid . joypanspeed , " vid.joypanspeed " , ISPANDORA ? 0.0001 : 0 ) ;
2024-05-26 18:22:29 +00:00
param_b ( autojoy , " autojoy " ) ;
2020-11-06 14:40:59 +00:00
vid . killreduction = 0 ;
2021-02-01 02:11:15 +00:00
param_b ( vid . skipstart , " skip the start menu " , false ) ;
2024-05-27 13:53:59 +00:00
param_b ( vid . quickmouse , " quick mouse " , ! ISPANDORA )
- > help ( " Buttons activate when they are pressed (by clicking), not when they are released. " ) ;
2020-11-06 14:40:59 +00:00
// colors
2023-08-15 18:28:36 +00:00
param_f ( crosshair_size , " size:crosshair " )
- > set_extra ( draw_crosshair ) ;
param_color ( crosshair_color , " color:crosshair " , true , crosshair_color )
- > set_extra ( draw_crosshair ) ;
2020-11-06 14:40:59 +00:00
2023-08-06 20:16:29 +00:00
param_b ( mapeditor : : drawplayer , " drawplayer " ) ;
2023-08-06 20:07:08 +00:00
param_color ( backcolor , " color:background " , false ) ;
param_color ( forecolor , " color:foreground " , false ) ;
param_color ( bordcolor , " color:borders " , false ) ;
param_color ( ringcolor , " color:ring " , true ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . multiplier_ring , parameter_names ( " mring " , " mult:ring " ) , 1 ) ;
2023-08-06 20:07:08 +00:00
param_color ( modelcolor , " color:model " , true ) ;
param_color ( periodcolor , " color:period " , true ) ;
param_color ( stdgridcolor , " color:stdgrid " , true ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . multiplier_grid , parameter_names ( " mgrid " , " mult:grid " ) , 1 ) ;
2023-08-06 20:13:48 +00:00
param_color ( dialog : : dialogcolor , " color:dialog " , false ) ;
2024-05-05 18:15:53 +00:00
for ( auto p : ccolor : : all )
2024-05-26 19:15:26 +00:00
param_colortable ( p - > ctab , s0 + " canvas: " + p - > name ) ;
param_colortable ( distcolors , " distance " ) ;
param_colortable ( minecolors , " mines " ) ;
2020-11-06 14:40:59 +00:00
# if CAP_COMPLEX2
2024-05-26 19:15:26 +00:00
param_colortable ( brownian : : colors , " color:brown " ) ;
2020-11-06 14:40:59 +00:00
# endif
for ( int i = 0 ; i < motypes ; i + + )
2024-05-26 18:22:29 +00:00
param_color ( minf [ i ] . color , " color:monster: " + its ( i ) , false ) ;
2020-11-06 14:40:59 +00:00
for ( int i = 0 ; i < ittypes ; i + + )
2024-05-26 18:22:29 +00:00
param_color ( iinf [ i ] . color , " color:item: " + its ( i ) , false ) ;
2020-11-06 14:40:59 +00:00
for ( int i = 0 ; i < landtypes ; i + + )
2024-05-26 18:22:29 +00:00
param_color ( floorcolors [ i ] , " color:land: " + its ( i ) , false ) ;
2020-11-06 14:40:59 +00:00
for ( int i = 0 ; i < walltypes ; i + + )
2024-05-26 18:22:29 +00:00
param_color ( winf [ i ] . color , " color:wall: " + its ( i ) , false ) ;
2020-11-06 14:40:59 +00:00
// modes
2024-05-26 18:22:29 +00:00
param_b ( shmup : : on , " mode-shmup " , false ) - > be_non_editable ( ) ;
2024-05-27 08:51:11 +00:00
param_b ( hardcore , " mode-hardcore " , false ) - > set_reaction ( [ ] { hardcore = ! hardcore ; switchHardcore_quiet ( ) ; } ) ;
2024-05-26 18:22:29 +00:00
param_enum ( land_structure , " mode-chaos " , lsNiceWalls ) - > be_non_editable ( ) ;
2020-11-06 14:40:59 +00:00
# if CAP_INV
2024-05-27 13:53:59 +00:00
param_b ( inv : : on , " mode-Orb Strategy " ) - > be_non_editable ( ) ;
2020-11-06 14:40:59 +00:00
# endif
2024-05-27 13:53:59 +00:00
param_b ( peace : : on , " mode-peace " ) - > be_non_editable ( ) ;
param_b ( peace : : otherpuzzles , " mode-peace-submode " ) - > be_non_editable ( ) ;
2024-05-26 18:22:29 +00:00
param_enum ( specialland , parameter_names ( " specialland " , " land for special modes " ) , specialland ) - > be_non_editable ( ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_b ( viewdists , " expansion mode " ) ;
param_f ( backbrightness , parameter_names ( " back " , " brightness behind sphere " ) ) ;
2022-10-21 17:22:30 +00:00
param_b ( auto_extend , " expansion_auto_extend " )
- > editable ( " extend automatically " , ' E ' ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_f ( vid . ipd , parameter_names ( " ipd " , " interpupilar-distance " ) , 0.05 ) ;
param_f ( vid . lr_eyewidth , parameter_names ( " lr " , " eyewidth-lr " ) , 0.5 ) ;
param_f ( vid . anaglyph_eyewidth , parameter_names ( " anaglyph " , " eyewidth-anaglyph " ) , 0.1 ) ;
param_f ( vid . fov , parameter_names ( " fov " , " field-of-vision " ) , 90 ) ;
param_i ( vid . desaturate , " desaturate " , 0 ) ;
2021-02-01 00:35:34 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( vid . stereo_mode , " stereo-mode " , vid . stereo_mode )
2023-11-30 11:32:24 +00:00
- > editable ( {
{ " OFF " , " linear perspective " } , { " anaglyph " , " for red-cyan glasses " } , { " side-by-side " , " for mobile VR " } ,
{ " ODS " , " for rendering 360° VR videos (implemented only in raycaster and some other parts) " } ,
{ " Panini " , " Projection believed to be used by Italian painters. Allows very high FOV angles while rendering more straight lines as straight than the stereographic projection. " } ,
{ " stereographic " , " Stereographic projection allows very high FOV angles. " } ,
2024-01-07 08:13:31 +00:00
{ " equirectangular " , " for rendering 360° videos (implemented only in raycaster) " } ,
{ " cylindrical " , " full vertical (not implemented in raycaster) " }
2024-01-07 08:09:18 +00:00
} , " stereo/high-FOV mode " , ' m ' )
- > set_reaction ( reset_all_shaders ) ;
2020-11-06 14:40:59 +00:00
2021-04-23 18:12:08 +00:00
param_f ( vid . plevel_factor , " plevel_factor " , 0.7 ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 02:11:15 +00:00
param_b ( nohud , " no-hud " , false ) ;
2022-08-06 23:40:00 +00:00
param_b ( nomap , " nomap " , false ) ;
2021-02-01 02:11:15 +00:00
param_b ( nofps , " no-fps " , false ) ;
2020-11-06 14:40:59 +00:00
# if CAP_IRR
2024-05-26 18:22:29 +00:00
param_f ( irr : : density , " irregular-density " , 2 ) ;
param_i ( irr : : cellcount , " irregular-cellcount " , 150 ) ;
param_f ( irr : : quality , " irregular-quality " , .2 ) ;
param_i ( irr : : place_attempts , " irregular-place " , 10 ) ;
param_i ( irr : : rearrange_max_attempts , " irregular-rearrange-max " , 50 ) ;
param_i ( irr : : rearrange_less , " irregular-rearrangeless " , 10 ) ;
2020-11-06 14:40:59 +00:00
# endif
2021-02-01 02:11:15 +00:00
param_i ( vid . linequality , " line quality " , 0 ) ;
2020-11-06 14:40:59 +00:00
# if CAP_FILES && CAP_SHOT && CAP_ANIMATIONS
2024-05-28 13:08:30 +00:00
param_str ( anims : : animfile , " animation file format " ) - > set_file_editor ( " .png " ) ;
2020-11-06 14:40:59 +00:00
# endif
2020-11-08 11:43:07 +00:00
# if CAP_RUG
2024-05-26 18:22:29 +00:00
param_f ( rug : : move_on_touch , " rug move on touch " ) ;
2020-11-06 14:40:59 +00:00
# endif
# if CAP_CRYSTAL
2024-05-26 18:22:29 +00:00
param_f ( crystal : : compass_probability , parameter_names ( " cprob " , " compass-probability " ) ) ;
param_b ( crystal : : view_coordinates , " crystal-coordinates " ) ;
2020-11-06 14:40:59 +00:00
# endif
# if CAP_TEXTURE
2021-02-01 02:11:15 +00:00
param_b ( texture : : texture_aura , " texture-aura " , false ) ;
2020-11-06 14:40:59 +00:00
# endif
2021-02-04 20:58:53 +00:00
param_f ( vid . smart_range_detail , " smart-range-detail " , 8 )
2023-08-15 17:53:29 +00:00
- > editable ( 1 , 50 , 1 , " minimum visible cell in pixels " , " " , ' d ' )
- > set_extra ( [ ] { add_cells_drawn ( ' C ' ) ; } ) ;
2021-02-04 20:58:53 +00:00
param_f ( vid . smart_range_detail_3 , " smart-range-detail-3 " , 30 )
2023-08-15 17:53:29 +00:00
- > editable ( 1 , 50 , 1 , " minimum visible cell in pixels " , " " , ' d ' )
- > set_extra ( [ ] { add_cells_drawn ( ' C ' ) ; } ) ;
2021-02-04 20:58:53 +00:00
2021-02-01 02:11:15 +00:00
param_b ( vid . smart_area_based , " smart-area-based " , false ) ;
param_i ( vid . cells_drawn_limit , " limit on cells drawn " , 10000 ) ;
param_i ( vid . cells_generated_limit , " limit on cells generated " , 250 ) ;
2022-05-21 11:08:42 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( diskshape , " disk_shape " , dshTiles )
2022-05-21 15:09:34 +00:00
- > editable ( { { " distance in tiles " , " " } , { " distance in vertices " , " " } , { " geometric distance " , " " }
} , " disk shape " , ' S ' )
- > set_reaction ( [ ] { if ( game_active ) { stop_game ( ) ; start_game ( ) ; } } ) ;
2022-05-21 11:08:42 +00:00
param_i ( req_disksize , " disk_size " )
- > editable ( 10 , 100000 , 10 , " disk size " , " Play on a disk. Enables the special game rules for small bounded spaces (especially relevant for e.g. Minefield and Halloween). The number given is the number of tiles to use; it is not used exactly, actually the smallest disk above this size is used. Set to 0 to disable. " , ' d ' )
- > set_sets ( [ ] { dialog : : bound_low ( 0 ) ; } )
2022-05-21 15:09:34 +00:00
- > set_reaction ( [ ] { if ( game_active ) { stop_game ( ) ; start_game ( ) ; } } )
- > set_extra ( [ ] {
add_edit ( diskshape ) ;
} ) ;
2020-11-06 14:40:59 +00:00
# if CAP_SOLV
2024-05-26 18:22:29 +00:00
param_f ( sn : : solrange_xy , " solrange-xy " ) ;
param_f ( sn : : solrange_z , " solrange-z " ) ;
2020-11-06 14:40:59 +00:00
# endif
2022-05-28 16:43:43 +00:00
param_i ( slr : : shader_iterations , " slr-steps " ) ;
param_f ( slr : : range_xy , " slr-range-xy " ) ;
2022-10-15 20:57:37 +00:00
param_f ( slr : : range_z , " slr-range-z " ) ;
2021-08-05 10:21:39 +00:00
param_f ( arcm : : euclidean_edge_length , " arcm-euclid-length " ) ;
2020-11-06 14:40:59 +00:00
# if CAP_ARCM
2024-05-28 13:08:30 +00:00
auto arcms = param_str ( arcm : : current . symbol , " arcm-symbol " , " 4^5 " ) ;
arcms - > editor = [ ] { pushScreen ( arcm : : show ) ; arcm : : init_symbol_edit ( ) ; } ;
arcms - > pre_reaction = non_editable_pre ;
2024-05-28 18:20:28 +00:00
arcms - > reaction = [ ] { if ( ! arcm : : load_symbol ( arcm : : current . symbol , false ) ) throw hr_parse_exception ( " wrong Archimedean symbol " ) ; non_editable_post ( ) ; } ;
2020-11-06 14:40:59 +00:00
# endif
2024-05-26 18:22:29 +00:00
param_enum ( hybrid : : underlying , " product_underlying " , hybrid : : underlying ) - > be_non_editable ( ) ;
2020-11-06 14:40:59 +00:00
for ( int i = 0 ; i < isize ( ginf ) ; i + + ) {
if ( ginf [ i ] . flags & qELLIPTIC )
sightranges [ i ] = M_PI ;
else if ( ginf [ i ] . cclass = = gcSphere )
2022-11-12 21:38:45 +00:00
sightranges [ i ] = TAU ;
2020-11-06 14:40:59 +00:00
else if ( ginf [ i ] . cclass = = gcEuclid )
sightranges [ i ] = 10 ;
else if ( ginf [ i ] . cclass = = gcSL2 )
sightranges [ i ] = 4.5 ;
else if ( ginf [ i ] . cclass = = gcHyperbolic & & ginf [ i ] . g . gameplay_dimension = = 2 )
sightranges [ i ] = 4.5 ;
else
sightranges [ i ] = 5 ;
sightranges [ gArchimedean ] = 10 ;
2024-05-26 18:22:29 +00:00
if ( i < gBinary3 ) param_f ( sightranges [ i ] , " sight-g " + its ( i ) ) ;
2020-11-06 14:40:59 +00:00
}
ld bonus = 0 ;
ld emul = 1 ;
2021-02-01 12:42:12 +00:00
param_b ( dialog : : onscreen_keyboard , " onscreen_keyboard " )
- > editable ( " onscreen keyboard " , ' k ' ) ;
2021-03-31 12:35:22 +00:00
param_b ( context_fog , " coolfog " ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_f ( sightranges [ gBinary3 ] , " sight-binary3 " , 3.1 + bonus ) ;
param_f ( sightranges [ gCubeTiling ] , " sight-cubes " , 10 ) ;
param_f ( sightranges [ gCell120 ] , " sight-120cell " , TAU ) ;
param_f ( sightranges [ gECell120 ] , " sight-120cell-elliptic " , M_PI ) ;
param_f ( sightranges [ gRhombic3 ] , " sight-rhombic " , 10.5 * emul ) ;
param_f ( sightranges [ gBitrunc3 ] , " sight-bitrunc " , 12 * emul ) ;
param_f ( sightranges [ gSpace534 ] , " sight-534 " , 4 + bonus ) ;
param_f ( sightranges [ gSpace435 ] , " sight-435 " , 3.8 + bonus ) ;
param_f ( sightranges [ gCell5 ] , " sight-5cell " , TAU ) ;
param_f ( sightranges [ gCell8 ] , " sight-8cell " , TAU ) ;
param_f ( sightranges [ gECell8 ] , " sight-8cell-elliptic " , M_PI ) ;
param_f ( sightranges [ gCell16 ] , " sight-16cell " , TAU ) ;
param_f ( sightranges [ gECell16 ] , " sight-16cell-elliptic " , M_PI ) ;
param_f ( sightranges [ gCell24 ] , " sight-24cell " , TAU ) ;
param_f ( sightranges [ gECell24 ] , " sight-24cell-elliptic " , M_PI ) ;
param_f ( sightranges [ gCell600 ] , " sight-600cell " , TAU ) ;
param_f ( sightranges [ gECell600 ] , " sight-600cell-elliptic " , M_PI ) ;
param_f ( sightranges [ gHoroTris ] , " sight-horotris " , 2.9 + bonus ) ;
param_f ( sightranges [ gHoroRec ] , " sight-hororec " , 2.2 + bonus ) ;
param_f ( sightranges [ gHoroHex ] , " sight-horohex " , 2.75 + bonus ) ;
param_f ( sightranges [ gKiteDart3 ] , " sight-kd3 " , 2.25 + bonus ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_f ( sightranges [ gField435 ] , " sight-field435 " , 4 + bonus ) ;
param_f ( sightranges [ gField534 ] , " sight-field534 " , 3.8 + bonus ) ;
param_f ( sightranges [ gSol ] , " sight-sol " ) ;
param_f ( sightranges [ gNil ] , " sight-nil " , 6.5 + bonus ) ;
param_f ( sightranges [ gNIH ] , " sight-nih " ) ;
param_f ( sightranges [ gSolN ] , " sight-solnih " ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_f ( sightranges [ gCrystal344 ] , " sight-crystal344 " , 2.5 ) ; /* assume raycasting */
param_f ( sightranges [ gSpace344 ] , " sight-344 " , 4.5 ) ;
param_f ( sightranges [ gSpace336 ] , " sight-336 " , 4 ) ;
2020-11-06 14:40:59 +00:00
2024-05-27 13:53:59 +00:00
param_b ( vid . sloppy_3d , " sloppy3d " , true )
- > editable ( " sloppy range checking " , ' s ' )
- > help ( " Do not draw if their distance is greater than the sight range (although some points might be closer). This is faster. " ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 02:11:15 +00:00
param_i ( vid . texture_step , " wall-quality " , 4 ) ;
2020-11-06 14:40:59 +00:00
2024-05-27 13:53:59 +00:00
param_b ( smooth_scrolling , " smooth-scrolling " , false )
- > editable ( " smooth scrolling " , ' c ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( mouseaim_sensitivity , " mouseaim_sensitivity " , 0.01 ) ;
2020-11-06 14:40:59 +00:00
2024-05-27 13:53:59 +00:00
param_b ( vid . consider_shader_projection , " shader-projection " , true )
- > editable ( " use GPU to compute projections " , ' G ' )
- > help ( " Computing projections using a GPU (vertex shader) is faster, but sometimes, some projections or their minor details are not available. " ) ;
2023-05-15 00:40:05 +00:00
param_b ( semidirect_rendering , " semidirect_rendering " , false )
- > editable ( " semidirect_rendering (perspective on GPU) " , ' k ' ) ;
2023-05-15 00:39:46 +00:00
param_i ( forced_center_down , " forced_center_down " )
- > editable ( 0 , 100 , 10 , " forced center down " , " make the center not the actual screen center " , ' d ' ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 02:11:15 +00:00
param_b ( tortoise : : shading_enabled , " tortoise_shading " , true ) ;
2020-11-06 14:40:59 +00:00
2023-04-11 14:46:18 +00:00
param_f ( bounded_mine_percentage , " bounded_mine_freq " )
- > editable ( 0 , 1 , 0.01 , " fraction of mine in bounded minefield " , " " , ' % ' )
- > set_reaction ( [ ] {
if ( game_active ) { stop_game ( ) ; start_game ( ) ; }
} ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( nisot : : geodesic_movement , " solv_geodesic_movement " , true )
2022-12-25 11:14:36 +00:00
- > editable ( { { " Lie group " , " light, camera, and objects move in lines of constant direction, in the Lie group sense " } , { " geodesics " , " light, camera, and objects always take the shortest path " } } , " straight lines " , ' G ' )
- > set_reaction ( [ ] {
if ( pmodel = = mdLiePerspective & & nisot : : geodesic_movement ) pmodel = hyperbolic ? mdPerspective : mdGeodesic ;
if ( among ( pmodel , mdGeodesic , mdPerspective ) & & ! nisot : : geodesic_movement ) pmodel = mdLiePerspective ;
} ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_i ( s2xe : : qrings , " s2xe-rings " ) ;
2024-06-16 16:12:52 +00:00
param_f ( hybrid : : underlying_scale , " rots-underlying-scale " ) ;
param_b ( hybrid : : underlying_as_pc , " underlying_as_pc " )
2024-06-09 23:30:25 +00:00
- > editable ( " draw PC on the underlying map " , ' P ' ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 02:11:15 +00:00
param_b ( vid . bubbles_special , " bubbles-special " , 1 ) ;
param_b ( vid . bubbles_threshold , " bubbles-threshold " , 1 ) ;
param_b ( vid . bubbles_all , " bubbles-all " , 0 ) ;
2020-11-06 14:40:59 +00:00
# if CAP_SHMUP
multi : : initConfig ( ) ;
# endif
2024-05-26 18:22:29 +00:00
param_i ( asonov : : period_xy , " asonov:period_xy " ) ;
param_i ( asonov : : period_z , " asonov:period_z " ) ;
param_i ( nilv : : nilperiod [ 0 ] , " nilperiod_x " ) ;
param_i ( nilv : : nilperiod [ 1 ] , " nilperiod_y " ) ;
param_i ( nilv : : nilperiod [ 2 ] , " nilperiod_z " ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( neon_mode , " neon_mode " , neon_mode )
2021-02-01 00:35:34 +00:00
- > editable (
{ { " OFF " , " " } , { " standard " , " " } , { " no boundary mode " , " " } , { " neon mode II " , " " } , { " illustration mode " , " " } } ,
" neon mode " , ' M '
) ;
2024-05-26 18:22:29 +00:00
param_enum ( bow : : weapon , " pc_class " , bow : : weapon )
2023-10-26 10:32:36 +00:00
- > editable ( { { " blade " , " Standard Rogue weapon. Bump into a monster to hit. Most monsters attack you the same way. " } ,
{ " crossbow " , " Hits all monsters in a straight line, but slow to reload. Press 'f' or click the crossbow icon to target. " } } ,
" weapon selection " , ' w ' )
2023-10-29 10:00:19 +00:00
- > set_need_confirm ( )
2023-10-28 06:22:31 +00:00
- > set_value_to = [ ] ( bow : : eWeapon wpn ) { bool b = game_active ; if ( wpn ! = bow : : weapon ) stop_game ( ) ; bow : : weapon = wpn ;
peace : : on = false ; if ( dual : : state ) dual : : disable ( ) ; if ( multi : : players > 1 & & ! shmup : : on ) multi : : players = 1 ;
if ( b ) start_game ( ) ;
} ;
2024-05-26 18:22:29 +00:00
param_enum ( bow : : style , " bow_style " , bow : : style )
2023-10-26 10:32:36 +00:00
- > editable ( { { " bull line " , " Can go in either direction on odd shapes. 3 turns to reload. " } ,
2023-10-29 10:02:58 +00:00
{ " geodesic " , " Graph geodesic: any sequence of tiles is OK as long as there are no shortcuts. 4 turns to reload. " } ,
{ " geometric " , " Approximations of geometric straight lines. " } } ,
2023-10-26 10:32:36 +00:00
" crossbow straight line style " , ' l ' )
2023-10-29 10:00:19 +00:00
- > set_need_confirm ( )
2023-10-26 10:32:36 +00:00
- > set_value_to = [ ] ( bow : : eCrossbowStyle s ) { bool b = game_active ; if ( s ! = bow : : style ) stop_game ( ) ; bow : : style = s ; if ( b ) start_game ( ) ; } ;
param_b ( bow : : bump_to_shoot , " bump_to_shoot " , true ) - > editable ( " bump to shoot " , ' b ' ) ;
2024-05-26 18:22:29 +00:00
param_enum ( bow : : mouse_fire_mode , " mouse_fire_mode " , bow : : mfmPriority )
2023-12-02 10:30:51 +00:00
- > editable ( { { " explicit " , " You need to click crossbow or be close to fire. " } ,
{ " priority " , " Click on a faraway monster to fire if possible, or move if not. " } ,
{ " always " , " Clicking on a faraway monster always means an attempt to fire. " } } ,
" mouse auto-fire mode " , ' m ' ) ;
2023-10-26 10:32:36 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( vid . msgleft , " message_style " , 2 )
2023-10-26 10:32:36 +00:00
- > editable ( { { " centered " , " " } , { " left-aligned " , " " } , { " line-broken " , " " } } , " message style " , ' a ' ) ;
2024-05-26 18:22:29 +00:00
param_enum ( neon_nofill , " neon_nofill " , neon_nofill ) ;
2021-02-01 02:11:15 +00:00
param_b ( noshadow , " noshadow " ) ;
param_b ( bright , " bright " ) ;
param_b ( cblind , " cblind " ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_i ( berger_limit , " berger_limit " ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_enum ( centering , " centering " , centering ) ;
2020-11-06 14:40:59 +00:00
2024-05-26 18:22:29 +00:00
param_f ( camera_speed , parameter_names ( " camspd " , " camera-speed " ) , 1 ) ;
param_f ( camera_rot_speed , parameter_names ( " camrot " , " camera-rot-speed " ) , 1 ) ;
2021-11-30 19:56:36 +00:00
param_f ( third_person_rotation , " third_person_rotation " , 0 ) ;
2020-11-06 14:40:59 +00:00
2023-11-30 11:32:24 +00:00
param_f ( vid . stereo_param , " stereo_param " , 0.9 )
- > editable ( - 1 , 1 , 0.9 , " stereographic/Panini parameter " , " 1 for full stereographic/Panini projection. Lower values reduce the effect. \n \n "
" HyperRogue uses "
" a quick implementation, so parameter values too close to 1 may "
" be buggy (outside of raycasting); try e.g. 0.9 instead. " , ' d ' )
2023-03-16 13:43:29 +00:00
- > set_reaction ( reset_all_shaders ) ;
2020-11-06 14:40:59 +00:00
callhooks ( hooks_configfile ) ;
2021-01-31 17:34:54 +00:00
# if CAP_SHOT
2021-10-07 10:39:49 +00:00
param_f ( levellines , " levellines " , 0 ) ;
2021-01-31 17:34:54 +00:00
# endif
2020-11-06 14:40:59 +00:00
# if CAP_CONFIG
2024-05-26 18:22:29 +00:00
for ( auto s : params ) s . second - > reset ( ) ;
2020-11-06 14:40:59 +00:00
# endif
2021-02-01 02:11:15 +00:00
2024-05-26 18:22:29 +00:00
param_custom_int ( sightrange_bonus , " sightrange_bonus " , menuitem_sightrange_bonus , ' r ' ) ;
param_custom_int ( vid . use_smart_range , " sightrange_style " , menuitem_sightrange_style , ' s ' ) ;
2021-02-01 14:10:03 +00:00
2024-05-26 18:22:29 +00:00
param_custom_int ( gp : : param . first , " Goldberg x " , menuitem_change_variation , 0 ) ;
param_custom_int ( gp : : param . second , " Goldberg y " , menuitem_change_variation , 0 ) ;
param_custom_int ( variation , parameter_names ( " variation " , " mode-variation " ) , menuitem_change_variation , ' v ' )
2021-02-01 14:10:03 +00:00
- > help_text = " variation|dual|bitruncated " ;
2024-05-26 18:22:29 +00:00
param_custom_int ( geometry , parameter_names ( " geometry " , " mode-geometry " ) , menuitem_change_geometry , 0 )
2021-02-01 14:10:03 +00:00
- > help_text = " hyperbolic|spherical|Euclidean " ;
2021-07-29 10:05:07 +00:00
param_i ( stamplen , " stamplen " ) ;
2022-04-21 19:26:31 +00:00
param_f ( anims : : period , " animperiod " ) ;
2024-03-14 18:27:08 +00:00
2024-05-26 18:22:29 +00:00
param_b ( use_custom_land_list , " customland_use " ) - > be_non_editable ( ) ;
2024-03-14 18:27:08 +00:00
for ( int i = 0 ; i < landtypes ; i + + ) {
custom_land_list [ i ] = true ;
custom_land_treasure [ i ] = 100 ;
custom_land_difficulty [ i ] = 100 ;
custom_land_wandering [ i ] = 100 ;
2024-05-26 18:22:29 +00:00
param_b ( custom_land_list [ i ] , " customland " + its ( i ) + " i " , true ) - > be_non_editable ( ) ;
param_i ( custom_land_treasure [ i ] , " customland " + its ( i ) + " t " , 100 ) - > be_non_editable ( ) ;
param_i ( custom_land_difficulty [ i ] , " customland " + its ( i ) + " d " , 100 ) - > be_non_editable ( ) ;
param_i ( custom_land_wandering [ i ] , " customland " + its ( i ) + " w " , 100 ) - > be_non_editable ( ) ;
2024-03-14 18:27:08 +00:00
}
2020-11-06 14:40:59 +00:00
}
EX bool inSpecialMode ( ) {
2021-04-11 20:15:40 +00:00
return ! ls : : nice_walls ( ) | | ineligible_starting_land | | ! BITRUNCATED | | peace : : on | |
2020-11-06 14:40:59 +00:00
# if CAP_TOUR
tour : : on | |
# endif
yendor : : on | | tactic : : on | | randomPatternsMode | |
geometry ! = gNormal | | pmodel ! = mdDisk | | pconf . alpha ! = 1 | | pconf . scale ! = 1 | |
rug : : rugged | | vid . monmode ! = DEFAULT_MONMODE | |
vid . wallmode ! = DEFAULT_WALLMODE ;
}
EX bool have_current_settings ( ) {
int modecount = 0 ;
if ( inv : : on ) modecount + + ;
if ( shmup : : on ) modecount + = 10 ;
# if CAP_TOUR
if ( tour : : on ) modecount + = 10 ;
# endif
2021-04-11 20:15:40 +00:00
if ( ! ls : : nice_walls ( ) ) modecount + = 10 ;
2020-11-06 14:40:59 +00:00
if ( ! BITRUNCATED ) modecount + = 10 ;
if ( peace : : on ) modecount + = 10 ;
if ( yendor : : on ) modecount + = 10 ;
if ( tactic : : on ) modecount + = 10 ;
if ( randomPatternsMode ) modecount + = 10 ;
if ( geometry ! = gNormal ) modecount + = 10 ;
if ( modecount > 1 )
return true ;
return false ;
}
EX bool have_current_graph_settings ( ) {
if ( pconf . xposition | | pconf . yposition | | pconf . alpha ! = 1 | | pconf . scale ! = 1 )
return true ;
if ( pmodel ! = mdDisk | | vid . monmode ! = DEFAULT_MONMODE | | vid . wallmode ! = DEFAULT_WALLMODE )
return true ;
if ( firstland ! = laIce | | multi : : players ! = 1 | | rug : : rugged )
return true ;
return false ;
}
EX void reset_graph_settings ( ) {
pmodel = mdDisk ; pconf . alpha = 1 ; pconf . scale = 1 ;
pconf . xposition = pconf . yposition = 0 ;
# if CAP_RUG
if ( rug : : rugged ) rug : : close ( ) ;
# endif
vid . monmode = DEFAULT_MONMODE ;
vid . wallmode = DEFAULT_WALLMODE ;
}
EX void resetModes ( char leave IS ( ' c ' ) ) {
while ( game_active | | gamestack : : pushed ( ) ) {
if ( game_active ) stop_game ( ) ;
if ( gamestack : : pushed ( ) ) gamestack : : pop ( ) ;
}
if ( shmup : : on ! = ( leave = = rg : : shmup ) ) stop_game_and_switch_mode ( rg : : shmup ) ;
if ( inv : : on ! = ( leave = = rg : : inv ) ) stop_game_and_switch_mode ( rg : : inv ) ;
2021-04-11 20:15:40 +00:00
2021-05-01 10:35:26 +00:00
/* we do this twice to make sure that stop_game_and_switch_mode switches to the correct land_structure */
for ( int i = 0 ; i < 2 ; i + + ) {
if ( leave = = rg : : chaos & & ! ls : : std_chaos ( ) ) stop_game_and_switch_mode ( rg : : chaos ) ;
if ( leave ! = rg : : chaos & & ! ls : : nice_walls ( ) ) stop_game_and_switch_mode ( rg : : chaos ) ;
}
2020-11-06 14:40:59 +00:00
2021-03-06 10:59:32 +00:00
if ( ( ! ! dual : : state ) ! = ( leave = = rg : : dualmode ) ) stop_game_and_switch_mode ( rg : : dualmode ) ;
2020-11-06 14:40:59 +00:00
if ( peace : : on ! = ( leave = = rg : : peace ) ) stop_game_and_switch_mode ( rg : : peace ) ;
# if CAP_TOUR
if ( tour : : on ! = ( leave = = rg : : tour ) ) stop_game_and_switch_mode ( rg : : tour ) ;
# endif
if ( yendor : : on ! = ( leave = = rg : : yendor ) ) stop_game_and_switch_mode ( rg : : yendor ) ;
if ( tactic : : on ! = ( leave = = rg : : tactic ) ) stop_game_and_switch_mode ( rg : : tactic ) ;
if ( randomPatternsMode ! = ( leave = = rg : : randpattern ) ) stop_game_and_switch_mode ( rg : : randpattern ) ;
if ( multi : : players ! = 1 ) {
stop_game_and_switch_mode ( ) ; multi : : players = 1 ;
}
if ( firstland ! = laIce | | specialland ! = laIce ) {
stop_game ( ) ;
firstland = laIce ; specialland = laIce ; stop_game_and_switch_mode ( ) ;
}
set_geometry ( gNormal ) ;
set_variation ( leave = = rg : : heptagons ? eVariation : : pure : eVariation : : bitruncated ) ;
start_game ( ) ;
}
# if CAP_CONFIG
EX void resetConfig ( ) {
dynamicval < int > rx ( vid . xres , 0 ) ;
dynamicval < int > ry ( vid . yres , 0 ) ;
dynamicval < int > rf ( vid . fsize , 0 ) ;
dynamicval < bool > rfs ( vid . full , false ) ;
2024-05-26 18:22:29 +00:00
for ( auto s : params )
if ( s . second - > legacy_config_name . substr ( 0 , 5 ) ! = " mode- " )
s . second - > reset ( ) ;
2020-11-06 14:40:59 +00:00
}
# endif
# if CAP_CONFIG
EX void saveConfig ( ) {
DEBB ( DF_INIT , ( " save config \n " ) ) ;
FILE * f = fopen ( conffile , " wt " ) ;
if ( ! f ) {
addMessage ( s0 + " Could not open the config file: " + conffile ) ;
return ;
}
{
int pt_depth = 0 , pt_camera = 0 , pt_alpha = 0 ;
if ( vid . tc_depth > vid . tc_camera ) pt_depth + + ;
if ( vid . tc_depth < vid . tc_camera ) pt_camera + + ;
if ( vid . tc_depth > vid . tc_alpha ) pt_depth + + ;
if ( vid . tc_depth < vid . tc_alpha ) pt_alpha + + ;
if ( vid . tc_alpha > vid . tc_camera ) pt_alpha + + ;
if ( vid . tc_alpha < vid . tc_camera ) pt_camera + + ;
vid . tc_alpha = pt_alpha ;
vid . tc_camera = pt_camera ;
vid . tc_depth = pt_depth ;
}
2024-05-26 18:22:29 +00:00
for ( auto s : params ) if ( s . second - > dosave ( ) )
fprintf ( f , " %s=%s \n " , s . second - > name . c_str ( ) , s . second - > save ( ) . c_str ( ) ) ;
2020-11-06 14:40:59 +00:00
fclose ( f ) ;
# if !ISMOBILE
addMessage ( s0 + " Configuration saved to: " + conffile ) ;
# else
addMessage ( s0 + " Configuration saved " ) ;
# endif
}
void readf ( FILE * f , ld & x ) {
double fl = x ;
hr : : ignore ( fscanf ( f , " %lf " , & fl ) ) ;
x = fl ;
}
2024-05-26 18:22:29 +00:00
map < string , shared_ptr < parameter > > allconfigs ;
2020-11-06 14:40:59 +00:00
EX void parseline ( const string & str ) {
if ( str [ 0 ] = = ' # ' ) return ;
for ( int i = 0 ; i < isize ( str ) ; i + + ) if ( str [ i ] = = ' = ' ) {
string cname = str . substr ( 0 , i ) ;
if ( ! allconfigs . count ( cname ) ) {
printf ( " Warning: unknown config variable: %s \n " , str . c_str ( ) ) ;
return ;
}
auto sav = allconfigs [ cname ] ;
sav - > load ( str . substr ( i + 1 ) ) ;
return ;
}
printf ( " Warning: config line without equality sign: %s \n " , str . c_str ( ) ) ;
}
EX void loadNewConfig ( FILE * f ) {
2024-05-29 11:51:09 +00:00
dynamicval < bool > ds ( delayed_start , true ) ;
2024-05-26 18:22:29 +00:00
for ( auto & c : params ) allconfigs [ c . second - > name ] = allconfigs [ c . second - > legacy_config_name ] = c . second ;
2020-11-06 14:40:59 +00:00
string rd ;
while ( true ) {
int c = fgetc ( f ) ;
if ( c = = - 1 ) break ;
if ( c = = 10 | | c = = 13 ) {
if ( rd ! = " " ) parseline ( rd ) ;
rd = " " ;
}
else rd + = c ;
}
allconfigs . clear ( ) ;
}
EX void loadConfig ( ) {
DEBB ( DF_INIT , ( " load config " ) ) ;
2021-02-04 14:01:42 +00:00
vid . xres = 9999 ; vid . yres = 9999 ; vid . framelimit = 999 ;
2020-11-06 14:40:59 +00:00
FILE * f = fopen ( conffile , " rt " ) ;
if ( f ) {
int err ;
int fs ;
err = fscanf ( f , " %d%d%d%d " , & vid . xres , & vid . yres , & fs , & vid . fsize ) ;
if ( err ! = 4 )
loadNewConfig ( f ) ;
else {
vid . full = fs ;
# if CAP_LEGACY
loadOldConfig ( f ) ;
# endif
}
fclose ( f ) ;
DEBB ( DF_INIT , ( " Loaded configuration: %s \n " , conffile ) ) ;
}
geom3 : : apply_always3 ( ) ;
polygonal : : solve ( ) ;
check_cgi ( ) ;
2023-04-27 20:47:32 +00:00
cgi . require_basics ( ) ;
2020-11-06 14:40:59 +00:00
}
# endif
EX void add_cells_drawn ( char c IS ( ' C ' ) ) {
dialog : : addSelItem ( XLAT ( " cells drawn " ) , ( noclipped ? its ( cells_drawn ) + " ( " + its ( noclipped ) + " ) " : its ( cells_drawn ) ) + " / " + its ( vid . cells_drawn_limit ) , c ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( vid . cells_drawn_limit , 100 , 1000000 , log ( 10 ) , 10000 , XLAT ( " limit on cells drawn " ) ,
XLAT ( " This limit exists to protect the engine from freezing when too many cells would be drawn according to the current options. " )
) ;
dialog : : scaleLog ( ) ;
} ) ;
if ( WDIM = = 3 | | vid . use_smart_range = = 2 ) {
dialog : : addSelItem ( XLAT ( " limit generated cells per frame " ) , its ( vid . cells_generated_limit ) , ' L ' ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( vid . cells_generated_limit , 1 , 1000 , log ( 10 ) , 25 , XLAT ( " limit generated cells per frame " ) ,
XLAT ( " In the 3D mode, lowering this value may help if the game lags while exploring new areas. " )
) ;
} ) ;
}
}
string solhelp ( ) {
# if CAP_SOLV
return XLAT (
" Solv (aka Sol) is a 3D space where directions work in different ways. It is described by the following metric: \n "
" ds² = (eᶻdx)² + (e⁻ᶻdy)² + dz² \n \n "
" You are currently displaying Solv in the perspective projection based on native geodesics. You can control how "
" the fog effects depends on the geodesic distance, and how far object in X/Y/Z coordinates are rendered. "
) ;
# else
return " " ;
# endif
}
2021-02-01 02:11:15 +00:00
EX void menuitem_sightrange_bonus ( char c ) {
dialog : : addSelItem ( XLAT ( " sight range bonus " ) , its ( sightrange_bonus ) , c ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( sightrange_bonus , - 5 , allowIncreasedSight ( ) ? 3 : 0 , 1 , 0 , XLAT ( " sight range " ) ,
XLAT ( " Roughly 42% cells are on the edge of your sight range. Reducing "
" the sight range makes HyperRogue work faster, but also makes "
" the game effectively harder. " ) ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . reaction = doOvergenerate ;
2021-02-01 02:11:15 +00:00
dialog : : bound_low ( 1 - getDistLimit ( ) ) ;
dialog : : bound_up ( allowIncreasedSight ( ) ? euclid ? 99 : gp : : dist_2 ( ) * 5 : 0 ) ;
} ) ;
}
2023-08-15 17:53:29 +00:00
EX void edit_sightrange_3d ( char key , bool fog ) {
2023-12-03 13:29:02 +00:00
dialog : : addSelItem ( fog ? XLAT ( " 3D sight range for the fog effect " ) : ( " 3D sight range " ) , fts ( sightranges [ geometry ] ) , key ) ;
2023-08-15 17:53:29 +00:00
dialog : : add_action ( [ ] {
dialog : : editNumber ( sightranges [ geometry ] , 0 , TAU , 0.5 , M_PI , XLAT ( " 3D sight range " ) ,
XLAT (
" Sight range for 3D geometries is specified in the absolute units. This value also affects the fog effect. \n \n "
" In spherical geometries, the sight range of 2π will let you see things behind you as if they were in front of you, "
" and the sight range of π (or more) will let you see things on the antipodal point just as if they were close to you. \n \n "
" In hyperbolic geometries, the number of cells to render depends exponentially on the sight range. More cells to drawn "
" reduces the performance. \n \n "
" Sight range affects the gameplay, and monsters act iff they are visible. Monster generation takes this into account. "
)
) ;
dialog : : get_di ( ) . extra_options = [ ] { add_cells_drawn ( ' C ' ) ; } ;
} ) ;
}
2020-11-06 14:40:59 +00:00
EX void edit_sightrange ( ) {
2022-07-05 12:02:51 +00:00
cmode = sm : : SIDE ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2021-02-01 02:11:15 +00:00
dialog : : init ( " sight range settings " ) ;
2021-02-07 13:47:23 +00:00
add_edit ( vid . use_smart_range ) ;
2023-08-15 18:29:09 +00:00
int wdim = WDIM ;
# if CAP_RUG
USING_NATIVE_GEOMETRY_IN_RUG ;
# endif
2023-08-15 17:53:29 +00:00
if ( vid . use_smart_range ) {
2023-08-15 18:29:09 +00:00
add_edit ( wdim = = 2 ? vid . smart_range_detail : vid . smart_range_detail_3 ) ;
2023-08-15 17:53:29 +00:00
if ( GDIM = = 3 ) edit_sightrange_3d ( ' r ' , true ) ;
}
2020-11-06 14:40:59 +00:00
else {
2023-08-15 18:29:09 +00:00
if ( wdim = = 2 ) {
2021-02-07 13:47:23 +00:00
add_edit ( sightrange_bonus ) ;
2023-08-15 18:29:09 +00:00
if ( GDIM = = 3 ) edit_sightrange_3d ( ' r ' , true ) ;
2020-11-06 14:40:59 +00:00
}
2023-08-15 18:29:09 +00:00
if ( wdim = = 3 ) edit_sightrange_3d ( ' r ' , false ) ;
2021-02-01 02:11:15 +00:00
}
# if CAP_SOLV
2022-10-15 20:58:30 +00:00
if ( models : : is_perspective ( pmodel ) & & sol ) {
2021-02-06 00:52:47 +00:00
dialog : : addSelItem ( XLAT ( " max difference in X/Y coordinates " ) , fts ( sn : : solrange_xy ) , ' x ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] {
dialog : : editNumber ( sn : : solrange_xy , 0.01 , 200 , 0.1 , 50 , XLAT ( " max difference in X/Y coordinates " ) , solhelp ( ) ) , dialog : : scaleLog ( ) ;
2023-08-15 17:53:29 +00:00
dialog : : get_di ( ) . extra_options = [ ] { add_cells_drawn ( ' C ' ) ; } ;
2021-02-01 02:11:15 +00:00
} ) ;
2021-02-06 00:52:47 +00:00
dialog : : addSelItem ( XLAT ( " max difference in Z coordinate " ) , fts ( sn : : solrange_z ) , ' z ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] {
dialog : : editNumber ( sn : : solrange_z , 0 , 20 , 0.1 , 6 , XLAT ( " max difference in Z coordinates " ) , solhelp ( ) ) ;
2023-08-15 17:53:29 +00:00
dialog : : get_di ( ) . extra_options = [ ] { add_cells_drawn ( ' C ' ) ; } ;
2021-02-01 02:11:15 +00:00
} ) ;
}
# endif
2022-10-15 20:58:30 +00:00
if ( models : : is_perspective ( pmodel ) & & sl2 ) {
2021-02-06 00:52:47 +00:00
dialog : : addSelItem ( XLAT ( " max difference in X/Y coordinates " ) , fts ( slr : : range_xy ) , ' x ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] {
dialog : : editNumber ( slr : : range_xy , 0 , 10 , 0.5 , 4 , XLAT ( " max difference in X/Y coordinates " ) , " " ) ;
} ) ;
2022-10-15 20:57:37 +00:00
dialog : : addSelItem ( XLAT ( " max difference in Z coordinate " ) , fts ( slr : : range_z ) , ' x ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( slr : : range_xy , 0 , 10 , 0.5 , 4 , XLAT ( " max difference in Z coordinate " ) , " " ) ;
} ) ;
2022-05-28 16:43:43 +00:00
dialog : : addSelItem ( XLAT ( " shader_iterations " ) , its ( slr : : shader_iterations ) , ' z ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] {
2022-05-28 16:43:43 +00:00
dialog : : editNumber ( slr : : shader_iterations , 0 , 50 , 1 , 10 , " " , " " ) ;
2021-02-01 02:11:15 +00:00
} ) ;
}
2023-08-15 18:29:09 +00:00
if ( vid . use_smart_range & & wdim = = 2 ) {
2021-02-06 00:52:47 +00:00
dialog : : addBoolItem_action ( XLAT ( " area-based range " ) , vid . smart_area_based , ' a ' ) ;
2021-02-01 02:11:15 +00:00
}
2023-08-15 18:29:09 +00:00
if ( vid . use_smart_range = = 0 & & allowChangeRange ( ) & & wdim = = 2 ) {
2021-02-06 00:52:47 +00:00
dialog : : addSelItem ( XLAT ( " generation range bonus " ) , its ( genrange_bonus ) , ' o ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] ( ) { genrange_bonus = sightrange_bonus ; doOvergenerate ( ) ; } ) ;
2021-02-06 00:52:47 +00:00
dialog : : addSelItem ( XLAT ( " game range bonus " ) , its ( gamerange_bonus ) , ' s ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] ( ) { gamerange_bonus = sightrange_bonus ; doOvergenerate ( ) ; } ) ;
}
2023-08-15 18:29:09 +00:00
if ( wdim = = 3 & & ! vid . use_smart_range ) {
2024-05-27 13:53:59 +00:00
add_edit ( vid . sloppy_3d ) ;
2021-02-01 02:11:15 +00:00
}
if ( GDIM = = 3 & & ! vid . use_smart_range ) {
2021-02-06 00:52:47 +00:00
dialog : : addSelItem ( XLAT ( " limit generation " ) , fts ( extra_generation_distance ) , ' e ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] {
dialog : : editNumber ( extra_generation_distance , 0 , 999 , 0.5 , 999 , XLAT ( " limit generation " ) ,
" Cells over this distance will not be generated, but they will be drawn if they are already generated and in the sight range. "
) ;
} ) ;
}
2021-02-06 00:52:47 +00:00
add_cells_drawn ( ' c ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : display ( ) ;
}
EX void menuitem_sightrange_style ( char c IS ( ' c ' ) ) {
dialog : : addSelItem ( XLAT ( " draw range based on " ) ,
2021-05-23 12:33:25 +00:00
vid . use_smart_range = = 0 ? XLAT ( " distance " ) :
vid . use_smart_range = = 1 ? XLAT ( " size (no gen) " ) :
XLAT ( " size " ) ,
2021-02-01 02:11:15 +00:00
c
) ;
dialog : : add_action_push ( [ ] {
dialog : : init ( XLAT ( " draw range based on " ) ) ;
2021-02-01 02:12:39 +00:00
dialog : : addBoolItem ( XLAT ( " draw range based on distance " ) , vid . use_smart_range = = 0 , ' d ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] ( ) { vid . use_smart_range = 0 ; popScreen ( ) ; edit_sightrange ( ) ; } ) ;
if ( WDIM = = 2 & & allowIncreasedSight ( ) ) {
2021-02-01 02:12:39 +00:00
dialog : : addBoolItem ( XLAT ( " draw based on size in the projection (no generation) " ) , vid . use_smart_range = = 1 , ' n ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] ( ) { vid . use_smart_range = 1 ; popScreen ( ) ; edit_sightrange ( ) ; } ) ;
2020-11-06 14:40:59 +00:00
}
2021-02-01 02:11:15 +00:00
if ( allowChangeRange ( ) & & allowIncreasedSight ( ) ) {
2021-02-01 02:12:39 +00:00
dialog : : addBoolItem ( XLAT ( " draw based on size in the projection (generation) " ) , vid . use_smart_range = = 2 , ' g ' ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action ( [ ] ( ) { vid . use_smart_range = 2 ; popScreen ( ) ; edit_sightrange ( ) ; } ) ;
2020-11-06 14:40:59 +00:00
}
2021-02-01 02:11:15 +00:00
if ( ! allowChangeRange ( ) | | ! allowIncreasedSight ( ) ) {
dialog : : addItem ( XLAT ( " enable the cheat mode for additional options " ) , ' X ' ) ;
dialog : : add_action ( enable_cheat ) ;
}
dialog : : display ( ) ;
} ) ;
2020-11-06 14:40:59 +00:00
}
EX void menuitem_sightrange ( char c IS ( ' c ' ) ) {
# if CAP_SOLV
2021-02-01 02:11:15 +00:00
if ( pmodel = = mdGeodesic & & sol )
dialog : : addSelItem ( XLAT ( " sight range settings " ) , fts ( sn : : solrange_xy ) + " x " + fts ( sn : : solrange_z ) , c ) ;
2021-02-07 17:29:49 +00:00
else
2020-11-06 14:40:59 +00:00
# endif
2021-02-07 17:29:49 +00:00
if ( vid . use_smart_range )
2021-02-01 02:11:15 +00:00
dialog : : addSelItem ( XLAT ( " sight range settings " ) , fts ( WDIM = = 3 ? vid . smart_range_detail_3 : vid . smart_range_detail ) + " px " , c ) ;
2021-02-07 13:47:23 +00:00
else if ( WDIM = = 3 )
dialog : : addSelItem ( XLAT ( " sight range settings " ) , fts ( sightranges [ geometry ] ) + " au " , c ) ;
2020-11-06 14:40:59 +00:00
else
2023-08-21 17:02:25 +00:00
dialog : : addSelItem ( XLAT ( " sight range settings " ) , hr : : format ( " %+d " , sightrange_bonus ) , c ) ;
2021-02-01 02:11:15 +00:00
dialog : : add_action_push ( edit_sightrange ) ;
2020-11-06 14:40:59 +00:00
}
2021-02-01 14:10:03 +00:00
EX void sets_sfx_volume ( ) {
2021-02-07 17:29:49 +00:00
# if CAP_AUDIO
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags = sm : : NOSCR ;
2021-02-01 14:10:03 +00:00
# if ISANDROID
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . reaction = [ ] ( ) {
2021-02-01 14:10:03 +00:00
settingsChanged = true ;
} ;
2020-11-06 15:11:19 +00:00
# endif
2021-02-01 14:10:03 +00:00
dialog : : bound_low ( 0 ) ;
dialog : : bound_up ( MIX_MAX_VOLUME ) ;
2021-02-07 17:29:49 +00:00
# endif
2020-11-06 14:40:59 +00:00
}
2021-02-01 14:10:03 +00:00
EX void sets_music_volume ( ) {
2021-02-07 17:29:49 +00:00
# if CAP_AUDIO
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags = sm : : NOSCR ;
dialog : : get_di ( ) . reaction = [ ] ( ) {
2020-11-06 14:43:18 +00:00
# if CAP_SDLAUDIO
2021-02-01 14:10:03 +00:00
Mix_VolumeMusic ( musicvolume ) ;
2020-11-06 14:43:18 +00:00
# endif
2021-02-01 14:10:03 +00:00
# if ISANDROID
settingsChanged = true ;
# endif
} ;
dialog : : bound_low ( 0 ) ;
dialog : : bound_up ( MIX_MAX_VOLUME ) ;
# if CAP_SDLAUDIO
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . extra_options = [ ] {
2021-02-01 14:10:03 +00:00
dialog : : addBoolItem_action ( XLAT ( " play music when out of focus " ) , music_out_of_focus , ' A ' ) ;
} ;
2020-11-06 15:11:19 +00:00
# endif
2021-02-07 17:29:49 +00:00
# endif
2020-11-06 14:40:59 +00:00
}
EX void showSpecialEffects ( ) {
cmode = vid . xres > vid . yres * 1.4 ? sm : : SIDE : sm : : MAYDARK ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " extra graphical effects " ) ) ;
dialog : : addBoolItem_action ( XLAT ( " particles on attack " ) , ( vid . particles ) , ' p ' ) ;
dialog : : addBoolItem_action ( XLAT ( " floating bubbles: special " ) , vid . bubbles_special , ' s ' ) ;
dialog : : addBoolItem_action ( XLAT ( " floating bubbles: treasure thresholds " ) , vid . bubbles_threshold , ' t ' ) ;
dialog : : addBoolItem_action ( XLAT ( " floating bubbles: all treasures " ) , vid . bubbles_all , ' a ' ) ;
dialog : : addBoolItem_action ( XLAT ( " background particle effects " ) , ( vid . backeffects ) , ' b ' ) ;
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2021-02-01 10:19:20 +00:00
EX void show_vector_settings ( ) {
cmode = vid . xres > vid . yres * 1.4 ? sm : : SIDE : sm : : MAYDARK ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2021-02-01 10:19:20 +00:00
dialog : : init ( XLAT ( " vector settings " ) ) ;
dialog : : addSelItem ( XLAT ( " line width " ) , fts ( vid . linewidth ) , ' w ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . linewidth , 0 , 10 , 0.1 , 1 , XLAT ( " line width " ) ,
vid . usingGL ? " " : XLAT ( " Line width setting is only taken into account in OpenGL. " ) ) ;
} ) ;
2021-02-06 00:39:18 +00:00
dialog : : addSelItem ( XLAT ( " line quality " ) , its ( vid . linequality ) , ' l ' ) ;
2021-02-01 10:19:20 +00:00
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . linequality , - 3 , 5 , 1 , 1 , XLAT ( " line quality " ) ,
XLAT ( " Higher numbers make the curved lines smoother, but reduce the performance. " ) ) ;
} ) ;
2021-02-06 00:39:18 +00:00
dialog : : addBoolItem ( " perfect width " , perfect_linewidth = = 2 , ' p ' ) ;
2021-02-01 10:19:20 +00:00
if ( perfect_linewidth = = 1 )
dialog : : lastItem ( ) . value = XLAT ( " shots only " ) ;
dialog : : add_action ( [ ] { perfect_linewidth = ( 1 + perfect_linewidth ) % 3 ; } ) ;
2021-02-06 00:39:18 +00:00
dialog : : addBoolItem_action ( " finer lines at the boundary " , vid . fineline , ' O ' ) ;
if ( vid . fineline ) {
dialog : : addSelItem ( " variable width " , fts ( precise_width ) , ' m ' ) ;
2021-02-01 10:19:20 +00:00
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( precise_width , 0 , 2 , 0.1 , 0.5 ,
XLAT ( " variable width " ) , XLAT ( " lines longer than this value will be split into shorter lines, with width computed separately for each of them. " )
) ;
} ) ;
}
else dialog : : addBreak ( 100 ) ;
add_edit ( neon_mode ) ;
dialog : : addBreak ( 100 ) ;
dialog : : addInfo ( XLAT ( " hint: press Alt while testing modes " ) ) ;
dialog : : addBreak ( 100 ) ;
2021-02-06 00:39:18 +00:00
dialog : : addBoolItem_action ( XLAT ( " disable shadows " ) , noshadow , ' f ' ) ;
dialog : : addBoolItem_action ( XLAT ( " bright mode " ) , bright , ' g ' ) ;
dialog : : addBoolItem_action ( XLAT ( " colorblind simulation " ) , cblind , ' h ' ) ;
2021-02-01 10:19:20 +00:00
2021-02-06 00:39:18 +00:00
dialog : : addBoolItem_action ( XLAT ( " no fill in neon mode " ) , neon_nofill , ' n ' ) ;
2021-02-01 10:19:20 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2020-11-06 14:40:59 +00:00
EX void showGraphConfig ( ) {
cmode = vid . xres > vid . yres * 1.4 ? sm : : SIDE : sm : : MAYDARK ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " graphics configuration " ) ) ;
2021-06-01 08:09:44 +00:00
2021-02-06 00:39:18 +00:00
# if !ISIOS && !ISWEB
add_edit ( vid . want_fullscreen ) ;
2021-06-01 08:09:44 +00:00
# if !ISANDROID && !ISFAKEMOBILE
2021-02-06 00:39:18 +00:00
if ( vid . want_fullscreen ) {
add_edit ( vid . change_fullscr ) ;
if ( vid . change_fullscr )
add_edit ( vid . fullscreen_x ) , add_edit ( vid . fullscreen_y ) ;
else
dialog : : addBreak ( 200 ) ;
}
else {
add_edit ( vid . relative_window_size ) ;
if ( vid . relative_window_size )
add_edit ( vid . window_rel_x ) , add_edit ( vid . window_rel_y ) ;
else
add_edit ( vid . window_x ) , add_edit ( vid . window_y ) ;
2021-06-01 08:09:44 +00:00
}
# endif
2021-02-06 00:39:18 +00:00
# endif
2020-11-06 14:40:59 +00:00
# if CAP_GLORNOT
2021-02-06 00:39:18 +00:00
add_edit ( vid . wantGL ) ;
2020-11-06 14:40:59 +00:00
# endif
2021-06-01 08:09:44 +00:00
# if !ISIOS && !ISANDROID && !ISFAKEMOBILE
2021-02-06 00:39:18 +00:00
if ( ! vid . usingGL ) {
dialog : : addBoolItem ( XLAT ( " anti-aliasing " ) , vid . want_antialias & AA_NOGL , ' O ' ) ;
dialog : : add_action ( [ ] {
if ( ! vid . usingGL )
vid . want_antialias ^ = AA_NOGL | AA_FONT ;
} ) ;
}
else {
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " anti-aliasing " ) ,
2021-02-06 00:39:18 +00:00
( vid . want_antialias & AA_POLY ) ? " polygons " :
( vid . want_antialias & AA_LINES ) ? " lines " :
( vid . want_antialias & AA_MULTI ) ? " multisampling " :
2020-11-06 14:40:59 +00:00
" NO " , ' O ' ) ;
2021-02-06 00:39:18 +00:00
dialog : : add_action ( [ ] {
if ( vid . want_antialias & AA_MULTI )
vid . want_antialias ^ = AA_MULTI ;
else if ( vid . want_antialias & AA_POLY )
vid . want_antialias ^ = AA_POLY | AA_LINES | AA_MULTI ;
else if ( vid . want_antialias & AA_LINES )
vid . want_antialias | = AA_POLY ;
else
vid . want_antialias | = AA_LINES ;
} ) ;
}
2021-06-01 08:09:44 +00:00
# endif
2021-02-06 00:39:18 +00:00
2021-06-01 08:09:44 +00:00
# if !ISIOS && !ISANDROID && !ISFAKEMOBILE
2021-02-06 00:39:18 +00:00
if ( vid . usingGL ) {
if ( vrhr : : active ( ) )
dialog : : addInfo ( XLAT ( " (vsync disabled in VR) " ) ) ;
else
add_edit ( vid . want_vsync ) ;
}
else
dialog : : addBreak ( 100 ) ;
2021-06-01 08:09:44 +00:00
# endif
2021-02-06 00:39:18 +00:00
if ( need_to_apply_screen_settings ( ) ) {
dialog : : addItem ( XLAT ( " apply changes " ) , ' A ' ) ;
dialog : : add_action ( apply_screen_settings ) ;
dialog : : addBreak ( 100 ) ;
}
else
dialog : : addBreak ( 200 ) ;
add_edit ( vid . relative_font ) ;
if ( vid . relative_font )
add_edit ( vid . fontscale ) ;
else
add_edit ( vid . abs_fsize ) ;
2024-03-21 17:44:19 +00:00
add_edit ( mapfontscale ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 10:19:20 +00:00
dialog : : addSelItem ( XLAT ( " vector settings " ) , XLAT ( " width " ) + " " + fts ( vid . linewidth ) , ' w ' ) ;
dialog : : add_action_push ( show_vector_settings ) ;
2020-11-06 14:40:59 +00:00
# if CAP_FRAMELIMIT
dialog : : addSelItem ( XLAT ( " framerate limit " ) , its ( vid . framelimit ) , ' l ' ) ;
if ( getcstat = = ' l ' )
mouseovers = XLAT ( " Reduce the framerate limit to conserve CPU energy " ) ;
# endif
2021-02-06 00:39:18 +00:00
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " scrolling speed " ) , fts ( vid . sspeed ) , ' a ' ) ;
dialog : : addSelItem ( XLAT ( " camera movement speed " ) , fts ( camera_speed ) , ' c ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( camera_speed , - 10 , 10 , 0.1 , 1 , XLAT ( " camera movement speed " ) ,
" This affects: \n \n in 2D: scrolling with arrow keys and Wheel Up \n \n in 3D: camera movement with Home/End. "
) ;
} ) ;
dialog : : addSelItem ( XLAT ( " camera rotation speed " ) , fts ( camera_rot_speed ) , ' r ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( camera_rot_speed , - 10 , 10 , 0.1 , 1 , XLAT ( " camera rotation speed " ) ,
" This affects view rotation with Page Up/Down, and in 3D, camera rotation with arrow keys or mouse. "
) ;
} ) ;
dialog : : addSelItem ( XLAT ( " movement animation speed " ) , fts ( vid . mspeed ) , ' m ' ) ;
2022-01-31 21:21:36 +00:00
dialog : : addSelItem ( XLAT ( " idle animation speed " ) , fts ( vid . ispeed ) , ' i ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . ispeed , 0 , 4 , 0.1 , 1 ,
XLAT ( " idle animation speed " ) ,
" 0 = disable \n \n This affects non-movement animations such as orb effects, item rotation, and more. "
) ;
} ) ;
2020-11-06 14:40:59 +00:00
2024-05-27 13:53:59 +00:00
add_edit ( vid . flasheffects ) ;
2022-03-08 00:37:35 +00:00
2020-11-06 14:40:59 +00:00
dialog : : addItem ( XLAT ( " extra graphical effects " ) , ' u ' ) ;
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
char xuni = uni | 96 ;
if ( ( uni > = 32 & & uni < 64 ) | | uni = = ' L ' | | uni = = ' C ' ) xuni = uni ;
if ( xuni = = ' u ' ) pushScreen ( showSpecialEffects ) ;
else if ( xuni = = ' a ' ) dialog : : editNumber ( vid . sspeed , - 5 , 5 , 1 , 0 ,
XLAT ( " scrolling speed " ) ,
XLAT ( " +5 = center instantly, -5 = do not center the map " )
+ " \n \n " +
XLAT ( " press Space or Home to center on the PC " ) ) ;
else if ( xuni = = ' m ' ) dialog : : editNumber ( vid . mspeed , - 5 , 5 , 1 , 0 ,
XLAT ( " movement animation speed " ) ,
XLAT ( " +5 = move instantly " ) ) ;
# if CAP_FRAMELIMIT
else if ( xuni = = ' l ' ) {
dialog : : editNumber ( vid . framelimit , 5 , 300 , 10 , 300 , XLAT ( " framerate limit " ) , " " ) ;
dialog : : bound_low ( 5 ) ;
}
# endif
else if ( xuni = = ' p ' )
vid . backeffects = ! vid . backeffects ;
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
EX void edit_whatever ( char type , int index ) {
if ( type = = ' f ' ) {
dialog : : editNumber ( whatever [ index ] , - 10 , 10 , 1 , 0 , XLAT ( " whatever " ) ,
" f: " + its ( index ) ) ;
}
else {
dialog : : editNumber ( whateveri [ index ] , - 10 , 10 , 1 , 0 , XLAT ( " whatever " ) ,
" i: " + its ( index ) ) ;
}
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . extra_options = [ type , index ] {
2020-11-06 14:40:59 +00:00
dialog : : addItem ( XLAT ( " integer " ) , ' X ' ) ;
dialog : : add_action ( [ index ] { popScreen ( ) ; edit_whatever ( ' i ' , index ) ; } ) ;
dialog : : addItem ( XLAT ( " float " ) , ' Y ' ) ;
dialog : : add_action ( [ index ] { popScreen ( ) ; edit_whatever ( ' f ' , index ) ; } ) ;
for ( int x = 0 ; x < 8 ; x + + ) {
dialog : : addSelItem ( its ( x ) , type = = ' i ' ? its ( whateveri [ x ] ) : fts ( whatever [ x ] ) , ' A ' + x ) ;
dialog : : add_action ( [ type , x ] { popScreen ( ) ; edit_whatever ( type , x ) ; } ) ;
}
} ;
}
EX void configureOther ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " other settings " ) ) ;
# if ISSTEAM
dialog : : addBoolItem ( XLAT ( " send scores to Steam leaderboards " ) , ( vid . steamscore & 1 ) , ' x ' ) ;
dialog : : add_action ( [ ] { vid . steamscore = vid . steamscore ^ 1 ; } ) ;
# endif
dialog : : addBoolItem_action ( XLAT ( " skip the start menu " ) , vid . skipstart , ' m ' ) ;
dialog : : addItem ( XLAT ( " memory configuration " ) , ' y ' ) ;
dialog : : add_action_push ( show_memory_menu ) ;
// dialog::addBoolItem_action(XLAT("forget faraway cells"), memory_saving_mode, 'y');
# if CAP_AUDIO
2021-02-01 14:10:03 +00:00
add_edit ( musicvolume ) ;
add_edit ( effvolume ) ;
2020-11-06 14:40:59 +00:00
# endif
menuitem_sightrange ( ' r ' ) ;
2021-04-30 17:44:54 +00:00
add_edit ( vid . faraway_highlight ) ;
add_edit ( vid . faraway_highlight_color ) ;
2020-11-06 14:40:59 +00:00
# ifdef WHATEVER
dialog : : addSelItem ( XLAT ( " whatever " ) , fts ( whatever [ 0 ] ) , ' j ' ) ;
dialog : : add_action ( [ ] { edit_whatever ( ' f ' , 0 ) ; } ) ;
# endif
2022-09-15 10:38:39 +00:00
add_edit ( savefile_selection ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
EX void configureInterface ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " interface " ) ) ;
# if CAP_TRANS
dialog : : addSelItem ( XLAT ( " language " ) , XLAT ( " EN " ) , ' l ' ) ;
dialog : : add_action_push ( selectLanguageScreen ) ;
# endif
dialog : : addSelItem ( XLAT ( " player character " ) , numplayers ( ) > 1 ? " " : csname ( vid . cs ) , ' g ' ) ;
dialog : : add_action_push ( showCustomizeChar ) ;
if ( getcstat = = ' g ' ) mouseovers = XLAT ( " Affects looks and grammar " ) ;
dialog : : addSelItem ( XLAT ( " message flash time " ) , its ( vid . flashtime ) , ' t ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . flashtime , 0 , 64 , 1 , 8 , XLAT ( " message flash time " ) ,
XLAT ( " How long should the messages stay on the screen. " ) ) ;
dialog : : bound_low ( 0 ) ;
} ) ;
dialog : : addSelItem ( XLAT ( " limit messages shown " ) , its ( vid . msglimit ) , ' z ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . msglimit , 0 , 64 , 1 , 5 , XLAT ( " limit messages shown " ) ,
XLAT ( " Maximum number of messages on screen. " ) ) ;
dialog : : bound_low ( 0 ) ;
} ) ;
2023-03-25 08:24:47 +00:00
add_edit ( nohelp ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 00:35:34 +00:00
add_edit ( vid . msgleft ) ;
2020-11-06 14:40:59 +00:00
2021-02-01 00:35:34 +00:00
add_edit ( glyphsortorder ) ;
add_edit ( vid . graphglyph ) ;
2022-07-12 12:22:46 +00:00
add_edit ( less_in_landscape ) ;
add_edit ( less_in_portrait ) ;
2020-11-06 14:40:59 +00:00
2021-05-24 14:14:02 +00:00
add_edit ( display_yasc_codes ) ;
2022-10-06 11:10:57 +00:00
add_edit ( vid . orbmode ) ;
2021-05-24 14:14:02 +00:00
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " draw crosshair " ) , crosshair_size > 0 ? fts ( crosshair_size ) : ONOFF ( false ) , ' x ' ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( crosshair_size , 0 , 100 , 1 , 10 , XLAT ( " crosshair size " ) , XLAT (
" Display a targetting reticle in the center of the screen. Might be useful when exploring 3D modes, "
" as it precisely shows the direction we are going. However, the option is available in all modes. "
) ) ;
dialog : : bound_low ( 0 ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . extra_options = [ ] {
2023-08-15 18:28:36 +00:00
draw_crosshair ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : addColorItem ( XLAT ( " crosshair color " ) , crosshair_color , ' X ' ) ;
2023-08-15 18:28:36 +00:00
dialog : : add_action ( [ ] {
dialog : : openColorDialog ( crosshair_color ) ;
dialog : : get_di ( ) . extra_options = draw_crosshair ;
} ) ;
2020-11-06 14:40:59 +00:00
} ;
} ) ;
2022-07-05 09:51:06 +00:00
2024-05-28 13:09:00 +00:00
add_edit ( menu_format ) ;
2022-07-05 09:51:06 +00:00
add_edit ( menu_darkening ) ;
2022-07-12 12:41:54 +00:00
add_edit ( centered_menus ) ;
2022-07-05 09:51:49 +00:00
add_edit ( startanims : : enabled ) ;
2024-05-27 13:21:31 +00:00
add_edit ( use_bool_dialog ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
# if CAP_SDLJOY
EX void showJoyConfig ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " joystick configuration " ) ) ;
dialog : : addSelItem ( XLAT ( " first joystick position (movement) " ) , its ( joyx ) + " , " + its ( joyy ) , 0 ) ;
dialog : : addSelItem ( XLAT ( " second joystick position (panning) " ) , its ( panjoyx ) + " , " + its ( panjoyy ) , 0 ) ;
2021-05-23 12:33:25 +00:00
dialog : : addSelItem ( XLAT ( " joystick mode " ) , autojoy ? XLAT ( " automatic " ) : XLAT ( " manual " ) , ' p ' ) ;
2020-11-06 14:40:59 +00:00
if ( getcstat = = ' p ' ) {
if ( autojoy )
mouseovers = XLAT ( " joystick mode: automatic (release the joystick to move) " ) ;
if ( ! autojoy )
mouseovers = XLAT ( " joystick mode: manual (press a button to move) " ) ;
}
dialog : : addSelItem ( XLAT ( " first joystick: movement threshold " ) , its ( vid . joyvalue ) , ' a ' ) ;
dialog : : addSelItem ( XLAT ( " first joystick: execute movement threshold " ) , its ( vid . joyvalue2 ) , ' b ' ) ;
dialog : : addSelItem ( XLAT ( " second joystick: pan threshold " ) , its ( vid . joypanthreshold ) , ' c ' ) ;
dialog : : addSelItem ( XLAT ( " second joystick: panning speed " ) , fts ( vid . joypanspeed * 1000 ) , ' d ' ) ;
dialog : : addSelItem ( XLAT ( " smoothen " ) , its ( vid . joysmooth ) + " ms " , ' e ' ) ;
2024-05-28 09:59:03 +00:00
add_edit ( joy_init ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
if ( uni = = ' p ' ) autojoy = ! autojoy ;
else if ( uni = = ' a ' ) {
dialog : : editNumber ( vid . joyvalue , 0 , 32768 , 100 , 4800 , XLAT ( " first joystick: movement threshold " ) , " " ) ;
dialog : : bound_low ( 0 ) ;
}
else if ( uni = = ' b ' ) {
dialog : : editNumber ( vid . joyvalue2 , 0 , 32768 , 100 , 5600 , XLAT ( " first joystick: execute movement threshold " ) , " " ) ;
dialog : : bound_low ( 0 ) ;
}
else if ( uni = = ' c ' ) {
dialog : : editNumber ( vid . joypanthreshold , 0 , 32768 , 100 , 2500 , XLAT ( " second joystick: pan threshold " ) , " " ) ;
dialog : : bound_low ( 0 ) ;
}
else if ( uni = = ' d ' )
dialog : : editNumber ( vid . joypanspeed , 0 , 1e-2 , 1e-5 , 1e-4 , XLAT ( " second joystick: panning speed " ) , " " ) ;
else if ( uni = = ' e ' )
dialog : : editNumber ( vid . joypanspeed , 0 , 2000 , 20 , 200 , XLAT ( " smoothen " ) , " large values help if the joystick is imprecise " ) ;
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
# endif
EX void projectionDialog ( ) {
vid . tc_alpha = ticks ;
dialog : : editNumber ( vpconf . alpha , - 5 , 5 , .1 , 1 ,
2021-02-01 14:10:03 +00:00
XLAT ( " projection distance " ) ,
2020-11-06 14:40:59 +00:00
XLAT ( " HyperRogue uses the Minkowski hyperboloid model internally. "
" Klein and Poincaré models can be obtained by perspective, "
" and the Gans model is obtained by orthogonal projection. "
" See also the conformal mode (in the special modes menu) "
" for more models. " ) ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . extra_options = [ ] ( ) {
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 100 ) ;
if ( GDIM = = 2 ) dialog : : addHelp ( XLAT (
" If we are viewing an equidistant g absolute units below a plane, "
" from a point c absolute units above the plane, this corresponds "
" to viewing a Minkowski hyperboloid from a point "
" tanh(g)/tanh(c) units below the center. This in turn corresponds to "
" the Poincaré model for g=c, and Klein-Beltrami model for g=0. " ) ) ;
dialog : : addSelItem ( sphere ? " stereographic " : " Poincaré model " , " 1 " , ' P ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { * dialog : : get_ne ( ) . editwhat = 1 ; vpconf . scale = 1 ; dialog : : get_ne ( ) . s = " 1 " ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( sphere ? " gnomonic " : " Klein model " , " 0 " , ' K ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { * dialog : : get_ne ( ) . editwhat = 0 ; vpconf . scale = 1 ; dialog : : get_ne ( ) . s = " 0 " ; } ) ;
2020-11-06 14:40:59 +00:00
if ( hyperbolic ) {
dialog : : addSelItem ( " inverted Poincaré model " , " -1 " , ' I ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { * dialog : : get_ne ( ) . editwhat = - 1 ; vpconf . scale = 1 ; dialog : : get_ne ( ) . s = " -1 " ; } ) ;
2020-11-06 14:40:59 +00:00
}
dialog : : addItem ( sphere ? " orthographic " : " Gans model " , ' O ' ) ;
2023-08-09 12:22:32 +00:00
dialog : : add_action ( [ ] ( ) { vpconf . alpha = vpconf . scale = 999 ; dialog : : get_ne ( ) . reset_str ( ) ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addItem ( sphere ? " towards orthographic " : " towards Gans model " , ' T ' ) ;
2023-08-09 12:22:32 +00:00
dialog : : add_action ( [ ] ( ) { double d = 1.1 ; vpconf . alpha * = d ; vpconf . scale * = d ; dialog : : get_ne ( ) . reset_str ( ) ; } ) ;
2020-11-06 14:40:59 +00:00
} ;
}
2021-02-01 14:10:03 +00:00
EX void menuitem_projection_distance ( char key ) {
dialog : : addSelItem ( XLAT ( " projection distance " ) , fts ( vpconf . alpha ) + " ( " + current_proj_name ( ) + " ) " , key ) ;
dialog : : add_action ( projectionDialog ) ;
}
2020-11-06 14:40:59 +00:00
EX void explain_detail ( ) {
dialog : : addHelp ( XLAT (
" Objects at distance less than %1 absolute units "
" from the center will be displayed with high "
" detail, and at distance at least %2 with low detail. " ,
fts ( vid . highdetail ) , fts ( vid . middetail )
) ) ;
}
EX ld max_fov_angle ( ) {
2023-11-30 11:32:24 +00:00
auto p = get_stereo_param ( ) ;
2021-03-21 10:28:10 +00:00
if ( p > = 1 | | p < = - 1 ) return 360 ;
return acos ( - p ) * 2 / degree ;
2020-11-06 14:40:59 +00:00
}
2024-01-07 08:08:44 +00:00
EX void edit_fov_screen ( ) {
dialog : : editNumber ( vid . fov , 1 , max_fov_angle ( ) , 1 , 90 , " field of view " ,
XLAT (
" Horizontal field of view, in angles. "
" This affects the Hypersian Rug mode (even when stereo is OFF) "
" and non-disk models. " ) + " \n \n " +
XLAT (
" Must be less than %1°. Panini projection can be used to get higher values. " ,
fts ( max_fov_angle ( ) )
)
) ;
dialog : : bound_low ( 1e-8 ) ;
dialog : : bound_up ( max_fov_angle ( ) - 0.01 ) ;
dialog : : get_di ( ) . extra_options = [ ] {
auto ptr = dynamic_cast < dialog : : number_dialog * > ( screens . back ( ) . target_base ( ) ) ;
if ( ptr & & ptr - > vmax ! = max_fov_angle ( ) ) { popScreen ( ) ; edit_fov_screen ( ) ; return ; }
add_edit ( vid . stereo_mode , ' M ' ) ;
if ( among ( vid . stereo_mode , sPanini , sStereographic ) ) {
add_edit ( vid . stereo_param , ' P ' ) ;
}
} ;
}
2023-08-13 11:45:25 +00:00
EX void add_edit_fov ( char key IS ( ' f ' ) ) {
2020-11-06 14:40:59 +00:00
string sfov = fts ( vid . fov ) + " ° " ;
2023-11-30 11:32:24 +00:00
if ( get_stereo_param ( ) ) {
2020-11-06 14:40:59 +00:00
sfov + = " / " + fts ( max_fov_angle ( ) ) + " ° " ;
}
dialog : : addSelItem ( XLAT ( " field of view " ) , sfov , key ) ;
2024-01-07 08:08:44 +00:00
dialog : : add_action ( edit_fov_screen ) ;
2020-11-06 14:40:59 +00:00
}
bool supported_ods ( ) {
if ( ! CAP_ODS ) return false ;
return rug : : rugged | | ( hyperbolic & & GDIM = = 3 ) ;
}
EX void showStereo ( ) {
cmode = sm : : SIDE | sm : : MAYDARK ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " stereo vision config " ) ) ;
2021-02-01 00:35:34 +00:00
add_edit ( vid . stereo_mode ) ;
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " pupillary distance " ) , fts ( vid . ipd ) , ' e ' ) ;
switch ( vid . stereo_mode ) {
case sAnaglyph :
dialog : : addSelItem ( XLAT ( " distance between images " ) , fts ( vid . anaglyph_eyewidth ) , ' d ' ) ;
break ;
case sLR :
dialog : : addSelItem ( XLAT ( " distance between images " ) , fts ( vid . lr_eyewidth ) , ' d ' ) ;
break ;
2023-11-30 11:32:24 +00:00
case sPanini : case sStereographic :
add_edit ( vid . stereo_param ) ;
break ;
2020-11-06 14:40:59 +00:00
default :
dialog : : addBreak ( 100 ) ;
break ;
}
dialog : : addSelItem ( XLAT ( " desaturate colors " ) , its ( vid . desaturate ) + " % " , ' c ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . desaturate , 0 , 100 , 10 , 0 , XLAT ( " desaturate colors " ) ,
XLAT ( " Make the game colors less saturated. This is useful in the anaglyph mode. " )
) ;
} ) ;
add_edit_fov ( ' f ' ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
string help3 = XLAT (
" This allows you to view the world of HyperRogue in three dimensions. "
" Best used with the Hypersian Rug mode. When used in the disk model, "
" this lets you look at the Minkowski hyperboloid (which means the "
" depth of terrain features is actually reversed). It also works with non-disk models, "
" from the conformal menu. "
) + " " + XLAT (
" Currently, red-cyan anaglyph glasses and mobile VR googles are supported. "
) + " \n \n " ;
if ( uni = = ' m ' ) {
vid . stereo_mode = eStereo ( ( 1 + vid . stereo_mode ) % 4 ) ;
if ( vid . stereo_mode = = sODS & & ! supported_ods ( ) ) vid . stereo_mode = sOFF ;
}
else if ( uni = = ' e ' )
dialog : : editNumber ( vid . ipd , - 10 , 10 , 0.01 , 0 , XLAT ( " pupillary distance " ) ,
help3 +
XLAT ( " The distance between your eyes in the represented 3D object. This is given in absolute units. " )
) , dialog : : scaleSinh100 ( ) ;
else if ( uni = = ' d ' & & vid . stereo_mode = = sAnaglyph )
dialog : : editNumber ( vid . anaglyph_eyewidth , - 1 , 1 , 0.01 , 0 , XLAT ( " distance between images " ) ,
help3 +
XLAT ( " The distance between your eyes. 1 is the width of the screen. " ) ) ;
else if ( uni = = ' d ' & & vid . stereo_mode = = sLR )
dialog : : editNumber ( vid . lr_eyewidth , - 1 , 1 , 0.01 , 0 , XLAT ( " distance between images " ) ,
help3 +
XLAT ( " The distance between your eyes. 1 is the width of the screen. " ) ) ;
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
EX void add_edit_wall_quality ( char c ) {
dialog : : addSelItem ( XLAT ( " wall quality " ) , its ( vid . texture_step ) , c ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . texture_step , 1 , 16 , 1 , 1 , XLAT ( " wall quality " ) ,
XLAT (
" Controls the number of triangles used for wall surfaces. "
" Higher numbers reduce the performance. "
" This has a strong effect when the walls are curved indeed "
" (floors in 2D geometries, honeycombs based on horospheres, and projections other than native perspective), "
" but otherwise, usually it can be set to 1 without significant adverse effects other "
" than slightly incorrect texturing. "
)
) ;
dialog : : bound_low ( 1 ) ;
dialog : : bound_up ( 128 ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . reaction = [ ] {
2020-11-06 14:40:59 +00:00
# if MAXMDIM >= 4
if ( floor_textures ) {
delete floor_textures ;
floor_textures = NULL ;
}
# endif
} ;
} ) ;
}
EX void edit_levellines ( char c ) {
if ( levellines )
dialog : : addSelItem ( XLAT ( " level lines " ) , fts ( levellines ) , c ) ;
else
dialog : : addBoolItem ( XLAT ( " level lines " ) , false , c ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( levellines , 0 , 100 , 0.5 , 0 , XLAT ( " level lines " ) ,
XLAT (
" This feature superimposes level lines on the rendered screen. These lines depend on the Z coordinate. In 3D hyperbolic the Z coordinate is taken from the Klein model. "
" Level lines can be used to observe the curvature: circles correspond to positive curvature, while hyperbolas correspond to negative. See e.g. the Hypersian Rug mode. " )
) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . reaction = ray : : reset_raycaster ;
dialog : : get_di ( ) . extra_options = [ ] {
2020-11-06 14:40:59 +00:00
dialog : : addBoolItem ( XLAT ( " disable textures " ) , disable_texture , ' T ' ) ;
dialog : : add_action ( [ ] { ray : : reset_raycaster ( ) ; disable_texture = ! disable_texture ; } ) ;
dialog : : addItem ( XLAT ( " disable level lines " ) , ' D ' ) ;
dialog : : add_action ( [ ] { ray : : reset_raycaster ( ) ; levellines = 0 ; popScreen ( ) ; } ) ;
} ;
dialog : : bound_low ( 0 ) ;
} ) ;
}
2022-12-15 11:48:25 +00:00
EX geom3 : : eSpatialEmbedding shown_spatial_embedding ( ) {
2022-12-15 12:11:23 +00:00
if ( GDIM = = 2 ) return geom3 : : seNone ;
2022-12-15 11:48:25 +00:00
return geom3 : : spatial_embedding ;
}
2023-08-14 16:08:28 +00:00
EX bool in_tpp ( ) { return pmodel = = mdDisk & & ! models : : camera_straight ; }
2022-12-15 12:11:23 +00:00
2022-12-17 23:31:07 +00:00
EX void display_embedded_errors ( ) {
2023-01-07 22:21:03 +00:00
using namespace geom3 ;
2023-02-05 10:18:13 +00:00
auto eucs = [ ] {
dialog : : addItem ( XLAT ( " set square tiling " ) , ' A ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ; set_geometry ( gEuclidSquare ) ; set_variation ( eVariation : : pure ) ; start_game ( ) ; } ) ; } ) ;
dialog : : addItem ( XLAT ( " set hex tiling " ) , ' B ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ; set_geometry ( gEuclid ) ; set_variation ( eVariation : : pure ) ; start_game ( ) ; } ) ; } ) ;
} ;
if ( among ( spatial_embedding , seNil , seProductH , seProductS , seCliffordTorus , seSL2 ) & & ( ! among ( geometry , gEuclid , gEuclidSquare ) | | ! PURE ) ) {
2023-01-07 22:21:03 +00:00
dialog : : addInfo ( XLAT ( " error: currently works only in PURE Euclidean regular square or hex tiling " ) , 0xC00000 ) ;
2023-02-05 10:18:13 +00:00
eucs ( ) ;
2023-01-07 22:21:03 +00:00
return ;
}
2023-02-05 10:18:13 +00:00
if ( among ( spatial_embedding , seSol , seSolN , seNIH ) & & ( ! bt : : in ( ) & & ! among ( geometry , gEuclid , gEuclidSquare ) ) ) {
dialog : : addInfo ( XLAT ( " error: currently works only in pure Euclidean, or binary tiling and similar " ) , 0xC00000 ) ;
eucs ( ) ;
dialog : : addItem ( XLAT ( " set binary tiling variant " ) , ' C ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ; set_geometry ( gBinaryTiling ) ; geom3 : : switch_fpp ( ) ; geom3 : : switch_fpp ( ) ; start_game ( ) ; } ) ; } ) ;
dialog : : addItem ( XLAT ( " set ternary tiling " ) , ' D ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ; set_geometry ( gTernary ) ; geom3 : : switch_fpp ( ) ; geom3 : : switch_fpp ( ) ; start_game ( ) ; } ) ; } ) ;
dialog : : addItem ( XLAT ( " set binary tiling " ) , ' E ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ; set_geometry ( gBinary4 ) ; geom3 : : switch_fpp ( ) ; geom3 : : switch_fpp ( ) ; start_game ( ) ; } ) ; } ) ;
2023-01-07 22:21:03 +00:00
return ;
}
2023-02-04 18:40:49 +00:00
if ( shmup : : on & & cgi . emb - > no_spin ( ) ) {
dialog : : addInfo ( XLAT ( " error: this embedding does not work in shmup " ) , 0xC00000 ) ;
return ;
}
2023-01-07 22:21:03 +00:00
if ( meuclid & & spatial_embedding = = seCliffordTorus ) {
2023-02-05 10:18:13 +00:00
if ( ! clifford_torus_valid ( ) ) {
2023-01-07 22:21:03 +00:00
dialog : : addInfo ( XLAT ( " error: this method works only in rectangular torus " ) , 0xC00000 ) ;
2023-02-05 10:18:13 +00:00
dialog : : addItem ( XLAT ( " set 20x20 torus " ) , ' A ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ;
auto & T0 = euc : : eu_input . user_axes ;
T0 [ 0 ] [ 0 ] = T0 [ 1 ] [ 1 ] = 20 ;
T0 [ 0 ] [ 1 ] = 0 ;
T0 [ 1 ] [ 0 ] = geometry = = gEuclid ? 10 : 0 ;
euc : : eu_input . twisted = false ;
euc : : build_torus3 ( ) ;
2023-02-10 18:04:32 +00:00
geom3 : : apply_settings_full ( ) ; start_game ( ) ; } ) ; } ) ;
2023-01-07 22:21:03 +00:00
return ;
}
}
if ( meuclid & & spatial_embedding = = seProductS ) {
2023-02-18 11:53:52 +00:00
# if CAP_RUG
2023-01-07 22:21:03 +00:00
rug : : clifford_torus ct ;
bool err = sqhypot_d ( 2 , ct . xh ) < 1e-3 & & sqhypot_d ( 2 , ct . yh ) < 1e-3 ;
if ( err ) {
dialog : : addInfo ( XLAT ( " error: this method works only in cylinder " ) , 0xC00000 ) ;
2023-02-05 10:18:13 +00:00
dialog : : addItem ( XLAT ( " set cylinder " ) , ' A ' ) ; dialog : : add_action ( [ ] { dialog : : do_if_confirmed ( [ ] { stop_game ( ) ;
auto & T0 = euc : : eu_input . user_axes ;
T0 [ 0 ] [ 0 ] = 10 ;
T0 [ 0 ] [ 1 ] = T0 [ 1 ] [ 0 ] = T0 [ 1 ] [ 1 ] = 0 ;
euc : : eu_input . twisted = false ;
euc : : build_torus3 ( ) ;
2023-02-10 18:04:32 +00:00
geom3 : : apply_settings_full ( ) ; start_game ( ) ; } ) ; } ) ;
2023-01-07 22:21:03 +00:00
return ;
}
2023-02-18 11:53:52 +00:00
# else
dialog : : addInfo ( XLAT ( " error: not supported " ) , 0xC00000 ) ;
# endif
2023-01-07 22:21:03 +00:00
}
if ( msphere & & ! among ( spatial_embedding , seNone , seDefault , seLowerCurvature , seMuchLowerCurvature , seProduct , seProductS ) ) {
dialog : : addInfo ( XLAT ( " error: this method does not work in spherical geometry " ) , 0xC00000 ) ;
return ;
}
if ( mhyperbolic & & ! among ( spatial_embedding , seNone , seDefault , seLowerCurvature , seMuchLowerCurvature , seProduct , seProductH , seSol , seSolN , seNIH ) ) {
dialog : : addInfo ( XLAT ( " error: this method does not work in hyperbolic geometry " ) , 0xC00000 ) ;
return ;
}
2022-12-17 23:31:07 +00:00
}
2022-12-15 11:48:25 +00:00
EX void show_spatial_embedding ( ) {
cmode = sm : : SIDE | sm : : MAYDARK | sm : : CENTER | sm : : PANNING | sm : : SHOWCURSOR ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2022-12-15 11:48:25 +00:00
dialog : : init ( XLAT ( " 3D styles " ) ) ;
auto emb = shown_spatial_embedding ( ) ;
add_edit ( geom3 : : auto_configure ) ;
2020-11-06 14:40:59 +00:00
2022-12-15 11:48:25 +00:00
dialog : : addBreak ( 100 ) ;
auto & seo = geom3 : : spatial_embedding_options ;
for ( int i = 0 ; i < isize ( seo ) ; i + + ) {
auto se = geom3 : : eSpatialEmbedding ( i ) ;
dialog : : addBoolItem ( XLAT ( seo [ i ] . first ) , emb = = i , ' a ' + i ) ;
2023-01-28 03:08:32 +00:00
dialog : : add_action ( [ se ] { invoke_embed ( se ) ; } ) ;
2023-02-05 10:18:13 +00:00
string s = why_wrong ( se ) ;
if ( s ! = " " )
dialog : : items . back ( ) . value = ( emb = = i ? ONOFF ( true ) : XLAT ( " needs " ) ) + s ;
2020-11-07 14:47:19 +00:00
}
2022-12-08 18:38:06 +00:00
2022-12-15 11:48:25 +00:00
dialog : : addBreak ( 100 ) ;
dialog : : addHelp ( XLAT ( seo [ emb ] . second ) ) ;
2022-12-17 23:31:07 +00:00
display_embedded_errors ( ) ;
2022-12-15 11:48:25 +00:00
dialog : : addBreak ( 100 ) ;
2022-12-15 12:11:23 +00:00
if ( geom3 : : auto_configure ) {
if ( emb = = geom3 : : seNone ) {
dialog : : addBoolItem ( XLAT ( " third-person perspective " ) , in_tpp ( ) , ' T ' ) ;
dialog : : add_action ( geom3 : : switch_tpp ) ;
2023-02-18 11:53:52 +00:00
# if CAP_RUG
2023-01-05 15:57:08 +00:00
dialog : : addBoolItem ( XLAT ( " Hypersian Rug " ) , rug : : rugged , ' u ' ) ;
dialog : : add_action ( [ ] {
if ( in_tpp ( ) ) geom3 : : switch_tpp ( ) ;
if ( ! rug : : rugged ) {
pconf . alpha = 1 , pconf . scale = 1 ; if ( ! rug : : rugged ) rug : : init ( ) ;
}
else rug : : close ( ) ;
} ) ;
2023-02-18 11:53:52 +00:00
# endif
2022-12-15 12:11:23 +00:00
dialog : : addBreak ( 100 ) ;
}
else {
if ( geom3 : : supports_flat ( ) ) add_edit ( geom3 : : flat_embedding ) ;
else dialog : : addBreak ( 100 ) ;
if ( geom3 : : supports_invert ( ) ) add_edit ( geom3 : : inverted_embedding ) ;
else dialog : : addBreak ( 100 ) ;
}
}
2023-02-05 09:44:36 +00:00
dialog : : addSelItem ( XLAT ( " reset view " ) , embedded_plane & & isize ( current_display - > radarpoints ) = = 0 ? XLAT ( " (fix errors) " ) : ! cells_drawn ? XLAT ( " (fix errors) " ) : " " , ' ' ) ;
dialog : : add_action ( [ ] {
if ( rug : : rug_control ( ) )
rug : : reset_view ( ) ;
else
fullcenter ( ) ;
} ) ;
2022-12-15 12:11:23 +00:00
dialog : : addBreak ( 100 ) ;
2022-12-15 11:48:25 +00:00
dialog : : addBack ( ) ;
2022-12-09 00:57:41 +00:00
2022-12-15 11:48:25 +00:00
dialog : : display ( ) ;
}
2022-12-09 00:57:41 +00:00
2023-02-18 17:32:01 +00:00
EX void show3D_height_details ( ) {
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
dialog : : init ( XLAT ( " 3D detailed settings " ) ) ;
add_edit ( vid . wall_height ) ;
dialog : : addBreak ( 50 ) ;
add_edit ( vid . rock_wall_ratio ) ;
add_edit ( vid . human_wall_ratio ) ;
add_edit ( vid . lake_top ) ;
add_edit ( vid . lake_shallow ) ;
add_edit ( vid . lake_bottom ) ;
dialog : : addBreak ( 50 ) ;
if ( embedded_plane ) {
add_edit ( auto_remove_roofs ) ;
add_edit ( vid . wall_height2 ) ;
add_edit ( vid . wall_height3 ) ;
add_edit ( draw_sky ) ;
add_edit ( vid . lowsky_height ) ;
add_edit ( vid . sky_height ) ;
add_edit ( vid . star_height ) ;
add_edit ( vid . infdeep_height ) ;
add_edit ( vid . sun_size ) ;
add_edit ( vid . star_size ) ;
2023-04-11 15:10:04 +00:00
# if MAXMDIM >= 4
2023-02-18 18:33:27 +00:00
add_edit ( star_prob ) ;
2023-02-18 17:32:01 +00:00
add_edit ( vid . height_limits ) ;
if ( euclid & & msphere ) add_edit ( use_euclidean_infinity ) ;
2023-04-11 15:10:04 +00:00
# endif
2023-02-19 00:00:15 +00:00
dialog : : addBreak ( 100 ) ;
dialog : : addHelp ( lalign ( 0 , " absolute altitudes: \n \n "
" depth " , cgi . INFDEEP ,
" water " , tie ( cgi . BOTTOM , cgi . SHALLOW , cgi . LAKE ) ,
" floor " , cgi . FLOOR ,
" eye " , vid . eye ,
" walls " , tie ( cgi . WALL , cgi . HIGH , cgi . HIGH2 ) ,
" star " , cgi . STAR ,
" sky " , cgi . SKY ,
" \n \n " ,
" recommended: " , cgi . emb - > height_limit ( - 1 ) , " to " , cgi . emb - > height_limit ( 1 )
) ) ;
2023-02-18 17:32:01 +00:00
}
else dialog : : addInfo ( XLAT ( " more options in 3D engine " ) ) ;
dialog : : addBreak ( 100 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2022-12-15 11:48:25 +00:00
EX void show3D ( ) {
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
dialog : : init ( XLAT ( " 3D configuration " ) ) ;
2020-11-07 14:47:19 +00:00
2022-12-15 11:48:25 +00:00
# if MAXMDIM >=4
2020-11-06 14:40:59 +00:00
if ( WDIM = = 2 ) {
2023-12-03 13:28:30 +00:00
dialog : : addSelItem ( XLAT ( " 3D style " ) , XLAT ( geom3 : : spatial_embedding_options [ shown_spatial_embedding ( ) ] . first ) , ' E ' ) ;
2022-12-15 11:48:25 +00:00
dialog : : add_action_push ( show_spatial_embedding ) ;
2022-12-17 23:31:07 +00:00
display_embedded_errors ( ) ;
2022-12-15 11:48:25 +00:00
dialog : : addBreak ( 50 ) ;
2020-11-06 14:40:59 +00:00
}
# endif
2022-12-15 11:48:25 +00:00
2020-11-06 14:40:59 +00:00
if ( vid . use_smart_range = = 0 & & GDIM = = 2 ) {
2021-01-31 19:45:00 +00:00
add_edit ( vid . highdetail ) ;
add_edit ( vid . middetail ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 50 ) ;
}
if ( WDIM = = 2 ) {
2023-05-01 13:49:25 +00:00
if ( cgi . emb - > is_euc_scalable ( ) ) {
2023-01-05 13:01:23 +00:00
add_edit ( geom3 : : euclid_embed_scale ) ;
add_edit ( geom3 : : euclid_embed_scale_y ) ;
add_edit ( geom3 : : euclid_embed_rotate ) ;
}
2022-12-16 22:03:00 +00:00
add_edit ( embedded_shift_method_choice ) ;
2021-01-31 19:45:00 +00:00
add_edit ( vid . camera ) ;
2020-11-06 14:40:59 +00:00
if ( GDIM = = 3 )
2021-01-31 19:45:00 +00:00
add_edit ( vid . eye ) ;
2020-11-06 14:40:59 +00:00
2021-01-31 19:45:00 +00:00
add_edit ( vid . depth ) ;
if ( GDIM = = 2 ) {
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " Projection at the ground level " ) , fts ( pconf . alpha ) , ' p ' ) ;
2021-01-31 19:45:00 +00:00
dialog : : add_action ( projectionDialog ) ;
}
2020-11-06 14:40:59 +00:00
else if ( ! in_perspective ( ) )
2021-05-24 09:42:46 +00:00
dialog : : addSelItem ( XLAT ( " projection distance " ) , fts ( pconf . alpha ) , ' p ' ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 50 ) ;
2021-01-31 19:45:00 +00:00
add_edit ( vid . wall_height ) ;
2023-12-03 13:28:30 +00:00
dialog : : addSelItem ( XLAT ( " 3D detailed settings " ) , " " , ' D ' ) ;
2023-02-18 17:32:01 +00:00
dialog : : add_action_push ( show3D_height_details ) ;
2020-11-06 14:40:59 +00:00
2024-03-23 23:39:02 +00:00
add_edit ( vid . creature_scale ) ;
2020-11-06 14:40:59 +00:00
}
else {
2021-01-31 19:45:00 +00:00
add_edit ( vid . creature_scale ) ;
add_edit ( vid . height_width ) ;
2020-11-06 14:40:59 +00:00
menuitem_sightrange ( ' s ' ) ;
}
dialog : : addBreak ( 50 ) ;
2021-01-31 19:45:00 +00:00
add_edit ( vid . yshift ) ;
2020-11-06 14:40:59 +00:00
if ( GDIM = = 3 ) {
dialog : : addSelItem ( XLAT ( " mouse aiming sensitivity " ) , fts ( mouseaim_sensitivity ) , ' a ' ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( mouseaim_sensitivity , - 1 , 1 , 0.002 , 0.01 , XLAT ( " mouse aiming sensitivity " ) , " set to 0 to disable " ) ;
} ) ;
}
2023-08-14 16:08:28 +00:00
if ( true ) add_edit ( vpconf . cam ( ) ) ;
2020-11-06 14:40:59 +00:00
if ( GDIM = = 2 ) {
dialog : : addSelItem ( XLAT ( " fixed facing " ) , vid . fixed_facing ? fts ( vid . fixed_facing_dir ) : XLAT ( " OFF " ) , ' f ' ) ;
dialog : : add_action ( [ ] ( ) { vid . fixed_facing = ! vid . fixed_facing ;
if ( vid . fixed_facing ) {
dialog : : editNumber ( vid . fixed_facing_dir , 0 , 360 , 15 , 90 , " " , " " ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags | = sm : : CENTER ;
2020-11-06 14:40:59 +00:00
}
} ) ;
}
2022-12-08 18:38:06 +00:00
if ( mproduct | | embedded_plane )
2020-11-06 14:40:59 +00:00
dialog : : addBoolItem_action ( XLAT ( " fixed Y/Z rotation " ) , vid . fixed_yz , ' Z ' ) ;
2021-10-15 20:36:43 +00:00
if ( WDIM = = 2 & & GDIM = = 3 ) {
2021-10-15 20:38:24 +00:00
add_edit ( vid . pseudohedral ) ;
2021-10-15 20:36:43 +00:00
// add_edit(vid.depth_bonus);
}
2020-11-06 14:40:59 +00:00
if ( true ) {
dialog : : addBreak ( 50 ) ;
dialog : : addSelItem ( XLAT ( " projection " ) , current_proj_name ( ) , ' M ' ) ;
2021-01-31 19:45:00 +00:00
dialog : : add_action_push ( models : : model_menu ) ;
2020-11-06 14:40:59 +00:00
}
2023-02-18 11:53:52 +00:00
# if CAP_RUG
2023-01-05 15:57:08 +00:00
if ( GDIM = = 2 ) {
dialog : : addItem ( XLAT ( " configure Hypersian Rug " ) , ' u ' ) ;
dialog : : add_action_push ( rug : : show ) ;
}
2023-02-18 11:53:52 +00:00
# endif
2023-01-05 15:57:08 +00:00
2020-11-06 14:40:59 +00:00
# if MAXMDIM >= 4
if ( GDIM = = 3 ) add_edit_fov ( ' f ' ) ;
if ( GDIM = = 3 ) {
dialog : : addSelItem ( XLAT ( " radar size " ) , fts ( vid . radarsize ) , ' r ' ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( vid . radarsize , 0 , 360 , 15 , 90 , " " , XLAT ( " set to 0 to disable " ) ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . extra_options = [ ] ( ) { draw_radar ( true ) ; } ;
2020-11-06 14:40:59 +00:00
} ) ;
}
if ( WDIM = = 3 & & sphere & & stretch : : factor ) {
dialog : : addItem ( XLAT ( " Berger sphere limit " ) , berger_limit ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( berger_limit , 0 , 10 , 1 , 2 , " " ,
XLAT ( " Primitive-based rendering of Berger sphere is currently very slow and low quality. "
" Here you can choose how many images to draw. " )
) ;
} ) ;
}
# if CAP_RAY
if ( GDIM = = 3 ) {
dialog : : addItem ( XLAT ( " configure raycasting " ) , ' A ' ) ;
dialog : : add_action_push ( ray : : configure ) ;
}
# endif
edit_levellines ( ' L ' ) ;
2022-12-17 22:59:39 +00:00
if ( WDIM = = 3 | | ( GDIM = = 3 & & meuclid ) ) {
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " radar range " ) , fts ( vid . radarrange ) , ' R ' ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( vid . radarrange , 0 , 10 , 0.5 , 2 , " " , XLAT ( " " ) ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . extra_options = [ ] ( ) { draw_radar ( true ) ; } ;
2020-11-06 14:40:59 +00:00
} ) ;
}
if ( GDIM = = 3 ) add_edit_wall_quality ( ' W ' ) ;
# endif
# if CAP_RUG
if ( rug : : rugged ) {
dialog : : addBoolItem_action ( XLAT ( " 3D monsters/walls on the surface " ) , rug : : spatial_rug , ' S ' ) ;
}
# endif
if ( 0 ) ;
# if CAP_RUG
else if ( rug : : rugged & & ! rug : : spatial_rug )
dialog : : addBreak ( 100 ) ;
# endif
else if ( GDIM = = 2 & & non_spatial_model ( ) )
dialog : : addInfo ( XLAT ( " no 3D effects available in this projection " ) , 0xC00000 ) ;
else if ( GDIM = = 2 & & ! spatial_graphics )
dialog : : addInfo ( XLAT ( " set 3D monsters or walls in basic config first " ) ) ;
else if ( geom3 : : invalid ! = " " )
2021-05-23 13:47:45 +00:00
dialog : : addInfo ( XLAT ( " error: " ) + geom3 : : invalid , 0xC00000 ) ;
2020-11-06 14:40:59 +00:00
else
dialog : : addInfo ( XLAT ( " parameters set correctly " ) ) ;
dialog : : addBreak ( 50 ) ;
dialog : : addItem ( XLAT ( " stereo vision config " ) , ' e ' ) ;
2021-01-31 19:45:00 +00:00
dialog : : add_action_push ( showStereo ) ;
2020-11-19 17:20:06 +00:00
# if CAP_VR
2020-12-30 13:20:30 +00:00
dialog : : addBoolItem ( XLAT ( " VR settings " ) , vrhr : : active ( ) , ' v ' ) ;
2020-11-19 17:20:06 +00:00
dialog : : add_action_push ( vrhr : : show_vr_settings ) ;
# endif
2020-11-06 14:40:59 +00:00
dialog : : addBack ( ) ;
dialog : : display ( ) ;
2021-01-31 19:45:00 +00:00
}
2024-05-26 18:38:31 +00:00
# if HDR
namespace ccolor { struct data ; }
# endif
EX shared_ptr < custom_parameter > param_ccolor ( ccolor : : data * & val , const parameter_names & n ) {
shared_ptr < custom_parameter > u ( new custom_parameter ) ;
u - > setup ( n ) ;
2024-05-26 19:15:26 +00:00
u - > custom_viewer = [ ] ( char key ) { } ;
2024-05-26 18:38:31 +00:00
u - > custom_value = [ & val ] { for ( int i = 0 ; i < isize ( ccolor : : all ) ; i + + ) if ( ccolor : : all [ i ] = = val ) return i ; return - 1 ; } ;
u - > last_value = u - > custom_value ( ) ;
u - > custom_affect = [ & val ] ( void * v ) { return & val = = v ; } ;
u - > custom_load = [ & val ] ( const string & s ) { for ( auto c : ccolor : : all ) if ( c - > name = = s ) val = c ; } ;
u - > custom_save = [ & val ] { return val - > name ; } ;
u - > custom_clone = [ u ] ( struct local_parameter_set & lps , void * value ) { auto val = ( ccolor : : data * * ) value ; return param_ccolor ( * val , lps . mod ( & * u ) ) ; } ;
return u ;
}
2021-02-04 13:58:39 +00:00
EX int config3 = addHook ( hooks_configfile , 100 , [ ] {
2021-02-01 00:45:10 +00:00
param_f ( vid . eye , " eyelevel " , 0 )
2021-01-31 19:45:00 +00:00
- > editable ( - 5 , 5 , .1 , " eye level " , " " , ' E ' )
- > set_extra ( [ ] {
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags | = sm : : CENTER ;
2023-02-10 22:37:39 +00:00
vid . tc_camera = ticks ;
2020-11-06 14:40:59 +00:00
2021-01-31 19:45:00 +00:00
dialog : : addHelp ( XLAT ( " In the FPP mode, the camera will be set at this altitude (before applying shifts). " ) ) ;
dialog : : addBoolItem ( XLAT ( " auto-adjust to eyes on the player model " ) , vid . auto_eye , ' O ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . reaction = [ ] { vid . auto_eye = false ; } ;
2021-01-31 19:45:00 +00:00
dialog : : add_action ( [ ] ( ) {
vid . auto_eye = ! vid . auto_eye ;
geom3 : : do_auto_eye ( ) ;
} ) ;
} ) ;
2024-05-26 18:22:29 +00:00
param_b ( vid . auto_eye , " auto-eyelevel " , false ) ;
2021-01-31 19:45:00 +00:00
2023-08-08 10:04:19 +00:00
param_b ( nomenukey , " nomenukey " ) ;
param_b ( showstartmenu , " showstartmenu " ) ;
param_b ( draw_centerover , " draw_centerover " ) ;
2024-05-26 18:22:29 +00:00
param_enum ( nohelp , " help_messages " , 0 )
2023-03-25 08:24:47 +00:00
- > editable ( {
{ " all " , " all context help/welcome messages " } ,
{ " none " , " no context help/welcome messages " } ,
{ " automatic " , " I know I can press F1 for help " } ,
} , " context help " , ' H ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . creature_scale , parameter_names ( " creature_scale " , " 3d-creaturescale " ) , 1 )
2024-03-23 23:39:02 +00:00
- > editable ( 0 , 1 , .1 , " Creature scale " , " " , ' C ' )
- > set_extra ( [ ] { dialog : : addInfo ( XLAT ( " changing this during shmup is counted as cheating " ) ) ; } )
- > set_reaction ( [ ] { if ( shmup : : on ) cheater + + ; } ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . height_width , parameter_names ( " heiwi " , " 3d-heightwidth " ) , 1.5 )
2021-01-31 19:45:00 +00:00
- > editable ( 0 , 1 , .1 , " Height to width " , " " , ' h ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . yshift , parameter_names ( " yshift " , " Y shift " ) , 0 )
2021-01-31 19:45:00 +00:00
- > editable ( 0 , 1 , .1 , " Y shift " , " Don't center on the player character. " , ' y ' )
- > set_extra ( [ ] {
if ( WDIM = = 3 & & pmodel = = mdPerspective )
dialog : : addBoolItem_action ( XLAT ( " reduce if walls on the way " ) , vid . use_wall_radar , ' R ' ) ;
} ) ;
2024-05-26 18:22:29 +00:00
param_b ( vid . use_wall_radar , " wallradar " , true ) ;
param_b ( vid . fixed_facing , " fixed facing " , 0 ) ;
param_f ( vid . fixed_facing_dir , " fixed facing dir " , 90 ) ;
2021-08-08 16:29:21 +00:00
param_b ( vid . fixed_yz , " fixed YZ " , true ) ;
2022-04-16 11:58:01 +00:00
param_b ( frustum_culling , " frustum_culling " ) ;
2022-05-21 15:10:04 +00:00
param_b ( numerical_minefield , " numerical_minefield " )
2024-05-07 20:18:54 +00:00
- > editable ( " toggle numerical display " , ' n ' ) ;
param_b ( mine_hollow , " mine_hollow " )
- > editable ( " hollow mine symbols " , ' h ' ) ;
param_b ( mine_markers , " mine_markers " )
- > editable ( " markers on possible mines " , ' m ' ) ;
param_i ( mine_opacity , " minefield opacity " , 255 )
- > editable ( 0 , 255 , 51 , " opacity of undiscovered minefield " , " 3D modes only \n \n 0 = invisible, 255 = fully opaque " , ' o ' ) ;
2024-05-26 18:22:29 +00:00
param_enum ( mine_zero_display , " minefield_zero " , 1 )
2024-05-07 20:18:54 +00:00
- > editable ( { { " OFF " , " never display zeros " } , { " 3D " , " only in 3D modes " } , { " ON " , " always display zeros " } } , " display zeros in minefield " , ' z ' ) ;
2022-05-17 07:43:45 +00:00
param_b ( dont_display_minecount , " dont_display_minecount " ) ;
2023-04-11 15:10:04 +00:00
# if MAXMDIM >= 4
2024-05-26 18:22:29 +00:00
param_enum ( draw_sky , " draw_sky " , skyAutomatic )
2023-02-18 17:32:01 +00:00
- > editable ( { { " NO " , " do not draw sky " } , { " automatic " , " " } , { " skybox " , " works only in Euclidean " } , { " always " , " might be glitched in some settings " } } , " sky rendering " , ' s ' ) ;
param_b ( use_euclidean_infinity , " use_euclidean_infinity " , true )
- > editable ( " infinite sky " , ' i ' ) ;
2023-04-11 15:10:04 +00:00
# endif
2021-09-30 11:23:35 +00:00
param_f ( linepatterns : : parallel_count , " parallel_count " )
- > editable ( 0 , 24 , 1 , " number of parallels drawn " , " " , ' n ' ) ;
param_f ( linepatterns : : parallel_max , " parallel_max " )
2022-11-12 21:38:45 +00:00
- > editable ( 0 , TAU , 15 * degree , " last parallel drawn " , " " , ' n ' ) ;
2023-03-16 13:45:11 +00:00
param_f ( linepatterns : : mp_ori , " mp_ori " )
- > editable ( 0 , TAU , 15 * degree , " parallel/meridian orientation " , " " , ' n ' ) ;
param_f ( linepatterns : : meridian_max , " meridian_max " ) ;
param_f ( linepatterns : : meridian_count , " meridian_count " ) ;
param_f ( linepatterns : : meridian_length , " meridian_length " ) ;
param_f ( linepatterns : : meridian_prec , " meridian_prec " ) ;
param_f ( linepatterns : : meridian_prec2 , " meridian_prec2 " ) ;
2023-03-16 13:44:31 +00:00
2023-03-24 23:36:20 +00:00
param_f ( linepatterns : : dual_length , " dual_length " ) ;
2023-08-14 16:11:48 +00:00
param_matrix ( linepatterns : : dual_angle . v2 , " dual_angle " , 2 ) ;
param_matrix ( linepatterns : : dual_angle . v3 , " dual_angle3 " , 3 ) ;
2023-03-24 23:36:20 +00:00
2023-03-16 13:44:31 +00:00
param_f ( twopoint_xscale , " twopoint_xscale " ) ;
param_i ( twopoint_xshape , " twopoint_xshape " ) ;
param_f ( twopoint_xwidth , " twopoint_xwidth " ) ;
2023-05-15 00:26:02 +00:00
param_f ( periodwidth , " periodwidth " , 1 ) ;
2023-03-16 13:44:31 +00:00
2023-05-30 16:37:37 +00:00
param_b ( draw_plain_floors , " draw_plain_floors " , false )
- > editable ( " draw plain floors in 3D " , ' p ' ) ;
param_i ( default_flooralpha , " floor_alpha " )
- > editable ( 0 , 255 , 15 , " floor alpha " , " 255 = opaque " , ' a ' ) ;
2021-10-15 20:36:43 +00:00
param_f ( vid . depth_bonus , " depth_bonus " , 0 )
2021-10-15 20:38:24 +00:00
- > editable ( - 5 , 5 , .1 , " depth bonus in pseudohedral " , " " , ' b ' ) ;
2024-05-26 18:22:29 +00:00
param_enum ( vid . pseudohedral , " pseudohedral " , phOFF )
2023-05-23 18:22:14 +00:00
- > editable (
{ { " OFF " , " the tiles are curved " } ,
{ " inscribed " , " the tiles are inscribed " } ,
{ " circumscribed " , " the tiles are circumscribed " } } ,
" make the tiles flat " , ' p ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . depth , parameter_names ( " depth " , " 3D depth " ) , 1 )
2021-01-31 19:45:00 +00:00
- > editable ( 0 , 5 , .1 , " Ground level below the plane " , " " , ' d ' )
- > set_extra ( [ ] {
vid . tc_depth = ticks ;
2020-11-06 14:40:59 +00:00
help = XLAT (
" Ground level is actually an equidistant surface, "
" %1 absolute units below the plane P. "
" Theoretically, this value affects the world -- "
" for example, eagles could fly %2 times faster by "
" flying above the ground level, on the plane P -- "
" but the actual game mechanics are not affected. " , fts ( vid . depth ) , fts ( cosh ( vid . depth ) ) ) ;
if ( GDIM = = 2 )
help + = XLAT (
" (Distances reported by the vector graphics editor "
" are not about points on the ground level, but "
" about the matching points on the plane P -- "
" divide them by the factor above to get actual "
" distances.) "
) ;
if ( GDIM = = 3 & & pmodel = = mdPerspective & & ! euclid ) {
2022-03-27 18:35:09 +00:00
ld current_camera_level = hdist0 ( tC0 ( current_display - > radar_transform ) ) ;
2020-11-06 14:40:59 +00:00
help + = " \n \n " ;
if ( abs ( current_camera_level ) < 1e-6 )
help + = XLAT (
" The camera is currently exactly on the plane P. "
" The horizon is seen as a straight line. "
) ;
else help + = XLAT (
" The camera is currently %1 units above the plane P. "
" This makes you see the floor level as in general perspective projection "
" with parameter %2. " , fts ( current_camera_level ) , fts ( tan_auto ( vid . depth ) / tan_auto ( current_camera_level ) ) ) ;
}
dialog : : addHelp ( help ) ;
2023-02-10 18:04:32 +00:00
} )
2023-02-10 22:39:49 +00:00
- > set_reaction ( [ ] {
bool b = vid . tc_alpha < vid . tc_camera ;
if ( vid . tc_alpha > = vid . tc_depth ) vid . tc_alpha = vid . depth - 1 ;
if ( vid . tc_camera > = vid . tc_depth ) vid . tc_camera = vid . depth - 1 ;
if ( vid . tc_alpha = = vid . tc_camera ) ( b ? vid . tc_alpha : vid . tc_camera ) - - ;
geom3 : : apply_settings_light ( ) ;
} ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . camera , parameter_names ( " camera " , " 3D camera level " ) , 1 )
2021-02-01 00:35:34 +00:00
- > editable ( 0 , 5 , .1 , " " , " " , ' c ' )
2024-05-26 18:22:29 +00:00
- > modif ( [ ] ( float_parameter * x ) { x - > menu_item_name = ( GDIM = = 2 ? " Camera level above the plane " : " Z shift " ) ; } )
2021-02-01 00:35:34 +00:00
- > set_extra ( [ ] {
vid . tc_camera = ticks ;
if ( GDIM = = 2 )
dialog : : addHelp ( XLAT (
" Camera is placed %1 absolute units above a plane P in a three-dimensional "
" world. Ground level is actually an equidistant surface, %2 absolute units "
" below the plane P. The plane P (as well as the ground level or any "
" other equidistant surface below it) is viewed at an angle of %3 "
" (the tangent of the angle between the point in "
" the center of your vision and a faraway location is 1/cosh(c) = %4). " ,
fts ( vid . camera ) ,
fts ( vid . depth ) ,
fts ( atan ( 1 / cosh ( vid . camera ) ) * 2 / degree ) ,
fts ( 1 / cosh ( vid . camera ) ) ) ) ;
if ( GDIM = = 3 )
dialog : : addHelp ( XLAT ( " Look from behind. " ) ) ;
if ( GDIM = = 3 & & pmodel = = mdPerspective )
dialog : : addBoolItem_action ( XLAT ( " reduce if walls on the way " ) , vid . use_wall_radar , ' R ' ) ;
} ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . wall_height , parameter_names ( " wall_height " , " 3D wall height " ) , .3 )
2021-02-01 00:35:34 +00:00
- > editable ( 0 , 1 , .1 , " Height of walls " , " " , ' w ' )
- > set_extra ( [ ] ( ) {
2020-11-06 14:40:59 +00:00
dialog : : addHelp ( GDIM = = 3 ? " " : XLAT (
" The height of walls, in absolute units. For the current values of g and c, "
" wall height of %1 absolute units corresponds to projection value of %2. " ,
2021-02-01 00:35:34 +00:00
fts ( geom3 : : actual_wall_height ( ) ) , fts ( geom3 : : factor_to_projection ( cgi . WALL ) ) ) ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBoolItem ( XLAT ( " auto-adjust in Goldberg grids " ) , vid . gp_autoscale_heights , ' O ' ) ;
dialog : : add_action ( [ ] ( ) {
vid . gp_autoscale_heights = ! vid . gp_autoscale_heights ;
} ) ;
2023-02-10 18:04:32 +00:00
} )
- > set_reaction ( geom3 : : apply_settings_light ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . rock_wall_ratio , parameter_names ( " rock_wall_ratio " , " 3D rock-wall ratio " ) , .9 )
2021-02-01 00:35:34 +00:00
- > editable ( 0 , 1 , .1 , " Rock-III to wall ratio " , " " , ' r ' )
- > set_extra ( [ ] { dialog : : addHelp ( XLAT (
2020-11-06 14:40:59 +00:00
" The ratio of Rock III to walls is %1, so Rock III are %2 absolute units high. "
" Length of paths on the Rock III level is %3 of the corresponding length on the "
" ground level. " ,
fts ( vid . rock_wall_ratio ) , fts ( vid . wall_height * vid . rock_wall_ratio ) ,
fts ( cosh ( vid . depth - vid . wall_height * vid . rock_wall_ratio ) / cosh ( vid . depth ) ) ) ) ;
2021-02-01 00:35:34 +00:00
} ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . human_wall_ratio , parameter_names ( " human_wall_ratio " , " 3D human-wall ratio " ) , .7 )
2021-02-01 00:35:34 +00:00
- > editable ( 0 , 1 , .1 , " Human to wall ratio " , " " , ' h ' )
- > set_extra ( [ ] { dialog : : addHelp ( XLAT (
2020-11-06 14:40:59 +00:00
" Humans are %1 "
" absolute units high. Your head travels %2 times the distance travelled by your "
" feet. " ,
fts ( vid . wall_height * vid . human_wall_ratio ) ,
fts ( cosh ( vid . depth - vid . wall_height * vid . human_wall_ratio ) / cosh ( vid . depth ) ) )
) ;
2021-02-01 00:35:34 +00:00
} ) ;
2023-02-19 00:00:15 +00:00
string unitwarn =
2023-12-27 09:40:04 +00:00
" The unit this value is given in is wall height. "
2023-02-19 00:00:15 +00:00
" Note that, in exponentially expanding spaces, too high values could cause rendering issues. So "
" if you want infinity, values of 5 or similar should be used -- there is no visible difference "
" from infinity and glitches are avoided. " ;
2024-05-26 18:22:29 +00:00
param_f ( vid . lake_top , parameter_names ( " lake_top " , " 3D lake top " ) , .25 / 0.3 )
2023-02-19 00:00:15 +00:00
- > editable ( 0 , 1 , .1 , " Level of water surface " , unitwarn , ' l ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . lake_shallow , parameter_names ( " lake_shallow " , " 3D lake shallow " ) , .4 / 0.3 )
2023-02-19 00:00:15 +00:00
- > editable ( 0 , 1 , .1 , " Level of shallow water " , unitwarn , ' s ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . lake_bottom , parameter_names ( " lake_bottom " , " 3D lake bottom " ) , .9 / 0.3 )
2023-02-19 00:00:15 +00:00
- > editable ( 0 , 1 , .1 , " Level of water bottom " , unitwarn , ' k ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . wall_height2 , " wall_height2 " , 2 )
2023-02-19 00:00:15 +00:00
- > editable ( 0 , 5 , .1 , " ratio of high walls to normal walls " , unitwarn , ' 2 ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . wall_height3 , " wall_height3 " , 3 )
2023-02-19 00:00:15 +00:00
- > editable ( 0 , 5 , .1 , " ratio of very high walls to normal walls " , unitwarn , ' 3 ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . lowsky_height , " lowsky_height " , 2 )
2023-02-19 00:00:15 +00:00
- > editable ( 0 , 5 , .1 , " sky fake height " , " Sky is rendered at the distance computed based on "
" the sky height, which might be beyond the range visible in fog. To prevent this, "
" the intensity of the fog effect depends on the value here rather than the actual distance. "
" Stars are affected similarly. " , ' 4 ' ) ;
2023-04-11 15:10:40 +00:00
# if MAXMDIM >= 4
2023-02-19 00:00:15 +00:00
param_fd ( vid . sky_height , " sky_height " )
- > set_hint ( [ ] { return geom3 : : to_wh ( cgi . SKY ) ; } )
- > editable ( 0 , 10 , .1 , " altitude of the sky " , unitwarn , ' 5 ' )
- > set_reaction ( delete_sky ) ;
2023-04-11 15:10:04 +00:00
# endif
2023-02-19 00:00:15 +00:00
param_fd ( vid . star_height , " star_height " )
- > set_hint ( [ ] { return geom3 : : to_wh ( cgi . STAR ) ; } )
- > editable ( 0 , 10 , .1 , " altitude of the stars " , unitwarn , ' 6 ' ) ;
param_fd ( vid . infdeep_height , " infdeep_height " )
- > set_hint ( [ ] { return geom3 : : to_wh ( cgi . INFDEEP ) ; } )
- > editable ( 0 , 10 , .1 , " infinite depth " , unitwarn , ' 7 ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . sun_size , " sun_size " , 8 )
2023-02-18 17:32:01 +00:00
- > editable ( 0 , 10 , .1 , " sun size (relative to item sizes) " , " " , ' 8 ' ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . star_size , " star_size " , 0.75 )
2023-02-18 17:32:01 +00:00
- > editable ( 0 , 10 , .1 , " night star size (relative to item sizes) " , " " , ' 9 ' ) ;
2023-04-11 15:10:04 +00:00
# if MAXMDIM >= 4
2023-02-18 18:33:27 +00:00
param_f ( star_prob , " star_prob " , 0.3 )
- > editable ( 0 , 1 , .01 , " star probability " , " probability of star per tile " , ' * ' ) ;
2023-04-11 15:10:04 +00:00
# endif
2023-02-18 17:32:01 +00:00
param_b ( vid . height_limits , " height_limits " , true )
2023-02-19 00:00:15 +00:00
- > editable ( " prevent exceeding recommended altitudes " , ' l ' ) ;
2023-02-18 17:32:01 +00:00
param_b ( auto_remove_roofs , " auto_remove_roofs " , true )
- > editable ( " do not render higher levels if camera too high " , ' r ' ) ;
2024-05-26 18:22:29 +00:00
param_i ( vid . tc_depth , " 3D TC depth " , 1 ) ;
param_i ( vid . tc_camera , " 3D TC camera " , 2 ) ;
param_i ( vid . tc_alpha , " 3D TC alpha " , 3 ) ;
param_f ( vid . highdetail , parameter_names ( " highdetail " , " 3D highdetail " ) , 8 )
2021-02-01 00:35:34 +00:00
- > editable ( 0 , 5 , .5 , " High detail range " , " " , ' n ' )
- > set_extra ( explain_detail )
- > set_reaction ( [ ] {
if ( vid . highdetail > vid . middetail ) vid . middetail = vid . highdetail ;
} ) ;
2024-05-26 18:22:29 +00:00
param_f ( vid . middetail , parameter_names ( " middetail " , " 3D middetail " ) , 8 )
2021-02-01 00:35:34 +00:00
- > editable ( 0 , 5 , .5 , " Mid detail range " , " " , ' m ' )
- > set_extra ( explain_detail )
- > set_reaction ( [ ] {
if ( vid . highdetail > vid . middetail ) vid . highdetail = vid . middetail ;
} ) ;
2022-10-06 09:59:34 +00:00
param_i ( debug_tiles , " debug_tiles " ) - > editable ( 0 , 2 , 1 ,
" display tile debug values " ,
" Display cell type IDs, as well as vertex and edge identifiers. \n \n "
" Setting 1 uses the internal shape IDs, while setting 2 in tes files uses "
" the original IDs in case if extra tile types were added to "
" separate mirror images or different football types. " , ' d ' ) ;
2023-09-14 15:36:31 +00:00
param_b ( debug_voronoi , " debug_voronoi " ) - > editable (
" display Voronoi tie debug values " , ' d ' ) ;
2023-09-18 09:09:06 +00:00
param_i ( horodisk_from , " horodisk_from " , - 2 ) - > editable ( - 10 , 10 , 1 ,
" land size in horodisk mode " ,
" Set this to -2 to get perfect horodisks. Smaller values yield less dense horodisks, and "
" larger values might produce horodisks with errors or crashing into each other. " , ' H ' ) ;
2023-09-22 10:55:17 +00:00
param_i ( randomwalk_size , " randomwalk_size " , 10 ) - > editable ( 2 , 100 , 1 ,
" land size in randomwalk mode " ,
2024-03-21 19:15:45 +00:00
" The average size of a land in randomwalk mode. " , ' R ' )
- > set_reaction ( [ ] { if ( game_active ) { stop_game ( ) ; start_game ( ) ; } } ) ;
2024-03-21 21:50:42 +00:00
param_i ( landscape_div , " landscape_div " ) - > editable ( 1 , 100 , 1 ,
" land size in landscape structure " ,
" Each cell gets three coordinates, each of which change smoothly, using the same method as used for the generation of landscapes e.g. in Dragon Chasms. "
" Then, we find a cell of the bitruncated cubic honeycomb at these cordinates, and this cell determines which land it is. The bigger the value, the larger the lands. " , ' R ' )
2024-05-05 13:19:52 +00:00
- > set_sets ( [ ] { dialog : : bound_low ( 1 ) ; } )
2024-03-21 19:15:45 +00:00
- > set_reaction ( [ ] { if ( game_active ) { stop_game ( ) ; start_game ( ) ; } } ) ;
2024-04-06 16:33:29 +00:00
param_i ( curse_percentage , " curse_percentage " ) - > editable ( 0 , 100 , 1 ,
" curse percentage " ,
" The percentage of towers in Cursed Walls mode to be manned by Canyon Hags " , ' R ' )
- > set_reaction ( [ ] { if ( game_active ) { stop_game ( ) ; start_game ( ) ; } } ) ;
2023-09-18 09:09:06 +00:00
2022-10-06 10:26:17 +00:00
param_f ( global_boundary_ratio , " global_boundary_ratio " )
- > editable ( 0 , 5 , 0.1 , " Width of cell boundaries " ,
2023-02-21 17:53:01 +00:00
" How wide should the cell boundaries be. " , ' 0 ' ) ;
2024-05-26 18:22:29 +00:00
param_b ( vid . gp_autoscale_heights , " 3D Goldberg autoscaling " , true ) ;
2024-05-28 13:08:30 +00:00
auto scf = param_str ( scorefile , " savefile " ) ;
2024-05-29 11:51:20 +00:00
scf - > be_non_editable ( ) ; scf - > reaction = [ ] { if ( save_loaded ) exit ( 1 ) ; } ;
2022-09-15 10:38:39 +00:00
param_b ( savefile_selection , " savefile_selection " )
- > editable ( " select the score/save file on startup " , ' s ' )
- > set_reaction ( [ ] {
if ( savefile_selection )
addMessage ( XLAT ( " Save the config and restart to select another score/save file. " ) ) ;
else if ( scorefile = = " " )
addMessage ( XLAT ( " Save the config to always play without recording your progress. " ) ) ;
else
addMessage ( XLAT ( " Save the config to always use %1. " , scorefile ) ) ;
} ) ;
2024-05-26 18:38:31 +00:00
param_ccolor ( ccolor : : which , " pattern " ) ;
2024-05-27 11:37:18 +00:00
param_b ( ccolor : : live_canvas , " live_canvas " )
- > editable ( " apply color/pattern changes to canvas automatically " , ' l ' ) ;
2024-05-28 13:08:30 +00:00
param_str ( ccolor : : color_formula , " color_formula " )
- > editor = [ ] { ccolor : : config_formula ( false ) ; } ;
2021-02-01 00:35:34 +00:00
} ) ;
2020-11-06 14:40:59 +00:00
EX void switchcolor ( unsigned int & c , unsigned int * cs ) {
dialog : : openColorDialog ( c , cs ) ;
}
2021-02-01 02:11:15 +00:00
2020-11-06 14:40:59 +00:00
double cc_footphase ;
int lmousex , lmousey ;
EX void showCustomizeChar ( ) {
cc_footphase + = hypot ( mousex - lmousex , mousey - lmousey ) ;
lmousex = mousex ; lmousey = mousey ;
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " Customize character " ) ) ;
if ( shmup : : on | | multi : : players ) multi : : cpid = multi : : cpid_edit % multi : : players ;
charstyle & cs = getcs ( ) ;
dialog : : addSelItem ( XLAT ( " character " ) , csname ( cs ) , ' g ' ) ;
dialog : : addColorItem ( XLAT ( " skin color " ) , cs . skincolor , ' s ' ) ;
dialog : : addColorItem ( XLAT ( " eye color " ) , cs . eyecolor , ' e ' ) ;
dialog : : addColorItem ( XLAT ( " weapon color " ) , cs . swordcolor , ' w ' ) ;
dialog : : addColorItem ( XLAT ( " hair color " ) , cs . haircolor , ' h ' ) ;
2023-10-27 21:26:16 +00:00
if ( bow : : crossbow_mode ( ) ) {
dialog : : addColorItem ( XLAT ( " bow color " ) , cs . bowcolor , ' b ' ) ;
2023-12-03 13:29:08 +00:00
dialog : : addColorItem ( XLAT ( " bowstring color " ) , cs . bowcolor2 , ' c ' ) ;
2023-10-27 21:26:16 +00:00
}
2020-11-06 14:40:59 +00:00
if ( cs . charid > = 1 ) dialog : : addColorItem ( XLAT ( " dress color " ) , cs . dresscolor , ' d ' ) ;
else dialog : : addBreak ( 100 ) ;
if ( cs . charid = = 3 ) dialog : : addColorItem ( XLAT ( " dress color II " ) , cs . dresscolor2 , ' f ' ) ;
else dialog : : addBreak ( 100 ) ;
dialog : : addColorItem ( XLAT ( " movement color " ) , cs . uicolor , ' u ' ) ;
if ( ! shmup : : on & & multi : : players = = 1 ) dialog : : addSelItem ( XLAT ( " save whom " ) , XLAT1 ( minf [ moPrincess ] . name ) , ' p ' ) ;
if ( numplayers ( ) > 1 ) dialog : : addSelItem ( XLAT ( " player " ) , its ( multi : : cpid + 1 ) , ' a ' ) ;
dialog : : addBoolItem ( XLAT ( " left-handed " ) , cs . lefthanded , ' l ' ) ;
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
int firsty = dialog : : items [ 0 ] . position / 2 ;
int scale = firsty - 2 * vid . fsize ;
flat_model_enabler fme ;
initquickqueue ( ) ;
transmatrix V = atscreenpos ( vid . xres / 2 , firsty , scale ) ;
2022-11-12 21:38:45 +00:00
double alpha = atan2 ( mousex - vid . xres / 2 , mousey - firsty ) - 90. _deg ;
2020-11-06 14:40:59 +00:00
V = V * spin ( alpha ) ;
drawMonsterType ( moPlayer , NULL , shiftless ( V ) , 0 , cc_footphase / scale , NOCOLOR ) ;
quickqueue ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
if ( shmup : : on | | multi : : players ) multi : : cpid = multi : : cpid_edit % multi : : players ;
charstyle & cs = getcs ( ) ;
bool cat = cs . charid > = 4 ;
if ( uni = = ' a ' ) { multi : : cpid_edit + + ; multi : : cpid_edit % = 60 ; }
else if ( uni = = ' g ' ) {
cs . charid + + ;
if ( cs . charid = = 2 & & ! princess : : everSaved & & ! autocheat ) cs . charid = 4 ;
cs . charid % = 10 ;
}
else if ( uni = = ' p ' ) vid . samegender = ! vid . samegender ;
else if ( uni = = ' s ' ) switchcolor ( cs . skincolor , cat ? haircolors : skincolors ) ;
else if ( uni = = ' h ' ) switchcolor ( cs . haircolor , haircolors ) ;
else if ( uni = = ' w ' ) switchcolor ( cs . swordcolor , swordcolors ) ;
else if ( uni = = ' d ' ) switchcolor ( cs . dresscolor , cat ? haircolors : dresscolors ) ;
else if ( uni = = ' f ' ) switchcolor ( cs . dresscolor2 , dresscolors2 ) ;
else if ( uni = = ' u ' ) switchcolor ( cs . uicolor , eyecolors ) ;
else if ( uni = = ' e ' ) switchcolor ( cs . eyecolor , eyecolors ) ;
else if ( uni = = ' l ' ) cs . lefthanded = ! cs . lefthanded ;
2023-10-27 21:26:16 +00:00
else if ( uni = = ' b ' ) switchcolor ( cs . bowcolor , swordcolors ) ;
else if ( uni = = ' c ' ) switchcolor ( cs . bowcolor2 , eyecolors ) ;
2020-11-06 14:40:59 +00:00
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
2024-05-27 11:37:18 +00:00
EX void refresh_canvas ( ) { ccolor : : live_canvas = true ; }
2020-11-06 14:40:59 +00:00
2022-07-05 12:02:45 +00:00
EX color_t addalpha ( color_t c ) { return ( c < < 8 ) | 0xFF ; }
2020-11-06 14:40:59 +00:00
EX void edit_color_table ( colortable & ct , const reaction_t & r IS ( reaction_t ( ) ) , bool has_bit IS ( false ) ) {
cmode = sm : : SIDE ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " colors & aura " ) ) ;
for ( int i = 0 ; i < isize ( ct ) ; i + + ) {
2022-07-05 12:02:45 +00:00
dialog : : addColorItem ( its ( i ) , addalpha ( ct [ i ] ) , ' a ' + i ) ;
2020-11-06 14:40:59 +00:00
if ( WDIM = = 3 & & has_bit & & ! ( ct [ i ] & 0x1000000 ) ) dialog : : lastItem ( ) . value = XLAT ( " (no wall) " ) ;
dialog : : add_action ( [ i , & ct , r , has_bit ] ( ) {
if ( WDIM = = 3 & & has_bit ) {
ct [ i ] ^ = 0x1000000 ;
if ( ! ( ct [ i ] & 0x1000000 ) ) return ;
}
2024-05-10 16:37:05 +00:00
dialog : : openColorDialog ( ct [ i ] ) ;
if ( r ) dialog : : get_di ( ) . reaction = r ;
2020-11-06 14:40:59 +00:00
dialog : : colorAlpha = false ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags | = sm : : SIDE ;
2020-11-06 14:40:59 +00:00
} ) ;
}
2022-10-06 11:46:15 +00:00
dialog : : addItem ( " add a color " , ' A ' ) ;
dialog : : add_action ( [ & ct , r ] {
ct . push_back ( rand ( ) & 0x1FFFFFF ) ;
2024-05-10 16:37:05 +00:00
if ( r ) r ( ) ;
2022-10-06 11:46:15 +00:00
} ) ;
if ( isize ( ct ) > 2 ) {
dialog : : addItem ( " delete a color " , ' D ' ) ;
dialog : : add_action ( [ & ct , r ] {
ct . pop_back ( ) ;
2024-05-10 16:37:05 +00:00
if ( r ) r ( ) ;
2022-10-06 11:46:15 +00:00
} ) ;
}
2020-11-06 14:40:59 +00:00
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
EX void show_color_dialog ( ) {
cmode = sm : : SIDE | sm : : DIALOG_STRICT_X ;
getcstat = ' - ' ;
2022-07-05 09:51:06 +00:00
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " colors & aura " ) ) ;
2022-07-05 12:02:45 +00:00
dialog : : addColorItem ( XLAT ( " background " ) , addalpha ( backcolor ) , ' b ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( backcolor ) ; dialog : : colorAlpha = false ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
if ( WDIM = = 2 & & GDIM = = 3 & & hyperbolic )
dialog : : addBoolItem_action ( XLAT ( " cool fog effect " ) , context_fog , ' B ' ) ;
2022-07-05 12:02:45 +00:00
dialog : : addColorItem ( XLAT ( " foreground " ) , addalpha ( forecolor ) , ' f ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( forecolor ) ; dialog : : colorAlpha = false ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
2022-07-05 12:02:45 +00:00
dialog : : addColorItem ( XLAT ( " borders " ) , addalpha ( bordcolor ) , ' o ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( bordcolor ) ; dialog : : colorAlpha = false ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addColorItem ( XLAT ( " projection boundary " ) , ringcolor , ' r ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( ringcolor ) ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " boundary width multiplier " ) , fts ( vid . multiplier_ring ) , ' R ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( vid . multiplier_ring , 0 , 10 , 1 , 1 , XLAT ( " boundary width multiplier " ) , " " ) ; } ) ;
dialog : : addColorItem ( XLAT ( " projection background " ) , modelcolor , ' c ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( modelcolor ) ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addColorItem ( XLAT ( " standard grid color " ) , stdgridcolor , ' g ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { vid . grid = true ; dialog : : openColorDialog ( stdgridcolor ) ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addSelItem ( XLAT ( " grid width multiplier " ) , fts ( vid . multiplier_grid ) , ' G ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( vid . multiplier_grid , 0 , 10 , 1 , 1 , XLAT ( " grid width multiplier " ) , " " ) ; } ) ;
dialog : : addSelItem ( XLAT ( " brightness behind the sphere " ) , fts ( backbrightness ) , ' i ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( backbrightness , 0 , 1 , .01 , 0.25 , XLAT ( " brightness behind the sphere " ) ,
XLAT ( " In the orthogonal projection, objects on the other side of the sphere are drawn darker. " ) ) ; dialog : : bound_low ( 0 ) ; } ) ;
dialog : : addColorItem ( XLAT ( " projection period " ) , periodcolor , ' p ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( periodcolor ) ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
2022-07-05 12:02:45 +00:00
dialog : : addColorItem ( XLAT ( " dialogs " ) , addalpha ( dialog : : dialogcolor ) , ' d ' ) ;
2023-08-09 12:01:24 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( dialog : : dialogcolor ) ; dialog : : colorAlpha = false ; dialog : : get_di ( ) . dialogflags | = sm : : SIDE ; } ) ;
2020-11-06 14:40:59 +00:00
dialog : : addBreak ( 50 ) ;
2024-05-05 18:15:53 +00:00
if ( specialland = = laCanvas & & ccolor : : which - > ctab . size ( ) ) {
2020-11-06 14:40:59 +00:00
dialog : : addItem ( XLAT ( " pattern colors " ) , ' P ' ) ;
2024-05-05 18:15:53 +00:00
dialog : : add_action_push ( [ ] { edit_color_table ( ccolor : : which - > ctab , refresh_canvas , true ) ; } ) ;
2022-10-06 11:37:21 +00:00
2024-05-05 18:15:53 +00:00
if ( ccolor : : which = = & ccolor : : shape_mirror ) {
2022-10-06 11:37:21 +00:00
dialog : : addItem ( XLAT ( " unreversed colors " ) , ' U ' ) ;
2024-05-05 18:15:53 +00:00
dialog : : add_action_push ( [ ] { edit_color_table ( ccolor : : shape . ctab , refresh_canvas , true ) ; } ) ;
2022-10-06 11:37:21 +00:00
}
2024-05-27 11:37:18 +00:00
add_edit ( ccolor : : live_canvas ) ;
2020-11-06 14:40:59 +00:00
}
if ( cwt . at - > land = = laMinefield ) {
dialog : : addItem ( XLAT ( " minefield colors " ) , ' m ' ) ;
dialog : : add_action_push ( [ ] { edit_color_table ( minecolors ) ; } ) ;
}
if ( viewdists ) {
dialog : : addItem ( XLAT ( " distance colors " ) , ' d ' ) ;
dialog : : add_action_push ( [ ] ( ) { edit_color_table ( distcolors ) ; } ) ;
}
# if CAP_CRYSTAL
if ( cryst & & cheater ) {
dialog : : addItem ( XLAT ( " crystal coordinate colors " ) , ' C ' ) ;
dialog : : add_action ( [ ] ( ) { crystal : : view_coordinates = true ; pushScreen ( [ ] ( ) { edit_color_table ( crystal : : coordcolors ) ; } ) ; } ) ;
}
# endif
if ( cwt . at - > land = = laTortoise ) {
dialog : : addBoolItem_action ( XLAT ( " Galápagos shading " ) , tortoise : : shading_enabled , ' T ' ) ;
}
dialog : : addInfo ( XLAT ( " colors of some game objects can be edited by clicking them. " ) ) ;
dialog : : addBreak ( 50 ) ;
dialog : : addSelItem ( XLAT ( " aura brightness " ) , its ( vid . aurastr ) , ' a ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( vid . aurastr , 0 , 256 , 10 , 128 , XLAT ( " aura brightness " ) , " " ) ; dialog : : bound_low ( 0 ) ; } ) ;
dialog : : addSelItem ( XLAT ( " aura smoothening factor " ) , its ( vid . aurasmoothen ) , ' s ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( vid . aurasmoothen , 1 , 180 , 1 , 5 , XLAT ( " aura smoothening factor " ) , " " ) ; dialog : : bound_low ( 1 ) ; } ) ;
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
if ( uni = = ' - ' ) {
cell * c = mouseover ;
if ( ! c ) return ;
else if ( c = = cwt . at ) {
pushScreen ( showCustomizeChar ) ;
return ;
}
else if ( c - > monst )
dialog : : openColorDialog ( minf [ c - > monst ] . color ) ;
else if ( c - > item )
dialog : : openColorDialog ( iinf [ c - > item ] . color ) ;
else if ( c - > wall )
dialog : : openColorDialog ( winf [ c - > wall = = waMineMine ? waMineUnknown : c - > wall ] . color ) ;
# if CAP_COMPLEX2
else if ( c - > land = = laBrownian )
dialog : : openColorDialog ( brownian : : get_color_edit ( c - > landparam ) ) ;
# endif
else
dialog : : openColorDialog ( floorcolors [ c - > land ] ) ;
dialog : : colorAlpha = false ;
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . dialogflags | = sm : : SIDE ;
2020-11-06 14:40:59 +00:00
return ;
}
else dialog : : handleNavigation ( sym , uni ) ;
if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
# if CAP_CONFIG
EX void resetConfigMenu ( ) {
dialog : : init ( XLAT ( " reset all configuration " ) ) ;
dialog : : addInfo ( " Are you sure? " ) ;
dialog : : addItem ( " yes, and delete the config file " , ' d ' ) ;
dialog : : addItem ( " yes " , ' y ' ) ;
dialog : : addItem ( " cancel " , ' n ' ) ;
dialog : : addItem ( " reset the special game modes " , ' r ' ) ;
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
if ( uni = = ' d ' ) {
resetConfig ( ) ;
unlink ( conffile ) ;
popScreen ( ) ;
}
else if ( uni = = ' y ' ) {
printf ( " resetting config \n " ) ;
resetConfig ( ) ;
printf ( " config reset \n " ) ;
popScreen ( ) ;
}
else if ( uni = = ' r ' )
resetModes ( ) ;
else if ( uni = = ' n ' | | doexiton ( sym , uni ) )
popScreen ( ) ;
} ;
}
# endif
# if CAP_TRANS
EX void selectLanguageScreen ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( " select language " ) ; // intentionally not translated
int v = vid . language ;
dynamicval < int > d ( vid . language , - 1 ) ;
2022-07-01 18:04:45 +00:00
for ( int i = 0 ; i < NUMLAN ; i + + ) {
2020-11-06 14:40:59 +00:00
vid . language = i ;
dialog : : addSelItem ( XLAT ( " EN " ) , its ( 100 * transcompleteness [ i ] / transcompleteness [ 0 ] ) + " % " , ' a ' + i ) ;
}
dialog : : addBreak ( 50 ) ;
vid . language = - 1 ;
dialog : : addBoolItem ( XLAT ( " default " ) + " : " + XLAT ( " EN " ) , v = = - 1 , ' 0 ' ) ;
dialog : : addBack ( ) ;
dialog : : addBreak ( 50 ) ;
vid . language = v ;
if ( lang ( ) > = 1 )
dialog : : addHelp ( XLAT ( " add credits for your translation here " ) ) ;
else
dialog : : addHelp ( XLAT ( " original language " ) ) ;
if ( lang ( ) ! = 0 ) {
string tw = " " ;
string s = XLAT ( " TRANSLATIONWARNING " ) ;
if ( s ! = " " & & s ! = " TRANSLATIONWARNING " ) tw + = s ;
s = XLAT ( " TRANSLATIONWARNING2 " ) ;
if ( s ! = " " & & s ! = " TRANSLATIONWARNING2 " ) { if ( tw ! = " " ) tw + = " " ; tw + = s ; }
if ( tw ! = " " ) {
dialog : : addHelp ( tw ) ;
dialog : : lastItem ( ) . color = 0xFF0000 ;
}
}
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
if ( uni = = ' 0 ' ) {
vid . language = - 1 ;
2021-02-06 00:39:18 +00:00
android_settings_changed ( ) ;
2020-11-06 14:40:59 +00:00
}
else if ( uni > = ' a ' & & uni < ' a ' + NUMLAN ) {
vid . language = uni - ' a ' ;
2021-02-06 00:39:18 +00:00
android_settings_changed ( ) ;
2020-11-06 14:40:59 +00:00
}
else if ( doexiton ( sym , uni ) )
popScreen ( ) ;
} ;
}
# endif
EX void configureMouse ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " mouse & touchscreen " ) ) ;
dialog : : addBoolItem_action ( XLAT ( " reverse pointer control " ) , ( vid . revcontrol ) , ' r ' ) ;
dialog : : addBoolItem_action ( XLAT ( " draw circle around the target " ) , ( vid . drawmousecircle ) , ' d ' ) ;
if ( GDIM = = 3 ) {
dialog : : addBoolItem_action ( XLAT ( " highlight the cell forward " ) , vid . axes3 , ' f ' ) ;
}
# if ISMOBILE
dialog : : addBoolItem ( XLAT ( " targetting ranged Orbs long-click only " ) , ( vid . shifttarget & 2 ) , ' i ' ) ;
# else
dialog : : addBoolItem ( XLAT ( " targetting ranged Orbs Shift+click only " ) , ( vid . shifttarget & 1 ) , ' i ' ) ;
# endif
dialog : : add_action ( [ ] { vid . shifttarget = vid . shifttarget ^ 3 ; } ) ;
# if !ISMOBILE
dialog : : addBoolItem_action ( XLAT ( " quick mouse " ) , vid . quickmouse , ' M ' ) ;
# endif
dialog : : addSelItem ( XLAT ( " move by clicking on compass " ) , its ( vid . mobilecompasssize ) , ' C ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . mobilecompasssize , 0 , 100 , 10 , 20 , XLAT ( " compass size " ) , XLAT ( " 0 to disable " ) ) ;
// we need to check the moves
2023-08-09 12:01:24 +00:00
dialog : : get_di ( ) . reaction = checkmove ;
2020-11-06 14:40:59 +00:00
dialog : : bound_low ( 0 ) ;
} ) ;
# if CAP_ORIENTATION
if ( GDIM = = 2 ) {
dialog : : addSelItem ( XLAT ( " scrolling by device rotation " ) , ors : : choices [ ors : : mode ] , ' 1 ' ) ;
dialog : : add_action_push ( ors : : show ) ;
}
# endif
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2024-05-26 18:22:29 +00:00
vector < parameter * > last_changed ;
2021-01-31 18:55:33 +00:00
2024-05-26 18:22:29 +00:00
EX void add_to_changed ( parameter * f ) {
2021-02-01 14:10:03 +00:00
auto orig_f = f ;
2021-01-31 18:55:33 +00:00
for ( int i = 0 ; i < isize ( last_changed ) ; i + + ) {
if ( last_changed [ i ] = = f )
return ;
swap ( last_changed [ i ] , f ) ;
2021-02-01 14:10:03 +00:00
if ( f = = orig_f ) return ;
2021-01-31 18:55:33 +00:00
}
last_changed . push_back ( f ) ;
}
2024-05-26 18:22:29 +00:00
EX parameter * find_edit ( void * val ) {
2021-02-01 14:10:03 +00:00
for ( auto & fs : params ) {
fs . second - > check_change ( ) ;
2021-02-01 12:42:12 +00:00
if ( fs . second - > affects ( val ) )
return & * fs . second ;
2021-02-01 14:10:03 +00:00
}
2021-02-01 12:42:12 +00:00
return nullptr ;
}
2021-02-01 00:35:34 +00:00
EX void add_edit_ptr ( void * val ) {
int found = 0 ;
2021-02-01 14:10:03 +00:00
for ( auto & fs : params ) {
fs . second - > check_change ( ) ;
2021-02-01 00:35:34 +00:00
if ( fs . second - > affects ( val ) )
fs . second - > show_edit_option ( ) , found + + ;
2021-02-01 14:10:03 +00:00
}
2021-02-01 00:35:34 +00:00
if ( found ! = 1 ) println ( hlog , " found = " , found ) ;
}
2023-11-30 11:25:13 +00:00
EX void add_edit_ptr ( void * val , char key ) {
int found = 0 ;
for ( auto & fs : params ) {
fs . second - > check_change ( ) ;
if ( fs . second - > affects ( val ) )
fs . second - > show_edit_option ( key ) , found + + ;
}
if ( found ! = 1 ) println ( hlog , " found = " , found ) ;
}
2021-02-01 00:35:34 +00:00
# if HDR
template < class T > void add_edit ( T & val ) {
add_edit_ptr ( & val ) ;
2021-01-31 18:55:33 +00:00
}
2023-11-30 11:25:13 +00:00
template < class T > void add_edit ( T & val , char key ) {
add_edit_ptr ( & val , key ) ;
}
2021-02-01 00:35:34 +00:00
# endif
2021-01-31 18:55:33 +00:00
2024-05-26 18:22:29 +00:00
EX void find_parameter ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2021-01-31 18:55:33 +00:00
2021-05-24 09:42:46 +00:00
dialog : : init ( XLAT ( " find a setting " ) ) ;
2021-01-31 18:55:33 +00:00
if ( dialog : : infix ! = " " ) mouseovers = dialog : : infix ;
2022-10-21 09:30:51 +00:00
dialog : : start_list ( 900 , 900 , ' 1 ' ) ;
int found = 0 ;
2021-01-31 18:55:33 +00:00
for ( auto & p : params ) {
auto & fs = p . second ;
2021-02-01 00:35:34 +00:00
string key = fs - > search_key ( ) ;
2022-10-21 09:30:51 +00:00
if ( fs - > available ( ) & & dialog : : hasInfix ( key ) ) {
fs - > show_edit_option ( dialog : : list_fake_key + + ) ;
found + + ;
2021-01-31 18:55:33 +00:00
}
}
2022-10-21 09:30:51 +00:00
dialog : : end_list ( ) ;
2021-02-01 14:10:03 +00:00
dialog : : addBreak ( 100 ) ;
2021-05-28 22:11:04 +00:00
dialog : : addInfo ( XLAT ( " press letters to search " ) ) ;
2022-10-21 09:30:51 +00:00
dialog : : addSelItem ( XLAT ( " matching items " ) , its ( found ) , 0 ) ;
2021-01-31 18:55:33 +00:00
dialog : : display ( ) ;
2022-10-21 09:30:51 +00:00
2021-01-31 18:55:33 +00:00
keyhandler = [ ] ( int sym , int uni ) {
2022-10-21 10:47:20 +00:00
dialog : : handleNavigation ( sym , uni ) ;
if ( dialog : : editInfix ( uni ) ) dialog : : list_skip = 0 ;
2021-01-31 18:55:33 +00:00
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
2024-05-26 18:22:29 +00:00
EX void edit_all_parameters ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2021-02-01 14:10:03 +00:00
dialog : : init ( XLAT ( " recently changed settings " ) ) ;
for ( auto & fs : params ) fs . second - > check_change ( ) ;
2021-01-31 18:55:33 +00:00
2022-10-21 17:25:03 +00:00
dialog : : start_list ( 1000 , 1000 , ' a ' ) ;
2021-01-31 18:55:33 +00:00
for ( auto l : last_changed )
2022-10-21 17:25:03 +00:00
if ( l - > available ( ) )
l - > show_edit_option ( dialog : : list_fake_key + + ) ;
dialog : : end_list ( ) ;
2021-01-31 18:55:33 +00:00
dialog : : addBreak ( 100 ) ;
dialog : : addItem ( XLAT ( " find a setting " ) , ' / ' ) ;
2024-05-26 18:22:29 +00:00
dialog : : add_action_push ( find_parameter ) ;
2021-01-31 18:55:33 +00:00
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2024-05-26 18:22:29 +00:00
void list_parameter : : show_edit_option ( int key ) {
2023-08-15 13:28:25 +00:00
string opt ;
if ( get_value ( ) < 0 | | get_value ( ) > = isize ( options ) ) opt = its ( get_value ( ) ) ;
else opt = options [ get_value ( ) ] . first ;
2021-05-23 12:17:06 +00:00
dialog : : addSelItem ( XLAT ( menu_item_name ) , XLAT ( opt ) , key ) ;
2023-10-29 10:00:19 +00:00
reaction_t screen = [ this ] {
2021-02-01 00:35:34 +00:00
add_to_changed ( this ) ;
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2021-02-01 00:35:34 +00:00
dialog : : init ( XLAT ( menu_item_name ) ) ;
dialog : : addBreak ( 100 ) ;
int q = isize ( options ) ;
2022-12-15 20:14:36 +00:00
int need_list = q > 15 ? 2 : q > 10 ? 1 : 0 ;
if ( need_list > = 2 ) dialog : : start_list ( 1500 , 1500 , ' a ' ) ;
2021-02-01 00:35:34 +00:00
for ( int i = 0 ; i < q ; i + + ) {
2022-12-15 20:14:36 +00:00
dialog : : addBoolItem ( XLAT ( options [ i ] . first ) , get_value ( ) = = i , need_list > = 2 ? dialog : : list_fake_key + + : ' a ' + i ) ;
2023-10-29 10:00:19 +00:00
auto action = [ this , i , need_list ] { set_value ( i ) ; if ( reaction ) reaction ( ) ; if ( need_list = = 0 ) popScreen ( ) ; } ;
if ( needs_confirm )
dialog : : add_action_confirmed ( action ) ;
else
dialog : : add_action ( action ) ;
2022-12-15 20:14:36 +00:00
if ( need_list = = 0 & & options [ i ] . second ! = " " ) {
dialog : : addBreak ( 100 ) ;
2021-02-01 00:35:34 +00:00
dialog : : addHelp ( XLAT ( options [ i ] . second ) ) ;
dialog : : addBreak ( 100 ) ;
}
}
2022-12-15 20:14:36 +00:00
if ( need_list > = 2 ) dialog : : end_list ( ) ;
2021-02-01 00:35:34 +00:00
dialog : : addBreak ( 100 ) ;
2022-12-15 20:14:36 +00:00
if ( need_list > = 1 & & options [ get_value ( ) ] . second ! = " " ) {
2023-12-03 13:29:02 +00:00
string text = options [ get_value ( ) ] . second ;
dialog : : addHelp ( XLAT ( text ) ) ;
2022-12-15 20:14:36 +00:00
dialog : : addBreak ( 100 ) ;
}
2021-02-01 00:35:34 +00:00
dialog : : addBack ( ) ;
dialog : : display ( ) ;
2023-10-29 10:00:19 +00:00
} ;
dialog : : add_action_push ( screen ) ;
2021-02-01 00:35:34 +00:00
}
2020-11-06 14:40:59 +00:00
EX void showSettings ( ) {
2022-07-05 09:51:06 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
gamescreen ( ) ;
2020-11-06 14:40:59 +00:00
dialog : : init ( XLAT ( " settings " ) ) ;
dialog : : addItem ( XLAT ( " interface " ) , ' i ' ) ;
dialog : : add_action_push ( configureInterface ) ;
dialog : : addItem ( XLAT ( " general graphics " ) , ' g ' ) ;
dialog : : add_action_push ( showGraphConfig ) ;
dialog : : addItem ( XLAT ( " 3D configuration " ) , ' 9 ' ) ;
dialog : : add_action_push ( show3D ) ;
dialog : : addItem ( XLAT ( " quick options " ) , ' q ' ) ;
dialog : : add_action_push ( showGraphQuickKeys ) ;
dialog : : addItem ( XLAT ( " models & projections " ) , ' p ' ) ;
2021-02-01 10:20:22 +00:00
dialog : : add_action_push ( models : : quick_model ) ;
2020-11-06 14:40:59 +00:00
dialog : : addItem ( XLAT ( " colors & aura " ) , ' c ' ) ;
dialog : : add_action_push ( show_color_dialog ) ;
# if CAP_SHMUP && !ISMOBILE
dialog : : addSelItem ( XLAT ( " keyboard & joysticks " ) , " " , ' k ' ) ;
dialog : : add_action ( multi : : configure ) ;
# endif
dialog : : addSelItem ( XLAT ( " mouse & touchscreen " ) , " " , ' m ' ) ;
dialog : : add_action_push ( configureMouse ) ;
dialog : : addItem ( XLAT ( " other settings " ) , ' o ' ) ;
dialog : : add_action_push ( configureOther ) ;
dialog : : addBreak ( 100 ) ;
# if CAP_CONFIG
2022-10-21 17:25:03 +00:00
dialog : : addItem ( XLAT ( " find a setting " ) , ' / ' ) ;
2024-05-26 18:22:29 +00:00
dialog : : add_action_push ( edit_all_parameters ) ;
2021-02-01 14:10:03 +00:00
2020-11-06 14:40:59 +00:00
dialog : : addItem ( XLAT ( " save the current config " ) , ' s ' ) ;
dialog : : add_action ( saveConfig ) ;
dialog : : addItem ( XLAT ( " reset all configuration " ) , ' R ' ) ;
dialog : : add_action_push ( resetConfigMenu ) ;
# endif
if ( getcstat = = ' s ' ) mouseovers = XLAT ( " Config file: %1 " , conffile ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
# if CAP_COMMANDLINE
EX int read_color_args ( ) {
using namespace arg ;
if ( argis ( " -back " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; backcolor = argcolor ( 24 ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -fillmodel " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; modelcolor = argcolor ( 32 ) ;
2020-11-06 14:40:59 +00:00
}
2022-04-28 06:24:13 +00:00
else if ( argis ( " -apeirocolor " ) ) {
2024-05-05 18:15:53 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; ccolor : : apeirogonal_color = argcolor ( 32 ) ;
2022-04-28 06:24:13 +00:00
}
2020-11-06 14:40:59 +00:00
else if ( argis ( " -ring " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; ringcolor = argcolor ( 32 ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -ringw " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . multiplier_ring ) ;
}
else if ( argis ( " -stdgrid " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; stdgridcolor = argcolor ( 32 ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -gridw " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . multiplier_grid ) ;
}
else if ( argis ( " -period " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; periodcolor = argcolor ( 32 ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -crosshair " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; crosshair_color = argcolor ( 32 ) ;
2020-11-06 14:40:59 +00:00
shift_arg_formula ( crosshair_size ) ;
}
else if ( argis ( " -borders " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; bordcolor = argcolor ( 24 ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -fore " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; forecolor = argcolor ( 24 ) ;
2020-11-06 14:40:59 +00:00
}
2022-07-23 13:36:27 +00:00
else if ( argis ( " -title " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; titlecolor = argcolor ( 24 ) ;
}
2020-11-06 14:40:59 +00:00
else if ( argis ( " -dialog " ) ) {
2021-10-17 07:18:31 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; dialog : : dialogcolor = argcolor ( 24 ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -d:color " ) )
launch_dialog ( show_color_dialog ) ;
else return 1 ;
return 0 ;
}
EX int read_config_args ( ) {
using namespace arg ;
if ( argis ( " -c " ) ) { PHASE ( 1 ) ; shift ( ) ; conffile = argcs ( ) ; }
// change the configuration from the command line
2021-02-06 00:39:18 +00:00
else if ( argis ( " -aa " ) ) { PHASEFROM ( 2 ) ; shift ( ) ; vid . want_antialias = argi ( ) ; apply_screen_settings ( ) ; }
2020-11-06 14:40:59 +00:00
else if ( argis ( " -lw " ) ) { PHASEFROM ( 2 ) ; shift_arg_formula ( vid . linewidth ) ; }
else if ( argis ( " -wm " ) ) { PHASEFROM ( 2 ) ; shift ( ) ; vid . wallmode = argi ( ) ; }
else if ( argis ( " -mm " ) ) { PHASEFROM ( 2 ) ; shift ( ) ; vid . monmode = argi ( ) ; }
else if ( argis ( " -noshadow " ) ) { noshadow = true ; }
else if ( argis ( " -bright " ) ) { bright = true ; }
else if ( argis ( " -gridon " ) ) { vid . grid = true ; }
else if ( argis ( " -gridoff " ) ) { vid . grid = false ; }
// non-configurable options
else if ( argis ( " -vsync_off " ) ) {
2021-02-06 00:39:18 +00:00
vid . want_vsync = false ;
apply_screen_settings ( ) ;
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -aura " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; vid . aurastr = argi ( ) ;
shift ( ) ; vid . aurasmoothen = argi ( ) ;
}
else if ( argis ( " -nofps " ) ) {
PHASEFROM ( 2 ) ;
nofps = true ;
}
else if ( argis ( " -nohud " ) ) {
PHASEFROM ( 2 ) ;
nohud = true ;
}
else if ( argis ( " -nomenu " ) ) {
PHASEFROM ( 2 ) ;
nomenukey = true ;
}
2021-05-28 22:11:59 +00:00
else if ( argis ( " -nomsg " ) ) {
PHASEFROM ( 2 ) ;
nomsg = true ;
}
2020-11-06 14:40:59 +00:00
# if MAXMDIM >= 4
else if ( argis ( " -switch-fpp " ) ) {
PHASEFROM ( 2 ) ;
geom3 : : switch_fpp ( ) ;
}
# endif
else if ( argis ( " -switch-tpp " ) ) {
PHASEFROM ( 2 ) ;
geom3 : : switch_tpp ( ) ;
}
# if MAXMDIM >= 4
else if ( argis ( " -switch-3d " ) ) {
PHASEFROM ( 2 ) ;
geom3 : : switch_always3 ( ) ;
}
# endif
else if ( argis ( " -nohelp " ) ) {
PHASEFROM ( 2 ) ;
nohelp = true ;
}
else if ( argis ( " -dont_face_pc " ) ) {
PHASEFROM ( 2 ) ;
dont_face_pc = true ;
}
# if CAP_TRANS
else if ( argis ( " -lang " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; vid . language = argi ( ) ;
}
# endif
else if ( argis ( " -vlq " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; vid . linequality = argi ( ) ;
}
else if ( argis ( " -fov " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . fov ) ;
}
else if ( argis ( " -r " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ;
2021-09-17 23:55:55 +00:00
if ( vid . want_fullscreen ) {
int clWidth = 0 , clHeight = 0 , clFont = 0 ;
sscanf ( argcs ( ) , " %dx%dx%d " , & clWidth , & clHeight , & clFont ) ;
vid . change_fullscr = clWidth ;
if ( clWidth ) vid . fullscreen_x = clWidth ;
if ( clHeight ) vid . fullscreen_y = clHeight ;
if ( clFont ) vid . abs_fsize = clFont , vid . relative_font = true ;
}
else if ( args ( ) . find ( " . " ) ! = string : : npos ) {
vid . relative_window_size = true ;
ld dWidth = 0 , dHeight = 0 ;
sscanf ( argcs ( ) , " %lfx%lf " , & dWidth , & dHeight ) ;
if ( dWidth ) vid . window_rel_x = dWidth ;
if ( dHeight ) vid . window_rel_y = dHeight ;
}
else {
vid . want_fullscreen = false ;
vid . relative_window_size = false ;
int clFont = 0 ;
sscanf ( argcs ( ) , " %dx%dx%d " , & vid . window_x , & vid . window_y , & clFont ) ;
if ( clFont ) vid . abs_fsize = clFont , vid . relative_font = true ;
}
2020-11-06 14:40:59 +00:00
}
else if ( argis ( " -msm " ) ) {
PHASEFROM ( 2 ) ; memory_saving_mode = true ;
}
else if ( argis ( " -mrsv " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; reserve_limit = argi ( ) ; apply_memory_reserve ( ) ;
}
else if ( argis ( " -pside " ) ) {
PHASEFROM ( 2 ) ;
permaside = true ;
}
else if ( argis ( " -xy " ) ) {
PHASEFROM ( 2 ) ;
shift_arg_formula ( pconf . xposition ) ;
shift_arg_formula ( pconf . yposition ) ;
}
else if ( argis ( " -fixdir " ) ) {
PHASEFROM ( 2 ) ;
vid . fixed_facing = true ;
shift_arg_formula ( vid . fixed_facing_dir ) ;
}
else if ( argis ( " -fixdiroff " ) ) {
PHASEFROM ( 2 ) ;
vid . fixed_facing = false ;
}
else if ( argis ( " -msmoff " ) ) {
PHASEFROM ( 2 ) ; memory_saving_mode = false ;
}
else if ( argis ( " -levellines " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( levellines ) ;
}
else if ( argis ( " -level-notexture " ) ) {
PHASEFROM ( 2 ) ; disable_texture = true ;
}
else if ( argis ( " -level-texture " ) ) {
PHASEFROM ( 2 ) ; disable_texture = false ;
}
else if ( argis ( " -msens " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( mouseaim_sensitivity ) ;
}
2021-07-04 09:25:52 +00:00
TOGGLE ( ' o ' , vid . wantGL , { vid . wantGL = ! vid . wantGL ; apply_screen_settings ( ) ; } )
TOGGLE ( ' f ' , vid . want_fullscreen , { vid . want_fullscreen = ! vid . want_fullscreen ; apply_screen_settings ( ) ; } )
2020-11-06 14:40:59 +00:00
else if ( argis ( " -noshaders " ) ) {
PHASE ( 1 ) ;
glhr : : noshaders = true ;
}
else if ( argis ( " -d:sight " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( ) ; edit_sightrange ( ) ;
}
else if ( argis ( " -d:char " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( showCustomizeChar ) ;
}
else if ( argis ( " -d:3 " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( show3D ) ;
}
else if ( argis ( " -d:stereo " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( showStereo ) ;
}
else if ( argis ( " -d:iface " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( configureInterface ) ;
}
else if ( argis ( " -d:graph " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( showGraphConfig ) ;
}
else if ( argis ( " -tstep " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; vid . texture_step = argi ( ) ;
}
else if ( argis ( " -csc " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . creature_scale ) ;
}
else if ( argis ( " -neon " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; neon_mode = eNeon ( argi ( ) ) ;
}
2020-12-29 03:41:23 +00:00
else if ( argis ( " -dmc " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; vid . drawmousecircle = argi ( ) ;
}
2020-11-06 14:40:59 +00:00
else if ( argis ( " -smooths " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; smooth_scrolling = argi ( ) ;
}
else if ( argis ( " -via-shader " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; vid . consider_shader_projection = argi ( ) ;
}
else if ( argis ( " -neonnf " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; neon_nofill = argi ( ) ;
}
else if ( argis ( " -precw " ) ) {
PHASEFROM ( 2 ) ;
shift_arg_formula ( precise_width ) ;
}
2021-01-31 18:55:33 +00:00
else if ( argis ( " -d:all " ) ) {
2024-05-26 18:22:29 +00:00
PHASEFROM ( 2 ) ; launch_dialog ( edit_all_parameters ) ;
2021-01-31 18:55:33 +00:00
}
2022-10-21 09:30:51 +00:00
else if ( argis ( " -d:find " ) ) {
2024-05-26 18:22:29 +00:00
PHASEFROM ( 2 ) ; launch_dialog ( find_parameter ) ;
2022-10-21 09:30:51 +00:00
}
2023-08-13 11:54:08 +00:00
else if ( argis ( " -d:param " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ;
string s = args ( ) ;
2023-08-15 15:54:12 +00:00
cmode | = sm : : SIDE ;
2023-08-13 11:54:08 +00:00
for ( auto & fs : params ) if ( fs . first = = s ) {
dialog : : items . clear ( ) ;
dialog : : key_actions . clear ( ) ;
fs . second - > show_edit_option ( ) ;
for ( auto p : dialog : : key_actions ) { p . second ( ) ; return 0 ; }
println ( hlog , " no key action " ) ;
return 0 ;
}
println ( hlog , " unknown param to edit: " , s ) ;
}
2020-11-06 14:40:59 +00:00
else if ( argis ( " -char " ) ) {
auto & cs = vid . cs ;
2021-03-29 14:26:04 +00:00
shift ( ) ;
string s = args ( ) ;
2023-05-18 23:18:02 +00:00
set_char_by_name ( cs , s ) ;
2020-11-06 14:40:59 +00:00
}
else return 1 ;
return 0 ;
}
2023-05-18 23:18:02 +00:00
EX void set_char_by_name ( charstyle & cs , const string & s ) {
if ( s = = " dodek " ) {
cs . charid = 4 ;
cs . lefthanded = false ;
cs . skincolor = 0x202020FF ;
cs . eyecolor = 0x20C000FF ;
cs . haircolor = 0x202020FF ;
cs . dresscolor = 0x424242FF ;
cs . swordcolor = 0xF73333FF ;
}
else if ( s = = " rudy " ) {
cs . charid = 4 ;
cs . lefthanded = false ;
cs . skincolor = 0xA44139FF ;
cs . eyecolor = 0xD59533FF ;
cs . haircolor = 0xC6634AFF ;
cs . dresscolor = 0xC6634AFF ;
cs . swordcolor = 0x3CBB33FF ;
}
else if ( s = = " running " ) {
cs . charid = 6 ;
cs . lefthanded = false ;
cs . skincolor = 0xFFFFFFFF ;
cs . eyecolor = 0xFF ;
cs . haircolor = 0xFFFFFFFF ;
cs . dresscolor = 0xFFFFFFFF ;
cs . swordcolor = 0xFF0000FF ;
}
else if ( s = = " princess " ) {
cs . charid = 3 ;
cs . lefthanded = true ;
cs . skincolor = 0xEFD0C9FF ;
cs . haircolor = 0x301800FF ;
cs . eyecolor = 0xC000FF ;
cs . dresscolor = 0x408040FF ;
cs . swordcolor = 0xFFFFFFFF ;
}
else if ( s = = " worker " ) {
cs . charid = 2 ;
cs . skincolor = 0xC77A58FF ;
cs . haircolor = 0x502810FF ;
cs . dresscolor = 0xC0C000FF ;
cs . eyecolor = 0x500040FF ;
cs . swordcolor = 0x808080FF ;
}
else {
cs . charid = atoi ( s . c_str ( ) ) ;
cs . lefthanded = cs . charid > = 10 ;
cs . charid % = 10 ;
}
}
2021-02-04 14:01:27 +00:00
EX int read_param_args ( ) {
2021-02-04 14:07:58 +00:00
const string & s = arg : : args ( ) ;
auto pos = s . find ( " = " ) ;
2021-02-04 14:01:27 +00:00
if ( pos = = string : : npos ) return 1 ;
2021-02-04 14:07:58 +00:00
string name = s . substr ( 0 , pos ) ;
string value = s . substr ( pos + 1 ) ;
2021-02-04 14:01:27 +00:00
PHASEFROM ( 2 ) ;
if ( ! params . count ( name ) ) {
println ( hlog , " parameter unknown: " , name ) ;
exit ( 1 ) ;
}
2023-08-08 23:01:32 +00:00
params [ name ] - > load_as_animation ( value ) ;
2021-02-04 14:07:58 +00:00
return 0 ;
2021-02-04 14:01:27 +00:00
}
2020-11-06 14:40:59 +00:00
// mode changes:
EX int read_gamemode_args ( ) {
using namespace arg ;
if ( argis ( " -P " ) ) {
PHASE ( 2 ) ; shift ( ) ;
stop_game_and_switch_mode ( rg : : nothing ) ;
multi : : players = argi ( ) ;
}
TOGGLE ( ' S ' , shmup : : on , stop_game_and_switch_mode ( rg : : shmup ) )
TOGGLE ( ' H ' , hardcore , switchHardcore ( ) )
TOGGLE ( ' R ' , randomPatternsMode , stop_game_and_switch_mode ( rg : : randpattern ) )
TOGGLE ( ' i ' , inv : : on , stop_game_and_switch_mode ( rg : : inv ) )
else return 1 ;
return 0 ;
}
2021-02-04 14:01:27 +00:00
auto ah_config =
addHook ( hooks_args , 0 , read_config_args ) +
addHook ( hooks_args , 0 , read_param_args ) +
addHook ( hooks_args , 0 , read_gamemode_args ) + addHook ( hooks_args , 0 , read_color_args ) ;
2020-11-06 14:40:59 +00:00
# endif
2023-08-06 20:06:39 +00:00
/* local parameter, for another game */
local_parameter_set * current_lps ;
void local_parameter_set : : pswitch ( ) {
2023-08-08 09:47:08 +00:00
if ( extends ) extends - > pswitch ( ) ;
2023-08-06 20:06:39 +00:00
for ( auto s : swaps ) {
2024-05-26 18:22:29 +00:00
s . first - > swap_with ( & * s . second ) ;
2023-08-08 09:47:08 +00:00
swap ( s . first - > name , s . second - > name ) ;
2023-08-06 20:06:39 +00:00
}
}
EX void lps_enable ( local_parameter_set * lps ) {
2023-08-08 14:28:04 +00:00
if ( lps = = current_lps ) return ;
2023-08-06 20:06:39 +00:00
if ( current_lps ) current_lps - > pswitch ( ) ;
current_lps = lps ;
if ( current_lps ) current_lps - > pswitch ( ) ;
}
2023-08-08 09:47:08 +00:00
# if HDR
2023-08-08 14:28:04 +00:00
//template<class T> vector<std::unique_ptr<T>> lps_of_type;
extern vector < void * > lps_of_type ;
2023-08-06 20:06:39 +00:00
2023-08-08 09:47:08 +00:00
template < class T , class U > void lps_add ( local_parameter_set & lps , T & val , U nvalue ) {
2023-08-06 20:06:39 +00:00
int found = 0 ;
2024-05-26 18:22:29 +00:00
for ( auto & fs : params ) {
if ( fs . second - > affects ( & val ) ) {
2023-08-06 20:06:39 +00:00
found + + ;
2023-08-08 14:28:04 +00:00
T * nv = new T ( nvalue ) ;
lps_of_type . emplace_back ( nv ) ;
2024-05-26 18:22:29 +00:00
println ( hlog , lps . label , " found saver: " , fs . second - > name ) ;
auto fs2 = fs . second - > clone ( lps , nv ) ;
lps . swaps . emplace_back ( fs . second , fs2 ) ;
2023-08-08 09:47:08 +00:00
return ;
2023-08-07 15:15:21 +00:00
}
}
2023-08-08 09:47:08 +00:00
if ( found ! = 1 ) println ( hlog , lps . label , " saver not found " ) ;
2023-08-07 15:15:21 +00:00
}
# endif
2023-08-08 14:28:04 +00:00
vector < void * > lps_of_type ;
2020-11-06 14:40:59 +00:00
}