Logo Search packages:      
Sourcecode: vdrift version File versions

gui.cpp

/* gui.cpp */

#include <iostream>
#include <iterator>
#include <stdio.h>
#include "vamosworld.h"
#include "controls.h"
#include "mouse.h"
#include "utility.h"
#include "gui/widget.h"
#include "gui/page.h"
#include "gui/gui.h"
#include "gui/button.h"
#include "gui/calibrate.h"
#include "gui/controlgrab.h"
#include "gui/image.h"
#include "gui/label.h"
#include "gui/multi_image.h"
#include "gui/slider.h"
#include "gui/spinning_car.h"
#include "gui/textbox.h"
#include "gui/toggle.h"
#include "gui/wheel.h"

using namespace VGUI;

extern void Quit( int returnCode );
extern void MainPause();
extern void MainUnpause();
extern void ReloadDisplay();
extern void ResetWorld( bool fullreset );
extern bool LoadWorld();
extern bool UnloadWorld();
extern bool verbose_output;


Gui::Gui()
{
      menu_path = settings.GetSkinPath() + "/menus";
      loaded = false;
}

Gui::Gui( string path )
{
      menu_path = path;
      loaded = false;
}

Gui::~Gui()
{
}

void Gui::Init()
{
      bool was_loaded = false;
      if( loaded )
      {
            DeInit();
            was_loaded = true;
      }

      string filename_path = settings.GetDataDir() + "/" + menu_path + "/menus";
      string name;
      ifstream f;

      if( verbose_output ) cout << "menu_path: " << menu_path << endl;
      if( verbose_output ) cout << "filename_path: " << filename_path << endl;

      // open the list of menus to load from data file menu_path/menus
      f.open( filename_path.c_str() );
      if( !f )
      {
            cout << "Could not open menu at: " << filename_path << endl;
      }

      // read each line of the menus list and make a new page with the menu filename read
      name = utility.sGetLine( f );
      while( name != ENDOFFILESTRING )
      {
            pages[name] = new Page( settings.GetFullDataPath( menu_path + "/" + name ) );
            name = utility.sGetLine( f );
      }

      // close the menus list
      f.close();

      menu_enabled = true;
      if( !was_loaded ) cur_page = "Main";

      // get screen size
      settings.Get( "display.width", screen_width );
      settings.Get( "display.height", screen_height );

      // figure out dimensions of pointer in percentage of screen
      ptr_w = 0.0555;
      ptr_h = 0.0740;

      // load mouse pointer graphic
      mouse_pointer.Load( settings.GetSkinPath() + "/textures/mouse.png", false );
      is_locked = l=m=r=u=d=joy_l=joy_r=joy_u=joy_d=key_down=cancel_down = false;

      loaded = true;
      if( !settings.Get( "joystick.calibrated", calibrated ) )
      {
            calibrated = false;
            settings.Set( "joystick.calibrated", calibrated );
      }
}

void Gui::ReInit()
{
      if( !loaded )
            return;

      Init();
      menu_enabled = true;
}

void Gui::DeInit()
{
      string filename_path = settings.GetFullDataPath( menu_path + "/menus" );
      string name;
      ifstream f;

      if( verbose_output ) cout << "menu_path: " << menu_path << endl;
      if( verbose_output ) cout << "filename_path: " << filename_path << endl;

      // open the list of menus to load from data file menu_path/menus
      f.open( filename_path.c_str() );
      if( !f )
      {
            cout << "Could not open menu at filename_path." << endl;
      }

      // read each line of the menus list and delete the page with the menu filename read
      name = utility.sGetLine( f );
      while( name != ENDOFFILESTRING )
      {
            delete pages[name];
            name = utility.sGetLine( f );
      }

      pages.clear();

      // close the menus list
      f.close();

      menu_enabled = false;

      loaded = false;
}

void Gui::UpdateScreenSize()
{
      // get screen size
      settings.Get( "display.width", screen_width );
      settings.Get( "display.height", screen_height );
}

