Merge pull request #245 from 0lvin/back_button_as_escape

Add support for use controller back button as ESC
This commit is contained in:
Yamagi 2017-10-22 18:19:56 +02:00 committed by GitHub
commit 7b6340ddff
6 changed files with 129 additions and 32 deletions

View file

@ -73,6 +73,7 @@ static qboolean mlooking;
static int joystick_yaw, joystick_pitch;
static int joystick_forwardmove, joystick_sidemove;
static int joystick_up;
static int back_button_id = -1;
static char last_hat = SDL_HAT_CENTERED;
static qboolean left_trigger = false;
static qboolean right_trigger = false;
@ -523,6 +524,15 @@ IN_Update(void)
#endif
break;
#if SDL_VERSION_ATLEAST(2, 0, 0)
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERBUTTONDOWN: /* Handle Controller Back button */
{
qboolean down = (event.type == SDL_CONTROLLERBUTTONDOWN);
if(event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) {
Key_Event(K_JOY_BACK, down, true);
}
}
break;
case SDL_CONTROLLERAXISMOTION: /* Handle Controller Motion */
{
char* direction_type;
@ -635,6 +645,9 @@ IN_Update(void)
case SDL_JOYBUTTONDOWN:
{
qboolean down = (event.type == SDL_JOYBUTTONDOWN);
/* Ignore back button, we dont need event for such button */
if (back_button_id == event.jbutton.button)
return;
if(event.jbutton.button <= (K_JOY32 - K_JOY1)) {
Key_Event(event.jbutton.button + K_JOY1, down, true);
}
@ -824,6 +837,11 @@ IN_MLookUp(void)
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
/*
* Shutdown haptic functionality
*/
static void IN_Haptic_Shutdown(void);
/* ------------------------------------------------------------------ */
/*
* Init haptic effects
@ -852,7 +870,9 @@ IN_Haptic_Effect_Init(int dir, int period, int magnitude, int length, int attack
effect_id = SDL_HapticNewEffect(joystick_haptic, &haptic_effect);
if (effect_id < 0)
{
Com_Printf ("SDL_HapticNewEffect failed: %s", SDL_GetError());
Com_Printf ("SDL_HapticNewEffect failed: %s\n", SDL_GetError());
Com_Printf ("Please try to rerun game. Effects will be disabled for now.\n");
IN_Haptic_Shutdown();
}
return effect_id;
}
@ -1006,7 +1026,7 @@ IN_Haptic_Effect_Shutdown(int * effect_id)
}
static void
IN_Haptic_Effects_Shotdown(void)
IN_Haptic_Effects_Shutdown(void)
{
for (int i=0; i<HAPTIC_EFFECT_LAST; i++)
{
@ -1030,7 +1050,7 @@ Haptic_Feedback(char *name)
if (last_haptic_volume != (int)(joy_haptic_magnitude->value * 255))
{
IN_Haptic_Effects_Shotdown();
IN_Haptic_Effects_Shutdown();
IN_Haptic_Effects_Init();
}
last_haptic_volume = joy_haptic_magnitude->value * 255;
@ -1217,6 +1237,7 @@ IN_Init(void)
if(SDL_IsGameController(i))
{
SDL_GameControllerButtonBind backBind;
controller = SDL_GameControllerOpen(i);
Com_Printf ("Controller settings: %s\n", SDL_GameControllerMapping(controller));
Com_Printf ("Controller axis: \n");
@ -1235,6 +1256,12 @@ IN_Init(void)
Com_Printf (" * triggerleft = %f\n", joy_axis_triggerleft_threshold->value);
Com_Printf (" * triggerright = %f\n", joy_axis_triggerright_threshold->value);
backBind = SDL_GameControllerGetBindForButton(controller, SDL_CONTROLLER_BUTTON_BACK);
if (backBind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
back_button_id = backBind.value.button;
Com_Printf ("\nBack button JOY%d will be unbindable.\n", back_button_id+1);
}
break;
}
else
@ -1244,7 +1271,7 @@ IN_Init(void)
guid = SDL_JoystickGetDeviceGUID(i);
SDL_JoystickGetGUIDString(guid, joystick_guid, 255);
Com_Printf ("For use joystic as game contoller please set SDL_GAMECONTROLLERCONFIG:\n");
Com_Printf ("e.g.: SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,...\n", joystick_guid, SDL_JoystickName(joystick));
Com_Printf ("e.g.: SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,back:b1,...\n", joystick_guid, SDL_JoystickName(joystick));
}
}
}
@ -1266,6 +1293,18 @@ IN_Init(void)
/*
* Shuts the backend down
*/
static void
IN_Haptic_Shutdown(void)
{
if (joystick_haptic)
{
IN_Haptic_Effects_Shutdown();
SDL_HapticClose(joystick_haptic);
joystick_haptic = NULL;
}
}
void
IN_Shutdown(void)
{
@ -1276,16 +1315,11 @@ IN_Shutdown(void)
Com_Printf("Shutting down input.\n");
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (joystick_haptic)
{
IN_Haptic_Effects_Shotdown();
SDL_HapticClose(joystick_haptic);
joystick_haptic = NULL;
}
IN_Haptic_Shutdown();
if (controller)
{
back_button_id = -1;
SDL_GameControllerClose(controller);
controller = NULL;
}

View file

@ -66,7 +66,7 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height)
byte *raw;
pcx_t *pcx;
int x, y;
int len;
int len, full_size;
int dataByte, runLength;
byte *out, *pix;
@ -75,7 +75,7 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height)
/* load the file */
len = FS_LoadFile(filename, (void **)&raw);
if (!raw)
if (!raw || len < sizeof(pcx_t))
{
return;
}
@ -95,7 +95,8 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height)
return;
}
out = Z_Malloc((pcx->ymax + 1) * (pcx->xmax + 1));
full_size = (pcx->ymax + 1) * (pcx->xmax + 1);
out = Z_Malloc(full_size);
*pic = out;
@ -135,7 +136,15 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height)
while (runLength-- > 0)
{
pix[x++] = dataByte;
if ((*pic + full_size) <= (pix + x))
{
x += runLength;
runLength = 0;
}
else
{
pix[x++] = dataByte;
}
}
}
}

