mirror of
https://github.com/diasurgical/DevilutionX.git
synced 2026-10-12 02:13:06 +00:00
SDL3: Make text_render_integration_test build
Adds support for just enough SDL3 to make `text_render_integration_test` work.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
name: Linux x64 SDL3 Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- 'docs/**'
|
||||
pull_request:
|
||||
types: [ opened, synchronize ]
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- 'docs/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y cmake curl g++ git libgtest-dev libgmock-dev libbenchmark-dev libfmt-dev libsodium-dev libpng-dev libbz2-dev wget
|
||||
|
||||
- name: Cache CMake build folder
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: build
|
||||
key: ${{ github.workflow }}-v2-${{ github.sha }}
|
||||
restore-keys: ${{ github.workflow }}-v2-
|
||||
|
||||
# We specify `-DDEVILUTIONX_SYSTEM_BENCHMARK=OFF` to work around the following error:
|
||||
# lto1: fatal error: bytecode stream in file ‘/usr/lib/x86_64-linux-gnu/libbenchmark_main.a’ generated with LTO version 11.2 instead of the expected 11.3
|
||||
- name: Build tests
|
||||
run: |
|
||||
cmake -S. -Bbuild -G Ninja -DUSE_SDL3=ON -DDEVILUTIONX_SYSTEM_SDL3=OFF -DDEVILUTIONX_STATIC_SDL3=ON -DDEVILUTIONX_SYSTEM_SDL_IMAGE=OFF -DNOSOUND=ON -DDEVILUTIONX_SYSTEM_BENCHMARK=OFF
|
||||
wget -qnc https://github.com/diasurgical/devilutionx-assets/releases/download/v2/spawn.mpq -P build
|
||||
cmake --build build -j $(nproc) --target text_render_integration_test
|
||||
|
||||
- name: Run tests
|
||||
run: cd build && ctest -R 'TextRenderIntegrationTest' --output-on-failure
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
- name: Build tests
|
||||
run: |
|
||||
cmake -S. -Bbuild -DENABLE_CODECOVERAGE=ON -DDEVILUTIONX_SYSTEM_BENCHMARK=OFF
|
||||
wget -nc https://github.com/diasurgical/devilutionx-assets/releases/download/v2/spawn.mpq -P build
|
||||
wget -qnc https://github.com/diasurgical/devilutionx-assets/releases/download/v2/spawn.mpq -P build
|
||||
cmake --build build -j $(nproc)
|
||||
|
||||
- name: Run tests
|
||||
|
||||
Vendored
+1
@@ -25,6 +25,7 @@ else()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif()
|
||||
|
||||
set(SDLIMAGE_BACKEND_STB OFF)
|
||||
set(SDLIMAGE_AVIF OFF)
|
||||
set(SDLIMAGE_BMP OFF)
|
||||
set(SDLIMAGE_GIF OFF)
|
||||
|
||||
+12
-1
@@ -6,12 +6,18 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_thread.h>
|
||||
#include <SDL3/SDL_timer.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "diablo.h"
|
||||
#include "multi.h"
|
||||
@@ -27,8 +33,13 @@ namespace {
|
||||
|
||||
/** Set to true when a fatal error is encountered and the application should shut down. */
|
||||
bool Terminating = false;
|
||||
|
||||
/** Thread id of the last callee to FreeDlg(). */
|
||||
#ifdef USE_SDL3
|
||||
SDL_ThreadID CleanupThreadId;
|
||||
#else
|
||||
SDL_threadID CleanupThreadId;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Cleans up after a fatal application error.
|
||||
|
||||
@@ -7,6 +7,17 @@
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -7,11 +7,16 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include "monstdat.h"
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <pkware.h>
|
||||
|
||||
#include "encrypt.h"
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "appfat.h"
|
||||
#include "game_mode.hpp"
|
||||
#include "utils/file_util.h"
|
||||
@@ -45,16 +52,25 @@ char *FindUnpackedMpqFile(char *relativePath)
|
||||
#else
|
||||
bool IsDebugLogging()
|
||||
{
|
||||
return SDL_LogGetPriority(SDL_LOG_CATEGORY_APPLICATION) <= SDL_LOG_PRIORITY_DEBUG;
|
||||
return IsLogLevel(LogCategory::Application, SDL_LOG_PRIORITY_DEBUG);
|
||||
}
|
||||
|
||||
SDL_RWops *OpenOptionalRWops(const std::string &path)
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
OpenOptionalRWops(const std::string &path)
|
||||
{
|
||||
// SDL always logs an error in Debug mode.
|
||||
// We check the file presence in Debug mode to avoid this.
|
||||
if (IsDebugLogging() && !FileExists(path.c_str()))
|
||||
return nullptr;
|
||||
#ifdef USE_SDL3
|
||||
return SDL_IOFromFile(path.c_str(), "rb");
|
||||
#else
|
||||
return SDL_RWFromFile(path.c_str(), "rb");
|
||||
#endif
|
||||
};
|
||||
|
||||
bool FindMpqFile(std::string_view filename, MpqArchive **archive, uint32_t *fileNumber)
|
||||
@@ -128,7 +144,12 @@ AssetRef FindAsset(std::string_view filename)
|
||||
#endif
|
||||
|
||||
if (relativePath[0] == '/') {
|
||||
result.directHandle = SDL_RWFromFile(relativePath.c_str(), "rb");
|
||||
result.directHandle =
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOFromFile(relativePath.c_str(), "rb");
|
||||
#else
|
||||
SDL_RWFromFile(relativePath.c_str(), "rb");
|
||||
#endif
|
||||
if (result.directHandle != nullptr) {
|
||||
return result;
|
||||
}
|
||||
@@ -161,7 +182,12 @@ AssetRef FindAsset(std::string_view filename)
|
||||
// Fall back to the bundled assets on supported systems.
|
||||
// This is handled by SDL when we pass a relative path.
|
||||
if (!paths::AssetsPath().empty()) {
|
||||
result.directHandle = SDL_RWFromFile(relativePath.c_str(), "rb");
|
||||
result.directHandle =
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOFromFile(relativePath.c_str(), "rb");
|
||||
#else
|
||||
SDL_RWFromFile(relativePath.c_str(), "rb");
|
||||
#endif
|
||||
if (result.directHandle != nullptr)
|
||||
return result;
|
||||
}
|
||||
@@ -180,7 +206,7 @@ AssetHandle OpenAsset(AssetRef &&ref, bool threadsafe)
|
||||
return AssetHandle { SDL_RWops_FromMpqFile(*ref.archive, ref.fileNumber, ref.filename, threadsafe) };
|
||||
if (ref.directHandle != nullptr) {
|
||||
// Transfer handle ownership:
|
||||
SDL_RWops *handle = ref.directHandle;
|
||||
auto *handle = ref.directHandle;
|
||||
ref.directHandle = nullptr;
|
||||
return AssetHandle { handle };
|
||||
}
|
||||
@@ -205,13 +231,22 @@ AssetHandle OpenAsset(std::string_view filename, size_t &fileSize, bool threadsa
|
||||
return OpenAsset(std::move(ref), threadsafe);
|
||||
}
|
||||
|
||||
SDL_RWops *OpenAssetAsSdlRwOps(std::string_view filename, bool threadsafe)
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
OpenAssetAsSdlRwOps(std::string_view filename, bool threadsafe)
|
||||
{
|
||||
#ifdef UNPACKED_MPQS
|
||||
AssetRef ref = FindAsset(filename);
|
||||
if (!ref.ok())
|
||||
return nullptr;
|
||||
#ifdef USE_SDL3
|
||||
return SDL_IOFromFile(ref.path, "rb");
|
||||
#else
|
||||
return SDL_RWFromFile(ref.path, "rb");
|
||||
#endif
|
||||
#else
|
||||
return OpenAsset(filename, threadsafe).release();
|
||||
#endif
|
||||
@@ -361,7 +396,7 @@ std::vector<std::string> GetMPQSearchPaths()
|
||||
paths.emplace_back(); // PWD
|
||||
}
|
||||
|
||||
if (SDL_LOG_PRIORITY_VERBOSE >= SDL_LogGetPriority(SDL_LOG_CATEGORY_APPLICATION)) {
|
||||
if (IsLogLevel(LogCategory::Application, SDL_LOG_PRIORITY_VERBOSE)) {
|
||||
LogVerbose("Paths:\n base: {}\n pref: {}\n config: {}\n assets: {}",
|
||||
paths::BasePath(), paths::PrefPath(), paths::ConfigPath(), paths::AssetsPath());
|
||||
|
||||
|
||||
+76
-12
@@ -9,7 +9,13 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include <fmt/format.h>
|
||||
@@ -114,8 +120,13 @@ struct AssetRef {
|
||||
uint32_t fileNumber;
|
||||
std::string_view filename;
|
||||
|
||||
#ifdef USE_SDL3
|
||||
// Alternatively, a direct SDL_IOStream handle:
|
||||
SDL_IOStream *directHandle = nullptr;
|
||||
#else
|
||||
// Alternatively, a direct SDL_RWops handle:
|
||||
SDL_RWops *directHandle = nullptr;
|
||||
#endif
|
||||
|
||||
AssetRef() = default;
|
||||
|
||||
@@ -130,8 +141,7 @@ struct AssetRef {
|
||||
|
||||
AssetRef &operator=(AssetRef &&other) noexcept
|
||||
{
|
||||
if (directHandle != nullptr)
|
||||
SDL_RWclose(directHandle);
|
||||
closeDirectHandle();
|
||||
archive = other.archive;
|
||||
fileNumber = other.fileNumber;
|
||||
filename = other.filename;
|
||||
@@ -142,8 +152,7 @@ struct AssetRef {
|
||||
|
||||
~AssetRef()
|
||||
{
|
||||
if (directHandle != nullptr)
|
||||
SDL_RWclose(directHandle);
|
||||
closeDirectHandle();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool ok() const
|
||||
@@ -163,16 +172,42 @@ struct AssetRef {
|
||||
int32_t error;
|
||||
return archive->GetUnpackedFileSize(fileNumber, error);
|
||||
}
|
||||
#ifdef USE_SDL3
|
||||
return static_cast<size_t>(SDL_GetIOSize(directHandle));
|
||||
#else
|
||||
return static_cast<size_t>(SDL_RWsize(directHandle));
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
void closeDirectHandle()
|
||||
{
|
||||
if (directHandle != nullptr) {
|
||||
#ifdef USE_SDL3
|
||||
SDL_CloseIO(directHandle);
|
||||
#else
|
||||
SDL_RWclose(directHandle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct AssetHandle {
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *handle = nullptr;
|
||||
#else
|
||||
SDL_RWops *handle = nullptr;
|
||||
#endif
|
||||
|
||||
AssetHandle() = default;
|
||||
|
||||
explicit AssetHandle(SDL_RWops *handle)
|
||||
explicit AssetHandle(
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
handle)
|
||||
: handle(handle)
|
||||
{
|
||||
}
|
||||
@@ -185,9 +220,7 @@ struct AssetHandle {
|
||||
|
||||
AssetHandle &operator=(AssetHandle &&other) noexcept
|
||||
{
|
||||
if (handle != nullptr) {
|
||||
SDL_RWclose(handle);
|
||||
}
|
||||
closeHandle();
|
||||
handle = other.handle;
|
||||
other.handle = nullptr;
|
||||
return *this;
|
||||
@@ -195,8 +228,7 @@ struct AssetHandle {
|
||||
|
||||
~AssetHandle()
|
||||
{
|
||||
if (handle != nullptr)
|
||||
SDL_RWclose(handle);
|
||||
closeHandle();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool ok() const
|
||||
@@ -206,7 +238,9 @@ struct AssetHandle {
|
||||
|
||||
bool read(void *buffer, size_t len)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#ifdef USE_SDL3
|
||||
return SDL_ReadIO(handle, buffer, len) == len;
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
return handle->read(handle, buffer, len, 1) == 1;
|
||||
#else
|
||||
return handle->read(handle, buffer, static_cast<int>(len), 1) == 1;
|
||||
@@ -215,7 +249,11 @@ struct AssetHandle {
|
||||
|
||||
bool seek(long pos)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDL_SeekIO(handle, pos, SDL_IO_SEEK_SET) != -1;
|
||||
#else
|
||||
return handle->seek(handle, pos, RW_SEEK_SET) != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard]] const char *error() const
|
||||
@@ -223,12 +261,33 @@ struct AssetHandle {
|
||||
return SDL_GetError();
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *release() &&
|
||||
{
|
||||
SDL_IOStream *result = handle;
|
||||
handle = nullptr;
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
SDL_RWops *release() &&
|
||||
{
|
||||
SDL_RWops *result = handle;
|
||||
handle = nullptr;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void closeHandle()
|
||||
{
|
||||
if (handle != nullptr) {
|
||||
#ifdef USE_SDL3
|
||||
SDL_CloseIO(handle);
|
||||
#else
|
||||
SDL_RWclose(handle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -265,7 +324,12 @@ AssetHandle OpenAsset(AssetRef &&ref, bool threadsafe = false);
|
||||
AssetHandle OpenAsset(std::string_view filename, bool threadsafe = false);
|
||||
AssetHandle OpenAsset(std::string_view filename, size_t &fileSize, bool threadsafe = false);
|
||||
|
||||
SDL_RWops *OpenAssetAsSdlRwOps(std::string_view filename, bool threadsafe = false);
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
OpenAssetAsSdlRwOps(std::string_view filename, bool threadsafe = false);
|
||||
|
||||
struct AssetData {
|
||||
std::unique_ptr<char[]> data;
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "mpq/mpq_common.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "engine/clx_sprite.hpp"
|
||||
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
#include <cstring>
|
||||
#include <span>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "engine/backbuffer_state.hpp"
|
||||
#include "engine/demomode.h"
|
||||
#include "engine/dx.h"
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "levels/gendung_defs.hpp"
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_version.h>
|
||||
#else
|
||||
#include <SDL_version.h>
|
||||
#endif
|
||||
|
||||
#define VOLUME_MIN -1600
|
||||
#define VOLUME_MAX 0
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_rect.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#else
|
||||
#include <SDL_version.h>
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
@@ -12,6 +16,7 @@
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#include <SDL_video.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "engine/point.hpp"
|
||||
#include "utils/sdl_geometry.h"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_timer.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
namespace devilution {
|
||||
|
||||
|
||||
@@ -8,7 +8,13 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_version.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "control.h"
|
||||
|
||||
@@ -7,7 +7,12 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_version.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "utils/ui_fwd.h"
|
||||
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
namespace devilution {
|
||||
|
||||
namespace {
|
||||
@@ -26,6 +32,9 @@ struct Data {
|
||||
std::unique_ptr<uint8_t[]> blockData;
|
||||
};
|
||||
|
||||
#ifdef USE_SDL3
|
||||
Data *GetData(void *userdata) { return reinterpret_cast<Data *>(userdata); }
|
||||
#else
|
||||
Data *GetData(struct SDL_RWops *context)
|
||||
{
|
||||
return reinterpret_cast<Data *>(context->hidden.unknown.data1);
|
||||
@@ -35,6 +44,7 @@ void SetData(struct SDL_RWops *context, Data *data)
|
||||
{
|
||||
context->hidden.unknown.data1 = data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL1
|
||||
using OffsetType = Sint64;
|
||||
@@ -47,24 +57,46 @@ using SizeType = int;
|
||||
extern "C" {
|
||||
|
||||
#ifndef USE_SDL1
|
||||
static Sint64 MpqFileRwSize(struct SDL_RWops *context)
|
||||
static Sint64 MpqFileRwSize(
|
||||
#ifdef USE_SDL3
|
||||
void *
|
||||
#else
|
||||
struct SDL_RWops *
|
||||
#endif
|
||||
context)
|
||||
{
|
||||
return GetData(context)->size;
|
||||
return static_cast<Sint64>(GetData(context)->size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL3
|
||||
static Sint64 MpqFileRwSeek(void *context, Sint64 offset, SDL_IOWhence whence)
|
||||
#else
|
||||
static OffsetType MpqFileRwSeek(struct SDL_RWops *context, OffsetType offset, int whence)
|
||||
#endif
|
||||
{
|
||||
Data &data = *GetData(context);
|
||||
OffsetType newPosition;
|
||||
switch (whence) {
|
||||
#ifdef USE_SDL3
|
||||
case SDL_IO_SEEK_SET:
|
||||
#else
|
||||
case RW_SEEK_SET:
|
||||
#endif
|
||||
newPosition = offset;
|
||||
break;
|
||||
#ifdef USE_SDL3
|
||||
case SDL_IO_SEEK_CUR:
|
||||
#else
|
||||
case RW_SEEK_CUR:
|
||||
#endif
|
||||
newPosition = static_cast<OffsetType>(data.position + offset);
|
||||
break;
|
||||
#ifdef USE_SDL3
|
||||
case SDL_IO_SEEK_END:
|
||||
#else
|
||||
case RW_SEEK_END:
|
||||
#endif
|
||||
newPosition = static_cast<OffsetType>(data.size + offset);
|
||||
break;
|
||||
default:
|
||||
@@ -92,8 +124,15 @@ static OffsetType MpqFileRwSeek(struct SDL_RWops *context, OffsetType offset, in
|
||||
return newPosition;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
static SizeType MpqFileRwRead(void *context, void *ptr, size_t size, SDL_IOStatus *status)
|
||||
#else
|
||||
static SizeType MpqFileRwRead(struct SDL_RWops *context, void *ptr, SizeType size, SizeType maxnum)
|
||||
#endif
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
const size_t maxnum = 1;
|
||||
#endif
|
||||
Data &data = *GetData(context);
|
||||
const size_t totalSize = size * maxnum;
|
||||
size_t remainingSize = totalSize;
|
||||
@@ -104,9 +143,12 @@ static SizeType MpqFileRwRead(struct SDL_RWops *context, void *ptr, SizeType siz
|
||||
data.blockData = std::unique_ptr<uint8_t[]> { new uint8_t[data.blockSize] };
|
||||
}
|
||||
|
||||
uint32_t blockNumber = static_cast<uint32_t>(data.position / data.blockSize);
|
||||
auto blockNumber = static_cast<uint32_t>(data.position / data.blockSize);
|
||||
while (remainingSize > 0) {
|
||||
if (data.position == data.size) {
|
||||
#ifdef USE_SDL3
|
||||
*status = SDL_IO_STATUS_EOF;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -121,13 +163,17 @@ static SizeType MpqFileRwRead(struct SDL_RWops *context, void *ptr, SizeType siz
|
||||
data.blockRead = true;
|
||||
}
|
||||
|
||||
const size_t blockPosition = data.position - blockNumber * data.blockSize;
|
||||
const size_t blockPosition = data.position - (blockNumber * data.blockSize);
|
||||
const size_t remainingBlockSize = currentBlockSize - blockPosition;
|
||||
|
||||
if (remainingSize < remainingBlockSize) {
|
||||
std::memcpy(out, data.blockData.get() + blockPosition, remainingSize);
|
||||
data.position += remainingSize;
|
||||
#ifdef USE_SDL3
|
||||
return size;
|
||||
#else
|
||||
return maxnum;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::memcpy(out, data.blockData.get() + blockPosition, remainingBlockSize);
|
||||
@@ -138,30 +184,55 @@ static SizeType MpqFileRwRead(struct SDL_RWops *context, void *ptr, SizeType siz
|
||||
data.blockRead = false;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
return static_cast<SizeType>(totalSize - remainingSize);
|
||||
#else
|
||||
return static_cast<SizeType>((totalSize - remainingSize) / size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
static bool MpqFileRwClose(void *context)
|
||||
#else
|
||||
static int MpqFileRwClose(struct SDL_RWops *context)
|
||||
#endif
|
||||
{
|
||||
Data *data = GetData(context);
|
||||
data->mpqArchive->CloseBlockOffsetTable(data->fileNumber);
|
||||
delete data;
|
||||
#ifdef USE_SDL3
|
||||
return true;
|
||||
#else
|
||||
delete context;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
} // namespace
|
||||
|
||||
SDL_RWops *SDL_RWops_FromMpqFile(MpqArchive &mpqArchive, uint32_t fileNumber, std::string_view filename, bool threadsafe)
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
SDL_RWops_FromMpqFile(MpqArchive &mpqArchive, uint32_t fileNumber, std::string_view filename, bool threadsafe)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStreamInterface interface;
|
||||
SDL_INIT_INTERFACE(&interface);
|
||||
SDL_IOStreamInterface *result = &interface;
|
||||
#else
|
||||
auto result = std::make_unique<SDL_RWops>();
|
||||
std::memset(result.get(), 0, sizeof(*result));
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL1
|
||||
result->size = &MpqFileRwSize;
|
||||
#ifndef USE_SDL3
|
||||
result->type = SDL_RWOPS_UNKNOWN;
|
||||
#endif
|
||||
#else
|
||||
result->type = 0;
|
||||
#endif
|
||||
@@ -170,6 +241,9 @@ SDL_RWops *SDL_RWops_FromMpqFile(MpqArchive &mpqArchive, uint32_t fileNumber, st
|
||||
result->read = &MpqFileRwRead;
|
||||
result->write = nullptr;
|
||||
result->close = &MpqFileRwClose;
|
||||
#ifdef USE_SDL3
|
||||
result->flush = nullptr;
|
||||
#endif
|
||||
|
||||
auto data = std::make_unique<Data>();
|
||||
int32_t error = 0;
|
||||
@@ -226,8 +300,12 @@ SDL_RWops *SDL_RWops_FromMpqFile(MpqArchive &mpqArchive, uint32_t fileNumber, st
|
||||
data->position = 0;
|
||||
data->blockRead = false;
|
||||
|
||||
#ifdef USE_SDL3
|
||||
return SDL_OpenIO(&interface, data.release());
|
||||
#else
|
||||
SetData(result.get(), data.release());
|
||||
return result.release();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -3,12 +3,21 @@
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "mpq/mpq_reader.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
SDL_RWops *SDL_RWops_FromMpqFile(MpqArchive &mpqArchive, uint32_t fileNumber, std::string_view filename, bool threadsafe);
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
SDL_RWops_FromMpqFile(MpqArchive &mpqArchive, uint32_t fileNumber, std::string_view filename, bool threadsafe);
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
+12
-12
@@ -6,11 +6,11 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include <SDL_endian.h>
|
||||
#include <libmpq/mpq.h>
|
||||
|
||||
#include "appfat.h"
|
||||
#include "encrypt.h"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/file_util.h"
|
||||
#include "utils/language.h"
|
||||
#include "utils/log.hpp"
|
||||
@@ -63,15 +63,15 @@ constexpr uint32_t MinBlockSize = 1024;
|
||||
|
||||
void ByteSwapHdr(MpqFileHeader *hdr)
|
||||
{
|
||||
hdr->signature = SDL_SwapLE32(hdr->signature);
|
||||
hdr->headerSize = SDL_SwapLE32(hdr->headerSize);
|
||||
hdr->fileSize = SDL_SwapLE32(hdr->fileSize);
|
||||
hdr->version = SDL_SwapLE16(hdr->version);
|
||||
hdr->blockSizeFactor = SDL_SwapLE16(hdr->blockSizeFactor);
|
||||
hdr->hashEntriesOffset = SDL_SwapLE32(hdr->hashEntriesOffset);
|
||||
hdr->blockEntriesOffset = SDL_SwapLE32(hdr->blockEntriesOffset);
|
||||
hdr->hashEntriesCount = SDL_SwapLE32(hdr->hashEntriesCount);
|
||||
hdr->blockEntriesCount = SDL_SwapLE32(hdr->blockEntriesCount);
|
||||
hdr->signature = Swap32LE(hdr->signature);
|
||||
hdr->headerSize = Swap32LE(hdr->headerSize);
|
||||
hdr->fileSize = Swap32LE(hdr->fileSize);
|
||||
hdr->version = Swap16LE(hdr->version);
|
||||
hdr->blockSizeFactor = Swap16LE(hdr->blockSizeFactor);
|
||||
hdr->hashEntriesOffset = Swap32LE(hdr->hashEntriesOffset);
|
||||
hdr->blockEntriesOffset = Swap32LE(hdr->blockEntriesOffset);
|
||||
hdr->hashEntriesCount = Swap32LE(hdr->hashEntriesCount);
|
||||
hdr->blockEntriesCount = Swap32LE(hdr->blockEntriesCount);
|
||||
}
|
||||
|
||||
bool IsAllocatedUnusedBlock(const MpqBlockEntry *block)
|
||||
@@ -421,7 +421,7 @@ bool MpqWriter::WriteFileContents(const std::byte *fileData, uint32_t fileSize,
|
||||
len = PkwareCompress(mpqBuf, len);
|
||||
if (!stream_.Write(reinterpret_cast<const char *>(&mpqBuf[0]), len))
|
||||
return false;
|
||||
offsetTable[curSector++] = SDL_SwapLE32(destSize);
|
||||
offsetTable[curSector++] = Swap32LE(destSize);
|
||||
destSize += len; // compressed length
|
||||
if (fileSize <= BlockSize)
|
||||
break;
|
||||
@@ -429,7 +429,7 @@ bool MpqWriter::WriteFileContents(const std::byte *fileData, uint32_t fileSize,
|
||||
fileSize -= BlockSize;
|
||||
}
|
||||
|
||||
offsetTable[numSectors] = SDL_SwapLE32(destSize);
|
||||
offsetTable[numSectors] = Swap32LE(destSize);
|
||||
if (!stream_.Seekp(block->offset, SEEK_SET))
|
||||
return false;
|
||||
if (!stream_.Write(reinterpret_cast<const char *>(offsetTable.get()), offsetTableByteSize))
|
||||
|
||||
+57
-11
@@ -17,7 +17,15 @@
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_version.h>
|
||||
#else
|
||||
#include <SDL_version.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <function_ref.hpp>
|
||||
@@ -36,6 +44,7 @@
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/logged_fstream.hpp"
|
||||
#include "utils/paths.h"
|
||||
#include "utils/sdl_ptrs.h"
|
||||
#include "utils/str_cat.hpp"
|
||||
#include "utils/str_split.hpp"
|
||||
#include "utils/utf8.hpp"
|
||||
@@ -198,6 +207,8 @@ bool HardwareCursorSupported()
|
||||
{
|
||||
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) || __DJGPP__
|
||||
return false;
|
||||
#elif USE_SDL3
|
||||
return true;
|
||||
#else
|
||||
SDL_version v;
|
||||
SDL_GetVersion(&v);
|
||||
@@ -645,7 +656,11 @@ void OptionEntryAudioDevice::SaveToIni(std::string_view category) const
|
||||
|
||||
size_t OptionEntryAudioDevice::GetListSize() const
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
#if defined(USE_SDL3)
|
||||
int numDevices = 0;
|
||||
SDLUniquePtr<SDL_AudioDeviceID> devices { SDL_GetAudioPlaybackDevices(&numDevices) };
|
||||
return static_cast<size_t>(numDevices) + 1;
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
return SDL_GetNumAudioDevices(false) + 1;
|
||||
#else
|
||||
return 1;
|
||||
@@ -661,12 +676,22 @@ std::string_view OptionEntryAudioDevice::GetListDescription(size_t index) const
|
||||
|
||||
size_t OptionEntryAudioDevice::GetActiveListIndex() const
|
||||
{
|
||||
for (size_t i = 0; i < GetListSize(); i++) {
|
||||
const std::string_view deviceName = GetDeviceName(i);
|
||||
if (deviceName == deviceName_)
|
||||
return i;
|
||||
#ifdef USE_SDL3
|
||||
int numDevices;
|
||||
SDLUniquePtr<SDL_AudioDeviceID> devices { SDL_GetAudioPlaybackDevices(&numDevices) };
|
||||
if (devices == nullptr) return 0;
|
||||
for (int i = 0; i < numDevices; ++i) {
|
||||
const char *deviceName = SDL_GetAudioDeviceName(devices.get()[i]);
|
||||
if (deviceName_ == deviceName) return i;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
for (size_t i = 0; i < GetListSize(); i++) {
|
||||
const std::string_view deviceName = GetDeviceName(i);
|
||||
if (deviceName_ == deviceName) return i;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OptionEntryAudioDevice::SetActiveListIndex(size_t index)
|
||||
@@ -677,11 +702,18 @@ void OptionEntryAudioDevice::SetActiveListIndex(size_t index)
|
||||
|
||||
std::string_view OptionEntryAudioDevice::GetDeviceName(size_t index) const
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (index != 0)
|
||||
return SDL_GetAudioDeviceName(static_cast<int>(index) - 1, false);
|
||||
if (index == 0) return {}; // System Default
|
||||
#if defined(USE_SDL3)
|
||||
int numDevices = 0;
|
||||
SDLUniquePtr<SDL_AudioDeviceID> devices { SDL_GetAudioPlaybackDevices(&numDevices) };
|
||||
if (devices == nullptr || static_cast<int>(index) > numDevices) return "Unknown";
|
||||
const char *deviceName = SDL_GetAudioDeviceName(devices.get()[index - 1]);
|
||||
if (deviceName == nullptr) return "Unknown";
|
||||
return deviceName;
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
return SDL_GetAudioDeviceName(static_cast<int>(index) - 1, false);
|
||||
#endif
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
GraphicsOptions::GraphicsOptions()
|
||||
@@ -1078,12 +1110,26 @@ KeymapperOptions::KeymapperOptions()
|
||||
keyIDToKeyName.emplace(MouseScrollLeftButton, "SCROLLLEFTMOUSE");
|
||||
keyIDToKeyName.emplace(MouseScrollRightButton, "SCROLLRIGHTMOUSE");
|
||||
|
||||
keyIDToKeyName.emplace(SDLK_BACKQUOTE, "`");
|
||||
keyIDToKeyName.emplace(
|
||||
#ifdef USE_SDL3
|
||||
SDLK_GRAVE
|
||||
#else
|
||||
SDLK_BACKQUOTE
|
||||
#endif
|
||||
,
|
||||
"`");
|
||||
keyIDToKeyName.emplace(SDLK_LEFTBRACKET, "[");
|
||||
keyIDToKeyName.emplace(SDLK_RIGHTBRACKET, "]");
|
||||
keyIDToKeyName.emplace(SDLK_BACKSLASH, "\\");
|
||||
keyIDToKeyName.emplace(SDLK_SEMICOLON, ";");
|
||||
keyIDToKeyName.emplace(SDLK_QUOTE, "'");
|
||||
keyIDToKeyName.emplace(
|
||||
#ifdef USE_SDL3
|
||||
SDLK_APOSTROPHE
|
||||
#else
|
||||
SDLK_QUOTE
|
||||
#endif
|
||||
,
|
||||
"'");
|
||||
keyIDToKeyName.emplace(SDLK_COMMA, ",");
|
||||
keyIDToKeyName.emplace(SDLK_PERIOD, ".");
|
||||
keyIDToKeyName.emplace(SDLK_SLASH, "/");
|
||||
|
||||
@@ -12,7 +12,12 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_version.h>
|
||||
#else
|
||||
#include <SDL_version.h>
|
||||
#endif
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
|
||||
@@ -52,21 +52,21 @@ SDL_Window *ghMainWnd;
|
||||
|
||||
Size forceResolution;
|
||||
|
||||
Uint16 gnScreenWidth;
|
||||
Uint16 gnScreenHeight;
|
||||
Uint16 gnViewportHeight;
|
||||
uint16_t gnScreenWidth;
|
||||
uint16_t gnScreenHeight;
|
||||
uint16_t gnViewportHeight;
|
||||
|
||||
Uint16 GetScreenWidth()
|
||||
uint16_t GetScreenWidth()
|
||||
{
|
||||
return gnScreenWidth;
|
||||
}
|
||||
|
||||
Uint16 GetScreenHeight()
|
||||
uint16_t GetScreenHeight()
|
||||
{
|
||||
return gnScreenHeight;
|
||||
}
|
||||
|
||||
Uint16 GetViewportHeight()
|
||||
uint16_t GetViewportHeight()
|
||||
{
|
||||
return gnViewportHeight;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_endian.h>
|
||||
#else
|
||||
#include <SDL_endian.h>
|
||||
#endif
|
||||
|
||||
namespace devilution {
|
||||
|
||||
constexpr uint16_t Swap16LE(uint16_t val)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDL_Swap16LE(val);
|
||||
#else
|
||||
return SDL_SwapLE16(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr uint32_t Swap32LE(uint32_t val)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDL_Swap32LE(val);
|
||||
#else
|
||||
return SDL_SwapLE32(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace devilution
|
||||
@@ -3,19 +3,19 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include <SDL_endian.h>
|
||||
#include "utils/endian_swap.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
inline void WriteLE16(void *out, uint16_t val)
|
||||
{
|
||||
const uint16_t littleEndian = SDL_SwapLE16(val);
|
||||
const uint16_t littleEndian = Swap16LE(val);
|
||||
memcpy(out, &littleEndian, 2);
|
||||
}
|
||||
|
||||
inline void WriteLE32(void *out, uint32_t val)
|
||||
{
|
||||
const uint32_t littleEndian = SDL_SwapLE32(val);
|
||||
const uint32_t littleEndian = Swap32LE(val);
|
||||
memcpy(out, &littleEndian, 4);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/stdcompat/filesystem.hpp"
|
||||
@@ -112,10 +116,14 @@ bool FileExists(const char *path)
|
||||
#elif defined(DVL_HAS_FILESYSTEM)
|
||||
std::error_code ec;
|
||||
return std::filesystem::exists(reinterpret_cast<const char8_t *>(path), ec);
|
||||
#elif USE_SDL3
|
||||
SDL_IOStream *file = SDL_IOFromFile(path, "rb");
|
||||
if (file == nullptr) return false;
|
||||
SDL_CloseIO(file);
|
||||
return true;
|
||||
#else
|
||||
SDL_RWops *file = SDL_RWFromFile(path, "r+b");
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
SDL_RWops *file = SDL_RWFromFile(path, "rb");
|
||||
if (file == nullptr) return false;
|
||||
SDL_RWclose(file);
|
||||
return true;
|
||||
#endif
|
||||
@@ -176,12 +184,18 @@ bool FileExistsAndIsWriteable(const char *path)
|
||||
#else
|
||||
if (!FileExists(path))
|
||||
return false;
|
||||
SDL_RWops *file = SDL_RWFromFile(path, "a+b");
|
||||
if (file == nullptr)
|
||||
return false;
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *file = SDL_IOFromFile(path, "ab");
|
||||
if (file == nullptr) return false;
|
||||
SDL_CloseIO(file);
|
||||
return true;
|
||||
#else
|
||||
SDL_RWops *file = SDL_RWFromFile(path, "ab");
|
||||
if (file == nullptr) return false;
|
||||
SDL_RWclose(file);
|
||||
return true;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GetFileSize(const char *path, std::uintmax_t *size)
|
||||
|
||||
+16
-2
@@ -2,7 +2,12 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_log.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ranges.h>
|
||||
@@ -85,10 +90,19 @@ inline void LogVerbose(LogCategory category, std::string_view str)
|
||||
SDL_LogVerbose(static_cast<int>(category), "%.*s", static_cast<int>(str.size()), str.data());
|
||||
}
|
||||
|
||||
inline bool IsLogLevel(LogCategory category, SDL_LogPriority priority)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDL_GetLogPriority(static_cast<int>(category)) <= priority;
|
||||
#else
|
||||
return SDL_LogGetPriority(static_cast<int>(category)) <= priority;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void LogVerbose(LogCategory category, std::string_view fmt, Args &&...args)
|
||||
{
|
||||
if (SDL_LogGetPriority(static_cast<int>(category)) > SDL_LOG_PRIORITY_VERBOSE) return;
|
||||
if (!IsLogLevel(category, SDL_LOG_PRIORITY_VERBOSE)) return;
|
||||
auto str = detail::format(fmt, std::forward<Args>(args)...);
|
||||
SDL_LogVerbose(static_cast<int>(category), "%s", str.c_str());
|
||||
}
|
||||
@@ -107,7 +121,7 @@ inline void LogDebug(LogCategory category, std::string_view str)
|
||||
template <typename... Args>
|
||||
void LogDebug(LogCategory category, std::string_view fmt, Args &&...args)
|
||||
{
|
||||
if (SDL_LogGetPriority(static_cast<int>(category)) > SDL_LOG_PRIORITY_DEBUG) return;
|
||||
if (!IsLogLevel(category, SDL_LOG_PRIORITY_DEBUG)) return;
|
||||
auto str = detail::format(fmt, std::forward<Args>(args)...);
|
||||
SDL_LogDebug(static_cast<int>(category), "%s", str.c_str());
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "utils/palette_kd_tree.hpp"
|
||||
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
namespace devilution {
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#elif defined(USE_SDL1)
|
||||
#include <SDL_video.h>
|
||||
#else
|
||||
#include <SDL_pixels.h>
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#elif defined(USE_SDL1)
|
||||
#include <SDL_video.h>
|
||||
#else
|
||||
#include <SDL_pixels.h>
|
||||
|
||||
+27
-7
@@ -4,7 +4,12 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "appfat.h"
|
||||
#include "utils/file_util.h"
|
||||
@@ -67,16 +72,31 @@ const std::string &NxdkGetPrefPath()
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string GetSdlBasePath()
|
||||
{
|
||||
std::string result;
|
||||
#if defined(__DJGPP__)
|
||||
// In DOS, use an empty base path.
|
||||
#elif defined(USE_SDL3)
|
||||
const char *s = SDL_GetBasePath();
|
||||
if (s == nullptr) {
|
||||
LogError("{}", SDL_GetError());
|
||||
SDL_ClearError();
|
||||
} else {
|
||||
result = s;
|
||||
}
|
||||
#else
|
||||
result = FromSDL(SDL_GetBasePath());
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const std::string &BasePath()
|
||||
{
|
||||
if (!basePath) {
|
||||
#if defined(__DJGPP__)
|
||||
basePath = std::string();
|
||||
#else
|
||||
basePath = FromSDL(SDL_GetBasePath());
|
||||
#endif
|
||||
basePath = GetSdlBasePath();
|
||||
}
|
||||
return *basePath;
|
||||
}
|
||||
@@ -148,9 +168,9 @@ const std::string &AssetsPath()
|
||||
//
|
||||
// Note that SDL3 reverts to SDL1 behaviour!
|
||||
// https://github.com/libsdl-org/SDL/blob/962268ca21ed10b9cee31198c22681099293f20a/docs/README-migration.md?plain=1#L1623
|
||||
assetsPath.emplace(FromSDL(SDL_GetBasePath()));
|
||||
assetsPath.emplace(GetSdlBasePath());
|
||||
#else
|
||||
assetsPath.emplace(FromSDL(SDL_GetBasePath()) + ("assets" DIRECTORY_SEPARATOR_STR));
|
||||
assetsPath.emplace(GetSdlBasePath() + ("assets" DIRECTORY_SEPARATOR_STR));
|
||||
#endif
|
||||
}
|
||||
return *assetsPath;
|
||||
|
||||
@@ -9,11 +9,16 @@
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL_endian.h>
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "appfat.h"
|
||||
#include "utils/clx_encode.hpp"
|
||||
#include "utils/endian_read.hpp"
|
||||
#include "utils/endian_swap.hpp"
|
||||
#include "utils/endian_write.hpp"
|
||||
#include "utils/pcx.hpp"
|
||||
|
||||
@@ -47,8 +52,8 @@ bool LoadPcxMeta(AssetHandle &handle, int &width, int &height, uint8_t &bpp)
|
||||
if (!handle.read(&pcxhdr, PcxHeaderSize)) {
|
||||
return false;
|
||||
}
|
||||
width = SDL_SwapLE16(pcxhdr.Xmax) - SDL_SwapLE16(pcxhdr.Xmin) + 1;
|
||||
height = SDL_SwapLE16(pcxhdr.Ymax) - SDL_SwapLE16(pcxhdr.Ymin) + 1;
|
||||
width = Swap16LE(pcxhdr.Xmax) - Swap16LE(pcxhdr.Xmin) + 1;
|
||||
height = Swap16LE(pcxhdr.Ymax) - Swap16LE(pcxhdr.Ymin) + 1;
|
||||
bpp = pcxhdr.BitsPerPixel;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "engine/assets.hpp"
|
||||
#include "engine/clx_sprite.hpp"
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_rect.h>
|
||||
#else
|
||||
#include <SDL_version.h>
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
@@ -11,6 +14,7 @@
|
||||
#else
|
||||
#include <SDL_video.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "engine/rectangle.hpp"
|
||||
|
||||
|
||||
+21
-2
@@ -6,12 +6,21 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_mouse.h>
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#include <SDL3/SDL_render.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#include <SDL3/SDL_version.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#else
|
||||
#include "utils/sdl2_backports.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace devilution {
|
||||
|
||||
@@ -21,7 +30,11 @@ namespace devilution {
|
||||
struct SDLSurfaceDeleter {
|
||||
void operator()(SDL_Surface *surface) const
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_DestroySurface(surface);
|
||||
#else
|
||||
SDL_FreeSurface(surface);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,14 +44,16 @@ using SDLSurfaceUniquePtr = std::unique_ptr<SDL_Surface, SDLSurfaceDeleter>;
|
||||
struct SDLCursorDeleter {
|
||||
void operator()(SDL_Cursor *cursor) const
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_DestroyCursor(cursor);
|
||||
#else
|
||||
SDL_FreeCursor(cursor);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
using SDLCursorUniquePtr = std::unique_ptr<SDL_Cursor, SDLCursorDeleter>;
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL1
|
||||
struct SDLTextureDeleter {
|
||||
void operator()(SDL_Texture *texture) const
|
||||
{
|
||||
@@ -52,7 +67,11 @@ using SDLTextureUniquePtr = std::unique_ptr<SDL_Texture, SDLTextureDeleter>;
|
||||
struct SDLPaletteDeleter {
|
||||
void operator()(SDL_Palette *palette) const
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_DestroyPalette(palette);
|
||||
#else
|
||||
SDL_FreePalette(palette);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_thread.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "appfat.h"
|
||||
#include "utils/attributes.h"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
namespace this_sdl_thread {
|
||||
#ifdef USE_SDL3
|
||||
inline SDL_ThreadID get_id()
|
||||
#else
|
||||
inline SDL_threadID get_id()
|
||||
#endif
|
||||
{
|
||||
#if defined(__DJGPP__)
|
||||
return 1;
|
||||
@@ -39,7 +48,12 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
SDL_ThreadID get_id() const
|
||||
#else
|
||||
SDL_threadID get_id() const
|
||||
#endif
|
||||
{
|
||||
return this_sdl_thread::get_id();
|
||||
}
|
||||
@@ -79,7 +93,11 @@ public:
|
||||
return thread != nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
SDL_ThreadID get_id() const
|
||||
#else
|
||||
SDL_threadID get_id() const
|
||||
#endif
|
||||
{
|
||||
return SDL_GetThreadID(thread.get());
|
||||
}
|
||||
|
||||
+118
-72
@@ -1,72 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#else
|
||||
#include "utils/sdl2_backports.h"
|
||||
#endif
|
||||
|
||||
#include "appfat.h"
|
||||
#include "utils/sdl_ptrs.h"
|
||||
|
||||
#define NonNull(x) NullErrDlg(x, __FILE__, __LINE__)
|
||||
|
||||
namespace devilution {
|
||||
|
||||
namespace SDLWrap {
|
||||
|
||||
template <typename T>
|
||||
T NullErrDlg(T x, const char *file, int line)
|
||||
{
|
||||
if (x == nullptr)
|
||||
ErrDlg("SDL Error", SDL_GetError(), file, line);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask)) };
|
||||
}
|
||||
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format)) };
|
||||
}
|
||||
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateRGBSurfaceWithFormatFrom(pixels, width, height, depth, pitch, format)) };
|
||||
}
|
||||
|
||||
#ifndef USE_SDL1
|
||||
inline SDLSurfaceUniquePtr ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, Uint32 flags)
|
||||
#else
|
||||
inline SDLSurfaceUniquePtr ConvertSurface(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags)
|
||||
#endif
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_ConvertSurface(src, fmt, flags)) };
|
||||
}
|
||||
|
||||
#ifndef USE_SDL1
|
||||
inline SDLSurfaceUniquePtr ConvertSurfaceFormat(SDL_Surface *src, Uint32 pixel_format, Uint32 flags)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_ConvertSurfaceFormat(src, pixel_format, flags)) };
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL1
|
||||
inline SDLTextureUniquePtr CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h)
|
||||
{
|
||||
return SDLTextureUniquePtr { NonNull(SDL_CreateTexture(renderer, format, access, w, h)) };
|
||||
}
|
||||
#endif
|
||||
|
||||
inline SDLPaletteUniquePtr AllocPalette(int ncolors = 256)
|
||||
{
|
||||
return SDLPaletteUniquePtr { NonNull(SDL_AllocPalette(ncolors)) };
|
||||
}
|
||||
|
||||
} // namespace SDLWrap
|
||||
|
||||
} // namespace devilution
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_error.h>
|
||||
#include <SDL3/SDL_pixels.h>
|
||||
#include <SDL3/SDL_render.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#ifdef USE_SDL1
|
||||
#include "utils/sdl2_to_1_2_backports.h"
|
||||
#else
|
||||
#include "utils/sdl2_backports.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "appfat.h"
|
||||
#include "utils/sdl_ptrs.h"
|
||||
|
||||
#define NonNull(x) NullErrDlg(x, __FILE__, __LINE__)
|
||||
|
||||
namespace devilution {
|
||||
|
||||
namespace SDLWrap {
|
||||
|
||||
template <typename T>
|
||||
T NullErrDlg(T x, const char *file, int line)
|
||||
{
|
||||
if (x == nullptr)
|
||||
ErrDlg("SDL Error", SDL_GetError(), file, line);
|
||||
return x;
|
||||
}
|
||||
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateSurface(width, height, SDL_GetPixelFormatForMasks(depth, Rmask, Gmask, Bmask, Amask))) };
|
||||
#else
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask)) };
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SDL3
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, SDL_PixelFormat format)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateSurface(width, height, format)) };
|
||||
}
|
||||
#else
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format)) };
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL3
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, SDL_PixelFormat format)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateSurfaceFrom(width, height, format, pixels, pitch)) };
|
||||
}
|
||||
#else
|
||||
inline SDLSurfaceUniquePtr CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_CreateRGBSurfaceWithFormatFrom(pixels, width, height, depth, pitch, format)) };
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL1
|
||||
inline SDLSurfaceUniquePtr ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, Uint32 flags)
|
||||
#else
|
||||
inline SDLSurfaceUniquePtr ConvertSurface(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags)
|
||||
#endif
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_ConvertSurface(src, *fmt)) };
|
||||
#else
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_ConvertSurface(src, fmt, flags)) };
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef USE_SDL1
|
||||
#ifdef USE_SDL3
|
||||
inline SDLSurfaceUniquePtr ConvertSurfaceFormat(SDL_Surface *src, SDL_PixelFormat format, Uint32 flags)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_ConvertSurface(src, format)) };
|
||||
}
|
||||
#else
|
||||
inline SDLSurfaceUniquePtr ConvertSurfaceFormat(SDL_Surface *src, Uint32 format, Uint32 flags)
|
||||
{
|
||||
return SDLSurfaceUniquePtr { NonNull(SDL_ConvertSurfaceFormat(src, format, flags)) };
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL3
|
||||
inline SDLTextureUniquePtr CreateTexture(SDL_Renderer *renderer, SDL_PixelFormat format, SDL_TextureAccess access, int w, int h)
|
||||
{
|
||||
return SDLTextureUniquePtr { NonNull(SDL_CreateTexture(renderer, format, access, w, h)) };
|
||||
}
|
||||
#else
|
||||
inline SDLTextureUniquePtr CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h)
|
||||
{
|
||||
return SDLTextureUniquePtr { NonNull(SDL_CreateTexture(renderer, format, access, w, h)) };
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline SDLPaletteUniquePtr AllocPalette(int ncolors = 256)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
return SDLPaletteUniquePtr { NonNull(SDL_CreatePalette(ncolors)) };
|
||||
#else
|
||||
return SDLPaletteUniquePtr { NonNull(SDL_AllocPalette(ncolors)) };
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace SDLWrap
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -1,21 +1,39 @@
|
||||
#include "utils/surface_to_png.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#include <SDL3_image/SDL_image.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/surface.hpp"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
#ifndef USE_SDL3
|
||||
extern "C" int IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);
|
||||
#endif
|
||||
|
||||
tl::expected<void, std::string>
|
||||
WriteSurfaceToFilePng(const Surface &buf, SDL_RWops *dst)
|
||||
WriteSurfaceToFilePng(const Surface &buf,
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
dst)
|
||||
{
|
||||
if (IMG_SavePNG_RW(buf.surface, dst, /*freedst=*/1) != 0) {
|
||||
#ifdef USE_SDL3
|
||||
const bool ok = IMG_SavePNG_IO(buf.surface, dst, /*closeio=*/true);
|
||||
#else
|
||||
const bool ok = IMG_SavePNG_RW(buf.surface, dst, /*freedst=*/1) == 0;
|
||||
#endif
|
||||
if (!ok) {
|
||||
tl::expected<void, std::string> result = tl::make_unexpected(std::string(SDL_GetError()));
|
||||
SDL_ClearError();
|
||||
return result;
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
|
||||
#include "engine/surface.hpp"
|
||||
@@ -14,6 +20,12 @@ namespace devilution {
|
||||
* Takes ownership of `dst` and closes it when done.
|
||||
*/
|
||||
tl::expected<void, std::string>
|
||||
WriteSurfaceToFilePng(const Surface &buf, SDL_RWops *dst);
|
||||
WriteSurfaceToFilePng(const Surface &buf,
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *
|
||||
#else
|
||||
SDL_RWops *
|
||||
#endif
|
||||
dst);
|
||||
|
||||
} // namespace devilution
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#include <cstdint>
|
||||
|
||||
#include "engine/rectangle.hpp"
|
||||
#include "utils/attributes.h"
|
||||
|
||||
namespace devilution {
|
||||
|
||||
extern DVL_API_FOR_TEST Uint16 gnScreenWidth;
|
||||
extern DVL_API_FOR_TEST Uint16 gnScreenHeight;
|
||||
extern DVL_API_FOR_TEST Uint16 gnViewportHeight;
|
||||
extern DVL_API_FOR_TEST uint16_t gnScreenWidth;
|
||||
extern DVL_API_FOR_TEST uint16_t gnScreenHeight;
|
||||
extern DVL_API_FOR_TEST uint16_t gnViewportHeight;
|
||||
|
||||
Uint16 GetScreenWidth();
|
||||
Uint16 GetScreenHeight();
|
||||
Uint16 GetViewportHeight();
|
||||
uint16_t GetScreenWidth();
|
||||
uint16_t GetScreenHeight();
|
||||
uint16_t GetViewportHeight();
|
||||
|
||||
/** @brief Returns the UI (Menus, Messages, Help) can use. Currently this is 640x480 like vanilla. */
|
||||
const Rectangle &GetUIRectangle();
|
||||
|
||||
@@ -8,7 +8,13 @@
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
#ifdef USE_SDL3
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#include <SDL3/SDL_surface.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include <expected.hpp>
|
||||
#include <function_ref.hpp>
|
||||
|
||||
@@ -223,13 +229,28 @@ SDLPaletteUniquePtr LoadPalette()
|
||||
|
||||
std::vector<std::byte> ReadFile(const std::string &path)
|
||||
{
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *rwops = SDL_IOFromFile(path.c_str(), "rb");
|
||||
#else
|
||||
SDL_RWops *rwops = SDL_RWFromFile(path.c_str(), "rb");
|
||||
#endif
|
||||
std::vector<std::byte> result;
|
||||
if (rwops == nullptr) return result;
|
||||
const size_t size = static_cast<size_t>(SDL_RWsize(rwops));
|
||||
const size_t size = static_cast<size_t>(
|
||||
#ifdef USE_SDL3
|
||||
SDL_GetIOSize(rwops)
|
||||
#else
|
||||
SDL_RWsize(rwops)
|
||||
#endif
|
||||
);
|
||||
result.resize(size);
|
||||
#ifdef USE_SDL3
|
||||
SDL_ReadIO(rwops, result.data(), size);
|
||||
SDL_CloseIO(rwops);
|
||||
#else
|
||||
SDL_RWread(rwops, result.data(), size, 1);
|
||||
SDL_RWclose(rwops);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -294,9 +315,15 @@ TEST_P(TextRenderIntegrationTest, RenderAndCompareTest)
|
||||
|
||||
const std::string actualPath = StrCat(paths::BasePath(), FixturesPath, GetParam().name, "-Actual.png");
|
||||
const std::string expectedPath = StrCat(paths::BasePath(), FixturesPath, GetParam().name, ".png");
|
||||
#ifdef USE_SDL3
|
||||
SDL_IOStream *actual = SDL_IOFromFile(actualPath.c_str(), "wb");
|
||||
#else
|
||||
SDL_RWops *actual = SDL_RWFromFile(actualPath.c_str(), "wb");
|
||||
#endif
|
||||
ASSERT_NE(actual, nullptr) << SDL_GetError();
|
||||
ASSERT_TRUE(WriteSurfaceToFilePng(out, actual).has_value());
|
||||
|
||||
const tl::expected<void, std::string> result = WriteSurfaceToFilePng(out, actual);
|
||||
ASSERT_TRUE(result.has_value()) << result.error();
|
||||
|
||||
EXPECT_THAT(actualPath, FileContentsEq(expectedPath));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user