diff options
author | Josh <32826900+ShinyDragonHunter@users.noreply.github.com> | 2022-01-06 19:48:08 +0000 |
---|---|---|
committer | Josh <32826900+ShinyDragonHunter@users.noreply.github.com> | 2022-01-06 19:48:08 +0000 |
commit | 64a7ee8810238aedb2aacd672391660ef9de41ca (patch) | |
tree | 1567d7012725bd7c9689561288491a6279e2627f | |
parent | 9fb4f28b23d0f61b6339925b4af582e64de08128 (diff) |
Updated Adding Support for Connectivity with Other Hacks Whilst Maintaining Connectivity with Vanilla (markdown)
-rw-r--r-- | Adding-Support-for-Connectivity-with-Other-Hacks-Whilst-Maintaining-Connectivity-with-Vanilla.md | 88 |
1 files changed, 39 insertions, 49 deletions
diff --git a/Adding-Support-for-Connectivity-with-Other-Hacks-Whilst-Maintaining-Connectivity-with-Vanilla.md b/Adding-Support-for-Connectivity-with-Other-Hacks-Whilst-Maintaining-Connectivity-with-Vanilla.md index 31a77e9..c6aa27f 100644 --- a/Adding-Support-for-Connectivity-with-Other-Hacks-Whilst-Maintaining-Connectivity-with-Vanilla.md +++ b/Adding-Support-for-Connectivity-with-Other-Hacks-Whilst-Maintaining-Connectivity-with-Vanilla.md @@ -38,24 +38,21 @@ struct LinkPlayer /* 0x1A */ u16 language; }; ``` -And in `include/link_rfu.h`, we need to find `struct __attribute__((packed, aligned(2))) GFtgtGname` and make the following change: +And in `include/link_rfu.h`, we need to find `struct __attribute__((packed, aligned(2))) RfuGameData` and make the following change: ```diff -struct __attribute__((packed, aligned(2))) GFtgtGname +struct __attribute__((packed, aligned(2))) RfuGameData { - struct GFtgtGnameSub unk_00; - u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3; - // u8 gender:1; - // u8 unk_4:3 - // u8 active:1 - u16 species:10; - u16 type:6; + struct RfuGameCompatibilityData compatibility; + u8 partnerInfo[RFU_CHILD_MAX]; + u16 tradeSpecies:10; + u16 tradeType:6; u8 activity:7; - u8 started:1; + u8 startedActivity:1; u8 playerGender:1; - u8 level:7; + u8 tradeLevel:7; - u8 padding; + u8 versionModifier; -}; // size: RFU_GNAME_SIZE +}; ``` If you notice, we now have a `versionModifier` in both structs which we will be using to signal hacks that the game is in fact an unofficial game. @@ -87,46 +84,35 @@ if ((linkPlayer->version & 0xFF) == VERSION_RUBY || (linkPlayer->version & 0xFF) - linkPlayer->neverRead = 0; linkPlayer->progressFlags = 0; } -ConvertLinkPlayerName(linkPlayer); -if (strcmp(block->magic1, sASCIIGameFreakInc) != 0 - || strcmp(block->magic2, sASCIIGameFreakInc) != 0) -{ - SetMainCallback2(CB2_LinkError); -} -else -{ - HandleReceiveRemoteLinkPlayer(i); -} ``` This removes the reference to `linkPlayer->neverRead`, which was changed to our new `versionModifier` label. Don't worry, that byte is written to but never read hence it being named `neverRead`. Now, we need to open [src/link_rfu_3](https://github.com/pret/pokeemerald/blob/master/src/link_rfu_3.c) and find the function named `InitHostRFUtgtGname`and make changes as follows: ```diff -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders) +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) { s32 i; - for (i = 0; i < 2; i++) - { - data->unk_00.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; - } + for (i = 0; i < (s32)ARRAY_COUNT(data->compatibility.playerTrainerId); i++) + data->compatibility.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; + for (i = 0; i < RFU_CHILD_MAX; i++) { - data->child_sprite_gender[i] = child_sprite_genders; - child_sprite_genders >>= 8; + data->partnerInfo[i] = partnerInfo; + partnerInfo >>= 8; // Each element is 1 byte } data->playerGender = gSaveBlock2Ptr->playerGender; data->activity = activity; data->started = started; + data->versionModifier = VERSION_MODIFIER; - data->unk_00.language = GAME_LANGUAGE; - data->unk_00.version = GAME_VERSION; - data->unk_00.hasNews = FALSE; - data->unk_00.hasCard = FALSE; -- data->unk_00.unknown = FALSE; - data->unk_00.isChampion = FlagGet(FLAG_IS_CHAMPION); - data->unk_00.hasNationalDex = IsNationalPokedexEnabled(); - data->unk_00.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); + data->compatibility.language = GAME_LANGUAGE; + data->compatibility.version = GAME_VERSION; + data->compatibility.hasNews = FALSE; + data->compatibility.hasCard = FALSE; + data->compatibility.unknown = FALSE; + data->compatibility.isChampion = FlagGet(FLAG_IS_CHAMPION); + data->compatibility.hasNationalDex = IsNationalPokedexEnabled(); + data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); } ``` Now, our game will send our `versionModifier` ID through both wireless and cable link. Now, we need to make a few edits to the trainer card. This is probably the most difficult step in this tutorial so follow carefully. @@ -158,8 +144,11 @@ struct TrainerCard /*0x28*/ u16 easyChatProfile[TRAINER_CARD_PROFILE_LENGTH]; /*0x30*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x38*/ u8 version; - /*0x3A*/ bool16 hasAllFrontierSymbols; - /*0x3C*/ u32 berryCrushPoints; + /*0x3A*/ bool16 linkHasAllFrontierSymbols; + /*0x3C*/ union { + u32 berryCrush; + u32 frontier; + } linkPoints; // This field is used differently by FRLG vs Emerald /*0x40*/ u32 unionRoomNum; /*0x44*/ u8 filler[8]; /*0x4C*/ bool8 shouldDrawStickers; // FRLG only @@ -167,10 +156,12 @@ struct TrainerCard /*0x4E*/ u8 monIconTint; // FRLG only /*0x4F*/ u8 facilityClass; /*0x50*/ u8 stickers[TRAINER_CARD_STICKER_TYPES]; // FRLG only ++ /*0x53*/ u8 versionModifier; /*0x54*/ u16 monSpecies[PARTY_SIZE]; // FRLG only - /*0x60*/ bool16 hasAllSymbols; + // Note: Link players use linkHasAllFrontierSymbols, not the field below, + // which they use for a Wonder Card flag id instead (see CreateTrainerCardInBuffer) + /*0x60*/ bool16 hasAllFrontierSymbols; /*0x62*/ u16 frontierBP; -+ /*0x64*/ u8 versionModifier; }; ``` This is so the game can use the `versionModifier` value when loading the trainer card. @@ -181,8 +172,8 @@ void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion, u8 v Okay, now we actually need to use that new byte! Open [src/trainer_card.c](https://github.com/pret/pokeemerald/blob/master/src/trainer_card.c) and find the functions `CopyTrainerCardData`, `TrainerCard_GenerateCardForLinkPlayer` and `TrainerCard_GenerateCardForPlayer`. In `CopyTrainerCardData`, make the following changes: ```diff -- void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion) -+ void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion, u8 versionModifier) +- void CopyTrainerCardData(struct TrainerCard *dst, struct TrainerCard *src, u8 gameVersion) ++ void CopyTrainerCardData(struct TrainerCard *dst, struct TrainerCard *src, u8 gameVersion, u8 versionModifier) { memset(dst, 0, sizeof(struct TrainerCard)); dst->version = gameVersion; @@ -198,9 +189,9 @@ In `CopyTrainerCardData`, make the following changes: break; case CARD_TYPE_EMERALD: memcpy(dst, src, 0x60); - dst->berryCrushPoints = 0; - dst->hasAllSymbols = src[29]; - dst->frontierBP = src[30]; + dst->linkPoints.frontier = 0; + dst->hasAllFrontierSymbols = src->linkHasAllFrontierSymbols; + dst->frontierBP = *((u16*)&src->linkPoints.frontier); break; } } @@ -229,14 +220,13 @@ In `TrainerCard_GenerateCardForPlayer`, make the following changes: ```diff void TrainerCard_GenerateCardForPlayer(struct TrainerCard *trainerCard) { -- memset(trainerCard, 0, 0x60); -+ memset(trainerCard, 0, sizeof(struct TrainerCard)); + memset(trainerCard, 0, sizeof(struct TrainerCard)); trainerCard->version = GAME_VERSION; + trainerCard->versionModifier = VERSION_MODIFIER; - SetPlayerCardData(trainerCard, CARD_TYPE_EMERALD); + SetPlayerCardData(trainerCard, VersionToCardType(GAME_VERSION, VERSION_MODIFIER)); trainerCard->hasAllFrontierSymbols = HasAllFrontierSymbols(); - *((u16*)&trainerCard->berryCrushPoints) = gSaveBlock2Ptr->frontier.cardBattlePoints; + trainerCard->frontierBP = gSaveBlock2Ptr->frontier.cardBattlePoints; if (trainerCard->hasAllFrontierSymbols) trainerCard->stars++; |