--- hatari/src/gui-sdl/dlgJoystick.c 2019/04/01 07:11:38 1.1 +++ hatari/src/gui-sdl/dlgJoystick.c 2019/04/09 08:53:28 1.1.1.10 @@ -1,10 +1,10 @@ /* Hatari - dlgJoystick.c - This file is distributed under the GNU Public License, version 2 or at - your option any later version. Read the file gpl.txt for details. + This file is distributed under the GNU General Public License, version 2 + or at your option any later version. Read the file gpl.txt for details. */ -char DlgJoystick_rcsid[] = "Hatari $Id: dlgJoystick.c,v 1.1 2019/04/01 07:11:38 root Exp $"; +const char DlgJoystick_fileid[] = "Hatari dlgJoystick.c : " __DATE__ " " __TIME__; #include "main.h" #include "configuration.h" @@ -12,72 +12,253 @@ char DlgJoystick_rcsid[] = "Hatari $Id: #include "sdlgui.h" -#define DLGJOY_J1CURSOR 4 -#define DLGJOY_J1AUTOFIRE 5 -#define DLGJOY_J0CURSOR 8 -#define DLGJOY_J0AUTOFIRE 9 -#define DLGJOY_EXIT 10 +#define DLGJOY_DISABLED 3 +#define DLGJOY_USEREALJOY 4 +#define DLGJOY_USEKEYS 5 +#define DLGJOY_DEFINEKEYS 6 +#define DLGJOY_SDLJOYNAME 8 +#define DLGJOY_PREVSDLJOY 9 +#define DLGJOY_NEXTSDLJOY 10 +#define DLGJOY_AUTOFIRE 11 +#define DLGJOY_STJOYNAME 13 +#define DLGJOY_PREVSTJOY 14 +#define DLGJOY_NEXTSTJOY 15 +#define DLGJOY_EXIT 16 /* The joysticks dialog: */ -static SGOBJ joystickdlg[] = + +static char sSdlStickName[20]; + +static SGOBJ joydlg[] = { - { SGBOX, 0, 0, 0,0, 30,19, NULL }, - { SGTEXT, 0, 0, 7,1, 15,1, "Joysticks setup" }, - { SGBOX, 0, 0, 1,3, 28,6, NULL }, - { SGTEXT, 0, 0, 2,4, 11,1, "Joystick 1:" }, - { SGCHECKBOX, 0, 0, 5,6, 22,1, "Use cursor emulation" }, - { SGCHECKBOX, 0, 0, 5,7, 17,1, "Enable autofire" }, - { SGBOX, 0, 0, 1,10, 28,6, NULL }, - { SGTEXT, 0, 0, 2,11, 11,1, "Joystick 0:" }, - { SGCHECKBOX, 0, 0, 5,13, 22,1, "Use cursor emulation" }, - { SGCHECKBOX, 0, 0, 5,14, 17,1, "Enable autofire" }, - { SGBUTTON, 0, 0, 5,17, 20,1, "Back to main menu" }, - { -1, 0, 0, 0,0, 0,0, NULL } + { SGBOX, 0, 0, 0,0, 32,18, NULL }, + { SGTEXT, 0, 0, 8,1, 15,1, "Joysticks setup" }, + + { SGBOX, 0, 0, 1,4, 30,11, NULL }, + { SGRADIOBUT, 0, 0, 2,5, 10,1, "disabled" }, + { SGRADIOBUT, 0, 0, 2,9, 20,1, "use real joystick:" }, + { SGRADIOBUT, 0, 0, 2,7, 14,1, "use keyboard" }, + + { SGBUTTON, 0, 0, 19,7, 11,1, "Define keys" }, + { SGBOX, 0, 0, 5,11, 22,1, NULL }, + { SGTEXT, 0, 0, 6,11, 20,1, sSdlStickName }, + { SGBUTTON, 0, 0, 4,11, 1,1, "\x04" }, /* Arrow left */ + { SGBUTTON, 0, 0, 27,11, 1,1, "\x03" }, /* Arrow right */ + + { SGCHECKBOX, 0, 0, 2,13, 17,1, "Enable autofire" }, + + { SGBOX, 0, 0, 4,3, 24,1, NULL }, + { SGTEXT, 0, 0, 5,3, 22,1, NULL }, + { SGBUTTON, 0, 0, 1,3, 3,1, "\x04" }, /* Arrow left */ + { SGBUTTON, 0, 0, 28,3, 3,1, "\x03" }, /* Arrow right */ + + { SGBUTTON, SG_DEFAULT, 0, 6,16, 20,1, "Back to main menu" }, + { -1, 0, 0, 0,0, 0,0, NULL } +}; + + +/* The joystick keys setup dialog: */ + +static char sKeyInstruction[24]; +static char sKeyName[24]; + +static SGOBJ joykeysdlg[] = +{ + { SGBOX, 0, 0, 0,0, 28,5, NULL }, + { SGTEXT, 0, 0, 2,1, 24,1, sKeyInstruction }, + { SGTEXT, 0, 0, 2,3, 24,1, sKeyName }, + { -1, 0, 0, 0,0, 0,0, NULL } +}; + + +static char *sJoystickNames[JOYSTICK_COUNT] = +{ + "ST Joystick 0", + "ST Joystick 1", + "STE Joypad A", + "STE Joypad B", + "Parallel port stick 1", + "Parallel port stick 2" }; /*-----------------------------------------------------------------------*/ -/* - Show and process the joystick dialog. -*/ -void Dialog_JoyDlg(void) +/** + * Show dialogs for defining joystick keys and wait for a key press. + */ +static void DlgJoystick_DefineOneKey(char *pType, int *pKey) +{ + SDL_Event sdlEvent; + + if (bQuitProgram) + return; + + snprintf(sKeyInstruction, sizeof(sKeyInstruction), "Press key for '%s'...", pType); + snprintf(sKeyName, sizeof(sKeyName), "(was: '%s')", SDL_GetKeyName(*pKey)); + + SDLGui_DrawDialog(joykeysdlg); + + do + { + SDL_WaitEvent(&sdlEvent); + if (sdlEvent.type == SDL_KEYDOWN) + { + *pKey = sdlEvent.key.keysym.sym; + snprintf(sKeyName, sizeof(sKeyName), "(now: '%s')", SDL_GetKeyName(*pKey)); + SDLGui_DrawDialog(joykeysdlg); + } + else if (sdlEvent.type == SDL_QUIT) + { + bQuitProgram = true; + return; + } + } while (sdlEvent.type != SDL_KEYUP); + SDL_Delay(200); +} + + +/*-----------------------------------------------------------------------*/ +/** + * Let the user define joystick keys. + */ +static void DlgJoystick_DefineKeys(int nActJoy) { - int but; - SDLGui_CenterDlg(joystickdlg); + SDLGui_CenterDlg(joykeysdlg); + DlgJoystick_DefineOneKey("up", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeUp); + DlgJoystick_DefineOneKey("down", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeDown); + DlgJoystick_DefineOneKey("left", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeLeft); + DlgJoystick_DefineOneKey("right", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeRight); + DlgJoystick_DefineOneKey("fire", &ConfigureParams.Joysticks.Joy[nActJoy].nKeyCodeFire); +} + + +/*-----------------------------------------------------------------------*/ +/** + * Adapt dialog using the values from the configration structure. + */ +static void DlgJoystick_ReadValuesFromConf(int nActJoy, int nMaxId) +{ + int i; + + /* Check if joystick ID is available */ + if (SDL_NumJoysticks() == 0) + { + strcpy(sSdlStickName, "0: (none available)"); + } + else if (ConfigureParams.Joysticks.Joy[nActJoy].nJoyId <= nMaxId) + { + snprintf(sSdlStickName, 20, "%i: %s", ConfigureParams.Joysticks.Joy[nActJoy].nJoyId, + SDL_JoystickName(ConfigureParams.Joysticks.Joy[nActJoy].nJoyId)); + } + else + { + snprintf(sSdlStickName, 20, "0: %s", SDL_JoystickName(0)); + /* Unavailable joystick ID -> disable it if necessary*/ + if (ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode == JOYSTICK_REALSTICK) + ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode = JOYSTICK_DISABLED; + } + + for (i = DLGJOY_DISABLED; i <= DLGJOY_USEKEYS; i++) + joydlg[i].state &= ~SG_SELECTED; + joydlg[DLGJOY_DISABLED + ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode].state |= SG_SELECTED; + + if (ConfigureParams.Joysticks.Joy[nActJoy].bEnableAutoFire) + joydlg[DLGJOY_AUTOFIRE].state |= SG_SELECTED; + else + joydlg[DLGJOY_AUTOFIRE].state &= ~SG_SELECTED; +} - /* Set up dialog from actual values: */ - if( DialogParams.Joysticks.Joy[1].bCursorEmulation ) - joystickdlg[DLGJOY_J1CURSOR].state |= SG_SELECTED; - else - joystickdlg[DLGJOY_J1CURSOR].state &= ~SG_SELECTED; - - if( DialogParams.Joysticks.Joy[1].bEnableAutoFire ) - joystickdlg[DLGJOY_J1AUTOFIRE].state |= SG_SELECTED; - else - joystickdlg[DLGJOY_J1AUTOFIRE].state &= ~SG_SELECTED; - - if( DialogParams.Joysticks.Joy[0].bCursorEmulation ) - joystickdlg[DLGJOY_J0CURSOR].state |= SG_SELECTED; - else - joystickdlg[DLGJOY_J0CURSOR].state &= ~SG_SELECTED; - - if( DialogParams.Joysticks.Joy[0].bEnableAutoFire ) - joystickdlg[DLGJOY_J0AUTOFIRE].state |= SG_SELECTED; - else - joystickdlg[DLGJOY_J0AUTOFIRE].state &= ~SG_SELECTED; - - do - { - but = SDLGui_DoDialog(joystickdlg); - } - while( but!=DLGJOY_EXIT && !bQuitProgram ); - - /* Read values from dialog */ - DialogParams.Joysticks.Joy[1].bCursorEmulation = (joystickdlg[DLGJOY_J1CURSOR].state & SG_SELECTED); - DialogParams.Joysticks.Joy[1].bEnableAutoFire = (joystickdlg[DLGJOY_J1AUTOFIRE].state & SG_SELECTED); - DialogParams.Joysticks.Joy[0].bCursorEmulation = (joystickdlg[DLGJOY_J0CURSOR].state & SG_SELECTED); - DialogParams.Joysticks.Joy[0].bEnableAutoFire = (joystickdlg[DLGJOY_J0AUTOFIRE].state & SG_SELECTED); +/*-----------------------------------------------------------------------*/ +/** + * Read values from dialog and write them to the configuration structure. + */ +static void DlgJoystick_WriteValuesToConf(int nActJoy) +{ + JOYSTICKMODE jmi; + for (jmi = JOYSTICK_DISABLED; jmi <= JOYSTICK_KEYBOARD; jmi++) + { + if (joydlg[jmi + DLGJOY_DISABLED].state & SG_SELECTED) + { + ConfigureParams.Joysticks.Joy[nActJoy].nJoystickMode = jmi; + break; + } + } + + ConfigureParams.Joysticks.Joy[nActJoy].bEnableAutoFire = (joydlg[DLGJOY_AUTOFIRE].state & SG_SELECTED); + ConfigureParams.Joysticks.Joy[nActJoy].nJoyId = joydlg[DLGJOY_SDLJOYNAME].txt[0] - '0'; +} + + +/*-----------------------------------------------------------------------*/ +/** + * Show and process the joystick dialog. + */ +void Dialog_JoyDlg(void) +{ + int but; + static int nActJoy = 1; + int nMaxJoyId; + + SDLGui_CenterDlg(joydlg); + + joydlg[DLGJOY_STJOYNAME].txt = sJoystickNames[nActJoy]; + + nMaxJoyId = SDL_NumJoysticks() - 1; + if (nMaxJoyId > 5) + nMaxJoyId = 5; + + /* Set up dialog from actual values: */ + DlgJoystick_ReadValuesFromConf(nActJoy, nMaxJoyId); + + do + { + but = SDLGui_DoDialog(joydlg, NULL); + switch (but) + { + case DLGJOY_PREVSDLJOY: // Select the previous SDL joystick + if (ConfigureParams.Joysticks.Joy[nActJoy].nJoyId > 0) + { + ConfigureParams.Joysticks.Joy[nActJoy].nJoyId -= 1; + snprintf(sSdlStickName, 20, "%i: %s", ConfigureParams.Joysticks.Joy[nActJoy].nJoyId, + SDL_JoystickName(ConfigureParams.Joysticks.Joy[nActJoy].nJoyId)); + } + break; + case DLGJOY_NEXTSDLJOY: // Select the next SDL joystick + if (ConfigureParams.Joysticks.Joy[nActJoy].nJoyId < nMaxJoyId) + { + ConfigureParams.Joysticks.Joy[nActJoy].nJoyId += 1; + snprintf(sSdlStickName, 20, "%i: %s", ConfigureParams.Joysticks.Joy[nActJoy].nJoyId, + SDL_JoystickName(ConfigureParams.Joysticks.Joy[nActJoy].nJoyId)); + } + break; + case DLGJOY_DEFINEKEYS: // Define new keys for keyboard emulation + DlgJoystick_DefineKeys(nActJoy); + break; + case DLGJOY_PREVSTJOY: // Switch to the previous ST joystick setup tab + if (nActJoy > 0) + { + DlgJoystick_WriteValuesToConf(nActJoy); + nActJoy -= 1; + DlgJoystick_ReadValuesFromConf(nActJoy, nMaxJoyId); + joydlg[DLGJOY_STJOYNAME].txt = sJoystickNames[nActJoy]; + } + break; + case DLGJOY_NEXTSTJOY: // Switch to the next ST joystick setup tab + if (nActJoy < 5) + { + DlgJoystick_WriteValuesToConf(nActJoy); + nActJoy += 1; + DlgJoystick_ReadValuesFromConf(nActJoy, nMaxJoyId); + joydlg[DLGJOY_STJOYNAME].txt = sJoystickNames[nActJoy]; + } + break; + } + } + while (but != DLGJOY_EXIT && but != SDLGUI_QUIT + && but != SDLGUI_ERROR && !bQuitProgram); + + DlgJoystick_WriteValuesToConf(nActJoy); }