terom@185: terom@185: #include "Engine.hh" terom@185: #include "SinglePlayer.hh" terom@380: #include "Config.hh" terom@185: terom@417: // XXX: how does this work if we don't have NETWORK_ENABLED? terom@417: #include "Network/Reactor.hh" terom@417: terom@417: // include the real component definitions terom@417: #if NETWORK_ENABLED terom@417: #include "Network/Client.hh" terom@417: #include "Network/Server.hh" terom@417: #endif terom@417: terom@417: #if GRAPHICS_ENABLED terom@417: #include "Graphics/Graphics.hh" terom@423: #include "Graphics/GameView.hh" terom@417: #endif terom@417: terom@185: #include terom@417: #include terom@185: terom@418: /* terom@418: * Initialize static Engine global state terom@418: */ terom@418: LogLevel Engine::log_level = DEBUG; terom@418: terom@418: Engine::Engine (const EngineConfig &config) : terom@411: terrain(NULL), game_state(NULL), graphics(NULL), net_server(NULL), net_client_connect(NULL), terom@419: game_view(NULL), terom@418: is_running(true), resources(config.resource_path) terom@233: { terom@418: // update global log_level terom@418: Engine::log_level = config.log_level; terom@185: } terom@185: terom@419: void Engine::setupGame (Terrain *terrain) { terom@408: // ensure this isn't called in inappropriate ways terom@408: assert(!net_server); terom@408: terom@408: // remember the terrain terom@408: this->terrain = terrain; terom@408: terom@408: // create the GameState terom@408: game_state = new GameState(*terrain); terom@408: } terom@408: terom@409: void Engine::setupGame (const TerrainConfig &config) { terom@408: // proxy off to setupGame(Terrain *) terom@409: setupGame(new Terrain(config)); terom@408: } terom@408: terom@417: void Engine::setupGraphics (const DisplayConfig &config) { terom@417: terom@417: #if GRAPHICS_ENABLED terom@417: assert(!graphics); terom@417: terom@185: // create the graphics terom@411: graphics = new graphics::Graphics(*this, resources, config); terom@417: terom@417: #else terom@417: (void) config; terom@417: terom@417: throw Error("No Graphics support available"); terom@417: terom@417: #endif terom@417: terom@417: } terom@417: terom@417: void Engine::startGameView (LocalPlayer *player) { terom@417: terom@417: #if GRAPHICS_ENABLED terom@419: assert(graphics && !game_view); terom@417: terom@419: game_view = graphics->displayGameView(*game_state, player); terom@417: terom@417: #else terom@417: (void) player; terom@417: terom@417: throw Error("No Graphics support available"); terom@417: terom@417: #endif terom@417: terom@185: } terom@185: terom@185: void Engine::setupNetworkServer (const std::string &listen_port) { terom@417: terom@418: #if NETWORK_ENABLED terom@381: NetworkEndpoint listen_addr(listen_port); terom@408: terom@409: assert(terrain && game_state); terom@409: terom@185: // create the server terom@408: net_server = new NetworkServer(*game_state, listen_addr); terom@411: terom@411: // put graphics into GameView mode terom@411: if (graphics) terom@417: startGameView(NULL); terom@417: terom@417: #else terom@417: (void) listen_port; terom@417: terom@417: throw Error("No Network support available"); terom@417: terom@417: #endif terom@185: } terom@185: terom@185: void Engine::setupNetworkClient (const std::string &connect_host, const std::string &connect_port) { terom@417: terom@418: #if NETWORK_ENABLED terom@423: // client operation requires graphics terom@423: if (!GRAPHICS_ENABLED) terom@423: throw Error("Network client mode requires graphics support"); terom@423: terom@185: // connect_to terom@381: NetworkEndpoint connect_addr(connect_host, connect_port); terom@185: terom@408: // begin connecting, the client will callback us with setupGame once it's connected terom@408: net_client_connect = new NetworkClientConnect(*this, connect_addr); terom@417: terom@417: #else terom@417: (void) connect_host; terom@417: (void) connect_port; terom@417: terom@417: throw Error("No Network support available"); terom@417: terom@417: #endif terom@417: terom@185: } terom@185: terom@185: void Engine::setupSinglePlayer (void) { terom@409: assert(terrain && game_state); terom@408: terom@185: // create player directly terom@408: LocalPlayer* lp = new SinglePlayer(*game_state); terom@185: terom@185: // add to gamestate terom@408: game_state->setLocalPlayer(lp); terom@411: terom@411: // put graphics into GameView mode terom@411: if (graphics) terom@417: startGameView(lp); terom@419: } terom@419: terom@423: GameState& Engine::onNetworkClientConnected (Terrain *terrain) { terom@423: // sanity-check terom@423: assert(!terrain && !game_state && graphics); terom@419: terom@419: // setup the game terom@419: setupGame(terrain); terom@419: terom@419: // start the GameView, but no LocalPlayer yet terom@419: startGameView(NULL); terom@419: terom@419: // return GameState terom@419: return *game_state; terom@419: } terom@423: terom@419: void Engine::onNetworkClientPlayer (LocalPlayer *player) { terom@423: terom@423: #if GRAPHICS_ENABLED terom@419: assert(game_view); terom@419: terom@419: // set the GameView's player terom@419: game_view->setPlayer(player); terom@423: terom@423: #else terom@423: (void) player; terom@423: terom@423: assert(graphics); terom@423: terom@423: #endif terom@423: terom@185: } terom@185: terom@185: void Engine::stop (void) { terom@185: is_running = false; terom@185: } terom@185: terom@185: void Engine::run (void) { terom@424: #if NETWORK_ENABLED terom@418: // timeout for NetworkReactor terom@418: timeval timeout; terom@424: #endif terom@418: terom@185: while (is_running) { terom@417: /* terom@417: * Run internal ClanLib stuff (also includes our timers) until our timeout has elapsed terom@417: */ terom@417: CL_System::keep_alive(ENGINE_TIMEOUT_MS); terom@380: terom@418: #if NETWORK_ENABLED terom@418: // setup timeout to zero terom@418: timeout.tv_sec = 0; terom@418: timeout.tv_usec = 0; terom@418: terom@380: /* terom@380: * Thursday came and went, I re-wrote clan-event. terom@380: * terom@417: * (actually, we only use it for zero-timeout polling now... not sure if this is better than using the above terom@417: * CL_System::keep_alive) terom@380: */ terom@418: NetworkReactor::current->poll(&timeout); terom@417: #endif terom@185: } terom@185: } terom@185: