Skip to content

Commit

Permalink
feat(gameinput): new sorting algo and new native
Browse files Browse the repository at this point in the history
* Added a native to be able to hide all resource names from the FiveM key page
* Removed specific handling for txAdmin
* Improved sorting algorithm to sort by resource names and then alphabetically within each resource (including lowercase)
  • Loading branch information
ahcenezdh committed Oct 4, 2024
1 parent e31630e commit ad58271
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 20 deletions.
11 changes: 11 additions & 0 deletions code/components/citizen-resources-gta/src/GameInputFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ static InitFunction initFunction([]()
}
});

fx::ScriptEngine::RegisterNativeHandler("SET_KEY_MAPPING_HIDE", [](fx::ScriptContext& context)
{
bool hide = context.GetArgument<bool>(0);

fx::OMPtr<IScriptRuntime> runtime;
if (FX_SUCCEEDED(fx::GetCurrentScriptRuntime(&runtime)))
{
game::SetKeyMappingHide(hide);
}
});

fx::Resource::OnInitializeInstance.Connect([](fx::Resource* resource)
{
resource->OnStart.Connect([resource]()
Expand Down
2 changes: 2 additions & 0 deletions code/components/gta-core-five/include/GameInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ namespace game
GAMEINPUT_EXPORT void RegisterBindingForTag(const std::string& tag, const std::string& command, const std::string& languageDesc, const std::string& ioms, const std::string& ioParam);

GAMEINPUT_EXPORT bool IsControlKeyDown(int control);

GAMEINPUT_EXPORT void SetKeyMappingHide(bool hide);
}
79 changes: 59 additions & 20 deletions code/components/gta-core-five/src/GameInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,9 +1033,15 @@ static void* GetFunc()
}

static std::map<std::string, std::tuple<std::string, std::string>> g_registeredBindings;
static bool g_hideAllResourceNames = false;

namespace game
{
GAMEINPUT_EXPORT void SetKeyMappingHide(bool hide)
{
g_hideAllResourceNames = hide;
}

void SetBindingTagActive(const std::string& tag, bool active)
{
if (active)
Expand Down Expand Up @@ -1172,22 +1178,45 @@ static void(*g_origGetMappingCategoryInputs)(uint32_t* categoryId, atArray<uint3

static void GetMappingCategoryInputs(uint32_t* categoryId, atArray<uint32_t>& controlIds)
{
g_origGetMappingCategoryInputs(categoryId, controlIds);

if (*categoryId == HashString("PM_PANE_CFX"))
{
std::vector<std::pair<std::string, std::tuple<std::string, std::string>>> sortedBindings(g_registeredBindings.begin(), g_registeredBindings.end());
std::sort(sortedBindings.begin(), sortedBindings.end(), [](const auto& left, const auto& right)
{
// #TODO: Unicode-aware comparison
return std::get<1>(left.second) < std::get<1>(right.second);
});

for (auto& binding : sortedBindings)
{
controlIds.Set(controlIds.GetCount(), HashBinding(binding.first));
}
}
g_origGetMappingCategoryInputs(categoryId, controlIds);

if (*categoryId == HashString("PM_PANE_CFX"))
{
auto caseInsensitiveCompare = [](const std::string& a, const std::string& b)
{
return std::lexicographical_compare(
a.begin(), a.end(),
b.begin(), b.end(),
[](char a, char b) {
return std::tolower(static_cast<unsigned char>(a)) < std::tolower(static_cast<unsigned char>(b));
}
);
};

std::map<std::string, std::vector<std::pair<std::string, std::tuple<std::string, std::string>>>, decltype(caseInsensitiveCompare)> groupedBindings(caseInsensitiveCompare);

for (const auto& [command, info] : g_registeredBindings)
{
const auto& [tag, desc] = info;
groupedBindings[tag].push_back({command, info});
}

std::vector<std::pair<std::string, std::vector<std::pair<std::string, std::tuple<std::string, std::string>>>>> sortedGroups(groupedBindings.begin(), groupedBindings.end());


for (auto& [tag, bindings] : sortedGroups)
{
std::sort(bindings.begin(), bindings.end(),
[&caseInsensitiveCompare](const auto& a, const auto& b) {
return caseInsensitiveCompare(std::get<1>(a.second), std::get<1>(b.second));
});

for (const auto& [command, info] : bindings)
{
controlIds.Set(controlIds.GetCount(), HashBinding(command));
}
}
}
}

static void*(*g_origGetBindingForControl)(void* control, rage::ioInputSource* outBinding, uint32_t controlId, int source, uint8_t subIdx, bool unk);
Expand Down Expand Up @@ -1232,16 +1261,26 @@ static const char* GetNameForControl(uint32_t controlId)
static std::string str;
str = fmt::sprintf("INPUT_%08X", HashString(pair.first.c_str()));

// #TODO: replace once GH-1111 is done
auto resourceName = std::get<0>(pair.second);
auto actionName = std::get<1>(pair.second);

if (resourceName == "monitor")
{
resourceName = "txAdmin";
}

// lame hack
game::AddCustomText(HashString(str.c_str()), fmt::sprintf("~HC_3~(%s)~s~ %s", resourceName, std::get<1>(pair.second)));

std::string displayName;

if (g_hideAllResourceNames)
{
displayName = fmt::sprintf("%s", actionName);
}
else
{
displayName = fmt::sprintf("~HC_3~(%s)~s~ %s", resourceName, actionName);
}

game::AddCustomText(HashString(str.c_str()), displayName);

return str.c_str();
}
Expand Down
12 changes: 12 additions & 0 deletions ext/native-decls/SetKeyMappingHide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
ns: CFX
apiset: client
---
## SET_KEY_MAPPING_HIDE

```c
void SET_KEY_MAPPING_HIDE(bool hide);
```
## Parameters
* **hide**:

0 comments on commit ad58271

Please sign in to comment.