Re: [hatari-devel] Joystick buttons config and sdl gui patches

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi Robin,

Patches look fine for me too, but GUI needs descriptions for the buttons.

Attached patch adds that, generalizes mapping handling a bit by using array instead of separate variables, and notes the change in docs (manual not yet updated).

Does it work OK for you?


	- Eero

On 30.7.2023 11.46, Robin Sergeant wrote:
Hi,

Please find the attached patches.  The first just adds the config as
before, but with checks to allow for undefined buttons (with negative
indexes).

The second adds a "Remap joystick buttons" button to the sdl joystick
dialog.  This behaves like the existing "Define keys" button.  The
user is guided to press each of the 3 buttons, but can also press the
ESC key for none (which results in a value of -1 being stored and the
button being ignored).   The dialog looks like this:

--------------------------------
Press joystick button 1
or ESC for none...

(was: id 3)
--------------------------------

And then after pressing button 0 (but before releasing):

--------------------------------
Press joystick button 1
or ESC for none...

(now: id 0)
--------------------------------

So as I said, basically consistent with how "Define keys" currently works.

Does this look ok, and can the patches be included?  Obviously happy
to make any further tweaks or change the UI etc.  I should probably
have sent the proposal first, but I got carried away with the coding
and wanted to figure out how the dialogs worked :-)

Any feedback welcome!

Cheers,

Robin.
From 4c49d5880857b0e6b41e304360a4499b5c5acc90 Mon Sep 17 00:00:00 2001
From: Eero Tamminen <oak@xxxxxxxxxxxxxx>
Date: Mon, 7 Aug 2023 11:43:23 +0300
Subject: [PATCH] Add button descriptions and generalize joystick mapping code

By using button mapping array instead of separate variables.

Also add notes of the changes to docs.
---
 doc/authors.txt              |  3 +++
 doc/release-notes.txt        |  1 +
 src/configuration.c          | 41 ++++++++++++++++++------------------
 src/gui-sdl/dlgJoystick.c    | 25 +++++++++++++++-------
 src/includes/configuration.h |  3 ++-
 src/joy.c                    | 23 +++++++-------------
 6 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/doc/authors.txt b/doc/authors.txt
index c41753e6..6f880009 100644
--- a/doc/authors.txt
+++ b/doc/authors.txt
@@ -171,6 +171,9 @@ random order - and if someone is missing here, please remind us!):
 - Chris Jenkins : patch to compile the macOS version when PortMidi is not 
   available.
 
+- Robin Sergeant <robin.sergeant at gmail.com> : support for remapping
+  joystick buttons
+
 See also "thanks.txt" for people who've helped Hatari development in
 other ways than code contributions.
 
diff --git a/doc/release-notes.txt b/doc/release-notes.txt
index f29aa6a5..f0cfc097 100644
--- a/doc/release-notes.txt
+++ b/doc/release-notes.txt
@@ -47,6 +47,7 @@ Emulator improvements:
     applications that do not handle current dates
 - Joystick support:
   - Fix: joystick button 2 space key emulation "autofiring"
+  - Support for mapping joystick buttons
 - GEMDOS HD:
   - Support up to 64 simultaneously open files (earlier limit was 32)
   - Similarly to TOS, allow programs to write to a file they have opened
diff --git a/src/configuration.c b/src/configuration.c
index e07b7327..09230026 100644
--- a/src/configuration.c
+++ b/src/configuration.c
@@ -108,9 +108,9 @@ static const struct Config_Tag configs_Joystick0[] =
 	{ "bEnableAutoFire", Bool_Tag, &ConfigureParams.Joysticks.Joy[0].bEnableAutoFire },
 	{ "bEnableJumpOnFire2", Bool_Tag, &ConfigureParams.Joysticks.Joy[0].bEnableJumpOnFire2 },
 	{ "nJoyId", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyId },
-	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyBut1Index },
-	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyBut2Index },
-	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyBut3Index },
+	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyButMap[0] },
+	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyButMap[1] },
+	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[0].nJoyButMap[2] },
 	{ "kUp", Key_Tag, &ConfigureParams.Joysticks.Joy[0].nKeyCodeUp },
 	{ "kDown", Key_Tag, &ConfigureParams.Joysticks.Joy[0].nKeyCodeDown },
 	{ "kLeft", Key_Tag, &ConfigureParams.Joysticks.Joy[0].nKeyCodeLeft },
