Browse Source

`sgOptions` -> `GetOptions()`

In C++, globals initialization order accross translation units is not
defined. Accessing a global via a function ensures that it is initialized.

This will be needed for #7638, which will statically initialize change
handlers after the Options object has been initialized.
pull/7642/head
Gleb Mazovetskiy 1 year ago
parent
commit
d94bc424df
  1. 6
      Source/DiabloUI/diabloui.cpp
  2. 4
      Source/DiabloUI/hero/selhero.cpp
  3. 14
      Source/DiabloUI/multi/selgame.cpp
  4. 2
      Source/DiabloUI/selstart.cpp
  5. 8
      Source/DiabloUI/settingsmenu.cpp
  6. 2
      Source/control.cpp
  7. 32
      Source/controls/controller_motion.cpp
  8. 14
      Source/controls/game_controls.cpp
  9. 2
      Source/controls/plrctrls.cpp
  10. 8
      Source/cursor.cpp
  11. 222
      Source/diablo.cpp
  12. 4
      Source/dvlnet/tcp_client.cpp
  13. 104
      Source/engine/demomode.cpp
  14. 6
      Source/engine/dx.cpp
  15. 2
      Source/engine/events.cpp
  16. 20
      Source/engine/palette.cpp
  17. 30
      Source/engine/render/scrollrt.cpp
  18. 28
      Source/engine/sound.cpp
  19. 2
      Source/gamemenu.cpp
  20. 10
      Source/hwcursor.cpp
  21. 2
      Source/hwcursor.hpp
  22. 4
      Source/init.cpp
  23. 2
      Source/interfac.cpp
  24. 18
      Source/inv.cpp
  25. 12
      Source/items.cpp
  26. 2
      Source/lua/lua.cpp
  27. 4
      Source/menu.cpp
  28. 4
      Source/monster.cpp
  29. 2
      Source/movie.cpp
  30. 2
      Source/msg.cpp
  31. 13
      Source/multi.cpp
  32. 2
      Source/objects.cpp
  33. 107
      Source/options.cpp
  34. 5
      Source/options.h
  35. 4
      Source/panels/spell_list.cpp
  36. 2
      Source/platform/vita/touch.cpp
  37. 6
      Source/player.cpp
  38. 20
      Source/qol/autopickup.cpp
  39. 12
      Source/qol/floatingnumbers.cpp
  40. 6
      Source/qol/itemlabels.cpp
  41. 6
      Source/qol/monhealthbar.cpp
  42. 6
      Source/qol/xpbar.cpp
  43. 2
      Source/quests.cpp
  44. 10
      Source/stores.cpp
  45. 2
      Source/storm/storm_svid.cpp
  46. 4
      Source/utils/aulib.hpp
  47. 64
      Source/utils/display.cpp
  48. 2
      Source/utils/language.cpp
  49. 2
      test/main.cpp
  50. 26
      test/scrollrt_test.cpp

6
Source/DiabloUI/diabloui.cpp

@ -429,7 +429,7 @@ void UiHandleEvents(SDL_Event *event)
if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_RETURN) {
const Uint8 *state = SDLC_GetKeyState();
if (state[SDLC_KEYSTATE_LALT] != 0 || state[SDLC_KEYSTATE_RALT] != 0) {
sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen());
GetOptions().Graphics.fullscreen.SetValue(!IsFullScreen());
SaveOptions();
if (gfnFullscreen != nullptr)
gfnFullscreen();
@ -455,9 +455,9 @@ void UiHandleEvents(SDL_Event *event)
// For example, if the previous size was too large for a hardware cursor then it was invisible
// but may now become visible.
DoReinitializeHardwareCursor();
} else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST && *sgOptions.Gameplay.pauseOnFocusLoss) {
} else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST && *GetOptions().Gameplay.pauseOnFocusLoss) {
music_mute();
} else if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED && *sgOptions.Gameplay.pauseOnFocusLoss) {
} else if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED && *GetOptions().Gameplay.pauseOnFocusLoss) {
diablo_focus_unpause();
}
}

4
Source/DiabloUI/hero/selhero.cpp

