Implemented use of the game controller SDL API.

Fixes #7

Designed to use the game controller API if possible, or fall back
to the regular joystick API otherwise.

This also makes it so that all connected controllers can be used,
rather than just the first one.
This commit is contained in:
Layla Marchant 2020-07-27 11:29:35 -04:00
parent 21e16c157b
commit ca11cdea27
3 changed files with 119 additions and 11 deletions

View File

@ -33,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RANDRANGE(x, y) (((x) < (y)) ? ((x) + (rand() % (long)(1 + (y) - (x)))) : (x))
#define DRAND ((double)rand() / RAND_MAX)
#define _(s) gettext(s)
#define CSDLP(x) (((x) == SDL_PRESSED) ? 1 : 0)
// A soft dependency defines these as well, so check if they are
// defined before defining (avoids compiler warnings)

View File

@ -265,6 +265,9 @@ void engine_setMode()
int autoPause = 0;
int radioLife = DEFAULT_RADIO_LIFE;
char lang[STRMAX_SHORT];
int i;
int use_gc;
strcpy(lang, "default");
strcpy(engine.configDirectory, "");
@ -272,7 +275,7 @@ void engine_setMode()
engine_setupConfigDirectory();
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK) < 0)
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK|SDL_INIT_GAMECONTROLLER) < 0)
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
@ -329,8 +332,27 @@ void engine_setMode()
SDL_ShowCursor(SDL_DISABLE);
SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
SDL_JoystickEventState(SDL_ENABLE);
SDL_JoystickOpen(0);
// Determine if the GameController API can be used
use_gc = 1;
for (i=0; i<SDL_NumJoysticks(); i++) {
if (!SDL_IsGameController(i)) {
use_gc = 0;
break;
}
}
if (use_gc)
SDL_GameControllerEventState(SDL_ENABLE);
else
SDL_JoystickEventState(SDL_ENABLE);
// Open controllers
for (i=0; i<SDL_NumJoysticks(); i++) {
if (use_gc)
SDL_GameControllerOpen(i);
else
SDL_JoystickOpen(i);
}
}
void engine_setFullscreen(int value)

View File

@ -263,8 +263,10 @@ void player_getInput()
case SDL_MOUSEBUTTONDOWN:
if (engine.gameSection == SECTION_INTERMISSION)
{
if (engine.event.button.button == SDL_BUTTON_LEFT) engine.keyState[KEY_FIRE] = 1;
if (engine.event.button.button == SDL_BUTTON_RIGHT) engine.keyState[KEY_ALTFIRE] = 1;
if (engine.event.button.button == SDL_BUTTON_LEFT)
engine.keyState[KEY_FIRE] = 1;
if (engine.event.button.button == SDL_BUTTON_RIGHT)
engine.keyState[KEY_ALTFIRE] = 1;
}
break;
@ -289,24 +291,74 @@ void player_getInput()
{
case 0:
case 3:
engine.keyState[KEY_ALTFIRE] = engine.event.jbutton.state;
engine.keyState[KEY_ALTFIRE] = CSDLP(
engine.event.jbutton.state);
break;
case 1:
case 2:
engine.keyState[KEY_FIRE] = engine.event.jbutton.state;
engine.keyState[KEY_FIRE] = CSDLP(
engine.event.jbutton.state);
break;
case 4:
case 6:
engine.keyState[KEY_ESCAPE] = engine.event.jbutton.state;
engine.keyState[KEY_ESCAPE] = CSDLP(
engine.event.jbutton.state);
break;
case 5:
case 7:
case 8:
engine.keyState[KEY_SWITCH] = engine.event.jbutton.state;
engine.keyState[KEY_SWITCH] = CSDLP(
engine.event.jbutton.state);
break;
case 9:
if (engine.event.jbutton.state)
engine.keyState[KEY_PAUSE] = 1;
engine.keyState[KEY_PAUSE] = CSDLP(
engine.event.jbutton.state);
break;
}
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
switch (engine.event.cbutton.button)
{
case SDL_CONTROLLER_BUTTON_A:
case SDL_CONTROLLER_BUTTON_Y:
engine.keyState[KEY_ALTFIRE] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_B:
case SDL_CONTROLLER_BUTTON_X:
engine.keyState[KEY_FIRE] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
engine.keyState[KEY_ESCAPE] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_BACK:
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
engine.keyState[KEY_SWITCH] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_START:
engine.keyState[KEY_PAUSE] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_DPAD_UP:
engine.keyState[KEY_UP] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
engine.keyState[KEY_DOWN] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
engine.keyState[KEY_LEFT] = CSDLP(
engine.event.cbutton.state);
break;
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
engine.keyState[KEY_RIGHT] = CSDLP(
engine.event.cbutton.state);
break;
}
break;
@ -348,6 +400,39 @@ void player_getInput()
break;
case SDL_CONTROLLERAXISMOTION:
if (engine.gameSection == SECTION_TITLE) {
if (engine.event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX)
{
joyleft = engine.event.caxis.value < -16384;
joyright = engine.event.caxis.value >= 16384;
if (joyleft != prevjoyleft)
engine.keyState[KEY_LEFT] = prevjoyleft = joyleft;
if (joyright != prevjoyright)
engine.keyState[KEY_RIGHT] = prevjoyright = joyright;
}
else if (engine.event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY)
{
joyup = engine.event.caxis.value < -16384;
joydown = engine.event.caxis.value >= 16384;
if (joyup != prevjoyup)
engine.keyState[KEY_UP] = prevjoyup = joyup;
if (joydown != prevjoydown)
engine.keyState[KEY_DOWN] = prevjoydown = joydown;
}
} else {
val = MIN(1, (double)(abs(engine.event.caxis.value)) / JS_MAX);
if (val < JS_DEADZONE)
val = 0;
if (engine.event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX)
engine.xaxis = copysign(val, engine.event.caxis.value);
else if (engine.event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY)
engine.yaxis = copysign(val, engine.event.caxis.value);
}
break;
case SDL_WINDOWEVENT:
if (engine.event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
{