Skip to content

Commit

Permalink
Merge pull request #3 from Rackover/native_rumble_support
Browse files Browse the repository at this point in the history
Native rumble & FF support
  • Loading branch information
Rackover authored Oct 23, 2024
2 parents 42d5277 + d605d6f commit ca98c5f
Show file tree
Hide file tree
Showing 38 changed files with 3,295 additions and 434 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@
[submodule "deps/iw4-open-formats"]
path = deps/iw4-open-formats
url = https://github.com/iw4x/iw4-open-formats.git
[submodule "deps/dualsense-windows"]
path = deps/dualsense-windows
url = [email protected]:Ohjurot/DualSense-Windows.git
1 change: 1 addition & 0 deletions deps/dualsense-windows
Submodule dualsense-windows added at 0b869f
42 changes: 42 additions & 0 deletions deps/premake/dualsense-windows.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
dlwin = {
source = path.join(dependencies.basePath, "dualsense-windows/VS19_Solution/DualSenseWindows"),
}

function dlwin.import()
links {"dualsense-windows"}

dlwin.includes()
end

function dlwin.includes()
includedirs {
path.join(dlwin.source, "include"),
}
end


function dlwin.project()
project "dualsense-windows"
language "C++"

defines {
"DS5W_BUILD_LIB"
}

includedirs {
path.join(dlwin.source, "include"),
path.join(dlwin.source, "src"),
}

files
{
path.join(dlwin.source, "**.cpp"),
path.join(dlwin.source, "**.h"),
}

warnings "Off"

kind "StaticLib"
end

table.insert(dependencies, dlwin)
2 changes: 2 additions & 0 deletions src/Components/Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "Modules/RawFiles.hpp"
#include "Modules/RawMouse.hpp"
#include "Modules/RCon.hpp"
#include "Modules/Rumble.hpp"
#include "Modules/Security.hpp"
#include "Modules/ServerCommands.hpp"
#include "Modules/ServerInfo.hpp"
Expand Down Expand Up @@ -141,6 +142,7 @@ namespace Components
Register(new FileSystem());
Register(new Friends());
Register(new Gamepad());
Register(new Rumble());
Register(new Huffman());
Register(new Lean());
Register(new Localization());
Expand Down
1 change: 1 addition & 0 deletions src/Components/Loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,6 @@ namespace Components
#include "Modules/Renderer.hpp"
#include "Modules/Scheduler.hpp"
#include "Modules/Zones.hpp"
#include "Modules/Rumble.hpp"

#include "Modules/GSC/GSC.hpp"
24 changes: 23 additions & 1 deletion src/Components/Modules/ConfigStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Components
constexpr auto EXTRA_MODELCACHE_LAST = EXTRA_MODELCACHE_FIRST + ModelCache::ADDITIONAL_GMODELS;

constexpr auto RUMBLE_FIRST = EXTRA_MODELCACHE_LAST + 1;
constexpr auto RUMBLE_LAST = RUMBLE_FIRST + 31; // TODO
constexpr auto RUMBLE_LAST = RUMBLE_FIRST + Gamepad::RUMBLE_CONFIGSTRINGS_COUNT - 1; // TODO

