From 5580b4934565823844a7fa02ad0eb62cc7e3ab55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 16 Oct 2021 18:05:41 +0200 Subject: [PATCH] ksys/act: Add more Actor members --- CMakeLists.txt | 3 + data/uking_functions.csv | 40 +- lib/sead | 2 +- lib/xlink2/.clang-format | 74 ++++ lib/xlink2/CMakeLists.txt | 16 + lib/xlink2/include/xlink2/xlink2.h | 10 + lib/xlink2/src/dummy.cpp | 0 src/KingSystem/ActorSystem/actActor.cpp | 65 +++ src/KingSystem/ActorSystem/actActor.h | 406 +++++++++++++++++- .../ActorSystem/actBaseProcJobHandler.h | 15 + src/KingSystem/Utils/AtomicLongBitFlag.h | 87 ++++ src/KingSystem/Utils/CMakeLists.txt | 1 + 12 files changed, 677 insertions(+), 42 deletions(-) create mode 100644 lib/xlink2/.clang-format create mode 100644 lib/xlink2/CMakeLists.txt create mode 100644 lib/xlink2/include/xlink2/xlink2.h create mode 100644 lib/xlink2/src/dummy.cpp create mode 100644 src/KingSystem/Utils/AtomicLongBitFlag.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3da992cb..fa0e9f2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,4 +45,7 @@ target_link_libraries(uking PRIVATE gsys) add_subdirectory(lib/EventFlow) target_link_libraries(uking PRIVATE evfl) +add_subdirectory(lib/xlink2) +target_link_libraries(uking PRIVATE xlink2) + add_subdirectory(src) diff --git a/data/uking_functions.csv b/data/uking_functions.csv index e36ea46a..c15280c6 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -41312,7 +41312,7 @@ Address,Quality,Size,Name 0x0000007100699b64,O,000052,_ZN5uking5query17EnemyRestLifeRateC1ERKN4ksys3act2ai5Query7InitArgE 0x0000007100699b98,O,000020,_ZN5uking5query17EnemyRestLifeRateD1Ev 0x0000007100699bac,O,000052,_ZN5uking5query17EnemyRestLifeRateD0Ev -0x0000007100699be0,m,000112,_ZN5uking5query17EnemyRestLifeRate7doQueryEv +0x0000007100699be0,O,000112,_ZN5uking5query17EnemyRestLifeRate7doQueryEv 0x0000007100699c50,O,000064,_ZN5uking5query17EnemyRestLifeRate10loadParamsERKN4evfl8QueryArgE 0x0000007100699c90,O,000064,_ZN5uking5query17EnemyRestLifeRate10loadParamsEv 0x0000007100699cd0,O,000204,_ZNK5uking5query17EnemyRestLifeRate27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE @@ -45172,7 +45172,7 @@ Address,Quality,Size,Name 0x00000071006dfd8c,m,000076,_ZN5uking3dmg17DamageManagerBaseC1EPN4ksys3act5ActorE 0x00000071006dfdd8,U,000096,DamageMgrBase::m20 0x00000071006dfe38,U,000020,DamageMgrBase::resetStuff -0x00000071006dfe4c,M,000500,_ZN5uking3dmg17DamageManagerBase11applyDamageERi +0x00000071006dfe4c,O,000500,_ZN5uking3dmg17DamageManagerBase11applyDamageERi 0x00000071006e0040,O,000204,_ZN5uking3dmg17DamageManagerBase21handleDamageForPlayerEPjS2_S2_S2_S2_ 0x00000071006e010c,O,000072,_ZN5uking3dmg17DamageManagerBase9addDamageEliiiiii 0x00000071006e0154,U,000004,DamageMgrBase::isSlowTime @@ -91935,7 +91935,7 @@ Address,Quality,Size,Name 0x00000071011c2dcc,O,000068,_ZNK4ksys3act2ai7Actions11onPreDeleteEv 0x00000071011c2e10,U,000068,Dummy::construct 0x00000071011c2e54,O,000012,_ZN4ksys3act20getDummyBaseProcLinkEv -0x00000071011c2e60,U,001208,Actor::ctor +0x00000071011c2e60,m,001208,_ZN4ksys3act5ActorC1ERKNS0_8BaseProc9CreateArgE 0x00000071011c3318,U,003008,Actor::job0_1 0x00000071011c3ed8,U,000324,Actor::job0_2 0x00000071011c401c,U,001252,Actor::job1_1 @@ -91943,22 +91943,22 @@ Address,Quality,Size,Name 0x00000071011c45bc,U,001888,Actor::job2_1 0x00000071011c4d1c,U,000036,Actor::job2_2 0x00000071011c4d40,U,000144,Actor::job4 -0x00000071011c4dd0,U,000292,Actor::dtor +0x00000071011c4dd0,U,000292,_ZN4ksys3act5ActorD1Ev 0x00000071011c4ef4,U,000060, -0x00000071011c4f30,U,000008, -0x00000071011c4f38,U,000008, -0x00000071011c4f40,U,000036,Actor::dtorDelete -0x00000071011c4f64,U,000040, -0x00000071011c4f8c,U,000040, +0x00000071011c4f30,U,000008,_ZThn384_N4ksys3act5ActorD1Ev +0x00000071011c4f38,U,000008,_ZThn392_N4ksys3act5ActorD1Ev +0x00000071011c4f40,U,000036,_ZN4ksys3act5ActorD0Ev +0x00000071011c4f64,U,000040,_ZThn384_N4ksys3act5ActorD0Ev +0x00000071011c4f8c,U,000040,_ZThn392_N4ksys3act5ActorD0Ev 0x00000071011c4fb4,U,001252,Actor::preDelete3 -0x00000071011c5498,U,000072, -0x00000071011c54e0,U,000060,Actor::checkFlag +0x00000071011c5498,O,000072,_ZN4ksys3act5Actor9clearFlagENS1_9ActorFlagE +0x00000071011c54e0,O,000060,_ZNK4ksys3act5Actor9checkFlagENS1_9ActorFlagE 0x00000071011c551c,U,000276,Actor::createModel_ 0x00000071011c5630,U,000100, 0x00000071011c5694,U,000300, 0x00000071011c57c0,U,000516,Actor::x_27 0x00000071011c59c4,U,000580,Actor::initModelBind -0x00000071011c5c08,U,000068,Actor::setFlag_0 +0x00000071011c5c08,O,000068,_ZN4ksys3act5Actor7setFlagENS1_9ActorFlagE 0x00000071011c5c4c,U,000028, 0x00000071011c5c68,U,000040,Actor::afterUpdateState 0x00000071011c5c90,U,004996,Actor::onEnterCalc @@ -91974,7 +91974,7 @@ Address,Quality,Size,Name 0x00000071011c7948,U,000072,Actor::initEventStruct3A 0x00000071011c7990,U,000016, 0x00000071011c79a0,U,000152,Actor::x_13 -0x00000071011c7a38,U,000096,Actor::setFlag +0x00000071011c7a38,O,000096,_ZN4ksys3act5Actor7setFlagENS1_9ActorFlagEb 0x00000071011c7a98,U,000012, 0x00000071011c7aa4,U,000540,Actor::onEnterSleep 0x00000071011c7cc0,U,000004,Actor::failedDelete @@ -91996,11 +91996,11 @@ Address,Quality,Size,Name 0x00000071011c8b84,U,000032,Actor::setFlag0x40 0x00000071011c8ba4,U,000032, 0x00000071011c8bc4,U,000484,Actor::setMtxVelAngVelLife -0x00000071011c8da8,U,000072,Actor::m104 -0x00000071011c8df0,U,000076, -0x00000071011c8e3c,U,000076,Actor::m105 +0x00000071011c8da8,O,000072,_ZN4ksys3act5Actor9handleAckERKNS_10MessageAckE +0x00000071011c8df0,O,000076,_ZThn392_N4ksys3act5Actor9handleAckERKNS_10MessageAckE +0x00000071011c8e3c,O,000076,_ZN4ksys3act5Actor13handleMessageERKNS_7MessageE 0x00000071011c8e88,U,002104,Actor::handleMessageMaybe -0x00000071011c96c0,U,000080, +0x00000071011c96c0,O,000080,_ZThn384_N4ksys3act5Actor13handleMessageERKNS_7MessageE 0x00000071011c9710,U,000260,Actor::updateVelocityStuff 0x00000071011c9814,U,000108,Actor::deleteAndEmit 0x00000071011c9880,U,000120,Actor::x_15 @@ -92009,7 +92009,7 @@ Address,Quality,Size,Name 0x00000071011c99dc,U,000172,Actor::x_14 0x00000071011c9a88,U,000024, 0x00000071011c9aa0,U,000348,Actor::createXlinkInstance -0x00000071011c9bfc,U,000132,Actor::getUniqueName +0x00000071011c9bfc,O,000132,_ZNK4ksys3act5Actor13getUniqueNameEv 0x00000071011c9c80,U,000732, 0x00000071011c9f5c,U,000096,Actor::m120 0x00000071011c9fbc,U,000044,Actor::m121 @@ -92204,8 +92204,8 @@ Address,Quality,Size,Name 0x00000071011db3b8,U,000084, 0x00000071011db40c,U,000004,nullsub_4649 0x00000071011db410,U,000004,nullsub_6153 -0x00000071011db414,U,000204,Actor::rtti1 -0x00000071011db4e0,U,000092,Actor::rtti2 +0x00000071011db414,O,000204,_ZNK4ksys3act5Actor27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE +0x00000071011db4e0,O,000092,_ZNK4ksys3act5Actor18getRuntimeTypeInfoEv 0x00000071011db53c,U,000204, 0x00000071011db608,U,000092, 0x00000071011db664,U,000140, diff --git a/lib/sead b/lib/sead index d3c0a7d7..533d0500 160000 --- a/lib/sead +++ b/lib/sead @@ -1 +1 @@ -Subproject commit d3c0a7d736acf8d5d163b824d1ffee5b73b0c48b +Subproject commit 533d050068a36d0c3fa08f6f15b603fbe659a304 diff --git a/lib/xlink2/.clang-format b/lib/xlink2/.clang-format new file mode 100644 index 00000000..ef862606 --- /dev/null +++ b/lib/xlink2/.clang-format @@ -0,0 +1,74 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +CommentPragmas: '^ (IWYU pragma:|NOLINT)' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ForEachMacros: [] +IncludeCategories: + - Regex: '^<[Ww]indows\.h>$' + Priority: 1 + - Regex: '^<' + Priority: 2 + - Regex: '^"' + Priority: 3 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++17 +TabWidth: 4 +UseTab: Never +... diff --git a/lib/xlink2/CMakeLists.txt b/lib/xlink2/CMakeLists.txt new file mode 100644 index 00000000..06aaaf60 --- /dev/null +++ b/lib/xlink2/CMakeLists.txt @@ -0,0 +1,16 @@ +project(xlink2 CXX ASM) + +add_library(xlink2 OBJECT + include/xlink2/xlink2.h + src/dummy.cpp +) + +target_compile_options(xlink2 PRIVATE -fno-exceptions) +target_compile_options(xlink2 PRIVATE -fno-strict-aliasing) +target_compile_options(xlink2 PRIVATE -Wno-invalid-offsetof) +target_include_directories(xlink2 PUBLIC include/) + +if(NOT TARGET sead) + add_subdirectory(../sead) +endif() +target_link_libraries(xlink2 PUBLIC sead) diff --git a/lib/xlink2/include/xlink2/xlink2.h b/lib/xlink2/include/xlink2/xlink2.h new file mode 100644 index 00000000..04c0833b --- /dev/null +++ b/lib/xlink2/include/xlink2/xlink2.h @@ -0,0 +1,10 @@ +#pragma once + +namespace xlink2 { + +struct Handle { + void* _0 = nullptr; + int _8 = 0; +}; + +} // namespace xlink2 diff --git a/lib/xlink2/src/dummy.cpp b/lib/xlink2/src/dummy.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/KingSystem/ActorSystem/actActor.cpp b/src/KingSystem/ActorSystem/actActor.cpp index 7d93a0a5..8346b964 100644 --- a/src/KingSystem/ActorSystem/actActor.cpp +++ b/src/KingSystem/ActorSystem/actActor.cpp @@ -1,6 +1,8 @@ #include "KingSystem/ActorSystem/actActor.h" #include "KingSystem/ActorSystem/actActorParam.h" +#include "KingSystem/ActorSystem/actAiRoot.h" #include "KingSystem/ActorSystem/actBaseProcLink.h" +#include "KingSystem/ActorSystem/actBaseProcMgr.h" namespace ksys::act { @@ -12,8 +14,71 @@ BaseProcLink& getDummyBaseProcLink() { return sDummyBaseProcLink; } +Actor::Actor(const CreateArg& arg) : BaseProc(arg) { + mJobHandlers[BaseProcMgr::getConstant0()] = &mJob0; + mJobHandlers[BaseProcMgr::getConstant1()] = &mJob1; + mJobHandlers[BaseProcMgr::getConstant2()] = &mJob2; + mJobHandlers[BaseProcMgr::getConstant4()] = &mJob4; + + mUnk1.actor = this; + mUnk1._4 = 0; +} + +Actor::~Actor() { + // FIXME +} + +void Actor::clearFlag(Actor::ActorFlag flag) { + mActorFlags.resetBit(flag); +} + +bool Actor::checkFlag(Actor::ActorFlag flag) const { + return mActorFlags.isOnBit(flag); +} + +void Actor::setFlag(Actor::ActorFlag flag) { + setFlag(flag, true); +} + +void Actor::setFlag(Actor::ActorFlag flag, bool on) { + mActorFlags.changeBit(flag, on); +} + const sead::SafeString& Actor::getProfile() const { return mActorParam->getProfile(); } +const char* Actor::getUniqueName() const { + const char* unique_name = nullptr; + + if (mMapObjIter.tryGetParamStringByKey(&unique_name, "UniqueName")) + return unique_name; + + if (mUniqueName && mUniqueName->unique_name) + unique_name = mUniqueName->unique_name->cstr(); + + return unique_name; +} + +void Actor::handleAck(const MessageAck& ack) { + if (m80()) + return; + + if (mRootAi) + mRootAi->handleAck(ack); +} + +int Actor::handleMessage(const Message& message) { + const auto result = doHandleMessage_(message); + switch (result) { + default: + return 0; + case HandleMessageResult::_1: + return 1; + case HandleMessageResult::_2: + m107(); + return 1; + } +} + } // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h index 71d5d0f8..e7e598c2 100644 --- a/src/KingSystem/ActorSystem/actActor.h +++ b/src/KingSystem/ActorSystem/actActor.h @@ -1,17 +1,58 @@ #pragma once +#include +#include +#include #include #include +#include #include +#include +#include +#include "KingSystem/ActorSystem/actActorEditorNode.h" #include "KingSystem/ActorSystem/actBaseProc.h" +#include "KingSystem/ActorSystem/actBaseProcJobHandler.h" +#include "KingSystem/ActorSystem/actBaseProcLink.h" +#include "KingSystem/ActorSystem/actPhysicsConstraints.h" +#include "KingSystem/ActorSystem/actPhysicsUserTag.h" #include "KingSystem/Map/mapMubinIter.h" +#include "KingSystem/Utils/AtomicLongBitFlag.h" +#include "KingSystem/Utils/Thread/ActorMessageTransceiver.h" + +namespace gsys { +class Model; +} // namespace gsys namespace ksys { +namespace as { +class ASList; +} // namespace as + namespace map { class Object; } // namespace map +namespace mii { +class HylianInfo; +class UMii; +} // namespace mii + +namespace phys { +class FieldBodyGroup; +class Physics; +class Reaction; +class RigidBody; +} // namespace phys + +namespace res { +class Handle; +} // namespace res + +namespace xlink { +class XLink; +} // namespace xlink + namespace act { namespace ai { @@ -19,11 +60,40 @@ class RootAi; } class LifeRecoverInfo; +class Actor; class ActorCreator; class ActorParam; +class Attention; +class Awareness; class BaseProcLink; +class BoneControl; +class Chemical; +class ImpulseBaseProcLink; +class ModelBindInfo; +class Schedule; -class Actor : public BaseProc { +// FIXME: move this to a separate file and rename +class UMiiModelLink { +public: + explicit UMiiModelLink(Actor* actor) : mActor(actor) {} + + virtual void m0() {} + virtual void m1() {} + virtual void m2() {} + virtual void m3() {} + +private: + Actor* mActor = nullptr; +}; +KSYS_CHECK_SIZE_NX150(UMiiModelLink, 0x10); + +struct ActorUniqueName { + sead::BufferedSafeString* unique_name; + sead::FixedSafeString<16> change_attention_type; +}; +KSYS_CHECK_SIZE_NX150(ActorUniqueName, 0x30); + +class Actor : public BaseProc, public ActorMessageTransceiver::IHandler { public: enum class StasisFlag { _1 = 1, @@ -52,11 +122,12 @@ public: _3 = 3, }; - Actor(); // FIXME + explicit Actor(const CreateArg& arg); ~Actor() override; SEAD_RTTI_OVERRIDE(Actor, BaseProc) +public: const sead::SafeString& getProfile() const; const char* getUniqueName() const; @@ -65,16 +136,135 @@ public: map::Object* getMapObject() const { return mMapObject; } const map::MubinIter& getMapObjIter() const { return mMapObjIter; } + void clearFlag(ActorFlag flag); bool checkFlag(ActorFlag flag) const; + void setFlag(ActorFlag flag); + void setFlag(ActorFlag flag, bool on); bool deleteEx(DeleteType type, DeleteReason reason, bool* ok = nullptr); void setProperties(int x, const sead::Matrix34f& mtx, const sead::Vector3f& vel, const sead::Vector3f& ang_vel, const sead::Vector3f& scale, bool is_life_infinite, int i, int life) const; + // FIXME: figure out return types, parameters and names virtual s32 getMaxLife(); + virtual void m31(); + virtual void m32(); + virtual void m33(); + virtual void m34(); + virtual void m35(); + virtual void m36(); + virtual void getGuardableAngle(); + virtual void m38(); + virtual void m39(); + virtual void m40(); + virtual void m41(); + virtual void m42(); + virtual void m43(); + virtual void m44(); + virtual void m45(); + virtual void m46(); + virtual void m47(); + virtual void m48(); + virtual void m49(); + virtual void m50(); + virtual void m51(); + virtual void m52(); + virtual void m53(); + virtual void killWithDropsAndEffects(); + virtual void m55(); + virtual void m56(); + virtual void m57(); + virtual void onPreFadeOutDelete(); + virtual void onFadeOutSleep(); + virtual void m60(); + virtual void m61(); + virtual bool shouldUnload(); + virtual void m63(); + virtual void initMaybe(); + virtual void updateLodStuff(); + virtual void m66(); + virtual void m67(); + virtual void m68(); + virtual void calcMaybe(); + virtual void m70(); + virtual void updatePositionMaybe(); + virtual void m72(); + virtual void m73(); + virtual void m74(); + virtual void m75(); + virtual void m76(); + virtual void m77(); + virtual void afterModelMatrixUpdate(); + virtual void m79(); + virtual bool m80(); + virtual void m81(); + virtual int getCalcTiming(); + virtual void m83(); + virtual void updateMtxFromPhysics(); + virtual void setMtx(); + virtual void m86(); virtual s32* getLife(); + virtual void m88(); + virtual void m89(); + virtual void m90(); + virtual void m91(); + virtual void m92(); + virtual void m93(); + virtual void m94(); + virtual void m95(); + virtual void m96(); + virtual void getChemicalStuff(); + virtual void getWeapons(); + virtual void getArmors(); + virtual void m100(); + virtual void m101(); + virtual int getExtraHeapSize(); + virtual void m103(); + int handleMessage(const Message& message) override; + void handleAck(const MessageAck& ack) override; + virtual void m106(); + virtual void m107(); + virtual void m108(); + virtual void m109(); + virtual void m110(); + virtual void m111(); + virtual void m112(); + virtual void m113(); + virtual void m114(); + virtual void m115(); + virtual void m116(); + virtual void m117(); + virtual void m118(); + virtual void m119(); + virtual void m120(); + virtual void m121(); + virtual void m122(); + virtual void m123(); + virtual void onPlacementObjReset(); + virtual void getAtk(); + virtual void m126(); + virtual void getDamageMgr(); + virtual void m128(); + virtual void m129(); + virtual void getPlayerRideInfo(); + virtual void getHorseOptionsMaybe(); + virtual void m132(); + virtual void getMotorcyclePriorityStuffMaybe(); + virtual void getDropData(); + virtual void m135(); virtual LifeRecoverInfo* getLifeRecoverInfo(); + virtual void m137(); + virtual void m138(); + virtual void m139(); + virtual void m140(); + virtual void m141(); + virtual void m142(); + virtual void m143(); + virtual void m144(); + virtual void m145(); + virtual void m146(); + virtual void m147(); void emitBasicSigOn(); void emitBasicSigOff(); @@ -84,34 +274,208 @@ public: sead::TypedBitFlag& getActorFlags2() { return mActorFlags2; } const sead::TypedBitFlag& getActorFlags2() const { return mActorFlags2; } - const sead::TypedBitFlag& getStasisFlags() const { return mStasisFlags; } - void onAiEnter(const char* name, const char* context); - static constexpr size_t getCreatorListNodeOffset() { return offsetof(Actor, mCreatorListNode); } + static constexpr size_t getCreatorListNodeOffset() { + return offsetof(Actor, mCreatorActorListNode); + } protected: friend class ActorCreator; - /* 0x17c */ u8 TEMP_0x17c[0x518 - 0x17c]; // FIXME - /* 0x518 */ sead::TypedBitFlag mActorFlags2; - /* 0x51c */ u8 TEMP_0x51c[0x558 - 0x51c]; - /* 0x558 */ ai::RootAi* mRootAi; - /* 0x560 */ void* mASList; // FIXME - /* 0x568 */ void* mEffects; // FIXME - /* 0x570 */ ActorParam* mActorParam; - /* 0x578 */ u8 TEMP_0x578[0x648 - 0x578]; + struct Unk1 { + Actor* actor; + u32 _4; + }; + + struct Unk2 { + s16 _0 = -1; + s16 _2 = -1; + }; + + // FIXME: rename + void job0_1(); + void job0_2(); + void job1_1(); + void job1_2(); + void job2_1(); + void job2_2(); + void job4(); + + /* 0x190 */ sead::Atomic mMainBody = nullptr; + /* 0x198 */ sead::Atomic mTgtBody = nullptr; + /* 0x1a0 */ void* _1a0 = nullptr; + /* 0x1a8 */ void* _1a8 = nullptr; + /* 0x1b0 */ Unk1 mUnk1; + /* 0x1c0 */ u32 _1c0 = 3; + + /* 0x1c8 */ BaseProcJobHandlerDualT mJob0{this, &Actor::job0_1, &Actor::job0_2}; + /* 0x238 */ BaseProcJobHandlerDualT mJob1{this, &Actor::job1_1, &Actor::job1_2}; + /* 0x2a8 */ BaseProcJobHandlerDualT mJob2{this, &Actor::job2_1, &Actor::job2_2}; + /* 0x318 */ BaseProcJobHandlerT mJob4{this, &Actor::job4}; + + /* 0x368 */ sead::ListNode mActiveActorListNode; + /* 0x378 */ sead::ListNode mActorsThatLostPlacementObjListNode; + /* 0x388 */ sead::ListNode mVillagerListNode; + + /* 0x398 */ sead::Matrix34f mMtx = sead::Matrix34f::ident; + /* 0x3c8 */ sead::Matrix34f* mPhysicsMtx = nullptr; + /* 0x3d0 */ sead::Matrix34f mHomeMtx = sead::Matrix34f::ident; + /* 0x400 */ sead::Vector3f mVelocity{0, 0, 0}; + /* 0x40c */ sead::Vector3f mAngVelocity{0, 0, 0}; + /* 0x418 */ sead::Vector3f mScale{1, 1, 1}; + /* 0x424 */ float mDispDistanceSq; + /* 0x428 */ float mDeleteDistanceSq = -1.0; + /* 0x42c */ float mLoadDistance = -1.0; + /* 0x430 */ sead::Vector3f mPreviousPos{0, 0, 0}; + /* 0x43c */ sead::Vector3f mPreviousPos2{0, 0, 0}; + /* 0x448 */ sead::Vector3f _448{0, 0, 0}; + /* 0x454 */ sead::Vector3f _454{0, 0, 0}; + /* 0x460 */ sead::Vector3f _460{0, 0, 0}; + /* 0x46c */ sead::Vector3f _46c{0, 0, 0}; + /* 0x478 */ sead::Vector3f _478; + /* 0x484 */ sead::Vector3f mPreviousPos3{0, 0, 0}; + /* 0x490 */ float _490 = 0.0; + /* 0x494 */ float _494 = 0.0; + /* 0x498 */ Unk2 _498; + /* 0x49c */ Unk2 _49c; + /* 0x4a0 */ s16 _4a0 = -1; + /* 0x4a2 */ s16 _4a2 = -1; + /* 0x4a4 */ s16 _4a4 = -1; + /* 0x4a6 */ s16 _4a6 = -1; + /* 0x4a8 */ s16 _4a8 = -1; + /* 0x4aa */ s16 _4aa = -1; + /* 0x4ac */ s16 _4ac = -1; + /* 0x4ae */ s16 _4ae = -1; + /* 0x4b0 */ s16 _4b0 = -1; + /* 0x4b2 */ s16 _4b2 = -1; + /* 0x4b4 */ sead::Vector3f _4b4{0, 0, 0}; + /* 0x4c0 */ sead::Vector3f mEnterCalcPos{0, 0, 0}; + + /* 0x4d0 */ ModelBindInfo* mModelBindInfo = nullptr; + /* 0x4d8 */ void* _4d8 = nullptr; + /* 0x4e0 */ gsys::Model* mModel = nullptr; + /* 0x4e8 */ float _4e8 = 1.0; + /* 0x4ec */ float mStartModelOpacity = 0.0; + /* 0x4f0 */ float _4f0 = 1.0; + /* 0x4f4 */ float _4f4 = 0.0; + /* 0x4f8 */ float _4f8 = 0.0; + /* 0x4fc */ float _4fc = 0.0; + /* 0x500 */ sead::BoundBox3f mAabb{sead::Vector3f::zero, sead::Vector3f::zero}; + + /* 0x518 */ sead::TypedBitFlag mActorFlags2{}; + /* 0x51c */ sead::TypedBitFlag mActorFlags2Prev{}; + /* 0x520 */ util::AtomicLongBitFlag<64, ActorFlag> mActorFlags{}; + + /* 0x528 */ PhysicsUserTag mPhysicsUserTag{this}; + /* 0x540 */ sead::Atomic _540 = false; + + /* 0x548 */ void* _548 = nullptr; + /* 0x550 */ Awareness* mAwareness = nullptr; + /* 0x558 */ ai::RootAi* mRootAi = nullptr; + /* 0x560 */ as::ASList* mASList = nullptr; + /* 0x568 */ xlink::XLink* mXLink = nullptr; + /* 0x570 */ ActorParam* mActorParam = nullptr; + /* 0x578 */ phys::Physics* mPhysics = nullptr; + /* 0x580 */ PhysicsConstraints mConstraints; + /* 0x598 */ void* _598 = nullptr; + /* 0x5a0 */ BoneControl* mBoneControl = nullptr; + /* 0x5a8 */ phys::FieldBodyGroup* mFieldBodyGroup = nullptr; + /* 0x5b0 */ void* _5b0 = nullptr; + /* 0x5b8 */ sead::Heap* mDualHeap = nullptr; // TODO: rename + /* 0x5c0 */ sead::Heap* mDualHeap2 = nullptr; // TODO: rename + /* 0x5c8 */ sead::Heap* mHeap = nullptr; // TODO: rename + /* 0x5d0 */ ActorUniqueName* mUniqueName = nullptr; + /* 0x5d8 */ Attention* mAttention = nullptr; + /* 0x5e0 */ ActorMessageTransceiver mMsgTransceiver{*this, this}; + /* 0x638 */ Schedule* mSchedule = nullptr; + + /* 0x640 */ u32 mHashId = 0; /* 0x648 */ map::MubinIter mMapObjIter; - /* 0x658 */ u8 TEMP_0x650[0x710 - 0x658]; - /* ..... */ // The name could be incorrect. - /* 0x710 */ sead::TypedBitFlag mStasisFlags; - /* 0x714 */ u8 TEMP_0x714[0x7b0 - 0x714]; // FIXME + + /* 0x658 */ xlink2::Handle _658; + /* 0x668 */ xlink2::Handle _668; + /* 0x678 */ res::Handle* mModelResMaybe = nullptr; + /* 0x680 */ u8 _680 = 0; + /* 0x681 */ u8 _681 = 0; + /* 0x682 */ u8 _682 = 0; + /* 0x683 */ u8 _683 = 0; + /* 0x684 */ u8 mSkipJobPushTimer = 0; + /* 0x685 */ sead::BitFlag8 mSpecialJobTypesMaskOverride; + /* 0x686 */ s8 _686 = -1; + /* 0x687 */ sead::Atomic _687 = false; + /* 0x688 */ sead::Atomic mLifeInfiniteMaybe = false; + /* 0x689 */ sead::Atomic _689 = false; + /* 0x68a */ sead::Atomic _68a = false; + /* 0x68b */ sead::Atomic mNoFadeInCreate = false; + /* 0x68c */ sead::Atomic _68c = false; + /* 0x68d */ sead::Atomic _68d = false; + /* 0x68e */ sead::Atomic _68e = false; + /* 0x68f */ sead::Atomic _68f = false; + /* 0x690 */ bool _690 = false; + /* 0x691 */ bool _691 = false; + /* 0x694 */ sead::Atomic mFadeOutDeleteType = 0; + /* 0x698 */ sead::Atomic mFadeOutSleepFlags; + /* 0x6a0 */ void* _6a0 = nullptr; + /* 0x6a8 */ Chemical* mChemical = nullptr; + /* 0x6b0 */ phys::Reaction* mReaction = nullptr; + /* 0x6b8 */ void* _6b8 = nullptr; + /* 0x6c0 */ UMiiModelLink mUMiiModelLink{this}; + /* 0x6d0 */ float _6d0 = 0.0; + /* 0x6d8 */ void* _6d8 = nullptr; + /* 0x6e0 */ float _6e0 = 0.0; + /* 0x6e4 */ float _6e4 = 0.0; + /* 0x6e8 */ float _6e8 = -1.0; + /* 0x6ec */ int _6ec = 0; + /* 0x6f0 */ float _6f0 = -1.0; + /* 0x6f4 */ float _6f4 = 0.0; + /* 0x6f8 */ float _6f8 = 0.0; + /* 0x6fc */ int _6fc = 0; + /* 0x700 */ int _700 = 0; + /* 0x708 */ ImpulseBaseProcLink* mImpulseBaseProcLink = nullptr; + /* 0x710 */ sead::TypedBitFlag mStasisFlags; // TODO: probably need to rename this + /* 0x714 */ float mLodLoadDistanceMultiplier = 1.0; + /* 0x718 */ float _718 = 0.0; + /* 0x71c */ sead::BitFlag32 mSignals; + /* 0x720 */ sead::BitFlag32 _720; + /* 0x728 */ void* _728 = nullptr; + /* 0x730 */ u16 _730 = 0; + /* 0x732 */ sead::BitFlag16 mDrawDistanceFlags; + /* 0x738 */ BaseProcLink _738; + /* 0x748 */ BaseProcLink mCreateArgBaseProcLink; + /* 0x758 */ void* _758 = nullptr; + /* 0x760 */ xlink2::Handle _760; + /* 0x770 */ xlink2::Handle _770; + /* 0x780 */ xlink2::Handle mSwordBlurHandle; + /* 0x790 */ xlink2::Handle _790; + /* 0x7a0 */ sead::Vector3f _7a0 = sead::Vector3f::zero; + /* 0x7b0 */ ActorCreator* mCreator{}; - /* 0x7b8 */ sead::ListNode mCreatorListNode; - /* 0x7c8 */ map::Object* mMapObject; - /* 0x7d0 */ u8 TEMP_0x7d0[0x838 - 0x7d0]; + /* 0x7b8 */ sead::ListNode mCreatorActorListNode; + /* 0x7c8 */ map::Object* mMapObject{}; + + /* 0x7d0 */ void* _7d0 = nullptr; + /* 0x7d8 */ bool _7d8 = false; + + /* 0x7e0 */ ActorEditorNode mActorEditorNode; + /* 0x810 */ sead::Buffer mUMiiBones; // FIXME: type + /* 0x820 */ mii::UMii* mUMii = nullptr; + /* 0x828 */ mii::HylianInfo* mUMiiHylianInfo = nullptr; + + /* 0x830 */ float _830 = 1.0; + /* 0x834 */ int _834 = 0; + /* 0x838 */ int _838 = 0; + +private: + enum class HandleMessageResult { + _0, + _1, + _2, + }; + + HandleMessageResult doHandleMessage_(const Message& message); }; -KSYS_CHECK_SIZE_NX150(Actor, 0x838); +KSYS_CHECK_SIZE_NX150(Actor, 0x840); BaseProcLink& getDummyBaseProcLink(); diff --git a/src/KingSystem/ActorSystem/actBaseProcJobHandler.h b/src/KingSystem/ActorSystem/actBaseProcJobHandler.h index c2796680..4ba4c1d4 100644 --- a/src/KingSystem/ActorSystem/actBaseProcJobHandler.h +++ b/src/KingSystem/ActorSystem/actBaseProcJobHandler.h @@ -33,4 +33,19 @@ private: sead::Delegate mDelegate; }; +/// For binding two actor member functions. +template +class BaseProcJobHandlerDualT : public BaseProcJobHandler { +public: + BaseProcJobHandlerDualT(T* proc, void (T::*fn)(), void (T::*fn_special)()) + : BaseProcJobHandler(proc), mDelegate(proc, fn), mDelegateSpecial(proc, fn_special) {} + + void invoke() override { mDelegate.invoke(); } + void invokeSpecial() override { mDelegateSpecial.invoke(); } + +private: + sead::Delegate mDelegate; + sead::Delegate mDelegateSpecial; +}; + } // namespace ksys::act diff --git a/src/KingSystem/Utils/AtomicLongBitFlag.h b/src/KingSystem/Utils/AtomicLongBitFlag.h new file mode 100644 index 00000000..f5b2c31b --- /dev/null +++ b/src/KingSystem/Utils/AtomicLongBitFlag.h @@ -0,0 +1,87 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace ksys::util { + +template +class AtomicLongBitFlag { +public: + using Word = sead::Atomic; + + void makeAllZero() { mStorage.fill(0); } + void makeAllOne() { mStorage.fill(~Word(0)); } + + Word& getWord(Enum bit); + const Word& getWord(Enum bit) const; + + bool isZero() const; + + bool setBit(Enum bit); + bool resetBit(Enum bit); + bool changeBit(Enum bit, bool on); + bool isOnBit(Enum bit) const; + bool isOffBit(Enum bit) const; + +protected: + static constexpr s32 BitsPerWord = 8 * sizeof(Word); + + static_assert(N % BitsPerWord == 0, "N must be a multiple of the number of bits per word"); + sead::SafeArray mStorage{}; +}; + +template +inline typename AtomicLongBitFlag::Word& AtomicLongBitFlag::getWord(Enum bit) { + return mStorage[s32(bit) / BitsPerWord]; +} + +template +inline const typename AtomicLongBitFlag::Word& +AtomicLongBitFlag::getWord(Enum bit) const { + return mStorage[s32(bit) / BitsPerWord]; +} + +template +inline bool AtomicLongBitFlag::setBit(Enum bit) { + return getWord(bit).setBitOn(s32(bit) % BitsPerWord); +} + +template +inline bool AtomicLongBitFlag::resetBit(Enum bit) { + return getWord(bit).setBitOff(s32(bit) % BitsPerWord); +} + +template +inline bool AtomicLongBitFlag::changeBit(Enum bit, bool on) { + if (on) + return setBit(bit); + else + return resetBit(bit); +} + +template +inline bool AtomicLongBitFlag::isOnBit(Enum bit) const { + return getWord(bit).isBitOn(s32(bit) % BitsPerWord); +} + +template +inline bool AtomicLongBitFlag::isOffBit(Enum bit) const { + return !isOnBit(bit); +} + +template +inline bool AtomicLongBitFlag::isZero() const { + for (const auto& word : mStorage) { + if (word != 0) + return false; + } + return true; +} + +} // namespace ksys::util diff --git a/src/KingSystem/Utils/CMakeLists.txt b/src/KingSystem/Utils/CMakeLists.txt index 7efc89f2..e452eea1 100644 --- a/src/KingSystem/Utils/CMakeLists.txt +++ b/src/KingSystem/Utils/CMakeLists.txt @@ -64,6 +64,7 @@ target_sources(uking PRIVATE Byaml/ByamlLocal.h Byaml/ByamlUtil.cpp + AtomicLongBitFlag.h Debug.h FixedString.h HashUtil.h