Merge commit '4339847'

This commit is contained in:
Jack Garrard 2023-09-12 13:35:35 -07:00
commit 3570175752
79 changed files with 2754 additions and 523 deletions

View file

@ -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/

View file

@ -10,6 +10,10 @@ inputs:
description : 'filename prefix'
required : false
default : ''
emu:
description : 'what system the build is for: Switch, Ryujinx or yuzu'
required : false
default : 'Switch'
outputs:
@ -27,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)) || '' }}"
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
@ -49,13 +53,25 @@ 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 != '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/exefs/
rm -rf ./atmosphere/
-
name : Upload artifacts
uses : actions/upload-artifact@v3

View file

@ -20,6 +20,9 @@ on:
jobs:
build:
strategy:
matrix:
emu : [ Switch, Ryujinx, yuzu ]
runs-on: ubuntu-latest
steps:
-
@ -28,3 +31,5 @@ jobs:
-
name : Build artifacts
uses : ./.github/actions/build
with:
emu : ${{ matrix.emu }}

View file

@ -19,9 +19,14 @@ concurrency:
jobs:
build:
strategy:
matrix:
emu : [ Switch, Ryujinx, yuzu ]
runs-on: ubuntu-latest
outputs:
filename: ${{ steps.build.outputs.filename }}
filename1: ${{ steps.set-output.outputs.filename-Switch }}
filename2: ${{ steps.set-output.outputs.filename-Ryujinx }}
filename3: ${{ steps.set-output.outputs.filename-yuzu }}
steps:
-
name : Checkout
@ -31,13 +36,20 @@ 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
uses : ./.github/actions/build
with:
prefix : ${{ steps.env.outputs.prefix }}
emu : ${{ matrix.emu }}
-
name : Set output
id : set-output
shell : bash
run : |
echo "filename-${{ matrix.emu }}=${{ steps.build.outputs.filename }}" >>$GITHUB_OUTPUT
attach:
needs: build
@ -52,12 +64,26 @@ 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
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 (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 }}

View file

@ -12,9 +12,14 @@ on:
jobs:
build:
strategy:
matrix:
emu : [ Switch, Ryujinx, yuzu ]
runs-on: ubuntu-latest
outputs:
filename: ${{ steps.build.outputs.filename }}
filename1: ${{ steps.set-output.outputs.filename-Switch }}
filename2: ${{ steps.set-output.outputs.filename-Ryujinx }}
filename3: ${{ steps.set-output.outputs.filename-yuzu }}
steps:
-
name : Checkout
@ -25,6 +30,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 +53,23 @@ 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 (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 }}

1
.gitignore vendored
View file

