text: #pragma once
  
  #include <cstdint>
  
  #include <SDL_version.h>
  
  #include "pack.h"
  
  namespace devilution {
  
  struct DiabloOptions {
  	/** @brief Play game intro video on startup. */
  	bool bIntro;
  };
  
  struct HellfireOptions {
  	/** @brief Play game intro video on startup. */
  	bool bIntro;
  	/** @brief Cornerstone of the world item. */
  	char szItem[sizeof(ItemPack) * 2 + 1];
  };
  
  struct AudioOptions {
  	/** @brief Movie and SFX volume. */
  	int nSoundVolume;
  	/** @brief Music volume. */
  	int nMusicVolume;
  	/** @brief Player emits sound when walking. */
  	bool bWalkingSound;
  	/** @brief Automatically equipping items on pickup emits the equipment sound. */
  	bool bAutoEquipSound;
  
  	/** @brief Output sample rate (Hz) */
  	std::uint32_t nSampleRate;
  	/** @brief The number of output channels (1 or 2) */
  	std::uint8_t nChannels;
  	/** @brief Buffer size (number of frames per channel) */
  	std::uint32_t nBufferSize;
  	/** @brief Quality of the resampler, from 0 (lowest) to 10 (highest) */
  	std::uint8_t nResamplingQuality;
  };
  
  struct GraphicsOptions {
  	/** @brief Render width. */
  	int nWidth;
  	/** @brief Render height. */
  	int nHeight;
  	/** @brief Run in fullscreen or windowed mode. */
  	bool bFullscreen;
  	/** @brief Scale the image after rendering. */
  	bool bUpscale;
  	/** @brief Expand the aspect ratio to match the screen. */
  	bool bFitToScreen;
  	/** @brief See SDL_HINT_RENDER_SCALE_QUALITY. */
  	char szScaleQuality[2];
  	/** @brief Only scale by values divisible by the width and height. */
  	bool bIntegerScaling;
  	/** @brief Enable vsync on the output. */
  	bool bVSync;
  	/** @brief Use blended transparency rather than stippled. */
  	bool bBlendedTransparancy;
  	/** @brief Gamma correction level. */
  	int nGammaCorrection;
  	/** @brief Enable color cycling animations. */
  	bool bColorCycling;
  #if SDL_VERSION_ATLEAST(2, 0, 0)
  	/** @brief Use a hardware cursor (SDL2 only). */
  	bool bHardwareCursor;
  	/** @brief Use a hardware cursor for items. */
  	bool bHardwareCursorForItems;
  	/** @brief Maximum width / height for the hardware cursor. Larger cursors fall back to software. */
  	int nHardwareCursorMaxSize;
  #endif
  	/** @brief Enable FPS Limit. */
  	bool bFPSLimit;
  	/** @brief Show FPS, even without the -f command line flag. */
  	bool bShowFPS;
  };
  
  struct GameplayOptions {
  	/** @brief Gameplay ticks per second. */
  	int nTickRate;
  	/** @brief Enable double walk speed when in town. */
  	bool bRunInTown;
  	/** @brief Do not let the mouse leave the application window. */
  	bool bGrabInput;
  	/** @brief Enable the Theo quest. */
  	bool bTheoQuest;
  	/** @brief Enable the cow quest. */
  	bool bCowQuest;
  	/** @brief Will players still damage other players in non-PvP mode. */
  	bool bFriendlyFire;
  	/** @brief Enable the bard hero class. */
  	bool bTestBard;
  	/** @brief Enable the babarian hero class. */
  	bool bTestBarbarian;
  	/** @brief Show the current level progress. */
  	bool bExperienceBar;
  	/** @brief Show enemy health at the top of the screen. */
  	bool bEnemyHealthBar;
  	/** @brief Automatically pick up gold when walking over it. */
  	bool bAutoGoldPickup;
  	/** @brief Recover mana when talking to Adria. */
  	bool bAdriaRefillsMana;
  	/** @brief Automatically attempt to equip weapon-type items when picking them up. */
  	bool bAutoEquipWeapons;
  	/** @brief Automatically attempt to equip armor-type items when picking them up. */
  	bool bAutoEquipArmor;
  	/** @brief Automatically attempt to equip helm-type items when picking them up. */
  	bool bAutoEquipHelms;
  	/** @brief Automatically attempt to equip shield-type items when picking them up. */
  	bool bAutoEquipShields;
  	/** @brief Automatically attempt to equip jewelry-type items when picking them up. */
  	bool bAutoEquipJewelry;
  	/** @brief Only enable 2/3 quests in each game session */
  	bool bRandomizeQuests;
  	/** @brief Indicates whether or not monster type (Animal, Demon, Undead) is shown along with other monster information. */
  	bool bShowMonsterType;
  	/** @brief Locally disable clicking on shrines which permanently cripple character. */
  	bool bDisableCripplingShrines;
  };
  
  struct ControllerOptions {
  	/** @brief SDL Controller mapping, see SDL_GameControllerDB. */
  	char szMapping[1024];
  	/** @brief Use dpad for spell hotkeys without holding "start" */
  	bool bDpadHotkeys;
  	/** @brief Shoulder gamepad shoulder buttons act as potions by default */
  	bool bSwapShoulderButtonMode;
  	/** @brief Configure gamepad joysticks deadzone */
  	float fDeadzone;
  #ifdef __vita__
  	/** @brief Enable input via rear touchpad */
  	bool bRearTouch;
  #endif
  };
  
  struct NetworkOptions {
  	/** @brief Optionally bind to a specific network interface. */
  	char szBindAddress[129];
  	/** @brief Most recently entered Hostname in join dialog. */
  	char szPreviousHost[129];
  	/** @brief What network port to use. */
  	uint16_t nPort;
  };
  
  struct ChatOptions {
  	/** @brief Quick chat messages. */
  	char szHotKeyMsgs[QUICK_MESSAGE_OPTIONS][MAX_SEND_STR_LEN];
  };
  
  struct LanguageOptions {
  	/** @brief Language code (IETF) for text. */
  	char szCode[5];
  };
  
  struct Options {
  	DiabloOptions Diablo;
  	HellfireOptions Hellfire;
  	AudioOptions Audio;
  	GameplayOptions Gameplay;
  	GraphicsOptions Graphics;
  	ControllerOptions Controller;
  	NetworkOptions Network;
  	ChatOptions Chat;
  	LanguageOptions Language;
  };
  
  bool GetIniValue(const char *sectionName, const char *keyName, char *string, int stringSize, const char *defaultString = "");
  void SetIniValue(const char *sectionName, const char *keyName, const char *value, int len = 0);
  
  extern Options sgOptions;
  extern bool sbWasOptionsLoaded;
  
  void SaveOptions();
  void LoadOptions();
  
  } // namespace devilution
  