Browse Source

Add OptionEntry Resolution

pull/3710/head
obligaron 4 years ago committed by Anders Jenbo
parent
commit
5e2ad66e64
  1. 2
      Source/engine/demomode.cpp
  2. 91
      Source/options.cpp
  3. 30
      Source/options.h
  4. 2
      Source/utils/display.cpp

2
Source/engine/demomode.cpp

@ -144,8 +144,6 @@ void InitRecording(int recordNumber)
}
void OverrideOptions()
{
sgOptions.Graphics.nWidth = DemoGraphicsWidth;
sgOptions.Graphics.nHeight = DemoGraphicsHeight;
#ifndef USE_SDL1
sgOptions.Graphics.fitToScreen.SetValue(false);
#endif

91
Source/options.cpp

@ -299,8 +299,6 @@ void LoadOptions()
sgOptions.Audio.nBufferSize = GetIniInt("Audio", "Buffer Size", DEFAULT_AUDIO_BUFFER_SIZE);
sgOptions.Audio.nResamplingQuality = GetIniInt("Audio", "Resampling Quality", DEFAULT_AUDIO_RESAMPLING_QUALITY);
sgOptions.Graphics.nWidth = GetIniInt("Graphics", "Width", DEFAULT_WIDTH);
sgOptions.Graphics.nHeight = GetIniInt("Graphics", "Height", DEFAULT_HEIGHT);
sgOptions.Graphics.nGammaCorrection = GetIniInt("Graphics", "Gamma Correction", 100);
#if SDL_VERSION_ATLEAST(2, 0, 0)
sgOptions.Graphics.bHardwareCursor = GetIniBool("Graphics", "Hardware Cursor", HardwareCursorDefault());
@ -354,8 +352,6 @@ void SaveOptions()
SetIniValue("Audio", "Channels", sgOptions.Audio.nChannels);
SetIniValue("Audio", "Buffer Size", sgOptions.Audio.nBufferSize);
SetIniValue("Audio", "Resampling Quality", sgOptions.Audio.nResamplingQuality);
SetIniValue("Graphics", "Width", sgOptions.Graphics.nWidth);
SetIniValue("Graphics", "Height", sgOptions.Graphics.nHeight);
SetIniValue("Graphics", "Gamma Correction", sgOptions.Graphics.nGammaCorrection);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SetIniValue("Graphics", "Hardware Cursor", sgOptions.Graphics.bHardwareCursor);
@ -572,6 +568,91 @@ std::vector<OptionEntryBase *> AudioOptions::GetEntries()
};
}
OptionEntryResolution::OptionEntryResolution()
: OptionEntryListBase("", OptionEntryFlags::CantChangeInGame | OptionEntryFlags::RecreateUI, N_("Resolution"), N_("Affect the game's internal resolution and determine your view area. Note: This can differ from screen resolution, when Upscaling, Integer Scaling or Fit to Screen is used."))
{
}
void OptionEntryResolution::LoadFromIni(string_view category)
{
size = { GetIniInt(category.data(), "Width", DEFAULT_WIDTH), GetIniInt(category.data(), "Height", DEFAULT_HEIGHT) };
}
void OptionEntryResolution::SaveToIni(string_view category) const
{
SetIniValue(category.data(), "Width", size.width);
SetIniValue(category.data(), "Height", size.height);
}
void OptionEntryResolution::CheckResolutionsAreInitialized() const
{
if (!resolutions.empty())
return;
std::vector<Size> sizes;
// Add resolutions
#ifdef USE_SDL1
auto *modes = SDL_ListModes(nullptr, SDL_FULLSCREEN | SDL_HWPALETTE);
// SDL_ListModes returns -1 if any resolution is allowed (for example returned on 3DS)
if (modes != nullptr && modes != (SDL_Rect **)-1) {
for (size_t i = 0; modes[i] != nullptr; i++) {
sizes.emplace_back(Size { modes[i]->w, modes[i]->h });
}
}
#else
int displayModeCount = SDL_GetNumDisplayModes(0);
for (int i = 0; i < displayModeCount; i++) {
SDL_DisplayMode mode;
if (SDL_GetDisplayMode(0, i, &mode) != 0) {
ErrSdl();
}
sizes.emplace_back(Size { mode.w, mode.h });
}
#endif
// Ensures that the ini specified resolution is present in resolution list even if it doesn't match a monitor resolution (for example if played in window mode)
sizes.push_back(this->size);
// Ensures that the vanilla/default resolution is always present
sizes.emplace_back(Size { DEFAULT_WIDTH, DEFAULT_HEIGHT });
// Sort by width then by height
std::sort(sizes.begin(), sizes.end(),
[](const Size &x, const Size &y) -> bool {
if (x.width == y.width)
return x.height > y.height;
return x.width > y.width;
});
// Remove duplicate entries
sizes.erase(std::unique(sizes.begin(), sizes.end()), sizes.end());
for (auto &size : sizes) {
resolutions.emplace_back(size, fmt::format("{}x{}", size.width, size.height));
}
}
size_t OptionEntryResolution::GetListSize() const
{
CheckResolutionsAreInitialized();
return resolutions.size();
}
string_view OptionEntryResolution::GetListDescription(size_t index) const
{
CheckResolutionsAreInitialized();
return resolutions[index].second;
}
size_t OptionEntryResolution::GetActiveListIndex() const
{
CheckResolutionsAreInitialized();
auto found = std::find_if(resolutions.begin(), resolutions.end(), [this](const auto &x) { return x.first == this->size; });
if (found == resolutions.end())
return 0;
return std::distance(resolutions.begin(), found);
}
void OptionEntryResolution::SetActiveListIndex(size_t index)
{
size = resolutions[index].first;
NotifyValueChanged();
}
GraphicsOptions::GraphicsOptions()
: OptionCategoryBase("Graphics", N_("Graphics"), N_("Graphics Settings"))
, fullscreen("Fullscreen", OptionEntryFlags::CantChangeInGame | OptionEntryFlags::RecreateUI, N_("Fullscreen"), N_("Display the game in windowed or fullscreen mode."), true)
@ -594,6 +675,7 @@ GraphicsOptions::GraphicsOptions()
, limitFPS("FPS Limiter", OptionEntryFlags::None, N_("FPS Limiter"), N_("FPS is limited to avoid high CPU load. Limit considers refresh rate."), true)
, showFPS("Show FPS", OptionEntryFlags::None, N_("Show FPS"), N_("Displays the FPS in the upper left corner of the screen."), true)
{
resolution.SetValueChangedCallback(ResizeWindow);
fullscreen.SetValueChangedCallback(ResizeWindow);
#if !defined(USE_SDL1) || defined(__3DS__)
fitToScreen.SetValueChangedCallback(ResizeWindow);
@ -610,6 +692,7 @@ std::vector<OptionEntryBase *> GraphicsOptions::GetEntries()
{
// clang-format off
return {
&resolution,
#ifndef __vita__
&fullscreen,
#endif

30
Source/options.h

@ -216,6 +216,31 @@ private:
void CheckLanguagesAreInitialized() const;
};
class OptionEntryResolution : public OptionEntryListBase {
public:
OptionEntryResolution();
void LoadFromIni(string_view category) override;
void SaveToIni(string_view category) const override;
[[nodiscard]] size_t GetListSize() const override;
[[nodiscard]] string_view GetListDescription(size_t index) const override;
[[nodiscard]] size_t GetActiveListIndex() const override;
void SetActiveListIndex(size_t index) override;
Size operator*() const
{
return size;
}
private:
/** @brief View size. */
Size size;
mutable std::vector<std::pair<Size, std::string>> resolutions;
void CheckResolutionsAreInitialized() const;
};
struct OptionCategoryBase {
OptionCategoryBase(string_view key, string_view name, string_view description);
@ -295,10 +320,7 @@ struct GraphicsOptions : OptionCategoryBase {
GraphicsOptions();
std::vector<OptionEntryBase *> GetEntries() override;
/** @brief Render width. */
int nWidth;
/** @brief Render height. */
int nHeight;
OptionEntryResolution resolution;
/** @brief Run in fullscreen or windowed mode. */
OptionEntryBoolean fullscreen;
#if !defined(USE_SDL1) || defined(__3DS__)

2
Source/utils/display.cpp

@ -100,7 +100,7 @@ void AdjustToScreenGeometry(Size windowSize)
Size GetPreferredWindowSize()
{
Size windowSize = { sgOptions.Graphics.nWidth, sgOptions.Graphics.nHeight };
Size windowSize = *sgOptions.Graphics.resolution;
#ifndef USE_SDL1
if (*sgOptions.Graphics.upscale && *sgOptions.Graphics.fitToScreen) {

Loading…
Cancel
Save