From 48da93f634d24a4c6e4b9479b02dc3475110cd3a Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Wed, 6 Dec 2023 12:28:40 -0600 Subject: [PATCH] Code cleanup and moved to multifunction declaration --- .../Enhancements/scripting-layer/bridge.cpp | 58 +- soh/soh/Enhancements/scripting-layer/bridge.h | 10 +- .../scripting-layer/hosts/hostapi.h | 4 +- .../scripting-layer/hosts/lua.cpp | 105 +-- .../Enhancements/scripting-layer/hosts/lua.h | 2 +- .../interactors/game-interactor/gi-bridge.cpp | 143 ++-- .../interactors/libultraship/imgui-bridge.cpp | 685 +++++++++++------- .../interactors/n64-native/n64-bridge.cpp | 118 +-- .../interactors/soh/soh-bridge.cpp | 97 +-- .../scripting-layer/types/methodcall.h | 2 +- 10 files changed, 690 insertions(+), 534 deletions(-) diff --git a/soh/soh/Enhancements/scripting-layer/bridge.cpp b/soh/soh/Enhancements/scripting-layer/bridge.cpp index 764cf8d3296..aeb1995b7f8 100644 --- a/soh/soh/Enhancements/scripting-layer/bridge.cpp +++ b/soh/soh/Enhancements/scripting-layer/bridge.cpp @@ -16,7 +16,7 @@ #define ERROR_MESSAGE std::reinterpret_pointer_cast(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendErrorMessage #define INFO_MESSAGE std::reinterpret_pointer_cast(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendInfoMessage -static bool RunScript(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RunScript(const std::shared_ptr&, const std::vector& args, std::string*) { if (args.size() > 1) { auto path = std::filesystem::path("scripts") / args[1]; auto ext = path.extension().string().substr(1); @@ -55,13 +55,13 @@ static bool RunScript(std::shared_ptr Console, const std::vector Console, const std::vector& args, std::string* output) { +static bool KillScript(const std::shared_ptr&, const std::vector& args, std::string*) { if (args.size() > 1) { try { - uint16_t pid = std::stoi(args[1]); + const uint16_t pid = std::stoi(args[1]); GameBridge::Instance->Kill(pid); INFO_MESSAGE("Script with pid %d killed", pid); - } catch (std::invalid_argument& e) { + } catch (std::invalid_argument&) { ERROR_MESSAGE("Invalid pid: %s", args[1].c_str()); return true; } @@ -74,11 +74,11 @@ static bool KillScript(std::shared_ptr Console, const std::vector< void GameBridge::Initialize() { this->RegisterHost("lua", std::make_shared()); - this->BindFunction("print", [](uintptr_t ctx, MethodCall* method) { - size_t count = method->ArgumentCount(); + this->BindFunction("print", [](uintptr_t, MethodCall* method) { + const size_t count = method->ArgumentCount(); std::stringstream message; for(size_t i = 0; i < count; i++) { - std::any value = method->RawArgument(i); + std::any value = method->RawArgument(static_cast(i)); if (IS_TYPE(std::string, value)) { message << std::any_cast(value); } else if (IS_TYPE(bool, value)) { @@ -100,27 +100,27 @@ void GameBridge::Initialize() { method->success(); }); // TODO: Find a way to automatically bind all hooks - this->BindFunction("hook", [](uintptr_t ctx, MethodCall* method) { - auto mode = method->GetArgument(0); - auto hook = method->GetArgument(1); + this->BindFunction("hook", [](uintptr_t, MethodCall* method) { + const auto mode = method->GetArgument(0); + const auto hook = method->GetArgument(1); if(mode == "add"){ auto function = method->GetArgument(2); if(hook == "update"){ - size_t idx = GameInteractor::Instance->RegisterGameHook([function]() { + const size_t idx = GameInteractor::Instance->RegisterGameHook([function]() { try { function->execute(); } catch (HostAPIException& e) { ERROR_MESSAGE("Error while executing script: %s", e.what()); } }); - method->success((int) idx); + method->success(static_cast(idx)); return; } method->error("Unknown hook: " + hook); return; } if(mode == "remove"){ - auto idx = method->GetArgument(2); + const auto idx = method->GetArgument(2); if(hook == "update"){ GameInteractor::Instance->UnregisterGameHook(idx); method->success(); @@ -140,23 +140,23 @@ void GameBridge::Initialize() { } uint16_t GameBridge::Execute(const std::string& script, const std::string& hostname){ - auto host = this->hosts.find(hostname); + const auto host = this->hosts.find(hostname); if(host == this->hosts.end()){ throw GameBridgeException("Host api not found: " + hostname); } - uint16_t pid = host->second->Execute(script); + const uint16_t pid = host->second->Execute(script); this->pids[pid] = host->second; return pid; } -void GameBridge::Kill(uint16_t pid){ +void GameBridge::Kill(const uint16_t pid) const { if(!this->pids.contains(pid)){ return; } - auto host = this->pids.find(pid); + const auto host = this->pids.find(pid); return host->second->Kill(pid); } @@ -167,24 +167,22 @@ void GameBridge::RegisterHost(const std::string& name, std::shared_ptr this->hosts[name] = std::move(host); } -void GameBridge::Register(std::vector entries, const std::variant& mod_name) { - for (auto& host : this->hosts) { - for (auto& entry : entries) { - host.second->Bind(entry.name, { (BindingType) entry.link.index(), entry.link, mod_name }); +void GameBridge::Register(const std::vector& entries, const std::string& mod_name) const { + for (const auto& [fst, snd] : this->hosts) { + for (auto& [name, link] : entries) { + snd->Bind(name, { static_cast(link.index()), link, mod_name }); } } } -[[deprecated]] -void GameBridge::BindField(const std::string& name, const std::any& field, const std::variant& mod_name){ - for(auto& host : this->hosts){ - host.second->Bind(name, { BindingType::KField, field, mod_name }); +void GameBridge::BindField(const std::string& name, const std::any& field, const std::string& mod_name) const { + for(const auto& [fst, snd] : this->hosts){ + snd->Bind(name, { BindingType::KField, field, mod_name }); } } -[[deprecated]] -void GameBridge::BindFunction(const std::string& name, FunctionPtr function, const std::variant& mod_name){ - for(auto& host : this->hosts){ - host.second->Bind(name, { BindingType::KFunction, function, mod_name }); +void GameBridge::BindFunction(const std::string& name, FunctionPtr function, const std::string& mod_name) const { + for(const auto& [fst, snd] : this->hosts){ + snd->Bind(name, { BindingType::KFunction, function, mod_name }); } -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/scripting-layer/bridge.h b/soh/soh/Enhancements/scripting-layer/bridge.h index 34cdf8acfd2..258f9323d2e 100644 --- a/soh/soh/Enhancements/scripting-layer/bridge.h +++ b/soh/soh/Enhancements/scripting-layer/bridge.h @@ -4,7 +4,6 @@ #include "types/methodcall.h" #include #include -#include #define BIND_FUNCTION(name, ptr) NamedEntry { name, (FunctionPtr)ptr } #define BIND_FIELD(name, field) NamedEntry { name, field } @@ -16,10 +15,11 @@ struct NamedEntry { }; class GameBridge { -private: std::unordered_map> hosts; std::unordered_map> pids; void RegisterHost(const std::string& name, std::shared_ptr host); + void BindField(const std::string& name, const std::any& field, const std::string& mod_name = ROOT_MODULE) const; + void BindFunction(const std::string& name, FunctionPtr function, const std::string& mod_name = ROOT_MODULE) const; public: GameBridge() { this->Initialize(); @@ -29,8 +29,6 @@ class GameBridge { uint16_t Execute(const std::string& script, const std::string& hostname); // Static Methods - void Register(std::vector entries, const std::variant& mod_name = std::monostate()); - void BindField(const std::string& name, const std::any& field, const std::variant& mod_name = std::monostate()); - void BindFunction(const std::string& name, FunctionPtr function, const std::variant& mod_name = std::monostate()); - void Kill(uint16_t pid); + void Register(const std::vector& entries, const std::string& mod_name = ROOT_MODULE) const; + void Kill(uint16_t pid) const; }; \ No newline at end of file diff --git a/soh/soh/Enhancements/scripting-layer/hosts/hostapi.h b/soh/soh/Enhancements/scripting-layer/hosts/hostapi.h index c127b092e7d..11a52e9eb2b 100644 --- a/soh/soh/Enhancements/scripting-layer/hosts/hostapi.h +++ b/soh/soh/Enhancements/scripting-layer/hosts/hostapi.h @@ -1,14 +1,12 @@ #pragma once -#include #include #include -#include struct GameBinding; #define IS_TYPE(t, value) value.type() == typeid(t) -typedef std::variant ModName; +#define ROOT_MODULE "root" class HostAPI { public: diff --git a/soh/soh/Enhancements/scripting-layer/hosts/lua.cpp b/soh/soh/Enhancements/scripting-layer/hosts/lua.cpp index 098b8a3638f..cf61bded69d 100644 --- a/soh/soh/Enhancements/scripting-layer/hosts/lua.cpp +++ b/soh/soh/Enhancements/scripting-layer/hosts/lua.cpp @@ -23,7 +23,7 @@ extern "C" { typedef int(*LuaFunction)(lua_State*); typedef std::variant LuaBinding; -std::unordered_map> mLuaBindings; +std::unordered_map> mLuaBindings; std::vector mLuaStates; const char* tryCatchImpl = R"( @@ -61,19 +61,19 @@ void LuaHost::BindRequireOverride() { auto path = std::filesystem::path("scripts") / _module; auto ext = path.extension().string().substr(1); - if(!std::filesystem::exists(path)) { + if(!exists(path)) { method->error("File not found"); return; } std::ifstream file(path); - std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); - luaL_loadstring((lua_State*) ctx, content.c_str()); + std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + luaL_loadstring(reinterpret_cast(ctx), content.c_str()); method->success(); return; } - auto state = (lua_State*) ctx; + auto state = reinterpret_cast(ctx); if (!mLuaBindings.contains(_module)){ method->error("Module not found"); @@ -83,7 +83,7 @@ void LuaHost::BindRequireOverride() { auto& functions = mLuaBindings[_module]; luaL_checkversion(state); - lua_createtable(state, 0, (int) (functions.size() - 1)); + lua_createtable(state, 0, static_cast(functions.size() - 1)); for (auto& func : functions) { @@ -91,11 +91,11 @@ void LuaHost::BindRequireOverride() { if(binding.index() == 0){ lua_pushlightuserdata(state, method->GetHost()); - lua_pushlightuserdata(state, &((LuaHost*)method->GetHost())->mBindings[func.first]); + lua_pushlightuserdata(state, &dynamic_cast(method->GetHost())->mBindings[func.first]); lua_pushcclosure(state, std::get(binding), 2); } else { auto value = std::get(binding); - LuaHost::PushIntoLua((uintptr_t) state, value); + PushIntoLua(reinterpret_cast(state), value); } lua_setfield(state, -2, func.first.c_str()); @@ -106,11 +106,11 @@ void LuaHost::BindRequireOverride() { method->success(); }; // TODO: Find a better way to avoid repeating this. - this->Bind("require", { BindingType::KFunction, call, std::monostate() }); + this->Bind("require", { BindingType::KFunction, call }); } -void LuaHost::PushIntoLua(uintptr_t context, const std::any& value) { - auto *state = (lua_State *) context; +void LuaHost::PushIntoLua(const uintptr_t context, const std::any& value) { + auto *state = reinterpret_cast(context); if (IS_TYPE(std::string, value)) { lua_pushstring(state, std::any_cast(value).c_str()); @@ -133,7 +133,7 @@ void LuaHost::PushIntoLua(uintptr_t context, const std::any& value) { } else if (IS_TYPE(std::monostate, value) || IS_TYPE(nullptr, value)) { lua_pushnil(state); } else if (IS_TYPE(EmptyTable, value)) { - // This is a workaround for the import function + // TODO: Remove this, it's a workaround for the import function } else { throw HostAPIException("Unknown type" + std::string(value.type().name())); } @@ -143,14 +143,14 @@ void LuaHost::Bind(std::string name, GameBinding binding) { mBindings[name] = binding; if (binding.type == BindingType::KFunction) { LuaFunction func = [](lua_State* state) -> int { - auto* api = (LuaHost*) lua_topointer(state, lua_upvalueindex(1)); - const auto* binding = (const GameBinding*) lua_topointer(state, lua_upvalueindex(2)); + auto* api = static_cast(const_cast(lua_topointer(state, lua_upvalueindex(1)))); + const auto* bind = static_cast(lua_topointer(state, lua_upvalueindex(2))); - auto* result = new MethodCall(api, (uintptr_t) state); - auto execute = std::get(binding->binding); - execute((uintptr_t) state, result); + auto* result = new MethodCall(api, reinterpret_cast(state)); + const auto execute = std::get(bind->binding); + execute(reinterpret_cast(state), result); - std::vector results = result->result(); + const std::vector results = result->result(); if(results.empty()){ throw HostAPIException("No results returned from function"); @@ -158,49 +158,49 @@ void LuaHost::Bind(std::string name, GameBinding binding) { if (result->succeed()) { for (auto& value : results) { - LuaHost::PushIntoLua((uintptr_t) state, value); + PushIntoLua(reinterpret_cast(state), value); } } else { luaL_error(state, std::any_cast(results[0]).c_str()); } - return (int) results.size(); + return static_cast(results.size()); }; - mLuaBindings[binding.modName].insert({ name, func }); + mLuaBindings[binding.module].insert({ name, func }); return; } if (binding.type == BindingType::KField) { - mLuaBindings[binding.modName].insert({ name, std::get(binding.binding) }); + mLuaBindings[binding.module].insert({ name, std::get(binding.binding) }); } } -void LuaHost::Call(uintptr_t context, uintptr_t function, const std::vector &arguments) { +void LuaHost::Call(const uintptr_t context, const uintptr_t function, const std::vector &arguments) { - auto* state = (lua_State*) context; - auto func = (char*) function; + auto* state = reinterpret_cast(context); + const auto ref = static_cast(function); if (state == nullptr) { throw HostAPIException("Invalid host state, probably closed"); } - lua_getglobal(state, func); + lua_rawgeti( state, LUA_REGISTRYINDEX, ref ); for (auto& argument : arguments) { - LuaHost::PushIntoLua((uintptr_t) state, argument); + PushIntoLua(reinterpret_cast(state), argument); } - if (lua_pcall(state, (int) arguments.size(), 0, 0) != 0) { - throw HostAPIException("Error while calling function: " + std::string(lua_tostring(state, -1))); + if (lua_pcall(state, static_cast(arguments.size()), 0, 0) != 0) { + throw HostAPIException("Error while calling function with ref " + std::to_string(ref)); } } -std::any LuaHost::GetArgument(int index, uintptr_t context) { - auto* state = (lua_State*) context; +std::any LuaHost::GetArgument(int index, const uintptr_t context) { + auto* state = reinterpret_cast(context); index += 1; if (lua_isinteger(state, index)) { - return (int) luaL_checkinteger(state, index); + return static_cast(luaL_checkinteger(state, index)); } if (lua_isnumber(state, index)) { @@ -211,23 +211,24 @@ std::any LuaHost::GetArgument(int index, uintptr_t context) { return luaL_checkinteger(state, index); } - if (lua_isnoneornil(state, index)) { - return nullptr; + if (lua_isstring(state, index)) { + return std::string(luaL_checkstring(state, index)); } - if (lua_isstring(state, index)) { - std::string str = luaL_checkstring(state, index); - if(str.starts_with("func:")){ - return new HostFunction(this, (uintptr_t) state, (uintptr_t) strdup(str.substr(5).c_str())); - } - return str; + if (lua_isfunction(state, index)) { + const int ref = luaL_ref(state, LUA_REGISTRYINDEX); + return new HostFunction(this, reinterpret_cast(state), ref); } - throw HostAPIException("Unknown argument type: " + std::string(typeid(index).name())); + if (lua_isnoneornil(state, index)) { + return nullptr; + } + + throw HostAPIException("Unknown argument type: " + std::string(lua_typename(state, lua_type(state, index)))); } -size_t LuaHost::GetArgumentCount(uintptr_t context) { - auto* state = (lua_State*) context; +size_t LuaHost::GetArgumentCount(const uintptr_t context) { + auto* state = reinterpret_cast(context); return lua_gettop(state); } @@ -241,36 +242,38 @@ uint16_t LuaHost::Execute(const std::string& script) { lua_call(state, 1, 0); } - for (auto& func : mLuaBindings[std::monostate()]) { + for (auto& [fst, snd] : mLuaBindings[ROOT_MODULE]) { - LuaBinding binding = func.second; + LuaBinding binding = snd; if(binding.index() == 0){ lua_pushlightuserdata(state, this); - lua_pushlightuserdata(state, &this->mBindings[func.first]); + lua_pushlightuserdata(state, &this->mBindings[fst]); lua_pushcclosure(state, std::get(binding), 2); } else { auto value = std::get(binding); - LuaHost::PushIntoLua((uintptr_t) state, value); + PushIntoLua(reinterpret_cast(state), value); } - lua_setglobal(state, func.first.c_str()); + lua_setglobal(state, fst.c_str()); } luaL_dostring(state, tryCatchImpl); + + const int ret = luaL_dostring(state, script.c_str()); if (ret != LUA_OK) { - std::string error(lua_tostring(state, -1)); + const std::string error(lua_tostring(state, -1)); lua_close(state); throw HostAPIException(error); } mLuaStates.push_back(state); - return (uint16_t) mLuaStates.size() - 1; + return static_cast(mLuaStates.size()) - 1; } -void LuaHost::Kill(uint16_t pid) { +void LuaHost::Kill(const uint16_t pid) { if (pid > mLuaStates.size()) { return; } diff --git a/soh/soh/Enhancements/scripting-layer/hosts/lua.h b/soh/soh/Enhancements/scripting-layer/hosts/lua.h index 71feef0e237..79a56689758 100644 --- a/soh/soh/Enhancements/scripting-layer/hosts/lua.h +++ b/soh/soh/Enhancements/scripting-layer/hosts/lua.h @@ -1,12 +1,12 @@ #pragma once #include "hostapi.h" +#include #include struct GameBinding; class LuaHost : public HostAPI { -private: std::unordered_map mBindings; public: bool Initialize() override; diff --git a/soh/soh/Enhancements/scripting-layer/interactors/game-interactor/gi-bridge.cpp b/soh/soh/Enhancements/scripting-layer/interactors/game-interactor/gi-bridge.cpp index d43e960f1bf..b16e3fff102 100644 --- a/soh/soh/Enhancements/scripting-layer/interactors/game-interactor/gi-bridge.cpp +++ b/soh/soh/Enhancements/scripting-layer/interactors/game-interactor/gi-bridge.cpp @@ -3,76 +3,75 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" void GameInteractorBridge::Initialize() { - GameBridge::Instance->BindFunction("AddOrRemoveHealthContainers", [](uintptr_t ctx, MethodCall* method) { - auto amount = method->GetArgument(0); - GameInteractor::RawAction::AddOrRemoveHealthContainers((int16_t) amount); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("AddOrRemoveMagic", [](uintptr_t ctx, MethodCall* method) { - auto amount = method->GetArgument(0); - GameInteractor::RawAction::AddOrRemoveMagic((int8_t) amount); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("HealOrDamagePlayer", [](uintptr_t ctx, MethodCall* method) { - auto amount = method->GetArgument(0); - GameInteractor::RawAction::HealOrDamagePlayer((int16_t) amount); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("SetPlayerHealth", [](uintptr_t ctx, MethodCall* method) { - auto amount = method->GetArgument(0); - GameInteractor::RawAction::SetPlayerHealth((int16_t) amount); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("SetLinkInvisibility", [](uintptr_t ctx, MethodCall* method) { - auto active = method->GetArgument(0); - GameInteractor::RawAction::SetLinkInvisibility(active); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("SetWeatherStorm", [](uintptr_t ctx, MethodCall* method) { - auto active = method->GetArgument(0); - GameInteractor::RawAction::SetWeatherStorm(active); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("ForceEquipBoots", [](uintptr_t ctx, MethodCall* method) { - auto amount = method->GetArgument(0); - GameInteractor::RawAction::ForceEquipBoots((int8_t) amount); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("FreezePlayer", [](uintptr_t ctx, MethodCall* method) { - GameInteractor::RawAction::FreezePlayer(); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("BurnPlayer", [](uintptr_t ctx, MethodCall* method) { - GameInteractor::RawAction::BurnPlayer(); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("ElectrocutePlayer", [](uintptr_t ctx, MethodCall* method) { - GameInteractor::RawAction::ElectrocutePlayer(); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("KnockbackPlayer", [](uintptr_t ctx, MethodCall* method) { - auto strength = method->GetArgument(0); - GameInteractor::RawAction::KnockbackPlayer((float) strength); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("GiveOrTakeShield", [](uintptr_t ctx, MethodCall* method) { - auto shield = method->GetArgument(0); - GameInteractor::RawAction::GiveOrTakeShield(shield); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("SetWeatherStorm", [](uintptr_t ctx, MethodCall* method) { - auto status = method->GetArgument(0); - GameInteractor::RawAction::SetWeatherStorm(status); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("ForceInterfaceUpdate", [](uintptr_t ctx, MethodCall* method) { - GameInteractor::RawAction::ForceInterfaceUpdate(); - method->success(); - }, "GameInteractor"); - GameBridge::Instance->BindFunction("SpawnEnemyWithOffset", [](uintptr_t ctx, MethodCall* method) { - auto enemyId = method->GetArgument(0); - auto enemyParams = method->GetArgument(1); - int result = GameInteractor::RawAction::SpawnEnemyWithOffset(enemyId, enemyParams); - method->success(result); - }, "GameInteractor"); + const auto entries = { + BIND_FUNCTION("AddOrRemoveHealthContainers", [](uintptr_t ctx, MethodCall* method) { + const auto amount = method->GetArgument(0); + GameInteractor::RawAction::AddOrRemoveHealthContainers((int16_t) amount); + method->success(); + }), + BIND_FUNCTION("AddOrRemoveMagic", [](uintptr_t, MethodCall* method) { + const auto amount = method->GetArgument(0); + GameInteractor::RawAction::AddOrRemoveMagic(static_cast(amount)); + method->success(); + }), + BIND_FUNCTION("HealOrDamagePlayer", [](uintptr_t, MethodCall* method) { + const auto amount = method->GetArgument(0); + GameInteractor::RawAction::HealOrDamagePlayer(static_cast(amount)); + method->success(); + }), + BIND_FUNCTION("SetPlayerHealth", [](uintptr_t, MethodCall* method) { + const auto amount = method->GetArgument(0); + GameInteractor::RawAction::SetPlayerHealth(static_cast(amount)); + method->success(); + }), + BIND_FUNCTION("SetLinkInvisibility", [](uintptr_t, MethodCall* method) { + const auto active = method->GetArgument(0); + GameInteractor::RawAction::SetLinkInvisibility(active); + method->success(); + }), + BIND_FUNCTION("SetWeatherStorm", [](uintptr_t, MethodCall* method) { + const auto active = method->GetArgument(0); + GameInteractor::RawAction::SetWeatherStorm(active); + method->success(); + }), + BIND_FUNCTION("ForceEquipBoots", [](uintptr_t, MethodCall* method) { + const auto amount = method->GetArgument(0); + GameInteractor::RawAction::ForceEquipBoots(static_cast(amount)); + method->success(); + }), + BIND_FUNCTION("FreezePlayer", [](uintptr_t, MethodCall* method) { + GameInteractor::RawAction::FreezePlayer(); + method->success(); + }), + BIND_FUNCTION("BurnPlayer", [](uintptr_t, MethodCall* method) { + GameInteractor::RawAction::BurnPlayer(); + method->success(); + }), + BIND_FUNCTION("ElectrocutePlayer", [](uintptr_t, MethodCall* method) { + GameInteractor::RawAction::ElectrocutePlayer(); + method->success(); + }), + BIND_FUNCTION("KnockbackPlayer", [](uintptr_t, MethodCall* method) { + const auto strength = method->GetArgument(0); + GameInteractor::RawAction::KnockbackPlayer(static_cast(strength)); + method->success(); + }), + BIND_FUNCTION("GiveOrTakeShield", [](uintptr_t, MethodCall* method) { + const auto amount = method->GetArgument(0); + GameInteractor::RawAction::GiveOrTakeShield(static_cast(amount)); + method->success(); + }), + BIND_FUNCTION("ForceInterfaceUpdate", [](uintptr_t, MethodCall* method) { + GameInteractor::RawAction::ForceInterfaceUpdate(); + method->success(); + }), + BIND_FUNCTION("SpawnEnemyWithOffset", [](uintptr_t, MethodCall* method) { + const auto enemyId = method->GetArgument(0); + const auto enemyParams = method->GetArgument(1); + int result = GameInteractor::RawAction::SpawnEnemyWithOffset(enemyId, enemyParams); + method->success(result); + }), + }; + + GameBridge::Instance->Register(entries, "GameInteractor"); } \ No newline at end of file diff --git a/soh/soh/Enhancements/scripting-layer/interactors/libultraship/imgui-bridge.cpp b/soh/soh/Enhancements/scripting-layer/interactors/libultraship/imgui-bridge.cpp index 7a686716dd4..64c39a46498 100644 --- a/soh/soh/Enhancements/scripting-layer/interactors/libultraship/imgui-bridge.cpp +++ b/soh/soh/Enhancements/scripting-layer/interactors/libultraship/imgui-bridge.cpp @@ -2,281 +2,418 @@ #include #include "soh/Enhancements/scripting-layer/bridge.h" -#define BIND_FLAG(flag) GameBridge::Instance->BindField(#flag, (int) flag, "ImGui"); +#define BIND_FLAG(flag) BIND_FIELD(#flag, (int) flag) void ImGuiBridge::Initialize() { - BIND_FLAG(ImGuiWindowFlags_None); - BIND_FLAG(ImGuiWindowFlags_NoTitleBar); - BIND_FLAG(ImGuiWindowFlags_NoResize); - BIND_FLAG(ImGuiWindowFlags_NoMove); - BIND_FLAG(ImGuiWindowFlags_NoScrollbar); - BIND_FLAG(ImGuiWindowFlags_NoScrollWithMouse); - BIND_FLAG(ImGuiWindowFlags_NoCollapse); - BIND_FLAG(ImGuiWindowFlags_AlwaysAutoResize); - BIND_FLAG(ImGuiWindowFlags_NoBackground); - BIND_FLAG(ImGuiWindowFlags_NoSavedSettings); - BIND_FLAG(ImGuiWindowFlags_NoMouseInputs); - BIND_FLAG(ImGuiWindowFlags_MenuBar); - BIND_FLAG(ImGuiWindowFlags_HorizontalScrollbar); - BIND_FLAG(ImGuiWindowFlags_NoFocusOnAppearing); - BIND_FLAG(ImGuiWindowFlags_NoBringToFrontOnFocus); - BIND_FLAG(ImGuiWindowFlags_AlwaysVerticalScrollbar); - BIND_FLAG(ImGuiWindowFlags_AlwaysHorizontalScrollbar); - BIND_FLAG(ImGuiWindowFlags_AlwaysUseWindowPadding); - BIND_FLAG(ImGuiWindowFlags_NoNavInputs); - BIND_FLAG(ImGuiWindowFlags_NoNavFocus); - BIND_FLAG(ImGuiWindowFlags_UnsavedDocument); - BIND_FLAG(ImGuiWindowFlags_NoNav); - BIND_FLAG(ImGuiWindowFlags_NoDecoration); - BIND_FLAG(ImGuiWindowFlags_NoInputs); - BIND_FLAG(ImGuiWindowFlags_NavFlattened); - BIND_FLAG(ImGuiWindowFlags_ChildWindow); - BIND_FLAG(ImGuiWindowFlags_Tooltip); - BIND_FLAG(ImGuiWindowFlags_Popup); - BIND_FLAG(ImGuiWindowFlags_Modal); - BIND_FLAG(ImGuiWindowFlags_ChildMenu); - BIND_FLAG(ImGuiButtonFlags_None); - BIND_FLAG(ImGuiButtonFlags_MouseButtonLeft); - BIND_FLAG(ImGuiButtonFlags_MouseButtonRight); - BIND_FLAG(ImGuiButtonFlags_MouseButtonMiddle); - BIND_FLAG(ImGuiButtonFlags_MouseButtonMask_); - BIND_FLAG(ImGuiButtonFlags_MouseButtonDefault_); + const auto entries = { + BIND_FLAG(ImGuiWindowFlags_None), + BIND_FLAG(ImGuiWindowFlags_NoTitleBar), + BIND_FLAG(ImGuiWindowFlags_NoResize), + BIND_FLAG(ImGuiWindowFlags_NoMove), + BIND_FLAG(ImGuiWindowFlags_NoScrollbar), + BIND_FLAG(ImGuiWindowFlags_NoScrollWithMouse), + BIND_FLAG(ImGuiWindowFlags_NoCollapse), + BIND_FLAG(ImGuiWindowFlags_AlwaysAutoResize), + BIND_FLAG(ImGuiWindowFlags_NoBackground), + BIND_FLAG(ImGuiWindowFlags_NoSavedSettings), + BIND_FLAG(ImGuiWindowFlags_NoMouseInputs), + BIND_FLAG(ImGuiWindowFlags_MenuBar), + BIND_FLAG(ImGuiWindowFlags_HorizontalScrollbar), + BIND_FLAG(ImGuiWindowFlags_NoFocusOnAppearing), + BIND_FLAG(ImGuiWindowFlags_NoBringToFrontOnFocus), + BIND_FLAG(ImGuiWindowFlags_AlwaysVerticalScrollbar), + BIND_FLAG(ImGuiWindowFlags_AlwaysHorizontalScrollbar), + BIND_FLAG(ImGuiWindowFlags_AlwaysUseWindowPadding), + BIND_FLAG(ImGuiWindowFlags_NoNavInputs), + BIND_FLAG(ImGuiWindowFlags_NoNavFocus), + BIND_FLAG(ImGuiWindowFlags_UnsavedDocument), + BIND_FLAG(ImGuiWindowFlags_NoNav), + BIND_FLAG(ImGuiWindowFlags_NoDecoration), + BIND_FLAG(ImGuiWindowFlags_NoInputs), + BIND_FLAG(ImGuiWindowFlags_NavFlattened), + BIND_FLAG(ImGuiWindowFlags_ChildWindow), + BIND_FLAG(ImGuiWindowFlags_Tooltip), + BIND_FLAG(ImGuiWindowFlags_Popup), + BIND_FLAG(ImGuiWindowFlags_Modal), + BIND_FLAG(ImGuiWindowFlags_ChildMenu), + BIND_FLAG(ImGuiButtonFlags_None), + BIND_FLAG(ImGuiButtonFlags_MouseButtonLeft), + BIND_FLAG(ImGuiButtonFlags_MouseButtonRight), + BIND_FLAG(ImGuiButtonFlags_MouseButtonMiddle), + BIND_FLAG(ImGuiButtonFlags_MouseButtonMask_), + BIND_FLAG(ImGuiButtonFlags_MouseButtonDefault_), + BIND_FUNCTION("Begin", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + const auto result = ImGui::Begin(name.c_str(), nullptr, flags); + method->success(result); + }), + BIND_FUNCTION("End", [](uintptr_t, MethodCall* method) { + ImGui::End(); + method->success(); + }), + BIND_FUNCTION("BeginChild", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto size = method->GetArgument(1); + const auto border = method->GetArgument(2); + const auto flags = method->GetArgument(3); + const auto result = ImGui::BeginChild(name.c_str(), size, border, flags); + method->success(result); + }), + BIND_FUNCTION("EndChild", [](uintptr_t, MethodCall* method) { + ImGui::EndChild(); + method->success(); + }), + BIND_FUNCTION("BeginGroup", [](uintptr_t, MethodCall* method) { + ImGui::BeginGroup(); + method->success(); + }), + BIND_FUNCTION("EndGroup", [](uintptr_t, MethodCall* method) { + ImGui::EndGroup(); + method->success(); + }), + BIND_FUNCTION("BeginPopupContextItem", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + const auto result = ImGui::BeginPopupContextItem(name.c_str(), flags); + method->success(result); + }), + BIND_FUNCTION("BeginPopupContextWindow", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + const auto result = ImGui::BeginPopupContextWindow(name.c_str(), flags); + method->success(result); + }), + BIND_FUNCTION("BeginPopupContextVoid", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + const auto result = ImGui::BeginPopupContextVoid(name.c_str(), flags); + method->success(result); + }), + BIND_FUNCTION("BeginPopupModal", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + auto open = method->GetArgument(1); + const auto flags = method->GetArgument(2); + const auto result = ImGui::BeginPopupModal(name.c_str(), &open, flags); + method->success(result); + }), + BIND_FUNCTION("EndPopup", [](uintptr_t, MethodCall* method) { + ImGui::EndPopup(); + method->success(); + }), + BIND_FUNCTION("BeginPopup", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + const auto result = ImGui::BeginPopup(name.c_str(), flags); + method->success(result); + }), + BIND_FUNCTION("OpenPopup", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + ImGui::OpenPopup(name.c_str(), flags); + method->success(); + }), + BIND_FUNCTION("CloseCurrentPopup", [](uintptr_t, MethodCall* method) { + ImGui::CloseCurrentPopup(); + method->success(); + }), + BIND_FUNCTION("BeginTooltip", [](uintptr_t, MethodCall* method) { + ImGui::BeginTooltip(); + method->success(); + }), + BIND_FUNCTION("EndTooltip", [](uintptr_t, MethodCall* method) { + ImGui::EndTooltip(); + method->success(); + }), + BIND_FUNCTION("SetTooltip", [](uintptr_t, MethodCall* method) { + const auto text = method->GetArgument(0); + ImGui::SetTooltip(text.c_str()); + method->success(); + }), + BIND_FUNCTION("IsItemHovered", [](uintptr_t, MethodCall* method) { + const auto flags = method->GetArgument(0); + const auto result = ImGui::IsItemHovered(flags); + method->success(result); + }), + BIND_FUNCTION("IsItemActive", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemActive(); + method->success(result); + }), + BIND_FUNCTION("IsItemFocused", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemFocused(); + method->success(result); + }), + BIND_FUNCTION("IsItemClicked", [](uintptr_t, MethodCall* method) { + const auto button = method->GetArgument(0); + const auto result = ImGui::IsItemClicked(button); + method->success(result); + }), + BIND_FUNCTION("IsItemVisible", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemVisible(); + method->success(result); + }), + BIND_FUNCTION("IsItemEdited", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemEdited(); + method->success(result); + }), + BIND_FUNCTION("IsItemActivated", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemActivated(); + method->success(result); + }), + BIND_FUNCTION("IsItemDeactivated", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemDeactivated(); + method->success(result); + }), + BIND_FUNCTION("IsItemDeactivatedAfterEdit", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemDeactivatedAfterEdit(); + method->success(result); + }), + BIND_FUNCTION("IsItemToggledOpen", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsItemToggledOpen(); + method->success(result); + }), + BIND_FUNCTION("IsAnyItemHovered", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsAnyItemHovered(); + method->success(result); + }), + BIND_FUNCTION("IsAnyItemActive", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsAnyItemActive(); + method->success(result); + }), + BIND_FUNCTION("IsAnyItemFocused", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsAnyItemFocused(); + method->success(result); + }), + BIND_FUNCTION("GetItemRectMin", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetItemRectMin(); + method->success(result); + }), + BIND_FUNCTION("GetItemRectMax", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetItemRectMax(); + method->success(result); + }), + BIND_FUNCTION("GetItemRectSize", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetItemRectSize(); + method->success(result); + }), + BIND_FUNCTION("BeginChildFrame", [](uintptr_t, MethodCall* method) { + const auto id = method->GetArgument(0); + const auto size = method->GetArgument(1); + const auto flags = method->GetArgument(2); + const auto result = ImGui::BeginChildFrame(id, size, flags); + method->success(result); + }), + BIND_FUNCTION("EndChildFrame", [](uintptr_t, MethodCall* method) { + ImGui::EndChildFrame(); + method->success(); + }), + BIND_FUNCTION("CalcItemWidth", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::CalcItemWidth(); + method->success(result); + }), + BIND_FUNCTION("PushItemWidth", [](uintptr_t, MethodCall* method) { + const auto width = method->GetArgument(0); + ImGui::PushItemWidth(width); + method->success(); + }), + BIND_FUNCTION("PopItemWidth", [](uintptr_t, MethodCall* method) { + ImGui::PopItemWidth(); + method->success(); + }), + BIND_FUNCTION("SetNextItemWidth", [](uintptr_t, MethodCall* method) { + const auto width = method->GetArgument(0); + ImGui::SetNextItemWidth(width); + method->success(); + }), + BIND_FUNCTION("GetContentRegionAvail", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetContentRegionAvail(); + method->success(result); + }), + BIND_FUNCTION("GetContentRegionMax", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetContentRegionMax(); + method->success(result); + }), + BIND_FUNCTION("GetWindowContentRegionMin", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowContentRegionMin(); + method->success(result); + }), + BIND_FUNCTION("GetWindowContentRegionMax", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowContentRegionMax(); + method->success(result); + }), + BIND_FUNCTION("GetWindowContentRegionWidth", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowContentRegionWidth(); + method->success(result); + }), + BIND_FUNCTION("GetWindowDrawList", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowDrawList(); + method->success(result); + }), + BIND_FUNCTION("GetWindowPos", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowPos(); + method->success(result); + }), + BIND_FUNCTION("GetWindowSize", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowSize(); + method->success(result); + }), + BIND_FUNCTION("GetWindowWidth", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowWidth(); + method->success(result); + }), + BIND_FUNCTION("GetWindowHeight", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::GetWindowHeight(); + method->success(result); + }), + BIND_FUNCTION("IsWindowCollapsed", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsWindowCollapsed(); + method->success(result); + }), + BIND_FUNCTION("IsWindowAppearing", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::IsWindowAppearing(); + method->success(result); + }), + BIND_FUNCTION("SetWindowFontScale", [](uintptr_t, MethodCall* method) { + const auto scale = method->GetArgument(0); + ImGui::SetWindowFontScale(scale); + method->success(); + }), + BIND_FUNCTION("SetNextWindowPos", [](uintptr_t, MethodCall* method) { + const auto pos = method->GetArgument(0); + const auto cond = method->GetArgument(1); + const auto pivot = method->GetArgument(2); + ImGui::SetNextWindowPos(pos, cond, pivot); + method->success(); + }), + BIND_FUNCTION("SetNextWindowSize", [](uintptr_t, MethodCall* method) { + const auto size = method->GetArgument(0); + const auto cond = method->GetArgument(1); + ImGui::SetNextWindowSize(size, cond); + method->success(); + }), + BIND_FUNCTION("BeginTabBar", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto flags = method->GetArgument(1); + const auto result = ImGui::BeginTabBar(name.c_str(), flags); + method->success(result); + }), + BIND_FUNCTION("EndTabBar", [](uintptr_t, MethodCall* method) { + ImGui::EndTabBar(); + method->success(); + }), + BIND_FUNCTION("BeginTabItem", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + auto open = method->GetArgument(1); + const auto flags = method->GetArgument(2); + const auto result = ImGui::BeginTabItem(name.c_str(), &open, flags); + method->success(result); + }), + BIND_FUNCTION("EndTabItem", [](uintptr_t, MethodCall* method) { + ImGui::EndTabItem(); + method->success(); + }), + BIND_FUNCTION("BeginMenuBar", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::BeginMenuBar(); + method->success(result); + }), + BIND_FUNCTION("EndMenuBar", [](uintptr_t, MethodCall* method) { + ImGui::EndMenuBar(); + method->success(); + }), + BIND_FUNCTION("BeginMainMenuBar", [](uintptr_t, MethodCall* method) { + const auto result = ImGui::BeginMainMenuBar(); + method->success(result); + }), + BIND_FUNCTION("EndMainMenuBar", [](uintptr_t, MethodCall* method) { + ImGui::EndMainMenuBar(); + method->success(); + }), + BIND_FUNCTION("BeginMenu", [](uintptr_t, MethodCall* method) { + const auto name = method->GetArgument(0); + const auto enabled = method->GetArgument(1); + const auto result = ImGui::BeginMenu(name.c_str(), enabled); + method->success(result); + }), + BIND_FUNCTION("EndMenu", [](uintptr_t, MethodCall* method) { + ImGui::EndMenu(); + method->success(); + }), + BIND_FUNCTION("MenuItem", [](uintptr_t, MethodCall* method) { + const auto label = method->GetArgument(0); + const auto shortcut = method->GetArgument(1); + const auto selected = method->GetArgument(2); + const auto enabled = method->GetArgument(3); + const auto result = ImGui::MenuItem(label.c_str(), shortcut.c_str(), selected, enabled); + method->success(result); + }), + BIND_FUNCTION("Text", [](uintptr_t, MethodCall* method) { + const auto fmt = method->GetArgument(0); + ImGui::Text(fmt.c_str()); + method->success(); + }), + BIND_FUNCTION("TextColored", [](uintptr_t, MethodCall* method) { + const auto color = method->GetArgument(0); + const auto fmt = method->GetArgument(1); + ImGui::TextColored(color, fmt.c_str()); + method->success(); + }), + BIND_FUNCTION("TextDisabled", [](uintptr_t, MethodCall* method) { + const auto fmt = method->GetArgument(0); + ImGui::TextDisabled(fmt.c_str()); + method->success(); + }), + BIND_FUNCTION("TextWrapped", [](uintptr_t, MethodCall* method) { + const auto fmt = method->GetArgument(0); + ImGui::TextWrapped(fmt.c_str()); + method->success(); + }), + BIND_FUNCTION("LabelText", [](uintptr_t, MethodCall* method) { + const auto label = method->GetArgument(0); + const auto fmt = method->GetArgument(1); + ImGui::LabelText(label.c_str(), fmt.c_str()); + method->success(); + }), + BIND_FUNCTION("BulletText", [](uintptr_t, MethodCall* method) { + const auto fmt = method->GetArgument(0); + ImGui::BulletText(fmt.c_str()); + method->success(); + }), + BIND_FUNCTION("Button", [](uintptr_t, MethodCall* method) { + const auto count = method->ArgumentCount(); + if(count == 1) { + const auto label = method->GetArgument(0); + const auto result = ImGui::Button(label.c_str()); + method->success(result); + } else if(count == 3) { + const auto label = method->GetArgument(0); + const auto width = method->GetArgument(1); + const auto height = method->GetArgument(2); + const auto result = ImGui::Button(label.c_str(), ImVec2(width, height)); + method->success(result); + } + }), + BIND_FUNCTION("SmallButton", [](uintptr_t, MethodCall* method) { + const auto label = method->GetArgument(0); + const auto result = ImGui::SmallButton(label.c_str()); + method->success(result); + }), + BIND_FUNCTION("InvisibleButton", [](uintptr_t, MethodCall* method) { + const auto label = method->GetArgument(0); + const auto size = method->GetArgument(1); + const auto result = ImGui::InvisibleButton(label.c_str(), size); + method->success(result); + }), + BIND_FUNCTION("ArrowButton", [](uintptr_t, MethodCall* method) { + const auto label = method->GetArgument(0); + const auto dir = method->GetArgument(1); + const auto result = ImGui::ArrowButton(label.c_str(), dir); + method->success(result); + }), + BIND_FUNCTION("SameLine", [](uintptr_t, MethodCall* method) { + ImGui::SameLine(); + method->success(); + }), + }; - GameBridge::Instance->BindFunction("Begin", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::Begin(name.c_str(), nullptr, flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("End", [](uintptr_t ctx, MethodCall* method) { - ImGui::End(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginChild", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto size = method->GetArgument(1); - auto border = method->GetArgument(2); - auto flags = method->GetArgument(3); - auto result = ImGui::BeginChild(name.c_str(), size, border, flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndChild", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndChild(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginChildFrame", [](uintptr_t ctx, MethodCall* method) { - auto id = method->GetArgument(0); - auto size = method->GetArgument(1); - auto flags = method->GetArgument(2); - auto result = ImGui::BeginChildFrame(id, size, flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndChildFrame", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndChildFrame(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginTabBar", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginTabBar(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndTabBar", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndTabBar(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginTabItem", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(2); - auto result = ImGui::BeginTabItem(name.c_str(), nullptr, flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndTabItem", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndTabItem(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginMenuBar", [](uintptr_t ctx, MethodCall* method) { - auto result = ImGui::BeginMenuBar(); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndMenuBar", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndMenuBar(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginMainMenuBar", [](uintptr_t ctx, MethodCall* method) { - auto result = ImGui::BeginMainMenuBar(); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndMainMenuBar", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndMainMenuBar(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginMenu", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto enabled = method->GetArgument(1); - auto result = ImGui::BeginMenu(name.c_str(), enabled); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndMenu", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndMenu(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopup", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopup(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndPopup", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndPopup(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupModal", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(2); - auto result = ImGui::BeginPopupModal(name.c_str(), nullptr, flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndPopup", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndPopup(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextItem", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextItem(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextWindow", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextWindow(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextVoid", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextVoid(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginTooltip", [](uintptr_t ctx, MethodCall* method) { - ImGui::BeginTooltip(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("EndTooltip", [](uintptr_t ctx, MethodCall* method) { - ImGui::EndTooltip(); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextItem", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextItem(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextWindow", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextWindow(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextVoid", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextVoid(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextItem", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextItem(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextWindow", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextWindow(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("BeginPopupContextVoid", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - auto flags = method->GetArgument(1); - auto result = ImGui::BeginPopupContextVoid(name.c_str(), flags); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("MenuItem", [](uintptr_t ctx, MethodCall* method) { - auto label = method->GetArgument(0); - auto shortcut = method->GetArgument(1); - auto selected = method->GetArgument(2); - auto enabled = method->GetArgument(3); - auto result = ImGui::MenuItem(label.c_str(), shortcut.c_str(), selected, enabled); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("Text", [](uintptr_t ctx, MethodCall* method) { - auto fmt = method->GetArgument(0); - ImGui::Text(fmt.c_str()); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("TextColored", [](uintptr_t ctx, MethodCall* method) { - auto raw = method->GetArgument>(0); - auto fmt = method->GetArgument(1); - auto col = ImVec4(std::any_cast(raw[0]), std::any_cast(raw[1]), std::any_cast(raw[2]), std::any_cast(raw[3])); - ImGui::TextColored(col, fmt.c_str()); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("TextDisabled", [](uintptr_t ctx, MethodCall* method) { - auto fmt = method->GetArgument(0); - ImGui::TextDisabled(fmt.c_str()); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("TextWrapped", [](uintptr_t ctx, MethodCall* method) { - auto fmt = method->GetArgument(0); - ImGui::TextWrapped(fmt.c_str()); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("LabelText", [](uintptr_t ctx, MethodCall* method) { - auto label = method->GetArgument(0); - auto fmt = method->GetArgument(1); - ImGui::LabelText(label.c_str(), fmt.c_str()); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("BulletText", [](uintptr_t ctx, MethodCall* method) { - auto fmt = method->GetArgument(0); - ImGui::BulletText(fmt.c_str()); - method->success(); - }, "ImGui"); - GameBridge::Instance->BindFunction("Button", [](uintptr_t ctx, MethodCall* method) { - auto count = method->ArgumentCount(); - if(count == 1) { - auto label = method->GetArgument(0); - auto result = ImGui::Button(label.c_str()); - method->success(result); - } else if(count == 3) { - auto label = method->GetArgument(0); - auto width = method->GetArgument(1); - auto height = method->GetArgument(2); - auto result = ImGui::Button(label.c_str(), ImVec2(width, height)); - method->success(result); - } - }, "ImGui"); - GameBridge::Instance->BindFunction("SmallButton", [](uintptr_t ctx, MethodCall* method) { - auto label = method->GetArgument(0); - auto result = ImGui::SmallButton(label.c_str()); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("InvisibleButton", [](uintptr_t ctx, MethodCall* method) { - auto label = method->GetArgument(0); - auto size = method->GetArgument>(1); - auto result = ImGui::InvisibleButton(label.c_str(), ImVec2(std::any_cast(size[0]), std::any_cast(size[1]))); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("ArrowButton", [](uintptr_t ctx, MethodCall* method) { - auto label = method->GetArgument(0); - auto dir = method->GetArgument(1); - auto result = ImGui::ArrowButton(label.c_str(), dir); - method->success(result); - }, "ImGui"); - GameBridge::Instance->BindFunction("SameLine", [](uintptr_t ctx, MethodCall* method) { - ImGui::SameLine(); - method->success(); - }, "ImGui"); + GameBridge::Instance->Register(entries, "ImGui"); } \ No newline at end of file diff --git a/soh/soh/Enhancements/scripting-layer/interactors/n64-native/n64-bridge.cpp b/soh/soh/Enhancements/scripting-layer/interactors/n64-native/n64-bridge.cpp index e3db0588fb3..30c2b8b1d10 100644 --- a/soh/soh/Enhancements/scripting-layer/interactors/n64-native/n64-bridge.cpp +++ b/soh/soh/Enhancements/scripting-layer/interactors/n64-native/n64-bridge.cpp @@ -8,62 +8,82 @@ extern "C" { extern PlayState* gPlayState; } +#define CHECK_BTN_ALL(state, combo) (~((state) | ~(combo)) == 0) +#define CHECK_BTN_ANY(state, combo) (((state) & (combo)) != 0) + enum class ControllerMode { kPress, kHold, kRelease }; -#define BIND_BTN(btn) GameBridge::Instance->BindField(#btn, btn, "N64"); -#define BIND_MODE(mode) GameBridge::Instance->BindField(#mode, (int) ControllerMode::mode, "ControllerMode"); +#define BIND_BTN(btn) BIND_FIELD(#btn, btn) +#define BIND_MODE(mode) BIND_FIELD(#mode, (int) ControllerMode::mode) void N64Bridge::Initialize() { // Push button constants - BIND_BTN(BTN_A) BIND_BTN(BTN_B) - BIND_BTN(BTN_L) BIND_BTN(BTN_R) - BIND_BTN(BTN_Z) BIND_BTN(BTN_START) - - BIND_BTN(BTN_CUP) BIND_BTN(BTN_CDOWN) - BIND_BTN(BTN_CLEFT) BIND_BTN(BTN_CRIGHT) - - BIND_BTN(BTN_DUP) BIND_BTN(BTN_DDOWN) - BIND_BTN(BTN_DLEFT) BIND_BTN(BTN_DRIGHT) - - BIND_BTN(BTN_STICKUP) BIND_BTN(BTN_STICKDOWN) - BIND_BTN(BTN_STICKLEFT) BIND_BTN(BTN_STICKRIGHT) - - BIND_BTN(BTN_VSTICKUP) BIND_BTN(BTN_VSTICKDOWN) - BIND_BTN(BTN_VSTICKLEFT) BIND_BTN(BTN_VSTICKRIGHT) - - BIND_BTN(BTN_MODIFIER1) BIND_BTN(BTN_MODIFIER2) - - // Push controller modes - BIND_MODE(kPress) BIND_MODE(kHold) BIND_MODE(kRelease) - - GameBridge::Instance->BindFunction("RawControllerInput", [](uintptr_t ctx, MethodCall* method) { - auto type = (ControllerMode) method->GetArgument(0); - auto slot = method->GetArgument(1); - int buttons = -1; - - if(gPlayState == nullptr) { - method->error("No play state"); - return; - } - - switch (type) { - case ControllerMode::kPress: - buttons = gPlayState->state.input[slot].press.button; - break; - case ControllerMode::kHold: - buttons = gPlayState->state.input[slot].cur.button; - break; - case ControllerMode::kRelease: - buttons = gPlayState->state.input[slot].rel.button; - break; - default: - method->error("Invalid controller mode"); - return; - } + const auto entries = { + BIND_BTN(BTN_A), BIND_BTN(BTN_B), + BIND_BTN(BTN_L), BIND_BTN(BTN_R), + BIND_BTN(BTN_Z), BIND_BTN(BTN_START), + + BIND_BTN(BTN_CUP), BIND_BTN(BTN_CDOWN), + BIND_BTN(BTN_CLEFT), BIND_BTN(BTN_CRIGHT), + + BIND_BTN(BTN_DUP), BIND_BTN(BTN_DDOWN), + BIND_BTN(BTN_DLEFT), BIND_BTN(BTN_DRIGHT), + + BIND_BTN(BTN_STICKUP), BIND_BTN(BTN_STICKDOWN), + BIND_BTN(BTN_STICKLEFT), BIND_BTN(BTN_STICKRIGHT), - method->success(buttons); - }, "N64"); + BIND_BTN(BTN_VSTICKUP), BIND_BTN(BTN_VSTICKDOWN), + BIND_BTN(BTN_VSTICKLEFT), BIND_BTN(BTN_VSTICKRIGHT), + + BIND_BTN(BTN_MODIFIER1), BIND_BTN(BTN_MODIFIER2), + + BIND_MODE(kPress), BIND_MODE(kHold), BIND_MODE(kRelease), + + BIND_FUNCTION("RawControllerInput", [](uintptr_t, MethodCall* method) { + const auto type = method->GetArgument(0); + const auto slot = method->GetArgument(1); + int buttons = -1; + + if(gPlayState == nullptr) { + method->error("No play state"); + return; + } + + switch (static_cast(type)) { + case ControllerMode::kPress: + buttons = gPlayState->state.input[slot].press.button; + break; + case ControllerMode::kHold: + buttons = gPlayState->state.input[slot].cur.button; + break; + case ControllerMode::kRelease: + buttons = gPlayState->state.input[slot].rel.button; + break; + default: + method->error("Invalid controller mode"); + return; + } + + method->success(buttons); + }), + + BIND_FUNCTION("CheckBtnAll", [](uintptr_t, MethodCall* method) { + const auto state = method->GetArgument(0); + const auto combo = method->GetArgument(1); + + method->success(CHECK_BTN_ALL(state, combo)); + }), + + BIND_FUNCTION("CheckBtnAny", [](uintptr_t, MethodCall* method) { + const auto state = method->GetArgument(0); + const auto combo = method->GetArgument(1); + + method->success(CHECK_BTN_ANY(state, combo)); + }) + }; + + GameBridge::Instance->Register(entries, "N64"); } \ No newline at end of file diff --git a/soh/soh/Enhancements/scripting-layer/interactors/soh/soh-bridge.cpp b/soh/soh/Enhancements/scripting-layer/interactors/soh/soh-bridge.cpp index 14d8225be3f..9fdded833fb 100644 --- a/soh/soh/Enhancements/scripting-layer/interactors/soh/soh-bridge.cpp +++ b/soh/soh/Enhancements/scripting-layer/interactors/soh/soh-bridge.cpp @@ -3,61 +3,64 @@ #include "soh/Enhancements/scripting-layer/bridge.h" #include "soh/Enhancements/scripting-layer/types/hostfunction.h" -#include #include void BindUIWidgets(){ - GameBridge::Instance->BindFunction("WrappedText", [](uintptr_t ctx, MethodCall* method) { - auto text = method->GetArgument(0); - auto charactersPerLine = method->GetArgument(1); - auto result = UIWidgets::WrappedText(text, charactersPerLine); - method->success(std::string(result)); - }, "UIWidgets"); - GameBridge::Instance->BindFunction("SetLastItemHoverText", [](uintptr_t ctx, MethodCall* method) { - auto text = method->GetArgument(0); - UIWidgets::SetLastItemHoverText(text); - method->success(); - }, "UIWidgets"); - GameBridge::Instance->BindFunction("InsertHelpHoverText", [](uintptr_t ctx, MethodCall* method) { - auto text = method->GetArgument(0); - UIWidgets::InsertHelpHoverText(text); - method->success(); - }, "UIWidgets"); - GameBridge::Instance->BindFunction("Tooltip", [](uintptr_t ctx, MethodCall* method) { - auto text = method->GetArgument(0); - UIWidgets::Tooltip(text.c_str()); - method->success(); - }, "UIWidgets"); - GameBridge::Instance->BindFunction("Tooltip", [](uintptr_t ctx, MethodCall* method) { - auto text = method->GetArgument(0); - UIWidgets::Tooltip(text.c_str()); - method->success(); - }, "UIWidgets"); - GameBridge::Instance->BindFunction("Spacer", [](uintptr_t ctx, MethodCall* method) { - auto height = method->GetArgument(0); - UIWidgets::Spacer(height); - method->success(); - }, "UIWidgets"); + + const auto entries = { + BIND_FUNCTION("WrappedText", [](uintptr_t, MethodCall* method) { + const auto text = method->GetArgument(0); + const auto charactersPerLine = method->GetArgument(1); + const auto result = UIWidgets::WrappedText(text, charactersPerLine); + method->success(std::string(result)); + }), + BIND_FUNCTION("SetLastItemHoverText", [](uintptr_t, MethodCall* method) { + const auto text = method->GetArgument(0); + UIWidgets::SetLastItemHoverText(text); + method->success(); + }), + BIND_FUNCTION("InsertHelpHoverText", [](uintptr_t, MethodCall* method) { + const auto text = method->GetArgument(0); + UIWidgets::InsertHelpHoverText(text); + method->success(); + }), + BIND_FUNCTION("Tooltip", [](uintptr_t, MethodCall* method) { + const auto text = method->GetArgument(0); + UIWidgets::Tooltip(text.c_str()); + method->success(); + }), + BIND_FUNCTION("Spacer", [](uintptr_t, MethodCall* method) { + const auto height = method->GetArgument(0); + UIWidgets::Spacer(height); + method->success(); + }), + }; + + GameBridge::Instance->Register(entries, "UIWidgets"); } void BindSohImgui(){ - GameBridge::Instance->BindFunction("AddWindow", [](uintptr_t ctx, MethodCall* method) { - auto category = method->GetArgument(0); - auto name = method->GetArgument(1); - auto callback = method->GetArgument(2); - // SohImGui::AddWindow(category, name, [callback](bool& open){ - // callback->execute(open); - // }); - method->success(); - }, "SohImGui"); - GameBridge::Instance->BindFunction("RemoveWindow", [](uintptr_t ctx, MethodCall* method) { - auto name = method->GetArgument(0); - // SohImGui::RemoveWindow(name); - method->success(); - }, "SohImGui"); + const auto entries = { + BIND_FUNCTION("AddWindow", [](uintptr_t ctx, MethodCall* method) { + const auto category = method->GetArgument(0); + const auto name = method->GetArgument(1); + const auto callback = method->GetArgument(2); + // SohImGui::AddWindow(category, name, [callback](bool& open){ + // callback->execute(open); + // }); + method->success(); + }), + BIND_FUNCTION("RemoveWindow", [](uintptr_t ctx, MethodCall* method) { + const auto name = method->GetArgument(0); + // SohImGui::RemoveWindow(name); + method->success(); + }), + }; + + GameBridge::Instance->Register(entries, "SohImGui"); } void SOHBridge::Initialize() { BindUIWidgets(); - BindSohImgui(); + // BindSohImgui(); } \ No newline at end of file diff --git a/soh/soh/Enhancements/scripting-layer/types/methodcall.h b/soh/soh/Enhancements/scripting-layer/types/methodcall.h index 62391b8abdc..1d61ec32cc6 100644 --- a/soh/soh/Enhancements/scripting-layer/types/methodcall.h +++ b/soh/soh/Enhancements/scripting-layer/types/methodcall.h @@ -19,7 +19,7 @@ enum class BindingType { struct GameBinding { BindingType type; std::variant binding; - ModName modName; + std::string module = ROOT_MODULE; }; class MethodCall {