From 840f9b8678f607aecc15d47bc77248c4ac8b8574 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 4 Feb 2008 00:54:30 +0000 Subject: tweaked console client status with timer and fps core connect/disconnect --- src/client/application.cc | 60 ++++++++------- src/client/application.h | 3 + src/client/client.h | 3 + src/client/console.cc | 134 +++++++++++++-------------------- src/client/console.h | 7 +- src/client/input.cc | 35 +++++---- src/client/input.h | 4 +- src/client/video.cc | 5 +- src/client/video.h | 4 +- src/client/view.cc | 158 +++++++++++++++++++++++++++++---------- src/client/view.h | 10 ++- src/core/applicationinterface.cc | 78 ++++++++++++++++--- src/core/applicationinterface.h | 8 ++ src/core/core.h | 8 +- src/core/gameinterface.cc | 27 +------ src/core/gameinterface.h | 18 ++--- src/filesystem/filesystem.h | 2 + src/game/game.cc | 29 +++---- src/game/game.h | 2 +- src/render/text.cc | 78 ++++++++++++------- src/render/text.h | 15 +++- src/server/application.cc | 9 ++- src/server/timer.cc | 8 +- src/server/timer.h | 5 -- src/sys/sys.cc | 33 +++++++- src/sys/sys.h | 18 ++++- 26 files changed, 471 insertions(+), 290 deletions(-) diff --git a/src/client/application.cc b/src/client/application.cc index 5822600..b7505a1 100644 --- a/src/client/application.cc +++ b/src/client/application.cc @@ -1,7 +1,7 @@ /* client/application.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 + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 */ // project headers @@ -15,7 +15,8 @@ // C++ headers #include -namespace client { +namespace client +{ extern "C" void func_con_toggle(std::stringstream &args) { @@ -33,16 +34,16 @@ void Application::init() // initialize core core::ApplicationInterface::init(); - con_debug << "Initializing client..." << std::endl; + con_print << "Initializing client..." << std::endl; // Initialize the video subsystem video.init(); if (!video.initialized) { - quit(1); - } + quit(1); + } - // initialize input - input.init(); + // initialize input + input.init(); // register our engine functions core::func_register("con_toggle", func_con_toggle); @@ -52,41 +53,46 @@ void Application::run() { Uint32 chrono = SDL_GetTicks(); - while(true) { - Uint32 current = SDL_GetTicks(); - - // overflow protection ~49 days - if (current < chrono) { - chrono = current; - } + while (true) { + Uint32 current = SDL_GetTicks(); - // update the game chronometers - float elapsed = (float) ( current - chrono) / 1000.0f; - chrono = current; + // overflow protection ~49 days + if (current < chrono) { + chrono = current; + } - core::ApplicationInterface::frame(elapsed); + // update the core chronometer + float seconds = ((float)(current - chrono)) / 1000.0f; + frame(seconds); + + // update the video chronometers and draw + video.frame(seconds); + if (seconds > 0) + current_fps = floorf(1/seconds); + else + current_fps = 9999; - // update the video chronometers and draw - video.draw(elapsed); + // process input + input.frame(); - // process input - input.process(); - } + // update the main loop chronometer + chrono = current; + } } -void Application::shutdown() +void Application::shutdown() { con_debug << "Shutting down client..." << std::endl; console.flush(); input.shutdown(); console.flush(); - + video.shutdown(); console.flush(); - core::ApplicationInterface::shutdown(); + core::ApplicationInterface::shutdown(); console.flush(); quit(0); diff --git a/src/client/application.h b/src/client/application.h index 40da1da..62eccd6 100644 --- a/src/client/application.h +++ b/src/client/application.h @@ -25,6 +25,9 @@ public: /// quit the client Application virtual void quit(int status); + + /// current fps + float current_fps; }; } diff --git a/src/client/client.h b/src/client/client.h index 64f1aab..66a7700 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -47,6 +47,9 @@ extern Console console; /// global Game instance extern game::Game game; +/// current fps +inline float fps() { return (application.current_fps); } + } // namespace client #endif // __INCLUDED_CLIENT_H__ diff --git a/src/client/console.cc b/src/client/console.cc index a0cc7c5..dfc1d08 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -14,7 +14,7 @@ namespace client { Console::Console() { - visible = false; + console_visible = true; } std::ostream & Console::messagestream() @@ -40,87 +40,65 @@ std::ostream & Console::debugstream() void Console::draw() { using namespace render; - - // flush console messages in the buffer - flush(); - - float height; - bool showloader = false; - - if (core::game()) { - if (!core::game()->ready()) { - height = 0.6f; - showloader = true; - } else if (visible) - height = 0.6f; - else - height = 0.0f; - } else { - showloader = true; - height = 1.0f; - } + + console.flush(); + if(!console_visible) + return; - if (showloader) { - // draw the loader background - gl::color(0.5f, 0.5f, 0.5f, 1.0f); + float con_height = 0.70f; - gl::begin(gl::Quads); - gl::vertex(0,0, 0); - gl::vertex(video.width,0,0); - gl::vertex(video.width,video.height,0); - gl::vertex(0,video.height,0); - gl::end(); - } + glBindTexture(GL_TEXTURE_2D, render::textures[1]); // bitmaps/conchars.tga + + // draw version below the bottom of the console + gl::enable(GL_TEXTURE_2D); + gl::color(0.0f, 1.0f, 0.0f, 0.5f); + std:: string version = std::string("The Osirion Project "); + version.append(VERSION); + draw_text(video.width-CHARWIDTH*(version.size()+1), video.height*con_height-CHARHEIGHT-4, version); + gl::disable(GL_TEXTURE_2D); + + // draw the transparent console background + gl::color(1.0f, 1.0f, 1.0f, 0.01f); + + gl::begin(gl::Quads); + gl::vertex(0.0f, 0.0f, 0.0f); + gl::vertex(video.width, 0.0f,0.0f); + gl::vertex(video.width,video.height*con_height,0.0f); + gl::vertex(0,video.height*con_height,0.0f); + gl::end(); - if (height > 0) { - // draw version below the bottom of the console - gl::color(0.0f, 1.0f, 0.0f, 1.0f); - std:: string version = std::string("The Osirion Project "); - version.append(PACKAGE_VERSION); - draw_text(video.width-CHARSIZE*(version.size()+1), video.height*height-CHARSIZE-4, version); - - // draw the transparent console background - gl::color(1, 1, 1, .5); + // draw the console text + gl::enable(GL_TEXTURE_2D); + std::deque::reverse_iterator rit = console.text.rbegin(); + float y = video.height*con_height-2*CHARHEIGHT-8; + while (y > 0 && rit < console.text.rend()) { + std::string line(*rit); - gl::enable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, render::textures[0]); // bitmaps/loader.tga + if (line[0] == '?') + gl::color(0.7f,0.7f,0.7f, 1.0f); + else if (line[0] == '*') + gl::color(1.0f,1.0f,0.0f, 1.0f); + else if (line[0] == '!') + gl::color(1.0f,0.0f,0.0f, 1.0f); + else + gl::color(1.0f,1.0f,1.0f, 1.0f); + line.erase(0,2); - gl::begin(gl::Quads); - glTexCoord2f(0.0f, 0.0f); - gl::vertex(0,0, 0); - - glTexCoord2f(1.0f, 0.0f); - gl::vertex(video.width,0,0); - - glTexCoord2f(1.0f, 1.0f); - gl::vertex(video.width,video.height*height,0); - - glTexCoord2f(0.0f, 1.0f); - gl::vertex(0,video.height*height,0); - - gl::end(); + draw_text(CHARWIDTH, y, line); + y -= CHARHEIGHT; + ++rit; + } - glBindTexture(GL_TEXTURE_2D, render::textures[1]); // bitmaps/conchars.tga - gl::enable(GL_BLEND); - - // draw the console text - gl::color(1,1,1,1); - std::deque::reverse_iterator rit = console.text.rbegin(); - float y = video.height*height-2*CHARSIZE-8; - while (y > 0 && rit < console.text.rend()) { - draw_text(0, y, *rit); - y -= CHARSIZE; - ++rit; - } + // draw the console input + gl::color(0.0f, 1.0f, 0.0f, 1.0f); + draw_text(CHARWIDTH, video.height*con_height - CHARHEIGHT - 4, input); - // draw the console input - gl::color(0.0f, 1.0f, 0.0f, 1.0f); - draw_text(0, video.height*height - CHARSIZE - 4, input); - - gl::disable(GL_TEXTURE_2D); - gl::disable(GL_BLEND); + // draw cursor + if ((core::time() - floorf(core::time())) < 0.5f) { + std::string cursor("_"); + draw_text(CHARWIDTH*(input.size()+1), video.height*con_height - CHARHEIGHT - 4 , cursor); } - + gl::disable(GL_TEXTURE_2D); } void Console::flush() @@ -140,18 +118,12 @@ void Console::flush() void Console::toggle() { - visible = !visible; + console_visible = !console_visible; } void Console::handle_keyreleased(SDL_keysym* keysym) { switch( keysym->sym ) { - case '`': - case '~': - toggle(); - return; - break; - case SDLK_RETURN: if (input.size()) { core::cmd << input << std::endl; diff --git a/src/client/console.h b/src/client/console.h index 7f98666..c0d485f 100644 --- a/src/client/console.h +++ b/src/client/console.h @@ -44,7 +44,8 @@ public: /// toggle the console on or off void toggle(); - bool visible; + /// true of the console is visible + inline bool visible() { return console_visible; } /// toggle handle keyboard input void handle_keyreleased(SDL_keysym* keysym); @@ -54,13 +55,13 @@ protected: std::stringstream buffer; /// console text data - std::deque text; + std::deque text; private: std::string input; + bool console_visible; }; } #endif // __INCLUDED_CLIENT_CONSOLE_H__ - diff --git a/src/client/input.cc b/src/client/input.cc index 96cd032..c46c66f 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -28,15 +28,10 @@ see http://docs.mandragor.org/files/Common_libs_documentation/SDL/SDL_Documentation_project_en/sdlevent.html */ -// handle key_release events +// handle key_release events for the game world void Input::handle_keyreleased(SDL_keysym* keysym) { switch( keysym->sym ) { - case '`': - case '~': - //console.toggle(); - core::cmd << "con_toggle" << std::endl; - break; case SDLK_SPACE: camera.nextmode(); break; @@ -45,13 +40,10 @@ void Input::handle_keyreleased(SDL_keysym* keysym) } } -// handle pressed keys +// handle pressed keys for the game world void Input::handle_keypressed(SDL_keysym* keysym) { switch( keysym->sym ) { - case SDLK_ESCAPE: - client::application.shutdown(); - break; case SDLK_LEFT: camera.rotate_left(); break; @@ -82,22 +74,37 @@ void Input::handle_keypressed(SDL_keysym* keysym) } -void Input::process() +void Input::frame() { SDL_Event event; while( SDL_PollEvent( &event ) ) { + switch( event.type ) { case SDL_KEYDOWN: - if (!console.visible) + /* + if (event.key.keysym.sym == SDLK_ESCAPE) { + client::application.shutdown(); + } + */ + if (core::connected() && !console.visible()) { + // send key events to the game world handle_keypressed( &event.key.keysym ); + } break; + case SDL_KEYUP: - if (console.visible) + if (event.key.keysym.sym == '`' || event.key.keysym.sym == '~') { + console.toggle(); + } else if (console.visible()) { + // send key events to the console console.handle_keyreleased( &event.key.keysym ); - else + } else if (core::connected()) { + // send key events to the game world handle_keyreleased( &event.key.keysym ); + } break; + case SDL_QUIT: client::application.shutdown(); break; diff --git a/src/client/input.h b/src/client/input.h index 23ddd5d..6067522 100644 --- a/src/client/input.h +++ b/src/client/input.h @@ -18,8 +18,8 @@ public: /// shutdown the input subsystem void shutdown(); - /// process input events - void process(); + /// handle one frame of input events + void frame(); protected: /// handle key release events diff --git a/src/client/video.cc b/src/client/video.cc index 4018834..bfff445 100644 --- a/src/client/video.cc +++ b/src/client/video.cc @@ -88,10 +88,9 @@ void Video::init() return; } -void Video::draw(float elapsed) +void Video::frame(float seconds) { - if (core::game() && core::game()->ready()) - view.draw(elapsed); + view.frame(seconds); SDL_GL_SwapBuffers(); } diff --git a/src/client/video.h b/src/client/video.h index 6da89f3..edf7823 100644 --- a/src/client/video.h +++ b/src/client/video.h @@ -17,8 +17,8 @@ public: void init(); /// shutdown the video subsystem void shutdown(); - /// Update the screen state and redraw - void draw(float elapsed); + /// draw the next client video frame + void frame(float seconds); /// reset and clear the viewport void reset(); diff --git a/src/client/view.cc b/src/client/view.cc index 3b5f785..1dd0df6 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -12,6 +12,11 @@ #include "sys/sys.h" #include "math/mathlib.h" +#include +#include +#include +#include + using namespace render; namespace client @@ -41,25 +46,26 @@ void View::shutdown() } void View::reset() { - // Our shading model--Gouraud (smooth). + // shading model: Gouraud (smooth). gl::shademodel(GL_SMOOTH); - // Culling + // culling gl::cullface( GL_BACK ); gl::frontface(GL_CCW ); + // alpha-blending + gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl::disable(GL_BLEND); + + // depth + gl::depthmask(GL_TRUE); + gl::disable(GL_DEPTH_TEST); + gl::disable( GL_CULL_FACE ); } void View::draw_world(float elapsed) { - - gl::enable( GL_CULL_FACE ); - - // Depth buffer writing - gl::depthmask(GL_TRUE); - gl::enable(GL_DEPTH_TEST); - // draw the world gl::push(); @@ -73,17 +79,11 @@ void View::draw_world(float elapsed) stardrawer->draw(elapsed); gl::pop(); - gl::disable( GL_CULL_FACE ); - } void View::draw_background(float elapsed) { using namespace gl; - - // enable Alpha blending - gl::blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl::enable(GL_BLEND); // galactic axis begin(Lines); @@ -125,42 +125,107 @@ void View::draw_background(float elapsed) vertex(gridsize-dx, y, i-dz); } end(); - - gl::disable(GL_BLEND); - gl::disable(GL_DEPTH_TEST); } -void View::draw(float elapsed) +void View::draw_loader() { - // Clear the color and depth buffers. - gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + gl::enable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, render::textures[0]); // bitmaps/loader.tga + gl::color(1.0f, 1.0f, 1.0f, 1.0f); + + gl::begin(gl::Quads); + + glTexCoord2f(0.0f, 0.0f); + gl::vertex(0,0, 0); + + glTexCoord2f(1.0f, 0.0f); + gl::vertex(video.width,0,0); - // Change to the projection matrix and set our viewing volume. - gl::matrixmode( GL_PROJECTION ); - gl::loadidentity(); + glTexCoord2f(1.0f, 1.0f); + gl::vertex(video.width,video.height,0); - //glu::perspective( 64.0, video::ratio, 1.0, 1024.0 ); - const float frustumsize = 0.5f; - x = -frustumsize * video.ratio; - width = video.ratio; - y = -frustumsize; - height = 1; + glTexCoord2f(0.0f, 1.0f); + gl::vertex(0,video.height,0); + gl::end(); - //gl::frustum( -frustumsize * video.ratio, frustumsize * video.ratio, -frustumsize, frustumsize, 1.0f, 1024.0f); - gl::frustum(x, x+width, y, y +height, 1.0f, 1024.0f); + gl::disable(GL_TEXTURE_2D); +} - gl::matrixmode( GL_MODELVIEW ); - gl::loadidentity(); - gl::rotate(90.0f, 0, 1.0, 0); +void View::draw_status() +{ + using namespace std; + + if (console.visible()) + return; + + glBindTexture(GL_TEXTURE_2D, render::textures[1]); // bitmaps/conchars.tga + gl::enable(GL_TEXTURE_2D); + + // print the status in the upper left corner + gl::color(1.0f, 1.0f, 1.0f, 1.0f); + std::stringstream status; - // Camera transformation - camera.draw(elapsed); + int hours = (int) sys::time() / 3600; + int minutes = (int) (sys::time() - 3600*hours) / 60; + int seconds = (int) (sys::time() - 3600*hours - 60 *minutes); + status << " clock " << setfill('0') << setw(2) << hours << ":" + << setfill('0') << setw(2) << minutes << ":" + << setfill('0') << setw(2) << seconds; + + minutes = (int) floorf(core::time() / 60.0f); + seconds = (int) floorf(core::time() - (float) minutes* 60.0f); + + status << " time " << setfill('0') << setw(2) << minutes << ":" << setfill('0') << setw(2) << seconds; + status << " fps " << setw(4) << client::fps(); + draw_text(0, 4, status); + + // print the version number in the upper right corner + gl::color(0.0f, 1.0f, 0.0f, 1.0f); + std::string version("ver. "); + version.append(VERSION); + draw_text(video.width-(version.size()+1)*CHARWIDTH, 4, version); + + gl::disable(GL_TEXTURE_2D); +} - // draw the world - draw_world(elapsed); +void View::frame(float seconds) +{ + // Clear the color and depth buffers. + gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + if (core::connected()) { + // draw the game world + + // Change to the projection matrix and set our viewing volume. + gl::matrixmode( GL_PROJECTION ); + gl::loadidentity(); + + const float frustumsize = 0.5f; + x = -frustumsize * video.ratio; + width = video.ratio; + y = -frustumsize; + height = 1; + gl::frustum(x, x+width, y, y +height, 1.0f, 1024.0f); + + gl::matrixmode( GL_MODELVIEW ); + gl::loadidentity(); + gl::rotate(90.0f, 0, 1.0, 0); - // draw the semi-static background - draw_background(elapsed); + // Camera transformation + camera.draw(seconds); + + gl::enable(GL_DEPTH_TEST); // enable depth buffer writing + gl::enable(GL_CULL_FACE); // enable culling + + draw_world(seconds); // draw the world + + gl::disable(GL_CULL_FACE); // disable culling + gl::enable(GL_BLEND); // enable alpha blending + + draw_background(seconds); // draw the spacegrid + + gl::disable(GL_DEPTH_TEST); // disable depth buffer writing + } // switch to ortographic projection to draw the GUI gl::matrixmode( GL_PROJECTION ); @@ -169,9 +234,20 @@ void View::draw(float elapsed) gl::matrixmode( GL_MODELVIEW ); gl::loadidentity(); + + if (!core::connected()) { + // draw the loader bitmap + draw_loader(); + gl::enable(GL_BLEND); // enable alpha blending + } // draw the console console.draw(); + + // draw the status line + draw_status(); + + gl::disable(GL_BLEND); } } // namespace view diff --git a/src/client/view.h b/src/client/view.h index 92965ce..06d139d 100644 --- a/src/client/view.h +++ b/src/client/view.h @@ -18,8 +18,8 @@ public: /// shutdown the view void shutdown(); - /// update the chronometer and draw the game view - void draw(float elapsed); + /// draw the next frame + void frame(float seconds); /// reset the projection matrix void reset(); @@ -42,6 +42,12 @@ protected: /// draw the background void draw_background(float elapsed); + + /// draw the loader screen + void draw_loader(); + + /// draw the status bar + void draw_status(); }; } // namespace client diff --git a/src/core/applicationinterface.cc b/src/core/applicationinterface.cc index d195881..63e1dea 100644 --- a/src/core/applicationinterface.cc +++ b/src/core/applicationinterface.cc @@ -17,8 +17,9 @@ namespace core { // --------------- function repository ------------------------------ extern "C" void func_print(std::stringstream &args) { char text[MAXCMDSIZE]; + // FIXME leading space if(args.getline(text, MAXCMDSIZE)) - con_print << args << std::endl; + con_print << text << std::endl; } extern "C" void func_help(std::stringstream &args) { @@ -26,8 +27,20 @@ extern "C" void func_help(std::stringstream &args) { } extern "C" void func_quit(std::stringstream &args) { - ApplicationInterface::instance()->shutdown(); - ApplicationInterface::instance()->quit(0); + if(ApplicationInterface::instance()) { + ApplicationInterface::instance()->shutdown(); + ApplicationInterface::instance()->quit(0); + } +} + +extern "C" void func_connect(std::stringstream &args) { + if(ApplicationInterface::instance()) + ApplicationInterface::instance()->connect(); +} + +extern "C" void func_disconnect(std::stringstream &args) { + if(ApplicationInterface::instance()) + ApplicationInterface::instance()->disconnect(); } // --------------- signal_handler ----------------------------------- @@ -83,21 +96,25 @@ ApplicationInterface *ApplicationInterface::instance() void ApplicationInterface::init() { - filesystem::init(); - con_print << "Initializing core..." << std::endl; con_debug << "Debug messages enabled" << std::endl; + // initialize core subsystems + filesystem::init(); + // register our functions func_register("print", func_print); func_register("help", func_help); func_register("quit", func_quit); + func_register("connect", func_connect); + func_register("disconnect", func_disconnect); + if (game()) - game()->init(); + game()->connected = false; else con_warn << "No game module loaded!" << std::endl; - + current_time = 0; } void ApplicationInterface::shutdown() @@ -105,7 +122,8 @@ void ApplicationInterface::shutdown() con_print << "Shutting down core..." << std::endl; if (game()) - game()->shutdown(); + if (game()->connected) + disconnect(); else con_warn << "No game module loaded!" << std::endl; @@ -117,9 +135,51 @@ void ApplicationInterface::quit(int status) sys::quit(status); } +void ApplicationInterface::connect() +{ + if (!game()) { + con_warn << "No game module loaded!" << std::endl; + return; + } + + if (game()->connected) { + con_warn << "Connected. Disconnect first." << std::endl; + } + + game()->current_time = 0; + if (game()->connected = game()->init()) { + con_print << "Connected." << std::endl; + } else { + con_warn << "Connect failed." << std::endl; + } +} + +void ApplicationInterface::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; + + con_print << "Disconnected." << std::endl; +} + void ApplicationInterface::frame(float seconds) { - if (game()) { + current_time += seconds; + + if (game() && game()->connected) { + game()->current_time += seconds; game()->frame(seconds); } diff --git a/src/core/applicationinterface.h b/src/core/applicationinterface.h index ef02d8f..76dfe01 100644 --- a/src/core/applicationinterface.h +++ b/src/core/applicationinterface.h @@ -33,6 +33,14 @@ public: /// quit the application virtual void quit(int status); + /// connect to the game module + void connect(); + + /// disconnect from the game module + void disconnect(); + + /// time the core has been running, in seconds + float current_time; private: /// console singleton static ApplicationInterface *applicationinterface_instance; diff --git a/src/core/core.h b/src/core/core.h index 64eadb1..eb8e067 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -10,8 +10,6 @@ #include "core/gameinterface.h" #include "core/applicationinterface.h" -#define MAXCMDSIZE 1024 - /// core contains the basic functionality of the engine namespace core { @@ -20,6 +18,12 @@ namespace core /// pointer to the current ApplicationInterface inline ApplicationInterface *application() { return ApplicationInterface::instance(); } + + /// true if the core is connected to a game module + inline bool connected() { return (GameInterface::instance() && GameInterface::instance()->connected); } + + /// return the time the core has been running, in seconds + inline float time() { return ApplicationInterface::instance()->current_time; } }; #include "core/commandbuffer.h" diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc index ac5209b..86e8556 100644 --- a/src/core/gameinterface.cc +++ b/src/core/gameinterface.cc @@ -21,7 +21,7 @@ GameInterface::GameInterface() exit(2); } gameinterface_instance = this; - game_ready = false; + connected = false; } GameInterface::~GameInterface() @@ -34,29 +34,4 @@ GameInterface *GameInterface::instance() return gameinterface_instance; } -void GameInterface::init() -{ - game_ready = true; -} - -void GameInterface::shutdown() -{ - game_ready = false; -} - -bool GameInterface::ready() const -{ - return game_ready; -} - -float GameInterface::time() const -{ - return current_time; -} - -void GameInterface::frame (float seconds) -{ - current_time += seconds; -} - } diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h index 1986939..dde7f12 100644 --- a/src/core/gameinterface.h +++ b/src/core/gameinterface.h @@ -21,31 +21,27 @@ public: virtual ~GameInterface(); /// initialize the game - virtual void init(); + virtual bool init() = 0; /// shutdown the game - virtual void shutdown(); + virtual void shutdown() = 0; /// run one frame of the game /** @param sec time since the previous frame, in seconds */ - virtual void frame (float seconds); + virtual void frame (float seconds) = 0; /// a pointer to the current game instance static GameInterface * instance(); - /// return true if the game is ready and running - bool ready() const; + /// true if the game is ready and running + bool connected; - /// return the current game time, in seconds - float time() const; + /// time the game has been running, in seconds + float current_time; private: static GameInterface *gameinterface_instance; - - bool game_ready; - - float current_time; }; } diff --git a/src/filesystem/filesystem.h b/src/filesystem/filesystem.h index e1ff8c6..1685fd2 100644 --- a/src/filesystem/filesystem.h +++ b/src/filesystem/filesystem.h @@ -11,6 +11,8 @@ #include /// The filesystem namespace contains classes and functions for common file operations. +/** filesystem is a core subsystem + */ namespace filesystem { /// location of the main data files, includes trailing / diff --git a/src/game/game.cc b/src/game/game.cc index 0d79195..65e9450 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -18,11 +18,13 @@ namespace game { -void Game::init() +bool Game::init() { using math::Vector3f; using filesystem::IniFile; + con_print << "Initializing game..." << std::endl; + // read game.ini IniFile f; f.open("ini/game.ini"); @@ -78,7 +80,7 @@ void Game::init() con_warn << f.name() << " unknown key '" << f.key() << "' at line " << f.line() << std::endl; } } else if (f.got_section("world")) { - con_debug << "[world] section" << std::endl; + //con_debug << "[world] section" << std::endl; } else if (f.got_section("sector")) { sector = new Sector(); sectors.push_back(sector); @@ -88,23 +90,21 @@ void Game::init() } f.close(); - con_print << "Load sectors" << std::endl; + /* + con_print << "Loading sectors..." << std::endl; for (unsigned n =0; n < sectors.size(); n++) - con_print << sectors[n]->label << " " << sectors[n]->name << std::endl; - + con_print << " " << sectors[n]->label << " " << sectors[n]->name << std::endl; + */ star.location = Vector3f(256.0f, 0.0f, 256.0f); ship.location = Vector3f(0,0,0); - - // signal the gameinterface the game is ready - core::GameInterface::init(); - - // test functions - core::cmd << "help" << std::endl; - core::cmd << "test" << std::endl; + + return true; } void Game::shutdown() { + con_print << "Shutting down game..." << std::endl; + // delete every sector object in the sectors vector for (unsigned int n =0; n< sectors.size(); n++) { delete sectors[n]; @@ -112,15 +112,10 @@ void Game::shutdown() } // clear the sectors vector sectors.clear(); - - // signal the gameinterface the game has shutdown - core::GameInterface::shutdown(); } void Game::frame(float seconds) { - GameInterface::frame(seconds); - ship.update(seconds); } diff --git a/src/game/game.h b/src/game/game.h index 29f3e1b..f9c6667 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -27,7 +27,7 @@ namespace game class Game : public core::GameInterface { public: /// initialize the game - void init(); + bool init(); /// shutdown the game void shutdown(); /// execute one game grame diff --git a/src/render/text.cc b/src/render/text.cc index f97aff6..768ebf8 100644 --- a/src/render/text.cc +++ b/src/render/text.cc @@ -5,37 +5,63 @@ */ #include "render/render.h" -#include "GL/glut.h" +#include "sys/sys.h" namespace render { -void draw_text(float x, float y, std::string text) +void draw_text(float x, float y, const char ascii) +{ + if (ascii != ' ') { + int row = (int) ascii >> 4; + int col = (int) ascii & 15; + + float frow = row * 0.0625f; + float fcol = col * 0.0625f; + + gl::begin(gl::Quads); + + glTexCoord2f(fcol, frow); + gl::vertex(x,y,0); + + glTexCoord2f(fcol + 0.0625f, frow); + gl::vertex(x+CHARWIDTH,y,0); + + glTexCoord2f(fcol +0.0625f, frow + 0.0625f); + gl::vertex(x+CHARWIDTH,y+CHARHEIGHT,0); + + glTexCoord2f(fcol, frow+0.0625f); + gl::vertex(x,y+CHARHEIGHT,0); + + gl::end(); + } +} + + +void draw_text(float x, float y, const char *text) +{ + const char *c = text; + while (*c) { + draw_text(x, y, *c); + c++; + x += CHARWIDTH; + } +} + +void draw_text(float x, float y, std::stringstream & textstream) +{ + char line[MAXCMDSIZE]; + while (textstream.getline(line, MAXCMDSIZE-1)) { + draw_text(x, y, line); + y += CHARHEIGHT; + } + textstream.clear(); +} + +void draw_text(float x, float y, const std::string & text) { for (size_t i =0; i < text.size(); i++) { - if (text[i] != ' ') { - int row = (int) text[i] >> 4; - int col = (int) text[i] & 15; - - float frow = row * 0.0625f; - float fcol = col * 0.0625f; - - gl::begin(gl::Quads); - - glTexCoord2f(fcol, frow); - gl::vertex(x,y,0); - - glTexCoord2f(fcol + 0.0625f, frow); - gl::vertex(x+CHARSIZE,y,0); - - glTexCoord2f(fcol +0.0625f, frow + 0.0625f); - gl::vertex(x+CHARSIZE,y+CHARSIZE,0); - - glTexCoord2f(fcol, frow+0.0625f); - gl::vertex(x,y+CHARSIZE,0); - - gl::end(); - } - x += CHARSIZE; + draw_text(x, y, text[i]); + x += CHARWIDTH; } } diff --git a/src/render/text.h b/src/render/text.h index 19b2150..ac7d104 100644 --- a/src/render/text.h +++ b/src/render/text.h @@ -8,13 +8,24 @@ #define __INCLUDED_RENDER_TEXT_H__ #include +#include -#define CHARSIZE 16 +#define CHARWIDTH 16 +#define CHARHEIGHT 24 namespace render { + /// draw a character + void draw_text(float x, float y, const char ascii); /// draw a text string - void draw_text(float x, float y, std::string text); + void draw_text(float x, float y, const std::string & text); + /// draw a text string + void draw_text(float x, float y, const char *text); + /// draw a text stream + /** If the stream contains multiple lines, each new line will be + * drawn at the same x value. The stream is cleared after reading + */ + void draw_text(float x, float y, std::stringstream & textstream); } #endif //__INCLUDED_RENDER_TEXT_H__ diff --git a/src/server/application.cc b/src/server/application.cc index ee5f32f..8ea0808 100644 --- a/src/server/application.cc +++ b/src/server/application.cc @@ -19,10 +19,13 @@ void Application::init() // force initialization of the game object server::game = new game::Game(); + con_print << "Initializing server..." << std::endl; + // initialize core - core::ApplicationInterface::init(); + core::ApplicationInterface::init(); - con_debug << "Initializing server..." << std::endl; + // connect to the game module + core::ApplicationInterface::connect(); } void Application::run() @@ -37,7 +40,7 @@ void Application::run() frame(elapsed); - timer.sleep(server_framerate - elapsed); + sys::sleep(server_framerate - elapsed); timer.mark(); } diff --git a/src/server/timer.cc b/src/server/timer.cc index c184659..946da2c 100644 --- a/src/server/timer.cc +++ b/src/server/timer.cc @@ -25,7 +25,8 @@ void Timer::mark() } float Timer::elapsed() -{ timeval tick; +{ + timeval tick; gettimeofday(&tick, &timer_tz); @@ -34,9 +35,4 @@ float Timer::elapsed() return( (float) delta / 1000000); } -void Timer::sleep(float seconds) -{ - usleep((useconds_t) seconds * (useconds_t) 1000000.0 ); -} - } diff --git a/src/server/timer.h b/src/server/timer.h index a96fa0e..496d698 100644 --- a/src/server/timer.h +++ b/src/server/timer.h @@ -27,11 +27,6 @@ public: */ float elapsed(); - /// suspend calling process for a number of seconds - void sleep(float seconds); - - /// TODO add inspectors for current timestamp and last mark - private: float timer_elapsed; struct timezone timer_tz; diff --git a/src/sys/sys.cc b/src/sys/sys.cc index dc342bd..9957408 100644 --- a/src/sys/sys.cc +++ b/src/sys/sys.cc @@ -14,14 +14,18 @@ #else +#include #include +#include #include #include #endif #include -bool sys::mkdir(const char *path) +namespace sys { + +bool mkdir(const char *path) { #ifdef _WIN32 ::mkdir(path); @@ -32,7 +36,7 @@ bool sys::mkdir(const char *path) #endif } -void sys::signal(int signum, signalfunc handler) +void signal(int signum, signalfunc handler) { #ifndef _WIN32 struct sigaction sa; @@ -44,6 +48,27 @@ void sys::signal(int signum, signalfunc handler) #endif } -void sys::quit(int status) { - exit(status); +unsigned long time() +{ +#ifndef _WIN32 + struct ::tm localtime; + time_t epochtime = ::time(0); + ::localtime_r(&epochtime, &localtime); + return ((unsigned long) (localtime.tm_sec + localtime.tm_min*60 + localtime.tm_hour*3600)); +#else + retrun 0; +#endif +} + +void sleep(float seconds) +{ +#ifndef _WIN32 + ::usleep((useconds_t) seconds * (useconds_t) 1000000.0 ); +#endif +} + +void quit(int status) { + ::exit(status); +} + } diff --git a/src/sys/sys.h b/src/sys/sys.h index 86642e5..dec5ab9 100644 --- a/src/sys/sys.h +++ b/src/sys/sys.h @@ -9,18 +9,30 @@ #include "config.h" +/// maximum line size throught the game +#define MAXCMDSIZE 1024 + /// contains operating system dependent functions +/** sys is a core subsystem + */ namespace sys { typedef void (* signalfunc)(int signum); /// create a directory - bool mkdir(const char *path); + extern bool mkdir(const char *path); /// intercept OS signals - void signal(int signum, signalfunc handler); + extern void signal(int signum, signalfunc handler); /// quit /** @param status return value */ - void quit(int status); + extern void quit(int status); + + /// suspend process for a number of seconds + extern void sleep(float seconds); + + /// return the current system time of day, in seconds after midnight + extern unsigned long time(); + } #include "sys/consoleinterface.h" -- cgit v1.2.3