@@ -126,9 +126,9 @@ static const struct Config_Tag configs_Joystick1[] =
 	{ "bEnableAutoFire", Bool_Tag, &ConfigureParams.Joysticks.Joy[1].bEnableAutoFire },
 	{ "bEnableJumpOnFire2", Bool_Tag, &ConfigureParams.Joysticks.Joy[1].bEnableJumpOnFire2 },
 	{ "nJoyId", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyId },
-	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyBut1Index },
-	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyBut2Index },
-	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyBut3Index },
+	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyButMap[0] },
+	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyButMap[1] },
+	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[1].nJoyButMap[2] },
 	{ "kUp", Key_Tag, &ConfigureParams.Joysticks.Joy[1].nKeyCodeUp },
 	{ "kDown", Key_Tag, &ConfigureParams.Joysticks.Joy[1].nKeyCodeDown },
 	{ "kLeft", Key_Tag, &ConfigureParams.Joysticks.Joy[1].nKeyCodeLeft },
@@ -144,9 +144,9 @@ static const struct Config_Tag configs_Joystick2[] =
 	{ "bEnableAutoFire", Bool_Tag, &ConfigureParams.Joysticks.Joy[2].bEnableAutoFire },
 	{ "bEnableJumpOnFire2", Bool_Tag, &ConfigureParams.Joysticks.Joy[2].bEnableJumpOnFire2 },
 	{ "nJoyId", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyId },
-	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyBut1Index },
-	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyBut2Index },
-	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyBut3Index },
+	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyButMap[0] },
+	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyButMap[1] },
+	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[2].nJoyButMap[2] },
 	{ "kUp", Key_Tag, &ConfigureParams.Joysticks.Joy[2].nKeyCodeUp },
 	{ "kDown", Key_Tag, &ConfigureParams.Joysticks.Joy[2].nKeyCodeDown },
 	{ "kLeft", Key_Tag, &ConfigureParams.Joysticks.Joy[2].nKeyCodeLeft },
@@ -162,9 +162,9 @@ static const struct Config_Tag configs_Joystick3[] =
 	{ "bEnableAutoFire", Bool_Tag, &ConfigureParams.Joysticks.Joy[3].bEnableAutoFire },
 	{ "bEnableJumpOnFire2", Bool_Tag, &ConfigureParams.Joysticks.Joy[3].bEnableJumpOnFire2 },
 	{ "nJoyId", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyId },
-	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyBut1Index },
-	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyBut2Index },
-	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyBut3Index },
+	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyButMap[0] },
+	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyButMap[1] },
+	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[3].nJoyButMap[2] },
 	{ "kUp", Key_Tag, &ConfigureParams.Joysticks.Joy[3].nKeyCodeUp },
 	{ "kDown", Key_Tag, &ConfigureParams.Joysticks.Joy[3].nKeyCodeDown },
 	{ "kLeft", Key_Tag, &ConfigureParams.Joysticks.Joy[3].nKeyCodeLeft },
@@ -180,9 +180,9 @@ static const struct Config_Tag configs_Joystick4[] =
 	{ "bEnableAutoFire", Bool_Tag, &ConfigureParams.Joysticks.Joy[4].bEnableAutoFire },
 	{ "bEnableJumpOnFire2", Bool_Tag, &ConfigureParams.Joysticks.Joy[4].bEnableJumpOnFire2 },
 	{ "nJoyId", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyId },
-	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyBut1Index },
-	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyBut2Index },
-	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyBut3Index },
+	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyButMap[0] },
+	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyButMap[1] },
+	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[4].nJoyButMap[2] },
 	{ "kUp", Key_Tag, &ConfigureParams.Joysticks.Joy[4].nKeyCodeUp },
 	{ "kDown", Key_Tag, &ConfigureParams.Joysticks.Joy[4].nKeyCodeDown },
 	{ "kLeft", Key_Tag, &ConfigureParams.Joysticks.Joy[4].nKeyCodeLeft },
@@ -198,9 +198,9 @@ static const struct Config_Tag configs_Joystick5[] =
 	{ "bEnableAutoFire", Bool_Tag, &ConfigureParams.Joysticks.Joy[5].bEnableAutoFire },
 	{ "bEnableJumpOnFire2", Bool_Tag, &ConfigureParams.Joysticks.Joy[5].bEnableJumpOnFire2 },
 	{ "nJoyId", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyId },
