Skip to content

Commit

Permalink
Implement SensorMsg related functions in al
Browse files Browse the repository at this point in the history
  • Loading branch information
LynxDev2 committed Feb 26, 2025
1 parent c2d0a22 commit 6da8aca
Show file tree
Hide file tree
Showing 7 changed files with 2,343 additions and 914 deletions.
1,814 changes: 907 additions & 907 deletions data/odyssey_functions.csv

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions lib/al/Library/Base/Macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,43 @@
#define FE_63(WHAT, X0, X1, ...) WHAT(X0, X1) FE_62(WHAT, X0, __VA_ARGS__)

#define FOR_EACH(action, x0, ...) VFUNC(FE_, __VA_ARGS__)(action, x0, __VA_ARGS__)

#define _FUNC_(name, n) name n

#define FOR_EACH_TUPL(action, ...) FOR_EACH(_FUNC_, action, __VA_ARGS__)

#define DECL_MEMBER_VAR(type, name)\
type m##name;

#define PARAM_END_COMMA(type, name)\
type p##name,

#define DECL_GET(type, name)\
type get##name() const {return m##name;}

#define POINTER_PARAM_END_COMMA(type, name)\
type * p##name,

#define PARAM_START_COMMA(type, name)\
, type p##name

#define CALL_PARAM_START_COMMA(_, name)\
, p##name

#define SET_MEMBER_PARAM(_, name)\
m##name = p##name;

#define SET_OUT_VAR_MEMBER(_, name)\
* p##name = m##name;

#define DECL_MEMBER_VAR_MULTI(...) FOR_EACH_TUPL(DECL_MEMBER_VAR, __VA_ARGS__)
#define DECL_GET_MULTI(...) FOR_EACH_TUPL(DECL_GET, __VA_ARGS__)

#define PARAM_LIST_END_COMMA(...) FOR_EACH_TUPL(PARAM_END_COMMA, __VA_ARGS__)
#define POINTER_PARAM_LIST_END_COMMA(...) FOR_EACH_TUPL(POINTER_PARAM_END_COMMA, __VA_ARGS__)
#define PARAM_LIST_START_COMMA(...) FOR_EACH_TUPL(PARAM_START_COMMA, __VA_ARGS__)
#define CALL_PARAM_LIST_START_COMMA(...) FOR_EACH_TUPL(CALL_PARAM_START_COMMA, __VA_ARGS__)

#define SET_MEMEBER_PARAM_MULTI(...) FOR_EACH_TUPL(SET_MEMBER_PARAM, __VA_ARGS__)
#define SET_OUT_VAR_MEMEBER_MULTI(...) FOR_EACH_TUPL(SET_OUT_VAR_MEMBER, __VA_ARGS__)

191 changes: 191 additions & 0 deletions lib/al/Library/HitSensor/SensorMsgSetupUtil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
#pragma once

#include <prim/seadRuntimeTypeInfo.h>

#include "Library/Base/Macros.h"
#include "Library/LiveActor/ActorSensorFunction.h"

namespace al{
class HitSensor;
class ComboCounter;

class SensorMsg {
SEAD_RTTI_BASE(SensorMsg);
};
}

/*
Declares a SensorMsg class
Creating a SensorMsg class called SenosorMsgTest:
SENSOR_MSG(Test);
*/

#define SENSOR_MSG(Type) \
class SensorMsg##Type : public al::SensorMsg { \
SEAD_RTTI_OVERRIDE(SensorMsg##Type, al::SensorMsg) \
inline SensorMsg##Type() = default; \
virtual ~SensorMsg##Type() = default; \
};

/*
Declares a SensorMsg class with data.
Creating a SensorMsg class called SenosorMsgTest2 that holds a string:
SENSOR_MSG_WITH_DATA(Test2, (const char*, str));
*/

#define SENSOR_MSG_WITH_DATA(Type, ...) \
class SensorMsg##Type : public al::SensorMsg { \
SEAD_RTTI_OVERRIDE(SensorMsg##Type, al::SensorMsg) \
public: \
inline SensorMsg##Type( PARAM_LIST_END_COMMA(__VA_ARGS__) void* _ = nullptr ){ \
SET_MEMEBER_PARAM_MULTI(__VA_ARGS__); \
} \
\
DECL_GET_MULTI(__VA_ARGS__); \
\
inline void extractData( POINTER_PARAM_LIST_END_COMMA(__VA_ARGS__) void* _ = nullptr ){ \
SET_OUT_VAR_MEMEBER_MULTI(__VA_ARGS__); \
} \
\
virtual ~SensorMsg##Type() = default; \
private: \
DECL_MEMBER_VAR_MULTI(__VA_ARGS__); \
};

//Use this in the edge cases where there's no macro to implement a specific type of isMsg
#define MSG_TYPE_CHECK_(Type, MsgVar) \
sead::IsDerivedFrom<SensorMsg##Type>(MsgVar)

//Helper macro passed into FOR_EACH, shouldn't be used directly
#define IS_MSG_MULTIPLE_PART_(_, Type) \
|| MSG_TYPE_CHECK_(Type, msg)

/*
Implements an isMsg function that checkes if the given message is one of multiple message types.
Implementing a function called isMsgTestAll that checks if the given message is of type SensorMsgTest or SensorMsgTest2:
IS_MSG_MULTIPLE_IMPL(TestAll, Test, Test2);
*/

