/* client/client.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 "audio/audio.h" #include "audio/sources.h" #include "client/chat.h" #include "client/client.h" #include "client/video.h" #include "client/console.h" #include "client/input.h" #include "client/view.h" #include "core/core.h" namespace client { core::Cvar *cl_framerate = 0; core::Cvar *cl_frametime = 0; Client app; //--- engine functions -------------------------------------------- void func_snd_restart(std::string const &args) { // unload entity sounds for (core::Entity::Registry::iterator it = core::Entity::registry().begin(); it != core::Entity::registry().end(); it++) { core::Entity *entity = (*it).second; if (entity->state()) entity->state()->clearsound(); } audio::shutdown(); audio::init(); } void func_r_restart(std::string const &args) { video::shutdown(); if (!video::init()) { app.quit(1); } input::reset(); } //--- public ------------------------------------------------------ void client_main(int count, char **arguments) { std::cout << core::name() << " " << core::version() << std::endl; for (int i =0; i < count; i++) std::cout << arguments[i] << " "; std::cout << std::endl; app.init(count, arguments); app.run(); app.shutdown(); } Client *client() { return &app; } //--- private ----------------------------------------------------- void Client::quit(int status) { SDL_Quit(); core::Application::quit(status); } 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::Application::init(count, arguments); Console::init(); // client variables core::Cvar *cvar = 0; cvar = core::Cvar::get("cl_name", "Player", core::Cvar::Archive | core::Cvar::Info); cvar->set_info("[str] player name"); cvar = core::Cvar::get("cl_color", "1.0 1.0 1.0", core::Cvar::Archive | core::Cvar::Info); cvar->set_info("[r g b] player primary color"); cvar = core::Cvar::get("cl_colorsecond", "1.0 1.0 1.0", core::Cvar::Archive | core::Cvar::Info); cvar->set_info("[r g b] player secondary color"); cl_framerate = core::Cvar::get("cl_framerate", "125", core::Cvar::Archive); cl_framerate->set_info("[int] client framerate in frames/sec"); // initialize SDL, but do not initialize any subsystems SDL_Init(0); // Initialize the video subsystem if (!video::init()) { quit(1); } // initialize console chat::init(); // initialize input input::init(); // initialize audio audio::init(); // add engine functions core::Func *func = 0; func = core::Func::add("r_restart", (core::FuncPtr) func_r_restart); func->set_info("restart render subsystem"); func = core::Func::add("snd_restart", (core::FuncPtr) func_snd_restart); func->set_info("restart audio subsystem"); } void Client::run() { con_print << "^BRunning client..." << std::endl; // default framerate 125fps, 8 milliseconds Uint32 client_frame_lenght = 8; Uint32 client_previous_timestamp = 0; Uint32 client_current_timestamp = 0; console()->flush(); console()->clear_notify(); while (true) { // current time in microseconds client_current_timestamp = SDL_GetTicks(); // calculate the desired frame length if (cl_framerate->value() < 0) { (*cl_framerate) = 0.0f; } else if (cl_framerate->value() > 1000.0f) { (*cl_framerate) = 1000.0f; } if (cl_framerate->value()) { client_frame_lenght = (Uint32) roundf(1000.0f / cl_framerate->value()); } else { client_frame_lenght = 0; } // only advance per microsecond frame Uint32 d = client_current_timestamp - client_previous_timestamp; if ((d > 0)) { if (d >= client_frame_lenght) { float elapsed = (float)(d) / 1000.f; core::Application::frame(elapsed); video::frame(elapsed); input::frame(elapsed); client_previous_timestamp = client_current_timestamp; } else { SDL_Delay(client_frame_lenght - d); } } else { SDL_Delay(1); } } } void Client::shutdown() { con_print << "^BShutting down client..." << std::endl; core::Func::remove("r_restart"); core::Func::remove("snd_restart"); chat::shutdown(); audio::shutdown(); Console::shutdown(); input::shutdown(); video::shutdown(); core::Application::shutdown(); quit(0); } void Client::notify_sound(const char * name) { audio::play(name); } void Client::notify_remove_sound(size_t source) { audio::Sources::remove(source); } void Client::notify_message(std::string const & message) { con_print << message << std::endl; console()->notify(message); } void Client::notify_zoneclear(core::Zone *zone) { // FIXME unload zone textures /* if (!zone) return; for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content.end(); i++) { core:: Entity *entity = (*it); if (entity->type() == core::Entity::Globe) { core::EntityGlobe *globe = static_cast(entity); if (globe->render_texture) render::Textures::unload(render_texture); } if (zone->sky_texture()) { render::Textures::unload(zone->sky_texture()); zone->set_sky_texture(0); } */ } } // namespace client