@ -6,5 +6,6 @@ Crash Reports/**
.cache/**
Custom Stage Builds/**
*.lst
*.disabled
compile_commands.json

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -7,6 +7,7 @@
#include "RenderTargetColor.h"
#include "RenderTargetDepth.h"
#include "DrawContext.h"
#include "sead/gfx/seadFrameBuffer.h"

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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<SubActorInfo> mArray;
};

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,11 @@
#pragma once
namespace al {
struct ExecuteOrder
{
const char *mListName;
const char *mExecuteGroup;
int mListMaxSize;
const char *mGroupType;
};
}

View file

@ -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
};
}

View file

@ -0,0 +1,9 @@
#pragma once
#include "agl/DrawContext.h"
namespace al {
struct ExecuteSystemInitInfo {
agl::DrawContext *mDrawCtx;
};
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "ExecuteOrder.h"
namespace al {
struct ExecuteTable
{
const char *mName;
const al::ExecuteOrder* mExecuteOrders;
int mExecuteOrderCount;
};
}

View file

@ -0,0 +1,65 @@
#pragma once
#include <cstring>
#include <string_view>
#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<al::ExecutorListBase> mActiveExecutors;
sead::PtrArray<al::ExecutorListBase> mExecutorsAll;
sead::PtrArray<al::ExecutorListActorDraw> mExecutorsActor;
sead::PtrArray<al::ExecutorListActorModelDrawBase> mExecutorsActorModel;
sead::PtrArray<al::ExecutorListLayoutDrawBase> mExecutorsLayout;
sead::PtrArray<al::ExecutorListIUseExecutorDraw> mExecutorsUser;
sead::PtrArray<al::ExecutorListFunctor> mExecutorsFunctor;
};
}
extern "C" al::ExecuteTable gameDrawTable[]; // pointer to original draw table found in the exefs
extern const al::ExecuteTable drawTable[];
extern int drawTableSize;

View file

@ -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<al::ExecutorListBase> mActiveExecutors;
sead::PtrArray<al::ExecutorListBase> mExecutorsAll;
sead::PtrArray<al::ExecutorListActorExecuteBase> mExecutorsActor;
sead::PtrArray<al::ExecutorListLayoutUpdate> mExecutorsLayout;
sead::PtrArray<al::ExecutorListIUseExecutorUpdate> mExecutorsUser;
sead::PtrArray<al::ExecutorListFunctor> 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;

View file

@ -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;
};
}

View file

@ -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<al::UniformBlock> 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<float> 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;
};
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "types.h"
namespace al {
class UniformBlock {
UniformBlock();
~UniformBlock();
void swap();
};
}

View file

@ -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<float> const&);
void setModelProjMtx1(sead::Matrix44<float> const&);
void setModelProjMtx2(sead::Matrix44<float> const&);
void setModelProgProjMtx0(sead::Matrix44<float> const&);
void setModelProgProjMtx1(sead::Matrix44<float> const&);
void setModelProgProjMtx2(sead::Matrix44<float> const&);
void setModelProgProjMtx3(sead::Matrix44<float> 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<float> const*, sead::Matrix44<float> const*);
void getShapeObj(int) const;
};
}

View file

@ -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;
};
}

View file

@ -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*);
};
}

View file

@ -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
};
}

View file

@ -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");

View file

@ -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();
};
}

View file

@ -0,0 +1,48 @@
#pragma once
#include <heap/seadHeap.h>
#include <prim/seadSafeString.h>
#include <resource/seadArchiveRes.h>
#include <filedevice/seadArchiveFileDevice.h>
#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");

View file

@ -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;
};
};

View file

@ -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;
};
};

View file

@ -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;
};
}

View file

@ -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
{

17
include/al/util/KitUtil.h Normal file
View file

@ -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*);
}

View file

@ -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<float> const&);
void initActorPoseTR(al::LiveActor *,sead::Vector3<float> const&,sead::Vector3<float> const&);
void initActorPoseTR(al::LiveActor*, sead::Vector3<float> const&, sead::Vector3<float> 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<char> *,al::Resource const*,char const*,char const*);
bool tryGetActorInitFileIter(al::ByamlIter *,al::Resource const*,char const*,char const*);
bool tryGetActorInitFileIterAndName(al::ByamlIter *,sead::BufferedSafeStringBase<char> *,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*);

View file

@ -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*);
}

View file

@ -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;

View file

@ -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;

View file

@ -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);
};
};
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);
}
}

View file

@ -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;
};

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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);
};

View file

@ -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);

View file

@ -1,7 +1,48 @@
#pragma once
class WorldResourceLoader {
public:
void loadWorldResource(int,int,bool,char const *);
bool requestLoadWorldHomeStageResource(int worldIndex, int scenario);
};
#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");

View file

@ -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);

View file

@ -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",

View file

@ -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); }
};
};

View file

@ -11,6 +11,10 @@
namespace rs {
bool updateNormalStateExcludeGraphics(al::Scene*);
void updateEffectSystemEnv(al::Scene *);
bool isModeE3Rom(void);
bool isModeE3LiveRom(void);

View file

@ -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

View file

@ -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:

View file

@ -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 <cstddef>
#include <stdlib.h>
#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();
@ -104,16 +103,21 @@ 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; }
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 +130,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 +148,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 +206,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;
@ -221,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
@ -230,12 +237,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 +266,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 ---

View file

@ -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,58 @@
#include "syssocket/sockdefines.h"
#include "thread/seadMessageQueue.h"
#include "thread/seadMutex.h"
#include "types.h"
#include "packets/Packet.h"
class Client;
class SocketClient : public SocketBase {
public:
SocketClient(const char *name) : SocketBase(name) {
mPacketQueue = sead::PtrArray<Packet>();
mPacketQueue.tryAllocBuffer(maxBufSize, nullptr);
};
SocketClient(const char* name, sead::Heap* heap, Client* client);
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<Packet> 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;
Client* client = 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 +74,5 @@ class SocketClient : public SocketBase {
*/
bool stringToIPAddress(const char* str, in_addr* out);
};
typedef void (SocketClient::*SocketThreadFunc)(void);