void Gui::Draw()
{
      float x, y;
      float last_page_opacity = 0.0;
      float this_page_opacity = 1.0;

      /*glPushMatrix();
      glPushAttrib( GL_ALL_ATTRIB_BITS );*/
      
      glDisable(GL_LIGHTING);
      
      // is the menu on right now?
      if( !menu_enabled )
            return;

      MouseUpdate();

      // convert mouse position to screen percentage
      x = (float)mouse_x / (float)screen_width;
      y = (float)mouse_y / (float)screen_height;

      // update selection from mouse movements
      if( !is_locked )
            pages[cur_page]->MouseSelect( x, y );

      if( last_page != "" )
      {
            float elapsed_switch_time = (float)( SDL_GetTicks() - page_switch_time ) / 1000.0;
            if( elapsed_switch_time <= 0.3 )
            {
                  // this will crossfade the menus in 3 tenths of a second
                  this_page_opacity = ( elapsed_switch_time / 0.3 );
                  last_page_opacity = 1.0 - this_page_opacity;
                  pages[last_page]->Draw( last_page_opacity );
            }
            else
            {
                  last_page = "";
            }
      }

      // draw the current page
      pages[cur_page]->Draw( this_page_opacity );

      // draw the mouse pointer
      if( is_locked == false )
            utility.Draw2D( x, y, x + ptr_w, y + ptr_h, &mouse_pointer, 0.0, 64, 1.0 );
      
      /*glPopAttrib();
      glMatrixMode( GL_MODELVIEW );
      glPopMatrix();*/
}

void Gui::KeyPress( SDLKey key )
{

      // is the menu on right now?
      if( !menu_enabled )
            return;

      if( is_locked == true )
      {
            pages[cur_page]->ControlGrabKey( key );
            is_locked = false;
      }
      else
      {
            if( key == SDLK_UP )
            {
                  pages[cur_page]->UpWidget();
            }
            else if( key == SDLK_DOWN )
            {
                  pages[cur_page]->DownWidget();
            }
            else if( key == SDLK_LEFT )
            {
                  pages[cur_page]->LeftWidgetPress();
            }
            else if( key == SDLK_RIGHT )
            {
                  pages[cur_page]->RightWidgetPress();
            }
            else if( key == SDLK_BACKSPACE )
            {
                  pages[cur_page]->BackspacePress();
            }
            else if( key == SDLK_DELETE )
            {
                  pages[cur_page]->DeletePress();
            }
            else if( ( key == SDLK_RETURN ) ||
                         ( key == SDLK_SPACE ) )
            {
                  pages[cur_page]->KeyPress();
            }
            else if( key == SDLK_ESCAPE )
            {
                  pages[cur_page]->CancelPress();
            }
            else
            {
                  pages[cur_page]->Type( key );
            }
      }
}

void Gui::KeyRelease( SDLKey key )
{
      string action = "";

      // is the menu on right now?
      if( !menu_enabled )
            return;

      if( is_locked == true )
            return;

      if( ( key == SDLK_RETURN ) ||
          ( key == SDLK_SPACE ) )
      {
            action = pages[cur_page]->KeyRelease();
      }
      else if( key == SDLK_ESCAPE )
      {
            action = pages[cur_page]->CancelRelease();
      }
      else if( key == SDLK_LEFT )
      {
            pages[cur_page]->LeftWidgetRelease();
      }
      else if( key == SDLK_RIGHT )
      {
            pages[cur_page]->RightWidgetRelease();
      }
      else if( key == SDLK_BACKSPACE )
      {
            pages[cur_page]->BackspaceRelease();
      }
      else if( key == SDLK_DELETE )
      {
            pages[cur_page]->DeleteRelease();
      }

      ProcessAction( action );
}

void Gui::MousePress()
{
      float x, y;

      // is the menu on right now?
      if( !menu_enabled )
            return;

      // get mouse buttons status
      mouse.GetMouseButtons( l, m, r, u, d );
      // get mouse position 
      mouse.GetMousePos( mouse_x, mouse_y );
      // convert to screen percentage
      x = (float)mouse_x / (float)screen_width;
      y = (float)mouse_y / (float)screen_height;

      if( is_locked == true )
      {
            int button_idx = 0;
            for( int i = 1; i <= 10; i++ )
            {
                  if( mouse.IsPressed( i ) )
                  {
                        button_idx = i;
                        break;
                  }
            }
            if( button_idx == 0 )
            {
                  cout << "Couldn't add button 0!" << endl;
            }
            else
            {
                  pages[cur_page]->ControlGrabMouseButton( button_idx );
            }
            is_locked = false;
      }
      else
      {
            // update selection from mouse movements
            pages[cur_page]->MouseSelect( x, y );

            if( l && pages[cur_page]->MouseOver( x, y ) )
            {
                  pages[cur_page]->MousePressWidget( x, y );
            }
      }
}

