diff --git a/include/Kyoto/Animation/CAnimSysContext.hpp b/include/Kyoto/Animation/CAnimSysContext.hpp new file mode 100644 index 0000000..af47c6c --- /dev/null +++ b/include/Kyoto/Animation/CAnimSysContext.hpp @@ -0,0 +1,24 @@ +#ifndef _CANIMSYSCONTEXT +#define _CANIMSYSCONTEXT + +#include "Kyoto/TToken.hpp" + +#include "rstl/rc_ptr.hpp" + +class CTransitionDatabaseGame; +class CRandom16; +class CSimplePool; + +class CAnimSysContext { +public: + CAnimSysContext(const TToken< CTransitionDatabaseGame >& transDb, + const rstl::ncrc_ptr< CRandom16 >& random, CSimplePool& store) + : x0_transDb(transDb), x8_random(random), xc_store(store) {} + +private: + TToken< CTransitionDatabaseGame > x0_transDb; + rstl::rc_ptr< CRandom16 > x8_random; + CSimplePool& xc_store; +}; + +#endif // _CANIMSYSCONTEXT diff --git a/include/Kyoto/Animation/CAnimTreeNode.hpp b/include/Kyoto/Animation/CAnimTreeNode.hpp new file mode 100644 index 0000000..5b41ada --- /dev/null +++ b/include/Kyoto/Animation/CAnimTreeNode.hpp @@ -0,0 +1,14 @@ +#ifndef _CANIMTREENODE +#define _CANIMTREENODE + +#include "Kyoto/Animation/IAnimReader.hpp" + +class CAnimTreeNode : public IAnimReader { +public: + virtual CAnimTreeEffectiveContribution VGetContributionOfHighestInfluence() const = 0; + CAnimTreeEffectiveContribution GetContributionOfHighestInfluence() const { + return VGetContributionOfHighestInfluence(); + } +}; + +#endif // _CANIMTREENODE diff --git a/include/Kyoto/Animation/CAnimation.hpp b/include/Kyoto/Animation/CAnimation.hpp new file mode 100644 index 0000000..7e37cff --- /dev/null +++ b/include/Kyoto/Animation/CAnimation.hpp @@ -0,0 +1,20 @@ +#ifndef _CANIMATION +#define _CANIMATION + +#include "rstl/rc_ptr.hpp" +#include "rstl/string.hpp" + +class IMetaAnim; +class CInputStream; + +class CAnimation { +public: + CAnimation(CInputStream& in); + const rstl::rc_ptr< IMetaAnim >& GetMetaAnim() const { return x10_anim; } + +private: + rstl::string x0_name; + rstl::rc_ptr< IMetaAnim > x10_anim; +}; + +#endif // _CANIMATION diff --git a/include/Kyoto/Animation/CAnimationManager.hpp b/include/Kyoto/Animation/CAnimationManager.hpp new file mode 100644 index 0000000..64417d6 --- /dev/null +++ b/include/Kyoto/Animation/CAnimationManager.hpp @@ -0,0 +1,17 @@ +#ifndef _CANIMATIONMANAGER +#define _CANIMATIONMANAGER + +#include "Kyoto/TToken.hpp" + + +class CAnimationManager { +public: + //CAnimationManager(const TToken& animDB, const CAnimSysContext& sysCtx); + +private: + //TToken< CAnimationDatabase > x0_animDB; + //CAnimSysContext x8_sysCtx; +}; + + +#endif // _CANIMATIONMANAGER diff --git a/include/Kyoto/Animation/CBoolPOINode.hpp b/include/Kyoto/Animation/CBoolPOINode.hpp new file mode 100644 index 0000000..9efb310 --- /dev/null +++ b/include/Kyoto/Animation/CBoolPOINode.hpp @@ -0,0 +1,21 @@ +#ifndef _CBOOLPOINODE +#define _CBOOLPOINODE + +#include "Kyoto/Animation/CPOINode.hpp" + +class CBoolPOINode : public CPOINode { +public: + CBoolPOINode(rstl::string name, ushort type, const CCharAnimTime& time, int index, bool unique, + float weight, int charIdx, int flags, bool value); + // : CPOINode(name, type, time, index, unique, weight, charIdx, flags), x38_val(value) {} + + CBoolPOINode(CInputStream& in); + static CBoolPOINode CopyNodeMinusStartTime(const CBoolPOINode& node, + const CCharAnimTime& startTime); + bool GetValue() const { return x38_val; } + +private: + bool x38_val; +}; + +#endif // _CBOOLPOINODE diff --git a/include/Kyoto/Animation/CCharAnimMemoryMetrics.hpp b/include/Kyoto/Animation/CCharAnimMemoryMetrics.hpp new file mode 100644 index 0000000..db2de52 --- /dev/null +++ b/include/Kyoto/Animation/CCharAnimMemoryMetrics.hpp @@ -0,0 +1,17 @@ +#ifndef _CCHARANIMMEMORYMETRICS +#define _CCHARANIMMEMORYMETRICS + +#include + +class CCharAnimMemoryMetrics { +public: + enum EAnimSubSystem { + kASS_Zero, + kASS_One, + kASS_Two, + }; + + static void AddToTotalSize(uint size, EAnimSubSystem subSystem); +}; + +#endif // _CCHARANIMMEMORYMETRICS diff --git a/include/Kyoto/Animation/CCharAnimTime.hpp b/include/Kyoto/Animation/CCharAnimTime.hpp new file mode 100644 index 0000000..bc2aad7 --- /dev/null +++ b/include/Kyoto/Animation/CCharAnimTime.hpp @@ -0,0 +1,47 @@ +#ifndef _CCHARANIMTIME +#define _CCHARANIMTIME + +#include "types.h" + +class COutputStream; +class CInputStream; +class CCharAnimTime { +public: + enum EType { + kT_NonZero, + kT_ZeroIncreasing, + kT_ZeroSteady, + kT_ZeroDecreasing, + kT_Infinity, + }; + float GetSeconds() const { return x0_time; } + + explicit CCharAnimTime(CInputStream& in); + explicit CCharAnimTime(float time); + explicit CCharAnimTime(EType type, float time) : x0_time(time), x4_type(type) {} + CCharAnimTime(const CCharAnimTime& other) : x0_time(other.x0_time), x4_type(other.x4_type) {} + + bool operator>(const CCharAnimTime& other) const; + bool operator==(const CCharAnimTime& other) const; + bool operator!=(const CCharAnimTime& other) const; + bool operator<(const CCharAnimTime& other) const; + float operator/(const CCharAnimTime& other) const; + float operator*(const float& other) const; + CCharAnimTime operator-(const CCharAnimTime& other) const; + CCharAnimTime operator+(const CCharAnimTime& other) const; + const CCharAnimTime& operator+=(const CCharAnimTime& other); + const CCharAnimTime& operator-=(const CCharAnimTime& other); + bool operator<=(const CCharAnimTime& other) const; + bool operator>=(const CCharAnimTime& other) const; + bool GreaterThanZero() const; + bool EqualsZero() const; + void PutTo(COutputStream& out) const; + static CCharAnimTime Infinity() { return CCharAnimTime(kT_Infinity, 1.0f); } + +private: + float x0_time; + EType x4_type; +}; +CHECK_SIZEOF(CCharAnimTime, 0x8) + +#endif // _CCHARANIMTIME diff --git a/include/Kyoto/Animation/CCharacterInfo.hpp b/include/Kyoto/Animation/CCharacterInfo.hpp new file mode 100644 index 0000000..2dc39b2 --- /dev/null +++ b/include/Kyoto/Animation/CCharacterInfo.hpp @@ -0,0 +1,47 @@ +#ifndef _CCHARACTERINFO +#define _CCHARACTERINFO + +#include "types.h" + +#include "Kyoto/Animation/CEffectComponent.hpp" + +#include "Kyoto/Animation/CPASDatabase.hpp" +#include "Kyoto/IObjectStore.hpp" +#include "Kyoto/Math/CAABox.hpp" + +#include "rstl/pair.hpp" +#include "rstl/string.hpp" +#include "rstl/vector.hpp" + +class CCharacterInfo { +public: + class CParticleResData { + private: + rstl::vector< CAssetId > x0_part; + rstl::vector< CAssetId > x10_swhc; + rstl::vector< CAssetId > x20_elsc; + rstl::vector< CAssetId > x30_elsc; + }; + + const CPASDatabase& GetPASDatabase() const { return x30_pasDatabase; } + const rstl::vector< rstl::pair< rstl::string, CAABox > >& GetAnimBBoxList() const { return x88_aabbs; } + +private: + ushort x0_tableCount; + rstl::string x4_name; + CAssetId x14_cmdl; + CAssetId x18_cksr; + CAssetId x1c_cinf; + rstl::vector< rstl::pair< int, rstl::pair< rstl::string, rstl::string > > > x20_animInfo; + CPASDatabase x30_pasDatabase; + CParticleResData x44_partRes; + uint x84_unk; + rstl::vector< rstl::pair< rstl::string, CAABox > > x88_aabbs; + rstl::vector< rstl::pair< rstl::string, rstl::vector< CEffectComponent > > > x98_effects; + uint xa8_cmdlOverlay; + uint xac_cksrOverlay; + rstl::vector< int > xb0_animIdxs; +}; +CHECK_SIZEOF(CCharacterInfo, 0xc0) + +#endif // _CCHARACTERINFO diff --git a/include/Kyoto/Animation/CEffectComponent.hpp b/include/Kyoto/Animation/CEffectComponent.hpp new file mode 100644 index 0000000..e61f0dd --- /dev/null +++ b/include/Kyoto/Animation/CEffectComponent.hpp @@ -0,0 +1,18 @@ +#ifndef _CEFFECTCOMPONENT +#define _CEFFECTCOMPONENT + +#include "types.h" + +#include "Kyoto/Particles/CParticleData.hpp" + +class CEffectComponent { +private: + rstl::string x0_name; + SObjectTag x10_tag; + rstl::string x18_boneName; + float x28_scale; + CParticleData::EParentedMode x2c_parentedMode; + uint x30_flags; +}; + +#endif // _CEFFECTCOMPONENT diff --git a/include/Kyoto/Animation/CHalfTransition.hpp b/include/Kyoto/Animation/CHalfTransition.hpp new file mode 100644 index 0000000..d068833 --- /dev/null +++ b/include/Kyoto/Animation/CHalfTransition.hpp @@ -0,0 +1,17 @@ +#ifndef _CHALFTRANSITION +#define _CHALFTRANSITION + +#include "rstl/rc_ptr.hpp" + +class IMetaTrans; +class CInputStream; +class CHalfTransition { +public: + explicit CHalfTransition(CInputStream& in); + +private: + uint x0_id; + rstl::rc_ptr x4_trans; +}; + +#endif // _CHALFTRANSITION diff --git a/include/Kyoto/Animation/CInt32POINode.hpp b/include/Kyoto/Animation/CInt32POINode.hpp new file mode 100644 index 0000000..d279900 --- /dev/null +++ b/include/Kyoto/Animation/CInt32POINode.hpp @@ -0,0 +1,27 @@ +#ifndef _CINT32POINODE +#define _CINT32POINODE + +#include "Kyoto/Animation/CPOINode.hpp" + +class CInt32POINode : public CPOINode { +public: + CInt32POINode(rstl::string name, ushort type, const CCharAnimTime& time, int index, bool unique, + float weight, int charIdx, int flags, int value, const rstl::string& locatorName); + /*: CPOINode(name, type, time, index, unique, weight, charIdx, flags) + , x38_val(value) + , x3c_lctrName(locatorName) {} */ + + explicit CInt32POINode(CInputStream& in); + + static CInt32POINode CopyNodeMinusStartTime(const CInt32POINode& node, + const CCharAnimTime& startTime); + + int GetValue() const { return x38_val; } + const rstl::string& GetLocatorName() const { return x3c_lctrName; } + +private: + int x38_val; + rstl::string x3c_lctrName; +}; + +#endif // _CINT32POINODE diff --git a/include/Kyoto/Animation/CMetaAnimFactory.hpp b/include/Kyoto/Animation/CMetaAnimFactory.hpp new file mode 100644 index 0000000..a26daa9 --- /dev/null +++ b/include/Kyoto/Animation/CMetaAnimFactory.hpp @@ -0,0 +1,13 @@ +#ifndef _CMETAANIMFACTORY +#define _CMETAANIMFACTORY + +#include "rstl/rc_ptr.hpp" + +class IMetaAnim; +class CInputStream; +class CMetaAnimFactory { +public: + static rstl::rc_ptr< IMetaAnim > CreateMetaAnim(CInputStream& in); +}; + +#endif // _CMETAANIMFACTORY diff --git a/include/Kyoto/Animation/CMetaTransFactory.hpp b/include/Kyoto/Animation/CMetaTransFactory.hpp new file mode 100644 index 0000000..487c0b5 --- /dev/null +++ b/include/Kyoto/Animation/CMetaTransFactory.hpp @@ -0,0 +1,13 @@ +#ifndef _CMETATRANSFACTORY +#define _CMETATRANSFACTORY + +#include "rstl/rc_ptr.hpp" + +class IMetaTrans; +class CInputStream; +class CMetaTransFactory { +public: + static rstl::rc_ptr< IMetaTrans > CreateMetaTrans(CInputStream& in); +}; + +#endif // _CMETATRANSFACTORY diff --git a/include/Kyoto/Animation/CPASAnimInfo.hpp b/include/Kyoto/Animation/CPASAnimInfo.hpp new file mode 100644 index 0000000..56f4d48 --- /dev/null +++ b/include/Kyoto/Animation/CPASAnimInfo.hpp @@ -0,0 +1,21 @@ +#ifndef _CPASANIMINFO +#define _CPASANIMINFO + +#include "Kyoto/Animation/CPASAnimParm.hpp" + +#include "rstl/reserved_vector.hpp" + +class CPASAnimInfo { +public: + CPASAnimInfo(int id); + CPASAnimInfo(int id, const rstl::reserved_vector& parms); + + int GetAnimId() const { return x0_id; } + CPASAnimParm GetAnimParmData(uint idx, CPASAnimParm::EParmType type) const; + const CPASAnimParm::UParmValue& GetAnimParmValue(uint idx) const; +private: + uint x0_id; + rstl::reserved_vector< CPASAnimParm::UParmValue, 8 > x4_parms; +}; + +#endif // _CPASANIMINFO diff --git a/include/Kyoto/Animation/CPASAnimParm.hpp b/include/Kyoto/Animation/CPASAnimParm.hpp new file mode 100644 index 0000000..dc27bf2 --- /dev/null +++ b/include/Kyoto/Animation/CPASAnimParm.hpp @@ -0,0 +1,46 @@ +#ifndef _CPASANIMPARM +#define _CPASANIMPARM + +#include "types.h" + +class CPASAnimParm { +public: + enum EParmType { + kPT_None = -1, + kPT_Int32 = 0, + kPT_UInt32 = 1, + kPT_Float = 2, + kPT_Bool = 3, + kPT_Enum = 4, + + }; + union UParmValue { + int m_int; + uint m_uint; + float m_float; + bool m_bool; + }; + + CPASAnimParm(UParmValue value, EParmType type); + + static CPASAnimParm NoParameter(); + static CPASAnimParm FromInt32(int value); + static CPASAnimParm FromUint32(uint value); + static CPASAnimParm FromReal32(float value); + static CPASAnimParm FromBool(bool val); + static CPASAnimParm FromEnum(int value); + + int GetInt32Value() const; + uint GetUint32Value() const; + float GetReal32Value() const; + bool GetBoolValue() const; + int GetEnumValue() const; + + UParmValue GetParameter() { return x0_value; } + +private: + UParmValue x0_value; + EParmType x4_type; +}; + +#endif // _CPASANIMPARM diff --git a/include/Kyoto/Animation/CPASAnimParmData.hpp b/include/Kyoto/Animation/CPASAnimParmData.hpp new file mode 100644 index 0000000..a1824df --- /dev/null +++ b/include/Kyoto/Animation/CPASAnimParmData.hpp @@ -0,0 +1,42 @@ +#ifndef _CPASANIMPARMDATA +#define _CPASANIMPARMDATA + +#include "Kyoto/Animation/CPASAnimState.hpp" + +class CPASAnimParmData { + pas::EAnimationState x0_stateId; + rstl::reserved_vector< CPASAnimParm, 8 > x4_parms; + +public: + CPASAnimParmData(pas::EAnimationState stateId, + const CPASAnimParm& parm1 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm2 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm3 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm4 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm5 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm6 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm7 = CPASAnimParm::NoParameter(), + const CPASAnimParm& parm8 = CPASAnimParm::NoParameter()); + /* + : x0_stateId(stateId) { + x4_parms.push_back(parm1); + x4_parms.push_back(parm2); + x4_parms.push_back(parm3); + x4_parms.push_back(parm4); + x4_parms.push_back(parm5); + x4_parms.push_back(parm6); + x4_parms.push_back(parm7); + x4_parms.push_back(parm8); + } + */ + ~CPASAnimParmData() {} + + pas::EAnimationState GetStateId() const { return x0_stateId; } + const rstl::reserved_vector< CPASAnimParm, 8 >& GetAnimParmData() const { return x4_parms; } + + static CPASAnimParmData NoParameters(pas::EAnimationState stateId) { + return CPASAnimParmData(stateId); + } +}; + +#endif // _CPASANIMPARMDATA diff --git a/include/Kyoto/Animation/CPASAnimState.hpp b/include/Kyoto/Animation/CPASAnimState.hpp new file mode 100644 index 0000000..4c2fff0 --- /dev/null +++ b/include/Kyoto/Animation/CPASAnimState.hpp @@ -0,0 +1,29 @@ +#ifndef _CPASANIMSTATE +#define _CPASANIMSTATE + +#include "types.h" + +#include "Kyoto/Animation/CPASAnimInfo.hpp" +#include "Kyoto/Animation/CPASAnimParm.hpp" +#include "Kyoto/Animation/CPASParmInfo.hpp" +#include "Kyoto/Animation/CharacterCommon.hpp" + +#include "rstl/reserved_vector.hpp" +#include "rstl/vector.hpp" + +class CPASAnimState { +public: + CPASAnimParm GetAnimParmData(int, unsigned int) const; + + pas::EAnimationState GetStateId() const { return x0_id; } + bool HasAnims() const { return static_cast< uint >(x14_anims.size()) != 0; } + +private: + pas::EAnimationState x0_id; + rstl::vector< CPASParmInfo > x4_parms; + rstl::vector< CPASAnimInfo > x14_anims; + rstl::vector< int > x24_selectionCache; +}; +CHECK_SIZEOF(CPASAnimState, 0x34) + +#endif // _CPASANIMSTATE diff --git a/include/Kyoto/Animation/CPASDatabase.hpp b/include/Kyoto/Animation/CPASDatabase.hpp new file mode 100644 index 0000000..625ecd0 --- /dev/null +++ b/include/Kyoto/Animation/CPASDatabase.hpp @@ -0,0 +1,39 @@ +#ifndef _CPASDATABASE +#define _CPASDATABASE + +#include "types.h" + +#include "Kyoto/Animation/CPASAnimState.hpp" + +#include "rstl/pair.hpp" +#include "rstl/vector.hpp" + +class CPASAnimParmData; +class CRandom16; + +class CPASDatabase { + +public: + bool HasState(int id) const; + const CPASAnimState* GetAnimState(int) const; + + rstl::pair< float, int > FindBestAnimation(const CPASAnimParmData& data, int ignoreAnim) const; + rstl::pair< float, int > FindBestAnimation(const CPASAnimParmData&, CRandom16&, int) const; + + size_t GetNumAnimStates() const; // { return x0_states.size(); } + const CPASAnimState* GetAnimStateByIndex(int index) const; /* { + if (index >= x0_states.size()) { + return nullptr; + } + + return &x0_states[index]; + }*/ + + int GetDefaultState() const { return x10_defaultState; } +private: + rstl::vector< CPASAnimState > x0_states; + int x10_defaultState; +}; +CHECK_SIZEOF(CPASDatabase, 0x14) + +#endif // _CPASDATABASE diff --git a/include/Kyoto/Animation/CPASParmInfo.hpp b/include/Kyoto/Animation/CPASParmInfo.hpp new file mode 100644 index 0000000..4d10268 --- /dev/null +++ b/include/Kyoto/Animation/CPASParmInfo.hpp @@ -0,0 +1,33 @@ +#ifndef _CPASPARMINFO +#define _CPASPARMINFO + +#include "Kyoto/Animation/CPASAnimParm.hpp" + +class CInputStream; +class CPASParmInfo { +public: + enum EWeightFunction { + kWF_Invalid = -1, + kWF_ExactMatch, + kWF_PercentError, + kWF_AngularPercent, + kWF_NoWeight, + }; + + CPASParmInfo(CInputStream& in); + + CPASAnimParm::EParmType GetParameterType() const { return x0_type; } + EWeightFunction GetWeightFunction() const { return x4_weightFunction; } + float GetWeight() const { return x8_weight; } + CPASAnimParm::UParmValue GetParameterMinValue() const { return xc_min; } + CPASAnimParm::UParmValue GetParameterMaxValue() const { return x10_max; } + +private: + CPASAnimParm::EParmType x0_type; + EWeightFunction x4_weightFunction; + float x8_weight; + CPASAnimParm::UParmValue xc_min; + CPASAnimParm::UParmValue x10_max; +}; + +#endif // _CPASPARMINFO diff --git a/include/Kyoto/Animation/CPOINode.hpp b/include/Kyoto/Animation/CPOINode.hpp new file mode 100644 index 0000000..a3beea3 --- /dev/null +++ b/include/Kyoto/Animation/CPOINode.hpp @@ -0,0 +1,55 @@ +#ifndef _CPOINODE +#define _CPOINODE + +#include "types.h" + +#include "Kyoto/Animation/CCharAnimTime.hpp" +#include "rstl/string.hpp" + +enum EPOIType { + kPT_Loop = 0, + kPT_EmptyBool = 1, + kPT_EmptyInt32 = 2, + kPT_SoundInt32 = 4, + kPT_Particle = 5, + kPT_UserEvent = 6, + kPT_RandRate = 7, + kPT_Sound = 8, +}; + +class CInputStream; +class CPOINode { +public: + CPOINode(const rstl::string& name, ushort type, const CCharAnimTime& time, int index, bool unique, + float weight, int charIdx, int flags); + CPOINode(CInputStream& in); + virtual ~CPOINode() {} + + const rstl::string& GetString() const { return x8_name; } + const EPOIType GetPoiType() const { return static_cast< EPOIType >(x18_type); } + const CCharAnimTime& GetTime() const { return x1c_time; } + const int GetIndex() const { return x24_index; } + const bool GetSaveState() const { return x28_unique; } + const float GetWeight() const { return x2c_weight; } + const int GetCharacterIndex() const { return x30_charIdx; } + const int GetFlags() const { return x34_flags; } + + bool operator>(const CPOINode& other) const; + bool operator<(const CPOINode& other) const; + static int compare(const void* a, const void* b); + +protected: + ushort x4_; + rstl::string x8_name; + ushort x18_type; + CCharAnimTime x1c_time; + int x24_index; + bool x28_unique; + float x2c_weight; + int x30_charIdx; + int x34_flags; +}; +CHECK_SIZEOF(CPOINode, 0x38) + + +#endif // _CPOINODE diff --git a/include/Kyoto/Animation/CParticlePOINode.hpp b/include/Kyoto/Animation/CParticlePOINode.hpp new file mode 100644 index 0000000..6f03bca --- /dev/null +++ b/include/Kyoto/Animation/CParticlePOINode.hpp @@ -0,0 +1,24 @@ +#ifndef _CPARTICLEPOINODE +#define _CPARTICLEPOINODE + +#include "Kyoto/Animation/CPOINode.hpp" +#include "Kyoto/Particles/CParticleData.hpp" + +class CParticlePOINode : public CPOINode { +public: + CParticlePOINode(rstl::string name, ushort type, const CCharAnimTime& time, int index, + bool unique, float weight, int charIdx, int flags, const CParticleData& data); + //: CPOINode(name, type, time, index, unique, weight, charIdx, flags), x38_val(value) {} + + explicit CParticlePOINode(CInputStream& in); + + const CParticleData& GetParticleData() const { return x38_data; } + + static CParticlePOINode CopyNodeMinusStartTime(const CParticlePOINode& node, + const CCharAnimTime& startTime); + +private: + CParticleData x38_data; +}; + +#endif // _CPARTICLEPOINODE diff --git a/include/Kyoto/Animation/CPoseAsTransforms.hpp b/include/Kyoto/Animation/CPoseAsTransforms.hpp new file mode 100644 index 0000000..63873ac --- /dev/null +++ b/include/Kyoto/Animation/CPoseAsTransforms.hpp @@ -0,0 +1,26 @@ +#ifndef _CPOSEASTRANSFORMS +#define _CPOSEASTRANSFORMS + +#include "types.h" + +#include "MetroidPrime/TGameTypes.hpp" + +#include "Kyoto/Math/CTransform4f.hpp" + +#include "rstl/reserved_vector.hpp" +#include "rstl/single_ptr.hpp" + +class CPoseAsTransforms { +public: + const CMatrix3f& GetRotation(const CSegId& id) const; +private: + CSegId x0_nextId; + CSegId x1_count; + // TODO TSegIdMapVariableSize + rstl::reserved_vector< rstl::pair< CSegId, CSegId >, 100 > x4_links; + rstl::single_ptr< CTransform4f > xd0_transformArr; + CSegId xd4_lastInserted; +}; +CHECK_SIZEOF(CPoseAsTransforms, 0xd8) + +#endif // _CPOSEASTRANSFORMS diff --git a/include/Kyoto/Animation/CPrimitive.hpp b/include/Kyoto/Animation/CPrimitive.hpp new file mode 100644 index 0000000..5a84020 --- /dev/null +++ b/include/Kyoto/Animation/CPrimitive.hpp @@ -0,0 +1,22 @@ +#ifndef _CPRIMITIVE +#define _CPRIMITIVE + +#include "Kyoto/SObjectTag.hpp" + +#include "rstl/string.hpp" + +class CInputStream; +class COutputStream; +class CPrimitive { +public: + CPrimitive(CInputStream& in); + void PutTo(COutputStream& out) const; + CAssetId GetAnimResId() const { return x0_animId; } + +private: + CAssetId x0_animId; + int x4_animIdx; + rstl::string x8_animName; +}; + +#endif // _CPRIMITIVE diff --git a/include/Kyoto/Animation/CSegId.hpp b/include/Kyoto/Animation/CSegId.hpp new file mode 100644 index 0000000..00f6572 --- /dev/null +++ b/include/Kyoto/Animation/CSegId.hpp @@ -0,0 +1,16 @@ +#ifndef _CSEGID +#define _CSEGID + +#include + +#include "Kyoto/Streams/CInputStream.hpp" + +class CSegId { +public: + CSegId() : x0_id(-1) {} + CSegId(CInputStream& in) : x0_id(in.ReadInt32()) {} +private: + uchar x0_id; +}; + +#endif // _CSEGID diff --git a/include/Kyoto/Animation/CSegIdList.hpp b/include/Kyoto/Animation/CSegIdList.hpp new file mode 100644 index 0000000..78d3ba0 --- /dev/null +++ b/include/Kyoto/Animation/CSegIdList.hpp @@ -0,0 +1,15 @@ +#ifndef _CSEGIDLIST +#define _CSEGIDLIST + +#include "Kyoto/Animation/CSegId.hpp" +#include "rstl/vector.hpp" + +class CInputStream; +class CSegIdList { +public: + CSegIdList(CInputStream& in); +public: + rstl::vector x0_segList; +}; + +#endif // _CSEGIDLIST diff --git a/include/Kyoto/Animation/CSkinRules.hpp b/include/Kyoto/Animation/CSkinRules.hpp new file mode 100644 index 0000000..94fa83b --- /dev/null +++ b/include/Kyoto/Animation/CSkinRules.hpp @@ -0,0 +1,18 @@ +#ifndef _CSKINRULES +#define _CSKINRULES + +#include "Kyoto/Animation/CVirtualBone.hpp" + +class CInputStream; +class CSkinRules { +public: + CSkinRules(CInputStream& in); + ~CSkinRules(); + +private: + rstl::vector x0_virtualBones; + uint x10_vertexCount; + uint x14_normalCount; +}; + +#endif // _CSKINRULES diff --git a/include/Kyoto/Animation/CSkinnedModel.hpp b/include/Kyoto/Animation/CSkinnedModel.hpp new file mode 100644 index 0000000..0eaac82 --- /dev/null +++ b/include/Kyoto/Animation/CSkinnedModel.hpp @@ -0,0 +1,35 @@ +#ifndef _CSKINNEDMODEL +#define _CSKINNEDMODEL + +#include "types.h" + +#include "Kyoto/TToken.hpp" + +#include "rstl/auto_ptr.hpp" + +class CModel; +class CSkinRules; +class CCharLayoutInfo; + +class CSkinnedModel { +public: + virtual ~CSkinnedModel(); + + static void ClearPointGeneratorFunc(); + + TLockedToken< CModel >& Model() { return x4_model; } + const TLockedToken< CModel >& GetModel() const { return x4_model; } + + static void SetPointGeneratorFunc(void*, void (*)(void*, const CVector3f*, const CVector3f*, int)); + +private: + TLockedToken< CModel > x4_model; + TLockedToken< CSkinRules > x10_skinRules; + TLockedToken< CCharLayoutInfo > x1c_layoutInfo; + rstl::auto_ptr< float[] > x24_vertWorkspace; + rstl::auto_ptr< float[] > x2c_normalWorkspace; + bool x34_owned; + bool x35_disableWorkspaces; +}; + +#endif // _CSKINNEDMODEL diff --git a/include/Kyoto/Animation/CSoundPOINode.hpp b/include/Kyoto/Animation/CSoundPOINode.hpp new file mode 100644 index 0000000..30776d0 --- /dev/null +++ b/include/Kyoto/Animation/CSoundPOINode.hpp @@ -0,0 +1,42 @@ +#ifndef _CSOUNDPOINODE +#define _CSOUNDPOINODE + +#include "Kyoto/Animation/CPOINode.hpp" +#include "Kyoto/Streams/CInputStream.hpp" + +class CSoundPOINode : public CPOINode { +public: + CSoundPOINode(rstl::string name, ushort type, const CCharAnimTime& time, int index, bool unique, + float weight, int charIdx, int flags, int sfxId, float fallOff, float maxDist); + /* : CPOINode(name, type, time, index, unique, weight, charIdx, flags) + , x38_sfxId(sfxId) + , x3c_falloff(fallOff) + , x40_maxDist(maxDist) {} + */ + + CSoundPOINode(CInputStream& in); + /*: CPOINode(in) + , x38_sfxId(in.ReadInt32()) + , x3c_falloff(in.ReadFloat()) + , x40_maxDist(in.ReadFloat()) {} + */ + + uint GetSoundId() const { return x38_sfxId; } + float GetFallOff() const { return x3c_falloff; } + float GetMaxDistance() const { return x40_maxDist; } + + static CSoundPOINode CopyNodeMinusStartTime(const CSoundPOINode& node, + const CCharAnimTime& startTime) { + return CSoundPOINode(node.GetString(), node.GetPoiType(), node.GetTime() - startTime, + node.GetIndex(), node.GetSaveState(), node.GetWeight(), + node.GetCharacterIndex(), node.GetFlags(), node.GetSoundId(), + node.GetFallOff(), node.GetMaxDistance()); + } + +private: + uint x38_sfxId; + float x3c_falloff; + float x40_maxDist; +}; + +#endif // _CSOUNDPOINODE diff --git a/include/Kyoto/Animation/CTransition.hpp b/include/Kyoto/Animation/CTransition.hpp new file mode 100644 index 0000000..50d8969 --- /dev/null +++ b/include/Kyoto/Animation/CTransition.hpp @@ -0,0 +1,24 @@ +#ifndef _CTRANSITION +#define _CTRANSITION + +#include "rstl/rc_ptr.hpp" +#include "rstl/pair.hpp" + + +class IMetaTrans; +class CInputStream; +class CTransition { + uint x0_id; + uint x4_animA; + uint x8_animB; + rstl::rc_ptr xc_trans; + +public: + explicit CTransition(CInputStream& in); + u32 GetAnimA() const { return x4_animA; } + u32 GetAnimB() const { return x8_animB; } + rstl::pair GetAnimPair() const { return rstl::pair(x4_animA, x8_animB); } + const rstl::rc_ptr& GetMetaTrans() const { return xc_trans; } +}; + +#endif // _CTRANSITION diff --git a/include/Kyoto/Animation/CTransitionManager.hpp b/include/Kyoto/Animation/CTransitionManager.hpp new file mode 100644 index 0000000..9d3682d --- /dev/null +++ b/include/Kyoto/Animation/CTransitionManager.hpp @@ -0,0 +1,16 @@ +#ifndef _CTRANSITIONMANAGER +#define _CTRANSITIONMANAGER + +#include "Kyoto/Animation/CAnimSysContext.hpp" + +class CAnimTreeNode; +class CTransitionManager { +public: + rstl::rc_ptr< CAnimTreeNode > GetTransitionTree(const rstl::ncrc_ptr< CAnimTreeNode >& a, + const rstl::ncrc_ptr< CAnimTreeNode >& b) const; + +private: + CAnimSysContext x0_context; +}; + +#endif // _CTRANSITIONMANAGER diff --git a/include/Kyoto/Animation/CTreeUtils.hpp b/include/Kyoto/Animation/CTreeUtils.hpp new file mode 100644 index 0000000..99e5309 --- /dev/null +++ b/include/Kyoto/Animation/CTreeUtils.hpp @@ -0,0 +1,15 @@ +#ifndef _CTREEUTILS +#define _CTREEUTILS + +#include "rstl/rc_ptr.hpp" + +class CAnimTreeNode; +class CAnimSysContext; +class CTreeUtils { +public: + static rstl::rc_ptr< CAnimTreeNode > GetTransitionTree(const rstl::ncrc_ptr< CAnimTreeNode >& a, + const rstl::ncrc_ptr< CAnimTreeNode >& b, + const CAnimSysContext& animCtx); +}; + +#endif // _CTREEUTILS diff --git a/include/Kyoto/Animation/CVertexMorphEffect.hpp b/include/Kyoto/Animation/CVertexMorphEffect.hpp new file mode 100644 index 0000000..ce0cd01 --- /dev/null +++ b/include/Kyoto/Animation/CVertexMorphEffect.hpp @@ -0,0 +1,26 @@ +#ifndef _CVERTEXMORPHEFFECT +#define _CVERTEXMORPHEFFECT + +#include "Kyoto/Math/CUnitVector3f.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +#include "rstl/vector.hpp" + +class CRandom16; + +class CVertexMorphEffect { +public: + ~CVertexMorphEffect() {} + +private: + CUnitVector3f x0_dir; + CVector3f xc_pos; + float x18_duration; + float x1c_elapsed; + float x20_diagExtent; + CRandom16& x24_random; + rstl::vector< uint > x28_indices; + rstl::vector< float > x38_floats; +}; + +#endif // _CVERTEXMORPHEFFECT diff --git a/include/Kyoto/Animation/CVirtualBone.hpp b/include/Kyoto/Animation/CVirtualBone.hpp new file mode 100644 index 0000000..055ef52 --- /dev/null +++ b/include/Kyoto/Animation/CVirtualBone.hpp @@ -0,0 +1,34 @@ +#ifndef _CVIRTUALBONE +#define _CVIRTUALBONE + +#include "Kyoto/Animation/CSegId.hpp" +#include "Kyoto/Math/CMatrix3f.hpp" +#include "Kyoto/Math/CTransform4f.hpp" + +struct SSkinWeighting { + CSegId x0_id; + float x4_weight; + explicit SSkinWeighting(CInputStream& in) : x0_id(in), x4_weight(in.ReadFloat()) {} +}; + +class CPoseAsTransforms; +class CVirtualBone { +public: + explicit CVirtualBone(CInputStream& in); + const rstl::reserved_vector< SSkinWeighting, 3 >& GetWeights() const { return x0_weights; } + uint GetVertexCount() const { return x1c_vertexCount; } + + void BuildPoints(const ushort*, volatile void*, int) const; + void BuildNormals(const ushort*, volatile void*, int) const; + void BuildNormals(const CVector3f*, CVector3f*, int) const; + void BuildAccumulatedTransform(const CPoseAsTransforms& pose, const CVector3f* points) const; + void BuildFinalPosMatrix(const CPoseAsTransforms& pose, const CVector3f* points) const; + +private: + rstl::reserved_vector< SSkinWeighting, 3 > x0_weights; + uint x1c_vertexCount; + mutable CTransform4f x20_xf; + mutable CMatrix3f x50_rotation; +}; + +#endif // _CVIRTUALBONE diff --git a/include/Kyoto/Animation/CharacterCommon.hpp b/include/Kyoto/Animation/CharacterCommon.hpp new file mode 100644 index 0000000..ff0392d --- /dev/null +++ b/include/Kyoto/Animation/CharacterCommon.hpp @@ -0,0 +1,216 @@ +#ifndef _CHARACTERCOMMON +#define _CHARACTERCOMMON + +namespace pas { +enum ELocomotionType { + kLT_Invalid = -1, + kLT_Crouch = 0, + kLT_Relaxed = 1, + kLT_Lurk = 2, + kLT_Combat = 3, + kLT_Internal4 = 4, + kLT_Internal5 = 5, + kLT_Internal6 = 6, + kLT_Internal7 = 7, + kLT_Internal8 = 8, + kLT_Internal9 = 9, + kLT_Internal10 = 10, + kLT_Internal11 = 11, + kLT_Internal12 = 12, + kLT_Internal13 = 13, + kLT_Internal14 = 14 +}; + +enum ELocomotionAnim { + kLA_Invalid = -1, + kLA_Idle, + kLA_Walk, + kLA_Run, + kLA_BackUp, + kLA_StrafeLeft, + kLA_StrafeRight, + kLA_StrafeUp, + kLA_StrafeDown +}; + +enum EAnimationState { + kAS_Invalid = -1, + kAS_Fall = 0, + kAS_Getup = 1, + kAS_LieOnGround = 2, + kAS_Step = 3, + kAS_Death = 4, + kAS_Locomotion = 5, + kAS_KnockBack = 6, + kAS_MeleeAttack = 7, + kAS_Turn = 8, + kAS_LoopAttack = 9, + kAS_LoopReaction = 10, + kAS_GroundHit = 11, + kAS_Generate = 12, + kAS_Jump = 13, + kAS_Hurled = 14, + kAS_Slide = 15, + kAS_Taunt = 16, + kAS_Scripted = 17, + kAS_ProjectileAttack = 18, + kAS_Cover = 19, + kAS_WallHang = 20, + kAS_AdditiveIdle = 21, + kAS_AdditiveAim = 22, + kAS_AdditiveFlinch = 23, + kAS_AdditiveReaction = 24 +}; + +enum EHurledState { + kHS_Invalid = -1, + kHS_KnockIntoAir, + kHS_KnockLoop, + kHS_KnockDown, + kHS_StrikeWall, + kHS_StrikeWallFallLoop, + kHS_OutOfStrikeWall, + kHS_Six, + kHS_Seven +}; + +enum EFallState { kFS_Invalid = -1, kFS_Zero, kFS_One, kFS_Two }; + +enum EReactionType { kRT_Invalid = -1, kRT_Zero, kRT_One, kRT_Two, kRT_Three }; + +enum EAdditiveReactionType { + kART_Invalid = -1, + kART_Electrocution, + kART_One, + kART_Two, + kART_IceBreakout, + kART_Four, + kART_Five, + kART_Six, + kART_Seven +}; + +enum EJumpType { kJT_Normal, kJT_One, kJT_Ambush }; + +enum EJumpState { + kJS_Invalid = -1, + kJS_IntoJump, + kJS_AmbushJump, + kJS_Loop, + kJS_OutOfJump, + kJS_WallBounceLeft, + kJS_WallBounceRight +}; + +enum EStepDirection { + kSD_Invalid = -1, + kSD_Forward = 0, + kSD_Backward = 1, + kSD_Left = 2, + kSD_Right = 3, + kSD_Up = 4, + kSD_Down = 5 +}; + +enum EStepType { kStep_Normal = 0, kStep_Dodge = 1, kStep_BreakDodge = 2, kStep_RollDodge = 3 }; + +enum ESeverity { + kS_Invalid = -1, + kS_Zero = 0, + kS_One = 1, + kS_Two = 2, + kS_Three = 3, + kS_Four = 4, + kS_Five = 5, + kS_Six = 6, + kS_Seven = 7, + kS_Eight = 8 +}; + +enum EGetupType { kGetup_Invalid = -1, kGetup_Zero = 0, kGetup_One = 1, kGetup_Two = 2 }; + +enum ELoopState { kLS_Invalid = -1, kLS_Begin, kLS_Loop, kLS_End }; + +enum ELoopAttackType { kLAT_Invalid = -1, kLAT_Zero, kLAT_One, kLAT_Two, kLAT_Three }; + +enum EGenerateType { + kGType_Invalid = -1, + kGType_Zero, + kGType_One, + kGType_Two, + kGType_Three, + kGType_Four, + kGType_Five, + kGType_Six, + kGType_Seven, + kGType_Eight +}; + +enum ESlideType { kSlide_Invalid = -1, kSlide_Zero = 0 }; + +enum ETauntType { kTT_Invalid = -1, kTT_Zero, kTT_One, kTT_Two }; + +enum ECoverState { kCS_Invalid = -1, kCS_IntoCover, kCS_Cover, kCS_Lean, kCS_OutOfCover }; + +enum ECoverDirection { kCD_Invalid = -1, kCD_Left, kCD_Right }; + +enum ETurnDirection { kTD_Invalid = -1, kTD_Right, kTD_Left }; + +enum EWallHangState { + kWHS_Invalid = -1, + kWHS_IntoJump, + kWHS_JumpArc, + kWHS_JumpAirLoop, + kWHS_IntoWallHang, + kWHS_WallHang, + kWHS_Five, + kWHS_OutOfWallHang, + kWHS_OutOfWallHangTurn, + kWHS_DetachJumpLoop, + kWHS_DetachOutOfJump +}; +} // namespace pas + +enum EBodyType { + kBT_Invalid, + kBT_BiPedal, + kBT_Restricted, + kBT_Flyer, + kBT_Pitchable, + kBT_RestrictedFlyer, + kBT_WallWalker, + kBT_NewFlyer +}; + +enum EBodyStateCmd { + kBSC_Getup, + kBSC_Step, + kBSC_Die, + kBSC_KnockDown, + kBSC_KnockBack, + kBSC_MeleeAttack, + kBSC_ProjectileAttack, + kBSC_LoopAttack, + kBSC_LoopReaction, + kBSC_LoopHitReaction, + kBSC_ExitState, + kBSC_LeanFromCover, + kBSC_NextState, + kBSC_MaintainVelocity, + kBSC_Generate, + kBSC_Hurled, + kBSC_Jump, + kBSC_Slide, + kBSC_Taunt, + kBSC_Scripted, + kBSC_Cover, + kBSC_WallHang, + kBSC_Locomotion, + kBSC_AdditiveIdle, + kBSC_AdditiveAim, + kBSC_AdditiveFlinch, + kBSC_AdditiveReaction, + kBSC_StopReaction +}; + +#endif // _CHARACTERCOMMON diff --git a/include/Kyoto/Animation/IAnimReader.hpp b/include/Kyoto/Animation/IAnimReader.hpp new file mode 100644 index 0000000..e0bab4a --- /dev/null +++ b/include/Kyoto/Animation/IAnimReader.hpp @@ -0,0 +1,94 @@ +#ifndef _IANIMREADER +#define _IANIMREADER + +#include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/Math/CQuaternion.hpp" + +#include "Kyoto/Animation/CCharAnimTime.hpp" + +#include "rstl/string.hpp" + +struct SAdvancementDeltas { + CVector3f x0_posDelta; + CQuaternion xc_rotDelta; + + static SAdvancementDeltas Interpolate(const SAdvancementDeltas& a, const SAdvancementDeltas& b, float oldWeight, + float newWeight); + static SAdvancementDeltas Blend(const SAdvancementDeltas& a, const SAdvancementDeltas& b, float w); +}; + +struct SAdvancementResults { + CCharAnimTime x0_remTime; + SAdvancementDeltas x8_deltas; +}; + + +class CSteadyStateAnimInfo { + CCharAnimTime x0_duration; + CVector3f x8_offset; + bool x14_looping; + +public: + CSteadyStateAnimInfo(bool looping, const CCharAnimTime& duration, const CVector3f& offset) + : x0_duration(duration), x8_offset(offset), x14_looping(looping) {} + + const CCharAnimTime& GetDuration() const { return x0_duration; } + const CVector3f& GetOffset() const { return x8_offset; } + bool IsLooping() const { return x14_looping; } +}; + +struct CAnimTreeEffectiveContribution { + float x0_contributionWeight; + rstl::string x4_name; + CSteadyStateAnimInfo x14_ssInfo; + CCharAnimTime x2c_remTime; + u32 x34_dbIdx; + +public: + CAnimTreeEffectiveContribution(float cweight, const rstl::string& name, const CSteadyStateAnimInfo& ssInfo, + const CCharAnimTime& remTime, u32 dbIdx) + : x0_contributionWeight(cweight), x4_name(name), x14_ssInfo(ssInfo), x2c_remTime(remTime), x34_dbIdx(dbIdx) {} + float GetContributionWeight() const { return x0_contributionWeight; } + const rstl::string& GetPrimitiveName() const { return x4_name; } + const CSteadyStateAnimInfo& GetSteadyStateAnimInfo() const { return x14_ssInfo; } + const CCharAnimTime& GetTimeRemaining() const { return x2c_remTime; } + u32 GetAnimDatabaseIndex() const { return x34_dbIdx; } +}; + +class CSegId; +class CSegIdList; +class CBoolPOINode; +class CInt32POINode; +class CParticlePOINode; +class CSoundPOINode; +class CSegStatementSet; + +class IAnimReader { +public: + virtual ~IAnimReader(); + virtual bool IsCAnimTreeNode() const { return false; } + virtual SAdvancementResults VAdvanceView(const CCharAnimTime& a) = 0; + virtual CCharAnimTime VGetTimeRemaining() const = 0; + virtual CSteadyStateAnimInfo VGetSteadyStateAnimInfo() const = 0; + virtual bool VHasOffset(const CSegId& seg) const = 0; + virtual CVector3f VGetOffset(const CSegId& seg) const = 0; + virtual CQuaternion VGetRotation(const CSegId& seg) const = 0; + virtual size_t VGetBoolPOIList(const CCharAnimTime& time, CBoolPOINode* listOut, size_t capacity, size_t iterator, + u32) const = 0; + virtual size_t VGetInt32POIList(const CCharAnimTime& time, CInt32POINode* listOut, size_t capacity, size_t iterator, + u32) const = 0; + virtual size_t VGetParticlePOIList(const CCharAnimTime& time, CParticlePOINode* listOut, size_t capacity, + size_t iterator, u32) const = 0; + virtual size_t VGetSoundPOIList(const CCharAnimTime& time, CSoundPOINode* listOut, size_t capacity, size_t iterator, + u32) const = 0; + virtual bool VGetBoolPOIState(const rstl::string& name) const = 0; + virtual s32 VGetInt32POIState(const rstl::string& name) const = 0; + // virtual CParticleData::EParentedMode VGetParticlePOIState(const rstl::string& name) const = 0; + virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut) const = 0; + virtual void VGetSegStatementSet(const CSegIdList& list, CSegStatementSet& setOut, + const CCharAnimTime& time) const = 0; + // virtual std::unique_ptr VClone() const = 0; +}; + + +#endif // _IANIMREADER diff --git a/include/Kyoto/Animation/IMetaAnim.hpp b/include/Kyoto/Animation/IMetaAnim.hpp new file mode 100644 index 0000000..75b5258 --- /dev/null +++ b/include/Kyoto/Animation/IMetaAnim.hpp @@ -0,0 +1,33 @@ +#ifndef _IMETAANIM +#define _IMETAANIM + +#include "rstl/rc_ptr.hpp" +#include "rstl/set.hpp" + +enum EMetaAnimType { kMAT_Play, kMAT_Blend, kMAT_PhaseBlend, kMAT_Random, kMAT_Sequence }; + +class CAnimTreeNode; +class CPrimitive; +class CCharAnimTime; +class IAnimReader; +class CAnimSysContext; +class CMetaAnimTreeBuildOrders; +class CPreAdvanceIndicator; + +class IMetaAnim { +public: + virtual ~IMetaAnim(); + + virtual rstl::rc_ptr< CAnimTreeNode > + GetAnimationTree(const CAnimSysContext& animSys, const CMetaAnimTreeBuildOrders& orders) const; + virtual void GetUniquePrimitives(rstl::set< CPrimitive >& primsOut) const = 0; + virtual EMetaAnimType GetType() const = 0; + virtual rstl::rc_ptr< CAnimTreeNode > + VGetAnimationTree(const CAnimSysContext& animSys, + const CMetaAnimTreeBuildOrders& orders) const = 0; + + static void AdvanceAnim(IAnimReader& anim, const CCharAnimTime& dt); + static CCharAnimTime GetTime(const CPreAdvanceIndicator& ind, const IAnimReader& anim); +}; + +#endif // _IMETAANIM diff --git a/include/Kyoto/Audio/CAudioGroupSet.hpp b/include/Kyoto/Audio/CAudioGroupSet.hpp new file mode 100644 index 0000000..027de82 --- /dev/null +++ b/include/Kyoto/Audio/CAudioGroupSet.hpp @@ -0,0 +1,51 @@ +#ifndef _CAUDIOGROUPSET +#define _CAUDIOGROUPSET + +#include "Kyoto/TToken.hpp" + +#include "rstl/auto_ptr.hpp" +#include "rstl/optional_object.hpp" +#include "rstl/single_ptr.hpp" +#include "rstl/string.hpp" + +#include "Kyoto/CResFactory.hpp" + +class CInputStream; +class CAudioGrpSetLoc { +public: + CAudioGrpSetLoc(const rstl::auto_ptr< uchar >& data, int length); + const rstl::string& GetBaseDirName() const { return x10_baseDirName; } + const rstl::string& GetGroupSetName() const { return x20_groupSetName; } + uint AramUsage() const; + const void* GetPool() const; + const void* GetProject() const; + const void* GetSample() const; + const void* GetSampleDir() const; + +private: + rstl::auto_ptr< uchar > x0_data; + rstl::auto_ptr< uchar > x8_; + rstl::string x10_baseDirName; + rstl::string x20_groupSetName; + uint x30_; + uint x34_; + uint x38_; + uint x3c_; + uint x40_; +}; + +class CAudioGroupSet { +public: + CAudioGroupSet(const TLockedToken< CAudioGrpSetLoc >& group); + ~CAudioGroupSet(); + void Reload(); + void FreeSampleBuffer(); + void FreeAllBuffers(); + +private: + rstl::string x0_baseDir; + rstl::string x10_groupSetName; + rstl::optional_object< TLockedToken< CAudioGrpSetLoc > > x10_groupSetTok; +}; + +#endif // _CAUDIOGROUPSET diff --git a/include/Kyoto/Audio/CAudioSys.hpp b/include/Kyoto/Audio/CAudioSys.hpp new file mode 100644 index 0000000..14193f4 --- /dev/null +++ b/include/Kyoto/Audio/CAudioSys.hpp @@ -0,0 +1,104 @@ +#ifndef _CAUDIOSYS +#define _CAUDIOSYS + +#include "types.h" + +#include "rstl/map.hpp" +#include "rstl/rc_ptr.hpp" +#include "rstl/string.hpp" +#include "rstl/vector.hpp" + +#include "Kyoto/Math/CVector3f.hpp" + +class CAudioGroupSet; + +enum ETRKSampleRate { + kTSR_Zero, + kTSR_One, + // TODO +}; + +enum ETRKRepeatMode { + // TODO +}; + +class CAudioSys { + static const rstl::string mpDefaultInvalidString; + +public: + enum ESurroundModes { kSM_Mono, kSM_Stereo, kSM_Surround }; + class CEmitterData { + public: + CEmitterData() : _50(0), _51(0), _52(kEmitterMedPriority){}; + + private: + char data[0x50]; + char _50; + char _51; + uchar _52; + }; + + struct C3DEmitterParmData { + C3DEmitterParmData(const CVector3f& pos, const CVector3f& dir, float maxDist, float distComp, + uint flags, ushort sfxId, float maxVol, float minVol, bool important, + uchar prio) + : x0_pos(pos) + , xc_dir(dir) + , x18_maxDist(maxDist) + , x1c_distComp(distComp) + , x20_flags(flags) + , x24_sfxId(sfxId) + , x26_maxVol(maxVol) + , x27_minVol(minVol) + , x28_important(important) + , x29_prio(prio) {} + + CVector3f x0_pos; + CVector3f xc_dir; + float x18_maxDist; + float x1c_distComp; + uint x20_flags; + ushort x24_sfxId; + float x26_maxVol; + float x27_minVol; + bool x28_important; // Can't be allocated over, regardless of priority + uchar x29_prio; + }; + + class CTrkData {}; + + CAudioSys(char, char, char, char, uint); + ~CAudioSys(); + + static void SysSetVolume(uchar, uint, uchar); + static void SysSetSfxVolume(uchar, ushort, uchar, uchar); + + static void SetDefaultVolumeScale(short); + static void SetVolumeScale(short); + static void SetSurroundMode(ESurroundModes); + static void TrkSetSampleRate(ETRKSampleRate); + + static short GetDefaultVolumeScale(); + static bool GetVerbose(); + + static bool mInitialized; + static bool mIsListenerActive; + static bool mVerbose; + static uchar mMaxNumEmitters; + static rstl::map< rstl::string, rstl::ncrc_ptr< CAudioGroupSet > >* mpGroupSetDB; + static rstl::map< uint, rstl::string >* mpGroupSetResNameDB; + static rstl::map< rstl::string, rstl::ncrc_ptr< CTrkData > >* mpDVDTrackDB; + static rstl::vector< CEmitterData >* mpEmitterDB; + static unkptr mpListener; + + /* TODO: Remaining globals */ + + static ESurroundModes mSurroundMode; + static uint mMaxAramUsage; + static uint mCurrentAramUsage; + static bool mProLogic2; + static const uchar kMaxVolume; + static uchar kEmitterMedPriority; +}; + +#endif // _CAUDIOSYS diff --git a/include/Kyoto/Audio/CDSPStreamManager.hpp b/include/Kyoto/Audio/CDSPStreamManager.hpp new file mode 100644 index 0000000..227ac70 --- /dev/null +++ b/include/Kyoto/Audio/CDSPStreamManager.hpp @@ -0,0 +1,12 @@ +#ifndef _CDSPSTREAMMANAGER +#define _CDSPSTREAMMANAGER + +#include "types.h" + +class CDSPStreamManager { +public: + static void Initialize(); + static void Shutdown(); +}; + +#endif // _CDSPSTREAMMANAGER diff --git a/include/Kyoto/Audio/CMidiManager.hpp b/include/Kyoto/Audio/CMidiManager.hpp new file mode 100644 index 0000000..4168ffc --- /dev/null +++ b/include/Kyoto/Audio/CMidiManager.hpp @@ -0,0 +1,15 @@ +#ifndef _CMIDIMANAGER +#define _CMIDIMANAGER + +#include "Kyoto/Audio/CSfxHandle.hpp" + +class CMidiManager { +public: + class CMidiWrapper {}; + class CMidiData {}; + + static CSfxHandle Play(const CMidiData&, unsigned short fadeTime, bool stopExisting, short volume); + static void Stop(const CSfxHandle&, unsigned short); +}; + +#endif // _CMIDIMANAGER diff --git a/include/Kyoto/Audio/CSfxHandle.hpp b/include/Kyoto/Audio/CSfxHandle.hpp new file mode 100644 index 0000000..772a379 --- /dev/null +++ b/include/Kyoto/Audio/CSfxHandle.hpp @@ -0,0 +1,25 @@ +#ifndef _CSFXHANDLE +#define _CSFXHANDLE + +#include "types.h" + +class CSfxHandle { +public: + CSfxHandle() : mID(0) {} + CSfxHandle(uint value); + + uint GetIndex() const { return mID & 0xFFF; } + static CSfxHandle NullHandle() { return CSfxHandle(); } + void operator=(const CSfxHandle& other) { mID = other.mID; } + bool operator==(const CSfxHandle& other) { return mID == other.mID; } + bool operator!=(const CSfxHandle& other) { return mID != other.mID; } + operator bool() const { return mID != 0; } + void Clear() { mID = 0; } + +private: + uint mID; + static uint mRefCount; +}; +CHECK_SIZEOF(CSfxHandle, 0x4) + +#endif // _CSFXHANDLE diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp new file mode 100644 index 0000000..8f587e8 --- /dev/null +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -0,0 +1,121 @@ +#ifndef _CSFXMANAGER +#define _CSFXMANAGER + +#include "types.h" + +#include "Kyoto/Audio/CAudioSys.hpp" +#include "Kyoto/Audio/CSfxHandle.hpp" + +struct _SND_REVSTD_DELAYLINE { + int inPoint; + int outPoint; + int length; + float* inputs; + float lastOutput; +}; + +struct _SND_REVSTD_WORK { + struct _SND_REVSTD_DELAYLINE AP[6]; + struct _SND_REVSTD_DELAYLINE C[6]; + float allPassCoef; + float combCoef[6]; + float lpLastout[3]; + float level; + float damping; + int preDelayTime; + float* preDelayLine[3]; + float* preDelayPtr[3]; +}; + +struct SND_AUX_REVERBHI { + uchar pad0[0x1c4]; + bool hiDis; + float damping; + float crosstalk; + float coloration; + float time; + float mix; + float preDelay; +}; +struct SND_AUX_CHORUS { + uchar pad[144]; + uint baseDelay; + uint variation; + uint period; +}; +struct SND_AUX_REVERBSTD { + _SND_REVSTD_WORK rv; + bool tempDisableFX; + float damping; + float preDelay; + float coloration; + float time; + float mix; +}; +struct SND_AUX_DELAY { + uint currentSize[3]; + uint currentPos[3]; + uint currentFeedback[3]; + uint currentOutput[3]; + uint* left; + uint* right; + uint* sur; + uint delay[3]; // delay buffer length in ms per channel + uint feedback[3]; // feedback volume in % per channel + uint output[3]; // output volume in % per channel +}; + +class CVector3f; +class CSfxManager { +public: + enum ESfxChannels { kSC_Invalid = -1, kSC_Default = 0, kSC_Game, kSC_PauseScreen }; + + static void Update(float dt); + static void RemoveEmitter(CSfxHandle handle); + static void UpdateEmitter(CSfxHandle handle, const CVector3f& pos, const CVector3f& dir, + uchar maxVol); + static void UpdateListener(const CVector3f& pos, const CVector3f& dir, const CVector3f&, + const CVector3f&, const uchar); + + static const short kMaxPriority; // 0xFF + static const short kMedPriority; // 0x7F + static const ushort kInternalInvalidSfxId; // 0xFFFF + static const int kAllAreas; // 0xFFFFFFFF + static CSfxHandle AddEmitter(const ushort id, const CVector3f& pos, const CVector3f& dir, + const bool useAcoustics, const bool looped, const short prio = kMedPriority, + const int areaId = kAllAreas); + static CSfxHandle AddEmitter(const ushort id, const CVector3f& pos, const CVector3f& dir, uchar vol, + const bool useAcoustics, const bool looped, const short prio = kMedPriority, + const int areaId = kAllAreas); + static CSfxHandle AddEmitter(CAudioSys::C3DEmitterParmData& parmData, bool useAcoustics, + short prio, bool looped, int areaId = kAllAreas); + + static void AddListener(ESfxChannels channel, const CVector3f& pos, const CVector3f& dir, + const CVector3f& vec1, const CVector3f& vec2, float f1, float f2, + float f3, uint w1, const uchar maxVolume); + static void Shutdown(); + static ushort TranslateSFXID(ushort); + + static void PitchBend(CSfxHandle handle, int pitch); + + static CSfxHandle SfxStart(ushort id, short vol, short pan, bool useAcoustics, + short prio = kMaxPriority, bool looped = false, + int areaId = kAllAreas); + static void SfxSpan(CSfxHandle, uchar); + static bool IsPlaying(const CSfxHandle& handle); + + static void SetChannel(ESfxChannels); + static void KillAll(ESfxChannels); + static void TurnOnChannel(ESfxChannels); + static void TurnOffChannel(ESfxChannels); + + static void DisableAuxCallback(); + static void EnableAuxCallback(); + static void PrepareDelayCallback(const SND_AUX_DELAY& info); + static void PrepareReverbStdCallback(const SND_AUX_REVERBSTD& info); + static void PrepareChorusCallback(const SND_AUX_CHORUS& info); + static void PrepareReverbHiCallback(const SND_AUX_REVERBHI& info); + static void DisableAuxProcessing(); +}; + +#endif // _CSFXMANAGER diff --git a/include/Kyoto/Audio/CStreamAudioManager.hpp b/include/Kyoto/Audio/CStreamAudioManager.hpp new file mode 100644 index 0000000..ca3aeae --- /dev/null +++ b/include/Kyoto/Audio/CStreamAudioManager.hpp @@ -0,0 +1,31 @@ +#ifndef _CSTREAMAUDIOMANAGER +#define _CSTREAMAUDIOMANAGER + +#include "types.h" + +#include "rstl/string.hpp" + +class CStreamAudioManager { +public: + static void Update(float dt); + static void StopAll(); + static void SetMusicVolume(uint); + static void SetSfxVolume(uint); + + static void FadeBackIn(int, float); + static void TemporaryFadeOut(int, float); + + static void Start(int, const rstl::string&, int, bool, float, float); + static void Stop(int, const rstl::string&); + + static void sub_803653f8(float); + static void sub_80365424(float); + static void sub_8036590c(float); + + static void SetDefaultAudio(const rstl::string&, float, float, unsigned char); + static void SetCurrentAudio(const rstl::string&, float, float, unsigned char); + +private: +}; + +#endif // _CSTREAMAUDIOMANAGER diff --git a/include/Kyoto/Audio/g721.h b/include/Kyoto/Audio/g721.h new file mode 100644 index 0000000..a0a06ac --- /dev/null +++ b/include/Kyoto/Audio/g721.h @@ -0,0 +1,34 @@ +#ifndef _G721 +#define _G721 + +struct g72x_state { + long yl; /* Locked or steady state step size multiplier. */ + short yu; /* Unlocked or non-steady state step size multiplier. */ + short dms; /* Short term energy estimate. */ + short dml; /* Long term energy estimate. */ + short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ + + short a[2]; /* Coefficients of pole portion of prediction filter. */ + short b[6]; /* Coefficients of zero portion of prediction filter. */ + short pk[2]; /* + * Signs of previous two samples of a partially + * reconstructed signal. + */ + short dq[6]; /* + * Previous 6 samples of the quantized difference + * signal represented in an internal floating point + * format. + */ + short sr[2]; /* + * Previous 2 samples of the quantized difference + * signal represented in an internal floating point + * format. + */ + char td; /* delayed tone detect, new in 1988 version */ +}; + +void g72x_init_state(struct g72x_state* state_ptr); + +int g721_decoder(int i, struct g72x_state* state_ptr); + +#endif // _G721 diff --git a/include/Kyoto/Basics/CBasics.hpp b/include/Kyoto/Basics/CBasics.hpp new file mode 100644 index 0000000..23ea9f9 --- /dev/null +++ b/include/Kyoto/Basics/CBasics.hpp @@ -0,0 +1,28 @@ +#ifndef _CBASICS +#define _CBASICS + +#include "types.h" + +namespace CBasics { +bool Init(); +char* Stringize(const char* fmt, ...); +inline uint SwapBytes(uint x) { +#if 0 + x = ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24)); +#endif + return x; +} +inline float SwapBytes(float x) { + union { + float f; + uint u; + }; + f = x; +#if 0 + u = SwapBytes(u); +#endif + return f; +} +}; // namespace CBasics + +#endif // _CBASICS diff --git a/include/Kyoto/Basics/CCast.hpp b/include/Kyoto/Basics/CCast.hpp new file mode 100644 index 0000000..4887035 --- /dev/null +++ b/include/Kyoto/Basics/CCast.hpp @@ -0,0 +1,67 @@ +#ifndef _CCAST +#define _CCAST + +#include "types.h" + +#include "dolphin/os/OSFastCast.h" + +namespace CCast { +#ifdef __MWERKS__ +inline uchar ToUint8(register float in) { + uchar a; + register uchar* ptr = &a; + + asm { + psq_st in, 0(ptr), 1, OS_FASTCAST_U8 + } + return *ptr; +} + +inline uchar ToUint8(int c) { return static_cast(c); } + +inline float ToReal32(register const uchar& in) { + register float r; + asm { + psq_l r, 0(in), 1, 2 + } + return r; +} + +inline short FtoS(register float in) { + short a; + register short* ptr = &a; + + asm { + psq_st in, 0(ptr), 1, OS_FASTCAST_S16 + } + return *ptr; +} + +inline ushort FtoUS(register float in) { + ushort a; + register ushort* ptr = &a; + + asm { + psq_st in, 0(ptr), 1, OS_FASTCAST_U16 + } + return *ptr; +} + +inline int FtoL(float in) { return static_cast< int >(in); } +inline float LtoF(int in) { return static_cast< float >(in); } + +#else +inline uchar ToUint8(float in) { return static_cast< uchar >(in); } +inline uchar ToUint8(int c) { return static_cast(c); } +inline float ToReal32(uchar in) { return static_cast< float >(in); } +inline short FtoS(float in) { return static_cast< short >(in); } +inline ushort FtoUS(float in) { return static_cast< ushort >(in); } +inline int FtoL(float in) { return static_cast< int >(in); } +inline float LtoF(int in) { return static_cast< float >(in); } +#endif + +inline int ToInt32(float in) { return static_cast< int >(in); } +inline char ToChar(int c) { return ToUint8(c) ; } +} // namespace CCast + +#endif // _CCAST diff --git a/include/Kyoto/Basics/COsContext.hpp b/include/Kyoto/Basics/COsContext.hpp new file mode 100644 index 0000000..0e1aeef --- /dev/null +++ b/include/Kyoto/Basics/COsContext.hpp @@ -0,0 +1,77 @@ +#ifndef _COSCONTEXT +#define _COSCONTEXT + +#include + +#include "types.h" + +#include + +enum EConsoleType { + kCT_Emulator, + kCT_Development1, + kCT_Development2Or3, + kCT_Retail, +}; + +class COsKeyState { +public: + COsKeyState(int key, bool down, bool released, bool repeat, bool unk) + : x0_key(key), x4_down(down), x4_released(released), x4_repeat(repeat), x4_unk(unk) {} + + bool IsPressed() const { return x4_down; } + bool JustPressed() const { return x4_unk && x4_down; } + +private: + int x0_key; + short x4_down : 1; + short x4_released : 1; + short x4_repeat : 1; + short x4_unk : 1; +}; + +class COsContext { +public: + // TODO: Once main.cpp is matched make this private + static bool mProgressiveMode; + + COsContext(bool, bool); + ~COsContext(); + + int OpenWindow(const char* title, int x, int y, int w, int h, bool fullscreen); + bool Update(); + COsKeyState GetOsKeyState(int key) const; + + void* AllocFromArena(size_t sz); + + uint GetBaseFreeRam() const { + size_t hiAddr = reinterpret_cast< size_t >(x1c_arenaHi); + size_t loAddr = reinterpret_cast< size_t >(x20_arenaLo2); + return ((hiAddr & ~31) - ((loAddr + 31) & ~31)); + } + + void* GetFramebuf1() const { return x24_frameBuffer1; } + void* GetFramebuf2() const { return x28_frameBuffer2; } + const GXRenderModeObj& GetRenderModeObj() const { return x30_renderMode; } + + static void SetProgressiveMode(bool progressive) { mProgressiveMode = progressive; } + static bool GetProgressiveMode() { return mProgressiveMode; } + +private: + int x0_right; + int x4_bottom; + int x8_left; + int xc_top; + int x10_format; + int x14_consoleType; + void* x18_arenaLo1; + void* x1c_arenaHi; + void* x20_arenaLo2; + void* x24_frameBuffer1; + void* x28_frameBuffer2; + int x2c_frameBufferSize; + GXRenderModeObj x30_renderMode; +}; +CHECK_SIZEOF(COsContext, 0x6c) + +#endif // _COSCONTEXT diff --git a/include/Kyoto/CARAMManager.hpp b/include/Kyoto/CARAMManager.hpp new file mode 100644 index 0000000..6585786 --- /dev/null +++ b/include/Kyoto/CARAMManager.hpp @@ -0,0 +1,38 @@ +#ifndef _CARAMMANAGER +#define _CARAMMANAGER + +#include "types.h" + +class CARAMManager { +public: + enum EDMAPriority { + kDMAPrio_Zero, + kDMAPrio_One, + kDMAPrio_Two, + kDMAPrio_Three, + kDMAPrio_Four, + kDMAPrio_Five, + kDMAPrio_Six, + }; + + static void Shutdown(); + static void CollectGarbage(); + static void PreInitializeAlloc(uint size) { mPreInitializeAlloc += size; } + static void Initialize(uint); + static void WaitForAllDMAsToComplete(); + static const void* GetInvalidAlloc() { return (const void*)kInvalidAlloc; } + static const uint GetInvalidDMAHandle() { return kInvalidHandle; } + static bool CancelDMA(uint); + static void WaitForDMACompletion(uint); + static bool IsDMACompleted(uint handle); + static void* Alloc(uint len); + static void Free(const void* ptr); + static int DMAToARAM(void*, void*, uint, EDMAPriority); + static int DMAToMRAM(void*, void*, uint, EDMAPriority); +private: + static uint mPreInitializeAlloc; + static const int kInvalidAlloc; + static const int kInvalidHandle; +}; + +#endif // _CARAMMANAGER diff --git a/include/Kyoto/CARAMToken.hpp b/include/Kyoto/CARAMToken.hpp new file mode 100644 index 0000000..646e2d8 --- /dev/null +++ b/include/Kyoto/CARAMToken.hpp @@ -0,0 +1,50 @@ +#ifndef _CARAMTOKEN +#define _CARAMTOKEN + +#include "types.h" + +class CARAMToken { + static CARAMToken* sLists[7]; +public: + enum EStatus { + kS_Zero, + kS_One, + kS_Two, + kS_Three, + kS_Four, + kS_Five, + kS_Six, + }; + + CARAMToken(); + CARAMToken(void* ptr, uint len, int unk); + CARAMToken(const CARAMToken& other); + ~CARAMToken(); + void PostConstruct(void* ptr, uint len, int unk); + CARAMToken& operator=(const CARAMToken& other); + bool LoadToMRAM(); + bool LoadToARAM(); + bool RefreshStatus(); + static void UpdateAllDMAs(); + void InitiallyMoveToList(); + void MoveToList(EStatus status); + void RemoveFromList(); + void MakeInvalid(); + + void* sub_803583d4(); + void sub_80358388(); + + void* GetMRAMSafe(); + +private: + EStatus x0_status; + void* x4_mramPtr; + const void* x8_aramPtr; + int xc_dataLen; + uint x10_dmaHandle; + CARAMToken* x14_prev; + CARAMToken* x18_next; + bool x1c_24_ : 1; +}; + +#endif // _CARAMTOKEN diff --git a/include/Kyoto/CCrc32.hpp b/include/Kyoto/CCrc32.hpp new file mode 100644 index 0000000..3363892 --- /dev/null +++ b/include/Kyoto/CCrc32.hpp @@ -0,0 +1,10 @@ +#ifndef _CCRC32 +#define _CCRC32 +#include "types.h" + +class CCRC32 { +public: + static uint Calculate(const void* data, uint length); +}; + +#endif // _CCRC32 diff --git a/include/Kyoto/CDependencyGroup.hpp b/include/Kyoto/CDependencyGroup.hpp new file mode 100644 index 0000000..cfe6981 --- /dev/null +++ b/include/Kyoto/CDependencyGroup.hpp @@ -0,0 +1,23 @@ +#ifndef _CDEPENDENCYGROUP +#define _CDEPENDENCYGROUP + +#include "Kyoto/SObjectTag.hpp" + +#include "rstl/vector.hpp" + +class CInputStream; + +class CDependencyGroup { +public: + explicit CDependencyGroup(CInputStream& in); + ~CDependencyGroup() {} + void ReadFromStream(CInputStream& in); + int GetCountForResType(FourCC type) const; + + const rstl::vector< SObjectTag >& GetObjectTagVector() const { return x0_objectTags; } + +private: + rstl::vector< SObjectTag > x0_objectTags; +}; + +#endif // _CDEPENDENCYGROUP diff --git a/include/Kyoto/CDvdFile.hpp b/include/Kyoto/CDvdFile.hpp new file mode 100644 index 0000000..edefbb3 --- /dev/null +++ b/include/Kyoto/CDvdFile.hpp @@ -0,0 +1,57 @@ +#ifndef _CDVDFILE +#define _CDVDFILE + +#include "Kyoto/CDvdRequest.hpp" +#include "types.h" + +#include "rstl/auto_ptr.hpp" +#include "rstl/reserved_vector.hpp" +#include "rstl/single_ptr.hpp" +#include "rstl/string.hpp" + +enum ESeekOrigin { kSO_Set, kSO_Cur, kSO_End }; + + +class CDvdFile; +struct CDvdFileARAM; +struct DVDFileInfo; +class CDvdFile { +public: + CDvdFile(const char* name); + ~CDvdFile(); + uint Length() { return x14_size; } + void HandleDVDInterrupt(); + void HandleARAMInterrupt(); + void PingARAMTransfer(); + void TryARAMFile(); + void PushARAMFileLoad(); + void PopARAMFileLoad(); + bool IsARAMFileLoaded(); + void StartARAMFileLoad(); + void StallForARAMFile(); + CDvdRequest* SyncRead(void* buf, uint len); + CDvdRequest* SyncSeekRead(void* buf, uint len, ESeekOrigin, int offset); + CDvdRequest* AsyncSeekRead(void* buf, uint len, ESeekOrigin, int offset); + void CloseFile(); + void CalcFileOffset(int offset, ESeekOrigin origin); + void UpdateFilePos(int pos); + const int GetFileSize() const { return x14_size; } + + static bool FileExists(const char*); + static void DVDARAMXferCallback(long, DVDFileInfo*); + static void ARAMARAMXferCallback(u32 addr); + static void internalCallback(s32, DVDFileInfo*); + +private: + int x0_fileEntry; + uchar* x4_; + bool x8_; + bool x9_; + rstl::single_ptr< CDvdFileARAM > xc_; + int x10_offset; + int x14_size; + rstl::string x18_filename; +}; +CHECK_SIZEOF(CDvdFile, 0x28) + +#endif // _CDVDFILE diff --git a/include/Kyoto/CDvdRequest.hpp b/include/Kyoto/CDvdRequest.hpp new file mode 100644 index 0000000..85df208 --- /dev/null +++ b/include/Kyoto/CDvdRequest.hpp @@ -0,0 +1,42 @@ +#ifndef _CDVDREQUEST +#define _CDVDREQUEST + +#include "dolphin/dvd.h" +#include "types.h" + +class CDvdRequest { +public: + virtual ~CDvdRequest(){}; // 8 + virtual void WaitUntilComplete() = 0; // c + virtual bool IsComplete() = 0; // 10 + virtual void PostCancelRequest() = 0; // 14 + virtual int GetMediaType() const = 0; // 18 +}; + +class CRealDvdRequest : public CDvdRequest { +public: + ~CRealDvdRequest(); + void WaitUntilComplete(); + bool IsComplete(); + void PostCancelRequest(); + int GetMediaType() const; + + DVDFileInfo& FileInfo() { return mFileInfo; } + +private: + DVDFileInfo mFileInfo; +}; + +class CARAMDvdRequest : public CDvdRequest { +public: + CARAMDvdRequest(uint i) : x4_dmaReq(i) {} + void WaitUntilComplete(); + bool IsComplete(); + void PostCancelRequest(); + int GetMediaType() const; + +private: + uint x4_dmaReq; +}; + +#endif // _CDVDREQUEST diff --git a/include/Kyoto/CDvdRequestManager.hpp b/include/Kyoto/CDvdRequestManager.hpp new file mode 100644 index 0000000..377ab47 --- /dev/null +++ b/include/Kyoto/CDvdRequestManager.hpp @@ -0,0 +1,10 @@ +#ifndef _CDVDREQUESTMANAGER +#define _CDVDREQUESTMANAGER + +class CDvdRequestSys { +public: + static bool mManagerInstalled; +}; + + +#endif // _CDVDREQUESTMANAGER diff --git a/include/Kyoto/CFactoryMgr.hpp b/include/Kyoto/CFactoryMgr.hpp new file mode 100644 index 0000000..6d9c46f --- /dev/null +++ b/include/Kyoto/CFactoryMgr.hpp @@ -0,0 +1,29 @@ +#ifndef _CFACTORYMGR +#define _CFACTORYMGR + +#include "types.h" + +#include "Kyoto/IObjectStore.hpp" +#include "Kyoto/Streams/CInputStream.hpp" +#include "Kyoto/TToken.hpp" + +class CFactoryMgr { +public: +private: + uchar pad[0x38]; +}; + +class CFactoryFnReturn { +public: + template < typename T > + CFactoryFnReturn(T* ptr) : obj(TToken< T >::GetIObjObjectFor(ptr).release()) {} + + const rstl::auto_ptr& GetObjForTransfer() const { return obj; } +private: + rstl::auto_ptr< CObjOwnerDerivedFromIObjUntyped > obj; +}; + +CFactoryFnReturn FStringTableFactory(const SObjectTag& tag, CInputStream& in, + const CVParamTransfer& xfer); + +#endif // _CFACTORYMGR diff --git a/include/Kyoto/CFrameDelayedKiller.hpp b/include/Kyoto/CFrameDelayedKiller.hpp new file mode 100644 index 0000000..68998c4 --- /dev/null +++ b/include/Kyoto/CFrameDelayedKiller.hpp @@ -0,0 +1,15 @@ +#ifndef _CFRAMEDELAYEDKILLER +#define _CFRAMEDELAYEDKILLER + +#include "types.h" + +class CFrameDelayedKiller { +public: + static void Initialize(); + static void ShutDown(); + + static void sub_8036cb90(); + static void sub_8036cc1c(bool unk1, void* unk2); +}; + +#endif // _CFRAMEDELAYEDKILLER diff --git a/include/Kyoto/CMemoryCardSys.hpp b/include/Kyoto/CMemoryCardSys.hpp new file mode 100644 index 0000000..a841e81 --- /dev/null +++ b/include/Kyoto/CMemoryCardSys.hpp @@ -0,0 +1,112 @@ +#ifndef _CMEMORYCARDSYS +#define _CMEMORYCARDSYS + +#include "string.h" +#include "types.h" + +#include "Kyoto/CSimplePool.hpp" +#include "Kyoto/Streams/CMemoryStreamOut.hpp" + +#include "rstl/string.hpp" + +// TODO: likely comes from dolphin sdk +enum ECardResult { + kCR_CRC_MISMATCH = -1003, /* Extension enum for Retro's CRC check */ + kCR_FATAL_ERROR = -128, + kCR_ENCODING = -13, + kCR_NAMETOOLONG = -12, + kCR_INSSPACE = -9, + kCR_NOENT = -8, + kCR_EXIST = -7, + kCR_BROKEN = -6, + kCR_IOERROR = -5, + kCR_NOFILE = -4, + kCR_NOCARD = -3, + kCR_WRONGDEVICE = -2, + kCR_BUSY = -1, + kCR_READY = 0 +}; + +struct FileHandle { + u8 x0_pad[0x10]; +}; + +struct ProbeResults { + ECardResult x0_error; + int x4_cardSize; /* in megabits */ + int x8_sectorSize; /* in bytes */ +}; + +struct CardStat { + u8 x0_pad[0x6c]; + + CardStat() { memset(this, 0, sizeof(CardStat)); } + + int GetTime() const; + int GetCommentAddr() const; +}; + + +class CMemoryCardSys { +public: + enum EMemoryCardPort { kCS_SlotA, kCS_SlotB }; + + class CCardFileInfo { + uchar pad[0xf4]; + rstl::vector xf4_saveBuffer; + rstl::vector x104_cardBuffer; + + public: + CCardFileInfo(EMemoryCardPort port, const rstl::string& name); + ~CCardFileInfo(); + + void SetComment(const rstl::string& name); + void LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp); + void LockIconToken(CAssetId iconTxtr, int speed, CSimplePool& sp); + + ECardResult PumpCardTransfer(); + ECardResult CreateFile(); + ECardResult WriteFile(); + ECardResult CloseFile(); + + rstl::vector& SaveBuffer() { return xf4_saveBuffer; } + + inline CMemoryStreamOut BeginMemoryOut(uint sz) { + xf4_saveBuffer.resize(sz, '\x00'); + return CMemoryStreamOut(xf4_saveBuffer.data(), sz); + } + }; + + struct CardFileHandle { + EMemoryCardPort slot; + FileHandle handle; + CardFileHandle(EMemoryCardPort slot) : slot(slot) {} + int GetFileNo() const; + }; + + CMemoryCardSys(); + ~CMemoryCardSys(); + + static ECardResult GetResultCode(int); + static ECardResult MountCard(EMemoryCardPort port); + static ECardResult CheckCard(EMemoryCardPort port); + static ECardResult GetStatus(EMemoryCardPort port, int fileNo, CardStat& statOut); + static ECardResult DeleteFile(EMemoryCardPort port, const rstl::string& name); + static ECardResult FastDeleteFile(EMemoryCardPort port, int fileNo); + static ECardResult FormatCard(EMemoryCardPort port); + + static ProbeResults IsMemoryCardInserted(EMemoryCardPort); + static ECardResult GetSerialNo(EMemoryCardPort port, long long& serialOut); + static void UnmountCard(EMemoryCardPort); + static ECardResult Rename(EMemoryCardPort, const rstl::string&, const rstl::string&); + static ECardResult GetNumFreeBytes(EMemoryCardPort port, uint& freeBytes, uint& freeFiles); + + void Initialize(); + +private: + // TODO +}; + +NESTED_CHECK_SIZEOF(CMemoryCardSys, CCardFileInfo, 0x114) + +#endif // _CMEMORYCARDSYS diff --git a/include/Kyoto/CObjectReference.hpp b/include/Kyoto/CObjectReference.hpp new file mode 100644 index 0000000..8f7e6b2 --- /dev/null +++ b/include/Kyoto/CObjectReference.hpp @@ -0,0 +1,38 @@ +#ifndef _COBJECTREFERENCE +#define _COBJECTREFERENCE + +#include +#include +#include + +class IObj; +class IObjectStore; +class CObjectReference { +public: + CObjectReference(const rstl::auto_ptr< IObj >& obj); + ~CObjectReference(); + CObjectReference(IObjectStore& store, const rstl::auto_ptr< IObj >& obj, const SObjectTag& tag, + CVParamTransfer xfer); + + bool IsLoaded() const { return x10_object != nullptr; } + + void AddReference() { x0_refCount++; } + int RemoveReference(); + void Lock(); + void Unlock(); + IObj* GetObject(); + void Unload(); + void CancelLoad(); + bool IsLoading() const; + const SObjectTag& GetTag() const { return x4_objTag; } + +private: + short x0_refCount : 16; + short x2_lockCount : 15; + short x3_loading : 1; + SObjectTag x4_objTag; + IObjectStore* xc_objectStore; + IObj* x10_object; + CVParamTransfer x14_params; +}; +#endif // _COBJECTREFERENCE diff --git a/include/Kyoto/CPakFile.hpp b/include/Kyoto/CPakFile.hpp new file mode 100644 index 0000000..3a1918c --- /dev/null +++ b/include/Kyoto/CPakFile.hpp @@ -0,0 +1,40 @@ +#ifndef _CPAKFILE +#define _CPAKFILE + +#include "types.h" + +#include "rstl/auto_ptr.hpp" +#include "rstl/string.hpp" + +#include "Kyoto/CDvdFile.hpp" +#include "Kyoto/CResLoader.hpp" +#include "Kyoto/IObjectStore.hpp" + +class CDvdRequest; + +class CPakFile : CDvdFile { +public: + bool IsWorldPak() const { return x28_26_worldPak; } + void EnsureWorldPakReady(); + void sub_8036742c(); + + rstl::vector< rstl::pair< rstl::string, SObjectTag > >& NameList() { return x54_nameList; } + +private: + bool x28_24_buildDepList : 1; + bool x28_25_aramFile : 1; + bool x28_26_worldPak : 1; + bool x28_27_stashedInARAM : 1; + int x2c_asyncLoadPhase; // EAsyncPhase + rstl::auto_ptr< CDvdRequest > x30_dvdReq; + rstl::vector< uchar > x38_headerData; + uint x48_resTableOffset; + uint x4c_resTableCount; + int x50_aramBase; + rstl::vector< rstl::pair< rstl::string, SObjectTag > > x54_nameList; + rstl::vector< CAssetId > x64_depList; + rstl::vector< SResInfo > x74_resList; + mutable int x84_currentSeek; +}; + +#endif // _CPAKFILE diff --git a/include/Kyoto/CRandom16.hpp b/include/Kyoto/CRandom16.hpp new file mode 100644 index 0000000..a61103e --- /dev/null +++ b/include/Kyoto/CRandom16.hpp @@ -0,0 +1,39 @@ +#ifndef _CRANDOM16 +#define _CRANDOM16 + +#include "types.h" + +class CRandom16; +class CGlobalRandom { + static CGlobalRandom* gCurrentGlobalRandom; + +public: + CGlobalRandom(CRandom16& rnd); + ~CGlobalRandom(); + +private: + CRandom16& mRandom; + bool mIsFirst; + CGlobalRandom* mPrev; +}; + +class CRandom16 { + friend class CGlobalRandom; + static CRandom16* gRandomNumber; + static void _SetRandomNumber(CRandom16* rnd); + +public: + CRandom16(uint seed = 99); + void SetSeed(uint seed); + int Range(int min, int max); + float Range(float min, float max); + int Next(); + float Float(); + + static CRandom16* GetRandomNumber(); + +private: + uint mSeed; +}; + +#endif // _CRANDOM16 diff --git a/include/Kyoto/CResFactory.hpp b/include/Kyoto/CResFactory.hpp new file mode 100644 index 0000000..0be5a39 --- /dev/null +++ b/include/Kyoto/CResFactory.hpp @@ -0,0 +1,56 @@ +#ifndef _CRESFACTORY +#define _CRESFACTORY + +#include "types.h" + +#include "rstl/list.hpp" + +#include "Kyoto/CFactoryMgr.hpp" +#include "Kyoto/CResLoader.hpp" + +class IFactory { +public: + virtual ~IFactory() {} + virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&) = 0; + virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**) = 0; + virtual void CancelBuild(const SObjectTag&) = 0; + virtual bool CanBuild(const SObjectTag&) = 0; + virtual const SObjectTag* GetResourceIdByName(const char* name) const = 0; + // TODO +}; + +class CResFactory : public IFactory { +public: + CResFactory(); + + ~CResFactory() {} + CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&); + void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**); + void CancelBuild(const SObjectTag&); + bool CanBuild(const SObjectTag&); + const SObjectTag* GetResourceIdByName(const char* name) const; + + uint ResourceSize(const SObjectTag& tag) const { return x4_resLoader.ResourceSize(tag); } + + void AsyncIdle(uint time); + + CResLoader& GetResLoader() { return x4_resLoader; } + FourCC GetResourceTypeById(CAssetId id) { return GetResLoader().GetResourceTypeById(id); } + +private: + CResLoader x4_resLoader; + CFactoryMgr x5c_factoryMgr; + uint x94_; + uint x98_; + uint x9c_; + uint xa0_; + uint xa4_; + uint xa8_; + uint xac_; + rstl::list< unkptr > xb0_; +}; +CHECK_SIZEOF(CResFactory, 0xc8); + +extern CResFactory* gpResourceFactory; + +#endif // _CRESFACTORY diff --git a/include/Kyoto/CResLoader.hpp b/include/Kyoto/CResLoader.hpp new file mode 100644 index 0000000..9b66e01 --- /dev/null +++ b/include/Kyoto/CResLoader.hpp @@ -0,0 +1,46 @@ +#ifndef _CRESLOADER +#define _CRESLOADER + +#include "types.h" + +#include "rstl/list.hpp" +#include "rstl/string.hpp" + +#include "Kyoto/IObjectStore.hpp" + +class CPakFile; +class CARAMDvdRequest; + +struct SResInfo { + CAssetId x0_id; + bool x4_compressed : 1; + int x4_typeIdx; // CFactoryMgr::ETypeTable + uint x5_offsetDiv32 : 27; + uint x7_sizeDiv32 : 27; +}; + +class CResLoader { +public: + int GetPakCount() const; + CPakFile& GetPakFile(int idx) const; + void AddPakFileAsync(const rstl::string&, bool, bool); + void AsyncIdlePakLoading(); + bool AreAllPaksLoaded() const; + CInputStream* LoadNewResourceSync(const SObjectTag& tag, char* extBuf); + CInputStream* LoadNewResourceSync(const SObjectTag& tag, int, int, char* extBuf); + CARAMDvdRequest* LoadResourcePartAsync(const SObjectTag& tag, int, int, char*); + + FourCC GetResourceTypeById(CAssetId) const; + uint ResourceSize(const SObjectTag& tag) const; + +private: + rstl::list< unkptr > x0_aramList; + rstl::list< unkptr > x18_pakLoadedList; + rstl::list< unkptr > x30_pakLoadingList; + unkptr x48_curPak; + CAssetId x4c_cachedResId; + SResInfo* x50_cachedResInfo; + bool x54_forwardSeek; +}; + +#endif // _CRESLOADER diff --git a/include/Kyoto/CSimplePool.hpp b/include/Kyoto/CSimplePool.hpp new file mode 100644 index 0000000..5cd6059 --- /dev/null +++ b/include/Kyoto/CSimplePool.hpp @@ -0,0 +1,39 @@ +#ifndef _CSIMPLEPOOL +#define _CSIMPLEPOOL + +#include "types.h" + +#include "rstl/hash_map.hpp" +#include "rstl/rc_ptr.hpp" + +#include "Kyoto/CToken.hpp" +#include "Kyoto/IObjectStore.hpp" + +class IFactory; +class CSimplePool : public IObjectStore { +public: + CSimplePool(IFactory& factory) : x18_factory(factory) {} + ~CSimplePool(); + + virtual CToken GetObj(const SObjectTag& tag, CVParamTransfer xfer); + virtual CToken GetObj(const SObjectTag& tag); + virtual CToken GetObj(const char* name); + virtual CToken GetObj(const char* name, CVParamTransfer xfer); + virtual bool HasObject(const SObjectTag& tag); + virtual bool ObjectIsLive(const SObjectTag& tag); + virtual IFactory& GetFactory() { return x18_factory; } + virtual void Flush(); + virtual void ObjectUnreferenced(const SObjectTag& tag); + +private: + uchar x4_; + uchar x5_; + rstl::hash_map< unkptr, unkptr, void, void > x8_resources; + IFactory& x18_factory; + rstl::rc_ptr< CVParamTransfer > x1c_paramXfr; +}; +CHECK_SIZEOF(CSimplePool, 0x20) + +extern CSimplePool* gpSimplePool; + +#endif // _CSIMPLEPOOL diff --git a/include/Kyoto/CTimeProvider.hpp b/include/Kyoto/CTimeProvider.hpp new file mode 100644 index 0000000..d847795 --- /dev/null +++ b/include/Kyoto/CTimeProvider.hpp @@ -0,0 +1,20 @@ +#ifndef _CTIMEPROVIDER +#define _CTIMEPROVIDER + +#include + +class CTimeProvider { + static CTimeProvider* gCurrentTimeProvider; + +public: + CTimeProvider(const float& time); + ~CTimeProvider(); + float GetSecondsMod900() const { return x0_currentTime; } + +private: + const float& x0_currentTime; // in seconds + bool x4_first; + CTimeProvider* x8_lastProvider; +}; + +#endif // _CTIMEPROVIDER diff --git a/include/Kyoto/CToken.hpp b/include/Kyoto/CToken.hpp new file mode 100644 index 0000000..d55b572 --- /dev/null +++ b/include/Kyoto/CToken.hpp @@ -0,0 +1,38 @@ +#ifndef _CTOKEN +#define _CTOKEN + +#include "types.h" + +#include "Kyoto/CObjectReference.hpp" +#include "Kyoto/IObj.hpp" + +class CObjectReference; + +class CToken { +public: + CToken() {} + CToken(CObjectReference* ref); + CToken(IObj* obj); // : x0_objRef(new CObjectReference(obj)), x4_lockHeld(false) {} + CToken(const CToken& other); + ~CToken(); + + CObjOwnerDerivedFromIObjUntyped* GetObj(); + void Lock(); + void Unlock(); + bool IsLoaded() const { return x0_objRef->IsLoaded(); } + void RemoveRef(); + CToken& operator=(const CToken&); + bool HasReference() const { return x0_objRef != nullptr; } + const SObjectTag& GetTag() const { return x0_objRef->GetTag(); } + FourCC GetReferenceType() { return GetTag().type; } + + bool HasLock() { return x4_lockHeld; } + + const CObjectReference* GetRef() const { return x0_objRef; } + +private: + CObjectReference* x0_objRef; + bool x4_lockHeld; +}; + +#endif // _CTOKEN diff --git a/include/Kyoto/CVParamTransfer.hpp b/include/Kyoto/CVParamTransfer.hpp new file mode 100644 index 0000000..9f3945d --- /dev/null +++ b/include/Kyoto/CVParamTransfer.hpp @@ -0,0 +1,33 @@ +#ifndef _CVPARAMTRANSFER +#define _CVPARAMTRANSFER + +#include "Kyoto/IObj.hpp" +#include + +class IVParamObj : public IObj {}; + +template < typename T > +class TObjOwnerParam : public IVParamObj { +public: + ~TObjOwnerParam() {} + TObjOwnerParam(T data) : x4_data(data) {} + T GetData() const { return static_cast(x4_data); } + +private: + T x4_data; +}; + +class CVParamTransfer { +public: + CVParamTransfer() {} + template < typename T > + CVParamTransfer(TObjOwnerParam< T >* obj) : x0_obj(obj) {} + static CVParamTransfer Null(); + + const IVParamObj& operator*() const { return *x0_obj; } + +private: + rstl::rc_ptr< IVParamObj > x0_obj; +}; + +#endif // _CVPARAMTRANSFER diff --git a/include/Kyoto/Graphics/CColor.hpp b/include/Kyoto/Graphics/CColor.hpp new file mode 100644 index 0000000..63417c7 --- /dev/null +++ b/include/Kyoto/Graphics/CColor.hpp @@ -0,0 +1,106 @@ +#ifndef _CCOLOR +#define _CCOLOR + +#include "types.h" + +#include "Kyoto/Basics/CCast.hpp" +#include "Kyoto/Math/CMath.hpp" + +#include + +#ifdef __MWERKS__ +#pragma cpp_extensions on +#endif + +class CInputStream; +class CColor { +public: + CColor() { Set(255, 0, 255); } + CColor(uint col) { Set(col); } + CColor(CInputStream& in); + CColor(float r, float g, float b, float a = 1.f); + CColor(uchar r, uchar g, uchar b, uchar a = 255) { + mR = r; + mG = g; + mB = b; + mA = a; + } + + void Set(float r, float g, float b, float a); + void Set(uchar r, uchar g, uchar b, uchar a = 255) { + mR = r; + mG = g; + mB = b; + mA = a; + } + void Set(uint col) { mRgba = col; } + void Get(float& r, float& g, float& b, float& a) const; + void Get(float& r, float& g, float& b) const; + // TODO check. Maybe this calls SetAlpha(uchar)? + void SetAlpha(float a) { mA = CCast::ToUint8(a * 255.f); } + void SetAlpha(uchar a) { mRgba = (mRgba & ~0xff) | a; } + + static CColor Lerp(const CColor& a, const CColor& b, float t); + static uint Lerp(uint a, uint b, float t); + static CColor Modulate(const CColor& a, const CColor& b); + static CColor Add(const CColor& a, const CColor& b); + float GetRed() const { return CCast::ToReal32(mR) * (1.f / 255.f); } + float GetGreen() const { return CCast::ToReal32(mG) * (1.f / 255.f); } + float GetBlue() const { return CCast::ToReal32(mB) * (1.f / 255.f); } + float GetAlpha() const { return CCast::ToReal32(mA) * (1.f / 255.f); } + uchar GetRedu8() const { return mR; } + uchar GetGreenu8() const { return mG; } + uchar GetBlueu8() const { return mB; } + uchar GetAlphau8() const { return mA; } + ushort ToRGB5A3() const; + uint GetColor_u32() const { return mRgba; } + const GXColor& GetGXColor() const { return *reinterpret_cast< const GXColor* >(this); } + + CColor WithAlphaOf(float a) const { return CColor((mRgba & ~0xff) | CCast::ToUint8(a * 255.f)); } + CColor WithAlphaModulatedBy(float a) const { + return CColor((mRgba & ~0xff) | CCast::ToUint8(a * static_cast< float >(mA))); + } + + bool operator==(const CColor& other) const { return mRgba == other.mRgba; } + + // TODO check + static GXColor ToGX(uint c) { return *reinterpret_cast< const GXColor* >(&c); } + + static const CColor& Black(); + static const CColor& White(); + static const CColor& Grey(); + static const CColor& Red(); + static const CColor& Green(); + static const CColor& Blue(); + static const CColor& Yellow(); + static const CColor& Purple(); + static const CColor& Orange(); + +private: + union { + struct { + uchar mR; + uchar mG; + uchar mB; + uchar mA; + }; + uint mRgba; + }; + + static const CColor sBlackColor; + static const CColor sWhiteColor; + static const CColor sGreyColor; + static const CColor sRedColor; + static const CColor sGreenColor; + static const CColor sBlueColor; + static const CColor sYellowColor; + static const CColor sPurpleColor; + static const CColor sOrangeColor; +}; +CHECK_SIZEOF(CColor, 0x4) + +#ifdef __MWERKS__ +#pragma cpp_extensions off +#endif + +#endif // _CCOLOR diff --git a/include/Kyoto/Graphics/CCubeMaterial.hpp b/include/Kyoto/Graphics/CCubeMaterial.hpp new file mode 100644 index 0000000..406e526 --- /dev/null +++ b/include/Kyoto/Graphics/CCubeMaterial.hpp @@ -0,0 +1,19 @@ +#ifndef _CCUBEMATERIAL +#define _CCUBEMATERIAL + +#include "types.h" + +#include "Kyoto/Graphics/CModelFlags.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +extern CVector3f sPlayerPosition; + +class CCubeMaterial { +public: +private: + static void SetupBlendMode(uint blendFactors, const CModelFlags& flags, bool alphaTest); + + static CVector3f sViewingFrom; +}; + +#endif // _CCUBEMATERIAL diff --git a/include/Kyoto/Graphics/CCubeModel.hpp b/include/Kyoto/Graphics/CCubeModel.hpp new file mode 100644 index 0000000..67adf34 --- /dev/null +++ b/include/Kyoto/Graphics/CCubeModel.hpp @@ -0,0 +1,15 @@ +#ifndef _CCUBEMODEL +#define _CCUBEMODEL + +class CTexture; +class CTransform4f; + +class CCubeModel { +public: + static void SetRenderModelBlack(bool v); + static void DisableShadowMaps(); + static void EnableShadowMaps(const CTexture*, const CTransform4f&, unsigned char, unsigned char); + static void SetDrawingOccluders(bool); +}; + +#endif // _CCUBEMODEL diff --git a/include/Kyoto/Graphics/CCubeSurface.hpp b/include/Kyoto/Graphics/CCubeSurface.hpp new file mode 100644 index 0000000..ed472cc --- /dev/null +++ b/include/Kyoto/Graphics/CCubeSurface.hpp @@ -0,0 +1,25 @@ +#ifndef _CCUBESURFACE +#define _CCUBESURFACE + +#include "Kyoto/Math/CAABox.hpp" + +class CCubeModel; +class CCubeSurface { + struct SSurfaceData { + CVector3f mCenter; + uint mMaterialIndex; + uint mDisplayListSizeAndNormalHint; + CCubeModel* mParent; + CCubeSurface* mNextSurface; + uint mExtraSize; + CVector3f mNormal; + CAABox mBounds; + }; + + static const CVector3f skDefaultNormal; + const SSurfaceData* x0_data; + + CAABox GetBounds() const; +private: +}; +#endif // _CCUBESURFACE diff --git a/include/Kyoto/Graphics/CGX.hpp b/include/Kyoto/Graphics/CGX.hpp new file mode 100644 index 0000000..0eff4c3 --- /dev/null +++ b/include/Kyoto/Graphics/CGX.hpp @@ -0,0 +1,172 @@ +#ifndef _CGX +#define _CGX + +#include "types.h" + +#include + +#include +#include + +class CGX { +public: + struct STevState { + uint x0_colorInArgs; + uint x4_alphaInArgs; + uint x8_colorOps; + uint xc_alphaOps; + uint x10_indFlags; + uint x14_tevOrderFlags; + uchar x18_kColorSel; + uchar x19_kAlphaSel; + + STevState(); + }; + + struct STexState { + uint x0_coordGen; + + STexState(); + }; + + struct SFogParams { + float x0_fogStartZ; + float x4_fogEndZ; + float x8_fogNearZ; + float xc_fogFarZ; + GXColor x10_fogColor; + + SFogParams() : x0_fogStartZ(0.f), x4_fogEndZ(1.f), x8_fogNearZ(0.1f), xc_fogFarZ(1.f) { + x10_fogColor.a = 0; + x10_fogColor.b = 0; + x10_fogColor.g = 0; + x10_fogColor.r = 0; + } + }; + + struct SGXState { + const void* x0_arrayPtrs[12]; + ushort x30_prevChanCtrls[2]; + ushort x34_chanCtrls[2]; + GXColor x38_chanAmbColors[2]; + GXColor x40_chanMatColors[2]; + uint x48_descList; + union { + uchar x4c_chanFlags; + struct { + uchar unused : 5; + uchar chansDirty : 2; + uchar numDirty : 1; + } x4c_flags; + }; + uchar x4d_prevNumChans; + uchar x4e_numChans; + uchar x4f_numTexGens; + uchar x50_numTevStages; + uchar x51_numIndStages; + uchar x52_zmode; + uchar x53_fogType; + ushort x54_lineWidthAndOffset; + ushort x56_blendMode; + GXColor x58_kColors[4]; + STevState x68_tevStates[16]; + STexState x228_texStates[8]; + uint x248_alphaCompare; + SFogParams x24c_fogParams; + + SGXState(); + }; + + enum EChannelId { + Channel0, // GX_COLOR0 + Channel1, // GX_COLOR1 + }; + + static void SetNumChans(uchar num); + static void SetNumTexGens(uchar num); + static void SetNumTevStages(uchar num); + static void SetNumIndStages(uchar num); + static void SetChanAmbColor(EChannelId channel, const GXColor& color); + static void SetChanMatColor(EChannelId channel, const GXColor& color); + static void SetChanCtrl(EChannelId channel, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, + GXLightID lights, GXDiffuseFn diffFn, GXAttnFn attnFn); + static void SetTevKColor(GXTevKColorID id, const GXColor& color); + static void SetTevColorIn(GXTevStageID stageId, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, + GXTevColorArg d); + static void SetTevAlphaIn(GXTevStageID stageId, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, + GXTevAlphaArg d); + static void SetTevColorOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevScale scale, + GXBool clamp, GXTevRegID outReg); + static void SetTevColorOp_Compressed(GXTevStageID stageId, uint flags); + static void SetTevAlphaOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevScale scale, + GXBool clamp, GXTevRegID outReg); + static void SetTevAlphaOp_Compressed(GXTevStageID stageId, uint flags); + static void SetTevKColorSel(GXTevStageID stageId, GXTevKColorSel sel); + static void SetTevKAlphaSel(GXTevStageID stageId, GXTevKAlphaSel sel); + static void SetTevOrder(GXTevStageID stageId, GXTexCoordID texCoord, GXTexMapID texMap, + GXChannelID color); + static void SetBlendMode(GXBlendMode mode, GXBlendFactor srcFac, GXBlendFactor dstFac, + GXLogicOp op); + static void SetZMode(GXBool compareEnable, GXCompare func, GXBool updateEnable); + static void SetAlphaCompare(GXCompare comp0, uchar ref0, GXAlphaOp op, GXCompare comp1, + uchar ref1); + static void SetTevIndirect(GXTevStageID stageId, GXIndTexStageID indStage, GXIndTexFormat fmt, + GXIndTexBiasSel biasSel, GXIndTexMtxID mtxSel, GXIndTexWrap wrapS, + GXIndTexWrap wrapT, GXBool addPrev, GXBool indLod, + GXIndTexAlphaSel alphaSel); + static void SetTevDirect(GXTevStageID stageId); + static void SetTexCoordGen(GXTexCoordID dstCoord, GXTexGenType fn, GXTexGenSrc src, GXTexMtx mtx, + GXBool normalize, GXPTTexMtx postMtx); + static void SetArray(GXAttr attr, const void* data, uchar stride); + static void SetFog(GXFogType type, float startZ, float endZ, float nearZ, float farZ, + const GXColor& color); + static void SetLineWidth(uchar width, GXTexOffset offset); + static void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp); + static void SetVtxDescv_Compressed(uint flags); + static void SetVtxDesc(GXAttr attr, GXAttrType type); // name? + static void ResetVtxDescv(); // name? + static void SetVtxDescv(const GXVtxDescList* list); + static void SetStandardDirectTev_Compressed(GXTevStageID stageId, uint colorArgs, uint alphaArgs, + uint colorOps, uint alphaOps); + static void SetStandardTevColorAlphaOp(GXTevStageID stageId); + + static void CallDisplayList(const void* ptr, size_t size); + static void Begin(GXPrimitive prim, GXVtxFmt fmt, ushort numVtx); + static void End(); + static void ResetGXStates(); + static void ResetGXStatesFull(); // name? + + static inline void LoadTexMtxImm(const float mtx[][4], unsigned long id, GXTexMtxType type) { + GXLoadTexMtxImm(const_cast< MtxPtr >(mtx), id, type); + } + + static GXColor GetChanAmbColor(EChannelId channel); + static void GetFog(GXFogType* fogType, float* fogStartZ, float* fogEndZ, float* fogNearZ, + float* fogFarZ, GXColor* fogColor); + + static inline bool CompareGXColors(const GXColor& lhs, const GXColor& rhs) { + return *reinterpret_cast< const uint* >(&lhs) == *reinterpret_cast< const uint* >(&rhs); + } + static inline void CopyGXColor(GXColor& dst, const GXColor& src) { + *reinterpret_cast< uint* >(&dst) = *reinterpret_cast< const uint* >(&src); + } + static inline uint MaskAndShiftLeft(uint v, uint m, uint s) { return (v & m) << s; } + static inline uint ShiftRightAndMask(uint v, uint m, uint s) { return (v >> s) & m; } + +private: + static void FlushState(); + static void update_fog(uint flags); + static void apply_fog() { + static const GXColor black = {0, 0, 0, 0}; + GXSetFog(static_cast< GXFogType >(sGXState.x53_fogType), sGXState.x24c_fogParams.x0_fogStartZ, + sGXState.x24c_fogParams.x4_fogEndZ, sGXState.x24c_fogParams.x8_fogNearZ, + sGXState.x24c_fogParams.xc_fogFarZ, + (sGXState.x56_blendMode & (7 << 5)) == (GX_BL_ONE << 5) + ? black + : sGXState.x24c_fogParams.x10_fogColor); + } + + static SGXState sGXState; +}; + +#endif // _CGX diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp new file mode 100644 index 0000000..d837018 --- /dev/null +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -0,0 +1,464 @@ +#ifndef _CGRAPHICS +#define _CGRAPHICS + +#include "types.h" + +#include "Kyoto/CTimeProvider.hpp" +#include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Graphics/CLight.hpp" +#include "Kyoto/Graphics/CTevCombiners.hpp" +#include "Kyoto/Graphics/CTexture.hpp" +#include "Kyoto/Math/CMatrix4f.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector2i.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +#include "dolphin/gx.h" +#include "dolphin/mtx.h" + +enum ERglFogMode { + kRFM_None = GX_FOG_NONE, + + kRFM_PerspLin = GX_FOG_PERSP_LIN, + kRFM_PerspExp = GX_FOG_PERSP_EXP, + kRFM_PerspExp2 = GX_FOG_ORTHO_EXP2, + kRFM_PerspRevExp = GX_FOG_PERSP_REVEXP, + kRFM_PerspRevExp2 = GX_FOG_PERSP_REVEXP2, + + kRFM_OrthoLin = GX_FOG_ORTHO_LIN, + kRFM_OrthoExp = GX_FOG_ORTHO_EXP, + kRFM_OrthoExp2 = GX_FOG_ORTHO_EXP2, + kRFM_OrthoRevExp = GX_FOG_ORTHO_REVEXP, + kRFM_OrthoRevExp2 = GX_FOG_ORTHO_REVEXP2, +}; + +enum ERglTevStage { + kTS_Stage0, + kTS_Stage1, + kTS_Stage2, + kTS_Stage3, + kTS_Stage4, + kTS_Stage5, + kTS_Stage6, + kTS_Stage7, + kTS_Stage8, + kTS_Stage9, + kTS_Stage10, + kTS_Stage11, + kTS_Stage12, + kTS_Stage13, + kTS_Stage14, + kTS_Stage15, + kTS_MaxStage, +}; + +enum ERglPrimitive { + kP_Quads = GX_QUADS, + kP_Triangles = GX_TRIANGLES, + kP_TriangleStrip = GX_TRIANGLESTRIP, + kP_TriangleFan = GX_TRIANGLEFAN, + kP_Lines = GX_LINES, + kP_LineStrip = GX_LINESTRIP, + kP_Points = GX_POINTS, +}; + +enum ERglBlendMode { + kBM_None = GX_BM_NONE, + kBM_Blend = GX_BM_BLEND, + kBM_Logic = GX_BM_LOGIC, + kBM_Subtract = GX_BM_SUBTRACT, + kBM_Max = GX_MAX_BLENDMODE, +}; + +enum ERglBlendFactor { + kBF_Zero = GX_BL_ZERO, + kBF_One = GX_BL_ONE, + kBF_SrcColor = GX_BL_SRCCLR, + kBF_InvSrcColor = GX_BL_INVSRCCLR, + kBF_SrcAlpha = GX_BL_SRCALPHA, + kBF_InvSrcAlpha = GX_BL_INVSRCALPHA, + kBF_DstAlpha = GX_BL_DSTALPHA, + kBF_InvDstAlpha = GX_BL_INVDSTALPHA, + kBF_DstColor = GX_BL_DSTCLR, + kBF_InvDstColor = GX_BL_INVDSTCLR, +}; + +enum ERglLogicOp { + kLO_Clear = GX_LO_CLEAR, + kLO_And = GX_LO_AND, + kLO_RevAnd = GX_LO_REVAND, + kLO_Copy = GX_LO_COPY, + kLO_InvAnd = GX_LO_INVAND, + kLO_NoOp = GX_LO_NOOP, + kLO_Xor = GX_LO_XOR, + kLO_Or = GX_LO_OR, + kLO_Nor = GX_LO_NOR, + kLO_Equiv = GX_LO_EQUIV, + kLO_Inv = GX_LO_INV, + kLO_RevOr = GX_LO_REVOR, + kLO_InvCopy = GX_LO_INVCOPY, + kLO_InvOr = GX_LO_INVOR, + kLO_NAnd = GX_LO_NAND, + kLO_Set = GX_LO_SET, +}; + +enum ERglAlphaFunc { + kAF_Never = GX_NEVER, + kAF_Less = GX_LESS, + kAF_Equal = GX_EQUAL, + kAF_LEqual = GX_LEQUAL, + kAF_Greater = GX_GREATER, + kAF_NEqual = GX_NEQUAL, + kAF_GEqual = GX_GEQUAL, + kAF_Always = GX_ALWAYS, +}; + +enum ERglAlphaOp { + kAO_And = GX_AOP_AND, + kAO_Or = GX_AOP_OR, + kAO_Xor = GX_AOP_XOR, + kAO_XNor = GX_AOP_XNOR, + kAO_Max = GX_MAX_ALPHAOP, +}; + +enum ERglEnum { + kE_Never = GX_NEVER, + kE_Less = GX_LESS, + kE_Equal = GX_EQUAL, + kE_LEqual = GX_LEQUAL, + kE_Greater = GX_GREATER, + kE_NEqual = GX_NEQUAL, + kE_GEqual = GX_GEQUAL, + kE_Always = GX_ALWAYS, +}; + +enum ERglCullMode { + kCM_None = GX_CULL_NONE, + kCM_Front = GX_CULL_FRONT, + kCM_Back = GX_CULL_BACK, + kCM_All = GX_CULL_ALL, +}; + +enum ERglLight { + kLight0, + kLight1, + kLight2, + kLight3, + kLight4, + kLight5, + kLight6, + kLight7, + kLightMax, +}; + +enum ERglTexOffset { + kTO_Zero = GX_TO_ZERO, + kTO_Sixteenth = GX_TO_SIXTEENTH, + kTO_Eighth = GX_TO_EIGHTH, + kTO_Fourth = GX_TO_FOURTH, + kTO_Half = GX_TO_HALF, + kTO_One = GX_TO_ONE, +}; + +struct CViewport { + int mLeft; + int mTop; + int mWidth; + int mHeight; + float mHalfWidth; + float mHalfHeight; +}; + +class COsContext; +class CTexture; +class CTimeProvider; + +// TODO +typedef struct { + float x; + float y; +} Vec2, *Vec2Ptr; + +class CGraphics { +public: + class CRenderState { + public: + CRenderState(); + + void Flush(); + void ResetFlushAll(); + int SetVtxState(const float* pos, const float* nrm, const uint* clr); + + // In map this takes two args, but x4 is unused? + void Set(int v0) { x0_ = v0; } + + private: + int x0_; + int x4_; + }; + + class CProjectionState { + public: + CProjectionState(bool persp, float left, float right, float top, float bottom, float near, + float far) + : x0_persp(persp) + , x4_left(left) + , x8_right(right) + , xc_top(top) + , x10_bottom(bottom) + , x14_near(near) + , x18_far(far) {} + + bool IsPerspective() const { return x0_persp; } + float GetLeft() const { return x4_left; } + float GetRight() const { return x8_right; } + float GetTop() const { return xc_top; } + float GetBottom() const { return x10_bottom; } + float GetNear() const { return x14_near; } + float GetFar() const { return x18_far; } + + private: + bool x0_persp; + float x4_left; + float x8_right; + float xc_top; + float x10_bottom; + float x14_near; + float x18_far; + }; + + class CClippedScreenRect { + public: + CClippedScreenRect() : x0_valid(false) {} + CClippedScreenRect(int x, int y, int width, int height, int texWidth, float minU, float maxU, + float minV, float maxV) + : x0_valid(true) + , x4_x(x) + , x8_y(y) + , xc_width(width) + , x10_height(height) + , x14_texWidth(texWidth) + , x18_minU(minU) + , x1c_maxU(maxU) + , x20_minV(minV) + , x24_maxV(maxV) {} + + bool IsValid() const { return x0_valid; } + int GetX() const { return x4_x; } + int GetY() const { return x8_y; } + int GetWidth() const { return xc_width; } + int GetHeight() const { return x10_height; } + int GetTexWidth() const { return x14_texWidth; } + float GetMinU() const { return x18_minU; } + float GetMaxU() const { return x1c_maxU; } + float GetMinV() const { return x20_minV; } + float GetMaxV() const { return x24_maxV; } + + private: + bool x0_valid; + int x4_x; + int x8_y; + int xc_width; + int x10_height; + int x14_texWidth; + float x18_minU; + float x1c_maxU; + float x20_minV; + float x24_maxV; + }; + + static bool Startup(const COsContext& osContext, uint fifoSize, void* fifoBase); + static GXTexRegion* TexRegionCallback(const GXTexObj* obj, GXTexMapID id); + static void InitGraphicsVariables(); + static void Shutdown(); + static void InitGraphicsDefaults(); + static void ConfigureFrameBuffer(const COsContext& osContext); + static void EnableLight(ERglLight light); + static void LoadLight(ERglLight light, const CLight& info); + static void SetLightState(uchar lights); + static void SetViewMatrix(); + static void SetScissor(int left, int bottom, int width, int height); + static void SetLineWidth(float w, ERglTexOffset offs); + static void ClearBackAndDepthBuffers(); + + static void SetIdentityViewPointMatrix(); + static void SetIdentityModelMatrix(); + static void SetViewport(int left, int bottom, int width, int height); + static void SetPerspective(float fovy, float aspect, float znear, float zfar); + static void SetCopyClear(const CColor& color, float depth); + static void SetClearColor(const CColor& color); + static void SetDepthRange(float near, float far); + static void FlushProjection(); + static void SetDefaultVtxAttrFmt(); + static CMatrix4f GetPerspectiveProjectionMatrix(); + static CMatrix4f CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar); + static void ResetGfxStates(); + static void LoadDolphinSpareTexture(int width, int height, GXTexFmt fmt, void* data, + GXTexMapID texId); + static void LoadDolphinSpareTexture(int width, int height, GXCITexFmt fmt, GXTlut tlut, + void* data, GXTexMapID texId); + static void TickRenderTimings(); + static const CProjectionState& GetProjectionState(); + static void SetProjectionState(const CProjectionState& proj); + static CClippedScreenRect ClipScreenRectFromVS(const CVector3f& p1, const CVector3f& p2, + ETexelFormat fmt); + static CClippedScreenRect ClipScreenRectFromMS(const CVector3f& p1, const CVector3f& p2, + ETexelFormat fmt); + static CVector2i ProjectPoint(const CVector3f& point); + + static float GetDepthNear() { return mDepthNear; } + static float GetDepthFar() { return mDepthFar; } + + static bool IsBeginSceneClearFb(); + static void SetIsBeginSceneClearFb(bool); + static void BeginScene(); + static void EndScene(); + static void SwapBuffers(); + static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass); + static void StreamBegin(ERglPrimitive primitive); + static void StreamColor(uint color); + static void StreamColor(float r, float g, float b, float a); + static void StreamColor(const CColor& color); + static void StreamTexcoord(float u, float v); + static void StreamTexcoord(const CVector2f& uv); + static void StreamVertex(float x, float y, float z); + static void StreamVertex(const CVector3f& vtx); + static void StreamVertex(const float* vtx); + static void StreamNormal(const float* nrm); + static void StreamEnd(); + static void Render2D(const CTexture& tex, int x, int y, int w, int h, const CColor& col); + static void DrawPrimitive(ERglPrimitive primitive, const float* pos, const CVector3f& normal, + const CColor& col, int numVerts); + + static void VideoPreCallback(u32 retraceCount); + static void VideoPostCallback(u32 retraceCount); + + static const CViewport& GetViewport() { return mViewport; } + static const CVector3f& GetViewPoint() { return mViewPoint; } + static const CTransform4f& GetViewMatrix() { return mViewMatrix; } + static const CTransform4f& GetModelMatrix() { return mModelMatrix; } + static void SetViewPointMatrix(const CTransform4f&); + static void SetBrightness(float b) { mBrightness = b; } + static void SetOrtho(float left, float right, float top, float bottom, float znear, float zfar); + + static float GetSecondsMod900(); + static float GetFPS(); + static void SetExternalTimeProvider(CTimeProvider* provider); + static void DisableAllLights(); + + static void SetAmbientColor(const CColor&); + static void SetFog(ERglFogMode mode, float startz, float endz, const CColor& color); + + static void SetModelMatrix(const CTransform4f& xf); + static void SetAlphaCompare(ERglAlphaFunc comp0, uchar ref0, ERglAlphaOp op, ERglAlphaFunc comp1, + uchar ref1); + static void SetDepthWriteMode(bool test, ERglEnum comp, bool write); + static void SetBlendMode(ERglBlendMode mode, ERglBlendFactor src, ERglBlendFactor dst, + ERglLogicOp op); + static void SetCullMode(ERglCullMode cullMode); + static void SetTevStates(uchar); + + static void SetUseVideoFilter(bool b); + static GXBool GetUseVideoFilter(); + static int GetFrameCounter(); + static void SetProgressiveMode(bool b); + static bool GetProgressiveMode(); + static bool CanSetProgressiveMode(); + static bool GetProgressiveDefault(); + + // Screen Position + static void GetScreenPosition(int* stretch, int* xOffset, int* yOffset); + static void SetScreenPosition(int stretch, int xOffset, int yOffset); + + static const CTevCombiners::CTevPass& kEnvPassthru; + static CTevCombiners::CTevPass kEnvModulateConstColor; + static CTevCombiners::CTevPass kEnvConstColor; + static CTevCombiners::CTevPass kEnvModulate; + static CTevCombiners::CTevPass kEnvDecal; + static CTevCombiners::CTevPass kEnvBlend; + static CTevCombiners::CTevPass kEnvReplace; + static CTevCombiners::CTevPass kEnvModulateAlpha; + static CTevCombiners::CTevPass kEnvModulateColor; + static CTevCombiners::CTevPass kEnvModulateColorByAlpha; + +private: + static void UpdateVertexDataStream(); + static void ResetVertexDataStream(bool initial); + static void FlushStream(); + static void FullRender(); + + static CRenderState sRenderState; + static VecPtr vtxBuffer; + static VecPtr nrmBuffer; + static Vec2Ptr txtBuffer0; + static Vec2Ptr txtBuffer1; + static uint* clrBuffer; + static bool mJustReset; + static ERglCullMode mCullMode; + static int mNumLightsActive; + static float mDepthNear; + static VecPtr mpVtxBuffer; + static VecPtr mpNrmBuffer; + static Vec2Ptr mpTxtBuffer0; + static Vec2Ptr mpTxtBuffer1; + static uint* mpClrBuffer; + static int mNumPrimitives; + static int mFrameCounter; + static float mFramesPerSecond; + static float mLastFramesPerSecond; + static int mNumBreakpointsWaiting; + static int mFlippingState; + static bool mLastFrameUsedAbove; + static bool mInterruptLastFrameUsedAbove; + static uchar mLightActive; + static uchar mLightsWereOn; + static void* mpFrameBuf1; + static void* mpFrameBuf2; + static void* mpCurrenFrameBuf; + static int mSpareBufferSize; + static void* mpSpareBuffer; + static int mSpareBufferTexCacheSize; + static GXTexRegionCallback mGXDefaultTexRegionCallback; + static void* mpFifo; + static GXFifoObj* mpFifoObj; + static uint mRenderTimings; + static float mSecondsMod900; + static CTimeProvider* mpExternalTimeProvider; + static int mScreenStretch; + static int mScreenPositionX; + static int mScreenPositionY; + + static CVector3f kDefaultPositionVector; + static CVector3f kDefaultDirectionVector; + static CProjectionState mProj; + static CTransform4f mViewMatrix; + static CTransform4f mModelMatrix; + static CColor mClearColor; + static CVector3f mViewPoint; + static CViewport mViewport; + static ELightType mLightTypes[8]; + static GXLightObj mLightObj[8]; + static GXTexRegion mTexRegions[GX_MAX_TEXMAP]; + static GXTexRegion mTexRegionsCI[GX_MAX_TEXMAP / 2]; + static GXRenderModeObj mRenderModeObj; + static Mtx mGXViewPointMatrix; + static Mtx mGXModelMatrix; + static Mtx mGxModelView; + static Mtx mCameraMtx; + + // .sdata + static bool mIsBeginSceneClearFb; + static ERglEnum mDepthFunc; + static ERglPrimitive mCurrentPrimitive; + static float mDepthFar; + static u32 mClearDepthValue; // = GX_MAX_Z24 + static bool mIsGXModelMatrixIdentity; + static bool mFirstFrame; + static GXBool mUseVideoFilter; + static float mBrightness; + + // .sdata2 + static const GXTexMapID kSpareBufferTexMapID; +}; + +#endif // _CGRAPHICS diff --git a/include/Kyoto/Graphics/CGraphicsPalette.hpp b/include/Kyoto/Graphics/CGraphicsPalette.hpp new file mode 100644 index 0000000..a7d9532 --- /dev/null +++ b/include/Kyoto/Graphics/CGraphicsPalette.hpp @@ -0,0 +1,39 @@ +#ifndef _CGRAPHICSPALETTE +#define _CGRAPHICSPALETTE + +#include "types.h" + +#include "dolphin/gx.h" + +#include + +enum EPaletteFormat { + kPF_IA8 = GX_TL_IA8, + kPF_RGB565 = GX_TL_RGB565, + kPF_RGB5A3 = GX_TL_RGB5A3, +}; + +class CInputStream; + +class CGraphicsPalette { +public: + CGraphicsPalette(EPaletteFormat format, int numEntries); + CGraphicsPalette(CInputStream& in); + ~CGraphicsPalette(); + + ushort* GetPaletteData() { return xc_entries.get(); } + const ushort* GetPaletteData() const { return xc_entries.get(); } + void Load() const; + void UnLock(); + +private: + static uint sCurrentFrameCount; + EPaletteFormat x0_fmt; + mutable uint x4_frameLoaded; + uint x8_entryCount; + rstl::single_ptr xc_entries; + GXTlutObj x10_tlutObj; + bool x1c_locked; +}; + +#endif // _CGRAPHICSPALETTE diff --git a/include/Kyoto/Graphics/CGraphicsSys.hpp b/include/Kyoto/Graphics/CGraphicsSys.hpp new file mode 100644 index 0000000..b507848 --- /dev/null +++ b/include/Kyoto/Graphics/CGraphicsSys.hpp @@ -0,0 +1,20 @@ +#ifndef _CGRAPHICSSYS +#define _CGRAPHICSSYS + +#include "types.h" + +class COsContext; +class CMemorySys; + +class CGraphicsSys { +public: + CGraphicsSys(const COsContext& osContext, const CMemorySys& memorySys, uint, void*); + ~CGraphicsSys(); + +private: + uint pad; + + static bool mGraphicsInitialized; +}; + +#endif // _CGRAPHICSSYS diff --git a/include/Kyoto/Graphics/CLight.hpp b/include/Kyoto/Graphics/CLight.hpp new file mode 100644 index 0000000..0dcd714 --- /dev/null +++ b/include/Kyoto/Graphics/CLight.hpp @@ -0,0 +1,88 @@ +#ifndef _CLIGHT +#define _CLIGHT + +#include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +enum ELightType { + kLT_Spot = 0, + kLT_Point = 1, + kLT_Directional = 2, + kLT_LocalAmbient = 3, + kLT_Custom = 4, +}; + +enum EFalloffType { kFT_Constant, kFT_Linear, kFT_Quadratic }; + +class CLight { + static const CVector3f kDefaultPosition; + static const CVector3f kDefaultDirection; + + float CalculateLightRadius() const; + +public: + CLight(ELightType type, const CVector3f& position, const CVector3f& direction, + const CColor& color, float cutoff); + CLight(const CVector3f& pos, const CVector3f& direction, const CColor& color, float distC, + float distL, float distQ, float angleC, float angleL, float angleQ); + CLight(const CLight&); + + void SetPosition(const CVector3f& pos); + const CVector3f& GetPosition() const { return x0_pos; } + void SetDirection(const CVector3f& dir); + const CVector3f& GetDirection() const { return xc_dir; } + void SetColor(const CColor& col); + void SetAttenuation(float constant, float linear, float quadratic); + float GetSpotCutoff() const { return x20_spotCutoff; } + float GetAttenuationConstant() const { return x24_distC; } + float GetAttenuationLinear() const { return x28_distL; } + float GetAttenuationQuadratic() const { return x2c_distQ; } + + void SetAngleAttenuation(float constant, float linear, float quadratic); + float GetAngleAttenuationConstant() const { return x30_angleC; } + float GetAngleAttenuationLinear() const { return x34_angleL; } + float GetAngleAttenuationQuadratic() const { return x38_angleQ; } + + ELightType GetType() const { return x1c_type; } + uint GetId() const { return x40_lightId; } + float GetIntensity() const; + float GetRadius() const; + const CColor& GetColor() const { return x18_color; } + + int GetPriority() const { return x3c_priority; } + void SetPriority(uint priority) { x3c_priority = priority; } + void SetLightId(uint lightId) { x40_lightId = lightId; } + + CVector3f GetNormalIndependentLightingAtPoint(const CVector3f& point) const; + + static CLight BuildDirectional(const CVector3f& dir, const CColor& color); + static CLight BuildSpot(const CVector3f& pos, const CVector3f& dir, const CColor& color, + float cutoff); + static CLight BuildPoint(const CVector3f& pos, const CColor& color); + static CLight BuildCustom(const CVector3f& pos, const CVector3f& dir, const CColor& color, + float distC, float distL, float distQ, float angleC, float angleL, + float angleQ); + static CLight BuildLocalAmbient(const CVector3f& pos, const CColor& color); + +private: + CVector3f x0_pos; + CVector3f xc_dir; + CColor x18_color; + ELightType x1c_type; + float x20_spotCutoff; + float x24_distC; + float x28_distL; + float x2c_distQ; + float x30_angleC; + float x34_angleL; + float x38_angleQ; + int x3c_priority; + uint x40_lightId; + mutable float x44_cachedRadius; + mutable float x48_cachedIntensity; + mutable bool x4c_24_intensityDirty : 1; + mutable bool x4c_25_radiusDirty : 1; +}; +CHECK_SIZEOF(CLight, 0x50) + +#endif // _CLIGHT diff --git a/include/Kyoto/Graphics/CModel.hpp b/include/Kyoto/Graphics/CModel.hpp new file mode 100644 index 0000000..940645b --- /dev/null +++ b/include/Kyoto/Graphics/CModel.hpp @@ -0,0 +1,17 @@ +#ifndef _CMODEL +#define _CMODEL + +class CModelFlags; + +class CModel { + static uint sTotalMemory; +public: + void Touch(int) const; + void Draw(const CModelFlags&) const; + bool IsLoaded(int matIdx) const; + + static void AddToTotal(uint amt) { sTotalMemory += amt; } + static void RemoveFromTotal(uint amt) { sTotalMemory -= amt; } +}; + +#endif // _CMODEL diff --git a/include/Kyoto/Graphics/CModelFlags.hpp b/include/Kyoto/Graphics/CModelFlags.hpp new file mode 100644 index 0000000..f2fa4bf --- /dev/null +++ b/include/Kyoto/Graphics/CModelFlags.hpp @@ -0,0 +1,118 @@ +#ifndef _CMODELFLAGS +#define _CMODELFLAGS + +#include "types.h" + +#include "Kyoto/Graphics/CColor.hpp" + +class CModelFlags { +public: + enum ETrans { + kT_Opaque = 0, + kT_One = 1, // ? + kT_Two = 2, // ? + kT_Blend = 5, + kT_Additive = 7, + }; + enum EFlags { + kF_DepthCompare = 0x1, + kF_DepthUpdate = 0x2, + kF_NoTextureLock = 0x4, + kF_DepthGreater = 0x8, + kF_DepthNonInclusive = 0x10, + kF_DrawNormal = 0x20, + kF_ThermalUnsortedOnly = 0x40, + }; + + CModelFlags(ETrans trans, float rgba) + : x0_blendMode(trans) + , x1_matSetIdx(0) + , x2_flags(kF_DepthCompare | kF_DepthUpdate) + , x4_color(1.f, 1.f, 1.f, rgba) {} + CModelFlags(ETrans trans, CColor color) + : x0_blendMode(trans) + , x1_matSetIdx(0) + , x2_flags(kF_DepthCompare | kF_DepthUpdate) + , x4_color(color) {} + + CModelFlags(ETrans blendMode, uchar shadIdx, EFlags flags, const CColor& col) + : x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {} + + CModelFlags(const CModelFlags& flags, uint otherFlags) + : x0_blendMode(flags.x0_blendMode) + , x1_matSetIdx(flags.x1_matSetIdx) + , x2_flags(otherFlags) + , x4_color(flags.x4_color) {} + CModelFlags(const CModelFlags& flags, bool b /* TODO what's this? */, int shaderSet) + : x0_blendMode(flags.x0_blendMode) + , x1_matSetIdx(shaderSet) + , x2_flags(flags.x2_flags) + , x4_color(flags.x4_color) {} + + // ? + CModelFlags(const CModelFlags& flags, ETrans trans, CColor color) + : x0_blendMode(trans) + , x1_matSetIdx(flags.x1_matSetIdx) + , x2_flags(flags.x2_flags) + , x4_color(color) {} + + // CModelFlags(const CModelFlags& other) + // : x0_blendMode(other.x0_blendMode) + // , x1_matSetIdx(other.x1_matSetIdx) + // , x2_flags(other.x2_flags) + // , x4_color(other.x4_color) {} + CModelFlags& operator=(const CModelFlags& other) { + x0_blendMode = other.x0_blendMode; + x1_matSetIdx = other.x1_matSetIdx; + x2_flags = other.x2_flags; + x4_color = other.x4_color; + return *this; + } + + CModelFlags UseShaderSet(int matSet) const { return CModelFlags(*this, false, matSet); } + CModelFlags DontLoadTextures() const { + return CModelFlags(*this, GetOtherFlags() | kF_NoTextureLock); + } + CModelFlags DepthCompareUpdate(bool compare, bool update) const { + uint newFlags = 0; + if (compare) { + newFlags |= kF_DepthCompare; + } + if (update) { + newFlags |= kF_DepthUpdate; + } + return CModelFlags(*this, (x2_flags & ~(kF_DepthCompare | kF_DepthUpdate)) | newFlags); + } + CModelFlags DepthBackwards() const { + return CModelFlags(*this, GetOtherFlags() | kF_DepthGreater); + } + + ETrans GetTrans() const { return static_cast< ETrans >(x0_blendMode); } + int GetShaderSet() const { return x1_matSetIdx; } + uint GetOtherFlags() const { return x2_flags; } + CColor GetColor() const { return x4_color; } + + bool operator==(const CModelFlags& other) const { + // TODO: cast to char for extsb; see CScriptActor::PreRender + return static_cast< char >(x0_blendMode) == static_cast< char >(other.x0_blendMode) && + static_cast< char >(x1_matSetIdx) == static_cast< char >(other.x1_matSetIdx) && + x2_flags == other.x2_flags && x4_color == other.x4_color; + } + + static CModelFlags Normal() { return CModelFlags(kT_Opaque, 1.f); } + static CModelFlags AlphaBlended(float alpha) { return CModelFlags(kT_Blend, alpha); } + static CModelFlags AlphaBlended(const CColor& color) { return CModelFlags(kT_Blend, color); } + static CModelFlags Additive(float f) { return CModelFlags(CModelFlags::kT_Additive, f); } + static CModelFlags Additive(const CColor& color) { return CModelFlags(CModelFlags::kT_Additive, color); } + static CModelFlags AdditiveRGB(const CColor& color); + static CModelFlags ColorModulate(const CColor& color); + +private: + uchar x0_blendMode; + uchar x1_matSetIdx; + ushort x2_flags; + CColor x4_color; +}; +CHECK_SIZEOF(CModelFlags, 0x8) + +#endif // _CMODELFLAGS diff --git a/include/Kyoto/Graphics/CMoviePlayer.hpp b/include/Kyoto/Graphics/CMoviePlayer.hpp new file mode 100644 index 0000000..c03e844 --- /dev/null +++ b/include/Kyoto/Graphics/CMoviePlayer.hpp @@ -0,0 +1,20 @@ +#ifndef _CMOVIEPLAYER +#define _CMOVIEPLAYER + +#include "types.h" + +class CMoviePlayer { +public: + static void SetSfxVolume(uchar); + + CMoviePlayer(const char*, float, bool, bool); + ~CMoviePlayer(); + + void Update(float); + bool DrawVideo() const; + + private: + char x0_pad[0x100]; +}; + +#endif // _CMOVIEPLAYER diff --git a/include/Kyoto/Graphics/CTevCombiners.hpp b/include/Kyoto/Graphics/CTevCombiners.hpp new file mode 100644 index 0000000..201a855 --- /dev/null +++ b/include/Kyoto/Graphics/CTevCombiners.hpp @@ -0,0 +1,190 @@ +#ifndef _CTEVCOMBINERS +#define _CTEVCOMBINERS + +#include "types.h" + +#include + +class CTevCombiners { +public: + enum EColorSrc { + kCS_PreviousColor, + kCS_PreviousAlpha, + kCS_RegisterC0, + kCS_RegisterA0, + kCS_RegisterC1, + kCS_RegisterA1, + kCS_RegisterC2, + kCS_RegisterA2, + kCS_TextureColor, + kCS_TextureAlpha, + kCS_RasterColor, + kCS_RasterAlpha, + kCS_One, + kCS_Half, + kCS_Konst, + kCS_Zero, + }; + + class ColorVar { + public: + ColorVar(EColorSrc src); + ColorVar(const ColorVar& other) : x0_src(other.GetSource()) {} + + EColorSrc GetSource() const { return x0_src; } + + private: + EColorSrc x0_src; + }; + + class ColorPass { + public: + ColorPass(const ColorVar& a, const ColorVar& b, const ColorVar& c, const ColorVar& d) + : x0_a(a), x4_b(b), x8_c(c), xc_d(d) {} + ColorPass(const ColorPass& other) + : x0_a(other.GetA()), x4_b(other.GetB()), x8_c(other.GetC()), xc_d(other.GetD()) {} + + ColorVar GetA() const { return x0_a; } + ColorVar GetB() const { return x4_b; } + ColorVar GetC() const { return x8_c; } + ColorVar GetD() const { return xc_d; } + + private: + ColorVar x0_a; + ColorVar x4_b; + ColorVar x8_c; + ColorVar xc_d; + }; + + enum EAlphaSrc { + kAS_PreviousAlpha, + kAS_RegisterA0, + kAS_RegisterA1, + kAS_RegisterA2, + kAS_TextureAlpha, + kAS_RasterAlpha, + kAS_Konst, + kAS_Zero, + }; + + class AlphaVar { + public: + AlphaVar(EAlphaSrc src); + AlphaVar(const AlphaVar& other) : x0_src(other.GetSource()) {} + + EAlphaSrc GetSource() const { return x0_src; } + + private: + EAlphaSrc x0_src; + }; + + class AlphaPass { + public: + AlphaPass(const AlphaVar& a, const AlphaVar& b, const AlphaVar& c, const AlphaVar& d) + : x0_a(a), x4_b(b), x8_c(c), xc_d(d) {} + AlphaPass(const AlphaPass& other) + : x0_a(other.GetA()), x4_b(other.GetB()), x8_c(other.GetC()), xc_d(other.GetD()) {} + + AlphaVar GetA() const { return x0_a; } + AlphaVar GetB() const { return x4_b; } + AlphaVar GetC() const { return x8_c; } + AlphaVar GetD() const { return xc_d; } + + private: + AlphaVar x0_a; + AlphaVar x4_b; + AlphaVar x8_c; + AlphaVar xc_d; + }; + + enum ETevOp { + kTO_Add, + kTO_Subtract, + }; + + enum ETevBias { + kTB_Zero, + kTB_AddHalf, + kTB_SubHalf, + }; + + enum ETevScale { + kTS_Scale1, + kTS_Scale2, + kTS_Scale4, + kTS_Divide2, + }; + + enum ETevOutput { + kTO_Previous, + kTO_Register0, + kTO_Register1, + kTO_Register2, + }; + + class CTevOp { + public: + CTevOp(ETevOp op = kTO_Add, ETevBias bias = kTB_Zero, ETevScale scale = kTS_Scale1, + bool clamp = true, ETevOutput output = kTO_Previous) + : x0_clamp(clamp), x4_op(op), x8_bias(bias), xc_scale(scale), x10_output(output) {} + CTevOp(const CTevOp& other) + : x0_clamp(other.GetClamp()) + , x4_op(other.GetOp()) + , x8_bias(other.GetBias()) + , xc_scale(other.GetScale()) + , x10_output(other.GetOutput()) {} + + bool GetClamp() const { return x0_clamp; } + ETevOp GetOp() const { return x4_op; } + ETevBias GetBias() const { return x8_bias; } + ETevScale GetScale() const { return xc_scale; } + ETevOutput GetOutput() const { return x10_output; } + + private: + bool x0_clamp; + ETevOp x4_op; + ETevBias x8_bias; + ETevScale xc_scale; + ETevOutput x10_output; + }; + + class CTevPass { + public: + CTevPass(const ColorPass& colorPass, const AlphaPass& alphaPass, + const CTevOp& colorOp = CTevOp(), const CTevOp& alphaOp = CTevOp()) + : x0_id(sNextUniquePass++) + , x4_colorPass(colorPass) + , x14_alphaPass(alphaPass) + , x24_colorOp(colorOp) + , x38_alphaOp(alphaOp) {} + + void Execute(int) const; + + private: + uint x0_id; + ColorPass x4_colorPass; + AlphaPass x14_alphaPass; + CTevOp x24_colorOp; + CTevOp x38_alphaOp; + }; + + static void RecomputePasses(); + static void Init(); + static void DeletePass(int); + static void SetupPass(int, const CTevPass& pass); + static bool SetPassCombiners(int stage, const CTevPass& pass); + static void ResetStates(); + + static int sNextUniquePass; + static const CTevPass kEnvPassthru; + static const AlphaVar skAlphaOne; + static const ColorVar skColorOne; + +private: + static bool sValidPasses[2]; + static uint sNumEnabledPasses; +}; + +extern CTevCombiners::CTevPass CTevPass_805a5ebc; + +#endif // _CTEVCOMBINERS diff --git a/include/Kyoto/Graphics/CTexture.hpp b/include/Kyoto/Graphics/CTexture.hpp new file mode 100644 index 0000000..dc0a03a --- /dev/null +++ b/include/Kyoto/Graphics/CTexture.hpp @@ -0,0 +1,113 @@ +#ifndef _CTEXTURE +#define _CTEXTURE + +#include "types.h" + +#include "Kyoto/CARAMToken.hpp" +#include "rstl/single_ptr.hpp" + +#include + +class CDvdRequest; +class CInputStream; +class CGraphicsPalette; + +enum ETexelFormat { + kTF_Invalid = -1, + kTF_I4 = 0, + kTF_I8 = 1, + kTF_IA4 = 2, + kTF_IA8 = 3, + kTF_C4 = 4, + kTF_C8 = 5, + kTF_C14X2 = 6, + kTF_RGB565 = 7, + kTF_RGB5A3 = 8, + kTF_RGBA8 = 9, + kTF_CMPR = 10, +}; + +class CTexture { +public: + class CDumpedBitmapDataReloader { + int x0_; + uint x4_; + int x8_; + uint xc_; + bool x10_; + rstl::single_ptr< CDvdRequest > x14_; + rstl::single_ptr< uchar > x18_; + }; + + enum EClampMode { + kCM_Clamp, + kCM_Repeat, + kCM_Mirror, + }; + enum EAutoMipmap { + kAM_Zero, + }; + enum EBlackKey { + kBK_Zero, + }; + + CTexture(ETexelFormat fmt, short w, short h, int mips); + CTexture(CInputStream& stream, EAutoMipmap mip, EBlackKey bk); + ~CTexture(); + + // Used in certain destructors + void sub_8030e10c(); + + void Load(GXTexMapID texMapId, EClampMode clampMode) const; + void UnLock(); + + void* GetBitMapData(int); + + void InitBitmapBuffers(ETexelFormat fmt, short w, short h, int mips); + void InitTextureObjects(); + ETexelFormat GetTexelFormat() const { return mTexelFormat; } + short GetWidth() const { return mWidth; } + short GetHeight() const { return mHeight; } + + void* Lock() { + mLocked = true; + return GetBitMapData(0); + } + + void MakeSwappable() const; + void CountMemory() const; + void UncountMemory() const; + void SetFlag1(bool b) { mLocked = b; } + + static uint TexelFormatBitsPerPixel(ETexelFormat fmt); + static void InvalidateTexmap(GXTexMapID id); + + static int sCurrentFrameCount; + static int sTotalAllocatedMemory; + static bool sMangleMips; + +private: + ETexelFormat mTexelFormat; // TODO: Enum + short mWidth; + short mHeight; + uchar mNumMips; + uchar mBitsPerPixel; + bool mLocked : 1; + bool mCanLoadPalette : 1; + bool mIsPowerOfTwo : 1; + mutable bool mNoSwap : 1; + mutable bool mCounted : 1; + uchar mCanLoadObj : 1; + uint mMemoryAllocated; + rstl::single_ptr< CGraphicsPalette > mGraphicsPalette; + rstl::single_ptr< CDumpedBitmapDataReloader > mBitmapReloader; + uint mNativeFormat; + uint mNativeCIFormat; + GXTexObj mTexObj; + EClampMode mClampMode; + CARAMToken mARAMToken; + uint mFrameAllocated; +}; +CHECK_SIZEOF(CTexture, 0x68) + +#endif // _CTEXTURE diff --git a/include/Kyoto/IObj.hpp b/include/Kyoto/IObj.hpp new file mode 100644 index 0000000..8209e97 --- /dev/null +++ b/include/Kyoto/IObj.hpp @@ -0,0 +1,53 @@ +#ifndef _IOBJ +#define _IOBJ + +#include "types.h" + +#include "Kyoto/SObjectTag.hpp" +#include "rstl/auto_ptr.hpp" + +extern const SObjectTag gkInvalidObjectTag; + +class IObj { +public: + virtual ~IObj() {} +}; + +class CObjOwnerDerivedFromIObjUntyped : public IObj { +public: + ~CObjOwnerDerivedFromIObjUntyped() {} + template < typename T > + CObjOwnerDerivedFromIObjUntyped(T* obj) : m_objPtr(obj) {} + template < typename T > + CObjOwnerDerivedFromIObjUntyped(const rstl::auto_ptr< T >& obj) : m_objPtr(obj.release()) {} + + void* GetContents() { return m_objPtr; } + +protected: + void* m_objPtr; +}; + +template < typename T > +class TObjOwnerDerivedFromIObj : public CObjOwnerDerivedFromIObjUntyped { +public: + ~TObjOwnerDerivedFromIObj() { + if (Owned()) { + delete Owned(); + } + } + T* Owned() { return static_cast< T* >(m_objPtr); } + + static rstl::auto_ptr< TObjOwnerDerivedFromIObj< T > > GetNewDerivedObject(T* obj) { + return new TObjOwnerDerivedFromIObj< T >(obj); + } + static rstl::auto_ptr< TObjOwnerDerivedFromIObj< T > > + GetNewDerivedObject(const rstl::auto_ptr< T >& obj) { + return new TObjOwnerDerivedFromIObj< T >(obj); + } + +private: + TObjOwnerDerivedFromIObj(T* obj) : CObjOwnerDerivedFromIObjUntyped(obj) {} + TObjOwnerDerivedFromIObj(const rstl::auto_ptr< T >& obj) : CObjOwnerDerivedFromIObjUntyped(obj) {} +}; + +#endif // _IOBJ diff --git a/include/Kyoto/IObjectStore.hpp b/include/Kyoto/IObjectStore.hpp new file mode 100644 index 0000000..3a03193 --- /dev/null +++ b/include/Kyoto/IObjectStore.hpp @@ -0,0 +1,26 @@ +#ifndef _IOBJECTSTORE +#define _IOBJECTSTORE + +#include "types.h" + +#include "Kyoto/CToken.hpp" + +#include "rstl/auto_ptr.hpp" +#include "rstl/rc_ptr.hpp" + +class IFactory; +class IObjectStore { +public: + IObjectStore() {} + virtual CToken GetObj(const SObjectTag& tag, CVParamTransfer xfer) = 0; + virtual CToken GetObj(const SObjectTag& tag) = 0; + virtual CToken GetObj(const char* name) = 0; + virtual CToken GetObj(const char* name, CVParamTransfer xfer) = 0; + virtual bool HasObject(const SObjectTag& tag) = 0; + virtual bool ObjectIsLive(const SObjectTag& tag) = 0; + virtual IFactory& GetFactory() = 0; + virtual void Flush() = 0; + virtual void ObjectUnreferenced(const SObjectTag& tag) = 0; +}; + +#endif // _IOBJECTSTORE diff --git a/include/Kyoto/Input/CControllerAxis.hpp b/include/Kyoto/Input/CControllerAxis.hpp new file mode 100644 index 0000000..f2e7c63 --- /dev/null +++ b/include/Kyoto/Input/CControllerAxis.hpp @@ -0,0 +1,17 @@ +#ifndef _CCONTROLLERAXIS +#define _CCONTROLLERAXIS + +class CControllerAxis { +public: + CControllerAxis() : x0_relative(0.f), x4_absolute(0.f) {} + void SetRelativeValue(float val) { x0_relative = val; } + float GetRelativeValue() const { return x0_relative; } + void SetAbsoluteValue(float val) { x4_absolute = val; } + float GetAbsoluteValue() const { return x4_absolute; } + +public: + float x0_relative; + float x4_absolute; +}; + +#endif // _CCONTROLLERAXIS diff --git a/include/Kyoto/Input/CControllerButton.hpp b/include/Kyoto/Input/CControllerButton.hpp new file mode 100644 index 0000000..b346bf6 --- /dev/null +++ b/include/Kyoto/Input/CControllerButton.hpp @@ -0,0 +1,20 @@ +#ifndef _CCONTROLLERBUTTON +#define _CCONTROLLERBUTTON + +class CControllerButton { +public: + CControllerButton() : x0_pressed(false), x1_pressEvent(false), x2_releaseEvent(false) {} + void SetIsPressed(bool pressed) { x0_pressed = pressed; } + uint GetIsPressed() const { return x0_pressed; } + void SetPressEvent(bool press) { x1_pressEvent = press; } + uint GetPressEvent() const { return x1_pressEvent; } + void SetReleaseEvent(bool release) { x2_releaseEvent = release; }; + uint GetReleaseEvent() const { return x2_releaseEvent; } + +private: + uchar x0_pressed; + uchar x1_pressEvent; + uchar x2_releaseEvent; +}; + +#endif // _CCONTROLLERBUTTON diff --git a/include/Kyoto/Input/CControllerGamepadData.hpp b/include/Kyoto/Input/CControllerGamepadData.hpp new file mode 100644 index 0000000..d45dea0 --- /dev/null +++ b/include/Kyoto/Input/CControllerGamepadData.hpp @@ -0,0 +1,31 @@ +#ifndef _CCONTROLLERGAMEPADDATA +#define _CCONTROLLERGAMEPADDATA + +#include "Kyoto/Input/CControllerAxis.hpp" +#include "Kyoto/Input/CControllerButton.hpp" +#include "Kyoto/Input/InputTypes.hpp" + +class CControllerGamepadData { +public: + void SetDeviceIsPresent(bool present) { x0_present = present; } + bool DeviceIsPresent() const { return x0_present; } + + const CControllerAxis& GetAxis(EJoyAxis axis) const { return x4_axes[axis]; } + CControllerAxis& GetAxis(EJoyAxis axis) { return x4_axes[axis]; } + + const CControllerButton& GetButton(EButton button) const { return x34_buttons[button]; } + CControllerButton& GetButton(EButton button) { return x34_buttons[button]; } + + const CControllerAxis& GetAnalogButton(EAnalogButton button) const { + return x24_triggers[button]; + } + CControllerAxis& GetAnalogButton(EAnalogButton button) { return x24_triggers[button]; } + +private: + bool x0_present; + CControllerAxis x4_axes[4]; + CControllerAxis x24_triggers[2]; + CControllerButton x34_buttons[12]; +}; + +#endif // _CCONTROLLERGAMEPADDATA diff --git a/include/Kyoto/Input/CDolphinController.hpp b/include/Kyoto/Input/CDolphinController.hpp new file mode 100644 index 0000000..ea4d29c --- /dev/null +++ b/include/Kyoto/Input/CDolphinController.hpp @@ -0,0 +1,41 @@ +#ifndef _CDOLPHINCONTROLLER +#define _CDOLPHINCONTROLLER + +#include "Kyoto/Input/IController.hpp" + +class CDolphinController : public IController { + static const uint skTypeUnknown; + static const uint skTypeStandard; + static const uint skTypeGBA; + static const uint skTypeWavebird; + +public: + CDolphinController(); + ~CDolphinController() override; + void Poll() override; + uint GetDeviceCount() const override; + CControllerGamepadData& GetGamepadData(int controller) override; + uint GetControllerType(int) const override; + void SetMotorState(EIOPort port, EMotorState state) override; + + bool Initialize(); + float GetAnalogStickMaxValue(EJoyAxis axis) const; + +private: + void ReadDevices(); + void ProcessInputData(); + void ProcessAxis(int controller, EJoyAxis axis); + void ProcessButtons(int controller); + void ProcessDigitalButton(int value, CControllerButton& button, ushort mapping); + void ProcessAnalogButton(float value, CControllerAxis& axis); + PADStatus x4_status[4]; + CControllerGamepadData x34_gamepadStates[4]; + EMotorState x194_motorStates[4]; + uint x1a4_controllerTypes[4]; + uint x1b4_controllerTypePollTime[4]; + uint x1c4_; + uint x1c8_invalidControllers; + uint x1cc_; +}; + +#endif // _CDOLPHINCONTROLLER diff --git a/include/Kyoto/Input/CFinalInput.hpp b/include/Kyoto/Input/CFinalInput.hpp new file mode 100644 index 0000000..5a0cc26 --- /dev/null +++ b/include/Kyoto/Input/CFinalInput.hpp @@ -0,0 +1,248 @@ +#ifndef _CFINALINPUT +#define _CFINALINPUT + +#include + +#ifdef __MWERKS__ +#pragma cpp_extensions on +#endif + +class CControllerGamepadData; +class COsContext; + +class CFinalInput { + static const float kInput_AnalogOnThreshhold; + static const float kInput_AnalogTriggerOnThreshhold; + +public: + CFinalInput(); + CFinalInput(int channel, float dt, const CControllerGamepadData& data, float leftDif, + float rightDiv); + CFinalInput(int channel, float dt, const COsContext& context); + CFinalInput(const CFinalInput& other) + : x0_dt(other.x0_dt) + , x4_controllerIdx(other.x4_controllerIdx) + , x8_anaLeftX(other.x8_anaLeftX) + , xc_anaLeftY(other.xc_anaLeftY) + , x10_anaRightX(other.x10_anaRightX) + , x14_anaRightY(other.x14_anaRightY) + , x18_anaLeftTrigger(other.x18_anaLeftTrigger) + , x1c_anaRightTrigger(other.x1c_anaRightTrigger) + , x20_enableAnaLeftXP(other.x20_enableAnaLeftXP) + , x21_enableAnaLeftYP(other.x21_enableAnaLeftYP) + , x22_enableAnaRightXP(other.x22_enableAnaRightXP) + , x23_enableAnaRightYP(other.x23_enableAnaRightYP) + , x24_anaLeftTriggerP(other.x24_anaLeftTriggerP) + , x28_anaRightTriggerP(other.x28_anaRightTriggerP) + , btns1(other.btns1) + , btns2(other.btns2) + , btns3(other.btns3) {} + + void InitializeAnalog(float leftDiv, float rightDiv); + + CFinalInput ScaleAnalogueSticks(float leftDiv, float rightDiv) const; + + float DeltaTime() const { return x0_dt; } + + float ALAUp() const { return xc_anaLeftY > 0.f ? xc_anaLeftY : 0.f; } + + float ALADown() const { return xc_anaLeftY < 0.f ? -xc_anaLeftY : 0.f; } + + float ALALeft() const { return x8_anaLeftX < 0.f ? -x8_anaLeftX : 0.f; } + + float ALARight() const { return x8_anaLeftX > 0.f ? x8_anaLeftX : 0.f; } + + float ARAUp() const { return x14_anaRightY > 0.f ? x14_anaRightY : 0.f; } + + float ARADown() const { return x14_anaRightY < 0.f ? -x14_anaRightY : 0.f; } + + float ARALeft() const { return x10_anaRightX < 0.f ? -x10_anaRightX : 0.f; } + + float ARARight() const { return x10_anaRightX > 0.f ? x10_anaRightX : 0.f; } + + float ALTrigger() const { return x18_anaLeftTrigger; } + + float ARTrigger() const { return x1c_anaRightTrigger; } + + float ADPUp() const { return x2c_b31_DPUp ? 1.f : 0.f; } + + float ADPDown() const { return x2d_b25_DPDown ? 1.f : 0.f; } + + float ADPLeft() const { return x2d_b26_DPLeft ? 1.f : 0.f; } + + float ADPRight() const { return x2d_b24_DPRight ? 1.f : 0.f; } + + float AA() const { return x2c_b24_A ? 1.f : 0.f; } + + float AB() const { return x2c_b25_B ? 1.f : 0.f; } + + float AX() const { return x2c_b26_X ? 1.f : 0.f; } + + float AY() const { return x2c_b27_Y ? 1.f : 0.f; } + + float AZ() const { return x2c_b28_Z ? 1.f : 0.f; } + + float AL() const { return x2c_b29_L ? 1.f : 0.f; } + + float AR() const { return x2c_b30_R ? 1.f : 0.f; } + + float AStart() const { return x2d_b27_Start ? 1.f : 0.f; } + + bool DLAUp() const { return kInput_AnalogOnThreshhold < xc_anaLeftY ? true : false; } + + bool DLADown() const { return -kInput_AnalogOnThreshhold > xc_anaLeftY ? true : false; } + + bool DLALeft() const { return -kInput_AnalogOnThreshhold > x8_anaLeftX ? true : false; } + + bool DLARight() const { return kInput_AnalogOnThreshhold < x8_anaLeftX ? true : false; } + + bool DRAUp() const { return kInput_AnalogOnThreshhold < x14_anaRightY ? true : false; } + + bool DRADown() const { return -kInput_AnalogOnThreshhold > x14_anaRightY ? true : false; } + + bool DRALeft() const { return -kInput_AnalogOnThreshhold > x10_anaRightX ? true : false; } + + bool DRARight() const { return kInput_AnalogOnThreshhold < x10_anaRightX ? true : false; } + + bool DLTrigger() const { + return kInput_AnalogTriggerOnThreshhold < x18_anaLeftTrigger ? true : false; + } + + bool DRTrigger() const { + return kInput_AnalogTriggerOnThreshhold < x1c_anaRightTrigger ? true : false; + } + + bool DDPUp() const { return x2c_b31_DPUp; } + + bool DDPDown() const { return x2d_b25_DPDown; } + + bool DDPLeft() const { return x2d_b26_DPLeft; } + + bool DDPRight() const { return x2d_b24_DPRight; } + + bool DA() const { return x2c_b24_A; } + + bool DB() const { return x2c_b25_B; } + + bool DX() const { return x2c_b26_X; } + + bool DY() const { return x2c_b27_Y; } + + bool DZ() const { return x2c_b28_Z; } + + bool DL() const { return x2c_b29_L; } + + bool DR() const { return x2c_b30_R; } + + bool DStart() const { return x2d_b27_Start; } + + bool PLAUp() const { return kInput_AnalogOnThreshhold < xc_anaLeftY && x21_enableAnaLeftYP ? true : false; } + + bool PLADown() const { return -kInput_AnalogOnThreshhold > xc_anaLeftY && x21_enableAnaLeftYP ? true : false; } + + bool PLALeft() const { return -kInput_AnalogOnThreshhold > x8_anaLeftX && x20_enableAnaLeftXP ? true : false; } + + bool PLARight() const { return kInput_AnalogOnThreshhold < x8_anaLeftX && x20_enableAnaLeftXP ? true : false; } + + bool PRAUp() const { return kInput_AnalogOnThreshhold < x14_anaRightY && x23_enableAnaRightYP ? true : false; } + + bool PRADown() const { return -kInput_AnalogOnThreshhold > x14_anaRightY && x23_enableAnaRightYP ? true : false; } + + bool PRALeft() const { return -kInput_AnalogOnThreshhold > x10_anaRightX && x22_enableAnaRightXP ? true : false; } + + bool PRARight() const { return kInput_AnalogOnThreshhold < x10_anaRightX && x22_enableAnaRightXP ? true : false; } + + bool PLTrigger() const { return kInput_AnalogTriggerOnThreshhold < x24_anaLeftTriggerP ? true : false; } + + bool PRTrigger() const { return kInput_AnalogTriggerOnThreshhold < x28_anaRightTriggerP ? true : false; } + + bool PDPUp() const { return x2e_b27_PDPUp; } + + bool PDPDown() const { return x2e_b29_PDPDown; } + + bool PDPLeft() const { return x2e_b30_PDPLeft; } + + bool PDPRight() const { return x2e_b28_PDPRight; } + + bool PA() const { return x2d_b28_PA; } + + bool PB() const { return x2d_b29_PB; } + + bool PX() const { return x2d_b30_PX; } + + bool PY() const { return x2d_b31_PY; } + + bool PZ() const { return x2e_b24_PZ; } + + bool PL() const { return x2e_b25_PL; } + + bool PR() const { return x2e_b26_PR; } + + bool PStart() const { return x2e_b31_PStart; } + +private: + float x0_dt; + uint x4_controllerIdx; + float x8_anaLeftX; + float xc_anaLeftY; + float x10_anaRightX; + float x14_anaRightY; + float x18_anaLeftTrigger; + float x1c_anaRightTrigger; + + bool x20_enableAnaLeftXP; + bool x21_enableAnaLeftYP; + bool x22_enableAnaRightXP; + bool x23_enableAnaRightYP; + + float x24_anaLeftTriggerP; + float x28_anaRightTriggerP; + + union { + struct { + uchar x2c_b24_A : 1; + uchar x2c_b25_B : 1; + uchar x2c_b26_X : 1; + uchar x2c_b27_Y : 1; + uchar x2c_b28_Z : 1; + uchar x2c_b29_L : 1; + uchar x2c_b30_R : 1; + uchar x2c_b31_DPUp : 1; + }; + uchar btns1; + }; + union { + struct { + uchar x2d_b24_DPRight : 1; + uchar x2d_b25_DPDown : 1; + uchar x2d_b26_DPLeft : 1; + uchar x2d_b27_Start : 1; + uchar x2d_b28_PA : 1; + uchar x2d_b29_PB : 1; + uchar x2d_b30_PX : 1; + uchar x2d_b31_PY : 1; + }; + uchar btns2; + }; + union { + struct { + uchar x2e_b24_PZ : 1; + uchar x2e_b25_PL : 1; + uchar x2e_b26_PR : 1; + uchar x2e_b27_PDPUp : 1; + uchar x2e_b28_PDPRight : 1; + uchar x2e_b29_PDPDown : 1; + uchar x2e_b30_PDPLeft : 1; + uchar x2e_b31_PStart : 1; + }; + uchar btns3; + }; +}; + +CHECK_SIZEOF(CFinalInput, 48) + +#ifdef __MWERKS__ +#pragma cpp_extensions reset +#endif + +#endif // _CFINALINPUT diff --git a/include/Kyoto/Input/CRumbleGenerator.hpp b/include/Kyoto/Input/CRumbleGenerator.hpp new file mode 100644 index 0000000..11fe9e7 --- /dev/null +++ b/include/Kyoto/Input/CRumbleGenerator.hpp @@ -0,0 +1,35 @@ +#ifndef _CRUMBLEGENERATOR +#define _CRUMBLEGENERATOR + +#include "types.h" + +#include "Kyoto/Input/CRumbleVoice.hpp" +#include "Kyoto/Input/InputTypes.hpp" + +class CRumbleGenerator { +private: + static const EMotorState kStopAll[4]; + CRumbleVoice x0_voices[4]; + float xc0_periodTime[4]; + float xd0_onTime[4]; + EMotorState xe0_commandArray[4]; + bool xf0_24_disabled : 1; + +public: + CRumbleGenerator(); + ~CRumbleGenerator(); + + short Rumble(const SAdsrData& adsr, float, ERumblePriority prio, EIOPort port); + void Stop(short id, EIOPort port) { + if (id == -1) + return; + CRumbleVoice& vox = x0_voices[size_t(port)]; + vox.Deactivate(id, false); + } + void Deactivate(short, bool); + void Update(float); + void HardStopAll(); + void SetDisabled(const bool disabled); +}; + +#endif // _CRUMBLEGENERATOR diff --git a/include/Kyoto/Input/CRumbleVoice.hpp b/include/Kyoto/Input/CRumbleVoice.hpp new file mode 100644 index 0000000..3a13bea --- /dev/null +++ b/include/Kyoto/Input/CRumbleVoice.hpp @@ -0,0 +1,100 @@ +#ifndef _CRUMBLEVOICE +#define _CRUMBLEVOICE + +#include "types.h" + +#include "rstl/reserved_vector.hpp" +#include "rstl/vector.hpp" + +enum ERumbleFxId { + kRFX_Zero = 0, + kRFX_One = 1, + kRFX_CameraShake = 6, + kRFX_EscapeSequenceShake = 7, + kRFX_PlayerBump = 11, + kRFX_PlayerGunCharge = 12, + kRFX_PlayerMissileFire = 13, + kRFX_PlayerGrappleFire = 14, + kRFX_PlayerLand = 15, + kRFX_PlayerGrappleSwoosh = 17, + kRFX_IntroBossProjectile = 19, + kRFX_Twenty = 20, + kRFX_TwentyOne = 21, + kRFX_TwentyTwo = 22, + kRFX_TwentyThree = 23 +}; + +enum ERumblePriority { + kRP_None = 0, + kRP_One = 1, + kRP_Two = 2, + kRP_Three = 3, +}; + +struct SAdsrData { + SAdsrData(); + SAdsrData(float attackGain, float autoReleaseDur, float attackDur, float decayDur, + float sustainGain, float releaseDur, bool hasSustain, bool autoRelease); + + float x0_attackGain; + float x4_autoReleaseDur; + float x8_attackDur; + float xc_decayDur; + float x10_sustainGain; + float x14_releaseDur; + bool x18_24_hasSustain : 1; + bool x18_25_autoRelease : 1; +}; + +struct SAdsrDelta { + enum EPhase { + kP_Stop, + kP_PrePulse, + kP_Attack, + kP_Decay, + kP_Sustain, + kP_Release, + }; + + SAdsrDelta(EPhase phase, ERumblePriority priority); + SAdsrDelta(EPhase phase); + static SAdsrDelta Stopped(); + static SAdsrDelta Start(ERumblePriority priority, bool prePulse); + + float x0_curIntensity; + float x4_attackTime; + float x8_decayTime; + float xc_releaseTime; + float x10_autoReleaseTime; + float x14_attackIntensity; + float x18_sustainIntensity; + ERumblePriority x1c_priority; + EPhase x20_phase; +}; + +class CRumbleVoice { +private: + rstl::vector< SAdsrData > x0_datas; + rstl::vector< SAdsrDelta > x10_deltas; + rstl::reserved_vector< ushort, 4 > x20_handleIds; + ushort x2c_usedChannels; + uchar x2e_lastId; + +public: + CRumbleVoice(); + + short Activate(const SAdsrData& data, ushort idx, float gain, ERumblePriority prio); + void Deactivate(short id, bool b1); + void HardReset(); + bool UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt); + bool Update(float dt); + ushort GetFreeChannel() const; + float GetIntensity() const; + bool OwnsSustained(short id) const; + short CreateRumbleHandle(ushort idx); + ushort GetChannelId(short handle) const { return handle & 0xf; } + ushort GetOwnerId(short handle) const { return ((handle >> 8) & 0xFF); } + ERumblePriority GetPriority(uint idx) { return x10_deltas[idx].x1c_priority; } +}; + +#endif // _CRUMBLEVOICE diff --git a/include/Kyoto/Input/IController.hpp b/include/Kyoto/Input/IController.hpp new file mode 100644 index 0000000..83f011a --- /dev/null +++ b/include/Kyoto/Input/IController.hpp @@ -0,0 +1,29 @@ +#ifndef _ICONTROLLER +#define _ICONTROLLER + +#include + +#include "Kyoto/Input/CControllerGamepadData.hpp" +#include "Kyoto/Input/InputTypes.hpp" + +class COsContext; +class IController { +protected: + static const float kAbsoluteMinimum; + static const float kAbsoluteMaximum; + static const float kRelativeMinimum; + static const float kRelativeMaximum; + +public: + IController(); + virtual ~IController(); + virtual void Poll() = 0; + virtual uint GetDeviceCount() const = 0; + virtual CControllerGamepadData& GetGamepadData(int controller) = 0; + virtual uint GetControllerType(int) const = 0; + virtual void SetMotorState(EIOPort port, EMotorState state) = 0; + + static IController* Create(const COsContext& ctx); +}; + +#endif // _ICONTROLLER diff --git a/include/Kyoto/Input/InputTypes.hpp b/include/Kyoto/Input/InputTypes.hpp new file mode 100644 index 0000000..ecba1ba --- /dev/null +++ b/include/Kyoto/Input/InputTypes.hpp @@ -0,0 +1,39 @@ +#ifndef _INPUTTYPES +#define _INPUTTYPES + +#include + +enum EIOPort { + kIOP_Player1 = PAD_CHAN0, + kIOP_Player2 = PAD_CHAN1, + kIOP_Player3 = PAD_CHAN2, + kIOP_Player4 = PAD_CHAN3, +}; + +enum EMotorState { + kMS_Stop = PAD_MOTOR_STOP, + kMS_Rumble = PAD_MOTOR_RUMBLE, + kMS_StopHard = PAD_MOTOR_STOP_HARD, +}; + +enum EJoyAxis { kJA_LeftX, kJA_LeftY, kJA_RightX, kJA_RightY, kJA_MAX }; + +enum EButton { + kBU_A, + kBU_B, + kBU_X, + kBU_Y, + kBU_Start, + kBU_Z, + kBU_Up, + kBU_Right, + kBU_Down, + kBU_Left, + kBU_L, + kBU_R, + kBU_MAX, +}; + +enum EAnalogButton { kBA_Left, kBA_Right, kBA_MAX }; + +#endif // _INPUTTYPES diff --git a/include/Kyoto/Math/CAABox.hpp b/include/Kyoto/Math/CAABox.hpp new file mode 100644 index 0000000..19c3e71 --- /dev/null +++ b/include/Kyoto/Math/CAABox.hpp @@ -0,0 +1,107 @@ +#ifndef _CAABOX +#define _CAABOX + +#include "Kyoto/Math/CVector3f.hpp" + +class CInputStream; +class CLineSeg; +class CPlane; +class CTransform4f; +class CTri; + +class CAABox { +public: + enum EBoxEdgeId { + kE_Z0, + kE_X0, + kE_Z1, + kE_X1, + kE_Z2, + kE_X2, + kE_Z3, + kE_X3, + kE_Y0, + kE_Y1, + kE_Y2, + kE_Y3, + }; + enum EBoxFaceId { + kF_YMin, + kF_YMax, + kF_XMin, + kF_XMax, + kF_ZMax, + kF_ZMin, + }; + + CAABox(const CVector3f& min, const CVector3f& max); + CAABox(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) + : min(minX, minY, minZ), max(maxX, maxY, maxZ) {} + CAABox(CInputStream& in); + // CAABox(const CAABox& other) + // : min(other.min) + // , max(other.max) {} + + // CAABox& operator=(const CAABox& other) { + // min = other.min; + // max = other.max; + // return *this; + // } + + CLineSeg GetEdge(EBoxEdgeId edge) const; + CTri GetTri(EBoxFaceId face, int windOffset) const; + CVector3f ClosestPointAlongVector(const CVector3f& vec) const; + CVector3f FurthestPointAlongVector(const CVector3f& vec) const; + CVector3f GetCenterPoint() const; + CVector3f GetPoint(int) const; + // Include__6CAABoxFRC9CVector3f weak + // Include__6CAABoxFRC6CAABox weak + void AccumulateBounds(const CVector3f&); + bool Invalid() const; + bool PointInside(const CVector3f& vec) const; + bool DoBoundsOverlap(const CAABox&) const; + float GetVolume() const; + CAABox GetBooleanIntersection(const CAABox& other) const; + bool Inside(const CAABox& other) const; + bool InsidePlane(const CPlane& plane) const; + CVector3f ClampToBox(const CVector3f& vec) const; + CAABox GetTransformedAABox(const CTransform4f& xf) const; + + inline CVector3f GetHalfExtent() const { + // Name is a guess + return (max - min) * 0.5f; + } + + const CVector3f& GetMinPoint() const { return min; } + const CVector3f& GetMaxPoint() const { return max; } + + // GetPointA__6CAABoxCFv weak + // GetPointB__6CAABoxCFv weak + // GetPointC__6CAABoxCFv weak + // GetPointD__6CAABoxCFv weak + // GetPointE__6CAABoxCFv weak + // GetPointF__6CAABoxCFv weak + // GetPointG__6CAABoxCFv weak + // GetPointH__6CAABoxCFv weak + + // GetWidth__6CAABoxCFv weak + // GetDepth__6CAABoxCFv weak + // GetHeight__6CAABoxCFv weak + // GetTri__6CAABoxCFii weak + // GetEdge__6CAABoxCFi weak + + static const CAABox& Identity() { return mskNullBox; } + static const CAABox& MakeMaxInvertedBox() { return mskInvertedBox; } + // MakeNullBox__6CAABoxFv ?? + static float DistanceBetween(const CAABox& a, const CAABox& b); + +private: + CVector3f min; + CVector3f max; + + static CAABox mskInvertedBox; + static CAABox mskNullBox; +}; +CHECK_SIZEOF(CAABox, 0x18) + +#endif // _CAABOX diff --git a/include/Kyoto/Math/CAbsAngle.hpp b/include/Kyoto/Math/CAbsAngle.hpp new file mode 100644 index 0000000..3e38653 --- /dev/null +++ b/include/Kyoto/Math/CAbsAngle.hpp @@ -0,0 +1,51 @@ +#ifndef _CABSANGLE +#define _CABSANGLE + +#include "types.h" + +#include "Kyoto/Math/CMath.hpp" + +class CAbsAngle { +public: + float AsDegrees() const { return x0_angle * (180.f / M_PIF); } + float AsRadians() const { return x0_angle; } + // ArcCosine__9CAbsAngleFf weak + // -> calls ArcCosineR__5CMathFf + + CAbsAngle& operator+=(const CAbsAngle& v) { + x0_angle += v.x0_angle; + return *this; + } + CAbsAngle& operator-=(const CAbsAngle& v) { + x0_angle -= v.x0_angle; + return *this; + } + CAbsAngle& operator*=(float v) { + x0_angle *= v; + return *this; + } + CAbsAngle& operator/=(float v) { + x0_angle /= v; + return *this; + } + + // __apl__9CAbsAngleFRC9CRelAngle + // __ami__9CAbsAngleFRC9CRelAngle + + static CAbsAngle FromDegrees(float deg) { + return CAbsAngle(CMath::ClampRadians(deg * (M_PIF / 180.f))); + } + static CAbsAngle FromRadians(float rad) { return CAbsAngle(CMath::ClampRadians(rad)); } + +private: + CAbsAngle(float rad) : x0_angle(rad) {} + + float x0_angle; +}; +CHECK_SIZEOF(CAbsAngle, 0x4) + +// __mi__FRC9CAbsAngleRC9CAbsAngle + +static inline float cosine(const CAbsAngle& angle) { return cos(angle.AsRadians()); } + +#endif // _CABSANGLE diff --git a/include/Kyoto/Math/CFrustumPlanes.hpp b/include/Kyoto/Math/CFrustumPlanes.hpp new file mode 100644 index 0000000..047150b --- /dev/null +++ b/include/Kyoto/Math/CFrustumPlanes.hpp @@ -0,0 +1,35 @@ +#ifndef _CFRUSTUMPLANES +#define _CFRUSTUMPLANES + +#include "types.h" + +#include "Kyoto/Math/CVector3f.hpp" + +#include "rstl/optional_object.hpp" +#include "rstl/reserved_vector.hpp" + +class CAABox; +class CSphere; +class CTransform4f; + +class CFrustumPlanes { +public: + class SPlane { + private: + float x; + float y; + float z; + float d; + }; + CFrustumPlanes(const CTransform4f&, float, float, float, bool, float); + + bool BoxInFrustumPlanes(const CAABox& box) const; + bool BoxInFrustumPlanes(const rstl::optional_object< CAABox >& box) const; + bool SphereInFrustumPlanes(const CSphere& sphere) const; + bool PointInFrustumPlanes(const CVector3f& point) const; + +private: + rstl::reserved_vector< SPlane, 6 > x0_planes; +}; + +#endif // _CFRUSTUMPLANES diff --git a/include/Kyoto/Math/CLine.hpp b/include/Kyoto/Math/CLine.hpp new file mode 100644 index 0000000..04b1af2 --- /dev/null +++ b/include/Kyoto/Math/CLine.hpp @@ -0,0 +1,21 @@ +#ifndef _CLINE +#define _CLINE + +#include "types.h" + +#include "Kyoto/Math/CUnitVector3f.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +class CLine { +public: + CLine(const CVector3f& origin, const CUnitVector3f& dir) : x0_origin(origin), xc_dir(dir) {} + + const CVector3f& GetRefPoint() const { return x0_origin; } + const CUnitVector3f& GetNormal() const { return xc_dir; } + +private: + CVector3f x0_origin; + CUnitVector3f xc_dir; +}; + +#endif // _CLINE diff --git a/include/Kyoto/Math/CLineSeg.hpp b/include/Kyoto/Math/CLineSeg.hpp new file mode 100644 index 0000000..df3ba73 --- /dev/null +++ b/include/Kyoto/Math/CLineSeg.hpp @@ -0,0 +1,22 @@ +#ifndef _CLINESEG +#define _CLINESEG + +#include "types.h" + +#include "Kyoto/Math/CLine.hpp" +#include "Kyoto/Math/CUnitVector3f.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +class CLineSeg : public CLine { +public: + CLineSeg(const CVector3f& start, const CVector3f& end) + : CLine(start, (end - start).AsNormalized()), x18_end(end) {} + + const CVector3f& GetEndPoint() const { return x18_end; } + +private: + CVector3f x18_end; +}; +CHECK_SIZEOF(CLineSeg, 0x24) + +#endif // _CLINESEG diff --git a/include/Kyoto/Math/CMatrix4f.hpp b/include/Kyoto/Math/CMatrix4f.hpp new file mode 100644 index 0000000..1d03dba --- /dev/null +++ b/include/Kyoto/Math/CMatrix4f.hpp @@ -0,0 +1,41 @@ +#ifndef _CMATRIX4F +#define _CMATRIX4F + +#include "types.h" + +#include "Kyoto/Math/CVector3f.hpp" + +class CMatrix4f { +public: + CMatrix4f(float, float, float, float, float, float, float, float, float, float, float, float, + float, float, float, float); + + CVector3f operator*(const CVector3f& vec) const; + + CVector3f MultiplyOneOverW(const CVector3f& vec) const; + float MultiplyGetW(const CVector3f& vec) const; + + static const CMatrix4f& Identity() { return sIdentity; } + +private: + static const CMatrix4f sIdentity; + float m00; + float m01; + float m02; + float m03; + float m10; + float m11; + float m12; + float m13; + float m20; + float m21; + float m22; + float m23; + float m30; + float m31; + float m32; + float m33; +}; +CHECK_SIZEOF(CMatrix4f, 0x40); + +#endif // _CMATRIX4F diff --git a/include/Kyoto/Math/CNUQuaternion.hpp b/include/Kyoto/Math/CNUQuaternion.hpp new file mode 100644 index 0000000..dc8ea80 --- /dev/null +++ b/include/Kyoto/Math/CNUQuaternion.hpp @@ -0,0 +1,31 @@ +#ifndef _CNUQUATERNION +#define _CNUQUATERNION + +#include "types.h" + +class CMatrix3f; +class CVector3f; +class CQuaternion; + +class CNUQuaternion { +public: + CNUQuaternion(float w, float x, float y, float z) : w(w), x(x), y(y), z(z) {} + CNUQuaternion(float, const CVector3f&); + + static CNUQuaternion BuildFromMatrix3f(const CMatrix3f& matrix); + static CNUQuaternion BuildFromQuaternion(const CQuaternion& quat); + + CNUQuaternion& operator+=(const CNUQuaternion&); + CNUQuaternion operator*(const CNUQuaternion&) const; + +private: + float w; + float x; + float y; + float z; +}; + +CNUQuaternion operator*(float f, const CNUQuaternion&); +CNUQuaternion operator*(const CNUQuaternion&, float f); + +#endif // _CNUQUATERNION diff --git a/include/Kyoto/Math/CPlane.hpp b/include/Kyoto/Math/CPlane.hpp new file mode 100644 index 0000000..b847a92 --- /dev/null +++ b/include/Kyoto/Math/CPlane.hpp @@ -0,0 +1,31 @@ +#ifndef _CPLANE +#define _CPLANE + +#include "types.h" + +#include "Kyoto/Math/CUnitVector3f.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +class CPlane { +public: + CPlane(const CVector3f& vec, const CUnitVector3f& normal) + : x0_normal(normal), xc_constant(CVector3f::Dot(vec, normal)) {} + CPlane(float constant, const CUnitVector3f& normal) : x0_normal(normal), xc_constant(constant) {} + CPlane(const CVector3f&, const CVector3f&, const CVector3f&); + // TODO + + const CUnitVector3f& GetNormal() const { return x0_normal; } + float GetConstant() const { return xc_constant; } + float GetHeight(const CVector3f& pos) const { + return CVector3f::Dot(GetNormal(), pos) - GetConstant(); + } + // IsFacing__6CPlaneCFRC9CVector3f + float ClipLineSegment(const CVector3f& start, const CVector3f& end) const; + +private: + CUnitVector3f x0_normal; + float xc_constant; +}; +CHECK_SIZEOF(CPlane, 0x10) + +#endif // _CPLANE diff --git a/include/Kyoto/Math/CQuaternion.hpp b/include/Kyoto/Math/CQuaternion.hpp new file mode 100644 index 0000000..5aa924b --- /dev/null +++ b/include/Kyoto/Math/CQuaternion.hpp @@ -0,0 +1,83 @@ +#ifndef _CQUATERNION +#define _CQUATERNION + +#include "types.h" + +#include "Kyoto/Math/CMatrix3f.hpp" +#include "Kyoto/Math/CTransform4f.hpp" + +class CRelAngle; +class CUnitVector3f; +class CNUQuaternion; + +class CQuaternion { +public: + CQuaternion(float w, float x, float y, float z) : w(w), imaginary(x, y, z) {} + // __ct__11CQuaternionFfRC9CVector3f + + // CQuaternion(const CQuaternion& other) + // : w(other.w) + // , x(other.x) + // , y(other.y) + // , z(other.z) {} + // CQuaternion& operator=(const CQuaternion& other) { + // w = other.w; + // x = other.x; + // y = other.y; + // z = other.z; + // } + + CQuaternion operator*(const CQuaternion&) const; + // __amu__11CQuaternionFRC11CQuaternion + // ScalarVector__11CQuaternionFfRC9CVector3f + // Slerp__11CQuaternionFRC11CQuaternionRC11CQuaternionf + // ShortestRotationArc__11CQuaternionFRC9CVector3fRC9CVector3f + // LookAt__11CQuaternionFRC13CUnitVector3fRC13CUnitVector3fRC9CRelAngle + static CQuaternion LookAt(const CUnitVector3f&, const CUnitVector3f&, const CRelAngle&); + // normalize_angle__Ff + // IsValidQuaternion__11CQuaternionCFf + static CQuaternion SlerpLocal(const CQuaternion& from, const CQuaternion& to, float t); + // AngleFrom__11CQuaternionCFRC11CQuaternion + // BuildEquivalent__11CQuaternionCFv + // BuildNormalized__11CQuaternionCFv + static CQuaternion AxisAngle(const CUnitVector3f&, const CRelAngle&); + CVector3f Transform(const CVector3f&) const; + static CQuaternion XRotation(const CRelAngle&); + static CQuaternion YRotation(const CRelAngle&); + static CQuaternion ZRotation(const CRelAngle&); + CMatrix3f BuildTransform() const; + CTransform4f BuildTransform4f() const; + CTransform4f BuildTransform4f(const CVector3f&) const; + CQuaternion BuildInverted() const { + // double w = this->w; + // double x = -this->x; + // double y = -this->y; + // double z = -this->z; + return CQuaternion(w, -imaginary.GetX(), -imaginary.GetY(), -imaginary.GetZ()); + } + + static CQuaternion FromMatrixRows(const CVector3f&, const CVector3f&, const CVector3f&); + static CQuaternion FromMatrix(const CMatrix3f&); + static CQuaternion FromMatrix(const CTransform4f&); + static CQuaternion FromNUQuaternion(const CNUQuaternion&); + + static const CQuaternion& NoRotation() { return sNoRotation; } + + static float Dot(const CQuaternion& a, const CQuaternion& b) { + return (a.GetW() * b.GetW()) + (a.GetX() * b.GetX()) + (a.GetY() * b.GetY()) + (a.GetZ() * b.GetZ()); + } + + float GetW() const { return w; } + float GetX() const { return imaginary.GetX(); } + float GetY() const { return imaginary.GetY(); } + float GetZ() const { return imaginary.GetZ(); } + const CVector3f& GetImaginary() const { return imaginary; } + +private: + float w; + CVector3f imaginary; + + static const CQuaternion sNoRotation; +}; + +#endif // _CQUATERNION diff --git a/include/Kyoto/Math/CSphere.hpp b/include/Kyoto/Math/CSphere.hpp new file mode 100644 index 0000000..316a8ef --- /dev/null +++ b/include/Kyoto/Math/CSphere.hpp @@ -0,0 +1,23 @@ +#ifndef _CSPHERE +#define _CSPHERE + +#include "types.h" + +#include "Kyoto/Math/CUnitVector3f.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +class CSphere { +public: + CSphere(const CVector3f& pos, float radius) : x0_center(pos), xc_radius(radius) {} + + CVector3f GetCenter() const { return x0_center; } + float GetRadius() const { return xc_radius; } + CUnitVector3f GetSurfaceNormal(const CVector3f& v) const; + +private: + CVector3f x0_center; + float xc_radius; +}; +CHECK_SIZEOF(CSphere, 0x10) + +#endif // _CSPHERE diff --git a/include/Kyoto/Math/CTri.hpp b/include/Kyoto/Math/CTri.hpp new file mode 100644 index 0000000..c2c484a --- /dev/null +++ b/include/Kyoto/Math/CTri.hpp @@ -0,0 +1,27 @@ +#ifndef _CTRI +#define _CTRI + +#include "types.h" + +#include "Kyoto/Math/CPlane.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +class CTri { +public: + CTri(const CVector3f& a, const CVector3f& b, const CVector3f& c) + : x0_plane(a, b, c), x10_a(a), x1c_b(b), x28_c(c) {} + + const CPlane& GetPlane() const { return x0_plane; } + const CVector3f& GetPointA() const { return x10_a; } + const CVector3f& GetPointB() const { return x1c_b; } + const CVector3f& GetPointC() const { return x28_c; } + +private: + CPlane x0_plane; + CVector3f x10_a; + CVector3f x1c_b; + CVector3f x28_c; +}; +CHECK_SIZEOF(CTri, 0x34) + +#endif // _CTRI diff --git a/include/Kyoto/Math/CUnitVector3f.hpp b/include/Kyoto/Math/CUnitVector3f.hpp new file mode 100644 index 0000000..fe80527 --- /dev/null +++ b/include/Kyoto/Math/CUnitVector3f.hpp @@ -0,0 +1,34 @@ +#ifndef _CUNITVECTOR3F +#define _CUNITVECTOR3F + +#include "types.h" + +#include "Kyoto/Math/CVector3f.hpp" + +class CUnitVector3f : public CVector3f { +public: + enum ENormalize { + kN_No, + kN_Yes, + }; + CUnitVector3f(float x, float y, float z, ENormalize normalize) : CVector3f(x, y, z) { + if (normalize == kN_Yes) { + Normalize(); + } + } + CUnitVector3f( + const CVector3f& vec);//: CVector3f(vec.IsNonZero() ? vec.AsNormalized() : Zero()) {} + // TODO + + static CUnitVector3f Forward() { + return CUnitVector3f(CVector3f::Forward().GetX(), CVector3f::Forward().GetY(), + CVector3f::Forward().GetZ(), kN_No); + } +}; +CHECK_SIZEOF(CUnitVector3f, 0xc) + +inline CUnitVector3f operator-(const CUnitVector3f& vec) { + return CUnitVector3f(-vec.GetX(), -vec.GetY(), -vec.GetZ(), CUnitVector3f::kN_No); +} + +#endif // _CUNITVECTOR3F diff --git a/include/Kyoto/PVS/CPVSVisOctree.hpp b/include/Kyoto/PVS/CPVSVisOctree.hpp new file mode 100644 index 0000000..f63518f --- /dev/null +++ b/include/Kyoto/PVS/CPVSVisOctree.hpp @@ -0,0 +1,22 @@ +#ifndef _CPVSVISOCTREE +#define _CPVSVISOCTREE + +#include "Kyoto/Math/CAABox.hpp" +#include "Kyoto/Math/CVector3f.hpp" +#include "rstl/auto_ptr.hpp" + +class CPVSVisOctree { +public: + int IterateSearch(uchar a, const CVector3f& pos) const; + uint GetNumChildren(uchar a) const; + +private: + CAABox mBounds; + uint mNumObjects; + uint mNumLights; + rstl::auto_ptr< uchar > mOctreeData; + uint _28; + CAABox mSearchBounds; +}; + +#endif // _CPVSVISOCTREE diff --git a/include/Kyoto/PVS/CPVSVisSet.hpp b/include/Kyoto/PVS/CPVSVisSet.hpp new file mode 100644 index 0000000..26695a1 --- /dev/null +++ b/include/Kyoto/PVS/CPVSVisSet.hpp @@ -0,0 +1,17 @@ +#ifndef _CPVSVISSET +#define _CPVSVISSET + +#include "rstl/auto_ptr.hpp" + +class CPVSVisSet { +public: + static CPVSVisSet Reset(int); + +private: + int x0_state; + uint x4_numBits; + uint x8_numLights; + rstl::auto_ptr< u8 > x10_ptr; +}; + +#endif // _CPVSVISSET diff --git a/include/Kyoto/Particles/CColorElement.hpp b/include/Kyoto/Particles/CColorElement.hpp new file mode 100644 index 0000000..4bf917a --- /dev/null +++ b/include/Kyoto/Particles/CColorElement.hpp @@ -0,0 +1,97 @@ +#ifndef _CCOLORELEMENT +#define _CCOLORELEMENT + +#include "types.h" + +#include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Particles/IElement.hpp" + +class CCEConstant : public CColorElement { + CRealElement* x4_r; + CRealElement* x8_g; + CRealElement* xc_b; + CRealElement* x10_a; + +public: + CCEConstant(CRealElement* r, CRealElement* g, CRealElement* b, CRealElement* a); + ~CCEConstant() override; + bool GetValue(int frame, CColor& colorOut) const override; +}; + +class CCEFastConstant : public CColorElement { + CColor x4_val; + +public: + CCEFastConstant(float r, float g, float b, float a); + ~CCEFastConstant() override; + bool GetValue(int frame, CColor& colorOut) const override; +}; + +class CCEFade : public CColorElement { + CColorElement* x4_a; + CColorElement* x8_b; + CRealElement* xc_endFrame; + +public: + CCEFade(CColorElement* a, CColorElement* b, CRealElement* end); + ~CCEFade() override; + bool GetValue(int frame, CColor& colorOut) const override; +}; + +class CCEFadeEnd : public CColorElement { + CColorElement* x4_a; + CColorElement* x8_b; + CRealElement* xc_startFrame; + CRealElement* x10_endFrame; + +public: + CCEFadeEnd(CColorElement* a, CColorElement* b, CRealElement* start, CRealElement* end); + ~CCEFadeEnd() override; + bool GetValue(int frame, CColor& colorOut) const override; +}; + +class CCETimeChain : public CColorElement { + CColorElement* x4_a; + CColorElement* x8_b; + CIntElement* xc_swFrame; + +public: + CCETimeChain(CColorElement* a, CColorElement* b, CIntElement* c); + ~CCETimeChain() override; + bool GetValue(int frame, CColor& colorOut) const override; +}; + +class CCEPulse : public CColorElement { + CIntElement* x4_aDuration; + CIntElement* x8_bDuration; + CColorElement* xc_aVal; + CColorElement* x10_bVal; + +public: + CCEPulse(CIntElement* a, CIntElement* b, CColorElement* c, CColorElement* d); + ~CCEPulse() override; + bool GetValue(int frame, CColor& colorOut) const override; +}; + +class CCEKeyframeEmitter : public CColorElement { + int x4_percent; + int x8_unk1; + bool xc_loop; + bool xd_unk2; + int x10_loopEnd; + int x14_loopStart; + rstl::vector< CColor > x18_keys; + +public: + CCEKeyframeEmitter(CInputStream& in); + ~CCEKeyframeEmitter() override; + bool GetValue(int frame, CColor& valOut) const override; +}; + +class CCEParticleColor : public CColorElement { +public: + ~CCEParticleColor() override {} + bool GetValue(int frame, CColor& colorOut) const override; +}; + +#endif // _CCOLORELEMENT diff --git a/include/Kyoto/Particles/CEffectComponent.hpp b/include/Kyoto/Particles/CEffectComponent.hpp new file mode 100644 index 0000000..32071ff --- /dev/null +++ b/include/Kyoto/Particles/CEffectComponent.hpp @@ -0,0 +1,30 @@ +#ifndef _CEFFECTCOMPONENT +#define _CEFFECTCOMPONENT + +#include "Kyoto/Particles/CParticleData.hpp" + +#include "rstl/string.hpp" + +class CEffectComponent { +public: + explicit CEffectComponent(CInputStream& in); + + const rstl::string& GetComponentName() const { return x0_name; } + const SObjectTag& GetParticleTag() const { return x10_tag; } + const rstl::string& GetSegmentName() const { return x18_boneName; } + float GetScale() const { return x28_scale; } + CParticleData::EParentedMode GetParentedMode() const { return x2c_parentedMode; } + uint GetFlags() const {return x30_flags; } + +private: + SObjectTag GetSObjectTagFromStream(CInputStream& in); + + rstl::string x0_name; + SObjectTag x10_tag; + rstl::string x18_boneName; + float x28_scale; + CParticleData::EParentedMode x2c_parentedMode; + uint x30_flags; +}; + +#endif // _CEFFECTCOMPONENT diff --git a/include/Kyoto/Particles/CElectricDescription.hpp b/include/Kyoto/Particles/CElectricDescription.hpp new file mode 100644 index 0000000..e075625 --- /dev/null +++ b/include/Kyoto/Particles/CElectricDescription.hpp @@ -0,0 +1,40 @@ +#ifndef _CELECTRICDESCRIPTION +#define _CELECTRICDESCRIPTION + +#include "Kyoto/Particles/CParticleDataFactory.hpp" + +class CColorElement; +class CEmitterElement; +class CIntElement; +class CRealElement; + +// using SParticleModel = STokenDesc; +// using SChildGeneratorDesc = STokenDesc; +// using SSwooshGeneratorDesc = STokenDesc; +// using SElectricGeneratorDesc = STokenDesc; + +class CElectricDescription { +public: + CIntElement* x0_LIFE; + CIntElement* x4_SLIF; + CRealElement* x8_GRAT; + CIntElement* xc_SCNT; + CIntElement* x10_SSEG; + CColorElement* x14_COLR; + CEmitterElement* x18_IEMT; + CEmitterElement* x1c_FEMT; + CRealElement* x20_AMPL; + CRealElement* x24_AMPD; + CRealElement* x28_LWD1; + CRealElement* x2c_LWD2; + CRealElement* x30_LWD3; + CColorElement* x34_LCL1; + CColorElement* x38_LCL2; + CColorElement* x3c_LCL3; + // SSwooshGeneratorDesc x40_SSWH; + // SChildGeneratorDesc x50_GPSM; + // SChildGeneratorDesc x60_EPSM; + // bool x70_ZERY = false; +}; + +#endif // _CELECTRICDESCRIPTION diff --git a/include/Kyoto/Particles/CElementGen.hpp b/include/Kyoto/Particles/CElementGen.hpp new file mode 100644 index 0000000..fdc66e4 --- /dev/null +++ b/include/Kyoto/Particles/CElementGen.hpp @@ -0,0 +1,171 @@ +#ifndef _CELEMENTGEN +#define _CELEMENTGEN + +#include "types.h" + +#include "Kyoto/CRandom16.hpp" +#include "Kyoto/Math/CMatrix3f.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/Particles/CParticleGen.hpp" +#include "Kyoto/TToken.hpp" + +class CGenDescription; +class CModVectorElement; + +class CElementGen : public CParticleGen { +public: + enum EModelOrientationType { + kMOT_Normal, + kMOT_One, + }; + enum EOptionalSystemFlags { + kOSF_None, + kOSF_One, + kOSF_Two, + }; + enum LightType { + kLT_None = 0, + kLT_Custom = 1, + kLT_Directional = 2, + kLT_Spot = 3, + }; + struct CParticle { + int x0_endFrame; + CVector3f x4_pos; + CVector3f x10_prevPos; + CVector3f x1c_vel; + int x28_startFrame; + float x2c_lineLengthOrSize; + float x30_lineWidthOrRota; + CColor x34_color; + }; + + CElementGen(TToken< CGenDescription >, EModelOrientationType = kMOT_Normal, + EOptionalSystemFlags = kOSF_One); + ~CElementGen() override; + + virtual void Update(double) override; + virtual void Render() const override; + virtual void SetOrientation(const CTransform4f& orientation) override; + virtual void SetTranslation(const CVector3f& translation) override; + virtual void SetGlobalOrientation(const CTransform4f& orientation) override; + virtual void SetGlobalTranslation(const CVector3f& translation) override; + virtual void SetGlobalScale(const CVector3f& scale) override; + virtual void SetLocalScale(const CVector3f& scale) override; + virtual void SetParticleEmission(bool emission) override; + virtual void SetModulationColor(const CColor& col) override; + virtual void SetGeneratorRate(float rate) override {} + virtual const CTransform4f& GetOrientation() const override; + virtual const CVector3f& GetTranslation() const override; + virtual CTransform4f GetGlobalOrientation() const override; + virtual CVector3f GetGlobalTranslation() const override; + virtual CVector3f GetGlobalScale() const override; + virtual bool GetParticleEmission() const override; + virtual CColor GetModulationColor() const override; + virtual bool IsSystemDeletable() const override; + virtual rstl::optional_object GetBounds() const override; + virtual int GetParticleCount() const override; + virtual bool SystemHasLight() const override; + virtual CLight GetLight() override; + virtual void DestroyParticles() override; + virtual void AddModifier(CWarp*) override; + virtual uint Get4CharId() const override; + + int GetEmitterTime() const; + int GetSystemCount(); + + int GetCumulativeParticleCount() const { return x260_cumulativeParticles; } + bool IsIndirectTextured() const; // { return x28_loadedGenDesc->x54_x40_TEXR && x28_loadedGenDesc->x58_x44_TIND; } + float GetExternalVar(int index) const; + + static void Initialize(); + static void ShutDown(); + + void SetGlobalOrientAndTrans(const CTransform4f& xf); + void SetLeaveLightsEnabledForModelRender(bool b) { x26d_26_modelsUseLights = b; } + + static void SetSubtractBlend(bool subtract) { sSubtractBlend = subtract; } + +public: + TLockedToken< CGenDescription > x1c_genDesc; + CGenDescription* x28_loadedGenDesc; + EModelOrientationType x2c_orientType; + rstl::vector< CParticle > x30_particles; + rstl::vector< uint > x40; + rstl::vector< CMatrix3f > x50_parentMatrices; + rstl::vector< float[8] > x60_advValues; + int x70_internalStartFrame; + int x74_curFrame; + double x78_curSeconds; + float x80_timeDeltaScale; + int x84_prevFrame; + bool x88_particleEmission; + float x8c_generatorRemainder; + int x90_MAXP; + ushort x94_randomSeed; + float x98_generatorRate; + float x9c_externalVars[16]; + CVector3f xdc_translation; + CVector3f xe8_globalTranslation; + CVector3f xf4_POFS; + CVector3f x100_globalScale; + CTransform4f x10c_globalScaleTransform; + CTransform4f x13c_globalScaleTransformInverse; + CVector3f x16c_localScale; + CTransform4f x178_localScaleTransform; + CTransform4f x1a8_localScaleTransformInverse; + CTransform4f x1d8_orientation; + CMatrix3f x208_orientationInverse; + CTransform4f x22c_globalOrientation; + uint x25c_activeParticleCount; + uint x260_cumulativeParticles; + uint x264_recursiveParticleCount; + int x268_PSLT; + bool x26c_24_translationDirty : 1; + bool x26c_25_LIT_ : 1; + bool x26c_26_AAPH : 1; + bool x26c_27_ZBUF : 1; + bool x26c_28_zTest : 1; + bool x26c_29_ORNT : 1; + bool x26c_30_MBLR : 1; + bool x26c_31_LINE : 1; + bool x26d_24_FXLL : 1; + bool x26d_25_warmedUp : 1; + bool x26d_26_modelsUseLights : 1; + bool x26d_27_enableOPTS : 1; + bool x26d_28_enableADV : 1; + int x270_MBSP; + GXLightID x274_backupLightActive; + bool x278_hasVMD[4]; + CRandom16 x27c_randState; + CModVectorElement* x280_VELSources[4]; + rstl::vector< rstl::auto_ptr< CParticleGen > > x290_activePartChildren; + int x2a0_CSSD; + int x2a4_SISY; + int x2a8_PISY; + int x2ac_SSSD; + CVector3f x2b0_SSPO; + int x2bc_SESD; + CVector3f x2c0_SEPO; + float x2cc; + float x2d0; + CVector3f x2d4_aabbMin; + CVector3f x2e0_aabbMax; + float x2ec_maxSize; + CAABox x2f0_systemBounds; + LightType x308_lightType; + CColor x30c_LCLR; + float x310_LINT; + CVector3f x314_LOFF; + CVector3f x320_LDIR; + EFalloffType x32c_falloffType; + float x330_LFOR; + float x334_LSLA; + CColor x338_moduColor; + + static bool sSubtractBlend; +}; +CHECK_SIZEOF(CElementGen, 0x340) + +#endif // _CELEMENTGEN diff --git a/include/Kyoto/Particles/CEmitterElement.hpp b/include/Kyoto/Particles/CEmitterElement.hpp new file mode 100644 index 0000000..fd3232f --- /dev/null +++ b/include/Kyoto/Particles/CEmitterElement.hpp @@ -0,0 +1,50 @@ +#ifndef _CEMITTERELEMENT +#define _CEMITTERELEMENT + +#include "Kyoto/Particles/IElement.hpp" + +class CEESimpleEmitter : CEmitterElement { +public: + CEESimpleEmitter(CVectorElement* pos, CVectorElement* vel); + ~CEESimpleEmitter(); + + bool GetValue(int frame, CVector3f& pPos, CVector3f& pVel) const; + +private: + CVectorElement* x4_pos; + CVectorElement* x8_vel; +}; + +class CVESphere : CEmitterElement { +public: + CVESphere(CVectorElement* origin, CRealElement* radius, CRealElement* velocityMag); + ~CVESphere(); + + bool GetValue(int frame, CVector3f& pPos, CVector3f& pVel) const; + +private: + CVectorElement* x4_sphereOrigin; + CRealElement* x8_sphereRadius; + CRealElement* xc_velocityMag; +}; + +class CVEAngleSphere : CEmitterElement { +public: + CVEAngleSphere(CVectorElement* origin, CRealElement* radius, CRealElement* velocityMag, + CRealElement* angleXBias, CRealElement* angleYBias, CRealElement* angleXRange, + CRealElement* angleYRange); + ~CVEAngleSphere(); + + bool GetValue(int frame, CVector3f& pPos, CVector3f& pVel) const; + +private: + CVectorElement* x4_sphereOrigin; + CRealElement* x8_sphereRadius; + CRealElement* xc_velocityMag; + CRealElement* x10_angleXBias; + CRealElement* x14_angleYBias; + CRealElement* x18_angleXRange; + CRealElement* x1c_angleYRange; +}; + +#endif // _CEMITTERELEMENT diff --git a/include/Kyoto/Particles/CGenDescription.hpp b/include/Kyoto/Particles/CGenDescription.hpp new file mode 100644 index 0000000..a5b6970 --- /dev/null +++ b/include/Kyoto/Particles/CGenDescription.hpp @@ -0,0 +1,106 @@ +#ifndef _CGENDESCRIPTION +#define _CGENDESCRIPTION + +#include "types.h" + +#include "Kyoto/Particles/IElement.hpp" +#include "Kyoto/TToken.hpp" + +#include "rstl/optional_object.hpp" +#include "rstl/single_ptr.hpp" + +class CModel; +class CElectricDescription; +class CSwooshDescription; +class CSpawnSystemKeyframeData; + +class CGenDescription { +public: + typedef rstl::optional_object< TCachedToken< CModel > > TParticleModel; + typedef rstl::optional_object< TCachedToken< CGenDescription > > TChildGeneratorDesc; + typedef rstl::optional_object< TCachedToken< CSwooshDescription > > TSwooshGeneratorDesc; + typedef TCachedToken< CElectricDescription > TElectricGeneratorDesc; + + CGenDescription(); + ~CGenDescription(); + +private: + rstl::single_ptr< CIntElement > x0_PSLT; + rstl::single_ptr< CIntElement > x4_PSWT; + rstl::single_ptr< CRealElement > x8_PSTS; + rstl::single_ptr< CVectorElement > xc_POFS; + rstl::single_ptr< CIntElement > x10_SEED; + rstl::single_ptr< CRealElement > x14_LENG; + rstl::single_ptr< CRealElement > x18_WIDT; + rstl::single_ptr< CIntElement > x1c_MAXP; + rstl::single_ptr< CRealElement > x20_GRTE; + rstl::single_ptr< CColorElement > x24_COLR; + rstl::single_ptr< CIntElement > x28_LTME; + rstl::single_ptr< CEmitterElement > x2c_EMTR; + bool x30_28_SORT : 1; + bool x31_24_MBLR : 1; + bool x30_24_LINE : 1; + bool x30_29_LIT_ : 1; + bool x30_26_AAPH : 1; + bool x30_27_ZBUF : 1; + bool x30_25_FXLL : 1; + bool x31_25_PMAB : 1; + bool x31_31_VMD4 : 1; + bool x31_30_VMD3 : 1; + bool x31_29_VMD2 : 1; + bool x31_28_VMD1 : 1; + bool x32_25_OPTS : 1; + bool x31_26_PMUS : 1; + bool x31_27_PMOO : 1; + bool x32_24_CIND : 1; + bool x30_30_ORNT : 1; + bool x30_31_RSOP : 1; + rstl::single_ptr< CIntElement > x34_MBSP; + rstl::single_ptr< CRealElement > x38_SIZE; + rstl::single_ptr< CRealElement > x3c_ROTA; + rstl::single_ptr< CUVElement > x40_TEXR; + rstl::single_ptr< CUVElement > x44_TIND; + TParticleModel x48_PMDL; + rstl::single_ptr< CVectorElement > x58_PMOP; + rstl::single_ptr< CVectorElement > x5c_PMRT; + rstl::single_ptr< CVectorElement > x60_PMSC; + rstl::single_ptr< CColorElement > x64_PMCL; + rstl::single_ptr< CModVectorElement > x68_VEL1; + rstl::single_ptr< CModVectorElement > x6c_VEL2; + rstl::single_ptr< CModVectorElement > x70_VEL3; + rstl::single_ptr< CModVectorElement > x74_VEL4; + TChildGeneratorDesc x78_ICTS; + rstl::single_ptr< CIntElement > x88_NCSY; + rstl::single_ptr< CIntElement > x8c_CSSD; + TChildGeneratorDesc x90_IDTS; + rstl::single_ptr< CIntElement > xa0_NDSY; + TChildGeneratorDesc xa4_IITS; + rstl::single_ptr< CIntElement > xb4_PISY; + rstl::single_ptr< CIntElement > xb8_SISY; + rstl::single_ptr< CSpawnSystemKeyframeData > xbc_KSSM; + TSwooshGeneratorDesc xc0_SSWH; + rstl::single_ptr< CIntElement > xd0_SSSD; + rstl::single_ptr< CVectorElement > xd4_SSPO; + TElectricGeneratorDesc xd8_SELC; + rstl::single_ptr< CIntElement > xe4_SESD; + rstl::single_ptr< CVectorElement > xe8_SEPO; + rstl::single_ptr< CIntElement > xec_LTYP; + rstl::single_ptr< CColorElement > xf0_LCLR; + rstl::single_ptr< CRealElement > xf4_LINT; + rstl::single_ptr< CVectorElement > xf8_LOFF; + rstl::single_ptr< CVectorElement > xfc_LDIR; + rstl::single_ptr< CIntElement > x100_LFOT; + rstl::single_ptr< CRealElement > x104_LFOR; + rstl::single_ptr< CRealElement > x108_LSLA; + rstl::single_ptr< CRealElement > x10c_ADV1; + rstl::single_ptr< CRealElement > x110_ADV2; + rstl::single_ptr< CRealElement > x114_ADV3; + rstl::single_ptr< CRealElement > x118_ADV4; + rstl::single_ptr< CRealElement > x11c_ADV5; + rstl::single_ptr< CRealElement > x120_ADV6; + rstl::single_ptr< CRealElement > x124_ADV7; + rstl::single_ptr< CRealElement > x128_ADV8; +}; +CHECK_SIZEOF(CGenDescription, 0x12c) + +#endif // _CGENDESCRIPTION diff --git a/include/Kyoto/Particles/CIntElement.hpp b/include/Kyoto/Particles/CIntElement.hpp new file mode 100644 index 0000000..bf6ddb9 --- /dev/null +++ b/include/Kyoto/Particles/CIntElement.hpp @@ -0,0 +1,208 @@ +#ifndef _CINTELEMENT +#define _CINTELEMENT + +#include "types.h" + +#include "Kyoto/Particles/IElement.hpp" + +#include "rstl/vector.hpp" + +class CInputStream; + +class CIEConstant : public CIntElement { + int x4_val; + +public: + CIEConstant(int val); + ~CIEConstant() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEDeath : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIEDeath(CIntElement* a, CIntElement* b); + ~CIEDeath() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEAdd : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIEAdd(CIntElement* a, CIntElement* b); + ~CIEAdd() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEMultiply : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIEMultiply(CIntElement* a, CIntElement* b); + ~CIEMultiply() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEModulo : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIEModulo(CIntElement* a, CIntElement* b); + ~CIEModulo() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIERandom : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIERandom(CIntElement* a, CIntElement* b); + ~CIERandom() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIESampleAndHold : public CIntElement { + CIntElement* x4_sampleSource; + mutable int x8_nextSampleFrame; + CIntElement* xc_waitFramesMin; + CIntElement* x10_waitFramesMax; + mutable int x14_holdVal; + +public: + CIESampleAndHold(CIntElement* a, CIntElement* b, CIntElement* c); + ~CIESampleAndHold() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEImpulse : public CIntElement { + CIntElement* x4_a; + +public: + CIEImpulse(CIntElement* a); + ~CIEImpulse() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIETimescale : public CIntElement { + CRealElement* x4_a; + +public: + CIETimescale(CRealElement* a); + ~CIETimescale(); + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEInitialRandom : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIEInitialRandom(CIntElement* a, CIntElement* b); + ~CIEInitialRandom() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIETimeChain : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + CIntElement* xc_swFrame; + +public: + CIETimeChain(CIntElement* a, CIntElement* b, CIntElement* c); + ~CIETimeChain() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEClamp : public CIntElement { + CIntElement* x4_min; + CIntElement* x8_max; + CIntElement* xc_val; + +public: + CIEClamp(CIntElement* a, CIntElement* b, CIntElement* c); + ~CIEClamp() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEPulse : public CIntElement { + CIntElement* x4_aDuration; + CIntElement* x8_bDuration; + CIntElement* xc_aVal; + CIntElement* x10_bVal; + +public: + CIEPulse(CIntElement* a, CIntElement* b, CIntElement* c, CIntElement* d); + ~CIEPulse() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIELifetimePercent : public CIntElement { + CIntElement* x4_percentVal; + +public: + CIELifetimePercent(CIntElement* a); + ~CIELifetimePercent() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEKeyframeEmitter : public CIntElement { + int x4_percent; + int x8_unk1; + bool xc_loop; + bool xd_unk2; + int x10_loopEnd; + int x14_loopStart; + rstl::vector< int > x18_keys; + +public: + CIEKeyframeEmitter(CInputStream& in); + ~CIEKeyframeEmitter() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIESubtract : public CIntElement { + CIntElement* x4_a; + CIntElement* x8_b; + +public: + CIESubtract(CIntElement* a, CIntElement* b); + ~CIESubtract() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIERealToInt : public CIntElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CIERealToInt(CRealElement* a, CRealElement* b); + ~CIERealToInt() override; + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEGetCumulativeParticleCount : public CIntElement { +public: + ~CIEGetCumulativeParticleCount() override {} + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEGetActiveParticleCount : public CIntElement { +public: + ~CIEGetActiveParticleCount() override {} + bool GetValue(int frame, int& valOut) const override; +}; + +class CIEGetEmitterTime : public CIntElement { +public: + ~CIEGetEmitterTime() override; + bool GetValue(int frame, int& valOut) const override; +}; + +#endif // _CINTELEMENT diff --git a/include/Kyoto/Particles/CModVectorElement.hpp b/include/Kyoto/Particles/CModVectorElement.hpp new file mode 100644 index 0000000..74f4141 --- /dev/null +++ b/include/Kyoto/Particles/CModVectorElement.hpp @@ -0,0 +1,159 @@ +#ifndef _CMODVECTORELEMENT +#define _CMODVECTORELEMENT + +#include "types.h" + +#include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/Particles/IElement.hpp" + +class CMVEConstant : public CModVectorElement { + CRealElement* x4_x; + CRealElement* x8_y; + CRealElement* xc_z; + +public: + CMVEConstant(CRealElement* a, CRealElement* b, CRealElement* c); + ~CMVEConstant() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEFastConstant : public CModVectorElement { + CVector3f x4_val; + +public: + CMVEFastConstant(float a, float b, float c); + ~CMVEFastConstant() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEGravity : public CModVectorElement { + CVectorElement* x4_a; + +public: + CMVEGravity(CVectorElement* a); + ~CMVEGravity() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEWind : public CModVectorElement { + CVectorElement* x4_velocity; + CRealElement* x8_factor; + +public: + CMVEWind(CVectorElement* velocity, CRealElement* factor); + ~CMVEWind() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEExplode : public CModVectorElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CMVEExplode(CRealElement* a, CRealElement* b); + ~CMVEExplode() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVETimeChain : public CModVectorElement { + CModVectorElement* x4_a; + CModVectorElement* x8_b; + CIntElement* xc_swFrame; + +public: + CMVETimeChain(CModVectorElement* a, CModVectorElement* b, CIntElement* c); + ~CMVETimeChain() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEPulse : public CModVectorElement { + CIntElement* x4_aDuration; + CIntElement* x8_bDuration; + CModVectorElement* xc_aVal; + CModVectorElement* x10_bVal; + +public: + CMVEPulse(CIntElement* a, CIntElement* b, CModVectorElement* c, CModVectorElement* d); + ~CMVEPulse() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEImplosion : public CModVectorElement { + CVectorElement* x4_implPoint; + CRealElement* x8_magScale; + CRealElement* xc_maxMag; + CRealElement* x10_minMag; + bool x14_enableMinMag; + +public: + CMVEImplosion(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, bool e); + ~CMVEImplosion() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVELinearImplosion : public CModVectorElement { + CVectorElement* x4_implPoint; + CRealElement* x8_magScale; + CRealElement* xc_maxMag; + CRealElement* x10_minMag; + bool x14_enableMinMag; + +public: + CMVELinearImplosion(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, bool e); + ~CMVELinearImplosion() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEExponentialImplosion : public CModVectorElement { + CVectorElement* x4_implPoint; + CRealElement* x8_magScale; + CRealElement* xc_maxMag; + CRealElement* x10_minMag; + bool x14_enableMinMag; + +public: + CMVEExponentialImplosion(CVectorElement* a, CRealElement* b, CRealElement* c, CRealElement* d, + bool e); + ~CMVEExponentialImplosion() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVESwirl : public CModVectorElement { + CVectorElement* x4_helixPoint; + CVectorElement* x8_curveBinormal; + CRealElement* xc_filterGain; + CRealElement* x10_tangentialVelocity; + +public: + CMVESwirl(CVectorElement* a, CVectorElement* b, CRealElement* c, CRealElement* d); + ~CMVESwirl() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVEBounce : public CModVectorElement { + CVectorElement* x4_planePoint; + CVectorElement* x8_planeNormal; + CRealElement* xc_friction; + CRealElement* x10_restitution; + bool x14_planePrecomputed; + bool x15_dieOnPenetrate; + mutable CVector3f x18_planeValidatedNormal; + mutable float x24_planeD; + +public: + CMVEBounce(CVectorElement* planePoint, CVectorElement* planeNormal, CRealElement* friction, + CRealElement* restitution, bool e); + ~CMVEBounce() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +class CMVESetPosition : public CModVectorElement { + CVectorElement* x4_a; + +public: + CMVESetPosition(CVectorElement* a); + ~CMVESetPosition() override; + bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const override; +}; + +#endif // _CMODVECTORELEMENT diff --git a/include/Kyoto/Particles/CParticleData.hpp b/include/Kyoto/Particles/CParticleData.hpp new file mode 100644 index 0000000..cdbe7aa --- /dev/null +++ b/include/Kyoto/Particles/CParticleData.hpp @@ -0,0 +1,46 @@ +#ifndef _CPARTICLEDATA +#define _CPARTICLEDATA + +#include "types.h" + +#include "Kyoto/IObjectStore.hpp" +#include "Kyoto/Math/CVector3f.hpp" + +#include "rstl/string.hpp" + +class CInputStream; +class CParticleData { +public: + enum EParentedMode { + kPM_Initial, + kPM_ContinuousEmitter, + kPM_ContinuousSystem, + }; + + CParticleData(int duration, const SObjectTag& tag, const rstl::string& boneName, float scale, + EParentedMode mode) + : x0_duration(duration) + , x4_particle(tag) + , xc_boneName(boneName) + , x1c_scale(scale) + , x20_parentMode(mode) {} + + CParticleData(CInputStream& in); + +private: + int x0_duration; + SObjectTag x4_particle; + rstl::string xc_boneName; + float x1c_scale; + EParentedMode x20_parentMode; +}; + +class CAuxiliaryParticleData { +private: + uint x0_duration; + SObjectTag x4_particle; + CVector3f xc_translation; + float x18_scale; +}; + +#endif // _CPARTICLEDATA diff --git a/include/Kyoto/Particles/CParticleDataFactory.hpp b/include/Kyoto/Particles/CParticleDataFactory.hpp new file mode 100644 index 0000000..23a42f9 --- /dev/null +++ b/include/Kyoto/Particles/CParticleDataFactory.hpp @@ -0,0 +1,24 @@ +#ifndef _CPARTICLEDATAFACTORY +#define _CPARTICLEDATAFACTORY + +#include "Kyoto/Particles/IElement.hpp" +#include "Kyoto/SObjectTag.hpp" + +class CInputStream; + +class CParticleDataFactory { + static CUVElement* GetTextureElement(CInputStream& in, CSimplePool* resPool); + static CColorElement* GetColorElement(CInputStream& in); + static CModVectorElement* GetModVectorElement(CInputStream& in); + static CEmitterElement* GetEmitterElement(CInputStream& in); + static CVectorElement* GetVectorElement(CInputStream& in); + static CRealElement* GetRealElement(CInputStream& in); + static CIntElement* GetIntElement(CInputStream& in); + + static float GetReal(CInputStream& in); + static int GetInt(CInputStream& in); + static bool GetBool(CInputStream& in); + static FourCC GetClassID(CInputStream& in); +}; + +#endif // _CPARTICLEDATAFACTORY diff --git a/include/Kyoto/Particles/CParticleElectric.hpp b/include/Kyoto/Particles/CParticleElectric.hpp new file mode 100644 index 0000000..127bc2a --- /dev/null +++ b/include/Kyoto/Particles/CParticleElectric.hpp @@ -0,0 +1,58 @@ +#ifndef _CPARTICLEELECTRIC +#define _CPARTICLEELECTRIC + +#include "Kyoto/Particles/CParticleGen.hpp" + +#include "Kyoto/TToken.hpp" + +class CElectricDescription; + +class CParticleElectric : public CParticleGen { +public: + explicit CParticleElectric(TToken desc); + + ~CParticleElectric() override; + void Update(double) override; + void Render() const override; + void SetOrientation(const CTransform4f& orientation) override; + void SetTranslation(const CVector3f& translation) override; + void SetGlobalOrientation(const CTransform4f& orientation) override; + void SetGlobalTranslation(const CVector3f& translation) override; + void SetGlobalScale(const CVector3f& scale) override; + void SetLocalScale(const CVector3f& scale) override; + void SetParticleEmission(bool emission) override; + void SetModulationColor(const CColor& col) override; + void SetGeneratorRate(float rate) {} + const CTransform4f& GetOrientation() const override; + const CVector3f& GetTranslation() const override; + CTransform4f GetGlobalOrientation() const override; + CVector3f GetGlobalTranslation() const override; + CVector3f GetGlobalScale() const override; + bool GetParticleEmission() const override; + CColor GetModulationColor() const override; + bool IsSystemDeletable() const override; + rstl::optional_object GetBounds() const override; + int GetParticleCount() const override; + bool SystemHasLight() const override; + CLight GetLight() override; + void DestroyParticles() override; + void AddModifier(CWarp*) override; + uint Get4CharId() const override; + + + void SetOverrideIPos(const CVector3f& vec) { x178_overrideIPos = vec; } + void SetOverrideIVel(const CVector3f& vec) { x188_overrideIVel = vec; } + void SetOverrideFPos(const CVector3f& vec) { x198_overrideFPos = vec; } + void SetOverrideFVel(const CVector3f& vec) { x1a8_overrideFVel = vec; } + +private: + uchar x1c_pad[0x15c]; + rstl::optional_object x178_overrideIPos; + rstl::optional_object x188_overrideIVel; + rstl::optional_object x198_overrideFPos; + rstl::optional_object x1a8_overrideFVel; + uchar x1b8_pad[0x2a0]; +}; +CHECK_SIZEOF(CParticleElectric, 0x458) + +#endif // _CPARTICLEELECTRIC diff --git a/include/Kyoto/Particles/CParticleGen.hpp b/include/Kyoto/Particles/CParticleGen.hpp new file mode 100644 index 0000000..d399542 --- /dev/null +++ b/include/Kyoto/Particles/CParticleGen.hpp @@ -0,0 +1,52 @@ +#ifndef _CPARTICLEGEN +#define _CPARTICLEGEN + +#include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Graphics/CLight.hpp" +#include "Kyoto/Math/CAABox.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/Particles/CWarp.hpp" + +#include "rstl/list.hpp" +#include "rstl/pair.hpp" +#include "rstl/optional_object.hpp" + +class CWarp; + +class CParticleGen { +public: + virtual ~CParticleGen() {}; + virtual void Update(double) = 0; + virtual void Render() const = 0; + virtual void SetOrientation(const CTransform4f& orientation) = 0; + virtual void SetTranslation(const CVector3f& translation) = 0; + virtual void SetGlobalOrientation(const CTransform4f& orientation) = 0; + virtual void SetGlobalTranslation(const CVector3f& translation) = 0; + virtual void SetGlobalScale(const CVector3f& scale) = 0; + virtual void SetLocalScale(const CVector3f& scale) = 0; + virtual void SetParticleEmission(bool emission) = 0; + virtual void SetModulationColor(const CColor& col) = 0; + virtual void SetGeneratorRate(float rate) {} + virtual const CTransform4f& GetOrientation() const = 0; + virtual const CVector3f& GetTranslation() const = 0; + virtual CTransform4f GetGlobalOrientation() const = 0; + virtual CVector3f GetGlobalTranslation() const = 0; + virtual CVector3f GetGlobalScale() const = 0; + virtual bool GetParticleEmission() const = 0; + virtual CColor GetModulationColor() const = 0; + virtual float GetGeneratorRate() const { return 1.f; } + virtual bool IsSystemDeletable() const = 0; + virtual rstl::optional_object GetBounds() const = 0; + virtual int GetParticleCount() const = 0; + virtual bool SystemHasLight() const = 0; + virtual CLight GetLight() = 0; + virtual void DestroyParticles() = 0; + virtual void AddModifier(CWarp*) = 0; + virtual uint Get4CharId() const = 0; + +private: + rstl::list< CWarp* > x4_modifiersList; +}; + +#endif // _CPARTICLEGEN diff --git a/include/Kyoto/Particles/CParticleGlobals.hpp b/include/Kyoto/Particles/CParticleGlobals.hpp new file mode 100644 index 0000000..d7480c2 --- /dev/null +++ b/include/Kyoto/Particles/CParticleGlobals.hpp @@ -0,0 +1,46 @@ +#ifndef _CPARTICLEGLOBALS +#define _CPARTICLEGLOBALS + +#include "types.h" + +#include "Kyoto/SObjectTag.hpp" +#include "Kyoto/Particles/CElementGen.hpp" + +class CParticleGlobals { +public: + struct SParticleSystem { + FourCC x0_type; + CElementGen* x4_system; + }; + + static void SetEmitterTime(int time); + static void SetParticleLifetime(int lifetime); + static void UpdateParticleLifetimeTweenValues(int time); + + static int GetParticleLifetime() { return mParticleLifetime; } + static float GetParticleLifetimeReal() { return mParticleLifetimeReal; } + static int GetEmitterTime() { return mEmitterTime; } + static float GetEmitterTimeReal() { return mEmitterTimeReal; } + static int GetParticleLifetimePercentage() { return mParticleLifetimePercentage; } + static float GetParticleLifetimePercentageReal() { return mParticleLifetimePercentageReal; } + static float GetParticleLifetimePercentageRemainder() { + return mParticleLifetimePercentageRemainder; + } + static CElementGen::CParticle* GetCurrentParticle() { return mCurrentParticle; } + static float* GetParticleAccessParameters() { return mParticleAccessParameters; } + static SParticleSystem* GetCurrentParticleSystem() { return mCurrentParticleSystem; } + +private: + static int mParticleLifetime; + static float mParticleLifetimeReal; + static int mEmitterTime; + static float mEmitterTimeReal; + static int mParticleLifetimePercentage; + static float mParticleLifetimePercentageReal; + static float mParticleLifetimePercentageRemainder; + static CElementGen::CParticle* mCurrentParticle; + static float* mParticleAccessParameters; + static SParticleSystem* mCurrentParticleSystem; +}; + +#endif // _CPARTICLEGLOBALS diff --git a/include/Kyoto/Particles/CRealElement.hpp b/include/Kyoto/Particles/CRealElement.hpp new file mode 100644 index 0000000..61c0259 --- /dev/null +++ b/include/Kyoto/Particles/CRealElement.hpp @@ -0,0 +1,368 @@ +#ifndef _CREALELEMENT +#define _CREALELEMENT + +#include "types.h" + +#include "Kyoto/Particles/IElement.hpp" + +#include "rstl/vector.hpp" + +class CREConstant : public CRealElement { + float x4_val; + +public: + CREConstant(float val); + ~CREConstant() override; + bool GetValue(int frame, float& valOut) const override; + bool IsConstant() const override { return true; } +}; + +class CRESineWave : public CRealElement { + CRealElement* x4_frequency; + CRealElement* x8_amplitude; + CRealElement* xc_phase; + +public: + CRESineWave(CRealElement* a, CRealElement* b, CRealElement* c); + ~CRESineWave() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRETimeScale : public CRealElement { + CRealElement* x4_a; + +public: + CRETimeScale(CRealElement* a); + ~CRETimeScale() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREAdd : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CREAdd(CRealElement* a, CRealElement* b); + ~CREAdd() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREMultiply : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CREMultiply(CRealElement* a, CRealElement* b); + ~CREMultiply() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREDotProduct : public CRealElement { + CVectorElement* x4_a; + CVectorElement* x8_b; + +public: + CREDotProduct(CVectorElement* a, CVectorElement* b); + ~CREDotProduct() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRERandom : public CRealElement { + CRealElement* x4_min; + CRealElement* x8_max; + +public: + CRERandom(CRealElement* min, CRealElement* max); + ~CRERandom() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREInitialRandom : public CRealElement { + CRealElement* x4_min; + CRealElement* x8_max; + +public: + CREInitialRandom(CRealElement* min, CRealElement* max); + ~CREInitialRandom() override; + bool GetValue(int frame, float& valOut) const override; + bool IsConstant() const override { return true; } +}; + +class CRETimeChain : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + CIntElement* xc_swFrame; + +public: + CRETimeChain(CRealElement* a, CRealElement* b, CIntElement* c); + ~CRETimeChain() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREClamp : public CRealElement { + CRealElement* x4_min; + CRealElement* x8_max; + CRealElement* xc_val; + +public: + CREClamp(CRealElement* a, CRealElement* b, CRealElement* c); + ~CREClamp() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREPulse : public CRealElement { + CIntElement* x4_aDuration; + CIntElement* x8_bDuration; + CRealElement* xc_valA; + CRealElement* x10_valB; + +public: + CREPulse(CIntElement* a, CIntElement* b, CRealElement* c, CRealElement* d); + ~CREPulse() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRELifetimePercent : public CRealElement { + CRealElement* x4_percentVal; + +public: + CRELifetimePercent(CRealElement* a); // : x4_percentVal(a) {} + ~CRELifetimePercent() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRELifetimeTween : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CRELifetimeTween(CRealElement* a, CRealElement* b); + ~CRELifetimeTween() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREKeyframeEmitter : public CRealElement { + int x4_percent; + int x8_unk1; + bool xc_loop; + bool xd_unk2; + int x10_loopEnd; + int x14_loopStart; + rstl::vector< float > x18_keys; + +public: + CREKeyframeEmitter(CInputStream& in); + ~CREKeyframeEmitter() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter1 : public CRealElement { +public: + ~CREParticleAccessParameter1() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter2 : public CRealElement { +public: + ~CREParticleAccessParameter2() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter3 : public CRealElement { +public: + ~CREParticleAccessParameter3() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter4 : public CRealElement { +public: + ~CREParticleAccessParameter4() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter5 : public CRealElement { +public: + ~CREParticleAccessParameter5() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter6 : public CRealElement { +public: + ~CREParticleAccessParameter6() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter7 : public CRealElement { +public: + ~CREParticleAccessParameter7() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleAccessParameter8 : public CRealElement { +public: + ~CREParticleAccessParameter8() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleSizeOrLineLength : public CRealElement { +public: + ~CREParticleSizeOrLineLength() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREParticleRotationOrLineWidth : public CRealElement { +public: + ~CREParticleRotationOrLineWidth() override {} + bool GetValue(int frame, float& valOut) const override; +}; + +class CREVectorXToReal : public CRealElement { + CVectorElement* x4_a; + +public: + CREVectorXToReal(CVectorElement* a); + ~CREVectorXToReal() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREVectorYToReal : public CRealElement { + CVectorElement* x4_a; + +public: + CREVectorYToReal(CVectorElement* a); + ~CREVectorYToReal() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREVectorZToReal : public CRealElement { + CVectorElement* x4_a; + +public: + CREVectorZToReal(CVectorElement* a); + ~CREVectorZToReal() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREVectorMagnitude : public CRealElement { + CVectorElement* x4_a; + +public: + CREVectorMagnitude(CVectorElement* a); + ~CREVectorMagnitude() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREInitialSwitch : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CREInitialSwitch(CRealElement* a, CRealElement* b); + ~CREInitialSwitch() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRECompareLessThan : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + CRealElement* xc_c; + CRealElement* x10_d; + +public: + CRECompareLessThan(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d); + ~CRECompareLessThan() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRECompareEqual : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + CRealElement* xc_c; + CRealElement* x10_d; + +public: + CRECompareEqual(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d); + ~CRECompareEqual() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREConstantRange : public CRealElement { + CRealElement* x4_val; + CRealElement* x8_min; + CRealElement* xc_max; + CRealElement* x10_inRange; + CRealElement* x14_outOfRange; + +public: + CREConstantRange(CRealElement* a, CRealElement* b, CRealElement* c, CRealElement* d, + CRealElement* e); + ~CREConstantRange() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREExternalVar : public CRealElement { + CIntElement* x4_a; + +public: + CREExternalVar(CIntElement* a); + ~CREExternalVar() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CRESubtract : public CRealElement { + CRealElement* x4_a; + CRealElement* x8_b; + +public: + CRESubtract(CRealElement* a, CRealElement* b); + ~CRESubtract() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREGetComponentRed : public CRealElement { + CColorElement* x4_a; + +public: + CREGetComponentRed(CColorElement* a); + ~CREGetComponentRed() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREGetComponentGreen : public CRealElement { + CColorElement* x4_a; + +public: + CREGetComponentGreen(CColorElement* a); + ~CREGetComponentGreen() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREGetComponentBlue : public CRealElement { + CColorElement* x4_a; + +public: + CREGetComponentBlue(CColorElement* a); + ~CREGetComponentBlue() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREGetComponentAlpha : public CRealElement { + CColorElement* x4_a; + +public: + CREGetComponentAlpha(CColorElement* a); + ~CREGetComponentAlpha() override; + bool GetValue(int frame, float& valOut) const override; +}; + +class CREIntTimesReal : public CRealElement { + CIntElement* x4_a; + CRealElement* x8_b; + +public: + CREIntTimesReal(CIntElement* a, CRealElement* b); + ~CREIntTimesReal() override; + bool GetValue(int frame, float& valOut) const override; +}; + +#endif // _CREALELEMENT diff --git a/include/Kyoto/Particles/CUVElement.hpp b/include/Kyoto/Particles/CUVElement.hpp new file mode 100644 index 0000000..c7ae538 --- /dev/null +++ b/include/Kyoto/Particles/CUVElement.hpp @@ -0,0 +1,44 @@ +#ifndef _CUVELEMENT +#define _CUVELEMENT + +#include "types.h" + +#include "Kyoto/Particles/IElement.hpp" +#include "Kyoto/TToken.hpp" + +class CTexture; + +class CUVEConstant : public CUVElement { + TLockedToken< CTexture > x4_tex; + +public: + CUVEConstant(TToken< CTexture > tex); + ~CUVEConstant() override; + TLockedToken< CTexture > GetValueTexture(int frame) const override; + void GetValueUV(int frame, SUVElementSet& valOut) const override; + bool HasConstantTexture() const override { return true; } + bool HasConstantUV() const override { return true; } +}; + +class CUVEAnimTexture : public CUVElement { + TLockedToken< CTexture > x4_tex; + int x10_tileW; + int x14_tileH; + int x18_strideW; + int x1c_strideH; + int x20_tiles; + bool x24_loop; + CIntElement* x28_cycleFrames; + rstl::vector< SUVElementSet > x2c_uvElems; + +public: + CUVEAnimTexture(TToken< CTexture > tex, CIntElement* tileW, CIntElement* tileH, + CIntElement* strideW, CIntElement* strideH, CIntElement* cycleFrames, bool loop); + ~CUVEAnimTexture() override; + TLockedToken< CTexture > GetValueTexture(int frame) const override; + void GetValueUV(int frame, SUVElementSet& valOut) const override; + bool HasConstantTexture() const override { return true; } + bool HasConstantUV() const override { return false; } +}; + +#endif // _CUVELEMENT diff --git a/include/Kyoto/Particles/CVectorElement.hpp b/include/Kyoto/Particles/CVectorElement.hpp new file mode 100644 index 0000000..0145bd9 --- /dev/null +++ b/include/Kyoto/Particles/CVectorElement.hpp @@ -0,0 +1,102 @@ +#ifndef _CVECTORELEMENT +#define _CVECTORELEMENT + +#include "types.h" + +#include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/Particles/IElement.hpp" + +#include "rstl/single_ptr.hpp" + +class CVEFastConstant : public CVectorElement { +public: + CVEFastConstant(float x, float y, float z); + ~CVEFastConstant() override; + bool GetValue(int frame, CVector3f& valOut) const override; + bool IsFastConstant() const override { return true; } + +private: + CVector3f x4_val; +}; + +class CVEParticleLocation : public CVectorElement { +public: + ~CVEParticleLocation() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEParticleColor : public CVectorElement { +public: + ~CVEParticleColor() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEParticleVelocity : public CVectorElement { +public: + ~CVEParticleVelocity() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEParticleSystemOrientationFront : public CVectorElement { +public: + ~CVEParticleSystemOrientationFront() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEParticleSystemOrientationUp : public CVectorElement { +public: + ~CVEParticleSystemOrientationUp() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEParticleSystemOrientationRight : public CVectorElement { +public: + ~CVEParticleSystemOrientationRight() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEParticleSystemTranslation : public CVectorElement { +public: + ~CVEParticleSystemTranslation() override {} + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEConstant : public CVectorElement { +public: + CVEConstant(CRealElement* x, CRealElement* y, CRealElement* z); + ~CVEConstant(); + bool GetValue(int frame, CVector3f& valOut) const override; + +public: + CRealElement* x4_x; + CRealElement* x8_y; + CRealElement* xc_z; +}; + +class CVECone : public CVectorElement { + CVectorElement* x4_direction; + CRealElement* x8_magnitude; + CVector3f xc_xVec; + CVector3f x18_yVec; + +public: + CVECone(CVectorElement* direction, CRealElement* magnitude); + ~CVECone(); + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +class CVEAngleCone : public CVectorElement { + CRealElement* x4_angleXConstant; + CRealElement* x8_angleYConstant; + CRealElement* xc_angleXRange; + CRealElement* x10_angleYRange; + CRealElement* x14_magnitude; + +public: + CVEAngleCone(CRealElement* angleXConstant, CRealElement* angleYConstant, + CRealElement* angleXRange, CRealElement* angleYRange, CRealElement* magnitude); + ~CVEAngleCone(); + bool GetValue(int frame, CVector3f& valOut) const override; +}; + +#endif // _CVECTORELEMENT diff --git a/include/Kyoto/Particles/CWarp.hpp b/include/Kyoto/Particles/CWarp.hpp new file mode 100644 index 0000000..f660066 --- /dev/null +++ b/include/Kyoto/Particles/CWarp.hpp @@ -0,0 +1,24 @@ +#ifndef _CWARP +#define _CWARP + +#include "Kyoto/SObjectTag.hpp" + +#include "rstl/vector.hpp" + +class CParticle; +class CColor; +class CVector3f; + +class CWarp { +public: + virtual ~CWarp(); + virtual bool UpdateWarp() = 0; + virtual void ModifyParticles(int particleCount, int stripe, int*, CVector3f* particlePos, + CVector3f* particlePrevPos, CVector3f* particleVelocity, + CColor* color, float* lineLengthOrSize, float* lineWidthOrRota) = 0; + virtual void Activate(bool) = 0; + virtual bool IsActivated() = 0; + virtual FourCC Get4CharID() = 0; +}; + +#endif // _CWARP diff --git a/include/Kyoto/Particles/IElement.hpp b/include/Kyoto/Particles/IElement.hpp new file mode 100644 index 0000000..95ddcfa --- /dev/null +++ b/include/Kyoto/Particles/IElement.hpp @@ -0,0 +1,73 @@ +#ifndef _IELEMENT +#define _IELEMENT + +#include "types.h" + +#include "Kyoto/TToken.hpp" + +class CColor; +class CTexture; +class CVector3f; + +class IElement { +public: + virtual ~IElement(){}; + + // -> CFrameDelayedKiller + void* operator new(size_t sz, const char*, const char*); + void* operator new(size_t sz) { return operator new(sz, "??(??)", nullptr); } + void operator delete(void* ptr, size_t sz); +}; + +class CRealElement : public IElement { +public: + virtual bool GetValue(int frame, float& valOut) const = 0; + virtual bool IsConstant() const { return false; } +}; + +class CIntElement : public IElement { +public: + ~CIntElement() override{}; + virtual bool GetValue(int frame, int& valOut) const = 0; +}; + +class CVectorElement : public IElement { +public: + virtual bool GetValue(int frame, CVector3f& valOut) const = 0; + virtual bool IsFastConstant() const { return false; } +}; + +class CModVectorElement : public IElement { +public: + virtual bool GetValue(int frame, CVector3f& pVel, CVector3f& pPos) const = 0; +}; + +class CColorElement : public IElement { +public: + virtual bool GetValue(int frame, CColor& colorOut) const = 0; +}; + +class CEmitterElement : public IElement { +public: + virtual bool GetValue(int frame, CVector3f& pPos, CVector3f& pVel) const = 0; +}; + +struct SUVElementSet { + float xMin, yMin, xMax, yMax; + + // SUVElementSet() : xMin(0.f), yMin(1.f), xMax(0.f), yMax(1.f) {} + //SUVElementSet(float xMin, float yMin, float xMax, float yMax) + //: xMin(xMin), yMin(yMin), xMax(xMax), yMax(yMax) {} + // SUVElementSet(const SUVElementSet& other) + // : xMin(other.xMin), yMin(other.yMin), xMax(other.xMax), yMax(other.yMax) {} +}; + +class CUVElement : public IElement { +public: + virtual TLockedToken< CTexture > GetValueTexture(int frame) const = 0; + virtual void GetValueUV(int frame, SUVElementSet& valOut) const = 0; + virtual bool HasConstantTexture() const = 0; + virtual bool HasConstantUV() const = 0; +}; + +#endif // _IELEMENT diff --git a/include/Kyoto/RumbleFxTable.hpp b/include/Kyoto/RumbleFxTable.hpp new file mode 100644 index 0000000..74fd47b --- /dev/null +++ b/include/Kyoto/RumbleFxTable.hpp @@ -0,0 +1,8 @@ +#ifndef _RUMBLEFXTABLE +#define _RUMBLEFXTABLE + +#include "Kyoto/Input/CRumbleVoice.hpp" + +extern const SAdsrData skRumbleFxTable[]; + +#endif // _RUMBLEFXTABLE diff --git a/include/Kyoto/Streams/CMemoryInStream.hpp b/include/Kyoto/Streams/CMemoryInStream.hpp new file mode 100644 index 0000000..aabdcaf --- /dev/null +++ b/include/Kyoto/Streams/CMemoryInStream.hpp @@ -0,0 +1,19 @@ +#ifndef _CMEMORYINSTREAM +#define _CMEMORYINSTREAM + +#include "Kyoto/Streams/CInputStream.hpp" + +class CMemoryInStream : public CInputStream { +public: + enum EOwnerShip { + kOS_Owned, + kOS_NotOwned, + }; + + CMemoryInStream(const void* ptr, unsigned long len); + CMemoryInStream(const void* ptr, unsigned long len, EOwnerShip ownership); + virtual ~CMemoryInStream() override {} + virtual size_t Read(void* dest, size_t len) override; +}; + +#endif // _CMEMORYINSTREAM diff --git a/include/Kyoto/Streams/CMemoryStreamOut.hpp b/include/Kyoto/Streams/CMemoryStreamOut.hpp new file mode 100644 index 0000000..0224870 --- /dev/null +++ b/include/Kyoto/Streams/CMemoryStreamOut.hpp @@ -0,0 +1,26 @@ +#ifndef _CMEMORYSTREAMOUT +#define _CMEMORYSTREAMOUT + +#include "Kyoto/Streams/COutputStream.hpp" + +class CMemoryStreamOut : public COutputStream { +public: + enum EOwnerShip { + kOS_Owned, + kOS_NotOwned, + }; + + CMemoryStreamOut(void* buffer, size_t len, EOwnerShip ownerShip = kOS_NotOwned, + int blockLen = 4096); + virtual ~CMemoryStreamOut(); + + void Write(const void* ptr, size_t len); + +private: + void* mOutPtr; + size_t mOutLength; + size_t mCurrentPosition; + bool mBufferOwned; +}; + +#endif // _CMEMORYSTREAMOUT diff --git a/include/Kyoto/Streams/CZipInputStream.hpp b/include/Kyoto/Streams/CZipInputStream.hpp new file mode 100644 index 0000000..416abfd --- /dev/null +++ b/include/Kyoto/Streams/CZipInputStream.hpp @@ -0,0 +1,25 @@ +#ifndef _CZIPINPUTSTREAM +#define _CZIPINPUTSTREAM + +#include "types.h" + +#include "Kyoto/Streams/CInputStream.hpp" + +#include "rstl/auto_ptr.hpp" +#include "rstl/single_ptr.hpp" + +#include "zlib/zlib.h" + +class CZipInputStream : public CInputStream { +public: + CZipInputStream(rstl::auto_ptr< CInputStream > in); + ~CZipInputStream() override; + size_t Read(void* dest, size_t len) override; + +private: + rstl::single_ptr mCompBuf; + rstl::auto_ptr< CInputStream > mStream; + rstl::single_ptr mZStream; +}; + +#endif // _CZIPINPUTSTREAM diff --git a/include/Kyoto/Streams/CZipOutputStream.hpp b/include/Kyoto/Streams/CZipOutputStream.hpp new file mode 100644 index 0000000..42b15c6 --- /dev/null +++ b/include/Kyoto/Streams/CZipOutputStream.hpp @@ -0,0 +1,29 @@ +#ifndef _CZIPOUTPUTSTREAM +#define _CZIPOUTPUTSTREAM + + +#include "Kyoto/Streams/COutputStream.hpp" + +#include "rstl/auto_ptr.hpp" + +#include "zlib/zlib.h" + +class CZipOutputStream : public COutputStream { +public: + CZipOutputStream(COutputStream* out, int level); + ~CZipOutputStream(); + + void Finish(); + bool Process(bool v); + void Write(const void* ptr, size_t len); + + int GetCompressedBytesWritten() { return mCompressedBytesWritten; } +private: + COutputStream* mOutput; + int mCompressedBytesWritten; + rstl::auto_ptr mZStream; + int mUnk; +}; + + +#endif // _CZIPOUTPUTSTREAM diff --git a/include/Kyoto/Streams/CZipSupport.hpp b/include/Kyoto/Streams/CZipSupport.hpp new file mode 100644 index 0000000..e419f6a --- /dev/null +++ b/include/Kyoto/Streams/CZipSupport.hpp @@ -0,0 +1,13 @@ +#ifndef _CZIPSUPPORT +#define _CZIPSUPPORT + +#include "rstl/single_ptr.hpp" +#include + +class CZipSupport { +public: + static void * Alloc(void* ptr, uint w1, uint w2); + static void Free(void*, void*); +}; + +#endif // _CZIPSUPPORT diff --git a/include/Kyoto/Streams/StreamSupport.hpp b/include/Kyoto/Streams/StreamSupport.hpp new file mode 100644 index 0000000..ee85e03 --- /dev/null +++ b/include/Kyoto/Streams/StreamSupport.hpp @@ -0,0 +1,9 @@ +#ifndef _STREAMSUPPORT +#define _STREAMSUPPORT +#include + +static inline uint min_containing_bytes(uint bits) { + return (bits / 8) + ((bits % 8) != 0); +} + +#endif // _STREAMSUPPORT diff --git a/include/Kyoto/TAverage.hpp b/include/Kyoto/TAverage.hpp new file mode 100644 index 0000000..a196967 --- /dev/null +++ b/include/Kyoto/TAverage.hpp @@ -0,0 +1,42 @@ +#ifndef _TAVERAGE +#define _TAVERAGE + +#include "types.h" + +#include "rstl/optional_object.hpp" +#include "rstl/vector.hpp" + +template < typename T > +T GetAverageValue(const T* ptr, int count); // TODO + +template < typename T > +class TAverage : rstl::vector< T > { +public: + TAverage() {} + TAverage(int capacity, const T& value); + + void AddValue(const T& value); + rstl::optional_object< T > GetAverage() const { + if (this->empty()) { + return rstl::optional_object_null(); + } else { + return GetAverageValue(this->data(), this->size()); + } + } +}; + +template < typename T > +TAverage< T >::TAverage(int capacity, const T& value) { + this->resize(capacity, value); +} + +template < typename T > +void TAverage< T >::AddValue(const T& value) { + if (this->size() == this->capacity()) { + // TODO ? + this->x4_count -= 1; + } + this->insert(this->begin(), value); +} + +#endif // _TAVERAGE diff --git a/include/Kyoto/TOneStatic.hpp b/include/Kyoto/TOneStatic.hpp new file mode 100644 index 0000000..54e6758 --- /dev/null +++ b/include/Kyoto/TOneStatic.hpp @@ -0,0 +1,36 @@ +#ifndef _TONESTATIC +#define _TONESTATIC + +#include "types.h" +#include "stdio.h" + +template < typename T > +class TOneStatic { +public: + void* operator new(size_t sz, const char*, const char*); /* { + ReferenceCount()++; + return GetAllocSpace(); + }*/ + void* operator new(size_t sz) { return operator new(sz, "??(??)", nullptr); } + void operator delete(void* ptr); + +private: + static void* GetAllocSpace() { + static uchar sAllocSpace[sizeof(T)]; + return &sAllocSpace; + } + static uint& ReferenceCount(); +}; + +template < typename T > +uint& TOneStatic< T >::ReferenceCount() { + static uint sReferenceCount = 0; + return sReferenceCount; +} + +template < typename T > +void TOneStatic< T >::operator delete(void* ptr) { + ReferenceCount()--; +} + +#endif // _TONESTATIC diff --git a/include/Kyoto/TReservedAverage.hpp b/include/Kyoto/TReservedAverage.hpp new file mode 100644 index 0000000..cfb2d1c --- /dev/null +++ b/include/Kyoto/TReservedAverage.hpp @@ -0,0 +1,28 @@ +#ifndef _TRESERVEDAVERAGE +#define _TRESERVEDAVERAGE + +#include "types.h" + +#include "Kyoto/TAverage.hpp" + +#include "rstl/optional_object.hpp" +#include "rstl/reserved_vector.hpp" + +template < typename T, int N > +class TReservedAverage : public rstl::reserved_vector< T, N > { +public: + TReservedAverage() {} + TReservedAverage(const T& value) { + // resize(value, N); TODO + } + void AddValue(const T& value) { + this->push_back(value); + for (int i = this->size() - 1; i > 0; --i) { + this->operator[](i) = this->operator[](i - 1); + } + this->operator[](0) = value; + } + rstl::optional_object< T > GetAverage() const; +}; + +#endif // _TRESERVEDAVERAGE diff --git a/include/Kyoto/TToken.hpp b/include/Kyoto/TToken.hpp new file mode 100644 index 0000000..2623046 --- /dev/null +++ b/include/Kyoto/TToken.hpp @@ -0,0 +1,86 @@ +#ifndef _TTOKEN +#define _TTOKEN + +#include "types.h" + +#include "Kyoto/CSimplePool.hpp" +#include "Kyoto/CToken.hpp" +#include "Kyoto/IObj.hpp" + +#include "rstl/auto_ptr.hpp" + +template < typename T > +class TToken : public CToken { +public: + TToken() {} + TToken(const CToken& token) : CToken(token) {} + TToken(T* obj) : CToken(TObjOwnerDerivedFromIObj< T >::GetNewDerivedObject(obj).release()) {} + TToken(const rstl::auto_ptr< T >& obj) : CToken(GetIObjObjectFor(obj).release()) {} + + T* GetT() { return reinterpret_cast< T* >(CToken::GetObj()->GetContents()); } + T* operator*() { return GetT(); } + T* operator->() { return GetT(); } + + static rstl::auto_ptr< TObjOwnerDerivedFromIObj< T > > + GetIObjObjectFor(const rstl::auto_ptr< T >& obj) { + return TObjOwnerDerivedFromIObj< T >::GetNewDerivedObject(obj); + } + + TToken< T > NonConstCopy() const { return *const_cast< TToken< T >* >(this); } +}; + +template < typename T > +class TCachedToken : public TToken< T > { +public: + TCachedToken() {} + TCachedToken(const CToken& token) : TToken< T >(token), x8_item(nullptr) {} + + T* operator*() { return x8_item; } + + bool IsLoaded() { + if (x8_item != nullptr) { + return true; + } + if (CToken::HasLock() && CToken::IsLoaded()) { + x8_item = TToken< T >::GetT(); + return true; + } else { + return false; + } + } + + void Unlock() { + x8_item = nullptr; + TToken< T >::Unlock(); + } + +private: + T* x8_item; +}; + +template < typename T > +class TLockedToken { +public: + TLockedToken() {} + TLockedToken(const CToken& token) : x0_token(token), x8_item(*x0_token) {} + TLockedToken(const TLockedToken< T >& token) : x0_token(token), x8_item(*token) { + x0_token.Lock(); + } + + TLockedToken& operator=(const TLockedToken< T >& token) { + x0_token = token; + x8_item = *token; + return *this; + } + + operator const TToken< T >&() const { return x0_token; } + T* operator*() const { return x8_item; } + T* operator->() const { return x8_item; } + bool IsLoaded() const { return x0_token.IsLoaded(); } + +private: + TToken< T > x0_token; + T* x8_item; +}; + +#endif // _TTOKEN diff --git a/include/Kyoto/Text/CBlockInstruction.hpp b/include/Kyoto/Text/CBlockInstruction.hpp new file mode 100644 index 0000000..8ff4146 --- /dev/null +++ b/include/Kyoto/Text/CBlockInstruction.hpp @@ -0,0 +1,59 @@ +#ifndef _CBLOCKINSTRUCTION +#define _CBLOCKINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" +#include "Kyoto/Text/TextCommon.hpp" + +class CBlockInstruction : public CInstruction { +public: + CBlockInstruction(int offX, int offY, int extX, int extY, ETextDirection dir, EJustification just, + EVerticalJustification vjust) + : x4_offsetX(offX) + , x8_offsetY(offY) + , xc_blockExtentX(extX) + , x10_blockExtentY(extY) + , x14_dir(dir) + , x18_justification(just) + , x1c_vertJustification(vjust) + , x20_largestMonoW(0) + , x24_largestMonoH(0) + , x28_largestBaseline(0) + , x2c_lineX(0) + , x30_lineY(0) + , x34_lineCount(0) {} + + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void SetupPositionLTR(CFontRenderState& state) const; + void TestLargestFont(int monoW, int monoH, int baseline); + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + + int GetOutputX() const { return x4_offsetX; } + int GetOutputY() const { return x8_offsetY; } + int GetOutputWidth() const { return xc_blockExtentX; } + int GetOutputHeight() const { return x10_blockExtentY; } + ETextDirection GetTextDirection() const { return x14_dir; } + EJustification GetJustification() const { return x18_justification; } + EVerticalJustification GetVerticalJustification() const { return x1c_vertJustification; } + int GetLargestFontWidth() const { return x20_largestMonoW; } + int GetLargestFontHeight() const { return x24_largestMonoH; } + int GetLineX() const { return x2c_lineX; } + int GetLineY() const { return x30_lineY; } + int GetLines() const { return x34_lineCount; } + +private: + int x4_offsetX; + int x8_offsetY; + int xc_blockExtentX; + int x10_blockExtentY; + ETextDirection x14_dir; + EJustification x18_justification; + EVerticalJustification x1c_vertJustification; + int x20_largestMonoW; + int x24_largestMonoH; + int x28_largestBaseline; + int x2c_lineX; + int x30_lineY; + int x34_lineCount; +}; + +#endif // _CBLOCKINSTRUCTION diff --git a/include/Kyoto/Text/CColorInstruction.hpp b/include/Kyoto/Text/CColorInstruction.hpp new file mode 100644 index 0000000..710a930 --- /dev/null +++ b/include/Kyoto/Text/CColorInstruction.hpp @@ -0,0 +1,21 @@ +#ifndef _CCOLORINSTRUCTION +#define _CCOLORINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +#include "Kyoto/Text/CTextColor.hpp" +#include "Kyoto/Text/TextCommon.hpp" + +class CColorInstruction : CInstruction { +public: + CColorInstruction(EColorType type, const CTextColor& color) : x4_type(type), x8_color(color) {} + + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + +private: + EColorType x4_type; + CTextColor x8_color; +}; + +#endif // _CCOLORINSTRUCTION diff --git a/include/Kyoto/Text/CColorOverrideInstruction.hpp b/include/Kyoto/Text/CColorOverrideInstruction.hpp new file mode 100644 index 0000000..63abe7c --- /dev/null +++ b/include/Kyoto/Text/CColorOverrideInstruction.hpp @@ -0,0 +1,19 @@ +#ifndef _CCOLOROVERRIDEINSTRUCTION +#define _CCOLOROVERRIDEINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" +#include "Kyoto/Text/CTextColor.hpp" + +class CColorOverrideInstruction : public CInstruction { +public: + explicit CColorOverrideInstruction(int idx, const CTextColor& color) + : x4_idx(idx), x8_color(color) {} + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + +private: + int x4_idx; + CTextColor x8_color; +}; + +#endif // _CCOLOROVERRIDEINSTRUCTION diff --git a/include/Kyoto/Text/CDrawStringOptions.hpp b/include/Kyoto/Text/CDrawStringOptions.hpp new file mode 100644 index 0000000..40e2565 --- /dev/null +++ b/include/Kyoto/Text/CDrawStringOptions.hpp @@ -0,0 +1,20 @@ +#ifndef _CDRAWSTRINGOPTIONS +#define _CDRAWSTRINGOPTIONS + +#include "Kyoto/Graphics/CColor.hpp" +#include "rstl/reserved_vector.hpp" +#include "Kyoto/Text/TextCommon.hpp" + +class CDrawStringOptions { +public: + CDrawStringOptions(); + + void SetTextDirection(ETextDirection dir) { x0_direction = dir; } + ETextDirection GetTextDirection() const { return x0_direction; } + void SetPaletteEntry(int idx, uint color) { x4_colors[idx] = color; } +private: + ETextDirection x0_direction; + rstl::reserved_vector x4_colors; +}; + +#endif // _CDRAWSTRINGOPTIONS diff --git a/include/Kyoto/Text/CFont.hpp b/include/Kyoto/Text/CFont.hpp new file mode 100644 index 0000000..6a996be --- /dev/null +++ b/include/Kyoto/Text/CFont.hpp @@ -0,0 +1,17 @@ +#ifndef _CFONT +#define _CFONT + +#include "Kyoto/Graphics/CColor.hpp" + +class CFont { +public: + CFont(float scale); + ~CFont(); + int CharWidth(char) const; + void DrawString(const char* str, long x, long y, const CColor& col) const; +private: + int mFontSize; + float mScale; +}; + +#endif // _CFONT diff --git a/include/Kyoto/Text/CFontImageDef.hpp b/include/Kyoto/Text/CFontImageDef.hpp new file mode 100644 index 0000000..40a89c9 --- /dev/null +++ b/include/Kyoto/Text/CFontImageDef.hpp @@ -0,0 +1,31 @@ +#ifndef _CFONTIMAGEDEF +#define _CFONTIMAGEDEF + +#include +#include +#include +#include + +class CTexture; +class CVector2f; +class CFontImageDef { +public: + CFontImageDef(const TToken< CTexture >& texture, const CVector2f& cropFactor); + CFontImageDef(const rstl::vector< TToken< CTexture > >& texture, float fps, + const CVector2f& cropFactor); + + bool IsLoaded() const; + // inline short GetWidth() { } + int GetHeight() { + TToken< CTexture > tex = mTextures[0]; + return tex.GetT()->GetHeight() * mCropFactor.GetY(); + } + int CalculateBaseline(); + +private: + float mFPS; + rstl::vector< TToken< CTexture > > mTextures; + CVector2f mCropFactor; +}; + +#endif // _CFONTIMAGEDEF diff --git a/include/Kyoto/Text/CFontRenderState.hpp b/include/Kyoto/Text/CFontRenderState.hpp new file mode 100644 index 0000000..68ae2e3 --- /dev/null +++ b/include/Kyoto/Text/CFontRenderState.hpp @@ -0,0 +1,51 @@ +#ifndef _CFONTRENDERSTATE +#define _CFONTRENDERSTATE + +#include "Kyoto/Text/CDrawStringOptions.hpp" +#include "Kyoto/Text/CSaveableState.hpp" +#include "Kyoto/Text/TextCommon.hpp" + +class CBlockInstruction; +class CLineInstruction; + +class CFontRenderState { +public: + uint ConvertToTextureSpace(const CTextColor& color) const; + void PushState(); + void PopState(); + void SetColor(EColorType type, const CTextColor& color); + void RefreshPalette(); + CDrawStringOptions& GetOptions() { return x0_state.GetOptions(); } + TToken< CRasterFont >& GetFont() { return x0_state.GetFont(); } + rstl::vector< CTextColor >& GetColors() { return x0_state.GetColors(); } + rstl::vector< bool >& GetOverride() { return x0_state.GetOverride(); } + void SetLineSpacing(float spacing) { x0_state.SetLineSpacing(spacing); } + void SetExtraLineSpace(int spacing) { x0_state.SetLineExtraSpace(spacing); } + const CBlockInstruction* GetBlock() const { return x88_curBlock; } + void SetBlock(const CBlockInstruction* block) { + x88_curBlock = const_cast< CBlockInstruction* >(block); + } + void SetX(int x) { xd4_curX = x; } + int GetX() const { return xd4_curX; } + void SetY(int y) { xd8_curY = y; } + int GetY() const { return xd8_curY; } + const CLineInstruction* GetLine() const { return xdc_currentLineInst; } + bool IsFirstWordOnLine() const { return x108_lineInitialized; } + void SetFirstWordOnLine(bool v) { x108_lineInitialized = v; } + +private: + CSaveableState x0_state; + CBlockInstruction* x88_curBlock; + CDrawStringOptions x8c_drawOpts; + int xd4_curX; + int xd8_curY; + const CLineInstruction* xdc_currentLineInst; + uint xe0_; + uint xe4_; + rstl::vector< uint > xe8_; + rstl::vector< uchar > xf8_; + bool x108_lineInitialized; + rstl::list< CSaveableState > x10c_pushedStates; +}; + +#endif // _CFONTRENDERSTATE diff --git a/include/Kyoto/Text/CInstruction.hpp b/include/Kyoto/Text/CInstruction.hpp new file mode 100644 index 0000000..e52f880 --- /dev/null +++ b/include/Kyoto/Text/CInstruction.hpp @@ -0,0 +1,22 @@ +#ifndef _CINSTRUCTION +#define _CINSTRUCTION + +#include "types.h" + +#include "Kyoto/CToken.hpp" + +#include "rstl/vector.hpp" + +class CFontRenderState; +class CTextRenderBuffer; + +class CInstruction { +public: + virtual ~CInstruction() {} + virtual void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const = 0; + virtual void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const {} + virtual void GetAssets(rstl::vector< CToken >& assetsOut) const {} + virtual uint GetAssetCount() const { return 0; } +}; + +#endif // _CINSTRUCTION diff --git a/include/Kyoto/Text/CLineExtraSpaceInstruction.hpp b/include/Kyoto/Text/CLineExtraSpaceInstruction.hpp new file mode 100644 index 0000000..3b14633 --- /dev/null +++ b/include/Kyoto/Text/CLineExtraSpaceInstruction.hpp @@ -0,0 +1,17 @@ +#ifndef _CLINEEXTRASPACINGINSTRUCTION +#define _CLINEEXTRASPACINGINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +class CLineExtraSpaceInstruction : public CInstruction { +public: + CLineExtraSpaceInstruction(int spacing) : x4_spacing(spacing) {} + ~CLineExtraSpaceInstruction() {} + + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; +private: + int x4_spacing; +}; + +#endif // _CLINEEXTRASPACINGINSTRUCTION diff --git a/include/Kyoto/Text/CLineSpacingInstruction.hpp b/include/Kyoto/Text/CLineSpacingInstruction.hpp new file mode 100644 index 0000000..c74f8ac --- /dev/null +++ b/include/Kyoto/Text/CLineSpacingInstruction.hpp @@ -0,0 +1,17 @@ +#ifndef _CLINESPACINGINSTRUCTION +#define _CLINESPACINGINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +class CLineSpacingInstruction : public CInstruction { +public: + CLineSpacingInstruction(float spacing) : x4_spacing(spacing) {} + ~CLineSpacingInstruction() {} + + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; +private: + float x4_spacing; +}; + +#endif // _CLINESPACINGINSTRUCTION diff --git a/include/Kyoto/Text/CPopStateInstruction.hpp b/include/Kyoto/Text/CPopStateInstruction.hpp new file mode 100644 index 0000000..faf97ec --- /dev/null +++ b/include/Kyoto/Text/CPopStateInstruction.hpp @@ -0,0 +1,16 @@ +#ifndef _CPOPSTATEINSTRUCTION +#define _CPOPSTATEINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +class CPopStateInstruction : public CInstruction { +public: + CPopStateInstruction() {} + ~CPopStateInstruction() {} + + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; +}; + + +#endif // _CPOPSTATEINSTRUCTION diff --git a/include/Kyoto/Text/CPushStateInstruction.hpp b/include/Kyoto/Text/CPushStateInstruction.hpp new file mode 100644 index 0000000..7c3b9b8 --- /dev/null +++ b/include/Kyoto/Text/CPushStateInstruction.hpp @@ -0,0 +1,16 @@ +#ifndef _CPUSHSTATEINSTRUCTION +#define _CPUSHSTATEINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +class CPushStateInstruction : public CInstruction { +public: + CPushStateInstruction() {} + ~CPushStateInstruction() {} + + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; +}; + + +#endif // _CPUSHSTATEINSTRUCTION diff --git a/include/Kyoto/Text/CRasterFont.hpp b/include/Kyoto/Text/CRasterFont.hpp new file mode 100644 index 0000000..b8cbaa2 --- /dev/null +++ b/include/Kyoto/Text/CRasterFont.hpp @@ -0,0 +1,125 @@ +#ifndef _CRASTERFONT +#define _CRASTERFONT + +#include "types.h" + +#include "Kyoto/TToken.hpp" +#include "rstl/optional_object.hpp" +#include "rstl/pair.hpp" +#include "rstl/vector.hpp" + +#include "string.h" + +class CTexture; +class CDrawStringOptions; +class IObjectStore; + +class CFontInfo { +public: + CFontInfo(bool a, bool b, int c, int fontSize, const char* name) + : x0_(a), x1_(b), x4_(c), x8_fontSize(fontSize) { + strcpy(xc_name, name); + } + +private: + bool x0_; + bool x1_; + int x4_; + int x8_fontSize; + char xc_name[64]; +}; + +class CKernPair { +public: + CKernPair(wchar_t first, wchar_t second, int howMuch) + : x0_first(first), x2_second(second), x4_howMuch(howMuch) {} + + wchar_t GetFirst() const { return x0_first; } + wchar_t GetSecond() const { return x2_second; } + int GetHowMuch() const { return x4_howMuch; } + +private: + wchar_t x0_first; + wchar_t x2_second; + int x4_howMuch; +}; + +class CGlyph { +public: + CGlyph(int a, int b, int c, float startU, float startV, float endU, float endV, int cellWidth, + int cellHeight, int baseline, int kernStart) + : x0_a(a) + , x2_b(b) + , x4_c(c) + , x8_startU(startU) + , xc_startV(startV) + , x10_endU(endU) + , x14_endV(endV) + , x18_cellWidth(cellWidth) + , x1a_cellHeight(cellHeight) + , x1c_baseline(baseline) + , x1e_kernStart(kernStart) + {} + + short GetA() const { return x0_a; } + short GetB() const { return x2_b; } + short GetC() const { return x4_c; } + float GetStartU() const { return x8_startU; } + float GetStartV() const { return xc_startV; } + float GetEndU() const { return x10_endU; } + float GetEndV() const { return x14_endV; } + short GetCellWidth() const { return x18_cellWidth; } + short GetCellHeight() const { return x1a_cellHeight; } + short GetBaseline() const { return x1c_baseline; } + short GetKernStart() const { return x1e_kernStart; } + //short GetLayer() const { return x20_layer; } + +private: + short x0_a; + short x2_b; + short x4_c; + float x8_startU; + float xc_startV; + float x10_endU; + float x14_endV; + short x18_cellWidth; + short x1a_cellHeight; + short x1c_baseline; + short x1e_kernStart; + //short x20_layer; +}; + +enum EFontMode { + kFM_None = -1, + kFM_OneLayer, + kFM_OneLayerOutline, + kFM_FourLayers, + kFM_TwoLayersOutline, + kFM_TwoLayers, +}; + +class CRasterFont { +public: + CRasterFont(CInputStream& in, IObjectStore* store); + ~CRasterFont(); + + EFontMode GetMode() const; + void GetSize(const CDrawStringOptions&, int&, int&, const wchar_t*, int) const; + void SetTexture(TToken< CTexture > token) { x80_texture = token; } + bool IsFinishedLoading(); + +private: + bool x0_initialized; + int x4_monoWidth; + int x8_monoHeight; + rstl::vector< rstl::pair< wchar_t, CGlyph > > xc_glyphs; + rstl::vector< CKernPair > x1c_kerning; + EFontMode x2c_mode; + rstl::optional_object< CFontInfo > x30_fontInfo; + rstl::optional_object< TToken< CTexture > > x80_texture; + int x8c_baseline; + int x90_lineMargin; +}; +CHECK_SIZEOF(CRasterFont, 0x94) + +#endif // _CRASTERFONT diff --git a/include/Kyoto/Text/CRemoveColorOverrideInstruction.hpp b/include/Kyoto/Text/CRemoveColorOverrideInstruction.hpp new file mode 100644 index 0000000..9e9da0f --- /dev/null +++ b/include/Kyoto/Text/CRemoveColorOverrideInstruction.hpp @@ -0,0 +1,16 @@ +#ifndef _CREMOVECOLOROVERRIDEINSTRUCTION +#define _CREMOVECOLOROVERRIDEINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +class CRemoveColorOverrideInstruction : public CInstruction { +public: + explicit CRemoveColorOverrideInstruction(int idx) : x4_idx(idx) {} + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + +private: + int x4_idx; +}; + +#endif // _CREMOVECOLOROVERRIDEINSTRUCTION diff --git a/include/Kyoto/Text/CSaveableState.hpp b/include/Kyoto/Text/CSaveableState.hpp new file mode 100644 index 0000000..2d58cbf --- /dev/null +++ b/include/Kyoto/Text/CSaveableState.hpp @@ -0,0 +1,36 @@ +#ifndef _CSAVEABLESTATE +#define _CSAVEABLESTATE + +#include "Kyoto/Text/CDrawStringOptions.hpp" +#include "Kyoto/Text/CRasterFont.hpp" +#include "Kyoto/Text/CTextColor.hpp" + +#include "rstl/optional_object.hpp" +#include "rstl/vector.hpp" + +class CSaveableState { +public: + CSaveableState(); + bool IsFinishedLoading(); + + CDrawStringOptions& GetOptions() { return x0_drawStringOptions; } + TToken& GetFont() { return *x48_font; } + rstl::vector& GetColors() { return x54_colors; } + rstl::vector& GetOverride() { return x64_colorOverrides; } + void SetLineSpacing(float spacing) { x74_lineSpacing = spacing; } + void SetLineExtraSpace(int spacing) { x78_extraLineSpacing = spacing; } + + +private: + CDrawStringOptions x0_drawStringOptions; + rstl::optional_object< TToken< CRasterFont > > x48_font; + rstl::vector< CTextColor > x54_colors; + rstl::vector x64_colorOverrides; + float x74_lineSpacing; + int x78_extraLineSpacing; + bool x7c_enableWordWrap; + EJustification x80_just; + EVerticalJustification x84_vjust; +}; + +#endif // _CSAVEABLESTATE diff --git a/include/Kyoto/Text/CStringTable.hpp b/include/Kyoto/Text/CStringTable.hpp new file mode 100644 index 0000000..deeead1 --- /dev/null +++ b/include/Kyoto/Text/CStringTable.hpp @@ -0,0 +1,22 @@ +#ifndef _CSTRINGTABLE +#define _CSTRINGTABLE + +#include "types.h" + +#include "rstl/single_ptr.hpp" + +#include "Kyoto/Streams/CInputStream.hpp" + +class CStringTable { + int x0_stringCount; + rstl::single_ptr< uchar > x4_data; + +public: + CStringTable(CInputStream& in); + const wchar_t* GetString(int idx) const; + int GetStringCount() const { return x0_stringCount; } +}; + +extern CStringTable* gpStringTable; + +#endif // _CSTRINGTABLE diff --git a/include/Kyoto/Text/CTextColor.hpp b/include/Kyoto/Text/CTextColor.hpp new file mode 100644 index 0000000..4c5ed2d --- /dev/null +++ b/include/Kyoto/Text/CTextColor.hpp @@ -0,0 +1,40 @@ +#ifndef _CTEXTCOLOR +#define _CTEXTCOLOR + +#include + +#ifdef __MWERKS__ +#pragma cpp_extensions on +#endif + +class CTextColor { +public: + CTextColor(uchar r, uchar g, uchar b, uchar a) : mR(r), mG(g), mB(b), mA(a) {} + + CTextColor(const CTextColor& other) : mR(other.mR), mG(other.mG), mB(other.mB), mA(other.mA) {} + + const CTextColor& operator=(const CTextColor& other) { + mR = other.mR; + mG = other.mG; + mB = other.mB; + mA = other.mA; + return *this; + } + +private: + union { + struct { + uchar mR; + uchar mG; + uchar mB; + uchar mA; + }; + uint mRgba; + }; +}; + +#ifdef __MWERKS__ +#pragma cpp_extensions off +#endif + +#endif // _CTEXTCOLOR diff --git a/include/Kyoto/Text/CTextExecuteBuffer.hpp b/include/Kyoto/Text/CTextExecuteBuffer.hpp new file mode 100644 index 0000000..222a69d --- /dev/null +++ b/include/Kyoto/Text/CTextExecuteBuffer.hpp @@ -0,0 +1,34 @@ +#ifndef _CTEXTEXECUTEBUFFER +#define _CTEXTEXECUTEBUFFER + +#include "rstl/list.hpp" +#include "rstl/rc_ptr.hpp" + +#include "Kyoto/Text/CSaveableState.hpp" + +class CInstruction; +class CBlockInstruction; +class CLineInstruction; + +class CTextExecuteBuffer { + typedef rstl::list< rstl::ncrc_ptr< CInstruction > > InstList; + +public: + CTextExecuteBuffer(); + +private: + InstList x0_instructions; + CSaveableState x18_; + CBlockInstruction* xa0_curBlock; + CLineInstruction* xa4_curLine; + InstList::const_iterator xa8_curWordIt; + int xac_curY; + int xb0_curX; + int xb4_curWordX; + int xb8_curWordY; + int xbc_spaceDistance; + bool xc0_imageBaseline; + rstl::list xc4_stateStack; +}; + +#endif // _CTEXTEXECUTEBUFFER diff --git a/include/Kyoto/Text/CTextParser.hpp b/include/Kyoto/Text/CTextParser.hpp new file mode 100644 index 0000000..0a1034c --- /dev/null +++ b/include/Kyoto/Text/CTextParser.hpp @@ -0,0 +1,32 @@ +#ifndef _CTEXTPARSER +#define _CTEXTPARSER + +#include +#include + +#include + +class IObjectStore; +class CTextExecuteBuffer; + +class CTextParser { +public: + CTextParser(IObjectStore& store); + void ParseText(CTextExecuteBuffer&, const wchar_t* str, int len); + uint GetAssetIdFromString(const rstl::string& str); + uint GetFont(const wchar_t* str, int len); + uint GetImage(const wchar_t* str, int len); + uint HandleUserTag(CTextExecuteBuffer& buffer, const wchar_t* str, int len); + void ParseTag(CTextExecuteBuffer&, const wchar_t* str, int len); + static bool BeginsWith(const wchar_t* str1, int len, const wchar_t* str2); + static bool Equals(const wchar_t* str1, int len, const wchar_t* str2); + static uint ParseInt(const wchar_t* str, int len, bool); + static uint FromHex(wchar_t c); + static uint GetColorValue(const wchar_t* str); + CTextColor ParseColor(const wchar_t* str, int len); + +private: + IObjectStore& mObjectStore; +}; + +#endif // _CTEXTPARSER diff --git a/include/Kyoto/Text/CTextRenderBuffer.hpp b/include/Kyoto/Text/CTextRenderBuffer.hpp new file mode 100644 index 0000000..843d596 --- /dev/null +++ b/include/Kyoto/Text/CTextRenderBuffer.hpp @@ -0,0 +1,12 @@ +#ifndef _CTEXTRENDERBUFFER +#define _CTEXTRENDERBUFFER + +#include "Kyoto/TToken.hpp" + +class CRasterFont; +class CTextRenderBuffer { +public: + void AddFontChange(const TToken< CRasterFont >& font); +}; + +#endif // _CTEXTRENDERBUFFER diff --git a/include/Kyoto/Text/CWordBreakTables.hpp b/include/Kyoto/Text/CWordBreakTables.hpp new file mode 100644 index 0000000..ff69aa5 --- /dev/null +++ b/include/Kyoto/Text/CWordBreakTables.hpp @@ -0,0 +1,13 @@ +#ifndef _CWORDBREAKTABLES +#define _CWORDBREAKTABLES + +#include + +class CWordBreakTables { +public: + static int GetBeginRank(wchar_t ch); + static int GetEndRank(wchar_t ch); +}; + + +#endif // _CWORDBREAKTABLES diff --git a/include/Kyoto/Text/CWordInstruction.hpp b/include/Kyoto/Text/CWordInstruction.hpp new file mode 100644 index 0000000..81856ea --- /dev/null +++ b/include/Kyoto/Text/CWordInstruction.hpp @@ -0,0 +1,13 @@ +#ifndef _CWORDINSTRUCTION +#define _CWORDINSTRUCTION + +#include "Kyoto/Text/CInstruction.hpp" + +class CWordInstruction : public CInstruction { +public: + void Invoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void PageInvoke(CFontRenderState& state, CTextRenderBuffer* buf) const; + void InvokeLTR(CFontRenderState& state) const; +}; + +#endif // _CWORDINSTRUCTION diff --git a/include/Kyoto/Text/TextCommon.hpp b/include/Kyoto/Text/TextCommon.hpp new file mode 100644 index 0000000..8c81e47 --- /dev/null +++ b/include/Kyoto/Text/TextCommon.hpp @@ -0,0 +1,39 @@ +#ifndef _TEXTCOMMON +#define _TEXTCOMMON + +enum EColorType { + +}; + +enum ETextDirection { + kTD_Horizontal, + kTD_Vertical, +}; + +enum EJustification { + kJustification_Left = 0, + kJustification_Center, + kJustification_Right, + kJustification_Full, + kJustification_NLeft, + kJustification_NCenter, + kJustification_NRight, + kJustification_LeftMono, + kJustification_CenterMono, + kJustification_RightMono, +}; + +enum EVerticalJustification { + kVerticalJustification_Top = 0, + kVerticalJustification_Center, + kVerticalJustification_Bottom, + kVerticalJustification_Full, + kVerticalJustification_NTop, + kVerticalJustification_NCenter, + kVerticalJustification_NBottom, + kVerticalJustification_TopMono, + kVerticalJustification_CenterMono, + kVerticalJustification_RightMono, +}; + +#endif // _TEXTCOMMON