@ -162,10 +162,10 @@ void SelheroListSelect(size_t value)
vecSelHeroDlgItems.push_back(std::make_unique<UiListItem>(_("Sorcerer"), static_cast<int>(HeroClass::Sorcerer)));
if (gbIsHellfire) {
vecSelHeroDlgItems.push_back(std::make_unique<UiListItem>(_("Monk"), static_cast<int>(HeroClass::Monk)));
if (HaveBardAssets() || *sgOptions.Gameplay.testBard) {
if (HaveBardAssets() || *GetOptions().Gameplay.testBard) {
vecSelHeroDlgItems.push_back(std::make_unique<UiListItem>(_("Bard"), static_cast<int>(HeroClass::Bard)));
}
if (HaveBarbarianAssets() || *sgOptions.Gameplay.testBarbarian) {
if (HaveBarbarianAssets() || *GetOptions().Gameplay.testBarbarian) {
vecSelHeroDlgItems.push_back(std::make_unique<UiListItem>(_("Barbarian"), static_cast<int>(HeroClass::Barbarian)));
}
}

14
Source/DiabloUI/multi/selgame.cpp

@ -115,9 +115,9 @@ void UiInitGameSelectionList(std::string_view search)
}
if (provider == SELCONN_ZT) {
CopyUtf8(selgame_Ip, sgOptions.Network.szPreviousZTGame, sizeof(selgame_Ip));
CopyUtf8(selgame_Ip, GetOptions().Network.szPreviousZTGame, sizeof(selgame_Ip));
} else {
CopyUtf8(selgame_Ip, sgOptions.Network.szPreviousHost, sizeof(selgame_Ip));
CopyUtf8(selgame_Ip, GetOptions().Network.szPreviousHost, sizeof(selgame_Ip));
}
selgame_FreeVectors();
@ -622,9 +622,9 @@ void selgame_Password_Select(size_t /*value*/)
for (unsigned int i = 0; i < (sizeof(selgame_Ip) / sizeof(selgame_Ip[0])); i++) {
selgame_Ip[i] = (selgame_Ip[i] >= 'A' && selgame_Ip[i] <= 'Z') ? selgame_Ip[i] + 'a' - 'A' : selgame_Ip[i];
}
strcpy(sgOptions.Network.szPreviousZTGame, selgame_Ip);
strcpy(GetOptions().Network.szPreviousZTGame, selgame_Ip);
} else {
strcpy(sgOptions.Network.szPreviousHost, selgame_Ip);
strcpy(GetOptions().Network.szPreviousHost, selgame_Ip);
}
if (allowJoin && SNetJoinGame(selgame_Ip, gamePassword, gdwPlayerId)) {
if (!IsGameCompatibleWithErrorMessage(*m_game_data)) {
@ -657,9 +657,9 @@ void selgame_Password_Select(size_t /*value*/)
m_game_data->nDifficulty = nDifficulty;
m_game_data->nTickRate = nTickRate;
m_game_data->bRunInTown = *sgOptions.Gameplay.runInTown ? 1 : 0;
m_game_data->bTheoQuest = *sgOptions.Gameplay.theoQuest ? 1 : 0;
m_game_data->bCowQuest = *sgOptions.Gameplay.cowQuest ? 1 : 0;
m_game_data->bRunInTown = *GetOptions().Gameplay.runInTown ? 1 : 0;
m_game_data->bTheoQuest = *GetOptions().Gameplay.theoQuest ? 1 : 0;
m_game_data->bCowQuest = *GetOptions().Gameplay.cowQuest ? 1 : 0;
GameData gameInitInfo = *m_game_data;
gameInitInfo.swapLE();

2
Source/DiabloUI/selstart.cpp

@ -18,7 +18,7 @@ std::vector<std::unique_ptr<UiItemBase>> vecDialog;
void ItemSelected(size_t value)
{
auto option = static_cast<StartUpGameMode>(vecDialogItems[value]->m_value);
sgOptions.GameMode.gameMode.SetValue(option);
GetOptions().GameMode.gameMode.SetValue(option);
SaveOptions();
endMenu = true;
}

8
Source/DiabloUI/settingsmenu.cpp

@ -171,7 +171,7 @@ void ItemFocused(size_t value)
optionDescription[0] = '\0';
if (vecItem->m_value < 0)
return;
auto *pCategory = sgOptions.GetCategories()[vecItem->m_value];
auto *pCategory = GetOptions().GetCategories()[vecItem->m_value];
UpdateDescription(*pCategory);
} break;
case ShownMenuType::Settings: {
@ -255,7 +255,7 @@ void ItemSelected(size_t value)
switch (shownMenu) {
case ShownMenuType::Categories: {
selectedCategory = sgOptions.GetCategories()[vecItemValue];
selectedCategory = GetOptions().GetCategories()[vecItemValue];
endMenu = true;
shownMenu = ShownMenuType::Settings;
} break;
@ -319,7 +319,7 @@ void EscPressed()
void FullscreenChanged()
{
auto *fullscreenOption = &sgOptions.Graphics.fullscreen;
auto *fullscreenOption = &GetOptions().Graphics.fullscreen;
for (auto &vecItem : vecDialogItems) {
int vecItemValue = vecItem->m_value;
@ -386,7 +386,7 @@ void UiSettingsMenu()
switch (shownMenu) {
case ShownMenuType::Categories: {
size_t catIndex = 0;
for (OptionCategoryBase *pCategory : sgOptions.GetCategories()) {
for (OptionCategoryBase *pCategory : GetOptions().GetCategories()) {
for (OptionEntryBase *pEntry : pCategory->GetEntries()) {
if (!IsValidEntry(pEntry))
continue;

2
Source/control.cpp

@ -1693,7 +1693,7 @@ void DiabloHotkeyMsg(uint32_t dwMsg)
assert(dwMsg < QuickMessages.size());
for (const std::string &msg : sgOptions.Chat.szHotKeyMsgs[dwMsg]) {
for (const std::string &msg : GetOptions().Chat.szHotKeyMsgs[dwMsg]) {
#ifdef _DEBUG
constexpr std::string_view LuaPrefix = "/lua ";
if (msg.starts_with(LuaPrefix)) {

32
Source/controls/controller_motion.cpp

@ -71,15 +71,16 @@ void ScaleJoystickAxes(float *x, float *y, float deadzone)
bool IsMovementOverriddenByPadmapper(ControllerButton button)
{
ControllerButtonEvent releaseEvent { button, true };
std::string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(releaseEvent);
ControllerButtonCombo buttonCombo = sgOptions.Padmapper.ButtonComboForAction(actionName);
const Options &options = GetOptions();
std::string_view actionName = options.Padmapper.ActionNameTriggeredByButtonEvent(releaseEvent);
ControllerButtonCombo buttonCombo = options.Padmapper.ButtonComboForAction(actionName);
return buttonCombo.modifier != ControllerButton_NONE;
}
bool TriggersQuickSpellAction(ControllerButton button)
{
ControllerButtonEvent releaseEvent { button, true };
std::string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(releaseEvent);
std::string_view actionName = GetOptions().Padmapper.ActionNameTriggeredByButtonEvent(releaseEvent);
std::string_view prefix { "QuickSpell" };
if (actionName.size() < prefix.size())
@ -118,8 +119,9 @@ namespace {
void ScaleJoysticks()
{
const float rightDeadzone = sgOptions.Controller.fDeadzone;
const float leftDeadzone = sgOptions.Controller.fDeadzone;
const Options &options = GetOptions();
const float rightDeadzone = options.Controller.fDeadzone;
const float leftDeadzone = options.Controller.fDeadzone;
if (leftStickNeedsScaling) {
leftStickX = leftStickXUnscaled;
@ -208,11 +210,12 @@ AxisDirection GetLeftStickOrDpadDirection(bool usePadmapper)
bool isLeftPressed = stickX <= -0.5;
bool isRightPressed = stickX >= 0.5;
const Options &options = GetOptions();
if (usePadmapper) {
isUpPressed |= sgOptions.Padmapper.IsActive("MoveUp");
isDownPressed |= sgOptions.Padmapper.IsActive("MoveDown");
isLeftPressed |= sgOptions.Padmapper.IsActive("MoveLeft");
isRightPressed |= sgOptions.Padmapper.IsActive("MoveRight");
isUpPressed |= options.Padmapper.IsActive("MoveUp");
isDownPressed |= options.Padmapper.IsActive("MoveDown");
isLeftPressed |= options.Padmapper.IsActive("MoveLeft");
isRightPressed |= options.Padmapper.IsActive("MoveRight");
} else if (!SimulatingMouseWithPadmapper) {
isUpPressed |= IsPressedForMovement(ControllerButton_BUTTON_DPAD_UP);
isDownPressed |= IsPressedForMovement(ControllerButton_BUTTON_DPAD_DOWN);
@ -251,7 +254,8 @@ void SimulateRightStickWithPadmapper(ControllerButtonEvent ctrlEvent)
if (!ctrlEvent.up && ctrlEvent.button == SuppressedButton)
return;
std::string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent);
const Options &options = GetOptions();
std::string_view actionName = options.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent);
bool upTriggered = actionName == "MouseUp";
bool downTriggered = actionName == "MouseDown";
bool leftTriggered = actionName == "MouseLeft";
@ -262,10 +266,10 @@ void SimulateRightStickWithPadmapper(ControllerButtonEvent ctrlEvent)
return;
}
bool upActive = (upTriggered && !ctrlEvent.up) || (!upTriggered && sgOptions.Padmapper.IsActive("MouseUp"));
bool downActive = (downTriggered && !ctrlEvent.up) || (!downTriggered && sgOptions.Padmapper.IsActive("MouseDown"));
bool leftActive = (leftTriggered && !ctrlEvent.up) || (!leftTriggered && sgOptions.Padmapper.IsActive("MouseLeft"));
bool rightActive = (rightTriggered && !ctrlEvent.up) || (!rightTriggered && sgOptions.Padmapper.IsActive("MouseRight"));
bool upActive = (upTriggered && !ctrlEvent.up) || (!upTriggered && options.Padmapper.IsActive("MouseUp"));
bool downActive = (downTriggered && !ctrlEvent.up) || (!downTriggered && options.Padmapper.IsActive("MouseDown"));
bool leftActive = (leftTriggered && !ctrlEvent.up) || (!leftTriggered && options.Padmapper.IsActive("MouseLeft"));
bool rightActive = (rightTriggered && !ctrlEvent.up) || (!rightTriggered && options.Padmapper.IsActive("MouseRight"));
rightStickX = 0;
rightStickY = 0;

14
Source/controls/game_controls.cpp

@ -238,7 +238,7 @@ void PressControllerButton(ControllerButton button)
SetSpeedSpell(slot);
return;
}
if (!*sgOptions.Gameplay.quickCast)
if (!*GetOptions().Gameplay.quickCast)
ToggleSpell(slot);
else
QuickCast(slot);
@ -289,7 +289,7 @@ void PressControllerButton(ControllerButton button)
return;
case devilution::ControllerButton_BUTTON_Y:
#ifdef __3DS__
sgOptions.Graphics.zoom.SetValue(!*sgOptions.Graphics.zoom);
GetOptions().Graphics.zoom.SetValue(!*GetOptions().Graphics.zoom);
CalcViewportGeometry();
#endif
return;
@ -298,7 +298,7 @@ void PressControllerButton(ControllerButton button)
}
}
sgOptions.Padmapper.ButtonPressed(button);
GetOptions().Padmapper.ButtonPressed(button);
}
} // namespace
@ -337,7 +337,7 @@ bool IsSimulatedMouseClickBinding(ControllerButtonEvent ctrlEvent)
return false;
if (!ctrlEvent.up && ctrlEvent.button == SuppressedButton)
return false;
std::string_view actionName = sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent);
std::string_view actionName = GetOptions().Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent);
return IsAnyOf(actionName, "LeftMouseClick1", "LeftMouseClick2", "RightMouseClick1", "RightMouseClick2");
}
@ -356,7 +356,7 @@ bool HandleControllerButtonEvent(const SDL_Event &event, const ControllerButtonE
~ButtonReleaser()
{
if (ctrlEvent.up)
sgOptions.Padmapper.ButtonReleased(ctrlEvent.button, false);
GetOptions().Padmapper.ButtonReleased(ctrlEvent.button, false);
}
ControllerButtonEvent ctrlEvent;
};
@ -377,10 +377,10 @@ bool HandleControllerButtonEvent(const SDL_Event &event, const ControllerButtonE
SuppressedButton = ControllerButton_NONE;
}
if (ctrlEvent.up && sgOptions.Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent) != "") {
if (ctrlEvent.up && GetOptions().Padmapper.ActionNameTriggeredByButtonEvent(ctrlEvent) != "") {
// Button press may have brought up a menu;
// don't confuse release of that button with intent to interact with the menu
sgOptions.Padmapper.ButtonReleased(ctrlEvent.button);
GetOptions().Padmapper.ButtonReleased(ctrlEvent.button);
return true;
} else if (GetGameAction(event, ctrlEvent, &action)) {
ProcessGameAction(action);

2
Source/controls/plrctrls.cpp

@ -488,7 +488,7 @@ void FindTrigger()
bool IsStandingGround()
{
if (ControlMode == ControlTypes::Gamepad) {
ControllerButtonCombo standGroundCombo = sgOptions.Padmapper.ButtonComboForAction("StandGround");
ControllerButtonCombo standGroundCombo = GetOptions().Padmapper.ButtonComboForAction("StandGround");
return StandToggle || IsControllerButtonComboPressed(standGroundCombo);
}
#ifndef USE_SDL1

8
Source/cursor.cpp

@ -256,7 +256,7 @@ bool TrySelectPixelBased(Point tile)
const Point renderPosition = GetScreenPosition(renderingTile) + renderingOffset;
Point spriteTopLeft = renderPosition - Displacement { 0, sprite.height() };
Size spriteSize = { sprite.width(), sprite.height() };
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
spriteSize *= 2;
spriteTopLeft *= 2;
}
@ -264,7 +264,7 @@ bool TrySelectPixelBased(Point tile)
if (!spriteCoords.contains(MousePosition))
return false;
Point pointInSprite = Point { 0, 0 } + (MousePosition - spriteCoords.position);
if (*sgOptions.Graphics.zoom)
if (*GetOptions().Graphics.zoom)
pointInSprite /= 2;
return IsPointWithinClx(pointInSprite, sprite);
};
@ -666,7 +666,7 @@ void AlterMousePositionViaScrolling(Point &screenPosition, Rectangle mainPanel)
*/
void AlterMousePositionViaZoom(Point &screenPosition)
{
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
screenPosition.x /= 2;
screenPosition.y /= 2;
}
@ -722,7 +722,7 @@ Point ConvertToTileGrid(Point &screenPosition)
currentTile.y++;
}
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
screenPosition.y -= TILE_HEIGHT / 4;
}

222
Source/diablo.cpp

@ -457,7 +457,7 @@ void ReleaseKey(SDL_Keycode vkey)
remap_keyboard_key(&vkey);
if (sgnTimeoutCurs != CURSOR_NONE)
return;
sgOptions.Keymapper.KeyReleased(vkey);
GetOptions().Keymapper.KeyReleased(vkey);
}
void ClosePanels()
@ -477,6 +477,7 @@ void ClosePanels()
void PressKey(SDL_Keycode vkey, uint16_t modState)
{
Options &options = GetOptions();
remap_keyboard_key(&vkey);
if (vkey == SDLK_UNKNOWN)
@ -490,10 +491,10 @@ void PressKey(SDL_Keycode vkey, uint16_t modState)
if (sgnTimeoutCurs != CURSOR_NONE) {
return;
}
sgOptions.Keymapper.KeyPressed(vkey);
options.Keymapper.KeyPressed(vkey);
if (vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) {
if ((modState & KMOD_ALT) != 0) {
sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen());
options.Graphics.fullscreen.SetValue(!IsFullScreen());
SaveOptions();
} else {
TypeChatMessage();
@ -524,11 +525,11 @@ void PressKey(SDL_Keycode vkey, uint16_t modState)
return;
}
sgOptions.Keymapper.KeyPressed(vkey);
options.Keymapper.KeyPressed(vkey);
if (PauseMode == 2) {
if ((vkey == SDLK_RETURN || vkey == SDLK_KP_ENTER) && (modState & KMOD_ALT) != 0) {
sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen());
options.Graphics.fullscreen.SetValue(!IsFullScreen());
SaveOptions();
}
return;
@ -566,7 +567,7 @@ void PressKey(SDL_Keycode vkey, uint16_t modState)
case SDLK_RETURN:
case SDLK_KP_ENTER:
if ((modState & KMOD_ALT) != 0) {
sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen());
options.Graphics.fullscreen.SetValue(!IsFullScreen());
SaveOptions();
} else if (ActiveStore != TalkID::None) {
StoreEnter();
@ -655,7 +656,7 @@ void HandleMouseButtonDown(Uint8 button, uint16_t modState)
RightMouseDown((modState & KMOD_SHIFT) != 0);
break;
default:
sgOptions.Keymapper.KeyPressed(button | KeymapperMouseButtonMask);
GetOptions().Keymapper.KeyPressed(button | KeymapperMouseButtonMask);
break;
}
}
@ -671,7 +672,7 @@ void HandleMouseButtonUp(Uint8 button, uint16_t modState)
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
} else {
sgOptions.Keymapper.KeyReleased(static_cast<SDL_Keycode>(button | KeymapperMouseButtonMask));
GetOptions().Keymapper.KeyReleased(static_cast<SDL_Keycode>(button | KeymapperMouseButtonMask));
}
}
@ -682,6 +683,7 @@ void HandleMouseButtonUp(Uint8 button, uint16_t modState)
void GameEventHandler(const SDL_Event &event, uint16_t modState)
{
[[maybe_unused]] Options &options = GetOptions();
StaticVector<ControllerButtonEvent, 4> ctrlEvents = ToControllerButtonEvents(event);
for (ControllerButtonEvent ctrlEvent : ctrlEvents) {
GameAction action;
@ -755,7 +757,7 @@ void GameEventHandler(const SDL_Event &event, uint16_t modState)
} else if (IsStashOpen) {
Stash.PreviousPage();
} else {
sgOptions.Keymapper.KeyPressed(MouseScrollUpButton);
options.Keymapper.KeyPressed(MouseScrollUpButton);
}
} else if (event.wheel.y < 0) { // down
if (ActiveStore != TalkID::None) {
@ -769,12 +771,12 @@ void GameEventHandler(const SDL_Event &event, uint16_t modState)
} else if (IsStashOpen) {
Stash.NextPage();
} else {
sgOptions.Keymapper.KeyPressed(MouseScrollDownButton);
options.Keymapper.KeyPressed(MouseScrollDownButton);
}
} else if (event.wheel.x > 0) { // left
sgOptions.Keymapper.KeyPressed(MouseScrollLeftButton);
options.Keymapper.KeyPressed(MouseScrollLeftButton);
} else if (event.wheel.x < 0) { // right
sgOptions.Keymapper.KeyPressed(MouseScrollRightButton);
options.Keymapper.KeyPressed(MouseScrollRightButton);
}
break;
#endif
@ -1150,7 +1152,7 @@ void CheckArchivesUpToDate()
void ApplicationInit()
{
if (*sgOptions.Graphics.showFPS)
if (*GetOptions().Graphics.showFPS)
EnableFrameCount();
init_create_window();
@ -1166,9 +1168,9 @@ void ApplicationInit()
void DiabloInit()
{
if (forceSpawn || *sgOptions.GameMode.shareware)
if (forceSpawn || *GetOptions().GameMode.shareware)
gbIsSpawn = true;
if (forceDiablo || *sgOptions.GameMode.gameMode == StartUpGameMode::Diablo)
if (forceDiablo || *GetOptions().GameMode.gameMode == StartUpGameMode::Diablo)
gbIsHellfire = false;
if (forceHellfire)
gbIsHellfire = true;
@ -1176,7 +1178,7 @@ void DiabloInit()
gbIsHellfireSaveGame = gbIsHellfire;
for (size_t i = 0; i < QuickMessages.size(); i++) {
auto &messages = sgOptions.Chat.szHotKeyMsgs[i];
auto &messages = GetOptions().Chat.szHotKeyMsgs[i];
if (messages.empty()) {
messages.emplace_back(_(QuickMessages[i].message));
}
@ -1189,7 +1191,7 @@ void DiabloInit()
UiInitialize();
was_ui_init = true;
if (gbIsHellfire && !forceHellfire && *sgOptions.GameMode.gameMode == StartUpGameMode::Ask) {
if (gbIsHellfire && !forceHellfire && *GetOptions().GameMode.gameMode == StartUpGameMode::Ask) {
UiSelStartUpGameOption();
if (!gbIsHellfire) {
// Reinitialize the UI Elements because we changed the game
@ -1220,10 +1222,10 @@ void DiabloSplash()
if (!gbShowIntro)
return;
if (*sgOptions.StartUp.splash == StartUpSplash::LogoAndTitleDialog)
if (*GetOptions().StartUp.splash == StartUpSplash::LogoAndTitleDialog)
play_movie("gendata\\logo.smk", true);
auto &intro = gbIsHellfire ? sgOptions.StartUp.hellfireIntro : sgOptions.StartUp.diabloIntro;
auto &intro = gbIsHellfire ? GetOptions().StartUp.hellfireIntro : GetOptions().StartUp.diabloIntro;
if (*intro != StartUpIntro::Off) {
if (gbIsHellfire)
@ -1236,7 +1238,7 @@ void DiabloSplash()
}
}
if (IsAnyOf(*sgOptions.StartUp.splash, StartUpSplash::TitleDialog, StartUpSplash::LogoAndTitleDialog))
if (IsAnyOf(*GetOptions().StartUp.splash, StartUpSplash::TitleDialog, StartUpSplash::LogoAndTitleDialog))
UiTitleDialog();
}
@ -1674,8 +1676,9 @@ bool CanAutomapBeToggledOff()
void InitKeymapActions()
{
Options &options = GetOptions();
for (uint32_t i = 0; i < 8; ++i) {
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"BeltItem{}",
N_("Belt item {}"),
N_("Use Belt item."),
@ -1691,7 +1694,7 @@ void InitKeymapActions()
i + 1);
}
for (uint32_t i = 0; i < NumHotkeys; ++i) {
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuickSpell{}",
N_("Quick spell {}"),
N_("Hotkey for skill or spell."),
@ -1701,7 +1704,7 @@ void InitKeymapActions()
SetSpeedSpell(i);
return;
}
if (!*sgOptions.Gameplay.quickCast)
if (!*GetOptions().Gameplay.quickCast)
ToggleSpell(i);
else
QuickCast(i);
@ -1710,7 +1713,7 @@ void InitKeymapActions()
CanPlayerTakeAction,
i + 1);
}
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuickSpellPrevious",
N_("Previous quick spell"),
N_("Selects the previous quick spell (cycles)."),
@ -1718,7 +1721,7 @@ void InitKeymapActions()
[] { CycleSpellHotkeys(false); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuickSpellNext",
N_("Next quick spell"),
N_("Selects the next quick spell (cycles)."),
@ -1726,7 +1729,7 @@ void InitKeymapActions()
[] { CycleSpellHotkeys(true); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"UseHealthPotion",
N_("Use health potion"),
N_("Use health potions from belt."),
@ -1734,7 +1737,7 @@ void InitKeymapActions()
[] { UseBeltItem(BeltItemType::Healing); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"UseManaPotion",
N_("Use mana potion"),
N_("Use mana potions from belt."),
@ -1742,7 +1745,7 @@ void InitKeymapActions()
[] { UseBeltItem(BeltItemType::Mana); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"DisplaySpells",
N_("Speedbook"),
N_("Open Speedbook."),
@ -1750,7 +1753,7 @@ void InitKeymapActions()
DisplaySpellsKeyPressed,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuickSave",
N_("Quick save"),
N_("Saves the game."),
@ -1758,7 +1761,7 @@ void InitKeymapActions()
[] { gamemenu_save_game(false); },
nullptr,
[&]() { return !gbIsMultiplayer && CanPlayerTakeAction(); });
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuickLoad",
N_("Quick load"),
N_("Loads the game."),
@ -1767,14 +1770,14 @@ void InitKeymapActions()
nullptr,
[&]() { return !gbIsMultiplayer && gbValidSaveFile && ActiveStore == TalkID::None && IsGameRunning(); });
#ifndef NOEXIT
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuitGame",
N_("Quit game"),
N_("Closes the game."),
SDLK_UNKNOWN,
[] { gamemenu_quit_game(false); });
#endif
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"StopHero",
N_("Stop hero"),
N_("Stops walking and cancel pending actions."),
@ -1782,21 +1785,21 @@ void InitKeymapActions()
[] { MyPlayer->Stop(); },
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Item Highlighting",
N_("Item highlighting"),
N_("Show/hide items on ground."),
SDLK_LALT,
[] { HighlightKeyPressed(true); },
[] { HighlightKeyPressed(false); });
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Toggle Item Highlighting",
N_("Toggle item highlighting"),
N_("Permanent show/hide items on ground."),
SDLK_RCTRL,
nullptr,
[] { ToggleItemLabelHighlight(); });
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Toggle Automap",
N_("Toggle automap"),
N_("Toggles if automap is displayed."),
@ -1804,7 +1807,7 @@ void InitKeymapActions()
DoAutoMap,
nullptr,
IsGameRunning);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"CycleAutomapType",
N_("Cycle map type"),
N_("Opaque -> Transparent -> Minimap -> None"),
@ -1813,7 +1816,7 @@ void InitKeymapActions()
nullptr,
IsGameRunning);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Inventory",
N_("Inventory"),
N_("Open Inventory screen."),
@ -1821,7 +1824,7 @@ void InitKeymapActions()
InventoryKeyPressed,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Character",
N_("Character"),
N_("Open Character screen."),
@ -1829,7 +1832,7 @@ void InitKeymapActions()
CharacterSheetKeyPressed,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuestLog",
N_("Quest log"),
N_("Open Quest log."),
@ -1837,7 +1840,7 @@ void InitKeymapActions()
QuestLogKeyPressed,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"SpellBook",
N_("Spellbook"),
N_("Open Spellbook."),
@ -1846,7 +1849,7 @@ void InitKeymapActions()
nullptr,
CanPlayerTakeAction);
for (uint32_t i = 0; i < QuickMessages.size(); ++i) {
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"QuickMessage{}",
N_("Quick Message {}"),
N_("Use Quick Message in chat."),
@ -1856,7 +1859,7 @@ void InitKeymapActions()
nullptr,
i + 1);
}
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Hide Info Screens",
N_("Hide Info Screens"),
N_("Hide all info screens."),
@ -1880,30 +1883,30 @@ void InitKeymapActions()
},
nullptr,
IsGameRunning);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Zoom",
N_("Zoom"),
N_("Zoom Game Screen."),
'Z',
[] {
sgOptions.Graphics.zoom.SetValue(!*sgOptions.Graphics.zoom);
GetOptions().Graphics.zoom.SetValue(!*GetOptions().Graphics.zoom);
CalcViewportGeometry();
},
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Pause Game",
N_("Pause Game"),
N_("Pauses the game."),
'P',
diablo_pause_game);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Pause Game (Alternate)",
N_("Pause Game (Alternate)"),
N_("Pauses the game."),
SDLK_PAUSE,
diablo_pause_game);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"DecreaseGamma",
N_("Decrease Gamma"),
N_("Reduce screen brightness."),
@ -1911,7 +1914,7 @@ void InitKeymapActions()
DecreaseGamma,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"IncreaseGamma",
N_("Increase Gamma"),
N_("Increase screen brightness."),
@ -1919,7 +1922,7 @@ void InitKeymapActions()
IncreaseGamma,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Help",
N_("Help"),
N_("Open Help Screen."),
@ -1927,14 +1930,14 @@ void InitKeymapActions()
HelpKeyPressed,
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"Screenshot",
N_("Screenshot"),
N_("Takes a screenshot."),
SDLK_PRINTSCREEN,
nullptr,
CaptureScreen);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"GameInfo",
N_("Game info"),
N_("Displays game infos."),
@ -1948,7 +1951,7 @@ void InitKeymapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"ChatLog",
N_("Chat Log"),
N_("Displays chat log."),
@ -1956,7 +1959,7 @@ void InitKeymapActions()
[] {
ToggleChatLog();
});
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"SortInv",
N_("Sort Inventory"),
N_("Sorts the inventory."),
@ -1965,13 +1968,13 @@ void InitKeymapActions()
ReorganizeInventory(*MyPlayer);
});
#ifdef _DEBUG
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"OpenConsole",
N_("Console"),
N_("Opens Lua console."),
SDLK_BACKQUOTE,
OpenConsole);
sgOptions.Keymapper.AddAction(
options.Keymapper.AddAction(
"DebugToggle",
"Debug toggle",
"Programming is like magic.",
@ -1980,13 +1983,14 @@ void InitKeymapActions()
DebugToggle = !DebugToggle;
});
#endif
sgOptions.Keymapper.CommitActions();
options.Keymapper.CommitActions();
}
void InitPadmapActions()
{
Options &options = GetOptions();
for (int i = 0; i < 8; ++i) {
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"BeltItem{}",
N_("Belt item {}"),
N_("Use Belt item."),
@ -2002,7 +2006,7 @@ void InitPadmapActions()
i + 1);
}
for (uint32_t i = 0; i < NumHotkeys; ++i) {
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"QuickSpell{}",
N_("Quick spell {}"),
N_("Hotkey for skill or spell."),
@ -2012,7 +2016,7 @@ void InitPadmapActions()
SetSpeedSpell(i);
return;
}
if (!*sgOptions.Gameplay.quickCast)
if (!*GetOptions().Gameplay.quickCast)
ToggleSpell(i);
else
QuickCast(i);
@ -2021,7 +2025,7 @@ void InitPadmapActions()
CanPlayerTakeAction,
i + 1);
}
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"PrimaryAction",
N_("Primary action"),
N_("Attack monsters, talk to towners, lift and place inventory items."),
@ -2036,7 +2040,7 @@ void InitPadmapActions()
LastMouseButtonAction = MouseActionType::None;
},
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"SecondaryAction",
N_("Secondary action"),
N_("Open chests, interact with doors, pick up items."),
@ -2051,7 +2055,7 @@ void InitPadmapActions()
LastMouseButtonAction = MouseActionType::None;
},
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"SpellAction",
N_("Spell action"),
N_("Cast the active spell."),
@ -2066,7 +2070,7 @@ void InitPadmapActions()
LastMouseButtonAction = MouseActionType::None;
},
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"CancelAction",
N_("Cancel action"),
N_("Close menus."),
@ -2092,37 +2096,37 @@ void InitPadmapActions()
},
nullptr,
[] { return DoomFlag || SpellSelectFlag || invflag || SpellbookFlag || QuestLogIsOpen || CharFlag; });
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MoveUp",
N_("Move up"),
N_("Moves the player character up."),
ControllerButton_BUTTON_DPAD_UP,
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MoveDown",
N_("Move down"),
N_("Moves the player character down."),
ControllerButton_BUTTON_DPAD_DOWN,
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MoveLeft",
N_("Move left"),
N_("Moves the player character left."),
ControllerButton_BUTTON_DPAD_LEFT,
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MoveRight",
N_("Move right"),
N_("Moves the player character right."),
ControllerButton_BUTTON_DPAD_RIGHT,
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"StandGround",
N_("Stand ground"),
N_("Hold to prevent the player from moving."),
ControllerButton_NONE,
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"ToggleStandGround",
N_("Toggle stand ground"),
N_("Toggle whether the player moves."),
@ -2130,7 +2134,7 @@ void InitPadmapActions()
[] { StandToggle = !StandToggle; },
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"UseHealthPotion",
N_("Use health potion"),
N_("Use health potions from belt."),
@ -2138,7 +2142,7 @@ void InitPadmapActions()
[] { UseBeltItem(BeltItemType::Healing); },
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"UseManaPotion",
N_("Use mana potion"),
N_("Use mana potions from belt."),
@ -2146,7 +2150,7 @@ void InitPadmapActions()
[] { UseBeltItem(BeltItemType::Mana); },
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Character",
N_("Character"),
N_("Open Character screen."),
@ -2154,7 +2158,7 @@ void InitPadmapActions()
[] {
ProcessGameAction(GameAction { GameActionType_TOGGLE_CHARACTER_INFO });
});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Inventory",
N_("Inventory"),
N_("Open Inventory screen."),
@ -2164,7 +2168,7 @@ void InitPadmapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"QuestLog",
N_("Quest log"),
N_("Open Quest log."),
@ -2174,7 +2178,7 @@ void InitPadmapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"SpellBook",
N_("Spellbook"),
N_("Open Spellbook."),
@ -2184,7 +2188,7 @@ void InitPadmapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"DisplaySpells",
N_("Speedbook"),
N_("Open Speedbook."),
@ -2194,57 +2198,57 @@ void InitPadmapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Toggle Automap",
N_("Toggle automap"),
N_("Toggles if automap is displayed."),
ControllerButton_BUTTON_LEFTSTICK,
DoAutoMap);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MouseUp",
N_("Move mouse up"),
N_("Simulates upward mouse movement."),
{ ControllerButton_BUTTON_BACK, ControllerButton_BUTTON_DPAD_UP },
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MouseDown",
N_("Move mouse down"),
N_("Simulates downward mouse movement."),
{ ControllerButton_BUTTON_BACK, ControllerButton_BUTTON_DPAD_DOWN },
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MouseLeft",
N_("Move mouse left"),
N_("Simulates leftward mouse movement."),
{ ControllerButton_BUTTON_BACK, ControllerButton_BUTTON_DPAD_LEFT },
[] {});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"MouseRight",
N_("Move mouse right"),
N_("Simulates rightward mouse movement."),
{ ControllerButton_BUTTON_BACK, ControllerButton_BUTTON_DPAD_RIGHT },
[] {});
auto leftMouseDown = [] {
ControllerButtonCombo standGroundCombo = sgOptions.Padmapper.ButtonComboForAction("StandGround");
ControllerButtonCombo standGroundCombo = GetOptions().Padmapper.ButtonComboForAction("StandGround");
bool standGround = StandToggle || IsControllerButtonComboPressed(standGroundCombo);
sgbMouseDown = CLICK_LEFT;
LeftMouseDown(standGround ? KMOD_SHIFT : KMOD_NONE);
};
auto leftMouseUp = [] {
ControllerButtonCombo standGroundCombo = sgOptions.Padmapper.ButtonComboForAction("StandGround");
ControllerButtonCombo standGroundCombo = GetOptions().Padmapper.ButtonComboForAction("StandGround");
bool standGround = StandToggle || IsControllerButtonComboPressed(standGroundCombo);
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
LeftMouseUp(standGround ? KMOD_SHIFT : KMOD_NONE);
};
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"LeftMouseClick1",
N_("Left mouse click"),
N_("Simulates the left mouse button."),
ControllerButton_BUTTON_RIGHTSTICK,
leftMouseDown,
leftMouseUp);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"LeftMouseClick2",
N_("Left mouse click"),
N_("Simulates the left mouse button."),
@ -2252,7 +2256,7 @@ void InitPadmapActions()
leftMouseDown,
leftMouseUp);
auto rightMouseDown = [] {
ControllerButtonCombo standGroundCombo = sgOptions.Padmapper.ButtonComboForAction("StandGround");
ControllerButtonCombo standGroundCombo = GetOptions().Padmapper.ButtonComboForAction("StandGround");
bool standGround = StandToggle || IsControllerButtonComboPressed(standGroundCombo);
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_RIGHT;
@ -2262,28 +2266,28 @@ void InitPadmapActions()
LastMouseButtonAction = MouseActionType::None;
sgbMouseDown = CLICK_NONE;
};
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"RightMouseClick1",
N_("Right mouse click"),
N_("Simulates the right mouse button."),
{ ControllerButton_BUTTON_BACK, ControllerButton_BUTTON_RIGHTSTICK },
rightMouseDown,
rightMouseUp);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"RightMouseClick2",
N_("Right mouse click"),
N_("Simulates the right mouse button."),
{ ControllerButton_BUTTON_BACK, ControllerButton_BUTTON_RIGHTSHOULDER },
rightMouseDown,
rightMouseUp);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"PadHotspellMenu",
N_("Gamepad hotspell menu"),
N_("Hold to set or use spell hotkeys."),
ControllerButton_BUTTON_BACK,
[] { PadHotspellMenuActive = true; },
[] { PadHotspellMenuActive = false; });
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"PadMenuNavigator",
N_("Gamepad menu navigator"),
N_("Hold to access gamepad menu navigation."),
@ -2299,7 +2303,7 @@ void InitPadmapActions()
if (!inMenu)
gamemenu_on();
};
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"ToggleGameMenu1",
N_("Toggle game menu"),
N_("Opens the game menu."),
@ -2308,7 +2312,7 @@ void InitPadmapActions()
ControllerButton_BUTTON_START,
},
toggleGameMenu);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"ToggleGameMenu2",
N_("Toggle game menu"),
N_("Opens the game menu."),
@ -2317,7 +2321,7 @@ void InitPadmapActions()
ControllerButton_BUTTON_BACK,
},
toggleGameMenu);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"QuickSave",
N_("Quick save"),
N_("Saves the game."),
@ -2325,7 +2329,7 @@ void InitPadmapActions()
[] { gamemenu_save_game(false); },
nullptr,
[&]() { return !gbIsMultiplayer && CanPlayerTakeAction(); });
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"QuickLoad",
N_("Quick load"),
N_("Loads the game."),
@ -2333,21 +2337,21 @@ void InitPadmapActions()
[] { gamemenu_load_game(false); },
nullptr,
[&]() { return !gbIsMultiplayer && gbValidSaveFile && ActiveStore == TalkID::None && IsGameRunning(); });
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Item Highlighting",
N_("Item highlighting"),
N_("Show/hide items on ground."),
ControllerButton_NONE,
[] { HighlightKeyPressed(true); },
[] { HighlightKeyPressed(false); });
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Toggle Item Highlighting",
N_("Toggle item highlighting"),
N_("Permanent show/hide items on ground."),
ControllerButton_NONE,
nullptr,
[] { ToggleItemLabelHighlight(); });
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Hide Info Screens",
N_("Hide Info Screens"),
N_("Hide all info screens."),
@ -2371,24 +2375,24 @@ void InitPadmapActions()
},
nullptr,
IsGameRunning);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Zoom",
N_("Zoom"),
N_("Zoom Game Screen."),
ControllerButton_NONE,
[] {
sgOptions.Graphics.zoom.SetValue(!*sgOptions.Graphics.zoom);
GetOptions().Graphics.zoom.SetValue(!*GetOptions().Graphics.zoom);
CalcViewportGeometry();
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Pause Game",
N_("Pause Game"),
N_("Pauses the game."),
ControllerButton_NONE,
diablo_pause_game);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"DecreaseGamma",
N_("Decrease Gamma"),
N_("Reduce screen brightness."),
@ -2396,7 +2400,7 @@ void InitPadmapActions()
DecreaseGamma,
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"IncreaseGamma",
N_("Increase Gamma"),
N_("Increase screen brightness."),
@ -2404,7 +2408,7 @@ void InitPadmapActions()
IncreaseGamma,
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Help",
N_("Help"),
N_("Open Help Screen."),
@ -2412,14 +2416,14 @@ void InitPadmapActions()
HelpKeyPressed,
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"Screenshot",
N_("Screenshot"),
N_("Takes a screenshot."),
ControllerButton_NONE,
nullptr,
CaptureScreen);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"GameInfo",
N_("Game info"),
N_("Displays game infos."),
@ -2433,7 +2437,7 @@ void InitPadmapActions()
},
nullptr,
CanPlayerTakeAction);
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"SortInv",
N_("Sort Inventory"),
N_("Sorts the inventory."),
@ -2441,7 +2445,7 @@ void InitPadmapActions()
[] {
ReorganizeInventory(*MyPlayer);
});
sgOptions.Padmapper.AddAction(
options.Padmapper.AddAction(
"ChatLog",
N_("Chat Log"),
N_("Displays chat log."),
@ -2449,7 +2453,7 @@ void InitPadmapActions()
[] {
ToggleChatLog();
});
sgOptions.Padmapper.CommitActions();
options.Padmapper.CommitActions();
}
void SetCursorPos(Point position)
@ -3281,7 +3285,7 @@ bool game_loop(bool bStartup)
void diablo_color_cyc_logic()
{
if (!*sgOptions.Graphics.colorCycling)
if (!*GetOptions().Graphics.colorCycling)
return;
if (PauseMode != 0)

4
Source/dvlnet/tcp_client.cpp

@ -19,7 +19,7 @@ namespace devilution::net {
int tcp_client::create(std::string_view addrstr)
{
auto port = *sgOptions.Network.port;
auto port = *GetOptions().Network.port;
local_server = std::make_unique<tcp_server>(ioc, std::string(addrstr), port, *pktfty);
return join(local_server->LocalhostSelf());
}
@ -218,7 +218,7 @@ bool tcp_client::SNetLeaveGame(int type)
std::string tcp_client::make_default_gamename()
{
return std::string(sgOptions.Network.szBindAddress);
return std::string(GetOptions().Network.szBindAddress);
}
void tcp_client::RaiseIoHandlerError(const PacketError &error)

104
Source/engine/demomode.cpp

@ -215,29 +215,30 @@ void WriteSettings(FILE *out)
{
WriteLE16(out, gnScreenWidth);
WriteLE16(out, gnScreenHeight);
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.runInTown));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.theoQuest));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.cowQuest));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoGoldPickup));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoElixirPickup));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoOilPickup));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoPickupInTown));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.adriaRefillsMana));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoEquipWeapons));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoEquipArmor));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoEquipHelms));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoEquipShields));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoEquipJewelry));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.randomizeQuests));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.showItemLabels));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.autoRefillBelt));
WriteByte(out, static_cast<uint8_t>(*sgOptions.Gameplay.disableCripplingShrines));
WriteByte(out, *sgOptions.Gameplay.numHealPotionPickup);
WriteByte(out, *sgOptions.Gameplay.numFullHealPotionPickup);
WriteByte(out, *sgOptions.Gameplay.numManaPotionPickup);
WriteByte(out, *sgOptions.Gameplay.numFullManaPotionPickup);
WriteByte(out, *sgOptions.Gameplay.numRejuPotionPickup);
WriteByte(out, *sgOptions.Gameplay.numFullRejuPotionPickup);
const Options &options = GetOptions();
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.runInTown));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.theoQuest));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.cowQuest));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoGoldPickup));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoElixirPickup));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoOilPickup));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoPickupInTown));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.adriaRefillsMana));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipWeapons));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipArmor));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipHelms));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipShields));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoEquipJewelry));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.randomizeQuests));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.showItemLabels));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.autoRefillBelt));
WriteByte(out, static_cast<uint8_t>(*options.Gameplay.disableCripplingShrines));
WriteByte(out, *options.Gameplay.numHealPotionPickup);
WriteByte(out, *options.Gameplay.numFullHealPotionPickup);
WriteByte(out, *options.Gameplay.numManaPotionPickup);
WriteByte(out, *options.Gameplay.numFullManaPotionPickup);
WriteByte(out, *options.Gameplay.numRejuPotionPickup);
WriteByte(out, *options.Gameplay.numFullRejuPotionPickup);
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
@ -589,39 +590,40 @@ void InitRecording(int recordNumber, bool createDemoReference)
void OverrideOptions()
{
#ifndef USE_SDL1
sgOptions.Graphics.fitToScreen.SetValue(false);
GetOptions().Graphics.fitToScreen.SetValue(false);
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
sgOptions.Graphics.hardwareCursor.SetValue(false);
GetOptions().Graphics.hardwareCursor.SetValue(false);
#endif
if (Timedemo) {
sgOptions.Graphics.frameRateControl.SetValue(FrameRateControl::None);
GetOptions().Graphics.frameRateControl.SetValue(FrameRateControl::None);
}
forceResolution = Size(DemoGraphicsWidth, DemoGraphicsHeight);
sgOptions.Gameplay.runInTown.SetValue(DemoSettings.runInTown);
sgOptions.Gameplay.theoQuest.SetValue(DemoSettings.theoQuest);
sgOptions.Gameplay.cowQuest.SetValue(DemoSettings.cowQuest);
sgOptions.Gameplay.autoGoldPickup.SetValue(DemoSettings.autoGoldPickup);
sgOptions.Gameplay.autoElixirPickup.SetValue(DemoSettings.autoElixirPickup);
sgOptions.Gameplay.autoOilPickup.SetValue(DemoSettings.autoOilPickup);
sgOptions.Gameplay.autoPickupInTown.SetValue(DemoSettings.autoPickupInTown);
sgOptions.Gameplay.adriaRefillsMana.SetValue(DemoSettings.adriaRefillsMana);
sgOptions.Gameplay.autoEquipWeapons.SetValue(DemoSettings.autoEquipWeapons);
sgOptions.Gameplay.autoEquipArmor.SetValue(DemoSettings.autoEquipArmor);
sgOptions.Gameplay.autoEquipHelms.SetValue(DemoSettings.autoEquipHelms);
sgOptions.Gameplay.autoEquipShields.SetValue(DemoSettings.autoEquipShields);
sgOptions.Gameplay.autoEquipJewelry.SetValue(DemoSettings.autoEquipJewelry);
sgOptions.Gameplay.randomizeQuests.SetValue(DemoSettings.randomizeQuests);
sgOptions.Gameplay.showItemLabels.SetValue(DemoSettings.showItemLabels);
sgOptions.Gameplay.autoRefillBelt.SetValue(DemoSettings.autoRefillBelt);
sgOptions.Gameplay.disableCripplingShrines.SetValue(DemoSettings.disableCripplingShrines);
sgOptions.Gameplay.numHealPotionPickup.SetValue(DemoSettings.numHealPotionPickup);
sgOptions.Gameplay.numFullHealPotionPickup.SetValue(DemoSettings.numFullHealPotionPickup);
sgOptions.Gameplay.numManaPotionPickup.SetValue(DemoSettings.numManaPotionPickup);
sgOptions.Gameplay.numFullManaPotionPickup.SetValue(DemoSettings.numFullManaPotionPickup);
sgOptions.Gameplay.numRejuPotionPickup.SetValue(DemoSettings.numRejuPotionPickup);
sgOptions.Gameplay.numFullRejuPotionPickup.SetValue(DemoSettings.numFullRejuPotionPickup);
Options &options = GetOptions();
options.Gameplay.runInTown.SetValue(DemoSettings.runInTown);
options.Gameplay.theoQuest.SetValue(DemoSettings.theoQuest);
options.Gameplay.cowQuest.SetValue(DemoSettings.cowQuest);
options.Gameplay.autoGoldPickup.SetValue(DemoSettings.autoGoldPickup);
options.Gameplay.autoElixirPickup.SetValue(DemoSettings.autoElixirPickup);
options.Gameplay.autoOilPickup.SetValue(DemoSettings.autoOilPickup);
options.Gameplay.autoPickupInTown.SetValue(DemoSettings.autoPickupInTown);
options.Gameplay.adriaRefillsMana.SetValue(DemoSettings.adriaRefillsMana);
options.Gameplay.autoEquipWeapons.SetValue(DemoSettings.autoEquipWeapons);
options.Gameplay.autoEquipArmor.SetValue(DemoSettings.autoEquipArmor);
options.Gameplay.autoEquipHelms.SetValue(DemoSettings.autoEquipHelms);
options.Gameplay.autoEquipShields.SetValue(DemoSettings.autoEquipShields);
options.Gameplay.autoEquipJewelry.SetValue(DemoSettings.autoEquipJewelry);
options.Gameplay.randomizeQuests.SetValue(DemoSettings.randomizeQuests);
options.Gameplay.showItemLabels.SetValue(DemoSettings.showItemLabels);
options.Gameplay.autoRefillBelt.SetValue(DemoSettings.autoRefillBelt);
options.Gameplay.disableCripplingShrines.SetValue(DemoSettings.disableCripplingShrines);
options.Gameplay.numHealPotionPickup.SetValue(DemoSettings.numHealPotionPickup);
options.Gameplay.numFullHealPotionPickup.SetValue(DemoSettings.numFullHealPotionPickup);
options.Gameplay.numManaPotionPickup.SetValue(DemoSettings.numManaPotionPickup);
options.Gameplay.numFullManaPotionPickup.SetValue(DemoSettings.numFullManaPotionPickup);
options.Gameplay.numRejuPotionPickup.SetValue(DemoSettings.numRejuPotionPickup);
options.Gameplay.numFullRejuPotionPickup.SetValue(DemoSettings.numFullRejuPotionPickup);
}
bool IsRunning()
@ -700,12 +702,12 @@ bool FetchMessage(SDL_Event *event, uint16_t *modState)
}
if (e.type == SDL_KEYDOWN && IsAnyOf(e.key.keysym.sym, SDLK_KP_PLUS, SDLK_PLUS) && sgGameInitInfo.nTickRate < 255) {
sgGameInitInfo.nTickRate++;
sgOptions.Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate);
GetOptions().Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate);
gnTickDelay = 1000 / sgGameInitInfo.nTickRate;
}
if (e.type == SDL_KEYDOWN && IsAnyOf(e.key.keysym.sym, SDLK_KP_MINUS, SDLK_MINUS) && sgGameInitInfo.nTickRate > 1) {
sgGameInitInfo.nTickRate--;
sgOptions.Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate);
GetOptions().Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate);
gnTickDelay = 1000 / sgGameInitInfo.nTickRate;
}
}

