diff --git a/source/acmd_imports.hpp b/source/acmd_imports.hpp index 69e8e7c..ea4e17f 100644 --- a/source/acmd_imports.hpp +++ b/source/acmd_imports.hpp @@ -3,17 +3,17 @@ #include <switch.h> -namespace app::sv_animcmd -{ - extern void frame(u64, float) asm("_ZN3app10sv_animcmd5frameEP9lua_Statef") LINKABLE; - extern void is_excute(u64) asm("_ZN3app10sv_animcmd9is_excuteEP9lua_State") LINKABLE; - extern u64 ATTACK(u64) asm("_ZN3app10sv_animcmd6ATTACKEP9lua_State") LINKABLE; - extern u64 EFFECT(u64) asm("_ZN3app10sv_animcmd6EFFECTEP9lua_State") LINKABLE; +namespace app::sv_animcmd { + extern void wait(u64, float) asm("_ZN3app10sv_animcmd4waitEP9lua_Statef") LINKABLE; + extern void frame(u64, float) asm("_ZN3app10sv_animcmd5frameEP9lua_Statef") LINKABLE; + extern void is_excute(u64) asm("_ZN3app10sv_animcmd9is_excuteEP9lua_State") LINKABLE; + extern u64 ATTACK(u64) asm("_ZN3app10sv_animcmd6ATTACKEP9lua_State") LINKABLE; + extern u64 CATCH(u64) asm("_ZN3app10sv_animcmd5CATCHEP9lua_State") LINKABLE; - extern u64 EFFECT(u64) asm("_ZN3app10sv_animcmd6EFFECTEP9lua_State") LINKABLE; - extern u64 EFFECT_FOLLOW_NO_SCALE(u64) asm("_ZN3app10sv_animcmd22EFFECT_FOLLOW_NO_SCALEEP9lua_State") LINKABLE; - extern u64 LAST_EFFECT_SET_COLOR(u64) asm("_ZN3app10sv_animcmd21LAST_EFFECT_SET_COLOREP9lua_State") LINKABLE; - extern u64 LAST_EFFECT_SET_RATE(u64) asm("_ZN3app10sv_animcmd20LAST_EFFECT_SET_RATEEP9lua_State") LINKABLE; + extern u64 EFFECT(u64) asm("_ZN3app10sv_animcmd6EFFECTEP9lua_State") LINKABLE; + extern u64 EFFECT_FOLLOW_NO_SCALE(u64) asm("_ZN3app10sv_animcmd22EFFECT_FOLLOW_NO_SCALEEP9lua_State") LINKABLE; + extern u64 LAST_EFFECT_SET_COLOR(u64) asm("_ZN3app10sv_animcmd21LAST_EFFECT_SET_COLOREP9lua_State") LINKABLE; + extern u64 LAST_EFFECT_SET_RATE(u64) asm("_ZN3app10sv_animcmd20LAST_EFFECT_SET_RATEEP9lua_State") LINKABLE; } -#endif // ACMD_IMPORTS_H \ No newline at end of file +#endif // ACMD_IMPORTS_H diff --git a/source/acmd_wrapper.hpp b/source/acmd_wrapper.hpp index 14768b2..96018cd 100644 --- a/source/acmd_wrapper.hpp +++ b/source/acmd_wrapper.hpp @@ -5,201 +5,229 @@ #include "acmd_imports.hpp" #include "l2c_imports.hpp" -#include "lua_helper.hpp" #include <initializer_list> using namespace lib; u64 load_module(u64 module_accessor, u64 module_offset) { - return LOAD64(module_accessor + module_offset); + return LOAD64(module_accessor + module_offset); } void* load_module_impl(u64 module, u64 function_offset) { - u64 function_impl = LOAD64(module) + function_offset; - return (void*) LOAD64(function_impl); -} - -namespace app::sv_system -{ - u64 battle_object_module_accessor(u64) asm("_ZN3app9sv_system29battle_object_module_accessorEP9lua_State") LINKABLE; + u64 function_impl = LOAD64(module) + function_offset; + return (void*) LOAD64(function_impl); } namespace app::sv_math { - int rand(u64 hash, int endIndex) asm("_ZN3app7sv_math4randEN3phx6Hash40Ei") LINKABLE; + int rand(u64, int) asm("_ZN3app7sv_math4randEN3phx6Hash40Ei") LINKABLE; } -namespace app::lua_bind -{ - namespace AttackModule { - void clear_all(u64) asm("_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - } - - namespace ControlModule { - bool check_button_on(u64, int) asm("_ZN3app8lua_bind35ControlModule__check_button_on_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; - } - - namespace EffectModule { - // boma, effect, joint, pos, rot, size, random_pos, random_rot, NO_SCALE?, attr?, unkint1, unkint2 - uint req_on_joint(u64, u64, u64, const Vector3f*, const Vector3f*, float a6, const Vector3f*, const Vector3f*, bool, uint, int, int) - asm("_ZN3app8lua_bind31EffectModule__req_on_joint_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40ES4_RKNS3_8Vector3fES7_fS7_S7_bjii") LINKABLE; - - void kill_kind(u64, u64, bool, bool) - asm("_ZN3app8lua_bind28EffectModule__kill_kind_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40Ebb") LINKABLE; - } - - namespace FighterManager { - u64 get_fighter_information(u64, int) asm("_ZN3app8lua_bind44FighterManager__get_fighter_information_implEPNS_14FighterManagerENS_14FighterEntryIDE") LINKABLE; - } - - namespace FighterInformation { - bool is_operation_cpu(u64) asm("_ZN3app8lua_bind41FighterInformation__is_operation_cpu_implEPNS_18FighterInformationE") LINKABLE; - } - - namespace MotionModule { - float frame(u64) asm("_ZN3app8lua_bind24MotionModule__frame_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - u64 motion_kind(u64) asm("_ZN3app8lua_bind30MotionModule__motion_kind_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - } - - namespace PostureModule { - float lr(u64) asm("_ZN3app8lua_bind22PostureModule__lr_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - float pos_x(u64) asm("_ZN3app8lua_bind25PostureModule__pos_x_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - float pos_y(u64) asm("_ZN3app8lua_bind25PostureModule__pos_y_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - float set_pos(u64, const Vector3f*) asm("_ZN3app8lua_bind27PostureModule__set_pos_implEPNS_26BattleObjectModuleAccessorERKN3phx8Vector3fE") LINKABLE; - } - - namespace StatusModule { - u64 change_status_request_from_script(u64, int, bool) asm("_ZN3app8lua_bind52StatusModule__change_status_request_from_script_implEPNS_26BattleObjectModuleAccessorEib") LINKABLE; - int status_kind(u64) asm("_ZN3app8lua_bind30StatusModule__status_kind_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - int situation_kind(u64) asm("_ZN3app8lua_bind33StatusModule__situation_kind_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; - } - - namespace WorkModule { - // PT crashes if this doesn't return a bool? - bool get_int(u64, int) asm("_ZN3app8lua_bind24WorkModule__get_int_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; - int get_param_int(u64, u64, u64) asm("_ZN3app8lua_bind30WorkModule__get_param_int_implEPNS_26BattleObjectModuleAccessorEmm") LINKABLE; - void inc_int(u64, int) asm("_ZN3app8lua_bind24WorkModule__inc_int_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; - } +namespace app::sv_system { + u64 battle_object(u64) asm("_ZN3app9sv_system13battle_objectEP9lua_State") LINKABLE; + u64 battle_object_module_accessor(u64) asm("_ZN3app9sv_system29battle_object_module_accessorEP9lua_State") LINKABLE; + u8 battle_object_category(u64) asm("_ZN3app9sv_system22battle_object_categoryEP9lua_State") LINKABLE; + int battle_object_kind(u64) asm("_ZN3app9sv_system18battle_object_kindEP9lua_State") LINKABLE; } -struct ACMD -{ - L2CAgent* l2c_agent; - u64 module_accessor; +namespace app::lua_bind { + namespace AttackModule { + void clear_all(u64) asm("_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + } - ACMD(L2CAgent* agent) { - l2c_agent = agent; - module_accessor = app::sv_system::battle_object_module_accessor(l2c_agent->lua_state_agent); - } + namespace ControlModule { + bool check_button_on(u64, int) asm("_ZN3app8lua_bind35ControlModule__check_button_on_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; + } - void frame(float f) { - app::sv_animcmd::frame(l2c_agent->lua_state_agent, f); - l2c_agent->clear_lua_stack(); - } + namespace EffectModule { + // boma, effect, joint, pos, rot, size, random_pos, random_rot, NO_SCALE?, attr?, unkint1, unkint2 + uint req_on_joint(u64, u64, u64, const Vector3f*, const Vector3f*, float a6, const Vector3f*, const Vector3f*, bool, uint, int, int) + asm("_ZN3app8lua_bind31EffectModule__req_on_joint_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40ES4_RKNS3_8Vector3fES7_fS7_S7_bjii") LINKABLE; - bool is_excute() { - app::sv_animcmd::is_excute(l2c_agent->lua_state_agent); - L2CValue is_excute; - l2c_agent->get_lua_stack(1, &is_excute); - bool excute = is_excute.raw; - l2c_agent->clear_lua_stack(); - return excute; - } + void kill_kind(u64, u64, bool, bool) asm("_ZN3app8lua_bind28EffectModule__kill_kind_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40Ebb") LINKABLE; + } - void wrap( u64 (*acmd_func)(u64), std::initializer_list<L2CValue> list ) - { - l2c_agent->clear_lua_stack(); - for( L2CValue elem : list ) - l2c_agent->push_lua_stack(&elem); + namespace FighterManager { + u64 get_fighter_information(u64, int) asm("_ZN3app8lua_bind44FighterManager__get_fighter_information_implEPNS_14FighterManagerENS_14FighterEntryIDE") LINKABLE; + } - acmd_func(l2c_agent->lua_state_agent); - l2c_agent->clear_lua_stack(); - } + namespace FighterInformation { + bool is_operation_cpu(u64) asm("_ZN3app8lua_bind41FighterInformation__is_operation_cpu_implEPNS_18FighterInformationE") LINKABLE; + } - void ATTACK( - u64 i1, - u64 i2, - u64 h1, - float f1, - u64 i3, - u64 i4, - u64 i5, - u64 i6, - float f2, - float f3, - float f4, - float f5, - //void, - //void, - //void, - float f6, - float f7, - u64 i7, - u64 i8, - u64 i9, - u64 i10, - float f8, - u64 i11, - u64 i12, - u64 i13, - u64 i14, - u64 i15, - u64 i16, - u64 i17, - u64 i18, - u64 i19, - u64 i20, - u64 h2, - u64 i21, - u64 i22, - u64 i23 - ) { - L2CValue hitbox_params[36] = { - L2CValue(i1), // ID - L2CValue(i2), // Unk - L2CValue(h1), // Joint - L2CValue(f1), // Damage - L2CValue(i3), // Angle - L2CValue(i4), // KBG - L2CValue(i5), // WBKB - L2CValue(i6), // BKB - L2CValue(f2), // Size - L2CValue(f3), // X - L2CValue(f4), // Y - L2CValue(f5), // Z - L2CValue("void"), // X2 - L2CValue("void"), // Y2 - L2CValue("void"), // Z2 - L2CValue(f6), // Hitlag - L2CValue(f7), // SDI - L2CValue(i7), - L2CValue(i8), - L2CValue(i9), - L2CValue(i10), - L2CValue(f8), - L2CValue(i11), - L2CValue(i12), - L2CValue(i13), - L2CValue(i14), - L2CValue(i15), - L2CValue(i16), - L2CValue(i17), - L2CValue(i18), - L2CValue(i19), - L2CValue(i20), - L2CValue(h2), - L2CValue(i21), - L2CValue(i22), - L2CValue(i23) - }; + namespace MotionModule { + float frame(u64) asm("_ZN3app8lua_bind24MotionModule__frame_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + u64 motion_kind(u64) asm("_ZN3app8lua_bind30MotionModule__motion_kind_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + } - for (size_t i = 0; i < 36; i++) - l2c_agent->push_lua_stack(&hitbox_params[i]); + namespace PostureModule { + float lr(u64) asm("_ZN3app8lua_bind22PostureModule__lr_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + float pos_x(u64) asm("_ZN3app8lua_bind25PostureModule__pos_x_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + float pos_y(u64) asm("_ZN3app8lua_bind25PostureModule__pos_y_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + float set_pos(u64, const Vector3f*) asm("_ZN3app8lua_bind27PostureModule__set_pos_implEPNS_26BattleObjectModuleAccessorERKN3phx8Vector3fE") LINKABLE; + } - app::sv_animcmd::ATTACK(l2c_agent->lua_state_agent); + namespace StatusModule { + u64 change_status_request_from_script(u64, int, bool) asm("_ZN3app8lua_bind52StatusModule__change_status_request_from_script_implEPNS_26BattleObjectModuleAccessorEib") LINKABLE; + int status_kind(u64) asm("_ZN3app8lua_bind30StatusModule__status_kind_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + int situation_kind(u64) asm("_ZN3app8lua_bind33StatusModule__situation_kind_implEPNS_26BattleObjectModuleAccessorE") LINKABLE; + } - l2c_agent->clear_lua_stack(); - } + namespace WorkModule { + float get_float(u64, int) asm("_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; + int get_int(u64, int) asm("_ZN3app8lua_bind24WorkModule__get_int_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; + void inc_int(u64, int) asm("_ZN3app8lua_bind24WorkModule__inc_int_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; + float get_param_float(u64, u64, u64) asm("_ZN3app8lua_bind32WorkModule__get_param_float_implEPNS_26BattleObjectModuleAccessorEmm") LINKABLE; + int get_param_int(u64, u64, u64) asm("_ZN3app8lua_bind30WorkModule__get_param_int_implEPNS_26BattleObjectModuleAccessorEmm") LINKABLE; + void on_flag(u64, int) asm("_ZN3app8lua_bind24WorkModule__on_flag_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; + void off_flag(u64, int) asm("_ZN3app8lua_bind25WorkModule__off_flag_implEPNS_26BattleObjectModuleAccessorEi") LINKABLE; + float set_float(u64, float, int) asm("_ZN3app8lua_bind26WorkModule__set_float_implEPNS_26BattleObjectModuleAccessorEfi") LINKABLE; + int set_int(u64, int, int) asm("_ZN3app8lua_bind24WorkModule__set_int_implEPNS_26BattleObjectModuleAccessorEii") LINKABLE; + } +} + +struct ACMD { + L2CAgent* l2c_agent; + u64 module_accessor; + + ACMD(L2CAgent* agent) { + l2c_agent = agent; + module_accessor = app::sv_system::battle_object_module_accessor(l2c_agent->lua_state_agent); + } + + void frame(float f) { + l2c_agent->clear_lua_stack(); + L2CValue frame_val(f); + l2c_agent->push_lua_stack(&frame_val); + app::sv_animcmd::frame(l2c_agent->lua_state_agent, f); + l2c_agent->clear_lua_stack(); + } + + void wait(float f) { + l2c_agent->clear_lua_stack(); + L2CValue frame_val(f); + l2c_agent->push_lua_stack(&frame_val); + app::sv_animcmd::wait(l2c_agent->lua_state_agent, f); + l2c_agent->clear_lua_stack(); + } + + bool is_excute() { + l2c_agent->clear_lua_stack(); + app::sv_animcmd::is_excute(l2c_agent->lua_state_agent); + L2CValue is_excute; + l2c_agent->get_lua_stack(1, &is_excute); + bool excute = (bool)(is_excute); + l2c_agent->clear_lua_stack(); + return excute; + } + + void wrap(u64 (*acmd_func)(u64), std::initializer_list<L2CValue> list) { + l2c_agent->clear_lua_stack(); + for (L2CValue elem : list) + l2c_agent->push_lua_stack(&elem); + acmd_func(l2c_agent->lua_state_agent); + l2c_agent->clear_lua_stack(); + } + + void ATTACK( + u64 i1, // ID + u64 i2, // Part + u64 h1, // Bone + float f1, // Damage + u64 i3, // Angle + u64 i4, // KBG + u64 i5, // FKB + u64 i6, // BKB + float f2, // Size + float f3, // X + float f4, // Y + float f5, // Z + // X2 + // Y2 + // Z2 + float f6, // Hitlag + float f7, // SDI + u64 i7, // Clang/Rebound + u64 i8, // Facing Restriction + u64 i9, // Fixed Weight + u64 i10, // Shield Damage + float f8, // Trip Chance + u64 i11, // Rehit Rate + u64 i12, // Reflectable + u64 i13, // Absorbable + u64 i14, // Flinchless + u64 i15, // Disable Hitlag + u64 i16, // Direct + u64 i17, // Ground/Air + u64 i18, // Hit Bits + u64 i19, // Collision Bits + u64 i20, // Friendly Fire + u64 h2, // Effect + u64 i21, // SFX Level + u64 i22, // SFX Type + u64 i23) { // Move Type + wrap(app::sv_animcmd::ATTACK, { + L2CValue(i1), L2CValue(i2), L2CValue(h1), L2CValue(f1), + L2CValue(i3), L2CValue(i4), L2CValue(i5), L2CValue(i6), + L2CValue(f2), L2CValue(f3), L2CValue(f4), L2CValue(f5), + L2CValue(), L2CValue(), L2CValue(), L2CValue(f6), + L2CValue(f7), L2CValue(i7), L2CValue(i8), L2CValue(i9), + L2CValue(i10), L2CValue(f8), L2CValue(i11), L2CValue(i12), + L2CValue(i13), L2CValue(i14), L2CValue(i15), L2CValue(i16), + L2CValue(i17), L2CValue(i18), L2CValue(i19), L2CValue(i20), + L2CValue(h2), L2CValue(i21), L2CValue(i22), L2CValue(i23) + }); + } + + void ATTACK( + u64 i1, // ID + u64 i2, // Part + u64 h1, // Bone + float f1, // Damage + u64 i3, // Angle + u64 i4, // KBG + u64 i5, // FKB + u64 i6, // BKB + float f2, // Size + float f3, // X + float f4, // Y + float f5, // Z + float fX2, // X2 + float fY2, // Y2 + float fZ2, // Z2 + float f6, // Hitlag + float f7, // SDI + u64 i7, // Clang/Rebound + u64 i8, // Facing Restriction + u64 i9, // Fixed Weight + u64 i10, // Shield Damage + float f8, // Trip Chance + u64 i11, // Rehit Rate + u64 i12, // Reflectable + u64 i13, // Absorbable + u64 i14, // Flinchless + u64 i15, // Disable Hitlag + u64 i16, // Direct + u64 i17, // Ground/Air + u64 i18, // Hit Bits + u64 i19, // Collision Bits + u64 i20, // Friendly Fire + u64 h2, // Effect + u64 i21, // SFX Level + u64 i22, // SFX Type + u64 i23) { // Move Type + wrap(app::sv_animcmd::ATTACK, { + L2CValue(i1), L2CValue(i2), L2CValue(h1), L2CValue(f1), + L2CValue(i3), L2CValue(i4), L2CValue(i5), L2CValue(i6), + L2CValue(f2), L2CValue(f3), L2CValue(f4), L2CValue(f5), + L2CValue(fX2), L2CValue(fY2), L2CValue(fZ2), L2CValue(f6), + L2CValue(f7), L2CValue(i7), L2CValue(i8), L2CValue(i9), + L2CValue(i10), L2CValue(f8), L2CValue(i11), L2CValue(i12), + L2CValue(i13), L2CValue(i14), L2CValue(i15), L2CValue(i16), + L2CValue(i17), L2CValue(i18), L2CValue(i19), L2CValue(i20), + L2CValue(h2), L2CValue(i21), L2CValue(i22), L2CValue(i23) + }); + } }; -#endif // ACMD_WRAPPER_H \ No newline at end of file +#endif // ACMD_WRAPPER_H diff --git a/source/const_value_table.h b/source/const_value_table.h index e55f707..a81ce11 100644 --- a/source/const_value_table.h +++ b/source/const_value_table.h @@ -1,5 +1,6 @@ #ifndef CONST_VALUE_TABLE_H #define CONST_VALUE_TABLE_H + #define LUA_SCRIPT_LINE_MAX lua_const("LUA_SCRIPT_LINE_MAX") #define LUA_SCRIPT_LINE_SYSTEM lua_const("LUA_SCRIPT_LINE_SYSTEM") #define LUA_SCRIPT_LINE_SYSTEM_POST lua_const("LUA_SCRIPT_LINE_SYSTEM_POST") @@ -15877,4 +15878,5 @@ #define ITEM_ZOROARK_INSTANCE_WORK_INT_TARGET_STATE lua_const("ITEM_ZOROARK_INSTANCE_WORK_INT_TARGET_STATE") #define ITEM_ZOROARK_INSTANCE_WORK_FLOAT_THROWUP_LR lua_const("ITEM_ZOROARK_INSTANCE_WORK_FLOAT_THROWUP_LR") #define ITEM_ZOROARK_INSTANCE_WORK_FLAG_THROW_UP_GRAVITY_START lua_const("ITEM_ZOROARK_INSTANCE_WORK_FLAG_THROW_UP_GRAVITY_START") + #endif // CONST_VALUE_TABLE_H diff --git a/source/crc32.h b/source/crc32.h index dd34249..66241b0 100644 --- a/source/crc32.h +++ b/source/crc32.h @@ -2,7 +2,6 @@ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or * code or tables extracted from it, as desired without restriction. */ - #ifndef CRC32_H #define CRC32_H @@ -55,8 +54,7 @@ const uint32_t crc32_tab[] = { 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -uint32_t crc32_part(const void *buf, size_t size, uint32_t crc) -{ +uint32_t crc32_part(const void *buf, size_t size, uint32_t crc) { const uint8_t* p = (const uint8_t*)buf; crc = crc ^ ~0U; while (size--) @@ -64,8 +62,7 @@ uint32_t crc32_part(const void *buf, size_t size, uint32_t crc) return crc ^ ~0U; } -uint32_t crc32(const void *buf, size_t size) -{ +uint32_t crc32(const void *buf, size_t size) { const uint8_t* p = (const uint8_t*)buf; uint32_t crc; crc = ~0U; @@ -74,10 +71,9 @@ uint32_t crc32(const void *buf, size_t size) return crc ^ ~0U; } -uint64_t hash40(const char* data) -{ +uint64_t hash40(const char* data) { size_t len = strlen(data); - return crc32(data, len) | (len & 0xFF) << 32; + return crc32(data, len) | (len & 0xFF) << 32; } #endif // CRC32_H diff --git a/source/hitbox_visualizer.hpp b/source/hitbox_visualizer.hpp index 4d91f98..6ba997c 100644 --- a/source/hitbox_visualizer.hpp +++ b/source/hitbox_visualizer.hpp @@ -1,9 +1,10 @@ #include <math.h> #include "l2c.hpp" -#include "saltysd_helper.hpp" #include "l2c_imports.hpp" -#include "acmd_imports.hpp" +#include "acmd_wrapper.hpp" +#include "saltysd_helper.hpp" +#include "const_value_table.h" #include "taunt_toggles.h" using namespace lib; @@ -13,144 +14,143 @@ using namespace app::sv_animcmd; void (*AttackModule_set_attack_lua_state)(u64, u64); Vector3f id_colors[8] = { - {1.0f, 0.0f, 0.0f}, {0.7843f, 0.3529f, 1.0f}, - {1.0f, 0.7843f, 0.7843f}, {0.0f, 1.0f, 0.8431f}, - {1.0f, 0.4706f, 0.0f}, {0.7843f, 0.7059f, 0.0f}, - {0.7843f, 0.0f, 1.0f}, {0.3765f, 0.2863f, 0.5294f}, + { 1.0f, 0.0f, 0.0f }, // 0xff0000 (red) + { 0.7843f, 0.3529f, 1.0f }, // 0xc85aff (purple) + { 1.0f, 0.7843f, 0.7843f }, // 0xffc8c8 (pink) + { 0.0f, 1.0f, 0.8431f }, // 0x00ffd7 (turquoise) + { 1.0f, 0.4706f, 0.0f }, // 0xff7800 (orange) + { 0.7843f, 0.7059f, 0.0f }, // 0xc8b400 (dark goldenrod) + { 0.7843f, 0.0f, 1.0f }, // 0xc800ff (purple) + { 0.3765f, 0.2863f, 0.5294f }, // 0x604987 (dark blue-gray) }; namespace app::lua_bind::AttackModule { - // Clear graphics every time we clear all hitboxes - void clear_all_replace(u64 module_accessor) { - if (is_training_mode()) { - // Only if we're not shielding - int status_kind = StatusModule::status_kind(module_accessor); - if (!(status_kind >= FIGHTER_STATUS_KIND_GUARD_ON && status_kind <= FIGHTER_STATUS_KIND_GUARD_OFF)) { - Hash40 shieldEffectHash = {.hash = 0xAFAE75F05LL}; - EffectModule::kill_kind(module_accessor, shieldEffectHash.hash, 0, 1); - } - } + // clear graphics every time we clear all hitboxes + void clear_all_replace(u64 module_accessor) { + if (is_training_mode()) { + // only if we're not shielding + int status_kind = StatusModule::status_kind(module_accessor); + if (!(status_kind >= FIGHTER_STATUS_KIND_GUARD_ON && status_kind <= FIGHTER_STATUS_KIND_GUARD_OFF)) { + Hash40 shieldEffectHash = { .hash = 0xAFAE75F05LL }; + EffectModule::kill_kind(module_accessor, shieldEffectHash.hash, 0, 1); + } + } - // call original AttackModule::clear_all_impl - u64 attack_module = load_module(module_accessor, 0xA0); - void (*clear_all)(u64) = (void(*)(u64))(load_module_impl(attack_module, 0x50)); + // call original AttackModule::clear_all_impl + u64 attack_module = load_module(module_accessor, 0xA0); + void (*clear_all)(u64) = (void(*)(u64))(load_module_impl(attack_module, 0x50)); - return clear_all(attack_module); - } + return clear_all(attack_module); + } } void generate_hitbox_effects(L2CAgent *l2c_agent, - L2CValue *id, L2CValue *bone, L2CValue *size, - L2CValue *x, L2CValue *y, L2CValue *z, - L2CValue *x2, L2CValue *y2, L2CValue *z2) { - Vector3f color = id_colors[id->raw % 8]; - L2CValue red(color.x); - L2CValue green(color.y); - L2CValue blue(color.z); + L2CValue *id, L2CValue *bone, L2CValue *size, + L2CValue *x, L2CValue *y, L2CValue *z, + L2CValue *x2, L2CValue *y2, L2CValue *z2) { + Vector3f color = id_colors[id->raw % 8]; + L2CValue red(color.x); + L2CValue green(color.y); + L2CValue blue(color.z); - float sizeMult = 19.0 / 200.0; - Hash40 shieldEffectHash = {.hash = 0xAFAE75F05LL}; + float sizeMult = 19.0 / 200.0; + Hash40 shieldEffectHash = { .hash = 0xAFAE75F05LL }; - L2CValue shieldEffect(shieldEffectHash.hash); - L2CValue xRot(0.0f); - L2CValue yRot(0.0f); - L2CValue zRot(0.0f); - L2CValue terminate(true); - L2CValue effectSize((float)size->raw_float * sizeMult); + L2CValue shieldEffect(shieldEffectHash.hash); + L2CValue xRot(0.0f); + L2CValue yRot(0.0f); + L2CValue zRot(0.0f); + L2CValue terminate(true); + L2CValue effectSize((float)size->raw_float * sizeMult); - L2CValue rate(8.0f); + L2CValue rate(8.0f); - float xDist = x2->raw_float - x->raw_float; - float yDist = y2->raw_float - y->raw_float; - float zDist = z2->raw_float - z->raw_float; + float xDist = x2->raw_float - x->raw_float; + float yDist = y2->raw_float - y->raw_float; + float zDist = z2->raw_float - z->raw_float; - int num_effects; - if (x2->type != L2C_void && y2->type != L2C_void && z2->type != L2C_void) { // extended hitbox - float dist = sqrt(xDist * xDist + yDist * yDist + xDist * xDist); - num_effects = ceil(dist / (size->raw_float * 0.95)); // just enough effects to form a continuous line - if (num_effects < 2) - num_effects = 2; - if (num_effects > 16) - num_effects = 16; - } else { // non-extended hitbox - *x2 = *x; - *y2 = *y; - *z2 = *z; - num_effects = 1; - } + int num_effects; + if (x2->type != L2C_void && y2->type != L2C_void && z2->type != L2C_void) { // extended hitbox + float dist = sqrt(xDist * xDist + yDist * yDist + xDist * xDist); + num_effects = ceil(dist / (size->raw_float * 0.95)); // just enough effects to form a continuous line + if (num_effects < 2) + num_effects = 2; + if (num_effects > 16) + num_effects = 16; + } else { // non-extended hitbox + *x2 = *x; + *y2 = *y; + *z2 = *z; + num_effects = 1; + } - for (int i = 0; i < num_effects; i++) { - float mult = (float)i / num_effects; - L2CValue currX(x->raw_float + xDist * mult); - L2CValue currY(y->raw_float + yDist * mult); - L2CValue currZ(z->raw_float + zDist * mult); + for (int i = 0; i < num_effects; i++) { + float mult = (float)i / num_effects; + L2CValue currX(x->raw_float + xDist * mult); + L2CValue currY(y->raw_float + yDist * mult); + L2CValue currZ(z->raw_float + zDist * mult); - ACMD acmd(l2c_agent); - acmd.wrap(EFFECT_FOLLOW_NO_SCALE, { shieldEffect, *bone, currX, currY, currZ, xRot, yRot, zRot, effectSize, terminate }); + ACMD acmd(l2c_agent); + acmd.wrap(EFFECT_FOLLOW_NO_SCALE, { shieldEffect, *bone, currX, currY, currZ, xRot, yRot, zRot, effectSize, terminate }); - // Set to hitbox ID color - acmd.wrap(LAST_EFFECT_SET_COLOR, { red, green, blue }); + // set to hitbox ID color + acmd.wrap(LAST_EFFECT_SET_COLOR, { red, green, blue }); - // Speed up animation by rate to remove pulsing effect - // LAST_EFFECT_SET_RATE(Rate) - acmd.wrap(LAST_EFFECT_SET_RATE, { rate }); - } + // speed up animation by rate to remove pulsing effect + acmd.wrap(LAST_EFFECT_SET_RATE, { rate }); + } } namespace app::sv_animcmd { - void ATTACK_replace(u64 a1) { - // Instantiate our own L2CAgent with the given lua_State - L2CAgent l2c_agent; - l2c_agent.L2CAgent_constr(a1); + void ATTACK_replace(u64 a1) { + // instantiate our own L2CAgent with the given lua_State + L2CAgent l2c_agent; + l2c_agent.L2CAgent_constr(a1); - // Get all necessary hitbox params - L2CValue id, bone, damage, angle, kbg, wkb, bkb, size, x, y, z, x2, y2, z2; - l2c_agent.get_lua_stack(1, &id); - l2c_agent.get_lua_stack(3, &bone); - l2c_agent.get_lua_stack(4, &damage); - l2c_agent.get_lua_stack(5, &angle); - l2c_agent.get_lua_stack(6, &kbg); - l2c_agent.get_lua_stack(7, &wkb); - l2c_agent.get_lua_stack(8, &bkb); - l2c_agent.get_lua_stack(9, &size); - l2c_agent.get_lua_stack(10, &x); - l2c_agent.get_lua_stack(11, &y); - l2c_agent.get_lua_stack(12, &z); - l2c_agent.get_lua_stack(13, &x2); - l2c_agent.get_lua_stack(14, &y2); - l2c_agent.get_lua_stack(15, &z2); + // get all necessary hitbox params + L2CValue id, bone, damage, angle, kbg, wkb, bkb, size, x, y, z, x2, y2, z2; + l2c_agent.get_lua_stack(1, &id); + l2c_agent.get_lua_stack(3, &bone); + l2c_agent.get_lua_stack(4, &damage); + l2c_agent.get_lua_stack(5, &angle); + l2c_agent.get_lua_stack(6, &kbg); + l2c_agent.get_lua_stack(7, &wkb); + l2c_agent.get_lua_stack(8, &bkb); + l2c_agent.get_lua_stack(9, &size); + l2c_agent.get_lua_stack(10, &x); + l2c_agent.get_lua_stack(11, &y); + l2c_agent.get_lua_stack(12, &z); + l2c_agent.get_lua_stack(13, &x2); + l2c_agent.get_lua_stack(14, &y2); + l2c_agent.get_lua_stack(15, &z2); - // original code: parse lua stack and call AttackModule::set_attack() - AttackModule_set_attack_lua_state(LOAD64(LOAD64(a1 - 8) + 416LL), a1); + // original code: parse lua stack and call AttackModule::set_attack() + AttackModule_set_attack_lua_state(LOAD64(LOAD64(a1 - 8) + 416LL), a1); - if (HITBOX_VIS && is_training_mode()) { - // Generate hitbox effect(s) - generate_hitbox_effects(&l2c_agent, &id, &bone, &size, &x, &y, &z, &x2, &y2, &z2); - } + if (HITBOX_VIS && is_training_mode()) { + generate_hitbox_effects(&l2c_agent, &id, &bone, &size, &x, &y, &z, &x2, &y2, &z2); // generate hitbox effect(s) + } - u64 v1, v2, i; - v1 = a1; + u64 v1, v2, i; + v1 = a1; - // original code: clear_lua_stack section - v2 = LOAD64(v1 + 16); - for (i = **(u64 **)(v1 + 32) + 16LL; v2 < i; v2 = LOAD64(v1 + 16)) { - LOAD64(v1 + 16) = v2 + 16; - *(__int32_t *)(v2 + 8) = 0; - } - LOAD64(v1 + 16) = i; - } + // original code: clear_lua_stack section + v2 = LOAD64(v1 + 16); + for (i = **(u64 **)(v1 + 32) + 16LL; v2 < i; v2 = LOAD64(v1 + 16)) { + LOAD64(v1 + 16) = v2 + 16; + *(__int32_t *)(v2 + 8) = 0; + } + LOAD64(v1 + 16) = i; + } } void hitbox_vis_main() { - AttackModule_set_attack_lua_state = - (void (*)(u64, u64))SaltySDCore_FindSymbol("_ZN3app10sv_animcmd6ATTACKEP9lua_State") + 0xD0 - 0x70; - - SaltySD_function_replace_sym( - "_ZN3app10sv_animcmd6ATTACKEP9lua_State", - (u64)&ATTACK_replace); - - SaltySD_function_replace_sym( - "_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE", - (u64)&AttackModule::clear_all_replace); + AttackModule_set_attack_lua_state = (void (*)(u64, u64))SaltySDCore_FindSymbol("_ZN3app10sv_animcmd6ATTACKEP9lua_State") + 0xD0 - 0x70; + SaltySD_function_replace_sym( + "_ZN3app10sv_animcmd6ATTACKEP9lua_State", + (u64)&ATTACK_replace); + SaltySD_function_replace_sym( + "_ZN3app8lua_bind28AttackModule__clear_all_implEPNS_26BattleObjectModuleAccessorE", + (u64)&AttackModule::clear_all_replace); } diff --git a/source/l2c.hpp b/source/l2c.hpp index 70ea469..80bb242 100644 --- a/source/l2c.hpp +++ b/source/l2c.hpp @@ -1,16 +1,14 @@ #ifndef L2C_H #define L2C_H -typedef struct Hash40 -{ - uint64_t hash : 40; +typedef struct Hash40 { + uint64_t hash : 40; } Hash40; -typedef struct Vector3f -{ - float x; - float y; - float z; +typedef struct Vector3f { + float x; + float y; + float z; } Vector3f; #endif // L2C_H diff --git a/source/l2c_imports.hpp b/source/l2c_imports.hpp index 5084115..c5b61f3 100644 --- a/source/l2c_imports.hpp +++ b/source/l2c_imports.hpp @@ -1,7 +1,10 @@ #ifndef L2C_IMPORTS_H #define L2C_IMPORTS_H + #include <switch.h> +#include <math.h> + #include "l2c.hpp" #include "lua_bind_hash.hpp" @@ -9,130 +12,141 @@ u64 is_training_mode(void) asm("_ZN3app9smashball16is_training_modeEv") LINKABLE; -namespace lib -{ - enum L2CVarType - { - L2C_void = 0, - L2C_bool = 1, - L2C_integer = 2, - L2C_number = 3, - L2C_pointer = 4, - L2C_table = 5, - L2C_inner_function = 6, - L2C_hash = 7, - L2C_string = 8, - }; +namespace lib { + enum L2CVarType { + L2C_void = 0, + L2C_bool = 1, + L2C_integer = 2, + L2C_number = 3, + L2C_pointer = 4, + L2C_table = 5, + L2C_inner_function = 6, + L2C_hash = 7, + L2C_string = 8, + }; - struct L2CTable_meta - { - uint64_t a; - uint64_t b; - uint64_t c; - uint64_t d; - }; + struct L2CTable_meta { + uint64_t a; + uint64_t b; + uint64_t c; + uint64_t d; + }; - struct L2CTable - { - uint32_t refcnt; - uint32_t unk; - - uint64_t begin; // L2CValue* - uint64_t end; // L2CValue* - uint64_t also_end; // L2CValue* - struct L2CTable_meta meta; - uint64_t unk_ptr; - }; + struct L2CTable { + uint32_t refcnt; + uint32_t unk; - struct L2CInnerFunctionBase - { - uint64_t unk; - uint32_t refcnt; - } L2CInnerFunctionBase; + uint64_t begin; // L2CValue* + uint64_t end; // L2CValue* + uint64_t also_end; // L2CValue* + struct L2CTable_meta meta; + uint64_t unk_ptr; + }; - struct L2CValue - { - uint32_t type; - uint32_t unk; - union - { - uint64_t raw; - float raw_float; - void* raw_pointer; - struct L2CTable* raw_table; - struct L2CInnerFunctionBase* raw_innerfunc; - //std::string* raw_string; - }; + struct L2CInnerFunctionBase { + uint64_t unk; + uint32_t refcnt; + } L2CInnerFunctionBase; - L2CValue() {} + struct L2CValue { + uint32_t type; + uint32_t unk; + union { + uint64_t raw; + float raw_float; + // void* raw_pointer; + // struct L2CTable* raw_table; + // struct L2CInnerFunctionBase* raw_innerfunc; + //std::string* raw_string; + }; - L2CValue(bool val) { - type = L2C_bool; - raw = val; - } + L2CValue() { + type = L2C_void; + } - L2CValue(u64 val) { - type = L2C_integer; - raw = val; - } + L2CValue(bool val) { + type = L2C_bool; + raw = val; + } - L2CValue(float val) { - type = L2C_number; - raw_float = val; - } + L2CValue(int val) { + type = L2C_integer; + raw = val; + } - L2CValue(const char* str) { - type = L2C_void; - } + L2CValue(u64 val) { + type = L2C_integer; + raw = val; + } - }; + L2CValue(float val) { + if (isnan(val)) { + type = L2C_void; + } else { + type = L2C_number; + raw_float = val; + } + } - struct L2CAgent - { - uint64_t vtable; - uint64_t lua_state_agent; - uint64_t unk10; - uint64_t unk18; - uint64_t unk20; - uint64_t unk28; - uint64_t unk30; - uint64_t unk38; - uint64_t lua_state_agentbase; + L2CValue(double val) { + if (isnan(val)) { + type = L2C_void; + } else { + type = L2C_number; + raw_float = val; + } + } - L2CAgent* L2CAgent_constr(u64 lua_state) asm("_ZN3lib8L2CAgentC2EP9lua_State") LINKABLE; - u64 push_lua_stack(L2CValue* l2c_value) asm("_ZN3lib8L2CAgent14push_lua_stackERKNS_8L2CValueE") LINKABLE; - // pop_lua_stack - // Notes: - // Actually takes three arguments, but the third is given through X8 due to how - // AArch64 treats struct pointers that are used as pass by reference to get the value. - // Thus, my current solution is to use inline ASM before using this to pass the - // last arg. This is done using asm("mov x8, %x0" : : "r"(&popped) : "x8" );, where - // popped is an L2CValue that will be populated by the function. - // FURTHERMORE, this function does NOT actually pop the stack, it only returns the value at the - // position indicated by the second argument. - // This index is either positive, meaning absolute position in the stack, or negative, - // which is more traditional, i.e. -1 is the top of the stack. - //__int64_t (*lib_L2CAgent_pop_lua_stack)(__int64_t, int); - u64 pop_lua_stack(int index) asm("_ZN3lib8L2CAgent13pop_lua_stackEi") LINKABLE; + operator bool() asm("_ZNK3lib8L2CValuecvbEv") LINKABLE; - void get_lua_stack(int index, lib::L2CValue* l2c_val) { - asm("mov x8, %x0" : : "r"(l2c_val) : "x8" ); - pop_lua_stack(index); - } + void push_variadic(u64, const char*, void*) asm("_ZN3lib8L2CValue13push_variadicEmPKcRNS_7utility8VariadicE") LINKABLE; + }; - u64 sv_set_function_hash(u64 (*func)(L2CAgent*, void*), u64 hash) asm("_ZN3lib8L2CAgent20sv_set_function_hashEPvN3phx6Hash40E") LINKABLE; - u64 clear_lua_stack() asm("_ZN3lib8L2CAgent15clear_lua_stackEv") LINKABLE; - }; + struct L2CAgent { + uint64_t vtable; + uint64_t lua_state_agent; + uint64_t unk10; + uint64_t unk18; + uint64_t unk20; + uint64_t unk28; + uint64_t unk30; + uint64_t unk38; + uint64_t lua_state_agentbase; - bool lua_bind_get_value(u64, int*) asm("_ZN3lib18lua_bind_get_valueIiEEbmRT_") LINKABLE; + L2CAgent* L2CAgent_constr(u64 lua_state) asm("_ZN3lib8L2CAgentC2EP9lua_State") LINKABLE; + u64 push_lua_stack(L2CValue* l2c_value) asm("_ZN3lib8L2CAgent14push_lua_stackERKNS_8L2CValueE") LINKABLE; + // pop_lua_stack + // Notes: + // Actually takes three arguments, but the third is given through X8 due to how + // AArch64 treats struct pointers that are used as pass by reference to get the value. + // Thus, my current solution is to use inline ASM before using this to pass the + // last arg. This is done using asm("mov x8, %x0" : : "r"(&popped) : "x8" );, where + // popped is an L2CValue that will be populated by the function. + // FURTHERMORE, this function does NOT actually pop the stack, it only returns the value at the + // position indicated by the second argument. + // This index is either positive, meaning absolute position in the stack, or negative, + // which is more traditional, i.e. -1 is the top of the stack. + //__int64_t (*lib_L2CAgent_pop_lua_stack)(__int64_t, int); + u64 pop_lua_stack(int index) asm("_ZN3lib8L2CAgent13pop_lua_stackEi") LINKABLE; - int lua_const(const char* str) { - int val; - if (lua_bind_get_value(lua_bind_hash_str(str), &val)) - return val; - else - return -1; - } + void get_lua_stack(int index, lib::L2CValue* l2c_val) { + asm("mov x8, %x0" : : "r"(l2c_val) : "x8" ); + pop_lua_stack(index); + } + + u64 sv_set_function_hash(u64 (*func)(L2CAgent*, void*), u64 hash) asm("_ZN3lib8L2CAgent20sv_set_function_hashEPvN3phx6Hash40E") LINKABLE; + u64 clear_lua_stack() asm("_ZN3lib8L2CAgent15clear_lua_stackEv") LINKABLE; + }; + + bool lua_bind_get_value(u64, int*) asm("_ZN3lib18lua_bind_get_valueIiEEbmRT_") LINKABLE; + + int lua_const(const char* str) { + int val; + if (lua_bind_get_value(lua_bind_hash_str(str), &val)) + return val; + else + return -1; + } } #endif // L2C_IMPORTS_H diff --git a/source/lua_bind_hash.hpp b/source/lua_bind_hash.hpp index e387581..e10a3dc 100644 --- a/source/lua_bind_hash.hpp +++ b/source/lua_bind_hash.hpp @@ -1,97 +1,101 @@ +#ifndef LUA_BIND_HASH_H +#define LUA_BIND_HASH_H + #include <stdio.h> #include <string.h> #include <stdint.h> #include <inttypes.h> uint64_t lua_bind_hash(const void* data_, size_t len) { - int64_t *data = (int64_t*)data_; - size_t hash = len; - int64_t hash_add = 0x27d4eb2f165667c4; - int64_t* data_end = (int64_t *)((int64_t)data + len); + int64_t *data = (int64_t*)data_; + size_t hash = len; + int64_t hash_add = 0x27d4eb2f165667c4; + int64_t* data_end = (int64_t *)((int64_t)data + len); - uint64_t hash_vals[4] = { - 0x60ea27eeadc0b5d5, - 0xc2b2ae3d27d4eb4e, - 0xffffffffffffffff, - 0x61c8864e7a143578, - }; + uint64_t hash_vals[4] = { + 0x60ea27eeadc0b5d5, + 0xc2b2ae3d27d4eb4e, + 0xffffffffffffffff, + 0x61c8864e7a143578, + }; - uint64_t hash_vals_mid[4]; + uint64_t hash_vals_mid[4]; - const uint64_t hash_vals_end[4] = { - 0x3c6ef3630bd7950e, - 0x1bbcd8c2f5e54380, - 0x779b185ebca87000, - 0xe6c617af2a1c0000 - }; + const uint64_t hash_vals_end[4] = { + 0x3c6ef3630bd7950e, + 0x1bbcd8c2f5e54380, + 0x779b185ebca87000, + 0xe6c617af2a1c0000 + }; - const uint64_t hash_vals_end_2[4] = { - 0x3f, - 0x39, - 0x34, - 0x2e - }; + const uint64_t hash_vals_end_2[4] = { + 0x3f, + 0x39, + 0x34, + 0x2e + }; - const uint64_t MULT1 = 0x87bcb65480000000; // -0x784349ab80000000 - const uint64_t MULT2 = 0xdef35b010f796ca9; // -0x210ca4fef0869357 - const uint64_t MULT3 = 0x9e3779b185ebca87; // -0x61c8864e7a143579 - const uint64_t MULT4 = 0xc2b2ae3d27d4eb4f; // -0x3d4d51c2d82b14b1 - const uint64_t MULT5 = 0x93ea75a780000000; // -0x6c158a5880000000 - const uint64_t MULT6 = 0x27d4eb2f165667c5; - const uint64_t ADD1 = 0x85ebca77c2b2ae63; - const uint64_t ADD2 = 0x165667b19e3779f9; - - if (len >= 32) { - do { - for (int i = 0; i < 4; i++) { - hash_vals[i] += data[i] * MULT4; - hash_vals_mid[i] = hash_vals[i] >> 0x21 | hash_vals[i] * 0x80000000; - hash_vals[i] = hash_vals_mid[i] * MULT3; - } - - data = data + 4; - } while (data <= data_end + -4); - uint64_t val = 0; - for (int i = 0; i < 4; i++) { - val += (hash_vals_mid[i] * hash_vals_end[i] | hash_vals[i] >> hash_vals_end_2[i]); - } + const uint64_t MULT1 = 0x87bcb65480000000; // -0x784349ab80000000 + const uint64_t MULT2 = 0xdef35b010f796ca9; // -0x210ca4fef0869357 + const uint64_t MULT3 = 0x9e3779b185ebca87; // -0x61c8864e7a143579 + const uint64_t MULT4 = 0xc2b2ae3d27d4eb4f; // -0x3d4d51c2d82b14b1 + const uint64_t MULT5 = 0x93ea75a780000000; // -0x6c158a5880000000 + const uint64_t MULT6 = 0x27d4eb2f165667c5; + const uint64_t ADD1 = 0x85ebca77c2b2ae63; + const uint64_t ADD2 = 0x165667b19e3779f9; + + if (len >= 32) { + do { + for (int i = 0; i < 4; i++) { + hash_vals[i] += data[i] * MULT4; + hash_vals_mid[i] = hash_vals[i] >> 0x21 | hash_vals[i] * 0x80000000; + hash_vals[i] = hash_vals_mid[i] * MULT3; + } + + data = data + 4; + } while (data <= data_end + -4); + uint64_t val = 0; + for (int i = 0; i < 4; i++) { + val += (hash_vals_mid[i] * hash_vals_end[i] | hash_vals[i] >> hash_vals_end_2[i]); + } - val = (val ^ (hash_vals_mid[0] * MULT1 | hash_vals_mid[0] * MULT2 >> 0x21) * MULT3) * MULT3; - for (int i = 1; i < 4; i++) { - val = (val + ADD1 ^ (hash_vals_mid[i] * MULT1 | hash_vals_mid[i] * MULT2 >> 0x21) * MULT3) * MULT3; - } - val += ADD1; + val = (val ^ (hash_vals_mid[0] * MULT1 | hash_vals_mid[0] * MULT2 >> 0x21) * MULT3) * MULT3; + for (int i = 1; i < 4; i++) { + val = (val + ADD1 ^ (hash_vals_mid[i] * MULT1 | hash_vals_mid[i] * MULT2 >> 0x21) * MULT3) * MULT3; + } + val += ADD1; - hash_add = val; - } + hash_add = val; + } - hash += hash_add; - for (; data + 1 <= data_end; data++) { - hash = (*data * MULT5 | (*data * MULT4) >> 0x21) * - MULT3 ^ hash; - hash = (hash >> 0x25 | hash << 0x1b) * MULT3 + ADD1; - } + hash += hash_add; + for (; data + 1 <= data_end; data++) { + hash = (*data * MULT5 | (*data * MULT4) >> 0x21) * MULT3 ^ hash; + hash = (hash >> 0x25 | hash << 0x1b) * MULT3 + ADD1; + } - int32_t* data_32 = (int32_t*) data; - if ((int64_t *)(data_32 + 1) <= data_end) { - hash = (uint64_t)*data_32 * MULT3 ^ hash; - hash = (hash >> 0x29 | hash << 0x17) * MULT4 + ADD2; - data = (int64_t *)(data_32 + 1); - } + int32_t* data_32 = (int32_t*) data; + if ((int64_t *)(data_32 + 1) <= data_end) { + hash = (uint64_t)*data_32 * MULT3 ^ hash; + hash = (hash >> 0x29 | hash << 0x17) * MULT4 + ADD2; + data = (int64_t *)(data_32 + 1); + } - int8_t* data_8 = (int8_t*) data; + int8_t* data_8 = (int8_t*) data; - for (; data != data_end; data = (int64_t*)data_8) { - hash = (uint64_t)(*data_8) * MULT6 ^ hash; - hash = (hash >> 0x35 | hash << 0xb) * MULT3; - data_8++; - } - - uint64_t final_hash = (hash ^ hash >> 0x21) * MULT4; - final_hash = (final_hash ^ final_hash >> 0x1d) * ADD2; - return final_hash ^ final_hash >> 0x20; + for (; data != data_end; data = (int64_t*)data_8) { + hash = (uint64_t)(*data_8) * MULT6 ^ hash; + hash = (hash >> 0x35 | hash << 0xb) * MULT3; + data_8++; + } + + uint64_t final_hash = (hash ^ hash >> 0x21) * MULT4; + final_hash = (final_hash ^ final_hash >> 0x1d) * ADD2; + return final_hash ^ final_hash >> 0x20; } uint64_t lua_bind_hash_str(const char* str) { - return lua_bind_hash(str, strlen(str)); -} \ No newline at end of file + return lua_bind_hash(str, strlen(str)); +} + +#endif // LUA_BIND_HASH_H diff --git a/source/lua_helper.hpp b/source/lua_helper.hpp deleted file mode 100644 index 09f1af0..0000000 --- a/source/lua_helper.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef LUA_HELPER_H -#define LUA_HELPER_H -#include <switch.h> -#include "l2c_imports.hpp" - - - -#endif // LUA_HELPER_H diff --git a/source/main.cpp b/source/main.cpp index 2acf863..061f801 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,7 +1,6 @@ #include <switch.h> #include <string.h> -#include <math.h> #include <stdio.h> #include <dirent.h> #include <sys/iosupport.h> @@ -15,21 +14,24 @@ #include "saltysd_dynamic.h" #include "saltysd_helper.hpp" +#include "l2c.hpp" +#include "l2c_imports.hpp" +#include "acmd_imports.hpp" -#include "script_replacement.hpp" #include "hitbox_visualizer.hpp" +#include "script_replacement.hpp" #include "training_mods.hpp" extern "C" { -extern u32 __start__; + extern u32 __start__; -static char g_heap[0x8000]; + static char g_heap[0x8000]; -void __libnx_init(void* ctx, Handle main_thread, void* saved_lr); -void __attribute__((weak)) NORETURN __libnx_exit(int rc); -void __nx_exit(int, void*); -void __libc_fini_array(void); -void __libc_init_array(void); + void __libnx_init(void* ctx, Handle main_thread, void* saved_lr); + void __attribute__((weak)) NORETURN __libnx_exit(int rc); + void __nx_exit(int, void*); + void __libc_fini_array(void); + void __libc_init_array(void); } u32 __nx_applet_type = AppletType_None; @@ -38,61 +40,58 @@ Handle orig_main_thread; void* orig_ctx; void* orig_saved_lr; -void __libnx_init(void* ctx, Handle main_thread, void* saved_lr) -{ - extern char* fake_heap_start; - extern char* fake_heap_end; +void __libnx_init(void* ctx, Handle main_thread, void* saved_lr) { + extern char* fake_heap_start; + extern char* fake_heap_end; - fake_heap_start = &g_heap[0]; - fake_heap_end = &g_heap[sizeof g_heap]; - - orig_ctx = ctx; - orig_main_thread = main_thread; - orig_saved_lr = saved_lr; - - // Call constructors. - //void __libc_init_array(void); - __libc_init_array(); + fake_heap_start = &g_heap[0]; + fake_heap_end = &g_heap[sizeof g_heap]; + + orig_ctx = ctx; + orig_main_thread = main_thread; + orig_saved_lr = saved_lr; + + // Call constructors. + //void __libc_init_array(void); + __libc_init_array(); } -void __attribute__((weak)) NORETURN __libnx_exit(int rc) -{ - // Call destructors. - //void __libc_fini_array(void); - __libc_fini_array(); +void __attribute__((weak)) NORETURN __libnx_exit(int rc) { + // Call destructors. + //void __libc_fini_array(void); + __libc_fini_array(); - SaltySD_printf("SaltySD Plugin: jumping to %p\n", orig_saved_lr); + SaltySD_printf("SaltySD Plugin: jumping to %p\n", orig_saved_lr); - __nx_exit(0, orig_saved_lr); - while (true); + __nx_exit(0, orig_saved_lr); + while (true); } -int main(int argc, char *argv[]) -{ - SaltySD_printf("SaltySD Plugin: alive\n"); - - // Get anchor for imports - // do not remove if you plan on using IMPORT - ANCHOR_ABS = SaltySDCore_getCodeStart(); +int main(int argc, char *argv[]) { + SaltySD_printf("SaltySD Plugin: alive\n"); + + // Get anchor for imports + // do not remove if you plan on using IMPORT + ANCHOR_ABS = SaltySDCore_getCodeStart(); - /* - Example of string replacement: - replaces the title screen's version number with the string - below. - */ + /* + Example of string replacement: + replaces the title screen's version number with the string + below. + */ - const char *ver = "Ver. %d.%d.%d"; - u64 version_string = SaltySDCore_findCode((u8 *)ver, strlen(ver)); - if (version_string) { - SaltySD_Memcpy(version_string, (u64) "Salty v%d%d%d", 13); - } + const char *ver = "Ver. %d.%d.%d"; + u64 version_string = SaltySDCore_findCode((u8 *)ver, strlen(ver)); + if (version_string) { + SaltySD_Memcpy(version_string, (u64) "Salty v%d%d%d", 13); + } - // Necessary for script replacement - SaltySD_function_replace_sym("_ZN3lib8L2CAgent15clear_lua_stackEv", (u64) &clear_lua_stack_replace); - - hitbox_vis_main(); - training_mods_main(); + // Necessary for script replacement + SaltySD_function_replace_sym("_ZN3lib8L2CAgent15clear_lua_stackEv", (u64) &clear_lua_stack_replace); + + // Add function replacements here + hitbox_vis_main(); + training_mods_main(); - __libnx_exit(0); + __libnx_exit(0); } - diff --git a/source/nn_ro.h b/source/nn_ro.h index a6a1f73..ce79112 100644 --- a/source/nn_ro.h +++ b/source/nn_ro.h @@ -1,78 +1,82 @@ +#ifndef NN_RO_H +#define NN_RO_H + #include <switch.h> #define nn_ro_LoadModule _ZN2nn2ro10LoadModuleEPNS0_6ModuleEPKvPvmi extern uint64_t _ZN2nn2ro10LoadModuleEPNS0_6ModuleEPKvPvmi(void* module, void const* unk_1, void* unk_2, unsigned long unk_3, int unk_4) LINKABLE; -typedef unsigned char undefined; -typedef unsigned char byte; -typedef unsigned char dwfenc; -typedef unsigned int dword; -typedef long long longlong; -typedef unsigned long long qword; -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; -typedef unsigned long long ulonglong; -typedef unsigned char undefined1; -typedef unsigned short undefined2; -typedef unsigned int undefined3; -typedef unsigned int undefined4; -typedef unsigned long long undefined5; -typedef unsigned long long undefined6; -typedef unsigned long long undefined7; -typedef unsigned long long undefined8; -typedef unsigned short ushort; -typedef unsigned short word; +typedef unsigned char undefined; +typedef unsigned char byte; +typedef unsigned char dwfenc; +typedef unsigned int dword; +typedef long long longlong; +typedef unsigned long long qword; +typedef unsigned char uchar; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned long long ulonglong; +typedef unsigned char undefined1; +typedef unsigned short undefined2; +typedef unsigned int undefined3; +typedef unsigned int undefined4; +typedef unsigned long long undefined5; +typedef unsigned long long undefined6; +typedef unsigned long long undefined7; +typedef unsigned long long undefined8; +typedef unsigned short ushort; +typedef unsigned short word; enum module_state {module_unloaded, module_loaded}; typedef struct RoModule_t { - struct RoModule_t *next; - struct RoModule_t *prev; - union { - void *rel; - void *rela; - void *raw; - } rela_or_rel_plt; - union { - void *rel; - void *rela; - } rela_or_rel; - uint64_t module_base; - void *dyanmic; - bool is_rela; - uint64_t rela_or_rel_plt_size; - void (*dt_init)(void); - void (*dt_fini)(void); - uint32_t *hash_bucket; - uint32_t *hash_chain; - char *dynstr; - void *dynsym; - uint64_t dynstr_size; - void **got; - uint64_t rela_dyn_size; - uint64_t rel_dyn_size; - uint64_t rel_count; - uint64_t rela_count; - uint64_t hash_nchain_value; - uint64_t hash_nbucket_value; - uint64_t got_stub_ptr; + struct RoModule_t *next; + struct RoModule_t *prev; + union { + void *rel; + void *rela; + void *raw; + } rela_or_rel_plt; + union { + void *rel; + void *rela; + } rela_or_rel; + uint64_t module_base; + void *dyanmic; + bool is_rela; + uint64_t rela_or_rel_plt_size; + void (*dt_init)(void); + void (*dt_fini)(void); + uint32_t *hash_bucket; + uint32_t *hash_chain; + char *dynstr; + void *dynsym; + uint64_t dynstr_size; + void **got; + uint64_t rela_dyn_size; + uint64_t rel_dyn_size; + uint64_t rel_count; + uint64_t rela_count; + uint64_t hash_nchain_value; + uint64_t hash_nbucket_value; + uint64_t got_stub_ptr; } RoModule; typedef struct Module_t { - RoModule *module; - enum module_state state; - uintptr_t module_address; - uintptr_t bss_address; + RoModule *module; + enum module_state state; + uintptr_t module_address; + uintptr_t bss_address; } Module; typedef struct SmashModule { /* PlaceHolder Structure */ - Module module; - void * field_0x20; - void * src_buffer; - char name[256]; /* Created by retype action */ - undefined field_0x130; - undefined field_0x131; - undefined4 is_loaded; // bool + Module module; + void *field_0x20; + void *src_buffer; + char name[256]; /* Created by retype action */ + undefined field_0x130; + undefined field_0x131; + undefined4 is_loaded; // bool } SmashModule; +# endif // NN_RO_H diff --git a/source/saltysd_core.h b/source/saltysd_core.h index aacda7e..9e25bb1 100644 --- a/source/saltysd_core.h +++ b/source/saltysd_core.h @@ -6,9 +6,9 @@ #include "useful.h" extern "C" { -u64 SaltySDCore_getCodeStart() LINKABLE; -u64 SaltySDCore_getCodeSize() LINKABLE; -u64 SaltySDCore_findCode(u8* code, size_t size) LINKABLE; + u64 SaltySDCore_getCodeStart() LINKABLE; + u64 SaltySDCore_getCodeSize() LINKABLE; + u64 SaltySDCore_findCode(u8* code, size_t size) LINKABLE; } #endif // SALTYSD_CORE_H diff --git a/source/saltysd_dynamic.h b/source/saltysd_dynamic.h index 361439f..d04d65a 100644 --- a/source/saltysd_dynamic.h +++ b/source/saltysd_dynamic.h @@ -6,14 +6,14 @@ #include "useful.h" extern "C" { -uint64_t SaltySDCore_GetSymbolAddr(void* base, char* name) LINKABLE; -uint64_t SaltySDCore_FindSymbol(char* name) LINKABLE; -uint64_t SaltySDCore_FindSymbolBuiltin(char* name) LINKABLE; -void SaltySDCore_RegisterModule(void* base) LINKABLE; -void SaltySDCore_RegisterBuiltinModule(void* base) LINKABLE; -void SaltySDCore_DynamicLinkModule(void* base) LINKABLE; -void SaltySDCore_ReplaceModuleImport(void* base, char* name, void* new_replace) LINKABLE; -void SaltySDCore_ReplaceImport(char* name, void* new_replace) LINKABLE; + uint64_t SaltySDCore_GetSymbolAddr(void* base, char* name) LINKABLE; + uint64_t SaltySDCore_FindSymbol(char* name) LINKABLE; + uint64_t SaltySDCore_FindSymbolBuiltin(char* name) LINKABLE; + void SaltySDCore_RegisterModule(void* base) LINKABLE; + void SaltySDCore_RegisterBuiltinModule(void* base) LINKABLE; + void SaltySDCore_DynamicLinkModule(void* base) LINKABLE; + void SaltySDCore_ReplaceModuleImport(void* base, char* name, void* new_replace) LINKABLE; + void SaltySDCore_ReplaceImport(char* name, void* new_replace) LINKABLE; } #endif // SALTYSD_DYNAMIC_H diff --git a/source/saltysd_helper.cpp b/source/saltysd_helper.cpp new file mode 100644 index 0000000..c80c042 --- /dev/null +++ b/source/saltysd_helper.cpp @@ -0,0 +1,36 @@ +#include <switch.h> + +#include "saltysd_core.h" +#include "saltysd_ipc.h" +#include "saltysd_dynamic.h" +#include "nn_ro.h" + +void (*SaltySD_installed_hook)(char*, u64) = NULL; + +int SaltySD_function_replace(u64 addr, u64 new_func) { + if (addr) { + SaltySD_Memcpy(addr, (u64) "\x49\x00\x00\x58", 4); // LDR X9, .+8 + SaltySD_Memcpy(addr+4, (u64) "\x20\x01\x1F\xD6", 4); // BR X9 + SaltySD_Memcpy(addr+8, (u64) &new_func, 8); // .dword newaddr + + return 0; + } + return -1; +} + +int SaltySD_function_replace_sym(char* function_sym, u64 new_func) { + u64 addr = SaltySDCore_FindSymbol(function_sym); + return SaltySD_function_replace(addr, new_func); +} + +void LoadModule(SmashModule *module, void *param_2, void *param_3, unsigned long param_4, int param_5) { + nn_ro_LoadModule(module, param_2, param_3, param_4, param_5); + if (SaltySD_installed_hook != NULL) { + SaltySD_installed_hook((char*)&module->name, (u64)module->module.module->module_base); + } +} + +void SaltySD_install_nro_hook(u64 LoadModule_thunk_addr, void hook_main(char*, u64)) { + SaltySD_installed_hook = hook_main; + SaltySD_function_replace(LoadModule_thunk_addr, (u64) LoadModule); +} diff --git a/source/saltysd_helper.hpp b/source/saltysd_helper.hpp index 94a81ed..f45c8b9 100644 --- a/source/saltysd_helper.hpp +++ b/source/saltysd_helper.hpp @@ -2,43 +2,12 @@ #define SALTYSD_HELPER_H #include <switch.h> -#include "saltysd_core.h" -#include "saltysd_ipc.h" -#include "saltysd_dynamic.h" -#include "nn_ro.h" #define ANCHOR_REL 0x70ffffc000 u64 ANCHOR_ABS; #define IMPORT(x) (x - ANCHOR_REL + ANCHOR_ABS) -void (*SaltySD_installed_hook)(char*, u64) = NULL; - -int SaltySD_function_replace(u64 addr, u64 new_func) { - if (addr) { - SaltySD_Memcpy(addr, (u64) "\x49\x00\x00\x58", 4); // LDR X9, .+8 - SaltySD_Memcpy(addr+4, (u64) "\x20\x01\x1F\xD6", 4); // BR X9 - SaltySD_Memcpy(addr+8, (u64) &new_func, 8); // .dword newaddr - - return 0; - } - return -1; -} - -int SaltySD_function_replace_sym(char* function_sym, u64 new_func) { - u64 addr = SaltySDCore_FindSymbol(function_sym); - return SaltySD_function_replace(addr, new_func); -} - -void LoadModule(SmashModule *module, void *param_2, void *param_3, unsigned long param_4, int param_5) { - nn_ro_LoadModule(module, param_2, param_3, param_4, param_5); - if(SaltySD_installed_hook != NULL) { - SaltySD_installed_hook((char*)&module->name, (u64)module->module.module->module_base); - } -} - -void SaltySD_install_nro_hook(u64 LoadModule_thunk_addr, void hook_main(char*, u64)) { - SaltySD_installed_hook = hook_main; - SaltySD_function_replace(LoadModule_thunk_addr, (u64) LoadModule); -} +int SaltySD_function_replace(u64 addr, u64 new_func); +int SaltySD_function_replace_sym(char* function_sym, u64 new_func); #endif // SALTYSD_HELPER_H diff --git a/source/saltysd_ipc.h b/source/saltysd_ipc.h index 27034a6..294435a 100644 --- a/source/saltysd_ipc.h +++ b/source/saltysd_ipc.h @@ -6,14 +6,14 @@ #include "useful.h" extern "C" { -void SaltySD_Init() LINKABLE; -Result SaltySD_Deinit() LINKABLE; -Result SaltySD_Term() LINKABLE; -Result SaltySD_Restore() LINKABLE; -Result SaltySD_LoadELF(u64 heap, u64* elf_addr, u64* elf_size, char* name) LINKABLE; -Result SaltySD_Memcpy(u64 to, u64 from, u64 size) LINKABLE; -Result SaltySD_GetSDCard(Handle *retrieve) LINKABLE; -Result SaltySD_printf(const char* format, ...) LINKABLE; + void SaltySD_Init() LINKABLE; + Result SaltySD_Deinit() LINKABLE; + Result SaltySD_Term() LINKABLE; + Result SaltySD_Restore() LINKABLE; + Result SaltySD_LoadELF(u64 heap, u64* elf_addr, u64* elf_size, char* name) LINKABLE; + Result SaltySD_Memcpy(u64 to, u64 from, u64 size) LINKABLE; + Result SaltySD_GetSDCard(Handle *retrieve) LINKABLE; + Result SaltySD_printf(const char* format, ...) LINKABLE; } #endif //SALTYSD_IPC_H diff --git a/source/script_replacement.hpp b/source/script_replacement.hpp index 6a66260..4930c0e 100644 --- a/source/script_replacement.hpp +++ b/source/script_replacement.hpp @@ -7,7 +7,6 @@ #include "l2c.hpp" #include "l2c_imports.hpp" #include "acmd_wrapper.hpp" -#include "lua_helper.hpp" #include "raygun_printer.hpp" @@ -36,99 +35,84 @@ void replace_scripts(L2CAgent* l2c_agent, u8 category, int kind) { } u64 appeal_lw_replace(L2CAgent* l2c_agent, void* variadic) { - ACMD acmd = ACMD(l2c_agent); + ACMD acmd = ACMD(l2c_agent); - acmd.frame(1); - if (acmd.is_excute()) { - TOGGLE_STATE = (TOGGLE_STATE + 1) % NUM_TOGGLE_STATES; - if (TOGGLE_STATE == MASH_AIRDODGE) - print_string(acmd.module_accessor, "MASH\nAIRDODGE"); - else if (TOGGLE_STATE == MASH_JUMP) - print_string(acmd.module_accessor, "MASH\nJUMP"); - else - print_string(acmd.module_accessor, "NONE"); - } + acmd.frame(1); + if (acmd.is_excute()) { + TOGGLE_STATE = (TOGGLE_STATE + 1) % NUM_TOGGLE_STATES; + if (TOGGLE_STATE == MASH_AIRDODGE) + print_string(acmd.module_accessor, "MASH\nAIRDODGE"); + else if (TOGGLE_STATE == MASH_JUMP) + print_string(acmd.module_accessor, "MASH\nJUMP"); + else + print_string(acmd.module_accessor, "NONE"); + } - return 0; + return 0; } u64 appeal_hi_replace(L2CAgent* l2c_agent, void* variadic) { - ACMD acmd = ACMD(l2c_agent); + ACMD acmd = ACMD(l2c_agent); - acmd.frame(1); - if (acmd.is_excute()) { - HITBOX_VIS = !HITBOX_VIS; - if (HITBOX_VIS) - print_string(acmd.module_accessor, "HITBOX\nVIS"); - else - print_string(acmd.module_accessor, "NO\nHITBOX"); - } + acmd.frame(1); + if (acmd.is_excute()) { + HITBOX_VIS = !HITBOX_VIS; + if (HITBOX_VIS) + print_string(acmd.module_accessor, "HITBOX\nVIS"); + else + print_string(acmd.module_accessor, "NO\nHITBOX"); + } - return 0; + return 0; } u64 appeal_s_replace(L2CAgent* l2c_agent, void* variadic) { - ACMD acmd = ACMD(l2c_agent); + ACMD acmd = ACMD(l2c_agent); - acmd.frame(1); - if (acmd.is_excute()) { - DI_STATE = (DI_STATE + 1) % NUM_DI_STATES; - const char* DI_strings[NUM_DI_STATES] = {"NONE", "AWAY", "DOWN AWAY", "DOWN", "DOWN IN", - "IN", "UP IN", "UP", "UP AWAY", "RANDOM\nIN AWAY"}; - print_string(acmd.module_accessor, DI_strings[DI_STATE]); - } + acmd.frame(1); + if (acmd.is_excute()) { + DI_STATE = (DI_STATE + 1) % NUM_DI_STATES; + const char* DI_strings[NUM_DI_STATES] = {"NONE", "AWAY", "DOWN AWAY", "DOWN", "DOWN IN", + "IN", "UP IN", "UP", "UP AWAY", "RANDOM\nIN AWAY"}; + print_string(acmd.module_accessor, DI_strings[DI_STATE]); + } - return 0; -} - -// AnimCMD replacement function -u64 shine_replace(L2CAgent* l2c_agent, void* variadic) { - ACMD acmd = ACMD(l2c_agent); - - acmd.frame(1); - if (acmd.is_excute()) { - acmd.ATTACK(0, 0, hash40("top"), 10.0, 10, 32, 0, 66, 7.5, 0, 6.5, - // 0, 0, 0, //L2C_voids: no X2, Y2, Z2 - 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 63, 31, 0, - 0x13462FCFE4LL, 2, 7, 25); - } - - return 0; + return 0; } void* sv_get_status_func(u64 l2c_agentbase, int status_kind, u64 key) { - u64 unk48 = LOAD64(l2c_agentbase + 0x48); - u64 unk50 = LOAD64(l2c_agentbase + 0x50); - if ( 0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind) - return *(void **)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29)); - - return 0; + u64 unk48 = LOAD64(l2c_agentbase + 0x48); + u64 unk50 = LOAD64(l2c_agentbase + 0x50); + if (0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind) + return *(void **)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29)); + + return 0; } void sv_replace_status_func(u64 l2c_agentbase, int status_kind, u64 key, void* func) { - u64 unk48 = LOAD64(l2c_agentbase + 0x48); - u64 unk50 = LOAD64(l2c_agentbase + 0x50); - if ( 0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind) { - *(void **)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29)) = func; - } + u64 unk48 = LOAD64(l2c_agentbase + 0x48); + u64 unk50 = LOAD64(l2c_agentbase + 0x50); + if (0x2E8BA2E8BA2E8BA3LL * ((unk50 - unk48) >> 4) > (u64)status_kind) { + *(void **)(unk48 + 0xB0LL * status_kind + (key << 32 >> 29)) = func; + } } u64 clear_lua_stack_replace(u64 l2c_agent) { - u64 lua_state = LOAD64(l2c_agent + 8); - if (lua_state-8 && LOAD64(lua_state-8) && LOAD64(LOAD64(lua_state - 8) + 416LL)) { - u8 battle_object_category = *(u8 *)(LOAD64(lua_state - 8) + 404LL); - int battle_object_kind = *(int *)(LOAD64(lua_state - 8) + 408LL); - replace_scripts((L2CAgent*)l2c_agent, battle_object_category, battle_object_kind); - } + u64 lua_state = LOAD64(l2c_agent + 8); + if ((lua_state - 8) && LOAD64(lua_state - 8) && (LOAD64(LOAD64(lua_state - 8) + 416LL))) { + u8 battle_object_category = *(u8 *)(LOAD64(lua_state - 8) + 404LL); + int battle_object_kind = *(int *)(LOAD64(lua_state - 8) + 408LL); + replace_scripts((L2CAgent*)l2c_agent, battle_object_category, battle_object_kind); + } - // Original clear_lua_stack: - u64 v1 = LOAD64(l2c_agent + 8); - u64 v2 = LOAD64(v1 + 16); - u64 i = LOAD64(LOAD64(v1 + 32)) + 16LL; - for (; v2 < i; v2 = LOAD64(v1 + 16)) { - LOAD64(v1 + 16) = v2 + 16; - *(u32 *)(v2 + 8) = 0; - } - LOAD64(v1 + 16) = i; - return l2c_agent; + // Original clear_lua_stack: + u64 v1 = LOAD64(l2c_agent + 8); + u64 v2 = LOAD64(v1 + 16); + u64 i = LOAD64(LOAD64(v1 + 32)) + 16LL; + for (; v2 < i; v2 = LOAD64(v1 + 16)) { + LOAD64(v1 + 16) = v2 + 16; + *(u32 *)(v2 + 8) = 0; + } + LOAD64(v1 + 16) = i; + return l2c_agent; } diff --git a/source/taunt_toggles.h b/source/taunt_toggles.h index 536d79b..7dda4b4 100644 --- a/source/taunt_toggles.h +++ b/source/taunt_toggles.h @@ -21,4 +21,4 @@ int DI_STATE = 0; int TOGGLE_STATE = 0; #define NUM_TOGGLE_STATES 3 -#endif // TAUNT_TOGGLES_H \ No newline at end of file +#endif // TAUNT_TOGGLES_H diff --git a/source/training_mods.hpp b/source/training_mods.hpp index e76c113..e8bbbba 100644 --- a/source/training_mods.hpp +++ b/source/training_mods.hpp @@ -12,130 +12,122 @@ using namespace app::sv_animcmd; u64 fighter_manager_addr; bool is_operation_cpu(u64 module_accessor) { - int entry_id = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID); - u64 fighter_information = FighterManager::get_fighter_information(LOAD64(fighter_manager_addr), entry_id); + int entry_id = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID); + u64 fighter_information = FighterManager::get_fighter_information(LOAD64(fighter_manager_addr), entry_id); - return FighterInformation::is_operation_cpu(fighter_information); + return FighterInformation::is_operation_cpu(fighter_information); } bool is_in_hitstun(u64 module_accessor) { - int status_kind = StatusModule::status_kind(module_accessor); - return status_kind >= FIGHTER_STATUS_KIND_DAMAGE && status_kind <= FIGHTER_STATUS_KIND_DAMAGE_FALL; + int status_kind = StatusModule::status_kind(module_accessor); + return status_kind >= FIGHTER_STATUS_KIND_DAMAGE && status_kind <= FIGHTER_STATUS_KIND_DAMAGE_FALL; } void perform_jump(u64 module_accessor) { - int jump_count = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_JUMP_COUNT); - int max_jump_count = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_JUMP_COUNT_MAX); - if (jump_count < max_jump_count) { - if (StatusModule::situation_kind(module_accessor) == SITUATION_KIND_AIR) { - if (WorkModule::get_param_int(module_accessor, 0xB99CC3FBCLL, 0) == FIGHTER_JUMP_AERIAL_TYPE_NORMAL) - StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_JUMP_AERIAL, 1); - else - StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_FLY, 1); - } else if (StatusModule::situation_kind(module_accessor) == SITUATION_KIND_GROUND) - StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_JUMP_SQUAT, 1); - WorkModule::inc_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_JUMP_COUNT); - } + int jump_count = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_JUMP_COUNT); + int max_jump_count = WorkModule::get_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_JUMP_COUNT_MAX); + if (jump_count < max_jump_count) { + if (StatusModule::situation_kind(module_accessor) == SITUATION_KIND_AIR) { + if (WorkModule::get_param_int(module_accessor, 0xB99CC3FBCLL, 0) == FIGHTER_JUMP_AERIAL_TYPE_NORMAL) + StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_JUMP_AERIAL, 1); + else + StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_FLY, 1); + } else if (StatusModule::situation_kind(module_accessor) == SITUATION_KIND_GROUND) { + StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_JUMP_SQUAT, 1); + } + WorkModule::inc_int(module_accessor, FIGHTER_INSTANCE_WORK_ID_INT_JUMP_COUNT); + } } namespace app::lua_bind::WorkModule { - // Force option out of hitstun - u64 enable_transition_term_group_replace(u64 module_accessor, int transition_group) { - if (is_training_mode() && is_operation_cpu(module_accessor)) { - if (is_in_hitstun(module_accessor)) { - // Airdodge - if (TOGGLE_STATE == MASH_AIRDODGE) { - if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_ESCAPE) - StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1); - } - // Jump - else if (TOGGLE_STATE == MASH_JUMP) { - if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_JUMP_AERIAL) - perform_jump(module_accessor); - else if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_GROUND_JUMP) - perform_jump(module_accessor); - } - } - } + // Force option out of hitstun + u64 enable_transition_term_group_replace(u64 module_accessor, int transition_group) { + if (is_training_mode() && is_operation_cpu(module_accessor)) { + if (is_in_hitstun(module_accessor)) { + if (TOGGLE_STATE == MASH_AIRDODGE) { // airdodge + if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_ESCAPE) + StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1); + } else if (TOGGLE_STATE == MASH_JUMP) { // jump + if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_AIR_JUMP_AERIAL) + perform_jump(module_accessor); + else if (transition_group == FIGHTER_STATUS_TRANSITION_GROUP_CHK_GROUND_JUMP) + perform_jump(module_accessor); + } + } + } - // call original WorkModule::enable_transition_term_group_impl - u64 work_module = load_module(module_accessor, 0x50); - u64 (*enable_transition_term_group)(u64, u64) = (u64(*)(u64, u64))(load_module_impl(work_module, 0x140)); + // call original WorkModule::enable_transition_term_group_impl + u64 work_module = load_module(module_accessor, 0x50); + u64 (*enable_transition_term_group)(u64, u64) = (u64(*)(u64, u64))(load_module_impl(work_module, 0x140)); - return enable_transition_term_group(work_module, transition_group); - } + return enable_transition_term_group(work_module, transition_group); + } - // Force DI - float get_float_replace(u64 module_accessor, int var) { - if (is_training_mode() && is_operation_cpu(module_accessor)) { - if (is_in_hitstun(module_accessor)) { - if (DI_STATE != NONE) { - float angle = (DI_STATE - 1) * M_PI / 4.0; + // Force DI + float get_float_replace(u64 module_accessor, int var) { + if (is_training_mode() && is_operation_cpu(module_accessor)) { + if (is_in_hitstun(module_accessor)) { + if (DI_STATE != NONE) { + float angle = (DI_STATE - 1) * M_PI / 4.0; - // Either 0 (right) or PI (left) - if (DI_STATE == DI_RANDOM_IN_AWAY) { - angle = app::sv_math::rand(hash40("fighter"), 2) * M_PI; - } + // Either 0 (right) or PI (left) + if (DI_STATE == DI_RANDOM_IN_AWAY) { + angle = app::sv_math::rand(hash40("fighter"), 2) * M_PI; + } - // If facing left, reverse angle - if (PostureModule::lr(module_accessor) != -1.0) - angle -= M_PI; + // If facing left, reverse angle + if (PostureModule::lr(module_accessor) != -1.0) + angle -= M_PI; - if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X) - return cos(angle); + if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X) + return cos(angle); - if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y) - return sin(angle); - } - } - } + if (var == FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_Y) + return sin(angle); + } + } + } - // call original WorkModule::get_float_impl - u64 work_module = load_module(module_accessor, 0x50); - float (*get_float)(u64, int) = (float (*)(u64, int))(load_module_impl(work_module, 0x58)); + // call original WorkModule::get_float_impl + u64 work_module = load_module(module_accessor, 0x50); + float (*get_float)(u64, int) = (float (*)(u64, int))(load_module_impl(work_module, 0x58)); - return get_float(work_module, var); - } + return get_float(work_module, var); + } } namespace app::lua_bind::MotionModule { - void change_motion_replace(u64 module_accessor, u64 motion_kind, float start_frame, float frame_speed_mult, bool unk1, float unk2, bool unk3, bool unk4) { - - u64 curr_motion_kind = MotionModule::motion_kind(module_accessor); - if ((curr_motion_kind == hash40("damage_air_1") || - curr_motion_kind == hash40("damage_air_2") || - curr_motion_kind == hash40("damage_air_3")) && motion_kind == hash40("fall")) { - if (is_training_mode() && is_operation_cpu(module_accessor)) { - // Airdodge - if (TOGGLE_STATE == MASH_AIRDODGE) - StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1); - // Jump - else if (TOGGLE_STATE == MASH_JUMP) - perform_jump(module_accessor); - } - } + void change_motion_replace(u64 module_accessor, u64 motion_kind, float start_frame, float frame_speed_mult, bool unk1, float unk2, bool unk3, bool unk4) { + u64 curr_motion_kind = MotionModule::motion_kind(module_accessor); + if ((curr_motion_kind == hash40("damage_air_1") || + curr_motion_kind == hash40("damage_air_2") || + curr_motion_kind == hash40("damage_air_3")) && motion_kind == hash40("fall")) { + if (is_training_mode() && is_operation_cpu(module_accessor)) { + if (TOGGLE_STATE == MASH_AIRDODGE) // airdodge + StatusModule::change_status_request_from_script(module_accessor, FIGHTER_STATUS_KIND_ESCAPE_AIR, 1); + else if (TOGGLE_STATE == MASH_JUMP) // jump + perform_jump(module_accessor); + } + } - // call original - u64 motion_module = load_module(module_accessor, 0x88); - void (*change_motion)(u64, u64, float, float, bool, float, bool, bool) = - (void (*)(u64, u64, float, float, bool, float, bool, bool)) load_module_impl(motion_module, 0xD8); + // call original + u64 motion_module = load_module(module_accessor, 0x88); + void (*change_motion)(u64, u64, float, float, bool, float, bool, bool) = + (void (*)(u64, u64, float, float, bool, float, bool, bool)) load_module_impl(motion_module, 0xD8); - change_motion(motion_module, motion_kind, start_frame, frame_speed_mult, unk1, unk2, unk3, unk4); - } + change_motion(motion_module, motion_kind, start_frame, frame_speed_mult, unk1, unk2, unk3, unk4); + } } void training_mods_main() { - fighter_manager_addr = SaltySDCore_FindSymbol("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E"); - - SaltySD_function_replace_sym( - "_ZN3app8lua_bind45WorkModule__enable_transition_term_group_implEPNS_26BattleObjectModuleAccessorEi", - (u64)&WorkModule::enable_transition_term_group_replace); - - SaltySD_function_replace_sym( - "_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi", - (u64)&WorkModule::get_float_replace); - - SaltySD_function_replace_sym( - "_ZN3app8lua_bind32MotionModule__change_motion_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40Effbfbb", - (u64)&MotionModule::change_motion_replace); -} \ No newline at end of file + fighter_manager_addr = SaltySDCore_FindSymbol("_ZN3lib9SingletonIN3app14FighterManagerEE9instance_E"); + SaltySD_function_replace_sym( + "_ZN3app8lua_bind45WorkModule__enable_transition_term_group_implEPNS_26BattleObjectModuleAccessorEi", + (u64)&WorkModule::enable_transition_term_group_replace); + SaltySD_function_replace_sym( + "_ZN3app8lua_bind26WorkModule__get_float_implEPNS_26BattleObjectModuleAccessorEi", + (u64)&WorkModule::get_float_replace); + SaltySD_function_replace_sym( + "_ZN3app8lua_bind32MotionModule__change_motion_implEPNS_26BattleObjectModuleAccessorEN3phx6Hash40Effbfbb", + (u64)&MotionModule::change_motion_replace); +} diff --git a/source/useful.h b/source/useful.h index 153bb31..c576bbb 100644 --- a/source/useful.h +++ b/source/useful.h @@ -8,7 +8,7 @@ #define LINKABLE __attribute__ ((weak)) #define debug_log(...) \ - {char log_buf[0x200]; snprintf(log_buf, 0x200, __VA_ARGS__); \ - svcOutputDebugString(log_buf, strlen(log_buf));} - + {char log_buf[0x200]; snprintf(log_buf, 0x200, __VA_ARGS__); \ + svcOutputDebugString(log_buf, strlen(log_buf));} + #endif // USEFUL_H