/* core/application.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include #include #include #include "math/mathlib.h" #include "sys/sys.h" #include "filesystem/filesystem.h" #include "core/application.h" #include "core/core.h" #include "core/entity.h" #include "core/func.h" #include "core/cvar.h" #include "core/netserver.h" namespace core { Cvar sv_dedicated; Cvar net_host; Cvar net_port; // --------------- engine functions ------------------------------ void func_print(std::stringstream &args) { char text[MAXCMDSIZE]; if (args.getline(text, MAXCMDSIZE)) { // remove the leading space if (text[0] && text[1]) { con_print << text+1 << std::endl; } } } void func_help(std::stringstream &args) { con_print << "This is the help function" << std::endl; } void func_quit(std::stringstream &args) { if (Application::instance()) { Application::instance()->shutdown(); Application::instance()->quit(0); } } void func_connect(std::stringstream &args) { if (Application::instance()) Application::instance()->connect(); } void func_disconnect(std::stringstream &args) { if (Application::instance()) Application::instance()->disconnect(); } void func_list_func(std::stringstream &args) { func::list(); } void func_list_var(std::stringstream &args) { cvar::list(); } void func_list_ent(std::stringstream &args) { entity::list(); } // --------------- signal_handler ----------------------------------- extern "C" void signal_handler(int signum) { switch (signum) { case SIGHUP: case SIGINT: case SIGQUIT: case SIGTERM: if (Application::instance()) { con_warn << "Received signal " << signum << ", shutting down..." << std::endl; Application::instance()->shutdown(); Application::instance()->quit(0); } else { std::cerr << "Received signal " << signum << ", terminated..." << std::endl; sys::quit(1); } break; default: std::cerr << "Received signal " << signum << ", terminated..." << std::endl; sys::quit(1); break; } } // --------------- Application ----------------------------- Application *Application::application_instance = 0; Application::Application() { netserver = 0; if (application_instance) { std::cerr << "multiple core::Application instances!" << std::endl; sys::quit(2); } application_instance = this; sys::signal(SIGHUP, signal_handler); sys::signal(SIGINT, signal_handler); sys::signal(SIGQUIT, signal_handler); sys::signal(SIGTERM, signal_handler); } Application::~Application() { application_instance = 0; } Application *Application::instance() { return application_instance; } void Application::init() { con_print << "Initializing core..." << std::endl; con_debug << "Debug messages enabled" << std::endl; // initialize core subsystems filesystem::init(); // dedicated or not, client should have set this to 0 core::sv_dedicated = core::cvar::get("sv_dedicated", "1", core::cvar::ReadOnly); if (sv_dedicated->value()) localplayer.name = "Console"; else localplayer.name = "Player"; // network settings core::net_host = core::cvar::get("net_host", "0.0.0.0"); core::net_port = core::cvar::get("net_port", "8042"); // register our functions func::add("print", func_print); func::add("help", func_help); func::add("quit", func_quit); func::add("connect", func_connect); func::add("disconnect", func_disconnect); func::add("list_var", func_list_var); func::add("list_func", func_list_func); func::add("list_ent", func_list_ent); if (game()) game()->connected = false; current_time = 0; } void Application::shutdown() { con_print << "Shutting down core..." << std::endl; if (game() && game()->connected) disconnect(); if (netserver) { delete netserver; netserver = 0; } filesystem::shutdown(); } void Application::quit(int status) { sys::quit(status); } void Application::connect() { if (!game()) { con_warn << "No game module loaded!" << std::endl; return; } if (game()->connected) { con_warn << "Connected. Disconnect first." << std::endl; } entity::clear(); game()->current_time = 0; if (game()->connected = game()->init()) { con_print << "Connected." << std::endl; } else { con_warn << "Connect failed." << std::endl; return; } if (core::sv_dedicated->value() && !netserver) { netserver = new NetServer(net_host->text(), (unsigned int)net_port->value()); } } void Application::disconnect() { if (!game()) { con_warn << "No game module loaded!" << std::endl; return; } if (!game()->connected) { con_warn << "Not connected." << std::endl; return; } game()->shutdown(); game()->connected = false; game()->current_time = 0; // remove all entities entity::clear(); // TODO remove all game functions // TODO remove all game cvars con_print << "Disconnected." << std::endl; } void Application::frame(float seconds) { current_time += seconds; if (netserver) { // TODO limit netserver frames in local mode netserver->frame(seconds); } if (game() && game()->connected) { entity::frame(seconds); game()->current_time += seconds; game()->frame(seconds); } // execute commands in the buffer commandbuffer::execute(); } }