This commit is contained in:
Bruno Rybársky 2024-02-27 14:14:29 +01:00
commit dd460bfbb3

@ -33,7 +33,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/mapblock_mesh.h"
#include "client/sound.h"
#include "clientmap.h"
#include "clientmedia.h" // For clientMediaUpdateCacheCopy
#include "clouds.h"
#include "config.h"
#include "content_cao.h"
@ -664,7 +663,11 @@ public:
}
};
#define SIZE_TAG "size[11,5.5,true]" // Fixed size (ignored in touchscreen mode)
#ifdef HAVE_TOUCHSCREENGUI
#define SIZE_TAG "size[11,5.5]"
#else
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
#endif
/****************************************************************************
****************************************************************************/
@ -766,7 +769,6 @@ protected:
bool initSound();
bool createSingleplayerServer(const std::string &map_dir,
const SubgameSpec &gamespec, u16 port);
void copyServerClientCache();
// Client creation
bool createClient(const GameStartData &start_data);
@ -1017,11 +1019,13 @@ private:
// this happens in pause menu in singleplayer
bool m_is_paused = false;
bool m_touch_simulate_aux1 = false;
#ifdef HAVE_TOUCHSCREENGUI
bool m_cache_hold_aux1;
bool m_touch_use_crosshair;
inline bool isTouchCrosshairDisabled() {
inline bool isNoCrosshairAllowed() {
return !m_touch_use_crosshair && camera->getCameraMode() == CAMERA_MODE_FIRST;
}
#endif
#ifdef __ANDROID__
bool m_android_chat_open;
#endif
@ -1069,6 +1073,11 @@ Game::Game() :
&settingChangedCallback, this);
readSettings();
#ifdef HAVE_TOUCHSCREENGUI
m_cache_hold_aux1 = false; // This is initialised properly later
#endif
}
@ -1171,7 +1180,9 @@ bool Game::startup(bool *kill,
m_first_loop_after_window_activation = true;
#ifdef HAVE_TOUCHSCREENGUI
m_touch_use_crosshair = g_settings->getBool("touch_use_crosshair");
#endif
g_client_translations->clear();
@ -1206,8 +1217,10 @@ void Game::run()
set_light_table(g_settings->getFloat("display_gamma"));
m_touch_simulate_aux1 = g_settings->getBool("fast_move")
#ifdef HAVE_TOUCHSCREENGUI
m_cache_hold_aux1 = g_settings->getBool("fast_move")
&& client->checkPrivilege("fast");
#endif
const irr::core::dimension2du initial_screen_size(
g_settings->getU16("screen_w"),
@ -1275,6 +1288,9 @@ void Game::run()
updateFrame(&graph, &stats, dtime, cam_view);
updateProfilerGraphs(&graph);
// Update if minimap has been disabled by the server
m_game_ui->m_flags.show_minimap &= client->shouldShowMinimap();
if (m_does_lost_focus_pause_game && !device->isWindowFocused() && !isMenuActive()) {
showPauseMenu();
}
@ -1293,8 +1309,9 @@ void Game::shutdown()
// Clear text when exiting.
m_game_ui->clearText();
if (g_touchscreengui)
g_touchscreengui->hide();
#ifdef HAVE_TOUCHSCREENGUI
g_touchscreengui->hide();
#endif
showOverlayMessage(N_("Shutting down..."), 0, 0, false);
@ -1436,31 +1453,9 @@ bool Game::createSingleplayerServer(const std::string &map_dir,
false, nullptr, error_message);
server->start();
copyServerClientCache();
return true;
}
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
// remote servers.
// (Imagine that you launch a game once locally and then connect to a server.)
assert(server);
auto map = server->getMediaList();
u32 n = 0;
for (auto &it : map) {
assert(it.first.size() == 20); // SHA1
if (clientMediaUpdateCacheCopy(it.first, it.second))
n++;
}
infostream << "Copied " << n << " files directly from server to client cache"
<< std::endl;
}
bool Game::createClient(const GameStartData &start_data)
{
showOverlayMessage(N_("Creating client..."), 0, 10);
@ -1504,10 +1499,11 @@ bool Game::createClient(const GameStartData &start_data)
if (client->modsLoaded())
client->getScript()->on_camera_ready(camera);
client->setCamera(camera);
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
g_touchscreengui->setUseCrosshair(!isTouchCrosshairDisabled());
g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
}
#endif
/* Clouds
*/
@ -1534,20 +1530,18 @@ bool Game::createClient(const GameStartData &start_data)
/* Set window caption
*/
#if IRRLICHT_VERSION_MT_REVISION >= 15
auto driver_name = driver->getName();
#else
auto driver_name = wide_to_utf8(driver->getName());
#endif
std::string str = std::string(PROJECT_NAME_C) +
" " + g_version_hash + " [";
str += simple_singleplayer_mode ? gettext("Singleplayer")
: gettext("Multiplayer");
str += "] [";
str += driver_name;
str += "]";
std::wstring str = utf8_to_wide(PROJECT_NAME_C);
str += L" ";
str += utf8_to_wide(g_version_hash);
str += L" [";
str += simple_singleplayer_mode ? wstrgettext("Singleplayer")
: wstrgettext("Multiplayer");
str += L"]";
str += L" [";
str += driver->getName();
str += L"]";
device->setWindowCaption(utf8_to_wide(str).c_str());
device->setWindowCaption(str.c_str());
LocalPlayer *player = client->getEnv().getLocalPlayer();
player->hurt_tilt_timer = 0;
@ -1577,8 +1571,10 @@ bool Game::initGui()
gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(),
-1, chat_backend, client, &g_menumgr);
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->init(texture_src);
#endif
return true;
}
@ -2012,17 +2008,18 @@ void Game::processUserInput(f32 dtime)
} else {
input->clear();
}
if (g_touchscreengui)
g_touchscreengui->hide();
#ifdef HAVE_TOUCHSCREENGUI
g_touchscreengui->hide();
#endif
} else {
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
/* on touchscreengui 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);
}
#endif
m_game_focused = true;
}
@ -2214,11 +2211,13 @@ void Game::processItemSelection(u16 *new_playeritem)
}
}
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
std::optional<u16> selection = g_touchscreengui->getHotbarSelection();
if (selection)
*new_playeritem = *selection;
}
#endif
// Clamp selection again in case it wasn't changed but max_item was
*new_playeritem = MYMIN(*new_playeritem, max_item);
@ -2369,7 +2368,9 @@ void Game::toggleFast()
m_game_ui->showTranslatedStatusText("Fast mode disabled");
}
m_touch_simulate_aux1 = fast_move && has_fast_privs;
#ifdef HAVE_TOUCHSCREENGUI
m_cache_hold_aux1 = fast_move && has_fast_privs;
#endif
}
@ -2454,14 +2455,26 @@ void Game::toggleMinimap(bool shift_pressed)
// -->
u32 hud_flags = client->getEnv().getLocalPlayer()->hud_flags;
if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) {
// If radar is disabled, try to find a non radar mode or fall back to 0
if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE))
while (mapper->getModeIndex() &&
mapper->getModeDef().type == MINIMAP_TYPE_RADAR)
mapper->nextMode();
}
m_game_ui->showStatusText(utf8_to_wide(mapper->getModeDef().label));
if (!(hud_flags & HUD_FLAG_MINIMAP_VISIBLE)) {
m_game_ui->m_flags.show_minimap = false;
} else {
// If radar is disabled, try to find a non radar mode or fall back to 0
if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE))
while (mapper->getModeIndex() &&
mapper->getModeDef().type == MINIMAP_TYPE_RADAR)
mapper->nextMode();
m_game_ui->m_flags.show_minimap = mapper->getModeDef().type != MINIMAP_TYPE_OFF;
// <--
// End of 'not so satifying code'
if ((hud_flags & HUD_FLAG_MINIMAP_VISIBLE) ||
(hud && hud->hasElementOfType(HUD_ELEM_MINIMAP)))
m_game_ui->showStatusText(utf8_to_wide(mapper->getModeDef().label));
else
m_game_ui->showTranslatedStatusText(
"Minimap currently disabled by game or mod");
}
}
void Game::toggleFog()
@ -2614,8 +2627,10 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
Since Minetest has its own code to synthesize mouse events from touch events,
this results in duplicated input. To avoid that, we don't enable relative
mouse mode if we're in touchscreen mode. */
#ifndef HAVE_TOUCHSCREENGUI
if (cur_control)
cur_control->setRelativeMode(!g_touchscreengui && !isMenuActive());
cur_control->setRelativeMode(!isMenuActive());
#endif
if ((device->isWindowActive() && device->isWindowFocused()
&& !isMenuActive()) || input->isRandom()) {
@ -2653,15 +2668,17 @@ f32 Game::getSensitivityScaleFactor() const
// Multiply by a constant such that it becomes 1.0 at 72 degree FOV and
// 16:9 aspect ratio to minimize disruption of existing sensitivity
// settings.
return std::tan(fov_y / 2.0f) * 1.3763819f;
return tan(fov_y / 2.0f) * 1.3763818698f;
}
void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
{
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
cam->camera_yaw += g_touchscreengui->getYawChange();
cam->camera_pitch += g_touchscreengui->getPitchChange();
} else {
#endif
v2s32 center(driver->getScreenSize().Width / 2, driver->getScreenSize().Height / 2);
v2s32 dist = input->getMousePos() - center;
@ -2675,7 +2692,9 @@ void Game::updateCameraOrientation(CameraOrientation *cam, float dtime)
if (dist.X != 0 || dist.Y != 0)
input->setMousePos(center.X, center.Y);
#ifdef HAVE_TOUCHSCREENGUI
}
#endif
if (m_cache_enable_joysticks) {
f32 sens_scale = getSensitivityScaleFactor();
@ -2716,18 +2735,20 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
client->activeObjectsReceived() && !player->isDead()) {
control.movement_speed = 1.0f;
// sideways movement only
float dx = std::sin(control.movement_direction);
control.movement_direction = std::atan2(dx, 1.0f);
float dx = sin(control.movement_direction);
control.movement_direction = atan2(dx, 1.0f);
}
#ifdef HAVE_TOUCHSCREENGUI
/* For touch, simulate holding down AUX1 (fast move) if the user has
* the fast_move setting toggled on. If there is an aux1 key defined for
* touch then its meaning is inverted (i.e. holding aux1 means walk and
* not fast)
*/
if (g_touchscreengui && m_touch_simulate_aux1) {
if (m_cache_hold_aux1) {
control.aux1 = control.aux1 ^ true;
}
#endif
client->setPlayerControl(control);
@ -2756,16 +2777,10 @@ inline void Game::step(f32 dtime)
g_settings->getFloat("fps_max_unfocused") :
g_settings->getFloat("fps_max");
fps_max = std::max(fps_max, 1.0f);
/*
* Unless you have a barebones game, running the server at more than 60Hz
* is hardly realistic and you're at the point of diminishing returns.
* fps_max is also not necessarily anywhere near the FPS actually achieved
* (also due to vsync).
*/
fps_max = std::min(fps_max, 60.0f);
float steplen = 1.0f / fps_max;
server->setStepSettings(Server::StepSettings{
1.0f / fps_max,
steplen,
m_is_paused
});
@ -3214,8 +3229,10 @@ void Game::updateCamera(f32 dtime)
camera->toggleCameraMode();
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->setUseCrosshair(!isTouchCrosshairDisabled());
g_touchscreengui->setUseCrosshair(!isNoCrosshairAllowed());
#endif
// Make the player visible depending on camera mode.
playercao->updateMeshCulling();
@ -3316,7 +3333,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
}
shootline.end = shootline.start + camera_direction * BS * d;
if (g_touchscreengui && isTouchCrosshairDisabled()) {
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui && isNoCrosshairAllowed()) {
shootline = g_touchscreengui->getShootline();
// Scale shootline to the acual distance the player can reach
shootline.end = shootline.start +
@ -3324,6 +3342,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
shootline.start += intToFloat(camera_offset, BS);
shootline.end += intToFloat(camera_offset, BS);
}
#endif
PointedThing pointed = updatePointedThing(shootline,
selected_def.liquids_pointable,
@ -3334,8 +3353,10 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud)
if (pointed != runData.pointed_old)
infostream << "Pointing at " << pointed.dump() << std::endl;
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->applyContextControls(selected_def.touch_interaction.getMode(pointed));
#endif
// Note that updating the selection mesh every frame is not particularly efficient,
// but the halo rendering code is already inefficient so there's no point in optimizing it here
@ -3713,11 +3734,11 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
break;
};
case NDT_SIGNLIKE: {
rotate90 = std::abs(pdir.X) < std::abs(pdir.Z);
rotate90 = abs(pdir.X) < abs(pdir.Z);
break;
}
default: {
rotate90 = std::abs(pdir.X) > std::abs(pdir.Z);
rotate90 = abs(pdir.X) > abs(pdir.Z);
break;
}
}
@ -4255,14 +4276,14 @@ void Game::updateShadows()
if (!shadow)
return;
float in_timeofday = std::fmod(runData.time_of_day_smooth, 1.0f);
float in_timeofday = fmod(runData.time_of_day_smooth, 1.0f);
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);
timeoftheday = std::fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
timeoftheday = fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
const float offset_constant = 10000.0f;
v3f light = is_day ? sky->getSunDirection() : sky->getMoonDirection();
@ -4318,12 +4339,12 @@ void Game::drawScene(ProfilerGraph *graph, RunStats *stats)
bool draw_crosshair = (
(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
(this->camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
if (g_touchscreengui && isTouchCrosshairDisabled())
#ifdef HAVE_TOUCHSCREENGUI
if (this->isNoCrosshairAllowed())
draw_crosshair = false;
#endif
this->m_rendering_engine->draw_scene(sky_color, this->m_game_ui->m_flags.show_hud,
draw_wield_tool, draw_crosshair);
this->m_game_ui->m_flags.show_minimap, draw_wield_tool, draw_crosshair);
/*
Profiler graph
@ -4469,23 +4490,21 @@ void Game::showDeathFormspec()
#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
void Game::showPauseMenu()
{
std::string control_text;
if (g_touchscreengui) {
control_text = strgettext("Controls:\n"
"No menu open:\n"
"- slide finger: look around\n"
"- tap: place/punch/use (default)\n"
"- long tap: dig/use (default)\n"
"Menu/inventory open:\n"
"- double tap (outside):\n"
" --> close\n"
"- touch stack, touch slot:\n"
" --> move stack\n"
"- touch&drag, tap 2nd finger\n"
" --> place single item to slot\n"
);
}
#ifdef HAVE_TOUCHSCREENGUI
static const std::string control_text = strgettext("Controls:\n"
"No menu open:\n"
"- slide finger: look around\n"
"- tap: place/punch/use (default)\n"
"- long tap: dig/use (default)\n"
"Menu/inventory open:\n"
"- double tap (outside):\n"
" --> close\n"
"- touch stack, touch slot:\n"
" --> move stack\n"
"- touch&drag, tap 2nd finger\n"
" --> place single item to slot\n"
);
#endif
float ypos = simple_singleplayer_mode ? 0.7f : 0.1f;
std::ostringstream os;
@ -4515,9 +4534,9 @@ void Game::showPauseMenu()
<< strgettext("Exit to Menu") << "]";
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_os;"
<< strgettext("Exit to OS") << "]";
if (!control_text.empty()) {
#ifdef HAVE_TOUCHSCREENGUI
os << "textarea[7.5,0.25;3.9,6.25;;" << control_text << ";]";
}
#endif
os << "textarea[0.4,0.25;3.9,6.25;;" << PROJECT_NAME_C " " VERSION_STRING "\n"
<< "\n"
<< strgettext("Game info:") << "\n";