GamePad.hh 4.36 KB
Newer Older
Robert Menzel's avatar
Robert Menzel committed
1 2 3 4 5 6 7 8 9 10
/***********************************************************************
 * Copyright 2011-2013 Computer Graphics Group RWTH Aachen University. *
 * All rights reserved.                                                *
 * Distributed under the terms of the MIT License (see LICENSE.TXT).   *
 **********************************************************************/

#pragma once

#include <ACGL/ACGL.hh>
#include <string>
11
#include <linuxjoystick/Joystick.h>
Robert Menzel's avatar
Robert Menzel committed
12 13 14 15 16

namespace ACGL{
namespace HardwareSupport{

/**
17
 * NOTE: Will not work unless ACGL_COMPILE_WITH_GLFW or ACGL_COMPILE_WITH_QT (linux only) is defined!
Robert Menzel's avatar
Robert Menzel committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
 */
class GamePad {
public:
    enum GamePadButton {
        SELECT = 0,
        START  = 1,
        LEFT_PAD_NORTH  = 2,
        LEFT_PAD_EAST   = 3,
        LEFT_PAD_SOUTH  = 4,
        LEFT_PAD_WEST   = 5,
        RIGHT_PAD_NORTH = 6,
        RIGHT_PAD_EAST  = 7,
        RIGHT_PAD_SOUTH = 8,
        RIGHT_PAD_WEST  = 9,
        LEFT_SHOULDER   = 10,
        RIGHT_SHOULDER  = 11,
        LEFT_TRIGGER    = 12,
        RIGHT_TRIGGER   = 13,

        // number of elements in this enum (itself not included):
        GAMEPAD_BUTTON_ENUM_SIZE = 14
    };

    enum GamePadAxis {
        LEFT_ANALOG_TRIGGER  = 0,
        RIGHT_ANALOG_TRIGGER = 1,
        LEFT_ANALOG_STICK_X  = 2, // aka left-right
        LEFT_ANALOG_STICK_Y  = 3, // aka up-down / front-back
        RIGHT_ANALOG_STICK_X = 4, // aka left-right
        RIGHT_ANALOG_STICK_Y = 5, // aka up-down / front-back

        // number of elements in this enum (itself not included):
        GAMEPAD_AXIS_ENUM_SIZE = 6
    };


    //! connects to the _n-th joystick, start counting at 1!
    GamePad( int _n = 1 );
    ~GamePad();

    //! true if the joystick was found, note that unplugging the GamePad at runtime can not be detected!
    bool ok() { return mGamePadOK; }

    ///////////// Buttons

    //! true if the button with the internal number _button is pressed
    bool isPressedRaw( unsigned int _button );

    //! only returns true if the button was mapped first!
    bool isPressed( GamePadButton _button );

    //! true if the button was just pressed or released
    bool buttonStateChanged( unsigned int _button );

    //! true if the button was just pressed or released
    bool buttonStateChanged( GamePadButton _button );

    //! define the mapping of one button
    void setButtonMapping( GamePadButton _button, unsigned int _rawButtonNumber );

    ///////////// Axes

    //! analog sticks and analog trigger, values are from -1..1. An unknown axis will return 0.0
    float getAxisRaw( unsigned int _axis );

    float getAxis( GamePadAxis _axis );

    //! define the mapping of one button
    void setAxisMapping( GamePadAxis _axis, unsigned int _rawAxisNumber );

Robert Menzel's avatar
Robert Menzel committed
88 89 90 91 92 93 94 95 96
    //! sets the minimal value an axis has to be pushed to trigger.
    //! _sensitivity has to be >= 0.0 and < 1.0.
    //! reported axis values will still be between -1..0..1
    void setMinAxisSensitivity( float _sensitivity );

    float getMinAxisSensitivity() { return mMinSensitivity; }

    //! set and unset the invertation of an axis (1..-1 -> -1..1)
    void invertAxis( int _axis, bool _invert = true );
Robert Menzel's avatar
Robert Menzel committed
97 98 99 100 101 102 103 104 105 106 107 108 109

    //! print the button and axes state for debugging:
    void printState();

    //! fetches the current device state, will do nothing if the joystick is not ok
    void update();

private:
    bool  mGamePadOK;
    int   mNumberOfButtons;
    int   mNumberOfAxes;
    int   mButtonMap[GAMEPAD_BUTTON_ENUM_SIZE];
    int   mAxisMap[GAMEPAD_AXIS_ENUM_SIZE];
110 111 112 113 114 115 116 117 118 119
    unsigned char *mButtonState; // 0 = released, 1 = pressed
    unsigned char *mLastButtonState;
    float *mAxes; // -1 .. 1 per axis
    float *mAxesMultiplier; // used for scaling from the used API to -1..1
    float mMinSensitivity;  // a minimal axis value that has to be exceeded before it is evaluated

    std::string mJoystickName;

    // fills mAxis and mButtonState and also stores the old state
    void getAxisAndButtonValues();
Robert Menzel's avatar
Robert Menzel committed
120 121 122 123

    //
    // GLFW specifics: replace this to support joysticks with other APIs
    //
124
#ifdef ACGL_COMPILE_WITH_GLFW
125 126
    const unsigned char *mGLFWButtons; // temp. used as GLFW needs a const array
    const float         *mGLFWAxes;    // temp. used as GLFW needs a const array
Robert Menzel's avatar
Robert Menzel committed
127
    int mGLFWGamePadNumber;
128
#endif
129 130 131 132 133 134 135

    //
    // Custom Linux Joystick support:
    //
#ifdef ACGL_OWN_LINUX_JOYSTICK
    Joystick mLinuxGamePad;
#endif
Robert Menzel's avatar
Robert Menzel committed
136 137 138 139 140 141
};
ACGL_SMARTPOINTER_TYPEDEFS(GamePad)

}
}