Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions config/RSPE01_01/symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7230,11 +7230,11 @@ fn_8018E59C = .text:0x8018E59C; // type:function size:0x10
fn_8018E5AC = .text:0x8018E5AC; // type:function size:0x10
fn_8018E5BC = .text:0x8018E5BC; // type:function size:0xD4
fn_8018E690 = .text:0x8018E690; // type:function size:0x60
fn_8018E6F0 = .text:0x8018E6F0; // type:function size:0xC84
fn_8018F374 = .text:0x8018F374; // type:function size:0x132C
fn_801906A0 = .text:0x801906A0; // type:function size:0x5C
fn_801906FC = .text:0x801906FC; // type:function size:0x48
fn_80190744 = .text:0x80190744; // type:function size:0x50
saveData__11RPSysPlayerFRC14RPSysPlayerArg = .text:0x8018E6F0; // type:function size:0xC84
loadData__11RPSysPlayerFRC14RPSysPlayerArg = .text:0x8018F374; // type:function size:0x132C
setAvatar__11RPSysPlayerFScUs11RFLCreateID = .text:0x801906A0; // type:function size:0x5C
reset__11RPSysPlayerFv = .text:0x801906FC; // type:function size:0x48
__ct__11RPSysPlayerFv = .text:0x80190744; // type:function size:0x50
__dt__18IRPSysHostIOSocketFv = .text:0x80190794; // type:function size:0x40
__ct__18IRPSysHostIOSocketFv = .text:0x801907D4; // type:function size:0x10
__ct__18IRPSysHostIOSocketFPCce = .text:0x801907E4; // type:function size:0x5C
Expand Down
2 changes: 1 addition & 1 deletion configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ def MatchingFor(*versions):
Object(Matching, "Pack/RPSystem/RPPartySystemData.cpp"),
Object(Matching, "Pack/RPSystem/RPPartyPlayerData.cpp"),
Object(NonMatching, "Pack/RPSystem/RPSysPlayerMgr.cpp"),
Object(NonMatching, "Pack/RPSystem/RPSysPlayer.cpp"),
Object(Matching, "Pack/RPSystem/RPSysPlayer.cpp"),
],
},
{
Expand Down
92 changes: 87 additions & 5 deletions include/Pack/RPSystem/RPSysPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,114 @@
#define RP_SYSTEM_PLAYER_H
#include <Pack/types_pack.h>

#include <Pack/RPSingleton.h>
#include <Pack/RPSystem/RPPartyPlayerData.h>
#include <Pack/RPSystem/RPSportsPlayerData.h>

#include <RVLFaceLib.h>

//! @addtogroup rp_system
//! @{

/**
* @brief Player function parameter set
*/
struct RPSysPlayerArg {
//! Sports Pack player data for official database Miis
RPSportsPlayerData* pSportsPlayerData; // at 0x0
//! Sports Pack player data for temporary storage (guest/controller miis)
RPSportsPlayerData** ppTempSportsPlayerData; // at 0x4

//! Party Pack player data for official database Miis
RPPartyPlayerData* pPartyPlayerData; // at 0x8
//! Party Pack player data for temporary storage (guest/controller miis)
RPPartyPlayerData** ppTempPartyPlayerData; // at 0xC
};

/**
* @brief Player object
*/
class RPSysPlayer {
public:
/**
* @brief Constructor
*/
RPSysPlayer();

/**
* @brief Destructor
*/
~RPSysPlayer() {
// @bug Memory leak
#if defined(BUG_FIX)
delete mpSportsPlayerData;
mpSportsPlayerData = NULL;

delete mpPartyPlayerData;
mpPartyPlayerData = NULL;
#endif
}

/**
* @brief Resets the data to a default state
*/
void reset();

/**
* @brief Sets the Mii avatar associated with this player
*
* @param dataSrc Mii data source
* @param index Mii database index
* @param createID Mii create ID
*/
void setAvatar(s8 dataSrc, u16 index, RFLCreateID createID);

/**
* @brief Loads this player's data
*
* @param rArg Parameter set
*/
void loadData(const RPSysPlayerArg& rArg);

/**
* @brief Saves this player's data
*
* @param rArg Parameter set
*/
void saveData(const RPSysPlayerArg& rArg);

/**
* @brief Gets the RFL data source where this player avatar can be found
* @details If the data source was never configured, this value will be -1.
*/
s8 getDataSource() const {
return mDataSource;
}

/**
* @brief Gets the database index where this player avatar can be found
*/
u16 getIndex() const {
return mIndex;
}

private:
u8 mChannel; // at 0x0
s8 mDataSource; // at 0x1
u16 mIndex; // at 0x2
//! Controller channel
u8 mChannel; // at 0x0

//! Mii data source
s8 mDataSource; // at 0x1
//! Mii database index
u16 mIndex; // at 0x2
//! Mii create ID
RFLCreateID mCreateID; // at 0x4
// . . .

//! Player data list index
s32 mPlayerDataIndex; // at 0xC

//! Sports Pack player data
RPSportsPlayerData* mpSportsPlayerData; // at 0x10
//! Party Pack player datya
RPPartyPlayerData* mpPartyPlayerData; // at 0x14
};

//! @}
Expand Down
179 changes: 179 additions & 0 deletions src/Pack/RPSystem/RPSysPlayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#include <Pack/RPSystem.h>

#include <RVLFaceLib.h>

namespace {

/**
* @brief Tests whether two given RFL create IDs are equivalent
*
* @param rLhs Left-hand side ID
* @param rRhs Right-hand side ID
*/
bool IsSameCreateID(const RFLCreateID& rLhs, const RFLCreateID& rRhs) {
for (u32 i = 0; i < RFL_CREATEID_LEN; i++) {
if (rLhs.data[i] != rRhs.data[i]) {
return false;
}
}

return true;
}

} // namespace

/**
* @brief Constructor
*/
RPSysPlayer::RPSysPlayer() : mpSportsPlayerData(NULL), mpPartyPlayerData(NULL) {
#if defined(PACK_SPORTS)
mpSportsPlayerData = new RPSportsPlayerData();
#elif defined(PACK_PARTY)
mpPartyPlayerData = new RPPartyPlayerData();
#endif
}

/**
* @brief Resets the data to a default state
*/
void RPSysPlayer::reset() {
mChannel = WPAD_CHAN0;
mDataSource = -1;
mIndex = -1;
mPlayerDataIndex = -1;

for (int i = 0; i < RFL_CREATEID_LEN; i++) {
mCreateID.data[i] = 0;
}

#if defined(PACK_SPORTS)
mpSportsPlayerData->reset();
#elif defined(PACK_PARTY)
mpPartyPlayerData->reset();
#endif
}

/**
* @brief Sets the Mii avatar associated with this player
*
* @param dataSrc Mii data source
* @param index Mii database index
* @param createID Mii create ID
*/
void RPSysPlayer::setAvatar(s8 dataSrc, u16 index, RFLCreateID createID) {
mDataSource = dataSrc;
mIndex = index;
mCreateID = createID;
}

/**
* @brief Loads this player's data
*
* @param rArg Parameter set
*/
void RPSysPlayer::loadData(const RPSysPlayerArg& rArg) {
mPlayerDataIndex = mIndex;

if (mDataSource == RFLDataSource_Official && mIndex < RFL_DB_CHAR_MAX) {
RPSysSaveDataMgr* pSaveDataMgr = RP_GET_INSTANCE(RPSysSaveDataMgr);

if (mpSportsPlayerData != NULL) {
*mpSportsPlayerData =
pSaveDataMgr->getSportsPlayerData(mPlayerDataIndex);
}

if (mpPartyPlayerData != NULL) {
*mpPartyPlayerData =
pSaveDataMgr->getPartyPlayerData(mPlayerDataIndex);
}

} else if (mDataSource == RFLDataSource_Default &&
mIndex < RFL_DEFAULT_CHAR_MAX) {

if (mpSportsPlayerData != NULL && rArg.pSportsPlayerData != NULL) {
*mpSportsPlayerData = rArg.pSportsPlayerData[mPlayerDataIndex];
}

if (mpPartyPlayerData != NULL && rArg.pPartyPlayerData != NULL) {
*mpPartyPlayerData = rArg.pPartyPlayerData[mPlayerDataIndex];
}

} else if (mDataSource >= RFLDataSource_Controller1 &&
mDataSource <= RFLDataSource_Controller4 &&
mIndex < RFL_CTRL_CHAR_MAX) {

u32 ctrlIndex = mDataSource - RFLDataSource_Controller1;

if (mpSportsPlayerData != NULL && rArg.ppTempSportsPlayerData != NULL) {
*mpSportsPlayerData =
rArg.ppTempSportsPlayerData[ctrlIndex][mPlayerDataIndex];
}

if (mpPartyPlayerData != NULL && rArg.ppTempPartyPlayerData != NULL) {
*mpPartyPlayerData =
rArg.ppTempPartyPlayerData[ctrlIndex][mPlayerDataIndex];
}
}

RFLCreateID expected;
mpSportsPlayerData->getCreateID(&expected);

if (!IsSameCreateID(mCreateID, expected)) {
mpSportsPlayerData->reset();
mpSportsPlayerData->setCreateID(&mCreateID);
}
}

/**
* @brief Saves this player's data
*
* @param rArg Parameter set
*/
void RPSysPlayer::saveData(const RPSysPlayerArg& rArg) {
if (mPlayerDataIndex < 0) {
return;
}

if (mDataSource == RFLDataSource_Official &&
mPlayerDataIndex < RFL_DB_CHAR_MAX) {

RPSysSaveDataMgr* pSaveDataMgr = RP_GET_INSTANCE(RPSysSaveDataMgr);

if (mpSportsPlayerData != NULL) {
pSaveDataMgr->setSportsPlayerData(*mpSportsPlayerData,
mPlayerDataIndex);
}

if (mpPartyPlayerData != NULL) {
pSaveDataMgr->setPartyPlayerData(*mpPartyPlayerData,
mPlayerDataIndex);
}

} else if (mDataSource == RFLDataSource_Default &&
mPlayerDataIndex < RFL_DEFAULT_CHAR_MAX) {

if (mpSportsPlayerData != NULL && rArg.pSportsPlayerData != NULL) {
rArg.pSportsPlayerData[mPlayerDataIndex] = *mpSportsPlayerData;
}

if (mpPartyPlayerData != NULL && rArg.pPartyPlayerData != NULL) {
rArg.pPartyPlayerData[mPlayerDataIndex] = *mpPartyPlayerData;
}

} else if (mDataSource >= RFLDataSource_Controller1 &&
mDataSource <= RFLDataSource_Controller4 &&
mPlayerDataIndex < RFL_CTRL_CHAR_MAX) {

u32 ctrlIndex = mDataSource - RFLDataSource_Controller1;

if (mpSportsPlayerData != NULL && rArg.ppTempSportsPlayerData != NULL) {
rArg.ppTempSportsPlayerData[ctrlIndex][mPlayerDataIndex] =
*mpSportsPlayerData;
}

if (mpPartyPlayerData != NULL && rArg.ppTempPartyPlayerData != NULL) {
rArg.ppTempPartyPlayerData[ctrlIndex][mPlayerDataIndex] =
*mpPartyPlayerData;
}
}
}
Loading