6
Source/engine/dx.cpp

@ -72,7 +72,7 @@ bool CanRenderDirectlyToOutputSurface()
*/
void LimitFrameRate()
{
if (*sgOptions.Graphics.frameRateControl != FrameRateControl::CPUSleep)
if (*GetOptions().Graphics.frameRateControl != FrameRateControl::CPUSleep)
return;
static uint32_t frameDeadline;
uint32_t tc = SDL_GetTicks() * 1000;
@ -117,7 +117,7 @@ void dx_cleanup()
#ifndef USE_SDL1
texture = nullptr;
FreeVirtualGamepadTextures();
if (*sgOptions.Graphics.upscale)
if (*GetOptions().Graphics.upscale)
SDL_DestroyRenderer(renderer);
#endif
SDL_DestroyWindow(ghMainWnd);
@ -249,7 +249,7 @@ void RenderPresent()
}
SDL_RenderPresent(renderer);
if (*sgOptions.Graphics.frameRateControl != FrameRateControl::VerticalSync) {
if (*GetOptions().Graphics.frameRateControl != FrameRateControl::VerticalSync) {
LimitFrameRate();
}
} else {

2
Source/engine/events.cpp

@ -143,7 +143,7 @@ EventHandler CurrentEventHandler;
EventHandler SetEventHandler(EventHandler eventHandler)
{
sgOptions.Padmapper.ReleaseAllActiveButtons();
GetOptions().Padmapper.ReleaseAllActiveButtons();
EventHandler previousHandler = CurrentEventHandler;
CurrentEventHandler = eventHandler;

20
Source/engine/palette.cpp

@ -42,9 +42,9 @@ bool sgbFadedIn = true;
void LoadGamma()
{
int gammaValue = *sgOptions.Graphics.gammaCorrection;
int gammaValue = *GetOptions().Graphics.gammaCorrection;
gammaValue = std::clamp(gammaValue, 30, 100);
sgOptions.Graphics.gammaCorrection.SetValue(gammaValue - gammaValue % 5);
GetOptions().Graphics.gammaCorrection.SetValue(gammaValue - gammaValue % 5);
}
Uint8 FindBestMatchForColor(std::array<SDL_Color, 256> &palette, SDL_Color color, int skipFrom, int skipTo)
@ -185,7 +185,7 @@ void palette_update(int first, int ncolor)
void ApplyGamma(std::array<SDL_Color, 256> &dst, const std::array<SDL_Color, 256> &src, int n)
{
float g = *sgOptions.Graphics.gammaCorrection / 100.0F;
float g = *GetOptions().Graphics.gammaCorrection / 100.0F;
for (int i = 0; i < n; i++) {
dst[i].r = static_cast<Uint8>(pow(src[i].r / 256.0F, g) * 256.0F);
@ -257,7 +257,7 @@ void LoadRndLvlPal(dungeon_type l)
int rv = RandomIntBetween(1, 4);
char szFileName[27];
if (l == DTYPE_NEST) {
if (!*sgOptions.Graphics.alternateNestArt) {
if (!*GetOptions().Graphics.alternateNestArt) {
rv++;
}
*fmt::format_to(szFileName, R"(nlevels\l{0}data\l{0}base{1}.pal)", 6, rv) = '\0';
@ -269,9 +269,9 @@ void LoadRndLvlPal(dungeon_type l)
void IncreaseGamma()
{
int gammaValue = *sgOptions.Graphics.gammaCorrection;
int gammaValue = *GetOptions().Graphics.gammaCorrection;
if (gammaValue < 100) {
sgOptions.Graphics.gammaCorrection.SetValue(std::min(gammaValue + 5, 100));
GetOptions().Graphics.gammaCorrection.SetValue(std::min(gammaValue + 5, 100));
ApplyGamma(system_palette, logical_palette, 256);
palette_update();
}
@ -279,9 +279,9 @@ void IncreaseGamma()
void DecreaseGamma()
{
int gammaValue = *sgOptions.Graphics.gammaCorrection;
int gammaValue = *GetOptions().Graphics.gammaCorrection;
if (gammaValue > 30) {
sgOptions.Graphics.gammaCorrection.SetValue(std::max(gammaValue - 5, 30));
GetOptions().Graphics.gammaCorrection.SetValue(std::max(gammaValue - 5, 30));
ApplyGamma(system_palette, logical_palette, 256);
palette_update();
}
@ -290,11 +290,11 @@ void DecreaseGamma()
int UpdateGamma(int gamma)
{
if (gamma > 0) {
sgOptions.Graphics.gammaCorrection.SetValue(130 - gamma);
GetOptions().Graphics.gammaCorrection.SetValue(130 - gamma);
ApplyGamma(system_palette, logical_palette, 256);
palette_update();
}
return 130 - *sgOptions.Graphics.gammaCorrection;
return 130 - *GetOptions().Graphics.gammaCorrection;
}
void SetFadeLevel(int fadeval, bool updateHardwareCursor, const std::array<SDL_Color, 256> &srcPalette)

30
Source/engine/render/scrollrt.cpp

@ -1023,11 +1023,11 @@ void CalcFirstTilePosition(Point &position, Displacement &offset)
// Skip rendering parts covered by the panels
if (CanPanelsCoverView() && (IsLeftPanelOpen() || IsRightPanelOpen())) {
int multiplier = (*sgOptions.Graphics.zoom) ? 1 : 2;
int multiplier = (*GetOptions().Graphics.zoom) ? 1 : 2;
position += Displacement(Direction::East) * multiplier;
offset.deltaX += -TILE_WIDTH * multiplier / 2 / 2;
if (IsLeftPanelOpen() && !*sgOptions.Graphics.zoom) {
if (IsLeftPanelOpen() && !*GetOptions().Graphics.zoom) {
offset.deltaX += SidePanelSize.width;
// SidePanelSize.width accounted for in Zoom()
}
@ -1065,7 +1065,7 @@ void CalcFirstTilePosition(Point &position, Displacement &offset)
void DrawGame(const Surface &fullOut, Point position, Displacement offset)
{
// Limit rendering to the view area
const Surface &out = !*sgOptions.Graphics.zoom
const Surface &out = !*GetOptions().Graphics.zoom
? fullOut.subregionY(0, gnViewportHeight)
: fullOut.subregionY(0, (gnViewportHeight + 1) / 2);
@ -1074,7 +1074,7 @@ void DrawGame(const Surface &fullOut, Point position, Displacement offset)
// Skip rendering parts covered by the panels
if (CanPanelsCoverView() && (IsLeftPanelOpen() || IsRightPanelOpen())) {
columns -= (*sgOptions.Graphics.zoom) ? 2 : 4;
columns -= (*GetOptions().Graphics.zoom) ? 2 : 4;
}
UpdateMissilesRendererData();
@ -1112,7 +1112,7 @@ void DrawGame(const Surface &fullOut, Point position, Displacement offset)
DrawFloor(out, position, Point {} + offset, rows, columns);
DrawTileContent(out, position, Point {} + offset, rows, columns);
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
Zoom(fullOut.subregionY(0, gnViewportHeight));
}
@ -1165,11 +1165,11 @@ void DrawView(const Surface &out, Point startPosition)
continue;
if (megaTiles)
pixelCoords += Displacement { 0, TILE_HEIGHT / 2 };
if (*sgOptions.Graphics.zoom)
if (*GetOptions().Graphics.zoom)
pixelCoords *= 2;
if (debugGridTextNeeded && GetDebugGridText(dunCoords, debugGridTextBuffer)) {
Size tileSize = { TILE_WIDTH, TILE_HEIGHT };
if (*sgOptions.Graphics.zoom)
if (*GetOptions().Graphics.zoom)
tileSize *= 2;
DrawString(out, debugGridTextBuffer, { pixelCoords - Displacement { 0, tileSize.height }, tileSize },
{ .flags = UiFlags::ColorRed | UiFlags::AlignCenter | UiFlags::VerticalCenter });
@ -1177,7 +1177,7 @@ void DrawView(const Surface &out, Point startPosition)
if (DebugGrid) {
int halfTileWidth = TILE_WIDTH / 2;
int halfTileHeight = TILE_HEIGHT / 2;
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
halfTileWidth *= 2;
halfTileHeight *= 2;
}
@ -1426,7 +1426,7 @@ int RowsCoveredByPanel()
}
int rows = mainPanelSize.height / TILE_HEIGHT;
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
rows /= 2;
}
@ -1441,7 +1441,7 @@ void CalcTileOffset(int *offsetX, int *offsetY)
int x;
int y;
if (!*sgOptions.Graphics.zoom) {
if (!*GetOptions().Graphics.zoom) {
x = screenWidth % TILE_WIDTH;
y = viewportHeight % TILE_HEIGHT;
} else {
@ -1472,7 +1472,7 @@ void TilesInView(int *rcolumns, int *rrows)
rows++;
}
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
// Half the number of tiles, rounded up
if ((columns & 1) != 0) {
columns++;
@ -1490,14 +1490,14 @@ void TilesInView(int *rcolumns, int *rrows)
void CalcViewportGeometry()
{
const int zoomFactor = *sgOptions.Graphics.zoom ? 2 : 1;
const int zoomFactor = *GetOptions().Graphics.zoom ? 2 : 1;
const int screenWidth = GetScreenWidth() / zoomFactor;
const int screenHeight = GetScreenHeight() / zoomFactor;
const int panelHeight = GetMainPanel().size.height / zoomFactor;
const int pixelsToPanel = screenHeight - panelHeight;
Point playerPosition { screenWidth / 2, pixelsToPanel / 2 };
if (*sgOptions.Graphics.zoom)
if (*GetOptions().Graphics.zoom)
playerPosition.y += TILE_HEIGHT / 4;
const int tilesToTop = (playerPosition.y + TILE_HEIGHT - 1) / TILE_HEIGHT;
@ -1705,9 +1705,9 @@ void DrawAndBlit()
DrawChatBox(out);
}
DrawXPBar(out);
if (*sgOptions.Gameplay.showHealthValues)
if (*GetOptions().Gameplay.showHealthValues)
DrawFlaskValues(out, { mainPanel.position.x + 134, mainPanel.position.y + 28 }, MyPlayer->_pHitPoints >> 6, MyPlayer->_pMaxHP >> 6);
if (*sgOptions.Gameplay.showManaValues)
if (*GetOptions().Gameplay.showManaValues)
DrawFlaskValues(out, { mainPanel.position.x + mainPanel.size.width - 138, mainPanel.position.y + 28 },
(HasAnyOf(InspectPlayer->_pIFlags, ItemSpecialEffect::NoMana) || (MyPlayer->_pMana >> 6) <= 0) ? 0 : MyPlayer->_pMana >> 6,
HasAnyOf(InspectPlayer->_pIFlags, ItemSpecialEffect::NoMana) ? 0 : MyPlayer->_pMaxMana >> 6);

28
Source/engine/sound.cpp

@ -176,7 +176,7 @@ void snd_play_snd(TSnd *pSnd, int lVolume, int lPan)
return;
}
sound->PlayWithVolumeAndPan(lVolume, *sgOptions.Audio.soundVolume, lPan);
sound->PlayWithVolumeAndPan(lVolume, *GetOptions().Audio.soundVolume, lPan);
pSnd->start_tc = tc;
}
@ -206,17 +206,17 @@ TSnd::~TSnd()
void snd_init()
{
sgOptions.Audio.soundVolume.SetValue(CapVolume(*sgOptions.Audio.soundVolume));
gbSoundOn = *sgOptions.Audio.soundVolume > VOLUME_MIN;
GetOptions().Audio.soundVolume.SetValue(CapVolume(*GetOptions().Audio.soundVolume));
gbSoundOn = *GetOptions().Audio.soundVolume > VOLUME_MIN;
sgbSaveSoundOn = gbSoundOn;
sgOptions.Audio.musicVolume.SetValue(CapVolume(*sgOptions.Audio.musicVolume));
gbMusicOn = *sgOptions.Audio.musicVolume > VOLUME_MIN;
GetOptions().Audio.musicVolume.SetValue(CapVolume(*GetOptions().Audio.musicVolume));
gbMusicOn = *GetOptions().Audio.musicVolume > VOLUME_MIN;
// Initialize the SDL_audiolib library. Set the output sample rate to
// 22kHz, the audio format to 16-bit signed, use 2 output channels
// (stereo), and a 2KiB output buffer.
if (!Aulib::init(*sgOptions.Audio.sampleRate, AUDIO_S16, *sgOptions.Audio.channels, *sgOptions.Audio.bufferSize, *sgOptions.Audio.device)) {
if (!Aulib::init(*GetOptions().Audio.sampleRate, AUDIO_S16, *GetOptions().Audio.channels, *GetOptions().Audio.bufferSize, *GetOptions().Audio.device)) {
LogError(LogCategory::Audio, "Failed to initialize audio (Aulib::init): {}", SDL_GetError());
return;
}
@ -288,7 +288,7 @@ void music_start(_music_id nTrack)
return;
}
music.SetVolume(*sgOptions.Audio.musicVolume, VOLUME_MIN, VOLUME_MAX);
music.SetVolume(*GetOptions().Audio.musicVolume, VOLUME_MIN, VOLUME_MAX);
if (!diablo_is_focused())
music_mute();
if (!music.Play(/*numIterations=*/0)) {
@ -312,24 +312,24 @@ void sound_disable_music(bool disable)
int sound_get_or_set_music_volume(int volume)
{
if (volume == 1)
return *sgOptions.Audio.musicVolume;
return *GetOptions().Audio.musicVolume;
sgOptions.Audio.musicVolume.SetValue(volume);
GetOptions().Audio.musicVolume.SetValue(volume);
if (music.IsLoaded())
music.SetVolume(*sgOptions.Audio.musicVolume, VOLUME_MIN, VOLUME_MAX);
music.SetVolume(*GetOptions().Audio.musicVolume, VOLUME_MIN, VOLUME_MAX);
return *sgOptions.Audio.musicVolume;
return *GetOptions().Audio.musicVolume;
}
int sound_get_or_set_sound_volume(int volume)
{
if (volume == 1)
return *sgOptions.Audio.soundVolume;
return *GetOptions().Audio.soundVolume;
sgOptions.Audio.soundVolume.SetValue(volume);
GetOptions().Audio.soundVolume.SetValue(volume);
return *sgOptions.Audio.soundVolume;
return *GetOptions().Audio.soundVolume;
}
void music_mute()

2
Source/gamemenu.cpp

@ -282,7 +282,7 @@ void GamemenuSpeed(bool bActivate)
sgGameInitInfo.nTickRate = gmenu_slider_get(&sgOptionsMenu[3], 20, 50);
}
sgOptions.Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate);
GetOptions().Gameplay.tickRate.SetValue(sgGameInitInfo.nTickRate);
gnTickDelay = 1000 / sgGameInitInfo.nTickRate;
}

10
Source/hwcursor.cpp

@ -46,11 +46,11 @@ Size ScaledSize(Size size)
bool IsCursorSizeAllowed(Size size)
{
if (*sgOptions.Graphics.hardwareCursorMaxSize <= 0)
if (*GetOptions().Graphics.hardwareCursorMaxSize <= 0)
return true;
size = ScaledSize(size);
return size.width <= *sgOptions.Graphics.hardwareCursorMaxSize
&& size.height <= *sgOptions.Graphics.hardwareCursorMaxSize;
return size.width <= *GetOptions().Graphics.hardwareCursorMaxSize
&& size.height <= *GetOptions().Graphics.hardwareCursorMaxSize;
}
Point GetHotpointPosition(const SDL_Surface &surface, HotpointPosition position)
@ -66,7 +66,7 @@ Point GetHotpointPosition(const SDL_Surface &surface, HotpointPosition position)
bool ShouldUseBilinearScaling()
{
return *sgOptions.Graphics.scaleQuality != ScalingQuality::NearestPixel;
return *GetOptions().Graphics.scaleQuality != ScalingQuality::NearestPixel;
}
bool SetHardwareCursorFromSurface(SDL_Surface *surface, HotpointPosition hotpointPosition)
@ -124,7 +124,7 @@ bool SetHardwareCursorFromClxSprite(ClxSprite sprite, HotpointPosition hotpointP
bool SetHardwareCursorFromSprite(int pcurs)
{
const bool isItem = !MyPlayer->HoldItem.isEmpty();
if (isItem && !*sgOptions.Graphics.hardwareCursorForItems)
if (isItem && !*GetOptions().Graphics.hardwareCursorForItems)
return false;
const int outlineWidth = isItem ? 1 : 0;

2
Source/hwcursor.hpp

@ -21,7 +21,7 @@ namespace devilution {
inline bool IsHardwareCursorEnabled()
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
return *sgOptions.Graphics.hardwareCursor && HardwareCursorSupported();
return *GetOptions().Graphics.hardwareCursor && HardwareCursorSupported();
#else
return false;
#endif

4
Source/init.cpp

@ -182,11 +182,11 @@ void MainWndProc(const SDL_Event &event)
diablo_quit(0);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
if (*sgOptions.Gameplay.pauseOnFocusLoss)
if (*GetOptions().Gameplay.pauseOnFocusLoss)
diablo_focus_pause();
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
if (*sgOptions.Gameplay.pauseOnFocusLoss)
if (*GetOptions().Gameplay.pauseOnFocusLoss)
diablo_focus_unpause();
break;
case SDL_WINDOWEVENT_MOVED:

2
Source/interfac.cpp

@ -473,7 +473,7 @@ void InitRendering()
void CheckShouldSkipRendering()
{
if (!ProgressEventHandlerState.skipRendering) return;
const bool shouldSkip = ProgressEventHandlerState.loadStartedAt + *sgOptions.Gameplay.skipLoadingScreenThresholdMs > SDL_GetTicks();
const bool shouldSkip = ProgressEventHandlerState.loadStartedAt + *GetOptions().Gameplay.skipLoadingScreenThresholdMs > SDL_GetTicks();
if (shouldSkip) return;
ProgressEventHandlerState.skipRendering = false;
if (!HeadlessMode) InitRendering();

18
Source/inv.cpp

@ -277,7 +277,7 @@ bool AutoEquip(Player &player, const Item &item, inv_body_loc bodyLocation, bool
if (persistItem) {
ChangeEquipment(player, bodyLocation, item, sendNetworkMessage);
if (sendNetworkMessage && *sgOptions.Audio.autoEquipSound) {
if (sendNetworkMessage && *GetOptions().Audio.autoEquipSound) {
PlaySFX(ItemInvSnds[ItemCAnimTbl[item._iCurs]]);
}
@ -1352,23 +1352,23 @@ bool AutoEquipEnabled(const Player &player, const Item &item)
if (item.isWeapon()) {
// Monk can use unarmed attack as an encouraged option, thus we do not automatically equip weapons on him so as to not
// annoy players who prefer that playstyle.
return player._pClass != HeroClass::Monk && *sgOptions.Gameplay.autoEquipWeapons;
return player._pClass != HeroClass::Monk && *GetOptions().Gameplay.autoEquipWeapons;
}
if (item.isArmor()) {
return *sgOptions.Gameplay.autoEquipArmor;
return *GetOptions().Gameplay.autoEquipArmor;
}
if (item.isHelm()) {
return *sgOptions.Gameplay.autoEquipHelms;
return *GetOptions().Gameplay.autoEquipHelms;
}
if (item.isShield()) {
return *sgOptions.Gameplay.autoEquipShields;
return *GetOptions().Gameplay.autoEquipShields;
}
if (item.isJewelry()) {
return *sgOptions.Gameplay.autoEquipJewelry;
return *GetOptions().Gameplay.autoEquipJewelry;
}
return true;
@ -1754,7 +1754,7 @@ void AutoGetItem(Player &player, Item *itemPointer, int ii)
}
if (done) {
if (!autoEquipped && *sgOptions.Audio.itemPickupSound && &player == MyPlayer) {
if (!autoEquipped && *GetOptions().Audio.itemPickupSound && &player == MyPlayer) {
PlaySFX(SfxID::GrabItem);
}
@ -2086,7 +2086,7 @@ bool UseInvItem(int cii)
speedlist = true;
// If selected speedlist item exists in InvList, use the InvList item.
for (int i = 0; i < player._pNumInv && *sgOptions.Gameplay.autoRefillBelt; i++) {
for (int i = 0; i < player._pNumInv && *GetOptions().Gameplay.autoRefillBelt; i++) {
if (player.InvList[i]._iMiscId == item->_iMiscId && player.InvList[i]._iSpell == item->_iSpell) {
c = i;
item = &player.InvList[c];
@ -2097,7 +2097,7 @@ bool UseInvItem(int cii)
}
// If speedlist item is not inventory, use same item at the end of the speedlist if exists.
if (speedlist && *sgOptions.Gameplay.autoRefillBelt) {
if (speedlist && *GetOptions().Gameplay.autoRefillBelt) {
for (int i = INVITEM_BELT_LAST - INVITEM_BELT_FIRST; i > c; i--) {
Item &candidate = player.SpdList[i];

12
Source/items.cpp

@ -2402,7 +2402,7 @@ bool IsItemAvailable(int i)
|| (
// Bard items are technically Hellfire-exclusive
// but are just normal items with adjusted stats.
*sgOptions.Gameplay.testBard && IsAnyOf(i, IDI_BARDSWORD, IDI_BARDDAGGER));
*GetOptions().Gameplay.testBard && IsAnyOf(i, IDI_BARDSWORD, IDI_BARDDAGGER));
}
uint8_t GetOutlineColor(const Item &item, bool checkReq)
@ -3583,11 +3583,11 @@ void CornerstoneSave()
PackItem(id, CornerStone.item, (CornerStone.item.dwBuff & CF_HELLFIRE) != 0);
const auto *buffer = reinterpret_cast<uint8_t *>(&id);
for (size_t i = 0; i < sizeof(ItemPack); i++) {
fmt::format_to(&sgOptions.Hellfire.szItem[i * 2], "{:02X}", buffer[i]);
fmt::format_to(&GetOptions().Hellfire.szItem[i * 2], "{:02X}", buffer[i]);
}
sgOptions.Hellfire.szItem[sizeof(sgOptions.Hellfire.szItem) - 1] = '\0';
GetOptions().Hellfire.szItem[sizeof(GetOptions().Hellfire.szItem) - 1] = '\0';
} else {
sgOptions.Hellfire.szItem[0] = '\0';
GetOptions().Hellfire.szItem[0] = '\0';
}
}
@ -3612,10 +3612,10 @@ void CornerstoneLoad(Point position)
dItem[position.x][position.y] = 0;
}
if (strlen(sgOptions.Hellfire.szItem) < sizeof(ItemPack) * 2)
if (strlen(GetOptions().Hellfire.szItem) < sizeof(ItemPack) * 2)
return;
Hex2bin(sgOptions.Hellfire.szItem, sizeof(ItemPack), reinterpret_cast<uint8_t *>(&pkSItem));
Hex2bin(GetOptions().Hellfire.szItem, sizeof(ItemPack), reinterpret_cast<uint8_t *>(&pkSItem));
int ii = AllocateItem();
auto &item = Items[ii];

2
Source/lua/lua.cpp

@ -201,7 +201,7 @@ void LuaReloadActiveMods()
CurrentLuaState->events = RunScript(/*env=*/std::nullopt, "devilutionx.events", /*optional=*/false);
CurrentLuaState->commonPackages["devilutionx.events"] = CurrentLuaState->events;
for (std::string_view modname : sgOptions.Mods.GetActiveModList()) {
for (std::string_view modname : GetOptions().Mods.GetActiveModList()) {
std::string packageName = StrCat("mods.", modname, ".init");
RunScript(CreateLuaSandbox(), packageName, /*optional=*/true);
}

4
Source/menu.cpp

@ -101,7 +101,7 @@ bool mainmenu_select_hero_dialog(GameData *gameData)
pfile_ui_set_hero_infos(DummyGetHeroInfo);
gbLoadGame = true;
} else if (!gbIsMultiplayer) {
pSaveNumberFromOptions = gbIsHellfire ? &sgOptions.Hellfire.lastSinglePlayerHero : &sgOptions.Diablo.lastSinglePlayerHero;
pSaveNumberFromOptions = gbIsHellfire ? &GetOptions().Hellfire.lastSinglePlayerHero : &GetOptions().Diablo.lastSinglePlayerHero;
gSaveNumber = **pSaveNumberFromOptions;
UiSelHeroSingDialog(
pfile_ui_set_hero_infos,
@ -114,7 +114,7 @@ bool mainmenu_select_hero_dialog(GameData *gameData)
gbLoadGame = (dlgresult == SELHERO_CONTINUE);
} else {
pSaveNumberFromOptions = gbIsHellfire ? &sgOptions.Hellfire.lastMultiplayerHero : &sgOptions.Diablo.lastMultiplayerHero;
pSaveNumberFromOptions = gbIsHellfire ? &GetOptions().Hellfire.lastMultiplayerHero : &GetOptions().Diablo.lastMultiplayerHero;
gSaveNumber = **pSaveNumberFromOptions;
UiSelHeroMultDialog(
pfile_ui_set_hero_infos,

4
Source/monster.cpp

@ -4314,7 +4314,7 @@ void M_FallenFear(Point position)
void PrintMonstHistory(int mt)
{
if (*sgOptions.Gameplay.showMonsterType) {
if (*GetOptions().Gameplay.showMonsterType) {
AddInfoBoxString(fmt::format(fmt::runtime(_("Type: {:s} Kills: {:d}")), GetMonsterTypeText(MonstersData[mt]), MonsterKillCounts[mt]));
} else {
AddInfoBoxString(fmt::format(fmt::runtime(_("Total kills: {:d}")), MonsterKillCounts[mt]));
@ -4383,7 +4383,7 @@ void PrintMonstHistory(int mt)
void PrintUniqueHistory()
{
Monster &monster = Monsters[pcursmonst];
if (*sgOptions.Gameplay.showMonsterType) {
if (*GetOptions().Gameplay.showMonsterType) {
AddInfoBoxString(fmt::format(fmt::runtime(_("Type: {:s}")), GetMonsterTypeText(monster.data())));
}

2
Source/movie.cpp

@ -59,7 +59,7 @@ void play_movie(const char *pszMovie, bool userCanClose)
break;
#ifndef USE_SDL1
case SDL_WINDOWEVENT:
if (*sgOptions.Gameplay.pauseOnFocusLoss) {
if (*GetOptions().Gameplay.pauseOnFocusLoss) {
if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST)
diablo_focus_pause();
else if (event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)

2
Source/msg.cpp

@ -2287,7 +2287,7 @@ size_t OnCheatExperience(const TCmd *pCmd, Player &player) // NOLINT(misc-unused
SendPacket(player, pCmd, sizeof(*pCmd));
else if (!player.isMaxCharacterLevel()) {
player._pExperience = player.getNextExperienceThreshold();
if (*sgOptions.Gameplay.experienceBar) {
if (*GetOptions().Gameplay.experienceBar) {
RedrawEverything();
}
NextPlrLevel(player);

13
Source/multi.cpp

@ -516,12 +516,13 @@ void InitGameInfo()
sgGameInitInfo.versionMajor = PROJECT_VERSION_MAJOR;
sgGameInitInfo.versionMinor = PROJECT_VERSION_MINOR;
sgGameInitInfo.versionPatch = PROJECT_VERSION_PATCH;
sgGameInitInfo.nTickRate = *sgOptions.Gameplay.tickRate;
sgGameInitInfo.bRunInTown = *sgOptions.Gameplay.runInTown ? 1 : 0;
sgGameInitInfo.bTheoQuest = *sgOptions.Gameplay.theoQuest ? 1 : 0;
sgGameInitInfo.bCowQuest = *sgOptions.Gameplay.cowQuest ? 1 : 0;
sgGameInitInfo.bFriendlyFire = *sgOptions.Gameplay.friendlyFire ? 1 : 0;
sgGameInitInfo.fullQuests = (!gbIsMultiplayer || *sgOptions.Gameplay.multiplayerFullQuests) ? 1 : 0;
const Options &options = GetOptions();
sgGameInitInfo.nTickRate = *options.Gameplay.tickRate;
sgGameInitInfo.bRunInTown = *options.Gameplay.runInTown ? 1 : 0;
sgGameInitInfo.bTheoQuest = *options.Gameplay.theoQuest ? 1 : 0;
sgGameInitInfo.bCowQuest = *options.Gameplay.cowQuest ? 1 : 0;
sgGameInitInfo.bFriendlyFire = *options.Gameplay.friendlyFire ? 1 : 0;
sgGameInitInfo.fullQuests = (!gbIsMultiplayer || *options.Gameplay.multiplayerFullQuests) ? 1 : 0;
}
void NetSendLoPri(uint8_t playerId, const std::byte *data, size_t size)

2
Source/objects.cpp

@ -3619,7 +3619,7 @@ unsigned int Object::GetId() const
bool Object::IsDisabled() const
{
if (!*sgOptions.Gameplay.disableCripplingShrines) {
if (!*GetOptions().Gameplay.disableCripplingShrines) {
return false;
}
if (IsAnyOf(_otype, _object_id::OBJ_GOATSHRINE, _object_id::OBJ_CAULDRON)) {

107
Source/options.cpp

@ -145,10 +145,10 @@ bool HardwareCursorDefault()
void OptionGrabInputChanged()
{
#ifdef USE_SDL1
SDL_WM_GrabInput(*sgOptions.Gameplay.grabInput ? SDL_GRAB_ON : SDL_GRAB_OFF);
SDL_WM_GrabInput(*GetOptions().Gameplay.grabInput ? SDL_GRAB_ON : SDL_GRAB_OFF);
#else
if (ghMainWnd != nullptr)
SDL_SetWindowGrab(ghMainWnd, *sgOptions.Gameplay.grabInput ? SDL_TRUE : SDL_FALSE);
SDL_SetWindowGrab(ghMainWnd, *GetOptions().Gameplay.grabInput ? SDL_TRUE : SDL_FALSE);
#endif
}
@ -156,7 +156,7 @@ void OptionExperienceBarChanged()
{
if (!gbRunGame)
return;
if (*sgOptions.Gameplay.experienceBar)
if (*GetOptions().Gameplay.experienceBar)
InitXPBar();
else
FreeXPBar();
@ -166,7 +166,7 @@ void OptionEnemyHealthBarChanged()
{
if (!gbRunGame)
return;
if (*sgOptions.Gameplay.enemyHealthBar)
if (*GetOptions().Gameplay.enemyHealthBar)
InitMonsterHealthBar();
else
FreeMonsterHealthBar();
@ -177,14 +177,14 @@ void ResizeWindowAndUpdateResolutionOptions()
{
ResizeWindow();
#ifndef __3DS__
sgOptions.Graphics.resolution.InvalidateList();
GetOptions().Graphics.resolution.InvalidateList();
#endif
}
#endif
void OptionShowFPSChanged()
{
if (*sgOptions.Graphics.showFPS)
if (*GetOptions().Graphics.showFPS)
EnableFrameCount();
else
frameflag = false;
@ -199,13 +199,13 @@ void OptionLanguageCodeChanged()
void OptionGameModeChanged()
{
gbIsHellfire = *sgOptions.GameMode.gameMode == StartUpGameMode::Hellfire;
gbIsHellfire = *GetOptions().GameMode.gameMode == StartUpGameMode::Hellfire;
discord_manager::UpdateMenu(true);
}
void OptionSharewareChanged()
{
gbIsSpawn = *sgOptions.GameMode.shareware;
gbIsSpawn = *GetOptions().GameMode.shareware;
}
void OptionAudioChanged()
@ -223,8 +223,11 @@ void OptionAudioChanged()
} // namespace
/** Game options */
Options sgOptions;
Options &GetOptions()
{
static Options options;
return options;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
bool HardwareCursorSupported()
@ -242,20 +245,21 @@ bool HardwareCursorSupported()
void LoadOptions()
{
LoadIni();
for (OptionCategoryBase *pCategory : sgOptions.GetCategories()) {
Options &options = GetOptions();
for (OptionCategoryBase *pCategory : options.GetCategories()) {
for (OptionEntryBase *pEntry : pCategory->GetEntries()) {
pEntry->LoadFromIni(pCategory->GetKey());
}
}
ini->getUtf8Buf("Hellfire", "SItem", sgOptions.Hellfire.szItem, sizeof(sgOptions.Hellfire.szItem));
ini->getUtf8Buf("Network", "Bind Address", "0.0.0.0", sgOptions.Network.szBindAddress, sizeof(sgOptions.Network.szBindAddress));
ini->getUtf8Buf("Network", "Previous Game ID", sgOptions.Network.szPreviousZTGame, sizeof(sgOptions.Network.szPreviousZTGame));
ini->getUtf8Buf("Network", "Previous Host", sgOptions.Network.szPreviousHost, sizeof(sgOptions.Network.szPreviousHost));
ini->getUtf8Buf("Hellfire", "SItem", options.Hellfire.szItem, sizeof(options.Hellfire.szItem));
ini->getUtf8Buf("Network", "Bind Address", "0.0.0.0", options.Network.szBindAddress, sizeof(options.Network.szBindAddress));
ini->getUtf8Buf("Network", "Previous Game ID", options.Network.szPreviousZTGame, sizeof(options.Network.szPreviousZTGame));
ini->getUtf8Buf("Network", "Previous Host", options.Network.szPreviousHost, sizeof(options.Network.szPreviousHost));
for (size_t i = 0; i < QuickMessages.size(); i++) {
std::span<const Ini::Value> values = ini->get("NetMsg", QuickMessages[i].key);
std::vector<std::string> &result = sgOptions.Chat.szHotKeyMsgs[i];
std::vector<std::string> &result = options.Chat.szHotKeyMsgs[i];
result.clear();
result.reserve(values.size());
for (const Ini::Value &value : values) {
@ -263,10 +267,10 @@ void LoadOptions()
}
}
ini->getUtf8Buf("Controller", "Mapping", sgOptions.Controller.szMapping, sizeof(sgOptions.Controller.szMapping));
sgOptions.Controller.fDeadzone = ini->getFloat("Controller", "deadzone", 0.07F);
ini->getUtf8Buf("Controller", "Mapping", options.Controller.szMapping, sizeof(options.Controller.szMapping));
options.Controller.fDeadzone = ini->getFloat("Controller", "deadzone", 0.07F);
#ifdef __vita__
sgOptions.Controller.bRearTouch = ini->getBool("Controller", "Enable Rear Touchpad", true);
options.Controller.bRearTouch = ini->getBool("Controller", "Enable Rear Touchpad", true);
#endif
if (demo::IsRunning())
@ -278,26 +282,27 @@ void SaveOptions()
if (demo::IsRunning())
return;
for (OptionCategoryBase *pCategory : sgOptions.GetCategories()) {
for (OptionEntryBase *pEntry : pCategory->GetEntries()) {
Options &options = GetOptions();
for (OptionCategoryBase *pCategory : options.GetCategories()) {
for (const OptionEntryBase *pEntry : pCategory->GetEntries()) {
pEntry->SaveToIni(pCategory->GetKey());
}
}
ini->set("Hellfire", "SItem", sgOptions.Hellfire.szItem);
ini->set("Hellfire", "SItem", options.Hellfire.szItem);
ini->set("Network", "Bind Address", sgOptions.Network.szBindAddress);
ini->set("Network", "Previous Game ID", sgOptions.Network.szPreviousZTGame);
ini->set("Network", "Previous Host", sgOptions.Network.szPreviousHost);
ini->set("Network", "Bind Address", options.Network.szBindAddress);
ini->set("Network", "Previous Game ID", options.Network.szPreviousZTGame);
ini->set("Network", "Previous Host", options.Network.szPreviousHost);
for (size_t i = 0; i < QuickMessages.size(); i++) {
ini->set("NetMsg", QuickMessages[i].key, sgOptions.Chat.szHotKeyMsgs[i]);
ini->set("NetMsg", QuickMessages[i].key, options.Chat.szHotKeyMsgs[i]);
}
ini->set("Controller", "Mapping", sgOptions.Controller.szMapping);
ini->set("Controller", "deadzone", sgOptions.Controller.fDeadzone);
ini->set("Controller", "Mapping", options.Controller.szMapping);
ini->set("Controller", "deadzone", options.Controller.fDeadzone);
#ifdef __vita__
ini->set("Controller", "Enable Rear Touchpad", sgOptions.Controller.bRearTouch);
ini->set("Controller", "Enable Rear Touchpad", options.Controller.bRearTouch);
#endif
SaveIni();
@ -634,7 +639,7 @@ void OptionEntryResolution::CheckResolutionsAreInitialized() const
static_cast<int>(mode.w * scaleFactor),
static_cast<int>(mode.h * scaleFactor) });
}
supportsAnyResolution = *sgOptions.Graphics.upscale;
supportsAnyResolution = *GetOptions().Graphics.upscale;
#endif
if (supportsAnyResolution && sizes.size() == 1) {
@ -659,7 +664,7 @@ void OptionEntryResolution::CheckResolutionsAreInitialized() const
sizes.emplace_back(Size { 640, 480 });
#ifndef USE_SDL1
if (*sgOptions.Graphics.fitToScreen) {
if (*GetOptions().Graphics.fitToScreen) {
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(0, &mode) != 0) {
ErrSdl();
@ -685,7 +690,7 @@ void OptionEntryResolution::CheckResolutionsAreInitialized() const
for (auto &size : sizes) {
#ifndef USE_SDL1
if (*sgOptions.Graphics.fitToScreen) {
if (*GetOptions().Graphics.fitToScreen) {
resolutions.emplace_back(size, StrCat(size.height, "p"));
continue;
}
@ -772,9 +777,9 @@ void OptionEntryResampler::UpdateDependentOptions() const
{
#ifdef DEVILUTIONX_RESAMPLER_SPEEX
if (resampler_ == Resampler::Speex) {
sgOptions.Audio.resamplingQuality.flags &= ~OptionEntryFlags::Invisible;
GetOptions().Audio.resamplingQuality.flags &= ~OptionEntryFlags::Invisible;
} else {
sgOptions.Audio.resamplingQuality.flags |= OptionEntryFlags::Invisible;
GetOptions().Audio.resamplingQuality.flags |= OptionEntryFlags::Invisible;
}
#endif
}
@ -1314,8 +1319,8 @@ void KeymapperOptions::Action::LoadFromIni(std::string_view category)
return;
}
auto keyIt = sgOptions.Keymapper.keyNameToKeyID.find(iniValue);
if (keyIt == sgOptions.Keymapper.keyNameToKeyID.end()) {
auto keyIt = GetOptions().Keymapper.keyNameToKeyID.find(iniValue);
if (keyIt == GetOptions().Keymapper.keyNameToKeyID.end()) {
// Use the default key if the key is unknown.
Log("Keymapper: unknown key '{}'", iniValue);
SetValue(defaultKey);
@ -1333,8 +1338,8 @@ void KeymapperOptions::Action::SaveToIni(std::string_view category) const
ini->set(category, key, std::string {});
return;
}
auto keyNameIt = sgOptions.Keymapper.keyIDToKeyName.find(boundKey);
if (keyNameIt == sgOptions.Keymapper.keyIDToKeyName.end()) {
auto keyNameIt = GetOptions().Keymapper.keyIDToKeyName.find(boundKey);
if (keyNameIt == GetOptions().Keymapper.keyIDToKeyName.end()) {
LogVerbose("Keymapper: no name found for key {} bound to {}", boundKey, key);
return;
}
@ -1345,8 +1350,8 @@ std::string_view KeymapperOptions::Action::GetValueDescription() const
{
if (boundKey == SDLK_UNKNOWN)
return "";
auto keyNameIt = sgOptions.Keymapper.keyIDToKeyName.find(boundKey);
if (keyNameIt == sgOptions.Keymapper.keyIDToKeyName.end()) {
auto keyNameIt = GetOptions().Keymapper.keyIDToKeyName.find(boundKey);
if (keyNameIt == GetOptions().Keymapper.keyIDToKeyName.end()) {
return "";
}
return keyNameIt->second;
@ -1354,27 +1359,27 @@ std::string_view KeymapperOptions::Action::GetValueDescription() const
bool KeymapperOptions::Action::SetValue(int value)
{
if (value != SDLK_UNKNOWN && sgOptions.Keymapper.keyIDToKeyName.find(value) == sgOptions.Keymapper.keyIDToKeyName.end()) {
if (value != SDLK_UNKNOWN && GetOptions().Keymapper.keyIDToKeyName.find(value) == GetOptions().Keymapper.keyIDToKeyName.end()) {
// Ignore invalid key values
return false;
}
// Remove old key
if (boundKey != SDLK_UNKNOWN) {
sgOptions.Keymapper.keyIDToAction.erase(boundKey);
GetOptions().Keymapper.keyIDToAction.erase(boundKey);
boundKey = SDLK_UNKNOWN;
}
// Add new key
if (value != SDLK_UNKNOWN) {
auto it = sgOptions.Keymapper.keyIDToAction.find(value);
if (it != sgOptions.Keymapper.keyIDToAction.end()) {
auto it = GetOptions().Keymapper.keyIDToAction.find(value);
if (it != GetOptions().Keymapper.keyIDToAction.end()) {
// Warn about overwriting keys.
Log("Keymapper: key '{}' is already bound to action '{}', overwriting", value, it->second.get().name);
it->second.get().boundKey = SDLK_UNKNOWN;
}
sgOptions.Keymapper.keyIDToAction.insert_or_assign(value, *this);
GetOptions().Keymapper.keyIDToAction.insert_or_assign(value, *this);
boundKey = value;
}
@ -1545,8 +1550,8 @@ void PadmapperOptions::Action::LoadFromIni(std::string_view category)
ControllerButtonCombo input {};
if (!modName.empty()) {
auto modifierIt = sgOptions.Padmapper.buttonNameToButton.find(modName);
if (modifierIt == sgOptions.Padmapper.buttonNameToButton.end()) {
auto modifierIt = GetOptions().Padmapper.buttonNameToButton.find(modName);
if (modifierIt == GetOptions().Padmapper.buttonNameToButton.end()) {
// Use the default button combo if the modifier name is unknown.
LogWarn("Padmapper: unknown button '{}'", modName);
SetValue(defaultInput);
@ -1555,8 +1560,8 @@ void PadmapperOptions::Action::LoadFromIni(std::string_view category)
input.modifier = modifierIt->second;
}
auto buttonIt = sgOptions.Padmapper.buttonNameToButton.find(buttonName);
if (buttonIt == sgOptions.Padmapper.buttonNameToButton.end()) {
auto buttonIt = GetOptions().Padmapper.buttonNameToButton.find(buttonName);
if (buttonIt == GetOptions().Padmapper.buttonNameToButton.end()) {
// Use the default button combo if the button name is unknown.
LogWarn("Padmapper: unknown button '{}'", buttonName);
SetValue(defaultInput);
@ -1575,13 +1580,13 @@ void PadmapperOptions::Action::SaveToIni(std::string_view category) const
ini->set(category, key, "");
return;
}
std::string inputName = sgOptions.Padmapper.buttonToButtonName[static_cast<size_t>(boundInput.button)];
std::string inputName = GetOptions().Padmapper.buttonToButtonName[static_cast<size_t>(boundInput.button)];
if (inputName.empty()) {
LogVerbose("Padmapper: no name found for button {} bound to {}", static_cast<size_t>(boundInput.button), key);
return;
}
if (boundInput.modifier != ControllerButton_NONE) {
const std::string &modifierName = sgOptions.Padmapper.buttonToButtonName[static_cast<size_t>(boundInput.modifier)];
const std::string &modifierName = GetOptions().Padmapper.buttonToButtonName[static_cast<size_t>(boundInput.modifier)];
if (modifierName.empty()) {
LogVerbose("Padmapper: no name found for modifier button {} bound to {}", static_cast<size_t>(boundInput.button), key);
return;

5
Source/options.h

@ -864,7 +864,10 @@ struct Options {
}
};
extern DVL_API_FOR_TEST Options sgOptions;
/**
* @brief Get the Options singleton object
*/
[[nodiscard]] Options &GetOptions();
bool HardwareCursorSupported();

4
Source/panels/spell_list.cpp

@ -73,8 +73,8 @@ std::optional<std::string_view> GetHotkeyName(SpellID spellId, SpellType spellTy
continue;
auto quickSpellActionKey = StrCat("QuickSpell", t + 1);
if (ControlMode == ControlTypes::Gamepad)
return sgOptions.Padmapper.InputNameForAction(quickSpellActionKey, useShortName);
return sgOptions.Keymapper.KeyNameForAction(quickSpellActionKey);
return GetOptions().Padmapper.InputNameForAction(quickSpellActionKey, useShortName);
return GetOptions().Keymapper.KeyNameForAction(quickSpellActionKey);
}
return {};
}

2
Source/platform/vita/touch.cpp

@ -405,7 +405,7 @@ void PreprocessEvents(SDL_Event *event)
// front (0) or back (1) panel
SDL_TouchID port = event->tfinger.touchId;
if (port != 0) {
if (devilution::sgOptions.Controller.bRearTouch) {
if (devilution::GetOptions().Controller.bRearTouch) {
switch (event->type) {
case SDL_FINGERDOWN:
PreprocessBackFingerDown(event);

6
Source/player.cpp

@ -393,7 +393,7 @@ void InitLevelChange(Player &player)
bool DoWalk(Player &player)
{
// Play walking sound effect on certain animation frames
if (*sgOptions.Audio.walkingSound && (leveltype != DTYPE_TOWN || sgGameInitInfo.bRunInTown == 0)) {
if (*GetOptions().Audio.walkingSound && (leveltype != DTYPE_TOWN || sgGameInitInfo.bRunInTown == 0)) {
if (player.AnimInfo.currentFrame == 0
|| player.AnimInfo.currentFrame == 4) {
PlaySfxLoc(SfxID::Walk, player.position.tile);
@ -1409,7 +1409,7 @@ void ValidatePlayer()
// This lets us catch cases where someone is editing experience directly through memory modification and reset their experience back to the expected cap.
if (myPlayer._pExperience > myPlayer.getNextExperienceThreshold()) {
myPlayer._pExperience = myPlayer.getNextExperienceThreshold();
if (*sgOptions.Gameplay.experienceBar) {
if (*GetOptions().Gameplay.experienceBar) {
RedrawEverything();
}
}
@ -2380,7 +2380,7 @@ void Player::_addExperience(uint32_t experience, int levelDelta)
// ensure we only add enough experience to reach the max experience cap so we don't overflow
_pExperience += std::min(clampedExp, maxExperience - _pExperience);
if (*sgOptions.Gameplay.experienceBar) {
if (*GetOptions().Gameplay.experienceBar) {
RedrawEverything();
}

20
Source/qol/autopickup.cpp

@ -43,29 +43,29 @@ int NumMiscItemsInInv(int iMiscId)
bool DoPickup(Item item)
{
if (item._itype == ItemType::Gold && *sgOptions.Gameplay.autoGoldPickup && HasRoomForGold())
if (item._itype == ItemType::Gold && *GetOptions().Gameplay.autoGoldPickup && HasRoomForGold())
return true;
if (item._itype == ItemType::Misc
&& (CanFitItemInInventory(*MyPlayer, item) || AutoPlaceItemInBelt(*MyPlayer, item))) {
switch (item._iMiscId) {
case IMISC_HEAL:
return *sgOptions.Gameplay.numHealPotionPickup > NumMiscItemsInInv(item._iMiscId);
return *GetOptions().Gameplay.numHealPotionPickup > NumMiscItemsInInv(item._iMiscId);
case IMISC_FULLHEAL:
return *sgOptions.Gameplay.numFullHealPotionPickup > NumMiscItemsInInv(item._iMiscId);
return *GetOptions().Gameplay.numFullHealPotionPickup > NumMiscItemsInInv(item._iMiscId);
case IMISC_MANA:
return *sgOptions.Gameplay.numManaPotionPickup > NumMiscItemsInInv(item._iMiscId);
return *GetOptions().Gameplay.numManaPotionPickup > NumMiscItemsInInv(item._iMiscId);
case IMISC_FULLMANA:
return *sgOptions.Gameplay.numFullManaPotionPickup > NumMiscItemsInInv(item._iMiscId);
return *GetOptions().Gameplay.numFullManaPotionPickup > NumMiscItemsInInv(item._iMiscId);
case IMISC_REJUV:
return *sgOptions.Gameplay.numRejuPotionPickup > NumMiscItemsInInv(item._iMiscId);
return *GetOptions().Gameplay.numRejuPotionPickup > NumMiscItemsInInv(item._iMiscId);
case IMISC_FULLREJUV:
return *sgOptions.Gameplay.numFullRejuPotionPickup > NumMiscItemsInInv(item._iMiscId);
return *GetOptions().Gameplay.numFullRejuPotionPickup > NumMiscItemsInInv(item._iMiscId);
case IMISC_ELIXSTR:
case IMISC_ELIXMAG:
case IMISC_ELIXDEX:
case IMISC_ELIXVIT:
return *sgOptions.Gameplay.autoElixirPickup;
return *GetOptions().Gameplay.autoElixirPickup;
case IMISC_OILFIRST:
case IMISC_OILOF:
case IMISC_OILACC:
@ -79,7 +79,7 @@ bool DoPickup(Item item)
case IMISC_OILHARD:
case IMISC_OILIMP:
case IMISC_OILLAST:
return *sgOptions.Gameplay.autoOilPickup;
return *GetOptions().Gameplay.autoOilPickup;
default:
return false;
}
@ -94,7 +94,7 @@ void AutoPickup(const Player &player)
{
if (&player != MyPlayer)
return;
if (leveltype == DTYPE_TOWN && !*sgOptions.Gameplay.autoPickupInTown)
if (leveltype == DTYPE_TOWN && !*GetOptions().Gameplay.autoPickupInTown)
return;
for (auto pathDir : PathDirs) {

12
Source/qol/floatingnumbers.cpp

@ -101,9 +101,9 @@ void AddFloatingNumber(Point pos, Displacement offset, DamageType type, int valu
};
Displacement endOffset;
if (*sgOptions.Gameplay.enableFloatingNumbers == FloatingNumbers::Random) {
if (*GetOptions().Gameplay.enableFloatingNumbers == FloatingNumbers::Random) {
endOffset = goodAngles[rand() % 3];
} else if (*sgOptions.Gameplay.enableFloatingNumbers == FloatingNumbers::Vertical) {
} else if (*GetOptions().Gameplay.enableFloatingNumbers == FloatingNumbers::Vertical) {
endOffset = goodAngles[0];
}
@ -129,7 +129,7 @@ void AddFloatingNumber(Point pos, Displacement offset, DamageType type, int valu
void AddFloatingNumber(DamageType damageType, const Monster &monster, int damage)
{
if (*sgOptions.Gameplay.enableFloatingNumbers == FloatingNumbers::Off)
if (*GetOptions().Gameplay.enableFloatingNumbers == FloatingNumbers::Off)
return;
Displacement offset = {};
@ -152,7 +152,7 @@ void AddFloatingNumber(DamageType damageType, const Monster &monster, int damage
void AddFloatingNumber(DamageType damageType, const Player &player, int damage)
{
if (*sgOptions.Gameplay.enableFloatingNumbers == FloatingNumbers::Off)
if (*GetOptions().Gameplay.enableFloatingNumbers == FloatingNumbers::Off)
return;
Displacement offset = {};
@ -171,14 +171,14 @@ void AddFloatingNumber(DamageType damageType, const Player &player, int damage)
void DrawFloatingNumbers(const Surface &out, Point viewPosition, Displacement offset)
{
if (*sgOptions.Gameplay.enableFloatingNumbers == FloatingNumbers::Off)
if (*GetOptions().Gameplay.enableFloatingNumbers == FloatingNumbers::Off)
return;
for (auto &floatingNum : FloatingQueue) {
Displacement worldOffset = viewPosition - floatingNum.startPos;
worldOffset = worldOffset.worldToScreen() + offset + Displacement { TILE_WIDTH / 2, -TILE_HEIGHT / 2 } + floatingNum.startOffset;
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
worldOffset *= 2;
}

6
Source/qol/itemlabels.cpp

@ -79,7 +79,7 @@ private:
void ToggleItemLabelHighlight()
{
sgOptions.Gameplay.showItemLabels.SetValue(!*sgOptions.Gameplay.showItemLabels);
GetOptions().Gameplay.showItemLabels.SetValue(!*GetOptions().Gameplay.showItemLabels);
}
void HighlightKeyPressed(bool pressed)
@ -99,7 +99,7 @@ void ResetItemlabelHighlighted()
bool IsHighlightingLabelsEnabled()
{
return ActiveStore == TalkID::None && highlightKeyPressed != *sgOptions.Gameplay.showItemLabels;
return ActiveStore == TalkID::None && highlightKeyPressed != *GetOptions().Gameplay.showItemLabels;
}
void AddItemToLabelQueue(int id, Point position)
@ -125,7 +125,7 @@ void AddItemToLabelQueue(int id, Point position)
position.x += *labelCenterOffsets[index];
position.y -= TILE_HEIGHT;
if (*sgOptions.Graphics.zoom) {
if (*GetOptions().Graphics.zoom) {
position *= 2;
}
position.x -= nameWidth / 2;

6
Source/qol/monhealthbar.cpp

@ -32,7 +32,7 @@ OptionalOwnedClxSpriteList playerExpTags;
void InitMonsterHealthBar()
{
if (!*sgOptions.Gameplay.enemyHealthBar)
if (!*GetOptions().Gameplay.enemyHealthBar)
return;
healthBox = LoadClx("data\\healthbox.clx");
@ -59,7 +59,7 @@ void FreeMonsterHealthBar()
void DrawMonsterHealthBar(const Surface &out)
{
if (!*sgOptions.Gameplay.enemyHealthBar)
if (!*GetOptions().Gameplay.enemyHealthBar)
return;
if (leveltype == DTYPE_TOWN)
@ -120,7 +120,7 @@ void DrawMonsterHealthBar(const Surface &out)
}
};
if (*sgOptions.Gameplay.showMonsterType) {
if (*GetOptions().Gameplay.showMonsterType) {
Uint8 borderColor = GetBorderColor(monster.data().monsterClass);
int borderWidth = width - (border * 2);
UnsafeDrawHorizontalLine(out, { position.x + border, position.y + border }, borderWidth, borderColor);

6
Source/qol/xpbar.cpp

@ -54,7 +54,7 @@ void DrawEndCap(const Surface &out, Point point, int idx, const ColorGradient &g
void InitXPBar()
{
if (*sgOptions.Gameplay.experienceBar) {
if (*GetOptions().Gameplay.experienceBar) {
xpbarArt = LoadClx("data\\xpbar.clx");
}
}
@ -66,7 +66,7 @@ void FreeXPBar()
void DrawXPBar(const Surface &out)
{
if (!*sgOptions.Gameplay.experienceBar || ChatFlag)
if (!*GetOptions().Gameplay.experienceBar || ChatFlag)
return;
const Player &player = *MyPlayer;
@ -109,7 +109,7 @@ void DrawXPBar(const Surface &out)
bool CheckXPBarInfo()
{
if (!*sgOptions.Gameplay.experienceBar)
if (!*GetOptions().Gameplay.experienceBar)
return false;
const Rectangle &mainPanel = GetMainPanel();

2
Source/quests.cpp

@ -250,7 +250,7 @@ void InitQuests()
}
}
if (!UseMultiplayerQuests() && *sgOptions.Gameplay.randomizeQuests) {
if (!UseMultiplayerQuests() && *GetOptions().Gameplay.randomizeQuests) {
// Quests are set from the seed used to generate level 15.
InitialiseQuestPools(DungeonSeeds[15], Quests);
}

10
Source/stores.cpp

@ -663,7 +663,7 @@ void StartSmithRepair()
void FillManaPlayer()
{
if (!*sgOptions.Gameplay.adriaRefillsMana)
if (!*GetOptions().Gameplay.adriaRefillsMana)
return;
Player &myPlayer = *MyPlayer;
@ -2150,7 +2150,7 @@ void SetupTownStores()
void FreeStoreMem()
{
if (*sgOptions.Gameplay.showItemGraphicsInStores) {
if (*GetOptions().Gameplay.showItemGraphicsInStores) {
FreeHalfSizeItemSprites();
}
ActiveStore = TalkID::None;
@ -2182,7 +2182,7 @@ void PrintSString(const Surface &out, int margin, int line, std::string_view tex
constexpr int CursWidth = INV_SLOT_SIZE_PX * 2;
constexpr int HalfCursWidth = CursWidth / 2;
if (*sgOptions.Gameplay.showItemGraphicsInStores && cursId >= 0) {
if (*GetOptions().Gameplay.showItemGraphicsInStores && cursId >= 0) {
const Size size = GetInvItemSize(static_cast<int>(CURSOR_FIRSTITEM) + cursId);
const bool useHalfSize = size.width > INV_SLOT_SIZE_PX || size.height > INV_SLOT_SIZE_PX;
const bool useRed = HasAnyOf(flags, UiFlags::ColorRed);
@ -2200,7 +2200,7 @@ void PrintSString(const Surface &out, int margin, int line, std::string_view tex
}
}
if (*sgOptions.Gameplay.showItemGraphicsInStores && cursIndent) {
if (*GetOptions().Gameplay.showItemGraphicsInStores && cursIndent) {
const Rectangle textRect { { rect.position.x + HalfCursWidth + 8, rect.position.y }, { rect.size.width - HalfCursWidth + 8, rect.size.height } };
DrawString(out, text, textRect, { .flags = flags });
} else {
@ -2254,7 +2254,7 @@ void ClearSText(int s, int e)
void StartStore(TalkID s)
{
if (*sgOptions.Gameplay.showItemGraphicsInStores) {
if (*GetOptions().Gameplay.showItemGraphicsInStores) {
CreateHalfSizeItemSprites();
}
SpellbookFlag = false;

2
Source/storm/storm_svid.cpp

@ -279,7 +279,7 @@ bool SVidPlayBegin(const char *filename, int flags)
auto decoder = std::make_unique<PushAulibDecoder>(audioInfo.nChannels, audioInfo.sampleRate);
SVidAudioDecoder = decoder.get();
SVidAudioStream.emplace(/*rwops=*/nullptr, std::move(decoder), CreateAulibResampler(audioInfo.sampleRate), /*closeRw=*/false);
const float volume = static_cast<float>(*sgOptions.Audio.soundVolume - VOLUME_MIN) / -VOLUME_MIN;
const float volume = static_cast<float>(*GetOptions().Audio.soundVolume - VOLUME_MIN) / -VOLUME_MIN;
SVidAudioStream->setVolume(volume);
if (!diablo_is_focused())
SVidMute();

4
Source/utils/aulib.hpp

@ -21,10 +21,10 @@ inline std::unique_ptr<Aulib::Resampler> CreateAulibResampler(int sourceRate)
{
if (Aulib::sampleRate() == sourceRate)
return nullptr;
switch (*sgOptions.Audio.resampler) {
switch (*GetOptions().Audio.resampler) {
#ifdef DEVILUTIONX_RESAMPLER_SPEEX
case Resampler::Speex:
return std::make_unique<Aulib::ResamplerSpeex>(*sgOptions.Audio.resamplingQuality);
return std::make_unique<Aulib::ResamplerSpeex>(*GetOptions().Audio.resamplingQuality);
#endif
#ifdef DVL_AULIB_SUPPORTS_SDL_RESAMPLER
case Resampler::SDL:

64
Source/utils/display.cpp

@ -90,7 +90,7 @@ void CalculatePreferredWindowSize(int &width, int &height)
std::swap(mode.w, mode.h);
}
if (*sgOptions.Graphics.integerScaling) {
if (*GetOptions().Graphics.integerScaling) {
int factor = std::min(mode.w / width, mode.h / height);
width = mode.w / factor;
height = mode.h / factor;
@ -125,7 +125,7 @@ void FreeRenderer()
#if defined(_WIN32) && !defined(NXDK) && !defined(USE_SDL1)
// On Windows 11 the directx9 VSYNC timer doesn't get recreated properly, see https://github.com/libsdl-org/SDL/issues/5099
if (wasD3D9 && *sgOptions.Graphics.upscale && *sgOptions.Graphics.frameRateControl != FrameRateControl::VerticalSync) {
if (wasD3D9 && *GetOptions().Graphics.upscale && *GetOptions().Graphics.frameRateControl != FrameRateControl::VerticalSync) {
std::string title = SDL_GetWindowTitle(ghMainWnd);
Uint32 flags = SDL_GetWindowFlags(ghMainWnd);
Rectangle dimensions;
@ -182,10 +182,10 @@ void CalculateUIRectangle()
Size GetPreferredWindowSize()
{
Size windowSize = forceResolution.width != 0 ? forceResolution : *sgOptions.Graphics.resolution;
Size windowSize = forceResolution.width != 0 ? forceResolution : *GetOptions().Graphics.resolution;
#ifndef USE_SDL1
if (*sgOptions.Graphics.upscale && *sgOptions.Graphics.fitToScreen) {
if (*GetOptions().Graphics.upscale && *GetOptions().Graphics.fitToScreen) {
CalculatePreferredWindowSize(windowSize.width, windowSize.height);
}
#endif
@ -249,7 +249,7 @@ void SetVideoModeToPrimary(bool fullscreen, int width, int height)
flags |= SDL_FULLSCREEN;
#ifdef __3DS__
flags &= ~SDL_FULLSCREEN;
flags |= Get3DSScalingFlag(*sgOptions.Graphics.fitToScreen, width, height);
flags |= Get3DSScalingFlag(*GetOptions().Graphics.fitToScreen, width, height);
#endif
SetVideoMode(width, height, SDL1_VIDEO_MODE_BPP, flags);
if (OutputRequiresScaling())
@ -273,7 +273,7 @@ bool SpawnWindow(const char *lpWindowName)
#endif
#ifdef NXDK
{
Size windowSize = forceResolution.width != 0 ? forceResolution : *sgOptions.Graphics.resolution;
Size windowSize = forceResolution.width != 0 ? forceResolution : *GetOptions().Graphics.resolution;
VIDEO_MODE xmode;
void *p = nullptr;
while (XVideoListModes(&xmode, 0, 0, &p)) {
@ -315,8 +315,8 @@ bool SpawnWindow(const char *lpWindowName)
RegisterCustomEvents();
#ifndef USE_SDL1
if (sgOptions.Controller.szMapping[0] != '\0') {
SDL_GameControllerAddMapping(sgOptions.Controller.szMapping);
if (GetOptions().Controller.szMapping[0] != '\0') {
SDL_GameControllerAddMapping(GetOptions().Controller.szMapping);
}
#endif
@ -334,18 +334,18 @@ bool SpawnWindow(const char *lpWindowName)
#ifdef USE_SDL1
SDL_WM_SetCaption(lpWindowName, WINDOW_ICON_NAME);
SetVideoModeToPrimary(*sgOptions.Graphics.fullscreen, windowSize.width, windowSize.height);
if (*sgOptions.Gameplay.grabInput)
SetVideoModeToPrimary(*GetOptions().Graphics.fullscreen, windowSize.width, windowSize.height);
if (*GetOptions().Gameplay.grabInput)
SDL_WM_GrabInput(SDL_GRAB_ON);
atexit(SDL_VideoQuit); // Without this video mode is not restored after fullscreen.
#else
int flags = SDL_WINDOW_ALLOW_HIGHDPI;
if (*sgOptions.Graphics.upscale) {
if (*sgOptions.Graphics.fullscreen) {
if (*GetOptions().Graphics.upscale) {
if (*GetOptions().Graphics.fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
flags |= SDL_WINDOW_RESIZABLE;
} else if (*sgOptions.Graphics.fullscreen) {
} else if (*GetOptions().Graphics.fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN;
}
@ -355,7 +355,7 @@ bool SpawnWindow(const char *lpWindowName)
// This is a solution to a problem related to SDL mouse grab.
// See https://github.com/diasurgical/devilutionX/issues/4251
if (ghMainWnd != nullptr)
SDL_SetWindowGrab(ghMainWnd, *sgOptions.Gameplay.grabInput ? SDL_TRUE : SDL_FALSE);
SDL_SetWindowGrab(ghMainWnd, *GetOptions().Gameplay.grabInput ? SDL_TRUE : SDL_FALSE);
#endif
if (ghMainWnd == nullptr) {
@ -386,7 +386,7 @@ void ReinitializeTexture()
if (renderer == nullptr)
return;
auto quality = StrCat(static_cast<int>(*sgOptions.Graphics.scaleQuality));
auto quality = StrCat(static_cast<int>(*GetOptions().Graphics.scaleQuality));
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, quality.c_str());
texture = SDLWrap::CreateTexture(renderer, DEVILUTIONX_DISPLAY_TEXTURE_FORMAT, SDL_TEXTUREACCESS_STREAMING, gnScreenWidth, gnScreenHeight);
@ -394,12 +394,12 @@ void ReinitializeTexture()
void ReinitializeIntegerScale()
{
if (*sgOptions.Graphics.fitToScreen) {
if (*GetOptions().Graphics.fitToScreen) {
ResizeWindow();
return;
}
if (renderer != nullptr && SDL_RenderSetIntegerScale(renderer, *sgOptions.Graphics.integerScaling ? SDL_TRUE : SDL_FALSE) < 0) {
if (renderer != nullptr && SDL_RenderSetIntegerScale(renderer, *GetOptions().Graphics.integerScaling ? SDL_TRUE : SDL_FALSE) < 0) {
ErrSdl();
}
}
@ -422,10 +422,10 @@ void ReinitializeRenderer()
FreeRenderer();
if (*sgOptions.Graphics.upscale) {
if (*GetOptions().Graphics.upscale) {
Uint32 rendererFlags = 0;
if (*sgOptions.Graphics.frameRateControl == FrameRateControl::VerticalSync) {
if (*GetOptions().Graphics.frameRateControl == FrameRateControl::VerticalSync) {
rendererFlags |= SDL_RENDERER_PRESENTVSYNC;
}
@ -436,7 +436,7 @@ void ReinitializeRenderer()
ReinitializeTexture();
if (SDL_RenderSetIntegerScale(renderer, *sgOptions.Graphics.integerScaling ? SDL_TRUE : SDL_FALSE) < 0) {
if (SDL_RenderSetIntegerScale(renderer, *GetOptions().Graphics.integerScaling ? SDL_TRUE : SDL_FALSE) < 0) {
ErrSdl();
}
@ -460,7 +460,7 @@ void SetFullscreenMode()
{
#ifdef USE_SDL1
Uint32 flags = ghMainWnd->flags ^ SDL_FULLSCREEN;
if (*sgOptions.Graphics.fullscreen) {
if (*GetOptions().Graphics.fullscreen) {
flags |= SDL_FULLSCREEN;
}
ghMainWnd = SDL_SetVideoMode(0, 0, 0, flags);
@ -471,7 +471,7 @@ void SetFullscreenMode()
// When switching from windowed to "true fullscreen",
// update the display mode of the window before changing the
// fullscreen mode so that the display mode only has to change once
if (*sgOptions.Graphics.fullscreen && !*sgOptions.Graphics.upscale) {
if (*GetOptions().Graphics.fullscreen && !*GetOptions().Graphics.upscale) {
Size windowSize = GetPreferredWindowSize();
SDL_DisplayMode displayMode = GetNearestDisplayMode(windowSize);
if (SDL_SetWindowDisplayMode(ghMainWnd, &displayMode) != 0) {
@ -480,19 +480,19 @@ void SetFullscreenMode()
}
Uint32 flags = 0;
if (*sgOptions.Graphics.fullscreen) {
flags = *sgOptions.Graphics.upscale ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN;
if (*GetOptions().Graphics.fullscreen) {
flags = *GetOptions().Graphics.upscale ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN;
}
if (SDL_SetWindowFullscreen(ghMainWnd, flags) != 0) {
ErrSdl();
}
if (!*sgOptions.Graphics.fullscreen) {
if (!*GetOptions().Graphics.fullscreen) {
SDL_RestoreWindow(ghMainWnd); // Avoid window being maximized before resizing
Size windowSize = GetPreferredWindowSize();
SDL_SetWindowSize(ghMainWnd, windowSize.width, windowSize.height);
}
if (!*sgOptions.Graphics.upscale) {
if (!*GetOptions().Graphics.upscale) {
// Because "true fullscreen" is locked into specific resolutions based on the modes
// supported by the display, the resolution may have changed when fullscreen was toggled
ReinitializeRenderer();
@ -511,10 +511,10 @@ void ResizeWindow()
Size windowSize = GetPreferredWindowSize();
#ifdef USE_SDL1
SetVideoModeToPrimary(*sgOptions.Graphics.fullscreen, windowSize.width, windowSize.height);
SetVideoModeToPrimary(*GetOptions().Graphics.fullscreen, windowSize.width, windowSize.height);
#else
// For "true fullscreen" windows, the window resizes automatically based on the display mode
bool trueFullscreen = *sgOptions.Graphics.fullscreen && !*sgOptions.Graphics.upscale;
bool trueFullscreen = *GetOptions().Graphics.fullscreen && !*GetOptions().Graphics.upscale;
if (trueFullscreen) {
SDL_DisplayMode displayMode = GetNearestDisplayMode(windowSize);
if (SDL_SetWindowDisplayMode(ghMainWnd, &displayMode) != 0)
@ -522,12 +522,12 @@ void ResizeWindow()
}
// Handle switching between "fake fullscreen" and "true fullscreen" when upscale is toggled
bool upscaleChanged = *sgOptions.Graphics.upscale != (renderer != nullptr);
if (upscaleChanged && *sgOptions.Graphics.fullscreen) {
Uint32 flags = *sgOptions.Graphics.upscale ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN;
bool upscaleChanged = *GetOptions().Graphics.upscale != (renderer != nullptr);
if (upscaleChanged && *GetOptions().Graphics.fullscreen) {
Uint32 flags = *GetOptions().Graphics.upscale ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN;
if (SDL_SetWindowFullscreen(ghMainWnd, flags) != 0)
ErrSdl();
if (!*sgOptions.Graphics.fullscreen)
if (!*GetOptions().Graphics.fullscreen)
SDL_RestoreWindow(ghMainWnd); // Avoid window being maximized before resizing
}

2
Source/utils/language.cpp

@ -335,7 +335,7 @@ std::string_view GetLanguageCode()
{
if (!forceLocale.empty())
return forceLocale;
return *sgOptions.Language.code;
return *GetOptions().Language.code;
}
void LanguageInitialize()

2
test/main.cpp

@ -11,7 +11,7 @@ int main(int argc, char **argv)
#if SDL_VERSION_ATLEAST(2, 0, 0)
// Disable hardware cursor while testing.
devilution::sgOptions.Graphics.hardwareCursor.SetValue(false);
devilution::GetOptions().Graphics.hardwareCursor.SetValue(false);
#endif
#ifdef __APPLE__

26
test/scrollrt_test.cpp

@ -15,7 +15,7 @@ TEST(Scroll_rt, calc_tiles_in_view_original)
gnScreenWidth = 640;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight - 128;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
int columns = 0;
int rows = 0;
TilesInView(&columns, &rows);
@ -28,7 +28,7 @@ TEST(Scroll_rt, calc_tiles_in_view_original_zoom)
gnScreenWidth = 640;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight - 128;
sgOptions.Graphics.zoom.SetValue(true);
GetOptions().Graphics.zoom.SetValue(true);
int columns = 0;
int rows = 0;
TilesInView(&columns, &rows);
@ -41,7 +41,7 @@ TEST(Scroll_rt, calc_tiles_in_view_960_540)
gnScreenWidth = 960;
gnScreenHeight = 540;
gnViewportHeight = gnScreenHeight;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
int columns = 0;
int rows = 0;
TilesInView(&columns, &rows);
@ -54,7 +54,7 @@ TEST(Scroll_rt, calc_tiles_in_view_640_512)
gnScreenWidth = 640;
gnScreenHeight = 512;
gnViewportHeight = gnScreenHeight - 128;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
int columns = 0;
int rows = 0;
TilesInView(&columns, &rows);
@ -67,7 +67,7 @@ TEST(Scroll_rt, calc_tiles_in_view_768_480_zoom)
gnScreenWidth = 768;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight;
sgOptions.Graphics.zoom.SetValue(true);
GetOptions().Graphics.zoom.SetValue(true);
int columns = 0;
int rows = 0;
TilesInView(&columns, &rows);
@ -82,7 +82,7 @@ TEST(Scroll_rt, calc_tile_offset_original)
gnScreenWidth = 640;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight - 128;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
int x = 0;
int y = 0;
CalcTileOffset(&x, &y);
@ -95,7 +95,7 @@ TEST(Scroll_rt, calc_tile_offset_original_zoom)
gnScreenWidth = 640;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight - 128;
sgOptions.Graphics.zoom.SetValue(true);
GetOptions().Graphics.zoom.SetValue(true);
int x = 0;
int y = 0;
CalcTileOffset(&x, &y);
@ -108,7 +108,7 @@ TEST(Scroll_rt, calc_tile_offset_960_540)
gnScreenWidth = 960;
gnScreenHeight = 540;
gnViewportHeight = gnScreenHeight;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
int x = 0;
int y = 0;
CalcTileOffset(&x, &y);
@ -121,7 +121,7 @@ TEST(Scroll_rt, calc_tile_offset_853_480)
gnScreenWidth = 853;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
int x = 0;
int y = 0;
CalcTileOffset(&x, &y);
@ -134,7 +134,7 @@ TEST(Scroll_rt, calc_tile_offset_768_480_zoom)
gnScreenWidth = 768;
gnScreenHeight = 480;
gnViewportHeight = gnScreenHeight;
sgOptions.Graphics.zoom.SetValue(true);
GetOptions().Graphics.zoom.SetValue(true);
int x = 0;
int y = 0;
CalcTileOffset(&x, &y);
@ -147,7 +147,7 @@ TEST(Scroll_rt, calc_tile_offset_768_480_zoom)
TEST(Scroll_rt, calc_tiles_covered_by_panel_original)
{
gnScreenWidth = 640;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
CalculatePanelAreas();
EXPECT_EQ(RowsCoveredByPanel(), 0);
}
@ -155,7 +155,7 @@ TEST(Scroll_rt, calc_tiles_covered_by_panel_original)
TEST(Scroll_rt, calc_tiles_covered_by_panel_960)
{
gnScreenWidth = 960;
sgOptions.Graphics.zoom.SetValue(false);
GetOptions().Graphics.zoom.SetValue(false);
CalculatePanelAreas();
EXPECT_EQ(RowsCoveredByPanel(), 4);
}
@ -163,7 +163,7 @@ TEST(Scroll_rt, calc_tiles_covered_by_panel_960)
TEST(Scroll_rt, calc_tiles_covered_by_panel_960_zoom)
{
gnScreenWidth = 960;
sgOptions.Graphics.zoom.SetValue(true);
GetOptions().Graphics.zoom.SetValue(true);
CalculatePanelAreas();
EXPECT_EQ(RowsCoveredByPanel(), 2);
}

Loading…
Cancel
Save