View file

@ -3,8 +3,10 @@
#include <heap/seadDisposer.h>
#include <heap/seadHeap.h>
#include <container/seadSafeArray.h>
#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<class T>

View file

@ -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;
};

View file

@ -0,0 +1,24 @@
#pragma once
#include <cmath>
#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;
};

View file

@ -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 <class T>
ModeModifierBase* createModifier(GameModeBase* mode)
{
return new T(mode);
};
__attribute((used)) constexpr al::NameToCreator<createMod> modifierTable[] = {
{"Gravity", &createModifier<GravityModifier>},
{"NoCap", &createModifier<NoCapModifier>}
};
constexpr const char* modifierNames[] = {
"Sticky Gravity",
"Cappy-Less"
};
class ModifierFactory : public al::Factory<createMod> {
public:
ModifierFactory(const char *fName) {
this->factoryName = fName;
this->actorTable = modifierTable;
this->factoryCount = sizeof(modifierTable)/sizeof(modifierTable[0]);
};
};

View file

@ -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;
};

View file

@ -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;

View file

@ -1 +1,8 @@
_ZN14PlayerFunction20initMarioModelCommonEPN2al9LiveActorERKNS0_13ActorInitInfoEPKcS7_ibPNS0_11AudioKeeperEbb = 0x444028 - 0x2C63000;
_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;

View file

@ -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
// 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

View file

@ -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
// very wip stuff for implementing custom executors
// 4D1814 BL updateStateHook
// 87C90C BL updateDrawHook

View file

