mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
Replaced Joystick:saveGamepadMapping with love.joystick.saveGamepadMappings, which saves all gamepad mappings from both recently-used joysticks and recently-modified mappings. saveGamepadMappings returns a string of newline-separated mappings and takes an optional filename argument which writes it to a file.
This commit is contained in:
@@ -88,15 +88,16 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Loads a newline-separated list of virtual Gamepad mapping strings for
|
* Loads a newline-separated list of virtual Gamepad mapping strings for
|
||||||
* multiple joysticks at a time. The mapping strings must have been
|
* multiple joysticks at a time. The mapping strings must have been
|
||||||
* generated with saveGamepadMapping, via Steam, or some other tool which
|
* generated with saveGamepadMappings, via Steam, or some other tool which
|
||||||
* generates SDL GameController mappings.
|
* generates SDL GameController mappings.
|
||||||
**/
|
**/
|
||||||
virtual void loadGamepadMappings(const std::string &mappings) = 0;
|
virtual void loadGamepadMappings(const std::string &mappings) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the virtual Gamepad mapping string for the specified joystick GUID.
|
* Gets a newline-separated list of virtual Gamepad mapping strings for
|
||||||
|
* all used or modified Joysticks which are identified as Gamepads.
|
||||||
**/
|
**/
|
||||||
virtual std::string saveGamepadMapping(const std::string &pguid) = 0;
|
virtual std::string saveGamepadMappings() = 0;
|
||||||
|
|
||||||
}; // JoystickModule
|
}; // JoystickModule
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,9 @@ love::joystick::Joystick *JoystickModule::addJoystick(int deviceindex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (joystick->isGamepad())
|
||||||
|
recentGamepadGUIDs[joystick->getGUID()] = true;
|
||||||
|
|
||||||
activeSticks.push_back(joystick);
|
activeSticks.push_back(joystick);
|
||||||
return joystick;
|
return joystick;
|
||||||
}
|
}
|
||||||
@@ -257,6 +260,9 @@ bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::Gamepa
|
|||||||
// 1 == added, 0 == updated, -1 == error.
|
// 1 == added, 0 == updated, -1 == error.
|
||||||
int status = SDL_GameControllerAddMapping(mapstr.c_str());
|
int status = SDL_GameControllerAddMapping(mapstr.c_str());
|
||||||
|
|
||||||
|
if (status != -1)
|
||||||
|
recentGamepadGUIDs[guid] = true;
|
||||||
|
|
||||||
// FIXME: massive hack until missing APIs are added to SDL 2:
|
// FIXME: massive hack until missing APIs are added to SDL 2:
|
||||||
// https://bugzilla.libsdl.org/show_bug.cgi?id=1975
|
// https://bugzilla.libsdl.org/show_bug.cgi?id=1975
|
||||||
if (status == 1)
|
if (status == 1)
|
||||||
@@ -498,10 +504,11 @@ void JoystickModule::loadGamepadMappings(const std::string &mappings)
|
|||||||
if (SDL_GameControllerAddMapping(mapping.c_str()) != -1)
|
if (SDL_GameControllerAddMapping(mapping.c_str()) != -1)
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
|
std::string guid = mapping.substr(0, mapping.find_first_of(','));
|
||||||
|
recentGamepadGUIDs[guid] = true;
|
||||||
|
|
||||||
// FIXME: massive hack until missing APIs are added to SDL 2:
|
// FIXME: massive hack until missing APIs are added to SDL 2:
|
||||||
// https://bugzilla.libsdl.org/show_bug.cgi?id=1975
|
// https://bugzilla.libsdl.org/show_bug.cgi?id=1975
|
||||||
std::string guid = mapping.substr(0, mapping.find_first_of(','));
|
|
||||||
checkGamepads(guid);
|
checkGamepads(guid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,26 +517,30 @@ void JoystickModule::loadGamepadMappings(const std::string &mappings)
|
|||||||
throw love::Exception("Invalid gamepad mappings.");
|
throw love::Exception("Invalid gamepad mappings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string JoystickModule::saveGamepadMapping(const std::string &pguid)
|
std::string JoystickModule::saveGamepadMappings()
|
||||||
{
|
{
|
||||||
SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(pguid.c_str());
|
std::string mappings;
|
||||||
|
|
||||||
std::string mapping;
|
for (const auto &g : recentGamepadGUIDs)
|
||||||
char *sdlmapping = SDL_GameControllerMappingForGUID(sdlguid);
|
{
|
||||||
|
SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(g.first.c_str());
|
||||||
|
|
||||||
if (sdlmapping == nullptr)
|
char *sdlmapping = SDL_GameControllerMappingForGUID(sdlguid);
|
||||||
throw love::Exception("The specified Joystick GUID string has no gamepad mapping.");
|
if (sdlmapping == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
mapping = sdlmapping;
|
std::string mapping = sdlmapping;
|
||||||
SDL_free(sdlmapping);
|
SDL_free(sdlmapping);
|
||||||
|
|
||||||
if (mapping.find_last_of(',') != mapping.size() - 1)
|
if (mapping.find_last_of(',') != mapping.length() - 1)
|
||||||
mapping += ",";
|
mapping += ",";
|
||||||
|
|
||||||
// Matches SDL_GameControllerAddMappingsFromRW.
|
// Matches SDL_GameControllerAddMappingsFromRW.
|
||||||
mapping += "platform:" + std::string(SDL_GetPlatform()) + ",";
|
mapping += "platform:" + std::string(SDL_GetPlatform()) + ",\n";
|
||||||
|
mappings += mapping;
|
||||||
|
}
|
||||||
|
|
||||||
return mapping;
|
return mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // sdl
|
} // sdl
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -57,7 +58,7 @@ public:
|
|||||||
bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput);
|
bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput);
|
||||||
Joystick::JoystickInput getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput);
|
Joystick::JoystickInput getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput);
|
||||||
void loadGamepadMappings(const std::string &mappings);
|
void loadGamepadMappings(const std::string &mappings);
|
||||||
std::string saveGamepadMapping(const std::string &pguid);
|
std::string saveGamepadMappings();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -76,6 +77,10 @@ private:
|
|||||||
// Persistent list of all Joysticks which have been connected at some point.
|
// Persistent list of all Joysticks which have been connected at some point.
|
||||||
std::list<Joystick *> joysticks;
|
std::list<Joystick *> joysticks;
|
||||||
|
|
||||||
|
// Persistent map indicating GUIDs for Gamepads which have been connected or
|
||||||
|
// modified at some point.
|
||||||
|
std::map<std::string, bool> recentGamepadGUIDs;
|
||||||
|
|
||||||
}; // JoystickModule
|
}; // JoystickModule
|
||||||
|
|
||||||
} // sdl
|
} // sdl
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ int w_Joystick_getHat(lua_State *L)
|
|||||||
Joystick::Hat h = j->getHat(hatindex);
|
Joystick::Hat h = j->getHat(hatindex);
|
||||||
|
|
||||||
const char *direction = "";
|
const char *direction = "";
|
||||||
love::joystick::Joystick::getConstant(h, direction);
|
Joystick::getConstant(h, direction);
|
||||||
|
|
||||||
lua_pushstring(L, direction);
|
lua_pushstring(L, direction);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -249,7 +249,6 @@ static const luaL_Reg functions[] =
|
|||||||
// From wrap_JoystickModule.
|
// From wrap_JoystickModule.
|
||||||
{ "getConnectedIndex", w_getIndex },
|
{ "getConnectedIndex", w_getIndex },
|
||||||
{ "getGamepadMapping", w_getGamepadMapping },
|
{ "getGamepadMapping", w_getGamepadMapping },
|
||||||
{ "saveGamepadMapping", w_saveGamepadMapping },
|
|
||||||
|
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ int w_getJoysticks(lua_State *L)
|
|||||||
|
|
||||||
for (int i = 0; i < stickcount; i++)
|
for (int i = 0; i < stickcount; i++)
|
||||||
{
|
{
|
||||||
love::joystick::Joystick *stick = instance->getJoystick(i);
|
Joystick *stick = instance->getJoystick(i);
|
||||||
stick->retain();
|
stick->retain();
|
||||||
luax_pushtype(L, "Joystick", JOYSTICK_JOYSTICK_T, stick);
|
luax_pushtype(L, "Joystick", JOYSTICK_JOYSTICK_T, stick);
|
||||||
lua_rawseti(L, -2, i + 1);
|
lua_rawseti(L, -2, i + 1);
|
||||||
@@ -50,7 +50,7 @@ int w_getJoysticks(lua_State *L)
|
|||||||
|
|
||||||
int w_getIndex(lua_State *L)
|
int w_getIndex(lua_State *L)
|
||||||
{
|
{
|
||||||
love::joystick::Joystick *j = luax_checkjoystick(L, 1);
|
Joystick *j = luax_checkjoystick(L, 1);
|
||||||
int index = instance->getIndex(j);
|
int index = instance->getIndex(j);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
lua_pushinteger(L, index + 1);
|
lua_pushinteger(L, index + 1);
|
||||||
@@ -75,9 +75,9 @@ int w_setGamepadMapping(lua_State *L)
|
|||||||
const char *gpbindstr = luaL_checkstring(L, 2);
|
const char *gpbindstr = luaL_checkstring(L, 2);
|
||||||
Joystick::GamepadInput gpinput;
|
Joystick::GamepadInput gpinput;
|
||||||
|
|
||||||
if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis))
|
if (Joystick::getConstant(gpbindstr, gpinput.axis))
|
||||||
gpinput.type = Joystick::INPUT_TYPE_AXIS;
|
gpinput.type = Joystick::INPUT_TYPE_AXIS;
|
||||||
else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button))
|
else if (Joystick::getConstant(gpbindstr, gpinput.button))
|
||||||
gpinput.type = Joystick::INPUT_TYPE_BUTTON;
|
gpinput.type = Joystick::INPUT_TYPE_BUTTON;
|
||||||
else
|
else
|
||||||
return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
|
return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
|
||||||
@@ -85,7 +85,7 @@ int w_setGamepadMapping(lua_State *L)
|
|||||||
const char *jinputtypestr = luaL_checkstring(L, 3);
|
const char *jinputtypestr = luaL_checkstring(L, 3);
|
||||||
Joystick::JoystickInput jinput;
|
Joystick::JoystickInput jinput;
|
||||||
|
|
||||||
if (!love::joystick::Joystick::getConstant(jinputtypestr, jinput.type))
|
if (!Joystick::getConstant(jinputtypestr, jinput.type))
|
||||||
return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr);
|
return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr);
|
||||||
|
|
||||||
const char *hatstr;
|
const char *hatstr;
|
||||||
@@ -101,7 +101,7 @@ int w_setGamepadMapping(lua_State *L)
|
|||||||
// Hats need both a hat index and a hat value.
|
// Hats need both a hat index and a hat value.
|
||||||
jinput.hat.index = luaL_checkint(L, 4) - 1;
|
jinput.hat.index = luaL_checkint(L, 4) - 1;
|
||||||
hatstr = luaL_checkstring(L, 5);
|
hatstr = luaL_checkstring(L, 5);
|
||||||
if (!love::joystick::Joystick::getConstant(hatstr, jinput.hat.value))
|
if (!Joystick::getConstant(hatstr, jinput.hat.value))
|
||||||
return luaL_error(L, "Invalid joystick hat: %s", hatstr);
|
return luaL_error(L, "Invalid joystick hat: %s", hatstr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -125,16 +125,16 @@ int w_getGamepadMapping(lua_State *L)
|
|||||||
guid = luax_checkstring(L, 1);
|
guid = luax_checkstring(L, 1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
love::joystick::Joystick *stick = luax_checkjoystick(L, 1);
|
Joystick *stick = luax_checkjoystick(L, 1);
|
||||||
guid = stick->getGUID();
|
guid = stick->getGUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *gpbindstr = luaL_checkstring(L, 2);
|
const char *gpbindstr = luaL_checkstring(L, 2);
|
||||||
Joystick::GamepadInput gpinput;
|
Joystick::GamepadInput gpinput;
|
||||||
|
|
||||||
if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis))
|
if (Joystick::getConstant(gpbindstr, gpinput.axis))
|
||||||
gpinput.type = Joystick::INPUT_TYPE_AXIS;
|
gpinput.type = Joystick::INPUT_TYPE_AXIS;
|
||||||
else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button))
|
else if (Joystick::getConstant(gpbindstr, gpinput.button))
|
||||||
gpinput.type = Joystick::INPUT_TYPE_BUTTON;
|
gpinput.type = Joystick::INPUT_TYPE_BUTTON;
|
||||||
else
|
else
|
||||||
return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
|
return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
|
||||||
@@ -148,7 +148,7 @@ int w_getGamepadMapping(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const char *inputtypestr;
|
const char *inputtypestr;
|
||||||
if (!love::joystick::Joystick::getConstant(jinput.type, inputtypestr))
|
if (!Joystick::getConstant(jinput.type, inputtypestr))
|
||||||
return luaL_error(L, "Unknown joystick input type.");
|
return luaL_error(L, "Unknown joystick input type.");
|
||||||
|
|
||||||
lua_pushstring(L, inputtypestr);
|
lua_pushstring(L, inputtypestr);
|
||||||
@@ -164,7 +164,7 @@ int w_getGamepadMapping(lua_State *L)
|
|||||||
return 2;
|
return 2;
|
||||||
case Joystick::INPUT_TYPE_HAT:
|
case Joystick::INPUT_TYPE_HAT:
|
||||||
lua_pushinteger(L, jinput.hat.index + 1);
|
lua_pushinteger(L, jinput.hat.index + 1);
|
||||||
if (love::joystick::Joystick::getConstant(jinput.hat.value, hatstr))
|
if (Joystick::getConstant(jinput.hat.value, hatstr))
|
||||||
{
|
{
|
||||||
lua_pushstring(L, hatstr);
|
lua_pushstring(L, hatstr);
|
||||||
return 3;
|
return 3;
|
||||||
@@ -201,23 +201,22 @@ int w_loadGamepadMappings(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_saveGamepadMapping(lua_State *L)
|
int w_saveGamepadMappings(lua_State *L)
|
||||||
{
|
{
|
||||||
std::string guid, mapping;
|
lua_settop(L, 1);
|
||||||
|
std::string mappings = instance->saveGamepadMappings();
|
||||||
|
|
||||||
// Accept either a GUID string or a Joystick object. This way we can re-use
|
// Optionally write the mappings string to a file.
|
||||||
// the function for Joystick:getGamepadMapping.
|
if (!lua_isnoneornil(L, 1))
|
||||||
if (lua_type(L, 1) == LUA_TSTRING)
|
|
||||||
guid = luax_checkstring(L, 1);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
love::joystick::Joystick *stick = luax_checkjoystick(L, 1);
|
luax_pushstring(L, mappings);
|
||||||
guid = stick->getGUID();
|
int idxs[] = {1, 2};
|
||||||
|
luax_convobj(L, idxs, 2, "filesystem", "write");
|
||||||
|
lua_pop(L, 1); // Pop the return value.
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_catchexcept(L, [&](){ mapping = instance->saveGamepadMapping(guid); });
|
// Return the actual string even if we also wrote it to a file.
|
||||||
|
luax_pushstring(L, mappings);
|
||||||
luax_pushstring(L, mapping);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +228,7 @@ static const luaL_Reg functions[] =
|
|||||||
{ "setGamepadMapping", w_setGamepadMapping },
|
{ "setGamepadMapping", w_setGamepadMapping },
|
||||||
{ "getGamepadMapping", w_getGamepadMapping },
|
{ "getGamepadMapping", w_getGamepadMapping },
|
||||||
{ "loadGamepadMappings", w_loadGamepadMappings },
|
{ "loadGamepadMappings", w_loadGamepadMappings },
|
||||||
{ "saveGamepadMapping", w_saveGamepadMapping },
|
{ "saveGamepadMappings", w_saveGamepadMappings },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ int w_getJoystickCount(lua_State *L);
|
|||||||
int w_setGamepadMapping(lua_State *L);
|
int w_setGamepadMapping(lua_State *L);
|
||||||
int w_getGamepadMapping(lua_State *L);
|
int w_getGamepadMapping(lua_State *L);
|
||||||
int w_loadGamepadMappings(lua_State *L);
|
int w_loadGamepadMappings(lua_State *L);
|
||||||
int w_saveGamepadMapping(lua_State *L);
|
int w_saveGamepadMappings(lua_State *L);
|
||||||
extern "C" LOVE_EXPORT int luaopen_love_joystick(lua_State *L);
|
extern "C" LOVE_EXPORT int luaopen_love_joystick(lua_State *L);
|
||||||
|
|
||||||
} // joystick
|
} // joystick
|
||||||
|
|||||||
Reference in New Issue
Block a user