Files
hdk-sdl/test/CoreBindings_test.cpp
T
2026-05-13 19:48:22 +00:00

135 lines
4.5 KiB
C++

#include <doctest/doctest.h>
#include <SDL3/SDL.h>
#include <hdk/sdl/Application.hpp>
#include <hdk/sdl/Log.hpp>
#include <hdk/sdl/pixels.hpp>
#include <hdk/sdl/video/Display.hpp>
#include <string>
#include "SDL_headless_fixture.hpp"
namespace {
void SDLCALL TestLogOutput(void* userdata, int category, SDL_LogPriority priority, const char* message) {
auto* callCount = static_cast<int*>(userdata);
if (callCount) {
++(*callCount);
}
(void)category;
(void)priority;
(void)message;
}
} // namespace
TEST_CASE("Core SDL bindings are exercised") {
SDLSession sdl;
if (!sdl.IsInitialized()) {
INFO(SDL_GetError());
CHECK(false);
return;
}
hdk::sdl::PublicApp app;
SDL_Event event {};
CHECK(app.Init(0, nullptr) == SDL_APP_CONTINUE);
CHECK(app.Event(&event) == SDL_APP_CONTINUE);
CHECK(app.Iterate() == SDL_APP_CONTINUE);
app.Quit(SDL_APP_SUCCESS);
int logCalls = 0;
hdk::sdl::Log::SetOutputFunction(TestLogOutput, &logCalls);
auto defaultOutput = hdk::sdl::Log::GetDefaultOutputFunction();
CHECK(defaultOutput != nullptr);
SDL_LogOutputFunction callback = nullptr;
void* userdata = nullptr;
hdk::sdl::Log::GetOutputFunction(&callback, &userdata);
CHECK(callback == TestLogOutput);
CHECK(userdata == &logCalls);
hdk::sdl::Log appLog(SDL_LOG_CATEGORY_APPLICATION);
hdk::sdl::Log::SetPriorities(SDL_LOG_PRIORITY_INFO);
appLog.SetPriority(SDL_LOG_PRIORITY_VERBOSE);
CHECK(appLog.GetPriority() >= SDL_LOG_PRIORITY_INVALID);
appLog.Critical("critical");
appLog.Debug("debug");
appLog.Error("error");
appLog.Info("info");
appLog.LogMessage(SDL_LOG_PRIORITY_WARN, "message");
appLog.Trace("trace");
appLog.Verbose("verbose");
appLog.Warn("warn");
CHECK(logCalls > 0);
hdk::sdl::Log::ResetPriorities();
hdk::sdl::PixelFormat format(SDL_PIXELFORMAT_RGBA8888);
int bpp = 0;
Uint32 rmask = 0;
Uint32 gmask = 0;
Uint32 bmask = 0;
Uint32 amask = 0;
CHECK(format.GetMasks(&bpp, &rmask, &gmask, &bmask, &amask));
CHECK(std::string(format.GetName()).find("RGBA") != std::string::npos);
CHECK(hdk::sdl::PixelFormat::GetForMasks(bpp, rmask, gmask, bmask, amask) != SDL_PIXELFORMAT_UNKNOWN);
auto details = format.GetDetails();
REQUIRE(details);
Uint32 mappedRgb = details.MapRGB(nullptr, 1, 2, 3);
Uint32 mappedRgba = details.MapRGBA(nullptr, 4, 5, 6, 7);
Uint8 r = 0;
Uint8 g = 0;
Uint8 b = 0;
Uint8 a = 0;
details.GetRGB(mappedRgb, nullptr, &r, &g, &b);
details.GetRGBA(mappedRgba, nullptr, &r, &g, &b, &a);
CHECK(a == 7);
int displayCount = 0;
SDL_DisplayID* displayIds = hdk::sdl::Display::GetDisplays(&displayCount);
if (displayIds) {
SDL_free(displayIds);
}
auto displays = hdk::sdl::Display::GetDisplays();
CHECK_FALSE(displays.empty());
auto primary = hdk::sdl::Display::GetPrimaryDisplay();
CHECK(static_cast<SDL_DisplayID>(primary) != 0);
SDL_Rect rect {};
SDL_Point point { 0, 0 };
auto pointDisplay = hdk::sdl::Display::GetForPoint(&point);
auto rectDisplay = hdk::sdl::Display::GetForRect(&rect);
CHECK((static_cast<SDL_DisplayID>(pointDisplay) != 0 || static_cast<SDL_DisplayID>(pointDisplay) == 0));
CHECK((static_cast<SDL_DisplayID>(rectDisplay) != 0 || static_cast<SDL_DisplayID>(rectDisplay) == 0));
auto window = SDL_CreateWindow("display-test", 32, 32, SDL_WINDOW_HIDDEN);
REQUIRE(window != nullptr);
auto windowDisplay = hdk::sdl::Display::GetForWindow(window);
CHECK((static_cast<SDL_DisplayID>(windowDisplay) != 0 || static_cast<SDL_DisplayID>(windowDisplay) == 0));
CHECK((primary.GetCurrentMode() != nullptr || primary.GetCurrentMode() == nullptr));
(void)primary.GetCurrentOrientation();
CHECK((primary.GetDesktopMode() != nullptr || primary.GetDesktopMode() == nullptr));
CHECK((primary.GetBounds(&rect) || !primary.GetBounds(&rect)));
(void)primary.GetContentScale();
CHECK((primary.GetName() != nullptr || primary.GetName() == nullptr));
auto properties = primary.GetProperties();
CHECK((static_cast<SDL_PropertiesID>(properties) != 0 || static_cast<SDL_PropertiesID>(properties) == 0));
CHECK((primary.GetUsableBounds(&rect) || !primary.GetUsableBounds(&rect)));
int modeCount = 0;
SDL_DisplayMode** modes = primary.GetFullscreenModes(&modeCount);
if (modes) {
SDL_free(modes);
}
auto fullscreenModes = primary.GetFullscreenModes();
CHECK(fullscreenModes.size() >= 0);
(void)primary.GetNaturalOrientation();
SDL_DisplayMode closest {};
CHECK((primary.GetClosestFullscreenMode(32, 32, 0.0f, false, &closest) ||
!primary.GetClosestFullscreenMode(32, 32, 0.0f, false, &closest)));
SDL_DestroyWindow(window);
}