diff --git a/.gitignore b/.gitignore index 02fd517..fab39ec 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,6 @@ Crash Reports/** .cache/** Custom Stage Builds/** *.lst +*.disabled compile_commands.json diff --git a/MakefileNSO b/MakefileNSO index 3f8ea04..1d2bc7f 100644 --- a/MakefileNSO +++ b/MakefileNSO @@ -32,7 +32,8 @@ include $(DEVKITPRO)/libnx/switch_rules #--------------------------------------------------------------------------------- TARGET ?= $(notdir $(CURDIR))$(SMOVER) BUILD ?= build$(SMOVER) -SOURCES := source/sead/time source/sead source/puppets source/server/hns source/server/gamemode source/server source/layouts source/states source/cameras source/nx source +SOURCES := source/sead/time source/sead source/puppets source/server/hns source/server/gamemode source/server/gamemode/modifiers source/server source/layouts source/states source/cameras source/nx source +SOURCES += source/al/execute DATA := data INCLUDES := include include/sead diff --git a/include/actors/PuppetActor.h b/include/actors/PuppetActor.h index b10868b..8da3dc5 100644 --- a/include/actors/PuppetActor.h +++ b/include/actors/PuppetActor.h @@ -33,6 +33,7 @@ class PuppetActor : public al::LiveActor { virtual void movement(void) override; virtual void makeActorAlive(void) override; virtual void makeActorDead(void) override; + virtual void calcAnim(void) override; virtual void attackSensor(al::HitSensor *, al::HitSensor *) override; virtual bool receiveMsg(const al::SensorMsg*, al::HitSensor*, al::HitSensor*) override; @@ -92,3 +93,8 @@ class PuppetActor : public al::LiveActor { float mClosingSpeed = 0; }; + +PlayerCostumeInfo* initMarioModelPuppet(al::LiveActor* player, const al::ActorInitInfo& initInfo, + char const* bodyName, char const* capName, int subActorNum, + al::AudioKeeper* audioKeeper); +PlayerHeadCostumeInfo* initMarioHeadCostumeInfo(al::LiveActor* player, const al::ActorInitInfo &initInfo, const char* headModelName, const char* capModelName, const char* headType, const char* headSuffix); \ No newline at end of file diff --git a/include/agl/RenderBuffer.h b/include/agl/RenderBuffer.h index 30c6759..04f2f4d 100644 --- a/include/agl/RenderBuffer.h +++ b/include/agl/RenderBuffer.h @@ -7,6 +7,7 @@ #include "RenderTargetColor.h" #include "RenderTargetDepth.h" +#include "DrawContext.h" #include "sead/gfx/seadFrameBuffer.h" diff --git a/include/al/LiveActor/LiveActor.h b/include/al/LiveActor/LiveActor.h index 444eebf..cf53bb3 100644 --- a/include/al/LiveActor/LiveActor.h +++ b/include/al/LiveActor/LiveActor.h @@ -19,6 +19,7 @@ #include "al/sensor/HitSensorKeeper.h" #include "al/switch/StageSwitchKeeper.h" #include "al/actor/SubActorKeeper.h" +#include "al/model/ModelKeeper.h" // vtable for LiveActor: 1C4EB58 @@ -31,7 +32,6 @@ namespace al class ActorScoreKeeper; class Collider; class CollisionParts; - class ModelKeeper; class ShadowKeeper; class ActorPrePassLightKeeper; class ActorOcclusionKeeper; @@ -93,11 +93,13 @@ namespace al virtual al::CameraDirector *getCameraDirector() const { return this->mSceneInfo->mCameraDirector; }; virtual void initStageSwitchKeeper() { this->mStageSwitchKeeper = new StageSwitchKeeper(); }; - + virtual void control(); virtual void updateCollider(); + void initSubActorKeeper(al::SubActorKeeper *); + const char *mActorName; // 0x48 al::ActorPoseKeeperBase *mPoseKeeper; // 0x50 al::ActorExecuteInfo *mLayoutExecuteInfo; // 0x58 diff --git a/include/al/actor/ActorActionKeeper.h b/include/al/actor/ActorActionKeeper.h index a8cbea5..aaa13ca 100644 --- a/include/al/actor/ActorActionKeeper.h +++ b/include/al/actor/ActorActionKeeper.h @@ -1,14 +1,13 @@ #pragma once - -#include "al/LiveActor/LiveActor.h" #include "al/action/ActionEffectCtrl.h" +#include "al/resource/ActorResource.h" #include "sead/math/seadVector.h" namespace al { + class LiveActor; - class ActorResource; class ActionAnimCtrl; class NerveActionCtrl; class ActionFlagCtrl; diff --git a/include/al/actor/ActorSceneInfo.h b/include/al/actor/ActorSceneInfo.h index 3ca0213..3b54eb9 100644 --- a/include/al/actor/ActorSceneInfo.h +++ b/include/al/actor/ActorSceneInfo.h @@ -6,6 +6,7 @@ #include "al/scene/SceneObjHolder.h" #include "al/layout/LayoutInitInfo.h" #include "game/GameData/GameDataHolderBase.h" +#include "al/gfx/GraphicsSystemInfo.h" namespace al { @@ -19,7 +20,6 @@ namespace al { struct ScreenCoverCtrl; struct ShadowDirector; struct ModelGroup; - struct GraphicsSystemInfo; struct PlayerHolder; struct ModelDrawBufferCounter; diff --git a/include/al/actor/SubActorKeeper.h b/include/al/actor/SubActorKeeper.h index c1e0a80..bacb787 100644 --- a/include/al/actor/SubActorKeeper.h +++ b/include/al/actor/SubActorKeeper.h @@ -1,7 +1,8 @@ #pragma once - +#include "al/actor/ActorInitInfo.h" #include "container/seadPtrArray.h" + namespace al { struct SubActorInfo { struct LiveActor* mActor; @@ -10,6 +11,13 @@ namespace al { }; class SubActorKeeper { + public: + SubActorKeeper(al::LiveActor*); + static SubActorKeeper *tryCreate(al::LiveActor*, char const*, int); + static SubActorKeeper *create(al::LiveActor*); + void registerSubActor(al::LiveActor*, unsigned int); + void init(al::ActorInitInfo const&, char const*, int); + al::LiveActor* mRootActor; sead::PtrArray mArray; }; diff --git a/include/al/area/ChangeStageInfo.h b/include/al/area/ChangeStageInfo.h index a3d7628..dfc1be5 100644 --- a/include/al/area/ChangeStageInfo.h +++ b/include/al/area/ChangeStageInfo.h @@ -31,9 +31,9 @@ class ChangeStageInfo { sead::FixedSafeString<0x80> changeStageId; // 0x0 (Size: 0x98) sead::FixedSafeString<0x80> changeStageName; // 0xA0 - sead::FixedSafeString<0x80> placementString; // 0x138 + sead::FixedSafeString<0x80> placementString; // 0x130 bool isReturn; // 0x1C8 - int scenarioNo; // 0x1CC or 0x134 + int scenarioNo; // 0x1CC SubScenarioType subType; // 0x1D0 sead::FixedSafeString<0x80> wipeType; // 0x1D8 int hintPriority; // 0x270 diff --git a/include/al/execute/ExecuteDirector.h b/include/al/execute/ExecuteDirector.h index 90ca68a..37b4568 100644 --- a/include/al/execute/ExecuteDirector.h +++ b/include/al/execute/ExecuteDirector.h @@ -1,8 +1,48 @@ #pragma once +#include "al/async/FunctorBase.h" + +#include "IUseExecutor.h" +#include "ExecuteSystemInitInfo.h" +#include "ExecuteRequestKeeper.h" +#include "ExecuteTableHolderDraw.h" +#include "ExecuteTableHolderUpdate.h" +#include "container/seadPtrArray.h" +#include "container/seadBuffer.h" + namespace al { + + class LiveActor; + class LayoutActor; + class ExecuteDirector { - public: + public: + ExecuteDirector(int); + virtual ~ExecuteDirector(); + void init(al::ExecuteSystemInitInfo const&); + void registerActorUpdate(al::LiveActor*, char const*); + void registerActorDraw(al::LiveActor*, char const*); + void registerActorModelDraw(al::LiveActor*, char const*); + void registerLayoutUpdate(al::LayoutActor*, char const*); + void registerLayoutDraw(al::LayoutActor*, char const*); + void registerUser(al::IUseExecutor*, char const*); + void registerFunctor(al::FunctorBase const&, char const*); + void registerFunctorDraw(al::FunctorBase const&, char const*); + void createExecutorListTable(); + void execute(char const*) const; + void executeList(char const*, char const*) const; + void draw(char const*) const; + void drawList(char const*, char const*) const; + void isActiveDraw(char const*) const; + + int mRequestMax; // 0x8 + + int mUpdateTableCount; + al::ExecuteTableHolderUpdate **mUpdateTables; + int mDrawTableCount; + al::ExecuteTableHolderDraw **mDrawTables; + + al::ExecuteRequestKeeper *mRequestKeeper; }; } // namespace al diff --git a/include/al/execute/ExecuteOrder.h b/include/al/execute/ExecuteOrder.h new file mode 100644 index 0000000..98baa6c --- /dev/null +++ b/include/al/execute/ExecuteOrder.h @@ -0,0 +1,11 @@ +#pragma once + +namespace al { + struct ExecuteOrder + { + const char *mListName; + const char *mExecuteGroup; + int mListMaxSize; + const char *mGroupType; + }; +} \ No newline at end of file diff --git a/include/al/execute/ExecuteRequestKeeper.h b/include/al/execute/ExecuteRequestKeeper.h new file mode 100644 index 0000000..fe69095 --- /dev/null +++ b/include/al/execute/ExecuteRequestKeeper.h @@ -0,0 +1,25 @@ +#pragma once + +#include "types.h" + +namespace al { + struct LiveActor; +} + +namespace al { +class ExecuteRequestKeeper { + public: + ExecuteRequestKeeper(int); + void executeRequestActorMovementAllOn(); + void executeRequestActorMovementAllOff(); + void executeRequestActorDrawAllOn(); + void executeRequestActorDrawAllOff(); + void request(al::LiveActor*, int); + + void *mActorMovementAllOn; // 0x0 + void *mActorMovementAllOff; // 0x8 + void *mActorDrawAllOn; // 0x10 + void *mActorDrawAllOff; // 0x18 + + }; +} \ No newline at end of file diff --git a/include/al/execute/ExecuteSystemInitInfo.h b/include/al/execute/ExecuteSystemInitInfo.h new file mode 100644 index 0000000..06686df --- /dev/null +++ b/include/al/execute/ExecuteSystemInitInfo.h @@ -0,0 +1,9 @@ +#pragma once + +#include "agl/DrawContext.h" + +namespace al { + struct ExecuteSystemInitInfo { + agl::DrawContext *mDrawCtx; + }; +} \ No newline at end of file diff --git a/include/al/execute/ExecuteTable.h b/include/al/execute/ExecuteTable.h new file mode 100644 index 0000000..1191b4e --- /dev/null +++ b/include/al/execute/ExecuteTable.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ExecuteOrder.h" + +namespace al { + struct ExecuteTable + { + const char *mName; + const al::ExecuteOrder* mExecuteOrders; + int mExecuteOrderCount; + }; +} \ No newline at end of file diff --git a/include/al/execute/ExecuteTableHolderDraw.h b/include/al/execute/ExecuteTableHolderDraw.h new file mode 100644 index 0000000..7008943 --- /dev/null +++ b/include/al/execute/ExecuteTableHolderDraw.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include "ExecuteOrder.h" +#include "al/async/FunctorBase.h" +#include "al/execute/ExecuteTable.h" +#include "al/execute/ExecutorListBase.h" +#include "al/execute/IUseExecutor.h" + +#include "container/seadPtrArray.h" +#include "types.h" + +namespace al { + struct ExecuteSystemInitInfo; + struct ExecutorListActorModelDrawBase; + struct ExecutorListActorDraw; + struct ExecutorListLayoutDrawBase; + struct ExecutorListIUseExecutorDraw; + struct ExecutorListFunctor; + struct ExecutorListBase; + struct LiveActor; + struct LayoutActor; +} + +namespace al { +class ExecuteTableHolderDraw { + public: + ExecuteTableHolderDraw(); + virtual ~ExecuteTableHolderDraw(); + void init(char const*, al::ExecuteSystemInitInfo const&, al::ExecuteOrder const*, int); + void registerExecutorListActorModel(al::ExecutorListActorModelDrawBase*); + void registerExecutorListActor(al::ExecutorListActorDraw*); + void registerExecutorListLayout(al::ExecutorListLayoutDrawBase*); + void registerExecutorListUser(al::ExecutorListIUseExecutorDraw*); + void registerExecutorListFunctor(al::ExecutorListFunctor*); + void registerExecutorListAll(al::ExecutorListBase*); + void tryRegisterActor(al::LiveActor*, char const*); + void tryRegisterActorModel(al::LiveActor*, char const*); + void tryRegisterLayout(al::LayoutActor*, char const*); + void tryRegisterUser(al::IUseExecutor*, char const*); + void tryRegisterFunctor(al::FunctorBase const&, char const*); + void createExecutorListTable(); + void execute() const; + void executeList(char const*) const; + bool isActive() const; + + const char* mName; + + sead::PtrArray mActiveExecutors; + sead::PtrArray mExecutorsAll; + sead::PtrArray mExecutorsActor; + sead::PtrArray mExecutorsActorModel; + sead::PtrArray mExecutorsLayout; + sead::PtrArray mExecutorsUser; + sead::PtrArray mExecutorsFunctor; + + }; +} + +extern "C" al::ExecuteTable gameDrawTable[]; // pointer to original draw table found in the exefs + +extern const al::ExecuteTable drawTable[]; + +extern int drawTableSize; \ No newline at end of file diff --git a/include/al/execute/ExecuteTableHolderUpdate.h b/include/al/execute/ExecuteTableHolderUpdate.h new file mode 100644 index 0000000..a691d6c --- /dev/null +++ b/include/al/execute/ExecuteTableHolderUpdate.h @@ -0,0 +1,58 @@ +#pragma once + +#include "ExecuteOrder.h" +#include "al/async/FunctorBase.h" +#include "al/execute/ExecuteTable.h" +#include "al/execute/ExecutorListBase.h" +#include "al/execute/IUseExecutor.h" +#include "ExecuteSystemInitInfo.h" + +#include "container/seadPtrArray.h" +#include "types.h" + +namespace al { + struct ExecutorListActorExecuteBase; + struct ExecutorListLayoutUpdate; + struct ExecutorListIUseExecutorUpdate; + struct ExecutorListFunctor; + struct ExecutorListBase; + struct LiveActor; + struct LayoutActor; +} + +namespace al { +class ExecuteTableHolderUpdate { + public: + ExecuteTableHolderUpdate(); + virtual ~ExecuteTableHolderUpdate(); + void init(char const*, al::ExecuteSystemInitInfo const&, al::ExecuteOrder const*, int); + void registerExecutorListActor(al::ExecutorListActorExecuteBase*); + void registerExecutorListLayout(al::ExecutorListLayoutUpdate*); + void registerExecutorListUser(al::ExecutorListIUseExecutorUpdate*); + void registerExecutorListFunctor(al::ExecutorListFunctor*); + void registerExecutorListAll(al::ExecutorListBase*); + void tryRegisterActor(al::LiveActor*, char const*); + void tryRegisterLayout(al::LayoutActor*, char const*); + void tryRegisterUser(al::IUseExecutor*, char const*); + void tryRegisterFunctor(al::FunctorBase const&, char const*); + void createExecutorListTable(); + void execute() const; + void executeList(char const*) const; + + const char *mName; + sead::PtrArray mActiveExecutors; + sead::PtrArray mExecutorsAll; + sead::PtrArray mExecutorsActor; + sead::PtrArray mExecutorsLayout; + sead::PtrArray mExecutorsUser; + sead::PtrArray mExecutorsFunctor; + + }; +} // namespace al + +extern "C" al::ExecuteTable gameUpdateTable[]; // pointer to original update table found in the exefs + +extern const al::ExecuteTable updateTable[]; + +extern int updateTableSize; + diff --git a/include/al/execute/ExecutorListBase.h b/include/al/execute/ExecutorListBase.h new file mode 100644 index 0000000..acb2f60 --- /dev/null +++ b/include/al/execute/ExecutorListBase.h @@ -0,0 +1,15 @@ +#pragma once + +#include "types.h" + +namespace al { + class ExecutorListBase { + public: + ExecutorListBase(char const*); + virtual ~ExecutorListBase(); + virtual void executeList() const; + virtual bool isActive() const; + + const char *mName; + }; +} \ No newline at end of file diff --git a/include/al/gfx/GraphicsSystemInfo.h b/include/al/gfx/GraphicsSystemInfo.h new file mode 100644 index 0000000..e9c0f98 --- /dev/null +++ b/include/al/gfx/GraphicsSystemInfo.h @@ -0,0 +1,193 @@ +#pragma once + +#include "al/execute/ExecuteDirector.h" +#include "al/model/ModelMaterialCategory.h" +#include "al/resource/Resource.h" +#include "container/seadPtrArray.h" +#include "gfx/seadCamera.h" + +#include "UniformBlock.h" +#include "types.h" + +namespace al { + struct GraphicsInitArg; + struct GraphicsUpdateInfo; + struct GraphicsCalcGpuInfo; + struct PartsGraphics; + struct GraphicsRenderInfo; + struct GraphicsCopyInfo; + struct GraphicsComputeInfo; + struct AreaObjDirector; + struct EffectSystem; + struct SceneCameraInfo; + struct ShaderHolder; + struct GBufferArray; + struct Projection; + struct RenderVariables; + struct ShaderCubeMapKeeper; + struct ShaderMirrorDirector; + struct SubCameraRenderer; + struct GraphicsParamFilePath; + struct PlayerHolder; +} + +namespace agl { + struct DrawContext; + + namespace utl { + struct ParameterOfBool { char size[0x20]; }; + struct ParameterOfInt { char size[0x20]; }; + struct ParameterOfFloat { char size[0x20]; }; + struct IParameterObj { char size[0x30]; }; + struct IParameterIO { char size[0x1D0]; }; + } +} + +namespace al { + class GraphicsSystemInfo { + public: + GraphicsSystemInfo(); + ~GraphicsSystemInfo(); + void getModelEnv() const; + void getDrawContext() const; + void getShaderCubeMapKeeper() const; + void getViewIndexedUboArray(char const*) const; + void setViewIndexedUboArray(char const*, sead::PtrArray const*); + void initAtmosScatter(al::ExecuteDirector*); + void init(al::GraphicsInitArg const&, al::AreaObjDirector*, al::ExecuteDirector*, al::EffectSystem*, al::PlayerHolder*, al::SceneCameraInfo*, al::ShaderHolder*); + void initProjectResource(); + void initStageResource(al::Resource const*, char const*, char const*); + void endInit(); + void initAfterPlacement(); + void initAfterCreateDrawTable(); + void setDrawEnv(int, al::GBufferArray*, sead::Camera const*, al::Projection const*); + void clearGraphicsRequest(); + void cancelLerp(); + void updateGraphics(); + void updatePartsGraphics(al::GraphicsUpdateInfo const&); + void preDrawGraphics(al::SceneCameraInfo const*); + void calcGpuPartsGraphics(al::GraphicsCalcGpuInfo const&); + void updateViewGpu(int, sead::Camera const*, al::Projection const*); + void updateViewVolume(sead::Matrix34f const&, sead::Matrix44 const&); + void clearViewVolume(); + void tryGetAtmosLightDir(sead::Vector3f*) const; + void tryDirectionalLightInfo(sead::Vector3f*) const; + void activateDirLitColorTex() const; + void activateDirLitColorTex(agl::DrawContext*) const; + void registPartsGraphics(al::PartsGraphics*); + void drawSystemPartsGraphics(al::GraphicsRenderInfo const*) const; + void doPartsGraphicsCommandBufferCopy(al::GraphicsCopyInfo const&) const; + void doPartsGraphicsCompute(al::GraphicsComputeInfo const&) const; + void drawPartsGraphics(al::GraphicsRenderInfo const&, al::RenderVariables const&) const; + void drawPartsGraphicsGBufferAfterSky(al::GraphicsRenderInfo const&) const; + void drawPartsGraphicsDeferred(al::GraphicsRenderInfo const&) const; + void drawPartsGraphicsLdr(al::GraphicsRenderInfo const&) const; + void drawPartsGraphicsIndirect(al::GraphicsRenderInfo const&, al::RenderVariables const&) const; + void drawPartsGraphicsCubemap(al::GraphicsRenderInfo const&) const; + + void *qword0; + void *qword8; + void *qword10; + void *qword18; + char gap20[5]; + char byte25; + u16 word26; + int dword28; + int dword2C; + int dword30; + int dword34; + int dword38; + int dword3C; + char byte40; + int dword44; + char byte48; + int dword4C; + int dword50; + int dword54; + int dword58; + int dword5C; + void *qword60; + char char68; + al::ShaderCubeMapKeeper **field_70; + char gap78[56]; + al::ShadowDirector *field_B0; + char gapB8[16]; + al::ShaderMirrorDirector *field_C8; + char gapD0[320]; + char char210; + void *qword218; + void *qword220; + void *qword228; + void *qword230; + al::MaterialCategoryKeeper *mMaterialCategoryKeeper; + void *qword240; + void *qword248; + void *qword250; + void *qword258; + void *qword260; + void *qword268; + void *qword270; + void *qword278; + void *qword280; + al::GpuMemAllocator *field_288; + char gap290[8]; + void *qword298; + void *qword2A0; + char gap2A8[8]; + void *qword2B0; + al::SubCameraRenderer *field_2B8; + void *qword2C0; + void *qword2C8; + void *qword2D0; + void *qword2D8; + void *qword2E0; + void *qword2E8; + int dword2F0; + __attribute__((packed)) __attribute__((aligned(1))) void *qword2F4; + __attribute__((packed)) __attribute__((aligned(1))) void *qword2FC; + __attribute__((packed)) __attribute__((aligned(1))) void *qword304; + int dword30C; + al::GraphicsParamFilePath *mParamFilePath; + agl::utl::IParameterIO agl__utl__iparameterio318; + agl::utl::IParameterObj agl__utl__iparameterobj4E8; + agl::utl::ParameterOfInt field_518; + agl::utl::ParameterOfInt field_538; + agl::utl::ParameterOfBool field_558; + agl::utl::ParameterOfBool field_578; + agl::utl::ParameterOfInt field_598; + agl::utl::IParameterIO field_5B8; + agl::utl::IParameterObj field_788; + agl::utl::ParameterOfBool field_7B8; + agl::utl::ParameterOfBool field_7D8; + agl::utl::ParameterOfBool field_7F8; + agl::utl::ParameterOfFloat field_818; + agl::utl::ParameterOfFloat field_838; + agl::utl::ParameterOfFloat field_858; + agl::utl::ParameterOfFloat field_878; + agl::utl::ParameterOfFloat field_898; + agl::utl::ParameterOfFloat field_8B8; + agl::utl::ParameterOfFloat field_8D8; + agl::utl::ParameterOfFloat field_8F8; + void *qword918; + void *qword920; + void *qword928; + void *qword930; + void *qword938; + void *qword940; + void *qword948; + void *qword950; + void *qword958; + int dword960; + void *qword968; + void *qword970; + int dword978; + void *qword980; + al::ModelOcclusionCullingDirector *field_988; + void *qword990; + al::ModelShaderHolder *field_998; + al::PrepassTriangleCulling *field_9A0; + char byte9A8; + void *field_9B0; + + }; +} \ No newline at end of file diff --git a/include/al/gfx/UniformBlock.h b/include/al/gfx/UniformBlock.h new file mode 100644 index 0000000..373b93a --- /dev/null +++ b/include/al/gfx/UniformBlock.h @@ -0,0 +1,12 @@ +#pragma once + +#include "types.h" + +namespace al { + class UniformBlock { + UniformBlock(); + ~UniformBlock(); + void swap(); + + }; +} \ No newline at end of file diff --git a/include/al/model/ModelCtrl.h b/include/al/model/ModelCtrl.h new file mode 100644 index 0000000..eefb416 --- /dev/null +++ b/include/al/model/ModelCtrl.h @@ -0,0 +1,107 @@ +#pragma once + +#include "agl/DisplayList.h" +#include "al/resource/Resource.h" +#include "math/seadMatrix.h" +#include "nn/g3d/ResModel.h" + +namespace al { + struct ShaderHolder; + struct ModelShaderHolder; + struct ModelOcclusionCullingDirector; + struct ShadowDirector; + struct PrepassTriangleCulling; + struct ModelLodCtrl; + struct DitherAnimator; + struct ModelMaterialCategory; + struct GpuMemAllocator; +} + +namespace nn { namespace g3d { + struct Sphere; +}} + +namespace al { + class ModelCtrl { + public: + ModelCtrl(); + ~ModelCtrl(); + void initialize(nn::g3d::ResModel*, int, int, sead::Heap*, al::ShaderHolder*); + void tryBindShader(); + void tryUpdateModelAdditionalInfoUbo(int); + void updateWorldMatrix(sead::Matrix34f const&, sead::Vector3f const&); + void updateGpuBuffer(int); + void calcBounding(); + void getLodLevel() const; + void getLodLevelDepthShadow() const; + void calcBoundingLod(int); + void updateQueryBox(); + void updateModelDrawBuffer(int); + void updateGpuBufferAll(); + void isShapeVisible(int) const; + void setCubeMapIndexAllShape(int); + void recreateDisplayList(); + void setMaterialProgrammable(int, bool); + void isMaterialProgrammable(int); + void setSkeletonUpdateInfo(bool, sead::Matrix34f const&, sead::Vector3f const&); + void setDirtyTexture(); + void onZPrePass(); + void offZPrePass(); + void getEnvTexInfo(int) const; + void requestModelAdditionalInfoUbo(); + void setLodCtrl(al::ModelLodCtrl*); + void getLodLevelMax() const; + void getLodLevelMaterial() const; + void getLodLevelNoClamp() const; + void setLodLevelForce(int); + void updateLodCtrl(); + void setDitherAnimator(al::DitherAnimator*); + void updateDitherAnimator(); + void checkChangeDisplayList(); + void addToDrawerCulling(); + void removeFromDrawerCulling(); + void updateSubMesh(); + void setModelMaterialCategory(al::ModelMaterialCategory const*); + void setModelAlphaMask(float); + void setModelUvOffset(sead::Vector2f const&); + void setModelProjMtx0(sead::Matrix44 const&); + void setModelProjMtx1(sead::Matrix44 const&); + void setModelProjMtx2(sead::Matrix44 const&); + void setModelProgProjMtx0(sead::Matrix44 const&); + void setModelProgProjMtx1(sead::Matrix44 const&); + void setModelProgProjMtx2(sead::Matrix44 const&); + void setModelProgProjMtx3(sead::Matrix44 const&); + void setModelProgConstant0(float); + void setModelProgConstant1(float); + void setModelProgConstant2(float); + void setModelProgConstant3(float); + void setModelProgConstant4(float); + void setModelProgConstant5(float); + void setModelProgConstant6(float); + void setModelProgConstant7(float); + void setNormalAxisXScale(float); + void calcCameraToBoundingSphereDistance() const; + void isUseLocalShadowMap() const; + void validateOcclusionQuery(); + void invalidateOcclusionQuery(); + void isValidOcclusionQuery() const; + void createUniqShader(); + void isCreateUniqShader(int); + void getUniqModelShader(int); + void getUniqModelShaderAssgin(int); + void pushDisplayListModel(agl::DisplayList*); + void pushDisplayListShape(agl::DisplayList*, int); + void getModelShapeCtrl(int) const; + void initResource(al::Resource*, al::Resource*); + void initModel(al::GpuMemAllocator*, al::ModelShaderHolder*, al::ModelOcclusionCullingDirector*, al::ShadowDirector*, al::PrepassTriangleCulling*, int, int); + void tryCreateCulledIndexBuffer(); + void show(); + void hide(); + void calc(sead::Matrix34f const&, sead::Vector3f const&); + void calcView(); + void calcModelObjBoundingWithOffset(nn::g3d::Sphere*) const; + void setCameraInfo(sead::Matrix34f const*, sead::Matrix34f const*, sead::Matrix44 const*, sead::Matrix44 const*); + void getShapeObj(int) const; + + }; +} \ No newline at end of file diff --git a/include/al/model/ModelKeeper.h b/include/al/model/ModelKeeper.h new file mode 100644 index 0000000..704da26 --- /dev/null +++ b/include/al/model/ModelKeeper.h @@ -0,0 +1,46 @@ +#pragma once + +#include "al/resource/ActorResource.h" +#include "math/seadMatrix.h" +#include "types.h" +#include "ModelCtrl.h" + +namespace al { + struct ModelLodCtrl; + struct DitherAnimator; + struct GpuMemAllocator; + struct ModelShaderHolder; + struct ModelOcclusionCullingDirector; + struct ShadowDirector; + struct PrepassTriangleCulling; +} + +namespace al { + class ModelKeeper { + public: + ModelKeeper(); + virtual ~ModelKeeper(); + void initResource(al::ActorResource const*); + void createMatAnimForProgram(int); + void getAnimResource() const; + void getModelResource() const; + void setDisplayRootJointMtxPtr(sead::Matrix34f const*); + void setModelLodCtrl(al::ModelLodCtrl*); + void setDitherAnimator(al::DitherAnimator*); + void initModel(int, al::GpuMemAllocator*, al::ModelShaderHolder*, al::ModelOcclusionCullingDirector*, al::ShadowDirector*, al::PrepassTriangleCulling*); + void show(); + void hide(); + void update(); + void updateLast(); + void calc(sead::Matrix34f const&, sead::Vector3f const&); + void getBaseMtx() const; + void getWorldMtxPtrByIndex(int) const; + + const char *mResourceName; + al::ModelCtrl *mModelCtrl; + const al::ActorResource *mResource; + char gap20[67]; + bool field_63; + + }; +} \ No newline at end of file diff --git a/include/al/model/ModelMaterialCategory.h b/include/al/model/ModelMaterialCategory.h new file mode 100644 index 0000000..5486e45 --- /dev/null +++ b/include/al/model/ModelMaterialCategory.h @@ -0,0 +1,19 @@ +#pragma once + +#include "ModelCtrl.h" +#include "al/byaml/ByamlIter.h" + +namespace al { + struct MaterialCategoryKeeper; + + class ModelMaterialCategory { + public: + ModelMaterialCategory(al::ModelCtrl*, al::MaterialCategoryKeeper*); + void init(char const*); + void init(al::ByamlIter const&); + void getCategoryIdFromMaterialName(char const*) const; + void getCategoryIdFromMaterialIndex(int) const; + static void tryCreate(al::ModelCtrl*, al::Resource const*, char const*, al::MaterialCategoryKeeper*); + static void tryCreate(al::ModelCtrl*, char const*, al::MaterialCategoryKeeper*); + }; +} \ No newline at end of file diff --git a/include/al/model/PartsModel.h b/include/al/model/PartsModel.h new file mode 100644 index 0000000..b120399 --- /dev/null +++ b/include/al/model/PartsModel.h @@ -0,0 +1,42 @@ +#pragma once + +#include "al/LiveActor/LiveActor.h" +#include "types.h" + +namespace al { +class PartsModel : public al::LiveActor { + public: + PartsModel(char const*); + void endClipped() override; + void calcAnim() override; + void attackSensor(al::HitSensor*, al::HitSensor*) override; + bool receiveMsg(al::SensorMsg const*, al::HitSensor*, al::HitSensor*) override; + + void initPartsDirect(al::LiveActor*, al::ActorInitInfo const&, char const*, sead::Matrix34f const*, sead::Vector3f const&, sead::Vector3f const&, sead::Vector3f const&, bool); + void initPartsSuffix(al::LiveActor*, al::ActorInitInfo const&, char const*, char const*, sead::Matrix34f const*, bool); + void initPartsMtx(al::LiveActor*, al::ActorInitInfo const&, char const*, sead::Matrix34f const*, bool); + void initPartsFixFile(al::LiveActor*, al::ActorInitInfo const&, char const*, char const*, char const*); + void initPartsFixFileNoRegister(al::LiveActor*, al::ActorInitInfo const&, char const*, + char const*, char const*); + + void updatePose(); + void offSyncAppearAndHide(); + void onSyncAppearAndHide(); + + void *unkPtr1; // 0x108 + void* unkPtr2; // 0x110 + int unkInt1; // 0x118 + int unkInt2; // 0x11C + int unkInt3; // 0x120 + int unkInt4; // 0x124 + int unkInt5; // 0x128 + int unkInt6; // 0x12C + int unkInt7; // 0x130 + float unkFloat1; // 0x134 + float unkFloat2; // 0x138 + float unkFloat3; // 0x13C + bool unkBool; // 0x140 + bool unkBool2; // 0x141 + bool unkBool3; // 0x142 + }; +} \ No newline at end of file diff --git a/include/al/resource/ActorResource.h b/include/al/resource/ActorResource.h new file mode 100644 index 0000000..8e94276 --- /dev/null +++ b/include/al/resource/ActorResource.h @@ -0,0 +1,35 @@ +#pragma once + +#include "prim/seadSafeString.h" +#include "types.h" +#include "Resource.h" + +namespace al { + + class AnimInfoTable { char size[0x18]; }; + + struct InitResourceDataAnim { + al::AnimInfoTable *mInfoTable; // 0x0 + al::AnimInfoTable *mFclAnim; // 0x8 + al::AnimInfoTable *mFtsAnim; // 0x10 + al::AnimInfoTable *mFtpAnim; // 0x18 + al::AnimInfoTable *mInfoTable2; // 0x18 + }; + + class ActorResource { + public: + ActorResource(sead::SafeString const&, al::Resource*, al::Resource*); + virtual ~ActorResource(); + + void initResourceData(char const*, bool); + + sead::FixedSafeString<0x80> unkStr; // 0x8 + al::Resource *mResourceModel; // 0xA0 + al::Resource *mResourceAnim; // 0xA8 + bool unkBool1; // 0xB0 + al::InitResourceDataAnim *mAnimResData; // 0xB8 + void *unkPtr2; // 0xC0 + }; +} + +static_assert(sizeof(al::ActorResource) == 0xC8, "ActorResource Size"); \ No newline at end of file diff --git a/include/al/resource/ActorResourceHolder.h b/include/al/resource/ActorResourceHolder.h new file mode 100644 index 0000000..09d94ea --- /dev/null +++ b/include/al/resource/ActorResourceHolder.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Resource.h" +#include "types.h" + +namespace al { + class ActorResourceHolder { + + ActorResourceHolder(int); + ~ActorResourceHolder(); + + void tryFindActorResource(sead::SafeString const&); + void findActorResourceImpl(sead::SafeString const&); + void createActorResource(sead::SafeString const&, al::Resource*, al::Resource*); + void removeAll(); + void eraseResourceUser(al::Resource*); + void freeErasedActorResource(); + + }; +} \ No newline at end of file diff --git a/include/al/resource/Resource.h b/include/al/resource/Resource.h new file mode 100644 index 0000000..0de7c77 --- /dev/null +++ b/include/al/resource/Resource.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include +#include + +#include "nn/g3d/g3d_ResFile.h" + +namespace al { + class Resource { + public: + Resource(sead::SafeString const&); + Resource(sead::SafeString const&, sead::ArchiveRes*); + + bool isExistFile(sead::SafeString const&) const; + bool isExistByml(char const*) const; + + int getSize() const; + + int getEntryNum(sead::SafeString const&) const; + const char *getEntryName(sead::BufferedSafeString*, sead::SafeString const&, unsigned int) const; + + void getFileSize(sead::SafeString const&) const; + void getByml(sead::SafeString const&) const; + void getFile(sead::SafeString const&) const; + void tryGetByml(sead::SafeString const&) const; + void getKcl(sead::SafeString const&) const; + void tryGetKcl(sead::SafeString const&) const; + void getPa(sead::SafeString const&) const; + void tryGetPa(sead::SafeString const&) const; + void getOtherFile(sead::SafeString const&) const; + const char* getArchiveName() const; + + bool tryCreateResGraphicsFile(sead::SafeString const&, nn::g3d::ResFile*); + void cleanupResGraphicsFile(); + + sead::ArchiveRes* mArc; // 0x0 + sead::ArchiveFileDevice *mFileDevice; // 0x8 + sead::FixedSafeString<0x80> mArcName; // 0x10 + sead::Heap* mCurrentHeap; // 0xA8 + void *unkPtr; // 0xB0 + nn::g3d::ResFile *mResGfxFile; // 0xB8 + + }; +} // namespace al + +static_assert(sizeof(al::Resource) == 0xC0, "al::Resource Size"); diff --git a/include/al/scene/Scene.h b/include/al/scene/Scene.h index 78bdb24..68a680e 100644 --- a/include/al/scene/Scene.h +++ b/include/al/scene/Scene.h @@ -5,11 +5,19 @@ #include "al/audio/AudioKeeper.h" #include "al/camera/CameraDirector.h" #include "al/scene/SceneObjHolder.h" +#include "prim/seadSafeString.h" namespace al { class GraphicsInitArg; + class StageResourceKeeper; + class LiveActorKit; + class LayoutKit; + class SceneStopCtrl; + class SceneMsgCtrl; + class ScreenCoverCtrl; + class AudioDirector; class Scene : public al::NerveExecutor, public al::IUseAudioKeeper, public al::IUseCamera, public al::IUseSceneObjHolder { @@ -32,6 +40,17 @@ namespace al void initLiveActorKitWithGraphics(al::GraphicsInitArg const &, al::SceneInitInfo const &, int, int, int); - unsigned char _28[0xD8-0x28]; + bool mIsAlive; + sead::FixedSafeString<0x40> mName; + al::StageResourceKeeper *mStageResourceKeeper; + al::LiveActorKit *mActorKit; + al::LayoutKit *mLayoutKit; + al::SceneObjHolder *mSceneObjHolder; + al::SceneStopCtrl *mSceneStopCtrl; + al::SceneMsgCtrl *mSceneMsgCtrl; + al::ScreenCoverCtrl *mScreenCoverCtrl; + al::AudioDirector *mAudioDirector; + al::AudioKeeper *mAudioKeeper; + al::NerveKeeper *mNerveKeeper; }; }; \ No newline at end of file diff --git a/include/al/scene/SceneCreator.h b/include/al/scene/SceneCreator.h index dc7d41d..2581883 100644 --- a/include/al/scene/SceneCreator.h +++ b/include/al/scene/SceneCreator.h @@ -8,6 +8,6 @@ namespace al { public: virtual al::SceneCreator* getSceneCreator() const = 0; - virtual al::SceneCreator* setSceneCreator() const = 0; + virtual void setSceneCreator(al::SceneCreator* ) = 0; }; }; \ No newline at end of file diff --git a/include/al/sequence/Sequence.h b/include/al/sequence/Sequence.h index f140ce0..76c7ffd 100644 --- a/include/al/sequence/Sequence.h +++ b/include/al/sequence/Sequence.h @@ -1,12 +1,61 @@ #pragma once +#include "al/audio/AudioDirector.h" #include "al/nerve/NerveExecutor.h" #include "al/audio/AudioKeeper.h" #include "al/scene/SceneCreator.h" +#include "game/System/GameDrawInfo.h" namespace al { + + class GameSystemInfo; + class SequenceInitInfo; + class AudioSystemInfo; + class Scene; + class Sequence : public al::NerveExecutor, public al::IUseAudioKeeper, public al::IUseSceneCreator { public: - Sequence(const char *seqName); + Sequence(const char* name); + virtual ~Sequence() override; + virtual void init(const al::SequenceInitInfo& initInfo); + virtual void update(); + virtual void kill(); + virtual void drawMain() const; + virtual void drawSub() const; + virtual bool isDisposable() { return false; } + al::Scene* getCurrentScene() const; + al::SceneCreator* getSceneCreator() const override; + void setSceneCreator(al::SceneCreator* sceneCreator) override; + + al::AudioKeeper* getAudioKeeper() const override; + void initAudio(const al::GameSystemInfo&, const char*, int, int, int, const char*); + void initAudioKeeper(const char*); + void initDrawSystemInfo(const al::SequenceInitInfo&); + al::AudioSystemInfo* getAudioSystemInfo(); + + al::GameDrawInfo* getDrawInfo() const { + return mGameDrawInfo; + } + + al::AudioDirector* getAudioDirector() const { + return mAudioDirector; + } + + void setNextScene(al::Scene* scene) { + mNextScene = scene; + } + + const sead::SafeString& getName() const { + return mName; + } + + const sead::FixedSafeString<0x40> mName; + al::Scene* mNextScene; + al::Scene* mCurrentScene; + al::SceneCreator* mSceneCreator; + al::AudioDirector* mAudioDirector; + al::AudioKeeper* mAudioKeeper; + al::GameDrawInfo* mGameDrawInfo; + bool mIsAlive; }; } \ No newline at end of file diff --git a/include/al/util.hpp b/include/al/util.hpp index 527285b..ebcd06c 100644 --- a/include/al/util.hpp +++ b/include/al/util.hpp @@ -10,6 +10,7 @@ #include "al/util/MathUtil.h" #include "al/util/NerveUtil.h" #include "al/util/CameraUtil.h" +#include "al/util/KitUtil.h" namespace al { diff --git a/include/al/util/KitUtil.h b/include/al/util/KitUtil.h new file mode 100644 index 0000000..09a3e16 --- /dev/null +++ b/include/al/util/KitUtil.h @@ -0,0 +1,17 @@ +#pragma once + +#include "al/scene/Scene.h" + +namespace al { + + class LayoutKit; + class LiveActorKit; + + void updateKitList(al::Scene *,char const*,char const*); + void updateKitList(al::Scene*, char const*); + + void executeUpdateList(al::LayoutKit *,char const*,char const*); + void executeUpdateList(al::LiveActorKit*, char const*, char const*); + + void executeDrawList(al::LiveActorKit const*,char const*,char const*); +} \ No newline at end of file diff --git a/include/al/util/LiveActorUtil.h b/include/al/util/LiveActorUtil.h index 7c42255..e3b93a7 100644 --- a/include/al/util/LiveActorUtil.h +++ b/include/al/util/LiveActorUtil.h @@ -26,6 +26,9 @@ namespace al { void onSyncClippingSubActor(LiveActor*, const LiveActor*); void onSyncHideSubActor(LiveActor*, const LiveActor*); void onSyncAlphaMaskSubActor(LiveActor*, const LiveActor*); + void onSyncAppearSubActor(al::LiveActor *,al::LiveActor const*); + void onSyncAppearSubActor(al::LiveActor *,char const*); + void onSyncAppearSubActorAll(al::LiveActor *); void setMaterialProgrammable(LiveActor*); void startAction(LiveActor*, char const*); void startAction(IUseLayoutAction*, const char *, const char *); @@ -41,6 +44,8 @@ namespace al { void turnToTarget(LiveActor*, const al::LiveActor *, float); void expandClippingRadiusByShadowLength(LiveActor *,sead::Vector3f *, float); + void addPartialSklAnimPartsListRecursive(al::LiveActor*, char const*, int); + void setMaterialProgrammable(al::LiveActor *); void initJointLocalXRotator(const LiveActor *,const float *,const char *); void initJointLocalYRotator(const LiveActor *,const float *,const char *); @@ -56,7 +61,23 @@ namespace al { void initActorPoseTQGSV(al::LiveActor *); void initActorPoseTQGMSV(al::LiveActor *); void initActorPoseT(al::LiveActor *,sead::Vector3 const&); - void initActorPoseTR(al::LiveActor *,sead::Vector3 const&,sead::Vector3 const&); + void initActorPoseTR(al::LiveActor*, sead::Vector3 const&, sead::Vector3 const&); + + void initActorSRT(al::LiveActor*, al::ActorInitInfo const&); + void initActorSceneInfo(al::LiveActor *, al::ActorInitInfo const&); + void initActorModelKeeper(al::LiveActor *,al::ActorInitInfo const&,al::ActorResource const*,int); + void initActorModelKeeper(al::LiveActor*, al::ActorInitInfo const&, char const*, int, + char const*); + void initActorEffectKeeper(al::LiveActor*, al::ActorInitInfo const&, char const*); + void initActorActionKeeper(al::LiveActor *,al::ActorInitInfo const&,char const*,char const*); + void initActorActionKeeper(al::LiveActor*, al::ActorResource const*, char const*, char const*); + void initActorClipping(al::LiveActor *,al::ActorInitInfo const&); + void initPartialSklAnim(al::LiveActor*, int, int, int); + + bool tryGetActorInitFileIterAndName(al::ByamlIter *,sead::BufferedSafeStringBase *,al::Resource const*,char const*,char const*); + bool tryGetActorInitFileIter(al::ByamlIter *,al::Resource const*,char const*,char const*); + bool tryGetActorInitFileIterAndName(al::ByamlIter *,sead::BufferedSafeStringBase *,al::LiveActor const*,char const*,char const*); + bool tryGetActorInitFileIter(al::ByamlIter *,al::LiveActor const*,char const*,char const*); void initLayoutPartsActor(LayoutActor*, LayoutActor*, const LayoutInitInfo&, char const*, char const*); diff --git a/include/al/util/ResourceUtil.h b/include/al/util/ResourceUtil.h new file mode 100644 index 0000000..685b90c --- /dev/null +++ b/include/al/util/ResourceUtil.h @@ -0,0 +1,17 @@ +#pragma once + +#include "al/LiveActor/LiveActor.h" +#include "al/resource/ActorResourceHolder.h" +#include "al/resource/ActorResource.h" + +namespace al { + + al::ActorResource *findOrCreateActorResource(al::ActorResourceHolder *,char const*,char const*); + al::ActorResource* findOrCreateActorResourceWithAnimResource(al::ActorResourceHolder*, + char const*, char const*, + char const*, bool); + + al::Resource *getModelResource(al::LiveActor const*); + al::Resource *getModelResourceYaml(al::LiveActor const*,char const*,char const*); + +} \ No newline at end of file diff --git a/include/game/Actors/Shine.h b/include/game/Actors/Shine.h index c51df7a..a7f750d 100644 --- a/include/game/Actors/Shine.h +++ b/include/game/Actors/Shine.h @@ -51,7 +51,7 @@ class Shine : public al::LiveActor , public IUseDimension { QuestInfo *shineQuestInfo; // 0x278 void *unkPtr1; // 0x280 ActorDimensionKeeper *mDimensionKeeper; // 0x288 - int shineId; // 0x290 + int mShineIdx; // 0x290 bool mIsMainShine; void *qword298; void *qword2A0; diff --git a/include/game/GameData/GameDataFile.h b/include/game/GameData/GameDataFile.h index 5728bfa..f6454a4 100644 --- a/include/game/GameData/GameDataFile.h +++ b/include/game/GameData/GameDataFile.h @@ -7,6 +7,7 @@ #include "al/scene/SceneObjHolder.h" #include "container/seadPtrArray.h" +#include "prim/seadSafeString.h" #include "types.h" #include "UniqueObjInfo.h" #include "GameProgressData.h" @@ -43,7 +44,48 @@ class ShineInfo; class GameDataFile { public: - GameDataFile(GameDataHolder *); + GameDataFile(GameDataHolder*); + + struct HintInfo { + void clear(void); + bool isDisableByWorldWarpHole(bool) const; + bool isEnableUnlock(int, bool, int, bool) const; + bool isHintStatusUnlock(int, int, bool) const; + bool isHintStatusUnlockByNpc(void) const; + bool isHintStatusUnlockByAmiibo(void) const; + bool isEnableNameUnlockByScenario(int, int, bool) const; + + sead::FixedSafeString<0x80> mStageName; // 0x0 + sead::FixedSafeString<0x80> mObjId; // 0x98 + sead::FixedSafeString<0x40> mScenarioName; // 0x130 + const char *mObjectName; // 0x188 + sead::Vector3f mTrans; // 0x190 + sead::Vector3f mTransAgain; // 0x19C + void *unkPtr1; // 0x1A8 + void *unkPtr2; // 0x1B0 + void *unkPtr3; // 0x1B8 + void *unkPtr4; // 0x1C0 + s32 mMainScenarioNo; // 0x1C8 + int mWorldIndex; // 0x1CC + bool mIsMoonRock; // 0x1D0 + bool unkBool1; // 0x1D1 + bool mIsAchievement; // 0x1D2 + bool mIsGrand; // 0x1D3 + bool mIsShopMoon; // 0x1D4 + int unkInt; // 0x1D8 + int unkInt2; // 0x1DC + void *unkPtr6; // 0x1E0 + void *unkPtr7; // 0x1E8 + int mUniqueID; // 0x1F0 + int mHintIdx; // 0x1F4 + sead::FixedSafeString<0x20> mOptionalID; // 0x1F8 + uint mProcessBitflag; // 0x230 + bool unkBool2; // 0x234 + bool unkBool3; // 0x235 + }; + + static_assert(sizeof(HintInfo) == 0x238, "size of HintInfo"); + void initializeData(void); void tryReadByamlData(uchar const*); void tryFindCoinCollectInfo(char const*,char const*); @@ -151,7 +193,7 @@ class GameDataFile void wearCostume(char const*); void wearCap(char const*); void addHackDictionary(char const*); - void findShine(int,int); + HintInfo* findShine(int worldIndex, int shineIndex); void calcShineNumInOneShine(int,int); void checkAchievementShine(int,int); void winRace(void); @@ -195,7 +237,7 @@ class GameDataFile void tryFindUniqueId(ShineInfo const*); void findUnlockShineNumCurrentWorld(bool *); void trySetCollectedBgm(char const*,char const*); - // void setGotShine(GameDataFile::HintInfo const*); + void setGotShine(GameDataFile::HintInfo const*); // void tryWriteByByaml(al::ByamlWriter *); int getTotalShineNum(void); @@ -229,7 +271,7 @@ class GameDataFile void getPlayerHitPointData(void); void getLastUpdateTime(void); void getPlayTimeTotal(void); - void getMainScenarioNo(int); + int getMainScenarioNo(int) const; void getCollectedBgmMaxNum(void); int getScenarioNo(void) const; void getMiniGameName(int); @@ -314,6 +356,21 @@ class GameDataFile bool isGameClear(void) const; bool isEmpty(void) const; bool isKidsMode(void) const; + + // custom methods + + // custom impl of findShine that uses shine UID instead of index to get the right HintInfo + HintInfo* findShine(int shineUid) { + for (int x = 0; x < 0x400; x++) { + GameDataFile::HintInfo* curInfo = &mShineHintList[x]; + if (curInfo->mUniqueID == shineUid) { + return curInfo; + } + } + return nullptr; + } + + // end custom methods ShineInfo **mShineInfoArray; ShineInfo **mShineInfoArray2; @@ -349,7 +406,7 @@ class GameDataFile void *qword5E8; void *qword5F0; u16 word5F8; - bool byte5FA; + bool mIsEnableCap; void *qword600; int dword608; bool byte60C; @@ -403,7 +460,7 @@ class GameDataFile bool byte901; int dword904; sead::FixedSafeString<0x80> char908; - void *char9A0; + HintInfo *mShineHintList; // 0x9A0 sead::PtrArrayImpl sead__ptrarrayimpl9A8; sead::PtrArrayImpl sead__ptrarrayimpl9B8; sead::PtrArrayImpl sead__ptrarrayimpl9C8; diff --git a/include/game/GameData/GameDataFunction.h b/include/game/GameData/GameDataFunction.h index bd9a987..e730ab1 100644 --- a/include/game/GameData/GameDataFunction.h +++ b/include/game/GameData/GameDataFunction.h @@ -67,6 +67,12 @@ public: // checks save file if shine is collected by shine index only (0 through 725) static bool isGotShine(GameDataHolderAccessor, int); + // checks save file if shine is collected using the shines ShineInfo + static bool isGotShine(GameDataHolderAccessor, ShineInfo const*); + + // checks save file if shine is collected using the shines stage and obj ID + static bool isGotShine(GameDataHolderAccessor, const char *stageName, const char *objID); + // Gets Index for X Kingdom static s32 getWorldIndexWaterfall(void); static s32 getWorldIndexMoon(void); @@ -151,5 +157,19 @@ public: static bool isUnlockFirstForest(void); static bool isUnlockFirstSea(void); +}; -}; \ No newline at end of file +namespace CustomGameDataFunction { + static GameDataFile::HintInfo* getHintInfoByUniqueID(GameDataHolderAccessor accessor, int uid) { + return accessor.mData->mGameDataFile->findShine(uid); + } + + static const GameDataFile::HintInfo* getHintInfoByIndex(GameDataHolderAccessor accessor, int index) { + return &accessor.mData->mGameDataFile->mShineHintList[index]; + } + + static const GameDataFile::HintInfo* getHintInfoByIndex(al::LiveActor* actor, int index) { + GameDataHolderAccessor accessor(actor); + return getHintInfoByIndex(accessor, index); + } +} \ No newline at end of file diff --git a/include/game/HakoniwaSequence/HakoniwaSequence.h b/include/game/HakoniwaSequence/HakoniwaSequence.h index 2e4b056..de3884f 100644 --- a/include/game/HakoniwaSequence/HakoniwaSequence.h +++ b/include/game/HakoniwaSequence/HakoniwaSequence.h @@ -21,12 +21,18 @@ #include "HakoniwaStateSimpleDemo.h" #include "HakoniwaStateBootLoadData.h" -namespace al -{ +namespace al { class WipeHolder; class ScreenCaptureExecutor; - class BootLayout; -} // namespace al + class SeadAudioPlayer; + class AudioBusSendFader; + class SimpleAudioUser; +} // namespace al + +class BootLayout; +class TimeBalloonSequenceInfo; +class CollectBgmPlayer; +class LoadLayoutCtrl; class HakoniwaSequence : public al::Sequence { public: @@ -40,36 +46,59 @@ class HakoniwaSequence : public al::Sequence { void update(void); bool isEnableSave(void); void drawMain(void); - al::Scene *getCurrentScene(void) const; // {return this->curScene} + al::Scene* getCurrentScene(void) const; // {return this->curScene} - void* qword20; - void* qword28; - void* qword30; - void* qword38; - void* qword40; - void* qword48; - void* qword50; - void* qword58; - void* qword60; - void* qword68; - void* qword70; - void* qword78; - void* qword80; - void* qword88; - al::AudioDirector *mAudioDirector; // 0x90 - void *qword98; - void *qwordA0; - void *qwordA8; - al::Scene *curScene; // 0xB0 - GameDataHolderAccessor mGameDataHolder; // 0xB8 - al::GamePadSystem *mGamepadSys; // 0xC0 - HakoniwaStateDemoOpening *mDemoOpening; // 0xC8 - HakoniwaStateDemoEnding *mDemoEnding; // 0xD0 + void exeBootLoadData(); + void exeDemoOpening(); + void exeLoadWorldResource(); + void exeLoadWorldResourceWithBoot(); + void exeLoadStage(); + void exePlayStage(); + void exeDemoWorldWarp(); + void exeDemoEnding(); + void exeDestroy(); + void exeMiss(); + void exeMissCoinSub(); + void exeMissEnd(); + void exeDemoLava(); + void exeFadeToNewGame(); + + al::Scene *curScene; // 0xB0 + GameDataHolderAccessor mGameDataHolder; // 0xB8 + al::GamePadSystem *mGamepadSys; // 0xC0 + HakoniwaStateDemoOpening *mDemoOpening; // 0xC8 + HakoniwaStateDemoEnding *mDemoEnding; // 0xD0 HakoniwaStateDemoWorldWarp *mDemoWorldWarp; // 0xD8 - HakoniwaStateSimpleDemo *mSimpleDemo; // 0xE0 - HakoniwaStateBootLoadData *mBootLoadData; // 0xE8 - HakoniwaStateDeleteScene *mDeleteScene; // 0xF0 - al::LayoutKit* mLytKit; // 0xF8 - unsigned char padding_168[0x108]; - WorldResourceLoader* mResourceLoader; // 0x208 + HakoniwaStateSimpleDemo *mSimpleDemo; // 0xE0 + HakoniwaStateBootLoadData *mBootLoadData; // 0xE8 + HakoniwaStateDeleteScene *mDeleteScene; // 0xF0 + al::LayoutKit* mLytKit; // 0xF8 + bool mYBalls; + sead::FixedSafeString<0x80> stageName; + int scenarioNum; + al::ScreenCaptureExecutor* mScreenCapExecutor; + al::WipeHolder* mWipeHolder; + bool mMissEnd; + al::SimpleLayoutAppearWaitEnd* mCounterMiss; + int mCurCoins; + int mFinalCoins; + BootLayout* mBootLayout; + al::EffectSystem* mEffectSystem; + al::AsyncFunctorThread* mInitThread; + bool mInitialized; + al::SeadAudioPlayer* mSeAudioPlayer; + al::SeadAudioPlayer* mBgmAudioPlayer; + al::AudioBusSendFader* mBusSendFader; + WorldResourceLoader* mResourceLoader; + sead::Heap* mPlayerResHeap; + sead::FixedSafeString<0x80> mCapName; + sead::FixedSafeString<0x80> mCostumeName; + al::SimpleAudioUser* mPlayerAudioUser; + bool mHackEnd; + TimeBalloonSequenceInfo* mBalloonSeqInfo; + CollectBgmPlayer* mCollectBgmPlayer; + sead::FixedSafeString<0x80> mLanguage; + int mFileId; + LoadLayoutCtrl* mLoadLayoutCtrl; + bool mKidsMode; }; \ No newline at end of file diff --git a/include/game/Info/ShineInfo.h b/include/game/Info/ShineInfo.h index 1ea023c..2420b8a 100644 --- a/include/game/Info/ShineInfo.h +++ b/include/game/Info/ShineInfo.h @@ -30,7 +30,7 @@ class ShineInfo { sead::FixedSafeString<0x80> stageName = sead::FixedSafeString<0x80>(); // 0x0 (Size: 0x98) sead::FixedSafeString<0x80> objectId = sead::FixedSafeString<0x80>(); // 0xA0 - sead::FixedSafeString<0x80> scenObjId = sead::FixedSafeString<0x80>(); // 0x138 + sead::FixedSafeString<0x80> mShineLabel = sead::FixedSafeString<0x80>(); // 0x138 int shineId; // 1C8 const QuestInfo *curQuest; // 1D0 diff --git a/include/game/Player/PlayerActorBase.h b/include/game/Player/PlayerActorBase.h index b26ce2c..aec041b 100644 --- a/include/game/Player/PlayerActorBase.h +++ b/include/game/Player/PlayerActorBase.h @@ -24,6 +24,7 @@ class PlayerActorBase : public al::LiveActor, public IUsePlayerHack { virtual int getPortNo(void); virtual sead::Matrix34f *getViewMtx(void) const; virtual IUsePlayerCollision* getPlayerCollision(void) const; + virtual PlayerHackKeeper* getPlayerHackKeeper() const override; virtual bool isEnableDemo(void); virtual void startDemo(void); @@ -60,7 +61,6 @@ class PlayerActorBase : public al::LiveActor, public IUsePlayerHack { virtual void sendCollisionMsg(void); virtual bool receivePushMsg(al::SensorMsg const*,al::HitSensor *,al::HitSensor *,float); - virtual PlayerHackKeeper* getPlayerHackKeeper() const override; sead::Matrix34f* mViewMtx; // 0x110 int mPortNo; // 0x118 diff --git a/include/game/Player/PlayerCostumeFunction.h b/include/game/Player/PlayerCostumeFunction.h new file mode 100644 index 0000000..d0a9070 --- /dev/null +++ b/include/game/Player/PlayerCostumeFunction.h @@ -0,0 +1,9 @@ +#pragma once + +#include "al/resource/Resource.h" +#include "game/Player/PlayerCostumeInfo.h" + +namespace PlayerCostumeFunction { + PlayerBodyCostumeInfo *createBodyCostumeInfo(al::Resource *,char const*); + PlayerHeadCostumeInfo *createHeadCostumeInfo(al::Resource *,char const*,bool); +} \ No newline at end of file diff --git a/include/game/Player/PlayerFunction.h b/include/game/Player/PlayerFunction.h index 16c03f1..dc15d69 100644 --- a/include/game/Player/PlayerFunction.h +++ b/include/game/Player/PlayerFunction.h @@ -1,11 +1,26 @@ #pragma once #include "al/LiveActor/LiveActor.h" +#include "al/actor/ActorInitInfo.h" +#include "al/actor/SubActorKeeper.h" +#include "al/byaml/ByamlIter.h" +#include "al/model/ModelCtrl.h" +#include "al/model/ModelMaterialCategory.h" +#include "al/model/PartsModel.h" +#include "al/resource/ActorResource.h" +#include "al/string/StringTmp.h" +#include "al/util.hpp" +#include "al/util/LiveActorUtil.h" +#include "al/util/ResourceUtil.h" +#include "game/Player/PlayerCostumeFunction.h" #include "game/Player/PlayerJointControlPartsDynamics.h" #include "game/Player/PlayerConst.h" +#include "rs/util/LiveActorUtil.h" + #include "PlayerCostumeInfo.h" +#include "math/seadVector.h" namespace al { class Resource; @@ -31,7 +46,33 @@ class PlayerFunction static al::Resource *initCapModelActor(al::LiveActor *, al::ActorInitInfo const &, char const *); static al::Resource *initCapModelActorDemo(al::LiveActor *, al::ActorInitInfo const &, char const *); static PlayerCostumeInfo *initMarioModelActor(al::LiveActor *player, const al::ActorInitInfo &initInfo, const char *modelName, const char *capType, al::AudioKeeper *keeper, bool isCloset); - // joint, init, pconst, nosescale, earscale - static PlayerCostumeInfo *initMarioModelActorDemo(PlayerJointControlPartsDynamics **jointCtrlPtr, al::LiveActor *player, const al::ActorInitInfo &initInfo, char const *bodyName, char const *capName, PlayerConst const *pConst,sead::Vector3f *noseScale, sead::Vector3f *earScale, bool isCloset); - static PlayerCostumeInfo *initMarioModelCommon(al::LiveActor *player, const al::ActorInitInfo &initInfo, char const *bodyName, char const *capName, int subActorNum, bool isDemo, al::AudioKeeper *audioKeeper, bool guessIsChromaKey, bool isCloset); + + static PlayerCostumeInfo* initMarioModelActorDemo(PlayerJointControlPartsDynamics** jointCtrlPtr, + al::LiveActor* player, const al::ActorInitInfo& initInfo, + char const* bodyName, char const* capName, + PlayerConst const* pConst, sead::Vector3f* noseScale, + sead::Vector3f* earScale, bool isCloset); + + static PlayerCostumeInfo* initMarioModelCommon(al::LiveActor* player, + const al::ActorInitInfo& initInfo, + char const* bodyName, char const* capName, + int subActorNum, bool isDemo, + al::AudioKeeper* audioKeeper, + bool guessIsChromaKey, bool isCloset); + // not a real symbol, func at 0x445A24 + static void initMarioAudio(al::LiveActor* player, const al::ActorInitInfo& initInfo, + al::Resource* modelRes, bool isDemo, + al::AudioKeeper* audioKeeper); + // not a real symbol, func at 0x448B8C + static void initMarioSubModel(al::LiveActor* subactor, const al::ActorInitInfo& initInfo, + bool isInvisible, bool isDemo, bool isChromaKey, + bool isCloset); + // not a real symbol, func at 0x445128 + static PlayerHeadCostumeInfo* initMarioHeadCostumeInfo(al::LiveActor* player, + const al::ActorInitInfo& initInfo, + const char*, const char*, + const char*, const char*, bool, bool, + bool, bool, bool); + // not a real symbol, func at 0x445DF4 + static void initMarioDepthModel(al::LiveActor *player, bool isDemo, bool isChromaKey); }; \ No newline at end of file diff --git a/include/game/StageScene/StageSceneLayout.h b/include/game/StageScene/StageSceneLayout.h index 9f521f2..b204168 100644 --- a/include/game/StageScene/StageSceneLayout.h +++ b/include/game/StageScene/StageSceneLayout.h @@ -44,7 +44,7 @@ class StageSceneLayout : public al::NerveStateBase { void startShineChipCompleteAnim(void); void tryStartDemoGetLifeMaxUpItem(bool); void startCloset(void); - void startShineCountAnim(bool); + void startShineCountAnim(bool isGameClear); void exeAppear(void); void exeWait(void); diff --git a/include/game/WorldList/WorldResourceLoader.h b/include/game/WorldList/WorldResourceLoader.h index 14ceaf0..3bfd208 100644 --- a/include/game/WorldList/WorldResourceLoader.h +++ b/include/game/WorldList/WorldResourceLoader.h @@ -1,7 +1,48 @@ #pragma once -class WorldResourceLoader { - public: - void loadWorldResource(int,int,bool,char const *); - bool requestLoadWorldHomeStageResource(int worldIndex, int scenario); -}; \ No newline at end of file +#include "al/async/AsyncFunctorThread.h" +#include "al/hio/HioNode.h" +#include "game/GameData/GameDataHolder.h" +#include "heap/seadHeap.h" + + +class WorldResourceLoader : public al::HioNode { +public: + WorldResourceLoader(GameDataHolder *); + virtual ~WorldResourceLoader(); + + void loadResource(void); + void cancelLoadWorldResource(void); + void tryDestroyWorldResource(void); + bool requestLoadWorldHomeStageResource(int worldIndex, int scenario); + bool isEndLoadWorldResource(void) const; // { return mResourceLoadThread->isDone(); }; + void requestLoadWorldResourceCommon(int); + void requestLoadWorldResource(int); + void createResourcePlayer(void); + void tryDestroyWorldResourceOnlyCap(void); + void calcLoadPercent(void); + void getLoadWorldId(void); + bool tryLoadResource(char const*,char const*,char const*); + void loadWorldResource(int,int,bool,char const*); + void calcWorldResourceHeapSize(void); + + al::AsyncFunctorThread* mResourceLoadThread; // 0x8 + sead::Heap* mWorldResHeap = nullptr; // 0x10 + sead::Heap* mCapHeap = nullptr; // 0x18 + sead::Heap* mWaterfallHeap = nullptr; // 0x20 + int mCurWorld = -1; // 0x28 + int mCurScenario = -1; // 0x2C + bool unkBool = true; // 0x30 + bool mIsCancelLoad = true; // 0x31 + void *unkPtr4 = nullptr; // 0x38 + void* unkPtr5 = nullptr; // 0x40 + int unkInt3 = 0; // 0x48 + bool unkBool3 = true; // 0x4C + int unkInt4 = 0; // 0x50 + int unkInt5 = 1; // 0x5C + GameDataHolder* mDataHolder; // 0x58 + bool mIsDoneLoadingArcs = false; // 0x60 + int mArcCount = 0; // 0x64 +}; + +static_assert(sizeof(WorldResourceLoader) == 0x68, "WorldResourceLoader size"); \ No newline at end of file diff --git a/include/helpers.hpp b/include/helpers.hpp index 8e3bbd4..6672774 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -14,14 +14,6 @@ #include "game/GameData/GameDataFunction.h" -#define RAD(deg) (deg * (M_PI / 180)) // converts Degrees to Radians -#define DEG(rad) (rad * (180 / M_PI)) // converts Radians to Degrees -#define BTOC(bool) (bool ? "True" : "False") // converts boolean to true/false char -#define ACNT(arr) (sizeof(arr) / sizeof(arr[0])) // returns size of inputted array -// used to convert macro values to strings -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - bool isPartOf(const char* w1, const char* w2); int indexOf(char *w1, char c1); diff --git a/include/main.hpp b/include/main.hpp index b288d12..548f2f7 100644 --- a/include/main.hpp +++ b/include/main.hpp @@ -55,12 +55,6 @@ static bool isInGame = false; static bool debugMode = false; -static bool isSmallMode = true; - -static float scale = 0.3f; - -extern float camDist; - constexpr const char* captureNames[] = { "AnagramAlphabetCharacter", "Byugo", "Bubble", "Bull", "Car", "ElectricWire", "KillerLauncherMagnum", "KuriboPossessed", diff --git a/include/rs/util.hpp b/include/rs/util.hpp index 11f6ad2..6459890 100644 --- a/include/rs/util.hpp +++ b/include/rs/util.hpp @@ -11,6 +11,10 @@ namespace rs { + bool updateNormalStateExcludeGraphics(al::Scene*); + + void updateEffectSystemEnv(al::Scene *); + bool isModeE3Rom(void); bool isModeE3LiveRom(void); diff --git a/include/rs/util/LiveActorUtil.h b/include/rs/util/LiveActorUtil.h index ab65598..a6f2c1f 100644 --- a/include/rs/util/LiveActorUtil.h +++ b/include/rs/util/LiveActorUtil.h @@ -2,8 +2,8 @@ #include "al/LiveActor/LiveActor.h" -namespace rs -{ +namespace rs { + void createPlayerSklRetargettingInfo(al::LiveActor *,sead::Vector3f const&); void initItemByPlacementInfo(al::LiveActor *, al::ActorInitInfo const &, bool); float setShadowDropLength(al::LiveActor *,al::ActorInitInfo const&,char const*); } // namespace rs diff --git a/include/sead/thread/seadMessageQueue.h b/include/sead/thread/seadMessageQueue.h index 97ac260..ffdba6d 100644 --- a/include/sead/thread/seadMessageQueue.h +++ b/include/sead/thread/seadMessageQueue.h @@ -34,6 +34,11 @@ public: Element peek(BlockType block_type) const; bool jam(Element message, BlockType block_type); + // custom funcs + inline u32 getCount() {return mMessageQueueInner.Count;} + inline u32 getMaxCount() {return mMessageQueueInner.MaxCount;} + inline bool isFull() const {return mMessageQueueInner.Count == mMessageQueueInner.MaxCount;} + static constexpr Element cNullElement = 0; private: diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 75df45f..16a2ca2 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -15,6 +15,7 @@ #include "al/async/FunctorV0M.hpp" #include "al/LiveActor/LiveActor.h" #include "al/layout/LayoutInitInfo.h" +#include "al/layout/SimpleLayoutAppearWaitEnd.h" #include "al/layout/WindowConfirmWait.h" #include "al/util.hpp" #include "al/layout/LayoutActor.h" @@ -32,8 +33,7 @@ #include "game/GameData/GameDataHolderWriter.h" #include "game/GameData/GameDataFunction.h" -#include "heap/seadFrameHeap.h" -#include "heap/seadHeap.h" +#include "heap/seadExpHeap.h" #include "layouts/HideAndSeekIcon.h" #include "rs/util.hpp" @@ -66,6 +66,7 @@ #include "puppets/PuppetInfo.h" +#include #include #define MAXPUPINDEX 32 @@ -85,12 +86,10 @@ class Client { void init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder); - bool StartThreads(); + bool startThread(); void readFunc(); - void recvFunc(); static void restartConnection(); - bool isDone() { return mReadThread->isDone(); }; static bool isSocketActive() { return sInstance ? sInstance->mSocket->isConnected() : false; }; bool isPlayerConnected(int index) { return mPuppetInfoArr[index]->isConnected; } static bool isNeedUpdateShines(); @@ -108,12 +107,16 @@ class Client { int getCollectedShinesCount() { return curCollectedShines.size(); } int getShineID(int index) { if (index < curCollectedShines.size()) { return curCollectedShines[index]; } return -1; } - static void setStageInfo(GameDataHolderAccessor holder); + static void update(); + + static void clearArrays(); static bool tryAddPuppet(PuppetActor *puppet); static bool tryAddDebugPuppet(PuppetActor* puppet); + static bool isFirstConnect() { return sInstance ? sInstance->mIsFirstConnect : false;} + static const char *getClientName() { return sInstance ? sInstance->mUsername.cstr() : "Player"; } static PuppetActor *getPuppet(int idx); @@ -126,24 +129,12 @@ class Client { static PuppetActor* getDebugPuppet(); + static sead::Heap *getClientHeap() { return sInstance ? sInstance->mHeap : nullptr; } + static int getMaxPlayerCount() { return sInstance ? sInstance->maxPuppets + 1 : 10;} - static void updateStates(); - - static void clearArrays(); - - static Keyboard* getKeyboard(); - - static const char* getCurrentIP(); - - static void setLastUsedIP(const char* ip); - static const int getCurrentPort(); - static void setLastUsedPort(const int port); - - static void setTagState(bool state); - static int getConnectCount() { if (sInstance) return sInstance->mConnectCount; @@ -156,6 +147,22 @@ class Client { return nullptr; } + static Keyboard* getKeyboard(); + + static const char* getCurrentIP(); + + static nn::account::Uid getClientId() { return sInstance ? sInstance->mUserID : nn::account::Uid::EmptyId;} + + static sead::FixedSafeString<0x20> getUsername() { return sInstance ? sInstance->mUsername : sead::FixedSafeString<0x20>::cEmptyString;} + + static void setStageInfo(GameDataHolderAccessor holder); + + static void setLastUsedIP(const char* ip); + + static void setLastUsedPort(const int port); + + static void setTagState(bool state); + static void setSceneInfo(const al::ActorInitInfo& initInfo, const StageScene *stageScene); static bool tryRegisterShine(Shine* shine); @@ -198,9 +205,7 @@ class Client { // --- General Server Members --- - // currently, only readThread is used to recieve and update PuppetInfo, while the main game thread is used to send packets without queueing them up first, which might cause performance issues - al::AsyncFunctorThread *mReadThread = nullptr; // TODO: use this thread to send any queued packets - // al::AsyncFunctorThread *mRecvThread; // TODO: use this thread to recieve packets and update PuppetInfo + al::AsyncFunctorThread *mReadThread = nullptr; // processes data queued in the SocketClient's RecvQueue int mConnectCount = 0; @@ -230,12 +235,14 @@ class Client { int mServerPort = 0; bool waitForGameInit = true; - bool isFirstConnect = true; + bool mIsFirstConnect = true; // --- Game Layouts --- al::WindowConfirmWait* mConnectionWait; + al::SimpleLayoutAppearWaitEnd *mConnectStatus; + // --- Game Info --- bool isClientCaptured = false; @@ -257,7 +264,7 @@ class Client { u8 mScenario = 0; - sead::FrameHeap *mHeap = nullptr; // Custom FrameHeap used for all Client related memory + sead::ExpHeap *mHeap = nullptr; // Custom FrameHeap used for all Client related memory // --- Puppet Info --- diff --git a/include/server/SocketClient.hpp b/include/server/SocketClient.hpp index 42dad30..2f6dd74 100644 --- a/include/server/SocketClient.hpp +++ b/include/server/SocketClient.hpp @@ -1,6 +1,8 @@ #pragma once #include "SocketBase.hpp" +#include "al/async/AsyncFunctorThread.h" +#include "heap/seadHeap.h" #include "nn/result.h" #include "sead/math/seadVector.h" #include "sead/math/seadQuat.h" @@ -12,27 +14,55 @@ #include "syssocket/sockdefines.h" +#include "thread/seadMessageQueue.h" +#include "thread/seadMutex.h" #include "types.h" #include "packets/Packet.h" class SocketClient : public SocketBase { public: - SocketClient(const char *name) : SocketBase(name) { - mPacketQueue = sead::PtrArray(); - mPacketQueue.tryAllocBuffer(maxBufSize, nullptr); - }; + SocketClient(const char *name, sead::Heap *heap); nn::Result init(const char* ip, u16 port) override; + bool tryReconnect(); bool closeSocket() override; - bool SEND(Packet *packet); - bool RECV(); - void printPacket(Packet* packet); - bool isConnected() {return socket_log_state == SOCKET_LOG_CONNECTED; } - sead::PtrArray mPacketQueue; + bool startThreads(); + void endThreads(); + + bool send(Packet* packet); + bool recv(); + + bool queuePacket(Packet *packet); + void trySendQueue(); + + void sendFunc(); + void recvFunc(); + + Packet *tryGetPacket(sead::MessageQueue::BlockType blockType = sead::MessageQueue::BlockType::Blocking); + + void printPacket(Packet* packet); + bool isConnected() { return socket_log_state == SOCKET_LOG_CONNECTED; } + + u32 getSendCount() { return mSendQueue.getCount(); } + u32 getSendMaxCount() { return mSendQueue.getMaxCount(); } + + u32 getRecvCount() { return mRecvQueue.getCount(); } + u32 getRecvMaxCount() { return mRecvQueue.getMaxCount(); } + + void setIsFirstConn(bool value) { mIsFirstConnect = value; } private: + sead::Heap* mHeap = nullptr; + + al::AsyncFunctorThread* mRecvThread = nullptr; + al::AsyncFunctorThread* mSendThread = nullptr; + + sead::MessageQueue mRecvQueue; + sead::MessageQueue mSendQueue; + int maxBufSize = 100; + bool mIsFirstConnect = true; /** * @param str a string containing an IPv4 address or a hostname that can be resolved via DNS @@ -41,3 +71,5 @@ class SocketClient : public SocketBase { */ bool stringToIPAddress(const char* str, in_addr* out); }; + +typedef void (SocketClient::*SocketThreadFunc)(void); \ No newline at end of file diff --git a/include/server/gamemode/GameModeManager.hpp b/include/server/gamemode/GameModeManager.hpp index 3b881ac..8815b25 100644 --- a/include/server/gamemode/GameModeManager.hpp +++ b/include/server/gamemode/GameModeManager.hpp @@ -3,8 +3,10 @@ #include #include #include +#include "al/util.hpp" #include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeInfoBase.hpp" +#include "server/gamemode/modifiers/ModeModifierBase.hpp" class GameModeManager { SEAD_SINGLETON_DISPOSER(GameModeManager) @@ -29,6 +31,7 @@ public: T* createModeInfo(); sead::Heap* getHeap() { return mHeap; } + static sead::Heap* getSceneHeap() { return al::getSceneHeap(); } void toggleActive(); void setActive(bool active) { mActive = active; } void setPaused(bool paused); @@ -47,6 +50,7 @@ private: GameModeBase* mCurModeBase = nullptr; GameModeInfoBase *mModeInfo = nullptr; GameModeInitInfo *mLastInitInfo = nullptr; + ModeModifierBase *mCurModifier = nullptr; }; template diff --git a/include/server/gamemode/modifiers/GravityModifier.hpp b/include/server/gamemode/modifiers/GravityModifier.hpp new file mode 100644 index 0000000..6ba56ca --- /dev/null +++ b/include/server/gamemode/modifiers/GravityModifier.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "ModeModifierBase.hpp" +#include "game/StageScene/StageScene.h" + +class GravityModifier : public ModeModifierBase { +public: + GravityModifier(GameModeBase* modeInfo); + + void enable() override; + void disable() override; + void update() override; + + void setCamTicket(al::CameraTicket *ticket) {mTicket = ticket;}; + +private: + al::CameraTicket *mTicket = nullptr; +}; \ No newline at end of file diff --git a/include/server/gamemode/modifiers/ModeModifierBase.hpp b/include/server/gamemode/modifiers/ModeModifierBase.hpp new file mode 100644 index 0000000..34c7423 --- /dev/null +++ b/include/server/gamemode/modifiers/ModeModifierBase.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include "game/StageScene/StageScene.h" + +class GameModeBase; + +class ModeModifierBase { +public: + ModeModifierBase(GameModeBase* mode) : mMode(mode) {} + + bool isActive() const { return mIsEnabled; } + + virtual void init(StageScene *scene) { mScene = scene; } + + virtual void enable() { mIsEnabled = true; } + virtual void disable() { mIsEnabled = false; } + virtual void update() {} + +protected: + GameModeBase* mMode = nullptr; + StageScene *mScene = nullptr; + bool mIsEnabled = false; +}; \ No newline at end of file diff --git a/include/server/gamemode/modifiers/ModifierFactory.hpp b/include/server/gamemode/modifiers/ModifierFactory.hpp new file mode 100644 index 0000000..f36d6a5 --- /dev/null +++ b/include/server/gamemode/modifiers/ModifierFactory.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "al/factory/Factory.h" +#include "server/gamemode/GameModeBase.hpp" +#include "server/gamemode/modifiers/GravityModifier.hpp" +#include "server/gamemode/modifiers/ModeModifierBase.hpp" +#include "server/gamemode/modifiers/NoCapModifier.hpp" + +typedef ModeModifierBase* (*createMod)(GameModeBase* mode); + +template +ModeModifierBase* createModifier(GameModeBase* mode) +{ + return new T(mode); +}; + +__attribute((used)) constexpr al::NameToCreator modifierTable[] = { + {"Gravity", &createModifier}, + {"NoCap", &createModifier} +}; + +constexpr const char* modifierNames[] = { + "Sticky Gravity", + "Cappy-Less" +}; + +class ModifierFactory : public al::Factory { + public: + ModifierFactory(const char *fName) { + this->factoryName = fName; + this->actorTable = modifierTable; + this->factoryCount = sizeof(modifierTable)/sizeof(modifierTable[0]); + }; +}; \ No newline at end of file diff --git a/include/server/gamemode/modifiers/NoCapModifier.hpp b/include/server/gamemode/modifiers/NoCapModifier.hpp new file mode 100644 index 0000000..859a532 --- /dev/null +++ b/include/server/gamemode/modifiers/NoCapModifier.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "server/gamemode/modifiers/ModeModifierBase.hpp" + +class NoCapModifier : public ModeModifierBase { +public: + NoCapModifier(GameModeBase* modeInfo); + + void enable() override; + void disable() override; +}; \ No newline at end of file diff --git a/include/types.h b/include/types.h index e571b4d..0cc0d83 100644 --- a/include/types.h +++ b/include/types.h @@ -61,6 +61,14 @@ typedef __builtin_va_list va_list; #define va_start(v,l) __builtin_va_start(v,l) #define va_end(v) __builtin_va_end(v) +#define RAD(deg) (deg * (M_PI / 180)) // converts Degrees to Radians +#define DEG(rad) (rad * (180 / M_PI)) // converts Radians to Degrees +#define BTOC(bool) (bool ? "True" : "False") // converts boolean to true/false char +#define ACNT(arr) (sizeof(arr) / sizeof(arr[0])) // returns size of inputted array +// used to convert macro values to strings +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + //using u64 = std::uint64_t; //using s64 = std::int64_t; diff --git a/linkerscripts/syms100.ld b/linkerscripts/syms100.ld index d267ff1..5a55df7 100644 --- a/linkerscripts/syms100.ld +++ b/linkerscripts/syms100.ld @@ -1 +1,8 @@ -_ZN14PlayerFunction20initMarioModelCommonEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_ibPNS0_11AudioKeeperEbb = 0x444028 - 0x2C63000; \ No newline at end of file +_ZN14PlayerFunction20initMarioModelCommonEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_ibPNS0_11AudioKeeperEbb = 0x444028 - 0x2C63000; +_ZN14PlayerFunction14initMarioAudioEPN2al9LiveActorERKNS0_13ActorInitInfoEPNS0_8ResourceEbPNS0_11AudioKeeperE = 0x445A24 - 0x2C63000; +_ZN14PlayerFunction17initMarioSubModelEPN2al9LiveActorERKNS0_13ActorInitInfoEbbbb = 0x448B8C - 0x2C63000; +_ZN14PlayerFunction24initMarioHeadCostumeInfoEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_S7_S7_bbbbb = 0x445128 - 0x2C63000; +_ZN14PlayerFunction19initMarioDepthModelEPN2al9LiveActorEbb = 0x445DF4 - 0x2C63000; + +gameDrawTable = 0x1DDFB38 - 0x2C63000; +gameUpdateTable = 0x1DDFAD8 - 0x2C63000; \ No newline at end of file diff --git a/patches/codehook.slpatch b/patches/codehook.slpatch index 992672f..bd23a58 100644 --- a/patches/codehook.slpatch +++ b/patches/codehook.slpatch @@ -90,6 +90,13 @@ B59E28 B seadPrintHook // sead::system::print 20CA78 BL startCounterHook // starts coin counter if a gamemode is not active 20CAA8 BL startCounterHook // starts purple coin counter if gamemode is not active +// Other HUD Changes + +20CB4C BL modeE3Hook // PlayGuideMenuLyt at StageSceneStateLayout::start+140 +20CA5C BL modeE3Hook // MapMini::appearSlideIn at StageSceneStateLayout::start+50 +20D160 BL modeE3Hook // MapMini::end at StageSceneStateLayout::exeEnd+8C +20D154 BL playGuideEndHook + // Pause Menu Changes 4EAEC4 B overrideNerveHook // makes any button on pause menu run a specific nerve @@ -112,4 +119,9 @@ B59E28 B seadPrintHook // sead::system::print 5C00B0 BL borderPullBackHook // hooks over isFirstStep in WorldEndBorderKeeper::exePullBack so we can kill the player if they reach the border of the map -// 4E46BC NOP // removes call to setEnableData for one of the commonverticallists in the options menu, which makes all entries in the menu look the same \ No newline at end of file +// 4E46BC NOP // removes call to setEnableData for one of the commonverticallists in the options menu, which makes all entries in the menu look the same + +8912B8 B drawTableHook + +// 891394 BL drawInitHook +// 91328 BL updateInitHook \ No newline at end of file diff --git a/patches/tests.slpatch b/patches/tests.slpatch index 0ebc94a..84022d5 100644 --- a/patches/tests.slpatch +++ b/patches/tests.slpatch @@ -45,7 +45,7 @@ //4EAE58: // forces StageSceneStatePauseMenu to immediately select continue // MOV X0, #1 -20CB4C BL modeE3Hook // PlayGuideMenuLyt at StageSceneStateLayout::start+140 -20CA5C BL modeE3Hook // MapMini::appearSlideIn at StageSceneStateLayout::start+50 -20D160 BL modeE3Hook // MapMini::end at StageSceneStateLayout::exeEnd+8C -20D154 BL playGuideEndHook \ No newline at end of file +// very wip stuff for implementing custom executors +// 4D1814 BL updateStateHook + +// 87C90C BL updateDrawHook \ No newline at end of file diff --git a/source/al/execute/ExecuteTables.cpp b/source/al/execute/ExecuteTables.cpp new file mode 100644 index 0000000..94cb425 --- /dev/null +++ b/source/al/execute/ExecuteTables.cpp @@ -0,0 +1,480 @@ +#include +#include "al/execute/ExecuteOrder.h" +#include "al/execute/ExecuteTable.h" + +#include "al/execute/ExecuteTableHolderDraw.h" +#include "al/execute/ExecuteTableHolderUpdate.h" + +static constexpr al::ExecuteOrder drawTableArr[] = { + // 3D(カリング) + {"カリング", "ActorModelDrawCulling", 512, "システム"}, + // 3D(デプスシャドウ) + {"デプスシャドウ[キャラクター]", "ActorModelDrawDepthShadow", 192, "影"}, + {"デプスシャドウ[地形]", "ActorModelDrawDepthShadow", 192, "影"}, + {"デプスシャドウ[マーチングキューブ]", "ActorModelDrawDepthShadowMarchingCube", 16, "影"}, + {"デプスシャドウ[独自]", "Functor", 16, "影"}, + // 3D(デプスシャドウプレイヤー) + {"デプスシャドウ[プレイヤー]", "ActorModelDrawDepthShadow", 128, "影"}, + {"Mii[顔モデル](デプスシャドウ)", "Draw", 8, "影"}, + // 3D(スタティックデプスシャドウ) + {"スタティックデプスシャドウ[地形]", "ActorModelDrawStaticDepthShadow", 128, "影"}, + // 3D(ワールドAo) + {"ワールドAo[地形]", "ActorModelDrawWorldAo", 192, "影"}, + // 3D(海用デプス) + {"海用デプス[浜辺]", "ActorModelDrawWorldAo", 8, "影"}, + {"海用デプス[高さ]", "ActorModelDrawWorldAo", 8, "影"}, + // 3D(空) + {"空", "ActorModelDraw", 8, "地形"}, + // 3D(不透明Zプリパス) + {"Zプリパス[カリング]", "ActorModelDrawDepthOnly", 512, "地形"}, + {"Zプリパス[キャラクター]", "ActorModelDrawDepthOnly", 128, "敵"}, + {"Zプリパス[地形]", "ActorModelDrawDepthOnly", 128, "地形"}, + {"Zプリパス[遠景]", "ActorModelDrawDepthOnly", 128, "地形"}, + {"Zプリパス[ディザ]", "ActorModelDrawDepthDither", 196, "敵"}, + {"プレイヤー", "ActorModelDrawDepthDither", 196, "プレイヤー"}, + // 3D(ディファード地形) + {"地形オブジェ[地形前]", "ActorModelDrawDeferred", 128, "地形オブジェ"}, + {"地形オブジェ[地形前ディファードのみ]", "ActorModelDrawDeferredOnly", 32, "地形オブジェ"}, + {"地形オブジェ[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "地形オブジェ"}, + {"敵[地形前]", "ActorModelDrawDeferred", 16, "敵"}, + {"敵[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "敵"}, + {"NPC[地形前]", "ActorModelDrawDeferred", 16, "NPC"}, + {"NPC[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "NPC"}, + {"プレイヤー[地形前]", "ActorModelDrawDeferred", 16, "プレイヤー"}, + {"地形[浮遊]", "ActorModelDrawDeferred", 32, "地形"}, + {"地形", "ActorModelDrawDeferred", 256, "地形"}, + {"地形[ディファード]", "ActorModelDrawDeferredOnly", 32, "地形"}, + {"地形[ディファードのみ]", "ActorModelDrawDeferredOnly", 32, "地形"}, + {"地形[ディファード不透明]", "ActorModelDrawDeferredOpa", 16, "地形"}, + {"地形[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 64, "地形"}, + {"地形[埋没]", "ActorModelDrawDeferred", 32, "地形"}, + // 3D(ディファード鏡映り込みなし) + {"地形[鏡映り込みなし]", "ActorModelDrawDeferred", 32, "地形"}, + // 3D(ディファードキャラクター) + {"シャドウマスク[地形オブジェ]", "Draw", 3, "影"}, + {"足跡", "ActorModelDrawDeferredFootPrint", 4, "プレイヤー"}, + {"地形オブジェ", "ActorModelDrawDeferred", 128, "地形オブジェ"}, + {"地形オブジェ[ディファードのみ]", "ActorModelDrawDeferredOnly", 16, "地形オブジェ"}, + {"地形オブジェ[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "地形オブジェ"}, + {"地形オブジェ[マーチングキューブ]", "ActorModelDrawDeferredMarchingCube", 32, "地形オブジェ"}, + {"地形[地形オブジェ後]", "ActorModelDrawDeferred", 32, "地形"}, + {"敵[シルエット前]", "ActorModelDrawDeferred", 128, "敵"}, + {"アクター描画[シルエット前]", "ActorDraw", 8, "アクター"}, + {"シルエット[プレイヤー]", "ActorModelDrawDeferredSilhouette", 196, "プレイヤー"}, + {"シルエット[オブジェ]", "ActorModelDrawDeferredSilhouette", 64, "地形オブジェ"}, + {"シルエットモデル[敵]", "ActorModelDrawDeferred", 64, "敵"}, + {"地形[シルエット後]", "ActorModelDrawDeferred", 32, "地形"}, + {"地形オブジェ[シルエット後]", "ActorModelDrawDeferred", 32, "地形オブジェ"}, + {"シャドウマスク[敵]", "Draw", 3, "影"}, + {"敵", "ActorModelDrawDeferred", 128, "敵"}, + {"敵[ディファードのみ]", "ActorModelDrawDeferredOnly", 16, "敵"}, + {"敵[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "敵"}, + {"NPC", "ActorModelDrawDeferred", 96, "NPC"}, + {"NPC[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "NPC"}, + {"NPC[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, "NPC"}, + {"Mii[顔モデル]", "Draw", 4, "システム"}, + {"シャドウマスク[アイテム]", "Draw", 3, "影"}, + {"アイテム", "ActorModelDrawDeferred", 64, "アイテム"}, + {"アイテム[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "アイテム"}, + {"アイテム[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, "アイテム"}, + // 3D(ディファード異空間) + {"異空間オブジェ", "ActorModelDrawDeferred", 64, "地形オブジェ"}, + // 3D(ディファードプレイヤー) + {"シャドウマスク[プレイヤー]", "Draw", 4, "影"}, + {"プレイヤー", "ActorModelDrawDeferred", 196, "プレイヤー"}, + {"プレイヤー装飾", "ActorModelDrawDeferred", 32, "プレイヤー"}, + {"プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, "プレイヤー"}, + // 3D(ディファード中景) + {"地形オブジェ[キャラ後]", "ActorModelDrawDeferred", 32, "地形オブジェ"}, + {"シャドウマスク[ブロック]", "Draw", 3, "影"}, + {"中景", "ActorModelDrawDeferred", 8, "地形"}, + {"中景[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "地形"}, + {"中景[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, "地形"}, + {"大気散乱", "Draw", 1, "地形"}, + {"ディファード空", "ActorModelDrawDeferredSky", 16, "地形"}, + {"ディファード空[デモ]", "ActorModelDrawDeferredSky", 8, "地形"}, + // 3D(ディファード半透明) + {"地形[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "地形"}, + {"地形[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "地形"}, + {"地形オブジェ[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "地形オブジェ"}, + {"地形オブジェ[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "地形オブジェ"}, + {"敵[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "敵"}, + {"敵[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "敵"}, + {"NPC[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "NPC"}, + {"NPC[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "NPC"}, + {"アイテム[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "アイテム"}, + {"アイテム[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, "アイテム"}, + {"プレイヤー装飾[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, "プレイヤー"}, + {"プレイヤー装飾[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 16, "プレイヤー"}, + {"シャドウマスク[モデルライト後]", "Draw", 4, "影"}, + {"アクター描画", "ActorDraw", 8, "アクター"}, + // 3D(デプスクリアプレイヤー) + {"プレイヤー", "ActorModelDrawDepthForce", 196, "プレイヤー"}, + {"プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"}, + {"プレイヤー装飾[ディファード半透明のみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"}, + {"プレイヤー装飾[フォワードのみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"}, + {"プレイヤー装飾[インダイレクトのみ]", "ActorModelDrawDepthForce", 16, "プレイヤー"}, + // 3D(フォワード遠景) + {"遠景[ライトバッファ]", "ActorModelDraw", 8, "地形"}, + {"遠景[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"大気散乱雲遠距離[ライトバッファ]", "ActorModelDraw", 8, "地形"}, + {"大気散乱雲遠距離[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"大気散乱雲[ライトバッファ]", "ActorModelDraw", 8, "地形"}, + {"大気散乱雲[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"大気散乱雲近距離[ライトバッファ]", "ActorModelDraw", 8, "地形"}, + {"大気散乱雲近距離[ライトバッファのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + // 3D(フォワードプレイヤー) + {"Zプリパス[プレイヤー]", "ActorModelDrawDepthOnly", 32, "プレイヤー"}, + {"プレイヤー[地形前]", "ActorModelDrawForwardForce", 16, "プレイヤー"}, + {"プレイヤー", "ActorModelDrawForwardForce", 196, "プレイヤー"}, + {"Zプリパス[プレイヤー装飾]", "ActorModelDrawDepthDither", 128, "プレイヤー"}, + {"プレイヤー装飾", "ActorModelDrawForwardForce", 32, "プレイヤー"}, + {"プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawForwardForce", 16, "プレイヤー"}, + // 3D(フォワード) + {"半透明Zプリパス", "ActorModelDrawDepthXlu", 8, "地形"}, + {"フォワードZプリパス[ディザ]", "ActorModelDrawDepthDither", 8, "地形"}, + {"中景[フォワード]", "ActorModelDraw", 8, "地形"}, + {"中景[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"大気散乱雲[フォワード]", "ActorModelDraw", 8, "地形"}, + {"大気散乱雲[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"地形[フォワード]", "ActorModelDraw", 32, "地形"}, + {"地形[フォワードのみ]", "ActorModelDrawForwardOnly", 48, "地形"}, + {"地形オブジェ[フォワード]", "ActorModelDraw", 32, "地形オブジェ"}, + {"地形オブジェ[フォワードのみ]", "ActorModelDrawForwardOnly", 32, "地形オブジェ"}, + {"敵[フォワード]", "ActorModelDraw", 32, "敵"}, + {"敵[フォワードのみ]", "ActorModelDrawForwardOnly", 16, "敵"}, + {"NPC[フォワード]", "ActorModelDraw", 32, "NPC"}, + {"NPC[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "NPC"}, + {"アイテム[フォワード]", "ActorModelDraw", 32, "アイテム"}, + {"アイテム[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "アイテム"}, + {"プレイヤー[フォワード]", "ActorModelDraw", 8, "プレイヤー"}, + {"プレイヤー装飾[フォワード]", "ActorModelDraw", 8, "プレイヤー"}, + {"プレイヤー装飾[フォワードのみ]", "ActorModelDrawForwardOnly", 16, "プレイヤー"}, + {"アクター描画[フォワード]", "ActorDraw", 8, "アクター"}, + // 3D(インダイレクト) + {"半透明Zプリパス[インダイレクト]", "ActorModelDrawDepthIndirect", 8, "地形"}, + {"インダイレクトZプリパス[ディザ]", "ActorModelDrawDepthDitherIndirect", 8, "地形"}, + {"地形[インダイレクト]", "ActorModelDrawIndirect", 32, "地形"}, + {"地形[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 16, "地形"}, + {"地形オブジェ[インダイレクト]", "ActorModelDrawIndirect", 32, "地形オブジェ"}, + {"地形オブジェ[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 32, "地形オブジェ"}, + {"コイン[インダイレクト]", "ActorModelDrawIndirect", 8, "アイテム"}, + {"ルート土管内側[インダイレクト]", "ActorModelDrawIndirect", 32, "地形オブジェ"}, + {"ルート土管外側[インダイレクト]", "ActorModelDrawIndirect", 32, "地形オブジェ"}, + {"敵[インダイレクト]", "ActorModelDrawIndirect", 32, "敵"}, + {"敵[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, "敵"}, + {"NPC[インダイレクト]", "ActorModelDrawIndirect", 32, "NPC"}, + {"NPC[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, "NPC"}, + {"アイテム[インダイレクト]", "ActorModelDrawIndirect", 32, "アイテム"}, + {"アイテム[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 32, "アイテム"}, + {"プレイヤー装飾[インダイレクト]", "ActorModelDrawIndirect", 8, "プレイヤー"}, + {"プレイヤー装飾[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, "プレイヤー"}, + {"アクター描画[インダイレクト]", "ActorDraw", 8, "アクター"}, + // 3D(インダイレクト後フォワード) + {"半透明Zプリパス[インダイレクト後]", "ActorModelDrawDepthIndirect", 8, "地形"}, + {"地形オブジェ[フォワードインダイレクト後のみ]", "ActorModelDrawForwardOnly", 8, + "地形オブジェ"}, + {"敵[フォワードインダイレクト後]", "ActorModelDraw", 32, "敵"}, + // 3D(インダイレクト後遠景) + {"大気散乱雲[インダイレクト後]", "ActorModelDraw", 8, "地形"}, + {"大気散乱雲[インダイレクト後のみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + // 3D(フォグ後インダイレクト) + {"地形[インダイレクトフォグ後]", "ActorModelDrawIndirect", 8, "地形"}, + {"地形[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly", 8, "地形"}, + {"敵[インダイレクトフォグ後]", "ActorModelDrawIndirect", 8, "敵"}, + {"敵[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly", 8, "敵"}, + {"アイテム[インダイレクトフォグ後]", "ActorModelDrawIndirect", 32, "アイテム"}, + {"アイテム[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly", 32, "アイテム"}, + // 3D(フォグ後遠景) + {"遠景[フォグ後]", "ActorModelDraw", 8, "地形"}, + {"遠景[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"大気散乱雲[フォグ後]", "ActorModelDraw", 8, "地形"}, + {"大気散乱雲[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + // 3D(フォグ後) + {"半透明Zプリパス[フォグ後]", "ActorModelDrawDepthXlu", 8, "地形"}, + {"地形[フォグ後]", "ActorModelDraw", 8, "地形"}, + {"地形[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"地形オブジェ[フォグ後]", "ActorModelDraw", 8, "地形オブジェ"}, + {"地形オブジェ[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "地形オブジェ"}, + {"敵[フォグ後]", "ActorModelDraw", 8, "敵"}, + {"敵[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "敵"}, + {"NPC[フォグ後]", "ActorModelDraw", 8, "NPC"}, + {"NPC[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, "NPC"}, + // 3D(クロマキーZプリパス) + {"Zプリパス[プレイヤークロマキー]", "ActorModelDrawDepthChromakey", 208, "プレイヤー"}, + {"Zプリパス[NPCクロマキー]", "ActorModelDrawDepthChromakey", 32, "NPC"}, + {"Zプリパス[ディザクロマキー]", "ActorModelDrawDitherChromakey", 208, "プレイヤー"}, + // 3D(クロマキープレイヤー) + {"プレイヤー[クロマキー]", "ActorModelDrawPlayerChromakey", 208, "プレイヤー"}, + {"プレイヤー[クロマキー不透明]", "ActorModelDrawPlayerChromakeyOpa", 208, "プレイヤー"}, + {"プレイヤー[クロマキー半透明]", "ActorModelDrawPlayerChromakeyXlu", 64, "プレイヤー"}, + // 3D(クロマキーキャラクター) + {"NPC[クロマキー]", "ActorModelDrawCharacterChromakey", 32, "NPC"}, + // 2Dバック(メイン画面) + {"2Dバック", "LayoutDraw", 64, "レイアウト"}, + // 2Dベース(メイン画面) + {"2Dベース", "LayoutDraw", 32, "レイアウト"}, + {"2D情報バルーン", "LayoutDraw", 64, "レイアウト"}, + {"2D会話バルーン", "LayoutDraw", 128, "レイアウト"}, + {"2D", "LayoutDraw", 256, "レイアウト"}, + {"2Dフィルターバルーン", "LayoutDraw", 64, "レイアウト"}, + {"2Dフィルター", "LayoutDraw", 32, "レイアウト"}, + {"2D(メイン画面のみ)", "LayoutDraw", 32, "レイアウト"}, + {"2Dガイド", "LayoutDraw", 64, "レイアウト"}, + {"2Dカウンター", "LayoutDraw", 32, "レイアウト"}, + {"2Dマップアイコン", "LayoutDraw", 32, "レイアウト"}, + {"2D通知", "LayoutDraw", 8, "レイアウト"}, + // 2Dエフェクト(メイン画面) + {"2Dベースエフェクト", "Draw", 1, "エフェクト"}, + // 2Dオーバー(メイン画面) + {"2Dヘッド", "LayoutDraw", 16, "レイアウト"}, + {"2Dポーズ", "LayoutDraw", 32, "レイアウト"}, + {"2Dランキング", "LayoutDraw", 4, "レイアウト"}, + {"2Dライン", "LayoutDraw", 8, "レイアウト"}, + {"2Dアイコン[最低]", "LayoutDraw", 32, "レイアウト"}, + {"2Dアイコン[低]", "LayoutDraw", 32, "レイアウト"}, + {"2Dアイコン[中]", "LayoutDraw", 16, "レイアウト"}, + {"2Dアイコン[高]", "LayoutDraw", 356, "レイアウト"}, + {"2Dアイコン[最高]", "LayoutDraw", 16, "レイアウト"}, + {"2Dカーソル", "LayoutDraw", 12, "レイアウト"}, + {"2Dリスト", "LayoutDraw", 12, "レイアウト"}, + {"2Dリストアイコン", "LayoutDraw", 256, "レイアウト"}, + {"2Dリストカーソル", "LayoutDraw", 8, "レイアウト"}, + {"2Dゲームオーバー", "LayoutDraw", 8, "レイアウト"}, + {"2Dカバー", "LayoutDraw", 8, "レイアウト"}, + {"2Dエフェクト", "Draw", 1, "エフェクト"}, + {"2Dワイプ[ウィンドウ前]", "LayoutDraw", 4, "レイアウト"}, + {"2Dウィンドウ", "LayoutDraw", 24, "レイアウト"}, + {"2Dウィンドウカウンター", "LayoutDraw", 8, "レイアウト"}, + {"2Dワイプ", "LayoutDraw", 48, "レイアウト"}, + {"2Dリザルト", "LayoutDraw", 4, "レイアウト"}, + // 2D(デモ画面) + {"2Dデモベース", "LayoutDraw", 16, "レイアウト"}, + {"2Dデモ", "LayoutDraw", 96, "レイアウト"}, + {"2Dデモ情報バルーン", "LayoutDraw", 16, "レイアウト"}, + {"2Dデモライン", "LayoutDraw", 8, "レイアウト"}, + {"2Dデモアイコン", "LayoutDraw", 196, "レイアウト"}, + {"2Dデモアイコンオーバー", "LayoutDraw", 128, "レイアウト"}, + {"2Dデモアイコンプレイヤー", "LayoutDraw", 4, "レイアウト"}, + {"2Dデモカーソル", "LayoutDraw", 8, "レイアウト"}, + // ポストエフェクトマスク + {"ポストエフェクトマスク", "ActorModelDrawPostEffectMask", 32, "地形"}, + // アクター描画(独自レンダーターゲット) + {"アクター描画[独自レンダーターゲット]", "ActorDraw", 8, "アクター"}, + // アクター描画(プロジェクト固有) + {"アクター描画(プロジェクト固有)", "ActorDraw", 8, "アクター"}, + // モデル描画バッファ更新 + {"モデル描画バッファ更新", "ActorModelDrawUpdate", 1024, "システム"}, + // 3D(ワールドマップディファード) + {"ワールドマップ地形", "ActorModelDrawDeferred", 128, "地形"}, + {"ワールドマップ地形[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, "地形"}, + {"ワールドマップディファード空", "ActorModelDrawDeferredSky", 8, "地形"}, + {"ワールドマップ地形[ディファード半透明]", "ActorModelDrawDeferredXlu", 16, "地形"}, + // 3D(ワールドマップフォワード) + {"ワールドマップ地形[フォワード]", "ActorModelDraw", 32, "地形"}, + {"ワールドマップ地形[フォワードのみ]", "ActorModelDrawForwardOnly", 8, "地形"}, + {"ワールドマップ地形オブジェ[フォワード]", "ActorModelDraw", 8, "地形オブジェ"}, + // 2D(ワールドマップ画面) + {"2Dワールドマップベース", "LayoutDraw", 32, "レイアウト"}, + {"2Dワールドマップ", "LayoutDraw", 32, "レイアウト"}, + // 2D(ムーンゲット画面) + {"2D(ムーンゲット)", "LayoutDraw", 8, "レイアウト"}, + {"2Dカウンター(ムーンゲット)", "LayoutDraw", 1, "レイアウト"}, + {"2Dワイプ(ムーンゲット)", "LayoutDraw", 4, "レイアウト"}, + // 2D(スナップショット) + {"2Dスナップショット", "LayoutDraw", 3, "レイアウト"}, + // 2D(撮影用) + {"2D撮影用", "LayoutDraw", 16, "レイアウト"}, + // 2D(ミス) + {"2Dミス", "LayoutDraw", 2, "レイアウト"}, + // Custom Entries + {"PuppetActor", "ActorModelDrawDeferred", 512, "ボス"} +}; + +static constexpr al::ExecuteOrder updateTableArr[] = { + // Update Table Name: 更新 + {"ステージ同期カウンタ", "Execute", 1, "システム"}, + {"乗り物(カメラ前)[Movement]", "ActorMovement", 8, "乗り物"}, + {"カメラ前プレイヤー[Movement]", "ActorMovement", 16, "プレイヤー"}, + {"カメラ前プレイヤー", "ActorMovementCalcAnim", 16, "プレイヤー"}, + {"カメラ", "Execute", 1, "カメラ"}, + {"クリッピング", "Execute", 1, "システム"}, + {"センサー", "Execute", 1, "システム"}, + {"試作用処理1", "Execute", 2, "システム"}, + {"試作用処理2", "Execute", 8, "システム"}, + {"試作用処理3", "Execute", 2, "システム"}, + {"試作用処理4", "Execute", 1, "システム"}, + {"空", "ActorMovementCalcAnim", 16, "地形"}, + {"波", "ActorMovement", 16, "地形"}, + {"遠景", "ActorMovementCalcAnim", 8, "地形"}, + {"コリジョン地形", "ActorMovementCalcAnim", 256, "地形"}, + {"コリジョン地形[デモ]", "ActorMovementCalcAnim", 64, "地形"}, + {"コリジョン地形[Movement]", "ActorMovement", 32, "地形"}, + {"コリジョン地形装飾", "ActorMovementCalcAnim", 32, "地形"}, + {"コリジョン地形装飾[Movement]", "ActorMovement", 32, "地形"}, + {"コリジョン地形オブジェ", "ActorMovementCalcAnim", 64, "地形オブジェ"}, + {"コリジョン地形オブジェ[Movement]", "ActorMovement", 32, "地形オブジェ"}, + {"コリジョンディレクター", "Execute", 1, "システム"}, + {"地形オブジェ", "ActorMovementCalcAnim", 128, "地形オブジェ"}, + {"地形オブジェ[Movement]", "ActorMovement", 32, "地形オブジェ"}, + {"地形オブジェ装飾", "ActorMovementCalcAnim", 32, "地形オブジェ"}, + {"乗り物", "ActorMovementCalcAnim", 32, "乗り物"}, + {"エフェクトオブジェ", "ActorMovement", 32, "エフェクト"}, + {"デモプレイヤーロケーター", "ActorMovementCalcAnim", 4, "プレイヤー"}, + {"デモプレイヤー前処理", "ActorMovement", 16, "プレイヤー"}, + {"プレイヤー前処理", "Functor", 1, "プレイヤー"}, + {"プレイヤー[Movement]", "ActorMovement", 16, "プレイヤー"}, + {"プレイヤー", "ActorMovementCalcAnim", 128, "プレイヤー"}, + {"プレイヤー後処理", "Functor", 1, "プレイヤー"}, + {"プレイヤー装飾", "ActorMovementCalcAnim", 64, "プレイヤー"}, + {"プレイヤー装飾2", "ActorMovementCalcAnim", 64, "プレイヤー"}, + {"帽子(武器)", "ActorMovementCalcAnim", 1, "アイテム"}, + {"帽子(表示)", "ActorMovementCalcAnim", 16, "アイテム"}, + {"敵", "ActorMovementCalcAnim", 128, "敵"}, + {"敵[Movement]", "ActorMovement", 32, "敵"}, + {"敵装飾", "ActorMovementCalcAnim", 32, "敵"}, + {"敵装飾[Movement]", "ActorMovement", 32, "敵"}, + {"デモ", "ActorMovementCalcAnim", 32, "地形"}, + {"デモ装飾", "ActorMovementCalcAnim", 32, "地形"}, + {"デモオブジェクト", "ActorMovement", 32, "地形"}, + {"NPC", "ActorMovementCalcAnim", 64, "NPC"}, + {"NPC装飾", "ActorMovementCalcAnim", 32, "NPC"}, + {"帽子装着位置更新", "Functor", 8, "システム"}, + {"NPCイベントディレクター", "Execute", 1, "システム"}, + {"エリア監視オブジェ", "Execute", 8, "システム"}, + {"通知レイアウト更新", "Execute", 3, "システム"}, + {"バルーン位置更新", "Execute", 1, "システム"}, + {"ネットワーク", "Execute", 2, "システム"}, + {"プレイヤーゴースト管理", "Execute", 1, "プレイヤー"}, + {"エコーエミッター管理", "Execute", 1, "地形オブジェ"}, + {"メッシュ変形モデル管理", "Execute", 1, "地形オブジェ"}, + {"アイテム", "ActorMovementCalcAnim", 64, "アイテム"}, + {"アイテム[デモ]", "ActorMovementCalcAnim", 64, "アイテム"}, + {"アイテム[Movement]", "ActorMovement", 16, "アイテム"}, + {"シャドウマスク", "ActorMovement", 64, "影"}, + {"グラフィックス要求者", "ActorMovement", 64, "システム"}, + {"プロジェクト用グラフィックス", "Execute", 64, "システム"}, + {"監視オブジェ", "ActorMovement", 32, "システム"}, + {"キッズルートガイド管理", "ActorMovement", 1, "システム"}, + {"キッズルートガイド", "ActorMovementCalcAnim", 4, "システム"}, + {"サウンド制御", "ActorMovement", 10, "システム"}, + {"ステージスイッチディレクター", "Execute", 1, "システム"}, + {"2D", "LayoutUpdate", 404, "レイアウト"}, + {"2D(ポーズ無視)", "LayoutUpdate", 360, "レイアウト"}, + {"エフェクト(前処理)", "Functor", 1, "エフェクト"}, + {"エフェクト(3D)", "Execute", 1, "エフェクト"}, + {"エフェクト(プレイヤー)", "Execute", 1, "エフェクト"}, + {"エフェクト(Zソート)", "Execute", 1, "エフェクト"}, + {"エフェクト(カメラデモ)", "Execute", 1, "エフェクト"}, + {"エフェクト(カメラ前エフェクト)", "Execute", 1, "エフェクト"}, + {"エフェクト(ベース2D)", "Execute", 1, "エフェクト"}, + {"エフェクト(2D)", "Execute", 1, "エフェクト"}, + {"エフェクト(後処理)", "Functor", 1, "エフェクト"}, + // Update Table Name: ビュー更新(コア1) + {"ビュー更新(コア1)", "ActorCalcView", 512, "システム"}, + // Update Table Name: ビュー更新(コア2) + {"ビュー更新(コア2)", "ActorCalcView", 1024, "システム"}, + // Update Table Name: スナップショット + {"スナップショット[CalcAnim]", "ActorCalcAnim", 16, "NPC"}, + {"スナップショット[ActorMovement]", "ActorMovement", 1, "地形オブジェ"}, + // Custom Tables + {"PuppetActor", "ActorMovementCalcAnim", 512, "ボス"} +}; + +static constexpr int getUpdateTableIndex(const char* listName) { + for (int i = 0; i < sizeof(updateTableArr) / sizeof(updateTableArr[0]); i++) { + if (std::string_view(updateTableArr[i].mListName)==listName) { + return i; + } + } + return 0; +} + +static constexpr al::ExecuteTable createUpdateTable(const char* tableName, const char* startListName, const char* endListName) { + al::ExecuteTable drawTable; + drawTable.mName = tableName; + int startIndex = getUpdateTableIndex(startListName); + drawTable.mExecuteOrders = &updateTableArr[startIndex]; + drawTable.mExecuteOrderCount = (getUpdateTableIndex(endListName) - startIndex) + 1; + return drawTable; +} + +static constexpr int getDrawTableIndex(const char* listName, const char *groupName) { + for (int i = 0; i < sizeof(drawTableArr)/sizeof(drawTableArr[0]); i++) { + if (std::string_view(drawTableArr[i].mListName)==listName && std::string_view(drawTableArr[i].mExecuteGroup)==groupName) { + return i; + } + } + return 0; +} + +static constexpr al::ExecuteTable createDrawTable(const char* tableName, const char* startListName, const char *groupStartName, const char* endListName, const char *groupEndName) { + al::ExecuteTable drawTable; + drawTable.mName = tableName; + int startIndex = getDrawTableIndex(startListName, groupStartName); + drawTable.mExecuteOrders = &drawTableArr[startIndex]; + drawTable.mExecuteOrderCount = (getDrawTableIndex(endListName, groupEndName) - startIndex) + 1; + return drawTable; +} + +constexpr al::ExecuteTable drawTable[] = { + createDrawTable("3D(カリング)", "カリング", "ActorModelDrawCulling", "カリング", "ActorModelDrawCulling"), + createDrawTable("3D(デプスシャドウ)", "デプスシャドウ[キャラクター]", "ActorModelDrawDepthShadow", "デプスシャドウ[独自]", "Functor"), + createDrawTable("3D(デプスシャドウプレイヤー)", "デプスシャドウ[プレイヤー]", "ActorModelDrawDepthShadow", "Mii[顔モデル](デプスシャドウ)", "Draw"), + createDrawTable("3D(スタティックデプスシャドウ)", "スタティックデプスシャドウ[地形]", "ActorModelDrawStaticDepthShadow", "スタティックデプスシャドウ[地形]", "ActorModelDrawStaticDepthShadow"), + createDrawTable("3D(ワールドAo)", "ワールドAo[地形]", "ActorModelDrawWorldAo", "ワールドAo[地形]", "ActorModelDrawWorldAo"), + createDrawTable("3D(海用デプス)", "海用デプス[浜辺]", "ActorModelDrawWorldAo", "海用デプス[高さ]", "ActorModelDrawWorldAo"), + createDrawTable("3D(空)", "空", "ActorModelDraw", "空", "ActorModelDraw"), + createDrawTable("3D(不透明Zプリパス)", "Zプリパス[カリング]", "ActorModelDrawDepthOnly", "プレイヤー", "ActorModelDrawDepthDither"), + createDrawTable("3D(ディファード地形)", "地形オブジェ[地形前]", "ActorModelDrawDeferred", "地形[埋没]", "ActorModelDrawDeferred"), + createDrawTable("3D(ディファード鏡映り込みなし)", "地形[鏡映り込みなし]", "ActorModelDrawDeferred", "地形[鏡映り込みなし]", "ActorModelDrawDeferred"), + createDrawTable("3D(ディファードキャラクター)", "シャドウマスク[地形オブジェ]", "Draw", "アイテム[ディファード不透明のみ]", "ActorModelDrawDeferredOpa"), + createDrawTable("3D(ディファード異空間)", "異空間オブジェ", "ActorModelDrawDeferred", "異空間オブジェ", "ActorModelDrawDeferred"), + createDrawTable("3D(ディファードプレイヤー)", "シャドウマスク[プレイヤー]", "Draw", "プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawDeferredOpa"), + createDrawTable("3D(ディファード中景)", "地形オブジェ[キャラ後]", "ActorModelDrawDeferred", "ディファード空[デモ]", "ActorModelDrawDeferredSky"), + createDrawTable("3D(ディファード半透明)", "地形[ディファード半透明]", "ActorModelDrawDeferredXlu", "アクター描画", "ActorDraw"), + createDrawTable("3D(デプスクリアプレイヤー)", "プレイヤー", "ActorModelDrawDepthForce", "プレイヤー装飾[インダイレクトのみ]", "ActorModelDrawDepthForce"), + createDrawTable("3D(フォワード遠景)", "遠景[ライトバッファ]", "ActorModelDraw", "大気散乱雲近距離[ライトバッファのみ]", "ActorModelDrawForwardOnly"), + createDrawTable("3D(フォワードプレイヤー)", "Zプリパス[プレイヤー]", "ActorModelDrawDepthOnly", "プレイヤー装飾[ディファード不透明のみ]", "ActorModelDrawForwardForce"), + createDrawTable("3D(フォワード)", "半透明Zプリパス", "ActorModelDrawDepthXlu", "アクター描画[フォワード]", "ActorDraw"), + createDrawTable("3D(インダイレクト)", "半透明Zプリパス[インダイレクト]", "ActorModelDrawDepthIndirect", "アクター描画[インダイレクト]", "ActorDraw"), + createDrawTable("3D(インダイレクト後フォワード)", "半透明Zプリパス[インダイレクト後]", "ActorModelDrawDepthIndirect", "敵[フォワードインダイレクト後]", "ActorModelDraw"), + createDrawTable("3D(インダイレクト後遠景)", "大気散乱雲[インダイレクト後]", "ActorModelDraw", "大気散乱雲[インダイレクト後のみ]", "ActorModelDrawForwardOnly"), + createDrawTable("3D(フォグ後インダイレクト)", "地形[インダイレクトフォグ後]", "ActorModelDrawIndirect", "アイテム[インダイレクトフォグ後のみ]", "ActorModelDrawIndirectOnly"), + createDrawTable("3D(フォグ後遠景)", "遠景[フォグ後]", "ActorModelDraw", "大気散乱雲[フォグ後のみ]", "ActorModelDrawForwardOnly"), + createDrawTable("3D(フォグ後)", "半透明Zプリパス[フォグ後]", "ActorModelDrawDepthXlu", "NPC[フォグ後のみ]", "ActorModelDrawForwardOnly"), + createDrawTable("3D(クロマキーZプリパス)", "Zプリパス[プレイヤークロマキー]", "ActorModelDrawDepthChromakey", "Zプリパス[ディザクロマキー]", "ActorModelDrawDitherChromakey"), + createDrawTable("3D(クロマキープレイヤー)", "プレイヤー[クロマキー]", "ActorModelDrawPlayerChromakey", "プレイヤー[クロマキー半透明]", "ActorModelDrawPlayerChromakeyXlu"), + createDrawTable("3D(クロマキーキャラクター)", "NPC[クロマキー]", "ActorModelDrawCharacterChromakey", "NPC[クロマキー]", "ActorModelDrawCharacterChromakey"), + createDrawTable("2Dバック(メイン画面)", "2Dバック", "LayoutDraw", "2Dバック", "LayoutDraw"), + createDrawTable("2Dベース(メイン画面)", "2Dベース", "LayoutDraw", "2D通知", "LayoutDraw"), + createDrawTable("2Dエフェクト(メイン画面)", "2Dベースエフェクト", "Draw", "2Dベースエフェクト", "Draw"), + createDrawTable("2Dオーバー(メイン画面)", "2Dヘッド", "LayoutDraw", "2Dリザルト", "LayoutDraw"), + createDrawTable("2D(デモ画面)", "2Dデモベース", "LayoutDraw", "2Dデモカーソル", "LayoutDraw"), + createDrawTable("ポストエフェクトマスク", "ポストエフェクトマスク", "ActorModelDrawPostEffectMask", "ポストエフェクトマスク", "ActorModelDrawPostEffectMask"), + createDrawTable("アクター描画(独自レンダーターゲット)", "アクター描画[独自レンダーターゲット]", "ActorDraw", "アクター描画[独自レンダーターゲット]", "ActorDraw"), + createDrawTable("アクター描画(プロジェクト固有)", "アクター描画(プロジェクト固有)", "ActorDraw", "アクター描画(プロジェクト固有)", "ActorDraw"), + createDrawTable("モデル描画バッファ更新", "モデル描画バッファ更新", "ActorModelDrawUpdate", "モデル描画バッファ更新", "ActorModelDrawUpdate"), + createDrawTable("3D(ワールドマップディファード)", "ワールドマップ地形", "ActorModelDrawDeferred", "ワールドマップ地形[ディファード半透明]", "ActorModelDrawDeferredXlu"), + createDrawTable("3D(ワールドマップフォワード)", "ワールドマップ地形[フォワード]", "ActorModelDraw", "ワールドマップ地形オブジェ[フォワード]", "ActorModelDraw"), + createDrawTable("2D(ワールドマップ画面)", "2Dワールドマップベース", "LayoutDraw", "2Dワールドマップ", "LayoutDraw"), + createDrawTable("2D(ムーンゲット画面)", "2D(ムーンゲット)", "LayoutDraw", "2Dワイプ(ムーンゲット)", "LayoutDraw"), + createDrawTable("2D(スナップショット)", "2Dスナップショット", "LayoutDraw", "2Dスナップショット", "LayoutDraw"), + createDrawTable("2D(撮影用)", "2D撮影用", "LayoutDraw", "2D撮影用", "LayoutDraw"), + createDrawTable("2D(ミス)", "2Dミス", "LayoutDraw", "2Dミス", "LayoutDraw"), + // Custom Tables + createDrawTable("OnlineDrawExecutors", "PuppetActor", "ActorModelDrawDeferred", "PuppetActor", "ActorModelDrawDeferred"), +}; + +int drawTableSize = sizeof(drawTable)/sizeof(drawTable[0]); + +constexpr al::ExecuteTable updateTable[] = { + createUpdateTable("更新", "ステージ同期カウンタ", "エフェクト(後処理)"), + createUpdateTable("ビュー更新(コア1)", "ビュー更新(コア1)", "ビュー更新(コア1)"), + createUpdateTable("ビュー更新(コア2)", "ビュー更新(コア2)", "ビュー更新(コア2)"), + createUpdateTable("スナップショット", "スナップショット[CalcAnim]", "スナップショット[ActorMovement]"), + // Custom Tables + createUpdateTable("OnlineUpdateExecutors", "PuppetActor", "PuppetActor"), +}; + +int updateTableSize = sizeof(updateTable)/sizeof(updateTable[0]); \ No newline at end of file diff --git a/source/hooks.cpp b/source/hooks.cpp index 4cb2cea..24d148f 100644 --- a/source/hooks.cpp +++ b/source/hooks.cpp @@ -1,26 +1,23 @@ #include +#include "al/execute/ExecuteDirector.h" +#include "al/execute/ExecuteOrder.h" +#include "al/execute/ExecuteTable.h" +#include "al/execute/ExecuteTableHolderDraw.h" +#include "al/execute/ExecuteTableHolderUpdate.h" +#include "al/scene/Scene.h" +#include "al/util/GraphicsUtil.h" +#include "al/util/KitUtil.h" +#include "basis/seadNew.h" +#include "logger.hpp" +#include "rs/util.hpp" #include "server/Client.hpp" -#include "al/LiveActor/LiveActor.h" -#include "al/actor/ActorInitInfo.h" -#include "al/actor/Placement.h" #include "al/byaml/ByamlIter.h" -#include "al/nerve/Nerve.h" -#include "al/nerve/NerveExecutor.h" -#include "al/nerve/NerveKeeper.h" #include "al/util.hpp" -#include "al/util/ControllerUtil.h" -#include "al/util/LiveActorUtil.h" -#include "al/util/NerveUtil.h" #include "game/Actors/WorldEndBorderKeeper.h" -#include "game/Layouts/CoinCounter.h" -#include "game/Player/Actions/PlayerActionGroundMoveControl.h" #include "game/Player/PlayerActorHakoniwa.h" -#include "game/Player/PlayerConst.h" -#include "game/Player/States/PlayerStateRunHakoniwa.h" #include "game/StageScene/StageSceneStateOption.h" #include "game/StageScene/StageSceneStatePauseMenu.h" #include "game/StageScene/StageSceneStateServerConfig.hpp" -#include "logger.hpp" #include "main.hpp" #include "al/byaml/writer/ByamlWriter.h" #include "math/seadVector.h" @@ -74,7 +71,7 @@ bool saveReadHook(int* padRumbleInt, al::ByamlIter const& saveByml, char const* bool registerShineToList(Shine* shineActor) { - if (shineActor->shineId >= 0) { + if (shineActor->mShineIdx >= 0) { Client::tryRegisterShine(shineActor); } @@ -169,3 +166,41 @@ bool borderPullBackHook(WorldEndBorderKeeper* thisPtr) { return isFirstStep; } + +void drawTableHook(al::ExecuteDirector* thisPtr, const al::ExecuteSystemInitInfo &initInfo) { + + thisPtr->mUpdateTableCount = updateTableSize; + thisPtr->mUpdateTables = new al::ExecuteTableHolderUpdate*[thisPtr->mUpdateTableCount](); + + for (int i = 0; i < thisPtr->mUpdateTableCount; i++) { + thisPtr->mUpdateTables[i] = new al::ExecuteTableHolderUpdate(); + const al::ExecuteTable &curTable = updateTable[i]; + // Logger::log("Update Table Name: %s Count: %d\n", curTable.mName, curTable.mExecuteOrderCount); + thisPtr->mUpdateTables[i]->init(curTable.mName, initInfo, curTable.mExecuteOrders, curTable.mExecuteOrderCount); + } + + thisPtr->mDrawTableCount = drawTableSize; + thisPtr->mDrawTables = new al::ExecuteTableHolderDraw*[thisPtr->mDrawTableCount](); + + for (int i = 0; i < thisPtr->mDrawTableCount; i++) { + thisPtr->mDrawTables[i] = new al::ExecuteTableHolderDraw(); + const al::ExecuteTable* curTable = &drawTable[i]; + // Logger::log("Draw Table Name: %s Count: %d\n", curTable->mName, curTable->mExecuteOrderCount); + thisPtr->mDrawTables[i]->init(curTable->mName, initInfo, curTable->mExecuteOrders, curTable->mExecuteOrderCount); + } + + thisPtr->mRequestKeeper = new al::ExecuteRequestKeeper(thisPtr->mRequestMax); +} + +void updateStateHook(al::Scene* scene) { + al::executeUpdateList(scene->mActorKit, "OnlineUpdateExecutors", "PuppetActor"); + rs::updateEffectSystemEnv(scene); +} + +void updateDrawHook(al::ExecuteDirector* thisPtr, const char* listName, const char* kit) { + + thisPtr->drawList("OnlineDrawExecutors", "PuppetActor"); + + Logger::log("Updating Draw List for: %s %s\n", listName, kit); + thisPtr->drawList(listName, kit); +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index c328ada..39f2810 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,9 +1,16 @@ #include "main.hpp" #include #include +#include "al/execute/ExecuteOrder.h" +#include "al/execute/ExecuteTable.h" +#include "al/execute/ExecuteTableHolderDraw.h" +#include "al/util/GraphicsUtil.h" +#include "container/seadSafeArray.h" +#include "game/GameData/GameDataHolderAccessor.h" #include "game/Player/PlayerActorBase.h" #include "game/Player/PlayerActorHakoniwa.h" #include "game/Player/PlayerHackKeeper.h" +#include "heap/seadHeap.h" #include "math/seadVector.h" #include "server/Client.hpp" #include "puppets/PuppetInfo.h" @@ -78,14 +85,14 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead: // Application::sInstance->mFramework->mGpuPerf->drawResult((agl::DrawContext *)drawContext, frameBuffer); // } - Time::calcTime(); // this needs to be ran every frame, so running it here works + Time::calcTime(); // this needs to be ran every frame, so running it here works if(!debugMode) { al::executeDraw(curSequence->mLytKit, "2Dバック(メイン画面)"); return; } - //int dispWidth = al::getLayoutDisplayWidth(); + // int dispWidth = al::getLayoutDisplayWidth(); int dispHeight = al::getLayoutDisplayHeight(); gTextWriter->mViewport = viewport; @@ -102,10 +109,20 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead: gTextWriter->setCursorFromTopLeft(sead::Vector2f(10.f, (dispHeight / 3) + 30.f)); gTextWriter->setScaleFromFontHeight(20.f); + sead::Heap* clientHeap = Client::getClientHeap(); + sead::Heap *gmHeap = GameModeManager::instance()->getHeap(); + + if (clientHeap) { + gTextWriter->printf("Client Heap Free Size: %f/%f\n", clientHeap->getFreeSize() * 0.001f, clientHeap->getSize() * 0.001f); + gTextWriter->printf("Gamemode Heap Free Size: %f/%f\n", gmHeap->getFreeSize() * 0.001f, gmHeap->getSize()* 0.001f); + } + gTextWriter->printf("Client Socket Connection Status: %s\n", Client::instance()->mSocket->getStateChar()); - gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno); - gTextWriter->printf("Packet Queue Length: %d\n", Client::instance()->mSocket->mPacketQueue.size()); - gTextWriter->printf("Total Connected Players: %d\n", Client::getConnectCount() + 1); + //gTextWriter->printf("nn::socket::GetLastErrno: 0x%x\n", Client::instance()->mSocket->socket_errno); + gTextWriter->printf("Connected Players: %d/%d\n", Client::getConnectCount() + 1, Client::getMaxPlayerCount()); + + gTextWriter->printf("Send Queue Count: %d/%d\n", Client::instance()->mSocket->getSendCount(), Client::instance()->mSocket->getSendMaxCount()); + gTextWriter->printf("Recv Queue Count: %d/%d\n", Client::instance()->mSocket->getRecvCount(), Client::instance()->mSocket->getRecvMaxCount()); al::Scene *curScene = curSequence->curScene; @@ -142,31 +159,33 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead: PuppetInfo* curPupInfo = curPuppet->getInfo(); - // al::LiveActor *curCapture = curPuppet->getCapture(debugCaptureIndex); + if (curModel && curPupInfo) { + // al::LiveActor *curCapture = curPuppet->getCapture(debugCaptureIndex); - gTextWriter->printf("Puppet Index: %d\n", debugPuppetIndex); - gTextWriter->printf("Player Name: %s\n", curPupInfo->puppetName); - gTextWriter->printf("Connection Status: %s\n", curPupInfo->isConnected ? "Online" : "Offline"); - gTextWriter->printf("Is in Same Stage: %s\n", curPupInfo->isInSameStage ? "True" : "False"); - gTextWriter->printf("Is in Capture: %s\n", curPupInfo->isCaptured ? "True" : "False"); - gTextWriter->printf("Puppet Stage: %s\n", curPupInfo->stageName); - gTextWriter->printf("Puppet Scenario: %u\n", curPupInfo->scenarioNo); - gTextWriter->printf("Puppet Costume: H: %s B: %s\n", curPupInfo->costumeHead, curPupInfo->costumeBody); - //gTextWriter->printf("Packet Coords:\nX: %f\nY: %f\nZ: %f\n", curPupInfo->playerPos.x, curPupInfo->playerPos.y, curPupInfo->playerPos.z); - // if (curModel) { - // sead::Vector3f* pupPos = al::getTrans(curModel); - // gTextWriter->printf("In-Game Coords:\nX: %f\nY: %f\nZ: %f\n", pupPos->x, pupPos->y, pupPos->z); - // } + gTextWriter->printf("Puppet Index: %d\n", debugPuppetIndex); + gTextWriter->printf("Player Name: %s\n", curPupInfo->puppetName); + gTextWriter->printf("Connection Status: %s\n", curPupInfo->isConnected ? "Online" : "Offline"); + gTextWriter->printf("Is in Same Stage: %s\n", curPupInfo->isInSameStage ? "True" : "False"); + gTextWriter->printf("Is in Capture: %s\n", curPupInfo->isCaptured ? "True" : "False"); + gTextWriter->printf("Puppet Stage: %s\n", curPupInfo->stageName); + gTextWriter->printf("Puppet Scenario: %u\n", curPupInfo->scenarioNo); + gTextWriter->printf("Puppet Costume: H: %s B: %s\n", curPupInfo->costumeHead, curPupInfo->costumeBody); + //gTextWriter->printf("Packet Coords:\nX: %f\nY: %f\nZ: %f\n", curPupInfo->playerPos.x, curPupInfo->playerPos.y, curPupInfo->playerPos.z); + // if (curModel) { + // sead::Vector3f* pupPos = al::getTrans(curModel); + // gTextWriter->printf("In-Game Coords:\nX: %f\nY: %f\nZ: %f\n", pupPos->x, pupPos->y, pupPos->z); + // } - if(curPupInfo->isCaptured) { - gTextWriter->printf("Current Capture: %s\n", curPupInfo->curHack); - gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr); - gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim); - }else { - gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr); - gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim); - if (curModel) { - gTextWriter->printf("Current Animation: %s\n", al::getActionName(curModel)); + if(curPupInfo->isCaptured) { + gTextWriter->printf("Current Capture: %s\n", curPupInfo->curHack); + gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr); + gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim); + }else { + gTextWriter->printf("Current Packet Animation: %s\n", curPupInfo->curAnimStr); + gTextWriter->printf("Animation Index: %d\n", curPupInfo->curAnim); + if (curModel) { + gTextWriter->printf("Current Animation: %s\n", al::getActionName(curModel)); + } } } } @@ -253,10 +272,14 @@ void drawMainHook(HakoniwaSequence *curSequence, sead::Viewport *viewport, sead: } -void sendShinePacket(GameDataHolderWriter thisPtr, Shine* curShine) { +void sendShinePacket(GameDataHolderAccessor thisPtr, Shine* curShine) { if (!curShine->isGot()) { - Client::sendShineCollectPacket(curShine->shineId); + + GameDataFile::HintInfo* curHintInfo = + &thisPtr.mData->mGameDataFile->mShineHintList[curShine->mShineIdx]; + + Client::sendShineCollectPacket(curHintInfo->mUniqueID); } GameDataFunction::setGotShine(thisPtr, curShine->curShineInfo); @@ -331,11 +354,7 @@ bool hakoniwaSequenceHook(HakoniwaSequence* sequence) { GameModeManager::instance()->setPaused(stageScene->isPause()); Client::setStageInfo(stageScene->mHolder); - Client::updateStates(); - - if (Client::isNeedUpdateShines()) { - Client::updateShines(); - } + Client::update(); updatePlayerInfo(stageScene->mHolder, playerBase, isYukimaru); diff --git a/source/puppets/PuppetActor.cpp b/source/puppets/PuppetActor.cpp index 2c20b61..7ef88ee 100644 --- a/source/puppets/PuppetActor.cpp +++ b/source/puppets/PuppetActor.cpp @@ -1,6 +1,9 @@ #include #include +#include "al/model/PartsModel.h" #include "al/util/SensorUtil.h" +#include "game/Player/PlayerCostumeFunction.h" +#include "game/Player/PlayerCostumeInfo.h" #include "rs/util/SensorUtil.h" #include "server/Client.hpp" #include "al/LiveActor/LiveActor.h" @@ -52,7 +55,7 @@ void PuppetActor::init(al::ActorInitInfo const &initInfo) { al::LiveActor *normalModel = new al::LiveActor("Normal"); - mCostumeInfo = PlayerFunction::initMarioModelCommon(normalModel, initInfo, bodyName, capName, 0, false, nullptr, false, false); + mCostumeInfo = initMarioModelPuppet(normalModel, initInfo, bodyName, capName, 0, nullptr); normalModel->mActorActionKeeper->mPadAndCamCtrl->mRumbleCount = 0; // set rumble count to zero so that no rumble actions will run @@ -100,6 +103,10 @@ void PuppetActor::movement() { al::LiveActor::movement(); } +void PuppetActor::calcAnim() { + al::LiveActor::calcAnim(); +} + void PuppetActor::control() { if(mInfo) { @@ -405,4 +412,217 @@ void PuppetActor::emitJoinEffect() { al::tryDeleteEffect(this, "Disappear"); // remove previous effect (if played previously) al::tryEmitEffect(this, "Disappear", nullptr); +} + +const char *executorName = "NPC"; + +PlayerCostumeInfo* initMarioModelPuppet(al::LiveActor* player, + const al::ActorInitInfo& initInfo, + const char* bodyName, const char* capName, + int subActorNum, + al::AudioKeeper* audioKeeper) { + + // Logger::log("Loading Resources for Mario Puppet Model.\n"); + + + al::ActorResource* modelRes = al::findOrCreateActorResourceWithAnimResource( + initInfo.mResourceHolder, al::StringTmp<0x100>("ObjectData/%s", bodyName).cstr(), + al::StringTmp<0x100>("ObjectData/%s", "PlayerAnimation").cstr(), 0, false); + + // Logger::log("Creating Body Costume Info.\n"); + + PlayerBodyCostumeInfo* bodyInfo = + PlayerCostumeFunction::createBodyCostumeInfo(modelRes->mResourceModel, bodyName); + + // Logger::log("Initializing Basic Actor Data.\n"); + + al::initActorSceneInfo(player, initInfo); + al::initActorPoseTQGSV(player); + al::initActorSRT(player, initInfo); + + al::initActorModelKeeper(player, initInfo, + al::StringTmp<0x100>("ObjectData/%s", bodyName).cstr(), 6, + al::StringTmp<0x100>("ObjectData/%s", "PlayerAnimation").cstr()); + + // Logger::log("Creating Material Category for Player Type\n"); + + al::ModelMaterialCategory::tryCreate( + player->mModelKeeper->mModelCtrl, "Player", + initInfo.mActorSceneInfo.mGfxSysInfo->mMaterialCategoryKeeper); + + // Logger::log("Initing Skeleton.\n"); + + al::initPartialSklAnim(player, 1, 1, 32); + al::addPartialSklAnimPartsListRecursive(player, "Spine1", 0); + + // Logger::log("Setting Up Executor Info.\n"); + + al::initExecutorUpdate(player, initInfo, executorName); + al::initExecutorDraw(player, initInfo, executorName); + al::initExecutorModelUpdate(player, initInfo); + + // Logger::log("Getting InitEffect Byml from resource.\n"); + + al::ByamlIter iter; + if (al::tryGetActorInitFileIter(&iter, modelRes->mResourceModel, "InitEffect", 0)) { + const char *effectKeeperName; + if (iter.tryGetStringByKey(&effectKeeperName, "Name")) { + + // Logger::log("Initializing Effect Keeper.\n"); + + al::initActorEffectKeeper(player, initInfo, effectKeeperName); + } + } + + // Logger::log("Initing Player Audio.\n"); + + PlayerFunction::initMarioAudio(player, initInfo, modelRes->mResourceModel, false, audioKeeper); + al::initActorActionKeeper(player, modelRes, bodyName, 0); + al::setMaterialProgrammable(player); + + // Logger::log("Creating Sub-Actor Keeper.\n"); + + al::SubActorKeeper* actorKeeper = al::SubActorKeeper::tryCreate(player, 0, subActorNum); + + if (actorKeeper) { + player->initSubActorKeeper(actorKeeper); + } + + actorKeeper->init(initInfo, 0, subActorNum); + + // Logger::log("Initializing Sub-Actors.\n"); + + int subModelNum = al::getSubActorNum(player); + + if (subModelNum >= 1) { + for (int i = 0; i < subModelNum; i++) { + al::LiveActor* subActor = al::getSubActor(player, i); + const char* actorName = subActor->getName(); + + if (!al::isEqualString(actorName, "シルエットモデル")) { + al::initExecutorUpdate(subActor, initInfo, executorName); + al::initExecutorDraw(subActor, initInfo, executorName); + al::setMaterialProgrammable(subActor); + } + } + } + + // Logger::log("Creating Clipping.\n"); + + al::initActorClipping(player, initInfo); + al::invalidateClipping(player); + + // Logger::log("Getting Cap Model/Head Model Name.\n"); + + const char *capModelName; + + if (bodyInfo->mIsUseHeadSuffix) { + if (al::isEqualString(bodyInfo->costumeName, capName)) { + capModelName = ""; + } else { + capModelName = capName; + } + } else { + capModelName = ""; + } + + const char *headType; + + if (!al::isEqualSubString(capName, "Mario64")) { + if (bodyInfo->mIsUseShortHead && al::isEqualString(capName, "MarioPeach")) { + headType = "Short"; + } else { + headType = ""; + } + } else if (al::isEqualString(bodyInfo->costumeName, "Mario64")) { + headType = ""; + } else if (al::isEqualString(bodyInfo->costumeName, "Mario64Metal")) { + headType = "Metal"; + } else { + headType = "Other"; + } + + // Logger::log("Creating Head Costume Info. Cap Model: %s. Head Type: %s. Cap Name: %s.\n", capModelName, headType, capName); + + PlayerHeadCostumeInfo* headInfo = initMarioHeadCostumeInfo( + player, initInfo, "頭", capName, headType, capModelName); + + // Logger::log("Creating Costume Info.\n"); + + PlayerCostumeInfo* costumeInfo = new PlayerCostumeInfo(); + costumeInfo->init(bodyInfo, headInfo); + + if (costumeInfo->isNeedBodyHair()) { + + Logger::log("Creating Body Hair Parts Model.\n"); + + al::PartsModel* partsModel = new al::PartsModel("髪"); + + partsModel->initPartsFixFile( + player, initInfo, + al::StringTmp<0x100>("%sHair%s", bodyName, + costumeInfo->isEnableHairNoCap() ? "NoCap" : "") + .cstr(), + 0, "Hair"); + + al::initExecutorUpdate(partsModel, initInfo, executorName); + al::initExecutorDraw(partsModel, initInfo, executorName); + al::setMaterialProgrammable(partsModel); + partsModel->makeActorDead(); + al::onSyncAppearSubActor(player, partsModel); + al::onSyncClippingSubActor(player, partsModel); + al::onSyncAlphaMaskSubActor(player, partsModel); + al::onSyncHideSubActor(player, partsModel); + } + + // Logger::log("Initing Depth Model.\n"); + + PlayerFunction::initMarioDepthModel(player, false, false); + + // Logger::log("Creating Retarget Info.\n"); + + rs::createPlayerSklRetargettingInfo(player, sead::Vector3f::ones); + + // Logger::log("Making Player Model Dead.\n"); + + player->makeActorDead(); + return costumeInfo; +} + +PlayerHeadCostumeInfo* initMarioHeadCostumeInfo(al::LiveActor* player, + const al::ActorInitInfo &initInfo, + const char* headModelName, const char* capModelName, + const char* headType, const char* headSuffix) { + + al::PartsModel* headModel = new al::PartsModel(headModelName); + + al::StringTmp<0x80> headArcName("%sHead%s", capModelName, headType); + al::StringTmp<0x100> arcSuffix("Head"); + if (headSuffix) arcSuffix.format("Head%s", headSuffix); + + headModel->initPartsFixFile(player, initInfo, headArcName.cstr(), 0, arcSuffix.cstr()); + al::setMaterialProgrammable(headModel); + + al::initExecutorUpdate(headModel, initInfo, executorName); + al::initExecutorDraw(headModel, initInfo, executorName); + + headModel->makeActorDead(); + + al::onSyncAppearSubActor(player, headModel); + al::onSyncClippingSubActor(player, headModel); + al::onSyncAlphaMaskSubActor(player, headModel); + al::onSyncHideSubActor(player, headModel); + + al::PartsModel* capEyesModel = new al::PartsModel("キャップの目"); + capEyesModel->initPartsFixFile(headModel, initInfo, "CapManHeroEyes", "", 0); + + al::onSyncClippingSubActor(headModel, capEyesModel); + al::onSyncAlphaMaskSubActor(headModel, capEyesModel); + al::onSyncHideSubActor(headModel, capEyesModel); + + al::setMaterialProgrammable(headModel); + headModel->makeActorDead(); + + return PlayerCostumeFunction::createHeadCostumeInfo(al::getModelResource(headModel), capModelName, false); + } \ No newline at end of file diff --git a/source/sead/seadNew.cpp b/source/sead/seadNew.cpp index 9b7844d..66c361a 100644 --- a/source/sead/seadNew.cpp +++ b/source/sead/seadNew.cpp @@ -151,14 +151,14 @@ void operator delete[](void* ptr, sead::Heap*, const std::nothrow_t&) noexcept // operator delete(void*, sead::Heap*, s32) -void operator delete(void* ptr, sead::Heap*, s32) +void operator delete(void* ptr, sead::Heap* heap, s32) { - sead::system::DeleteImpl(ptr); + heap->free(ptr); } -void operator delete[](void* ptr, sead::Heap*, s32) +void operator delete[](void* ptr, sead::Heap*heap, s32) { - sead::system::DeleteImpl(ptr); + heap->free(ptr); } void operator delete(void* ptr, sead::Heap*, s32, const std::nothrow_t&) noexcept diff --git a/source/server/Client.cpp b/source/server/Client.cpp index bd5dc6c..9f8f1c4 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -1,42 +1,10 @@ #include "server/Client.hpp" -#include -#include -#include "al/actor/ActorSceneInfo.h" -#include "al/layout/WindowConfirmWait.h" -#include "al/util/ControllerUtil.h" +#include "al/layout/SimpleLayoutAppearWaitEnd.h" #include "al/util/LiveActorUtil.h" -#include "algorithms/PlayerAnims.h" -#include "game/GameData/GameDataFunction.h" -#include "game/GameData/GameDataHolderAccessor.h" -#include "game/Info/QuestInfo.h" -#include "game/Player/PlayerActorBase.h" -#include "game/Player/PlayerActorHakoniwa.h" #include "game/SaveData/SaveDataAccessFunction.h" -#include "game/StageScene/StageScene.h" -#include "heap/seadDisposer.h" -#include "heap/seadHeap.h" -#include "heap/seadFrameHeap.h" #include "heap/seadHeapMgr.h" -#include "helpers.hpp" -#include "layouts/HideAndSeekIcon.h" #include "logger.hpp" -#include "math/seadVector.h" -#include "nn/err.h" -#include "nn/result.h" -#include "nn/swkbd/swkbd.h" -#include "nn/util.h" -#include "packets/ChangeStagePacket.h" -#include "packets/InitPacket.h" #include "packets/Packet.h" -#include "packets/PlayerConnect.h" -#include "packets/PlayerDC.h" -#include "packets/TagInf.h" -#include "puppets/PuppetInfo.h" -#include "sead/basis/seadRawPrint.h" -#include "sead/math/seadQuat.h" -#include "server/gamemode/GameModeBase.hpp" -#include "server/gamemode/GameModeManager.hpp" -#include "server/hns/HideAndSeekConfigMenu.hpp" #include "server/hns/HideAndSeekMode.hpp" SEAD_SINGLETON_DISPOSER_IMPL(Client) @@ -50,15 +18,16 @@ typedef void (Client::*ClientThreadFunc)(void); */ Client::Client() { - mHeap = sead::FrameHeap::create(0x100000, "ClientHeap", sead::HeapMgr::instance()->getCurrentHeap(), 8, sead::Heap::cHeapDirection_Forward, false); + mHeap = sead::ExpHeap::create(0x50000, "ClientHeap", sead::HeapMgr::instance()->getCurrentHeap(), 8, sead::Heap::cHeapDirection_Forward, false); - sead::ScopedCurrentHeapSetter heapSetter(mHeap); // every new call after this will use ClientHeap instead of SequenceHeap + sead::ScopedCurrentHeapSetter heapSetter( + mHeap); // every new call after this will use ClientHeap instead of SequenceHeap - this->mReadThread = new al::AsyncFunctorThread("ClientReadThread", al::FunctorV0M(this, &Client::readFunc), 0, 0x10000, {0}); + mReadThread = new al::AsyncFunctorThread("ClientReadThread", al::FunctorV0M(this, &Client::readFunc), 0, 0x1000, {0}); mKeyboard = new Keyboard(nn::swkbd::GetRequiredStringBufferSize()); - mSocket = new SocketClient("SocketClient"); + mSocket = new SocketClient("SocketClient", mHeap); mPuppetHolder = new PuppetHolder(maxPuppets); @@ -103,33 +72,34 @@ Client::Client() { void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor holder) { mConnectionWait = new (mHeap) al::WindowConfirmWait("ServerWaitConnect", "WindowConfirmWait", initInfo); + + mConnectStatus = new (mHeap) al::SimpleLayoutAppearWaitEnd("", "SaveMessage", initInfo, 0, false); mConnectionWait->setTxtMessage(u"Connecting to Server."); - mConnectionWait->setTxtMessageConfirm(u"Failed to Connect!"); + al::setPaneString(mConnectStatus, "TxtSave", u"Connecting to Server.", 0); + al::setPaneString(mConnectStatus, "TxtSaveSh", u"Connecting to Server.", 0); + mHolder = holder; - StartThreads(); - - Logger::log("Remaining Heap Size: %d\n", mHeap->getFreeSize()); + startThread(); + Logger::log("Heap Free Size: %f/%f\n", mHeap->getFreeSize() * 0.001f, mHeap->getSize() * 0.001f); } - /** * @brief starts client read thread * * @return true if read thread was sucessfully started * @return false if read thread was unable to start, or thread was already started. */ -bool Client::StartThreads() { - if(this->mReadThread->isDone()) { // && this->recvThread->isDone()) { - this->mReadThread->start(); - //this->recvThread->start(); - Logger::log("Threads Sucessfully Started.\n"); +bool Client::startThread() { + if(mReadThread->isDone() ) { + mReadThread->start(); + Logger::log("Read Thread Sucessfully Started.\n"); return true; }else { - Logger::log("Thread(s) has/have already started! Or other unknown reason.\n"); + Logger::log("Read Thread has already started! Or other unknown reason.\n"); return false; } } @@ -144,13 +114,15 @@ void Client::restartConnection() { return; } + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); + Logger::log("Sending Disconnect.\n"); - PlayerDC playerDC = PlayerDC(); + PlayerDC *playerDC = new PlayerDC(); - playerDC.mUserID = sInstance->mUserID; + playerDC->mUserID = sInstance->mUserID; - sInstance->mSocket->SEND(&playerDC); + sInstance->mSocket->queuePacket(playerDC); if (sInstance->mSocket->closeSocket()) { Logger::log("Sucessfully Closed Socket.\n"); @@ -164,14 +136,6 @@ void Client::restartConnection() { Logger::log("Reconnect Sucessful!\n"); - PlayerConnect initPacket; - initPacket.mUserID = sInstance->mUserID; - strcpy(initPacket.clientName, sInstance->mUsername.cstr()); - - initPacket.conType = ConnectionTypes::INIT; - - sInstance->mSocket->SEND(&initPacket); - } else { Logger::log("Reconnect Unsuccessful.\n"); } @@ -216,27 +180,25 @@ bool Client::startConnection() { bool waitingForInitPacket = true; // wait for client init packet + while (waitingForInitPacket) { - if (mSocket->RECV()) { - if(!mSocket->mPacketQueue.isEmpty()){ - Packet* curPacket = mSocket->mPacketQueue.popFront(); + Packet *curPacket = mSocket->tryGetPacket(); - if (curPacket->mType == PacketType::CLIENTINIT) { - InitPacket* initPacket = (InitPacket*)curPacket; + if (curPacket) { + + if (curPacket->mType == PacketType::CLIENTINIT) { + InitPacket* initPacket = (InitPacket*)curPacket; - Logger::log("Server Max Player Size: %d\n", initPacket->maxPlayers); + Logger::log("Server Max Player Size: %d\n", initPacket->maxPlayers); - maxPuppets = initPacket->maxPlayers - 1; - } else { - Logger::log("First Packet was not Init!\n"); - mIsConnectionActive = false; - } + maxPuppets = initPacket->maxPlayers - 1; - free(curPacket); waitingForInitPacket = false; } + mHeap->free(curPacket); + } else { Logger::log("Recieve failed! Stopping Connection.\n"); mIsConnectionActive = false; @@ -280,9 +242,11 @@ bool Client::openKeyboardIP() { nn::os::YieldThread(); // allow other threads to run } - sInstance->isFirstConnect = prevIp != sInstance->mServerIP; + bool isFirstConnect = prevIp != sInstance->mServerIP; - return sInstance->isFirstConnect; + sInstance->mSocket->setIsFirstConn(isFirstConnect); + + return isFirstConnect; } /** @@ -319,13 +283,15 @@ bool Client::openKeyboardPort() { nn::os::YieldThread(); // allow other threads to run } - sInstance->isFirstConnect = prevPort != sInstance->mServerPort; + bool isFirstConnect = prevPort != sInstance->mServerPort; - return sInstance->isFirstConnect; + sInstance->mSocket->setIsFirstConn(isFirstConnect); + + return isFirstConnect; } /** - * @brief main thread function for read thread, responsible for receiving and processing packets from server + * @brief main thread function for read thread, responsible for processing packets from server * */ void Client::readFunc() { @@ -336,166 +302,100 @@ void Client::readFunc() { waitForGameInit = false; } - // we can use the start of readFunc to display an al::WindowConfirmWait while the client - // connects + mConnectStatus->appear(); - mConnectionWait->appear(); - - mConnectionWait->playLoop(); + al::startAction(mConnectStatus, "Loop", "Loop"); if (!startConnection()) { Logger::log("Failed to Connect to Server.\n"); - al::hidePane(mConnectionWait, "Page01"); // hide A button prompt since connection message automatically hides after 0.25 seconds - - al::startAction(mConnectionWait, "Confirm", "State"); - nn::os::SleepThread(nn::TimeSpan::FromNanoSeconds(250000000)); // sleep active thread for 0.25 seconds - mConnectionWait->tryEnd(); - + mConnectStatus->end(); + return; } - PlayerConnect initPacket; - initPacket.mUserID = mUserID; - strcpy(initPacket.clientName, mUsername.cstr()); - - if (isFirstConnect) { - initPacket.conType = ConnectionTypes::INIT; - isFirstConnect = false; - } else { - initPacket.conType = ConnectionTypes::RECONNECT; - } - - mSocket->SEND(&initPacket); // send initial packet - nn::os::SleepThread(nn::TimeSpan::FromNanoSeconds(500000000)); // sleep for 0.5 seconds to let connection layout fully show (probably should find a better way to do this) - mConnectionWait->tryEnd(); + mConnectStatus->end(); while(mIsConnectionActive) { - if (mSocket->getLogState() != SOCKET_LOG_CONNECTED) { - - if (!mConnectionWait->mIsAlive) { - - mConnectionWait->appear(); + Packet *curPacket = mSocket->tryGetPacket(); // will block until a packet has been recieved, or socket disconnected - mConnectionWait->playLoop(); + if (curPacket) { + + switch (curPacket->mType) + { + case PacketType::PLAYERINF: + updatePlayerInfo((PlayerInf*)curPacket); + break; + case PacketType::GAMEINF: + updateGameInfo((GameInf*)curPacket); + break; + case PacketType::HACKCAPINF: + updateHackCapInfo((HackCapInf *)curPacket); + break; + case PacketType::CAPTUREINF: + updateCaptureInfo((CaptureInf*)curPacket); + break; + case PacketType::PLAYERCON: + updatePlayerConnect((PlayerConnect*)curPacket); + + // Send relevant info packets when another client is connected + + // Assume game packets are empty from first connection + if (lastGameInfPacket.mUserID != mUserID) + lastGameInfPacket.mUserID = mUserID; + mSocket->send(&lastGameInfPacket); + + // No need to send player/costume packets if they're empty + if (lastPlayerInfPacket.mUserID == mUserID) + mSocket->send(&lastPlayerInfPacket); + if (lastCostumeInfPacket.mUserID == mUserID) + mSocket->send(&lastCostumeInfPacket); + + break; + case PacketType::COSTUMEINF: + updateCostumeInfo((CostumeInf*)curPacket); + break; + case PacketType::SHINECOLL: + updateShineInfo((ShineCollect*)curPacket); + break; + case PacketType::PLAYERDC: + Logger::log("Received Player Disconnect!\n"); + curPacket->mUserID.print(); + disconnectPlayer((PlayerDC*)curPacket); + break; + case PacketType::TAGINF: + updateTagInfo((TagInf*)curPacket); + break; + case PacketType::CHANGESTAGE: + sendToStage((ChangeStagePacket*)curPacket); + break; + case PacketType::CLIENTINIT: { + InitPacket* initPacket = (InitPacket*)curPacket; + Logger::log("Server Max Player Size: %d\n", initPacket->maxPlayers); + maxPuppets = initPacket->maxPlayers - 1; + break; } - - // if we ever disconnect, reset all our values until we reconnect - - mConnectCount = 0; - - if (mSocket->init(mServerIP.cstr(), mServerPort).isSuccess()) { - - Logger::log("Connected!\n"); - - if (isFirstConnect) { - initPacket.conType = - ConnectionTypes::INIT; // if we've changed the IP/Port since last connect, - // send init instead of reconnect - isFirstConnect = false; - } else { - initPacket.conType = ConnectionTypes::RECONNECT; - } - - mSocket->SEND(&initPacket); - mConnectionWait->tryEnd(); - continue; - } else { - Logger::log("%s: not reconnected\n", __func__); + default: + Logger::log("Discarding Unknown Packet Type.\n"); + break; } - nn::os::YieldThread(); // if we're currently waiting on the socket to be initialized, wait until it is - nn::os::SleepThread(nn::TimeSpan::FromSeconds(5)); - } - - if(mSocket->RECV()) { // will block until a packet has been recieved, or socket disconnected - - while(!mSocket->mPacketQueue.isEmpty()) { - - Packet *curPacket = mSocket->mPacketQueue.popFront(); - - switch (curPacket->mType) - { - case PacketType::PLAYERINF: - updatePlayerInfo((PlayerInf*)curPacket); - break; - case PacketType::GAMEINF: - updateGameInfo((GameInf*)curPacket); - break; - case PacketType::HACKCAPINF: - updateHackCapInfo((HackCapInf *)curPacket); - break; - case PacketType::CAPTUREINF: - updateCaptureInfo((CaptureInf*)curPacket); - break; - case PacketType::PLAYERCON: - updatePlayerConnect((PlayerConnect*)curPacket); - - // Send relevant info packets when another client is connected - - // Assume game packets are empty from first connection - if (lastGameInfPacket.mUserID != mUserID) - lastGameInfPacket.mUserID = mUserID; - mSocket->SEND(&lastGameInfPacket); - - // No need to send player/costume packets if they're empty - if (lastPlayerInfPacket.mUserID == mUserID) - mSocket->SEND(&lastPlayerInfPacket); - if (lastCostumeInfPacket.mUserID == mUserID) - mSocket->SEND(&lastCostumeInfPacket); - - break; - case PacketType::COSTUMEINF: - updateCostumeInfo((CostumeInf*)curPacket); - break; - case PacketType::SHINECOLL: - updateShineInfo((ShineCollect*)curPacket); - break; - case PacketType::PLAYERDC: - Logger::log("Received Player Disconnect!\n"); - curPacket->mUserID.print(); - disconnectPlayer((PlayerDC*)curPacket); - break; - case PacketType::TAGINF: - updateTagInfo((TagInf*)curPacket); - break; - case PacketType::CHANGESTAGE: - sendToStage((ChangeStagePacket*)curPacket); - break; - case PacketType::CLIENTINIT: { - InitPacket* initPacket = (InitPacket*)curPacket; - Logger::log("Server Max Player Size: %d\n", initPacket->maxPlayers); - maxPuppets = initPacket->maxPlayers - 1; - break; - } - default: - break; - } - - free(curPacket); - - } + mHeap->free(curPacket); }else { // if false, socket has errored or disconnected, so close the socket and end this thread. Logger::log("Client Socket Encountered an Error! Errno: 0x%x\n", mSocket->socket_errno); } - nn::os::YieldThread(); // allow other threads to run } Logger::log("Client Read Thread ending.\n"); } -/** - * @brief unused thread function for receiving thread - * - */ -void Client::recvFunc() {} /** * @brief sends player info packet to current server @@ -514,12 +414,14 @@ void Client::sendPlayerInfPacket(const PlayerActorBase *playerBase, bool isYukim return; } - PlayerInf packet = PlayerInf(); - packet.mUserID = sInstance->mUserID; + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); - packet.playerPos = al::getTrans(playerBase); + PlayerInf *packet = new PlayerInf(); + packet->mUserID = sInstance->mUserID; - al::calcQuat(&packet.playerRot, + packet->playerPos = al::getTrans(playerBase); + + al::calcQuat(&packet->playerRot, playerBase); // calculate rotation based off pose instead of using quat rotation if (!isYukimaru) { @@ -528,7 +430,7 @@ void Client::sendPlayerInfPacket(const PlayerActorBase *playerBase, bool isYukim for (size_t i = 0; i < 6; i++) { - packet.animBlendWeights[i] = player->mPlayerAnimator->getBlendWeight(i); + packet->animBlendWeights[i] = player->mPlayerAnimator->getBlendWeight(i); } const char *hackName = player->mHackKeeper->getCurrentHackName(); @@ -540,16 +442,16 @@ void Client::sendPlayerInfPacket(const PlayerActorBase *playerBase, bool isYukim const char* actName = al::getActionName(player->mHackKeeper->currentHackActor); if (actName) { - packet.actName = PlayerAnims::FindType(actName); - packet.subActName = PlayerAnims::Type::Unknown; + packet->actName = PlayerAnims::FindType(actName); + packet->subActName = PlayerAnims::Type::Unknown; //strcpy(packet.actName, actName); } else { - packet.actName = PlayerAnims::Type::Unknown; - packet.subActName = PlayerAnims::Type::Unknown; + packet->actName = PlayerAnims::Type::Unknown; + packet->subActName = PlayerAnims::Type::Unknown; } } else { - packet.actName = PlayerAnims::FindType(player->mPlayerAnimator->mAnimFrameCtrl->getActionName()); - packet.subActName = PlayerAnims::FindType(player->mPlayerAnimator->curSubAnim.cstr()); + packet->actName = PlayerAnims::FindType(player->mPlayerAnimator->mAnimFrameCtrl->getActionName()); + packet->subActName = PlayerAnims::FindType(player->mPlayerAnimator->curSubAnim.cstr()); sInstance->isClientCaptured = false; } @@ -560,21 +462,22 @@ void Client::sendPlayerInfPacket(const PlayerActorBase *playerBase, bool isYukim for (size_t i = 0; i < 6; i++) { - packet.animBlendWeights[i] = 0; + packet->animBlendWeights[i] = 0; } sInstance->isClientCaptured = false; - packet.actName = PlayerAnims::Type::Unknown; - packet.subActName = PlayerAnims::Type::Unknown; + packet->actName = PlayerAnims::Type::Unknown; + packet->subActName = PlayerAnims::Type::Unknown; } - - if(sInstance->lastPlayerInfPacket != packet) { - sInstance->mSocket->SEND(&packet); + + if(sInstance->lastPlayerInfPacket != *packet) { + sInstance->lastPlayerInfPacket = *packet; // deref packet and store in client memory + sInstance->mSocket->queuePacket(packet); + } else { + sInstance->mHeap->free(packet); // free packet if we're not using it } - sInstance->lastPlayerInfPacket = packet; - } /** * @brief sends info related to player's cap actor to server @@ -587,35 +490,37 @@ void Client::sendHackCapInfPacket(const HackCap* hackCap) { Logger::log("Static Instance is Null!\n"); return; } + + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); bool isFlying = hackCap->isFlying(); // if cap is in flying state, send packet as often as this function is called if (isFlying) { - HackCapInf packet = HackCapInf(); - packet.mUserID = sInstance->mUserID; - packet.capPos = al::getTrans(hackCap); + HackCapInf *packet = new HackCapInf(); + packet->mUserID = sInstance->mUserID; + packet->capPos = al::getTrans(hackCap); - packet.isCapVisible = isFlying; + packet->isCapVisible = isFlying; - packet.capQuat.x = hackCap->mJointKeeper->mJointRot.x; - packet.capQuat.y = hackCap->mJointKeeper->mJointRot.y; - packet.capQuat.z = hackCap->mJointKeeper->mJointRot.z; - packet.capQuat.w = hackCap->mJointKeeper->mSkew; + packet->capQuat.x = hackCap->mJointKeeper->mJointRot.x; + packet->capQuat.y = hackCap->mJointKeeper->mJointRot.y; + packet->capQuat.z = hackCap->mJointKeeper->mJointRot.z; + packet->capQuat.w = hackCap->mJointKeeper->mSkew; - strcpy(packet.capAnim, al::getActionName(hackCap)); + strcpy(packet->capAnim, al::getActionName(hackCap)); - sInstance->mSocket->SEND(&packet); + sInstance->mSocket->queuePacket(packet); sInstance->isSentHackInf = true; } else if (sInstance->isSentHackInf) { // if cap is not flying, check to see if previous function call sent a packet, and if so, send one final packet resetting cap data. - HackCapInf packet = HackCapInf(); - packet.mUserID = sInstance->mUserID; - packet.isCapVisible = false; - packet.capPos = sead::Vector3f::zero; - packet.capQuat = sead::Quatf::unit; - sInstance->mSocket->SEND(&packet); + HackCapInf *packet = new HackCapInf(); + packet->mUserID = sInstance->mUserID; + packet->isCapVisible = false; + packet->capPos = sead::Vector3f::zero; + packet->capQuat = sead::Quatf::unit; + sInstance->mSocket->queuePacket(packet); sInstance->isSentHackInf = false; } } @@ -632,25 +537,29 @@ void Client::sendGameInfPacket(const PlayerActorHakoniwa* player, GameDataHolder Logger::log("Static Instance is Null!\n"); return; } + + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); - GameInf packet = GameInf(); - packet.mUserID = sInstance->mUserID; + GameInf *packet = new GameInf(); + packet->mUserID = sInstance->mUserID; if (player) { - packet.is2D = player->mDimKeeper->is2DModel; + packet->is2D = player->mDimKeeper->is2DModel; } else { - packet.is2D = false; + packet->is2D = false; } - packet.scenarioNo = holder.mData->mGameDataFile->getScenarioNo(); + packet->scenarioNo = holder.mData->mGameDataFile->getScenarioNo(); - strcpy(packet.stageName, GameDataFunction::getCurrentStageName(holder)); + strcpy(packet->stageName, GameDataFunction::getCurrentStageName(holder)); - if(packet != sInstance->lastGameInfPacket) { - sInstance->mSocket->SEND(&packet); + if(*packet != sInstance->lastGameInfPacket) { + sInstance->lastGameInfPacket = *packet; + sInstance->mSocket->queuePacket(packet); + } else { + sInstance->mHeap->free(packet); // free packet if we're not using it } - sInstance->lastGameInfPacket = packet; } /** * @brief @@ -663,19 +572,21 @@ void Client::sendGameInfPacket(GameDataHolderAccessor holder) { Logger::log("Static Instance is Null!\n"); return; } + + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); - GameInf packet = GameInf(); - packet.mUserID = sInstance->mUserID; + GameInf *packet = new GameInf(); + packet->mUserID = sInstance->mUserID; - packet.is2D = false; + packet->is2D = false; - packet.scenarioNo = holder.mData->mGameDataFile->getScenarioNo(); + packet->scenarioNo = holder.mData->mGameDataFile->getScenarioNo(); - strcpy(packet.stageName, GameDataFunction::getCurrentStageName(holder)); + strcpy(packet->stageName, GameDataFunction::getCurrentStageName(holder)); - sInstance->mSocket->SEND(&packet); + sInstance->lastGameInfPacket = *packet; - sInstance->lastGameInfPacket = packet; + sInstance->mSocket->queuePacket(packet); } /** @@ -689,6 +600,8 @@ void Client::sendTagInfPacket() { return; } + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); + HideAndSeekMode* hsMode = GameModeManager::instance()->getMode(); if (!GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) { @@ -698,17 +611,17 @@ void Client::sendTagInfPacket() { HideAndSeekInfo* curInfo = GameModeManager::instance()->getInfo(); - TagInf packet = TagInf(); + TagInf *packet = new TagInf(); - packet.mUserID = sInstance->mUserID; + packet->mUserID = sInstance->mUserID; - packet.isIt = hsMode->isPlayerIt(); + packet->isIt = hsMode->isPlayerIt(); - packet.minutes = curInfo->mHidingTime.mMinutes; - packet.seconds = curInfo->mHidingTime.mSeconds; - packet.updateType = static_cast(TagUpdateType::STATE | TagUpdateType::TIME); + packet->minutes = curInfo->mHidingTime.mMinutes; + packet->seconds = curInfo->mHidingTime.mSeconds; + packet->updateType = static_cast(TagUpdateType::STATE | TagUpdateType::TIME); - sInstance->mSocket->SEND(&packet); + sInstance->mSocket->queuePacket(packet); } /** @@ -723,11 +636,13 @@ void Client::sendCostumeInfPacket(const char* body, const char* cap) { Logger::log("Static Instance is Null!\n"); return; } + + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); - CostumeInf packet = CostumeInf(body, cap); - packet.mUserID = sInstance->mUserID; - sInstance->mSocket->SEND(&packet); - sInstance->lastCostumeInfPacket = packet; + CostumeInf *packet = new CostumeInf(body, cap); + packet->mUserID = sInstance->mUserID; + sInstance->lastCostumeInfPacket = *packet; + sInstance->mSocket->queuePacket(packet); } /** @@ -741,18 +656,20 @@ void Client::sendCaptureInfPacket(const PlayerActorHakoniwa* player) { Logger::log("Static Instance is Null!\n"); return; } + + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); if (sInstance->isClientCaptured && !sInstance->isSentCaptureInf) { - CaptureInf packet = CaptureInf(); - packet.mUserID = sInstance->mUserID; - strcpy(packet.hackName, tryConvertName(player->mHackKeeper->getCurrentHackName())); - sInstance->mSocket->SEND(&packet); + CaptureInf *packet = new CaptureInf(); + packet->mUserID = sInstance->mUserID; + strcpy(packet->hackName, tryConvertName(player->mHackKeeper->getCurrentHackName())); + sInstance->mSocket->queuePacket(packet); sInstance->isSentCaptureInf = true; } else if (!sInstance->isClientCaptured && sInstance->isSentCaptureInf) { - CaptureInf packet = CaptureInf(); - packet.mUserID = sInstance->mUserID; - strcpy(packet.hackName, ""); - sInstance->mSocket->SEND(&packet); + CaptureInf *packet = new CaptureInf(); + packet->mUserID = sInstance->mUserID; + strcpy(packet->hackName, ""); + sInstance->mSocket->queuePacket(packet); sInstance->isSentCaptureInf = false; } } @@ -769,14 +686,16 @@ void Client::sendShineCollectPacket(int shineID) { return; } + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); + if(sInstance->lastCollectedShine != shineID) { - ShineCollect packet = ShineCollect(); - packet.mUserID = sInstance->mUserID; - packet.shineId = shineID; + ShineCollect *packet = new ShineCollect(); + packet->mUserID = sInstance->mUserID; + packet->shineId = shineID; sInstance->lastCollectedShine = shineID; - sInstance->mSocket->SEND(&packet); + sInstance->mSocket->queuePacket(packet); } } @@ -1241,10 +1160,17 @@ void Client::updateShines() { { int shineID = sInstance->getShineID(i); - if (shineID >= 0) { - Shine* stageShine = findStageShine(shineID); + if(shineID < 0) continue; - if (!GameDataFunction::isGotShine(accessor, shineID)) { + Logger::log("Shine UID: %d\n", shineID); + + GameDataFile::HintInfo* shineInfo = CustomGameDataFunction::getHintInfoByUniqueID(accessor, shineID); + + if (shineInfo) { + if (!GameDataFunction::isGotShine(accessor, shineInfo->mStageName.cstr(), shineInfo->mObjId.cstr())) { + + Shine* stageShine = findStageShine(shineID); + if (stageShine) { if (al::isDead(stageShine)) { @@ -1253,30 +1179,31 @@ void Client::updateShines() { stageShine->getDirect(); stageShine->onSwitchGet(); - - accessor.mData->mGameDataFile->setGotShine(shineID); - - // TODO: add a system for displaying moon get layout when this runs - - } else { - accessor.mData->mGameDataFile->setGotShine(shineID); } + + accessor.mData->mGameDataFile->setGotShine(shineInfo); } } } sInstance->resetCollectedShines(); sInstance->mCurStageScene->mSceneLayout->startShineCountAnim(false); + sInstance->mCurStageScene->mSceneLayout->updateCounterParts(); // updates shine chip layout to (maybe) prevent softlocks } /** * @brief * */ -void Client::updateStates() { - if(sInstance) { +void Client::update() { + if (sInstance) { + sInstance->mPuppetHolder->update(); + if (isNeedUpdateShines()) { + updateShines(); + } + GameModeManager::instance()->update(); } } @@ -1425,9 +1352,15 @@ bool Client::tryRegisterShine(Shine* shine) { Shine* Client::findStageShine(int shineID) { if (sInstance) { for (int i = 0; i < sInstance->mShineArray.size(); i++) { + Shine* curShine = sInstance->mShineArray[i]; + if (curShine) { - if (curShine->shineId == shineID) { + + auto hintInfo = + CustomGameDataFunction::getHintInfoByIndex(curShine, curShine->mShineIdx); + + if (hintInfo->mUniqueID == shineID) { return curShine; } } diff --git a/source/server/SocketBase.cpp b/source/server/SocketBase.cpp index d36b8ef..4f82d95 100644 --- a/source/server/SocketBase.cpp +++ b/source/server/SocketBase.cpp @@ -6,8 +6,11 @@ SocketBase::SocketBase(const char *name) { strcpy(this->sockName, name); - +#if EMU this->sock_flags = 0x80; +#else + this->sock_flags = 0; +#endif } const char *SocketBase::getStateChar() { diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 8abc7e6..08d9349 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -1,14 +1,27 @@ #include "server/SocketClient.hpp" #include #include +#include #include "SocketBase.hpp" +#include "al/async/FunctorV0M.hpp" #include "logger.hpp" #include "nn/result.h" #include "nn/socket.h" #include "packets/Packet.h" +#include "server/Client.hpp" +#include "thread/seadMessageQueue.h" #include "types.h" +SocketClient::SocketClient(const char* name, sead::Heap* heap) : mHeap(heap), SocketBase(name) { + + mRecvThread = new al::AsyncFunctorThread("SocketRecvThread", al::FunctorV0M(this, &SocketClient::recvFunc), 0, 0x1000, {0}); + mSendThread = new al::AsyncFunctorThread("SocketSendThread", al::FunctorV0M(this, &SocketClient::sendFunc), 0, 0x1000, {0}); + + mRecvQueue.allocate(maxBufSize, mHeap); + mSendQueue.allocate(maxBufSize, mHeap); +}; + nn::Result SocketClient::init(const char* ip, u16 port) { this->sock_ip = ip; @@ -69,11 +82,28 @@ nn::Result SocketClient::init(const char* ip, u16 port) { Logger::log("Socket fd: %d\n", socket_log_socket); + startThreads(); // start recv and send threads after sucessful connection + + // send init packet to server once we connect (an issue with the server prevents this from working properly, waiting for a fix to implement) + + PlayerConnect initPacket; + initPacket.mUserID = Client::getClientId(); + strcpy(initPacket.clientName, Client::getUsername().cstr()); + + if (mIsFirstConnect) { + initPacket.conType = ConnectionTypes::INIT; + mIsFirstConnect = false; + } else { + initPacket.conType = ConnectionTypes::RECONNECT; + } + + send(&initPacket); + return result; } -bool SocketClient::SEND(Packet *packet) { +bool SocketClient::send(Packet *packet) { if (this->socket_log_state != SOCKET_LOG_CONNECTED) return false; @@ -90,18 +120,18 @@ bool SocketClient::SEND(Packet *packet) { } else { Logger::log("Failed to Fully Send Packet! Result: %d Type: %s Packet Size: %d\n", valread, packetNames[packet->mType], packet->mPacketSize); this->socket_errno = nn::socket::GetLastErrno(); - this->closeSocket(); + this->tryReconnect(); return false; } return true; } -bool SocketClient::RECV() { +bool SocketClient::recv() { if (this->socket_log_state != SOCKET_LOG_CONNECTED) { Logger::log("Unable To Receive! Socket Not Connected.\n"); this->socket_errno = nn::socket::GetLastErrno(); - return false; + return this->tryReconnect(); } int headerSize = sizeof(Packet); @@ -122,8 +152,7 @@ bool SocketClient::RECV() { return true; } else { Logger::log("Header Read Failed! Value: %d Total Read: %d\n", result, valread); - this->closeSocket(); - return false; + return this->tryReconnect(); // if we sucessfully reconnect, we dont want } } } @@ -146,9 +175,8 @@ bool SocketClient::RECV() { Logger::log(" Type String: %s\n", packetNames[header->mType]); Logger::enableName(); } - - char* packetBuf = (char*)malloc(fullSize); + char* packetBuf = (char*)mHeap->alloc(fullSize); if (packetBuf) { @@ -164,19 +192,18 @@ bool SocketClient::RECV() { if (result > 0) { valread += result; } else { - free(packetBuf); + mHeap->free(packetBuf); Logger::log("Packet Read Failed! Value: %d\nPacket Size: %d\nPacket Type: %s\n", result, header->mPacketSize, packetNames[header->mType]); - this->closeSocket(); - return false; + return this->tryReconnect(); } } - Packet *packet = reinterpret_cast(packetBuf); + Packet* packet = reinterpret_cast(packetBuf); - if(mPacketQueue.size() < maxBufSize - 1) { - mPacketQueue.pushBack(packet); + if (!mRecvQueue.isFull()) { + mRecvQueue.push((s64)packet, sead::MessageQueue::BlockType::NonBlocking); } else { - free(packetBuf); + mHeap->free(packetBuf); } } } else { @@ -187,8 +214,7 @@ bool SocketClient::RECV() { } else { // if we error'd, close the socket Logger::log("valread was zero! Disconnecting.\n"); this->socket_errno = nn::socket::GetLastErrno(); - this->closeSocket(); - return false; + return this->tryReconnect(); } } @@ -208,6 +234,20 @@ void SocketClient::printPacket(Packet *packet) { } } +bool SocketClient::tryReconnect() { + + Logger::log("Attempting to Reconnect.\n"); + + if (closeSocket()) { // unfortunately we cannot use the same fd from the previous connection, so close the socket entirely and attempt a new connection. + if (init(sock_ip, port).isSuccess()) { // call init again + Logger::log("Reconnect Successful.\n"); + return true; + } + } + + return false; +} + bool SocketClient::closeSocket() { Logger::log("Closing Socket.\n"); @@ -240,3 +280,81 @@ bool SocketClient::stringToIPAddress(const char* str, in_addr* out) { return false; } + +/** + * @brief starts client read thread + * + * @return true if read thread was sucessfully started + * @return false if read thread was unable to start, or thread was already started. + */ +bool SocketClient::startThreads() { + + Logger::log("Recv Thread isDone: %s\n", BTOC(this->mRecvThread->isDone())); + Logger::log("Send Thread isDone: %s\n", BTOC(this->mSendThread->isDone())); + + if(this->mRecvThread->isDone() && this->mSendThread->isDone()) { + this->mRecvThread->start(); + this->mSendThread->start(); + Logger::log("Socket threads sucessfully started.\n"); + return true; + }else { + Logger::log("Socket threads failed to start.\n"); + return false; + } +} + +void SocketClient::endThreads() { + mRecvThread->mDelegateThread->destroy(); + mSendThread->mDelegateThread->destroy(); +} + +void SocketClient::sendFunc() { + + Logger::log("Starting Send Thread.\n"); + + while (true) { + trySendQueue(); + } + + Logger::log("Ending Send Thread.\n"); +} + +void SocketClient::recvFunc() { + + nn::socket::Recv(this->socket_log_socket, nullptr, 0, 0); + + Logger::log("Starting Recv Thread.\n"); + + while (true) { + if (!recv()) { + Logger::log("Receiving Packet Failed!\n"); + } + } + + Logger::log("Ending Recv Thread.\n"); +} + +bool SocketClient::queuePacket(Packet* packet) { + if (socket_log_state == SOCKET_LOG_CONNECTED) { + mSendQueue.push((s64)packet, + sead::MessageQueue::BlockType::NonBlocking); // as this is non-blocking, it + // will always return true. + return true; + } else { + mHeap->free(packet); + return false; + } +} + +void SocketClient::trySendQueue() { + + Packet* curPacket = (Packet*)mSendQueue.pop(sead::MessageQueue::BlockType::Blocking); + + send(curPacket); + + mHeap->free(curPacket); +} + +Packet* SocketClient::tryGetPacket(sead::MessageQueue::BlockType blockType) { + return socket_log_state == SOCKET_LOG_CONNECTED ? (Packet*)mRecvQueue.pop(blockType) : nullptr; +} \ No newline at end of file diff --git a/source/server/gamemode/GameModeManager.cpp b/source/server/gamemode/GameModeManager.cpp index 2bb341b..680eb15 100644 --- a/source/server/gamemode/GameModeManager.cpp +++ b/source/server/gamemode/GameModeManager.cpp @@ -1,16 +1,19 @@ #include "server/gamemode/GameModeManager.hpp" #include -#include +#include +#include +#include #include "al/util.hpp" -#include "basis/seadNew.h" -#include "heap/seadHeapMgr.h" +#include "logger.hpp" #include "server/gamemode/GameModeBase.hpp" #include "server/gamemode/GameModeFactory.hpp" +#include "server/gamemode/modifiers/ModeModifierBase.hpp" +#include "server/gamemode/modifiers/ModifierFactory.hpp" SEAD_SINGLETON_DISPOSER_IMPL(GameModeManager) GameModeManager::GameModeManager() { - mHeap = sead::FrameHeap::create(0x100000, "GameModeHeap", al::getSequenceHeap(), 8, + mHeap = sead::ExpHeap::create(0x50000, "GameModeHeap", al::getSequenceHeap(), 8, sead::Heap::HeapDirection::cHeapDirection_Reverse, false); setMode(GameMode::HIDEANDSEEK); } @@ -84,6 +87,7 @@ void GameModeManager::initScene(const GameModeInitInfo& info) { } if (mCurModeBase) { + sead::ScopedCurrentHeapSetter heapSetter(GameModeManager::getSceneHeap()); mCurModeBase->init(*mLastInitInfo); if (mCurModeBase->isModeActive()) mWasSceneTrans = true; diff --git a/source/server/gamemode/modifiers/GravityModifier.cpp b/source/server/gamemode/modifiers/GravityModifier.cpp new file mode 100644 index 0000000..fd695af --- /dev/null +++ b/source/server/gamemode/modifiers/GravityModifier.cpp @@ -0,0 +1,46 @@ +#include "server/gamemode/modifiers/GravityModifier.hpp" +#include "helpers.hpp" +#include "math/seadVector.h" +#include "rs/util.hpp" + +GravityModifier::GravityModifier(GameModeBase* mode) : ModeModifierBase(mode) {} + +void GravityModifier::enable() { + ModeModifierBase::enable(); + if(mTicket && mScene) + al::startCamera(mScene, mTicket, -1); +} + +void GravityModifier::disable() { + ModeModifierBase::disable(); + if(mTicket && mScene) + al::endCamera(mScene, mTicket, -1, false); +} + +void GravityModifier::update() { + + sead::Vector3f gravity; + PlayerActorBase *playerBase = rs::getPlayerActor(mScene); + + if (rs::calcOnGroundNormalOrGravityDir(&gravity, playerBase, playerBase->getPlayerCollision())) { + gravity = -gravity; + al::normalize(&gravity); + al::setGravity(playerBase, gravity); + al::setGravity(((PlayerActorHakoniwa*)playerBase)->mHackCap, gravity); + } + + if (al::isPadHoldL(-1)) { + if (al::isPadTriggerRight(-1)) { + if (al::isActiveCamera(mTicket)) { + al::endCamera(mScene, mTicket, -1, false); + } else { + al::startCamera(mScene, mTicket, -1); + } + } + } else if (al::isPadTriggerZL(-1)) { + if (al::isPadTriggerLeft(-1)) { + killMainPlayer(((PlayerActorHakoniwa*)playerBase)); + } + } + +} \ No newline at end of file diff --git a/source/server/gamemode/modifiers/NoCapModifier.cpp b/source/server/gamemode/modifiers/NoCapModifier.cpp new file mode 100644 index 0000000..d1f60fe --- /dev/null +++ b/source/server/gamemode/modifiers/NoCapModifier.cpp @@ -0,0 +1,18 @@ +#include "server/gamemode/modifiers/NoCapModifier.hpp" +#include "game/GameData/GameDataFunction.h" +#include "server/gamemode/GameModeBase.hpp" +#include "game/GameData/GameDataHolderAccessor.h" +#include "helpers.hpp" +#include "math/seadVector.h" +#include "rs/util.hpp" +#include "server/gamemode/GameModeManager.hpp" + +NoCapModifier::NoCapModifier(GameModeBase* mode) : ModeModifierBase(mode) {} + +void NoCapModifier::enable() { + ModeModifierBase::enable(); +} + +void NoCapModifier::disable() { + ModeModifierBase::disable(); +} \ No newline at end of file diff --git a/source/server/hns/HideAndSeekMode.cpp b/source/server/hns/HideAndSeekMode.cpp index 0038c75..65e97c0 100644 --- a/source/server/hns/HideAndSeekMode.cpp +++ b/source/server/hns/HideAndSeekMode.cpp @@ -32,8 +32,6 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) { GameModeInfoBase* curGameInfo = GameModeManager::instance()->getInfo(); - sead::ScopedCurrentHeapSetter heapSetter(GameModeManager::instance()->getHeap()); - if (curGameInfo) Logger::log("Gamemode info found: %s %s\n", GameModeFactory::getModeString(curGameInfo->mMode), GameModeFactory::getModeString(info.mMode)); else Logger::log("No gamemode info found\n"); if (curGameInfo && curGameInfo->mMode == mMode) { @@ -74,6 +72,8 @@ void HideAndSeekMode::begin() { MapMini* compass = mCurScene->mSceneLayout->mMapMiniLyt; al::SimpleLayoutAppearWaitEnd* playGuideLyt = mCurScene->mSceneLayout->mPlayGuideMenuLyt; + mInvulnTime = 0; + if(coinCounter->mIsAlive) coinCounter->tryEnd(); if(coinCollect->mIsAlive) @@ -97,6 +97,8 @@ void HideAndSeekMode::end() { MapMini* compass = mCurScene->mSceneLayout->mMapMiniLyt; al::SimpleLayoutAppearWaitEnd* playGuideLyt = mCurScene->mSceneLayout->mPlayGuideMenuLyt; + mInvulnTime = 0.0f; + if(!coinCounter->mIsAlive) coinCounter->tryStart(); if(!coinCollect->mIsAlive)