2017-08-13 18:49:38 +00:00
// Hyperbolic Rogue -- configuration
2018-02-08 23:40:26 +00:00
// Copyright (C) 2017-2018 Zeno Rogue, see 'hyper.cpp' for details
2017-08-13 18:49:38 +00:00
2019-08-10 11:43:24 +00:00
/** \file config.cpp
* \ brief Configuration - - initial settings , saving / loading ini files , menus , etc .
*/
2019-09-05 07:15:40 +00:00
# include "hyper.h"
2018-06-10 23:58:31 +00:00
namespace hr {
2019-08-10 00:16:48 +00:00
# if HDR
struct supersaver {
string name ;
virtual string save ( ) = 0 ;
virtual void load ( const string & s ) = 0 ;
virtual bool dosave ( ) = 0 ;
virtual void reset ( ) = 0 ;
virtual ~ supersaver ( ) { } ;
} ;
typedef vector < shared_ptr < supersaver > > saverlist ;
extern saverlist savers ;
# if CAP_CONFIG
template < class T > struct dsaver : supersaver {
T & val ;
T dft ;
bool dosave ( ) { return val ! = dft ; }
void reset ( ) { val = dft ; }
dsaver ( T & val ) : val ( val ) { }
} ;
template < class T > struct saver : dsaver < T > { } ;
template < class T , class U , class V > void addsaver ( T & i , U name , V dft ) {
auto s = make_shared < saver < T > > ( i ) ;
s - > dft = dft ;
s - > name = name ;
savers . push_back ( s ) ;
}
template < class T > void addsaver ( T & i , string name ) {
addsaver ( i , name , i ) ;
}
template < class T > struct saverenum : supersaver {
T & val ;
T dft ;
bool dosave ( ) { return val ! = dft ; }
void reset ( ) { val = dft ; }
saverenum < T > ( T & v ) : val ( v ) { }
string save ( ) { return its ( int ( val ) ) ; }
void load ( const string & s ) { val = ( T ) atoi ( s . c_str ( ) ) ; }
} ;
template < class T , class U > void addsaverenum ( T & i , U name , T dft ) {
auto s = make_shared < saverenum < T > > ( i ) ;
s - > dft = dft ;
s - > name = name ;
savers . push_back ( s ) ;
}
template < class T , class U > void addsaverenum ( T & i , U name ) {
addsaverenum ( i , name , i ) ;
}
template < > struct saver < int > : dsaver < int > {
saver < int > ( int & val ) : dsaver < int > ( val ) { }
string save ( ) { return its ( val ) ; }
void load ( const string & s ) { val = atoi ( s . c_str ( ) ) ; }
} ;
template < > struct saver < char > : dsaver < char > {
saver < char > ( char & val ) : dsaver < char > ( val ) { }
string save ( ) { return its ( val ) ; }
void load ( const string & s ) { val = atoi ( s . c_str ( ) ) ; }
} ;
template < > struct saver < bool > : dsaver < bool > {
saver < bool > ( bool & val ) : dsaver < bool > ( val ) { }
string save ( ) { return val ? " yes " : " no " ; }
void load ( const string & s ) { val = isize ( s ) & & s [ 0 ] = = ' y ' ; }
} ;
template < > struct saver < unsigned > : dsaver < unsigned > {
saver < unsigned > ( unsigned & val ) : dsaver < unsigned > ( val ) { }
string save ( ) { return itsh ( val ) ; }
void load ( const string & s ) { val = ( unsigned ) strtoll ( s . c_str ( ) , NULL , 16 ) ; }
} ;
template < > struct saver < string > : dsaver < string > {
saver < string > ( string & val ) : dsaver < string > ( val ) { }
string save ( ) { return val ; }
void load ( const string & s ) { val = s ; }
} ;
template < > struct saver < ld > : dsaver < ld > {
saver < ld > ( ld & val ) : dsaver < ld > ( val ) { }
string save ( ) { return fts ( val , 10 ) ; }
void load ( const string & s ) {
if ( s = = " 0.0000000000e+000 " ) ; // ignore!
else val = atof ( s . c_str ( ) ) ;
}
} ;
# endif
2019-11-16 13:46:12 +00:00
void addparam ( ld & val , const string s ) ;
# endif
# if CAP_CONFIG
void addparam ( ld & val , const string s ) {
2019-11-16 00:39:58 +00:00
addsaver ( val , s ) ;
2019-11-16 02:39:00 +00:00
params . insert ( { s , val } ) ;
2019-11-16 00:39:58 +00:00
}
2019-11-16 13:46:12 +00:00
# else
void addparam ( ld & val , const string s ) {
params . insert ( { s , val } ) ;
}
2019-11-16 07:39:51 +00:00
# endif
2019-08-09 19:00:52 +00:00
EX ld bounded_mine_percentage = 0.1 ;
EX int bounded_mine_quantity , bounded_mine_max ;
2019-04-04 12:36:45 +00:00
2019-09-06 06:17:02 +00:00
EX const char * conffile = " hyperrogue.ini " ;
2018-07-19 22:04:23 +00:00
2019-08-09 19:00:52 +00:00
EX array < ld , gGUARD > sightranges ;
2019-02-25 16:21:53 +00:00
2019-08-09 19:00:52 +00:00
EX videopar vid ;
2017-07-10 18:47:38 +00:00
2018-03-24 15:00:13 +00:00
# define DEFAULT_WALLMODE (ISMOBILE ? 3 : 5)
# define DEFAULT_MONMODE (ISMOBILE ? 2 : 4)
2017-12-03 18:51:45 +00:00
2017-08-06 12:50:16 +00:00
# if ISANDROID
# define ANDROID_SETTINGS settingsChanged = true;
# else
# define ANDROID_SETTINGS ;
# endif
2018-11-08 20:56:06 +00:00
extern color_t floorcolors [ landtypes ] ;
2019-08-09 20:07:03 +00:00
EX charstyle & getcs ( int id IS ( multi : : cpid ) ) {
2017-08-06 12:50:16 +00:00
if ( multi : : players > 1 & & id > = 0 & & id < multi : : players )
return multi : : scs [ id ] ;
2017-07-10 18:47:38 +00:00
else
return vid . cs ;
}
2019-05-13 15:16:15 +00:00
struct charstyle_old {
int charid ;
color_t skincolor , haircolor , dresscolor , swordcolor , dresscolor2 , uicolor ;
bool lefthanded ;
} ;
2019-09-06 06:17:02 +00:00
EX void hread ( hstream & hs , charstyle & cs ) {
2019-05-21 22:21:22 +00:00
// before 0xA61A there was no eyecolor
2019-05-21 23:14:11 +00:00
if ( hs . get_vernum ( ) < 0xA61A ) {
2019-05-21 22:21:22 +00:00
charstyle_old cso ;
hread_raw ( hs , cso ) ;
cs . charid = cso . charid ;
cs . skincolor = cso . skincolor ;
cs . haircolor = cso . haircolor ;
cs . dresscolor = cso . dresscolor ;
cs . swordcolor = cs . eyecolor = cso . swordcolor ;
if ( cs . charid < 4 ) cs . eyecolor = 0 ;
cs . dresscolor2 = cso . dresscolor2 ;
cs . uicolor = cso . uicolor ;
cs . lefthanded = cso . lefthanded ;
}
else hread_raw ( hs , cs ) ;
2019-05-13 15:16:15 +00:00
}
2019-09-06 06:17:02 +00:00
EX void hwrite ( hstream & hs , const charstyle & cs ) {
2019-05-21 22:21:22 +00:00
hwrite_raw ( hs , cs ) ;
2019-05-13 15:16:15 +00:00
}
// void hread(hstream& hs, charstyle& cs) { hread_raw(hs, cs); }
// void hwrite(hstream& hs, const charstyle& cs) { hwrite_raw(hs, cs); }
2018-11-24 16:01:49 +00:00
2019-08-09 19:00:52 +00:00
EX string csnameid ( int id ) {
2017-07-10 18:47:38 +00:00
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 " ) ;
}
2019-08-09 19:00:52 +00:00
EX string csname ( charstyle & cs ) {
2017-07-10 18:47:38 +00:00
return csnameid ( cs . charid ) ;
}
2019-08-09 19:00:52 +00:00
EX int playergender ( ) {
2019-01-11 14:00:53 +00:00
return ( getcs ( ) . charid > = 0 & & ( getcs ( ) . charid & 1 ) ) ? GEN_F : GEN_M ;
2017-07-10 18:47:38 +00:00
}
2019-08-09 19:00:52 +00:00
EX int princessgender ( ) {
2017-07-10 18:47:38 +00:00
int g = playergender ( ) ;
if ( vid . samegender ) return g ;
return g = = GEN_M ? GEN_F : GEN_M ;
}
2019-08-09 19:00:52 +00:00
EX int default_language ;
2017-07-10 18:47:38 +00:00
2019-08-09 19:00:52 +00:00
EX int lang ( ) {
2017-07-10 18:47:38 +00:00
if ( vid . language > = 0 )
return vid . language ;
return default_language ;
}
2019-09-06 06:17:02 +00:00
EX bool autojoy = true ;
2017-07-10 18:47:38 +00:00
2017-08-13 18:49:38 +00:00
# if CAP_CONFIG
2017-12-14 11:10:40 +00:00
saverlist savers ;
2017-08-13 18:49:38 +00:00
# endif
# if !CAP_CONFIG
template < class T , class U , class V > void addsaver ( T & i , U name , V dft ) {
i = dft ;
}
template < class T , class U > void addsaver ( T & i , U name ) { }
template < class T , class U > void addsaverenum ( T & i , U name ) { }
2018-08-31 18:59:58 +00:00
template < class T , class U > void addsaverenum ( T & i , U name , T dft ) { }
2017-08-13 18:49:38 +00:00
# endif
2017-07-10 18:47:38 +00:00
2019-09-06 06:17:02 +00:00
EX void addsaver ( charstyle & cs , string s ) {
2017-07-16 21:00:55 +00:00
addsaver ( cs . charid , s + " .charid " ) ;
addsaver ( cs . skincolor , s + " .skincolor " ) ;
2019-06-17 23:37:44 +00:00
addsaver ( cs . eyecolor , s + " .eyecolor " ) ;
2017-07-16 21:00:55 +00:00
addsaver ( cs . haircolor , s + " .haircolor " ) ;
addsaver ( cs . dresscolor , s + " .dresscolor " ) ;
addsaver ( cs . swordcolor , s + " .swordcolor " ) ;
addsaver ( cs . dresscolor2 , s + " .dresscolor2 " ) ;
addsaver ( cs . uicolor , s + " .uicolor " ) ;
2018-11-10 17:32:55 +00:00
addsaver ( cs . lefthanded , s + " .lefthanded " ) ;
2017-07-16 21:00:55 +00:00
}
2017-07-10 18:47:38 +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 } ;
2019-05-12 19:09:27 +00:00
unsigned int eyecolors [ ] = { 4 , 0x00C000FF , 0x0000C0FF , 0xC00000FF , 0xC0C000FF , 0x804010FF , 0x00C000FF } ;
2017-07-10 18:47:38 +00:00
2019-08-09 19:00:52 +00:00
EX void initcs ( charstyle & cs ) {
2017-07-10 18:47:38 +00:00
cs . charid = 0 ;
cs . skincolor = 0xD0D0D0FF ;
cs . haircolor = 0x686868FF ;
cs . dresscolor = 0xC00000FF ;
cs . swordcolor = 0xD0D0D0FF ;
cs . dresscolor2 = 0x8080FFC0 ;
cs . uicolor = 0xFF0000FF ;
2019-05-12 19:09:27 +00:00
cs . eyecolor = 0x603000FF ;
2018-11-10 17:32:55 +00:00
cs . lefthanded = false ;
2017-07-10 18:47:38 +00:00
}
2019-08-09 19:00:52 +00:00
EX void savecolortable ( colortable & ct , string name ) {
2018-11-08 20:56:06 +00:00
for ( int i = 0 ; i < isize ( ct ) ; i + + )
addsaver ( ct [ i ] , " color: " + name + " : " + its ( i ) ) ;
}
2019-11-16 00:39:58 +00:00
EX purehookset hooks_configfile ;
2019-08-09 19:00:52 +00:00
EX void initConfig ( ) {
2017-07-10 18:47:38 +00:00
2017-07-16 21:00:55 +00:00
// basic config
addsaver ( vid . flashtime , " flashtime " , 8 ) ;
2017-10-09 08:51:16 +00:00
addsaver ( vid . msgleft , " message style " , 2 ) ;
addsaver ( vid . msglimit , " message limit " , 5 ) ;
addsaver ( vid . timeformat , " message log time format " , 0 ) ;
2017-10-29 11:41:04 +00:00
addsaver ( fontscale , " fontscale " , 100 ) ;
2017-10-09 08:51:16 +00:00
2019-02-08 09:03:22 +00:00
addsaver ( vid . mobilecompasssize , " mobile compass size " , 0 ) ; // ISMOBILE || ISPANDORA ? 30 : 0);
2019-02-28 15:24:46 +00:00
addsaver ( vid . radarsize , " radarsize size " , 120 ) ;
2019-07-31 15:32:44 +00:00
addsaver ( vid . radarrange , " radarrange " , 2.5 ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . axes , " movement help " , 1 ) ;
2019-06-25 08:30:31 +00:00
addsaver ( vid . axes3 , " movement help3 " , false ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . shifttarget , " shift-targetting " , 2 ) ;
addsaver ( vid . steamscore , " scores to Steam " , 1 ) ;
initcs ( vid . cs ) ; addsaver ( vid . cs , " single " ) ;
addsaver ( vid . samegender , " princess choice " , false ) ;
addsaver ( vid . language , " language " , - 1 ) ;
addsaver ( vid . drawmousecircle , " mouse circle " , ISMOBILE | | ISPANDORA ) ;
addsaver ( vid . revcontrol , " reverse control " , false ) ;
addsaver ( musicvolume , " music volume " ) ;
addsaver ( effvolume , " sound effect volume " ) ;
addsaverenum ( glyphsortorder , " glyph sort order " ) ;
2017-07-10 18:47:38 +00:00
2017-07-16 21:00:55 +00:00
// basic graphics
2017-07-10 18:47:38 +00:00
2017-07-16 21:00:55 +00:00
addsaver ( vid . usingGL , " usingGL " , true ) ;
2019-05-06 23:10:11 +00:00
addsaver ( vid . antialias , " antialias " , AA_NOGL | AA_FONT | ( ISWEB ? AA_MULTI : AA_LINES ) | AA_LINEWIDTH | AA_VERSION ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . linewidth , " linewidth " , 1 ) ;
2018-11-08 21:34:23 +00:00
addsaver ( linepatterns : : width , " pattern-linewidth " , 1 ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . scale , " scale " , 1 ) ;
2017-12-25 09:26:50 +00:00
addsaver ( vid . xposition , " xposition " , 0 ) ;
addsaver ( vid . yposition , " yposition " , 0 ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . alpha , " projection " , 1 ) ;
addsaver ( vid . sspeed , " scrollingspeed " , 0 ) ;
addsaver ( vid . mspeed , " movement speed " , 1 ) ;
addsaver ( vid . full , " fullscreen " , false ) ;
2017-07-22 23:33:27 +00:00
addsaver ( vid . aurastr , " aura strength " , ISMOBILE ? 0 : 128 ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . aurasmoothen , " aura smoothen " , 5 ) ;
addsaver ( vid . graphglyph , " graphical items/kills " , 1 ) ;
addsaver ( vid . particles , " extra effects " , 1 ) ;
addsaver ( vid . framelimit , " frame limit " , 75 ) ;
addsaver ( vid . xres , " xres " ) ;
addsaver ( vid . yres , " yres " ) ;
addsaver ( vid . fsize , " font size " ) ;
addsaver ( vid . darkhepta , " mark heptagons " , false ) ;
2017-07-10 18:47:38 +00:00
2017-07-16 21:00:55 +00:00
// special graphics
addsaver ( vid . ballangle , " ball angle " , 20 ) ;
addsaver ( vid . yshift , " Y shift " , 0 ) ;
2019-04-29 01:34:21 +00:00
addsaver ( vid . use_wall_radar , " wallradar " , true ) ;
2019-01-17 13:09:00 +00:00
addsaver ( vid . fixed_facing , " fixed facing " , 0 ) ;
2019-11-13 23:42:36 +00:00
addsaver ( vid . fixed_facing_dir , " fixed facing dir " , 90 ) ;
2019-05-09 17:45:20 +00:00
addsaver ( vid . fixed_yz , " fixed YZ " , true ) ;
2017-07-16 21:00:55 +00:00
addsaver ( vid . camera_angle , " camera angle " , 0 ) ;
addsaver ( vid . ballproj , " ballproj " , 1 ) ;
2017-12-03 18:51:45 +00:00
addsaver ( vid . monmode , " monster display mode " , DEFAULT_MONMODE ) ;
addsaver ( vid . wallmode , " wall display mode " , DEFAULT_WALLMODE ) ;
2017-07-16 21:00:55 +00:00
2019-05-29 14:27:24 +00:00
addsaver ( vid . depth , " 3D depth " , 1 ) ;
addsaver ( vid . camera , " 3D camera level " , 1 ) ;
addsaver ( vid . wall_height , " 3D wall height " , .3 ) ;
addsaver ( vid . rock_wall_ratio , " 3D rock-wall ratio " , .9 ) ;
addsaver ( vid . human_wall_ratio , " 3D human-wall ratio " , .7 ) ;
addsaver ( vid . lake_top , " 3D lake top " , .25 ) ;
addsaver ( vid . lake_bottom , " 3D lake bottom " , .9 ) ;
addsaver ( vid . tc_depth , " 3D TC depth " , 1 ) ;
addsaver ( vid . tc_camera , " 3D TC camera " , 2 ) ;
addsaver ( vid . tc_alpha , " 3D TC alpha " , 3 ) ;
addsaver ( vid . highdetail , " 3D highdetail " , 8 ) ;
addsaver ( vid . middetail , " 3D middetail " , 8 ) ;
addsaver ( vid . gp_autoscale_heights , " 3D Goldberg autoscaling " , true ) ;
addsaver ( vid . always3 , " 3D always " , false ) ;
2018-01-25 18:49:19 +00:00
2019-06-01 17:58:07 +00:00
addsaver ( vid . eye , " eyelevel " , 0 ) ;
addsaver ( vid . auto_eye , " auto-eyelevel " , false ) ;
2018-02-03 13:31:17 +00:00
addsaver ( memory_saving_mode , " memory_saving_mode " , ( ISMOBILE | | ISPANDORA | | ISWEB ) ? 1 : 0 ) ;
2019-06-13 17:19:15 +00:00
addsaver ( reserve_limit , " memory_reserve " , 128 ) ;
addsaver ( show_memory_warning , " show_memory_warning " ) ;
2017-07-16 21:00:55 +00:00
addsaver ( rug : : renderonce , " rug-renderonce " ) ;
addsaver ( rug : : rendernogl , " rug-rendernogl " ) ;
addsaver ( rug : : texturesize , " rug-texturesize " ) ;
2018-01-20 17:10:12 +00:00
# if CAP_RUG
2017-12-27 17:53:00 +00:00
addsaver ( rug : : model_distance , " rug-model-distance " ) ;
2018-01-20 17:10:12 +00:00
# endif
2017-07-16 21:00:55 +00:00
2019-05-29 14:27:24 +00:00
addsaverenum ( pmodel , " used model " , mdDisk ) ;
2017-07-16 21:00:55 +00:00
addsaver ( polygonal : : SI , " polygon sides " ) ;
addsaver ( polygonal : : STAR , " polygon star factor " ) ;
addsaver ( polygonal : : deg , " polygonal degree " ) ;
2019-08-09 22:58:50 +00:00
addsaver ( history : : autobandhistory , " include history " ) ; // check!
addsaver ( history : : lvspeed , " lineview speed " ) ;
addsaver ( history : : extra_line_steps , " lineview extension " ) ;
2017-07-16 21:00:55 +00:00
addsaver ( polygonal : : maxcoef , " polynomial degree " ) ;
for ( int i = 0 ; i < polygonal : : MSI ; i + + ) {
addsaver ( polygonal : : coefr [ i ] , " polynomial " + its ( i ) + " .real " ) ;
addsaver ( polygonal : : coefi [ i ] , " polynomial " + its ( i ) + " .imag " ) ;
}
2019-08-09 22:58:50 +00:00
addsaver ( history : : bandhalf , " band width " ) ;
addsaver ( history : : bandsegment , " band segment " ) ;
addsaver ( models : : rotation , " conformal rotation " ) ;
addsaver ( models : : rotation_xz , " conformal rotation_xz " ) ;
addsaver ( models : : rotation_xy2 , " conformal rotation_2 " ) ;
addsaver ( models : : do_rotate , " conformal rotation mode " , 1 ) ;
addsaver ( models : : model_orientation , " model orientation " , 0 ) ;
addsaver ( models : : model_orientation_yz , " model orientation-yz " , 0 ) ;
addsaver ( models : : top_z , " topz " , 5 ) ;
addsaver ( models : : model_transition , " model transition " , 1 ) ;
addsaver ( models : : halfplane_scale , " halfplane scale " , 1 ) ;
addsaver ( history : : autoband , " automatic band " ) ;
addsaver ( history : : autobandhistory , " automatic band history " ) ;
addsaver ( history : : dospiral , " do spiral " ) ;
addsaver ( models : : clip_min , " clip-min " , - 1 ) ;
addsaver ( models : : clip_max , " clip-max " , + 1 ) ;
2017-07-16 21:00:55 +00:00
2017-10-17 19:26:21 +00:00
addsaver ( vid . backeffects , " background particle effects " , ( ISMOBILE | | ISPANDORA ) ? false : true ) ;
2017-07-16 21:00:55 +00:00
// control
addsaver ( vid . joyvalue , " vid.joyvalue " , 4800 ) ;
addsaver ( vid . joyvalue2 , " vid.joyvalue2 " , 5600 ) ;
addsaver ( vid . joypanthreshold , " vid.joypanthreshold " , 2500 ) ;
addsaver ( vid . joypanspeed , " vid.joypanspeed " , ISPANDORA ? 0.0001 : 0 ) ;
addsaver ( autojoy , " autojoy " ) ;
vid . killreduction = 0 ;
2017-08-06 12:50:16 +00:00
addsaver ( vid . skipstart , " skip the start menu " , false ) ;
addsaver ( vid . quickmouse , " quick mouse " , ! ISPANDORA ) ;
// colors
2019-09-09 14:10:57 +00:00
addsaver ( crosshair_size , " size:crosshair " ) ;
addsaver ( crosshair_color , " color:crosshair " ) ;
2017-08-06 12:50:16 +00:00
addsaver ( backcolor , " color:background " ) ;
addsaver ( forecolor , " color:foreground " ) ;
addsaver ( bordcolor , " color:borders " ) ;
2018-11-08 20:56:06 +00:00
addsaver ( ringcolor , " color:ring " ) ;
2019-07-13 12:37:30 +00:00
addsaver ( vid . multiplier_ring , " mult:ring " , 1 ) ;
2018-11-08 20:56:06 +00:00
addsaver ( modelcolor , " color:model " ) ;
addsaver ( periodcolor , " color:period " ) ;
2019-03-08 21:40:34 +00:00
addsaver ( stdgridcolor , " color:stdgrid " ) ;
2019-07-13 12:37:30 +00:00
addsaver ( vid . multiplier_grid , " mult:grid " , 1 ) ;
2018-09-05 13:18:40 +00:00
addsaver ( dialog : : dialogcolor , " color:dialog " ) ;
2018-11-08 20:56:06 +00:00
for ( auto & p : colortables )
savecolortable ( p . second , s0 + " canvas " + p . first ) ;
savecolortable ( distcolors , " distance " ) ;
savecolortable ( minecolors , " mines " ) ;
2019-02-17 17:37:23 +00:00
# if CAP_COMPLEX2
2019-01-03 16:21:11 +00:00
savecolortable ( brownian : : colors , " color:brown " ) ;
2019-02-17 17:37:23 +00:00
# endif
2018-11-08 20:56:06 +00:00
for ( int i = 0 ; i < motypes ; i + + )
addsaver ( minf [ i ] . color , " color:monster: " + its ( i ) ) ;
for ( int i = 0 ; i < ittypes ; i + + )
addsaver ( iinf [ i ] . color , " color:item: " + its ( i ) ) ;
for ( int i = 0 ; i < landtypes ; i + + )
addsaver ( floorcolors [ i ] , " color:land: " + its ( i ) ) ;
for ( int i = 0 ; i < walltypes ; i + + )
addsaver ( winf [ i ] . color , " color:wall: " + its ( i ) ) ;
2017-08-06 12:50:16 +00:00
2017-07-16 21:00:55 +00:00
// modes
addsaverenum ( geometry , " mode-geometry " ) ;
addsaver ( shmup : : on , " mode-shmup " , false ) ;
addsaver ( hardcore , " mode-hardcore " , false ) ;
addsaver ( chaosmode , " mode-chaos " ) ;
addsaver ( inv : : on , " mode-Orb Strategy " ) ;
2018-08-28 15:17:34 +00:00
addsaverenum ( variation , " mode-variation " , eVariation : : bitruncated ) ;
2017-07-24 22:21:36 +00:00
addsaver ( peace : : on , " mode-peace " ) ;
2017-08-06 12:50:16 +00:00
addsaver ( peace : : otherpuzzles , " mode-peace-submode " ) ;
addsaverenum ( specialland , " land for special modes " ) ;
2017-07-24 22:21:36 +00:00
addsaver ( viewdists , " expansion mode " ) ;
2017-11-13 11:23:42 +00:00
addsaver ( backbrightness , " brightness behind sphere " ) ;
2018-02-03 12:41:49 +00:00
2018-11-17 18:24:02 +00:00
addsaver ( vid . ipd , " interpupilar-distance " , 0.05 ) ;
addsaver ( vid . lr_eyewidth , " eyewidth-lr " , 0.5 ) ;
addsaver ( vid . anaglyph_eyewidth , " eyewidth-anaglyph " , 0.1 ) ;
addsaver ( vid . fov , " field-of-vision " , 90 ) ;
2019-03-09 02:32:24 +00:00
addsaver ( vid . desaturate , " desaturate " , 0 ) ;
2018-11-17 18:24:02 +00:00
addsaverenum ( vid . stereo_mode , " stereo-mode " ) ;
2018-03-24 14:15:30 +00:00
addsaver ( vid . euclid_to_sphere , " euclid to sphere projection " , 1.5 ) ;
2018-03-26 17:06:47 +00:00
addsaver ( vid . twopoint_param , " twopoint parameter " , 1 ) ;
2019-10-05 10:32:16 +00:00
addsaver ( vid . fisheye_param , " fisheye parameter " , 1 ) ;
2018-07-30 15:44:11 +00:00
addsaver ( vid . stretch , " stretch " , 1 ) ;
2018-08-14 08:18:18 +00:00
addsaver ( vid . binary_width , " binary-tiling-width " , 1 ) ;
2019-08-14 16:59:21 +00:00
addsaver ( vid . collignon_parameter , " collignon-parameter " , 1 ) ;
addsaver ( vid . collignon_reflected , " collignon-reflect " , false ) ;
2019-02-28 02:41:59 +00:00
2019-08-18 21:10:44 +00:00
addsaver ( vid . plevel_factor , " plevel_factor " , 0.7 ) ;
2019-08-18 19:16:27 +00:00
2019-05-29 14:27:24 +00:00
addsaver ( vid . creature_scale , " 3d-creaturescale " , 1 ) ;
addsaver ( vid . height_width , " 3d-heightwidth " , 1.5 ) ;
2019-02-28 02:41:59 +00:00
2019-02-17 17:28:20 +00:00
# if CAP_GP
2018-04-10 22:53:05 +00:00
addsaver ( gp : : param . first , " goldberg-x " , gp : : param . first ) ;
addsaver ( gp : : param . second , " goldberg-y " , gp : : param . second ) ;
2019-02-17 17:28:20 +00:00
# endif
2018-04-10 22:53:05 +00:00
2018-07-09 16:10:28 +00:00
addsaver ( nohud , " no-hud " , false ) ;
addsaver ( nofps , " no-fps " , false ) ;
2019-02-17 17:28:20 +00:00
# if CAP_IRR
2018-08-22 09:21:49 +00:00
addsaver ( irr : : density , " irregular-density " , 2 ) ;
2018-07-17 12:28:49 +00:00
addsaver ( irr : : cellcount , " irregular-cellcount " , 150 ) ;
addsaver ( irr : : quality , " irregular-quality " , .2 ) ;
addsaver ( irr : : place_attempts , " irregular-place " , 10 ) ;
addsaver ( irr : : rearrange_max_attempts , " irregular-rearrange-max " , 50 ) ;
addsaver ( irr : : rearrange_less , " irregular-rearrangeless " , 10 ) ;
2019-02-17 17:28:20 +00:00
# endif
2018-07-17 12:28:49 +00:00
2018-08-01 09:07:22 +00:00
addsaver ( vid . linequality , " line quality " , 0 ) ;
2018-09-10 17:44:01 +00:00
2019-02-21 17:47:57 +00:00
# if CAP_FILES && CAP_SHOT && CAP_ANIMATIONS
2018-09-10 17:44:01 +00:00
addsaver ( anims : : animfile , " animation file format " ) ;
2018-12-15 16:54:36 +00:00
# endif
2019-02-17 17:43:39 +00:00
# if CAP_ANIMATIONS
2018-09-10 17:44:01 +00:00
addsaver ( anims : : period , " animation period " ) ;
addsaver ( anims : : noframes , " animation frames " ) ;
addsaver ( anims : : cycle_length , " animation cycle length " ) ;
addsaver ( anims : : parabolic_length , " animation parabolic length " ) ;
addsaver ( anims : : rug_angle , " animation rug angle " ) ;
addsaver ( anims : : circle_radius , " animation circle radius " ) ;
addsaver ( anims : : circle_spins , " animation circle spins " ) ;
2019-02-17 17:43:39 +00:00
# endif
2018-12-04 01:36:08 +00:00
2019-02-17 17:28:20 +00:00
# if CAP_CRYSTAL
2018-12-04 01:36:08 +00:00
addsaver ( crystal : : compass_probability , " compass-probability " ) ;
addsaver ( crystal : : view_coordinates , " crystal-coordinates " ) ;
2019-02-17 17:28:20 +00:00
# endif
2018-12-13 12:33:08 +00:00
2018-12-15 14:20:27 +00:00
# if CAP_SHOT
2018-12-13 12:33:08 +00:00
addsaver ( shot : : shotx , " shotx " ) ;
addsaver ( shot : : shoty , " shoty " ) ;
addsaver ( shot : : make_svg , " shotsvg " ) ;
addsaver ( shot : : transparent , " shottransparent " ) ;
addsaver ( shot : : gamma , " shotgamma " ) ;
addsaver ( shot : : caption , " shotcaption " ) ;
addsaver ( shot : : fade , " shotfade " ) ;
2018-12-15 14:20:27 +00:00
# endif
2018-08-04 09:14:47 +00:00
# if CAP_TEXTURE
2018-08-03 08:47:20 +00:00
addsaver ( texture : : texture_aura , " texture-aura " , false ) ;
2018-08-04 09:14:47 +00:00
# endif
2018-11-01 17:59:25 +00:00
addsaver ( vid . use_smart_range , " smart-range " , 0 ) ;
addsaver ( vid . smart_range_detail , " smart-range-detail " , 8 ) ;
2019-03-21 18:13:45 +00:00
addsaver ( vid . smart_range_detail_3 , " smart-range-detail " , 30 ) ;
2018-11-01 17:59:25 +00:00
addsaver ( vid . cells_drawn_limit , " limit on cells drawn " , 10000 ) ;
2019-10-12 11:11:28 +00:00
addsaver ( vid . cells_generated_limit , " limit on cells generated " , 250 ) ;
2018-11-06 14:54:55 +00:00
2019-09-13 17:50:12 +00:00
# if CAP_SOLV
2019-10-03 18:10:48 +00:00
addsaver ( solnihv : : solrange_xy , " solrange-xy " ) ;
addsaver ( solnihv : : solrange_z , " solrange-z " ) ;
2019-09-13 17:50:12 +00:00
# endif
2019-08-25 17:14:03 +00:00
addsaver ( slr : : steps , " slr-steps " ) ;
addsaver ( slr : : range_xy , " slr-range-xy " ) ;
2018-11-06 14:54:55 +00:00
addsaver ( vid . skiprope , " mobius " , 0 ) ;
2018-11-06 23:52:48 +00:00
2019-08-09 22:58:50 +00:00
addsaver ( models : : formula , " formula " ) ;
addsaverenum ( models : : basic_model , " basic model " ) ;
addsaver ( models : : use_atan , " use_atan " ) ;
2019-02-25 16:21:53 +00:00
2019-08-17 12:07:29 +00:00
addsaver ( arcm : : current . symbol , " arcm-symbol " , " 4^5 " ) ;
2019-08-24 12:07:46 +00:00
addsaverenum ( hybrid : : underlying , " product-underlying " ) ;
2019-08-17 12:07:29 +00:00
2019-05-09 17:14:40 +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 )
sightranges [ i ] = 2 * M_PI ;
else if ( ginf [ i ] . cclass = = gcEuclid )
sightranges [ i ] = 10 ;
2019-08-24 09:55:45 +00:00
else if ( ginf [ i ] . cclass = = gcSL2 )
2019-08-25 17:44:24 +00:00
sightranges [ i ] = 4.5 ;
2019-05-09 17:14:40 +00:00
else
sightranges [ i ] = 5 ;
sightranges [ gArchimedean ] = 10 ;
if ( i < gBinary3 ) addsaver ( sightranges [ i ] , " sight-g " + its ( i ) ) ;
}
2019-05-11 15:22:26 +00:00
ld bonus = 0 ;
ld emul = 1 ;
2019-05-09 17:14:40 +00:00
2019-05-11 15:22:26 +00:00
addsaver ( sightranges [ gBinary3 ] , " sight-binary3 " , 3.1 + bonus ) ;
addsaver ( sightranges [ gCubeTiling ] , " sight-cubes " , 10 ) ;
2019-02-25 16:21:53 +00:00
addsaver ( sightranges [ gCell120 ] , " sight-120cell " , 2 * M_PI ) ;
2019-02-25 17:13:09 +00:00
addsaver ( sightranges [ gECell120 ] , " sight-120cell-elliptic " , M_PI ) ;
2019-05-11 15:22:26 +00:00
addsaver ( sightranges [ gRhombic3 ] , " sight-rhombic " , 10.5 * emul ) ;
addsaver ( sightranges [ gBitrunc3 ] , " sight-bitrunc " , 12 * emul ) ;
addsaver ( sightranges [ gSpace534 ] , " sight-534 " , 4 + bonus ) ;
addsaver ( sightranges [ gSpace435 ] , " sight-435 " , 3.8 + bonus ) ;
2019-03-02 23:49:17 +00:00
addsaver ( sightranges [ gCell5 ] , " sight-5cell " , 2 * M_PI ) ;
addsaver ( sightranges [ gCell8 ] , " sight-8cell " , 2 * M_PI ) ;
addsaver ( sightranges [ gECell8 ] , " sight-8cell-elliptic " , M_PI ) ;
addsaver ( sightranges [ gCell16 ] , " sight-16cell " , 2 * M_PI ) ;
addsaver ( sightranges [ gECell16 ] , " sight-16cell-elliptic " , M_PI ) ;
addsaver ( sightranges [ gCell24 ] , " sight-24cell " , 2 * M_PI ) ;
addsaver ( sightranges [ gECell24 ] , " sight-24cell-elliptic " , M_PI ) ;
addsaver ( sightranges [ gCell600 ] , " sight-600cell " , 2 * M_PI ) ;
addsaver ( sightranges [ gECell600 ] , " sight-600cell-elliptic " , M_PI ) ;
2019-05-11 15:22:26 +00:00
addsaver ( sightranges [ gHoroTris ] , " sight-horotris " , 2.9 + bonus ) ;
addsaver ( sightranges [ gHoroRec ] , " sight-hororec " , 2.2 + bonus ) ;
addsaver ( sightranges [ gHoroHex ] , " sight-horohex " , 2.75 + bonus ) ;
2019-07-25 10:24:02 +00:00
addsaver ( sightranges [ gKiteDart3 ] , " sight-kd3 " , 2.25 + bonus ) ;
2019-03-02 23:49:17 +00:00
2019-05-11 15:22:26 +00:00
addsaver ( sightranges [ gField435 ] , " sight-field435 " , 4 + bonus ) ;
addsaver ( sightranges [ gField534 ] , " sight-field534 " , 3.8 + bonus ) ;
2019-08-07 21:29:39 +00:00
addsaver ( sightranges [ gSol ] , " sight-sol " ) ;
addsaver ( sightranges [ gNil ] , " sight-nil " , 6.5 + bonus ) ;
2019-10-12 11:47:58 +00:00
addsaver ( sightranges [ gNIH ] , " sight-nih " ) ;
addsaver ( sightranges [ gSolN ] , " sight-solnih " ) ;
2019-10-26 13:33:28 +00:00
addsaver ( sightranges [ gCrystal344 ] , " sight-crystal344 " , 2.5 ) ; /* assume raycasting */
2019-10-12 11:47:58 +00:00
addsaver ( sightranges [ gSpace344 ] , " sight-344 " , 4.5 ) ;
addsaver ( sightranges [ gSpace336 ] , " sight-336 " , 4 ) ;
2019-08-07 21:29:39 +00:00
2019-05-11 15:22:26 +00:00
addsaver ( vid . sloppy_3d , " sloppy3d " , true ) ;
2019-08-07 21:29:39 +00:00
2019-05-04 18:41:07 +00:00
addsaver ( vid . texture_step , " wall-quality " , 1 ) ;
2019-03-15 13:24:59 +00:00
2019-02-25 17:39:36 +00:00
addsaver ( smooth_scrolling , " smooth-scrolling " , false ) ;
2019-02-26 01:35:30 +00:00
addsaver ( mouseaim_sensitivity , " mouseaim_sensitivity " , 0.01 ) ;
2018-11-01 17:59:25 +00:00
2018-11-18 16:27:27 +00:00
addsaver ( vid . consider_shader_projection , " shader-projection " , true ) ;
2019-01-11 01:24:13 +00:00
2019-01-24 13:50:36 +00:00
# if CAP_RACING
2019-01-11 01:24:13 +00:00
addsaver ( racing : : race_advance , " race_advance " ) ;
addsaver ( racing : : race_angle , " race_angle " ) ;
addsaver ( racing : : ghosts_to_show , " race_ghosts_to_show " ) ;
addsaver ( racing : : ghosts_to_save , " race_ghosts_to_save " ) ;
addsaver ( racing : : guiding , " race_guiding " ) ;
addsaver ( racing : : player_relative , " race_player_relative " ) ;
2019-01-17 00:15:28 +00:00
addsaver ( racing : : standard_centering , " race_standard_centering " ) ;
2019-01-24 13:50:36 +00:00
# endif
2018-11-18 16:27:27 +00:00
2019-04-04 12:36:45 +00:00
addsaver ( bounded_mine_percentage , " bounded_mine_percentage " ) ;
2019-08-06 10:00:46 +00:00
addsaver ( nisot : : geodesic_movement , " solv_geodesic_movement " , true ) ;
2019-07-28 09:07:21 +00:00
2019-09-08 23:35:45 +00:00
addsaver ( s2xe : : qrings , " s2xe-rings " ) ;
2019-09-09 14:06:39 +00:00
addsaver ( rots : : underlying_scale , " rots-underlying-scale " ) ;
2019-09-08 23:35:45 +00:00
2017-08-13 18:49:38 +00:00
# if CAP_SHMUP
2019-08-09 21:08:42 +00:00
multi : : initConfig ( ) ;
2017-08-13 18:49:38 +00:00
# endif
2017-12-14 11:10:40 +00:00
2019-11-16 00:39:58 +00:00
addsaver ( asonov : : period_xy , " asonov:period_xy " ) ;
addsaver ( asonov : : period_z , " asonov:period_z " ) ;
addsaver ( nilv : : nilperiod [ 0 ] , " nilperiod_x " ) ;
addsaver ( nilv : : nilperiod [ 1 ] , " nilperiod_y " ) ;
addsaver ( nilv : : nilperiod [ 2 ] , " nilperiod_z " ) ;
callhooks ( hooks_configfile ) ;
2018-02-03 13:31:17 +00:00
# if CAP_CONFIG
2017-12-14 11:10:40 +00:00
for ( auto s : savers ) s - > reset ( ) ;
2018-02-03 13:31:17 +00:00
# endif
2017-07-10 18:47:38 +00:00
}
2019-08-09 19:00:52 +00:00
EX bool inSpecialMode ( ) {
2018-08-28 15:17:34 +00:00
return chaosmode | | ! BITRUNCATED | | peace : : on | |
2018-02-08 21:27:12 +00:00
# if CAP_TOUR
tour : : on | |
# endif
2017-12-03 18:51:45 +00:00
yendor : : on | | tactic : : on | | randomPatternsMode | |
geometry ! = gNormal | | pmodel ! = mdDisk | | vid . alpha ! = 1 | | vid . scale ! = 1 | |
rug : : rugged | | vid . monmode ! = DEFAULT_MONMODE | |
vid . wallmode ! = DEFAULT_WALLMODE ;
}
2019-08-09 19:00:52 +00:00
EX bool have_current_settings ( ) {
2018-03-24 15:00:13 +00:00
int modecount = 0 ;
if ( inv : : on ) modecount + + ;
if ( shmup : : on ) modecount + = 10 ;
2018-05-07 18:09:58 +00:00
# if CAP_TOUR
2018-03-24 15:00:13 +00:00
if ( tour : : on ) modecount + = 10 ;
2018-05-07 18:09:58 +00:00
# endif
2018-03-24 15:00:13 +00:00
if ( chaosmode ) modecount + = 10 ;
2018-08-28 15:17:34 +00:00
if ( ! BITRUNCATED ) modecount + = 10 ;
2018-03-24 15:00:13 +00:00
if ( peace : : on ) modecount + = 10 ;
if ( yendor : : on ) modecount + = 10 ;
if ( tactic : : on ) modecount + = 10 ;
if ( randomPatternsMode ) modecount + = 10 ;
if ( geometry ! = gNormal ) modecount + = 10 ;
2019-01-02 15:20:14 +00:00
if ( modecount > 1 )
return true ;
2018-03-24 15:00:13 +00:00
2019-01-02 15:20:14 +00:00
return false ;
}
2019-08-09 19:00:52 +00:00
EX bool have_current_graph_settings ( ) {
2018-03-24 15:00:13 +00:00
if ( vid . xposition | | vid . yposition | | vid . alpha ! = 1 | | vid . scale ! = 1 )
return true ;
if ( pmodel ! = mdDisk | | vid . monmode ! = DEFAULT_MONMODE | | vid . wallmode ! = DEFAULT_WALLMODE )
return true ;
2018-11-18 02:18:11 +00:00
if ( firstland ! = laIce | | multi : : players ! = 1 | | rug : : rugged )
2018-03-24 15:00:13 +00:00
return true ;
2019-01-02 15:20:14 +00:00
2018-03-24 15:00:13 +00:00
return false ;
}
2019-08-09 19:00:52 +00:00
EX void reset_graph_settings ( ) {
2019-01-02 15:20:14 +00:00
pmodel = mdDisk ; vid . alpha = 1 ; vid . scale = 1 ;
vid . xposition = vid . yposition = 0 ;
# if CAP_RUG
if ( rug : : rugged ) rug : : close ( ) ;
# endif
vid . monmode = DEFAULT_MONMODE ;
vid . wallmode = DEFAULT_WALLMODE ;
}
2019-08-09 21:48:28 +00:00
EX void resetModes ( char leave IS ( ' c ' ) ) {
2019-05-28 23:09:38 +00:00
while ( game_active | | gamestack : : pushed ( ) ) {
if ( game_active ) stop_game ( ) ;
if ( gamestack : : pushed ( ) ) gamestack : : pop ( ) ;
}
2018-06-10 22:58:38 +00:00
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 ) ;
if ( chaosmode ! = ( leave = = rg : : chaos ) ) stop_game_and_switch_mode ( rg : : chaos ) ;
2018-08-28 15:17:34 +00:00
2018-06-10 22:58:38 +00:00
if ( peace : : on ! = ( leave = = rg : : peace ) ) stop_game_and_switch_mode ( rg : : peace ) ;
2017-08-13 18:49:38 +00:00
# if CAP_TOUR
2018-06-10 22:58:38 +00:00
if ( tour : : on ! = ( leave = = rg : : tour ) ) stop_game_and_switch_mode ( rg : : tour ) ;
2017-08-13 18:49:38 +00:00
# endif
2018-06-10 22:58:38 +00:00
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 ) ;
2018-11-18 02:18:11 +00:00
if ( multi : : players ! = 1 ) {
stop_game_and_switch_mode ( ) ; multi : : players = 1 ;
2018-06-11 16:13:10 +00:00
}
if ( firstland ! = laIce | | specialland ! = laIce ) {
2018-07-11 10:25:19 +00:00
stop_game ( ) ;
2018-06-11 16:13:10 +00:00
firstland = laIce ; specialland = laIce ; stop_game_and_switch_mode ( ) ;
}
2017-12-03 18:51:45 +00:00
2018-08-28 15:17:34 +00:00
set_geometry ( gNormal ) ;
2019-09-12 14:25:48 +00:00
set_variation ( leave = = rg : : heptagons ? eVariation : : pure : eVariation : : bitruncated ) ;
2017-12-03 18:51:45 +00:00
2018-06-10 22:58:38 +00:00
start_game ( ) ;
2017-07-24 22:21:36 +00:00
}
2017-08-13 18:49:38 +00:00
# if CAP_CONFIG
2019-08-09 19:00:52 +00:00
EX void resetConfig ( ) {
2017-07-24 22:21:36 +00:00
dynamicval < int > rx ( vid . xres , 0 ) ;
dynamicval < int > ry ( vid . yres , 0 ) ;
dynamicval < int > rf ( vid . fsize , 0 ) ;
dynamicval < bool > rfs ( vid . full , false ) ;
for ( auto s : savers )
if ( s - > name . substr ( 0 , 5 ) ! = " mode- " )
s - > reset ( ) ;
}
2017-08-13 18:49:38 +00:00
# endif
2017-07-24 22:21:36 +00:00
2017-08-13 18:49:38 +00:00
# if CAP_CONFIG
2019-08-09 19:00:52 +00:00
EX void saveConfig ( ) {
2019-05-12 23:57:40 +00:00
DEBB ( DF_INIT , ( " save config \n " ) ) ;
2017-07-10 18:47:38 +00:00
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 ;
2019-05-29 14:27:24 +00:00
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 ;
2017-07-10 18:47:38 +00:00
}
2017-07-16 21:00:55 +00:00
for ( auto s : savers ) if ( s - > dosave ( ) )
fprintf ( f , " %s=%s \n " , s - > name . c_str ( ) , s - > save ( ) . c_str ( ) ) ;
2017-07-10 18:47:38 +00:00
fclose ( f ) ;
2017-07-22 23:33:27 +00:00
# if ISMOBILE==0
2017-07-10 18:47:38 +00:00
addMessage ( s0 + " Configuration saved to: " + conffile ) ;
# else
addMessage ( s0 + " Configuration saved " ) ;
# endif
}
void readf ( FILE * f , ld & x ) {
double fl = x ;
2018-07-14 06:45:14 +00:00
hr : : ignore ( fscanf ( f , " %lf " , & fl ) ) ;
2017-07-10 18:47:38 +00:00
x = fl ;
}
2017-07-16 21:00:55 +00:00
map < string , shared_ptr < supersaver > > allconfigs ;
2019-08-09 19:00:52 +00:00
EX void parseline ( const string & str ) {
2017-12-14 01:49:32 +00:00
if ( str [ 0 ] = = ' # ' ) return ;
2018-06-22 12:47:24 +00:00
for ( int i = 0 ; i < isize ( str ) ; i + + ) if ( str [ i ] = = ' = ' ) {
2017-07-16 21:00:55 +00:00
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 ( ) ) ;
}
2019-08-09 19:00:52 +00:00
EX void loadNewConfig ( FILE * f ) {
2017-07-16 21:00:55 +00:00
for ( auto & c : savers ) allconfigs [ c - > name ] = c ;
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 ( ) ;
}
2018-11-01 17:59:25 +00:00
2019-08-09 19:00:52 +00:00
EX void loadConfig ( ) {
2018-11-01 19:57:05 +00:00
2019-05-12 23:57:40 +00:00
DEBB ( DF_INIT , ( " load config " ) ) ;
2018-11-01 19:57:05 +00:00
vid . xres = 9999 ; vid . yres = 9999 ; vid . framelimit = 300 ;
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 ) ;
2019-10-22 10:05:22 +00:00
if ( err ! = 4 )
2018-11-01 19:57:05 +00:00
loadNewConfig ( f ) ;
else {
vid . full = fs ;
2019-04-29 11:48:09 +00:00
# if CAP_LEGACY
2018-11-01 19:57:05 +00:00
loadOldConfig ( f ) ;
2019-04-29 11:48:09 +00:00
# endif
2018-11-01 19:57:05 +00:00
}
fclose ( f ) ;
2019-05-12 23:57:40 +00:00
DEBB ( DF_INIT , ( " Loaded configuration: %s \n " , conffile ) ) ;
2018-11-01 19:57:05 +00:00
}
2019-08-22 09:24:25 +00:00
geom3 : : apply_always3 ( ) ;
2018-11-01 19:57:05 +00:00
polygonal : : solve ( ) ;
2019-05-26 16:04:02 +00:00
check_cgi ( ) ;
cgi . prepare_basics ( ) ;
2018-11-01 19:57:05 +00:00
}
# endif
2019-08-09 19:00:52 +00:00
EX void add_cells_drawn ( char c IS ( ' C ' ) ) {
2019-07-31 11:12:35 +00:00
dialog : : addSelItem ( XLAT ( " cells drawn " ) , ( noclipped ? its ( cells_drawn ) + " ( " + its ( noclipped ) + " ) " : its ( cells_drawn ) ) + " / " + its ( vid . cells_drawn_limit ) , c ) ;
2019-03-10 11:12:47 +00:00
dialog : : add_action ( [ ] ( ) {
popScreen ( ) ;
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 ( ) ;
} ) ;
2019-05-11 15:20:57 +00:00
if ( WDIM = = 3 | | vid . use_smart_range = = 2 ) {
2019-06-17 05:22:41 +00:00
dialog : : addSelItem ( XLAT ( " limit generated cells per frame " ) , its ( vid . cells_generated_limit ) , ' L ' ) ;
2019-05-11 15:20:57 +00:00
dialog : : add_action ( [ ] ( ) {
2019-06-17 05:22:41 +00:00
dialog : : editNumber ( vid . cells_generated_limit , 1 , 1000 , log ( 10 ) , 25 , XLAT ( " limit generated cells per frame " ) ,
2019-05-11 15:20:57 +00:00
XLAT ( " In the 3D mode, lowering this value may help if the game lags while exploring new areas. " )
) ;
} ) ;
}
2019-03-10 11:12:47 +00:00
}
2019-07-30 10:58:42 +00:00
string solhelp ( ) {
2019-09-13 17:50:12 +00:00
# if CAP_SOLV
2019-07-30 10:58:42 +00:00
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 "
2019-09-26 11:15:49 +00:00
" the fog effects depends on the geodesic distance, and how far object in X/Y/Z coordinates are rendered. "
2019-07-30 10:58:42 +00:00
) ;
2019-09-13 17:50:12 +00:00
# else
return " " ;
# endif
2019-07-30 10:58:42 +00:00
}
2019-08-09 19:00:52 +00:00
EX void edit_sightrange ( ) {
2019-03-21 18:13:45 +00:00
if ( vid . use_smart_range ) {
2019-05-08 16:33:08 +00:00
ld & det = WDIM = = 2 ? vid . smart_range_detail : vid . smart_range_detail_3 ;
dialog : : editNumber ( det , 1 , 50 , 1 , WDIM = = 2 ? 8 : 30 , XLAT ( " minimum visible cell in pixels " ) , " " ) ;
2019-03-21 18:13:45 +00:00
}
2019-05-08 16:33:08 +00:00
else if ( WDIM = = 3 ) {
2019-03-21 18:13:45 +00:00
dialog : : editNumber ( sightranges [ geometry ] , 0 , 2 * M_PI , 0.5 , M_PI , XLAT ( " 3D sight range " ) ,
2019-08-06 19:01:00 +00:00
( pmodel = = mdGeodesic & & sol ) ? solhelp ( ) : XLAT (
2019-03-21 18:13:45 +00:00
" Sight range for 3D geometries is specified in the absolute units. This value also affects the fog effect. \n \n "
2019-04-04 15:13:15 +00:00
" 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 "
2019-03-21 18:13:45 +00:00
" 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. "
)
) ;
}
else {
2018-11-01 17:59:25 +00:00
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. " ) ) ;
2018-11-09 19:41:55 +00:00
dialog : : reaction = doOvergenerate ;
dialog : : bound_low ( 1 - getDistLimit ( ) ) ;
2019-05-28 23:09:59 +00:00
dialog : : bound_up ( allowIncreasedSight ( ) ? euclid ? 99 : gp : : dist_2 ( ) * 5 : 0 ) ;
2018-11-01 17:59:25 +00:00
}
dialog : : extra_options = [ ] ( ) {
2019-08-06 19:01:00 +00:00
if ( pmodel = = mdGeodesic & & sol ) {
2019-09-13 17:50:12 +00:00
# if CAP_SOLV
2019-07-30 10:58:42 +00:00
dialog : : addSelItem ( XLAT ( " fog effect " ) , fts ( sightranges [ geometry ] ) , ' R ' ) ;
2019-03-21 18:13:45 +00:00
dialog : : add_action ( [ ] {
2019-07-30 10:58:42 +00:00
auto xo = dialog : : extra_options ;
dialog : : editNumber ( sightranges [ geometry ] , 0 , 10 , 0.5 , M_PI , solhelp ( ) , " " ) ;
dialog : : extra_options = xo ; popScreen ( ) ;
2019-03-21 18:13:45 +00:00
} ) ;
2019-10-03 18:10:48 +00:00
dialog : : addSelItem ( XLAT ( " max difference in X/Y coordinates " ) , fts ( solnihv : : solrange_xy ) , ' X ' ) ;
2019-07-30 10:58:42 +00:00
dialog : : add_action ( [ ] {
auto xo = dialog : : extra_options ;
2019-10-03 18:10:48 +00:00
dialog : : editNumber ( solnihv : : solrange_xy , 0.01 , 200 , 0.1 , 50 , XLAT ( " max difference in X/Y coordinates " ) , solhelp ( ) ) , dialog : : scaleLog ( ) ;
2019-07-30 10:58:42 +00:00
dialog : : extra_options = xo ; popScreen ( ) ;
} ) ;
2019-10-03 18:10:48 +00:00
dialog : : addSelItem ( XLAT ( " max difference in Z coordinate " ) , fts ( solnihv : : solrange_z ) , ' Z ' ) ;
2019-07-30 10:58:42 +00:00
dialog : : add_action ( [ ] {
auto xo = dialog : : extra_options ;
2019-10-03 18:10:48 +00:00
dialog : : editNumber ( solnihv : : solrange_z , 0 , 20 , 0.1 , 6 , XLAT ( " max difference in Z coordinates " ) , solhelp ( ) ) ;
2019-07-30 10:58:42 +00:00
dialog : : extra_options = xo ; popScreen ( ) ;
} ) ;
2019-09-13 17:50:12 +00:00
# endif
2019-07-30 10:58:42 +00:00
}
2019-08-25 17:14:03 +00:00
else if ( pmodel = = mdGeodesic & & sl2 ) {
dialog : : addSelItem ( XLAT ( " fog effect " ) , fts ( sightranges [ geometry ] ) , ' R ' ) ;
dialog : : add_action ( [ ] {
auto xo = dialog : : extra_options ;
dialog : : editNumber ( sightranges [ geometry ] , 0 , 10 , 0.5 , M_PI , " " , " " ) ;
dialog : : extra_options = xo ; popScreen ( ) ;
} ) ;
dialog : : addSelItem ( XLAT ( " max difference in X/Y coordinates " ) , fts ( slr : : range_xy ) , ' X ' ) ;
dialog : : add_action ( [ ] {
auto xo = dialog : : extra_options ;
2019-08-25 17:44:10 +00:00
dialog : : editNumber ( slr : : range_xy , 0 , 10 , 0.5 , 4 , XLAT ( " max difference in X/Y coordinates " ) , " " ) ;
2019-08-25 17:14:03 +00:00
dialog : : extra_options = xo ; popScreen ( ) ;
} ) ;
dialog : : addSelItem ( XLAT ( " steps " ) , its ( slr : : steps ) , ' Z ' ) ;
dialog : : add_action ( [ ] {
auto xo = dialog : : extra_options ;
dialog : : editNumber ( slr : : steps , 0 , 50 , 1 , 10 , " " , " " ) ;
dialog : : extra_options = xo ; popScreen ( ) ;
} ) ;
}
2019-07-30 10:58:42 +00:00
else {
dialog : : addBoolItem ( XLAT ( " draw range based on distance " ) , vid . use_smart_range = = 0 , ' D ' ) ;
dialog : : add_action ( [ ] ( ) { vid . use_smart_range = 0 ; popScreen ( ) ; edit_sightrange ( ) ; } ) ;
if ( WDIM = = 2 & & allowIncreasedSight ( ) ) {
dialog : : addBoolItem ( XLAT ( " draw based on size in the projection (no generation) " ) , vid . use_smart_range = = 1 , ' N ' ) ;
dialog : : add_action ( [ ] ( ) { vid . use_smart_range = 1 ; popScreen ( ) ; edit_sightrange ( ) ; } ) ;
}
if ( allowChangeRange ( ) & & allowIncreasedSight ( ) ) {
dialog : : addBoolItem ( XLAT ( " draw based on size in the projection (generation) " ) , vid . use_smart_range = = 2 , ' G ' ) ;
dialog : : add_action ( [ ] ( ) { vid . use_smart_range = 2 ; popScreen ( ) ; edit_sightrange ( ) ; } ) ;
}
if ( vid . use_smart_range = = 0 & & allowChangeRange ( ) & & WDIM = = 2 ) {
dialog : : addSelItem ( XLAT ( " generation range bonus " ) , its ( genrange_bonus ) , ' O ' ) ;
dialog : : add_action ( [ ] ( ) { genrange_bonus = sightrange_bonus ; doOvergenerate ( ) ; } ) ;
dialog : : addSelItem ( XLAT ( " game range bonus " ) , its ( gamerange_bonus ) , ' S ' ) ;
dialog : : add_action ( [ ] ( ) { gamerange_bonus = sightrange_bonus ; doOvergenerate ( ) ; } ) ;
}
if ( ! allowChangeRange ( ) | | ! allowIncreasedSight ( ) ) {
dialog : : addItem ( XLAT ( " enable the cheat mode for additional options " ) , ' X ' ) ;
dialog : : add_action ( enable_cheat ) ;
}
if ( WDIM = = 3 & & ! vid . use_smart_range ) {
dialog : : addBoolItem_action ( XLAT ( " sloppy range checking " ) , vid . sloppy_3d , ' S ' ) ;
}
2019-08-15 13:05:43 +00:00
if ( GDIM = = 3 & & ! vid . use_smart_range ) {
2019-07-30 10:58:42 +00:00
dialog : : addSelItem ( XLAT ( " limit generation " ) , fts ( extra_generation_distance ) , ' E ' ) ;
dialog : : add_action ( [ ] {
auto xo = dialog : : extra_options ;
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. "
) ;
dialog : : extra_options = xo ; popScreen ( ) ;
} ) ;
}
2019-03-21 18:13:45 +00:00
}
2019-03-10 11:12:47 +00:00
add_cells_drawn ( ' C ' ) ;
2019-05-09 17:14:40 +00:00
if ( GDIM = = 3 & & WDIM = = 2 & & pmodel = = mdPerspective ) {
dialog : : addSelItem ( XLAT ( " fog effect " ) , fts ( sightranges [ geometry ] ) , ' R ' ) ;
dialog : : add_action ( [ ] {
2019-07-30 10:58:42 +00:00
auto xo = dialog : : extra_options ;
2019-05-09 17:14:40 +00:00
dialog : : editNumber ( sightranges [ geometry ] , 0 , 2 * M_PI , 0.5 , M_PI , XLAT ( " fog effect " ) , " " ) ;
2019-07-30 10:58:42 +00:00
dialog : : extra_options = xo ; popScreen ( ) ;
2019-05-09 17:14:40 +00:00
} ) ;
} ;
2018-11-01 17:59:25 +00:00
} ;
}
2019-08-09 20:37:11 +00:00
EX void menuitem_sightrange ( char c IS ( ' c ' ) ) {
2019-03-21 18:13:45 +00:00
if ( vid . use_smart_range )
2019-05-08 16:33:08 +00:00
dialog : : addSelItem ( XLAT ( " minimum visible cell in pixels " ) , fts ( WDIM = = 3 ? vid . smart_range_detail_3 : vid . smart_range_detail ) , c ) ;
2019-09-13 17:50:12 +00:00
# if CAP_SOLV
2019-08-06 19:01:00 +00:00
else if ( pmodel = = mdGeodesic & & sol )
2019-10-03 18:10:48 +00:00
dialog : : addSelItem ( XLAT ( " 3D sight range " ) , fts ( solnihv : : solrange_xy ) + " x " + fts ( solnihv : : solrange_z ) , c ) ;
2019-09-13 17:50:12 +00:00
# endif
2019-05-08 16:33:08 +00:00
else if ( WDIM = = 3 )
2019-02-25 16:21:53 +00:00
dialog : : addSelItem ( XLAT ( " 3D sight range " ) , fts ( sightranges [ geometry ] ) , c ) ;
2019-03-21 18:13:45 +00:00
else
dialog : : addSelItem ( XLAT ( " sight range " ) , its ( sightrange_bonus ) , c ) ;
dialog : : add_action ( edit_sightrange ) ;
2018-11-01 17:59:25 +00:00
}
2017-07-16 21:00:55 +00:00
2019-08-09 19:00:52 +00:00
EX void showGraphConfig ( ) {
2017-12-03 10:48:02 +00:00
cmode = vid . xres > vid . yres * 1.4 ? sm : : SIDE : sm : : MAYDARK ;
2017-07-12 17:50:39 +00:00
gamescreen ( 0 ) ;
2017-07-10 18:47:38 +00:00
dialog : : init ( XLAT ( " graphics configuration " ) ) ;
2017-07-22 23:33:27 +00:00
# if CAP_GLORNOT
2017-07-10 18:47:38 +00:00
dialog : : addBoolItem ( XLAT ( " openGL mode " ) , vid . usingGL , ' o ' ) ;
# endif
if ( ! vid . usingGL )
dialog : : addBoolItem ( XLAT ( " anti-aliasing " ) , vid . antialias & AA_NOGL , ' O ' ) ;
if ( vid . usingGL )
dialog : : addSelItem ( XLAT ( " anti-aliasing " ) ,
( vid . antialias & AA_POLY ) ? " polygons " :
( vid . antialias & AA_LINES ) ? " lines " :
( vid . antialias & AA_MULTI ) ? " multisampling " :
" NO " , ' O ' ) ;
if ( vid . usingGL ) {
dialog : : addSelItem ( XLAT ( " line width " ) , fts ( vid . linewidth ) , ' w ' ) ;
// dialog::addBoolItem(XLAT("finer lines at the boundary"), vid.antialias & AA_LINEWIDTH, 'b');
}
2018-07-21 22:39:57 +00:00
else
dialog : : addBreak ( 100 ) ;
2018-08-01 09:07:22 +00:00
dialog : : addSelItem ( XLAT ( " line quality " ) , its ( vid . linequality ) , ' L ' ) ;
2017-07-10 18:47:38 +00:00
2017-07-22 23:33:27 +00:00
# if CAP_FRAMELIMIT
2017-07-10 18:47:38 +00:00
dialog : : addSelItem ( XLAT ( " framerate limit " ) , its ( vid . framelimit ) , ' l ' ) ;
2017-07-12 16:03:53 +00:00
if ( getcstat = = ' l ' )
mouseovers = XLAT ( " Reduce the framerate limit to conserve CPU energy " ) ;
2017-07-10 18:47:38 +00:00
# endif
2017-07-22 23:33:27 +00:00
# if !ISIOS && !ISWEB
2017-07-10 18:47:38 +00:00
dialog : : addBoolItem ( XLAT ( " fullscreen mode " ) , ( vid . full ) , ' f ' ) ;
# endif
dialog : : addSelItem ( XLAT ( " scrolling speed " ) , fts ( vid . sspeed ) , ' a ' ) ;
2017-07-12 16:03:53 +00:00
2017-07-10 18:47:38 +00:00
dialog : : addSelItem ( XLAT ( " movement animation speed " ) , fts ( vid . mspeed ) , ' m ' ) ;
dialog : : addBoolItem ( XLAT ( " extra graphical effects " ) , ( vid . particles ) , ' u ' ) ;
2017-10-17 19:26:21 +00:00
dialog : : addBoolItem ( XLAT ( " background particle effects " ) , ( vid . backeffects ) , ' p ' ) ;
2017-07-10 18:47:38 +00:00
2019-03-30 22:45:28 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
2017-07-10 18:47:38 +00:00
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
if ( uni = = ' O ' ) uni = ' o ' , shiftmul = - 1 ;
char xuni = uni | 96 ;
2018-11-08 20:56:06 +00:00
if ( ( uni > = 32 & & uni < 64 ) | | uni = = ' L ' | | uni = = ' C ' ) xuni = uni ;
2018-07-23 03:14:19 +00:00
2017-07-10 18:47:38 +00:00
if ( xuni = = ' u ' ) vid . particles = ! vid . particles ;
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' a ' ) dialog : : editNumber ( vid . sspeed , - 5 , 5 , 1 , 0 ,
2017-07-10 18:47:38 +00:00
XLAT ( " scrolling speed " ) ,
2017-07-12 16:03:53 +00:00
XLAT ( " +5 = center instantly, -5 = do not center the map " )
+ " \n \n " +
XLAT ( " press Space or Home to center on the PC " ) ) ;
2017-07-10 18:47:38 +00:00
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' m ' ) dialog : : editNumber ( vid . mspeed , - 5 , 5 , 1 , 0 ,
2017-07-10 18:47:38 +00:00
XLAT ( " movement animation speed " ) ,
XLAT ( " +5 = move instantly " ) ) ;
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' f ' ) switchFullscreen ( ) ;
2017-07-10 18:47:38 +00:00
2017-07-22 23:33:27 +00:00
# if CAP_GLORNOT
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' o ' & & shiftmul > 0 ) switchGL ( ) ;
2017-07-10 18:47:38 +00:00
# endif
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' o ' & & shiftmul < 0 ) {
2017-07-10 18:47:38 +00:00
if ( ! vid . usingGL )
vid . antialias ^ = AA_NOGL | AA_FONT ;
else if ( vid . antialias & AA_MULTI )
vid . antialias ^ = AA_MULTI ;
else if ( vid . antialias & AA_POLY )
vid . antialias ^ = AA_POLY | AA_LINES | AA_MULTI ;
else if ( vid . antialias & AA_LINES )
vid . antialias | = AA_POLY ;
else
vid . antialias | = AA_LINES ;
2017-07-22 23:33:27 +00:00
# if CAP_SDL
2017-07-10 18:47:38 +00:00
setvideomode ( ) ;
2017-07-22 23:33:27 +00:00
# endif
2017-07-10 18:47:38 +00:00
}
// if(xuni == 'b') vid.antialias ^= AA_LINEWIDTH;
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' w ' & & vid . usingGL ) {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . linewidth , 0 , 10 , 0.1 , 1 , XLAT ( " line width " ) , " " ) ;
2018-08-01 01:59:20 +00:00
dialog : : extra_options = [ ] ( ) {
2018-11-09 21:18:18 +00:00
dialog : : addBoolItem ( " finer lines at the boundary " , vid . antialias & AA_LINEWIDTH , ' O ' ) ;
2018-08-01 01:59:20 +00:00
dialog : : add_action ( [ ] ( ) { vid . antialias ^ = AA_LINEWIDTH ; } ) ;
} ;
}
2018-08-01 09:07:22 +00:00
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' L ' ) {
2018-08-01 09:07:22 +00:00
dialog : : editNumber ( vid . linequality , - 3 , 5 , 1 , 1 , XLAT ( " line quality " ) ,
2018-08-01 11:31:13 +00:00
XLAT ( " Higher numbers make the curved lines smoother, but reduce the performance. " ) ) ;
2018-08-01 09:07:22 +00:00
}
2017-07-10 18:47:38 +00:00
2017-07-22 23:33:27 +00:00
# if CAP_FRAMELIMIT
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' l ' ) {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . framelimit , 5 , 300 , 10 , 300 , XLAT ( " framerate limit " ) , " " ) ;
2018-11-09 19:41:55 +00:00
dialog : : bound_low ( 5 ) ;
}
2017-07-22 23:33:27 +00:00
# endif
2019-03-30 22:45:28 +00:00
else if ( xuni = = ' p ' )
2017-10-17 19:26:21 +00:00
vid . backeffects = ! vid . backeffects ;
2019-03-30 22:45:28 +00:00
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
2017-07-10 18:47:38 +00:00
} ;
}
2019-08-09 19:00:52 +00:00
EX void switchFullscreen ( ) {
2017-07-10 18:47:38 +00:00
vid . full = ! vid . full ;
2017-07-22 23:33:27 +00:00
# if ISANDROID
2017-07-10 18:47:38 +00:00
addMessage ( XLAT ( " Reenter HyperRogue to apply this setting " ) ) ;
2017-08-06 12:50:16 +00:00
ANDROID_SETTINGS
2017-07-10 18:47:38 +00:00
# endif
2017-07-22 23:33:27 +00:00
# if CAP_SDL
2017-07-10 18:47:38 +00:00
if ( true ) {
vid . xres = vid . full ? vid . xscr : 9999 ;
vid . yres = vid . full ? vid . yscr : 9999 ;
extern bool setfsize ;
setfsize = true ;
}
setvideomode ( ) ;
# endif
}
2019-08-09 19:00:52 +00:00
EX void switchGL ( ) {
2017-07-10 18:47:38 +00:00
vid . usingGL = ! vid . usingGL ;
if ( vid . usingGL ) addMessage ( XLAT ( " openGL mode enabled " ) ) ;
if ( ! vid . usingGL ) addMessage ( XLAT ( " openGL mode disabled " ) ) ;
2017-08-06 12:50:16 +00:00
ANDROID_SETTINGS ;
# if CAP_SDL
2017-07-10 18:47:38 +00:00
setvideomode ( ) ;
2018-04-21 10:02:33 +00:00
if ( vid . usingGL ) {
glhr : : be_textured ( ) ; glhr : : be_nontextured ( ) ;
}
2017-07-10 18:47:38 +00:00
# endif
}
2019-08-09 19:00:52 +00:00
EX void edit_whatever ( char type , int index ) {
2019-05-05 15:29:56 +00:00
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 ) ) ;
}
dialog : : extra_options = [ type , index ] {
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 ) ; } ) ;
}
} ;
}
2019-08-09 19:00:52 +00:00
EX void configureOther ( ) {
2017-07-10 18:47:38 +00:00
gamescreen ( 3 ) ;
2019-04-04 15:13:15 +00:00
dialog : : init ( XLAT ( " other settings " ) ) ;
2017-07-22 23:33:27 +00:00
# if ISSTEAM
2017-10-27 18:08:48 +00:00
dialog : : addBoolItem ( XLAT ( " send scores to Steam leaderboards " ) , ( vid . steamscore & 1 ) , ' x ' ) ;
2019-03-30 22:45:28 +00:00
dialog : : add_action ( [ ] { vid . steamscore = vid . steamscore ^ 1 ; } ) ;
2017-07-10 18:47:38 +00:00
# endif
2019-05-03 10:11:40 +00:00
dialog : : addBoolItem_action ( XLAT ( " skip the start menu " ) , vid . skipstart , ' m ' ) ;
2019-06-06 17:37:17 +00:00
dialog : : addItem ( XLAT ( " memory configuration " ) , ' y ' ) ;
dialog : : add_action_push ( show_memory_menu ) ;
2017-08-06 12:50:16 +00:00
2019-06-06 17:37:17 +00:00
// dialog::addBoolItem_action(XLAT("forget faraway cells"), memory_saving_mode, 'y');
2019-05-06 23:08:49 +00:00
# if CAP_AUDIO
2019-03-30 22:45:28 +00:00
if ( CAP_AUDIO ) {
dialog : : addSelItem ( XLAT ( " background music volume " ) , its ( musicvolume ) , ' b ' ) ;
dialog : : add_action ( [ ] {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( musicvolume , 0 , 128 , 10 , 60 , XLAT ( " background music volume " ) , " " ) ;
2018-11-09 19:41:55 +00:00
dialog : : reaction = [ ] ( ) {
# if CAP_SDLAUDIO
Mix_VolumeMusic ( musicvolume ) ;
# endif
# if ISANDROID
settingsChanged = true ;
# endif
} ;
dialog : : bound_low ( 0 ) ;
dialog : : bound_up ( MIX_MAX_VOLUME ) ;
2019-03-30 22:45:28 +00:00
} ) ;
2018-11-09 19:41:55 +00:00
2019-03-30 22:45:28 +00:00
dialog : : addSelItem ( XLAT ( " sound effects volume " ) , its ( effvolume ) , ' e ' ) ;
dialog : : add_action ( [ ] {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( effvolume , 0 , 128 , 10 , 60 , XLAT ( " sound effects volume " ) , " " ) ;
2018-11-09 19:41:55 +00:00
dialog : : reaction = [ ] ( ) {
# if ISANDROID
settingsChanged = true ;
# endif
} ;
dialog : : bound_low ( 0 ) ;
dialog : : bound_up ( MIX_MAX_VOLUME ) ;
2019-03-30 22:45:28 +00:00
} ) ;
}
2019-05-06 23:08:49 +00:00
# endif
2019-03-30 22:45:28 +00:00
menuitem_sightrange ( ' r ' ) ;
2019-05-05 15:29:56 +00:00
# ifdef WHATEVER
dialog : : addSelItem ( XLAT ( " whatever " ) , fts ( whatever [ 0 ] ) , ' j ' ) ;
dialog : : add_action ( [ ] { edit_whatever ( ' f ' , 0 ) ; } ) ;
# endif
2019-03-30 22:45:28 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
2017-07-10 18:47:38 +00:00
2019-03-30 22:45:28 +00:00
dialog : : display ( ) ;
}
2017-10-08 12:49:49 +00:00
2019-08-09 19:00:52 +00:00
EX void configureInterface ( ) {
2019-03-30 22:45:28 +00:00
gamescreen ( 3 ) ;
dialog : : init ( XLAT ( " interface " ) ) ;
2019-09-13 01:10:26 +00:00
# if CAP_TRANS
2019-03-30 22:45:28 +00:00
if ( CAP_TRANS ) {
dialog : : addSelItem ( XLAT ( " language " ) , XLAT ( " EN " ) , ' l ' ) ;
dialog : : add_action_push ( selectLanguageScreen ) ;
}
2019-09-13 01:10:26 +00:00
# endif
2019-03-30 22:45:28 +00:00
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 ) ;
} ) ;
const char * msgstyles [ 3 ] = { " centered " , " left-aligned " , " line-broken " } ;
2017-07-10 18:47:38 +00:00
2019-03-30 22:45:28 +00:00
dialog : : addSelItem ( XLAT ( " message style " ) , XLAT ( msgstyles [ vid . msgleft ] ) , ' a ' ) ;
dialog : : add_action ( [ ] {
vid . msgleft = ( 1 + vid . msgleft ) % 3 ;
} ) ;
dialog : : addSelItem ( XLAT ( " font scale " ) , its ( fontscale ) , ' b ' ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( fontscale , 25 , 400 , 10 , 100 , XLAT ( " font scale " ) , " " ) ;
const int minfontscale = ISMOBILE ? 50 : 25 ;
dialog : : reaction = [ ] ( ) { setfsize = true ; do_setfsize ( ) ; } ;
dialog : : bound_low ( minfontscale ) ;
} ) ;
const char * glyphsortnames [ 6 ] = {
" first on top " , " first on bottom " ,
" last on top " , " last on bottom " ,
" by land " , " by number "
2017-07-10 18:47:38 +00:00
} ;
2019-03-30 22:45:28 +00:00
dialog : : addSelItem ( XLAT ( " inventory/kill sorting " ) , XLAT ( glyphsortnames [ glyphsortorder ] ) , ' k ' ) ;
dialog : : add_action ( [ ] {
glyphsortorder = eGlyphsortorder ( ( glyphsortorder + 6 + ( shiftmul > 0 ? 1 : - 1 ) ) % gsoMAX ) ;
} ) ;
const char * glyphmodenames [ 3 ] = { " letters " , " auto " , " images " } ;
dialog : : addSelItem ( XLAT ( " inventory/kill mode " ) , XLAT ( glyphmodenames [ vid . graphglyph ] ) , ' d ' ) ;
dialog : : add_action ( [ ] {
vid . graphglyph = ( 1 + vid . graphglyph ) % 3 ;
} ) ;
2019-09-09 14:10:57 +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 ) ;
dialog : : extra_options = [ ] {
dialog : : addColorItem ( XLAT ( " crosshair color " ) , crosshair_color , ' X ' ) ;
dialog : : add_action ( [ ] { dialog : : openColorDialog ( crosshair_color ) ; } ) ;
} ;
} ) ;
2019-03-30 22:45:28 +00:00
dialog : : addBreak ( 50 ) ;
dialog : : addBack ( ) ;
dialog : : display ( ) ;
2017-07-10 18:47:38 +00:00
}
2017-07-22 23:33:27 +00:00
# if CAP_SDLJOY
2019-08-09 19:00:52 +00:00
EX void showJoyConfig ( ) {
2017-07-10 18:47:38 +00:00
gamescreen ( 4 ) ;
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 ) ;
dialog : : addSelItem ( XLAT ( " joystick mode " ) , XLAT ( autojoy ? " automatic " : " manual " ) , ' p ' ) ;
2017-07-12 16:03:53 +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) " ) ;
}
2017-07-10 18:47:38 +00:00
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 ' ) ;
2017-10-29 19:16:29 +00:00
dialog : : addBreak ( 50 ) ;
2018-06-12 22:00:01 +00:00
dialog : : addBack ( ) ;
2017-07-10 18:47:38 +00:00
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
2018-06-12 22:00:01 +00:00
if ( uni = = ' p ' ) autojoy = ! autojoy ;
2018-12-25 22:53:52 +00:00
else if ( uni = = ' a ' ) {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . joyvalue , 0 , 32768 , 100 , 4800 , XLAT ( " first joystick: movement threshold " ) , " " ) ;
2018-12-25 22:53:52 +00:00
dialog : : bound_low ( 0 ) ;
}
else if ( uni = = ' b ' ) {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . joyvalue2 , 0 , 32768 , 100 , 5600 , XLAT ( " first joystick: execute movement threshold " ) , " " ) ;
2018-12-25 22:53:52 +00:00
dialog : : bound_low ( 0 ) ;
}
else if ( uni = = ' c ' ) {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . joypanthreshold , 0 , 32768 , 100 , 2500 , XLAT ( " second joystick: pan threshold " ) , " " ) ;
2018-12-25 22:53:52 +00:00
dialog : : bound_low ( 0 ) ;
}
else if ( uni = = ' d ' )
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . joypanspeed , 0 , 1e-2 , 1e-5 , 1e-4 , XLAT ( " second joystick: panning speed " ) , " " ) ;
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
2017-07-22 23:33:27 +00:00
# endif
2017-07-10 18:47:38 +00:00
2019-08-09 19:00:52 +00:00
EX void projectionDialog ( ) {
2019-05-29 14:27:24 +00:00
vid . tc_alpha = ticks ;
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . alpha , - 5 , 5 , .1 , 1 ,
XLAT ( " projection " ) ,
XLAT ( " HyperRogue uses the Minkowski hyperboloid model internally. "
2017-07-12 17:50:39 +00:00
" Klein and Poincaré models can be obtained by perspective, "
2017-07-10 18:47:38 +00:00
" and the Gans model is obtained by orthogonal projection. "
// "This parameter specifies the distance from the hyperboloid center "
// "to the eye. "
" See also the conformal mode (in the special modes menu) "
" for more models. " ) ) ;
2018-08-01 01:59:20 +00:00
dialog : : extra_options = [ ] ( ) {
dialog : : addBreak ( 100 ) ;
2019-06-01 17:25:24 +00:00
if ( GDIM = = 2 ) dialog : : addHelp ( XLAT (
2019-05-04 18:40:46 +00:00
" 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. " ) ) ;
2018-11-09 21:18:18 +00:00
dialog : : addSelItem ( sphere ? " stereographic " : " Poincaré model " , " 1 " , ' P ' ) ;
2018-08-01 01:59:20 +00:00
dialog : : add_action ( [ ] ( ) { * dialog : : ne . editwhat = 1 ; vid . scale = 1 ; dialog : : ne . s = " 1 " ; } ) ;
2018-11-09 21:18:18 +00:00
dialog : : addSelItem ( sphere ? " gnomonic " : " Klein model " , " 0 " , ' K ' ) ;
2018-08-01 01:59:20 +00:00
dialog : : add_action ( [ ] ( ) { * dialog : : ne . editwhat = 0 ; vid . scale = 1 ; dialog : : ne . s = " 0 " ; } ) ;
2019-03-23 15:28:25 +00:00
if ( hyperbolic ) {
2019-04-04 15:13:15 +00:00
dialog : : addSelItem ( " inverted Poincaré model " , " -1 " , ' I ' ) ;
2019-03-23 15:28:25 +00:00
dialog : : add_action ( [ ] ( ) { * dialog : : ne . editwhat = - 1 ; vid . scale = 1 ; dialog : : ne . s = " -1 " ; } ) ;
}
dialog : : addItem ( sphere ? " orthographic " : " Gans model " , ' O ' ) ;
dialog : : add_action ( [ ] ( ) { vid . alpha = vid . scale = 999 ; dialog : : ne . s = dialog : : disp ( vid . alpha ) ; } ) ;
dialog : : addItem ( sphere ? " towards orthographic " : " towards Gans model " , ' T ' ) ;
2019-03-10 17:59:05 +00:00
dialog : : add_action ( [ ] ( ) { double d = 1.1 ; vid . alpha * = d ; vid . scale * = d ; dialog : : ne . s = dialog : : disp ( vid . alpha ) ; } ) ;
2018-08-01 01:59:20 +00:00
} ;
2017-07-10 18:47:38 +00:00
}
2019-08-09 19:00:52 +00:00
EX void explain_detail ( ) {
2019-05-04 18:40:46 +00:00
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. " ,
2019-05-29 14:27:24 +00:00
fts ( vid . highdetail ) , fts ( vid . middetail )
2019-05-04 18:40:46 +00:00
) ) ;
2017-07-10 18:47:38 +00:00
}
2019-08-09 19:00:52 +00:00
EX void add_edit_fov ( char key IS ( ' f ' ) ) {
2019-02-28 02:41:59 +00:00
dialog : : addSelItem ( XLAT ( " field of view " ) , fts ( vid . fov ) + " ° " , key ) ;
dialog : : add_action ( [ ] {
dialog : : editNumber ( vid . fov , 1 , 170 , 1 , 45 , " 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. " )
) ;
dialog : : bound_low ( 1e-8 ) ;
dialog : : bound_up ( 179 ) ;
} ) ;
}
2019-10-21 20:42:27 +00:00
bool supported_ods ( ) {
if ( ! CAP_ODS ) return false ;
return rug : : rugged | | ( hyperbolic & & GDIM = = 3 ) ;
}
2019-08-09 19:00:52 +00:00
EX void showStereo ( ) {
2018-12-13 16:02:10 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
2018-02-03 12:41:49 +00:00
gamescreen ( 0 ) ;
dialog : : init ( XLAT ( " stereo vision config " ) ) ;
2018-02-13 12:37:20 +00:00
string modenames [ 4 ] = { " OFF " , " anaglyph " , " side-by-side " , " ODS " } ;
2018-02-03 12:41:49 +00:00
2018-11-17 18:24:02 +00:00
dialog : : addSelItem ( XLAT ( " stereo mode " ) , XLAT ( modenames [ vid . stereo_mode ] ) , ' m ' ) ;
2019-05-21 22:01:30 +00:00
dialog : : addSelItem ( XLAT ( " pupillary distance " ) , fts ( vid . ipd ) , ' e ' ) ;
2018-02-03 12:41:49 +00:00
2018-11-17 18:24:02 +00:00
switch ( vid . stereo_mode ) {
case sAnaglyph :
dialog : : addSelItem ( XLAT ( " distance between images " ) , fts ( vid . anaglyph_eyewidth ) , ' d ' ) ;
2018-02-03 12:41:49 +00:00
break ;
2018-11-17 18:24:02 +00:00
case sLR :
dialog : : addSelItem ( XLAT ( " distance between images " ) , fts ( vid . lr_eyewidth ) , ' d ' ) ;
2018-02-03 12:41:49 +00:00
break ;
default :
dialog : : addBreak ( 100 ) ;
break ;
}
2019-02-28 02:41:59 +00:00
2019-03-09 02:32:24 +00:00
dialog : : addSelItem ( XLAT ( " desaturate colors " ) , its ( vid . desaturate ) + " % " , ' c ' ) ;
dialog : : add_action ( [ ] {
2019-04-04 15:13:15 +00:00
dialog : : editNumber ( vid . desaturate , 0 , 100 , 10 , 0 , XLAT ( " desaturate colors " ) ,
2019-03-09 02:32:24 +00:00
XLAT ( " Make the game colors less saturated. This is useful in the anaglyph mode. " )
) ;
} ) ;
2019-02-28 02:41:59 +00:00
add_edit_fov ( ' f ' ) ;
2018-02-03 12:41:49 +00:00
2018-06-12 22:00:01 +00:00
dialog : : addBack ( ) ;
2018-02-03 12:41:49 +00:00
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
2018-02-13 12:37:20 +00:00
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 " ;
2018-02-03 12:41:49 +00:00
2019-10-21 20:42:27 +00:00
if ( uni = = ' m ' ) {
vid . stereo_mode = eStereo ( ( 1 + vid . stereo_mode ) % 4 ) ;
if ( vid . stereo_mode = = sODS & & ! supported_ods ( ) ) vid . stereo_mode = sOFF ;
}
2018-02-03 12:41:49 +00:00
else if ( uni = = ' e ' )
2018-11-17 18:24:02 +00:00
dialog : : editNumber ( vid . ipd , - 10 , 10 , 0.01 , 0 , XLAT ( " pupillary distance " ) ,
2018-02-13 12:37:20 +00:00
help3 +
XLAT ( " The distance between your eyes in the represented 3D object. This is given in absolute units. " )
2019-07-03 02:55:27 +00:00
) , dialog : : scaleSinh100 ( ) ;
2018-02-03 12:41:49 +00:00
2018-11-17 18:24:02 +00:00
else if ( uni = = ' d ' & & vid . stereo_mode = = sAnaglyph )
dialog : : editNumber ( vid . anaglyph_eyewidth , - 1 , 1 , 0.01 , 0 , XLAT ( " distance between images " ) ,
2018-02-13 12:37:20 +00:00
help3 +
XLAT ( " The distance between your eyes. 1 is the width of the screen. " ) ) ;
2018-02-03 12:41:49 +00:00
2018-11-17 18:24:02 +00:00
else if ( uni = = ' d ' & & vid . stereo_mode = = sLR )
dialog : : editNumber ( vid . lr_eyewidth , - 1 , 1 , 0.01 , 0 , XLAT ( " distance between images " ) ,
2018-02-13 12:37:20 +00:00
help3 +
XLAT ( " The distance between your eyes. 1 is the width of the screen. " ) ) ;
2018-02-03 12:41:49 +00:00
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
2019-08-09 19:00:52 +00:00
EX void config_camera_rotation ( ) {
2018-03-24 14:15:30 +00:00
dialog : : editNumber ( vid . ballangle , 0 , 90 , 5 , 0 , XLAT ( " camera rotation in 3D models " ) ,
" Rotate the camera in 3D models (ball model, hyperboloid, and hemisphere). "
" Note that hyperboloid and hemisphere models are also available in the "
" Hypersian Rug surfaces menu, but they are rendered differently there -- "
2018-03-25 12:04:55 +00:00
" by making a flat picture first, then mapping it to a surface. "
2018-03-24 14:15:30 +00:00
" This makes the output better in some ways, but 3D effects are lost. "
" Hypersian Rug model also allows more camera freedom. "
) ;
}
2019-08-09 19:00:52 +00:00
EX void add_edit_wall_quality ( char c ) {
2019-05-09 15:54:30 +00:00
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 "
2019-06-17 23:40:38 +00:00
" (floors in 2D geometries, honeycombs based on horospheres, and projections other than native perspective), "
2019-05-09 15:54:30 +00:00
" 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 ) ;
dialog : : reaction = [ ] {
2019-05-10 01:16:40 +00:00
# if MAXMDIM >= 4
2019-05-09 15:54:30 +00:00
if ( floor_textures ) {
delete floor_textures ;
floor_textures = NULL ;
}
2019-05-10 01:16:40 +00:00
# endif
2019-05-09 15:54:30 +00:00
} ;
} ) ;
}
2019-11-03 12:36:06 +00:00
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. " )
) ;
dialog : : reaction = ray : : reset_raycaster ;
dialog : : extra_options = [ ] {
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 ) ;
} ) ;
}
2019-08-09 19:00:52 +00:00
EX void show3D ( ) {
2019-05-04 18:40:46 +00:00
cmode = sm : : SIDE | sm : : MAYDARK ;
2017-07-12 17:50:39 +00:00
gamescreen ( 0 ) ;
2017-07-10 18:47:38 +00:00
dialog : : init ( XLAT ( " 3D configuration " ) ) ;
2019-05-11 06:19:38 +00:00
# if MAXMDIM >= 4
2019-05-08 23:39:32 +00:00
if ( WDIM = = 2 ) {
2019-05-29 14:27:24 +00:00
dialog : : addBoolItem ( XLAT ( " use the full 3D models " ) , vid . always3 , ' U ' ) ;
2019-05-09 15:01:08 +00:00
dialog : : add_action ( geom3 : : switch_always3 ) ;
2019-05-08 23:39:32 +00:00
}
2019-05-11 06:19:38 +00:00
# endif
2019-08-15 13:05:43 +00:00
if ( vid . use_smart_range = = 0 & & GDIM = = 2 ) {
2019-05-29 14:27:24 +00:00
dialog : : addSelItem ( XLAT ( " High detail range " ) , fts ( vid . highdetail ) , ' n ' ) ;
dialog : : addSelItem ( XLAT ( " Mid detail range " ) , fts ( vid . middetail ) , ' m ' ) ;
2018-11-01 17:59:25 +00:00
dialog : : addBreak ( 50 ) ;
}
2017-07-10 18:47:38 +00:00
2019-05-08 16:33:08 +00:00
if ( WDIM = = 2 ) {
2019-05-29 14:27:24 +00:00
dialog : : addSelItem ( XLAT ( GDIM = = 2 ? " Camera level above the plane " : " Z shift " ) , fts ( vid . camera ) , ' c ' ) ;
2019-06-01 17:58:07 +00:00
if ( GDIM = = 3 )
dialog : : addSelItem ( XLAT ( " Eye level " ) , fts ( vid . eye ) , ' E ' ) ;
2019-05-29 14:27:24 +00:00
dialog : : addSelItem ( XLAT ( " Ground level below the plane " ) , fts ( vid . depth ) , ' g ' ) ;
2019-06-06 17:37:17 +00:00
2017-07-10 18:47:38 +00:00
2019-06-01 17:25:24 +00:00
if ( GDIM = = 2 )
dialog : : addSelItem ( XLAT ( " Projection at the ground level " ) , fts ( vid . alpha ) , ' p ' ) ;
2019-07-28 09:07:21 +00:00
else if ( ! in_perspective ( ) )
2019-06-01 17:25:24 +00:00
dialog : : addSelItem ( XLAT ( " Projection distance " ) , fts ( vid . alpha ) , ' p ' ) ;
2019-02-28 02:41:59 +00:00
dialog : : addBreak ( 50 ) ;
2019-05-29 14:27:24 +00:00
dialog : : addSelItem ( XLAT ( " Height of walls " ) , fts ( vid . wall_height ) , ' w ' ) ;
2019-02-28 02:41:59 +00:00
2019-05-29 14:27:24 +00:00
dialog : : addSelItem ( XLAT ( " Rock-III to wall ratio " ) , fts ( vid . rock_wall_ratio ) , ' r ' ) ;
dialog : : addSelItem ( XLAT ( " Human to wall ratio " ) , fts ( vid . human_wall_ratio ) , ' h ' ) ;
dialog : : addSelItem ( XLAT ( " Level of water surface " ) , fts ( vid . lake_top ) , ' l ' ) ;
dialog : : addSelItem ( XLAT ( " Level of water bottom " ) , fts ( vid . lake_bottom ) , ' k ' ) ;
2019-07-21 21:12:16 +00:00
if ( scale_used ( ) )
dialog : : addSelItem ( XLAT ( " Creature scale " ) , fts ( vid . creature_scale ) , ' C ' ) ;
2019-02-28 02:41:59 +00:00
}
else {
2019-05-29 14:27:24 +00:00
dialog : : addSelItem ( XLAT ( " Creature scale " ) , fts ( vid . creature_scale ) , ' c ' ) ;
dialog : : addSelItem ( XLAT ( " Height to width " ) , fts ( vid . height_width ) , ' h ' ) ;
2019-02-28 21:22:31 +00:00
menuitem_sightrange ( ' s ' ) ;
2019-02-28 02:41:59 +00:00
}
2017-07-10 18:47:38 +00:00
dialog : : addBreak ( 50 ) ;
2019-08-15 13:05:43 +00:00
dialog : : addSelItem ( XLAT ( GDIM = = 3 & & WDIM = = 2 ? " Y shift " : " third person perspective " ) , fts ( vid . yshift ) , ' y ' ) ;
if ( GDIM = = 3 ) {
2019-02-28 02:41:59 +00:00
dialog : : addSelItem ( XLAT ( " mouse aiming sensitivity " ) , fts ( mouseaim_sensitivity ) , ' a ' ) ;
2019-02-26 11:58:46 +00:00
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( mouseaim_sensitivity , - 1 , 1 , 0.002 , 0.01 , XLAT ( " mouse aiming sensitivity " ) , " set to 0 to disable " ) ;
} ) ;
}
2019-07-31 14:12:21 +00:00
dialog : : addSelItem ( XLAT ( " camera rotation " ) , fts ( vid . camera_angle ) , ' x ' ) ;
2019-08-15 13:05:43 +00:00
if ( GDIM = = 2 ) {
2019-02-26 11:57:52 +00:00
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 , " " , " " ) ;
dialog : : dialogflags | = sm : : CENTER ;
}
} ) ;
}
2019-05-09 17:45:20 +00:00
2019-09-10 07:22:08 +00:00
if ( ( WDIM = = 2 & & GDIM = = 3 ) | | prod )
2019-06-17 05:22:41 +00:00
dialog : : addBoolItem_action ( XLAT ( " fixed Y/Z rotation " ) , vid . fixed_yz , ' Z ' ) ;
2019-05-09 17:45:20 +00:00
2019-05-08 23:39:32 +00:00
if ( true ) {
2019-02-26 11:23:07 +00:00
dialog : : addBreak ( 50 ) ;
2019-04-04 15:13:15 +00:00
dialog : : addSelItem ( XLAT ( " projection " ) , current_proj_name ( ) , ' M ' ) ;
2019-02-26 11:23:07 +00:00
}
2019-05-06 23:08:49 +00:00
# if MAXMDIM >= 4
2019-08-15 13:05:43 +00:00
if ( GDIM = = 3 ) add_edit_fov ( ' f ' ) ;
if ( GDIM = = 3 ) {
2019-05-21 22:01:30 +00:00
dialog : : addSelItem ( XLAT ( " radar size " ) , fts ( vid . radarsize ) , ' r ' ) ;
2019-02-28 15:24:46 +00:00
dialog : : add_action ( [ ] ( ) {
2019-06-17 05:22:41 +00:00
dialog : : editNumber ( vid . radarsize , 0 , 360 , 15 , 90 , " " , XLAT ( " set to 0 to disable " ) ) ;
2019-07-31 15:32:44 +00:00
dialog : : extra_options = [ ] ( ) { draw_radar ( true ) ; } ;
} ) ;
}
2019-10-25 12:50:48 +00:00
if ( GDIM = = 3 ) {
2019-11-03 01:24:26 +00:00
dialog : : addItem ( XLAT ( " configure raycasting " ) , ' A ' ) ;
2019-10-25 12:50:48 +00:00
dialog : : add_action_push ( ray : : configure ) ;
}
2019-11-03 12:36:06 +00:00
edit_levellines ( ' L ' ) ;
2019-07-31 15:32:44 +00:00
if ( WDIM = = 3 | | ( GDIM = = 3 & & euclid ) ) {
dialog : : addSelItem ( XLAT ( " radar range " ) , fts ( vid . radarrange ) , ' R ' ) ;
dialog : : add_action ( [ ] ( ) {
dialog : : editNumber ( vid . radarrange , 0 , 10 , 0.5 , 2 , " " , XLAT ( " " ) ) ;
dialog : : extra_options = [ ] ( ) { draw_radar ( true ) ; } ;
2019-02-28 15:24:46 +00:00
} ) ;
}
2019-08-15 13:05:43 +00:00
if ( GDIM = = 3 ) add_edit_wall_quality ( ' W ' ) ;
2019-05-06 23:08:49 +00:00
# endif
2017-11-13 11:23:42 +00:00
2017-07-10 18:47:38 +00:00
dialog : : addBreak ( 50 ) ;
2019-02-17 17:45:42 +00:00
# if CAP_RUG
2018-12-05 18:57:35 +00:00
if ( rug : : rugged ) {
2019-05-03 10:11:40 +00:00
dialog : : addBoolItem_action ( XLAT ( " 3D monsters/walls on the surface " ) , rug : : spatial_rug , ' S ' ) ;
2018-12-05 18:57:35 +00:00
}
2019-02-17 17:45:42 +00:00
# endif
2019-05-08 16:33:08 +00:00
if ( GDIM = = 2 ) {
dialog : : addBoolItem ( XLAT ( " configure TPP automatically " ) , pmodel = = mdDisk & & vid . camera_angle , ' T ' ) ;
2019-05-09 15:01:08 +00:00
dialog : : add_action ( geom3 : : switch_tpp ) ;
2019-05-08 16:33:08 +00:00
}
2019-05-11 06:19:38 +00:00
# if MAXMDIM >=4
2019-05-08 16:33:08 +00:00
if ( WDIM = = 2 ) {
2019-08-15 13:05:43 +00:00
dialog : : addBoolItem ( XLAT ( " configure FPP automatically " ) , GDIM = = 3 , ' F ' ) ;
2019-05-09 15:01:08 +00:00
dialog : : add_action ( geom3 : : switch_fpp ) ;
2019-05-08 16:33:08 +00:00
}
2019-05-11 06:19:38 +00:00
# endif
2019-01-17 13:09:00 +00:00
2019-02-17 17:45:42 +00:00
if ( 0 ) ;
# if CAP_RUG
else if ( rug : : rugged & & ! rug : : spatial_rug )
2018-12-05 18:57:35 +00:00
dialog : : addBreak ( 100 ) ;
2019-02-17 17:45:42 +00:00
# endif
2019-05-09 15:04:37 +00:00
else if ( GDIM = = 2 & & non_spatial_model ( ) )
2018-12-05 18:57:35 +00:00
dialog : : addInfo ( XLAT ( " no 3D effects available in this projection " ) , 0xC00000 ) ;
2019-05-09 15:04:37 +00:00
else if ( GDIM = = 2 & & ! spatial_graphics )
2017-07-10 18:47:38 +00:00
dialog : : addInfo ( XLAT ( " set 3D monsters or walls in basic config first " ) ) ;
2019-05-29 14:27:24 +00:00
else if ( geom3 : : invalid ! = " " )
dialog : : addInfo ( XLAT ( " error: " + geom3 : : invalid ) , 0xC00000 ) ;
2017-07-10 18:47:38 +00:00
else
dialog : : addInfo ( XLAT ( " parameters set correctly " ) ) ;
dialog : : addBreak ( 50 ) ;
2018-02-03 12:41:49 +00:00
dialog : : addItem ( XLAT ( " stereo vision config " ) , ' e ' ) ;
2018-06-12 22:00:01 +00:00
dialog : : addBack ( ) ;
2017-07-10 18:47:38 +00:00
dialog : : display ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
using namespace geom3 ;
dialog : : handleNavigation ( sym , uni ) ;
2019-08-15 13:05:43 +00:00
if ( uni = = ' n ' & & GDIM = = 2 ) {
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . highdetail , 0 , 5 , .5 , 7 , XLAT ( " High detail range " ) , " " ) ;
2019-05-04 18:40:46 +00:00
dialog : : extra_options = explain_detail ;
2018-11-09 19:41:55 +00:00
dialog : : reaction = [ ] ( ) {
2019-05-29 14:27:24 +00:00
if ( vid . highdetail > vid . middetail ) vid . middetail = vid . highdetail ;
2018-11-09 19:41:55 +00:00
} ;
}
2019-08-15 13:05:43 +00:00
else if ( uni = = ' m ' & & GDIM = = 2 ) {
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . middetail , 0 , 5 , .5 , 7 , XLAT ( " Mid detail range " ) , " " ) ;
2019-05-04 18:40:46 +00:00
dialog : : extra_options = explain_detail ;
2018-11-09 19:41:55 +00:00
dialog : : reaction = [ ] ( ) {
2019-05-29 14:27:24 +00:00
if ( vid . highdetail > vid . middetail ) vid . highdetail = vid . middetail ;
2018-11-09 19:41:55 +00:00
} ;
}
2019-05-08 16:33:08 +00:00
else if ( uni = = ' c ' & & WDIM = = 2 )
2019-05-29 14:27:24 +00:00
vid . tc_camera = ticks ,
dialog : : editNumber ( vid . camera , 0 , 5 , .1 , 1 , XLAT ( GDIM = = 2 ? " Camera level above the plane " : " Z shift " ) , " " ) ,
2019-05-04 18:40:46 +00:00
dialog : : extra_options = [ ] {
2019-05-11 21:52:18 +00:00
dialog : : addHelp ( GDIM = = 2 ? XLAT (
2019-05-04 18:40:46 +00:00
" 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). " ,
2019-05-29 14:27:24 +00:00
fts ( vid . camera ) ,
fts ( vid . depth ) ,
fts ( atan ( 1 / cosh ( vid . camera ) ) * 2 / degree ) ,
fts ( 1 / cosh ( vid . camera ) ) ) : XLAT ( " Look from behind. " ) ) ;
2019-08-15 13:05:43 +00:00
if ( GDIM = = 3 & & pmodel = = mdPerspective ) dialog : : extra_options = [ ] ( ) {
2019-05-11 21:52:18 +00:00
dialog : : addBoolItem_action ( XLAT ( " reduce if walls on the way " ) , vid . use_wall_radar , ' R ' ) ;
} ;
2019-05-04 18:40:46 +00:00
} ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' g ' & & WDIM = = 2 )
2019-05-29 14:27:24 +00:00
vid . tc_depth = ticks ,
dialog : : editNumber ( vid . depth , 0 , 5 , .1 , 1 , XLAT ( " Ground level below the plane " ) , " " ) ,
2019-05-04 18:40:46 +00:00
dialog : : extra_options = [ ] {
2019-06-01 18:13:23 +00:00
help = XLAT (
2019-05-04 18:40:46 +00:00
" 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 -- "
2019-06-01 18:13:23 +00:00
" 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 ) {
ld current_camera_level = hdist0 ( tC0 ( radar_transform ) ) ;
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 ) ;
} ;
else if ( uni = = ' E ' & & WDIM = = 2 & & GDIM = = 3 )
vid . tc_depth = ticks ,
dialog : : editNumber ( vid . eye , - 5 , 5 , .1 , 0 , XLAT ( " eye level " ) , " " ) ,
dialog : : dialogflags | = sm : : CENTER ,
dialog : : extra_options = [ ] {
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 ' ) ;
dialog : : reaction = [ ] { vid . auto_eye = false ; } ;
dialog : : add_action ( [ ] ( ) {
vid . auto_eye = ! vid . auto_eye ;
geom3 : : do_auto_eye ( ) ;
} ) ;
} ;
else if ( uni = = ' p ' & & WDIM = = 2 )
2017-07-10 18:47:38 +00:00
projectionDialog ( ) ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' w ' & & WDIM = = 2 ) {
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . wall_height , 0 , 1 , .1 , .3 , XLAT ( " Height of walls " ) , " " ) ;
2018-08-01 01:59:20 +00:00
dialog : : extra_options = [ ] ( ) {
2019-06-01 18:13:23 +00:00
dialog : : addHelp ( GDIM = = 3 ? " " : XLAT (
2019-05-04 18:40:46 +00:00
" 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. " ,
2019-05-26 16:04:02 +00:00
fts ( actual_wall_height ( ) ) , fts ( factor_to_projection ( cgi . WALL ) ) ) ) ;
2019-05-29 14:27:24 +00:00
dialog : : addBoolItem ( XLAT ( " auto-adjust in Goldberg grids " ) , vid . gp_autoscale_heights , ' O ' ) ;
2018-08-01 01:59:20 +00:00
dialog : : add_action ( [ ] ( ) {
2019-05-29 14:27:24 +00:00
vid . gp_autoscale_heights = ! vid . gp_autoscale_heights ;
2018-08-01 01:59:20 +00:00
} ) ;
} ;
}
2019-05-08 16:33:08 +00:00
else if ( uni = = ' l ' & & WDIM = = 2 )
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . lake_top , 0 , 1 , .1 , .25 , XLAT ( " Level of water surface " ) , " " ) ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' k ' & & WDIM = = 2 )
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . lake_bottom , 0 , 1 , .1 , .9 , XLAT ( " Level of water bottom " ) , " " ) ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' r ' & & WDIM = = 2 )
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . rock_wall_ratio , 0 , 1 , .1 , .9 , XLAT ( " Rock-III to wall ratio " ) , " " ) ,
2019-05-04 18:40:46 +00:00
dialog : : extra_options = [ ] { dialog : : addHelp ( XLAT (
" 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. " ,
2019-05-29 14:27:24 +00:00
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 ) ) ) ) ;
2019-05-26 16:04:02 +00:00
} ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' h ' & & WDIM = = 2 )
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . human_wall_ratio , 0 , 1 , .1 , .7 , XLAT ( " Human to wall ratio " ) , " " ) ,
2019-05-04 18:40:46 +00:00
dialog : : extra_options = [ ] { dialog : : addHelp ( XLAT (
" Humans are %1 "
" absolute units high. Your head travels %2 times the distance travelled by your "
" feet. " ,
2019-05-29 14:27:24 +00:00
fts ( vid . wall_height * vid . human_wall_ratio ) ,
fts ( cosh ( vid . depth - vid . wall_height * vid . human_wall_ratio ) / cosh ( vid . depth ) ) )
2019-05-04 18:40:46 +00:00
) ;
} ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' h ' & & WDIM = = 3 )
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . height_width , 0 , 1 , .1 , .7 , XLAT ( " Height to width " ) , " " ) ;
2019-05-08 16:33:08 +00:00
else if ( uni = = ' c ' & & WDIM = = 3 )
2019-05-29 14:27:24 +00:00
dialog : : editNumber ( vid . creature_scale , 0 , 1 , .1 , .7 , XLAT ( " Creature scale " ) , " " ) ;
2019-07-21 21:12:16 +00:00
else if ( uni = = ' C ' & & WDIM = = 2 & & scale_used ( ) )
dialog : : editNumber ( vid . creature_scale , 0 , 1 , .1 , .7 , XLAT ( " Creature scale " ) , " " ) ;
2018-02-03 12:41:49 +00:00
2017-07-12 17:50:39 +00:00
else if ( uni = = ' e ' )
2018-02-03 12:41:49 +00:00
pushScreen ( showStereo ) ;
2019-04-29 01:34:21 +00:00
else if ( uni = = ' y ' ) {
2017-07-10 18:47:38 +00:00
dialog : : editNumber ( vid . yshift , 0 , 1 , .1 , 0 , XLAT ( " Y shift " ) ,
2018-08-01 02:31:40 +00:00
XLAT ( " Don't center on the player character. " )
2017-07-10 18:47:38 +00:00
) ;
2019-05-11 21:52:18 +00:00
if ( WDIM = = 3 & & pmodel = = mdPerspective ) dialog : : extra_options = [ ] ( ) {
2019-05-03 10:11:40 +00:00
dialog : : addBoolItem_action ( XLAT ( " reduce if walls on the way " ) , vid . use_wall_radar , ' R ' ) ;
2019-04-29 01:34:21 +00:00
} ;
}
2017-07-10 18:47:38 +00:00
else if ( uni = = ' s ' )
dialog : : editNumber ( vid . camera_angle , - 180 , 180 , 5 , 0 , XLAT ( " camera rotation " ) ,
2018-08-01 02:31:40 +00:00
XLAT ( " Rotate the camera. Can be used to obtain a first person perspective, "
" or third person perspective when combined with Y shift. " )
2017-07-10 18:47:38 +00:00
) ;
else if ( uni = = ' b ' )
2018-03-24 14:15:30 +00:00
config_camera_rotation ( ) ;
2017-07-10 18:47:38 +00:00
else if ( uni = = ' M ' )
2019-08-09 22:58:50 +00:00
pushScreen ( models : : model_menu ) ;
2018-03-25 12:04:40 +00:00
else if ( doexiton ( sym , uni ) )
popScreen ( ) ;
2017-07-10 18:47:38 +00:00
} ;
}
2019-08-09 19:00:52 +00:00
EX void switchcolor ( unsigned int & c , unsigned int * cs ) {
2017-07-10 18:47:38 +00:00
dialog : : openColorDialog ( c , cs ) ;
}
2017-08-06 12:50:16 +00:00
double cc_footphase ;
int lmousex , lmousey ;
2019-08-09 19:00:52 +00:00
EX void showCustomizeChar ( ) {
2017-08-06 12:50:16 +00:00
cc_footphase + = hypot ( mousex - lmousex , mousey - lmousey ) ;
lmousex = mousex ; lmousey = mousey ;
2017-07-10 18:47:38 +00:00
gamescreen ( 4 ) ;
dialog : : init ( XLAT ( " Customize character " ) ) ;
2019-08-09 21:08:42 +00:00
if ( shmup : : on | | multi : : players ) multi : : cpid = multi : : cpid_edit % multi : : players ;
2017-07-10 18:47:38 +00:00
charstyle & cs = getcs ( ) ;
dialog : : addSelItem ( XLAT ( " character " ) , csname ( cs ) , ' g ' ) ;
dialog : : addColorItem ( XLAT ( " skin color " ) , cs . skincolor , ' s ' ) ;
2019-05-12 19:09:27 +00:00
dialog : : addColorItem ( XLAT ( " eye color " ) , cs . eyecolor , ' e ' ) ;
2017-07-10 18:47:38 +00:00
dialog : : addColorItem ( XLAT ( " weapon color " ) , cs . swordcolor , ' w ' ) ;
dialog : : addColorItem ( XLAT ( " hair color " ) , cs . haircolor , ' h ' ) ;
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 ' ) ;
2019-08-09 21:08:42 +00:00
if ( numplayers ( ) > 1 ) dialog : : addSelItem ( XLAT ( " player " ) , its ( multi : : cpid + 1 ) , ' a ' ) ;
2018-11-10 17:32:55 +00:00
dialog : : addBoolItem ( XLAT ( " left-handed " ) , cs . lefthanded , ' l ' ) ;
2017-07-10 18:47:38 +00:00
dialog : : addBreak ( 50 ) ;
2018-06-12 22:00:01 +00:00
dialog : : addBack ( ) ;
2017-07-10 18:47:38 +00:00
dialog : : display ( ) ;
int firsty = dialog : : items [ 0 ] . position / 2 ;
2017-08-06 12:50:16 +00:00
int scale = firsty - 2 * vid . fsize ;
2019-05-16 15:02:17 +00:00
2019-08-19 07:39:19 +00:00
dynamicval < eModel > pm ( pmodel , flat_model ( ) ) ;
glClear ( GL_DEPTH_BUFFER_BIT ) ;
2019-05-16 15:02:17 +00:00
dynamicval < ld > va ( vid . alpha , 1 ) ;
dynamicval < ld > vs ( vid . scale , 1 ) ;
dynamicval < ld > vc ( vid . camera_angle , 0 ) ;
2017-07-10 18:47:38 +00:00
initquickqueue ( ) ;
2017-08-06 12:50:16 +00:00
transmatrix V = atscreenpos ( vid . xres / 2 , firsty , scale ) ;
2017-07-10 18:47:38 +00:00
double alpha = atan2 ( mousex - vid . xres / 2 , mousey - firsty ) - M_PI / 2 ;
2019-05-26 16:04:02 +00:00
V = V * spin ( alpha ) ;
2019-06-24 10:57:00 +00:00
drawMonsterType ( moPlayer , NULL , V , 0 , cc_footphase / scale , NOCOLOR ) ;
2017-07-10 18:47:38 +00:00
quickqueue ( ) ;
keyhandler = [ ] ( int sym , int uni ) {
dialog : : handleNavigation ( sym , uni ) ;
2019-08-09 21:08:42 +00:00
if ( shmup : : on | | multi : : players ) multi : : cpid = multi : : cpid_edit % multi : : players ;
2017-07-10 18:47:38 +00:00
charstyle & cs = getcs ( ) ;
2018-06-12 22:00:01 +00:00
bool cat = cs . charid > = 4 ;
2019-08-09 21:08:42 +00:00
if ( uni = = ' a ' ) { multi : : cpid_edit + + ; multi : : cpid_edit % = 60 ; }
2018-06-12 22:00:01 +00:00
else if ( uni = = ' g ' ) {
2017-07-10 18:47:38 +00:00
cs . charid + + ;
2017-08-06 12:50:16 +00:00
if ( cs . charid = = 2 & & ! princess : : everSaved & & ! autocheat ) cs . charid = 4 ;
2017-07-10 18:47:38 +00:00
cs . charid % = 10 ;
}
2018-06-12 22:00:01 +00:00
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 ) ;
2019-05-12 19:09:27 +00:00
else if ( uni = = ' w ' ) switchcolor ( cs . swordcolor , swordcolors ) ;
2018-06-12 22:00:01 +00:00
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 ) ;
2019-05-12 19:09:27 +00:00
else if ( uni = = ' e ' ) switchcolor ( cs . eyecolor , eyecolors ) ;
2018-11-10 17:32:55 +00:00
else if ( uni = = ' l ' ) cs . lefthanded = ! cs . lefthanded ;
2018-06-12 22:00:01 +00:00
else if ( doexiton ( sym , uni ) ) popScreen ( ) ;
2017-07-10 18:47:38 +00:00
} ;
}
2019-08-09 19:00:52 +00:00
EX void refresh_canvas ( ) {
2018-11-08 20:56:06 +00:00
manual_celllister cl ;
cl . add ( cwt . at ) ;
int at = 0 ;
while ( at < isize ( cl . lst ) ) {
cell * c2 = cl . lst [ at ] ;
c2 - > landparam = patterns : : generateCanvas ( c2 ) ;
at + + ;
forCellEx ( c3 , c2 ) cl . add ( c3 ) ;
}
}
2019-10-06 11:03:21 +00:00
EX void edit_color_table ( colortable & ct , const reaction_t & r IS ( reaction_t ( ) ) , bool has_bit IS ( false ) ) {
2018-11-08 20:56:06 +00:00
cmode = sm : : SIDE ;
gamescreen ( 0 ) ;
2019-03-30 22:59:51 +00:00
dialog : : init ( XLAT ( " colors & aura " ) ) ;
2018-11-08 20:56:06 +00:00
for ( int i = 0 ; i < isize ( ct ) ; i + + ) {
dialog : : addColorItem ( its ( i ) , ct [ i ] < < 8 , ' a ' + i ) ;
2019-10-06 11:03:21 +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 ;
}
dialog : : openColorDialog ( ct [ i ] ) ;
dialog : : reaction = r ;
dialog : : colorAlpha = false ;
dialog : : dialogflags | = sm : : SIDE ;
} ) ;
2018-11-08 20:56:06 +00:00
}
dialog : : addBack ( ) ;
dialog : : display ( ) ;
}
2019-08-09 19:00:52 +00:00
EX void show_color_dialog ( ) {
2018-11-08 20:56:06 +00:00
cmode = sm : : SIDE | sm : : DIALOG_STRICT_X ;
2018-12-11 17:59:11 +00:00
getcstat = ' - ' ;
2018-11-08 20:56:06 +00:00
gamescreen ( 0 ) ;
2019-03-30 22:59:51 +00:00
dialog : : init ( XLAT ( " colors & aura " ) ) ;
2018-11-08 20:56:06 +00:00
dialog : : addColorItem ( XLAT ( " background " ) , backcolor < < 8 , ' b ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( backcolor ) ; dialog : : colorAlpha = false ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
dialog : : addColorItem ( XLAT ( " foreground " ) , forecolor < < 8 , ' f ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( forecolor ) ; dialog : : colorAlpha = false ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
dialog : : addColorItem ( XLAT ( " borders " ) , bordcolor < < 8 , ' o ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( bordcolor ) ; dialog : : colorAlpha = false ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
dialog : : addColorItem ( XLAT ( " projection boundary " ) , ringcolor , ' r ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( ringcolor ) ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
2019-07-13 12:37:30 +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 " ) , " " ) ; } ) ;
2018-11-10 19:19:27 +00:00
dialog : : addColorItem ( XLAT ( " projection background " ) , modelcolor , ' c ' ) ;
2018-11-08 20:56:06 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( modelcolor ) ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
2019-03-08 21:40:34 +00:00
dialog : : addColorItem ( XLAT ( " standard grid color " ) , stdgridcolor , ' g ' ) ;
dialog : : add_action ( [ ] ( ) { vid . grid = true ; dialog : : openColorDialog ( stdgridcolor ) ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
2019-07-13 12:37:30 +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 " ) , " " ) ; } ) ;
2019-03-08 21:40:34 +00:00
2019-05-21 22:01:30 +00:00
dialog : : addSelItem ( XLAT ( " brightness behind the sphere " ) , fts ( backbrightness ) , ' i ' ) ;
2019-04-04 15:13:15 +00:00
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 ) ; } ) ;
2018-11-11 11:21:22 +00:00
2018-11-08 20:56:06 +00:00
dialog : : addColorItem ( XLAT ( " projection period " ) , periodcolor , ' p ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( periodcolor ) ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
dialog : : addColorItem ( XLAT ( " dialogs " ) , dialog : : dialogcolor < < 8 , ' d ' ) ;
dialog : : add_action ( [ ] ( ) { dialog : : openColorDialog ( dialog : : dialogcolor ) ; dialog : : colorAlpha = false ; dialog : : dialogflags | = sm : : SIDE ; } ) ;
dialog : : addBreak ( 50 ) ;
if ( specialland = = laCanvas & & colortables . count ( patterns : : whichCanvas ) ) {
dialog : : addItem ( XLAT ( " pattern colors " ) , ' P ' ) ;
2019-10-06 11:03:21 +00:00
dialog : : add_action_push ( [ ] { edit_color_table ( colortables [ patterns : : whichCanvas ] , refresh_canvas , true ) ; } ) ;
2018-11-08 20:56:06 +00:00
}
if ( cwt . at - > land = = laMinefield ) {
dialog : : addItem ( XLAT ( " minefield colors " ) , ' m ' ) ;
2019-03-30 22:59:51 +00:00
dialog : : add_action_push ( [ ] { edit_color_table ( minecolors ) ; } ) ;
2018-11-08 20:56:06 +00:00
}
if ( viewdists ) {
dialog : : addItem ( XLAT ( " distance colors " ) , ' d ' ) ;
2019-03-30 22:59:51 +00:00
dialog : : add_action_push ( [ ] ( ) { edit_color_table ( distcolors ) ; } ) ;
2018-11-08 20:56:06 +00:00
}
2018-12-04 01:36:08 +00:00
2019-02-17 17:28:20 +00:00
# if CAP_CRYSTAL
2019-08-22 10:14:39 +00:00
if ( cryst & & cheater ) {
2018-12-04 01:36:08 +00:00
dialog : : addItem ( XLAT ( " crystal coordinate colors " ) , ' C ' ) ;
dialog : : add_action ( [ ] ( ) { crystal : : view_coordinates = true ; pushScreen ( [ ] ( ) { edit_color_table ( crystal : : coordcolors ) ; } ) ; } ) ;
}
2019-02-17 17:28:20 +00:00
# endif
2018-11-08 20:56:06 +00:00
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 ' ) ;
2018-12-25 22:53:52 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( vid . aurastr , 0 , 256 , 10 , 128 , XLAT ( " aura brightness " ) , " " ) ; dialog : : bound_low ( 0 ) ; } ) ;
2018-11-08 20:56:06 +00:00
dialog : : addSelItem ( XLAT ( " aura smoothening factor " ) , its ( vid . aurasmoothen ) , ' s ' ) ;
2018-12-25 22:53:52 +00:00
dialog : : add_action ( [ ] ( ) { dialog : : editNumber ( vid . aurasmoothen , 1 , 180 , 1 , 5 , XLAT ( " aura smoothening factor " ) , " " ) ; dialog : : bound_low ( 1 ) ; } ) ;
2018-11-08 20:56:06 +00:00
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 )
2018-12-11 17:59:35 +00:00
dialog : : openColorDialog ( winf [ c - > wall = = waMineMine ? waMineUnknown : c - > wall ] . color ) ;
2019-02-17 17:37:23 +00:00
# if CAP_COMPLEX2
2019-01-03 16:21:11 +00:00
else if ( c - > land = = laBrownian )
dialog : : openColorDialog ( brownian : : get_color_edit ( c - > landparam ) ) ;
2019-02-17 17:37:23 +00:00
# endif
2018-11-08 20:56:06 +00:00
else
dialog : : openColorDialog ( floorcolors [ c - > land ] ) ;
dialog : : colorAlpha = false ;
dialog : : dialogflags | = sm : : SIDE ;
return ;
}
else dialog : : handleNavigation ( sym , uni ) ;
if ( doexiton ( sym , uni ) ) popScreen ( ) ;
} ;
}
2017-08-13 18:49:38 +00:00
# if CAP_CONFIG
2019-08-09 19:00:52 +00:00
EX void resetConfigMenu ( ) {
2017-07-24 22:21:36 +00:00
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 ' ) {
2019-09-13 16:13:39 +00:00
printf ( " resetting config \n " ) ;
2017-07-24 22:21:36 +00:00
resetConfig ( ) ;
printf ( " config reset \n " ) ;
popScreen ( ) ;
}
else if ( uni = = ' r ' )
resetModes ( ) ;
else if ( uni = = ' n ' | | doexiton ( sym , uni ) )
popScreen ( ) ;
} ;
}
2017-08-13 18:49:38 +00:00
# endif
2017-08-06 12:50:16 +00:00
2017-08-13 18:49:38 +00:00
# if CAP_TRANS
2019-08-09 19:00:52 +00:00
EX void selectLanguageScreen ( ) {
2017-08-06 12:50:16 +00:00
gamescreen ( 4 ) ;
dialog : : init ( " select language " ) ; // intentionally not translated
int v = vid . language ;
dynamicval < int > d ( vid . language , - 1 ) ;
for ( int i = 0 ; i < NUMLAN - 1 | | i = = v ; i + + ) {
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 ' ) ;
2018-06-12 22:00:01 +00:00
dialog : : addBack ( ) ;
2017-08-06 12:50:16 +00:00
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 ;
ANDROID_SETTINGS ;
}
2018-06-12 22:00:01 +00:00
else if ( uni > = ' a ' & & uni < ' a ' + NUMLAN ) {
vid . language = uni - ' a ' ;
2017-08-06 12:50:16 +00:00
ANDROID_SETTINGS ;
}
else if ( doexiton ( sym , uni ) )
popScreen ( ) ;
} ;
}
2017-08-13 18:49:38 +00:00
# endif
2018-07-19 22:04:23 +00:00
2019-08-09 19:00:52 +00:00
EX void configureMouse ( ) {
2019-03-30 22:45:28 +00:00
gamescreen ( 1 ) ;
dialog : : init ( XLAT ( " mouse & touchscreen " ) ) ;
2019-05-03 10:11:40 +00:00
dialog : : addBoolItem_action ( XLAT ( " reverse pointer control " ) , ( vid . revcontrol ) , ' r ' ) ;
2019-03-30 22:45:28 +00:00
2019-05-03 10:11:40 +00:00
dialog : : addBoolItem_action ( XLAT ( " draw circle around the target " ) , ( vid . drawmousecircle ) , ' d ' ) ;
2019-03-30 22:45:28 +00:00
2019-06-25 08:30:31 +00:00
if ( GDIM = = 3 ) {
dialog : : addBoolItem_action ( XLAT ( " highlight the cell forward " ) , vid . axes3 , ' f ' ) ;
}
2019-03-30 22:45:28 +00:00
# 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
2019-05-03 10:11:40 +00:00
dialog : : addBoolItem_action ( XLAT ( " quick mouse " ) , vid . quickmouse , ' M ' ) ;
2019-03-30 22:45:28 +00:00
# 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
dialog : : reaction = checkmove ;
dialog : : bound_low ( 0 ) ;
} ) ;
# if CAP_ORIENTATION
2019-06-28 07:49:07 +00:00
if ( GDIM = = 2 ) {
dialog : : addSelItem ( XLAT ( " scrolling by device rotation " ) , ors : : choices [ ors : : mode ] , ' 1 ' ) ;
dialog : : add_action_push ( ors : : show ) ;
}
2019-03-30 22:45:28 +00:00
# endif
2019-06-28 07:48:54 +00:00
dialog : : addBack ( ) ;
2019-03-30 22:45:28 +00:00
dialog : : display ( ) ;
}
2019-08-09 19:00:52 +00:00
EX void showSettings ( ) {
2019-03-30 22:45:28 +00:00
gamescreen ( 1 ) ;
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 ) ;
2019-03-30 22:46:46 +00:00
dialog : : addItem ( XLAT ( " 3D configuration " ) , ' 9 ' ) ;
2019-03-30 22:45:28 +00:00
dialog : : add_action_push ( show3D ) ;
dialog : : addItem ( XLAT ( " quick options " ) , ' q ' ) ;
dialog : : add_action_push ( showGraphQuickKeys ) ;
2019-03-30 22:59:51 +00:00
dialog : : addItem ( XLAT ( " models & projections " ) , ' p ' ) ;
2019-08-09 22:58:50 +00:00
dialog : : add_action_push ( models : : model_menu ) ;
2019-03-30 22:45:28 +00:00
2019-03-30 22:59:51 +00:00
dialog : : addItem ( XLAT ( " colors & aura " ) , ' c ' ) ;
dialog : : add_action_push ( show_color_dialog ) ;
2019-03-30 22:45:28 +00:00
# if CAP_SHMUP
if ( CAP_SHMUP & & ! ISMOBILE ) {
dialog : : addSelItem ( XLAT ( " keyboard & joysticks " ) , " " , ' k ' ) ;
2019-08-09 21:08:42 +00:00
dialog : : add_action ( multi : : configure ) ;
2019-03-30 22:45:28 +00:00
}
# 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
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 ( ) ;
}
2018-07-19 22:04:23 +00:00
# if CAP_COMMANDLINE
2019-08-09 19:00:52 +00:00
EX int read_color_args ( ) {
2018-07-19 22:04:23 +00:00
using namespace arg ;
2018-11-11 10:06:32 +00:00
if ( argis ( " -back " ) ) {
2018-07-19 22:04:23 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; backcolor = arghex ( ) ;
}
2018-11-08 15:28:17 +00:00
else if ( argis ( " -fillmodel " ) ) {
2018-11-08 18:39:55 +00:00
PHASEFROM ( 2 ) ; shift ( ) ; modelcolor = arghex ( ) ;
2018-11-08 15:28:17 +00:00
}
2018-10-23 18:09:34 +00:00
else if ( argis ( " -ring " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; ringcolor = arghex ( ) ;
}
2019-07-13 12:37:30 +00:00
else if ( argis ( " -ringw " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . multiplier_ring ) ;
}
2019-03-08 21:40:34 +00:00
else if ( argis ( " -stdgrid " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; stdgridcolor = arghex ( ) ;
}
2019-07-13 12:37:30 +00:00
else if ( argis ( " -gridw " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . multiplier_grid ) ;
}
2018-11-08 18:39:55 +00:00
else if ( argis ( " -period " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; periodcolor = arghex ( ) ;
}
2019-09-09 14:10:57 +00:00
else if ( argis ( " -crosshair " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; crosshair_color = arghex ( ) ;
shift_arg_formula ( crosshair_size ) ;
}
2018-07-19 22:04:23 +00:00
else if ( argis ( " -borders " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; bordcolor = arghex ( ) ;
}
else if ( argis ( " -fore " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; forecolor = arghex ( ) ;
}
2018-09-05 13:18:40 +00:00
else if ( argis ( " -dialog " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; dialog : : dialogcolor = arghex ( ) ;
}
2018-11-11 10:06:32 +00:00
else if ( argis ( " -d:color " ) )
launch_dialog ( show_color_dialog ) ;
else return 1 ;
return 0 ;
}
2019-08-09 19:00:52 +00:00
EX int read_config_args ( ) {
2018-11-11 10:06:32 +00:00
using namespace arg ;
if ( argis ( " -c " ) ) { PHASE ( 1 ) ; shift ( ) ; conffile = argcs ( ) ; }
// change the configuration from the command line
2018-07-19 22:04:23 +00:00
else if ( argis ( " -aa " ) ) { PHASEFROM ( 2 ) ; shift ( ) ; vid . antialias = argi ( ) ; }
2018-11-09 13:26:31 +00:00
else if ( argis ( " -lw " ) ) { PHASEFROM ( 2 ) ; shift_arg_formula ( vid . linewidth ) ; }
2018-07-19 22:04:23 +00:00
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 ; }
2019-03-21 18:13:54 +00:00
else if ( argis ( " -gridon " ) ) { vid . grid = true ; }
2018-07-19 22:04:23 +00:00
// non-configurable options
else if ( argis ( " -vsync_off " ) ) {
vsync_off = true ;
if ( curphase = = 3 ) setvideomode ( ) ;
}
2018-11-08 15:28:17 +00:00
else if ( argis ( " -aura " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ; vid . aurastr = argi ( ) ;
shift ( ) ; vid . aurasmoothen = argi ( ) ;
}
2018-07-19 22:04:23 +00:00
else if ( argis ( " -nofps " ) ) {
2019-01-24 13:48:53 +00:00
PHASEFROM ( 2 ) ;
2018-07-19 22:04:23 +00:00
nofps = true ;
}
else if ( argis ( " -nohud " ) ) {
2019-01-24 13:48:53 +00:00
PHASEFROM ( 2 ) ;
2018-07-19 22:04:23 +00:00
nohud = true ;
}
else if ( argis ( " -nomenu " ) ) {
2019-01-24 13:48:53 +00:00
PHASEFROM ( 2 ) ;
2018-07-19 22:04:23 +00:00
nomenukey = true ;
}
2019-05-11 06:19:38 +00:00
# if MAXMDIM >= 4
2019-05-09 15:01:08 +00:00
else if ( argis ( " -switch-fpp " ) ) {
PHASEFROM ( 2 ) ;
geom3 : : switch_fpp ( ) ;
}
2019-05-11 06:19:38 +00:00
# endif
2019-05-09 15:01:08 +00:00
else if ( argis ( " -switch-tpp " ) ) {
PHASEFROM ( 2 ) ;
geom3 : : switch_tpp ( ) ;
}
2019-05-11 06:19:38 +00:00
# if MAXMDIM >= 4
2019-05-09 15:01:08 +00:00
else if ( argis ( " -switch-3d " ) ) {
2019-05-08 16:33:08 +00:00
PHASEFROM ( 2 ) ;
2019-05-09 15:01:08 +00:00
geom3 : : switch_always3 ( ) ;
2019-05-08 16:33:08 +00:00
}
2019-05-11 06:19:38 +00:00
# endif
2018-07-19 22:04:23 +00:00
else if ( argis ( " -nohelp " ) ) {
2019-01-24 13:48:53 +00:00
PHASEFROM ( 2 ) ;
2018-07-19 22:04:23 +00:00
nohelp = true ;
}
else if ( argis ( " -dont_face_pc " ) ) {
2019-01-24 13:48:53 +00:00
PHASEFROM ( 2 ) ;
2018-07-19 22:04:23 +00:00
dont_face_pc = true ;
}
2018-09-30 22:01:55 +00:00
# if CAP_TRANS
else if ( argis ( " -lang " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; vid . language = argi ( ) ;
}
# endif
2018-11-06 14:52:41 +00:00
else if ( argis ( " -vlq " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; vid . linequality = argi ( ) ;
}
2019-07-30 10:58:52 +00:00
else if ( argis ( " -fov " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . fov ) ;
}
2018-07-19 22:04:23 +00:00
else if ( argis ( " -r " ) ) {
PHASEFROM ( 2 ) ;
shift ( ) ;
int clWidth = 0 , clHeight = 0 , clFont = 0 ;
sscanf ( argcs ( ) , " %dx%dx%d " , & clWidth , & clHeight , & clFont ) ;
if ( clWidth ) vid . xres = clWidth ;
if ( clHeight ) vid . yres = clHeight ;
if ( clFont ) vid . fsize = clFont ;
}
2018-09-23 21:53:55 +00:00
else if ( argis ( " -msm " ) ) {
PHASEFROM ( 2 ) ; memory_saving_mode = true ;
}
2019-06-06 17:37:17 +00:00
else if ( argis ( " -mrsv " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; reserve_limit = argi ( ) ; apply_memory_reserve ( ) ;
}
2019-01-10 02:06:21 +00:00
else if ( argis ( " -yca " ) ) {
PHASEFROM ( 2 ) ;
shift_arg_formula ( vid . yshift ) ;
shift_arg_formula ( vid . camera_angle ) ;
}
2019-10-06 22:08:37 +00:00
else if ( argis ( " -pside " ) ) {
PHASEFROM ( 2 ) ;
permaside = true ;
}
2019-01-10 02:06:21 +00:00
else if ( argis ( " -xy " ) ) {
PHASEFROM ( 2 ) ;
shift_arg_formula ( vid . xposition ) ;
shift_arg_formula ( vid . yposition ) ;
}
2019-01-17 13:09:00 +00:00
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 ;
}
2018-09-23 21:53:55 +00:00
else if ( argis ( " -msmoff " ) ) {
PHASEFROM ( 2 ) ; memory_saving_mode = false ;
}
2019-11-03 12:36:06 +00:00
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 ;
}
2019-02-26 11:58:46 +00:00
else if ( argis ( " -msens " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( mouseaim_sensitivity ) ;
}
2018-07-21 14:58:50 +00:00
TOGGLE ( ' o ' , vid . usingGL , switchGL ( ) )
TOGGLE ( ' f ' , vid . full , switchFullscreen ( ) )
2019-07-03 05:51:30 +00:00
else if ( argis ( " -noshaders " ) ) {
PHASE ( 1 ) ;
glhr : : noshaders = true ;
}
2018-11-11 10:06:32 +00:00
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 ) ;
}
2019-03-30 22:45:28 +00:00
else if ( argis ( " -d:iface " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( configureInterface ) ;
2018-11-11 10:06:32 +00:00
}
else if ( argis ( " -d:graph " ) ) {
PHASEFROM ( 2 ) ; launch_dialog ( showGraphConfig ) ;
}
2019-06-17 04:01:56 +00:00
else if ( argis ( " -tstep " ) ) {
PHASEFROM ( 2 ) ; shift ( ) ; vid . texture_step = argi ( ) ;
}
2019-08-17 11:51:33 +00:00
else if ( argis ( " -csc " ) ) {
PHASEFROM ( 2 ) ; shift_arg_formula ( vid . creature_scale ) ;
}
else if ( argis ( " -char " ) ) {
auto & cs = vid . cs ;
shift ( ) ; cs . charid = argi ( ) ;
cs . lefthanded = cs . charid > = 10 ;
cs . charid % = 10 ;
}
2018-07-21 14:58:50 +00:00
else return 1 ;
return 0 ;
}
2018-07-19 22:07:30 +00:00
// mode changes:
2019-08-09 19:00:52 +00:00
EX int read_gamemode_args ( ) {
2018-07-21 14:58:50 +00:00
using namespace arg ;
if ( argis ( " -P " ) ) {
PHASE ( 2 ) ; shift ( ) ;
stop_game_and_switch_mode ( rg : : nothing ) ;
2018-11-18 02:18:11 +00:00
multi : : players = argi ( ) ;
2018-07-21 14:58:50 +00:00
}
2018-07-19 22:07:30 +00:00
TOGGLE ( ' C ' , chaosmode , stop_game_and_switch_mode ( rg : : chaos ) )
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 ) )
2018-07-19 22:04:23 +00:00
else return 1 ;
return 0 ;
}
2018-11-11 10:06:32 +00:00
auto ah_config = addHook ( hooks_args , 0 , read_config_args ) + addHook ( hooks_args , 0 , read_gamemode_args ) + addHook ( hooks_args , 0 , read_color_args ) ;
2018-07-19 22:04:23 +00:00
# endif
2018-07-23 03:14:19 +00:00
2019-08-09 19:18:13 +00:00
EX unordered_map < string , ld & > params = {
2018-11-09 20:18:58 +00:00
{ " linewidth " , vid . linewidth } ,
{ " patternlinewidth " , linepatterns : : width } ,
{ " scale " , vid . scale } ,
{ " xposition " , vid . xposition } ,
{ " yposition " , vid . yposition } ,
{ " projection " , vid . alpha } ,
{ " sspeed " , vid . sspeed } ,
{ " mspeed " , vid . mspeed } ,
{ " ballangle " , vid . ballangle } ,
{ " yshift " , vid . yshift } ,
{ " cameraangle " , vid . camera_angle } ,
2019-06-01 17:58:07 +00:00
{ " eye " , vid . eye } ,
2019-05-29 14:27:24 +00:00
{ " depth " , vid . depth } ,
{ " camera " , vid . camera } ,
{ " wall_height " , vid . wall_height } ,
{ " highdetail " , vid . highdetail } ,
{ " middetail " , vid . middetail } ,
{ " rock_wall_ratio " , vid . rock_wall_ratio } ,
{ " human_wall_ratio " , vid . human_wall_ratio } ,
{ " lake_top " , vid . lake_top } ,
{ " lake_bottom " , vid . lake_bottom } ,
2019-02-17 17:45:42 +00:00
# if CAP_RUG
2018-11-09 20:18:58 +00:00
{ " rug_model_distance " , rug : : model_distance } ,
2019-02-17 17:45:42 +00:00
# endif
2018-11-09 20:18:58 +00:00
{ " star " , polygonal : : STAR } ,
2019-08-09 22:58:50 +00:00
{ " lvspeed " , history : : lvspeed } ,
{ " rotation " , models : : rotation } ,
{ " mori " , models : : model_orientation } ,
{ " mori_yz " , models : : model_orientation_yz } ,
{ " clipmin " , models : : clip_min } ,
{ " clipmax " , models : : clip_max } ,
{ " topz " , models : : top_z } ,
{ " mtrans " , models : : model_transition } ,
{ " hp " , models : : halfplane_scale } ,
2018-11-09 20:18:58 +00:00
{ " back " , backbrightness } ,
2018-11-17 18:24:02 +00:00
{ " ipd " , vid . ipd } ,
{ " lr " , vid . lr_eyewidth } ,
{ " anaglyph " , vid . anaglyph_eyewidth } ,
{ " fov " , vid . fov } ,
2018-11-09 20:18:58 +00:00
{ " ets " , vid . euclid_to_sphere } ,
{ " stretch " , vid . stretch } ,
{ " twopoint " , vid . twopoint_param } ,
2019-10-05 10:32:16 +00:00
{ " fisheye " , vid . fisheye_param } ,
2018-11-09 20:18:58 +00:00
{ " bwidth " , vid . binary_width } ,
2019-02-17 17:43:39 +00:00
# if CAP_ANIMATIONS
2018-11-09 20:18:58 +00:00
{ " aperiod " , anims : : period } ,
{ " acycle " , anims : : cycle_length } ,
{ " aparabolic " , anims : : parabolic_length } ,
{ " arugangle " , anims : : rug_angle } ,
{ " acradius " , anims : : circle_radius } ,
{ " acspins " , anims : : circle_spins } ,
{ " a " , anims : : a } ,
{ " b " , anims : : b } ,
2019-02-17 17:43:39 +00:00
# endif
{ " mobius " , vid . skiprope } ,
2019-08-09 22:58:50 +00:00
{ " sang " , models : : spiral_angle } ,
{ " spiralx " , models : : spiral_x } ,
{ " spiraly " , models : : spiral_y } ,
2019-02-17 17:28:20 +00:00
# if CAP_CRYSTAL
2018-12-13 12:33:08 +00:00
{ " cprob " , crystal : : compass_probability } ,
2019-02-17 17:28:20 +00:00
# endif
2018-12-15 14:20:27 +00:00
# if CAP_SHOT
2018-12-13 12:33:08 +00:00
{ " gamma " , shot : : gamma } ,
2018-12-15 14:20:27 +00:00
{ " fade " , shot : : fade } ,
2019-07-13 12:37:30 +00:00
{ " mgrid " , vid . multiplier_grid } ,
{ " mring " , vid . multiplier_ring } ,
2019-08-14 16:59:21 +00:00
{ " collignon " , vid . collignon_parameter } ,
2019-11-03 12:36:06 +00:00
{ " levellines " , levellines } ,
2018-12-15 14:20:27 +00:00
# endif
2018-11-09 20:18:58 +00:00
} ;
2018-06-10 23:58:31 +00:00
}