Logo Search packages:      
Sourcecode: race version File versions

season.cpp

/* Season loop:
 *  - track selector creates a season object and calls Season::start()
 *  - next_track() called until no_more_tracks or abandon_season() is true.
 *  - next track shows last_race_results
 *  - new season shows final results after the next_track() loop ends
 */

#include <ClanLib/core.h>
#include <ClanLib/display.h>
#include <ClanLib/gl.h>
#include <ClanLib/jpeg.h>
#include <ClanLib/gui.h>

#include "season.h"

#include "car.h"
#include "player.h"
#include "ai.h"
#include "game_data.h"
#include "draw_track.h"
#include "dust.h"
#include "start_pos.h"
#include "game_config.h"
#include "config.h"
#include "fonts.h"
#include "track.h"
#include "render_track.h"
#include "texture.h"
#include "info_gfx.h"
#include "track_sfx.h"
#include "menu_sfx.h"
#include "car_sfx.h"
#include "height_map.h"
#include "map.h"
#include "music.h"
#include "track_list_entry.h"
#include "debug.h"
#include "misc_utils.h"
#include "race_opengl.h"

#include "car_loader.h"
#include "theme_loader.h"

// menu
#include "menu/GUI/stylemanager_opengl.h"
#include "menu/pause_menu.h"
#include "menu/result_menu.h"

Season::Season()
{
      // init season
      GameData::track_num = 0;
      cars_inited = false;
}

Season::~Season()
{
      for( std::vector<Car*>::iterator it = GameData::cars.begin();
           it != GameData::cars.end();
           it++ )
      {
            delete *it;
            if( it == GameData::cars.end() )
                  break;
      }   
}

void Season::start()
{
      Config::abandon_season = false;

      ThemeLoader::load_theme(Config::selected_theme);
      CarLoader::load_cars();
      
      while( !season_ended() )
            next_track();
      
      Race_OpenGL::begin_2d();

      ResultMenu::show(true);

      cleanup();
}

void Season::cleanup()
{
      std::vector<Car*>::iterator it;

      for( it = GameData::cars.begin(); it != GameData::cars.end(); it++ )
      {
            delete *it;
            it = GameData::cars.erase(it);
            if( it == GameData::cars.end() )
                  break;
      }
      GameData::cars.clear();
}

void Season::next_track()
{
      if( Config::random_theme )
            ThemeLoader::load_random_theme();
      
      if( !load_next_track() )
      {
            RaceDebug::print("Season::next_track(): error loading track", 3);
            return;
      }
      
      setup_cars();
      
      place_cars_on_start_positions();
      
      race();
      
      ResultMenu::show();
      
      HeightMap::deinit();
}




bool Season::load_next_track()
{
      // set path of track to load
      CL_String path = "tracks/";   
      path += Config::selected_tracks[GameData::track_num];
            
      // load the map
      Track::load( path );
      
      // create the track texture
      RenderTrack::render();
      
      // load height map
      path += ".height.jpg";
      HeightMap::map_surface = CL_JPEGProvider::create( path, NULL );
      
      // create the 3d terrain
      HeightMap::init();
      
      GameData::track_num++;
      
      return true;
}




void Season::setup_cars()
{
      if( cars_inited )
      {
            reset_cars();
            return;
      }
      
      int id = 0, i=0;
      
      RaceDebug::print( "Season::setup_cars: create player(s)", 4 );
      
      while( i < Config::num_players )
      {
            RaceDebug::print( "Season::setup_cars: get start positions", 5 );
            
            short x = Track::track->start_positions[i].x;
            short y = Track::track->start_positions[i].y;
      
            if( x < 0 || x > 40 || y < 0 || y > 40 )
            {
                  cl_assert(false); // start pos not ok.
            }

            char player_num = i;
            
            RaceDebug::print( "Season::setup_cars: add player", 5 );
            GameData::cars.push_back( new Car_Player(x, y, id, player_num) );
            RaceDebug::print( "Season::setup_cars: add player -- done", 5 );
            
            i++; id++;
      }
      
      RaceDebug::print("Season::setup_cars: create player(s) -- done", 4);
      RaceDebug::print("Season::setup_cars: create ai", 4);
      
      int ai_id = 0;
      while( ai_id < Config::num_ai )
      {
            short x = Track::track->start_positions[i].x;
            short y = Track::track->start_positions[i].y;
            
            GameData::cars.push_back( new Car_AI(x, y, id, ai_id ));
            i++; id++; ai_id++;
      }
      
      cars_inited = true;
      
      RaceDebug::print("Season::setup_cars: create ai -- done", 4);
}





void Season::place_cars_on_start_positions()
{
      std::vector<Car*>::iterator it;
      
      for( it = GameData::cars.begin();
             it != GameData::cars.end();
             it++)
      {
            (*it)->set_pos( Track::track->start_positions[(*it)->next_race_start_pos].x,
                           Track::track->start_positions[(*it)->next_race_start_pos].y );
            (*it)->z = HeightMap::get_height_tile_coord((*it)->x, (*it)->y);
      }
}



bool Season::season_ended()
{
      unsigned char num_tracks = Config::selected_tracks.size();

      if( GameData::track_num >= 0 && GameData::track_num < num_tracks )
            return false;

      return true;
}




