1
/*
2
 *  The Mana World
3
 *  Copyright (C) 2004  The Mana World Development Team
4
 *
5
 *  This file is part of The Mana World.
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 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
22
#include "configuration.h"
23
#include "joystick.h"
24
#include "log.h"
25
26
#include <cassert>
27
28
int Joystick::joystickCount = 0;
29
30
void Joystick::init()
31
{
32
    SDL_InitSubSystem(SDL_INIT_JOYSTICK);
33
34
    // Have SDL call SDL_JoystickUpdate() automatically
35
    SDL_JoystickEventState(SDL_ENABLE);
36
37
    joystickCount = SDL_NumJoysticks();
38
    logger->log("%i joysticks/gamepads found", joystickCount);
39
    for (int i = 0; i < joystickCount; i++)
40
        logger->log("- %s", SDL_JoystickName(i));
41
}
42
43
Joystick::Joystick(int no):
44
    mDirection(0),
45
    mCalibrating(false),
46
    mEnabled(false)
47
{
48
    assert(no < joystickCount);
49
50
    mJoystick = SDL_JoystickOpen(no);
51
52
    // TODO Bail out!
53
    if (!mJoystick)
54
    {
55
        logger->log("Couldn't open joystick: %s", SDL_GetError());
56
        return;
57
    }
58
59
    logger->log("Axes: %i ", SDL_JoystickNumAxes(mJoystick));
60
    logger->log("Balls: %i", SDL_JoystickNumBalls(mJoystick));
61
    logger->log("Hats: %i", SDL_JoystickNumHats(mJoystick));
62
    logger->log("Buttons: %i", SDL_JoystickNumButtons(mJoystick));
63
64
    mEnabled = (int) config.getValue("joystickEnabled", 0) != 0;
65
    mUpTolerance = (int) config.getValue("upTolerance", 100);
66
    mDownTolerance = (int) config.getValue("downTolerance", 100);
67
    mLeftTolerance = (int) config.getValue("leftTolerance", 100);
68
    mRightTolerance = (int) config.getValue("rightTolerance", 100);
69
}
70
71
Joystick::~Joystick()
72
{
73
    SDL_JoystickClose(mJoystick);
74
}
75
76
void Joystick::update()
77
{
78
    mDirection = 0;
79
80
    // When calibrating, don't bother the outside with our state
81
    if (mCalibrating) {
82
        doCalibration();
83
        return;
84
    };
85
86
    if (!mEnabled)
87
        return;
88
89
    // X-Axis
90
    int position = SDL_JoystickGetAxis(mJoystick, 0);
91
    if (position >= mRightTolerance)
92
        mDirection |= RIGHT;
93
    else if (position <= mLeftTolerance)
94
        mDirection |= LEFT;
95
96
    // Y-Axis
97
    position = SDL_JoystickGetAxis(mJoystick, 1);
98
    if (position <= mUpTolerance)
99
        mDirection |= UP;
100
    else if (position >= mDownTolerance)
101
        mDirection |= DOWN;
102
103
    // Buttons
104
    for (int i = 0; i < MAX_BUTTONS; i++)
105
        mButtons[i] = (SDL_JoystickGetButton(mJoystick, i) == 1);
106
}
107
108
void Joystick::startCalibration()
109
{
110
    mUpTolerance = 0;
111
    mDownTolerance = 0;
112
    mLeftTolerance = 0;
113
    mRightTolerance = 0;
114
    mCalibrating = true;
115
}
116
117
void Joystick::doCalibration()
118
{
119
    // X-Axis
120
    int position = SDL_JoystickGetAxis(mJoystick, 0);
121
    if (position > mRightTolerance)
122
        mRightTolerance = position;
123
    else if (position < mLeftTolerance)
124
        mLeftTolerance = position;
125
126
    // Y-Axis
127
    position = SDL_JoystickGetAxis(mJoystick, 1);
128
    if (position > mDownTolerance)
129
        mDownTolerance = position;
130
    else if (position < mUpTolerance)
131
        mUpTolerance = position;
132
}
133
134
void Joystick::finishCalibration()
135
{
136
    config.setValue("leftTolerance", mLeftTolerance);
137
    config.setValue("rightTolerance", mRightTolerance);
138
    config.setValue("upTolerance", mUpTolerance);
139
    config.setValue("downTolerance", mDownTolerance);
140
    mCalibrating = false;
141
}
142
143
bool Joystick::buttonPressed(unsigned char no) const
144
{
145
    return (mEnabled && no < MAX_BUTTONS) ? mButtons[no] : false;
146
}