void Gui::MouseRelease()
{
      string action = "";
      float x, y;

      // is the menu on right now?
      if( !menu_enabled )
            return;

      if( is_locked == true )
            return;

      // get mouse position 
      mouse.GetMousePos( mouse_x, mouse_y );
      // convert to screen percentage
      x = (float)mouse_x / (float)screen_width;
      y = (float)mouse_y / (float)screen_height;

      // update selection from mouse movements
      pages[cur_page]->MouseSelect( x, y );

      if( l )
      {
            action = pages[cur_page]->MouseReleaseWidget( x, y );
            ProcessAction( action );
      }

      // get mouse buttons status
      mouse.GetMouseButtons( l, m, r, u, d );
}

void Gui::MouseUpdate()
{
      // get mouse position 
      mouse.GetMousePos( mouse_x, mouse_y );

      if( is_locked == true )
      {
            float mouse_cur_x = mouse_x / (float)screen_width;
            float mouse_cur_y = mouse_y / (float)screen_height;
            float lock_x = mouse_lock_x / (float)screen_width;
            float lock_y = mouse_lock_y / (float)screen_height;
            float moved_x = mouse_cur_x - lock_x;
            float moved_y = mouse_cur_y - lock_y;
            float distance_x = moved_x > 0 ? moved_x : -moved_x;
            float distance_y = moved_y > 0 ? moved_y : -moved_y;

            // in which direction is there greater movement?
            if( distance_x > distance_y )
            {
                  // see if distance is greater than threshold (about 100 pixels at 1280x1024)
                  if( distance_x > 0.078 )
                  {
                        if( moved_x < 0 )
                        {
                              pages[cur_page]->ControlGrabMouseMove( "left" );
                        }
                        else
                        {
                              pages[cur_page]->ControlGrabMouseMove( "right" );
                        }
                        is_locked = false;
                  }
            }
            else if( distance_y > distance_x )
            {
                  if( distance_y > 0.097 )
                  {
                        if( moved_y < 0 )
                        {
                              pages[cur_page]->ControlGrabMouseMove( "up" );
                        }
                        else
                        {
                              pages[cur_page]->ControlGrabMouseMove( "down" );
                        }
                        is_locked = false;
                  }
            }
      }
}

void Gui::MouseReturn()
{
      SDL_WarpMouse( mouse_x, mouse_y );
}

void Gui::JoyPress( Uint8 joy_idx, Uint8 joy_btn )
{
      if( !menu_enabled )
            return;

      if( !calibrated )
            return;

      if( is_locked == true )
      {
            pages[cur_page]->ControlGrabJoyButton( joy_idx, joy_btn );
            is_locked = false;
            return;
      }

      // for now, we're going to assume that buttons 0,1,2 are "OK" buttons and 3,4,5 are "Cancel" buttons.

      switch( joy_btn % 2 )
      {
      case 0:
            key_down = true;
            pages[cur_page]->KeyPress();
            break;
      case 1:
            cancel_down = true;
            pages[cur_page]->CancelPress();
            break;
      }
}

void Gui::JoyRelease( Uint8 joy_idx, Uint8 joy_btn )
{
      if( !menu_enabled )
            return;

      if( !calibrated )
            return;

      if( is_locked == true )
            return;

      // for now, we're going to assume that buttons 0,1,2 are "OK" buttons and 3,4,5 are "Cancel" buttons.

      string action = "";

      switch( joy_btn % 2 )
      {
      case 0:
            if( key_down )
            {
                  action = pages[cur_page]->KeyRelease();
                  key_down = false;
            }
            break;
      case 1:
            if( cancel_down )
            {
                  action = pages[cur_page]->CancelRelease();
                  cancel_down = false;
            }
            break;
      }

      ProcessAction( action );
}

void Gui::JoyMove( Uint8 joy_idx, Uint8 joy_axis, float val )
{
      if( !menu_enabled )
            return;

      if( ( cur_page == "JoystickCalibrate" ) || ( cur_page == "InGameJoystickCalibrate" ) )
      {
            calibrated = false;
            pages[cur_page]->ControlGrabJoyMove( joy_idx, joy_axis, joy_positive, val );
      }

      if( !calibrated )
            return;

      joy_axis_value = val;
      last_axis = joy_axis;
      last_joy = joy_idx;

      if( is_locked == true )
      {
            if( joy_axis_value < -0.2 )
            {
                  joy_press_time = SDL_GetTicks();
                  joy_positive = false;
            }
            else if( joy_axis_value > 0.2 )
            {
                  joy_press_time = SDL_GetTicks();
                  joy_positive = true;
            }
      }

      // for now, we're going to assume that axis 0 is left(-)/right(+) motion and axis 1 is up(-)/down(+).

      switch( last_axis % 2 )
      {
      case 0:
            if( !joy_l && ( joy_axis_value < -0.2 ) )
            {
                  joy_press_time = SDL_GetTicks();
                  joy_l = true;
                  if( !is_locked ) pages[cur_page]->LeftWidgetPress();
            }
            else if( !joy_r && ( joy_axis_value > 0.2 ) )
            {
                  joy_press_time = SDL_GetTicks();
                  joy_r = true;
                  if( !is_locked ) pages[cur_page]->RightWidgetPress();
            }
            break;
      case 1:
            if( !joy_u && ( joy_axis_value < -0.2 ) )
            {
                  joy_press_time = SDL_GetTicks();
                  joy_u = true;
                  if( !is_locked ) pages[cur_page]->UpWidget();
            }
            else if( !joy_d && ( joy_axis_value > 0.2 ) )
            {
                  joy_press_time = SDL_GetTicks();
                  joy_d = true;
                  if( !is_locked ) pages[cur_page]->DownWidget();
            }
            break;
      }
}

void Gui::JoyUpdate()
{
      if( !calibrated )
            return;

      Uint32 time_since_joy_press = SDL_GetTicks() - joy_press_time;
      float sec_since_move = (float)( (float)time_since_joy_press / 1000.0 );

      // time delay for joystick axis movements is 3 tenths of a second
      if( sec_since_move >= 0.3 )
      {
            if( ( is_locked == true ) && ( joy_u || joy_d || joy_l || joy_r ) )
            {
                  pages[cur_page]->ControlGrabJoyMove( last_joy, last_axis, joy_positive, joy_axis_value );
                  is_locked = joy_u = joy_d = joy_l = joy_r = false;
                  return;
            }

            if( joy_u )
            {
                  joy_u = false;
            }

            if( joy_d )
            {
                  joy_d = false;
            }

            if( joy_l )
            {
                  pages[cur_page]->LeftWidgetRelease();
                  joy_l = false;
            }

            if( joy_r )
            {
                  pages[cur_page]->RightWidgetRelease();
                  joy_r = false;
            }
      }
}