-	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyBut1Index },
-	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyBut2Index },
-	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyBut3Index },
+	{ "nJoyBut1Index", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyButMap[0] },
+	{ "nJoyBut2Index", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyButMap[1] },
+	{ "nJoyBut3Index", Int_Tag, &ConfigureParams.Joysticks.Joy[5].nJoyButMap[2] },
 	{ "kUp", Key_Tag, &ConfigureParams.Joysticks.Joy[5].nKeyCodeUp },
 	{ "kDown", Key_Tag, &ConfigureParams.Joysticks.Joy[5].nKeyCodeDown },
 	{ "kLeft", Key_Tag, &ConfigureParams.Joysticks.Joy[5].nKeyCodeLeft },
@@ -627,9 +627,8 @@ void Configuration_SetDefault(void)
 		ConfigureParams.Joysticks.Joy[i].bEnableAutoFire = false;
 		ConfigureParams.Joysticks.Joy[i].bEnableJumpOnFire2 = true;
 		ConfigureParams.Joysticks.Joy[i].nJoyId = (i > maxjoy ? maxjoy : i);
-		ConfigureParams.Joysticks.Joy[i].nJoyBut1Index = 0;
-		ConfigureParams.Joysticks.Joy[i].nJoyBut2Index = 1;
-		ConfigureParams.Joysticks.Joy[i].nJoyBut3Index = 2;
+		for (int j = 0; j < JOYSTICK_BUTTONS; j++)
+			ConfigureParams.Joysticks.Joy[i].nJoyButMap[j] = j;
 		ConfigureParams.Joysticks.Joy[i].nKeyCodeUp = SDLK_UP;
 		ConfigureParams.Joysticks.Joy[i].nKeyCodeDown = SDLK_DOWN;
 		ConfigureParams.Joysticks.Joy[i].nKeyCodeLeft = SDLK_LEFT;
diff --git a/src/gui-sdl/dlgJoystick.c b/src/gui-sdl/dlgJoystick.c
index bd31de5a..445c147e 100644
--- a/src/gui-sdl/dlgJoystick.c
+++ b/src/gui-sdl/dlgJoystick.c
@@ -11,6 +11,7 @@ const char DlgJoystick_fileid[] = "Hatari dlgJoystick.c";
 #include "dialog.h"
 #include "sdlgui.h"
 #include "joy.h"
+#include "str.h"
 
 #define DLGJOY_STJOYNAME     3
 #define DLGJOY_PREVSTJOY     4
@@ -83,9 +84,10 @@ static SGOBJ joykeysdlg[] =
 
 static SGOBJ joybuttondlg[] =
 {
-	{ SGBOX, 0, 0, 0,0, 27,7, NULL },
-	{ SGTEXT, 0, 0, 2,1, 23,1, sKeyInstruction },
-	{ SGTEXT, 0, 0, 2,2, 23,1, "or ESC for none..." },
+	{ SGBOX, 0, 0, 0,0, 25,7, NULL },
+	{ SGTEXT, 0, 0, 2,1, 23,1, "Press joystick button" },
+	{ SGTEXT, 0, 0, 5,2, 18,1, sKeyInstruction },
+	{ SGTEXT, 0, 0, 2,3, 23,1, "or ESC for none..." },
 	{ SGTEXT, 0, 0, 2,5, 15,1, sKeyName },
 	{ SGSTOP, 0, 0, 0,0, 0,0, NULL }
 };
@@ -165,7 +167,7 @@ static void DlgJoystick_DefineKeys(int nActJoy)
 /**
  * Show dialogs for remapping joystick buttons and wait for a button press.
  */
