refactor: add platform interfaces, move GetPrimaryPad to Input, gut Profile stubs

This commit is contained in:
MatthewBeshay
2026-03-31 20:05:59 +11:00
parent adb3adfb8a
commit 9e207250cb
41 changed files with 1026 additions and 600 deletions
+48 -120
View File
@@ -1,5 +1,6 @@
#include "4J_Profile.h"
#include "../4J.Common/4J_ProfileConstants.h"
#include "../4J.Input/4J_Input.h"
#include <cstdio>
#include <cstring>
@@ -45,7 +46,6 @@ void* s_profileData[XUSER_MAX_COUNT] = {};
C_4JProfile::PROFILESETTINGS s_dashboardSettings[XUSER_MAX_COUNT] = {};
char s_gamertags[XUSER_MAX_COUNT][16] = {};
std::wstring s_displayNames[XUSER_MAX_COUNT];
int s_primaryPad = 0;
int s_lockedProfile = 0;
bool s_profileIsFullVersion = true;
int (*s_defaultOptionsCallback)(void*, C_4JProfile::PROFILESETTINGS*,
@@ -102,14 +102,9 @@ void initialiseDefaultGameSettings(ProfileGameSettings* gameSettings) {
}
} // namespace
void C_4JProfile::Initialise(std::uint32_t dwTitleID, std::uint32_t dwOfferID,
unsigned short usProfileVersion,
unsigned int uiProfileValuesC,
unsigned int uiProfileSettingsC,
std::uint32_t* pdwProfileSettingsA,
int iGameDefinedDataSizeX4,
unsigned int* puiGameDefinedDataChangedBitmask) {
s_primaryPad = 0;
void C_4JProfile::Initialise(std::uint32_t, std::uint32_t, unsigned short,
unsigned int, unsigned int, std::uint32_t*,
int iGameDefinedDataSizeX4, unsigned int*) {
s_lockedProfile = 0;
std::memset(s_dashboardSettings, 0, sizeof(s_dashboardSettings));
@@ -122,46 +117,28 @@ void C_4JProfile::Initialise(std::uint32_t dwTitleID, std::uint32_t dwOfferID,
ensureFakeIdentity(i);
}
}
void C_4JProfile::SetTrialTextStringTable(CXuiStringTable* pStringTable,
int iAccept, int iReject) {}
void C_4JProfile::SetTrialAwardText(eAwardType AwardType, int iTitle,
int iText) {}
int C_4JProfile::GetLockedProfile() { return s_lockedProfile; }
void C_4JProfile::SetLockedProfile(int iProf) { s_lockedProfile = iProf; }
bool C_4JProfile::IsSignedIn(int iQuadrant) { return iQuadrant == 0; }
bool C_4JProfile::IsSignedInLive(int iProf) { return IsSignedIn(iProf); }
bool C_4JProfile::IsGuest(int iQuadrant) { return false; }
unsigned int C_4JProfile::RequestSignInUI(
bool bFromInvite, bool bLocalGame, bool bNoGuestsAllowed,
bool bMultiplayerSignIn, bool bAddUser,
int (*Func)(void*, const bool, const int iPad), void* lpParam,
int iQuadrant) {
return 0;
}
unsigned int C_4JProfile::DisplayOfflineProfile(int (*Func)(void*, const bool,
const int iPad),
void* lpParam, int iQuadrant) {
return 0;
}
unsigned int C_4JProfile::RequestConvertOfflineToGuestUI(
int (*Func)(void*, const bool, const int iPad), void* lpParam,
int iQuadrant) {
return 0;
}
void C_4JProfile::SetPrimaryPlayerChanged(bool bVal) {}
bool C_4JProfile::QuerySigninStatus(void) { return true; }
void C_4JProfile::GetXUID(int iPad, PlayerUID* pXuid, bool bOnlineXuid) {
bool C_4JProfile::IsGuest(int) { return false; }
bool C_4JProfile::QuerySigninStatus() { return true; }
void C_4JProfile::GetXUID(int iPad, PlayerUID* pXuid, bool) {
if (pXuid)
*pXuid =
kFakeXuidBase + static_cast<PlayerUID>(isValidPad(iPad) ? iPad : 0);
}
bool C_4JProfile::AreXUIDSEqual(PlayerUID xuid1, PlayerUID xuid2) {
return xuid1 == xuid2;
}
bool C_4JProfile::XUIDIsGuest(PlayerUID xuid) { return false; }
bool C_4JProfile::AllowedToPlayMultiplayer(int iProf) { return true; }
bool C_4JProfile::GetChatAndContentRestrictions(int iPad,
bool* pbChatRestricted,
bool C_4JProfile::XUIDIsGuest(PlayerUID) { return false; }
bool C_4JProfile::AllowedToPlayMultiplayer(int) { return true; }
bool C_4JProfile::GetChatAndContentRestrictions(int, bool* pbChatRestricted,
bool* pbContentRestricted,
int* piAge) {
if (pbChatRestricted) *pbChatRestricted = false;
@@ -169,105 +146,56 @@ bool C_4JProfile::GetChatAndContentRestrictions(int iPad,
if (piAge) *piAge = 18;
return true;
}
void C_4JProfile::StartTrialGame() {}
void C_4JProfile::AllowedPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
bool* allAllowed,
bool* friendsAllowed) {
if (allAllowed) *allAllowed = true;
if (friendsAllowed) *friendsAllowed = true;
}
bool C_4JProfile::CanViewPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
PlayerUID* pXuids,
unsigned int xuidCount) {
return true;
}
void C_4JProfile::ShowProfileCard(int iPad, PlayerUID targetUid) {}
bool C_4JProfile::GetProfileAvatar(int iPad,
int (*Func)(void* lpParam,
std::uint8_t* thumbnailData,
unsigned int thumbnailBytes),
void* lpParam) {
return false;
}
void C_4JProfile::CancelProfileAvatarRequest() {}
int C_4JProfile::GetPrimaryPad() { return s_primaryPad; }
void C_4JProfile::SetPrimaryPad(int iPad) { s_primaryPad = iPad; }
char* C_4JProfile::GetGamertag(int iPad) {
const int resolvedPad = isValidPad(iPad) ? iPad : 0;
ensureFakeIdentity(resolvedPad);
return s_gamertags[resolvedPad];
const int p = isValidPad(iPad) ? iPad : 0;
ensureFakeIdentity(p);
return s_gamertags[p];
}
std::wstring C_4JProfile::GetDisplayName(int iPad) {
const int resolvedPad = isValidPad(iPad) ? iPad : 0;
ensureFakeIdentity(resolvedPad);
return s_displayNames[resolvedPad];
const int p = isValidPad(iPad) ? iPad : 0;
ensureFakeIdentity(p);
return s_displayNames[p];
}
bool C_4JProfile::IsFullVersion() { return s_profileIsFullVersion; }
void C_4JProfile::SetSignInChangeCallback(void (*Func)(void*, bool,
unsigned int),
void* lpParam) {}
void C_4JProfile::SetNotificationsCallback(void (*Func)(void*, std::uint32_t,
unsigned int),
void* lpParam) {}
bool C_4JProfile::RegionIsNorthAmerica(void) { return false; }
bool C_4JProfile::LocaleIsUSorCanada(void) { return false; }
int C_4JProfile::GetLiveConnectionStatus() { return 0; }
bool C_4JProfile::IsSystemUIDisplayed() { return false; }
void C_4JProfile::SetProfileReadErrorCallback(void (*Func)(void*),
void* lpParam) {}
int C_4JProfile::SetDefaultOptionsCallback(int (*Func)(void*, PROFILESETTINGS*,
const int iPad),
void* lpParam) {
int C_4JProfile::SetDefaultOptionsCallback(
int (*Func)(void*, PROFILESETTINGS*, const int iPad), void* lpParam) {
s_defaultOptionsCallback = Func;
s_defaultOptionsCallbackParam = lpParam;
return 0;
}
int C_4JProfile::SetOldProfileVersionCallback(int (*Func)(void*, unsigned char*,
const unsigned short,
const int),
void* lpParam) {
return 0;
}
C_4JProfile::PROFILESETTINGS* C_4JProfile::GetDashboardProfileSettings(
int iPad) {
return &s_dashboardSettings[isValidPad(iPad) ? iPad : 0];
}
void C_4JProfile::WriteToProfile(int iQuadrant, bool bGameDefinedDataChanged,
bool bOverride5MinuteLimitOnProfileWrites) {}
void C_4JProfile::ForceQueuedProfileWrites(int iPad) {}
void* C_4JProfile::GetGameDefinedProfileData(int iQuadrant) {
return isValidPad(iQuadrant) ? s_profileData[iQuadrant] : nullptr;
}
void C_4JProfile::ResetProfileProcessState() {}
void C_4JProfile::Tick(void) {}
void C_4JProfile::RegisterAward(int iAwardNumber, int iGamerconfigID,
eAwardType eType, bool bLeaderboardAffected,
CXuiStringTable* pStringTable, int iTitleStr,
int iTextStr, int iAcceptStr,
char* pszThemeName, unsigned int uiThemeSize) {}
int C_4JProfile::GetAwardId(int iAwardNumber) { return 0; }
eAwardType C_4JProfile::GetAwardType(int iAwardNumber) {
return eAwardType_Achievement;
void C_4JProfile::AllowedPlayerCreatedContent(int, bool, bool* allAllowed,
bool* friendsAllowed) {
if (allAllowed) *allAllowed = true;
if (friendsAllowed) *friendsAllowed = true;
}
bool C_4JProfile::CanBeAwarded(int iQuadrant, int iAwardNumber) {
return false;
bool C_4JProfile::CanViewPlayerCreatedContent(int, bool, PlayerUID*,
unsigned int) {
return true;
}
void C_4JProfile::Award(int iQuadrant, int iAwardNumber, bool bForce) {}
bool C_4JProfile::IsAwardsFlagSet(int iQuadrant, int iAward) { return false; }
void C_4JProfile::RichPresenceInit(int iPresenceCount, int iContextCount) {}
void C_4JProfile::RegisterRichPresenceContext(int iGameConfigContextID) {}
void C_4JProfile::SetRichPresenceContextValue(int iPad, int iContextID,
int iVal) {}
void C_4JProfile::SetCurrentGameActivity(int iPad, int iNewPresence,
bool bSetOthersToIdle) {}
void C_4JProfile::DisplayFullVersionPurchase(bool bRequired, int iQuadrant,
int iUpsellParam) {}
void C_4JProfile::SetUpsellCallback(void (*Func)(void* lpParam,
eUpsellType type,
eUpsellResponse response,
int iUserData),
void* lpParam) {}
void C_4JProfile::SetDebugFullOverride(bool bVal) {
s_profileIsFullVersion = bVal;
// GetPrimaryPad/SetPrimaryPad — delegates to InputManager.
// Kept here temporarily for call sites that still use ProfileManager.
// These forward to the canonical copies in C_4JInput.
int C_4JProfile::GetPrimaryPad() {
extern C_4JInput InputManager;
return InputManager.GetPrimaryPad();
}
void C_4JProfile::SetPrimaryPad(int iPad) {
extern C_4JInput InputManager;
InputManager.SetPrimaryPad(iPad);
}
+68 -156
View File
@@ -4,51 +4,11 @@
#include <string>
#include "../4J.Common/4J_Compat.h"
enum eAwardType {
eAwardType_Achievement = 0,
eAwardType_GamerPic,
eAwardType_Theme,
eAwardType_AvatarItem,
};
enum eUpsellType {
eUpsellType_Custom = 0, // This is the default, and means that the upsell
// dialog was initiated in the app code
eUpsellType_Achievement,
eUpsellType_GamerPic,
eUpsellType_Theme,
eUpsellType_AvatarItem,
};
enum eUpsellResponse {
eUpsellResponse_Declined,
eUpsellResponse_Accepted_NoPurchase,
eUpsellResponse_Accepted_Purchase,
};
//
// Title info
//
#include "../platform/IPlatformProfile.h"
#define TITLEID_MINECRAFT 0x584111F7
//
// Context ids
//
// These values are passed as the dwContextId to XUserSetContext.
//
#define CONTEXT_GAME_STATE 0
//
// Context values
//
// These values are passed as the dwContextValue to XUserSetContext.
//
// Values for CONTEXT_GAME_STATE
#define CONTEXT_GAME_STATE_BLANK 0
#define CONTEXT_GAME_STATE_RIDING_PIG 1
#define CONTEXT_GAME_STATE_RIDING_MINECART 2
@@ -59,12 +19,10 @@ enum eUpsellResponse {
#define CONTEXT_GAME_STATE_NETHER 7
#define CONTEXT_GAME_STATE_CD 8
#define CONTEXT_GAME_STATE_MAP 9
#define CONTEXT_GAME_STATE_ENCHANTING 5 // TODO 10
#define CONTEXT_GAME_STATE_BREWING 5 // TODO 11
#define CONTEXT_GAME_STATE_ANVIL 6 // TODO 12
#define CONTEXT_GAME_STATE_TRADING 0 // TODO 13
// Values for X_CONTEXT_PRESENCE
#define CONTEXT_GAME_STATE_ENCHANTING 5
#define CONTEXT_GAME_STATE_BREWING 5
#define CONTEXT_GAME_STATE_ANVIL 6
#define CONTEXT_GAME_STATE_TRADING 0
#define CONTEXT_PRESENCE_IDLE 0
#define CONTEXT_PRESENCE_MENUS 1
@@ -73,23 +31,10 @@ enum eUpsellResponse {
#define CONTEXT_PRESENCE_MULTIPLAYER_1P 4
#define CONTEXT_PRESENCE_MULTIPLAYER_1POFFLINE 5
// Values for X_CONTEXT_GAME_MODE
#define CONTEXT_GAME_MODE_GAMEMODE 0
#define CONTEXT_GAME_MODE_MULTIPLAYER 1
class C_4JProfile {
class C_4JProfile : public IPlatformProfile {
public:
struct PROFILESETTINGS {
int iYAxisInversion;
int iControllerSensitivity;
int iVibration;
bool bSwapSticks;
};
// --- Methods with real logic (implemented in .cpp) ---
// 4 players have game defined data, puiGameDefinedDataChangedBitmask needs
// to be checked by the game side to see if there's an update needed - it'll
// have the bits set for players to be updated
void Initialise(std::uint32_t dwTitleID, std::uint32_t dwOfferID,
unsigned short usProfileVersion,
unsigned int uiProfileValuesC,
@@ -97,118 +42,85 @@ public:
std::uint32_t* pdwProfileSettingsA,
int iGameDefinedDataSizeX4,
unsigned int* puiGameDefinedDataChangedBitmask);
void SetTrialTextStringTable(CXuiStringTable* pStringTable, int iAccept,
int iReject);
void SetTrialAwardText(eAwardType AwardType, int iTitle,
int iText); // achievement popup in the trial game
int GetLockedProfile();
void SetLockedProfile(int iProf);
bool IsSignedIn(int iQuadrant);
bool IsSignedInLive(int iProf);
bool IsGuest(int iQuadrant);
unsigned int RequestSignInUI(bool bFromInvite, bool bLocalGame,
bool bNoGuestsAllowed, bool bMultiplayerSignIn,
bool bAddUser,
int (*Func)(void*, const bool, const int iPad),
void* lpParam,
int iQuadrant = XUSER_INDEX_ANY);
unsigned int DisplayOfflineProfile(int (*Func)(void*, const bool,
const int iPad),
void* lpParam,
int iQuadrant = XUSER_INDEX_ANY);
unsigned int RequestConvertOfflineToGuestUI(
int (*Func)(void*, const bool, const int iPad), void* lpParam,
int iQuadrant = XUSER_INDEX_ANY);
void SetPrimaryPlayerChanged(bool bVal);
bool QuerySigninStatus(void);
bool QuerySigninStatus();
void GetXUID(int iPad, PlayerUID* pXuid, bool bOnlineXuid);
bool AreXUIDSEqual(PlayerUID xuid1, PlayerUID xuid2);
bool XUIDIsGuest(PlayerUID xuid);
bool AllowedToPlayMultiplayer(int iProf);
bool GetChatAndContentRestrictions(int iPad, bool* pbChatRestricted,
bool* pbContentRestricted, int* piAge);
void StartTrialGame(); // disables saves and leaderboard, and change state
// to readyforgame from pregame
char* GetGamertag(int iPad);
std::wstring GetDisplayName(int iPad);
bool IsFullVersion();
int SetDefaultOptionsCallback(int (*Func)(void*, PROFILESETTINGS*,
const int iPad),
void* lpParam);
PROFILESETTINGS* GetDashboardProfileSettings(int iPad);
void* GetGameDefinedProfileData(int iQuadrant);
void AllowedPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
bool* allAllowed, bool* friendsAllowed);
bool CanViewPlayerCreatedContent(int iPad, bool thisQuadrantOnly,
PlayerUID* pXuids, unsigned int xuidCount);
void ShowProfileCard(int iPad, PlayerUID targetUid);
bool GetProfileAvatar(int iPad,
int (*Func)(void* lpParam,
std::uint8_t* thumbnailData,
unsigned int thumbnailBytes),
void* lpParam);
void CancelProfileAvatarRequest();
// SYS
// --- Dead stubs (inline no-ops, kept for call-site compat) ---
void Tick() {}
void SetTrialTextStringTable(CXuiStringTable*, int, int) {}
void SetTrialAwardText(eAwardType, int, int) {}
void StartTrialGame() {}
unsigned int RequestSignInUI(bool, bool, bool, bool, bool,
int (*)(void*, const bool, const int),
void*, int = XUSER_INDEX_ANY) { return 0; }
unsigned int DisplayOfflineProfile(int (*)(void*, const bool, const int),
void*, int = XUSER_INDEX_ANY) { return 0; }
unsigned int RequestConvertOfflineToGuestUI(
int (*)(void*, const bool, const int), void*,
int = XUSER_INDEX_ANY) { return 0; }
void SetPrimaryPlayerChanged(bool) {}
void ShowProfileCard(int, PlayerUID) {}
bool GetProfileAvatar(int, int (*)(void*, std::uint8_t*, unsigned int),
void*) { return false; }
void CancelProfileAvatarRequest() {}
void SetSignInChangeCallback(void (*)(void*, bool, unsigned int), void*) {}
void SetNotificationsCallback(void (*)(void*, std::uint32_t, unsigned int),
void*) {}
bool RegionIsNorthAmerica() { return false; }
bool LocaleIsUSorCanada() { return false; }
int GetLiveConnectionStatus() { return 0; }
bool IsSystemUIDisplayed() { return false; }
void SetProfileReadErrorCallback(void (*)(void*), void*) {}
int SetOldProfileVersionCallback(int (*)(void*, unsigned char*,
const unsigned short, const int),
void*) { return 0; }
void WriteToProfile(int, bool = false, bool = false) {}
void ForceQueuedProfileWrites(int = XUSER_INDEX_ANY) {}
void ResetProfileProcessState() {}
void RegisterAward(int, int, eAwardType, bool = false,
CXuiStringTable* = nullptr, int = -1, int = -1,
int = -1, char* = nullptr, unsigned int = 0L) {}
int GetAwardId(int) { return 0; }
eAwardType GetAwardType(int) { return eAwardType_Achievement; }
bool CanBeAwarded(int, int) { return false; }
void Award(int, int, bool = false) {}
bool IsAwardsFlagSet(int, int) { return false; }
void RichPresenceInit(int, int) {}
void RegisterRichPresenceContext(int) {}
void SetRichPresenceContextValue(int, int, int) {}
void SetCurrentGameActivity(int, int, bool = false) {}
void DisplayFullVersionPurchase(bool, int, int = -1) {}
void SetUpsellCallback(void (*)(void*, eUpsellType, eUpsellResponse, int),
void*) {}
void SetDebugFullOverride(bool) {}
// GetPrimaryPad/SetPrimaryPad moved to InputManager
int GetPrimaryPad();
void SetPrimaryPad(int iPad);
char* GetGamertag(int iPad);
std::wstring GetDisplayName(int iPad);
bool IsFullVersion();
void SetSignInChangeCallback(void (*Func)(void*, bool, unsigned int),
void* lpParam);
void SetNotificationsCallback(void (*Func)(void*, std::uint32_t,
unsigned int),
void* lpParam);
bool RegionIsNorthAmerica(void);
bool LocaleIsUSorCanada(void);
int GetLiveConnectionStatus();
bool IsSystemUIDisplayed();
void SetProfileReadErrorCallback(void (*Func)(void*), void* lpParam);
// PROFILE DATA
int SetDefaultOptionsCallback(int (*Func)(void*, PROFILESETTINGS*,
const int iPad),
void* lpParam);
int SetOldProfileVersionCallback(int (*Func)(void*, unsigned char*,
const unsigned short,
const int),
void* lpParam);
PROFILESETTINGS* GetDashboardProfileSettings(int iPad);
void WriteToProfile(int iQuadrant, bool bGameDefinedDataChanged = false,
bool bOverride5MinuteLimitOnProfileWrites = false);
void ForceQueuedProfileWrites(int iPad = XUSER_INDEX_ANY);
void* GetGameDefinedProfileData(int iQuadrant);
void ResetProfileProcessState(); // after a sign out from the primary
// player, call this
void Tick(void);
// ACHIEVEMENTS & AWARDS
void RegisterAward(int iAwardNumber, int iGamerconfigID, eAwardType eType,
bool bLeaderboardAffected = false,
CXuiStringTable* pStringTable = nullptr,
int iTitleStr = -1, int iTextStr = -1,
int iAcceptStr = -1, char* pszThemeName = nullptr,
unsigned int uiThemeSize = 0L);
int GetAwardId(int iAwardNumber);
eAwardType GetAwardType(int iAwardNumber);
bool CanBeAwarded(int iQuadrant, int iAwardNumber);
void Award(int iQuadrant, int iAwardNumber, bool bForce = false);
bool IsAwardsFlagSet(int iQuadrant, int iAward);
// RICH PRESENCE
void RichPresenceInit(int iPresenceCount, int iContextCount);
void RegisterRichPresenceContext(int iGameConfigContextID);
void SetRichPresenceContextValue(int iPad, int iContextID, int iVal);
void SetCurrentGameActivity(int iPad, int iNewPresence,
bool bSetOthersToIdle = false);
// PURCHASE
void DisplayFullVersionPurchase(bool bRequired, int iQuadrant,
int iUpsellParam = -1);
void SetUpsellCallback(void (*Func)(void* lpParam, eUpsellType type,
eUpsellResponse response,
int iUserData),
void* lpParam);
// Debug
void SetDebugFullOverride(
bool bVal); // To override the license version (trail/full). Only in
// debug/release, not ContentPackage
};
// Singleton
-5
View File
@@ -1,10 +1,5 @@
profile_sources = files(
'4J_Profile.cpp',
'PRO_AwardManager.cpp',
'PRO_Data.cpp',
'PRO_Main.cpp',
'PRO_RichPresence.cpp',
'PRO_Sys.cpp',
'stdafx.cpp',
)
# 4jprofile stink