This patch is against FCE Ultra 0.97.5. I doubt that it will work with modern FCEU. njk diff -urN fceu/drivers/cli/sdl-joystick.c fceu-dev/drivers/cli/sdl-joystick.c --- fceu/drivers/cli/sdl-joystick.c Mon Nov 10 12:59:55 2003 +++ fceu-dev/drivers/cli/sdl-joystick.c Tue Nov 25 08:10:46 2003 @@ -3,7 +3,8 @@ * Copyright notice for this file: * Copyright (C) 2002 Xodnizel * Copyright (C) 2002 Paul Kuliniewicz - * + * Copyright (C) 2003 Nicholas Kain + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -20,6 +21,7 @@ */ /* PK: SDL joystick input stuff */ +/* NK: Significantly improved and generalized support. */ #include #include @@ -50,39 +52,46 @@ Sint16 pos; /* axis position */ uint32 ret = 0; /* return value */ - - if(joy[0]|joy[1]|joy[2]|joy[3]) - SDL_JoystickUpdate(); + if(joy[0]|joy[1]|joy[2]|joy[3]) SDL_JoystickUpdate(); rtoggle^=1; - for (n = 0; n < 4; n++) - { + + for (n = 0; n < 4; n++) { if (joy[n] == 0) continue; joym = joyBMap[n]; - /* Axis information. */ - pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][0]); - if (pos <= -16383) - ret |= JOY_LEFT << (n << 3); - else if (pos >= 16363) - ret |= JOY_RIGHT << (n << 3); - pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][1]); - if (pos <= -16383) - ret |= JOY_UP << (n << 3); - else if (pos >= 16383) - ret |= JOY_DOWN << (n << 3); + if (joy_aorb[n] == 0) { + /* Axis information. */ + pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][0]); + if (pos <= -16383) + ret |= JOY_LEFT << (n << 3); + else if (pos >= 16363) + ret |= JOY_RIGHT << (n << 3); + pos = SDL_JoystickGetAxis(jo[n], joyAMap[n][1]); + if (pos <= -16383) + ret |= JOY_UP << (n << 3); + else if (pos >= 16383) + ret |= JOY_DOWN << (n << 3); + } else { + if (SDL_JoystickGetButton(jo[n],joyABMap[n][0]) == SDL_PRESSED) + ret |= JOY_UP << (n << 3); + if (SDL_JoystickGetButton(jo[n],joyABMap[n][1]) == SDL_PRESSED) + ret |= JOY_DOWN << (n << 3); + if (SDL_JoystickGetButton(jo[n],joyABMap[n][2]) == SDL_PRESSED) + ret |= JOY_LEFT << (n << 3); + if (SDL_JoystickGetButton(jo[n],joyABMap[n][3]) == SDL_PRESSED) + ret |= JOY_RIGHT << (n << 3); + } /* Button information. */ - for (b = 0; b < 6; b++) - { - if(joym[b]) - if((b>=4 && rtoggle) || b<4) - if (SDL_JoystickGetButton(jo[n], joym[b]-1)) - ret |= (1 << (b&3)) << (n << 3); + for (b = 0; b < 6; b++) { + if(joym[b]) if((b>=4 && rtoggle) || b<4) + if (SDL_JoystickGetButton(jo[n], joym[b]) + == SDL_PRESSED) + ret |= (1 << (b&3)) << (n << 3); } } - return ret; } @@ -91,11 +100,7 @@ { int n; /* joystick index */ - for (n = 0; n < 4; n++) - { - if (joy[n] != 0) - SDL_JoystickClose(jo[n]); - } + for (n = 0; n < 4; n++) if (joy[n] != 0) SDL_JoystickClose(jo[n]); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); return; } @@ -105,26 +110,25 @@ { int n; /* joystick index */ - if(!(joy[0]|joy[1]|joy[2]|joy[3])) - return(0); + if(!(joy[0]|joy[1]|joy[2]|joy[3])) return(0); SDL_InitSubSystem(SDL_INIT_JOYSTICK); - for (n = 0; n < 4; n++) - { - if (joy[n] == 0) - continue; - - /* Open the joystick under SDL. */ + for (n = 0; n < SDL_NumJoysticks() && n < 4; n++) { + if (joy[n] == 0) continue; + + /* Open the joystick under SDL. */ jo[n] = SDL_JoystickOpen(joy[n] - 1); - if (jo[n] == NULL) - { + if (jo[n] == NULL) { printf("Could not open joystick %d: %s.\n", joy[n] - 1, SDL_GetError()); joy[n] = 0; continue; } - printf("Physical Joystick #%d: %d axes, %d buttons\n", n+1, SDL_JoystickNumAxes(jo[n]), SDL_JoystickNumButtons(jo[n])); - /* Check for a button map. */ + printf("Physical Joystick #%d: %d axes, %d buttons\n", n+1, + SDL_JoystickNumAxes(jo[n]), + SDL_JoystickNumButtons(jo[n])); + + /* Check for a button map. */ if (!(joyBMap[n][0]|joyBMap[n][1]|joyBMap[n][2]|joyBMap[n][3])) { ConfigJoystick(n); @@ -134,97 +138,99 @@ return (1); } -static void WNoInput(void) -{ - uint8 t; - while(read(fileno(stdin),&t,1)!=-1); -} - /* Configure a joystick axis. */ -void AConfig (int n, int a) +void AConfig (int n) { - Sint16 lastaxe[64]; - int numaxes; - int axis; - - WNoInput(); - - joyAMap[n][a] = a; - - numaxes=SDL_JoystickNumAxes(jo[n]); - if(numaxes>64) numaxes=64; - - for(axis=0;axis 15 || + event.jaxis.which != joy[n] - 1) break; - - SDL_JoystickUpdate(); + axis[event.jaxis.axis]++; + if (axis[event.jaxis.axis] > 25) done = 1; + break; + case SDL_JOYBUTTONDOWN: + if (event.jbutton.which == joy[n] - 1) { + done = 2; + break; + } + break; + case SDL_QUIT: + done = 1; + break; + } + } + } - for (axis=0;axis 8192) { - joyAMap[n][a] = axis; - /* 4096 should be good enough to account for any jitter. */ - while (abs((Sint32)SDL_JoystickGetAxis(jo[n],axis)-lastaxe[axis]) > 4096) { - SDL_JoystickUpdate(); - SDL_Delay(50); - } - goto endaconfig; - } - } - SDL_Delay(100); + if (done == 2) { + joy_aorb[n] = 1; + return; + } + + /* Store the two axes that occur most often. */ + for (i=0, xn=0, xv=0, yn=0, yv=0; i<16; i++) { + if (axis[i] > yv) { + xn = yn; + xv = yv; + yn = i; + yv = axis[i]; + continue; } + if (axis[i] > xv) { + xn = i; + xv = axis[i]; + continue; + } + } - endaconfig: - WNoInput(); - return; + /* Assume that x-axis is of lower number than y-axis; should + * be true for any sane device. */ + if (xn > yn) { + xv = xn; + xn = yn; + yn = xv; + } + + printf("Detected x-axis as %d and y-axis as %d.\n", xn, yn); + + joyAMap[n][0] = xn; + joyAMap[n][1] = yn; } /* Configure a joystick button. */ -void BConfig (int n, int b) +void BConfig (int n, int *b) { - WNoInput(); - joyBMap[n][b] = 0; - while (1) - { - uint8 t; - if (read(fileno(stdin), &t, 1) == -1) - { - if (errno != EAGAIN) - break; - } - else - break; - - SDL_JoystickUpdate(); - { - int buttons; - for (buttons = SDL_JoystickNumButtons(jo[n])-1;buttons >= 0;buttons--) { - if (SDL_JoystickGetButton(jo[n],buttons)) { - joyBMap[n][b] = buttons+1; - while (SDL_JoystickGetButton(jo[n], buttons)) { - SDL_JoystickUpdate(); - SDL_Delay(50); - } - goto endbconfig; - } - } - } - SDL_Delay(100); - } + int done = 0, btn = 0; + SDL_Event event; - endbconfig: - WNoInput(); - return; + *b = btn; + + while (!done) { + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_JOYBUTTONDOWN: + if (event.jbutton.which != joy[n] - 1) + break; + btn = event.jbutton.button; + case SDL_QUIT: + done = 1; + break; + } + } + } + *b = btn; } /* Joystick button and axis configuration. */ @@ -243,31 +249,41 @@ printf("**** Configuring joystick %d ****\n\n", n + 1); sa = fcntl(fileno(stdin), F_GETFL); - fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + + AConfig(n); - printf("** Move axis to use for the x-axis (default 0).\n"); - AConfig(n,0); + if (joy_aorb[n] == 1) { + printf("** Press button for \"Up\".\n"); + BConfig(n, &(joyABMap[n][0])); - printf("** Move axis to use for the y-axis (default 1).\n"); - AConfig(n,1); + printf("** Press button for \"Down\".\n"); + BConfig(n, &(joyABMap[n][1])); + printf("** Press button for \"Left\".\n"); + BConfig(n, &(joyABMap[n][2])); + + printf("** Press button for \"Right\".\n"); + BConfig(n, &(joyABMap[n][3])); + } + printf("** Press button for \"Select\".\n"); - BConfig(n, 2); + BConfig(n, &(joyBMap[n][2])); printf("** Press button for \"Start\".\n"); - BConfig(n, 3); + BConfig(n, &(joyBMap[n][3])); printf("** Press button for \"B\".\n"); - BConfig(n, 1); + BConfig(n, &(joyBMap[n][1])); printf("** Press button for \"A\".\n"); - BConfig(n, 0); + BConfig(n, &(joyBMap[n][0])); - printf("** Press button for rapid fire \"B\".\n"); - BConfig(n, 5); + printf("** Press button for rapid fire \"B\".\n"); + BConfig(n, &(joyBMap[n][5])); - printf("** Press button for rapid fire \"A\".\n"); - BConfig(n, 4); + printf("** Press button for rapid fire \"A\".\n"); + BConfig(n, &(joyBMap[n][4])); fcntl(fileno(stdin), F_SETFL, sa); } diff -urN fceu/drivers/cli/sdl.c fceu-dev/drivers/cli/sdl.c --- fceu/drivers/cli/sdl.c Sun Nov 9 22:33:13 2003 +++ fceu-dev/drivers/cli/sdl.c Tue Nov 25 06:58:37 2003 @@ -32,6 +32,8 @@ AC(_fullscreen), AC(_xres), AC(_yres), + ACA(joyABMap), + ACA(joy_aorb), ACA(joyBMap), ACA(joyAMap), ACA(joy), @@ -162,6 +164,8 @@ { memset(joyBMap[x],0,sizeof(joyBMap[0])); memset(joyAMap[x],0,sizeof(joyAMap[0])); + memset(joyABMap[x],0,sizeof(joyABMap[0])); + joy_aorb[x] = 0; } } diff -urN fceu/drivers/cli/sdl.h fceu-dev/drivers/cli/sdl.h --- fceu/drivers/cli/sdl.h Sun Nov 9 22:33:13 2003 +++ fceu-dev/drivers/cli/sdl.h Tue Nov 25 06:58:37 2003 @@ -18,6 +18,8 @@ int joy[4]; int joyAMap[4][2]; int joyBMap[4][6]; + int joy_aorb[4]; + int joyABMap[4][4]; char *fshack; char *fshacksave; #ifdef OPENGL @@ -54,4 +56,6 @@ #define joyAMap Settings.joyAMap #define joyBMap Settings.joyBMap +#define joyABMap Settings.joyABMap +#define joy_aorb Settings.joy_aorb #define joy Settings.joy