From d4eabffff1281e8d00677049d1bff0705e2666a0 Mon Sep 17 00:00:00 2001 From: CraftyBoss Date: Sun, 4 Sep 2022 02:23:02 -0700 Subject: [PATCH 1/7] executor table re-impl, shine sync changes, send/recv netcode refactored --- .gitignore | 1 + MakefileNSO | 3 +- include/actors/PuppetActor.h | 6 + include/agl/RenderBuffer.h | 1 + include/al/LiveActor/LiveActor.h | 6 +- include/al/actor/ActorActionKeeper.h | 5 +- include/al/actor/ActorSceneInfo.h | 2 +- include/al/actor/SubActorKeeper.h | 10 +- include/al/area/ChangeStageInfo.h | 4 +- include/al/execute/ExecuteDirector.h | 42 +- include/al/execute/ExecuteOrder.h | 11 + include/al/execute/ExecuteRequestKeeper.h | 25 + include/al/execute/ExecuteSystemInitInfo.h | 9 + include/al/execute/ExecuteTable.h | 12 + include/al/execute/ExecuteTableHolderDraw.h | 65 +++ include/al/execute/ExecuteTableHolderUpdate.h | 58 ++ include/al/execute/ExecutorListBase.h | 15 + include/al/gfx/GraphicsSystemInfo.h | 193 +++++++ include/al/gfx/UniformBlock.h | 12 + include/al/model/ModelCtrl.h | 107 ++++ include/al/model/ModelKeeper.h | 46 ++ include/al/model/ModelMaterialCategory.h | 19 + include/al/model/PartsModel.h | 42 ++ include/al/resource/ActorResource.h | 35 ++ include/al/resource/ActorResourceHolder.h | 20 + include/al/resource/Resource.h | 48 ++ include/al/scene/Scene.h | 21 +- include/al/scene/SceneCreator.h | 2 +- include/al/sequence/Sequence.h | 51 +- include/al/util.hpp | 1 + include/al/util/KitUtil.h | 17 + include/al/util/LiveActorUtil.h | 23 +- include/al/util/ResourceUtil.h | 17 + include/game/Actors/Shine.h | 2 +- include/game/GameData/GameDataFile.h | 69 ++- include/game/GameData/GameDataFunction.h | 22 +- .../game/HakoniwaSequence/HakoniwaSequence.h | 97 ++-- include/game/Info/ShineInfo.h | 2 +- include/game/Player/PlayerActorBase.h | 2 +- include/game/Player/PlayerCostumeFunction.h | 9 + include/game/Player/PlayerFunction.h | 47 +- include/game/StageScene/StageSceneLayout.h | 2 +- include/game/WorldList/WorldResourceLoader.h | 51 +- include/helpers.hpp | 8 - include/main.hpp | 6 - include/rs/util.hpp | 4 + include/rs/util/LiveActorUtil.h | 4 +- include/sead/thread/seadMessageQueue.h | 5 + include/server/Client.hpp | 57 +- include/server/SocketClient.hpp | 50 +- include/server/gamemode/GameModeManager.hpp | 4 + .../gamemode/modifiers/GravityModifier.hpp | 18 + .../gamemode/modifiers/ModeModifierBase.hpp | 24 + .../gamemode/modifiers/ModifierFactory.hpp | 34 ++ .../gamemode/modifiers/NoCapModifier.hpp | 11 + include/types.h | 8 + linkerscripts/syms100.ld | 9 +- patches/codehook.slpatch | 14 +- patches/tests.slpatch | 8 +- source/al/execute/ExecuteTables.cpp | 480 ++++++++++++++++ source/hooks.cpp | 65 ++- source/main.cpp | 89 +-- source/puppets/PuppetActor.cpp | 222 +++++++- source/sead/seadNew.cpp | 8 +- source/server/Client.cpp | 521 ++++++++---------- source/server/SocketBase.cpp | 5 +- source/server/SocketClient.cpp | 152 ++++- source/server/gamemode/GameModeManager.cpp | 12 +- .../gamemode/modifiers/GravityModifier.cpp | 46 ++ .../gamemode/modifiers/NoCapModifier.cpp | 18 + source/server/hns/HideAndSeekMode.cpp | 6 +- 71 files changed, 2623 insertions(+), 497 deletions(-) create mode 100644 include/al/execute/ExecuteOrder.h create mode 100644 include/al/execute/ExecuteRequestKeeper.h create mode 100644 include/al/execute/ExecuteSystemInitInfo.h create mode 100644 include/al/execute/ExecuteTable.h create mode 100644 include/al/execute/ExecuteTableHolderDraw.h create mode 100644 include/al/execute/ExecuteTableHolderUpdate.h create mode 100644 include/al/execute/ExecutorListBase.h create mode 100644 include/al/gfx/GraphicsSystemInfo.h create mode 100644 include/al/gfx/UniformBlock.h create mode 100644 include/al/model/ModelCtrl.h create mode 100644 include/al/model/ModelKeeper.h create mode 100644 include/al/model/ModelMaterialCategory.h create mode 100644 include/al/model/PartsModel.h create mode 100644 include/al/resource/ActorResource.h create mode 100644 include/al/resource/ActorResourceHolder.h create mode 100644 include/al/resource/Resource.h create mode 100644 include/al/util/KitUtil.h create mode 100644 include/al/util/ResourceUtil.h create mode 100644 include/game/Player/PlayerCostumeFunction.h create mode 100644 include/server/gamemode/modifiers/GravityModifier.hpp create mode 100644 include/server/gamemode/modifiers/ModeModifierBase.hpp create mode 100644 include/server/gamemode/modifiers/ModifierFactory.hpp create mode 100644 include/server/gamemode/modifiers/NoCapModifier.hpp create mode 100644 source/al/execute/ExecuteTables.cpp create mode 100644 source/server/gamemode/modifiers/GravityModifier.cpp create mode 100644 source/server/gamemode/modifiers/NoCapModifier.cpp 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) From 65d6ffb4fc36dbeb9ac9af8cb3629c76c62696ac Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Mon, 5 Sep 2022 01:41:34 +0200 Subject: [PATCH 2/7] separate build for emulators --- .github/actions/attach/action.yml | 9 +++++++-- .github/actions/build/action.yml | 13 +++++++++---- .github/workflows/build.yml | 5 +++++ .github/workflows/dev-release.yml | 24 +++++++++++++++++++++--- .github/workflows/release.yml | 24 +++++++++++++++++++++--- docker-build.sh | 3 +++ 6 files changed, 66 insertions(+), 12 deletions(-) diff --git a/.github/actions/attach/action.yml b/.github/actions/attach/action.yml index cbcefea..536c759 100644 --- a/.github/actions/attach/action.yml +++ b/.github/actions/attach/action.yml @@ -27,7 +27,7 @@ runs: shell : bash run: | cd ./starlight_patch_100/ - zip -rmT9 ${{ inputs.filename }}.zip ./* + zip -rmT9 "${{ inputs.filename }}.zip" ./* - name : Attach to release uses : actions/upload-release-asset@v1 @@ -36,5 +36,10 @@ runs: with: upload_url : ${{ inputs.upload_url }} asset_path : ./starlight_patch_100/${{ inputs.filename }}.zip - asset_name : ${{ inputs.filename }}.zip + asset_name : "${{ inputs.filename }}.zip" asset_content_type : application/zip + - + name : Cleanup artifacts + shell : bash + run: | + rm -rf ./starlight_patch_100/ diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 0790503..78a7f1a 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -10,6 +10,10 @@ inputs: description : 'filename prefix' required : false default : '' + emu: + description : 'what system the build is for, Switch or Emulators' + required : false + default : 'Switch' outputs: @@ -28,7 +32,7 @@ runs: run: | VERS=${{ inputs.tag }} echo "::set-output name=version::${VERS:1}" - echo "::set-output name=filename::${{ inputs.prefix }}SMO_Online${{ (inputs.tag != '' && format('_{0}', inputs.tag)) || '' }}" + echo "::set-output name=filename::${{ inputs.prefix }}SMO_Online${{ (inputs.tag != '' && format('_{0}', inputs.tag)) || '' }}_for_${{ inputs.emu }}" - name : Set up Docker Buildx uses : docker/setup-buildx-action@v2 @@ -49,9 +53,10 @@ runs: name : Build mod shell : bash run: | - docker run --rm \ - -u `id -u`:`id -g` \ - -v "/$PWD/":/app/ \ + docker run --rm \ + -u `id -u`:`id -g` \ + -v "/$PWD/":/app/ \ + -e ISEMU=${{ (inputs.emu == 'Emulators' && '1') || '0' }} \ ${{ (steps.env.outputs.version != '' && format('-e BUILDVER={0}', steps.env.outputs.version)) || '' }} \ smoo-build-env \ ; diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 893e378..25259ca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,9 @@ on: jobs: build: + strategy: + matrix: + emu : [ Switch, Emulators ] runs-on: ubuntu-latest steps: - @@ -28,3 +31,5 @@ jobs: - name : Build artifacts uses : ./.github/actions/build + with: + emu : ${{ matrix.emu }} diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml index 4051a44..d8aea1a 100644 --- a/.github/workflows/dev-release.yml +++ b/.github/workflows/dev-release.yml @@ -19,9 +19,13 @@ concurrency: jobs: build: + strategy: + matrix: + emu : [ Switch, Emulators ] runs-on: ubuntu-latest outputs: - filename: ${{ steps.build.outputs.filename }} + filename1: ${{ steps.set-output.outputs.filename-Switch }} + filename2: ${{ steps.set-output.outputs.filename-Emulators }} steps: - name : Checkout @@ -38,6 +42,13 @@ jobs: uses : ./.github/actions/build with: prefix : ${{ steps.env.outputs.prefix }} + emu : ${{ matrix.emu }} + - + name : Set output + id : set-output + shell : bash + run : | + echo "::set-output name=filename-${{ matrix.emu }}::${{ steps.build.outputs.filename }}" attach: needs: build @@ -54,10 +65,17 @@ jobs: url=`curl -sS --fail ${{ github.api_url }}/repos/${{ github.repository }}/releases/tags/${{ env.TAG }} | jq .upload_url -r` echo "::set-output name=upload_url::$url" - - name : Attach build artifacts to release + name : Attach build artifacts to release (Switch) uses : ./.github/actions/attach with: - filename : ${{ needs.build.outputs.filename }} + filename : ${{ needs.build.outputs.filename1 }} + upload_url : ${{ steps.release.outputs.upload_url }} + GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} + - + name : Attach build artifacts to release (Emulators) + uses : ./.github/actions/attach + with: + filename : ${{ needs.build.outputs.filename2 }} upload_url : ${{ steps.release.outputs.upload_url }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3def7de..1d72252 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,9 +12,13 @@ on: jobs: build: + strategy: + matrix: + emu : [ Switch, Emulators ] runs-on: ubuntu-latest outputs: - filename: ${{ steps.build.outputs.filename }} + filename1: ${{ steps.set-output.outputs.filename-Switch }} + filename2: ${{ steps.set-output.outputs.filename-Emulators }} steps: - name : Checkout @@ -25,6 +29,13 @@ jobs: uses : ./.github/actions/build with: tag : ${{ github.ref_name }} + emu : ${{ matrix.emu }} + - + name : Set output + id : set-output + shell : bash + run : | + echo "::set-output name=filename-${{ matrix.emu }}::${{ steps.build.outputs.filename }}" release: needs: build @@ -41,9 +52,16 @@ jobs: tag : ${{ github.ref_name }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} - - name : Attach build artifacts to release + name : Attach build artifacts to release (Switch) uses : ./.github/actions/attach with: - filename : ${{ needs.build.outputs.filename }} + filename : ${{ needs.build.outputs.filename1 }} + upload_url : ${{ steps.release.outputs.upload_url }} + GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} + - + name : Attach build artifacts to release (Emulators) + uses : ./.github/actions/attach + with: + filename : ${{ needs.build.outputs.filename2 }} upload_url : ${{ steps.release.outputs.upload_url }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} diff --git a/docker-build.sh b/docker-build.sh index 4064e74..3bfb953 100755 --- a/docker-build.sh +++ b/docker-build.sh @@ -1,10 +1,13 @@ #!/bin/bash +ISEMU=${1:-0} + export DOCKER_BUILDKIT=1 docker build . -t smoo-client-build docker run --rm \ -u $(id -u):$(id -g) \ -v "/$PWD/":/app/ \ + -e ISEMU=${ISEMU} \ smoo-client-build \ ; docker rmi smoo-client-build From 36f9343f838505b2f933dccf40d16e303aa0e74c Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Mon, 5 Sep 2022 03:21:43 +0200 Subject: [PATCH 3/7] don't send empty GameInf and CostumeInf packets and resend them on reconnect Resend because: on server restarts the server will lose the stage and costume information. If only one client is connected to the server, the packets currently aren't resent, so the server doesn't know in which stage the client is and what costume it wears (which I'd like to display on the website). With more then one client connected it already works, because when another client joins the server, the client will send both packets. --- include/packets/GameInf.h | 4 +-- include/server/Client.hpp | 2 ++ include/server/SocketClient.hpp | 7 +++-- source/server/Client.cpp | 55 ++++++++++++++++++++++++--------- source/server/SocketClient.cpp | 11 +++++-- 5 files changed, 58 insertions(+), 21 deletions(-) diff --git a/include/packets/GameInf.h b/include/packets/GameInf.h index 34c5793..f435421 100644 --- a/include/packets/GameInf.h +++ b/include/packets/GameInf.h @@ -6,7 +6,7 @@ struct PACKED GameInf : Packet { GameInf() : Packet() {this->mType = PacketType::GAMEINF; mPacketSize = sizeof(GameInf) - sizeof(Packet);}; bool1 is2D = false; - u8 scenarioNo = -1; + u8 scenarioNo = 255; char stageName[0x40] = {}; bool operator==(const GameInf &rhs) const { @@ -19,4 +19,4 @@ struct PACKED GameInf : Packet { bool operator!=(const GameInf& rhs) const { return !operator==(rhs); } -}; \ No newline at end of file +}; diff --git a/include/server/Client.hpp b/include/server/Client.hpp index 16a2ca2..028fee9 100644 --- a/include/server/Client.hpp +++ b/include/server/Client.hpp @@ -103,6 +103,7 @@ class Client { static void sendShineCollectPacket(int shineId); static void sendTagInfPacket(); static void sendCaptureInfPacket(const PlayerActorHakoniwa *player); + void resendInitPackets(); int getCollectedShinesCount() { return curCollectedShines.size(); } int getShineID(int index) { if (index < curCollectedShines.size()) { return curCollectedShines[index]; } return -1; } @@ -226,6 +227,7 @@ class Client { // Backups for our last player/game packets, used for example to re-send them for newly connected clients PlayerInf lastPlayerInfPacket = PlayerInf(); GameInf lastGameInfPacket = GameInf(); + GameInf emptyGameInfPacket = GameInf(); CostumeInf lastCostumeInfPacket = CostumeInf(); Keyboard* mKeyboard = nullptr; // keyboard for setting server IP diff --git a/include/server/SocketClient.hpp b/include/server/SocketClient.hpp index 2f6dd74..217b292 100644 --- a/include/server/SocketClient.hpp +++ b/include/server/SocketClient.hpp @@ -20,9 +20,11 @@ #include "packets/Packet.h" +class Client; + class SocketClient : public SocketBase { public: - SocketClient(const char *name, sead::Heap *heap); + SocketClient(const char* name, sead::Heap* heap, Client* client); nn::Result init(const char* ip, u16 port) override; bool tryReconnect(); bool closeSocket() override; @@ -54,6 +56,7 @@ class SocketClient : public SocketBase { private: sead::Heap* mHeap = nullptr; + Client* client = nullptr; al::AsyncFunctorThread* mRecvThread = nullptr; al::AsyncFunctorThread* mSendThread = nullptr; @@ -72,4 +75,4 @@ class SocketClient : public SocketBase { bool stringToIPAddress(const char* str, in_addr* out); }; -typedef void (SocketClient::*SocketThreadFunc)(void); \ No newline at end of file +typedef void (SocketClient::*SocketThreadFunc)(void); diff --git a/source/server/Client.cpp b/source/server/Client.cpp index 9f8f1c4..4457ef0 100644 --- a/source/server/Client.cpp +++ b/source/server/Client.cpp @@ -27,7 +27,7 @@ Client::Client() { mKeyboard = new Keyboard(nn::swkbd::GetRequiredStringBufferSize()); - mSocket = new SocketClient("SocketClient", mHeap); + mSocket = new SocketClient("SocketClient", mHeap, this); mPuppetHolder = new PuppetHolder(maxPuppets); @@ -87,6 +87,7 @@ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor hol Logger::log("Heap Free Size: %f/%f\n", mHeap->getFreeSize() * 0.001f, mHeap->getSize() * 0.001f); } + /** * @brief starts client read thread * @@ -103,6 +104,7 @@ bool Client::startThread() { return false; } } + /** * @brief restarts currently active connection to server * @@ -140,6 +142,7 @@ void Client::restartConnection() { Logger::log("Reconnect Unsuccessful.\n"); } } + /** * @brief starts a connection using client's TCP socket class, pulling up the software keyboard for user inputted IP if save file does not have one saved. * @@ -346,16 +349,18 @@ void Client::readFunc() { // 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); + if (lastGameInfPacket != emptyGameInfPacket) { + // 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); + // 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: @@ -479,6 +484,7 @@ void Client::sendPlayerInfPacket(const PlayerActorBase *playerBase, bool isYukim } } + /** * @brief sends info related to player's cap actor to server * @@ -553,14 +559,14 @@ void Client::sendGameInfPacket(const PlayerActorHakoniwa* player, GameDataHolder strcpy(packet->stageName, GameDataFunction::getCurrentStageName(holder)); - if(*packet != sInstance->lastGameInfPacket) { + if (*packet != sInstance->lastGameInfPacket && *packet != sInstance->emptyGameInfPacket) { sInstance->lastGameInfPacket = *packet; sInstance->mSocket->queuePacket(packet); } else { sInstance->mHeap->free(packet); // free packet if we're not using it } - } + /** * @brief * Sends only stage info to the server. @@ -584,9 +590,10 @@ void Client::sendGameInfPacket(GameDataHolderAccessor holder) { strcpy(packet->stageName, GameDataFunction::getCurrentStageName(holder)); - sInstance->lastGameInfPacket = *packet; - - sInstance->mSocket->queuePacket(packet); + if (*packet != sInstance->emptyGameInfPacket) { + sInstance->lastGameInfPacket = *packet; + sInstance->mSocket->queuePacket(packet); + } } /** @@ -637,6 +644,8 @@ void Client::sendCostumeInfPacket(const char* body, const char* cap) { return; } + if (!strcmp(body, "") && !strcmp(cap, "")) { return; } + sead::ScopedCurrentHeapSetter setter(sInstance->mHeap); CostumeInf *packet = new CostumeInf(body, cap); @@ -674,6 +683,21 @@ void Client::sendCaptureInfPacket(const PlayerActorHakoniwa* player) { } } +/** + * @brief + */ +void Client::resendInitPackets() { + // CostumeInfPacket + if (lastCostumeInfPacket.mUserID == mUserID) { + mSocket->queuePacket(&lastCostumeInfPacket); + } + + // GameInfPacket + if (lastGameInfPacket != emptyGameInfPacket) { + mSocket->queuePacket(&lastGameInfPacket); + } +} + /** * @brief * @@ -858,6 +882,7 @@ void Client::updatePlayerConnect(PlayerConnect* packet) { mConnectCount++; } } + /** * @brief * diff --git a/source/server/SocketClient.cpp b/source/server/SocketClient.cpp index 08d9349..2389cc7 100644 --- a/source/server/SocketClient.cpp +++ b/source/server/SocketClient.cpp @@ -13,7 +13,9 @@ #include "thread/seadMessageQueue.h" #include "types.h" -SocketClient::SocketClient(const char* name, sead::Heap* heap) : mHeap(heap), SocketBase(name) { +SocketClient::SocketClient(const char* name, sead::Heap* heap, Client* client) : mHeap(heap), SocketBase(name) { + + this->client = client; 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}); @@ -99,6 +101,11 @@ nn::Result SocketClient::init(const char* ip, u16 port) { send(&initPacket); + // on a reconnect, resend some maybe missing packets + if (initPacket.conType == ConnectionTypes::RECONNECT) { + client->resendInitPackets(); + } + return result; } @@ -357,4 +364,4 @@ void SocketClient::trySendQueue() { 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 +} From 6a5b5146b8848d9be5c62a3fb6e09fe7a950a73f Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Fri, 21 Oct 2022 00:04:08 +0200 Subject: [PATCH 4/7] use devkitpro docker image installing it via pacman everytime is unsupported and will lead to http 403 errors. --- Dockerfile | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7cf9951..b2f0afa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,13 @@ -FROM ubuntu:20.04 as builder +FROM devkitpro/devkita64:latest as builder # install dependencies RUN apt-get update \ && apt-get install -y \ - curl \ - apt-transport-https \ python3 \ python3-pip \ - && pip install keystone-engine \ -; - -# install devkitpro -RUN ln -s /proc/self/mounts /etc/mtab \ - && mkdir /devkitpro/ \ - && echo "deb [signed-by=/devkitpro/pub.gpg] https://apt.devkitpro.org stable main" >/etc/apt/sources.list.d/devkitpro.list \ - && curl --fail -o /devkitpro/pub.gpg https://apt.devkitpro.org/devkitpro-pub.gpg \ - && apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y devkitpro-pacman \ - && dkp-pacman --noconfirm -S switch-dev \ + && pip3 install keystone-engine \ ; WORKDIR /app/ -ENV DEVKITPRO /opt/devkitpro ENTRYPOINT make From 7f6df57f4ac0d870ee2f6057f7eaf406cd876387 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Fri, 21 Oct 2022 00:06:52 +0200 Subject: [PATCH 5/7] patch out deprecated ::set-output ::set-output currently triggers deprecation warnings and will stop working at 2023-06-01. https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ --- .github/actions/build/action.yml | 4 ++-- .github/workflows/dev-release.yml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 78a7f1a..5aa2a0a 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -31,8 +31,8 @@ runs: shell : bash run: | VERS=${{ inputs.tag }} - echo "::set-output name=version::${VERS:1}" - echo "::set-output name=filename::${{ inputs.prefix }}SMO_Online${{ (inputs.tag != '' && format('_{0}', inputs.tag)) || '' }}_for_${{ inputs.emu }}" + echo "version=${VERS:1}" >>$GITHUB_OUTPUT + echo "filename=${{ inputs.prefix }}SMO_Online${{ (inputs.tag != '' && format('_{0}', inputs.tag)) || '' }}_for_${{ inputs.emu }}" >>$GITHUB_OUTPUT - name : Set up Docker Buildx uses : docker/setup-buildx-action@v2 diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml index d8aea1a..92bb0aa 100644 --- a/.github/workflows/dev-release.yml +++ b/.github/workflows/dev-release.yml @@ -35,7 +35,7 @@ jobs: id : env shell : bash run: | - echo "::set-output name=prefix::$(date +'%Y%m%d_%H%M%S_' --utc)" + echo "prefix=$(date +'%Y%m%d_%H%M%S_' --utc)" >>$GITHUB_OUTPUT - name : Build artifacts id : build @@ -48,7 +48,7 @@ jobs: id : set-output shell : bash run : | - echo "::set-output name=filename-${{ matrix.emu }}::${{ steps.build.outputs.filename }}" + echo "filename-${{ matrix.emu }}=${{ steps.build.outputs.filename }}" >>$GITHUB_OUTPUT attach: needs: build @@ -63,7 +63,7 @@ jobs: shell : bash run: | url=`curl -sS --fail ${{ github.api_url }}/repos/${{ github.repository }}/releases/tags/${{ env.TAG }} | jq .upload_url -r` - echo "::set-output name=upload_url::$url" + echo "upload_url=$url" >>$GITHUB_OUTPUT - name : Attach build artifacts to release (Switch) uses : ./.github/actions/attach From f60fc956d638a555a14027dc595e8c150d12cfc2 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Fri, 21 Oct 2022 00:08:09 +0200 Subject: [PATCH 6/7] for Emulators => for Ryujinx & for yuzu --- .github/actions/build/action.yml | 15 +++++++++++++-- .github/workflows/build.yml | 2 +- .github/workflows/dev-release.yml | 14 +++++++++++--- .github/workflows/release.yml | 14 +++++++++++--- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 5aa2a0a..1524ee4 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -11,7 +11,7 @@ inputs: required : false default : '' emu: - description : 'what system the build is for, Switch or Emulators' + description : 'what system the build is for: Switch, Ryujinx or yuzu' required : false default : 'Switch' @@ -56,11 +56,22 @@ runs: docker run --rm \ -u `id -u`:`id -g` \ -v "/$PWD/":/app/ \ - -e ISEMU=${{ (inputs.emu == 'Emulators' && '1') || '0' }} \ + -e ISEMU=${{ (inputs.emu != 'Switch' && '1') || '0' }} \ ${{ (steps.env.outputs.version != '' && format('-e BUILDVER={0}', steps.env.outputs.version)) || '' }} \ smoo-build-env \ ; cp -r ./romfs/ ./starlight_patch_100/atmosphere/contents/0100000000010000/. + - + name : Yuzu + shell : bash + if : ${{ inputs.emu == 'yuzu' }} + run: | + cd ./starlight_patch_100/ + mkdir ./SMOO/ + mv ./atmosphere/contents/0100000000010000/exefs ./SMOO/exefs + mv ./atmosphere/contents/0100000000010000/romfs ./SMOO/romfs + mv ./atmosphere/exefs_patches/StarlightBase/3CA12DFAAF9C82DA064D1698DF79CDA1.ips ./SMOO/romfs/ + rm -rf ./atmosphere/ - name : Upload artifacts uses : actions/upload-artifact@v3 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25259ca..76179ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: build: strategy: matrix: - emu : [ Switch, Emulators ] + emu : [ Switch, Ryujinx, yuzu ] runs-on: ubuntu-latest steps: - diff --git a/.github/workflows/dev-release.yml b/.github/workflows/dev-release.yml index 92bb0aa..000ffea 100644 --- a/.github/workflows/dev-release.yml +++ b/.github/workflows/dev-release.yml @@ -21,11 +21,12 @@ jobs: build: strategy: matrix: - emu : [ Switch, Emulators ] + emu : [ Switch, Ryujinx, yuzu ] runs-on: ubuntu-latest outputs: filename1: ${{ steps.set-output.outputs.filename-Switch }} - filename2: ${{ steps.set-output.outputs.filename-Emulators }} + filename2: ${{ steps.set-output.outputs.filename-Ryujinx }} + filename3: ${{ steps.set-output.outputs.filename-yuzu }} steps: - name : Checkout @@ -72,12 +73,19 @@ jobs: upload_url : ${{ steps.release.outputs.upload_url }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} - - name : Attach build artifacts to release (Emulators) + name : Attach build artifacts to release (Ryujinx) uses : ./.github/actions/attach with: filename : ${{ needs.build.outputs.filename2 }} upload_url : ${{ steps.release.outputs.upload_url }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} + - + name : Attach build artifacts to release (yuzu) + uses : ./.github/actions/attach + with: + filename : ${{ needs.build.outputs.filename3 }} + upload_url : ${{ steps.release.outputs.upload_url }} + GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} move: needs: attach diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d72252..859a4d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,11 +14,12 @@ jobs: build: strategy: matrix: - emu : [ Switch, Emulators ] + emu : [ Switch, Ryujinx, yuzu ] runs-on: ubuntu-latest outputs: filename1: ${{ steps.set-output.outputs.filename-Switch }} - filename2: ${{ steps.set-output.outputs.filename-Emulators }} + filename2: ${{ steps.set-output.outputs.filename-Ryujinx }} + filename3: ${{ steps.set-output.outputs.filename-yuzu }} steps: - name : Checkout @@ -59,9 +60,16 @@ jobs: upload_url : ${{ steps.release.outputs.upload_url }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} - - name : Attach build artifacts to release (Emulators) + name : Attach build artifacts to release (Ryujinx) uses : ./.github/actions/attach with: filename : ${{ needs.build.outputs.filename2 }} upload_url : ${{ steps.release.outputs.upload_url }} GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} + - + name : Attach build artifacts to release (yuzu) + uses : ./.github/actions/attach + with: + filename : ${{ needs.build.outputs.filename3 }} + upload_url : ${{ steps.release.outputs.upload_url }} + GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} From 4339847da55fa232f22f2f81c77aff4119ed7180 Mon Sep 17 00:00:00 2001 From: "Robin C. Ladiges" Date: Fri, 16 Dec 2022 23:21:07 +0100 Subject: [PATCH 7/7] fix yuzu build Accidentially moved it into the wrong directory. --- .github/actions/build/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index 1524ee4..ec64178 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -70,7 +70,7 @@ runs: mkdir ./SMOO/ mv ./atmosphere/contents/0100000000010000/exefs ./SMOO/exefs mv ./atmosphere/contents/0100000000010000/romfs ./SMOO/romfs - mv ./atmosphere/exefs_patches/StarlightBase/3CA12DFAAF9C82DA064D1698DF79CDA1.ips ./SMOO/romfs/ + mv ./atmosphere/exefs_patches/StarlightBase/3CA12DFAAF9C82DA064D1698DF79CDA1.ips ./SMOO/exefs/ rm -rf ./atmosphere/ - name : Upload artifacts