[SettingsMenuState] Now using sliders for some settings.

This commit is contained in:
Quentin Bazin 2020-07-08 11:59:25 +02:00
parent e3dc327b71
commit 18d0fa8cb1
13 changed files with 285 additions and 109 deletions

View File

@ -1,34 +0,0 @@
-- You can copy this file as 'config/client.lua' to load automatically those settings at client startup
-- Here the default values are set, you can remove options or change them accordingly
-- See source/client/core/Config.cpp for more details
-- Gameplay
isFlyModeEnabled = false
isNoClipEnabled = false
-- Interface
isBlockInfoWidgetEnabled = true
isFpsCounterEnabled = true
isHotbarVisible = true
isCrosshairVisible = true
-- Graphics
renderDistance = 8
isSmoothLightingEnabled = true
isAmbientOcclusionEnabled = false
isWireframeModeEnabled = false
isFullscreenModeEnabled = false
isVerticalSyncEnabled = true
cameraFOV = 70.0
screenWidth = 1600
screenHeight = 1050
guiScale = 3
mipmapLevels = 0
aoStrength = 1
-- Input
mouseSensitivity = 8
-- Other
username = ""

View File

@ -1,6 +0,0 @@
-- You can copy this file as 'config/server.lua' to load automatically those settings at server startup
-- Here the default values are set, you can remove options or change them accordingly
-- See source/server/core/ServerConfig.cpp for more details
maxPlayers = 5

View File

