/* Danger from the Deep - Open source submarine simulation Copyright (C) 2003-2006 Thorsten Jordan, Luis Barrancos and others. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // global data // subsim (C)+(W) Thorsten Jordan. SEE LICENSE #include "model.h" #include "texture.h" #include "image.h" #include "font.h" #include "global_data.h" #include #include #include #include "oglext/OglExt.h" #include "system.h" #include "datadirs.h" #include #include using namespace std; // computed with an earth radius of 40030.17359km const double DEGREE_IN_METERS = 111194.9266388889; const double MINUTE_IN_METERS = 1853.248777315; // same with version string string get_program_version() { return string(VERSION); } global_data* global_data::inst = 0; global_data::global_data() : modelcache(get_data_dir()), imagecache(get_image_dir()), texturecache(get_texture_dir()), //soundcache(get_sound_dir()), fontcache(get_font_dir()) { if (inst != 0) throw std::runtime_error("must not initialize global_data object twice"); inst = this; } global_data::~global_data() { inst = 0; } // remove this ASAP. texture *notepadsheet, *terraintex, *panelbackground; font *font_arial, *font_jphsl, *font_vtremington10, *font_vtremington12, *font_typenr16; bool loading_screen_usable = false; void init_global_data() { font_arial = fontcache().ref("font_arial"); loading_screen_usable = true; font_jphsl = fontcache().ref("font_jphsl"); font_vtremington10 = fontcache().ref("font_vtremington10"); font_vtremington12 = fontcache().ref("font_vtremington12"); font_typenr16 = fontcache().ref("font_typenr16"); add_loading_screen("fonts loaded"); // later: they should get loaded by environmental classes (sky/water/user_interface) panelbackground = 0; // not used with new ingame gui notepadsheet = new texture(get_texture_dir() + "notepadsheet.png" /*, GL_CLAMP_TO_EDGE*/); terraintex = new texture(get_texture_dir() + "terrain.jpg", texture::LINEAR); add_loading_screen("textures loaded"); } void deinit_global_data() { delete panelbackground; delete notepadsheet; delete terraintex; } // display loading progress list loading_screen_messages; unsigned starttime; void display_loading_screen() { if (!loading_screen_usable) return; glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); sys().prepare_2d_drawing(); glColor4f(1, 1, 1, 1); unsigned fh = font_arial->get_height(); unsigned y = 0; for (list::const_iterator it = loading_screen_messages.begin(); it != loading_screen_messages.end(); ++it) { font_arial->print(0, y, *it); y += fh; } sys().unprepare_2d_drawing(); sys().swap_buffers(); } void reset_loading_screen() { loading_screen_messages.clear(); loading_screen_messages.push_back("Loading..."); sys().add_console("Loading..."); display_loading_screen(); starttime = sys().millisec(); } void add_loading_screen(const string& msg) { unsigned tm = sys().millisec(); unsigned deltatime = tm - starttime; starttime = tm; ostringstream oss; oss << msg << " (" << deltatime << "ms)"; loading_screen_messages.push_back(oss.str()); sys().add_console(oss.str()); display_loading_screen(); } string get_time_string(double tm) { unsigned seconds = unsigned(floor(myfmod(tm, 86400))); unsigned hours = seconds / 3600; unsigned minutes = (seconds % 3600) / 60; seconds = seconds % 60; ostringstream oss; oss << setw(2) << setfill('0') << hours << ":" << setw(2) << setfill('0') << minutes << ":" << setw(2) << setfill('0') << seconds; return oss.str(); } static double transform_nautic_coord_to_real(const string& s, char minus, char plus, int degmax) { if (s.length() < 2) throw error(string("nautic coordinate invalid ") + s); char sign = s[s.length() - 1]; if (sign != minus && sign != plus) throw error(string("nautic coordinate (direction sign) invalid ") + s); // find separator string::size_type st = s.find("/"); if (st == string::npos) throw error(string("no separator in position string ") + s); string degrees = s.substr(0, st); string minutes = s.substr(st + 1, s.length() - st - 2); int deg = atoi(degrees.c_str()); if (deg < 0 || deg > degmax) throw error(string("degrees are not in range [0...180/360] in position string ") + s); int mts = atoi(minutes.c_str()); if (mts < 0 || mts > 59) throw error(string("minutes are not in [0...59] in position string ") + s); return (sign == minus ? -1 : 1) * ((DEGREE_IN_METERS * deg) + (MINUTE_IN_METERS * mts)); } double transform_nautic_posx_to_real(const string& s) { return transform_nautic_coord_to_real(s, 'W', 'E', 180); } double transform_nautic_posy_to_real(const string& s) { return transform_nautic_coord_to_real(s, 'S', 'N', 90); } std::list string_split(const std::string& src, char splitter) { std::list result; std::string::size_type where = 0, st = 0; do { st = src.find(splitter, where); if (st == std::string::npos) { // rest of string result.push_back(src.substr(where)); } else { result.push_back(src.substr(where, st - where)); where = st + 1; } } while (st != std::string::npos); return result; }