/**
* @ file options . cpp
*
* Load and save options from the diablo . ini file .
*/
# include <cstdint>
# include <fstream>
# include <locale>
# ifdef __ANDROID__
# include "SDL.h"
# include <jni.h>
# endif
# ifdef __vita__
# include <psp2/apputil.h>
# include <psp2/system_param.h>
# endif
# ifdef __3DS__
# include "platform/ctr/locale.hpp"
# endif
# define SI_SUPPORT_IOSTREAMS
# include <SimpleIni.h>
# include "diablo.h"
# include "engine/demomode.h"
# include "options.h"
# include "utils/file_util.h"
# include "utils/language.h"
# include "utils/paths.h"
# include "utils/utf8.hpp"
namespace devilution {
# ifndef DEFAULT_WIDTH
# define DEFAULT_WIDTH 640
# endif
# ifndef DEFAULT_HEIGHT
# define DEFAULT_HEIGHT 480
# endif
# ifndef DEFAULT_AUDIO_SAMPLE_RATE
# define DEFAULT_AUDIO_SAMPLE_RATE 22050
# endif
# ifndef DEFAULT_AUDIO_CHANNELS
# define DEFAULT_AUDIO_CHANNELS 2
# endif
# ifndef DEFAULT_AUDIO_BUFFER_SIZE
# define DEFAULT_AUDIO_BUFFER_SIZE 2048
# endif
# ifndef DEFAULT_AUDIO_RESAMPLING_QUALITY
# define DEFAULT_AUDIO_RESAMPLING_QUALITY 5
# endif
# ifdef VIRTUAL_GAMEPAD
# define AUTO_PICKUP_DEFAULT(bValue) true
# else
# define AUTO_PICKUP_DEFAULT(bValue) bValue
# endif
namespace {
std : : string GetIniPath ( )
{
auto path = paths : : ConfigPath ( ) + std : : string ( " diablo.ini " ) ;
return path ;
}
CSimpleIni & GetIni ( )
{
static CSimpleIni ini ;
static bool isIniLoaded = false ;
if ( ! isIniLoaded ) {
auto path = GetIniPath ( ) ;
auto stream = CreateFileStream ( path . c_str ( ) , std : : fstream : : in | std : : fstream : : binary ) ;
ini . SetSpaces ( false ) ;
if ( stream )
ini . LoadData ( * stream ) ;
isIniLoaded = true ;
}
return ini ;
}
bool IniChanged = false ;
/**
* @ brief Checks if a ini entry is changed by comparing value before and after
*/
class IniChangedChecker {
public :
IniChangedChecker ( const char * sectionName , const char * keyName )
{
this - > sectionName_ = sectionName ;
this - > keyName_ = keyName ;
std : : list < CSimpleIni : : Entry > values ;
if ( ! GetIni ( ) . GetAllValues ( sectionName , keyName , values ) ) {
// No entry found in original ini => new entry => changed
IniChanged = true ;
}
const auto * value = GetIni ( ) . GetValue ( sectionName , keyName ) ;
if ( value ! = nullptr )
oldValue_ = value ;
}
~ IniChangedChecker ( )
{
const auto * value = GetIni ( ) . GetValue ( sectionName_ , keyName_ ) ;
std : : string newValue ;
if ( value ! = nullptr )
newValue = value ;
if ( oldValue_ ! = newValue )
IniChanged = true ;
}
private :
std : : string oldValue_ ;
const char * sectionName_ ;
const char * keyName_ ;
} ;
int GetIniInt ( const char * keyname , const char * valuename , int defaultValue )
{
return GetIni ( ) . GetLongValue ( keyname , valuename , defaultValue ) ;
}
bool GetIniBool ( const char * sectionName , const char * keyName , bool defaultValue )
{
return GetIni ( ) . GetBoolValue ( sectionName , keyName , defaultValue ) ;
}
float GetIniFloat ( const char * sectionName , const char * keyName , float defaultValue )
{
return ( float ) GetIni ( ) . GetDoubleValue ( sectionName , keyName , defaultValue ) ;
}
void SetIniValue ( const char * keyname , const char * valuename , int value )
{
IniChangedChecker changedChecker ( keyname , valuename ) ;
GetIni ( ) . SetLongValue ( keyname , valuename , value ) ;
}
void SetIniValue ( const char * keyname , const char * valuename , std : : uint8_t value )
{
IniChangedChecker changedChecker ( keyname , valuename ) ;
GetIni ( ) . SetLongValue ( keyname , valuename , value ) ;
}
void SetIniValue ( const char * keyname , const char * valuename , std : : uint32_t value )
{
IniChangedChecker changedChecker ( keyname , valuename ) ;
GetIni ( ) . SetLongValue ( keyname , valuename , value ) ;
}
void SetIniValue ( const char * keyname , const char * valuename , bool value )
{
IniChangedChecker changedChecker ( keyname , valuename ) ;
GetIni ( ) . SetLongValue ( keyname , valuename , value ? 1 : 0 ) ;
}
void SetIniValue ( const char * keyname , const char * valuename , float value )
{
IniChangedChecker changedChecker ( keyname , valuename ) ;
GetIni ( ) . SetDoubleValue ( keyname , valuename , value ) ;
}
void SaveIni ( )
{
if ( ! IniChanged )
return ;
auto iniPath = GetIniPath ( ) ;
auto stream = CreateFileStream ( iniPath . c_str ( ) , std : : fstream : : out | std : : fstream : : trunc | std : : fstream : : binary ) ;
GetIni ( ) . Save ( * stream , true ) ;
IniChanged = false ;
}
# if SDL_VERSION_ATLEAST(2, 0, 0)
bool HardwareCursorDefault ( )
{
# ifdef __ANDROID__
// See https://github.com/diasurgical/devilutionX/issues/2502
return false ;
# else
SDL_version v ;
SDL_GetVersion ( & v ) ;
return SDL_VERSIONNUM ( v . major , v . minor , v . patch ) > = SDL_VERSIONNUM ( 2 , 0 , 12 ) ;
# endif
}
# endif
} // namespace
void SetIniValue ( const char * sectionName , const char * keyName , const char * value , int len )
{
IniChangedChecker changedChecker ( sectionName , keyName ) ;
auto & ini = GetIni ( ) ;
std : : string stringValue ( value , len ! = 0 ? len : strlen ( value ) ) ;
ini . SetValue ( sectionName , keyName , stringValue . c_str ( ) ) ;
}
bool GetIniValue ( const char * sectionName , const char * keyName , char * string , int stringSize , const char * defaultString )
{
const char * value = GetIni ( ) . GetValue ( sectionName , keyName ) ;
if ( value = = nullptr ) {
CopyUtf8 ( string , defaultString , stringSize ) ;
return false ;
}
CopyUtf8 ( string , value , stringSize ) ;
return true ;
}
/** Game options */
Options sgOptions ;
bool sbWasOptionsLoaded = false ;
void LoadOptions ( )
{
for ( OptionCategoryBase * pCategory : sgOptions . GetCategories ( ) ) {
for ( OptionEntryBase * pEntry : pCategory - > GetEntries ( ) ) {
pEntry - > LoadFromIni ( pCategory - > GetKey ( ) ) ;
}
}
sgOptions . Diablo . bIntro = GetIniBool ( " Diablo " , " Intro " , true ) ;
sgOptions . Diablo . lastSinglePlayerHero = GetIniInt ( " Diablo " , " LastSinglePlayerHero " , 0 ) ;
sgOptions . Diablo . lastMultiplayerHero = GetIniInt ( " Diablo " , " LastMultiplayerHero " , 0 ) ;
sgOptions . Hellfire . bIntro = GetIniBool ( " Hellfire " , " Intro " , true ) ;
sgOptions . Hellfire . lastSinglePlayerHero = GetIniInt ( " Hellfire " , " LastSinglePlayerHero " , 0 ) ;
sgOptions . Hellfire . lastMultiplayerHero = GetIniInt ( " Hellfire " , " LastMultiplayerHero " , 0 ) ;
sgOptions . Hellfire . startUpGameOption = static_cast < StartUpGameOption > ( GetIniInt ( " Hellfire " , " StartUpGameOption " , static_cast < int > ( StartUpGameOption : : None ) ) ) ;
GetIniValue ( " Hellfire " , " SItem " , sgOptions . Hellfire . szItem , sizeof ( sgOptions . Hellfire . szItem ) , " " ) ;
sgOptions . Audio . nSoundVolume = GetIniInt ( " Audio " , " Sound Volume " , VOLUME_MAX ) ;
sgOptions . Audio . nMusicVolume = GetIniInt ( " Audio " , " Music Volume " , VOLUME_MAX ) ;
sgOptions . Audio . nSampleRate = GetIniInt ( " Audio " , " Sample Rate " , DEFAULT_AUDIO_SAMPLE_RATE ) ;
sgOptions . Audio . nChannels = GetIniInt ( " Audio " , " Channels " , DEFAULT_AUDIO_CHANNELS ) ;
sgOptions . Audio . nBufferSize = GetIniInt ( " Audio " , " Buffer Size " , DEFAULT_AUDIO_BUFFER_SIZE ) ;
sgOptions . Audio . nResamplingQuality = GetIniInt ( " Audio " , " Resampling Quality " , DEFAULT_AUDIO_RESAMPLING_QUALITY ) ;
sgOptions . Graphics . nWidth = GetIniInt ( " Graphics " , " Width " , DEFAULT_WIDTH ) ;
sgOptions . Graphics . nHeight = GetIniInt ( " Graphics " , " Height " , DEFAULT_HEIGHT ) ;
# ifndef __vita__
sgOptions . Graphics . bFullscreen = GetIniBool ( " Graphics " , " Fullscreen " , true ) ;
# else
sgOptions . Graphics . bFullscreen = true ;
# endif
# if !defined(USE_SDL1)
sgOptions . Graphics . bUpscale = GetIniBool ( " Graphics " , " Upscale " , true ) ;
# else
sgOptions . Graphics . bUpscale = false ;
# endif
sgOptions . Graphics . bFitToScreen = GetIniBool ( " Graphics " , " Fit to Screen " , true ) ;
sgOptions . Graphics . bIntegerScaling = GetIniBool ( " Graphics " , " Integer Scaling " , false ) ;
sgOptions . Graphics . bVSync = GetIniBool ( " Graphics " , " Vertical Sync " , true ) ;
sgOptions . Graphics . bBlendedTransparancy = GetIniBool ( " Graphics " , " Blended Transparency " , true ) ;
sgOptions . Graphics . nGammaCorrection = GetIniInt ( " Graphics " , " Gamma Correction " , 100 ) ;
sgOptions . Graphics . bColorCycling = GetIniBool ( " Graphics " , " Color Cycling " , true ) ;
# if SDL_VERSION_ATLEAST(2, 0, 0)
sgOptions . Graphics . bHardwareCursor = GetIniBool ( " Graphics " , " Hardware Cursor " , HardwareCursorDefault ( ) ) ;
sgOptions . Graphics . bHardwareCursorForItems = GetIniBool ( " Graphics " , " Hardware Cursor For Items " , false ) ;
sgOptions . Graphics . nHardwareCursorMaxSize = GetIniInt ( " Graphics " , " Hardware Cursor Maximum Size " , 128 ) ;
# endif
sgOptions . Graphics . bFPSLimit = GetIniBool ( " Graphics " , " FPS Limiter " , true ) ;
sgOptions . Graphics . bShowFPS = ( GetIniInt ( " Graphics " , " Show FPS " , 0 ) ! = 0 ) ;
sgOptions . Gameplay . nTickRate = GetIniInt ( " Game " , " Speed " , 20 ) ;
sgOptions . Gameplay . bGrabInput = GetIniBool ( " Game " , " Grab Input " , false ) ;
sgOptions . Gameplay . bTheoQuest = GetIniBool ( " Game " , " Theo Quest " , false ) ;
sgOptions . Gameplay . bCowQuest = GetIniBool ( " Game " , " Cow Quest " , false ) ;
sgOptions . Gameplay . bFriendlyFire = GetIniBool ( " Game " , " Friendly Fire " , true ) ;
sgOptions . Gameplay . bTestBard = GetIniBool ( " Game " , " Test Bard " , false ) ;
sgOptions . Gameplay . bTestBarbarian = GetIniBool ( " Game " , " Test Barbarian " , false ) ;
sgOptions . Gameplay . bExperienceBar = GetIniBool ( " Game " , " Experience Bar " , AUTO_PICKUP_DEFAULT ( false ) ) ;
sgOptions . Gameplay . bEnemyHealthBar = GetIniBool ( " Game " , " Enemy Health Bar " , false ) ;
sgOptions . Gameplay . bAutoGoldPickup = GetIniBool ( " Game " , " Auto Gold Pickup " , AUTO_PICKUP_DEFAULT ( false ) ) ;
sgOptions . Gameplay . bAdriaRefillsMana = GetIniBool ( " Game " , " Adria Refills Mana " , false ) ;
sgOptions . Gameplay . bAutoEquipWeapons = GetIniBool ( " Game " , " Auto Equip Weapons " , true ) ;
sgOptions . Gameplay . bAutoEquipArmor = GetIniBool ( " Game " , " Auto Equip Armor " , AUTO_PICKUP_DEFAULT ( false ) ) ;
sgOptions . Gameplay . bAutoEquipHelms = GetIniBool ( " Game " , " Auto Equip Helms " , AUTO_PICKUP_DEFAULT ( false ) ) ;
sgOptions . Gameplay . bAutoEquipShields = GetIniBool ( " Game " , " Auto Equip Shields " , AUTO_PICKUP_DEFAULT ( false ) ) ;
sgOptions . Gameplay . bAutoEquipJewelry = GetIniBool ( " Game " , " Auto Equip Jewelry " , AUTO_PICKUP_DEFAULT ( false ) ) ;
sgOptions . Gameplay . bRandomizeQuests = GetIniBool ( " Game " , " Randomize Quests " , true ) ;
sgOptions . Gameplay . bShowMonsterType = GetIniBool ( " Game " , " Show Monster Type " , false ) ;
sgOptions . Gameplay . bDisableCripplingShrines = GetIniBool ( " Game " , " Disable Crippling Shrines " , false ) ;
sgOptions . Gameplay . bAutoRefillBelt = GetIniBool ( " Game " , " Auto Refill Belt " , AUTO_PICKUP_DEFAULT ( false ) ) ;
GetIniValue ( " Network " , " Bind Address " , sgOptions . Network . szBindAddress , sizeof ( sgOptions . Network . szBindAddress ) , " 0.0.0.0 " ) ;
sgOptions . Network . nPort = GetIniInt ( " Network " , " Port " , 6112 ) ;
GetIniValue ( " Network " , " Previous Host " , sgOptions . Network . szPreviousHost , sizeof ( sgOptions . Network . szPreviousHost ) , " " ) ;
for ( size_t i = 0 ; i < QUICK_MESSAGE_OPTIONS ; i + + )
GetIniValue ( " NetMsg " , QuickMessages [ i ] . key , sgOptions . Chat . szHotKeyMsgs [ i ] , MAX_SEND_STR_LEN , " " ) ;
GetIniValue ( " Controller " , " Mapping " , sgOptions . Controller . szMapping , sizeof ( sgOptions . Controller . szMapping ) , " " ) ;
sgOptions . Controller . bSwapShoulderButtonMode = GetIniBool ( " Controller " , " Swap Shoulder Button Mode " , false ) ;
sgOptions . Controller . bDpadHotkeys = GetIniBool ( " Controller " , " Dpad Hotkeys " , false ) ;
sgOptions . Controller . fDeadzone = GetIniFloat ( " Controller " , " deadzone " , 0.07F ) ;
# ifdef __vita__
sgOptions . Controller . bRearTouch = GetIniBool ( " Controller " , " Enable Rear Touchpad " , true ) ;
# endif
# ifdef __ANDROID__
JNIEnv * env = ( JNIEnv * ) SDL_AndroidGetJNIEnv ( ) ;
jobject activity = ( jobject ) SDL_AndroidGetActivity ( ) ;
jclass clazz ( env - > GetObjectClass ( activity ) ) ;
jmethodID method_id = env - > GetMethodID ( clazz , " getLocale " , " ()Ljava/lang/String; " ) ;
jstring jLocale = ( jstring ) env - > CallObjectMethod ( activity , method_id ) ;
const char * cLocale = env - > GetStringUTFChars ( jLocale , nullptr ) ;
std : : string locale = cLocale ;
env - > ReleaseStringUTFChars ( jLocale , cLocale ) ;
env - > DeleteLocalRef ( jLocale ) ;
env - > DeleteLocalRef ( activity ) ;
env - > DeleteLocalRef ( clazz ) ;
# elif defined(__vita__)
int32_t language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US ; // default to english
const char * vita_locales [ ] = {
" ja_JP " ,
" en_US " ,
" fr_FR " ,
" es_ES " ,
" de_DE " ,
" it_IT " ,
" nl_NL " ,
" pt_PT " ,
" ru_RU " ,
" ko_KR " ,
" zh_TW " ,
" zh_CN " ,
" fi_FI " ,
" sv_SE " ,
" da_DK " ,
" no_NO " ,
" pl_PL " ,
" pt_BR " ,
" en_GB " ,
" tr_TR " ,
} ;
SceAppUtilInitParam initParam ;
SceAppUtilBootParam bootParam ;
memset ( & initParam , 0 , sizeof ( SceAppUtilInitParam ) ) ;
memset ( & bootParam , 0 , sizeof ( SceAppUtilBootParam ) ) ;
sceAppUtilInit ( & initParam , & bootParam ) ;
sceAppUtilSystemParamGetInt ( SCE_SYSTEM_PARAM_ID_LANG , & language ) ;
if ( language < 0 | | language > SCE_SYSTEM_PARAM_LANG_TURKISH )
language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US ; // default to english
std : : string locale = std : : string ( vita_locales [ language ] ) ;
sceAppUtilShutdown ( ) ;
# elif defined(__3DS__)
std : : string locale = n3ds : : GetLocale ( ) ;
# else
std : : string locale = std : : locale ( " " ) . name ( ) . substr ( 0 , 5 ) ;
# endif
locale = locale . substr ( 0 , 5 ) ;
LogVerbose ( " Prefered locale: {} " , locale ) ;
if ( ! HasTranslation ( locale ) ) {
locale = locale . substr ( 0 , 2 ) ;
if ( ! HasTranslation ( locale ) ) {
locale = " en " ;
}
}
LogVerbose ( " Best match locale: {} " , locale ) ;
GetIniValue ( " Language " , " Code " , sgOptions . Language . szCode , sizeof ( sgOptions . Language . szCode ) , locale . c_str ( ) ) ;
keymapper . Load ( ) ;
if ( demo : : IsRunning ( ) )
demo : : OverrideOptions ( ) ;
sbWasOptionsLoaded = true ;
}
void SaveOptions ( )
{
for ( OptionCategoryBase * pCategory : sgOptions . GetCategories ( ) ) {
for ( OptionEntryBase * pEntry : pCategory - > GetEntries ( ) ) {
pEntry - > SaveToIni ( pCategory - > GetKey ( ) ) ;
}
}
SetIniValue ( " Diablo " , " Intro " , sgOptions . Diablo . bIntro ) ;
SetIniValue ( " Diablo " , " LastSinglePlayerHero " , sgOptions . Diablo . lastSinglePlayerHero ) ;
SetIniValue ( " Diablo " , " LastMultiplayerHero " , sgOptions . Diablo . lastMultiplayerHero ) ;
SetIniValue ( " Hellfire " , " Intro " , sgOptions . Hellfire . bIntro ) ;
SetIniValue ( " Hellfire " , " SItem " , sgOptions . Hellfire . szItem ) ;
SetIniValue ( " Hellfire " , " LastSinglePlayerHero " , sgOptions . Hellfire . lastSinglePlayerHero ) ;
SetIniValue ( " Hellfire " , " LastMultiplayerHero " , sgOptions . Hellfire . lastMultiplayerHero ) ;
SetIniValue ( " Hellfire " , " StartUpGameOption " , static_cast < int > ( sgOptions . Hellfire . startUpGameOption ) ) ;
SetIniValue ( " Audio " , " Sound Volume " , sgOptions . Audio . nSoundVolume ) ;
SetIniValue ( " Audio " , " Music Volume " , sgOptions . Audio . nMusicVolume ) ;
SetIniValue ( " Audio " , " Sample Rate " , sgOptions . Audio . nSampleRate ) ;
SetIniValue ( " Audio " , " Channels " , sgOptions . Audio . nChannels ) ;
SetIniValue ( " Audio " , " Buffer Size " , sgOptions . Audio . nBufferSize ) ;
SetIniValue ( " Audio " , " Resampling Quality " , sgOptions . Audio . nResamplingQuality ) ;
SetIniValue ( " Graphics " , " Width " , sgOptions . Graphics . nWidth ) ;
SetIniValue ( " Graphics " , " Height " , sgOptions . Graphics . nHeight ) ;
# ifndef __vita__
SetIniValue ( " Graphics " , " Fullscreen " , sgOptions . Graphics . bFullscreen ) ;
# endif
# if !defined(USE_SDL1)
SetIniValue ( " Graphics " , " Upscale " , sgOptions . Graphics . bUpscale ) ;
# endif
SetIniValue ( " Graphics " , " Fit to Screen " , sgOptions . Graphics . bFitToScreen ) ;
SetIniValue ( " Graphics " , " Integer Scaling " , sgOptions . Graphics . bIntegerScaling ) ;
SetIniValue ( " Graphics " , " Vertical Sync " , sgOptions . Graphics . bVSync ) ;
SetIniValue ( " Graphics " , " Blended Transparency " , sgOptions . Graphics . bBlendedTransparancy ) ;
SetIniValue ( " Graphics " , " Gamma Correction " , sgOptions . Graphics . nGammaCorrection ) ;
SetIniValue ( " Graphics " , " Color Cycling " , sgOptions . Graphics . bColorCycling ) ;
# if SDL_VERSION_ATLEAST(2, 0, 0)
SetIniValue ( " Graphics " , " Hardware Cursor " , sgOptions . Graphics . bHardwareCursor ) ;
SetIniValue ( " Graphics " , " Hardware Cursor For Items " , sgOptions . Graphics . bHardwareCursorForItems ) ;
SetIniValue ( " Graphics " , " Hardware Cursor Maximum Size " , sgOptions . Graphics . nHardwareCursorMaxSize ) ;
# endif
SetIniValue ( " Graphics " , " FPS Limiter " , sgOptions . Graphics . bFPSLimit ) ;
SetIniValue ( " Graphics " , " Show FPS " , sgOptions . Graphics . bShowFPS ) ;
SetIniValue ( " Game " , " Speed " , sgOptions . Gameplay . nTickRate ) ;
SetIniValue ( " Game " , " Grab Input " , sgOptions . Gameplay . bGrabInput ) ;
SetIniValue ( " Game " , " Theo Quest " , sgOptions . Gameplay . bTheoQuest ) ;
SetIniValue ( " Game " , " Cow Quest " , sgOptions . Gameplay . bCowQuest ) ;
SetIniValue ( " Game " , " Friendly Fire " , sgOptions . Gameplay . bFriendlyFire ) ;
SetIniValue ( " Game " , " Test Bard " , sgOptions . Gameplay . bTestBard ) ;
SetIniValue ( " Game " , " Test Barbarian " , sgOptions . Gameplay . bTestBarbarian ) ;
SetIniValue ( " Game " , " Experience Bar " , sgOptions . Gameplay . bExperienceBar ) ;
SetIniValue ( " Game " , " Enemy Health Bar " , sgOptions . Gameplay . bEnemyHealthBar ) ;
SetIniValue ( " Game " , " Auto Gold Pickup " , sgOptions . Gameplay . bAutoGoldPickup ) ;
SetIniValue ( " Game " , " Adria Refills Mana " , sgOptions . Gameplay . bAdriaRefillsMana ) ;
SetIniValue ( " Game " , " Auto Equip Weapons " , sgOptions . Gameplay . bAutoEquipWeapons ) ;
SetIniValue ( " Game " , " Auto Equip Armor " , sgOptions . Gameplay . bAutoEquipArmor ) ;
SetIniValue ( " Game " , " Auto Equip Helms " , sgOptions . Gameplay . bAutoEquipHelms ) ;
SetIniValue ( " Game " , " Auto Equip Shields " , sgOptions . Gameplay . bAutoEquipShields ) ;
SetIniValue ( " Game " , " Auto Equip Jewelry " , sgOptions . Gameplay . bAutoEquipJewelry ) ;
SetIniValue ( " Game " , " Randomize Quests " , sgOptions . Gameplay . bRandomizeQuests ) ;
SetIniValue ( " Game " , " Show Monster Type " , sgOptions . Gameplay . bShowMonsterType ) ;
SetIniValue ( " Game " , " Disable Crippling Shrines " , sgOptions . Gameplay . bDisableCripplingShrines ) ;
SetIniValue ( " Game " , " Auto Refill Belt " , sgOptions . Gameplay . bAutoRefillBelt ) ;
SetIniValue ( " Network " , " Bind Address " , sgOptions . Network . szBindAddress ) ;
SetIniValue ( " Network " , " Port " , sgOptions . Network . nPort ) ;
SetIniValue ( " Network " , " Previous Host " , sgOptions . Network . szPreviousHost ) ;
for ( size_t i = 0 ; i < QUICK_MESSAGE_OPTIONS ; i + + )
SetIniValue ( " NetMsg " , QuickMessages [ i ] . key , sgOptions . Chat . szHotKeyMsgs [ i ] ) ;
SetIniValue ( " Controller " , " Mapping " , sgOptions . Controller . szMapping ) ;
SetIniValue ( " Controller " , " Swap Shoulder Button Mode " , sgOptions . Controller . bSwapShoulderButtonMode ) ;
SetIniValue ( " Controller " , " Dpad Hotkeys " , sgOptions . Controller . bDpadHotkeys ) ;
SetIniValue ( " Controller " , " deadzone " , sgOptions . Controller . fDeadzone ) ;
# ifdef __vita__
SetIniValue ( " Controller " , " Enable Rear Touchpad " , sgOptions . Controller . bRearTouch ) ;
# endif
SetIniValue ( " Language " , " Code " , sgOptions . Language . szCode ) ;
keymapper . Save ( ) ;
SaveIni ( ) ;
}
string_view OptionEntryBase : : GetName ( ) const
{
return _ ( name . data ( ) ) ;
}
string_view OptionEntryBase : : GetDescription ( ) const
{
return _ ( description . data ( ) ) ;
}
OptionEntryFlags OptionEntryBase : : GetFlags ( ) const
{
return flags ;
}
void OptionEntryBase : : SetValueChangedCallback ( std : : function < void ( ) > callback )
{
this - > callback = callback ;
}
void OptionEntryBase : : NotifyValueChanged ( )
{
if ( callback )
callback ( ) ;
}
void OptionEntryBoolean : : LoadFromIni ( string_view category )
{
value = GetIniBool ( category . data ( ) , key . data ( ) , defaultValue ) ;
}
void OptionEntryBoolean : : SaveToIni ( string_view category ) const
{
SetIniValue ( category . data ( ) , key . data ( ) , value ) ;
}
bool OptionEntryBoolean : : operator * ( ) const
{
return value ;
}
void OptionEntryBoolean : : SetValue ( bool value )
{
this - > value = value ;
this - > NotifyValueChanged ( ) ;
}
OptionEntryType OptionEntryBoolean : : GetType ( ) const
{
return OptionEntryType : : Boolean ;
}
string_view OptionEntryBoolean : : GetValueDescription ( ) const
{
return value ? _ ( " ON " ) : _ ( " OFF " ) ;
}
OptionEntryType OptionEntryListBase : : GetType ( ) const
{
return OptionEntryType : : List ;
}
string_view OptionEntryListBase : : GetValueDescription ( ) const
{
return GetListDescription ( GetActiveListIndex ( ) ) ;
}
void OptionEntryEnumBase : : LoadFromIni ( string_view category )
{
value = GetIniInt ( category . data ( ) , key . data ( ) , defaultValue ) ;
}
void OptionEntryEnumBase : : SaveToIni ( string_view category ) const
{
SetIniValue ( category . data ( ) , key . data ( ) , value ) ;
}
int OptionEntryEnumBase : : GetValueInternal ( ) const
{
return value ;
}
void OptionEntryEnumBase : : AddEntry ( int value , string_view name )
{
entryValues . push_back ( value ) ;
entryNames . push_back ( name ) ;
}
size_t OptionEntryEnumBase : : GetListSize ( ) const
{
return entryValues . size ( ) ;
}
string_view OptionEntryEnumBase : : GetListDescription ( size_t index ) const
{
return _ ( entryNames [ index ] . data ( ) ) ;
}
size_t OptionEntryEnumBase : : GetActiveListIndex ( ) const
{
auto iterator = std : : find ( entryValues . begin ( ) , entryValues . end ( ) , value ) ;
if ( iterator = = entryValues . end ( ) )
return 0 ;
return std : : distance ( entryValues . begin ( ) , iterator ) ;
}
void OptionEntryEnumBase : : SetActiveListIndex ( size_t index )
{
this - > value = entryValues [ index ] ;
this - > NotifyValueChanged ( ) ;
}
OptionCategoryBase : : OptionCategoryBase ( string_view key , string_view name , string_view description )
: key ( key )
, name ( name )
, description ( description )
{
}
string_view OptionCategoryBase : : GetKey ( ) const
{
return key ;
}
string_view OptionCategoryBase : : GetName ( ) const
{
return _ ( name . data ( ) ) ;
}
string_view OptionCategoryBase : : GetDescription ( ) const
{
return _ ( description . data ( ) ) ;
}
DiabloOptions : : DiabloOptions ( )
: OptionCategoryBase ( " Diablo " , N_ ( " Diablo " ) , N_ ( " Diablo specific Settings " ) )
{
}
std : : vector < OptionEntryBase * > DiabloOptions : : GetEntries ( )
{
return { } ;
}
HellfireOptions : : HellfireOptions ( )
: OptionCategoryBase ( " Hellfire " , N_ ( " Hellfire " ) , N_ ( " Hellfire specific Settings " ) )
{
}
std : : vector < OptionEntryBase * > HellfireOptions : : GetEntries ( )
{
return { } ;
}
AudioOptions : : AudioOptions ( )
: OptionCategoryBase ( " Audio " , N_ ( " Audio " ) , N_ ( " Audio Settings " ) )
, walkingSound ( " Walking Sound " , OptionEntryFlags : : None , N_ ( " Walking Sound " ) , N_ ( " Player emits sound when walking. " ) , true )
, autoEquipSound ( " Auto Equip Sound " , OptionEntryFlags : : None , N_ ( " Auto Equip Sound " ) , N_ ( " Automatically equipping items on pickup emits the equipment sound. " ) , AUTO_PICKUP_DEFAULT ( false ) )
, itemPickupSound ( " Item Pickup Sound " , OptionEntryFlags : : None , N_ ( " Item Pickup Sound " ) , N_ ( " Picking up items emits the items pickup sound. " ) , AUTO_PICKUP_DEFAULT ( false ) )
{
}
std : : vector < OptionEntryBase * > AudioOptions : : GetEntries ( )
{
return {
& walkingSound ,
& autoEquipSound ,
& itemPickupSound ,
} ;
}
GraphicsOptions : : GraphicsOptions ( )
: OptionCategoryBase ( " Graphics " , N_ ( " Graphics " ) , N_ ( " Graphics Settings " ) )
, scaleQuality ( " Scaling Quality " , OptionEntryFlags : : None , N_ ( " Scaling Quality " ) , N_ ( " Enables optional filters to the output image when upscaling. " ) , ScalingQuality : : AnisotropicFiltering ,
{
{ ScalingQuality : : NearestPixel , N_ ( " Nearest Pixel " ) } ,
{ ScalingQuality : : BilinearFiltering , N_ ( " Bilinear " ) } ,
{ ScalingQuality : : AnisotropicFiltering , N_ ( " Anisotropic " ) } ,
} )
{
}
std : : vector < OptionEntryBase * > GraphicsOptions : : GetEntries ( )
{
return {
& scaleQuality ,
} ;
}
GameplayOptions : : GameplayOptions ( )
: OptionCategoryBase ( " Game " , N_ ( " Gameplay " ) , N_ ( " Gameplay Settings " ) )
, runInTown ( " Run in Town " , OptionEntryFlags : : CantChangeInMultiPlayer , N_ ( " Run in Town " ) , N_ ( " Enable jogging/fast walking in town for Diablo and Hellfire. This option was introduced in the expansion. " ) , AUTO_PICKUP_DEFAULT ( false ) )
{
}
std : : vector < OptionEntryBase * > GameplayOptions : : GetEntries ( )
{
return {
& runInTown ,
} ;
}
ControllerOptions : : ControllerOptions ( )
: OptionCategoryBase ( " Controller " , N_ ( " Controller " ) , N_ ( " Controller Settings " ) )
{
}
std : : vector < OptionEntryBase * > ControllerOptions : : GetEntries ( )
{
return { } ;
}
NetworkOptions : : NetworkOptions ( )
: OptionCategoryBase ( " Network " , N_ ( " Network " ) , N_ ( " Network Settings " ) )
{
}
std : : vector < OptionEntryBase * > NetworkOptions : : GetEntries ( )
{
return { } ;
}
ChatOptions : : ChatOptions ( )
: OptionCategoryBase ( " NetMsg " , N_ ( " Chat " ) , N_ ( " Chat Settings " ) )
{
}
std : : vector < OptionEntryBase * > ChatOptions : : GetEntries ( )
{
return { } ;
}
LanguageOptions : : LanguageOptions ( )
: OptionCategoryBase ( " Language " , N_ ( " Language " ) , N_ ( " Language Settings " ) )
{
}
std : : vector < OptionEntryBase * > LanguageOptions : : GetEntries ( )
{
return { } ;
}
} // namespace devilution