diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_2.c | 25 | ||||
-rw-r--r-- | src/battle_controller_player.c | 4 | ||||
-rw-r--r-- | src/battle_controllers.c | 610 | ||||
-rw-r--r-- | src/egg_hatch.c | 6 | ||||
-rw-r--r-- | src/evolution_scene.c | 7 | ||||
-rw-r--r-- | src/link.c | 2271 | ||||
-rw-r--r-- | src/link_rfu.c | 16 | ||||
-rw-r--r-- | src/main.c | 94 | ||||
-rw-r--r-- | src/reshow_battle_screen.c | 2 | ||||
-rw-r--r-- | src/rom_8011DC0.c | 18 |
10 files changed, 2645 insertions, 408 deletions
diff --git a/src/battle_2.c b/src/battle_2.c index 798fabf4b..ffec02d17 100644 --- a/src/battle_2.c +++ b/src/battle_2.c @@ -17,6 +17,7 @@ #include "items.h" #include "hold_effects.h" #include "link.h" +#include "link_rfu.h" #include "bg.h" #include "dma3.h" #include "string_util.h" @@ -735,7 +736,7 @@ static void CB2_HandleStartBattle(void) sub_805EF14(); gBattleCommunication[MULTIUSE_STATE] = 1; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E0E8(); break; case 1: @@ -759,7 +760,7 @@ static void CB2_HandleStartBattle(void) SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32); gBattleCommunication[MULTIUSE_STATE] = 2; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800DFB4(0, 0); } } @@ -930,7 +931,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) sub_805EF14(); gBattleCommunication[MULTIUSE_STATE] = 1; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E0E8(); // fall through case 1: @@ -961,7 +962,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) gBattleCommunication[MULTIUSE_STATE] = 2; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800DFB4(0, 0); } } @@ -1238,14 +1239,14 @@ static void CB2_PreInitMultiBattle(void) if (sub_800A520() && !gPaletteFade.active) { gBattleCommunication[MULTIUSE_STATE]++; - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800ADF8(); else sub_800AC34(); } break; case 3: - if (gLinkVSyncDisabled) + if (gWirelessCommType) { if (sub_8010500()) { @@ -1330,7 +1331,7 @@ static void CB2_HandleStartMultiBattle(void) sub_805EF14(); gBattleCommunication[MULTIUSE_STATE] = 1; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E0E8(); break; case 1: @@ -1348,7 +1349,7 @@ static void CB2_HandleStartMultiBattle(void) SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32); gBattleCommunication[MULTIUSE_STATE]++; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800DFB4(0, 0); } } @@ -2133,12 +2134,12 @@ static void sub_8038F34(void) } break; case 8: - if (!gLinkVSyncDisabled) + if (!gWirelessCommType) sub_800AC34(); gBattleCommunication[MULTIUSE_STATE]++; break; case 9: - if (!gMain.field_439_x4 || gLinkVSyncDisabled || gReceivedRemoteLinkPlayers != 1) + if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1) { gMain.field_439_x4 = 0; SetMainCallback2(gMain.savedCallback); @@ -2317,13 +2318,13 @@ static void sub_803939C(void) case 8: if (--gBattleCommunication[1] == 0) { - if (gMain.field_439_x4 && !gLinkVSyncDisabled) + if (gMain.field_439_x4 && !gWirelessCommType) sub_800AC34(); gBattleCommunication[MULTIUSE_STATE]++; } break; case 9: - if (!gMain.field_439_x4 || gLinkVSyncDisabled || gReceivedRemoteLinkPlayers != 1) + if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1) { gMain.field_439_x4 = 0; if (!gPaletteFade.active) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 16c62c53b..65f48f6ae 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -896,7 +896,7 @@ static void HandleMoveSwitchting(void) static void sub_80586F8(void) { - if (gLinkVSyncDisabled == 0) + if (gWirelessCommType == 0) { if (gReceivedRemoteLinkPlayers == 0) { @@ -932,7 +932,7 @@ void sub_80587B0(void) { if (sub_800A520()) { - if (gLinkVSyncDisabled == 0) + if (gWirelessCommType == 0) sub_800AC34(); else sub_800ADF8(); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 5c874438e..b3d93d759 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -12,7 +12,6 @@ #include "abilities.h" #include "battle_message.h" -extern u32 gBattleTypeFlags; extern u32 gBattleExecBuffer; extern void (*gBattleMainFunc)(void); extern void (*gBattleBankFunc[BATTLE_BANKS_COUNT])(void); @@ -27,7 +26,6 @@ extern u8 gUnknown_0203C7B4; extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200]; extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; -extern u8 gBattleBuffersTransferData[0x100]; extern u8 gUnknown_02022D08; extern u8 gUnknown_02022D09; extern u8 gUnknown_02022D0A; @@ -39,11 +37,11 @@ extern u16 gBattleWeather; extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT]; extern u16 gCurrentMove; extern u16 gLastUsedMove; -extern u16 gLastUsedItem; -extern u8 gBattleOutcome; extern u8 gLastUsedAbility; extern u8 gStringBank; +static EWRAM_DATA u8 sBattleBuffersTransferData[0x100] = {}; + extern const struct BattleMove gBattleMoves[]; extern void task00_08081A90(u8 taskId); // cable_club @@ -61,10 +59,10 @@ void HandleLinkBattleSetup(void) { if (gBattleTypeFlags & BATTLE_TYPE_LINK) { - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800B488(); if (!gReceivedRemoteLinkPlayers) - sub_8009734(); + OpenLink(); CreateTask(task00_08081A90, 0); CreateTasksForSendRecvLinkBuffers(); } @@ -782,7 +780,7 @@ static void Task_HandleSendLinkBuffersData(u8 taskId) gTasks[taskId].data[11]++; break; case 2: - if (gLinkVSyncDisabled) + if (gWirelessCommType) { gTasks[taskId].data[11]++; } @@ -793,9 +791,9 @@ static void Task_HandleSendLinkBuffersData(u8 taskId) else var = (gBattleTypeFlags & BATTLE_TYPE_MULTI) ? 4 : 2; - if (sub_800ABAC() >= var) + if (GetLinkPlayerCount_2() >= var) { - if (sub_800ABBC()) + if (IsLinkMaster()) { sub_800A620(); gTasks[taskId].data[11]++; @@ -941,171 +939,171 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) void EmitGetMonData(u8 bufferId, u8 requestId, u8 monToCheck) { - gBattleBuffersTransferData[0] = CONTROLLER_GETMONDATA; - gBattleBuffersTransferData[1] = requestId; - gBattleBuffersTransferData[2] = monToCheck; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_GETMONDATA; + sBattleBuffersTransferData[1] = requestId; + sBattleBuffersTransferData[2] = monToCheck; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitGetRawMonData(u8 bufferId, u8 monId, u8 bytes) { - gBattleBuffersTransferData[0] = CONTROLLER_GETRAWMONDATA; - gBattleBuffersTransferData[1] = monId; - gBattleBuffersTransferData[2] = bytes; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_GETRAWMONDATA; + sBattleBuffersTransferData[1] = monId; + sBattleBuffersTransferData[2] = bytes; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitSetMonData(u8 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_SETMONDATA; - gBattleBuffersTransferData[1] = requestId; - gBattleBuffersTransferData[2] = monToCheck; + sBattleBuffersTransferData[0] = CONTROLLER_SETMONDATA; + sBattleBuffersTransferData[1] = requestId; + sBattleBuffersTransferData[2] = monToCheck; for (i = 0; i < bytes; i++) - gBattleBuffersTransferData[3 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 3 + bytes); + sBattleBuffersTransferData[3 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 3 + bytes); } void EmitSetRawMonData(u8 bufferId, u8 monId, u8 bytes, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_SETRAWMONDATA; - gBattleBuffersTransferData[1] = monId; - gBattleBuffersTransferData[2] = bytes; + sBattleBuffersTransferData[0] = CONTROLLER_SETRAWMONDATA; + sBattleBuffersTransferData[1] = monId; + sBattleBuffersTransferData[2] = bytes; for (i = 0; i < bytes; i++) - gBattleBuffersTransferData[3 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, bytes + 3); + sBattleBuffersTransferData[3 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, bytes + 3); } void EmitLoadMonSprite(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_LOADMONSPRITE; - gBattleBuffersTransferData[1] = CONTROLLER_LOADMONSPRITE; - gBattleBuffersTransferData[2] = CONTROLLER_LOADMONSPRITE; - gBattleBuffersTransferData[3] = CONTROLLER_LOADMONSPRITE; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_LOADMONSPRITE; + sBattleBuffersTransferData[1] = CONTROLLER_LOADMONSPRITE; + sBattleBuffersTransferData[2] = CONTROLLER_LOADMONSPRITE; + sBattleBuffersTransferData[3] = CONTROLLER_LOADMONSPRITE; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitSwitchInAnim(u8 bufferId, u8 partyId, bool8 dontClearSubstituteBit) { - gBattleBuffersTransferData[0] = CONTROLLER_SWITCHINANIM; - gBattleBuffersTransferData[1] = partyId; - gBattleBuffersTransferData[2] = dontClearSubstituteBit; - gBattleBuffersTransferData[3] = 5; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_SWITCHINANIM; + sBattleBuffersTransferData[1] = partyId; + sBattleBuffersTransferData[2] = dontClearSubstituteBit; + sBattleBuffersTransferData[3] = 5; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitReturnMonToBall(u8 bufferId, u8 arg1) { - gBattleBuffersTransferData[0] = CONTROLLER_RETURNMONTOBALL; - gBattleBuffersTransferData[1] = arg1; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_RETURNMONTOBALL; + sBattleBuffersTransferData[1] = arg1; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void EmitDrawTrainerPic(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_DRAWTRAINERPIC; - gBattleBuffersTransferData[1] = CONTROLLER_DRAWTRAINERPIC; - gBattleBuffersTransferData[2] = CONTROLLER_DRAWTRAINERPIC; - gBattleBuffersTransferData[3] = CONTROLLER_DRAWTRAINERPIC; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_DRAWTRAINERPIC; + sBattleBuffersTransferData[1] = CONTROLLER_DRAWTRAINERPIC; + sBattleBuffersTransferData[2] = CONTROLLER_DRAWTRAINERPIC; + sBattleBuffersTransferData[3] = CONTROLLER_DRAWTRAINERPIC; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitTrainerSlide(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDE; - gBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDE; - gBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDE; - gBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDE; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDE; + sBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDE; + sBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDE; + sBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDE; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitTrainerSlideBack(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDEBACK; - gBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDEBACK; - gBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDEBACK; - gBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDEBACK; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDEBACK; + sBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDEBACK; + sBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDEBACK; + sBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDEBACK; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitFaintAnimation(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_FAINTANIMATION; - gBattleBuffersTransferData[1] = CONTROLLER_FAINTANIMATION; - gBattleBuffersTransferData[2] = CONTROLLER_FAINTANIMATION; - gBattleBuffersTransferData[3] = CONTROLLER_FAINTANIMATION; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_FAINTANIMATION; + sBattleBuffersTransferData[1] = CONTROLLER_FAINTANIMATION; + sBattleBuffersTransferData[2] = CONTROLLER_FAINTANIMATION; + sBattleBuffersTransferData[3] = CONTROLLER_FAINTANIMATION; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitPaletteFade(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_PALETTEFADE; - gBattleBuffersTransferData[1] = CONTROLLER_PALETTEFADE; - gBattleBuffersTransferData[2] = CONTROLLER_PALETTEFADE; - gBattleBuffersTransferData[3] = CONTROLLER_PALETTEFADE; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_PALETTEFADE; + sBattleBuffersTransferData[1] = CONTROLLER_PALETTEFADE; + sBattleBuffersTransferData[2] = CONTROLLER_PALETTEFADE; + sBattleBuffersTransferData[3] = CONTROLLER_PALETTEFADE; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitSuccessBallThrowAnim(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_SUCCESSBALLTHROWANIM; - gBattleBuffersTransferData[1] = CONTROLLER_SUCCESSBALLTHROWANIM; - gBattleBuffersTransferData[2] = CONTROLLER_SUCCESSBALLTHROWANIM; - gBattleBuffersTransferData[3] = CONTROLLER_SUCCESSBALLTHROWANIM; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_SUCCESSBALLTHROWANIM; + sBattleBuffersTransferData[1] = CONTROLLER_SUCCESSBALLTHROWANIM; + sBattleBuffersTransferData[2] = CONTROLLER_SUCCESSBALLTHROWANIM; + sBattleBuffersTransferData[3] = CONTROLLER_SUCCESSBALLTHROWANIM; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitBallThrowAnim(u8 bufferId, u8 caseId) { - gBattleBuffersTransferData[0] = CONTROLLER_BALLTHROWANIM; - gBattleBuffersTransferData[1] = caseId; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_BALLTHROWANIM; + sBattleBuffersTransferData[1] = caseId; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void EmitPause(u8 bufferId, u8 toWait, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_PAUSE; - gBattleBuffersTransferData[1] = toWait; + sBattleBuffersTransferData[0] = CONTROLLER_PAUSE; + sBattleBuffersTransferData[1] = toWait; for (i = 0; i < toWait * 3; i++) - gBattleBuffersTransferData[2 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, toWait * 3 + 2); + sBattleBuffersTransferData[2 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, toWait * 3 + 2); } void EmitMoveAnimation(u8 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit) { - gBattleBuffersTransferData[0] = CONTROLLER_MOVEANIMATION; - gBattleBuffersTransferData[1] = move; - gBattleBuffersTransferData[2] = (move & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = turnOfMove; - gBattleBuffersTransferData[4] = movePower; - gBattleBuffersTransferData[5] = (movePower & 0xFF00) >> 8; - gBattleBuffersTransferData[6] = dmg; - gBattleBuffersTransferData[7] = (dmg & 0x0000FF00) >> 8; - gBattleBuffersTransferData[8] = (dmg & 0x00FF0000) >> 16; - gBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24; - gBattleBuffersTransferData[10] = friendship; - gBattleBuffersTransferData[11] = multihit; + sBattleBuffersTransferData[0] = CONTROLLER_MOVEANIMATION; + sBattleBuffersTransferData[1] = move; + sBattleBuffersTransferData[2] = (move & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = turnOfMove; + sBattleBuffersTransferData[4] = movePower; + sBattleBuffersTransferData[5] = (movePower & 0xFF00) >> 8; + sBattleBuffersTransferData[6] = dmg; + sBattleBuffersTransferData[7] = (dmg & 0x0000FF00) >> 8; + sBattleBuffersTransferData[8] = (dmg & 0x00FF0000) >> 16; + sBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24; + sBattleBuffersTransferData[10] = friendship; + sBattleBuffersTransferData[11] = multihit; if (WEATHER_HAS_EFFECT2) { - gBattleBuffersTransferData[12] = gBattleWeather; - gBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8; + sBattleBuffersTransferData[12] = gBattleWeather; + sBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8; } else { - gBattleBuffersTransferData[12] = 0; - gBattleBuffersTransferData[13] = 0; + sBattleBuffersTransferData[12] = 0; + sBattleBuffersTransferData[13] = 0; } - gBattleBuffersTransferData[14] = 0; - gBattleBuffersTransferData[15] = 0; - memcpy(&gBattleBuffersTransferData[16], disableStructPtr, sizeof(struct DisableStruct)); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 16 + sizeof(struct DisableStruct)); + sBattleBuffersTransferData[14] = 0; + sBattleBuffersTransferData[15] = 0; + memcpy(&sBattleBuffersTransferData[16], disableStructPtr, sizeof(struct DisableStruct)); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 16 + sizeof(struct DisableStruct)); } void EmitPrintString(u8 bufferId, u16 stringID) @@ -1113,12 +1111,12 @@ void EmitPrintString(u8 bufferId, u16 stringID) s32 i; struct StringInfoBattle* stringInfo; - gBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRING; - gBattleBuffersTransferData[1] = gBattleOutcome; - gBattleBuffersTransferData[2] = stringID; - gBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRING; + sBattleBuffersTransferData[1] = gBattleOutcome; + sBattleBuffersTransferData[2] = stringID; + sBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; - stringInfo = (struct StringInfoBattle*)(&gBattleBuffersTransferData[4]); + stringInfo = (struct StringInfoBattle*)(&sBattleBuffersTransferData[4]); stringInfo->currentMove = gCurrentMove; stringInfo->lastMove = gLastUsedMove; stringInfo->lastItem = gLastUsedItem; @@ -1137,7 +1135,7 @@ void EmitPrintString(u8 bufferId, u16 stringID) stringInfo->textBuffs[1][i] = gBattleTextBuff2[i]; stringInfo->textBuffs[2][i] = gBattleTextBuff3[i]; } - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); } void EmitPrintStringPlayerOnly(u8 bufferId, u16 stringID) @@ -1145,12 +1143,12 @@ void EmitPrintStringPlayerOnly(u8 bufferId, u16 stringID) s32 i; struct StringInfoBattle* stringInfo; - gBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRINGPLAYERONLY; - gBattleBuffersTransferData[1] = CONTROLLER_PRINTSTRINGPLAYERONLY; - gBattleBuffersTransferData[2] = stringID; - gBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRINGPLAYERONLY; + sBattleBuffersTransferData[1] = CONTROLLER_PRINTSTRINGPLAYERONLY; + sBattleBuffersTransferData[2] = stringID; + sBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; - stringInfo = (struct StringInfoBattle*)(&gBattleBuffersTransferData[4]); + stringInfo = (struct StringInfoBattle*)(&sBattleBuffersTransferData[4]); stringInfo->currentMove = gCurrentMove; stringInfo->lastMove = gLastUsedMove; stringInfo->lastItem = gLastUsedItem; @@ -1166,386 +1164,386 @@ void EmitPrintStringPlayerOnly(u8 bufferId, u16 stringID) stringInfo->textBuffs[1][i] = gBattleTextBuff2[i]; stringInfo->textBuffs[2][i] = gBattleTextBuff3[i]; } - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); } void EmitChooseAction(u8 bufferId, u8 arg1, u16 arg2) { - gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEACTION; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = arg2; - gBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEACTION; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = arg2; + sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitUnknownYesNoBox(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_UNKNOWNYESNOBOX; - gBattleBuffersTransferData[1] = CONTROLLER_UNKNOWNYESNOBOX; - gBattleBuffersTransferData[2] = CONTROLLER_UNKNOWNYESNOBOX; - gBattleBuffersTransferData[3] = CONTROLLER_UNKNOWNYESNOBOX; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_UNKNOWNYESNOBOX; + sBattleBuffersTransferData[1] = CONTROLLER_UNKNOWNYESNOBOX; + sBattleBuffersTransferData[2] = CONTROLLER_UNKNOWNYESNOBOX; + sBattleBuffersTransferData[3] = CONTROLLER_UNKNOWNYESNOBOX; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitChooseMove(u8 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEMOVE; - gBattleBuffersTransferData[1] = isDoubleBattle; - gBattleBuffersTransferData[2] = NoPpNumber; - gBattleBuffersTransferData[3] = 0; + sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEMOVE; + sBattleBuffersTransferData[1] = isDoubleBattle; + sBattleBuffersTransferData[2] = NoPpNumber; + sBattleBuffersTransferData[3] = 0; for (i = 0; i < sizeof(*movePpData); i++) - gBattleBuffersTransferData[4 + i] = *((u8*)(movePpData) + i); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(*movePpData) + 4); + sBattleBuffersTransferData[4 + i] = *((u8*)(movePpData) + i); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(*movePpData) + 4); } void EmitChooseItem(u8 bufferId, u8 *arg1) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_OPENBAG; + sBattleBuffersTransferData[0] = CONTROLLER_OPENBAG; for (i = 0; i < 3; i++) - gBattleBuffersTransferData[1 + i] = arg1[i]; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[1 + i] = arg1[i]; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u8 abilityId, u8* arg4) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON; - gBattleBuffersTransferData[1] = caseId; - gBattleBuffersTransferData[2] = arg2; - gBattleBuffersTransferData[3] = abilityId; + sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON; + sBattleBuffersTransferData[1] = caseId; + sBattleBuffersTransferData[2] = arg2; + sBattleBuffersTransferData[3] = abilityId; for (i = 0; i < 3; i++) - gBattleBuffersTransferData[4 + i] = arg4[i]; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 8); // but only 7 bytes were written + sBattleBuffersTransferData[4 + i] = arg4[i]; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 8); // but only 7 bytes were written } void EmitCmd23(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_23; - gBattleBuffersTransferData[1] = CONTROLLER_23; - gBattleBuffersTransferData[2] = CONTROLLER_23; - gBattleBuffersTransferData[3] = CONTROLLER_23; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_23; + sBattleBuffersTransferData[1] = CONTROLLER_23; + sBattleBuffersTransferData[2] = CONTROLLER_23; + sBattleBuffersTransferData[3] = CONTROLLER_23; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } // why is the argument u16 if it's being cast to s16 anyway? void EmitHealthBarUpdate(u8 bufferId, u16 hpValue) { - gBattleBuffersTransferData[0] = CONTROLLER_HEALTHBARUPDATE; - gBattleBuffersTransferData[1] = 0; - gBattleBuffersTransferData[2] = (s16)hpValue; - gBattleBuffersTransferData[3] = ((s16)hpValue & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_HEALTHBARUPDATE; + sBattleBuffersTransferData[1] = 0; + sBattleBuffersTransferData[2] = (s16)hpValue; + sBattleBuffersTransferData[3] = ((s16)hpValue & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } // why is the argument u16 if it's being cast to s16 anyway? void EmitExpUpdate(u8 bufferId, u8 partyId, u16 expPoints) { - gBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE; - gBattleBuffersTransferData[1] = partyId; - gBattleBuffersTransferData[2] = (s16)expPoints; - gBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE; + sBattleBuffersTransferData[1] = partyId; + sBattleBuffersTransferData[2] = (s16)expPoints; + sBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitStatusIconUpdate(u8 bufferId, u32 status1, u32 status2) { - gBattleBuffersTransferData[0] = CONTROLLER_STATUSICONUPDATE; - gBattleBuffersTransferData[1] = status1; - gBattleBuffersTransferData[2] = (status1 & 0x0000FF00) >> 8; - gBattleBuffersTransferData[3] = (status1 & 0x00FF0000) >> 16; - gBattleBuffersTransferData[4] = (status1 & 0xFF000000) >> 24; - gBattleBuffersTransferData[5] = status2; - gBattleBuffersTransferData[6] = (status2 & 0x0000FF00) >> 8; - gBattleBuffersTransferData[7] = (status2 & 0x00FF0000) >> 16; - gBattleBuffersTransferData[8] = (status2 & 0xFF000000) >> 24; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 9); + sBattleBuffersTransferData[0] = CONTROLLER_STATUSICONUPDATE; + sBattleBuffersTransferData[1] = status1; + sBattleBuffersTransferData[2] = (status1 & 0x0000FF00) >> 8; + sBattleBuffersTransferData[3] = (status1 & 0x00FF0000) >> 16; + sBattleBuffersTransferData[4] = (status1 & 0xFF000000) >> 24; + sBattleBuffersTransferData[5] = status2; + sBattleBuffersTransferData[6] = (status2 & 0x0000FF00) >> 8; + sBattleBuffersTransferData[7] = (status2 & 0x00FF0000) >> 16; + sBattleBuffersTransferData[8] = (status2 & 0xFF000000) >> 24; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 9); } void EmitStatusAnimation(u8 bufferId, bool8 status2, u32 status) { - gBattleBuffersTransferData[0] = CONTROLLER_STATUSANIMATION; - gBattleBuffersTransferData[1] = status2; - gBattleBuffersTransferData[2] = status; - gBattleBuffersTransferData[3] = (status & 0x0000FF00) >> 8; - gBattleBuffersTransferData[4] = (status & 0x00FF0000) >> 16; - gBattleBuffersTransferData[5] = (status & 0xFF000000) >> 24; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 6); + sBattleBuffersTransferData[0] = CONTROLLER_STATUSANIMATION; + sBattleBuffersTransferData[1] = status2; + sBattleBuffersTransferData[2] = status; + sBattleBuffersTransferData[3] = (status & 0x0000FF00) >> 8; + sBattleBuffersTransferData[4] = (status & 0x00FF0000) >> 16; + sBattleBuffersTransferData[5] = (status & 0xFF000000) >> 24; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 6); } void EmitStatusXor(u8 bufferId, u8 b) { - gBattleBuffersTransferData[0] = CONTROLLER_STATUSXOR; - gBattleBuffersTransferData[1] = b; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_STATUSXOR; + sBattleBuffersTransferData[1] = b; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void EmitDataTransfer(u8 bufferId, u16 size, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_DATATRANSFER; - gBattleBuffersTransferData[1] = CONTROLLER_DATATRANSFER; - gBattleBuffersTransferData[2] = size; - gBattleBuffersTransferData[3] = (size & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_DATATRANSFER; + sBattleBuffersTransferData[1] = CONTROLLER_DATATRANSFER; + sBattleBuffersTransferData[2] = size; + sBattleBuffersTransferData[3] = (size & 0xFF00) >> 8; for (i = 0; i < size; i++) - gBattleBuffersTransferData[4 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 4); + sBattleBuffersTransferData[4 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 4); } void EmitDMA3Transfer(u8 bufferId, void *dst, u16 size, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_DMA3TRANSFER; - gBattleBuffersTransferData[1] = (u32)(dst); - gBattleBuffersTransferData[2] = ((u32)(dst) & 0x0000FF00) >> 8; - gBattleBuffersTransferData[3] = ((u32)(dst) & 0x00FF0000) >> 16; - gBattleBuffersTransferData[4] = ((u32)(dst) & 0xFF000000) >> 24; - gBattleBuffersTransferData[5] = size; - gBattleBuffersTransferData[6] = (size & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_DMA3TRANSFER; + sBattleBuffersTransferData[1] = (u32)(dst); + sBattleBuffersTransferData[2] = ((u32)(dst) & 0x0000FF00) >> 8; + sBattleBuffersTransferData[3] = ((u32)(dst) & 0x00FF0000) >> 16; + sBattleBuffersTransferData[4] = ((u32)(dst) & 0xFF000000) >> 24; + sBattleBuffersTransferData[5] = size; + sBattleBuffersTransferData[6] = (size & 0xFF00) >> 8; for (i = 0; i < size; i++) - gBattleBuffersTransferData[7 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 7); + sBattleBuffersTransferData[7 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 7); } void EmitPlayBGM(u8 bufferId, u16 songId, void *unusedDumbDataParameter) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_31; - gBattleBuffersTransferData[1] = songId; - gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_31; + sBattleBuffersTransferData[1] = songId; + sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; for (i = 0; i < songId; i++) // ???? - gBattleBuffersTransferData[3 + i] = *(u8*)(unusedDumbDataParameter++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, songId + 3); + sBattleBuffersTransferData[3 + i] = *(u8*)(unusedDumbDataParameter++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, songId + 3); } void EmitCmd32(u8 bufferId, u16 size, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_32; - gBattleBuffersTransferData[1] = size; - gBattleBuffersTransferData[2] = (size & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_32; + sBattleBuffersTransferData[1] = size; + sBattleBuffersTransferData[2] = (size & 0xFF00) >> 8; for (i = 0; i < size; i++) - gBattleBuffersTransferData[3 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 3); + sBattleBuffersTransferData[3 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 3); } void EmitTwoReturnValues(u8 bufferId, u8 arg1, u16 arg2) { - gBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = arg2; - gBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = arg2; + sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitChosenMonReturnValue(u8 bufferId, u8 b, u8 *c) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_CHOSENMONRETURNVALUE; - gBattleBuffersTransferData[1] = b; + sBattleBuffersTransferData[0] = CONTROLLER_CHOSENMONRETURNVALUE; + sBattleBuffersTransferData[1] = b; for (i = 0; i < 3; i++) - gBattleBuffersTransferData[2 + i] = c[i]; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 5); + sBattleBuffersTransferData[2 + i] = c[i]; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 5); } void EmitOneReturnValue(u8 bufferId, u16 arg1) { - gBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = (arg1 & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = (arg1 & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitOneReturnValue_Duplicate(u8 bufferId, u16 b) { - gBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE_DUPLICATE; - gBattleBuffersTransferData[1] = b; - gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE_DUPLICATE; + sBattleBuffersTransferData[1] = b; + sBattleBuffersTransferData[2] = (b & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitCmd37(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_37; - gBattleBuffersTransferData[1] = CONTROLLER_37; - gBattleBuffersTransferData[2] = CONTROLLER_37; - gBattleBuffersTransferData[3] = CONTROLLER_37; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_37; + sBattleBuffersTransferData[1] = CONTROLLER_37; + sBattleBuffersTransferData[2] = CONTROLLER_37; + sBattleBuffersTransferData[3] = CONTROLLER_37; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitCmd38(u8 bufferId, u8 b) { - gBattleBuffersTransferData[0] = CONTROLLER_38; - gBattleBuffersTransferData[1] = b; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_38; + sBattleBuffersTransferData[1] = b; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void EmitCmd39(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_39; - gBattleBuffersTransferData[1] = CONTROLLER_39; - gBattleBuffersTransferData[2] = CONTROLLER_39; - gBattleBuffersTransferData[3] = CONTROLLER_39; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_39; + sBattleBuffersTransferData[1] = CONTROLLER_39; + sBattleBuffersTransferData[2] = CONTROLLER_39; + sBattleBuffersTransferData[3] = CONTROLLER_39; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitCmd40(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_40; - gBattleBuffersTransferData[1] = CONTROLLER_40; - gBattleBuffersTransferData[2] = CONTROLLER_40; - gBattleBuffersTransferData[3] = CONTROLLER_40; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_40; + sBattleBuffersTransferData[1] = CONTROLLER_40; + sBattleBuffersTransferData[2] = CONTROLLER_40; + sBattleBuffersTransferData[3] = CONTROLLER_40; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitHitAnimation(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_HITANIMATION; - gBattleBuffersTransferData[1] = CONTROLLER_HITANIMATION; - gBattleBuffersTransferData[2] = CONTROLLER_HITANIMATION; - gBattleBuffersTransferData[3] = CONTROLLER_HITANIMATION; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_HITANIMATION; + sBattleBuffersTransferData[1] = CONTROLLER_HITANIMATION; + sBattleBuffersTransferData[2] = CONTROLLER_HITANIMATION; + sBattleBuffersTransferData[3] = CONTROLLER_HITANIMATION; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitCmd42(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_42; - gBattleBuffersTransferData[1] = CONTROLLER_42; - gBattleBuffersTransferData[2] = CONTROLLER_42; - gBattleBuffersTransferData[3] = CONTROLLER_42; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_42; + sBattleBuffersTransferData[1] = CONTROLLER_42; + sBattleBuffersTransferData[2] = CONTROLLER_42; + sBattleBuffersTransferData[3] = CONTROLLER_42; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitEffectivenessSound(u8 bufferId, u16 songId) { - gBattleBuffersTransferData[0] = CONTROLLER_EFFECTIVENESSSOUND; - gBattleBuffersTransferData[1] = songId; - gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_EFFECTIVENESSSOUND; + sBattleBuffersTransferData[1] = songId; + sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitPlayFanfareOrBGM(u8 bufferId, u16 songId, bool8 playBGM) { - gBattleBuffersTransferData[0] = CONTROLLER_PLAYFANFAREORBGM; - gBattleBuffersTransferData[1] = songId; - gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = playBGM; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_PLAYFANFAREORBGM; + sBattleBuffersTransferData[1] = songId; + sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = playBGM; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitFaintingCry(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_FAINTINGCRY; - gBattleBuffersTransferData[1] = CONTROLLER_FAINTINGCRY; - gBattleBuffersTransferData[2] = CONTROLLER_FAINTINGCRY; - gBattleBuffersTransferData[3] = CONTROLLER_FAINTINGCRY; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_FAINTINGCRY; + sBattleBuffersTransferData[1] = CONTROLLER_FAINTINGCRY; + sBattleBuffersTransferData[2] = CONTROLLER_FAINTINGCRY; + sBattleBuffersTransferData[3] = CONTROLLER_FAINTINGCRY; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitIntroSlide(u8 bufferId, u8 terrainId) { - gBattleBuffersTransferData[0] = CONTROLLER_INTROSLIDE; - gBattleBuffersTransferData[1] = terrainId; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_INTROSLIDE; + sBattleBuffersTransferData[1] = terrainId; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void EmitIntroTrainerBallThrow(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_INTROTRAINERBALLTHROW; - gBattleBuffersTransferData[1] = CONTROLLER_INTROTRAINERBALLTHROW; - gBattleBuffersTransferData[2] = CONTROLLER_INTROTRAINERBALLTHROW; - gBattleBuffersTransferData[3] = CONTROLLER_INTROTRAINERBALLTHROW; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_INTROTRAINERBALLTHROW; + sBattleBuffersTransferData[1] = CONTROLLER_INTROTRAINERBALLTHROW; + sBattleBuffersTransferData[2] = CONTROLLER_INTROTRAINERBALLTHROW; + sBattleBuffersTransferData[3] = CONTROLLER_INTROTRAINERBALLTHROW; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitDrawPartyStatusSummary(u8 bufferId, struct HpAndStatus* hpAndStatus, u8 arg2) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; - gBattleBuffersTransferData[1] = arg2 & 0x7F; - gBattleBuffersTransferData[2] = (arg2 & 0x80) >> 7; - gBattleBuffersTransferData[3] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; + sBattleBuffersTransferData[0] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; + sBattleBuffersTransferData[1] = arg2 & 0x7F; + sBattleBuffersTransferData[2] = (arg2 & 0x80) >> 7; + sBattleBuffersTransferData[3] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; for (i = 0; i < (s32)(sizeof(struct HpAndStatus) * 6); i++) - gBattleBuffersTransferData[4 + i] = *(i + (u8*)(hpAndStatus)); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct HpAndStatus) * 6 + 4); + sBattleBuffersTransferData[4 + i] = *(i + (u8*)(hpAndStatus)); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct HpAndStatus) * 6 + 4); } void EmitCmd49(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_49; - gBattleBuffersTransferData[1] = CONTROLLER_49; - gBattleBuffersTransferData[2] = CONTROLLER_49; - gBattleBuffersTransferData[3] = CONTROLLER_49; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_49; + sBattleBuffersTransferData[1] = CONTROLLER_49; + sBattleBuffersTransferData[2] = CONTROLLER_49; + sBattleBuffersTransferData[3] = CONTROLLER_49; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitCmd50(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_50; - gBattleBuffersTransferData[1] = CONTROLLER_50; - gBattleBuffersTransferData[2] = CONTROLLER_50; - gBattleBuffersTransferData[3] = CONTROLLER_50; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_50; + sBattleBuffersTransferData[1] = CONTROLLER_50; + sBattleBuffersTransferData[2] = CONTROLLER_50; + sBattleBuffersTransferData[3] = CONTROLLER_50; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitSpriteInvisibility(u8 bufferId, bool8 isInvisible) { - gBattleBuffersTransferData[0] = CONTROLLER_SPRITEINVISIBILITY; - gBattleBuffersTransferData[1] = isInvisible; - gBattleBuffersTransferData[2] = CONTROLLER_SPRITEINVISIBILITY; - gBattleBuffersTransferData[3] = CONTROLLER_SPRITEINVISIBILITY; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_SPRITEINVISIBILITY; + sBattleBuffersTransferData[1] = isInvisible; + sBattleBuffersTransferData[2] = CONTROLLER_SPRITEINVISIBILITY; + sBattleBuffersTransferData[3] = CONTROLLER_SPRITEINVISIBILITY; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitBattleAnimation(u8 bufferId, u8 animationId, u16 argument) { - gBattleBuffersTransferData[0] = CONTROLLER_BATTLEANIMATION; - gBattleBuffersTransferData[1] = animationId; - gBattleBuffersTransferData[2] = argument; - gBattleBuffersTransferData[3] = (argument & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_BATTLEANIMATION; + sBattleBuffersTransferData[1] = animationId; + sBattleBuffersTransferData[2] = argument; + sBattleBuffersTransferData[3] = (argument & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void EmitLinkStandbyMsg(u8 bufferId, u8 arg1, bool32 arg2) { bool8 arg2_ = arg2; - gBattleBuffersTransferData[0] = CONTROLLER_LINKSTANDBYMSG; - gBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[0] = CONTROLLER_LINKSTANDBYMSG; + sBattleBuffersTransferData[1] = arg1; if (arg2_) - gBattleBuffersTransferData[3] = gBattleBuffersTransferData[2] = sub_81850DC(&gBattleBuffersTransferData[4]); + sBattleBuffersTransferData[3] = sBattleBuffersTransferData[2] = sub_81850DC(&sBattleBuffersTransferData[4]); else - gBattleBuffersTransferData[3] = gBattleBuffersTransferData[2] = 0; + sBattleBuffersTransferData[3] = sBattleBuffersTransferData[2] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, gBattleBuffersTransferData[2] + 4); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sBattleBuffersTransferData[2] + 4); } void EmitResetActionMoveSelection(u8 bufferId, u8 caseId) { - gBattleBuffersTransferData[0] = CONTROLLER_RESETACTIONMOVESELECTION; - gBattleBuffersTransferData[1] = caseId; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_RESETACTIONMOVESELECTION; + sBattleBuffersTransferData[1] = caseId; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void EmitCmd55(u8 bufferId, u8 arg1) { - gBattleBuffersTransferData[0] = CONTROLLER_55; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = gSaveBlock2Ptr->field_CA9_b; - gBattleBuffersTransferData[3] = gSaveBlock2Ptr->field_CA9_b; - gBattleBuffersTransferData[5] = gBattleBuffersTransferData[4] = sub_81850DC(&gBattleBuffersTransferData[6]); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, gBattleBuffersTransferData[4] + 6); + sBattleBuffersTransferData[0] = CONTROLLER_55; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = gSaveBlock2Ptr->field_CA9_b; + sBattleBuffersTransferData[3] = gSaveBlock2Ptr->field_CA9_b; + sBattleBuffersTransferData[5] = sBattleBuffersTransferData[4] = sub_81850DC(&sBattleBuffersTransferData[6]); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sBattleBuffersTransferData[4] + 6); } diff --git a/src/egg_hatch.c b/src/egg_hatch.c index 13c088883..a6f02ea23 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -58,20 +58,14 @@ extern const u8 gText_NickHatchPrompt[]; extern u8* GetMonNick(struct Pokemon* mon, u8* dst); extern u8* GetBoxMonNick(struct BoxPokemon* boxMon, u8* dst); extern u8 sav1_map_get_name(void); -extern s8 sub_8198C58(void); extern void TVShowConvertInternationalString(u8* str1, u8* str2, u8); extern void sub_806A068(u16, u8); extern void fade_screen(u8, u8); extern void overworld_free_bg_tilemaps(void); extern void sub_80AF168(void); -extern void AllocateMonSpritesGfx(void); -extern void FreeMonSpritesGfx(void); extern void remove_some_task(void); -extern void reset_temp_tile_data_buffers(void); extern void c2_exit_to_overworld_2_switch(void); extern void play_some_sound(void); -extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode); -extern void CreateYesNoMenu(const struct WindowTemplate*, u16, u8, u8); extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback); extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor* colors, s8 speed, u8 *str); extern u16 sub_80D22D0(void); diff --git a/src/evolution_scene.c b/src/evolution_scene.c index 68731a14a..03b9dec3f 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -75,9 +75,6 @@ extern const u8 gText_PkmnStoppedEvolving[]; extern const u8 gText_EllipsisQuestionMark[]; extern const u8 gText_CommunicationStandby5[]; -extern void copy_decompressed_tile_data_to_vram_autofree(u8 arg0, const void *arg1, bool32 arg2, u16 arg3, u8 arg4); -extern u32 sub_80391E0(u8, u8); -extern void SpriteCallbackDummy_2(struct Sprite *sprite); extern void sub_80356D0(void); extern void sub_807B154(void); extern void sub_806A068(u16, u8); @@ -405,7 +402,7 @@ static void CB2_TradeEvolutionSceneLoadGraphics(void) } break; case 6: - if (gLinkVSyncDisabled) + if (gWirelessCommType) { sub_800E0E8(); sub_800DFB4(0, 0); @@ -1188,7 +1185,7 @@ static void Task_TradeEvolutionScene(u8 taskID) case 5: if (!gPaletteFade.active) { - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E084(); Free(GetBgTilemapBuffer(3)); diff --git a/src/link.c b/src/link.c index ae2cd1992..23ebdc01a 100644 --- a/src/link.c +++ b/src/link.c @@ -1,6 +1,33 @@ // Includes #include "global.h" +#include "m4a.h" +#include "malloc.h" +#include "reset_save_heap.h" +#include "save.h" +#include "bg.h" +#include "window.h" +#include "librfu.h" +#include "rng.h" +#include "decompress.h" +#include "string_util.h" +#include "event_data.h" +#include "item_menu.h" +#include "overworld.h" +#include "gpu_regs.h" +#include "palette.h" +#include "task.h" +#include "unknown_task.h" +#include "menu.h" +#include "new_menu_helpers.h" +#include "text.h" +#include "strings.h" +#include "songs.h" +#include "sound.h" +#include "trade.h" +#include "battle.h" +#include "link_rfu.h" +#include "link.h" // Static type declarations @@ -8,7 +35,7 @@ struct BlockTransfer { u16 pos; u16 size; - void *src; + const u8 *src; bool8 active; u8 multiplayerId; }; @@ -23,34 +50,2240 @@ struct LinkTestBGInfo // Static RAM declarations -IWRAM_DATA struct BlockTransfer gUnknown_03000D10; +IWRAM_DATA struct BlockTransfer sBlockSend; IWRAM_DATA u32 link_c_unused_03000d1c; -IWRAM_DATA struct BlockTransfer gUnknown_03000D20[4]; -IWRAM_DATA u32 gUnknown_03000D50; +IWRAM_DATA struct BlockTransfer sBlockRecv[MAX_LINK_PLAYERS]; +IWRAM_DATA u32 sBlockSendDelayCounter; IWRAM_DATA u32 gUnknown_03000D54; IWRAM_DATA u8 gUnknown_03000D58; -IWRAM_DATA u32 gUnknown_03000D5C; +IWRAM_DATA u32 sPlayerDataExchangeStatus; IWRAM_DATA u32 gUnknown_03000D60; -IWRAM_DATA u8 gUnknown_03000D64[4]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D68[4]; -IWRAM_DATA u8 gUnknown_03000D6C; +IWRAM_DATA u8 sLinkTestLastBlockSendPos; +ALIGNED() IWRAM_DATA u8 sLinkTestLastBlockRecvPos[MAX_LINK_PLAYERS]; +IWRAM_DATA u8 sNumVBlanksWithoutSerialIntr; IWRAM_DATA bool8 gUnknown_03000D6D; -IWRAM_DATA u16 gUnknown_03000D6E; +IWRAM_DATA u16 sSendNonzeroCheck; IWRAM_DATA u16 gUnknown_03000D70; IWRAM_DATA u8 gUnknown_03000D72; -IWRAM_DATA u8 gUnknown_03000D73; -IWRAM_DATA u8 gUnknown_03000D74[4]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D78[8]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D80[16]; -IWRAM_DATA u16 gUnknown_03000D90[8]; -IWRAM_DATA u32 gUnknown_03000DA0; -IWRAM_DATA u32 gUnknown_03000DA4; -IWRAM_DATA void *gUnknown_03000DA8; -IWRAM_DATA void *gUnknown_03000DAC; -IWRAM_DATA bool32 gUnknown_03000DB0; +IWRAM_DATA u8 sHandshakePlayerCount; +IWRAM_DATA u8 gUnknown_03000D74; + +u16 gLinkPartnersHeldKeys[6]; +u32 gLinkDebugSeed; +struct LinkPlayerBlock gLocalLinkPlayerBlock; +bool8 gLinkErrorOccurred; +u32 gLinkDebugFlags; +u32 gFiller_03003074; +bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS]; +u8 gBlockReceivedStatus[MAX_LINK_PLAYERS]; +u32 gFiller_03003080; +u16 gLinkHeldKeys; +u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH]; +u32 gLinkStatus; +bool8 gUnknown_030030E4; +bool8 gUnknown_030030E8; +bool8 gUnknown_030030EC[MAX_LINK_PLAYERS]; +bool8 gUnknown_030030F0[MAX_LINK_PLAYERS]; +u16 gUnknown_030030F4; +u8 gSuppressLinkErrorMessage; +bool8 gWirelessCommType; +bool8 gSavedLinkPlayerCount; +u16 gSendCmd[CMD_LENGTH]; +u8 gSavedMultiplayerId; +bool8 gReceivedRemoteLinkPlayers; +struct LinkTestBGInfo gLinkTestBGInfo; +void (*gLinkCallback)(void); +u8 gShouldAdvanceLinkState; +u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS]; +u8 gBlockRequestType; +u32 gFiller_03003154; +u32 gFiller_03003158; +u32 gFiller_0300315c; +u8 gLastSendQueueCount; +struct Link gLink; +u8 gLastRecvQueueCount; +u16 gLinkSavedIme; +u32 gFiller_03004138; +u32 gFiller_0300413C; + +EWRAM_DATA u8 gLinkTestDebugValuesEnabled = 0; +EWRAM_DATA u8 gUnknown_020223BD = 0; +EWRAM_DATA u32 gUnknown_020223C0 = 0; +EWRAM_DATA u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2] = {}; +EWRAM_DATA u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE] = {}; +EWRAM_DATA bool8 gLinkOpen = FALSE; +EWRAM_DATA u16 gLinkType = 0; +EWRAM_DATA u16 gLinkTimeOutCounter = 0; +EWRAM_DATA struct LinkPlayer gLocalLinkPlayer = {}; +EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS] = {}; +EWRAM_DATA struct LinkPlayer gSavedLinkPlayers[MAX_RFU_PLAYERS] = {}; +EWRAM_DATA struct { + u32 status; + u8 lastRecvQueueCount; + u8 lastSendQueueCount; + u8 unk_06; +} sLinkErrorBuffer = {}; +EWRAM_DATA u16 gUnknown_02022B08 = 0; +EWRAM_DATA void *gUnknown_02022B0C = NULL; // Static ROM declarations +static void InitLocalLinkPlayer(void); +static void sub_80096BC(void); +static void CB2_LinkTest(void); +static void ProcessRecvCmds(u8 unused); +static void sub_8009F70(void); +static void ResetBlockSend(void); +static bool32 InitBlockSend(const void *src, size_t size); +static void LinkCB_BlockSendBegin(void); +static void LinkCB_BlockSend(void); +static void LinkCB_BlockSendEnd(void); +static void SetBlockReceivedFlag(u8 who); +static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size); +static void LinkTest_prnthex(u32 pos, u8 a0, u8 a1, u8 a2); +static void LinkCB_RequestPlayerDataExchange(void); +static void Task_PrintTestData(u8 taskId); +static void sub_800AC80(void); +static void sub_800ACAC(void); +static void sub_800AD5C(void); +static void sub_800AD88(void); +static void sub_800AE30(void); +static void sub_800AE5C(void); +static void CheckErrorStatus(void); +static void CB2_PrintErrorMessage(void); +static bool8 IsSioMultiMaster(void); +static void sub_800B4A4(void); +static void DisableSerial(void); +static void EnableSerial(void); +static void CheckMasterOrSlave(void); +static void InitTimer(void); +static void EnqueueSendCmd(u16 *sendCmd); +static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]); +static void StartTransfer(void); +static bool8 DoHandshake(void); +void DoRecv(void); +void DoSend(void); +void StopTimer(void); +void SendRecvDone(void); + // .rodata +ALIGNED(4) const u16 gWirelessLinkDisplayPal[] = INCBIN_U16("graphics/interface/wireless_link_display.gbapal"); +const u8 gWirelessLinkDisplayGfx[] = INCBIN_U8("graphics/interface/wireless_link_display.4bpp.lz"); +const u8 gWirelessLinkDisplayTilemap[] = INCBIN_U8("graphics/interface/wireless_link_display.bin.lz"); +const u16 gLinkTestDigitsPal[] = INCBIN_U16("graphics/interface/link_test_digits.gbapal"); +const u16 gLinkTestDigitsGfx[] = INCBIN_U16("graphics/interface/link_test_digits.4bpp"); +const u8 unkstring_82ed160[] = _("{HIGHLIGHT TRANSPARENT}{COLOR WHITE}"); +const u16 g2BlankTilesGfx[] = INCBIN_U16("graphics/interface/blank_1x2.4bpp"); +const struct BlockRequest gUnknown_082ED1A8[] = { + {gBlockSendBuffer, 200}, + {gBlockSendBuffer, 200}, + {gBlockSendBuffer, 100}, + {gBlockSendBuffer, 220}, + {gBlockSendBuffer, 40} +}; +const u8 gBGControlRegs[] = { + REG_OFFSET_BG0CNT, + REG_OFFSET_BG1CNT, + REG_OFFSET_BG2CNT, + REG_OFFSET_BG3CNT +}; +const char gASCIIGameFreakInc[] = "GameFreak inc."; +const char gASCIITestPrint[] = "TEST PRINT\nP0\nP1\nP2\nP3"; +const struct BgTemplate gUnknown_082ED1FC[] = { + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .priority = 0 + }, { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 8, + .priority = 1 + } +}; +const struct WindowTemplate gUnknown_082ED204[] = { + {0x00, 0x00, 0x00, 0x1E, 0x05, 0x0F, 0x0002}, + {0x00, 0x00, 0x06, 0x1E, 0x07, 0x0F, 0x0098}, + {0x00, 0x00, 0x0D, 0x1E, 0x07, 0x0F, 0x016A}, + DUMMY_WIN_TEMPLATE +}; +const u8 gUnknown_082ED224[] = { + 0x00, 0x01, 0x02, 0x00, + 0xff, 0xfe, 0xff, 0x00 +}; + // .text + +bool8 sub_80093CC(void) +{ + sub_800B488(); + sub_800E700(); + if (sub_800BEC0() == 0x8001) + { + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + return TRUE; + } + sub_800B4A4(); + CloseLink(); + RestoreSerialTimer3IntrHandlers(); + return FALSE; +} + +void Task_DestroySelf(u8 taskId) +{ + DestroyTask(taskId); +} + +static void InitLinkTestBG(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock, u16 a4) +{ + LoadPalette(gLinkTestDigitsPal, paletteNum * 16, 0x20); + DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(charBaseBlock) + (16 * a4), sizeof gLinkTestDigitsGfx); + gLinkTestBGInfo.screenBaseBlock = screenBaseBlock; + gLinkTestBGInfo.paletteNum = paletteNum; + gLinkTestBGInfo.dummy_8 = a4; + switch (bgNum) + { + case 1: + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock)); + break; + case 2: + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock)); + break; + case 3: + SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock)); + break; + } + SetGpuReg(REG_OFFSET_BG0HOFS + bgNum * 4, 0); + SetGpuReg(REG_OFFSET_BG0VOFS + bgNum * 4, 0); +} + +void sub_80094EC(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock) +{ + LoadPalette(gLinkTestDigitsPal, paletteNum * 16, 0x20); + DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(charBaseBlock), sizeof gLinkTestDigitsGfx); + gLinkTestBGInfo.screenBaseBlock = screenBaseBlock; + gLinkTestBGInfo.paletteNum = paletteNum; + gLinkTestBGInfo.dummy_8 = 0; + SetGpuReg(gBGControlRegs[bgNum], BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_CHARBASE(charBaseBlock)); +} + +void LinkTestScreen(void) +{ + int i; + + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + SetVBlankCallback(sub_80096BC); + ResetBlockSend(); + gLinkType = 0x1111; + OpenLink(); + SeedRng(gMain.vblankCounter2); + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + gSaveBlock2Ptr->playerTrainerId[i] = Random() % 256; + } + InitLinkTestBG(0, 2, 4, 0, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); + CreateTask(Task_DestroySelf, 0); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + gUnknown_03000D60 = 0; + InitLocalLinkPlayer(); + CreateTask(Task_PrintTestData, 0); + SetMainCallback2(CB2_LinkTest); +} + +void sub_8009628(u8 a0) +{ + gLocalLinkPlayer.lp_field_18 = a0; +} + +static void InitLocalLinkPlayer(void) +{ + gLocalLinkPlayer.trainerId = gSaveBlock2Ptr->playerTrainerId[0] | (gSaveBlock2Ptr->playerTrainerId[1] << 8) | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[3] << 24); + StringCopy(gLocalLinkPlayer.name, gSaveBlock2Ptr->playerName); + gLocalLinkPlayer.gender = gSaveBlock2Ptr->playerGender; + gLocalLinkPlayer.linkType = gLinkType; + gLocalLinkPlayer.language = gGameLanguage; + gLocalLinkPlayer.version = gGameVersion + 0x4000; + gLocalLinkPlayer.lp_field_2 = 0x8000; + gLocalLinkPlayer.name[8] = IsNationalPokedexEnabled(); + if (FlagGet(FLAG_SYS_UNKNOWN_87F)) + { + gLocalLinkPlayer.name[8] |= 0x10; + } +} + +static void sub_80096BC(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void InitLink(void) +{ + int i; + + for (i = 0; i < 8; i ++) + { + gSendCmd[i] = 0xefff; + } + gLinkOpen = TRUE; + EnableSerial(); +} + +static void Task_TriggerHandshake(u8 taskId) +{ + if (++ gTasks[taskId].data[0] == 5) + { + gShouldAdvanceLinkState = 1; + DestroyTask(taskId); + } +} + +void OpenLink(void) +{ + int i; + + if (!gWirelessCommType) + { + ResetSerial(); + InitLink(); + gLinkCallback = LinkCB_RequestPlayerDataExchange; + gLinkVSyncDisabled = FALSE; + gLinkErrorOccurred = FALSE; + gSuppressLinkErrorMessage = FALSE; + ResetBlockReceivedFlags(); + ResetBlockSend(); + gUnknown_03000D54 = 0; + gUnknown_030030E8 = FALSE; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = 0; + CreateTask(Task_TriggerHandshake, 2); + } + else + { + sub_800E700(); + } + gReceivedRemoteLinkPlayers = 0; + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + gRemoteLinkPlayersNotReceived[i] = TRUE; + gUnknown_030030F0[i] = FALSE; + gUnknown_030030EC[i] = FALSE; + } +} + +void CloseLink(void) +{ + gReceivedRemoteLinkPlayers = FALSE; + if (gWirelessCommType) + { + sub_800EDD4(); + } + gLinkOpen = FALSE; + DisableSerial(); +} + +static void TestBlockTransfer(u8 nothing, u8 is, u8 used) +{ + u8 i; + u8 status; + + if (sLinkTestLastBlockSendPos != sBlockSend.pos) + { + LinkTest_prnthex(sBlockSend.pos, 2, 3, 2); + sLinkTestLastBlockSendPos = sBlockSend.pos; + } + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + if (sLinkTestLastBlockRecvPos[i] != sBlockRecv[i].pos) + { + LinkTest_prnthex(sBlockRecv[i].pos, 2, i + 4, 2); + sLinkTestLastBlockRecvPos[i] = sBlockRecv[i].pos; + } + } + status = GetBlockReceivedStatus(); + if (status == 0xF) // 0b1111 + { + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + if ((status >> i) & 1) + { + gLinkTestBlockChecksums[i] = LinkTestCalcBlockChecksum(gBlockRecvBuffer[i], sBlockRecv[i].size); + ResetBlockReceivedFlag(i); + if (gLinkTestBlockChecksums[i] != 0x0342) + { + gLinkTestDebugValuesEnabled = FALSE; + gUnknown_020223BD = FALSE; + } + } + } + } +} + +static void LinkTestProcessKeyInput(void) +{ + if (gMain.newKeys & A_BUTTON) + { + gShouldAdvanceLinkState = 1; + } + if (gMain.heldKeys & B_BUTTON) + { + InitBlockSend(gHeap + 0x4000, 0x00002004); + } + if (gMain.newKeys & L_BUTTON) + { + BeginNormalPaletteFade(-1, 0, 16, 0, 2); + } + if (gMain.newKeys & START_BUTTON) + { + SetSuppressLinkErrorMessage(TRUE); + } + if (gMain.newKeys & R_BUTTON) + { + TrySavingData(1); + } + if (gMain.newKeys & SELECT_BUTTON) + { + sub_800AC34(); + } + if (gLinkTestDebugValuesEnabled) + { + SetLinkDebugValues(gMain.vblankCounter2, gLinkCallback ? gLinkVSyncDisabled : gLinkVSyncDisabled | 0x10); + } +} + +static void CB2_LinkTest(void) +{ + LinkTestProcessKeyInput(); + TestBlockTransfer(1, 1, 0); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +u16 LinkMain2(const u16 *heldKeys) +{ + u8 i; + + if (!gLinkOpen) + { + return 0; + } + for (i = 0; i < 8; i ++) + { + gSendCmd[i] = 0; + } + gLinkHeldKeys = *heldKeys; + if (gLinkStatus & LINK_STAT_CONN_ESTABLISHED) + { + ProcessRecvCmds(SIO_MULTI_CNT->id); + if (gLinkCallback != NULL) + { + gLinkCallback(); + } + CheckErrorStatus(); + } + return gLinkStatus; +} + +static void HandleReceiveRemoteLinkPlayer(u8 who) +{ + int i; + int count; + + count = 0; + gRemoteLinkPlayersNotReceived[who] = FALSE; + for (i = 0; i < GetLinkPlayerCount_2(); i ++) + { + count += gRemoteLinkPlayersNotReceived[i]; + } + if (count == 0 && gReceivedRemoteLinkPlayers == 0) + { + gReceivedRemoteLinkPlayers = 1; + } +} + +static void ProcessRecvCmds(u8 unused) +{ + u16 i; + + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + gLinkPartnersHeldKeys[i] = 0; + if (gRecvCmds[i][0] == 0) + { + continue; + } + switch (gRecvCmds[i][0]) + { + case LINKCMD_SEND_LINK_TYPE: + { + struct LinkPlayerBlock *block; + + InitLocalLinkPlayer(); + block = &gLocalLinkPlayerBlock; + block->linkPlayer = gLocalLinkPlayer; + memcpy(block->magic1, gASCIIGameFreakInc, sizeof(block->magic1) - 1); + memcpy(block->magic2, gASCIIGameFreakInc, sizeof(block->magic2) - 1); + InitBlockSend(block, sizeof(*block)); + break; + } + case LINKCMD_SEND_HELD_KEYS: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; + break; + case LINKCMD_0x5555: + gUnknown_030030E8 = TRUE; + break; + case LINKCMD_0x5566: + gUnknown_030030E8 = TRUE; + break; + case LINKCMD_INIT_BLOCK: + { + struct BlockTransfer *blockRecv; + + blockRecv = &sBlockRecv[i]; + blockRecv->pos = 0; + blockRecv->size = gRecvCmds[i][1]; + blockRecv->multiplayerId = gRecvCmds[i][2]; + break; + } + case LINKCMD_CONT_BLOCK: + { + if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE) + { + u16 *buffer; + u16 j; + + buffer = (u16 *)gDecompressionBuffer; + for (j = 0; j < CMD_LENGTH - 1; j ++) + { + buffer[(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1]; + } + } + else + { + u16 j; + + for (j = 0; j < CMD_LENGTH - 1; j ++) + { + gBlockRecvBuffer[i][(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1]; + } + } + + sBlockRecv[i].pos += (CMD_LENGTH - 1) * 2; + + if (sBlockRecv[i].pos >= sBlockRecv[i].size) + { + if (gRemoteLinkPlayersNotReceived[i] == TRUE) + { + struct LinkPlayerBlock *block; + struct LinkPlayer *linkPlayer; + + block = (struct LinkPlayerBlock *)&gBlockRecvBuffer[i]; + linkPlayer = &gLinkPlayers[i]; + *linkPlayer = block->linkPlayer; + if ((linkPlayer->version & 0xFF) == VERSION_RUBY || (linkPlayer->version & 0xFF) == VERSION_SAPPHIRE) + { + linkPlayer->name[10] = 0; + linkPlayer->name[9] = 0; + linkPlayer->name[8] = 0; + } + sub_800B524(linkPlayer); + if (strcmp(block->magic1, gASCIIGameFreakInc) != 0 + || strcmp(block->magic2, gASCIIGameFreakInc) != 0) + { + SetMainCallback2(CB2_LinkError); + } + else + { + HandleReceiveRemoteLinkPlayer(i); + } + } + else + { + SetBlockReceivedFlag(i); + } + } + } + break; + case LINKCMD_0x5FFF: + gUnknown_030030F0[i] = TRUE; + break; + case LINKCMD_0x2FFE: + gUnknown_030030EC[i] = TRUE; + break; + case LINKCMD_0xAAAA: + sub_800A418(); + break; + case LINKCMD_0xCCCC: + SendBlock(0, gUnknown_082ED1A8[gRecvCmds[i][1]].address, gUnknown_082ED1A8[gRecvCmds[i][1]].size); + break; + case LINKCMD_SEND_HELD_KEYS_2: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; + break; + } + } +} + +static void BuildSendCmd(u16 command) +{ + switch (command) + { + case LINKCMD_SEND_LINK_TYPE: + gSendCmd[0] = LINKCMD_SEND_LINK_TYPE; + gSendCmd[1] = gLinkType; + break; + case LINKCMD_0x2FFE: + gSendCmd[0] = LINKCMD_0x2FFE; + break; + case LINKCMD_SEND_HELD_KEYS: + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS; + gSendCmd[1] = gMain.heldKeys; + break; + case LINKCMD_0x5555: + gSendCmd[0] = LINKCMD_0x5555; + break; + case LINKCMD_0x6666: + gSendCmd[0] = LINKCMD_0x6666; + gSendCmd[1] = 0; + break; + case LINKCMD_0x7777: + { + u8 i; + + gSendCmd[0] = LINKCMD_0x7777; + for (i = 0; i < 5; i ++) + { + gSendCmd[i + 1] = 0xEE; + } + break; + } + case LINKCMD_INIT_BLOCK: + gSendCmd[0] = LINKCMD_INIT_BLOCK; + gSendCmd[1] = sBlockSend.size; + gSendCmd[2] = sBlockSend.multiplayerId + 0x80; + break; + case LINKCMD_0xAAAA: + gSendCmd[0] = LINKCMD_0xAAAA; + break; + case LINKCMD_0xAAAB: + gSendCmd[0] = LINKCMD_0xAAAB; + gSendCmd[1] = gSpecialVar_ItemId; + break; + case LINKCMD_0xCCCC: + gSendCmd[0] = LINKCMD_0xCCCC; + gSendCmd[1] = gBlockRequestType; + break; + case LINKCMD_0x5FFF: + gSendCmd[0] = LINKCMD_0x5FFF; + gSendCmd[1] = gUnknown_030030F4; + break; + case LINKCMD_0x5566: + gSendCmd[0] = LINKCMD_0x5566; + break; + case LINKCMD_SEND_HELD_KEYS_2: + if (gUnknown_03005DA8 == 0 || gLinkTransferringData) + { + break; + } + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2; + gSendCmd[1] = gUnknown_03005DA8; + break; + } +} + +void sub_8009F18(void) +{ + if (gWirelessCommType) + { + sub_800F804(); + } + gLinkCallback = sub_8009F70; +} + +bool32 sub_8009F3C(void) +{ + if (gWirelessCommType) + { + return sub_800F7E4(); + } + if (gLinkCallback == sub_8009F70) + { + return TRUE; + } + return FALSE; +} + +static void sub_8009F70(void) +{ + if (gReceivedRemoteLinkPlayers == TRUE) + { + BuildSendCmd(LINKCMD_SEND_HELD_KEYS_2); + } +} + +void ClearLinkCallback(void) +{ + if (gWirelessCommType) + { + Rfu_set_zero(); + } + else + { + gLinkCallback = NULL; + } +} + +void ClearLinkCallback_2(void) +{ + if (gWirelessCommType) + { + Rfu_set_zero(); + } + else + { + gLinkCallback = NULL; + } +} + +u8 GetLinkPlayerCount(void) +{ + if (gWirelessCommType) + { + return sub_80104F4(); + } + return EXTRACT_PLAYER_COUNT(gLinkStatus); +} + +static int sub_8009FF8(u32 version1, u32 version2) +{ + int i; + u8 nPlayers; + + nPlayers = GetLinkPlayerCount(); + for (i = 0; i < nPlayers; i ++) + { + if ((gLinkPlayers[i].version & 0xFF) == version1 || (gLinkPlayers[i].version & 0xFF) == version2) + { + return 1; + } + } + return -1; +} + +u32 sub_800A03C(void) +{ + return 2; +} + +bool32 sub_800A040(void) +{ + if (GetLinkPlayerCount() != 4 || sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) < 0) + { + return FALSE; + } + return TRUE; +} + +bool32 sub_800A064(void) +{ + if (sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) >= 0) + { + return TRUE; + } + return FALSE; +} + +bool32 sub_800A07C(void) +{ + int i; + + i = sub_8009FF8(VERSION_FIRE_RED, VERSION_LEAF_GREEN); + if (i >= 0 && gLinkPlayers[i].language == LANGUAGE_JAPANESE) + { + return TRUE; + } + return FALSE; +} + +void OpenLinkTimed(void) +{ + sPlayerDataExchangeStatus = EXCHANGE_NOT_STARTED; + gLinkTimeOutCounter = 0; + OpenLink(); +} + +u8 GetLinkPlayerDataExchangeStatusTimed(int lower, int upper) +{ + int i; + int count; + u32 index; + u8 cmpVal; + u32 linkType1; + u32 linkType2; + + count = 0; + if (gReceivedRemoteLinkPlayers == TRUE) + { + cmpVal = GetLinkPlayerCount_2(); + if (lower > cmpVal || cmpVal > upper) + { + sPlayerDataExchangeStatus = EXCHANGE_STAT_6; + return 6; + } + else + { + if (GetLinkPlayerCount() == 0) + { + gLinkErrorOccurred = TRUE; + CloseLink(); + } + for (i = 0, index = 0; i < GetLinkPlayerCount(); index ++, i ++) + { + if (gLinkPlayers[index].linkType == gLinkPlayers[0].linkType) + { + count ++; + } + } + if (count == GetLinkPlayerCount()) + { + if (gLinkPlayers[0].linkType == 0x1133) + { + switch (sub_807A728()) + { + case 1: + sPlayerDataExchangeStatus = EXCHANGE_STAT_4; + break; + case 2: + sPlayerDataExchangeStatus = EXCHANGE_STAT_5; + break; + case 0: + sPlayerDataExchangeStatus = EXCHANGE_COMPLETE; + break; + } + } + else + { + sPlayerDataExchangeStatus = EXCHANGE_COMPLETE; + } + } + else + { + sPlayerDataExchangeStatus = EXCHANGE_IN_PROGRESS; + linkType1 = gLinkPlayers[GetMultiplayerId()].linkType; + linkType2 = gLinkPlayers[GetMultiplayerId() ^ 1].linkType; + if ((linkType1 == 0x2266 && linkType2 == 0x2277) || (linkType1 == 0x2277 && linkType2 == 0x2266)) + { + gSpecialVar_0x8005 = 3; + } + } + } + } + else if (++ gLinkTimeOutCounter > 600) + { + sPlayerDataExchangeStatus = EXCHANGE_TIMED_OUT; + } + return sPlayerDataExchangeStatus; +} + +bool8 IsLinkPlayerDataExchangeComplete(void) +{ + u8 i; + u8 count; + bool8 retval; + + count = 0; + for (i = 0; i < GetLinkPlayerCount(); i ++) + { + if (gLinkPlayers[i].linkType == gLinkPlayers[0].linkType) + { + count ++; + } + } + if (count == GetLinkPlayerCount()) + { + retval = TRUE; + sPlayerDataExchangeStatus = EXCHANGE_COMPLETE; + } + else + { + retval = FALSE; + sPlayerDataExchangeStatus = EXCHANGE_IN_PROGRESS; + } + return retval; +} + +u32 GetLinkPlayerTrainerId(u8 who) +{ + return gLinkPlayers[who].trainerId; +} + +void ResetLinkPlayers(void) +{ + int i; + + for (i = 0; i <= MAX_LINK_PLAYERS; i ++) + { + gLinkPlayers[i] = (struct LinkPlayer){}; + } +} + +static void ResetBlockSend(void) +{ + sBlockSend.active = FALSE; + sBlockSend.pos = 0; + sBlockSend.size = 0; + sBlockSend.src = NULL; +} + +static bool32 InitBlockSend(const void *src, size_t size) +{ + if (sBlockSend.active) + { + return FALSE; + } + sBlockSend.multiplayerId = GetMultiplayerId(); + sBlockSend.active = TRUE; + sBlockSend.size = size; + sBlockSend.pos = 0; + if (size > 0x100) + { + sBlockSend.src = src; + } + else + { + if (src != gBlockSendBuffer) + { + memcpy(gBlockSendBuffer, src, size); + } + sBlockSend.src = gBlockSendBuffer; + } + BuildSendCmd(LINKCMD_INIT_BLOCK); + gLinkCallback = LinkCB_BlockSendBegin; + sBlockSendDelayCounter = 0; + return TRUE; +} + +static void LinkCB_BlockSendBegin(void) +{ + if (++ sBlockSendDelayCounter > 2) + { + gLinkCallback = LinkCB_BlockSend; + } +} + +static void LinkCB_BlockSend(void) +{ + int i; + const u8 *src; + + src = sBlockSend.src; + gSendCmd[0] = LINKCMD_CONT_BLOCK; + for (i = 0; i < 7; i ++) + { + gSendCmd[i + 1] = (src[sBlockSend.pos + i * 2 + 1] << 8) | src[sBlockSend.pos + i * 2]; + } + sBlockSend.pos += 14; + if (sBlockSend.size <= sBlockSend.pos) + { + sBlockSend.active = FALSE; + gLinkCallback = LinkCB_BlockSendEnd; + } +} + +static void LinkCB_BlockSendEnd(void) +{ + gLinkCallback = NULL; +} + +static void sub_800A3F8(void) +{ + GetMultiplayerId(); + BuildSendCmd(LINKCMD_SEND_HELD_KEYS); + gUnknown_020223C0 ++; +} + +void sub_800A418(void) +{ + gUnknown_020223C0 = 0; + if (gWirelessCommType) + { + sub_800F850(); + } + else + { + gLinkCallback = sub_800A3F8; + } +} + +u32 sub_800A44C(void) +{ + return gUnknown_020223C0; +} + +void sub_800A458(void) +{ + BuildSendCmd(LINKCMD_0xAAAA); +} + +u8 GetMultiplayerId(void) +{ + if (gWirelessCommType == TRUE) + { + return rfu_get_multiplayer_id(); + } + return SIO_MULTI_CNT->id; +} + +u8 bitmask_all_link_players_but_self(void) +{ + u8 mpId; + + mpId = GetMultiplayerId(); + return ((1 << MAX_LINK_PLAYERS) - 1) ^ (1 << mpId); +} + +bool8 SendBlock(u8 unused, const void *src, u16 size) +{ + if (gWirelessCommType == TRUE) + { + return sub_800FE84(src, size); + } + return InitBlockSend(src, size); +} + +bool8 sub_800A4D8(u8 a0) +{ + if (gWirelessCommType == TRUE) + { + return sub_8010100(a0); + } + if (gLinkCallback == NULL) + { + gBlockRequestType = a0; + BuildSendCmd(LINKCMD_0xCCCC); + return TRUE; + } + return FALSE; +} + +bool8 sub_800A520(void) +{ + if (gWirelessCommType == TRUE) + { + return sub_8010500(); + } + return gLinkCallback == NULL; +} + +u8 GetBlockReceivedStatus(void) +{ + if (gWirelessCommType == TRUE) + { + return sub_800FCD8(); + } + return (gBlockReceivedStatus[3] << 3) | (gBlockReceivedStatus[2] << 2) | (gBlockReceivedStatus[1] << 1) | (gBlockReceivedStatus[0] << 0); +} + +static void SetBlockReceivedFlag(u8 who) +{ + if (gWirelessCommType == TRUE) + { + sub_800F6FC(who); + } + else + { + gBlockReceivedStatus[who] = TRUE; + } +} + +void ResetBlockReceivedFlags(void) +{ + int i; + + if (gWirelessCommType == TRUE) + { + for (i = 0; i < MAX_RFU_PLAYERS; i ++) + { + sub_800F728(i); + } + } + else + { + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + gBlockReceivedStatus[i] = FALSE; + } + } +} + +void ResetBlockReceivedFlag(u8 who) +{ + if (gWirelessCommType == TRUE) + { + sub_800F728(who); + } + else if (gBlockReceivedStatus[who]) + { + gBlockReceivedStatus[who] = FALSE; + } +} + +void sub_800A620(void) +{ + if ((gLinkStatus & LINK_STAT_MASTER) && EXTRACT_PLAYER_COUNT(gLinkStatus) > 1) + { + gShouldAdvanceLinkState = 1; + } +} + +static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size) +{ + u16 chksum; + u16 i; + + chksum = 0; + for (i = 0; i < size / 2; i ++) + { + chksum += src[i]; + } + return chksum; +} + +static void LinkTest_prnthexchar(char a0, u8 a1, u8 a2) +{ + u16 *vAddr; + + vAddr = (u16 *)BG_SCREEN_ADDR(gLinkTestBGInfo.screenBaseBlock); + vAddr[a2 * 32 + a1] = (gLinkTestBGInfo.paletteNum << 12) | (a0 + 1 + gLinkTestBGInfo.dummy_8); +} + +static void LinkTest_prntchar(char a0, u8 a1, u8 a2) +{ + u16 *vAddr; + + vAddr = (u16 *)BG_SCREEN_ADDR(gLinkTestBGInfo.screenBaseBlock); + vAddr[a2 * 32 + a1] = (gLinkTestBGInfo.paletteNum << 12) | (a0 + gLinkTestBGInfo.dummy_8); +} + +static void LinkTest_prnthex(u32 pos, u8 a0, u8 a1, u8 a2) +{ + char sp[32 / 2]; + int i; + + for (i = 0; i < a2; i ++) + { + sp[i] = pos & 0xf; + pos >>= 4; + } + for (i = a2 - 1; i >= 0; i --) + { + LinkTest_prnthexchar(sp[i], a0, a1); + a0 ++; + } +} + +static void LinkTest_prntint(int a0, u8 a1, u8 a2, u8 a3) +{ + char sp[32 / 2]; + int sp10; + int i; + + sp10 = -1; + if (a0 < 0) + { + sp10 = a1; + a0 = -a0; + } + for (i = 0; i < a3; i ++) + { + sp[i] = a0 % 10; + a0 /= 10; + } + for (i = a3 - 1; i >= 0; i --) + { + LinkTest_prnthexchar(sp[i], a1, a2); + a1 ++; + } + if (sp10 != -1) + { + LinkTest_prnthexchar(*"\n", sp10, a2); + } +} + +static void LinkTest_prntstr(const char *a0, u8 a1, u8 a2) +{ + int r6; + int i; + int r5; + + r5 = 0; + r6 = 0; + for (i = 0; a0[i] != 0; a0 ++) + { + if (a0[i] == *"\n") + { + r5 ++; + r6 = 0; + } + else + { + LinkTest_prntchar(a0[i], a1 + r6, a2 + r5); + r6 ++; + } + } +} + +static void LinkCB_RequestPlayerDataExchange(void) +{ + if (gLinkStatus & LINK_STAT_MASTER) + { + BuildSendCmd(LINKCMD_SEND_LINK_TYPE); + } + gLinkCallback = NULL; +} + +static void Task_PrintTestData(u8 taskId) +{ + char sp[32]; + int i; + + strcpy(sp, gASCIITestPrint); + LinkTest_prntstr(sp, 5, 2); + LinkTest_prnthex(gShouldAdvanceLinkState, 2, 1, 2); + LinkTest_prnthex(gLinkStatus, 15, 1, 8); + LinkTest_prnthex(gLink.state, 2, 10, 2); + LinkTest_prnthex(EXTRACT_PLAYER_COUNT(gLinkStatus), 15, 10, 2); + LinkTest_prnthex(GetMultiplayerId(), 15, 12, 2); + LinkTest_prnthex(gLastSendQueueCount, 25, 1, 2); + LinkTest_prnthex(gLastRecvQueueCount, 25, 2, 2); + LinkTest_prnthex(GetBlockReceivedStatus(), 15, 5, 2); + LinkTest_prnthex(gLinkDebugSeed, 2, 12, 8); + LinkTest_prnthex(gLinkDebugFlags, 2, 13, 8); + LinkTest_prnthex(GetSioMultiSI(), 25, 5, 1); + LinkTest_prnthex(IsSioMultiMaster(), 25, 6, 1); + LinkTest_prnthex(IsLinkConnectionEstablished(), 25, 7, 1); + LinkTest_prnthex(HasLinkErrorOccurred(), 25, 8, 1); + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + LinkTest_prnthex(gLinkTestBlockChecksums[i], 10, 4 + i, 4); + } +} + +void SetLinkDebugValues(u32 seed, u32 flags) +{ + gLinkDebugSeed = seed; + gLinkDebugFlags = flags; +} + +u8 sub_800A9A8(void) +{ + int i; + u8 flags; + + flags = 0; + for (i = 0; i < gSavedLinkPlayerCount; i ++) + { + flags |= (1 << i); + } + return flags; +} + +u8 sub_800A9D8(void) +{ + int i; + u8 flags; + + flags = 0; + for (i = 0; i < GetLinkPlayerCount(); i ++) + { + flags |= (1 << i); + } + return flags; +} + +void sub_800AA04(u8 a0) +{ + int i; + + gSavedLinkPlayerCount = a0; + gSavedMultiplayerId = GetMultiplayerId(); + for (i = 0; i < MAX_RFU_PLAYERS; i ++) + { + gSavedLinkPlayers[i] = gLinkPlayers[i]; + } +} + +u8 sub_800AA48(void) +{ + return gSavedLinkPlayerCount; +} + +u8 sub_800AA54(void) +{ + return gSavedMultiplayerId; +} + +bool8 sub_800AA60(void) +{ + int i; + unsigned count; + + count = 0; + for (i = 0; i < gSavedLinkPlayerCount; i ++) + { + if (gLinkPlayers[i].trainerId == gSavedLinkPlayers[i].trainerId) + { + if (gLinkType == 0x2288) + { + if (gLinkType == gLinkPlayers[i].linkType) + { + count ++; + } + } + else + { + count ++; + } + } + } + if (count == gSavedLinkPlayerCount) + { + if (GetLinkPlayerCount_2() == gSavedLinkPlayerCount) + { + return TRUE; + } + } + return FALSE; +} + +void sub_800AAF4(void) +{ + int i; + + // Clearly not what was meant to be written, but here it is anyway. + for (i = 0; i < 4; i ++) + { + CpuSet(&gSavedLinkPlayers[i], NULL, sizeof(struct LinkPlayer)); + } +} + +void sub_800AB18(void) +{ + u8 i; + + for (i = 0; i < gSavedLinkPlayerCount; i ++) + { + if (gSavedLinkPlayers[i].trainerId != gLinkPlayers[i].trainerId || StringCompare(gSavedLinkPlayers[i].name, gLinkPlayers[i].name) != 0) + { + gLinkErrorOccurred = TRUE; + CloseLink(); + SetMainCallback2(CB2_LinkError); + } + } +} + +void sub_800AB98(void) +{ + gSavedLinkPlayerCount = 0; + gSavedMultiplayerId = 0; +} + +u8 GetLinkPlayerCount_2(void) +{ + return EXTRACT_PLAYER_COUNT(gLinkStatus); +} + +bool8 IsLinkMaster(void) +{ + if (gWirelessCommType) + { + return Rfu_IsMaster(); + } + return EXTRACT_MASTER(gLinkStatus); +} + +u8 sub_800ABE8(void) +{ + return gUnknown_03000D58; +} + +void sub_800ABF4(u16 a0) +{ + if (gWirelessCommType == TRUE) + { + task_add_05_task_del_08FA224_when_no_RfuFunc(); + } + else + { + if (gLinkCallback == NULL) + { + gLinkCallback = sub_800AC80; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = a0; + } + } +} + +void sub_800AC34(void) +{ + if (gWirelessCommType == TRUE) + { + task_add_05_task_del_08FA224_when_no_RfuFunc(); + } + else + { + if (gLinkCallback != NULL) + { + gUnknown_02022B08 ++; + } + else + { + gLinkCallback = sub_800AC80; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = 0; + } + } +} + +static void sub_800AC80(void) +{ + if (gLastRecvQueueCount == 0) + { + BuildSendCmd(LINKCMD_0x5FFF); + gLinkCallback = sub_800ACAC; + } +} + +static void sub_800ACAC(void) +{ + int i; + unsigned count; + u8 linkPlayerCount; + + linkPlayerCount = GetLinkPlayerCount(); + count = 0; + for (i = 0; i < linkPlayerCount; i ++) + { + if (gUnknown_030030F0[i]) + { + count ++; + } + } + if (count == linkPlayerCount) + { + gBattleTypeFlags &= ~BATTLE_TYPE_20; + gLinkVSyncDisabled = TRUE; + CloseLink(); + gLinkCallback = NULL; + gUnknown_030030E4 = TRUE; + } +} + +void sub_800AD10(void) +{ + if (gWirelessCommType == TRUE) + { + task_add_05_task_del_08FA224_when_no_RfuFunc(); + } + else + { + if (gLinkCallback != NULL) + { + gUnknown_02022B08 ++; + } + else + { + gLinkCallback = sub_800AD5C; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = 0; + } + } +} + +static void sub_800AD5C(void) +{ + if (gLastRecvQueueCount == 0) + { + BuildSendCmd(LINKCMD_0x5FFF); + gLinkCallback = sub_800AD88; + } +} + +static void sub_800AD88(void) +{ + int i; + unsigned count; + u8 linkPlayerCount; + + linkPlayerCount = GetLinkPlayerCount(); + count = 0; + for (i = 0; i < linkPlayerCount; i ++) + { + if (gLinkPlayers[i].language == LANGUAGE_JAPANESE) + { + count ++; + } + else if (gUnknown_030030F0[i]) + { + count ++; + } + } + if (count == linkPlayerCount) + { + gBattleTypeFlags &= ~BATTLE_TYPE_20; + gLinkVSyncDisabled = TRUE; + CloseLink(); + gLinkCallback = NULL; + gUnknown_030030E4 = TRUE; + } +} + +void sub_800ADF8(void) +{ + if (gWirelessCommType == TRUE) + { + sub_8010434(); + } + else + { + if (gLinkCallback == NULL) + { + gLinkCallback = sub_800AE30; + } + gUnknown_030030E4 = FALSE; + } +} + +static void sub_800AE30(void) +{ + if (gLastRecvQueueCount == 0) + { + BuildSendCmd(LINKCMD_0x2FFE); + gLinkCallback = sub_800AE5C; + } +} + +static void sub_800AE5C(void) +{ + u8 i; + u8 linkPlayerCount; + + linkPlayerCount = GetLinkPlayerCount(); + for (i = 0; i < linkPlayerCount; i ++) + { + if (!gUnknown_030030EC[i]) + { + break; + } + } + if (i == linkPlayerCount) + { + for (i = 0; i < MAX_LINK_PLAYERS; i ++) + { + gUnknown_030030EC[i] = FALSE; + } + gLinkCallback = NULL; + } +} + +static void CheckErrorStatus(void) +{ + if (gLinkOpen && EXTRACT_LINK_ERRORS(gLinkStatus)) + { + if (!gSuppressLinkErrorMessage) + { + sLinkErrorBuffer.status = gLinkStatus; + sLinkErrorBuffer.lastRecvQueueCount = gLastRecvQueueCount; + sLinkErrorBuffer.lastSendQueueCount = gLastSendQueueCount; + SetMainCallback2(CB2_LinkError); + } + gLinkErrorOccurred = TRUE; + CloseLink(); + } +} + +void sub_800AF18(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, u8 unk_06) +{ + sLinkErrorBuffer.status = status; + sLinkErrorBuffer.lastSendQueueCount = lastSendQueueCount; + sLinkErrorBuffer.lastRecvQueueCount = lastRecvQueueCount; + sLinkErrorBuffer.unk_06 = unk_06; +} + +void CB2_LinkError(void) +{ + u8 *tilemapBuffer; + + SetGpuReg(REG_OFFSET_DISPCNT, 0); + m4aMPlayStop(&gMPlay_SE1); + m4aMPlayStop(&gMPlay_SE2); + m4aMPlayStop(&gMPlay_SE3); + InitHeap(gHeap, HEAP_SIZE); + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetPaletteFadeControl(); + FillPalette(0, 0, 2); + ResetTasks(); + remove_some_task(); + if (gWirelessCommType) + { + if (!sLinkErrorBuffer.unk_06) + { + gWirelessCommType = 3; + } + sub_800E604(); + } + SetVBlankCallback(sub_80096BC); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_082ED1FC, 2); + gUnknown_02022B0C = tilemapBuffer = malloc(0x800); + SetBgTilemapBuffer(1, tilemapBuffer); + if (InitWindows(gUnknown_082ED204)) + { + DeactivateAllTextPrinters(); + reset_temp_tile_data_buffers(); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON); + LoadPalette(gUnknown_0860F074, 0xf0, 0x20); + gSoftResetDisabled = FALSE; + CreateTask(Task_DestroySelf, 0); + StopMapMusic(); + gMain.callback1 = NULL; + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + SetMainCallback2(CB2_PrintErrorMessage); + } +} + +static void sub_800B080(void) +{ + LoadBgTiles(0, g2BlankTilesGfx, 0x20, 0); + copy_decompressed_tile_data_to_vram_autofree(1, gWirelessLinkDisplayGfx, FALSE, 0, 0); + CopyToBgTilemapBuffer(1, gWirelessLinkDisplayTilemap, 0, 0); + CopyBgTilemapBufferToVram(1); + LoadPalette(gWirelessLinkDisplayPal, 0, 0x20); + FillWindowPixelBuffer(0, 0x00); + FillWindowPixelBuffer(2, 0x00); + box_print(0, 3, 2, 6, gUnknown_082ED224, 0, gText_CommErrorEllipsis); + box_print(2, 3, 2, 1, gUnknown_082ED224, 0, gText_MoveCloserToLinkPartner); + PutWindowTilemap(0); + PutWindowTilemap(2); + CopyWindowToVram(0, 0); + CopyWindowToVram(2, 3); +} + +static void sub_800B138(void) +{ + LoadBgTiles(0, g2BlankTilesGfx, 0x20, 0); + FillWindowPixelBuffer(1, 0x00); + FillWindowPixelBuffer(2, 0x00); + box_print(1, 3, 2, 0, gUnknown_082ED224, 0, gText_CommErrorCheckConnections); + PutWindowTilemap(1); + PutWindowTilemap(2); + CopyWindowToVram(1, 0); + CopyWindowToVram(2, 3); +} + +static void CB2_PrintErrorMessage(void) +{ + switch (gMain.state) + { + case 00: + if (sLinkErrorBuffer.unk_06) + { + sub_800B080(); + } + else + { + sub_800B138(); + } + break; + case 02: + ShowBg(0); + if (sLinkErrorBuffer.unk_06) + { + ShowBg(1); + } + break; + case 30: + PlaySE(SE_BOO); + break; + case 60: + PlaySE(SE_BOO); + break; + case 90: + PlaySE(SE_BOO); + break; + case 130: + if (gWirelessCommType == 2) + { + box_print(0, 3, 2, 20, gUnknown_082ED224, 0, gText_ABtnTitleScreen); + } + else if (gWirelessCommType == 1) + { + box_print(0, 3, 2, 20, gUnknown_082ED224, 0, gText_ABtnRegistrationCounter); + } + break; + } + if (gMain.state == 160) + { + if (gWirelessCommType == 1) + { + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_PIN); + gWirelessCommType = 0; + sLinkErrorBuffer.unk_06 = 0; + sub_81700F8(); + } + } + else if (gWirelessCommType == 2) + { + if (gMain.newKeys & A_BUTTON) + { + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + DoSoftReset(); + } + } + } + if (gMain.state != 160) + { + gMain.state ++; + } +} + +bool8 GetSioMultiSI(void) +{ + return (REG_SIOCNT & 0x04) != 0; +} + +static bool8 IsSioMultiMaster(void) +{ + return (REG_SIOCNT & 0x8) && !(REG_SIOCNT & 0x04); +} + +bool8 IsLinkConnectionEstablished(void) +{ + return EXTRACT_CONN_ESTABLISHED(gLinkStatus); +} + +void SetSuppressLinkErrorMessage(bool8 flag) +{ + gSuppressLinkErrorMessage = flag; +} + +bool8 HasLinkErrorOccurred(void) +{ + return gLinkErrorOccurred; +} + +void sub_800B348(void) +{ + struct LinkPlayerBlock *block; + + InitLocalLinkPlayer(); + block = &gLocalLinkPlayerBlock; + block->linkPlayer = gLocalLinkPlayer; + memcpy(block->magic1, gASCIIGameFreakInc, sizeof(block->magic1) - 1); + memcpy(block->magic2, gASCIIGameFreakInc, sizeof(block->magic2) - 1); + memcpy(gBlockSendBuffer, block, sizeof(*block)); +} + +void sub_800B3A4(u8 who) +{ + struct LinkPlayerBlock *block; + struct LinkPlayer *player; + + block = (struct LinkPlayerBlock *)gBlockRecvBuffer[who]; + player = &gLinkPlayers[who]; + *player = block->linkPlayer; + sub_800B524(player); + if (strcmp(block->magic1, gASCIIGameFreakInc) != 0 || strcmp(block->magic2, gASCIIGameFreakInc) != 0) + { + SetMainCallback2(CB2_LinkError); + } +} + +bool8 HandleLinkConnection(void) +{ + bool32 r4; + bool32 r5; + + if (gWirelessCommType == 0) + { + gLinkStatus = LinkMain1(&gShouldAdvanceLinkState, gSendCmd, gRecvCmds); + LinkMain2(&gMain.heldKeys); + if ((gLinkStatus & LINK_STAT_RECEIVED_NOTHING) && sub_808766C() == TRUE) + { + return TRUE; + } + } + else + { + r4 = sub_8010EC0(); + r5 = sub_8010F1C(); + if (sub_808766C() == TRUE) + { + if (r4 == TRUE || sub_800F0B8() || r5) + { + return TRUE; + } + } + } + return FALSE; +} + +void sub_800B488(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gWirelessCommType = 1; + } +} + +static void sub_800B4A4(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gWirelessCommType = 0; + } +} + +void sub_800B4C0(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gWirelessCommType = 0; + } +} + +u32 sub_800B4DC(void) +{ + if (gWirelessCommType != 0) + { + return sub_80124D4(); + } + return gLink.recvQueue.count; +} + +bool8 sub_800B504(void) +{ + if (sub_800B4DC() > 2) + { + return TRUE; + } + return FALSE; +} + +u8 sub_800B518(void) +{ + return gWirelessCommType; +} + +void sub_800B524(struct LinkPlayer *player) +{ + player->name[10] = player->name[8]; + ConvertInternationalString(player->name, player->language); +} + +static void DisableSerial(void) +{ + DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + REG_SIOCNT = SIO_MULTI_MODE; + REG_TMCNT_H(3) = 0; + REG_IF = INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL; + REG_SIOMLT_SEND = 0; + REG_SIOMLT_RECV = 0; + CpuFill32(0, &gLink, sizeof(gLink)); +} + +static void EnableSerial(void) +{ + DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + REG_RCNT = 0; + REG_SIOCNT = SIO_MULTI_MODE; + REG_SIOCNT |= SIO_115200_BPS | SIO_INTR_ENABLE; + EnableInterrupts(INTR_FLAG_SERIAL); + REG_SIOMLT_SEND = 0; + CpuFill32(0, &gLink, sizeof(gLink)); + sNumVBlanksWithoutSerialIntr = 0; + sSendNonzeroCheck = 0; + gUnknown_03000D70 = 0; + gUnknown_03000D72 = 0; + sHandshakePlayerCount = 0; + gLastSendQueueCount = 0; + gLastRecvQueueCount = 0; +} + +void ResetSerial(void) +{ + EnableSerial(); + DisableSerial(); +} + +u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENGTH]) +{ + u32 retVal; + u32 retVal2; + + switch (gLink.state) + { + case LINK_STATE_START0: + DisableSerial(); + gLink.state = 1; + break; + case LINK_STATE_START1: + if (*shouldAdvanceLinkState == 1) + { + EnableSerial(); + gLink.state = 2; + } + break; + case LINK_STATE_HANDSHAKE: + switch (*shouldAdvanceLinkState) + { + default: + CheckMasterOrSlave(); + break; + case 1: + if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1) + { + gLink.handshakeAsMaster = TRUE; + } + break; + case 2: + gLink.state = LINK_STATE_START0; + REG_SIOMLT_SEND = 0; + break; + } + break; + case LINK_STATE_INIT_TIMER: + InitTimer(); + gLink.state = LINK_STATE_CONN_ESTABLISHED; + // fallthrough + case LINK_STATE_CONN_ESTABLISHED: + EnqueueSendCmd(sendCmd); + DequeueRecvCmds(recvCmds); + break; + } + *shouldAdvanceLinkState = 0; + retVal = gLink.localId; + retVal |= (gLink.playerCount << LINK_STAT_PLAYER_COUNT_SHIFT); + if (gLink.isMaster == LINK_MASTER) + { + retVal |= LINK_STAT_MASTER; + } + { + u32 receivedNothing = gLink.receivedNothing << LINK_STAT_RECEIVED_NOTHING_SHIFT; + u32 link_field_F = gLink.link_field_F << LINK_STAT_UNK_FLAG_9_SHIFT; + u32 hardwareError = gLink.hardwareError << LINK_STAT_ERROR_HARDWARE_SHIFT; + u32 badChecksum = gLink.badChecksum << LINK_STAT_ERROR_CHECKSUM_SHIFT; + u32 queueFull = gLink.queueFull << LINK_STAT_ERROR_QUEUE_FULL_SHIFT; + u32 val; + + if (gLink.state == LINK_STATE_CONN_ESTABLISHED) + { + val = LINK_STAT_CONN_ESTABLISHED; + val |= receivedNothing; + val |= retVal; + val |= link_field_F; + val |= hardwareError; + val |= badChecksum; + val |= queueFull; + } + else + { + val = retVal; + val |= receivedNothing; + val |= link_field_F; + val |= hardwareError; + val |= badChecksum; + val |= queueFull; + } + + retVal = val; + } + + if (gLink.lag == LAG_MASTER) + { + retVal |= LINK_STAT_ERROR_LAG_MASTER; + } + + if (gLink.localId >= MAX_LINK_PLAYERS) + { + retVal |= LINK_STAT_ERROR_INVALID_ID; + } + + retVal2 = retVal; + if (gLink.lag == LAG_SLAVE) + { + retVal2 |= LINK_STAT_ERROR_LAG_SLAVE; + } + + return retVal2; +} + +static void CheckMasterOrSlave(void) +{ + u32 terminals; + + terminals = *(vu32 *)REG_ADDR_SIOCNT & (SIO_MULTI_SD | SIO_MULTI_SI); + if (terminals == SIO_MULTI_SD && gLink.localId == 0) + { + gLink.isMaster = LINK_MASTER; + } + else + { + gLink.isMaster = LINK_SLAVE; + } +} + +static void InitTimer(void) +{ + if (gLink.isMaster) + { + REG_TM3CNT_L = 0xFF3B; + REG_TM3CNT_H = TIMER_64CLK | TIMER_INTR_ENABLE; + EnableInterrupts(INTR_FLAG_TIMER3); + } +} + +static void EnqueueSendCmd(u16 *sendCmd) +{ + u8 i; + u8 offset; + + gLinkSavedIme = REG_IME; + REG_IME = 0; + if (gLink.sendQueue.count < QUEUE_CAPACITY) + { + offset = gLink.sendQueue.pos + gLink.sendQueue.count; + if (offset >= QUEUE_CAPACITY) + { + offset -= QUEUE_CAPACITY; + } + for (i = 0; i < CMD_LENGTH; i ++) + { + sSendNonzeroCheck |= *sendCmd; + gLink.sendQueue.data[i][offset] = *sendCmd; + *sendCmd = 0; + sendCmd++; + } + } + else + { + gLink.queueFull = QUEUE_FULL_SEND; + } + if (sSendNonzeroCheck) + { + gLink.sendQueue.count ++; + sSendNonzeroCheck = 0; + } + REG_IME = gLinkSavedIme; + gLastSendQueueCount = gLink.sendQueue.count; +} + + +static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]) +{ + u8 i; + u8 j; + + gLinkSavedIme = REG_IME; + REG_IME = 0; + if (gLink.recvQueue.count == 0) + { + for (i = 0; i < gLink.playerCount; i ++) + { + for (j = 0; j < CMD_LENGTH; j ++) + { + recvCmds[i][j] = 0; + } + } + + gLink.receivedNothing = TRUE; + } + else + { + for (i = 0; i < gLink.playerCount; i ++) + { + for (j = 0; j < CMD_LENGTH; j ++) + { + recvCmds[i][j] = gLink.recvQueue.data[i][j][gLink.recvQueue.pos]; + } + } + gLink.recvQueue.count --; + gLink.recvQueue.pos ++; + if (gLink.recvQueue.pos >= QUEUE_CAPACITY) + { + gLink.recvQueue.pos = 0; + } + gLink.receivedNothing = FALSE; + } + REG_IME = gLinkSavedIme; +} + +void LinkVSync(void) +{ + if (gLink.isMaster) + { + switch (gLink.state) + { + case LINK_STATE_CONN_ESTABLISHED: + if (gLink.serialIntrCounter < 9) + { + if (gLink.hardwareError != TRUE) + { + gLink.lag = LAG_MASTER; + } + else + { + StartTransfer(); + } + } + else if (gLink.lag != LAG_MASTER) + { + gLink.serialIntrCounter = 0; + StartTransfer(); + } + break; + case LINK_STATE_HANDSHAKE: + StartTransfer(); + break; + } + } + else if (gLink.state == LINK_STATE_CONN_ESTABLISHED || gLink.state == LINK_STATE_HANDSHAKE) + { + if (++ sNumVBlanksWithoutSerialIntr > 10) + { + if (gLink.state == LINK_STATE_CONN_ESTABLISHED) + { + gLink.lag = LAG_SLAVE; + } + if (gLink.state == LINK_STATE_HANDSHAKE) + { + gLink.playerCount = 0; + gLink.link_field_F = FALSE; + } + } + } +} + +void Timer3Intr(void) +{ + StopTimer(); + StartTransfer(); +} + +void SerialCB(void) +{ + gLink.localId = SIO_MULTI_CNT->id; + switch (gLink.state) + { + case LINK_STATE_CONN_ESTABLISHED: + gLink.hardwareError = SIO_MULTI_CNT->error; + DoRecv(); + DoSend(); + SendRecvDone(); + break; + case LINK_STATE_HANDSHAKE: + if (DoHandshake()) + { + if (gLink.isMaster) + { + gLink.state = LINK_STATE_INIT_TIMER; + gLink.serialIntrCounter = 8; + } + else + { + gLink.state = LINK_STATE_CONN_ESTABLISHED; + } + } + break; + } + gLink.serialIntrCounter ++; + sNumVBlanksWithoutSerialIntr = 0; + if (gLink.serialIntrCounter == 8) + { + gLastRecvQueueCount = gLink.recvQueue.count; + } +} + +static void StartTransfer(void) +{ + REG_SIOCNT |= SIO_START; +} + +static bool8 DoHandshake(void) +{ + u8 i; + u8 playerCount; + u16 minRecv; + + playerCount = 0; + minRecv = 0xFFFF; + if (gLink.handshakeAsMaster == TRUE) + { + REG_SIOMLT_SEND = MASTER_HANDSHAKE; + } + else + { + REG_SIOMLT_SEND = SLAVE_HANDSHAKE; + } + *(u64 *)gLink.tempRecvBuffer = REG_SIOMLT_RECV; + REG_SIOMLT_RECV = 0; + gLink.handshakeAsMaster = FALSE; + for (i = 0; i < 4; i ++) + { + if ((gLink.tempRecvBuffer[i] & ~0x3) == SLAVE_HANDSHAKE || gLink.tempRecvBuffer[i] == MASTER_HANDSHAKE) + { + playerCount ++; + if (minRecv > gLink.tempRecvBuffer[i] && gLink.tempRecvBuffer[i] != 0) + { + minRecv = gLink.tempRecvBuffer[i]; + } + } + else + { + if (gLink.tempRecvBuffer[i] != 0xFFFF) + { + playerCount = 0; + } + break; + } + } + gLink.playerCount = playerCount; + if (gLink.playerCount > 1 && gLink.playerCount == sHandshakePlayerCount && gLink.tempRecvBuffer[0] == MASTER_HANDSHAKE) + { + return TRUE; + } + if (gLink.playerCount > 1) + { + gLink.link_field_F = (minRecv & 3) + 1; + } + else + { + gLink.link_field_F = 0; + } + sHandshakePlayerCount = gLink.playerCount; + return FALSE; +} diff --git a/src/link_rfu.c b/src/link_rfu.c new file mode 100644 index 000000000..43169a275 --- /dev/null +++ b/src/link_rfu.c @@ -0,0 +1,16 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations +IWRAM_DATA u8 gUnknown_03000D78[8]; +IWRAM_DATA u8 gUnknown_03000D80[16]; +IWRAM_DATA u16 gUnknown_03000D90[8]; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/main.c b/src/main.c index 665a4dd84..09ab3f5e4 100644 --- a/src/main.c +++ b/src/main.c @@ -1,50 +1,30 @@ #include "global.h" -#include "main.h" +#include "crt0.h" +#include "malloc.h" +#include "link.h" +#include "link_rfu.h" +#include "librfu.h" #include "m4a.h" +#include "bg.h" #include "rtc.h" +#include "unknown_task.h" #include "rng.h" +#include "overworld.h" +#include "play_time.h" #include "dma3.h" #include "gba/flash_internal.h" +#include "load_save.h" +#include "gpu_regs.h" +#include "agb_flash.h" +#include "sound.h" #include "battle.h" +#include "battle_controllers.h" +#include "text.h" +#include "intro.h" +#include "main.h" -extern u16 GetGpuReg(u8); -extern void SetGpuReg(u8, u16); -extern void LinkVSync(void); -extern void sub_800E174(void); -extern void sub_800B9B8(void); -extern void InitGpuRegManager(void); -extern void sub_800E6D0(void); -extern void CheckForFlashMemory(void); -extern void InitMapMusic(void); -extern void ResetBgs(void); -extern void SetDefaultFontsPointer(void); -extern void InitHeap(void *heapStart, u32 heapSize); // malloc.h -extern void rfu_REQ_stopMode(void); -extern void rfu_waitREQComplete(void); -extern bool32 sub_8087634(void); -extern bool32 sub_80875C8(void); -extern void ClearSpriteCopyRequests(void); -extern void PlayTimeCounter_Update(void); -extern void MapMusicMain(void); -extern void EnableInterrupts(u16); -extern void sub_8033648(void); -extern u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void)); -extern void remove_some_task(void); - -extern struct SoundInfo gSoundInfo; -extern u32 gFlashMemoryPresent; -extern u32 IntrMain[]; -extern u8 gHeap[]; -extern struct SaveBlock2 gSaveblock2; -extern struct PokemonStorage gPokemonStorage; -extern u32 gBattleTypeFlags; -extern u8 gUnknown_03002748; extern u32 *gUnknown_0203CF5C; -void Timer3Intr(void); -bool8 HandleLinkConnection(void); -void c2_copyright_1(void); - static void VBlankIntr(void); static void HBlankIntr(void); static void VCountIntr(void); @@ -79,19 +59,19 @@ const IntrFunc gIntrTableTemplate[] = static u16 gUnknown_03000000; -extern u16 gKeyRepeatStartDelay; -extern u8 gUnknown_030022B4; -extern struct Main gMain; -extern u16 gKeyRepeatContinueDelay; -extern u8 gSoftResetDisabled; -extern IntrFunc gIntrTable[INTR_COUNT]; -extern bool8 gLinkVSyncDisabled; -extern u32 IntrMain_Buffer[0x200]; -extern u8 gPcmDmaCounter; +u16 gKeyRepeatStartDelay; +bool8 gLinkTransferringData; +struct Main gMain; +u16 gKeyRepeatContinueDelay; +bool8 gSoftResetDisabled; +IntrFunc gIntrTable[INTR_COUNT]; +u8 gLinkVSyncDisabled; +u32 IntrMain_Buffer[0x200]; +u8 gPcmDmaCounter; -extern u16 gTrainerId; +static EWRAM_DATA u16 gTrainerId = 0; -EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL; +//EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL; static void UpdateLinkAndCallCallbacks(void); static void InitMainCallbacks(void); @@ -129,7 +109,7 @@ void AgbMain() if (gFlashMemoryPresent != TRUE) SetMainCallback2(NULL); - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; gUnknown_03000000 = 0xFC0; for (;;) @@ -147,22 +127,22 @@ void AgbMain() if (sub_8087634() == 1) { - gUnknown_030022B4 = 1; + gLinkTransferringData = TRUE; UpdateLinkAndCallCallbacks(); - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; } else { - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; UpdateLinkAndCallCallbacks(); if (sub_80875C8() == 1) { gMain.newKeys = 0; ClearSpriteCopyRequests(); - gUnknown_030022B4 = 1; + gLinkTransferringData = TRUE; UpdateLinkAndCallCallbacks(); - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; } } @@ -336,10 +316,10 @@ extern void ProcessDma3Requests(void); static void VBlankIntr(void) { - if (gLinkVSyncDisabled != FALSE) + if (gWirelessCommType != 0) + RfuVSync(); + else if (gLinkVSyncDisabled == FALSE) LinkVSync(); - else if (gUnknown_03002748 == FALSE) - sub_800B9B8(); gMain.vblankCounter1++; diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c index 3177a8946..de2dcf213 100644 --- a/src/reshow_battle_screen.c +++ b/src/reshow_battle_screen.c @@ -177,7 +177,7 @@ static void CB2_ReshowBattleScreenAfterMenu(void) ActionSelectionCreateCursorAt(gActionSelectionCursor[gBankInMenu], 0); - if (gLinkVSyncDisabled != 0 && gReceivedRemoteLinkPlayers != 0) + if (gWirelessCommType != 0 && gReceivedRemoteLinkPlayers != 0) { sub_800E0E8(); sub_800DFB4(0, 0); diff --git a/src/rom_8011DC0.c b/src/rom_8011DC0.c new file mode 100644 index 000000000..9076b611a --- /dev/null +++ b/src/rom_8011DC0.c @@ -0,0 +1,18 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations +IWRAM_DATA u32 gUnknown_03000DA0; +IWRAM_DATA u32 gUnknown_03000DA4; +IWRAM_DATA void *gUnknown_03000DA8; +IWRAM_DATA void *gUnknown_03000DAC; +IWRAM_DATA bool32 gUnknown_03000DB0; + +// Static ROM declarations + +// .rodata + +// .text |