@ -0,0 +1,480 @@
#include <string_view>
#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, ""},
// ワールド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, ""},
{"[地形前]", "ActorModelDrawDeferred", 16, ""},
{"[地形前ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 16, ""},
{"プレイヤー[地形前]", "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, ""},
{"", "ActorModelDrawDeferred", 96, ""},
{"[ディファードのみ]", "ActorModelDrawDeferredOnly", 8, ""},
{"[ディファード不透明のみ]", "ActorModelDrawDeferredOpa", 8, ""},
{"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, ""},
{"[ディファード半透明]", "ActorModelDrawDeferredXlu", 8, ""},
{"[ディファード半透明のみ]", "ActorModelDrawDeferredXlu", 8, ""},
{"アイテム[ディファード半透明]", "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, ""},
{"[フォワード]", "ActorModelDraw", 32, ""},
{"[フォワードのみ]", "ActorModelDrawForwardOnly", 8, ""},
{"アイテム[フォワード]", "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, ""},
{"[インダイレクト]", "ActorModelDrawIndirect", 32, ""},
{"[インダイレクトのみ]", "ActorModelDrawIndirectOnly", 8, ""},
{"アイテム[インダイレクト]", "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, ""},
{"[フォグ後]", "ActorModelDraw", 8, ""},
{"[フォグ後のみ]", "ActorModelDrawForwardOnly", 8, ""},
// 3D(クロマキーZプリパス)
{"Zプリパス[プレイヤークロマキー]", "ActorModelDrawDepthChromakey", 208, "プレイヤー"},
{"Zプリパス[NPCクロマキー]", "ActorModelDrawDepthChromakey", 32, ""},
{"Zプリパス[ディザクロマキー]", "ActorModelDrawDitherChromakey", 208, "プレイヤー"},
// 3D(クロマキープレイヤー)
{"プレイヤー[クロマキー]", "ActorModelDrawPlayerChromakey", 208, "プレイヤー"},
{"プレイヤー[クロマキー不透明]", "ActorModelDrawPlayerChromakeyOpa", 208, "プレイヤー"},
{"プレイヤー[クロマキー半透明]", "ActorModelDrawPlayerChromakeyXlu", 64, "プレイヤー"},
// 3D(クロマキーキャラクター)
{"[クロマキー]", "ActorModelDrawCharacterChromakey", 32, ""},
// 2Dバック(メイン画面)
{"2Dバック", "LayoutDraw", 64, "レイアウト"},
// 2Dベース(メイン画面)
{"2Dベース", "LayoutDraw", 32, "レイアウト"},
{"2D情報バルーン", "LayoutDraw", 64, "レイアウト"},
{"2D会話バルーン", "LayoutDraw", 128, "レイアウト"},
{"", "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, "地形"},
{"", "ActorMovementCalcAnim", 64, ""},
{"NPC装飾", "ActorMovementCalcAnim", 32, ""},
{"帽子装着位置更新", "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, "システム"},
{"", "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("ワールド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", "[フォグ後のみ]", "ActorModelDrawForwardOnly"),
createDrawTable("3D(クロマキーZプリパス)", "Zプリパス[プレイヤークロマキー]", "ActorModelDrawDepthChromakey", "Zプリパス[ディザクロマキー]", "ActorModelDrawDitherChromakey"),
createDrawTable("3D(クロマキープレイヤー)", "プレイヤー[クロマキー]", "ActorModelDrawPlayerChromakey", "プレイヤー[クロマキー半透明]", "ActorModelDrawPlayerChromakeyXlu"),
createDrawTable("3D(クロマキーキャラクター)", "[クロマキー]", "ActorModelDrawCharacterChromakey", "[クロマキー]", "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]);

View file

@ -1,26 +1,23 @@
#include <sys/types.h>
#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);
}

View file

@ -1,9 +1,16 @@
#include "main.hpp"
#include <cmath>
#include <math.h>
#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);

View file

@ -1,6 +1,9 @@
#include <cmath>
#include <cstddef>
#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 = "";
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);
}

View file

@ -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

View file

@ -1,42 +1,10 @@
#include "server/Client.hpp"
#include <cmath>
#include <cstring>
#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<Client*, ClientThreadFunc>(this, &Client::readFunc), 0, 0x10000, {0});
mReadThread = new al::AsyncFunctorThread("ClientReadThread", al::FunctorV0M<Client*, ClientThreadFunc>(this, &Client::readFunc), 0, 0x1000, {0});
mKeyboard = new Keyboard(nn::swkbd::GetRequiredStringBufferSize());
mSocket = new SocketClient("SocketClient");
mSocket = new SocketClient("SocketClient", mHeap, this);
mPuppetHolder = new PuppetHolder(maxPuppets);
@ -103,17 +72,20 @@ 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);
}
/**
@ -122,17 +94,17 @@ void Client::init(al::LayoutInitInfo const &initInfo, GameDataHolderAccessor hol
* @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;
}
}
/**
* @brief restarts currently active connection to server
*
@ -144,13 +116,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,18 +138,11 @@ 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");
}
}
/**
* @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.
*
@ -216,27 +183,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 +245,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 +286,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 +305,102 @@ 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 we ever disconnect, reset all our values until we reconnect
if (curPacket) {
mConnectCount = 0;
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);
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__);
}
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
// Send relevant info packets when another client is connected
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);
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;
mSocket->send(&lastGameInfPacket);
}
free(curPacket);
// 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:
Logger::log("Discarding Unknown Packet Type.\n");
break;
}
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 +419,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 +435,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 +447,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,22 +467,24 @@ 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 +496,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,26 +543,30 @@ 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 && *packet != sInstance->emptyGameInfPacket) {
sInstance->lastGameInfPacket = *packet;
sInstance->mSocket->queuePacket(packet);
} else {
sInstance->mHeap->free(packet); // free packet if we're not using it
}
sInstance->lastGameInfPacket = packet;
}
/**
* @brief
* Sends only stage info to the server.
@ -663,19 +578,22 @@ 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;
if (*packet != sInstance->emptyGameInfPacket) {
sInstance->lastGameInfPacket = *packet;
sInstance->mSocket->queuePacket(packet);
}
}
/**
@ -689,6 +607,8 @@ void Client::sendTagInfPacket() {
return;
}
sead::ScopedCurrentHeapSetter setter(sInstance->mHeap);
HideAndSeekMode* hsMode = GameModeManager::instance()->getMode<HideAndSeekMode>();
if (!GameModeManager::instance()->isMode(GameMode::HIDEANDSEEK)) {
@ -698,17 +618,17 @@ void Client::sendTagInfPacket() {
HideAndSeekInfo* curInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
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>(TagUpdateType::STATE | TagUpdateType::TIME);
packet->minutes = curInfo->mHidingTime.mMinutes;
packet->seconds = curInfo->mHidingTime.mSeconds;
packet->updateType = static_cast<TagUpdateType>(TagUpdateType::STATE | TagUpdateType::TIME);
sInstance->mSocket->SEND(&packet);
sInstance->mSocket->queuePacket(packet);
}
/**
@ -723,11 +643,15 @@ void Client::sendCostumeInfPacket(const char* body, const char* cap) {
Logger::log("Static Instance is Null!\n");
return;
}
if (!strcmp(body, "") && !strcmp(cap, "")) { 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,22 +665,39 @@ 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;
}
}
/**
* @brief
*/
void Client::resendInitPackets() {
// CostumeInfPacket
if (lastCostumeInfPacket.mUserID == mUserID) {
mSocket->queuePacket(&lastCostumeInfPacket);
}
// GameInfPacket
if (lastGameInfPacket != emptyGameInfPacket) {
mSocket->queuePacket(&lastGameInfPacket);
}
}
/**
* @brief
*
@ -769,14 +710,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);
}
}
@ -939,6 +882,7 @@ void Client::updatePlayerConnect(PlayerConnect* packet) {
mConnectCount++;
}
}
/**
* @brief
*
@ -1241,10 +1185,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 +1204,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 +1377,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;
}
}

View file

@ -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() {

View file

@ -1,14 +1,29 @@
#include "server/SocketClient.hpp"
#include <cstdlib>
#include <cstring>
#include <basis/seadNew.h>
#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, Client* client) : mHeap(heap), SocketBase(name) {
this->client = client;
mRecvThread = new al::AsyncFunctorThread("SocketRecvThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(this, &SocketClient::recvFunc), 0, 0x1000, {0});
mSendThread = new al::AsyncFunctorThread("SocketSendThread", al::FunctorV0M<SocketClient*, SocketThreadFunc>(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 +84,33 @@ 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);
// on a reconnect, resend some maybe missing packets
if (initPacket.conType == ConnectionTypes::RECONNECT) {
client->resendInitPackets();
}
return result;
}
bool SocketClient::SEND(Packet *packet) {
bool SocketClient::send(Packet *packet) {
if (this->socket_log_state != SOCKET_LOG_CONNECTED)
return false;
@ -90,18 +127,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 +159,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 +182,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 +199,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<Packet*>(packetBuf);
Packet* packet = reinterpret_cast<Packet*>(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 +221,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 +241,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 +287,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;
}

View file

@ -1,16 +1,19 @@
#include "server/gamemode/GameModeManager.hpp"
#include <cstring>
#include <heap/seadFrameHeap.h>
#include <heap/seadExpHeap.h>
#include <basis/seadNew.h>
#include <heap/seadHeapMgr.h>
#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;

View file

@ -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));
}
}
}

View file

@ -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();
}

View file

@ -32,8 +32,6 @@ void HideAndSeekMode::init(const GameModeInitInfo& info) {
GameModeInfoBase* curGameInfo = GameModeManager::instance()->getInfo<HideAndSeekInfo>();
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)