Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-05-07 18:56:00 +0000
committerStijn Buys <ingar@osirion.org>2008-05-07 18:56:00 +0000
commit421fc71813f08bfe359f9ac7596933a7e4cea6e0 (patch)
tree15b3630488281280d6634804b4a1a41fc402ab0a
parent91d3a0352088611d3b78d3344b7a2bf2d4955a0a (diff)
client-side frame interpolation: network updates, interpolation of position
-rw-r--r--ROADMAP32
-rw-r--r--TODO11
-rw-r--r--osirion.kdevelop.pcsbin639076 -> 653766 bytes
-rw-r--r--osirion.kdevses21
-rw-r--r--src/client/camera.cc8
-rw-r--r--src/core/commandbuffer.cc45
-rw-r--r--src/core/commandbuffer.h3
-rw-r--r--src/core/gameconnection.cc7
-rw-r--r--src/core/gameinterface.cc28
-rw-r--r--src/core/gameinterface.h4
-rw-r--r--src/core/gameserver.cc2
-rw-r--r--src/core/netserver.cc2
-rw-r--r--src/render/draw.cc30
13 files changed, 126 insertions, 67 deletions
diff --git a/ROADMAP b/ROADMAP
index 39f07ec..6241459 100644
--- a/ROADMAP
+++ b/ROADMAP
@@ -1,6 +1,6 @@
ROADMAP
-* MILESTONE 1
+* MILESTONE 1 - version 0.1
Description:
The game takes place in a simple solar system with one star,
@@ -12,32 +12,44 @@ Description:
they can use private chat or global chat.
Requires:
- Network subsystem
+ Client console
+ Entities
Ship instances
+ Network subsystem
Entities
+ Camera handling
+ Keyboard bindings
+* MILESTONE 2 - version 0.2
-* MILESTONE 2
+Description:
Players can shoot at each other. They can crash into the star
or the planet.
Requires:
- weapons
- turret and cannon models
-
+ Events: explosions, weapons fire
+ Model weapon support
+ Turret and cannon models
+ Particle systems
clip brushes and collision detection
+* MILESTONE 3 - version 0.3
-* MILESTONE 3
+Description:
Players can dock at the space station and buy a ship or purchase
weapons.
Requires:
- mechanisms for docking
- gui
+ Docking
+ Docking GUI
-* MILESTONE 4
+* MILESTONE 4 - version 0.4
* MILESTONE 5
+* Release 1.0
+
+Requires:
+ Stable network protocol
+
diff --git a/TODO b/TODO
index 728bd34..c93629e 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,13 @@
TODO
+milestone 1:
+ console text color and wrapping
+ entity axis interpolation
+ camera axis interpolation
+ camera tracking mode
+ camera frustum clip
+ keyboard binds
+
filesystem:
write a filesystem based on streams
write handlers for zip
@@ -16,6 +24,7 @@ core:
parse command line options (ok)
execute command line options (ok)
globe entity (ok)
+ execute config files
game module loading/unloading
network:
@@ -29,7 +38,7 @@ network:
zlib compression
fix lag
protocol version in handshake
-
+ detect and disconnect clients behaving badly
client:
input handler switching (ok)
console chars (ok)
diff --git a/osirion.kdevelop.pcs b/osirion.kdevelop.pcs
index c991dc8..d35692e 100644
--- a/osirion.kdevelop.pcs
+++ b/osirion.kdevelop.pcs
Binary files differ
diff --git a/osirion.kdevses b/osirion.kdevses
index 2f81c5c..d014ce3 100644
--- a/osirion.kdevses
+++ b/osirion.kdevses
@@ -1,25 +1,16 @@
<?xml version = '1.0' encoding = 'UTF-8'?>
<!DOCTYPE KDevPrjSession>
<KDevPrjSession>
- <DocsAndViews NumberOfDocuments="6" >
- <Doc0 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/gameconnection.cc" >
- <View0 Encoding="" line="44" Type="Source" />
+ <DocsAndViews NumberOfDocuments="3" >
+ <Doc0 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/netconnection.cc" >
+ <View0 Encoding="" line="0" Type="Source" />
</Doc0>
- <Doc1 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/gameserver.cc" >
- <View0 Encoding="" line="313" Type="Source" />
+ <Doc1 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/gameconnection.cc" >
+ <View0 Encoding="" line="95" Type="Source" />
</Doc1>
- <Doc2 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/entity.cc" >
+ <Doc2 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/gameserver.cc" >
<View0 Encoding="" line="0" Type="Source" />
</Doc2>
- <Doc3 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/netconnection.cc" >
- <View0 Encoding="" line="330" Type="Source" />
- </Doc3>
- <Doc4 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/entity.h" >
- <View0 Encoding="" line="44" Type="Source" />
- </Doc4>
- <Doc5 NumberOfViews="1" URL="file:///home/ingar/projects/osirion/osirion-work/src/core/netserver.cc" >
- <View0 Encoding="" line="277" Type="Source" />
- </Doc5>
</DocsAndViews>
<pluginList>
<kdevdebugger>
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());