diff --git a/src/client/game.cpp b/src/client/game.cpp index 48e9d9ea0..dd956c52b 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -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 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";