void ConfigStrings::PatchConfigStrings()
{
Expand Down Expand Up @@ -156,6 +156,21 @@ namespace Components
{
SV_SetConfigString(index, data, Game::CS_WEAPONFILES_LAST, EXTRA_WEAPONS_FIRST);
}

const char* ConfigStrings::CL_GetRumbleConfigString(int index)
{
return CL_GetConfigString(RUMBLE_FIRST + index, Game::CS_LAST, Game::MAX_CONFIGSTRINGS);
}

unsigned int ConfigStrings::SV_GetRumbleConfigStringConst(int index)
{
return SV_GetConfigString(RUMBLE_FIRST +index, Game::CS_LAST, Game::MAX_CONFIGSTRINGS);
}

void ConfigStrings::SV_SetRumbleConfigString(int index, const char* data)
{
SV_SetConfigString(RUMBLE_FIRST + index, data, Game::CS_LAST, Game::MAX_CONFIGSTRINGS);
}

void ConfigStrings::SV_SetCachedModelConfigString(int index, const char* data)
{
Expand Down Expand Up @@ -251,6 +266,13 @@ namespace Components
index = index - EXTRA_MODELCACHE_FIRST + ModelCache::BASE_GMODEL_COUNT;
ModelCache::gameModels_reallocated[index] = Utils::Hook::Call<Game::XModel*(const char*)>(R_RegisterModel)(name);
}
// Rumble!
else if (index >= RUMBLE_FIRST && index <= RUMBLE_LAST)
{
// Apparently, there is nothing to do here. At least the game doesn't look like
// it needs anything to be done. If there was to do rumble string replication
// between server and client, it would happen here
}
else
{
// Unknown for now?
Expand Down
5 changes: 5 additions & 0 deletions src/Components/Modules/ConfigStrings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace Components

ConfigStrings();

static const char* CL_GetRumbleConfigString(int index);
static unsigned int SV_GetRumbleConfigStringConst(int index);
static void SV_SetRumbleConfigString(int index, const char* data);


private:
static void PatchConfigStrings();

Expand Down
89 changes: 82 additions & 7 deletions src/Components/Modules/GSC/Script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ namespace Components::GSC
std::vector<Script::ScriptFunction> Script::CustomScrFunctions;
std::vector<Script::ScriptMethod> Script::CustomScrMethods;

std::vector<Script::ScriptFunction> Script::CommonOverridenFunctions;
std::vector<Script::ScriptMethod> Script::CommonOverridenMethods;

std::unordered_map<std::string, int> Script::ScriptMainHandles;
std::unordered_map<std::string, int> Script::ScriptInitHandles;

Expand Down Expand Up @@ -117,24 +120,38 @@ namespace Components::GSC
Game::GScr_LoadGameTypeScript();
}

void Script::AddFunction(const std::string& name, const Game::BuiltinFunction func, const bool type)
void Script::AddFunction(const std::string& name, const Game::BuiltinFunction func, const bool type, const bool builtIn)
{
ScriptFunction toAdd;
toAdd.actionFunc = func;
toAdd.type = type;
toAdd.aliases.push_back({Utils::String::ToLower(name)});
toAdd.aliases.push_back({ Utils::String::ToLower(name) });

CustomScrFunctions.emplace_back(toAdd);
if (builtIn)
{
CommonOverridenFunctions.emplace_back(toAdd);
}
else
{
CustomScrFunctions.emplace_back(toAdd);
}
}

void Script::AddMethod(const std::string& name, const Game::BuiltinMethod func, const bool type)
void Script::AddMethod(const std::string& name, const Game::BuiltinMethod func, const bool type, const bool builtIn)
{
ScriptMethod toAdd;
toAdd.actionFunc = func;
toAdd.type = type;
toAdd.aliases.push_back({Utils::String::ToLower(name)});

CustomScrMethods.emplace_back(toAdd);
toAdd.aliases.push_back({ Utils::String::ToLower(name) });

if (builtIn)
{
CommonOverridenMethods.emplace_back(toAdd);
}
else
{
CustomScrMethods.emplace_back(toAdd);
}
}

void Script::AddFuncMultiple(Game::BuiltinFunction func, bool type, scriptNames aliases)
Expand All @@ -161,6 +178,34 @@ namespace Components::GSC
CustomScrMethods.emplace_back(toAdd);
}

Game::BuiltinFunction Script::Common_GetFunctionStub(const char** pName, int* type)
{
if (pName != nullptr)
{
const auto name = Utils::String::ToLower(*pName);
for (const auto& funcs : CommonOverridenFunctions)
{
if (std::ranges::find(funcs.aliases, name) != funcs.aliases.end())
{
*type = funcs.type;
return funcs.actionFunc;
}
}
}
else
{
// "func" here is a struct that contains several things
for (const auto& func : CommonOverridenFunctions)
{
const auto& name = func.aliases.at(0);
Game::Scr_RegisterFunction(reinterpret_cast<int>(func.actionFunc), name.data());
}
}

// If no function was found let's call game's function
return Utils::Hook::Call<Game::BuiltinFunction(const char**, int* type)>(0x4BCF80)(pName, type); // Common_GetFunction
}

