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-10-16 16:34:15 +0000
committerStijn Buys <ingar@osirion.org>2008-10-16 16:34:15 +0000
commit1a28393dabf4f4696bf433ddde52e7a25253c955 (patch)
tree4d4fa4034f30fc882a78ab6ea148a32e83b9e88c
parent1e0df536c2fae85c317ce9c3cc17603d5f98c911 (diff)
various user interface related updates
-rw-r--r--src/audio/audio.cc19
-rw-r--r--src/audio/audio.h3
-rw-r--r--src/audio/buffers.cc8
-rw-r--r--src/audio/buffers.h1
-rw-r--r--src/audio/sources.cc15
-rw-r--r--src/audio/sources.h1
-rw-r--r--src/client/chat.cc15
-rw-r--r--src/client/chat.h4
-rw-r--r--src/client/client.cc30
-rw-r--r--src/client/client.h4
-rw-r--r--src/client/console.cc28
-rw-r--r--src/client/console.h4
-rw-r--r--src/client/input.cc34
-rw-r--r--src/client/input.h2
-rw-r--r--src/client/targets.cc4
-rw-r--r--src/client/video.cc41
-rw-r--r--src/client/video.h11
-rw-r--r--src/client/view.cc170
-rw-r--r--src/core/application.cc19
-rw-r--r--src/core/application.h11
-rw-r--r--src/core/clientstate.cc16
-rw-r--r--src/core/cvar.cc25
-rw-r--r--src/core/cvar.h1
-rw-r--r--src/core/func.cc2
-rw-r--r--src/core/gameconnection.cc22
-rw-r--r--src/core/gameconnection.h11
-rw-r--r--src/core/gameinterface.cc48
-rw-r--r--src/core/gameinterface.h35
-rw-r--r--src/core/gameserver.cc37
-rw-r--r--src/core/gameserver.h11
-rw-r--r--src/core/net.h2
-rw-r--r--src/core/netconnection.cc9
-rw-r--r--src/core/netconnection.h7
-rw-r--r--src/core/netserver.cc12
-rw-r--r--src/core/netserver.h6
-rw-r--r--src/core/timer.cc14
-rw-r--r--src/core/timer.h5
-rw-r--r--src/filesystem/diskfile.cc4
-rw-r--r--src/filesystem/filesystem.cc9
-rw-r--r--src/render/image.cc25
-rw-r--r--src/render/image.h3
-rw-r--r--src/render/render.cc17
-rw-r--r--src/render/render.h3
-rw-r--r--src/server/console.cc20
-rw-r--r--src/server/console.h8
-rw-r--r--src/server/server.cc13
-rw-r--r--src/sys/consoleinterface.h10
-rw-r--r--src/ui/Makefile.am4
-rw-r--r--src/ui/button.cc14
-rw-r--r--src/ui/container.cc17
-rw-r--r--src/ui/container.h2
-rw-r--r--src/ui/definitions.h2
-rw-r--r--src/ui/inputbox.cc (renamed from src/ui/input.cc)20
-rw-r--r--src/ui/inputbox.h (renamed from src/ui/input.h)14
-rw-r--r--src/ui/menu.h2
-rw-r--r--src/ui/palette.cc27
-rw-r--r--src/ui/palette.h16
-rw-r--r--src/ui/ui.cc68
-rw-r--r--src/ui/ui.h16
-rw-r--r--src/ui/widget.cc4
-rw-r--r--src/ui/widget.h2
-rw-r--r--src/ui/window.cc8
-rw-r--r--src/ui/window.h3
63 files changed, 586 insertions, 432 deletions
diff --git a/src/audio/audio.cc b/src/audio/audio.cc
index 81a260c..ca30590 100644
--- a/src/audio/audio.cc
+++ b/src/audio/audio.cc
@@ -18,13 +18,13 @@ ALCcontext *audio_context = 0;
void init()
{
- con_print << "^BInitializing audio...";
+ con_print << "^BInitializing audio..." << std::endl;
// open the default audio device
audio_device = alcOpenDevice(0);
if (!audio_device) {
- con_warn << "Could not initialize audio!";
+ con_warn << "Could not initialize audio!" << std::endl;
return;
}
@@ -34,7 +34,7 @@ void init()
if (!audio_context) {
alcCloseDevice(audio_device);
audio_device = 0;
- con_warn << "Could not create audio context!";
+ con_warn << "Could not create audio context!" << std::endl;
return;
}
@@ -56,6 +56,17 @@ void init()
load("ui/console");
}
+void reset()
+{
+ con_print << "^BReloading audio..." << std::endl;
+
+ Sources::reset();
+ Buffers::reset();
+
+ load("ui/nosnd");
+ load("ui/console");
+}
+
void load (const char *name)
{
Buffers::load(std::string(name));
@@ -63,7 +74,7 @@ void load (const char *name)
void shutdown()
{
- con_print << "^BShutting down audio...";
+ con_print << "^BShutting down audio..." << std::endl;
Sources::shutdown();
diff --git a/src/audio/audio.h b/src/audio/audio.h
index c0479d3..930edaf 100644
--- a/src/audio/audio.h
+++ b/src/audio/audio.h
@@ -29,6 +29,9 @@ void init();
/// shut down the audio subsystem
void shutdown();
+/// reload audio
+void reset();
+
/// load an audio sample
void load(const char *name);
diff --git a/src/audio/buffers.cc b/src/audio/buffers.cc
index af14cb1..33c4dbf 100644
--- a/src/audio/buffers.cc
+++ b/src/audio/buffers.cc
@@ -25,7 +25,7 @@ void Buffers::init()
alGenBuffers(MAXBUFFERS, buffers);
if ((error = alGetError()) != AL_NO_ERROR) {
- con_warn << "Error " << std::hex << error << " initializing OpenAL buffers!" << std::endl;
+ con_warn << "Error " << error << " initializing OpenAL buffers!" << std::endl;
return;
}
}
@@ -44,6 +44,12 @@ void Buffers::clear()
index = 0;
}
+void Buffers::reset()
+{
+ shutdown();
+ init();
+}
+
size_t Buffers::load(std::string name)
{
// check if it is already loaded
diff --git a/src/audio/buffers.h b/src/audio/buffers.h
index cc7a6c8..462afff 100644
--- a/src/audio/buffers.h
+++ b/src/audio/buffers.h
@@ -23,6 +23,7 @@ class Buffers {
public:
static void init();
static void shutdown();
+ static void reset();
/// find previously loaded PCM data
static size_t find(std::string name);
diff --git a/src/audio/sources.cc b/src/audio/sources.cc
index 584f366..01fbafb 100644
--- a/src/audio/sources.cc
+++ b/src/audio/sources.cc
@@ -23,7 +23,7 @@ void Sources::init()
alGenSources(MAXSOURCES, sources);
if ((error = alGetError()) != AL_NO_ERROR) {
- con_warn << "Error " << std::hex << error << " initializing OpenAL sources!" << std::endl;
+ con_warn << "Error " << error << " initializing OpenAL sources!" << std::endl;
return;
}
@@ -55,6 +55,19 @@ void Sources::clear()
}
+void Sources::reset()
+{
+ for (size_t index= 0; index < MAXSOURCES; index++) {
+ source_available[index] = true;
+ alSourceRewind(sources[index]);
+ }
+
+ // reserve ui sound sources
+ for (size_t i=0; i < MAXUISOURCES; i++) {
+ source_available[i] = false;
+ }
+}
+
size_t Sources::get()
{
for (size_t i= MAXUISOURCES; i < MAXSOURCES; i++) {
diff --git a/src/audio/sources.h b/src/audio/sources.h
index 078c424..f01e7a4 100644
--- a/src/audio/sources.h
+++ b/src/audio/sources.h
@@ -23,6 +23,7 @@ class Sources {
public:
static void init();
static void shutdown();
+ static void reset();
static inline bool available(size_t index) { return source_available[index]; }
diff --git a/src/client/chat.cc b/src/client/chat.cc
index 6d294ba..9d51adc 100644
--- a/src/client/chat.cc
+++ b/src/client/chat.cc
@@ -23,9 +23,10 @@ Chat::Chat(ui::Widget *parent) : ui::Window(parent)
chat_label = new ui::Label(this, "^BSay^F:^B");
chat_label->set_alignment(ui::AlignLeft | ui::AlignVCenter);
+ chat_label->set_border(false);
- chat_input = new ui::Input(this);
- chat_input->set_border(true);
+ chat_input = new ui::InputBox(this);
+ chat_input->set_border(false);
chat_input->set_focus();
@@ -79,19 +80,17 @@ bool Chat::on_keypress(const int key, const unsigned int modifier)
}
case SDLK_RETURN:
if (chat_input->text().size()) {
- (*history_pos).assign(chat_input->text());
-
// store input into history
while (history.size() >= DEFAULT_MAX_HISTO_LINES) {
history.pop_front();
}
- if ((*history_pos).c_str()[0] == '/' || (*history_pos).c_str()[0] == '\\') {
- core::cmd() << &(*history_pos).c_str()[1] << std::endl;
+ if (chat_input->text().c_str()[0] == '/' || chat_input->text().c_str()[0] == '\\') {
+ core::cmd() << &chat_input->text().c_str()[1] << std::endl;
} else {
- core::cmd() << "say " << (*history_pos) << std::endl;
+ core::cmd() << "say " << chat_input->text() << std::endl;
}
- (*history.rbegin()) = (*history_pos);
+ (*history.rbegin()) = chat_input->text();
history.push_back("");
history_pos = history.rbegin();
diff --git a/src/client/chat.h b/src/client/chat.h
index f076075..c7232a9 100644
--- a/src/client/chat.h
+++ b/src/client/chat.h
@@ -10,7 +10,7 @@
#include <sstream>
#include <deque>
-#include "ui/input.h"
+#include "ui/inputbox.h"
#include "ui/label.h"
#include "ui/window.h"
@@ -34,7 +34,7 @@ protected:
private:
ui::Label *chat_label;
- ui::Input *chat_input;
+ ui::InputBox *chat_input;
typedef std::deque<std::string> History;
diff --git a/src/client/client.cc b/src/client/client.cc
index 200becd..13c6214 100644
--- a/src/client/client.cc
+++ b/src/client/client.cc
@@ -41,9 +41,7 @@ void func_snd_restart(std::string const &args)
entity->state()->clearsound();
}
- audio::shutdown();
-
- audio::init();
+ audio::reset();
}
void func_r_restart(std::string const &args)
@@ -96,7 +94,7 @@ void Client::init(int count, char **arguments)
con_print << "^BInitializing client..." << std::endl;
// initialize core
- core::Cvar::sv_dedicated = core::Cvar::set("sv_private", "0");
+ core::Cvar::sv_private = core::Cvar::set("sv_private", "0");
core::Application::init(count, arguments);
// client variables
@@ -145,8 +143,10 @@ void Client::init(int count, char **arguments)
func = core::Func::add("ui_console", func_ui_console);
func->set_info("toggle console on or off");
- //func = core::Func::add("snd_restart", (core::FuncPtr) func_snd_restart);
- //func->set_info("restart audio subsystem");
+ func = core::Func::add("snd_restart", (core::FuncPtr) func_snd_restart);
+ func->set_info("restart audio subsystem");
+
+ previous_timestamp = 0;
}
void Client::run()
@@ -182,10 +182,7 @@ void Client::run()
Uint32 d = client_current_timestamp - client_previous_timestamp;
if ((d > 0)) {
if (d >= client_frame_lenght) {
- float elapsed = (float)(d) / 1000.f;
-
- frame(elapsed);
-
+ frame(client_current_timestamp);
client_previous_timestamp = client_current_timestamp;
} else {
SDL_Delay(client_frame_lenght - d);
@@ -197,9 +194,9 @@ void Client::run()
}
-void Client::frame(float seconds)
+void Client::frame(unsigned long timestamp)
{
- core::Application::frame(seconds);
+ core::Application::frame(timestamp);
if (!core::application()->connected()) {
// load the intro if nothing is running
@@ -217,8 +214,9 @@ void Client::frame(float seconds)
}
}
- video::frame(seconds);
- input::frame(seconds);
+ video::frame((float)(timestamp - previous_timestamp) / 1000.0f);
+ input::frame();
+ previous_timestamp = timestamp;
}
void Client::shutdown()
@@ -230,7 +228,7 @@ void Client::shutdown()
core::Func::remove("r_restart");
core::Func::remove("ui_chat");
core::Func::remove("ui_console");
- //core::Func::remove("snd_restart");
+ core::Func::remove("snd_restart");
audio::shutdown();
@@ -254,7 +252,7 @@ void Client::notify_connect()
void Client::notify_disconnect()
{
- // FIXME unload sounds
+ audio::reset();
render::reset();
input::reset();
}
diff --git a/src/client/client.h b/src/client/client.h
index 6e19848..67fba13 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -56,11 +56,13 @@ public:
protected:
/// run a client frame
- virtual void frame(float seconds);
+ virtual void frame(unsigned long timestamp);
private:
View *client_view;
Console *client_console;
+
+ unsigned long previous_timestamp;
};
diff --git a/src/client/console.cc b/src/client/console.cc
index 0ab0767..80b6224 100644
--- a/src/client/console.cc
+++ b/src/client/console.cc
@@ -48,18 +48,17 @@ Console::Console(ui::Widget *parent) : ui::Window(parent)
set_background(true);
set_label("console");
- //clear_notify();
- load_history();
-
console_scroll = 0;
history.clear();
history.push_back("");
history_pos = history.rbegin();
- console_input = new ui::Input(this);
+ console_input = new ui::InputBox(this);
console_input->set_focus();
console_input->set_border(false);
console_input->set_background(false);
+
+ load_history();
}
Console::~Console()
@@ -125,15 +124,12 @@ bool Console::on_keypress(const int key, const unsigned int modifier)
case SDLK_RETURN:
if (console_input->text().size()) {
// store input in history
- (*history_pos).assign(console_input->text());
while (history.size() >= DEFAULT_MAX_HISTO_LINES) {
history.pop_front();
}
-
- core::cmd() << (*history_pos) << std::endl;
- con_print << "^B>" << (*history_pos) << std::endl;
- (*history.rbegin()) = (*history_pos);
-
+ core::cmd() << console_input->text() << std::endl;
+ con_print << "^B>" << console_input->text() << std::endl;
+ (*history.rbegin()).assign(console_input->text());
history.push_back("");
history_pos = history.rbegin();
console_input->set_text((*history_pos));
@@ -209,10 +205,10 @@ void Console::draw()
if (console_scroll > log().size())
console_scroll = log().size();
- size_t height = (size_t) (this->height() / font()->height()) -1;
- size_t width = (size_t) ((this->width()-8) / font()->width());
- size_t bottom = log().size() - console_scroll;
- size_t current_line = 0;
+ int height = (size_t) (this->height() / font()->height()) -1;
+ int width = (size_t) ((this->width()-8) / font()->width());
+ int bottom = (int) log().size() - console_scroll;
+ int current_line = 0;
Text lines;
for (Text::iterator it = log().begin(); it != log().end() && current_line < bottom; it++) {
@@ -243,7 +239,7 @@ void Console::draw()
// new word, wrap if necessary
else if ((*c == '\n' ) || ( *c == ' ')) {
- if (line_length + word_length > width) {
+ if (line_length + word_length > (size_t) width) {
if (line.size()) {
lines.push_back(line);
line.clear();
@@ -277,7 +273,7 @@ void Console::draw()
word += *c;
word_length++;
- if (word_length == width) {
+ if (word_length == (size_t) width) {
if (line.size()) {
lines.push_back(line);
line.clear();
diff --git a/src/client/console.h b/src/client/console.h
index 4b2df20..7400c32 100644
--- a/src/client/console.h
+++ b/src/client/console.h
@@ -9,7 +9,7 @@
#include "sys/consoleinterface.h"
#include "ui/window.h"
-#include "ui/input.h"
+#include "ui/inputbox.h"
namespace client {
@@ -69,7 +69,7 @@ private:
size_t console_scroll;
// input widget
- ui::Input *console_input;
+ ui::InputBox *console_input;
// console buffer
static ConsoleBuffer con_buffer;
diff --git a/src/client/input.cc b/src/client/input.cc
index a72999e..1e018f5 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -486,8 +486,19 @@ void key_pressed(Key *key)
render::Camera::set_pitch(0.0f);
client()->console()->toggle();
+ return;
+ }
+
+ if (ui::root()->active()) {
+ local_direction = 0.0f;
+ local_pitch = 0.0f;
+ local_roll = 0.0f;
- } else if (ui::root()->input_key(true, Keyboard::translate_keysym(key->sym(), keyboard_modifiers), keyboard_modifiers)) {
+ render::Camera::set_direction(0.0f);
+ render::Camera::set_pitch(0.0f);
+ }
+
+ if (ui::root()->input_key(true, Keyboard::translate_keysym(key->sym(), keyboard_modifiers), keyboard_modifiers)) {
return;
} else if (core::application()->connected() && core::localcontrol()) {
@@ -609,8 +620,8 @@ void reset()
}
mouse_pitch = 0.0f;
mouse_direction = 0.0f;
- mouse_x = video::width / 2;
- mouse_y = video::height / 2;
+ mouse_x = render::Camera::width() / 2;
+ mouse_y = render::Camera::height() / 2;
render::Camera::reset();
render::Dust::reset();
mouse_control_override = false;
@@ -631,7 +642,7 @@ void reset()
joystick_lastmoved = 0;
}
-void frame(float seconds)
+void frame()
{
/* -- detect localcontrol() changes --------------- */
if (core::localcontrol() && (last_control != core::localcontrol()->id())) {
@@ -662,6 +673,9 @@ void frame(float seconds)
key = 0;
switch (event.type) {
+ case SDL_VIDEORESIZE:
+ video::resize((float) event.resize.w, (float) event.resize.h);
+ break;
case SDL_MOUSEMOTION:
mouse_x = event.motion.x;
@@ -774,26 +788,26 @@ void frame(float seconds)
mouse_deadzone = true;
// direction
- int l = mouse_x - (video::width >> 1);
+ int l = mouse_x - (render::Camera::width() >> 1);
if (abs(l) < ( deadzone_size >> 1 )) {
// dead zone
mouse_direction = 0;
} else {
- l = (mouse_x - deadzone_size) - ((video::width - deadzone_size) >> 1);
- mouse_direction = float (-l) / (float) ((video::width - deadzone_size) >> 1);
+ l = (mouse_x - deadzone_size) - ((render::Camera::width() - deadzone_size) >> 1);
+ mouse_direction = float (-l) / (float) ((render::Camera::width() - deadzone_size) >> 1);
mouse_deadzone = false;
}
// pitch
- int h = mouse_y - (video::height >> 1);
+ int h = mouse_y - (render::Camera::height() >> 1);
if (abs(h) < ( deadzone_size >> 1 )) {
// dead zone
mouse_pitch = 0;
} else {
- h = (mouse_y - deadzone_size) - ((video::height - deadzone_size) >> 1);
- mouse_pitch = float (-h) / (float) ((video::height - deadzone_size) >> 1);
+ h = (mouse_y - deadzone_size) - ((render::Camera::height() - deadzone_size) >> 1);
+ mouse_pitch = float (-h) / (float) ((render::Camera::height() - deadzone_size) >> 1);
mouse_deadzone = false;
}
diff --git a/src/client/input.h b/src/client/input.h
index a954040..88a65b3 100644
--- a/src/client/input.h
+++ b/src/client/input.h
@@ -23,7 +23,7 @@ void init();
void shutdown();
/// handle one frame of input events
-void frame(float seconds);
+void frame();
/// reset input state
void reset();
diff --git a/src/client/targets.cc b/src/client/targets.cc
index b533974..c7fcf9e 100644
--- a/src/client/targets.cc
+++ b/src/client/targets.cc
@@ -413,8 +413,8 @@ void draw()
x = 0;
y = 0;
} else {
- x = (float)(input::mouse_position_x() - video::width /2) / (float)video::width;
- y = (float)(input::mouse_position_y() - video::height /2) / (float)video::height / render::Camera::aspect();
+ x = (float)(input::mouse_position_x() - render::Camera::width() /2) / (float)render::Camera::width();
+ y = (float)(input::mouse_position_y() - render::Camera::height() /2) / (float)render::Camera::height() / render::Camera::aspect();
}
Vector3f cursor = render::Camera::eye() + render::Camera::axis().forward() * (render::Camera::frustum_front() + 0.001);
diff --git a/src/client/video.cc b/src/client/video.cc
index 7338d70..d8ba316 100644
--- a/src/client/video.cc
+++ b/src/client/video.cc
@@ -28,6 +28,9 @@ namespace video {
float fullscreen = 0;
+int bpp = 0;
+int flags = 0;
+
int width = 0;
int height = 0;
@@ -57,9 +60,6 @@ bool init()
r_fullscreen = core::Cvar::get("r_fullscreen", "0", core::Cvar::Archive);
r_fullscreen->set_info("[bool] enable or disable fullscreen video");
- int bpp = 0;
- int flags = 0;
-
if( SDL_InitSubSystem(SDL_INIT_VIDEO) < 0 ) {
con_error << "SDL_InitSubSystem() failed: " << SDL_GetError() << std::endl;
return false;
@@ -103,7 +103,7 @@ bool init()
if (r_fullscreen->value()) {
flags = SDL_OPENGL | SDL_FULLSCREEN;
} else {
- flags = SDL_OPENGL;
+ flags = SDL_OPENGL | SDL_RESIZABLE;
}
if(!SDL_SetVideoMode(width, height, bpp, flags )) {
@@ -147,17 +147,42 @@ bool init()
// resize user interface
ui::root()->set_size((float) width, (float) height);
ui::root()->event_resize();
+
+ // to grab or not to grab
+ if (client()->console()->visible()) {
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ SDL_ShowCursor(SDL_ENABLE);
+ } else {
+ SDL_WM_GrabInput(SDL_GRAB_ON);
+ SDL_ShowCursor(SDL_DISABLE);
+ }
// initialize renderer
- render::Camera::resize(width, height);
render::init();
- render::Camera::resize(width, height); // yes twice, bug
+ render::resize(width, height);
view::init();
return true;
}
+void resize(float w, float h)
+{
+ if (fullscreen)
+ return;
+
+ if (h < 64) h = 64;
+ if (w < 64) w = 64;
+
+ if (SDL_SetVideoMode(w, h, bpp, flags )) {
+ render::resize(w, h);
+ ui::root()->set_size(w, h);
+ ui::root()->event_resize();
+ } else {
+ con_warn << "Could not resize window!" << std::endl;
+ }
+}
+
void restart()
{
shutdown();
@@ -168,14 +193,14 @@ void restart()
input::reset();
}
-void frame(float seconds)
+void frame(float elapsed)
{
// detect fullscreen/windowed mode switch
if (fullscreen != r_fullscreen->value())
restart();
// render a client frame
- view::frame(seconds);
+ view::frame(elapsed);
SDL_GL_SwapBuffers();
}
diff --git a/src/client/video.h b/src/client/video.h
index daa136c..a28b17d 100644
--- a/src/client/video.h
+++ b/src/client/video.h
@@ -24,14 +24,11 @@ namespace video
*/
void restart();
- /// draw the next client video frame
- void frame(float seconds);
-
- /// width of the application window in pixels
- extern int width;
+ /// application window resize event in windowed mode
+ void resize(float w, float h);
- /// height of the application window in pixels
- extern int height;
+ /// draw the next client video frame
+ void frame(float elapsed);
} // namespace video
diff --git a/src/client/view.cc b/src/client/view.cc
index a8d9c4f..22d39a7 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -38,7 +38,7 @@ core::Cvar *draw_keypress = 0;
core::Cvar *ui_pointercolor = 0;
core::Cvar *ui_pointerhovercolor = 0;
-const float pointer_size = 48.0f;
+unsigned long previousframe = 0;
void time_to_stream(std::stringstream &str, float time)
{
@@ -127,7 +127,7 @@ void Stats::draw()
if (core::game()) {
textstream << "^Ntime ^B";
- time_to_stream(textstream, core::game()->clientframetime());
+ time_to_stream(textstream, core::game()->time());
}
textstream << std::setfill(' ') << "\n";
@@ -226,7 +226,7 @@ void View::resize()
height() - view_keypress->height() - font()->height() * 0.5f);
// reposition center
- view_center->set_size(pointer_size, pointer_size);
+ view_center->set_size(ui::pointer_size, ui::pointer_size);
view_center->set_location((size() - view_center->size()) * 0.5f);
view_center->set_color(palette()->pointer());
}
@@ -263,6 +263,8 @@ void init()
ui_pointerhovercolor->set_info("[r g b] mouse pointer hover color");
targets::init();
+
+ previousframe = 0;
}
void shutdown()
@@ -366,9 +368,9 @@ void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target)
const float r = 16;
const float margin = 24;
- cx = (0.5f - cx) * ((float) video::width - margin*2);
+ cx = (0.5f - cx) * ((float) render::Camera::width() - margin*2);
cx += margin;
- cy = (0.5f - cy) * ((float)video::height - margin*2);
+ cy = (0.5f - cy) * ((float) render::Camera::height() - margin*2);
cy += margin;
render::gl::disable(GL_TEXTURE_2D);
@@ -419,16 +421,15 @@ void draw_entity_target(core::Entity *entity, bool is_active_target)
float t = (render::Camera::frustum_front() + 0.001f) / target.x;
Vector3f center(target *t);
- float cx = video::width * (0.5 - center.y);
- float cy = video::height * (0.5 - center.z * render::Camera::aspect());
+ float cx = render::Camera::width() * (0.5 - center.y);
+ float cy = render::Camera::height() * (0.5 - center.z * render::Camera::aspect());
- if ((cx < 0 ) || (cy < 0) || (cx > video::width) || (cy > video::height)) {
+ if ((cx < 0 ) || (cy < 0) || (cx > render::Camera::width()) || (cy > render::Camera::height())) {
draw_entity_offscreen_target(entity, is_active_target);
return;
}
- const float pointer_size = 48.0f;
- float r = pointer_size;
+ float r = ui::pointer_size;
if (!is_active_target)
r *= 0.5;
@@ -524,7 +525,7 @@ void draw_hud()
statestr << "^FJumping...";
}
- Text::draw(4, video::height - Text::fontheight()*3-4, statestr);
+ Text::draw(4, render::Camera::height() - Text::fontheight()*3-4, statestr);
}
core::Entity *target = targets::current();
@@ -550,28 +551,28 @@ void draw_hud()
strtarget << " --";
}
strtarget << '\n';
- Text::draw(video::width - 4-Text::fontwidth()*32, video::height - Text::fontheight()*2 -4, strtarget);
+ Text::draw(render::Camera::width() - 4-Text::fontwidth()*32, render::Camera::height() - Text::fontheight()*2 -4, strtarget);
y = 3.0f;
}
Text::setcolor('N'); //set normal color
- Text::draw(video::width-4-Text::fontwidth()*32, video::height-Text::fontheight()*y-4, core::localcontrol()->zone()->name());
+ Text::draw(render::Camera::width()-4-Text::fontwidth()*32, render::Camera::height()-Text::fontheight()*y-4, core::localcontrol()->zone()->name());
Textures::bind("bitmaps/hud/thruster_base"); // 316 x 32 bitmap
gl::color(1, 1, 1, 1);
gl::begin(render::gl::Quads);
glTexCoord2f(0, 0);
- gl::vertex(4, video::height - 4 - 32, 0);
+ gl::vertex(4, render::Camera::height() - 4 - 32, 0);
glTexCoord2f(1, 0);
- gl::vertex(4 + 316, video::height - 4 - 32, 0);
+ gl::vertex(4 + 316, render::Camera::height() - 4 - 32, 0);
glTexCoord2f(1, 1);
- gl::vertex(4 + 316, video::height - 4 , 0);
+ gl::vertex(4 + 316, render::Camera::height() - 4 , 0);
glTexCoord2f(0, 1);
- gl::vertex(4, video::height - 4 , 0);
+ gl::vertex(4, render::Camera::height() - 4 , 0);
gl::end();
@@ -594,16 +595,16 @@ void draw_hud()
Textures::bind("bitmaps/hud/thruster_indicator"); // 316 x 32 bitmap
gl::begin(render::gl::Quads);
glTexCoord2f(0, 0);
- gl::vertex(4, video::height - 4 - 32, 0);
+ gl::vertex(4, render::Camera::height() - 4 - 32, 0);
glTexCoord2f(u, 0);
- gl::vertex(4.0f + u * 316.0f, video::height - 4 - 32, 0);
+ gl::vertex(4.0f + u * 316.0f, render::Camera::height() - 4 - 32, 0);
glTexCoord2f(u, 1);
- gl::vertex(4.0f + u * 316.0f, video::height - 4 , 0);
+ gl::vertex(4.0f + u * 316.0f, render::Camera::height() - 4 , 0);
glTexCoord2f(0, 1);
- gl::vertex(4, video::height - 4 , 0);
+ gl::vertex(4, render::Camera::height() - 4 , 0);
gl::end();
}
@@ -613,7 +614,7 @@ void draw_hud()
std::stringstream speedstr;
speedstr << "^B" << roundf(core::localcontrol()->speed() * 100.0f);
- Text::draw( 316+4+10, video::height - 6 -16 - render::Text::fontwidth() /2, speedstr);
+ Text::draw( 316+4+10, render::Camera::height() - 6 -16 - render::Text::fontwidth() /2, speedstr);
Text::setfont("gui", 12, 18);
Text::setcolor('N'); //set normal color
@@ -622,102 +623,45 @@ void draw_hud()
void draw_cursor()
{
- if (client()->console()->visible())
- return;
+ if (client()->console()->visible()) {
+ ui::root()->set_pointer();
- float angle = 0;
-
- float x = (float) input::mouse_position_x() - (pointer_size / 2.0f);
- float y = (float) input::mouse_position_y() - (pointer_size / 2.0f);
- bool cursor_animated = false;
- math::Color color(1.0, 0.5);
-
- if(ui::root()->active()) {
- render::Textures::bind("bitmaps/pointers/pointer");
+ } else if(ui::root()->active()) {
- } else if (core::localcontrol()) {
+ ui::root()->set_pointer("pointer");
- if (render::Camera::mode() == render::Camera::Overview) {
- render::Textures::bind("bitmaps/pointers/aim");
-
- } else {
- if (targets::hover()) {
-
- if (ui_pointerhovercolor) {
- std::stringstream colorstr(ui_pointerhovercolor->str());
- colorstr >> color;
- }
- render::Textures::bind("bitmaps/pointers/target");
-
- cursor_animated = true;
-
- if (input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) {
- x = (video::width - pointer_size) /2;
- y = (video::height - pointer_size) /2;
- }
-
- } else if (input::mouse_control) {
-
- if (ui_pointercolor) {
- std::stringstream colorstr(ui_pointercolor->str());
- colorstr >> color;
- }
-
- render::Textures::bind("bitmaps/pointers/control");
-
- if (!input::mouse_deadzone) {
- x = input::mouse_position_x() - (pointer_size /2);
- y = input::mouse_position_y() - (pointer_size /2);
-
- } else {
- x = (video::width - pointer_size) /2;
- y = (video::height - pointer_size) /2;
- }
-
- } else {
- if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) {
- color.assign(1.0, 0.0);
- } else {
- color.assign(1.0, 0.5);
- }
- render::Textures::bind("bitmaps/pointers/aim");
- }
-
- }
+ } else if (!core::localcontrol()) {
- } else {
- return;
- }
+ ui::root()->set_pointer();
- if (cursor_animated) {
- render::gl::push();
- render::gl::translate(x+pointer_size/2, y+pointer_size/2, 0.0f);
+ } else if (render::Camera::mode() == render::Camera::Overview) {
- angle = core::application()->time()* 0.75f - floorf(core::application()->time() * 0.75f);
- angle *= 360.0f;
- render::gl::rotate(angle, math::Vector3f(0, 0, 1.0f));
- render::gl::translate(-x-pointer_size/2, -y-pointer_size/2, 0.0f);
- }
+ ui::root()->set_pointer("aim");
- render::gl::color(color);
- render::gl::begin(render::gl::Quads);
+ } else if (targets::hover()) {
- glTexCoord2f(0,0 );
- render::gl::vertex(x,y,0.0f);
+ ui::root()->set_pointer("target", ui::Palette::Active, true);
- glTexCoord2f(1, 0);
- render::gl::vertex(x+pointer_size, y, 0.0f);
+ if (input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) {
+ ui::root()->input_mouse(render::Camera::width()/2, render::Camera::height() /2);
+ }
- glTexCoord2f(1, 1);
- render::gl::vertex(x+pointer_size, y+pointer_size, 0.0f);
+ } else if (input::mouse_control) {
- glTexCoord2f(0, 1);
- render::gl::vertex(x, y+pointer_size, 0.0f);
+ ui::root()->set_pointer("control", ui::Palette::Pointer);
- render::gl::end();
+ if (input::mouse_deadzone) {
+ ui::root()->input_mouse(render::Camera::width()/2, render::Camera::height() /2);
+ }
+
+ } else if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) &&
+ (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) {
+
+ ui::root()->set_pointer();
+
+ } else {
- if (cursor_animated) {
- render::gl::pop();
+ ui::root()->set_pointer("aim", ui::Palette::Foreground);
}
}
@@ -730,7 +674,7 @@ void frame(float elapsed)
render::Stats::clear();
- if (core::application()->connected() && core::game()->serverframetime() && core::localplayer()->zone()) {
+ if (core::application()->connected() && core::game()->time() && core::localplayer()->zone()) {
render::Camera::frame(elapsed);
render::Camera::frustum();
@@ -751,24 +695,18 @@ void frame(float elapsed)
gl::disable(GL_TEXTURE_2D);
gl::enable(GL_BLEND);
+ draw_cursor();
ui::root()->frame();
// draw the hud - TODO move as much as possible into ui::
-
- gl::enable(GL_TEXTURE_2D);
- gl::color(1.0f, 1.0f, 1.0f, 1.0f);
-
- // draw text elements
- if (draw_ui->value()) {
+ if (draw_ui->value() && !ui::root()->active()) {
+ gl::enable(GL_TEXTURE_2D);
+ gl::color(1.0f, 1.0f, 1.0f, 1.0f);
Text::setfont("gui", 12, 18);
// draw the hud
draw_hud();
-
- // draw the mouse cursor
- draw_cursor();
}
-
gl::disable(GL_TEXTURE_2D);
gl::disable(GL_BLEND);
diff --git a/src/core/application.cc b/src/core/application.cc
index f98d44e..837f294 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -147,7 +147,7 @@ Application::Application()
}
application_instance = this;
- application_time = 0;
+ application_timestamp = 0;
application_game = 0;
module_interactive = 0;
@@ -171,9 +171,8 @@ Application::~Application()
void Application::init(int count, char **arguments)
{
- con_debug << "Debug messages enabled\n";
con_print << "^BInitializing core...\n";
-
+ con_debug << " debug messages enabled\n";
filesystem::init("base", "");
CommandBuffer::init();
@@ -243,6 +242,7 @@ void Application::init(int count, char **arguments)
// register our engine functions
Func *func = 0;
+
func = Func::add("help", func_help);
func->set_info("help function");
@@ -258,11 +258,13 @@ void Application::init(int count, char **arguments)
func = Func::add("disconnect", func_disconnect);
func->set_info("leave the current game");
- func = Func::add("say",func_say);
+ func = Func::add("say", func_say);
func->set_info("say [text] say something on the public chat");
- func = Func::add("msg",func_msg);
+ func = Func::add("msg", func_msg);
func->set_info("msg [player] [text] send a private message to another player");
+
+ func = 0;
}
void Application::shutdown()
@@ -282,6 +284,7 @@ void Application::shutdown()
Module::clear();
// remove our engine functions
+ Func::remove("msg");
Func::remove("say");
Func::remove("help");
Func::remove("quit");
@@ -373,9 +376,9 @@ void Application::disconnect()
}
}
-void Application::frame(float seconds)
+void Application::frame(unsigned long timestamp)
{
- application_time += seconds;
+ application_timestamp = timestamp;
// execute commands in the buffer
CommandBuffer::exec();
@@ -384,7 +387,7 @@ void Application::frame(float seconds)
return;
// run a game interface frame
- application_game->frame(seconds);
+ application_game->frame(timestamp);
if (!application_game->running())
disconnect();
diff --git a/src/core/application.h b/src/core/application.h
index e55c37f..229f318 100644
--- a/src/core/application.h
+++ b/src/core/application.h
@@ -30,9 +30,12 @@ public:
/*----- inspectors ----------------------------------------------- */
- /// time the application has been running
- inline float time() const { return application_time; }
+ /// the current application time, in microseconds
+ inline unsigned long timestamp() const { return application_timestamp; }
+ /// the current application time, in seconds
+ float time() const { return ((float)(timestamp()) / 1000.0f); }
+
/// true if the core is connected to a running game interface
inline bool connected() const { return (application_game && application_game->running()); }
@@ -88,7 +91,7 @@ public:
protected:
/// run a core frame
- virtual void frame(float seconds);
+ virtual void frame(unsigned long timestamp);
/// load cvar config
void load_config();
@@ -104,7 +107,7 @@ protected:
private:
/// time the core has been running
- float application_time;
+ unsigned long application_timestamp;
GameInterface *application_game;
static Application *application_instance;
diff --git a/src/core/clientstate.cc b/src/core/clientstate.cc
index 84e1fe0..298e653 100644
--- a/src/core/clientstate.cc
+++ b/src/core/clientstate.cc
@@ -65,10 +65,22 @@ void ClientState::clearsound()
{
if (state_engineloopsource) {
application()->notify_remove_sound(state_engineloopsource);
+ }
+
+ if (state_engineeventsource) {
application()->notify_remove_sound(state_engineeventsource);
- state_engineloopsource = 0;
- state_engineloopbuffer = 0;
}
+
+ state_thusterloopbuffer = 0;
+ state_impulseloopbuffer = 0;
+ state_impulsestartbuffer = 0;
+ state_impulsestopbuffer = 0;
+
+ state_engineloopbuffer = 0;
+ state_engineloopsource = 0;
+
+ state_engineeventbuffer = 0;
+ state_engineeventsource = 0;
}
void ClientState::assign(Entity * entity)
diff --git a/src/core/cvar.cc b/src/core/cvar.cc
index 50043f2..7db202d 100644
--- a/src/core/cvar.cc
+++ b/src/core/cvar.cc
@@ -35,16 +35,10 @@ Cvar *Cvar::rconpassword = 0;
Cvar::Registry Cvar::cvar_registry;
-Cvar::Cvar(const char *name, const unsigned int flags)
+Cvar::Cvar(const char *name, const unsigned int flags) : cvar_name(), cvar_info(), cvar_str()
{
cvar_flags = flags;
-
- if (name)
- cvar_name.assign(name);
- else
- cvar_name.clear();
-
- cvar_info.clear();
+ cvar_name.assign(name);
}
void Cvar::set_info(const char *info)
@@ -64,7 +58,8 @@ Cvar & Cvar::operator=(const std::string &other)
Cvar & Cvar::operator=(const char *other)
{
- return ((*this) = std::string(other));
+ std::string value(other);
+ return (this->operator=(value));
}
Cvar & Cvar::operator=(float other)
@@ -81,11 +76,10 @@ Cvar* Cvar::get(const char *name, const char *value, const unsigned int flags)
Cvar *c = find(name);
if (c) {
//con_debug << "get " << name << " already exist with value " << cvar->str() << std::endl;
- c->cvar_flags |= flags;
} else {
//con_debug << "get " << name << " " << value << std::endl;
c = new Cvar(name, flags);
- cvar_registry[std::string(name)] = c;
+ cvar_registry[c->name()] = c;
(*c) = value;
}
c->cvar_flags |= flags;
@@ -100,7 +94,7 @@ Cvar* Cvar::get(const char *name, float value, const unsigned int flags)
} else {
//con_debug << "get " << name << " " << value << std::endl;
c = new Cvar(name, flags);
- cvar_registry[std::string(name)] = c;
+ cvar_registry[c->name()] = c;
(*c) = value;
}
c->cvar_flags |= flags;
@@ -112,7 +106,7 @@ Cvar* Cvar::set(const char *name, const char *value, const unsigned int flags)
Cvar *c = find(name);
if (!c) {
c = new Cvar(name, flags);
- cvar_registry[std::string(name)] = c;
+ cvar_registry[c->name()] = c;
}
(*c) = value;
c->cvar_flags = flags;
@@ -126,7 +120,7 @@ Cvar* Cvar::set(const char *name, float value, unsigned int flags)
Cvar *c = find(name);
if (!c) {
c = new Cvar(name, flags);
- cvar_registry[std::string(name)] = c;
+ cvar_registry[c->name()] = c;
}
(*c) = value;
c->cvar_flags = flags;
@@ -161,7 +155,8 @@ Cvar *Cvar::find(std::string const &name)
Cvar *Cvar::find(const char *name)
{
- return(find(std::string(name)));
+ std::string s(name);
+ return(find(s));
}
void Cvar::list()
diff --git a/src/core/cvar.h b/src/core/cvar.h
index d934872..acb6f89 100644
--- a/src/core/cvar.h
+++ b/src/core/cvar.h
@@ -130,6 +130,7 @@ private:
std::string cvar_name;
std::string cvar_info;
std::string cvar_str;
+
unsigned int cvar_flags;
float cvar_value;
diff --git a/src/core/func.cc b/src/core/func.cc
index edebc8a..81175f8 100644
--- a/src/core/func.cc
+++ b/src/core/func.cc
@@ -39,7 +39,7 @@ Func *Func::add(const char *name, GameFuncPtr gamefunctionptr, unsigned int flag
Registry::iterator it = func_registry.find(name);
if (it == func_registry.end()) {
func = new Func(name, (void *)gamefunctionptr, flags | Func::Game);
- func_registry[std::string(name)] = func;
+ func_registry[func->name()] = func;
//con_debug << "Function '" << name << "' registered." << std::endl;
} else {
con_warn << "Function '" << name << "' already registered!" << std::endl;
diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc
index 114931c..eaafe91 100644
--- a/src/core/gameconnection.cc
+++ b/src/core/gameconnection.cc
@@ -22,7 +22,9 @@ GameConnection::GameConnection(std::string const &connectionstr)
connection_instance = this;
connection_network = 0;
connection_running = false;
- connection_frametime = 0;
+
+ connection_timestamp = 0;
+ connection_netframe = 0;
unsigned int port = DEFAULTPORT;
std::string host(connectionstr);
@@ -101,7 +103,7 @@ void GameConnection::private_message(std::string const &args)
connection_network->send_private_message(args);
}
-void GameConnection::frame(float seconds)
+void GameConnection::frame(unsigned long timestamp)
{
if (!running())
return;
@@ -111,20 +113,21 @@ void GameConnection::frame(float seconds)
return;
}
- update_clientstate(seconds);
-
- connection_network->frame(seconds);
+ update_clientstate();
- connection_frametime += seconds;
+ // get incoming messages
+ connection_network->frame();
float f = 0;
if (core::Cvar::net_framerate->value()) {
- f = 0.5f / core::Cvar::net_framerate->value();
- if (connection_frametime < f) {
+ f = 1000.0f / core::Cvar::net_framerate->value();
+ if (connection_netframe + f > timestamp) {
return;
}
}
+ connection_netframe = timestamp;
+
if (connection_network->state() == NetConnection::Connected) {
if(localcontrol() && localcontrol()->dirty()) {
@@ -139,9 +142,8 @@ void GameConnection::frame(float seconds)
}
}
+ connection_timestamp = connection_network->timestamp();
connection_network->transmit();
-
- connection_frametime = 0;
}
}
diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h
index 95df9f3..70e3015 100644
--- a/src/core/gameconnection.h
+++ b/src/core/gameconnection.h
@@ -32,12 +32,12 @@ public:
inline bool interactive() const { return true; }
/// return the current game time
- inline float time() const { return game_clientframetime; }
+ inline unsigned long timestamp() const { return connection_timestamp; }
/*----- mutators -------------------------------------------------- */
/// run a game connection time frame
- void frame(float seconds);
+ void frame(unsigned long timestamp);
/// forward a command line to the remote server
void forward(std::string const &cmdline);
@@ -59,10 +59,11 @@ protected:
private:
bool connection_running;
- static GameConnection *connection_instance;
+ unsigned long connection_timestamp; // server game time
+ unsigned long connection_netframe; // last network frame timestamp
+
NetConnection *connection_network;
- float connection_frametime;
-
+ static GameConnection *connection_instance;
};
inline GameConnection *connection() { return GameConnection::instance(); }
diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index 74acced..d99ec15 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -118,16 +118,13 @@ void GameInterface::clear()
}
game_players.clear();
-
- game_previousframetime = 0;
- game_serverframetime = 0;
- game_clientframetime = 0;
}
-void GameInterface::reset_clientstate(float timestamp, float prevtimestamp)
+void GameInterface::reset_clientstate()
{
- game_previousframetime = prevtimestamp;
- game_serverframetime = timestamp;
+// game_previousframetime = prevtimestamp;
+// game_serverframetime = timestamp;
+// game_time = timestamp;
for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
@@ -137,10 +134,10 @@ void GameInterface::reset_clientstate(float timestamp, float prevtimestamp)
entity->state()->assign(entity);
}
- if ( game_clientframetime < game_previousframetime)
- game_clientframetime = game_previousframetime;
- else if ( game_clientframetime > game_serverframetime)
- game_clientframetime = game_serverframetime;
+// if ( game_clientframetime < game_previousframetime)
+// game_clientframetime = game_previousframetime;
+// else if ( game_clientframetime > game_serverframetime)
+// game_clientframetime = game_serverframetime;
}
@@ -150,14 +147,11 @@ void GameInterface::update_entity_clientstate(Entity *entity)
if (!entity->state()) {
entity->entity_clientstate = new ClientState(entity);
entity->entity_clientstate->assign(entity);
- }
-
- if(Cvar::cl_prediction->value() == 0) {
-
+ } else
entity->state()->assign(entity);
- return;
}
+/*
if (!(entity->flags() & Entity::Static)) {
// clientstate location
@@ -181,7 +175,7 @@ void GameInterface::update_entity_clientstate(Entity *entity)
if (angle > MIN_DELTA)
entity->state()->state_axis.rotate(n, -angle);
}
- /*
+
n.assign(math::crossproduct( entity->state()->axis().left(), entity->axis().left()));
if (!(n.length() < MIN_DELTA)) {
n.normalize();
@@ -199,7 +193,7 @@ void GameInterface::update_entity_clientstate(Entity *entity)
if (angle > MIN_DELTA)
entity->state()->state_axis.rotate(n, -angle);
}
- */
+
} else {
entity->state()->state_axis.assign(entity->axis());
}
@@ -211,29 +205,15 @@ void GameInterface::update_entity_clientstate(Entity *entity)
entity->state()->assign(entity);
}
}
+*/
-void GameInterface::update_clientstate(float seconds)
+void GameInterface::update_clientstate()
{
- game_clientframetime += seconds;
-
for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
update_entity_clientstate((*it).second);
}
}
-float GameInterface::timeoffset() {
-
- if (game_clientframetime > game_serverframetime)
- return 1;
-
- float d = game_serverframetime - game_previousframetime;
- if (d <= 0)
- return 0;
-
- float t = game_clientframetime - game_previousframetime;
- return t/d;
-}
-
void GameInterface::list_players()
{
using namespace std;
diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h
index fea86fe..c916d15 100644
--- a/src/core/gameinterface.h
+++ b/src/core/gameinterface.h
@@ -30,20 +30,6 @@ public:
/// return the local player
inline Player *localplayer() { return &game_localplayer; }
- /// return the server time of the last received server frame
- inline float serverframetime() const { return game_serverframetime; }
-
- /// return the server time of the previous received server frame
- inline float previousframetime() const { return game_previousframetime; }
-
- /// return the server time of the previous received server frame
- inline float clientframetime() const { return game_clientframetime; }
-
- /// client frame time between previousframetime and serverframetime, from 0 - 1
- float timeoffset();
-
- inline float timestep() const { return game_timestep; }
-
inline Players & players() { return game_players; }
/// show a list of connected players
@@ -58,7 +44,10 @@ public:
virtual bool interactive() const = 0;
/// return the current game time
- virtual float time() const = 0;
+ virtual unsigned long timestamp() const = 0;
+
+ /// return the current game time, in seconds
+ float time() const { return ((float)(timestamp()) / 1000.0f); }
/*----- mutators ------------------------------------------------- */
@@ -66,18 +55,18 @@ public:
void clear();
/// reset the client state
- void reset_clientstate(float timestamp, float prevtimestamp);
+ void reset_clientstate();
/// update the client state timers
- void update_clientstate(float seconds);
+ void update_clientstate();
void update_entity_clientstate(Entity *entity);
/*----- virtual mutators ------------------------------------------ */
/// run one game time frame
- /// @param seconds time since the previous frame, in seconds
- virtual void frame(float seconds) = 0;
+ /// @param timestamp current application time
+ virtual void frame(unsigned long timestamp) = 0;
protected:
/// the local player
@@ -85,14 +74,6 @@ protected:
/// all the players
Players game_players;
-
- float game_serverframetime;
- float game_previousframetime;
-
- float game_timestep;
- float game_clientframetime;
-
- unsigned int game_serverframelength;
};
/// global local player instance
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index e42d1b2..4fc3924 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -120,10 +120,10 @@ GameServer::GameServer() : GameInterface()
con_print << "^BInitializing game server...\n";
server_instance = this;
server_network = 0;
- server_time = 0;
+ server_timestamp = 0;
server_previoustime = 0;
- server_frametime = 0.0f;
server_maxplayerid = 1;
+ server_startup = application()->timestamp();
server_module = Module::current();
if (!server_module) {
@@ -558,14 +558,11 @@ void GameServer::player_disconnect(Player *player)
}
}
-void GameServer::frame(float seconds)
+void GameServer::frame(unsigned long timestamp)
{
if (error())
return;
- server_time += seconds;
- server_frametime += seconds;
-
// process incoming network messages
if (server_network) {
server_network->receive();
@@ -580,24 +577,25 @@ void GameServer::frame(float seconds)
localplayer()->update_info();
if (!Cvar::sv_dedicated->value()) {
- update_clientstate(seconds);
+ update_clientstate();
}
if ((Cvar::sv_dedicated->value() || Cvar::sv_private->value())) {
if (core::Cvar::sv_framerate->value()) {
- float f = 1.0f / core::Cvar::sv_framerate->value();
- if (server_frametime < f) {
+ float f = 1000.0f / core::Cvar::sv_framerate->value();
+ if (server_startup + server_timestamp + f > timestamp) {
return;
}
}
- }
+ }
+
+ server_previoustime = server_timestamp;
+ server_timestamp = timestamp - server_startup;
+ float elapsed = (float) (server_timestamp - server_previoustime) / 1000.0f;
// copy the previous entity state to the client state
if (!Cvar::sv_dedicated->value()) {
- reset_clientstate(server_time, server_previoustime);
- } else {
- game_serverframetime = server_time;
- game_previousframetime = server_previoustime;
+ reset_clientstate();
}
// run a time frame on each entity
@@ -605,13 +603,13 @@ void GameServer::frame(float seconds)
Entity *entity = (*it).second;
if ((entity->type() == Entity::Controlable) || (entity->type() == Entity::Dynamic)) {
- entity->frame(server_frametime);
+ entity->frame(elapsed);
}
}
// run a frame on the module
if (server_module) {
- server_module->frame(server_frametime);
+ server_module->frame(elapsed);
if (server_module->error()) {
abort();
return;
@@ -620,7 +618,7 @@ void GameServer::frame(float seconds)
if (server_network) {
// send network updates
- server_network->frame(server_time, server_previoustime);
+ server_network->frame(server_timestamp);
}
// mark all entities as updated
@@ -643,11 +641,8 @@ void GameServer::frame(float seconds)
}
if (!Cvar::sv_dedicated->value()) {
- update_clientstate(0);
+ update_clientstate();
}
-
- server_frametime = 0;
- server_previoustime = server_time;
}
void GameServer::save_config()
diff --git a/src/core/gameserver.h b/src/core/gameserver.h
index 550dd99..4ea476b 100644
--- a/src/core/gameserver.h
+++ b/src/core/gameserver.h
@@ -37,7 +37,7 @@ public:
virtual bool interactive() const;
/// current server game time
- virtual inline float time() const { return server_time; }
+ virtual inline unsigned long timestamp() const { return server_timestamp; }
/*----- mutators -------------------------------------------------- */
@@ -48,7 +48,7 @@ public:
void player_disconnect(Player *player);
/// run a game server time frame
- void frame(float seconds);
+ void frame(unsigned long timestamp);
/// a player sends a chat message to the public channel
void say(Player *player, std::string const &args);
@@ -104,9 +104,10 @@ private:
NetServer *server_network;
unsigned int server_maxplayerid;
- float server_frametime;
- float server_time;
- float server_previoustime;
+
+ unsigned long server_timestamp;
+ unsigned long server_previoustime;
+ unsigned long server_startup;
};
inline GameServer *server() { return GameServer::instance(); }
diff --git a/src/core/net.h b/src/core/net.h
index 4909136..c724f85 100644
--- a/src/core/net.h
+++ b/src/core/net.h
@@ -11,7 +11,7 @@ namespace core
{
/// network protocol version
-const unsigned int PROTOCOLVERSION = 10;
+const unsigned int PROTOCOLVERSION = 11;
/// maximum lenght of a (compressed) network message block
const unsigned int FRAMESIZE = 1152;
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index ae1118f..704551b 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -23,6 +23,7 @@ NetConnection::NetConnection()
{
connection_timeout = core::application()->time();
connection_state = Connecting;
+ connection_timestamp = 0;
receive_compressed = false;
received_compressed_size = 0;
@@ -233,7 +234,7 @@ void NetConnection::receive()
}
-void NetConnection::frame(float seconds)
+void NetConnection::frame()
{
timeval timeout;
timeout.tv_sec = 0;
@@ -458,9 +459,9 @@ void NetConnection::parse_incoming_message(const std::string & message)
} else if (command == "ping") {
} else if (command == "frame") {
- float timestamp, prevtimestamp;
- if ((msgstream >> timestamp) && (msgstream >> prevtimestamp)) {
- game()->reset_clientstate(timestamp, prevtimestamp);
+ unsigned long timestamp;
+ if ((msgstream >> timestamp)) {
+ connection_timestamp = timestamp;
}
} else if (command == "die") {
diff --git a/src/core/netconnection.h b/src/core/netconnection.h
index cb04ce2..66f7369 100644
--- a/src/core/netconnection.h
+++ b/src/core/netconnection.h
@@ -48,7 +48,7 @@ public:
virtual void disconnect();
/// process pending incoming messages
- void frame(float seconds);
+ void frame();
/// send a connect message to the remote server
void send_connect();
@@ -93,6 +93,9 @@ public:
State connection_state;
+ /// return the current game time
+ inline unsigned long timestamp() const { return connection_timestamp; }
+
protected:
/// add a raw network message to the send queue
void send_raw(std::string const &msg);
@@ -128,6 +131,8 @@ private:
size_t received_compressed_size;
size_t compressed_size;
char zrecvbuf[BLOCKSIZE];
+
+ unsigned long connection_timestamp;
};
}
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index 95b047a..cdcdad7 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -300,7 +300,7 @@ void NetServer::client_initialize(NetClient *client) {
}
// send updates to one client
-void NetServer::client_frame(NetClient *client, float timestamp, float previoustimestamp)
+void NetServer::client_frame(NetClient *client, unsigned long timestamp)
{
if (client->state() != NetClient::Connected)
return;
@@ -328,7 +328,7 @@ void NetServer::client_frame(NetClient *client, float timestamp, float previoust
} else {
// send a server frame marker
- send_frame_marker(client, timestamp, previoustimestamp);
+ send_frame_marker(client, timestamp);
// send updates for entities in the zone
for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
@@ -361,7 +361,7 @@ void NetServer::client_frame(NetClient *client, float timestamp, float previoust
}
// run a network server frame, send updates to clients
-void NetServer::frame(float timestamp, float previoustimestamp)
+void NetServer::frame(unsigned long timestamp)
{
/* FIXME
Only entities within visual range should send updates (1024 game units?)
@@ -376,7 +376,7 @@ void NetServer::frame(float timestamp, float previoustimestamp)
client->transmit(fd());
if (client->state() == NetClient::Connected)
- client_frame(client, timestamp, previoustimestamp);
+ client_frame(client, timestamp);
// update player info always gets through
if (client->player()->dirty() || client->player()->zonechange()) {
@@ -449,10 +449,10 @@ void NetServer::send_disconnect(NetClient *client)
}
// send a "frame" message to a client
-void NetServer::send_frame_marker(NetClient *client, float timestamp, float previoustimestamp)
+void NetServer::send_frame_marker(NetClient *client, unsigned long timestamp)
{
std::ostringstream msg("");
- msg << "frame " << timestamp << " " << previoustimestamp << "\n";
+ msg << "frame " << timestamp << "\n";
if (client->state() == NetClient::Connected) {
client->send_raw(msg.str());
diff --git a/src/core/netserver.h b/src/core/netserver.h
index 1d2e131..8877707 100644
--- a/src/core/netserver.h
+++ b/src/core/netserver.h
@@ -53,7 +53,7 @@ public:
/*----- mutators -------------------------------------------------- */
/// run a network server frame
- void frame(float timestamp, float previoustimestamp);
+ void frame(unsigned long timestamp);
/// receive data from clients
void receive();
@@ -72,7 +72,7 @@ public:
protected:
/// send a server frame marker
- void send_frame_marker(NetClient *client, float timestamp, float previoustimestamp);
+ void send_frame_marker(NetClient *client, unsigned long timestamp);
/// send a create entity event
void send_entity_create(NetClient *client, Entity *entity);
@@ -105,7 +105,7 @@ protected:
void parse_incoming_message(NetClient *client, const std::string & message);
/// send a server frame to a single client
- void client_frame(NetClient *client, float timestamp, float previoustimestamp);
+ void client_frame(NetClient *client, unsigned long timestamp);
private:
bool netserver_error;
diff --git a/src/core/timer.cc b/src/core/timer.cc
index e5a808e..b614af1 100644
--- a/src/core/timer.cc
+++ b/src/core/timer.cc
@@ -8,6 +8,7 @@
#include <unistd.h>
#include <iostream>
+#include <cmath>
namespace core {
@@ -26,7 +27,7 @@ void Timer::mark()
gettimeofday(&timer_tick, &timer_tz);
}
-float Timer::elapsed()
+unsigned long Timer::timestamp()
{
struct timeval tick;
struct timezone tick_tz;
@@ -34,8 +35,15 @@ float Timer::elapsed()
gettimeofday(&tick, &tick_tz);
// calculate elapsed time in 10^-6 seconds
- long delta = (tick.tv_sec - timer_tick.tv_sec) * 1000000 + (tick.tv_usec - timer_tick.tv_usec);
- return( (float) delta / 1000000.0f);
+ unsigned long delta = 0;
+ delta = tick.tv_sec * 1000 + tick.tv_usec / 1000;
+ delta -= timer_tick.tv_sec * 1000 + timer_tick.tv_usec / 1000;
+ return delta;
+}
+
+float Timer::elapsed()
+{
+ return ((float) timestamp() / 1000.0f);
}
}
diff --git a/src/core/timer.h b/src/core/timer.h
index 9e172bf..b878875 100644
--- a/src/core/timer.h
+++ b/src/core/timer.h
@@ -28,11 +28,14 @@ public:
*/
void mark();
- /*! return the time elapsed since the last mark
+ /*! return the time elapsed since the last mark, in seconds
* @see mark()
*/
float elapsed();
+ /// return timestamp since last mark, in microseconds
+ unsigned long timestamp();
+
private:
float timer_elapsed;
struct timezone timer_tz;
diff --git a/src/filesystem/diskfile.cc b/src/filesystem/diskfile.cc
index 6554f1e..6def055 100644
--- a/src/filesystem/diskfile.cc
+++ b/src/filesystem/diskfile.cc
@@ -35,6 +35,10 @@ bool DiskFile::open(const char *filename)
file_name.assign(filename);
file_path.clear();
+#ifdef _WIN32
+ for (size_t i = 0; i < file_name.size(); i++)
+ if (file_name[i] == '/') file_name[i] = '\\';
+#endif
for (SearchPath::iterator path = searchpath().begin(); path != searchpath().end(); path++) {
std::string fn((*path));
fn.append(filename);
diff --git a/src/filesystem/filesystem.cc b/src/filesystem/filesystem.cc
index 3404296..a8fca1d 100644
--- a/src/filesystem/filesystem.cc
+++ b/src/filesystem/filesystem.cc
@@ -153,12 +153,15 @@ void init(std::string const & basename, std::string const & modname)
// print search path
for (SearchPath::iterator path = filesystem_searchpath.begin(); path != filesystem_searchpath.end(); ++path) {
- con_print << " " << (*path) << std::endl;
+#ifdef _WIN32
+ for (size_t i = 0; i < (*path).size(); i++)
+ if ((*path)[i] == '/') (*path)[i] = '\\';
+#endif
+ con_print << " directory: " << (*path) << std::endl;
}
- con_print << " " << filesystem_searchpath.size() << " directories added to searchpath" << std::endl;
// create writedir
- con_print << " files are created in " << filesystem_writedir << std::endl;
+ con_print << " home directory: " << filesystem_writedir << std::endl;
}
void shutdown()
diff --git a/src/render/image.cc b/src/render/image.cc
index 7ce8113..e740d56 100644
--- a/src/render/image.cc
+++ b/src/render/image.cc
@@ -44,6 +44,31 @@ void Image::swap_channels()
}
}
+void Image::pad()
+{
+ unsigned int w = width();
+ unsigned int h = height();
+
+ if ((w % 8) != 0) {
+ image_width = w + (8 - (w % 8));
+ }
+
+ if ((w % 8) != 0) {
+ image_height = h + (8 - (h % 8));
+ }
+
+ unsigned char *image_new = (unsigned char *) malloc(size());
+ memset(image_new, 0, size());
+
+ for (size_t y =0; y < h; y++) {
+ memcpy((void *)&image_new[y * image_width * image_channels],
+ (void *)image_data[y * w * image_channels], (size_t) w);
+ }
+
+ free(image_data);
+ image_data = image_new;
+}
+
void Image::flip()
{
unsigned char line[image_width*image_channels];
diff --git a/src/render/image.h b/src/render/image.h
index 3c82792..c7add6f 100644
--- a/src/render/image.h
+++ b/src/render/image.h
@@ -47,6 +47,9 @@ public:
/// flip upside-down
void flip();
+ /// pad width and height up to 8 bytes
+ void pad();
+
private:
unsigned char *image_data;
diff --git a/src/render/render.cc b/src/render/render.cc
index fbbaba1..55756d9 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -43,9 +43,6 @@ void func_list_textures(std::string const &args)
void reset_gl()
{
- // setup our viewport.
- gl::viewport(0, 0, Camera::width(), Camera::height());
-
// set clear color
gl::clearcolor(0.0f, 0.0f, 0.0f, 1.0f);
@@ -152,6 +149,13 @@ void init()
func->set_info("list loaded textures");
}
+void resize(int width, int height)
+{
+ // setup our viewport.
+ gl::viewport(0, 0, width, height);
+ Camera::resize(width, height);
+}
+
// unload game assets (zone change)
void unload()
{
@@ -313,8 +317,15 @@ void screenshot()
image.flip();
if (filetype == TYPEPNG) {
+/* if ((Camera::width() % 8 != 0 ) || (Camera::height() % 8 != 0 )) {
+ image.pad();
+ }*/
render::PNG::save(filename.c_str(), image);
} else if (filetype == TYPEJPG) {
+/* if ((Camera::width() % 8 != 0 ) || (Camera::height() % 8 != 0 )) {
+ image.pad();
+ }
+*/
render::JPG::save(filename.c_str(), image, (int) screenshotquality->value());
} else if (filetype == TYPETGA) {
render::TGA::save(filename.c_str(), image);
diff --git a/src/render/render.h b/src/render/render.h
index cd90953..a7aec70 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -38,6 +38,9 @@ namespace render {
/// make a screenshot
void screenshot();
+ /// resize viewport
+ void resize(int w, int h);
+
extern core::Cvar *r_arraysize;
extern core::Cvar *r_bbox;
extern core::Cvar *r_grid;
diff --git a/src/server/console.cc b/src/server/console.cc
index ab03c58..9fdad4f 100644
--- a/src/server/console.cc
+++ b/src/server/console.cc
@@ -104,7 +104,7 @@ Console::~Console()
void Console::dump()
{
// dump console content
- for (Text::iterator it = log().begin(); it != log().end(); it++) {
+ for (Queue::iterator it = log().begin(); it != log().end(); it++) {
sys::ConsoleInterface::print((*it));
}
}
@@ -200,8 +200,8 @@ void Console::draw_status()
if (core::game()) {
attroff(A_BOLD);
color_set(2, NULL);
- int minutes = (int) floorf(core::game()->serverframetime() / 60.0f);
- int seconds = (int) floorf( core::game()->serverframetime() - (float) minutes* 60.0f);
+ int minutes = (int) floorf(core::game()->time() / 60.0f);
+ int seconds = (int) floorf( core::game()->time() - (float) minutes* 60.0f);
std::stringstream status;
status << "time " << std::setfill(' ') << std::setw(3) << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
mvaddnstr(0, 2, status.str().c_str(), status.str().size());
@@ -215,7 +215,7 @@ void Console::draw_text()
if ((w < 3) || (h < 3))
return;
- Text lines;
+ Queue lines;
int height = stdwin->_maxy - 1;
int width = stdwin->_maxx - 1;
@@ -223,7 +223,7 @@ void Console::draw_text()
int current_line = 0;
// parse console text, wrap long lines
- for (Text::iterator it = log().begin(); it != log().end() && current_line < bottom; it++) {
+ for (Queue::iterator it = log().begin(); it != log().end() && current_line < bottom; it++) {
if (current_line >= bottom - height) {
std::string linedata(*it);
linedata += '\n';
@@ -314,7 +314,7 @@ void Console::draw_text()
color_set(0, NULL);
attroff(A_BOLD);
- for (Text::reverse_iterator rit = lines.rbegin(); (y > 0) && (rit != lines.rend()); ++rit) {
+ for (Queue::reverse_iterator rit = lines.rbegin(); (y > 0) && (rit != lines.rend()); ++rit) {
const char *c = (*rit).c_str();
int x = 0;
@@ -360,10 +360,10 @@ void Console::draw()
console_updated = false;
}
-void Console::frame(float seconds)
+void Console::frame()
{
const size_t scroll_offset = 3;
- Text::reverse_iterator upit;
+ History::reverse_iterator upit;
if (!console_initialized)
return;
@@ -467,9 +467,9 @@ void Console::frame(float seconds)
if (input_updated) {
draw_input();
}
- if (roundf(core::game()->serverframetime()) != prev_time) {
+ if (roundf(core::application()->time()) != prev_time) {
draw_status();
- prev_time = roundf(core::game()->serverframetime());
+ prev_time = roundf(core::application()->time());
input_updated = true;
}
if (input_updated) {
diff --git a/src/server/console.h b/src/server/console.h
index 59d65d9..13db3fc 100644
--- a/src/server/console.h
+++ b/src/server/console.h
@@ -25,7 +25,7 @@ public:
/// resize the console
virtual void resize();
/// run one console frame
- void frame(float seconds);
+ void frame();
protected:
/// draw the ncurses console
@@ -44,12 +44,14 @@ protected:
virtual void print(const std::string & text);
private:
+ typedef std::deque<std::string> History;
+
/// set ncurses drawing color
void set_color(const char *color_code);
// input history
- Text history;
- Text::reverse_iterator history_pos;
+ History history;
+ History::reverse_iterator history_pos;
size_t input_pos;
size_t console_scroll;
diff --git a/src/server/server.cc b/src/server/server.cc
index f08ca6c..a4424a0 100644
--- a/src/server/server.cc
+++ b/src/server/server.cc
@@ -58,7 +58,8 @@ void Server::init(int count, char **arguments)
{
con_print << "^BInitializing server..." << std::endl;
- core::Cvar::sv_private = core::Cvar::set("sv_dedicated", "1", core::Cvar::ReadOnly);
+ core::Cvar::set("sv_dedicated", "1", core::Cvar::ReadOnly);
+
core::Application::init(count, arguments);
Console::init();
@@ -78,15 +79,13 @@ void Server::run()
server_framerate = 1.0f / core::Cvar::sv_framerate->value();
core::Timer timer;
- float elapsed = 0;
+ timer.mark();
- while(connected()) {
- timer.mark();
- frame(elapsed);
+ while(connected()) {
+ frame(timer.timestamp());
#ifdef HAVE_CURSES
- console()->frame(elapsed);
+ console()->frame();
#endif
- elapsed = timer.elapsed();
}
}
diff --git a/src/sys/consoleinterface.h b/src/sys/consoleinterface.h
index 3a7d3ed..2eae1d8 100644
--- a/src/sys/consoleinterface.h
+++ b/src/sys/consoleinterface.h
@@ -95,14 +95,14 @@ public:
/// enable or disable rcon
void set_rcon(bool enable = true);
- typedef std::deque<std::string> Text;
+ typedef std::deque<std::string> Queue;
- inline Text & rconbuf()
+ inline Queue & rconbuf()
{
return consoleinterface_rconbuf;
}
- inline Text & log()
+ inline Queue & log()
{
return consoleinterface_log;
}
@@ -126,9 +126,9 @@ private:
static ConsoleInterface *consoleinterface_instance;
bool consoleinterface_rcon;
- Text consoleinterface_rconbuf;
+ Queue consoleinterface_rconbuf;
- Text consoleinterface_log;
+ Queue consoleinterface_log;
size_t consoleinterface_logsize;
};
diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am
index a68c307..4bfad3d 100644
--- a/src/ui/Makefile.am
+++ b/src/ui/Makefile.am
@@ -7,9 +7,9 @@ else
noinst_LTLIBRARIES = libui.la
endif
-noinst_HEADERS = bitmap.h button.h container.h definitions.h font.h input.h label.h \
+noinst_HEADERS = bitmap.h button.h container.h definitions.h font.h inputbox.h label.h \
menu.h paint.h palette.h ui.h widget.h window.h
-libui_la_SOURCES = bitmap.cc button.cc container.cc font.cc input.cc label.cc \
+libui_la_SOURCES = bitmap.cc button.cc container.cc font.cc inputbox.cc label.cc \
menu.cc paint.cc palette.cc ui.cc widget.cc window.cc
libui_la_LDFLAGS = -avoid-version -no-undefined
diff --git a/src/ui/button.cc b/src/ui/button.cc
index 08fd0e9..e36d036 100644
--- a/src/ui/button.cc
+++ b/src/ui/button.cc
@@ -71,18 +71,18 @@ void Button::draw_text()
}
bool Button::on_keypress(const int key, const unsigned int modifier)
-{
- return false;
-}
-
-bool Button::on_keyrelease(const int key, const unsigned int modifier)
-{
+{
if (key == 512 + SDL_BUTTON_LEFT) {
core::cmd() << button_command << std::endl;
audio::play("ui/button");
return true;
}
-
+
+ return false;
+}
+
+bool Button::on_keyrelease(const int key, const unsigned int modifier)
+{
return false;
}
diff --git a/src/ui/container.cc b/src/ui/container.cc
index 5a12e8e..37fbea8 100644
--- a/src/ui/container.cc
+++ b/src/ui/container.cc
@@ -6,6 +6,7 @@
#include "ui/container.h"
+#include "ui/paint.h"
namespace ui
{
@@ -31,9 +32,8 @@ void Container::resize()
{
float w = container_childsize.width() * 1.5f;
float h = children().size() * (container_childsize.height() + margin()) + container_childsize.height();
-
set_size(w, h);
-
+
const float x = container_childsize.width() * 0.25f;
float y = container_childsize.height() * 0.5f;
@@ -56,4 +56,17 @@ void Container::set_margin(const float margin)
container_margin = margin;
}
+void Container::draw_border()
+{
+ if (!border())
+ return;
+
+ if(focus()) {
+ paint::color(palette()->foreground());
+ } else {
+ paint::color(palette()->border());
+ }
+ paint::border(global_location(), size());
+}
+
}
diff --git a/src/ui/container.h b/src/ui/container.h
index ae97bdf..5556759 100644
--- a/src/ui/container.h
+++ b/src/ui/container.h
@@ -27,6 +27,8 @@ public:
inline float margin() const { return container_margin; }
protected:
+ virtual void draw_border();
+
virtual void resize();
private:
diff --git a/src/ui/definitions.h b/src/ui/definitions.h
index b9b4e3c..ea3e040 100644
--- a/src/ui/definitions.h
+++ b/src/ui/definitions.h
@@ -23,6 +23,8 @@ enum Alignment {
AlignCenter = AlignHCenter | AlignVCenter
};
+const float pointer_size = 48.0f;
+
}
#endif // __INCLUDED_UI_DEFINITIONS_H__
diff --git a/src/ui/input.cc b/src/ui/inputbox.cc
index 8113354..30cae3b 100644
--- a/src/ui/input.cc
+++ b/src/ui/inputbox.cc
@@ -1,10 +1,10 @@
/*
- ui/input.cc
+ ui/inputbox.cc
This file is part of the Osirion project and is distributed under
the terms of the GNU General Public License version 2
*/
-#include "ui/input.h"
+#include "ui/inputbox.h"
#include "ui/paint.h"
#include "auxiliary/functions.h"
#include "core/core.h"
@@ -12,7 +12,7 @@
namespace ui
{
-Input::Input(Widget *parent) : Widget(parent)
+InputBox::InputBox(Widget *parent) : Widget(parent)
{
input_text.clear();
input_pos = 0;
@@ -22,22 +22,22 @@ Input::Input(Widget *parent) : Widget(parent)
set_border(false);
}
-Input::~Input()
+InputBox::~InputBox()
{
}
-void Input::clear()
+void InputBox::clear()
{
input_text.clear();
input_pos = 0;
}
-void Input::set_text(std::string const &text)
+void InputBox::set_text(std::string const &text)
{
input_text.assign(text);
input_pos = input_text.size();
}
-void Input::set_text(const char *text)
+void InputBox::set_text(const char *text)
{
if (text)
input_text.assign(text);
@@ -46,7 +46,7 @@ void Input::set_text(const char *text)
input_pos = input_text.size();
}
-void Input::draw()
+void InputBox::draw()
{
draw_background();
draw_border();
@@ -114,7 +114,7 @@ void Input::draw()
}
}
-bool Input::on_keypress(const int key, const unsigned int modifier)
+bool InputBox::on_keypress(const int key, const unsigned int modifier)
{
switch (key) {
case SDLK_TAB:
@@ -174,7 +174,7 @@ bool Input::on_keypress(const int key, const unsigned int modifier)
return false;
}
-bool Input::on_keyrelease(const int key, const unsigned int modifier)
+bool InputBox::on_keyrelease(const int key, const unsigned int modifier)
{
return false;
}
diff --git a/src/ui/input.h b/src/ui/inputbox.h
index 214f63e..557ca6c 100644
--- a/src/ui/input.h
+++ b/src/ui/inputbox.h
@@ -1,11 +1,11 @@
/*
- ui/input.h
+ ui/inputbox.h
This file is part of the Osirion project and is distributed under
the terms of the GNU General Public License version 2
*/
-#ifndef __INCLUDED_UI_INPUT_H__
-#define __INCLUDED_UI_INPUT_H__
+#ifndef __INCLUDED_UI_INPUTBOX_H__
+#define __INCLUDED_UI_INPUTBOX_H__
#include "ui/widget.h"
@@ -13,11 +13,11 @@ namespace ui
{
/// text input widget
-class Input : public Widget
+class InputBox : public Widget
{
public:
- Input(Widget *parent);
- ~Input();
+ InputBox(Widget *parent);
+ ~InputBox();
/// set the text displayed by the label
void set_text(std::string const &text);
@@ -51,5 +51,5 @@ private:
}
-#endif // __INCLUDED_UI_INPUT_H__
+#endif // __INCLUDED_UI_INPUTBOX_H__
diff --git a/src/ui/menu.h b/src/ui/menu.h
index a909e20..e3a853a 100644
--- a/src/ui/menu.h
+++ b/src/ui/menu.h
@@ -36,7 +36,7 @@ public:
/// add a button with a command
Button *add_button(char const *text=0, char const *command=0);
-
+
protected:
/// resize event
virtual void resize();
diff --git a/src/ui/palette.cc b/src/ui/palette.cc
index 20d1e93..3a9dc78 100644
--- a/src/ui/palette.cc
+++ b/src/ui/palette.cc
@@ -24,6 +24,33 @@ Palette::~Palette()
{
}
+const math::Color &Palette::color(Color palettecolor) const
+{
+ switch(palettecolor) {
+ case Foreground:
+ return foreground();
+ break;
+ case Background:
+ return background();
+ break;
+ case Highlight:
+ return highlight();
+ break;
+ case Border:
+ return border();
+ break;
+ case Pointer:
+ return pointer();
+ break;
+ case Active:
+ return active();
+ break;
+ default:
+ return foreground();
+ break;
+ }
+}
+
void Palette::set_foreground(math::Color const &color)
{
palette_foreground.assign(color);
diff --git a/src/ui/palette.h b/src/ui/palette.h
index 9d27f95..41eee03 100644
--- a/src/ui/palette.h
+++ b/src/ui/palette.h
@@ -19,6 +19,8 @@ public:
Palette();
~Palette();
+ enum Color { Foreground=0, Background=1, Highlight=2, Border=3, Pointer=4, Active=5 };
+
void set_foreground(math::Color const &color);
void set_highlight(math::Color const &color);
@@ -31,29 +33,31 @@ public:
void set_active(math::Color const &color);
- inline math::Color const &foreground() const {
+ inline const math::Color &foreground() const {
return palette_foreground;
}
- inline math::Color const &highlight() const {
+ inline const math::Color &highlight() const {
return palette_highlight;
}
- inline math::Color const &background() const {
+ inline const math::Color &background() const {
return palette_background;
}
- inline math::Color const &border() const {
+ inline const math::Color &border() const {
return palette_border;
}
- inline math::Color const &pointer() const {
+ inline const math::Color &pointer() const {
return palette_pointer;
}
- inline math::Color const &active() const {
+ inline const math::Color &active() const {
return palette_active;
}
+
+ const math::Color &color(Palette::Color palettecolor) const;
private:
diff --git a/src/ui/ui.cc b/src/ui/ui.cc
index baedd38..1ecfbb1 100644
--- a/src/ui/ui.cc
+++ b/src/ui/ui.cc
@@ -7,13 +7,16 @@
#include <string>
#include <sstream>
+#include "audio/audio.h"
#include "auxiliary/functions.h"
#include "core/core.h"
#include "filesystem/filesystem.h"
+#include "render/gl.h"
#include "sys/sys.h"
#include "ui/button.h"
#include "ui/label.h"
#include "ui/menu.h"
+#include "ui/paint.h"
#include "ui/ui.h"
#include "ui/widget.h"
@@ -204,6 +207,9 @@ UI::UI() : Window(0)
ui_mouse_focus = this;
ui_input_focus = this;
set_focus();
+
+ mouse_pointer_color = Palette::Pointer;
+ mouse_pointer_bitmap.assign("pointer");
}
UI::~UI()
@@ -386,7 +392,9 @@ void UI::show_menu(const char *label)
ui_active_menu = menu;
ui_active_menu->event_resize();
- ui_active_menu->show();
+ ui_active_menu->show();
+
+ set_pointer("pointer");
} else {
con_warn << "Unknown window '" << label << "'" << std::endl;
}
@@ -418,6 +426,9 @@ void UI::frame()
}
event_draw();
+
+ if (visible())
+ draw_pointer();
}
/* -- global event handlers ---------------------------------------- */
@@ -453,21 +464,18 @@ bool UI::input_key(const bool pressed, const int key, const unsigned int modifie
return handled;
}
-/* -- event handlers ----------------------------------------------- */
-/*
- These functions handle events for this widget only. They are
- the fallback input handlers
-*/
bool UI::on_keypress(const int key, const unsigned int modifier)
{
switch( key ) {
case SDLK_ESCAPE:
if (active()) {
- previous_menu();
+ hide_menu();
+ audio::play("ui/menu");
} else {
if (core::application()->connected()) {
show_menu("game");
+ audio::play("ui/menu");
}
}
return true;
@@ -484,5 +492,51 @@ bool UI::on_keyrelease(const int key, const unsigned int modifier)
return false;
}
+void UI::set_pointer(const char *pointerbitmap, const Palette::Color color, const bool animated)
+{
+ if (!pointerbitmap) {
+ mouse_pointer_bitmap.clear();
+ } else {
+ mouse_pointer_bitmap.assign(pointerbitmap);
+ }
+ mouse_pointer_animated = animated;
+ mouse_pointer_color = color;
+}
+
+void UI::draw_pointer()
+{
+ if (!mouse_pointer_bitmap.size())
+ return;
+
+ math::Color c(palette()->color(mouse_pointer_color));
+ if (mouse_pointer_animated) {
+ c.a = 1;
+ } else {
+ c.a = 0.5f;
+ }
+ paint::color(c);
+ math::Vector2f pos(mouse_cursor.x - pointer_size * 0.5f, mouse_cursor.y - pointer_size * 0.5f);
+ math::Vector2f s(pointer_size, pointer_size);
+
+ std::string texture("pointers/");
+ texture.append(mouse_pointer_bitmap);
+
+ if (mouse_pointer_animated) {
+ render::gl::push();
+ render::gl::translate(mouse_cursor.x, mouse_cursor.y, 0);
+
+ float angle = core::application()->time()* 0.75f - floorf(core::application()->time() * 0.75f);
+ angle *= 360.0f;
+ render::gl::rotate(angle, math::Vector3f(0, 0, 1.0f));
+ render::gl::translate(-mouse_cursor.x, -mouse_cursor.y, 0);
+ }
+
+ paint::bitmap(pos, s, texture);
+
+ if (mouse_pointer_animated) {
+ render::gl::pop();
+ }
+}
+
}
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 8fa32c2..24f9793 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -62,7 +62,7 @@ public:
/// receive global key input
bool input_key(const bool pressed, const int key, const unsigned int modifier);
-
+
/// run a user interface frame
void frame();
@@ -77,7 +77,12 @@ public:
inline const Font *font_large() const {
return ui_font_large;
}
-
+
+ /* -- mouse pointer ---------------------------------------- */
+
+ /// set mouse pointer bitmap
+ void set_pointer(const char *pointerbitmap=0, const Palette::Color color = Palette::Highlight,const bool animated = false);
+
protected:
typedef std::list<Window *> Menus;
@@ -95,6 +100,8 @@ protected:
virtual bool on_keyrelease(const int key, const unsigned int modifier);
private:
+ void draw_pointer();
+
Palette *ui_palette;
Font *ui_font_small;
Font *ui_font_large;
@@ -106,7 +113,10 @@ private:
Menus ui_menus;
/// TODO move to separate object to handle mouse cursor drawing
- math::Vector2f mouse_cursor;
+ math::Vector2f mouse_cursor;
+ std::string mouse_pointer_bitmap;
+ Palette::Color mouse_pointer_color;
+ bool mouse_pointer_animated;
};
/// initialize the user interface
diff --git a/src/ui/widget.cc b/src/ui/widget.cc
index 24dfe5c..606c4ab 100644
--- a/src/ui/widget.cc
+++ b/src/ui/widget.cc
@@ -209,6 +209,7 @@ void Widget::set_width(float const w)
{
widget_size.x = w;
}
+
void Widget::set_height(float const h)
{
widget_size.y = h;
@@ -339,10 +340,11 @@ void Widget::event_draw()
void Widget::event_resize()
{
+ resize();
+
for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) {
(*it)->event_resize();
}
- resize();
}
/* -- event handlers ----------------------------------------------- */
diff --git a/src/ui/widget.h b/src/ui/widget.h
index 41ad795..ef386c0 100644
--- a/src/ui/widget.h
+++ b/src/ui/widget.h
@@ -200,7 +200,7 @@ protected:
/// find the widget that has input focus
virtual Widget *find_input_focus();
-
+
/// find widget that has mosue focus
/** @param cursor mouse cursor position relative to this widget's location
*/
diff --git a/src/ui/window.cc b/src/ui/window.cc
index 3015a10..9ae9ec5 100644
--- a/src/ui/window.cc
+++ b/src/ui/window.cc
@@ -50,12 +50,8 @@ void Window::draw_border()
if (!border())
return;
- if(focus()) {
- paint::color(palette()->foreground());
- } else {
- paint::color(palette()->border());
- }
- paint::border(global_location(), size());
+ paint::color(palette()->border());
+ paint::border(global_location(), size());
}
}
diff --git a/src/ui/window.h b/src/ui/window.h
index 412d1f1..2a077ff 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -20,8 +20,6 @@ public:
Window(Widget *parent=0);
~Window();
- virtual void draw_border();
-
/// set the label of the previous window
void set_previous(Window *previous);
@@ -38,6 +36,7 @@ public:
}
protected:
+ virtual void draw_border();
std::string window_previous;
};