/* view.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include #include #include #include #include #include "auxiliary/functions.h" #include "client/client.h" #include "client/chat.h" #include "client/input.h" #include "client/targets.h" #include "client/video.h" #include "client/view.h" #include "render/render.h" #include "core/core.h" #include "math/mathlib.h" #include "sys/sys.h" #include "ui/paint.h" #include "ui/ui.h" #include "ui/widget.h" namespace client { void time_to_stream(std::stringstream &str, float time) { int minutes = (int) floorf(time / 60.0f); int seconds = (int) floorf( time - (float) minutes* 60.0f); str << std::setfill(' ') << std::setw(4) << minutes << ":" << std::setfill('0') << std::setw(2) << seconds; } /* -- DevInfo------------------------------------------------------- */ DevInfo::DevInfo(ui::Widget *parent) : ui::Widget(parent) { set_label("devinfo"); set_border(false); set_background(false); } void DevInfo::draw() { std::stringstream textstream; core::Entity *target = targets::current(); float d = 0; textstream << "^Ncore ^B"; time_to_stream(textstream, core::application()->time()); textstream << '\n'; if (core::game()) { textstream << "^Ntime ^B"; time_to_stream(textstream, core::game()->time()); } textstream << '\n'; if (core::localcontrol()) { textstream << std::fixed << std::setprecision(2) << "^Nx ^B" << core::localcontrol()->location().x << " " << "^Ny ^B" << core::localcontrol()->location().y << " " << "^Nz ^B" << core::localcontrol()->location().z << '\n'; textstream << "^Nthurst ^B" << core::localcontrol()->thrust() << " " << "^Nspeed ^B" << core::localcontrol()->speed() << '\n'; if (target) { d = math::distance(core::localcontrol()->location(), target->location()) - target->radius() - core::localcontrol()->radius(); textstream << "^Ndist ^B" << d << '\n'; } } ui::paint::color(palette()->foreground()); ui::paint::text(global_location(), size(), font(), textstream); } /* -- Stats -------------------------------------------------------- */ Stats::Stats(ui::Widget *parent) : ui::Widget(parent) { set_label("stats"); set_border(false); set_background(false); // clear counters for (size_t i =0; i < fps_counter_size; i++) fps_counter_time[i] = 0.0f; for (size_t i = 0; i < net_counter_size; i++) net_counter_traffic[i] = 0; net_counter_index = 0; fps_counter_index = 0; } void Stats::draw() { // average fps fps_counter_time[fps_counter_index] = core::application()->time(); fps_counter_index = (fps_counter_index + 1 ) % fps_counter_size; float min_time = core::application()->time(); for (size_t i=0; i < fps_counter_size; i++) if (fps_counter_time[i] < min_time) min_time = fps_counter_time[i]; float fps = 0.0f; float t = (core::application()->time() - min_time); if (t > 0) { fps = roundf(((float) fps_counter_size - 1.0f) / t); } std::stringstream textstream; if (core::game()) { textstream << "^Ntime ^B"; time_to_stream(textstream, core::game()->time()); } textstream << std::setfill(' ') << "\n"; textstream << "^Nfps ^B" << std::setw(6) << fps << "\n"; if (core::application()->connected()) { textstream << "^Ntris ^B" << std::setw(5) << render::Stats::tris << "\n"; textstream << "^Nquads ^B" << std::setw(5) << render::Stats::quads << "\n"; if (core::Stats::network_bytes_sent + core::Stats::network_bytes_received) { net_counter_traffic[net_counter_index] = core::Stats::network_bytes_sent + core::Stats::network_bytes_received; net_counter_time[net_counter_index] = core::application()->time(); size_t index_max = net_counter_index; net_counter_index = (net_counter_index + 1) % net_counter_size; size_t index_min = net_counter_index; float d = net_counter_time[index_max] - net_counter_time[index_min]; if (d > 0) { float traffic = net_counter_traffic[index_max] - net_counter_traffic[index_min]; textstream << "^Nnet ^B" << std::setw(6) << roundf( (float) traffic / d ) << "\n"; } } } ui::paint::color(palette()->foreground()); ui::paint::text(global_location(), size(), font(), textstream); } /* -- KeyPress ----------------------------------------------------- */ KeyPress::KeyPress(ui::Widget *parent) : Widget(parent) { set_label("keypress"); set_border(false); set_background(false); } void KeyPress::draw() { std::string label; ui::paint::color(palette()->highlight()); Key::Modifier mod = input::modifier(); if (mod != Key::None) { if (mod == Key::Shift) label.assign("shift+"); else if (mod == Key::Ctrl) label.assign("ctrl+"); else if (mod == Key::Alt) label.assign("alt+"); } if(input::last_key_pressed()) { label.append(input::last_key_pressed()->name()); } if (label.size()) ui::paint::label(global_location(), size(), font(), label , ui::AlignCenter); } /* -- View --------------------------------------------------------- */ View::View(ui::Widget *parent) : ui::Widget(parent) { set_label("view"); set_border(false); // add child widgets view_devinfo = new DevInfo(this); view_stats = new Stats(this); view_keypress = new KeyPress(this); view_notify = new Notifications(this); view_chat = new Chat(this); view_map = new Map(this); view_hud = new HUD(this); // make sure the view is at the bottom of the draw stack lower(); } void View::resize() { set_size(parent()->size()); // set hud geometry view_hud->set_geometry(0,0, width(), height()); view_hud->event_resize(); // reposition devinfo widget view_devinfo->set_size(font()->width()*32, font()->height()*5); view_devinfo->set_location(font()->width() * 0.5f, font()->height() * 0.5f); // reposition stats widget view_stats->set_size(font()->width()*12, font()->height()*5); view_stats->set_location(width() - view_stats->width() - font()->width() * 0.5, font()->height() * 0.5f); // reposition keypress widget view_keypress->set_size(font()->width()*12, font()->height()*1); view_keypress->set_location(width() - view_keypress->width() - font()->width() * 0.5, height() - view_keypress->height() - font()->height() * 0.5f); // reposition map view_map->set_size(width() - font()->width() * 8, height() - font()->height() * 8); view_map->set_location(font()->width() * 4, font()->height() * 4); // reposition notifications view_notify->set_location(ui::UI::elementsize.width()*2.0f+ font()->width(), view_devinfo->top() + view_devinfo->height() + font()->height()); view_notify->set_size(width() - ui::UI::elementsize.width()*2.0f - font()->width() * 2, height() * 0.5f - view_notify->top()); } void View::draw() { // draw hud only when connected and controlling a spacecraft if (core::application()->connected() && core::localcontrol() && !ui::root()->active()) { view_hud->set_visible(true); } else { view_hud->set_visible(false); } // reposition chat widget if (!view_chat->small_view()) { view_chat->set_location(font()->width(), view_devinfo->top() + view_devinfo->height() + font()->height()); view_chat->set_size(width() - font()->width() * 16, height() - view_chat->top() - font()->height() * 8); } else { view_chat->set_size(width() - font()->width() * 16, font()->height() * 2); view_chat->set_location(font()->width(), height() - font()->height() * 8 - view_chat->height()); } view_chat->event_resize(); view_devinfo->set_visible(draw_devinfo->value() ? true : false); view_stats->set_visible(draw_stats->value() ? true : false); view_keypress->set_visible(draw_keypress->value() ? true : false); if (core::application()->connected() && core::game()->interactive()) { if (ui::console()->visible()) { view_notify->set_visible(false); } else if (view_chat->visible() && !view_chat->small_view()) { view_notify->set_visible(false); } else { view_notify->set_visible(true); } } else { view_notify->set_visible(false); view_chat->set_visible(false); } if (!core::localcontrol()) { view_map->set_visible(false); } } } // namespace client