void Gui::ProcessAction( string action )
{
      if( action == "" )
      {
            return;
      }
      else if( action == "Quit" )
      {
            Quit(0);
      }
      else if( action == "Lock" )
      {
            // get the mouse position
            mouse_lock_x = mouse_x;
            mouse_lock_y = mouse_y;
            is_locked = true;
      }
      else if( action == "Unlock" )
      {
            is_locked = false;
      }
      else if( action == "ReloadDisplay" )
      {
            ReloadDisplay();

            if( cur_page == "DisplayOptions" )
                  ChangePage( "Options" );
            else if( cur_page == "InGameDisplayOptions" )
                  ChangePage( "InGameOptions" );
      }
      else if( action == "UpdateMouse" )
      {
            mouse.UpdateSettings();

            if( cur_page == "MouseOptions" )
                  ChangePage( "ControlsOptions" );
            else if( cur_page == "InGameMouseOptions" )
                  ChangePage( "InGameControlsOptions" );
      }
      else if( action == "UpdateJoystick" )
      {
            gamecontrols.UpdateSettings();

            if( cur_page == "JoystickOptions" )
                  ChangePage( "ControlsOptions" );
            else if( cur_page == "InGameJoystickOptions" )
                  ChangePage( "InGameControlsOptions" );
      }
      else if( action == "UpdateCalibrations" )
      {
            calibrated = true;
            settings.Set( "joystick.calibrated", calibrated );

            if( cur_page == "JoystickCalibrate" )
                  ChangePage( "JoystickOptions" );
            else if( cur_page == "InGameJoystickCalibrate" )
                  ChangePage( "InGameJoystickOptions" );
      }
      else if( action == "UpdateControls" )
      {
            gamecontrols.UpdateSettings();
            world.UpdateSettings();

            if( cur_page == "ControlsOptions" )
                  ChangePage( "Options" );
            else if( cur_page == "InGameControlsOptions" )
                  ChangePage( "InGameOptions" );
      }
      else if( action == "UpdateSound" )
      {
            sound.UpdateSettings();
            world.UpdateSettings();

            if( cur_page == "SoundOptions" )
                  ChangePage( "Options" );
            else if( cur_page == "InGameSoundOptions" )
                  ChangePage( "InGameOptions" );
      }
      else if( action == "Pause" )
      {
            ChangePage( "InGameMenu" );
            last_page = "";
            //SDL_WarpMouse( 0, 0 );
            pages[cur_page]->SelectDefault();
            //SDL_WarpMouse( 0, 0 );
            menu_enabled = true;
      }
      else if( action == "StartPracticeGame" )
      {
            pages[cur_page]->SelectDefault();
            LoadWorld();
            state.SetGameState( STATE_PLAYING );
            menu_enabled = false;
            pages[cur_page]->StartGame();
            bool record_replay = false;
            if( settings.Get( "game.record", record_replay ) )
            {
                  if( record_replay )
                  {
                        replay.Start();
                  }
            }
            else
            {
                  settings.Set( "game.record", false );
            }
      }
      else if( action == "StartNetworkGame" )
      {
            pages[cur_page]->SelectDefault();
            state.SetGameMode( MODE_NETMULTIFREE );
            pages[cur_page]->StartGame();

            bool net_host, net_success;
            string net_ip;
            settings.Get( "network.host_game", net_host );
            settings.Get( "network.server_ip", net_ip );

            multiplay.Disconnect();
            
            if( !net_host )
            {
                  net_success = multiplay.Connect( net_ip );
            }
            else
            {
                  net_success = multiplay.Host();
                  LoadWorld();
            }

            if( net_success )
            {
                  menu_enabled = false;
                  state.SetGameState( STATE_PLAYING );
            }
            else
            {
                  ChangePage( "ConnectionError" );
            }
      }
      else if( action == "StartReplay" )
      {
            pages[cur_page]->SelectDefault();
            menu_enabled = false;
            if( !replay.PlayStart("1") )
            {
                  ChangePage( "ReplayStartError" );
                  menu_enabled = true;
            }
      }
      else if( action == "ReturnToGame" )
      {
            pages[cur_page]->SelectDefault();
            menu_enabled = false;
            MainUnpause();
      }
      else if( action == "RestartGame" )
      {
            pages[cur_page]->SelectDefault();
            menu_enabled = false;
            MainUnpause();
            ResetWorld( true );
      }
      else if( action == "LeaveGame" )
      {
            //pages[cur_page]->SelectDefault();
            //menu_enabled = false;
            replay.Stop();
            replay.PlayStop();
            MainUnpause();
            UnloadWorld();
            state.SetGameState( STATE_INITIALMENU );
            ChangePage( "Main" );
            //ResetWorld( true );
      }
      else
      {
            pages[cur_page]->SelectDefault();
            // go to a menu
            ChangePage( action );
      }
}

void Gui::ChangePage( string page_name )
{
      page_switch_time = SDL_GetTicks();
      last_page = cur_page;
      cur_page = page_name;
      pages[cur_page]->ClearSettings();
}

Generated by  Doxygen 1.6.0   Back to index