Game::BuiltinFunction Script::BuiltIn_GetFunctionStub(const char** pName, int* type)
{
if (pName != nullptr)
Expand Down Expand Up @@ -188,6 +233,32 @@ namespace Components::GSC
return Utils::Hook::Call<Game::BuiltinFunction(const char**, int*)>(0x5FA2B0)(pName, type); // BuiltIn_GetFunction
}

Game::BuiltinMethod Script::Common_GetMethodStub(const char** pName)
{
if (pName != nullptr)
{
const auto name = Utils::String::ToLower(*pName);
for (const auto& meths : CommonOverridenMethods)
{
if (std::ranges::find(meths.aliases, name) != meths.aliases.end())
{
return meths.actionFunc;
}
}
}
else
{
for (const auto& meth : CommonOverridenMethods)
{
const auto& name = meth.aliases.at(0);
Game::Scr_RegisterFunction(reinterpret_cast<int>(meth.actionFunc), name.data());
}
}

// If no method was found let's call game's function
return Utils::Hook::Call<Game::BuiltinMethod(const char**)>(0x4DBA50)(pName); // Player_GetMethod
}

Game::BuiltinMethod Script::BuiltIn_GetMethodStub(const char** pName, int* type)
{
if (pName != nullptr)
Expand Down Expand Up @@ -282,6 +353,10 @@ namespace Components::GSC
// Fetch custom functions
Utils::Hook(0x44E72E, BuiltIn_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction
Utils::Hook(0x4EC8DD, BuiltIn_GetMethodStub, HOOK_CALL).install()->quick(); // Scr_GetMethod
Utils::Hook(0x4EC881, Common_GetMethodStub, HOOK_CALL).install()->quick(); // Scr_GetMethod

Utils::Hook(0x44E712, Common_GetFunctionStub, HOOK_CALL).install()->quick(); // Scr_GetFunction


Utils::Hook(0x5F41A3, SetExpFogStub, HOOK_CALL).install()->quick();

Expand Down
11 changes: 9 additions & 2 deletions src/Components/Modules/GSC/Script.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ namespace Components::GSC
Script();

using scriptNames = std::vector<std::string>;
static void AddFunction(const std::string& name, Game::BuiltinFunction func, bool type = false);
static void AddMethod(const std::string& name, Game::BuiltinMethod func, bool type = false);
static void AddFunction(const std::string& name, Game::BuiltinFunction func, bool type = false, bool isBuitIn= false);
static void AddMethod(const std::string& name, Game::BuiltinMethod func, bool type = false, bool isBuitIn= false);

static void AddFuncMultiple(Game::BuiltinFunction func, bool type, scriptNames);
static void AddMethMultiple(Game::BuiltinMethod func, bool type, scriptNames);


static Game::client_s* GetClient(const Game::gentity_s* gentity);
// Probably a macro 'originally' but this is fine
static Game::gentity_s* Scr_GetPlayerEntity(Game::scr_entref_t entref);
Expand All @@ -33,6 +34,9 @@ namespace Components::GSC
scriptNames aliases;
};

static std::vector<ScriptFunction> CommonOverridenFunctions;
static std::vector<ScriptMethod> CommonOverridenMethods;

static std::vector<ScriptFunction> CustomScrFunctions;
static std::vector<ScriptMethod> CustomScrMethods;

Expand All @@ -46,6 +50,9 @@ namespace Components::GSC
static void Scr_StartupGameType_Stub();
static void GScr_LoadGameTypeScript_Stub();

static Game::BuiltinFunction Common_GetFunctionStub(const char** pName, int* type);
static Game::BuiltinMethod Common_GetMethodStub(const char** pName);

static Game::BuiltinFunction BuiltIn_GetFunctionStub(const char** pName, int* type);
static Game::BuiltinMethod BuiltIn_GetMethodStub(const char** pName, int* type);

Expand Down
2 changes: 1 addition & 1 deletion src/Components/Modules/GSC/ScriptError.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ namespace Components::GSC
unsigned int ScriptError::Scr_LoadScriptInternal_Hk(const char* filename, Game::PrecacheEntry* entries, int entriesCount)
{
char extFilename[MAX_QPATH];
Game::sval_u parseData;
Game::sval_u parseData{};

assert(Game::scrCompilePub->script_loading);
assert(std::strlen(filename) < MAX_QPATH);
Expand Down
Loading

0 comments on commit ca98c5f

Please sign in to comment.