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
|
// handle player controls
|
||||||
updateControls(event.key.keysym.sym, false);
|
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)
|
void Game::initViewports(int num)
|
||||||
{
|
{
|
||||||
numViewports = num;
|
numViewports = num;
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ public:
|
||||||
Level &getLevel();
|
Level &getLevel();
|
||||||
static Game &getInstance();
|
static Game &getInstance();
|
||||||
|
|
||||||
|
int getPlayerForController(SDL_JoystickID id);
|
||||||
|
|
||||||
void initViewports(int num);
|
void initViewports(int num);
|
||||||
|
|
||||||
Player &getPlayer(int n);
|
Player &getPlayer(int n);
|
||||||
|
|
@ -60,6 +62,8 @@ private:
|
||||||
bool updateControls(int keysym, bool down);
|
bool updateControls(int keysym, bool down);
|
||||||
void updateWorld(float t);
|
void updateWorld(float t);
|
||||||
|
|
||||||
|
SDL_Keycode mapControllerAxis(SDL_JoystickID joy, Uint8 axis, Sint16 value);
|
||||||
|
|
||||||
void resetListener();
|
void resetListener();
|
||||||
void updateListener();
|
void updateListener();
|
||||||
|
|
||||||
|
|
|
||||||
32
src/main.cpp
32
src/main.cpp
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_opengl.h"
|
#include "SDL_opengl.h"
|
||||||
|
//#include "SDL_gamecontroller.h"
|
||||||
#include <AL/alut.h>
|
#include <AL/alut.h>
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -93,7 +94,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
atexit(cleanup);
|
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());
|
fprintf(stderr, "Can't initialize SDL: %s\n", SDL_GetError());
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -160,15 +161,40 @@ int main(int argc, char *argv[])
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
|
||||||
Game &game = Game::getInstance();
|
Game &game = Game::getInstance();
|
||||||
|
|
||||||
if(game.init(screen)) return 1;
|
if(game.init(screen)) return 1;
|
||||||
if(Menu::init()) 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);
|
Menu menu(screen);
|
||||||
while(1) {
|
while(1) {
|
||||||
if(menu.show())
|
if(menu.show())
|
||||||
return 0;
|
break;
|
||||||
if(game.gameLoop())
|
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);
|
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)
|
void Menu::togglePlayer(int p)
|
||||||
{
|
{
|
||||||
Game &game = Game::getInstance();
|
togglePlayer(Game::getInstance().getPlayer(p));
|
||||||
Player &plr = game.getPlayer(p);
|
}
|
||||||
|
|
||||||
|
void Menu::togglePlayer(Player &plr)
|
||||||
|
{
|
||||||
plr.setActive(!plr.isActive());
|
plr.setActive(!plr.isActive());
|
||||||
int act=0;
|
int act=0;
|
||||||
for(int plr=0;plr<4;plr++) {
|
for(int p=0;p<4;p++) {
|
||||||
if(game.getPlayer(plr).isActive())
|
if(plr.isActive())
|
||||||
++act;
|
++act;
|
||||||
}
|
}
|
||||||
canstart = act>0;
|
canstart = act>0;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ class Menu {
|
||||||
int show();
|
int show();
|
||||||
private:
|
private:
|
||||||
void togglePlayer(int p);
|
void togglePlayer(int p);
|
||||||
|
void togglePlayer(Player &plr);
|
||||||
void drawPlayer(int p);
|
void drawPlayer(int p);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ ALuint Player::buffer;
|
||||||
float Player::engineVolume = 1.0;
|
float Player::engineVolume = 1.0;
|
||||||
|
|
||||||
Player::Player()
|
Player::Player()
|
||||||
: finished(false)
|
: joyid(-1),
|
||||||
|
finished(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,6 +70,9 @@ void Player::setTexture(m3dTexture *tex)
|
||||||
void Player::setActive(bool a)
|
void Player::setActive(bool a)
|
||||||
{
|
{
|
||||||
active = a;
|
active = a;
|
||||||
|
|
||||||
|
if (!active)
|
||||||
|
joyid = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setLocal(bool l)
|
void Player::setLocal(bool l)
|
||||||
|
|
@ -76,10 +80,17 @@ void Player::setLocal(bool l)
|
||||||
local = l;
|
local = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::setController(SDL_JoystickID id)
|
||||||
|
{
|
||||||
|
joyid = id;
|
||||||
|
}
|
||||||
|
|
||||||
Craft &Player::getCraft() { return craft; }
|
Craft &Player::getCraft() { return craft; }
|
||||||
bool Player::isActive() const { return active; }
|
bool Player::isActive() const { return active; }
|
||||||
bool Player::isLocal() const { return local; }
|
bool Player::isLocal() const { return local; }
|
||||||
const char *Player::getName() const { return name; }
|
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; }
|
bool Player::isFinished() const { return finished; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef _PLAYER_H_
|
#ifndef _PLAYER_H_
|
||||||
#define _PLAYER_H_
|
#define _PLAYER_H_
|
||||||
|
|
||||||
|
#include "SDL_gamecontroller.h"
|
||||||
|
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -13,6 +15,8 @@ public:
|
||||||
void setTexture(m3dTexture *texture);
|
void setTexture(m3dTexture *texture);
|
||||||
void setActive(bool active);
|
void setActive(bool active);
|
||||||
void setLocal(bool l);
|
void setLocal(bool l);
|
||||||
|
void setController(SDL_JoystickID id);
|
||||||
|
void unsetController();
|
||||||
|
|
||||||
void setColor(float r, float g, float b);
|
void setColor(float r, float g, float b);
|
||||||
void setColor(const float *col);
|
void setColor(const float *col);
|
||||||
|
|
@ -29,6 +33,8 @@ public:
|
||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
bool isLocal() const;
|
bool isLocal() const;
|
||||||
bool isFinished() const;
|
bool isFinished() const;
|
||||||
|
bool hasController() const;
|
||||||
|
bool hasController(SDL_JoystickID id) const;
|
||||||
const char *getName() const;
|
const char *getName() const;
|
||||||
|
|
||||||
void drawHud(const GLint *viewport, int activePlayers, int num);
|
void drawHud(const GLint *viewport, int activePlayers, int num);
|
||||||
|
|
@ -46,6 +52,8 @@ private:
|
||||||
|
|
||||||
Craft craft;
|
Craft craft;
|
||||||
|
|
||||||
|
SDL_JoystickID joyid;
|
||||||
|
|
||||||
bool active;
|
bool active;
|
||||||
bool local;
|
bool local;
|
||||||
bool finished;
|
bool finished;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue