src/interface/mouse.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Mouse management
00020  *****************************************************************************/
00021 
00022 #include "mouse.h"
00023 
00024 #include "cursor.h"
00025 #include "interface.h"
00026 #include "../game/game_mode.h"
00027 #include "../game/game_loop.h"
00028 #include "../game/time.h"
00029 #include "../graphic/video.h"
00030 #include "../include/app.h"
00031 #include "../include/action_handler.h"
00032 #include "../map/camera.h"
00033 #include "../map/map.h"
00034 #include "../team/macro.h"
00035 #include "../tool/point.h"
00036 #include "../weapon/weapon.h"
00037 
00038 // mouse scroll speed
00039 const uint SCROLL_MOUSE = 20;
00040 
00041 // size of the sensitive area use to scroll the map with mouse
00042 const uint SENSIT_SCROLL_MOUSE = 40;
00043 
00044 Mouse * Mouse::singleton = NULL;
00045 
00046 Mouse * Mouse::GetInstance() {
00047   if (singleton == NULL) {
00048     singleton = new Mouse();
00049   }
00050   return singleton;
00051 }
00052 
00053 Mouse::Mouse(){
00054   scroll_actif = false;
00055   hide = false;
00056   // Load the different pointers
00057   Profile *res = resource_manager.LoadXMLProfile("graphism.xml", false);
00058   pointer_select = resource_manager.LoadImage(res, "mouse/pointer_select");
00059   pointer_move = resource_manager.LoadImage(res, "mouse/pointer_move");
00060   pointer_aim = resource_manager.LoadImage(res, "mouse/pointer_aim");
00061   //resource_manager.UnLoadXMLProfile( res);
00062   current_pointer = POINTER_STANDARD;
00063   delete res;
00064 }
00065 
00066 void Mouse::Reset(){
00067 }
00068 
00069 bool Mouse::ActionClicD(){
00070   if( ActiveTeam().GetWeapon().CanChangeWeapon() )
00071     Interface::GetInstance()->weapons_menu.SwitchDisplay();
00072 
00073   return true;
00074 }
00075 
00076 //WORKING=============================================
00077 bool Mouse::ActionWhellUp(){
00078   if (GameLoop::GetInstance()->ReadState() == GameLoop::PLAYING) {
00079     ActiveTeam().AccessWeapon().ActionUp();
00080     return true ;
00081     }
00082 
00083   return true;
00084 }
00085 
00086 bool Mouse::ActionWhellDown(){
00087   if (GameLoop::GetInstance()->ReadState() == GameLoop::PLAYING) {
00088     ActiveTeam().AccessWeapon().ActionDown();
00089     return true ;
00090     }
00091 
00092   return true;
00093 }
00094 //==========================================================
00095 
00096 bool Mouse::ActionClicG()
00097 {
00098   if(!ActiveTeam().IsLocal())
00099     return false;
00100 
00101   const Point2i pos_monde = GetWorldPosition();
00102 
00103   // Action dans le menu des armes ?
00104   if( Interface::GetInstance()->weapons_menu.ActionClic( GetPosition() ) )
00105     return true;
00106 
00107   // On peut changer de ver ?
00108   //Change character by mouse click only if the choosen weapon allows it
00109   if( GameMode::GetInstance()->AllowCharacterSelection() && ActiveTeam().GetWeapon().mouse_character_selection){
00110 
00111     // S�ection d'un ver se son �uipe ?
00112     bool ver_choisi=false;
00113     Team::iterator it=ActiveTeam().begin(),
00114                          fin=ActiveTeam().end();
00115 
00116     for( ; it != fin; ++it) {
00117       if( &(*it) != &ActiveCharacter()
00118         && !it -> IsDead()
00119         && it->GetRect().Contains( pos_monde ) ){
00120 
00121         ver_choisi = true;
00122         break;
00123       }
00124     }
00125 
00126     if( ver_choisi ){
00127       while ( &(*it) != &ActiveCharacter() )
00128         ActiveTeam().NextCharacter ();
00129       return true;
00130     }
00131 
00132     if( ActiveCharacter().GetRect().Contains( pos_monde ) ){
00133       CharacterCursor::GetInstance()->FollowActiveCharacter();
00134       return true;
00135     }
00136   }
00137 
00138 /*  // Action dans le menu des armes ?
00139   if( Interface::GetInstance()->weapons_menu.ActionClic(GetPosition()) )
00140     return true; */
00141 
00142   // Choosing target for a weapon, many posibilities :
00143   // - Do nothing
00144   // - Choose a target but don't fire
00145   // - Choose a target and fire it !
00146   if (GameLoop::GetInstance()->ReadState() == GameLoop::PLAYING) {
00147     Action* a = new Action(Action::ACTION_SET_TARGET);
00148     a->Push(GetWorldPosition().x);
00149     a->Push(GetWorldPosition().y);
00150     ActionHandler::GetInstance()->NewAction (a);
00151     return true ;
00152   }
00153 
00154   return false;
00155 }
00156 
00157 void Mouse::ChoixVerPointe(){
00158   if (GameLoop::GetInstance()->ReadState() != GameLoop::PLAYING)
00159     return;
00160 
00161   const Point2i pos_monde = GetWorldPosition();
00162 
00163   // Quel ver est point�par la souris ? (en dehors du ver actif)
00164   Interface::GetInstance()->character_under_cursor = NULL;
00165   FOR_ALL_LIVING_CHARACTERS(equipe,ver){
00166     if ((&(*ver) != &ActiveCharacter())
00167        && ver->GetRect().Contains(pos_monde) ){
00168       Interface::GetInstance()->character_under_cursor = &(*ver);
00169     }
00170   }
00171 
00172   // Aucun ver n'est point�... et le ver actif alors ?
00173   if ((Interface::GetInstance()->character_under_cursor == NULL)
00174       && ActiveCharacter().GetRect().Contains( pos_monde)){
00175       Interface::GetInstance()->character_under_cursor = &ActiveCharacter();
00176   }
00177 
00178   // Dessine le curseur autour du ver point�s'il y en a un
00179 //  if (interface.character_under_cursor != NULL) {
00180 //    curseur_ver.PointeObj (interface.character_under_cursor);
00181 //  } else {
00182 //    curseur_ver.PointeAucunObj();
00183 //  }
00184 }
00185 
00186 void Mouse::ScrollCamera() {
00187   bool scroll = false;
00188 
00189   Point2i mousePos = GetPosition();
00190   Point2i winSize = AppWormux::GetInstance()->video.window.GetSize();
00191   Point2i tstVector;
00192   // If application is fullscreen, mouse is only sensitive when touching the border screen
00193   int coef = (AppWormux::GetInstance()->video.IsFullScreen() ? 10 : 1);
00194   Point2i sensitZone(SENSIT_SCROLL_MOUSE / coef, SENSIT_SCROLL_MOUSE / coef);
00195 
00196   tstVector = mousePos.inf(sensitZone);
00197   if( !tstVector.IsNull() ){
00198     camera.SetXY( tstVector * (mousePos - (sensitZone * coef))/2 );
00199     camera.SetAutoCrop(false);
00200     scroll = true;
00201   }
00202 
00203   tstVector = winSize.inf(mousePos + sensitZone);
00204   if( !tstVector.IsNull() ){
00205     camera.SetXY( tstVector * (mousePos + (sensitZone * coef) - winSize)/2 );
00206     camera.SetAutoCrop(false);
00207     scroll = true;
00208   }
00209 
00210 }
00211 
00212 void Mouse::TestCamera(){
00213   Point2i mousePos = GetPosition();
00214   int x,y;
00215   //Move camera with mouse holding Ctrl key down or with middle button of mouse
00216   const bool demande_scroll = SDL_GetModState() & KMOD_CTRL |
00217                               SDL_GetMouseState(&x, &y) & SDL_BUTTON(SDL_BUTTON_MIDDLE);
00218 
00219   // Show cursor and information interface when moving mouse
00220   if(lastPos != mousePos) {
00221     Show();
00222     Interface::GetInstance()->Show();
00223     lastPos = mousePos;
00224   }
00225 
00226   if( demande_scroll ){
00227     if( scroll_actif ){
00228       Point2i offset = savedPos - mousePos;
00229       camera.SetXY(offset);
00230       camera.SetAutoCrop(false);
00231     }else{
00232       scroll_actif = true;
00233     }
00234     savedPos = mousePos;
00235     return;
00236   }else{
00237     scroll_actif = false;
00238   }
00239 
00240   if(!Interface::GetInstance()->weapons_menu.IsDisplayed() &&
00241      Config::GetInstance()->GetScrollOnBorder())
00242     ScrollCamera();
00243 }
00244 
00245 void Mouse::Refresh(){
00246   if (!scroll_actif)
00247     ChoixVerPointe();
00248 }
00249 
00250 Point2i Mouse::GetPosition() const{
00251         int x, y;
00252 
00253         SDL_GetMouseState( &x, &y);
00254         return Point2i(x, y);
00255 }
00256 
00257 Point2i Mouse::GetWorldPosition() const{
00258    return GetPosition() + camera.GetPosition();
00259 }
00260 
00261 void Mouse::TraiteClic (const SDL_Event *event){
00262   if( event->type == SDL_MOUSEBUTTONDOWN ){
00263 
00264     if( event->button.button == SDL_BUTTON_RIGHT ){
00265       ActionClicD();
00266       return;
00267     }
00268 
00269     // Clic gauche de la souris ?
00270     if( event->button.button == SDL_BUTTON_LEFT ){
00271       ActionClicG();
00272       return;
00273     }
00274 
00275 
00276     if (event->button.button == SDL_BUTTON_WHEELDOWN){
00277       ActionWhellDown();
00278       return;
00279     }
00280 
00281     if (event->button.button == SDL_BUTTON_WHEELUP){
00282       ActionWhellUp();
00283       return;
00284     }
00285 
00286   }
00287 }
00288 
00289 // set the new pointer type and return the previous one
00290 Mouse::pointer_t Mouse::SetPointer(pointer_t pointer)
00291 {
00292   if (Config::GetInstance()->GetDefaultMouseCursor()) return current_pointer;
00293 
00294   if (current_pointer == pointer) return current_pointer;
00295 
00296   if (pointer == POINTER_STANDARD) SDL_ShowCursor(true);
00297   else SDL_ShowCursor(false);
00298 
00299   pointer_t old_pointer = current_pointer;  
00300   current_pointer = pointer;
00301   
00302   return old_pointer;
00303 }
00304 
00305 void Mouse::Show()
00306 {
00307   hide = false;
00308 }
00309 
00310 void Mouse::Hide()
00311 {
00312   hide = true;
00313 }
00314 
00315 bool Mouse::IsVisible() const
00316 {
00317   return !hide;
00318 }
00319 
00320 bool Mouse::ScrollPointer()
00321 {
00322   if (!Config::GetInstance()->GetScrollOnBorder() ||
00323       Interface::GetInstance()->weapons_menu.IsDisplayed())
00324     return false;
00325 
00326   Point2i mousePos = GetPosition();
00327   Point2i winSize = AppWormux::GetInstance()->video.window.GetSize();
00328   Point2i cameraPos = camera.GetPosition();
00329 
00330   // tries to go on the left
00331   if ( (mousePos.x > 0 && mousePos.x < (int)SENSIT_SCROLL_MOUSE)
00332        && (cameraPos.x > 0) )
00333       return true;
00334 
00335   // tries to go on the right
00336   if ( (mousePos.x > winSize.x - (int)SENSIT_SCROLL_MOUSE)
00337        && ( cameraPos.x + winSize.x < world.GetWidth() ))
00338       return true;
00339 
00340   // tries to go up
00341   if ( (mousePos.y > 0 && mousePos.y < (int)SENSIT_SCROLL_MOUSE)
00342        && (cameraPos.y > 0) )
00343       return true;
00344 
00345   // tries to go down
00346   if ( (mousePos.y > winSize.y - (int)SENSIT_SCROLL_MOUSE)
00347        && (cameraPos.y + winSize.y < world.GetHeight()) )
00348     return true;
00349 
00350 
00351   return false;
00352 }
00353 
00354 bool Mouse::DrawMovePointer()
00355 {
00356   if (ScrollPointer() || scroll_actif) {
00357     AppWormux::GetInstance()->video.window.Blit( pointer_move, GetPosition() );
00358     world.ToRedrawOnScreen(Rectanglei(GetPosition().x, GetPosition().y , pointer_move.GetWidth(), pointer_move.GetHeight()));
00359     return true;
00360   }
00361   return false;
00362 }
00363 
00364 void Mouse::Draw()
00365 {
00366   if (current_pointer == POINTER_STANDARD || !IsVisible())
00367     return; // use standard SDL cursor
00368 
00369   if ( DrawMovePointer() )
00370     return;
00371 
00372   switch (current_pointer)
00373     {
00374     case POINTER_SELECT:
00375       AppWormux::GetInstance()->video.window.Blit( pointer_select, GetPosition() );
00376       world.ToRedrawOnScreen(Rectanglei(GetPosition().x, GetPosition().y , pointer_select.GetWidth(), pointer_select.GetHeight()));
00377       break;
00378     case POINTER_MOVE:
00379       AppWormux::GetInstance()->video.window.Blit( pointer_move, GetPosition() );
00380       world.ToRedrawOnScreen(Rectanglei(GetPosition().x, GetPosition().y , pointer_move.GetWidth(), pointer_move.GetHeight()));
00381       break;
00382     case POINTER_AIM:
00383       if(ActiveTeam().IsLocal()) {
00384         AppWormux::GetInstance()->video.window.Blit( pointer_aim, Point2i(GetPosition().x-7, GetPosition().y-10 ));
00385         world.ToRedrawOnScreen(Rectanglei(GetPosition().x-7, GetPosition().y-10, pointer_aim.GetWidth(), pointer_aim.GetHeight()));
00386       } else {
00387         AppWormux::GetInstance()->video.window.Blit( pointer_select, GetPosition() );
00388         world.ToRedrawOnScreen(Rectanglei(GetPosition().x, GetPosition().y , pointer_select.GetWidth(), pointer_select.GetHeight()));
00389       }
00390       break;
00391     default:
00392       break;
00393     };
00394 }
00395 
00396 
00397 // Center the pointer on the screen
00398 void Mouse::CenterPointer()
00399 {
00400   SDL_WarpMouse(AppWormux::GetInstance()->video.window.GetWidth()/2,
00401                 AppWormux::GetInstance()->video.window.GetHeight()/2);
00402 }

Generated on Mon Jan 1 13:10:58 2007 for Wormux by  doxygen 1.4.7