@ -59,7 +59,6 @@ u16 Config::screenWidth = 1600;
u16 Config::screenHeight = 1050;
u8 Config::guiScale = 3;
u8 Config::mipmapLevels = 3;
float Config::aoStrength = 1.0f;
// Input
u8 Config::mouseSensitivity = 8;
@ -99,7 +98,6 @@ void Config::loadConfigFromFile(const char *filename) {
screenHeight = lua["screenHeight"].get_or(screenHeight);
guiScale = lua["guiScale"].get_or(guiScale);
mipmapLevels = lua["mipmapLevels"].get_or(mipmapLevels);
aoStrength = lua["aoStrength"].get_or(aoStrength);
mouseSensitivity = lua["mouseSensitivity"].get_or(mouseSensitivity);
@ -135,7 +133,6 @@ void Config::saveConfigToFile(const char *filename) {
file << "screenHeight = " << screenHeight << std::endl;
file << "guiScale = " << (u16)guiScale << std::endl;
file << "mipmapLevels = " << (u16)mipmapLevels << std::endl;
file << "aoStrength = " << aoStrength << std::endl;
file << std::endl;
file << "mouseSensitivity = " << (u16)mouseSensitivity << std::endl;
file << std::endl;

View File

@ -54,7 +54,6 @@ namespace Config {
extern u16 screenHeight;
extern u8 guiScale;
extern u8 mipmapLevels;
extern float aoStrength;
// Input
extern u8 mouseSensitivity;

View File

@ -37,21 +37,26 @@ void MenuWidget::reset(u16 width, u16 height) {
m_height = height;
m_buttons.clear();
m_buttons.reserve(m_width * m_height);
m_sliders.clear();
Widget::m_width = 0;
Widget::m_height = 0;
}
void MenuWidget::onEvent(const SDL_Event &event) {
for (std::size_t i = 0 ; i < m_buttons.size() ; ++i) {
m_buttons.at(i).onEvent(event);
for (auto &it : m_buttons) {
it.first.onEvent(event);
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
int x = i % m_width;
int y = i / m_width;
updateWidgetPosition(it.first, it.second.x, it.second.y);
}
}
updateButtonPosition(m_buttons.at(i), x, y);
for (auto &it : m_sliders) {
it.first.onEvent(event);
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
updateWidgetPosition(it.first, it.second.x, it.second.y);
}
}
}
@ -59,54 +64,78 @@ void MenuWidget::onEvent(const SDL_Event &event) {
void MenuWidget::onGuiScaleChanged(const GuiScaleChangedEvent &event) {
setScale(event.guiScale, event.guiScale, 1);
for (std::size_t i = 0 ; i < m_buttons.size() ; ++i) {
int x = i % m_width;
int y = i / m_width;
for (auto &it : m_buttons) {
updateWidgetPosition(it.first, it.second.x, it.second.y);
}
updateButtonPosition(m_buttons.at(i), x, y);
for (auto &it : m_sliders) {
updateWidgetPosition(it.first, it.second.x, it.second.y);
}
}
TextButton &MenuWidget::addButton(const std::string &text, const TextButton::CppCallback &callback, u16 width) {
int x = m_buttons.size() % m_width;
int y = m_buttons.size() / m_width;
int x = (m_buttons.size() + m_sliders.size()) % m_width;
int y = (m_buttons.size() + m_sliders.size()) / m_width;
m_buttons.emplace_back(width, this);
m_buttons.emplace_back(std::piecewise_construct,
std::forward_as_tuple(width, this), std::forward_as_tuple(x, y));
TextButton &button = m_buttons.back();
TextButton &button = m_buttons.back().first;
button.setText(text);
button.setCallback(callback);
updateButtonPosition(button, x, y);
updateWidgetPosition(button, x, y);
return button;
}
void MenuWidget::setButtonEnabled(const std::string &text, bool isEnabled) {
for (auto &it : m_buttons) {
if (it.text() == text)
it.setEnabled(isEnabled);
if (it.first.text() == text)
it.first.setEnabled(isEnabled);
}
}
void MenuWidget::updateButtonPosition(TextButton &button, int x, int y) {
button.setPosition(x * (button.width() + m_horizontalSpacing),
y * (button.height() + m_verticalSpacing));
SliderWidget &MenuWidget::addSlider(const std::string &text, const SliderWidget::CppCallback &callback, int min, int max, int initialValue) {
int x = (m_buttons.size() + m_sliders.size()) % m_width;
int y = (m_buttons.size() + m_sliders.size()) / m_width;
if (button.getPosition().x + button.width() > Widget::m_width) {
Widget::m_width = button.getPosition().x + button.width();
m_sliders.emplace_back(std::piecewise_construct,
std::forward_as_tuple(this), std::forward_as_tuple(x, y));
SliderWidget &slider = m_sliders.back().first;
slider.setText(text);
slider.setCallback(callback);
slider.setMinMaxValues(min, max);
slider.setCurrentValue(initialValue);
updateWidgetPosition(slider, x, y);
return slider;
}
void MenuWidget::updateWidgetPosition(Widget &widget, int x, int y) {
widget.setPosition(x * (widget.width() + m_horizontalSpacing),
y * (widget.height() + m_verticalSpacing));
if (widget.getPosition().x + widget.width() > Widget::m_width) {
Widget::m_width = widget.getPosition().x + widget.width();
}
if (button.getPosition().y + button.height() > Widget::m_height) {
Widget::m_height = button.getPosition().y + button.height();
if (widget.getPosition().y + widget.height() > Widget::m_height) {
Widget::m_height = widget.getPosition().y + widget.height();
}
}
void MenuWidget::draw(gk::RenderTarget &target, gk::RenderStates states) const {
states.transform *= getTransform();
for (const TextButton &button : m_buttons) {
if (!button.text().empty())
target.draw(button, states);
for (auto &it : m_buttons) {
if (!it.first.text().empty())
target.draw(it.first, states);
}
for (auto &it : m_sliders) {
target.draw(it.first, states);
}
}

View File

@ -27,6 +27,7 @@
#ifndef MENUWIDGET_HPP_
#define MENUWIDGET_HPP_
#include "SliderWidget.hpp"
#include "TextButton.hpp"
struct GuiScaleChangedEvent;
@ -45,11 +46,13 @@ class MenuWidget : public Widget {
TextButton &addButton(const std::string &text, const TextButton::CppCallback &callback, u16 width = 200);
void setButtonEnabled(const std::string &text, bool isEnabled);
SliderWidget &addSlider(const std::string &text, const SliderWidget::CppCallback &callback, int min, int max, int initialValue);
void setVerticalSpacing(u16 verticalSpacing) { m_verticalSpacing = verticalSpacing; }
void setHorizontalSpacing(u16 horizontalSpacing) { m_horizontalSpacing = horizontalSpacing; }
private:
void updateButtonPosition(TextButton &button, int x, int y);
void updateWidgetPosition(Widget &widget, int x, int y);
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
@ -59,7 +62,8 @@ class MenuWidget : public Widget {
u16 m_width = 1;
u16 m_height = 1;
std::vector<TextButton> m_buttons;
std::vector<std::pair<TextButton, gk::Vector2i>> m_buttons;
std::vector<std::pair<SliderWidget, gk::Vector2i>> m_sliders;
};
#endif // MENUWIDGET_HPP_

View File

@ -0,0 +1,111 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#include "Config.hpp"
#include "SliderWidget.hpp"
SliderWidget::SliderWidget(Widget *parent) : SliderWidget(200, parent) {
}
SliderWidget::SliderWidget(u16 width, Widget *parent) : Widget(width, 20, parent) {
m_text.setColor(m_defaultTextColor);
m_text.setShadowColor({56, 56, 56});
m_slider.setClipRect(0, 66, 8, 20);
m_background.setClipRect(0, 46, width, 20);
m_sliderBorder.setClipRect(200 - 2, 66, 2, 20);
m_backgroundBorder.setClipRect(200 - 2, 46, 2, 20);
m_sliderBorder.setPosition(8 - 2, 0);
m_backgroundBorder.setPosition(width - 2, 0);
}
void SliderWidget::onEvent(const SDL_Event &event) {
if (event.type == SDL_MOUSEMOTION) {
if (m_isDragging || isPointInWidget(event.motion.x, event.motion.y)) {
m_text.setColor(m_hoverColor);
updatePercentage(event.motion.x);
}
else
m_text.setColor(m_defaultTextColor);
if (m_isDragging)
m_callback(*this, event.type);
}
else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT) {
m_isDragging = isPointInWidget(event.button.x, event.button.y);
updatePercentage(event.button.x);
if (m_isDragging)
m_callback(*this, event.type);
}
else if (event.type == SDL_MOUSEBUTTONUP && event.button.button == SDL_BUTTON_LEFT) {
if (m_isDragging)
m_callback(*this, event.type);
m_isDragging = false;
}
}
void SliderWidget::setCurrentValue(int currentValue) {
m_percentage = (currentValue - m_min) / float(m_max - m_min);
updateSliderPosition();
}
void SliderWidget::setText(const std::string &text) {
m_text.setString(text);
m_text.updateVertexBuffer();
m_text.setPosition(m_width / 2 - m_text.getSize().x / 2,
m_height / 2 - m_text.getSize().y / 2, 0);
}
void SliderWidget::updatePercentage(s32 mouseX) {
if (m_isDragging) {
m_percentage = (mouseX - getGlobalBounds().x) / Config::guiScale / m_width;
m_percentage = std::clamp(m_percentage, 0.f, 1.f);
updateSliderPosition();
}
}
void SliderWidget::updateSliderPosition() {
m_slider.setPosition(m_percentage * (m_width - 8), 0);
m_sliderBorder.setPosition(m_percentage * (m_width - 8) + 6, 0);
}
void SliderWidget::draw(gk::RenderTarget &target, gk::RenderStates states) const {
states.transform *= getTransform();
target.draw(m_background, states);
target.draw(m_backgroundBorder, states);
target.draw(m_slider, states);
target.draw(m_sliderBorder, states);
target.draw(m_text, states);
}

View File

@ -0,0 +1,82 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef SLIDERWIDGET_HPP_
#define SLIDERWIDGET_HPP_
#include <functional>
#include <gk/graphics/Image.hpp>
#include "Text.hpp"
#include "Widget.hpp"
class SliderWidget : public Widget {
public:
using CppCallback = std::function<void(SliderWidget &, u32)>;
SliderWidget(Widget *parent = nullptr);
SliderWidget(u16 width, Widget *parent = nullptr);
void onEvent(const SDL_Event &event) override;
int getCurrentValue() const { return m_min + (m_max - m_min) * m_percentage; }
void setMinMaxValues(int min, int max) { m_min = min; m_max = max; }
void setCurrentValue(int currentValue);
const std::string &text() const { return m_text.string(); }
void setText(const std::string &text);
void setCallback(const CppCallback &callback) { m_callback = callback; }
private:
void updatePercentage(s32 mouseX);
void updateSliderPosition();
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
const gk::Color m_defaultTextColor{224, 224, 224};
const gk::Color m_hoverColor{255, 255, 160};
gk::Image m_slider{"texture-widgets"};
gk::Image m_background{"texture-widgets"};
gk::Image m_sliderBorder{"texture-widgets"};
gk::Image m_backgroundBorder{"texture-widgets"};
Text m_text;
int m_min = 0;
int m_max = 100;
float m_percentage = 0.f;
bool m_isDragging = false;
CppCallback m_callback;
};
#endif // SLIDERWIDGET_HPP_

View File

@ -153,7 +153,7 @@ void GameState::onEvent(const SDL_Event &event) {
void GameState::update() {
m_world.checkPlayerChunk(m_player.x(), m_player.y(), m_player.z());
m_world.update();
m_world.update(!m_stateStack->empty() && &m_stateStack->top() == this);
if (m_camera.getFieldOfView() != Config::cameraFOV)
m_camera.setFieldOfView(Config::cameraFOV);

View File

@ -193,11 +193,11 @@ void SettingsMenuState::addInterfaceButtons() {
void SettingsMenuState::addGraphicsButtons() {
m_menuWidget.reset(2, 8);
m_menuWidget.addButton("Render Distance: " + std::to_string(Config::renderDistance), [] (TextButton &button) {
Config::renderDistance = std::max(4, (Config::renderDistance + 2) % 16);
button.setText("Render Distance: " + std::to_string(Config::renderDistance));
m_menuWidget.addSlider("Render Distance: " + std::to_string(Config::renderDistance), [] (SliderWidget &slider, u32) {
Config::renderDistance = slider.getCurrentValue();
slider.setText("Render Distance: " + std::to_string(Config::renderDistance));
World::isReloadRequested = true;
});
}, 4, 16, Config::renderDistance);
addToggleButton("Wireframe Mode", Config::isWireframeModeEnabled, false);
@ -213,12 +213,13 @@ void SettingsMenuState::addGraphicsButtons() {
m_aoButton = &addToggleButton("Ambient Occlusion", Config::isAmbientOcclusionEnabled, true);
m_aoButton->setEnabled(!Config::isSmoothLightingEnabled);
m_menuWidget.addButton("GUI Scale: " + std::to_string(Config::guiScale), [this] (TextButton &button) {
Config::guiScale = 1 + (Config::guiScale + 1) % 3;
button.setText("GUI Scale: " + std::to_string(Config::guiScale));
m_eventHandler->emplaceEvent<GuiScaleChangedEvent>(Config::guiScale);
});
m_menuWidget.addSlider("GUI Scale: " + std::to_string(Config::guiScale), [this] (SliderWidget &slider, u32 eventType) {
slider.setText("GUI Scale: " + std::to_string(slider.getCurrentValue()));
if (eventType == SDL_MOUSEBUTTONUP) {
Config::guiScale = slider.getCurrentValue();
m_eventHandler->emplaceEvent<GuiScaleChangedEvent>(Config::guiScale);
}
}, 1, 3, Config::guiScale);
addToggleButton("Fullscreen", Config::isFullscreenModeEnabled, false);
m_menuWidget.addButton("Resolution: " + std::to_string(Config::screenWidth) + "x" + std::to_string(Config::screenHeight), [] (TextButton &button) {
@ -243,20 +244,10 @@ void SettingsMenuState::addGraphicsButtons() {
addToggleButton("Use VSync", Config::isVerticalSyncEnabled, false);
m_menuWidget.addButton("Mipmap Levels: " + std::to_string(Config::mipmapLevels), [] (TextButton &button) {
Config::mipmapLevels = (Config::mipmapLevels + 1) % 5;
button.setText("Mipmap Levels: " + std::to_string(Config::mipmapLevels));
});
m_menuWidget.addButton("AO Strength: " + gk::toString(Config::aoStrength, 2), [] (TextButton &button) {
Config::aoStrength += 0.25f;
if (Config::aoStrength > 1.5f)
Config::aoStrength = 0.f;
button.setText("AO Strength: " + gk::toString(Config::aoStrength, 2));
World::isReloadRequested = true;
});
m_menuWidget.addSlider("Mipmap Levels: " + std::to_string(Config::mipmapLevels), [] (SliderWidget &slider, u32) {
Config::mipmapLevels = slider.getCurrentValue();
slider.setText("Mipmap Levels: " + std::to_string(Config::mipmapLevels));
}, 0, 4, Config::mipmapLevels);
updateWidgetPosition();
}
@ -274,10 +265,10 @@ void SettingsMenuState::addInputButtons() {
});
}
m_menuWidget.addButton("Mouse sensitivity: " + std::to_string(Config::mouseSensitivity), [] (TextButton &button) {
Config::mouseSensitivity = std::max(2, (Config::mouseSensitivity + 2) % 22);
button.setText("Mouse sensitivity: " + std::to_string(Config::mouseSensitivity));
});
m_menuWidget.addSlider("Mouse Sensitivity: " + std::to_string(Config::mouseSensitivity), [] (SliderWidget &slider, u32) {
Config::mouseSensitivity = slider.getCurrentValue();
slider.setText("Mouse Sensitivity: " + std::to_string(Config::mouseSensitivity));
}, 4, 32, Config::mouseSensitivity);
updateWidgetPosition();
}

View File

@ -406,9 +406,11 @@ inline u8 ChunkBuilder::getLightForVertex(Light light, s8f x, s8f y, s8f z, cons
// If the chunk is initialized, add the light value to the total
if (lightValues[i] != -1) {
float strength = ((surroundingBlocks[i] - normal == gk::Vector3i{x, y, z}) ? 1 : Config::aoStrength);
total += lightValues[i] * strength;
count += strength;
// float strength = ((surroundingBlocks[i] - normal == gk::Vector3i{x, y, z}) ? 1 : Config::aoStrength);
// total += lightValues[i] * strength;
// count += strength;
total += lightValues[i];
++count;
}
}

View File

@ -43,7 +43,7 @@ ClientWorld::ClientWorld() : m_textureAtlas(gk::ResourceHandler::getInstance().g
{
}
void ClientWorld::update() {
void ClientWorld::update(bool allowWorldReload) {
// Update loaded chunks
for (auto it = m_chunks.begin() ; it != m_chunks.end() ;) {
// If chunk is too far, remove it
@ -52,7 +52,7 @@ void ClientWorld::update() {
}
// Otherwise, update the chunk
else {
if (World::isReloadRequested)
if (World::isReloadRequested && allowWorldReload)
it->second->setChanged(true);
if (it->second->areAllNeighboursInitialized())
@ -62,7 +62,8 @@ void ClientWorld::update() {
}
}
World::isReloadRequested = false;
if (allowWorldReload)
World::isReloadRequested = false;
sendChunkRequests();

View File

@ -47,7 +47,7 @@ class ClientWorld : public World, public gk::Drawable {
public:
ClientWorld();
void update();
void update(bool allowWorldReload);
void sendChunkRequests();
void checkPlayerChunk(double playerX, double playerY, double playerZ);