NOTE: iostream.imbue(std::locale("C")) is very slow\r
NOTE: Global locale is now set at initialization\r
\r
-SUGGESTION: add a second lighting value to the MS nibble of param of\r
- air to tell how bright the air node is when there is no sunlight.\r
- When day changes to night, these two values can be interpolated.\r
+SUGG: Fix address to be ipv6 compatible\r
\r
-TODO: Fix address to be ipv6 compatible\r
+FIXME: When a new sector is generated, it may change the ground level\r
+ of it's and it's neighbors border that two blocks that are\r
+ above and below each other and that are generated before and\r
+ after the sector heightmap generation (order doesn't matter),\r
+ can have a small gap between each other at the border.\r
+SUGGESTION: Use same technique for sector heightmaps as what we're\r
+ using for UnlimitedHeightmap? (getting all neighbors\r
+ when generating)\r
+\r
+SUGG: Transfer more blocks in a single packet\r
+SUGG: A blockdata combiner class, to which blocks are added and at\r
+ destruction it sends all the stuff in as few packets as possible.\r
+\r
+SUGG: If player is on ground, mainly fetch ground-level blocks\r
+SUGG: Fetch stuff mainly from the viewing direction\r
+\r
+SUGG: Expose Connection's seqnums and ACKs to server and client.\r
+ - This enables saving many packets and making a faster connection\r
+ - This also enables server to check if client has received the\r
+ most recent block sent, for example.\r
+SUGG: Add a sane bandwidth throttling system to Connection\r
+\r
+SUGG: More fine-grained control of client's dumping of blocks from\r
+ memory\r
+ - ...What does this mean in the first place?\r
+\r
+SUGG: A map editing mode (similar to dedicated server mode)\r
+\r
+SUGG: Add a time value to the param of footstepped grass and check it\r
+ against a global timer when a block is accessed, to make old\r
+ steps fade away.\r
+\r
+SUGG: Make a copy of close-range environment on client for showing\r
+ on screen, with minimal mutexes to slow down the main loop\r
+\r
+SUGG: Make a PACKET_COMBINED which contains many subpackets. Utilize\r
+ it by sending more stuff in a single packet.\r
+ - Add a packet queue to RemoteClient, from which packets will be\r
+ combined with object data packets\r
+ - This is not exactly trivial: the object data packets are\r
+ sometimes very big by themselves\r
+\r
+SUGG: Split MapBlockObject serialization to to-client and to-disk\r
+ - This will allow saving ages of rats on disk but not sending\r
+ them to clients\r
+\r
+SUGG: Implement lighting using VoxelManipulator\r
+ - Would it be significantly faster?\r
+\r
+FIXME: Rats somehow go underground sometimes (you can see it in water)\r
+ - Does their position get saved to a border value or something?\r
+ - Does this happen anymore?\r
+\r
+SUGG: MovingObject::move and Player::move are basically the same.\r
+ combine them.\r
+\r
+SUGG: Implement a "Fast check queue" (a queue with a map for checking\r
+ if something is already in it)\r
+ - Use it in active block queue in water flowing\r
+\r
+SUGG: Signs could be done in the same way as torches. For this, blocks\r
+ need an additional metadata field for the texts\r
+\r
+SUGG: Precalculate lighting translation table at runtime (at startup)\r
+\r
+SUGG: A version number to blocks, which increments when the block is\r
+ modified (node add/remove, water update, lighting update)\r
+ - This can then be used to make sure the most recent version of\r
+ a block has been sent to client\r
\r
-TODO: ESC Pause mode in which the cursor is not kept at the center of window.\r
TODO: Stop player if focus of window is taken away (go to pause mode)\r
-TODO: Optimize and fix makeFastFace or whatever it's called\r
- - Face calculation is the source of CPU usage on the client\r
-SUGGESTION: The client will calculate and send lighting changes and\r
- the server will randomly check some of them and kick the client out\r
- if it fails to calculate them right.\r
- - Actually, it could just start ignoring them and calculate them\r
- itself.\r
-SUGGESTION: Combine MapBlock's face caches to so big pieces that VBO\r
- gets used\r
- - That is >500 vertices\r
+\r
+TODO: Combine MapBlock's face caches to so big pieces that VBO\r
+ gets used\r
+ - That is >500 vertices\r
\r
TODO: Better dungeons\r
-TODO: There should be very slight natural caves also, starting from\r
- only a straightened-up cliff\r
+TODO: Cliffs, arcs\r
\r
-TODO: Changing of block with mouse wheel or something\r
TODO: Menus\r
\r
TODO: Mobs\r
avg_rtt/2 before the moment the packet is received.\r
TODO: - Scripting\r
\r
-SUGGESTION: Modify client to calculate single changes asynchronously\r
-\r
TODO: Moving players more smoothly. Calculate moving animation\r
in a way that doesn't make the player jump to the right place\r
immediately when the server sends a new position\r
TODO: There are some lighting-related todos and fixmes in\r
ServerMap::emergeBlock\r
\r
-FIXME: When a new sector is generated, it may change the ground level\r
- of it's and it's neighbors border that two blocks that are\r
- above and below each other and that are generated before and\r
- after the sector heightmap generation (order doesn't matter),\r
- can have a small gap between each other at the border.\r
-SUGGESTION: Use same technique for sector heightmaps as what we're\r
- using for UnlimitedHeightmap? (getting all neighbors\r
- when generating)\r
-\r
-SUGG: Set server to automatically find a good spawning place in some\r
- place where there is water and land.\r
- - Map to have a getWalkableNear(p)\r
- - Is this a good idea? It's part of the game to find a good place.\r
-\r
-TODO: Transfer more blocks in a single packet\r
-SUGG: A blockdata combiner class, to which blocks are added and at\r
- destruction it sends all the stuff in as few packets as possible.\r
-\r
-SUGG: If player is on ground, mainly fetch ground-level blocks\r
-SUGG: Fetch stuff mainly from the viewing direction\r
-\r
-SUGG: Expose Connection's seqnums and ACKs to server and client.\r
- - This enables saving many packets and making a faster connection\r
- - This also enables server to check if client has received the\r
- most recent block sent, for example.\r
-TODO: Add a sane bandwidth throttling system to Connection\r
-\r
-SUGG: More fine-grained control of client's dumping of blocks from\r
- memory\r
- - ...What does this mean in the first place?\r
+TODO: Proper handling of spawning place (try to find something that\r
+ is not in the middle of an ocean (some land to stand on at\r
+ least) and save it in map config.\r
\r
TODO: Make the amount of blocks sending to client and the total\r
amount of blocks dynamically limited. Transferring blocks is the\r
\r
TODO: Server to load starting inventory from disk\r
\r
-TODO: PLayers to only be hidden when the client quits.\r
+TODO: Players to only be hidden when the client quits.\r
TODO: - Players to be saved on disk, with inventory\r
TODO: Players to be saved as text in map/players/<name>\r
\r
-SUGG: A map editing mode (similar to dedicated server mode)\r
-\r
TODO: Make fetching sector's blocks more efficient when rendering\r
sectors that have very large amounts of blocks (on client)\r
\r
- For all blocks in the buffer, objects are stepped(). This\r
means they are active.\r
- TODO: A global active buffer is needed for the server\r
+ - TODO: A timestamp to blocks\r
- TODO: All blocks going in and out of the buffer are recorded.\r
- - TODO: For outgoing blocks, a timestamp is written.\r
- - TODO: For incoming blocks, the time difference is calculated and\r
+ - TODO: For outgoing blocks, timestamp is written.\r
+ - TODO: For incoming blocks, time difference is calculated and\r
objects are stepped according to it.\r
-TODO: A timestamp to blocks\r
-\r
-SUGG: Add a time value to the param of footstepped grass and check it\r
- against a global timer when a block is accessed, to make old\r
- steps fade away.\r
\r
TODO: Add config parameters for server's sending and generating distance\r
\r
TODO: Untie client network operations from framerate\r
- Needs some input queues or something\r
\r
-SUGG: Make a copy of close-range environment on client for showing\r
- on screen, with minimal mutexes to slow down the main loop\r
-\r
-SUGG: Make a PACKET_COMBINED which contains many subpackets. Utilize\r
- it by sending more stuff in a single packet.\r
- - Add a packet queue to RemoteClient, from which packets will be\r
- combined with object data packets\r
- - This is not exactly trivial: the object data packets are\r
- sometimes very big by themselves\r
-\r
-SUGG: Split MapBlockObject serialization to to-client and to-disk\r
- - This will allow saving ages of rats on disk but not sending\r
- them to clients\r
-\r
TODO: Get rid of GotSplitPacketException\r
\r
-SUGG: Implement lighting using VoxelManipulator\r
- - Would it be significantly faster?\r
-\r
TODO: Check what goes wrong with caching map to disk (Kray)\r
\r
TODO: Remove LazyMeshUpdater. It is not used as supposed.\r
\r
+TODO: Node cracking animation when digging\r
+ - TODO: A way to generate new textures by combining textures\r
+ - TODO: Mesh update to fetch cracked faces from the former\r
+\r
+TODO: Add server unused sector deletion settings to settings\r
+\r
+TODO: TOSERVER_LEAVE\r
+\r
Doing now:\r
======================================================================\r
\r
-\r
======================================================================\r
\r
*/\r
#ifdef _MSC_VER\r
#pragma comment(lib, "Irrlicht.lib")\r
#pragma comment(lib, "jthread.lib")\r
+#pragma comment(lib, "zlibwapi.lib")\r
// This would get rid of the console window\r
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")\r
#endif\r
#include <fstream>\r
#include <time.h>\r
#include <jmutexautolock.h>\r
+#include <locale.h>\r
#include "common_irrlicht.h"\r
#include "debug.h"\r
#include "map.h"\r
#include "constants.h"\r
#include "strfnd.h"\r
#include "porting.h"\r
-#include <locale.h>\r
+#include "guiPauseMenu.h"\r
\r
IrrlichtDevice *g_device = NULL;\r
\r
-const char *g_material_filenames[MATERIALS_COUNT] =\r
+/*const char *g_content_filenames[MATERIALS_COUNT] =\r
{\r
"../data/stone.png",\r
"../data/grass.png",\r
"../data/water.png",\r
- "../data/light.png",\r
+ "../data/torch_on_floor.png",\r
"../data/tree.png",\r
"../data/leaves.png",\r
"../data/grass_footsteps.png",\r
"../data/mese.png",\r
- "../data/mud.png"\r
+ "../data/mud.png",\r
+ "../data/water.png", // CONTENT_OCEAN\r
};\r
\r
-video::SMaterial g_materials[MATERIALS_COUNT];\r
-//video::SMaterial g_mesh_materials[3];\r
+// Material cache\r
+video::SMaterial g_materials[MATERIALS_COUNT];*/\r
+\r
+// Texture cache\r
+TextureCache g_texturecache;\r
+\r
\r
// All range-related stuff below is locked behind this\r
JMutex g_range_mutex;\r
\r
// Blocks are viewed in this range from the player\r
s16 g_viewing_range_nodes = 60;\r
+//s16 g_viewing_range_nodes = 0;\r
\r
// This is updated by the client's fetchBlocks routine\r
//s16 g_actual_viewing_range_nodes = VIEWING_RANGE_NODES_DEFAULT;\r
// Sets default settings\r
void set_default_settings()\r
{\r
- g_settings.set("dedicated_server", "");\r
-\r
// Client stuff\r
- g_settings.set("wanted_fps", "30");\r
- g_settings.set("fps_max", "60");\r
- g_settings.set("viewing_range_nodes_max", "300");\r
- g_settings.set("viewing_range_nodes_min", "20");\r
- g_settings.set("screenW", "");\r
- g_settings.set("screenH", "");\r
- g_settings.set("host_game", "");\r
- g_settings.set("port", "");\r
- g_settings.set("address", "");\r
- g_settings.set("name", "");\r
- g_settings.set("random_input", "false");\r
- g_settings.set("client_delete_unused_sectors_timeout", "1200");\r
+ g_settings.setDefault("wanted_fps", "30");\r
+ g_settings.setDefault("fps_max", "60");\r
+ g_settings.setDefault("viewing_range_nodes_max", "300");\r
+ g_settings.setDefault("viewing_range_nodes_min", "35");\r
+ g_settings.setDefault("screenW", "");\r
+ g_settings.setDefault("screenH", "");\r
+ g_settings.setDefault("host_game", "");\r
+ g_settings.setDefault("port", "");\r
+ g_settings.setDefault("address", "");\r
+ g_settings.setDefault("name", "");\r
+ g_settings.setDefault("random_input", "false");\r
+ g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");\r
+ g_settings.setDefault("enable_fog", "true");\r
\r
// Server stuff\r
- g_settings.set("creative_mode", "false");\r
- g_settings.set("heightmap_blocksize", "128");\r
- g_settings.set("height_randmax", "constant 70.0");\r
- g_settings.set("height_randfactor", "constant 0.6");\r
- g_settings.set("height_base", "linear 0 35 0");\r
- g_settings.set("plants_amount", "1.0");\r
- g_settings.set("ravines_amount", "1.0");\r
- g_settings.set("objectdata_interval", "0.2");\r
- g_settings.set("active_object_range", "2");\r
- g_settings.set("max_simultaneous_block_sends_per_client", "1");\r
- g_settings.set("max_simultaneous_block_sends_server_total", "4");\r
+ g_settings.setDefault("creative_mode", "false");\r
+ g_settings.setDefault("heightmap_blocksize", "32");\r
+ g_settings.setDefault("height_randmax", "constant 50.0");\r
+ g_settings.setDefault("height_randfactor", "constant 0.6");\r
+ g_settings.setDefault("height_base", "linear 0 0 0");\r
+ g_settings.setDefault("plants_amount", "1.0");\r
+ g_settings.setDefault("ravines_amount", "1.0");\r
+ g_settings.setDefault("objectdata_interval", "0.2");\r
+ g_settings.setDefault("active_object_range", "2");\r
+ g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");\r
+ g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");\r
+ g_settings.setDefault("disable_water_climb", "true");\r
+ g_settings.setDefault("endless_water", "true");\r
+ g_settings.setDefault("max_block_send_distance", "5");\r
+ g_settings.setDefault("max_block_generate_distance", "4");\r
}\r
\r
/*\r
\r
if(event.KeyInput.Key == irr::KEY_ESCAPE)\r
{\r
+ //TODO: Not used anymore?\r
if(g_game_focused == true)\r
{\r
dstream<<DTIME<<"ESC pressed"<<std::endl;\r
\r
if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)\r
{\r
+ left_active = event.MouseInput.isLeftPressed();\r
+ middle_active = event.MouseInput.isMiddlePressed();\r
+ right_active = event.MouseInput.isRightPressed();\r
+\r
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)\r
{\r
leftclicked = true;\r
{\r
rightclicked = true;\r
}\r
+ if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)\r
+ {\r
+ leftreleased = true;\r
+ }\r
+ if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)\r
+ {\r
+ rightreleased = true;\r
+ }\r
if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)\r
{\r
/*dstream<<"event.MouseInput.Wheel="\r
keyIsDown[i] = false;\r
leftclicked = false;\r
rightclicked = false;\r
+ leftreleased = false;\r
+ rightreleased = false;\r
+\r
+ left_active = false;\r
+ middle_active = false;\r
+ right_active = false;\r
}\r
\r
bool leftclicked;\r
bool rightclicked;\r
+ bool leftreleased;\r
+ bool rightreleased;\r
+\r
+ bool left_active;\r
+ bool middle_active;\r
+ bool right_active;\r
+\r
private:\r
// We use this array to store the current state of each key\r
bool keyIsDown[KEY_KEY_CODES_COUNT];\r
virtual ~InputHandler()\r
{\r
}\r
+\r
virtual bool isKeyDown(EKEY_CODE keyCode) = 0;\r
+\r
virtual v2s32 getMousePos() = 0;\r
virtual void setMousePos(s32 x, s32 y) = 0;\r
+\r
+ virtual bool getLeftState() = 0;\r
+ virtual bool getRightState() = 0;\r
+\r
virtual bool getLeftClicked() = 0;\r
virtual bool getRightClicked() = 0;\r
virtual void resetLeftClicked() = 0;\r
virtual void resetRightClicked() = 0;\r
+\r
+ virtual bool getLeftReleased() = 0;\r
+ virtual bool getRightReleased() = 0;\r
+ virtual void resetLeftReleased() = 0;\r
+ virtual void resetRightReleased() = 0;\r
\r
virtual void step(float dtime) {};\r
\r
m_device->getCursorControl()->setPosition(x, y);\r
}\r
\r
+ virtual bool getLeftState()\r
+ {\r
+ return m_receiver->left_active;\r
+ }\r
+ virtual bool getRightState()\r
+ {\r
+ return m_receiver->right_active;\r
+ }\r
+ \r
virtual bool getLeftClicked()\r
{\r
if(g_game_focused == false)\r
m_receiver->rightclicked = false;\r
}\r
\r
+ virtual bool getLeftReleased()\r
+ {\r
+ if(g_game_focused == false)\r
+ return false;\r
+ return m_receiver->leftreleased;\r
+ }\r
+ virtual bool getRightReleased()\r
+ {\r
+ if(g_game_focused == false)\r
+ return false;\r
+ return m_receiver->rightreleased;\r
+ }\r
+ virtual void resetLeftReleased()\r
+ {\r
+ m_receiver->leftreleased = false;\r
+ }\r
+ virtual void resetRightReleased()\r
+ {\r
+ m_receiver->rightreleased = false;\r
+ }\r
+\r
void clear()\r
{\r
resetRightClicked();\r
mousepos = v2s32(x,y);\r
}\r
\r
+ virtual bool getLeftState()\r
+ {\r
+ return false;\r
+ }\r
+ virtual bool getRightState()\r
+ {\r
+ return false;\r
+ }\r
+\r
virtual bool getLeftClicked()\r
{\r
return leftclicked;\r
rightclicked = false;\r
}\r
\r
+ virtual bool getLeftReleased()\r
+ {\r
+ return false;\r
+ }\r
+ virtual bool getRightReleased()\r
+ {\r
+ return false;\r
+ }\r
+ virtual void resetLeftReleased()\r
+ {\r
+ }\r
+ virtual void resetRightReleased()\r
+ {\r
+ }\r
+\r
virtual void step(float dtime)\r
{\r
{\r
if(counter1 < 0.0)\r
{\r
counter1 = 0.1*Rand(1,10);\r
- /*if(g_selected_material < USEFUL_MATERIAL_COUNT-1)\r
+ /*if(g_selected_material < USEFUL_CONTENT_COUNT-1)\r
g_selected_material++;\r
else\r
g_selected_material = 0;*/\r
\r
// Initialize to the target value\r
static float frametime_avg = 1.0/wanted_fps;\r
- frametime_avg = frametime_avg * 0.9 + frametime * 0.1;\r
+ //frametime_avg = frametime_avg * 0.9 + frametime * 0.1;\r
+ frametime_avg = frametime_avg * 0.7 + frametime * 0.3;\r
\r
static f32 counter = 0;\r
if(counter > 0){\r
\r
float fraction = sqrt(frametime_avg / frametime_wanted);\r
\r
+ /*float fraction = sqrt(frametime_avg / frametime_wanted) / 2.0\r
+ + frametime_avg / frametime_wanted / 2.0;*/\r
+ \r
+ //float fraction = frametime_avg / frametime_wanted;\r
+\r
static bool fraction_is_good = false;\r
\r
float fraction_good_threshold = 0.1;\r
- float fraction_bad_threshold = 0.25;\r
+ //float fraction_bad_threshold = 0.25;\r
+ float fraction_bad_threshold = 0.1;\r
float fraction_limit;\r
// Use high limit if fraction is good AND the fraction would\r
// lower the range. We want to keep the range fairly high.\r
try\r
{\r
\r
+ /*\r
+ Parse command line\r
+ */\r
+ \r
+ // List all allowed options\r
+ core::map<std::string, ValueSpec> allowed_options;\r
+ allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));\r
+ allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,\r
+ "Run server directly"));\r
+ allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,\r
+ "Load configuration from specified file"));\r
+ allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));\r
+ allowed_options.insert("address", ValueSpec(VALUETYPE_STRING));\r
+ allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));\r
+ allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));\r
+ allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));\r
+\r
+ Settings cmd_args;\r
+ \r
+ bool ret = cmd_args.parseCommandLine(argc, argv, allowed_options);\r
+\r
+ if(ret == false || cmd_args.getFlag("help"))\r
+ {\r
+ dstream<<"Allowed options:"<<std::endl;\r
+ for(core::map<std::string, ValueSpec>::Iterator\r
+ i = allowed_options.getIterator();\r
+ i.atEnd() == false; i++)\r
+ {\r
+ dstream<<" --"<<i.getNode()->getKey();\r
+ if(i.getNode()->getValue().type == VALUETYPE_FLAG)\r
+ {\r
+ }\r
+ else\r
+ {\r
+ dstream<<" <value>";\r
+ }\r
+ dstream<<std::endl;\r
+\r
+ if(i.getNode()->getValue().help != NULL)\r
+ {\r
+ dstream<<" "<<i.getNode()->getValue().help\r
+ <<std::endl;\r
+ }\r
+ }\r
+\r
+ return cmd_args.getFlag("help") ? 0 : 1;\r
+ }\r
+\r
+\r
/*\r
Basic initialization\r
*/\r
// Initialize timestamp mutex\r
g_timestamp_mutex.Init();\r
\r
- /*\r
- Run unit tests\r
- */\r
- if(ENABLE_TESTS)\r
- {\r
- run_tests();\r
- }\r
- \r
/*\r
Initialization\r
*/\r
\r
- // Read config file\r
+ /*\r
+ Read config file\r
+ */\r
+ \r
+ // Path of configuration file in use\r
+ std::string configpath = "";\r
\r
- if(argc >= 2)\r
+ if(cmd_args.exists("config"))\r
{\r
- g_settings.readConfigFile(argv[1]);\r
+ bool r = g_settings.readConfigFile(cmd_args.get("config").c_str());\r
+ if(r == false)\r
+ {\r
+ dstream<<"Could not read configuration from \""\r
+ <<cmd_args.get("config")<<"\""<<std::endl;\r
+ return 1;\r
+ }\r
+ configpath = cmd_args.get("config");\r
}\r
else\r
{\r
{\r
bool r = g_settings.readConfigFile(filenames[i]);\r
if(r)\r
+ {\r
+ configpath = filenames[i];\r
break;\r
+ }\r
}\r
}\r
\r
// Initialize random seed\r
srand(time(0));\r
\r
+ /*\r
+ Run unit tests\r
+ */\r
+ if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)\r
+ || cmd_args.getFlag("enable-unittests") == true)\r
+ {\r
+ run_tests();\r
+ }\r
+ \r
+ /*\r
+ Global range mutex\r
+ */\r
g_range_mutex.Init();\r
assert(g_range_mutex.IsInitialized());\r
\r
*/\r
\r
std::cout<<std::endl<<std::endl;\r
- char templine[100];\r
\r
- // Dedicated?\r
- bool dedicated = g_settings.getBoolAsk\r
- ("dedicated_server", "Dedicated server?", false);\r
- std::cout<<"dedicated = "<<dedicated<<std::endl;\r
+ std::cout\r
+ <<" .__ __ __ "<<std::endl\r
+ <<" _____ |__| ____ _____/ |_ ____ _______/ |_ "<<std::endl\r
+ <<" / \\| |/ \\_/ __ \\ __\\/ __ \\ / ___/\\ __\\"<<std::endl\r
+ <<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<<std::endl\r
+ <<"|__|_| /__|___| /\\___ >__| \\___ >____ > |__| "<<std::endl\r
+ <<" \\/ \\/ \\/ \\/ \\/ "<<std::endl\r
+ <<std::endl\r
+ <<"Now with more waterish water!"\r
+ <<std::endl;\r
+\r
+ std::cout<<std::endl;\r
+ char templine[100];\r
\r
// Port?\r
- u16 port = g_settings.getU16Ask("port", "Port", 30000);\r
- std::cout<<"-> "<<port<<std::endl;\r
+ u16 port = 30000;\r
+ if(cmd_args.exists("port"))\r
+ {\r
+ port = cmd_args.getU16("port");\r
+ }\r
+ else\r
+ {\r
+ port = g_settings.getU16Ask("port", "Port", 30000);\r
+ std::cout<<"-> "<<port<<std::endl;\r
+ }\r
\r
- if(dedicated)\r
+ if(cmd_args.getFlag("server"))\r
{\r
DSTACK("Dedicated server branch");\r
\r
bool hosting = false;\r
char connect_name[100] = "";\r
\r
- std::cout<<"Address to connect to [empty = host a game]: ";\r
- if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)\r
+ if(cmd_args.exists("address"))\r
+ {\r
+ snprintf(connect_name, 100, "%s", cmd_args.get("address").c_str());\r
+ }\r
+ else if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)\r
{\r
std::cout<<g_settings.get("address")<<std::endl;\r
snprintf(connect_name, 100, "%s", g_settings.get("address").c_str());\r
}\r
else\r
{\r
+ std::cout<<"Address to connect to [empty = host a game]: ";\r
std::cin.getline(connect_name, 100);\r
}\r
\r
}\r
\r
if(hosting)\r
- std::cout<<"-> hosting"<<std::endl;\r
+ std::cout<<"> Hosting game"<<std::endl;\r
else\r
- std::cout<<"-> "<<connect_name<<std::endl;\r
+ std::cout<<"> Connecting to "<<connect_name<<std::endl;\r
\r
char playername[PLAYERNAME_SIZE] = "";\r
if(g_settings.get("name") != "")\r
\r
device->setResizable(true);\r
\r
- if(g_settings.getBool("random_input"))\r
+ bool random_input = g_settings.getBool("random_input")\r
+ || cmd_args.getFlag("random-input");\r
+ if(random_input)\r
g_input = new RandomInputHandler();\r
else\r
g_input = new RealInputHandler(device, &receiver);\r
//driver->setMinHardwareBufferVertexCount(1);\r
\r
scene::ISceneManager* smgr = device->getSceneManager();\r
+ \r
+ // Pause menu\r
+ guiPauseMenu pauseMenu(device, &receiver);\r
\r
gui::IGUIEnvironment* guienv = device->getGUIEnvironment();\r
gui::IGUISkin* skin = guienv->getSkin();\r
driver->endScene();\r
\r
/*\r
- Initialize material array\r
+ Preload some random textures that are used in threads\r
*/\r
-\r
- //video::SMaterial g_materials[MATERIALS_COUNT];\r
- for(u16 i=0; i<MATERIALS_COUNT; i++)\r
+ \r
+ g_texturecache.set("torch", driver->getTexture("../data/torch.png"));\r
+ g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));\r
+ g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));\r
+ \r
+ /*\r
+ Load tile textures\r
+ */\r
+ for(s32 i=0; i<TILES_COUNT; i++)\r
{\r
- g_materials[i].Lighting = false;\r
- g_materials[i].BackfaceCulling = false;\r
-\r
- const char *filename = g_material_filenames[i];\r
- if(filename != NULL){\r
- video::ITexture *t = driver->getTexture(filename);\r
- if(t == NULL){\r
- std::cout<<DTIME<<"Texture could not be loaded: \""\r
- <<filename<<"\""<<std::endl;\r
- return 1;\r
- }\r
- g_materials[i].setTexture(0, driver->getTexture(filename));\r
- }\r
- //g_materials[i].setFlag(video::EMF_TEXTURE_WRAP, video::ETC_REPEAT);\r
- g_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);\r
- //g_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);\r
- //g_materials[i].setFlag(video::EMF_FOG_ENABLE, true);\r
- if(i == MATERIAL_WATER)\r
- {\r
- g_materials[i].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;\r
- //g_materials[i].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;\r
- }\r
+ if(g_tile_texture_names[i] == NULL)\r
+ continue;\r
+ std::string name = g_tile_texture_names[i];\r
+ std::string filename;\r
+ filename += "../data/";\r
+ filename += name;\r
+ filename += ".png";\r
+ g_texturecache.set(name, driver->getTexture(filename.c_str()));\r
}\r
\r
- /*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));\r
- g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));\r
- g_mesh_materials[2].setTexture(0, driver->getTexture("../data/stone.png"));\r
- for(u32 i=0; i<3; i++)\r
- {\r
- g_mesh_materials[i].Lighting = false;\r
- g_mesh_materials[i].BackfaceCulling = false;\r
- g_mesh_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);\r
- g_mesh_materials[i].setFlag(video::EMF_FOG_ENABLE, true);\r
- }*/\r
+ tile_materials_preload(g_texturecache);\r
\r
- // Make a scope here for the client so that it gets removed\r
- // before the irrlicht device\r
+ /*\r
+ Make a scope here for the client so that it gets removed\r
+ before the irrlicht device\r
+ */\r
{\r
\r
std::cout<<DTIME<<"Creating server and client"<<std::endl;\r
Create client\r
*/\r
\r
- // TODO: Get rid of the g_materials parameter or it's globalness\r
- Client client(device, g_materials,\r
- g_settings.getFloat("client_delete_unused_sectors_timeout"),\r
- playername);\r
+ Client client(device, playername,\r
+ g_range_mutex,\r
+ g_viewing_range_nodes,\r
+ g_viewing_range_all);\r
\r
Address connect_address(0,0,0,0, port);\r
try{\r
std::cout<<DTIME<<"Timed out."<<std::endl;\r
return 0;\r
}\r
+\r
+ /*\r
+ Create skybox\r
+ */\r
+ /*scene::ISceneNode* skybox;\r
+ skybox = smgr->addSkyBoxSceneNode(\r
+ driver->getTexture("../data/skybox2.png"),\r
+ driver->getTexture("../data/skybox3.png"),\r
+ driver->getTexture("../data/skybox1.png"),\r
+ driver->getTexture("../data/skybox1.png"),\r
+ driver->getTexture("../data/skybox1.png"),\r
+ driver->getTexture("../data/skybox1.png"));*/\r
\r
/*\r
Create the camera node\r
// Just so big a value that everything rendered is visible\r
camera->setFarValue(100000*BS);\r
\r
- /*//f32 range = BS*HEIGHTMAP_RANGE_NODES*0.9;\r
- f32 range = BS*HEIGHTMAP_RANGE_NODES*0.9;\r
- \r
- camera->setFarValue(range);\r
- \r
- driver->setFog(\r
- skycolor,\r
- video::EFT_FOG_LINEAR,\r
- range*0.8,\r
- range,\r
- 0.01,\r
- false,\r
- false\r
- );*/\r
- \r
f32 camera_yaw = 0; // "right/left"\r
f32 camera_pitch = 0; // "up/down"\r
+\r
+ /*\r
+ Move into game\r
+ */\r
\r
gui_loadingtext->remove();\r
\r
+ pauseMenu.setVisible(true);\r
+\r
/*\r
Add some gui stuff\r
*/\r
// First line of debug text\r
gui::IGUIStaticText *guitext = guienv->addStaticText(\r
L"Minetest-c55",\r
- core::rect<s32>(5, 5, 5+600, 5+textsize.Y),\r
+ core::rect<s32>(5, 5, 795, 5+textsize.Y),\r
false, false);\r
// Second line of debug text\r
gui::IGUIStaticText *guitext2 = guienv->addStaticText(\r
L"",\r
- core::rect<s32>(5, 5+(textsize.Y+5)*1, 5+600, (5+textsize.Y)*2),\r
+ core::rect<s32>(5, 5+(textsize.Y+5)*1, 795, (5+textsize.Y)*2),\r
false, false);\r
\r
// At the middle of the screen\r
Some statistics are collected in these\r
*/\r
u32 drawtime = 0;\r
+ u32 beginscenetime = 0;\r
u32 scenetime = 0;\r
u32 endscenetime = 0;\r
\r
//gui::IGUIWindow* input_window = NULL;\r
gui::IGUIStaticText* input_guitext = NULL;\r
\r
+ /*\r
+ Digging animation\r
+ */\r
+ //f32 \r
+\r
/*\r
Main loop\r
*/\r
\r
while(device->run())\r
{\r
+ /*\r
+ Random calculations\r
+ */\r
+ v2u32 screensize = driver->getScreenSize();\r
+ core::vector2d<s32> displaycenter(screensize.X/2,screensize.Y/2);\r
+\r
// Hilight boxes collected during the loop and displayed\r
core::list< core::aabbox3d<f32> > hilightboxes;\r
\r
/*\r
Special keys\r
*/\r
- if(g_esc_pressed)\r
+ /*if(g_esc_pressed)\r
{\r
break;\r
- }\r
+ }*/\r
\r
/*\r
Player speed control\r
Mouse and camera control\r
*/\r
\r
- if(device->isWindowActive() && g_game_focused)\r
+ if((device->isWindowActive() && g_game_focused && !pauseMenu.isVisible())\r
+ || random_input)\r
{\r
- device->getCursorControl()->setVisible(false);\r
+ if(!random_input)\r
+ device->getCursorControl()->setVisible(false);\r
\r
if(first_loop_after_window_activation){\r
//std::cout<<"window active, first loop"<<std::endl;\r
first_loop_after_window_activation = false;\r
}\r
else{\r
- s32 dx = g_input->getMousePos().X - 320;\r
- s32 dy = g_input->getMousePos().Y - 240;\r
+ s32 dx = g_input->getMousePos().X - displaycenter.X;\r
+ s32 dy = g_input->getMousePos().Y - displaycenter.Y;\r
//std::cout<<"window active, pos difference "<<dx<<","<<dy<<std::endl;\r
camera_yaw -= dx*0.2;\r
camera_pitch += dy*0.2;\r
if(camera_pitch < -89.5) camera_pitch = -89.5;\r
if(camera_pitch > 89.5) camera_pitch = 89.5;\r
}\r
- g_input->setMousePos(320, 240);\r
+ g_input->setMousePos(displaycenter.X, displaycenter.Y);\r
}\r
else{\r
device->getCursorControl()->setVisible(true);\r
if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)\r
{\r
dstream<<"Sign object right-clicked"<<std::endl;\r
-\r
+ \r
unFocusGame();\r
\r
input_guitext = guienv->addStaticText(L"",\r
\r
input_guitext->setDrawBackground(true);\r
\r
- g_text_buffer = L"";\r
- g_text_buffer_accepted = false;\r
+ if(random_input)\r
+ {\r
+ g_text_buffer = L"ASD LOL 8)";\r
+ g_text_buffer_accepted = true;\r
+ }\r
+ else\r
+ {\r
+ g_text_buffer = L"";\r
+ g_text_buffer_accepted = false;\r
+ }\r
+\r
textbuf_dest = new TextDestSign(\r
selected_object->getBlock()->getPos(),\r
selected_object->getId(),\r
}\r
else // selected_object == NULL\r
{\r
+\r
+ /*\r
+ Find out which node we are pointing at\r
+ */\r
\r
bool nodefound = false;\r
v3s16 nodepos;\r
s16 zend = pos_i.Z + (camera_direction.Z>0 ? a : 1);\r
s16 xend = pos_i.X + (camera_direction.X>0 ? a : 1);\r
\r
- for(s16 y = ystart; y <= yend; y++){\r
- for(s16 z = zstart; z <= zend; z++){\r
+ for(s16 y = ystart; y <= yend; y++)\r
+ for(s16 z = zstart; z <= zend; z++)\r
for(s16 x = xstart; x <= xend; x++)\r
{\r
- try{\r
- if(client.getNode(v3s16(x,y,z)).d == MATERIAL_AIR){\r
+ MapNode n;\r
+ try\r
+ {\r
+ n = client.getNode(v3s16(x,y,z));\r
+ if(content_pointable(n.d) == false)\r
continue;\r
- }\r
- }catch(InvalidPositionException &e){\r
+ }\r
+ catch(InvalidPositionException &e)\r
+ {\r
continue;\r
}\r
\r
\r
f32 d = 0.01;\r
\r
- v3s16 directions[6] = {\r
+ v3s16 dirs[6] = {\r
v3s16(0,0,1), // back\r
v3s16(0,1,0), // top\r
v3s16(1,0,0), // right\r
- v3s16(0,0,-1),\r
- v3s16(0,-1,0),\r
- v3s16(-1,0,0),\r
+ v3s16(0,0,-1), // front\r
+ v3s16(0,-1,0), // bottom\r
+ v3s16(-1,0,0), // left\r
};\r
+ \r
+ /*\r
+ Meta-objects\r
+ */\r
+ if(n.d == CONTENT_TORCH)\r
+ {\r
+ v3s16 dir = unpackDir(n.dir);\r
+ v3f dir_f = v3f(dir.X, dir.Y, dir.Z);\r
+ dir_f *= BS/2 - BS/6 - BS/20;\r
+ v3f cpf = npf + dir_f;\r
+ f32 distance = (cpf - camera_position).getLength();\r
\r
- for(u16 i=0; i<6; i++){\r
- //{u16 i=3;\r
- v3f dir_f = v3f(directions[i].X,\r
- directions[i].Y, directions[i].Z);\r
- v3f centerpoint = npf + dir_f * BS/2;\r
- f32 distance =\r
- (centerpoint - camera_position).getLength();\r
+ core::aabbox3d<f32> box;\r
\r
- if(distance < mindistance){\r
- //std::cout<<DTIME<<"for centerpoint=("<<centerpoint.X<<","<<centerpoint.Y<<","<<centerpoint.Z<<"): distance < mindistance"<<std::endl;\r
- //std::cout<<DTIME<<"npf=("<<npf.X<<","<<npf.Y<<","<<npf.Z<<")"<<std::endl;\r
- core::CMatrix4<f32> m;\r
- m.buildRotateFromTo(v3f(0,0,1), dir_f);\r
-\r
- // This is the back face\r
- v3f corners[2] = {\r
- v3f(BS/2, BS/2, BS/2),\r
- v3f(-BS/2, -BS/2, BS/2+d)\r
- };\r
- \r
- for(u16 j=0; j<2; j++){\r
- m.rotateVect(corners[j]);\r
- corners[j] += npf;\r
- //std::cout<<DTIME<<"box corners["<<j<<"]: ("<<corners[j].X<<","<<corners[j].Y<<","<<corners[j].Z<<")"<<std::endl;\r
- }\r
-\r
- //core::aabbox3d<f32> facebox(corners[0],corners[1]);\r
- core::aabbox3d<f32> facebox(corners[0]);\r
- facebox.addInternalPoint(corners[1]);\r
+ // bottom\r
+ if(dir == v3s16(0,-1,0))\r
+ {\r
+ box = core::aabbox3d<f32>(\r
+ npf - v3f(BS/6, BS/2, BS/6),\r
+ npf + v3f(BS/6, -BS/2+BS/3*2, BS/6)\r
+ );\r
+ }\r
+ // top\r
+ else if(dir == v3s16(0,1,0))\r
+ {\r
+ box = core::aabbox3d<f32>(\r
+ npf - v3f(BS/6, -BS/2+BS/3*2, BS/6),\r
+ npf + v3f(BS/6, BS/2, BS/6)\r
+ );\r
+ }\r
+ // side\r
+ else\r
+ {\r
+ box = core::aabbox3d<f32>(\r
+ cpf - v3f(BS/6, BS/3, BS/6),\r
+ cpf + v3f(BS/6, BS/3, BS/6)\r
+ );\r
+ }\r
\r
- if(facebox.intersectsWithLine(shootline)){\r
+ if(distance < mindistance)\r
+ {\r
+ if(box.intersectsWithLine(shootline))\r
+ {\r
nodefound = true;\r
nodepos = np;\r
- neighbourpos = np + directions[i];\r
+ neighbourpos = np;\r
mindistance = distance;\r
- nodefacebox = facebox;\r
+ nodefacebox = box;\r
}\r
}\r
}\r
- }}}\r
+ /*\r
+ Regular blocks\r
+ */\r
+ else\r
+ {\r
+ for(u16 i=0; i<6; i++)\r
+ {\r
+ v3f dir_f = v3f(dirs[i].X,\r
+ dirs[i].Y, dirs[i].Z);\r
+ v3f centerpoint = npf + dir_f * BS/2;\r
+ f32 distance =\r
+ (centerpoint - camera_position).getLength();\r
+ \r
+ if(distance < mindistance)\r
+ {\r
+ core::CMatrix4<f32> m;\r
+ m.buildRotateFromTo(v3f(0,0,1), dir_f);\r
+\r
+ // This is the back face\r
+ v3f corners[2] = {\r
+ v3f(BS/2, BS/2, BS/2),\r
+ v3f(-BS/2, -BS/2, BS/2+d)\r
+ };\r
+ \r
+ for(u16 j=0; j<2; j++)\r
+ {\r
+ m.rotateVect(corners[j]);\r
+ corners[j] += npf;\r
+ }\r
+\r
+ core::aabbox3d<f32> facebox(corners[0]);\r
+ facebox.addInternalPoint(corners[1]);\r
+\r
+ if(facebox.intersectsWithLine(shootline))\r
+ {\r
+ nodefound = true;\r
+ nodepos = np;\r
+ neighbourpos = np + dirs[i];\r
+ mindistance = distance;\r
+ nodefacebox = facebox;\r
+ }\r
+ } // if distance < mindistance\r
+ } // for dirs\r
+ } // regular block\r
+ } // for coords\r
+\r
+ /*static v3s16 oldnodepos;\r
+ static bool oldnodefound = false;*/\r
\r
if(nodefound)\r
{\r
if(nodepos != nodepos_old){\r
std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","\r
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;\r
- nodepos_old = nodepos;\r
-\r
- /*wchar_t positiontext[20];\r
- swprintf(positiontext, 20, L"(%i,%i,%i)",\r
- nodepos.X, nodepos.Y, nodepos.Z);\r
- positiontextgui->setText(positiontext);*/\r
}\r
\r
hilightboxes.push_back(nodefacebox);\r
\r
- if(g_input->getLeftClicked())\r
+ //if(g_input->getLeftClicked())\r
+ if(g_input->getLeftClicked() ||\r
+ (g_input->getLeftState() && nodepos != nodepos_old))\r
{\r
- //std::cout<<DTIME<<"Removing node"<<std::endl;\r
- //client.removeNode(nodepos);\r
std::cout<<DTIME<<"Ground left-clicked"<<std::endl;\r
- client.clickGround(0, nodepos, neighbourpos, g_selected_item);\r
+ client.pressGround(0, nodepos, neighbourpos, g_selected_item);\r
}\r
if(g_input->getRightClicked())\r
+ /*if(g_input->getRightClicked() ||\r
+ (g_input->getRightState() && nodepos != nodepos_old))*/\r
{\r
- //std::cout<<DTIME<<"Placing node"<<std::endl;\r
- //client.addNodeFromInventory(neighbourpos, g_selected_item);\r
std::cout<<DTIME<<"Ground right-clicked"<<std::endl;\r
- client.clickGround(1, nodepos, neighbourpos, g_selected_item);\r
+ client.pressGround(1, nodepos, neighbourpos, g_selected_item);\r
}\r
+ \r
+ nodepos_old = nodepos;\r
}\r
else{\r
//std::cout<<DTIME<<"nodefound == false"<<std::endl;\r
//positiontextgui->setText(L"");\r
}\r
\r
+ /*oldnodefound = nodefound;\r
+ oldnodepos = nodepos;*/\r
+\r
} // selected_object == NULL\r
\r
g_input->resetLeftClicked();\r
g_input->resetRightClicked();\r
\r
+ if(g_input->getLeftReleased())\r
+ {\r
+ std::cout<<DTIME<<"Left released"<<std::endl;\r
+ client.stopDigging();\r
+ }\r
+ if(g_input->getRightReleased())\r
+ {\r
+ //std::cout<<DTIME<<"Right released"<<std::endl;\r
+ // Nothing here\r
+ }\r
+ \r
+ g_input->resetLeftReleased();\r
+ g_input->resetRightReleased();\r
+ \r
/*\r
Calculate stuff for drawing\r
*/\r
\r
- v2u32 screensize = driver->getScreenSize();\r
- core::vector2d<s32> displaycenter(screensize.X/2,screensize.Y/2);\r
-\r
camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);\r
+ \r
+ // Background color is choosen based on whether the player is\r
+ // much beyond the initial ground level\r
+ /*video::SColor bgcolor;\r
+ v3s16 p0 = Map::floatToInt(player_position);\r
+ // Does this make short random delays?\r
+ // NOTE: no need for this, sky doesn't show underground with\r
+ // enough range\r
+ bool is_underground = client.isNodeUnderground(p0);\r
+ //bool is_underground = false;\r
+ if(is_underground == false)\r
+ bgcolor = video::SColor(255,90,140,200);\r
+ else\r
+ bgcolor = video::SColor(255,0,0,0);*/\r
+ \r
+ //video::SColor bgcolor = video::SColor(255,90,140,200);\r
+ //video::SColor bgcolor = skycolor;\r
+ \r
+ //s32 daynight_i = client.getDayNightIndex();\r
+ //video::SColor bgcolor = skycolor[daynight_i];\r
+\r
+ u32 daynight_ratio = client.getDayNightRatio();\r
+ video::SColor bgcolor = video::SColor(\r
+ 255,\r
+ skycolor.getRed() * daynight_ratio / 1000,\r
+ skycolor.getGreen() * daynight_ratio / 1000,\r
+ skycolor.getBlue() * daynight_ratio / 1000);\r
+\r
+ /*\r
+ Fog\r
+ */\r
+ \r
+ if(g_settings.getBool("enable_fog") == true)\r
+ {\r
+ f32 range = g_viewing_range_nodes * BS;\r
+ if(g_viewing_range_all)\r
+ range = 100000*BS;\r
+\r
+ driver->setFog(\r
+ bgcolor,\r
+ video::EFT_FOG_LINEAR,\r
+ range*0.6,\r
+ range,\r
+ 0.01,\r
+ false, // pixel fog\r
+ false // range fog\r
+ );\r
+ }\r
+\r
\r
/*\r
Update gui stuff (0ms)\r
//TimeTaker guiupdatetimer("Gui updating", device);\r
\r
{\r
- wchar_t temptext[100];\r
+ wchar_t temptext[150];\r
\r
static float drawtime_avg = 0;\r
drawtime_avg = drawtime_avg * 0.98 + (float)drawtime*0.02;\r
+ static float beginscenetime_avg = 0;\r
+ beginscenetime_avg = beginscenetime_avg * 0.98 + (float)beginscenetime*0.02;\r
static float scenetime_avg = 0;\r
scenetime_avg = scenetime_avg * 0.98 + (float)scenetime*0.02;\r
static float endscenetime_avg = 0;\r
endscenetime_avg = endscenetime_avg * 0.98 + (float)endscenetime*0.02;\r
\r
- swprintf(temptext, 100, L"Minetest-c55 ("\r
+ swprintf(temptext, 150, L"Minetest-c55 ("\r
L"F: item=%i"\r
L", R: range_all=%i"\r
L")"\r
- L" drawtime=%.0f, scenetime=%.0f, endscenetime=%.0f",\r
+ L" drawtime=%.0f, beginscenetime=%.0f, scenetime=%.0f, endscenetime=%.0f",\r
g_selected_item,\r
g_viewing_range_all,\r
drawtime_avg,\r
+ beginscenetime_avg,\r
scenetime_avg,\r
endscenetime_avg\r
);\r
}\r
\r
{\r
- wchar_t temptext[100];\r
- /*swprintf(temptext, 100,\r
- L"("\r
- L"% .3f < btime_jitter < % .3f"\r
- L", dtime_jitter = % .1f %%"\r
- //L", ftime_ratio = % .3f"\r
- L")",\r
- busytime_jitter1_min_sample,\r
- busytime_jitter1_max_sample,\r
- dtime_jitter1_max_fraction * 100.0\r
- //g_freetime_ratio\r
- );*/\r
- swprintf(temptext, 100,\r
+ wchar_t temptext[150];\r
+ swprintf(temptext, 150,\r
L"(% .1f, % .1f, % .1f)"\r
L" (% .3f < btime_jitter < % .3f"\r
L", dtime_jitter = % .1f %%)",\r
\r
TimeTaker drawtimer("Drawing", device);\r
\r
- /*\r
- Background color is choosen based on whether the player is\r
- much beyond the initial ground level\r
- */\r
- /*video::SColor bgcolor;\r
- v3s16 p0 = Map::floatToInt(player_position);\r
- // Does this make short random delays?\r
- // NOTE: no need for this, sky doesn't show underground with\r
- // enough range\r
- bool is_underground = client.isNodeUnderground(p0);\r
- //bool is_underground = false;\r
- if(is_underground == false)\r
- bgcolor = video::SColor(255,90,140,200);\r
- else\r
- bgcolor = video::SColor(255,0,0,0);*/\r
- \r
- //video::SColor bgcolor = video::SColor(255,90,140,200);\r
- video::SColor bgcolor = skycolor;\r
\r
- // 0ms\r
+ {\r
+ TimeTaker timer("beginScene", device);\r
driver->beginScene(true, true, bgcolor);\r
+ //driver->beginScene(false, true, bgcolor);\r
+ beginscenetime = timer.stop(true);\r
+ }\r
\r
//timer3.stop();\r
\r
device->yield();*/\r
}\r
\r
+ delete quick_inventory;\r
+\r
} // client is deleted at this point\r
\r
delete g_input;\r
In the end, delete the Irrlicht device.\r
*/\r
device->drop();\r
+ \r
+ /*\r
+ Update configuration file\r
+ */\r
+ if(configpath != "")\r
+ {\r
+ g_settings.updateConfigFile(configpath.c_str());\r
+ }\r
\r
} //try\r
catch(con::PeerNotFoundException &e)\r