-static void DlgJoystick_MapOneButton(int button, int *pButton)
+static void DlgJoystick_MapOneButton(const char *name, int *pButton)
 {
 	SDL_Event sdlEvent;
 	bool bDone = false;
@@ -173,7 +175,7 @@ static void DlgJoystick_MapOneButton(int button, int *pButton)
 	if (bQuitProgram)
 		return;
 
-	snprintf(sKeyInstruction, sizeof(sKeyInstruction), "Press joystick button %d", button);
+	Str_Copy(sKeyInstruction, name, sizeof(sKeyInstruction));
 	if (*pButton >= 0)
 	{
 		snprintf(sKeyName, sizeof(sKeyName), "(was: id %d)", *pButton);
@@ -227,11 +229,18 @@ static void DlgJoystick_MapOneButton(int button, int *pButton)
  */
 static void DlgJoystick_RemapButtons(int nActJoy)
 {
+	int *map = ConfigureParams.Joysticks.Joy[nActJoy].nJoyButMap;
+	const char *names[JOYSTICK_BUTTONS] =
+	{
+		"1: fire",
+		"2: space / jump",
+		"3: autofire"
+	};
+	int i;
 
 	SDLGui_CenterDlg(joybuttondlg);
-	DlgJoystick_MapOneButton(1, &ConfigureParams.Joysticks.Joy[nActJoy].nJoyBut1Index);
-	DlgJoystick_MapOneButton(2, &ConfigureParams.Joysticks.Joy[nActJoy].nJoyBut2Index);
-	DlgJoystick_MapOneButton(3, &ConfigureParams.Joysticks.Joy[nActJoy].nJoyBut3Index);
+	for (i = 0; i < JOYSTICK_BUTTONS; i++)
+		DlgJoystick_MapOneButton(names[i], &map[i]);
 }
 
 
diff --git a/src/includes/configuration.h b/src/includes/configuration.h
index fa92760a..0b6976c5 100644
--- a/src/includes/configuration.h
+++ b/src/includes/configuration.h
@@ -162,6 +162,7 @@ typedef enum
   JOYSTICK_KEYBOARD
 } JOYSTICKMODE;
 #define JOYSTICK_MODES 3
+#define JOYSTICK_BUTTONS 3
 
 typedef struct
 {
@@ -169,7 +170,7 @@ typedef struct
   bool bEnableAutoFire;
   bool bEnableJumpOnFire2;
   int nJoyId;
-  int nJoyBut1Index, nJoyBut2Index, nJoyBut3Index;
+  int nJoyButMap[JOYSTICK_BUTTONS];
   int nKeyCodeUp, nKeyCodeDown, nKeyCodeLeft, nKeyCodeRight, nKeyCodeFire;
 } JOYSTICK;
 
diff --git a/src/joy.c b/src/joy.c
index bc4360f0..037a5018 100644
--- a/src/joy.c
+++ b/src/joy.c
@@ -197,9 +197,6 @@ void Joy_UnInit(void)
 static bool Joy_ReadJoystick(int nStJoyId, JOYREADING *pJoyReading)
 {
 	int nSdlJoyID = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyId;
-	int button1 = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyBut1Index;
-	int button2 = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyBut2Index;
-	int button3 = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyBut3Index;
 	unsigned hat = SDL_JoystickGetHat(sdlJoystick[nSdlJoyID], 0);
 
 	/* Joystick is OK, read position from the configured joystick axis */
@@ -214,19 +211,15 @@ static bool Joy_ReadJoystick(int nStJoyId, JOYREADING *pJoyReading)
 		pJoyReading->YPos = -32768;
 	if (hat & SDL_HAT_DOWN)
 		pJoyReading->YPos = 32767;
-	/* Sets bit #0 if button #1 is pressed: */
-	if (button1 >= 0)
-		pJoyReading->Buttons = SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], button1);
-	else
-		pJoyReading->Buttons = 0;
-
-	/* Sets bit #1 if button #2 is pressed: */
-	if ((button2 >= 0) && SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], button2))
-		pJoyReading->Buttons |= JOYREADING_BUTTON2;
-	/* Sets bit #2 if button #3 is pressed: */
-	if ((button3 >= 0) && SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], button3))
-		pJoyReading->Buttons |= JOYREADING_BUTTON3;
 
+	pJoyReading->Buttons = 0;
+	/* Sets bits based on pressed buttons */
+	for (int i = 0; i < JOYSTICK_BUTTONS; i++)
+	{
+		int button = ConfigureParams.Joysticks.Joy[nStJoyId].nJoyButMap[i];
+		if (button >= 0 && SDL_JoystickGetButton(sdlJoystick[nSdlJoyID], button))
+			pJoyReading->Buttons |= 1 << i;
+	}
 	return true;
 }
 
-- 
2.39.2



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/