diff options
author | Stijn Buys <ingar@osirion.org> | 2008-05-07 18:56:00 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2008-05-07 18:56:00 +0000 |
commit | 421fc71813f08bfe359f9ac7596933a7e4cea6e0 (patch) | |
tree | 15b3630488281280d6634804b4a1a41fc402ab0a /src | |
parent | 91d3a0352088611d3b78d3344b7a2bf2d4955a0a (diff) |
client-side frame interpolation: network updates, interpolation of position
Diffstat (limited to 'src')
-rw-r--r-- | src/client/camera.cc | 8 | ||||
-rw-r--r-- | src/core/commandbuffer.cc | 45 | ||||
-rw-r--r-- | src/core/commandbuffer.h | 3 | ||||
-rw-r--r-- | src/core/gameconnection.cc | 7 | ||||
-rw-r--r-- | src/core/gameinterface.cc | 28 | ||||
-rw-r--r-- | src/core/gameinterface.h | 4 | ||||
-rw-r--r-- | src/core/gameserver.cc | 2 | ||||
-rw-r--r-- | src/core/netserver.cc | 2 | ||||
-rw-r--r-- | src/render/draw.cc | 30 |
9 files changed, 88 insertions, 41 deletions
diff --git a/src/client/camera.cc b/src/client/camera.cc index 808ff7e..573194a 100644 --- a/src/client/camera.cc +++ b/src/client/camera.cc @@ -169,7 +169,13 @@ void draw(float seconds) if (mode == Overview) set_mode(Track); - target.assign(core::localcontrol()->location()); + if (core::localcontrol()->state()) { + // client prediction has not been run yet + target = core::localcontrol()->state()->previouslocation() + + (core::localcontrol()->location() - core::localcontrol()->state()->previouslocation()) * core::game()->timeoffset(); + } + else + target = core::localcontrol()->location(); if (mode == Track) { if (core::localcontrol()->model()) diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index ead2a98..56aba16 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -5,10 +5,12 @@ */ #include <string> +#include <fstream> #include <sstream> #include <list> #include "sys/sys.h" +#include "filesystem/filesystem.h" #include "core/application.h" #include "core/commandbuffer.h" #include "core/gameconnection.h" @@ -59,6 +61,16 @@ void func_set(std::string const &args) return; } +void func_exec(std::string const &args) +{ + std::istringstream argstream(args); + std::string filename; + if (!(argstream >> filename)) + return; + + CommandBuffer::exec_file(filename); +} + std::stringstream CommandBuffer::cmdbuf(std::stringstream::in | std::stringstream::out); void CommandBuffer::init() @@ -77,6 +89,9 @@ void CommandBuffer::init() func = Func::add("set", (FuncPtr)func_set); func->set_info("[variable] [str] set variable value"); + + func = Func::add("exec", (FuncPtr)exec); + func->set_info("[filename] execute commands from file"); } void CommandBuffer::shutdown() @@ -142,7 +157,7 @@ void CommandBuffer::exec(std::string const &cmdline) return; } - // TODO this must get forwarded to the server + // this gets forwarded to the server if (connection()) connection()->forward(cmdline); else @@ -219,5 +234,33 @@ void CommandBuffer::complete(std::string &input, size_t &pos) } +void CommandBuffer::exec_file(std::string const & filename) +{ + filesystem::File *f = filesystem::open(filename.c_str()); + if (!f) { + con_warn << "Could not open " << filename << std::endl; + return; + } + + std::string fn = f->path(); + fn.append(f->name()); + filesystem::close(f); + + std::ifstream ifs; + ifs.open(fn.c_str()); + if (!ifs.is_open()) { + con_warn << "Could not stream " << fn << "!\n"; + return; + } + + char line[MAXCMDSIZE]; + while (ifs.getline(line, MAXCMDSIZE-1)) { + if (line[0] && line[0] != '#' && line[0] != ';') + exec(std::string(line)); + } + + ifs.close(); +} + } diff --git a/src/core/commandbuffer.h b/src/core/commandbuffer.h index 8970d89..7b26211 100644 --- a/src/core/commandbuffer.h +++ b/src/core/commandbuffer.h @@ -28,6 +28,9 @@ public: /// clear the command buffer static void clear(); + /// execute commands from a file + static void exec_file(std::string const & filename); + /// global buffer to hold the command stream static std::stringstream cmd; diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index baf0967..b5ac27d 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -89,20 +89,21 @@ void GameConnection::frame(float seconds) } if (!Cvar::sv_dedicated->value()) { - update_clientstate(); + update_clientstate(seconds); } + connection_network->frame(seconds); + connection_frametime += seconds; float f = 0; if (core::Cvar::sv_framerate->value()) { - f = 1.0f / core::Cvar::sv_framerate->value(); + f = 0.5f / core::Cvar::sv_framerate->value(); if (connection_frametime < f) { return; } } - connection_network->frame(connection_frametime); connection_frametime = 0; if (localcontrol() && localcontrol()->dirty()) { diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc index 8d351a0..d1bc1c3 100644 --- a/src/core/gameinterface.cc +++ b/src/core/gameinterface.cc @@ -95,48 +95,40 @@ void GameInterface::clear() game_previousframetime = 0; game_serverframetime = 0; game_clientframetime = 0; - game_timestep = 0; - game_frames = 0; } void GameInterface::reset_clientstate(float servertime) { - game_timestep = (servertime - game_serverframetime); - - if (game_timestep < 0) - game_timestep = 0; - game_previousframetime = game_serverframetime; - game_serverframetime = servertime; - game_clientframetime = game_previousframetime; + game_clientframetime = game_serverframetime; + game_serverframetime = servertime; + std::map<unsigned int, core::Entity *>::iterator it; for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { core::Entity *entity = (*it).second; - if (entity->state() && !(entity->flags() & Entity::Static)) + if (entity->state() && !(entity->flags() & core::Entity::Static)) entity->state()->assign(entity); } - - game_frames = 0; } -void GameInterface::update_clientstate() +void GameInterface::update_clientstate(float seconds) { - game_frames++; - game_clientframetime += game_timestep; + game_clientframetime += seconds; if (game_clientframetime > game_serverframetime) game_clientframetime = game_serverframetime; } float GameInterface::timeoffset() { + float d = game_serverframetime - game_previousframetime; - if (d < 0) - d = 1; - float t = game_serverframetime - game_clientframetime; + if (d <= 0) + return 0; + float t = game_clientframetime - game_previousframetime; return t/d; } diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h index 2324bb5..0edcb1b 100644 --- a/src/core/gameinterface.h +++ b/src/core/gameinterface.h @@ -55,7 +55,7 @@ public: void reset_clientstate(float servertime); /// update the client state timers - void update_clientstate(); + void update_clientstate(float seconds); /*----- virtual mutators ------------------------------------------ */ @@ -73,7 +73,7 @@ protected: float game_timestep; float game_clientframetime; - unsigned int game_frames; + unsigned int game_serverframelength; }; /// global local player instance diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 3c126fc..3e5241e 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -260,7 +260,7 @@ void GameServer::frame(float seconds) localplayer()->update_info(); if (!Cvar::sv_dedicated->value()) { - update_clientstate(); + update_clientstate(seconds); } server_frametime += seconds; diff --git a/src/core/netserver.cc b/src/core/netserver.cc index 3005922..e66f63d 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -179,7 +179,7 @@ void NetServer::receive() timeval timeout; timeout.tv_sec = 0; - timeout.tv_usec = 5000; + timeout.tv_usec = 2500; fd_set readset = serverset; int nb = select(fd()+1, &readset, NULL, NULL, &timeout); diff --git a/src/render/draw.cc b/src/render/draw.cc index b0671de..26655e0 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -238,12 +238,7 @@ void pass_prepare() for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { core::Entity *entity = (*it).second; - if (!entity->state()) { - entity->entity_clientstate = new core::ClientState(); - } - entity->state()->state_visible = false; - entity->state()->state_detailvisible = false; - + // load entity models and light flare textures if (!entity->model() && entity->modelname().size()) { entity->entity_model = model::Model::load(entity->modelname()); @@ -263,7 +258,14 @@ void pass_prepare() } // update client state - if (entity->state() && flag_is_set(entity->flags(), core::Entity::Static)) { + if (!entity->state()) { + entity->entity_clientstate = new core::ClientState(); + entity->state()->assign(entity); + } + entity->state()->state_visible = false; + entity->state()->state_detailvisible = false; + + if (!flag_is_set(entity->flags(), core::Entity::Static)) { entity->state()->state_location = entity->state()->previouslocation() + (entity->location() - entity->state()->previouslocation()) * core::game()->timeoffset(); } @@ -310,7 +312,7 @@ void draw_pass_default() // draw entities without model if (!entity->model()) { gl::push(); - gl::translate(entity->location()); + gl::translate(entity->state()->location()); gl::multmatrix(entity->axis()); if (flag_is_set(entity->flags(), core::Entity::Bright)) { @@ -353,7 +355,7 @@ void draw_pass_model_vertex() core::Entity *entity = (*it).second; if (entity->model() && entity->state()->visible()) { gl::push(); - gl::translate(entity->location()); + gl::translate(entity->state()->location()); gl::multmatrix(entity->axis()); draw_model_vertex(entity); @@ -373,7 +375,7 @@ void draw_pass_model_evertex() if (entity->model() && entity->state()->visible()) { gl::push(); - gl::translate(entity->location()); + gl::translate(entity->state()->location()); gl::multmatrix(entity->axis()); draw_model_evertex(entity); @@ -395,7 +397,7 @@ void draw_pass_model_shields() { if (entity->type() == core::Entity::Controlable) { gl::push(); - gl::translate(entity->location()); + gl::translate(entity->state()->location()); gl::multmatrix(entity->axis()); draw_model_shield((core::EntityControlable *)entity); @@ -432,7 +434,7 @@ void draw_pass_model_fx() t = (core::application()->time() + entity->state()->fuzz() + (*lit)->offset()) * (*lit)->frequency(); if (!(*lit)->strobe() || (( t - floorf(t)) <= (*lit)->time())) { - math::Vector3f location = entity->location() + (entity->axis() * (*lit)->location()); + math::Vector3f location = entity->state()->location() + (entity->axis() * (*lit)->location()); float light_size = 0.0625 * (*lit)->radius(); if ((*lit)->render_texture != flare_texture) { @@ -483,7 +485,7 @@ void draw_pass_model_fx() t = 0.75f + t/2; for(std::list<model::Engine*>::iterator eit = entity->model()->model_engine.begin(); eit != entity->model()->model_engine.end(); eit++) { - math::Vector3f location = entity->location() + (entity->axis() * (*eit)->location()); + math::Vector3f location = entity->state()->location() + (entity->axis() * (*eit)->location()); float engine_size = 0.0625 * (*eit)->radius() * t; math::Color color(1.0f, 0.0f, 0.0f, 0.9f * u); @@ -518,7 +520,7 @@ void draw_pass_model_corona() if (entity->state()->visible() && (entity->shape() != core::Entity::Sphere)) { gl::push(); - gl::translate(entity->location()); + gl::translate(entity->state()->location()); math::Color color = entity->color(); color.a = 0.25f; draw_sphere(color, entity->model()->radius()); |