#define IS_MSG_MULTIPLE_IMPL(Name, FirstType, ...) \
bool isMsg##Name(const al::SensorMsg* msg){ \
return sead::IsDerivedFrom<SensorMsg##FirstType>(msg) FOR_EACH(IS_MSG_MULTIPLE_PART_, _, __VA_ARGS__); \
}

/*
Implements an isMsg function that checks if the given message is of a specific message type.
Creating a function called isMsgX that checks if the message is of type SensorMsgTest2:
IS_MSG_IMPL_(X, Test2);
*/

#define IS_MSG_IMPL_(Name, Type) \
bool isMsg##Name(const al::SensorMsg* msg){ \
return sead::IsDerivedFrom<SensorMsg##Type>(msg); \
}

/*
Same as above, but the name of the isMsg function and the SensorMsg are the same.
Creating a function called isMsgTest that checks if the message is of type SensorMsgTest:
IS_MSG_IMPL(Test);
*/

#define IS_MSG_IMPL(Name) IS_MSG_IMPL_(Name, Name)

/*
Implements a sendMsg function that sends a message of the given type.
Creating a function called sendMsgX that sends a SensorMsgTest2:
SEND_MSG_IMPL_(X, Test2);
*/

#define SEND_MSG_IMPL_(Name, Type) \
bool sendMsg##Name(al::HitSensor* receiver, al::HitSensor* sender){ \
SensorMsg##Type msg; \
return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); \
}

/*
Implements a sendMsg function that sends a message of the given type to the first sensor of the actor passed in.
Creating a function called sendMsgX that sends a SensorMsgTest2 to the first sensor of the target actor:
SEND_MSG_TO_ACTOR_IMPL(X, Test2);
*/


#define SEND_MSG_TO_ACTOR_IMPL_(Name, Type) \
bool sendMsg##Name(al::LiveActor* actor){ \
SensorMsg##Type msg; \
return alActorSensorFunction::sendMsgToActorUnusedSensor(msg, actor); \
}

#define SEND_MSG_TO_ACTOR_IMPL(Name) SEND_MSG_TO_ACTOR_IMPL_(Name, Name)

/*
Same as above, but the name of the sendMsg function and the SensorMsg are the same.
Creating a function called sendMsgTest that sends a SensorMsgTest:
SEND_MSG_IMPL(Test);
*/

#define SEND_MSG_IMPL(Name) SEND_MSG_IMPL_(Name, Name)

/*
Implements a sendMsg function that takes in data of a specific type and sends a message of the given message type with the data.
Creating a function called sendMsgX that takes a const char* and sends a SensorMsgTest2 with that string:
SEND_MSG_DATA_IMPL(X, Test2, const char*);
*/

#define SEND_MSG_DATA_IMPL_(Name, Type, DataType) \
bool sendMsg##Name(al::HitSensor* receiver, al::HitSensor* sender, DataType data){ \
SensorMsg##Type msg(data); \
return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); \
}

//Same as SEND_MSG_TO_ACTOR_IMPL but also includes data like the macro above
#define SEND_MSG_DATA_TO_ACTOR_IMPL(Name, DataType) \
bool sendMsg##Name(al::LiveActor* actor, DataType data){ \
SensorMsg##Name msg(data); \
return alActorSensorFunction::sendMsgToActorUnusedSensor(msg, actor); \
}


//Same as above, but a shorter version
#define SEND_MSG_DATA_IMPL(Name, DataType) SEND_MSG_DATA_IMPL_(Name, Name, DataType)

/*
Similar to SEND_MSG_DATA_IMPL, but for sending a message with multiple different data fields.
Creating a function called sendMsgX that takes a const char* and and an int and sends a SensorMsgTest2 with that string and int:
SEND_MSG_DATA_IMPL(X, Test2, const char*, (int, Number));
NOTE: all fields after the first one need to be pairs of type and name.
*/

#define SEND_MSG_DATA_MULTI_IMPL_(Name, Type, FirstDataType, ...) \
bool sendMsg##Name(al::HitSensor* receiver, al::HitSensor* sender, FirstDataType pFirstData PARAM_LIST_START_COMMA(__VA_ARGS__)){ \
SensorMsg##Type msg(pFirstData CALL_PARAM_LIST_START_COMMA(__VA_ARGS__)); \
return alActorSensorFunction::sendMsgSensorToSensor(msg, sender, receiver); \
}

//Same as above, but a shorter version
#define SEND_MSG_DATA_MULTI_IMPL(Name, FirstDataType, ...) SEND_MSG_DATA_MULTI_IMPL_(Name, Name, FirstDataType, __VA_ARGS__)

//Shorter macros for messages that store a ComboCounter (There are 31 of them in al alone)
#define SENSOR_MSG_CBC(Name) SENSOR_MSG_WITH_DATA(Name, (al::ComboCounter*, ComboCounter))
#define SEND_MSG_CBC_IMPL_(Name, Type) SEND_MSG_DATA_IMPL_(Name, Type, al::ComboCounter*)
#define SEND_MSG_CBC_IMPL(Name) SEND_MSG_DATA_IMPL_(Name, Name, al::ComboCounter*)
Loading

0 comments on commit 6da8aca

Please sign in to comment.