Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

data_file_test: Make it a standalone test #7670

Merged
merged 2 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ target_link_dependencies(libdevilutionx_assets PUBLIC
libdevilutionx_game_mode
libdevilutionx_mpq
libdevilutionx_sdl2_to_1_2_backports
libdevilutionx_sound
libdevilutionx_strings
${DEVILUTIONX_PLATFORM_ASSETS_LINK_LIBRARIES}
)
Expand Down Expand Up @@ -305,6 +304,7 @@ add_devilutionx_object_library(libdevilutionx_init
target_link_dependencies(libdevilutionx_init PUBLIC
libdevilutionx_assets
libdevilutionx_config
libdevilutionx_options
)

add_devilutionx_object_library(libdevilutionx_lighting
Expand Down Expand Up @@ -434,6 +434,7 @@ target_link_dependencies(libdevilutionx_options PUBLIC
DevilutionX::SDL
fmt::fmt
tl
unordered_dense::unordered_dense
libdevilutionx_controller_buttons
libdevilutionx_control_mode
libdevilutionx_logged_fstream
Expand Down
2 changes: 2 additions & 0 deletions Source/controls/padmapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <array>

#include "controller.h"
#include "game_controls.h"
#include "options.h"

namespace devilution {
Expand Down
131 changes: 9 additions & 122 deletions Source/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@

namespace devilution {

#ifndef DEFAULT_WIDTH
#define DEFAULT_WIDTH 640
#endif
#ifndef DEFAULT_HEIGHT
#define DEFAULT_HEIGHT 480
#endif
#ifndef DEFAULT_AUDIO_SAMPLE_RATE
#define DEFAULT_AUDIO_SAMPLE_RATE 22050
#endif
Expand Down Expand Up @@ -488,139 +482,32 @@ OptionEntryResolution::OptionEntryResolution()
}
void OptionEntryResolution::LoadFromIni(std::string_view category)
{
size = { ini->getInt(category, "Width", DEFAULT_WIDTH), ini->getInt(category, "Height", DEFAULT_HEIGHT) };
size_ = { ini->getInt(category, "Width", DEFAULT_WIDTH), ini->getInt(category, "Height", DEFAULT_HEIGHT) };
}
void OptionEntryResolution::SaveToIni(std::string_view category) const
{
ini->set(category, "Width", size.width);
ini->set(category, "Height", size.height);
}

void OptionEntryResolution::InvalidateList()
{
resolutions.clear();
}

void OptionEntryResolution::CheckResolutionsAreInitialized() const
{
if (!resolutions.empty())
return;

std::vector<Size> sizes;
float scaleFactor = GetDpiScalingFactor();

// Add resolutions
bool supportsAnyResolution = false;
#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 == (SDL_Rect **)-1) {
supportsAnyResolution = true;
} else if (modes != nullptr) {
for (size_t i = 0; modes[i] != nullptr; i++) {
if (modes[i]->w < modes[i]->h) {
std::swap(modes[i]->w, modes[i]->h);
}
sizes.emplace_back(Size {
static_cast<int>(modes[i]->w * scaleFactor),
static_cast<int>(modes[i]->h * scaleFactor) });
}
}
#else
int displayModeCount = SDL_GetNumDisplayModes(0);
for (int i = 0; i < displayModeCount; i++) {
SDL_DisplayMode mode;
if (SDL_GetDisplayMode(0, i, &mode) != 0) {
ErrSdl();
}
if (mode.w < mode.h) {
std::swap(mode.w, mode.h);
}
sizes.emplace_back(Size {
static_cast<int>(mode.w * scaleFactor),
static_cast<int>(mode.h * scaleFactor) });
}
supportsAnyResolution = *GetOptions().Graphics.upscale;
#endif

if (supportsAnyResolution && sizes.size() == 1) {
// Attempt to provide sensible options for 4:3 and the native aspect ratio
const int width = sizes[0].width;
const int height = sizes[0].height;
const int commonHeights[] = { 480, 540, 720, 960, 1080, 1440, 2160 };
for (int commonHeight : commonHeights) {
if (commonHeight > height)
break;
sizes.emplace_back(Size { commonHeight * 4 / 3, commonHeight });
if (commonHeight * width % height == 0)
sizes.emplace_back(Size { commonHeight * width / height, commonHeight });
}
}
// 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 platform's preferred default resolution is always present
sizes.emplace_back(Size { DEFAULT_WIDTH, DEFAULT_HEIGHT });
// Ensures that the vanilla Diablo resolution is present on systems that would support it
if (supportsAnyResolution)
sizes.emplace_back(Size { 640, 480 });

#ifndef USE_SDL1
if (*GetOptions().Graphics.fitToScreen) {
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(0, &mode) != 0) {
ErrSdl();
}
for (auto &size : sizes) {
// Ensure that the ini specified resolution remains present in the resolution list
if (size.height == this->size.height)
size.width = this->size.width;
else
size.width = size.height * mode.w / mode.h;
}
}
#endif

// Sort by width then by height
c_sort(sizes, [](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) {
#ifndef USE_SDL1
if (*GetOptions().Graphics.fitToScreen) {
resolutions.emplace_back(size, StrCat(size.height, "p"));
continue;
}
#endif
resolutions.emplace_back(size, StrCat(size.width, "x", size.height));
}
ini->set(category, "Width", size_.width);
ini->set(category, "Height", size_.height);
}

size_t OptionEntryResolution::GetListSize() const
{
CheckResolutionsAreInitialized();
return resolutions.size();
return resolutions_.size();
}
std::string_view OptionEntryResolution::GetListDescription(size_t index) const
{
CheckResolutionsAreInitialized();
return resolutions[index].second;
return resolutions_[index].second;
}
size_t OptionEntryResolution::GetActiveListIndex() const
{
CheckResolutionsAreInitialized();
auto found = c_find_if(resolutions, [this](const auto &x) { return x.first == this->size; });
if (found == resolutions.end())
auto found = c_find_if(resolutions_, [this](const auto &x) { return x.first == size_; });
if (found == resolutions_.end())
return 0;
return std::distance(resolutions.begin(), found);
return std::distance(resolutions_.begin(), found);
}
void OptionEntryResolution::SetActiveListIndex(size_t index)
{
size = resolutions[index].first;
size_ = resolutions_[index].first;
NotifyValueChanged();
}

Expand Down
29 changes: 20 additions & 9 deletions Source/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <forward_list>
#include <functional>
#include <initializer_list>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

#include <SDL_version.h>
#include <ankerl/unordered_dense.h>
#include <function_ref.hpp>

#include "controls/controller.h"
#include "appfat.h"
#include "controls/controller_buttons.h"
#include "controls/game_controls.h"
#include "engine/size.hpp"
#include "engine/sound_defs.hpp"
#include "pack.h"
#include "quick_messages.hpp"
Expand All @@ -22,6 +27,13 @@

namespace devilution {

#ifndef DEFAULT_WIDTH
#define DEFAULT_WIDTH 640
#endif
#ifndef DEFAULT_HEIGHT
#define DEFAULT_HEIGHT 480
#endif

enum class StartUpGameMode : uint8_t {
/** @brief If hellfire is present, asks the user what game they want to start. */
Ask = 0,
Expand Down Expand Up @@ -338,19 +350,18 @@ class OptionEntryResolution : public OptionEntryListBase {
[[nodiscard]] std::string_view GetListDescription(size_t index) const override;
[[nodiscard]] size_t GetActiveListIndex() const override;
void SetActiveListIndex(size_t index) override;
void InvalidateList();

Size operator*() const
void setAvailableResolutions(std::vector<std::pair<Size, std::string>> &&resolutions)
{
return size;
resolutions_ = std::move(resolutions);
}

Size operator*() const { return size_; }

private:
/** @brief View size. */
Size size;
mutable std::vector<std::pair<Size, std::string>> resolutions;

void CheckResolutionsAreInitialized() const;
Size size_;
std::vector<std::pair<Size, std::string>> resolutions_;
};

class OptionEntryResampler : public OptionEntryListBase {
Expand Down
113 changes: 111 additions & 2 deletions Source/utils/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <utility>

#ifdef __vita__
#include <psp2/power.h>
Expand Down Expand Up @@ -207,12 +208,115 @@ void OptionGrabInputChanged()
}
const auto OptionChangeHandlerGrabInput = (GetOptions().Gameplay.grabInput.SetValueChangedCallback(OptionGrabInputChanged), true);

void UpdateAvailableResolutions()
{
GraphicsOptions &graphicsOptions = GetOptions().Graphics;

std::vector<Size> sizes;
float scaleFactor = GetDpiScalingFactor();

// Add resolutions
bool supportsAnyResolution = false;
#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 == (SDL_Rect **)-1) {
supportsAnyResolution = true;
} else if (modes != nullptr) {
for (size_t i = 0; modes[i] != nullptr; i++) {
if (modes[i]->w < modes[i]->h) {
std::swap(modes[i]->w, modes[i]->h);
}
sizes.emplace_back(Size {
static_cast<int>(modes[i]->w * scaleFactor),
static_cast<int>(modes[i]->h * scaleFactor) });
}
}
#else
int displayModeCount = SDL_GetNumDisplayModes(0);
for (int i = 0; i < displayModeCount; i++) {
SDL_DisplayMode mode;
if (SDL_GetDisplayMode(0, i, &mode) != 0) {
ErrSdl();
}
if (mode.w < mode.h) {
std::swap(mode.w, mode.h);
}
sizes.emplace_back(Size {
static_cast<int>(mode.w * scaleFactor),
static_cast<int>(mode.h * scaleFactor) });
}
supportsAnyResolution = *GetOptions().Graphics.upscale;
#endif

if (supportsAnyResolution && sizes.size() == 1) {
// Attempt to provide sensible options for 4:3 and the native aspect ratio
const int width = sizes[0].width;
const int height = sizes[0].height;
const int commonHeights[] = { 480, 540, 720, 960, 1080, 1440, 2160 };
for (int commonHeight : commonHeights) {
if (commonHeight > height)
break;
sizes.emplace_back(Size { commonHeight * 4 / 3, commonHeight });
if (commonHeight * width % height == 0)
sizes.emplace_back(Size { commonHeight * width / height, commonHeight });
}
}

const Size configuredSize = *graphicsOptions.resolution;

// 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(configuredSize);
// Ensures that the platform's preferred default resolution is always present
sizes.emplace_back(Size { DEFAULT_WIDTH, DEFAULT_HEIGHT });
// Ensures that the vanilla Diablo resolution is present on systems that would support it
if (supportsAnyResolution)
sizes.emplace_back(Size { 640, 480 });

#ifndef USE_SDL1
if (*graphicsOptions.fitToScreen) {
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(0, &mode) != 0) {
ErrSdl();
}
for (auto &size : sizes) {
// Ensure that the ini specified resolution remains present in the resolution list
if (size.height == configuredSize.height)
size.width = configuredSize.width;
else
size.width = size.height * mode.w / mode.h;
}
}
#endif

// Sort by width then by height
c_sort(sizes, [](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());

std::vector<std::pair<Size, std::string>> resolutions;
for (auto &size : sizes) {
#ifndef USE_SDL1
if (*graphicsOptions.fitToScreen) {
resolutions.emplace_back(size, StrCat(size.height, "p"));
continue;
}
#endif
resolutions.emplace_back(size, StrCat(size.width, "x", size.height));
}
graphicsOptions.resolution.setAvailableResolutions(std::move(resolutions));
}

#if !defined(USE_SDL1) || defined(__3DS__)
void ResizeWindowAndUpdateResolutionOptions()
{
ResizeWindow();
#ifndef __3DS__
GetOptions().Graphics.resolution.InvalidateList();
UpdateAvailableResolutions();
#endif
}
const auto OptionChangeHandlerFitToScreen = (GetOptions().Graphics.fitToScreen.SetValueChangedCallback(ResizeWindowAndUpdateResolutionOptions), true);
Expand Down Expand Up @@ -405,7 +509,12 @@ bool SpawnWindow(const char *lpWindowName)

ReinitializeRenderer();

return ghMainWnd != nullptr;
if (ghMainWnd != nullptr) {
UpdateAvailableResolutions();
return true;
}

return false;
}

#ifndef USE_SDL1
Expand Down
Loading
Loading