From 808fa5ecb3ddfd5d993000cc6b4c972257e182db Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 23 Jul 2020 19:54:58 +0200 Subject: Improve default inventory+wield images of node drawtypes (#9299) --- src/client/content_mapblock.cpp | 4 +- src/client/content_mapblock.h | 2 +- src/client/wieldmesh.cpp | 207 ++++++++++++++++++++-------------------- 3 files changed, 109 insertions(+), 104 deletions(-) (limited to 'src/client') diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index 3d06584c4..65a85709b 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -1454,10 +1454,10 @@ void MapblockMeshGenerator::generate() } } -void MapblockMeshGenerator::renderSingle(content_t node) +void MapblockMeshGenerator::renderSingle(content_t node, u8 param2) { p = {0, 0, 0}; - n = MapNode(node, 0xff, 0x00); + n = MapNode(node, 0xff, param2); f = &nodedef->get(n); drawNode(); } diff --git a/src/client/content_mapblock.h b/src/client/content_mapblock.h index 97947cdbe..487d84a07 100644 --- a/src/client/content_mapblock.h +++ b/src/client/content_mapblock.h @@ -174,5 +174,5 @@ public: public: MapblockMeshGenerator(MeshMakeData *input, MeshCollector *output); void generate(); - void renderSingle(content_t node); + void renderSingle(content_t node, u8 param2 = 0x00); }; diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 8cd3e29a9..a268895ed 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -303,13 +303,24 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, } } -scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector *colors) +scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector *colors, const ContentFeatures &f) { MeshMakeData mesh_make_data(client, false, false); MeshCollector collector; mesh_make_data.setSmoothLighting(false); MapblockMeshGenerator gen(&mesh_make_data, &collector); - gen.renderSingle(id); + u8 param2 = 0; + if (f.param_type_2 == CPT2_WALLMOUNTED || + f.param_type_2 == CPT2_COLORED_WALLMOUNTED) { + if (f.drawtype == NDT_TORCHLIKE) + param2 = 1; + else if (f.drawtype == NDT_SIGNLIKE || + f.drawtype == NDT_NODEBOX || + f.drawtype == NDT_MESH) + param2 = 4; + } + gen.renderSingle(id, param2); + colors->clear(); scene::SMesh *mesh = new scene::SMesh(); for (auto &prebuffers : collector.prebuffers) @@ -319,8 +330,9 @@ scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vectorMaterial.setTexture(0, p.layer.texture); p.layer.applyMaterialOptions(buf->Material); @@ -368,73 +380,61 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che // Handle nodes // See also CItemDefManager::createClientCached() if (def.type == ITEM_NODE) { - if (f.mesh_ptr[0]) { - // e.g. mesh nodes and nodeboxes - mesh = cloneMesh(f.mesh_ptr[0]); - postProcessNodeMesh(mesh, f, m_enable_shaders, true, - &m_material_type, &m_colors); + bool cull_backface = f.needsBackfaceCulling(); + + // Select rendering method + switch (f.drawtype) { + case NDT_AIRLIKE: + setExtruded("no_texture_airlike.png", "", + v3f(1.0, 1.0, 1.0), tsrc, 1); + break; + case NDT_SIGNLIKE: + case NDT_TORCHLIKE: + case NDT_RAILLIKE: + case NDT_PLANTLIKE: + case NDT_PLANTLIKE_ROOTED: + case NDT_FLOWINGLIQUID: { + v3f wscale = def.wield_scale; + if (f.drawtype == NDT_FLOWINGLIQUID) + wscale.Z *= 0.1f; + setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + tsrc->getTextureName(f.tiles[0].layers[1].texture_id), + wscale, tsrc, + f.tiles[0].layers[0].animation_frame_count); + // Add color + const TileLayer &l0 = f.tiles[0].layers[0]; + m_colors.emplace_back(l0.has_color, l0.color); + const TileLayer &l1 = f.tiles[0].layers[1]; + m_colors.emplace_back(l1.has_color, l1.color); + break; + } + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + setCube(f, def.wield_scale); + break; + default: + // Render non-trivial drawtypes like the actual node + mesh = createSpecialNodeMesh(client, id, &m_colors, f); changeToMesh(mesh); mesh->drop(); - // mesh is pre-scaled by BS * f->visual_scale m_meshnode->setScale( - def.wield_scale * WIELD_SCALE_FACTOR - / (BS * f.visual_scale)); - } else { - switch (f.drawtype) { - case NDT_AIRLIKE: { - changeToMesh(nullptr); - break; - } - case NDT_PLANTLIKE: { - setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id), - tsrc->getTextureName(f.tiles[0].layers[1].texture_id), - def.wield_scale, tsrc, - f.tiles[0].layers[0].animation_frame_count); - // Add color - const TileLayer &l0 = f.tiles[0].layers[0]; - m_colors.emplace_back(l0.has_color, l0.color); - const TileLayer &l1 = f.tiles[0].layers[1]; - m_colors.emplace_back(l1.has_color, l1.color); - break; - } - case NDT_PLANTLIKE_ROOTED: { - setExtruded(tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), - "", def.wield_scale, tsrc, - f.special_tiles[0].layers[0].animation_frame_count); - // Add color - const TileLayer &l0 = f.special_tiles[0].layers[0]; - m_colors.emplace_back(l0.has_color, l0.color); - break; - } - case NDT_NORMAL: - case NDT_ALLFACES: - case NDT_LIQUID: - case NDT_FLOWINGLIQUID: { - setCube(f, def.wield_scale); - break; - } - default: { - mesh = createSpecialNodeMesh(client, id, &m_colors); - changeToMesh(mesh); - mesh->drop(); - m_meshnode->setScale( - def.wield_scale * WIELD_SCALE_FACTOR - / (BS * f.visual_scale)); - } - } + def.wield_scale * WIELD_SCALE_FACTOR + / (BS * f.visual_scale)); + break; } + u32 material_count = m_meshnode->getMaterialCount(); for (u32 i = 0; i < material_count; ++i) { video::SMaterial &material = m_meshnode->getMaterial(i); material.MaterialType = m_material_type; material.MaterialTypeParam = 0.5f; - material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BACK_FACE_CULLING, cull_backface); material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter); material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); } return; - } - else if (!def.inventory_image.empty()) { + } else if (!def.inventory_image.empty()) { setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, tsrc, 1); m_colors.emplace_back(); @@ -529,6 +529,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) // Shading is on by default result->needs_shading = true; + bool cull_backface = f.needsBackfaceCulling(); + // If inventory_image is defined, it overrides everything else if (!def.inventory_image.empty()) { mesh = getExtrudedMesh(tsrc, def.inventory_image, @@ -538,51 +540,54 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) result->buffer_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); // Items with inventory images do not need shading result->needs_shading = false; + } else if (def.type == ITEM_NODE && f.drawtype == NDT_AIRLIKE) { + // Fallback image for airlike node + mesh = getExtrudedMesh(tsrc, "no_texture_airlike.png", + def.inventory_overlay); + result->needs_shading = false; } else if (def.type == ITEM_NODE) { - if (f.mesh_ptr[0]) { - mesh = cloneMesh(f.mesh_ptr[0]); - scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + switch (f.drawtype) { + case NDT_NORMAL: + case NDT_ALLFACES: + case NDT_LIQUID: + case NDT_FLOWINGLIQUID: { + scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); + mesh = cloneMesh(cube); + cube->drop(); + if (f.drawtype == NDT_FLOWINGLIQUID) { + scaleMesh(mesh, v3f(1.2, 0.03, 1.2)); + translateMesh(mesh, v3f(0, -0.57, 0)); + } else + scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); + // add overlays postProcessNodeMesh(mesh, f, false, false, nullptr, - &result->buffer_colors); - } else { - switch (f.drawtype) { - case NDT_PLANTLIKE: { - mesh = getExtrudedMesh(tsrc, - tsrc->getTextureName(f.tiles[0].layers[0].texture_id), - tsrc->getTextureName(f.tiles[0].layers[1].texture_id)); - // Add color - const TileLayer &l0 = f.tiles[0].layers[0]; - result->buffer_colors.emplace_back(l0.has_color, l0.color); - const TileLayer &l1 = f.tiles[0].layers[1]; - result->buffer_colors.emplace_back(l1.has_color, l1.color); - break; - } - case NDT_PLANTLIKE_ROOTED: { - mesh = getExtrudedMesh(tsrc, - tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), ""); - // Add color - const TileLayer &l0 = f.special_tiles[0].layers[0]; - result->buffer_colors.emplace_back(l0.has_color, l0.color); - break; - } - case NDT_NORMAL: - case NDT_ALLFACES: - case NDT_LIQUID: - case NDT_FLOWINGLIQUID: { - scene::IMesh *cube = g_extrusion_mesh_cache->createCube(); - mesh = cloneMesh(cube); - cube->drop(); - scaleMesh(mesh, v3f(1.2, 1.2, 1.2)); - // add overlays - postProcessNodeMesh(mesh, f, false, false, nullptr, - &result->buffer_colors); - break; - } - default: { - mesh = createSpecialNodeMesh(client, id, &result->buffer_colors); - scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); - } - } + &result->buffer_colors, true); + break; + } + case NDT_PLANTLIKE: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.tiles[0].layers[0].texture_id), + tsrc->getTextureName(f.tiles[0].layers[1].texture_id)); + // Add color + const TileLayer &l0 = f.tiles[0].layers[0]; + result->buffer_colors.emplace_back(l0.has_color, l0.color); + const TileLayer &l1 = f.tiles[0].layers[1]; + result->buffer_colors.emplace_back(l1.has_color, l1.color); + break; + } + case NDT_PLANTLIKE_ROOTED: { + mesh = getExtrudedMesh(tsrc, + tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id), ""); + // Add color + const TileLayer &l0 = f.special_tiles[0].layers[0]; + result->buffer_colors.emplace_back(l0.has_color, l0.color); + break; + } + default: + // Render non-trivial drawtypes like the actual node + mesh = createSpecialNodeMesh(client, id, &result->buffer_colors, f); + scaleMesh(mesh, v3f(0.12, 0.12, 0.12)); + break; } u32 mc = mesh->getMeshBufferCount(); @@ -593,7 +598,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) material.MaterialTypeParam = 0.5f; material.setFlag(video::EMF_BILINEAR_FILTER, false); material.setFlag(video::EMF_TRILINEAR_FILTER, false); - material.setFlag(video::EMF_BACK_FACE_CULLING, true); + material.setFlag(video::EMF_BACK_FACE_CULLING, cull_backface); material.setFlag(video::EMF_LIGHTING, false); } -- cgit v1.2.3 From ae83edd16581b2b5426b565e703a8766e88dbbf6 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Mon, 27 Jul 2020 19:40:33 +0200 Subject: Play place_failed sound if occupied or cannot attach (#9486) --- doc/lua_api.txt | 7 +++++-- src/client/game.cpp | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index e0c895c97..5fe02b452 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -7217,10 +7217,13 @@ Used by `minetest.register_node`. -- Node was placed. Also played after falling place_failed = , - -- When node placement failed + -- When node placement failed. + -- Note: This happens if the _built-in_ node placement failed. + -- This sound will still be played if the node is placed in the + -- `on_place` callback manually. fall = , - -- When node starts to fall + -- When node starts to fall or is detached }, drop = "", diff --git a/src/client/game.cpp b/src/client/game.cpp index 42d60b21c..20d2c6f90 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3379,6 +3379,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, } else { node = map.getNode(p, &is_valid_position); if (is_valid_position && !nodedef->get(node).buildable_to) { + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; // Report to server client->interact(INTERACT_PLACE, pointed); return false; @@ -3451,6 +3452,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, pp = p + v3s16(0, -1, 0); if (!nodedef->get(map.getNode(pp)).walkable) { + soundmaker->m_player_rightpunch_sound = selected_def.sound_place_failed; // Report to server client->interact(INTERACT_PLACE, pointed); return false; -- cgit v1.2.3 From 715a123a33db7b0f191259ba68cbc9c565d0d4e8 Mon Sep 17 00:00:00 2001 From: Lejo Date: Thu, 30 Jul 2020 00:16:21 +0300 Subject: Add PUT and DELETE request + specific method value to HTTP API (#9909) --- doc/lua_api.txt | 12 ++++++-- src/client/clientmedia.cpp | 3 +- src/httpfetch.cpp | 66 +++++++++++++++++++++++++------------------ src/httpfetch.h | 22 +++++++++++---- src/network/networkprotocol.h | 2 +- src/script/lua_api/l_http.cpp | 29 +++++++++++++++++-- src/script/lua_api/l_http.h | 4 +-- src/serverlist.cpp | 4 +-- 8 files changed, 98 insertions(+), 44 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 5fe02b452..2d22dc899 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -8071,11 +8071,13 @@ Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. timeout = 10, -- Timeout for connection in seconds. Default is 3 seconds. - post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, - -- Optional, if specified a POST request with post_data is performed. + method = "GET", "POST", "PUT" or "DELETE" + -- The http method to use. Defaults to "GET". + + data = "Raw request data string" OR {field1 = "data1", field2 = "data2"}, + -- Data for the POST, PUT or DELETE request. -- Accepts both a string and a table. If a table is specified, encodes -- table as x-www-form-urlencoded key-value pairs. - -- If post_data is not specified, a GET request is performed instead. user_agent = "ExampleUserAgent", -- Optional, if specified replaces the default minetest user agent with @@ -8089,6 +8091,10 @@ Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`. multipart = boolean -- Optional, if true performs a multipart HTTP request. -- Default is false. + -- Post only, data must be array + + post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"}, + -- Deprecated, use `data` instead. Forces `method = "POST"`. } `HTTPRequestResult` definition diff --git a/src/client/clientmedia.cpp b/src/client/clientmedia.cpp index 8cd3b6bcc..c4c08c05d 100644 --- a/src/client/clientmedia.cpp +++ b/src/client/clientmedia.cpp @@ -260,7 +260,8 @@ void ClientMediaDownloader::initialStep(Client *client) fetch_request.request_id = m_httpfetch_next_id; // == i fetch_request.timeout = m_httpfetch_timeout; fetch_request.connect_timeout = m_httpfetch_timeout; - fetch_request.post_data = required_hash_set; + fetch_request.method = HTTP_POST; + fetch_request.raw_data = required_hash_set; fetch_request.extra_headers.emplace_back( "Content-Type: application/octet-stream"); diff --git a/src/httpfetch.cpp b/src/httpfetch.cpp index 326b5052f..65202ce3e 100644 --- a/src/httpfetch.cpp +++ b/src/httpfetch.cpp @@ -294,13 +294,11 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss); } - // Set POST (or GET) data - if (request.post_fields.empty() && request.post_data.empty()) { - curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); - } else if (request.multipart) { + // Set data from fields or raw_data + if (request.multipart) { curl_httppost *last = NULL; - for (StringMap::iterator it = request.post_fields.begin(); - it != request.post_fields.end(); ++it) { + for (StringMap::iterator it = request.fields.begin(); + it != request.fields.end(); ++it) { curl_formadd(&post, &last, CURLFORM_NAMELENGTH, it->first.size(), CURLFORM_PTRNAME, it->first.c_str(), @@ -311,28 +309,42 @@ HTTPFetchOngoing::HTTPFetchOngoing(const HTTPFetchRequest &request_, curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); // request.post_fields must now *never* be // modified until CURLOPT_HTTPPOST is cleared - } else if (request.post_data.empty()) { - curl_easy_setopt(curl, CURLOPT_POST, 1); - std::string str; - for (auto &post_field : request.post_fields) { - if (!str.empty()) - str += "&"; - str += urlencode(post_field.first); - str += "="; - str += urlencode(post_field.second); - } - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, - str.size()); - curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, - str.c_str()); } else { - curl_easy_setopt(curl, CURLOPT_POST, 1); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, - request.post_data.size()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, - request.post_data.c_str()); - // request.post_data must now *never* be - // modified until CURLOPT_POSTFIELDS is cleared + switch (request.method) { + case HTTP_GET: + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + break; + case HTTP_POST: + curl_easy_setopt(curl, CURLOPT_POST, 1); + break; + case HTTP_PUT: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); + break; + case HTTP_DELETE: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + break; + } + if (request.method != HTTP_GET) { + if (!request.raw_data.empty()) { + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, + request.raw_data.size()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, + request.raw_data.c_str()); + } else if (!request.fields.empty()) { + std::string str; + for (auto &field : request.fields) { + if (!str.empty()) + str += "&"; + str += urlencode(field.first); + str += "="; + str += urlencode(field.second); + } + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, + str.size()); + curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, + str.c_str()); + } + } } // Set additional HTTP headers for (const std::string &extra_header : request.extra_headers) { diff --git a/src/httpfetch.h b/src/httpfetch.h index ae8b5afb5..3b9f17f0a 100644 --- a/src/httpfetch.h +++ b/src/httpfetch.h @@ -28,6 +28,15 @@ with this program; if not, write to the Free Software Foundation, Inc., #define HTTPFETCH_DISCARD 0 #define HTTPFETCH_SYNC 1 +// Methods +enum HttpMethod : u8 +{ + HTTP_GET, + HTTP_POST, + HTTP_PUT, + HTTP_DELETE, +}; + struct HTTPFetchRequest { std::string url = ""; @@ -50,12 +59,15 @@ struct HTTPFetchRequest // application/x-www-form-urlencoded. POST-only. bool multipart = false; - // POST fields. Fields are escaped properly. - // If this is empty a GET request is done instead. - StringMap post_fields; + // The Method to use default = GET + // Avaible methods GET, POST, PUT, DELETE + HttpMethod method = HTTP_GET; + + // Fields of the request + StringMap fields; - // Raw POST data, overrides post_fields. - std::string post_data; + // Raw data of the request overrides fields + std::string raw_data; // If not empty, should contain entries such as "Accept: text/html" std::vector extra_headers; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 28abf02c0..05600cda9 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -1034,7 +1034,7 @@ const static std::string accessDeniedStrings[SERVER_ACCESSDENIED_MAX] = { "This server has experienced an internal error. You will now be disconnected." }; -enum PlayerListModifer: u8 +enum PlayerListModifer : u8 { PLAYER_LIST_INIT, PLAYER_LIST_ADD, diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp index ec43bf174..5ea3b3f99 100644 --- a/src/script/lua_api/l_http.cpp +++ b/src/script/lua_api/l_http.cpp @@ -49,17 +49,40 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req) req.multipart = getboolfield_default(L, 1, "multipart", false); req.timeout = getintfield_default(L, 1, "timeout", 3) * 1000; - // post_data: if table, post form data, otherwise raw data + lua_getfield(L, 1, "method"); + if (lua_isstring(L, -1)) { + std::string mth = getstringfield_default(L, 1, "method", ""); + if (mth == "GET") + req.method = HTTP_GET; + else if (mth == "POST") + req.method = HTTP_POST; + else if (mth == "PUT") + req.method = HTTP_PUT; + else if (mth == "DELETE") + req.method = HTTP_DELETE; + } + lua_pop(L, 1); + + // post_data: if table, post form data, otherwise raw data DEPRECATED use data and method instead lua_getfield(L, 1, "post_data"); + if (lua_isnil(L, 2)) { + lua_pop(L, 1); + lua_getfield(L, 1, "data"); + } + else { + req.method = HTTP_POST; + } + if (lua_istable(L, 2)) { lua_pushnil(L); while (lua_next(L, 2) != 0) { - req.post_fields[readParam(L, -2)] = readParam(L, -1); + req.fields[readParam(L, -2)] = readParam(L, -1); lua_pop(L, 1); } } else if (lua_isstring(L, 2)) { - req.post_data = readParam(L, 2); + req.raw_data = readParam(L, 2); } + lua_pop(L, 1); lua_getfield(L, 1, "extra_headers"); diff --git a/src/script/lua_api/l_http.h b/src/script/lua_api/l_http.h index de6e51b37..c3a2a5276 100644 --- a/src/script/lua_api/l_http.h +++ b/src/script/lua_api/l_http.h @@ -32,10 +32,10 @@ private: static void read_http_fetch_request(lua_State *L, HTTPFetchRequest &req); static void push_http_fetch_result(lua_State *L, HTTPFetchResult &res, bool completed = true); - // http_fetch_sync({url=, timeout=, post_data=}) + // http_fetch_sync({url=, timeout=, data=}) static int l_http_fetch_sync(lua_State *L); - // http_fetch_async({url=, timeout=, post_data=}) + // http_fetch_async({url=, timeout=, data=}) static int l_http_fetch_async(lua_State *L); // http_fetch_async_get(handle) diff --git a/src/serverlist.cpp b/src/serverlist.cpp index 18264e933..2f6ab2e61 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -261,11 +261,11 @@ void sendAnnounce(AnnounceAction action, HTTPFetchRequest fetch_request; fetch_request.url = g_settings->get("serverlist_url") + std::string("/announce"); - fetch_request.post_fields["json"] = fastWriteJson(server); + fetch_request.method = HTTP_POST; + fetch_request.fields["json"] = fastWriteJson(server); fetch_request.multipart = true; httpfetch_async(fetch_request); } #endif } // namespace ServerList - -- cgit v1.2.3 From 470f32821627a56b682ea1947ab5a50ef57c1c10 Mon Sep 17 00:00:00 2001 From: Lars Müller <34514239+appgurueu@users.noreply.github.com> Date: Wed, 29 Jul 2020 23:17:52 +0200 Subject: Revert "Get rid of non-ascii characters in the debug display code (#8821)" (#9828) This reverts commit 4f9ccd89b347dad3db5ce63d3405a8d60c163af5. --- src/client/gameui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client') diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp index c216f405d..81c268e44 100644 --- a/src/client/gameui.cpp +++ b/src/client/gameui.cpp @@ -133,9 +133,9 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_ << "pos: (" << (player_position.X / BS) << ", " << (player_position.Y / BS) << ", " << (player_position.Z / BS) - << ") | yaw: " << (wrapDegrees_0_360(cam.camera_yaw)) << "\xC2\xB0 " + << ") | yaw: " << (wrapDegrees_0_360(cam.camera_yaw)) << "° " << yawToDirectionString(cam.camera_yaw) - << " | pitch: " << (-wrapDegrees_180(cam.camera_pitch)) << "\xC2\xB0" + << " | pitch: " << (-wrapDegrees_180(cam.camera_pitch)) << "°" << " | seed: " << ((u64)client->getMapSeed()); if (pointed_old.type == POINTEDTHING_NODE) { -- cgit v1.2.3 From e5725dfb8e476a5a6f63f020a23a53ca3ef610e9 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Wed, 29 Jul 2020 23:20:01 +0200 Subject: Allow starting local server using --go again (#10229) --- src/client/clientlauncher.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/client') diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index ce16797e6..29427f609 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -327,13 +327,13 @@ void ClientLauncher::init_args(GameStartData &start_data, const Settings &cmd_ar // Join a remote server start_data.address = cmd_args.get("address"); start_data.world_path.clear(); + start_data.name = g_settings->get("name"); } if (!start_data.world_path.empty()) { // Start a singleplayer instance start_data.address = ""; } - start_data.name = g_settings->get("name"); if (cmd_args.exists("name")) start_data.name = cmd_args.get("name"); @@ -419,7 +419,6 @@ bool ClientLauncher::launch_game(std::string &error_message, /* Show the GUI menu */ std::string server_name, server_description; - start_data.local_server = false; if (!skip_main_menu) { // Initialize menu data // TODO: Re-use existing structs (GameStartData) @@ -467,6 +466,9 @@ bool ClientLauncher::launch_game(std::string &error_message, start_data.local_server = !menudata.simple_singleplayer_mode && start_data.address.empty(); + } else { + start_data.local_server = !start_data.world_path.empty() && + start_data.address.empty() && !start_data.name.empty(); } if (!RenderingEngine::run()) -- cgit v1.2.3 From 9bba52c4000a06043f5100dbb0ef66d869707ffc Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 30 Jul 2020 17:39:57 +0200 Subject: content_cao: Support texture animation for upright_sprite (#10020) --- doc/lua_api.txt | 18 +++++++++--------- games/devtest/mods/testentities/visuals.lua | 16 ++++++++++++++-- src/client/content_cao.cpp | 28 +++++++++++++++++++++++++--- src/client/mesh.cpp | 9 +++++++++ src/client/mesh.h | 7 +++++++ 5 files changed, 64 insertions(+), 14 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2d22dc899..8ac3ad7f2 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6077,15 +6077,15 @@ object you are working with still exists. * `get_yaw()`: returns number in radians * `set_texture_mod(mod)` * `get_texture_mod()` returns current texture modifier -* `set_sprite(p, num_frames, framelength, select_horiz_by_yawpitch)` - * Select sprite from spritesheet with optional animation and Dungeon Master - style texture selection based on yaw relative to camera - * `p`: {x=number, y=number}, the coordinate of the first frame - (x: column, y: row), default: `{x=0, y=0}` - * `num_frames`: number, default: `1` - * `framelength`: number, default: `0.2` - * `select_horiz_by_yawpitch`: boolean, this was once used for the Dungeon - Master mob, default: `false` +* `set_sprite(p, num_frames, framelength, select_x_by_camera)` + * Specifies and starts a sprite animation + * Animations iterate along the frame `y` position. + * `p`: {x=column number, y=row number}, the coordinate of the first frame + default: `{x=0, y=0}` + * `num_frames`: Total frames in the texture, default: `1` + * `framelength`: Time per animated frame in seconds, default: `0.2` + * `select_x_by_camera`: Only for visual = `sprite`. Changes the frame `x` + position according to the view direction. default: `false`. * `get_entity_name()` (**Deprecated**: Will be removed in a future version) * `get_luaentity()` diff --git a/games/devtest/mods/testentities/visuals.lua b/games/devtest/mods/testentities/visuals.lua index 83f361f16..8848ba49f 100644 --- a/games/devtest/mods/testentities/visuals.lua +++ b/games/devtest/mods/testentities/visuals.lua @@ -68,7 +68,7 @@ minetest.register_entity("testentities:mesh_unshaded", { -- Advanced visual tests --- A test entity for testing animated and yaw-modulated sprites +-- An entity for testing animated and yaw-modulated sprites minetest.register_entity("testentities:yawsprite", { initial_properties = { selectionbox = {-0.3, -0.5, -0.3, 0.3, 0.3, 0.3}, @@ -79,6 +79,18 @@ minetest.register_entity("testentities:yawsprite", { initial_sprite_basepos = {x=0, y=0}, }, on_activate = function(self, staticdata) - self.object:set_sprite({x=0, y=0}, 1, 0, true) + self.object:set_sprite({x=0, y=0}, 3, 0.5, true) + end, +}) + +-- An entity for testing animated upright sprites +minetest.register_entity("testentities:upright_animated", { + initial_properties = { + visual = "upright_sprite", + textures = {"testnodes_anim.png"}, + spritediv = {x = 1, y = 4}, + }, + on_activate = function(self) + self.object:set_sprite({x=0, y=0}, 4, 1.0, false) end, }) diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 4f949f6b0..88688d18c 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1176,6 +1176,7 @@ void GenericCAO::updateTexturePos() int row = m_tx_basepos.Y; int col = m_tx_basepos.X; + // Yawpitch goes rightwards if (m_tx_select_horiz_by_yawpitch) { if (cam_to_entity.Y > 0.75) col += 5; @@ -1206,6 +1207,27 @@ void GenericCAO::updateTexturePos() float tys = m_tx_size.Y; setBillboardTextureMatrix(m_spritenode, txs, tys, col, row); } + + else if (m_meshnode) { + if (m_prop.visual == "upright_sprite") { + int row = m_tx_basepos.Y; + int col = m_tx_basepos.X; + + // Animation goes downwards + row += m_anim_frame; + + const auto &tx = m_tx_size; + v2f t[4] = { // cf. vertices in GenericCAO::addToScene() + tx * v2f(col+1, row+1), + tx * v2f(col, row+1), + tx * v2f(col, row), + tx * v2f(col+1, row), + }; + auto mesh = m_meshnode->getMesh(); + setMeshBufferTextureCoords(mesh->getMeshBuffer(0), t, 4); + setMeshBufferTextureCoords(mesh->getMeshBuffer(1), t, 4); + } + } } // Do not pass by reference, see header. @@ -1247,7 +1269,7 @@ void GenericCAO::updateTextures(std::string mod) } } - if (m_animated_meshnode) { + else if (m_animated_meshnode) { if (m_prop.visual == "mesh") { for (u32 i = 0; i < m_prop.textures.size() && i < m_animated_meshnode->getMaterialCount(); ++i) { @@ -1296,8 +1318,8 @@ void GenericCAO::updateTextures(std::string mod) } } } - if(m_meshnode) - { + + else if (m_meshnode) { if(m_prop.visual == "cube") { for (u32 i = 0; i < 6; ++i) diff --git a/src/client/mesh.cpp b/src/client/mesh.cpp index e1ec22068..2400a374c 100644 --- a/src/client/mesh.cpp +++ b/src/client/mesh.cpp @@ -203,6 +203,15 @@ void setMeshColor(scene::IMesh *mesh, const video::SColor &color) setMeshBufferColor(mesh->getMeshBuffer(j), color); } +void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count) +{ + const u32 stride = getVertexPitchFromType(buf->getVertexType()); + assert(buf->getVertexCount() >= count); + u8 *vertices = (u8 *) buf->getVertices(); + for (u32 i = 0; i < count; i++) + ((video::S3DVertex*) (vertices + i * stride))->TCoords = uv[i]; +} + template static void applyToMesh(scene::IMesh *mesh, const F &fn) { diff --git a/src/client/mesh.h b/src/client/mesh.h index 103c61e45..dbc091a06 100644 --- a/src/client/mesh.h +++ b/src/client/mesh.h @@ -58,6 +58,13 @@ void setMeshBufferColor(scene::IMeshBuffer *buf, const video::SColor &color); */ void setMeshColor(scene::IMesh *mesh, const video::SColor &color); + +/* + Sets texture coords for vertices in the mesh buffer. + `uv[]` must have `count` elements +*/ +void setMeshBufferTextureCoords(scene::IMeshBuffer *buf, const v2f *uv, u32 count); + /* Set a constant color for an animated mesh */ -- cgit v1.2.3 From 542df11bed89ebad786220f1162597353ecc277d Mon Sep 17 00:00:00 2001 From: Paul Ouellette Date: Sat, 1 Aug 2020 11:25:33 -0400 Subject: Fix GCC class-memaccess warnings (#10239) --- src/client/mapblock_mesh.cpp | 7 +++++++ src/noise.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 1020e35f5..2f96ca61f 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -419,7 +419,14 @@ static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs) u8 idx = (dir.X + 2 * dir.Y + 3 * dir.Z) & 7; idx = (idx - 1) * 4; +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif memcpy(vertex_dirs, &vertex_dirs_table[idx], 4 * sizeof(v3s16)); +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif } static void getNodeTextureCoords(v3f base, const v3f &scale, const v3s16 &dir, float *u, float *v) diff --git a/src/noise.cpp b/src/noise.cpp index 5a1d989cb..e16564b05 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -424,7 +424,7 @@ float NoisePerlin3D(NoiseParams *np, float x, float y, float z, s32 seed) Noise::Noise(NoiseParams *np_, s32 seed, u32 sx, u32 sy, u32 sz) { - memcpy(&np, np_, sizeof(np)); + np = *np_; this->seed = seed; this->sx = sx; this->sy = sy; -- cgit v1.2.3 From 291a6b70d674d9003f522b5875a60f7e2753e32b Mon Sep 17 00:00:00 2001 From: ANAND Date: Fri, 5 Jun 2020 18:36:35 +0530 Subject: Allow binding dig, place actions to keys; remove LMB/RMB hardcoding Co-authored-by: Sam Caulfield --- builtin/settingtypes.txt | 14 ++- doc/client_lua_api.txt | 4 +- doc/lua_api.txt | 24 +++-- src/client/client.cpp | 2 +- src/client/content_cao.cpp | 12 +-- src/client/game.cpp | 164 ++++++++++++++++++---------------- src/client/inputhandler.cpp | 166 +++++++++++++++++------------------ src/client/inputhandler.h | 154 +++++++++++--------------------- src/client/keys.h | 2 + src/defaultsettings.cpp | 4 +- src/network/serverpackethandler.cpp | 23 ++--- src/player.h | 12 +-- src/script/lua_api/l_localplayer.cpp | 4 +- src/script/lua_api/l_object.cpp | 9 +- 14 files changed, 284 insertions(+), 310 deletions(-) (limited to 'src/client') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 01736f586..3aa113190 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -110,9 +110,9 @@ doubletap_jump (Double tap jump for fly) bool false # enabled. always_fly_fast (Always fly and fast) bool true -# The time in seconds it takes between repeated right clicks when holding the right -# mouse button. -repeat_rightclick_time (Rightclick repetition interval) float 0.25 0.001 +# The time in seconds it takes between repeated node placements when holding +# the place button. +repeat_place_time (Place repetition interval) float 0.25 0.001 # Automatically jump up single-node obstacles. autojump (Automatic jumping) bool false @@ -182,6 +182,14 @@ keymap_jump (Jump key) key KEY_SPACE # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 keymap_sneak (Sneak key) key KEY_LSHIFT +# Key for digging. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_dig (Dig key) key KEY_LBUTTON + +# Key for placing. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_place (Place key) key KEY_RBUTTON + # Key for opening the inventory. # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 keymap_inventory (Inventory key) key KEY_KEY_I diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 3b0046b4f..4c5231b79 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -1100,8 +1100,8 @@ Methods: aux1 = boolean, sneak = boolean, zoom = boolean, - LMB = boolean, - RMB = boolean, + dig = boolean, + place = boolean, } ``` diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 6366a34c3..88d99fcd5 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6163,15 +6163,23 @@ object you are working with still exists. * Only affects formspecs shown after this is called. * `get_formspec_prepend(formspec)`: returns a formspec string. * `get_player_control()`: returns table with player pressed keys - * The table consists of fields with boolean value representing the pressed - keys, the fields are jump, right, left, LMB, RMB, sneak, aux1, down, up, zoom. - * example: `{jump=false, right=true, left=false, LMB=false, RMB=false, - sneak=true, aux1=false, down=false, up=false, zoom=false}` - * The `zoom` field is available since 5.3 + * The table consists of fields with the following boolean values + representing the pressed keys: `up`, `down`, `left`, `right`, `jump`, + `aux1`, `sneak`, `dig`, `place`, `LMB`, `RMB`, and `zoom`. + * The fields `LMB` and `RMB` are equal to `dig` and `place` respectively, + and exist only to preserve backwards compatibility. * `get_player_control_bits()`: returns integer with bit packed player pressed - keys. - * bit nr/meaning: 0/up, 1/down, 2/left, 3/right, 4/jump, 5/aux1, 6/sneak, - 7/LMB, 8/RMB, 9/zoom (zoom available since 5.3) + keys. Bits: + * 0 - up + * 1 - down + * 2 - left + * 3 - right + * 4 - jump + * 5 - aux1 + * 6 - sneak + * 7 - dig + * 8 - place + * 9 - zoom * `set_physics_override(override_table)` * `override_table` is a table with the following fields: * `speed`: multiplier to default walking speed value (default: `1`) diff --git a/src/client/client.cpp b/src/client/client.cpp index 65e5b3d8c..745cce900 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1307,7 +1307,7 @@ void Client::sendPlayerPos() player->last_pitch == player->getPitch() && player->last_yaw == player->getYaw() && player->last_keyPressed == player->keyPressed && - player->last_camera_fov == camera_fov && + player->last_camera_fov == camera_fov && player->last_wanted_range == wanted_range) return; diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 88688d18c..599139aa3 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -975,13 +975,13 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) if (controls.sneak && walking) new_speed /= 2; - if (walking && (controls.LMB || controls.RMB)) { + if (walking && (controls.dig || controls.place)) { new_anim = player->local_animations[3]; player->last_animation = WD_ANIM; - } else if(walking) { + } else if (walking) { new_anim = player->local_animations[1]; player->last_animation = WALK_ANIM; - } else if(controls.LMB || controls.RMB) { + } else if (controls.dig || controls.place) { new_anim = player->local_animations[2]; player->last_animation = DIG_ANIM; } @@ -1004,9 +1004,9 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) // Update local player animations if ((player->last_animation != old_anim || - m_animation_speed != old_anim_speed) && - player->last_animation != NO_ANIM && allow_update) - updateAnimation(); + m_animation_speed != old_anim_speed) && + player->last_animation != NO_ANIM && allow_update) + updateAnimation(); } } diff --git a/src/client/game.cpp b/src/client/game.cpp index 20d2c6f90..0d3a0ca15 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -604,7 +604,6 @@ public: #endif /**************************************************************************** - ****************************************************************************/ const float object_hit_delay = 0.2; @@ -625,15 +624,15 @@ struct GameRunData { u16 new_playeritem; PointedThing pointed_old; bool digging; - bool ldown_for_dig; + bool punching; + bool btn_down_for_dig; bool dig_instantly; bool digging_blocked; - bool left_punch; bool reset_jump_timer; float nodig_delay_timer; float dig_time; float dig_time_complete; - float repeat_rightclick_timer; + float repeat_place_timer; float object_hit_delay_timer; float time_from_last_punch; ClientActiveObject *selected_object; @@ -787,6 +786,14 @@ protected: { return input->wasKeyDown(k); } + inline bool wasKeyPressed(GameKeyType k) + { + return input->wasKeyPressed(k); + } + inline bool wasKeyReleased(GameKeyType k) + { + return input->wasKeyReleased(k); + } #ifdef __ANDROID__ void handleAndroidChatInput(); @@ -900,7 +907,7 @@ private: bool m_cache_enable_free_move; f32 m_cache_mouse_sensitivity; f32 m_cache_joystick_frustum_sensitivity; - f32 m_repeat_right_click_time; + f32 m_repeat_place_time; f32 m_cache_cam_smoothing; f32 m_cache_fog_start; @@ -934,7 +941,7 @@ Game::Game() : &settingChangedCallback, this); g_settings->registerChangedCallback("joystick_frustum_sensitivity", &settingChangedCallback, this); - g_settings->registerChangedCallback("repeat_rightclick_time", + g_settings->registerChangedCallback("repeat_place_time", &settingChangedCallback, this); g_settings->registerChangedCallback("noclip", &settingChangedCallback, this); @@ -992,7 +999,7 @@ Game::~Game() &settingChangedCallback, this); g_settings->deregisterChangedCallback("mouse_sensitivity", &settingChangedCallback, this); - g_settings->deregisterChangedCallback("repeat_rightclick_time", + g_settings->deregisterChangedCallback("repeat_place_time", &settingChangedCallback, this); g_settings->deregisterChangedCallback("noclip", &settingChangedCallback, this); @@ -2465,8 +2472,8 @@ void Game::updatePlayerControl(const CameraOrientation &cam) isKeyDown(KeyType::SPECIAL1), isKeyDown(KeyType::SNEAK), isKeyDown(KeyType::ZOOM), - input->getLeftState(), - input->getRightState(), + isKeyDown(KeyType::DIG), + isKeyDown(KeyType::PLACE), cam.camera_pitch, cam.camera_yaw, input->joystick.getAxisWithoutDead(JA_SIDEWARD_MOVE), @@ -2481,8 +2488,8 @@ void Game::updatePlayerControl(const CameraOrientation &cam) ( (u32)(isKeyDown(KeyType::JUMP) & 0x1) << 4) | ( (u32)(isKeyDown(KeyType::SPECIAL1) & 0x1) << 5) | ( (u32)(isKeyDown(KeyType::SNEAK) & 0x1) << 6) | - ( (u32)(input->getLeftState() & 0x1) << 7) | - ( (u32)(input->getRightState() & 0x1) << 8) | + ( (u32)(isKeyDown(KeyType::DIG) & 0x1) << 7) | + ( (u32)(isKeyDown(KeyType::PLACE) & 0x1) << 8) | ( (u32)(isKeyDown(KeyType::ZOOM) & 0x1) << 9) ); @@ -3064,7 +3071,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) PointedThing pointed = updatePointedThing(shootline, selected_def.liquids_pointable, - !runData.ldown_for_dig, + !runData.btn_down_for_dig, camera_offset); if (pointed != runData.pointed_old) { @@ -3072,20 +3079,18 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) hud->updateSelectionMesh(camera_offset); } - if (runData.digging_blocked && !input->getLeftState()) { - // allow digging again if button is not pressed + // Allow digging again if button is not pressed + if (runData.digging_blocked && !isKeyDown(KeyType::DIG)) runData.digging_blocked = false; - } /* Stop digging when - - releasing left mouse button + - releasing dig button - pointing away from node */ if (runData.digging) { - if (input->getLeftReleased()) { - infostream << "Left button released" - << " (stopped digging)" << std::endl; + if (wasKeyReleased(KeyType::DIG)) { + infostream << "Dig button released (stopped digging)" << std::endl; runData.digging = false; } else if (pointed != runData.pointed_old) { if (pointed.type == POINTEDTHING_NODE @@ -3095,8 +3100,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) // Still pointing to the same node, but a different face. // Don't reset. } else { - infostream << "Pointing away from node" - << " (stopped digging)" << std::endl; + infostream << "Pointing away from node (stopped digging)" << std::endl; runData.digging = false; hud->updateSelectionMesh(camera_offset); } @@ -3107,55 +3111,57 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) client->setCrack(-1, v3s16(0, 0, 0)); runData.dig_time = 0.0; } - } else if (runData.dig_instantly && input->getLeftReleased()) { - // Remove e.g. torches faster when clicking instead of holding LMB + } else if (runData.dig_instantly && wasKeyReleased(KeyType::DIG)) { + // Remove e.g. torches faster when clicking instead of holding dig button runData.nodig_delay_timer = 0; runData.dig_instantly = false; } - if (!runData.digging && runData.ldown_for_dig && !input->getLeftState()) { - runData.ldown_for_dig = false; - } + if (!runData.digging && runData.btn_down_for_dig && !isKeyDown(KeyType::DIG)) + runData.btn_down_for_dig = false; - runData.left_punch = false; + runData.punching = false; soundmaker->m_player_leftpunch_sound.name = ""; // Prepare for repeating, unless we're not supposed to - if (input->getRightState() && !g_settings->getBool("safe_dig_and_place")) - runData.repeat_rightclick_timer += dtime; + if (isKeyDown(KeyType::PLACE) && !g_settings->getBool("safe_dig_and_place")) + runData.repeat_place_timer += dtime; else - runData.repeat_rightclick_timer = 0; + runData.repeat_place_timer = 0; - if (selected_def.usable && input->getLeftState()) { - if (input->getLeftClicked() && (!client->modsLoaded() - || !client->getScript()->on_item_use(selected_item, pointed))) + if (selected_def.usable && isKeyDown(KeyType::DIG)) { + if (wasKeyPressed(KeyType::DIG) && (!client->modsLoaded() || + !client->getScript()->on_item_use(selected_item, pointed))) client->interact(INTERACT_USE, pointed); } else if (pointed.type == POINTEDTHING_NODE) { handlePointingAtNode(pointed, selected_item, hand_item, dtime); } else if (pointed.type == POINTEDTHING_OBJECT) { v3f player_position = player->getPosition(); handlePointingAtObject(pointed, tool_item, player_position, show_debug); - } else if (input->getLeftState()) { + } else if (isKeyDown(KeyType::DIG)) { // When button is held down in air, show continuous animation - runData.left_punch = true; + runData.punching = true; // Run callback even though item is not usable - if (input->getLeftClicked() && client->modsLoaded()) + if (wasKeyPressed(KeyType::DIG) && client->modsLoaded()) client->getScript()->on_item_use(selected_item, pointed); - } else if (input->getRightClicked()) { + } else if (wasKeyPressed(KeyType::PLACE)) { handlePointingAtNothing(selected_item); } runData.pointed_old = pointed; - if (runData.left_punch || input->getLeftClicked()) - camera->setDigging(0); // left click animation + if (runData.punching || wasKeyPressed(KeyType::DIG)) + camera->setDigging(0); // dig animation - input->resetLeftClicked(); - input->resetRightClicked(); + input->clearWasKeyPressed(); + input->clearWasKeyReleased(); - input->resetLeftReleased(); - input->resetRightReleased(); + input->joystick.clearWasKeyDown(KeyType::MOUSE_L); + input->joystick.clearWasKeyDown(KeyType::MOUSE_R); + + input->joystick.clearWasKeyReleased(KeyType::MOUSE_L); + input->joystick.clearWasKeyReleased(KeyType::MOUSE_R); } @@ -3255,7 +3261,7 @@ PointedThing Game::updatePointedThing( void Game::handlePointingAtNothing(const ItemStack &playerItem) { - infostream << "Right Clicked in Air" << std::endl; + infostream << "Attempted to place item while pointing at nothing" << std::endl; PointedThing fauxPointed; fauxPointed.type = POINTEDTHING_NOTHING; client->interact(INTERACT_ACTIVATE, fauxPointed); @@ -3274,7 +3280,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed, ClientMap &map = client->getEnv().getClientMap(); - if (runData.nodig_delay_timer <= 0.0 && input->getLeftState() + if (runData.nodig_delay_timer <= 0.0 && isKeyDown(KeyType::DIG) && !runData.digging_blocked && client->checkPrivilege("interact")) { handleDigging(pointed, nodepos, selected_item, hand_item, dtime); @@ -3295,13 +3301,14 @@ void Game::handlePointingAtNode(const PointedThing &pointed, } } - if ((input->getRightClicked() || - runData.repeat_rightclick_timer >= m_repeat_right_click_time) && + if ((wasKeyPressed(KeyType::PLACE) || + runData.repeat_place_timer >= m_repeat_place_time) && client->checkPrivilege("interact")) { - runData.repeat_rightclick_timer = 0; - infostream << "Ground right-clicked" << std::endl; + runData.repeat_place_timer = 0; + infostream << "Place button pressed while looking at ground" << std::endl; - camera->setDigging(1); // right click animation (always shown for feedback) + // Placing animation (always shown for feedback) + camera->setDigging(1); soundmaker->m_player_rightpunch_sound = SimpleSoundSpec(); @@ -3367,8 +3374,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, } verbosestream << "Node placement prediction for " - << selected_def.name << " is " - << prediction << std::endl; + << selected_def.name << " is " << prediction << std::endl; v3s16 p = neighbourpos; // Place inside node itself if buildable_to @@ -3529,7 +3535,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed, m_game_ui->setInfoText(infotext); - if (input->getLeftState()) { + if (isKeyDown(KeyType::DIG)) { bool do_punch = false; bool do_punch_damage = false; @@ -3539,12 +3545,12 @@ void Game::handlePointingAtObject(const PointedThing &pointed, runData.object_hit_delay_timer = object_hit_delay; } - if (input->getLeftClicked()) + if (wasKeyPressed(KeyType::DIG)) do_punch = true; if (do_punch) { - infostream << "Left-clicked object" << std::endl; - runData.left_punch = true; + infostream << "Punched object" << std::endl; + runData.punching = true; } if (do_punch_damage) { @@ -3559,8 +3565,8 @@ void Game::handlePointingAtObject(const PointedThing &pointed, if (!disable_send) client->interact(INTERACT_START_DIGGING, pointed); } - } else if (input->getRightClicked()) { - infostream << "Right-clicked object" << std::endl; + } else if (wasKeyDown(KeyType::PLACE)) { + infostream << "Pressed place button while pointing at object" << std::endl; client->interact(INTERACT_PLACE, pointed); // place } } @@ -3606,7 +3612,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, return; client->interact(INTERACT_START_DIGGING, pointed); runData.digging = true; - runData.ldown_for_dig = true; + runData.btn_down_for_dig = true; } if (!runData.dig_instantly) { @@ -3700,7 +3706,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, client->setCrack(-1, nodepos); } - camera->setDigging(0); // left click animation + camera->setDigging(0); // Dig animation } @@ -4039,7 +4045,7 @@ void Game::readSettings() m_cache_enable_fog = g_settings->getBool("enable_fog"); m_cache_mouse_sensitivity = g_settings->getFloat("mouse_sensitivity"); m_cache_joystick_frustum_sensitivity = g_settings->getFloat("joystick_frustum_sensitivity"); - m_repeat_right_click_time = g_settings->getFloat("repeat_rightclick_time"); + m_repeat_place_time = g_settings->getFloat("repeat_place_time"); m_cache_enable_noclip = g_settings->getBool("noclip"); m_cache_enable_free_move = g_settings->getBool("free_move"); @@ -4131,30 +4137,32 @@ void Game::showPauseMenu() "- %s: move backwards\n" "- %s: move left\n" "- %s: move right\n" - "- %s: jump/climb\n" - "- %s: sneak/go down\n" + "- %s: jump/climb up\n" + "- %s: dig/punch\n" + "- %s: place/use\n" + "- %s: sneak/climb down\n" "- %s: drop item\n" "- %s: inventory\n" "- Mouse: turn/look\n" - "- Mouse left: dig/punch\n" - "- Mouse right: place/use\n" "- Mouse wheel: select item\n" "- %s: chat\n" ); - char control_text_buf[600]; - - porting::mt_snprintf(control_text_buf, sizeof(control_text_buf), control_text_template.c_str(), - GET_KEY_NAME(keymap_forward), - GET_KEY_NAME(keymap_backward), - GET_KEY_NAME(keymap_left), - GET_KEY_NAME(keymap_right), - GET_KEY_NAME(keymap_jump), - GET_KEY_NAME(keymap_sneak), - GET_KEY_NAME(keymap_drop), - GET_KEY_NAME(keymap_inventory), - GET_KEY_NAME(keymap_chat) - ); + char control_text_buf[600]; + + porting::mt_snprintf(control_text_buf, sizeof(control_text_buf), control_text_template.c_str(), + GET_KEY_NAME(keymap_forward), + GET_KEY_NAME(keymap_backward), + GET_KEY_NAME(keymap_left), + GET_KEY_NAME(keymap_right), + GET_KEY_NAME(keymap_jump), + GET_KEY_NAME(keymap_dig), + GET_KEY_NAME(keymap_place), + GET_KEY_NAME(keymap_sneak), + GET_KEY_NAME(keymap_drop), + GET_KEY_NAME(keymap_inventory), + GET_KEY_NAME(keymap_chat) + ); std::string control_text = std::string(control_text_buf); str_formspec_escape(control_text); diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index a79b04a90..608a405a8 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -37,6 +37,8 @@ void KeyCache::populate() key[KeyType::JUMP] = getKeySetting("keymap_jump"); key[KeyType::SPECIAL1] = getKeySetting("keymap_special1"); key[KeyType::SNEAK] = getKeySetting("keymap_sneak"); + key[KeyType::DIG] = getKeySetting("keymap_dig"); + key[KeyType::PLACE] = getKeySetting("keymap_place"); key[KeyType::AUTOFORWARD] = getKeySetting("keymap_autoforward"); @@ -111,57 +113,81 @@ bool MyEventReceiver::OnEvent(const SEvent &event) if (event.EventType == irr::EET_KEY_INPUT_EVENT) { const KeyPress &keyCode = event.KeyInput; if (keysListenedFor[keyCode]) { + // If the key is being held down then the OS may + // send a continuous stream of keydown events. + // In this case, we don't want to let this + // stream reach the application as it will cause + // certain actions to repeat constantly. if (event.KeyInput.PressedDown) { + if (!IsKeyDown(keyCode)) { + keyWasDown.set(keyCode); + keyWasPressed.set(keyCode); + } keyIsDown.set(keyCode); - keyWasDown.set(keyCode); } else { + if (IsKeyDown(keyCode)) + keyWasReleased.set(keyCode); + keyIsDown.unset(keyCode); } + return true; } - } #ifdef HAVE_TOUCHSCREENGUI - // case of touchscreengui we have to handle different events - if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) { + } else if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) { + // In case of touchscreengui, we have to handle different events m_touchscreengui->translateEvent(event); return true; - } #endif - if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) { + } else if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) { /* TODO add a check like: if (event.JoystickEvent != joystick_we_listen_for) return false; */ return joystick->handleEvent(event.JoystickEvent); - } - // handle mouse events - if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) { - if (isMenuActive()) { - left_active = false; - middle_active = false; - right_active = false; - } else { - left_active = event.MouseInput.isLeftPressed(); - middle_active = event.MouseInput.isMiddlePressed(); - right_active = event.MouseInput.isRightPressed(); - - if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { - leftclicked = true; - } - if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) { - rightclicked = true; - } - if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) { - leftreleased = true; - } - if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) { - rightreleased = true; - } - if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) { - mouse_wheel += event.MouseInput.Wheel; - } + } else if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) { + // Handle mouse events + KeyPress key; + switch (event.MouseInput.Event) { + case EMIE_LMOUSE_PRESSED_DOWN: + key = "KEY_LBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_MMOUSE_PRESSED_DOWN: + key = "KEY_MBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_RMOUSE_PRESSED_DOWN: + key = "KEY_RBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_LMOUSE_LEFT_UP: + key = "KEY_LBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_MMOUSE_LEFT_UP: + key = "KEY_MBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_RMOUSE_LEFT_UP: + key = "KEY_RBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_MOUSE_WHEEL: + mouse_wheel += event.MouseInput.Wheel; + break; + default: break; } } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) { static const LogLevel irr_loglev_conv[] = { @@ -188,38 +214,28 @@ s32 RandomInputHandler::Rand(s32 min, s32 max) return (myrand() % (max - min + 1)) + min; } +struct RandomInputHandlerSimData { + std::string key; + float counter; + int time_max; +}; + void RandomInputHandler::step(float dtime) { - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_jump")); - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_special1")); - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_forward")); - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_left")); + static RandomInputHandlerSimData rnd_data[] = { + { "keymap_jump", 0.0f, 40 }, + { "keymap_special1", 0.0f, 40 }, + { "keymap_forward", 0.0f, 40 }, + { "keymap_left", 0.0f, 40 }, + { "keymap_dig", 0.0f, 30 }, + { "keymap_place", 0.0f, 15 } + }; + + for (auto &i : rnd_data) { + i.counter -= dtime; + if (i.counter < 0.0) { + i.counter = 0.1 * Rand(1, i.time_max); + keydown.toggle(getKeySetting(i.key.c_str())); } } { @@ -230,29 +246,5 @@ void RandomInputHandler::step(float dtime) mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20)); } } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 30); - leftdown = !leftdown; - if (leftdown) - leftclicked = true; - if (!leftdown) - leftreleased = true; - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 15); - rightdown = !rightdown; - if (rightdown) - rightclicked = true; - if (!rightdown) - rightreleased = true; - } - } mousepos += mousespeed; } diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index fc7998f20..def147a82 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -144,6 +144,14 @@ public: return b; } + // Checks whether a key was just pressed. State will be cleared + // in the subsequent iteration of Game::processPlayerInteraction + bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; } + + // Checks whether a key was just released. State will be cleared + // in the subsequent iteration of Game::processPlayerInteraction + bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; } + void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); } void dontListenForKeys() { keysListenedFor.clear(); } @@ -158,17 +166,20 @@ public: { keyIsDown.clear(); keyWasDown.clear(); + keyWasPressed.clear(); + keyWasReleased.clear(); - leftclicked = false; - rightclicked = false; - leftreleased = false; - rightreleased = false; + mouse_wheel = 0; + } - left_active = false; - middle_active = false; - right_active = false; + void clearWasKeyPressed() + { + keyWasPressed.clear(); + } - mouse_wheel = 0; + void clearWasKeyReleased() + { + keyWasReleased.clear(); } MyEventReceiver() @@ -178,15 +189,6 @@ public: #endif } - bool leftclicked = false; - bool rightclicked = false; - bool leftreleased = false; - bool rightreleased = false; - - bool left_active = false; - bool middle_active = false; - bool right_active = false; - s32 mouse_wheel = 0; JoystickController *joystick = nullptr; @@ -198,8 +200,16 @@ public: private: // The current state of keys KeyList keyIsDown; - // Whether a key has been pressed or not + + // Whether a key was down KeyList keyWasDown; + + // Whether a key has just been pressed + KeyList keyWasPressed; + + // Whether a key has just been released + KeyList keyWasReleased; + // List of keys we listen for // TODO perhaps the type of this is not really // performant as KeyList is designed for few but @@ -226,27 +236,19 @@ public: virtual bool isKeyDown(GameKeyType k) = 0; virtual bool wasKeyDown(GameKeyType k) = 0; + virtual bool wasKeyPressed(GameKeyType k) = 0; + virtual bool wasKeyReleased(GameKeyType k) = 0; virtual bool cancelPressed() = 0; + virtual void clearWasKeyPressed() {} + virtual void clearWasKeyReleased() {} + virtual void listenForKey(const KeyPress &keyCode) {} virtual void dontListenForKeys() {} virtual v2s32 getMousePos() = 0; virtual void setMousePos(s32 x, s32 y) = 0; - virtual bool getLeftState() = 0; - virtual bool getRightState() = 0; - - virtual bool getLeftClicked() = 0; - virtual bool getRightClicked() = 0; - virtual void resetLeftClicked() = 0; - virtual void resetRightClicked() = 0; - - virtual bool getLeftReleased() = 0; - virtual bool getRightReleased() = 0; - virtual void resetLeftReleased() = 0; - virtual void resetRightReleased() = 0; - virtual s32 getMouseWheel() = 0; virtual void step(float dtime) {} @@ -275,10 +277,26 @@ public: { return m_receiver->WasKeyDown(keycache.key[k]) || joystick.wasKeyDown(k); } + virtual bool wasKeyPressed(GameKeyType k) + { + return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyReleased(k); + } + virtual bool wasKeyReleased(GameKeyType k) + { + return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k); + } virtual bool cancelPressed() { return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey); } + virtual void clearWasKeyPressed() + { + m_receiver->clearWasKeyPressed(); + } + virtual void clearWasKeyReleased() + { + m_receiver->clearWasKeyReleased(); + } virtual void listenForKey(const KeyPress &keyCode) { m_receiver->listenForKey(keyCode); @@ -306,59 +324,6 @@ public: } } - virtual bool getLeftState() - { - return m_receiver->left_active || joystick.isKeyDown(KeyType::MOUSE_L); - } - virtual bool getRightState() - { - return m_receiver->right_active || joystick.isKeyDown(KeyType::MOUSE_R); - } - - virtual bool getLeftClicked() - { - return m_receiver->leftclicked || - joystick.getWasKeyDown(KeyType::MOUSE_L); - } - virtual bool getRightClicked() - { - return m_receiver->rightclicked || - joystick.getWasKeyDown(KeyType::MOUSE_R); - } - - virtual void resetLeftClicked() - { - m_receiver->leftclicked = false; - joystick.clearWasKeyDown(KeyType::MOUSE_L); - } - virtual void resetRightClicked() - { - m_receiver->rightclicked = false; - joystick.clearWasKeyDown(KeyType::MOUSE_R); - } - - virtual bool getLeftReleased() - { - return m_receiver->leftreleased || - joystick.wasKeyReleased(KeyType::MOUSE_L); - } - virtual bool getRightReleased() - { - return m_receiver->rightreleased || - joystick.wasKeyReleased(KeyType::MOUSE_R); - } - - virtual void resetLeftReleased() - { - m_receiver->leftreleased = false; - joystick.clearWasKeyReleased(KeyType::MOUSE_L); - } - virtual void resetRightReleased() - { - m_receiver->rightreleased = false; - joystick.clearWasKeyReleased(KeyType::MOUSE_R); - } - virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); } void clear() @@ -384,23 +349,12 @@ public: virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } virtual bool wasKeyDown(GameKeyType k) { return false; } + virtual bool wasKeyPressed(GameKeyType k) { return false; } + virtual bool wasKeyReleased(GameKeyType k) { return false; } virtual bool cancelPressed() { return false; } virtual v2s32 getMousePos() { return mousepos; } virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); } - virtual bool getLeftState() { return leftdown; } - virtual bool getRightState() { return rightdown; } - - virtual bool getLeftClicked() { return leftclicked; } - virtual bool getRightClicked() { return rightclicked; } - virtual void resetLeftClicked() { leftclicked = false; } - virtual void resetRightClicked() { rightclicked = false; } - - virtual bool getLeftReleased() { return leftreleased; } - virtual bool getRightReleased() { return rightreleased; } - virtual void resetLeftReleased() { leftreleased = false; } - virtual void resetRightReleased() { rightreleased = false; } - virtual s32 getMouseWheel() { return 0; } virtual void step(float dtime); @@ -411,10 +365,4 @@ private: KeyList keydown; v2s32 mousepos; v2s32 mousespeed; - bool leftdown = false; - bool rightdown = false; - bool leftclicked = false; - bool rightclicked = false; - bool leftreleased = false; - bool rightreleased = false; }; diff --git a/src/client/keys.h b/src/client/keys.h index 50d3d194b..b6ce59b4a 100644 --- a/src/client/keys.h +++ b/src/client/keys.h @@ -35,6 +35,8 @@ public: SPECIAL1, SNEAK, AUTOFORWARD, + DIG, + PLACE, ESC, diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 07bf0ebb8..103f0fb02 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -73,6 +73,8 @@ void set_default_settings(Settings *settings) settings->setDefault("keymap_right", "KEY_KEY_D"); settings->setDefault("keymap_jump", "KEY_SPACE"); settings->setDefault("keymap_sneak", "KEY_LSHIFT"); + settings->setDefault("keymap_dig", "KEY_LBUTTON"); + settings->setDefault("keymap_place", "KEY_RBUTTON"); settings->setDefault("keymap_drop", "KEY_KEY_Q"); settings->setDefault("keymap_zoom", "KEY_KEY_Z"); settings->setDefault("keymap_inventory", "KEY_KEY_I"); @@ -269,7 +271,7 @@ void set_default_settings(Settings *settings) // Input settings->setDefault("invert_mouse", "false"); settings->setDefault("mouse_sensitivity", "0.2"); - settings->setDefault("repeat_rightclick_time", "0.25"); + settings->setDefault("repeat_place_time", "0.25"); settings->setDefault("safe_dig_and_place", "false"); settings->setDefault("random_input", "false"); settings->setDefault("aux1_descends", "false"); diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index b3008bb50..dcbb114bf 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -491,17 +491,18 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, playersao->setPlayerYaw(yaw); playersao->setFov(fov); playersao->setWantedRange(wanted_range); + player->keyPressed = keyPressed; - player->control.up = (keyPressed & 1); - player->control.down = (keyPressed & 2); - player->control.left = (keyPressed & 4); - player->control.right = (keyPressed & 8); - player->control.jump = (keyPressed & 16); - player->control.aux1 = (keyPressed & 32); - player->control.sneak = (keyPressed & 64); - player->control.LMB = (keyPressed & 128); - player->control.RMB = (keyPressed & 256); - player->control.zoom = (keyPressed & 512); + player->control.up = (keyPressed & (0x1 << 0)); + player->control.down = (keyPressed & (0x1 << 1)); + player->control.left = (keyPressed & (0x1 << 2)); + player->control.right = (keyPressed & (0x1 << 3)); + player->control.jump = (keyPressed & (0x1 << 4)); + player->control.aux1 = (keyPressed & (0x1 << 5)); + player->control.sneak = (keyPressed & (0x1 << 6)); + player->control.dig = (keyPressed & (0x1 << 7)); + player->control.place = (keyPressed & (0x1 << 8)); + player->control.zoom = (keyPressed & (0x1 << 9)); if (playersao->checkMovementCheat()) { // Call callbacks @@ -1670,7 +1671,7 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt) if (client->chosen_mech != AUTH_MECHANISM_SRP && client->chosen_mech != AUTH_MECHANISM_LEGACY_PASSWORD) { actionstream << "Server: got SRP _M packet, while auth" - << "is going on with mech " << client->chosen_mech << " from " + << "is going on with mech " << client->chosen_mech << " from " << addr_s << " (wantSudo=" << wantSudo << "). Denying." << std::endl; if (wantSudo) { DenySudoAccess(peer_id); diff --git a/src/player.h b/src/player.h index 3bc7762fa..ec068a8b1 100644 --- a/src/player.h +++ b/src/player.h @@ -57,8 +57,8 @@ struct PlayerControl bool a_aux1, bool a_sneak, bool a_zoom, - bool a_LMB, - bool a_RMB, + bool a_dig, + bool a_place, float a_pitch, float a_yaw, float a_sidew_move_joystick_axis, @@ -73,8 +73,8 @@ struct PlayerControl aux1 = a_aux1; sneak = a_sneak; zoom = a_zoom; - LMB = a_LMB; - RMB = a_RMB; + dig = a_dig; + place = a_place; pitch = a_pitch; yaw = a_yaw; sidew_move_joystick_axis = a_sidew_move_joystick_axis; @@ -88,8 +88,8 @@ struct PlayerControl bool aux1 = false; bool sneak = false; bool zoom = false; - bool LMB = false; - bool RMB = false; + bool dig = false; + bool place = false; float pitch = 0.0f; float yaw = 0.0f; float sidew_move_joystick_axis = 0.0f; diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index 851ede535..33fa27c8b 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -231,8 +231,8 @@ int LuaLocalPlayer::l_get_control(lua_State *L) set("aux1", c.aux1); set("sneak", c.sneak); set("zoom", c.zoom); - set("LMB", c.LMB); - set("RMB", c.RMB); + set("dig", c.dig); + set("place", c.place); return 1; } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index e7394133a..495d8bced 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1455,9 +1455,14 @@ int ObjectRef::l_get_player_control(lua_State *L) lua_setfield(L, -2, "aux1"); lua_pushboolean(L, control.sneak); lua_setfield(L, -2, "sneak"); - lua_pushboolean(L, control.LMB); + lua_pushboolean(L, control.dig); + lua_setfield(L, -2, "dig"); + lua_pushboolean(L, control.place); + lua_setfield(L, -2, "place"); + // Legacy fields to ensure mod compatibility + lua_pushboolean(L, control.dig); lua_setfield(L, -2, "LMB"); - lua_pushboolean(L, control.RMB); + lua_pushboolean(L, control.place); lua_setfield(L, -2, "RMB"); lua_pushboolean(L, control.zoom); lua_setfield(L, -2, "zoom"); -- cgit v1.2.3 From 5bda36143f9bd332b6ba420d9b91be1713092eae Mon Sep 17 00:00:00 2001 From: hecks <42101236+hecktest@users.noreply.github.com> Date: Wed, 19 Aug 2020 19:26:37 +0200 Subject: Clean up sound_fade (#10119) Add proper documentation and correct gain reduction calculations. Co-authored-by: hecktest <> --- doc/lua_api.txt | 7 ++++-- src/client/sound_openal.cpp | 55 ++++++++++++++++++++++++--------------------- 2 files changed, 35 insertions(+), 27 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 88d99fcd5..ba55033dd 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -5238,9 +5238,12 @@ Sounds * `minetest.sound_fade(handle, step, gain)` * `handle` is a handle returned by `minetest.sound_play` * `step` determines how fast a sound will fade. - Negative step will lower the sound volume, positive step will increase - the sound volume. + The gain will change by this much per second, + until it reaches the target gain. + Note: Older versions used a signed step. This is deprecated, but old + code will still work. (the client uses abs(step) to correct it) * `gain` the target gain for the fade. + Fading to zero will delete the sound. Timing ------ diff --git a/src/client/sound_openal.cpp b/src/client/sound_openal.cpp index 20a651c1d..c1c916e68 100644 --- a/src/client/sound_openal.cpp +++ b/src/client/sound_openal.cpp @@ -337,14 +337,12 @@ private: }; std::unordered_map m_sounds_fading; - float m_fade_delay; public: OpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher): m_fetcher(fetcher), m_device(smg->m_device.get()), m_context(smg->m_context.get()), - m_next_id(1), - m_fade_delay(0) + m_next_id(1) { infostream << "Audio: Initialized: OpenAL " << std::endl; } @@ -616,38 +614,45 @@ public: void fadeSound(int soundid, float step, float gain) { - m_sounds_fading[soundid] = FadeState(step, getSoundGain(soundid), gain); + // Ignore the command if step isn't valid. + if (step == 0) + return; + float current_gain = getSoundGain(soundid); + step = gain - current_gain > 0 ? abs(step) : -abs(step); + if (m_sounds_fading.find(soundid) != m_sounds_fading.end()) { + auto current_fade = m_sounds_fading[soundid]; + // Do not replace the fade if it's equivalent. + if (current_fade.target_gain == gain && current_fade.step == step) + return; + m_sounds_fading.erase(soundid); + } + gain = rangelim(gain, 0, 1); + m_sounds_fading[soundid] = FadeState(step, current_gain, gain); } void doFades(float dtime) { - m_fade_delay += dtime; - - if (m_fade_delay < 0.1f) - return; + for (auto i = m_sounds_fading.begin(); i != m_sounds_fading.end();) { + FadeState& fade = i->second; + assert(fade.step != 0); + fade.current_gain += (fade.step * dtime); - float chkGain = 0; - for (auto i = m_sounds_fading.begin(); - i != m_sounds_fading.end();) { - if (i->second.step < 0.f) - chkGain = -(i->second.current_gain); + if (fade.step < 0.f) + fade.current_gain = std::max(fade.current_gain, fade.target_gain); else - chkGain = i->second.current_gain; + fade.current_gain = std::min(fade.current_gain, fade.target_gain); - if (chkGain < i->second.target_gain) { - i->second.current_gain += (i->second.step * m_fade_delay); - i->second.current_gain = rangelim(i->second.current_gain, 0, 1); - - updateSoundGain(i->first, i->second.current_gain); - ++i; - } else { - if (i->second.target_gain <= 0.f) - stopSound(i->first); + if (fade.current_gain <= 0.f) + stopSound(i->first); + else + updateSoundGain(i->first, fade.current_gain); + // The increment must happen during the erase call, or else it'll segfault. + if (fade.current_gain == fade.target_gain) m_sounds_fading.erase(i++); - } + else + i++; } - m_fade_delay = 0; } bool soundExists(int sound) -- cgit v1.2.3 From 3c2890692bb4c292023a8260cf9ce70f82b2e780 Mon Sep 17 00:00:00 2001 From: adrido Date: Sun, 23 Aug 2020 15:41:04 +0200 Subject: Fix MSVC compiler warnings (#10197) --- src/client/fontengine.h | 2 +- src/gui/guiChatConsole.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client') diff --git a/src/client/fontengine.h b/src/client/fontengine.h index 865b2d3ff..c6efa0df4 100644 --- a/src/client/fontengine.h +++ b/src/client/fontengine.h @@ -48,7 +48,7 @@ struct FontSpec { u16 getHash() { - return (mode << 2) | (bold << 1) | italic; + return (mode << 2) | (static_cast(bold) << 1) | static_cast(italic); } unsigned int size; diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 8de00c12f..575c6ab25 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -545,7 +545,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) if (prompt.getCursorLength() <= 0) return true; std::wstring wselected = prompt.getSelection(); - std::string selected(wselected.begin(), wselected.end()); + std::string selected = wide_to_utf8(wselected); Environment->getOSOperator()->copyToClipboard(selected.c_str()); return true; } @@ -575,7 +575,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event) if (prompt.getCursorLength() <= 0) return true; std::wstring wselected = prompt.getSelection(); - std::string selected(wselected.begin(), wselected.end()); + std::string selected = wide_to_utf8(wselected); Environment->getOSOperator()->copyToClipboard(selected.c_str()); prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, -- cgit v1.2.3 From f27cf4777933f06f85fa2f013d56ca0a2cf1d588 Mon Sep 17 00:00:00 2001 From: Desour Date: Sun, 23 Aug 2020 19:44:25 +0200 Subject: Properly handle mod-errors in on_shutdown --- src/client/game.cpp | 3 ++- src/server.cpp | 17 +++++++++++++++-- src/server.h | 7 ++++++- 3 files changed, 23 insertions(+), 4 deletions(-) (limited to 'src/client') diff --git a/src/client/game.cpp b/src/client/game.cpp index 0d3a0ca15..920383aaf 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1300,7 +1300,8 @@ bool Game::createSingleplayerServer(const std::string &map_dir, return false; } - server = new Server(map_dir, gamespec, simple_singleplayer_mode, bind_addr, false); + server = new Server(map_dir, gamespec, simple_singleplayer_mode, bind_addr, + false, nullptr, error_message); server->start(); return true; diff --git a/src/server.cpp b/src/server.cpp index ef36aedca..7b3978462 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -213,7 +213,8 @@ Server::Server( bool simple_singleplayer_mode, Address bind_addr, bool dedicated, - ChatInterface *iface + ChatInterface *iface, + std::string *on_shutdown_errmsg ): m_bind_addr(bind_addr), m_path_world(path_world), @@ -232,6 +233,7 @@ Server::Server( m_thread(new ServerThread(this)), m_clients(m_con), m_admin_chat(iface), + m_on_shutdown_errmsg(on_shutdown_errmsg), m_modchannel_mgr(new ModChannelMgr()) { if (m_path_world.empty()) @@ -314,7 +316,18 @@ Server::~Server() // Execute script shutdown hooks infostream << "Executing shutdown hooks" << std::endl; - m_script->on_shutdown(); + try { + m_script->on_shutdown(); + } catch (ModError &e) { + errorstream << "ModError: " << e.what() << std::endl; + if (m_on_shutdown_errmsg) { + if (m_on_shutdown_errmsg->empty()) { + *m_on_shutdown_errmsg = std::string("ModError: ") + e.what(); + } else { + *m_on_shutdown_errmsg += std::string("\nModError: ") + e.what(); + } + } + } infostream << "Server: Saving environment metadata" << std::endl; m_env->saveMeta(); diff --git a/src/server.h b/src/server.h index f44716531..be6f60abc 100644 --- a/src/server.h +++ b/src/server.h @@ -131,7 +131,8 @@ public: bool simple_singleplayer_mode, Address bind_addr, bool dedicated, - ChatInterface *iface = nullptr + ChatInterface *iface = nullptr, + std::string *on_shutdown_errmsg = nullptr ); ~Server(); DISABLE_CLASS_COPY(Server); @@ -596,6 +597,10 @@ private: ChatInterface *m_admin_chat; std::string m_admin_nick; + // if a mod-error occurs in the on_shutdown callback, the error message will + // be written into this + std::string *const m_on_shutdown_errmsg; + /* Map edit event queue. Automatically receives all map edits. The constructor of this class registers us to receive them through -- cgit v1.2.3 From 44c98089cf923fda924902bceec4edb01f36ce2c Mon Sep 17 00:00:00 2001 From: mntmn Date: Tue, 25 Aug 2020 20:49:51 +0200 Subject: shaders: Fix transparency on GC7000L (#10036) Workaround for the missing GL_ALPHA_TEST implementation in Mesa (etnaviv driver). --- client/shaders/nodes_shader/opengl_fragment.glsl | 8 ++++++++ client/shaders/object_shader/opengl_fragment.glsl | 8 ++++++++ src/client/shader.cpp | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) (limited to 'src/client') diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 19e6c2d86..7213612bd 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -190,6 +190,14 @@ void main(void) #endif vec4 base = texture2D(baseTexture, uv).rgba; +#ifdef USE_DISCARD + // If alpha is zero, we can just discard the pixel. This fixes transparency + // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa. + if (base.a == 0.0) { + discard; + } +#endif + #ifdef ENABLE_BUMPMAPPING if (use_normalmap) { vec3 L = normalize(lightVec); diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index 0534dc049..2d33ca439 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -129,6 +129,14 @@ void main(void) vec4 base = texture2D(baseTexture, uv).rgba; +#ifdef USE_DISCARD + // If alpha is zero, we can just discard the pixel. This fixes transparency + // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa. + if (base.a == 0.0) { + discard; + } +#endif + #ifdef ENABLE_BUMPMAPPING if (use_normalmap) { vec3 L = normalize(lightVec); diff --git a/src/client/shader.cpp b/src/client/shader.cpp index ee6079f7a..0aba7b118 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -38,6 +38,16 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "client/tile.h" +#if ENABLE_GLES +#ifdef _IRR_COMPILE_WITH_OGLES1_ +#include +#else +#include +#endif +#else +#include +#endif + /* A cache from shader name to shader path */ @@ -607,6 +617,14 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp // Create shaders header std::string shaders_header = "#version 120\n"; +#ifdef __unix__ + // For renderers that should use discard instead of GL_ALPHA_TEST + const char* gl_renderer = (const char*)glGetString(GL_RENDERER); + if (strstr(gl_renderer, "GC7000")) { + shaders_header += "#define USE_DISCARD\n"; + } +#endif + static const char* drawTypes[] = { "NDT_NORMAL", "NDT_AIRLIKE", -- cgit v1.2.3 From 9976f36b18b8d227e3240feb24000dda0916ee44 Mon Sep 17 00:00:00 2001 From: Hugues Ross Date: Sat, 29 Aug 2020 11:41:19 -0400 Subject: Make bgcolor tint button background images (#9818) --- games/devtest/mods/testformspec/formspec.lua | 2 +- src/client/guiscalingfilter.cpp | 5 +---- src/client/guiscalingfilter.h | 3 ++- src/gui/guiButton.cpp | 21 ++++++++++++++------- src/gui/guiButton.h | 1 + 5 files changed, 19 insertions(+), 13 deletions(-) (limited to 'src/client') diff --git a/games/devtest/mods/testformspec/formspec.lua b/games/devtest/mods/testformspec/formspec.lua index 08c1b6dc0..87a05fc96 100644 --- a/games/devtest/mods/testformspec/formspec.lua +++ b/games/devtest/mods/testformspec/formspec.lua @@ -164,7 +164,7 @@ local style_fs = [[ style[one_btn14:hovered+pressed;textcolor=purple] image_button[0,9.6;1,1;testformspec_button_image.png;one_btn14;Bg] - style[one_btn15;border=false;bgimg=testformspec_bg.png;bgimg_hovered=testformspec_bg_hovered.png;bgimg_pressed=testformspec_bg_pressed.png] + style[one_btn15;border=false;bgcolor=#1cc;bgimg=testformspec_bg.png;bgimg_hovered=testformspec_bg_hovered.png;bgimg_pressed=testformspec_bg_pressed.png] item_image_button[1.25,9.6;1,1;testformspec:item;one_btn15;Bg] style[one_btn16;border=false;bgimg=testformspec_bg_9slice.png;bgimg_hovered=testformspec_bg_9slice_hovered.png;bgimg_pressed=testformspec_bg_9slice_pressed.png;bgimg_middle=4,6] diff --git a/src/client/guiscalingfilter.cpp b/src/client/guiscalingfilter.cpp index 4262331bd..406c096e6 100644 --- a/src/client/guiscalingfilter.cpp +++ b/src/client/guiscalingfilter.cpp @@ -172,11 +172,8 @@ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture, const core::rect &rect, const core::rect &middle, - const core::rect *cliprect) + const core::rect *cliprect, const video::SColor *const colors) { - const video::SColor color(255,255,255,255); - const video::SColor colors[] = {color,color,color,color}; - auto originalSize = texture->getOriginalSize(); core::vector2di lowerRightOffset = core::vector2di(originalSize.Width, originalSize.Height) - middle.LowerRightCorner; diff --git a/src/client/guiscalingfilter.h b/src/client/guiscalingfilter.h index b703d91f0..379a4bdb0 100644 --- a/src/client/guiscalingfilter.h +++ b/src/client/guiscalingfilter.h @@ -54,4 +54,5 @@ void draw2DImageFilterScaled(video::IVideoDriver *driver, video::ITexture *txr, */ void draw2DImage9Slice(video::IVideoDriver *driver, video::ITexture *texture, const core::rect &rect, const core::rect &middle, - const core::rect *cliprect = nullptr); + const core::rect *cliprect = nullptr, + const video::SColor *const colors = nullptr); diff --git a/src/gui/guiButton.cpp b/src/gui/guiButton.cpp index e0d6337cd..b98e5de82 100644 --- a/src/gui/guiButton.cpp +++ b/src/gui/guiButton.cpp @@ -313,11 +313,12 @@ void GUIButton::draw() // PATCH video::ITexture* texture = ButtonImages[(u32)imageState].Texture; + video::SColor image_colors[] = { BgColor, BgColor, BgColor, BgColor }; if (BgMiddle.getArea() == 0) { driver->draw2DImage(texture, ScaleImage? AbsoluteRect : core::rect(pos, sourceRect.getSize()), sourceRect, &AbsoluteClippingRect, - 0, UseAlphaChannel); + image_colors, UseAlphaChannel); } else { core::rect middle = BgMiddle; // `-x` is interpreted as `w - x` @@ -327,7 +328,7 @@ void GUIButton::draw() middle.LowerRightCorner.Y += texture->getOriginalSize().Height; draw2DImage9Slice(driver, texture, ScaleImage ? AbsoluteRect : core::rect(pos, sourceRect.getSize()), - middle, &AbsoluteClippingRect); + middle, &AbsoluteClippingRect, image_colors); } // END PATCH } @@ -722,6 +723,8 @@ GUIButton* GUIButton::addButton(IGUIEnvironment *environment, void GUIButton::setColor(video::SColor color) { + BgColor = color; + float d = 0.65f; for (size_t i = 0; i < 4; i++) { video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i); @@ -750,22 +753,26 @@ void GUIButton::setFromStyle(const StyleSpec& style) bool pressed = (style.getState() & StyleSpec::STATE_PRESSED) != 0; if (style.isNotDefault(StyleSpec::BGCOLOR)) { - setColor(style.getColor(StyleSpec::BGCOLOR)); // If we have a propagated hover/press color, we need to automatically // lighten/darken it if (!Styles[style.getState()].isNotDefault(StyleSpec::BGCOLOR)) { - for (size_t i = 0; i < 4; i++) { if (pressed) { - Colors[i] = multiplyColorValue(Colors[i], COLOR_PRESSED_MOD); + BgColor = multiplyColorValue(BgColor, COLOR_PRESSED_MOD); + + for (size_t i = 0; i < 4; i++) + Colors[i] = multiplyColorValue(Colors[i], COLOR_PRESSED_MOD); } else if (hovered) { - Colors[i] = multiplyColorValue(Colors[i], COLOR_HOVERED_MOD); + BgColor = multiplyColorValue(BgColor, COLOR_HOVERED_MOD); + + for (size_t i = 0; i < 4; i++) + Colors[i] = multiplyColorValue(Colors[i], COLOR_HOVERED_MOD); } - } } } else { + BgColor = video::SColor(255, 255, 255, 255); for (size_t i = 0; i < 4; i++) { video::SColor base = Environment->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i); diff --git a/src/gui/guiButton.h b/src/gui/guiButton.h index 95fa1a2a1..4e1b04aac 100644 --- a/src/gui/guiButton.h +++ b/src/gui/guiButton.h @@ -338,5 +338,6 @@ private: core::rect BgMiddle; core::rect Padding; core::vector2d ContentOffset; + video::SColor BgColor; // END PATCH }; -- cgit v1.2.3 From 5c4b560b6812bbdf7a9d3202c95bad5c9df97d66 Mon Sep 17 00:00:00 2001 From: EvidenceB <49488517+EvidenceBKidscode@users.noreply.github.com> Date: Sat, 29 Aug 2020 20:13:30 +0200 Subject: Add compass HUD element (#9312) Co-authored-by: Jean-Patrick Guerrero Co-authored-by: Pierre-Yves Rollo Co-authored-by: SmallJoker --- doc/lua_api.txt | 18 ++++++- src/client/hud.cpp | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/client/hud.h | 8 +++ src/hud.cpp | 1 + src/hud.h | 10 +++- 5 files changed, 175 insertions(+), 2 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 08bdba03e..c81824163 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1451,7 +1451,23 @@ Same as `image`, but does not accept a `position`; the position is instead deter * `world_pos`: World position of the waypoint. * `offset`: offset in pixels from position. +### `compass` +Displays an image oriented or translated according to current heading direction. + +* `size`: The size of this element. Negative values represent percentage + of the screen; e.g. `x=-100` means 100% (width). +* `scale`: Scale of the translated image (used only for dir = 2 or dir = 3). +* `text`: The name of the texture to use. +* `alignment`: The alignment of the image. +* `offset`: Offset in pixels from position. +* `dir`: How the image is rotated/translated: + * 0 - Rotate as heading direction + * 1 - Rotate in reverse direction + * 2 - Translate as landscape direction + * 3 - Translate in reverse direction + +If translation is chosen, texture is repeated horizontally to fill the whole element. Representations of simple things ================================ @@ -7968,7 +7984,7 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`. { hud_elem_type = "image", -- See HUD element types - -- Type of element, can be "image", "text", "statbar", or "inventory" + -- Type of element, can be "image", "text", "statbar", "inventory" or "compass" position = {x=0.5, y=0.5}, -- Left corner position of element diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 2b347c1e0..d3038230c 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -114,6 +114,28 @@ Hud::Hud(gui::IGUIEnvironment *guienv, Client *client, LocalPlayer *player, } else { m_selection_material.MaterialType = video::EMT_SOLID; } + + // Prepare mesh for compass drawing + m_rotation_mesh_buffer.Vertices.set_used(4); + m_rotation_mesh_buffer.Indices.set_used(6); + + video::SColor white(255, 255, 255, 255); + v3f normal(0.f, 0.f, 1.f); + + m_rotation_mesh_buffer.Vertices[0] = video::S3DVertex(v3f(-1.f, -1.f, 0.f), normal, white, v2f(0.f, 1.f)); + m_rotation_mesh_buffer.Vertices[1] = video::S3DVertex(v3f(-1.f, 1.f, 0.f), normal, white, v2f(0.f, 0.f)); + m_rotation_mesh_buffer.Vertices[2] = video::S3DVertex(v3f( 1.f, 1.f, 0.f), normal, white, v2f(1.f, 0.f)); + m_rotation_mesh_buffer.Vertices[3] = video::S3DVertex(v3f( 1.f, -1.f, 0.f), normal, white, v2f(1.f, 1.f)); + + m_rotation_mesh_buffer.Indices[0] = 0; + m_rotation_mesh_buffer.Indices[1] = 1; + m_rotation_mesh_buffer.Indices[2] = 2; + m_rotation_mesh_buffer.Indices[3] = 2; + m_rotation_mesh_buffer.Indices[4] = 3; + m_rotation_mesh_buffer.Indices[5] = 0; + + m_rotation_mesh_buffer.getMaterial().Lighting = false; + m_rotation_mesh_buffer.getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; } Hud::~Hud() @@ -423,6 +445,54 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) core::rect(core::position2d(0,0), imgsize), NULL, colors, true); break; } + case HUD_ELEM_COMPASS: { + video::ITexture *texture = tsrc->getTexture(e->text); + if (!texture) + continue; + + // Positionning : + v2s32 dstsize(e->size.X, e->size.Y); + if (e->size.X < 0) + dstsize.X = m_screensize.X * (e->size.X * -0.01); + if (e->size.Y < 0) + dstsize.Y = m_screensize.Y * (e->size.Y * -0.01); + + if (dstsize.X <= 0 || dstsize.Y <= 0) + return; // Avoid zero divides + + // Angle according to camera view + v3f fore(0.f, 0.f, 1.f); + scene::ICameraSceneNode *cam = RenderingEngine::get_scene_manager()->getActiveCamera(); + cam->getAbsoluteTransformation().rotateVect(fore); + int angle = - fore.getHorizontalAngle().Y; + + // Limit angle and ajust with given offset + angle = (angle + (int)e->number) % 360; + + core::rect dstrect(0, 0, dstsize.X, dstsize.Y); + dstrect += pos + v2s32( + (e->align.X - 1.0) * dstsize.X / 2, + (e->align.Y - 1.0) * dstsize.Y / 2) + + v2s32(e->offset.X * m_hud_scaling, e->offset.Y * m_hud_scaling); + + switch (e->dir) { + case HUD_COMPASS_ROTATE: + drawCompassRotate(e, texture, dstrect, angle); + break; + case HUD_COMPASS_ROTATE_REVERSE: + drawCompassRotate(e, texture, dstrect, -angle); + break; + case HUD_COMPASS_TRANSLATE: + drawCompassTranslate(e, texture, dstrect, angle); + break; + case HUD_COMPASS_TRANSLATE_REVERSE: + drawCompassTranslate(e, texture, dstrect, -angle); + break; + default: + break; + } + + break; } default: infostream << "Hud::drawLuaElements: ignoring drawform " << e->type << " of hud element ID " << i << " due to unrecognized type" << std::endl; @@ -430,6 +500,76 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) } } +void Hud::drawCompassTranslate(HudElement *e, video::ITexture *texture, + const core::rect &rect, int angle) +{ + const video::SColor color(255, 255, 255, 255); + const video::SColor colors[] = {color, color, color, color}; + + // Compute source image scaling + core::dimension2di imgsize(texture->getOriginalSize()); + core::rect srcrect(0, 0, imgsize.Width, imgsize.Height); + + v2s32 dstsize(rect.getHeight() * e->scale.X * imgsize.Width / imgsize.Height, + rect.getHeight() * e->scale.Y); + + // Avoid infinite loop + if (dstsize.X <= 0 || dstsize.Y <= 0) + return; + + core::rect tgtrect(0, 0, dstsize.X, dstsize.Y); + tgtrect += v2s32( + (rect.getWidth() - dstsize.X) / 2, + (rect.getHeight() - dstsize.Y) / 2) + + rect.UpperLeftCorner; + + int offset = angle * dstsize.X / 360; + + tgtrect += v2s32(offset, 0); + + // Repeat image as much as needed + while (tgtrect.UpperLeftCorner.X > rect.UpperLeftCorner.X) + tgtrect -= v2s32(dstsize.X, 0); + + draw2DImageFilterScaled(driver, texture, tgtrect, srcrect, &rect, colors, true); + tgtrect += v2s32(dstsize.X, 0); + + while (tgtrect.UpperLeftCorner.X < rect.LowerRightCorner.X) { + draw2DImageFilterScaled(driver, texture, tgtrect, srcrect, &rect, colors, true); + tgtrect += v2s32(dstsize.X, 0); + } +} + +void Hud::drawCompassRotate(HudElement *e, video::ITexture *texture, + const core::rect &rect, int angle) +{ + core::dimension2di imgsize(texture->getOriginalSize()); + + core::rect oldViewPort = driver->getViewPort(); + core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); + core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); + + core::matrix4 Matrix; + Matrix.makeIdentity(); + Matrix.setRotationDegrees(v3f(0.f, 0.f, angle)); + + driver->setViewPort(rect); + driver->setTransform(video::ETS_PROJECTION, core::matrix4()); + driver->setTransform(video::ETS_VIEW, core::matrix4()); + driver->setTransform(video::ETS_WORLD, Matrix); + + video::SMaterial &material = m_rotation_mesh_buffer.getMaterial(); + material.TextureLayer[0].Texture = texture; + driver->setMaterial(material); + driver->drawMeshBuffer(&m_rotation_mesh_buffer); + + driver->setTransform(video::ETS_WORLD, core::matrix4()); + driver->setTransform(video::ETS_VIEW, oldViewMat); + driver->setTransform(video::ETS_PROJECTION, oldProjMat); + + // restore the view area + driver->setViewPort(oldViewPort); +} void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, const std::string &texture, const std::string &bgtexture, diff --git a/src/client/hud.h b/src/client/hud.h index ba34d479d..cf83cb16e 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -95,6 +95,12 @@ private: void drawItem(const ItemStack &item, const core::rect &rect, bool selected); + void drawCompassTranslate(HudElement *e, video::ITexture *texture, + const core::rect &rect, int way); + + void drawCompassRotate(HudElement *e, video::ITexture *texture, + const core::rect &rect, int way); + float m_hud_scaling; // cached minetest setting float m_scale_factor; v3s16 m_camera_offset; @@ -115,6 +121,8 @@ private: video::SMaterial m_selection_material; + scene::SMeshBuffer m_rotation_mesh_buffer; + enum { HIGHLIGHT_BOX, diff --git a/src/hud.cpp b/src/hud.cpp index 4830c56a4..175701342 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -28,6 +28,7 @@ const struct EnumString es_HudElementType[] = {HUD_ELEM_INVENTORY, "inventory"}, {HUD_ELEM_WAYPOINT, "waypoint"}, {HUD_ELEM_IMAGE_WAYPOINT, "image_waypoint"}, + {HUD_ELEM_COMPASS, "compass"}, {0, NULL}, }; diff --git a/src/hud.h b/src/hud.h index e015baec1..0a6993c1b 100644 --- a/src/hud.h +++ b/src/hud.h @@ -60,7 +60,8 @@ enum HudElementType { HUD_ELEM_STATBAR = 2, HUD_ELEM_INVENTORY = 3, HUD_ELEM_WAYPOINT = 4, - HUD_ELEM_IMAGE_WAYPOINT = 5 + HUD_ELEM_IMAGE_WAYPOINT = 5, + HUD_ELEM_COMPASS = 6 }; enum HudElementStat { @@ -79,6 +80,13 @@ enum HudElementStat { HUD_STAT_TEXT2, }; +enum HudCompassDir { + HUD_COMPASS_ROTATE = 0, + HUD_COMPASS_ROTATE_REVERSE, + HUD_COMPASS_TRANSLATE, + HUD_COMPASS_TRANSLATE_REVERSE, +}; + struct HudElement { HudElementType type; v2f pos; -- cgit v1.2.3 From b3ace8f19746b53f839e7b0bdff0843c83866f64 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 4 Sep 2020 20:49:50 +0200 Subject: Scale inventory image for scaled allfaces nodes (#10225) The inventory image size of the inventory image of nodes with drawtype allfaces (and related) is scaled as well if visual_scale is set (previously, the inventory image size was always the same) --- games/devtest/mods/testnodes/drawtypes.lua | 9 +++++++++ src/client/wieldmesh.cpp | 2 ++ 2 files changed, 11 insertions(+) (limited to 'src/client') diff --git a/games/devtest/mods/testnodes/drawtypes.lua b/games/devtest/mods/testnodes/drawtypes.lua index 6bf57fa37..82d862819 100644 --- a/games/devtest/mods/testnodes/drawtypes.lua +++ b/games/devtest/mods/testnodes/drawtypes.lua @@ -514,6 +514,15 @@ local scale = function(subname, desc_double, desc_half) minetest.register_node("testnodes:"..subname.."_half", def) end +scale("allfaces", + S("Double-sized Allfaces Drawtype Test Node"), + S("Half-sized Allfaces Drawtype Test Node")) +scale("allfaces_optional", + S("Double-sized Allfaces Optional Drawtype Test Node"), + S("Half-sized Allfaces Optional Drawtype Test Node")) +scale("allfaces_optional_waving", + S("Double-sized Waving Allfaces Optional Drawtype Test Node"), + S("Half-sized Waving Allfaces Optional Drawtype Test Node")) scale("plantlike", S("Double-sized Plantlike Drawtype Test Node"), S("Half-sized Plantlike Drawtype Test Node")) diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index a268895ed..285cc38e5 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -562,6 +562,8 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result) // add overlays postProcessNodeMesh(mesh, f, false, false, nullptr, &result->buffer_colors, true); + if (f.drawtype == NDT_ALLFACES) + scaleMesh(mesh, v3f(f.visual_scale)); break; } case NDT_PLANTLIKE: { -- cgit v1.2.3 From 62913b872ea1b21a5aada55ed323476fbcea61dc Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 9 Sep 2020 18:12:03 +0100 Subject: Darwin platform build fix (#10376) the event header seemingly being generic with libevent thus renaming it. openal and opengl are deprecated on newer mac os releases thus suppressing the build warnings. --- src/client/camera.cpp | 2 +- src/client/clientenvironment.cpp | 2 +- src/client/event_manager.h | 2 +- src/client/localplayer.cpp | 2 +- src/client/shader.cpp | 5 +++ src/client/sound_openal.cpp | 1 + src/event.h | 71 ---------------------------------------- src/mtevent.h | 71 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 81 insertions(+), 75 deletions(-) delete mode 100644 src/event.h create mode 100644 src/mtevent.h (limited to 'src/client') diff --git a/src/client/camera.cpp b/src/client/camera.cpp index abc55e4b7..11f8a1c90 100644 --- a/src/client/camera.cpp +++ b/src/client/camera.cpp @@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "wieldmesh.h" #include "noise.h" // easeCurve #include "sound.h" -#include "event.h" +#include "mtevent.h" #include "nodedef.h" #include "util/numeric.h" #include "constants.h" diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index 895b0193c..0b7e92325 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "clientmap.h" #include "scripting_client.h" #include "mapblock_mesh.h" -#include "event.h" +#include "mtevent.h" #include "collision.h" #include "nodedef.h" #include "profiler.h" diff --git a/src/client/event_manager.h b/src/client/event_manager.h index 3762e89bf..16f7bcf07 100644 --- a/src/client/event_manager.h +++ b/src/client/event_manager.h @@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once -#include "event.h" +#include "mtevent.h" #include #include diff --git a/src/client/localplayer.cpp b/src/client/localplayer.cpp index 1e7040d57..f3eb1a2dd 100644 --- a/src/client/localplayer.cpp +++ b/src/client/localplayer.cpp @@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "localplayer.h" #include -#include "event.h" +#include "mtevent.h" #include "collision.h" #include "nodedef.h" #include "settings.h" diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 0aba7b118..fc0a72319 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -45,7 +45,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #endif #else +#ifndef __APPLE__ #include +#else +#define GL_SILENCE_DEPRECATION +#include +#endif #endif /* diff --git a/src/client/sound_openal.cpp b/src/client/sound_openal.cpp index c1c916e68..f4e61f93e 100644 --- a/src/client/sound_openal.cpp +++ b/src/client/sound_openal.cpp @@ -28,6 +28,7 @@ with this program; ifnot, write to the Free Software Foundation, Inc., #include //#include #elif defined(__APPLE__) + #define OPENAL_DEPRECATED #include #include //#include diff --git a/src/event.h b/src/event.h deleted file mode 100644 index 149f7eecd..000000000 --- a/src/event.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -Minetest -Copyright (C) 2013 celeron55, Perttu Ahola - -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 "irrlichttypes.h" - -class MtEvent -{ -public: - enum Type : u8 - { - VIEW_BOBBING_STEP = 0, - CAMERA_PUNCH_LEFT, - CAMERA_PUNCH_RIGHT, - PLAYER_FALLING_DAMAGE, - PLAYER_DAMAGE, - NODE_DUG, - PLAYER_JUMP, - PLAYER_REGAIN_GROUND, - TYPE_MAX, - }; - - virtual ~MtEvent() = default; - virtual Type getType() const = 0; -}; - -// An event with no parameters and customizable name -class SimpleTriggerEvent : public MtEvent -{ - Type type; - -public: - SimpleTriggerEvent(Type type) : type(type) {} - Type getType() const override { return type; } -}; - -class MtEventReceiver -{ -public: - virtual ~MtEventReceiver() = default; - virtual void onEvent(MtEvent *e) = 0; -}; - -typedef void (*event_receive_func)(MtEvent *e, void *data); - -class MtEventManager -{ -public: - virtual ~MtEventManager() = default; - virtual void put(MtEvent *e) = 0; - virtual void reg(MtEvent::Type type, event_receive_func f, void *data) = 0; - // If data==NULL, every occurence of f is deregistered. - virtual void dereg(MtEvent::Type type, event_receive_func f, void *data) = 0; -}; diff --git a/src/mtevent.h b/src/mtevent.h new file mode 100644 index 000000000..149f7eecd --- /dev/null +++ b/src/mtevent.h @@ -0,0 +1,71 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +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 "irrlichttypes.h" + +class MtEvent +{ +public: + enum Type : u8 + { + VIEW_BOBBING_STEP = 0, + CAMERA_PUNCH_LEFT, + CAMERA_PUNCH_RIGHT, + PLAYER_FALLING_DAMAGE, + PLAYER_DAMAGE, + NODE_DUG, + PLAYER_JUMP, + PLAYER_REGAIN_GROUND, + TYPE_MAX, + }; + + virtual ~MtEvent() = default; + virtual Type getType() const = 0; +}; + +// An event with no parameters and customizable name +class SimpleTriggerEvent : public MtEvent +{ + Type type; + +public: + SimpleTriggerEvent(Type type) : type(type) {} + Type getType() const override { return type; } +}; + +class MtEventReceiver +{ +public: + virtual ~MtEventReceiver() = default; + virtual void onEvent(MtEvent *e) = 0; +}; + +typedef void (*event_receive_func)(MtEvent *e, void *data); + +class MtEventManager +{ +public: + virtual ~MtEventManager() = default; + virtual void put(MtEvent *e) = 0; + virtual void reg(MtEvent::Type type, event_receive_func f, void *data) = 0; + // If data==NULL, every occurence of f is deregistered. + virtual void dereg(MtEvent::Type type, event_receive_func f, void *data) = 0; +}; -- cgit v1.2.3 From fcff9f291103411af6d8f946fbb275b6fa0583b9 Mon Sep 17 00:00:00 2001 From: hecks <42101236+hecktest@users.noreply.github.com> Date: Mon, 14 Sep 2020 19:27:25 +0200 Subject: Remove "generate normal maps" feature (#10313) Erase all traces of normal "generation" from fragment shaders Remove the "feature" from the engine and default config Remove any leftover documentation of it --- builtin/mainmenu/tab_settings.lua | 22 ++++------- builtin/settingtypes.txt | 14 +------ client/shaders/nodes_shader/opengl_fragment.glsl | 47 +---------------------- client/shaders/object_shader/opengl_fragment.glsl | 31 --------------- minetest.conf.example | 17 +------- src/client/shader.cpp | 28 -------------- src/defaultsettings.cpp | 3 -- src/settings_translation_file.cpp | 8 +--- 8 files changed, 12 insertions(+), 158 deletions(-) (limited to 'src/client') diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index 02b15c81b..510346f8d 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -191,15 +191,13 @@ local function formspec(tabview, name, tabdata) .. dump(core.settings:get_bool("enable_bumpmapping")) .. "]" .. "checkbox[8.25,1;cb_tonemapping;" .. fgettext("Tone Mapping") .. ";" .. dump(core.settings:get_bool("tone_mapping")) .. "]" .. - "checkbox[8.25,1.5;cb_generate_normalmaps;" .. fgettext("Generate Normal Maps") .. ";" - .. dump(core.settings:get_bool("generate_normalmaps")) .. "]" .. - "checkbox[8.25,2;cb_parallax;" .. fgettext("Parallax Occlusion") .. ";" + "checkbox[8.25,1.5;cb_parallax;" .. fgettext("Parallax Occlusion") .. ";" .. dump(core.settings:get_bool("enable_parallax_occlusion")) .. "]" .. - "checkbox[8.25,2.5;cb_waving_water;" .. fgettext("Waving Liquids") .. ";" + "checkbox[8.25,2;cb_waving_water;" .. fgettext("Waving Liquids") .. ";" .. dump(core.settings:get_bool("enable_waving_water")) .. "]" .. - "checkbox[8.25,3;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";" + "checkbox[8.25,2.5;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";" .. dump(core.settings:get_bool("enable_waving_leaves")) .. "]" .. - "checkbox[8.25,3.5;cb_waving_plants;" .. fgettext("Waving Plants") .. ";" + "checkbox[8.25,3;cb_waving_plants;" .. fgettext("Waving Plants") .. ";" .. dump(core.settings:get_bool("enable_waving_plants")) .. "]" else tab_string = tab_string .. @@ -208,14 +206,12 @@ local function formspec(tabview, name, tabdata) "label[8.38,1.2;" .. core.colorize("#888888", fgettext("Tone Mapping")) .. "]" .. "label[8.38,1.7;" .. core.colorize("#888888", - fgettext("Generate Normal Maps")) .. "]" .. - "label[8.38,2.2;" .. core.colorize("#888888", fgettext("Parallax Occlusion")) .. "]" .. - "label[8.38,2.7;" .. core.colorize("#888888", + "label[8.38,2.2;" .. core.colorize("#888888", fgettext("Waving Liquids")) .. "]" .. - "label[8.38,3.2;" .. core.colorize("#888888", + "label[8.38,2.7;" .. core.colorize("#888888", fgettext("Waving Leaves")) .. "]" .. - "label[8.38,3.7;" .. core.colorize("#888888", + "label[8.38,3.2;" .. core.colorize("#888888", fgettext("Waving Plants")) .. "]" end @@ -275,10 +271,6 @@ local function handle_settings_buttons(this, fields, tabname, tabdata) core.settings:set("tone_mapping", fields["cb_tonemapping"]) return true end - if fields["cb_generate_normalmaps"] then - core.settings:set("generate_normalmaps", fields["cb_generate_normalmaps"]) - return true - end if fields["cb_parallax"] then core.settings:set("enable_parallax_occlusion", fields["cb_parallax"]) return true diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 39cc22d62..6d9c6f573 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -543,22 +543,10 @@ tone_mapping (Filmic tone mapping) bool false [***Bumpmapping] -# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack -# or need to be auto-generated. +# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack. # Requires shaders to be enabled. enable_bumpmapping (Bumpmapping) bool false -# Enables on the fly normalmap generation (Emboss effect). -# Requires bumpmapping to be enabled. -generate_normalmaps (Generate normalmaps) bool false - -# Strength of generated normalmaps. -normalmaps_strength (Normalmaps strength) float 0.6 - -# Defines sampling step of texture. -# A higher value results in smoother normal maps. -normalmaps_smooth (Normalmaps sampling) int 0 0 2 - [***Parallax Occlusion] # Enables parallax occlusion mapping. diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 7213612bd..437b325d3 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -71,16 +71,6 @@ void get_texture_flags() } } -float intensity(vec3 color) -{ - return (color.r + color.g + color.b) / 3.0; -} - -float get_rgb_height(vec2 uv) -{ - return intensity(texture2D(baseTexture, uv).rgb); -} - vec4 get_normal_map(vec2 uv) { vec4 bump = texture2D(normalTexture, uv).rgba; @@ -115,19 +105,6 @@ float find_intersection(vec2 dp, vec2 ds) return best_depth; } -float find_intersectionRGB(vec2 dp, vec2 ds) -{ - const float depth_step = 1.0 / 24.0; - float depth = 1.0; - for (int i = 0 ; i < 24 ; i++) { - float h = get_rgb_height(dp + ds * depth); - if (h >= depth) - break; - depth -= depth_step; - } - return depth; -} - void main(void) { vec3 color; @@ -149,21 +126,17 @@ void main(void) float h = normal.a * scale - bias; uv += h * normal.z * eyeRay; } + } #endif - #if PARALLAX_OCCLUSION_MODE == 1 // Relief mapping if (normalTexturePresent && area_enable_parallax > 0.0) { vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE; float dist = find_intersection(uv, ds); uv += dist * ds; -#endif - } else if (GENERATE_NORMALMAPS == 1 && area_enable_parallax > 0.0) { - vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE; - float dist = find_intersectionRGB(uv, ds); - uv += dist * ds; } #endif +#endif #if USE_NORMALMAPS == 1 if (normalTexturePresent) { @@ -172,22 +145,6 @@ void main(void) } #endif -#if GENERATE_NORMALMAPS == 1 - if (normalTexturePresent == false) { - float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP)); - float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP)); - float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP)); - float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y)); - float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP)); - float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP)); - float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP)); - float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y)); - float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); - float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); - bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0); - use_normalmap = true; - } -#endif vec4 base = texture2D(baseTexture, uv).rgba; #ifdef USE_DISCARD diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index 2d33ca439..a8a43e1e2 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -74,20 +74,6 @@ void get_texture_flags() } } -float intensity(vec3 color) -{ - return (color.r + color.g + color.b) / 3.0; -} - -float get_rgb_height(vec2 uv) -{ - if (texSeamless) { - return intensity(texture2D(baseTexture, uv).rgb); - } else { - return intensity(texture2D(baseTexture, clamp(uv, 0.0, 0.999)).rgb); - } -} - vec4 get_normal_map(vec2 uv) { vec4 bump = texture2D(normalTexture, uv).rgba; @@ -110,23 +96,6 @@ void main(void) } #endif -#if GENERATE_NORMALMAPS == 1 - if (normalTexturePresent == false) { - float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP)); - float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP)); - float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP)); - float r = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y)); - float br = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y - SAMPLE_STEP)); - float b = get_rgb_height(vec2(uv.x, uv.y - SAMPLE_STEP)); - float bl = get_rgb_height(vec2(uv.x -SAMPLE_STEP, uv.y - SAMPLE_STEP)); - float l = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y)); - float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl); - float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr); - bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0); - use_normalmap = true; - } -#endif - vec4 base = texture2D(baseTexture, uv).rgba; #ifdef USE_DISCARD diff --git a/minetest.conf.example b/minetest.conf.example index 520125713..6b315b6ea 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -604,26 +604,11 @@ #### Bumpmapping -# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack -# or need to be auto-generated. +# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack. # Requires shaders to be enabled. # type: bool # enable_bumpmapping = false -# Enables on the fly normalmap generation (Emboss effect). -# Requires bumpmapping to be enabled. -# type: bool -# generate_normalmaps = false - -# Strength of generated normalmaps. -# type: float -# normalmaps_strength = 0.6 - -# Defines sampling step of texture. -# A higher value results in smoother normal maps. -# type: int min: 0 max: 2 -# normalmaps_smooth = 0 - #### Parallax Occlusion # Enables parallax occlusion mapping. diff --git a/src/client/shader.cpp b/src/client/shader.cpp index fc0a72319..c5fe5dfe0 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -688,34 +688,6 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += itos(drawtype); shaders_header += "\n"; - if (g_settings->getBool("generate_normalmaps")) { - shaders_header += "#define GENERATE_NORMALMAPS 1\n"; - } else { - shaders_header += "#define GENERATE_NORMALMAPS 0\n"; - } - shaders_header += "#define NORMALMAPS_STRENGTH "; - shaders_header += ftos(g_settings->getFloat("normalmaps_strength")); - shaders_header += "\n"; - float sample_step; - int smooth = (int)g_settings->getFloat("normalmaps_smooth"); - switch (smooth){ - case 0: - sample_step = 0.0078125; // 1.0 / 128.0 - break; - case 1: - sample_step = 0.00390625; // 1.0 / 256.0 - break; - case 2: - sample_step = 0.001953125; // 1.0 / 512.0 - break; - default: - sample_step = 0.0078125; - break; - } - shaders_header += "#define SAMPLE_STEP "; - shaders_header += ftos(sample_step); - shaders_header += "\n"; - if (g_settings->getBool("enable_bumpmapping")) shaders_header += "#define ENABLE_BUMPMAPPING\n"; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index d2115c959..3a0b88dc2 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -253,9 +253,6 @@ void set_default_settings(Settings *settings) settings->setDefault("tone_mapping", "false"); settings->setDefault("enable_bumpmapping", "false"); settings->setDefault("enable_parallax_occlusion", "false"); - settings->setDefault("generate_normalmaps", "false"); - settings->setDefault("normalmaps_strength", "0.6"); - settings->setDefault("normalmaps_smooth", "1"); settings->setDefault("parallax_occlusion_mode", "1"); settings->setDefault("parallax_occlusion_iterations", "4"); settings->setDefault("parallax_occlusion_scale", "0.08"); diff --git a/src/settings_translation_file.cpp b/src/settings_translation_file.cpp index febfbb9d3..0cd772337 100644 --- a/src/settings_translation_file.cpp +++ b/src/settings_translation_file.cpp @@ -242,13 +242,7 @@ fake_function() { gettext("Enables Hable's 'Uncharted 2' filmic tone mapping.\nSimulates the tone curve of photographic film and how this approximates the\nappearance of high dynamic range images. Mid-range contrast is slightly\nenhanced, highlights and shadows are gradually compressed."); gettext("Bumpmapping"); gettext("Bumpmapping"); - gettext("Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack\nor need to be auto-generated.\nRequires shaders to be enabled."); - gettext("Generate normalmaps"); - gettext("Enables on the fly normalmap generation (Emboss effect).\nRequires bumpmapping to be enabled."); - gettext("Normalmaps strength"); - gettext("Strength of generated normalmaps."); - gettext("Normalmaps sampling"); - gettext("Defines sampling step of texture.\nA higher value results in smoother normal maps."); + gettext("Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack.\nRequires shaders to be enabled."); gettext("Parallax Occlusion"); gettext("Parallax occlusion"); gettext("Enables parallax occlusion mapping.\nRequires shaders to be enabled."); -- cgit v1.2.3 From 9ec75d77651c333eca3c5b46a3a56c8353fed464 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 16 Sep 2020 14:51:11 +0100 Subject: Clean up server-side translations, remove global variable (#10075) --- src/client/client.cpp | 9 ++------ src/filesys.cpp | 15 +++++++++++++ src/filesys.h | 2 ++ src/script/lua_api/l_env.cpp | 6 ++--- src/server.cpp | 53 ++++++++++++++++++-------------------------- src/server.h | 7 ++++-- src/serverlist.cpp | 10 +-------- src/translation.cpp | 8 ------- src/translation.h | 5 ----- 9 files changed, 50 insertions(+), 65 deletions(-) (limited to 'src/client') diff --git a/src/client/client.cpp b/src/client/client.cpp index 745cce900..d6e529c40 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -238,18 +238,13 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo infostream << "Client::scanModSubfolder(): Loading \"" << real_path << "\" as \"" << vfs_path << "\"." << std::endl; - std::ifstream is(real_path, std::ios::binary | std::ios::ate); - if(!is.good()) { + std::string contents; + if (!fs::ReadFile(real_path, contents)) { errorstream << "Client::scanModSubfolder(): Can't read file \"" << real_path << "\"." << std::endl; continue; } - auto size = is.tellg(); - std::string contents(size, '\0'); - is.seekg(0); - is.read(&contents[0], size); - infostream << " size: " << size << " bytes" << std::endl; m_mod_vfs.emplace(vfs_path, contents); } } diff --git a/src/filesys.cpp b/src/filesys.cpp index 0bc351669..2470b1b64 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -750,6 +750,21 @@ bool safeWriteToFile(const std::string &path, const std::string &content) return true; } +bool ReadFile(const std::string &path, std::string &out) +{ + std::ifstream is(path, std::ios::binary | std::ios::ate); + if (!is.good()) { + return false; + } + + auto size = is.tellg(); + out.resize(size); + is.seekg(0); + is.read(&out[0], size); + + return true; +} + bool Rename(const std::string &from, const std::string &to) { return rename(from.c_str(), to.c_str()) == 0; diff --git a/src/filesys.h b/src/filesys.h index 09f129aa3..b2c800c55 100644 --- a/src/filesys.h +++ b/src/filesys.h @@ -128,6 +128,8 @@ const char *GetFilenameFromPath(const char *path); bool safeWriteToFile(const std::string &path, const std::string &content); +bool ReadFile(const std::string &path, std::string &out); + bool Rename(const std::string &from, const std::string &to); } // namespace fs diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index b2bc8c5f6..138e88ae8 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -1340,9 +1340,9 @@ int ModApiEnvMod::l_get_translated_string(lua_State * L) GET_ENV_PTR; std::string lang_code = luaL_checkstring(L, 1); std::string string = luaL_checkstring(L, 2); - getServer(L)->loadTranslationLanguage(lang_code); - string = wide_to_utf8(translate_string(utf8_to_wide(string), - &(*g_server_translations)[lang_code])); + + auto *translations = getServer(L)->getTranslationLanguage(lang_code); + string = wide_to_utf8(translate_string(utf8_to_wide(string), translations)); lua_pushstring(L, string.c_str()); return 1; } diff --git a/src/server.cpp b/src/server.cpp index 7b3978462..b8a99f6ae 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2451,31 +2451,14 @@ bool Server::addMediaFile(const std::string &filename, // Ok, attempt to load the file and add to cache // Read data - std::ifstream fis(filepath.c_str(), std::ios_base::binary); - if (!fis.good()) { - errorstream << "Server::addMediaFile(): Could not open \"" - << filename << "\" for reading" << std::endl; - return false; - } std::string filedata; - bool bad = false; - for (;;) { - char buf[1024]; - fis.read(buf, sizeof(buf)); - std::streamsize len = fis.gcount(); - filedata.append(buf, len); - if (fis.eof()) - break; - if (!fis.good()) { - bad = true; - break; - } - } - if (bad) { - errorstream << "Server::addMediaFile(): Failed to read \"" - << filename << "\"" << std::endl; + if (!fs::ReadFile(filepath, filedata)) { + errorstream << "Server::addMediaFile(): Failed to open \"" + << filename << "\" for reading" << std::endl; return false; - } else if (filedata.empty()) { + } + + if (filedata.empty()) { errorstream << "Server::addMediaFile(): Empty file \"" << filepath << "\"" << std::endl; return false; @@ -3890,19 +3873,27 @@ void Server::broadcastModChannelMessage(const std::string &channel, } } -void Server::loadTranslationLanguage(const std::string &lang_code) +Translations *Server::getTranslationLanguage(const std::string &lang_code) { - if (g_server_translations->count(lang_code)) - return; // Already loaded + if (lang_code.empty()) + return nullptr; + + auto it = server_translations.find(lang_code); + if (it != server_translations.end()) + return &it->second; // Already loaded + + // [] will create an entry + auto *translations = &server_translations[lang_code]; std::string suffix = "." + lang_code + ".tr"; for (const auto &i : m_media) { if (str_ends_with(i.first, suffix)) { - std::ifstream t(i.second.path); - std::string data((std::istreambuf_iterator(t)), - std::istreambuf_iterator()); - - (*g_server_translations)[lang_code].loadTranslation(data); + std::string data; + if (fs::ReadFile(i.second.path, data)) { + translations->loadTranslation(data); + } } } + + return translations; } diff --git a/src/server.h b/src/server.h index be6f60abc..258d75eaf 100644 --- a/src/server.h +++ b/src/server.h @@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverenvironment.h" #include "clientiface.h" #include "chatmessage.h" +#include "translation.h" #include #include #include @@ -343,8 +344,8 @@ public: // Send block to specific player only bool SendBlock(session_t peer_id, const v3s16 &blockpos); - // Load translations for a language - void loadTranslationLanguage(const std::string &lang_code); + // Get or load translations for a language + Translations *getTranslationLanguage(const std::string &lang_code); // Bind address Address m_bind_addr; @@ -557,6 +558,8 @@ private: // Mods std::unique_ptr m_modmgr; + std::unordered_map server_translations; + /* Threads */ diff --git a/src/serverlist.cpp b/src/serverlist.cpp index 2f6ab2e61..c7fe2d888 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -52,15 +52,7 @@ std::vector getLocal() { std::string path = ServerList::getFilePath(); std::string liststring; - if (fs::PathExists(path)) { - std::ifstream istream(path.c_str()); - if (istream.is_open()) { - std::ostringstream ostream; - ostream << istream.rdbuf(); - liststring = ostream.str(); - istream.close(); - } - } + fs::ReadFile(path, liststring); return deSerialize(liststring); } diff --git a/src/translation.cpp b/src/translation.cpp index 8bbaee0a3..82e813a5d 100644 --- a/src/translation.cpp +++ b/src/translation.cpp @@ -29,14 +29,6 @@ Translations client_translations; Translations *g_client_translations = &client_translations; #endif -// Per language server translations -std::unordered_map server_translations; -std::unordered_map *g_server_translations = &server_translations; - -Translations::~Translations() -{ - clear(); -} void Translations::clear() { diff --git a/src/translation.h b/src/translation.h index 71423b15e..f1a336fca 100644 --- a/src/translation.h +++ b/src/translation.h @@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include class Translations; -extern std::unordered_map *g_server_translations; #ifndef SERVER extern Translations *g_client_translations; #endif @@ -31,10 +30,6 @@ extern Translations *g_client_translations; class Translations { public: - Translations() = default; - - ~Translations(); - void loadTranslation(const std::string &data); void clear(); const std::wstring &getTranslation( -- cgit v1.2.3 From 55e2dd911b16a70ee976e067cf34a48922db9dcb Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Tue, 22 Sep 2020 18:38:33 +0200 Subject: Fix chat/infotext overlap if many chat lines (#10399) Moves the infotext depending on the value of the recent_chat_messages value + 2 additional lines to account for the 2 debug mode lines + 1 additional line as "buffer" for better readability if chat is full. --- src/client/gameui.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'src/client') diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp index 81c268e44..75e7d15b9 100644 --- a/src/client/gameui.cpp +++ b/src/client/gameui.cpp @@ -61,17 +61,6 @@ void GameUI::init() m_guitext2 = gui::StaticText::add(guienv, L"", core::rect(0, 0, 0, 0), false, false, guiroot); - // At the middle of the screen - // Object infos are shown in this - m_guitext_info = gui::StaticText::add(guienv, L"", - core::rect(0, 0, 400, g_fontengine->getTextHeight() * 5 + 5) - + v2s32(100, 200), false, true, guiroot); - - // Status text (displays info when showing and hiding GUI stuff, etc.) - m_guitext_status = gui::StaticText::add(guienv, L"", - core::rect(0, 0, 0, 0), false, false, guiroot); - m_guitext_status->setVisible(false); - // Chat text m_guitext_chat = gui::StaticText::add(guienv, L"", core::rect(0, 0, 0, 0), //false, false); // Disable word wrap as of now @@ -82,6 +71,20 @@ void GameUI::init() chat_font_size, FM_Unspecified)); } + // At the middle of the screen + // Object infos are shown in this + u32 chat_font_height = m_guitext_chat->getActiveFont()->getDimension(L"Ay").Height; + m_guitext_info = gui::StaticText::add(guienv, L"", + core::rect(0, 0, 400, g_fontengine->getTextHeight() * 5 + 5) + + v2s32(100, chat_font_height * + (g_settings->getU16("recent_chat_messages") + 3)), + false, true, guiroot); + + // Status text (displays info when showing and hiding GUI stuff, etc.) + m_guitext_status = gui::StaticText::add(guienv, L"", + core::rect(0, 0, 0, 0), false, false, guiroot); + m_guitext_status->setVisible(false); + // Profiler text (size is updated when text is updated) m_guitext_profiler = gui::StaticText::add(guienv, L"", core::rect(0, 0, 0, 0), false, false, guiroot); -- cgit v1.2.3 From 787561b29afdbc78769f68c2f5c4f2cff1b32340 Mon Sep 17 00:00:00 2001 From: Vincent Robinson Date: Wed, 23 Sep 2020 10:12:20 -0700 Subject: Replace MyEventReceiver KeyList with std::unordered_set (#10419) --- src/client/inputhandler.cpp | 48 +++++++++++--------- src/client/inputhandler.h | 108 ++++++++------------------------------------ src/client/keycode.h | 19 ++++++++ 3 files changed, 64 insertions(+), 111 deletions(-) (limited to 'src/client') diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index 608a405a8..ee3e37ae9 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -112,7 +112,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event) // Remember whether each key is down or up if (event.EventType == irr::EET_KEY_INPUT_EVENT) { const KeyPress &keyCode = event.KeyInput; - if (keysListenedFor[keyCode]) { + if (keysListenedFor.count(keyCode)) { // If the key is being held down then the OS may // send a continuous stream of keydown events. // In this case, we don't want to let this @@ -120,15 +120,15 @@ bool MyEventReceiver::OnEvent(const SEvent &event) // certain actions to repeat constantly. if (event.KeyInput.PressedDown) { if (!IsKeyDown(keyCode)) { - keyWasDown.set(keyCode); - keyWasPressed.set(keyCode); + keyWasDown.insert(keyCode); + keyWasPressed.insert(keyCode); } - keyIsDown.set(keyCode); + keyIsDown.insert(keyCode); } else { if (IsKeyDown(keyCode)) - keyWasReleased.set(keyCode); + keyWasReleased.insert(keyCode); - keyIsDown.unset(keyCode); + keyIsDown.erase(keyCode); } return true; @@ -153,36 +153,36 @@ bool MyEventReceiver::OnEvent(const SEvent &event) switch (event.MouseInput.Event) { case EMIE_LMOUSE_PRESSED_DOWN: key = "KEY_LBUTTON"; - keyIsDown.set(key); - keyWasDown.set(key); - keyWasPressed.set(key); + keyIsDown.insert(key); + keyWasDown.insert(key); + keyWasPressed.insert(key); break; case EMIE_MMOUSE_PRESSED_DOWN: key = "KEY_MBUTTON"; - keyIsDown.set(key); - keyWasDown.set(key); - keyWasPressed.set(key); + keyIsDown.insert(key); + keyWasDown.insert(key); + keyWasPressed.insert(key); break; case EMIE_RMOUSE_PRESSED_DOWN: key = "KEY_RBUTTON"; - keyIsDown.set(key); - keyWasDown.set(key); - keyWasPressed.set(key); + keyIsDown.insert(key); + keyWasDown.insert(key); + keyWasPressed.insert(key); break; case EMIE_LMOUSE_LEFT_UP: key = "KEY_LBUTTON"; - keyIsDown.unset(key); - keyWasReleased.set(key); + keyIsDown.erase(key); + keyWasReleased.insert(key); break; case EMIE_MMOUSE_LEFT_UP: key = "KEY_MBUTTON"; - keyIsDown.unset(key); - keyWasReleased.set(key); + keyIsDown.erase(key); + keyWasReleased.insert(key); break; case EMIE_RMOUSE_LEFT_UP: key = "KEY_RBUTTON"; - keyIsDown.unset(key); - keyWasReleased.set(key); + keyIsDown.erase(key); + keyWasReleased.insert(key); break; case EMIE_MOUSE_WHEEL: mouse_wheel += event.MouseInput.Wheel; @@ -235,7 +235,11 @@ void RandomInputHandler::step(float dtime) i.counter -= dtime; if (i.counter < 0.0) { i.counter = 0.1 * Rand(1, i.time_max); - keydown.toggle(getKeySetting(i.key.c_str())); + KeyPress k = getKeySetting(i.key.c_str()); + if (keydown.count(k)) + keydown.erase(k); + else + keydown.insert(k); } } { diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index def147a82..885f34e05 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "joystick_controller.h" -#include #include "keycode.h" #include "renderingengine.h" +#include #ifdef HAVE_TOUCHSCREENGUI #include "gui/touchscreengui.h" @@ -61,98 +61,32 @@ struct KeyCache InputHandler *handler; }; -class KeyList : private std::list -{ - typedef std::list super; - typedef super::iterator iterator; - typedef super::const_iterator const_iterator; - - virtual const_iterator find(const KeyPress &key) const - { - const_iterator f(begin()); - const_iterator e(end()); - - while (f != e) { - if (*f == key) - return f; - - ++f; - } - - return e; - } - - virtual iterator find(const KeyPress &key) - { - iterator f(begin()); - iterator e(end()); - - while (f != e) { - if (*f == key) - return f; - - ++f; - } - - return e; - } - -public: - void clear() { super::clear(); } - - void set(const KeyPress &key) - { - if (find(key) == end()) - push_back(key); - } - - void unset(const KeyPress &key) - { - iterator p(find(key)); - - if (p != end()) - erase(p); - } - - void toggle(const KeyPress &key) - { - iterator p(this->find(key)); - - if (p != end()) - erase(p); - else - push_back(key); - } - - bool operator[](const KeyPress &key) const { return find(key) != end(); } -}; - class MyEventReceiver : public IEventReceiver { public: // This is the one method that we have to implement virtual bool OnEvent(const SEvent &event); - bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; } + bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown.count(keyCode); } // Checks whether a key was down and resets the state bool WasKeyDown(const KeyPress &keyCode) { - bool b = keyWasDown[keyCode]; + bool b = keyWasDown.count(keyCode); if (b) - keyWasDown.unset(keyCode); + keyWasDown.erase(keyCode); return b; } // Checks whether a key was just pressed. State will be cleared // in the subsequent iteration of Game::processPlayerInteraction - bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; } + bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed.count(keycode); } // Checks whether a key was just released. State will be cleared // in the subsequent iteration of Game::processPlayerInteraction - bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; } + bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased.count(keycode); } - void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); } + void listenForKey(const KeyPress &keyCode) { keysListenedFor.insert(keyCode); } void dontListenForKeys() { keysListenedFor.clear(); } s32 getMouseWheel() @@ -198,24 +132,20 @@ public: #endif private: - // The current state of keys - KeyList keyIsDown; + //! The current state of keys + std::unordered_set keyIsDown; - // Whether a key was down - KeyList keyWasDown; + //! Whether a key was down + std::unordered_set keyWasDown; - // Whether a key has just been pressed - KeyList keyWasPressed; + //! Whether a key has just been pressed + std::unordered_set keyWasPressed; - // Whether a key has just been released - KeyList keyWasReleased; + //! Whether a key has just been released + std::unordered_set keyWasReleased; - // List of keys we listen for - // TODO perhaps the type of this is not really - // performant as KeyList is designed for few but - // often changing keys, and keysListenedFor is expected - // to change seldomly but contain lots of keys. - KeyList keysListenedFor; + //! List of keys we listen for + std::unordered_set keysListenedFor; }; class InputHandler @@ -347,7 +277,7 @@ public: return true; } - virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } + virtual bool isKeyDown(GameKeyType k) { return keydown.count(keycache.key[k]); } virtual bool wasKeyDown(GameKeyType k) { return false; } virtual bool wasKeyPressed(GameKeyType k) { return false; } virtual bool wasKeyReleased(GameKeyType k) { return false; } @@ -362,7 +292,7 @@ public: s32 Rand(s32 min, s32 max); private: - KeyList keydown; + std::unordered_set keydown; v2s32 mousepos; v2s32 mousespeed; }; diff --git a/src/client/keycode.h b/src/client/keycode.h index 7036705d1..263b722c7 100644 --- a/src/client/keycode.h +++ b/src/client/keycode.h @@ -24,12 +24,20 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +class KeyPress; +namespace std +{ + template <> struct hash; +} + /* A key press, consisting of either an Irrlicht keycode or an actual char */ class KeyPress { public: + friend struct std::hash; + KeyPress() = default; KeyPress(const char *name); @@ -55,6 +63,17 @@ protected: std::string m_name = ""; }; +namespace std +{ + template <> struct hash + { + size_t operator()(const KeyPress &key) const + { + return key.Key; + } + }; +} + extern const KeyPress EscapeKey; extern const KeyPress CancelKey; -- cgit v1.2.3 From 9bff154cba14686f5a3b56f4cba405824b88c402 Mon Sep 17 00:00:00 2001 From: Paramat Date: Thu, 24 Sep 2020 00:10:50 +0100 Subject: Fix horizontal/vertical merging bug of hardware-colored framed glass (#10417) Previously, the param2-controlled horizontal/vertical merge feature (which was undocumented and forgotten) was always active, causing uses of param2 other than "glasslikeliquidlevel" to affect H/V merging. Only respect H/V merge bits when paramtype2 = "glasslikeliquidlevel". H/V merge bits and liquid level bits are designed to be used simultaneously. --- src/client/content_mapblock.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index 65a85709b..df2748212 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -723,7 +723,8 @@ void MapblockMeshGenerator::drawGlasslikeFramedNode() for (auto &glass_tile : glass_tiles) glass_tile = tiles[4]; - u8 param2 = n.getParam2(); + // Only respect H/V merge bits when paramtype2 = "glasslikeliquidlevel" (liquid tank) + u8 param2 = (f->param_type_2 == CPT2_GLASSLIKE_LIQUID_LEVEL) ? n.getParam2() : 0; bool H_merge = !(param2 & 128); bool V_merge = !(param2 & 64); param2 &= 63; -- cgit v1.2.3 From 947466ab28129fd69e6630974c6c4e901f2bebc6 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 20 Sep 2020 13:12:55 +0200 Subject: (se)SerializeString: Include max length in the name This commit clarifies the maximal length of the serialized strings. It will avoid accidental use of serializeString() when a larger string can be expected. Removes unused Wide String serialization functions --- src/client/content_cao.cpp | 12 +++---- src/content_nodemeta.cpp | 18 +++++------ src/database/database-leveldb.cpp | 16 +++++----- src/itemdef.cpp | 52 +++++++++++++++--------------- src/mapblock.cpp | 4 +-- src/mapgen/mg_schematic.cpp | 4 +-- src/nameidmapping.cpp | 4 +-- src/network/clientpackethandler.cpp | 8 ++--- src/nodedef.cpp | 40 +++++++++++------------ src/nodemetadata.cpp | 8 ++--- src/object_properties.cpp | 28 ++++++++--------- src/particles.cpp | 4 +-- src/server.cpp | 4 +-- src/server/luaentity_sao.cpp | 28 ++++++++--------- src/server/player_sao.cpp | 16 +++++----- src/server/serveractiveobject.cpp | 2 +- src/server/unit_sao.cpp | 6 ++-- src/sound.h | 4 +-- src/staticobject.cpp | 4 +-- src/tool.cpp | 8 ++--- src/unittest/test_serialization.cpp | 50 +++++++++++++---------------- src/util/serialize.cpp | 63 +++++-------------------------------- src/util/serialize.h | 8 ++--- 23 files changed, 168 insertions(+), 223 deletions(-) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 599139aa3..71a9d4b54 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -371,7 +371,7 @@ void GenericCAO::processInitData(const std::string &data) } // PROTOCOL_VERSION >= 37 - m_name = deSerializeString(is); + m_name = deSerializeString16(is); m_is_player = readU8(is); m_id = readU16(is); m_position = readV3F32(is); @@ -381,7 +381,7 @@ void GenericCAO::processInitData(const std::string &data) const u8 num_messages = readU8(is); for (int i = 0; i < num_messages; i++) { - std::string message = deSerializeLongString(is); + std::string message = deSerializeString32(is); processMessage(message); } @@ -1657,7 +1657,7 @@ void GenericCAO::processMessage(const std::string &data) rot_translator.update(m_rotation, false, update_interval); updateNodePos(); } else if (cmd == AO_CMD_SET_TEXTURE_MOD) { - std::string mod = deSerializeString(is); + std::string mod = deSerializeString16(is); // immediately reset a engine issued texture modifier if a mod sends a different one if (m_reset_textures_timer > 0) { @@ -1735,7 +1735,7 @@ void GenericCAO::processMessage(const std::string &data) m_animation_speed = readF32(is); updateAnimationSpeed(); } else if (cmd == AO_CMD_SET_BONE_POSITION) { - std::string bone = deSerializeString(is); + std::string bone = deSerializeString16(is); v3f position = readV3F32(is); v3f rotation = readV3F32(is); m_bone_position[bone] = core::vector2d(position, rotation); @@ -1743,7 +1743,7 @@ void GenericCAO::processMessage(const std::string &data) // updateBonePosition(); now called every step } else if (cmd == AO_CMD_ATTACH_TO) { u16 parent_id = readS16(is); - std::string bone = deSerializeString(is); + std::string bone = deSerializeString16(is); v3f position = readV3F32(is); v3f rotation = readV3F32(is); @@ -1793,7 +1793,7 @@ void GenericCAO::processMessage(const std::string &data) int armor_groups_size = readU16(is); for(int i=0; igetInventory()->deSerialize(is); - deSerializeLongString(is); // m_text - deSerializeString(is); // m_owner + deSerializeString32(is); // m_text + deSerializeString16(is); // m_owner - meta->setString("infotext",deSerializeString(is)); - meta->setString("formspec",deSerializeString(is)); + meta->setString("infotext",deSerializeString16(is)); + meta->setString("formspec",deSerializeString16(is)); readU8(is); // m_allow_text_input readU8(is); // m_allow_removal readU8(is); // m_enforce_owner int num_vars = readU32(is); for(int i=0; isetString(name, var); } return false; } else if(id == NODEMETA_SIGN) // SignNodeMetadata { - meta->setString("text", deSerializeString(is)); + meta->setString("text", deSerializeString16(is)); //meta->setString("infotext","\"${text}\""); meta->setString("infotext", std::string("\"") + meta->getString("text") + "\""); @@ -87,7 +87,7 @@ static bool content_nodemeta_deserialize_legacy_body( } else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata { - meta->setString("owner", deSerializeString(is)); + meta->setString("owner", deSerializeString16(is)); meta->getInventory()->deSerialize(is); // Rename inventory list "0" to "main" @@ -138,7 +138,7 @@ static bool content_nodemeta_deserialize_legacy_meta( s16 id = readS16(is); // Read data - std::string data = deSerializeString(is); + std::string data = deSerializeString16(is); std::istringstream tmp_is(data, std::ios::binary); return content_nodemeta_deserialize_legacy_body(tmp_is, id, meta); } diff --git a/src/database/database-leveldb.cpp b/src/database/database-leveldb.cpp index 1976ae13d..73cd63f6d 100644 --- a/src/database/database-leveldb.cpp +++ b/src/database/database-leveldb.cpp @@ -145,8 +145,8 @@ void PlayerDatabaseLevelDB::savePlayer(RemotePlayer *player) StringMap stringvars = sao->getMeta().getStrings(); writeU32(os, stringvars.size()); for (const auto &it : stringvars) { - os << serializeString(it.first); - os << serializeLongString(it.second); + os << serializeString16(it.first); + os << serializeString32(it.second); } player->inventory.serialize(os); @@ -183,8 +183,8 @@ bool PlayerDatabaseLevelDB::loadPlayer(RemotePlayer *player, PlayerSAO *sao) u32 attribute_count = readU32(is); for (u32 i = 0; i < attribute_count; i++) { - std::string name = deSerializeString(is); - std::string value = deSerializeLongString(is); + std::string name = deSerializeString16(is); + std::string value = deSerializeString32(is); sao->getMeta().setString(name, value); } sao->getMeta().setModified(false); @@ -247,13 +247,13 @@ bool AuthDatabaseLevelDB::getAuth(const std::string &name, AuthEntry &res) res.id = 1; res.name = name; - res.password = deSerializeString(is); + res.password = deSerializeString16(is); u16 privilege_count = readU16(is); res.privileges.clear(); res.privileges.reserve(privilege_count); for (u16 i = 0; i < privilege_count; i++) { - res.privileges.push_back(deSerializeString(is)); + res.privileges.push_back(deSerializeString16(is)); } res.last_login = readS64(is); @@ -264,14 +264,14 @@ bool AuthDatabaseLevelDB::saveAuth(const AuthEntry &authEntry) { std::ostringstream os; writeU8(os, 1); - os << serializeString(authEntry.password); + os << serializeString16(authEntry.password); size_t privilege_count = authEntry.privileges.size(); FATAL_ERROR_IF(privilege_count > U16_MAX, "Unsupported number of privileges"); writeU16(os, privilege_count); for (const std::string &privilege : authEntry.privileges) { - os << serializeString(privilege); + os << serializeString16(privilege); } writeS64(os, authEntry.last_login); diff --git a/src/itemdef.cpp b/src/itemdef.cpp index 8e0492827..df20bdf15 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -128,10 +128,10 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const u8 version = 6; writeU8(os, version); writeU8(os, type); - os << serializeString(name); - os << serializeString(description); - os << serializeString(inventory_image); - os << serializeString(wield_image); + os << serializeString16(name); + os << serializeString16(description); + os << serializeString16(inventory_image); + os << serializeString16(wield_image); writeV3F32(os, wield_scale); writeS16(os, stack_max); writeU8(os, usable); @@ -143,25 +143,25 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const tool_capabilities->serialize(tmp_os, protocol_version); tool_capabilities_s = tmp_os.str(); } - os << serializeString(tool_capabilities_s); + os << serializeString16(tool_capabilities_s); writeU16(os, groups.size()); for (const auto &group : groups) { - os << serializeString(group.first); + os << serializeString16(group.first); writeS16(os, group.second); } - os << serializeString(node_placement_prediction); + os << serializeString16(node_placement_prediction); // Version from ContentFeatures::serialize to keep in sync sound_place.serialize(os, CONTENTFEATURES_VERSION); sound_place_failed.serialize(os, CONTENTFEATURES_VERSION); writeF32(os, range); - os << serializeString(palette_image); + os << serializeString16(palette_image); writeARGB8(os, color); - os << serializeString(inventory_overlay); - os << serializeString(wield_overlay); + os << serializeString16(inventory_overlay); + os << serializeString16(wield_overlay); } void ItemDefinition::deSerialize(std::istream &is) @@ -175,16 +175,16 @@ void ItemDefinition::deSerialize(std::istream &is) throw SerializationError("unsupported ItemDefinition version"); type = (enum ItemType)readU8(is); - name = deSerializeString(is); - description = deSerializeString(is); - inventory_image = deSerializeString(is); - wield_image = deSerializeString(is); + name = deSerializeString16(is); + description = deSerializeString16(is); + inventory_image = deSerializeString16(is); + wield_image = deSerializeString16(is); wield_scale = readV3F32(is); stack_max = readS16(is); usable = readU8(is); liquids_pointable = readU8(is); - std::string tool_capabilities_s = deSerializeString(is); + std::string tool_capabilities_s = deSerializeString16(is); if (!tool_capabilities_s.empty()) { std::istringstream tmp_is(tool_capabilities_s, std::ios::binary); tool_capabilities = new ToolCapabilities; @@ -194,22 +194,22 @@ void ItemDefinition::deSerialize(std::istream &is) groups.clear(); u32 groups_size = readU16(is); for(u32 i=0; iserialize(tmp_os, protocol_version); - os << serializeString(tmp_os.str()); + os << serializeString16(tmp_os.str()); } writeU16(os, m_aliases.size()); for (const auto &it : m_aliases) { - os << serializeString(it.first); - os << serializeString(it.second); + os << serializeString16(it.first); + os << serializeString16(it.second); } } void deSerialize(std::istream &is) @@ -543,7 +543,7 @@ public: for(u16 i=0; iidef()); } else { - //std::string data = deSerializeLongString(is); + //std::string data = deSerializeString32(is); std::ostringstream oss(std::ios_base::binary); decompressZlib(is, oss); std::istringstream iss(oss.str(), std::ios_base::binary); diff --git a/src/mapgen/mg_schematic.cpp b/src/mapgen/mg_schematic.cpp index ba102d997..dfd414709 100644 --- a/src/mapgen/mg_schematic.cpp +++ b/src/mapgen/mg_schematic.cpp @@ -314,7 +314,7 @@ bool Schematic::deserializeFromMts(std::istream *is, //// Read node names u16 nidmapcount = readU16(ss); for (int i = 0; i != nidmapcount; i++) { - std::string name = deSerializeString(ss); + std::string name = deSerializeString16(ss); // Instances of "ignore" from v1 are converted to air (and instances // are fixed to have MTSCHEM_PROB_NEVER later on). @@ -372,7 +372,7 @@ bool Schematic::serializeToMts(std::ostream *os, writeU16(ss, names.size()); // name count for (size_t i = 0; i != names.size(); i++) - ss << serializeString(names[i]); // node names + ss << serializeString16(names[i]); // node names // compressed bulk node data MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, diff --git a/src/nameidmapping.cpp b/src/nameidmapping.cpp index bd5bb1fc8..05cfae069 100644 --- a/src/nameidmapping.cpp +++ b/src/nameidmapping.cpp @@ -27,7 +27,7 @@ void NameIdMapping::serialize(std::ostream &os) const writeU16(os, m_id_to_name.size()); for (const auto &i : m_id_to_name) { writeU16(os, i.first); - os << serializeString(i.second); + os << serializeString16(i.second); } } @@ -41,7 +41,7 @@ void NameIdMapping::deSerialize(std::istream &is) m_name_to_id.clear(); for (u32 i = 0; i < count; i++) { u16 id = readU16(is); - std::string name = deSerializeString(is); + std::string name = deSerializeString16(is); m_id_to_name[id] = name; m_name_to_id[name] = id; } diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 8d87ff8f2..5683564a0 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -497,7 +497,7 @@ void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt) if (!is.good()) break; - std::string message = deSerializeString(is); + std::string message = deSerializeString16(is); // Pass on to the environment m_env.processActiveObjectMessage(id, message); @@ -994,7 +994,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) p.minsize = readF32(is); p.maxsize = readF32(is); p.collisiondetection = readU8(is); - p.texture = deSerializeLongString(is); + p.texture = deSerializeString32(is); server_id = readU32(is); @@ -1207,11 +1207,11 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt) SkyboxParams skybox; skybox.bgcolor = video::SColor(readARGB8(is)); - skybox.type = std::string(deSerializeString(is)); + skybox.type = std::string(deSerializeString16(is)); u16 count = readU16(is); for (size_t i = 0; i < count; i++) - skybox.textures.emplace_back(deSerializeString(is)); + skybox.textures.emplace_back(deSerializeString16(is)); skybox.clouds = true; try { diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 392f5eb98..3a5934cf3 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -207,7 +207,7 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const u8 version = 6; writeU8(os, version); - os << serializeString(name); + os << serializeString16(name); animation.serialize(os, version); bool has_scale = scale > 0; u16 flags = 0; @@ -241,7 +241,7 @@ void TileDef::deSerialize(std::istream &is, u8 contentfeatures_version, int version = readU8(is); if (version < 6) throw SerializationError("unsupported TileDef version"); - name = deSerializeString(is); + name = deSerializeString16(is); animation.deSerialize(is, version); u16 flags = readU16(is); backface_culling = flags & TILE_FLAG_BACKFACE_CULLING; @@ -416,10 +416,10 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU8(os, version); // general - os << serializeString(name); + os << serializeString16(name); writeU16(os, groups.size()); for (const auto &group : groups) { - os << serializeString(group.first); + os << serializeString16(group.first); writeS16(os, group.second); } writeU8(os, param_type); @@ -427,7 +427,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const // visual writeU8(os, drawtype); - os << serializeString(mesh); + os << serializeString16(mesh); writeF32(os, visual_scale); writeU8(os, 6); for (const TileDef &td : tiledef) @@ -442,7 +442,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU8(os, color.getRed()); writeU8(os, color.getGreen()); writeU8(os, color.getBlue()); - os << serializeString(palette_name); + os << serializeString16(palette_name); writeU8(os, waving); writeU8(os, connect_sides); writeU16(os, connects_to_ids.size()); @@ -470,8 +470,8 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const // liquid writeU8(os, liquid_type); - os << serializeString(liquid_alternative_flowing); - os << serializeString(liquid_alternative_source); + os << serializeString16(liquid_alternative_flowing); + os << serializeString16(liquid_alternative_source); writeU8(os, liquid_viscosity); writeU8(os, liquid_renewable); writeU8(os, liquid_range); @@ -492,7 +492,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU8(os, legacy_facedir_simple); writeU8(os, legacy_wallmounted); - os << serializeString(node_dig_prediction); + os << serializeString16(node_dig_prediction); writeU8(os, leveled_max); } @@ -519,11 +519,11 @@ void ContentFeatures::deSerialize(std::istream &is) throw SerializationError("unsupported ContentFeatures version"); // general - name = deSerializeString(is); + name = deSerializeString16(is); groups.clear(); u32 groups_size = readU16(is); for (u32 i = 0; i < groups_size; i++) { - std::string name = deSerializeString(is); + std::string name = deSerializeString16(is); int value = readS16(is); groups[name] = value; } @@ -532,7 +532,7 @@ void ContentFeatures::deSerialize(std::istream &is) // visual drawtype = (enum NodeDrawType) readU8(is); - mesh = deSerializeString(is); + mesh = deSerializeString16(is); visual_scale = readF32(is); if (readU8(is) != 6) throw SerializationError("unsupported tile count"); @@ -548,7 +548,7 @@ void ContentFeatures::deSerialize(std::istream &is) color.setRed(readU8(is)); color.setGreen(readU8(is)); color.setBlue(readU8(is)); - palette_name = deSerializeString(is); + palette_name = deSerializeString16(is); waving = readU8(is); connect_sides = readU8(is); u16 connects_to_size = readU16(is); @@ -578,8 +578,8 @@ void ContentFeatures::deSerialize(std::istream &is) // liquid liquid_type = (enum LiquidType) readU8(is); - liquid_alternative_flowing = deSerializeString(is); - liquid_alternative_source = deSerializeString(is); + liquid_alternative_flowing = deSerializeString16(is); + liquid_alternative_source = deSerializeString16(is); liquid_viscosity = readU8(is); liquid_renewable = readU8(is); liquid_range = readU8(is); @@ -601,7 +601,7 @@ void ContentFeatures::deSerialize(std::istream &is) legacy_wallmounted = readU8(is); try { - node_dig_prediction = deSerializeString(is); + node_dig_prediction = deSerializeString16(is); u8 tmp_leveled_max = readU8(is); if (is.eof()) /* readU8 doesn't throw exceptions so we have to do this */ throw SerializationError(""); @@ -1472,7 +1472,7 @@ void NodeDefManager::serialize(std::ostream &os, u16 protocol_version) const // strict version incompatibilities std::ostringstream wrapper_os(std::ios::binary); f->serialize(wrapper_os, protocol_version); - os2<= 2) writeU8(os, (priv) ? 1 : 0); } @@ -63,8 +63,8 @@ void NodeMetadata::deSerialize(std::istream &is, u8 version) clear(); int num_vars = readU32(is); for(int i=0; i= 2) { if (readU8(is) == 1) diff --git a/src/object_properties.cpp b/src/object_properties.cpp index 8d51bcbfa..c31c667e7 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -84,11 +84,11 @@ void ObjectProperties::serialize(std::ostream &os) const writeV3F32(os, selectionbox.MinEdge); writeV3F32(os, selectionbox.MaxEdge); writeU8(os, pointable); - os << serializeString(visual); + os << serializeString16(visual); writeV3F32(os, visual_size); writeU16(os, textures.size()); for (const std::string &texture : textures) { - os << serializeString(texture); + os << serializeString16(texture); } writeV2S16(os, spritediv); writeV2S16(os, initial_sprite_basepos); @@ -96,7 +96,7 @@ void ObjectProperties::serialize(std::ostream &os) const writeU8(os, makes_footstep_sound); writeF32(os, automatic_rotate); // Added in protocol version 14 - os << serializeString(mesh); + os << serializeString16(mesh); writeU16(os, colors.size()); for (video::SColor color : colors) { writeARGB8(os, color); @@ -106,17 +106,17 @@ void ObjectProperties::serialize(std::ostream &os) const writeU8(os, automatic_face_movement_dir); writeF32(os, automatic_face_movement_dir_offset); writeU8(os, backface_culling); - os << serializeString(nametag); + os << serializeString16(nametag); writeARGB8(os, nametag_color); writeF32(os, automatic_face_movement_max_rotation_per_sec); - os << serializeString(infotext); - os << serializeString(wield_item); + os << serializeString16(infotext); + os << serializeString16(wield_item); writeS8(os, glow); writeU16(os, breath_max); writeF32(os, eye_height); writeF32(os, zoom_fov); writeU8(os, use_texture_alpha); - os << serializeString(damage_texture_modifier); + os << serializeString16(damage_texture_modifier); writeU8(os, shaded); // Add stuff only at the bottom. @@ -137,19 +137,19 @@ void ObjectProperties::deSerialize(std::istream &is) selectionbox.MinEdge = readV3F32(is); selectionbox.MaxEdge = readV3F32(is); pointable = readU8(is); - visual = deSerializeString(is); + visual = deSerializeString16(is); visual_size = readV3F32(is); textures.clear(); u32 texture_count = readU16(is); for (u32 i = 0; i < texture_count; i++){ - textures.push_back(deSerializeString(is)); + textures.push_back(deSerializeString16(is)); } spritediv = readV2S16(is); initial_sprite_basepos = readV2S16(is); is_visible = readU8(is); makes_footstep_sound = readU8(is); automatic_rotate = readF32(is); - mesh = deSerializeString(is); + mesh = deSerializeString16(is); colors.clear(); u32 color_count = readU16(is); for (u32 i = 0; i < color_count; i++){ @@ -160,18 +160,18 @@ void ObjectProperties::deSerialize(std::istream &is) automatic_face_movement_dir = readU8(is); automatic_face_movement_dir_offset = readF32(is); backface_culling = readU8(is); - nametag = deSerializeString(is); + nametag = deSerializeString16(is); nametag_color = readARGB8(is); automatic_face_movement_max_rotation_per_sec = readF32(is); - infotext = deSerializeString(is); - wield_item = deSerializeString(is); + infotext = deSerializeString16(is); + wield_item = deSerializeString16(is); glow = readS8(is); breath_max = readU16(is); eye_height = readF32(is); zoom_fov = readF32(is); use_texture_alpha = readU8(is); try { - damage_texture_modifier = deSerializeString(is); + damage_texture_modifier = deSerializeString16(is); u8 tmp = readU8(is); if (is.eof()) throw SerializationError(""); diff --git a/src/particles.cpp b/src/particles.cpp index fd81238dc..14c987958 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -28,7 +28,7 @@ void ParticleParameters::serialize(std::ostream &os, u16 protocol_ver) const writeF32(os, expirationtime); writeF32(os, size); writeU8(os, collisiondetection); - os << serializeLongString(texture); + os << serializeString32(texture); writeU8(os, vertical); writeU8(os, collision_removal); animation.serialize(os, 6); /* NOT the protocol ver */ @@ -47,7 +47,7 @@ void ParticleParameters::deSerialize(std::istream &is, u16 protocol_ver) expirationtime = readF32(is); size = readF32(is); collisiondetection = readU8(is); - texture = deSerializeLongString(is); + texture = deSerializeString32(is); vertical = readU8(is); collision_removal = readU8(is); animation.deSerialize(is, 6); /* NOT the protocol ver */ diff --git a/src/server.cpp b/src/server.cpp index d40ff259f..982f904f4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -802,7 +802,7 @@ void Server::AsyncRunStep(bool initial_step) // u16 id // std::string data buffer.append(idbuf, sizeof(idbuf)); - buffer.append(serializeString(aom.datastring)); + buffer.append(serializeString16(aom.datastring)); } } /* @@ -1993,7 +1993,7 @@ void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersa writeU8((u8*)buf, type); data.append(buf, 1); - data.append(serializeLongString( + data.append(serializeString32( obj->getClientInitializationData(client->net_proto_version))); // Add to known objects diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index d504c42ca..f20914f7f 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -42,8 +42,8 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &d u8 version2 = 0; u8 version = readU8(is); - name = deSerializeString(is); - state = deSerializeLongString(is); + name = deSerializeString16(is); + state = deSerializeString32(is); if (version < 1) break; @@ -225,7 +225,7 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) // PROTOCOL_VERSION >= 37 writeU8(os, 1); // version - os << serializeString(""); // name + os << serializeString16(""); // name writeU8(os, 0); // is_player writeU16(os, getId()); //id writeV3F32(os, m_base_position); @@ -233,26 +233,26 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) writeU16(os, m_hp); std::ostringstream msg_os(std::ios::binary); - msg_os << serializeLongString(getPropertyPacket()); // message 1 - msg_os << serializeLongString(generateUpdateArmorGroupsCommand()); // 2 - msg_os << serializeLongString(generateUpdateAnimationCommand()); // 3 + msg_os << serializeString32(getPropertyPacket()); // message 1 + msg_os << serializeString32(generateUpdateArmorGroupsCommand()); // 2 + msg_os << serializeString32(generateUpdateAnimationCommand()); // 3 for (const auto &bone_pos : m_bone_position) { - msg_os << serializeLongString(generateUpdateBonePositionCommand( + msg_os << serializeString32(generateUpdateBonePositionCommand( bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // m_bone_position.size } - msg_os << serializeLongString(generateUpdateAttachmentCommand()); // 4 + msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 int message_count = 4 + m_bone_position.size(); for (const auto &id : getAttachmentChildIds()) { if (ServerActiveObject *obj = m_env->getActiveObject(id)) { message_count++; - msg_os << serializeLongString(obj->generateUpdateInfantCommand( + msg_os << serializeString32(obj->generateUpdateInfantCommand( id, protocol_version)); } } - msg_os << serializeLongString(generateSetTextureModCommand()); + msg_os << serializeString32(generateSetTextureModCommand()); message_count++; writeU8(os, message_count); @@ -270,14 +270,14 @@ void LuaEntitySAO::getStaticData(std::string *result) const // version must be 1 to keep backwards-compatibility. See version2 writeU8(os, 1); // name - os<getScriptIface()-> luaentity_GetStaticdata(m_id); - os<= 15 writeU8(os, 1); // version - os << serializeString(m_player->getName()); // name + os << serializeString16(m_player->getName()); // name writeU8(os, 1); // is_player writeS16(os, getId()); // id writeV3F32(os, m_base_position); @@ -117,22 +117,22 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeU16(os, getHP()); std::ostringstream msg_os(std::ios::binary); - msg_os << serializeLongString(getPropertyPacket()); // message 1 - msg_os << serializeLongString(generateUpdateArmorGroupsCommand()); // 2 - msg_os << serializeLongString(generateUpdateAnimationCommand()); // 3 + msg_os << serializeString32(getPropertyPacket()); // message 1 + msg_os << serializeString32(generateUpdateArmorGroupsCommand()); // 2 + msg_os << serializeString32(generateUpdateAnimationCommand()); // 3 for (const auto &bone_pos : m_bone_position) { - msg_os << serializeLongString(generateUpdateBonePositionCommand( + msg_os << serializeString32(generateUpdateBonePositionCommand( bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // m_bone_position.size } - msg_os << serializeLongString(generateUpdateAttachmentCommand()); // 4 - msg_os << serializeLongString(generateUpdatePhysicsOverrideCommand()); // 5 + msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 + msg_os << serializeString32(generateUpdatePhysicsOverrideCommand()); // 5 int message_count = 5 + m_bone_position.size(); for (const auto &id : getAttachmentChildIds()) { if (ServerActiveObject *obj = m_env->getActiveObject(id)) { message_count++; - msg_os << serializeLongString(obj->generateUpdateInfantCommand( + msg_os << serializeString32(obj->generateUpdateInfantCommand( id, protocol_version)); } } diff --git a/src/server/serveractiveobject.cpp b/src/server/serveractiveobject.cpp index 3341dc008..8cb59b2d6 100644 --- a/src/server/serveractiveobject.cpp +++ b/src/server/serveractiveobject.cpp @@ -61,7 +61,7 @@ std::string ServerActiveObject::generateUpdateInfantCommand(u16 infant_id, u16 p // Clients since 4aa9a66 so no longer need this data // Version 38 is the first bump after that commit. // See also: ClientEnvironment::addActiveObject - os << serializeLongString(getClientInitializationData(protocol_version)); + os << serializeString32(getClientInitializationData(protocol_version)); } return os.str(); } diff --git a/src/server/unit_sao.cpp b/src/server/unit_sao.cpp index ef0e87f2c..d906e885e 100644 --- a/src/server/unit_sao.cpp +++ b/src/server/unit_sao.cpp @@ -242,7 +242,7 @@ std::string UnitSAO::generateUpdateAttachmentCommand() const writeU8(os, AO_CMD_ATTACH_TO); // parameters writeS16(os, m_attachment_parent_id); - os << serializeString(m_attachment_bone); + os << serializeString16(m_attachment_bone); writeV3F32(os, m_attachment_position); writeV3F32(os, m_attachment_rotation); return os.str(); @@ -255,7 +255,7 @@ std::string UnitSAO::generateUpdateBonePositionCommand( // command writeU8(os, AO_CMD_SET_BONE_POSITION); // parameters - os << serializeString(bone); + os << serializeString16(bone); writeV3F32(os, position); writeV3F32(os, rotation); return os.str(); @@ -291,7 +291,7 @@ std::string UnitSAO::generateUpdateArmorGroupsCommand() const writeU8(os, AO_CMD_UPDATE_ARMOR_GROUPS); writeU16(os, m_armor_groups.size()); for (const auto &armor_group : m_armor_groups) { - os << serializeString(armor_group.first); + os << serializeString16(armor_group.first); writeS16(os, armor_group.second); } return os.str(); diff --git a/src/sound.h b/src/sound.h index 6cbd55e8f..6f7b0a1af 100644 --- a/src/sound.h +++ b/src/sound.h @@ -39,7 +39,7 @@ struct SimpleSoundSpec // keep in sync with item definitions void serialize(std::ostream &os, u8 cf_version) const { - os << serializeString(name); + os << serializeString16(name); writeF32(os, gain); writeF32(os, pitch); writeF32(os, fade); @@ -49,7 +49,7 @@ struct SimpleSoundSpec void deSerialize(std::istream &is, u8 cf_version) { - name = deSerializeString(is); + name = deSerializeString16(is); gain = readF32(is); pitch = readF32(is); fade = readF32(is); diff --git a/src/staticobject.cpp b/src/staticobject.cpp index 5ccb7baf5..86e455b9f 100644 --- a/src/staticobject.cpp +++ b/src/staticobject.cpp @@ -35,7 +35,7 @@ void StaticObject::serialize(std::ostream &os) // pos writeV3F1000(os, pos); // data - os<uses); writeS16(os, cap->maxlevel); writeU32(os, cap->times.size()); @@ -79,7 +79,7 @@ void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const writeU32(os, damageGroups.size()); for (const auto &damageGroup : damageGroups) { - os << serializeString(damageGroup.first); + os << serializeString16(damageGroup.first); writeS16(os, damageGroup.second); } @@ -98,7 +98,7 @@ void ToolCapabilities::deSerialize(std::istream &is) groupcaps.clear(); u32 groupcaps_size = readU32(is); for (u32 i = 0; i < groupcaps_size; i++) { - std::string name = deSerializeString(is); + std::string name = deSerializeString16(is); ToolGroupCap cap; cap.uses = readS16(is); cap.maxlevel = readS16(is); @@ -113,7 +113,7 @@ void ToolCapabilities::deSerialize(std::istream &is) u32 damage_groups_size = readU32(is); for (u32 i = 0; i < damage_groups_size; i++) { - std::string name = deSerializeString(is); + std::string name = deSerializeString16(is); s16 rating = readS16(is); damageGroups[name] = rating; } diff --git a/src/unittest/test_serialization.cpp b/src/unittest/test_serialization.cpp index d72bf0d4c..660d77d02 100644 --- a/src/unittest/test_serialization.cpp +++ b/src/unittest/test_serialization.cpp @@ -44,7 +44,7 @@ public: std::wstring teststring2_w; std::string teststring2_w_encoded; - static const u8 test_serialized_data[12 * 13 - 8]; + static const u8 test_serialized_data[12 * 11 - 2]; }; static TestSerialization g_test_instance; @@ -91,21 +91,21 @@ void TestSerialization::buildTestStrings() void TestSerialization::testSerializeString() { // Test blank string - UASSERT(serializeString("") == mkstr("\0\0")); + UASSERT(serializeString16("") == mkstr("\0\0")); // Test basic string - UASSERT(serializeString("Hello world!") == mkstr("\0\14Hello world!")); + UASSERT(serializeString16("Hello world!") == mkstr("\0\14Hello world!")); // Test character range - UASSERT(serializeString(teststring2) == mkstr("\1\0") + teststring2); + UASSERT(serializeString16(teststring2) == mkstr("\1\0") + teststring2); } void TestSerialization::testDeSerializeString() { // Test deserialize { - std::istringstream is(serializeString(teststring2), std::ios::binary); - UASSERT(deSerializeString(is) == teststring2); + std::istringstream is(serializeString16(teststring2), std::ios::binary); + UASSERT(deSerializeString16(is) == teststring2); UASSERT(!is.eof()); is.get(); UASSERT(is.eof()); @@ -114,34 +114,34 @@ void TestSerialization::testDeSerializeString() // Test deserialize an incomplete length specifier { std::istringstream is(mkstr("\x53"), std::ios::binary); - EXCEPTION_CHECK(SerializationError, deSerializeString(is)); + EXCEPTION_CHECK(SerializationError, deSerializeString16(is)); } // Test deserialize a string with incomplete data { std::istringstream is(mkstr("\x00\x55 abcdefg"), std::ios::binary); - EXCEPTION_CHECK(SerializationError, deSerializeString(is)); + EXCEPTION_CHECK(SerializationError, deSerializeString16(is)); } } void TestSerialization::testSerializeLongString() { // Test blank string - UASSERT(serializeLongString("") == mkstr("\0\0\0\0")); + UASSERT(serializeString32("") == mkstr("\0\0\0\0")); // Test basic string - UASSERT(serializeLongString("Hello world!") == mkstr("\0\0\0\14Hello world!")); + UASSERT(serializeString32("Hello world!") == mkstr("\0\0\0\14Hello world!")); // Test character range - UASSERT(serializeLongString(teststring2) == mkstr("\0\0\1\0") + teststring2); + UASSERT(serializeString32(teststring2) == mkstr("\0\0\1\0") + teststring2); } void TestSerialization::testDeSerializeLongString() { // Test deserialize { - std::istringstream is(serializeLongString(teststring2), std::ios::binary); - UASSERT(deSerializeLongString(is) == teststring2); + std::istringstream is(serializeString32(teststring2), std::ios::binary); + UASSERT(deSerializeString32(is) == teststring2); UASSERT(!is.eof()); is.get(); UASSERT(is.eof()); @@ -150,19 +150,19 @@ void TestSerialization::testDeSerializeLongString() // Test deserialize an incomplete length specifier { std::istringstream is(mkstr("\x53"), std::ios::binary); - EXCEPTION_CHECK(SerializationError, deSerializeLongString(is)); + EXCEPTION_CHECK(SerializationError, deSerializeString32(is)); } // Test deserialize a string with incomplete data { std::istringstream is(mkstr("\x00\x00\x00\x05 abc"), std::ios::binary); - EXCEPTION_CHECK(SerializationError, deSerializeLongString(is)); + EXCEPTION_CHECK(SerializationError, deSerializeString32(is)); } // Test deserialize a string with a length too large { std::istringstream is(mkstr("\xFF\xFF\xFF\xFF blah"), std::ios::binary); - EXCEPTION_CHECK(SerializationError, deSerializeLongString(is)); + EXCEPTION_CHECK(SerializationError, deSerializeString32(is)); } } @@ -235,19 +235,17 @@ void TestSerialization::testStreamRead() UASSERT(readF1000(is) == F1000_MIN); UASSERT(readF1000(is) == F1000_MAX); - UASSERT(deSerializeString(is) == "foobar!"); + UASSERT(deSerializeString16(is) == "foobar!"); UASSERT(readV2S16(is) == v2s16(500, 500)); UASSERT(readV3S16(is) == v3s16(4207, 604, -30)); UASSERT(readV2S32(is) == v2s32(1920, 1080)); UASSERT(readV3S32(is) == v3s32(-400, 6400054, 290549855)); - UASSERT(deSerializeWideString(is) == L"\x02~woof~\x5455"); - UASSERT(readV3F1000(is) == v3f(500, 10024.2f, -192.54f)); UASSERT(readARGB8(is) == video::SColor(255, 128, 50, 128)); - UASSERT(deSerializeLongString(is) == "some longer string here"); + UASSERT(deSerializeString32(is) == "some longer string here"); UASSERT(is.rdbuf()->in_avail() == 2); UASSERT(readU16(is) == 0xF00D); @@ -275,7 +273,7 @@ void TestSerialization::testStreamWrite() writeF1000(os, F1000_MIN); writeF1000(os, F1000_MAX); - os << serializeString("foobar!"); + os << serializeString16("foobar!"); data = os.str(); UASSERT(data.size() < sizeof(test_serialized_data)); @@ -286,12 +284,10 @@ void TestSerialization::testStreamWrite() writeV2S32(os, v2s32(1920, 1080)); writeV3S32(os, v3s32(-400, 6400054, 290549855)); - os << serializeWideString(L"\x02~woof~\x5455"); - writeV3F1000(os, v3f(500, 10024.2f, -192.54f)); writeARGB8(os, video::SColor(255, 128, 50, 128)); - os << serializeLongString("some longer string here"); + os << serializeString32("some longer string here"); writeU16(os, 0xF00D); @@ -384,7 +380,7 @@ void TestSerialization::testFloatFormat() UASSERT(test_single(i)); } -const u8 TestSerialization::test_serialized_data[12 * 13 - 8] = { +const u8 TestSerialization::test_serialized_data[12 * 11 - 2] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x80, 0x75, 0x30, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x00, 0x00, 0xd1, 0x1e, 0xee, 0x1e, @@ -392,9 +388,7 @@ const u8 TestSerialization::test_serialized_data[12 * 13 - 8] = { 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x21, 0x01, 0xf4, 0x01, 0xf4, 0x10, 0x6f, 0x02, 0x5c, 0xff, 0xe2, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x04, 0x38, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x61, 0xa8, 0x36, 0x11, 0x51, 0x70, - 0x5f, 0x00, 0x08, 0x00, - 0x02, 0x00, 0x7e, 0x00, 'w', 0x00, 'o', 0x00, 'o', 0x00, 'f', 0x00, // \x02~woof~\x5455 - 0x7e, 0x54, 0x55, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff, + 0x5f, 0x00, 0x07, 0xa1, 0x20, 0x00, 0x98, 0xf5, 0x08, 0xff, 0xfd, 0x0f, 0xe4, 0xff, 0x80, 0x32, 0x80, 0x00, 0x00, 0x00, 0x17, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x65, 0x72, 0x65, 0xF0, 0x0D, diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index fd5cbda21..d770101f2 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -35,13 +35,13 @@ FloatType g_serialize_f32_type = FLOATTYPE_UNKNOWN; //// String //// -std::string serializeString(const std::string &plain) +std::string serializeString16(const std::string &plain) { std::string s; char buf[2]; if (plain.size() > STRING_MAX_LEN) - throw SerializationError("String too long for serializeString"); + throw SerializationError("String too long for serializeString16"); s.reserve(2 + plain.size()); writeU16((u8 *)&buf[0], plain.size()); @@ -51,14 +51,14 @@ std::string serializeString(const std::string &plain) return s; } -std::string deSerializeString(std::istream &is) +std::string deSerializeString16(std::istream &is) { std::string s; char buf[2]; is.read(buf, 2); if (is.gcount() != 2) - throw SerializationError("deSerializeString: size not read"); + throw SerializationError("deSerializeString16: size not read"); u16 s_size = readU16((u8 *)buf); if (s_size == 0) @@ -67,66 +67,17 @@ std::string deSerializeString(std::istream &is) s.resize(s_size); is.read(&s[0], s_size); if (is.gcount() != s_size) - throw SerializationError("deSerializeString: couldn't read all chars"); + throw SerializationError("deSerializeString16: couldn't read all chars"); return s; } -//// -//// Wide String -//// - -std::string serializeWideString(const std::wstring &plain) -{ - std::string s; - char buf[2]; - - if (plain.size() > WIDE_STRING_MAX_LEN) - throw SerializationError("String too long for serializeWideString"); - s.reserve(2 + 2 * plain.size()); - - writeU16((u8 *)buf, plain.size()); - s.append(buf, 2); - - for (wchar_t i : plain) { - writeU16((u8 *)buf, i); - s.append(buf, 2); - } - return s; -} - -std::wstring deSerializeWideString(std::istream &is) -{ - std::wstring s; - char buf[2]; - - is.read(buf, 2); - if (is.gcount() != 2) - throw SerializationError("deSerializeWideString: size not read"); - - u16 s_size = readU16((u8 *)buf); - if (s_size == 0) - return s; - - s.reserve(s_size); - for (u32 i = 0; i < s_size; i++) { - is.read(&buf[0], 2); - if (is.gcount() != 2) { - throw SerializationError( - "deSerializeWideString: couldn't read all chars"); - } - - wchar_t c16 = readU16((u8 *)buf); - s.append(&c16, 1); - } - return s; -} //// //// Long String //// -std::string serializeLongString(const std::string &plain) +std::string serializeString32(const std::string &plain) { std::string s; char buf[4]; @@ -141,7 +92,7 @@ std::string serializeLongString(const std::string &plain) return s; } -std::string deSerializeLongString(std::istream &is) +std::string deSerializeString32(std::istream &is) { std::string s; char buf[4]; diff --git a/src/util/serialize.h b/src/util/serialize.h index a988a8f78..b3ec28eab 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -440,16 +440,16 @@ MAKE_STREAM_WRITE_FXN(video::SColor, ARGB8, 4); //// // Creates a string with the length as the first two bytes -std::string serializeString(const std::string &plain); +std::string serializeString16(const std::string &plain); // Reads a string with the length as the first two bytes -std::string deSerializeString(std::istream &is); +std::string deSerializeString16(std::istream &is); // Creates a string with the length as the first four bytes -std::string serializeLongString(const std::string &plain); +std::string serializeString32(const std::string &plain); // Reads a string with the length as the first four bytes -std::string deSerializeLongString(std::istream &is); +std::string deSerializeString32(std::istream &is); // Creates a string encoded in JSON format (almost equivalent to a C string literal) std::string serializeJsonString(const std::string &plain); -- cgit v1.2.3 From 9dc29a75b416c6dab27ce93d0129383309cbf2c2 Mon Sep 17 00:00:00 2001 From: HybridDog <3192173+HybridDog@users.noreply.github.com> Date: Sat, 3 Oct 2020 18:33:51 +0200 Subject: Reduce the FPS when the window is unfocused (#8837) --- builtin/settingtypes.txt | 4 ++-- src/client/game.cpp | 7 ++++--- src/defaultsettings.cpp | 4 ++-- src/gui/guiEngine.cpp | 17 +++++++++-------- src/gui/guiEngine.h | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) (limited to 'src/client') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 6d9c6f573..7f2d12be5 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -606,8 +606,8 @@ arm_inertia (Arm inertia) bool true # to not waste CPU power for no benefit. fps_max (Maximum FPS) int 60 1 -# Maximum FPS when game is paused. -pause_fps_max (FPS in pause menu) int 20 1 +# Maximum FPS when the window is not focused, or when the game is paused. +fps_max_unfocused (FPS when unfocused or paused) int 20 1 # Open the pause menu when the window's focus is lost. Does not pause if a formspec is # open. diff --git a/src/client/game.cpp b/src/client/game.cpp index 920383aaf..8f9d51417 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3996,9 +3996,10 @@ inline void Game::limitFps(FpsControl *fps_timings, f32 *dtime) else fps_timings->busy_time = 0; - u32 frametime_min = 1000 / (g_menumgr.pausesGame() - ? g_settings->getFloat("pause_fps_max") - : g_settings->getFloat("fps_max")); + u32 frametime_min = 1000 / ( + device->isWindowFocused() && !g_menumgr.pausesGame() + ? g_settings->getFloat("fps_max") + : g_settings->getFloat("fps_max_unfocused")); if (fps_timings->busy_time < frametime_min) { fps_timings->sleep_time = frametime_min - fps_timings->busy_time; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 3a0b88dc2..8f5ed3e17 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -165,7 +165,7 @@ void set_default_settings(Settings *settings) settings->setDefault("tooltip_show_delay", "400"); settings->setDefault("tooltip_append_itemname", "false"); settings->setDefault("fps_max", "60"); - settings->setDefault("pause_fps_max", "20"); + settings->setDefault("fps_max_unfocused", "20"); settings->setDefault("viewing_range", "100"); #if ENABLE_GLES settings->setDefault("near_plane", "0.1"); @@ -477,7 +477,7 @@ void set_default_settings(Settings *settings) settings->setDefault("max_block_generate_distance", "5"); settings->setDefault("enable_3d_clouds", "false"); settings->setDefault("fps_max", "30"); - settings->setDefault("pause_fps_max", "10"); + settings->setDefault("fps_max_unfocused", "10"); settings->setDefault("max_objects_per_block", "20"); settings->setDefault("sqlite_synchronous", "1"); settings->setDefault("server_map_save_interval", "15"); diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index b40707d01..4a13f0b11 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -297,10 +297,14 @@ void GUIEngine::run() driver->endScene(); + IrrlichtDevice *device = RenderingEngine::get_raw_device(); + u32 frametime_min = 1000 / (device->isWindowFocused() + ? g_settings->getFloat("fps_max") + : g_settings->getFloat("fps_max_unfocused")); if (m_clouds_enabled) - cloudPostProcess(); + cloudPostProcess(frametime_min, device); else - sleep_ms(25); + sleep_ms(frametime_min); m_script->step(); @@ -367,9 +371,8 @@ void GUIEngine::cloudPreProcess() } /******************************************************************************/ -void GUIEngine::cloudPostProcess() +void GUIEngine::cloudPostProcess(u32 frametime_min, IrrlichtDevice *device) { - float fps_max = g_settings->getFloat("pause_fps_max"); // Time of frame without fps limit u32 busytime_u32; @@ -380,12 +383,10 @@ void GUIEngine::cloudPostProcess() else busytime_u32 = 0; - // FPS limiter - u32 frametime_min = 1000./fps_max; - + // FPS limit if (busytime_u32 < frametime_min) { u32 sleeptime = frametime_min - busytime_u32; - RenderingEngine::get_raw_device()->sleep(sleeptime); + device->sleep(sleeptime); } } diff --git a/src/gui/guiEngine.h b/src/gui/guiEngine.h index f9ad0fb0a..e5b3edce7 100644 --- a/src/gui/guiEngine.h +++ b/src/gui/guiEngine.h @@ -277,7 +277,7 @@ private: /** do preprocessing for cloud subsystem */ void cloudPreProcess(); /** do postprocessing for cloud subsystem */ - void cloudPostProcess(); + void cloudPostProcess(u32 frametime_min, IrrlichtDevice *device); /** internam data required for drawing clouds */ struct clouddata { -- cgit v1.2.3 From 0f98b54aa4b2361575002d92b29fe222703ba557 Mon Sep 17 00:00:00 2001 From: Lars Müller <34514239+appgurueu@users.noreply.github.com> Date: Sun, 4 Oct 2020 15:09:12 +0200 Subject: Fix short 180 degree rotation when using set_bone_position (#10405) --- src/client/content_cao.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 71a9d4b54..c1715a289 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1460,24 +1460,17 @@ void GenericCAO::updateBonePosition() if (!bone) continue; - //If bone is manually positioned there is no need to perform the bug check - bool skip = false; - for (auto &it : m_bone_position) { - if (it.first == bone->getName()) { - skip = true; - break; - } - } - if (skip) - continue; - // Workaround for Irrlicht bug // We check each bone to see if it has been rotated ~180deg from its expected position due to a bug in Irricht // when using EJUOR_CONTROL joint control. If the bug is detected we update the bone to the proper position // and update the bones transformation. v3f bone_rot = bone->getRelativeTransformation().getRotationDegrees(); - float offset = fabsf(bone_rot.X - bone->getRotation().X); - if (offset > 179.9f && offset < 180.1f) { + float offset_X = fabsf(bone_rot.X - bone->getRotation().X); + float offset_Y = fabsf(bone_rot.Y - bone->getRotation().Y); + float offset_Z = fabsf(bone_rot.Z - bone->getRotation().Z); + if ((offset_X > 179.9f && offset_X < 180.1f) + || (offset_Y > 179.9f && offset_Y < 180.1f) + || (offset_Z > 179.9f && offset_Z < 180.1f)) { bone->setRotation(bone_rot); bone->updateAbsolutePosition(); } -- cgit v1.2.3 From 3068853e8a58ccc7370a5ce977c08223601c497a Mon Sep 17 00:00:00 2001 From: Jordan Snelling Date: Sun, 4 Oct 2020 14:10:34 +0100 Subject: Add First Person Attachments (#10360) Fixes some other third person camera specific attachments. Implements a single new flag for entities to be forced visible in first person mode. Old mods do not need to be updated to use the new flag and are fully backwards compatible. --- doc/lua_api.txt | 8 +++--- src/activeobject.h | 4 +-- src/client/content_cao.cpp | 56 ++++++++++++++++++++++++++++++++++++----- src/client/content_cao.h | 8 ++++++ src/client/game.cpp | 3 ++- src/clientiface.cpp | 5 ++-- src/script/lua_api/l_camera.cpp | 3 ++- src/script/lua_api/l_object.cpp | 14 +++++++---- src/server/luaentity_sao.cpp | 4 +-- src/server/player_sao.cpp | 9 ++++--- src/server/unit_sao.cpp | 17 +++++++------ src/server/unit_sao.h | 5 ++-- 12 files changed, 101 insertions(+), 35 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index c21da1871..77fb4a654 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6167,12 +6167,14 @@ object you are working with still exists. `frame_loop`. * `set_animation_frame_speed(frame_speed)` * `frame_speed`: number, default: `15.0` -* `set_attach(parent, bone, position, rotation)` +* `set_attach(parent, bone, position, rotation, forced_visible)` * `bone`: string * `position`: `{x=num, y=num, z=num}` (relative) * `rotation`: `{x=num, y=num, z=num}` = Rotation on each axis, in degrees -* `get_attach()`: returns parent, bone, position, rotation or nil if it isn't - attached. + * `forced_visible`: Boolean to control whether the attached entity + should appear in first person. +* `get_attach()`: returns parent, bone, position, rotation, forced_visible, + or nil if it isn't attached. * `set_detach()` * `set_bone_position(bone, position, rotation)` * `bone`: string diff --git a/src/activeobject.h b/src/activeobject.h index 85e160d10..0829858ad 100644 --- a/src/activeobject.h +++ b/src/activeobject.h @@ -120,9 +120,9 @@ public: virtual void setAttachment(int parent_id, const std::string &bone, v3f position, - v3f rotation) {} + v3f rotation, bool force_visible) {} virtual void getAttachment(int *parent_id, std::string *bone, v3f *position, - v3f *rotation) const {} + v3f *rotation, bool *force_visible) const {} virtual void clearChildAttachments() {} virtual void clearParentAttachment() {} virtual void addAttachmentChild(int child_id) {} diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index c1715a289..fae06554a 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -456,7 +456,8 @@ void GenericCAO::setChildrenVisible(bool toset) for (u16 cao_id : m_attachment_child_ids) { GenericCAO *obj = m_env->getGenericCAO(cao_id); if (obj) { - obj->setVisible(toset); + // Check if the entity is forced to appear in first person. + obj->setVisible(obj->isForcedVisible() ? true : toset); } } } @@ -477,8 +478,6 @@ void GenericCAO::setAttachment(int parent_id, const std::string &bone, v3f posit if (parent) parent->addAttachmentChild(m_id); } - - updateAttachments(); } @@ -498,7 +497,7 @@ void GenericCAO::clearChildAttachments() int child_id = *m_attachment_child_ids.begin(); if (ClientActiveObject *child = m_env->getActiveObject(child_id)) - child->setAttachment(0, "", v3f(), v3f()); + child->setAttachment(0, "", v3f(), v3f(), false); removeAttachmentChild(child_id); } @@ -800,6 +799,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) updateBonePosition(); updateAttachments(); setNodeLight(m_last_light); + updateMeshCulling(); } void GenericCAO::updateLight(u32 day_night_ratio) @@ -1411,6 +1411,9 @@ void GenericCAO::updateTextures(std::string mod) setMeshColor(mesh, m_prop.colors[0]); } } + // Prevent showing the player after changing texture + if (m_is_local_player) + updateMeshCulling(); } void GenericCAO::updateAnimation() @@ -1739,12 +1742,25 @@ void GenericCAO::processMessage(const std::string &data) std::string bone = deSerializeString16(is); v3f position = readV3F32(is); v3f rotation = readV3F32(is); + m_force_visible = readU8(is); // Returns false for EOF setAttachment(parent_id, bone, position, rotation); + // Forcibly show attachments if required by set_attach + if (m_force_visible) + m_is_visible = true; // localplayer itself can't be attached to localplayer - if (!m_is_local_player) - m_is_visible = !m_attached_to_local; + else if (!m_is_local_player) { + // Objects attached to the local player should be hidden in first + // person provided the forced boolean isn't set. + m_is_visible = !m_attached_to_local || + m_client->getCamera()->getCameraMode() != CAMERA_MODE_FIRST; + m_force_visible = false; + } else { + // Local players need to have this set, + // otherwise first person attachments fail. + m_is_visible = true; + } } else if (cmd == AO_CMD_PUNCHED) { u16 result_hp = readU16(is); @@ -1858,5 +1874,33 @@ std::string GenericCAO::debugInfoText() return os.str(); } +void GenericCAO::updateMeshCulling() +{ + if (!m_is_local_player) + return; + + // Grab the active player scene node so we know there's + // at least a mesh to occlude from the camera. + irr::scene::ISceneNode *node = getSceneNode(); + if (!node) + return; + + if (m_client->getCamera()->getCameraMode() == CAMERA_MODE_FIRST) { + // Hide the mesh by culling both front and + // back faces. Serious hackyness but it works for our + // purposes. This also preserves the skeletal armature. + node->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + true); + node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, + true); + } else { + // Restore mesh visibility. + node->setMaterialFlag(video::EMF_BACK_FACE_CULLING, + m_prop.backface_culling); + node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, + false); + } +} + // Prototype GenericCAO proto_GenericCAO(NULL, NULL); diff --git a/src/client/content_cao.h b/src/client/content_cao.h index 974ff9a1e..daf697767 100644 --- a/src/client/content_cao.h +++ b/src/client/content_cao.h @@ -124,6 +124,7 @@ private: float m_step_distance_counter = 0.0f; u8 m_last_light = 255; bool m_is_visible = false; + bool m_force_visible = false; s8 m_glow = 0; // Material video::E_MATERIAL_TYPE m_material_type; @@ -215,6 +216,11 @@ public: m_is_visible = toset; } + inline bool isForcedVisible() const + { + return m_force_visible; + } + void setChildrenVisible(bool toset); void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation); void getAttachment(int *parent_id, std::string *bone, v3f *position, @@ -275,4 +281,6 @@ public: { return m_prop.infotext; } + + void updateMeshCulling(); }; diff --git a/src/client/game.cpp b/src/client/game.cpp index 8f9d51417..366464467 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2950,7 +2950,8 @@ void Game::updateCamera(u32 busy_time, f32 dtime) camera->toggleCameraMode(); - playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); + // Make the player visible depending on camera mode. + playercao->updateMeshCulling(); playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); } diff --git a/src/clientiface.cpp b/src/clientiface.cpp index 602a44c90..28a0ee770 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -80,10 +80,11 @@ LuaEntitySAO *getAttachedObject(PlayerSAO *sao, ServerEnvironment *env) int id; std::string bone; v3f dummy; - sao->getAttachment(&id, &bone, &dummy, &dummy); + bool force_visible; + sao->getAttachment(&id, &bone, &dummy, &dummy, &force_visible); ServerActiveObject *ao = env->getActiveObject(id); while (id && ao) { - ao->getAttachment(&id, &bone, &dummy, &dummy); + ao->getAttachment(&id, &bone, &dummy, &dummy, &force_visible); if (id) ao = env->getActiveObject(id); } diff --git a/src/script/lua_api/l_camera.cpp b/src/script/lua_api/l_camera.cpp index bfa60be67..40251154c 100644 --- a/src/script/lua_api/l_camera.cpp +++ b/src/script/lua_api/l_camera.cpp @@ -63,7 +63,8 @@ int LuaCamera::l_set_camera_mode(lua_State *L) return 0; camera->setCameraMode((CameraMode)((int)lua_tonumber(L, 2))); - playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); + // Make the player visible depending on camera mode. + playercao->updateMeshCulling(); playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST); return 0; } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 303b1175b..fead4e849 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -664,7 +664,7 @@ int ObjectRef::l_get_bone_position(lua_State *L) return 2; } -// set_attach(self, parent, bone, position, rotation) +// set_attach(self, parent, bone, position, rotation, force_visible) int ObjectRef::l_set_attach(lua_State *L) { GET_ENV_PTR; @@ -687,7 +687,8 @@ int ObjectRef::l_set_attach(lua_State *L) std::string bone; v3f position = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0); - co->getAttachment(&parent_id, &bone, &position, &rotation); + bool force_visible; + co->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible); if (parent_id) { ServerActiveObject *old_parent = env->getActiveObject(parent_id); old_parent->removeAttachmentChild(co->getId()); @@ -702,7 +703,8 @@ int ObjectRef::l_set_attach(lua_State *L) rotation = v3f(0, 0, 0); if (!lua_isnil(L, 5)) rotation = read_v3f(L, 5); - co->setAttachment(parent->getId(), bone, position, rotation); + force_visible = readParam(L, 6, false); + co->setAttachment(parent->getId(), bone, position, rotation, force_visible); parent->addAttachmentChild(co->getId()); return 0; } @@ -722,7 +724,8 @@ int ObjectRef::l_get_attach(lua_State *L) std::string bone; v3f position = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0); - co->getAttachment(&parent_id, &bone, &position, &rotation); + bool force_visible; + co->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible); if (!parent_id) return 0; ServerActiveObject *parent = env->getActiveObject(parent_id); @@ -731,7 +734,8 @@ int ObjectRef::l_get_attach(lua_State *L) lua_pushlstring(L, bone.c_str(), bone.size()); push_v3f(L, position); push_v3f(L, rotation); - return 4; + lua_pushboolean(L, force_visible); + return 5; } // set_detach(self) diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index f20914f7f..b39797531 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -238,9 +238,9 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) msg_os << serializeString32(generateUpdateAnimationCommand()); // 3 for (const auto &bone_pos : m_bone_position) { msg_os << serializeString32(generateUpdateBonePositionCommand( - bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // m_bone_position.size + bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // 3 + N } - msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 + msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 + m_bone_position.size int message_count = 4 + m_bone_position.size(); diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 8d4938c3c..344d18a20 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -122,10 +122,10 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) msg_os << serializeString32(generateUpdateAnimationCommand()); // 3 for (const auto &bone_pos : m_bone_position) { msg_os << serializeString32(generateUpdateBonePositionCommand( - bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // m_bone_position.size + bone_pos.first, bone_pos.second.X, bone_pos.second.Y)); // 3 + N } - msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 - msg_os << serializeString32(generateUpdatePhysicsOverrideCommand()); // 5 + msg_os << serializeString32(generateUpdateAttachmentCommand()); // 4 + m_bone_position.size + msg_os << serializeString32(generateUpdatePhysicsOverrideCommand()); // 5 + m_bone_position.size int message_count = 5 + m_bone_position.size(); @@ -569,7 +569,8 @@ bool PlayerSAO::checkMovementCheat() int parent_id; std::string bone; v3f attachment_rot; - getAttachment(&parent_id, &bone, &attachment_pos, &attachment_rot); + bool force_visible; + getAttachment(&parent_id, &bone, &attachment_pos, &attachment_rot, &force_visible); } v3f parent_pos = parent->getBasePosition(); diff --git a/src/server/unit_sao.cpp b/src/server/unit_sao.cpp index d906e885e..2371640ca 100644 --- a/src/server/unit_sao.cpp +++ b/src/server/unit_sao.cpp @@ -121,8 +121,8 @@ void UnitSAO::sendOutdatedData() } // clang-format on -void UnitSAO::setAttachment( - int parent_id, const std::string &bone, v3f position, v3f rotation) +void UnitSAO::setAttachment(int parent_id, const std::string &bone, v3f position, + v3f rotation, bool force_visible) { // Attachments need to be handled on both the server and client. // If we just attach on the server, we can only copy the position of the parent. @@ -137,6 +137,7 @@ void UnitSAO::setAttachment( m_attachment_bone = bone; m_attachment_position = position; m_attachment_rotation = rotation; + m_force_visible = force_visible; m_attachment_sent = false; if (parent_id != old_parent) { @@ -145,13 +146,14 @@ void UnitSAO::setAttachment( } } -void UnitSAO::getAttachment( - int *parent_id, std::string *bone, v3f *position, v3f *rotation) const +void UnitSAO::getAttachment(int *parent_id, std::string *bone, v3f *position, + v3f *rotation, bool *force_visible) const { *parent_id = m_attachment_parent_id; *bone = m_attachment_bone; *position = m_attachment_position; *rotation = m_attachment_rotation; + *force_visible = m_force_visible; } void UnitSAO::clearChildAttachments() @@ -159,7 +161,7 @@ void UnitSAO::clearChildAttachments() for (int child_id : m_attachment_child_ids) { // Child can be NULL if it was deleted earlier if (ServerActiveObject *child = m_env->getActiveObject(child_id)) - child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0)); + child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0), false); } m_attachment_child_ids.clear(); } @@ -169,9 +171,9 @@ void UnitSAO::clearParentAttachment() ServerActiveObject *parent = nullptr; if (m_attachment_parent_id) { parent = m_env->getActiveObject(m_attachment_parent_id); - setAttachment(0, "", m_attachment_position, m_attachment_rotation); + setAttachment(0, "", m_attachment_position, m_attachment_rotation, false); } else { - setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0)); + setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0), false); } // Do it if (parent) @@ -245,6 +247,7 @@ std::string UnitSAO::generateUpdateAttachmentCommand() const os << serializeString16(m_attachment_bone); writeV3F32(os, m_attachment_position); writeV3F32(os, m_attachment_rotation); + writeU8(os, m_force_visible); return os.str(); } diff --git a/src/server/unit_sao.h b/src/server/unit_sao.h index 3cb7f0ad5..a21e055c5 100644 --- a/src/server/unit_sao.h +++ b/src/server/unit_sao.h @@ -64,9 +64,9 @@ public: ServerActiveObject *getParent() const; inline bool isAttached() const { return getParent(); } void setAttachment(int parent_id, const std::string &bone, v3f position, - v3f rotation); + v3f rotation, bool force_visible); void getAttachment(int *parent_id, std::string *bone, v3f *position, - v3f *rotation) const; + v3f *rotation, bool *force_visible) const; void clearChildAttachments(); void clearParentAttachment(); void addAttachmentChild(int child_id); @@ -133,4 +133,5 @@ private: v3f m_attachment_position; v3f m_attachment_rotation; bool m_attachment_sent = false; + bool m_force_visible = false; }; -- cgit v1.2.3 From 81c66d6efb9fb0ab8a03b40e2bc22aa49eff9a04 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Sun, 4 Oct 2020 15:24:29 +0200 Subject: Minimap as HUD element with API control Features: * Define Minimap available modes (surface/radar, scale) from Lua, using player:set_minimap_modes() * New HUD elements for displaying minimap with custom size and placing * New minimap mode for displaying a texture instead of the map --- doc/lua_api.txt | 33 ++++- src/client/client.cpp | 1 + src/client/client.h | 1 + src/client/game.cpp | 75 +++++------- src/client/hud.cpp | 30 ++++- src/client/hud.h | 2 + src/client/mapblock_mesh.cpp | 2 +- src/client/minimap.cpp | 237 +++++++++++++++++++++++++++--------- src/client/minimap.h | 41 ++++--- src/hud.cpp | 1 + src/hud.h | 13 +- src/network/clientopcodes.cpp | 1 + src/network/clientpackethandler.cpp | 46 ++++++- src/network/networkprotocol.h | 14 ++- src/network/serveropcodes.cpp | 1 + src/script/lua_api/l_minimap.cpp | 24 ++-- src/script/lua_api/l_object.cpp | 62 ++++++++++ src/script/lua_api/l_object.h | 3 + src/server.cpp | 17 +++ src/server.h | 12 ++ 20 files changed, 471 insertions(+), 145 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 77fb4a654..9e9af20da 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1484,6 +1484,15 @@ Displays an image oriented or translated according to current heading direction. If translation is chosen, texture is repeated horizontally to fill the whole element. +### `minimap` + +Displays a minimap on the HUD. + +* `size`: Size of the minimap to display. Minimap should be a square to avoid + distortion. +* `alignment`: The alignment of the minimap. +* `offset`: offset in pixels from position. + Representations of simple things ================================ @@ -6366,6 +6375,27 @@ object you are working with still exists. * `hud_set_hotbar_selected_image(texturename)` * sets image for selected item of hotbar * `hud_get_hotbar_selected_image`: returns texturename +* `set_minimap_modes({mode, mode, ...}, selected_mode)` + * Overrides the available minimap modes (and toggle order), and changes the + selected mode. + * `mode` is a table consisting of up to four fields: + * `type`: Available type: + * `off`: Minimap off + * `surface`: Minimap in surface mode + * `radar`: Minimap in radar mode + * `texture`: Texture to be displayed instead of terrain map + (texture is centered around 0,0 and can be scaled). + Texture size is limited to 512 x 512 pixel. + * `label`: Optional label to display on minimap mode toggle + The translation must be handled within the mod. + * `size`: Sidelength or diameter, in number of nodes, of the terrain + displayed in minimap + * `texture`: Only for texture type, name of the texture to display + * `scale`: Only for texture type, scale of the texture map in nodes per + pixel (for example a `scale` of 2 means each pixel represents a 2x2 + nodes square) + * `selected_mode` is the mode index to be selected after modes have been changed + (0 is the first mode). * `set_sky(parameters)` * `parameters` is a table with the following optional fields: * `base_color`: ColorSpec, changes fog in "skybox" and "plain". @@ -8047,7 +8077,8 @@ Used by `Player:hud_add`. Returned by `Player:hud_get`. { hud_elem_type = "image", -- See HUD element types - -- Type of element, can be "image", "text", "statbar", "inventory" or "compass" + -- Type of element, can be "image", "text", "statbar", "inventory", + -- "compass" or "minimap" position = {x=0.5, y=0.5}, -- Left corner position of element diff --git a/src/client/client.cpp b/src/client/client.cpp index d6e529c40..7fafe0da9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -129,6 +129,7 @@ Client::Client( if (g_settings->getBool("enable_minimap")) { m_minimap = new Minimap(this); } + m_cache_save_interval = g_settings->getU16("server_map_save_interval"); } diff --git a/src/client/client.h b/src/client/client.h index 733634db1..8f4aac6e3 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -223,6 +223,7 @@ public: void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt); void handleCommand_PlayerSpeed(NetworkPacket *pkt); void handleCommand_MediaPush(NetworkPacket *pkt); + void handleCommand_MinimapModes(NetworkPacket *pkt); void ProcessData(NetworkPacket *pkt); diff --git a/src/client/game.cpp b/src/client/game.cpp index 366464467..54e0c9f20 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1416,11 +1416,9 @@ bool Game::createClient(const GameStartData &start_data) } mapper = client->getMinimap(); - if (mapper) { - mapper->setMinimapMode(MINIMAP_MODE_OFF); - if (client->modsLoaded()) - client->getScript()->on_minimap_ready(mapper); - } + + if (mapper && client->modsLoaded()) + client->getScript()->on_minimap_ready(mapper); return true; } @@ -2222,52 +2220,37 @@ void Game::toggleMinimap(bool shift_pressed) if (!mapper || !m_game_ui->m_flags.show_hud || !g_settings->getBool("enable_minimap")) return; - if (shift_pressed) { + if (shift_pressed) mapper->toggleMinimapShape(); - return; - } + else + mapper->nextMode(); + + // TODO: When legacy minimap is deprecated, keep only HUD minimap stuff here + // Not so satisying code to keep compatibility with old fixed mode system + // --> u32 hud_flags = client->getEnv().getLocalPlayer()->hud_flags; - MinimapMode mode = MINIMAP_MODE_OFF; - if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) { - mode = mapper->getMinimapMode(); - mode = (MinimapMode)((int)mode + 1); - // If radar is disabled and in, or switching to, radar mode - if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE) && mode > 3) - mode = MINIMAP_MODE_OFF; - } + if (!(hud_flags & HUD_FLAG_MINIMAP_VISIBLE)) { + m_game_ui->m_flags.show_minimap = false; + } else { - m_game_ui->m_flags.show_minimap = true; - switch (mode) { - case MINIMAP_MODE_SURFACEx1: - m_game_ui->showTranslatedStatusText("Minimap in surface mode, Zoom x1"); - break; - case MINIMAP_MODE_SURFACEx2: - m_game_ui->showTranslatedStatusText("Minimap in surface mode, Zoom x2"); - break; - case MINIMAP_MODE_SURFACEx4: - m_game_ui->showTranslatedStatusText("Minimap in surface mode, Zoom x4"); - break; - case MINIMAP_MODE_RADARx1: - m_game_ui->showTranslatedStatusText("Minimap in radar mode, Zoom x1"); - break; - case MINIMAP_MODE_RADARx2: - m_game_ui->showTranslatedStatusText("Minimap in radar mode, Zoom x2"); - break; - case MINIMAP_MODE_RADARx4: - m_game_ui->showTranslatedStatusText("Minimap in radar mode, Zoom x4"); - break; - default: - mode = MINIMAP_MODE_OFF; - m_game_ui->m_flags.show_minimap = false; - if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) - m_game_ui->showTranslatedStatusText("Minimap hidden"); - else - m_game_ui->showTranslatedStatusText("Minimap currently disabled by game or mod"); - } + // If radar is disabled, try to find a non radar mode or fall back to 0 + if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE)) + while (mapper->getModeIndex() && + mapper->getModeDef().type == MINIMAP_TYPE_RADAR) + mapper->nextMode(); - mapper->setMinimapMode(mode); + m_game_ui->m_flags.show_minimap = mapper->getModeDef().type != + MINIMAP_TYPE_OFF; + } + // <-- + // End of 'not so satifying code' + if ((hud_flags & HUD_FLAG_MINIMAP_VISIBLE) || + (hud && hud->hasElementOfType(HUD_ELEM_MINIMAP))) + m_game_ui->showStatusText(utf8_to_wide(mapper->getModeDef().label)); + else + m_game_ui->showTranslatedStatusText("Minimap currently disabled by game or mod"); } void Game::toggleFog() @@ -3954,7 +3937,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, /* Update minimap pos and rotation */ - if (mapper && m_game_ui->m_flags.show_minimap && m_game_ui->m_flags.show_hud) { + if (mapper && m_game_ui->m_flags.show_hud) { mapper->setPos(floatToInt(player->getPosition(), BS)); mapper->setAngle(player->getYaw()); } diff --git a/src/client/hud.cpp b/src/client/hud.cpp index d3038230c..f6497fe25 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mesh.h" #include "wieldmesh.h" #include "client/renderingengine.h" +#include "client/minimap.h" #ifdef HAVE_TOUCHSCREENGUI #include "gui/touchscreengui.h" @@ -297,6 +298,18 @@ void Hud::drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount, } } +bool Hud::hasElementOfType(HudElementType type) +{ + for (size_t i = 0; i != player->maxHudId(); i++) { + HudElement *e = player->getHud(i); + if (!e) + continue; + if (e->type == type) + return true; + } + return false; +} + // Calculates screen position of waypoint. Returns true if waypoint is visible (in front of the player), else false. bool Hud::calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *pos) { @@ -491,7 +504,22 @@ void Hud::drawLuaElements(const v3s16 &camera_offset) default: break; } - + break; } + case HUD_ELEM_MINIMAP: { + if (e->size.X <= 0 || e->size.Y <= 0) + break; + if (!client->getMinimap()) + break; + // Draw a minimap of size "size" + v2s32 dstsize(e->size.X * m_scale_factor, + e->size.Y * m_scale_factor); + // (no percent size as minimap would likely be anamorphosed) + v2s32 offset((e->align.X - 1.0) * dstsize.X / 2, + (e->align.Y - 1.0) * dstsize.Y / 2); + core::rect rect(0, 0, dstsize.X, dstsize.Y); + rect += pos + offset + v2s32(e->offset.X * m_scale_factor, + e->offset.Y * m_scale_factor); + client->getMinimap()->drawMinimap(rect); break; } default: infostream << "Hud::drawLuaElements: ignoring drawform " << e->type << diff --git a/src/client/hud.h b/src/client/hud.h index cf83cb16e..d46545d71 100644 --- a/src/client/hud.h +++ b/src/client/hud.h @@ -81,6 +81,8 @@ public: m_selected_face_normal = face_normal; } + bool hasElementOfType(HudElementType type); + void drawLuaElements(const v3s16 &camera_offset); private: diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 2f96ca61f..b59679523 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -1044,7 +1044,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): m_use_tangent_vertices = data->m_use_tangent_vertices; m_enable_vbo = g_settings->getBool("enable_vbo"); - if (g_settings->getBool("enable_minimap")) { + if (data->m_client->getMinimap()) { m_minimap_mapblock = new MinimapMapblock; m_minimap_mapblock->getMinimapNodes( &data->m_vmanip, data->m_blockpos * MAP_BLOCKSIZE); diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index 68770ec19..6bae408b4 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "shader.h" #include "mapblock.h" #include "client/renderingengine.h" - +#include "gettext.h" //// //// MinimapUpdateThread @@ -108,8 +108,11 @@ void MinimapUpdateThread::doUpdate() } } - if (data->map_invalidated && data->mode != MINIMAP_MODE_OFF) { - getMap(data->pos, data->map_size, data->scan_height); + + if (data->map_invalidated && ( + data->mode.type == MINIMAP_TYPE_RADAR || + data->mode.type == MINIMAP_TYPE_SURFACE)) { + getMap(data->pos, data->mode.map_size, data->mode.scan_height); data->map_invalidated = false; } } @@ -181,19 +184,26 @@ Minimap::Minimap(Client *client) this->m_ndef = client->getNodeDefManager(); m_angle = 0.f; + m_current_mode_index = 0; // Initialize static settings m_enable_shaders = g_settings->getBool("enable_shaders"); m_surface_mode_scan_height = g_settings->getBool("minimap_double_scan_height") ? 256 : 128; + // Initialize minimap modes + addMode(MINIMAP_TYPE_OFF); + addMode(MINIMAP_TYPE_SURFACE, 256); + addMode(MINIMAP_TYPE_SURFACE, 128); + addMode(MINIMAP_TYPE_SURFACE, 64); + addMode(MINIMAP_TYPE_RADAR, 512); + addMode(MINIMAP_TYPE_RADAR, 256); + addMode(MINIMAP_TYPE_RADAR, 128); + // Initialize minimap data data = new MinimapData; - data->mode = MINIMAP_MODE_OFF; - data->is_radar = false; - data->map_invalidated = true; - data->texture = NULL; - data->heightmap_texture = NULL; + data->map_invalidated = true; + data->minimap_shape_round = g_settings->getBool("minimap_shape_round"); // Get round minimap textures @@ -215,6 +225,8 @@ Minimap::Minimap(Client *client) // Create object marker texture data->object_marker_red = m_tsrc->getTexture("object_marker_red.png"); + setModeIndex(0); + // Create mesh buffer for minimap m_meshbuffer = getMinimapMeshBuffer(); @@ -280,29 +292,101 @@ MinimapShape Minimap::getMinimapShape() return MINIMAP_SHAPE_SQUARE; } -void Minimap::setMinimapMode(MinimapMode mode) +void Minimap::setModeIndex(size_t index) { - static const MinimapModeDef modedefs[MINIMAP_MODE_COUNT] = { - {false, 0, 0}, - {false, m_surface_mode_scan_height, 256}, - {false, m_surface_mode_scan_height, 128}, - {false, m_surface_mode_scan_height, 64}, - {true, 32, 128}, - {true, 32, 64}, - {true, 32, 32} - }; - - if (mode >= MINIMAP_MODE_COUNT) - return; - MutexAutoLock lock(m_mutex); - data->is_radar = modedefs[mode].is_radar; - data->scan_height = modedefs[mode].scan_height; - data->map_size = modedefs[mode].map_size; - data->mode = mode; + if (index < m_modes.size()) { + data->mode = m_modes[index]; + m_current_mode_index = index; + } else { + data->mode = MinimapModeDef{MINIMAP_TYPE_OFF, N_("Minimap hidden"), 0, 0, ""}; + m_current_mode_index = 0; + } + + data->map_invalidated = true; - m_minimap_update_thread->deferUpdate(); + if (m_minimap_update_thread) + m_minimap_update_thread->deferUpdate(); +} + +void Minimap::addMode(MinimapModeDef mode) +{ + // Check validity + if (mode.type == MINIMAP_TYPE_TEXTURE) { + if (mode.texture.empty()) + return; + if (mode.scale < 1) + mode.scale = 1; + } + + int zoom = -1; + + // Build a default standard label + if (mode.label == "") { + switch (mode.type) { + case MINIMAP_TYPE_OFF: + mode.label = N_("Minimap hidden"); + break; + case MINIMAP_TYPE_SURFACE: + mode.label = N_("Minimap in surface mode, Zoom x%d"); + if (mode.map_size > 0) + zoom = 256 / mode.map_size; + break; + case MINIMAP_TYPE_RADAR: + mode.label = N_("Minimap in radar mode, Zoom x%d"); + if (mode.map_size > 0) + zoom = 512 / mode.map_size; + break; + case MINIMAP_TYPE_TEXTURE: + mode.label = N_("Minimap in texture mode"); + break; + default: + break; + } + } + + if (zoom >= 0) { + char label_buf[1024]; + porting::mt_snprintf(label_buf, sizeof(label_buf), + mode.label.c_str(), zoom); + mode.label = label_buf; + } + + m_modes.push_back(mode); +} + +void Minimap::addMode(MinimapType type, u16 size, std::string label, + std::string texture, u16 scale) +{ + MinimapModeDef mode; + mode.type = type; + mode.label = label; + mode.map_size = size; + mode.texture = texture; + mode.scale = scale; + switch (type) { + case MINIMAP_TYPE_SURFACE: + mode.scan_height = m_surface_mode_scan_height; + break; + case MINIMAP_TYPE_RADAR: + mode.scan_height = 32; + break; + default: + mode.scan_height = 0; + } + addMode(mode); +} + +void Minimap::nextMode() +{ + if (m_modes.empty()) + return; + m_current_mode_index++; + if (m_current_mode_index >= m_modes.size()) + m_current_mode_index = 0; + + setModeIndex(m_current_mode_index); } void Minimap::setPos(v3s16 pos) @@ -331,16 +415,16 @@ void Minimap::setAngle(f32 angle) void Minimap::blitMinimapPixelsToImageRadar(video::IImage *map_image) { video::SColor c(240, 0, 0, 0); - for (s16 x = 0; x < data->map_size; x++) - for (s16 z = 0; z < data->map_size; z++) { - MinimapPixel *mmpixel = &data->minimap_scan[x + z * data->map_size]; + for (s16 x = 0; x < data->mode.map_size; x++) + for (s16 z = 0; z < data->mode.map_size; z++) { + MinimapPixel *mmpixel = &data->minimap_scan[x + z * data->mode.map_size]; if (mmpixel->air_count > 0) c.setGreen(core::clamp(core::round32(32 + mmpixel->air_count * 8), 0, 255)); else c.setGreen(0); - map_image->setPixel(x, data->map_size - z - 1, c); + map_image->setPixel(x, data->mode.map_size - z - 1, c); } } @@ -349,9 +433,9 @@ void Minimap::blitMinimapPixelsToImageSurface( { // This variable creation/destruction has a 1% cost on rendering minimap video::SColor tilecolor; - for (s16 x = 0; x < data->map_size; x++) - for (s16 z = 0; z < data->map_size; z++) { - MinimapPixel *mmpixel = &data->minimap_scan[x + z * data->map_size]; + for (s16 x = 0; x < data->mode.map_size; x++) + for (s16 z = 0; z < data->mode.map_size; z++) { + MinimapPixel *mmpixel = &data->minimap_scan[x + z * data->mode.map_size]; const ContentFeatures &f = m_ndef->get(mmpixel->n); const TileDef *tile = &f.tiledef[0]; @@ -367,10 +451,10 @@ void Minimap::blitMinimapPixelsToImageSurface( tilecolor.setBlue(tilecolor.getBlue() * f.minimap_color.getBlue() / 255); tilecolor.setAlpha(240); - map_image->setPixel(x, data->map_size - z - 1, tilecolor); + map_image->setPixel(x, data->mode.map_size - z - 1, tilecolor); u32 h = mmpixel->height; - heightmap_image->setPixel(x,data->map_size - z - 1, + heightmap_image->setPixel(x,data->mode.map_size - z - 1, video::SColor(255, h, h, h)); } } @@ -378,21 +462,46 @@ void Minimap::blitMinimapPixelsToImageSurface( video::ITexture *Minimap::getMinimapTexture() { // update minimap textures when new scan is ready - if (data->map_invalidated) + if (data->map_invalidated && data->mode.type != MINIMAP_TYPE_TEXTURE) return data->texture; // create minimap and heightmap images in memory - core::dimension2d dim(data->map_size, data->map_size); + core::dimension2d dim(data->mode.map_size, data->mode.map_size); video::IImage *map_image = driver->createImage(video::ECF_A8R8G8B8, dim); video::IImage *heightmap_image = driver->createImage(video::ECF_A8R8G8B8, dim); video::IImage *minimap_image = driver->createImage(video::ECF_A8R8G8B8, core::dimension2d(MINIMAP_MAX_SX, MINIMAP_MAX_SY)); // Blit MinimapPixels to images - if (data->is_radar) - blitMinimapPixelsToImageRadar(map_image); - else + switch(data->mode.type) { + case MINIMAP_TYPE_OFF: + break; + case MINIMAP_TYPE_SURFACE: blitMinimapPixelsToImageSurface(map_image, heightmap_image); + break; + case MINIMAP_TYPE_RADAR: + blitMinimapPixelsToImageRadar(map_image); + break; + case MINIMAP_TYPE_TEXTURE: + // Want to use texture source, to : 1 find texture, 2 cache it + video::ITexture* texture = m_tsrc->getTexture(data->mode.texture); + video::IImage* image = driver->createImageFromData( + texture->getColorFormat(), texture->getSize(), texture->lock(), true, false); + texture->unlock(); + + auto dim = image->getDimension(); + + map_image->fill(video::SColor(255, 0, 0, 0)); + + image->copyTo(map_image, + irr::core::vector2d { + ((data->mode.map_size - (static_cast(dim.Width))) >> 1) + - data->pos.X / data->mode.scale, + ((data->mode.map_size - (static_cast(dim.Height))) >> 1) + + data->pos.Z / data->mode.scale + }); + image->drop(); + } map_image->copyToScaling(minimap_image); map_image->drop(); @@ -461,21 +570,31 @@ scene::SMeshBuffer *Minimap::getMinimapMeshBuffer() void Minimap::drawMinimap() { + // Non hud managed minimap drawing (legacy minimap) + v2u32 screensize = RenderingEngine::get_instance()->getWindowSize(); + const u32 size = 0.25 * screensize.Y; + + drawMinimap(core::rect( + screensize.X - size - 10, 10, + screensize.X - 10, size + 10)); +} + +void Minimap::drawMinimap(core::rect rect) { + video::ITexture *minimap_texture = getMinimapTexture(); if (!minimap_texture) return; + if (data->mode.type == MINIMAP_TYPE_OFF) + return; + updateActiveMarkers(); - v2u32 screensize = RenderingEngine::get_instance()->getWindowSize(); - const u32 size = 0.25 * screensize.Y; core::rect oldViewPort = driver->getViewPort(); core::matrix4 oldProjMat = driver->getTransform(video::ETS_PROJECTION); core::matrix4 oldViewMat = driver->getTransform(video::ETS_VIEW); - driver->setViewPort(core::rect( - screensize.X - size - 10, 10, - screensize.X - 10, size + 10)); + driver->setViewPort(rect); driver->setTransform(video::ETS_PROJECTION, core::matrix4()); driver->setTransform(video::ETS_VIEW, core::matrix4()); @@ -488,7 +607,7 @@ void Minimap::drawMinimap() material.TextureLayer[0].Texture = minimap_texture; material.TextureLayer[1].Texture = data->heightmap_texture; - if (m_enable_shaders && !data->is_radar) { + if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) { u16 sid = m_shdrsrc->getShader("minimap_shader", 1, 1); material.MaterialType = m_shdrsrc->getShaderInfo(sid).material; } else { @@ -529,14 +648,14 @@ void Minimap::drawMinimap() driver->setViewPort(oldViewPort); // Draw player markers - v2s32 s_pos(screensize.X - size - 10, 10); + v2s32 s_pos(rect.UpperLeftCorner.X, rect.UpperLeftCorner.Y); core::dimension2di imgsize(data->object_marker_red->getOriginalSize()); core::rect img_rect(0, 0, imgsize.Width, imgsize.Height); static const video::SColor col(255, 255, 255, 255); static const video::SColor c[4] = {col, col, col, col}; f32 sin_angle = std::sin(m_angle * core::DEGTORAD); f32 cos_angle = std::cos(m_angle * core::DEGTORAD); - s32 marker_size2 = 0.025 * (float)size; + s32 marker_size2 = 0.025 * (float)rect.getWidth();; for (std::list::const_iterator i = m_active_markers.begin(); i != m_active_markers.end(); ++i) { @@ -547,8 +666,8 @@ void Minimap::drawMinimap() posf.X = t1; posf.Y = t2; } - posf.X = (posf.X + 0.5) * (float)size; - posf.Y = (posf.Y + 0.5) * (float)size; + posf.X = (posf.X + 0.5) * (float)rect.getWidth(); + posf.Y = (posf.Y + 0.5) * (float)rect.getHeight(); core::rect dest_rect( s_pos.X + posf.X - marker_size2, s_pos.Y + posf.Y - marker_size2, @@ -571,16 +690,16 @@ void Minimap::updateActiveMarkers() for (Nametag *nametag : nametags) { v3s16 pos = floatToInt(nametag->parent_node->getAbsolutePosition() + intToFloat(client->getCamera()->getOffset(), BS), BS); - pos -= data->pos - v3s16(data->map_size / 2, - data->scan_height / 2, - data->map_size / 2); - if (pos.X < 0 || pos.X > data->map_size || - pos.Y < 0 || pos.Y > data->scan_height || - pos.Z < 0 || pos.Z > data->map_size) { + pos -= data->pos - v3s16(data->mode.map_size / 2, + data->mode.scan_height / 2, + data->mode.map_size / 2); + if (pos.X < 0 || pos.X > data->mode.map_size || + pos.Y < 0 || pos.Y > data->mode.scan_height || + pos.Z < 0 || pos.Z > data->mode.map_size) { continue; } - pos.X = ((float)pos.X / data->map_size) * MINIMAP_MAX_SX; - pos.Z = ((float)pos.Z / data->map_size) * MINIMAP_MAX_SY; + pos.X = ((float)pos.X / data->mode.map_size) * MINIMAP_MAX_SX; + pos.Z = ((float)pos.Z / data->mode.map_size) * MINIMAP_MAX_SY; const video::SColor &mask_col = minimap_mask->getPixel(pos.X, pos.Z); if (!mask_col.getAlpha()) { continue; diff --git a/src/client/minimap.h b/src/client/minimap.h index 258d5330d..11374b116 100644 --- a/src/client/minimap.h +++ b/src/client/minimap.h @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once +#include "../hud.h" #include "irrlichttypes_extrabloated.h" #include "util/thread.h" #include "voxel.h" @@ -33,26 +34,18 @@ class IShaderSource; #define MINIMAP_MAX_SX 512 #define MINIMAP_MAX_SY 512 -enum MinimapMode { - MINIMAP_MODE_OFF, - MINIMAP_MODE_SURFACEx1, - MINIMAP_MODE_SURFACEx2, - MINIMAP_MODE_SURFACEx4, - MINIMAP_MODE_RADARx1, - MINIMAP_MODE_RADARx2, - MINIMAP_MODE_RADARx4, - MINIMAP_MODE_COUNT, -}; - enum MinimapShape { MINIMAP_SHAPE_SQUARE, MINIMAP_SHAPE_ROUND, }; struct MinimapModeDef { - bool is_radar; + MinimapType type; + std::string label; u16 scan_height; u16 map_size; + std::string texture; + u16 scale; }; struct MinimapPixel { @@ -69,12 +62,9 @@ struct MinimapMapblock { }; struct MinimapData { - bool is_radar; - MinimapMode mode; + MinimapModeDef mode; v3s16 pos; v3s16 old_pos; - u16 scan_height; - u16 map_size; MinimapPixel minimap_scan[MINIMAP_MAX_SX * MINIMAP_MAX_SY]; bool map_invalidated; bool minimap_shape_round; @@ -127,12 +117,22 @@ public: v3s16 getPos() const { return data->pos; } void setAngle(f32 angle); f32 getAngle() const { return m_angle; } - void setMinimapMode(MinimapMode mode); - MinimapMode getMinimapMode() const { return data->mode; } void toggleMinimapShape(); void setMinimapShape(MinimapShape shape); MinimapShape getMinimapShape(); + void clearModes() { m_modes.clear(); }; + void addMode(MinimapModeDef mode); + void addMode(MinimapType type, u16 size = 0, std::string label = "", + std::string texture = "", u16 scale = 1); + + void setModeIndex(size_t index); + size_t getModeIndex() const { return m_current_mode_index; }; + size_t getMaxModeIndex() const { return m_modes.size() - 1; }; + void nextMode(); + + void setModesFromString(std::string modes_string); + MinimapModeDef getModeDef() const { return data->mode; } video::ITexture *getMinimapTexture(); @@ -144,6 +144,7 @@ public: void updateActiveMarkers(); void drawMinimap(); + void drawMinimap(core::rect rect); video::IVideoDriver *driver; Client* client; @@ -153,9 +154,11 @@ private: ITextureSource *m_tsrc; IShaderSource *m_shdrsrc; const NodeDefManager *m_ndef; - MinimapUpdateThread *m_minimap_update_thread; + MinimapUpdateThread *m_minimap_update_thread = nullptr; scene::SMeshBuffer *m_meshbuffer; bool m_enable_shaders; + std::vector m_modes; + size_t m_current_mode_index; u16 m_surface_mode_scan_height; f32 m_angle; std::mutex m_mutex; diff --git a/src/hud.cpp b/src/hud.cpp index 175701342..1791e04df 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -29,6 +29,7 @@ const struct EnumString es_HudElementType[] = {HUD_ELEM_WAYPOINT, "waypoint"}, {HUD_ELEM_IMAGE_WAYPOINT, "image_waypoint"}, {HUD_ELEM_COMPASS, "compass"}, + {HUD_ELEM_MINIMAP, "minimap"}, {0, NULL}, }; diff --git a/src/hud.h b/src/hud.h index 0a6993c1b..a0613ae98 100644 --- a/src/hud.h +++ b/src/hud.h @@ -51,7 +51,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define HUD_HOTBAR_ITEMCOUNT_DEFAULT 8 #define HUD_HOTBAR_ITEMCOUNT_MAX 32 - #define HOTBAR_IMAGE_SIZE 48 enum HudElementType { @@ -61,7 +60,8 @@ enum HudElementType { HUD_ELEM_INVENTORY = 3, HUD_ELEM_WAYPOINT = 4, HUD_ELEM_IMAGE_WAYPOINT = 5, - HUD_ELEM_COMPASS = 6 + HUD_ELEM_COMPASS = 6, + HUD_ELEM_MINIMAP = 7 }; enum HudElementStat { @@ -108,3 +108,12 @@ extern const EnumString es_HudElementType[]; extern const EnumString es_HudElementStat[]; extern const EnumString es_HudBuiltinElement[]; +// Minimap stuff + +enum MinimapType { + MINIMAP_TYPE_OFF, + MINIMAP_TYPE_SURFACE, + MINIMAP_TYPE_RADAR, + MINIMAP_TYPE_TEXTURE, +}; + diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index f812a08a1..55cfdd4dc 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -122,6 +122,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = null_command_handler, { "TOCLIENT_SRP_BYTES_S_B", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60 { "TOCLIENT_FORMSPEC_PREPEND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61, + { "TOCLIENT_MINIMAP_MODES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MinimapModes }, // 0x62, }; const static ServerCommandFactory null_command_factory = { "TOSERVER_NULL", 0, false }; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 5683564a0..65db02300 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1164,15 +1164,24 @@ void Client::handleCommand_HudSetFlags(NetworkPacket* pkt) m_minimap_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE); bool m_minimap_radar_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE); + // Not so satisying code to keep compatibility with old fixed mode system + // --> + // Hide minimap if it has been disabled by the server if (m_minimap && m_minimap_disabled_by_server && was_minimap_visible) // defers a minimap update, therefore only call it if really // needed, by checking that minimap was visible before - m_minimap->setMinimapMode(MINIMAP_MODE_OFF); - - // Switch to surface mode if radar disabled by server - if (m_minimap && m_minimap_radar_disabled_by_server && was_minimap_radar_visible) - m_minimap->setMinimapMode(MINIMAP_MODE_SURFACEx1); + m_minimap->setModeIndex(0); + + // If radar has been disabled, try to find a non radar mode or fall back to 0 + if (m_minimap && m_minimap_radar_disabled_by_server + && was_minimap_radar_visible) { + while (m_minimap->getModeIndex() > 0 && + m_minimap->getModeDef().type == MINIMAP_TYPE_RADAR) + m_minimap->nextMode(); + } + // <-- + // End of 'not so satifying code' } void Client::handleCommand_HudSetParam(NetworkPacket* pkt) @@ -1611,3 +1620,30 @@ void Client::handleCommand_ModChannelSignal(NetworkPacket *pkt) if (valid_signal) m_script->on_modchannel_signal(channel, signal); } + +void Client::handleCommand_MinimapModes(NetworkPacket *pkt) +{ + u16 count; // modes + u16 mode; // wanted current mode index after change + + *pkt >> count >> mode; + + if (m_minimap) + m_minimap->clearModes(); + + for (size_t index = 0; index < count; index++) { + u16 type; + std::string label; + u16 size; + std::string texture; + u16 scale; + + *pkt >> type >> label >> size >> texture >> scale; + + if (m_minimap) + m_minimap->addMode(MinimapType(type), size, label, texture, scale); + } + + if (m_minimap) + m_minimap->setModeIndex(mode); +} diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 05600cda9..666e75e45 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -204,6 +204,7 @@ with this program; if not, write to the Free Software Foundation, Inc., PROTOCOL VERSION 39: Updated set_sky packet Adds new sun, moon and stars packets + Minimap modes */ #define LATEST_PROTOCOL_VERSION 39 @@ -764,7 +765,18 @@ enum ToClientCommand u8[len] formspec */ - TOCLIENT_NUM_MSG_TYPES = 0x62, + TOCLIENT_MINIMAP_MODES = 0x62, + /* + u16 count // modes + u16 mode // wanted current mode index after change + for each mode + u16 type + std::string label + u16 size + std::string extra + */ + + TOCLIENT_NUM_MSG_TYPES = 0x63, }; enum ToServerCommand diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index 2fc3197c2..aea5d7174 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -221,4 +221,5 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = null_command_factory, // 0x5f { "TOSERVER_SRP_BYTES_S_B", 0, true }, // 0x60 { "TOCLIENT_FORMSPEC_PREPEND", 0, true }, // 0x61 + { "TOCLIENT_MINIMAP_MODES", 0, true }, // 0x62 }; diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp index 5fba76eb8..3bbb6e5e3 100644 --- a/src/script/lua_api/l_minimap.cpp +++ b/src/script/lua_api/l_minimap.cpp @@ -89,7 +89,7 @@ int LuaMinimap::l_get_mode(lua_State *L) LuaMinimap *ref = checkobject(L, 1); Minimap *m = getobject(ref); - lua_pushinteger(L, m->getMinimapMode()); + lua_pushinteger(L, m->getModeIndex()); return 1; } @@ -98,13 +98,11 @@ int LuaMinimap::l_set_mode(lua_State *L) LuaMinimap *ref = checkobject(L, 1); Minimap *m = getobject(ref); - s32 mode = lua_tointeger(L, 2); - if (mode < MINIMAP_MODE_OFF || - mode >= MINIMAP_MODE_COUNT) { + u32 mode = lua_tointeger(L, 2); + if (mode >= m->getMaxModeIndex()) return 0; - } - m->setMinimapMode((MinimapMode) mode); + m->setModeIndex(mode); return 1; } @@ -140,8 +138,11 @@ int LuaMinimap::l_show(lua_State *L) LuaMinimap *ref = checkobject(L, 1); Minimap *m = getobject(ref); - if (m->getMinimapMode() == MINIMAP_MODE_OFF) - m->setMinimapMode(MINIMAP_MODE_SURFACEx1); + // This is not very adapted to new minimap mode management. Btw, tried + // to do something compatible. + + if (m->getModeIndex() == 0 && m->getMaxModeIndex() > 0) + m->setModeIndex(1); client->showMinimap(true); return 1; @@ -155,8 +156,11 @@ int LuaMinimap::l_hide(lua_State *L) LuaMinimap *ref = checkobject(L, 1); Minimap *m = getobject(ref); - if (m->getMinimapMode() != MINIMAP_MODE_OFF) - m->setMinimapMode(MINIMAP_MODE_OFF); + // This is not very adapted to new minimap mode management. Btw, tried + // to do something compatible. + + if (m->getModeIndex() != 0) + m->setModeIndex(0); client->showMinimap(false); return 1; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index fead4e849..57ed7e2cd 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2199,6 +2199,67 @@ int ObjectRef::l_get_day_night_ratio(lua_State *L) return 1; } +// set_minimap_modes(self, modes, modeindex) +int ObjectRef::l_set_minimap_modes(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + // Arg 1 should be a player + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (player == NULL) + return 0; + + // Arg 2 should be a table (of tables) + if (!lua_istable(L, 2)) { + return 0; + } + + // Arg 3 should be a number + s16 wantedmode = lua_tonumber(L, 3); + + std::vector modes; + + lua_pushnil(L); + while (lua_next(L, 2) != 0) { + /* key is at index -2, value is at index -1 */ + if (lua_istable(L, -1)) { + bool ok = true; + MinimapMode mode; + std::string type = getstringfield_default(L, -1, "type", ""); + if (type == "off") + mode.type = MINIMAP_TYPE_OFF; + else if (type == "surface") + mode.type = MINIMAP_TYPE_SURFACE; + else if (type == "radar") + mode.type = MINIMAP_TYPE_RADAR; + else if (type == "texture") { + mode.type = MINIMAP_TYPE_TEXTURE; + mode.texture = getstringfield_default(L, -1, "texture", ""); + mode.scale = getintfield_default(L, -1, "scale", 1); + } else { + warningstream << "Minimap mode of unknown type \"" << type.c_str() + << "\" ignored.\n" << std::endl; + ok = false; + } + + if (ok) { + mode.label = getstringfield_default(L, -1, "label", ""); + // Size is limited to 512. Performance gets poor if size too large, and + // segfaults have been experienced. + mode.size = rangelim(getintfield_default(L, -1, "size", 0), 1, 512); + modes.push_back(mode); + } + } + /* removes 'value'; keeps 'key' for next iteration */ + lua_pop(L, 1); + } + lua_pop(L, 1); // Remove key + + getServer(L)->SendMinimapModes(player->getPeerId(), modes, wantedmode); + return 0; +} + ObjectRef::ObjectRef(ServerActiveObject *object): m_object(object) { @@ -2359,5 +2420,6 @@ luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, set_eye_offset), luamethod(ObjectRef, get_eye_offset), luamethod(ObjectRef, send_mapblock), + luamethod(ObjectRef, set_minimap_modes), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 126719b1f..ca03dfa2e 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -377,4 +377,7 @@ private: // send_mapblock(pos) static int l_send_mapblock(lua_State *L); + + // set_minimap_modes(self, modes, wanted_mode) + static int l_set_minimap_modes(lua_State *L); }; diff --git a/src/server.cpp b/src/server.cpp index 982f904f4..8f6257afe 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2662,6 +2662,23 @@ void Server::sendRequestedMedia(session_t peer_id, } } +void Server::SendMinimapModes(session_t peer_id, + std::vector &modes, size_t wanted_mode) +{ + RemotePlayer *player = m_env->getPlayer(peer_id); + assert(player); + if (player->getPeerId() == PEER_ID_INEXISTENT) + return; + + NetworkPacket pkt(TOCLIENT_MINIMAP_MODES, 0, peer_id); + pkt << (u16)modes.size() << (u16)wanted_mode; + + for (auto &mode : modes) + pkt << (u16)mode.type << mode.label << mode.size << mode.texture << mode.scale; + + Send(&pkt); +} + void Server::sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id) { NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id); diff --git a/src/server.h b/src/server.h index 258d75eaf..4b3ac5cf7 100644 --- a/src/server.h +++ b/src/server.h @@ -118,6 +118,14 @@ struct ServerPlayingSound std::unordered_set clients; // peer ids }; +struct MinimapMode { + MinimapType type = MINIMAP_TYPE_OFF; + std::string label; + u16 size = 0; + std::string texture; + u16 scale = 1; +}; + class Server : public con::PeerHandler, public MapEventReceiver, public IGameDef { @@ -331,6 +339,10 @@ public: void SendPlayerSpeed(session_t peer_id, const v3f &added_vel); void SendPlayerFov(session_t peer_id); + void SendMinimapModes(session_t peer_id, + std::vector &modes, + size_t wanted_mode); + void sendDetachedInventories(session_t peer_id, bool incremental); virtual bool registerModStorage(ModMetadata *storage); -- cgit v1.2.3 From f46509d5e2c681b6da2abdeb27779be3c36a6916 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Mon, 5 Oct 2020 09:07:33 +0200 Subject: Remove unused functions reported by cppcheck (#10463) Run unused functions reported by cppcheck This change removes a few (but not all) unused functions. Some unused helper functions were not removed due to their complexity and potential of future use. --- src/chat.cpp | 13 ++---- src/chat.h | 2 - src/client/client.cpp | 5 --- src/client/client.h | 1 - src/client/clientenvironment.cpp | 15 ------- src/client/clientmap.cpp | 2 +- src/client/mapblock_mesh.cpp | 27 ------------ src/client/mapblock_mesh.h | 5 --- src/content/CMakeLists.txt | 1 - src/content/packages.cpp | 69 ------------------------------ src/content/packages.h | 52 ---------------------- src/gui/guiChatConsole.cpp | 5 --- src/gui/guiChatConsole.h | 4 -- src/log.cpp | 11 +---- src/log.h | 10 ----- src/map.cpp | 63 +-------------------------- src/map.h | 21 +-------- src/mapgen/mapgen.cpp | 33 -------------- src/mapgen/mapgen.h | 7 +-- src/mapgen/mapgen_v6.cpp | 6 --- src/mapgen/mapgen_v6.h | 1 - src/mapgen/treegen.cpp | 13 ------ src/mapgen/treegen.h | 2 - src/network/networkpacket.cpp | 7 --- src/network/networkpacket.h | 1 - src/script/common/c_converter.cpp | 45 ------------------- src/script/common/c_converter.h | 2 - src/script/lua_api/l_mainmenu.cpp | 1 - src/unittest/test_map_settings_manager.cpp | 28 +----------- 29 files changed, 13 insertions(+), 439 deletions(-) delete mode 100644 src/content/packages.cpp delete mode 100644 src/content/packages.h (limited to 'src/client') diff --git a/src/chat.cpp b/src/chat.cpp index c3ed59804..2f65e68b3 100644 --- a/src/chat.cpp +++ b/src/chat.cpp @@ -123,14 +123,14 @@ void ChatBuffer::deleteByAge(f32 maxAge) deleteOldest(count); } -u32 ChatBuffer::getColumns() const +u32 ChatBuffer::getRows() const { - return m_cols; + return m_rows; } -u32 ChatBuffer::getRows() const +void ChatBuffer::scrollTop() { - return m_rows; + m_scroll = getTopScrollPos(); } void ChatBuffer::reformat(u32 cols, u32 rows) @@ -220,11 +220,6 @@ void ChatBuffer::scrollBottom() m_scroll = getBottomScrollPos(); } -void ChatBuffer::scrollTop() -{ - m_scroll = getTopScrollPos(); -} - u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, std::vector& destination) const { diff --git a/src/chat.h b/src/chat.h index f84ece206..0b98e4d3c 100644 --- a/src/chat.h +++ b/src/chat.h @@ -94,8 +94,6 @@ public: // Delete lines older than maxAge. void deleteByAge(f32 maxAge); - // Get number of columns, 0 if reformat has not been called yet. - u32 getColumns() const; // Get number of rows, 0 if reformat has not been called yet. u32 getRows() const; // Update console size and reformat all formatted lines. diff --git a/src/client/client.cpp b/src/client/client.cpp index 7fafe0da9..0bd98b256 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1665,11 +1665,6 @@ ClientEvent *Client::getClientEvent() return event; } -bool Client::connectedToServer() -{ - return m_con->Connected(); -} - const Address Client::getServerAddress() { return m_con->GetPeerAddress(PEER_ID_SERVER); diff --git a/src/client/client.h b/src/client/client.h index 8f4aac6e3..bffdc7ec6 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -338,7 +338,6 @@ public: u16 getProtoVersion() { return m_proto_ver; } - bool connectedToServer(); void confirmRegistration(); bool m_is_registration_confirmation_state = false; bool m_simple_singleplayer_mode; diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index 0b7e92325..f831978a8 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -368,21 +368,6 @@ bool isFreeClientActiveObjectId(const u16 id, } -u16 getFreeClientActiveObjectId(ClientActiveObjectMap &objects) -{ - // try to reuse id's as late as possible - static u16 last_used_id = 0; - u16 startid = last_used_id; - for(;;) { - last_used_id ++; - if (isFreeClientActiveObjectId(last_used_id, objects)) - return last_used_id; - - if (last_used_id == startid) - return 0; - } -} - u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) { // Register object. If failed return zero id diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index 3e4ab2e94..3124313e7 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -36,7 +36,7 @@ ClientMap::ClientMap( MapDrawControl &control, s32 id ): - Map(dout_client, client), + Map(client), scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(), RenderingEngine::get_scene_manager(), id), m_client(client), diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index b59679523..f9332e399 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -81,33 +81,6 @@ void MeshMakeData::fill(MapBlock *block) } } -void MeshMakeData::fillSingleNode(MapNode *node) -{ - m_blockpos = v3s16(0,0,0); - - v3s16 blockpos_nodes = v3s16(0,0,0); - VoxelArea area(blockpos_nodes-v3s16(1,1,1)*MAP_BLOCKSIZE, - blockpos_nodes+v3s16(1,1,1)*MAP_BLOCKSIZE*2-v3s16(1,1,1)); - s32 volume = area.getVolume(); - s32 our_node_index = area.index(1,1,1); - - // Allocate this block + neighbors - m_vmanip.clear(); - m_vmanip.addArea(area); - - // Fill in data - MapNode *data = new MapNode[volume]; - for(s32 i = 0; i < volume; i++) - { - if (i == our_node_index) - data[i] = *node; - else - data[i] = MapNode(CONTENT_AIR, LIGHT_MAX, 0); - } - m_vmanip.copyFrom(data, area, area.MinEdge, area.MinEdge, area.getExtent()); - delete[] data; -} - void MeshMakeData::setCrack(int crack_level, v3s16 crack_pos) { if (crack_level >= 0) diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index 6af23a656..f8aed40dc 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -62,11 +62,6 @@ struct MeshMakeData */ void fill(MapBlock *block); - /* - Set up with only a single node at (1,1,1) - */ - void fillSingleNode(MapNode *node); - /* Set the (node) position of a crack */ diff --git a/src/content/CMakeLists.txt b/src/content/CMakeLists.txt index 5adcf6b1e..6dd049418 100644 --- a/src/content/CMakeLists.txt +++ b/src/content/CMakeLists.txt @@ -1,6 +1,5 @@ set(content_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/content.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/packages.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mods.cpp ${CMAKE_CURRENT_SOURCE_DIR}/subgames.cpp PARENT_SCOPE diff --git a/src/content/packages.cpp b/src/content/packages.cpp deleted file mode 100644 index 2d488eb76..000000000 --- a/src/content/packages.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* -Minetest -Copyright (C) 2018 rubenwardy - -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 "content/packages.h" -#include "log.h" -#include "filesys.h" -#include "porting.h" -#include "settings.h" -#include "content/mods.h" -#include "content/subgames.h" - -std::string Package::getDownloadURL(const std::string &baseURL) const -{ - return baseURL + "/packages/" + author + "/" + name + "/releases/" + - std::to_string(release) + "/download/"; -} - -#if USE_CURL -std::vector getPackagesFromURL(const std::string &url) -{ - std::vector extra_headers; - extra_headers.emplace_back("Accept: application/json"); - - Json::Value json = fetchJsonValue(url, &extra_headers); - if (!json.isArray()) { - errorstream << "Invalid JSON download " << std::endl; - return std::vector(); - } - - std::vector packages; - - // Note: `unsigned int` is required to index JSON - for (unsigned int i = 0; i < json.size(); ++i) { - Package package; - - package.author = json[i]["author"].asString(); - package.name = json[i]["name"].asString(); - package.title = json[i]["title"].asString(); - package.type = json[i]["type"].asString(); - package.shortDesc = json[i]["shortDesc"].asString(); - package.release = json[i]["release"].asInt(); - if (json[i].isMember("thumbnail")) - package.thumbnail = json[i]["thumbnail"].asString(); - - if (package.valid()) - packages.push_back(package); - else - errorstream << "Invalid package at " << i << std::endl; - } - - return packages; -} -#endif diff --git a/src/content/packages.h b/src/content/packages.h deleted file mode 100644 index 9029475ef..000000000 --- a/src/content/packages.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -Minetest -Copyright (C) 2018 rubenwardy - -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 "config.h" -#include "convert_json.h" -#include "irrlichttypes.h" - -struct Package -{ - std::string author; - std::string name; // Technical name - std::string title; - std::string type; // One of "mod", "game", or "txp" - - std::string shortDesc; - u32 release; - std::string thumbnail; - - bool valid() const - { - return !(author.empty() || name.empty() || title.empty() || - type.empty() || release <= 0); - } - - std::string getDownloadURL(const std::string &baseURL) const; -}; - -#if USE_CURL -std::vector getPackagesFromURL(const std::string &url); -#else -inline std::vector getPackagesFromURL(const std::string &url) -{ - return std::vector(); -} -#endif diff --git a/src/gui/guiChatConsole.cpp b/src/gui/guiChatConsole.cpp index 575c6ab25..ef471106d 100644 --- a/src/gui/guiChatConsole.cpp +++ b/src/gui/guiChatConsole.cpp @@ -136,11 +136,6 @@ void GUIChatConsole::closeConsoleAtOnce() recalculateConsolePosition(); } -f32 GUIChatConsole::getDesiredHeight() const -{ - return m_desired_height_fraction; -} - void GUIChatConsole::replaceAndAddToHistory(const std::wstring &line) { ChatPrompt& prompt = m_chat_backend->getPrompt(); diff --git a/src/gui/guiChatConsole.h b/src/gui/guiChatConsole.h index 7be40e27c..204f9f9cc 100644 --- a/src/gui/guiChatConsole.h +++ b/src/gui/guiChatConsole.h @@ -55,10 +55,6 @@ public: // Set whether to close the console after the user presses enter. void setCloseOnEnter(bool close) { m_close_on_enter = close; } - // Return the desired height (fraction of screen size) - // Zero if the console is closed or getting closed - f32 getDesiredHeight() const; - // Replace actual line when adding the actual to the history (if there is any) void replaceAndAddToHistory(const std::wstring &line); diff --git a/src/log.cpp b/src/log.cpp index 54442c39b..3c61414e9 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -97,16 +97,7 @@ LogBuffer verbose_buf(g_logger, LL_VERBOSE); std::ostream *dout_con_ptr = &null_stream; std::ostream *derr_con_ptr = &verbosestream; -// Server -std::ostream *dout_server_ptr = &infostream; -std::ostream *derr_server_ptr = &errorstream; - -#ifndef SERVER -// Client -std::ostream *dout_client_ptr = &infostream; -std::ostream *derr_client_ptr = &errorstream; -#endif - +// Common streams std::ostream rawstream(&raw_buf); std::ostream dstream(&none_buf); std::ostream errorstream(&error_buf); diff --git a/src/log.h b/src/log.h index 856d3479b..6ed6b1fb7 100644 --- a/src/log.h +++ b/src/log.h @@ -192,14 +192,8 @@ extern std::ostream null_stream; extern std::ostream *dout_con_ptr; extern std::ostream *derr_con_ptr; -extern std::ostream *dout_server_ptr; extern std::ostream *derr_server_ptr; -#ifndef SERVER -extern std::ostream *dout_client_ptr; -extern std::ostream *derr_client_ptr; -#endif - extern Logger g_logger; // Writes directly to all LL_NONE log outputs for g_logger with no prefix. @@ -222,8 +216,4 @@ extern std::ostream dstream; #define dout_con (*dout_con_ptr) #define derr_con (*derr_con_ptr) -#define dout_server (*dout_server_ptr) -#ifndef SERVER - #define dout_client (*dout_client_ptr) -#endif diff --git a/src/map.cpp b/src/map.cpp index b9ab7c066..ef7eddb39 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -62,8 +62,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Map */ -Map::Map(std::ostream &dout, IGameDef *gamedef): - m_dout(dout), +Map::Map(IGameDef *gamedef): m_gamedef(gamedef), m_nodedef(gamedef->ndef()) { @@ -1201,7 +1200,7 @@ bool Map::isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes) */ ServerMap::ServerMap(const std::string &savedir, IGameDef *gamedef, EmergeManager *emerge, MetricsBackend *mb): - Map(dout_server, gamedef), + Map(gamedef), settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"), m_emerge(emerge) { @@ -1327,11 +1326,6 @@ u64 ServerMap::getSeed() return getMapgenParams()->seed; } -s16 ServerMap::getWaterLevel() -{ - return getMapgenParams()->water_level; -} - bool ServerMap::blockpos_over_mapgen_limit(v3s16 p) { const s16 mapgen_limit_bp = rangelim( @@ -1732,59 +1726,6 @@ void ServerMap::updateVManip(v3s16 pos) vm->m_is_dirty = true; } -s16 ServerMap::findGroundLevel(v2s16 p2d) -{ -#if 0 - /* - Uh, just do something random... - */ - // Find existing map from top to down - s16 max=63; - s16 min=-64; - v3s16 p(p2d.X, max, p2d.Y); - for(; p.Y>min; p.Y--) - { - MapNode n = getNodeNoEx(p); - if(n.getContent() != CONTENT_IGNORE) - break; - } - if(p.Y == min) - goto plan_b; - // If this node is not air, go to plan b - if(getNodeNoEx(p).getContent() != CONTENT_AIR) - goto plan_b; - // Search existing walkable and return it - for(; p.Y>min; p.Y--) - { - MapNode n = getNodeNoEx(p); - if(content_walkable(n.d) && n.getContent() != CONTENT_IGNORE) - return p.Y; - } - - // Move to plan b -plan_b: -#endif - - /* - Determine from map generator noise functions - */ - - s16 level = m_emerge->getGroundLevelAtPoint(p2d); - return level; - - //double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT; - //return (s16)level; -} - -void ServerMap::createDirs(const std::string &path) -{ - if (!fs::CreateAllDirs(path)) { - m_dout<<"ServerMap: Failed to create directory " - <<"\""< *getSectorsPtr(){return &m_sectors;} - /* Variables */ @@ -283,8 +276,6 @@ public: protected: friend class LuaVoxelManip; - std::ostream &m_dout; // A bit deprecated, could be removed - IGameDef *m_gamedef; std::set m_event_receivers; @@ -374,15 +365,6 @@ public: */ MapBlock *getBlockOrEmerge(v3s16 p3d); - // Helper for placing objects on ground level - s16 findGroundLevel(v2s16 p2d); - - /* - Misc. helper functions for fiddling with directory and file - names when saving - */ - void createDirs(const std::string &path); - /* Database functions */ @@ -414,7 +396,6 @@ public: bool isSavingEnabled(){ return m_map_saving_enabled; } u64 getSeed(); - s16 getWaterLevel(); /*! * Fixes lighting in one map block. diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 52ef64e7e..e0dfd2d71 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -244,26 +244,6 @@ u32 Mapgen::getBlockSeed2(v3s16 p, s32 seed) } -// Returns Y one under area minimum if not found -s16 Mapgen::findGroundLevelFull(v2s16 p2d) -{ - const v3s16 &em = vm->m_area.getExtent(); - s16 y_nodes_max = vm->m_area.MaxEdge.Y; - s16 y_nodes_min = vm->m_area.MinEdge.Y; - u32 i = vm->m_area.index(p2d.X, y_nodes_max, p2d.Y); - s16 y; - - for (y = y_nodes_max; y >= y_nodes_min; y--) { - MapNode &n = vm->m_data[i]; - if (ndef->get(n).walkable) - break; - - VoxelArea::add_y(em, i, -1); - } - return (y >= y_nodes_min) ? y : y_nodes_min - 1; -} - - // Returns -MAX_MAP_GENERATION_LIMIT if not found s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) { @@ -984,19 +964,6 @@ GenerateNotifier::GenerateNotifier(u32 notify_on, } -void GenerateNotifier::setNotifyOn(u32 notify_on) -{ - m_notify_on = notify_on; -} - - -void GenerateNotifier::setNotifyOnDecoIds( - const std::set *notify_on_deco_ids) -{ - m_notify_on_deco_ids = notify_on_deco_ids; -} - - bool GenerateNotifier::addEvent(GenNotifyType type, v3s16 pos, u32 id) { if (!(m_notify_on & (1 << type))) diff --git a/src/mapgen/mapgen.h b/src/mapgen/mapgen.h index 0f2977c4c..1487731e2 100644 --- a/src/mapgen/mapgen.h +++ b/src/mapgen/mapgen.h @@ -88,19 +88,17 @@ struct GenNotifyEvent { class GenerateNotifier { public: + // Use only for temporary Mapgen objects with no map generation! GenerateNotifier() = default; GenerateNotifier(u32 notify_on, const std::set *notify_on_deco_ids); - void setNotifyOn(u32 notify_on); - void setNotifyOnDecoIds(const std::set *notify_on_deco_ids); - bool addEvent(GenNotifyType type, v3s16 pos, u32 id=0); void getEvents(std::map > &event_map); void clearEvents(); private: u32 m_notify_on = 0; - const std::set *m_notify_on_deco_ids; + const std::set *m_notify_on_deco_ids = nullptr; std::list m_notify_events; }; @@ -186,7 +184,6 @@ public: static u32 getBlockSeed(v3s16 p, s32 seed); static u32 getBlockSeed2(v3s16 p, s32 seed); - s16 findGroundLevelFull(v2s16 p2d); s16 findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax); s16 findLiquidSurface(v2s16 p2d, s16 ymin, s16 ymax); void updateHeightmap(v3s16 nmin, v3s16 nmax); diff --git a/src/mapgen/mapgen_v6.cpp b/src/mapgen/mapgen_v6.cpp index 8bea5eb69..90a52e031 100644 --- a/src/mapgen/mapgen_v6.cpp +++ b/src/mapgen/mapgen_v6.cpp @@ -341,12 +341,6 @@ float MapgenV6::baseTerrainLevelFromMap(int index) } -s16 MapgenV6::find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision) -{ - return baseTerrainLevelFromNoise(p2d) + MGV6_AVERAGE_MUD_AMOUNT; -} - - int MapgenV6::getGroundLevelAtPoint(v2s16 p) { return baseTerrainLevelFromNoise(p) + MGV6_AVERAGE_MUD_AMOUNT; diff --git a/src/mapgen/mapgen_v6.h b/src/mapgen/mapgen_v6.h index ff565edec..a6e6da8c6 100644 --- a/src/mapgen/mapgen_v6.h +++ b/src/mapgen/mapgen_v6.h @@ -150,7 +150,6 @@ public: s16 find_stone_level(v2s16 p2d); bool block_is_underground(u64 seed, v3s16 blockpos); - s16 find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision); float getHumidity(v2s16 p); float getTreeAmount(v2s16 p); diff --git a/src/mapgen/treegen.cpp b/src/mapgen/treegen.cpp index e7e30c880..e633d800a 100644 --- a/src/mapgen/treegen.cpp +++ b/src/mapgen/treegen.cpp @@ -527,19 +527,6 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, } -void tree_node_placement(MMVManip &vmanip, v3f p0, MapNode node) -{ - v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z)); - if (!vmanip.m_area.contains(p1)) - return; - u32 vi = vmanip.m_area.index(p1); - if (vmanip.m_data[vi].getContent() != CONTENT_AIR - && vmanip.m_data[vi].getContent() != CONTENT_IGNORE) - return; - vmanip.m_data[vmanip.m_area.index(p1)] = node; -} - - void tree_trunk_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition) { v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z)); diff --git a/src/mapgen/treegen.h b/src/mapgen/treegen.h index 447baabb3..59a418824 100644 --- a/src/mapgen/treegen.h +++ b/src/mapgen/treegen.h @@ -76,8 +76,6 @@ namespace treegen { const NodeDefManager *ndef, const TreeDef &tree_definition); // L-System tree gen helper functions - void tree_node_placement(MMVManip &vmanip, v3f p0, - MapNode node); void tree_trunk_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition); void tree_leaves_placement(MMVManip &vmanip, v3f p0, diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp index 4d531b611..6d0abb12c 100644 --- a/src/network/networkpacket.cpp +++ b/src/network/networkpacket.cpp @@ -223,13 +223,6 @@ NetworkPacket& NetworkPacket::operator>>(char& dst) return *this; } -char NetworkPacket::getChar(u32 offset) -{ - checkReadOffset(offset, 1); - - return readU8(&m_data[offset]); -} - NetworkPacket& NetworkPacket::operator<<(char src) { checkDataSize(1); diff --git a/src/network/networkpacket.h b/src/network/networkpacket.h index fc8617651..e77bfb744 100644 --- a/src/network/networkpacket.h +++ b/src/network/networkpacket.h @@ -64,7 +64,6 @@ public: std::string readLongString(); - char getChar(u32 offset); NetworkPacket &operator>>(char &dst); NetworkPacket &operator<<(char src); diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index eb6ab5331..c00401b58 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -679,48 +679,3 @@ size_t write_array_slice_float( return elem_index - 1; } - - -size_t write_array_slice_u16( - lua_State *L, - int table_index, - u16 *data, - v3u16 data_size, - v3u16 slice_offset, - v3u16 slice_size) -{ - v3u16 pmin, pmax(data_size); - - if (slice_offset.X > 0) { - slice_offset.X--; - pmin.X = slice_offset.X; - pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X); - } - - if (slice_offset.Y > 0) { - slice_offset.Y--; - pmin.Y = slice_offset.Y; - pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y); - } - - if (slice_offset.Z > 0) { - slice_offset.Z--; - pmin.Z = slice_offset.Z; - pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z); - } - - const u32 ystride = data_size.X; - const u32 zstride = data_size.X * data_size.Y; - - u32 elem_index = 1; - for (u32 z = pmin.Z; z != pmax.Z; z++) - for (u32 y = pmin.Y; y != pmax.Y; y++) - for (u32 x = pmin.X; x != pmax.X; x++) { - u32 i = z * zstride + y * ystride + x; - lua_pushinteger(L, data[i]); - lua_rawseti(L, table_index, elem_index); - elem_index++; - } - - return elem_index - 1; -} diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index a4a7079fd..6ad6f3212 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -136,5 +136,3 @@ void warn_if_field_exists(lua_State *L, int table, size_t write_array_slice_float(lua_State *L, int table_index, float *data, v3u16 data_size, v3u16 slice_offset, v3u16 slice_size); -size_t write_array_slice_u16(lua_State *L, int table_index, u16 *data, - v3u16 data_size, v3u16 slice_offset, v3u16 slice_size); diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index e49ec4052..0aa2760e9 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "filesys.h" #include "convert_json.h" -#include "content/packages.h" #include "content/content.h" #include "content/subgames.h" #include "serverlist.h" diff --git a/src/unittest/test_map_settings_manager.cpp b/src/unittest/test_map_settings_manager.cpp index 0a5c971b9..3d642a9b4 100644 --- a/src/unittest/test_map_settings_manager.cpp +++ b/src/unittest/test_map_settings_manager.cpp @@ -65,31 +65,6 @@ void check_noise_params(const NoiseParams *np1, const NoiseParams *np2) } -std::string read_file_to_string(const std::string &filepath) -{ - std::string buf; - FILE *f = fopen(filepath.c_str(), "rb"); - if (!f) - return ""; - - fseek(f, 0, SEEK_END); - - long filesize = ftell(f); - if (filesize == -1) { - fclose(f); - return ""; - } - rewind(f); - - buf.resize(filesize); - - UASSERTEQ(size_t, fread(&buf[0], 1, filesize, f), 1); - - fclose(f); - return buf; -} - - void TestMapSettingsManager::makeUserConfig(Settings *conf) { conf->set("mg_name", "v7"); @@ -199,7 +174,8 @@ void TestMapSettingsManager::testMapSettingsManager() }; SHA1 ctx; - std::string metafile_contents = read_file_to_string(test_mapmeta_path); + std::string metafile_contents; + UASSERT(fs::ReadFile(test_mapmeta_path, metafile_contents)); ctx.addBytes(&metafile_contents[0], metafile_contents.size()); unsigned char *sha1_result = ctx.getDigest(); int resultdiff = memcmp(sha1_result, expected_contents_hash, 20); -- cgit v1.2.3 From a37e96eefc646f01f34d0c6d8948d4a9c4062cae Mon Sep 17 00:00:00 2001 From: Zughy <63455151+Zughy@users.noreply.github.com> Date: Tue, 6 Oct 2020 20:51:27 +0200 Subject: -Wmem-access only called when GCC > 7 (#10453) --- src/client/mapblock_mesh.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/client') diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index f9332e399..c7790f1e4 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -394,7 +394,9 @@ static void getNodeVertexDirs(const v3s16 &dir, v3s16 *vertex_dirs) #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push +#if __GNUC__ > 7 #pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif #endif memcpy(vertex_dirs, &vertex_dirs_table[idx], 4 * sizeof(v3s16)); #if defined(__GNUC__) && !defined(__clang__) -- cgit v1.2.3 From 521a04222a71325ef217d1214febf5591919e169 Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 12 Oct 2020 19:47:04 -0700 Subject: Avoid drawing invisible blocks on the client. --- src/client/clientmap.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'src/client') diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index 3124313e7..d372a8e46 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -124,12 +124,6 @@ void ClientMap::updateDrawList() v3f camera_position = m_camera_position; v3f camera_direction = m_camera_direction; - f32 camera_fov = m_camera_fov; - - // Use a higher fov to accomodate faster camera movements. - // Blocks are cropped better when they are drawn. - // Or maybe they aren't? Well whatever. - camera_fov *= 1.2; v3s16 cam_pos_nodes = floatToInt(camera_position, BS); v3s16 p_blocks_min; @@ -190,7 +184,7 @@ void ClientMap::updateDrawList() float d = 0.0; if (!isBlockInSight(block->getPos(), camera_position, - camera_direction, camera_fov, range, &d)) + camera_direction, m_camera_fov, range, &d)) continue; -- cgit v1.2.3 From ed22260822086f84016aa8384c3174bfc6d1739d Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 12 Oct 2020 13:29:31 -0700 Subject: Remove all bump mapping and parallax occlusion related code. --- builtin/mainmenu/tab_settings.lua | 30 ++----- builtin/settingtypes.txt | 25 ------ client/shaders/nodes_shader/opengl_fragment.glsl | 99 ----------------------- client/shaders/nodes_shader/opengl_vertex.glsl | 45 +---------- client/shaders/object_shader/opengl_fragment.glsl | 54 ------------- client/shaders/object_shader/opengl_vertex.glsl | 5 -- doc/lua_api.txt | 40 +-------- src/client/game.cpp | 10 +-- src/client/mapblock_mesh.cpp | 41 ++-------- src/client/mapblock_mesh.h | 5 +- src/client/mesh_generator_thread.cpp | 6 +- src/client/mesh_generator_thread.h | 1 - src/client/shader.cpp | 29 ------- src/client/wieldmesh.cpp | 2 +- src/defaultsettings.cpp | 6 -- src/nodedef.cpp | 9 --- src/nodedef.h | 1 - 17 files changed, 24 insertions(+), 384 deletions(-) (limited to 'src/client') diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index 510346f8d..8a7445394 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -187,31 +187,23 @@ local function formspec(tabview, name, tabdata) if shaders_enabled then tab_string = tab_string .. - "checkbox[8.25,0.5;cb_bumpmapping;" .. fgettext("Bump Mapping") .. ";" - .. dump(core.settings:get_bool("enable_bumpmapping")) .. "]" .. - "checkbox[8.25,1;cb_tonemapping;" .. fgettext("Tone Mapping") .. ";" + "checkbox[8.25,0.5;cb_tonemapping;" .. fgettext("Tone Mapping") .. ";" .. dump(core.settings:get_bool("tone_mapping")) .. "]" .. - "checkbox[8.25,1.5;cb_parallax;" .. fgettext("Parallax Occlusion") .. ";" - .. dump(core.settings:get_bool("enable_parallax_occlusion")) .. "]" .. - "checkbox[8.25,2;cb_waving_water;" .. fgettext("Waving Liquids") .. ";" + "checkbox[8.25,1;cb_waving_water;" .. fgettext("Waving Liquids") .. ";" .. dump(core.settings:get_bool("enable_waving_water")) .. "]" .. - "checkbox[8.25,2.5;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";" + "checkbox[8.25,1.5;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";" .. dump(core.settings:get_bool("enable_waving_leaves")) .. "]" .. - "checkbox[8.25,3;cb_waving_plants;" .. fgettext("Waving Plants") .. ";" + "checkbox[8.25,2;cb_waving_plants;" .. fgettext("Waving Plants") .. ";" .. dump(core.settings:get_bool("enable_waving_plants")) .. "]" else tab_string = tab_string .. "label[8.38,0.7;" .. core.colorize("#888888", - fgettext("Bump Mapping")) .. "]" .. - "label[8.38,1.2;" .. core.colorize("#888888", fgettext("Tone Mapping")) .. "]" .. - "label[8.38,1.7;" .. core.colorize("#888888", - fgettext("Parallax Occlusion")) .. "]" .. - "label[8.38,2.2;" .. core.colorize("#888888", + "label[8.38,1.2;" .. core.colorize("#888888", fgettext("Waving Liquids")) .. "]" .. - "label[8.38,2.7;" .. core.colorize("#888888", + "label[8.38,1.7;" .. core.colorize("#888888", fgettext("Waving Leaves")) .. "]" .. - "label[8.38,3.2;" .. core.colorize("#888888", + "label[8.38,2.2;" .. core.colorize("#888888", fgettext("Waving Plants")) .. "]" end @@ -263,18 +255,10 @@ local function handle_settings_buttons(this, fields, tabname, tabdata) end return true end - if fields["cb_bumpmapping"] then - core.settings:set("enable_bumpmapping", fields["cb_bumpmapping"]) - return true - end if fields["cb_tonemapping"] then core.settings:set("tone_mapping", fields["cb_tonemapping"]) return true end - if fields["cb_parallax"] then - core.settings:set("enable_parallax_occlusion", fields["cb_parallax"]) - return true - end if fields["cb_waving_water"] then core.settings:set("enable_waving_water", fields["cb_waving_water"]) return true diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 1c28470d5..27f375693 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -546,31 +546,6 @@ shader_path (Shader path) path # enhanced, highlights and shadows are gradually compressed. tone_mapping (Filmic tone mapping) bool false -[***Bumpmapping] - -# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack. -# Requires shaders to be enabled. -enable_bumpmapping (Bumpmapping) bool false - -[***Parallax Occlusion] - -# Enables parallax occlusion mapping. -# Requires shaders to be enabled. -enable_parallax_occlusion (Parallax occlusion) bool false - -# 0 = parallax occlusion with slope information (faster). -# 1 = relief mapping (slower, more accurate). -parallax_occlusion_mode (Parallax occlusion mode) int 1 0 1 - -# Number of parallax occlusion iterations. -parallax_occlusion_iterations (Parallax occlusion iterations) int 4 - -# Overall scale of parallax occlusion effect. -parallax_occlusion_scale (Parallax occlusion scale) float 0.08 - -# Overall bias of parallax occlusion effect, usually scale/2. -parallax_occlusion_bias (Parallax occlusion bias) float 0.04 - [***Waving Nodes] # Set to true to enable waving liquids (like water). diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 437b325d3..36d47d1f5 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -1,6 +1,4 @@ uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D textureFlags; uniform vec4 skyBgColor; uniform float fogDistance; @@ -17,17 +15,9 @@ varying vec3 vPosition; // cameraOffset + worldPosition (for large coordinates the limits of float // precision must be considered). varying vec3 worldPosition; -varying float area_enable_parallax; varying vec3 eyeVec; -varying vec3 tsEyeVec; -varying vec3 lightVec; -varying vec3 tsLightVec; -bool normalTexturePresent = false; - -const float e = 2.718281828459; -const float BS = 10.0; const float fogStart = FOG_START; const float fogShadingParameter = 1 / ( 1 - fogStart); @@ -63,87 +53,10 @@ vec4 applyToneMapping(vec4 color) } #endif -void get_texture_flags() -{ - vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); - if (flags.r > 0.5) { - normalTexturePresent = true; - } -} - -vec4 get_normal_map(vec2 uv) -{ - vec4 bump = texture2D(normalTexture, uv).rgba; - bump.xyz = normalize(bump.xyz * 2.0 - 1.0); - return bump; -} - -float find_intersection(vec2 dp, vec2 ds) -{ - float depth = 1.0; - float best_depth = 0.0; - float size = 0.0625; - for (int i = 0; i < 15; i++) { - depth -= size; - float h = texture2D(normalTexture, dp + ds * depth).a; - if (depth <= h) { - best_depth = depth; - break; - } - } - depth = best_depth; - for (int i = 0; i < 4; i++) { - size *= 0.5; - float h = texture2D(normalTexture,dp + ds * depth).a; - if (depth <= h) { - best_depth = depth; - depth += size; - } else { - depth -= size; - } - } - return best_depth; -} - void main(void) { vec3 color; - vec4 bump; vec2 uv = gl_TexCoord[0].st; - bool use_normalmap = false; - get_texture_flags(); - -#ifdef ENABLE_PARALLAX_OCCLUSION - vec2 eyeRay = vec2 (tsEyeVec.x, -tsEyeVec.y); - const float scale = PARALLAX_OCCLUSION_SCALE / PARALLAX_OCCLUSION_ITERATIONS; - const float bias = PARALLAX_OCCLUSION_BIAS / PARALLAX_OCCLUSION_ITERATIONS; - -#if PARALLAX_OCCLUSION_MODE == 0 - // Parallax occlusion with slope information - if (normalTexturePresent && area_enable_parallax > 0.0) { - for (int i = 0; i < PARALLAX_OCCLUSION_ITERATIONS; i++) { - vec4 normal = texture2D(normalTexture, uv.xy); - float h = normal.a * scale - bias; - uv += h * normal.z * eyeRay; - } - } -#endif -#if PARALLAX_OCCLUSION_MODE == 1 - // Relief mapping - if (normalTexturePresent && area_enable_parallax > 0.0) { - vec2 ds = eyeRay * PARALLAX_OCCLUSION_SCALE; - float dist = find_intersection(uv, ds); - uv += dist * ds; - } -#endif -#endif - -#if USE_NORMALMAPS == 1 - if (normalTexturePresent) { - bump = get_normal_map(uv); - use_normalmap = true; - } -#endif vec4 base = texture2D(baseTexture, uv).rgba; @@ -155,19 +68,7 @@ void main(void) } #endif -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap) { - vec3 L = normalize(lightVec); - vec3 E = normalize(eyeVec); - float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0); - float diffuse = dot(-E,bump.xyz); - color = (diffuse + 0.1 * specular) * base.rgb; - } else { - color = base.rgb; - } -#else color = base.rgb; -#endif vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0); diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl index 0d8d0a2a5..56bff09a8 100644 --- a/client/shaders/nodes_shader/opengl_vertex.glsl +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -18,10 +18,6 @@ varying vec3 vPosition; varying vec3 worldPosition; varying vec3 eyeVec; -varying vec3 lightVec; -varying vec3 tsEyeVec; -varying vec3 tsLightVec; -varying float area_enable_parallax; // Color of the light emitted by the light sources. const vec3 artificialLight = vec3(1.04, 1.04, 1.04); @@ -86,21 +82,9 @@ float snoise(vec3 p) void main(void) { gl_TexCoord[0] = gl_MultiTexCoord0; - //TODO: make offset depending on view angle and parallax uv displacement - //thats for textures that doesnt align vertically, like dirt with grass - //gl_TexCoord[0].y += 0.008; - - //Allow parallax/relief mapping only for certain kind of nodes - //Variable is also used to control area of the effect -#if (DRAW_TYPE == NDT_NORMAL || DRAW_TYPE == NDT_LIQUID || DRAW_TYPE == NDT_FLOWINGLIQUID) - area_enable_parallax = 1.0; -#else - area_enable_parallax = 0.0; -#endif - -float disp_x; -float disp_z; + float disp_x; + float disp_z; // OpenGL < 4.3 does not support continued preprocessor lines #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS) vec4 pos2 = mWorld * gl_Vertex; @@ -148,32 +132,7 @@ float disp_z; vPosition = gl_Position.xyz; - // Don't generate heightmaps when too far from the eye - float dist = distance (vec3(0.0, 0.0, 0.0), vPosition); - if (dist > 150.0) { - area_enable_parallax = 0.0; - } - - vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); - - vec3 normal, tangent, binormal; - normal = normalize(gl_NormalMatrix * gl_Normal); - tangent = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz); - binormal = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); - - vec3 v; - - lightVec = sunPosition - worldPosition; - v.x = dot(lightVec, tangent); - v.y = dot(lightVec, binormal); - v.z = dot(lightVec, normal); - tsLightVec = normalize (v); - eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; - v.x = dot(eyeVec, tangent); - v.y = dot(eyeVec, binormal); - v.z = dot(eyeVec, normal); - tsEyeVec = normalize (v); // Calculate color. // Red, green and blue components are pre-multiplied with diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index a8a43e1e2..86d5c1c92 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -1,6 +1,4 @@ uniform sampler2D baseTexture; -uniform sampler2D normalTexture; -uniform sampler2D textureFlags; uniform vec4 emissiveColor; uniform vec4 skyBgColor; @@ -12,14 +10,8 @@ varying vec3 vPosition; varying vec3 worldPosition; varying vec3 eyeVec; -varying vec3 lightVec; varying float vIDiff; -bool normalTexturePresent = false; -bool texTileableHorizontal = false; -bool texTileableVertical = false; -bool texSeamless = false; - const float e = 2.718281828459; const float BS = 10.0; const float fogStart = FOG_START; @@ -57,44 +49,10 @@ vec4 applyToneMapping(vec4 color) } #endif -void get_texture_flags() -{ - vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0)); - if (flags.r > 0.5) { - normalTexturePresent = true; - } - if (flags.g > 0.5) { - texTileableHorizontal = true; - } - if (flags.b > 0.5) { - texTileableVertical = true; - } - if (texTileableHorizontal && texTileableVertical) { - texSeamless = true; - } -} - -vec4 get_normal_map(vec2 uv) -{ - vec4 bump = texture2D(normalTexture, uv).rgba; - bump.xyz = normalize(bump.xyz * 2.0 - 1.0); - return bump; -} - void main(void) { vec3 color; - vec4 bump; vec2 uv = gl_TexCoord[0].st; - bool use_normalmap = false; - get_texture_flags(); - -#if USE_NORMALMAPS == 1 - if (normalTexturePresent) { - bump = get_normal_map(uv); - use_normalmap = true; - } -#endif vec4 base = texture2D(baseTexture, uv).rgba; @@ -106,19 +64,7 @@ void main(void) } #endif -#ifdef ENABLE_BUMPMAPPING - if (use_normalmap) { - vec3 L = normalize(lightVec); - vec3 E = normalize(eyeVec); - float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0), 1.0); - float diffuse = dot(-E,bump.xyz); - color = (diffuse + 0.1 * specular) * base.rgb; - } else { - color = base.rgb; - } -#else color = base.rgb; -#endif vec4 col = vec4(color.rgb, base.a); diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl index 968a07e22..f8c1cd932 100644 --- a/client/shaders/object_shader/opengl_vertex.glsl +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -9,7 +9,6 @@ varying vec3 vPosition; varying vec3 worldPosition; varying vec3 eyeVec; -varying vec3 lightVec; varying float vIDiff; const float e = 2.718281828459; @@ -33,10 +32,6 @@ void main(void) vPosition = gl_Position.xyz; vNormal = gl_Normal; worldPosition = (mWorld * gl_Vertex).xyz; - - vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0); - - lightVec = sunPosition - worldPosition; eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; #if (MATERIAL_TYPE == TILE_MATERIAL_PLAIN) || (MATERIAL_TYPE == TILE_MATERIAL_PLAIN_ALPHA) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 1631d564c..d3aaa309c 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -401,35 +401,6 @@ stripping out the file extension: * e.g. `foomod_foothing` -Normalmap Textures ------------------- - -If shaders and bumpmapping or parallax occlusion is enabled, Minetest tries -to load normalmaps. -Those image files have to end with `_normal.png` and start with the same name -as their corresponding texture. -For example a normalmap for `foomod_foothing.png` has to be called -`foomod_foothing_normal.png`. - -The sRGB R, G and B colour values of a normalmap pixel are each directly -mapped from `{0, ..., 255}` to `[-1, 1]` and, taken together, -define the normal vector. -The alpha channel defines the heightmap for parallax occlusion. -To be safe, the alpha values should always be bigger than zero -because the colour values, which define the normal vector, -may be undefined for image formats where colour is discarded in fully -transparent pixels. - -Bumpmapping and parallax occlusion are currently experimental features: - -* Bumpmapping in Minetest happens in an obscure way; there are no light sources - defined in the shaders except the sunlight direction. -* Parallax occlusion with relief-mapping mode does not yet work correctly - together with Minetest's Fastfaces. -* The normalmap files must end with `.png`, so other image files are not - supported. - - Texture modifiers ----------------- @@ -834,7 +805,7 @@ Example (colored grass block): -- Overlay tiles: define them in the same style -- The top and bottom tile does not have overlay overlay_tiles = {"", "", - {name = "default_grass_side.png", tileable_vertical = false}}, + {name = "default_grass_side.png"}}, -- Global color, used in inventory color = "green", -- Palette in the world @@ -1204,7 +1175,7 @@ Look for examples in `games/devtest` or `games/minetest_game`. base cube without affecting them. * The base cube texture tiles are defined as normal, the `plantlike` extension uses the defined special tile, for example: - `special_tiles = {{name = "default_papyrus.png", tileable_vertical = true}},` + `special_tiles = {{name = "default_papyrus.png"}},` `*_optional` drawtypes need less rendering time if deactivated (always client-side). @@ -7043,13 +7014,8 @@ Tile definition * `"image.png"` * `{name="image.png", animation={Tile Animation definition}}` -* `{name="image.png", backface_culling=bool, tileable_vertical=bool, - tileable_horizontal=bool, align_style="node"/"world"/"user", scale=int}` +* `{name="image.png", backface_culling=bool, align_style="node"/"world"/"user", scale=int}` * backface culling enabled by default for most nodes - * tileable flags are info for shaders, how they should treat texture - when displacement mapping is used. - Directions are from the point of view of the tile texture, - not the node it's on. * align style determines whether the texture will be rotated with the node or kept aligned with its surroundings. "user" means that client setting will be used, similar to `glasslike_framed_optional`. diff --git a/src/client/game.cpp b/src/client/game.cpp index 54e0c9f20..309a8e194 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -430,8 +430,6 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_camera_offset_pixel; CachedPixelShaderSetting m_camera_offset_vertex; CachedPixelShaderSetting m_base_texture; - CachedPixelShaderSetting m_normal_texture; - CachedPixelShaderSetting m_texture_flags; Client *m_client; public: @@ -464,8 +462,6 @@ public: m_camera_offset_pixel("cameraOffset"), m_camera_offset_vertex("cameraOffset"), m_base_texture("baseTexture"), - m_normal_texture("normalTexture"), - m_texture_flags("textureFlags"), m_client(client) { g_settings->registerChangedCallback("enable_fog", settingsCallback, this); @@ -553,12 +549,8 @@ public: m_camera_offset_pixel.set(camera_offset_array, services); m_camera_offset_vertex.set(camera_offset_array, services); - SamplerLayer_t base_tex = 0, - normal_tex = 1, - flags_tex = 2; + SamplerLayer_t base_tex = 0; m_base_texture.set(&base_tex, services); - m_normal_texture.set(&normal_tex, services); - m_texture_flags.set(&flags_tex, services); } }; diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index c7790f1e4..6a59fabe3 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -35,11 +35,9 @@ with this program; if not, write to the Free Software Foundation, Inc., MeshMakeData */ -MeshMakeData::MeshMakeData(Client *client, bool use_shaders, - bool use_tangent_vertices): +MeshMakeData::MeshMakeData(Client *client, bool use_shaders): m_client(client), - m_use_shaders(use_shaders), - m_use_tangent_vertices(use_tangent_vertices) + m_use_shaders(use_shaders) {} void MeshMakeData::fillBlockDataBegin(const v3s16 &blockpos) @@ -1016,7 +1014,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): for (auto &m : m_mesh) m = new scene::SMesh(); m_enable_shaders = data->m_use_shaders; - m_use_tangent_vertices = data->m_use_tangent_vertices; m_enable_vbo = g_settings->getBool("enable_vbo"); if (data->m_client->getMinimap()) { @@ -1170,28 +1167,12 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): scene::SMesh *mesh = (scene::SMesh *)m_mesh[layer]; - // Create meshbuffer, add to mesh - if (m_use_tangent_vertices) { - scene::SMeshBufferTangents *buf = - new scene::SMeshBufferTangents(); - buf->Material = material; - buf->Vertices.reallocate(p.vertices.size()); - buf->Indices.reallocate(p.indices.size()); - for (const video::S3DVertex &v: p.vertices) - buf->Vertices.push_back(video::S3DVertexTangents(v.Pos, v.Color, v.TCoords)); - for (u16 i: p.indices) - buf->Indices.push_back(i); - buf->recalculateBoundingBox(); - mesh->addMeshBuffer(buf); - buf->drop(); - } else { - scene::SMeshBuffer *buf = new scene::SMeshBuffer(); - buf->Material = material; - buf->append(&p.vertices[0], p.vertices.size(), - &p.indices[0], p.indices.size()); - mesh->addMeshBuffer(buf); - buf->drop(); - } + scene::SMeshBuffer *buf = new scene::SMeshBuffer(); + buf->Material = material; + buf->append(&p.vertices[0], p.vertices.size(), + &p.indices[0], p.indices.size()); + mesh->addMeshBuffer(buf); + buf->drop(); } /* @@ -1201,12 +1182,6 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): translateMesh(m_mesh[layer], intToFloat(data->m_blockpos * MAP_BLOCKSIZE - camera_offset, BS)); - if (m_use_tangent_vertices) { - scene::IMeshManipulator* meshmanip = - RenderingEngine::get_scene_manager()->getMeshManipulator(); - meshmanip->recalculateTangents(m_mesh[layer], true, false, false); - } - if (m_mesh[layer]) { #if 0 // Usually 1-700 faces and 1-7 materials diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index f8aed40dc..6a9c00ed5 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -45,10 +45,8 @@ struct MeshMakeData Client *m_client; bool m_use_shaders; - bool m_use_tangent_vertices; - MeshMakeData(Client *client, bool use_shaders, - bool use_tangent_vertices = false); + MeshMakeData(Client *client, bool use_shaders); /* Copy block data manually (to allow optimizations by the caller) @@ -136,7 +134,6 @@ private: IShaderSource *m_shdrsrc; bool m_enable_shaders; - bool m_use_tangent_vertices; bool m_enable_vbo; // Must animate() be called before rendering? diff --git a/src/client/mesh_generator_thread.cpp b/src/client/mesh_generator_thread.cpp index 53b980eeb..c8d1cba26 100644 --- a/src/client/mesh_generator_thread.cpp +++ b/src/client/mesh_generator_thread.cpp @@ -52,9 +52,6 @@ MeshUpdateQueue::MeshUpdateQueue(Client *client): m_client(client) { m_cache_enable_shaders = g_settings->getBool("enable_shaders"); - m_cache_use_tangent_vertices = m_cache_enable_shaders && ( - g_settings->getBool("enable_bumpmapping") || - g_settings->getBool("enable_parallax_occlusion")); m_cache_smooth_lighting = g_settings->getBool("smooth_lighting"); m_meshgen_block_cache_size = g_settings->getS32("meshgen_block_cache_size"); } @@ -207,8 +204,7 @@ CachedMapBlockData* MeshUpdateQueue::getCachedBlock(const v3s16 &p) void MeshUpdateQueue::fillDataFromMapBlockCache(QueuedMeshUpdate *q) { - MeshMakeData *data = new MeshMakeData(m_client, m_cache_enable_shaders, - m_cache_use_tangent_vertices); + MeshMakeData *data = new MeshMakeData(m_client, m_cache_enable_shaders); q->data = data; data->fillBlockDataBegin(q->p); diff --git a/src/client/mesh_generator_thread.h b/src/client/mesh_generator_thread.h index 9a42852a3..f3c5e7da8 100644 --- a/src/client/mesh_generator_thread.h +++ b/src/client/mesh_generator_thread.h @@ -88,7 +88,6 @@ private: // TODO: Add callback to update these when g_settings changes bool m_cache_enable_shaders; - bool m_cache_use_tangent_vertices; bool m_cache_smooth_lighting; int m_meshgen_block_cache_size; diff --git a/src/client/shader.cpp b/src/client/shader.cpp index c5fe5dfe0..e2eeb4ab0 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -688,35 +688,6 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += itos(drawtype); shaders_header += "\n"; - if (g_settings->getBool("enable_bumpmapping")) - shaders_header += "#define ENABLE_BUMPMAPPING\n"; - - if (g_settings->getBool("enable_parallax_occlusion")){ - int mode = g_settings->getFloat("parallax_occlusion_mode"); - float scale = g_settings->getFloat("parallax_occlusion_scale"); - float bias = g_settings->getFloat("parallax_occlusion_bias"); - int iterations = g_settings->getFloat("parallax_occlusion_iterations"); - shaders_header += "#define ENABLE_PARALLAX_OCCLUSION\n"; - shaders_header += "#define PARALLAX_OCCLUSION_MODE "; - shaders_header += itos(mode); - shaders_header += "\n"; - shaders_header += "#define PARALLAX_OCCLUSION_SCALE "; - shaders_header += ftos(scale); - shaders_header += "\n"; - shaders_header += "#define PARALLAX_OCCLUSION_BIAS "; - shaders_header += ftos(bias); - shaders_header += "\n"; - shaders_header += "#define PARALLAX_OCCLUSION_ITERATIONS "; - shaders_header += itos(iterations); - shaders_header += "\n"; - } - - shaders_header += "#define USE_NORMALMAPS "; - if (g_settings->getBool("enable_bumpmapping") || g_settings->getBool("enable_parallax_occlusion")) - shaders_header += "1\n"; - else - shaders_header += "0\n"; - if (g_settings->getBool("enable_waving_water")){ shaders_header += "#define ENABLE_WAVING_WATER 1\n"; shaders_header += "#define WATER_WAVE_HEIGHT "; diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 285cc38e5..ad583210a 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -305,7 +305,7 @@ void WieldMeshSceneNode::setExtruded(const std::string &imagename, scene::SMesh *createSpecialNodeMesh(Client *client, content_t id, std::vector *colors, const ContentFeatures &f) { - MeshMakeData mesh_make_data(client, false, false); + MeshMakeData mesh_make_data(client, false); MeshCollector collector; mesh_make_data.setSmoothLighting(false); MapblockMeshGenerator gen(&mesh_make_data, &collector); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 8f5ed3e17..6c7d4be97 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -251,12 +251,6 @@ void set_default_settings(Settings *settings) settings->setDefault("bilinear_filter", "false"); settings->setDefault("trilinear_filter", "false"); settings->setDefault("tone_mapping", "false"); - settings->setDefault("enable_bumpmapping", "false"); - settings->setDefault("enable_parallax_occlusion", "false"); - settings->setDefault("parallax_occlusion_mode", "1"); - settings->setDefault("parallax_occlusion_iterations", "4"); - settings->setDefault("parallax_occlusion_scale", "0.08"); - settings->setDefault("parallax_occlusion_bias", "0.04"); settings->setDefault("enable_waving_water", "false"); settings->setDefault("water_wave_height", "1.0"); settings->setDefault("water_wave_length", "20.0"); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 3a5934cf3..5c2e5cd09 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -266,9 +266,6 @@ void TextureSettings::readSettings() { connected_glass = g_settings->getBool("connected_glass"); opaque_water = g_settings->getBool("opaque_water"); - bool enable_shaders = g_settings->getBool("enable_shaders"); - bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping"); - bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion"); bool smooth_lighting = g_settings->getBool("smooth_lighting"); enable_mesh_cache = g_settings->getBool("enable_mesh_cache"); enable_minimap = g_settings->getBool("enable_minimap"); @@ -281,8 +278,6 @@ void TextureSettings::readSettings() if (smooth_lighting) enable_mesh_cache = false; - use_normal_texture = enable_shaders && - (enable_bumpmapping || enable_parallax_occlusion); if (leaves_style_str == "fancy") { leaves_style = LEAVES_FANCY; } else if (leaves_style_str == "simple") { @@ -635,10 +630,6 @@ static void fillTileAttribs(ITextureSource *tsrc, TileLayer *layer, if (!tile.world_aligned) layer->scale = 1; - // Normal texture and shader flags texture - if (tsettings.use_normal_texture) { - layer->normal_texture = tsrc->getNormalTexture(tiledef.name); - } layer->flags_texture = tsrc->getShaderFlagsTexture(layer->normal_texture ? true : false); // Material flags diff --git a/src/nodedef.h b/src/nodedef.h index 71c56bda9..66c21cc07 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -158,7 +158,6 @@ public: int node_texture_size; bool opaque_water; bool connected_glass; - bool use_normal_texture; bool enable_mesh_cache; bool enable_minimap; -- cgit v1.2.3 From 738f62421872c0be5fcd483ad4573e5d879e7418 Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 15 Oct 2020 00:06:37 -0700 Subject: Periodically release all mesh HW buffers to avoid an Irrlicht bottleneck. --- src/client/game.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/game.cpp b/src/client/game.cpp index 309a8e194..a7e367ae2 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -909,6 +909,7 @@ private: bool m_does_lost_focus_pause_game = false; + int m_reset_HW_buffer_counter = 0; #ifdef __ANDROID__ bool m_cache_hold_aux1; bool m_android_chat_open; @@ -3686,7 +3687,6 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, camera->setDigging(0); // Dig animation } - void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, const CameraOrientation &cam) { @@ -3937,6 +3937,27 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime, /* End scene */ + if (++m_reset_HW_buffer_counter > 500) { + /* + Periodically remove all mesh HW buffers. + + Work around for a quirk in Irrlicht where a HW buffer is only + released after 20000 iterations (triggered from endScene()). + + Without this, all loaded but unused meshes will retain their HW + buffers for at least 5 minutes, at which point looking up the HW buffers + becomes a bottleneck and the framerate drops (as much as 30%). + + Tests showed that numbers between 50 and 1000 are good, so picked 500. + There are no other public Irrlicht APIs that allow interacting with the + HW buffers without tracking the status of every individual mesh. + + The HW buffers for _visible_ meshes will be reinitialized in the next frame. + */ + infostream << "Game::updateFrame(): Removing all HW buffers." << std::endl; + driver->removeAllHardwareBuffers(); + m_reset_HW_buffer_counter = 0; + } driver->endScene(); stats->drawtime = tt_draw.stop(true); -- cgit v1.2.3 From b826e3973065a0bb81269c8decb5a33073508164 Mon Sep 17 00:00:00 2001 From: Lars Date: Sun, 18 Oct 2020 16:38:51 -0700 Subject: Minor clientmap improvements. - Avoid calculating isBlockInSight for blocks without meshes. - Add metric for how many blocks the client has currently loaded. - Make some variables constant. --- src/client/clientmap.cpp | 36 +++++++++++++++++++----------------- src/mapsector.h | 1 + 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src/client') diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index d372a8e46..c8561def6 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -122,14 +122,17 @@ void ClientMap::updateDrawList() } m_drawlist.clear(); - v3f camera_position = m_camera_position; - v3f camera_direction = m_camera_direction; + const v3f camera_position = m_camera_position; + const v3f camera_direction = m_camera_direction; + const f32 camera_fov = m_camera_fov; v3s16 cam_pos_nodes = floatToInt(camera_position, BS); v3s16 p_blocks_min; v3s16 p_blocks_max; getBlocksInViewRange(cam_pos_nodes, &p_blocks_min, &p_blocks_max); + // Number of blocks currently loaded by the client + u32 blocks_loaded = 0; // Number of blocks with mesh in rendering range u32 blocks_in_range_with_mesh = 0; // Number of blocks occlusion culled @@ -154,6 +157,7 @@ void ClientMap::updateDrawList() MapSector *sector = sector_it.second; v2s16 sp = sector->getPos(); + blocks_loaded += sector->size(); if (!m_control.range_all) { if (sp.X < p_blocks_min.X || sp.X > p_blocks_max.X || sp.Y < p_blocks_min.Z || sp.Y > p_blocks_max.Z) @@ -175,8 +179,12 @@ void ClientMap::updateDrawList() if not seen on display */ - if (block->mesh) + if (block->mesh) { block->mesh->updateCameraOffset(m_camera_offset); + } else { + // Ignore if mesh doesn't exist + continue; + } float range = 100000 * BS; if (!m_control.range_all) @@ -184,14 +192,7 @@ void ClientMap::updateDrawList() float d = 0.0; if (!isBlockInSight(block->getPos(), camera_position, - camera_direction, m_camera_fov, range, &d)) - continue; - - - /* - Ignore if mesh doesn't exist - */ - if (!block->mesh) + camera_direction, camera_fov, range, &d)) continue; blocks_in_range_with_mesh++; @@ -222,6 +223,7 @@ void ClientMap::updateDrawList() g_profiler->avg("MapBlock meshes in range [#]", blocks_in_range_with_mesh); g_profiler->avg("MapBlocks occlusion culled [#]", blocks_occlusion_culled); g_profiler->avg("MapBlocks drawn [#]", m_drawlist.size()); + g_profiler->avg("MapBlocks loaded [#]", blocks_loaded); } struct MeshBufList @@ -287,13 +289,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) /* Get animation parameters */ - float animation_time = m_client->getAnimationTime(); - int crack = m_client->getCrackLevel(); - u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); + const float animation_time = m_client->getAnimationTime(); + const int crack = m_client->getCrackLevel(); + const u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); - v3f camera_position = m_camera_position; - v3f camera_direction = m_camera_direction; - f32 camera_fov = m_camera_fov; + const v3f camera_position = m_camera_position; + const v3f camera_direction = m_camera_direction; + const f32 camera_fov = m_camera_fov; /* Get all blocks and draw all visible ones diff --git a/src/mapsector.h b/src/mapsector.h index dede364f6..ffd4cdd1d 100644 --- a/src/mapsector.h +++ b/src/mapsector.h @@ -62,6 +62,7 @@ public: bool empty() const { return m_blocks.empty(); } + int size() const { return m_blocks.size(); } protected: // The pile of MapBlocks -- cgit v1.2.3 From 660115c1abc76f3d4f6a6597ed0c4737465c6c55 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 19 Oct 2020 20:38:15 +0200 Subject: Decouple entity minimap markers from nametags replacing with show_on_minimap property (#10443) --- doc/lua_api.txt | 4 ++++ src/client/camera.h | 2 -- src/client/client.cpp | 2 ++ src/client/content_cao.cpp | 27 +++++++++++++++++++++++++++ src/client/content_cao.h | 4 ++++ src/client/minimap.cpp | 35 ++++++++++++++++++++++++++--------- src/client/minimap.h | 11 +++++++++++ src/object_properties.cpp | 8 +++++++- src/object_properties.h | 1 + src/script/common/c_content.cpp | 3 +++ src/server/player_sao.cpp | 1 + 11 files changed, 86 insertions(+), 12 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index d3aaa309c..9a46c7b57 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6880,6 +6880,10 @@ Player properties need to be saved manually. shaded = true, -- Setting this to 'false' disables diffuse lighting of entity + + show_on_minimap = false, + -- Defaults to true for players, false for other entities. + -- If set to true the entity will show as a marker on the minimap. } Entity definition diff --git a/src/client/camera.h b/src/client/camera.h index 3a59637bc..16a1961be 100644 --- a/src/client/camera.h +++ b/src/client/camera.h @@ -169,8 +169,6 @@ public: void removeNametag(Nametag *nametag); - const std::list &getNametags() { return m_nametags; } - void drawNametags(); inline void addArmInertia(f32 player_yaw); diff --git a/src/client/client.cpp b/src/client/client.cpp index 0bd98b256..af69d0ec9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -326,6 +326,8 @@ Client::~Client() } delete m_minimap; + m_minimap = nullptr; + delete m_media_downloader; } diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index fae06554a..42184b08f 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -47,6 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "client/shader.h" +#include "client/minimap.h" class Settings; struct ToolCapabilities; @@ -566,6 +567,9 @@ void GenericCAO::removeFromScene(bool permanent) m_client->getCamera()->removeNametag(m_nametag); m_nametag = nullptr; } + + if (m_marker && m_client->getMinimap()) + m_client->getMinimap()->removeMarker(&m_marker); } void GenericCAO::addToScene(ITextureSource *tsrc) @@ -794,6 +798,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc) node->setParent(m_matrixnode); updateNametag(); + updateMarker(); updateNodePos(); updateAnimation(); updateBonePosition(); @@ -885,6 +890,23 @@ u16 GenericCAO::getLightPosition(v3s16 *pos) return 3; } +void GenericCAO::updateMarker() +{ + if (!m_prop.show_on_minimap) { + if (m_marker) + m_client->getMinimap()->removeMarker(&m_marker); + return; + } + + if (m_marker) + return; + + scene::ISceneNode *node = getSceneNode(); + if (!node) + return; + m_marker = m_client->getMinimap()->addMarker(node); +} + void GenericCAO::updateNametag() { if (m_is_local_player) // No nametag for local player @@ -1576,6 +1598,8 @@ void GenericCAO::processMessage(const std::string &data) u8 cmd = readU8(is); if (cmd == AO_CMD_SET_PROPERTIES) { ObjectProperties newprops; + newprops.show_on_minimap = m_is_player; // default + newprops.deSerialize(is); // Check what exactly changed @@ -1609,6 +1633,8 @@ void GenericCAO::processMessage(const std::string &data) if ((m_is_player && !m_is_local_player) && m_prop.nametag.empty()) m_prop.nametag = m_name; + if (m_is_local_player) + m_prop.show_on_minimap = false; if (expire_visuals) { expireVisuals(); @@ -1621,6 +1647,7 @@ void GenericCAO::processMessage(const std::string &data) updateTextures(m_current_texture_modifier); } updateNametag(); + updateMarker(); } } else if (cmd == AO_CMD_UPDATE_POSITION) { // Not sent by the server if this object is an attachment. diff --git a/src/client/content_cao.h b/src/client/content_cao.h index daf697767..435fc2931 100644 --- a/src/client/content_cao.h +++ b/src/client/content_cao.h @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., class Camera; class Client; struct Nametag; +struct MinimapMarker; /* SmoothTranslator @@ -84,6 +85,7 @@ private: scene::IBillboardSceneNode *m_spritenode = nullptr; scene::IDummyTransformationSceneNode *m_matrixnode = nullptr; Nametag *m_nametag = nullptr; + MinimapMarker *m_marker = nullptr; v3f m_position = v3f(0.0f, 10.0f * BS, 0); v3f m_velocity; v3f m_acceleration; @@ -254,6 +256,8 @@ public: void updateNametag(); + void updateMarker(); + void updateNodePos(); void step(float dtime, ClientEnvironment *env); diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index 6bae408b4..d068ad5f7 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -252,6 +252,10 @@ Minimap::~Minimap() driver->removeTexture(data->minimap_overlay_square); driver->removeTexture(data->object_marker_red); + for (MinimapMarker *m : m_markers) + delete m; + m_markers.clear(); + delete data; delete m_minimap_update_thread; } @@ -678,21 +682,34 @@ void Minimap::drawMinimap(core::rect rect) { } } +MinimapMarker* Minimap::addMarker(scene::ISceneNode *parent_node) +{ + MinimapMarker *m = new MinimapMarker(parent_node); + m_markers.push_back(m); + return m; +} + +void Minimap::removeMarker(MinimapMarker **m) +{ + m_markers.remove(*m); + delete *m; + *m = nullptr; +} + void Minimap::updateActiveMarkers() { video::IImage *minimap_mask = data->minimap_shape_round ? data->minimap_mask_round : data->minimap_mask_square; - const std::list &nametags = client->getCamera()->getNametags(); - m_active_markers.clear(); - - for (Nametag *nametag : nametags) { - v3s16 pos = floatToInt(nametag->parent_node->getAbsolutePosition() + - intToFloat(client->getCamera()->getOffset(), BS), BS); - pos -= data->pos - v3s16(data->mode.map_size / 2, - data->mode.scan_height / 2, - data->mode.map_size / 2); + v3f cam_offset = intToFloat(client->getCamera()->getOffset(), BS); + v3s16 pos_offset = data->pos - v3s16(data->mode.map_size / 2, + data->mode.scan_height / 2, + data->mode.map_size / 2); + + for (MinimapMarker *marker : m_markers) { + v3s16 pos = floatToInt(marker->parent_node->getAbsolutePosition() + + cam_offset, BS) - pos_offset; if (pos.X < 0 || pos.X > data->mode.map_size || pos.Y < 0 || pos.Y > data->mode.scan_height || pos.Z < 0 || pos.Z > data->mode.map_size) { diff --git a/src/client/minimap.h b/src/client/minimap.h index 11374b116..4a2c462f8 100644 --- a/src/client/minimap.h +++ b/src/client/minimap.h @@ -48,6 +48,13 @@ struct MinimapModeDef { u16 scale; }; +struct MinimapMarker { + MinimapMarker(scene::ISceneNode *parent_node): + parent_node(parent_node) + { + } + scene::ISceneNode *parent_node; +}; struct MinimapPixel { //! The topmost node that the minimap displays. MapNode n; @@ -142,6 +149,9 @@ public: scene::SMeshBuffer *getMinimapMeshBuffer(); + MinimapMarker* addMarker(scene::ISceneNode *parent_node); + void removeMarker(MinimapMarker **marker); + void updateActiveMarkers(); void drawMinimap(); void drawMinimap(core::rect rect); @@ -162,5 +172,6 @@ private: u16 m_surface_mode_scan_height; f32 m_angle; std::mutex m_mutex; + std::list m_markers; std::list m_active_markers; }; diff --git a/src/object_properties.cpp b/src/object_properties.cpp index c31c667e7..f31773060 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -70,6 +70,7 @@ std::string ObjectProperties::dump() os << ", use_texture_alpha=" << use_texture_alpha; os << ", damage_texture_modifier=" << damage_texture_modifier; os << ", shaded=" << shaded; + os << ", show_on_minimap=" << show_on_minimap; return os.str(); } @@ -118,6 +119,7 @@ void ObjectProperties::serialize(std::ostream &os) const writeU8(os, use_texture_alpha); os << serializeString16(damage_texture_modifier); writeU8(os, shaded); + writeU8(os, show_on_minimap); // Add stuff only at the bottom. // Never remove anything, because we don't want new versions of this @@ -174,7 +176,11 @@ void ObjectProperties::deSerialize(std::istream &is) damage_texture_modifier = deSerializeString16(is); u8 tmp = readU8(is); if (is.eof()) - throw SerializationError(""); + return; shaded = tmp; + tmp = readU8(is); + if (is.eof()) + return; + show_on_minimap = tmp; } catch (SerializationError &e) {} } diff --git a/src/object_properties.h b/src/object_properties.h index f010c1daf..adb483527 100644 --- a/src/object_properties.h +++ b/src/object_properties.h @@ -62,6 +62,7 @@ struct ObjectProperties float zoom_fov = 0.0f; bool use_texture_alpha = false; bool shaded = true; + bool show_on_minimap = false; ObjectProperties(); std::string dump(); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index a95cf94a1..e3cb9042e 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -331,6 +331,7 @@ void read_object_properties(lua_State *L, int index, getfloatfield(L, -1, "zoom_fov", prop->zoom_fov); getboolfield(L, -1, "use_texture_alpha", prop->use_texture_alpha); getboolfield(L, -1, "shaded", prop->shaded); + getboolfield(L, -1, "show_on_minimap", prop->show_on_minimap); getstringfield(L, -1, "damage_texture_modifier", prop->damage_texture_modifier); } @@ -419,6 +420,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop) lua_setfield(L, -2, "shaded"); lua_pushlstring(L, prop->damage_texture_modifier.c_str(), prop->damage_texture_modifier.size()); lua_setfield(L, -2, "damage_texture_modifier"); + lua_pushboolean(L, prop->show_on_minimap); + lua_setfield(L, -2, "show_on_minimap"); } /******************************************************************************/ diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 344d18a20..9fb53380c 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -55,6 +55,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t p m_prop.backface_culling = false; m_prop.makes_footstep_sound = true; m_prop.stepheight = PLAYER_DEFAULT_STEPHEIGHT * BS; + m_prop.show_on_minimap = true; m_hp = m_prop.hp_max; m_breath = m_prop.breath_max; // Disable zoom in survival mode using a value of 0 -- cgit v1.2.3 From c7aa92aaed27ad8e10af7463b154b5b580c86da5 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 20 Oct 2020 16:34:14 +0200 Subject: Fix show_on_minimap default value for local player fixes #10526 --- src/client/content_cao.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 42184b08f..29a3acf25 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -354,6 +354,8 @@ void GenericCAO::initialize(const std::string &data) m_is_local_player = true; m_is_visible = false; player->setCAO(this); + + m_prop.show_on_minimap = false; } } -- cgit v1.2.3 From 5c0a57f6068000b0414cf2a3ef76a8bf4852b379 Mon Sep 17 00:00:00 2001 From: Maksim Date: Wed, 21 Oct 2020 21:42:40 +0200 Subject: Fix Media... 0% on loading screen (#9478) --- src/client/game.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/game.cpp b/src/client/game.cpp index a7e367ae2..0380c1661 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1641,7 +1641,10 @@ bool Game::getServerContent(bool *aborted) std::stringstream message; std::fixed(message); message.precision(0); - message << gettext("Media...") << " " << (client->mediaReceiveProgress()*100) << "%"; + float receive = client->mediaReceiveProgress() * 100; + message << gettext("Media..."); + if (receive > 0) + message << " " << receive << "%"; message.precision(2); if ((USE_CURL == 0) || -- cgit v1.2.3 From 707c8c1e95d8db2d84909e7957b4dc9138e05599 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Sun, 25 Oct 2020 20:01:03 +0300 Subject: Shaders for Android (GLES 2) (#10506) Shader support for OpenGL ES 2 devices (Android) Co-authored-by: sfan5 --- build/android/app/build.gradle | 5 +- builtin/mainmenu/tab_settings.lua | 11 +- builtin/settingtypes.txt | 4 +- .../3d_interlaced_merge/opengl_fragment.glsl | 4 +- .../shaders/3d_interlaced_merge/opengl_vertex.glsl | 7 +- client/shaders/default_shader/opengl_fragment.glsl | 4 +- client/shaders/default_shader/opengl_vertex.glsl | 8 +- client/shaders/minimap_shader/opengl_fragment.glsl | 7 +- client/shaders/minimap_shader/opengl_vertex.glsl | 10 +- client/shaders/nodes_shader/opengl_fragment.glsl | 13 +- client/shaders/nodes_shader/opengl_vertex.glsl | 42 ++--- client/shaders/object_shader/opengl_fragment.glsl | 11 +- client/shaders/object_shader/opengl_vertex.glsl | 25 +-- .../shaders/selection_shader/opengl_fragment.glsl | 7 +- client/shaders/selection_shader/opengl_vertex.glsl | 9 +- games/devtest/mods/basenodes/init.lua | 4 + src/client/shader.cpp | 182 +++++++++++++++------ 17 files changed, 233 insertions(+), 120 deletions(-) (limited to 'src/client') diff --git a/build/android/app/build.gradle b/build/android/app/build.gradle index 812726030..fccb7b3b4 100644 --- a/build/android/app/build.gradle +++ b/build/android/app/build.gradle @@ -64,10 +64,9 @@ task prepareAssets() { copy { from "${projRoot}/builtin" into "${assetsFolder}/builtin" } - /*copy { - // ToDo: fix Minetest shaders that currently don't work with OpenGL ES + copy { from "${projRoot}/client/shaders" into "${assetsFolder}/client/shaders" - }*/ + } copy { from "../native/deps/Android/Irrlicht/shaders" into "${assetsFolder}/client/shaders/Irrlicht" } diff --git a/builtin/mainmenu/tab_settings.lua b/builtin/mainmenu/tab_settings.lua index 8a7445394..29744048a 100644 --- a/builtin/mainmenu/tab_settings.lua +++ b/builtin/mainmenu/tab_settings.lua @@ -154,15 +154,18 @@ local function formspec(tabview, name, tabdata) "box[8,0;3.75,4.5;#999999]" local video_driver = core.settings:get("video_driver") - local shaders_supported = video_driver == "opengl" - local shaders_enabled = false - if shaders_supported then - shaders_enabled = core.settings:get_bool("enable_shaders") + local shaders_enabled = core.settings:get_bool("enable_shaders") + if video_driver == "opengl" then tab_string = tab_string .. "checkbox[8.25,0;cb_shaders;" .. fgettext("Shaders") .. ";" .. tostring(shaders_enabled) .. "]" + elseif video_driver == "ogles2" then + tab_string = tab_string .. + "checkbox[8.25,0;cb_shaders;" .. fgettext("Shaders (experimental)") .. ";" + .. tostring(shaders_enabled) .. "]" else core.settings:set_bool("enable_shaders", false) + shaders_enabled = false tab_string = tab_string .. "label[8.38,0.2;" .. core.colorize("#888888", fgettext("Shaders (unavailable)")) .. "]" diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 27f375693..36446f808 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -658,8 +658,8 @@ texture_path (Texture path) path # The rendering back-end for Irrlicht. # A restart is required after changing this. # Note: On Android, stick with OGLES1 if unsure! App may fail to start otherwise. -# On other platforms, OpenGL is recommended, and it’s the only driver with -# shader support currently. +# On other platforms, OpenGL is recommended. +# Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental) video_driver (Video driver) enum opengl null,software,burningsvideo,direct3d8,direct3d9,opengl,ogles1,ogles2 # Radius of cloud area stated in number of 64 node cloud squares. diff --git a/client/shaders/3d_interlaced_merge/opengl_fragment.glsl b/client/shaders/3d_interlaced_merge/opengl_fragment.glsl index 25945ad7f..7cba61b39 100644 --- a/client/shaders/3d_interlaced_merge/opengl_fragment.glsl +++ b/client/shaders/3d_interlaced_merge/opengl_fragment.glsl @@ -6,9 +6,11 @@ uniform sampler2D textureFlags; #define rightImage normalTexture #define maskImage textureFlags +varying mediump vec2 varTexCoord; + void main(void) { - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; vec4 left = texture2D(leftImage, uv).rgba; vec4 right = texture2D(rightImage, uv).rgba; vec4 mask = texture2D(maskImage, uv).rgba; diff --git a/client/shaders/3d_interlaced_merge/opengl_vertex.glsl b/client/shaders/3d_interlaced_merge/opengl_vertex.glsl index 4e0b2b125..860049481 100644 --- a/client/shaders/3d_interlaced_merge/opengl_vertex.glsl +++ b/client/shaders/3d_interlaced_merge/opengl_vertex.glsl @@ -1,6 +1,7 @@ +varying mediump vec2 varTexCoord; + void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = gl_Vertex; - gl_FrontColor = gl_BackColor = gl_Color; + varTexCoord = inTexCoord0; + gl_Position = inVertexPosition; } diff --git a/client/shaders/default_shader/opengl_fragment.glsl b/client/shaders/default_shader/opengl_fragment.glsl index 925ab6e1d..5018ac6ea 100644 --- a/client/shaders/default_shader/opengl_fragment.glsl +++ b/client/shaders/default_shader/opengl_fragment.glsl @@ -1,4 +1,6 @@ +varying lowp vec4 varColor; + void main(void) { - gl_FragColor = gl_Color; + gl_FragColor = varColor; } diff --git a/client/shaders/default_shader/opengl_vertex.glsl b/client/shaders/default_shader/opengl_vertex.glsl index d0b16c8b0..d95a3c2d3 100644 --- a/client/shaders/default_shader/opengl_vertex.glsl +++ b/client/shaders/default_shader/opengl_vertex.glsl @@ -1,9 +1,7 @@ -uniform mat4 mWorldViewProj; +varying lowp vec4 varColor; void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; - - gl_FrontColor = gl_BackColor = gl_Color; + gl_Position = mWorldViewProj * inVertexPosition; + varColor = inVertexColor; } diff --git a/client/shaders/minimap_shader/opengl_fragment.glsl b/client/shaders/minimap_shader/opengl_fragment.glsl index fa4f9cb1a..cef359e8a 100644 --- a/client/shaders/minimap_shader/opengl_fragment.glsl +++ b/client/shaders/minimap_shader/opengl_fragment.glsl @@ -2,9 +2,12 @@ uniform sampler2D baseTexture; uniform sampler2D normalTexture; uniform vec3 yawVec; +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + void main (void) { - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; //texture sampling rate const float step = 1.0 / 256.0; @@ -27,6 +30,6 @@ void main (void) vec3 color = (1.1 * diffuse + 0.05 * height + 0.5 * specular) * base.rgb; vec4 col = vec4(color.rgb, base.a); - col *= gl_Color; + col *= varColor; gl_FragColor = vec4(col.rgb, base.a); } diff --git a/client/shaders/minimap_shader/opengl_vertex.glsl b/client/shaders/minimap_shader/opengl_vertex.glsl index 88f9356d5..1a9491805 100644 --- a/client/shaders/minimap_shader/opengl_vertex.glsl +++ b/client/shaders/minimap_shader/opengl_vertex.glsl @@ -1,9 +1,11 @@ -uniform mat4 mWorldViewProj; uniform mat4 mWorld; +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; - gl_FrontColor = gl_BackColor = gl_Color; + varTexCoord = inTexCoord0.st; + gl_Position = mWorldViewProj * inVertexPosition; + varColor = inVertexColor; } diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 36d47d1f5..82c87073a 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -15,11 +15,12 @@ varying vec3 vPosition; // cameraOffset + worldPosition (for large coordinates the limits of float // precision must be considered). varying vec3 worldPosition; - +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; varying vec3 eyeVec; const float fogStart = FOG_START; -const float fogShadingParameter = 1 / ( 1 - fogStart); +const float fogShadingParameter = 1.0 / ( 1.0 - fogStart); #ifdef ENABLE_TONE_MAPPING @@ -56,13 +57,13 @@ vec4 applyToneMapping(vec4 color) void main(void) { vec3 color; - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; vec4 base = texture2D(baseTexture, uv).rgba; - #ifdef USE_DISCARD // If alpha is zero, we can just discard the pixel. This fixes transparency - // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa. + // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa, + // and also on GLES 2, where GL_ALPHA_TEST is missing entirely. if (base.a == 0.0) { discard; } @@ -70,7 +71,7 @@ void main(void) color = base.rgb; - vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0); + vec4 col = vec4(color.rgb * varColor.rgb, 1.0); #ifdef ENABLE_TONE_MAPPING col = applyToneMapping(col); diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl index 56bff09a8..cb344f6e6 100644 --- a/client/shaders/nodes_shader/opengl_vertex.glsl +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -1,4 +1,3 @@ -uniform mat4 mWorldViewProj; uniform mat4 mWorld; // Color of the light emitted by the sun. @@ -16,7 +15,8 @@ varying vec3 vPosition; // cameraOffset + worldPosition (for large coordinates the limits of float // precision must be considered). varying vec3 worldPosition; - +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; varying vec3 eyeVec; // Color of the light emitted by the light sources. @@ -81,13 +81,13 @@ float snoise(vec3 p) void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; + varTexCoord = inTexCoord0.st; float disp_x; float disp_z; // OpenGL < 4.3 does not support continued preprocessor lines #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES) || (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS) - vec4 pos2 = mWorld * gl_Vertex; + vec4 pos2 = mWorld * inVertexPosition; float tOffset = (pos2.x + pos2.y) * 0.001 + pos2.z * 0.002; disp_x = (smoothTriangleWave(animationTimer * 23.0 + tOffset) + smoothTriangleWave(animationTimer * 11.0 + tOffset)) * 0.4; @@ -96,43 +96,43 @@ void main(void) smoothTriangleWave(animationTimer * 13.0 + tOffset)) * 0.5; #endif - worldPosition = (mWorld * gl_Vertex).xyz; + worldPosition = (mWorld * inVertexPosition).xyz; // OpenGL < 4.3 does not support continued preprocessor lines #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC) && ENABLE_WAVING_WATER // Generate waves with Perlin-type noise. // The constants are calibrated such that they roughly // correspond to the old sine waves. - vec4 pos = gl_Vertex; + vec4 pos = inVertexPosition; vec3 wavePos = worldPosition + cameraOffset; // The waves are slightly compressed along the z-axis to get // wave-fronts along the x-axis. - wavePos.x /= WATER_WAVE_LENGTH * 3; - wavePos.z /= WATER_WAVE_LENGTH * 2; - wavePos.z += animationTimer * WATER_WAVE_SPEED * 10; - pos.y += (snoise(wavePos) - 1) * WATER_WAVE_HEIGHT * 5; + wavePos.x /= WATER_WAVE_LENGTH * 3.0; + wavePos.z /= WATER_WAVE_LENGTH * 2.0; + wavePos.z += animationTimer * WATER_WAVE_SPEED * 10.0; + pos.y += (snoise(wavePos) - 1.0) * WATER_WAVE_HEIGHT * 5.0; gl_Position = mWorldViewProj * pos; #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES - vec4 pos = gl_Vertex; + vec4 pos = inVertexPosition; pos.x += disp_x; pos.y += disp_z * 0.1; pos.z += disp_z; gl_Position = mWorldViewProj * pos; #elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS - vec4 pos = gl_Vertex; - if (gl_TexCoord[0].y < 0.05) { + vec4 pos = inVertexPosition; + if (varTexCoord.y < 0.05) { pos.x += disp_x; pos.z += disp_z; } gl_Position = mWorldViewProj * pos; #else - gl_Position = mWorldViewProj * gl_Vertex; + gl_Position = mWorldViewProj * inVertexPosition; #endif vPosition = gl_Position.xyz; - eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; + eyeVec = -(mWorldView * inVertexPosition).xyz; // Calculate color. // Red, green and blue components are pre-multiplied with @@ -141,16 +141,16 @@ void main(void) // The pre-baked colors are halved to prevent overflow. vec4 color; // The alpha gives the ratio of sunlight in the incoming light. - float nightRatio = 1 - gl_Color.a; - color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb + - nightRatio * artificialLight.rgb) * 2; - color.a = 1; + float nightRatio = 1.0 - inVertexColor.a; + color.rgb = inVertexColor.rgb * (inVertexColor.a * dayLight.rgb + + nightRatio * artificialLight.rgb) * 2.0; + color.a = 1.0; // Emphase blue a bit in darker places // See C++ implementation in mapblock_mesh.cpp final_color_blend() - float brightness = (color.r + color.g + color.b) / 3; + float brightness = (color.r + color.g + color.b) / 3.0; color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) + 0.07 * brightness); - gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0); + varColor = clamp(color, 0.0, 1.0); } diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index 86d5c1c92..7ac182a63 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -8,6 +8,8 @@ uniform vec3 eyePosition; varying vec3 vNormal; varying vec3 vPosition; varying vec3 worldPosition; +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; varying vec3 eyeVec; varying float vIDiff; @@ -15,7 +17,7 @@ varying float vIDiff; const float e = 2.718281828459; const float BS = 10.0; const float fogStart = FOG_START; -const float fogShadingParameter = 1 / ( 1 - fogStart); +const float fogShadingParameter = 1.0 / (1.0 - fogStart); #ifdef ENABLE_TONE_MAPPING @@ -52,13 +54,14 @@ vec4 applyToneMapping(vec4 color) void main(void) { vec3 color; - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; vec4 base = texture2D(baseTexture, uv).rgba; #ifdef USE_DISCARD // If alpha is zero, we can just discard the pixel. This fixes transparency - // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa. + // on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa, + // and also on GLES 2, where GL_ALPHA_TEST is missing entirely. if (base.a == 0.0) { discard; } @@ -68,7 +71,7 @@ void main(void) vec4 col = vec4(color.rgb, base.a); - col.rgb *= gl_Color.rgb; + col.rgb *= varColor.rgb; col.rgb *= emissiveColor.rgb * vIDiff; diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl index f8c1cd932..e44984dc8 100644 --- a/client/shaders/object_shader/opengl_vertex.glsl +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -1,4 +1,3 @@ -uniform mat4 mWorldViewProj; uniform mat4 mWorld; uniform vec3 eyePosition; @@ -7,6 +6,8 @@ uniform float animationTimer; varying vec3 vNormal; varying vec3 vPosition; varying vec3 worldPosition; +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; varying vec3 eyeVec; varying float vIDiff; @@ -18,31 +19,31 @@ float directional_ambient(vec3 normal) { vec3 v = normal * normal; - if (normal.y < 0) - return dot(v, vec3(0.670820f, 0.447213f, 0.836660f)); + if (normal.y < 0.0) + return dot(v, vec3(0.670820, 0.447213, 0.836660)); - return dot(v, vec3(0.670820f, 1.000000f, 0.836660f)); + return dot(v, vec3(0.670820, 1.000000, 0.836660)); } void main(void) { - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; + varTexCoord = (mTexture * inTexCoord0).st; + gl_Position = mWorldViewProj * inVertexPosition; vPosition = gl_Position.xyz; - vNormal = gl_Normal; - worldPosition = (mWorld * gl_Vertex).xyz; - eyeVec = -(gl_ModelViewMatrix * gl_Vertex).xyz; + vNormal = inVertexNormal; + worldPosition = (mWorld * inVertexPosition).xyz; + eyeVec = -(mWorldView * inVertexPosition).xyz; #if (MATERIAL_TYPE == TILE_MATERIAL_PLAIN) || (MATERIAL_TYPE == TILE_MATERIAL_PLAIN_ALPHA) vIDiff = 1.0; #else // This is intentional comparison with zero without any margin. // If normal is not equal to zero exactly, then we assume it's a valid, just not normalized vector - vIDiff = length(gl_Normal) == 0.0 + vIDiff = length(inVertexNormal) == 0.0 ? 1.0 - : directional_ambient(normalize(gl_Normal)); + : directional_ambient(normalize(inVertexNormal)); #endif - gl_FrontColor = gl_BackColor = gl_Color; + varColor = inVertexColor; } diff --git a/client/shaders/selection_shader/opengl_fragment.glsl b/client/shaders/selection_shader/opengl_fragment.glsl index c679d0e12..35b1f8902 100644 --- a/client/shaders/selection_shader/opengl_fragment.glsl +++ b/client/shaders/selection_shader/opengl_fragment.glsl @@ -1,9 +1,12 @@ uniform sampler2D baseTexture; +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; + void main(void) { - vec2 uv = gl_TexCoord[0].st; + vec2 uv = varTexCoord.st; vec4 color = texture2D(baseTexture, uv); - color.rgb *= gl_Color.rgb; + color.rgb *= varColor.rgb; gl_FragColor = color; } diff --git a/client/shaders/selection_shader/opengl_vertex.glsl b/client/shaders/selection_shader/opengl_vertex.glsl index d0b16c8b0..9ca87a9cf 100644 --- a/client/shaders/selection_shader/opengl_vertex.glsl +++ b/client/shaders/selection_shader/opengl_vertex.glsl @@ -1,9 +1,10 @@ -uniform mat4 mWorldViewProj; +varying lowp vec4 varColor; +varying mediump vec2 varTexCoord; void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_Position = mWorldViewProj * gl_Vertex; + varTexCoord = inTexCoord0.st; + gl_Position = mWorldViewProj * inVertexPosition; - gl_FrontColor = gl_BackColor = gl_Color; + varColor = inVertexColor; } diff --git a/games/devtest/mods/basenodes/init.lua b/games/devtest/mods/basenodes/init.lua index 7ffbadbea..0cb85d808 100644 --- a/games/devtest/mods/basenodes/init.lua +++ b/games/devtest/mods/basenodes/init.lua @@ -127,6 +127,7 @@ minetest.register_node("basenodes:water_source", { description = "Water Source".."\n".. "Drowning damage: 1", drawtype = "liquid", + waving = 3, tiles = {"default_water.png"}, special_tiles = { {name = "default_water.png", backface_culling = false}, @@ -152,6 +153,7 @@ minetest.register_node("basenodes:water_flowing", { description = "Flowing Water".."\n".. "Drowning damage: 1", drawtype = "flowingliquid", + waving = 3, tiles = {"default_water_flowing.png"}, special_tiles = { {name = "default_water_flowing.png", backface_culling = false}, @@ -178,6 +180,7 @@ minetest.register_node("basenodes:river_water_source", { description = "River Water Source".."\n".. "Drowning damage: 1", drawtype = "liquid", + waving = 3, tiles = { "default_river_water.png" }, special_tiles = { {name = "default_river_water.png", backface_culling = false}, @@ -205,6 +208,7 @@ minetest.register_node("basenodes:river_water_flowing", { description = "Flowing River Water".."\n".. "Drowning damage: 1", drawtype = "flowingliquid", + waving = 3, tiles = {"default_river_water_flowing.png"}, special_tiles = { {name = "default_river_water_flowing.png", backface_culling = false}, diff --git a/src/client/shader.cpp b/src/client/shader.cpp index e2eeb4ab0..f2aa00246 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "gamedef.h" #include "client/tile.h" +#include "config.h" #if ENABLE_GLES #ifdef _IRR_COMPILE_WITH_OGLES1_ @@ -230,11 +231,24 @@ class MainShaderConstantSetter : public IShaderConstantSetter { CachedVertexShaderSetting m_world_view_proj; CachedVertexShaderSetting m_world; +#if ENABLE_GLES + // Modelview matrix + CachedVertexShaderSetting m_world_view; + // Texture matrix + CachedVertexShaderSetting m_texture; + // Normal matrix + CachedVertexShaderSetting m_normal; +#endif public: MainShaderConstantSetter() : - m_world_view_proj("mWorldViewProj"), - m_world("mWorld") + m_world_view_proj("mWorldViewProj") + , m_world("mWorld") +#if ENABLE_GLES + , m_world_view("mWorldView") + , m_texture("mTexture") + , m_normal("mNormal") +#endif {} ~MainShaderConstantSetter() = default; @@ -244,23 +258,42 @@ public: 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); + // Set clip matrix + core::matrix4 worldView; + worldView = driver->getTransform(video::ETS_VIEW); + worldView *= world; core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_PROJECTION); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); + worldViewProj *= worldView; if (is_highlevel) m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); else services->setVertexShaderConstant(worldViewProj.pointer(), 0, 4); - // 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); - +#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); + } +#endif } }; @@ -620,15 +653,62 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp return shaderinfo; // Create shaders header - std::string shaders_header = "#version 120\n"; - + 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 + if (use_gles) { + shaders_header = + "#version 100\n" + ; + vertex_header = R"( + uniform highp mat4 mWorldView; + uniform highp mat4 mWorldViewProj; + uniform mediump mat4 mTexture; + uniform mediump mat3 mNormal; + + attribute highp vec4 inVertexPosition; + attribute lowp vec4 inVertexColor; + attribute mediump vec4 inTexCoord0; + attribute mediump vec3 inVertexNormal; + attribute mediump vec4 inVertexTangent; + attribute mediump vec4 inVertexBinormal; + )"; + pixel_header = R"( + precision mediump float; + )"; + } else { + shaders_header = R"( + #version 120 + #define lowp + #define mediump + #define highp + )"; + vertex_header = R"( + #define mWorldView gl_ModelViewMatrix + #define mWorldViewProj gl_ModelViewProjectionMatrix + #define mTexture (gl_TextureMatrix[0]) + #define mNormal gl_NormalMatrix + + #define inVertexPosition gl_Vertex + #define inVertexColor gl_Color + #define inTexCoord0 gl_MultiTexCoord0 + #define inVertexNormal gl_Normal + #define inVertexTangent gl_MultiTexCoord1 + #define inVertexBinormal gl_MultiTexCoord2 + )"; + } + + bool use_discard = use_gles; #ifdef __unix__ // For renderers that should use discard instead of GL_ALPHA_TEST const char* gl_renderer = (const char*)glGetString(GL_RENDERER); - if (strstr(gl_renderer, "GC7000")) { - shaders_header += "#define USE_DISCARD\n"; - } + if (strstr(gl_renderer, "GC7000")) + 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", @@ -654,7 +734,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define "; shaders_header += drawTypes[i]; shaders_header += " "; - shaders_header += itos(i); + shaders_header += std::to_string(i); shaders_header += "\n"; } @@ -677,27 +757,27 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define "; shaders_header += materialTypes[i]; shaders_header += " "; - shaders_header += itos(i); + shaders_header += std::to_string(i); shaders_header += "\n"; } shaders_header += "#define MATERIAL_TYPE "; - shaders_header += itos(material_type); + shaders_header += std::to_string(material_type); shaders_header += "\n"; shaders_header += "#define DRAW_TYPE "; - shaders_header += itos(drawtype); + shaders_header += std::to_string(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 += ftos(g_settings->getFloat("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 += ftos(g_settings->getFloat("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 += ftos(g_settings->getFloat("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"; @@ -719,7 +799,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define ENABLE_TONE_MAPPING\n"; shaders_header += "#define FOG_START "; - shaders_header += ftos(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f)); + shaders_header += std::to_string(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f)); shaders_header += "\n"; // Call addHighLevelShaderMaterial() or addShaderMaterial() @@ -727,11 +807,11 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp const c8* pixel_program_ptr = 0; const c8* geometry_program_ptr = 0; if (!vertex_program.empty()) { - vertex_program = shaders_header + vertex_program; + vertex_program = shaders_header + vertex_header + vertex_program; vertex_program_ptr = vertex_program.c_str(); } if (!pixel_program.empty()) { - pixel_program = shaders_header + pixel_program; + pixel_program = shaders_header + pixel_header + pixel_program; pixel_program_ptr = pixel_program.c_str(); } if (!geometry_program.empty()) { @@ -813,27 +893,37 @@ void load_shaders(const std::string &name, SourceShaderCache *sourcecache, geometry_program = ""; is_highlevel = false; - if(enable_shaders){ - // Look for high level shaders - if(drivertype == 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; - } - else if(drivertype == video::EDT_OPENGL){ - // 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"); - } - if (!vertex_program.empty() || !pixel_program.empty() || !geometry_program.empty()){ - is_highlevel = true; - return; - } - } + 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, -- cgit v1.2.3 From a701d24a0070f3f581c47e5722aa07d4f89d7b98 Mon Sep 17 00:00:00 2001 From: Oblomov Date: Thu, 29 Oct 2020 20:09:59 +0100 Subject: Show RTT in ms with 2 digits of precision (#10573) If your ping is in seconds, you probably have other problems. --- src/client/gameui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client') diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp index 75e7d15b9..0c08efeb5 100644 --- a/src/client/gameui.cpp +++ b/src/client/gameui.cpp @@ -116,8 +116,8 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_ << std::setprecision(1) << " | view range: " << (draw_control->range_all ? "All" : itos(draw_control->wanted_range)) - << std::setprecision(3) - << " | RTT: " << client->getRTT() << "s"; + << std::setprecision(2) + << " | RTT: " << (client->getRTT() * 1000.0f) << "ms"; setStaticText(m_guitext, utf8_to_wide(os.str()).c_str()); m_guitext->setRelativePosition(core::rect(5, 5, screensize.X, -- cgit v1.2.3 From 2dff3dd03f7ba25f3fab7c360759ddbf93615668 Mon Sep 17 00:00:00 2001 From: Lars Müller <34514239+appgurueu@users.noreply.github.com> Date: Thu, 29 Oct 2020 20:15:46 +0100 Subject: Player physics: Ensure larger dtime simulation steps (#10563) --- src/client/clientenvironment.cpp | 113 ++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 68 deletions(-) (limited to 'src/client') diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index f831978a8..ea7be4200 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -183,84 +183,61 @@ void ClientEnvironment::step(float dtime) if(dtime > 0.5) dtime = 0.5; - f32 dtime_downcount = dtime; - /* Stuff that has a maximum time increment */ - u32 loopcount = 0; - do - { - loopcount++; - - f32 dtime_part; - if(dtime_downcount > dtime_max_increment) - { - dtime_part = dtime_max_increment; - dtime_downcount -= dtime_part; - } - else - { - dtime_part = dtime_downcount; - /* - Setting this to 0 (no -=dtime_part) disables an infinite loop - when dtime_part is so small that dtime_downcount -= dtime_part - does nothing - */ - dtime_downcount = 0; - } - + u32 steps = ceil(dtime / dtime_max_increment); + f32 dtime_part = dtime / steps; + for (; steps > 0; --steps) { /* - Handle local player + Local player handling */ - { - // Control local player - lplayer->applyControl(dtime_part, this); - - // Apply physics - if (!free_move && !is_climbing) { - // Gravity - v3f speed = lplayer->getSpeed(); - if (!lplayer->in_liquid) - speed.Y -= lplayer->movement_gravity * - lplayer->physics_override_gravity * dtime_part * 2.0f; - - // Liquid floating / sinking - if (lplayer->in_liquid && !lplayer->swimming_vertical && - !lplayer->swimming_pitch) - speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f; - - // Liquid resistance - if (lplayer->in_liquid_stable || lplayer->in_liquid) { - // How much the node's viscosity blocks movement, ranges - // between 0 and 1. Should match the scale at which viscosity - // increase affects other liquid attributes. - static const f32 viscosity_factor = 0.3f; - - v3f d_wanted = -speed / lplayer->movement_liquid_fluidity; - f32 dl = d_wanted.getLength(); - if (dl > lplayer->movement_liquid_fluidity_smooth) - dl = lplayer->movement_liquid_fluidity_smooth; - - dl *= (lplayer->liquid_viscosity * viscosity_factor) + - (1 - viscosity_factor); - v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f); - speed += d; - } - - lplayer->setSpeed(speed); + // Control local player + lplayer->applyControl(dtime_part, this); + + // Apply physics + if (!free_move && !is_climbing) { + // Gravity + v3f speed = lplayer->getSpeed(); + if (!lplayer->in_liquid) + speed.Y -= lplayer->movement_gravity * + lplayer->physics_override_gravity * dtime_part * 2.0f; + + // Liquid floating / sinking + if (lplayer->in_liquid && !lplayer->swimming_vertical && + !lplayer->swimming_pitch) + speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f; + + // Liquid resistance + if (lplayer->in_liquid_stable || lplayer->in_liquid) { + // How much the node's viscosity blocks movement, ranges + // between 0 and 1. Should match the scale at which viscosity + // increase affects other liquid attributes. + static const f32 viscosity_factor = 0.3f; + + v3f d_wanted = -speed / lplayer->movement_liquid_fluidity; + f32 dl = d_wanted.getLength(); + if (dl > lplayer->movement_liquid_fluidity_smooth) + dl = lplayer->movement_liquid_fluidity_smooth; + + dl *= (lplayer->liquid_viscosity * viscosity_factor) + + (1 - viscosity_factor); + v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f); + speed += d; } - /* - Move the lplayer. - This also does collision detection. - */ - lplayer->move(dtime_part, this, position_max_increment, - &player_collisions); + lplayer->setSpeed(speed); } - } while (dtime_downcount > 0.001); + + /* + Move the lplayer. + This also does collision detection. + */ + lplayer->move(dtime_part, this, position_max_increment, + &player_collisions); + } bool player_immortal = lplayer->getCAO() && lplayer->getCAO()->isImmortal(); -- cgit v1.2.3 From e3bd6704a0eb65e9490347680441c7a08df36f7a Mon Sep 17 00:00:00 2001 From: Lars Müller <34514239+appgurueu@users.noreply.github.com> Date: Wed, 4 Nov 2020 21:43:32 +0100 Subject: Revert "Fix short 180 degree rotation when using set_bone_position (#10405)" (#10534) This reverts commit 0f98b54aa4b2361575002d92b29fe222703ba557. --- src/client/content_cao.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 29a3acf25..e7f9db845 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1487,17 +1487,24 @@ void GenericCAO::updateBonePosition() if (!bone) continue; + //If bone is manually positioned there is no need to perform the bug check + bool skip = false; + for (auto &it : m_bone_position) { + if (it.first == bone->getName()) { + skip = true; + break; + } + } + if (skip) + continue; + // Workaround for Irrlicht bug // We check each bone to see if it has been rotated ~180deg from its expected position due to a bug in Irricht // when using EJUOR_CONTROL joint control. If the bug is detected we update the bone to the proper position // and update the bones transformation. v3f bone_rot = bone->getRelativeTransformation().getRotationDegrees(); - float offset_X = fabsf(bone_rot.X - bone->getRotation().X); - float offset_Y = fabsf(bone_rot.Y - bone->getRotation().Y); - float offset_Z = fabsf(bone_rot.Z - bone->getRotation().Z); - if ((offset_X > 179.9f && offset_X < 180.1f) - || (offset_Y > 179.9f && offset_Y < 180.1f) - || (offset_Z > 179.9f && offset_Z < 180.1f)) { + float offset = fabsf(bone_rot.X - bone->getRotation().X); + if (offset > 179.9f && offset < 180.1f) { bone->setRotation(bone_rot); bone->updateAbsolutePosition(); } -- cgit v1.2.3 From 627c22c36e32185d48d2faf8197e22cbaa4c50b2 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 5 Nov 2020 19:34:40 +0100 Subject: Fix integer-string conversion for shaders closes #10605 --- src/client/shader.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/client') diff --git a/src/client/shader.cpp b/src/client/shader.cpp index f2aa00246..4f6430579 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -734,7 +734,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define "; shaders_header += drawTypes[i]; shaders_header += " "; - shaders_header += std::to_string(i); + shaders_header += itos(i); shaders_header += "\n"; } @@ -757,15 +757,15 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaders_header += "#define "; shaders_header += materialTypes[i]; shaders_header += " "; - shaders_header += std::to_string(i); + shaders_header += itos(i); shaders_header += "\n"; } shaders_header += "#define MATERIAL_TYPE "; - shaders_header += std::to_string(material_type); + shaders_header += itos(material_type); shaders_header += "\n"; shaders_header += "#define DRAW_TYPE "; - shaders_header += std::to_string(drawtype); + shaders_header += itos(drawtype); shaders_header += "\n"; if (g_settings->getBool("enable_waving_water")){ -- cgit v1.2.3 From c940a57a384b1a75730776906451078d25c5aa52 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 8 Nov 2020 11:30:16 +0100 Subject: ContentCAO: Fix segfault when minimap is disabled --- src/client/content_cao.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index e7f9db845..7c349244f 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -894,6 +894,9 @@ u16 GenericCAO::getLightPosition(v3s16 *pos) void GenericCAO::updateMarker() { + if (!m_client->getMinimap()) + return; + if (!m_prop.show_on_minimap) { if (m_marker) m_client->getMinimap()->removeMarker(&m_marker); -- cgit v1.2.3 From e1142ee57f2d7b59a86f6d0d72ae043844bc3121 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Sat, 7 Nov 2020 17:45:32 +0100 Subject: Joystick: Remap joystick-specific KeyTypes to generic ones According to the following table: * MOUSE_L -> DIG * MOUSE_R -> PLACE * SCROLL_UP -> HOTBAR_NEXT * SCROLL_DOWN -> HOTBAR_PREV This commit entirely removes the special KeyTypes used for joysticks. Support for the MOUSE KeyTypes had already been removed in the main game code without adapting the joystick code, breaking joystick input. This commit restores joystick functionality. --- src/client/game.cpp | 16 ++++++---------- src/client/joystick_controller.cpp | 22 +++++++++++----------- src/client/keys.h | 6 ------ 3 files changed, 17 insertions(+), 27 deletions(-) (limited to 'src/client') diff --git a/src/client/game.cpp b/src/client/game.cpp index 0380c1661..5c38e027d 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2014,15 +2014,11 @@ void Game::processItemSelection(u16 *new_playeritem) s32 dir = wheel; - if (input->joystick.wasKeyDown(KeyType::SCROLL_DOWN) || - wasKeyDown(KeyType::HOTBAR_NEXT)) { + if (wasKeyDown(KeyType::HOTBAR_NEXT)) dir = -1; - } - if (input->joystick.wasKeyDown(KeyType::SCROLL_UP) || - wasKeyDown(KeyType::HOTBAR_PREV)) { + if (wasKeyDown(KeyType::HOTBAR_PREV)) dir = 1; - } if (dir < 0) *new_playeritem = *new_playeritem < max_item ? *new_playeritem + 1 : 0; @@ -3138,11 +3134,11 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) input->clearWasKeyPressed(); input->clearWasKeyReleased(); - input->joystick.clearWasKeyDown(KeyType::MOUSE_L); - input->joystick.clearWasKeyDown(KeyType::MOUSE_R); + input->joystick.clearWasKeyDown(KeyType::DIG); + input->joystick.clearWasKeyDown(KeyType::PLACE); - input->joystick.clearWasKeyReleased(KeyType::MOUSE_L); - input->joystick.clearWasKeyReleased(KeyType::MOUSE_R); + input->joystick.clearWasKeyReleased(KeyType::DIG); + input->joystick.clearWasKeyReleased(KeyType::PLACE); } diff --git a/src/client/joystick_controller.cpp b/src/client/joystick_controller.cpp index c29e8b639..742115046 100644 --- a/src/client/joystick_controller.cpp +++ b/src/client/joystick_controller.cpp @@ -74,8 +74,8 @@ JoystickLayout create_default_layout() // Accessible without four modifier button pressed // regardless whether start is pressed or not - JLO_B_PB(KeyType::MOUSE_L, fb | 1 << 4, 1 << 4); - JLO_B_PB(KeyType::MOUSE_R, fb | 1 << 5, 1 << 5); + JLO_B_PB(KeyType::DIG, fb | 1 << 4, 1 << 4); + JLO_B_PB(KeyType::PLACE, fb | 1 << 5, 1 << 5); // Accessible without any modifier pressed JLO_B_PB(KeyType::JUMP, bm | 1 << 0, 1 << 0); @@ -83,9 +83,9 @@ JoystickLayout create_default_layout() // Accessible with start button not pressed, but four pressed // TODO find usage for button 0 - JLO_B_PB(KeyType::DROP, bm | 1 << 1, fb | 1 << 1); - JLO_B_PB(KeyType::SCROLL_UP, bm | 1 << 4, fb | 1 << 4); - JLO_B_PB(KeyType::SCROLL_DOWN,bm | 1 << 5, fb | 1 << 5); + JLO_B_PB(KeyType::DROP, bm | 1 << 1, fb | 1 << 1); + JLO_B_PB(KeyType::HOTBAR_PREV, bm | 1 << 4, fb | 1 << 4); + JLO_B_PB(KeyType::HOTBAR_NEXT, bm | 1 << 5, fb | 1 << 5); // Accessible with start button and four pressed // TODO find usage for buttons 0, 1 and 4, 5 @@ -99,8 +99,8 @@ JoystickLayout create_default_layout() JLO_A_PB(KeyType::RIGHT, 0, -1, 1024); // Scroll buttons - JLO_A_PB(KeyType::SCROLL_UP, 2, -1, 1024); - JLO_A_PB(KeyType::SCROLL_DOWN, 5, -1, 1024); + JLO_A_PB(KeyType::HOTBAR_PREV, 2, -1, 1024); + JLO_A_PB(KeyType::HOTBAR_NEXT, 5, -1, 1024); return jlo; } @@ -134,10 +134,10 @@ JoystickLayout create_xbox_layout() JLO_B_PB(KeyType::SNEAK, 1 << 12, 1 << 12); // right // Triggers - JLO_B_PB(KeyType::MOUSE_L, 1 << 6, 1 << 6); // lt - JLO_B_PB(KeyType::MOUSE_R, 1 << 7, 1 << 7); // rt - JLO_B_PB(KeyType::SCROLL_UP, 1 << 4, 1 << 4); // lb - JLO_B_PB(KeyType::SCROLL_DOWN, 1 << 5, 1 << 5); // rb + JLO_B_PB(KeyType::DIG, 1 << 6, 1 << 6); // lt + JLO_B_PB(KeyType::PLACE, 1 << 7, 1 << 7); // rt + JLO_B_PB(KeyType::HOTBAR_PREV, 1 << 4, 1 << 4); // lb + JLO_B_PB(KeyType::HOTBAR_NEXT, 1 << 5, 1 << 5); // rb // D-PAD JLO_B_PB(KeyType::ZOOM, 1 << 15, 1 << 15); // up diff --git a/src/client/keys.h b/src/client/keys.h index b6ce59b4a..60a7a3c45 100644 --- a/src/client/keys.h +++ b/src/client/keys.h @@ -110,12 +110,6 @@ public: SLOT_31, SLOT_32, - // joystick specific keys - MOUSE_L, - MOUSE_R, - SCROLL_UP, - SCROLL_DOWN, - // Fake keycode for array size and internal checks INTERNAL_ENUM_COUNT -- cgit v1.2.3 From 68139a28eb8b43b3685b81c77258912ffc5e0b8f Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Thu, 12 Nov 2020 19:16:02 +0100 Subject: Revert "Replace MyEventReceiver KeyList with std::unordered_set" (#10622) This reverts commit 787561b29afdbc78769f68c2f5c4f2cff1b32340. --- src/client/inputhandler.cpp | 48 +++++++++----------- src/client/inputhandler.h | 108 ++++++++++++++++++++++++++++++++++++-------- src/client/keycode.h | 19 -------- 3 files changed, 111 insertions(+), 64 deletions(-) (limited to 'src/client') diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index ee3e37ae9..608a405a8 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -112,7 +112,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event) // Remember whether each key is down or up if (event.EventType == irr::EET_KEY_INPUT_EVENT) { const KeyPress &keyCode = event.KeyInput; - if (keysListenedFor.count(keyCode)) { + if (keysListenedFor[keyCode]) { // If the key is being held down then the OS may // send a continuous stream of keydown events. // In this case, we don't want to let this @@ -120,15 +120,15 @@ bool MyEventReceiver::OnEvent(const SEvent &event) // certain actions to repeat constantly. if (event.KeyInput.PressedDown) { if (!IsKeyDown(keyCode)) { - keyWasDown.insert(keyCode); - keyWasPressed.insert(keyCode); + keyWasDown.set(keyCode); + keyWasPressed.set(keyCode); } - keyIsDown.insert(keyCode); + keyIsDown.set(keyCode); } else { if (IsKeyDown(keyCode)) - keyWasReleased.insert(keyCode); + keyWasReleased.set(keyCode); - keyIsDown.erase(keyCode); + keyIsDown.unset(keyCode); } return true; @@ -153,36 +153,36 @@ bool MyEventReceiver::OnEvent(const SEvent &event) switch (event.MouseInput.Event) { case EMIE_LMOUSE_PRESSED_DOWN: key = "KEY_LBUTTON"; - keyIsDown.insert(key); - keyWasDown.insert(key); - keyWasPressed.insert(key); + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); break; case EMIE_MMOUSE_PRESSED_DOWN: key = "KEY_MBUTTON"; - keyIsDown.insert(key); - keyWasDown.insert(key); - keyWasPressed.insert(key); + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); break; case EMIE_RMOUSE_PRESSED_DOWN: key = "KEY_RBUTTON"; - keyIsDown.insert(key); - keyWasDown.insert(key); - keyWasPressed.insert(key); + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); break; case EMIE_LMOUSE_LEFT_UP: key = "KEY_LBUTTON"; - keyIsDown.erase(key); - keyWasReleased.insert(key); + keyIsDown.unset(key); + keyWasReleased.set(key); break; case EMIE_MMOUSE_LEFT_UP: key = "KEY_MBUTTON"; - keyIsDown.erase(key); - keyWasReleased.insert(key); + keyIsDown.unset(key); + keyWasReleased.set(key); break; case EMIE_RMOUSE_LEFT_UP: key = "KEY_RBUTTON"; - keyIsDown.erase(key); - keyWasReleased.insert(key); + keyIsDown.unset(key); + keyWasReleased.set(key); break; case EMIE_MOUSE_WHEEL: mouse_wheel += event.MouseInput.Wheel; @@ -235,11 +235,7 @@ void RandomInputHandler::step(float dtime) i.counter -= dtime; if (i.counter < 0.0) { i.counter = 0.1 * Rand(1, i.time_max); - KeyPress k = getKeySetting(i.key.c_str()); - if (keydown.count(k)) - keydown.erase(k); - else - keydown.insert(k); + keydown.toggle(getKeySetting(i.key.c_str())); } } { diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index 885f34e05..def147a82 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -21,9 +21,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "joystick_controller.h" +#include #include "keycode.h" #include "renderingengine.h" -#include #ifdef HAVE_TOUCHSCREENGUI #include "gui/touchscreengui.h" @@ -61,32 +61,98 @@ struct KeyCache InputHandler *handler; }; +class KeyList : private std::list +{ + typedef std::list super; + typedef super::iterator iterator; + typedef super::const_iterator const_iterator; + + virtual const_iterator find(const KeyPress &key) const + { + const_iterator f(begin()); + const_iterator e(end()); + + while (f != e) { + if (*f == key) + return f; + + ++f; + } + + return e; + } + + virtual iterator find(const KeyPress &key) + { + iterator f(begin()); + iterator e(end()); + + while (f != e) { + if (*f == key) + return f; + + ++f; + } + + return e; + } + +public: + void clear() { super::clear(); } + + void set(const KeyPress &key) + { + if (find(key) == end()) + push_back(key); + } + + void unset(const KeyPress &key) + { + iterator p(find(key)); + + if (p != end()) + erase(p); + } + + void toggle(const KeyPress &key) + { + iterator p(this->find(key)); + + if (p != end()) + erase(p); + else + push_back(key); + } + + bool operator[](const KeyPress &key) const { return find(key) != end(); } +}; + class MyEventReceiver : public IEventReceiver { public: // This is the one method that we have to implement virtual bool OnEvent(const SEvent &event); - bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown.count(keyCode); } + bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; } // Checks whether a key was down and resets the state bool WasKeyDown(const KeyPress &keyCode) { - bool b = keyWasDown.count(keyCode); + bool b = keyWasDown[keyCode]; if (b) - keyWasDown.erase(keyCode); + keyWasDown.unset(keyCode); return b; } // Checks whether a key was just pressed. State will be cleared // in the subsequent iteration of Game::processPlayerInteraction - bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed.count(keycode); } + bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; } // Checks whether a key was just released. State will be cleared // in the subsequent iteration of Game::processPlayerInteraction - bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased.count(keycode); } + bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; } - void listenForKey(const KeyPress &keyCode) { keysListenedFor.insert(keyCode); } + void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); } void dontListenForKeys() { keysListenedFor.clear(); } s32 getMouseWheel() @@ -132,20 +198,24 @@ public: #endif private: - //! The current state of keys - std::unordered_set keyIsDown; + // The current state of keys + KeyList keyIsDown; - //! Whether a key was down - std::unordered_set keyWasDown; + // Whether a key was down + KeyList keyWasDown; - //! Whether a key has just been pressed - std::unordered_set keyWasPressed; + // Whether a key has just been pressed + KeyList keyWasPressed; - //! Whether a key has just been released - std::unordered_set keyWasReleased; + // Whether a key has just been released + KeyList keyWasReleased; - //! List of keys we listen for - std::unordered_set keysListenedFor; + // List of keys we listen for + // TODO perhaps the type of this is not really + // performant as KeyList is designed for few but + // often changing keys, and keysListenedFor is expected + // to change seldomly but contain lots of keys. + KeyList keysListenedFor; }; class InputHandler @@ -277,7 +347,7 @@ public: return true; } - virtual bool isKeyDown(GameKeyType k) { return keydown.count(keycache.key[k]); } + virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } virtual bool wasKeyDown(GameKeyType k) { return false; } virtual bool wasKeyPressed(GameKeyType k) { return false; } virtual bool wasKeyReleased(GameKeyType k) { return false; } @@ -292,7 +362,7 @@ public: s32 Rand(s32 min, s32 max); private: - std::unordered_set keydown; + KeyList keydown; v2s32 mousepos; v2s32 mousespeed; }; diff --git a/src/client/keycode.h b/src/client/keycode.h index 263b722c7..7036705d1 100644 --- a/src/client/keycode.h +++ b/src/client/keycode.h @@ -24,20 +24,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -class KeyPress; -namespace std -{ - template <> struct hash; -} - /* A key press, consisting of either an Irrlicht keycode or an actual char */ class KeyPress { public: - friend struct std::hash; - KeyPress() = default; KeyPress(const char *name); @@ -63,17 +55,6 @@ protected: std::string m_name = ""; }; -namespace std -{ - template <> struct hash - { - size_t operator()(const KeyPress &key) const - { - return key.Key; - } - }; -} - extern const KeyPress EscapeKey; extern const KeyPress CancelKey; -- cgit v1.2.3 From c441baa91b71c48a369178df287eeb91e15ea7d1 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 10 Nov 2020 21:22:02 +0100 Subject: Fix overloaded virtual warnings with get/setAttachment() --- src/client/content_cao.cpp | 49 +++++++++++++++++++++++----------------------- src/client/content_cao.h | 12 ++++-------- 2 files changed, 29 insertions(+), 32 deletions(-) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 7c349244f..c52bc62c5 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -460,18 +460,20 @@ void GenericCAO::setChildrenVisible(bool toset) GenericCAO *obj = m_env->getGenericCAO(cao_id); if (obj) { // Check if the entity is forced to appear in first person. - obj->setVisible(obj->isForcedVisible() ? true : toset); + obj->setVisible(obj->m_force_visible ? true : toset); } } } -void GenericCAO::setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation) +void GenericCAO::setAttachment(int parent_id, const std::string &bone, + v3f position, v3f rotation, bool force_visible) { int old_parent = m_attachment_parent_id; m_attachment_parent_id = parent_id; m_attachment_bone = bone; m_attachment_position = position; m_attachment_rotation = rotation; + m_force_visible = force_visible; ClientActiveObject *parent = m_env->getActiveObject(parent_id); @@ -482,15 +484,30 @@ void GenericCAO::setAttachment(int parent_id, const std::string &bone, v3f posit parent->addAttachmentChild(m_id); } updateAttachments(); + + // Forcibly show attachments if required by set_attach + if (m_force_visible) { + m_is_visible = true; + } else if (!m_is_local_player) { + // Objects attached to the local player should be hidden in first person + m_is_visible = !m_attached_to_local || + m_client->getCamera()->getCameraMode() != CAMERA_MODE_FIRST; + m_force_visible = false; + } else { + // Local players need to have this set, + // otherwise first person attachments fail. + m_is_visible = true; + } } void GenericCAO::getAttachment(int *parent_id, std::string *bone, v3f *position, - v3f *rotation) const + v3f *rotation, bool *force_visible) const { *parent_id = m_attachment_parent_id; *bone = m_attachment_bone; *position = m_attachment_position; *rotation = m_attachment_rotation; + *force_visible = m_force_visible; } void GenericCAO::clearChildAttachments() @@ -509,9 +526,9 @@ void GenericCAO::clearChildAttachments() void GenericCAO::clearParentAttachment() { if (m_attachment_parent_id) - setAttachment(0, "", m_attachment_position, m_attachment_rotation); + setAttachment(0, "", m_attachment_position, m_attachment_rotation, false); else - setAttachment(0, "", v3f(), v3f()); + setAttachment(0, "", v3f(), v3f(), false); } void GenericCAO::addAttachmentChild(int child_id) @@ -1781,25 +1798,9 @@ void GenericCAO::processMessage(const std::string &data) std::string bone = deSerializeString16(is); v3f position = readV3F32(is); v3f rotation = readV3F32(is); - m_force_visible = readU8(is); // Returns false for EOF - - setAttachment(parent_id, bone, position, rotation); - - // Forcibly show attachments if required by set_attach - if (m_force_visible) - m_is_visible = true; - // localplayer itself can't be attached to localplayer - else if (!m_is_local_player) { - // Objects attached to the local player should be hidden in first - // person provided the forced boolean isn't set. - m_is_visible = !m_attached_to_local || - m_client->getCamera()->getCameraMode() != CAMERA_MODE_FIRST; - m_force_visible = false; - } else { - // Local players need to have this set, - // otherwise first person attachments fail. - m_is_visible = true; - } + bool force_visible = readU8(is); // Returns false for EOF + + setAttachment(parent_id, bone, position, rotation, force_visible); } else if (cmd == AO_CMD_PUNCHED) { u16 result_hp = readU16(is); diff --git a/src/client/content_cao.h b/src/client/content_cao.h index 435fc2931..7c134fb48 100644 --- a/src/client/content_cao.h +++ b/src/client/content_cao.h @@ -111,6 +111,7 @@ private: v3f m_attachment_position; v3f m_attachment_rotation; bool m_attached_to_local = false; + bool m_force_visible = false; int m_anim_frame = 0; int m_anim_num_frames = 1; @@ -126,7 +127,6 @@ private: float m_step_distance_counter = 0.0f; u8 m_last_light = 255; bool m_is_visible = false; - bool m_force_visible = false; s8 m_glow = 0; // Material video::E_MATERIAL_TYPE m_material_type; @@ -218,15 +218,11 @@ public: m_is_visible = toset; } - inline bool isForcedVisible() const - { - return m_force_visible; - } - void setChildrenVisible(bool toset); - void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation); + void setAttachment(int parent_id, const std::string &bone, v3f position, + v3f rotation, bool force_visible); void getAttachment(int *parent_id, std::string *bone, v3f *position, - v3f *rotation) const; + v3f *rotation, bool *force_visible) const; void clearChildAttachments(); void clearParentAttachment(); void addAttachmentChild(int child_id); -- cgit v1.2.3 From b504a1aa4bdc56676b4b1c398ebfe98d336f8f6e Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 10 Nov 2020 21:36:58 +0100 Subject: Fix player sprite visibility in first person closes #10525 --- src/client/content_cao.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/client') diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index c52bc62c5..c645900aa 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1919,13 +1919,23 @@ void GenericCAO::updateMeshCulling() if (!m_is_local_player) return; - // Grab the active player scene node so we know there's - // at least a mesh to occlude from the camera. + const bool hidden = m_client->getCamera()->getCameraMode() == CAMERA_MODE_FIRST; + + if (m_meshnode && m_prop.visual == "upright_sprite") { + u32 buffers = m_meshnode->getMesh()->getMeshBufferCount(); + for (u32 i = 0; i < buffers; i++) { + video::SMaterial &mat = m_meshnode->getMesh()->getMeshBuffer(i)->getMaterial(); + // upright sprite has no backface culling + mat.setFlag(video::EMF_FRONT_FACE_CULLING, hidden); + } + return; + } + irr::scene::ISceneNode *node = getSceneNode(); if (!node) return; - if (m_client->getCamera()->getCameraMode() == CAMERA_MODE_FIRST) { + if (hidden) { // Hide the mesh by culling both front and // back faces. Serious hackyness but it works for our // purposes. This also preserves the skeletal armature. -- cgit v1.2.3 From 78273027bf4bbee7488c76c6d65f85381ec7c0ba Mon Sep 17 00:00:00 2001 From: Pierre-Yves Rollo Date: Wed, 16 Sep 2020 17:10:17 +0200 Subject: Add sound to press event of some formspecs elements (#10402) --- doc/lua_api.txt | 5 +++++ src/client/game.cpp | 12 ++++++------ src/gui/StyleSpec.h | 3 +++ src/gui/guiEngine.cpp | 1 + src/gui/guiFormSpecMenu.cpp | 40 +++++++++++++++++++++++++++++++++++++--- src/gui/guiFormSpecMenu.h | 6 +++++- 6 files changed, 57 insertions(+), 10 deletions(-) (limited to 'src/client') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ef283f0c1..27f871618 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2843,11 +2843,14 @@ Some types may inherit styles from parent types. * noclip - boolean, set to true to allow the element to exceed formspec bounds. * padding - rect, adds space between the edges of the button and the content. This value is relative to bgimg_middle. + * sound - a sound to be played when clicked. * textcolor - color, default white. * checkbox * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * sound - a sound to be played when clicked. * dropdown * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * sound - a sound to be played when clicked. * field, pwdfield, textarea * border - set to false to hide the textbox background and border. Default true. * font - Sets font type. See button `font` property for more information. @@ -2874,10 +2877,12 @@ Some types may inherit styles from parent types. * fgimg_pressed - image when pressed. Defaults to fgimg when not provided. * This is deprecated, use states instead. * NOTE: The parameters of any given image_button will take precedence over fgimg/fgimg_pressed + * sound - a sound to be played when clicked. * scrollbar * noclip - boolean, set to true to allow the element to exceed formspec bounds. * tabheader * noclip - boolean, set to true to allow the element to exceed formspec bounds. + * sound - a sound to be played when clicked. * textcolor - color. Default white. * table, textlist * font - Sets font type. See button `font` property for more information. diff --git a/src/client/game.cpp b/src/client/game.cpp index 5c38e027d..b7bb0a330 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -2071,7 +2071,7 @@ void Game::openInventory() TextDest *txt_dst = new TextDestPlayerInventory(client); auto *&formspec = m_game_ui->updateFormspec(""); GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src, - txt_dst, client->getFormspecPrepend()); + txt_dst, client->getFormspecPrepend(), sound); formspec->setFormSpec(fs_src->getForm(), inventoryloc); } @@ -2603,7 +2603,7 @@ void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation auto *&formspec = m_game_ui->updateFormspec(*(event->show_formspec.formname)); GUIFormSpecMenu::create(formspec, client, &input->joystick, - fs_src, txt_dst, client->getFormspecPrepend()); + fs_src, txt_dst, client->getFormspecPrepend(), sound); } delete event->show_formspec.formspec; @@ -2616,7 +2616,7 @@ void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrienta LocalFormspecHandler *txt_dst = new LocalFormspecHandler(*event->show_formspec.formname, client); GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, &input->joystick, - fs_src, txt_dst, client->getFormspecPrepend()); + fs_src, txt_dst, client->getFormspecPrepend(), sound); delete event->show_formspec.formspec; delete event->show_formspec.formname; @@ -3336,7 +3336,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, auto *&formspec = m_game_ui->updateFormspec(""); GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src, - txt_dst, client->getFormspecPrepend()); + txt_dst, client->getFormspecPrepend(), sound); formspec->setFormSpec(meta->getString("formspec"), inventoryloc); return false; @@ -4108,7 +4108,7 @@ void Game::showDeathFormspec() auto *&formspec = m_game_ui->getFormspecGUI(); GUIFormSpecMenu::create(formspec, client, &input->joystick, - fs_src, txt_dst, client->getFormspecPrepend()); + fs_src, txt_dst, client->getFormspecPrepend(), sound); formspec->setFocus("btn_respawn"); } @@ -4242,7 +4242,7 @@ void Game::showPauseMenu() auto *&formspec = m_game_ui->getFormspecGUI(); GUIFormSpecMenu::create(formspec, client, &input->joystick, - fs_src, txt_dst, client->getFormspecPrepend()); + fs_src, txt_dst, client->getFormspecPrepend(), sound); formspec->setFocus("btn_continue"); formspec->doPause = true; } diff --git a/src/gui/StyleSpec.h b/src/gui/StyleSpec.h index 36ad51a89..f2844ce28 100644 --- a/src/gui/StyleSpec.h +++ b/src/gui/StyleSpec.h @@ -54,6 +54,7 @@ public: COLORS, BORDERCOLORS, BORDERWIDTHS, + SOUND, NUM_PROPERTIES, NONE }; @@ -116,6 +117,8 @@ public: return BORDERCOLORS; } else if (name == "borderwidths") { return BORDERWIDTHS; + } else if (name == "sound") { + return SOUND; } else { return NONE; } diff --git a/src/gui/guiEngine.cpp b/src/gui/guiEngine.cpp index 4a13f0b11..c5ad5c323 100644 --- a/src/gui/guiEngine.cpp +++ b/src/gui/guiEngine.cpp @@ -170,6 +170,7 @@ GUIEngine::GUIEngine(JoystickController *joystick, m_menumanager, NULL /* &client */, m_texture_source, + m_sound_manager, m_formspecgui, m_buttonhandler, "", diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index 039b28e79..632b15992 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -48,6 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "client/client.h" #include "client/fontengine.h" +#include "client/sound.h" #include "util/hex.h" #include "util/numeric.h" #include "util/string.h" // for parseColorString() @@ -95,11 +96,13 @@ inline u32 clamp_u8(s32 value) GUIFormSpecMenu::GUIFormSpecMenu(JoystickController *joystick, gui::IGUIElement *parent, s32 id, IMenuManager *menumgr, - Client *client, ISimpleTextureSource *tsrc, IFormSource *fsrc, TextDest *tdst, + Client *client, ISimpleTextureSource *tsrc, ISoundManager *sound_manager, + IFormSource *fsrc, TextDest *tdst, const std::string &formspecPrepend, bool remap_dbl_click): GUIModalMenu(RenderingEngine::get_gui_env(), parent, id, menumgr, remap_dbl_click), m_invmgr(client), m_tsrc(tsrc), + m_sound_manager(sound_manager), m_client(client), m_formspec_prepend(formspecPrepend), m_form_src(fsrc), @@ -143,11 +146,12 @@ GUIFormSpecMenu::~GUIFormSpecMenu() void GUIFormSpecMenu::create(GUIFormSpecMenu *&cur_formspec, Client *client, JoystickController *joystick, IFormSource *fs_src, TextDest *txt_dest, - const std::string &formspecPrepend) + const std::string &formspecPrepend, ISoundManager *sound_manager) { if (cur_formspec == nullptr) { cur_formspec = new GUIFormSpecMenu(joystick, guiroot, -1, &g_menumgr, - client, client->getTextureSource(), fs_src, txt_dest, formspecPrepend); + client, client->getTextureSource(), sound_manager, fs_src, + txt_dest, formspecPrepend); cur_formspec->doPause = false; /* @@ -614,6 +618,9 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data, const std::string &element data->current_parent, spec.fid, spec.flabel.c_str()); auto style = getDefaultStyleForElement("checkbox", name); + + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); if (spec.fname == m_focused_element) { @@ -1020,6 +1027,9 @@ void GUIFormSpecMenu::parseButton(parserData* data, const std::string &element, data->current_parent, spec.fid, spec.flabel.c_str()); auto style = getStyleForElement(type, name, (type != "button") ? "button" : ""); + + spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, ""); + e->setStyles(style); if (spec.fname == m_focused_element) { @@ -1381,6 +1391,9 @@ void GUIFormSpecMenu::parseDropDown(parserData* data, const std::string &element e->setSelected(stoi(str_initial_selection)-1); auto style = getDefaultStyleForElement("dropdown", name); + + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, false)); m_fields.push_back(spec); @@ -1747,6 +1760,10 @@ void GUIFormSpecMenu::parseHyperText(parserData *data, const std::string &elemen ); spec.ftype = f_HyperText; + + auto style = getDefaultStyleForElement("hypertext", spec.fname); + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + GUIHyperText *e = new GUIHyperText(spec.flabel.c_str(), Environment, data->current_parent, spec.fid, rect, m_client, m_tsrc); e->drop(); @@ -1999,6 +2016,8 @@ void GUIFormSpecMenu::parseImageButton(parserData* data, const std::string &elem auto style = getStyleForElement("image_button", spec.fname); + spec.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, ""); + // Override style properties with values specified directly in the element if (!image_name.empty()) style[StyleSpec::STATE_DEFAULT].set(StyleSpec::FGIMG, image_name); @@ -2107,6 +2126,9 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data, const std::string &elemen e->setTabHeight(geom.Y); auto style = getDefaultStyleForElement("tabheader", name); + + spec.sound = style.get(StyleSpec::Property::SOUND, ""); + e->setNotClipped(style.getBool(StyleSpec::NOCLIP, true)); for (const std::string &button : buttons) { @@ -2195,6 +2217,9 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string & item_name, m_client); auto style = getStyleForElement("item_image_button", spec_btn.fname, "image_button"); + + spec_btn.sound = style[StyleSpec::STATE_DEFAULT].get(StyleSpec::Property::SOUND, ""); + e_btn->setStyles(style); if (spec_btn.fname == m_focused_element) { @@ -4486,6 +4511,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) for (GUIFormSpecMenu::FieldSpec &s : m_fields) { if ((s.ftype == f_TabHeader) && (s.fid == event.GUIEvent.Caller->getID())) { + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(s.sound, false, 1.0f); s.send = true; acceptInput(); s.send = false; @@ -4529,6 +4556,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) continue; if (s.ftype == f_Button || s.ftype == f_CheckBox) { + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(s.sound, false, 1.0f); + s.send = true; if (s.is_exit) { if (m_allowclose) { @@ -4551,6 +4581,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) s2.send = false; } } + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(s.sound, false, 1.0f); s.send = true; acceptInput(quit_mode_no); @@ -4567,6 +4599,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event) acceptInput(quit_mode_no); s.fdefault = L""; } else if (s.ftype == f_Unknown || s.ftype == f_HyperText) { + if (!s.sound.empty() && m_sound_manager) + m_sound_manager->playSound(s.sound, false, 1.0f); s.send = true; acceptInput(); s.send = false; diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h index c5d662a69..53076e3bd 100644 --- a/src/gui/guiFormSpecMenu.h +++ b/src/gui/guiFormSpecMenu.h @@ -39,6 +39,7 @@ class InventoryManager; class ISimpleTextureSource; class Client; class GUIScrollContainer; +class ISoundManager; typedef enum { f_Button, @@ -127,6 +128,7 @@ class GUIFormSpecMenu : public GUIModalMenu int priority; core::rect rect; gui::ECURSOR_ICON fcursor_icon; + std::string sound; }; struct TooltipSpec @@ -151,6 +153,7 @@ public: IMenuManager *menumgr, Client *client, ISimpleTextureSource *tsrc, + ISoundManager *sound_manager, IFormSource* fs_src, TextDest* txt_dst, const std::string &formspecPrepend, @@ -160,7 +163,7 @@ public: static void create(GUIFormSpecMenu *&cur_formspec, Client *client, JoystickController *joystick, IFormSource *fs_src, TextDest *txt_dest, - const std::string &formspecPrepend); + const std::string &formspecPrepend, ISoundManager *sound_manager); void setFormSpec(const std::string &formspec_string, const InventoryLocation ¤t_inventory_location) @@ -293,6 +296,7 @@ protected: InventoryManager *m_invmgr; ISimpleTextureSource *m_tsrc; + ISoundManager *m_sound_manager; Client *m_client; std::string m_formspec_string; -- cgit v1.2.3 From 8dc70ebb936277f740dffe9a11b5ee0fecc9de8e Mon Sep 17 00:00:00 2001 From: Lars Date: Tue, 24 Nov 2020 09:23:18 -0800 Subject: Fix camera panning glitches (partially revert 10489.) --- src/client/clientmap.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index c8561def6..09072858a 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -124,7 +124,10 @@ void ClientMap::updateDrawList() const v3f camera_position = m_camera_position; const v3f camera_direction = m_camera_direction; - const f32 camera_fov = m_camera_fov; + + // Use a higher fov to accomodate faster camera movements. + // Blocks are cropped better when they are drawn. + const f32 camera_fov = m_camera_fov * 1.1f; v3s16 cam_pos_nodes = floatToInt(camera_position, BS); v3s16 p_blocks_min; -- cgit v1.2.3 From 095f82692d3d1b8b190178d640f0a166d1851f60 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 09:13:16 +0300 Subject: Batch cloud drawing --- src/client/clouds.cpp | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'src/client') diff --git a/src/client/clouds.cpp b/src/client/clouds.cpp index 887a62f25..ccc94cc88 100644 --- a/src/client/clouds.cpp +++ b/src/client/clouds.cpp @@ -170,8 +170,9 @@ void Clouds::render() // Read noise - bool *grid = new bool[m_cloud_radius_i * 2 * m_cloud_radius_i * 2]; - + std::vector grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2); // vector is broken + std::vector vertices; + vertices.reserve(16 * m_cloud_radius_i * m_cloud_radius_i); for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) { u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i; @@ -195,12 +196,7 @@ void Clouds::render() { s16 zi = zi0; s16 xi = xi0; - // Draw from front to back (needed for transparency) - /*if(zi <= 0) - zi = -m_cloud_radius_i - zi; - if(xi <= 0) - xi = -m_cloud_radius_i - xi;*/ - // Draw from back to front + // Draw from back to front for proper transparency if(zi >= 0) zi = m_cloud_radius_i - zi - 1; if(xi >= 0) @@ -220,17 +216,10 @@ void Clouds::render() video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0) }; - /*if(zi <= 0 && xi <= 0){ - v[0].Color.setBlue(255); - v[1].Color.setBlue(255); - v[2].Color.setBlue(255); - v[3].Color.setBlue(255); - }*/ - - f32 rx = cloud_size / 2.0f; + const f32 rx = cloud_size / 2.0f; // if clouds are flat, the top layer should be at the given height - f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f; - f32 rz = cloud_size / 2; + const f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f; + const f32 rz = cloud_size / 2; for(int i=0; idrawVertexPrimitiveList(v, 4, indices, 2, - video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); + vertices.push_back(vertex); + } } } - - delete[] grid; + int quad_count = vertices.size() / 4; + std::vector indices; + indices.reserve(quad_count * 6); + for (int k = 0; k < quad_count; k++) { + indices.push_back(4 * k + 0); + indices.push_back(4 * k + 1); + indices.push_back(4 * k + 2); + indices.push_back(4 * k + 2); + indices.push_back(4 * k + 3); + indices.push_back(4 * k + 0); + } + driver->drawVertexPrimitiveList(vertices.data(), vertices.size(), indices.data(), 2 * quad_count, + video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); // Restore fog settings driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density, -- cgit v1.2.3 From 89cc5bf53730d72744d45f92fc11dc9ab6c232c9 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 16:43:38 +0300 Subject: Don't evaluate things many times --- src/client/clouds.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src/client') diff --git a/src/client/clouds.cpp b/src/client/clouds.cpp index ccc94cc88..253dee8b9 100644 --- a/src/client/clouds.cpp +++ b/src/client/clouds.cpp @@ -341,14 +341,13 @@ void Clouds::step(float dtime) void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse) { + video::SColorf ambient(m_params.color_ambient); + video::SColorf bright(m_params.color_bright); m_camera_pos = camera_p; - m_color.r = MYMIN(MYMAX(color_diffuse.r * m_params.color_bright.getRed(), - m_params.color_ambient.getRed()), 255) / 255.0f; - m_color.g = MYMIN(MYMAX(color_diffuse.g * m_params.color_bright.getGreen(), - m_params.color_ambient.getGreen()), 255) / 255.0f; - m_color.b = MYMIN(MYMAX(color_diffuse.b * m_params.color_bright.getBlue(), - m_params.color_ambient.getBlue()), 255) / 255.0f; - m_color.a = m_params.color_bright.getAlpha() / 255.0f; + m_color.r = core::clamp(color_diffuse.r * bright.r, ambient.r, 1.0f); + m_color.g = core::clamp(color_diffuse.g * bright.g, ambient.g, 1.0f); + m_color.b = core::clamp(color_diffuse.b * bright.b, ambient.b, 1.0f); + m_color.a = bright.a; // is the camera inside the cloud mesh? m_camera_inside_cloud = false; // default -- cgit v1.2.3 From 3077afc0a2039cd4c8d64d9df62ed9b2ba6463dc Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 16:29:31 +0300 Subject: Store stars in a single static mesh buffer --- src/client/sky.cpp | 199 +++++++++++++++++++++++------------------------------ src/client/sky.h | 8 ++- 2 files changed, 92 insertions(+), 115 deletions(-) (limited to 'src/client') diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 2e0cbca86..29a0545ab 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -1,6 +1,7 @@ /* Minetest Copyright (C) 2010-2013 celeron55, Perttu Ahola +Copyright (C) 2020 numzero, Lobachevskiy Vitaliy 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 @@ -34,16 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "config.h" using namespace irr::core; -Sky::Sky(s32 id, ITextureSource *tsrc) : - scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(), - RenderingEngine::get_scene_manager(), id) -{ - setAutomaticCulling(scene::EAC_OFF); - m_box.MaxEdge.set(0, 0, 0); - m_box.MinEdge.set(0, 0, 0); - - // Create material - +static video::SMaterial baseMaterial() { video::SMaterial mat; mat.Lighting = false; #if ENABLE_GLES @@ -56,14 +48,29 @@ Sky::Sky(s32 id, ITextureSource *tsrc) : mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; mat.BackfaceCulling = false; + return mat; +}; + +Sky::Sky(s32 id, ITextureSource *tsrc) : + scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(), + RenderingEngine::get_scene_manager(), id) +{ + setAutomaticCulling(scene::EAC_OFF); + m_box.MaxEdge.set(0, 0, 0); + m_box.MinEdge.set(0, 0, 0); + + // Create materials - m_materials[0] = mat; + m_materials[0] = baseMaterial(); + m_materials[0].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + m_materials[0].Lighting = true; + m_materials[0].ColorMaterial = video::ECM_NONE; - m_materials[1] = mat; + m_materials[1] = baseMaterial(); //m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - m_materials[2] = mat; + m_materials[2] = baseMaterial(); m_materials[2].setTexture(0, tsrc->getTextureForMesh("sunrisebg.png")); m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; //m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; @@ -80,7 +87,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc) : tsrc->getTexture(m_moon_params.tonemap) : NULL; if (m_sun_texture) { - m_materials[3] = mat; + m_materials[3] = baseMaterial(); m_materials[3].setTexture(0, m_sun_texture); m_materials[3].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; // Disables texture filtering @@ -92,7 +99,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc) : m_materials[3].Lighting = true; } if (m_moon_texture) { - m_materials[4] = mat; + m_materials[4] = baseMaterial(); m_materials[4].setTexture(0, m_moon_texture); m_materials[4].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; // Disables texture filtering @@ -105,7 +112,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc) : } for (int i = 5; i < 11; i++) { - m_materials[i] = mat; + m_materials[i] = baseMaterial(); m_materials[i].Lighting = true; m_materials[i].MaterialType = video::EMT_SOLID; } @@ -673,13 +680,12 @@ void Sky::draw_moon(video::IVideoDriver *driver, float moonsize, const video::SC c = video::SColor(255, 255, 255, 255); draw_sky_body(vertices, -d, d, c); place_sky_body(vertices, -90, wicked_time_of_day * 360 - 90); - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day) { - driver->setMaterial(m_materials[1]); // Tune values so that stars first appear just after the sun // disappears over the horizon, and disappear just before the sun // appears over the horizon. @@ -687,87 +693,19 @@ void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day) // to time 4000. float tod = wicked_time_of_day < 0.5f ? wicked_time_of_day : (1.0f - wicked_time_of_day); - float starbrightness = clamp((0.25f - fabsf(tod)) * 20.0f, 0.0f, 1.0f); - - float f = starbrightness; - float d = (0.006 / 2) * m_star_params.scale; - - video::SColor starcolor = m_star_params.starcolor; - starcolor.setAlpha(f * m_star_params.starcolor.getAlpha()); - - // Stars are only drawn when not fully transparent - if (m_star_params.starcolor.getAlpha() < 1) + float starbrightness = (0.25f - fabsf(tod)) * 20.0f; + int alpha = clamp(starbrightness * m_star_params.starcolor.getAlpha(), 0, 255); + if (!alpha) // Stars are only drawn when not fully transparent return; -#if ENABLE_GLES - u16 *indices = new u16[m_star_params.count * 3]; - video::S3DVertex *vertices = - new video::S3DVertex[m_star_params.count * 3]; - for (u32 i = 0; i < m_star_params.count; i++) { - indices[i * 3 + 0] = i * 3 + 0; - indices[i * 3 + 1] = i * 3 + 1; - indices[i * 3 + 2] = i * 3 + 2; - v3f r = m_stars[i]; - core::CMatrix4 a; - a.buildRotateFromTo(v3f(0, 1, 0), r); - v3f p = v3f(-d, 1, -d); - v3f p1 = v3f(d, 1, 0); - v3f p2 = v3f(-d, 1, d); - a.rotateVect(p); - a.rotateVect(p1); - a.rotateVect(p2); - p.rotateXYBy(wicked_time_of_day * 360 - 90); - p1.rotateXYBy(wicked_time_of_day * 360 - 90); - p2.rotateXYBy(wicked_time_of_day * 360 - 90); - vertices[i * 3 + 0].Pos = p; - vertices[i * 3 + 0].Color = starcolor; - vertices[i * 3 + 1].Pos = p1; - vertices[i * 3 + 1].Color = starcolor; - vertices[i * 3 + 2].Pos = p2; - vertices[i * 3 + 2].Color = starcolor; - } - driver->drawIndexedTriangleList(vertices, m_star_params.count * 3, - indices, m_star_params.count); - delete[] indices; - delete[] vertices; -#else - u16 *indices = new u16[m_star_params.count * 4]; - video::S3DVertex *vertices = - new video::S3DVertex[m_star_params.count * 4]; - for (u32 i = 0; i < m_star_params.count; i++) { - indices[i * 4 + 0] = i * 4 + 0; - indices[i * 4 + 1] = i * 4 + 1; - indices[i * 4 + 2] = i * 4 + 2; - indices[i * 4 + 3] = i * 4 + 3; - v3f r = m_stars[i]; - core::CMatrix4 a; - a.buildRotateFromTo(v3f(0, 1, 0), r); - v3f p = v3f(-d, 1, -d); - v3f p1 = v3f(d, 1, -d); - v3f p2 = v3f(d, 1, d); - v3f p3 = v3f(-d, 1, d); - a.rotateVect(p); - a.rotateVect(p1); - a.rotateVect(p2); - a.rotateVect(p3); - p.rotateXYBy(wicked_time_of_day * 360 - 90); - p1.rotateXYBy(wicked_time_of_day * 360 - 90); - p2.rotateXYBy(wicked_time_of_day * 360 - 90); - p3.rotateXYBy(wicked_time_of_day * 360 - 90); - vertices[i * 4 + 0].Pos = p; - vertices[i * 4 + 0].Color = starcolor; - vertices[i * 4 + 1].Pos = p1; - vertices[i * 4 + 1].Color = starcolor; - vertices[i * 4 + 2].Pos = p2; - vertices[i * 4 + 2].Color = starcolor; - vertices[i * 4 + 3].Pos = p3; - vertices[i * 4 + 3].Color = starcolor; - } - driver->drawVertexPrimitiveList(vertices, m_star_params.count * 4, - indices, m_star_params.count, video::EVT_STANDARD, - scene::EPT_QUADS, video::EIT_16BIT); - delete[] indices; - delete[] vertices; -#endif + + m_materials[0].DiffuseColor = video::SColor(alpha, 0, 0, 0); + m_materials[0].EmissiveColor = m_star_params.starcolor; + auto sky_rotation = core::matrix4().setRotationAxisRadians(2.0f * M_PI * (wicked_time_of_day - 0.25f), v3f(0.0f, 0.0f, 1.0f)); + auto world_matrix = driver->getTransform(video::ETS_WORLD); + driver->setTransform(video::ETS_WORLD, world_matrix * sky_rotation); + driver->setMaterial(m_materials[0]); + driver->drawMeshBuffer(m_stars.get()); + driver->setTransform(video::ETS_WORLD, world_matrix); } void Sky::draw_sky_body(std::array &vertices, float pos_1, float pos_2, const video::SColor &c) @@ -822,7 +760,7 @@ void Sky::setSunTexture(std::string sun_texture, m_sun_texture = tsrc->getTextureForMesh(m_sun_params.texture); if (m_sun_texture) { - m_materials[3] = m_materials[0]; + m_materials[3] = baseMaterial(); m_materials[3].setTexture(0, m_sun_texture); m_materials[3].MaterialType = video:: EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -870,7 +808,7 @@ void Sky::setMoonTexture(std::string moon_texture, m_moon_texture = tsrc->getTextureForMesh(m_moon_params.texture); if (m_moon_texture) { - m_materials[4] = m_materials[0]; + m_materials[4] = baseMaterial(); m_materials[4].setTexture(0, m_moon_texture); m_materials[4].MaterialType = video:: EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -892,19 +830,54 @@ void Sky::setStarCount(u16 star_count, bool force_update) // Allow force updating star count at game init. if (m_star_params.count != star_count || force_update) { m_star_params.count = star_count; - m_stars.clear(); - // Rebuild the stars surrounding the camera - for (u16 i = 0; i < star_count; i++) { - v3f star = v3f( - myrand_range(-10000, 10000), - myrand_range(-10000, 10000), - myrand_range(-10000, 10000) - ); - - star.normalize(); - m_stars.emplace_back(star); - } + updateStars(); + } +} + +void Sky::updateStars() { + m_stars.reset(new scene::SMeshBuffer()); + // Stupid IrrLicht doesn’t allow non-indexed rendering, and indexed quad + // rendering is slow due to lack of hardware support. So as indices are + // 16-bit and there are 4 vertices per star... the limit is 2^16/4 = 0x4000. + // That should be well enough actually. + if (m_star_params.count > 0x4000) { + warningstream << "Requested " << m_star_params.count << " stars but " << 0x4000 << " is the max\n"; + m_star_params.count = 0x4000; + } + m_stars->Vertices.reallocate(4 * m_star_params.count); + m_stars->Indices.reallocate(6 * m_star_params.count); + + float d = (0.006 / 2) * m_star_params.scale; + for (u16 i = 0; i < m_star_params.count; i++) { + v3f r = v3f( + myrand_range(-10000, 10000), + myrand_range(-10000, 10000), + myrand_range(-10000, 10000) + ); + core::CMatrix4 a; + a.buildRotateFromTo(v3f(0, 1, 0), r); + v3f p = v3f(-d, 1, -d); + v3f p1 = v3f(d, 1, -d); + v3f p2 = v3f(d, 1, d); + v3f p3 = v3f(-d, 1, d); + a.rotateVect(p); + a.rotateVect(p1); + a.rotateVect(p2); + a.rotateVect(p3); + m_stars->Vertices.push_back(video::S3DVertex(p, {}, {}, {})); + m_stars->Vertices.push_back(video::S3DVertex(p1, {}, {}, {})); + m_stars->Vertices.push_back(video::S3DVertex(p2, {}, {}, {})); + m_stars->Vertices.push_back(video::S3DVertex(p3, {}, {}, {})); + } + for (u16 i = 0; i < m_star_params.count; i++) { + m_stars->Indices.push_back(i * 4 + 0); + m_stars->Indices.push_back(i * 4 + 1); + m_stars->Indices.push_back(i * 4 + 2); + m_stars->Indices.push_back(i * 4 + 2); + m_stars->Indices.push_back(i * 4 + 3); + m_stars->Indices.push_back(i * 4 + 0); } + m_stars->setHardwareMappingHint(scene::EHM_STATIC); } void Sky::setSkyColors(const SkyColor &sky_color) @@ -936,7 +909,7 @@ void Sky::addTextureToSkybox(std::string texture, int material_id, // Keep a list of texture names handy. m_sky_params.textures.emplace_back(texture); video::ITexture *result = tsrc->getTextureForMesh(texture); - m_materials[material_id+5] = m_materials[0]; + m_materials[material_id+5] = baseMaterial(); m_materials[material_id+5].setTexture(0, result); m_materials[material_id+5].MaterialType = video::EMT_SOLID; } diff --git a/src/client/sky.h b/src/client/sky.h index 3227e8f59..176545015 100644 --- a/src/client/sky.h +++ b/src/client/sky.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "camera.h" #include "irrlichttypes_extrabloated.h" +#include "irr_ptr.h" #include "skyparams.h" #pragma once @@ -77,7 +78,7 @@ public: void setStarsVisible(bool stars_visible) { m_star_params.visible = stars_visible; } void setStarCount(u16 star_count, bool force_update); void setStarColor(video::SColor star_color) { m_star_params.starcolor = star_color; } - void setStarScale(f32 star_scale) { m_star_params.scale = star_scale; } + void setStarScale(f32 star_scale) { m_star_params.scale = star_scale; updateStars(); } bool getCloudsVisible() const { return m_clouds_visible && m_clouds_enabled; } const video::SColorf &getCloudColor() const { return m_cloudcolor_f; } @@ -178,13 +179,16 @@ private: bool m_default_tint = true; - std::vector m_stars; + irr_ptr m_stars; video::ITexture *m_sun_texture; video::ITexture *m_moon_texture; video::ITexture *m_sun_tonemap; video::ITexture *m_moon_tonemap; + void updateStars(); + void updateStarsColor(video::SColor color); + void draw_sun(video::IVideoDriver *driver, float sunsize, const video::SColor &suncolor, const video::SColor &suncolor2, float wicked_time_of_day); void draw_moon(video::IVideoDriver *driver, float moonsize, const video::SColor &mooncolor, -- cgit v1.2.3 From 560627eef8c02f8201e639c75fcd5301d3a33077 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 16:41:36 +0300 Subject: Reuse seed when updating stars The only currently relevant parameter is scale which can now be changed without resetting stars position --- src/client/sky.cpp | 8 +++++--- src/client/sky.h | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/client') diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 29a0545ab..cc9fb7d36 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -830,6 +830,7 @@ void Sky::setStarCount(u16 star_count, bool force_update) // Allow force updating star count at game init. if (m_star_params.count != star_count || force_update) { m_star_params.count = star_count; + m_seed = (u64)myrand() << 32 | myrand(); updateStars(); } } @@ -847,12 +848,13 @@ void Sky::updateStars() { m_stars->Vertices.reallocate(4 * m_star_params.count); m_stars->Indices.reallocate(6 * m_star_params.count); + PcgRandom rgen(m_seed); float d = (0.006 / 2) * m_star_params.scale; for (u16 i = 0; i < m_star_params.count; i++) { v3f r = v3f( - myrand_range(-10000, 10000), - myrand_range(-10000, 10000), - myrand_range(-10000, 10000) + rgen.range(-10000, 10000), + rgen.range(-10000, 10000), + rgen.range(-10000, 10000) ); core::CMatrix4 a; a.buildRotateFromTo(v3f(0, 1, 0), r); diff --git a/src/client/sky.h b/src/client/sky.h index 176545015..9f859f961 100644 --- a/src/client/sky.h +++ b/src/client/sky.h @@ -179,6 +179,7 @@ private: bool m_default_tint = true; + u64 m_seed = 0; irr_ptr m_stars; video::ITexture *m_sun_texture; -- cgit v1.2.3 From d7cf40a0ce996985cff20a156c56437f8b64c772 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 16:44:00 +0300 Subject: Replace TriangleFan as poorly supported --- src/client/sky.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/client') diff --git a/src/client/sky.cpp b/src/client/sky.cpp index cc9fb7d36..dda59dd11 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -209,7 +209,7 @@ void Sky::render() const f32 t = 1.0f; const f32 o = 0.0f; - static const u16 indices[4] = {0, 1, 2, 3}; + static const u16 indices[6] = {0, 1, 2, 0, 2, 3}; video::S3DVertex vertices[4]; driver->setMaterial(m_materials[1]); @@ -251,7 +251,7 @@ void Sky::render() vertex.Pos.rotateXZBy(180); } } - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } @@ -277,7 +277,7 @@ void Sky::render() // Switch from -Z (south) to +Z (north) vertex.Pos.rotateXZBy(-180); } - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } @@ -308,7 +308,7 @@ void Sky::render() // Switch from -Z (south) to -X (west) vertex.Pos.rotateXZBy(-90); } - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } // Draw sun @@ -344,7 +344,7 @@ void Sky::render() // Switch from -Z (south) to +Z (north) vertex.Pos.rotateXZBy(-180); } - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } // Draw bottom far cloudy fog thing in front of sun, moon and stars @@ -353,7 +353,7 @@ void Sky::render() vertices[1] = video::S3DVertex( 1, -1.0, -1, 0, 1, 0, c, o, t); vertices[2] = video::S3DVertex( 1, -1.0, 1, 0, 1, 0, c, o, o); vertices[3] = video::S3DVertex(-1, -1.0, 1, 0, 1, 0, c, t, o); - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } } @@ -597,7 +597,7 @@ void Sky::draw_sun(video::IVideoDriver *driver, float sunsize, const video::SCol * wicked_time_of_day: current time of day, to know where should be the sun in the sky */ { - static const u16 indices[4] = {0, 1, 2, 3}; + static const u16 indices[] = {0, 1, 2, 0, 2, 3}; std::array vertices; if (!m_sun_texture) { driver->setMaterial(m_materials[1]); @@ -615,7 +615,7 @@ void Sky::draw_sun(video::IVideoDriver *driver, float sunsize, const video::SCol for (int i = 0; i < 4; i++) { draw_sky_body(vertices, -sunsizes[i], sunsizes[i], colors[i]); place_sky_body(vertices, 90, wicked_time_of_day * 360 - 90); - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } else { driver->setMaterial(m_materials[3]); @@ -627,7 +627,7 @@ void Sky::draw_sun(video::IVideoDriver *driver, float sunsize, const video::SCol c = video::SColor(255, 255, 255, 255); draw_sky_body(vertices, -d, d, c); place_sky_body(vertices, 90, wicked_time_of_day * 360 - 90); - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } @@ -644,7 +644,7 @@ void Sky::draw_moon(video::IVideoDriver *driver, float moonsize, const video::SC * the sky */ { - static const u16 indices[4] = {0, 1, 2, 3}; + static const u16 indices[] = {0, 1, 2, 0, 2, 3}; std::array vertices; if (!m_moon_texture) { driver->setMaterial(m_materials[1]); @@ -668,7 +668,7 @@ void Sky::draw_moon(video::IVideoDriver *driver, float moonsize, const video::SC for (int i = 0; i < 4; i++) { draw_sky_body(vertices, moonsizes_1[i], moonsizes_2[i], colors[i]); place_sky_body(vertices, -90, wicked_time_of_day * 360 - 90); - driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); + driver->drawIndexedTriangleList(&vertices[0], 4, indices, 2); } } else { driver->setMaterial(m_materials[4]); -- cgit v1.2.3 From be59668f4743bb3bf85b37a188ffc1759601c152 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 17:36:59 +0300 Subject: Allow missing shaders --- src/client/shader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 4f6430579..1cec20d2c 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -577,7 +577,6 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaderinfo.name = name; shaderinfo.material_type = material_type; shaderinfo.drawtype = drawtype; - shaderinfo.material = video::EMT_SOLID; switch (material_type) { case TILE_MATERIAL_OPAQUE: case TILE_MATERIAL_LIQUID_OPAQUE: @@ -598,6 +597,7 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; break; } + shaderinfo.material = shaderinfo.base_material; bool enable_shaders = g_settings->getBool("enable_shaders"); if (!enable_shaders) -- cgit v1.2.3 From cdcf7dca7c9afb329d49f2016964f77ac379ed67 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 18:25:41 +0300 Subject: Sky: support GLES2 IrrLicht built-in shader is broken, have to write my own --- client/shaders/stars_shader/opengl_fragment.glsl | 6 ++++++ client/shaders/stars_shader/opengl_vertex.glsl | 4 ++++ src/client/game.cpp | 8 +++++++- src/client/sky.cpp | 15 ++++++++------- src/client/sky.h | 8 ++++++-- 5 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 client/shaders/stars_shader/opengl_fragment.glsl create mode 100644 client/shaders/stars_shader/opengl_vertex.glsl (limited to 'src/client') diff --git a/client/shaders/stars_shader/opengl_fragment.glsl b/client/shaders/stars_shader/opengl_fragment.glsl new file mode 100644 index 000000000..a9ed741bf --- /dev/null +++ b/client/shaders/stars_shader/opengl_fragment.glsl @@ -0,0 +1,6 @@ +uniform vec4 starColor; + +void main(void) +{ + gl_FragColor = starColor; +} diff --git a/client/shaders/stars_shader/opengl_vertex.glsl b/client/shaders/stars_shader/opengl_vertex.glsl new file mode 100644 index 000000000..77c401f34 --- /dev/null +++ b/client/shaders/stars_shader/opengl_vertex.glsl @@ -0,0 +1,4 @@ +void main(void) +{ + gl_Position = mWorldViewProj * inVertexPosition; +} diff --git a/src/client/game.cpp b/src/client/game.cpp index b7bb0a330..2001f0487 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -424,6 +424,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedVertexShaderSetting m_animation_timer_vertex; CachedPixelShaderSetting m_animation_timer_pixel; CachedPixelShaderSetting m_day_light; + CachedPixelShaderSetting m_star_color; CachedPixelShaderSetting m_eye_position_pixel; CachedVertexShaderSetting m_eye_position_vertex; CachedPixelShaderSetting m_minimap_yaw; @@ -456,6 +457,7 @@ public: m_animation_timer_vertex("animationTimer"), m_animation_timer_pixel("animationTimer"), m_day_light("dayLight"), + m_star_color("starColor"), m_eye_position_pixel("eyePosition"), m_eye_position_vertex("eyePosition"), m_minimap_yaw("yawVec"), @@ -507,6 +509,10 @@ public: sunlight.b }; m_day_light.set(dnc, services); + video::SColorf star_color = m_sky->getCurrentStarColor(); + float clr[4] = {star_color.r, star_color.g, star_color.b, star_color.a}; + m_star_color.set(clr, services); + u32 animation_timer = porting::getTimeMs() % 1000000; float animation_timer_f = (float)animation_timer / 100000.f; m_animation_timer_vertex.set(&animation_timer_f, services); @@ -1363,7 +1369,7 @@ bool Game::createClient(const GameStartData &start_data) /* Skybox */ - sky = new Sky(-1, texture_src); + sky = new Sky(-1, texture_src, shader_src); scsf->setSky(sky); skybox = NULL; // This is used/set later on in the main run loop diff --git a/src/client/sky.cpp b/src/client/sky.cpp index dda59dd11..3fc5a95b4 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -51,7 +51,7 @@ static video::SMaterial baseMaterial() { return mat; }; -Sky::Sky(s32 id, ITextureSource *tsrc) : +Sky::Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc) : scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(), RenderingEngine::get_scene_manager(), id) { @@ -59,10 +59,12 @@ Sky::Sky(s32 id, ITextureSource *tsrc) : m_box.MaxEdge.set(0, 0, 0); m_box.MinEdge.set(0, 0, 0); + m_enable_shaders = g_settings->getBool("enable_shaders"); + // Create materials m_materials[0] = baseMaterial(); - m_materials[0].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA, 0)).material; m_materials[0].Lighting = true; m_materials[0].ColorMaterial = video::ECM_NONE; @@ -694,12 +696,11 @@ void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day) float tod = wicked_time_of_day < 0.5f ? wicked_time_of_day : (1.0f - wicked_time_of_day); float starbrightness = (0.25f - fabsf(tod)) * 20.0f; - int alpha = clamp(starbrightness * m_star_params.starcolor.getAlpha(), 0, 255); - if (!alpha) // Stars are only drawn when not fully transparent + m_star_color = m_star_params.starcolor; + m_star_color.a = clamp(starbrightness * m_star_color.a, 0.0f, 1.0f); + if (m_star_color.a <= 0.0f) // Stars are only drawn when not fully transparent return; - - m_materials[0].DiffuseColor = video::SColor(alpha, 0, 0, 0); - m_materials[0].EmissiveColor = m_star_params.starcolor; + m_materials[0].DiffuseColor = m_materials[0].EmissiveColor = m_star_color.toSColor(); auto sky_rotation = core::matrix4().setRotationAxisRadians(2.0f * M_PI * (wicked_time_of_day - 0.25f), v3f(0.0f, 0.0f, 1.0f)); auto world_matrix = driver->getTransform(video::ETS_WORLD); driver->setTransform(video::ETS_WORLD, world_matrix * sky_rotation); diff --git a/src/client/sky.h b/src/client/sky.h index 9f859f961..10e1cd976 100644 --- a/src/client/sky.h +++ b/src/client/sky.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "camera.h" #include "irrlichttypes_extrabloated.h" #include "irr_ptr.h" +#include "shader.h" #include "skyparams.h" #pragma once @@ -35,7 +36,7 @@ class Sky : public scene::ISceneNode { public: //! constructor - Sky(s32 id, ITextureSource *tsrc); + Sky(s32 id, ITextureSource *tsrc, IShaderSource *ssrc); virtual void OnRegisterSceneNode(); @@ -102,6 +103,8 @@ public: void clearSkyboxTextures() { m_sky_params.textures.clear(); } void addTextureToSkybox(std::string texture, int material_id, ITextureSource *tsrc); + const video::SColorf &getCurrentStarColor() const { return m_star_color; } + private: aabb3f m_box; video::SMaterial m_materials[SKY_MATERIAL_COUNT]; @@ -155,6 +158,7 @@ private: bool m_clouds_enabled = true; // Initialised to true, reset only by set_sky API bool m_directional_colored_fog; bool m_in_clouds = true; // Prevent duplicating bools to remember old values + bool m_enable_shaders = false; video::SColorf m_bgcolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); video::SColorf m_skycolor_bright_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); @@ -181,6 +185,7 @@ private: u64 m_seed = 0; irr_ptr m_stars; + video::SColorf m_star_color; video::ITexture *m_sun_texture; video::ITexture *m_moon_texture; @@ -188,7 +193,6 @@ private: video::ITexture *m_moon_tonemap; void updateStars(); - void updateStarsColor(video::SColor color); void draw_sun(video::IVideoDriver *driver, float sunsize, const video::SColor &suncolor, const video::SColor &suncolor2, float wicked_time_of_day); -- cgit v1.2.3 From c158e20e5beab1037c905fe96b2a56baccddaec7 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 22 Nov 2020 19:49:38 +0300 Subject: Provide fallback star color for GLES 2 with MT shaders disabled --- src/client/sky.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/client') diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 3fc5a95b4..0fccf067c 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -849,6 +849,7 @@ void Sky::updateStars() { m_stars->Vertices.reallocate(4 * m_star_params.count); m_stars->Indices.reallocate(6 * m_star_params.count); + video::SColor fallback_color = m_star_params.starcolor; // used on GLES 2 “without shaders” PcgRandom rgen(m_seed); float d = (0.006 / 2) * m_star_params.scale; for (u16 i = 0; i < m_star_params.count; i++) { @@ -867,10 +868,10 @@ void Sky::updateStars() { a.rotateVect(p1); a.rotateVect(p2); a.rotateVect(p3); - m_stars->Vertices.push_back(video::S3DVertex(p, {}, {}, {})); - m_stars->Vertices.push_back(video::S3DVertex(p1, {}, {}, {})); - m_stars->Vertices.push_back(video::S3DVertex(p2, {}, {}, {})); - m_stars->Vertices.push_back(video::S3DVertex(p3, {}, {}, {})); + m_stars->Vertices.push_back(video::S3DVertex(p, {}, fallback_color, {})); + m_stars->Vertices.push_back(video::S3DVertex(p1, {}, fallback_color, {})); + m_stars->Vertices.push_back(video::S3DVertex(p2, {}, fallback_color, {})); + m_stars->Vertices.push_back(video::S3DVertex(p3, {}, fallback_color, {})); } for (u16 i = 0; i < m_star_params.count; i++) { m_stars->Indices.push_back(i * 4 + 0); -- cgit v1.2.3 From 8689e00fca2cf55594d53f4e112f0d7b6676c8b0 Mon Sep 17 00:00:00 2001 From: numzero Date: Mon, 23 Nov 2020 01:04:31 +0300 Subject: Fix style --- src/client/sky.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/client') diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 0fccf067c..180d43066 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -35,7 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "config.h" using namespace irr::core; -static video::SMaterial baseMaterial() { +static video::SMaterial baseMaterial() +{ video::SMaterial mat; mat.Lighting = false; #if ENABLE_GLES @@ -836,7 +837,8 @@ void Sky::setStarCount(u16 star_count, bool force_update) } } -void Sky::updateStars() { +void Sky::updateStars() +{ m_stars.reset(new scene::SMeshBuffer()); // Stupid IrrLicht doesn’t allow non-indexed rendering, and indexed quad // rendering is slow due to lack of hardware support. So as indices are -- cgit v1.2.3 From 868749b4f8e898be0c01f892ea78d859d054c17e Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 26 Nov 2020 22:17:11 +0100 Subject: Return star color calculation to what it previously was --- src/client/sky.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client') diff --git a/src/client/sky.cpp b/src/client/sky.cpp index 180d43066..9a2614eda 100644 --- a/src/client/sky.cpp +++ b/src/client/sky.cpp @@ -698,7 +698,7 @@ void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day) float tod = wicked_time_of_day < 0.5f ? wicked_time_of_day : (1.0f - wicked_time_of_day); float starbrightness = (0.25f - fabsf(tod)) * 20.0f; m_star_color = m_star_params.starcolor; - m_star_color.a = clamp(starbrightness * m_star_color.a, 0.0f, 1.0f); + m_star_color.a *= clamp(starbrightness, 0.0f, 1.0f); if (m_star_color.a <= 0.0f) // Stars are only drawn when not fully transparent return; m_materials[0].DiffuseColor = m_materials[0].EmissiveColor = m_star_color.toSColor(); -- cgit v1.2.3