home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 February / maximum-cd-2009-02.iso / DiscContents / SMC_1.6_win32.exe / src / input / joystick.cpp next >
Encoding:
C/C++ Source or Header  |  2008-08-23  |  11.4 KB  |  595 lines

  1. /***************************************************************************
  2.  * joystick.cpp  -  Joystick handling class
  3.  *
  4.  * Copyright (C) 2003 - 2008 Florian Richter
  5.  ***************************************************************************/
  6. /*
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 3 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. #include "../core/globals.h"
  17. #include "../input/keyboard.h"
  18. #include "../input/joystick.h"
  19. #include "../user/preferences.h"
  20. #include "../core/game_core.h"
  21. #include "../player/player.h"
  22. #include "../gui/hud.h"
  23. #include "../gui/menu.h"
  24. #include "../level/level.h"
  25. #include "../overworld/overworld.h"
  26.  
  27. /* *** *** *** *** *** *** cJoystick *** *** *** *** *** *** *** *** *** *** *** */
  28.  
  29. cJoystick :: cJoystick( void )
  30. {
  31.     joystick = NULL;
  32.  
  33.     stick_open = 0;
  34.  
  35.     cur_stick = 0;
  36.     num_buttons = 0;
  37.     num_axes = 0;
  38.     num_balls = 0;
  39.  
  40.     debug = 0;
  41.  
  42.     Reset_keys();
  43.  
  44.     Init();
  45. }
  46.  
  47. cJoystick :: ~cJoystick( void )
  48. {
  49.     Close();
  50. }
  51.  
  52. int cJoystick :: Init( void )
  53. {
  54.     // if not enabled
  55.     if( !pPreferences->joy_enabled )
  56.     {
  57.         return 0;
  58.     }
  59.  
  60.     int joy_count = SDL_NumJoysticks();
  61.  
  62.     // no joystick available
  63.     if( joy_count <= 0 )
  64.     {
  65.         printf( "No joysticks available\n" );
  66.         pPreferences->joy_enabled = 0;
  67.         return 0;
  68.     }
  69.  
  70.     if( debug )
  71.     {
  72.         printf( "Joysticks found : %d\n\n", joy_count );
  73.     }
  74.  
  75.     unsigned int default_joy = 0;
  76.  
  77.     // if default joy name is given
  78.     if( !pPreferences->joy_name.empty() )
  79.     {
  80.         vector<string> joy_names = Get_Names();
  81.  
  82.         for( unsigned int i = 0; i < joy_names.size(); i++ )
  83.         {
  84.             // found default joy
  85.             if( joy_names[i].compare( pPreferences->joy_name ) == 0 )
  86.             {
  87.                 default_joy = i;
  88.                 break;
  89.             }
  90.         }
  91.     }
  92.  
  93.     // setup
  94.     SDL_JoystickEventState( SDL_ENABLE );
  95.     Stick_Open( default_joy );
  96.  
  97.     if( debug )
  98.     {
  99.         printf( "Joypad System Initialized\n" );
  100.     }
  101.  
  102.     return 1;
  103. }
  104.  
  105. void cJoystick :: Close( void )
  106. {
  107.     Stick_Close();
  108. }
  109.  
  110. bool cJoystick :: Stick_Open( unsigned int index )
  111. {
  112.     // if a joystick is already opened close it first
  113.     if( stick_open )
  114.     {
  115.         Stick_Close();
  116.     }
  117.  
  118.     joystick = SDL_JoystickOpen( index );
  119.  
  120.     if( !joystick )
  121.     {
  122.         printf( "Couldn't open joystick %d\n", index );
  123.         stick_open = 0;
  124.         return 0;
  125.     }
  126.  
  127.     cur_stick = index;
  128.  
  129.     num_buttons = SDL_JoystickNumButtons( joystick );
  130.     num_axes = SDL_JoystickNumAxes( joystick );
  131.     num_balls = SDL_JoystickNumBalls( joystick );
  132.  
  133.     // todo : replace with STL fill
  134.     // setup available button
  135.     for( unsigned int i = 0; i < num_buttons; i++ )
  136.     {
  137.         buttons.push_back( 0 );
  138.     }
  139.  
  140.     if( debug )
  141.     {
  142.         printf( "Opened Joystick %d\n", cur_stick );
  143.         printf( "Name: %s\n", Get_Name().c_str() );
  144.         printf( "Number of Buttons: %d\n", num_buttons );
  145.         printf( "Number of Axes: %d\n", num_axes );
  146.         printf( "Number of Balls: %d\n\n", num_balls );
  147.     }
  148.  
  149.     stick_open = 1;
  150.     return 1;
  151. }
  152.  
  153. void cJoystick :: Stick_Close( void )
  154. {
  155.     // not available
  156.     if( !joystick )
  157.     {
  158.         return;
  159.     }
  160.  
  161.     SDL_JoystickClose( joystick );
  162.     joystick = NULL;
  163.  
  164.     Reset_keys();
  165.  
  166.     num_buttons = 0;
  167.     num_axes = 0;
  168.     num_balls = 0;
  169.  
  170.     buttons.clear();
  171.     stick_open = 0;
  172.  
  173.     if( debug )
  174.     {
  175.         printf( "Joystick %d closed\n", cur_stick );
  176.     }
  177.  
  178.     cur_stick = 0;
  179. }
  180.  
  181. void cJoystick :: Reset_keys( void )
  182. {
  183.     // clear buttons
  184.     for( unsigned int i = 0; i < buttons.size(); i++ )
  185.     {
  186.         buttons[i] = 0;
  187.     }
  188.     
  189.     left = 0;
  190.     right = 0;
  191.     up = 0;
  192.     down = 0;
  193. }
  194.  
  195. void cJoystick :: Handle_Motion( SDL_Event *ev )
  196. {
  197.     // Vertical Axis
  198.     if( ev->jaxis.axis == pPreferences->joy_axis_ver )
  199.     {
  200.         // Up
  201.         if( ev->jaxis.value < -pPreferences->joy_axis_threshold )
  202.         {
  203.             if( debug )
  204.             {
  205.                 printf( "Joystick %d : Up Button pressed\n", cur_stick );
  206.             }
  207.  
  208.             if( !up )
  209.             {
  210.                 pKeyboard->Key_Down( pPreferences->key_up );
  211.                 up = 1;
  212.             }
  213.  
  214.             if( down )
  215.             {
  216.                 pKeyboard->Key_Up( pPreferences->key_down );
  217.                 down = 0;
  218.             }
  219.         }
  220.         // Down
  221.         else if( ev->jaxis.value > pPreferences->joy_axis_threshold )
  222.         {
  223.             if( debug )
  224.             {
  225.                 printf( "Joystick %d : Down Button pressed\n", cur_stick );
  226.             }
  227.  
  228.             if( !down )
  229.             {
  230.                 pKeyboard->Key_Down( pPreferences->key_down );
  231.                 down = 1;
  232.             }
  233.  
  234.             if( up )
  235.             {
  236.                 pKeyboard->Key_Up( pPreferences->key_up );
  237.                 up = 0;
  238.             }
  239.         }
  240.         // No Down/Left
  241.         else
  242.         {
  243.             if( down )
  244.             {
  245.                 pKeyboard->Key_Up( pPreferences->key_down );
  246.                 down = 0;
  247.             }
  248.  
  249.             if( up )
  250.             {
  251.                 pKeyboard->Key_Up( pPreferences->key_up );
  252.                 up = 0;
  253.             }
  254.         }
  255.     }
  256.     // Horizontal Axis
  257.     else if( ev->jaxis.axis == pPreferences->joy_axis_hor )
  258.     {
  259.         // Left
  260.         if( ev->jaxis.value < -pPreferences->joy_axis_threshold )
  261.         {
  262.             if( debug )
  263.             {
  264.                 printf( "Joystick %d : Left Button pressed\n", cur_stick );
  265.             }
  266.  
  267.             if( !left )
  268.             {
  269.                 pKeyboard->Key_Down( pPreferences->key_left );
  270.                 left = 1;
  271.             }
  272.  
  273.             if( right )
  274.             {
  275.                 pKeyboard->Key_Up( pPreferences->key_right );
  276.                 right = 0;
  277.             }
  278.         }
  279.         // Right
  280.         else if( ev->jaxis.value > pPreferences->joy_axis_threshold )
  281.         {
  282.             if( debug )
  283.             {
  284.                 printf( "Joystick %d : Right Button pressed\n", cur_stick );
  285.             }
  286.  
  287.             if( !right )
  288.             {
  289.                 pKeyboard->Key_Down( pPreferences->key_right );
  290.                 right = 1;
  291.             }
  292.  
  293.             if( left )
  294.             {
  295.                 pKeyboard->Key_Up( pPreferences->key_left );
  296.                 left = 0;
  297.             }
  298.         }
  299.         // No Left/Right
  300.         else
  301.         {
  302.             if( left )
  303.             {
  304.                 pKeyboard->Key_Up( pPreferences->key_left );
  305.                 left = 0;
  306.             }
  307.  
  308.             if( right )
  309.             {
  310.                 pKeyboard->Key_Up( pPreferences->key_right );
  311.                 right = 0;
  312.             }
  313.         }
  314.     }
  315. }
  316.  
  317. bool cJoystick :: Handle_Button_Down_Event( SDL_Event *ev )
  318. {
  319.     // not enabled or opened
  320.     if( !pPreferences->joy_enabled || !stick_open )
  321.     {
  322.         return 0;
  323.     }
  324.  
  325.     Set_Button( ev->jbutton.button, 1 );
  326.  
  327.     // handle button in the current mode
  328.     if( Game_Mode == MODE_LEVEL )
  329.     {
  330.         // processed by the level
  331.         if( pActive_Level->Joy_Button_Down( ev->jbutton.button ) )
  332.         {
  333.             return 1;
  334.         }
  335.     }
  336.     else if( Game_Mode == MODE_OVERWORLD )
  337.     {
  338.         // processed by the overworld
  339.         if( pActive_Overworld->Joy_Button_Down( ev->jbutton.button ) )
  340.         {
  341.             return 1;
  342.         }
  343.     }
  344.     else if( Game_Mode == MODE_MENU )
  345.     {
  346.         // processed by the menu
  347.         if( pMenuCore->Joy_Button_Down( ev->jbutton.button ) )
  348.         {
  349.             return 1;
  350.         }
  351.     }
  352.  
  353.     if( ev->jbutton.button < buttons.size() )
  354.     {
  355.         // Jump
  356.         if( ev->jbutton.button == pPreferences->joy_button_jump )
  357.         {
  358.             //
  359.         }
  360.         // Shoot
  361.         else if( ev->jbutton.button == pPreferences->joy_button_shoot )
  362.         {
  363.             pKeyboard->Key_Down( pPreferences->key_shoot );
  364.             return 1;
  365.         }
  366.         // Request Itembox Item
  367.         else if( ev->jbutton.button == pPreferences->joy_button_item )
  368.         {
  369.             // not handled
  370.             return 1;
  371.         }
  372.         // Interaction
  373.         else if( ev->jbutton.button == pPreferences->joy_button_action )
  374.         {
  375.             pKeyboard->Key_Down( pPreferences->key_action );
  376.             return 1;
  377.         }
  378.         // Exit
  379.         else if( ev->jbutton.button == pPreferences->joy_button_exit )
  380.         {
  381.             pKeyboard->Key_Down( SDLK_ESCAPE );
  382.             return 1;
  383.         }
  384.         // Pause
  385.         else if( ev->jbutton.button == 9 )
  386.         {
  387.             pKeyboard->Key_Down( SDLK_PAUSE );
  388.             return 1;
  389.         }
  390.     }
  391.  
  392.     return 0;
  393. }
  394.  
  395. bool cJoystick :: Handle_Button_Up_Event( SDL_Event *ev )
  396. {
  397.     // not enabled or opened
  398.     if( !pPreferences->joy_enabled || !stick_open )
  399.     {
  400.         return 0;
  401.     }
  402.  
  403.     Set_Button( ev->jbutton.button, 0 );
  404.  
  405.     // handle button in the current mode
  406.     if( Game_Mode == MODE_LEVEL )
  407.     {
  408.         // processed by the level
  409.         if( pActive_Level->Joy_Button_Up( ev->jbutton.button ) )
  410.         {
  411.             return 1;
  412.         }
  413.     }
  414.     else if( Game_Mode == MODE_OVERWORLD )
  415.     {
  416.         // processed by the overworld
  417.         if( pActive_Overworld->Joy_Button_Up( ev->jbutton.button ) )
  418.         {
  419.             return 1;
  420.         }
  421.     }
  422.     else if( Game_Mode == MODE_MENU )
  423.     {
  424.         // processed by the menu
  425.         if( pMenuCore->Joy_Button_Up( ev->jbutton.button ) )
  426.         {
  427.             return 1;
  428.         }
  429.     }
  430.  
  431.     if( ev->jbutton.button < buttons.size() )
  432.     {
  433.         if( ev->jbutton.button == pPreferences->joy_button_jump )
  434.         {
  435.             pKeyboard->Key_Up( pPreferences->key_jump );
  436.             return 1;
  437.         }
  438.         else if( ev->jbutton.button == pPreferences->joy_button_shoot )
  439.         {
  440.             pKeyboard->Key_Up( pPreferences->key_shoot );
  441.             return 1;
  442.         }
  443.         else if( ev->jbutton.button == pPreferences->joy_button_item )
  444.         {
  445.             // not handled
  446.         }
  447.         else if( ev->jbutton.button == pPreferences->joy_button_action )
  448.         {
  449.             pKeyboard->Key_Up( pPreferences->key_action );
  450.             return 1;
  451.         }
  452.         else if( ev->jbutton.button == pPreferences->joy_button_exit )
  453.         {
  454.             pKeyboard->Key_Up( SDLK_ESCAPE );
  455.             return 1;
  456.         }
  457.     }
  458.  
  459.     return 0;
  460. }
  461.  
  462. string cJoystick :: Get_Name( void )
  463. {
  464.     return SDL_JoystickName( cur_stick );
  465. }
  466.  
  467. vector<string> cJoystick :: Get_Names( void )
  468. {
  469.     vector<string> names;
  470.     // get joy count
  471.     int joy_count = SDL_NumJoysticks();
  472.  
  473.     // joystick names
  474.     for( int i = 0; i < joy_count; i++  )
  475.     {
  476.         names.push_back( SDL_JoystickName( i ) );
  477.     }
  478.  
  479.     return names;
  480. }
  481.  
  482. void cJoystick :: Set_Button( Uint8 num, bool pressed )
  483. {
  484.     // not available
  485.     if( num >= buttons.size() )
  486.     {
  487.         return;
  488.     }
  489.  
  490.     if( debug )
  491.     {
  492.         if( pressed )
  493.         {
  494.             printf( "Joystick %d : Joy Button %d pressed\n", cur_stick, num );
  495.         }
  496.         else
  497.         {
  498.             printf( "Joystick %d : Joy Button %d released\n", cur_stick, num );
  499.         }
  500.     }
  501.  
  502.     buttons[num] = pressed;
  503. }
  504.  
  505. Uint8 *cJoystick :: Get_Shortcut( input_identifier shortcut_id )
  506. {
  507.     if( shortcut_id == INP_JUMP )
  508.     {
  509.         return &pPreferences->joy_button_jump;
  510.     }
  511.     else if( shortcut_id == INP_ITEM )
  512.     {
  513.         return &pPreferences->joy_button_item;
  514.     }
  515.     else if( shortcut_id == INP_SHOOT )
  516.     {
  517.         return &pPreferences->joy_button_shoot;
  518.     }
  519.     else if( shortcut_id == INP_ACTION )
  520.     {
  521.         return &pPreferences->joy_button_action;
  522.     }
  523.     else if( shortcut_id == INP_EXIT )
  524.     {
  525.         return &pPreferences->joy_button_exit;
  526.     }
  527.  
  528.     return NULL;
  529. }
  530.  
  531. void cJoystick :: Assign_Shortcut( input_identifier shortcut_id, Uint8 new_button )
  532. {
  533.     Uint8 *button = Get_Shortcut( shortcut_id );
  534.     *button = new_button;
  535. }
  536.  
  537. bool cJoystick :: Left( void )
  538. {
  539.     if( pPreferences->joy_enabled && input_event.type == SDL_JOYAXISMOTION && input_event.jaxis.value < -pPreferences->joy_axis_threshold && 
  540.         input_event.jaxis.axis == pPreferences->joy_axis_hor )
  541.     {
  542.         return 1;
  543.     }
  544.  
  545.     return 0;
  546. }
  547.  
  548. bool cJoystick :: Right( void )
  549. {
  550.     if( pPreferences->joy_enabled && input_event.type == SDL_JOYAXISMOTION && input_event.jaxis.value > pPreferences->joy_axis_threshold && 
  551.         input_event.jaxis.axis == pPreferences->joy_axis_hor )
  552.     {
  553.         return 1;
  554.     }
  555.     
  556.     return 0;
  557. }
  558.  
  559. bool cJoystick :: Up( void )
  560. {
  561.     if( pPreferences->joy_enabled && input_event.type == SDL_JOYAXISMOTION && input_event.jaxis.value < -pPreferences->joy_axis_threshold && 
  562.         input_event.jaxis.axis == pPreferences->joy_axis_ver )
  563.     {
  564.         return 1;
  565.     }
  566.     
  567.     return 0;
  568. }
  569.  
  570. bool cJoystick :: Down( void )
  571. {
  572.     if( pPreferences->joy_enabled && input_event.type == SDL_JOYAXISMOTION && input_event.jaxis.value > pPreferences->joy_axis_threshold && 
  573.         input_event.jaxis.axis == pPreferences->joy_axis_ver )
  574.     {
  575.         return 1;
  576.     }
  577.     
  578.     return 0;
  579. }
  580.  
  581. bool cJoystick :: Button( Uint8 num )
  582. {
  583.     // if available and pressed
  584.     if( num < buttons.size() && buttons[num] )
  585.     {
  586.         return 1;
  587.     }
  588.  
  589.     return 0;
  590. }
  591.  
  592. /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
  593.  
  594. cJoystick *pJoystick = NULL;
  595.