Add video settings UI and refresh loading assets

This commit is contained in:
Kelsi 2026-02-05 16:11:00 -08:00
parent f725f7834f
commit 83ef27c570
9 changed files with 150 additions and 2 deletions

BIN
assets/loading1.jpeg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

BIN
assets/loading2.jpeg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

View file

@ -37,6 +37,11 @@ public:
int getHeight() const { return height; }
void setSize(int w, int h) { width = w; height = h; }
float getAspectRatio() const { return static_cast<float>(width) / height; }
bool isFullscreen() const { return fullscreen; }
bool isVsyncEnabled() const { return vsync; }
void setFullscreen(bool enable);
void setVsync(bool enable);
void applyResolution(int w, int h);
SDL_Window* getSDLWindow() const { return window; }
SDL_GLContext getGLContext() const { return glContext; }
@ -48,6 +53,10 @@ private:
int width;
int height;
int windowedWidth = 0;
int windowedHeight = 0;
bool fullscreen = false;
bool vsync = true;
bool shouldCloseFlag = false;
};

View file

@ -55,6 +55,11 @@ private:
bool showTeleporter = false;
bool showEscapeMenu = false;
bool showEscapeSettingsNotice = false;
bool showSettingsWindow = false;
bool settingsInit = false;
bool pendingFullscreen = false;
bool pendingVsync = false;
int pendingResIndex = 0;
/**
* Render player info window
@ -124,6 +129,7 @@ private:
void renderVendorWindow(game::GameHandler& gameHandler);
void renderTeleporterPanel();
void renderEscapeMenu();
void renderSettingsWindow();
/**
* Inventory screen

View file

@ -8,7 +8,11 @@ namespace core {
Window::Window(const WindowConfig& config)
: config(config)
, width(config.width)
, height(config.height) {
, height(config.height)
, windowedWidth(config.width)
, windowedHeight(config.height)
, fullscreen(config.fullscreen)
, vsync(config.vsync) {
}
Window::~Window() {
@ -68,6 +72,7 @@ bool Window::initialize() {
if (SDL_GL_SetSwapInterval(config.vsync ? 1 : 0) != 0) {
LOG_WARNING("Failed to set VSync: ", SDL_GetError());
}
vsync = config.vsync;
// Initialize GLEW
glewExperimental = GL_TRUE;
@ -133,5 +138,54 @@ void Window::pollEvents() {
}
}
void Window::setFullscreen(bool enable) {
if (!window) return;
if (enable == fullscreen) return;
if (enable) {
windowedWidth = width;
windowedHeight = height;
if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) {
LOG_WARNING("Failed to enter fullscreen: ", SDL_GetError());
return;
}
fullscreen = true;
SDL_GetWindowSize(window, &width, &height);
} else {
if (SDL_SetWindowFullscreen(window, 0) != 0) {
LOG_WARNING("Failed to exit fullscreen: ", SDL_GetError());
return;
}
fullscreen = false;
SDL_SetWindowSize(window, windowedWidth, windowedHeight);
width = windowedWidth;
height = windowedHeight;
}
glViewport(0, 0, width, height);
}
void Window::setVsync(bool enable) {
if (SDL_GL_SetSwapInterval(enable ? 1 : 0) != 0) {
LOG_WARNING("Failed to set VSync: ", SDL_GetError());
return;
}
vsync = enable;
}
void Window::applyResolution(int w, int h) {
if (!window) return;
if (w <= 0 || h <= 0) return;
if (fullscreen) {
windowedWidth = w;
windowedHeight = h;
return;
}
SDL_SetWindowSize(window, w, h);
width = w;
height = h;
windowedWidth = w;
windowedHeight = h;
glViewport(0, 0, width, height);
}
} // namespace core
} // namespace wowee

View file

@ -82,6 +82,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
renderGossipWindow(gameHandler);
renderVendorWindow(gameHandler);
renderEscapeMenu();
renderSettingsWindow();
// World map (M key toggle handled inside)
renderWorldMap(gameHandler);
@ -355,6 +356,7 @@ void GameScreen::processTargetInput(game::GameHandler& gameHandler) {
if (showEscapeMenu) {
showEscapeMenu = false;
showEscapeSettingsNotice = false;
showSettingsWindow = false;
} else if (showTeleporter) {
showTeleporter = false;
} else if (gameHandler.isCasting()) {
@ -1757,7 +1759,9 @@ void GameScreen::renderEscapeMenu() {
core::Application::getInstance().shutdown();
}
if (ImGui::Button("Settings", ImVec2(-1, 0))) {
showEscapeSettingsNotice = true;
showEscapeSettingsNotice = false;
showSettingsWindow = true;
settingsInit = false;
}
if (showEscapeSettingsNotice) {
@ -1768,4 +1772,79 @@ void GameScreen::renderEscapeMenu() {
ImGui::End();
}
// ============================================================
// Settings Window
// ============================================================
void GameScreen::renderSettingsWindow() {
if (!showSettingsWindow) return;
auto* window = core::Application::getInstance().getWindow();
if (!window) return;
static const int kResolutions[][2] = {
{1280, 720},
{1600, 900},
{1920, 1080},
{2560, 1440},
{3840, 2160},
};
static const int kResCount = sizeof(kResolutions) / sizeof(kResolutions[0]);
if (!settingsInit) {
pendingFullscreen = window->isFullscreen();
pendingVsync = window->isVsyncEnabled();
pendingResIndex = 0;
int curW = window->getWidth();
int curH = window->getHeight();
for (int i = 0; i < kResCount; i++) {
if (kResolutions[i][0] == curW && kResolutions[i][1] == curH) {
pendingResIndex = i;
break;
}
}
settingsInit = true;
}
ImGuiIO& io = ImGui::GetIO();
float screenW = io.DisplaySize.x;
float screenH = io.DisplaySize.y;
ImVec2 size(360.0f, 240.0f);
ImVec2 pos((screenW - size.x) * 0.5f, (screenH - size.y) * 0.5f);
ImGui::SetNextWindowPos(pos, ImGuiCond_Always);
ImGui::SetNextWindowSize(size, ImGuiCond_Always);
ImGuiWindowFlags flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar;
if (ImGui::Begin("##SettingsWindow", nullptr, flags)) {
ImGui::Text("Settings");
ImGui::Separator();
ImGui::Text("Video");
ImGui::Checkbox("Fullscreen", &pendingFullscreen);
ImGui::Checkbox("VSync", &pendingVsync);
const char* resLabel = "Resolution";
const char* resItems[kResCount];
char resBuf[kResCount][16];
for (int i = 0; i < kResCount; i++) {
snprintf(resBuf[i], sizeof(resBuf[i]), "%dx%d", kResolutions[i][0], kResolutions[i][1]);
resItems[i] = resBuf[i];
}
ImGui::Combo(resLabel, &pendingResIndex, resItems, kResCount);
ImGui::Spacing();
if (ImGui::Button("Apply", ImVec2(-1, 0))) {
window->setVsync(pendingVsync);
window->setFullscreen(pendingFullscreen);
window->applyResolution(kResolutions[pendingResIndex][0], kResolutions[pendingResIndex][1]);
}
if (ImGui::Button("Close", ImVec2(-1, 0))) {
showSettingsWindow = false;
}
}
ImGui::End();
}
}} // namespace wowee::ui