View file

@ -147,6 +147,8 @@ keyname_t keynames[] = {
{"TRIG_LEFT", K_TRIG_LEFT},
{"TRIG_RIGHT", K_TRIG_RIGHT},
{"JOY_BACK", K_JOY_BACK},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
@ -756,7 +758,7 @@ Key_Bind_f(void)
}
/* don't allow binding escape or the special console keys */
if(b == K_ESCAPE || b == '^' || b == '`' || b == '~')
if(b == K_ESCAPE || b == '^' || b == '`' || b == '~' || b == K_JOY_BACK)
{
if(doneWithDefaultCfg)
{
@ -1102,12 +1104,12 @@ Key_Event(int key, qboolean down, qboolean special)
}
/* Key is unbound */
if ((key >= K_MOUSE1) && !keybindings[key] && (cls.key_dest != key_console))
if ((key >= K_MOUSE1 && key != K_JOY_BACK) && !keybindings[key] && (cls.key_dest != key_console))
{
Com_Printf("%s is unbound, hit F4 to set.\n", Key_KeynumToString(key));
}
/* While in attract loop all keys besides F1 to F12 (to
/* While in attract loop all keys besides F1 to F12 (to
allow quick load and the like) are treated like escape. */
if (cl.attractloop && (cls.key_dest != key_menu) &&
!((key >= K_F1) && (key <= K_F12)))
@ -1122,10 +1124,11 @@ Key_Event(int key, qboolean down, qboolean special)
- moves one menu level up
- closes the menu
- closes the help computer
- closes the chat window */
- closes the chat window
Fully same logic for K_JOY_BACK */
if (!cls.disable_screen)
{
if (key == K_ESCAPE)
if (key == K_ESCAPE || key == K_JOY_BACK)
{
if (!down)
{

View file

@ -152,6 +152,9 @@ enum QKEYS {
K_TRIG_LEFT,
K_TRIG_RIGHT,
/* Can't be mapped to any action */
K_JOY_BACK,
K_AUX1,
K_AUX2,
K_AUX3,

View file

@ -317,6 +317,10 @@ Key_GetMenuKey(int key)
case K_KP_ENTER:
case K_ENTER:
return K_ENTER;
case K_ESCAPE:
case K_JOY_BACK:
return K_ESCAPE;
}
return key;
@ -4317,7 +4321,8 @@ M_Menu_PlayerConfig_f(void)
static const char *
M_Quit_Key(int key)
{
switch (key)
int menu_key = Key_GetMenuKey(key);
switch (menu_key)
{
case K_ESCAPE:
case 'n':
@ -4325,6 +4330,7 @@ M_Quit_Key(int key)
M_PopMenu();
break;
case K_ENTER:
case 'Y':
case 'y':
cls.key_dest = key_console;

View file

@ -122,7 +122,9 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
byte *raw;
pcx_t *pcx;
int x, y;
int len;
int len, full_size;
int pcx_width, pcx_height;
qboolean image_issues = false;
int dataByte, runLength;
byte *out, *pix;
char filename[256];
@ -145,7 +147,7 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
/* load the file */
len = ri.FS_LoadFile(filename, (void **)&raw);
if (!raw)
if (!raw || len < sizeof(pcx_t))
{
R_Printf(PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
return;
@ -165,15 +167,19 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
raw = &pcx->data;
pcx_width = pcx->xmax - pcx->xmin;
pcx_height = pcx->ymax - pcx->ymin;
if ((pcx->manufacturer != 0x0a) || (pcx->version != 5) ||
(pcx->encoding != 1) || (pcx->bits_per_pixel != 8) ||
(pcx->xmax >= 640) || (pcx->ymax >= 480))
(pcx_width >= 4096) || (pcx_height >= 4096))
{
R_Printf(PRINT_ALL, "Bad pcx file %s\n", filename);
return;
}
out = malloc((pcx->ymax + 1) * (pcx->xmax + 1));
full_size = (pcx_height + 1) * (pcx_width + 1);
out = malloc(full_size);
*pic = out;
@ -182,28 +188,49 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
if (palette)
{
*palette = malloc(768);
memcpy(*palette, (byte *)pcx + len - 768, 768);
if (len > 768)
{
memcpy(*palette, (byte *)pcx + len - 768, 768);
}
else
{
image_issues = true;
}
}
if (width)
{
*width = pcx->xmax + 1;
*width = pcx_width + 1;
}
if (height)
{
*height = pcx->ymax + 1;
*height = pcx_height + 1;
}
for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1)
for (y = 0; y <= pcx_height; y++, pix += pcx_width + 1)
{
for (x = 0; x <= pcx->xmax; )
for (x = 0; x <= pcx_width; )
{
if (raw - (byte *)pcx > len)
{
// no place for read
image_issues = true;
x = pcx_width;
break;
}
dataByte = *raw++;
if ((dataByte & 0xC0) == 0xC0)
{
runLength = dataByte & 0x3F;
if (raw - (byte *)pcx > len)
{
// no place for read
image_issues = true;
x = pcx_width;
break;
}
dataByte = *raw++;
}
else
@ -213,7 +240,17 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
while (runLength-- > 0)
{
pix[x++] = dataByte;
if ((*pic + full_size) <= (pix + x))
{
// no place for write
image_issues = true;
x += runLength;
runLength = 0;
}
else
{
pix[x++] = dataByte;
}
}
}
}
@ -224,7 +261,7 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
free(*pic);
*pic = NULL;
}
else if(pcx->xmax == 319 && pcx->ymax == 239
else if(pcx_width == 319 && pcx_height == 239
&& Q_strcasecmp(origname, "pics/quit.pcx") == 0
&& Com_BlockChecksum(pcx, len) == 3329419434u)
{
@ -233,6 +270,11 @@ LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height)
fixQuitScreen(*pic);
}
if (image_issues)
{
R_Printf(PRINT_ALL, "PCX file %s has possible size issues.\n", filename);
}
ri.FS_FreeFile(pcx);
}