1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Merge remote-tracking branch 'upstream/master' into Visuals-Vol-2

This commit is contained in:
Gefüllte Taubenbrust 2024-09-25 20:53:09 +02:00
commit 71e648a776
647 changed files with 60434 additions and 37195 deletions

View file

@ -40,7 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content/subgames.h"
#include "client/event_manager.h"
#include "fontengine.h"
#include "gui/touchscreengui.h"
#include "gui/touchcontrols.h"
#include "itemdef.h"
#include "log.h"
#include "filesys.h"
@ -79,6 +79,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "hud.h"
#include "clientdynamicinfo.h"
#include <IAnimatedMeshSceneNode.h>
#include "util/tracy_wrapper.h"
#if USE_SOUND
#include "client/sound/sound_openal.h"
@ -185,7 +186,7 @@ struct LocalFormspecHandler : public TextDest
assert(m_client != nullptr);
if (fields.find("quit") != fields.end())
m_client->sendRespawn();
m_client->sendRespawnLegacy();
return;
}
@ -535,6 +536,10 @@ public:
float camera_far = m_client->getCamera()->getCameraNode()->getFarValue();
m_camera_far_pixel.set(&camera_far, services);
v3f camera_position = m_client->getCamera()->getPosition();
m_camera_position_pixel.set(camera_position, services);
m_camera_position_pixel.set(camera_position, services);
SamplerLayer_t tex_id;
tex_id = 0;
m_texture0.set(&tex_id, services);
@ -659,7 +664,8 @@ public:
m_client(client)
{}
void setSky(Sky *sky) {
void setSky(Sky *sky)
{
m_sky = sky;
for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
ggscs->setSky(m_sky);
@ -894,7 +900,7 @@ private:
bool disable_camera_update = false;
};
void showDeathFormspec();
void showDeathFormspecLegacy();
void showPauseMenu();
void pauseAnimation();
@ -904,7 +910,7 @@ private:
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_DeathscreenLegacy(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
void handleClientEvent_HandleParticleEvent(ClientEvent *event,
@ -954,11 +960,11 @@ private:
QuicktuneShortcutter *quicktune = nullptr;
std::unique_ptr<GameUI> m_game_ui;
GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
irr_ptr<GUIChatConsole> gui_chat_console;
MapDrawControl *draw_control = nullptr;
Camera *camera = nullptr;
Clouds *clouds = nullptr; // Free using ->Drop()
Sky *sky = nullptr; // Free using ->Drop()
irr_ptr<Clouds> clouds;
irr_ptr<Sky> sky;
Hud *hud = nullptr;
Minimap *mapper = nullptr;
@ -1205,6 +1211,8 @@ bool Game::startup(bool *kill,
void Game::run()
{
ZoneScoped;
ProfilerGraph graph;
RunStats stats = {};
CameraOrientation cam_view_target = {};
@ -1232,15 +1240,21 @@ void Game::run()
const bool initial_window_maximized = !g_settings->getBool("fullscreen") &&
g_settings->getBool("window_maximized");
auto framemarker = FrameMarker("Game::run()-frame").started();
while (m_rendering_engine->run()
&& !(*kill || g_gamecallback->shutdown_requested
|| (server && server->isShutdownRequested()))) {
framemarker.end();
// Calculate dtime =
// m_rendering_engine->run() from this iteration
// + Sleep time until the wanted FPS are reached
draw_times.limit(device, &dtime, g_menumgr.pausesGame());
framemarker.start();
const auto current_dynamic_info = ClientDynamicInfo::getCurrent();
if (!current_dynamic_info.equal(client_display_info)) {
client_display_info = current_dynamic_info;
@ -1297,6 +1311,8 @@ void Game::run()
}
}
framemarker.end();
RenderingEngine::autosaveScreensizeAndCo(initial_screen_size, initial_window_maximized);
}
@ -1310,21 +1326,18 @@ void Game::shutdown()
// Clear text when exiting.
m_game_ui->clearText();
if (g_touchscreengui)
g_touchscreengui->hide();
if (g_touchcontrols)
g_touchcontrols->hide();
// only if the shutdown progress bar isn't shown yet
if (m_shutdown_progress == 0.0f)
showOverlayMessage(N_("Shutting down..."), 0, 0);
if (clouds)
clouds->drop();
clouds.reset();
if (gui_chat_console)
gui_chat_console->drop();
gui_chat_console.reset();
if (sky)
sky->drop();
sky.reset();
/* cleanup menus */
while (g_menumgr.menuCount() > 0) {
@ -1511,7 +1524,7 @@ void Game::copyServerClientCache()
{
// It would be possible to let the client directly read the media files
// from where the server knows they are. But aside from being more complicated
// it would also *not* fill the media cache and cause slower joining of
// it would also *not* fill the media cache and cause slower joining of
// remote servers.
// (Imagine that you launch a game once locally and then connect to a server.)
@ -1575,20 +1588,16 @@ bool Game::createClient(const GameStartData &start_data)
client->getScript()->on_camera_ready(camera);
client->setCamera(camera);
if (g_touchscreengui) {
g_touchscreengui->setUseCrosshair(!isTouchCrosshairDisabled());
}
/* Clouds
*/
if (m_cache_enable_clouds)
clouds = new Clouds(smgr, shader_src, -1, rand());
clouds = make_irr<Clouds>(smgr, shader_src, -1, rand());
client->setClouds(clouds);
/* Skybox
*/
sky = new Sky(-1, m_rendering_engine, texture_src, shader_src);
scsf->setSky(sky);
sky = make_irr<Sky>(-1, m_rendering_engine, texture_src, shader_src);
scsf->setSky(sky.get());
/* Pre-calculated values
*/
@ -1641,11 +1650,13 @@ bool Game::initGui()
chat_backend->applySettings();
// Chat backend and console
gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(),
gui_chat_console = make_irr<GUIChatConsole>(guienv, guienv->getRootGUIElement(),
-1, chat_backend, client, &g_menumgr);
if (g_settings->getBool("enable_touch"))
g_touchscreengui = new TouchScreenGUI(device, texture_src);
if (g_settings->getBool("touch_controls")) {
g_touchcontrols = new TouchControls(device, texture_src);
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
}
return true;
}
@ -1739,9 +1750,13 @@ bool Game::connectToServer(const GameStartData &start_data,
fps_control.reset();
auto framemarker = FrameMarker("Game::connectToServer()-frame").started();
while (m_rendering_engine->run()) {
framemarker.end();
fps_control.limit(device, &dtime);
framemarker.start();
// Update client and server
step(dtime);
@ -1787,6 +1802,7 @@ bool Game::connectToServer(const GameStartData &start_data,
// Update status
showOverlayMessage(N_("Connecting to server..."), dtime, 20);
}
framemarker.end();
} catch (con::PeerNotFoundException &e) {
warningstream << "This should not happen. Please report a bug." << std::endl;
return false;
@ -1804,9 +1820,11 @@ bool Game::getServerContent(bool *aborted)
fps_control.reset();
auto framemarker = FrameMarker("Game::getServerContent()-frame").started();
while (m_rendering_engine->run()) {
framemarker.end();
fps_control.limit(device, &dtime);
framemarker.start();
// Update client and server
step(dtime);
@ -1872,6 +1890,7 @@ bool Game::getServerContent(bool *aborted)
texture_src, dtime, progress);
}
}
framemarker.end();
*aborted = true;
infostream << "Connect aborted [device]" << std::endl;
@ -1922,26 +1941,26 @@ inline bool Game::handleCallbacks()
}
if (g_gamecallback->changepassword_requested) {
(new GUIPasswordChange(guienv, guiroot, -1,
&g_menumgr, client, texture_src))->drop();
(void)make_irr<GUIPasswordChange>(guienv, guiroot, -1,
&g_menumgr, client, texture_src);
g_gamecallback->changepassword_requested = false;
}
if (g_gamecallback->changevolume_requested) {
(new GUIVolumeChange(guienv, guiroot, -1,
&g_menumgr, texture_src))->drop();
(void)make_irr<GUIVolumeChange>(guienv, guiroot, -1,
&g_menumgr, texture_src);
g_gamecallback->changevolume_requested = false;
}
if (g_gamecallback->keyconfig_requested) {
(new GUIKeyChangeMenu(guienv, guiroot, -1,
&g_menumgr, texture_src))->drop();
(void)make_irr<GUIKeyChangeMenu>(guienv, guiroot, -1,
&g_menumgr, texture_src);
g_gamecallback->keyconfig_requested = false;
}
if (!g_gamecallback->show_open_url_dialog.empty()) {
(new GUIOpenURLMenu(guienv, guiroot, -1,
&g_menumgr, texture_src, g_gamecallback->show_open_url_dialog))->drop();
(void)make_irr<GUIOpenURLMenu>(guienv, guiroot, -1,
&g_menumgr, texture_src, g_gamecallback->show_open_url_dialog);
g_gamecallback->show_open_url_dialog.clear();
}
@ -1980,6 +1999,10 @@ void Game::updateDebugState()
if (!has_debug) {
draw_control->show_wireframe = false;
m_flags.disable_camera_update = false;
auto formspec = m_game_ui->getFormspecGUI();
if (formspec) {
formspec->setDebugView(false);
}
}
// noclip
@ -2015,6 +2038,14 @@ void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times,
g_profiler->graphAdd("Sleep [us]", draw_times.sleep_time);
g_profiler->graphSet("FPS", 1.0f / dtime);
auto stats2 = driver->getFrameStats();
g_profiler->avg("Irr: drawcalls", stats2.Drawcalls);
if (stats2.Drawcalls > 0)
g_profiler->avg("Irr: primitives per drawcall",
stats2.PrimitivesDrawn / float(stats2.Drawcalls));
g_profiler->avg("Irr: buffers uploaded", stats2.HWBuffersUploaded);
g_profiler->avg("Irr: buffers uploaded (bytes)", stats2.HWBuffersUploadedSize);
}
void Game::updateStats(RunStats *stats, const FpsControl &draw_times,
@ -2075,7 +2106,7 @@ void Game::updateStats(RunStats *stats, const FpsControl &draw_times,
void Game::processUserInput(f32 dtime)
{
// Reset input if window not active or some menu is active
if (!device->isWindowActive() || isMenuActive() || guienv->hasFocus(gui_chat_console)) {
if (!device->isWindowActive() || isMenuActive() || guienv->hasFocus(gui_chat_console.get())) {
if (m_game_focused) {
m_game_focused = false;
infostream << "Game lost focus" << std::endl;
@ -2084,21 +2115,21 @@ void Game::processUserInput(f32 dtime)
input->clear();
}
if (g_touchscreengui)
g_touchscreengui->hide();
if (g_touchcontrols)
g_touchcontrols->hide();
} else {
if (g_touchscreengui) {
/* on touchscreengui step may generate own input events which ain't
if (g_touchcontrols) {
/* on touchcontrols step may generate own input events which ain't
* what we want in case we just did clear them */
g_touchscreengui->show();
g_touchscreengui->step(dtime);
g_touchcontrols->show();
g_touchcontrols->step(dtime);
}
m_game_focused = true;
}
if (!guienv->hasFocus(gui_chat_console) && gui_chat_console->isOpen()) {
if (!guienv->hasFocus(gui_chat_console.get()) && gui_chat_console->isOpen()) {
gui_chat_console->closeConsoleAtOnce();
}
@ -2250,12 +2281,14 @@ void Game::processItemSelection(u16 *new_playeritem)
{
LocalPlayer *player = client->getEnv().getLocalPlayer();
*new_playeritem = player->getWieldIndex();
u16 max_item = player->getMaxHotbarItemcount();
if (max_item == 0)
return;
max_item -= 1;
/* Item selection using mouse wheel
*/
*new_playeritem = player->getWieldIndex();
u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE - 1,
player->hud_hotbar_itemcount - 1);
s32 wheel = input->getMouseWheel();
if (!m_enable_hotbar_mouse_wheel)
wheel = 0;
@ -2285,8 +2318,8 @@ void Game::processItemSelection(u16 *new_playeritem)
}
}
if (g_touchscreengui) {
std::optional<u16> selection = g_touchscreengui->getHotbarSelection();
if (g_touchcontrols) {
std::optional<u16> selection = g_touchcontrols->getHotbarSelection();
if (selection)
*new_playeritem = *selection;
}
@ -2691,7 +2724,7 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
this results in duplicated input. To avoid that, we don't enable relative
mouse mode if we're in touchscreen mode. */
if (cur_control)
cur_control->setRelativeMode(!g_touchscreengui && !isMenuActive());
cur_control->setRelativeMode(!g_touchcontrols && !isMenuActive());
if ((device->isWindowActive() && device->isWindowFocused()
&& !isMenuActive()) || input->isRandom()) {
@ -2734,9 +2767,9 @@ f32 Game::getSensitivityScaleFactor() const
void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
{
if (g_touchscreengui) {
cam->camera_yaw += g_touchscreengui->getYawChange();
cam->camera_pitch += g_touchscreengui->getPitchChange();
if (g_touchcontrols) {
cam->camera_yaw += g_touchcontrols->getYawChange();
cam->camera_pitch += g_touchcontrols->getPitchChange();
} else {
v2s32 center(driver->getScreenSize().Width / 2, driver->getScreenSize().Height / 2);
v2s32 dist = input->getMousePos() - center;
@ -2801,7 +2834,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
* touch then its meaning is inverted (i.e. holding aux1 means walk and
* not fast)
*/
if (g_touchscreengui && m_touch_simulate_aux1) {
if (g_touchcontrols && m_touch_simulate_aux1) {
control.aux1 = control.aux1 ^ true;
}
@ -2827,6 +2860,8 @@ void Game::updatePauseState()
inline void Game::step(f32 dtime)
{
ZoneScoped;
if (server) {
float fps_max = (!device->isWindowFocused() || g_menumgr.pausesGame()) ?
g_settings->getFloat("fps_max_unfocused") :
@ -2883,7 +2918,7 @@ const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
{&Game::handleClientEvent_None},
{&Game::handleClientEvent_PlayerDamage},
{&Game::handleClientEvent_PlayerForceMove},
{&Game::handleClientEvent_Deathscreen},
{&Game::handleClientEvent_DeathscreenLegacy},
{&Game::handleClientEvent_ShowFormSpec},
{&Game::handleClientEvent_ShowLocalFormSpec},
{&Game::handleClientEvent_HandleParticleEvent},
@ -2939,20 +2974,9 @@ void Game::handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientati
cam->camera_pitch = event->player_force_move.pitch;
}
void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam)
void Game::handleClientEvent_DeathscreenLegacy(ClientEvent *event, CameraOrientation *cam)
{
// If client scripting is enabled, deathscreen is handled by CSM code in
// builtin/client/init.lua
if (client->modsLoaded())
client->getScript()->on_death();
else
showDeathFormspec();
/* Handle visualization */
LocalPlayer *player = client->getEnv().getLocalPlayer();
runData.damage_flash = 0;
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
showDeathFormspecLegacy();
}
void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam)
@ -3219,6 +3243,7 @@ void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *
clouds->setDensity(event->cloud_params.density);
clouds->setColorBright(video::SColor(event->cloud_params.color_bright));
clouds->setColorAmbient(video::SColor(event->cloud_params.color_ambient));
clouds->setColorShadow(video::SColor(event->cloud_params.color_shadow));
clouds->setHeight(event->cloud_params.height);
clouds->setThickness(event->cloud_params.thickness);
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
@ -3290,8 +3315,8 @@ void Game::updateCamera(f32 dtime)
camera->toggleCameraMode();
if (g_touchscreengui)
g_touchscreengui->setUseCrosshair(!isTouchCrosshairDisabled());
if (g_touchcontrols)
g_touchcontrols->setUseCrosshair(!isTouchCrosshairDisabled());
// Make the player visible depending on camera mode.
playercao->updateMeshCulling();
@ -3392,8 +3417,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
}
shootline.end = shootline.start + camera_direction * BS * d;
if (g_touchscreengui && isTouchCrosshairDisabled()) {
shootline = g_touchscreengui->getShootline();
if (g_touchcontrols && isTouchCrosshairDisabled()) {
shootline = g_touchcontrols->getShootline();
// Scale shootline to the acual distance the player can reach
shootline.end = shootline.start +
shootline.getVector().normalize() * BS * d;
@ -3410,9 +3435,13 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
if (pointed != runData.pointed_old)
infostream << "Pointing at " << pointed.dump() << std::endl;
if (g_touchscreengui) {
auto mode = selected_def.touch_interaction.getMode(pointed.type);
g_touchscreengui->applyContextControls(mode);
if (g_touchcontrols) {
auto mode = selected_def.touch_interaction.getMode(selected_def, pointed.type);
g_touchcontrols->applyContextControls(mode);
// applyContextControls may change dig/place input.
// Update again so that TOSERVER_INTERACT packets have the correct controls set.
player->control.dig = isKeyDown(KeyType::DIG);
player->control.place = isKeyDown(KeyType::PLACE);
}
// Note that updating the selection mesh every frame is not particularly efficient,
@ -4049,8 +4078,12 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
runData.nodig_delay_timer =
runData.dig_time_complete / (float)crack_animation_length;
// Don't add a corresponding delay to very time consuming nodes.
runData.nodig_delay_timer = std::min(runData.nodig_delay_timer, 0.3f);
// We don't want a corresponding delay to very time consuming nodes
// and nodes without digging time (e.g. torches) get a fixed delay.
if (runData.nodig_delay_timer > 0.3f)
runData.nodig_delay_timer = 0.3f;
else if (runData.dig_instantly)
runData.nodig_delay_timer = 0.15f;
// Ensure that the delay between breaking nodes
// (dig_time_complete + nodig_delay_timer) is at least the
@ -4098,6 +4131,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
const CameraOrientation &cam)
{
ZoneScoped;
TimeTaker tt_update("Game::updateFrame()");
LocalPlayer *player = client->getEnv().getLocalPlayer();
@ -4242,7 +4276,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
updateShadows();
}
m_game_ui->update(*stats, client, draw_control, cam, runData.pointed_old, gui_chat_console, dtime);
m_game_ui->update(*stats, client, draw_control, cam, runData.pointed_old,
gui_chat_console.get(), dtime);
/*
make sure menu is on top
@ -4340,7 +4375,9 @@ void Game::updateShadows()
float timeoftheday = getWickedTimeOfDay(in_timeofday);
bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75;
bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible();
shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f);
const auto &lighting = client->getEnv().getLocalPlayer()->getLighting();
shadow->setShadowIntensity(is_shadow_visible ? lighting.shadow_intensity : 0.0f);
shadow->setShadowTint(lighting.shadow_tint);
timeoftheday = std::fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
const float offset_constant = 10000.0f;
@ -4357,6 +4394,8 @@ void Game::updateShadows()
void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
{
ZoneScoped;
const video::SColor fog_color = this->sky->getFogColor();
const video::SColor sky_color = this->sky->getSkyColor();
@ -4399,7 +4438,7 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
(this->camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
if (g_touchscreengui && isTouchCrosshairDisabled())
if (g_touchcontrols && isTouchCrosshairDisabled())
draw_crosshair = false;
this->m_rendering_engine->draw_scene(sky_color, this->m_game_ui->m_flags.show_hud,
@ -4454,8 +4493,8 @@ void Game::readSettings()
m_cache_enable_fog = g_settings->getBool("enable_fog");
m_cache_mouse_sensitivity = g_settings->getFloat("mouse_sensitivity", 0.001f, 10.0f);
m_cache_joystick_frustum_sensitivity = std::max(g_settings->getFloat("joystick_frustum_sensitivity"), 0.001f);
m_repeat_place_time = g_settings->getFloat("repeat_place_time", 0.15f, 2.0f);
m_repeat_dig_time = g_settings->getFloat("repeat_dig_time", 0.15f, 2.0f);
m_repeat_place_time = g_settings->getFloat("repeat_place_time", 0.16f, 2.0f);
m_repeat_dig_time = g_settings->getFloat("repeat_dig_time", 0.0f, 2.0f);
m_cache_enable_noclip = g_settings->getBool("noclip");
m_cache_enable_free_move = g_settings->getBool("free_move");
@ -4482,7 +4521,7 @@ void Game::readSettings()
****************************************************************************/
/****************************************************************************/
void Game::showDeathFormspec()
void Game::showDeathFormspecLegacy()
{
static std::string formspec_str =
std::string("formspec_version[1]") +
@ -4510,7 +4549,7 @@ void Game::showPauseMenu()
{
std::string control_text;
if (g_touchscreengui) {
if (g_touchcontrols) {
control_text = strgettext("Controls:\n"
"No menu open:\n"
"- slide finger: look around\n"