From e18b6c5a21880125284d2a1e9dfb5471d5bc2bec Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Wed, 22 Jan 2020 20:23:40 +0100 Subject: GUIFormSpecMenu: Shift+Click listring workaround for MacOS event.MouseInput.Shift is not implemented for MacOS --- src/gui/guiFormSpecMenu.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 632b15992..74578111e 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -4075,6 +4075,9 @@ enum ButtonEventType : u8 bool GUIFormSpecMenu::OnEvent(const SEvent& event) { + // WORKAROUND: event.MouseInput.Shift is not implemented for MacOS + static thread_local bool is_shift_down = false; + if (event.EventType==EET_KEY_INPUT_EVENT) { KeyPress kp(event.KeyInput); if (event.KeyInput.PressedDown && ( @@ -4084,6 +4087,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) return true; } + is_shift_down = event.KeyInput.Shift; + if (m_client != NULL && event.KeyInput.PressedDown && (kp == getKeySetting("keymap_screenshot"))) { m_client->makeScreenshot(); @@ -4133,6 +4138,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) event.MouseInput.isRightPressed() && getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) { + // WORKAROUND: In case shift was pressed prior showing the formspec + is_shift_down |= event.MouseInput.Shift; + // Get selected item and hovered/clicked item (s) m_old_tooltip_id = -1; @@ -4263,7 +4271,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) else // left count = s_count; - if (!event.MouseInput.Shift) { + if (!is_shift_down) { // no shift: select item m_selected_amount = count; m_selected_dragging = button != BET_WHEEL_DOWN; -- cgit v1.2.3 From f2c8c6bf51e608ad6f71710032b8ae017b84fd3d Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 13 Dec 2020 18:25:13 +0100 Subject: Revert "GUIFormSpecMenu: Shift+Click listring workaround for MacOS" The commit caused Shift-Clicking issues on Linux due to another Irrlicht bug where KeyInput.Shift released keys do not trigger OnEvent() MacOS users should build using a recent Irrlicht 1.8 development version. See also: https://sourceforge.net/p/irrlicht/patches/321/ --- src/gui/guiFormSpecMenu.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src') diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 74578111e..632b15992 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -4075,9 +4075,6 @@ enum ButtonEventType : u8 bool GUIFormSpecMenu::OnEvent(const SEvent& event) { - // WORKAROUND: event.MouseInput.Shift is not implemented for MacOS - static thread_local bool is_shift_down = false; - if (event.EventType==EET_KEY_INPUT_EVENT) { KeyPress kp(event.KeyInput); if (event.KeyInput.PressedDown && ( @@ -4087,8 +4084,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) return true; } - is_shift_down = event.KeyInput.Shift; - if (m_client != NULL && event.KeyInput.PressedDown && (kp == getKeySetting("keymap_screenshot"))) { m_client->makeScreenshot(); @@ -4138,9 +4133,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) event.MouseInput.isRightPressed() && getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) { - // WORKAROUND: In case shift was pressed prior showing the formspec - is_shift_down |= event.MouseInput.Shift; - // Get selected item and hovered/clicked item (s) m_old_tooltip_id = -1; @@ -4271,7 +4263,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) else // left count = s_count; - if (!is_shift_down) { + if (!event.MouseInput.Shift) { // no shift: select item m_selected_amount = count; m_selected_dragging = button != BET_WHEEL_DOWN; -- cgit v1.2.3 From 4d41ed09750c7a2fbfeeeccb7a2c3452e3dd26dc Mon Sep 17 00:00:00 2001 From: Zughy <63455151+Zughy@users.noreply.github.com> Date: Mon, 14 Dec 2020 23:49:30 +0100 Subject: Semi-transparent background for nametags (#10152) --- games/devtest/mods/testentities/visuals.lua | 29 +++++++++++++++++++++++++++++ src/client/camera.cpp | 27 ++++++++++++++++++--------- 2 files changed, 47 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/games/devtest/mods/testentities/visuals.lua b/games/devtest/mods/testentities/visuals.lua index 8848ba49f..e3b758329 100644 --- a/games/devtest/mods/testentities/visuals.lua +++ b/games/devtest/mods/testentities/visuals.lua @@ -94,3 +94,32 @@ minetest.register_entity("testentities:upright_animated", { self.object:set_sprite({x=0, y=0}, 4, 1.0, false) end, }) + +minetest.register_entity("testentities:nametag", { + initial_properties = { + visual = "sprite", + textures = { "testentities_sprite.png" }, + }, + + on_activate = function(self, staticdata) + if staticdata ~= "" then + self.color = minetest.deserialize(staticdata).color + else + self.color = { + r = math.random(0, 255), + g = math.random(0, 255), + b = math.random(0, 255), + } + end + + assert(self.color) + self.object:set_properties({ + nametag = tostring(math.random(1000, 10000)), + nametag_color = self.color, + }) + end, + + get_staticdata = function(self) + return minetest.serialize({ color = self.color }) + end, +}) diff --git a/src/client/camera.cpp b/src/client/camera.cpp index 11f8a1c90..9a08254b4 100644 --- a/src/client/camera.cpp +++ b/src/client/camera.cpp @@ -691,10 +691,11 @@ void Camera::drawNametags() core::matrix4 trans = m_cameranode->getProjectionMatrix(); trans *= m_cameranode->getViewMatrix(); - for (std::list::const_iterator - i = m_nametags.begin(); - i != m_nametags.end(); ++i) { - Nametag *nametag = *i; + gui::IGUIFont *font = g_fontengine->getFont(); + video::IVideoDriver *driver = RenderingEngine::get_video_driver(); + v2u32 screensize = driver->getScreenSize(); + + for (const Nametag *nametag : m_nametags) { if (nametag->nametag_color.getAlpha() == 0) { // Enforce hiding nametag, // because if freetype is enabled, a grey @@ -707,21 +708,29 @@ void Camera::drawNametags() if (transformed_pos[3] > 0) { std::wstring nametag_colorless = unescape_translate(utf8_to_wide(nametag->nametag_text)); - core::dimension2d textsize = - g_fontengine->getFont()->getDimension( + core::dimension2d textsize = font->getDimension( nametag_colorless.c_str()); f32 zDiv = transformed_pos[3] == 0.0f ? 1.0f : core::reciprocal(transformed_pos[3]); - v2u32 screensize = RenderingEngine::get_video_driver()->getScreenSize(); v2s32 screen_pos; screen_pos.X = screensize.X * (0.5 * transformed_pos[0] * zDiv + 0.5) - textsize.Width / 2; screen_pos.Y = screensize.Y * (0.5 - transformed_pos[1] * zDiv * 0.5) - textsize.Height / 2; core::rect size(0, 0, textsize.Width, textsize.Height); - g_fontengine->getFont()->draw( + core::rect bg_size(-2, 0, textsize.Width+2, textsize.Height); + + video::SColor textColor = nametag->nametag_color; + + bool darkBackground = textColor.getLuminance() > 186; + video::SColor backgroundColor = darkBackground + ? video::SColor(50, 50, 50, 50) + : video::SColor(50, 255, 255, 255); + driver->draw2DRectangle(backgroundColor, bg_size + screen_pos); + + font->draw( translate_string(utf8_to_wide(nametag->nametag_text)).c_str(), - size + screen_pos, nametag->nametag_color); + size + screen_pos, textColor); } } } -- cgit v1.2.3 From d0a38f694d483fbd9c0554c8d7175a94097fd67e Mon Sep 17 00:00:00 2001 From: Thomas--S Date: Tue, 15 Dec 2020 19:06:36 +0100 Subject: Formspec: Allow to specify frame loop for model[] (#10679) Add the ability to specify an animation frame loop range for the model[] formspec element. --- doc/lua_api.txt | 6 +++++- src/gui/guiFormSpecMenu.cpp | 21 ++++++++++++++++----- src/gui/guiScene.cpp | 9 +++++++++ src/gui/guiScene.h | 1 + 4 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f5c07fe85..ddb6d4e19 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2277,7 +2277,7 @@ Elements * `frame duration`: Milliseconds between each frame. `0` means the frames don't advance. * `frame start` (Optional): The index of the frame to start on. Default `1`. -### `model[,;,;;;;;;]` +### `model[,;,;;;;;;;]` * Show a mesh model. * `name`: Element name that can be used for styling @@ -2288,6 +2288,9 @@ Elements The axes are euler angles in degrees. * `continuous` (Optional): Whether the rotation is continuous. Default `false`. * `mouse control` (Optional): Whether the model can be controlled with the mouse. Default `true`. +* `frame loop range` (Optional): Range of the animation frames. + * Defaults to the full range of all available frames. + * Syntax: `,` ### `item_image[,;,;]` @@ -2789,6 +2792,7 @@ Some types may inherit styles from parent types. * image_button * item_image_button * label +* model * pwdfield, inherits from field * scrollbar * tabheader diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 632b15992..ed197d0d1 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -70,7 +70,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define MY_CHECKPOS(a,b) \ if (v_pos.size() != 2) { \ - errorstream<< "Invalid pos for element " << a << "specified: \"" \ + errorstream<< "Invalid pos for element " << a << " specified: \"" \ << parts[b] << "\"" << std::endl; \ return; \ } @@ -78,7 +78,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define MY_CHECKGEOM(a,b) \ if (v_geom.size() != 2) { \ errorstream<< "Invalid geometry for element " << a << \ - "specified: \"" << parts[b] << "\"" << std::endl; \ + " specified: \"" << parts[b] << "\"" << std::endl; \ return; \ } /* @@ -2725,7 +2725,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element) { std::vector parts = split(element, ';'); - if (parts.size() < 5 || (parts.size() > 8 && + if (parts.size() < 5 || (parts.size() > 9 && m_formspec_version <= FORMSPEC_API_VERSION)) { errorstream << "Invalid model element (" << parts.size() << "): '" << element << "'" << std::endl; @@ -2733,8 +2733,8 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element) } // Avoid length checks by resizing - if (parts.size() < 8) - parts.resize(8); + if (parts.size() < 9) + parts.resize(9); std::vector v_pos = split(parts[0], ','); std::vector v_geom = split(parts[1], ','); @@ -2744,6 +2744,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element) std::vector vec_rot = split(parts[5], ','); bool inf_rotation = is_yes(parts[6]); bool mousectrl = is_yes(parts[7]) || parts[7].empty(); // default true + std::vector frame_loop = split(parts[8], ','); MY_CHECKPOS("model", 0); MY_CHECKGEOM("model", 1); @@ -2794,6 +2795,16 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element) e->enableContinuousRotation(inf_rotation); e->enableMouseControl(mousectrl); + s32 frame_loop_begin = 0; + s32 frame_loop_end = 0x7FFFFFFF; + + if (frame_loop.size() == 2) { + frame_loop_begin = stoi(frame_loop[0]); + frame_loop_end = stoi(frame_loop[1]); + } + + e->setFrameLoop(frame_loop_begin, frame_loop_end); + auto style = getStyleForElement("model", spec.fname); e->setStyles(style); e->drop(); diff --git a/src/gui/guiScene.cpp b/src/gui/guiScene.cpp index 08f119e07..5f4c50b91 100644 --- a/src/gui/guiScene.cpp +++ b/src/gui/guiScene.cpp @@ -152,6 +152,15 @@ void GUIScene::setStyles(const std::array &sty setBackgroundColor(style.getColor(StyleSpec::BGCOLOR, m_bgcolor)); } +/** + * Sets the frame loop range for the mesh + */ +void GUIScene::setFrameLoop(s32 begin, s32 end) +{ + if (m_mesh->getStartFrame() != begin || m_mesh->getEndFrame() != end) + m_mesh->setFrameLoop(begin, end); +} + /* Camera control functions */ inline void GUIScene::calcOptimalDistance() diff --git a/src/gui/guiScene.h b/src/gui/guiScene.h index 707e6f66a..08eb7f350 100644 --- a/src/gui/guiScene.h +++ b/src/gui/guiScene.h @@ -36,6 +36,7 @@ public: scene::IAnimatedMeshSceneNode *setMesh(scene::IAnimatedMesh *mesh = nullptr); void setTexture(u32 idx, video::ITexture *texture); void setBackgroundColor(const video::SColor &color) noexcept { m_bgcolor = color; }; + void setFrameLoop(s32 begin, s32 end); void enableMouseControl(bool enable) noexcept { m_mouse_ctrl = enable; }; void setRotation(v2f rot) noexcept { m_custom_rot = rot; }; void enableContinuousRotation(bool enable) noexcept { m_inf_rot = enable; }; -- cgit v1.2.3 From e6380565236d6d963acf75538f1f8fec807190cc Mon Sep 17 00:00:00 2001 From: Lars Date: Wed, 9 Dec 2020 14:30:37 -0800 Subject: Allow configuring block disk and net compression. Change default disk level. --- builtin/settingtypes.txt | 14 ++++++++++++++ src/defaultsettings.cpp | 4 ++++ src/map.cpp | 8 +++++--- src/map.h | 3 ++- src/mapblock.cpp | 10 +++++----- src/mapblock.h | 2 +- src/mapgen/mg_schematic.cpp | 4 ++-- src/mapnode.cpp | 34 ++++++++++------------------------ src/mapnode.h | 4 ++-- src/server.cpp | 4 ++-- 10 files changed, 47 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index c9f16578c..251b6d868 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -1048,6 +1048,13 @@ full_block_send_enable_min_time_from_building (Delay in sending blocks after bui # client number. max_packets_per_iteration (Max. packets per iteration) int 1024 +# ZLib compression level to use when sending mapblocks to the client. +# -1 - Zlib's default compression level +# 0 - no compresson, fastest +# 9 - best compression, slowest +# (levels 1-3 use Zlib's "fast" method, 4-9 use the normal method) +map_compression_level_net (Map Compression Level for Network Transfer) int -1 -1 9 + [*Game] # Default game when creating a new world. @@ -1240,6 +1247,13 @@ max_objects_per_block (Maximum objects per block) int 64 # See https://www.sqlite.org/pragma.html#pragma_synchronous sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2 +# ZLib compression level to use when saving mapblocks to disk. +# -1 - Zlib's default compression level +# 0 - no compresson, fastest +# 9 - best compression, slowest +# (levels 1-3 use Zlib's "fast" method, 4-9 use the normal method) +map_compression_level_disk (Map Compression Level for Disk Storage) int 3 -1 9 + # Length of a server tick and the interval at which objects are generally updated over # network. dedicated_server_step (Dedicated server step) float 0.09 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 177955589..e13977fe3 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -385,6 +385,8 @@ void set_default_settings(Settings *settings) settings->setDefault("chat_message_limit_per_10sec", "8.0"); settings->setDefault("chat_message_limit_trigger_kick", "50"); settings->setDefault("sqlite_synchronous", "2"); + settings->setDefault("map_compression_level_disk", "3"); + settings->setDefault("map_compression_level_net", "-1"); settings->setDefault("full_block_send_enable_min_time_from_building", "2.0"); settings->setDefault("dedicated_server_step", "0.09"); settings->setDefault("active_block_mgmt_interval", "2.0"); @@ -470,6 +472,8 @@ void set_default_settings(Settings *settings) settings->setDefault("fps_max_unfocused", "10"); settings->setDefault("max_objects_per_block", "20"); settings->setDefault("sqlite_synchronous", "1"); + settings->setDefault("map_compression_level_disk", "-1"); + settings->setDefault("map_compression_level_net", "3"); settings->setDefault("server_map_save_interval", "15"); settings->setDefault("client_mapblock_limit", "1000"); settings->setDefault("active_block_range", "2"); diff --git a/src/map.cpp b/src/map.cpp index 37b6e9b6b..6a7cadca5 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1235,6 +1235,8 @@ ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef, m_save_time_counter = mb->addCounter("minetest_core_map_save_time", "Map save time (in nanoseconds)"); + m_map_compression_level = rangelim(g_settings->getS16("map_compression_level_disk"), -1, 9); + try { // If directory exists, check contents and load if possible if (fs::PathExists(m_savedir)) { @@ -1863,10 +1865,10 @@ void ServerMap::endSave() bool ServerMap::saveBlock(MapBlock *block) { - return saveBlock(block, dbase); + return saveBlock(block, dbase, m_map_compression_level); } -bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db) +bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db, int compression_level) { v3s16 p3d = block->getPos(); @@ -1886,7 +1888,7 @@ bool ServerMap::saveBlock(MapBlock *block, MapDatabase *db) */ std::ostringstream o(std::ios_base::binary); o.write((char*) &version, 1); - block->serialize(o, version, true); + block->serialize(o, version, true, compression_level); bool ret = db->saveBlock(p3d, o.str()); if (ret) { diff --git a/src/map.h b/src/map.h index 3bc30c482..c8bae9451 100644 --- a/src/map.h +++ b/src/map.h @@ -381,7 +381,7 @@ public: MapgenParams *getMapgenParams(); bool saveBlock(MapBlock *block); - static bool saveBlock(MapBlock *block, MapDatabase *db); + static bool saveBlock(MapBlock *block, MapDatabase *db, int compression_level = -1); MapBlock* loadBlock(v3s16 p); // Database version void loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool save_after_load=false); @@ -416,6 +416,7 @@ private: std::string m_savedir; bool m_map_saving_enabled; + int m_map_compression_level; #if 0 // Chunk size in MapSectors // If 0, chunks are disabled. diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 8bfecd755..0ca71e643 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -355,7 +355,7 @@ static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes, } } -void MapBlock::serialize(std::ostream &os, u8 version, bool disk) +void MapBlock::serialize(std::ostream &os, u8 version, bool disk, int compression_level) { if(!ser_ver_supported(version)) throw VersionMismatchException("ERROR: MapBlock format not supported"); @@ -394,7 +394,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) writeU8(os, content_width); writeU8(os, params_width); MapNode::serializeBulk(os, version, tmp_nodes, nodecount, - content_width, params_width, true); + content_width, params_width, compression_level); delete[] tmp_nodes; } else @@ -404,7 +404,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) writeU8(os, content_width); writeU8(os, params_width); MapNode::serializeBulk(os, version, data, nodecount, - content_width, params_width, true); + content_width, params_width, compression_level); } /* @@ -412,7 +412,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) */ std::ostringstream oss(std::ios_base::binary); m_node_metadata.serialize(oss, version, disk); - compressZlib(oss.str(), os); + compressZlib(oss.str(), os, compression_level); /* Data that goes to disk, but not the network @@ -485,7 +485,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk) if(params_width != 2) throw SerializationError("MapBlock::deSerialize(): invalid params_width"); MapNode::deSerializeBulk(is, version, data, nodecount, - content_width, params_width, true); + content_width, params_width); /* NodeMetadata diff --git a/src/mapblock.h b/src/mapblock.h index 6b5015cab..641a1b69b 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -482,7 +482,7 @@ public: // These don't write or read version by itself // Set disk to true for on-disk format, false for over-the-network format // Precondition: version >= SER_FMT_VER_LOWEST_WRITE - void serialize(std::ostream &os, u8 version, bool disk); + void serialize(std::ostream &os, u8 version, bool disk, int compression_level); // If disk == true: In addition to doing other things, will add // unknown blocks from id-name mapping to wndef void deSerialize(std::istream &is, u8 version, bool disk); diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp index dfd414709..e70e97e48 100644 --- a/src/mapgen/mg_schematic.cpp +++ b/src/mapgen/mg_schematic.cpp @@ -334,7 +334,7 @@ bool Schematic::deserializeFromMts(std::istream *is, schemdata = new MapNode[nodecount]; MapNode::deSerializeBulk(ss, SER_FMT_VER_HIGHEST_READ, schemdata, - nodecount, 2, 2, true); + nodecount, 2, 2); // Fix probability values for nodes that were ignore; removed in v2 if (version < 2) { @@ -376,7 +376,7 @@ bool Schematic::serializeToMts(std::ostream *os, // compressed bulk node data MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, - schemdata, size.X * size.Y * size.Z, 2, 2, true); + schemdata, size.X * size.Y * size.Z, 2, 2, -1); return true; } diff --git a/src/mapnode.cpp b/src/mapnode.cpp index dcf1f6d6e..0551f3b6f 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -706,7 +706,7 @@ void MapNode::deSerialize(u8 *source, u8 version) } void MapNode::serializeBulk(std::ostream &os, int version, const MapNode *nodes, u32 nodecount, - u8 content_width, u8 params_width, bool compressed) + u8 content_width, u8 params_width, int compression_level) { if (!ser_ver_supported(version)) throw VersionMismatchException("ERROR: MapNode format not supported"); @@ -737,10 +737,7 @@ void MapNode::serializeBulk(std::ostream &os, int version, Compress data to output stream */ - if (compressed) - compressZlib(databuf, databuf_size, os); - else - os.write((const char*) &databuf[0], databuf_size); + compressZlib(databuf, databuf_size, os, compression_level); delete [] databuf; } @@ -748,7 +745,7 @@ void MapNode::serializeBulk(std::ostream &os, int version, // Deserialize bulk node data void MapNode::deSerializeBulk(std::istream &is, int version, MapNode *nodes, u32 nodecount, - u8 content_width, u8 params_width, bool compressed) + u8 content_width, u8 params_width) { if(!ser_ver_supported(version)) throw VersionMismatchException("ERROR: MapNode format not supported"); @@ -760,24 +757,13 @@ void MapNode::deSerializeBulk(std::istream &is, int version, // Uncompress or read data u32 len = nodecount * (content_width + params_width); - SharedBuffer databuf(len); - if(compressed) - { - std::ostringstream os(std::ios_base::binary); - decompressZlib(is, os); - std::string s = os.str(); - if(s.size() != len) - throw SerializationError("deSerializeBulkNodes: " - "decompress resulted in invalid size"); - memcpy(&databuf[0], s.c_str(), len); - } - else - { - is.read((char*) &databuf[0], len); - if(is.eof() || is.fail()) - throw SerializationError("deSerializeBulkNodes: " - "failed to read bulk node data"); - } + std::ostringstream os(std::ios_base::binary); + decompressZlib(is, os); + std::string s = os.str(); + if(s.size() != len) + throw SerializationError("deSerializeBulkNodes: " + "decompress resulted in invalid size"); + const u8 *databuf = reinterpret_cast(s.c_str()); // Deserialize content if(content_width == 1) diff --git a/src/mapnode.h b/src/mapnode.h index 32ac1b4f6..a9ae63ba3 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -292,10 +292,10 @@ struct MapNode // compressed = true to zlib-compress output static void serializeBulk(std::ostream &os, int version, const MapNode *nodes, u32 nodecount, - u8 content_width, u8 params_width, bool compressed); + u8 content_width, u8 params_width, int compression_level); static void deSerializeBulk(std::istream &is, int version, MapNode *nodes, u32 nodecount, - u8 content_width, u8 params_width, bool compressed); + u8 content_width, u8 params_width); private: // Deprecated serialization methods diff --git a/src/server.cpp b/src/server.cpp index 8f6257afe..b5352749c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2332,9 +2332,9 @@ void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, /* Create a packet with the block in the right format */ - + thread_local const int net_compression_level = rangelim(g_settings->getS16("map_compression_level_net"), -1, 9); std::ostringstream os(std::ios_base::binary); - block->serialize(os, ver, false); + block->serialize(os, ver, false, net_compression_level); block->serializeNetworkSpecific(os); std::string s = os.str(); -- cgit v1.2.3 From 6f8a1c99d5a30de0021c2c03bb5f79eb8281f868 Mon Sep 17 00:00:00 2001 From: DS Date: Fri, 18 Dec 2020 19:38:07 +0100 Subject: Documentation for highest formspec_version[] and changelog (#10592) --- doc/lua_api.txt | 17 +++++++++++++++++ src/network/networkprotocol.h | 17 +---------------- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ddb6d4e19..708d6b0bc 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2113,6 +2113,22 @@ Examples list[current_player;main;0,3.5;8,4;] list[current_player;craft;3,0;3,3;] list[current_player;craftpreview;7,1;1,1;] + +Version History +--------------- + +* FORMSPEC VERSION 1: + * (too much) +* FORMSPEC VERSION 2: + * Forced real coordinates + * background9[]: 9-slice scaling parameters +* FORMSPEC VERSION 3: + * Formspec elements are drawn in the order of definition + * bgcolor[]: use 3 parameters (bgcolor, formspec (now an enum), fbgcolor) + * box[] and image[] elements enable clipping by default + * new element: scroll_container[] +* FORMSPEC VERSION 4: + * Allow dropdown indexing events Elements -------- @@ -2125,6 +2141,7 @@ Elements * Clients older than this version can neither show newer elements nor display elements with new arguments correctly. * Available since feature `formspec_version_element`. +* See also: [Version History] ### `size[,,]` diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 666e75e45..838bf0b2c 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -226,22 +226,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PASSWORD_SIZE 28 // Maximum password length. Allows for // base64-encoded SHA-1 (27+\0). -/* - Changes by FORMSPEC_API_VERSION: - - FORMSPEC VERSION 1: - (too much) - FORMSPEC VERSION 2: - Forced real coordinates - background9[]: 9-slice scaling parameters - FORMSPEC VERSION 3: - Formspec elements are drawn in the order of definition - bgcolor[]: use 3 parameters (bgcolor, formspec (now an enum), fbgcolor) - box[] and image[] elements enable clipping by default - new element: scroll_container[] - FORMSPEC VERSION 4: - Allow dropdown indexing events -*/ +// See also: Formspec Version History in doc/lua_api.txt #define FORMSPEC_API_VERSION 4 #define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-" -- cgit v1.2.3 From 664f5ce9605b580b9500547fff1e54eac553f295 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 19 Dec 2020 13:27:15 +0000 Subject: Add open user data button to main menu (#10579) --- .../java/net/minetest/minetest/GameActivity.java | 4 +-- builtin/mainmenu/tab_credits.lua | 20 +++++++++++-- doc/menu_lua_api.txt | 7 +++++ src/porting.cpp | 35 +++++++++++++++++----- src/porting.h | 20 ++++++++++++- src/porting_android.cpp | 6 ++-- src/porting_android.h | 2 +- src/script/lua_api/l_mainmenu.cpp | 21 ++++++++++++- src/script/lua_api/l_mainmenu.h | 4 +++ 9 files changed, 100 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java index db126a2b9..38a388230 100644 --- a/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java +++ b/build/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -142,8 +142,8 @@ public class GameActivity extends NativeActivity { return getResources().getDisplayMetrics().widthPixels; } - public void openURL(String url) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + public void openURI(String uri) { + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); startActivity(browserIntent); } } diff --git a/builtin/mainmenu/tab_credits.lua b/builtin/mainmenu/tab_credits.lua index c2b7e503a..075274798 100644 --- a/builtin/mainmenu/tab_credits.lua +++ b/builtin/mainmenu/tab_credits.lua @@ -100,9 +100,10 @@ return { cbf_formspec = function(tabview, name, tabdata) local logofile = defaulttexturedir .. "logo.png" local version = core.get_version() - return "image[0.5,1;" .. core.formspec_escape(logofile) .. "]" .. - "label[0.5,2.8;" .. version.project .. " " .. version.string .. "]" .. - "button[0.5,3;2,2;homepage;minetest.net]" .. + local fs = "image[0.75,0.5;2.2,2.2;" .. core.formspec_escape(logofile) .. "]" .. + "style[label_button;border=false]" .. + "button[0.5,2;2.5,2;label_button;" .. version.project .. " " .. version.string .. "]" .. + "button[0.75,2.75;2,2;homepage;minetest.net]" .. "tablecolumns[color;text]" .. "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. "table[3.5,-0.25;8.5,6.05;list_credits;" .. @@ -115,10 +116,23 @@ return { "#FFFF00," .. fgettext("Previous Contributors") .. ",," .. buildCreditList(previous_contributors) .. "," .. ";1]" + + if PLATFORM ~= "Android" then + fs = fs .. "tooltip[userdata;" .. + fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" .. + "and texture packs in a file manager / explorer.") .. "]" + fs = fs .. "button[0,4.75;3.5,1;userdata;" .. fgettext("Open User Data Directory") .. "]" + end + + return fs end, cbf_button_handler = function(this, fields, name, tabdata) if fields.homepage then core.open_url("https://www.minetest.net") end + + if fields.userdata then + core.open_dir(core.get_user_path()) + end end, } diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 76bebe08b..8908552d5 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -43,10 +43,14 @@ core.get_max_supp_proto() core.open_url(url) ^ opens the URL in a web browser, returns false on failure. ^ Must begin with http:// or https:// +core.open_dir(path) +^ opens the path in the system file browser/explorer, returns false on failure. +^ Must be an existing directory. core.get_version() (possible in async calls) ^ returns current core version + Filesystem ---------- @@ -207,6 +211,9 @@ Content and Packages Content - an installed mod, modpack, game, or texture pack (txt) Package - content which is downloadable from the content db, may or may not be installed. +* core.get_user_path() (possible in async calls) + * returns path to global user data, + the directory that contains user-provided mods, worlds, games, and texture packs. * core.get_modpath() (possible in async calls) * returns path to global modpath * core.get_clientmodpath() (possible in async calls) diff --git a/src/porting.cpp b/src/porting.cpp index e7ed4e090..4c87bddee 100644 --- a/src/porting.cpp +++ b/src/porting.cpp @@ -719,29 +719,48 @@ int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...) return c; } -bool openURL(const std::string &url) +static bool open_uri(const std::string &uri) { - if ((url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") || - url.find_first_of("\r\n") != std::string::npos) { - errorstream << "Invalid url: " << url << std::endl; + if (uri.find_first_of("\r\n") != std::string::npos) { + errorstream << "Unable to open URI as it is invalid, contains new line: " << uri << std::endl; return false; } #if defined(_WIN32) - return (intptr_t)ShellExecuteA(NULL, NULL, url.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; + return (intptr_t)ShellExecuteA(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL) > 32; #elif defined(__ANDROID__) - openURLAndroid(url); + openURIAndroid(uri); return true; #elif defined(__APPLE__) - const char *argv[] = {"open", url.c_str(), NULL}; + const char *argv[] = {"open", uri.c_str(), NULL}; return posix_spawnp(NULL, "open", NULL, NULL, (char**)argv, (*_NSGetEnviron())) == 0; #else - const char *argv[] = {"xdg-open", url.c_str(), NULL}; + const char *argv[] = {"xdg-open", uri.c_str(), NULL}; return posix_spawnp(NULL, "xdg-open", NULL, NULL, (char**)argv, environ) == 0; #endif } +bool open_url(const std::string &url) +{ + if (url.substr(0, 7) != "http://" && url.substr(0, 8) != "https://") { + errorstream << "Unable to open browser as URL is missing schema: " << url << std::endl; + return false; + } + + return open_uri(url); +} + +bool open_directory(const std::string &path) +{ + if (!fs::IsDir(path)) { + errorstream << "Unable to open directory as it does not exist: " << path << std::endl; + return false; + } + + return open_uri(path); +} + // Load performance counter frequency only once at startup #ifdef _WIN32 diff --git a/src/porting.h b/src/porting.h index c7adf12a2..e4ebe36fd 100644 --- a/src/porting.h +++ b/src/porting.h @@ -332,7 +332,25 @@ void attachOrCreateConsole(); int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...); -bool openURL(const std::string &url); +/** + * Opens URL in default web browser + * + * Must begin with http:// or https://, and not contain any new lines + * + * @param url The URL + * @return true on success, false on failure + */ +bool open_url(const std::string &url); + +/** + * Opens a directory in the default file manager + * + * The directory must exist. + * + * @param path Path to directory + * @return true on success, false on failure + */ +bool open_directory(const std::string &path); } // namespace porting diff --git a/src/porting_android.cpp b/src/porting_android.cpp index 41b521ec2..f5870c174 100644 --- a/src/porting_android.cpp +++ b/src/porting_android.cpp @@ -213,13 +213,13 @@ void showInputDialog(const std::string &acceptButton, const std::string &hint, jacceptButton, jhint, jcurrent, jeditType); } -void openURLAndroid(const std::string &url) +void openURIAndroid(const std::string &url) { - jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURL", + jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURI", "(Ljava/lang/String;)V"); FATAL_ERROR_IF(url_open == nullptr, - "porting::openURLAndroid unable to find java openURL method"); + "porting::openURIAndroid unable to find java openURI method"); jstring jurl = jnienv->NewStringUTF(url.c_str()); jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); diff --git a/src/porting_android.h b/src/porting_android.h index 6eb054041..239815922 100644 --- a/src/porting_android.h +++ b/src/porting_android.h @@ -58,7 +58,7 @@ void initializePathsAndroid(); void showInputDialog(const std::string &acceptButton, const std::string &hint, const std::string ¤t, int editType); -void openURLAndroid(const std::string &url); +void openURIAndroid(const std::string &url); /** * WORKAROUND for not working callbacks from java -> c++ diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 0aa2760e9..0b0b2de3b 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -686,6 +686,14 @@ int ModApiMainMenu::l_get_mapgen_names(lua_State *L) } +/******************************************************************************/ +int ModApiMainMenu::l_get_user_path(lua_State *L) +{ + std::string path = fs::RemoveRelativePathComponents(porting::path_user); + lua_pushstring(L, path.c_str()); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_get_modpath(lua_State *L) { @@ -1067,7 +1075,15 @@ int ModApiMainMenu::l_get_max_supp_proto(lua_State *L) int ModApiMainMenu::l_open_url(lua_State *L) { std::string url = luaL_checkstring(L, 1); - lua_pushboolean(L, porting::openURL(url)); + lua_pushboolean(L, porting::open_url(url)); + return 1; +} + +/******************************************************************************/ +int ModApiMainMenu::l_open_dir(lua_State *L) +{ + std::string path = luaL_checkstring(L, 1); + lua_pushboolean(L, porting::open_directory(path)); return 1; } @@ -1113,6 +1129,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(set_background); API_FCT(set_topleft_text); API_FCT(get_mapgen_names); + API_FCT(get_user_path); API_FCT(get_modpath); API_FCT(get_clientmodpath); API_FCT(get_gamepath); @@ -1134,6 +1151,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_min_supp_proto); API_FCT(get_max_supp_proto); API_FCT(open_url); + API_FCT(open_dir); API_FCT(do_async_callback); } @@ -1144,6 +1162,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) API_FCT(get_games); API_FCT(get_favorites); API_FCT(get_mapgen_names); + API_FCT(get_user_path); API_FCT(get_modpath); API_FCT(get_clientmodpath); API_FCT(get_gamepath); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 5a16b3bfe..faa2bf273 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -112,6 +112,8 @@ private: static int l_get_mainmenu_path(lua_State *L); + static int l_get_user_path(lua_State *L); + static int l_get_modpath(lua_State *L); static int l_get_clientmodpath(lua_State *L); @@ -148,6 +150,8 @@ private: // other static int l_open_url(lua_State *L); + static int l_open_dir(lua_State *L); + // async static int l_do_async_callback(lua_State *L); -- cgit v1.2.3 From ccbf8029ea6bfc5bb5d4af340bd4c2c0d58fe0ff Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Sat, 19 Dec 2020 22:57:10 +0300 Subject: Cleanup shader generation code (#10663) Shader generation is a mess. This commit cleans some parts up, including dropping remains of HLSL support which was never actually implemented. --- client/shaders/nodes_shader/opengl_fragment.glsl | 4 +- client/shaders/object_shader/opengl_fragment.glsl | 4 +- src/client/clientenvironment.cpp | 6 +- src/client/game.cpp | 6 +- src/client/hud.cpp | 2 +- src/client/minimap.cpp | 2 +- src/client/render/interlaced.cpp | 2 +- src/client/shader.cpp | 493 +++++++--------------- src/client/shader.h | 21 +- src/client/sky.cpp | 2 +- src/nodedef.cpp | 6 +- 11 files changed, 164 insertions(+), 384 deletions(-) (limited to 'src') diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index b0f6d45d0..b5d85da64 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -22,7 +22,7 @@ varying vec3 eyeVec; const float fogStart = FOG_START; const float fogShadingParameter = 1.0 / ( 1.0 - fogStart); -#ifdef ENABLE_TONE_MAPPING +#if ENABLE_TONE_MAPPING /* Hable's UC2 Tone mapping parameters A = 0.22; @@ -73,7 +73,7 @@ void main(void) vec4 col = vec4(color.rgb * varColor.rgb, 1.0); -#ifdef ENABLE_TONE_MAPPING +#if ENABLE_TONE_MAPPING col = applyToneMapping(col); #endif diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index bf18c1499..12cc54ae7 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -19,7 +19,7 @@ const float BS = 10.0; const float fogStart = FOG_START; const float fogShadingParameter = 1.0 / (1.0 - fogStart); -#ifdef ENABLE_TONE_MAPPING +#if ENABLE_TONE_MAPPING /* Hable's UC2 Tone mapping parameters A = 0.22; @@ -75,7 +75,7 @@ void main(void) col.rgb *= emissiveColor.rgb * vIDiff; -#ifdef ENABLE_TONE_MAPPING +#if ENABLE_TONE_MAPPING col = applyToneMapping(col); #endif diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index ea7be4200..da1e6e9c7 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -51,12 +51,8 @@ public: ~CAOShaderConstantSetter() override = default; - void onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel) override + void onSetConstants(video::IMaterialRendererServices *services) override { - if (!is_highlevel) - return; - // Ambient color video::SColorf emissive_color(m_emissive_color); diff --git a/src/client/game.cpp b/src/client/game.cpp index 575fd46ff..fd4d09394 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -475,12 +475,8 @@ public: g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this); } - virtual void onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel) + void onSetConstants(video::IMaterialRendererServices *services) override { - if (!is_highlevel) - return; - // Background color video::SColor bgcolor = m_sky->getBgColor(); video::SColorf bgcolorf(bgcolor); diff --git a/src/client/hud.cpp b/src/client/hud.cpp index f6497fe25..8d8411ca1 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -100,7 +100,7 @@ Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player, if (g_settings->getBool("enable_shaders")) { IShaderSource *shdrsrc = client->getShaderSource(); u16 shader_id = shdrsrc->getShader( - m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", 1, 1); + m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", TILE_MATERIAL_ALPHA); m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material; } else { m_selection_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index d068ad5f7..c6ccf86e8 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -612,7 +612,7 @@ void Minimap::drawMinimap(core::rect rect) { material.TextureLayer[1].Texture = data->heightmap_texture; if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) { - u16 sid = m_shdrsrc->getShader("minimap_shader", 1, 1); + u16 sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA); material.MaterialType = m_shdrsrc->getShaderInfo(sid).material; } else { material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; diff --git a/src/client/render/interlaced.cpp b/src/client/render/interlaced.cpp index 2aadadc17..ce8e92f21 100644 --- a/src/client/render/interlaced.cpp +++ b/src/client/render/interlaced.cpp @@ -36,7 +36,7 @@ void RenderingCoreInterlaced::initMaterial() mat.UseMipMaps = false; mat.ZBuffer = false; mat.ZWriteEnable = false; - u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC, 0); + u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC); mat.MaterialType = s->getShaderInfo(shader).material; for (int k = 0; k < 3; ++k) { mat.TextureLayer[k].AnisotropicFilter = false; diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 1cec20d2c..b3e4911f4 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "shader.h" #include "irrlichttypes_extrabloated.h" +#include "irr_ptr.h" #include "debug.h" #include "filesys.h" #include "util/container.h" @@ -189,19 +190,14 @@ private: class ShaderCallback : public video::IShaderConstantSetCallBack { - std::vector m_setters; + std::vector> m_setters; public: - ShaderCallback(const std::vector &factories) + template + ShaderCallback(const Factories &factories) { - for (IShaderConstantSetterFactory *factory : factories) - m_setters.push_back(factory->create()); - } - - ~ShaderCallback() - { - for (IShaderConstantSetter *setter : m_setters) - delete setter; + for (auto &&factory : factories) + m_setters.push_back(std::unique_ptr(factory->create())); } virtual void OnSetConstants(video::IMaterialRendererServices *services, s32 userData) override @@ -209,15 +205,13 @@ public: video::IVideoDriver *driver = services->getVideoDriver(); sanity_check(driver != NULL); - bool is_highlevel = userData; - - for (IShaderConstantSetter *setter : m_setters) - setter->onSetConstants(services, is_highlevel); + for (auto &&setter : m_setters) + setter->onSetConstants(services); } virtual void OnSetMaterial(const video::SMaterial& material) override { - for (IShaderConstantSetter *setter : m_setters) + for (auto &&setter : m_setters) setter->onSetMaterial(material); } }; @@ -252,47 +246,39 @@ public: {} ~MainShaderConstantSetter() = default; - virtual void onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel) + virtual void onSetConstants(video::IMaterialRendererServices *services) override { video::IVideoDriver *driver = services->getVideoDriver(); sanity_check(driver); // Set world matrix core::matrix4 world = driver->getTransform(video::ETS_WORLD); - if (is_highlevel) - m_world.set(*reinterpret_cast(world.pointer()), services); - else - services->setVertexShaderConstant(world.pointer(), 4, 4); + m_world.set(*reinterpret_cast(world.pointer()), services); // Set clip matrix core::matrix4 worldView; worldView = driver->getTransform(video::ETS_VIEW); worldView *= world; + core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_PROJECTION); worldViewProj *= worldView; - if (is_highlevel) - m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); - else - services->setVertexShaderConstant(worldViewProj.pointer(), 0, 4); + m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); #if ENABLE_GLES - if (is_highlevel) { - core::matrix4 texture = driver->getTransform(video::ETS_TEXTURE_0); - m_world_view.set(*reinterpret_cast(worldView.pointer()), services); - m_texture.set(*reinterpret_cast(texture.pointer()), services); - - core::matrix4 normal; - worldView.getTransposed(normal); - sanity_check(normal.makeInverse()); - float m[9] = { - normal[0], normal[1], normal[2], - normal[4], normal[5], normal[6], - normal[8], normal[9], normal[10], - }; - m_normal.set(m, services); - } + core::matrix4 texture = driver->getTransform(video::ETS_TEXTURE_0); + m_world_view.set(*reinterpret_cast(worldView.pointer()), services); + m_texture.set(*reinterpret_cast(texture.pointer()), services); + + core::matrix4 normal; + worldView.getTransposed(normal); + sanity_check(normal.makeInverse()); + float m[9] = { + normal[0], normal[1], normal[2], + normal[4], normal[5], normal[6], + normal[8], normal[9], normal[10], + }; + m_normal.set(m, services); #endif } }; @@ -314,7 +300,6 @@ class ShaderSource : public IWritableShaderSource { public: ShaderSource(); - ~ShaderSource(); /* - If shader material specified by name is found from cache, @@ -324,7 +309,7 @@ public: The id 0 points to a null shader. Its material is EMT_SOLID. */ u32 getShaderIdDirect(const std::string &name, - const u8 material_type, const u8 drawtype); + MaterialType material_type, NodeDrawType drawtype) override; /* If shader specified by the name pointed by the id doesn't @@ -336,26 +321,26 @@ public: */ u32 getShader(const std::string &name, - const u8 material_type, const u8 drawtype); + MaterialType material_type, NodeDrawType drawtype) override; - ShaderInfo getShaderInfo(u32 id); + ShaderInfo getShaderInfo(u32 id) override; // Processes queued shader requests from other threads. // Shall be called from the main thread. - void processQueue(); + void processQueue() override; // Insert a shader program into the cache without touching the // filesystem. Shall be called from the main thread. void insertSourceShader(const std::string &name_of_shader, - const std::string &filename, const std::string &program); + const std::string &filename, const std::string &program) override; // Rebuild shaders from the current set of source shaders // Shall be called from the main thread. - void rebuildShaders(); + void rebuildShaders() override; - void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) + void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) override { - m_setter_factories.push_back(setter); + m_setter_factories.push_back(std::unique_ptr(setter)); } private: @@ -377,10 +362,11 @@ private: RequestQueue m_get_shader_queue; // Global constant setter factories - std::vector m_setter_factories; + std::vector> m_setter_factories; - // Shader callbacks - std::vector m_callbacks; + // Generate shader given the shader name. + ShaderInfo generateShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype); }; IWritableShaderSource *createShaderSource() @@ -388,22 +374,6 @@ IWritableShaderSource *createShaderSource() return new ShaderSource(); } -/* - Generate shader given the shader name. -*/ -ShaderInfo generate_shader(const std::string &name, - u8 material_type, u8 drawtype, std::vector &callbacks, - const std::vector &setter_factories, - SourceShaderCache *sourcecache); - -/* - Load shader programs -*/ -void load_shaders(const std::string &name, SourceShaderCache *sourcecache, - video::E_DRIVER_TYPE drivertype, bool enable_shaders, - std::string &vertex_program, std::string &pixel_program, - std::string &geometry_program, bool &is_highlevel); - ShaderSource::ShaderSource() { m_main_thread = std::this_thread::get_id(); @@ -415,18 +385,8 @@ ShaderSource::ShaderSource() addShaderConstantSetterFactory(new MainShaderConstantSetterFactory()); } -ShaderSource::~ShaderSource() -{ - for (ShaderCallback *callback : m_callbacks) { - delete callback; - } - for (IShaderConstantSetterFactory *setter_factorie : m_setter_factories) { - delete setter_factorie; - } -} - u32 ShaderSource::getShader(const std::string &name, - const u8 material_type, const u8 drawtype) + MaterialType material_type, NodeDrawType drawtype) { /* Get shader @@ -468,7 +428,7 @@ u32 ShaderSource::getShader(const std::string &name, This method generates all the shaders */ u32 ShaderSource::getShaderIdDirect(const std::string &name, - const u8 material_type, const u8 drawtype) + MaterialType material_type, NodeDrawType drawtype) { //infostream<<"getShaderIdDirect(): name=\""<name.empty()) { - *info = generate_shader(info->name, info->material_type, - info->drawtype, m_callbacks, - m_setter_factories, &m_sourcecache); + *info = generateShader(info->name, info->material_type, info->drawtype); } } } -ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtype, - std::vector &callbacks, - const std::vector &setter_factories, - SourceShaderCache *sourcecache) +ShaderInfo ShaderSource::generateShader(const std::string &name, + MaterialType material_type, NodeDrawType drawtype) { ShaderInfo shaderinfo; shaderinfo.name = name; @@ -604,64 +559,27 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp return shaderinfo; video::IVideoDriver *driver = RenderingEngine::get_video_driver(); - - video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices(); - if(!gpu){ - errorstream<<"generate_shader(): " - "failed to generate \""<queryFeature(video::EVDF_ARB_GLSL)) { + errorstream << "Shaders are enabled but GLSL is not supported by the driver\n"; return shaderinfo; } - - // Choose shader language depending on driver type and settings - // Then load shaders - std::string vertex_program; - std::string pixel_program; - std::string geometry_program; - bool is_highlevel; - load_shaders(name, sourcecache, driver->getDriverType(), - enable_shaders, vertex_program, pixel_program, - geometry_program, is_highlevel); - // Check hardware/driver support - if (!vertex_program.empty() && - !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) && - !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)){ - infostream<<"generate_shader(): vertex shaders disabled " - "because of missing driver/hardware support." - <queryFeature(video::EVDF_PIXEL_SHADER_1_1) && - !driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)){ - infostream<<"generate_shader(): pixel shaders disabled " - "because of missing driver/hardware support." - <queryFeature(video::EVDF_GEOMETRY_SHADER)){ - infostream<<"generate_shader(): geometry shaders disabled " - "because of missing driver/hardware support." - <getGPUProgrammingServices(); // Create shaders header bool use_gles = false; #if ENABLE_GLES use_gles = driver->getDriverType() == video::EDT_OGLES2; #endif - std::string shaders_header, vertex_header, pixel_header; // geometry shaders aren’t supported in GLES<3 + std::stringstream shaders_header; + shaders_header + << std::noboolalpha + << std::showpoint // for GLSL ES + ; + std::string vertex_header, fragment_header, geometry_header; if (use_gles) { - shaders_header = - "#version 100\n" - ; + shaders_header << R"( + #version 100 + )"; vertex_header = R"( uniform highp mat4 mWorldView; uniform highp mat4 mWorldViewProj; @@ -675,11 +593,11 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp attribute mediump vec4 inVertexTangent; attribute mediump vec4 inVertexBinormal; )"; - pixel_header = R"( + fragment_header = R"( precision mediump float; )"; } else { - shaders_header = R"( + shaders_header << R"( #version 120 #define lowp #define mediump @@ -708,224 +626,97 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp use_discard = true; #endif if (use_discard && shaderinfo.base_material != video::EMT_SOLID) - shaders_header += "#define USE_DISCARD\n"; - - static const char* drawTypes[] = { - "NDT_NORMAL", - "NDT_AIRLIKE", - "NDT_LIQUID", - "NDT_FLOWINGLIQUID", - "NDT_GLASSLIKE", - "NDT_ALLFACES", - "NDT_ALLFACES_OPTIONAL", - "NDT_TORCHLIKE", - "NDT_SIGNLIKE", - "NDT_PLANTLIKE", - "NDT_FENCELIKE", - "NDT_RAILLIKE", - "NDT_NODEBOX", - "NDT_GLASSLIKE_FRAMED", - "NDT_FIRELIKE", - "NDT_GLASSLIKE_FRAMED_OPTIONAL", - "NDT_PLANTLIKE_ROOTED", - }; - - for (int i = 0; i < 14; i++){ - shaders_header += "#define "; - shaders_header += drawTypes[i]; - shaders_header += " "; - shaders_header += itos(i); - shaders_header += "\n"; - } - - static const char* materialTypes[] = { - "TILE_MATERIAL_BASIC", - "TILE_MATERIAL_ALPHA", - "TILE_MATERIAL_LIQUID_TRANSPARENT", - "TILE_MATERIAL_LIQUID_OPAQUE", - "TILE_MATERIAL_WAVING_LEAVES", - "TILE_MATERIAL_WAVING_PLANTS", - "TILE_MATERIAL_OPAQUE", - "TILE_MATERIAL_WAVING_LIQUID_BASIC", - "TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT", - "TILE_MATERIAL_WAVING_LIQUID_OPAQUE", - "TILE_MATERIAL_PLAIN", - "TILE_MATERIAL_PLAIN_ALPHA", - }; - - for (int i = 0; i < 12; i++){ - shaders_header += "#define "; - shaders_header += materialTypes[i]; - shaders_header += " "; - shaders_header += itos(i); - shaders_header += "\n"; - } - - shaders_header += "#define MATERIAL_TYPE "; - shaders_header += itos(material_type); - shaders_header += "\n"; - shaders_header += "#define DRAW_TYPE "; - shaders_header += itos(drawtype); - shaders_header += "\n"; - - if (g_settings->getBool("enable_waving_water")){ - shaders_header += "#define ENABLE_WAVING_WATER 1\n"; - shaders_header += "#define WATER_WAVE_HEIGHT "; - shaders_header += std::to_string(g_settings->getFloat("water_wave_height")); - shaders_header += "\n"; - shaders_header += "#define WATER_WAVE_LENGTH "; - shaders_header += std::to_string(g_settings->getFloat("water_wave_length")); - shaders_header += "\n"; - shaders_header += "#define WATER_WAVE_SPEED "; - shaders_header += std::to_string(g_settings->getFloat("water_wave_speed")); - shaders_header += "\n"; - } else{ - shaders_header += "#define ENABLE_WAVING_WATER 0\n"; - } - - shaders_header += "#define ENABLE_WAVING_LEAVES "; - if (g_settings->getBool("enable_waving_leaves")) - shaders_header += "1\n"; - else - shaders_header += "0\n"; - - shaders_header += "#define ENABLE_WAVING_PLANTS "; - if (g_settings->getBool("enable_waving_plants")) - shaders_header += "1\n"; - else - shaders_header += "0\n"; - - if (g_settings->getBool("tone_mapping")) - shaders_header += "#define ENABLE_TONE_MAPPING\n"; - - shaders_header += "#define FOG_START "; - shaders_header += std::to_string(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f)); - shaders_header += "\n"; - - // Call addHighLevelShaderMaterial() or addShaderMaterial() - const c8* vertex_program_ptr = 0; - const c8* pixel_program_ptr = 0; - const c8* geometry_program_ptr = 0; - if (!vertex_program.empty()) { - vertex_program = shaders_header + vertex_header + vertex_program; - vertex_program_ptr = vertex_program.c_str(); - } - if (!pixel_program.empty()) { - pixel_program = shaders_header + pixel_header + pixel_program; - pixel_program_ptr = pixel_program.c_str(); - } - if (!geometry_program.empty()) { - geometry_program = shaders_header + geometry_program; - geometry_program_ptr = geometry_program.c_str(); - } - ShaderCallback *cb = new ShaderCallback(setter_factories); - s32 shadermat = -1; - if(is_highlevel){ - infostream<<"Compiling high level shaders for "<addHighLevelShaderMaterial( - vertex_program_ptr, // Vertex shader program - "vertexMain", // Vertex shader entry point - video::EVST_VS_1_1, // Vertex shader version - pixel_program_ptr, // Pixel shader program - "pixelMain", // Pixel shader entry point - video::EPST_PS_1_2, // Pixel shader version - geometry_program_ptr, // Geometry shader program - "geometryMain", // Geometry shader entry point - video::EGST_GS_4_0, // Geometry shader version - scene::EPT_TRIANGLES, // Geometry shader input - scene::EPT_TRIANGLE_STRIP, // Geometry shader output - 0, // Support maximum number of vertices - cb, // Set-constant callback - shaderinfo.base_material, // Base material - 1 // Userdata passed to callback - ); - if(shadermat == -1){ - errorstream<<"generate_shader(): " - "failed to generate \""<addShaderMaterial( - vertex_program_ptr, // Vertex shader program - pixel_program_ptr, // Pixel shader program - cb, // Set-constant callback - shaderinfo.base_material, // Base material - 0 // Userdata passed to callback - ); - - if(shadermat == -1){ - errorstream<<"generate_shader(): " - "failed to generate \""<getBool("enable_waving_water"); + shaders_header << "#define ENABLE_WAVING_WATER " << enable_waving_water << "\n"; + if (enable_waving_water) { + shaders_header << "#define WATER_WAVE_HEIGHT " << g_settings->getFloat("water_wave_height") << "\n"; + shaders_header << "#define WATER_WAVE_LENGTH " << g_settings->getFloat("water_wave_length") << "\n"; + shaders_header << "#define WATER_WAVE_SPEED " << g_settings->getFloat("water_wave_speed") << "\n"; + } + + shaders_header << "#define ENABLE_WAVING_LEAVES " << g_settings->getBool("enable_waving_leaves") << "\n"; + shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n"; + shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n"; + + shaders_header << "#define FOG_START " << core::clamp(g_settings->getFloat("fog_start"), 0.0f, 0.99f) << "\n"; + + std::string common_header = shaders_header.str(); + + std::string vertex_shader = m_sourcecache.getOrLoad(name, "opengl_vertex.glsl"); + std::string fragment_shader = m_sourcecache.getOrLoad(name, "opengl_fragment.glsl"); + std::string geometry_shader = m_sourcecache.getOrLoad(name, "opengl_geometry.glsl"); + + vertex_shader = common_header + vertex_header + vertex_shader; + fragment_shader = common_header + fragment_header + fragment_shader; + const char *geometry_shader_ptr = nullptr; // optional + if (!geometry_shader.empty()) { + geometry_shader = common_header + geometry_header + geometry_shader; + geometry_shader_ptr = geometry_shader.c_str(); + } + + irr_ptr cb{new ShaderCallback(m_setter_factories)}; + infostream<<"Compiling high level shaders for "<addHighLevelShaderMaterial( + vertex_shader.c_str(), nullptr, video::EVST_VS_1_1, + fragment_shader.c_str(), nullptr, video::EPST_PS_1_1, + geometry_shader_ptr, nullptr, video::EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLES, 0, + cb.get(), shaderinfo.base_material, 1); + if (shadermat == -1) { + errorstream<<"generate_shader(): " + "failed to generate \""<getMaterialRenderer(shadermat)->grab(); // Apply the newly created material type shaderinfo.material = (video::E_MATERIAL_TYPE) shadermat; return shaderinfo; } -void load_shaders(const std::string &name, SourceShaderCache *sourcecache, - video::E_DRIVER_TYPE drivertype, bool enable_shaders, - std::string &vertex_program, std::string &pixel_program, - std::string &geometry_program, bool &is_highlevel) -{ - vertex_program = ""; - pixel_program = ""; - geometry_program = ""; - is_highlevel = false; - - if (!enable_shaders) - return; - - // Look for high level shaders - switch (drivertype) { - case video::EDT_DIRECT3D9: - // Direct3D 9: HLSL - // (All shaders in one file) - vertex_program = sourcecache->getOrLoad(name, "d3d9.hlsl"); - pixel_program = vertex_program; - geometry_program = vertex_program; - break; - - case video::EDT_OPENGL: -#if ENABLE_GLES - case video::EDT_OGLES2: -#endif - // OpenGL: GLSL - vertex_program = sourcecache->getOrLoad(name, "opengl_vertex.glsl"); - pixel_program = sourcecache->getOrLoad(name, "opengl_fragment.glsl"); - geometry_program = sourcecache->getOrLoad(name, "opengl_geometry.glsl"); - break; - - default: - // e.g. OpenGL ES 1 (with no shader support) - break; - } - if (!vertex_program.empty() || !pixel_program.empty() || !geometry_program.empty()){ - is_highlevel = true; - return; - } -} - void dumpShaderProgram(std::ostream &output_stream, const std::string &program_type, const std::string &program) { diff --git a/src/client/shader.h b/src/client/shader.h index 109d39336..d99182693 100644 --- a/src/client/shader.h +++ b/src/client/shader.h @@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "irrlichttypes_bloated.h" #include +#include "tile.h" +#include "nodedef.h" class IGameDef; @@ -46,8 +48,8 @@ struct ShaderInfo { std::string name = ""; video::E_MATERIAL_TYPE base_material = video::EMT_SOLID; video::E_MATERIAL_TYPE material = video::EMT_SOLID; - u8 drawtype = 0; - u8 material_type = 0; + NodeDrawType drawtype = NDT_NORMAL; + MaterialType material_type = TILE_MATERIAL_BASIC; ShaderInfo() = default; virtual ~ShaderInfo() = default; @@ -65,8 +67,7 @@ namespace irr { namespace video { class IShaderConstantSetter { public: virtual ~IShaderConstantSetter() = default; - virtual void onSetConstants(video::IMaterialRendererServices *services, - bool is_highlevel) = 0; + virtual void onSetConstants(video::IMaterialRendererServices *services) = 0; virtual void onSetMaterial(const video::SMaterial& material) { } }; @@ -128,10 +129,10 @@ public: virtual ~IShaderSource() = default; virtual u32 getShaderIdDirect(const std::string &name, - const u8 material_type, const u8 drawtype){return 0;} + MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;} virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();} virtual u32 getShader(const std::string &name, - const u8 material_type, const u8 drawtype){return 0;} + MaterialType material_type, NodeDrawType drawtype = NDT_NORMAL){return 0;} }; class IWritableShaderSource : public IShaderSource { @@ -139,16 +140,12 @@ public: IWritableShaderSource() = default; virtual ~IWritableShaderSource() = default; - virtual u32 getShaderIdDirect(const std::string &name, - const u8 material_type, const u8 drawtype){return 0;} - virtual ShaderInfo getShaderInfo(u32 id){return ShaderInfo();} - virtual u32 getShader(const std::string &name, - const u8 material_type, const u8 drawtype){return 0;} - virtual void processQueue()=0; virtual void insertSourceShader(const std::string &name_of_shader, const std::string &filename, const std::string &program)=0; virtual void rebuildShaders()=0; + + /// @note Takes ownership of @p setter. virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0; }; diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 9a2614eda..3a40321dd 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -65,7 +65,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc) : // Create materials m_materials[0] = baseMaterial(); - m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA, 0)).material; + m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA)).material; m_materials[0].Lighting = true; m_materials[0].ColorMaterial = video::ECM_NONE; diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 5c2e5cd09..80013192d 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -774,7 +774,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc bool is_liquid = false; - u8 material_type = (alpha == 255) ? + MaterialType material_type = (alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA; switch (drawtype) { @@ -892,7 +892,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc u32 tile_shader = shdsrc->getShader("nodes_shader", material_type, drawtype); - u8 overlay_material = material_type; + MaterialType overlay_material = material_type; if (overlay_material == TILE_MATERIAL_OPAQUE) overlay_material = TILE_MATERIAL_BASIC; else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE) @@ -913,7 +913,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc tdef[j].backface_culling, tsettings); } - u8 special_material = material_type; + MaterialType special_material = material_type; if (drawtype == NDT_PLANTLIKE_ROOTED) { if (waving == 1) special_material = TILE_MATERIAL_WAVING_PLANTS; -- cgit v1.2.3 From af22dd86e3867a35e9e5ab911faa6e1e7671729d Mon Sep 17 00:00:00 2001 From: Markus Date: Sat, 19 Dec 2020 22:01:05 +0100 Subject: Fix some more joystick issues (#10624) --- builtin/settingtypes.txt | 3 +++ minetest.conf.example | 3 +++ src/client/game.cpp | 4 +-- src/client/inputhandler.h | 2 +- src/client/joystick_controller.cpp | 50 ++++++++++++++++++++------------------ src/client/joystick_controller.h | 38 +++++++++++++---------------- src/defaultsettings.cpp | 1 + 7 files changed, 53 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 251b6d868..7060a0b6e 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -152,6 +152,9 @@ joystick_type (Joystick type) enum auto auto,generic,xbox # when holding down a joystick button combination. repeat_joystick_button_time (Joystick button repetition interval) float 0.17 0.001 +# The deadzone of the joystick +joystick_deadzone (Joystick deadzone) int 2048 + # The sensitivity of the joystick axes for moving the # ingame view frustum around. joystick_frustum_sensitivity (Joystick frustum sensitivity) float 170 diff --git a/minetest.conf.example b/minetest.conf.example index 6b315b6ea..086339037 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -129,6 +129,9 @@ # type: float min: 0.001 # repeat_joystick_button_time = 0.17 +# The deadzone of the joystick +# joystick_deadzone = 2048 + # The sensitivity of the joystick axes for moving the # ingame view frustum around. # type: float diff --git a/src/client/game.cpp b/src/client/game.cpp index fd4d09394..6151d2aa6 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3139,8 +3139,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) wasKeyDown(KeyType::DIG); wasKeyDown(KeyType::PLACE); - input->joystick.clearWasKeyDown(KeyType::DIG); - input->joystick.clearWasKeyDown(KeyType::PLACE); + input->joystick.clearWasKeyPressed(KeyType::DIG); + input->joystick.clearWasKeyPressed(KeyType::PLACE); input->joystick.clearWasKeyReleased(KeyType::DIG); input->joystick.clearWasKeyReleased(KeyType::PLACE); diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index def147a82..7487bbdc7 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -279,7 +279,7 @@ public: } virtual bool wasKeyPressed(GameKeyType k) { - return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyReleased(k); + return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyPressed(k); } virtual bool wasKeyReleased(GameKeyType k) { diff --git a/src/client/joystick_controller.cpp b/src/client/joystick_controller.cpp index 742115046..f61ae4ae6 100644 --- a/src/client/joystick_controller.cpp +++ b/src/client/joystick_controller.cpp @@ -37,7 +37,7 @@ bool JoystickAxisCmb::isTriggered(const irr::SEvent::SJoystickEvent &ev) const { s16 ax_val = ev.Axis[axis_to_compare]; - return (ax_val * direction < 0) && (thresh * direction > ax_val * direction); + return (ax_val * direction < -thresh); } // spares many characters @@ -48,7 +48,7 @@ JoystickLayout create_default_layout() { JoystickLayout jlo; - jlo.axes_dead_border = 1024; + jlo.axes_deadzone = g_settings->getU16("joystick_deadzone"); const JoystickAxisLayout axes[JA_COUNT] = { {0, 1}, // JA_SIDEWARD_MOVE @@ -93,14 +93,14 @@ JoystickLayout create_default_layout() // Now about the buttons simulated by the axes // Movement buttons, important for vessels - JLO_A_PB(KeyType::FORWARD, 1, 1, 1024); - JLO_A_PB(KeyType::BACKWARD, 1, -1, 1024); - JLO_A_PB(KeyType::LEFT, 0, 1, 1024); - JLO_A_PB(KeyType::RIGHT, 0, -1, 1024); + JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone); // Scroll buttons - JLO_A_PB(KeyType::HOTBAR_PREV, 2, -1, 1024); - JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, 1024); + JLO_A_PB(KeyType::HOTBAR_PREV, 2, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, jlo.axes_deadzone); return jlo; } @@ -109,7 +109,7 @@ JoystickLayout create_xbox_layout() { JoystickLayout jlo; - jlo.axes_dead_border = 7000; + jlo.axes_deadzone = 7000; const JoystickAxisLayout axes[JA_COUNT] = { {0, 1}, // JA_SIDEWARD_MOVE @@ -146,10 +146,10 @@ JoystickLayout create_xbox_layout() JLO_B_PB(KeyType::FREEMOVE, 1 << 16, 1 << 16); // down // Movement buttons, important for vessels - JLO_A_PB(KeyType::FORWARD, 1, 1, 1024); - JLO_A_PB(KeyType::BACKWARD, 1, -1, 1024); - JLO_A_PB(KeyType::LEFT, 0, 1, 1024); - JLO_A_PB(KeyType::RIGHT, 0, -1, 1024); + JLO_A_PB(KeyType::FORWARD, 1, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::BACKWARD, 1, -1, jlo.axes_deadzone); + JLO_A_PB(KeyType::LEFT, 0, 1, jlo.axes_deadzone); + JLO_A_PB(KeyType::RIGHT, 0, -1, jlo.axes_deadzone); return jlo; } @@ -219,16 +219,19 @@ bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev) for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) { if (keys_pressed[i]) { - if (!m_past_pressed_keys[i] && + if (!m_past_keys_pressed[i] && m_past_pressed_time[i] < m_internal_time - doubling_dtime) { - m_past_pressed_keys[i] = true; + m_past_keys_pressed[i] = true; m_past_pressed_time[i] = m_internal_time; } - } else if (m_pressed_keys[i]) { - m_past_released_keys[i] = true; + } else if (m_keys_down[i]) { + m_keys_released[i] = true; } - m_pressed_keys[i] = keys_pressed[i]; + if (keys_pressed[i] && !(m_keys_down[i])) + m_keys_pressed[i] = true; + + m_keys_down[i] = keys_pressed[i]; } for (size_t i = 0; i < JA_COUNT; i++) { @@ -236,23 +239,22 @@ bool JoystickController::handleEvent(const irr::SEvent::SJoystickEvent &ev) m_axes_vals[i] = ax_la.invert * ev.Axis[ax_la.axis_id]; } - return true; } void JoystickController::clear() { - m_pressed_keys.reset(); - m_past_pressed_keys.reset(); - m_past_released_keys.reset(); + m_keys_pressed.reset(); + m_keys_down.reset(); + m_past_keys_pressed.reset(); + m_keys_released.reset(); memset(m_axes_vals, 0, sizeof(m_axes_vals)); } s16 JoystickController::getAxisWithoutDead(JoystickAxis axis) { s16 v = m_axes_vals[axis]; - if (((v > 0) && (v < m_layout.axes_dead_border)) || - ((v < 0) && (v > -m_layout.axes_dead_border))) + if (abs(v) < m_layout.axes_deadzone) return 0; return v; } diff --git a/src/client/joystick_controller.h b/src/client/joystick_controller.h index 7baacd81b..3f361e4ef 100644 --- a/src/client/joystick_controller.h +++ b/src/client/joystick_controller.h @@ -96,7 +96,7 @@ struct JoystickLayout { std::vector button_keys; std::vector axis_keys; JoystickAxisLayout axes[JA_COUNT]; - s16 axes_dead_border; + s16 axes_deadzone; }; class JoystickController { @@ -111,37 +111,32 @@ public: bool wasKeyDown(GameKeyType b) { - bool r = m_past_pressed_keys[b]; - m_past_pressed_keys[b] = false; + bool r = m_past_keys_pressed[b]; + m_past_keys_pressed[b] = false; return r; } - bool getWasKeyDown(GameKeyType b) + + bool wasKeyReleased(GameKeyType b) { - return m_past_pressed_keys[b]; + return m_keys_released[b]; } - void clearWasKeyDown(GameKeyType b) + void clearWasKeyReleased(GameKeyType b) { - m_past_pressed_keys[b] = false; + m_keys_released[b] = false; } - bool wasKeyReleased(GameKeyType b) + bool wasKeyPressed(GameKeyType b) { - bool r = m_past_released_keys[b]; - m_past_released_keys[b] = false; - return r; - } - bool getWasKeyReleased(GameKeyType b) - { - return m_past_pressed_keys[b]; + return m_keys_pressed[b]; } - void clearWasKeyReleased(GameKeyType b) + void clearWasKeyPressed(GameKeyType b) { - m_past_pressed_keys[b] = false; + m_keys_pressed[b] = false; } bool isKeyDown(GameKeyType b) { - return m_pressed_keys[b]; + return m_keys_down[b]; } s16 getAxis(JoystickAxis axis) @@ -162,12 +157,13 @@ private: u8 m_joystick_id = 0; - std::bitset m_pressed_keys; + std::bitset m_keys_down; + std::bitset m_keys_pressed; f32 m_internal_time; f32 m_past_pressed_time[KeyType::INTERNAL_ENUM_COUNT]; - std::bitset m_past_pressed_keys; - std::bitset m_past_released_keys; + std::bitset m_past_keys_pressed; + std::bitset m_keys_released; }; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index e13977fe3..e8fb18e05 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -279,6 +279,7 @@ void set_default_settings(Settings *settings) settings->setDefault("joystick_type", ""); settings->setDefault("repeat_joystick_button_time", "0.17"); settings->setDefault("joystick_frustum_sensitivity", "170"); + settings->setDefault("joystick_deadzone", "2048"); // Main menu settings->setDefault("main_menu_path", ""); -- cgit v1.2.3 From 2c3593b51eef193eb543a08eb1e83c37e2fafe72 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 23 Dec 2020 16:39:29 +0000 Subject: Fix unsafe cast in l_object --- src/script/lua_api/l_object.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index bc59bd55c..4d7a1bc41 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1409,7 +1409,7 @@ int ObjectRef::l_set_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - PlayerSAO *playersao = (PlayerSAO *) getobject(ref); + PlayerSAO *playersao = getplayersao(ref); if (playersao == nullptr) return 0; @@ -1449,7 +1449,7 @@ int ObjectRef::l_get_physics_override(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - PlayerSAO *playersao = (PlayerSAO *)getobject(ref); + PlayerSAO *playersao = getplayersao(ref); if (playersao == nullptr) return 0; -- cgit v1.2.3 From 289425f6bd6cfe1f66218918d9d5bd1b9f89aa7c Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 20 Dec 2020 19:22:04 -0800 Subject: Minor profiler fixes. --- src/client/clientmap.cpp | 3 +++ src/profiler.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index fa47df3f4..b9e0cc2ce 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -290,6 +290,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) */ u32 vertex_count = 0; + u32 drawcall_count = 0; // For limiting number of mesh animations per frame u32 mesh_animate_count = 0; @@ -391,6 +392,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) } driver->setMaterial(list.m); + drawcall_count += list.bufs.size(); for (auto &pair : list.bufs) { scene::IMeshBuffer *buf = pair.second; @@ -411,6 +413,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) } g_profiler->avg(prefix + "vertices drawn [#]", vertex_count); + g_profiler->avg(prefix + "drawcalls [#]", drawcall_count); } static bool getVisibleBrightness(Map *map, const v3f &p0, v3f dir, float step, diff --git a/src/profiler.cpp b/src/profiler.cpp index be8be591e..d05b7abfe 100644 --- a/src/profiler.cpp +++ b/src/profiler.cpp @@ -38,7 +38,7 @@ ScopeProfiler::~ScopeProfiler() return; float duration_ms = m_timer->stop(true); - float duration = duration_ms / 1000.0; + float duration = duration_ms; if (m_profiler) { switch (m_type) { case SPT_ADD: -- cgit v1.2.3 From 74762470b2aa11a5271b846549ff14b86c1705d2 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Wed, 23 Dec 2020 22:03:49 +0100 Subject: Fix some minor code issues all over the place --- CMakeLists.txt | 8 +------- lib/lua/CMakeLists.txt | 13 ++----------- src/CMakeLists.txt | 23 ----------------------- src/client/content_cao.cpp | 4 ++-- src/client/game.cpp | 36 +++++------------------------------- src/client/hud.cpp | 6 +++--- src/client/mapblock_mesh.cpp | 4 ++-- src/client/tile.cpp | 7 +++++++ src/filesys.cpp | 22 ++++++++-------------- src/gui/touchscreengui.cpp | 3 +-- src/irrlicht_changes/CGUITTFont.h | 2 +- src/irrlicht_changes/irrUString.h | 4 ++-- src/mapgen/mapgen_v7.cpp | 2 +- src/mapgen/treegen.cpp | 3 ++- src/network/serverpackethandler.cpp | 2 +- src/nodedef.cpp | 2 +- src/script/cpp_api/s_security.cpp | 7 +++---- src/util/srp.cpp | 4 ++-- src/util/string.cpp | 2 +- 19 files changed, 45 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 78d551168..1d53fcffd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,9 @@ -cmake_minimum_required(VERSION 2.6) - -if(${CMAKE_VERSION} STREQUAL "2.8.2") - # Bug http://vtk.org/Bug/view.php?id=11020 - message(WARNING "CMake/CPack version 2.8.2 will not create working .deb packages!") -endif() +cmake_minimum_required(VERSION 3.5) # This can be read from ${PROJECT_NAME} after project() is called project(minetest) set(PROJECT_NAME_CAPITALIZED "Minetest") -# Works only for cmake 3.1 and greater set(CMAKE_CXX_STANDARD 11) set(GCC_MINIMUM_VERSION "4.8") set(CLANG_MINIMUM_VERSION "3.4") diff --git a/lib/lua/CMakeLists.txt b/lib/lua/CMakeLists.txt index 119dd6302..5d0dc0f70 100644 --- a/lib/lua/CMakeLists.txt +++ b/lib/lua/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 2.4 FATAL_ERROR) - project(lua C) set(LUA_VERSION_MAJOR 5) @@ -15,9 +13,8 @@ set(LIBS) if(APPLE) set(DEFAULT_POSIX TRUE) - set(DEFAULT_DLOPEN ON) - # use this on Mac OS X 10.3- - option(LUA_USE_MACOSX "Mac OS X 10.3-" OFF) + set(DEFAULT_DLOPEN OFF) + set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX") elseif(UNIX OR CYGWIN) set(DEFAULT_POSIX TRUE) elseif(WIN32) @@ -32,12 +29,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(DEFAULT_DLOPEN ON) endif() -# For "Mac OS X 10.3-" -if(LUA_USE_MACOSX) - set(COMMON_CFLAGS "${COMMON_CFLAGS} -DLUA_USE_MACOSX") - set(LUA_USE_DLOPEN FALSE) -endif(LUA_USE_MACOSX) - option(LUA_USE_DLOPEN "Enable dlopen support." ${DEFAULT_DLOPEN}) mark_as_advanced(LUA_USE_DLOPEN) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b8ce69f1d..b6bba6e8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required(VERSION 2.6) - project(minetest) INCLUDE(CheckIncludeFiles) @@ -124,27 +122,6 @@ option(ENABLE_FREETYPE "Enable FreeType2 (TrueType fonts and basic unicode suppo set(USE_FREETYPE FALSE) if(ENABLE_FREETYPE) -## -## Note: FindFreetype.cmake seems to have been fixed in recent versions of -## CMake. If issues persist, re-enable this workaround specificially for the -## failing platforms. -## -# if(UNIX) -# include(FindPkgConfig) -# if(PKG_CONFIG_FOUND) -# pkg_check_modules(FREETYPE QUIET freetype2) -# if(FREETYPE_FOUND) -# SET(FREETYPE_PKGCONFIG_FOUND TRUE) -# SET(FREETYPE_LIBRARY ${FREETYPE_LIBRARIES}) -# # Because CMake is idiotic -# string(REPLACE ";" " " FREETYPE_CFLAGS_STR ${FREETYPE_CFLAGS}) -# string(REPLACE ";" " " FREETYPE_LDFLAGS_STR ${FREETYPE_LDFLAGS}) -# endif(FREETYPE_FOUND) -# endif(PKG_CONFIG_FOUND) -# endif(UNIX) -# if(NOT FREETYPE_FOUND) -# find_package(Freetype) -# endif() find_package(Freetype) if(FREETYPE_FOUND) message(STATUS "Freetype enabled.") diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index c645900aa..c65977b44 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1165,7 +1165,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } } - if (!getParent() && std::fabs(m_prop.automatic_rotate) > 0.001) { + if (!getParent() && node && fabs(m_prop.automatic_rotate) > 0.001f) { // This is the child node's rotation. It is only used for automatic_rotate. v3f local_rot = node->getRotation(); local_rot.Y = modulo360f(local_rot.Y - dtime * core::RADTODEG * @@ -1174,7 +1174,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) } if (!getParent() && m_prop.automatic_face_movement_dir && - (fabs(m_velocity.Z) > 0.001 || fabs(m_velocity.X) > 0.001)) { + (fabs(m_velocity.Z) > 0.001f || fabs(m_velocity.X) > 0.001f)) { float target_yaw = atan2(m_velocity.Z, m_velocity.X) * 180 / M_PI + m_prop.automatic_face_movement_dir_offset; float max_rotation_per_sec = diff --git a/src/client/game.cpp b/src/client/game.cpp index 6151d2aa6..9e942f47a 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -186,7 +186,7 @@ struct LocalFormspecHandler : public TextDest return; } - if (m_client && m_client->modsLoaded()) + if (m_client->modsLoaded()) m_client->getScript()->on_formspec_input(m_formname, fields); } @@ -583,7 +583,7 @@ public: virtual IShaderConstantSetter* create() { - GameGlobalShaderConstantSetter *scs = new GameGlobalShaderConstantSetter( + auto *scs = new GameGlobalShaderConstantSetter( m_sky, m_force_fog_off, m_fog_range, m_client); if (!m_sky) created_nosky.push_back(scs); @@ -1338,7 +1338,7 @@ bool Game::createClient(const GameStartData &start_data) return false; } - GameGlobalShaderConstantSetterFactory *scsf = new GameGlobalShaderConstantSetterFactory( + auto *scsf = new GameGlobalShaderConstantSetterFactory( &m_flags.force_fog_off, &runData.fog_range, client); shader_src->addShaderConstantSetterFactory(scsf); @@ -1348,20 +1348,14 @@ bool Game::createClient(const GameStartData &start_data) /* Camera */ camera = new Camera(*draw_control, client); - if (!camera || !camera->successfullyCreated(*error_message)) + if (!camera->successfullyCreated(*error_message)) return false; client->setCamera(camera); /* Clouds */ - if (m_cache_enable_clouds) { + if (m_cache_enable_clouds) clouds = new Clouds(smgr, -1, time(0)); - if (!clouds) { - *error_message = "Memory allocation error (clouds)"; - errorstream << *error_message << std::endl; - return false; - } - } /* Skybox */ @@ -1369,12 +1363,6 @@ bool Game::createClient(const GameStartData &start_data) scsf->setSky(sky); skybox = NULL; // This is used/set later on in the main run loop - if (!sky) { - *error_message = "Memory allocation error sky"; - errorstream << *error_message << std::endl; - return false; - } - /* Pre-calculated values */ video::ITexture *t = texture_src->getTexture("crack_anylength.png"); @@ -1404,12 +1392,6 @@ bool Game::createClient(const GameStartData &start_data) hud = new Hud(guienv, client, player, &player->inventory); - if (!hud) { - *error_message = "Memory error: could not create HUD"; - errorstream << *error_message << std::endl; - return false; - } - mapper = client->getMinimap(); if (mapper && client->modsLoaded()) @@ -1431,11 +1413,6 @@ bool Game::initGui() // Chat backend and console gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(), -1, chat_backend, client, &g_menumgr); - if (!gui_chat_console) { - *error_message = "Could not allocate memory for chat console"; - errorstream << *error_message << std::endl; - return false; - } #ifdef HAVE_TOUCHSCREENGUI @@ -1492,9 +1469,6 @@ bool Game::connectToServer(const GameStartData &start_data, itemdef_manager, nodedef_manager, sound, eventmgr, connect_address.isIPv6(), m_game_ui.get()); - if (!client) - return false; - client->m_simple_singleplayer_mode = simple_singleplayer_mode; infostream << "Connecting to server at "; diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 8d8411ca1..e956c2738 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -1055,9 +1055,9 @@ void drawItemStack( if (def.type == ITEM_TOOL && item.wear != 0) { // Draw a progressbar - float barheight = rect.getHeight() / 16; - float barpad_x = rect.getWidth() / 16; - float barpad_y = rect.getHeight() / 16; + float barheight = static_cast(rect.getHeight()) / 16; + float barpad_x = static_cast(rect.getWidth()) / 16; + float barpad_y = static_cast(rect.getHeight()) / 16; core::rect progressrect( rect.UpperLeftCorner.X + barpad_x, diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index dac25a066..4c43fcb61 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -1201,13 +1201,13 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): MapBlockMesh::~MapBlockMesh() { for (scene::IMesh *m : m_mesh) { - if (m_enable_vbo && m) + if (m_enable_vbo) { for (u32 i = 0; i < m->getMeshBufferCount(); i++) { scene::IMeshBuffer *buf = m->getMeshBuffer(i); RenderingEngine::get_video_driver()->removeHardwareBuffer(buf); } + } m->drop(); - m = NULL; } delete m_minimap_mapblock; } diff --git a/src/client/tile.cpp b/src/client/tile.cpp index d03588b2b..37836d0df 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -1633,6 +1633,13 @@ bool TextureSource::generateImagePart(std::string part_of_name, /* IMPORTANT: When changing this, getTextureForMesh() needs to be * updated too. */ + if (!baseimg) { + errorstream << "generateImagePart(): baseimg == NULL " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + // Apply the "clean transparent" filter, if configured. if (g_settings->getBool("texture_clean_transparent")) imageCleanTransparent(baseimg, 127); diff --git a/src/filesys.cpp b/src/filesys.cpp index 2470b1b64..28a33f4d0 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -295,31 +295,26 @@ bool RecursiveDelete(const std::string &path) infostream<<"Removing \""<(argv)); // Execv shouldn't return. Failed. _exit(1); @@ -331,7 +326,6 @@ bool RecursiveDelete(const std::string &path) pid_t tpid; do{ tpid = wait(&child_status); - //if(tpid != child_pid) process_terminated(tpid); }while(tpid != child_pid); return (child_status == 0); } diff --git a/src/gui/touchscreengui.cpp b/src/gui/touchscreengui.cpp index 0d64aa618..e1a971462 100644 --- a/src/gui/touchscreengui.cpp +++ b/src/gui/touchscreengui.cpp @@ -881,8 +881,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event) s32 dyj = event.TouchInput.Y - m_screensize.Y + button_size * 5.0f / 2.0f; bool inside_joystick = (dxj * dxj + dyj * dyj <= button_size * button_size * 1.5 * 1.5); - if (m_joystick_has_really_moved || - (!m_joystick_has_really_moved && inside_joystick) || + if (m_joystick_has_really_moved || inside_joystick || (!m_fixed_joystick && distance_sq > m_touchscreen_threshold * m_touchscreen_threshold)) { m_joystick_has_really_moved = true; diff --git a/src/irrlicht_changes/CGUITTFont.h b/src/irrlicht_changes/CGUITTFont.h index cf64934a2..310f74f67 100644 --- a/src/irrlicht_changes/CGUITTFont.h +++ b/src/irrlicht_changes/CGUITTFont.h @@ -356,7 +356,7 @@ namespace gui load_flags = FT_LOAD_DEFAULT | FT_LOAD_RENDER; if (!useHinting()) load_flags |= FT_LOAD_NO_HINTING; if (!useAutoHinting()) load_flags |= FT_LOAD_NO_AUTOHINT; - if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO | FT_RENDER_MODE_MONO; + if (useMonochrome()) load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO; else load_flags |= FT_LOAD_TARGET_NORMAL; } u32 getWidthFromCharacter(wchar_t c) const; diff --git a/src/irrlicht_changes/irrUString.h b/src/irrlicht_changes/irrUString.h index b628c092c..09172ee6d 100644 --- a/src/irrlicht_changes/irrUString.h +++ b/src/irrlicht_changes/irrUString.h @@ -1331,7 +1331,7 @@ public: { u32 i; const uchar16_t* oa = other.c_str(); - for(i=0; array[i] && oa[i] && i < n; ++i) + for(i=0; i < n && array[i] && oa[i]; ++i) if (array[i] != oa[i]) return false; @@ -1350,7 +1350,7 @@ public: if (!str) return false; u32 i; - for(i=0; array[i] && str[i] && i < n; ++i) + for(i=0; i < n && array[i] && str[i]; ++i) if (array[i] != str[i]) return false; diff --git a/src/mapgen/mapgen_v7.cpp b/src/mapgen/mapgen_v7.cpp index cc5f5726d..91f004518 100644 --- a/src/mapgen/mapgen_v7.cpp +++ b/src/mapgen/mapgen_v7.cpp @@ -297,7 +297,7 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p) int iters = 256; while (iters > 0 && y <= max_spawn_y) { if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { - if (y <= water_level || y > max_spawn_y) + if (y <= water_level) return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point // y + 1 due to biome 'dust' diff --git a/src/mapgen/treegen.cpp b/src/mapgen/treegen.cpp index e633d800a..ec7771439 100644 --- a/src/mapgen/treegen.cpp +++ b/src/mapgen/treegen.cpp @@ -406,7 +406,8 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, v3f(position.X, position.Y, position.Z - 1), tree_definition ); - } if (!stack_orientation.empty()) { + } + if (!stack_orientation.empty()) { s16 size = 1; for (x = -size; x <= size; x++) for (y = -size; y <= size; y++) diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 3db4eb286..c636d01e1 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -316,7 +316,7 @@ void Server::handleCommand_Init2(NetworkPacket* pkt) // Send active objects { PlayerSAO *sao = getPlayerSAO(peer_id); - if (client && sao) + if (sao) SendActiveObjectRemoveAdd(client, sao); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 80013192d..f9d15a9f6 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -617,7 +617,7 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer, bool has_scale = tiledef.scale > 0; bool use_autoscale = tsettings.autoscale_mode == AUTOSCALE_FORCE || (tsettings.autoscale_mode == AUTOSCALE_ENABLE && !has_scale); - if (use_autoscale && layer->texture) { + if (use_autoscale) { auto texture_size = layer->texture->getOriginalSize(); float base_size = tsettings.node_texture_size; float size = std::fmin(texture_size.Width, texture_size.Height); diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 01333b941..63058d7c3 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -398,10 +398,9 @@ bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char lua_pushfstring(L, "%s: %s", path, strerror(errno)); return false; } - chunk_name = new char[strlen(display_name) + 2]; - chunk_name[0] = '@'; - chunk_name[1] = '\0'; - strcat(chunk_name, display_name); + size_t len = strlen(display_name) + 2; + chunk_name = new char[len]; + snprintf(chunk_name, len, "@%s", display_name); } size_t start = 0; diff --git a/src/util/srp.cpp b/src/util/srp.cpp index f4d369d68..ceb2fef9e 100644 --- a/src/util/srp.cpp +++ b/src/util/srp.cpp @@ -1015,10 +1015,10 @@ void srp_user_process_challenge(struct SRPUser *usr, goto cleanup_and_exit; *bytes_M = usr->M; - if (len_M) *len_M = hash_length(usr->hash_alg); + *len_M = hash_length(usr->hash_alg); } else { *bytes_M = NULL; - if (len_M) *len_M = 0; + *len_M = 0; } cleanup_and_exit: diff --git a/src/util/string.cpp b/src/util/string.cpp index 8381a29c5..3ac3b8cf0 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -633,7 +633,7 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color color_name = value; } - color_name = lowercase(value); + color_name = lowercase(color_name); std::map::const_iterator it; it = named_colors.colors.find(color_name); -- cgit v1.2.3 From 8f72d4b2940f0bd5486e38bd58127d14a1762be8 Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Thu, 24 Dec 2020 14:48:05 +0100 Subject: Fix minetest.is_nan --- builtin/common/misc_helpers.lua | 4 ++++ src/script/lua_api/l_util.cpp | 11 ----------- src/script/lua_api/l_util.h | 3 --- 3 files changed, 4 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index e29a9f422..0f3897f47 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -697,3 +697,7 @@ function core.privs_to_string(privs, delim) end return table.concat(list, delim) end + +function core.is_nan(number) + return number ~= number +end diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index cd63e20c2..6490eb578 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -239,15 +239,6 @@ int ModApiUtil::l_is_yes(lua_State *L) return 1; } -// is_nan(arg) -int ModApiUtil::l_is_nan(lua_State *L) -{ - NO_MAP_LOCK_REQUIRED; - - lua_pushboolean(L, isNaN(L, 1)); - return 1; -} - // get_builtin_path() int ModApiUtil::l_get_builtin_path(lua_State *L) { @@ -493,7 +484,6 @@ void ModApiUtil::Initialize(lua_State *L, int top) API_FCT(get_password_hash); API_FCT(is_yes); - API_FCT(is_nan); API_FCT(get_builtin_path); @@ -526,7 +516,6 @@ void ModApiUtil::InitializeClient(lua_State *L, int top) API_FCT(write_json); API_FCT(is_yes); - API_FCT(is_nan); API_FCT(compress); API_FCT(decompress); diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index 9ff91bb53..b6c1b58af 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -65,9 +65,6 @@ private: // is_yes(arg) static int l_is_yes(lua_State *L); - // is_nan(arg) - static int l_is_nan(lua_State *L); - // get_builtin_path() static int l_get_builtin_path(lua_State *L); -- cgit v1.2.3 From 09d7fbd645888aac32d089ff528ac1d1eb87e72d Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Thu, 24 Dec 2020 14:26:42 +0100 Subject: Fix item tooltip background color not working --- src/gui/guiFormSpecMenu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index ed197d0d1..61112b570 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -3718,7 +3718,8 @@ void GUIFormSpecMenu::showTooltip(const std::wstring &text, { EnrichedString ntext(text); ntext.setDefaultColor(color); - ntext.setBackground(bgcolor); + if (!ntext.hasBackground()) + ntext.setBackground(bgcolor); setStaticText(m_tooltip_element, ntext); -- cgit v1.2.3 From 9250b5205a6c627dfa18b7870b454d74f8d9dae6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein <54945686+EliasFleckenstein03@users.noreply.github.com> Date: Tue, 29 Dec 2020 16:50:09 +0100 Subject: Add minetest.get_objects_in_area (#10668) --- doc/lua_api.txt | 3 +++ src/script/lua_api/l_env.cpp | 26 ++++++++++++++++++++++++++ src/script/lua_api/l_env.h | 3 +++ src/server/activeobjectmgr.cpp | 15 +++++++++++++++ src/server/activeobjectmgr.h | 3 +++ src/serverenvironment.h | 7 +++++++ 6 files changed, 57 insertions(+) (limited to 'src') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 708d6b0bc..800fc0c24 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4891,6 +4891,9 @@ Environment access * `minetest.get_objects_inside_radius(pos, radius)`: returns a list of ObjectRefs. * `radius`: using an euclidean metric +* `minetest.get_objects_in_area(pos1, pos2)`: returns a list of + ObjectRefs. + * `pos1` and `pos2` are the min and max positions of the area to search. * `minetest.set_timeofday(val)` * `val` is between `0` and `1`; `0` for midnight, `0.5` for midday * `minetest.get_timeofday()` diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 021ef2ea7..c75fc8dc7 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -743,6 +743,31 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L) return 1; } +// get_objects_in_area(pos, minp, maxp) +int ModApiEnvMod::l_get_objects_in_area(lua_State *L) +{ + GET_ENV_PTR; + ScriptApiBase *script = getScriptApiBase(L); + + v3f minp = read_v3f(L, 1) * BS; + v3f maxp = read_v3f(L, 2) * BS; + aabb3f box(minp, maxp); + box.repair(); + std::vector objs; + + auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); }; + env->getObjectsInArea(objs, box, include_obj_cb); + + int i = 0; + lua_createtable(L, objs.size(), 0); + for (const auto obj : objs) { + // Insert object reference into table + script->objectrefGetOrCreate(L, obj); + lua_rawseti(L, -2, ++i); + } + return 1; +} + // set_timeofday(val) // val = 0...1 int ModApiEnvMod::l_set_timeofday(lua_State *L) @@ -1413,6 +1438,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(get_node_timer); API_FCT(get_connected_players); API_FCT(get_player_by_name); + API_FCT(get_objects_in_area); API_FCT(get_objects_inside_radius); API_FCT(set_timeofday); API_FCT(get_timeofday); diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index 7f212b5fc..42c2d64f8 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -114,6 +114,9 @@ private: // get_objects_inside_radius(pos, radius) static int l_get_objects_inside_radius(lua_State *L); + + // get_objects_in_area(pos, minp, maxp) + static int l_get_objects_in_area(lua_State *L); // set_timeofday(val) // val = 0...1 diff --git a/src/server/activeobjectmgr.cpp b/src/server/activeobjectmgr.cpp index 1b8e31409..acd6611f4 100644 --- a/src/server/activeobjectmgr.cpp +++ b/src/server/activeobjectmgr.cpp @@ -127,6 +127,21 @@ void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius, } } +void ActiveObjectMgr::getObjectsInArea(const aabb3f &box, + std::vector &result, + std::function include_obj_cb) +{ + for (auto &activeObject : m_active_objects) { + ServerActiveObject *obj = activeObject.second; + const v3f &objectpos = obj->getBasePosition(); + if (!box.isPointInside(objectpos)) + continue; + + if (!include_obj_cb || include_obj_cb(obj)) + result.push_back(obj); + } +} + void ActiveObjectMgr::getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, f32 player_radius, std::set ¤t_objects, std::queue &added_objects) diff --git a/src/server/activeobjectmgr.h b/src/server/activeobjectmgr.h index bc2085499..d43f5643c 100644 --- a/src/server/activeobjectmgr.h +++ b/src/server/activeobjectmgr.h @@ -38,6 +38,9 @@ public: void getObjectsInsideRadius(const v3f &pos, float radius, std::vector &result, std::function include_obj_cb); + void getObjectsInArea(const aabb3f &box, + std::vector &result, + std::function include_obj_cb); void getAddedActiveObjectsAroundPos(const v3f &player_pos, f32 radius, f32 player_radius, std::set ¤t_objects, diff --git a/src/serverenvironment.h b/src/serverenvironment.h index cfd5b8f3e..c76d34a37 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -331,6 +331,13 @@ public: { return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb); } + + // Find all active objects inside a box + void getObjectsInArea(std::vector &objects, const aabb3f &box, + std::function include_obj_cb) + { + return m_ao_manager.getObjectsInArea(box, objects, include_obj_cb); + } // Clear objects, loading and going through every MapBlock void clearObjects(ClearObjectsMode mode); -- cgit v1.2.3 From ff921f6989cc6e8e0be6bf9ac196e90331bb3eb4 Mon Sep 17 00:00:00 2001 From: Jean-Patrick Guerrero Date: Fri, 1 Jan 2021 17:03:34 +0100 Subject: Formspecs: Fix broken texture escaping with model[] --- src/gui/guiFormSpecMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 61112b570..973fc60a8 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -2787,7 +2787,7 @@ void GUIFormSpecMenu::parseModel(parserData *data, const std::string &element) auto meshnode = e->setMesh(mesh); for (u32 i = 0; i < textures.size() && i < meshnode->getMaterialCount(); ++i) - e->setTexture(i, m_tsrc->getTexture(textures[i])); + e->setTexture(i, m_tsrc->getTexture(unescape_string(textures[i]))); if (vec_rot.size() >= 2) e->setRotation(v2f(stof(vec_rot[0]), stof(vec_rot[1]))); -- cgit v1.2.3 From dd5a732fa90550066bb96305b64b6648903cc822 Mon Sep 17 00:00:00 2001 From: hecks <42101236+hecktest@users.noreply.github.com> Date: Sat, 2 Jan 2021 15:14:29 +0100 Subject: Add on_deactivate callback for luaentities (#10723) --- builtin/profiler/instrumentation.lua | 1 + doc/lua_api.txt | 2 ++ games/devtest/mods/testentities/callbacks.lua | 3 ++ src/script/cpp_api/s_entity.cpp | 26 ++++++++++++++ src/script/cpp_api/s_entity.h | 1 + src/script/lua_api/l_object.cpp | 2 +- src/server/luaentity_sao.cpp | 13 +++++-- src/server/luaentity_sao.h | 5 +++ src/server/player_sao.cpp | 2 +- src/server/serveractiveobject.cpp | 16 +++++++++ src/server/serveractiveobject.h | 50 +++++++++++++++++---------- src/serverenvironment.cpp | 12 ++++--- 12 files changed, 106 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/builtin/profiler/instrumentation.lua b/builtin/profiler/instrumentation.lua index 237f048fb..6b951a2c2 100644 --- a/builtin/profiler/instrumentation.lua +++ b/builtin/profiler/instrumentation.lua @@ -160,6 +160,7 @@ local function init() -- Simple iteration would ignore lookup via __index. local entity_instrumentation = { "on_activate", + "on_deactivate", "on_step", "on_punch", "on_rightclick", diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 8bf6ade69..47c2776e6 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4207,6 +4207,8 @@ Callbacks: * Called when the object is instantiated. * `dtime_s` is the time passed since the object was unloaded, which can be used for updating the entity state. +* `on_deactivate(self) + * Called when the object is about to get removed or unloaded. * `on_step(self, dtime)` * Called on every server tick, after movement and collision processing. `dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting diff --git a/games/devtest/mods/testentities/callbacks.lua b/games/devtest/mods/testentities/callbacks.lua index 711079f87..320690b39 100644 --- a/games/devtest/mods/testentities/callbacks.lua +++ b/games/devtest/mods/testentities/callbacks.lua @@ -31,6 +31,9 @@ minetest.register_entity("testentities:callback", { on_activate = function(self, staticdata, dtime_s) message("Callback entity: on_activate! pos="..spos(self).."; dtime_s="..dtime_s) end, + on_deactivate = function(self) + message("Callback entity: on_deactivate! pos="..spos(self)) + end, on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) local name = get_object_name(puncher) message( diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index ea9320051..746f7013e 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -103,6 +103,32 @@ void ScriptApiEntity::luaentity_Activate(u16 id, lua_pop(L, 2); // Pop object and error handler } +void ScriptApiEntity::luaentity_Deactivate(u16 id) +{ + SCRIPTAPI_PRECHECKHEADER + + verbosestream << "scriptapi_luaentity_deactivate: id=" << id << std::endl; + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get the entity + luaentity_get(L, id); + int object = lua_gettop(L); + + // Get on_deactivate + lua_getfield(L, -1, "on_deactivate"); + if (!lua_isnil(L, -1)) { + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 1, 0, error_handler)); + } else { + lua_pop(L, 1); + } + lua_pop(L, 2); // Pop object and error handler +} + void ScriptApiEntity::luaentity_Remove(u16 id) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_entity.h b/src/script/cpp_api/s_entity.h index b5f7a6586..b52f6e447 100644 --- a/src/script/cpp_api/s_entity.h +++ b/src/script/cpp_api/s_entity.h @@ -33,6 +33,7 @@ public: bool luaentity_Add(u16 id, const char *name); void luaentity_Activate(u16 id, const std::string &staticdata, u32 dtime_s); + void luaentity_Deactivate(u16 id); void luaentity_Remove(u16 id); std::string luaentity_GetStaticdata(u16 id); void luaentity_GetProperties(u16 id, diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 4d7a1bc41..f52e4892e 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -110,7 +110,7 @@ int ObjectRef::l_remove(lua_State *L) sao->clearParentAttachment(); verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl; - sao->m_pending_removal = true; + sao->markForRemoval(); return 0; } diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index b39797531..c7277491a 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -112,6 +112,15 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) } } +void LuaEntitySAO::dispatchScriptDeactivate() +{ + // Ensure that this is in fact a registered entity, + // and that it isn't already gone. + // The latter also prevents this from ever being called twice. + if (m_registered && !isGone()) + m_env->getScriptIface()->luaentity_Deactivate(m_id); +} + void LuaEntitySAO::step(float dtime, bool send_recommended) { if(!m_properties_sent) @@ -302,7 +311,7 @@ u16 LuaEntitySAO::punch(v3f dir, { if (!m_registered) { // Delete unknown LuaEntities when punched - m_pending_removal = true; + markForRemoval(); return 0; } @@ -335,7 +344,7 @@ u16 LuaEntitySAO::punch(v3f dir, clearParentAttachment(); clearChildAttachments(); m_env->getScriptIface()->luaentity_on_death(m_id, puncher); - m_pending_removal = true; + markForRemoval(); } actionstream << puncher->getDescription() << " (id=" << puncher->getId() << diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h index e060aa06d..6883ae1b9 100644 --- a/src/server/luaentity_sao.h +++ b/src/server/luaentity_sao.h @@ -71,6 +71,11 @@ public: bool getSelectionBox(aabb3f *toset) const; bool collideWithObjects() const; +protected: + void dispatchScriptDeactivate(); + virtual void onMarkedForDeactivation() { dispatchScriptDeactivate(); } + virtual void onMarkedForRemoval() { dispatchScriptDeactivate(); } + private: std::string getPropertyPacket(); void sendPosition(bool do_interpolate, bool is_movement_end); diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 62515d1c9..232c6a01d 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -531,7 +531,7 @@ bool PlayerSAO::setWieldedItem(const ItemStack &item) void PlayerSAO::disconnected() { m_peer_id = PEER_ID_INEXISTENT; - m_pending_removal = true; + markForRemoval(); } void PlayerSAO::unlinkPlayerSessionAndSave() diff --git a/src/server/serveractiveobject.cpp b/src/server/serveractiveobject.cpp index 8cb59b2d6..96b433d1d 100644 --- a/src/server/serveractiveobject.cpp +++ b/src/server/serveractiveobject.cpp @@ -73,3 +73,19 @@ void ServerActiveObject::dumpAOMessagesToQueue(std::queue & m_messages_out.pop(); } } + +void ServerActiveObject::markForRemoval() +{ + if (!m_pending_removal) { + onMarkedForRemoval(); + m_pending_removal = true; + } +} + +void ServerActiveObject::markForDeactivation() +{ + if (!m_pending_deactivation) { + onMarkedForDeactivation(); + m_pending_deactivation = true; + } +} diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h index 2764d159e..25653a1ad 100644 --- a/src/server/serveractiveobject.h +++ b/src/server/serveractiveobject.h @@ -70,6 +70,10 @@ public: virtual bool environmentDeletes() const { return true; } + // Safely mark the object for removal or deactivation + void markForRemoval(); + void markForDeactivation(); + // Create a certain type of ServerActiveObject static ServerActiveObject* create(ActiveObjectType type, ServerEnvironment *env, u16 id, v3f pos, @@ -213,25 +217,6 @@ public: */ u16 m_known_by_count = 0; - /* - - Whether this object is to be removed when nobody knows about - it anymore. - - Removal is delayed to preserve the id for the time during which - it could be confused to some other object by some client. - - This is usually set to true by the step() method when the object wants - to be deleted but can be set by anything else too. - */ - bool m_pending_removal = false; - - /* - Same purpose as m_pending_removal but for deactivation. - deactvation = save static data in block, remove active object - - If this is set alongside with m_pending_removal, removal takes - priority. - */ - bool m_pending_deactivation = false; - /* A getter that unifies the above to answer the question: "Can the environment still interact with this object?" @@ -239,6 +224,9 @@ public: inline bool isGone() const { return m_pending_removal || m_pending_deactivation; } + inline bool isPendingRemoval() const + { return m_pending_removal; } + /* Whether the object's static data has been stored to a block */ @@ -250,6 +238,9 @@ public: v3s16 m_static_block = v3s16(1337,1337,1337); protected: + virtual void onMarkedForDeactivation() {} + virtual void onMarkedForRemoval() {} + virtual void onAttach(int parent_id) {} virtual void onDetach(int parent_id) {} @@ -257,6 +248,27 @@ protected: v3f m_base_position; std::unordered_set m_attached_particle_spawners; + /* + Same purpose as m_pending_removal but for deactivation. + deactvation = save static data in block, remove active object + + If this is set alongside with m_pending_removal, removal takes + priority. + Note: Do not assign this directly, use markForDeactivation() instead. + */ + bool m_pending_deactivation = false; + + /* + - Whether this object is to be removed when nobody knows about + it anymore. + - Removal is delayed to preserve the id for the time during which + it could be confused to some other object by some client. + - This is usually set to true by the step() method when the object wants + to be deleted but can be set by anything else too. + Note: Do not assign this directly, use markForRemoval() instead. + */ + bool m_pending_removal = false; + /* Queue of messages to be sent to the client */ diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index d044b003d..56dbb0632 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -1164,7 +1164,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode) // If known by some client, don't delete immediately if (obj->m_known_by_count > 0) { - obj->m_pending_removal = true; + obj->markForRemoval(); return false; } @@ -1792,7 +1792,7 @@ void ServerEnvironment::removeRemovedObjects() /* Delete static data from block if removed */ - if (obj->m_pending_removal) + if (obj->isPendingRemoval()) deleteStaticFromBlock(obj, id, MOD_REASON_REMOVE_OBJECTS_REMOVE, false); // If still known by clients, don't actually remove. On some future @@ -1803,7 +1803,7 @@ void ServerEnvironment::removeRemovedObjects() /* Move static data from active to stored if deactivated */ - if (!obj->m_pending_removal && obj->m_static_exists) { + if (!obj->isPendingRemoval() && obj->m_static_exists) { MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); if (block) { const auto i = block->m_static_objects.m_active.find(id); @@ -1991,6 +1991,7 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) if (!force_delete && obj->m_static_exists && !m_active_blocks.contains(obj->m_static_block) && m_active_blocks.contains(blockpos_o)) { + // Delete from block where object was located deleteStaticFromBlock(obj, id, MOD_REASON_STATIC_DATA_REMOVED, false); @@ -2068,6 +2069,10 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) force_delete = true; } + // Regardless of what happens to the object at this point, deactivate it first. + // This ensures that LuaEntity on_deactivate is always called. + obj->markForDeactivation(); + /* If known by some client, set pending deactivation. Otherwise delete it immediately. @@ -2077,7 +2082,6 @@ void ServerEnvironment::deactivateFarObjects(bool _force_delete) << "object id=" << id << " is known by clients" << "; not deleting yet" << std::endl; - obj->m_pending_deactivation = true; return false; } -- cgit v1.2.3 From edd083601173c1b67a2e5cd88e23122f46b88bbf Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Mon, 4 Jan 2021 15:18:31 +0000 Subject: ContentDB: Add overwrite dialog when content is already installed (#10768) --- builtin/mainmenu/dlg_contentstore.lua | 74 ++++++++++++++++++++++++++++++++--- doc/menu_lua_api.txt | 2 + src/script/lua_api/l_mainmenu.cpp | 11 ++++++ src/script/lua_api/l_mainmenu.h | 2 + 4 files changed, 84 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 7f6b4b7e4..b5f71e753 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -437,12 +437,53 @@ function install_dialog.create(package, raw_deps) install_dialog.package = package install_dialog.raw_deps = raw_deps install_dialog.will_install_deps = true - return dialog_create("package_view", + return dialog_create("install_dialog", install_dialog.get_formspec, install_dialog.handle_submit, nil) end + +local confirm_overwrite = {} +function confirm_overwrite.get_formspec() + local package = confirm_overwrite.package + + return "size[11.5,4.5,true]" .. + "label[2,2;" .. + fgettext("\"$1\" already exists. Would you like to overwrite it?", package.name) .. "]".. + "style[install;bgcolor=red]" .. + "button[3.25,3.5;2.5,0.5;install;" .. fgettext("Overwrite") .. "]" .. + "button[5.75,3.5;2.5,0.5;cancel;" .. fgettext("Cancel") .. "]" +end + +function confirm_overwrite.handle_submit(this, fields) + if fields.cancel then + this:delete() + return true + end + + if fields.install then + this:delete() + confirm_overwrite.callback() + return true + end + + return false +end + +function confirm_overwrite.create(package, callback) + assert(type(package) == "table") + assert(type(callback) == "function") + + confirm_overwrite.package = package + confirm_overwrite.callback = callback + return dialog_create("confirm_overwrite", + confirm_overwrite.get_formspec, + confirm_overwrite.handle_submit, + nil) +end + + local function get_file_extension(path) local parts = path:split(".") return parts[#parts] @@ -858,14 +899,37 @@ function store.handle_submit(this, fields) assert(package) if fields["install_" .. i] then - local deps = get_raw_dependencies(package) - if deps and has_hard_deps(deps) then - local dlg = install_dialog.create(package, deps) + local install_parent + if package.type == "mod" then + install_parent = core.get_modpath() + elseif package.type == "game" then + install_parent = core.get_gamepath() + elseif package.type == "txp" then + install_parent = core.get_texturepath() + else + error("Unknown package type: " .. package.type) + end + + + local function on_confirm() + local deps = get_raw_dependencies(package) + if deps and has_hard_deps(deps) then + local dlg = install_dialog.create(package, deps) + dlg:set_parent(this) + this:hide() + dlg:show() + else + queue_download(package) + end + end + + if not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then + local dlg = confirm_overwrite.create(package, on_confirm) dlg:set_parent(this) this:hide() dlg:show() else - queue_download(package) + on_confirm() end return true diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 8908552d5..1bcf697e9 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -67,6 +67,8 @@ core.copy_dir(source,destination,keep_soure) (possible in async calls) ^ destination folder ^ keep_source DEFAULT true --> if set to false source is deleted after copying ^ returns true/false +core.is_dir(path) (possible in async calls) +^ returns true if path is a valid dir core.extract_zip(zipfile,destination) [unzip within path required] ^ zipfile to extract ^ destination folder to extract to diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 0b0b2de3b..5070ec7d4 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -803,6 +803,15 @@ int ModApiMainMenu::l_copy_dir(lua_State *L) return 1; } +/******************************************************************************/ +int ModApiMainMenu::l_is_dir(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + + lua_pushboolean(L, fs::IsDir(path)); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_extract_zip(lua_State *L) { @@ -1139,6 +1148,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(create_dir); API_FCT(delete_dir); API_FCT(copy_dir); + API_FCT(is_dir); API_FCT(extract_zip); API_FCT(may_modify_path); API_FCT(get_mainmenu_path); @@ -1172,6 +1182,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) API_FCT(create_dir); API_FCT(delete_dir); API_FCT(copy_dir); + API_FCT(is_dir); //API_FCT(extract_zip); //TODO remove dependency to GuiEngine API_FCT(may_modify_path); API_FCT(download_file); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index faa2bf273..0b02ed892 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -132,6 +132,8 @@ private: static int l_copy_dir(lua_State *L); + static int l_is_dir(lua_State *L); + static int l_extract_zip(lua_State *L); static int l_may_modify_path(lua_State *L); -- cgit v1.2.3 From 58a709096ef8ff17644cf201f25b1831d9506514 Mon Sep 17 00:00:00 2001 From: Loïc Blot Date: Mon, 4 Jan 2021 20:19:20 +0100 Subject: refacto: factorize multiple code parts from guiEditbox childs (#10782) --- src/gui/CMakeLists.txt | 1 + src/gui/guiEditBox.cpp | 95 ++++++++++++++++ src/gui/guiEditBox.h | 103 +++++++++++++++++ src/gui/guiEditBoxWithScrollbar.cpp | 113 +------------------ src/gui/guiEditBoxWithScrollbar.h | 66 +---------- src/gui/intlGUIEditBox.cpp | 216 +++++++++--------------------------- src/gui/intlGUIEditBox.h | 63 +---------- 7 files changed, 266 insertions(+), 391 deletions(-) create mode 100644 src/gui/guiEditBox.cpp create mode 100644 src/gui/guiEditBox.h (limited to 'src') diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 5305e7ad3..fdd36914a 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -7,6 +7,7 @@ set(gui_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/guiButtonItemImage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiChatConsole.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiConfirmRegistration.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/guiEditBox.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiEditBoxWithScrollbar.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiEngine.cpp ${CMAKE_CURRENT_SOURCE_DIR}/guiFormSpecMenu.cpp diff --git a/src/gui/guiEditBox.cpp b/src/gui/guiEditBox.cpp new file mode 100644 index 000000000..159bd38ac --- /dev/null +++ b/src/gui/guiEditBox.cpp @@ -0,0 +1,95 @@ +/* +Minetest +Copyright (C) 2021 Minetest + +This program 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. + +This program 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 this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "guiEditBox.h" + +#include "IGUISkin.h" +#include "IGUIEnvironment.h" +#include "IGUIFont.h" + +GUIEditBox::~GUIEditBox() +{ + if (m_override_font) + m_override_font->drop(); +} + +void GUIEditBox::setOverrideFont(IGUIFont *font) +{ + if (m_override_font == font) + return; + + if (m_override_font) + m_override_font->drop(); + + m_override_font = font; + + if (m_override_font) + m_override_font->grab(); + + breakText(); +} + +//! Get the font which is used right now for drawing +IGUIFont *GUIEditBox::getActiveFont() const +{ + if (m_override_font) + return m_override_font; + IGUISkin *skin = Environment->getSkin(); + if (skin) + return skin->getFont(); + return 0; +} + +//! Sets another color for the text. +void GUIEditBox::setOverrideColor(video::SColor color) +{ + m_override_color = color; + m_override_color_enabled = true; +} + +video::SColor GUIEditBox::getOverrideColor() const +{ + return m_override_color; +} + +//! Sets if the text should use the overide color or the color in the gui skin. +void GUIEditBox::enableOverrideColor(bool enable) +{ + m_override_color_enabled = enable; +} + +//! Enables or disables word wrap +void GUIEditBox::setWordWrap(bool enable) +{ + m_word_wrap = enable; + breakText(); +} + +//! Enables or disables newlines. +void GUIEditBox::setMultiLine(bool enable) +{ + m_multiline = enable; +} + +//! Enables or disables automatic scrolling with cursor position +//! \param enable: If set to true, the text will move around with the cursor position +void GUIEditBox::setAutoScroll(bool enable) +{ + m_autoscroll = enable; +} diff --git a/src/gui/guiEditBox.h b/src/gui/guiEditBox.h new file mode 100644 index 000000000..c673f2f5f --- /dev/null +++ b/src/gui/guiEditBox.h @@ -0,0 +1,103 @@ +/* +Minetest +Copyright (C) 2021 Minetest + +This program 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. + +This program 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 this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once + +#include "IGUIEditBox.h" +#include "IOSOperator.h" +#include "guiScrollBar.h" + +using namespace irr; +using namespace irr::gui; + +class GUIEditBox : public IGUIEditBox +{ +public: + GUIEditBox(IGUIEnvironment *environment, IGUIElement *parent, s32 id, + core::rect rectangle) : + IGUIEditBox(environment, parent, id, rectangle) + { + } + + virtual ~GUIEditBox(); + + //! Sets another skin independent font. + virtual void setOverrideFont(IGUIFont *font = 0); + + virtual IGUIFont *getOverrideFont() const { return m_override_font; } + + //! Get the font which is used right now for drawing + /** Currently this is the override font when one is set and the + font of the active skin otherwise */ + virtual IGUIFont *getActiveFont() const; + + //! Sets another color for the text. + virtual void setOverrideColor(video::SColor color); + + //! Gets the override color + virtual video::SColor getOverrideColor() const; + + //! Sets if the text should use the overide color or the + //! color in the gui skin. + virtual void enableOverrideColor(bool enable); + + //! Checks if an override color is enabled + /** \return true if the override color is enabled, false otherwise */ + virtual bool isOverrideColorEnabled(void) const + { + return m_override_color_enabled; + } + + //! Enables or disables word wrap for using the edit box as multiline text editor. + virtual void setWordWrap(bool enable); + + //! Checks if word wrap is enabled + //! \return true if word wrap is enabled, false otherwise + virtual bool isWordWrapEnabled() const { return m_word_wrap; } + + //! Enables or disables newlines. + /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, + instead a newline character will be inserted. */ + virtual void setMultiLine(bool enable); + + //! Checks if multi line editing is enabled + //! \return true if mult-line is enabled, false otherwise + virtual bool isMultiLineEnabled() const { return m_multiline; } + + //! Enables or disables automatic scrolling with cursor position + //! \param enable: If set to true, the text will move around with the cursor + //! position + virtual void setAutoScroll(bool enable); + + //! Checks to see if automatic scrolling is enabled + //! \return true if automatic scrolling is enabled, false if not + virtual bool isAutoScrollEnabled() const { return m_autoscroll; } + +protected: + virtual void breakText() = 0; + + gui::IGUIFont *m_override_font = nullptr; + + bool m_override_color_enabled = false; + bool m_word_wrap = false; + bool m_multiline = false; + bool m_autoscroll = true; + + video::SColor m_override_color = video::SColor(101, 255, 255, 255); +}; \ No newline at end of file diff --git a/src/gui/guiEditBoxWithScrollbar.cpp b/src/gui/guiEditBoxWithScrollbar.cpp index 169425a9a..7f9fdafd7 100644 --- a/src/gui/guiEditBoxWithScrollbar.cpp +++ b/src/gui/guiEditBoxWithScrollbar.cpp @@ -22,16 +22,14 @@ optional? dragging selected text numerical */ - //! constructor GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool border, IGUIEnvironment* environment, IGUIElement* parent, s32 id, const core::rect& rectangle, bool writable, bool has_vscrollbar) - : IGUIEditBox(environment, parent, id, rectangle), m_mouse_marking(false), - m_border(border), m_background(true), m_override_color_enabled(false), m_mark_begin(0), m_mark_end(0), - m_override_color(video::SColor(101, 255, 255, 255)), m_override_font(0), m_last_break_font(0), + : GUIEditBox(environment, parent, id, rectangle), m_mouse_marking(false), + m_border(border), m_background(true), m_mark_begin(0), m_mark_end(0), m_last_break_font(0), m_operator(0), m_blink_start_time(0), m_cursor_pos(0), m_hscroll_pos(0), m_vscroll_pos(0), m_max(0), - m_word_wrap(false), m_multiline(false), m_autoscroll(true), m_passwordbox(false), + m_passwordbox(false), m_passwordchar(L'*'), m_halign(EGUIA_UPPERLEFT), m_valign(EGUIA_CENTER), m_current_text_rect(0, 0, 1, 1), m_frame_rect(rectangle), m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable), @@ -69,9 +67,6 @@ GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool borde //! destructor GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar() { - if (m_override_font) - m_override_font->drop(); - if (m_operator) m_operator->drop(); @@ -80,54 +75,6 @@ GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar() } -//! Sets another skin independent font. -void GUIEditBoxWithScrollBar::setOverrideFont(IGUIFont* font) -{ - if (m_override_font == font) - return; - - if (m_override_font) - m_override_font->drop(); - - m_override_font = font; - - if (m_override_font) - m_override_font->grab(); - - breakText(); -} - -//! Gets the override font (if any) -IGUIFont * GUIEditBoxWithScrollBar::getOverrideFont() const -{ - return m_override_font; -} - -//! Get the font which is used right now for drawing -IGUIFont* GUIEditBoxWithScrollBar::getActiveFont() const -{ - if (m_override_font) - return m_override_font; - IGUISkin* skin = Environment->getSkin(); - if (skin) - return skin->getFont(); - return 0; -} - -//! Sets another color for the text. -void GUIEditBoxWithScrollBar::setOverrideColor(video::SColor color) -{ - m_override_color = color; - m_override_color_enabled = true; -} - - -video::SColor GUIEditBoxWithScrollBar::getOverrideColor() const -{ - return m_override_color; -} - - //! Turns the border on or off void GUIEditBoxWithScrollBar::setDrawBorder(bool border) { @@ -140,24 +87,6 @@ void GUIEditBoxWithScrollBar::setDrawBackground(bool draw) m_background = draw; } -//! Sets if the text should use the overide color or the color in the gui skin. -void GUIEditBoxWithScrollBar::enableOverrideColor(bool enable) -{ - m_override_color_enabled = enable; -} - -bool GUIEditBoxWithScrollBar::isOverrideColorEnabled() const -{ - return m_override_color_enabled; -} - -//! Enables or disables word wrap -void GUIEditBoxWithScrollBar::setWordWrap(bool enable) -{ - m_word_wrap = enable; - breakText(); -} - void GUIEditBoxWithScrollBar::updateAbsolutePosition() { @@ -170,26 +99,6 @@ void GUIEditBoxWithScrollBar::updateAbsolutePosition() } } -//! Checks if word wrap is enabled -bool GUIEditBoxWithScrollBar::isWordWrapEnabled() const -{ - return m_word_wrap; -} - - -//! Enables or disables newlines. -void GUIEditBoxWithScrollBar::setMultiLine(bool enable) -{ - m_multiline = enable; -} - - -//! Checks if multi line editing is enabled -bool GUIEditBoxWithScrollBar::isMultiLineEnabled() const -{ - return m_multiline; -} - void GUIEditBoxWithScrollBar::setPasswordBox(bool password_box, wchar_t password_char) { @@ -850,22 +759,6 @@ void GUIEditBoxWithScrollBar::setText(const wchar_t* text) } -//! Enables or disables automatic scrolling with cursor position -//! \param enable: If set to true, the text will move around with the cursor position -void GUIEditBoxWithScrollBar::setAutoScroll(bool enable) -{ - m_autoscroll = enable; -} - - -//! Checks to see if automatic scrolling is enabled -//! \return true if automatic scrolling is enabled, false if not -bool GUIEditBoxWithScrollBar::isAutoScrollEnabled() const -{ - return m_autoscroll; -} - - //! Gets the area of the text in the edit box //! \return Returns the size in pixels of the text core::dimension2du GUIEditBoxWithScrollBar::getTextDimension() diff --git a/src/gui/guiEditBoxWithScrollbar.h b/src/gui/guiEditBoxWithScrollbar.h index 77538e2f7..5ae58b934 100644 --- a/src/gui/guiEditBoxWithScrollbar.h +++ b/src/gui/guiEditBoxWithScrollbar.h @@ -5,15 +5,10 @@ #ifndef GUIEDITBOXWITHSCROLLBAR_HEADER #define GUIEDITBOXWITHSCROLLBAR_HEADER -#include "IGUIEditBox.h" -#include "IOSOperator.h" -#include "guiScrollBar.h" +#include "guiEditBox.h" #include -using namespace irr; -using namespace irr::gui; - -class GUIEditBoxWithScrollBar : public IGUIEditBox +class GUIEditBoxWithScrollBar : public GUIEditBox { public: @@ -25,61 +20,13 @@ public: //! destructor virtual ~GUIEditBoxWithScrollBar(); - //! Sets another skin independent font. - virtual void setOverrideFont(IGUIFont* font = 0); - - //! Gets the override font (if any) - /** \return The override font (may be 0) */ - virtual IGUIFont* getOverrideFont() const; - - //! Get the font which is used right now for drawing - /** Currently this is the override font when one is set and the - font of the active skin otherwise */ - virtual IGUIFont* getActiveFont() const; - - //! Sets another color for the text. - virtual void setOverrideColor(video::SColor color); - - //! Gets the override color - virtual video::SColor getOverrideColor() const; - - //! Sets if the text should use the overide color or the - //! color in the gui skin. - virtual void enableOverrideColor(bool enable); - - //! Checks if an override color is enabled - /** \return true if the override color is enabled, false otherwise */ - virtual bool isOverrideColorEnabled(void) const; - //! Sets whether to draw the background virtual void setDrawBackground(bool draw); //! Turns the border on or off virtual void setDrawBorder(bool border); - //! Enables or disables word wrap for using the edit box as multiline text editor. - virtual void setWordWrap(bool enable); - - //! Checks if word wrap is enabled - //! \return true if word wrap is enabled, false otherwise - virtual bool isWordWrapEnabled() const; - - //! Enables or disables newlines. - /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, - instead a newline character will be inserted. */ - virtual void setMultiLine(bool enable); - //! Checks if multi line editing is enabled - //! \return true if mult-line is enabled, false otherwise - virtual bool isMultiLineEnabled() const; - - //! Enables or disables automatic scrolling with cursor position - //! \param enable: If set to true, the text will move around with the cursor position - virtual void setAutoScroll(bool enable); - - //! Checks to see if automatic scrolling is enabled - //! \return true if automatic scrolling is enabled, false if not - virtual bool isAutoScrollEnabled() const; //! Gets the size area of the text in the edit box //! \return Returns the size in pixels of the text @@ -137,7 +84,7 @@ public: protected: //! Breaks the single text line. - void breakText(); + virtual void breakText(); //! sets the area of the given line void setTextRect(s32 line); //! returns the line number that the cursor is on @@ -164,12 +111,11 @@ protected: bool m_mouse_marking; bool m_border; bool m_background; - bool m_override_color_enabled; + s32 m_mark_begin; s32 m_mark_end; - video::SColor m_override_color; - gui::IGUIFont *m_override_font, *m_last_break_font; + gui::IGUIFont *m_last_break_font; IOSOperator* m_operator; u32 m_blink_start_time; @@ -177,7 +123,7 @@ protected: s32 m_hscroll_pos, m_vscroll_pos; // scroll position in characters u32 m_max; - bool m_word_wrap, m_multiline, m_autoscroll, m_passwordbox; + bool m_passwordbox; wchar_t m_passwordchar; EGUI_ALIGNMENT m_halign, m_valign; diff --git a/src/gui/intlGUIEditBox.cpp b/src/gui/intlGUIEditBox.cpp index 8be63fd6f..e917f73c1 100644 --- a/src/gui/intlGUIEditBox.cpp +++ b/src/gui/intlGUIEditBox.cpp @@ -59,7 +59,7 @@ namespace gui intlGUIEditBox::intlGUIEditBox(const wchar_t* text, bool border, IGUIEnvironment* environment, IGUIElement* parent, s32 id, const core::rect& rectangle, bool writable, bool has_vscrollbar) - : IGUIEditBox(environment, parent, id, rectangle), + : GUIEditBox(environment, parent, id, rectangle), Border(border), FrameRect(rectangle), m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable) { @@ -108,9 +108,6 @@ intlGUIEditBox::intlGUIEditBox(const wchar_t* text, bool border, //! destructor intlGUIEditBox::~intlGUIEditBox() { - if (OverrideFont) - OverrideFont->drop(); - if (Operator) Operator->drop(); @@ -118,52 +115,6 @@ intlGUIEditBox::~intlGUIEditBox() m_vscrollbar->drop(); } - -//! Sets another skin independent font. -void intlGUIEditBox::setOverrideFont(IGUIFont* font) -{ - if (OverrideFont == font) - return; - - if (OverrideFont) - OverrideFont->drop(); - - OverrideFont = font; - - if (OverrideFont) - OverrideFont->grab(); - - breakText(); -} - -IGUIFont * intlGUIEditBox::getOverrideFont() const -{ - return OverrideFont; -} - -//! Get the font which is used right now for drawing -IGUIFont* intlGUIEditBox::getActiveFont() const -{ - if ( OverrideFont ) - return OverrideFont; - IGUISkin* skin = Environment->getSkin(); - if (skin) - return skin->getFont(); - return 0; -} - -//! Sets another color for the text. -void intlGUIEditBox::setOverrideColor(video::SColor color) -{ - OverrideColor = color; - OverrideColorEnabled = true; -} - -video::SColor intlGUIEditBox::getOverrideColor() const -{ - return OverrideColor; -} - //! Turns the border on or off void intlGUIEditBox::setDrawBorder(bool border) { @@ -175,25 +126,6 @@ void intlGUIEditBox::setDrawBackground(bool draw) { } -//! Sets if the text should use the overide color or the color in the gui skin. -void intlGUIEditBox::enableOverrideColor(bool enable) -{ - OverrideColorEnabled = enable; -} - -bool intlGUIEditBox::isOverrideColorEnabled() const -{ - return OverrideColorEnabled; -} - -//! Enables or disables word wrap -void intlGUIEditBox::setWordWrap(bool enable) -{ - WordWrap = enable; - breakText(); -} - - void intlGUIEditBox::updateAbsolutePosition() { core::rect oldAbsoluteRect(AbsoluteRect); @@ -204,28 +136,6 @@ void intlGUIEditBox::updateAbsolutePosition() } } - -//! Checks if word wrap is enabled -bool intlGUIEditBox::isWordWrapEnabled() const -{ - return WordWrap; -} - - -//! Enables or disables newlines. -void intlGUIEditBox::setMultiLine(bool enable) -{ - MultiLine = enable; -} - - -//! Checks if multi line editing is enabled -bool intlGUIEditBox::isMultiLineEnabled() const -{ - return MultiLine; -} - - void intlGUIEditBox::setPasswordBox(bool passwordBox, wchar_t passwordChar) { PasswordBox = passwordBox; @@ -464,7 +374,7 @@ bool intlGUIEditBox::processKey(const SEvent& event) case KEY_END: { s32 p = Text.size(); - if (WordWrap || MultiLine) + if (m_word_wrap || m_multiline) { p = getLineFromPos(CursorPos); p = BrokenTextPositions[p] + (s32)BrokenText[p].size(); @@ -492,7 +402,7 @@ bool intlGUIEditBox::processKey(const SEvent& event) { s32 p = 0; - if (WordWrap || MultiLine) + if (m_word_wrap || m_multiline) { p = getLineFromPos(CursorPos); p = BrokenTextPositions[p]; @@ -514,7 +424,7 @@ bool intlGUIEditBox::processKey(const SEvent& event) } break; case KEY_RETURN: - if (MultiLine) + if (m_multiline) { inputChar(L'\n'); return true; @@ -567,7 +477,7 @@ bool intlGUIEditBox::processKey(const SEvent& event) BlinkStartTime = porting::getTimeMs(); break; case KEY_UP: - if (MultiLine || (WordWrap && BrokenText.size() > 1) ) + if (m_multiline || (m_word_wrap && BrokenText.size() > 1) ) { s32 lineNo = getLineFromPos(CursorPos); s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin > MarkEnd ? MarkBegin : MarkEnd); @@ -598,7 +508,7 @@ bool intlGUIEditBox::processKey(const SEvent& event) } break; case KEY_DOWN: - if (MultiLine || (WordWrap && BrokenText.size() > 1) ) + if (m_multiline || (m_word_wrap && BrokenText.size() > 1) ) { s32 lineNo = getLineFromPos(CursorPos); s32 mb = (MarkBegin == MarkEnd) ? CursorPos : (MarkBegin < MarkEnd ? MarkBegin : MarkEnd); @@ -791,8 +701,8 @@ void intlGUIEditBox::draw() // draw the text - IGUIFont* font = OverrideFont; - if (!OverrideFont) + IGUIFont* font = m_override_font; + if (!m_override_font) font = skin->getFont(); s32 cursorLine = 0; @@ -813,7 +723,7 @@ void intlGUIEditBox::draw() core::stringw s, s2; // get mark position - const bool ml = (!PasswordBox && (WordWrap || MultiLine)); + const bool ml = (!PasswordBox && (m_word_wrap || m_multiline)); const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 hlineStart = ml ? getLineFromPos(realmbgn) : 0; @@ -822,14 +732,14 @@ void intlGUIEditBox::draw() // Save the override color information. // Then, alter it if the edit box is disabled. - const bool prevOver = OverrideColorEnabled; - const video::SColor prevColor = OverrideColor; + const bool prevOver = m_override_color_enabled; + const video::SColor prevColor = m_override_color; if (!Text.empty()) { - if (!IsEnabled && !OverrideColorEnabled) + if (!IsEnabled && !m_override_color_enabled) { - OverrideColorEnabled = true; - OverrideColor = skin->getColor(EGDC_GRAY_TEXT); + m_override_color_enabled = true; + m_override_color = skin->getColor(EGDC_GRAY_TEXT); } for (s32 i=0; i < lineCount; ++i) @@ -870,7 +780,7 @@ void intlGUIEditBox::draw() // draw normal text font->draw(txtLine->c_str(), CurrentTextRect, - OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), + m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT), false, true, &localClipRect); // draw mark and marked text @@ -914,20 +824,20 @@ void intlGUIEditBox::draw() if (!s.empty()) font->draw(s.c_str(), CurrentTextRect, - OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_HIGH_LIGHT_TEXT), + m_override_color_enabled ? m_override_color : skin->getColor(EGDC_HIGH_LIGHT_TEXT), false, true, &localClipRect); } } // Return the override color information to its previous settings. - OverrideColorEnabled = prevOver; - OverrideColor = prevColor; + m_override_color_enabled = prevOver; + m_override_color = prevColor; } // draw cursor - if (WordWrap || MultiLine) + if (m_word_wrap || m_multiline) { cursorLine = getLineFromPos(CursorPos); txtLine = &BrokenText[cursorLine]; @@ -943,7 +853,7 @@ void intlGUIEditBox::draw() CurrentTextRect.UpperLeftCorner.X += charcursorpos; font->draw(L"_", CurrentTextRect, - OverrideColorEnabled ? OverrideColor : skin->getColor(EGDC_BUTTON_TEXT), + m_override_color_enabled ? m_override_color : skin->getColor(EGDC_BUTTON_TEXT), false, true, &localClipRect); } } @@ -965,22 +875,6 @@ void intlGUIEditBox::setText(const wchar_t* text) } -//! Enables or disables automatic scrolling with cursor position -//! \param enable: If set to true, the text will move around with the cursor position -void intlGUIEditBox::setAutoScroll(bool enable) -{ - AutoScroll = enable; -} - - -//! Checks to see if automatic scrolling is enabled -//! \return true if automatic scrolling is enabled, false if not -bool intlGUIEditBox::isAutoScrollEnabled() const -{ - return AutoScroll; -} - - //! Gets the area of the text in the edit box //! \return Returns the size in pixels of the text core::dimension2du intlGUIEditBox::getTextDimension() @@ -1096,12 +990,12 @@ bool intlGUIEditBox::processMouse(const SEvent& event) s32 intlGUIEditBox::getCursorPos(s32 x, s32 y) { - IGUIFont* font = OverrideFont; + IGUIFont* font = m_override_font; IGUISkin* skin = Environment->getSkin(); - if (!OverrideFont) + if (!m_override_font) font = skin->getFont(); - const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1; + const u32 lineCount = (m_word_wrap || m_multiline) ? BrokenText.size() : 1; core::stringw *txtLine = NULL; s32 startPos = 0; @@ -1118,8 +1012,8 @@ s32 intlGUIEditBox::getCursorPos(s32 x, s32 y) // is it inside this region? if (y >= CurrentTextRect.UpperLeftCorner.Y && y <= CurrentTextRect.LowerRightCorner.Y) { // we've found the clicked line - txtLine = (WordWrap || MultiLine) ? &BrokenText[curr_line_idx] : &Text; - startPos = (WordWrap || MultiLine) ? BrokenTextPositions[curr_line_idx] : 0; + txtLine = (m_word_wrap || m_multiline) ? &BrokenText[curr_line_idx] : &Text; + startPos = (m_word_wrap || m_multiline) ? BrokenTextPositions[curr_line_idx] : 0; break; } } @@ -1144,14 +1038,14 @@ void intlGUIEditBox::breakText() { IGUISkin* skin = Environment->getSkin(); - if ((!WordWrap && !MultiLine) || !skin) + if ((!m_word_wrap && !m_multiline) || !skin) return; BrokenText.clear(); // need to reallocate :/ BrokenTextPositions.set_used(0); - IGUIFont* font = OverrideFont; - if (!OverrideFont) + IGUIFont* font = m_override_font; + if (!m_override_font) font = skin->getFont(); if (!font) @@ -1190,7 +1084,7 @@ void intlGUIEditBox::breakText() } // don't break if we're not a multi-line edit box - if (!MultiLine) + if (!m_multiline) lineBreak = false; if (c == L' ' || c == 0 || i == (size-1)) @@ -1201,7 +1095,7 @@ void intlGUIEditBox::breakText() s32 whitelgth = font->getDimension(whitespace.c_str()).Width; s32 worldlgth = font->getDimension(word.c_str()).Width; - if (WordWrap && length + worldlgth + whitelgth > elWidth) + if (m_word_wrap && length + worldlgth + whitelgth > elWidth) { // break to next line length = worldlgth; @@ -1260,14 +1154,14 @@ void intlGUIEditBox::setTextRect(s32 line) if (!skin) return; - IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont(); + IGUIFont* font = m_override_font ? m_override_font : skin->getFont(); if (!font) return; // get text dimension - const u32 lineCount = (WordWrap || MultiLine) ? BrokenText.size() : 1; - if (WordWrap || MultiLine) + const u32 lineCount = (m_word_wrap || m_multiline) ? BrokenText.size() : 1; + if (m_word_wrap || m_multiline) { d = font->getDimension(BrokenText[line].c_str()); } @@ -1328,7 +1222,7 @@ void intlGUIEditBox::setTextRect(s32 line) s32 intlGUIEditBox::getLineFromPos(s32 pos) { - if (!WordWrap && !MultiLine) + if (!m_word_wrap && !m_multiline) return 0; s32 i=0; @@ -1387,7 +1281,7 @@ void intlGUIEditBox::inputChar(wchar_t c) void intlGUIEditBox::calculateScrollPos() { - if (!AutoScroll) + if (!m_autoscroll) return; // calculate horizontal scroll position @@ -1395,18 +1289,18 @@ void intlGUIEditBox::calculateScrollPos() setTextRect(cursLine); // don't do horizontal scrolling when wordwrap is enabled. - if (!WordWrap) + if (!m_word_wrap) { // get cursor position IGUISkin* skin = Environment->getSkin(); if (!skin) return; - IGUIFont* font = OverrideFont ? OverrideFont : skin->getFont(); + IGUIFont* font = m_override_font ? m_override_font : skin->getFont(); if (!font) return; - core::stringw *txtLine = MultiLine ? &BrokenText[cursLine] : &Text; - s32 cPos = MultiLine ? CursorPos - BrokenTextPositions[cursLine] : CursorPos; + core::stringw *txtLine = m_multiline ? &BrokenText[cursLine] : &Text; + s32 cPos = m_multiline ? CursorPos - BrokenTextPositions[cursLine] : CursorPos; s32 cStart = CurrentTextRect.UpperLeftCorner.X + HScrollPos + font->getDimension(txtLine->subString(0, cPos).c_str()).Width; @@ -1423,7 +1317,7 @@ void intlGUIEditBox::calculateScrollPos() // todo: adjust scrollbar } - if (!WordWrap && !MultiLine) + if (!m_word_wrap && !m_multiline) return; // vertical scroll position @@ -1468,8 +1362,8 @@ void intlGUIEditBox::createVScrollBar() { s32 fontHeight = 1; - if (OverrideFont) { - fontHeight = OverrideFont->getDimension(L"").Height; + if (m_override_font) { + fontHeight = m_override_font->getDimension(L"").Height; } else { if (IGUISkin* skin = Environment->getSkin()) { if (IGUIFont* font = skin->getFont()) { @@ -1520,7 +1414,7 @@ void intlGUIEditBox::updateVScrollBar() m_vscrollbar->setPageSize(s32(getTextDimension().Height)); } - if (!m_vscrollbar->isVisible() && MultiLine) { + if (!m_vscrollbar->isVisible() && m_multiline) { AbsoluteRect.LowerRightCorner.X -= m_scrollbar_width; m_vscrollbar->setVisible(true); @@ -1548,20 +1442,20 @@ void intlGUIEditBox::serializeAttributes(io::IAttributes* out, io::SAttributeRea { // IGUIEditBox::serializeAttributes(out,options); - out->addBool ("OverrideColorEnabled",OverrideColorEnabled ); - out->addColor ("OverrideColor", OverrideColor); - // out->addFont("OverrideFont",OverrideFont); - out->addInt ("MaxChars", Max); - out->addBool ("WordWrap", WordWrap); - out->addBool ("MultiLine", MultiLine); - out->addBool ("AutoScroll", AutoScroll); - out->addBool ("PasswordBox", PasswordBox); + out->addBool ("OverrideColorEnabled", m_override_color_enabled ); + out->addColor ("OverrideColor", m_override_color); + // out->addFont("OverrideFont",m_override_font); + out->addInt ("MaxChars", Max); + out->addBool ("WordWrap", m_word_wrap); + out->addBool ("MultiLine", m_multiline); + out->addBool ("AutoScroll", m_autoscroll); + out->addBool ("PasswordBox", PasswordBox); core::stringw ch = L" "; ch[0] = PasswordChar; - out->addString("PasswordChar", ch.c_str()); - out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); - out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); - out->addBool ("Writable", m_writable); + out->addString("PasswordChar", ch.c_str()); + out->addEnum ("HTextAlign", HAlign, GUIAlignmentNames); + out->addEnum ("VTextAlign", VAlign, GUIAlignmentNames); + out->addBool ("Writable", m_writable); IGUIEditBox::serializeAttributes(out,options); } diff --git a/src/gui/intlGUIEditBox.h b/src/gui/intlGUIEditBox.h index 9d643495e..a1e423aa2 100644 --- a/src/gui/intlGUIEditBox.h +++ b/src/gui/intlGUIEditBox.h @@ -7,16 +7,15 @@ #include "IrrCompileConfig.h" //#ifdef _IRR_COMPILE_WITH_GUI_ -#include +#include "guiEditBox.h" #include "irrArray.h" #include "IOSOperator.h" -#include "guiScrollBar.h" namespace irr { namespace gui { - class intlGUIEditBox : public IGUIEditBox + class intlGUIEditBox : public GUIEditBox { public: @@ -28,32 +27,6 @@ namespace gui //! destructor virtual ~intlGUIEditBox(); - //! Sets another skin independent font. - virtual void setOverrideFont(IGUIFont* font=0); - - //! Gets the override font (if any) - /** \return The override font (may be 0) */ - virtual IGUIFont* getOverrideFont() const; - - //! Get the font which is used right now for drawing - /** Currently this is the override font when one is set and the - font of the active skin otherwise */ - virtual IGUIFont* getActiveFont() const; - - //! Sets another color for the text. - virtual void setOverrideColor(video::SColor color); - - //! Gets the override color - virtual video::SColor getOverrideColor() const; - - //! Sets if the text should use the overide color or the - //! color in the gui skin. - virtual void enableOverrideColor(bool enable); - - //! Checks if an override color is enabled - /** \return true if the override color is enabled, false otherwise */ - virtual bool isOverrideColorEnabled(void) const; - //! Sets whether to draw the background virtual void setDrawBackground(bool draw); @@ -64,30 +37,6 @@ namespace gui virtual bool isDrawBorderEnabled() const { return Border; } - //! Enables or disables word wrap for using the edit box as multiline text editor. - virtual void setWordWrap(bool enable); - - //! Checks if word wrap is enabled - //! \return true if word wrap is enabled, false otherwise - virtual bool isWordWrapEnabled() const; - - //! Enables or disables newlines. - /** \param enable: If set to true, the EGET_EDITBOX_ENTER event will not be fired, - instead a newline character will be inserted. */ - virtual void setMultiLine(bool enable); - - //! Checks if multi line editing is enabled - //! \return true if mult-line is enabled, false otherwise - virtual bool isMultiLineEnabled() const; - - //! Enables or disables automatic scrolling with cursor position - //! \param enable: If set to true, the text will move around with the cursor position - virtual void setAutoScroll(bool enable); - - //! Checks to see if automatic scrolling is enabled - //! \return true if automatic scrolling is enabled, false if not - virtual bool isAutoScrollEnabled() const; - //! Gets the size area of the text in the edit box //! \return Returns the size in pixels of the text virtual core::dimension2du getTextDimension(); @@ -143,7 +92,7 @@ namespace gui protected: //! Breaks the single text line. - void breakText(); + virtual void breakText(); //! sets the area of the given line void setTextRect(s32 line); //! returns the line number that the cursor is on @@ -169,12 +118,9 @@ namespace gui bool MouseMarking = false; bool Border; - bool OverrideColorEnabled = false; s32 MarkBegin = 0; s32 MarkEnd = 0; - video::SColor OverrideColor = video::SColor(101,255,255,255); - gui::IGUIFont *OverrideFont = nullptr; gui::IGUIFont *LastBreakFont = nullptr; IOSOperator *Operator = nullptr; @@ -184,9 +130,6 @@ namespace gui s32 VScrollPos = 0; // scroll position in characters u32 Max = 0; - bool WordWrap = false; - bool MultiLine = false; - bool AutoScroll = true; bool PasswordBox = false; wchar_t PasswordChar = L'*'; EGUI_ALIGNMENT HAlign = EGUIA_UPPERLEFT; -- cgit v1.2.3