diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a3df4ce6..2de45d90f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") # Also remember to set PROTOCOL_VERSION in clientserver.h when releasing set(VERSION_MAJOR 0) set(VERSION_MINOR 4) -set(VERSION_PATCH 4-dev) +set(VERSION_PATCH 4) if(VERSION_EXTRA) set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA}) endif() diff --git a/README.txt b/README.txt index 82240479e..8c5a46223 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -Minetest-c55 +Minetest ============ An InfiniMiner/Minecraft inspired game. @@ -15,9 +15,10 @@ See the README.txt in it. Further documentation ---------------------- -- Website: http://c55.me/minetest/ -- Wiki: http://c55.me/minetest/wiki/ -- Forum: http://c55.me/minetest/forum/ +- Website: http://minetest.net/ +- Wiki: http://wiki.minetest.com/ +- Developer wiki: http://minetest.net/wiki/ +- Forum: http://minetest.net/forum/ - Github: https://github.com/celeron55/minetest/ - doc/ directory of source distribution @@ -128,8 +129,8 @@ Compiling on Windows: * Optional: gettext bibrary and tools: http://gnuwin32.sourceforge.net/downlinks/gettext.php - This is used for other UI languages. Feel free to leave it out. - * And, of course, Minetest-c55: - http://c55.me/minetest/download + * And, of course, Minetest: + http://minetest.net/download.php - Steps: - Select a directory called DIR hereafter in which you will operate. - Make sure you have CMake and a compiler installed. @@ -244,19 +245,19 @@ popd echo Failed. exit /b 1 -License of Minetest-c55 textures and sounds -------------------------------------------- +License of Minetest textures and sounds +--------------------------------------- This applies to textures and sounds contained in the main Minetest distribution. -Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) http://creativecommons.org/licenses/by-sa/3.0/ -License of Minetest-c55 source code ------------------------------------ +License of Minetest source code +------------------------------- -Minetest-c55 +Minetest Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify diff --git a/builtin/item.lua b/builtin/item.lua index 4be77e1d7..80c665c99 100644 --- a/builtin/item.lua +++ b/builtin/item.lua @@ -76,10 +76,10 @@ function minetest.get_node_drops(nodename, toolname) local drop = ItemStack({name=nodename}):get_definition().drop if drop == nil then -- default drop - return {ItemStack({name=nodename})} + return {nodename} elseif type(drop) == "string" then -- itemstring drop - return {ItemStack(drop)} + return {drop} elseif drop.items == nil then -- drop = {} to disable default drop return {} diff --git a/builtin/privileges.lua b/builtin/privileges.lua index 9ec09d7f6..8dd06b24f 100644 --- a/builtin/privileges.lua +++ b/builtin/privileges.lua @@ -44,5 +44,9 @@ minetest.register_privilege("fast", { description = "Can walk fast using the fast_move mode", give_to_singleplayer = false, }) +minetest.register_privilege("noclip", { + description = "Can fly through walls", + give_to_singleplayer = false, +}) minetest.register_privilege("rollback", "Can use the rollback functionality") diff --git a/client/shaders/test_shader_1/opengl_vertex.glsl b/client/shaders/test_shader_1/opengl_vertex.glsl index 498085053..3cf1f122b 100644 --- a/client/shaders/test_shader_1/opengl_vertex.glsl +++ b/client/shaders/test_shader_1/opengl_vertex.glsl @@ -2,6 +2,7 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform float dayNightRatio; varying vec3 vPosition; @@ -11,15 +12,47 @@ void main(void) vPosition = (mWorldViewProj * gl_Vertex).xyz; - if(gl_Normal.y > 0.5) - gl_FrontColor = gl_BackColor = gl_Color; - else - gl_FrontColor = gl_BackColor = gl_Color * 0.7; + vec4 color; + //color = vec4(1.0, 1.0, 1.0, 1.0); - /*if(gl_Normal.y > 0.5) - gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0); - else - gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0) * 0.7;*/ + float day = gl_Color.r; + float night = gl_Color.g; + float light_source = gl_Color.b; + + /*color.r = mix(night, day, dayNightRatio); + color.g = color.r; + color.b = color.r;*/ + + float rg = mix(night, day, dayNightRatio); + rg += light_source * 1.0; // Make light sources brighter + float b = rg; + + // Moonlight is blue + b += (day - night) / 13.0; + rg -= (day - night) / 13.0; + + // Emphase blue a bit in darker places + // See C++ implementation in mapblock_mesh.cpp finalColorBlend() + b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025); + + // Artificial light is yellow-ish + // See C++ implementation in mapblock_mesh.cpp finalColorBlend() + rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065); + + color.r = rg; + color.g = rg; + color.b = b; + + // Make sides and bottom darker than the top + color = color * color; // SRGB -> Linear + if(gl_Normal.y <= 0.5) + color *= 0.6; + //color *= 0.7; + color = sqrt(color); // Linear -> SRGB + + color.a = gl_Color.a; + + gl_FrontColor = gl_BackColor = color; gl_TexCoord[0] = gl_MultiTexCoord0; } diff --git a/client/shaders/test_shader_2/opengl_vertex.glsl b/client/shaders/test_shader_2/opengl_vertex.glsl index 6286fc0d7..80fd6d427 100644 --- a/client/shaders/test_shader_2/opengl_vertex.glsl +++ b/client/shaders/test_shader_2/opengl_vertex.glsl @@ -2,6 +2,7 @@ uniform mat4 mWorldViewProj; uniform mat4 mInvWorld; uniform mat4 mTransWorld; +uniform float dayNightRatio; varying vec3 vPosition; @@ -13,8 +14,40 @@ void main(void) vPosition = (mWorldViewProj * gl_Vertex).xyz; - gl_FrontColor = gl_BackColor = gl_Color; - //gl_FrontColor = gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0); + vec4 color; + //color = vec4(1.0, 1.0, 1.0, 1.0); + + float day = gl_Color.r; + float night = gl_Color.g; + float light_source = gl_Color.b; + + /*color.r = mix(night, day, dayNightRatio); + color.g = color.r; + color.b = color.r;*/ + + float rg = mix(night, day, dayNightRatio); + rg += light_source * 1.0; // Make light sources brighter + float b = rg; + + // Moonlight is blue + b += (day - night) / 13.0; + rg -= (day - night) / 13.0; + + // Emphase blue a bit in darker places + // See C++ implementation in mapblock_mesh.cpp finalColorBlend() + b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025); + + // Artificial light is yellow-ish + // See C++ implementation in mapblock_mesh.cpp finalColorBlend() + rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065); + + color.r = rg; + color.g = rg; + color.b = b; + + color.a = gl_Color.a; + + gl_FrontColor = gl_BackColor = color; gl_TexCoord[0] = gl_MultiTexCoord0; } diff --git a/minetest.conf.example b/minetest.conf.example index 3ca794cc8..a0aa69125 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -135,7 +135,7 @@ #bilinear_filter = false #trilinear_filter = false # Set to true to pre-generate all item visuals -#preload_item_visuals = false +#preload_item_visuals = true # 0: disable shaders # (1: low level shaders; not implemented) # 2: enable high level shaders diff --git a/src/base64.h b/src/base64.h index a29e69687..5f2d6743d 100644 --- a/src/base64.h +++ b/src/base64.h @@ -1,5 +1,10 @@ +#ifndef BASE64_HEADER +#define BASE64_HEADER + #include bool base64_is_valid(std::string const& s); std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); + +#endif // BASE64_HEADER \ No newline at end of file diff --git a/src/camera.cpp b/src/camera.cpp index ca2a6eb53..1b9a8c763 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -544,7 +544,7 @@ void Camera::wield(const ItemStack &item) void Camera::drawWieldedTool() { // Set vertex colors of wield mesh according to light level - u8 li = decode_light(m_wieldlight); + u8 li = m_wieldlight; video::SColor color(255,li,li,li); setMeshColor(m_wieldnode->getMesh(), color); diff --git a/src/client.cpp b/src/client.cpp index 865cf71ee..3463e9262 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1976,10 +1976,24 @@ void Client::sendPlayerPos() { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - Player *myplayer = m_env.getLocalPlayer(); + LocalPlayer *myplayer = m_env.getLocalPlayer(); if(myplayer == NULL) return; - + + // Save bandwidth by only updating position when something changed + if(myplayer->last_position == myplayer->getPosition() && + myplayer->last_speed == myplayer->getSpeed() && + myplayer->last_pitch == myplayer->getPitch() && + myplayer->last_yaw == myplayer->getYaw() && + myplayer->last_keyPressed == myplayer->keyPressed) + return; + + myplayer->last_position = myplayer->getPosition(); + myplayer->last_speed = myplayer->getSpeed(); + myplayer->last_pitch = myplayer->getPitch(); + myplayer->last_yaw = myplayer->getYaw(); + myplayer->last_keyPressed = myplayer->keyPressed; + u16 our_peer_id; { //JMutexAutoLock lock(m_con_mutex); //bulk comment-out diff --git a/src/clientmap.cpp b/src/clientmap.cpp index 02c9fe9b1..800549a3b 100644 --- a/src/clientmap.cpp +++ b/src/clientmap.cpp @@ -352,13 +352,17 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver) if(sector_blocks_drawn != 0) m_last_drawn_sectors[sp] = true; } - + + m_control.blocks_would_have_drawn = blocks_would_have_drawn; + m_control.blocks_drawn = blocks_drawn; + g_profiler->avg("CM: blocks in range", blocks_in_range); g_profiler->avg("CM: blocks occlusion culled", blocks_occlusion_culled); if(blocks_in_range != 0) g_profiler->avg("CM: blocks in range without mesh (frac)", (float)blocks_in_range_without_mesh/blocks_in_range); g_profiler->avg("CM: blocks drawn", blocks_drawn); + g_profiler->avg("CM: wanted max blocks", m_control.wanted_max_blocks); } struct MeshBufList @@ -467,9 +471,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) u32 mesh_animate_count = 0; u32 mesh_animate_count_far = 0; - // Blocks that had mesh that would have been drawn according to - // rendering range (if max blocks limit didn't kick in) - u32 blocks_would_have_drawn = 0; // Blocks that were drawn and had a mesh u32 blocks_drawn = 0; // Blocks which had a corresponding meshbuffer for this pass @@ -665,9 +666,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) g_profiler->avg(prefix+"empty blocks (frac)", (float)blocks_without_stuff / blocks_drawn); - m_control.blocks_drawn = blocks_drawn; - m_control.blocks_would_have_drawn = blocks_would_have_drawn; - /*infostream<<"renderMap(): is_transparent_pass="<= 19500) - return 150; - else if(t < 4750 || t >= 19250) - return 250; - else if(t < 5000 || t >= 19000) - return 350; - else if(t < 5250 || t >= 18750) - return 500; - else if(t < 5500 || t >= 18500) - return 675; - else if(t < 5750 || t >= 18250) - return 875; - else + float t = time_of_day; + if(t < 0) + t += ((int)(-t)/24000)*24000; + if(t >= 24000) + t -= ((int)(t)/24000)*24000; + if(t > 12000) + t = 24000 - t; + float values[][2] = { + {4250+125, 150}, + {4500+125, 150}, + {4750+125, 250}, + {5000+125, 350}, + {5250+125, 500}, + {5500+125, 675}, + {5750+125, 875}, + {6000+125, 1000}, + {6250+125, 1000}, + }; + if(!smooth){ + float lastt = values[0][0]; + for(u32 i=1; isetDefault("keymap_rangeselect", "KEY_KEY_R"); settings->setDefault("keymap_freemove", "KEY_KEY_K"); settings->setDefault("keymap_fastmove", "KEY_KEY_J"); + settings->setDefault("keymap_noclip", "KEY_KEY_H"); settings->setDefault("keymap_screenshot", "KEY_F12"); settings->setDefault("keymap_toggle_hud", "KEY_F1"); settings->setDefault("keymap_toggle_chat", "KEY_F2"); @@ -73,7 +74,7 @@ void set_default_settings(Settings *settings) settings->setDefault("wanted_fps", "30"); settings->setDefault("fps_max", "60"); // A bit more than the server will send around the player, to make fog blend well - settings->setDefault("viewing_range_nodes_max", "160"); + settings->setDefault("viewing_range_nodes_max", "240"); settings->setDefault("viewing_range_nodes_min", "35"); settings->setDefault("screenW", "800"); settings->setDefault("screenH", "600"); @@ -95,6 +96,7 @@ void set_default_settings(Settings *settings) settings->setDefault("shader_path", ""); settings->setDefault("video_driver", "opengl"); settings->setDefault("free_move", "false"); + settings->setDefault("noclip", "false"); settings->setDefault("continuous_forward", "false"); settings->setDefault("fast_move", "false"); settings->setDefault("invert_mouse", "false"); @@ -114,7 +116,7 @@ void set_default_settings(Settings *settings) settings->setDefault("anisotropic_filter", "false"); settings->setDefault("bilinear_filter", "false"); settings->setDefault("trilinear_filter", "false"); - settings->setDefault("preload_item_visuals", "false"); + settings->setDefault("preload_item_visuals", "true"); settings->setDefault("enable_shaders", "2"); // Server stuff diff --git a/src/environment.cpp b/src/environment.cpp index 0473c71e2..24561d902 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -203,7 +203,8 @@ void Environment::printPlayers(std::ostream &o) u32 Environment::getDayNightRatio() { - return time_to_daynight_ratio(m_time_of_day); + bool smooth = (g_settings->getS32("enable_shaders") != 0); + return time_to_daynight_ratio(m_time_of_day_f*24000, smooth); } void Environment::stepTimeOfDay(float dtime) @@ -2132,15 +2133,15 @@ void ClientEnvironment::step(float dtime) } // Update lighting on all players on client - u8 light = LIGHT_MAX; + float light = 1.0; try{ // Get node at head v3s16 p = player->getLightPosition(); MapNode n = m_map->getNode(p); - light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef()); + light = n.getLightBlendF1((float)getDayNightRatio()/1000, m_gamedef->ndef()); } catch(InvalidPositionException &e){ - light = blend_light(getDayNightRatio(), LIGHT_SUN, 0); + light = blend_light_f1((float)getDayNightRatio()/1000, LIGHT_SUN, 0); } player->light = light; } diff --git a/src/game.cpp b/src/game.cpp index 0c1a21370..dbb71369f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -841,13 +841,15 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter Sky *m_sky; bool *m_force_fog_off; f32 *m_fog_range; + Client *m_client; public: GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off, - f32 *fog_range): + f32 *fog_range, Client *client): m_sky(sky), m_force_fog_off(force_fog_off), - m_fog_range(fog_range) + m_fog_range(fog_range), + m_client(client) {} ~GameGlobalShaderConstantSetter() {} @@ -873,10 +875,12 @@ public: if(*m_force_fog_off) fog_distance = 10000*BS; services->setPixelShaderConstant("fogDistance", &fog_distance, 1); - } -private: - IrrlichtDevice *m_device; + // Day-night ratio + u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); + float daynight_ratio_f = (float)daynight_ratio / 1000.0; + services->setPixelShaderConstant("dayNightRatio", &daynight_ratio_f, 1); + } }; void the_game( @@ -1210,7 +1214,7 @@ void the_game( // First line of debug text gui::IGUIStaticText *guitext = guienv->addStaticText( - L"Minetest-c55", + L"Minetest", core::rect(5, 5, 795, 5+text_height), false, false); // Second line of debug text @@ -1307,8 +1311,8 @@ void the_game( /* Shader constants */ - shsrc->addGlobalConstantSetter( - new GameGlobalShaderConstantSetter(sky, &force_fog_off, &fog_range)); + shsrc->addGlobalConstantSetter(new GameGlobalShaderConstantSetter( + sky, &force_fog_off, &fog_range, &client)); /* Main loop @@ -1661,6 +1665,23 @@ void the_game( statustext += L" (note: no 'fast' privilege)"; } } + else if(input->wasKeyDown(getKeySetting("keymap_noclip"))) + { + if(g_settings->getBool("noclip")) + { + g_settings->set("noclip","false"); + statustext = L"noclip disabled"; + statustext_time = 0; + } + else + { + g_settings->set("noclip","true"); + statustext = L"noclip enabled"; + statustext_time = 0; + if(!client.checkPrivilege("noclip")) + statustext += L" (note: no 'noclip' privilege)"; + } + } else if(input->wasKeyDown(getKeySetting("keymap_screenshot"))) { irr::video::IImage* const image = driver->createScreenShot(); @@ -2501,8 +2522,7 @@ void the_game( Calculate general brightness */ u32 daynight_ratio = client.getEnv().getDayNightRatio(); - float time_brightness = (float)decode_light( - (daynight_ratio * LIGHT_SUN) / 1000) / 255.0; + float time_brightness = decode_light_f((float)daynight_ratio/1000.0); float direct_brightness = 0; bool sunlight_seen = false; if(g_settings->getBool("free_move")){ @@ -2604,7 +2624,7 @@ void the_game( //TimeTaker guiupdatetimer("Gui updating"); const char program_name_and_version[] = - "Minetest-c55 " VERSION_STRING; + "Minetest " VERSION_STRING; if(show_debug) { @@ -2955,11 +2975,6 @@ void the_game( //timer10.stop(); //TimeTaker //timer11("//timer11"); - /* - Draw gui - */ - // 0-1ms - guienv->drawAll(); /* Draw hotbar @@ -2985,6 +3000,12 @@ void the_game( NULL); } + /* + Draw gui + */ + // 0-1ms + guienv->drawAll(); + /* End scene */ diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp index 405a81e0b..8f7c7245c 100644 --- a/src/guiKeyChangeMenu.cpp +++ b/src/guiKeyChangeMenu.cpp @@ -46,6 +46,7 @@ enum GUI_ID_KEY_FLY_BUTTON, GUI_ID_KEY_FAST_BUTTON, GUI_ID_KEY_JUMP_BUTTON, + GUI_ID_KEY_NOCLIP_BUTTON, GUI_ID_KEY_CHAT_BUTTON, GUI_ID_KEY_CMD_BUTTON, GUI_ID_KEY_CONSOLE_BUTTON, @@ -362,6 +363,7 @@ void GUIKeyChangeMenu::init_keys() this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, "Console", "keymap_console"); this->add_key(GUI_ID_KEY_FLY_BUTTON, "Toggle fly", "keymap_freemove"); this->add_key(GUI_ID_KEY_FAST_BUTTON, "Toggle fast", "keymap_fastmove"); + this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, "Toggle noclip", "keymap_noclip"); this->add_key(GUI_ID_KEY_RANGE_BUTTON, "Range select", "keymap_rangeselect"); this->add_key(GUI_ID_KEY_DUMP_BUTTON, "Print stacks", "keymap_print_debug_stacks"); } diff --git a/src/guiMainMenu.cpp b/src/guiMainMenu.cpp index c711577b0..d7c3f54ff 100644 --- a/src/guiMainMenu.cpp +++ b/src/guiMainMenu.cpp @@ -208,7 +208,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize) core::rect rect(0, 0, size.X, 40); rect += v2s32(4, 0); Environment->addStaticText(narrow_to_wide( - "Minetest-c55 " VERSION_STRING).c_str(), + "Minetest " VERSION_STRING).c_str(), rect, false, true, this, -1); } @@ -659,11 +659,11 @@ void GUIMainMenu::regenerateGui(v2u32 screensize) core::rect rect(0, 0, 454, 250); rect += m_topleft_client + v2s32(110, 50+35); Environment->addStaticText(narrow_to_wide( - "Minetest-c55 " VERSION_STRING "\n" + "Minetest " VERSION_STRING "\n" "http://minetest.net/\n" "\n" "by Perttu Ahola \n" - "and contributors: tango_, kahrl (kaaaaaahrl?), erlehmann (the hippie), SpeedProg, JacobF (sqlite worlds), teddydestodes, marktraceur, darkrose, Jonathan Neuschäfer (who the hell?), Felix Krausse (broke liquids, IIRC), sfan5... and >10 more random people." + "and contributors: PilzAdam, Taoki, tango_, kahrl (kaaaaaahrl?), darkrose, matttpt, erlehmann, SpeedProg, JacobF, teddydestodes, marktraceur, Jonathan Neuschäfer, thexyz, VanessaE, sfan5... and tens of more random people." ).c_str(), rect, false, true, this, -1); } } diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp index 96fd7d676..c800cf952 100644 --- a/src/guiPauseMenu.cpp +++ b/src/guiPauseMenu.cpp @@ -169,23 +169,8 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize) max_texture_size = driver->getMaxTextureSize(); } - /*wchar_t text[200]; - swprintf(text, 200, - L"Minetest-c55\n" - L"by Perttu Ahola\n" - L"celeron55@gmail.com\n\n" - SWPRINTF_CHARSTRING L"\n" - L"userdata path = " - SWPRINTF_CHARSTRING - , - BUILD_INFO, - porting::path_user.c_str() - );*/ - std::ostringstream os; os<<"Minetest\n"; - os<<"by Perttu Ahola and contributors\n"; - os<<"celeron55@gmail.com\n"; os<getS32("enable_shaders") != 0) + c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source)); + setMeshColor(node_mesh, c); /* Scale and translate the mesh so it's a unit cube diff --git a/src/light.h b/src/light.h index 218af348e..f1c458ad8 100644 --- a/src/light.h +++ b/src/light.h @@ -85,6 +85,24 @@ inline u8 decode_light(u8 light) return light_decode_table[light]; } +// 0.0 <= light <= 1.0 +// 0.0 <= return value <= 1.0 +inline float decode_light_f(float light_f) +{ + s32 i = (u32)(light_f * LIGHT_MAX + 0.5); + + if(i <= 0) + return (float)light_decode_table[0] / 255.0; + if(i >= LIGHT_MAX) + return (float)light_decode_table[LIGHT_MAX] / 255.0; + + float v1 = (float)light_decode_table[i-1] / 255.0; + float v2 = (float)light_decode_table[i] / 255.0; + float f0 = (float)i - 0.5; + float f = light_f * LIGHT_MAX - f0; + return f * v2 + (1.0 - f) * v1; +} + // 0 <= daylight_factor <= 1000 // 0 <= lightday, lightnight <= LIGHT_SUN // 0 <= return value <= LIGHT_SUN @@ -97,5 +115,15 @@ inline u8 blend_light(u32 daylight_factor, u8 lightday, u8 lightnight) return l; } +// 0.0 <= daylight_factor <= 1.0 +// 0 <= lightday, lightnight <= LIGHT_SUN +// 0 <= return value <= 255 +inline u8 blend_light_f1(float daylight_factor, u8 lightday, u8 lightnight) +{ + u8 l = ((daylight_factor * decode_light(lightday) + + (1.0-daylight_factor) * decode_light(lightnight))); + return l; +} + #endif diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 17c4cdeb9..96ddb4bb2 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -36,6 +36,11 @@ LocalPlayer::LocalPlayer(IGameDef *gamedef): Player(gamedef), isAttached(false), overridePosition(v3f(0,0,0)), + last_position(v3f(0,0,0)), + last_speed(v3f(0,0,0)), + last_pitch(0), + last_yaw(0), + last_keyPressed(0), m_sneak_node(32767,32767,32767), m_sneak_node_exists(false), m_old_node_below(32767,32767,32767), @@ -68,9 +73,11 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, return; } - // Skip collision detection if a special movement mode is used + // Skip collision detection if noclip mode is used bool fly_allowed = m_gamedef->checkLocalPrivilege("fly"); - bool free_move = fly_allowed && g_settings->getBool("free_move"); + bool noclip = m_gamedef->checkLocalPrivilege("noclip") && + g_settings->getBool("noclip"); + bool free_move = noclip && fly_allowed && g_settings->getBool("free_move"); if(free_move) { position += m_speed * dtime; @@ -295,7 +302,8 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, Report collisions */ bool bouncy_jump = false; - if(collision_info) + // Dont report if flying + if(collision_info && !g_settings->getBool("free_move")) { for(size_t i=0; isetColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0)); skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255,70,100,50)); skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255,255,255,255)); - + +#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2 + // Irrlicht 1.8 input colours + skin->setColor(gui::EGDC_EDITABLE, video::SColor(255,128,128,128)); + skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255,96,134,49)); +#endif + /* GUI stuff */ diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index a9f14f8f0..daebbe217 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -32,6 +32,16 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "util/directiontables.h" +float srgb_linear_multiply(float f, float m, float max) +{ + f = f * f; // SRGB -> Linear + f *= m; + f = sqrt(f); // Linear -> SRGB + if(f > max) + f = max; + return f; +} + /* MeshMakeData */ @@ -435,7 +445,7 @@ struct FastFace }; static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, - v3f p, v3s16 dir, v3f scale, core::array &dest) + v3f p, v3s16 dir, v3f scale, u8 light_source, core::array &dest) { FastFace face; @@ -477,16 +487,16 @@ static void makeFastFace(TileSpec tile, u16 li0, u16 li1, u16 li2, u16 li3, float h = tile.texture.size.Y; face.vertices[0] = video::S3DVertex(vertex_pos[0], normal, - MapBlock_LightColor(alpha, li0), + MapBlock_LightColor(alpha, li0, light_source), core::vector2d(x0+w*abs_scale, y0+h)); face.vertices[1] = video::S3DVertex(vertex_pos[1], normal, - MapBlock_LightColor(alpha, li1), + MapBlock_LightColor(alpha, li1, light_source), core::vector2d(x0, y0+h)); face.vertices[2] = video::S3DVertex(vertex_pos[2], normal, - MapBlock_LightColor(alpha, li2), + MapBlock_LightColor(alpha, li2, light_source), core::vector2d(x0, y0)); face.vertices[3] = video::S3DVertex(vertex_pos[3], normal, - MapBlock_LightColor(alpha, li3), + MapBlock_LightColor(alpha, li3, light_source), core::vector2d(x0+w*abs_scale, y0)); face.tile = tile; @@ -658,7 +668,8 @@ static void getTileInfo( v3s16 &p_corrected, v3s16 &face_dir_corrected, u16 *lights, - TileSpec &tile + TileSpec &tile, + u8 &light_source ) { VoxelManipulator &vmanip = data->m_vmanip; @@ -688,18 +699,20 @@ static void getTileInfo( tile = tile0; p_corrected = p; face_dir_corrected = face_dir; + light_source = ndef->get(n0).light_source; } else { tile = tile1; p_corrected = p + face_dir; face_dir_corrected = -face_dir; + light_source = ndef->get(n1).light_source; } // eg. water and glass if(equivalent) tile.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - + if(data->m_smooth_lighting == false) { lights[0] = lights[1] = lights[2] = lights[3] = @@ -743,9 +756,10 @@ static void updateFastFaceRow( v3s16 face_dir_corrected; u16 lights[4] = {0,0,0,0}; TileSpec tile; + u8 light_source = 0; getTileInfo(data, p, face_dir, makes_face, p_corrected, face_dir_corrected, - lights, tile); + lights, tile, light_source); for(u16 j=0; javg("Meshgen: faces drawn by tiling", 0); @@ -873,6 +889,7 @@ static void updateFastFaceRow( lights[2] = next_lights[2]; lights[3] = next_lights[3]; tile = next_tile; + light_source = next_light_source; } p = p_next; @@ -1058,18 +1075,28 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data): os<<"^[verticalframe:"<<(int)p.tile.animation_frame_count<<":0"; p.tile.texture = tsrc->getTexture(os.str()); } - // - Lighting - for(u32 j = 0; j < p.vertices.size(); j++) + // - Classic lighting (shaders handle this by themselves) + if(!enable_shaders) { - video::SColor &vc = p.vertices[j].Color; - u8 day = vc.getRed(); - u8 night = vc.getGreen(); - finalColorBlend(vc, day, night, 1000); - if(day != night) - m_daynight_diffs[i][j] = std::make_pair(day, night); + for(u32 j = 0; j < p.vertices.size(); j++) + { + video::SColor &vc = p.vertices[j].Color; + // Set initial real color and store for later updates + u8 day = vc.getRed(); + u8 night = vc.getGreen(); + finalColorBlend(vc, day, night, 1000); + if(day != night) + m_daynight_diffs[i][j] = std::make_pair(day, night); + // Brighten topside (no shaders) + if(p.vertices[j].Normal.Y > 0.5) + { + vc.setRed (srgb_linear_multiply(vc.getRed(), 1.3, 255.0)); + vc.setGreen(srgb_linear_multiply(vc.getGreen(), 1.3, 255.0)); + vc.setBlue (srgb_linear_multiply(vc.getBlue(), 1.3, 255.0)); + } + } } - // Create material video::SMaterial material; material.setFlag(video::EMF_LIGHTING, false); @@ -1220,6 +1247,14 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat u8 night = j->second.second; finalColorBlend(vertices[vertexIndex].Color, day, night, daynight_ratio); + // Brighten topside (no shaders) + if(vertices[vertexIndex].Normal.Y > 0.5) + { + video::SColor &vc = vertices[vertexIndex].Color; + vc.setRed (srgb_linear_multiply(vc.getRed(), 1.3, 255.0)); + vc.setGreen(srgb_linear_multiply(vc.getGreen(), 1.3, 255.0)); + vc.setBlue (srgb_linear_multiply(vc.getBlue(), 1.3, 255.0)); + } } } m_last_daynight_ratio = daynight_ratio; diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index 82268efd2..c23b6cc5a 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -160,9 +160,10 @@ struct MeshCollector // alpha in the A channel of the returned SColor // day light (0-255) in the R channel of the returned SColor // night light (0-255) in the G channel of the returned SColor -inline video::SColor MapBlock_LightColor(u8 alpha, u16 light) +// light source (0-255) in the B channel of the returned SColor +inline video::SColor MapBlock_LightColor(u8 alpha, u16 light, u8 light_source=0) { - return video::SColor(alpha, (light & 0xff), (light >> 8), 0); + return video::SColor(alpha, (light & 0xff), (light >> 8), light_source); } // Compute light at node diff --git a/src/mapnode.h b/src/mapnode.h index a95497ef5..de2529e4d 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -163,6 +163,16 @@ struct MapNode return blend_light(daylight_factor, lightday, lightnight); } + // 0.0 <= daylight_factor <= 1.0 + // 0 <= return value <= LIGHT_SUN + u8 getLightBlendF1(float daylight_factor, INodeDefManager *nodemgr) const + { + u8 lightday = 0; + u8 lightnight = 0; + getLightBanks(lightday, lightnight, nodemgr); + return blend_light_f1(daylight_factor, lightday, lightnight); + } + u8 getFaceDir(INodeDefManager *nodemgr) const; u8 getWallMounted(INodeDefManager *nodemgr) const; v3s16 getWallMountedDir(INodeDefManager *nodemgr) const; diff --git a/src/mesh.cpp b/src/mesh.cpp index 0f075f72b..29b853143 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -443,7 +443,7 @@ video::ITexture *generateTextureFromMesh(scene::IMesh *mesh, } // Set render target - driver->setRenderTarget(rtt, true, true, video::SColor(0,0,0,0)); + driver->setRenderTarget(rtt, false, true, video::SColor(0,0,0,0)); // Get a scene manager scene::ISceneManager *smgr_main = device->getSceneManager(); @@ -478,7 +478,7 @@ video::ITexture *generateTextureFromMesh(scene::IMesh *mesh, smgr->drop(); // Unset render target - driver->setRenderTarget(0, true, true, 0); + driver->setRenderTarget(0, false, true, 0); return rtt; } diff --git a/src/player.h b/src/player.h index 6c7c1e4ea..5a489e64f 100644 --- a/src/player.h +++ b/src/player.h @@ -220,7 +220,7 @@ public: } u32 keyPressed; - + protected: IGameDef *m_gamedef; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index e5815c462..e26e880a9 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -3604,7 +3604,7 @@ private: if(lua_isnumber(L, 3)) time_of_day = 24000.0 * lua_tonumber(L, 3); time_of_day %= 24000; - u32 dnr = time_to_daynight_ratio(time_of_day); + u32 dnr = time_to_daynight_ratio(time_of_day, true); MapNode n = env->getMap().getNodeNoEx(pos); try{ MapNode n = env->getMap().getNode(pos); diff --git a/src/util/serialize.h b/src/util/serialize.h index d552dec94..b356c484e 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -60,7 +60,7 @@ inline void writeU8(u8 *data, u8 i) data[0] = ((i>> 0)&0xff); } -inline u64 readU64(u8 *data) +inline u64 readU64(const u8 *data) { return ((u64)data[0]<<56) | ((u64)data[1]<<48) | ((u64)data[2]<<40) | ((u64)data[3]<<32) @@ -68,17 +68,17 @@ inline u64 readU64(u8 *data) | ((u64)data[6]<<8) | ((u64)data[7]<<0); } -inline u32 readU32(u8 *data) +inline u32 readU32(const u8 *data) { return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0); } -inline u16 readU16(u8 *data) +inline u16 readU16(const u8 *data) { return (data[0]<<8) | (data[1]<<0); } -inline u8 readU8(u8 *data) +inline u8 readU8(const u8 *data) { return (data[0]<<0); } @@ -86,28 +86,28 @@ inline u8 readU8(u8 *data) inline void writeS32(u8 *data, s32 i){ writeU32(data, (u32)i); } -inline s32 readS32(u8 *data){ +inline s32 readS32(const u8 *data){ return (s32)readU32(data); } inline void writeS16(u8 *data, s16 i){ writeU16(data, (u16)i); } -inline s16 readS16(u8 *data){ +inline s16 readS16(const u8 *data){ return (s16)readU16(data); } inline void writeS8(u8 *data, s8 i){ writeU8(data, (u8)i); } -inline s8 readS8(u8 *data){ +inline s8 readS8(const u8 *data){ return (s8)readU8(data); } inline void writeF1000(u8 *data, f32 i){ writeS32(data, i*1000); } -inline f32 readF1000(u8 *data){ +inline f32 readF1000(const u8 *data){ return (f32)readS32(data)/1000.; } @@ -117,7 +117,7 @@ inline void writeV3S32(u8 *data, v3s32 p) writeS32(&data[4], p.Y); writeS32(&data[8], p.Z); } -inline v3s32 readV3S32(u8 *data) +inline v3s32 readV3S32(const u8 *data) { v3s32 p; p.X = readS32(&data[0]); @@ -132,7 +132,7 @@ inline void writeV3F1000(u8 *data, v3f p) writeF1000(&data[4], p.Y); writeF1000(&data[8], p.Z); } -inline v3f readV3F1000(u8 *data) +inline v3f readV3F1000(const u8 *data) { v3f p; p.X = (float)readF1000(&data[0]); @@ -146,7 +146,7 @@ inline void writeV2F1000(u8 *data, v2f p) writeF1000(&data[0], p.X); writeF1000(&data[4], p.Y); } -inline v2f readV2F1000(u8 *data) +inline v2f readV2F1000(const u8 *data) { v2f p; p.X = (float)readF1000(&data[0]); @@ -160,7 +160,7 @@ inline void writeV2S16(u8 *data, v2s16 p) writeS16(&data[2], p.Y); } -inline v2s16 readV2S16(u8 *data) +inline v2s16 readV2S16(const u8 *data) { v2s16 p; p.X = readS16(&data[0]); @@ -174,7 +174,7 @@ inline void writeV2S32(u8 *data, v2s32 p) writeS32(&data[2], p.Y); } -inline v2s32 readV2S32(u8 *data) +inline v2s32 readV2S32(const u8 *data) { v2s32 p; p.X = readS32(&data[0]); @@ -189,7 +189,7 @@ inline void writeV3S16(u8 *data, v3s16 p) writeS16(&data[4], p.Z); } -inline v3s16 readV3S16(u8 *data) +inline v3s16 readV3S16(const u8 *data) { v3s16 p; p.X = readS16(&data[0]); @@ -206,7 +206,7 @@ inline void writeARGB8(u8 *data, video::SColor p) writeU8(&data[3], p.getBlue()); } -inline video::SColor readARGB8(u8 *data) +inline video::SColor readARGB8(const u8 *data) { video::SColor p; p.setAlpha(readU8(&data[0]));