#include "GuiInputConfig.h" #include "GuiGameList.h" #include #include #include "../Log.h" extern bool DEBUG; //defined in main.cpp std::string GuiInputConfig::sInputs[] = { "UNKNOWN", "UP", "DOWN", "LEFT", "RIGHT", "BUTTON1 (Accept)", "BUTTON2 (Back)", "START (Menu)", "SELECT (Jump-to-letter)", "PAGE UP", "PAGE DOWN" }; //must be same order as InputManager::InputButton enum; only add to the end to preserve backwards compatibility int GuiInputConfig::sInputCount = 11; GuiInputConfig::GuiInputConfig() { mInputNum = 1; mDone = false; mLastAxis = -1; Renderer::registerComponent(this); InputManager::registerComponent(this); if(SDL_NumJoysticks() < 1) { std::cerr << "Error - GuiInputConfig found no SDL joysticks!\n"; mJoystick = NULL; mDone = true; return; }else{ LOG(LogInfo) << "Opening joystick \"" << SDL_JoystickName(0) << "\" for configuration..."; mJoystick = SDL_JoystickOpen(0); } } GuiInputConfig::~GuiInputConfig() { Renderer::unregisterComponent(this); InputManager::unregisterComponent(this); } void GuiInputConfig::onRender() { Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFFFF); Font* font = Renderer::getDefaultFont(Renderer::MEDIUM); int height = font->getHeight() + 6; Renderer::drawCenteredText("It looks like you have a joystick plugged in!", 0, 2, 0x000000FF, font); Renderer::drawCenteredText("POV hats (some D-Pads) are automatically mapped to directions.", 0, height, 0x000000FF, font); Renderer::drawCenteredText("You can press a keyboard key to skip any input.", 0, height * 2, 0x000000FF, font); Renderer::drawCenteredText("If you want to remap later, delete ~/.emulationstation/es_input.cfg.", 0, height * 3, 0x000000FF, font); Renderer::drawCenteredText("This interface only configures the first joystick plugged in.", 0, height * 4, 0x000000FF, font); Renderer::drawCenteredText("Remember - you'll need to set up your emulator separately!", 0, Renderer::getScreenHeight() - height, 0x000000FF, font); if(mDone) Renderer::drawCenteredText("All done! Press a key or button to save.", 0, height * 5, 0x00BB00FF, font); else Renderer::drawCenteredText("Please press the axis/button for " + sInputs[mInputNum], 0, height * 5, 0x00C000FF, font); } void GuiInputConfig::onInput(InputManager::InputButton button, bool keyDown) { if(mDone) { if(InputManager::lastEvent->type == SDL_KEYUP || InputManager::lastEvent->type == SDL_JOYBUTTONDOWN) { LOG(LogDebug) << " finishing configuration..."; writeConfig(); if(mJoystick) SDL_JoystickClose(mJoystick); LOG(LogDebug) << "Config complete. Closed joystick, loading input then opening GuiGameList."; InputManager::loadConfig(); delete this; GuiGameList::create(); } return; } SDL_Event* event = InputManager::lastEvent; if(event->type == SDL_KEYUP) { LOG(LogDebug) << " [KEYUP] (skipping)"; //keyboard key pressed; skip and continue mInputNum++; } if(event->type == SDL_JOYBUTTONDOWN) { LOG(LogDebug) << " [JOYBUTTONDOWN] button " << event->jbutton.button; mButtonMap[event->jbutton.button] = (InputManager::InputButton)mInputNum; LOG(LogInfo) << " Mapping " << sInputs[mInputNum] << " to button " << (int)event->jbutton.button; mInputNum++; } if(event->type == SDL_JOYAXISMOTION) { LOG(LogDebug) << " [JOYAXISMOTION] axis " << event->jaxis.axis << ", value " << event->jaxis.value; if(event->jaxis.axis == mLastAxis) { if(event->jaxis.value < InputManager::deadzone && event->jaxis.value > -InputManager::deadzone) mLastAxis = -1; return; } if(event->jaxis.value > InputManager::deadzone) { mAxisPosMap[event->jaxis.axis] = (InputManager::InputButton)mInputNum; mInputNum++; mLastAxis = event->jaxis.axis; LOG(LogInfo) << " Mapping " << sInputs[mInputNum - 1] << " to axis+ " << mLastAxis; }else if(event->jaxis.value < -InputManager::deadzone) { mAxisNegMap[event->jaxis.axis] = (InputManager::InputButton)mInputNum; mInputNum++; mLastAxis = event->jaxis.axis; LOG(LogInfo) << " Mapping " << sInputs[mInputNum - 1] << " to axis- " << mLastAxis; } } if(mInputNum >= sInputCount) { mDone = true; return; } } void GuiInputConfig::writeConfig() { LOG(LogDebug) << " Writing config..."; std::string path = InputManager::getConfigPath(); std::ofstream file(path.c_str()); if(SDL_JoystickName(0)) file << "JOYNAME " << SDL_JoystickName(0) << "\n"; typedef std::map::iterator it_type; for(it_type iter = mButtonMap.begin(); iter != mButtonMap.end(); iter++) { file << "BUTTON " << iter->first << " " << iter->second << "\n"; } for(it_type iter = mAxisPosMap.begin(); iter != mAxisPosMap.end(); iter++) { file << "AXISPOS " << iter->first << " " << iter->second << "\n"; } for(it_type iter = mAxisNegMap.begin(); iter != mAxisNegMap.end(); iter++) { file << "AXISNEG " << iter->first << " " << iter->second << "\n"; } file.close(); LOG(LogDebug) << " Write complete.\n"; }