void Season::race()
{
      RaceDebug::print("Season::race()");
      
      int start_time = CL_System::get_time();
      long frames = 0;
      
      bool start = true;
//    abandon_season = false;
      
      float begin_time  = CL_System::get_time();
      float time_elapsed = 0;
      
      float turn_time  = CL_System::get_time();
      float lights_time = CL_System::get_time();
      
      int lights_y = 30;
      
      GameData::cars_in_goal = 0;
      Config::num_cars = Config::num_players + Config::num_ai;
      
      if(   Music::load_track((rand()%5)) )
            Music::play_track();
      
      RaceDebug::print("entering game loop...");
      
      // THE LOOOOOOP
      
      while ( GameData::cars_in_goal < Config::num_cars && !Config::abandon_season )
      {
            frames++;
            
            // misc opengl stuff...
            glEnable(GL_DEPTH_TEST);

            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
//          gluPerspective( 25.0f, (GLfloat)Config::screen_width/(GLfloat)Config::screen_height, 10.0f, 31.5f );
            gluPerspective( 42.0f, (GLfloat)Config::screen_width/(GLfloat)Config::screen_height, 3.0f, 23.5f );
            
            glMatrixMode(GL_MODELVIEW);
            glViewport( 0, 0, Config::screen_width, Config::screen_height );
            
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glLoadIdentity();             // Reset The View
            
            // UPDATE misc stuff that doesn't really fit anywhere else
            
            Music::update();
            CarSfx::update_ai_engine_frequency();
            
            
            RaceDebug::print("Season: calling DrawTrack::draw()", 1);
            DrawTrack::draw();

            if( start )
            {
                  {for(
                        std::vector<Car*>::iterator it = GameData::cars.begin();
                        it != GameData::cars.end();
                        it++)
                  {
                        if( (*it)->is_player() )
                        {
                              (*it)->camera.update((*it)->x,(*it)->y, (*it)->z );
                              (*it)->camera.look_at((*it)->x,(*it)->y, (*it)->z );
                        }
                        (*it)->show(0,0);
                  }}

                  int j = ((int)(CL_System::get_time() - lights_time)/1000);
                  if( j >= 0 && j < 3 )
                  {
                        Race_OpenGL::begin_2d();
                        InfoGfx::start_lights->put_screen( 500, 30, j );
                        Race_OpenGL::end_2d();
                  }
                  else
                  {
                        start = false;
                        begin_time = CL_System::get_time();
                        
                        if( Config::sfx_on == 0 )
                              TrackSfx::start->play();
                  }
            }
            
            if( start == false )
            {
                  // Scrolls out the lights 
                  if( lights_y + InfoGfx::start_lights->get_height() > 0 )
                  {
                        Race_OpenGL::begin_2d();
                        InfoGfx::start_lights->put_screen( 500, lights_y--, 3 );
                        Race_OpenGL::end_2d();
                  }
                  
                  time_elapsed  = (CL_System::get_time() - begin_time) /1000;
                  
                  if( time_elapsed > 0.01 ) // time_elapsed > 10 (max 100 fps)
                  {
                        begin_time = CL_System::get_time();
                        
                        RaceDebug::print("Season::race: turn", 1 );

                        if( (CL_System::get_time() - turn_time ) > 50 ) // limit turning speed
                        {
                              {for(
                                    std::vector<Car*>::iterator it = GameData::cars.begin();
                                    it != GameData::cars.end();
                                    it++)
                                    {
                                          (*it)->turn();
                                    }
                              }
                              turn_time = CL_System::get_time(); 
                        }
                        
                        RaceDebug::print("update",1);
                        
                        {for(
                              std::vector<Car*>::iterator it = GameData::cars.begin();
                              it != GameData::cars.end();
                              it++)
                            {
                                    (*it)->update( time_elapsed );
                            }
                        }
                        
                        {for(
                              std::vector<Dust>::iterator it = GameData::dust_list.begin();
                              it != GameData::dust_list.end();
                              it++)
                        {
                              (*it).update( time_elapsed );
                              if((CL_System::get_time() - (*it).get_life_time()) > 300 )
                              {
                                    it = GameData::dust_list.erase(it);
                                    if( it == GameData::dust_list.end() )
                                          break;
                              }
                        }}

                        {for(std::vector<Car*>::iterator it = GameData::cars.begin();
                              it != GameData::cars.end();
                              it++)
                        {
//                            if((*it)->hit_check()) ;
                              (*it)->hit_check();
                        }}
                  
                        RaceDebug::print("move",1);

                        {for(std::vector<Car*>::iterator it = GameData::cars.begin();
                              it != GameData::cars.end();
                              it++)
                        {
                              (*it)->move();
                        }}
                        
                  }
            }
            
            // check if esc pressed. Also works as pause
            // TODO: screws up fps counting
            if( CL_Keyboard::get_keycode(CL_KEY_ESCAPE) )
            {
                  Race_OpenGL::begin_2d(); // I donno why this has to be called twice... 
                  Race_OpenGL::begin_2d(); // But it has to, so don't delete this line

                  CL_String grpath = DATADIR;
                  grpath += "resources/gui.res";
                  CL_ResourceManager *resources = new CL_ResourceManager(grpath, false);
                  CL_StyleManager_OpenGL styles(resources);
                  
                  PauseMenu pause( NULL, &styles );
                  pause.run();

                  Race_OpenGL::end_2d();
                  Race_OpenGL::end_2d();

                  begin_time = CL_System::get_time();
            }
            
            CL_Display::flip_display();
            CL_System::keep_alive();
      }
      // game loop ends.

      // stop playing engine sounds
      {for(std::vector<Car*>::iterator it = GameData::cars.begin();
            it != GameData::cars.end();
            it++)
      {
            (*it)->sound_controller.stop();
      }}
      
      std::cout << "frames per second: " << MiscUtils::get_fps( start_time, frames ) << std::endl;
      
      // delete track texture from card memory...
      Track::road_texture->erase();
      
      CL_System::keep_alive();
}


void Season::reset_cars()
{
      std::vector<Car*>::iterator it;

      for( it = GameData::cars.begin();
            it != GameData::cars.end();
            it++ )
      {
            (*it)->reset();
      }
}

Generated by  Doxygen 1.6.0   Back to index