diff --git a/control.cpp b/control.cpp index 0bc30e18..151f0fb9 100644 --- a/control.cpp +++ b/control.cpp @@ -234,8 +234,69 @@ EX void mousemovement() { } #if CAP_SDLJOY -EX SDL_Joystick* sticks[8]; -EX int numsticks; + +#if HDR +struct joydata { + SDL_Joystick *joy; + #if SDLVER >= 2 + SDL_GameController *gc; + #else + void *gc; + #endif + }; +#endif + +EX vector sticks; + +EX bool gjoy_button(joydata &jd, int button) { + #if SDLVER >= 2 + if(jd.gc) return SDL_GameControllerGetButton(jd.gc, (SDL_GameControllerButton) button); + #endif + return SDL_JoystickGetButton(jd.joy, button); + } + +EX bool gjoy_axis(joydata &jd, int axis) { + #if SDLVER >= 2 + if(jd.gc) return SDL_GameControllerGetAxis(jd.gc, (SDL_GameControllerAxis) axis); + #endif + return SDL_JoystickGetButton(jd.joy, axis); + } + +EX bool gjoy_myid(int instance_id) { + #if SDLVER >= 2 + for(int i=0; i= 2 + int id = gjoy_myid(instance_id); + if(id >= 0 && id < isize(sticks)) + return sticks[id].gc; + return false; + #else + return false; + #endif + } + +EX int gjoy_buttons(joydata& jd) { + #if SDLVER >= 2 + if(jd.gc) return (int) SDL_CONTROLLER_BUTTON_MAX; + #endif + return SDL_GetNumJoystickButtons(jd.joy); + } + +EX int gjoy_hats(joydata& jd) { + #if SDLVER >= 2 + if(jd.gc) return 0; + #endif + return SDL_GetNumJoystickHats(jd.joy); + } EX bool joysticks_initialized; @@ -264,24 +325,38 @@ EX debugflag debug_joy_error = {"joy_error"}; EX debugflag debug_joy = {"joy"}; EX void countJoysticks() { + #if SDLVER == 1 indenter_finish(debug_init_joy, "countJoysticks"); - #if SDLVER <= 2 - numsticks = SDL_NumJoysticks(); - #else - SDL_GetJoysticks(&numsticks); - #endif - if(numsticks > 8) numsticks = 8; + int numsticks = SDL_NumJoysticks(); + sticks.resize(numsticks); for(int i=0; i= 2 +EX void add_joystick(int which) { + if(SDL_IsGameController(which)) { + auto gc = SDL_GameControllerOpen(which); + sticks.emplace_back(joydata{SDL_GameControllerGetJoystick(gc), gc}); + } + else { + sticks.emplace_back(joydata{SDL_OpenJoystick(which), nullptr}); } } +EX void delete_joystick(int instance) { + for(int i=0; i= 2 + if(s.gc) SDL_GameControllerClose(s.gc); else + #endif + SDL_CloseJoystick(s.joy); } - numsticks = 0; + sticks.clear(); } int joytime; @@ -993,10 +1070,10 @@ EX void mainloopiter() { hiliteclick = keystate[SDLK_LALT] | keystate[SDLK_RALT]; #endif - if(defaultjoy) for(int i=0; i= 2 + if(ev.type == SDL_JOYDEVICEADDED) { + add_joystick(ev.jdevice.which); + } + + if(ev.type == SDL_JOYDEVICEREMOVED) { + delete_joystick(ev.jdevice.which); + } + #endif + #if SDLVER == 3 if(ev.type == SDL_EVENT_WINDOW_MOUSE_ENTER) outoffocus = false; if(ev.type == SDL_EVENT_WINDOW_MOUSE_LEAVE) outoffocus = true; @@ -1223,31 +1310,52 @@ EX void handle_event(SDL_Event& ev) { } #endif -#if CAP_SDLJOY +#if CAP_SDLJOY if(ev.type == SDL_EVENT_JOYSTICK_AXIS_MOTION && normal && DEFAULTCONTROL) { + if(gjoy_is_controller(ev.jaxis.which)) return; if(ev.jaxis.which == 0) { if(ev.jaxis.axis == 0) joyx = ev.jaxis.value; else if(ev.jaxis.axis == 1) joyy = ev.jaxis.value; - else if(ev.jaxis.axis == 3) - panjoyx = ev.jaxis.value; - else if(ev.jaxis.axis == 4) - panjoyy = ev.jaxis.value; checkjoy(); // printf("panjoy = %d,%d\n", panjoyx, panjoyy); } else { if(ev.jaxis.axis == 0) panjoyx = ev.jaxis.value; - else + else panjoyy = ev.jaxis.value; } } + + #if SDLVER >= 2 + if(ev.type == SDL_CONTROLLERAXISMOTION && normal && DEFAULTCONTROL) { + if(ev.caxis.which == 0) { + if(ev.caxis.axis == 0) + joyx = ev.caxis.value; + else if(ev.caxis.axis == 1) + joyy = ev.caxis.value; + else if(ev.caxis.axis == 3) + panjoyx = ev.caxis.value; + else if(ev.caxis.axis == 4) + panjoyy = ev.caxis.value; + checkjoy(); + // printf("panjoy = %d,%d\n", panjoyx, panjoyy); + } + else { + if(ev.caxis.axis == 0) + panjoyx = ev.caxis.value; + else + panjoyy = ev.caxis.value; + } + } + #endif if(joyhandler && joyhandler(ev)) ; else if(ev.type == SDL_EVENT_JOYSTICK_HAT_MOTION && !normal && defaultjoy) { + if(gjoy_is_controller(ev.jhat.which)) return; if(ev.jhat.value == SDL_HAT_UP) sym = SDLK_UP; if(ev.jhat.value == SDL_HAT_DOWN) sym = SDLK_DOWN; if(ev.jhat.value == SDL_HAT_LEFT) sym = SDLK_LEFT; @@ -1255,8 +1363,19 @@ EX void handle_event(SDL_Event& ev) { } else if(ev.type == SDL_EVENT_JOYSTICK_BUTTON_DOWN && defaultjoy) { - sym = uni = PSEUDOKEY_JOY + JOY_ID * ev.jbutton.which + ev.jbutton.button; + if(gjoy_is_controller(ev.jbutton.which)) return; + sym = uni = PSEUDOKEY_JOY + JOY_ID * gjoy_myid(ev.jbutton.which) + ev.jbutton.button; } + + #if SDLVER >= 2 + else if(ev.type == SDL_CONTROLLERBUTTONDOWN && defaultjoy) { + sym = uni = PSEUDOKEY_JOY + JOY_ID * gjoy_myid(ev.cbutton.which) + ev.cbutton.button; + if(ev.cbutton.which == SDL_CONTROLLER_BUTTON_DPAD_UP) sym = uni = SDLK_UP; + if(ev.cbutton.which == SDL_CONTROLLER_BUTTON_DPAD_DOWN) sym = uni = SDLK_DOWN; + if(ev.cbutton.which == SDL_CONTROLLER_BUTTON_DPAD_LEFT) sym = uni = SDLK_LEFT; + if(ev.cbutton.which == SDL_CONTROLLER_BUTTON_DPAD_RIGHT) sym = uni = SDLK_RIGHT; + } + #endif #endif if(ev.type == SDL_EVENT_KEY_DOWN) { diff --git a/multi.cpp b/multi.cpp index 8634a295..963d44d8 100644 --- a/multi.cpp +++ b/multi.cpp @@ -185,6 +185,14 @@ EX int centerplayer = -1; int* axeconfigs[24]; int numaxeconfigs; int* dzconfigs[24]; +vector controller_button_names = { + "Ⓐ", "Ⓑ", "Ⓧ", "Ⓨ", + "(back)", "(guide)", "(start)", "(left stick)", "(right stick)", + "(left shoulder)", "(right shoulder)", + "(up)", "(down)", "(left)", "(right)", + "(misc)", "(p1)", "(p2)", "(p3)", "(p4)", "(touchpad)" + }; + string listkeys(config& scfg, int id) { #if CAP_SDL string lk = ""; @@ -196,15 +204,22 @@ string listkeys(config& scfg, int id) { lk = lk + " " + SDL_GetKeyName(SDLKey(i)); #endif #if CAP_SDLJOY - for(int i=0; i= 2 + if(s.gc) lk = lk + " " + cts('A'+i) + "-" + controller_button_names[k]; + else + #endif + lk = lk + " " + cts('A'+i)+"-B"+its(k); } + for(int k=0; k= 2 + if(ev.type == SDL_CONTROLLERBUTTONDOWN && setwhat) { + int joyid = gjoy_myid(ev.cbutton.which); + int button = ev.cbutton.button; + if(joyid < 8 && button < 32) + which_config->joyaction[joyid][button] = setwhat; + setwhat = 0; + return true; + } + #endif + if(ev.type == SDL_EVENT_JOYSTICK_BUTTON_DOWN && setwhat) { + if(gjoy_is_controller(ev.jaxis.which)) return false; int joyid = ev.jbutton.which; int button = ev.jbutton.button; if(joyid < 8 && button < 32) @@ -305,6 +332,7 @@ struct key_configurer { } else if(ev.type == SDL_EVENT_JOYSTICK_HAT_MOTION && setwhat) { + if(gjoy_is_controller(ev.jaxis.which)) return false; int joyid = ev.jhat.which; int hat = ev.jhat.hat; int dir = 4; @@ -358,9 +386,10 @@ struct joy_configurer { dialog::init(); getcstat = ' '; numaxeconfigs = 0; - for(int j=0; j 0) { + if(sticks.size()) { if(shmup::on || multi::alwaysuse || players > 1) { dialog::addItem(XLAT("configure joystick axes"), 'x'); dialog::add_action_push(joy_configurer(players, scfg_default)); @@ -773,8 +803,8 @@ EX void initConfig() { scfg.axeaction[0][0] = 4; scfg.axeaction[0][1] = 5; - scfg.axeaction[0][2] = 2; - scfg.axeaction[0][3] = 3; + scfg.axeaction[0][3] = 2; + scfg.axeaction[0][4] = 3; scfg.axeaction[1][0] = 8; scfg.axeaction[1][1] = 9; @@ -854,27 +884,30 @@ EX void get_actions(config& scfg) { pressaction(scfg.keyaction[i]); #if CAP_SDLJOY - for(int j=0; j dz) value -= dz; else if(value < -dz) value += dz; else value = 0; axe_states[scfg.axeaction[j][b] % SHMUPAXES] += value; } + + j++; } #endif #endif