Add support for game controllers
This commit is contained in:
parent
187776ed69
commit
e9ea95d3b9
7 changed files with 187 additions and 8 deletions
81
src/game.cpp
81
src/game.cpp
|
|
@ -284,6 +284,50 @@ int Game::gameLoop()
|
|||
{
|
||||
// handle player controls
|
||||
updateControls(event.key.keysym.sym, false);
|
||||
|
||||
} else if (event.type == SDL_CONTROLLERBUTTONUP) {
|
||||
switch (event.cbutton.button) {
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
if (state == WAITFORSTART) {
|
||||
state = START;
|
||||
stateTimer = 0;
|
||||
stateVal = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
case SDL_CONTROLLER_BUTTON_BACK:
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (event.type == SDL_CONTROLLERAXISMOTION) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
updateControls(
|
||||
mapControllerAxis(
|
||||
event.caxis.which,
|
||||
event.caxis.axis,
|
||||
event.caxis.value
|
||||
),
|
||||
event.caxis.value < -12000 || event.caxis.value > 12000
|
||||
);
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
updateControls(
|
||||
mapControllerAxis(
|
||||
event.caxis.which,
|
||||
event.caxis.axis,
|
||||
event.caxis.value
|
||||
),
|
||||
event.caxis.value > 500
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -435,6 +479,43 @@ void Game::updateWorld(float t)
|
|||
|
||||
}
|
||||
|
||||
SDL_Keycode Game::mapControllerAxis(SDL_JoystickID joy, Uint8 axis, Sint16 value)
|
||||
{
|
||||
int ctrl;
|
||||
|
||||
for(int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (!players[i].hasController(joy))
|
||||
continue;
|
||||
|
||||
// Controls in order: right, left, thrust
|
||||
switch(axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
ctrl = value > 0 ? 0 : 1;
|
||||
break;
|
||||
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
ctrl = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
return SDLK_ESCAPE;
|
||||
}
|
||||
|
||||
return CONTROLS[i][ctrl];
|
||||
}
|
||||
|
||||
return SDLK_ESCAPE;
|
||||
}
|
||||
|
||||
int Game::getPlayerForController(SDL_JoystickID id)
|
||||
{
|
||||
for(int p = 0; p < MAX_LOCAL_PLAYERS; p++)
|
||||
if (players[p].hasController(id))
|
||||
return p;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Game::initViewports(int num)
|
||||
{
|
||||
numViewports = num;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ public:
|
|||
Level &getLevel();
|
||||
static Game &getInstance();
|
||||
|
||||
int getPlayerForController(SDL_JoystickID id);
|
||||
|
||||
void initViewports(int num);
|
||||
|
||||
Player &getPlayer(int n);
|
||||
|
|
@ -60,6 +62,8 @@ private:
|
|||
bool updateControls(int keysym, bool down);
|
||||
void updateWorld(float t);
|
||||
|
||||
SDL_Keycode mapControllerAxis(SDL_JoystickID joy, Uint8 axis, Sint16 value);
|
||||
|
||||
void resetListener();
|
||||
void updateListener();
|
||||
|
||||
|
|
|
|||
32
src/main.cpp
32
src/main.cpp
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
//#include "SDL_gamecontroller.h"
|
||||
#include <AL/alut.h>
|
||||
#include <AL/al.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -93,7 +94,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
atexit(cleanup);
|
||||
|
||||
if(SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
fprintf(stderr, "Can't initialize SDL: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
|
|
@ -160,15 +161,40 @@ int main(int argc, char *argv[])
|
|||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
Game &game = Game::getInstance();
|
||||
|
||||
if(game.init(screen)) return 1;
|
||||
if(Menu::init()) return 1;
|
||||
|
||||
SDL_GameController *controllers[8] = {NULL};
|
||||
SDL_GameController *controller = NULL;
|
||||
|
||||
for (int i = 0, j = 0; i < SDL_NumJoysticks(); i++) {
|
||||
if (!SDL_IsGameController(i))
|
||||
continue;
|
||||
|
||||
controller = SDL_GameControllerOpen(i);
|
||||
|
||||
if (controller) {
|
||||
controllers[j++] = controller;
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Could not open gamecontroller %i: %s\n", i, SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
Menu menu(screen);
|
||||
while(1) {
|
||||
if(menu.show())
|
||||
return 0;
|
||||
break;
|
||||
if(game.gameLoop())
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (!controllers[i])
|
||||
break;
|
||||
|
||||
SDL_GameControllerClose(controllers[i]);
|
||||
}
|
||||
|
||||
SDL_GL_DeleteContext(glcontext);
|
||||
|
|
|
|||
56
src/menu.cpp
56
src/menu.cpp
|
|
@ -101,6 +101,51 @@ int Menu::show()
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (event.type == SDL_CONTROLLERBUTTONUP) {
|
||||
Game &game = Game::getInstance();
|
||||
|
||||
if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A ) {
|
||||
int p;
|
||||
|
||||
if ((p = game.getPlayerForController(event.cbutton.which)) == -1) {
|
||||
// Activate the first available player
|
||||
for(int p = 0; p < Game::MAX_LOCAL_PLAYERS; p++) {
|
||||
Player &plr = Game::getInstance().getPlayer(p);
|
||||
|
||||
if (plr.isActive())
|
||||
continue;
|
||||
|
||||
togglePlayer(plr);
|
||||
plr.setController(event.cbutton.which);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Player is already active, start the game
|
||||
if (canstart)
|
||||
rval = 0;
|
||||
}
|
||||
|
||||
} else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_B) {
|
||||
// Find out if this joystick already belongs to a player
|
||||
for(int p = 0; p < Game::MAX_LOCAL_PLAYERS; p++) {
|
||||
Player &plr = game.getPlayer(p);
|
||||
|
||||
if (plr.hasController(event.cbutton.which)) {
|
||||
togglePlayer(plr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_START) {
|
||||
if (canstart)
|
||||
rval = 0;
|
||||
|
||||
} else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) {
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,12 +154,15 @@ int Menu::show()
|
|||
|
||||
void Menu::togglePlayer(int p)
|
||||
{
|
||||
Game &game = Game::getInstance();
|
||||
Player &plr = game.getPlayer(p);
|
||||
togglePlayer(Game::getInstance().getPlayer(p));
|
||||
}
|
||||
|
||||
void Menu::togglePlayer(Player &plr)
|
||||
{
|
||||
plr.setActive(!plr.isActive());
|
||||
int act=0;
|
||||
for(int plr=0;plr<4;plr++) {
|
||||
if(game.getPlayer(plr).isActive())
|
||||
for(int p=0;p<4;p++) {
|
||||
if(plr.isActive())
|
||||
++act;
|
||||
}
|
||||
canstart = act>0;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class Menu {
|
|||
int show();
|
||||
private:
|
||||
void togglePlayer(int p);
|
||||
void togglePlayer(Player &plr);
|
||||
void drawPlayer(int p);
|
||||
void update();
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ ALuint Player::buffer;
|
|||
float Player::engineVolume = 1.0;
|
||||
|
||||
Player::Player()
|
||||
: finished(false)
|
||||
: joyid(-1),
|
||||
finished(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +70,9 @@ void Player::setTexture(m3dTexture *tex)
|
|||
void Player::setActive(bool a)
|
||||
{
|
||||
active = a;
|
||||
|
||||
if (!active)
|
||||
joyid = -1;
|
||||
}
|
||||
|
||||
void Player::setLocal(bool l)
|
||||
|
|
@ -76,10 +80,17 @@ void Player::setLocal(bool l)
|
|||
local = l;
|
||||
}
|
||||
|
||||
void Player::setController(SDL_JoystickID id)
|
||||
{
|
||||
joyid = id;
|
||||
}
|
||||
|
||||
Craft &Player::getCraft() { return craft; }
|
||||
bool Player::isActive() const { return active; }
|
||||
bool Player::isLocal() const { return local; }
|
||||
const char *Player::getName() const { return name; }
|
||||
bool Player::hasController() const { return joyid != -1; }
|
||||
bool Player::hasController(SDL_JoystickID id) const { return joyid == id; }
|
||||
|
||||
bool Player::isFinished() const { return finished; }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef _PLAYER_H_
|
||||
#define _PLAYER_H_
|
||||
|
||||
#include "SDL_gamecontroller.h"
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
|
|
@ -13,6 +15,8 @@ public:
|
|||
void setTexture(m3dTexture *texture);
|
||||
void setActive(bool active);
|
||||
void setLocal(bool l);
|
||||
void setController(SDL_JoystickID id);
|
||||
void unsetController();
|
||||
|
||||
void setColor(float r, float g, float b);
|
||||
void setColor(const float *col);
|
||||
|
|
@ -29,6 +33,8 @@ public:
|
|||
bool isActive() const;
|
||||
bool isLocal() const;
|
||||
bool isFinished() const;
|
||||
bool hasController() const;
|
||||
bool hasController(SDL_JoystickID id) const;
|
||||
const char *getName() const;
|
||||
|
||||
void drawHud(const GLint *viewport, int activePlayers, int num);
|
||||
|
|
@ -46,6 +52,8 @@ private:
|
|||
|
||||
Craft craft;
|
||||
|
||||
SDL_JoystickID joyid;
|
||||
|
||||
bool active;
|
||||
bool local;
|
||||
bool finished;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue